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 <iostream>  // NOLINT(readability/streams)
     29 
     30 #include "src/v8.h"
     31 
     32 #include "src/base/utils/random-number-generator.h"
     33 #include "src/disassembler.h"
     34 #include "src/factory.h"
     35 #include "src/macro-assembler.h"
     36 #include "src/mips/macro-assembler-mips.h"
     37 #include "src/mips/simulator-mips.h"
     38 
     39 #include "test/cctest/cctest.h"
     40 
     41 
     42 using namespace v8::internal;
     43 
     44 
     45 // Define these function prototypes to match JSEntryFunction in execution.cc.
     46 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
     47 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
     48 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
     49 
     50 
     51 #define __ assm.
     52 
     53 TEST(MIPS0) {
     54   CcTest::InitializeVM();
     55   Isolate* isolate = CcTest::i_isolate();
     56   HandleScope scope(isolate);
     57 
     58   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
     59 
     60   // Addition.
     61   __ addu(v0, a0, a1);
     62   __ jr(ra);
     63   __ nop();
     64 
     65   CodeDesc desc;
     66   assm.GetCode(&desc);
     67   Handle<Code> code = isolate->factory()->NewCode(
     68       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
     69   F2 f = FUNCTION_CAST<F2>(code->entry());
     70   int res = reinterpret_cast<int>(
     71       CALL_GENERATED_CODE(isolate, f, 0xab0, 0xc, 0, 0, 0));
     72   CHECK_EQ(static_cast<int32_t>(0xabc), res);
     73 }
     74 
     75 
     76 TEST(MIPS1) {
     77   CcTest::InitializeVM();
     78   Isolate* isolate = CcTest::i_isolate();
     79   HandleScope scope(isolate);
     80 
     81   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
     82   Label L, C;
     83 
     84   __ mov(a1, a0);
     85   __ li(v0, 0);
     86   __ b(&C);
     87   __ nop();
     88 
     89   __ bind(&L);
     90   __ addu(v0, v0, a1);
     91   __ addiu(a1, a1, -1);
     92 
     93   __ bind(&C);
     94   __ xori(v1, a1, 0);
     95   __ Branch(&L, ne, v1, Operand(0));
     96   __ nop();
     97 
     98   __ jr(ra);
     99   __ nop();
    100 
    101   CodeDesc desc;
    102   assm.GetCode(&desc);
    103   Handle<Code> code = isolate->factory()->NewCode(
    104       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    105   F1 f = FUNCTION_CAST<F1>(code->entry());
    106   int res = reinterpret_cast<int>(
    107       CALL_GENERATED_CODE(isolate, f, 50, 0, 0, 0, 0));
    108   CHECK_EQ(1275, res);
    109 }
    110 
    111 
    112 TEST(MIPS2) {
    113   CcTest::InitializeVM();
    114   Isolate* isolate = CcTest::i_isolate();
    115   HandleScope scope(isolate);
    116 
    117   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
    118 
    119   Label exit, error;
    120 
    121   // ----- Test all instructions.
    122 
    123   // Test lui, ori, and addiu, used in the li pseudo-instruction.
    124   // This way we can then safely load registers with chosen values.
    125 
    126   __ ori(t0, zero_reg, 0);
    127   __ lui(t0, 0x1234);
    128   __ ori(t0, t0, 0);
    129   __ ori(t0, t0, 0x0f0f);
    130   __ ori(t0, t0, 0xf0f0);
    131   __ addiu(t1, t0, 1);
    132   __ addiu(t2, t1, -0x10);
    133 
    134   // Load values in temporary registers.
    135   __ li(t0, 0x00000004);
    136   __ li(t1, 0x00001234);
    137   __ li(t2, 0x12345678);
    138   __ li(t3, 0x7fffffff);
    139   __ li(t4, 0xfffffffc);
    140   __ li(t5, 0xffffedcc);
    141   __ li(t6, 0xedcba988);
    142   __ li(t7, 0x80000000);
    143 
    144   // SPECIAL class.
    145   __ srl(v0, t2, 8);    // 0x00123456
    146   __ sll(v0, v0, 11);   // 0x91a2b000
    147   __ sra(v0, v0, 3);    // 0xf2345600
    148   __ srav(v0, v0, t0);  // 0xff234560
    149   __ sllv(v0, v0, t0);  // 0xf2345600
    150   __ srlv(v0, v0, t0);  // 0x0f234560
    151   __ Branch(&error, ne, v0, Operand(0x0f234560));
    152   __ nop();
    153 
    154   __ addu(v0, t0, t1);   // 0x00001238
    155   __ subu(v0, v0, t0);  // 0x00001234
    156   __ Branch(&error, ne, v0, Operand(0x00001234));
    157   __ nop();
    158   __ addu(v1, t3, t0);
    159   __ Branch(&error, ne, v1, Operand(0x80000003));
    160   __ nop();
    161   __ subu(v1, t7, t0);  // 0x7ffffffc
    162   __ Branch(&error, ne, v1, Operand(0x7ffffffc));
    163   __ nop();
    164 
    165   __ and_(v0, t1, t2);  // 0x00001230
    166   __ or_(v0, v0, t1);   // 0x00001234
    167   __ xor_(v0, v0, t2);  // 0x1234444c
    168   __ nor(v0, v0, t2);   // 0xedcba987
    169   __ Branch(&error, ne, v0, Operand(0xedcba983));
    170   __ nop();
    171 
    172   __ slt(v0, t7, t3);
    173   __ Branch(&error, ne, v0, Operand(0x1));
    174   __ nop();
    175   __ sltu(v0, t7, t3);
    176   __ Branch(&error, ne, v0, Operand(zero_reg));
    177   __ nop();
    178   // End of SPECIAL class.
    179 
    180   __ addiu(v0, zero_reg, 0x7421);  // 0x00007421
    181   __ addiu(v0, v0, -0x1);  // 0x00007420
    182   __ addiu(v0, v0, -0x20);  // 0x00007400
    183   __ Branch(&error, ne, v0, Operand(0x00007400));
    184   __ nop();
    185   __ addiu(v1, t3, 0x1);  // 0x80000000
    186   __ Branch(&error, ne, v1, Operand(0x80000000));
    187   __ nop();
    188 
    189   __ slti(v0, t1, 0x00002000);  // 0x1
    190   __ slti(v0, v0, 0xffff8000);  // 0x0
    191   __ Branch(&error, ne, v0, Operand(zero_reg));
    192   __ nop();
    193   __ sltiu(v0, t1, 0x00002000);  // 0x1
    194   __ sltiu(v0, v0, 0x00008000);  // 0x1
    195   __ Branch(&error, ne, v0, Operand(0x1));
    196   __ nop();
    197 
    198   __ andi(v0, t1, 0xf0f0);  // 0x00001030
    199   __ ori(v0, v0, 0x8a00);  // 0x00009a30
    200   __ xori(v0, v0, 0x83cc);  // 0x000019fc
    201   __ Branch(&error, ne, v0, Operand(0x000019fc));
    202   __ nop();
    203   __ lui(v1, 0x8123);  // 0x81230000
    204   __ Branch(&error, ne, v1, Operand(0x81230000));
    205   __ nop();
    206 
    207   // Bit twiddling instructions & conditional moves.
    208   // Uses t0-t7 as set above.
    209   __ Clz(v0, t0);       // 29
    210   __ Clz(v1, t1);       // 19
    211   __ addu(v0, v0, v1);  // 48
    212   __ Clz(v1, t2);       // 3
    213   __ addu(v0, v0, v1);  // 51
    214   __ Clz(v1, t7);       // 0
    215   __ addu(v0, v0, v1);  // 51
    216   __ Branch(&error, ne, v0, Operand(51));
    217   __ Movn(a0, t3, t0);  // Move a0<-t3 (t0 is NOT 0).
    218   __ Ins(a0, t1, 12, 8);  // 0x7ff34fff
    219   __ Branch(&error, ne, a0, Operand(0x7ff34fff));
    220   __ Movz(a0, t6, t7);    // a0 not updated (t7 is NOT 0).
    221   __ Ext(a1, a0, 8, 12);  // 0x34f
    222   __ Branch(&error, ne, a1, Operand(0x34f));
    223   __ Movz(a0, t6, v1);    // a0<-t6, v0 is 0, from 8 instr back.
    224   __ Branch(&error, ne, a0, Operand(t6));
    225 
    226   // Everything was correctly executed. Load the expected result.
    227   __ li(v0, 0x31415926);
    228   __ b(&exit);
    229   __ nop();
    230 
    231   __ bind(&error);
    232   // Got an error. Return a wrong result.
    233   __ li(v0, 666);
    234 
    235   __ bind(&exit);
    236   __ jr(ra);
    237   __ nop();
    238 
    239   CodeDesc desc;
    240   assm.GetCode(&desc);
    241   Handle<Code> code = isolate->factory()->NewCode(
    242       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    243   F2 f = FUNCTION_CAST<F2>(code->entry());
    244   int res = reinterpret_cast<int>(
    245       CALL_GENERATED_CODE(isolate, f, 0xab0, 0xc, 0, 0, 0));
    246   CHECK_EQ(static_cast<int32_t>(0x31415926), res);
    247 }
    248 
    249 
    250 TEST(MIPS3) {
    251   // Test floating point instructions.
    252   CcTest::InitializeVM();
    253   Isolate* isolate = CcTest::i_isolate();
    254   HandleScope scope(isolate);
    255 
    256   typedef struct {
    257     double a;
    258     double b;
    259     double c;
    260     double d;
    261     double e;
    262     double f;
    263     double g;
    264     double h;
    265     double i;
    266     float fa;
    267     float fb;
    268     float fc;
    269     float fd;
    270     float fe;
    271     float ff;
    272     float fg;
    273   } T;
    274   T t;
    275 
    276   // Create a function that accepts &t, and loads, manipulates, and stores
    277   // the doubles t.a ... t.f.
    278   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
    279   Label L, C;
    280 
    281   // Double precision floating point instructions.
    282   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    283   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    284   __ add_d(f8, f4, f6);
    285   __ sdc1(f8, MemOperand(a0, offsetof(T, c)) );  // c = a + b.
    286 
    287   __ mov_d(f10, f8);  // c
    288   __ neg_d(f12, f6);  // -b
    289   __ sub_d(f10, f10, f12);
    290   __ sdc1(f10, MemOperand(a0, offsetof(T, d)) );  // d = c - (-b).
    291 
    292   __ sdc1(f4, MemOperand(a0, offsetof(T, b)) );   // b = a.
    293 
    294   __ li(t0, 120);
    295   __ mtc1(t0, f14);
    296   __ cvt_d_w(f14, f14);   // f14 = 120.0.
    297   __ mul_d(f10, f10, f14);
    298   __ sdc1(f10, MemOperand(a0, offsetof(T, e)) );  // e = d * 120 = 1.8066e16.
    299 
    300   __ div_d(f12, f10, f4);
    301   __ sdc1(f12, MemOperand(a0, offsetof(T, f)) );  // f = e / a = 120.44.
    302 
    303   __ sqrt_d(f14, f12);
    304   __ sdc1(f14, MemOperand(a0, offsetof(T, g)) );
    305   // g = sqrt(f) = 10.97451593465515908537
    306 
    307   if (IsMipsArchVariant(kMips32r2)) {
    308     __ ldc1(f4, MemOperand(a0, offsetof(T, h)) );
    309     __ ldc1(f6, MemOperand(a0, offsetof(T, i)) );
    310     __ madd_d(f14, f6, f4, f6);
    311     __ sdc1(f14, MemOperand(a0, offsetof(T, h)) );
    312   }
    313 
    314   // Single precision floating point instructions.
    315   __ lwc1(f4, MemOperand(a0, offsetof(T, fa)) );
    316   __ lwc1(f6, MemOperand(a0, offsetof(T, fb)) );
    317   __ add_s(f8, f4, f6);
    318   __ swc1(f8, MemOperand(a0, offsetof(T, fc)) );  // fc = fa + fb.
    319 
    320   __ neg_s(f10, f6);  // -fb
    321   __ sub_s(f10, f8, f10);
    322   __ swc1(f10, MemOperand(a0, offsetof(T, fd)) );  // fd = fc - (-fb).
    323 
    324   __ swc1(f4, MemOperand(a0, offsetof(T, fb)) );   // fb = fa.
    325 
    326   __ li(t0, 120);
    327   __ mtc1(t0, f14);
    328   __ cvt_s_w(f14, f14);   // f14 = 120.0.
    329   __ mul_s(f10, f10, f14);
    330   __ swc1(f10, MemOperand(a0, offsetof(T, fe)) );  // fe = fd * 120
    331 
    332   __ div_s(f12, f10, f4);
    333   __ swc1(f12, MemOperand(a0, offsetof(T, ff)) );  // ff = fe / fa
    334 
    335   __ sqrt_s(f14, f12);
    336   __ swc1(f14, MemOperand(a0, offsetof(T, fg)) );
    337 
    338   __ jr(ra);
    339   __ nop();
    340 
    341   CodeDesc desc;
    342   assm.GetCode(&desc);
    343   Handle<Code> code = isolate->factory()->NewCode(
    344       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    345   F3 f = FUNCTION_CAST<F3>(code->entry());
    346   // Double test values.
    347   t.a = 1.5e14;
    348   t.b = 2.75e11;
    349   t.c = 0.0;
    350   t.d = 0.0;
    351   t.e = 0.0;
    352   t.f = 0.0;
    353   t.h = 1.5;
    354   t.i = 2.75;
    355   // Single test values.
    356   t.fa = 1.5e6;
    357   t.fb = 2.75e4;
    358   t.fc = 0.0;
    359   t.fd = 0.0;
    360   t.fe = 0.0;
    361   t.ff = 0.0;
    362   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    363   USE(dummy);
    364   // Expected double results.
    365   CHECK_EQ(1.5e14, t.a);
    366   CHECK_EQ(1.5e14, t.b);
    367   CHECK_EQ(1.50275e14, t.c);
    368   CHECK_EQ(1.50550e14, t.d);
    369   CHECK_EQ(1.8066e16, t.e);
    370   CHECK_EQ(120.44, t.f);
    371   CHECK_EQ(10.97451593465515908537, t.g);
    372   if (IsMipsArchVariant(kMips32r2)) {
    373     CHECK_EQ(6.875, t.h);
    374   }
    375   // Expected single results.
    376   CHECK_EQ(1.5e6, t.fa);
    377   CHECK_EQ(1.5e6, t.fb);
    378   CHECK_EQ(1.5275e06, t.fc);
    379   CHECK_EQ(1.5550e06, t.fd);
    380   CHECK_EQ(1.866e08, t.fe);
    381   CHECK_EQ(124.40000152587890625, t.ff);
    382   CHECK_EQ(11.1534748077392578125, t.fg);
    383 }
    384 
    385 
    386 TEST(MIPS4) {
    387   // Test moves between floating point and integer registers.
    388   CcTest::InitializeVM();
    389   Isolate* isolate = CcTest::i_isolate();
    390   HandleScope scope(isolate);
    391 
    392   typedef struct {
    393     double a;
    394     double b;
    395     double c;
    396   } T;
    397   T t;
    398 
    399   Assembler assm(isolate, NULL, 0);
    400   Label L, C;
    401 
    402   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    403   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    404 
    405   // Swap f4 and f6, by using four integer registers, t0-t3.
    406   if (!IsFp64Mode()) {
    407     __ mfc1(t0, f4);
    408     __ mfc1(t1, f5);
    409     __ mfc1(t2, f6);
    410     __ mfc1(t3, f7);
    411 
    412     __ mtc1(t0, f6);
    413     __ mtc1(t1, f7);
    414     __ mtc1(t2, f4);
    415     __ mtc1(t3, f5);
    416   } else {
    417     CHECK(!IsMipsArchVariant(kMips32r1) && !IsMipsArchVariant(kLoongson));
    418     __ mfc1(t0, f4);
    419     __ mfhc1(t1, f4);
    420     __ mfc1(t2, f6);
    421     __ mfhc1(t3, f6);
    422 
    423     __ mtc1(t0, f6);
    424     __ mthc1(t1, f6);
    425     __ mtc1(t2, f4);
    426     __ mthc1(t3, f4);
    427   }
    428   // Store the swapped f4 and f5 back to memory.
    429   __ sdc1(f4, MemOperand(a0, offsetof(T, a)) );
    430   __ sdc1(f6, MemOperand(a0, offsetof(T, c)) );
    431 
    432   __ jr(ra);
    433   __ nop();
    434 
    435   CodeDesc desc;
    436   assm.GetCode(&desc);
    437   Handle<Code> code = isolate->factory()->NewCode(
    438       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    439   F3 f = FUNCTION_CAST<F3>(code->entry());
    440   t.a = 1.5e22;
    441   t.b = 2.75e11;
    442   t.c = 17.17;
    443   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    444   USE(dummy);
    445 
    446   CHECK_EQ(2.75e11, t.a);
    447   CHECK_EQ(2.75e11, t.b);
    448   CHECK_EQ(1.5e22, t.c);
    449 }
    450 
    451 
    452 TEST(MIPS5) {
    453   // Test conversions between doubles and integers.
    454   CcTest::InitializeVM();
    455   Isolate* isolate = CcTest::i_isolate();
    456   HandleScope scope(isolate);
    457 
    458   typedef struct {
    459     double a;
    460     double b;
    461     int i;
    462     int j;
    463   } T;
    464   T t;
    465 
    466   Assembler assm(isolate, NULL, 0);
    467   Label L, C;
    468 
    469   // Load all structure elements to registers.
    470   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    471   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    472   __ lw(t0, MemOperand(a0, offsetof(T, i)) );
    473   __ lw(t1, MemOperand(a0, offsetof(T, j)) );
    474 
    475   // Convert double in f4 to int in element i.
    476   __ cvt_w_d(f8, f4);
    477   __ mfc1(t2, f8);
    478   __ sw(t2, MemOperand(a0, offsetof(T, i)) );
    479 
    480   // Convert double in f6 to int in element j.
    481   __ cvt_w_d(f10, f6);
    482   __ mfc1(t3, f10);
    483   __ sw(t3, MemOperand(a0, offsetof(T, j)) );
    484 
    485   // Convert int in original i (t0) to double in a.
    486   __ mtc1(t0, f12);
    487   __ cvt_d_w(f0, f12);
    488   __ sdc1(f0, MemOperand(a0, offsetof(T, a)) );
    489 
    490   // Convert int in original j (t1) to double in b.
    491   __ mtc1(t1, f14);
    492   __ cvt_d_w(f2, f14);
    493   __ sdc1(f2, MemOperand(a0, offsetof(T, b)) );
    494 
    495   __ jr(ra);
    496   __ nop();
    497 
    498   CodeDesc desc;
    499   assm.GetCode(&desc);
    500   Handle<Code> code = isolate->factory()->NewCode(
    501       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    502   F3 f = FUNCTION_CAST<F3>(code->entry());
    503   t.a = 1.5e4;
    504   t.b = 2.75e8;
    505   t.i = 12345678;
    506   t.j = -100000;
    507   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    508   USE(dummy);
    509 
    510   CHECK_EQ(12345678.0, t.a);
    511   CHECK_EQ(-100000.0, t.b);
    512   CHECK_EQ(15000, t.i);
    513   CHECK_EQ(275000000, t.j);
    514 }
    515 
    516 
    517 TEST(MIPS6) {
    518   // Test simple memory loads and stores.
    519   CcTest::InitializeVM();
    520   Isolate* isolate = CcTest::i_isolate();
    521   HandleScope scope(isolate);
    522 
    523   typedef struct {
    524     uint32_t ui;
    525     int32_t si;
    526     int32_t r1;
    527     int32_t r2;
    528     int32_t r3;
    529     int32_t r4;
    530     int32_t r5;
    531     int32_t r6;
    532   } T;
    533   T t;
    534 
    535   Assembler assm(isolate, NULL, 0);
    536   Label L, C;
    537 
    538   // Basic word load/store.
    539   __ lw(t0, MemOperand(a0, offsetof(T, ui)) );
    540   __ sw(t0, MemOperand(a0, offsetof(T, r1)) );
    541 
    542   // lh with positive data.
    543   __ lh(t1, MemOperand(a0, offsetof(T, ui)) );
    544   __ sw(t1, MemOperand(a0, offsetof(T, r2)) );
    545 
    546   // lh with negative data.
    547   __ lh(t2, MemOperand(a0, offsetof(T, si)) );
    548   __ sw(t2, MemOperand(a0, offsetof(T, r3)) );
    549 
    550   // lhu with negative data.
    551   __ lhu(t3, MemOperand(a0, offsetof(T, si)) );
    552   __ sw(t3, MemOperand(a0, offsetof(T, r4)) );
    553 
    554   // lb with negative data.
    555   __ lb(t4, MemOperand(a0, offsetof(T, si)) );
    556   __ sw(t4, MemOperand(a0, offsetof(T, r5)) );
    557 
    558   // sh writes only 1/2 of word.
    559   __ lui(t5, 0x3333);
    560   __ ori(t5, t5, 0x3333);
    561   __ sw(t5, MemOperand(a0, offsetof(T, r6)) );
    562   __ lhu(t5, MemOperand(a0, offsetof(T, si)) );
    563   __ sh(t5, MemOperand(a0, offsetof(T, r6)) );
    564 
    565   __ jr(ra);
    566   __ nop();
    567 
    568   CodeDesc desc;
    569   assm.GetCode(&desc);
    570   Handle<Code> code = isolate->factory()->NewCode(
    571       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    572   F3 f = FUNCTION_CAST<F3>(code->entry());
    573   t.ui = 0x11223344;
    574   t.si = 0x99aabbcc;
    575   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    576   USE(dummy);
    577 
    578   CHECK_EQ(static_cast<int32_t>(0x11223344), t.r1);
    579 #if __BYTE_ORDER == __LITTLE_ENDIAN
    580   CHECK_EQ(static_cast<int32_t>(0x3344), t.r2);
    581   CHECK_EQ(static_cast<int32_t>(0xffffbbcc), t.r3);
    582   CHECK_EQ(static_cast<int32_t>(0x0000bbcc), t.r4);
    583   CHECK_EQ(static_cast<int32_t>(0xffffffcc), t.r5);
    584   CHECK_EQ(static_cast<int32_t>(0x3333bbcc), t.r6);
    585 #elif __BYTE_ORDER == __BIG_ENDIAN
    586   CHECK_EQ(static_cast<int32_t>(0x1122), t.r2);
    587   CHECK_EQ(static_cast<int32_t>(0xffff99aa), t.r3);
    588   CHECK_EQ(static_cast<int32_t>(0x000099aa), t.r4);
    589   CHECK_EQ(static_cast<int32_t>(0xffffff99), t.r5);
    590   CHECK_EQ(static_cast<int32_t>(0x99aa3333), t.r6);
    591 #else
    592 #error Unknown endianness
    593 #endif
    594 }
    595 
    596 
    597 TEST(MIPS7) {
    598   // Test floating point compare and branch instructions.
    599   CcTest::InitializeVM();
    600   Isolate* isolate = CcTest::i_isolate();
    601   HandleScope scope(isolate);
    602 
    603   typedef struct {
    604     double a;
    605     double b;
    606     double c;
    607     double d;
    608     double e;
    609     double f;
    610     int32_t result;
    611   } T;
    612   T t;
    613 
    614   // Create a function that accepts &t, and loads, manipulates, and stores
    615   // the doubles t.a ... t.f.
    616   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
    617   Label neither_is_nan, less_than, outa_here;
    618 
    619   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    620   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    621   if (!IsMipsArchVariant(kMips32r6)) {
    622   __ c(UN, D, f4, f6);
    623   __ bc1f(&neither_is_nan);
    624   } else {
    625     __ cmp(UN, L, f2, f4, f6);
    626     __ bc1eqz(&neither_is_nan, f2);
    627   }
    628   __ nop();
    629   __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
    630   __ Branch(&outa_here);
    631 
    632   __ bind(&neither_is_nan);
    633 
    634   if (IsMipsArchVariant(kLoongson)) {
    635     __ c(OLT, D, f6, f4);
    636     __ bc1t(&less_than);
    637   } else if (IsMipsArchVariant(kMips32r6)) {
    638     __ cmp(OLT, L, f2, f6, f4);
    639     __ bc1nez(&less_than, f2);
    640   } else {
    641     __ c(OLT, D, f6, f4, 2);
    642     __ bc1t(&less_than, 2);
    643   }
    644 
    645   __ nop();
    646   __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
    647   __ Branch(&outa_here);
    648 
    649   __ bind(&less_than);
    650   __ Addu(t0, zero_reg, Operand(1));
    651   __ sw(t0, MemOperand(a0, offsetof(T, result)) );  // Set true.
    652 
    653 
    654   // This test-case should have additional tests.
    655 
    656   __ bind(&outa_here);
    657 
    658   __ jr(ra);
    659   __ nop();
    660 
    661   CodeDesc desc;
    662   assm.GetCode(&desc);
    663   Handle<Code> code = isolate->factory()->NewCode(
    664       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    665   F3 f = FUNCTION_CAST<F3>(code->entry());
    666   t.a = 1.5e14;
    667   t.b = 2.75e11;
    668   t.c = 2.0;
    669   t.d = -4.0;
    670   t.e = 0.0;
    671   t.f = 0.0;
    672   t.result = 0;
    673   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    674   USE(dummy);
    675   CHECK_EQ(1.5e14, t.a);
    676   CHECK_EQ(2.75e11, t.b);
    677   CHECK_EQ(1, t.result);
    678 }
    679 
    680 
    681 TEST(MIPS8) {
    682   // Test ROTR and ROTRV instructions.
    683   if (IsMipsArchVariant(kMips32r2)) {
    684     CcTest::InitializeVM();
    685     Isolate* isolate = CcTest::i_isolate();
    686     HandleScope scope(isolate);
    687 
    688     typedef struct {
    689       int32_t input;
    690       int32_t result_rotr_4;
    691       int32_t result_rotr_8;
    692       int32_t result_rotr_12;
    693       int32_t result_rotr_16;
    694       int32_t result_rotr_20;
    695       int32_t result_rotr_24;
    696       int32_t result_rotr_28;
    697       int32_t result_rotrv_4;
    698       int32_t result_rotrv_8;
    699       int32_t result_rotrv_12;
    700       int32_t result_rotrv_16;
    701       int32_t result_rotrv_20;
    702       int32_t result_rotrv_24;
    703       int32_t result_rotrv_28;
    704     } T;
    705     T t;
    706 
    707     MacroAssembler assm(isolate, NULL, 0,
    708                         v8::internal::CodeObjectRequired::kYes);
    709 
    710     // Basic word load.
    711     __ lw(t0, MemOperand(a0, offsetof(T, input)) );
    712 
    713     // ROTR instruction (called through the Ror macro).
    714     __ Ror(t1, t0, 0x0004);
    715     __ Ror(t2, t0, 0x0008);
    716     __ Ror(t3, t0, 0x000c);
    717     __ Ror(t4, t0, 0x0010);
    718     __ Ror(t5, t0, 0x0014);
    719     __ Ror(t6, t0, 0x0018);
    720     __ Ror(t7, t0, 0x001c);
    721 
    722     // Basic word store.
    723     __ sw(t1, MemOperand(a0, offsetof(T, result_rotr_4)) );
    724     __ sw(t2, MemOperand(a0, offsetof(T, result_rotr_8)) );
    725     __ sw(t3, MemOperand(a0, offsetof(T, result_rotr_12)) );
    726     __ sw(t4, MemOperand(a0, offsetof(T, result_rotr_16)) );
    727     __ sw(t5, MemOperand(a0, offsetof(T, result_rotr_20)) );
    728     __ sw(t6, MemOperand(a0, offsetof(T, result_rotr_24)) );
    729     __ sw(t7, MemOperand(a0, offsetof(T, result_rotr_28)) );
    730 
    731     // ROTRV instruction (called through the Ror macro).
    732     __ li(t7, 0x0004);
    733     __ Ror(t1, t0, t7);
    734     __ li(t7, 0x0008);
    735     __ Ror(t2, t0, t7);
    736     __ li(t7, 0x000C);
    737     __ Ror(t3, t0, t7);
    738     __ li(t7, 0x0010);
    739     __ Ror(t4, t0, t7);
    740     __ li(t7, 0x0014);
    741     __ Ror(t5, t0, t7);
    742     __ li(t7, 0x0018);
    743     __ Ror(t6, t0, t7);
    744     __ li(t7, 0x001C);
    745     __ Ror(t7, t0, t7);
    746 
    747     // Basic word store.
    748     __ sw(t1, MemOperand(a0, offsetof(T, result_rotrv_4)) );
    749     __ sw(t2, MemOperand(a0, offsetof(T, result_rotrv_8)) );
    750     __ sw(t3, MemOperand(a0, offsetof(T, result_rotrv_12)) );
    751     __ sw(t4, MemOperand(a0, offsetof(T, result_rotrv_16)) );
    752     __ sw(t5, MemOperand(a0, offsetof(T, result_rotrv_20)) );
    753     __ sw(t6, MemOperand(a0, offsetof(T, result_rotrv_24)) );
    754     __ sw(t7, MemOperand(a0, offsetof(T, result_rotrv_28)) );
    755 
    756     __ jr(ra);
    757     __ nop();
    758 
    759     CodeDesc desc;
    760     assm.GetCode(&desc);
    761     Handle<Code> code = isolate->factory()->NewCode(
    762         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    763     F3 f = FUNCTION_CAST<F3>(code->entry());
    764     t.input = 0x12345678;
    765     Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0x0, 0, 0, 0);
    766     USE(dummy);
    767     CHECK_EQ(static_cast<int32_t>(0x81234567), t.result_rotr_4);
    768     CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotr_8);
    769     CHECK_EQ(static_cast<int32_t>(0x67812345), t.result_rotr_12);
    770     CHECK_EQ(static_cast<int32_t>(0x56781234), t.result_rotr_16);
    771     CHECK_EQ(static_cast<int32_t>(0x45678123), t.result_rotr_20);
    772     CHECK_EQ(static_cast<int32_t>(0x34567812), t.result_rotr_24);
    773     CHECK_EQ(static_cast<int32_t>(0x23456781), t.result_rotr_28);
    774 
    775     CHECK_EQ(static_cast<int32_t>(0x81234567), t.result_rotrv_4);
    776     CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotrv_8);
    777     CHECK_EQ(static_cast<int32_t>(0x67812345), t.result_rotrv_12);
    778     CHECK_EQ(static_cast<int32_t>(0x56781234), t.result_rotrv_16);
    779     CHECK_EQ(static_cast<int32_t>(0x45678123), t.result_rotrv_20);
    780     CHECK_EQ(static_cast<int32_t>(0x34567812), t.result_rotrv_24);
    781     CHECK_EQ(static_cast<int32_t>(0x23456781), t.result_rotrv_28);
    782   }
    783 }
    784 
    785 
    786 TEST(MIPS9) {
    787   // Test BRANCH improvements.
    788   CcTest::InitializeVM();
    789   Isolate* isolate = CcTest::i_isolate();
    790   HandleScope scope(isolate);
    791 
    792   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
    793   Label exit, exit2, exit3;
    794 
    795   __ Branch(&exit, ge, a0, Operand(zero_reg));
    796   __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
    797   __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
    798 
    799   __ bind(&exit);
    800   __ bind(&exit2);
    801   __ bind(&exit3);
    802   __ jr(ra);
    803   __ nop();
    804 
    805   CodeDesc desc;
    806   assm.GetCode(&desc);
    807   isolate->factory()->NewCode(
    808       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    809 }
    810 
    811 
    812 TEST(MIPS10) {
    813   // Test conversions between doubles and words.
    814   // Test maps double to FP reg pairs in fp32 mode
    815   // and into FP reg in fp64 mode.
    816   CcTest::InitializeVM();
    817   Isolate* isolate = CcTest::i_isolate();
    818   HandleScope scope(isolate);
    819 
    820   typedef struct {
    821     double a;
    822     double b;
    823     int32_t dbl_mant;
    824     int32_t dbl_exp;
    825     int32_t word;
    826     int32_t b_word;
    827   } T;
    828   T t;
    829 
    830   Assembler assm(isolate, NULL, 0);
    831   Label L, C;
    832 
    833   if (!IsMipsArchVariant(kMips32r2)) return;
    834 
    835   // Load all structure elements to registers.
    836   // (f0, f1) = a (fp32), f0 = a (fp64)
    837   __ ldc1(f0, MemOperand(a0, offsetof(T, a)));
    838 
    839   if (IsFp64Mode()) {
    840     __ mfc1(t0, f0);  // t0 = f0(31..0)
    841     __ mfhc1(t1, f0);  // t1 = sign_extend(f0(63..32))
    842     __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant)));  // dbl_mant = t0
    843     __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp)));  // dbl_exp = t1
    844   } else {
    845     // Save the raw bits of the double.
    846     __ mfc1(t0, f0);  // t0 = a1
    847     __ mfc1(t1, f1);  // t1 = a2
    848     __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant)));  // dbl_mant = t0
    849     __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp)));  // dbl_exp = t1
    850   }
    851 
    852   // Convert double in f0 to word, save hi/lo parts.
    853   __ cvt_w_d(f0, f0);  // a_word = (word)a
    854   __ mfc1(t0, f0);  // f0 has a 32-bits word. t0 = a_word
    855   __ sw(t0, MemOperand(a0, offsetof(T, word)));  // word = a_word
    856 
    857   // Convert the b word to double b.
    858   __ lw(t0, MemOperand(a0, offsetof(T, b_word)));
    859   __ mtc1(t0, f8);  // f8 has a 32-bits word.
    860   __ cvt_d_w(f10, f8);
    861   __ sdc1(f10, MemOperand(a0, offsetof(T, b)));
    862 
    863   __ jr(ra);
    864   __ nop();
    865 
    866   CodeDesc desc;
    867   assm.GetCode(&desc);
    868   Handle<Code> code = isolate->factory()->NewCode(
    869       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    870   F3 f = FUNCTION_CAST<F3>(code->entry());
    871   t.a = 2.147483646e+09;       // 0x7FFFFFFE -> 0xFF80000041DFFFFF as double.
    872   t.b_word = 0x0ff00ff0;       // 0x0FF00FF0 -> 0x as double.
    873   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    874   USE(dummy);
    875   CHECK_EQ(static_cast<int32_t>(0x41DFFFFF), t.dbl_exp);
    876   CHECK_EQ(static_cast<int32_t>(0xFF800000), t.dbl_mant);
    877   CHECK_EQ(static_cast<int32_t>(0x7FFFFFFE), t.word);
    878   // 0x0FF00FF0 -> 2.6739096+e08
    879   CHECK_EQ(2.6739096e08, t.b);
    880 }
    881 
    882 
    883 TEST(MIPS11) {
    884   // Do not run test on MIPS32r6, as these instructions are removed.
    885   if (IsMipsArchVariant(kMips32r6)) return;
    886   // Test LWL, LWR, SWL and SWR instructions.
    887   CcTest::InitializeVM();
    888   Isolate* isolate = CcTest::i_isolate();
    889   HandleScope scope(isolate);
    890 
    891   typedef struct {
    892     int32_t reg_init;
    893     int32_t mem_init;
    894     int32_t lwl_0;
    895     int32_t lwl_1;
    896     int32_t lwl_2;
    897     int32_t lwl_3;
    898     int32_t lwr_0;
    899     int32_t lwr_1;
    900     int32_t lwr_2;
    901     int32_t lwr_3;
    902     int32_t swl_0;
    903     int32_t swl_1;
    904     int32_t swl_2;
    905     int32_t swl_3;
    906     int32_t swr_0;
    907     int32_t swr_1;
    908     int32_t swr_2;
    909     int32_t swr_3;
    910   } T;
    911   T t;
    912 
    913   Assembler assm(isolate, NULL, 0);
    914 
    915   // Test all combinations of LWL and vAddr.
    916   __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
    917   __ lwl(t0, MemOperand(a0, offsetof(T, mem_init)) );
    918   __ sw(t0, MemOperand(a0, offsetof(T, lwl_0)) );
    919 
    920   __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
    921   __ lwl(t1, MemOperand(a0, offsetof(T, mem_init) + 1) );
    922   __ sw(t1, MemOperand(a0, offsetof(T, lwl_1)) );
    923 
    924   __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
    925   __ lwl(t2, MemOperand(a0, offsetof(T, mem_init) + 2) );
    926   __ sw(t2, MemOperand(a0, offsetof(T, lwl_2)) );
    927 
    928   __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
    929   __ lwl(t3, MemOperand(a0, offsetof(T, mem_init) + 3) );
    930   __ sw(t3, MemOperand(a0, offsetof(T, lwl_3)) );
    931 
    932   // Test all combinations of LWR and vAddr.
    933   __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
    934   __ lwr(t0, MemOperand(a0, offsetof(T, mem_init)) );
    935   __ sw(t0, MemOperand(a0, offsetof(T, lwr_0)) );
    936 
    937   __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
    938   __ lwr(t1, MemOperand(a0, offsetof(T, mem_init) + 1) );
    939   __ sw(t1, MemOperand(a0, offsetof(T, lwr_1)) );
    940 
    941   __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
    942   __ lwr(t2, MemOperand(a0, offsetof(T, mem_init) + 2) );
    943   __ sw(t2, MemOperand(a0, offsetof(T, lwr_2)) );
    944 
    945   __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
    946   __ lwr(t3, MemOperand(a0, offsetof(T, mem_init) + 3) );
    947   __ sw(t3, MemOperand(a0, offsetof(T, lwr_3)) );
    948 
    949   // Test all combinations of SWL and vAddr.
    950   __ lw(t0, MemOperand(a0, offsetof(T, mem_init)) );
    951   __ sw(t0, MemOperand(a0, offsetof(T, swl_0)) );
    952   __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
    953   __ swl(t0, MemOperand(a0, offsetof(T, swl_0)) );
    954 
    955   __ lw(t1, MemOperand(a0, offsetof(T, mem_init)) );
    956   __ sw(t1, MemOperand(a0, offsetof(T, swl_1)) );
    957   __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
    958   __ swl(t1, MemOperand(a0, offsetof(T, swl_1) + 1) );
    959 
    960   __ lw(t2, MemOperand(a0, offsetof(T, mem_init)) );
    961   __ sw(t2, MemOperand(a0, offsetof(T, swl_2)) );
    962   __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
    963   __ swl(t2, MemOperand(a0, offsetof(T, swl_2) + 2) );
    964 
    965   __ lw(t3, MemOperand(a0, offsetof(T, mem_init)) );
    966   __ sw(t3, MemOperand(a0, offsetof(T, swl_3)) );
    967   __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
    968   __ swl(t3, MemOperand(a0, offsetof(T, swl_3) + 3) );
    969 
    970   // Test all combinations of SWR and vAddr.
    971   __ lw(t0, MemOperand(a0, offsetof(T, mem_init)) );
    972   __ sw(t0, MemOperand(a0, offsetof(T, swr_0)) );
    973   __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
    974   __ swr(t0, MemOperand(a0, offsetof(T, swr_0)) );
    975 
    976   __ lw(t1, MemOperand(a0, offsetof(T, mem_init)) );
    977   __ sw(t1, MemOperand(a0, offsetof(T, swr_1)) );
    978   __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
    979   __ swr(t1, MemOperand(a0, offsetof(T, swr_1) + 1) );
    980 
    981   __ lw(t2, MemOperand(a0, offsetof(T, mem_init)) );
    982   __ sw(t2, MemOperand(a0, offsetof(T, swr_2)) );
    983   __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
    984   __ swr(t2, MemOperand(a0, offsetof(T, swr_2) + 2) );
    985 
    986   __ lw(t3, MemOperand(a0, offsetof(T, mem_init)) );
    987   __ sw(t3, MemOperand(a0, offsetof(T, swr_3)) );
    988   __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
    989   __ swr(t3, MemOperand(a0, offsetof(T, swr_3) + 3) );
    990 
    991   __ jr(ra);
    992   __ nop();
    993 
    994   CodeDesc desc;
    995   assm.GetCode(&desc);
    996   Handle<Code> code = isolate->factory()->NewCode(
    997       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    998   F3 f = FUNCTION_CAST<F3>(code->entry());
    999   t.reg_init = 0xaabbccdd;
   1000   t.mem_init = 0x11223344;
   1001 
   1002   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   1003   USE(dummy);
   1004 
   1005 #if __BYTE_ORDER == __LITTLE_ENDIAN
   1006   CHECK_EQ(static_cast<int32_t>(0x44bbccdd), t.lwl_0);
   1007   CHECK_EQ(static_cast<int32_t>(0x3344ccdd), t.lwl_1);
   1008   CHECK_EQ(static_cast<int32_t>(0x223344dd), t.lwl_2);
   1009   CHECK_EQ(static_cast<int32_t>(0x11223344), t.lwl_3);
   1010 
   1011   CHECK_EQ(static_cast<int32_t>(0x11223344), t.lwr_0);
   1012   CHECK_EQ(static_cast<int32_t>(0xaa112233), t.lwr_1);
   1013   CHECK_EQ(static_cast<int32_t>(0xaabb1122), t.lwr_2);
   1014   CHECK_EQ(static_cast<int32_t>(0xaabbcc11), t.lwr_3);
   1015 
   1016   CHECK_EQ(static_cast<int32_t>(0x112233aa), t.swl_0);
   1017   CHECK_EQ(static_cast<int32_t>(0x1122aabb), t.swl_1);
   1018   CHECK_EQ(static_cast<int32_t>(0x11aabbcc), t.swl_2);
   1019   CHECK_EQ(static_cast<int32_t>(0xaabbccdd), t.swl_3);
   1020 
   1021   CHECK_EQ(static_cast<int32_t>(0xaabbccdd), t.swr_0);
   1022   CHECK_EQ(static_cast<int32_t>(0xbbccdd44), t.swr_1);
   1023   CHECK_EQ(static_cast<int32_t>(0xccdd3344), t.swr_2);
   1024   CHECK_EQ(static_cast<int32_t>(0xdd223344), t.swr_3);
   1025 #elif __BYTE_ORDER == __BIG_ENDIAN
   1026   CHECK_EQ(static_cast<int32_t>(0x11223344), t.lwl_0);
   1027   CHECK_EQ(static_cast<int32_t>(0x223344dd), t.lwl_1);
   1028   CHECK_EQ(static_cast<int32_t>(0x3344ccdd), t.lwl_2);
   1029   CHECK_EQ(static_cast<int32_t>(0x44bbccdd), t.lwl_3);
   1030 
   1031   CHECK_EQ(static_cast<int32_t>(0xaabbcc11), t.lwr_0);
   1032   CHECK_EQ(static_cast<int32_t>(0xaabb1122), t.lwr_1);
   1033   CHECK_EQ(static_cast<int32_t>(0xaa112233), t.lwr_2);
   1034   CHECK_EQ(static_cast<int32_t>(0x11223344), t.lwr_3);
   1035 
   1036   CHECK_EQ(static_cast<int32_t>(0xaabbccdd), t.swl_0);
   1037   CHECK_EQ(static_cast<int32_t>(0x11aabbcc), t.swl_1);
   1038   CHECK_EQ(static_cast<int32_t>(0x1122aabb), t.swl_2);
   1039   CHECK_EQ(static_cast<int32_t>(0x112233aa), t.swl_3);
   1040 
   1041   CHECK_EQ(static_cast<int32_t>(0xdd223344), t.swr_0);
   1042   CHECK_EQ(static_cast<int32_t>(0xccdd3344), t.swr_1);
   1043   CHECK_EQ(static_cast<int32_t>(0xbbccdd44), t.swr_2);
   1044   CHECK_EQ(static_cast<int32_t>(0xaabbccdd), t.swr_3);
   1045 #else
   1046 #error Unknown endianness
   1047 #endif
   1048 }
   1049 
   1050 
   1051 TEST(MIPS12) {
   1052   CcTest::InitializeVM();
   1053   Isolate* isolate = CcTest::i_isolate();
   1054   HandleScope scope(isolate);
   1055 
   1056   typedef struct {
   1057       int32_t  x;
   1058       int32_t  y;
   1059       int32_t  y1;
   1060       int32_t  y2;
   1061       int32_t  y3;
   1062       int32_t  y4;
   1063   } T;
   1064   T t;
   1065 
   1066   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   1067 
   1068   __ mov(t6, fp);  // Save frame pointer.
   1069   __ mov(fp, a0);  // Access struct T by fp.
   1070   __ lw(t0, MemOperand(a0, offsetof(T, y)) );
   1071   __ lw(t3, MemOperand(a0, offsetof(T, y4)) );
   1072 
   1073   __ addu(t1, t0, t3);
   1074   __ subu(t4, t0, t3);
   1075   __ nop();
   1076   __ push(t0);  // These instructions disappear after opt.
   1077   __ Pop();
   1078   __ addu(t0, t0, t0);
   1079   __ nop();
   1080   __ Pop();     // These instructions disappear after opt.
   1081   __ push(t3);
   1082   __ nop();
   1083   __ push(t3);  // These instructions disappear after opt.
   1084   __ pop(t3);
   1085   __ nop();
   1086   __ push(t3);
   1087   __ pop(t4);
   1088   __ nop();
   1089   __ sw(t0, MemOperand(fp, offsetof(T, y)) );
   1090   __ lw(t0, MemOperand(fp, offsetof(T, y)) );
   1091   __ nop();
   1092   __ sw(t0, MemOperand(fp, offsetof(T, y)) );
   1093   __ lw(t1, MemOperand(fp, offsetof(T, y)) );
   1094   __ nop();
   1095   __ push(t1);
   1096   __ lw(t1, MemOperand(fp, offsetof(T, y)) );
   1097   __ pop(t1);
   1098   __ nop();
   1099   __ push(t1);
   1100   __ lw(t2, MemOperand(fp, offsetof(T, y)) );
   1101   __ pop(t1);
   1102   __ nop();
   1103   __ push(t1);
   1104   __ lw(t2, MemOperand(fp, offsetof(T, y)) );
   1105   __ pop(t2);
   1106   __ nop();
   1107   __ push(t2);
   1108   __ lw(t2, MemOperand(fp, offsetof(T, y)) );
   1109   __ pop(t1);
   1110   __ nop();
   1111   __ push(t1);
   1112   __ lw(t2, MemOperand(fp, offsetof(T, y)) );
   1113   __ pop(t3);
   1114   __ nop();
   1115 
   1116   __ mov(fp, t6);
   1117   __ jr(ra);
   1118   __ nop();
   1119 
   1120   CodeDesc desc;
   1121   assm.GetCode(&desc);
   1122   Handle<Code> code = isolate->factory()->NewCode(
   1123       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1124   F3 f = FUNCTION_CAST<F3>(code->entry());
   1125   t.x = 1;
   1126   t.y = 2;
   1127   t.y1 = 3;
   1128   t.y2 = 4;
   1129   t.y3 = 0XBABA;
   1130   t.y4 = 0xDEDA;
   1131 
   1132   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   1133   USE(dummy);
   1134 
   1135   CHECK_EQ(3, t.y1);
   1136 }
   1137 
   1138 
   1139 TEST(MIPS13) {
   1140   // Test Cvt_d_uw and Trunc_uw_d macros.
   1141   CcTest::InitializeVM();
   1142   Isolate* isolate = CcTest::i_isolate();
   1143   HandleScope scope(isolate);
   1144 
   1145   typedef struct {
   1146     double cvt_big_out;
   1147     double cvt_small_out;
   1148     uint32_t trunc_big_out;
   1149     uint32_t trunc_small_out;
   1150     uint32_t cvt_big_in;
   1151     uint32_t cvt_small_in;
   1152   } T;
   1153   T t;
   1154 
   1155   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   1156 
   1157   __ sw(t0, MemOperand(a0, offsetof(T, cvt_small_in)));
   1158   __ Cvt_d_uw(f10, t0, f4);
   1159   __ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out)));
   1160 
   1161   __ Trunc_uw_d(f10, f10, f4);
   1162   __ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out)));
   1163 
   1164   __ sw(t0, MemOperand(a0, offsetof(T, cvt_big_in)));
   1165   __ Cvt_d_uw(f8, t0, f4);
   1166   __ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out)));
   1167 
   1168   __ Trunc_uw_d(f8, f8, f4);
   1169   __ swc1(f8, MemOperand(a0, offsetof(T, trunc_big_out)));
   1170 
   1171   __ jr(ra);
   1172   __ nop();
   1173 
   1174   CodeDesc desc;
   1175   assm.GetCode(&desc);
   1176   Handle<Code> code = isolate->factory()->NewCode(
   1177       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1178   F3 f = FUNCTION_CAST<F3>(code->entry());
   1179 
   1180   t.cvt_big_in = 0xFFFFFFFF;
   1181   t.cvt_small_in  = 333;
   1182 
   1183   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   1184   USE(dummy);
   1185 
   1186   CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
   1187   CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
   1188 
   1189   CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
   1190   CHECK_EQ(static_cast<int>(t.trunc_small_out),
   1191            static_cast<int>(t.cvt_small_in));
   1192 }
   1193 
   1194 
   1195 TEST(MIPS14) {
   1196   // Test round, floor, ceil, trunc, cvt.
   1197   CcTest::InitializeVM();
   1198   Isolate* isolate = CcTest::i_isolate();
   1199   HandleScope scope(isolate);
   1200 
   1201 #define ROUND_STRUCT_ELEMENT(x) \
   1202   uint32_t x##_isNaN2008; \
   1203   int32_t x##_up_out; \
   1204   int32_t x##_down_out; \
   1205   int32_t neg_##x##_up_out; \
   1206   int32_t neg_##x##_down_out; \
   1207   uint32_t x##_err1_out; \
   1208   uint32_t x##_err2_out; \
   1209   uint32_t x##_err3_out; \
   1210   uint32_t x##_err4_out; \
   1211   int32_t x##_invalid_result;
   1212 
   1213   typedef struct {
   1214     double round_up_in;
   1215     double round_down_in;
   1216     double neg_round_up_in;
   1217     double neg_round_down_in;
   1218     double err1_in;
   1219     double err2_in;
   1220     double err3_in;
   1221     double err4_in;
   1222 
   1223     ROUND_STRUCT_ELEMENT(round)
   1224     ROUND_STRUCT_ELEMENT(floor)
   1225     ROUND_STRUCT_ELEMENT(ceil)
   1226     ROUND_STRUCT_ELEMENT(trunc)
   1227     ROUND_STRUCT_ELEMENT(cvt)
   1228   } T;
   1229   T t;
   1230 
   1231 #undef ROUND_STRUCT_ELEMENT
   1232 
   1233   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   1234 
   1235   // Save FCSR.
   1236   __ cfc1(a1, FCSR);
   1237   // Disable FPU exceptions.
   1238   __ ctc1(zero_reg, FCSR);
   1239 #define RUN_ROUND_TEST(x) \
   1240   __ cfc1(t0, FCSR);\
   1241   __ sw(t0, MemOperand(a0, offsetof(T, x##_isNaN2008))); \
   1242   __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \
   1243   __ x##_w_d(f0, f0); \
   1244   __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \
   1245   \
   1246   __ ldc1(f0, MemOperand(a0, offsetof(T, round_down_in))); \
   1247   __ x##_w_d(f0, f0); \
   1248   __ swc1(f0, MemOperand(a0, offsetof(T, x##_down_out))); \
   1249   \
   1250   __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_up_in))); \
   1251   __ x##_w_d(f0, f0); \
   1252   __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_up_out))); \
   1253   \
   1254   __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_down_in))); \
   1255   __ x##_w_d(f0, f0); \
   1256   __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_down_out))); \
   1257   \
   1258   __ ldc1(f0, MemOperand(a0, offsetof(T, err1_in))); \
   1259   __ ctc1(zero_reg, FCSR); \
   1260   __ x##_w_d(f0, f0); \
   1261   __ cfc1(a2, FCSR); \
   1262   __ sw(a2, MemOperand(a0, offsetof(T, x##_err1_out))); \
   1263   \
   1264   __ ldc1(f0, MemOperand(a0, offsetof(T, err2_in))); \
   1265   __ ctc1(zero_reg, FCSR); \
   1266   __ x##_w_d(f0, f0); \
   1267   __ cfc1(a2, FCSR); \
   1268   __ sw(a2, MemOperand(a0, offsetof(T, x##_err2_out))); \
   1269   \
   1270   __ ldc1(f0, MemOperand(a0, offsetof(T, err3_in))); \
   1271   __ ctc1(zero_reg, FCSR); \
   1272   __ x##_w_d(f0, f0); \
   1273   __ cfc1(a2, FCSR); \
   1274   __ sw(a2, MemOperand(a0, offsetof(T, x##_err3_out))); \
   1275   \
   1276   __ ldc1(f0, MemOperand(a0, offsetof(T, err4_in))); \
   1277   __ ctc1(zero_reg, FCSR); \
   1278   __ x##_w_d(f0, f0); \
   1279   __ cfc1(a2, FCSR); \
   1280   __ sw(a2, MemOperand(a0, offsetof(T, x##_err4_out))); \
   1281   __ swc1(f0, MemOperand(a0, offsetof(T, x##_invalid_result)));
   1282 
   1283   RUN_ROUND_TEST(round)
   1284   RUN_ROUND_TEST(floor)
   1285   RUN_ROUND_TEST(ceil)
   1286   RUN_ROUND_TEST(trunc)
   1287   RUN_ROUND_TEST(cvt)
   1288 
   1289   // Restore FCSR.
   1290   __ ctc1(a1, FCSR);
   1291 
   1292   __ jr(ra);
   1293   __ nop();
   1294 
   1295   CodeDesc desc;
   1296   assm.GetCode(&desc);
   1297   Handle<Code> code = isolate->factory()->NewCode(
   1298       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1299   F3 f = FUNCTION_CAST<F3>(code->entry());
   1300 
   1301   t.round_up_in = 123.51;
   1302   t.round_down_in = 123.49;
   1303   t.neg_round_up_in = -123.5;
   1304   t.neg_round_down_in = -123.49;
   1305   t.err1_in = 123.51;
   1306   t.err2_in = 1;
   1307   t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
   1308   t.err4_in = NAN;
   1309 
   1310   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   1311   USE(dummy);
   1312 
   1313 #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
   1314 #define CHECK_NAN2008(x) (x & kFCSRNaN2008FlagMask)
   1315 #define CHECK_ROUND_RESULT(type)                                  \
   1316   CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask);   \
   1317   CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out));                    \
   1318   CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
   1319   CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
   1320   if (CHECK_NAN2008(t.type##_isNaN2008) && kArchVariant == kMips32r6) {\
   1321     CHECK_EQ(static_cast<int32_t>(0), t.type##_invalid_result);\
   1322   } else {\
   1323     CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result);\
   1324   }
   1325 
   1326 
   1327   CHECK_ROUND_RESULT(round);
   1328   CHECK_ROUND_RESULT(floor);
   1329   CHECK_ROUND_RESULT(ceil);
   1330   CHECK_ROUND_RESULT(cvt);
   1331 }
   1332 
   1333 
   1334 TEST(MIPS15) {
   1335   // Test chaining of label usages within instructions (issue 1644).
   1336   CcTest::InitializeVM();
   1337   Isolate* isolate = CcTest::i_isolate();
   1338   HandleScope scope(isolate);
   1339   Assembler assm(isolate, NULL, 0);
   1340 
   1341   Label target;
   1342   __ beq(v0, v1, &target);
   1343   __ nop();
   1344   __ bne(v0, v1, &target);
   1345   __ nop();
   1346   __ bind(&target);
   1347   __ nop();
   1348 }
   1349 
   1350 
   1351 // ----------------------mips32r6 specific tests----------------------
   1352 TEST(seleqz_selnez) {
   1353   if (IsMipsArchVariant(kMips32r6)) {
   1354     CcTest::InitializeVM();
   1355     Isolate* isolate = CcTest::i_isolate();
   1356     HandleScope scope(isolate);
   1357     MacroAssembler assm(isolate, NULL, 0,
   1358                         v8::internal::CodeObjectRequired::kYes);
   1359 
   1360     typedef struct test {
   1361       int a;
   1362       int b;
   1363       int c;
   1364       int d;
   1365       double e;
   1366       double f;
   1367       double g;
   1368       double h;
   1369       float i;
   1370       float j;
   1371       float k;
   1372       float l;
   1373     } Test;
   1374 
   1375     Test test;
   1376     // Integer part of test.
   1377     __ addiu(t1, zero_reg, 1);                      // t1 = 1
   1378     __ seleqz(t3, t1, zero_reg);                    // t3 = 1
   1379     __ sw(t3, MemOperand(a0, offsetof(Test, a)));  // a = 1
   1380     __ seleqz(t2, t1, t1);                          // t2 = 0
   1381     __ sw(t2, MemOperand(a0, offsetof(Test, b)));  // b = 0
   1382     __ selnez(t3, t1, zero_reg);                    // t3 = 1;
   1383     __ sw(t3, MemOperand(a0, offsetof(Test, c)));  // c = 0
   1384     __ selnez(t3, t1, t1);                          // t3 = 1
   1385     __ sw(t3, MemOperand(a0, offsetof(Test, d)));  // d = 1
   1386     // Floating point part of test.
   1387     __ ldc1(f0, MemOperand(a0, offsetof(Test, e)) );  // src
   1388     __ ldc1(f2, MemOperand(a0, offsetof(Test, f)) );  // test
   1389     __ lwc1(f8, MemOperand(a0, offsetof(Test, i)) );  // src
   1390     __ lwc1(f10, MemOperand(a0, offsetof(Test, j)) );  // test
   1391     __ seleqz_d(f4, f0, f2);
   1392     __ selnez_d(f6, f0, f2);
   1393     __ seleqz_s(f12, f8, f10);
   1394     __ selnez_s(f14, f8, f10);
   1395     __ sdc1(f4, MemOperand(a0, offsetof(Test, g)) );  // src
   1396     __ sdc1(f6, MemOperand(a0, offsetof(Test, h)) );  // src
   1397     __ swc1(f12, MemOperand(a0, offsetof(Test, k)) );  // src
   1398     __ swc1(f14, MemOperand(a0, offsetof(Test, l)) );  // src
   1399     __ jr(ra);
   1400     __ nop();
   1401     CodeDesc desc;
   1402     assm.GetCode(&desc);
   1403     Handle<Code> code = isolate->factory()->NewCode(
   1404         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1405     F3 f = FUNCTION_CAST<F3>(code->entry());
   1406 
   1407     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1408 
   1409     CHECK_EQ(test.a, 1);
   1410     CHECK_EQ(test.b, 0);
   1411     CHECK_EQ(test.c, 0);
   1412     CHECK_EQ(test.d, 1);
   1413 
   1414     const int test_size = 3;
   1415     const int input_size = 5;
   1416 
   1417     double inputs_D[input_size] = {0.0, 65.2, -70.32,
   1418       18446744073709551621.0, -18446744073709551621.0};
   1419     double outputs_D[input_size] = {0.0, 65.2, -70.32,
   1420       18446744073709551621.0, -18446744073709551621.0};
   1421     double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
   1422       18446744073709551616.0, 18446744073709555712.0};
   1423     float inputs_S[input_size] = {0.0, 65.2, -70.32,
   1424       18446744073709551621.0, -18446744073709551621.0};
   1425     float outputs_S[input_size] = {0.0, 65.2, -70.32,
   1426       18446744073709551621.0, -18446744073709551621.0};
   1427     float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
   1428       18446744073709551616.0, 18446746272732807168.0};
   1429     for (int j=0; j < test_size; j+=2) {
   1430       for (int i=0; i < input_size; i++) {
   1431         test.e = inputs_D[i];
   1432         test.f = tests_D[j];
   1433         test.i = inputs_S[i];
   1434         test.j = tests_S[j];
   1435         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1436         CHECK_EQ(test.g, outputs_D[i]);
   1437         CHECK_EQ(test.h, 0);
   1438         CHECK_EQ(test.k, outputs_S[i]);
   1439         CHECK_EQ(test.l, 0);
   1440 
   1441         test.f = tests_D[j+1];
   1442         test.j = tests_S[j+1];
   1443         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1444         CHECK_EQ(test.g, 0);
   1445         CHECK_EQ(test.h, outputs_D[i]);
   1446         CHECK_EQ(test.k, 0);
   1447         CHECK_EQ(test.l, outputs_S[i]);
   1448       }
   1449     }
   1450   }
   1451 }
   1452 
   1453 
   1454 TEST(min_max) {
   1455   if (IsMipsArchVariant(kMips32r6)) {
   1456     CcTest::InitializeVM();
   1457     Isolate* isolate = CcTest::i_isolate();
   1458     HandleScope scope(isolate);
   1459     MacroAssembler assm(isolate, NULL, 0,
   1460                         v8::internal::CodeObjectRequired::kYes);
   1461 
   1462     typedef struct test_float {
   1463       double a;
   1464       double b;
   1465       double c;
   1466       double d;
   1467       float e;
   1468       float f;
   1469       float g;
   1470       float h;
   1471     } TestFloat;
   1472 
   1473     TestFloat test;
   1474     const double double_nan = std::numeric_limits<double>::quiet_NaN();
   1475     const float  float_nan = std::numeric_limits<float>::quiet_NaN();
   1476     const int kTableLength = 5;
   1477     double inputsa[kTableLength] = {2.0, 3.0, double_nan, 3.0, double_nan};
   1478     double inputsb[kTableLength] = {3.0, 2.0, 3.0, double_nan, double_nan};
   1479     double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, double_nan};
   1480     double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, double_nan};
   1481 
   1482     float inputse[kTableLength] = {2.0, 3.0, float_nan, 3.0, float_nan};
   1483     float inputsf[kTableLength] = {3.0, 2.0, 3.0, float_nan, float_nan};
   1484     float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, float_nan};
   1485     float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, float_nan};
   1486 
   1487     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
   1488     __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
   1489     __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
   1490     __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
   1491     __ min_d(f10, f4, f8);
   1492     __ max_d(f12, f4, f8);
   1493     __ min_s(f14, f2, f6);
   1494     __ max_s(f16, f2, f6);
   1495     __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
   1496     __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
   1497     __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
   1498     __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
   1499     __ jr(ra);
   1500     __ nop();
   1501 
   1502     CodeDesc desc;
   1503     assm.GetCode(&desc);
   1504     Handle<Code> code = isolate->factory()->NewCode(
   1505         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1506     F3 f = FUNCTION_CAST<F3>(code->entry());
   1507     for (int i = 0; i < kTableLength; i++) {
   1508       test.a = inputsa[i];
   1509       test.b = inputsb[i];
   1510       test.e = inputse[i];
   1511       test.f = inputsf[i];
   1512 
   1513       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1514 
   1515       if (i < kTableLength - 1) {
   1516         CHECK_EQ(test.c, outputsdmin[i]);
   1517         CHECK_EQ(test.d, outputsdmax[i]);
   1518         CHECK_EQ(test.g, outputsfmin[i]);
   1519         CHECK_EQ(test.h, outputsfmax[i]);
   1520       } else {
   1521         CHECK(std::isnan(test.c));
   1522         CHECK(std::isnan(test.d));
   1523         CHECK(std::isnan(test.g));
   1524         CHECK(std::isnan(test.h));
   1525       }
   1526     }
   1527   }
   1528 }
   1529 
   1530 
   1531 TEST(rint_d)  {
   1532   if (IsMipsArchVariant(kMips32r6)) {
   1533     const int kTableLength = 30;
   1534     CcTest::InitializeVM();
   1535     Isolate* isolate = CcTest::i_isolate();
   1536     HandleScope scope(isolate);
   1537     MacroAssembler assm(isolate, NULL, 0,
   1538                         v8::internal::CodeObjectRequired::kYes);
   1539 
   1540     typedef struct test_float {
   1541       double a;
   1542       double b;
   1543       int fcsr;
   1544     }TestFloat;
   1545 
   1546     TestFloat test;
   1547     double inputs[kTableLength] = {18446744073709551617.0,
   1548       4503599627370496.0, -4503599627370496.0,
   1549       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1550       1.7976931348623157E+308, 6.27463370218383111104242366943E-307,
   1551       309485009821345068724781056.89,
   1552       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1553       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1554       37778931862957161709568.0, 37778931862957161709569.0,
   1555       37778931862957161709580.0, 37778931862957161709581.0,
   1556       37778931862957161709582.0, 37778931862957161709583.0,
   1557       37778931862957161709584.0, 37778931862957161709585.0,
   1558       37778931862957161709586.0, 37778931862957161709587.0};
   1559     double outputs_RN[kTableLength] = {18446744073709551617.0,
   1560       4503599627370496.0, -4503599627370496.0,
   1561       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1562       1.7976931348623157E308, 0,
   1563       309485009821345068724781057.0,
   1564       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   1565       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   1566       37778931862957161709568.0, 37778931862957161709569.0,
   1567       37778931862957161709580.0, 37778931862957161709581.0,
   1568       37778931862957161709582.0, 37778931862957161709583.0,
   1569       37778931862957161709584.0, 37778931862957161709585.0,
   1570       37778931862957161709586.0, 37778931862957161709587.0};
   1571     double outputs_RZ[kTableLength] = {18446744073709551617.0,
   1572       4503599627370496.0, -4503599627370496.0,
   1573       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1574       1.7976931348623157E308, 0,
   1575       309485009821345068724781057.0,
   1576       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1577       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1578       37778931862957161709568.0, 37778931862957161709569.0,
   1579       37778931862957161709580.0, 37778931862957161709581.0,
   1580       37778931862957161709582.0, 37778931862957161709583.0,
   1581       37778931862957161709584.0, 37778931862957161709585.0,
   1582       37778931862957161709586.0, 37778931862957161709587.0};
   1583     double outputs_RP[kTableLength] = {18446744073709551617.0,
   1584       4503599627370496.0, -4503599627370496.0,
   1585       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1586       1.7976931348623157E308, 1,
   1587       309485009821345068724781057.0,
   1588       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   1589       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1590       37778931862957161709568.0, 37778931862957161709569.0,
   1591       37778931862957161709580.0, 37778931862957161709581.0,
   1592       37778931862957161709582.0, 37778931862957161709583.0,
   1593       37778931862957161709584.0, 37778931862957161709585.0,
   1594       37778931862957161709586.0, 37778931862957161709587.0};
   1595     double outputs_RM[kTableLength] = {18446744073709551617.0,
   1596       4503599627370496.0, -4503599627370496.0,
   1597       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1598       1.7976931348623157E308, 0,
   1599       309485009821345068724781057.0,
   1600       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1601       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   1602       37778931862957161709568.0, 37778931862957161709569.0,
   1603       37778931862957161709580.0, 37778931862957161709581.0,
   1604       37778931862957161709582.0, 37778931862957161709583.0,
   1605       37778931862957161709584.0, 37778931862957161709585.0,
   1606       37778931862957161709586.0, 37778931862957161709587.0};
   1607     int fcsr_inputs[4] =
   1608       {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
   1609     double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
   1610     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
   1611     __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
   1612     __ cfc1(t1, FCSR);
   1613     __ ctc1(t0, FCSR);
   1614     __ rint_d(f8, f4);
   1615     __ sdc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
   1616     __ ctc1(t1, FCSR);
   1617     __ jr(ra);
   1618     __ nop();
   1619 
   1620     CodeDesc desc;
   1621     assm.GetCode(&desc);
   1622     Handle<Code> code = isolate->factory()->NewCode(
   1623         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1624     F3 f = FUNCTION_CAST<F3>(code->entry());
   1625 
   1626     for (int j = 0; j < 4; j++) {
   1627       test.fcsr = fcsr_inputs[j];
   1628       for (int i = 0; i < kTableLength; i++) {
   1629         test.a = inputs[i];
   1630         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1631         CHECK_EQ(test.b, outputs[j][i]);
   1632       }
   1633     }
   1634   }
   1635 }
   1636 
   1637 
   1638 TEST(sel) {
   1639   if (IsMipsArchVariant(kMips32r6)) {
   1640     CcTest::InitializeVM();
   1641     Isolate* isolate = CcTest::i_isolate();
   1642     HandleScope scope(isolate);
   1643     MacroAssembler assm(isolate, NULL, 0,
   1644                         v8::internal::CodeObjectRequired::kYes);
   1645 
   1646     typedef struct test {
   1647       double dd;
   1648       double ds;
   1649       double dt;
   1650       float fd;
   1651       float fs;
   1652       float ft;
   1653     } Test;
   1654 
   1655     Test test;
   1656     __ ldc1(f0, MemOperand(a0, offsetof(Test, dd)) );  // test
   1657     __ ldc1(f2, MemOperand(a0, offsetof(Test, ds)) );  // src1
   1658     __ ldc1(f4, MemOperand(a0, offsetof(Test, dt)) );  // src2
   1659     __ lwc1(f6, MemOperand(a0, offsetof(Test, fd)) );  // test
   1660     __ lwc1(f8, MemOperand(a0, offsetof(Test, fs)) );  // src1
   1661     __ lwc1(f10, MemOperand(a0, offsetof(Test, ft)) );  // src2
   1662     __ sel_d(f0, f2, f4);
   1663     __ sel_s(f6, f8, f10);
   1664     __ sdc1(f0, MemOperand(a0, offsetof(Test, dd)) );
   1665     __ swc1(f6, MemOperand(a0, offsetof(Test, fd)) );
   1666     __ jr(ra);
   1667     __ nop();
   1668     CodeDesc desc;
   1669     assm.GetCode(&desc);
   1670     Handle<Code> code = isolate->factory()->NewCode(
   1671         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1672     F3 f = FUNCTION_CAST<F3>(code->entry());
   1673 
   1674     const int test_size = 3;
   1675     const int input_size = 5;
   1676 
   1677     double inputs_dt[input_size] = {0.0, 65.2, -70.32,
   1678       18446744073709551621.0, -18446744073709551621.0};
   1679     double inputs_ds[input_size] = {0.1, 69.88, -91.325,
   1680       18446744073709551625.0, -18446744073709551625.0};
   1681     float inputs_ft[input_size] = {0.0, 65.2, -70.32,
   1682       18446744073709551621.0, -18446744073709551621.0};
   1683     float inputs_fs[input_size] = {0.1, 69.88, -91.325,
   1684       18446744073709551625.0, -18446744073709551625.0};
   1685     double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
   1686       18446744073709551616.0, 18446744073709555712.0};
   1687     float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
   1688       18446744073709551616.0, 18446746272732807168.0};
   1689     for (int j=0; j < test_size; j+=2) {
   1690       for (int i=0; i < input_size; i++) {
   1691         test.dt = inputs_dt[i];
   1692         test.dd = tests_D[j];
   1693         test.ds = inputs_ds[i];
   1694         test.ft = inputs_ft[i];
   1695         test.fd = tests_S[j];
   1696         test.fs = inputs_fs[i];
   1697         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1698         CHECK_EQ(test.dd, inputs_ds[i]);
   1699         CHECK_EQ(test.fd, inputs_fs[i]);
   1700 
   1701         test.dd = tests_D[j+1];
   1702         test.fd = tests_S[j+1];
   1703         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1704         CHECK_EQ(test.dd, inputs_dt[i]);
   1705         CHECK_EQ(test.fd, inputs_ft[i]);
   1706       }
   1707     }
   1708   }
   1709 }
   1710 
   1711 
   1712 TEST(rint_s)  {
   1713   if (IsMipsArchVariant(kMips32r6)) {
   1714     const int kTableLength = 30;
   1715     CcTest::InitializeVM();
   1716     Isolate* isolate = CcTest::i_isolate();
   1717     HandleScope scope(isolate);
   1718     MacroAssembler assm(isolate, NULL, 0,
   1719                         v8::internal::CodeObjectRequired::kYes);
   1720 
   1721     typedef struct test_float {
   1722       float a;
   1723       float b;
   1724       int fcsr;
   1725     }TestFloat;
   1726 
   1727     TestFloat test;
   1728     float inputs[kTableLength] = {18446744073709551617.0,
   1729       4503599627370496.0, -4503599627370496.0,
   1730       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1731       1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
   1732       309485009821345068724781056.89,
   1733       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1734       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1735       37778931862957161709568.0, 37778931862957161709569.0,
   1736       37778931862957161709580.0, 37778931862957161709581.0,
   1737       37778931862957161709582.0, 37778931862957161709583.0,
   1738       37778931862957161709584.0, 37778931862957161709585.0,
   1739       37778931862957161709586.0, 37778931862957161709587.0};
   1740     float outputs_RN[kTableLength] = {18446744073709551617.0,
   1741       4503599627370496.0, -4503599627370496.0,
   1742       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1743       1.7976931348623157E38, 0,
   1744       309485009821345068724781057.0,
   1745       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   1746       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   1747       37778931862957161709568.0, 37778931862957161709569.0,
   1748       37778931862957161709580.0, 37778931862957161709581.0,
   1749       37778931862957161709582.0, 37778931862957161709583.0,
   1750       37778931862957161709584.0, 37778931862957161709585.0,
   1751       37778931862957161709586.0, 37778931862957161709587.0};
   1752     float outputs_RZ[kTableLength] = {18446744073709551617.0,
   1753       4503599627370496.0, -4503599627370496.0,
   1754       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1755       1.7976931348623157E38, 0,
   1756       309485009821345068724781057.0,
   1757       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1758       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1759       37778931862957161709568.0, 37778931862957161709569.0,
   1760       37778931862957161709580.0, 37778931862957161709581.0,
   1761       37778931862957161709582.0, 37778931862957161709583.0,
   1762       37778931862957161709584.0, 37778931862957161709585.0,
   1763       37778931862957161709586.0, 37778931862957161709587.0};
   1764     float outputs_RP[kTableLength] = {18446744073709551617.0,
   1765       4503599627370496.0, -4503599627370496.0,
   1766       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1767       1.7976931348623157E38, 1,
   1768       309485009821345068724781057.0,
   1769       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   1770       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1771       37778931862957161709568.0, 37778931862957161709569.0,
   1772       37778931862957161709580.0, 37778931862957161709581.0,
   1773       37778931862957161709582.0, 37778931862957161709583.0,
   1774       37778931862957161709584.0, 37778931862957161709585.0,
   1775       37778931862957161709586.0, 37778931862957161709587.0};
   1776     float outputs_RM[kTableLength] = {18446744073709551617.0,
   1777       4503599627370496.0, -4503599627370496.0,
   1778       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1779       1.7976931348623157E38, 0,
   1780       309485009821345068724781057.0,
   1781       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1782       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   1783       37778931862957161709568.0, 37778931862957161709569.0,
   1784       37778931862957161709580.0, 37778931862957161709581.0,
   1785       37778931862957161709582.0, 37778931862957161709583.0,
   1786       37778931862957161709584.0, 37778931862957161709585.0,
   1787       37778931862957161709586.0, 37778931862957161709587.0};
   1788     int fcsr_inputs[4] =
   1789       {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
   1790     float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
   1791     __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
   1792     __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
   1793     __ cfc1(t1, FCSR);
   1794     __ ctc1(t0, FCSR);
   1795     __ rint_s(f8, f4);
   1796     __ swc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
   1797     __ ctc1(t1, FCSR);
   1798     __ jr(ra);
   1799     __ nop();
   1800 
   1801     CodeDesc desc;
   1802     assm.GetCode(&desc);
   1803     Handle<Code> code = isolate->factory()->NewCode(
   1804         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1805     F3 f = FUNCTION_CAST<F3>(code->entry());
   1806 
   1807     for (int j = 0; j < 4; j++) {
   1808       test.fcsr = fcsr_inputs[j];
   1809       for (int i = 0; i < kTableLength; i++) {
   1810         test.a = inputs[i];
   1811         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1812         CHECK_EQ(test.b, outputs[j][i]);
   1813       }
   1814     }
   1815   }
   1816 }
   1817 
   1818 
   1819 TEST(Cvt_d_uw) {
   1820   CcTest::InitializeVM();
   1821   Isolate* isolate = CcTest::i_isolate();
   1822   HandleScope scope(isolate);
   1823   MacroAssembler assm(isolate, NULL, 0,
   1824                       v8::internal::CodeObjectRequired::kYes);
   1825 
   1826   typedef struct test_struct {
   1827     unsigned input;
   1828     uint64_t output;
   1829   } TestStruct;
   1830 
   1831   unsigned inputs[] = {
   1832     0x0, 0xffffffff, 0x80000000, 0x7fffffff
   1833   };
   1834 
   1835   uint64_t outputs[] = {
   1836     0x0, 0x41efffffffe00000,
   1837     0x41e0000000000000, 0x41dfffffffc00000
   1838   };
   1839 
   1840   int kTableLength = sizeof(inputs)/sizeof(inputs[0]);
   1841 
   1842   TestStruct test;
   1843 
   1844   __ lw(t1, MemOperand(a0, offsetof(TestStruct, input)));
   1845   __ Cvt_d_uw(f4, t1, f6);
   1846   __ sdc1(f4, MemOperand(a0, offsetof(TestStruct, output)));
   1847   __ jr(ra);
   1848   __ nop();
   1849 
   1850   CodeDesc desc;
   1851   assm.GetCode(&desc);
   1852   Handle<Code> code = isolate->factory()->NewCode(
   1853       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1854   F3 f = FUNCTION_CAST<F3>(code->entry());
   1855   for (int i = 0; i < kTableLength; i++) {
   1856     test.input = inputs[i];
   1857     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1858     // Check outputs
   1859     CHECK_EQ(test.output, outputs[i]);
   1860   }
   1861 }
   1862 
   1863 
   1864 TEST(mina_maxa) {
   1865   if (IsMipsArchVariant(kMips32r6)) {
   1866     const int kTableLength = 15;
   1867     CcTest::InitializeVM();
   1868     Isolate* isolate = CcTest::i_isolate();
   1869     HandleScope scope(isolate);
   1870     MacroAssembler assm(isolate, NULL, 0,
   1871                         v8::internal::CodeObjectRequired::kYes);
   1872     const double double_nan = std::numeric_limits<double>::quiet_NaN();
   1873     const float  float_nan = std::numeric_limits<float>::quiet_NaN();
   1874 
   1875     typedef struct test_float {
   1876       double a;
   1877       double b;
   1878       double resd;
   1879       double resd1;
   1880       float c;
   1881       float d;
   1882       float resf;
   1883       float resf1;
   1884     }TestFloat;
   1885 
   1886     TestFloat test;
   1887     double inputsa[kTableLength] = {
   1888       5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9,
   1889       -9.8, -10.0, -8.9, -9.8, double_nan, 3.0, double_nan
   1890     };
   1891     double inputsb[kTableLength] = {
   1892       4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8,
   1893       9.8, -9.8, -11.2, -9.8, 3.0, double_nan, double_nan
   1894     };
   1895     double resd[kTableLength] = {
   1896       4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9,
   1897       -9.8, -9.8, -8.9, -9.8, 3.0, 3.0, double_nan
   1898     };
   1899     double resd1[kTableLength] = {
   1900       5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8,
   1901       9.8, -10.0, -11.2, -9.8, 3.0, 3.0, double_nan
   1902     };
   1903     float inputsc[kTableLength] = {
   1904       5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9,
   1905       -9.8, -10.0, -8.9, -9.8, float_nan, 3.0, float_nan
   1906     };
   1907     float inputsd[kTableLength] = {
   1908       4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8,
   1909       9.8, -9.8, -11.2, -9.8, 3.0, float_nan, float_nan
   1910     };
   1911     float resf[kTableLength] = {
   1912       4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9,
   1913       -9.8, -9.8, -8.9, -9.8, 3.0, 3.0, float_nan
   1914     };
   1915     float resf1[kTableLength] = {
   1916       5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8,
   1917       9.8, -10.0, -11.2, -9.8, 3.0, 3.0, float_nan
   1918     };
   1919 
   1920     __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   1921     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
   1922     __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   1923     __ lwc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
   1924     __ mina_d(f6, f2, f4);
   1925     __ mina_s(f12, f8, f10);
   1926     __ maxa_d(f14, f2, f4);
   1927     __ maxa_s(f16, f8, f10);
   1928     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, resf)) );
   1929     __ sdc1(f6, MemOperand(a0, offsetof(TestFloat, resd)) );
   1930     __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resf1)) );
   1931     __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resd1)) );
   1932     __ jr(ra);
   1933     __ nop();
   1934 
   1935     CodeDesc desc;
   1936     assm.GetCode(&desc);
   1937     Handle<Code> code = isolate->factory()->NewCode(
   1938         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1939     F3 f = FUNCTION_CAST<F3>(code->entry());
   1940     for (int i = 0; i < kTableLength; i++) {
   1941       test.a = inputsa[i];
   1942       test.b = inputsb[i];
   1943       test.c = inputsc[i];
   1944       test.d = inputsd[i];
   1945       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1946       if (i < kTableLength - 1) {
   1947         CHECK_EQ(test.resd, resd[i]);
   1948         CHECK_EQ(test.resf, resf[i]);
   1949         CHECK_EQ(test.resd1, resd1[i]);
   1950         CHECK_EQ(test.resf1, resf1[i]);
   1951       } else {
   1952         CHECK(std::isnan(test.resd));
   1953         CHECK(std::isnan(test.resf));
   1954         CHECK(std::isnan(test.resd1));
   1955         CHECK(std::isnan(test.resf1));
   1956       }
   1957     }
   1958   }
   1959 }
   1960 
   1961 
   1962 // ----------------------mips32r2 specific tests----------------------
   1963 TEST(trunc_l) {
   1964   if (IsMipsArchVariant(kMips32r2) && IsFp64Mode()) {
   1965     CcTest::InitializeVM();
   1966     Isolate* isolate = CcTest::i_isolate();
   1967     HandleScope scope(isolate);
   1968     MacroAssembler assm(isolate, NULL, 0,
   1969                         v8::internal::CodeObjectRequired::kYes);
   1970     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   1971     typedef struct test_float {
   1972       uint32_t isNaN2008;
   1973       double a;
   1974       float b;
   1975       int64_t c;  // a trunc result
   1976       int64_t d;  // b trunc result
   1977     }Test;
   1978     const int kTableLength = 15;
   1979     double inputs_D[kTableLength] = {
   1980         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1981         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1982         2147483648.0,
   1983         std::numeric_limits<double>::quiet_NaN(),
   1984         std::numeric_limits<double>::infinity()
   1985         };
   1986     float inputs_S[kTableLength] = {
   1987         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1988         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1989         2147483648.0,
   1990         std::numeric_limits<float>::quiet_NaN(),
   1991         std::numeric_limits<float>::infinity()
   1992         };
   1993     double outputs[kTableLength] = {
   1994         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1995         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1996         2147483648.0, dFPU64InvalidResult,
   1997         dFPU64InvalidResult};
   1998     double outputsNaN2008[kTableLength] = {
   1999         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2000         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2001         2147483648.0,
   2002         0,
   2003         dFPU64InvalidResult};
   2004 
   2005     __ cfc1(t1, FCSR);
   2006     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2007     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2008     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2009     __ trunc_l_d(f8, f4);
   2010     __ trunc_l_s(f10, f6);
   2011     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2012     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2013     __ jr(ra);
   2014     __ nop();
   2015     Test test;
   2016     CodeDesc desc;
   2017     assm.GetCode(&desc);
   2018     Handle<Code> code = isolate->factory()->NewCode(
   2019         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2020     F3 f = FUNCTION_CAST<F3>(code->entry());
   2021     for (int i = 0; i < kTableLength; i++) {
   2022       test.a = inputs_D[i];
   2023       test.b = inputs_S[i];
   2024       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2025       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   2026               kArchVariant == kMips32r6) {
   2027         CHECK_EQ(test.c, outputsNaN2008[i]);
   2028       } else {
   2029         CHECK_EQ(test.c, outputs[i]);
   2030       }
   2031       CHECK_EQ(test.d, test.c);
   2032     }
   2033   }
   2034 }
   2035 
   2036 
   2037 TEST(movz_movn) {
   2038   if (IsMipsArchVariant(kMips32r2)) {
   2039     const int kTableLength = 4;
   2040     CcTest::InitializeVM();
   2041     Isolate* isolate = CcTest::i_isolate();
   2042     HandleScope scope(isolate);
   2043     MacroAssembler assm(isolate, NULL, 0,
   2044                         v8::internal::CodeObjectRequired::kYes);
   2045 
   2046     typedef struct test_float {
   2047       int64_t rt;
   2048       double a;
   2049       double b;
   2050       double bold;
   2051       double b1;
   2052       double bold1;
   2053       float c;
   2054       float d;
   2055       float dold;
   2056       float d1;
   2057       float dold1;
   2058     }TestFloat;
   2059 
   2060     TestFloat test;
   2061     double inputs_D[kTableLength] = {
   2062       5.3, -5.3, 5.3, -2.9
   2063     };
   2064     double inputs_S[kTableLength] = {
   2065       4.8, 4.8, -4.8, -0.29
   2066     };
   2067 
   2068     float outputs_S[kTableLength] = {
   2069       4.8, 4.8, -4.8, -0.29
   2070     };
   2071     double outputs_D[kTableLength] = {
   2072       5.3, -5.3, 5.3, -2.9
   2073     };
   2074 
   2075     __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2076     __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
   2077     __ lw(t0, MemOperand(a0, offsetof(TestFloat, rt)) );
   2078     __ Move(f12, 0.0);
   2079     __ Move(f10, 0.0);
   2080     __ Move(f16, 0.0);
   2081     __ Move(f14, 0.0);
   2082     __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, bold)) );
   2083     __ swc1(f10, MemOperand(a0, offsetof(TestFloat, dold)) );
   2084     __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, bold1)) );
   2085     __ swc1(f14, MemOperand(a0, offsetof(TestFloat, dold1)) );
   2086     __ movz_s(f10, f6, t0);
   2087     __ movz_d(f12, f2, t0);
   2088     __ movn_s(f14, f6, t0);
   2089     __ movn_d(f16, f2, t0);
   2090     __ swc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
   2091     __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, b)) );
   2092     __ swc1(f14, MemOperand(a0, offsetof(TestFloat, d1)) );
   2093     __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, b1)) );
   2094     __ jr(ra);
   2095     __ nop();
   2096 
   2097     CodeDesc desc;
   2098     assm.GetCode(&desc);
   2099     Handle<Code> code = isolate->factory()->NewCode(
   2100         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2101     F3 f = FUNCTION_CAST<F3>(code->entry());
   2102     for (int i = 0; i < kTableLength; i++) {
   2103       test.a = inputs_D[i];
   2104       test.c = inputs_S[i];
   2105 
   2106       test.rt = 1;
   2107       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2108       CHECK_EQ(test.b, test.bold);
   2109       CHECK_EQ(test.d, test.dold);
   2110       CHECK_EQ(test.b1, outputs_D[i]);
   2111       CHECK_EQ(test.d1, outputs_S[i]);
   2112 
   2113       test.rt = 0;
   2114       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2115       CHECK_EQ(test.b, outputs_D[i]);
   2116       CHECK_EQ(test.d, outputs_S[i]);
   2117       CHECK_EQ(test.b1, test.bold1);
   2118       CHECK_EQ(test.d1, test.dold1);
   2119     }
   2120   }
   2121 }
   2122 
   2123 
   2124 TEST(movt_movd) {
   2125   if (IsMipsArchVariant(kMips32r2)) {
   2126     const int kTableLength = 4;
   2127     CcTest::InitializeVM();
   2128     Isolate* isolate = CcTest::i_isolate();
   2129 
   2130     typedef struct test_float {
   2131       double srcd;
   2132       double dstd;
   2133       double dstdold;
   2134       double dstd1;
   2135       double dstdold1;
   2136       float srcf;
   2137       float dstf;
   2138       float dstfold;
   2139       float dstf1;
   2140       float dstfold1;
   2141       int32_t cc;
   2142       int32_t fcsr;
   2143     }TestFloat;
   2144 
   2145     TestFloat test;
   2146     double inputs_D[kTableLength] = {
   2147       5.3, -5.3, 20.8, -2.9
   2148     };
   2149     double inputs_S[kTableLength] = {
   2150       4.88, 4.8, -4.8, -0.29
   2151     };
   2152 
   2153     float outputs_S[kTableLength] = {
   2154       4.88, 4.8, -4.8, -0.29
   2155     };
   2156     double outputs_D[kTableLength] = {
   2157       5.3, -5.3, 20.8, -2.9
   2158     };
   2159     int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7};
   2160 
   2161     for (int i = 0; i < kTableLength; i++) {
   2162       test.srcd = inputs_D[i];
   2163       test.srcf = inputs_S[i];
   2164 
   2165       for (int j = 0; j< 8; j++) {
   2166         test.cc = condition_flags[j];
   2167         if (test.cc == 0) {
   2168           test.fcsr = 1 << 23;
   2169         } else {
   2170           test.fcsr = 1 << (24+condition_flags[j]);
   2171         }
   2172         HandleScope scope(isolate);
   2173         MacroAssembler assm(isolate, NULL, 0,
   2174                             v8::internal::CodeObjectRequired::kYes);
   2175         __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) );
   2176         __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) );
   2177         __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) );
   2178         __ cfc1(t0, FCSR);
   2179         __ ctc1(t1, FCSR);
   2180         __ li(t2, 0x0);
   2181         __ mtc1(t2, f12);
   2182         __ mtc1(t2, f10);
   2183         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold)) );
   2184         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold)) );
   2185         __ movt_s(f12, f4, test.cc);
   2186         __ movt_d(f10, f2, test.cc);
   2187         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf)) );
   2188         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd)) );
   2189         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold1)) );
   2190         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold1)) );
   2191         __ movf_s(f12, f4, test.cc);
   2192         __ movf_d(f10, f2, test.cc);
   2193         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf1)) );
   2194         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd1)) );
   2195         __ ctc1(t0, FCSR);
   2196         __ jr(ra);
   2197         __ nop();
   2198 
   2199         CodeDesc desc;
   2200         assm.GetCode(&desc);
   2201         Handle<Code> code = isolate->factory()->NewCode(
   2202             desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2203         F3 f = FUNCTION_CAST<F3>(code->entry());
   2204 
   2205         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2206         CHECK_EQ(test.dstf, outputs_S[i]);
   2207         CHECK_EQ(test.dstd, outputs_D[i]);
   2208         CHECK_EQ(test.dstf1, test.dstfold1);
   2209         CHECK_EQ(test.dstd1, test.dstdold1);
   2210         test.fcsr = 0;
   2211         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2212         CHECK_EQ(test.dstf, test.dstfold);
   2213         CHECK_EQ(test.dstd, test.dstdold);
   2214         CHECK_EQ(test.dstf1, outputs_S[i]);
   2215         CHECK_EQ(test.dstd1, outputs_D[i]);
   2216       }
   2217     }
   2218   }
   2219 }
   2220 
   2221 
   2222 // ----------------------tests for all archs--------------------------
   2223 TEST(cvt_w_d) {
   2224   CcTest::InitializeVM();
   2225   Isolate* isolate = CcTest::i_isolate();
   2226   HandleScope scope(isolate);
   2227   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2228 
   2229   typedef struct test_float {
   2230     double a;
   2231     int32_t b;
   2232     int32_t fcsr;
   2233   }Test;
   2234   const int kTableLength = 24;
   2235   double inputs[kTableLength] = {
   2236       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2237       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2238       2147483637.0, 2147483638.0, 2147483639.0,
   2239       2147483640.0, 2147483641.0, 2147483642.0,
   2240       2147483643.0, 2147483644.0, 2147483645.0,
   2241       2147483646.0, 2147483647.0, 2147483653.0
   2242       };
   2243   double outputs_RN[kTableLength] = {
   2244       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2245       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2246       2147483637.0, 2147483638.0, 2147483639.0,
   2247       2147483640.0, 2147483641.0, 2147483642.0,
   2248       2147483643.0, 2147483644.0, 2147483645.0,
   2249       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2250   double outputs_RZ[kTableLength] = {
   2251       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2252       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2253       2147483637.0, 2147483638.0, 2147483639.0,
   2254       2147483640.0, 2147483641.0, 2147483642.0,
   2255       2147483643.0, 2147483644.0, 2147483645.0,
   2256       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2257   double outputs_RP[kTableLength] = {
   2258       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   2259       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2260       2147483637.0, 2147483638.0, 2147483639.0,
   2261       2147483640.0, 2147483641.0, 2147483642.0,
   2262       2147483643.0, 2147483644.0, 2147483645.0,
   2263       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2264   double outputs_RM[kTableLength] = {
   2265       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2266       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2267       2147483637.0, 2147483638.0, 2147483639.0,
   2268       2147483640.0, 2147483641.0, 2147483642.0,
   2269       2147483643.0, 2147483644.0, 2147483645.0,
   2270       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2271   int fcsr_inputs[4] =
   2272       {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
   2273   double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
   2274   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2275   __ lw(t0, MemOperand(a0, offsetof(Test, fcsr)) );
   2276   __ cfc1(t1, FCSR);
   2277   __ ctc1(t0, FCSR);
   2278   __ cvt_w_d(f8, f4);
   2279   __ swc1(f8, MemOperand(a0, offsetof(Test, b)) );
   2280   __ ctc1(t1, FCSR);
   2281   __ jr(ra);
   2282   __ nop();
   2283   Test test;
   2284   CodeDesc desc;
   2285   assm.GetCode(&desc);
   2286   Handle<Code> code = isolate->factory()->NewCode(
   2287       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2288   F3 f = FUNCTION_CAST<F3>(code->entry());
   2289   for (int j = 0; j < 4; j++) {
   2290     test.fcsr = fcsr_inputs[j];
   2291     for (int i = 0; i < kTableLength; i++) {
   2292       test.a = inputs[i];
   2293       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2294       CHECK_EQ(test.b, outputs[j][i]);
   2295     }
   2296   }
   2297 }
   2298 
   2299 
   2300 TEST(trunc_w) {
   2301   CcTest::InitializeVM();
   2302   Isolate* isolate = CcTest::i_isolate();
   2303   HandleScope scope(isolate);
   2304   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2305 
   2306   typedef struct test_float {
   2307     uint32_t isNaN2008;
   2308     double a;
   2309     float b;
   2310     int32_t c;  // a trunc result
   2311     int32_t d;  // b trunc result
   2312   }Test;
   2313   const int kTableLength = 15;
   2314   double inputs_D[kTableLength] = {
   2315       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2316       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2317       2147483648.0,
   2318       std::numeric_limits<double>::quiet_NaN(),
   2319       std::numeric_limits<double>::infinity()
   2320       };
   2321   float inputs_S[kTableLength] = {
   2322       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2323       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2324       2147483648.0,
   2325       std::numeric_limits<float>::quiet_NaN(),
   2326       std::numeric_limits<float>::infinity()
   2327       };
   2328   double outputs[kTableLength] = {
   2329       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2330       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2331       kFPUInvalidResult, kFPUInvalidResult,
   2332       kFPUInvalidResult};
   2333   double outputsNaN2008[kTableLength] = {
   2334       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2335       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2336       kFPUInvalidResult,
   2337       0,
   2338       kFPUInvalidResult};
   2339 
   2340   __ cfc1(t1, FCSR);
   2341   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2342   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2343   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2344   __ trunc_w_d(f8, f4);
   2345   __ trunc_w_s(f10, f6);
   2346   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2347   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2348   __ jr(ra);
   2349   __ nop();
   2350   Test test;
   2351   CodeDesc desc;
   2352   assm.GetCode(&desc);
   2353   Handle<Code> code = isolate->factory()->NewCode(
   2354       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2355   F3 f = FUNCTION_CAST<F3>(code->entry());
   2356   for (int i = 0; i < kTableLength; i++) {
   2357     test.a = inputs_D[i];
   2358     test.b = inputs_S[i];
   2359     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2360     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   2361       CHECK_EQ(test.c, outputsNaN2008[i]);
   2362     } else {
   2363       CHECK_EQ(test.c, outputs[i]);
   2364     }
   2365     CHECK_EQ(test.d, test.c);
   2366   }
   2367 }
   2368 
   2369 
   2370 TEST(round_w) {
   2371   CcTest::InitializeVM();
   2372   Isolate* isolate = CcTest::i_isolate();
   2373   HandleScope scope(isolate);
   2374   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2375 
   2376   typedef struct test_float {
   2377     uint32_t isNaN2008;
   2378     double a;
   2379     float b;
   2380     int32_t c;  // a trunc result
   2381     int32_t d;  // b trunc result
   2382   }Test;
   2383   const int kTableLength = 15;
   2384   double inputs_D[kTableLength] = {
   2385       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2386       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2387       2147483648.0,
   2388       std::numeric_limits<double>::quiet_NaN(),
   2389       std::numeric_limits<double>::infinity()
   2390       };
   2391   float inputs_S[kTableLength] = {
   2392       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2393       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2394       2147483648.0,
   2395       std::numeric_limits<float>::quiet_NaN(),
   2396       std::numeric_limits<float>::infinity()
   2397       };
   2398   double outputs[kTableLength] = {
   2399       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2400       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2401       kFPUInvalidResult, kFPUInvalidResult,
   2402       kFPUInvalidResult};
   2403   double outputsNaN2008[kTableLength] = {
   2404       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2405       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2406       kFPUInvalidResult, 0,
   2407       kFPUInvalidResult};
   2408 
   2409   __ cfc1(t1, FCSR);
   2410   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2411   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2412   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2413   __ round_w_d(f8, f4);
   2414   __ round_w_s(f10, f6);
   2415   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2416   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2417   __ jr(ra);
   2418   __ nop();
   2419   Test test;
   2420   CodeDesc desc;
   2421   assm.GetCode(&desc);
   2422   Handle<Code> code = isolate->factory()->NewCode(
   2423       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2424   F3 f = FUNCTION_CAST<F3>(code->entry());
   2425   for (int i = 0; i < kTableLength; i++) {
   2426     test.a = inputs_D[i];
   2427     test.b = inputs_S[i];
   2428     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2429     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   2430       CHECK_EQ(test.c, outputsNaN2008[i]);
   2431     } else {
   2432       CHECK_EQ(test.c, outputs[i]);
   2433     }
   2434     CHECK_EQ(test.d, test.c);
   2435   }
   2436 }
   2437 
   2438 
   2439 TEST(round_l) {
   2440   if (IsFp64Mode()) {
   2441     CcTest::InitializeVM();
   2442     Isolate* isolate = CcTest::i_isolate();
   2443     HandleScope scope(isolate);
   2444     MacroAssembler assm(isolate, NULL, 0,
   2445                         v8::internal::CodeObjectRequired::kYes);
   2446     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   2447     typedef struct test_float {
   2448       uint32_t isNaN2008;
   2449       double a;
   2450       float b;
   2451       int64_t c;
   2452       int64_t d;
   2453     }Test;
   2454     const int kTableLength = 15;
   2455     double inputs_D[kTableLength] = {
   2456         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2457         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2458         2147483648.0,
   2459         std::numeric_limits<double>::quiet_NaN(),
   2460         std::numeric_limits<double>::infinity()
   2461         };
   2462     float inputs_S[kTableLength] = {
   2463         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2464         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2465         2147483648.0,
   2466         std::numeric_limits<float>::quiet_NaN(),
   2467         std::numeric_limits<float>::infinity()
   2468         };
   2469     double outputs[kTableLength] = {
   2470         2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2471         -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2472         2147483648.0, dFPU64InvalidResult,
   2473         dFPU64InvalidResult};
   2474     double outputsNaN2008[kTableLength] = {
   2475         2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2476         -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2477         2147483648.0,
   2478         0,
   2479         dFPU64InvalidResult};
   2480 
   2481     __ cfc1(t1, FCSR);
   2482     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2483     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2484     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2485     __ round_l_d(f8, f4);
   2486     __ round_l_s(f10, f6);
   2487     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2488     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2489     __ jr(ra);
   2490     __ nop();
   2491     Test test;
   2492     CodeDesc desc;
   2493     assm.GetCode(&desc);
   2494     Handle<Code> code = isolate->factory()->NewCode(
   2495         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2496     F3 f = FUNCTION_CAST<F3>(code->entry());
   2497     for (int i = 0; i < kTableLength; i++) {
   2498       test.a = inputs_D[i];
   2499       test.b = inputs_S[i];
   2500       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2501       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   2502               kArchVariant == kMips32r6) {
   2503         CHECK_EQ(test.c, outputsNaN2008[i]);
   2504       } else {
   2505         CHECK_EQ(test.c, outputs[i]);
   2506       }
   2507       CHECK_EQ(test.d, test.c);
   2508     }
   2509   }
   2510 }
   2511 
   2512 
   2513 TEST(sub) {
   2514   const int kTableLength = 12;
   2515   CcTest::InitializeVM();
   2516   Isolate* isolate = CcTest::i_isolate();
   2517   HandleScope scope(isolate);
   2518   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2519 
   2520   typedef struct test_float {
   2521     float a;
   2522     float b;
   2523     float resultS;
   2524     double c;
   2525     double d;
   2526     double resultD;
   2527   }TestFloat;
   2528 
   2529   TestFloat test;
   2530   double inputfs_D[kTableLength] = {
   2531     5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
   2532     5.3, 4.8, 2.9, -5.3, -4.8, -2.9
   2533   };
   2534   double inputft_D[kTableLength] = {
   2535     4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
   2536     -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
   2537   };
   2538   double outputs_D[kTableLength] = {
   2539     0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
   2540     10.1, 10.1, 5.8, -0.5, 0.5, 0.0
   2541   };
   2542   float inputfs_S[kTableLength] = {
   2543     5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
   2544     5.3, 4.8, 2.9, -5.3, -4.8, -2.9
   2545   };
   2546   float inputft_S[kTableLength] = {
   2547     4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
   2548     -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
   2549   };
   2550   float outputs_S[kTableLength] = {
   2551     0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
   2552     10.1, 10.1, 5.8, -0.5, 0.5, 0.0
   2553   };
   2554   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2555   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
   2556   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   2557   __ ldc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
   2558   __ sub_s(f6, f2, f4);
   2559   __ sub_d(f12, f8, f10);
   2560   __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2561   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2562   __ jr(ra);
   2563   __ nop();
   2564 
   2565   CodeDesc desc;
   2566   assm.GetCode(&desc);
   2567   Handle<Code> code = isolate->factory()->NewCode(
   2568       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2569   F3 f = FUNCTION_CAST<F3>(code->entry());
   2570   for (int i = 0; i < kTableLength; i++) {
   2571     test.a = inputfs_S[i];
   2572     test.b = inputft_S[i];
   2573     test.c = inputfs_D[i];
   2574     test.d = inputft_D[i];
   2575     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2576     CHECK_EQ(test.resultS, outputs_S[i]);
   2577     CHECK_EQ(test.resultD, outputs_D[i]);
   2578   }
   2579 }
   2580 
   2581 
   2582 TEST(sqrt_rsqrt_recip) {
   2583   const int kTableLength = 4;
   2584   const double deltaDouble = 2E-15;
   2585   const float deltaFloat = 2E-7;
   2586   const float sqrt2_s = sqrt(2);
   2587   const double sqrt2_d = sqrt(2);
   2588   CcTest::InitializeVM();
   2589   Isolate* isolate = CcTest::i_isolate();
   2590   HandleScope scope(isolate);
   2591   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2592 
   2593   typedef struct test_float {
   2594     float a;
   2595     float resultS;
   2596     float resultS1;
   2597     float resultS2;
   2598     double c;
   2599     double resultD;
   2600     double resultD1;
   2601     double resultD2;
   2602   }TestFloat;
   2603   TestFloat test;
   2604 
   2605   double inputs_D[kTableLength] = {
   2606     0.0L, 4.0L, 2.0L, 4e-28L
   2607   };
   2608 
   2609   double outputs_D[kTableLength] = {
   2610     0.0L, 2.0L, sqrt2_d, 2e-14L
   2611   };
   2612   float inputs_S[kTableLength] = {
   2613     0.0, 4.0, 2.0, 4e-28
   2614   };
   2615 
   2616   float outputs_S[kTableLength] = {
   2617     0.0, 2.0, sqrt2_s, 2e-14
   2618   };
   2619 
   2620 
   2621   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2622   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   2623   __ sqrt_s(f6, f2);
   2624   __ sqrt_d(f12, f8);
   2625 
   2626   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
   2627     __ rsqrt_d(f14, f8);
   2628     __ rsqrt_s(f16, f2);
   2629     __ recip_d(f18, f8);
   2630     __ recip_s(f4, f2);
   2631   }
   2632   __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2633   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2634 
   2635   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
   2636     __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resultS1)) );
   2637     __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resultD1)) );
   2638     __ swc1(f4, MemOperand(a0, offsetof(TestFloat, resultS2)) );
   2639     __ sdc1(f18, MemOperand(a0, offsetof(TestFloat, resultD2)) );
   2640   }
   2641   __ jr(ra);
   2642   __ nop();
   2643 
   2644   CodeDesc desc;
   2645   assm.GetCode(&desc);
   2646   Handle<Code> code = isolate->factory()->NewCode(
   2647       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2648   F3 f = FUNCTION_CAST<F3>(code->entry());
   2649 
   2650   for (int i = 0; i < kTableLength; i++) {
   2651     float f1;
   2652     double d1;
   2653     test.a = inputs_S[i];
   2654     test.c = inputs_D[i];
   2655 
   2656     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2657 
   2658     CHECK_EQ(test.resultS, outputs_S[i]);
   2659     CHECK_EQ(test.resultD, outputs_D[i]);
   2660 
   2661     if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
   2662       if (i != 0) {
   2663         f1 = test.resultS1 - 1.0F/outputs_S[i];
   2664         f1 = (f1 < 0) ? f1 : -f1;
   2665         CHECK(f1 <= deltaFloat);
   2666         d1 = test.resultD1 - 1.0L/outputs_D[i];
   2667         d1 = (d1 < 0) ? d1 : -d1;
   2668         CHECK(d1 <= deltaDouble);
   2669         f1 = test.resultS2 - 1.0F/inputs_S[i];
   2670         f1 = (f1 < 0) ? f1 : -f1;
   2671         CHECK(f1 <= deltaFloat);
   2672         d1 = test.resultD2 - 1.0L/inputs_D[i];
   2673         d1 = (d1 < 0) ? d1 : -d1;
   2674         CHECK(d1 <= deltaDouble);
   2675       } else {
   2676         CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]);
   2677         CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]);
   2678         CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]);
   2679         CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]);
   2680       }
   2681     }
   2682   }
   2683 }
   2684 
   2685 
   2686 TEST(neg) {
   2687   const int kTableLength = 3;
   2688   CcTest::InitializeVM();
   2689   Isolate* isolate = CcTest::i_isolate();
   2690   HandleScope scope(isolate);
   2691   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2692 
   2693   typedef struct test_float {
   2694     float a;
   2695     float resultS;
   2696     double c;
   2697     double resultD;
   2698   }TestFloat;
   2699 
   2700   TestFloat test;
   2701   double inputs_D[kTableLength] = {
   2702     0.0, 4.0, -2.0
   2703   };
   2704 
   2705   double outputs_D[kTableLength] = {
   2706     0.0, -4.0, 2.0
   2707   };
   2708   float inputs_S[kTableLength] = {
   2709     0.0, 4.0, -2.0
   2710   };
   2711 
   2712   float outputs_S[kTableLength] = {
   2713     0.0, -4.0, 2.0
   2714   };
   2715   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2716   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   2717   __ neg_s(f6, f2);
   2718   __ neg_d(f12, f8);
   2719   __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2720   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2721   __ jr(ra);
   2722   __ nop();
   2723 
   2724   CodeDesc desc;
   2725   assm.GetCode(&desc);
   2726   Handle<Code> code = isolate->factory()->NewCode(
   2727       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2728   F3 f = FUNCTION_CAST<F3>(code->entry());
   2729   for (int i = 0; i < kTableLength; i++) {
   2730     test.a = inputs_S[i];
   2731     test.c = inputs_D[i];
   2732     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2733     CHECK_EQ(test.resultS, outputs_S[i]);
   2734     CHECK_EQ(test.resultD, outputs_D[i]);
   2735   }
   2736 }
   2737 
   2738 
   2739 TEST(mul) {
   2740   const int kTableLength = 4;
   2741   CcTest::InitializeVM();
   2742   Isolate* isolate = CcTest::i_isolate();
   2743   HandleScope scope(isolate);
   2744   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2745 
   2746   typedef struct test_float {
   2747     float a;
   2748     float b;
   2749     float resultS;
   2750     double c;
   2751     double d;
   2752     double resultD;
   2753   }TestFloat;
   2754 
   2755   TestFloat test;
   2756   double inputfs_D[kTableLength] = {
   2757     5.3, -5.3, 5.3, -2.9
   2758   };
   2759   double inputft_D[kTableLength] = {
   2760     4.8, 4.8, -4.8, -0.29
   2761   };
   2762 
   2763   float inputfs_S[kTableLength] = {
   2764     5.3, -5.3, 5.3, -2.9
   2765   };
   2766   float inputft_S[kTableLength] = {
   2767     4.8, 4.8, -4.8, -0.29
   2768   };
   2769 
   2770   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2771   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
   2772   __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
   2773   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
   2774   __ mul_s(f10, f2, f4);
   2775   __ mul_d(f12, f6, f8);
   2776   __ swc1(f10, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2777   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2778   __ jr(ra);
   2779   __ nop();
   2780 
   2781   CodeDesc desc;
   2782   assm.GetCode(&desc);
   2783   Handle<Code> code = isolate->factory()->NewCode(
   2784       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2785   F3 f = FUNCTION_CAST<F3>(code->entry());
   2786   for (int i = 0; i < kTableLength; i++) {
   2787     test.a = inputfs_S[i];
   2788     test.b = inputft_S[i];
   2789     test.c = inputfs_D[i];
   2790     test.d = inputft_D[i];
   2791     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2792     CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]);
   2793     CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]);
   2794   }
   2795 }
   2796 
   2797 
   2798 TEST(mov) {
   2799   const int kTableLength = 4;
   2800   CcTest::InitializeVM();
   2801   Isolate* isolate = CcTest::i_isolate();
   2802   HandleScope scope(isolate);
   2803   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2804 
   2805   typedef struct test_float {
   2806     double a;
   2807     double b;
   2808     float c;
   2809     float d;
   2810   }TestFloat;
   2811 
   2812   TestFloat test;
   2813   double inputs_D[kTableLength] = {
   2814     5.3, -5.3, 5.3, -2.9
   2815   };
   2816   double inputs_S[kTableLength] = {
   2817     4.8, 4.8, -4.8, -0.29
   2818   };
   2819 
   2820   float outputs_S[kTableLength] = {
   2821     4.8, 4.8, -4.8, -0.29
   2822   };
   2823   double outputs_D[kTableLength] = {
   2824     5.3, -5.3, 5.3, -2.9
   2825   };
   2826 
   2827   __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
   2828   __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
   2829   __ mov_s(f8, f6);
   2830   __ mov_d(f10, f4);
   2831   __ swc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
   2832   __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, b)) );
   2833 
   2834   __ jr(ra);
   2835   __ nop();
   2836 
   2837   CodeDesc desc;
   2838   assm.GetCode(&desc);
   2839   Handle<Code> code = isolate->factory()->NewCode(
   2840       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2841   F3 f = FUNCTION_CAST<F3>(code->entry());
   2842   for (int i = 0; i < kTableLength; i++) {
   2843     test.a = inputs_D[i];
   2844     test.c = inputs_S[i];
   2845 
   2846     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2847     CHECK_EQ(test.b, outputs_D[i]);
   2848     CHECK_EQ(test.d, outputs_S[i]);
   2849   }
   2850 }
   2851 
   2852 
   2853 TEST(floor_w) {
   2854   CcTest::InitializeVM();
   2855   Isolate* isolate = CcTest::i_isolate();
   2856   HandleScope scope(isolate);
   2857   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2858 
   2859   typedef struct test_float {
   2860     uint32_t isNaN2008;
   2861     double a;
   2862     float b;
   2863     int32_t c;  // a floor result
   2864     int32_t d;  // b floor result
   2865   }Test;
   2866   const int kTableLength = 15;
   2867   double inputs_D[kTableLength] = {
   2868       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2869       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2870       2147483648.0,
   2871       std::numeric_limits<double>::quiet_NaN(),
   2872       std::numeric_limits<double>::infinity()
   2873       };
   2874   float inputs_S[kTableLength] = {
   2875       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2876       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2877       2147483648.0,
   2878       std::numeric_limits<float>::quiet_NaN(),
   2879       std::numeric_limits<float>::infinity()
   2880       };
   2881   double outputs[kTableLength] = {
   2882       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2883       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2884       kFPUInvalidResult, kFPUInvalidResult,
   2885       kFPUInvalidResult};
   2886   double outputsNaN2008[kTableLength] = {
   2887       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2888       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2889       kFPUInvalidResult,
   2890       0,
   2891       kFPUInvalidResult};
   2892 
   2893   __ cfc1(t1, FCSR);
   2894   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2895   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2896   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2897   __ floor_w_d(f8, f4);
   2898   __ floor_w_s(f10, f6);
   2899   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2900   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2901   __ jr(ra);
   2902   __ nop();
   2903   Test test;
   2904   CodeDesc desc;
   2905   assm.GetCode(&desc);
   2906   Handle<Code> code = isolate->factory()->NewCode(
   2907       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2908   F3 f = FUNCTION_CAST<F3>(code->entry());
   2909   for (int i = 0; i < kTableLength; i++) {
   2910     test.a = inputs_D[i];
   2911     test.b = inputs_S[i];
   2912     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2913     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   2914       CHECK_EQ(test.c, outputsNaN2008[i]);
   2915     } else {
   2916       CHECK_EQ(test.c, outputs[i]);
   2917     }
   2918     CHECK_EQ(test.d, test.c);
   2919   }
   2920 }
   2921 
   2922 
   2923 TEST(floor_l) {
   2924   if (IsFp64Mode()) {
   2925     CcTest::InitializeVM();
   2926     Isolate* isolate = CcTest::i_isolate();
   2927     HandleScope scope(isolate);
   2928     MacroAssembler assm(isolate, NULL, 0,
   2929                         v8::internal::CodeObjectRequired::kYes);
   2930     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   2931     typedef struct test_float {
   2932       uint32_t isNaN2008;
   2933       double a;
   2934       float b;
   2935       int64_t c;
   2936       int64_t d;
   2937     }Test;
   2938     const int kTableLength = 15;
   2939     double inputs_D[kTableLength] = {
   2940         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2941         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2942         2147483648.0,
   2943         std::numeric_limits<double>::quiet_NaN(),
   2944         std::numeric_limits<double>::infinity()
   2945         };
   2946     float inputs_S[kTableLength] = {
   2947         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2948         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2949         2147483648.0,
   2950         std::numeric_limits<float>::quiet_NaN(),
   2951         std::numeric_limits<float>::infinity()
   2952         };
   2953     double outputs[kTableLength] = {
   2954         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2955         -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2956         2147483648.0, dFPU64InvalidResult,
   2957         dFPU64InvalidResult};
   2958     double outputsNaN2008[kTableLength] = {
   2959         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2960         -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2961         2147483648.0,
   2962         0,
   2963         dFPU64InvalidResult};
   2964 
   2965     __ cfc1(t1, FCSR);
   2966     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2967     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2968     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2969     __ floor_l_d(f8, f4);
   2970     __ floor_l_s(f10, f6);
   2971     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2972     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2973     __ jr(ra);
   2974     __ nop();
   2975     Test test;
   2976     CodeDesc desc;
   2977     assm.GetCode(&desc);
   2978     Handle<Code> code = isolate->factory()->NewCode(
   2979         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2980     F3 f = FUNCTION_CAST<F3>(code->entry());
   2981     for (int i = 0; i < kTableLength; i++) {
   2982       test.a = inputs_D[i];
   2983       test.b = inputs_S[i];
   2984       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2985       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   2986               kArchVariant == kMips32r6) {
   2987         CHECK_EQ(test.c, outputsNaN2008[i]);
   2988       } else {
   2989         CHECK_EQ(test.c, outputs[i]);
   2990       }
   2991       CHECK_EQ(test.d, test.c);
   2992     }
   2993   }
   2994 }
   2995 
   2996 
   2997 TEST(ceil_w) {
   2998   CcTest::InitializeVM();
   2999   Isolate* isolate = CcTest::i_isolate();
   3000   HandleScope scope(isolate);
   3001   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   3002 
   3003   typedef struct test_float {
   3004     uint32_t isNaN2008;
   3005     double a;
   3006     float b;
   3007     int32_t c;  // a floor result
   3008     int32_t d;  // b floor result
   3009   }Test;
   3010   const int kTableLength = 15;
   3011   double inputs_D[kTableLength] = {
   3012       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3013       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3014       2147483648.0,
   3015       std::numeric_limits<double>::quiet_NaN(),
   3016       std::numeric_limits<double>::infinity()
   3017       };
   3018   float inputs_S[kTableLength] = {
   3019       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3020       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3021       2147483648.0,
   3022       std::numeric_limits<float>::quiet_NaN(),
   3023       std::numeric_limits<float>::infinity()
   3024       };
   3025   double outputs[kTableLength] = {
   3026       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3027       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3028       kFPUInvalidResult, kFPUInvalidResult,
   3029       kFPUInvalidResult};
   3030   double outputsNaN2008[kTableLength] = {
   3031       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3032       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3033       kFPUInvalidResult,
   3034       0,
   3035       kFPUInvalidResult};
   3036 
   3037   __ cfc1(t1, FCSR);
   3038   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   3039   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   3040   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   3041   __ ceil_w_d(f8, f4);
   3042   __ ceil_w_s(f10, f6);
   3043   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   3044   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   3045   __ jr(ra);
   3046   __ nop();
   3047   Test test;
   3048   CodeDesc desc;
   3049   assm.GetCode(&desc);
   3050   Handle<Code> code = isolate->factory()->NewCode(
   3051       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3052   F3 f = FUNCTION_CAST<F3>(code->entry());
   3053   for (int i = 0; i < kTableLength; i++) {
   3054     test.a = inputs_D[i];
   3055     test.b = inputs_S[i];
   3056     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3057     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   3058       CHECK_EQ(test.c, outputsNaN2008[i]);
   3059     } else {
   3060       CHECK_EQ(test.c, outputs[i]);
   3061     }
   3062     CHECK_EQ(test.d, test.c);
   3063   }
   3064 }
   3065 
   3066 
   3067 TEST(ceil_l) {
   3068   if (IsFp64Mode()) {
   3069     CcTest::InitializeVM();
   3070     Isolate* isolate = CcTest::i_isolate();
   3071     HandleScope scope(isolate);
   3072     MacroAssembler assm(isolate, NULL, 0,
   3073                         v8::internal::CodeObjectRequired::kYes);
   3074     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   3075     typedef struct test_float {
   3076       uint32_t isNaN2008;
   3077       double a;
   3078       float b;
   3079       int64_t c;
   3080       int64_t d;
   3081     }Test;
   3082     const int kTableLength = 15;
   3083     double inputs_D[kTableLength] = {
   3084         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3085         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3086         2147483648.0,
   3087         std::numeric_limits<double>::quiet_NaN(),
   3088         std::numeric_limits<double>::infinity()
   3089         };
   3090     float inputs_S[kTableLength] = {
   3091         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3092         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3093         2147483648.0,
   3094         std::numeric_limits<float>::quiet_NaN(),
   3095         std::numeric_limits<float>::infinity()
   3096         };
   3097     double outputs[kTableLength] = {
   3098         3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3099         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3100         2147483648.0, dFPU64InvalidResult,
   3101         dFPU64InvalidResult};
   3102     double outputsNaN2008[kTableLength] = {
   3103         3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3104         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3105         2147483648.0,
   3106         0,
   3107         dFPU64InvalidResult};
   3108 
   3109     __ cfc1(t1, FCSR);
   3110     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   3111     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   3112     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   3113     __ ceil_l_d(f8, f4);
   3114     __ ceil_l_s(f10, f6);
   3115     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   3116     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   3117     __ jr(ra);
   3118     __ nop();
   3119     Test test;
   3120     CodeDesc desc;
   3121     assm.GetCode(&desc);
   3122     Handle<Code> code = isolate->factory()->NewCode(
   3123         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3124     F3 f = FUNCTION_CAST<F3>(code->entry());
   3125     for (int i = 0; i < kTableLength; i++) {
   3126       test.a = inputs_D[i];
   3127       test.b = inputs_S[i];
   3128       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3129       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   3130               kArchVariant == kMips32r6) {
   3131         CHECK_EQ(test.c, outputsNaN2008[i]);
   3132       } else {
   3133         CHECK_EQ(test.c, outputs[i]);
   3134       }
   3135       CHECK_EQ(test.d, test.c);
   3136     }
   3137   }
   3138 }
   3139 
   3140 
   3141 TEST(jump_tables1) {
   3142   // Test jump tables with forward jumps.
   3143   CcTest::InitializeVM();
   3144   Isolate* isolate = CcTest::i_isolate();
   3145   HandleScope scope(isolate);
   3146   Assembler assm(isolate, nullptr, 0);
   3147 
   3148   const int kNumCases = 512;
   3149   int values[kNumCases];
   3150   isolate->random_number_generator()->NextBytes(values, sizeof(values));
   3151   Label labels[kNumCases];
   3152 
   3153   __ addiu(sp, sp, -4);
   3154   __ sw(ra, MemOperand(sp));
   3155 
   3156   Label done;
   3157   {
   3158     __ BlockTrampolinePoolFor(kNumCases + 7);
   3159     PredictableCodeSizeScope predictable(
   3160         &assm, (kNumCases + 7) * Assembler::kInstrSize);
   3161     Label here;
   3162 
   3163     __ bal(&here);
   3164     __ nop();
   3165     __ bind(&here);
   3166     __ sll(at, a0, 2);
   3167     __ addu(at, at, ra);
   3168     __ lw(at, MemOperand(at, 5 * Assembler::kInstrSize));
   3169     __ jr(at);
   3170     __ nop();
   3171     for (int i = 0; i < kNumCases; ++i) {
   3172       __ dd(&labels[i]);
   3173     }
   3174   }
   3175 
   3176   for (int i = 0; i < kNumCases; ++i) {
   3177     __ bind(&labels[i]);
   3178     __ lui(v0, (values[i] >> 16) & 0xffff);
   3179     __ ori(v0, v0, values[i] & 0xffff);
   3180     __ b(&done);
   3181     __ nop();
   3182   }
   3183 
   3184   __ bind(&done);
   3185   __ lw(ra, MemOperand(sp));
   3186   __ addiu(sp, sp, 4);
   3187   __ jr(ra);
   3188   __ nop();
   3189 
   3190   CodeDesc desc;
   3191   assm.GetCode(&desc);
   3192   Handle<Code> code = isolate->factory()->NewCode(
   3193       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3194 #ifdef OBJECT_PRINT
   3195   code->Print(std::cout);
   3196 #endif
   3197   F1 f = FUNCTION_CAST<F1>(code->entry());
   3198   for (int i = 0; i < kNumCases; ++i) {
   3199     int res = reinterpret_cast<int>(
   3200         CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
   3201     ::printf("f(%d) = %d\n", i, res);
   3202     CHECK_EQ(values[i], res);
   3203   }
   3204 }
   3205 
   3206 
   3207 TEST(jump_tables2) {
   3208   // Test jump tables with backward jumps.
   3209   CcTest::InitializeVM();
   3210   Isolate* isolate = CcTest::i_isolate();
   3211   HandleScope scope(isolate);
   3212   Assembler assm(isolate, nullptr, 0);
   3213 
   3214   const int kNumCases = 512;
   3215   int values[kNumCases];
   3216   isolate->random_number_generator()->NextBytes(values, sizeof(values));
   3217   Label labels[kNumCases];
   3218 
   3219   __ addiu(sp, sp, -4);
   3220   __ sw(ra, MemOperand(sp));
   3221 
   3222   Label done, dispatch;
   3223   __ b(&dispatch);
   3224   __ nop();
   3225 
   3226   for (int i = 0; i < kNumCases; ++i) {
   3227     __ bind(&labels[i]);
   3228     __ lui(v0, (values[i] >> 16) & 0xffff);
   3229     __ ori(v0, v0, values[i] & 0xffff);
   3230     __ b(&done);
   3231     __ nop();
   3232   }
   3233 
   3234   __ bind(&dispatch);
   3235   {
   3236     __ BlockTrampolinePoolFor(kNumCases + 7);
   3237     PredictableCodeSizeScope predictable(
   3238         &assm, (kNumCases + 7) * Assembler::kInstrSize);
   3239     Label here;
   3240 
   3241     __ bal(&here);
   3242     __ nop();
   3243     __ bind(&here);
   3244     __ sll(at, a0, 2);
   3245     __ addu(at, at, ra);
   3246     __ lw(at, MemOperand(at, 5 * Assembler::kInstrSize));
   3247     __ jr(at);
   3248     __ nop();
   3249     for (int i = 0; i < kNumCases; ++i) {
   3250       __ dd(&labels[i]);
   3251     }
   3252   }
   3253 
   3254   __ bind(&done);
   3255   __ lw(ra, MemOperand(sp));
   3256   __ addiu(sp, sp, 4);
   3257   __ jr(ra);
   3258   __ nop();
   3259 
   3260   CodeDesc desc;
   3261   assm.GetCode(&desc);
   3262   Handle<Code> code = isolate->factory()->NewCode(
   3263       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3264 #ifdef OBJECT_PRINT
   3265   code->Print(std::cout);
   3266 #endif
   3267   F1 f = FUNCTION_CAST<F1>(code->entry());
   3268   for (int i = 0; i < kNumCases; ++i) {
   3269     int res = reinterpret_cast<int>(
   3270         CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
   3271     ::printf("f(%d) = %d\n", i, res);
   3272     CHECK_EQ(values[i], res);
   3273   }
   3274 }
   3275 
   3276 
   3277 TEST(jump_tables3) {
   3278   // Test jump tables with backward jumps and embedded heap objects.
   3279   CcTest::InitializeVM();
   3280   Isolate* isolate = CcTest::i_isolate();
   3281   HandleScope scope(isolate);
   3282   Assembler assm(isolate, nullptr, 0);
   3283 
   3284   const int kNumCases = 256;
   3285   Handle<Object> values[kNumCases];
   3286   for (int i = 0; i < kNumCases; ++i) {
   3287     double value = isolate->random_number_generator()->NextDouble();
   3288     values[i] = isolate->factory()->NewHeapNumber(value, IMMUTABLE, TENURED);
   3289   }
   3290   Label labels[kNumCases];
   3291   Object* obj;
   3292   int32_t imm32;
   3293 
   3294   __ addiu(sp, sp, -4);
   3295   __ sw(ra, MemOperand(sp));
   3296 
   3297   Label done, dispatch;
   3298   __ b(&dispatch);
   3299 
   3300 
   3301   for (int i = 0; i < kNumCases; ++i) {
   3302     __ bind(&labels[i]);
   3303     obj = *values[i];
   3304     imm32 = reinterpret_cast<intptr_t>(obj);
   3305     __ lui(v0, (imm32 >> 16) & 0xffff);
   3306     __ ori(v0, v0, imm32 & 0xffff);
   3307     __ b(&done);
   3308     __ nop();
   3309   }
   3310 
   3311   __ bind(&dispatch);
   3312   {
   3313     __ BlockTrampolinePoolFor(kNumCases + 7);
   3314     PredictableCodeSizeScope predictable(
   3315         &assm, (kNumCases + 7) * Assembler::kInstrSize);
   3316     Label here;
   3317 
   3318     __ bal(&here);
   3319     __ nop();
   3320     __ bind(&here);
   3321     __ sll(at, a0, 2);
   3322     __ addu(at, at, ra);
   3323     __ lw(at, MemOperand(at, 5 * Assembler::kInstrSize));
   3324     __ jr(at);
   3325     __ nop();
   3326     for (int i = 0; i < kNumCases; ++i) {
   3327       __ dd(&labels[i]);
   3328     }
   3329   }
   3330 
   3331   __ bind(&done);
   3332   __ lw(ra, MemOperand(sp));
   3333   __ addiu(sp, sp, 4);
   3334   __ jr(ra);
   3335   __ nop();
   3336 
   3337   CodeDesc desc;
   3338   assm.GetCode(&desc);
   3339   Handle<Code> code = isolate->factory()->NewCode(
   3340       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3341 #ifdef OBJECT_PRINT
   3342   code->Print(std::cout);
   3343 #endif
   3344   F1 f = FUNCTION_CAST<F1>(code->entry());
   3345   for (int i = 0; i < kNumCases; ++i) {
   3346     Handle<Object> result(
   3347         CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0), isolate);
   3348 #ifdef OBJECT_PRINT
   3349     ::printf("f(%d) = ", i);
   3350     result->Print(std::cout);
   3351     ::printf("\n");
   3352 #endif
   3353     CHECK(values[i].is_identical_to(result));
   3354   }
   3355 }
   3356 
   3357 
   3358 TEST(BITSWAP) {
   3359   // Test BITSWAP
   3360   if (IsMipsArchVariant(kMips32r6)) {
   3361     CcTest::InitializeVM();
   3362     Isolate* isolate = CcTest::i_isolate();
   3363     HandleScope scope(isolate);
   3364 
   3365     typedef struct {
   3366       int32_t r1;
   3367       int32_t r2;
   3368       int32_t r3;
   3369       int32_t r4;
   3370     } T;
   3371     T t;
   3372 
   3373     Assembler assm(isolate, NULL, 0);
   3374 
   3375     __ lw(a2, MemOperand(a0, offsetof(T, r1)));
   3376     __ nop();
   3377     __ bitswap(a1, a2);
   3378     __ sw(a1, MemOperand(a0, offsetof(T, r1)));
   3379 
   3380     __ lw(a2, MemOperand(a0, offsetof(T, r2)));
   3381     __ nop();
   3382     __ bitswap(a1, a2);
   3383     __ sw(a1, MemOperand(a0, offsetof(T, r2)));
   3384 
   3385     __ jr(ra);
   3386     __ nop();
   3387 
   3388     CodeDesc desc;
   3389     assm.GetCode(&desc);
   3390     Handle<Code> code = isolate->factory()->NewCode(
   3391         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3392     F3 f = FUNCTION_CAST<F3>(code->entry());
   3393     t.r1 = 0x781A15C3;
   3394     t.r2 = 0x8B71FCDE;
   3395     Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   3396     USE(dummy);
   3397 
   3398     CHECK_EQ(static_cast<int32_t>(0x1E58A8C3), t.r1);
   3399     CHECK_EQ(static_cast<int32_t>(0xD18E3F7B), t.r2);
   3400   }
   3401 }
   3402 
   3403 
   3404 TEST(class_fmt) {
   3405   if (IsMipsArchVariant(kMips32r6)) {
   3406     // Test CLASS.fmt instruction.
   3407     CcTest::InitializeVM();
   3408     Isolate* isolate = CcTest::i_isolate();
   3409     HandleScope scope(isolate);
   3410 
   3411     typedef struct {
   3412       double dSignalingNan;
   3413       double dQuietNan;
   3414       double dNegInf;
   3415       double dNegNorm;
   3416       double dNegSubnorm;
   3417       double dNegZero;
   3418       double dPosInf;
   3419       double dPosNorm;
   3420       double dPosSubnorm;
   3421       double dPosZero;
   3422       float  fSignalingNan;
   3423       float  fQuietNan;
   3424       float  fNegInf;
   3425       float  fNegNorm;
   3426       float  fNegSubnorm;
   3427       float  fNegZero;
   3428       float  fPosInf;
   3429       float  fPosNorm;
   3430       float  fPosSubnorm;
   3431       float  fPosZero;  } T;
   3432     T t;
   3433 
   3434     // Create a function that accepts &t, and loads, manipulates, and stores
   3435     // the doubles t.a ... t.f.
   3436     MacroAssembler assm(isolate, NULL, 0,
   3437                         v8::internal::CodeObjectRequired::kYes);
   3438 
   3439     __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan)));
   3440     __ class_d(f6, f4);
   3441     __ sdc1(f6, MemOperand(a0, offsetof(T, dSignalingNan)));
   3442 
   3443     __ ldc1(f4, MemOperand(a0, offsetof(T, dQuietNan)));
   3444     __ class_d(f6, f4);
   3445     __ sdc1(f6, MemOperand(a0, offsetof(T, dQuietNan)));
   3446 
   3447     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegInf)));
   3448     __ class_d(f6, f4);
   3449     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegInf)));
   3450 
   3451     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegNorm)));
   3452     __ class_d(f6, f4);
   3453     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegNorm)));
   3454 
   3455     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegSubnorm)));
   3456     __ class_d(f6, f4);
   3457     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegSubnorm)));
   3458 
   3459     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegZero)));
   3460     __ class_d(f6, f4);
   3461     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegZero)));
   3462 
   3463     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosInf)));
   3464     __ class_d(f6, f4);
   3465     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosInf)));
   3466 
   3467     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosNorm)));
   3468     __ class_d(f6, f4);
   3469     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosNorm)));
   3470 
   3471     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosSubnorm)));
   3472     __ class_d(f6, f4);
   3473     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosSubnorm)));
   3474 
   3475     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosZero)));
   3476     __ class_d(f6, f4);
   3477     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosZero)));
   3478 
   3479     // Testing instruction CLASS.S
   3480     __ lwc1(f4, MemOperand(a0, offsetof(T, fSignalingNan)));
   3481     __ class_s(f6, f4);
   3482     __ swc1(f6, MemOperand(a0, offsetof(T, fSignalingNan)));
   3483 
   3484     __ lwc1(f4, MemOperand(a0, offsetof(T, fQuietNan)));
   3485     __ class_s(f6, f4);
   3486     __ swc1(f6, MemOperand(a0, offsetof(T, fQuietNan)));
   3487 
   3488     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegInf)));
   3489     __ class_s(f6, f4);
   3490     __ swc1(f6, MemOperand(a0, offsetof(T, fNegInf)));
   3491 
   3492     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegNorm)));
   3493     __ class_s(f6, f4);
   3494     __ swc1(f6, MemOperand(a0, offsetof(T, fNegNorm)));
   3495 
   3496     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegSubnorm)));
   3497     __ class_s(f6, f4);
   3498     __ swc1(f6, MemOperand(a0, offsetof(T, fNegSubnorm)));
   3499 
   3500     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegZero)));
   3501     __ class_s(f6, f4);
   3502     __ swc1(f6, MemOperand(a0, offsetof(T, fNegZero)));
   3503 
   3504     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosInf)));
   3505     __ class_s(f6, f4);
   3506     __ swc1(f6, MemOperand(a0, offsetof(T, fPosInf)));
   3507 
   3508     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosNorm)));
   3509     __ class_s(f6, f4);
   3510     __ swc1(f6, MemOperand(a0, offsetof(T, fPosNorm)));
   3511 
   3512     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosSubnorm)));
   3513     __ class_s(f6, f4);
   3514     __ swc1(f6, MemOperand(a0, offsetof(T, fPosSubnorm)));
   3515 
   3516     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosZero)));
   3517     __ class_s(f6, f4);
   3518     __ swc1(f6, MemOperand(a0, offsetof(T, fPosZero)));
   3519 
   3520     __ jr(ra);
   3521     __ nop();
   3522 
   3523     CodeDesc desc;
   3524     assm.GetCode(&desc);
   3525     Handle<Code> code = isolate->factory()->NewCode(
   3526         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3527     F3 f = FUNCTION_CAST<F3>(code->entry());
   3528 
   3529     t.dSignalingNan =  std::numeric_limits<double>::signaling_NaN();
   3530     t.dQuietNan = std::numeric_limits<double>::quiet_NaN();
   3531     t.dNegInf       = -1.0 / 0.0;
   3532     t.dNegNorm      = -5.0;
   3533     t.dNegSubnorm   = -DBL_MIN / 2.0;
   3534     t.dNegZero      = -0.0;
   3535     t.dPosInf       = 2.0 / 0.0;
   3536     t.dPosNorm      = 275.35;
   3537     t.dPosSubnorm   = DBL_MIN / 2.0;
   3538     t.dPosZero      = +0.0;
   3539     // Float test values
   3540 
   3541     t.fSignalingNan = std::numeric_limits<float>::signaling_NaN();
   3542     t.fQuietNan     = std::numeric_limits<float>::quiet_NaN();
   3543     t.fNegInf       = -0.5/0.0;
   3544     t.fNegNorm      = -FLT_MIN;
   3545     t.fNegSubnorm   = -FLT_MIN / 1.5;
   3546     t.fNegZero      = -0.0;
   3547     t.fPosInf       = 100000.0 / 0.0;
   3548     t.fPosNorm      = FLT_MAX;
   3549     t.fPosSubnorm   = FLT_MIN / 20.0;
   3550     t.fPosZero      = +0.0;
   3551 
   3552     Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   3553     USE(dummy);
   3554     // Expected double results.
   3555     CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001);
   3556     CHECK_EQ(bit_cast<int64_t>(t.dQuietNan),     0x002);
   3557     CHECK_EQ(bit_cast<int64_t>(t.dNegInf),       0x004);
   3558     CHECK_EQ(bit_cast<int64_t>(t.dNegNorm),      0x008);
   3559     CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm),   0x010);
   3560     CHECK_EQ(bit_cast<int64_t>(t.dNegZero),      0x020);
   3561     CHECK_EQ(bit_cast<int64_t>(t.dPosInf),       0x040);
   3562     CHECK_EQ(bit_cast<int64_t>(t.dPosNorm),      0x080);
   3563     CHECK_EQ(bit_cast<int64_t>(t.dPosSubnorm),   0x100);
   3564     CHECK_EQ(bit_cast<int64_t>(t.dPosZero),      0x200);
   3565 
   3566     // Expected float results.
   3567     CHECK_EQ(bit_cast<int32_t>(t.fSignalingNan), 0x001);
   3568     CHECK_EQ(bit_cast<int32_t>(t.fQuietNan),     0x002);
   3569     CHECK_EQ(bit_cast<int32_t>(t.fNegInf),       0x004);
   3570     CHECK_EQ(bit_cast<int32_t>(t.fNegNorm),      0x008);
   3571     CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm),   0x010);
   3572     CHECK_EQ(bit_cast<int32_t>(t.fNegZero),      0x020);
   3573     CHECK_EQ(bit_cast<int32_t>(t.fPosInf),       0x040);
   3574     CHECK_EQ(bit_cast<int32_t>(t.fPosNorm),      0x080);
   3575     CHECK_EQ(bit_cast<int32_t>(t.fPosSubnorm),   0x100);
   3576     CHECK_EQ(bit_cast<int32_t>(t.fPosZero),      0x200);
   3577   }
   3578 }
   3579 
   3580 
   3581 TEST(ABS) {
   3582   CcTest::InitializeVM();
   3583   Isolate* isolate = CcTest::i_isolate();
   3584   HandleScope scope(isolate);
   3585   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   3586 
   3587   typedef struct test_float {
   3588     int64_t fir;
   3589     double a;
   3590     float b;
   3591     double fcsr;
   3592   } TestFloat;
   3593 
   3594   TestFloat test;
   3595 
   3596   // Save FIR.
   3597   __ cfc1(a1, FCSR);
   3598   // Disable FPU exceptions.
   3599   __ ctc1(zero_reg, FCSR);
   3600 
   3601   __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
   3602   __ abs_d(f10, f4);
   3603   __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, a)));
   3604 
   3605   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)));
   3606   __ abs_s(f10, f4);
   3607   __ swc1(f10, MemOperand(a0, offsetof(TestFloat, b)));
   3608 
   3609   // Restore FCSR.
   3610   __ ctc1(a1, FCSR);
   3611 
   3612   __ jr(ra);
   3613   __ nop();
   3614 
   3615   CodeDesc desc;
   3616   assm.GetCode(&desc);
   3617   Handle<Code> code = isolate->factory()->NewCode(
   3618       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3619   F3 f = FUNCTION_CAST<F3>(code->entry());
   3620   test.a = -2.0;
   3621   test.b = -2.0;
   3622   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3623   CHECK_EQ(test.a, 2.0);
   3624   CHECK_EQ(test.b, 2.0);
   3625 
   3626   test.a = 2.0;
   3627   test.b = 2.0;
   3628   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3629   CHECK_EQ(test.a, 2.0);
   3630   CHECK_EQ(test.b, 2.0);
   3631 
   3632   // Testing biggest positive number
   3633   test.a = std::numeric_limits<double>::max();
   3634   test.b = std::numeric_limits<float>::max();
   3635   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3636   CHECK_EQ(test.a, std::numeric_limits<double>::max());
   3637   CHECK_EQ(test.b, std::numeric_limits<float>::max());
   3638 
   3639   // Testing smallest negative number
   3640   test.a = -std::numeric_limits<double>::max();  // lowest()
   3641   test.b = -std::numeric_limits<float>::max();   // lowest()
   3642   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3643   CHECK_EQ(test.a, std::numeric_limits<double>::max());
   3644   CHECK_EQ(test.b, std::numeric_limits<float>::max());
   3645 
   3646   // Testing smallest positive number
   3647   test.a = -std::numeric_limits<double>::min();
   3648   test.b = -std::numeric_limits<float>::min();
   3649   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3650   CHECK_EQ(test.a, std::numeric_limits<double>::min());
   3651   CHECK_EQ(test.b, std::numeric_limits<float>::min());
   3652 
   3653   // Testing infinity
   3654   test.a = -std::numeric_limits<double>::max()
   3655           / std::numeric_limits<double>::min();
   3656   test.b = -std::numeric_limits<float>::max()
   3657           / std::numeric_limits<float>::min();
   3658   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3659   CHECK_EQ(test.a, std::numeric_limits<double>::max()
   3660                  / std::numeric_limits<double>::min());
   3661   CHECK_EQ(test.b, std::numeric_limits<float>::max()
   3662                  / std::numeric_limits<float>::min());
   3663 
   3664   test.a = std::numeric_limits<double>::quiet_NaN();
   3665   test.b = std::numeric_limits<float>::quiet_NaN();
   3666   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3667   CHECK_EQ(std::isnan(test.a), true);
   3668   CHECK_EQ(std::isnan(test.b), true);
   3669 
   3670   test.a = std::numeric_limits<double>::signaling_NaN();
   3671   test.b = std::numeric_limits<float>::signaling_NaN();
   3672   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3673   CHECK_EQ(std::isnan(test.a), true);
   3674   CHECK_EQ(std::isnan(test.b), true);
   3675 }
   3676 
   3677 
   3678 TEST(ADD_FMT) {
   3679   CcTest::InitializeVM();
   3680   Isolate* isolate = CcTest::i_isolate();
   3681   HandleScope scope(isolate);
   3682   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   3683 
   3684   typedef struct test_float {
   3685     double a;
   3686     double b;
   3687     double c;
   3688     float fa;
   3689     float fb;
   3690     float fc;
   3691   } TestFloat;
   3692 
   3693   TestFloat test;
   3694 
   3695   __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
   3696   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
   3697   __ add_d(f10, f8, f4);
   3698   __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
   3699 
   3700   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, fa)));
   3701   __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, fb)));
   3702   __ add_s(f10, f8, f4);
   3703   __ swc1(f10, MemOperand(a0, offsetof(TestFloat, fc)));
   3704 
   3705   __ jr(ra);
   3706   __ nop();
   3707 
   3708   CodeDesc desc;
   3709   assm.GetCode(&desc);
   3710   Handle<Code> code = isolate->factory()->NewCode(
   3711       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3712   F3 f = FUNCTION_CAST<F3>(code->entry());
   3713   test.a = 2.0;
   3714   test.b = 3.0;
   3715   test.fa = 2.0;
   3716   test.fb = 3.0;
   3717   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3718   CHECK_EQ(test.c, 5.0);
   3719   CHECK_EQ(test.fc, 5.0);
   3720 
   3721   test.a = std::numeric_limits<double>::max();
   3722   test.b = -std::numeric_limits<double>::max();  // lowest()
   3723   test.fa = std::numeric_limits<float>::max();
   3724   test.fb = -std::numeric_limits<float>::max();  // lowest()
   3725   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3726   CHECK_EQ(test.c, 0.0);
   3727   CHECK_EQ(test.fc, 0.0);
   3728 
   3729   test.a = std::numeric_limits<double>::max();
   3730   test.b = std::numeric_limits<double>::max();
   3731   test.fa = std::numeric_limits<float>::max();
   3732   test.fb = std::numeric_limits<float>::max();
   3733   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3734   CHECK_EQ(std::isfinite(test.c), false);
   3735   CHECK_EQ(std::isfinite(test.fc), false);
   3736 
   3737   test.a = 5.0;
   3738   test.b = std::numeric_limits<double>::signaling_NaN();
   3739   test.fa = 5.0;
   3740   test.fb = std::numeric_limits<float>::signaling_NaN();
   3741   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3742   CHECK_EQ(std::isnan(test.c), true);
   3743   CHECK_EQ(std::isnan(test.fc), true);
   3744 }
   3745 
   3746 
   3747 TEST(C_COND_FMT) {
   3748   if ((IsMipsArchVariant(kMips32r1)) || (IsMipsArchVariant(kMips32r2))) {
   3749     CcTest::InitializeVM();
   3750     Isolate* isolate = CcTest::i_isolate();
   3751     HandleScope scope(isolate);
   3752     MacroAssembler assm(isolate, NULL, 0,
   3753                         v8::internal::CodeObjectRequired::kYes);
   3754 
   3755     typedef struct test_float {
   3756       double dOp1;
   3757       double dOp2;
   3758       uint32_t dF;
   3759       uint32_t dUn;
   3760       uint32_t dEq;
   3761       uint32_t dUeq;
   3762       uint32_t dOlt;
   3763       uint32_t dUlt;
   3764       uint32_t dOle;
   3765       uint32_t dUle;
   3766       float fOp1;
   3767       float fOp2;
   3768       uint32_t fF;
   3769       uint32_t fUn;
   3770       uint32_t fEq;
   3771       uint32_t fUeq;
   3772       uint32_t fOlt;
   3773       uint32_t fUlt;
   3774       uint32_t fOle;
   3775       uint32_t fUle;
   3776     } TestFloat;
   3777 
   3778     TestFloat test;
   3779 
   3780     __ li(t1, 1);
   3781 
   3782     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
   3783     __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
   3784 
   3785     __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
   3786     __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
   3787 
   3788     __ mov(t2, zero_reg);
   3789     __ mov(t3, zero_reg);
   3790     __ c_d(F, f4, f6, 0);
   3791     __ c_s(F, f14, f16, 2);
   3792     __ movt(t2, t1, 0);
   3793     __ movt(t3, t1, 2);
   3794     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dF)) );
   3795     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fF)) );
   3796 
   3797     __ mov(t2, zero_reg);
   3798     __ mov(t3, zero_reg);
   3799     __ c_d(UN, f4, f6, 2);
   3800     __ c_s(UN, f14, f16, 4);
   3801     __ movt(t2, t1, 2);
   3802     __ movt(t3, t1, 4);
   3803     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUn)) );
   3804     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUn)) );
   3805 
   3806     __ mov(t2, zero_reg);
   3807     __ mov(t3, zero_reg);
   3808     __ c_d(EQ, f4, f6, 4);
   3809     __ c_s(EQ, f14, f16, 6);
   3810     __ movt(t2, t1, 4);
   3811     __ movt(t3, t1, 6);
   3812     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dEq)) );
   3813     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fEq)) );
   3814 
   3815     __ mov(t2, zero_reg);
   3816     __ mov(t3, zero_reg);
   3817     __ c_d(UEQ, f4, f6, 6);
   3818     __ c_s(UEQ, f14, f16, 0);
   3819     __ movt(t2, t1, 6);
   3820     __ movt(t3, t1, 0);
   3821     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
   3822     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUeq)) );
   3823 
   3824     __ mov(t2, zero_reg);
   3825     __ mov(t3, zero_reg);
   3826     __ c_d(OLT, f4, f6, 0);
   3827     __ c_s(OLT, f14, f16, 2);
   3828     __ movt(t2, t1, 0);
   3829     __ movt(t3, t1, 2);
   3830     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
   3831     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOlt)) );
   3832 
   3833     __ mov(t2, zero_reg);
   3834     __ mov(t3, zero_reg);
   3835     __ c_d(ULT, f4, f6, 2);
   3836     __ c_s(ULT, f14, f16, 4);
   3837     __ movt(t2, t1, 2);
   3838     __ movt(t3, t1, 4);
   3839     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
   3840     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUlt)) );
   3841 
   3842     __ mov(t2, zero_reg);
   3843     __ mov(t3, zero_reg);
   3844     __ c_d(OLE, f4, f6, 4);
   3845     __ c_s(OLE, f14, f16, 6);
   3846     __ movt(t2, t1, 4);
   3847     __ movt(t3, t1, 6);
   3848     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOle)) );
   3849     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOle)) );
   3850 
   3851     __ mov(t2, zero_reg);
   3852     __ mov(t3, zero_reg);
   3853     __ c_d(ULE, f4, f6, 6);
   3854     __ c_s(ULE, f14, f16, 0);
   3855     __ movt(t2, t1, 6);
   3856     __ movt(t3, t1, 0);
   3857     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUle)) );
   3858     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUle)) );
   3859 
   3860     __ jr(ra);
   3861     __ nop();
   3862 
   3863     CodeDesc desc;
   3864     assm.GetCode(&desc);
   3865     Handle<Code> code = isolate->factory()->NewCode(
   3866         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3867     F3 f = FUNCTION_CAST<F3>(code->entry());
   3868     test.dOp1 = 2.0;
   3869     test.dOp2 = 3.0;
   3870     test.fOp1 = 2.0;
   3871     test.fOp2 = 3.0;
   3872     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3873     CHECK_EQ(test.dF, 0U);
   3874     CHECK_EQ(test.dUn, 0U);
   3875     CHECK_EQ(test.dEq, 0U);
   3876     CHECK_EQ(test.dUeq, 0U);
   3877     CHECK_EQ(test.dOlt, 1U);
   3878     CHECK_EQ(test.dUlt, 1U);
   3879     CHECK_EQ(test.dOle, 1U);
   3880     CHECK_EQ(test.dUle, 1U);
   3881     CHECK_EQ(test.fF, 0U);
   3882     CHECK_EQ(test.fUn, 0U);
   3883     CHECK_EQ(test.fEq, 0U);
   3884     CHECK_EQ(test.fUeq, 0U);
   3885     CHECK_EQ(test.fOlt, 1U);
   3886     CHECK_EQ(test.fUlt, 1U);
   3887     CHECK_EQ(test.fOle, 1U);
   3888     CHECK_EQ(test.fUle, 1U);
   3889 
   3890     test.dOp1 = std::numeric_limits<double>::max();
   3891     test.dOp2 = std::numeric_limits<double>::min();
   3892     test.fOp1 = std::numeric_limits<float>::min();
   3893     test.fOp2 = -std::numeric_limits<float>::max();  // lowest()
   3894     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3895     CHECK_EQ(test.dF, 0U);
   3896     CHECK_EQ(test.dUn, 0U);
   3897     CHECK_EQ(test.dEq, 0U);
   3898     CHECK_EQ(test.dUeq, 0U);
   3899     CHECK_EQ(test.dOlt, 0U);
   3900     CHECK_EQ(test.dUlt, 0U);
   3901     CHECK_EQ(test.dOle, 0U);
   3902     CHECK_EQ(test.dUle, 0U);
   3903     CHECK_EQ(test.fF, 0U);
   3904     CHECK_EQ(test.fUn, 0U);
   3905     CHECK_EQ(test.fEq, 0U);
   3906     CHECK_EQ(test.fUeq, 0U);
   3907     CHECK_EQ(test.fOlt, 0U);
   3908     CHECK_EQ(test.fUlt, 0U);
   3909     CHECK_EQ(test.fOle, 0U);
   3910     CHECK_EQ(test.fUle, 0U);
   3911 
   3912     test.dOp1 = -std::numeric_limits<double>::max();  // lowest()
   3913     test.dOp2 = -std::numeric_limits<double>::max();  // lowest()
   3914     test.fOp1 = std::numeric_limits<float>::max();
   3915     test.fOp2 = std::numeric_limits<float>::max();
   3916     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3917     CHECK_EQ(test.dF, 0U);
   3918     CHECK_EQ(test.dUn, 0U);
   3919     CHECK_EQ(test.dEq, 1U);
   3920     CHECK_EQ(test.dUeq, 1U);
   3921     CHECK_EQ(test.dOlt, 0U);
   3922     CHECK_EQ(test.dUlt, 0U);
   3923     CHECK_EQ(test.dOle, 1U);
   3924     CHECK_EQ(test.dUle, 1U);
   3925     CHECK_EQ(test.fF, 0U);
   3926     CHECK_EQ(test.fUn, 0U);
   3927     CHECK_EQ(test.fEq, 1U);
   3928     CHECK_EQ(test.fUeq, 1U);
   3929     CHECK_EQ(test.fOlt, 0U);
   3930     CHECK_EQ(test.fUlt, 0U);
   3931     CHECK_EQ(test.fOle, 1U);
   3932     CHECK_EQ(test.fUle, 1U);
   3933 
   3934     test.dOp1 = std::numeric_limits<double>::quiet_NaN();
   3935     test.dOp2 = 0.0;
   3936     test.fOp1 = std::numeric_limits<float>::quiet_NaN();
   3937     test.fOp2 = 0.0;
   3938     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3939     CHECK_EQ(test.dF, 0U);
   3940     CHECK_EQ(test.dUn, 1U);
   3941     CHECK_EQ(test.dEq, 0U);
   3942     CHECK_EQ(test.dUeq, 1U);
   3943     CHECK_EQ(test.dOlt, 0U);
   3944     CHECK_EQ(test.dUlt, 1U);
   3945     CHECK_EQ(test.dOle, 0U);
   3946     CHECK_EQ(test.dUle, 1U);
   3947     CHECK_EQ(test.fF, 0U);
   3948     CHECK_EQ(test.fUn, 1U);
   3949     CHECK_EQ(test.fEq, 0U);
   3950     CHECK_EQ(test.fUeq, 1U);
   3951     CHECK_EQ(test.fOlt, 0U);
   3952     CHECK_EQ(test.fUlt, 1U);
   3953     CHECK_EQ(test.fOle, 0U);
   3954     CHECK_EQ(test.fUle, 1U);
   3955   }
   3956 }
   3957 
   3958 
   3959 TEST(CMP_COND_FMT) {
   3960   if (IsMipsArchVariant(kMips32r6)) {
   3961     CcTest::InitializeVM();
   3962     Isolate* isolate = CcTest::i_isolate();
   3963     HandleScope scope(isolate);
   3964     MacroAssembler assm(isolate, NULL, 0,
   3965                         v8::internal::CodeObjectRequired::kYes);
   3966 
   3967     typedef struct test_float {
   3968       double dOp1;
   3969       double dOp2;
   3970       double dF;
   3971       double dUn;
   3972       double dEq;
   3973       double dUeq;
   3974       double dOlt;
   3975       double dUlt;
   3976       double dOle;
   3977       double dUle;
   3978       double dOr;
   3979       double dUne;
   3980       double dNe;
   3981       float fOp1;
   3982       float fOp2;
   3983       float fF;
   3984       float fUn;
   3985       float fEq;
   3986       float fUeq;
   3987       float fOlt;
   3988       float fUlt;
   3989       float fOle;
   3990       float fUle;
   3991       float fOr;
   3992       float fUne;
   3993       float fNe;
   3994     } TestFloat;
   3995 
   3996     TestFloat test;
   3997 
   3998     __ li(t1, 1);
   3999 
   4000     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
   4001     __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
   4002 
   4003     __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
   4004     __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
   4005 
   4006     __ cmp_d(F, f2, f4, f6);
   4007     __ cmp_s(F, f12, f14, f16);
   4008     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dF)) );
   4009     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fF)) );
   4010 
   4011     __ cmp_d(UN, f2, f4, f6);
   4012     __ cmp_s(UN, f12, f14, f16);
   4013     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUn)) );
   4014     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUn)) );
   4015 
   4016     __ cmp_d(EQ, f2, f4, f6);
   4017     __ cmp_s(EQ, f12, f14, f16);
   4018     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dEq)) );
   4019     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fEq)) );
   4020 
   4021     __ cmp_d(UEQ, f2, f4, f6);
   4022     __ cmp_s(UEQ, f12, f14, f16);
   4023     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
   4024     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUeq)) );
   4025 
   4026     __ cmp_d(LT, f2, f4, f6);
   4027     __ cmp_s(LT, f12, f14, f16);
   4028     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
   4029     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOlt)) );
   4030 
   4031     __ cmp_d(ULT, f2, f4, f6);
   4032     __ cmp_s(ULT, f12, f14, f16);
   4033     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
   4034     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUlt)) );
   4035 
   4036     __ cmp_d(LE, f2, f4, f6);
   4037     __ cmp_s(LE, f12, f14, f16);
   4038     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOle)) );
   4039     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOle)) );
   4040 
   4041     __ cmp_d(ULE, f2, f4, f6);
   4042     __ cmp_s(ULE, f12, f14, f16);
   4043     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUle)) );
   4044     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUle)) );
   4045 
   4046     __ cmp_d(ORD, f2, f4, f6);
   4047     __ cmp_s(ORD, f12, f14, f16);
   4048     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOr)) );
   4049     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOr)) );
   4050 
   4051     __ cmp_d(UNE, f2, f4, f6);
   4052     __ cmp_s(UNE, f12, f14, f16);
   4053     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUne)) );
   4054     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUne)) );
   4055 
   4056     __ cmp_d(NE, f2, f4, f6);
   4057     __ cmp_s(NE, f12, f14, f16);
   4058     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dNe)) );
   4059     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fNe)) );
   4060 
   4061     __ jr(ra);
   4062     __ nop();
   4063 
   4064     CodeDesc desc;
   4065     assm.GetCode(&desc);
   4066     Handle<Code> code = isolate->factory()->NewCode(
   4067         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4068     F3 f = FUNCTION_CAST<F3>(code->entry());
   4069     uint64_t dTrue  = 0xFFFFFFFFFFFFFFFF;
   4070     uint64_t dFalse = 0x0000000000000000;
   4071     uint32_t fTrue  = 0xFFFFFFFF;
   4072     uint32_t fFalse = 0x00000000;
   4073 
   4074     test.dOp1 = 2.0;
   4075     test.dOp2 = 3.0;
   4076     test.fOp1 = 2.0;
   4077     test.fOp2 = 3.0;
   4078     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4079     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4080     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
   4081     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
   4082     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
   4083     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue);
   4084     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
   4085     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
   4086     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
   4087     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
   4088     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
   4089     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
   4090     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4091     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
   4092     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
   4093     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
   4094     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue);
   4095     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
   4096     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
   4097     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
   4098 
   4099     test.dOp1 = std::numeric_limits<double>::max();
   4100     test.dOp2 = std::numeric_limits<double>::min();
   4101     test.fOp1 = std::numeric_limits<float>::min();
   4102     test.fOp2 = -std::numeric_limits<float>::max();  // lowest()
   4103     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4104     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4105     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
   4106     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
   4107     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
   4108     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
   4109     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
   4110     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
   4111     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse);
   4112     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
   4113     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
   4114     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
   4115     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4116     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
   4117     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
   4118     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
   4119     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
   4120     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
   4121     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
   4122     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse);
   4123 
   4124     test.dOp1 = -std::numeric_limits<double>::max();  // lowest()
   4125     test.dOp2 = -std::numeric_limits<double>::max();  // lowest()
   4126     test.fOp1 = std::numeric_limits<float>::max();
   4127     test.fOp2 = std::numeric_limits<float>::max();
   4128     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4129     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4130     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
   4131     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue);
   4132     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
   4133     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
   4134     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
   4135     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
   4136     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
   4137     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
   4138     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse);
   4139     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
   4140     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4141     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
   4142     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue);
   4143     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
   4144     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
   4145     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
   4146     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
   4147     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
   4148 
   4149     test.dOp1 = std::numeric_limits<double>::quiet_NaN();
   4150     test.dOp2 = 0.0;
   4151     test.fOp1 = std::numeric_limits<float>::quiet_NaN();
   4152     test.fOp2 = 0.0;
   4153     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4154     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4155     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue);
   4156     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
   4157     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
   4158     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
   4159     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
   4160     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
   4161     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
   4162     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse);
   4163     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
   4164     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
   4165     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4166     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue);
   4167     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
   4168     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
   4169     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
   4170     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
   4171     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
   4172     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
   4173   }
   4174 }
   4175 
   4176 
   4177 TEST(CVT) {
   4178   CcTest::InitializeVM();
   4179   Isolate* isolate = CcTest::i_isolate();
   4180   HandleScope scope(isolate);
   4181   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4182 
   4183   typedef struct test_float {
   4184     float    cvt_d_s_in;
   4185     double   cvt_d_s_out;
   4186     int32_t  cvt_d_w_in;
   4187     double   cvt_d_w_out;
   4188     int64_t  cvt_d_l_in;
   4189     double   cvt_d_l_out;
   4190 
   4191     float    cvt_l_s_in;
   4192     int64_t  cvt_l_s_out;
   4193     double   cvt_l_d_in;
   4194     int64_t  cvt_l_d_out;
   4195 
   4196     double   cvt_s_d_in;
   4197     float    cvt_s_d_out;
   4198     int32_t  cvt_s_w_in;
   4199     float    cvt_s_w_out;
   4200     int64_t  cvt_s_l_in;
   4201     float    cvt_s_l_out;
   4202 
   4203     float    cvt_w_s_in;
   4204     int32_t  cvt_w_s_out;
   4205     double   cvt_w_d_in;
   4206     int32_t  cvt_w_d_out;
   4207   } TestFloat;
   4208 
   4209   TestFloat test;
   4210 
   4211   // Save FCSR.
   4212   __ cfc1(a1, FCSR);
   4213   // Disable FPU exceptions.
   4214   __ ctc1(zero_reg, FCSR);
   4215 
   4216 #define GENERATE_CVT_TEST(x, y, z) \
   4217   __ y##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_in))); \
   4218   __ x(f0, f0); \
   4219   __ nop(); \
   4220   __ z##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_out)));
   4221 
   4222   GENERATE_CVT_TEST(cvt_d_s, lw, sd)
   4223   GENERATE_CVT_TEST(cvt_d_w, lw, sd)
   4224   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4225          IsFp64Mode()) {
   4226     GENERATE_CVT_TEST(cvt_d_l, ld, sd)
   4227   }
   4228 
   4229   if (IsFp64Mode()) {
   4230     GENERATE_CVT_TEST(cvt_l_s, lw, sd)
   4231     GENERATE_CVT_TEST(cvt_l_d, ld, sd)
   4232   }
   4233 
   4234   GENERATE_CVT_TEST(cvt_s_d, ld, sw)
   4235   GENERATE_CVT_TEST(cvt_s_w, lw, sw)
   4236   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4237          IsFp64Mode()) {
   4238     GENERATE_CVT_TEST(cvt_s_l, ld, sw)
   4239   }
   4240 
   4241   GENERATE_CVT_TEST(cvt_w_s, lw, sw)
   4242   GENERATE_CVT_TEST(cvt_w_d, ld, sw)
   4243 
   4244   // Restore FCSR.
   4245   __ ctc1(a1, FCSR);
   4246 
   4247   __ jr(ra);
   4248   __ nop();
   4249 
   4250   CodeDesc desc;
   4251   assm.GetCode(&desc);
   4252   Handle<Code> code = isolate->factory()->NewCode(
   4253       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4254   F3 f = FUNCTION_CAST<F3>(code->entry());
   4255 
   4256   test.cvt_d_s_in = -0.51;
   4257   test.cvt_d_w_in = -1;
   4258   test.cvt_d_l_in = -1;
   4259   test.cvt_l_s_in = -0.51;
   4260   test.cvt_l_d_in = -0.51;
   4261   test.cvt_s_d_in = -0.51;
   4262   test.cvt_s_w_in = -1;
   4263   test.cvt_s_l_in = -1;
   4264   test.cvt_w_s_in = -0.51;
   4265   test.cvt_w_d_in = -0.51;
   4266 
   4267   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4268   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4269   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4270   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4271          IsFp64Mode()) {
   4272     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4273   }
   4274   if (IsFp64Mode()) {
   4275     CHECK_EQ(test.cvt_l_s_out, -1);
   4276     CHECK_EQ(test.cvt_l_d_out, -1);
   4277   }
   4278   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4279   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4280   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4281          IsFp64Mode()) {
   4282     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4283   }
   4284   CHECK_EQ(test.cvt_w_s_out, -1);
   4285   CHECK_EQ(test.cvt_w_d_out, -1);
   4286 
   4287 
   4288   test.cvt_d_s_in = 0.49;
   4289   test.cvt_d_w_in = 1;
   4290   test.cvt_d_l_in = 1;
   4291   test.cvt_l_s_in = 0.49;
   4292   test.cvt_l_d_in = 0.49;
   4293   test.cvt_s_d_in = 0.49;
   4294   test.cvt_s_w_in = 1;
   4295   test.cvt_s_l_in = 1;
   4296   test.cvt_w_s_in = 0.49;
   4297   test.cvt_w_d_in = 0.49;
   4298 
   4299   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4300   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4301   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4302   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4303          IsFp64Mode()) {
   4304     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4305   }
   4306   if (IsFp64Mode()) {
   4307     CHECK_EQ(test.cvt_l_s_out, 0);
   4308     CHECK_EQ(test.cvt_l_d_out, 0);
   4309   }
   4310   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4311   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4312   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4313          IsFp64Mode()) {
   4314     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4315   }
   4316   CHECK_EQ(test.cvt_w_s_out, 0);
   4317   CHECK_EQ(test.cvt_w_d_out, 0);
   4318 
   4319   test.cvt_d_s_in = std::numeric_limits<float>::max();
   4320   test.cvt_d_w_in = std::numeric_limits<int32_t>::max();
   4321   test.cvt_d_l_in = std::numeric_limits<int64_t>::max();
   4322   test.cvt_l_s_in = std::numeric_limits<float>::max();
   4323   test.cvt_l_d_in = std::numeric_limits<double>::max();
   4324   test.cvt_s_d_in = std::numeric_limits<double>::max();
   4325   test.cvt_s_w_in = std::numeric_limits<int32_t>::max();
   4326   test.cvt_s_l_in = std::numeric_limits<int64_t>::max();
   4327   test.cvt_w_s_in = std::numeric_limits<float>::max();
   4328   test.cvt_w_d_in = std::numeric_limits<double>::max();
   4329 
   4330   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4331   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4332   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4333   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4334          IsFp64Mode()) {
   4335     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4336   }
   4337   if (IsFp64Mode()) {
   4338     CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max());
   4339     CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max());
   4340   }
   4341   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4342   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4343   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4344          IsFp64Mode()) {
   4345     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4346   }
   4347   CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max());
   4348   CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max());
   4349 
   4350 
   4351   test.cvt_d_s_in = -std::numeric_limits<float>::max();   // lowest()
   4352   test.cvt_d_w_in = std::numeric_limits<int32_t>::min();  // lowest()
   4353   test.cvt_d_l_in = std::numeric_limits<int64_t>::min();  // lowest()
   4354   test.cvt_l_s_in = -std::numeric_limits<float>::max();   // lowest()
   4355   test.cvt_l_d_in = -std::numeric_limits<double>::max();  // lowest()
   4356   test.cvt_s_d_in = -std::numeric_limits<double>::max();  // lowest()
   4357   test.cvt_s_w_in = std::numeric_limits<int32_t>::min();  // lowest()
   4358   test.cvt_s_l_in = std::numeric_limits<int64_t>::min();  // lowest()
   4359   test.cvt_w_s_in = -std::numeric_limits<float>::max();   // lowest()
   4360   test.cvt_w_d_in = -std::numeric_limits<double>::max();  // lowest()
   4361 
   4362   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4363   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4364   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4365   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4366          IsFp64Mode()) {
   4367     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4368   }
   4369   // The returned value when converting from fixed-point to float-point
   4370   // is not consistent between board, simulator and specification
   4371   // in this test case, therefore modifying the test
   4372   if (IsFp64Mode()) {
   4373     CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() ||
   4374          test.cvt_l_s_out == std::numeric_limits<int64_t>::max());
   4375     CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() ||
   4376           test.cvt_l_d_out == std::numeric_limits<int64_t>::max());
   4377   }
   4378   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4379   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4380   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4381          IsFp64Mode()) {
   4382     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4383   }
   4384   CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() ||
   4385         test.cvt_w_s_out == std::numeric_limits<int32_t>::max());
   4386   CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() ||
   4387         test.cvt_w_d_out == std::numeric_limits<int32_t>::max());
   4388 
   4389 
   4390   test.cvt_d_s_in = std::numeric_limits<float>::min();
   4391   test.cvt_d_w_in = std::numeric_limits<int32_t>::min();
   4392   test.cvt_d_l_in = std::numeric_limits<int64_t>::min();
   4393   test.cvt_l_s_in = std::numeric_limits<float>::min();
   4394   test.cvt_l_d_in = std::numeric_limits<double>::min();
   4395   test.cvt_s_d_in = std::numeric_limits<double>::min();
   4396   test.cvt_s_w_in = std::numeric_limits<int32_t>::min();
   4397   test.cvt_s_l_in = std::numeric_limits<int64_t>::min();
   4398   test.cvt_w_s_in = std::numeric_limits<float>::min();
   4399   test.cvt_w_d_in = std::numeric_limits<double>::min();
   4400 
   4401   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4402   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4403   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4404   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4405          IsFp64Mode()) {
   4406     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4407   }
   4408   if (IsFp64Mode()) {
   4409     CHECK_EQ(test.cvt_l_s_out, 0);
   4410     CHECK_EQ(test.cvt_l_d_out, 0);
   4411   }
   4412   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4413   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4414   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4415          IsFp64Mode()) {
   4416     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4417   }
   4418   CHECK_EQ(test.cvt_w_s_out, 0);
   4419   CHECK_EQ(test.cvt_w_d_out, 0);
   4420 }
   4421 
   4422 
   4423 TEST(DIV_FMT) {
   4424   CcTest::InitializeVM();
   4425   Isolate* isolate = CcTest::i_isolate();
   4426   HandleScope scope(isolate);
   4427   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4428 
   4429   typedef struct test {
   4430     double dOp1;
   4431     double dOp2;
   4432     double dRes;
   4433     float  fOp1;
   4434     float  fOp2;
   4435     float  fRes;
   4436   } Test;
   4437 
   4438   Test test;
   4439 
   4440   // Save FCSR.
   4441   __ cfc1(a1, FCSR);
   4442   // Disable FPU exceptions.
   4443   __ ctc1(zero_reg, FCSR);
   4444 
   4445   __ ldc1(f4, MemOperand(a0, offsetof(Test, dOp1)) );
   4446   __ ldc1(f2, MemOperand(a0, offsetof(Test, dOp2)) );
   4447   __ nop();
   4448   __ div_d(f6, f4, f2);
   4449   __ sdc1(f6, MemOperand(a0, offsetof(Test, dRes)) );
   4450 
   4451   __ lwc1(f4, MemOperand(a0, offsetof(Test, fOp1)) );
   4452   __ lwc1(f2, MemOperand(a0, offsetof(Test, fOp2)) );
   4453   __ nop();
   4454   __ div_s(f6, f4, f2);
   4455   __ swc1(f6, MemOperand(a0, offsetof(Test, fRes)) );
   4456 
   4457     // Restore FCSR.
   4458   __ ctc1(a1, FCSR);
   4459 
   4460   __ jr(ra);
   4461   __ nop();
   4462 
   4463   CodeDesc desc;
   4464   assm.GetCode(&desc);
   4465   Handle<Code> code = isolate->factory()->NewCode(
   4466       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4467 
   4468   F3 f = FUNCTION_CAST<F3>(code->entry());
   4469 
   4470   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4471 
   4472   const int test_size = 3;
   4473 
   4474   double dOp1[test_size] = {
   4475     5.0,
   4476     DBL_MAX,
   4477     DBL_MAX,
   4478   };
   4479   double dOp2[test_size] = {
   4480     2.0,
   4481     2.0,
   4482     -DBL_MAX,
   4483   };
   4484   double dRes[test_size] = {
   4485     2.5,
   4486     DBL_MAX / 2.0,
   4487     -1.0,
   4488   };
   4489   float fOp1[test_size] = {
   4490     5.0,
   4491     FLT_MAX,
   4492     FLT_MAX,
   4493   };
   4494   float fOp2[test_size] = {
   4495     2.0,
   4496     2.0,
   4497     -FLT_MAX,
   4498   };
   4499   float fRes[test_size] = {
   4500     2.5,
   4501     FLT_MAX / 2.0,
   4502     -1.0,
   4503   };
   4504 
   4505   for (int i = 0; i < test_size; i++) {
   4506     test.dOp1 = dOp1[i];
   4507     test.dOp2 = dOp2[i];
   4508     test.fOp1 = fOp1[i];
   4509     test.fOp2 = fOp2[i];
   4510 
   4511     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4512     CHECK_EQ(test.dRes, dRes[i]);
   4513     CHECK_EQ(test.fRes, fRes[i]);
   4514   }
   4515 
   4516   test.dOp1 = DBL_MAX;
   4517   test.dOp2 = -0.0;
   4518   test.fOp1 = FLT_MAX;
   4519   test.fOp2 = -0.0;
   4520 
   4521   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4522   CHECK_EQ(false, std::isfinite(test.dRes));
   4523   CHECK_EQ(false, std::isfinite(test.fRes));
   4524 
   4525   test.dOp1 = 0.0;
   4526   test.dOp2 = -0.0;
   4527   test.fOp1 = 0.0;
   4528   test.fOp2 = -0.0;
   4529 
   4530   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4531   CHECK_EQ(true, std::isnan(test.dRes));
   4532   CHECK_EQ(true, std::isnan(test.fRes));
   4533 
   4534   test.dOp1 = std::numeric_limits<double>::quiet_NaN();
   4535   test.dOp2 = -5.0;
   4536   test.fOp1 = std::numeric_limits<float>::quiet_NaN();
   4537   test.fOp2 = -5.0;
   4538 
   4539   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4540   CHECK_EQ(true, std::isnan(test.dRes));
   4541   CHECK_EQ(true, std::isnan(test.fRes));
   4542 }
   4543 
   4544 
   4545 uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) {
   4546   Isolate* isolate = CcTest::i_isolate();
   4547   HandleScope scope(isolate);
   4548 
   4549   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4550 
   4551   __ align(v0, a0, a1, bp);
   4552   __ jr(ra);
   4553   __ nop();
   4554 
   4555   CodeDesc desc;
   4556   assm.GetCode(&desc);
   4557   Handle<Code> code = isolate->factory()->NewCode(
   4558       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4559 
   4560   F2 f = FUNCTION_CAST<F2>(code->entry());
   4561 
   4562   uint32_t res = reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(
   4563       isolate, f, rs_value, rt_value, 0, 0, 0));
   4564 
   4565   return res;
   4566 }
   4567 
   4568 
   4569 TEST(r6_align) {
   4570   if (IsMipsArchVariant(kMips32r6)) {
   4571     CcTest::InitializeVM();
   4572 
   4573     struct TestCaseAlign {
   4574       uint32_t  rs_value;
   4575       uint32_t  rt_value;
   4576       uint8_t   bp;
   4577       uint32_t  expected_res;
   4578     };
   4579 
   4580     struct TestCaseAlign tc[] = {
   4581       // rs_value,    rt_value,    bp,  expected_res
   4582       { 0x11223344,   0xaabbccdd,   0,  0xaabbccdd },
   4583       { 0x11223344,   0xaabbccdd,   1,  0xbbccdd11 },
   4584       { 0x11223344,   0xaabbccdd,   2,  0xccdd1122 },
   4585       { 0x11223344,   0xaabbccdd,   3,  0xdd112233 },
   4586     };
   4587 
   4588     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign);
   4589     for (size_t i = 0; i < nr_test_cases; ++i) {
   4590       CHECK_EQ(tc[i].expected_res, run_align(tc[i].rs_value,
   4591                                              tc[i].rt_value, tc[i].bp));
   4592     }
   4593   }
   4594 }
   4595 
   4596 uint32_t PC;  // The program counter.
   4597 
   4598 uint32_t run_aluipc(int16_t offset) {
   4599   Isolate* isolate = CcTest::i_isolate();
   4600   HandleScope scope(isolate);
   4601 
   4602   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4603 
   4604   __ aluipc(v0, offset);
   4605   __ jr(ra);
   4606   __ nop();
   4607 
   4608   CodeDesc desc;
   4609   assm.GetCode(&desc);
   4610   Handle<Code> code = isolate->factory()->NewCode(
   4611       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4612 
   4613   F2 f = FUNCTION_CAST<F2>(code->entry());
   4614   PC = (uint32_t) f;  // Set the program counter.
   4615 
   4616   uint32_t res = reinterpret_cast<uint32_t>(
   4617       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4618 
   4619   return res;
   4620 }
   4621 
   4622 
   4623 TEST(r6_aluipc) {
   4624   if (IsMipsArchVariant(kMips32r6)) {
   4625     CcTest::InitializeVM();
   4626 
   4627     struct TestCaseAluipc {
   4628       int16_t   offset;
   4629     };
   4630 
   4631     struct TestCaseAluipc tc[] = {
   4632       // offset
   4633       { -32768 },   // 0x8000
   4634       {     -1 },   // 0xFFFF
   4635       {      0 },
   4636       {      1 },
   4637       {  32767 },   // 0x7FFF
   4638     };
   4639 
   4640     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
   4641     for (size_t i = 0; i < nr_test_cases; ++i) {
   4642       PC = 0;
   4643       uint32_t res = run_aluipc(tc[i].offset);
   4644       // Now, the program_counter (PC) is set.
   4645       uint32_t expected_res = ~0x0FFFF & (PC + (tc[i].offset << 16));
   4646       CHECK_EQ(expected_res, res);
   4647     }
   4648   }
   4649 }
   4650 
   4651 
   4652 uint32_t run_auipc(int16_t offset) {
   4653   Isolate* isolate = CcTest::i_isolate();
   4654   HandleScope scope(isolate);
   4655 
   4656   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4657 
   4658   __ auipc(v0, offset);
   4659   __ jr(ra);
   4660   __ nop();
   4661 
   4662   CodeDesc desc;
   4663   assm.GetCode(&desc);
   4664   Handle<Code> code = isolate->factory()->NewCode(
   4665       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4666 
   4667   F2 f = FUNCTION_CAST<F2>(code->entry());
   4668   PC = (uint32_t) f;  // Set the program counter.
   4669 
   4670   uint32_t res = reinterpret_cast<uint32_t>(
   4671       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4672 
   4673   return res;
   4674 }
   4675 
   4676 
   4677 TEST(r6_auipc) {
   4678   if (IsMipsArchVariant(kMips32r6)) {
   4679     CcTest::InitializeVM();
   4680 
   4681     struct TestCaseAuipc {
   4682       int16_t   offset;
   4683     };
   4684 
   4685     struct TestCaseAuipc tc[] = {
   4686       // offset
   4687       { -32768 },   // 0x8000
   4688       {     -1 },   // 0xFFFF
   4689       {      0 },
   4690       {      1 },
   4691       {  32767 },   // 0x7FFF
   4692     };
   4693 
   4694     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
   4695     for (size_t i = 0; i < nr_test_cases; ++i) {
   4696       PC = 0;
   4697       uint32_t res = run_auipc(tc[i].offset);
   4698       // Now, the program_counter (PC) is set.
   4699       uint32_t expected_res = PC + (tc[i].offset << 16);
   4700       CHECK_EQ(expected_res, res);
   4701     }
   4702   }
   4703 }
   4704 
   4705 
   4706 uint32_t run_lwpc(int offset) {
   4707   Isolate* isolate = CcTest::i_isolate();
   4708   HandleScope scope(isolate);
   4709 
   4710   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4711 
   4712   // 256k instructions; 2^8k
   4713   // addiu t7, t0, 0xffff;  (0x250fffff)
   4714   // ...
   4715   // addiu t4, t0, 0x0000;  (0x250c0000)
   4716   uint32_t addiu_start_1 = 0x25000000;
   4717   for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
   4718     uint32_t addiu_new = addiu_start_1 + i;
   4719     __ dd(addiu_new);
   4720   }
   4721 
   4722   __ lwpc(t8, offset);         // offset 0; 0xef080000 (t8 register)
   4723   __ mov(v0, t8);
   4724 
   4725   // 256k instructions; 2^8k
   4726   // addiu t0, t0, 0x0000;  (0x25080000)
   4727   // ...
   4728   // addiu t3, t0, 0xffff;  (0x250bffff)
   4729   uint32_t addiu_start_2 = 0x25000000;
   4730   for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
   4731     uint32_t addiu_new = addiu_start_2 + i;
   4732     __ dd(addiu_new);
   4733   }
   4734 
   4735   __ jr(ra);
   4736   __ nop();
   4737 
   4738   CodeDesc desc;
   4739   assm.GetCode(&desc);
   4740   Handle<Code> code = isolate->factory()->NewCode(
   4741       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4742 
   4743   F2 f = FUNCTION_CAST<F2>(code->entry());
   4744 
   4745   uint32_t res = reinterpret_cast<uint32_t>(
   4746       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4747 
   4748   return res;
   4749 }
   4750 
   4751 
   4752 TEST(r6_lwpc) {
   4753   if (IsMipsArchVariant(kMips32r6)) {
   4754     CcTest::InitializeVM();
   4755 
   4756     struct TestCaseLwpc {
   4757       int      offset;
   4758       uint32_t expected_res;
   4759     };
   4760 
   4761     struct TestCaseLwpc tc[] = {
   4762       // offset,   expected_res
   4763       { -262144,    0x250fffff },   // offset 0x40000
   4764       {      -4,    0x250c0003 },
   4765       {      -1,    0x250c0000 },
   4766       {       0,    0xef080000 },
   4767       {       1,    0x03001025 },   // mov(v0, t8)
   4768       {       2,    0x25080000 },
   4769       {       4,    0x25080002 },
   4770       {  262143,    0x250bfffd },   // offset 0x3ffff
   4771     };
   4772 
   4773     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
   4774     for (size_t i = 0; i < nr_test_cases; ++i) {
   4775       uint32_t res = run_lwpc(tc[i].offset);
   4776       CHECK_EQ(tc[i].expected_res, res);
   4777     }
   4778   }
   4779 }
   4780 
   4781 
   4782 uint32_t run_jic(int16_t offset) {
   4783   Isolate* isolate = CcTest::i_isolate();
   4784   HandleScope scope(isolate);
   4785 
   4786   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4787 
   4788   Label get_program_counter, stop_execution;
   4789   __ push(ra);
   4790   __ li(v0, 0);
   4791   __ li(t1, 0x66);
   4792 
   4793   __ addiu(v0, v0, 0x1);        // <-- offset = -32
   4794   __ addiu(v0, v0, 0x2);
   4795   __ addiu(v0, v0, 0x10);
   4796   __ addiu(v0, v0, 0x20);
   4797   __ beq(v0, t1, &stop_execution);
   4798   __ nop();
   4799 
   4800   __ bal(&get_program_counter);  // t0 <- program counter
   4801   __ nop();
   4802   __ jic(t0, offset);
   4803 
   4804   __ addiu(v0, v0, 0x100);
   4805   __ addiu(v0, v0, 0x200);
   4806   __ addiu(v0, v0, 0x1000);
   4807   __ addiu(v0, v0, 0x2000);   // <--- offset = 16
   4808   __ pop(ra);
   4809   __ jr(ra);
   4810   __ nop();
   4811 
   4812   __ bind(&get_program_counter);
   4813   __ mov(t0, ra);
   4814   __ jr(ra);
   4815   __ nop();
   4816 
   4817   __ bind(&stop_execution);
   4818   __ pop(ra);
   4819   __ jr(ra);
   4820   __ nop();
   4821 
   4822   CodeDesc desc;
   4823   assm.GetCode(&desc);
   4824   Handle<Code> code = isolate->factory()->NewCode(
   4825       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4826 
   4827   F2 f = FUNCTION_CAST<F2>(code->entry());
   4828 
   4829   uint32_t res = reinterpret_cast<uint32_t>(
   4830       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4831 
   4832   return res;
   4833 }
   4834 
   4835 
   4836 TEST(r6_jic) {
   4837   if (IsMipsArchVariant(kMips32r6)) {
   4838     CcTest::InitializeVM();
   4839 
   4840     struct TestCaseJic {
   4841       // As rt will be used t0 register which will have value of
   4842       // the program counter for the jic instruction.
   4843       int16_t   offset;
   4844       uint32_t  expected_res;
   4845     };
   4846 
   4847     struct TestCaseJic tc[] = {
   4848       // offset,   expected_result
   4849       {      16,            0x2033 },
   4850       {       4,            0x3333 },
   4851       {     -32,              0x66 },
   4852     };
   4853 
   4854     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
   4855     for (size_t i = 0; i < nr_test_cases; ++i) {
   4856       uint32_t res = run_jic(tc[i].offset);
   4857       CHECK_EQ(tc[i].expected_res, res);
   4858     }
   4859   }
   4860 }
   4861 
   4862 
   4863 uint64_t run_beqzc(int32_t value, int32_t offset) {
   4864   Isolate* isolate = CcTest::i_isolate();
   4865   HandleScope scope(isolate);
   4866 
   4867   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4868 
   4869   Label stop_execution;
   4870   __ li(v0, 0);
   4871   __ li(t1, 0x66);
   4872 
   4873   __ addiu(v0, v0, 0x1);        // <-- offset = -32
   4874   __ addiu(v0, v0, 0x2);
   4875   __ addiu(v0, v0, 0x10);
   4876   __ addiu(v0, v0, 0x20);
   4877   __ beq(v0, t1, &stop_execution);
   4878   __ nop();
   4879 
   4880   __ beqzc(a0, offset);         // BEQZC rs, offset
   4881 
   4882   __ addiu(v0, v0,    0x1);
   4883   __ addiu(v0, v0,  0x100);
   4884   __ addiu(v0, v0,  0x200);
   4885   __ addiu(v0, v0, 0x1000);
   4886   __ addiu(v0, v0, 0x2000);   // <--- offset = 16
   4887   __ jr(ra);
   4888   __ nop();
   4889 
   4890   __ bind(&stop_execution);
   4891   __ jr(ra);
   4892   __ nop();
   4893 
   4894   CodeDesc desc;
   4895   assm.GetCode(&desc);
   4896   Handle<Code> code = isolate->factory()->NewCode(
   4897       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4898 
   4899   F2 f = FUNCTION_CAST<F2>(code->entry());
   4900 
   4901   uint32_t res = reinterpret_cast<uint32_t>(
   4902       CALL_GENERATED_CODE(isolate, f, value, 0, 0, 0, 0));
   4903 
   4904   return res;
   4905 }
   4906 
   4907 
   4908 TEST(r6_beqzc) {
   4909   if (IsMipsArchVariant(kMips32r6)) {
   4910     CcTest::InitializeVM();
   4911 
   4912     struct TestCaseBeqzc {
   4913       uint32_t  value;
   4914       int32_t   offset;
   4915       uint32_t  expected_res;
   4916     };
   4917 
   4918     struct TestCaseBeqzc tc[] = {
   4919       //    value,    offset,   expected_res
   4920       {       0x0,        -8,           0x66 },
   4921       {       0x0,         0,         0x3334 },
   4922       {       0x0,         1,         0x3333 },
   4923       {     0xabc,         1,         0x3334 },
   4924       {       0x0,         4,         0x2033 },
   4925     };
   4926 
   4927     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
   4928     for (size_t i = 0; i < nr_test_cases; ++i) {
   4929       uint32_t res = run_beqzc(tc[i].value, tc[i].offset);
   4930       CHECK_EQ(tc[i].expected_res, res);
   4931     }
   4932   }
   4933 }
   4934 
   4935 
   4936 uint32_t run_jialc(int16_t offset) {
   4937   Isolate* isolate = CcTest::i_isolate();
   4938   HandleScope scope(isolate);
   4939 
   4940   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4941 
   4942   Label main_block, get_program_counter;
   4943   __ push(ra);
   4944   __ li(v0, 0);
   4945   __ beq(v0, v0, &main_block);
   4946   __ nop();
   4947 
   4948   // Block 1
   4949   __ addiu(v0, v0, 0x1);        // <-- offset = -40
   4950   __ addiu(v0, v0, 0x2);
   4951   __ jr(ra);
   4952   __ nop();
   4953 
   4954   // Block 2
   4955   __ addiu(v0, v0, 0x10);        // <-- offset = -24
   4956   __ addiu(v0, v0, 0x20);
   4957   __ jr(ra);
   4958   __ nop();
   4959 
   4960   // Block 3 (Main)
   4961   __ bind(&main_block);
   4962   __ bal(&get_program_counter);  // t0 <- program counter
   4963   __ nop();
   4964   __ jialc(t0, offset);
   4965   __ addiu(v0, v0, 0x4);
   4966   __ pop(ra);
   4967   __ jr(ra);
   4968   __ nop();
   4969 
   4970   // Block 4
   4971   __ addiu(v0, v0, 0x100);      // <-- offset = 20
   4972   __ addiu(v0, v0, 0x200);
   4973   __ jr(ra);
   4974   __ nop();
   4975 
   4976   // Block 5
   4977   __ addiu(v0, v0, 0x1000);     // <--- offset = 36
   4978   __ addiu(v0, v0, 0x2000);
   4979   __ jr(ra);
   4980   __ nop();
   4981 
   4982   __ bind(&get_program_counter);
   4983   __ mov(t0, ra);
   4984   __ jr(ra);
   4985   __ nop();
   4986 
   4987 
   4988   CodeDesc desc;
   4989   assm.GetCode(&desc);
   4990   Handle<Code> code = isolate->factory()->NewCode(
   4991       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4992 
   4993   F2 f = FUNCTION_CAST<F2>(code->entry());
   4994 
   4995   uint32_t res = reinterpret_cast<uint32_t>(
   4996       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4997 
   4998   return res;
   4999 }
   5000 
   5001 
   5002 TEST(r6_jialc) {
   5003   if (IsMipsArchVariant(kMips32r6)) {
   5004     CcTest::InitializeVM();
   5005 
   5006     struct TestCaseJialc {
   5007       int16_t   offset;
   5008       uint32_t  expected_res;
   5009     };
   5010 
   5011     struct TestCaseJialc tc[] = {
   5012       // offset,   expected_res
   5013       {     -40,            0x7 },
   5014       {     -24,           0x34 },
   5015       {      20,          0x304 },
   5016       {      36,         0x3004 }
   5017     };
   5018 
   5019     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
   5020     for (size_t i = 0; i < nr_test_cases; ++i) {
   5021       uint32_t res = run_jialc(tc[i].offset);
   5022       CHECK_EQ(tc[i].expected_res, res);
   5023     }
   5024   }
   5025 }
   5026 
   5027 
   5028 uint64_t run_addiupc(int32_t imm19) {
   5029   Isolate* isolate = CcTest::i_isolate();
   5030   HandleScope scope(isolate);
   5031 
   5032   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5033 
   5034   __ addiupc(v0, imm19);
   5035   __ jr(ra);
   5036   __ nop();
   5037 
   5038   CodeDesc desc;
   5039   assm.GetCode(&desc);
   5040   Handle<Code> code = isolate->factory()->NewCode(
   5041       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5042 
   5043   F2 f = FUNCTION_CAST<F2>(code->entry());
   5044   PC = (uint32_t) f;  // Set the program counter.
   5045 
   5046   uint32_t rs = reinterpret_cast<uint32_t>(
   5047       CALL_GENERATED_CODE(isolate, f, imm19, 0, 0, 0, 0));
   5048 
   5049   return rs;
   5050 }
   5051 
   5052 
   5053 TEST(r6_addiupc) {
   5054   if (IsMipsArchVariant(kMips32r6)) {
   5055     CcTest::InitializeVM();
   5056 
   5057     struct TestCaseAddiupc {
   5058       int32_t   imm19;
   5059     };
   5060 
   5061     struct TestCaseAddiupc tc[] = {
   5062       //  imm19
   5063       { -262144 },   // 0x40000
   5064       {      -1 },   // 0x7FFFF
   5065       {       0 },
   5066       {       1 },   // 0x00001
   5067       {  262143 }    // 0x3FFFF
   5068     };
   5069 
   5070     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
   5071     for (size_t i = 0; i < nr_test_cases; ++i) {
   5072       PC = 0;
   5073       uint32_t res = run_addiupc(tc[i].imm19);
   5074       // Now, the program_counter (PC) is set.
   5075       uint32_t expected_res = PC + (tc[i].imm19 << 2);
   5076       CHECK_EQ(expected_res, res);
   5077     }
   5078   }
   5079 }
   5080 
   5081 
   5082 int32_t run_bc(int32_t offset) {
   5083   Isolate* isolate = CcTest::i_isolate();
   5084   HandleScope scope(isolate);
   5085 
   5086   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5087 
   5088   Label continue_1, stop_execution;
   5089   __ push(ra);
   5090   __ li(v0, 0);
   5091   __ li(t8, 0);
   5092   __ li(t9, 2);   // A condition for stopping execution.
   5093 
   5094   for (int32_t i = -100; i <= -11; ++i) {
   5095     __ addiu(v0, v0, 1);
   5096   }
   5097 
   5098   __ addiu(t8, t8, 1);              // -10
   5099 
   5100   __ beq(t8, t9, &stop_execution);  // -9
   5101   __ nop();                         // -8
   5102   __ beq(t8, t8, &continue_1);      // -7
   5103   __ nop();                         // -6
   5104 
   5105   __ bind(&stop_execution);
   5106   __ pop(ra);                       // -5, -4
   5107   __ jr(ra);                        // -3
   5108   __ nop();                         // -2
   5109 
   5110   __ bind(&continue_1);
   5111   __ bc(offset);                    // -1
   5112 
   5113   for (int32_t i = 0; i <= 99; ++i) {
   5114     __ addiu(v0, v0, 1);
   5115   }
   5116 
   5117   __ pop(ra);
   5118   __ jr(ra);
   5119   __ nop();
   5120 
   5121   CodeDesc desc;
   5122   assm.GetCode(&desc);
   5123   Handle<Code> code = isolate->factory()->NewCode(
   5124       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5125 
   5126   F2 f = FUNCTION_CAST<F2>(code->entry());
   5127 
   5128   int32_t res = reinterpret_cast<int32_t>(
   5129       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5130 
   5131   return res;
   5132 }
   5133 
   5134 
   5135 TEST(r6_bc) {
   5136   if (IsMipsArchVariant(kMips32r6)) {
   5137     CcTest::InitializeVM();
   5138 
   5139     struct TestCaseBc {
   5140       int32_t   offset;
   5141       int32_t   expected_res;
   5142     };
   5143 
   5144     struct TestCaseBc tc[] = {
   5145       //    offset,   expected_result
   5146       {       -100,   (abs(-100) - 10) * 2        },
   5147       {        -11,   (abs(-100) - 10 + 1)        },
   5148       {          0,   (abs(-100) - 10 + 1 + 99)   },
   5149       {          1,   (abs(-100) - 10 + 99)       },
   5150       {         99,   (abs(-100) - 10 + 1)        },
   5151     };
   5152 
   5153     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
   5154     for (size_t i = 0; i < nr_test_cases; ++i) {
   5155       int32_t res = run_bc(tc[i].offset);
   5156       CHECK_EQ(tc[i].expected_res, res);
   5157     }
   5158   }
   5159 }
   5160 
   5161 
   5162 int32_t run_balc(int32_t offset) {
   5163   Isolate* isolate = CcTest::i_isolate();
   5164   HandleScope scope(isolate);
   5165 
   5166   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5167 
   5168   Label continue_1, stop_execution;
   5169   __ push(ra);
   5170   __ li(v0, 0);
   5171   __ li(t8, 0);
   5172   __ li(t9, 2);   // A condition for stopping execution.
   5173 
   5174   __ beq(t8, t8, &continue_1);
   5175   __ nop();
   5176 
   5177   uint32_t instruction_addiu = 0x24420001;  // addiu v0, v0, 1
   5178   for (int32_t i = -117; i <= -57; ++i) {
   5179     __ dd(instruction_addiu);
   5180   }
   5181   __ jr(ra);                        // -56
   5182   __ nop();                         // -55
   5183 
   5184   for (int32_t i = -54; i <= -4; ++i) {
   5185     __ dd(instruction_addiu);
   5186   }
   5187   __ jr(ra);                        // -3
   5188   __ nop();                         // -2
   5189 
   5190   __ bind(&continue_1);
   5191   __ balc(offset);                    // -1
   5192 
   5193   __ pop(ra);                         // 0, 1
   5194   __ jr(ra);                          // 2
   5195   __ nop();                           // 3
   5196 
   5197   for (int32_t i = 4; i <= 44; ++i) {
   5198     __ dd(instruction_addiu);
   5199   }
   5200   __ jr(ra);
   5201   __ nop();
   5202 
   5203   CodeDesc desc;
   5204   assm.GetCode(&desc);
   5205   Handle<Code> code = isolate->factory()->NewCode(
   5206       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5207 
   5208   F2 f = FUNCTION_CAST<F2>(code->entry());
   5209 
   5210   int32_t res = reinterpret_cast<int32_t>(
   5211       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5212 
   5213   return res;
   5214 }
   5215 
   5216 
   5217 uint32_t run_aui(uint32_t rs, uint16_t offset) {
   5218   Isolate* isolate = CcTest::i_isolate();
   5219   HandleScope scope(isolate);
   5220 
   5221   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5222 
   5223   __ li(t0, rs);
   5224   __ aui(v0, t0, offset);
   5225   __ jr(ra);
   5226   __ nop();
   5227 
   5228   CodeDesc desc;
   5229   assm.GetCode(&desc);
   5230   Handle<Code> code = isolate->factory()->NewCode(
   5231       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5232 
   5233   F2 f = FUNCTION_CAST<F2>(code->entry());
   5234 
   5235   uint32_t res =
   5236     reinterpret_cast<uint32_t>
   5237         (CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5238 
   5239   return res;
   5240 }
   5241 
   5242 
   5243 TEST(r6_aui) {
   5244   if (IsMipsArchVariant(kMips32r6)) {
   5245     CcTest::InitializeVM();
   5246 
   5247     struct TestCaseAui {
   5248       uint32_t   rs;
   5249       uint16_t   offset;
   5250       uint32_t   ref_res;
   5251     };
   5252 
   5253     struct TestCaseAui tc[] = {
   5254       // input, offset, result
   5255       {0xfffeffff, 1, 0xffffffff},
   5256       {0xffffffff, 0, 0xffffffff},
   5257       {0, 0xffff, 0xffff0000},
   5258       {0x0008ffff, 0xfff7, 0xffffffff},
   5259       {32767, 32767, 0x7fff7fff},
   5260       // overflow cases
   5261       {0xffffffff, 0x1, 0x0000ffff},
   5262       {0xffffffff, 0xffff, 0xfffeffff},
   5263     };
   5264 
   5265     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAui);
   5266     for (size_t i = 0; i < nr_test_cases; ++i) {
   5267       PC = 0;
   5268       uint32_t res = run_aui(tc[i].rs, tc[i].offset);
   5269       CHECK_EQ(tc[i].ref_res, res);
   5270     }
   5271   }
   5272 }
   5273 
   5274 
   5275 TEST(r6_balc) {
   5276   if (IsMipsArchVariant(kMips32r6)) {
   5277     CcTest::InitializeVM();
   5278 
   5279     struct TestCaseBalc {
   5280       int32_t   offset;
   5281       int32_t   expected_res;
   5282     };
   5283 
   5284     struct TestCaseBalc tc[] = {
   5285       //  offset,   expected_result
   5286       {     -117,   61  },
   5287       {      -54,   51  },
   5288       {        0,   0   },
   5289       {        4,   41  },
   5290     };
   5291 
   5292     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
   5293     for (size_t i = 0; i < nr_test_cases; ++i) {
   5294       int32_t res = run_balc(tc[i].offset);
   5295       CHECK_EQ(tc[i].expected_res, res);
   5296     }
   5297   }
   5298 }
   5299 
   5300 
   5301 uint32_t run_bal(int16_t offset) {
   5302   Isolate* isolate = CcTest::i_isolate();
   5303   HandleScope scope(isolate);
   5304 
   5305   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5306 
   5307   __ mov(t0, ra);
   5308   __ bal(offset);       // Equivalent for "BGEZAL zero_reg, offset".
   5309   __ nop();
   5310 
   5311   __ mov(ra, t0);
   5312   __ jr(ra);
   5313   __ nop();
   5314 
   5315   __ li(v0, 1);
   5316   __ jr(ra);
   5317   __ nop();
   5318 
   5319   CodeDesc desc;
   5320   assm.GetCode(&desc);
   5321   Handle<Code> code = isolate->factory()->NewCode(
   5322       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5323 
   5324   F2 f = FUNCTION_CAST<F2>(code->entry());
   5325 
   5326   uint32_t res = reinterpret_cast<uint32_t>(
   5327       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5328 
   5329   return res;
   5330 }
   5331 
   5332 
   5333 TEST(bal) {
   5334   CcTest::InitializeVM();
   5335 
   5336   struct TestCaseBal {
   5337     int16_t  offset;
   5338     uint32_t  expected_res;
   5339   };
   5340 
   5341   struct TestCaseBal tc[] = {
   5342     // offset, expected_res
   5343     {       4,      1 },
   5344   };
   5345 
   5346   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBal);
   5347   for (size_t i = 0; i < nr_test_cases; ++i) {
   5348     CHECK_EQ(tc[i].expected_res, run_bal(tc[i].offset));
   5349   }
   5350 }
   5351 
   5352 
   5353 static uint32_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
   5354   Isolate* isolate = CcTest::i_isolate();
   5355   HandleScope scope(isolate);
   5356   MacroAssembler assm(isolate, nullptr, 0,
   5357                       v8::internal::CodeObjectRequired::kYes);
   5358 
   5359   __ lsa(v0, a0, a1, sa);
   5360   __ jr(ra);
   5361   __ nop();
   5362 
   5363   CodeDesc desc;
   5364   assm.GetCode(&desc);
   5365   Handle<Code> code = isolate->factory()->NewCode(
   5366       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5367 
   5368   F1 f = FUNCTION_CAST<F1>(code->entry());
   5369 
   5370   uint32_t res = reinterpret_cast<uint32_t>(
   5371       CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0));
   5372 
   5373   return res;
   5374 }
   5375 
   5376 
   5377 TEST(lsa) {
   5378   if (!IsMipsArchVariant(kMips32r6)) return;
   5379 
   5380   CcTest::InitializeVM();
   5381   struct TestCaseLsa {
   5382     int32_t rt;
   5383     int32_t rs;
   5384     uint8_t sa;
   5385     uint32_t expected_res;
   5386   };
   5387 
   5388   struct TestCaseLsa tc[] = {
   5389       // rt, rs, sa, expected_res
   5390       {0x4, 0x1, 1, 0x6},
   5391       {0x4, 0x1, 2, 0x8},
   5392       {0x4, 0x1, 3, 0xc},
   5393       {0x4, 0x1, 4, 0x14},
   5394       {0x0, 0x1, 1, 0x2},
   5395       {0x0, 0x1, 2, 0x4},
   5396       {0x0, 0x1, 3, 0x8},
   5397       {0x0, 0x1, 4, 0x10},
   5398       {0x4, 0x0, 1, 0x4},
   5399       {0x4, 0x0, 2, 0x4},
   5400       {0x4, 0x0, 3, 0x4},
   5401       {0x4, 0x0, 4, 0x4},
   5402       {0x4, INT32_MAX, 1, 0x2},              // Shift overflow.
   5403       {0x4, INT32_MAX >> 1, 2, 0x0},         // Shift overflow.
   5404       {0x4, INT32_MAX >> 2, 3, 0xfffffffc},  // Shift overflow.
   5405       {0x4, INT32_MAX >> 3, 4, 0xfffffff4},  // Shift overflow.
   5406       {INT32_MAX - 1, 0x1, 1, 0x80000000},   // Signed adition overflow.
   5407       {INT32_MAX - 3, 0x1, 2, 0x80000000},   // Signed addition overflow.
   5408       {INT32_MAX - 7, 0x1, 3, 0x80000000},   // Signed addition overflow.
   5409       {INT32_MAX - 15, 0x1, 4, 0x80000000},  // Signed addition overflow.
   5410       {-2, 0x1, 1, 0x0},                     // Addition overflow.
   5411       {-4, 0x1, 2, 0x0},                     // Addition overflow.
   5412       {-8, 0x1, 3, 0x0},                     // Addition overflow.
   5413       {-16, 0x1, 4, 0x0}};                   // Addition overflow.
   5414 
   5415   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
   5416   for (size_t i = 0; i < nr_test_cases; ++i) {
   5417     uint32_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa);
   5418     PrintF("0x%x =? 0x%x == lsa(v0, %x, %x, %hhu)\n", tc[i].expected_res, res,
   5419            tc[i].rt, tc[i].rs, tc[i].sa);
   5420     CHECK_EQ(tc[i].expected_res, res);
   5421   }
   5422 }
   5423 
   5424 
   5425 TEST(Trampoline) {
   5426   // Private member of Assembler class.
   5427   static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
   5428 
   5429   CcTest::InitializeVM();
   5430   Isolate* isolate = CcTest::i_isolate();
   5431   HandleScope scope(isolate);
   5432 
   5433   MacroAssembler assm(isolate, nullptr, 0,
   5434                       v8::internal::CodeObjectRequired::kYes);
   5435   Label done;
   5436   size_t nr_calls = kMaxBranchOffset / (2 * Instruction::kInstrSize) + 2;
   5437 
   5438   for (size_t i = 0; i < nr_calls; ++i) {
   5439     __ BranchShort(&done, eq, a0, Operand(a1));
   5440   }
   5441   __ bind(&done);
   5442   __ Ret(USE_DELAY_SLOT);
   5443   __ mov(v0, zero_reg);
   5444 
   5445   CodeDesc desc;
   5446   assm.GetCode(&desc);
   5447   Handle<Code> code = isolate->factory()->NewCode(
   5448       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5449   F2 f = FUNCTION_CAST<F2>(code->entry());
   5450 
   5451   int32_t res = reinterpret_cast<int32_t>(
   5452       CALL_GENERATED_CODE(isolate, f, 42, 42, 0, 0, 0));
   5453   CHECK_EQ(res, 0);
   5454 }
   5455 
   5456 #undef __
   5457