Home | History | Annotate | Download | only in wasm
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdint.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include "src/wasm/wasm-macro-gen.h"
     10 
     11 #include "test/cctest/cctest.h"
     12 #include "test/cctest/compiler/value-helper.h"
     13 #include "test/cctest/wasm/test-signatures.h"
     14 #include "test/cctest/wasm/wasm-run-utils.h"
     15 
     16 using namespace v8::base;
     17 using namespace v8::internal;
     18 using namespace v8::internal::compiler;
     19 using namespace v8::internal::wasm;
     20 
     21 #define BUILD(r, ...)                      \
     22   do {                                     \
     23     byte code[] = {__VA_ARGS__};           \
     24     r.Build(code, code + arraysize(code)); \
     25   } while (false)
     26 
     27 
     28 TEST(Run_WasmInt8Const) {
     29   WasmRunner<int8_t> r;
     30   const byte kExpectedValue = 121;
     31   // return(kExpectedValue)
     32   BUILD(r, WASM_I8(kExpectedValue));
     33   CHECK_EQ(kExpectedValue, r.Call());
     34 }
     35 
     36 
     37 TEST(Run_WasmInt8Const_fallthru1) {
     38   WasmRunner<int8_t> r;
     39   const byte kExpectedValue = 122;
     40   // kExpectedValue
     41   BUILD(r, WASM_I8(kExpectedValue));
     42   CHECK_EQ(kExpectedValue, r.Call());
     43 }
     44 
     45 
     46 TEST(Run_WasmInt8Const_fallthru2) {
     47   WasmRunner<int8_t> r;
     48   const byte kExpectedValue = 123;
     49   // -99 kExpectedValue
     50   BUILD(r, WASM_I8(-99), WASM_I8(kExpectedValue));
     51   CHECK_EQ(kExpectedValue, r.Call());
     52 }
     53 
     54 
     55 TEST(Run_WasmInt8Const_all) {
     56   for (int value = -128; value <= 127; value++) {
     57     WasmRunner<int8_t> r;
     58     // return(value)
     59     BUILD(r, WASM_I8(value));
     60     int8_t result = r.Call();
     61     CHECK_EQ(value, result);
     62   }
     63 }
     64 
     65 
     66 TEST(Run_WasmInt32Const) {
     67   WasmRunner<int32_t> r;
     68   const int32_t kExpectedValue = 0x11223344;
     69   // return(kExpectedValue)
     70   BUILD(r, WASM_I32(kExpectedValue));
     71   CHECK_EQ(kExpectedValue, r.Call());
     72 }
     73 
     74 
     75 TEST(Run_WasmInt32Const_many) {
     76   FOR_INT32_INPUTS(i) {
     77     WasmRunner<int32_t> r;
     78     const int32_t kExpectedValue = *i;
     79     // return(kExpectedValue)
     80     BUILD(r, WASM_I32(kExpectedValue));
     81     CHECK_EQ(kExpectedValue, r.Call());
     82   }
     83 }
     84 
     85 
     86 TEST(Run_WasmMemorySize) {
     87   WasmRunner<int32_t> r;
     88   TestingModule module;
     89   module.AddMemory(1024);
     90   r.env()->module = &module;
     91   BUILD(r, kExprMemorySize);
     92   CHECK_EQ(1024, r.Call());
     93 }
     94 
     95 
     96 #if WASM_64
     97 TEST(Run_WasmInt64Const) {
     98   WasmRunner<int64_t> r;
     99   const int64_t kExpectedValue = 0x1122334455667788LL;
    100   // return(kExpectedValue)
    101   BUILD(r, WASM_I64(kExpectedValue));
    102   CHECK_EQ(kExpectedValue, r.Call());
    103 }
    104 
    105 
    106 TEST(Run_WasmInt64Const_many) {
    107   int cntr = 0;
    108   FOR_INT32_INPUTS(i) {
    109     WasmRunner<int64_t> r;
    110     const int64_t kExpectedValue = (static_cast<int64_t>(*i) << 32) | cntr;
    111     // return(kExpectedValue)
    112     BUILD(r, WASM_I64(kExpectedValue));
    113     CHECK_EQ(kExpectedValue, r.Call());
    114     cntr++;
    115   }
    116 }
    117 #endif
    118 
    119 
    120 TEST(Run_WasmInt32Param0) {
    121   WasmRunner<int32_t> r(MachineType::Int32());
    122   // return(local[0])
    123   BUILD(r, WASM_GET_LOCAL(0));
    124   FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
    125 }
    126 
    127 
    128 TEST(Run_WasmInt32Param0_fallthru) {
    129   WasmRunner<int32_t> r(MachineType::Int32());
    130   // local[0]
    131   BUILD(r, WASM_GET_LOCAL(0));
    132   FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
    133 }
    134 
    135 
    136 TEST(Run_WasmInt32Param1) {
    137   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    138   // local[1]
    139   BUILD(r, WASM_GET_LOCAL(1));
    140   FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(-111, *i)); }
    141 }
    142 
    143 
    144 TEST(Run_WasmInt32Add) {
    145   WasmRunner<int32_t> r;
    146   // 11 + 44
    147   BUILD(r, WASM_I32_ADD(WASM_I8(11), WASM_I8(44)));
    148   CHECK_EQ(55, r.Call());
    149 }
    150 
    151 
    152 TEST(Run_WasmInt32Add_P) {
    153   WasmRunner<int32_t> r(MachineType::Int32());
    154   // p0 + 13
    155   BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
    156   FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
    157 }
    158 
    159 
    160 TEST(Run_WasmInt32Add_P_fallthru) {
    161   WasmRunner<int32_t> r(MachineType::Int32());
    162   // p0 + 13
    163   BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
    164   FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
    165 }
    166 
    167 
    168 TEST(Run_WasmInt32Add_P2) {
    169   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    170   //  p0 + p1
    171   BUILD(r, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    172   FOR_INT32_INPUTS(i) {
    173     FOR_INT32_INPUTS(j) {
    174       int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
    175                                               static_cast<uint32_t>(*j));
    176       CHECK_EQ(expected, r.Call(*i, *j));
    177     }
    178   }
    179 }
    180 
    181 
    182 // TODO(titzer): Fix for nosee4 and re-enable.
    183 #if 0
    184 
    185 TEST(Run_WasmFloat32Add) {
    186   WasmRunner<int32_t> r;
    187   // int(11.5f + 44.5f)
    188   BUILD(r,
    189         WASM_I32_SCONVERT_F32(WASM_F32_ADD(WASM_F32(11.5f), WASM_F32(44.5f))));
    190   CHECK_EQ(56, r.Call());
    191 }
    192 
    193 
    194 TEST(Run_WasmFloat64Add) {
    195   WasmRunner<int32_t> r;
    196   // return int(13.5d + 43.5d)
    197   BUILD(r, WASM_I32_SCONVERT_F64(WASM_F64_ADD(WASM_F64(13.5), WASM_F64(43.5))));
    198   CHECK_EQ(57, r.Call());
    199 }
    200 
    201 #endif
    202 
    203 
    204 void TestInt32Binop(WasmOpcode opcode, int32_t expected, int32_t a, int32_t b) {
    205   {
    206     WasmRunner<int32_t> r;
    207     // K op K
    208     BUILD(r, WASM_BINOP(opcode, WASM_I32(a), WASM_I32(b)));
    209     CHECK_EQ(expected, r.Call());
    210   }
    211   {
    212     WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    213     // a op b
    214     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    215     CHECK_EQ(expected, r.Call(a, b));
    216   }
    217 }
    218 
    219 
    220 TEST(Run_WasmInt32Binops) {
    221   TestInt32Binop(kExprI32Add, 88888888, 33333333, 55555555);
    222   TestInt32Binop(kExprI32Sub, -1111111, 7777777, 8888888);
    223   TestInt32Binop(kExprI32Mul, 65130756, 88734, 734);
    224   TestInt32Binop(kExprI32DivS, -66, -4777344, 72384);
    225   TestInt32Binop(kExprI32DivU, 805306368, 0xF0000000, 5);
    226   TestInt32Binop(kExprI32RemS, -3, -3003, 1000);
    227   TestInt32Binop(kExprI32RemU, 4, 4004, 1000);
    228   TestInt32Binop(kExprI32And, 0xEE, 0xFFEE, 0xFF0000FF);
    229   TestInt32Binop(kExprI32Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011);
    230   TestInt32Binop(kExprI32Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE);
    231   TestInt32Binop(kExprI32Shl, 0xA0000000, 0xA, 28);
    232   TestInt32Binop(kExprI32ShrU, 0x07000010, 0x70000100, 4);
    233   TestInt32Binop(kExprI32ShrS, 0xFF000000, 0x80000000, 7);
    234   TestInt32Binop(kExprI32Eq, 1, -99, -99);
    235   TestInt32Binop(kExprI32Ne, 0, -97, -97);
    236 
    237   TestInt32Binop(kExprI32LtS, 1, -4, 4);
    238   TestInt32Binop(kExprI32LeS, 0, -2, -3);
    239   TestInt32Binop(kExprI32LtU, 1, 0, -6);
    240   TestInt32Binop(kExprI32LeU, 1, 98978, 0xF0000000);
    241 
    242   TestInt32Binop(kExprI32GtS, 1, 4, -4);
    243   TestInt32Binop(kExprI32GeS, 0, -3, -2);
    244   TestInt32Binop(kExprI32GtU, 1, -6, 0);
    245   TestInt32Binop(kExprI32GeU, 1, 0xF0000000, 98978);
    246 }
    247 
    248 
    249 void TestInt32Unop(WasmOpcode opcode, int32_t expected, int32_t a) {
    250   {
    251     WasmRunner<int32_t> r;
    252     // return op K
    253     BUILD(r, WASM_UNOP(opcode, WASM_I32(a)));
    254     CHECK_EQ(expected, r.Call());
    255   }
    256   {
    257     WasmRunner<int32_t> r(MachineType::Int32());
    258     // return op a
    259     BUILD(r, WASM_UNOP(opcode, WASM_GET_LOCAL(0)));
    260     CHECK_EQ(expected, r.Call(a));
    261   }
    262 }
    263 
    264 
    265 TEST(Run_WasmInt32Clz) {
    266   TestInt32Unop(kExprI32Clz, 0, 0x80001000);
    267   TestInt32Unop(kExprI32Clz, 1, 0x40000500);
    268   TestInt32Unop(kExprI32Clz, 2, 0x20000300);
    269   TestInt32Unop(kExprI32Clz, 3, 0x10000003);
    270   TestInt32Unop(kExprI32Clz, 4, 0x08050000);
    271   TestInt32Unop(kExprI32Clz, 5, 0x04006000);
    272   TestInt32Unop(kExprI32Clz, 6, 0x02000000);
    273   TestInt32Unop(kExprI32Clz, 7, 0x010000a0);
    274   TestInt32Unop(kExprI32Clz, 8, 0x00800c00);
    275   TestInt32Unop(kExprI32Clz, 9, 0x00400000);
    276   TestInt32Unop(kExprI32Clz, 10, 0x0020000d);
    277   TestInt32Unop(kExprI32Clz, 11, 0x00100f00);
    278   TestInt32Unop(kExprI32Clz, 12, 0x00080000);
    279   TestInt32Unop(kExprI32Clz, 13, 0x00041000);
    280   TestInt32Unop(kExprI32Clz, 14, 0x00020020);
    281   TestInt32Unop(kExprI32Clz, 15, 0x00010300);
    282   TestInt32Unop(kExprI32Clz, 16, 0x00008040);
    283   TestInt32Unop(kExprI32Clz, 17, 0x00004005);
    284   TestInt32Unop(kExprI32Clz, 18, 0x00002050);
    285   TestInt32Unop(kExprI32Clz, 19, 0x00001700);
    286   TestInt32Unop(kExprI32Clz, 20, 0x00000870);
    287   TestInt32Unop(kExprI32Clz, 21, 0x00000405);
    288   TestInt32Unop(kExprI32Clz, 22, 0x00000203);
    289   TestInt32Unop(kExprI32Clz, 23, 0x00000101);
    290   TestInt32Unop(kExprI32Clz, 24, 0x00000089);
    291   TestInt32Unop(kExprI32Clz, 25, 0x00000041);
    292   TestInt32Unop(kExprI32Clz, 26, 0x00000022);
    293   TestInt32Unop(kExprI32Clz, 27, 0x00000013);
    294   TestInt32Unop(kExprI32Clz, 28, 0x00000008);
    295   TestInt32Unop(kExprI32Clz, 29, 0x00000004);
    296   TestInt32Unop(kExprI32Clz, 30, 0x00000002);
    297   TestInt32Unop(kExprI32Clz, 31, 0x00000001);
    298   TestInt32Unop(kExprI32Clz, 32, 0x00000000);
    299 }
    300 
    301 
    302 TEST(Run_WasmInt32Ctz) {
    303   TestInt32Unop(kExprI32Ctz, 32, 0x00000000);
    304   TestInt32Unop(kExprI32Ctz, 31, 0x80000000);
    305   TestInt32Unop(kExprI32Ctz, 30, 0x40000000);
    306   TestInt32Unop(kExprI32Ctz, 29, 0x20000000);
    307   TestInt32Unop(kExprI32Ctz, 28, 0x10000000);
    308   TestInt32Unop(kExprI32Ctz, 27, 0xa8000000);
    309   TestInt32Unop(kExprI32Ctz, 26, 0xf4000000);
    310   TestInt32Unop(kExprI32Ctz, 25, 0x62000000);
    311   TestInt32Unop(kExprI32Ctz, 24, 0x91000000);
    312   TestInt32Unop(kExprI32Ctz, 23, 0xcd800000);
    313   TestInt32Unop(kExprI32Ctz, 22, 0x09400000);
    314   TestInt32Unop(kExprI32Ctz, 21, 0xaf200000);
    315   TestInt32Unop(kExprI32Ctz, 20, 0xac100000);
    316   TestInt32Unop(kExprI32Ctz, 19, 0xe0b80000);
    317   TestInt32Unop(kExprI32Ctz, 18, 0x9ce40000);
    318   TestInt32Unop(kExprI32Ctz, 17, 0xc7920000);
    319   TestInt32Unop(kExprI32Ctz, 16, 0xb8f10000);
    320   TestInt32Unop(kExprI32Ctz, 15, 0x3b9f8000);
    321   TestInt32Unop(kExprI32Ctz, 14, 0xdb4c4000);
    322   TestInt32Unop(kExprI32Ctz, 13, 0xe9a32000);
    323   TestInt32Unop(kExprI32Ctz, 12, 0xfca61000);
    324   TestInt32Unop(kExprI32Ctz, 11, 0x6c8a7800);
    325   TestInt32Unop(kExprI32Ctz, 10, 0x8ce5a400);
    326   TestInt32Unop(kExprI32Ctz, 9, 0xcb7d0200);
    327   TestInt32Unop(kExprI32Ctz, 8, 0xcb4dc100);
    328   TestInt32Unop(kExprI32Ctz, 7, 0xdfbec580);
    329   TestInt32Unop(kExprI32Ctz, 6, 0x27a9db40);
    330   TestInt32Unop(kExprI32Ctz, 5, 0xde3bcb20);
    331   TestInt32Unop(kExprI32Ctz, 4, 0xd7e8a610);
    332   TestInt32Unop(kExprI32Ctz, 3, 0x9afdbc88);
    333   TestInt32Unop(kExprI32Ctz, 2, 0x9afdbc84);
    334   TestInt32Unop(kExprI32Ctz, 1, 0x9afdbc82);
    335   TestInt32Unop(kExprI32Ctz, 0, 0x9afdbc81);
    336 }
    337 
    338 
    339 TEST(Run_WasmInt32Popcnt) {
    340   TestInt32Unop(kExprI32Popcnt, 32, 0xffffffff);
    341   TestInt32Unop(kExprI32Popcnt, 0, 0x00000000);
    342   TestInt32Unop(kExprI32Popcnt, 1, 0x00008000);
    343   TestInt32Unop(kExprI32Popcnt, 13, 0x12345678);
    344   TestInt32Unop(kExprI32Popcnt, 19, 0xfedcba09);
    345 }
    346 
    347 
    348 #if WASM_64
    349 void TestInt64Binop(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) {
    350   if (!WasmOpcodes::IsSupported(opcode)) return;
    351   {
    352     WasmRunner<int64_t> r;
    353     // return K op K
    354     BUILD(r, WASM_BINOP(opcode, WASM_I64(a), WASM_I64(b)));
    355     CHECK_EQ(expected, r.Call());
    356   }
    357   {
    358     WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
    359     // return a op b
    360     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    361     CHECK_EQ(expected, r.Call(a, b));
    362   }
    363 }
    364 
    365 
    366 void TestInt64Cmp(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) {
    367   if (!WasmOpcodes::IsSupported(opcode)) return;
    368   {
    369     WasmRunner<int32_t> r;
    370     // return K op K
    371     BUILD(r, WASM_BINOP(opcode, WASM_I64(a), WASM_I64(b)));
    372     CHECK_EQ(expected, r.Call());
    373   }
    374   {
    375     WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64());
    376     // return a op b
    377     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    378     CHECK_EQ(expected, r.Call(a, b));
    379   }
    380 }
    381 
    382 
    383 TEST(Run_WasmInt64Binops) {
    384   // TODO(titzer): real 64-bit numbers
    385   TestInt64Binop(kExprI64Add, 8888888888888LL, 3333333333333LL,
    386                  5555555555555LL);
    387   TestInt64Binop(kExprI64Sub, -111111111111LL, 777777777777LL, 888888888888LL);
    388   TestInt64Binop(kExprI64Mul, 65130756, 88734, 734);
    389   TestInt64Binop(kExprI64DivS, -66, -4777344, 72384);
    390   TestInt64Binop(kExprI64DivU, 805306368, 0xF0000000, 5);
    391   TestInt64Binop(kExprI64RemS, -3, -3003, 1000);
    392   TestInt64Binop(kExprI64RemU, 4, 4004, 1000);
    393   TestInt64Binop(kExprI64And, 0xEE, 0xFFEE, 0xFF0000FF);
    394   TestInt64Binop(kExprI64Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011);
    395   TestInt64Binop(kExprI64Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE);
    396   TestInt64Binop(kExprI64Shl, 0xA0000000, 0xA, 28);
    397   TestInt64Binop(kExprI64ShrU, 0x0700001000123456LL, 0x7000010001234567LL, 4);
    398   TestInt64Binop(kExprI64ShrS, 0xFF00000000000000LL, 0x8000000000000000LL, 7);
    399   TestInt64Cmp(kExprI64Eq, 1, -9999, -9999);
    400   TestInt64Cmp(kExprI64Ne, 1, -9199, -9999);
    401   TestInt64Cmp(kExprI64LtS, 1, -4, 4);
    402   TestInt64Cmp(kExprI64LeS, 0, -2, -3);
    403   TestInt64Cmp(kExprI64LtU, 1, 0, -6);
    404   TestInt64Cmp(kExprI64LeU, 1, 98978, 0xF0000000);
    405 }
    406 
    407 
    408 TEST(Run_WasmInt64Clz) {
    409   struct {
    410     int64_t expected;
    411     uint64_t input;
    412   } values[] = {{0, 0x8000100000000000},  {1, 0x4000050000000000},
    413                 {2, 0x2000030000000000},  {3, 0x1000000300000000},
    414                 {4, 0x0805000000000000},  {5, 0x0400600000000000},
    415                 {6, 0x0200000000000000},  {7, 0x010000a000000000},
    416                 {8, 0x00800c0000000000},  {9, 0x0040000000000000},
    417                 {10, 0x0020000d00000000}, {11, 0x00100f0000000000},
    418                 {12, 0x0008000000000000}, {13, 0x0004100000000000},
    419                 {14, 0x0002002000000000}, {15, 0x0001030000000000},
    420                 {16, 0x0000804000000000}, {17, 0x0000400500000000},
    421                 {18, 0x0000205000000000}, {19, 0x0000170000000000},
    422                 {20, 0x0000087000000000}, {21, 0x0000040500000000},
    423                 {22, 0x0000020300000000}, {23, 0x0000010100000000},
    424                 {24, 0x0000008900000000}, {25, 0x0000004100000000},
    425                 {26, 0x0000002200000000}, {27, 0x0000001300000000},
    426                 {28, 0x0000000800000000}, {29, 0x0000000400000000},
    427                 {30, 0x0000000200000000}, {31, 0x0000000100000000},
    428                 {32, 0x0000000080001000}, {33, 0x0000000040000500},
    429                 {34, 0x0000000020000300}, {35, 0x0000000010000003},
    430                 {36, 0x0000000008050000}, {37, 0x0000000004006000},
    431                 {38, 0x0000000002000000}, {39, 0x00000000010000a0},
    432                 {40, 0x0000000000800c00}, {41, 0x0000000000400000},
    433                 {42, 0x000000000020000d}, {43, 0x0000000000100f00},
    434                 {44, 0x0000000000080000}, {45, 0x0000000000041000},
    435                 {46, 0x0000000000020020}, {47, 0x0000000000010300},
    436                 {48, 0x0000000000008040}, {49, 0x0000000000004005},
    437                 {50, 0x0000000000002050}, {51, 0x0000000000001700},
    438                 {52, 0x0000000000000870}, {53, 0x0000000000000405},
    439                 {54, 0x0000000000000203}, {55, 0x0000000000000101},
    440                 {56, 0x0000000000000089}, {57, 0x0000000000000041},
    441                 {58, 0x0000000000000022}, {59, 0x0000000000000013},
    442                 {60, 0x0000000000000008}, {61, 0x0000000000000004},
    443                 {62, 0x0000000000000002}, {63, 0x0000000000000001},
    444                 {64, 0x0000000000000000}};
    445 
    446   WasmRunner<int64_t> r(MachineType::Uint64());
    447   BUILD(r, WASM_I64_CLZ(WASM_GET_LOCAL(0)));
    448   for (size_t i = 0; i < arraysize(values); i++) {
    449     CHECK_EQ(values[i].expected, r.Call(values[i].input));
    450   }
    451 }
    452 
    453 
    454 TEST(Run_WasmInt64Ctz) {
    455   struct {
    456     int64_t expected;
    457     uint64_t input;
    458   } values[] = {{64, 0x0000000000000000}, {63, 0x8000000000000000},
    459                 {62, 0x4000000000000000}, {61, 0x2000000000000000},
    460                 {60, 0x1000000000000000}, {59, 0xa800000000000000},
    461                 {58, 0xf400000000000000}, {57, 0x6200000000000000},
    462                 {56, 0x9100000000000000}, {55, 0xcd80000000000000},
    463                 {54, 0x0940000000000000}, {53, 0xaf20000000000000},
    464                 {52, 0xac10000000000000}, {51, 0xe0b8000000000000},
    465                 {50, 0x9ce4000000000000}, {49, 0xc792000000000000},
    466                 {48, 0xb8f1000000000000}, {47, 0x3b9f800000000000},
    467                 {46, 0xdb4c400000000000}, {45, 0xe9a3200000000000},
    468                 {44, 0xfca6100000000000}, {43, 0x6c8a780000000000},
    469                 {42, 0x8ce5a40000000000}, {41, 0xcb7d020000000000},
    470                 {40, 0xcb4dc10000000000}, {39, 0xdfbec58000000000},
    471                 {38, 0x27a9db4000000000}, {37, 0xde3bcb2000000000},
    472                 {36, 0xd7e8a61000000000}, {35, 0x9afdbc8800000000},
    473                 {34, 0x9afdbc8400000000}, {33, 0x9afdbc8200000000},
    474                 {32, 0x9afdbc8100000000}, {31, 0x0000000080000000},
    475                 {30, 0x0000000040000000}, {29, 0x0000000020000000},
    476                 {28, 0x0000000010000000}, {27, 0x00000000a8000000},
    477                 {26, 0x00000000f4000000}, {25, 0x0000000062000000},
    478                 {24, 0x0000000091000000}, {23, 0x00000000cd800000},
    479                 {22, 0x0000000009400000}, {21, 0x00000000af200000},
    480                 {20, 0x00000000ac100000}, {19, 0x00000000e0b80000},
    481                 {18, 0x000000009ce40000}, {17, 0x00000000c7920000},
    482                 {16, 0x00000000b8f10000}, {15, 0x000000003b9f8000},
    483                 {14, 0x00000000db4c4000}, {13, 0x00000000e9a32000},
    484                 {12, 0x00000000fca61000}, {11, 0x000000006c8a7800},
    485                 {10, 0x000000008ce5a400}, {9, 0x00000000cb7d0200},
    486                 {8, 0x00000000cb4dc100},  {7, 0x00000000dfbec580},
    487                 {6, 0x0000000027a9db40},  {5, 0x00000000de3bcb20},
    488                 {4, 0x00000000d7e8a610},  {3, 0x000000009afdbc88},
    489                 {2, 0x000000009afdbc84},  {1, 0x000000009afdbc82},
    490                 {0, 0x000000009afdbc81}};
    491 
    492   WasmRunner<int64_t> r(MachineType::Uint64());
    493   BUILD(r, WASM_I64_CTZ(WASM_GET_LOCAL(0)));
    494   for (size_t i = 0; i < arraysize(values); i++) {
    495     CHECK_EQ(values[i].expected, r.Call(values[i].input));
    496   }
    497 }
    498 
    499 
    500 TEST(Run_WasmInt64Popcnt) {
    501   struct {
    502     int64_t expected;
    503     uint64_t input;
    504   } values[] = {{64, 0xffffffffffffffff},
    505                 {0, 0x0000000000000000},
    506                 {2, 0x0000080000008000},
    507                 {26, 0x1123456782345678},
    508                 {38, 0xffedcba09edcba09}};
    509 
    510   WasmRunner<int64_t> r(MachineType::Uint64());
    511   BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0)));
    512   for (size_t i = 0; i < arraysize(values); i++) {
    513     CHECK_EQ(values[i].expected, r.Call(values[i].input));
    514   }
    515 }
    516 
    517 
    518 #endif
    519 
    520 TEST(Run_WASM_Int32DivS_trap) {
    521   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    522   BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    523   CHECK_EQ(0, r.Call(0, 100));
    524   CHECK_TRAP(r.Call(100, 0));
    525   CHECK_TRAP(r.Call(-1001, 0));
    526   CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), -1));
    527   CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
    528 }
    529 
    530 
    531 TEST(Run_WASM_Int32RemS_trap) {
    532   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    533   BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    534   CHECK_EQ(33, r.Call(133, 100));
    535   CHECK_EQ(0, r.Call(std::numeric_limits<int32_t>::min(), -1));
    536   CHECK_TRAP(r.Call(100, 0));
    537   CHECK_TRAP(r.Call(-1001, 0));
    538   CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
    539 }
    540 
    541 
    542 TEST(Run_WASM_Int32DivU_trap) {
    543   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    544   BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    545   CHECK_EQ(0, r.Call(0, 100));
    546   CHECK_EQ(0, r.Call(std::numeric_limits<int32_t>::min(), -1));
    547   CHECK_TRAP(r.Call(100, 0));
    548   CHECK_TRAP(r.Call(-1001, 0));
    549   CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
    550 }
    551 
    552 
    553 TEST(Run_WASM_Int32RemU_trap) {
    554   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    555   BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    556   CHECK_EQ(17, r.Call(217, 100));
    557   CHECK_TRAP(r.Call(100, 0));
    558   CHECK_TRAP(r.Call(-1001, 0));
    559   CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
    560   CHECK_EQ(std::numeric_limits<int32_t>::min(),
    561            r.Call(std::numeric_limits<int32_t>::min(), -1));
    562 }
    563 
    564 
    565 TEST(Run_WASM_Int32DivS_byzero_const) {
    566   for (int8_t denom = -2; denom < 8; denom++) {
    567     WasmRunner<int32_t> r(MachineType::Int32());
    568     BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
    569     for (int32_t val = -7; val < 8; val++) {
    570       if (denom == 0) {
    571         CHECK_TRAP(r.Call(val));
    572       } else {
    573         CHECK_EQ(val / denom, r.Call(val));
    574       }
    575     }
    576   }
    577 }
    578 
    579 
    580 TEST(Run_WASM_Int32DivU_byzero_const) {
    581   for (uint32_t denom = 0xfffffffe; denom < 8; denom++) {
    582     WasmRunner<uint32_t> r(MachineType::Uint32());
    583     BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32(denom)));
    584 
    585     for (uint32_t val = 0xfffffff0; val < 8; val++) {
    586       if (denom == 0) {
    587         CHECK_TRAP(r.Call(val));
    588       } else {
    589         CHECK_EQ(val / denom, r.Call(val));
    590       }
    591     }
    592   }
    593 }
    594 
    595 
    596 TEST(Run_WASM_Int32DivS_trap_effect) {
    597   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
    598   TestingModule module;
    599   module.AddMemoryElems<int32_t>(8);
    600   r.env()->module = &module;
    601 
    602   BUILD(r,
    603         WASM_IF_ELSE(WASM_GET_LOCAL(0),
    604                      WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
    605                                                   WASM_ZERO, WASM_GET_LOCAL(0)),
    606                                    WASM_GET_LOCAL(1)),
    607                      WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
    608                                                   WASM_ZERO, WASM_GET_LOCAL(0)),
    609                                    WASM_GET_LOCAL(1))));
    610   CHECK_EQ(0, r.Call(0, 100));
    611   CHECK_TRAP(r.Call(8, 0));
    612   CHECK_TRAP(r.Call(4, 0));
    613   CHECK_TRAP(r.Call(0, 0));
    614 }
    615 
    616 
    617 #if WASM_64
    618 #define as64(x) static_cast<int64_t>(x)
    619 TEST(Run_WASM_Int64DivS_trap) {
    620   WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
    621   BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    622   CHECK_EQ(0, r.Call(as64(0), as64(100)));
    623   CHECK_TRAP64(r.Call(as64(100), as64(0)));
    624   CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
    625   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
    626   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
    627 }
    628 
    629 
    630 TEST(Run_WASM_Int64RemS_trap) {
    631   WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
    632   BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    633   CHECK_EQ(33, r.Call(as64(133), as64(100)));
    634   CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
    635   CHECK_TRAP64(r.Call(as64(100), as64(0)));
    636   CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
    637   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
    638 }
    639 
    640 
    641 TEST(Run_WASM_Int64DivU_trap) {
    642   WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
    643   BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    644   CHECK_EQ(0, r.Call(as64(0), as64(100)));
    645   CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
    646   CHECK_TRAP64(r.Call(as64(100), as64(0)));
    647   CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
    648   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
    649 }
    650 
    651 
    652 TEST(Run_WASM_Int64RemU_trap) {
    653   WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
    654   BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    655   CHECK_EQ(17, r.Call(as64(217), as64(100)));
    656   CHECK_TRAP64(r.Call(as64(100), as64(0)));
    657   CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
    658   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
    659   CHECK_EQ(std::numeric_limits<int64_t>::min(),
    660            r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
    661 }
    662 
    663 
    664 TEST(Run_WASM_Int64DivS_byzero_const) {
    665   for (int8_t denom = -2; denom < 8; denom++) {
    666     WasmRunner<int64_t> r(MachineType::Int64());
    667     BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64(denom)));
    668     for (int64_t val = -7; val < 8; val++) {
    669       if (denom == 0) {
    670         CHECK_TRAP64(r.Call(val));
    671       } else {
    672         CHECK_EQ(val / denom, r.Call(val));
    673       }
    674     }
    675   }
    676 }
    677 
    678 
    679 TEST(Run_WASM_Int64DivU_byzero_const) {
    680   for (uint64_t denom = 0xfffffffffffffffe; denom < 8; denom++) {
    681     WasmRunner<uint64_t> r(MachineType::Uint64());
    682     BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64(denom)));
    683 
    684     for (uint64_t val = 0xfffffffffffffff0; val < 8; val++) {
    685       if (denom == 0) {
    686         CHECK_TRAP64(r.Call(val));
    687       } else {
    688         CHECK_EQ(val / denom, r.Call(val));
    689       }
    690     }
    691   }
    692 }
    693 #endif
    694 
    695 
    696 void TestFloat32Binop(WasmOpcode opcode, int32_t expected, float a, float b) {
    697   {
    698     WasmRunner<int32_t> r;
    699     // return K op K
    700     BUILD(r, WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b)));
    701     CHECK_EQ(expected, r.Call());
    702   }
    703   {
    704     WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
    705     // return a op b
    706     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    707     CHECK_EQ(expected, r.Call(a, b));
    708   }
    709 }
    710 
    711 
    712 void TestFloat32BinopWithConvert(WasmOpcode opcode, int32_t expected, float a,
    713                                  float b) {
    714   {
    715     WasmRunner<int32_t> r;
    716     // return int(K op K)
    717     BUILD(r,
    718           WASM_I32_SCONVERT_F32(WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b))));
    719     CHECK_EQ(expected, r.Call());
    720   }
    721   {
    722     WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
    723     // return int(a op b)
    724     BUILD(r, WASM_I32_SCONVERT_F32(
    725                  WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
    726     CHECK_EQ(expected, r.Call(a, b));
    727   }
    728 }
    729 
    730 
    731 void TestFloat32UnopWithConvert(WasmOpcode opcode, int32_t expected, float a) {
    732   {
    733     WasmRunner<int32_t> r;
    734     // return int(op(K))
    735     BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_F32(a))));
    736     CHECK_EQ(expected, r.Call());
    737   }
    738   {
    739     WasmRunner<int32_t> r(MachineType::Float32());
    740     // return int(op(a))
    741     BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
    742     CHECK_EQ(expected, r.Call(a));
    743   }
    744 }
    745 
    746 
    747 void TestFloat64Binop(WasmOpcode opcode, int32_t expected, double a, double b) {
    748   {
    749     WasmRunner<int32_t> r;
    750     // return K op K
    751     BUILD(r, WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b)));
    752     CHECK_EQ(expected, r.Call());
    753   }
    754   {
    755     WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
    756     // return a op b
    757     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
    758     CHECK_EQ(expected, r.Call(a, b));
    759   }
    760 }
    761 
    762 
    763 void TestFloat64BinopWithConvert(WasmOpcode opcode, int32_t expected, double a,
    764                                  double b) {
    765   {
    766     WasmRunner<int32_t> r;
    767     // return int(K op K)
    768     BUILD(r,
    769           WASM_I32_SCONVERT_F64(WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b))));
    770     CHECK_EQ(expected, r.Call());
    771   }
    772   {
    773     WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
    774     BUILD(r, WASM_I32_SCONVERT_F64(
    775                  WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
    776     CHECK_EQ(expected, r.Call(a, b));
    777   }
    778 }
    779 
    780 
    781 void TestFloat64UnopWithConvert(WasmOpcode opcode, int32_t expected, double a) {
    782   {
    783     WasmRunner<int32_t> r;
    784     // return int(op(K))
    785     BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_F64(a))));
    786     CHECK_EQ(expected, r.Call());
    787   }
    788   {
    789     WasmRunner<int32_t> r(MachineType::Float64());
    790     // return int(op(a))
    791     BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
    792     CHECK_EQ(expected, r.Call(a));
    793   }
    794 }
    795 
    796 
    797 // TODO(titzer): Fix for nosee4 and re-enable.
    798 #if 0
    799 
    800 TEST(Run_WasmFloat32Binops) {
    801   TestFloat32Binop(kExprF32Eq, 1, 8.125f, 8.125f);
    802   TestFloat32Binop(kExprF32Ne, 1, 8.125f, 8.127f);
    803   TestFloat32Binop(kExprF32Lt, 1, -9.5f, -9.0f);
    804   TestFloat32Binop(kExprF32Le, 1, -1111.0f, -1111.0f);
    805   TestFloat32Binop(kExprF32Gt, 1, -9.0f, -9.5f);
    806   TestFloat32Binop(kExprF32Ge, 1, -1111.0f, -1111.0f);
    807 
    808   TestFloat32BinopWithConvert(kExprF32Add, 10, 3.5f, 6.5f);
    809   TestFloat32BinopWithConvert(kExprF32Sub, 2, 44.5f, 42.5f);
    810   TestFloat32BinopWithConvert(kExprF32Mul, -66, -132.1f, 0.5f);
    811   TestFloat32BinopWithConvert(kExprF32Div, 11, 22.1f, 2.0f);
    812 }
    813 
    814 
    815 TEST(Run_WasmFloat32Unops) {
    816   TestFloat32UnopWithConvert(kExprF32Abs, 8, 8.125f);
    817   TestFloat32UnopWithConvert(kExprF32Abs, 9, -9.125f);
    818   TestFloat32UnopWithConvert(kExprF32Neg, -213, 213.125f);
    819   TestFloat32UnopWithConvert(kExprF32Sqrt, 12, 144.4f);
    820 }
    821 
    822 
    823 TEST(Run_WasmFloat64Binops) {
    824   TestFloat64Binop(kExprF64Eq, 1, 16.25, 16.25);
    825   TestFloat64Binop(kExprF64Ne, 1, 16.25, 16.15);
    826   TestFloat64Binop(kExprF64Lt, 1, -32.4, 11.7);
    827   TestFloat64Binop(kExprF64Le, 1, -88.9, -88.9);
    828   TestFloat64Binop(kExprF64Gt, 1, 11.7, -32.4);
    829   TestFloat64Binop(kExprF64Ge, 1, -88.9, -88.9);
    830 
    831   TestFloat64BinopWithConvert(kExprF64Add, 100, 43.5, 56.5);
    832   TestFloat64BinopWithConvert(kExprF64Sub, 200, 12200.1, 12000.1);
    833   TestFloat64BinopWithConvert(kExprF64Mul, -33, 134, -0.25);
    834   TestFloat64BinopWithConvert(kExprF64Div, -1111, -2222.3, 2);
    835 }
    836 
    837 
    838 TEST(Run_WasmFloat64Unops) {
    839   TestFloat64UnopWithConvert(kExprF64Abs, 108, 108.125);
    840   TestFloat64UnopWithConvert(kExprF64Abs, 209, -209.125);
    841   TestFloat64UnopWithConvert(kExprF64Neg, -209, 209.125);
    842   TestFloat64UnopWithConvert(kExprF64Sqrt, 13, 169.4);
    843 }
    844 
    845 #endif
    846 
    847 
    848 TEST(Run_WasmFloat32Neg) {
    849   WasmRunner<float> r(MachineType::Float32());
    850   BUILD(r, WASM_F32_NEG(WASM_GET_LOCAL(0)));
    851 
    852   FOR_FLOAT32_INPUTS(i) {
    853     CHECK_EQ(0x80000000,
    854              bit_cast<uint32_t>(*i) ^ bit_cast<uint32_t>(r.Call(*i)));
    855   }
    856 }
    857 
    858 
    859 TEST(Run_WasmFloat64Neg) {
    860   WasmRunner<double> r(MachineType::Float64());
    861   BUILD(r, WASM_F64_NEG(WASM_GET_LOCAL(0)));
    862 
    863   FOR_FLOAT64_INPUTS(i) {
    864     CHECK_EQ(0x8000000000000000,
    865              bit_cast<uint64_t>(*i) ^ bit_cast<uint64_t>(r.Call(*i)));
    866   }
    867 }
    868 
    869 
    870 TEST(Run_Wasm_IfElse_P) {
    871   WasmRunner<int32_t> r(MachineType::Int32());
    872   // if (p0) return 11; else return 22;
    873   BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0),  // --
    874                         WASM_I8(11),        // --
    875                         WASM_I8(22)));      // --
    876   FOR_INT32_INPUTS(i) {
    877     int32_t expected = *i ? 11 : 22;
    878     CHECK_EQ(expected, r.Call(*i));
    879   }
    880 }
    881 
    882 
    883 TEST(Run_Wasm_IfElse_Unreachable1) {
    884   WasmRunner<int32_t> r;
    885   // if (0) unreachable; else return 22;
    886   BUILD(r, WASM_IF_ELSE(WASM_ZERO,         // --
    887                         WASM_UNREACHABLE,  // --
    888                         WASM_I8(27)));     // --
    889   CHECK_EQ(27, r.Call());
    890 }
    891 
    892 
    893 TEST(Run_Wasm_Return12) {
    894   WasmRunner<int32_t> r;
    895 
    896   BUILD(r, WASM_RETURN(WASM_I8(12)));
    897   CHECK_EQ(12, r.Call());
    898 }
    899 
    900 
    901 TEST(Run_Wasm_Return17) {
    902   WasmRunner<int32_t> r;
    903 
    904   BUILD(r, WASM_BLOCK(1, WASM_RETURN(WASM_I8(17))));
    905   CHECK_EQ(17, r.Call());
    906 }
    907 
    908 
    909 TEST(Run_Wasm_Return_I32) {
    910   WasmRunner<int32_t> r(MachineType::Int32());
    911 
    912   BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
    913 
    914   FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
    915 }
    916 
    917 
    918 #if WASM_64
    919 TEST(Run_Wasm_Return_I64) {
    920   WasmRunner<int64_t> r(MachineType::Int64());
    921 
    922   BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
    923 
    924   FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
    925 }
    926 #endif
    927 
    928 
    929 TEST(Run_Wasm_Return_F32) {
    930   WasmRunner<float> r(MachineType::Float32());
    931 
    932   BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
    933 
    934   FOR_FLOAT32_INPUTS(i) {
    935     float expect = *i;
    936     float result = r.Call(expect);
    937     if (std::isnan(expect)) {
    938       CHECK(std::isnan(result));
    939     } else {
    940       CHECK_EQ(expect, result);
    941     }
    942   }
    943 }
    944 
    945 
    946 TEST(Run_Wasm_Return_F64) {
    947   WasmRunner<double> r(MachineType::Float64());
    948 
    949   BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
    950 
    951   FOR_FLOAT64_INPUTS(i) {
    952     double expect = *i;
    953     double result = r.Call(expect);
    954     if (std::isnan(expect)) {
    955       CHECK(std::isnan(result));
    956     } else {
    957       CHECK_EQ(expect, result);
    958     }
    959   }
    960 }
    961 
    962 
    963 TEST(Run_Wasm_Select) {
    964   WasmRunner<int32_t> r(MachineType::Int32());
    965   // return select(a, 11, 22);
    966   BUILD(r, WASM_SELECT(WASM_GET_LOCAL(0), WASM_I8(11), WASM_I8(22)));
    967   FOR_INT32_INPUTS(i) {
    968     int32_t expected = *i ? 11 : 22;
    969     CHECK_EQ(expected, r.Call(*i));
    970   }
    971 }
    972 
    973 
    974 TEST(Run_Wasm_Select_strict1) {
    975   WasmRunner<int32_t> r(MachineType::Int32());
    976   // select(a, a = 11, 22); return a
    977   BUILD(r,
    978         WASM_BLOCK(2, WASM_SELECT(WASM_GET_LOCAL(0),
    979                                   WASM_SET_LOCAL(0, WASM_I8(11)), WASM_I8(22)),
    980                    WASM_GET_LOCAL(0)));
    981   FOR_INT32_INPUTS(i) { CHECK_EQ(11, r.Call(*i)); }
    982 }
    983 
    984 
    985 TEST(Run_Wasm_Select_strict2) {
    986   WasmRunner<int32_t> r(MachineType::Int32());
    987   // select(a, 11, a = 22); return a;
    988   BUILD(r, WASM_BLOCK(2, WASM_SELECT(WASM_GET_LOCAL(0), WASM_I8(11),
    989                                      WASM_SET_LOCAL(0, WASM_I8(22))),
    990                       WASM_GET_LOCAL(0)));
    991   FOR_INT32_INPUTS(i) { CHECK_EQ(22, r.Call(*i)); }
    992 }
    993 
    994 
    995 TEST(Run_Wasm_BrIf_strict) {
    996   WasmRunner<int32_t> r(MachineType::Int32());
    997   BUILD(r, WASM_BLOCK(
    998                2, WASM_BLOCK(1, WASM_BRV_IF(0, WASM_GET_LOCAL(0),
    999                                             WASM_SET_LOCAL(0, WASM_I8(99)))),
   1000                WASM_GET_LOCAL(0)));
   1001 
   1002   FOR_INT32_INPUTS(i) { CHECK_EQ(99, r.Call(*i)); }
   1003 }
   1004 
   1005 
   1006 TEST(Run_Wasm_TableSwitch1) {
   1007   WasmRunner<int32_t> r(MachineType::Int32());
   1008   BUILD(r, WASM_TABLESWITCH_OP(1, 1, WASM_CASE(0)),
   1009         WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(93))));
   1010   FOR_INT32_INPUTS(i) { CHECK_EQ(93, r.Call(*i)); }
   1011 }
   1012 
   1013 
   1014 TEST(Run_Wasm_TableSwitch_br) {
   1015   WasmRunner<int32_t> r(MachineType::Int32());
   1016   BUILD(r, WASM_TABLESWITCH_OP(1, 2, WASM_CASE_BR(0), WASM_CASE(0)),
   1017         WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(91))),
   1018         WASM_I8(99));
   1019   CHECK_EQ(99, r.Call(0));
   1020   CHECK_EQ(91, r.Call(1));
   1021   CHECK_EQ(91, r.Call(2));
   1022   CHECK_EQ(91, r.Call(3));
   1023 }
   1024 
   1025 
   1026 TEST(Run_Wasm_TableSwitch_br2) {
   1027   WasmRunner<int32_t> r(MachineType::Int32());
   1028   BUILD(r, WASM_BLOCK(
   1029                2, WASM_BLOCK(2, WASM_TABLESWITCH_OP(
   1030                                     1, 4, WASM_CASE_BR(0), WASM_CASE_BR(1),
   1031                                     WASM_CASE_BR(2), WASM_CASE(0)),
   1032                              WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0),
   1033                                                    WASM_RETURN(WASM_I8(85))),
   1034                              WASM_RETURN(WASM_I8(86))),
   1035                WASM_RETURN(WASM_I8(87))),
   1036         WASM_I8(88));
   1037   CHECK_EQ(86, r.Call(0));
   1038   CHECK_EQ(87, r.Call(1));
   1039   CHECK_EQ(88, r.Call(2));
   1040   CHECK_EQ(85, r.Call(3));
   1041   CHECK_EQ(85, r.Call(4));
   1042   CHECK_EQ(85, r.Call(5));
   1043 }
   1044 
   1045 
   1046 TEST(Run_Wasm_TableSwitch2) {
   1047   WasmRunner<int32_t> r(MachineType::Int32());
   1048   BUILD(r, WASM_TABLESWITCH_OP(2, 2, WASM_CASE(0), WASM_CASE(1)),
   1049         WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(91)),
   1050                               WASM_RETURN(WASM_I8(92))));
   1051   FOR_INT32_INPUTS(i) {
   1052     int32_t expected = *i == 0 ? 91 : 92;
   1053     CHECK_EQ(expected, r.Call(*i));
   1054   }
   1055 }
   1056 
   1057 
   1058 TEST(Run_Wasm_TableSwitch2b) {
   1059   WasmRunner<int32_t> r(MachineType::Int32());
   1060   BUILD(r, WASM_TABLESWITCH_OP(2, 2, WASM_CASE(1), WASM_CASE(0)),
   1061         WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(81)),
   1062                               WASM_RETURN(WASM_I8(82))));
   1063   FOR_INT32_INPUTS(i) {
   1064     int32_t expected = *i == 0 ? 82 : 81;
   1065     CHECK_EQ(expected, r.Call(*i));
   1066   }
   1067 }
   1068 
   1069 
   1070 TEST(Run_Wasm_TableSwitch4) {
   1071   for (int i = 0; i < 4; i++) {
   1072     const uint16_t br = 0x8000u;
   1073     uint16_t c = 0;
   1074     uint16_t cases[] = {i == 0 ? br : c++, i == 1 ? br : c++, i == 2 ? br : c++,
   1075                         i == 3 ? br : c++};
   1076     byte code[] = {
   1077         WASM_BLOCK(1, WASM_TABLESWITCH_OP(
   1078                           3, 4, WASM_CASE(cases[0]), WASM_CASE(cases[1]),
   1079                           WASM_CASE(cases[2]), WASM_CASE(cases[3])),
   1080                    WASM_TABLESWITCH_BODY(
   1081                        WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(71)),
   1082                        WASM_RETURN(WASM_I8(72)), WASM_RETURN(WASM_I8(73)))),
   1083         WASM_RETURN(WASM_I8(74))};
   1084 
   1085     WasmRunner<int32_t> r(MachineType::Int32());
   1086     r.Build(code, code + arraysize(code));
   1087 
   1088     FOR_INT32_INPUTS(i) {
   1089       int index = (*i < 0 || *i > 3) ? 3 : *i;
   1090       int32_t expected = 71 + cases[index];
   1091       if (expected >= 0x8000) expected = 74;
   1092       CHECK_EQ(expected, r.Call(*i));
   1093     }
   1094   }
   1095 }
   1096 
   1097 
   1098 TEST(Run_Wasm_TableSwitch4b) {
   1099   for (int a = 0; a < 2; a++) {
   1100     for (int b = 0; b < 2; b++) {
   1101       for (int c = 0; c < 2; c++) {
   1102         for (int d = 0; d < 2; d++) {
   1103           if (a + b + c + d == 0) continue;
   1104           if (a + b + c + d == 4) continue;
   1105 
   1106           byte code[] = {
   1107               WASM_TABLESWITCH_OP(2, 4, WASM_CASE(a), WASM_CASE(b),
   1108                                   WASM_CASE(c), WASM_CASE(d)),
   1109               WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(61)),
   1110                                     WASM_RETURN(WASM_I8(62)))};
   1111 
   1112           WasmRunner<int32_t> r(MachineType::Int32());
   1113           r.Build(code, code + arraysize(code));
   1114 
   1115           CHECK_EQ(61 + a, r.Call(0));
   1116           CHECK_EQ(61 + b, r.Call(1));
   1117           CHECK_EQ(61 + c, r.Call(2));
   1118           CHECK_EQ(61 + d, r.Call(3));
   1119           CHECK_EQ(61 + d, r.Call(4));
   1120         }
   1121       }
   1122     }
   1123   }
   1124 }
   1125 
   1126 
   1127 TEST(Run_Wasm_TableSwitch4_fallthru) {
   1128   byte code[] = {
   1129       WASM_TABLESWITCH_OP(4, 4, WASM_CASE(0), WASM_CASE(1), WASM_CASE(2),
   1130                           WASM_CASE(3)),
   1131       WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_INC_LOCAL_BY(1, 1),
   1132                             WASM_INC_LOCAL_BY(1, 2), WASM_INC_LOCAL_BY(1, 4),
   1133                             WASM_INC_LOCAL_BY(1, 8)),
   1134       WASM_GET_LOCAL(1)};
   1135 
   1136   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
   1137   r.Build(code, code + arraysize(code));
   1138 
   1139   CHECK_EQ(15, r.Call(0, 0));
   1140   CHECK_EQ(14, r.Call(1, 0));
   1141   CHECK_EQ(12, r.Call(2, 0));
   1142   CHECK_EQ(8, r.Call(3, 0));
   1143   CHECK_EQ(8, r.Call(4, 0));
   1144 
   1145   CHECK_EQ(115, r.Call(0, 100));
   1146   CHECK_EQ(114, r.Call(1, 100));
   1147   CHECK_EQ(112, r.Call(2, 100));
   1148   CHECK_EQ(108, r.Call(3, 100));
   1149   CHECK_EQ(108, r.Call(4, 100));
   1150 }
   1151 
   1152 
   1153 TEST(Run_Wasm_TableSwitch4_fallthru_br) {
   1154   byte code[] = {
   1155       WASM_TABLESWITCH_OP(4, 4, WASM_CASE(0), WASM_CASE(1), WASM_CASE(2),
   1156                           WASM_CASE(3)),
   1157       WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_INC_LOCAL_BY(1, 1),
   1158                             WASM_BRV(0, WASM_INC_LOCAL_BY(1, 2)),
   1159                             WASM_INC_LOCAL_BY(1, 4),
   1160                             WASM_BRV(0, WASM_INC_LOCAL_BY(1, 8))),
   1161       WASM_GET_LOCAL(1)};
   1162 
   1163   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
   1164   r.Build(code, code + arraysize(code));
   1165 
   1166   CHECK_EQ(3, r.Call(0, 0));
   1167   CHECK_EQ(2, r.Call(1, 0));
   1168   CHECK_EQ(12, r.Call(2, 0));
   1169   CHECK_EQ(8, r.Call(3, 0));
   1170   CHECK_EQ(8, r.Call(4, 0));
   1171 
   1172   CHECK_EQ(203, r.Call(0, 200));
   1173   CHECK_EQ(202, r.Call(1, 200));
   1174   CHECK_EQ(212, r.Call(2, 200));
   1175   CHECK_EQ(208, r.Call(3, 200));
   1176   CHECK_EQ(208, r.Call(4, 200));
   1177 }
   1178 
   1179 
   1180 TEST(Run_Wasm_F32ReinterpretI32) {
   1181   WasmRunner<int32_t> r;
   1182   TestingModule module;
   1183   int32_t* memory = module.AddMemoryElems<int32_t>(8);
   1184   r.env()->module = &module;
   1185 
   1186   BUILD(r, WASM_I32_REINTERPRET_F32(
   1187                WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)));
   1188 
   1189   FOR_INT32_INPUTS(i) {
   1190     int32_t expected = *i;
   1191     memory[0] = expected;
   1192     CHECK_EQ(expected, r.Call());
   1193   }
   1194 }
   1195 
   1196 
   1197 TEST(Run_Wasm_I32ReinterpretF32) {
   1198   WasmRunner<int32_t> r(MachineType::Int32());
   1199   TestingModule module;
   1200   int32_t* memory = module.AddMemoryElems<int32_t>(8);
   1201   r.env()->module = &module;
   1202 
   1203   BUILD(r, WASM_BLOCK(
   1204                2, WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
   1205                                  WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))),
   1206                WASM_I8(107)));
   1207 
   1208   FOR_INT32_INPUTS(i) {
   1209     int32_t expected = *i;
   1210     CHECK_EQ(107, r.Call(expected));
   1211     CHECK_EQ(expected, memory[0]);
   1212   }
   1213 }
   1214 
   1215 
   1216 TEST(Run_Wasm_ReturnStore) {
   1217   WasmRunner<int32_t> r;
   1218   TestingModule module;
   1219   int32_t* memory = module.AddMemoryElems<int32_t>(8);
   1220   r.env()->module = &module;
   1221 
   1222   BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
   1223                           WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
   1224 
   1225   FOR_INT32_INPUTS(i) {
   1226     int32_t expected = *i;
   1227     memory[0] = expected;
   1228     CHECK_EQ(expected, r.Call());
   1229   }
   1230 }
   1231 
   1232 
   1233 TEST(Run_Wasm_VoidReturn1) {
   1234   WasmRunner<void> r;
   1235   BUILD(r, kExprNop);
   1236   r.Call();
   1237 }
   1238 
   1239 
   1240 TEST(Run_Wasm_VoidReturn2) {
   1241   WasmRunner<void> r;
   1242   BUILD(r, WASM_RETURN0);
   1243   r.Call();
   1244 }
   1245 
   1246 
   1247 TEST(Run_Wasm_Block_If_P) {
   1248   WasmRunner<int32_t> r(MachineType::Int32());
   1249   // { if (p0) return 51; return 52; }
   1250   BUILD(r, WASM_BLOCK(2,                                  // --
   1251                       WASM_IF(WASM_GET_LOCAL(0),          // --
   1252                               WASM_BRV(0, WASM_I8(51))),  // --
   1253                       WASM_I8(52)));                      // --
   1254   FOR_INT32_INPUTS(i) {
   1255     int32_t expected = *i ? 51 : 52;
   1256     CHECK_EQ(expected, r.Call(*i));
   1257   }
   1258 }
   1259 
   1260 
   1261 TEST(Run_Wasm_Block_BrIf_P) {
   1262   WasmRunner<int32_t> r(MachineType::Int32());
   1263   BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(51)),
   1264                       WASM_I8(52)));
   1265   FOR_INT32_INPUTS(i) {
   1266     int32_t expected = *i ? 51 : 52;
   1267     CHECK_EQ(expected, r.Call(*i));
   1268   }
   1269 }
   1270 
   1271 
   1272 TEST(Run_Wasm_Block_IfElse_P_assign) {
   1273   WasmRunner<int32_t> r(MachineType::Int32());
   1274   // { if (p0) p0 = 71; else p0 = 72; return p0; }
   1275   BUILD(r, WASM_BLOCK(2,                                             // --
   1276                       WASM_IF_ELSE(WASM_GET_LOCAL(0),                // --
   1277                                    WASM_SET_LOCAL(0, WASM_I8(71)),   // --
   1278                                    WASM_SET_LOCAL(0, WASM_I8(72))),  // --
   1279                       WASM_GET_LOCAL(0)));
   1280   FOR_INT32_INPUTS(i) {
   1281     int32_t expected = *i ? 71 : 72;
   1282     CHECK_EQ(expected, r.Call(*i));
   1283   }
   1284 }
   1285 
   1286 
   1287 TEST(Run_Wasm_Block_IfElse_P_return) {
   1288   WasmRunner<int32_t> r(MachineType::Int32());
   1289   // if (p0) return 81; else return 82;
   1290   BUILD(r,                                        // --
   1291         WASM_IF_ELSE(WASM_GET_LOCAL(0),           // --
   1292                      WASM_RETURN(WASM_I8(81)),    // --
   1293                      WASM_RETURN(WASM_I8(82))));  // --
   1294   FOR_INT32_INPUTS(i) {
   1295     int32_t expected = *i ? 81 : 82;
   1296     CHECK_EQ(expected, r.Call(*i));
   1297   }
   1298 }
   1299 
   1300 
   1301 TEST(Run_Wasm_Block_If_P_assign) {
   1302   WasmRunner<int32_t> r(MachineType::Int32());
   1303   // { if (p0) p0 = 61; p0; }
   1304   BUILD(r, WASM_BLOCK(
   1305                2, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(61))),
   1306                WASM_GET_LOCAL(0)));
   1307   FOR_INT32_INPUTS(i) {
   1308     int32_t expected = *i ? 61 : *i;
   1309     CHECK_EQ(expected, r.Call(*i));
   1310   }
   1311 }
   1312 
   1313 
   1314 TEST(Run_Wasm_DanglingAssign) {
   1315   WasmRunner<int32_t> r(MachineType::Int32());
   1316   // { return 0; p0 = 0; }
   1317   BUILD(r,
   1318         WASM_BLOCK(2, WASM_RETURN(WASM_I8(99)), WASM_SET_LOCAL(0, WASM_ZERO)));
   1319   CHECK_EQ(99, r.Call(1));
   1320 }
   1321 
   1322 
   1323 TEST(Run_Wasm_ExprIf_P) {
   1324   WasmRunner<int32_t> r(MachineType::Int32());
   1325   // p0 ? 11 : 22;
   1326   BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0),  // --
   1327                         WASM_I8(11),        // --
   1328                         WASM_I8(22)));      // --
   1329   FOR_INT32_INPUTS(i) {
   1330     int32_t expected = *i ? 11 : 22;
   1331     CHECK_EQ(expected, r.Call(*i));
   1332   }
   1333 }
   1334 
   1335 
   1336 TEST(Run_Wasm_ExprIf_P_fallthru) {
   1337   WasmRunner<int32_t> r(MachineType::Int32());
   1338   // p0 ? 11 : 22;
   1339   BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0),  // --
   1340                         WASM_I8(11),        // --
   1341                         WASM_I8(22)));      // --
   1342   FOR_INT32_INPUTS(i) {
   1343     int32_t expected = *i ? 11 : 22;
   1344     CHECK_EQ(expected, r.Call(*i));
   1345   }
   1346 }
   1347 
   1348 
   1349 TEST(Run_Wasm_CountDown) {
   1350   WasmRunner<int32_t> r(MachineType::Int32());
   1351   BUILD(r,
   1352         WASM_BLOCK(
   1353             2, WASM_LOOP(
   1354                    1, WASM_IF(WASM_GET_LOCAL(0),
   1355                               WASM_BRV(0, WASM_SET_LOCAL(
   1356                                               0, WASM_I32_SUB(WASM_GET_LOCAL(0),
   1357                                                               WASM_I8(1)))))),
   1358             WASM_GET_LOCAL(0)));
   1359   CHECK_EQ(0, r.Call(1));
   1360   CHECK_EQ(0, r.Call(10));
   1361   CHECK_EQ(0, r.Call(100));
   1362 }
   1363 
   1364 
   1365 TEST(Run_Wasm_CountDown_fallthru) {
   1366   WasmRunner<int32_t> r(MachineType::Int32());
   1367   BUILD(r,
   1368         WASM_BLOCK(
   1369             2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(0)),
   1370                          WASM_SET_LOCAL(
   1371                              0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
   1372                          WASM_CONTINUE(0)),
   1373             WASM_GET_LOCAL(0)));
   1374   CHECK_EQ(0, r.Call(1));
   1375   CHECK_EQ(0, r.Call(10));
   1376   CHECK_EQ(0, r.Call(100));
   1377 }
   1378 
   1379 
   1380 TEST(Run_Wasm_WhileCountDown) {
   1381   WasmRunner<int32_t> r(MachineType::Int32());
   1382   BUILD(r, WASM_BLOCK(
   1383                2, WASM_WHILE(WASM_GET_LOCAL(0),
   1384                              WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
   1385                                                             WASM_I8(1)))),
   1386                WASM_GET_LOCAL(0)));
   1387   CHECK_EQ(0, r.Call(1));
   1388   CHECK_EQ(0, r.Call(10));
   1389   CHECK_EQ(0, r.Call(100));
   1390 }
   1391 
   1392 
   1393 TEST(Run_Wasm_Loop_if_break1) {
   1394   WasmRunner<int32_t> r(MachineType::Int32());
   1395   BUILD(r, WASM_BLOCK(2, WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(0)),
   1396                                    WASM_SET_LOCAL(0, WASM_I8(99))),
   1397                       WASM_GET_LOCAL(0)));
   1398   CHECK_EQ(99, r.Call(0));
   1399   CHECK_EQ(3, r.Call(3));
   1400   CHECK_EQ(10000, r.Call(10000));
   1401   CHECK_EQ(-29, r.Call(-29));
   1402 }
   1403 
   1404 
   1405 TEST(Run_Wasm_Loop_if_break2) {
   1406   WasmRunner<int32_t> r(MachineType::Int32());
   1407   BUILD(r, WASM_BLOCK(2, WASM_LOOP(2, WASM_BR_IF(1, WASM_GET_LOCAL(0)),
   1408                                    WASM_SET_LOCAL(0, WASM_I8(99))),
   1409                       WASM_GET_LOCAL(0)));
   1410   CHECK_EQ(99, r.Call(0));
   1411   CHECK_EQ(3, r.Call(3));
   1412   CHECK_EQ(10000, r.Call(10000));
   1413   CHECK_EQ(-29, r.Call(-29));
   1414 }
   1415 
   1416 
   1417 TEST(Run_Wasm_Loop_if_break_fallthru) {
   1418   WasmRunner<int32_t> r(MachineType::Int32());
   1419   BUILD(r, WASM_BLOCK(1, WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)),
   1420                                    WASM_SET_LOCAL(0, WASM_I8(93)))),
   1421         WASM_GET_LOCAL(0));
   1422   CHECK_EQ(93, r.Call(0));
   1423   CHECK_EQ(3, r.Call(3));
   1424   CHECK_EQ(10001, r.Call(10001));
   1425   CHECK_EQ(-22, r.Call(-22));
   1426 }
   1427 
   1428 
   1429 TEST(Run_Wasm_LoadMemI32) {
   1430   WasmRunner<int32_t> r(MachineType::Int32());
   1431   TestingModule module;
   1432   int32_t* memory = module.AddMemoryElems<int32_t>(8);
   1433   module.RandomizeMemory(1111);
   1434   r.env()->module = &module;
   1435 
   1436   BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(0)));
   1437 
   1438   memory[0] = 99999999;
   1439   CHECK_EQ(99999999, r.Call(0));
   1440 
   1441   memory[0] = 88888888;
   1442   CHECK_EQ(88888888, r.Call(0));
   1443 
   1444   memory[0] = 77777777;
   1445   CHECK_EQ(77777777, r.Call(0));
   1446 }
   1447 
   1448 
   1449 TEST(Run_Wasm_LoadMemI32_oob) {
   1450   WasmRunner<int32_t> r(MachineType::Uint32());
   1451   TestingModule module;
   1452   int32_t* memory = module.AddMemoryElems<int32_t>(8);
   1453   module.RandomizeMemory(1111);
   1454   r.env()->module = &module;
   1455 
   1456   BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
   1457 
   1458   memory[0] = 88888888;
   1459   CHECK_EQ(88888888, r.Call(0u));
   1460   for (uint32_t offset = 29; offset < 40; offset++) {
   1461     CHECK_TRAP(r.Call(offset));
   1462   }
   1463 
   1464   for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
   1465     CHECK_TRAP(r.Call(offset));
   1466   }
   1467 }
   1468 
   1469 
   1470 TEST(Run_Wasm_LoadMemI32_oob_asm) {
   1471   WasmRunner<int32_t> r(MachineType::Uint32());
   1472   TestingModule module;
   1473   module.asm_js = true;
   1474   int32_t* memory = module.AddMemoryElems<int32_t>(8);
   1475   module.RandomizeMemory(1112);
   1476   r.env()->module = &module;
   1477 
   1478   BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
   1479 
   1480   memory[0] = 999999;
   1481   CHECK_EQ(999999, r.Call(0u));
   1482   // TODO(titzer): offset 29-31 should also be OOB.
   1483   for (uint32_t offset = 32; offset < 40; offset++) {
   1484     CHECK_EQ(0, r.Call(offset));
   1485   }
   1486 
   1487   for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
   1488     CHECK_EQ(0, r.Call(offset));
   1489   }
   1490 }
   1491 
   1492 
   1493 TEST(Run_Wasm_LoadMem_offset_oob) {
   1494   TestingModule module;
   1495   module.AddMemoryElems<int32_t>(8);
   1496 
   1497   static const MachineType machineTypes[] = {
   1498       MachineType::Int8(),   MachineType::Uint8(),  MachineType::Int16(),
   1499       MachineType::Uint16(), MachineType::Int32(),  MachineType::Uint32(),
   1500       MachineType::Int64(),  MachineType::Uint64(), MachineType::Float32(),
   1501       MachineType::Float64()};
   1502 
   1503   for (size_t m = 0; m < arraysize(machineTypes); m++) {
   1504     module.RandomizeMemory(1116 + static_cast<int>(m));
   1505     WasmRunner<int32_t> r(MachineType::Uint32());
   1506     r.env()->module = &module;
   1507     uint32_t boundary = 24 - WasmOpcodes::MemSize(machineTypes[m]);
   1508 
   1509     BUILD(r, WASM_LOAD_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0)),
   1510           WASM_ZERO);
   1511 
   1512     CHECK_EQ(0, r.Call(boundary));  // in bounds.
   1513 
   1514     for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
   1515       CHECK_TRAP(r.Call(offset));  // out of bounds.
   1516     }
   1517   }
   1518 }
   1519 
   1520 
   1521 TEST(Run_Wasm_LoadMemI32_offset) {
   1522   WasmRunner<int32_t> r(MachineType::Int32());
   1523   TestingModule module;
   1524   int32_t* memory = module.AddMemoryElems<int32_t>(4);
   1525   module.RandomizeMemory(1111);
   1526   r.env()->module = &module;
   1527 
   1528   BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0)));
   1529 
   1530   memory[0] = 66666666;
   1531   memory[1] = 77777777;
   1532   memory[2] = 88888888;
   1533   memory[3] = 99999999;
   1534   CHECK_EQ(77777777, r.Call(0));
   1535   CHECK_EQ(88888888, r.Call(4));
   1536   CHECK_EQ(99999999, r.Call(8));
   1537 
   1538   memory[0] = 11111111;
   1539   memory[1] = 22222222;
   1540   memory[2] = 33333333;
   1541   memory[3] = 44444444;
   1542   CHECK_EQ(22222222, r.Call(0));
   1543   CHECK_EQ(33333333, r.Call(4));
   1544   CHECK_EQ(44444444, r.Call(8));
   1545 }
   1546 
   1547 
   1548 // TODO(titzer): Fix for mips and re-enable.
   1549 #if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
   1550 
   1551 TEST(Run_Wasm_LoadMemI32_const_oob) {
   1552   TestingModule module;
   1553   const int kMemSize = 12;
   1554   module.AddMemoryElems<byte>(kMemSize);
   1555 
   1556   for (int offset = 0; offset < kMemSize + 5; offset++) {
   1557     for (int index = 0; index < kMemSize + 5; index++) {
   1558       WasmRunner<int32_t> r;
   1559       r.env()->module = &module;
   1560       module.RandomizeMemory();
   1561 
   1562       BUILD(r,
   1563             WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
   1564 
   1565       if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
   1566         CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
   1567       } else {
   1568         CHECK_TRAP(r.Call());
   1569       }
   1570     }
   1571   }
   1572 }
   1573 
   1574 #endif
   1575 
   1576 
   1577 TEST(Run_Wasm_StoreMemI32_offset) {
   1578   WasmRunner<int32_t> r(MachineType::Int32());
   1579   const int32_t kWritten = 0xaabbccdd;
   1580   TestingModule module;
   1581   int32_t* memory = module.AddMemoryElems<int32_t>(4);
   1582   r.env()->module = &module;
   1583 
   1584   BUILD(r, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0),
   1585                                  WASM_I32(kWritten)));
   1586 
   1587   for (int i = 0; i < 2; i++) {
   1588     module.RandomizeMemory(1111);
   1589     memory[0] = 66666666;
   1590     memory[1] = 77777777;
   1591     memory[2] = 88888888;
   1592     memory[3] = 99999999;
   1593     CHECK_EQ(kWritten, r.Call(i * 4));
   1594     CHECK_EQ(66666666, memory[0]);
   1595     CHECK_EQ(i == 0 ? kWritten : 77777777, memory[1]);
   1596     CHECK_EQ(i == 1 ? kWritten : 88888888, memory[2]);
   1597     CHECK_EQ(i == 2 ? kWritten : 99999999, memory[3]);
   1598   }
   1599 }
   1600 
   1601 
   1602 TEST(Run_Wasm_StoreMem_offset_oob) {
   1603   TestingModule module;
   1604   byte* memory = module.AddMemoryElems<byte>(32);
   1605 
   1606 #if WASM_64
   1607   static const MachineType machineTypes[] = {
   1608       MachineType::Int8(),   MachineType::Uint8(),  MachineType::Int16(),
   1609       MachineType::Uint16(), MachineType::Int32(),  MachineType::Uint32(),
   1610       MachineType::Int64(),  MachineType::Uint64(), MachineType::Float32(),
   1611       MachineType::Float64()};
   1612 #else
   1613   static const MachineType machineTypes[] = {
   1614       MachineType::Int8(),    MachineType::Uint8(),  MachineType::Int16(),
   1615       MachineType::Uint16(),  MachineType::Int32(),  MachineType::Uint32(),
   1616       MachineType::Float32(), MachineType::Float64()};
   1617 #endif
   1618 
   1619   for (size_t m = 0; m < arraysize(machineTypes); m++) {
   1620     module.RandomizeMemory(1119 + static_cast<int>(m));
   1621     WasmRunner<int32_t> r(MachineType::Uint32());
   1622     r.env()->module = &module;
   1623 
   1624     BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
   1625                                    WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
   1626           WASM_ZERO);
   1627 
   1628     byte memsize = WasmOpcodes::MemSize(machineTypes[m]);
   1629     uint32_t boundary = 24 - memsize;
   1630     CHECK_EQ(0, r.Call(boundary));  // in bounds.
   1631     CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize));
   1632 
   1633     for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
   1634       CHECK_TRAP(r.Call(offset));  // out of bounds.
   1635     }
   1636   }
   1637 }
   1638 
   1639 
   1640 #if WASM_64
   1641 TEST(Run_Wasm_F64ReinterpretI64) {
   1642   WasmRunner<int64_t> r;
   1643   TestingModule module;
   1644   int64_t* memory = module.AddMemoryElems<int64_t>(8);
   1645   r.env()->module = &module;
   1646 
   1647   BUILD(r, WASM_I64_REINTERPRET_F64(
   1648                WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)));
   1649 
   1650   FOR_INT32_INPUTS(i) {
   1651     int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
   1652     memory[0] = expected;
   1653     CHECK_EQ(expected, r.Call());
   1654   }
   1655 }
   1656 
   1657 
   1658 TEST(Run_Wasm_I64ReinterpretF64) {
   1659   WasmRunner<int64_t> r(MachineType::Int64());
   1660   TestingModule module;
   1661   int64_t* memory = module.AddMemoryElems<int64_t>(8);
   1662   r.env()->module = &module;
   1663 
   1664   BUILD(r, WASM_BLOCK(
   1665                2, WASM_STORE_MEM(MachineType::Float64(), WASM_ZERO,
   1666                                  WASM_F64_REINTERPRET_I64(WASM_GET_LOCAL(0))),
   1667                WASM_GET_LOCAL(0)));
   1668 
   1669   FOR_INT32_INPUTS(i) {
   1670     int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
   1671     CHECK_EQ(expected, r.Call(expected));
   1672     CHECK_EQ(expected, memory[0]);
   1673   }
   1674 }
   1675 
   1676 
   1677 TEST(Run_Wasm_LoadMemI64) {
   1678   WasmRunner<int64_t> r;
   1679   TestingModule module;
   1680   int64_t* memory = module.AddMemoryElems<int64_t>(8);
   1681   module.RandomizeMemory(1111);
   1682   r.env()->module = &module;
   1683 
   1684   BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_I8(0)));
   1685 
   1686   memory[0] = 0xaabbccdd00112233LL;
   1687   CHECK_EQ(0xaabbccdd00112233LL, r.Call());
   1688 
   1689   memory[0] = 0x33aabbccdd001122LL;
   1690   CHECK_EQ(0x33aabbccdd001122LL, r.Call());
   1691 
   1692   memory[0] = 77777777;
   1693   CHECK_EQ(77777777, r.Call());
   1694 }
   1695 #endif
   1696 
   1697 
   1698 TEST(Run_Wasm_LoadMemI32_P) {
   1699   const int kNumElems = 8;
   1700   WasmRunner<int32_t> r(MachineType::Int32());
   1701   TestingModule module;
   1702   int32_t* memory = module.AddMemoryElems<int32_t>(kNumElems);
   1703   module.RandomizeMemory(2222);
   1704   r.env()->module = &module;
   1705 
   1706   BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
   1707 
   1708   for (int i = 0; i < kNumElems; i++) {
   1709     CHECK_EQ(memory[i], r.Call(i * 4));
   1710   }
   1711 }
   1712 
   1713 
   1714 TEST(Run_Wasm_MemI32_Sum) {
   1715   WasmRunner<uint32_t> r(MachineType::Int32());
   1716   const int kNumElems = 20;
   1717   const byte kSum = r.AllocateLocal(kAstI32);
   1718   TestingModule module;
   1719   uint32_t* memory = module.AddMemoryElems<uint32_t>(kNumElems);
   1720   r.env()->module = &module;
   1721 
   1722   BUILD(r, WASM_BLOCK(
   1723                2, WASM_WHILE(
   1724                       WASM_GET_LOCAL(0),
   1725                       WASM_BLOCK(
   1726                           2, WASM_SET_LOCAL(
   1727                                  kSum, WASM_I32_ADD(
   1728                                            WASM_GET_LOCAL(kSum),
   1729                                            WASM_LOAD_MEM(MachineType::Int32(),
   1730                                                          WASM_GET_LOCAL(0)))),
   1731                           WASM_SET_LOCAL(
   1732                               0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
   1733                WASM_GET_LOCAL(1)));
   1734 
   1735   // Run 4 trials.
   1736   for (int i = 0; i < 3; i++) {
   1737     module.RandomizeMemory(i * 33);
   1738     uint32_t expected = 0;
   1739     for (size_t j = kNumElems - 1; j > 0; j--) {
   1740       expected += memory[j];
   1741     }
   1742     uint32_t result = r.Call(static_cast<int>(4 * (kNumElems - 1)));
   1743     CHECK_EQ(expected, result);
   1744   }
   1745 }
   1746 
   1747 
   1748 TEST(Run_Wasm_CheckMachIntsZero) {
   1749   WasmRunner<uint32_t> r(MachineType::Int32());
   1750   const int kNumElems = 55;
   1751   TestingModule module;
   1752   module.AddMemoryElems<uint32_t>(kNumElems);
   1753   r.env()->module = &module;
   1754 
   1755   BUILD(r, kExprBlock, 2, kExprLoop, 1, kExprIf, kExprGetLocal, 0, kExprBr, 0,
   1756         kExprIfElse, kExprI32LoadMem, 0, kExprGetLocal, 0, kExprBr, 2,
   1757         kExprI8Const, 255, kExprSetLocal, 0, kExprI32Sub, kExprGetLocal, 0,
   1758         kExprI8Const, 4, kExprI8Const, 0);
   1759 
   1760   module.BlankMemory();
   1761   CHECK_EQ(0, r.Call((kNumElems - 1) * 4));
   1762 }
   1763 
   1764 
   1765 TEST(Run_Wasm_MemF32_Sum) {
   1766   WasmRunner<int32_t> r(MachineType::Int32());
   1767   const byte kSum = r.AllocateLocal(kAstF32);
   1768   const int kSize = 5;
   1769   TestingModule module;
   1770   module.AddMemoryElems<float>(kSize);
   1771   float* buffer = module.raw_mem_start<float>();
   1772   buffer[0] = -99.25;
   1773   buffer[1] = -888.25;
   1774   buffer[2] = -77.25;
   1775   buffer[3] = 66666.25;
   1776   buffer[4] = 5555.25;
   1777   r.env()->module = &module;
   1778 
   1779   BUILD(r, WASM_BLOCK(
   1780                3, WASM_WHILE(
   1781                       WASM_GET_LOCAL(0),
   1782                       WASM_BLOCK(
   1783                           2, WASM_SET_LOCAL(
   1784                                  kSum, WASM_F32_ADD(
   1785                                            WASM_GET_LOCAL(kSum),
   1786                                            WASM_LOAD_MEM(MachineType::Float32(),
   1787                                                          WASM_GET_LOCAL(0)))),
   1788                           WASM_SET_LOCAL(
   1789                               0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
   1790                WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
   1791                               WASM_GET_LOCAL(kSum)),
   1792                WASM_GET_LOCAL(0)));
   1793 
   1794   CHECK_EQ(0, r.Call(4 * (kSize - 1)));
   1795   CHECK_NE(-99.25, buffer[0]);
   1796   CHECK_EQ(71256.0f, buffer[0]);
   1797 }
   1798 
   1799 
   1800 #if WASM_64
   1801 TEST(Run_Wasm_MemI64_Sum) {
   1802   WasmRunner<uint64_t> r(MachineType::Int32());
   1803   const int kNumElems = 20;
   1804   const byte kSum = r.AllocateLocal(kAstI64);
   1805   TestingModule module;
   1806   uint64_t* memory = module.AddMemoryElems<uint64_t>(kNumElems);
   1807   r.env()->module = &module;
   1808 
   1809   BUILD(r, WASM_BLOCK(
   1810                2, WASM_WHILE(
   1811                       WASM_GET_LOCAL(0),
   1812                       WASM_BLOCK(
   1813                           2, WASM_SET_LOCAL(
   1814                                  kSum, WASM_I64_ADD(
   1815                                            WASM_GET_LOCAL(kSum),
   1816                                            WASM_LOAD_MEM(MachineType::Int64(),
   1817                                                          WASM_GET_LOCAL(0)))),
   1818                           WASM_SET_LOCAL(
   1819                               0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(8))))),
   1820                WASM_GET_LOCAL(1)));
   1821 
   1822   // Run 4 trials.
   1823   for (int i = 0; i < 3; i++) {
   1824     module.RandomizeMemory(i * 33);
   1825     uint64_t expected = 0;
   1826     for (size_t j = kNumElems - 1; j > 0; j--) {
   1827       expected += memory[j];
   1828     }
   1829     uint64_t result = r.Call(8 * (kNumElems - 1));
   1830     CHECK_EQ(expected, result);
   1831   }
   1832 }
   1833 #endif
   1834 
   1835 
   1836 template <typename T>
   1837 T GenerateAndRunFold(WasmOpcode binop, T* buffer, size_t size,
   1838                      LocalType astType, MachineType memType) {
   1839   WasmRunner<int32_t> r(MachineType::Int32());
   1840   const byte kAccum = r.AllocateLocal(astType);
   1841   TestingModule module;
   1842   module.AddMemoryElems<T>(size);
   1843   for (size_t i = 0; i < size; i++) {
   1844     module.raw_mem_start<T>()[i] = buffer[i];
   1845   }
   1846   r.env()->module = &module;
   1847 
   1848   BUILD(
   1849       r,
   1850       WASM_BLOCK(
   1851           4, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)),
   1852           WASM_WHILE(
   1853               WASM_GET_LOCAL(0),
   1854               WASM_BLOCK(
   1855                   2, WASM_SET_LOCAL(
   1856                          kAccum,
   1857                          WASM_BINOP(binop, WASM_GET_LOCAL(kAccum),
   1858                                     WASM_LOAD_MEM(memType, WASM_GET_LOCAL(0)))),
   1859                   WASM_SET_LOCAL(
   1860                       0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(sizeof(T)))))),
   1861           WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)),
   1862           WASM_GET_LOCAL(0)));
   1863   r.Call(static_cast<int>(sizeof(T) * (size - 1)));
   1864   return module.raw_mem_at<double>(0);
   1865 }
   1866 
   1867 
   1868 TEST(Run_Wasm_MemF64_Mul) {
   1869   const size_t kSize = 6;
   1870   double buffer[kSize] = {1, 2, 2, 2, 2, 2};
   1871   double result = GenerateAndRunFold<double>(kExprF64Mul, buffer, kSize,
   1872                                              kAstF64, MachineType::Float64());
   1873   CHECK_EQ(32, result);
   1874 }
   1875 
   1876 
   1877 TEST(Build_Wasm_Infinite_Loop) {
   1878   WasmRunner<int32_t> r(MachineType::Int32());
   1879   // Only build the graph and compile, don't run.
   1880   BUILD(r, WASM_INFINITE_LOOP);
   1881 }
   1882 
   1883 
   1884 TEST(Build_Wasm_Infinite_Loop_effect) {
   1885   WasmRunner<int32_t> r(MachineType::Int32());
   1886   TestingModule module;
   1887   module.AddMemoryElems<int8_t>(16);
   1888   r.env()->module = &module;
   1889 
   1890   // Only build the graph and compile, don't run.
   1891   BUILD(r, WASM_LOOP(1, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
   1892 }
   1893 
   1894 
   1895 TEST(Run_Wasm_Unreachable0a) {
   1896   WasmRunner<int32_t> r(MachineType::Int32());
   1897   BUILD(r,
   1898         WASM_BLOCK(2, WASM_BRV(0, WASM_I8(9)), WASM_RETURN(WASM_GET_LOCAL(0))));
   1899   CHECK_EQ(9, r.Call(0));
   1900   CHECK_EQ(9, r.Call(1));
   1901 }
   1902 
   1903 
   1904 TEST(Run_Wasm_Unreachable0b) {
   1905   WasmRunner<int32_t> r(MachineType::Int32());
   1906   BUILD(r, WASM_BLOCK(2, WASM_BRV(0, WASM_I8(7)), WASM_UNREACHABLE));
   1907   CHECK_EQ(7, r.Call(0));
   1908   CHECK_EQ(7, r.Call(1));
   1909 }
   1910 
   1911 
   1912 TEST(Build_Wasm_Unreachable1) {
   1913   WasmRunner<int32_t> r(MachineType::Int32());
   1914   BUILD(r, WASM_UNREACHABLE);
   1915 }
   1916 
   1917 
   1918 TEST(Build_Wasm_Unreachable2) {
   1919   WasmRunner<int32_t> r(MachineType::Int32());
   1920   BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE);
   1921 }
   1922 
   1923 
   1924 TEST(Build_Wasm_Unreachable3) {
   1925   WasmRunner<int32_t> r(MachineType::Int32());
   1926   BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE, WASM_UNREACHABLE);
   1927 }
   1928 
   1929 
   1930 TEST(Build_Wasm_UnreachableIf1) {
   1931   WasmRunner<int32_t> r(MachineType::Int32());
   1932   BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
   1933 }
   1934 
   1935 
   1936 TEST(Build_Wasm_UnreachableIf2) {
   1937   WasmRunner<int32_t> r(MachineType::Int32());
   1938   BUILD(r, WASM_UNREACHABLE,
   1939         WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
   1940 }
   1941 
   1942 
   1943 TEST(Run_Wasm_Unreachable_Load) {
   1944   WasmRunner<int32_t> r(MachineType::Int32());
   1945   BUILD(r, WASM_BLOCK(2, WASM_BRV(0, WASM_GET_LOCAL(0)),
   1946                       WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
   1947   CHECK_EQ(11, r.Call(11));
   1948   CHECK_EQ(21, r.Call(21));
   1949 }
   1950 
   1951 
   1952 TEST(Run_Wasm_Infinite_Loop_not_taken1) {
   1953   WasmRunner<int32_t> r(MachineType::Int32());
   1954   BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP),
   1955                       WASM_I8(45)));
   1956   // Run the code, but don't go into the infinite loop.
   1957   CHECK_EQ(45, r.Call(0));
   1958 }
   1959 
   1960 
   1961 TEST(Run_Wasm_Infinite_Loop_not_taken2) {
   1962   WasmRunner<int32_t> r(MachineType::Int32());
   1963   BUILD(r,
   1964         WASM_BLOCK(1, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(45)),
   1965                                    WASM_INFINITE_LOOP)));
   1966   // Run the code, but don't go into the infinite loop.
   1967   CHECK_EQ(45, r.Call(1));
   1968 }
   1969 
   1970 
   1971 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) {
   1972   WasmRunner<int32_t> r(MachineType::Int32());
   1973   BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)),
   1974                       WASM_INFINITE_LOOP));
   1975   // Run the code, but don't go into the infinite loop.
   1976   CHECK_EQ(45, r.Call(1));
   1977 }
   1978 
   1979 
   1980 static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
   1981   if (!WasmOpcodes::IsSupported(opcode)) return;
   1982 
   1983   Zone zone;
   1984   Isolate* isolate = CcTest::InitIsolateOnce();
   1985   HandleScope scope(isolate);
   1986   // Enable all optional operators.
   1987   CommonOperatorBuilder common(&zone);
   1988   MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(),
   1989                                  MachineOperatorBuilder::kAllOptionalOps);
   1990   Graph graph(&zone);
   1991   JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
   1992   FunctionEnv env;
   1993   FunctionSig* sig = WasmOpcodes::Signature(opcode);
   1994   init_env(&env, sig);
   1995 
   1996   if (sig->parameter_count() == 1) {
   1997     byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0};
   1998     TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code));
   1999   } else {
   2000     CHECK_EQ(2, sig->parameter_count());
   2001     byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal,
   2002                    1};
   2003     TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code));
   2004   }
   2005 }
   2006 
   2007 
   2008 TEST(Build_Wasm_SimpleExprs) {
   2009 // Test that the decoder can build a graph for all supported simple expressions.
   2010 #define GRAPH_BUILD_TEST(name, opcode, sig) \
   2011   TestBuildGraphForSimpleExpression(kExpr##name);
   2012 
   2013   FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST);
   2014 
   2015 #undef GRAPH_BUILD_TEST
   2016 }
   2017 
   2018 
   2019 TEST(Run_Wasm_Int32LoadInt8_signext) {
   2020   TestingModule module;
   2021   const int kNumElems = 16;
   2022   int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems);
   2023   module.RandomizeMemory();
   2024   memory[0] = -1;
   2025   WasmRunner<int32_t> r(MachineType::Int32());
   2026   r.env()->module = &module;
   2027   BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)));
   2028 
   2029   for (size_t i = 0; i < kNumElems; i++) {
   2030     CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
   2031   }
   2032 }
   2033 
   2034 
   2035 TEST(Run_Wasm_Int32LoadInt8_zeroext) {
   2036   TestingModule module;
   2037   const int kNumElems = 16;
   2038   byte* memory = module.AddMemory(kNumElems);
   2039   module.RandomizeMemory(77);
   2040   memory[0] = 255;
   2041   WasmRunner<int32_t> r(MachineType::Int32());
   2042   r.env()->module = &module;
   2043   BUILD(r, WASM_LOAD_MEM(MachineType::Uint8(), WASM_GET_LOCAL(0)));
   2044 
   2045   for (size_t i = 0; i < kNumElems; i++) {
   2046     CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
   2047   }
   2048 }
   2049 
   2050 
   2051 TEST(Run_Wasm_Int32LoadInt16_signext) {
   2052   TestingModule module;
   2053   const int kNumBytes = 16;
   2054   byte* memory = module.AddMemory(kNumBytes);
   2055   module.RandomizeMemory(888);
   2056   memory[1] = 200;
   2057   WasmRunner<int32_t> r(MachineType::Int32());
   2058   r.env()->module = &module;
   2059   BUILD(r, WASM_LOAD_MEM(MachineType::Int16(), WASM_GET_LOCAL(0)));
   2060 
   2061   for (size_t i = 0; i < kNumBytes; i += 2) {
   2062     int32_t expected = memory[i] | (static_cast<int8_t>(memory[i + 1]) << 8);
   2063     CHECK_EQ(expected, r.Call(static_cast<int>(i)));
   2064   }
   2065 }
   2066 
   2067 
   2068 TEST(Run_Wasm_Int32LoadInt16_zeroext) {
   2069   TestingModule module;
   2070   const int kNumBytes = 16;
   2071   byte* memory = module.AddMemory(kNumBytes);
   2072   module.RandomizeMemory(9999);
   2073   memory[1] = 204;
   2074   WasmRunner<int32_t> r(MachineType::Int32());
   2075   r.env()->module = &module;
   2076   BUILD(r, WASM_LOAD_MEM(MachineType::Uint16(), WASM_GET_LOCAL(0)));
   2077 
   2078   for (size_t i = 0; i < kNumBytes; i += 2) {
   2079     int32_t expected = memory[i] | (memory[i + 1] << 8);
   2080     CHECK_EQ(expected, r.Call(static_cast<int>(i)));
   2081   }
   2082 }
   2083 
   2084 
   2085 TEST(Run_WasmInt32Global) {
   2086   TestingModule module;
   2087   int32_t* global = module.AddGlobal<int32_t>(MachineType::Int32());
   2088   WasmRunner<int32_t> r(MachineType::Int32());
   2089   r.env()->module = &module;
   2090   // global = global + p0
   2091   BUILD(r, WASM_STORE_GLOBAL(
   2092                0, WASM_I32_ADD(WASM_LOAD_GLOBAL(0), WASM_GET_LOCAL(0))));
   2093 
   2094   *global = 116;
   2095   for (int i = 9; i < 444444; i += 111111) {
   2096     int32_t expected = *global + i;
   2097     r.Call(i);
   2098     CHECK_EQ(expected, *global);
   2099   }
   2100 }
   2101 
   2102 
   2103 TEST(Run_WasmInt32Globals_DontAlias) {
   2104   const int kNumGlobals = 3;
   2105   TestingModule module;
   2106   int32_t* globals[] = {module.AddGlobal<int32_t>(MachineType::Int32()),
   2107                         module.AddGlobal<int32_t>(MachineType::Int32()),
   2108                         module.AddGlobal<int32_t>(MachineType::Int32())};
   2109 
   2110   for (int g = 0; g < kNumGlobals; g++) {
   2111     // global = global + p0
   2112     WasmRunner<int32_t> r(MachineType::Int32());
   2113     r.env()->module = &module;
   2114     BUILD(r, WASM_STORE_GLOBAL(
   2115                  g, WASM_I32_ADD(WASM_LOAD_GLOBAL(g), WASM_GET_LOCAL(0))));
   2116 
   2117     // Check that reading/writing global number {g} doesn't alter the others.
   2118     *globals[g] = 116 * g;
   2119     int32_t before[kNumGlobals];
   2120     for (int i = 9; i < 444444; i += 111113) {
   2121       int32_t sum = *globals[g] + i;
   2122       for (int j = 0; j < kNumGlobals; j++) before[j] = *globals[j];
   2123       r.Call(i);
   2124       for (int j = 0; j < kNumGlobals; j++) {
   2125         int32_t expected = j == g ? sum : before[j];
   2126         CHECK_EQ(expected, *globals[j]);
   2127       }
   2128     }
   2129   }
   2130 }
   2131 
   2132 
   2133 #if WASM_64
   2134 TEST(Run_WasmInt64Global) {
   2135   TestingModule module;
   2136   int64_t* global = module.AddGlobal<int64_t>(MachineType::Int64());
   2137   WasmRunner<int32_t> r(MachineType::Int32());
   2138   r.env()->module = &module;
   2139   // global = global + p0
   2140   BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL(
   2141                              0, WASM_I64_ADD(
   2142                                     WASM_LOAD_GLOBAL(0),
   2143                                     WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
   2144                       WASM_ZERO));
   2145 
   2146   *global = 0xFFFFFFFFFFFFFFFFLL;
   2147   for (int i = 9; i < 444444; i += 111111) {
   2148     int64_t expected = *global + i;
   2149     r.Call(i);
   2150     CHECK_EQ(expected, *global);
   2151   }
   2152 }
   2153 #endif
   2154 
   2155 
   2156 TEST(Run_WasmFloat32Global) {
   2157   TestingModule module;
   2158   float* global = module.AddGlobal<float>(MachineType::Float32());
   2159   WasmRunner<int32_t> r(MachineType::Int32());
   2160   r.env()->module = &module;
   2161   // global = global + p0
   2162   BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL(
   2163                              0, WASM_F32_ADD(
   2164                                     WASM_LOAD_GLOBAL(0),
   2165                                     WASM_F32_SCONVERT_I32(WASM_GET_LOCAL(0)))),
   2166                       WASM_ZERO));
   2167 
   2168   *global = 1.25;
   2169   for (int i = 9; i < 4444; i += 1111) {
   2170     volatile float expected = *global + i;
   2171     r.Call(i);
   2172     CHECK_EQ(expected, *global);
   2173   }
   2174 }
   2175 
   2176 
   2177 TEST(Run_WasmFloat64Global) {
   2178   TestingModule module;
   2179   double* global = module.AddGlobal<double>(MachineType::Float64());
   2180   WasmRunner<int32_t> r(MachineType::Int32());
   2181   r.env()->module = &module;
   2182   // global = global + p0
   2183   BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL(
   2184                              0, WASM_F64_ADD(
   2185                                     WASM_LOAD_GLOBAL(0),
   2186                                     WASM_F64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
   2187                       WASM_ZERO));
   2188 
   2189   *global = 1.25;
   2190   for (int i = 9; i < 4444; i += 1111) {
   2191     volatile double expected = *global + i;
   2192     r.Call(i);
   2193     CHECK_EQ(expected, *global);
   2194   }
   2195 }
   2196 
   2197 
   2198 TEST(Run_WasmMixedGlobals) {
   2199   TestingModule module;
   2200   int32_t* unused = module.AddGlobal<int32_t>(MachineType::Int32());
   2201   byte* memory = module.AddMemory(32);
   2202 
   2203   int8_t* var_int8 = module.AddGlobal<int8_t>(MachineType::Int8());
   2204   uint8_t* var_uint8 = module.AddGlobal<uint8_t>(MachineType::Uint8());
   2205   int16_t* var_int16 = module.AddGlobal<int16_t>(MachineType::Int16());
   2206   uint16_t* var_uint16 = module.AddGlobal<uint16_t>(MachineType::Uint16());
   2207   int32_t* var_int32 = module.AddGlobal<int32_t>(MachineType::Int32());
   2208   uint32_t* var_uint32 = module.AddGlobal<uint32_t>(MachineType::Uint32());
   2209   float* var_float = module.AddGlobal<float>(MachineType::Float32());
   2210   double* var_double = module.AddGlobal<double>(MachineType::Float64());
   2211 
   2212   WasmRunner<int32_t> r(MachineType::Int32());
   2213   r.env()->module = &module;
   2214 
   2215   BUILD(
   2216       r,
   2217       WASM_BLOCK(
   2218           9,
   2219           WASM_STORE_GLOBAL(1, WASM_LOAD_MEM(MachineType::Int8(), WASM_ZERO)),
   2220           WASM_STORE_GLOBAL(2, WASM_LOAD_MEM(MachineType::Uint8(), WASM_ZERO)),
   2221           WASM_STORE_GLOBAL(3, WASM_LOAD_MEM(MachineType::Int16(), WASM_ZERO)),
   2222           WASM_STORE_GLOBAL(4, WASM_LOAD_MEM(MachineType::Uint16(), WASM_ZERO)),
   2223           WASM_STORE_GLOBAL(5, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
   2224           WASM_STORE_GLOBAL(6, WASM_LOAD_MEM(MachineType::Uint32(), WASM_ZERO)),
   2225           WASM_STORE_GLOBAL(7,
   2226                             WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)),
   2227           WASM_STORE_GLOBAL(8,
   2228                             WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)),
   2229           WASM_ZERO));
   2230 
   2231   memory[0] = 0xaa;
   2232   memory[1] = 0xcc;
   2233   memory[2] = 0x55;
   2234   memory[3] = 0xee;
   2235   memory[4] = 0x33;
   2236   memory[5] = 0x22;
   2237   memory[6] = 0x11;
   2238   memory[7] = 0x99;
   2239   r.Call(1);
   2240 
   2241   CHECK(static_cast<int8_t>(0xaa) == *var_int8);
   2242   CHECK(static_cast<uint8_t>(0xaa) == *var_uint8);
   2243   CHECK(static_cast<int16_t>(0xccaa) == *var_int16);
   2244   CHECK(static_cast<uint16_t>(0xccaa) == *var_uint16);
   2245   CHECK(static_cast<int32_t>(0xee55ccaa) == *var_int32);
   2246   CHECK(static_cast<uint32_t>(0xee55ccaa) == *var_uint32);
   2247   CHECK(bit_cast<float>(0xee55ccaa) == *var_float);
   2248   CHECK(bit_cast<double>(0x99112233ee55ccaaULL) == *var_double);
   2249 
   2250   USE(unused);
   2251 }
   2252 
   2253 
   2254 #if WASM_64
   2255 // Test the WasmRunner with an Int64 return value and different numbers of
   2256 // Int64 parameters.
   2257 TEST(Run_TestI64WasmRunner) {
   2258   {
   2259     FOR_INT64_INPUTS(i) {
   2260       WasmRunner<int64_t> r;
   2261       BUILD(r, WASM_I64(*i));
   2262       CHECK_EQ(*i, r.Call());
   2263     }
   2264   }
   2265   {
   2266     WasmRunner<int64_t> r(MachineType::Int64());
   2267     BUILD(r, WASM_GET_LOCAL(0));
   2268     FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
   2269   }
   2270   {
   2271     WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
   2272     BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2273     FOR_INT64_INPUTS(i) {
   2274       FOR_INT64_INPUTS(j) { CHECK_EQ(*i + *j, r.Call(*i, *j)); }
   2275     }
   2276   }
   2277   {
   2278     WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(),
   2279                           MachineType::Int64());
   2280     BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0),
   2281                           WASM_I64_ADD(WASM_GET_LOCAL(1), WASM_GET_LOCAL(2))));
   2282     FOR_INT64_INPUTS(i) {
   2283       FOR_INT64_INPUTS(j) {
   2284         CHECK_EQ(*i + *j + *j, r.Call(*i, *j, *j));
   2285         CHECK_EQ(*j + *i + *j, r.Call(*j, *i, *j));
   2286         CHECK_EQ(*j + *j + *i, r.Call(*j, *j, *i));
   2287       }
   2288     }
   2289   }
   2290   {
   2291     WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(),
   2292                           MachineType::Int64(), MachineType::Int64());
   2293     BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0),
   2294                           WASM_I64_ADD(WASM_GET_LOCAL(1),
   2295                                        WASM_I64_ADD(WASM_GET_LOCAL(2),
   2296                                                     WASM_GET_LOCAL(3)))));
   2297     FOR_INT64_INPUTS(i) {
   2298       FOR_INT64_INPUTS(j) {
   2299         CHECK_EQ(*i + *j + *j + *j, r.Call(*i, *j, *j, *j));
   2300         CHECK_EQ(*j + *i + *j + *j, r.Call(*j, *i, *j, *j));
   2301         CHECK_EQ(*j + *j + *i + *j, r.Call(*j, *j, *i, *j));
   2302         CHECK_EQ(*j + *j + *j + *i, r.Call(*j, *j, *j, *i));
   2303       }
   2304     }
   2305   }
   2306 }
   2307 #endif
   2308 
   2309 
   2310 TEST(Run_WasmCallEmpty) {
   2311   const int32_t kExpected = -414444;
   2312   // Build the target function.
   2313   TestSignatures sigs;
   2314   TestingModule module;
   2315   WasmFunctionCompiler t(sigs.i_v());
   2316   BUILD(t, WASM_I32(kExpected));
   2317   uint32_t index = t.CompileAndAdd(&module);
   2318 
   2319   // Build the calling function.
   2320   WasmRunner<int32_t> r;
   2321   r.env()->module = &module;
   2322   BUILD(r, WASM_CALL_FUNCTION0(index));
   2323 
   2324   int32_t result = r.Call();
   2325   CHECK_EQ(kExpected, result);
   2326 }
   2327 
   2328 
   2329 // TODO(tizer): Fix on arm and reenable.
   2330 #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
   2331 
   2332 TEST(Run_WasmCallF32StackParameter) {
   2333   // Build the target function.
   2334   LocalType param_types[20];
   2335   for (int i = 0; i < 20; i++) param_types[i] = kAstF32;
   2336   FunctionSig sig(1, 19, param_types);
   2337   TestingModule module;
   2338   WasmFunctionCompiler t(&sig);
   2339   BUILD(t, WASM_GET_LOCAL(17));
   2340   uint32_t index = t.CompileAndAdd(&module);
   2341 
   2342   // Build the calling function.
   2343   WasmRunner<float> r;
   2344   r.env()->module = &module;
   2345   BUILD(r, WASM_CALL_FUNCTION(
   2346                index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
   2347                WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
   2348                WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f),
   2349                WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f),
   2350                WASM_F32(16.5f), WASM_F32(32.5f), WASM_F32(64.5f),
   2351                WASM_F32(128.5f), WASM_F32(256.5f), WASM_F32(512.5f)));
   2352 
   2353   float result = r.Call();
   2354   CHECK_EQ(256.5f, result);
   2355 }
   2356 
   2357 
   2358 TEST(Run_WasmCallF64StackParameter) {
   2359   // Build the target function.
   2360   LocalType param_types[20];
   2361   for (int i = 0; i < 20; i++) param_types[i] = kAstF64;
   2362   FunctionSig sig(1, 19, param_types);
   2363   TestingModule module;
   2364   WasmFunctionCompiler t(&sig);
   2365   BUILD(t, WASM_GET_LOCAL(17));
   2366   uint32_t index = t.CompileAndAdd(&module);
   2367 
   2368   // Build the calling function.
   2369   WasmRunner<double> r;
   2370   r.env()->module = &module;
   2371   BUILD(r, WASM_CALL_FUNCTION(index, WASM_F64(1.0), WASM_F64(2.0),
   2372                               WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
   2373                               WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
   2374                               WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
   2375                               WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5),
   2376                               WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5),
   2377                               WASM_F64(256.5), WASM_F64(512.5)));
   2378 
   2379   float result = r.Call();
   2380   CHECK_EQ(256.5, result);
   2381 }
   2382 
   2383 #endif
   2384 
   2385 
   2386 TEST(Run_WasmCallVoid) {
   2387   const byte kMemOffset = 8;
   2388   const int32_t kElemNum = kMemOffset / sizeof(int32_t);
   2389   const int32_t kExpected = -414444;
   2390   // Build the target function.
   2391   TestSignatures sigs;
   2392   TestingModule module;
   2393   module.AddMemory(16);
   2394   module.RandomizeMemory();
   2395   WasmFunctionCompiler t(sigs.v_v());
   2396   t.env.module = &module;
   2397   BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(kMemOffset),
   2398                           WASM_I32(kExpected)));
   2399   uint32_t index = t.CompileAndAdd(&module);
   2400 
   2401   // Build the calling function.
   2402   WasmRunner<int32_t> r;
   2403   r.env()->module = &module;
   2404   BUILD(r, WASM_CALL_FUNCTION0(index),
   2405         WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kMemOffset)));
   2406 
   2407   int32_t result = r.Call();
   2408   CHECK_EQ(kExpected, result);
   2409   CHECK_EQ(kExpected, module.raw_mem_start<int32_t>()[kElemNum]);
   2410 }
   2411 
   2412 
   2413 TEST(Run_WasmCall_Int32Add) {
   2414   // Build the target function.
   2415   TestSignatures sigs;
   2416   TestingModule module;
   2417   WasmFunctionCompiler t(sigs.i_ii());
   2418   BUILD(t, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2419   uint32_t index = t.CompileAndAdd(&module);
   2420 
   2421   // Build the caller function.
   2422   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
   2423   r.env()->module = &module;
   2424   BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2425 
   2426   FOR_INT32_INPUTS(i) {
   2427     FOR_INT32_INPUTS(j) {
   2428       int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
   2429                                               static_cast<uint32_t>(*j));
   2430       CHECK_EQ(expected, r.Call(*i, *j));
   2431     }
   2432   }
   2433 }
   2434 
   2435 
   2436 #if WASM_64
   2437 TEST(Run_WasmCall_Int64Sub) {
   2438   // Build the target function.
   2439   TestSignatures sigs;
   2440   TestingModule module;
   2441   WasmFunctionCompiler t(sigs.l_ll());
   2442   BUILD(t, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2443   uint32_t index = t.CompileAndAdd(&module);
   2444 
   2445   // Build the caller function.
   2446   WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
   2447   r.env()->module = &module;
   2448   BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2449 
   2450   FOR_INT32_INPUTS(i) {
   2451     FOR_INT32_INPUTS(j) {
   2452       int64_t a = static_cast<int64_t>(*i) << 32 |
   2453                   (static_cast<int64_t>(*j) | 0xFFFFFFFF);
   2454       int64_t b = static_cast<int64_t>(*j) << 32 |
   2455                   (static_cast<int64_t>(*i) | 0xFFFFFFFF);
   2456 
   2457       int64_t expected = static_cast<int64_t>(static_cast<uint64_t>(a) -
   2458                                               static_cast<uint64_t>(b));
   2459       CHECK_EQ(expected, r.Call(a, b));
   2460     }
   2461   }
   2462 }
   2463 #endif
   2464 
   2465 
   2466 TEST(Run_WasmCall_Float32Sub) {
   2467   TestSignatures sigs;
   2468   WasmFunctionCompiler t(sigs.f_ff());
   2469 
   2470   // Build the target function.
   2471   TestingModule module;
   2472   BUILD(t, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2473   uint32_t index = t.CompileAndAdd(&module);
   2474 
   2475   // Builder the caller function.
   2476   WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
   2477   r.env()->module = &module;
   2478   BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2479 
   2480   FOR_FLOAT32_INPUTS(i) {
   2481     FOR_FLOAT32_INPUTS(j) {
   2482       volatile float expected = *i - *j;
   2483       CheckFloatEq(expected, r.Call(*i, *j));
   2484     }
   2485   }
   2486 }
   2487 
   2488 
   2489 TEST(Run_WasmCall_Float64Sub) {
   2490   WasmRunner<int32_t> r;
   2491   TestingModule module;
   2492   double* memory = module.AddMemoryElems<double>(16);
   2493   r.env()->module = &module;
   2494 
   2495   // TODO(titzer): convert to a binop test.
   2496   BUILD(r, WASM_BLOCK(
   2497                2, WASM_STORE_MEM(
   2498                       MachineType::Float64(), WASM_ZERO,
   2499                       WASM_F64_SUB(
   2500                           WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO),
   2501                           WASM_LOAD_MEM(MachineType::Float64(), WASM_I8(8)))),
   2502                WASM_I8(107)));
   2503 
   2504   FOR_FLOAT64_INPUTS(i) {
   2505     FOR_FLOAT64_INPUTS(j) {
   2506       memory[0] = *i;
   2507       memory[1] = *j;
   2508       double expected = *i - *j;
   2509       CHECK_EQ(107, r.Call());
   2510       if (expected != expected) {
   2511         CHECK(memory[0] != memory[0]);
   2512       } else {
   2513         CHECK_EQ(expected, memory[0]);
   2514       }
   2515     }
   2516   }
   2517 }
   2518 
   2519 #define ADD_CODE(vec, ...)                                              \
   2520   do {                                                                  \
   2521     byte __buf[] = {__VA_ARGS__};                                       \
   2522     for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
   2523   } while (false)
   2524 
   2525 
   2526 static void Run_WasmMixedCall_N(int start) {
   2527   const int kExpected = 6333;
   2528   const int kElemSize = 8;
   2529   TestSignatures sigs;
   2530 
   2531 #if WASM_64
   2532   static MachineType mixed[] = {
   2533       MachineType::Int32(),   MachineType::Float32(), MachineType::Int64(),
   2534       MachineType::Float64(), MachineType::Float32(), MachineType::Int64(),
   2535       MachineType::Int32(),   MachineType::Float64(), MachineType::Float32(),
   2536       MachineType::Float64(), MachineType::Int32(),   MachineType::Int64(),
   2537       MachineType::Int32(),   MachineType::Int32()};
   2538 #else
   2539   static MachineType mixed[] = {
   2540       MachineType::Int32(),   MachineType::Float32(), MachineType::Float64(),
   2541       MachineType::Float32(), MachineType::Int32(),   MachineType::Float64(),
   2542       MachineType::Float32(), MachineType::Float64(), MachineType::Int32(),
   2543       MachineType::Int32(),   MachineType::Int32()};
   2544 #endif
   2545 
   2546   int num_params = static_cast<int>(arraysize(mixed)) - start;
   2547   for (int which = 0; which < num_params; which++) {
   2548     Zone zone;
   2549     TestingModule module;
   2550     module.AddMemory(1024);
   2551     MachineType* memtypes = &mixed[start];
   2552     MachineType result = memtypes[which];
   2553 
   2554     // =========================================================================
   2555     // Build the selector function.
   2556     // =========================================================================
   2557     uint32_t index;
   2558     FunctionSig::Builder b(&zone, 1, num_params);
   2559     b.AddReturn(WasmOpcodes::LocalTypeFor(result));
   2560     for (int i = 0; i < num_params; i++) {
   2561       b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
   2562     }
   2563     WasmFunctionCompiler t(b.Build());
   2564     t.env.module = &module;
   2565     BUILD(t, WASM_GET_LOCAL(which));
   2566     index = t.CompileAndAdd(&module);
   2567 
   2568     // =========================================================================
   2569     // Build the calling function.
   2570     // =========================================================================
   2571     WasmRunner<int32_t> r;
   2572     r.env()->module = &module;
   2573 
   2574     {
   2575       std::vector<byte> code;
   2576       ADD_CODE(code,
   2577                static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
   2578                WasmOpcodes::LoadStoreAccessOf(false));
   2579       ADD_CODE(code, WASM_ZERO);
   2580       ADD_CODE(code, kExprCallFunction, static_cast<byte>(index));
   2581 
   2582       for (int i = 0; i < num_params; i++) {
   2583         int offset = (i + 1) * kElemSize;
   2584         ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
   2585       }
   2586 
   2587       ADD_CODE(code, WASM_I32(kExpected));
   2588       size_t end = code.size();
   2589       code.push_back(0);
   2590       r.Build(&code[0], &code[end]);
   2591     }
   2592 
   2593     // Run the code.
   2594     for (int t = 0; t < 10; t++) {
   2595       module.RandomizeMemory();
   2596       CHECK_EQ(kExpected, r.Call());
   2597 
   2598       int size = WasmOpcodes::MemSize(result);
   2599       for (int i = 0; i < size; i++) {
   2600         int base = (which + 1) * kElemSize;
   2601         byte expected = module.raw_mem_at<byte>(base + i);
   2602         byte result = module.raw_mem_at<byte>(i);
   2603         CHECK_EQ(expected, result);
   2604       }
   2605     }
   2606   }
   2607 }
   2608 
   2609 
   2610 TEST(Run_WasmMixedCall_0) { Run_WasmMixedCall_N(0); }
   2611 TEST(Run_WasmMixedCall_1) { Run_WasmMixedCall_N(1); }
   2612 TEST(Run_WasmMixedCall_2) { Run_WasmMixedCall_N(2); }
   2613 TEST(Run_WasmMixedCall_3) { Run_WasmMixedCall_N(3); }
   2614 
   2615 
   2616 TEST(Run_Wasm_CountDown_expr) {
   2617   WasmRunner<int32_t> r(MachineType::Int32());
   2618   BUILD(r, WASM_LOOP(
   2619                3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)),
   2620                           WASM_BREAKV(0, WASM_GET_LOCAL(0))),
   2621                WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
   2622                WASM_CONTINUE(0)));
   2623   CHECK_EQ(0, r.Call(1));
   2624   CHECK_EQ(0, r.Call(10));
   2625   CHECK_EQ(0, r.Call(100));
   2626 }
   2627 
   2628 
   2629 TEST(Run_Wasm_ExprBlock2a) {
   2630   WasmRunner<int32_t> r(MachineType::Int32());
   2631   BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))),
   2632                       WASM_I8(1)));
   2633   CHECK_EQ(1, r.Call(0));
   2634   CHECK_EQ(1, r.Call(1));
   2635 }
   2636 
   2637 
   2638 TEST(Run_Wasm_ExprBlock2b) {
   2639   WasmRunner<int32_t> r(MachineType::Int32());
   2640   BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))),
   2641                       WASM_I8(2)));
   2642   CHECK_EQ(2, r.Call(0));
   2643   CHECK_EQ(1, r.Call(1));
   2644 }
   2645 
   2646 
   2647 TEST(Run_Wasm_ExprBlock2c) {
   2648   WasmRunner<int32_t> r(MachineType::Int32());
   2649   BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(1)),
   2650                       WASM_I8(1)));
   2651   CHECK_EQ(1, r.Call(0));
   2652   CHECK_EQ(1, r.Call(1));
   2653 }
   2654 
   2655 
   2656 TEST(Run_Wasm_ExprBlock2d) {
   2657   WasmRunner<int32_t> r(MachineType::Int32());
   2658   BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(1)),
   2659                       WASM_I8(2)));
   2660   CHECK_EQ(2, r.Call(0));
   2661   CHECK_EQ(1, r.Call(1));
   2662 }
   2663 
   2664 
   2665 TEST(Run_Wasm_ExprBlock_ManualSwitch) {
   2666   WasmRunner<int32_t> r(MachineType::Int32());
   2667   BUILD(r, WASM_BLOCK(6, WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
   2668                                  WASM_BRV(0, WASM_I8(11))),
   2669                       WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
   2670                               WASM_BRV(0, WASM_I8(12))),
   2671                       WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
   2672                               WASM_BRV(0, WASM_I8(13))),
   2673                       WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
   2674                               WASM_BRV(0, WASM_I8(14))),
   2675                       WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
   2676                               WASM_BRV(0, WASM_I8(15))),
   2677                       WASM_I8(99)));
   2678   CHECK_EQ(99, r.Call(0));
   2679   CHECK_EQ(11, r.Call(1));
   2680   CHECK_EQ(12, r.Call(2));
   2681   CHECK_EQ(13, r.Call(3));
   2682   CHECK_EQ(14, r.Call(4));
   2683   CHECK_EQ(15, r.Call(5));
   2684   CHECK_EQ(99, r.Call(6));
   2685 }
   2686 
   2687 
   2688 TEST(Run_Wasm_ExprBlock_ManualSwitch_brif) {
   2689   WasmRunner<int32_t> r(MachineType::Int32());
   2690   BUILD(r,
   2691         WASM_BLOCK(6, WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
   2692                                   WASM_I8(11)),
   2693                    WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
   2694                                WASM_I8(12)),
   2695                    WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
   2696                                WASM_I8(13)),
   2697                    WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
   2698                                WASM_I8(14)),
   2699                    WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
   2700                                WASM_I8(15)),
   2701                    WASM_I8(99)));
   2702   CHECK_EQ(99, r.Call(0));
   2703   CHECK_EQ(11, r.Call(1));
   2704   CHECK_EQ(12, r.Call(2));
   2705   CHECK_EQ(13, r.Call(3));
   2706   CHECK_EQ(14, r.Call(4));
   2707   CHECK_EQ(15, r.Call(5));
   2708   CHECK_EQ(99, r.Call(6));
   2709 }
   2710 
   2711 
   2712 TEST(Run_Wasm_nested_ifs) {
   2713   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
   2714 
   2715   BUILD(r, WASM_IF_ELSE(
   2716                WASM_GET_LOCAL(0),
   2717                WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)),
   2718                WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14))));
   2719 
   2720 
   2721   CHECK_EQ(11, r.Call(1, 1));
   2722   CHECK_EQ(12, r.Call(1, 0));
   2723   CHECK_EQ(13, r.Call(0, 1));
   2724   CHECK_EQ(14, r.Call(0, 0));
   2725 }
   2726 
   2727 
   2728 TEST(Run_Wasm_ExprBlock_if) {
   2729   WasmRunner<int32_t> r(MachineType::Int32());
   2730 
   2731   BUILD(r,
   2732         WASM_BLOCK(1, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)),
   2733                                    WASM_BRV(0, WASM_I8(14)))));
   2734 
   2735   CHECK_EQ(11, r.Call(1));
   2736   CHECK_EQ(14, r.Call(0));
   2737 }
   2738 
   2739 
   2740 TEST(Run_Wasm_ExprBlock_nested_ifs) {
   2741   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
   2742 
   2743   BUILD(r, WASM_BLOCK(
   2744                1, WASM_IF_ELSE(
   2745                       WASM_GET_LOCAL(0),
   2746                       WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)),
   2747                                    WASM_BRV(0, WASM_I8(12))),
   2748                       WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)),
   2749                                    WASM_BRV(0, WASM_I8(14))))));
   2750 
   2751 
   2752   CHECK_EQ(11, r.Call(1, 1));
   2753   CHECK_EQ(12, r.Call(1, 0));
   2754   CHECK_EQ(13, r.Call(0, 1));
   2755   CHECK_EQ(14, r.Call(0, 0));
   2756 }
   2757 
   2758 
   2759 TEST(Run_Wasm_ExprLoop_nested_ifs) {
   2760   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
   2761 
   2762   BUILD(r, WASM_LOOP(
   2763                1, WASM_IF_ELSE(
   2764                       WASM_GET_LOCAL(0),
   2765                       WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(11)),
   2766                                    WASM_BRV(1, WASM_I8(12))),
   2767                       WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)),
   2768                                    WASM_BRV(1, WASM_I8(14))))));
   2769 
   2770 
   2771   CHECK_EQ(11, r.Call(1, 1));
   2772   CHECK_EQ(12, r.Call(1, 0));
   2773   CHECK_EQ(13, r.Call(0, 1));
   2774   CHECK_EQ(14, r.Call(0, 0));
   2775 }
   2776 
   2777 
   2778 #if WASM_64
   2779 TEST(Run_Wasm_LoadStoreI64_sx) {
   2780   byte loads[] = {kExprI64LoadMem8S, kExprI64LoadMem16S, kExprI64LoadMem32S,
   2781                   kExprI64LoadMem};
   2782 
   2783   for (size_t m = 0; m < arraysize(loads); m++) {
   2784     WasmRunner<int64_t> r;
   2785     TestingModule module;
   2786     byte* memory = module.AddMemoryElems<byte>(16);
   2787     r.env()->module = &module;
   2788 
   2789     byte code[] = {kExprI64StoreMem, 0, kExprI8Const, 8,
   2790                    loads[m],         0, kExprI8Const, 0};
   2791 
   2792     r.Build(code, code + arraysize(code));
   2793 
   2794     // Try a bunch of different negative values.
   2795     for (int i = -1; i >= -128; i -= 11) {
   2796       int size = 1 << m;
   2797       module.BlankMemory();
   2798       memory[size - 1] = static_cast<byte>(i);  // set the high order byte.
   2799 
   2800       int64_t expected = static_cast<int64_t>(i) << ((size - 1) * 8);
   2801 
   2802       CHECK_EQ(expected, r.Call());
   2803       CHECK_EQ(static_cast<byte>(i), memory[8 + size - 1]);
   2804       for (int j = size; j < 8; j++) {
   2805         CHECK_EQ(255, memory[8 + j]);
   2806       }
   2807     }
   2808   }
   2809 }
   2810 
   2811 
   2812 #endif
   2813 
   2814 
   2815 TEST(Run_Wasm_SimpleCallIndirect) {
   2816   Isolate* isolate = CcTest::InitIsolateOnce();
   2817 
   2818   WasmRunner<int32_t> r(MachineType::Int32());
   2819   TestSignatures sigs;
   2820   TestingModule module;
   2821   r.env()->module = &module;
   2822   WasmFunctionCompiler t1(sigs.i_ii());
   2823   BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2824   t1.CompileAndAdd(&module);
   2825 
   2826   WasmFunctionCompiler t2(sigs.i_ii());
   2827   BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2828   t2.CompileAndAdd(&module);
   2829 
   2830   // Signature table.
   2831   module.AddSignature(sigs.f_ff());
   2832   module.AddSignature(sigs.i_ii());
   2833   module.AddSignature(sigs.d_dd());
   2834 
   2835   // Function table.
   2836   int table_size = 2;
   2837   module.module->function_table = new std::vector<uint16_t>;
   2838   module.module->function_table->push_back(0);
   2839   module.module->function_table->push_back(1);
   2840 
   2841   // Function table.
   2842   Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size);
   2843   fixed->set(0, Smi::FromInt(1));
   2844   fixed->set(1, Smi::FromInt(1));
   2845   fixed->set(2, *module.function_code->at(0));
   2846   fixed->set(3, *module.function_code->at(1));
   2847   module.function_table = fixed;
   2848 
   2849   // Builder the caller function.
   2850   BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
   2851 
   2852   CHECK_EQ(88, r.Call(0));
   2853   CHECK_EQ(44, r.Call(1));
   2854   CHECK_TRAP(r.Call(2));
   2855 }
   2856 
   2857 
   2858 TEST(Run_Wasm_MultipleCallIndirect) {
   2859   Isolate* isolate = CcTest::InitIsolateOnce();
   2860 
   2861   WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32(),
   2862                         MachineType::Int32());
   2863   TestSignatures sigs;
   2864   TestingModule module;
   2865   r.env()->module = &module;
   2866   WasmFunctionCompiler t1(sigs.i_ii());
   2867   BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2868   t1.CompileAndAdd(&module);
   2869 
   2870   WasmFunctionCompiler t2(sigs.i_ii());
   2871   BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2872   t2.CompileAndAdd(&module);
   2873 
   2874   // Signature table.
   2875   module.AddSignature(sigs.f_ff());
   2876   module.AddSignature(sigs.i_ii());
   2877   module.AddSignature(sigs.d_dd());
   2878 
   2879   // Function table.
   2880   int table_size = 2;
   2881   module.module->function_table = new std::vector<uint16_t>;
   2882   module.module->function_table->push_back(0);
   2883   module.module->function_table->push_back(1);
   2884 
   2885   // Function table.
   2886   Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size);
   2887   fixed->set(0, Smi::FromInt(1));
   2888   fixed->set(1, Smi::FromInt(1));
   2889   fixed->set(2, *module.function_code->at(0));
   2890   fixed->set(3, *module.function_code->at(1));
   2891   module.function_table = fixed;
   2892 
   2893   // Builder the caller function.
   2894   BUILD(r,
   2895         WASM_I32_ADD(WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
   2896                                         WASM_GET_LOCAL(2)),
   2897                      WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
   2898                                         WASM_GET_LOCAL(0))));
   2899 
   2900   CHECK_EQ(5, r.Call(0, 1, 2));
   2901   CHECK_EQ(19, r.Call(0, 1, 9));
   2902   CHECK_EQ(1, r.Call(1, 0, 2));
   2903   CHECK_EQ(1, r.Call(1, 0, 9));
   2904 
   2905   CHECK_TRAP(r.Call(0, 2, 1));
   2906   CHECK_TRAP(r.Call(1, 2, 0));
   2907   CHECK_TRAP(r.Call(2, 0, 1));
   2908   CHECK_TRAP(r.Call(2, 1, 0));
   2909 }
   2910 
   2911 
   2912 // TODO(titzer): Fix for nosee4 and re-enable.
   2913 #if 0
   2914 
   2915 TEST(Run_Wasm_F32Floor) {
   2916   WasmRunner<float> r(MachineType::Float32());
   2917   BUILD(r, WASM_F32_FLOOR(WASM_GET_LOCAL(0)));
   2918 
   2919   FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floor(*i), r.Call(*i)); }
   2920 }
   2921 
   2922 
   2923 TEST(Run_Wasm_F32Ceil) {
   2924   WasmRunner<float> r(MachineType::Float32());
   2925   BUILD(r, WASM_F32_CEIL(WASM_GET_LOCAL(0)));
   2926 
   2927   FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceil(*i), r.Call(*i)); }
   2928 }
   2929 
   2930 
   2931 TEST(Run_Wasm_F32Trunc) {
   2932   WasmRunner<float> r(MachineType::Float32());
   2933   BUILD(r, WASM_F32_TRUNC(WASM_GET_LOCAL(0)));
   2934 
   2935   FOR_FLOAT32_INPUTS(i) { CheckFloatEq(trunc(*i), r.Call(*i)); }
   2936 }
   2937 
   2938 
   2939 TEST(Run_Wasm_F32NearestInt) {
   2940   WasmRunner<float> r(MachineType::Float32());
   2941   BUILD(r, WASM_F32_NEARESTINT(WASM_GET_LOCAL(0)));
   2942 
   2943   FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), r.Call(*i)); }
   2944 }
   2945 
   2946 
   2947 TEST(Run_Wasm_F64Floor) {
   2948   WasmRunner<double> r(MachineType::Float64());
   2949   BUILD(r, WASM_F64_FLOOR(WASM_GET_LOCAL(0)));
   2950 
   2951   FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), r.Call(*i)); }
   2952 }
   2953 
   2954 
   2955 TEST(Run_Wasm_F64Ceil) {
   2956   WasmRunner<double> r(MachineType::Float64());
   2957   BUILD(r, WASM_F64_CEIL(WASM_GET_LOCAL(0)));
   2958 
   2959   FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), r.Call(*i)); }
   2960 }
   2961 
   2962 
   2963 TEST(Run_Wasm_F64Trunc) {
   2964   WasmRunner<double> r(MachineType::Float64());
   2965   BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
   2966 
   2967   FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(trunc(*i), r.Call(*i)); }
   2968 }
   2969 
   2970 
   2971 TEST(Run_Wasm_F64NearestInt) {
   2972   WasmRunner<double> r(MachineType::Float64());
   2973   BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0)));
   2974 
   2975   FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), r.Call(*i)); }
   2976 }
   2977 
   2978 #endif
   2979 
   2980 
   2981 TEST(Run_Wasm_F32Min) {
   2982   WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
   2983   BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   2984 
   2985   FOR_FLOAT32_INPUTS(i) {
   2986     FOR_FLOAT32_INPUTS(j) {
   2987       float expected;
   2988       if (*i < *j) {
   2989         expected = *i;
   2990       } else if (*j < *i) {
   2991         expected = *j;
   2992       } else if (*i != *i) {
   2993         // If *i or *j is NaN, then the result is NaN.
   2994         expected = *i;
   2995       } else {
   2996         expected = *j;
   2997       }
   2998 
   2999       CheckFloatEq(expected, r.Call(*i, *j));
   3000     }
   3001   }
   3002 }
   3003 
   3004 
   3005 TEST(Run_Wasm_F64Min) {
   3006   WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
   3007   BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   3008 
   3009   FOR_FLOAT64_INPUTS(i) {
   3010     FOR_FLOAT64_INPUTS(j) {
   3011       double expected;
   3012       if (*i < *j) {
   3013         expected = *i;
   3014       } else if (*j < *i) {
   3015         expected = *j;
   3016       } else if (*i != *i) {
   3017         // If *i or *j is NaN, then the result is NaN.
   3018         expected = *i;
   3019       } else {
   3020         expected = *j;
   3021       }
   3022 
   3023       CheckDoubleEq(expected, r.Call(*i, *j));
   3024     }
   3025   }
   3026 }
   3027 
   3028 
   3029 TEST(Run_Wasm_F32Max) {
   3030   WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
   3031   BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   3032 
   3033   FOR_FLOAT32_INPUTS(i) {
   3034     FOR_FLOAT32_INPUTS(j) {
   3035       float expected;
   3036       if (*i > *j) {
   3037         expected = *i;
   3038       } else if (*j > *i) {
   3039         expected = *j;
   3040       } else if (*i != *i) {
   3041         // If *i or *j is NaN, then the result is NaN.
   3042         expected = *i;
   3043       } else {
   3044         expected = *j;
   3045       }
   3046 
   3047       CheckFloatEq(expected, r.Call(*i, *j));
   3048     }
   3049   }
   3050 }
   3051 
   3052 
   3053 TEST(Run_Wasm_F64Max) {
   3054   WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
   3055   BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   3056 
   3057   FOR_FLOAT64_INPUTS(i) {
   3058     FOR_FLOAT64_INPUTS(j) {
   3059       double expected;
   3060       if (*i > *j) {
   3061         expected = *i;
   3062       } else if (*j > *i) {
   3063         expected = *j;
   3064       } else if (*i != *i) {
   3065         // If *i or *j is NaN, then the result is NaN.
   3066         expected = *i;
   3067       } else {
   3068         expected = *j;
   3069       }
   3070 
   3071       CheckDoubleEq(expected, r.Call(*i, *j));
   3072     }
   3073   }
   3074 }
   3075 
   3076 
   3077 #if WASM_64
   3078 TEST(Run_Wasm_F32SConvertI64) {
   3079   WasmRunner<float> r(MachineType::Int64());
   3080   BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0)));
   3081   FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); }
   3082 }
   3083 
   3084 
   3085 #if !defined(_WIN64)
   3086 // TODO(ahaas): Fix this failure.
   3087 TEST(Run_Wasm_F32UConvertI64) {
   3088   WasmRunner<float> r(MachineType::Uint64());
   3089   BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0)));
   3090   FOR_UINT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); }
   3091 }
   3092 #endif
   3093 
   3094 
   3095 TEST(Run_Wasm_F64SConvertI64) {
   3096   WasmRunner<double> r(MachineType::Int64());
   3097   BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0)));
   3098   FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); }
   3099 }
   3100 
   3101 
   3102 #if !defined(_WIN64)
   3103 // TODO(ahaas): Fix this failure.
   3104 TEST(Run_Wasm_F64UConvertI64) {
   3105   WasmRunner<double> r(MachineType::Uint64());
   3106   BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0)));
   3107   FOR_UINT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); }
   3108 }
   3109 #endif
   3110 
   3111 
   3112 TEST(Run_Wasm_I64SConvertF32) {
   3113   WasmRunner<int64_t> r(MachineType::Float32());
   3114   BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
   3115 
   3116   FOR_FLOAT32_INPUTS(i) {
   3117     if (*i < static_cast<float>(INT64_MAX) &&
   3118         *i >= static_cast<float>(INT64_MIN)) {
   3119       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
   3120     } else {
   3121       CHECK_TRAP64(r.Call(*i));
   3122     }
   3123   }
   3124 }
   3125 
   3126 
   3127 TEST(Run_Wasm_I64SConvertF64) {
   3128   WasmRunner<int64_t> r(MachineType::Float64());
   3129   BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
   3130 
   3131   FOR_FLOAT64_INPUTS(i) {
   3132     if (*i < static_cast<double>(INT64_MAX) &&
   3133         *i >= static_cast<double>(INT64_MIN)) {
   3134       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
   3135     } else {
   3136       CHECK_TRAP64(r.Call(*i));
   3137     }
   3138   }
   3139 }
   3140 
   3141 
   3142 TEST(Run_Wasm_I64UConvertF32) {
   3143   WasmRunner<uint64_t> r(MachineType::Float32());
   3144   BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
   3145 
   3146   FOR_FLOAT32_INPUTS(i) {
   3147     if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
   3148       CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
   3149     } else {
   3150       CHECK_TRAP64(r.Call(*i));
   3151     }
   3152   }
   3153 }
   3154 
   3155 
   3156 TEST(Run_Wasm_I64UConvertF64) {
   3157   WasmRunner<uint64_t> r(MachineType::Float64());
   3158   BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
   3159 
   3160   FOR_FLOAT64_INPUTS(i) {
   3161     if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
   3162       CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
   3163     } else {
   3164       CHECK_TRAP64(r.Call(*i));
   3165     }
   3166   }
   3167 }
   3168 #endif
   3169 
   3170 
   3171 // TODO(titzer): Fix and re-enable.
   3172 #if 0
   3173 TEST(Run_Wasm_I32SConvertF32) {
   3174   WasmRunner<int32_t> r(MachineType::Float32());
   3175   BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0)));
   3176 
   3177   FOR_FLOAT32_INPUTS(i) {
   3178     if (*i < static_cast<float>(INT32_MAX) &&
   3179         *i >= static_cast<float>(INT32_MIN)) {
   3180       CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i));
   3181     } else {
   3182       CHECK_TRAP32(r.Call(*i));
   3183     }
   3184   }
   3185 }
   3186 
   3187 
   3188 TEST(Run_Wasm_I32SConvertF64) {
   3189   WasmRunner<int32_t> r(MachineType::Float64());
   3190   BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0)));
   3191 
   3192   FOR_FLOAT64_INPUTS(i) {
   3193     if (*i < static_cast<double>(INT32_MAX) &&
   3194         *i >= static_cast<double>(INT32_MIN)) {
   3195       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
   3196     } else {
   3197       CHECK_TRAP32(r.Call(*i));
   3198     }
   3199   }
   3200 }
   3201 
   3202 
   3203 TEST(Run_Wasm_I32UConvertF32) {
   3204   WasmRunner<uint32_t> r(MachineType::Float32());
   3205   BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0)));
   3206 
   3207   FOR_FLOAT32_INPUTS(i) {
   3208     if (*i < static_cast<float>(UINT32_MAX) && *i > -1) {
   3209       CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
   3210     } else {
   3211       CHECK_TRAP32(r.Call(*i));
   3212     }
   3213   }
   3214 }
   3215 
   3216 
   3217 TEST(Run_Wasm_I32UConvertF64) {
   3218   WasmRunner<uint32_t> r(MachineType::Float64());
   3219   BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0)));
   3220 
   3221   FOR_FLOAT64_INPUTS(i) {
   3222     if (*i < static_cast<float>(UINT32_MAX) && *i > -1) {
   3223       CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
   3224     } else {
   3225       CHECK_TRAP32(r.Call(*i));
   3226     }
   3227   }
   3228 }
   3229 #endif
   3230 
   3231 
   3232 TEST(Run_Wasm_F64CopySign) {
   3233   WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
   3234   BUILD(r, WASM_F64_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   3235 
   3236   FOR_FLOAT64_INPUTS(i) {
   3237     FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(copysign(*i, *j), r.Call(*i, *j)); }
   3238   }
   3239 }
   3240 
   3241 
   3242 // TODO(tizer): Fix on arm and reenable.
   3243 #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
   3244 
   3245 TEST(Run_Wasm_F32CopySign) {
   3246   WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
   3247   BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
   3248 
   3249   FOR_FLOAT32_INPUTS(i) {
   3250     FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); }
   3251   }
   3252 }
   3253 
   3254 #endif
   3255