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   // Exchange between GP anf FP registers is done through memory
    388   // on FPXX compiled binaries and architectures that do not support
    389   // MTHC1 and MTFC1. If this is the case, skipping this test.
    390   if (IsFpxxMode() &&
    391       (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kLoongson))) {
    392     return;
    393   }
    394 
    395   // Test moves between floating point and integer registers.
    396   CcTest::InitializeVM();
    397   Isolate* isolate = CcTest::i_isolate();
    398   HandleScope scope(isolate);
    399 
    400   typedef struct {
    401     double a;
    402     double b;
    403     double c;
    404   } T;
    405   T t;
    406 
    407   Assembler assm(isolate, NULL, 0);
    408   Label L, C;
    409 
    410   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    411   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    412 
    413   // Swap f4 and f6, by using four integer registers, t0-t3.
    414   if (IsFp32Mode()) {
    415     __ mfc1(t0, f4);
    416     __ mfc1(t1, f5);
    417     __ mfc1(t2, f6);
    418     __ mfc1(t3, f7);
    419 
    420     __ mtc1(t0, f6);
    421     __ mtc1(t1, f7);
    422     __ mtc1(t2, f4);
    423     __ mtc1(t3, f5);
    424   } else {
    425     CHECK(!IsMipsArchVariant(kMips32r1) && !IsMipsArchVariant(kLoongson));
    426     DCHECK(IsFp64Mode() || IsFpxxMode());
    427     __ mfc1(t0, f4);
    428     __ mfhc1(t1, f4);
    429     __ mfc1(t2, f6);
    430     __ mfhc1(t3, f6);
    431 
    432     __ mtc1(t0, f6);
    433     __ mthc1(t1, f6);
    434     __ mtc1(t2, f4);
    435     __ mthc1(t3, f4);
    436   }
    437 
    438   // Store the swapped f4 and f5 back to memory.
    439   __ sdc1(f4, MemOperand(a0, offsetof(T, a)) );
    440   __ sdc1(f6, MemOperand(a0, offsetof(T, c)) );
    441 
    442   __ jr(ra);
    443   __ nop();
    444 
    445   CodeDesc desc;
    446   assm.GetCode(&desc);
    447   Handle<Code> code = isolate->factory()->NewCode(
    448       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    449   F3 f = FUNCTION_CAST<F3>(code->entry());
    450   t.a = 1.5e22;
    451   t.b = 2.75e11;
    452   t.c = 17.17;
    453   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    454   USE(dummy);
    455 
    456   CHECK_EQ(2.75e11, t.a);
    457   CHECK_EQ(2.75e11, t.b);
    458   CHECK_EQ(1.5e22, t.c);
    459 }
    460 
    461 
    462 TEST(MIPS5) {
    463   // Test conversions between doubles and integers.
    464   CcTest::InitializeVM();
    465   Isolate* isolate = CcTest::i_isolate();
    466   HandleScope scope(isolate);
    467 
    468   typedef struct {
    469     double a;
    470     double b;
    471     int i;
    472     int j;
    473   } T;
    474   T t;
    475 
    476   Assembler assm(isolate, NULL, 0);
    477   Label L, C;
    478 
    479   // Load all structure elements to registers.
    480   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    481   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    482   __ lw(t0, MemOperand(a0, offsetof(T, i)) );
    483   __ lw(t1, MemOperand(a0, offsetof(T, j)) );
    484 
    485   // Convert double in f4 to int in element i.
    486   __ cvt_w_d(f8, f4);
    487   __ mfc1(t2, f8);
    488   __ sw(t2, MemOperand(a0, offsetof(T, i)) );
    489 
    490   // Convert double in f6 to int in element j.
    491   __ cvt_w_d(f10, f6);
    492   __ mfc1(t3, f10);
    493   __ sw(t3, MemOperand(a0, offsetof(T, j)) );
    494 
    495   // Convert int in original i (t0) to double in a.
    496   __ mtc1(t0, f12);
    497   __ cvt_d_w(f0, f12);
    498   __ sdc1(f0, MemOperand(a0, offsetof(T, a)) );
    499 
    500   // Convert int in original j (t1) to double in b.
    501   __ mtc1(t1, f14);
    502   __ cvt_d_w(f2, f14);
    503   __ sdc1(f2, MemOperand(a0, offsetof(T, b)) );
    504 
    505   __ jr(ra);
    506   __ nop();
    507 
    508   CodeDesc desc;
    509   assm.GetCode(&desc);
    510   Handle<Code> code = isolate->factory()->NewCode(
    511       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    512   F3 f = FUNCTION_CAST<F3>(code->entry());
    513   t.a = 1.5e4;
    514   t.b = 2.75e8;
    515   t.i = 12345678;
    516   t.j = -100000;
    517   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    518   USE(dummy);
    519 
    520   CHECK_EQ(12345678.0, t.a);
    521   CHECK_EQ(-100000.0, t.b);
    522   CHECK_EQ(15000, t.i);
    523   CHECK_EQ(275000000, t.j);
    524 }
    525 
    526 
    527 TEST(MIPS6) {
    528   // Test simple memory loads and stores.
    529   CcTest::InitializeVM();
    530   Isolate* isolate = CcTest::i_isolate();
    531   HandleScope scope(isolate);
    532 
    533   typedef struct {
    534     uint32_t ui;
    535     int32_t si;
    536     int32_t r1;
    537     int32_t r2;
    538     int32_t r3;
    539     int32_t r4;
    540     int32_t r5;
    541     int32_t r6;
    542   } T;
    543   T t;
    544 
    545   Assembler assm(isolate, NULL, 0);
    546   Label L, C;
    547 
    548   // Basic word load/store.
    549   __ lw(t0, MemOperand(a0, offsetof(T, ui)) );
    550   __ sw(t0, MemOperand(a0, offsetof(T, r1)) );
    551 
    552   // lh with positive data.
    553   __ lh(t1, MemOperand(a0, offsetof(T, ui)) );
    554   __ sw(t1, MemOperand(a0, offsetof(T, r2)) );
    555 
    556   // lh with negative data.
    557   __ lh(t2, MemOperand(a0, offsetof(T, si)) );
    558   __ sw(t2, MemOperand(a0, offsetof(T, r3)) );
    559 
    560   // lhu with negative data.
    561   __ lhu(t3, MemOperand(a0, offsetof(T, si)) );
    562   __ sw(t3, MemOperand(a0, offsetof(T, r4)) );
    563 
    564   // lb with negative data.
    565   __ lb(t4, MemOperand(a0, offsetof(T, si)) );
    566   __ sw(t4, MemOperand(a0, offsetof(T, r5)) );
    567 
    568   // sh writes only 1/2 of word.
    569   __ lui(t5, 0x3333);
    570   __ ori(t5, t5, 0x3333);
    571   __ sw(t5, MemOperand(a0, offsetof(T, r6)) );
    572   __ lhu(t5, MemOperand(a0, offsetof(T, si)) );
    573   __ sh(t5, MemOperand(a0, offsetof(T, r6)) );
    574 
    575   __ jr(ra);
    576   __ nop();
    577 
    578   CodeDesc desc;
    579   assm.GetCode(&desc);
    580   Handle<Code> code = isolate->factory()->NewCode(
    581       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    582   F3 f = FUNCTION_CAST<F3>(code->entry());
    583   t.ui = 0x11223344;
    584   t.si = 0x99aabbcc;
    585   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    586   USE(dummy);
    587 
    588   CHECK_EQ(static_cast<int32_t>(0x11223344), t.r1);
    589 #if __BYTE_ORDER == __LITTLE_ENDIAN
    590   CHECK_EQ(static_cast<int32_t>(0x3344), t.r2);
    591   CHECK_EQ(static_cast<int32_t>(0xffffbbcc), t.r3);
    592   CHECK_EQ(static_cast<int32_t>(0x0000bbcc), t.r4);
    593   CHECK_EQ(static_cast<int32_t>(0xffffffcc), t.r5);
    594   CHECK_EQ(static_cast<int32_t>(0x3333bbcc), t.r6);
    595 #elif __BYTE_ORDER == __BIG_ENDIAN
    596   CHECK_EQ(static_cast<int32_t>(0x1122), t.r2);
    597   CHECK_EQ(static_cast<int32_t>(0xffff99aa), t.r3);
    598   CHECK_EQ(static_cast<int32_t>(0x000099aa), t.r4);
    599   CHECK_EQ(static_cast<int32_t>(0xffffff99), t.r5);
    600   CHECK_EQ(static_cast<int32_t>(0x99aa3333), t.r6);
    601 #else
    602 #error Unknown endianness
    603 #endif
    604 }
    605 
    606 
    607 TEST(MIPS7) {
    608   // Test floating point compare and branch instructions.
    609   CcTest::InitializeVM();
    610   Isolate* isolate = CcTest::i_isolate();
    611   HandleScope scope(isolate);
    612 
    613   typedef struct {
    614     double a;
    615     double b;
    616     double c;
    617     double d;
    618     double e;
    619     double f;
    620     int32_t result;
    621   } T;
    622   T t;
    623 
    624   // Create a function that accepts &t, and loads, manipulates, and stores
    625   // the doubles t.a ... t.f.
    626   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
    627   Label neither_is_nan, less_than, outa_here;
    628 
    629   __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
    630   __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
    631   if (!IsMipsArchVariant(kMips32r6)) {
    632   __ c(UN, D, f4, f6);
    633   __ bc1f(&neither_is_nan);
    634   } else {
    635     __ cmp(UN, L, f2, f4, f6);
    636     __ bc1eqz(&neither_is_nan, f2);
    637   }
    638   __ nop();
    639   __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
    640   __ Branch(&outa_here);
    641 
    642   __ bind(&neither_is_nan);
    643 
    644   if (IsMipsArchVariant(kLoongson)) {
    645     __ c(OLT, D, f6, f4);
    646     __ bc1t(&less_than);
    647   } else if (IsMipsArchVariant(kMips32r6)) {
    648     __ cmp(OLT, L, f2, f6, f4);
    649     __ bc1nez(&less_than, f2);
    650   } else {
    651     __ c(OLT, D, f6, f4, 2);
    652     __ bc1t(&less_than, 2);
    653   }
    654 
    655   __ nop();
    656   __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
    657   __ Branch(&outa_here);
    658 
    659   __ bind(&less_than);
    660   __ Addu(t0, zero_reg, Operand(1));
    661   __ sw(t0, MemOperand(a0, offsetof(T, result)) );  // Set true.
    662 
    663 
    664   // This test-case should have additional tests.
    665 
    666   __ bind(&outa_here);
    667 
    668   __ jr(ra);
    669   __ nop();
    670 
    671   CodeDesc desc;
    672   assm.GetCode(&desc);
    673   Handle<Code> code = isolate->factory()->NewCode(
    674       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    675   F3 f = FUNCTION_CAST<F3>(code->entry());
    676   t.a = 1.5e14;
    677   t.b = 2.75e11;
    678   t.c = 2.0;
    679   t.d = -4.0;
    680   t.e = 0.0;
    681   t.f = 0.0;
    682   t.result = 0;
    683   Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
    684   USE(dummy);
    685   CHECK_EQ(1.5e14, t.a);
    686   CHECK_EQ(2.75e11, t.b);
    687   CHECK_EQ(1, t.result);
    688 }
    689 
    690 
    691 TEST(MIPS8) {
    692   // Test ROTR and ROTRV instructions.
    693   if (IsMipsArchVariant(kMips32r2)) {
    694     CcTest::InitializeVM();
    695     Isolate* isolate = CcTest::i_isolate();
    696     HandleScope scope(isolate);
    697 
    698     typedef struct {
    699       int32_t input;
    700       int32_t result_rotr_4;
    701       int32_t result_rotr_8;
    702       int32_t result_rotr_12;
    703       int32_t result_rotr_16;
    704       int32_t result_rotr_20;
    705       int32_t result_rotr_24;
    706       int32_t result_rotr_28;
    707       int32_t result_rotrv_4;
    708       int32_t result_rotrv_8;
    709       int32_t result_rotrv_12;
    710       int32_t result_rotrv_16;
    711       int32_t result_rotrv_20;
    712       int32_t result_rotrv_24;
    713       int32_t result_rotrv_28;
    714     } T;
    715     T t;
    716 
    717     MacroAssembler assm(isolate, NULL, 0,
    718                         v8::internal::CodeObjectRequired::kYes);
    719 
    720     // Basic word load.
    721     __ lw(t0, MemOperand(a0, offsetof(T, input)) );
    722 
    723     // ROTR instruction (called through the Ror macro).
    724     __ Ror(t1, t0, 0x0004);
    725     __ Ror(t2, t0, 0x0008);
    726     __ Ror(t3, t0, 0x000c);
    727     __ Ror(t4, t0, 0x0010);
    728     __ Ror(t5, t0, 0x0014);
    729     __ Ror(t6, t0, 0x0018);
    730     __ Ror(t7, t0, 0x001c);
    731 
    732     // Basic word store.
    733     __ sw(t1, MemOperand(a0, offsetof(T, result_rotr_4)) );
    734     __ sw(t2, MemOperand(a0, offsetof(T, result_rotr_8)) );
    735     __ sw(t3, MemOperand(a0, offsetof(T, result_rotr_12)) );
    736     __ sw(t4, MemOperand(a0, offsetof(T, result_rotr_16)) );
    737     __ sw(t5, MemOperand(a0, offsetof(T, result_rotr_20)) );
    738     __ sw(t6, MemOperand(a0, offsetof(T, result_rotr_24)) );
    739     __ sw(t7, MemOperand(a0, offsetof(T, result_rotr_28)) );
    740 
    741     // ROTRV instruction (called through the Ror macro).
    742     __ li(t7, 0x0004);
    743     __ Ror(t1, t0, t7);
    744     __ li(t7, 0x0008);
    745     __ Ror(t2, t0, t7);
    746     __ li(t7, 0x000C);
    747     __ Ror(t3, t0, t7);
    748     __ li(t7, 0x0010);
    749     __ Ror(t4, t0, t7);
    750     __ li(t7, 0x0014);
    751     __ Ror(t5, t0, t7);
    752     __ li(t7, 0x0018);
    753     __ Ror(t6, t0, t7);
    754     __ li(t7, 0x001C);
    755     __ Ror(t7, t0, t7);
    756 
    757     // Basic word store.
    758     __ sw(t1, MemOperand(a0, offsetof(T, result_rotrv_4)) );
    759     __ sw(t2, MemOperand(a0, offsetof(T, result_rotrv_8)) );
    760     __ sw(t3, MemOperand(a0, offsetof(T, result_rotrv_12)) );
    761     __ sw(t4, MemOperand(a0, offsetof(T, result_rotrv_16)) );
    762     __ sw(t5, MemOperand(a0, offsetof(T, result_rotrv_20)) );
    763     __ sw(t6, MemOperand(a0, offsetof(T, result_rotrv_24)) );
    764     __ sw(t7, MemOperand(a0, offsetof(T, result_rotrv_28)) );
    765 
    766     __ jr(ra);
    767     __ nop();
    768 
    769     CodeDesc desc;
    770     assm.GetCode(&desc);
    771     Handle<Code> code = isolate->factory()->NewCode(
    772         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    773     F3 f = FUNCTION_CAST<F3>(code->entry());
    774     t.input = 0x12345678;
    775     Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0x0, 0, 0, 0);
    776     USE(dummy);
    777     CHECK_EQ(static_cast<int32_t>(0x81234567), t.result_rotr_4);
    778     CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotr_8);
    779     CHECK_EQ(static_cast<int32_t>(0x67812345), t.result_rotr_12);
    780     CHECK_EQ(static_cast<int32_t>(0x56781234), t.result_rotr_16);
    781     CHECK_EQ(static_cast<int32_t>(0x45678123), t.result_rotr_20);
    782     CHECK_EQ(static_cast<int32_t>(0x34567812), t.result_rotr_24);
    783     CHECK_EQ(static_cast<int32_t>(0x23456781), t.result_rotr_28);
    784 
    785     CHECK_EQ(static_cast<int32_t>(0x81234567), t.result_rotrv_4);
    786     CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotrv_8);
    787     CHECK_EQ(static_cast<int32_t>(0x67812345), t.result_rotrv_12);
    788     CHECK_EQ(static_cast<int32_t>(0x56781234), t.result_rotrv_16);
    789     CHECK_EQ(static_cast<int32_t>(0x45678123), t.result_rotrv_20);
    790     CHECK_EQ(static_cast<int32_t>(0x34567812), t.result_rotrv_24);
    791     CHECK_EQ(static_cast<int32_t>(0x23456781), t.result_rotrv_28);
    792   }
    793 }
    794 
    795 
    796 TEST(MIPS9) {
    797   // Test BRANCH improvements.
    798   CcTest::InitializeVM();
    799   Isolate* isolate = CcTest::i_isolate();
    800   HandleScope scope(isolate);
    801 
    802   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
    803   Label exit, exit2, exit3;
    804 
    805   __ Branch(&exit, ge, a0, Operand(zero_reg));
    806   __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
    807   __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
    808 
    809   __ bind(&exit);
    810   __ bind(&exit2);
    811   __ bind(&exit3);
    812   __ jr(ra);
    813   __ nop();
    814 
    815   CodeDesc desc;
    816   assm.GetCode(&desc);
    817   isolate->factory()->NewCode(
    818       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    819 }
    820 
    821 
    822 TEST(MIPS10) {
    823   // Test conversions between doubles and words.
    824   CcTest::InitializeVM();
    825   Isolate* isolate = CcTest::i_isolate();
    826   HandleScope scope(isolate);
    827 
    828   typedef struct {
    829     double a;
    830     double b;
    831     int32_t dbl_mant;
    832     int32_t dbl_exp;
    833     int32_t word;
    834     int32_t b_word;
    835   } T;
    836   T t;
    837 
    838   Assembler assm(isolate, NULL, 0);
    839   Label L, C;
    840 
    841   if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kLoongson)) return;
    842 
    843   // Load all structure elements to registers.
    844   // (f0, f1) = a (fp32), f0 = a (fp64)
    845   __ ldc1(f0, MemOperand(a0, offsetof(T, a)));
    846 
    847   __ mfc1(t0, f0);   // t0 = f0(31..0)
    848   __ mfhc1(t1, f0);  // t1 = sign_extend(f0(63..32))
    849   __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant)));  // dbl_mant = t0
    850   __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp)));   // dbl_exp = t1
    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, nullptr, 0,
   1460                         v8::internal::CodeObjectRequired::kYes);
   1461 
   1462     struct TestFloat {
   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     };
   1472 
   1473     TestFloat test;
   1474     const double dnan = std::numeric_limits<double>::quiet_NaN();
   1475     const double dinf = std::numeric_limits<double>::infinity();
   1476     const double dminf = -std::numeric_limits<double>::infinity();
   1477     const float fnan = std::numeric_limits<float>::quiet_NaN();
   1478     const float finf = std::numeric_limits<float>::infinity();
   1479     const float fminf = std::numeric_limits<float>::infinity();
   1480     const int kTableLength = 13;
   1481     double inputsa[kTableLength] = {2.0,  3.0,  dnan, 3.0,   -0.0, 0.0, dinf,
   1482                                     dnan, 42.0, dinf, dminf, dinf, dnan};
   1483     double inputsb[kTableLength] = {3.0,  2.0,  3.0,  dnan, 0.0,   -0.0, dnan,
   1484                                     dinf, dinf, 42.0, dinf, dminf, dnan};
   1485     double outputsdmin[kTableLength] = {2.0,   2.0,   3.0,  3.0,  -0.0,
   1486                                         -0.0,  dinf,  dinf, 42.0, 42.0,
   1487                                         dminf, dminf, dnan};
   1488     double outputsdmax[kTableLength] = {3.0,  3.0,  3.0,  3.0,  0.0,  0.0, dinf,
   1489                                         dinf, dinf, dinf, dinf, dinf, dnan};
   1490 
   1491     float inputse[kTableLength] = {2.0,  3.0,  fnan, 3.0,   -0.0, 0.0, finf,
   1492                                    fnan, 42.0, finf, fminf, finf, fnan};
   1493     float inputsf[kTableLength] = {3.0,  2.0,  3.0,  fnan, 0.0,   -0.0, fnan,
   1494                                    finf, finf, 42.0, finf, fminf, fnan};
   1495     float outputsfmin[kTableLength] = {2.0,   2.0,   3.0,  3.0,  -0.0,
   1496                                        -0.0,  finf,  finf, 42.0, 42.0,
   1497                                        fminf, fminf, fnan};
   1498     float outputsfmax[kTableLength] = {3.0,  3.0,  3.0,  3.0,  0.0,  0.0, finf,
   1499                                        finf, finf, finf, finf, finf, fnan};
   1500 
   1501     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
   1502     __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
   1503     __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
   1504     __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
   1505     __ min_d(f10, f4, f8);
   1506     __ max_d(f12, f4, f8);
   1507     __ min_s(f14, f2, f6);
   1508     __ max_s(f16, f2, f6);
   1509     __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
   1510     __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
   1511     __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
   1512     __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
   1513     __ jr(ra);
   1514     __ nop();
   1515 
   1516     CodeDesc desc;
   1517     assm.GetCode(&desc);
   1518     Handle<Code> code = isolate->factory()->NewCode(
   1519         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1520     F3 f = FUNCTION_CAST<F3>(code->entry());
   1521     for (int i = 0; i < kTableLength; i++) {
   1522       test.a = inputsa[i];
   1523       test.b = inputsb[i];
   1524       test.e = inputse[i];
   1525       test.f = inputsf[i];
   1526 
   1527       CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0);
   1528 
   1529       CHECK_EQ(0, memcmp(&test.c, &outputsdmin[i], sizeof(test.c)));
   1530       CHECK_EQ(0, memcmp(&test.d, &outputsdmax[i], sizeof(test.d)));
   1531       CHECK_EQ(0, memcmp(&test.g, &outputsfmin[i], sizeof(test.g)));
   1532       CHECK_EQ(0, memcmp(&test.h, &outputsfmax[i], sizeof(test.h)));
   1533     }
   1534   }
   1535 }
   1536 
   1537 
   1538 TEST(rint_d)  {
   1539   if (IsMipsArchVariant(kMips32r6)) {
   1540     const int kTableLength = 30;
   1541     CcTest::InitializeVM();
   1542     Isolate* isolate = CcTest::i_isolate();
   1543     HandleScope scope(isolate);
   1544     MacroAssembler assm(isolate, NULL, 0,
   1545                         v8::internal::CodeObjectRequired::kYes);
   1546 
   1547     typedef struct test_float {
   1548       double a;
   1549       double b;
   1550       int fcsr;
   1551     }TestFloat;
   1552 
   1553     TestFloat test;
   1554     double inputs[kTableLength] = {18446744073709551617.0,
   1555       4503599627370496.0, -4503599627370496.0,
   1556       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1557       1.7976931348623157E+308, 6.27463370218383111104242366943E-307,
   1558       309485009821345068724781056.89,
   1559       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1560       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1561       37778931862957161709568.0, 37778931862957161709569.0,
   1562       37778931862957161709580.0, 37778931862957161709581.0,
   1563       37778931862957161709582.0, 37778931862957161709583.0,
   1564       37778931862957161709584.0, 37778931862957161709585.0,
   1565       37778931862957161709586.0, 37778931862957161709587.0};
   1566     double outputs_RN[kTableLength] = {18446744073709551617.0,
   1567       4503599627370496.0, -4503599627370496.0,
   1568       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1569       1.7976931348623157E308, 0,
   1570       309485009821345068724781057.0,
   1571       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   1572       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   1573       37778931862957161709568.0, 37778931862957161709569.0,
   1574       37778931862957161709580.0, 37778931862957161709581.0,
   1575       37778931862957161709582.0, 37778931862957161709583.0,
   1576       37778931862957161709584.0, 37778931862957161709585.0,
   1577       37778931862957161709586.0, 37778931862957161709587.0};
   1578     double outputs_RZ[kTableLength] = {18446744073709551617.0,
   1579       4503599627370496.0, -4503599627370496.0,
   1580       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1581       1.7976931348623157E308, 0,
   1582       309485009821345068724781057.0,
   1583       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1584       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1585       37778931862957161709568.0, 37778931862957161709569.0,
   1586       37778931862957161709580.0, 37778931862957161709581.0,
   1587       37778931862957161709582.0, 37778931862957161709583.0,
   1588       37778931862957161709584.0, 37778931862957161709585.0,
   1589       37778931862957161709586.0, 37778931862957161709587.0};
   1590     double outputs_RP[kTableLength] = {18446744073709551617.0,
   1591       4503599627370496.0, -4503599627370496.0,
   1592       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1593       1.7976931348623157E308, 1,
   1594       309485009821345068724781057.0,
   1595       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   1596       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1597       37778931862957161709568.0, 37778931862957161709569.0,
   1598       37778931862957161709580.0, 37778931862957161709581.0,
   1599       37778931862957161709582.0, 37778931862957161709583.0,
   1600       37778931862957161709584.0, 37778931862957161709585.0,
   1601       37778931862957161709586.0, 37778931862957161709587.0};
   1602     double outputs_RM[kTableLength] = {18446744073709551617.0,
   1603       4503599627370496.0, -4503599627370496.0,
   1604       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
   1605       1.7976931348623157E308, 0,
   1606       309485009821345068724781057.0,
   1607       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1608       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   1609       37778931862957161709568.0, 37778931862957161709569.0,
   1610       37778931862957161709580.0, 37778931862957161709581.0,
   1611       37778931862957161709582.0, 37778931862957161709583.0,
   1612       37778931862957161709584.0, 37778931862957161709585.0,
   1613       37778931862957161709586.0, 37778931862957161709587.0};
   1614     int fcsr_inputs[4] =
   1615       {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
   1616     double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
   1617     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
   1618     __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
   1619     __ cfc1(t1, FCSR);
   1620     __ ctc1(t0, FCSR);
   1621     __ rint_d(f8, f4);
   1622     __ sdc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
   1623     __ ctc1(t1, FCSR);
   1624     __ jr(ra);
   1625     __ nop();
   1626 
   1627     CodeDesc desc;
   1628     assm.GetCode(&desc);
   1629     Handle<Code> code = isolate->factory()->NewCode(
   1630         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1631     F3 f = FUNCTION_CAST<F3>(code->entry());
   1632 
   1633     for (int j = 0; j < 4; j++) {
   1634       test.fcsr = fcsr_inputs[j];
   1635       for (int i = 0; i < kTableLength; i++) {
   1636         test.a = inputs[i];
   1637         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1638         CHECK_EQ(test.b, outputs[j][i]);
   1639       }
   1640     }
   1641   }
   1642 }
   1643 
   1644 
   1645 TEST(sel) {
   1646   if (IsMipsArchVariant(kMips32r6)) {
   1647     CcTest::InitializeVM();
   1648     Isolate* isolate = CcTest::i_isolate();
   1649     HandleScope scope(isolate);
   1650     MacroAssembler assm(isolate, NULL, 0,
   1651                         v8::internal::CodeObjectRequired::kYes);
   1652 
   1653     typedef struct test {
   1654       double dd;
   1655       double ds;
   1656       double dt;
   1657       float fd;
   1658       float fs;
   1659       float ft;
   1660     } Test;
   1661 
   1662     Test test;
   1663     __ ldc1(f0, MemOperand(a0, offsetof(Test, dd)) );  // test
   1664     __ ldc1(f2, MemOperand(a0, offsetof(Test, ds)) );  // src1
   1665     __ ldc1(f4, MemOperand(a0, offsetof(Test, dt)) );  // src2
   1666     __ lwc1(f6, MemOperand(a0, offsetof(Test, fd)) );  // test
   1667     __ lwc1(f8, MemOperand(a0, offsetof(Test, fs)) );  // src1
   1668     __ lwc1(f10, MemOperand(a0, offsetof(Test, ft)) );  // src2
   1669     __ sel_d(f0, f2, f4);
   1670     __ sel_s(f6, f8, f10);
   1671     __ sdc1(f0, MemOperand(a0, offsetof(Test, dd)) );
   1672     __ swc1(f6, MemOperand(a0, offsetof(Test, fd)) );
   1673     __ jr(ra);
   1674     __ nop();
   1675     CodeDesc desc;
   1676     assm.GetCode(&desc);
   1677     Handle<Code> code = isolate->factory()->NewCode(
   1678         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1679     F3 f = FUNCTION_CAST<F3>(code->entry());
   1680 
   1681     const int test_size = 3;
   1682     const int input_size = 5;
   1683 
   1684     double inputs_dt[input_size] = {0.0, 65.2, -70.32,
   1685       18446744073709551621.0, -18446744073709551621.0};
   1686     double inputs_ds[input_size] = {0.1, 69.88, -91.325,
   1687       18446744073709551625.0, -18446744073709551625.0};
   1688     float inputs_ft[input_size] = {0.0, 65.2, -70.32,
   1689       18446744073709551621.0, -18446744073709551621.0};
   1690     float inputs_fs[input_size] = {0.1, 69.88, -91.325,
   1691       18446744073709551625.0, -18446744073709551625.0};
   1692     double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
   1693       18446744073709551616.0, 18446744073709555712.0};
   1694     float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
   1695       18446744073709551616.0, 18446746272732807168.0};
   1696     for (int j=0; j < test_size; j+=2) {
   1697       for (int i=0; i < input_size; i++) {
   1698         test.dt = inputs_dt[i];
   1699         test.dd = tests_D[j];
   1700         test.ds = inputs_ds[i];
   1701         test.ft = inputs_ft[i];
   1702         test.fd = tests_S[j];
   1703         test.fs = inputs_fs[i];
   1704         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1705         CHECK_EQ(test.dd, inputs_ds[i]);
   1706         CHECK_EQ(test.fd, inputs_fs[i]);
   1707 
   1708         test.dd = tests_D[j+1];
   1709         test.fd = tests_S[j+1];
   1710         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1711         CHECK_EQ(test.dd, inputs_dt[i]);
   1712         CHECK_EQ(test.fd, inputs_ft[i]);
   1713       }
   1714     }
   1715   }
   1716 }
   1717 
   1718 
   1719 TEST(rint_s)  {
   1720   if (IsMipsArchVariant(kMips32r6)) {
   1721     const int kTableLength = 30;
   1722     CcTest::InitializeVM();
   1723     Isolate* isolate = CcTest::i_isolate();
   1724     HandleScope scope(isolate);
   1725     MacroAssembler assm(isolate, NULL, 0,
   1726                         v8::internal::CodeObjectRequired::kYes);
   1727 
   1728     typedef struct test_float {
   1729       float a;
   1730       float b;
   1731       int fcsr;
   1732     }TestFloat;
   1733 
   1734     TestFloat test;
   1735     float inputs[kTableLength] = {18446744073709551617.0,
   1736       4503599627370496.0, -4503599627370496.0,
   1737       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1738       1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
   1739       309485009821345068724781056.89,
   1740       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1741       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1742       37778931862957161709568.0, 37778931862957161709569.0,
   1743       37778931862957161709580.0, 37778931862957161709581.0,
   1744       37778931862957161709582.0, 37778931862957161709583.0,
   1745       37778931862957161709584.0, 37778931862957161709585.0,
   1746       37778931862957161709586.0, 37778931862957161709587.0};
   1747     float outputs_RN[kTableLength] = {18446744073709551617.0,
   1748       4503599627370496.0, -4503599627370496.0,
   1749       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1750       1.7976931348623157E38, 0,
   1751       309485009821345068724781057.0,
   1752       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   1753       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   1754       37778931862957161709568.0, 37778931862957161709569.0,
   1755       37778931862957161709580.0, 37778931862957161709581.0,
   1756       37778931862957161709582.0, 37778931862957161709583.0,
   1757       37778931862957161709584.0, 37778931862957161709585.0,
   1758       37778931862957161709586.0, 37778931862957161709587.0};
   1759     float outputs_RZ[kTableLength] = {18446744073709551617.0,
   1760       4503599627370496.0, -4503599627370496.0,
   1761       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1762       1.7976931348623157E38, 0,
   1763       309485009821345068724781057.0,
   1764       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1765       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1766       37778931862957161709568.0, 37778931862957161709569.0,
   1767       37778931862957161709580.0, 37778931862957161709581.0,
   1768       37778931862957161709582.0, 37778931862957161709583.0,
   1769       37778931862957161709584.0, 37778931862957161709585.0,
   1770       37778931862957161709586.0, 37778931862957161709587.0};
   1771     float outputs_RP[kTableLength] = {18446744073709551617.0,
   1772       4503599627370496.0, -4503599627370496.0,
   1773       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1774       1.7976931348623157E38, 1,
   1775       309485009821345068724781057.0,
   1776       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   1777       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   1778       37778931862957161709568.0, 37778931862957161709569.0,
   1779       37778931862957161709580.0, 37778931862957161709581.0,
   1780       37778931862957161709582.0, 37778931862957161709583.0,
   1781       37778931862957161709584.0, 37778931862957161709585.0,
   1782       37778931862957161709586.0, 37778931862957161709587.0};
   1783     float outputs_RM[kTableLength] = {18446744073709551617.0,
   1784       4503599627370496.0, -4503599627370496.0,
   1785       1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
   1786       1.7976931348623157E38, 0,
   1787       309485009821345068724781057.0,
   1788       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1789       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   1790       37778931862957161709568.0, 37778931862957161709569.0,
   1791       37778931862957161709580.0, 37778931862957161709581.0,
   1792       37778931862957161709582.0, 37778931862957161709583.0,
   1793       37778931862957161709584.0, 37778931862957161709585.0,
   1794       37778931862957161709586.0, 37778931862957161709587.0};
   1795     int fcsr_inputs[4] =
   1796       {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
   1797     float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
   1798     __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
   1799     __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
   1800     __ cfc1(t1, FCSR);
   1801     __ ctc1(t0, FCSR);
   1802     __ rint_s(f8, f4);
   1803     __ swc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
   1804     __ ctc1(t1, FCSR);
   1805     __ jr(ra);
   1806     __ nop();
   1807 
   1808     CodeDesc desc;
   1809     assm.GetCode(&desc);
   1810     Handle<Code> code = isolate->factory()->NewCode(
   1811         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1812     F3 f = FUNCTION_CAST<F3>(code->entry());
   1813 
   1814     for (int j = 0; j < 4; j++) {
   1815       test.fcsr = fcsr_inputs[j];
   1816       for (int i = 0; i < kTableLength; i++) {
   1817         test.a = inputs[i];
   1818         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1819         CHECK_EQ(test.b, outputs[j][i]);
   1820       }
   1821     }
   1822   }
   1823 }
   1824 
   1825 
   1826 TEST(Cvt_d_uw) {
   1827   CcTest::InitializeVM();
   1828   Isolate* isolate = CcTest::i_isolate();
   1829   HandleScope scope(isolate);
   1830   MacroAssembler assm(isolate, NULL, 0,
   1831                       v8::internal::CodeObjectRequired::kYes);
   1832 
   1833   typedef struct test_struct {
   1834     unsigned input;
   1835     uint64_t output;
   1836   } TestStruct;
   1837 
   1838   unsigned inputs[] = {
   1839     0x0, 0xffffffff, 0x80000000, 0x7fffffff
   1840   };
   1841 
   1842   uint64_t outputs[] = {
   1843     0x0, 0x41efffffffe00000,
   1844     0x41e0000000000000, 0x41dfffffffc00000
   1845   };
   1846 
   1847   int kTableLength = sizeof(inputs)/sizeof(inputs[0]);
   1848 
   1849   TestStruct test;
   1850 
   1851   __ lw(t1, MemOperand(a0, offsetof(TestStruct, input)));
   1852   __ Cvt_d_uw(f4, t1, f6);
   1853   __ sdc1(f4, MemOperand(a0, offsetof(TestStruct, output)));
   1854   __ jr(ra);
   1855   __ nop();
   1856 
   1857   CodeDesc desc;
   1858   assm.GetCode(&desc);
   1859   Handle<Code> code = isolate->factory()->NewCode(
   1860       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1861   F3 f = FUNCTION_CAST<F3>(code->entry());
   1862   for (int i = 0; i < kTableLength; i++) {
   1863     test.input = inputs[i];
   1864     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1865     // Check outputs
   1866     CHECK_EQ(test.output, outputs[i]);
   1867   }
   1868 }
   1869 
   1870 
   1871 TEST(mina_maxa) {
   1872   if (IsMipsArchVariant(kMips32r6)) {
   1873     const int kTableLength = 23;
   1874     CcTest::InitializeVM();
   1875     Isolate* isolate = CcTest::i_isolate();
   1876     HandleScope scope(isolate);
   1877     MacroAssembler assm(isolate, nullptr, 0,
   1878                         v8::internal::CodeObjectRequired::kYes);
   1879     const double dnan = std::numeric_limits<double>::quiet_NaN();
   1880     const double dinf = std::numeric_limits<double>::infinity();
   1881     const double dminf = -std::numeric_limits<double>::infinity();
   1882     const float fnan = std::numeric_limits<float>::quiet_NaN();
   1883     const float finf = std::numeric_limits<float>::infinity();
   1884     const float fminf = std::numeric_limits<float>::infinity();
   1885 
   1886     struct TestFloat {
   1887       double a;
   1888       double b;
   1889       double resd;
   1890       double resd1;
   1891       float c;
   1892       float d;
   1893       float resf;
   1894       float resf1;
   1895     };
   1896 
   1897     TestFloat test;
   1898     double inputsa[kTableLength] = {
   1899         5.3,  4.8, 6.1,  9.8, 9.8,  9.8,  -10.0, -8.9, -9.8,  -10.0, -8.9, -9.8,
   1900         dnan, 3.0, -0.0, 0.0, dinf, dnan, 42.0,  dinf, dminf, dinf,  dnan};
   1901     double inputsb[kTableLength] = {
   1902         4.8, 5.3,  6.1, -10.0, -8.9, -9.8, 9.8,  9.8,  9.8,  -9.8,  -11.2, -9.8,
   1903         3.0, dnan, 0.0, -0.0,  dnan, dinf, dinf, 42.0, dinf, dminf, dnan};
   1904     double resd[kTableLength] = {
   1905         4.8, 4.8, 6.1,  9.8,  -8.9, -9.8, 9.8,  -8.9, -9.8,  -9.8,  -8.9, -9.8,
   1906         3.0, 3.0, -0.0, -0.0, dinf, dinf, 42.0, 42.0, dminf, dminf, dnan};
   1907     double resd1[kTableLength] = {
   1908         5.3, 5.3, 6.1, -10.0, 9.8,  9.8,  -10.0, 9.8,  9.8,  -10.0, -11.2, -9.8,
   1909         3.0, 3.0, 0.0, 0.0,   dinf, dinf, dinf,  dinf, dinf, dinf,  dnan};
   1910     float inputsc[kTableLength] = {
   1911         5.3,  4.8, 6.1,  9.8, 9.8,  9.8,  -10.0, -8.9, -9.8,  -10.0, -8.9, -9.8,
   1912         fnan, 3.0, -0.0, 0.0, finf, fnan, 42.0,  finf, fminf, finf,  fnan};
   1913     float inputsd[kTableLength] = {4.8,  5.3,  6.1,  -10.0, -8.9,  -9.8,
   1914                                    9.8,  9.8,  9.8,  -9.8,  -11.2, -9.8,
   1915                                    3.0,  fnan, -0.0, 0.0,   fnan,  finf,
   1916                                    finf, 42.0, finf, fminf, fnan};
   1917     float resf[kTableLength] = {
   1918         4.8, 4.8, 6.1,  9.8,  -8.9, -9.8, 9.8,  -8.9, -9.8,  -9.8,  -8.9, -9.8,
   1919         3.0, 3.0, -0.0, -0.0, finf, finf, 42.0, 42.0, fminf, fminf, fnan};
   1920     float resf1[kTableLength] = {
   1921         5.3, 5.3, 6.1, -10.0, 9.8,  9.8,  -10.0, 9.8,  9.8,  -10.0, -11.2, -9.8,
   1922         3.0, 3.0, 0.0, 0.0,   finf, finf, finf,  finf, finf, finf,  fnan};
   1923 
   1924     __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   1925     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
   1926     __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   1927     __ lwc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
   1928     __ mina_d(f6, f2, f4);
   1929     __ mina_s(f12, f8, f10);
   1930     __ maxa_d(f14, f2, f4);
   1931     __ maxa_s(f16, f8, f10);
   1932     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, resf)) );
   1933     __ sdc1(f6, MemOperand(a0, offsetof(TestFloat, resd)) );
   1934     __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resf1)) );
   1935     __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resd1)) );
   1936     __ jr(ra);
   1937     __ nop();
   1938 
   1939     CodeDesc desc;
   1940     assm.GetCode(&desc);
   1941     Handle<Code> code = isolate->factory()->NewCode(
   1942         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   1943     F3 f = FUNCTION_CAST<F3>(code->entry());
   1944     for (int i = 0; i < kTableLength; i++) {
   1945       test.a = inputsa[i];
   1946       test.b = inputsb[i];
   1947       test.c = inputsc[i];
   1948       test.d = inputsd[i];
   1949       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   1950       if (i < kTableLength - 1) {
   1951         CHECK_EQ(test.resd, resd[i]);
   1952         CHECK_EQ(test.resf, resf[i]);
   1953         CHECK_EQ(test.resd1, resd1[i]);
   1954         CHECK_EQ(test.resf1, resf1[i]);
   1955       } else {
   1956         CHECK(std::isnan(test.resd));
   1957         CHECK(std::isnan(test.resf));
   1958         CHECK(std::isnan(test.resd1));
   1959         CHECK(std::isnan(test.resf1));
   1960       }
   1961     }
   1962   }
   1963 }
   1964 
   1965 
   1966 // ----------------------mips32r2 specific tests----------------------
   1967 TEST(trunc_l) {
   1968   if (IsMipsArchVariant(kMips32r2) && IsFp64Mode()) {
   1969     CcTest::InitializeVM();
   1970     Isolate* isolate = CcTest::i_isolate();
   1971     HandleScope scope(isolate);
   1972     MacroAssembler assm(isolate, NULL, 0,
   1973                         v8::internal::CodeObjectRequired::kYes);
   1974     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   1975     typedef struct test_float {
   1976       uint32_t isNaN2008;
   1977       double a;
   1978       float b;
   1979       int64_t c;  // a trunc result
   1980       int64_t d;  // b trunc result
   1981     }Test;
   1982     const int kTableLength = 15;
   1983     double inputs_D[kTableLength] = {
   1984         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1985         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1986         2147483648.0,
   1987         std::numeric_limits<double>::quiet_NaN(),
   1988         std::numeric_limits<double>::infinity()
   1989         };
   1990     float inputs_S[kTableLength] = {
   1991         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   1992         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   1993         2147483648.0,
   1994         std::numeric_limits<float>::quiet_NaN(),
   1995         std::numeric_limits<float>::infinity()
   1996         };
   1997     double outputs[kTableLength] = {
   1998         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   1999         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2000         2147483648.0, dFPU64InvalidResult,
   2001         dFPU64InvalidResult};
   2002     double outputsNaN2008[kTableLength] = {
   2003         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2004         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2005         2147483648.0,
   2006         0,
   2007         dFPU64InvalidResult};
   2008 
   2009     __ cfc1(t1, FCSR);
   2010     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2011     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2012     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2013     __ trunc_l_d(f8, f4);
   2014     __ trunc_l_s(f10, f6);
   2015     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2016     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2017     __ jr(ra);
   2018     __ nop();
   2019     Test test;
   2020     CodeDesc desc;
   2021     assm.GetCode(&desc);
   2022     Handle<Code> code = isolate->factory()->NewCode(
   2023         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2024     F3 f = FUNCTION_CAST<F3>(code->entry());
   2025     for (int i = 0; i < kTableLength; i++) {
   2026       test.a = inputs_D[i];
   2027       test.b = inputs_S[i];
   2028       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2029       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   2030               kArchVariant == kMips32r6) {
   2031         CHECK_EQ(test.c, outputsNaN2008[i]);
   2032       } else {
   2033         CHECK_EQ(test.c, outputs[i]);
   2034       }
   2035       CHECK_EQ(test.d, test.c);
   2036     }
   2037   }
   2038 }
   2039 
   2040 
   2041 TEST(movz_movn) {
   2042   if (IsMipsArchVariant(kMips32r2)) {
   2043     const int kTableLength = 4;
   2044     CcTest::InitializeVM();
   2045     Isolate* isolate = CcTest::i_isolate();
   2046     HandleScope scope(isolate);
   2047     MacroAssembler assm(isolate, NULL, 0,
   2048                         v8::internal::CodeObjectRequired::kYes);
   2049 
   2050     typedef struct test_float {
   2051       int32_t rt;
   2052       double a;
   2053       double b;
   2054       double bold;
   2055       double b1;
   2056       double bold1;
   2057       float c;
   2058       float d;
   2059       float dold;
   2060       float d1;
   2061       float dold1;
   2062     }TestFloat;
   2063 
   2064     TestFloat test;
   2065     double inputs_D[kTableLength] = {
   2066       5.3, -5.3, 5.3, -2.9
   2067     };
   2068     double inputs_S[kTableLength] = {
   2069       4.8, 4.8, -4.8, -0.29
   2070     };
   2071 
   2072     float outputs_S[kTableLength] = {
   2073       4.8, 4.8, -4.8, -0.29
   2074     };
   2075     double outputs_D[kTableLength] = {
   2076       5.3, -5.3, 5.3, -2.9
   2077     };
   2078 
   2079     __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2080     __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
   2081     __ lw(t0, MemOperand(a0, offsetof(TestFloat, rt)) );
   2082     __ Move(f12, 0.0);
   2083     __ Move(f10, 0.0);
   2084     __ Move(f16, 0.0);
   2085     __ Move(f14, 0.0);
   2086     __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, bold)) );
   2087     __ swc1(f10, MemOperand(a0, offsetof(TestFloat, dold)) );
   2088     __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, bold1)) );
   2089     __ swc1(f14, MemOperand(a0, offsetof(TestFloat, dold1)) );
   2090     __ movz_s(f10, f6, t0);
   2091     __ movz_d(f12, f2, t0);
   2092     __ movn_s(f14, f6, t0);
   2093     __ movn_d(f16, f2, t0);
   2094     __ swc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
   2095     __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, b)) );
   2096     __ swc1(f14, MemOperand(a0, offsetof(TestFloat, d1)) );
   2097     __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, b1)) );
   2098     __ jr(ra);
   2099     __ nop();
   2100 
   2101     CodeDesc desc;
   2102     assm.GetCode(&desc);
   2103     Handle<Code> code = isolate->factory()->NewCode(
   2104         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2105     F3 f = FUNCTION_CAST<F3>(code->entry());
   2106     for (int i = 0; i < kTableLength; i++) {
   2107       test.a = inputs_D[i];
   2108       test.c = inputs_S[i];
   2109 
   2110       test.rt = 1;
   2111       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2112       CHECK_EQ(test.b, test.bold);
   2113       CHECK_EQ(test.d, test.dold);
   2114       CHECK_EQ(test.b1, outputs_D[i]);
   2115       CHECK_EQ(test.d1, outputs_S[i]);
   2116 
   2117       test.rt = 0;
   2118       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2119       CHECK_EQ(test.b, outputs_D[i]);
   2120       CHECK_EQ(test.d, outputs_S[i]);
   2121       CHECK_EQ(test.b1, test.bold1);
   2122       CHECK_EQ(test.d1, test.dold1);
   2123     }
   2124   }
   2125 }
   2126 
   2127 
   2128 TEST(movt_movd) {
   2129   if (IsMipsArchVariant(kMips32r2)) {
   2130     const int kTableLength = 4;
   2131     CcTest::InitializeVM();
   2132     Isolate* isolate = CcTest::i_isolate();
   2133 
   2134     typedef struct test_float {
   2135       double srcd;
   2136       double dstd;
   2137       double dstdold;
   2138       double dstd1;
   2139       double dstdold1;
   2140       float srcf;
   2141       float dstf;
   2142       float dstfold;
   2143       float dstf1;
   2144       float dstfold1;
   2145       int32_t cc;
   2146       int32_t fcsr;
   2147     }TestFloat;
   2148 
   2149     TestFloat test;
   2150     double inputs_D[kTableLength] = {
   2151       5.3, -5.3, 20.8, -2.9
   2152     };
   2153     double inputs_S[kTableLength] = {
   2154       4.88, 4.8, -4.8, -0.29
   2155     };
   2156 
   2157     float outputs_S[kTableLength] = {
   2158       4.88, 4.8, -4.8, -0.29
   2159     };
   2160     double outputs_D[kTableLength] = {
   2161       5.3, -5.3, 20.8, -2.9
   2162     };
   2163     int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7};
   2164 
   2165     for (int i = 0; i < kTableLength; i++) {
   2166       test.srcd = inputs_D[i];
   2167       test.srcf = inputs_S[i];
   2168 
   2169       for (int j = 0; j< 8; j++) {
   2170         test.cc = condition_flags[j];
   2171         if (test.cc == 0) {
   2172           test.fcsr = 1 << 23;
   2173         } else {
   2174           test.fcsr = 1 << (24+condition_flags[j]);
   2175         }
   2176         HandleScope scope(isolate);
   2177         MacroAssembler assm(isolate, NULL, 0,
   2178                             v8::internal::CodeObjectRequired::kYes);
   2179         __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) );
   2180         __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) );
   2181         __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) );
   2182         __ cfc1(t0, FCSR);
   2183         __ ctc1(t1, FCSR);
   2184         __ li(t2, 0x0);
   2185         __ mtc1(t2, f12);
   2186         __ mtc1(t2, f10);
   2187         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold)) );
   2188         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold)) );
   2189         __ movt_s(f12, f4, test.cc);
   2190         __ movt_d(f10, f2, test.cc);
   2191         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf)) );
   2192         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd)) );
   2193         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold1)) );
   2194         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold1)) );
   2195         __ movf_s(f12, f4, test.cc);
   2196         __ movf_d(f10, f2, test.cc);
   2197         __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf1)) );
   2198         __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd1)) );
   2199         __ ctc1(t0, FCSR);
   2200         __ jr(ra);
   2201         __ nop();
   2202 
   2203         CodeDesc desc;
   2204         assm.GetCode(&desc);
   2205         Handle<Code> code = isolate->factory()->NewCode(
   2206             desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2207         F3 f = FUNCTION_CAST<F3>(code->entry());
   2208 
   2209         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2210         CHECK_EQ(test.dstf, outputs_S[i]);
   2211         CHECK_EQ(test.dstd, outputs_D[i]);
   2212         CHECK_EQ(test.dstf1, test.dstfold1);
   2213         CHECK_EQ(test.dstd1, test.dstdold1);
   2214         test.fcsr = 0;
   2215         (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2216         CHECK_EQ(test.dstf, test.dstfold);
   2217         CHECK_EQ(test.dstd, test.dstdold);
   2218         CHECK_EQ(test.dstf1, outputs_S[i]);
   2219         CHECK_EQ(test.dstd1, outputs_D[i]);
   2220       }
   2221     }
   2222   }
   2223 }
   2224 
   2225 
   2226 // ----------------------tests for all archs--------------------------
   2227 TEST(cvt_w_d) {
   2228   CcTest::InitializeVM();
   2229   Isolate* isolate = CcTest::i_isolate();
   2230   HandleScope scope(isolate);
   2231   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2232 
   2233   typedef struct test_float {
   2234     double a;
   2235     int32_t b;
   2236     int32_t fcsr;
   2237   }Test;
   2238   const int kTableLength = 24;
   2239   double inputs[kTableLength] = {
   2240       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2241       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2242       2147483637.0, 2147483638.0, 2147483639.0,
   2243       2147483640.0, 2147483641.0, 2147483642.0,
   2244       2147483643.0, 2147483644.0, 2147483645.0,
   2245       2147483646.0, 2147483647.0, 2147483653.0
   2246       };
   2247   double outputs_RN[kTableLength] = {
   2248       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2249       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2250       2147483637.0, 2147483638.0, 2147483639.0,
   2251       2147483640.0, 2147483641.0, 2147483642.0,
   2252       2147483643.0, 2147483644.0, 2147483645.0,
   2253       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2254   double outputs_RZ[kTableLength] = {
   2255       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2256       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2257       2147483637.0, 2147483638.0, 2147483639.0,
   2258       2147483640.0, 2147483641.0, 2147483642.0,
   2259       2147483643.0, 2147483644.0, 2147483645.0,
   2260       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2261   double outputs_RP[kTableLength] = {
   2262       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   2263       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2264       2147483637.0, 2147483638.0, 2147483639.0,
   2265       2147483640.0, 2147483641.0, 2147483642.0,
   2266       2147483643.0, 2147483644.0, 2147483645.0,
   2267       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2268   double outputs_RM[kTableLength] = {
   2269       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2270       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2271       2147483637.0, 2147483638.0, 2147483639.0,
   2272       2147483640.0, 2147483641.0, 2147483642.0,
   2273       2147483643.0, 2147483644.0, 2147483645.0,
   2274       2147483646.0, 2147483647.0, kFPUInvalidResult};
   2275   int fcsr_inputs[4] =
   2276       {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
   2277   double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
   2278   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2279   __ lw(t0, MemOperand(a0, offsetof(Test, fcsr)) );
   2280   __ cfc1(t1, FCSR);
   2281   __ ctc1(t0, FCSR);
   2282   __ cvt_w_d(f8, f4);
   2283   __ swc1(f8, MemOperand(a0, offsetof(Test, b)) );
   2284   __ ctc1(t1, FCSR);
   2285   __ jr(ra);
   2286   __ nop();
   2287   Test test;
   2288   CodeDesc desc;
   2289   assm.GetCode(&desc);
   2290   Handle<Code> code = isolate->factory()->NewCode(
   2291       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2292   F3 f = FUNCTION_CAST<F3>(code->entry());
   2293   for (int j = 0; j < 4; j++) {
   2294     test.fcsr = fcsr_inputs[j];
   2295     for (int i = 0; i < kTableLength; i++) {
   2296       test.a = inputs[i];
   2297       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2298       CHECK_EQ(test.b, outputs[j][i]);
   2299     }
   2300   }
   2301 }
   2302 
   2303 
   2304 TEST(trunc_w) {
   2305   CcTest::InitializeVM();
   2306   Isolate* isolate = CcTest::i_isolate();
   2307   HandleScope scope(isolate);
   2308   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2309 
   2310   typedef struct test_float {
   2311     uint32_t isNaN2008;
   2312     double a;
   2313     float b;
   2314     int32_t c;  // a trunc result
   2315     int32_t d;  // b trunc result
   2316   }Test;
   2317   const int kTableLength = 15;
   2318   double inputs_D[kTableLength] = {
   2319       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2320       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2321       2147483648.0,
   2322       std::numeric_limits<double>::quiet_NaN(),
   2323       std::numeric_limits<double>::infinity()
   2324       };
   2325   float inputs_S[kTableLength] = {
   2326       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2327       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2328       2147483648.0,
   2329       std::numeric_limits<float>::quiet_NaN(),
   2330       std::numeric_limits<float>::infinity()
   2331       };
   2332   double outputs[kTableLength] = {
   2333       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2334       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2335       kFPUInvalidResult, kFPUInvalidResult,
   2336       kFPUInvalidResult};
   2337   double outputsNaN2008[kTableLength] = {
   2338       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2339       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   2340       kFPUInvalidResult,
   2341       0,
   2342       kFPUInvalidResult};
   2343 
   2344   __ cfc1(t1, FCSR);
   2345   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2346   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2347   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2348   __ trunc_w_d(f8, f4);
   2349   __ trunc_w_s(f10, f6);
   2350   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2351   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2352   __ jr(ra);
   2353   __ nop();
   2354   Test test;
   2355   CodeDesc desc;
   2356   assm.GetCode(&desc);
   2357   Handle<Code> code = isolate->factory()->NewCode(
   2358       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2359   F3 f = FUNCTION_CAST<F3>(code->entry());
   2360   for (int i = 0; i < kTableLength; i++) {
   2361     test.a = inputs_D[i];
   2362     test.b = inputs_S[i];
   2363     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2364     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   2365       CHECK_EQ(test.c, outputsNaN2008[i]);
   2366     } else {
   2367       CHECK_EQ(test.c, outputs[i]);
   2368     }
   2369     CHECK_EQ(test.d, test.c);
   2370   }
   2371 }
   2372 
   2373 
   2374 TEST(round_w) {
   2375   CcTest::InitializeVM();
   2376   Isolate* isolate = CcTest::i_isolate();
   2377   HandleScope scope(isolate);
   2378   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2379 
   2380   typedef struct test_float {
   2381     uint32_t isNaN2008;
   2382     double a;
   2383     float b;
   2384     int32_t c;  // a trunc result
   2385     int32_t d;  // b trunc result
   2386   }Test;
   2387   const int kTableLength = 15;
   2388   double inputs_D[kTableLength] = {
   2389       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2390       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2391       2147483648.0,
   2392       std::numeric_limits<double>::quiet_NaN(),
   2393       std::numeric_limits<double>::infinity()
   2394       };
   2395   float inputs_S[kTableLength] = {
   2396       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2397       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2398       2147483648.0,
   2399       std::numeric_limits<float>::quiet_NaN(),
   2400       std::numeric_limits<float>::infinity()
   2401       };
   2402   double outputs[kTableLength] = {
   2403       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2404       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2405       kFPUInvalidResult, kFPUInvalidResult,
   2406       kFPUInvalidResult};
   2407   double outputsNaN2008[kTableLength] = {
   2408       2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2409       -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2410       kFPUInvalidResult, 0,
   2411       kFPUInvalidResult};
   2412 
   2413   __ cfc1(t1, FCSR);
   2414   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2415   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2416   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2417   __ round_w_d(f8, f4);
   2418   __ round_w_s(f10, f6);
   2419   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2420   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2421   __ jr(ra);
   2422   __ nop();
   2423   Test test;
   2424   CodeDesc desc;
   2425   assm.GetCode(&desc);
   2426   Handle<Code> code = isolate->factory()->NewCode(
   2427       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2428   F3 f = FUNCTION_CAST<F3>(code->entry());
   2429   for (int i = 0; i < kTableLength; i++) {
   2430     test.a = inputs_D[i];
   2431     test.b = inputs_S[i];
   2432     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2433     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   2434       CHECK_EQ(test.c, outputsNaN2008[i]);
   2435     } else {
   2436       CHECK_EQ(test.c, outputs[i]);
   2437     }
   2438     CHECK_EQ(test.d, test.c);
   2439   }
   2440 }
   2441 
   2442 
   2443 TEST(round_l) {
   2444   if (IsFp64Mode()) {
   2445     CcTest::InitializeVM();
   2446     Isolate* isolate = CcTest::i_isolate();
   2447     HandleScope scope(isolate);
   2448     MacroAssembler assm(isolate, NULL, 0,
   2449                         v8::internal::CodeObjectRequired::kYes);
   2450     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   2451     typedef struct test_float {
   2452       uint32_t isNaN2008;
   2453       double a;
   2454       float b;
   2455       int64_t c;
   2456       int64_t d;
   2457     }Test;
   2458     const int kTableLength = 15;
   2459     double inputs_D[kTableLength] = {
   2460         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2461         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2462         2147483648.0,
   2463         std::numeric_limits<double>::quiet_NaN(),
   2464         std::numeric_limits<double>::infinity()
   2465         };
   2466     float inputs_S[kTableLength] = {
   2467         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2468         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2469         2147483648.0,
   2470         std::numeric_limits<float>::quiet_NaN(),
   2471         std::numeric_limits<float>::infinity()
   2472         };
   2473     double outputs[kTableLength] = {
   2474         2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2475         -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2476         2147483648.0, dFPU64InvalidResult,
   2477         dFPU64InvalidResult};
   2478     double outputsNaN2008[kTableLength] = {
   2479         2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
   2480         -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
   2481         2147483648.0,
   2482         0,
   2483         dFPU64InvalidResult};
   2484 
   2485     __ cfc1(t1, FCSR);
   2486     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2487     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2488     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2489     __ round_l_d(f8, f4);
   2490     __ round_l_s(f10, f6);
   2491     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2492     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2493     __ jr(ra);
   2494     __ nop();
   2495     Test test;
   2496     CodeDesc desc;
   2497     assm.GetCode(&desc);
   2498     Handle<Code> code = isolate->factory()->NewCode(
   2499         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2500     F3 f = FUNCTION_CAST<F3>(code->entry());
   2501     for (int i = 0; i < kTableLength; i++) {
   2502       test.a = inputs_D[i];
   2503       test.b = inputs_S[i];
   2504       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2505       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   2506               kArchVariant == kMips32r6) {
   2507         CHECK_EQ(test.c, outputsNaN2008[i]);
   2508       } else {
   2509         CHECK_EQ(test.c, outputs[i]);
   2510       }
   2511       CHECK_EQ(test.d, test.c);
   2512     }
   2513   }
   2514 }
   2515 
   2516 
   2517 TEST(sub) {
   2518   const int kTableLength = 12;
   2519   CcTest::InitializeVM();
   2520   Isolate* isolate = CcTest::i_isolate();
   2521   HandleScope scope(isolate);
   2522   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2523 
   2524   typedef struct test_float {
   2525     float a;
   2526     float b;
   2527     float resultS;
   2528     double c;
   2529     double d;
   2530     double resultD;
   2531   }TestFloat;
   2532 
   2533   TestFloat test;
   2534   double inputfs_D[kTableLength] = {
   2535     5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
   2536     5.3, 4.8, 2.9, -5.3, -4.8, -2.9
   2537   };
   2538   double inputft_D[kTableLength] = {
   2539     4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
   2540     -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
   2541   };
   2542   double outputs_D[kTableLength] = {
   2543     0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
   2544     10.1, 10.1, 5.8, -0.5, 0.5, 0.0
   2545   };
   2546   float inputfs_S[kTableLength] = {
   2547     5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
   2548     5.3, 4.8, 2.9, -5.3, -4.8, -2.9
   2549   };
   2550   float inputft_S[kTableLength] = {
   2551     4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
   2552     -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
   2553   };
   2554   float outputs_S[kTableLength] = {
   2555     0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
   2556     10.1, 10.1, 5.8, -0.5, 0.5, 0.0
   2557   };
   2558   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2559   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
   2560   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   2561   __ ldc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
   2562   __ sub_s(f6, f2, f4);
   2563   __ sub_d(f12, f8, f10);
   2564   __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2565   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2566   __ jr(ra);
   2567   __ nop();
   2568 
   2569   CodeDesc desc;
   2570   assm.GetCode(&desc);
   2571   Handle<Code> code = isolate->factory()->NewCode(
   2572       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2573   F3 f = FUNCTION_CAST<F3>(code->entry());
   2574   for (int i = 0; i < kTableLength; i++) {
   2575     test.a = inputfs_S[i];
   2576     test.b = inputft_S[i];
   2577     test.c = inputfs_D[i];
   2578     test.d = inputft_D[i];
   2579     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2580     CHECK_EQ(test.resultS, outputs_S[i]);
   2581     CHECK_EQ(test.resultD, outputs_D[i]);
   2582   }
   2583 }
   2584 
   2585 
   2586 TEST(sqrt_rsqrt_recip) {
   2587   const int kTableLength = 4;
   2588   const double deltaDouble = 2E-15;
   2589   const float deltaFloat = 2E-7;
   2590   const float sqrt2_s = sqrt(2);
   2591   const double sqrt2_d = sqrt(2);
   2592   CcTest::InitializeVM();
   2593   Isolate* isolate = CcTest::i_isolate();
   2594   HandleScope scope(isolate);
   2595   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2596 
   2597   typedef struct test_float {
   2598     float a;
   2599     float resultS;
   2600     float resultS1;
   2601     float resultS2;
   2602     double c;
   2603     double resultD;
   2604     double resultD1;
   2605     double resultD2;
   2606   }TestFloat;
   2607   TestFloat test;
   2608 
   2609   double inputs_D[kTableLength] = {
   2610     0.0L, 4.0L, 2.0L, 4e-28L
   2611   };
   2612 
   2613   double outputs_D[kTableLength] = {
   2614     0.0L, 2.0L, sqrt2_d, 2e-14L
   2615   };
   2616   float inputs_S[kTableLength] = {
   2617     0.0, 4.0, 2.0, 4e-28
   2618   };
   2619 
   2620   float outputs_S[kTableLength] = {
   2621     0.0, 2.0, sqrt2_s, 2e-14
   2622   };
   2623 
   2624 
   2625   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2626   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   2627   __ sqrt_s(f6, f2);
   2628   __ sqrt_d(f12, f8);
   2629 
   2630   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
   2631     __ rsqrt_d(f14, f8);
   2632     __ rsqrt_s(f16, f2);
   2633     __ recip_d(f18, f8);
   2634     __ recip_s(f4, f2);
   2635   }
   2636   __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2637   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2638 
   2639   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
   2640     __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resultS1)) );
   2641     __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resultD1)) );
   2642     __ swc1(f4, MemOperand(a0, offsetof(TestFloat, resultS2)) );
   2643     __ sdc1(f18, MemOperand(a0, offsetof(TestFloat, resultD2)) );
   2644   }
   2645   __ jr(ra);
   2646   __ nop();
   2647 
   2648   CodeDesc desc;
   2649   assm.GetCode(&desc);
   2650   Handle<Code> code = isolate->factory()->NewCode(
   2651       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2652   F3 f = FUNCTION_CAST<F3>(code->entry());
   2653 
   2654   for (int i = 0; i < kTableLength; i++) {
   2655     float f1;
   2656     double d1;
   2657     test.a = inputs_S[i];
   2658     test.c = inputs_D[i];
   2659 
   2660     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2661 
   2662     CHECK_EQ(test.resultS, outputs_S[i]);
   2663     CHECK_EQ(test.resultD, outputs_D[i]);
   2664 
   2665     if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
   2666       if (i != 0) {
   2667         f1 = test.resultS1 - 1.0F/outputs_S[i];
   2668         f1 = (f1 < 0) ? f1 : -f1;
   2669         CHECK(f1 <= deltaFloat);
   2670         d1 = test.resultD1 - 1.0L/outputs_D[i];
   2671         d1 = (d1 < 0) ? d1 : -d1;
   2672         CHECK(d1 <= deltaDouble);
   2673         f1 = test.resultS2 - 1.0F/inputs_S[i];
   2674         f1 = (f1 < 0) ? f1 : -f1;
   2675         CHECK(f1 <= deltaFloat);
   2676         d1 = test.resultD2 - 1.0L/inputs_D[i];
   2677         d1 = (d1 < 0) ? d1 : -d1;
   2678         CHECK(d1 <= deltaDouble);
   2679       } else {
   2680         CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]);
   2681         CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]);
   2682         CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]);
   2683         CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]);
   2684       }
   2685     }
   2686   }
   2687 }
   2688 
   2689 
   2690 TEST(neg) {
   2691   const int kTableLength = 3;
   2692   CcTest::InitializeVM();
   2693   Isolate* isolate = CcTest::i_isolate();
   2694   HandleScope scope(isolate);
   2695   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2696 
   2697   typedef struct test_float {
   2698     float a;
   2699     float resultS;
   2700     double c;
   2701     double resultD;
   2702   }TestFloat;
   2703 
   2704   TestFloat test;
   2705   double inputs_D[kTableLength] = {
   2706     0.0, 4.0, -2.0
   2707   };
   2708 
   2709   double outputs_D[kTableLength] = {
   2710     0.0, -4.0, 2.0
   2711   };
   2712   float inputs_S[kTableLength] = {
   2713     0.0, 4.0, -2.0
   2714   };
   2715 
   2716   float outputs_S[kTableLength] = {
   2717     0.0, -4.0, 2.0
   2718   };
   2719   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2720   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
   2721   __ neg_s(f6, f2);
   2722   __ neg_d(f12, f8);
   2723   __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2724   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2725   __ jr(ra);
   2726   __ nop();
   2727 
   2728   CodeDesc desc;
   2729   assm.GetCode(&desc);
   2730   Handle<Code> code = isolate->factory()->NewCode(
   2731       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2732   F3 f = FUNCTION_CAST<F3>(code->entry());
   2733   for (int i = 0; i < kTableLength; i++) {
   2734     test.a = inputs_S[i];
   2735     test.c = inputs_D[i];
   2736     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2737     CHECK_EQ(test.resultS, outputs_S[i]);
   2738     CHECK_EQ(test.resultD, outputs_D[i]);
   2739   }
   2740 }
   2741 
   2742 
   2743 TEST(mul) {
   2744   const int kTableLength = 4;
   2745   CcTest::InitializeVM();
   2746   Isolate* isolate = CcTest::i_isolate();
   2747   HandleScope scope(isolate);
   2748   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2749 
   2750   typedef struct test_float {
   2751     float a;
   2752     float b;
   2753     float resultS;
   2754     double c;
   2755     double d;
   2756     double resultD;
   2757   }TestFloat;
   2758 
   2759   TestFloat test;
   2760   double inputfs_D[kTableLength] = {
   2761     5.3, -5.3, 5.3, -2.9
   2762   };
   2763   double inputft_D[kTableLength] = {
   2764     4.8, 4.8, -4.8, -0.29
   2765   };
   2766 
   2767   float inputfs_S[kTableLength] = {
   2768     5.3, -5.3, 5.3, -2.9
   2769   };
   2770   float inputft_S[kTableLength] = {
   2771     4.8, 4.8, -4.8, -0.29
   2772   };
   2773 
   2774   __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
   2775   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
   2776   __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
   2777   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
   2778   __ mul_s(f10, f2, f4);
   2779   __ mul_d(f12, f6, f8);
   2780   __ swc1(f10, MemOperand(a0, offsetof(TestFloat, resultS)) );
   2781   __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
   2782   __ jr(ra);
   2783   __ nop();
   2784 
   2785   CodeDesc desc;
   2786   assm.GetCode(&desc);
   2787   Handle<Code> code = isolate->factory()->NewCode(
   2788       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2789   F3 f = FUNCTION_CAST<F3>(code->entry());
   2790   for (int i = 0; i < kTableLength; i++) {
   2791     test.a = inputfs_S[i];
   2792     test.b = inputft_S[i];
   2793     test.c = inputfs_D[i];
   2794     test.d = inputft_D[i];
   2795     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2796     CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]);
   2797     CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]);
   2798   }
   2799 }
   2800 
   2801 
   2802 TEST(mov) {
   2803   const int kTableLength = 4;
   2804   CcTest::InitializeVM();
   2805   Isolate* isolate = CcTest::i_isolate();
   2806   HandleScope scope(isolate);
   2807   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2808 
   2809   typedef struct test_float {
   2810     double a;
   2811     double b;
   2812     float c;
   2813     float d;
   2814   }TestFloat;
   2815 
   2816   TestFloat test;
   2817   double inputs_D[kTableLength] = {
   2818     5.3, -5.3, 5.3, -2.9
   2819   };
   2820   double inputs_S[kTableLength] = {
   2821     4.8, 4.8, -4.8, -0.29
   2822   };
   2823 
   2824   float outputs_S[kTableLength] = {
   2825     4.8, 4.8, -4.8, -0.29
   2826   };
   2827   double outputs_D[kTableLength] = {
   2828     5.3, -5.3, 5.3, -2.9
   2829   };
   2830 
   2831   __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
   2832   __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
   2833   __ mov_s(f8, f6);
   2834   __ mov_d(f10, f4);
   2835   __ swc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
   2836   __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, b)) );
   2837 
   2838   __ jr(ra);
   2839   __ nop();
   2840 
   2841   CodeDesc desc;
   2842   assm.GetCode(&desc);
   2843   Handle<Code> code = isolate->factory()->NewCode(
   2844       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2845   F3 f = FUNCTION_CAST<F3>(code->entry());
   2846   for (int i = 0; i < kTableLength; i++) {
   2847     test.a = inputs_D[i];
   2848     test.c = inputs_S[i];
   2849 
   2850     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2851     CHECK_EQ(test.b, outputs_D[i]);
   2852     CHECK_EQ(test.d, outputs_S[i]);
   2853   }
   2854 }
   2855 
   2856 
   2857 TEST(floor_w) {
   2858   CcTest::InitializeVM();
   2859   Isolate* isolate = CcTest::i_isolate();
   2860   HandleScope scope(isolate);
   2861   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   2862 
   2863   typedef struct test_float {
   2864     uint32_t isNaN2008;
   2865     double a;
   2866     float b;
   2867     int32_t c;  // a floor result
   2868     int32_t d;  // b floor result
   2869   }Test;
   2870   const int kTableLength = 15;
   2871   double inputs_D[kTableLength] = {
   2872       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2873       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2874       2147483648.0,
   2875       std::numeric_limits<double>::quiet_NaN(),
   2876       std::numeric_limits<double>::infinity()
   2877       };
   2878   float inputs_S[kTableLength] = {
   2879       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2880       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2881       2147483648.0,
   2882       std::numeric_limits<float>::quiet_NaN(),
   2883       std::numeric_limits<float>::infinity()
   2884       };
   2885   double outputs[kTableLength] = {
   2886       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2887       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2888       kFPUInvalidResult, kFPUInvalidResult,
   2889       kFPUInvalidResult};
   2890   double outputsNaN2008[kTableLength] = {
   2891       2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2892       -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2893       kFPUInvalidResult,
   2894       0,
   2895       kFPUInvalidResult};
   2896 
   2897   __ cfc1(t1, FCSR);
   2898   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2899   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2900   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2901   __ floor_w_d(f8, f4);
   2902   __ floor_w_s(f10, f6);
   2903   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2904   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2905   __ jr(ra);
   2906   __ nop();
   2907   Test test;
   2908   CodeDesc desc;
   2909   assm.GetCode(&desc);
   2910   Handle<Code> code = isolate->factory()->NewCode(
   2911       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2912   F3 f = FUNCTION_CAST<F3>(code->entry());
   2913   for (int i = 0; i < kTableLength; i++) {
   2914     test.a = inputs_D[i];
   2915     test.b = inputs_S[i];
   2916     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2917     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   2918       CHECK_EQ(test.c, outputsNaN2008[i]);
   2919     } else {
   2920       CHECK_EQ(test.c, outputs[i]);
   2921     }
   2922     CHECK_EQ(test.d, test.c);
   2923   }
   2924 }
   2925 
   2926 
   2927 TEST(floor_l) {
   2928   if (IsFp64Mode()) {
   2929     CcTest::InitializeVM();
   2930     Isolate* isolate = CcTest::i_isolate();
   2931     HandleScope scope(isolate);
   2932     MacroAssembler assm(isolate, NULL, 0,
   2933                         v8::internal::CodeObjectRequired::kYes);
   2934     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   2935     typedef struct test_float {
   2936       uint32_t isNaN2008;
   2937       double a;
   2938       float b;
   2939       int64_t c;
   2940       int64_t d;
   2941     }Test;
   2942     const int kTableLength = 15;
   2943     double inputs_D[kTableLength] = {
   2944         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2945         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2946         2147483648.0,
   2947         std::numeric_limits<double>::quiet_NaN(),
   2948         std::numeric_limits<double>::infinity()
   2949         };
   2950     float inputs_S[kTableLength] = {
   2951         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   2952         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   2953         2147483648.0,
   2954         std::numeric_limits<float>::quiet_NaN(),
   2955         std::numeric_limits<float>::infinity()
   2956         };
   2957     double outputs[kTableLength] = {
   2958         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2959         -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2960         2147483648.0, dFPU64InvalidResult,
   2961         dFPU64InvalidResult};
   2962     double outputsNaN2008[kTableLength] = {
   2963         2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
   2964         -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
   2965         2147483648.0,
   2966         0,
   2967         dFPU64InvalidResult};
   2968 
   2969     __ cfc1(t1, FCSR);
   2970     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   2971     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   2972     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   2973     __ floor_l_d(f8, f4);
   2974     __ floor_l_s(f10, f6);
   2975     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   2976     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   2977     __ jr(ra);
   2978     __ nop();
   2979     Test test;
   2980     CodeDesc desc;
   2981     assm.GetCode(&desc);
   2982     Handle<Code> code = isolate->factory()->NewCode(
   2983         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   2984     F3 f = FUNCTION_CAST<F3>(code->entry());
   2985     for (int i = 0; i < kTableLength; i++) {
   2986       test.a = inputs_D[i];
   2987       test.b = inputs_S[i];
   2988       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   2989       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   2990               kArchVariant == kMips32r6) {
   2991         CHECK_EQ(test.c, outputsNaN2008[i]);
   2992       } else {
   2993         CHECK_EQ(test.c, outputs[i]);
   2994       }
   2995       CHECK_EQ(test.d, test.c);
   2996     }
   2997   }
   2998 }
   2999 
   3000 
   3001 TEST(ceil_w) {
   3002   CcTest::InitializeVM();
   3003   Isolate* isolate = CcTest::i_isolate();
   3004   HandleScope scope(isolate);
   3005   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   3006 
   3007   typedef struct test_float {
   3008     uint32_t isNaN2008;
   3009     double a;
   3010     float b;
   3011     int32_t c;  // a floor result
   3012     int32_t d;  // b floor result
   3013   }Test;
   3014   const int kTableLength = 15;
   3015   double inputs_D[kTableLength] = {
   3016       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3017       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3018       2147483648.0,
   3019       std::numeric_limits<double>::quiet_NaN(),
   3020       std::numeric_limits<double>::infinity()
   3021       };
   3022   float inputs_S[kTableLength] = {
   3023       2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3024       -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3025       2147483648.0,
   3026       std::numeric_limits<float>::quiet_NaN(),
   3027       std::numeric_limits<float>::infinity()
   3028       };
   3029   double outputs[kTableLength] = {
   3030       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3031       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3032       kFPUInvalidResult, kFPUInvalidResult,
   3033       kFPUInvalidResult};
   3034   double outputsNaN2008[kTableLength] = {
   3035       3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3036       -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3037       kFPUInvalidResult,
   3038       0,
   3039       kFPUInvalidResult};
   3040 
   3041   __ cfc1(t1, FCSR);
   3042   __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   3043   __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   3044   __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   3045   __ ceil_w_d(f8, f4);
   3046   __ ceil_w_s(f10, f6);
   3047   __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
   3048   __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
   3049   __ jr(ra);
   3050   __ nop();
   3051   Test test;
   3052   CodeDesc desc;
   3053   assm.GetCode(&desc);
   3054   Handle<Code> code = isolate->factory()->NewCode(
   3055       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3056   F3 f = FUNCTION_CAST<F3>(code->entry());
   3057   for (int i = 0; i < kTableLength; i++) {
   3058     test.a = inputs_D[i];
   3059     test.b = inputs_S[i];
   3060     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3061     if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) {
   3062       CHECK_EQ(test.c, outputsNaN2008[i]);
   3063     } else {
   3064       CHECK_EQ(test.c, outputs[i]);
   3065     }
   3066     CHECK_EQ(test.d, test.c);
   3067   }
   3068 }
   3069 
   3070 
   3071 TEST(ceil_l) {
   3072   if (IsFp64Mode()) {
   3073     CcTest::InitializeVM();
   3074     Isolate* isolate = CcTest::i_isolate();
   3075     HandleScope scope(isolate);
   3076     MacroAssembler assm(isolate, NULL, 0,
   3077                         v8::internal::CodeObjectRequired::kYes);
   3078     const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
   3079     typedef struct test_float {
   3080       uint32_t isNaN2008;
   3081       double a;
   3082       float b;
   3083       int64_t c;
   3084       int64_t d;
   3085     }Test;
   3086     const int kTableLength = 15;
   3087     double inputs_D[kTableLength] = {
   3088         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3089         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3090         2147483648.0,
   3091         std::numeric_limits<double>::quiet_NaN(),
   3092         std::numeric_limits<double>::infinity()
   3093         };
   3094     float inputs_S[kTableLength] = {
   3095         2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
   3096         -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
   3097         2147483648.0,
   3098         std::numeric_limits<float>::quiet_NaN(),
   3099         std::numeric_limits<float>::infinity()
   3100         };
   3101     double outputs[kTableLength] = {
   3102         3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3103         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3104         2147483648.0, dFPU64InvalidResult,
   3105         dFPU64InvalidResult};
   3106     double outputsNaN2008[kTableLength] = {
   3107         3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
   3108         -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
   3109         2147483648.0,
   3110         0,
   3111         dFPU64InvalidResult};
   3112 
   3113     __ cfc1(t1, FCSR);
   3114     __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008)));
   3115     __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
   3116     __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
   3117     __ ceil_l_d(f8, f4);
   3118     __ ceil_l_s(f10, f6);
   3119     __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
   3120     __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
   3121     __ jr(ra);
   3122     __ nop();
   3123     Test test;
   3124     CodeDesc desc;
   3125     assm.GetCode(&desc);
   3126     Handle<Code> code = isolate->factory()->NewCode(
   3127         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3128     F3 f = FUNCTION_CAST<F3>(code->entry());
   3129     for (int i = 0; i < kTableLength; i++) {
   3130       test.a = inputs_D[i];
   3131       test.b = inputs_S[i];
   3132       (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3133       if ((test.isNaN2008 & kFCSRNaN2008FlagMask) &&
   3134               kArchVariant == kMips32r6) {
   3135         CHECK_EQ(test.c, outputsNaN2008[i]);
   3136       } else {
   3137         CHECK_EQ(test.c, outputs[i]);
   3138       }
   3139       CHECK_EQ(test.d, test.c);
   3140     }
   3141   }
   3142 }
   3143 
   3144 
   3145 TEST(jump_tables1) {
   3146   // Test jump tables with forward jumps.
   3147   CcTest::InitializeVM();
   3148   Isolate* isolate = CcTest::i_isolate();
   3149   HandleScope scope(isolate);
   3150   Assembler assm(isolate, nullptr, 0);
   3151 
   3152   const int kNumCases = 512;
   3153   int values[kNumCases];
   3154   isolate->random_number_generator()->NextBytes(values, sizeof(values));
   3155   Label labels[kNumCases];
   3156 
   3157   __ addiu(sp, sp, -4);
   3158   __ sw(ra, MemOperand(sp));
   3159 
   3160   Label done;
   3161   {
   3162     __ BlockTrampolinePoolFor(kNumCases + 7);
   3163     PredictableCodeSizeScope predictable(
   3164         &assm, (kNumCases + 7) * Assembler::kInstrSize);
   3165     Label here;
   3166 
   3167     __ bal(&here);
   3168     __ nop();
   3169     __ bind(&here);
   3170     __ sll(at, a0, 2);
   3171     __ addu(at, at, ra);
   3172     __ lw(at, MemOperand(at, 5 * Assembler::kInstrSize));
   3173     __ jr(at);
   3174     __ nop();
   3175     for (int i = 0; i < kNumCases; ++i) {
   3176       __ dd(&labels[i]);
   3177     }
   3178   }
   3179 
   3180   for (int i = 0; i < kNumCases; ++i) {
   3181     __ bind(&labels[i]);
   3182     __ lui(v0, (values[i] >> 16) & 0xffff);
   3183     __ ori(v0, v0, values[i] & 0xffff);
   3184     __ b(&done);
   3185     __ nop();
   3186   }
   3187 
   3188   __ bind(&done);
   3189   __ lw(ra, MemOperand(sp));
   3190   __ addiu(sp, sp, 4);
   3191   __ jr(ra);
   3192   __ nop();
   3193 
   3194   CHECK_EQ(assm.UnboundLabelsCount(), 0);
   3195 
   3196   CodeDesc desc;
   3197   assm.GetCode(&desc);
   3198   Handle<Code> code = isolate->factory()->NewCode(
   3199       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3200 #ifdef OBJECT_PRINT
   3201   code->Print(std::cout);
   3202 #endif
   3203   F1 f = FUNCTION_CAST<F1>(code->entry());
   3204   for (int i = 0; i < kNumCases; ++i) {
   3205     int res = reinterpret_cast<int>(
   3206         CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
   3207     ::printf("f(%d) = %d\n", i, res);
   3208     CHECK_EQ(values[i], res);
   3209   }
   3210 }
   3211 
   3212 
   3213 TEST(jump_tables2) {
   3214   // Test jump tables with backward jumps.
   3215   CcTest::InitializeVM();
   3216   Isolate* isolate = CcTest::i_isolate();
   3217   HandleScope scope(isolate);
   3218   Assembler assm(isolate, nullptr, 0);
   3219 
   3220   const int kNumCases = 512;
   3221   int values[kNumCases];
   3222   isolate->random_number_generator()->NextBytes(values, sizeof(values));
   3223   Label labels[kNumCases];
   3224 
   3225   __ addiu(sp, sp, -4);
   3226   __ sw(ra, MemOperand(sp));
   3227 
   3228   Label done, dispatch;
   3229   __ b(&dispatch);
   3230   __ nop();
   3231 
   3232   for (int i = 0; i < kNumCases; ++i) {
   3233     __ bind(&labels[i]);
   3234     __ lui(v0, (values[i] >> 16) & 0xffff);
   3235     __ ori(v0, v0, values[i] & 0xffff);
   3236     __ b(&done);
   3237     __ nop();
   3238   }
   3239 
   3240   __ bind(&dispatch);
   3241   {
   3242     __ BlockTrampolinePoolFor(kNumCases + 7);
   3243     PredictableCodeSizeScope predictable(
   3244         &assm, (kNumCases + 7) * Assembler::kInstrSize);
   3245     Label here;
   3246 
   3247     __ bal(&here);
   3248     __ nop();
   3249     __ bind(&here);
   3250     __ sll(at, a0, 2);
   3251     __ addu(at, at, ra);
   3252     __ lw(at, MemOperand(at, 5 * Assembler::kInstrSize));
   3253     __ jr(at);
   3254     __ nop();
   3255     for (int i = 0; i < kNumCases; ++i) {
   3256       __ dd(&labels[i]);
   3257     }
   3258   }
   3259 
   3260   __ bind(&done);
   3261   __ lw(ra, MemOperand(sp));
   3262   __ addiu(sp, sp, 4);
   3263   __ jr(ra);
   3264   __ nop();
   3265 
   3266   CodeDesc desc;
   3267   assm.GetCode(&desc);
   3268   Handle<Code> code = isolate->factory()->NewCode(
   3269       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3270 #ifdef OBJECT_PRINT
   3271   code->Print(std::cout);
   3272 #endif
   3273   F1 f = FUNCTION_CAST<F1>(code->entry());
   3274   for (int i = 0; i < kNumCases; ++i) {
   3275     int res = reinterpret_cast<int>(
   3276         CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
   3277     ::printf("f(%d) = %d\n", i, res);
   3278     CHECK_EQ(values[i], res);
   3279   }
   3280 }
   3281 
   3282 
   3283 TEST(jump_tables3) {
   3284   // Test jump tables with backward jumps and embedded heap objects.
   3285   CcTest::InitializeVM();
   3286   Isolate* isolate = CcTest::i_isolate();
   3287   HandleScope scope(isolate);
   3288   Assembler assm(isolate, nullptr, 0);
   3289 
   3290   const int kNumCases = 256;
   3291   Handle<Object> values[kNumCases];
   3292   for (int i = 0; i < kNumCases; ++i) {
   3293     double value = isolate->random_number_generator()->NextDouble();
   3294     values[i] = isolate->factory()->NewHeapNumber(value, IMMUTABLE, TENURED);
   3295   }
   3296   Label labels[kNumCases];
   3297   Object* obj;
   3298   int32_t imm32;
   3299 
   3300   __ addiu(sp, sp, -4);
   3301   __ sw(ra, MemOperand(sp));
   3302 
   3303   Label done, dispatch;
   3304   __ b(&dispatch);
   3305 
   3306 
   3307   for (int i = 0; i < kNumCases; ++i) {
   3308     __ bind(&labels[i]);
   3309     obj = *values[i];
   3310     imm32 = reinterpret_cast<intptr_t>(obj);
   3311     __ lui(v0, (imm32 >> 16) & 0xffff);
   3312     __ ori(v0, v0, imm32 & 0xffff);
   3313     __ b(&done);
   3314     __ nop();
   3315   }
   3316 
   3317   __ bind(&dispatch);
   3318   {
   3319     __ BlockTrampolinePoolFor(kNumCases + 7);
   3320     PredictableCodeSizeScope predictable(
   3321         &assm, (kNumCases + 7) * Assembler::kInstrSize);
   3322     Label here;
   3323 
   3324     __ bal(&here);
   3325     __ nop();
   3326     __ bind(&here);
   3327     __ sll(at, a0, 2);
   3328     __ addu(at, at, ra);
   3329     __ lw(at, MemOperand(at, 5 * Assembler::kInstrSize));
   3330     __ jr(at);
   3331     __ nop();
   3332     for (int i = 0; i < kNumCases; ++i) {
   3333       __ dd(&labels[i]);
   3334     }
   3335   }
   3336 
   3337   __ bind(&done);
   3338   __ lw(ra, MemOperand(sp));
   3339   __ addiu(sp, sp, 4);
   3340   __ jr(ra);
   3341   __ nop();
   3342 
   3343   CodeDesc desc;
   3344   assm.GetCode(&desc);
   3345   Handle<Code> code = isolate->factory()->NewCode(
   3346       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3347 #ifdef OBJECT_PRINT
   3348   code->Print(std::cout);
   3349 #endif
   3350   F1 f = FUNCTION_CAST<F1>(code->entry());
   3351   for (int i = 0; i < kNumCases; ++i) {
   3352     Handle<Object> result(
   3353         CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0), isolate);
   3354 #ifdef OBJECT_PRINT
   3355     ::printf("f(%d) = ", i);
   3356     result->Print(std::cout);
   3357     ::printf("\n");
   3358 #endif
   3359     CHECK(values[i].is_identical_to(result));
   3360   }
   3361 }
   3362 
   3363 
   3364 TEST(BITSWAP) {
   3365   // Test BITSWAP
   3366   if (IsMipsArchVariant(kMips32r6)) {
   3367     CcTest::InitializeVM();
   3368     Isolate* isolate = CcTest::i_isolate();
   3369     HandleScope scope(isolate);
   3370 
   3371     typedef struct {
   3372       int32_t r1;
   3373       int32_t r2;
   3374       int32_t r3;
   3375       int32_t r4;
   3376     } T;
   3377     T t;
   3378 
   3379     Assembler assm(isolate, NULL, 0);
   3380 
   3381     __ lw(a2, MemOperand(a0, offsetof(T, r1)));
   3382     __ nop();
   3383     __ bitswap(a1, a2);
   3384     __ sw(a1, MemOperand(a0, offsetof(T, r1)));
   3385 
   3386     __ lw(a2, MemOperand(a0, offsetof(T, r2)));
   3387     __ nop();
   3388     __ bitswap(a1, a2);
   3389     __ sw(a1, MemOperand(a0, offsetof(T, r2)));
   3390 
   3391     __ jr(ra);
   3392     __ nop();
   3393 
   3394     CodeDesc desc;
   3395     assm.GetCode(&desc);
   3396     Handle<Code> code = isolate->factory()->NewCode(
   3397         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3398     F3 f = FUNCTION_CAST<F3>(code->entry());
   3399     t.r1 = 0x781A15C3;
   3400     t.r2 = 0x8B71FCDE;
   3401     Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   3402     USE(dummy);
   3403 
   3404     CHECK_EQ(static_cast<int32_t>(0x1E58A8C3), t.r1);
   3405     CHECK_EQ(static_cast<int32_t>(0xD18E3F7B), t.r2);
   3406   }
   3407 }
   3408 
   3409 
   3410 TEST(class_fmt) {
   3411   if (IsMipsArchVariant(kMips32r6)) {
   3412     // Test CLASS.fmt instruction.
   3413     CcTest::InitializeVM();
   3414     Isolate* isolate = CcTest::i_isolate();
   3415     HandleScope scope(isolate);
   3416 
   3417     typedef struct {
   3418       double dSignalingNan;
   3419       double dQuietNan;
   3420       double dNegInf;
   3421       double dNegNorm;
   3422       double dNegSubnorm;
   3423       double dNegZero;
   3424       double dPosInf;
   3425       double dPosNorm;
   3426       double dPosSubnorm;
   3427       double dPosZero;
   3428       float  fSignalingNan;
   3429       float  fQuietNan;
   3430       float  fNegInf;
   3431       float  fNegNorm;
   3432       float  fNegSubnorm;
   3433       float  fNegZero;
   3434       float  fPosInf;
   3435       float  fPosNorm;
   3436       float  fPosSubnorm;
   3437       float  fPosZero;  } T;
   3438     T t;
   3439 
   3440     // Create a function that accepts &t, and loads, manipulates, and stores
   3441     // the doubles t.a ... t.f.
   3442     MacroAssembler assm(isolate, NULL, 0,
   3443                         v8::internal::CodeObjectRequired::kYes);
   3444 
   3445     __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan)));
   3446     __ class_d(f6, f4);
   3447     __ sdc1(f6, MemOperand(a0, offsetof(T, dSignalingNan)));
   3448 
   3449     __ ldc1(f4, MemOperand(a0, offsetof(T, dQuietNan)));
   3450     __ class_d(f6, f4);
   3451     __ sdc1(f6, MemOperand(a0, offsetof(T, dQuietNan)));
   3452 
   3453     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegInf)));
   3454     __ class_d(f6, f4);
   3455     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegInf)));
   3456 
   3457     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegNorm)));
   3458     __ class_d(f6, f4);
   3459     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegNorm)));
   3460 
   3461     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegSubnorm)));
   3462     __ class_d(f6, f4);
   3463     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegSubnorm)));
   3464 
   3465     __ ldc1(f4, MemOperand(a0, offsetof(T, dNegZero)));
   3466     __ class_d(f6, f4);
   3467     __ sdc1(f6, MemOperand(a0, offsetof(T, dNegZero)));
   3468 
   3469     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosInf)));
   3470     __ class_d(f6, f4);
   3471     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosInf)));
   3472 
   3473     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosNorm)));
   3474     __ class_d(f6, f4);
   3475     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosNorm)));
   3476 
   3477     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosSubnorm)));
   3478     __ class_d(f6, f4);
   3479     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosSubnorm)));
   3480 
   3481     __ ldc1(f4, MemOperand(a0, offsetof(T, dPosZero)));
   3482     __ class_d(f6, f4);
   3483     __ sdc1(f6, MemOperand(a0, offsetof(T, dPosZero)));
   3484 
   3485     // Testing instruction CLASS.S
   3486     __ lwc1(f4, MemOperand(a0, offsetof(T, fSignalingNan)));
   3487     __ class_s(f6, f4);
   3488     __ swc1(f6, MemOperand(a0, offsetof(T, fSignalingNan)));
   3489 
   3490     __ lwc1(f4, MemOperand(a0, offsetof(T, fQuietNan)));
   3491     __ class_s(f6, f4);
   3492     __ swc1(f6, MemOperand(a0, offsetof(T, fQuietNan)));
   3493 
   3494     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegInf)));
   3495     __ class_s(f6, f4);
   3496     __ swc1(f6, MemOperand(a0, offsetof(T, fNegInf)));
   3497 
   3498     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegNorm)));
   3499     __ class_s(f6, f4);
   3500     __ swc1(f6, MemOperand(a0, offsetof(T, fNegNorm)));
   3501 
   3502     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegSubnorm)));
   3503     __ class_s(f6, f4);
   3504     __ swc1(f6, MemOperand(a0, offsetof(T, fNegSubnorm)));
   3505 
   3506     __ lwc1(f4, MemOperand(a0, offsetof(T, fNegZero)));
   3507     __ class_s(f6, f4);
   3508     __ swc1(f6, MemOperand(a0, offsetof(T, fNegZero)));
   3509 
   3510     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosInf)));
   3511     __ class_s(f6, f4);
   3512     __ swc1(f6, MemOperand(a0, offsetof(T, fPosInf)));
   3513 
   3514     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosNorm)));
   3515     __ class_s(f6, f4);
   3516     __ swc1(f6, MemOperand(a0, offsetof(T, fPosNorm)));
   3517 
   3518     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosSubnorm)));
   3519     __ class_s(f6, f4);
   3520     __ swc1(f6, MemOperand(a0, offsetof(T, fPosSubnorm)));
   3521 
   3522     __ lwc1(f4, MemOperand(a0, offsetof(T, fPosZero)));
   3523     __ class_s(f6, f4);
   3524     __ swc1(f6, MemOperand(a0, offsetof(T, fPosZero)));
   3525 
   3526     __ jr(ra);
   3527     __ nop();
   3528 
   3529     CodeDesc desc;
   3530     assm.GetCode(&desc);
   3531     Handle<Code> code = isolate->factory()->NewCode(
   3532         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3533     F3 f = FUNCTION_CAST<F3>(code->entry());
   3534 
   3535     t.dSignalingNan =  std::numeric_limits<double>::signaling_NaN();
   3536     t.dQuietNan = std::numeric_limits<double>::quiet_NaN();
   3537     t.dNegInf       = -1.0 / 0.0;
   3538     t.dNegNorm      = -5.0;
   3539     t.dNegSubnorm   = -DBL_MIN / 2.0;
   3540     t.dNegZero      = -0.0;
   3541     t.dPosInf       = 2.0 / 0.0;
   3542     t.dPosNorm      = 275.35;
   3543     t.dPosSubnorm   = DBL_MIN / 2.0;
   3544     t.dPosZero      = +0.0;
   3545     // Float test values
   3546 
   3547     t.fSignalingNan = std::numeric_limits<float>::signaling_NaN();
   3548     t.fQuietNan     = std::numeric_limits<float>::quiet_NaN();
   3549     t.fNegInf       = -0.5/0.0;
   3550     t.fNegNorm      = -FLT_MIN;
   3551     t.fNegSubnorm   = -FLT_MIN / 1.5;
   3552     t.fNegZero      = -0.0;
   3553     t.fPosInf       = 100000.0 / 0.0;
   3554     t.fPosNorm      = FLT_MAX;
   3555     t.fPosSubnorm   = FLT_MIN / 20.0;
   3556     t.fPosZero      = +0.0;
   3557 
   3558     Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
   3559     USE(dummy);
   3560     // Expected double results.
   3561     CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001);
   3562     CHECK_EQ(bit_cast<int64_t>(t.dQuietNan),     0x002);
   3563     CHECK_EQ(bit_cast<int64_t>(t.dNegInf),       0x004);
   3564     CHECK_EQ(bit_cast<int64_t>(t.dNegNorm),      0x008);
   3565     CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm),   0x010);
   3566     CHECK_EQ(bit_cast<int64_t>(t.dNegZero),      0x020);
   3567     CHECK_EQ(bit_cast<int64_t>(t.dPosInf),       0x040);
   3568     CHECK_EQ(bit_cast<int64_t>(t.dPosNorm),      0x080);
   3569     CHECK_EQ(bit_cast<int64_t>(t.dPosSubnorm),   0x100);
   3570     CHECK_EQ(bit_cast<int64_t>(t.dPosZero),      0x200);
   3571 
   3572     // Expected float results.
   3573     CHECK_EQ(bit_cast<int32_t>(t.fSignalingNan), 0x001);
   3574     CHECK_EQ(bit_cast<int32_t>(t.fQuietNan),     0x002);
   3575     CHECK_EQ(bit_cast<int32_t>(t.fNegInf),       0x004);
   3576     CHECK_EQ(bit_cast<int32_t>(t.fNegNorm),      0x008);
   3577     CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm),   0x010);
   3578     CHECK_EQ(bit_cast<int32_t>(t.fNegZero),      0x020);
   3579     CHECK_EQ(bit_cast<int32_t>(t.fPosInf),       0x040);
   3580     CHECK_EQ(bit_cast<int32_t>(t.fPosNorm),      0x080);
   3581     CHECK_EQ(bit_cast<int32_t>(t.fPosSubnorm),   0x100);
   3582     CHECK_EQ(bit_cast<int32_t>(t.fPosZero),      0x200);
   3583   }
   3584 }
   3585 
   3586 
   3587 TEST(ABS) {
   3588   CcTest::InitializeVM();
   3589   Isolate* isolate = CcTest::i_isolate();
   3590   HandleScope scope(isolate);
   3591   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   3592 
   3593   typedef struct test_float {
   3594     int64_t fir;
   3595     double a;
   3596     float b;
   3597     double fcsr;
   3598   } TestFloat;
   3599 
   3600   TestFloat test;
   3601 
   3602   // Save FIR.
   3603   __ cfc1(a1, FCSR);
   3604   // Disable FPU exceptions.
   3605   __ ctc1(zero_reg, FCSR);
   3606 
   3607   __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
   3608   __ abs_d(f10, f4);
   3609   __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, a)));
   3610 
   3611   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)));
   3612   __ abs_s(f10, f4);
   3613   __ swc1(f10, MemOperand(a0, offsetof(TestFloat, b)));
   3614 
   3615   // Restore FCSR.
   3616   __ ctc1(a1, FCSR);
   3617 
   3618   __ jr(ra);
   3619   __ nop();
   3620 
   3621   CodeDesc desc;
   3622   assm.GetCode(&desc);
   3623   Handle<Code> code = isolate->factory()->NewCode(
   3624       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3625   F3 f = FUNCTION_CAST<F3>(code->entry());
   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   test.a = 2.0;
   3633   test.b = 2.0;
   3634   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3635   CHECK_EQ(test.a, 2.0);
   3636   CHECK_EQ(test.b, 2.0);
   3637 
   3638   // Testing biggest positive number
   3639   test.a = std::numeric_limits<double>::max();
   3640   test.b = std::numeric_limits<float>::max();
   3641   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3642   CHECK_EQ(test.a, std::numeric_limits<double>::max());
   3643   CHECK_EQ(test.b, std::numeric_limits<float>::max());
   3644 
   3645   // Testing smallest negative number
   3646   test.a = -std::numeric_limits<double>::max();  // lowest()
   3647   test.b = -std::numeric_limits<float>::max();   // lowest()
   3648   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3649   CHECK_EQ(test.a, std::numeric_limits<double>::max());
   3650   CHECK_EQ(test.b, std::numeric_limits<float>::max());
   3651 
   3652   // Testing smallest positive number
   3653   test.a = -std::numeric_limits<double>::min();
   3654   test.b = -std::numeric_limits<float>::min();
   3655   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3656   CHECK_EQ(test.a, std::numeric_limits<double>::min());
   3657   CHECK_EQ(test.b, std::numeric_limits<float>::min());
   3658 
   3659   // Testing infinity
   3660   test.a = -std::numeric_limits<double>::max()
   3661           / std::numeric_limits<double>::min();
   3662   test.b = -std::numeric_limits<float>::max()
   3663           / std::numeric_limits<float>::min();
   3664   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3665   CHECK_EQ(test.a, std::numeric_limits<double>::max()
   3666                  / std::numeric_limits<double>::min());
   3667   CHECK_EQ(test.b, std::numeric_limits<float>::max()
   3668                  / std::numeric_limits<float>::min());
   3669 
   3670   test.a = std::numeric_limits<double>::quiet_NaN();
   3671   test.b = std::numeric_limits<float>::quiet_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   test.a = std::numeric_limits<double>::signaling_NaN();
   3677   test.b = std::numeric_limits<float>::signaling_NaN();
   3678   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3679   CHECK_EQ(std::isnan(test.a), true);
   3680   CHECK_EQ(std::isnan(test.b), true);
   3681 }
   3682 
   3683 
   3684 TEST(ADD_FMT) {
   3685   CcTest::InitializeVM();
   3686   Isolate* isolate = CcTest::i_isolate();
   3687   HandleScope scope(isolate);
   3688   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   3689 
   3690   typedef struct test_float {
   3691     double a;
   3692     double b;
   3693     double c;
   3694     float fa;
   3695     float fb;
   3696     float fc;
   3697   } TestFloat;
   3698 
   3699   TestFloat test;
   3700 
   3701   __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
   3702   __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
   3703   __ add_d(f10, f8, f4);
   3704   __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
   3705 
   3706   __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, fa)));
   3707   __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, fb)));
   3708   __ add_s(f10, f8, f4);
   3709   __ swc1(f10, MemOperand(a0, offsetof(TestFloat, fc)));
   3710 
   3711   __ jr(ra);
   3712   __ nop();
   3713 
   3714   CodeDesc desc;
   3715   assm.GetCode(&desc);
   3716   Handle<Code> code = isolate->factory()->NewCode(
   3717       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3718   F3 f = FUNCTION_CAST<F3>(code->entry());
   3719   test.a = 2.0;
   3720   test.b = 3.0;
   3721   test.fa = 2.0;
   3722   test.fb = 3.0;
   3723   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3724   CHECK_EQ(test.c, 5.0);
   3725   CHECK_EQ(test.fc, 5.0);
   3726 
   3727   test.a = std::numeric_limits<double>::max();
   3728   test.b = -std::numeric_limits<double>::max();  // lowest()
   3729   test.fa = std::numeric_limits<float>::max();
   3730   test.fb = -std::numeric_limits<float>::max();  // lowest()
   3731   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3732   CHECK_EQ(test.c, 0.0);
   3733   CHECK_EQ(test.fc, 0.0);
   3734 
   3735   test.a = std::numeric_limits<double>::max();
   3736   test.b = std::numeric_limits<double>::max();
   3737   test.fa = std::numeric_limits<float>::max();
   3738   test.fb = std::numeric_limits<float>::max();
   3739   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3740   CHECK_EQ(std::isfinite(test.c), false);
   3741   CHECK_EQ(std::isfinite(test.fc), false);
   3742 
   3743   test.a = 5.0;
   3744   test.b = std::numeric_limits<double>::signaling_NaN();
   3745   test.fa = 5.0;
   3746   test.fb = std::numeric_limits<float>::signaling_NaN();
   3747   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3748   CHECK_EQ(std::isnan(test.c), true);
   3749   CHECK_EQ(std::isnan(test.fc), true);
   3750 }
   3751 
   3752 
   3753 TEST(C_COND_FMT) {
   3754   if ((IsMipsArchVariant(kMips32r1)) || (IsMipsArchVariant(kMips32r2))) {
   3755     CcTest::InitializeVM();
   3756     Isolate* isolate = CcTest::i_isolate();
   3757     HandleScope scope(isolate);
   3758     MacroAssembler assm(isolate, NULL, 0,
   3759                         v8::internal::CodeObjectRequired::kYes);
   3760 
   3761     typedef struct test_float {
   3762       double dOp1;
   3763       double dOp2;
   3764       uint32_t dF;
   3765       uint32_t dUn;
   3766       uint32_t dEq;
   3767       uint32_t dUeq;
   3768       uint32_t dOlt;
   3769       uint32_t dUlt;
   3770       uint32_t dOle;
   3771       uint32_t dUle;
   3772       float fOp1;
   3773       float fOp2;
   3774       uint32_t fF;
   3775       uint32_t fUn;
   3776       uint32_t fEq;
   3777       uint32_t fUeq;
   3778       uint32_t fOlt;
   3779       uint32_t fUlt;
   3780       uint32_t fOle;
   3781       uint32_t fUle;
   3782     } TestFloat;
   3783 
   3784     TestFloat test;
   3785 
   3786     __ li(t1, 1);
   3787 
   3788     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
   3789     __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
   3790 
   3791     __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
   3792     __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
   3793 
   3794     __ mov(t2, zero_reg);
   3795     __ mov(t3, zero_reg);
   3796     __ c_d(F, f4, f6, 0);
   3797     __ c_s(F, f14, f16, 2);
   3798     __ movt(t2, t1, 0);
   3799     __ movt(t3, t1, 2);
   3800     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dF)) );
   3801     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fF)) );
   3802 
   3803     __ mov(t2, zero_reg);
   3804     __ mov(t3, zero_reg);
   3805     __ c_d(UN, f4, f6, 2);
   3806     __ c_s(UN, f14, f16, 4);
   3807     __ movt(t2, t1, 2);
   3808     __ movt(t3, t1, 4);
   3809     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUn)) );
   3810     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUn)) );
   3811 
   3812     __ mov(t2, zero_reg);
   3813     __ mov(t3, zero_reg);
   3814     __ c_d(EQ, f4, f6, 4);
   3815     __ c_s(EQ, f14, f16, 6);
   3816     __ movt(t2, t1, 4);
   3817     __ movt(t3, t1, 6);
   3818     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dEq)) );
   3819     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fEq)) );
   3820 
   3821     __ mov(t2, zero_reg);
   3822     __ mov(t3, zero_reg);
   3823     __ c_d(UEQ, f4, f6, 6);
   3824     __ c_s(UEQ, f14, f16, 0);
   3825     __ movt(t2, t1, 6);
   3826     __ movt(t3, t1, 0);
   3827     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
   3828     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUeq)) );
   3829 
   3830     __ mov(t2, zero_reg);
   3831     __ mov(t3, zero_reg);
   3832     __ c_d(OLT, f4, f6, 0);
   3833     __ c_s(OLT, f14, f16, 2);
   3834     __ movt(t2, t1, 0);
   3835     __ movt(t3, t1, 2);
   3836     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
   3837     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOlt)) );
   3838 
   3839     __ mov(t2, zero_reg);
   3840     __ mov(t3, zero_reg);
   3841     __ c_d(ULT, f4, f6, 2);
   3842     __ c_s(ULT, f14, f16, 4);
   3843     __ movt(t2, t1, 2);
   3844     __ movt(t3, t1, 4);
   3845     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
   3846     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUlt)) );
   3847 
   3848     __ mov(t2, zero_reg);
   3849     __ mov(t3, zero_reg);
   3850     __ c_d(OLE, f4, f6, 4);
   3851     __ c_s(OLE, f14, f16, 6);
   3852     __ movt(t2, t1, 4);
   3853     __ movt(t3, t1, 6);
   3854     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOle)) );
   3855     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOle)) );
   3856 
   3857     __ mov(t2, zero_reg);
   3858     __ mov(t3, zero_reg);
   3859     __ c_d(ULE, f4, f6, 6);
   3860     __ c_s(ULE, f14, f16, 0);
   3861     __ movt(t2, t1, 6);
   3862     __ movt(t3, t1, 0);
   3863     __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUle)) );
   3864     __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUle)) );
   3865 
   3866     __ jr(ra);
   3867     __ nop();
   3868 
   3869     CodeDesc desc;
   3870     assm.GetCode(&desc);
   3871     Handle<Code> code = isolate->factory()->NewCode(
   3872         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   3873     F3 f = FUNCTION_CAST<F3>(code->entry());
   3874     test.dOp1 = 2.0;
   3875     test.dOp2 = 3.0;
   3876     test.fOp1 = 2.0;
   3877     test.fOp2 = 3.0;
   3878     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3879     CHECK_EQ(test.dF, 0U);
   3880     CHECK_EQ(test.dUn, 0U);
   3881     CHECK_EQ(test.dEq, 0U);
   3882     CHECK_EQ(test.dUeq, 0U);
   3883     CHECK_EQ(test.dOlt, 1U);
   3884     CHECK_EQ(test.dUlt, 1U);
   3885     CHECK_EQ(test.dOle, 1U);
   3886     CHECK_EQ(test.dUle, 1U);
   3887     CHECK_EQ(test.fF, 0U);
   3888     CHECK_EQ(test.fUn, 0U);
   3889     CHECK_EQ(test.fEq, 0U);
   3890     CHECK_EQ(test.fUeq, 0U);
   3891     CHECK_EQ(test.fOlt, 1U);
   3892     CHECK_EQ(test.fUlt, 1U);
   3893     CHECK_EQ(test.fOle, 1U);
   3894     CHECK_EQ(test.fUle, 1U);
   3895 
   3896     test.dOp1 = std::numeric_limits<double>::max();
   3897     test.dOp2 = std::numeric_limits<double>::min();
   3898     test.fOp1 = std::numeric_limits<float>::min();
   3899     test.fOp2 = -std::numeric_limits<float>::max();  // lowest()
   3900     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3901     CHECK_EQ(test.dF, 0U);
   3902     CHECK_EQ(test.dUn, 0U);
   3903     CHECK_EQ(test.dEq, 0U);
   3904     CHECK_EQ(test.dUeq, 0U);
   3905     CHECK_EQ(test.dOlt, 0U);
   3906     CHECK_EQ(test.dUlt, 0U);
   3907     CHECK_EQ(test.dOle, 0U);
   3908     CHECK_EQ(test.dUle, 0U);
   3909     CHECK_EQ(test.fF, 0U);
   3910     CHECK_EQ(test.fUn, 0U);
   3911     CHECK_EQ(test.fEq, 0U);
   3912     CHECK_EQ(test.fUeq, 0U);
   3913     CHECK_EQ(test.fOlt, 0U);
   3914     CHECK_EQ(test.fUlt, 0U);
   3915     CHECK_EQ(test.fOle, 0U);
   3916     CHECK_EQ(test.fUle, 0U);
   3917 
   3918     test.dOp1 = -std::numeric_limits<double>::max();  // lowest()
   3919     test.dOp2 = -std::numeric_limits<double>::max();  // lowest()
   3920     test.fOp1 = std::numeric_limits<float>::max();
   3921     test.fOp2 = std::numeric_limits<float>::max();
   3922     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3923     CHECK_EQ(test.dF, 0U);
   3924     CHECK_EQ(test.dUn, 0U);
   3925     CHECK_EQ(test.dEq, 1U);
   3926     CHECK_EQ(test.dUeq, 1U);
   3927     CHECK_EQ(test.dOlt, 0U);
   3928     CHECK_EQ(test.dUlt, 0U);
   3929     CHECK_EQ(test.dOle, 1U);
   3930     CHECK_EQ(test.dUle, 1U);
   3931     CHECK_EQ(test.fF, 0U);
   3932     CHECK_EQ(test.fUn, 0U);
   3933     CHECK_EQ(test.fEq, 1U);
   3934     CHECK_EQ(test.fUeq, 1U);
   3935     CHECK_EQ(test.fOlt, 0U);
   3936     CHECK_EQ(test.fUlt, 0U);
   3937     CHECK_EQ(test.fOle, 1U);
   3938     CHECK_EQ(test.fUle, 1U);
   3939 
   3940     test.dOp1 = std::numeric_limits<double>::quiet_NaN();
   3941     test.dOp2 = 0.0;
   3942     test.fOp1 = std::numeric_limits<float>::quiet_NaN();
   3943     test.fOp2 = 0.0;
   3944     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   3945     CHECK_EQ(test.dF, 0U);
   3946     CHECK_EQ(test.dUn, 1U);
   3947     CHECK_EQ(test.dEq, 0U);
   3948     CHECK_EQ(test.dUeq, 1U);
   3949     CHECK_EQ(test.dOlt, 0U);
   3950     CHECK_EQ(test.dUlt, 1U);
   3951     CHECK_EQ(test.dOle, 0U);
   3952     CHECK_EQ(test.dUle, 1U);
   3953     CHECK_EQ(test.fF, 0U);
   3954     CHECK_EQ(test.fUn, 1U);
   3955     CHECK_EQ(test.fEq, 0U);
   3956     CHECK_EQ(test.fUeq, 1U);
   3957     CHECK_EQ(test.fOlt, 0U);
   3958     CHECK_EQ(test.fUlt, 1U);
   3959     CHECK_EQ(test.fOle, 0U);
   3960     CHECK_EQ(test.fUle, 1U);
   3961   }
   3962 }
   3963 
   3964 
   3965 TEST(CMP_COND_FMT) {
   3966   if (IsMipsArchVariant(kMips32r6)) {
   3967     CcTest::InitializeVM();
   3968     Isolate* isolate = CcTest::i_isolate();
   3969     HandleScope scope(isolate);
   3970     MacroAssembler assm(isolate, NULL, 0,
   3971                         v8::internal::CodeObjectRequired::kYes);
   3972 
   3973     typedef struct test_float {
   3974       double dOp1;
   3975       double dOp2;
   3976       double dF;
   3977       double dUn;
   3978       double dEq;
   3979       double dUeq;
   3980       double dOlt;
   3981       double dUlt;
   3982       double dOle;
   3983       double dUle;
   3984       double dOr;
   3985       double dUne;
   3986       double dNe;
   3987       float fOp1;
   3988       float fOp2;
   3989       float fF;
   3990       float fUn;
   3991       float fEq;
   3992       float fUeq;
   3993       float fOlt;
   3994       float fUlt;
   3995       float fOle;
   3996       float fUle;
   3997       float fOr;
   3998       float fUne;
   3999       float fNe;
   4000     } TestFloat;
   4001 
   4002     TestFloat test;
   4003 
   4004     __ li(t1, 1);
   4005 
   4006     __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
   4007     __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
   4008 
   4009     __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
   4010     __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
   4011 
   4012     __ cmp_d(F, f2, f4, f6);
   4013     __ cmp_s(F, f12, f14, f16);
   4014     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dF)) );
   4015     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fF)) );
   4016 
   4017     __ cmp_d(UN, f2, f4, f6);
   4018     __ cmp_s(UN, f12, f14, f16);
   4019     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUn)) );
   4020     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUn)) );
   4021 
   4022     __ cmp_d(EQ, f2, f4, f6);
   4023     __ cmp_s(EQ, f12, f14, f16);
   4024     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dEq)) );
   4025     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fEq)) );
   4026 
   4027     __ cmp_d(UEQ, f2, f4, f6);
   4028     __ cmp_s(UEQ, f12, f14, f16);
   4029     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
   4030     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUeq)) );
   4031 
   4032     __ cmp_d(LT, f2, f4, f6);
   4033     __ cmp_s(LT, f12, f14, f16);
   4034     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
   4035     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOlt)) );
   4036 
   4037     __ cmp_d(ULT, f2, f4, f6);
   4038     __ cmp_s(ULT, f12, f14, f16);
   4039     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
   4040     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUlt)) );
   4041 
   4042     __ cmp_d(LE, f2, f4, f6);
   4043     __ cmp_s(LE, f12, f14, f16);
   4044     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOle)) );
   4045     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOle)) );
   4046 
   4047     __ cmp_d(ULE, f2, f4, f6);
   4048     __ cmp_s(ULE, f12, f14, f16);
   4049     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUle)) );
   4050     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUle)) );
   4051 
   4052     __ cmp_d(ORD, f2, f4, f6);
   4053     __ cmp_s(ORD, f12, f14, f16);
   4054     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOr)) );
   4055     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOr)) );
   4056 
   4057     __ cmp_d(UNE, f2, f4, f6);
   4058     __ cmp_s(UNE, f12, f14, f16);
   4059     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUne)) );
   4060     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUne)) );
   4061 
   4062     __ cmp_d(NE, f2, f4, f6);
   4063     __ cmp_s(NE, f12, f14, f16);
   4064     __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dNe)) );
   4065     __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fNe)) );
   4066 
   4067     __ jr(ra);
   4068     __ nop();
   4069 
   4070     CodeDesc desc;
   4071     assm.GetCode(&desc);
   4072     Handle<Code> code = isolate->factory()->NewCode(
   4073         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4074     F3 f = FUNCTION_CAST<F3>(code->entry());
   4075     uint64_t dTrue  = 0xFFFFFFFFFFFFFFFF;
   4076     uint64_t dFalse = 0x0000000000000000;
   4077     uint32_t fTrue  = 0xFFFFFFFF;
   4078     uint32_t fFalse = 0x00000000;
   4079 
   4080     test.dOp1 = 2.0;
   4081     test.dOp2 = 3.0;
   4082     test.fOp1 = 2.0;
   4083     test.fOp2 = 3.0;
   4084     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4085     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4086     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
   4087     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
   4088     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
   4089     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue);
   4090     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
   4091     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
   4092     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
   4093     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
   4094     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
   4095     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
   4096     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4097     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
   4098     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
   4099     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
   4100     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue);
   4101     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
   4102     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
   4103     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
   4104 
   4105     test.dOp1 = std::numeric_limits<double>::max();
   4106     test.dOp2 = std::numeric_limits<double>::min();
   4107     test.fOp1 = std::numeric_limits<float>::min();
   4108     test.fOp2 = -std::numeric_limits<float>::max();  // lowest()
   4109     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4110     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4111     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
   4112     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
   4113     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
   4114     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
   4115     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
   4116     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
   4117     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse);
   4118     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
   4119     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
   4120     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
   4121     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4122     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
   4123     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
   4124     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
   4125     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
   4126     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
   4127     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
   4128     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse);
   4129 
   4130     test.dOp1 = -std::numeric_limits<double>::max();  // lowest()
   4131     test.dOp2 = -std::numeric_limits<double>::max();  // lowest()
   4132     test.fOp1 = std::numeric_limits<float>::max();
   4133     test.fOp2 = std::numeric_limits<float>::max();
   4134     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4135     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4136     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
   4137     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue);
   4138     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
   4139     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
   4140     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
   4141     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
   4142     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
   4143     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
   4144     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse);
   4145     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
   4146     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4147     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
   4148     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue);
   4149     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
   4150     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
   4151     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
   4152     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
   4153     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
   4154 
   4155     test.dOp1 = std::numeric_limits<double>::quiet_NaN();
   4156     test.dOp2 = 0.0;
   4157     test.fOp1 = std::numeric_limits<float>::quiet_NaN();
   4158     test.fOp2 = 0.0;
   4159     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4160     CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
   4161     CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue);
   4162     CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
   4163     CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
   4164     CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
   4165     CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
   4166     CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
   4167     CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
   4168     CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse);
   4169     CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
   4170     CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
   4171     CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
   4172     CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue);
   4173     CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
   4174     CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
   4175     CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
   4176     CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
   4177     CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
   4178     CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
   4179   }
   4180 }
   4181 
   4182 
   4183 TEST(CVT) {
   4184   CcTest::InitializeVM();
   4185   Isolate* isolate = CcTest::i_isolate();
   4186   HandleScope scope(isolate);
   4187   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4188 
   4189   typedef struct test_float {
   4190     float    cvt_d_s_in;
   4191     double   cvt_d_s_out;
   4192     int32_t  cvt_d_w_in;
   4193     double   cvt_d_w_out;
   4194     int64_t  cvt_d_l_in;
   4195     double   cvt_d_l_out;
   4196 
   4197     float    cvt_l_s_in;
   4198     int64_t  cvt_l_s_out;
   4199     double   cvt_l_d_in;
   4200     int64_t  cvt_l_d_out;
   4201 
   4202     double   cvt_s_d_in;
   4203     float    cvt_s_d_out;
   4204     int32_t  cvt_s_w_in;
   4205     float    cvt_s_w_out;
   4206     int64_t  cvt_s_l_in;
   4207     float    cvt_s_l_out;
   4208 
   4209     float    cvt_w_s_in;
   4210     int32_t  cvt_w_s_out;
   4211     double   cvt_w_d_in;
   4212     int32_t  cvt_w_d_out;
   4213   } TestFloat;
   4214 
   4215   TestFloat test;
   4216 
   4217   // Save FCSR.
   4218   __ cfc1(a1, FCSR);
   4219   // Disable FPU exceptions.
   4220   __ ctc1(zero_reg, FCSR);
   4221 
   4222 #define GENERATE_CVT_TEST(x, y, z) \
   4223   __ y##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_in))); \
   4224   __ x(f0, f0); \
   4225   __ nop(); \
   4226   __ z##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_out)));
   4227 
   4228   GENERATE_CVT_TEST(cvt_d_s, lw, sd)
   4229   GENERATE_CVT_TEST(cvt_d_w, lw, sd)
   4230   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4231          IsFp64Mode()) {
   4232     GENERATE_CVT_TEST(cvt_d_l, ld, sd)
   4233   }
   4234 
   4235   if (IsFp64Mode()) {
   4236     GENERATE_CVT_TEST(cvt_l_s, lw, sd)
   4237     GENERATE_CVT_TEST(cvt_l_d, ld, sd)
   4238   }
   4239 
   4240   GENERATE_CVT_TEST(cvt_s_d, ld, sw)
   4241   GENERATE_CVT_TEST(cvt_s_w, lw, sw)
   4242   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4243          IsFp64Mode()) {
   4244     GENERATE_CVT_TEST(cvt_s_l, ld, sw)
   4245   }
   4246 
   4247   GENERATE_CVT_TEST(cvt_w_s, lw, sw)
   4248   GENERATE_CVT_TEST(cvt_w_d, ld, sw)
   4249 
   4250   // Restore FCSR.
   4251   __ ctc1(a1, FCSR);
   4252 
   4253   __ jr(ra);
   4254   __ nop();
   4255 
   4256   CodeDesc desc;
   4257   assm.GetCode(&desc);
   4258   Handle<Code> code = isolate->factory()->NewCode(
   4259       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4260   F3 f = FUNCTION_CAST<F3>(code->entry());
   4261 
   4262   test.cvt_d_s_in = -0.51;
   4263   test.cvt_d_w_in = -1;
   4264   test.cvt_d_l_in = -1;
   4265   test.cvt_l_s_in = -0.51;
   4266   test.cvt_l_d_in = -0.51;
   4267   test.cvt_s_d_in = -0.51;
   4268   test.cvt_s_w_in = -1;
   4269   test.cvt_s_l_in = -1;
   4270   test.cvt_w_s_in = -0.51;
   4271   test.cvt_w_d_in = -0.51;
   4272 
   4273   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4274   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4275   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4276   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4277          IsFp64Mode()) {
   4278     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4279   }
   4280   if (IsFp64Mode()) {
   4281     CHECK_EQ(test.cvt_l_s_out, -1);
   4282     CHECK_EQ(test.cvt_l_d_out, -1);
   4283   }
   4284   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4285   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4286   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4287          IsFp64Mode()) {
   4288     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4289   }
   4290   CHECK_EQ(test.cvt_w_s_out, -1);
   4291   CHECK_EQ(test.cvt_w_d_out, -1);
   4292 
   4293 
   4294   test.cvt_d_s_in = 0.49;
   4295   test.cvt_d_w_in = 1;
   4296   test.cvt_d_l_in = 1;
   4297   test.cvt_l_s_in = 0.49;
   4298   test.cvt_l_d_in = 0.49;
   4299   test.cvt_s_d_in = 0.49;
   4300   test.cvt_s_w_in = 1;
   4301   test.cvt_s_l_in = 1;
   4302   test.cvt_w_s_in = 0.49;
   4303   test.cvt_w_d_in = 0.49;
   4304 
   4305   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4306   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4307   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4308   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4309          IsFp64Mode()) {
   4310     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4311   }
   4312   if (IsFp64Mode()) {
   4313     CHECK_EQ(test.cvt_l_s_out, 0);
   4314     CHECK_EQ(test.cvt_l_d_out, 0);
   4315   }
   4316   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4317   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4318   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4319          IsFp64Mode()) {
   4320     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4321   }
   4322   CHECK_EQ(test.cvt_w_s_out, 0);
   4323   CHECK_EQ(test.cvt_w_d_out, 0);
   4324 
   4325   test.cvt_d_s_in = std::numeric_limits<float>::max();
   4326   test.cvt_d_w_in = std::numeric_limits<int32_t>::max();
   4327   test.cvt_d_l_in = std::numeric_limits<int64_t>::max();
   4328   test.cvt_l_s_in = std::numeric_limits<float>::max();
   4329   test.cvt_l_d_in = std::numeric_limits<double>::max();
   4330   test.cvt_s_d_in = std::numeric_limits<double>::max();
   4331   test.cvt_s_w_in = std::numeric_limits<int32_t>::max();
   4332   test.cvt_s_l_in = std::numeric_limits<int64_t>::max();
   4333   test.cvt_w_s_in = std::numeric_limits<float>::max();
   4334   test.cvt_w_d_in = std::numeric_limits<double>::max();
   4335 
   4336   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4337   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4338   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4339   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4340          IsFp64Mode()) {
   4341     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4342   }
   4343   if (IsFp64Mode()) {
   4344     CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max());
   4345     CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max());
   4346   }
   4347   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4348   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4349   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4350          IsFp64Mode()) {
   4351     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4352   }
   4353   CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max());
   4354   CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max());
   4355 
   4356 
   4357   test.cvt_d_s_in = -std::numeric_limits<float>::max();   // lowest()
   4358   test.cvt_d_w_in = std::numeric_limits<int32_t>::min();  // lowest()
   4359   test.cvt_d_l_in = std::numeric_limits<int64_t>::min();  // lowest()
   4360   test.cvt_l_s_in = -std::numeric_limits<float>::max();   // lowest()
   4361   test.cvt_l_d_in = -std::numeric_limits<double>::max();  // lowest()
   4362   test.cvt_s_d_in = -std::numeric_limits<double>::max();  // lowest()
   4363   test.cvt_s_w_in = std::numeric_limits<int32_t>::min();  // lowest()
   4364   test.cvt_s_l_in = std::numeric_limits<int64_t>::min();  // lowest()
   4365   test.cvt_w_s_in = -std::numeric_limits<float>::max();   // lowest()
   4366   test.cvt_w_d_in = -std::numeric_limits<double>::max();  // lowest()
   4367 
   4368   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4369   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4370   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4371   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4372          IsFp64Mode()) {
   4373     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4374   }
   4375   // The returned value when converting from fixed-point to float-point
   4376   // is not consistent between board, simulator and specification
   4377   // in this test case, therefore modifying the test
   4378   if (IsFp64Mode()) {
   4379     CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() ||
   4380          test.cvt_l_s_out == std::numeric_limits<int64_t>::max());
   4381     CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() ||
   4382           test.cvt_l_d_out == std::numeric_limits<int64_t>::max());
   4383   }
   4384   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4385   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4386   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4387          IsFp64Mode()) {
   4388     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4389   }
   4390   CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() ||
   4391         test.cvt_w_s_out == std::numeric_limits<int32_t>::max());
   4392   CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() ||
   4393         test.cvt_w_d_out == std::numeric_limits<int32_t>::max());
   4394 
   4395 
   4396   test.cvt_d_s_in = std::numeric_limits<float>::min();
   4397   test.cvt_d_w_in = std::numeric_limits<int32_t>::min();
   4398   test.cvt_d_l_in = std::numeric_limits<int64_t>::min();
   4399   test.cvt_l_s_in = std::numeric_limits<float>::min();
   4400   test.cvt_l_d_in = std::numeric_limits<double>::min();
   4401   test.cvt_s_d_in = std::numeric_limits<double>::min();
   4402   test.cvt_s_w_in = std::numeric_limits<int32_t>::min();
   4403   test.cvt_s_l_in = std::numeric_limits<int64_t>::min();
   4404   test.cvt_w_s_in = std::numeric_limits<float>::min();
   4405   test.cvt_w_d_in = std::numeric_limits<double>::min();
   4406 
   4407   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4408   CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
   4409   CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
   4410   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4411          IsFp64Mode()) {
   4412     CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
   4413   }
   4414   if (IsFp64Mode()) {
   4415     CHECK_EQ(test.cvt_l_s_out, 0);
   4416     CHECK_EQ(test.cvt_l_d_out, 0);
   4417   }
   4418   CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
   4419   CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
   4420   if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
   4421          IsFp64Mode()) {
   4422     CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
   4423   }
   4424   CHECK_EQ(test.cvt_w_s_out, 0);
   4425   CHECK_EQ(test.cvt_w_d_out, 0);
   4426 }
   4427 
   4428 
   4429 TEST(DIV_FMT) {
   4430   CcTest::InitializeVM();
   4431   Isolate* isolate = CcTest::i_isolate();
   4432   HandleScope scope(isolate);
   4433   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4434 
   4435   typedef struct test {
   4436     double dOp1;
   4437     double dOp2;
   4438     double dRes;
   4439     float  fOp1;
   4440     float  fOp2;
   4441     float  fRes;
   4442   } Test;
   4443 
   4444   Test test;
   4445 
   4446   // Save FCSR.
   4447   __ cfc1(a1, FCSR);
   4448   // Disable FPU exceptions.
   4449   __ ctc1(zero_reg, FCSR);
   4450 
   4451   __ ldc1(f4, MemOperand(a0, offsetof(Test, dOp1)) );
   4452   __ ldc1(f2, MemOperand(a0, offsetof(Test, dOp2)) );
   4453   __ nop();
   4454   __ div_d(f6, f4, f2);
   4455   __ sdc1(f6, MemOperand(a0, offsetof(Test, dRes)) );
   4456 
   4457   __ lwc1(f4, MemOperand(a0, offsetof(Test, fOp1)) );
   4458   __ lwc1(f2, MemOperand(a0, offsetof(Test, fOp2)) );
   4459   __ nop();
   4460   __ div_s(f6, f4, f2);
   4461   __ swc1(f6, MemOperand(a0, offsetof(Test, fRes)) );
   4462 
   4463     // Restore FCSR.
   4464   __ ctc1(a1, FCSR);
   4465 
   4466   __ jr(ra);
   4467   __ nop();
   4468 
   4469   CodeDesc desc;
   4470   assm.GetCode(&desc);
   4471   Handle<Code> code = isolate->factory()->NewCode(
   4472       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4473 
   4474   F3 f = FUNCTION_CAST<F3>(code->entry());
   4475 
   4476   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4477 
   4478   const int test_size = 3;
   4479 
   4480   double dOp1[test_size] = {
   4481     5.0,
   4482     DBL_MAX,
   4483     DBL_MAX,
   4484   };
   4485   double dOp2[test_size] = {
   4486     2.0,
   4487     2.0,
   4488     -DBL_MAX,
   4489   };
   4490   double dRes[test_size] = {
   4491     2.5,
   4492     DBL_MAX / 2.0,
   4493     -1.0,
   4494   };
   4495   float fOp1[test_size] = {
   4496     5.0,
   4497     FLT_MAX,
   4498     FLT_MAX,
   4499   };
   4500   float fOp2[test_size] = {
   4501     2.0,
   4502     2.0,
   4503     -FLT_MAX,
   4504   };
   4505   float fRes[test_size] = {
   4506     2.5,
   4507     FLT_MAX / 2.0,
   4508     -1.0,
   4509   };
   4510 
   4511   for (int i = 0; i < test_size; i++) {
   4512     test.dOp1 = dOp1[i];
   4513     test.dOp2 = dOp2[i];
   4514     test.fOp1 = fOp1[i];
   4515     test.fOp2 = fOp2[i];
   4516 
   4517     (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4518     CHECK_EQ(test.dRes, dRes[i]);
   4519     CHECK_EQ(test.fRes, fRes[i]);
   4520   }
   4521 
   4522   test.dOp1 = DBL_MAX;
   4523   test.dOp2 = -0.0;
   4524   test.fOp1 = FLT_MAX;
   4525   test.fOp2 = -0.0;
   4526 
   4527   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4528   CHECK_EQ(false, std::isfinite(test.dRes));
   4529   CHECK_EQ(false, std::isfinite(test.fRes));
   4530 
   4531   test.dOp1 = 0.0;
   4532   test.dOp2 = -0.0;
   4533   test.fOp1 = 0.0;
   4534   test.fOp2 = -0.0;
   4535 
   4536   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4537   CHECK_EQ(true, std::isnan(test.dRes));
   4538   CHECK_EQ(true, std::isnan(test.fRes));
   4539 
   4540   test.dOp1 = std::numeric_limits<double>::quiet_NaN();
   4541   test.dOp2 = -5.0;
   4542   test.fOp1 = std::numeric_limits<float>::quiet_NaN();
   4543   test.fOp2 = -5.0;
   4544 
   4545   (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
   4546   CHECK_EQ(true, std::isnan(test.dRes));
   4547   CHECK_EQ(true, std::isnan(test.fRes));
   4548 }
   4549 
   4550 
   4551 uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) {
   4552   Isolate* isolate = CcTest::i_isolate();
   4553   HandleScope scope(isolate);
   4554 
   4555   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4556 
   4557   __ align(v0, a0, a1, bp);
   4558   __ jr(ra);
   4559   __ nop();
   4560 
   4561   CodeDesc desc;
   4562   assm.GetCode(&desc);
   4563   Handle<Code> code = isolate->factory()->NewCode(
   4564       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4565 
   4566   F2 f = FUNCTION_CAST<F2>(code->entry());
   4567 
   4568   uint32_t res = reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(
   4569       isolate, f, rs_value, rt_value, 0, 0, 0));
   4570 
   4571   return res;
   4572 }
   4573 
   4574 
   4575 TEST(r6_align) {
   4576   if (IsMipsArchVariant(kMips32r6)) {
   4577     CcTest::InitializeVM();
   4578 
   4579     struct TestCaseAlign {
   4580       uint32_t  rs_value;
   4581       uint32_t  rt_value;
   4582       uint8_t   bp;
   4583       uint32_t  expected_res;
   4584     };
   4585 
   4586     struct TestCaseAlign tc[] = {
   4587       // rs_value,    rt_value,    bp,  expected_res
   4588       { 0x11223344,   0xaabbccdd,   0,  0xaabbccdd },
   4589       { 0x11223344,   0xaabbccdd,   1,  0xbbccdd11 },
   4590       { 0x11223344,   0xaabbccdd,   2,  0xccdd1122 },
   4591       { 0x11223344,   0xaabbccdd,   3,  0xdd112233 },
   4592     };
   4593 
   4594     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign);
   4595     for (size_t i = 0; i < nr_test_cases; ++i) {
   4596       CHECK_EQ(tc[i].expected_res, run_align(tc[i].rs_value,
   4597                                              tc[i].rt_value, tc[i].bp));
   4598     }
   4599   }
   4600 }
   4601 
   4602 uint32_t PC;  // The program counter.
   4603 
   4604 uint32_t run_aluipc(int16_t offset) {
   4605   Isolate* isolate = CcTest::i_isolate();
   4606   HandleScope scope(isolate);
   4607 
   4608   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4609 
   4610   __ aluipc(v0, offset);
   4611   __ jr(ra);
   4612   __ nop();
   4613 
   4614   CodeDesc desc;
   4615   assm.GetCode(&desc);
   4616   Handle<Code> code = isolate->factory()->NewCode(
   4617       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4618 
   4619   F2 f = FUNCTION_CAST<F2>(code->entry());
   4620   PC = (uint32_t) f;  // Set the program counter.
   4621 
   4622   uint32_t res = reinterpret_cast<uint32_t>(
   4623       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4624 
   4625   return res;
   4626 }
   4627 
   4628 
   4629 TEST(r6_aluipc) {
   4630   if (IsMipsArchVariant(kMips32r6)) {
   4631     CcTest::InitializeVM();
   4632 
   4633     struct TestCaseAluipc {
   4634       int16_t   offset;
   4635     };
   4636 
   4637     struct TestCaseAluipc tc[] = {
   4638       // offset
   4639       { -32768 },   // 0x8000
   4640       {     -1 },   // 0xFFFF
   4641       {      0 },
   4642       {      1 },
   4643       {  32767 },   // 0x7FFF
   4644     };
   4645 
   4646     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
   4647     for (size_t i = 0; i < nr_test_cases; ++i) {
   4648       PC = 0;
   4649       uint32_t res = run_aluipc(tc[i].offset);
   4650       // Now, the program_counter (PC) is set.
   4651       uint32_t expected_res = ~0x0FFFF & (PC + (tc[i].offset << 16));
   4652       CHECK_EQ(expected_res, res);
   4653     }
   4654   }
   4655 }
   4656 
   4657 
   4658 uint32_t run_auipc(int16_t offset) {
   4659   Isolate* isolate = CcTest::i_isolate();
   4660   HandleScope scope(isolate);
   4661 
   4662   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4663 
   4664   __ auipc(v0, offset);
   4665   __ jr(ra);
   4666   __ nop();
   4667 
   4668   CodeDesc desc;
   4669   assm.GetCode(&desc);
   4670   Handle<Code> code = isolate->factory()->NewCode(
   4671       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4672 
   4673   F2 f = FUNCTION_CAST<F2>(code->entry());
   4674   PC = (uint32_t) f;  // Set the program counter.
   4675 
   4676   uint32_t res = reinterpret_cast<uint32_t>(
   4677       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4678 
   4679   return res;
   4680 }
   4681 
   4682 
   4683 TEST(r6_auipc) {
   4684   if (IsMipsArchVariant(kMips32r6)) {
   4685     CcTest::InitializeVM();
   4686 
   4687     struct TestCaseAuipc {
   4688       int16_t   offset;
   4689     };
   4690 
   4691     struct TestCaseAuipc tc[] = {
   4692       // offset
   4693       { -32768 },   // 0x8000
   4694       {     -1 },   // 0xFFFF
   4695       {      0 },
   4696       {      1 },
   4697       {  32767 },   // 0x7FFF
   4698     };
   4699 
   4700     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
   4701     for (size_t i = 0; i < nr_test_cases; ++i) {
   4702       PC = 0;
   4703       uint32_t res = run_auipc(tc[i].offset);
   4704       // Now, the program_counter (PC) is set.
   4705       uint32_t expected_res = PC + (tc[i].offset << 16);
   4706       CHECK_EQ(expected_res, res);
   4707     }
   4708   }
   4709 }
   4710 
   4711 
   4712 uint32_t run_lwpc(int offset) {
   4713   Isolate* isolate = CcTest::i_isolate();
   4714   HandleScope scope(isolate);
   4715 
   4716   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4717 
   4718   // 256k instructions; 2^8k
   4719   // addiu t7, t0, 0xffff;  (0x250fffff)
   4720   // ...
   4721   // addiu t4, t0, 0x0000;  (0x250c0000)
   4722   uint32_t addiu_start_1 = 0x25000000;
   4723   for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
   4724     uint32_t addiu_new = addiu_start_1 + i;
   4725     __ dd(addiu_new);
   4726   }
   4727 
   4728   __ lwpc(t8, offset);         // offset 0; 0xef080000 (t8 register)
   4729   __ mov(v0, t8);
   4730 
   4731   // 256k instructions; 2^8k
   4732   // addiu t0, t0, 0x0000;  (0x25080000)
   4733   // ...
   4734   // addiu t3, t0, 0xffff;  (0x250bffff)
   4735   uint32_t addiu_start_2 = 0x25000000;
   4736   for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
   4737     uint32_t addiu_new = addiu_start_2 + i;
   4738     __ dd(addiu_new);
   4739   }
   4740 
   4741   __ jr(ra);
   4742   __ nop();
   4743 
   4744   CodeDesc desc;
   4745   assm.GetCode(&desc);
   4746   Handle<Code> code = isolate->factory()->NewCode(
   4747       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4748 
   4749   F2 f = FUNCTION_CAST<F2>(code->entry());
   4750 
   4751   uint32_t res = reinterpret_cast<uint32_t>(
   4752       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4753 
   4754   return res;
   4755 }
   4756 
   4757 
   4758 TEST(r6_lwpc) {
   4759   if (IsMipsArchVariant(kMips32r6)) {
   4760     CcTest::InitializeVM();
   4761 
   4762     struct TestCaseLwpc {
   4763       int      offset;
   4764       uint32_t expected_res;
   4765     };
   4766 
   4767     struct TestCaseLwpc tc[] = {
   4768       // offset,   expected_res
   4769       { -262144,    0x250fffff },   // offset 0x40000
   4770       {      -4,    0x250c0003 },
   4771       {      -1,    0x250c0000 },
   4772       {       0,    0xef080000 },
   4773       {       1,    0x03001025 },   // mov(v0, t8)
   4774       {       2,    0x25080000 },
   4775       {       4,    0x25080002 },
   4776       {  262143,    0x250bfffd },   // offset 0x3ffff
   4777     };
   4778 
   4779     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
   4780     for (size_t i = 0; i < nr_test_cases; ++i) {
   4781       uint32_t res = run_lwpc(tc[i].offset);
   4782       CHECK_EQ(tc[i].expected_res, res);
   4783     }
   4784   }
   4785 }
   4786 
   4787 
   4788 uint32_t run_jic(int16_t offset) {
   4789   Isolate* isolate = CcTest::i_isolate();
   4790   HandleScope scope(isolate);
   4791 
   4792   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4793 
   4794   Label get_program_counter, stop_execution;
   4795   __ push(ra);
   4796   __ li(v0, 0);
   4797   __ li(t1, 0x66);
   4798 
   4799   __ addiu(v0, v0, 0x1);        // <-- offset = -32
   4800   __ addiu(v0, v0, 0x2);
   4801   __ addiu(v0, v0, 0x10);
   4802   __ addiu(v0, v0, 0x20);
   4803   __ beq(v0, t1, &stop_execution);
   4804   __ nop();
   4805 
   4806   __ bal(&get_program_counter);  // t0 <- program counter
   4807   __ nop();
   4808   __ jic(t0, offset);
   4809 
   4810   __ addiu(v0, v0, 0x100);
   4811   __ addiu(v0, v0, 0x200);
   4812   __ addiu(v0, v0, 0x1000);
   4813   __ addiu(v0, v0, 0x2000);   // <--- offset = 16
   4814   __ pop(ra);
   4815   __ jr(ra);
   4816   __ nop();
   4817 
   4818   __ bind(&get_program_counter);
   4819   __ mov(t0, ra);
   4820   __ jr(ra);
   4821   __ nop();
   4822 
   4823   __ bind(&stop_execution);
   4824   __ pop(ra);
   4825   __ jr(ra);
   4826   __ nop();
   4827 
   4828   CodeDesc desc;
   4829   assm.GetCode(&desc);
   4830   Handle<Code> code = isolate->factory()->NewCode(
   4831       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4832 
   4833   F2 f = FUNCTION_CAST<F2>(code->entry());
   4834 
   4835   uint32_t res = reinterpret_cast<uint32_t>(
   4836       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   4837 
   4838   return res;
   4839 }
   4840 
   4841 
   4842 TEST(r6_jic) {
   4843   if (IsMipsArchVariant(kMips32r6)) {
   4844     CcTest::InitializeVM();
   4845 
   4846     struct TestCaseJic {
   4847       // As rt will be used t0 register which will have value of
   4848       // the program counter for the jic instruction.
   4849       int16_t   offset;
   4850       uint32_t  expected_res;
   4851     };
   4852 
   4853     struct TestCaseJic tc[] = {
   4854       // offset,   expected_result
   4855       {      16,            0x2033 },
   4856       {       4,            0x3333 },
   4857       {     -32,              0x66 },
   4858     };
   4859 
   4860     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
   4861     for (size_t i = 0; i < nr_test_cases; ++i) {
   4862       uint32_t res = run_jic(tc[i].offset);
   4863       CHECK_EQ(tc[i].expected_res, res);
   4864     }
   4865   }
   4866 }
   4867 
   4868 
   4869 uint64_t run_beqzc(int32_t value, int32_t offset) {
   4870   Isolate* isolate = CcTest::i_isolate();
   4871   HandleScope scope(isolate);
   4872 
   4873   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4874 
   4875   Label stop_execution;
   4876   __ li(v0, 0);
   4877   __ li(t1, 0x66);
   4878 
   4879   __ addiu(v0, v0, 0x1);        // <-- offset = -32
   4880   __ addiu(v0, v0, 0x2);
   4881   __ addiu(v0, v0, 0x10);
   4882   __ addiu(v0, v0, 0x20);
   4883   __ beq(v0, t1, &stop_execution);
   4884   __ nop();
   4885 
   4886   __ beqzc(a0, offset);         // BEQZC rs, offset
   4887 
   4888   __ addiu(v0, v0,    0x1);
   4889   __ addiu(v0, v0,  0x100);
   4890   __ addiu(v0, v0,  0x200);
   4891   __ addiu(v0, v0, 0x1000);
   4892   __ addiu(v0, v0, 0x2000);   // <--- offset = 16
   4893   __ jr(ra);
   4894   __ nop();
   4895 
   4896   __ bind(&stop_execution);
   4897   __ jr(ra);
   4898   __ nop();
   4899 
   4900   CodeDesc desc;
   4901   assm.GetCode(&desc);
   4902   Handle<Code> code = isolate->factory()->NewCode(
   4903       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4904 
   4905   F2 f = FUNCTION_CAST<F2>(code->entry());
   4906 
   4907   uint32_t res = reinterpret_cast<uint32_t>(
   4908       CALL_GENERATED_CODE(isolate, f, value, 0, 0, 0, 0));
   4909 
   4910   return res;
   4911 }
   4912 
   4913 
   4914 TEST(r6_beqzc) {
   4915   if (IsMipsArchVariant(kMips32r6)) {
   4916     CcTest::InitializeVM();
   4917 
   4918     struct TestCaseBeqzc {
   4919       uint32_t  value;
   4920       int32_t   offset;
   4921       uint32_t  expected_res;
   4922     };
   4923 
   4924     struct TestCaseBeqzc tc[] = {
   4925       //    value,    offset,   expected_res
   4926       {       0x0,        -8,           0x66 },
   4927       {       0x0,         0,         0x3334 },
   4928       {       0x0,         1,         0x3333 },
   4929       {     0xabc,         1,         0x3334 },
   4930       {       0x0,         4,         0x2033 },
   4931     };
   4932 
   4933     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
   4934     for (size_t i = 0; i < nr_test_cases; ++i) {
   4935       uint32_t res = run_beqzc(tc[i].value, tc[i].offset);
   4936       CHECK_EQ(tc[i].expected_res, res);
   4937     }
   4938   }
   4939 }
   4940 
   4941 
   4942 uint32_t run_jialc(int16_t offset) {
   4943   Isolate* isolate = CcTest::i_isolate();
   4944   HandleScope scope(isolate);
   4945 
   4946   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   4947 
   4948   Label main_block, get_program_counter;
   4949   __ push(ra);
   4950   __ li(v0, 0);
   4951   __ beq(v0, v0, &main_block);
   4952   __ nop();
   4953 
   4954   // Block 1
   4955   __ addiu(v0, v0, 0x1);        // <-- offset = -40
   4956   __ addiu(v0, v0, 0x2);
   4957   __ jr(ra);
   4958   __ nop();
   4959 
   4960   // Block 2
   4961   __ addiu(v0, v0, 0x10);        // <-- offset = -24
   4962   __ addiu(v0, v0, 0x20);
   4963   __ jr(ra);
   4964   __ nop();
   4965 
   4966   // Block 3 (Main)
   4967   __ bind(&main_block);
   4968   __ bal(&get_program_counter);  // t0 <- program counter
   4969   __ nop();
   4970   __ jialc(t0, offset);
   4971   __ addiu(v0, v0, 0x4);
   4972   __ pop(ra);
   4973   __ jr(ra);
   4974   __ nop();
   4975 
   4976   // Block 4
   4977   __ addiu(v0, v0, 0x100);      // <-- offset = 20
   4978   __ addiu(v0, v0, 0x200);
   4979   __ jr(ra);
   4980   __ nop();
   4981 
   4982   // Block 5
   4983   __ addiu(v0, v0, 0x1000);     // <--- offset = 36
   4984   __ addiu(v0, v0, 0x2000);
   4985   __ jr(ra);
   4986   __ nop();
   4987 
   4988   __ bind(&get_program_counter);
   4989   __ mov(t0, ra);
   4990   __ jr(ra);
   4991   __ nop();
   4992 
   4993 
   4994   CodeDesc desc;
   4995   assm.GetCode(&desc);
   4996   Handle<Code> code = isolate->factory()->NewCode(
   4997       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   4998 
   4999   F2 f = FUNCTION_CAST<F2>(code->entry());
   5000 
   5001   uint32_t res = reinterpret_cast<uint32_t>(
   5002       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5003 
   5004   return res;
   5005 }
   5006 
   5007 
   5008 TEST(r6_jialc) {
   5009   if (IsMipsArchVariant(kMips32r6)) {
   5010     CcTest::InitializeVM();
   5011 
   5012     struct TestCaseJialc {
   5013       int16_t   offset;
   5014       uint32_t  expected_res;
   5015     };
   5016 
   5017     struct TestCaseJialc tc[] = {
   5018       // offset,   expected_res
   5019       {     -40,            0x7 },
   5020       {     -24,           0x34 },
   5021       {      20,          0x304 },
   5022       {      36,         0x3004 }
   5023     };
   5024 
   5025     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
   5026     for (size_t i = 0; i < nr_test_cases; ++i) {
   5027       uint32_t res = run_jialc(tc[i].offset);
   5028       CHECK_EQ(tc[i].expected_res, res);
   5029     }
   5030   }
   5031 }
   5032 
   5033 static uint32_t run_addiupc(int32_t imm19) {
   5034   Isolate* isolate = CcTest::i_isolate();
   5035   HandleScope scope(isolate);
   5036 
   5037   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5038 
   5039   __ addiupc(v0, imm19);
   5040   __ jr(ra);
   5041   __ nop();
   5042 
   5043   CodeDesc desc;
   5044   assm.GetCode(&desc);
   5045   Handle<Code> code = isolate->factory()->NewCode(
   5046       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5047 
   5048   F2 f = FUNCTION_CAST<F2>(code->entry());
   5049   PC = (uint32_t) f;  // Set the program counter.
   5050 
   5051   uint32_t rs = reinterpret_cast<uint32_t>(
   5052       CALL_GENERATED_CODE(isolate, f, imm19, 0, 0, 0, 0));
   5053 
   5054   return rs;
   5055 }
   5056 
   5057 
   5058 TEST(r6_addiupc) {
   5059   if (IsMipsArchVariant(kMips32r6)) {
   5060     CcTest::InitializeVM();
   5061 
   5062     struct TestCaseAddiupc {
   5063       int32_t   imm19;
   5064     };
   5065 
   5066     TestCaseAddiupc tc[] = {
   5067         //  imm19
   5068         {-262144},  // 0x40000
   5069         {-1},       // 0x7FFFF
   5070         {0},
   5071         {1},      // 0x00001
   5072         {262143}  // 0x3FFFF
   5073     };
   5074 
   5075     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
   5076     for (size_t i = 0; i < nr_test_cases; ++i) {
   5077       PC = 0;
   5078       uint32_t res = run_addiupc(tc[i].imm19);
   5079       // Now, the program_counter (PC) is set.
   5080       uint32_t expected_res = PC + (tc[i].imm19 << 2);
   5081       CHECK_EQ(expected_res, res);
   5082     }
   5083   }
   5084 }
   5085 
   5086 
   5087 int32_t run_bc(int32_t offset) {
   5088   Isolate* isolate = CcTest::i_isolate();
   5089   HandleScope scope(isolate);
   5090 
   5091   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5092 
   5093   Label continue_1, stop_execution;
   5094   __ push(ra);
   5095   __ li(v0, 0);
   5096   __ li(t8, 0);
   5097   __ li(t9, 2);   // A condition for stopping execution.
   5098 
   5099   for (int32_t i = -100; i <= -11; ++i) {
   5100     __ addiu(v0, v0, 1);
   5101   }
   5102 
   5103   __ addiu(t8, t8, 1);              // -10
   5104 
   5105   __ beq(t8, t9, &stop_execution);  // -9
   5106   __ nop();                         // -8
   5107   __ beq(t8, t8, &continue_1);      // -7
   5108   __ nop();                         // -6
   5109 
   5110   __ bind(&stop_execution);
   5111   __ pop(ra);                       // -5, -4
   5112   __ jr(ra);                        // -3
   5113   __ nop();                         // -2
   5114 
   5115   __ bind(&continue_1);
   5116   __ bc(offset);                    // -1
   5117 
   5118   for (int32_t i = 0; i <= 99; ++i) {
   5119     __ addiu(v0, v0, 1);
   5120   }
   5121 
   5122   __ pop(ra);
   5123   __ jr(ra);
   5124   __ nop();
   5125 
   5126   CodeDesc desc;
   5127   assm.GetCode(&desc);
   5128   Handle<Code> code = isolate->factory()->NewCode(
   5129       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5130 
   5131   F2 f = FUNCTION_CAST<F2>(code->entry());
   5132 
   5133   int32_t res = reinterpret_cast<int32_t>(
   5134       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5135 
   5136   return res;
   5137 }
   5138 
   5139 
   5140 TEST(r6_bc) {
   5141   if (IsMipsArchVariant(kMips32r6)) {
   5142     CcTest::InitializeVM();
   5143 
   5144     struct TestCaseBc {
   5145       int32_t   offset;
   5146       int32_t   expected_res;
   5147     };
   5148 
   5149     struct TestCaseBc tc[] = {
   5150       //    offset,   expected_result
   5151       {       -100,   (abs(-100) - 10) * 2        },
   5152       {        -11,   (abs(-100) - 10 + 1)        },
   5153       {          0,   (abs(-100) - 10 + 1 + 99)   },
   5154       {          1,   (abs(-100) - 10 + 99)       },
   5155       {         99,   (abs(-100) - 10 + 1)        },
   5156     };
   5157 
   5158     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
   5159     for (size_t i = 0; i < nr_test_cases; ++i) {
   5160       int32_t res = run_bc(tc[i].offset);
   5161       CHECK_EQ(tc[i].expected_res, res);
   5162     }
   5163   }
   5164 }
   5165 
   5166 
   5167 int32_t run_balc(int32_t offset) {
   5168   Isolate* isolate = CcTest::i_isolate();
   5169   HandleScope scope(isolate);
   5170 
   5171   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5172 
   5173   Label continue_1, stop_execution;
   5174   __ push(ra);
   5175   __ li(v0, 0);
   5176   __ li(t8, 0);
   5177   __ li(t9, 2);   // A condition for stopping execution.
   5178 
   5179   __ beq(t8, t8, &continue_1);
   5180   __ nop();
   5181 
   5182   uint32_t instruction_addiu = 0x24420001;  // addiu v0, v0, 1
   5183   for (int32_t i = -117; i <= -57; ++i) {
   5184     __ dd(instruction_addiu);
   5185   }
   5186   __ jr(ra);                        // -56
   5187   __ nop();                         // -55
   5188 
   5189   for (int32_t i = -54; i <= -4; ++i) {
   5190     __ dd(instruction_addiu);
   5191   }
   5192   __ jr(ra);                        // -3
   5193   __ nop();                         // -2
   5194 
   5195   __ bind(&continue_1);
   5196   __ balc(offset);                    // -1
   5197 
   5198   __ pop(ra);                         // 0, 1
   5199   __ jr(ra);                          // 2
   5200   __ nop();                           // 3
   5201 
   5202   for (int32_t i = 4; i <= 44; ++i) {
   5203     __ dd(instruction_addiu);
   5204   }
   5205   __ jr(ra);
   5206   __ nop();
   5207 
   5208   CodeDesc desc;
   5209   assm.GetCode(&desc);
   5210   Handle<Code> code = isolate->factory()->NewCode(
   5211       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5212 
   5213   F2 f = FUNCTION_CAST<F2>(code->entry());
   5214 
   5215   int32_t res = reinterpret_cast<int32_t>(
   5216       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5217 
   5218   return res;
   5219 }
   5220 
   5221 
   5222 uint32_t run_aui(uint32_t rs, uint16_t offset) {
   5223   Isolate* isolate = CcTest::i_isolate();
   5224   HandleScope scope(isolate);
   5225 
   5226   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5227 
   5228   __ li(t0, rs);
   5229   __ aui(v0, t0, offset);
   5230   __ jr(ra);
   5231   __ nop();
   5232 
   5233   CodeDesc desc;
   5234   assm.GetCode(&desc);
   5235   Handle<Code> code = isolate->factory()->NewCode(
   5236       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5237 
   5238   F2 f = FUNCTION_CAST<F2>(code->entry());
   5239 
   5240   uint32_t res =
   5241     reinterpret_cast<uint32_t>
   5242         (CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5243 
   5244   return res;
   5245 }
   5246 
   5247 
   5248 TEST(r6_aui) {
   5249   if (IsMipsArchVariant(kMips32r6)) {
   5250     CcTest::InitializeVM();
   5251 
   5252     struct TestCaseAui {
   5253       uint32_t   rs;
   5254       uint16_t   offset;
   5255       uint32_t   ref_res;
   5256     };
   5257 
   5258     struct TestCaseAui tc[] = {
   5259       // input, offset, result
   5260       {0xfffeffff, 1, 0xffffffff},
   5261       {0xffffffff, 0, 0xffffffff},
   5262       {0, 0xffff, 0xffff0000},
   5263       {0x0008ffff, 0xfff7, 0xffffffff},
   5264       {32767, 32767, 0x7fff7fff},
   5265       // overflow cases
   5266       {0xffffffff, 0x1, 0x0000ffff},
   5267       {0xffffffff, 0xffff, 0xfffeffff},
   5268     };
   5269 
   5270     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAui);
   5271     for (size_t i = 0; i < nr_test_cases; ++i) {
   5272       PC = 0;
   5273       uint32_t res = run_aui(tc[i].rs, tc[i].offset);
   5274       CHECK_EQ(tc[i].ref_res, res);
   5275     }
   5276   }
   5277 }
   5278 
   5279 
   5280 TEST(r6_balc) {
   5281   if (IsMipsArchVariant(kMips32r6)) {
   5282     CcTest::InitializeVM();
   5283 
   5284     struct TestCaseBalc {
   5285       int32_t   offset;
   5286       int32_t   expected_res;
   5287     };
   5288 
   5289     struct TestCaseBalc tc[] = {
   5290       //  offset,   expected_result
   5291       {     -117,   61  },
   5292       {      -54,   51  },
   5293       {        0,   0   },
   5294       {        4,   41  },
   5295     };
   5296 
   5297     size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
   5298     for (size_t i = 0; i < nr_test_cases; ++i) {
   5299       int32_t res = run_balc(tc[i].offset);
   5300       CHECK_EQ(tc[i].expected_res, res);
   5301     }
   5302   }
   5303 }
   5304 
   5305 
   5306 uint32_t run_bal(int16_t offset) {
   5307   Isolate* isolate = CcTest::i_isolate();
   5308   HandleScope scope(isolate);
   5309 
   5310   MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
   5311 
   5312   __ mov(t0, ra);
   5313   __ bal(offset);       // Equivalent for "BGEZAL zero_reg, offset".
   5314   __ nop();
   5315 
   5316   __ mov(ra, t0);
   5317   __ jr(ra);
   5318   __ nop();
   5319 
   5320   __ li(v0, 1);
   5321   __ jr(ra);
   5322   __ nop();
   5323 
   5324   CodeDesc desc;
   5325   assm.GetCode(&desc);
   5326   Handle<Code> code = isolate->factory()->NewCode(
   5327       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5328 
   5329   F2 f = FUNCTION_CAST<F2>(code->entry());
   5330 
   5331   uint32_t res = reinterpret_cast<uint32_t>(
   5332       CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
   5333 
   5334   return res;
   5335 }
   5336 
   5337 
   5338 TEST(bal) {
   5339   CcTest::InitializeVM();
   5340 
   5341   struct TestCaseBal {
   5342     int16_t  offset;
   5343     uint32_t  expected_res;
   5344   };
   5345 
   5346   struct TestCaseBal tc[] = {
   5347     // offset, expected_res
   5348     {       4,      1 },
   5349   };
   5350 
   5351   size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBal);
   5352   for (size_t i = 0; i < nr_test_cases; ++i) {
   5353     CHECK_EQ(tc[i].expected_res, run_bal(tc[i].offset));
   5354   }
   5355 }
   5356 
   5357 
   5358 TEST(Trampoline) {
   5359   // Private member of Assembler class.
   5360   static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
   5361 
   5362   CcTest::InitializeVM();
   5363   Isolate* isolate = CcTest::i_isolate();
   5364   HandleScope scope(isolate);
   5365 
   5366   MacroAssembler assm(isolate, nullptr, 0,
   5367                       v8::internal::CodeObjectRequired::kYes);
   5368   Label done;
   5369   size_t nr_calls = kMaxBranchOffset / (2 * Instruction::kInstrSize) + 2;
   5370 
   5371   for (size_t i = 0; i < nr_calls; ++i) {
   5372     __ BranchShort(&done, eq, a0, Operand(a1));
   5373   }
   5374   __ bind(&done);
   5375   __ Ret(USE_DELAY_SLOT);
   5376   __ mov(v0, zero_reg);
   5377 
   5378   CodeDesc desc;
   5379   assm.GetCode(&desc);
   5380   Handle<Code> code = isolate->factory()->NewCode(
   5381       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
   5382   F2 f = FUNCTION_CAST<F2>(code->entry());
   5383 
   5384   int32_t res = reinterpret_cast<int32_t>(
   5385       CALL_GENERATED_CODE(isolate, f, 42, 42, 0, 0, 0));
   5386   CHECK_EQ(res, 0);
   5387 }
   5388 
   5389 #undef __
   5390