enabling <coroutine> from std library for folly when c++ version is 20
[hiphop-php.git] / hphp / runtime / test / vasm.cpp
blob9fac96cfa88b5d3687d5d3f17a4200c4b8faa7ef
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/phys-reg.h"
18 #include "hphp/runtime/vm/jit/vasm.h"
19 #include "hphp/runtime/vm/jit/vasm-emit.h"
20 #include "hphp/runtime/vm/jit/vasm-gen.h"
21 #include "hphp/runtime/vm/jit/vasm-instr.h"
22 #include "hphp/runtime/vm/jit/vasm-print.h"
23 #include "hphp/runtime/vm/jit/vasm-text.h"
24 #include "hphp/runtime/vm/jit/vasm-unit.h"
26 #if defined(__x86_64__)
27 #include <xmmintrin.h>
28 #endif
30 #include <gtest/gtest.h>
32 namespace HPHP { namespace jit {
34 namespace {
35 template<typename T, typename Lcodegen, typename Ltest>
36 void test_function(Lcodegen lcodegen, Ltest ltest) {
37 auto blockSize = 4096;
38 auto code = static_cast<uint8_t*>(mmap(nullptr, blockSize,
39 PROT_READ | PROT_WRITE | PROT_EXEC,
40 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
41 SCOPE_EXIT { munmap(code, blockSize); };
43 auto const dataSize = 100;
44 auto const codeSize = blockSize - dataSize;
45 // None of these tests should use much data.
46 auto data_buffer = code + codeSize;
48 CodeBlock main;
49 main.init(code, codeSize, "test");
50 DataBlock data;
51 data.init(data_buffer, dataSize, "data");
53 Vunit unit;
54 Vasm vasm{unit};
55 Vtext text { main, data };
57 auto& v = vasm.main();
58 unit.entry = v;
60 lcodegen(v);
62 CGMeta meta;
63 if (arch() == Arch::ARM) {
64 emitARM(unit, text, meta, nullptr);
65 } else if (arch() == Arch::X64) {
66 emitX64(unit, text, meta, nullptr);
69 ltest((T)code);
73 TEST(Vasm, Move128ARM) {
74 // A long double will use simd 128 bit registers for arguments and return
75 // types on ARM. __m128 will do the same on x86.
76 // This code checks that we actually copy a full 128 bit value when copying
77 // simd registers.
78 #if defined(__aarch64__)
79 using xmmType = long double;
80 #else
81 using xmmType = __m128;
82 #endif
83 using testfunc = xmmType (*)(xmmType, xmmType);
84 using namespace reg;
86 auto const l = [](Vout& v) {
87 v << copy{Vreg{xmm1}, Vreg{xmm0}};
88 v << ret{RegSet{xmm0}};
91 test_function<testfunc>(l, [](testfunc f) {
92 union { xmmType x; struct { uint64_t t; uint64_t v; }; } a0, a1, r;
94 a0.t = 0x88a6b5e2c10d3f9f; a0.v = 0x98713e0ad31c6b55;
95 a1.t = 0x256b36bd8ef79236; a1.v = 0x63f4b85d224d9dfb;
96 r.t = 0; r.v = 0;
98 r.x = f(a0.x, a1.x);
100 EXPECT_EQ(r.t, 0x256b36bd8ef79236);
101 EXPECT_EQ(r.v, 0x63f4b85d224d9dfb);
105 TEST(Vasm, PrintVptr) {
106 auto v0 = Vreg{Vreg::V0};
107 auto v1 = Vreg{Vreg::V0 + 1};
108 Vptr p{Vreg{v0}, Vreg{}, 1, 0};
109 EXPECT_EQ("[%128]", show(p));
110 p.index = v1;
111 EXPECT_EQ("[%128 + %129]", show(p));
112 p.scale = 4;
113 EXPECT_EQ("[%128 + %129 * 4]", show(p));
114 p.disp = 0xbeef;
115 EXPECT_EQ("[%128 + 0xbeef + %129 * 4]", show(p));
116 p.disp = -16;
117 p.index = Vreg{};
118 EXPECT_EQ("[%128 - 0x10]", show(p));
119 p.seg = Segment::FS;
120 EXPECT_EQ("[%fs + %128 - 0x10]", show(p));
121 p.base = Vreg{};
122 EXPECT_EQ("[%fs - 0x10]", show(p));