Home | History | Annotate | Download | only in cctest
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "v8.h"
     29 
     30 #include "disassembler.h"
     31 #include "factory.h"
     32 #include "arm/simulator-arm.h"
     33 #include "arm/assembler-arm-inl.h"
     34 #include "cctest.h"
     35 
     36 using namespace v8::internal;
     37 
     38 
     39 // Define these function prototypes to match JSEntryFunction in execution.cc.
     40 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
     41 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
     42 typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
     43 typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
     44 
     45 
     46 #define __ assm.
     47 
     48 TEST(0) {
     49   CcTest::InitializeVM();
     50   Isolate* isolate = Isolate::Current();
     51   HandleScope scope(isolate);
     52 
     53   Assembler assm(isolate, NULL, 0);
     54 
     55   __ add(r0, r0, Operand(r1));
     56   __ mov(pc, Operand(lr));
     57 
     58   CodeDesc desc;
     59   assm.GetCode(&desc);
     60   Object* code = isolate->heap()->CreateCode(
     61       desc,
     62       Code::ComputeFlags(Code::STUB),
     63       Handle<Code>())->ToObjectChecked();
     64   CHECK(code->IsCode());
     65 #ifdef DEBUG
     66   Code::cast(code)->Print();
     67 #endif
     68   F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
     69   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));
     70   ::printf("f() = %d\n", res);
     71   CHECK_EQ(7, res);
     72 }
     73 
     74 
     75 TEST(1) {
     76   CcTest::InitializeVM();
     77   Isolate* isolate = Isolate::Current();
     78   HandleScope scope(isolate);
     79 
     80   Assembler assm(isolate, NULL, 0);
     81   Label L, C;
     82 
     83   __ mov(r1, Operand(r0));
     84   __ mov(r0, Operand::Zero());
     85   __ b(&C);
     86 
     87   __ bind(&L);
     88   __ add(r0, r0, Operand(r1));
     89   __ sub(r1, r1, Operand(1));
     90 
     91   __ bind(&C);
     92   __ teq(r1, Operand::Zero());
     93   __ b(ne, &L);
     94   __ mov(pc, Operand(lr));
     95 
     96   CodeDesc desc;
     97   assm.GetCode(&desc);
     98   Object* code = isolate->heap()->CreateCode(
     99       desc,
    100       Code::ComputeFlags(Code::STUB),
    101       Handle<Code>())->ToObjectChecked();
    102   CHECK(code->IsCode());
    103 #ifdef DEBUG
    104   Code::cast(code)->Print();
    105 #endif
    106   F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
    107   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0));
    108   ::printf("f() = %d\n", res);
    109   CHECK_EQ(5050, res);
    110 }
    111 
    112 
    113 TEST(2) {
    114   CcTest::InitializeVM();
    115   Isolate* isolate = Isolate::Current();
    116   HandleScope scope(isolate);
    117 
    118   Assembler assm(isolate, NULL, 0);
    119   Label L, C;
    120 
    121   __ mov(r1, Operand(r0));
    122   __ mov(r0, Operand(1));
    123   __ b(&C);
    124 
    125   __ bind(&L);
    126   __ mul(r0, r1, r0);
    127   __ sub(r1, r1, Operand(1));
    128 
    129   __ bind(&C);
    130   __ teq(r1, Operand::Zero());
    131   __ b(ne, &L);
    132   __ mov(pc, Operand(lr));
    133 
    134   // some relocated stuff here, not executed
    135   __ RecordComment("dead code, just testing relocations");
    136   __ mov(r0, Operand(isolate->factory()->true_value()));
    137   __ RecordComment("dead code, just testing immediate operands");
    138   __ mov(r0, Operand(-1));
    139   __ mov(r0, Operand(0xFF000000));
    140   __ mov(r0, Operand(0xF0F0F0F0));
    141   __ mov(r0, Operand(0xFFF0FFFF));
    142 
    143   CodeDesc desc;
    144   assm.GetCode(&desc);
    145   Object* code = isolate->heap()->CreateCode(
    146       desc,
    147       Code::ComputeFlags(Code::STUB),
    148       Handle<Code>())->ToObjectChecked();
    149   CHECK(code->IsCode());
    150 #ifdef DEBUG
    151   Code::cast(code)->Print();
    152 #endif
    153   F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
    154   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));
    155   ::printf("f() = %d\n", res);
    156   CHECK_EQ(3628800, res);
    157 }
    158 
    159 
    160 TEST(3) {
    161   CcTest::InitializeVM();
    162   Isolate* isolate = Isolate::Current();
    163   HandleScope scope(isolate);
    164 
    165   typedef struct {
    166     int i;
    167     char c;
    168     int16_t s;
    169   } T;
    170   T t;
    171 
    172   Assembler assm(isolate, NULL, 0);
    173   Label L, C;
    174 
    175   __ mov(ip, Operand(sp));
    176   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
    177   __ sub(fp, ip, Operand(4));
    178   __ mov(r4, Operand(r0));
    179   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));
    180   __ mov(r2, Operand(r0, ASR, 1));
    181   __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));
    182   __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
    183   __ add(r0, r2, Operand(r0));
    184   __ mov(r2, Operand(r2, LSL, 2));
    185   __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));
    186   __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));
    187   __ add(r0, r2, Operand(r0));
    188   __ mov(r2, Operand(r2, ASR, 3));
    189   __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));
    190   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
    191 
    192   CodeDesc desc;
    193   assm.GetCode(&desc);
    194   Object* code = isolate->heap()->CreateCode(
    195       desc,
    196       Code::ComputeFlags(Code::STUB),
    197       Handle<Code>())->ToObjectChecked();
    198   CHECK(code->IsCode());
    199 #ifdef DEBUG
    200   Code::cast(code)->Print();
    201 #endif
    202   F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
    203   t.i = 100000;
    204   t.c = 10;
    205   t.s = 1000;
    206   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0));
    207   ::printf("f() = %d\n", res);
    208   CHECK_EQ(101010, res);
    209   CHECK_EQ(100000/2, t.i);
    210   CHECK_EQ(10*4, t.c);
    211   CHECK_EQ(1000/8, t.s);
    212 }
    213 
    214 
    215 TEST(4) {
    216   // Test the VFP floating point instructions.
    217   CcTest::InitializeVM();
    218   Isolate* isolate = Isolate::Current();
    219   HandleScope scope(isolate);
    220 
    221   typedef struct {
    222     double a;
    223     double b;
    224     double c;
    225     double d;
    226     double e;
    227     double f;
    228     double g;
    229     double h;
    230     int i;
    231     double j;
    232     double m;
    233     double n;
    234     float x;
    235     float y;
    236   } T;
    237   T t;
    238 
    239   // Create a function that accepts &t, and loads, manipulates, and stores
    240   // the doubles and floats.
    241   Assembler assm(isolate, NULL, 0);
    242   Label L, C;
    243 
    244 
    245   if (CpuFeatures::IsSupported(VFP3)) {
    246     CpuFeatureScope scope(&assm, VFP3);
    247 
    248     __ mov(ip, Operand(sp));
    249     __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
    250     __ sub(fp, ip, Operand(4));
    251 
    252     __ mov(r4, Operand(r0));
    253     __ vldr(d6, r4, OFFSET_OF(T, a));
    254     __ vldr(d7, r4, OFFSET_OF(T, b));
    255     __ vadd(d5, d6, d7);
    256     __ vstr(d5, r4, OFFSET_OF(T, c));
    257 
    258     __ vmla(d5, d6, d7);
    259     __ vmls(d5, d5, d6);
    260 
    261     __ vmov(r2, r3, d5);
    262     __ vmov(d4, r2, r3);
    263     __ vstr(d4, r4, OFFSET_OF(T, b));
    264 
    265     // Load t.x and t.y, switch values, and store back to the struct.
    266     __ vldr(s0, r4, OFFSET_OF(T, x));
    267     __ vldr(s31, r4, OFFSET_OF(T, y));
    268     __ vmov(s16, s0);
    269     __ vmov(s0, s31);
    270     __ vmov(s31, s16);
    271     __ vstr(s0, r4, OFFSET_OF(T, x));
    272     __ vstr(s31, r4, OFFSET_OF(T, y));
    273 
    274     // Move a literal into a register that can be encoded in the instruction.
    275     __ vmov(d4, 1.0);
    276     __ vstr(d4, r4, OFFSET_OF(T, e));
    277 
    278     // Move a literal into a register that requires 64 bits to encode.
    279     // 0x3ff0000010000000 = 1.000000059604644775390625
    280     __ vmov(d4, 1.000000059604644775390625);
    281     __ vstr(d4, r4, OFFSET_OF(T, d));
    282 
    283     // Convert from floating point to integer.
    284     __ vmov(d4, 2.0);
    285     __ vcvt_s32_f64(s31, d4);
    286     __ vstr(s31, r4, OFFSET_OF(T, i));
    287 
    288     // Convert from integer to floating point.
    289     __ mov(lr, Operand(42));
    290     __ vmov(s31, lr);
    291     __ vcvt_f64_s32(d4, s31);
    292     __ vstr(d4, r4, OFFSET_OF(T, f));
    293 
    294     // Convert from fixed point to floating point.
    295     __ mov(lr, Operand(1234));
    296     __ vmov(s8, lr);
    297     __ vcvt_f64_s32(d4, 1);
    298     __ vstr(d4, r4, OFFSET_OF(T, j));
    299 
    300     // Test vabs.
    301     __ vldr(d1, r4, OFFSET_OF(T, g));
    302     __ vabs(d0, d1);
    303     __ vstr(d0, r4, OFFSET_OF(T, g));
    304     __ vldr(d2, r4, OFFSET_OF(T, h));
    305     __ vabs(d0, d2);
    306     __ vstr(d0, r4, OFFSET_OF(T, h));
    307 
    308     // Test vneg.
    309     __ vldr(d1, r4, OFFSET_OF(T, m));
    310     __ vneg(d0, d1);
    311     __ vstr(d0, r4, OFFSET_OF(T, m));
    312     __ vldr(d1, r4, OFFSET_OF(T, n));
    313     __ vneg(d0, d1);
    314     __ vstr(d0, r4, OFFSET_OF(T, n));
    315 
    316     __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
    317 
    318     CodeDesc desc;
    319     assm.GetCode(&desc);
    320     Object* code = isolate->heap()->CreateCode(
    321         desc,
    322         Code::ComputeFlags(Code::STUB),
    323         Handle<Code>())->ToObjectChecked();
    324     CHECK(code->IsCode());
    325 #ifdef DEBUG
    326     Code::cast(code)->Print();
    327 #endif
    328     F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
    329     t.a = 1.5;
    330     t.b = 2.75;
    331     t.c = 17.17;
    332     t.d = 0.0;
    333     t.e = 0.0;
    334     t.f = 0.0;
    335     t.g = -2718.2818;
    336     t.h = 31415926.5;
    337     t.i = 0;
    338     t.j = 0;
    339     t.m = -2718.2818;
    340     t.n = 123.456;
    341     t.x = 4.5;
    342     t.y = 9.0;
    343     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    344     USE(dummy);
    345     CHECK_EQ(4.5, t.y);
    346     CHECK_EQ(9.0, t.x);
    347     CHECK_EQ(-123.456, t.n);
    348     CHECK_EQ(2718.2818, t.m);
    349     CHECK_EQ(2, t.i);
    350     CHECK_EQ(2718.2818, t.g);
    351     CHECK_EQ(31415926.5, t.h);
    352     CHECK_EQ(617.0, t.j);
    353     CHECK_EQ(42.0, t.f);
    354     CHECK_EQ(1.0, t.e);
    355     CHECK_EQ(1.000000059604644775390625, t.d);
    356     CHECK_EQ(4.25, t.c);
    357     CHECK_EQ(-4.1875, t.b);
    358     CHECK_EQ(1.5, t.a);
    359   }
    360 }
    361 
    362 
    363 TEST(5) {
    364   // Test the ARMv7 bitfield instructions.
    365   CcTest::InitializeVM();
    366   Isolate* isolate = Isolate::Current();
    367   HandleScope scope(isolate);
    368 
    369   Assembler assm(isolate, NULL, 0);
    370 
    371   if (CpuFeatures::IsSupported(ARMv7)) {
    372     CpuFeatureScope scope(&assm, ARMv7);
    373     // On entry, r0 = 0xAAAAAAAA = 0b10..10101010.
    374     __ ubfx(r0, r0, 1, 12);  // 0b00..010101010101 = 0x555
    375     __ sbfx(r0, r0, 0, 5);   // 0b11..111111110101 = -11
    376     __ bfc(r0, 1, 3);        // 0b11..111111110001 = -15
    377     __ mov(r1, Operand(7));
    378     __ bfi(r0, r1, 3, 3);    // 0b11..111111111001 = -7
    379     __ mov(pc, Operand(lr));
    380 
    381     CodeDesc desc;
    382     assm.GetCode(&desc);
    383     Object* code = isolate->heap()->CreateCode(
    384         desc,
    385         Code::ComputeFlags(Code::STUB),
    386         Handle<Code>())->ToObjectChecked();
    387     CHECK(code->IsCode());
    388 #ifdef DEBUG
    389     Code::cast(code)->Print();
    390 #endif
    391     F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
    392     int res = reinterpret_cast<int>(
    393                 CALL_GENERATED_CODE(f, 0xAAAAAAAA, 0, 0, 0, 0));
    394     ::printf("f() = %d\n", res);
    395     CHECK_EQ(-7, res);
    396   }
    397 }
    398 
    399 
    400 TEST(6) {
    401   // Test saturating instructions.
    402   CcTest::InitializeVM();
    403   Isolate* isolate = Isolate::Current();
    404   HandleScope scope(isolate);
    405 
    406   Assembler assm(isolate, NULL, 0);
    407 
    408   if (CpuFeatures::IsSupported(ARMv7)) {
    409     CpuFeatureScope scope(&assm, ARMv7);
    410     __ usat(r1, 8, Operand(r0));           // Sat 0xFFFF to 0-255 = 0xFF.
    411     __ usat(r2, 12, Operand(r0, ASR, 9));  // Sat (0xFFFF>>9) to 0-4095 = 0x7F.
    412     __ usat(r3, 1, Operand(r0, LSL, 16));  // Sat (0xFFFF<<16) to 0-1 = 0x0.
    413     __ add(r0, r1, Operand(r2));
    414     __ add(r0, r0, Operand(r3));
    415     __ mov(pc, Operand(lr));
    416 
    417     CodeDesc desc;
    418     assm.GetCode(&desc);
    419     Object* code = isolate->heap()->CreateCode(
    420         desc,
    421         Code::ComputeFlags(Code::STUB),
    422         Handle<Code>())->ToObjectChecked();
    423     CHECK(code->IsCode());
    424 #ifdef DEBUG
    425     Code::cast(code)->Print();
    426 #endif
    427     F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
    428     int res = reinterpret_cast<int>(
    429                 CALL_GENERATED_CODE(f, 0xFFFF, 0, 0, 0, 0));
    430     ::printf("f() = %d\n", res);
    431     CHECK_EQ(382, res);
    432   }
    433 }
    434 
    435 
    436 enum VCVTTypes {
    437   s32_f64,
    438   u32_f64
    439 };
    440 
    441 static void TestRoundingMode(VCVTTypes types,
    442                              VFPRoundingMode mode,
    443                              double value,
    444                              int expected,
    445                              bool expected_exception = false) {
    446   CcTest::InitializeVM();
    447   Isolate* isolate = Isolate::Current();
    448   HandleScope scope(isolate);
    449 
    450   Assembler assm(isolate, NULL, 0);
    451 
    452   if (CpuFeatures::IsSupported(VFP3)) {
    453     CpuFeatureScope scope(&assm, VFP3);
    454 
    455     Label wrong_exception;
    456 
    457     __ vmrs(r1);
    458     // Set custom FPSCR.
    459     __ bic(r2, r1, Operand(kVFPRoundingModeMask | kVFPExceptionMask));
    460     __ orr(r2, r2, Operand(mode));
    461     __ vmsr(r2);
    462 
    463     // Load value, convert, and move back result to r0 if everything went well.
    464     __ vmov(d1, value);
    465     switch (types) {
    466       case s32_f64:
    467         __ vcvt_s32_f64(s0, d1, kFPSCRRounding);
    468         break;
    469 
    470       case u32_f64:
    471         __ vcvt_u32_f64(s0, d1, kFPSCRRounding);
    472         break;
    473 
    474       default:
    475         UNREACHABLE();
    476         break;
    477     }
    478     // Check for vfp exceptions
    479     __ vmrs(r2);
    480     __ tst(r2, Operand(kVFPExceptionMask));
    481     // Check that we behaved as expected.
    482     __ b(&wrong_exception,
    483          expected_exception ? eq : ne);
    484     // There was no exception. Retrieve the result and return.
    485     __ vmov(r0, s0);
    486     __ mov(pc, Operand(lr));
    487 
    488     // The exception behaviour is not what we expected.
    489     // Load a special value and return.
    490     __ bind(&wrong_exception);
    491     __ mov(r0, Operand(11223344));
    492     __ mov(pc, Operand(lr));
    493 
    494     CodeDesc desc;
    495     assm.GetCode(&desc);
    496     Object* code = isolate->heap()->CreateCode(
    497         desc,
    498         Code::ComputeFlags(Code::STUB),
    499         Handle<Code>())->ToObjectChecked();
    500     CHECK(code->IsCode());
    501 #ifdef DEBUG
    502     Code::cast(code)->Print();
    503 #endif
    504     F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
    505     int res = reinterpret_cast<int>(
    506                 CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
    507     ::printf("res = %d\n", res);
    508     CHECK_EQ(expected, res);
    509   }
    510 }
    511 
    512 
    513 TEST(7) {
    514   // Test vfp rounding modes.
    515 
    516   // s32_f64 (double to integer).
    517 
    518   TestRoundingMode(s32_f64, RN,  0, 0);
    519   TestRoundingMode(s32_f64, RN,  0.5, 0);
    520   TestRoundingMode(s32_f64, RN, -0.5, 0);
    521   TestRoundingMode(s32_f64, RN,  1.5, 2);
    522   TestRoundingMode(s32_f64, RN, -1.5, -2);
    523   TestRoundingMode(s32_f64, RN,  123.7, 124);
    524   TestRoundingMode(s32_f64, RN, -123.7, -124);
    525   TestRoundingMode(s32_f64, RN,  123456.2,  123456);
    526   TestRoundingMode(s32_f64, RN, -123456.2, -123456);
    527   TestRoundingMode(s32_f64, RN, static_cast<double>(kMaxInt), kMaxInt);
    528   TestRoundingMode(s32_f64, RN, (kMaxInt + 0.49), kMaxInt);
    529   TestRoundingMode(s32_f64, RN, (kMaxInt + 1.0), kMaxInt, true);
    530   TestRoundingMode(s32_f64, RN, (kMaxInt + 0.5), kMaxInt, true);
    531   TestRoundingMode(s32_f64, RN, static_cast<double>(kMinInt), kMinInt);
    532   TestRoundingMode(s32_f64, RN, (kMinInt - 0.5), kMinInt);
    533   TestRoundingMode(s32_f64, RN, (kMinInt - 1.0), kMinInt, true);
    534   TestRoundingMode(s32_f64, RN, (kMinInt - 0.51), kMinInt, true);
    535 
    536   TestRoundingMode(s32_f64, RM,  0, 0);
    537   TestRoundingMode(s32_f64, RM,  0.5, 0);
    538   TestRoundingMode(s32_f64, RM, -0.5, -1);
    539   TestRoundingMode(s32_f64, RM,  123.7, 123);
    540   TestRoundingMode(s32_f64, RM, -123.7, -124);
    541   TestRoundingMode(s32_f64, RM,  123456.2,  123456);
    542   TestRoundingMode(s32_f64, RM, -123456.2, -123457);
    543   TestRoundingMode(s32_f64, RM, static_cast<double>(kMaxInt), kMaxInt);
    544   TestRoundingMode(s32_f64, RM, (kMaxInt + 0.5), kMaxInt);
    545   TestRoundingMode(s32_f64, RM, (kMaxInt + 1.0), kMaxInt, true);
    546   TestRoundingMode(s32_f64, RM, static_cast<double>(kMinInt), kMinInt);
    547   TestRoundingMode(s32_f64, RM, (kMinInt - 0.5), kMinInt, true);
    548   TestRoundingMode(s32_f64, RM, (kMinInt + 0.5), kMinInt);
    549 
    550   TestRoundingMode(s32_f64, RZ,  0, 0);
    551   TestRoundingMode(s32_f64, RZ,  0.5, 0);
    552   TestRoundingMode(s32_f64, RZ, -0.5, 0);
    553   TestRoundingMode(s32_f64, RZ,  123.7,  123);
    554   TestRoundingMode(s32_f64, RZ, -123.7, -123);
    555   TestRoundingMode(s32_f64, RZ,  123456.2,  123456);
    556   TestRoundingMode(s32_f64, RZ, -123456.2, -123456);
    557   TestRoundingMode(s32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt);
    558   TestRoundingMode(s32_f64, RZ, (kMaxInt + 0.5), kMaxInt);
    559   TestRoundingMode(s32_f64, RZ, (kMaxInt + 1.0), kMaxInt, true);
    560   TestRoundingMode(s32_f64, RZ, static_cast<double>(kMinInt), kMinInt);
    561   TestRoundingMode(s32_f64, RZ, (kMinInt - 0.5), kMinInt);
    562   TestRoundingMode(s32_f64, RZ, (kMinInt - 1.0), kMinInt, true);
    563 
    564 
    565   // u32_f64 (double to integer).
    566 
    567   // Negative values.
    568   TestRoundingMode(u32_f64, RN, -0.5, 0);
    569   TestRoundingMode(u32_f64, RN, -123456.7, 0, true);
    570   TestRoundingMode(u32_f64, RN, static_cast<double>(kMinInt), 0, true);
    571   TestRoundingMode(u32_f64, RN, kMinInt - 1.0, 0, true);
    572 
    573   TestRoundingMode(u32_f64, RM, -0.5, 0, true);
    574   TestRoundingMode(u32_f64, RM, -123456.7, 0, true);
    575   TestRoundingMode(u32_f64, RM, static_cast<double>(kMinInt), 0, true);
    576   TestRoundingMode(u32_f64, RM, kMinInt - 1.0, 0, true);
    577 
    578   TestRoundingMode(u32_f64, RZ, -0.5, 0);
    579   TestRoundingMode(u32_f64, RZ, -123456.7, 0, true);
    580   TestRoundingMode(u32_f64, RZ, static_cast<double>(kMinInt), 0, true);
    581   TestRoundingMode(u32_f64, RZ, kMinInt - 1.0, 0, true);
    582 
    583   // Positive values.
    584   // kMaxInt is the maximum *signed* integer: 0x7fffffff.
    585   static const uint32_t kMaxUInt = 0xffffffffu;
    586   TestRoundingMode(u32_f64, RZ,  0, 0);
    587   TestRoundingMode(u32_f64, RZ,  0.5, 0);
    588   TestRoundingMode(u32_f64, RZ,  123.7,  123);
    589   TestRoundingMode(u32_f64, RZ,  123456.2,  123456);
    590   TestRoundingMode(u32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt);
    591   TestRoundingMode(u32_f64, RZ, (kMaxInt + 0.5), kMaxInt);
    592   TestRoundingMode(u32_f64, RZ, (kMaxInt + 1.0),
    593                                 static_cast<uint32_t>(kMaxInt) + 1);
    594   TestRoundingMode(u32_f64, RZ, (kMaxUInt + 0.5), kMaxUInt);
    595   TestRoundingMode(u32_f64, RZ, (kMaxUInt + 1.0), kMaxUInt, true);
    596 
    597   TestRoundingMode(u32_f64, RM,  0, 0);
    598   TestRoundingMode(u32_f64, RM,  0.5, 0);
    599   TestRoundingMode(u32_f64, RM,  123.7, 123);
    600   TestRoundingMode(u32_f64, RM,  123456.2,  123456);
    601   TestRoundingMode(u32_f64, RM, static_cast<double>(kMaxInt), kMaxInt);
    602   TestRoundingMode(u32_f64, RM, (kMaxInt + 0.5), kMaxInt);
    603   TestRoundingMode(u32_f64, RM, (kMaxInt + 1.0),
    604                                 static_cast<uint32_t>(kMaxInt) + 1);
    605   TestRoundingMode(u32_f64, RM, (kMaxUInt + 0.5), kMaxUInt);
    606   TestRoundingMode(u32_f64, RM, (kMaxUInt + 1.0), kMaxUInt, true);
    607 
    608   TestRoundingMode(u32_f64, RN,  0, 0);
    609   TestRoundingMode(u32_f64, RN,  0.5, 0);
    610   TestRoundingMode(u32_f64, RN,  1.5, 2);
    611   TestRoundingMode(u32_f64, RN,  123.7, 124);
    612   TestRoundingMode(u32_f64, RN,  123456.2,  123456);
    613   TestRoundingMode(u32_f64, RN, static_cast<double>(kMaxInt), kMaxInt);
    614   TestRoundingMode(u32_f64, RN, (kMaxInt + 0.49), kMaxInt);
    615   TestRoundingMode(u32_f64, RN, (kMaxInt + 0.5),
    616                                 static_cast<uint32_t>(kMaxInt) + 1);
    617   TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.49), kMaxUInt);
    618   TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.5), kMaxUInt, true);
    619   TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true);
    620 }
    621 
    622 
    623 TEST(8) {
    624   // Test VFP multi load/store with ia_w.
    625   CcTest::InitializeVM();
    626   Isolate* isolate = Isolate::Current();
    627   HandleScope scope(isolate);
    628 
    629   typedef struct {
    630     double a;
    631     double b;
    632     double c;
    633     double d;
    634     double e;
    635     double f;
    636     double g;
    637     double h;
    638   } D;
    639   D d;
    640 
    641   typedef struct {
    642     float a;
    643     float b;
    644     float c;
    645     float d;
    646     float e;
    647     float f;
    648     float g;
    649     float h;
    650   } F;
    651   F f;
    652 
    653   // Create a function that uses vldm/vstm to move some double and
    654   // single precision values around in memory.
    655   Assembler assm(isolate, NULL, 0);
    656 
    657   __ mov(ip, Operand(sp));
    658   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
    659   __ sub(fp, ip, Operand(4));
    660 
    661   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
    662   __ vldm(ia_w, r4, d0, d3);
    663   __ vldm(ia_w, r4, d4, d7);
    664 
    665   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
    666   __ vstm(ia_w, r4, d6, d7);
    667   __ vstm(ia_w, r4, d0, d5);
    668 
    669   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
    670   __ vldm(ia_w, r4, s0, s3);
    671   __ vldm(ia_w, r4, s4, s7);
    672 
    673   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
    674   __ vstm(ia_w, r4, s6, s7);
    675   __ vstm(ia_w, r4, s0, s5);
    676 
    677   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
    678 
    679   CodeDesc desc;
    680   assm.GetCode(&desc);
    681   Object* code = isolate->heap()->CreateCode(
    682       desc,
    683       Code::ComputeFlags(Code::STUB),
    684       Handle<Code>())->ToObjectChecked();
    685   CHECK(code->IsCode());
    686 #ifdef DEBUG
    687   Code::cast(code)->Print();
    688 #endif
    689   F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
    690   d.a = 1.1;
    691   d.b = 2.2;
    692   d.c = 3.3;
    693   d.d = 4.4;
    694   d.e = 5.5;
    695   d.f = 6.6;
    696   d.g = 7.7;
    697   d.h = 8.8;
    698 
    699   f.a = 1.0;
    700   f.b = 2.0;
    701   f.c = 3.0;
    702   f.d = 4.0;
    703   f.e = 5.0;
    704   f.f = 6.0;
    705   f.g = 7.0;
    706   f.h = 8.0;
    707 
    708   Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
    709   USE(dummy);
    710 
    711   CHECK_EQ(7.7, d.a);
    712   CHECK_EQ(8.8, d.b);
    713   CHECK_EQ(1.1, d.c);
    714   CHECK_EQ(2.2, d.d);
    715   CHECK_EQ(3.3, d.e);
    716   CHECK_EQ(4.4, d.f);
    717   CHECK_EQ(5.5, d.g);
    718   CHECK_EQ(6.6, d.h);
    719 
    720   CHECK_EQ(7.0, f.a);
    721   CHECK_EQ(8.0, f.b);
    722   CHECK_EQ(1.0, f.c);
    723   CHECK_EQ(2.0, f.d);
    724   CHECK_EQ(3.0, f.e);
    725   CHECK_EQ(4.0, f.f);
    726   CHECK_EQ(5.0, f.g);
    727   CHECK_EQ(6.0, f.h);
    728 }
    729 
    730 
    731 TEST(9) {
    732   // Test VFP multi load/store with ia.
    733   CcTest::InitializeVM();
    734   Isolate* isolate = Isolate::Current();
    735   HandleScope scope(isolate);
    736 
    737   typedef struct {
    738     double a;
    739     double b;
    740     double c;
    741     double d;
    742     double e;
    743     double f;
    744     double g;
    745     double h;
    746   } D;
    747   D d;
    748 
    749   typedef struct {
    750     float a;
    751     float b;
    752     float c;
    753     float d;
    754     float e;
    755     float f;
    756     float g;
    757     float h;
    758   } F;
    759   F f;
    760 
    761   // Create a function that uses vldm/vstm to move some double and
    762   // single precision values around in memory.
    763   Assembler assm(isolate, NULL, 0);
    764 
    765   __ mov(ip, Operand(sp));
    766   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
    767   __ sub(fp, ip, Operand(4));
    768 
    769   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
    770   __ vldm(ia, r4, d0, d3);
    771   __ add(r4, r4, Operand(4 * 8));
    772   __ vldm(ia, r4, d4, d7);
    773 
    774   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
    775   __ vstm(ia, r4, d6, d7);
    776   __ add(r4, r4, Operand(2 * 8));
    777   __ vstm(ia, r4, d0, d5);
    778 
    779   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
    780   __ vldm(ia, r4, s0, s3);
    781   __ add(r4, r4, Operand(4 * 4));
    782   __ vldm(ia, r4, s4, s7);
    783 
    784   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
    785   __ vstm(ia, r4, s6, s7);
    786   __ add(r4, r4, Operand(2 * 4));
    787   __ vstm(ia, r4, s0, s5);
    788 
    789   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
    790 
    791   CodeDesc desc;
    792   assm.GetCode(&desc);
    793   Object* code = isolate->heap()->CreateCode(
    794       desc,
    795       Code::ComputeFlags(Code::STUB),
    796       Handle<Code>())->ToObjectChecked();
    797   CHECK(code->IsCode());
    798 #ifdef DEBUG
    799   Code::cast(code)->Print();
    800 #endif
    801   F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
    802   d.a = 1.1;
    803   d.b = 2.2;
    804   d.c = 3.3;
    805   d.d = 4.4;
    806   d.e = 5.5;
    807   d.f = 6.6;
    808   d.g = 7.7;
    809   d.h = 8.8;
    810 
    811   f.a = 1.0;
    812   f.b = 2.0;
    813   f.c = 3.0;
    814   f.d = 4.0;
    815   f.e = 5.0;
    816   f.f = 6.0;
    817   f.g = 7.0;
    818   f.h = 8.0;
    819 
    820   Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
    821   USE(dummy);
    822 
    823   CHECK_EQ(7.7, d.a);
    824   CHECK_EQ(8.8, d.b);
    825   CHECK_EQ(1.1, d.c);
    826   CHECK_EQ(2.2, d.d);
    827   CHECK_EQ(3.3, d.e);
    828   CHECK_EQ(4.4, d.f);
    829   CHECK_EQ(5.5, d.g);
    830   CHECK_EQ(6.6, d.h);
    831 
    832   CHECK_EQ(7.0, f.a);
    833   CHECK_EQ(8.0, f.b);
    834   CHECK_EQ(1.0, f.c);
    835   CHECK_EQ(2.0, f.d);
    836   CHECK_EQ(3.0, f.e);
    837   CHECK_EQ(4.0, f.f);
    838   CHECK_EQ(5.0, f.g);
    839   CHECK_EQ(6.0, f.h);
    840 }
    841 
    842 
    843 TEST(10) {
    844   // Test VFP multi load/store with db_w.
    845   CcTest::InitializeVM();
    846   Isolate* isolate = Isolate::Current();
    847   HandleScope scope(isolate);
    848 
    849   typedef struct {
    850     double a;
    851     double b;
    852     double c;
    853     double d;
    854     double e;
    855     double f;
    856     double g;
    857     double h;
    858   } D;
    859   D d;
    860 
    861   typedef struct {
    862     float a;
    863     float b;
    864     float c;
    865     float d;
    866     float e;
    867     float f;
    868     float g;
    869     float h;
    870   } F;
    871   F f;
    872 
    873   // Create a function that uses vldm/vstm to move some double and
    874   // single precision values around in memory.
    875   Assembler assm(isolate, NULL, 0);
    876 
    877   __ mov(ip, Operand(sp));
    878   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
    879   __ sub(fp, ip, Operand(4));
    880 
    881   __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
    882   __ vldm(db_w, r4, d4, d7);
    883   __ vldm(db_w, r4, d0, d3);
    884 
    885   __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
    886   __ vstm(db_w, r4, d0, d5);
    887   __ vstm(db_w, r4, d6, d7);
    888 
    889   __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
    890   __ vldm(db_w, r4, s4, s7);
    891   __ vldm(db_w, r4, s0, s3);
    892 
    893   __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
    894   __ vstm(db_w, r4, s0, s5);
    895   __ vstm(db_w, r4, s6, s7);
    896 
    897   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
    898 
    899   CodeDesc desc;
    900   assm.GetCode(&desc);
    901   Object* code = isolate->heap()->CreateCode(
    902       desc,
    903       Code::ComputeFlags(Code::STUB),
    904       Handle<Code>())->ToObjectChecked();
    905   CHECK(code->IsCode());
    906 #ifdef DEBUG
    907   Code::cast(code)->Print();
    908 #endif
    909   F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
    910   d.a = 1.1;
    911   d.b = 2.2;
    912   d.c = 3.3;
    913   d.d = 4.4;
    914   d.e = 5.5;
    915   d.f = 6.6;
    916   d.g = 7.7;
    917   d.h = 8.8;
    918 
    919   f.a = 1.0;
    920   f.b = 2.0;
    921   f.c = 3.0;
    922   f.d = 4.0;
    923   f.e = 5.0;
    924   f.f = 6.0;
    925   f.g = 7.0;
    926   f.h = 8.0;
    927 
    928   Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
    929   USE(dummy);
    930 
    931   CHECK_EQ(7.7, d.a);
    932   CHECK_EQ(8.8, d.b);
    933   CHECK_EQ(1.1, d.c);
    934   CHECK_EQ(2.2, d.d);
    935   CHECK_EQ(3.3, d.e);
    936   CHECK_EQ(4.4, d.f);
    937   CHECK_EQ(5.5, d.g);
    938   CHECK_EQ(6.6, d.h);
    939 
    940   CHECK_EQ(7.0, f.a);
    941   CHECK_EQ(8.0, f.b);
    942   CHECK_EQ(1.0, f.c);
    943   CHECK_EQ(2.0, f.d);
    944   CHECK_EQ(3.0, f.e);
    945   CHECK_EQ(4.0, f.f);
    946   CHECK_EQ(5.0, f.g);
    947   CHECK_EQ(6.0, f.h);
    948 }
    949 
    950 
    951 TEST(11) {
    952   // Test instructions using the carry flag.
    953   CcTest::InitializeVM();
    954   Isolate* isolate = Isolate::Current();
    955   HandleScope scope(isolate);
    956 
    957   typedef struct {
    958     int32_t a;
    959     int32_t b;
    960     int32_t c;
    961     int32_t d;
    962   } I;
    963   I i;
    964 
    965   i.a = 0xabcd0001;
    966   i.b = 0xabcd0000;
    967 
    968   Assembler assm(isolate, NULL, 0);
    969 
    970   // Test HeapObject untagging.
    971   __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
    972   __ mov(r1, Operand(r1, ASR, 1), SetCC);
    973   __ adc(r1, r1, Operand(r1), LeaveCC, cs);
    974   __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
    975 
    976   __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
    977   __ mov(r2, Operand(r2, ASR, 1), SetCC);
    978   __ adc(r2, r2, Operand(r2), LeaveCC, cs);
    979   __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
    980 
    981   // Test corner cases.
    982   __ mov(r1, Operand(0xffffffff));
    983   __ mov(r2, Operand::Zero());
    984   __ mov(r3, Operand(r1, ASR, 1), SetCC);  // Set the carry.
    985   __ adc(r3, r1, Operand(r2));
    986   __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
    987 
    988   __ mov(r1, Operand(0xffffffff));
    989   __ mov(r2, Operand::Zero());
    990   __ mov(r3, Operand(r2, ASR, 1), SetCC);  // Unset the carry.
    991   __ adc(r3, r1, Operand(r2));
    992   __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
    993 
    994   __ mov(pc, Operand(lr));
    995 
    996   CodeDesc desc;
    997   assm.GetCode(&desc);
    998   Object* code = isolate->heap()->CreateCode(
    999       desc,
   1000       Code::ComputeFlags(Code::STUB),
   1001       Handle<Code>())->ToObjectChecked();
   1002   CHECK(code->IsCode());
   1003 #ifdef DEBUG
   1004   Code::cast(code)->Print();
   1005 #endif
   1006   F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
   1007   Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0);
   1008   USE(dummy);
   1009 
   1010   CHECK_EQ(0xabcd0001, i.a);
   1011   CHECK_EQ(static_cast<int32_t>(0xabcd0000) >> 1, i.b);
   1012   CHECK_EQ(0x00000000, i.c);
   1013   CHECK_EQ(0xffffffff, i.d);
   1014 }
   1015 
   1016 
   1017 TEST(12) {
   1018   // Test chaining of label usages within instructions (issue 1644).
   1019   CcTest::InitializeVM();
   1020   Isolate* isolate = Isolate::Current();
   1021   HandleScope scope(isolate);
   1022 
   1023   Assembler assm(isolate, NULL, 0);
   1024   Label target;
   1025   __ b(eq, &target);
   1026   __ b(ne, &target);
   1027   __ bind(&target);
   1028   __ nop();
   1029 }
   1030 
   1031 
   1032 TEST(13) {
   1033   // Test VFP instructions using registers d16-d31.
   1034   CcTest::InitializeVM();
   1035   Isolate* isolate = Isolate::Current();
   1036   HandleScope scope(isolate);
   1037 
   1038   if (!CpuFeatures::IsSupported(VFP32DREGS)) {
   1039     return;
   1040   }
   1041 
   1042   typedef struct {
   1043     double a;
   1044     double b;
   1045     double c;
   1046     double x;
   1047     double y;
   1048     double z;
   1049     double i;
   1050     double j;
   1051     double k;
   1052     uint32_t low;
   1053     uint32_t high;
   1054   } T;
   1055   T t;
   1056 
   1057   // Create a function that accepts &t, and loads, manipulates, and stores
   1058   // the doubles and floats.
   1059   Assembler assm(isolate, NULL, 0);
   1060   Label L, C;
   1061 
   1062 
   1063   if (CpuFeatures::IsSupported(VFP3)) {
   1064     CpuFeatureScope scope(&assm, VFP3);
   1065 
   1066     __ stm(db_w, sp, r4.bit() | lr.bit());
   1067 
   1068     // Load a, b, c into d16, d17, d18.
   1069     __ mov(r4, Operand(r0));
   1070     __ vldr(d16, r4, OFFSET_OF(T, a));
   1071     __ vldr(d17, r4, OFFSET_OF(T, b));
   1072     __ vldr(d18, r4, OFFSET_OF(T, c));
   1073 
   1074     __ vneg(d25, d16);
   1075     __ vadd(d25, d25, d17);
   1076     __ vsub(d25, d25, d18);
   1077     __ vmul(d25, d25, d25);
   1078     __ vdiv(d25, d25, d18);
   1079 
   1080     __ vmov(d16, d25);
   1081     __ vsqrt(d17, d25);
   1082     __ vneg(d17, d17);
   1083     __ vabs(d17, d17);
   1084     __ vmla(d18, d16, d17);
   1085 
   1086     // Store d16, d17, d18 into a, b, c.
   1087     __ mov(r4, Operand(r0));
   1088     __ vstr(d16, r4, OFFSET_OF(T, a));
   1089     __ vstr(d17, r4, OFFSET_OF(T, b));
   1090     __ vstr(d18, r4, OFFSET_OF(T, c));
   1091 
   1092     // Load x, y, z into d29-d31.
   1093     __ add(r4, r0, Operand(OFFSET_OF(T, x)));
   1094     __ vldm(ia_w, r4, d29, d31);
   1095 
   1096     // Swap d29 and d30 via r registers.
   1097     __ vmov(r1, r2, d29);
   1098     __ vmov(d29, d30);
   1099     __ vmov(d30, r1, r2);
   1100 
   1101     // Convert to and from integer.
   1102     __ vcvt_s32_f64(s1, d31);
   1103     __ vcvt_f64_u32(d31, s1);
   1104 
   1105     // Store d29-d31 into x, y, z.
   1106     __ add(r4, r0, Operand(OFFSET_OF(T, x)));
   1107     __ vstm(ia_w, r4, d29, d31);
   1108 
   1109     // Move constants into d20, d21, d22 and store into i, j, k.
   1110     __ vmov(d20, 14.7610017472335499);
   1111     __ vmov(d21, 16.0);
   1112     __ mov(r1, Operand(372106121));
   1113     __ mov(r2, Operand(1079146608));
   1114     __ vmov(d22, VmovIndexLo, r1);
   1115     __ vmov(d22, VmovIndexHi, r2);
   1116     __ add(r4, r0, Operand(OFFSET_OF(T, i)));
   1117     __ vstm(ia_w, r4, d20, d22);
   1118     // Move d22 into low and high.
   1119     __ vmov(r4, VmovIndexLo, d22);
   1120     __ str(r4, MemOperand(r0, OFFSET_OF(T, low)));
   1121     __ vmov(r4, VmovIndexHi, d22);
   1122     __ str(r4, MemOperand(r0, OFFSET_OF(T, high)));
   1123 
   1124     __ ldm(ia_w, sp, r4.bit() | pc.bit());
   1125 
   1126     CodeDesc desc;
   1127     assm.GetCode(&desc);
   1128     Object* code = isolate->heap()->CreateCode(
   1129         desc,
   1130         Code::ComputeFlags(Code::STUB),
   1131         Handle<Code>())->ToObjectChecked();
   1132     CHECK(code->IsCode());
   1133 #ifdef DEBUG
   1134     Code::cast(code)->Print();
   1135 #endif
   1136     F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
   1137     t.a = 1.5;
   1138     t.b = 2.75;
   1139     t.c = 17.17;
   1140     t.x = 1.5;
   1141     t.y = 2.75;
   1142     t.z = 17.17;
   1143     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1144     USE(dummy);
   1145     CHECK_EQ(14.7610017472335499, t.a);
   1146     CHECK_EQ(3.84200491244266251, t.b);
   1147     CHECK_EQ(73.8818412254460241, t.c);
   1148     CHECK_EQ(2.75, t.x);
   1149     CHECK_EQ(1.5, t.y);
   1150     CHECK_EQ(17.0, t.z);
   1151     CHECK_EQ(14.7610017472335499, t.i);
   1152     CHECK_EQ(16.0, t.j);
   1153     CHECK_EQ(73.8818412254460241, t.k);
   1154     CHECK_EQ(372106121, t.low);
   1155     CHECK_EQ(1079146608, t.high);
   1156   }
   1157 }
   1158 
   1159 
   1160 TEST(14) {
   1161   // Test the VFP Canonicalized Nan mode.
   1162   CcTest::InitializeVM();
   1163   Isolate* isolate = Isolate::Current();
   1164   HandleScope scope(isolate);
   1165 
   1166   typedef struct {
   1167     double left;
   1168     double right;
   1169     double add_result;
   1170     double sub_result;
   1171     double mul_result;
   1172     double div_result;
   1173   } T;
   1174   T t;
   1175 
   1176   // Create a function that makes the four basic operations.
   1177   Assembler assm(isolate, NULL, 0);
   1178 
   1179   // Ensure FPSCR state (as JSEntryStub does).
   1180   Label fpscr_done;
   1181   __ vmrs(r1);
   1182   __ tst(r1, Operand(kVFPDefaultNaNModeControlBit));
   1183   __ b(ne, &fpscr_done);
   1184   __ orr(r1, r1, Operand(kVFPDefaultNaNModeControlBit));
   1185   __ vmsr(r1);
   1186   __ bind(&fpscr_done);
   1187 
   1188   __ vldr(d0, r0, OFFSET_OF(T, left));
   1189   __ vldr(d1, r0, OFFSET_OF(T, right));
   1190   __ vadd(d2, d0, d1);
   1191   __ vstr(d2, r0, OFFSET_OF(T, add_result));
   1192   __ vsub(d2, d0, d1);
   1193   __ vstr(d2, r0, OFFSET_OF(T, sub_result));
   1194   __ vmul(d2, d0, d1);
   1195   __ vstr(d2, r0, OFFSET_OF(T, mul_result));
   1196   __ vdiv(d2, d0, d1);
   1197   __ vstr(d2, r0, OFFSET_OF(T, div_result));
   1198 
   1199   __ mov(pc, Operand(lr));
   1200 
   1201   CodeDesc desc;
   1202   assm.GetCode(&desc);
   1203   Object* code = isolate->heap()->CreateCode(
   1204       desc,
   1205       Code::ComputeFlags(Code::STUB),
   1206       Handle<Code>())->ToObjectChecked();
   1207   CHECK(code->IsCode());
   1208 #ifdef DEBUG
   1209   Code::cast(code)->Print();
   1210 #endif
   1211   F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
   1212   t.left = BitCast<double>(kHoleNanInt64);
   1213   t.right = 1;
   1214   t.add_result = 0;
   1215   t.sub_result = 0;
   1216   t.mul_result = 0;
   1217   t.div_result = 0;
   1218   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1219   USE(dummy);
   1220   const uint32_t kArmNanUpper32 = 0x7ff80000;
   1221   const uint32_t kArmNanLower32 = 0x00000000;
   1222 #ifdef DEBUG
   1223   const uint64_t kArmNanInt64 =
   1224       (static_cast<uint64_t>(kArmNanUpper32) << 32) | kArmNanLower32;
   1225   ASSERT(kArmNanInt64 != kHoleNanInt64);
   1226 #endif
   1227   // With VFP2 the sign of the canonicalized Nan is undefined. So
   1228   // we remove the sign bit for the upper tests.
   1229   CHECK_EQ(kArmNanUpper32, (BitCast<int64_t>(t.add_result) >> 32) & 0x7fffffff);
   1230   CHECK_EQ(kArmNanLower32, BitCast<int64_t>(t.add_result) & 0xffffffffu);
   1231   CHECK_EQ(kArmNanUpper32, (BitCast<int64_t>(t.sub_result) >> 32) & 0x7fffffff);
   1232   CHECK_EQ(kArmNanLower32, BitCast<int64_t>(t.sub_result) & 0xffffffffu);
   1233   CHECK_EQ(kArmNanUpper32, (BitCast<int64_t>(t.mul_result) >> 32) & 0x7fffffff);
   1234   CHECK_EQ(kArmNanLower32, BitCast<int64_t>(t.mul_result) & 0xffffffffu);
   1235   CHECK_EQ(kArmNanUpper32, (BitCast<int64_t>(t.div_result) >> 32) & 0x7fffffff);
   1236   CHECK_EQ(kArmNanLower32, BitCast<int64_t>(t.div_result) & 0xffffffffu);
   1237 }
   1238 
   1239 
   1240 TEST(15) {
   1241   // Test the Neon instructions.
   1242   CcTest::InitializeVM();
   1243   Isolate* isolate = Isolate::Current();
   1244   HandleScope scope(isolate);
   1245 
   1246   typedef struct {
   1247     uint32_t src0;
   1248     uint32_t src1;
   1249     uint32_t src2;
   1250     uint32_t src3;
   1251     uint32_t src4;
   1252     uint32_t src5;
   1253     uint32_t src6;
   1254     uint32_t src7;
   1255     uint32_t dst0;
   1256     uint32_t dst1;
   1257     uint32_t dst2;
   1258     uint32_t dst3;
   1259     uint32_t dst4;
   1260     uint32_t dst5;
   1261     uint32_t dst6;
   1262     uint32_t dst7;
   1263     uint32_t srcA0;
   1264     uint32_t srcA1;
   1265     uint32_t dstA0;
   1266     uint32_t dstA1;
   1267     uint32_t dstA2;
   1268     uint32_t dstA3;
   1269   } T;
   1270   T t;
   1271 
   1272   // Create a function that accepts &t, and loads, manipulates, and stores
   1273   // the doubles and floats.
   1274   Assembler assm(isolate, NULL, 0);
   1275 
   1276 
   1277   if (CpuFeatures::IsSupported(NEON)) {
   1278     CpuFeatureScope scope(&assm, NEON);
   1279 
   1280     __ stm(db_w, sp, r4.bit() | lr.bit());
   1281     // Move 32 bytes with neon.
   1282     __ add(r4, r0, Operand(OFFSET_OF(T, src0)));
   1283     __ vld1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
   1284     __ add(r4, r0, Operand(OFFSET_OF(T, dst0)));
   1285     __ vst1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
   1286 
   1287     // Expand 8 bytes into 8 words(16 bits).
   1288     __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
   1289     __ vld1(Neon8, NeonListOperand(d0), NeonMemOperand(r4));
   1290     __ vmovl(NeonU8, q0, d0);
   1291     __ add(r4, r0, Operand(OFFSET_OF(T, dstA0)));
   1292     __ vst1(Neon8, NeonListOperand(d0, 2), NeonMemOperand(r4));
   1293 
   1294   __ ldm(ia_w, sp, r4.bit() | pc.bit());
   1295 
   1296     CodeDesc desc;
   1297     assm.GetCode(&desc);
   1298     Object* code = isolate->heap()->CreateCode(
   1299         desc,
   1300         Code::ComputeFlags(Code::STUB),
   1301         Handle<Code>())->ToObjectChecked();
   1302     CHECK(code->IsCode());
   1303 #ifdef DEBUG
   1304     Code::cast(code)->Print();
   1305 #endif
   1306     F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
   1307     t.src0 = 0x01020304;
   1308     t.src1 = 0x11121314;
   1309     t.src2 = 0x21222324;
   1310     t.src3 = 0x31323334;
   1311     t.src4 = 0x41424344;
   1312     t.src5 = 0x51525354;
   1313     t.src6 = 0x61626364;
   1314     t.src7 = 0x71727374;
   1315     t.dst0 = 0;
   1316     t.dst1 = 0;
   1317     t.dst2 = 0;
   1318     t.dst3 = 0;
   1319     t.dst4 = 0;
   1320     t.dst5 = 0;
   1321     t.dst6 = 0;
   1322     t.dst7 = 0;
   1323     t.srcA0 = 0x41424344;
   1324     t.srcA1 = 0x81828384;
   1325     t.dstA0 = 0;
   1326     t.dstA1 = 0;
   1327     t.dstA2 = 0;
   1328     t.dstA3 = 0;
   1329     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1330     USE(dummy);
   1331     CHECK_EQ(0x01020304, t.dst0);
   1332     CHECK_EQ(0x11121314, t.dst1);
   1333     CHECK_EQ(0x21222324, t.dst2);
   1334     CHECK_EQ(0x31323334, t.dst3);
   1335     CHECK_EQ(0x41424344, t.dst4);
   1336     CHECK_EQ(0x51525354, t.dst5);
   1337     CHECK_EQ(0x61626364, t.dst6);
   1338     CHECK_EQ(0x71727374, t.dst7);
   1339     CHECK_EQ(0x00430044, t.dstA0);
   1340     CHECK_EQ(0x00410042, t.dstA1);
   1341     CHECK_EQ(0x00830084, t.dstA2);
   1342     CHECK_EQ(0x00810082, t.dstA3);
   1343   }
   1344 }
   1345 
   1346 
   1347 TEST(16) {
   1348   // Test the pkh, uxtb, uxtab and uxtb16 instructions.
   1349   CcTest::InitializeVM();
   1350   Isolate* isolate = Isolate::Current();
   1351   HandleScope scope(isolate);
   1352 
   1353   typedef struct {
   1354     uint32_t src0;
   1355     uint32_t src1;
   1356     uint32_t src2;
   1357     uint32_t dst0;
   1358     uint32_t dst1;
   1359     uint32_t dst2;
   1360     uint32_t dst3;
   1361     uint32_t dst4;
   1362   } T;
   1363   T t;
   1364 
   1365   // Create a function that accepts &t, and loads, manipulates, and stores
   1366   // the doubles and floats.
   1367   Assembler assm(isolate, NULL, 0);
   1368 
   1369   __ stm(db_w, sp, r4.bit() | lr.bit());
   1370 
   1371   __ mov(r4, Operand(r0));
   1372   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src0)));
   1373   __ ldr(r1, MemOperand(r4, OFFSET_OF(T, src1)));
   1374 
   1375   __ pkhbt(r2, r0, Operand(r1, LSL, 8));
   1376   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst0)));
   1377 
   1378   __ pkhtb(r2, r0, Operand(r1, ASR, 8));
   1379   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst1)));
   1380 
   1381   __ uxtb16(r2, Operand(r0, ROR, 8));
   1382   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst2)));
   1383 
   1384   __ uxtb(r2, Operand(r0, ROR, 8));
   1385   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst3)));
   1386 
   1387   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src2)));
   1388   __ uxtab(r2, r0, Operand(r1, ROR, 8));
   1389   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst4)));
   1390 
   1391   __ ldm(ia_w, sp, r4.bit() | pc.bit());
   1392 
   1393   CodeDesc desc;
   1394   assm.GetCode(&desc);
   1395   Object* code = isolate->heap()->CreateCode(
   1396       desc,
   1397       Code::ComputeFlags(Code::STUB),
   1398       Handle<Code>())->ToObjectChecked();
   1399   CHECK(code->IsCode());
   1400 #ifdef DEBUG
   1401   Code::cast(code)->Print();
   1402 #endif
   1403   F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
   1404   t.src0 = 0x01020304;
   1405   t.src1 = 0x11121314;
   1406   t.src2 = 0x11121300;
   1407   t.dst0 = 0;
   1408   t.dst1 = 0;
   1409   t.dst2 = 0;
   1410   t.dst3 = 0;
   1411   t.dst4 = 0;
   1412   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1413   USE(dummy);
   1414   CHECK_EQ(0x12130304, t.dst0);
   1415   CHECK_EQ(0x01021213, t.dst1);
   1416   CHECK_EQ(0x00010003, t.dst2);
   1417   CHECK_EQ(0x00000003, t.dst3);
   1418   CHECK_EQ(0x11121313, t.dst4);
   1419 }
   1420 
   1421 
   1422 TEST(17) {
   1423   // Test generating labels at high addresses.
   1424   // Should not assert.
   1425   CcTest::InitializeVM();
   1426   Isolate* isolate = Isolate::Current();
   1427   HandleScope scope(isolate);
   1428 
   1429   // Generate a code segment that will be longer than 2^24 bytes.
   1430   Assembler assm(isolate, NULL, 0);
   1431   for (size_t i = 0; i < 1 << 23 ; ++i) {  // 2^23
   1432     __ nop();
   1433   }
   1434 
   1435   Label target;
   1436   __ b(eq, &target);
   1437   __ bind(&target);
   1438   __ nop();
   1439 }
   1440 
   1441 
   1442 #undef __
   1443