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 "src/v8.h"
     29 
     30 #include "src/disassembler.h"
     31 #include "src/factory.h"
     32 #include "src/macro-assembler.h"
     33 #include "src/mips64/macro-assembler-mips64.h"
     34 #include "src/mips64/simulator-mips64.h"
     35 
     36 #include "test/cctest/cctest.h"
     37 
     38 using namespace v8::internal;
     39 
     40 
     41 // Define these function prototypes to match JSEntryFunction in execution.cc.
     42 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
     43 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
     44 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
     45 
     46 
     47 #define __ assm.
     48 
     49 
     50 TEST(MIPS0) {
     51   CcTest::InitializeVM();
     52   Isolate* isolate = CcTest::i_isolate();
     53   HandleScope scope(isolate);
     54 
     55   MacroAssembler assm(isolate, NULL, 0);
     56 
     57   // Addition.
     58   __ addu(v0, a0, a1);
     59   __ jr(ra);
     60   __ nop();
     61 
     62   CodeDesc desc;
     63   assm.GetCode(&desc);
     64   Handle<Code> code = isolate->factory()->NewCode(
     65       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
     66   F2 f = FUNCTION_CAST<F2>(code->entry());
     67   int64_t res =
     68       reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
     69   ::printf("f() = %ld\n", res);
     70   CHECK_EQ(0xabcL, res);
     71 }
     72 
     73 
     74 TEST(MIPS1) {
     75   CcTest::InitializeVM();
     76   Isolate* isolate = CcTest::i_isolate();
     77   HandleScope scope(isolate);
     78 
     79   MacroAssembler assm(isolate, NULL, 0);
     80   Label L, C;
     81 
     82   __ mov(a1, a0);
     83   __ li(v0, 0);
     84   __ b(&C);
     85   __ nop();
     86 
     87   __ bind(&L);
     88   __ addu(v0, v0, a1);
     89   __ addiu(a1, a1, -1);
     90 
     91   __ bind(&C);
     92   __ xori(v1, a1, 0);
     93   __ Branch(&L, ne, v1, Operand((int64_t)0));
     94   __ nop();
     95 
     96   __ jr(ra);
     97   __ nop();
     98 
     99   CodeDesc desc;
    100   assm.GetCode(&desc);
    101   Handle<Code> code = isolate->factory()->NewCode(
    102       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    103   F1 f = FUNCTION_CAST<F1>(code->entry());
    104   int64_t res =
    105      reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
    106   ::printf("f() = %ld\n", res);
    107   CHECK_EQ(1275L, res);
    108 }
    109 
    110 
    111 TEST(MIPS2) {
    112   CcTest::InitializeVM();
    113   Isolate* isolate = CcTest::i_isolate();
    114   HandleScope scope(isolate);
    115 
    116   MacroAssembler assm(isolate, NULL, 0);
    117 
    118   Label exit, error;
    119 
    120   // ----- Test all instructions.
    121 
    122   // Test lui, ori, and addiu, used in the li pseudo-instruction.
    123   // This way we can then safely load registers with chosen values.
    124 
    125   __ ori(a4, zero_reg, 0);
    126   __ lui(a4, 0x1234);
    127   __ ori(a4, a4, 0);
    128   __ ori(a4, a4, 0x0f0f);
    129   __ ori(a4, a4, 0xf0f0);
    130   __ addiu(a5, a4, 1);
    131   __ addiu(a6, a5, -0x10);
    132 
    133   // Load values in temporary registers.
    134   __ li(a4, 0x00000004);
    135   __ li(a5, 0x00001234);
    136   __ li(a6, 0x12345678);
    137   __ li(a7, 0x7fffffff);
    138   __ li(t0, 0xfffffffc);
    139   __ li(t1, 0xffffedcc);
    140   __ li(t2, 0xedcba988);
    141   __ li(t3, 0x80000000);
    142 
    143   // SPECIAL class.
    144   __ srl(v0, a6, 8);    // 0x00123456
    145   __ sll(v0, v0, 11);   // 0x91a2b000
    146   __ sra(v0, v0, 3);    // 0xf2345600
    147   __ srav(v0, v0, a4);  // 0xff234560
    148   __ sllv(v0, v0, a4);  // 0xf2345600
    149   __ srlv(v0, v0, a4);  // 0x0f234560
    150   __ Branch(&error, ne, v0, Operand(0x0f234560));
    151   __ nop();
    152 
    153   __ addu(v0, a4, a5);  // 0x00001238
    154   __ subu(v0, v0, a4);  // 0x00001234
    155   __ Branch(&error, ne, v0, Operand(0x00001234));
    156   __ nop();
    157   __ addu(v1, a7, a4);  // 32bit addu result is sign-extended into 64bit reg.
    158   __ Branch(&error, ne, v1, Operand(0xffffffff80000003));
    159   __ nop();
    160   __ subu(v1, t3, a4);  // 0x7ffffffc
    161   __ Branch(&error, ne, v1, Operand(0x7ffffffc));
    162   __ nop();
    163 
    164   __ and_(v0, a5, a6);  // 0x0000000000001230
    165   __ or_(v0, v0, a5);   // 0x0000000000001234
    166   __ xor_(v0, v0, a6);  // 0x000000001234444c
    167   __ nor(v0, v0, a6);   // 0xffffffffedcba987
    168   __ Branch(&error, ne, v0, Operand(0xffffffffedcba983));
    169   __ nop();
    170 
    171   // Shift both 32bit number to left, to preserve meaning of next comparison.
    172   __ dsll32(a7, a7, 0);
    173   __ dsll32(t3, t3, 0);
    174 
    175   __ slt(v0, t3, a7);
    176   __ Branch(&error, ne, v0, Operand(0x1));
    177   __ nop();
    178   __ sltu(v0, t3, a7);
    179   __ Branch(&error, ne, v0, Operand(zero_reg));
    180   __ nop();
    181 
    182   // Restore original values in registers.
    183   __ dsrl32(a7, a7, 0);
    184   __ dsrl32(t3, t3, 0);
    185   // End of SPECIAL class.
    186 
    187   __ addiu(v0, zero_reg, 0x7421);  // 0x00007421
    188   __ addiu(v0, v0, -0x1);          // 0x00007420
    189   __ addiu(v0, v0, -0x20);         // 0x00007400
    190   __ Branch(&error, ne, v0, Operand(0x00007400));
    191   __ nop();
    192   __ addiu(v1, a7, 0x1);  // 0x80000000 - result is sign-extended.
    193   __ Branch(&error, ne, v1, Operand(0xffffffff80000000));
    194   __ nop();
    195 
    196   __ slti(v0, a5, 0x00002000);  // 0x1
    197   __ slti(v0, v0, 0xffff8000);  // 0x0
    198   __ Branch(&error, ne, v0, Operand(zero_reg));
    199   __ nop();
    200   __ sltiu(v0, a5, 0x00002000);  // 0x1
    201   __ sltiu(v0, v0, 0x00008000);  // 0x1
    202   __ Branch(&error, ne, v0, Operand(0x1));
    203   __ nop();
    204 
    205   __ andi(v0, a5, 0xf0f0);  // 0x00001030
    206   __ ori(v0, v0, 0x8a00);   // 0x00009a30
    207   __ xori(v0, v0, 0x83cc);  // 0x000019fc
    208   __ Branch(&error, ne, v0, Operand(0x000019fc));
    209   __ nop();
    210   __ lui(v1, 0x8123);  // Result is sign-extended into 64bit register.
    211   __ Branch(&error, ne, v1, Operand(0xffffffff81230000));
    212   __ nop();
    213 
    214   // Bit twiddling instructions & conditional moves.
    215   // Uses a4-t3 as set above.
    216   __ Clz(v0, a4);       // 29
    217   __ Clz(v1, a5);       // 19
    218   __ addu(v0, v0, v1);  // 48
    219   __ Clz(v1, a6);       // 3
    220   __ addu(v0, v0, v1);  // 51
    221   __ Clz(v1, t3);       // 0
    222   __ addu(v0, v0, v1);  // 51
    223   __ Branch(&error, ne, v0, Operand(51));
    224   __ Movn(a0, a7, a4);  // Move a0<-a7 (a4 is NOT 0).
    225   __ Ins(a0, a5, 12, 8);  // 0x7ff34fff
    226   __ Branch(&error, ne, a0, Operand(0x7ff34fff));
    227   __ Movz(a0, t2, t3);    // a0 not updated (t3 is NOT 0).
    228   __ Ext(a1, a0, 8, 12);  // 0x34f
    229   __ Branch(&error, ne, a1, Operand(0x34f));
    230   __ Movz(a0, t2, v1);    // a0<-t2, v0 is 0, from 8 instr back.
    231   __ Branch(&error, ne, a0, Operand(t2));
    232 
    233   // Everything was correctly executed. Load the expected result.
    234   __ li(v0, 0x31415926);
    235   __ b(&exit);
    236   __ nop();
    237 
    238   __ bind(&error);
    239   // Got an error. Return a wrong result.
    240   __ li(v0, 666);
    241 
    242   __ bind(&exit);
    243   __ jr(ra);
    244   __ nop();
    245 
    246   CodeDesc desc;
    247   assm.GetCode(&desc);
    248   Handle<Code> code = isolate->factory()->NewCode(
    249       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    250   F2 f = FUNCTION_CAST<F2>(code->entry());
    251   int64_t res =
    252       reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
    253   ::printf("f() = %ld\n", res);
    254 
    255   CHECK_EQ(0x31415926L, res);
    256 }
    257 
    258 
    259 TEST(MIPS3) {
    260   // Test floating point instructions.
    261   CcTest::InitializeVM();
    262   Isolate* isolate = CcTest::i_isolate();
    263   HandleScope scope(isolate);
    264 
    265   typedef struct {
    266     double a;
    267     double b;
    268     double c;
    269     double d;
    270     double e;
    271     double f;
    272     double g;
    273     double h;
    274     double i;
    275   } T;
    276   T t;
    277 
    278   // Create a function that accepts &t, and loads, manipulates, and stores
    279   // the doubles t.a ... t.f.
    280   MacroAssembler assm(isolate, NULL, 0);
    281   Label L, C;
    282 
    283   __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
    284   __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
    285   __ add_d(f8, f4, f6);
    286   __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) );  // c = a + b.
    287 
    288   __ mov_d(f10, f8);  // c
    289   __ neg_d(f12, f6);  // -b
    290   __ sub_d(f10, f10, f12);
    291   __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) );  // d = c - (-b).
    292 
    293   __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) );   // b = a.
    294 
    295   __ li(a4, 120);
    296   __ mtc1(a4, f14);
    297   __ cvt_d_w(f14, f14);   // f14 = 120.0.
    298   __ mul_d(f10, f10, f14);
    299   __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) );  // e = d * 120 = 1.8066e16.
    300 
    301   __ div_d(f12, f10, f4);
    302   __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) );  // f = e / a = 120.44.
    303 
    304   __ sqrt_d(f14, f12);
    305   __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
    306   // g = sqrt(f) = 10.97451593465515908537
    307 
    308   if (kArchVariant == kMips64r2) {
    309     __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
    310     __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
    311     __ madd_d(f14, f6, f4, f6);
    312     __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
    313   }
    314 
    315   __ jr(ra);
    316   __ nop();
    317 
    318   CodeDesc desc;
    319   assm.GetCode(&desc);
    320   Handle<Code> code = isolate->factory()->NewCode(
    321       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    322   F3 f = FUNCTION_CAST<F3>(code->entry());
    323   t.a = 1.5e14;
    324   t.b = 2.75e11;
    325   t.c = 0.0;
    326   t.d = 0.0;
    327   t.e = 0.0;
    328   t.f = 0.0;
    329   t.h = 1.5;
    330   t.i = 2.75;
    331   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    332   USE(dummy);
    333   CHECK_EQ(1.5e14, t.a);
    334   CHECK_EQ(1.5e14, t.b);
    335   CHECK_EQ(1.50275e14, t.c);
    336   CHECK_EQ(1.50550e14, t.d);
    337   CHECK_EQ(1.8066e16, t.e);
    338   CHECK_EQ(120.44, t.f);
    339   CHECK_EQ(10.97451593465515908537, t.g);
    340   if (kArchVariant == kMips64r2) {
    341     CHECK_EQ(6.875, t.h);
    342   }
    343 }
    344 
    345 
    346 TEST(MIPS4) {
    347   // Test moves between floating point and integer registers.
    348   CcTest::InitializeVM();
    349   Isolate* isolate = CcTest::i_isolate();
    350   HandleScope scope(isolate);
    351 
    352   typedef struct {
    353     double a;
    354     double b;
    355     double c;
    356     double d;
    357     int64_t high;
    358     int64_t low;
    359   } T;
    360   T t;
    361 
    362   Assembler assm(isolate, NULL, 0);
    363   Label L, C;
    364 
    365   __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)));
    366   __ ldc1(f5, MemOperand(a0, OFFSET_OF(T, b)));
    367 
    368   // Swap f4 and f5, by using 3 integer registers, a4-a6,
    369   // both two 32-bit chunks, and one 64-bit chunk.
    370   // mXhc1 is mips32/64-r2 only, not r1,
    371   // but we will not support r1 in practice.
    372   __ mfc1(a4, f4);
    373   __ mfhc1(a5, f4);
    374   __ dmfc1(a6, f5);
    375 
    376   __ mtc1(a4, f5);
    377   __ mthc1(a5, f5);
    378   __ dmtc1(a6, f4);
    379 
    380   // Store the swapped f4 and f5 back to memory.
    381   __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)));
    382   __ sdc1(f5, MemOperand(a0, OFFSET_OF(T, c)));
    383 
    384   // Test sign extension of move operations from coprocessor.
    385   __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, d)));
    386   __ mfhc1(a4, f4);
    387   __ mfc1(a5, f4);
    388 
    389   __ sd(a4, MemOperand(a0, OFFSET_OF(T, high)));
    390   __ sd(a5, MemOperand(a0, OFFSET_OF(T, low)));
    391 
    392   __ jr(ra);
    393   __ nop();
    394 
    395   CodeDesc desc;
    396   assm.GetCode(&desc);
    397   Handle<Code> code = isolate->factory()->NewCode(
    398       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    399   F3 f = FUNCTION_CAST<F3>(code->entry());
    400   t.a = 1.5e22;
    401   t.b = 2.75e11;
    402   t.c = 17.17;
    403   t.d = -2.75e11;
    404   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    405   USE(dummy);
    406 
    407   CHECK_EQ(2.75e11, t.a);
    408   CHECK_EQ(2.75e11, t.b);
    409   CHECK_EQ(1.5e22, t.c);
    410   CHECK_EQ(0xffffffffc25001d1L, t.high);
    411   CHECK_EQ(0xffffffffbf800000L, t.low);
    412 }
    413 
    414 
    415 TEST(MIPS5) {
    416   // Test conversions between doubles and integers.
    417   CcTest::InitializeVM();
    418   Isolate* isolate = CcTest::i_isolate();
    419   HandleScope scope(isolate);
    420 
    421   typedef struct {
    422     double a;
    423     double b;
    424     int i;
    425     int j;
    426   } T;
    427   T t;
    428 
    429   Assembler assm(isolate, NULL, 0);
    430   Label L, C;
    431 
    432   // Load all structure elements to registers.
    433   __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
    434   __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
    435   __ lw(a4, MemOperand(a0, OFFSET_OF(T, i)) );
    436   __ lw(a5, MemOperand(a0, OFFSET_OF(T, j)) );
    437 
    438   // Convert double in f4 to int in element i.
    439   __ cvt_w_d(f8, f4);
    440   __ mfc1(a6, f8);
    441   __ sw(a6, MemOperand(a0, OFFSET_OF(T, i)) );
    442 
    443   // Convert double in f6 to int in element j.
    444   __ cvt_w_d(f10, f6);
    445   __ mfc1(a7, f10);
    446   __ sw(a7, MemOperand(a0, OFFSET_OF(T, j)) );
    447 
    448   // Convert int in original i (a4) to double in a.
    449   __ mtc1(a4, f12);
    450   __ cvt_d_w(f0, f12);
    451   __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
    452 
    453   // Convert int in original j (a5) to double in b.
    454   __ mtc1(a5, f14);
    455   __ cvt_d_w(f2, f14);
    456   __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
    457 
    458   __ jr(ra);
    459   __ nop();
    460 
    461   CodeDesc desc;
    462   assm.GetCode(&desc);
    463   Handle<Code> code = isolate->factory()->NewCode(
    464       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    465   F3 f = FUNCTION_CAST<F3>(code->entry());
    466   t.a = 1.5e4;
    467   t.b = 2.75e8;
    468   t.i = 12345678;
    469   t.j = -100000;
    470   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    471   USE(dummy);
    472 
    473   CHECK_EQ(12345678.0, t.a);
    474   CHECK_EQ(-100000.0, t.b);
    475   CHECK_EQ(15000, t.i);
    476   CHECK_EQ(275000000, t.j);
    477 }
    478 
    479 
    480 TEST(MIPS6) {
    481   // Test simple memory loads and stores.
    482   CcTest::InitializeVM();
    483   Isolate* isolate = CcTest::i_isolate();
    484   HandleScope scope(isolate);
    485 
    486   typedef struct {
    487     uint32_t ui;
    488     int32_t si;
    489     int32_t r1;
    490     int32_t r2;
    491     int32_t r3;
    492     int32_t r4;
    493     int32_t r5;
    494     int32_t r6;
    495   } T;
    496   T t;
    497 
    498   Assembler assm(isolate, NULL, 0);
    499   Label L, C;
    500 
    501   // Basic word load/store.
    502   __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) );
    503   __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) );
    504 
    505   // lh with positive data.
    506   __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) );
    507   __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) );
    508 
    509   // lh with negative data.
    510   __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) );
    511   __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) );
    512 
    513   // lhu with negative data.
    514   __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) );
    515   __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) );
    516 
    517   // lb with negative data.
    518   __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) );
    519   __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) );
    520 
    521   // sh writes only 1/2 of word.
    522   __ lui(t1, 0x3333);
    523   __ ori(t1, t1, 0x3333);
    524   __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
    525   __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)) );
    526   __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
    527 
    528   __ jr(ra);
    529   __ nop();
    530 
    531   CodeDesc desc;
    532   assm.GetCode(&desc);
    533   Handle<Code> code = isolate->factory()->NewCode(
    534       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    535   F3 f = FUNCTION_CAST<F3>(code->entry());
    536   t.ui = 0x11223344;
    537   t.si = 0x99aabbcc;
    538   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    539   USE(dummy);
    540 
    541   CHECK_EQ(0x11223344, t.r1);
    542   CHECK_EQ(0x3344, t.r2);
    543   CHECK_EQ(0xffffbbcc, t.r3);
    544   CHECK_EQ(0x0000bbcc, t.r4);
    545   CHECK_EQ(0xffffffcc, t.r5);
    546   CHECK_EQ(0x3333bbcc, t.r6);
    547 }
    548 
    549 
    550 TEST(MIPS7) {
    551   // Test floating point compare and branch instructions.
    552   CcTest::InitializeVM();
    553   Isolate* isolate = CcTest::i_isolate();
    554   HandleScope scope(isolate);
    555 
    556   typedef struct {
    557     double a;
    558     double b;
    559     double c;
    560     double d;
    561     double e;
    562     double f;
    563     int32_t result;
    564   } T;
    565   T t;
    566 
    567   // Create a function that accepts &t, and loads, manipulates, and stores
    568   // the doubles t.a ... t.f.
    569   MacroAssembler assm(isolate, NULL, 0);
    570   Label neither_is_nan, less_than, outa_here;
    571 
    572   __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
    573   __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
    574   if (kArchVariant != kMips64r6) {
    575     __ c(UN, D, f4, f6);
    576     __ bc1f(&neither_is_nan);
    577   } else {
    578     __ cmp(UN, L, f2, f4, f6);
    579     __ bc1eqz(&neither_is_nan, f2);
    580   }
    581   __ nop();
    582   __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
    583   __ Branch(&outa_here);
    584 
    585   __ bind(&neither_is_nan);
    586 
    587   if (kArchVariant == kMips64r6) {
    588     __ cmp(OLT, L, f2, f6, f4);
    589     __ bc1nez(&less_than, f2);
    590   } else {
    591     __ c(OLT, D, f6, f4, 2);
    592     __ bc1t(&less_than, 2);
    593   }
    594 
    595   __ nop();
    596   __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
    597   __ Branch(&outa_here);
    598 
    599   __ bind(&less_than);
    600   __ Addu(a4, zero_reg, Operand(1));
    601   __ sw(a4, MemOperand(a0, OFFSET_OF(T, result)) );  // Set true.
    602 
    603 
    604   // This test-case should have additional tests.
    605 
    606   __ bind(&outa_here);
    607 
    608   __ jr(ra);
    609   __ nop();
    610 
    611   CodeDesc desc;
    612   assm.GetCode(&desc);
    613   Handle<Code> code = isolate->factory()->NewCode(
    614       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    615   F3 f = FUNCTION_CAST<F3>(code->entry());
    616   t.a = 1.5e14;
    617   t.b = 2.75e11;
    618   t.c = 2.0;
    619   t.d = -4.0;
    620   t.e = 0.0;
    621   t.f = 0.0;
    622   t.result = 0;
    623   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    624   USE(dummy);
    625   CHECK_EQ(1.5e14, t.a);
    626   CHECK_EQ(2.75e11, t.b);
    627   CHECK_EQ(1, t.result);
    628 }
    629 
    630 
    631 TEST(MIPS8) {
    632   // Test ROTR and ROTRV instructions.
    633   CcTest::InitializeVM();
    634   Isolate* isolate = CcTest::i_isolate();
    635   HandleScope scope(isolate);
    636 
    637   typedef struct {
    638     int32_t input;
    639     int32_t result_rotr_4;
    640     int32_t result_rotr_8;
    641     int32_t result_rotr_12;
    642     int32_t result_rotr_16;
    643     int32_t result_rotr_20;
    644     int32_t result_rotr_24;
    645     int32_t result_rotr_28;
    646     int32_t result_rotrv_4;
    647     int32_t result_rotrv_8;
    648     int32_t result_rotrv_12;
    649     int32_t result_rotrv_16;
    650     int32_t result_rotrv_20;
    651     int32_t result_rotrv_24;
    652     int32_t result_rotrv_28;
    653   } T;
    654   T t;
    655 
    656   MacroAssembler assm(isolate, NULL, 0);
    657 
    658   // Basic word load.
    659   __ lw(a4, MemOperand(a0, OFFSET_OF(T, input)) );
    660 
    661   // ROTR instruction (called through the Ror macro).
    662   __ Ror(a5, a4, 0x0004);
    663   __ Ror(a6, a4, 0x0008);
    664   __ Ror(a7, a4, 0x000c);
    665   __ Ror(t0, a4, 0x0010);
    666   __ Ror(t1, a4, 0x0014);
    667   __ Ror(t2, a4, 0x0018);
    668   __ Ror(t3, a4, 0x001c);
    669 
    670   // Basic word store.
    671   __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
    672   __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
    673   __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
    674   __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
    675   __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
    676   __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
    677   __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
    678 
    679   // ROTRV instruction (called through the Ror macro).
    680   __ li(t3, 0x0004);
    681   __ Ror(a5, a4, t3);
    682   __ li(t3, 0x0008);
    683   __ Ror(a6, a4, t3);
    684   __ li(t3, 0x000C);
    685   __ Ror(a7, a4, t3);
    686   __ li(t3, 0x0010);
    687   __ Ror(t0, a4, t3);
    688   __ li(t3, 0x0014);
    689   __ Ror(t1, a4, t3);
    690   __ li(t3, 0x0018);
    691   __ Ror(t2, a4, t3);
    692   __ li(t3, 0x001C);
    693   __ Ror(t3, a4, t3);
    694 
    695   // Basic word store.
    696   __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
    697   __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
    698   __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
    699   __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
    700   __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
    701   __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
    702   __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
    703 
    704   __ jr(ra);
    705   __ nop();
    706 
    707   CodeDesc desc;
    708   assm.GetCode(&desc);
    709   Handle<Code> code = isolate->factory()->NewCode(
    710       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    711   F3 f = FUNCTION_CAST<F3>(code->entry());
    712   t.input = 0x12345678;
    713   Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0);
    714   USE(dummy);
    715   CHECK_EQ(0x81234567, t.result_rotr_4);
    716   CHECK_EQ(0x78123456, t.result_rotr_8);
    717   CHECK_EQ(0x67812345, t.result_rotr_12);
    718   CHECK_EQ(0x56781234, t.result_rotr_16);
    719   CHECK_EQ(0x45678123, t.result_rotr_20);
    720   CHECK_EQ(0x34567812, t.result_rotr_24);
    721   CHECK_EQ(0x23456781, t.result_rotr_28);
    722 
    723   CHECK_EQ(0x81234567, t.result_rotrv_4);
    724   CHECK_EQ(0x78123456, t.result_rotrv_8);
    725   CHECK_EQ(0x67812345, t.result_rotrv_12);
    726   CHECK_EQ(0x56781234, t.result_rotrv_16);
    727   CHECK_EQ(0x45678123, t.result_rotrv_20);
    728   CHECK_EQ(0x34567812, t.result_rotrv_24);
    729   CHECK_EQ(0x23456781, t.result_rotrv_28);
    730 }
    731 
    732 
    733 TEST(MIPS9) {
    734   // Test BRANCH improvements.
    735   CcTest::InitializeVM();
    736   Isolate* isolate = CcTest::i_isolate();
    737   HandleScope scope(isolate);
    738 
    739   MacroAssembler assm(isolate, NULL, 0);
    740   Label exit, exit2, exit3;
    741 
    742   __ Branch(&exit, ge, a0, Operand(zero_reg));
    743   __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
    744   __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
    745 
    746   __ bind(&exit);
    747   __ bind(&exit2);
    748   __ bind(&exit3);
    749   __ jr(ra);
    750   __ nop();
    751 
    752   CodeDesc desc;
    753   assm.GetCode(&desc);
    754   isolate->factory()->NewCode(
    755       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    756 }
    757 
    758 
    759 TEST(MIPS10) {
    760   // Test conversions between doubles and long integers.
    761   // Test hos the long ints map to FP regs pairs.
    762   CcTest::InitializeVM();
    763   Isolate* isolate = CcTest::i_isolate();
    764   HandleScope scope(isolate);
    765 
    766   typedef struct {
    767     double a;
    768     double a_converted;
    769     double b;
    770     int32_t dbl_mant;
    771     int32_t dbl_exp;
    772     int32_t long_hi;
    773     int32_t long_lo;
    774     int64_t long_as_int64;
    775     int32_t b_long_hi;
    776     int32_t b_long_lo;
    777     int64_t b_long_as_int64;
    778   } T;
    779   T t;
    780 
    781   Assembler assm(isolate, NULL, 0);
    782   Label L, C;
    783 
    784   if (kArchVariant == kMips64r2) {
    785     // Rewritten for FR=1 FPU mode:
    786     //  -  32 FP regs of 64-bits each, no odd/even pairs.
    787     //  -  Note that cvt_l_d/cvt_d_l ARE legal in FR=1 mode.
    788     // Load all structure elements to registers.
    789     __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
    790 
    791     // Save the raw bits of the double.
    792     __ mfc1(a4, f0);
    793     __ mfhc1(a5, f0);
    794     __ sw(a4, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
    795     __ sw(a5, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
    796 
    797     // Convert double in f0 to long, save hi/lo parts.
    798     __ cvt_l_d(f0, f0);
    799     __ mfc1(a4, f0);  // f0 LS 32 bits of long.
    800     __ mfhc1(a5, f0);  // f0 MS 32 bits of long.
    801     __ sw(a4, MemOperand(a0, OFFSET_OF(T, long_lo)));
    802     __ sw(a5, MemOperand(a0, OFFSET_OF(T, long_hi)));
    803 
    804     // Combine the high/low ints, convert back to double.
    805     __ dsll32(a6, a5, 0);  // Move a5 to high bits of a6.
    806     __ or_(a6, a6, a4);
    807     __ dmtc1(a6, f1);
    808     __ cvt_d_l(f1, f1);
    809     __ sdc1(f1, MemOperand(a0, OFFSET_OF(T, a_converted)));
    810 
    811 
    812     // Convert the b long integers to double b.
    813     __ lw(a4, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
    814     __ lw(a5, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
    815     __ mtc1(a4, f8);  // f8 LS 32-bits.
    816     __ mthc1(a5, f8);  // f8 MS 32-bits.
    817     __ cvt_d_l(f10, f8);
    818     __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
    819 
    820     // Convert double b back to long-int.
    821     __ ldc1(f31, MemOperand(a0, OFFSET_OF(T, b)));
    822     __ cvt_l_d(f31, f31);
    823     __ dmfc1(a7, f31);
    824     __ sd(a7, MemOperand(a0, OFFSET_OF(T, b_long_as_int64)));
    825 
    826 
    827     __ jr(ra);
    828     __ nop();
    829 
    830     CodeDesc desc;
    831     assm.GetCode(&desc);
    832     Handle<Code> code = isolate->factory()->NewCode(
    833         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    834     F3 f = FUNCTION_CAST<F3>(code->entry());
    835     t.a = 2.147483647e9;       // 0x7fffffff -> 0x41DFFFFFFFC00000 as double.
    836     t.b_long_hi = 0x000000ff;  // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double.
    837     t.b_long_lo = 0x00ff00ff;
    838     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    839     USE(dummy);
    840 
    841     CHECK_EQ(0x41DFFFFF, t.dbl_exp);
    842     CHECK_EQ(0xFFC00000, t.dbl_mant);
    843     CHECK_EQ(0, t.long_hi);
    844     CHECK_EQ(0x7fffffff, t.long_lo);
    845     CHECK_EQ(2.147483647e9, t.a_converted);
    846 
    847     // 0xFF00FF00FF -> 1.095233372415e12.
    848     CHECK_EQ(1.095233372415e12, t.b);
    849     CHECK_EQ(0xFF00FF00FF, t.b_long_as_int64);
    850   }
    851 }
    852 
    853 
    854 TEST(MIPS11) {
    855   // Do not run test on MIPS64r6, as these instructions are removed.
    856   if (kArchVariant != kMips64r6) {
    857     // Test LWL, LWR, SWL and SWR instructions.
    858     CcTest::InitializeVM();
    859     Isolate* isolate = CcTest::i_isolate();
    860     HandleScope scope(isolate);
    861 
    862     typedef struct {
    863       int32_t reg_init;
    864       int32_t mem_init;
    865       int32_t lwl_0;
    866       int32_t lwl_1;
    867       int32_t lwl_2;
    868       int32_t lwl_3;
    869       int32_t lwr_0;
    870       int32_t lwr_1;
    871       int32_t lwr_2;
    872       int32_t lwr_3;
    873       int32_t swl_0;
    874       int32_t swl_1;
    875       int32_t swl_2;
    876       int32_t swl_3;
    877       int32_t swr_0;
    878       int32_t swr_1;
    879       int32_t swr_2;
    880       int32_t swr_3;
    881     } T;
    882     T t;
    883 
    884     Assembler assm(isolate, NULL, 0);
    885 
    886     // Test all combinations of LWL and vAddr.
    887     __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
    888     __ lwl(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
    889     __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwl_0)));
    890 
    891     __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
    892     __ lwl(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1));
    893     __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwl_1)));
    894 
    895     __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
    896     __ lwl(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2));
    897     __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwl_2)));
    898 
    899     __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
    900     __ lwl(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3));
    901     __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwl_3)));
    902 
    903     // Test all combinations of LWR and vAddr.
    904     __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
    905     __ lwr(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
    906     __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwr_0)));
    907 
    908     __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
    909     __ lwr(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1));
    910     __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwr_1)));
    911 
    912     __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
    913     __ lwr(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2));
    914     __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
    915 
    916     __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
    917     __ lwr(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3));
    918     __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
    919 
    920     // Test all combinations of SWL and vAddr.
    921     __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
    922     __ sw(a4, MemOperand(a0, OFFSET_OF(T, swl_0)));
    923     __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
    924     __ swl(a4, MemOperand(a0, OFFSET_OF(T, swl_0)));
    925 
    926     __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)));
    927     __ sw(a5, MemOperand(a0, OFFSET_OF(T, swl_1)));
    928     __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
    929     __ swl(a5, MemOperand(a0, OFFSET_OF(T, swl_1) + 1));
    930 
    931     __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)));
    932     __ sw(a6, MemOperand(a0, OFFSET_OF(T, swl_2)));
    933     __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
    934     __ swl(a6, MemOperand(a0, OFFSET_OF(T, swl_2) + 2));
    935 
    936     __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)));
    937     __ sw(a7, MemOperand(a0, OFFSET_OF(T, swl_3)));
    938     __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
    939     __ swl(a7, MemOperand(a0, OFFSET_OF(T, swl_3) + 3));
    940 
    941     // Test all combinations of SWR and vAddr.
    942     __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
    943     __ sw(a4, MemOperand(a0, OFFSET_OF(T, swr_0)));
    944     __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
    945     __ swr(a4, MemOperand(a0, OFFSET_OF(T, swr_0)));
    946 
    947     __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)));
    948     __ sw(a5, MemOperand(a0, OFFSET_OF(T, swr_1)));
    949     __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
    950     __ swr(a5, MemOperand(a0, OFFSET_OF(T, swr_1) + 1));
    951 
    952     __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)));
    953     __ sw(a6, MemOperand(a0, OFFSET_OF(T, swr_2)));
    954     __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
    955     __ swr(a6, MemOperand(a0, OFFSET_OF(T, swr_2) + 2));
    956 
    957     __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)));
    958     __ sw(a7, MemOperand(a0, OFFSET_OF(T, swr_3)));
    959     __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
    960     __ swr(a7, MemOperand(a0, OFFSET_OF(T, swr_3) + 3));
    961 
    962     __ jr(ra);
    963     __ nop();
    964 
    965     CodeDesc desc;
    966     assm.GetCode(&desc);
    967     Handle<Code> code = isolate->factory()->NewCode(
    968         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    969     F3 f = FUNCTION_CAST<F3>(code->entry());
    970     t.reg_init = 0xaabbccdd;
    971     t.mem_init = 0x11223344;
    972 
    973     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
    974     USE(dummy);
    975 
    976     CHECK_EQ(0x44bbccdd, t.lwl_0);
    977     CHECK_EQ(0x3344ccdd, t.lwl_1);
    978     CHECK_EQ(0x223344dd, t.lwl_2);
    979     CHECK_EQ(0x11223344, t.lwl_3);
    980 
    981     CHECK_EQ(0x11223344, t.lwr_0);
    982     CHECK_EQ(0xaa112233, t.lwr_1);
    983     CHECK_EQ(0xaabb1122, t.lwr_2);
    984     CHECK_EQ(0xaabbcc11, t.lwr_3);
    985 
    986     CHECK_EQ(0x112233aa, t.swl_0);
    987     CHECK_EQ(0x1122aabb, t.swl_1);
    988     CHECK_EQ(0x11aabbcc, t.swl_2);
    989     CHECK_EQ(0xaabbccdd, t.swl_3);
    990 
    991     CHECK_EQ(0xaabbccdd, t.swr_0);
    992     CHECK_EQ(0xbbccdd44, t.swr_1);
    993     CHECK_EQ(0xccdd3344, t.swr_2);
    994     CHECK_EQ(0xdd223344, t.swr_3);
    995   }
    996 }
    997 
    998 
    999 TEST(MIPS12) {
   1000   CcTest::InitializeVM();
   1001   Isolate* isolate = CcTest::i_isolate();
   1002   HandleScope scope(isolate);
   1003 
   1004   typedef struct {
   1005       int32_t  x;
   1006       int32_t  y;
   1007       int32_t  y1;
   1008       int32_t  y2;
   1009       int32_t  y3;
   1010       int32_t  y4;
   1011   } T;
   1012   T t;
   1013 
   1014   MacroAssembler assm(isolate, NULL, 0);
   1015 
   1016   __ mov(t2, fp);  // Save frame pointer.
   1017   __ mov(fp, a0);  // Access struct T by fp.
   1018   __ lw(a4, MemOperand(a0, OFFSET_OF(T, y)));
   1019   __ lw(a7, MemOperand(a0, OFFSET_OF(T, y4)));
   1020 
   1021   __ addu(a5, a4, a7);
   1022   __ subu(t0, a4, a7);
   1023   __ nop();
   1024   __ push(a4);  // These instructions disappear after opt.
   1025   __ Pop();
   1026   __ addu(a4, a4, a4);
   1027   __ nop();
   1028   __ Pop();     // These instructions disappear after opt.
   1029   __ push(a7);
   1030   __ nop();
   1031   __ push(a7);  // These instructions disappear after opt.
   1032   __ pop(a7);
   1033   __ nop();
   1034   __ push(a7);
   1035   __ pop(t0);
   1036   __ nop();
   1037   __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)));
   1038   __ lw(a4, MemOperand(fp, OFFSET_OF(T, y)));
   1039   __ nop();
   1040   __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)));
   1041   __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)));
   1042   __ nop();
   1043   __ push(a5);
   1044   __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)));
   1045   __ pop(a5);
   1046   __ nop();
   1047   __ push(a5);
   1048   __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
   1049   __ pop(a5);
   1050   __ nop();
   1051   __ push(a5);
   1052   __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
   1053   __ pop(a6);
   1054   __ nop();
   1055   __ push(a6);
   1056   __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
   1057   __ pop(a5);
   1058   __ nop();
   1059   __ push(a5);
   1060   __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
   1061   __ pop(a7);
   1062   __ nop();
   1063 
   1064   __ mov(fp, t2);
   1065   __ jr(ra);
   1066   __ nop();
   1067 
   1068   CodeDesc desc;
   1069   assm.GetCode(&desc);
   1070   Handle<Code> code = isolate->factory()->NewCode(
   1071       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1072   F3 f = FUNCTION_CAST<F3>(code->entry());
   1073   t.x = 1;
   1074   t.y = 2;
   1075   t.y1 = 3;
   1076   t.y2 = 4;
   1077   t.y3 = 0XBABA;
   1078   t.y4 = 0xDEDA;
   1079 
   1080   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1081   USE(dummy);
   1082 
   1083   CHECK_EQ(3, t.y1);
   1084 }
   1085 
   1086 
   1087 TEST(MIPS13) {
   1088   // Test Cvt_d_uw and Trunc_uw_d macros.
   1089   CcTest::InitializeVM();
   1090   Isolate* isolate = CcTest::i_isolate();
   1091   HandleScope scope(isolate);
   1092 
   1093   typedef struct {
   1094     double cvt_big_out;
   1095     double cvt_small_out;
   1096     uint32_t trunc_big_out;
   1097     uint32_t trunc_small_out;
   1098     uint32_t cvt_big_in;
   1099     uint32_t cvt_small_in;
   1100   } T;
   1101   T t;
   1102 
   1103   MacroAssembler assm(isolate, NULL, 0);
   1104 
   1105   __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
   1106   __ Cvt_d_uw(f10, a4, f22);
   1107   __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
   1108 
   1109   __ Trunc_uw_d(f10, f10, f22);
   1110   __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
   1111 
   1112   __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
   1113   __ Cvt_d_uw(f8, a4, f22);
   1114   __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
   1115 
   1116   __ Trunc_uw_d(f8, f8, f22);
   1117   __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
   1118 
   1119   __ jr(ra);
   1120   __ nop();
   1121 
   1122   CodeDesc desc;
   1123   assm.GetCode(&desc);
   1124   Handle<Code> code = isolate->factory()->NewCode(
   1125       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1126   F3 f = FUNCTION_CAST<F3>(code->entry());
   1127 
   1128   t.cvt_big_in = 0xFFFFFFFF;
   1129   t.cvt_small_in  = 333;
   1130 
   1131   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1132   USE(dummy);
   1133 
   1134   CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
   1135   CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
   1136 
   1137   CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
   1138   CHECK_EQ(static_cast<int>(t.trunc_small_out),
   1139            static_cast<int>(t.cvt_small_in));
   1140 }
   1141 
   1142 
   1143 TEST(MIPS14) {
   1144   // Test round, floor, ceil, trunc, cvt.
   1145   CcTest::InitializeVM();
   1146   Isolate* isolate = CcTest::i_isolate();
   1147   HandleScope scope(isolate);
   1148 
   1149 #define ROUND_STRUCT_ELEMENT(x) \
   1150   int32_t x##_up_out; \
   1151   int32_t x##_down_out; \
   1152   int32_t neg_##x##_up_out; \
   1153   int32_t neg_##x##_down_out; \
   1154   uint32_t x##_err1_out; \
   1155   uint32_t x##_err2_out; \
   1156   uint32_t x##_err3_out; \
   1157   uint32_t x##_err4_out; \
   1158   int32_t x##_invalid_result;
   1159 
   1160   typedef struct {
   1161     double round_up_in;
   1162     double round_down_in;
   1163     double neg_round_up_in;
   1164     double neg_round_down_in;
   1165     double err1_in;
   1166     double err2_in;
   1167     double err3_in;
   1168     double err4_in;
   1169 
   1170     ROUND_STRUCT_ELEMENT(round)
   1171     ROUND_STRUCT_ELEMENT(floor)
   1172     ROUND_STRUCT_ELEMENT(ceil)
   1173     ROUND_STRUCT_ELEMENT(trunc)
   1174     ROUND_STRUCT_ELEMENT(cvt)
   1175   } T;
   1176   T t;
   1177 
   1178 #undef ROUND_STRUCT_ELEMENT
   1179 
   1180   MacroAssembler assm(isolate, NULL, 0);
   1181 
   1182   // Save FCSR.
   1183   __ cfc1(a1, FCSR);
   1184   // Disable FPU exceptions.
   1185   __ ctc1(zero_reg, FCSR);
   1186 #define RUN_ROUND_TEST(x) \
   1187   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
   1188   __ x##_w_d(f0, f0); \
   1189   __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
   1190   \
   1191   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
   1192   __ x##_w_d(f0, f0); \
   1193   __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
   1194   \
   1195   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
   1196   __ x##_w_d(f0, f0); \
   1197   __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
   1198   \
   1199   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
   1200   __ x##_w_d(f0, f0); \
   1201   __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
   1202   \
   1203   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
   1204   __ ctc1(zero_reg, FCSR); \
   1205   __ x##_w_d(f0, f0); \
   1206   __ cfc1(a2, FCSR); \
   1207   __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
   1208   \
   1209   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
   1210   __ ctc1(zero_reg, FCSR); \
   1211   __ x##_w_d(f0, f0); \
   1212   __ cfc1(a2, FCSR); \
   1213   __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
   1214   \
   1215   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
   1216   __ ctc1(zero_reg, FCSR); \
   1217   __ x##_w_d(f0, f0); \
   1218   __ cfc1(a2, FCSR); \
   1219   __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
   1220   \
   1221   __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
   1222   __ ctc1(zero_reg, FCSR); \
   1223   __ x##_w_d(f0, f0); \
   1224   __ cfc1(a2, FCSR); \
   1225   __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
   1226   __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
   1227 
   1228   RUN_ROUND_TEST(round)
   1229   RUN_ROUND_TEST(floor)
   1230   RUN_ROUND_TEST(ceil)
   1231   RUN_ROUND_TEST(trunc)
   1232   RUN_ROUND_TEST(cvt)
   1233 
   1234   // Restore FCSR.
   1235   __ ctc1(a1, FCSR);
   1236 
   1237   __ jr(ra);
   1238   __ nop();
   1239 
   1240   CodeDesc desc;
   1241   assm.GetCode(&desc);
   1242   Handle<Code> code = isolate->factory()->NewCode(
   1243       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1244   F3 f = FUNCTION_CAST<F3>(code->entry());
   1245 
   1246   t.round_up_in = 123.51;
   1247   t.round_down_in = 123.49;
   1248   t.neg_round_up_in = -123.5;
   1249   t.neg_round_down_in = -123.49;
   1250   t.err1_in = 123.51;
   1251   t.err2_in = 1;
   1252   t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
   1253   t.err4_in = NAN;
   1254 
   1255   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1256   USE(dummy);
   1257 
   1258 #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
   1259 #define CHECK_ROUND_RESULT(type) \
   1260   CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
   1261   CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
   1262   CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
   1263   CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
   1264   CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result);
   1265 
   1266   CHECK_ROUND_RESULT(round);
   1267   CHECK_ROUND_RESULT(floor);
   1268   CHECK_ROUND_RESULT(ceil);
   1269   CHECK_ROUND_RESULT(cvt);
   1270 }
   1271 
   1272 
   1273 TEST(MIPS15) {
   1274   // Test chaining of label usages within instructions (issue 1644).
   1275   CcTest::InitializeVM();
   1276   Isolate* isolate = CcTest::i_isolate();
   1277   HandleScope scope(isolate);
   1278   Assembler assm(isolate, NULL, 0);
   1279 
   1280   Label target;
   1281   __ beq(v0, v1, &target);
   1282   __ nop();
   1283   __ bne(v0, v1, &target);
   1284   __ nop();
   1285   __ bind(&target);
   1286   __ nop();
   1287 }
   1288 
   1289 
   1290 // ----- mips64 tests -----------------------------------------------
   1291 
   1292 TEST(MIPS16) {
   1293   // Test 64-bit memory loads and stores.
   1294   CcTest::InitializeVM();
   1295   Isolate* isolate = CcTest::i_isolate();
   1296   HandleScope scope(isolate);
   1297 
   1298   typedef struct {
   1299     int64_t r1;
   1300     int64_t r2;
   1301     int64_t r3;
   1302     int64_t r4;
   1303     int64_t r5;
   1304     int64_t r6;
   1305     uint32_t ui;
   1306     int32_t si;
   1307   } T;
   1308   T t;
   1309 
   1310   Assembler assm(isolate, NULL, 0);
   1311   Label L, C;
   1312 
   1313   // Basic 32-bit word load/store, with un-signed data.
   1314   __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)));
   1315   __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)));
   1316 
   1317   // Check that the data got zero-extended into 64-bit a4.
   1318   __ sd(a4, MemOperand(a0, OFFSET_OF(T, r2)));
   1319 
   1320   // Basic 32-bit word load/store, with SIGNED data.
   1321   __ lw(a5, MemOperand(a0, OFFSET_OF(T, si)));
   1322   __ sw(a5, MemOperand(a0, OFFSET_OF(T, r3)));
   1323 
   1324   // Check that the data got sign-extended into 64-bit a4.
   1325   __ sd(a5, MemOperand(a0, OFFSET_OF(T, r4)));
   1326 
   1327   // 32-bit UNSIGNED word load/store, with SIGNED data.
   1328   __ lwu(a6, MemOperand(a0, OFFSET_OF(T, si)));
   1329   __ sw(a6, MemOperand(a0, OFFSET_OF(T, r5)));
   1330 
   1331   // Check that the data got zero-extended into 64-bit a4.
   1332   __ sd(a6, MemOperand(a0, OFFSET_OF(T, r6)));
   1333 
   1334   // lh with positive data.
   1335   __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)));
   1336   __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)));
   1337 
   1338   // lh with negative data.
   1339   __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)));
   1340   __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)));
   1341 
   1342   // lhu with negative data.
   1343   __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)));
   1344   __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)));
   1345 
   1346   // lb with negative data.
   1347   __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)));
   1348   __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)));
   1349 
   1350   // // sh writes only 1/2 of word.
   1351   __ lui(t1, 0x3333);
   1352   __ ori(t1, t1, 0x3333);
   1353   __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)));
   1354   __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)));
   1355   __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)));
   1356 
   1357   __ jr(ra);
   1358   __ nop();
   1359 
   1360   CodeDesc desc;
   1361   assm.GetCode(&desc);
   1362   Handle<Code> code = isolate->factory()->NewCode(
   1363       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1364   F3 f = FUNCTION_CAST<F3>(code->entry());
   1365   t.ui = 0x44332211;
   1366   t.si = 0x99aabbcc;
   1367   t.r1 = 0x1111111111111111;
   1368   t.r2 = 0x2222222222222222;
   1369   t.r3 = 0x3333333333333333;
   1370   t.r4 = 0x4444444444444444;
   1371   t.r5 = 0x5555555555555555;
   1372   t.r6 = 0x6666666666666666;
   1373   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
   1374   USE(dummy);
   1375 
   1376   // Unsigned data, 32 & 64.
   1377   CHECK_EQ(0x1111111144332211L, t.r1);
   1378   CHECK_EQ(0x0000000000002211L, t.r2);
   1379 
   1380   // Signed data, 32 & 64.
   1381   CHECK_EQ(0x33333333ffffbbccL, t.r3);
   1382   CHECK_EQ(0xffffffff0000bbccL, t.r4);
   1383 
   1384   // Signed data, 32 & 64.
   1385   CHECK_EQ(0x55555555ffffffccL, t.r5);
   1386   CHECK_EQ(0x000000003333bbccL, t.r6);
   1387 }
   1388 
   1389 #undef __
   1390