summaryrefslogtreecommitdiff
path: root/src/3rdparty/v8/test/cctest/test-assembler-mips.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/test/cctest/test-assembler-mips.cc')
-rw-r--r--src/3rdparty/v8/test/cctest/test-assembler-mips.cc1295
1 files changed, 0 insertions, 1295 deletions
diff --git a/src/3rdparty/v8/test/cctest/test-assembler-mips.cc b/src/3rdparty/v8/test/cctest/test-assembler-mips.cc
deleted file mode 100644
index 2abe6db..0000000
--- a/src/3rdparty/v8/test/cctest/test-assembler-mips.cc
+++ /dev/null
@@ -1,1295 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
-
-#include "disassembler.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "mips/macro-assembler-mips.h"
-#include "mips/simulator-mips.h"
-
-#include "cctest.h"
-
-using namespace v8::internal;
-
-
-// Define these function prototypes to match JSEntryFunction in execution.cc.
-typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
-typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
-typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
-
-
-static v8::Persistent<v8::Context> env;
-
-
-static void InitializeVM() {
- // Disable compilation of natives.
- FLAG_disable_native_files = true;
-
- if (env.IsEmpty()) {
- env = v8::Context::New();
- }
-}
-
-
-#define __ assm.
-
-
-TEST(MIPS0) {
- InitializeVM();
- v8::HandleScope scope;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
-
- // Addition.
- __ addu(v0, a0, a1);
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
- int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
- ::printf("f() = %d\n", res);
- CHECK_EQ(0xabc, res);
-}
-
-
-TEST(MIPS1) {
- InitializeVM();
- v8::HandleScope scope;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
- Label L, C;
-
- __ mov(a1, a0);
- __ li(v0, 0);
- __ b(&C);
- __ nop();
-
- __ bind(&L);
- __ addu(v0, v0, a1);
- __ addiu(a1, a1, -1);
-
- __ bind(&C);
- __ xori(v1, a1, 0);
- __ Branch(&L, ne, v1, Operand(0));
- __ nop();
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
- int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
- ::printf("f() = %d\n", res);
- CHECK_EQ(1275, res);
-}
-
-
-TEST(MIPS2) {
- InitializeVM();
- v8::HandleScope scope;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
-
- Label exit, error;
-
- // ----- Test all instructions.
-
- // Test lui, ori, and addiu, used in the li pseudo-instruction.
- // This way we can then safely load registers with chosen values.
-
- __ ori(t0, zero_reg, 0);
- __ lui(t0, 0x1234);
- __ ori(t0, t0, 0);
- __ ori(t0, t0, 0x0f0f);
- __ ori(t0, t0, 0xf0f0);
- __ addiu(t1, t0, 1);
- __ addiu(t2, t1, -0x10);
-
- // Load values in temporary registers.
- __ li(t0, 0x00000004);
- __ li(t1, 0x00001234);
- __ li(t2, 0x12345678);
- __ li(t3, 0x7fffffff);
- __ li(t4, 0xfffffffc);
- __ li(t5, 0xffffedcc);
- __ li(t6, 0xedcba988);
- __ li(t7, 0x80000000);
-
- // SPECIAL class.
- __ srl(v0, t2, 8); // 0x00123456
- __ sll(v0, v0, 11); // 0x91a2b000
- __ sra(v0, v0, 3); // 0xf2345600
- __ srav(v0, v0, t0); // 0xff234560
- __ sllv(v0, v0, t0); // 0xf2345600
- __ srlv(v0, v0, t0); // 0x0f234560
- __ Branch(&error, ne, v0, Operand(0x0f234560));
- __ nop();
-
- __ addu(v0, t0, t1); // 0x00001238
- __ subu(v0, v0, t0); // 0x00001234
- __ Branch(&error, ne, v0, Operand(0x00001234));
- __ nop();
- __ addu(v1, t3, t0);
- __ Branch(&error, ne, v1, Operand(0x80000003));
- __ nop();
- __ subu(v1, t7, t0); // 0x7ffffffc
- __ Branch(&error, ne, v1, Operand(0x7ffffffc));
- __ nop();
-
- __ and_(v0, t1, t2); // 0x00001230
- __ or_(v0, v0, t1); // 0x00001234
- __ xor_(v0, v0, t2); // 0x1234444c
- __ nor(v0, v0, t2); // 0xedcba987
- __ Branch(&error, ne, v0, Operand(0xedcba983));
- __ nop();
-
- __ slt(v0, t7, t3);
- __ Branch(&error, ne, v0, Operand(0x1));
- __ nop();
- __ sltu(v0, t7, t3);
- __ Branch(&error, ne, v0, Operand(0x0));
- __ nop();
- // End of SPECIAL class.
-
- __ addiu(v0, zero_reg, 0x7421); // 0x00007421
- __ addiu(v0, v0, -0x1); // 0x00007420
- __ addiu(v0, v0, -0x20); // 0x00007400
- __ Branch(&error, ne, v0, Operand(0x00007400));
- __ nop();
- __ addiu(v1, t3, 0x1); // 0x80000000
- __ Branch(&error, ne, v1, Operand(0x80000000));
- __ nop();
-
- __ slti(v0, t1, 0x00002000); // 0x1
- __ slti(v0, v0, 0xffff8000); // 0x0
- __ Branch(&error, ne, v0, Operand(0x0));
- __ nop();
- __ sltiu(v0, t1, 0x00002000); // 0x1
- __ sltiu(v0, v0, 0x00008000); // 0x1
- __ Branch(&error, ne, v0, Operand(0x1));
- __ nop();
-
- __ andi(v0, t1, 0xf0f0); // 0x00001030
- __ ori(v0, v0, 0x8a00); // 0x00009a30
- __ xori(v0, v0, 0x83cc); // 0x000019fc
- __ Branch(&error, ne, v0, Operand(0x000019fc));
- __ nop();
- __ lui(v1, 0x8123); // 0x81230000
- __ Branch(&error, ne, v1, Operand(0x81230000));
- __ nop();
-
- // Bit twiddling instructions & conditional moves.
- // Uses t0-t7 as set above.
- __ Clz(v0, t0); // 29
- __ Clz(v1, t1); // 19
- __ addu(v0, v0, v1); // 48
- __ Clz(v1, t2); // 3
- __ addu(v0, v0, v1); // 51
- __ Clz(v1, t7); // 0
- __ addu(v0, v0, v1); // 51
- __ Branch(&error, ne, v0, Operand(51));
- __ Movn(a0, t3, t0); // Move a0<-t3 (t0 is NOT 0).
- __ Ins(a0, t1, 12, 8); // 0x7ff34fff
- __ Branch(&error, ne, a0, Operand(0x7ff34fff));
- __ Movz(a0, t6, t7); // a0 not updated (t7 is NOT 0).
- __ Ext(a1, a0, 8, 12); // 0x34f
- __ Branch(&error, ne, a1, Operand(0x34f));
- __ Movz(a0, t6, v1); // a0<-t6, v0 is 0, from 8 instr back.
- __ Branch(&error, ne, a0, Operand(t6));
-
- // Everything was correctly executed. Load the expected result.
- __ li(v0, 0x31415926);
- __ b(&exit);
- __ nop();
-
- __ bind(&error);
- // Got an error. Return a wrong result.
- __ li(v0, 666);
-
- __ bind(&exit);
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
- int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
- ::printf("f() = %d\n", res);
- CHECK_EQ(0x31415926, res);
-}
-
-
-TEST(MIPS3) {
- // Test floating point instructions.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- double a;
- double b;
- double c;
- double d;
- double e;
- double f;
- double g;
- double h;
- double i;
- } T;
- T t;
-
- // Create a function that accepts &t, and loads, manipulates, and stores
- // the doubles t.a ... t.f.
- MacroAssembler assm(Isolate::Current(), NULL, 0);
- Label L, C;
-
- if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
- __ add_d(f8, f4, f6);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
-
- __ mov_d(f10, f8); // c
- __ neg_d(f12, f6); // -b
- __ sub_d(f10, f10, f12);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
-
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
-
- __ li(t0, 120);
- __ mtc1(t0, f14);
- __ cvt_d_w(f14, f14); // f14 = 120.0.
- __ mul_d(f10, f10, f14);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
-
- __ div_d(f12, f10, f4);
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44.
-
- __ sqrt_d(f14, f12);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
- // g = sqrt(f) = 10.97451593465515908537
-
- if (kArchVariant == kMips32r2) {
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
- __ madd_d(f14, f6, f4, f6);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
- }
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.a = 1.5e14;
- t.b = 2.75e11;
- t.c = 0.0;
- t.d = 0.0;
- t.e = 0.0;
- t.f = 0.0;
- t.h = 1.5;
- t.i = 2.75;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
- CHECK_EQ(1.5e14, t.a);
- CHECK_EQ(1.5e14, t.b);
- CHECK_EQ(1.50275e14, t.c);
- CHECK_EQ(1.50550e14, t.d);
- CHECK_EQ(1.8066e16, t.e);
- CHECK_EQ(120.44, t.f);
- CHECK_EQ(10.97451593465515908537, t.g);
- CHECK_EQ(6.875, t.h);
- }
-}
-
-
-TEST(MIPS4) {
- // Test moves between floating point and integer registers.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- double a;
- double b;
- double c;
- } T;
- T t;
-
- Assembler assm(Isolate::Current(), NULL, 0);
- Label L, C;
-
- if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
-
- // Swap f4 and f6, by using four integer registers, t0-t3.
- __ mfc1(t0, f4);
- __ mfc1(t1, f5);
- __ mfc1(t2, f6);
- __ mfc1(t3, f7);
-
- __ mtc1(t0, f6);
- __ mtc1(t1, f7);
- __ mtc1(t2, f4);
- __ mtc1(t3, f5);
-
- // Store the swapped f4 and f5 back to memory.
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.a = 1.5e22;
- t.b = 2.75e11;
- t.c = 17.17;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(2.75e11, t.a);
- CHECK_EQ(2.75e11, t.b);
- CHECK_EQ(1.5e22, t.c);
- }
-}
-
-
-TEST(MIPS5) {
- // Test conversions between doubles and integers.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- double a;
- double b;
- int i;
- int j;
- } T;
- T t;
-
- Assembler assm(Isolate::Current(), NULL, 0);
- Label L, C;
-
- if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
-
- // Load all structure elements to registers.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
-
- // Convert double in f4 to int in element i.
- __ cvt_w_d(f8, f4);
- __ mfc1(t2, f8);
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) );
-
- // Convert double in f6 to int in element j.
- __ cvt_w_d(f10, f6);
- __ mfc1(t3, f10);
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) );
-
- // Convert int in original i (t0) to double in a.
- __ mtc1(t0, f12);
- __ cvt_d_w(f0, f12);
- __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
-
- // Convert int in original j (t1) to double in b.
- __ mtc1(t1, f14);
- __ cvt_d_w(f2, f14);
- __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.a = 1.5e4;
- t.b = 2.75e8;
- t.i = 12345678;
- t.j = -100000;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(12345678.0, t.a);
- CHECK_EQ(-100000.0, t.b);
- CHECK_EQ(15000, t.i);
- CHECK_EQ(275000000, t.j);
- }
-}
-
-
-TEST(MIPS6) {
- // Test simple memory loads and stores.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- uint32_t ui;
- int32_t si;
- int32_t r1;
- int32_t r2;
- int32_t r3;
- int32_t r4;
- int32_t r5;
- int32_t r6;
- } T;
- T t;
-
- Assembler assm(Isolate::Current(), NULL, 0);
- Label L, C;
-
- // Basic word load/store.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r1)) );
-
- // lh with positive data.
- __ lh(t1, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, r2)) );
-
- // lh with negative data.
- __ lh(t2, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, r3)) );
-
- // lhu with negative data.
- __ lhu(t3, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, r4)) );
-
- // lb with negative data.
- __ lb(t4, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, r5)) );
-
- // sh writes only 1/2 of word.
- __ lui(t5, 0x3333);
- __ ori(t5, t5, 0x3333);
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
- __ lhu(t5, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sh(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.ui = 0x11223344;
- t.si = 0x99aabbcc;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(0x11223344, t.r1);
- CHECK_EQ(0x3344, t.r2);
- CHECK_EQ(0xffffbbcc, t.r3);
- CHECK_EQ(0x0000bbcc, t.r4);
- CHECK_EQ(0xffffffcc, t.r5);
- CHECK_EQ(0x3333bbcc, t.r6);
-}
-
-
-TEST(MIPS7) {
- // Test floating point compare and branch instructions.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- double a;
- double b;
- double c;
- double d;
- double e;
- double f;
- int32_t result;
- } T;
- T t;
-
- // Create a function that accepts &t, and loads, manipulates, and stores
- // the doubles t.a ... t.f.
- MacroAssembler assm(Isolate::Current(), NULL, 0);
- Label neither_is_nan, less_than, outa_here;
-
- if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
- __ c(UN, D, f4, f6);
- __ bc1f(&neither_is_nan);
- __ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
- __ Branch(&outa_here);
-
- __ bind(&neither_is_nan);
-
- if (kArchVariant == kLoongson) {
- __ c(OLT, D, f6, f4);
- __ bc1t(&less_than);
- } else {
- __ c(OLT, D, f6, f4, 2);
- __ bc1t(&less_than, 2);
- }
- __ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
- __ Branch(&outa_here);
-
- __ bind(&less_than);
- __ Addu(t0, zero_reg, Operand(1));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
-
-
- // This test-case should have additional tests.
-
- __ bind(&outa_here);
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.a = 1.5e14;
- t.b = 2.75e11;
- t.c = 2.0;
- t.d = -4.0;
- t.e = 0.0;
- t.f = 0.0;
- t.result = 0;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
- CHECK_EQ(1.5e14, t.a);
- CHECK_EQ(2.75e11, t.b);
- CHECK_EQ(1, t.result);
- }
-}
-
-
-TEST(MIPS8) {
- // Test ROTR and ROTRV instructions.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- int32_t input;
- int32_t result_rotr_4;
- int32_t result_rotr_8;
- int32_t result_rotr_12;
- int32_t result_rotr_16;
- int32_t result_rotr_20;
- int32_t result_rotr_24;
- int32_t result_rotr_28;
- int32_t result_rotrv_4;
- int32_t result_rotrv_8;
- int32_t result_rotrv_12;
- int32_t result_rotrv_16;
- int32_t result_rotrv_20;
- int32_t result_rotrv_24;
- int32_t result_rotrv_28;
- } T;
- T t;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
-
- // Basic word load.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, input)) );
-
- // ROTR instruction (called through the Ror macro).
- __ Ror(t1, t0, 0x0004);
- __ Ror(t2, t0, 0x0008);
- __ Ror(t3, t0, 0x000c);
- __ Ror(t4, t0, 0x0010);
- __ Ror(t5, t0, 0x0014);
- __ Ror(t6, t0, 0x0018);
- __ Ror(t7, t0, 0x001c);
-
- // Basic word store.
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
- __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
- __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
-
- // ROTRV instruction (called through the Ror macro).
- __ li(t7, 0x0004);
- __ Ror(t1, t0, t7);
- __ li(t7, 0x0008);
- __ Ror(t2, t0, t7);
- __ li(t7, 0x000C);
- __ Ror(t3, t0, t7);
- __ li(t7, 0x0010);
- __ Ror(t4, t0, t7);
- __ li(t7, 0x0014);
- __ Ror(t5, t0, t7);
- __ li(t7, 0x0018);
- __ Ror(t6, t0, t7);
- __ li(t7, 0x001C);
- __ Ror(t7, t0, t7);
-
- // Basic word store.
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
- __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
- __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.input = 0x12345678;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0);
- USE(dummy);
- CHECK_EQ(0x81234567, t.result_rotr_4);
- CHECK_EQ(0x78123456, t.result_rotr_8);
- CHECK_EQ(0x67812345, t.result_rotr_12);
- CHECK_EQ(0x56781234, t.result_rotr_16);
- CHECK_EQ(0x45678123, t.result_rotr_20);
- CHECK_EQ(0x34567812, t.result_rotr_24);
- CHECK_EQ(0x23456781, t.result_rotr_28);
-
- CHECK_EQ(0x81234567, t.result_rotrv_4);
- CHECK_EQ(0x78123456, t.result_rotrv_8);
- CHECK_EQ(0x67812345, t.result_rotrv_12);
- CHECK_EQ(0x56781234, t.result_rotrv_16);
- CHECK_EQ(0x45678123, t.result_rotrv_20);
- CHECK_EQ(0x34567812, t.result_rotrv_24);
- CHECK_EQ(0x23456781, t.result_rotrv_28);
-}
-
-
-TEST(MIPS9) {
- // Test BRANCH improvements.
- InitializeVM();
- v8::HandleScope scope;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
- Label exit, exit2, exit3;
-
- __ Branch(&exit, ge, a0, Operand(0x00000000));
- __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
- __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
-
- __ bind(&exit);
- __ bind(&exit2);
- __ bind(&exit3);
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
-}
-
-
-TEST(MIPS10) {
- // Test conversions between doubles and long integers.
- // Test hos the long ints map to FP regs pairs.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- double a;
- double b;
- int32_t dbl_mant;
- int32_t dbl_exp;
- int32_t long_hi;
- int32_t long_lo;
- int32_t b_long_hi;
- int32_t b_long_lo;
- } T;
- T t;
-
- Assembler assm(Isolate::Current(), NULL, 0);
- Label L, C;
-
- if (CpuFeatures::IsSupported(FPU) && kArchVariant == kMips32r2) {
- CpuFeatures::Scope scope(FPU);
-
- // Load all structure elements to registers.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
-
- // Save the raw bits of the double.
- __ mfc1(t0, f0);
- __ mfc1(t1, f1);
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
-
- // Convert double in f0 to long, save hi/lo parts.
- __ cvt_l_d(f0, f0);
- __ mfc1(t0, f0); // f0 has LS 32 bits of long.
- __ mfc1(t1, f1); // f1 has MS 32 bits of long.
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, long_lo)));
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, long_hi)));
-
- // Convert the b long integers to double b.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
- __ mtc1(t0, f8); // f8 has LS 32-bits.
- __ mtc1(t1, f9); // f9 has MS 32-bits.
- __ cvt_d_l(f10, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.a = 2.147483647e9; // 0x7fffffff -> 0x41DFFFFFFFC00000 as double.
- t.b_long_hi = 0x000000ff; // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double.
- t.b_long_lo = 0x00ff00ff;
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(0x41DFFFFF, t.dbl_exp);
- CHECK_EQ(0xFFC00000, t.dbl_mant);
- CHECK_EQ(0, t.long_hi);
- CHECK_EQ(0x7fffffff, t.long_lo);
- // 0xFF00FF00FF -> 1.095233372415e12.
- CHECK_EQ(1.095233372415e12, t.b);
- }
-}
-
-
-TEST(MIPS11) {
- // Test LWL, LWR, SWL and SWR instructions.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- int32_t reg_init;
- int32_t mem_init;
- int32_t lwl_0;
- int32_t lwl_1;
- int32_t lwl_2;
- int32_t lwl_3;
- int32_t lwr_0;
- int32_t lwr_1;
- int32_t lwr_2;
- int32_t lwr_3;
- int32_t swl_0;
- int32_t swl_1;
- int32_t swl_2;
- int32_t swl_3;
- int32_t swr_0;
- int32_t swr_1;
- int32_t swr_2;
- int32_t swr_3;
- } T;
- T t;
-
- Assembler assm(Isolate::Current(), NULL, 0);
-
- // Test all combinations of LWL and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwl_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwl_1)) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwl_2)) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwl_3)) );
-
- // Test all combinations of LWR and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwr_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwr_1)) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
-
- // Test all combinations of SWL and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, swl_1)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t1, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, swl_2)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t2, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, swl_3)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t3, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) );
-
- // Test all combinations of SWR and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, swr_1)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t1, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, swr_2)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t2, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, swr_3)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t3, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) );
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.reg_init = 0xaabbccdd;
- t.mem_init = 0x11223344;
-
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(0x44bbccdd, t.lwl_0);
- CHECK_EQ(0x3344ccdd, t.lwl_1);
- CHECK_EQ(0x223344dd, t.lwl_2);
- CHECK_EQ(0x11223344, t.lwl_3);
-
- CHECK_EQ(0x11223344, t.lwr_0);
- CHECK_EQ(0xaa112233, t.lwr_1);
- CHECK_EQ(0xaabb1122, t.lwr_2);
- CHECK_EQ(0xaabbcc11, t.lwr_3);
-
- CHECK_EQ(0x112233aa, t.swl_0);
- CHECK_EQ(0x1122aabb, t.swl_1);
- CHECK_EQ(0x11aabbcc, t.swl_2);
- CHECK_EQ(0xaabbccdd, t.swl_3);
-
- CHECK_EQ(0xaabbccdd, t.swr_0);
- CHECK_EQ(0xbbccdd44, t.swr_1);
- CHECK_EQ(0xccdd3344, t.swr_2);
- CHECK_EQ(0xdd223344, t.swr_3);
-}
-
-
-TEST(MIPS12) {
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- int32_t x;
- int32_t y;
- int32_t y1;
- int32_t y2;
- int32_t y3;
- int32_t y4;
- } T;
- T t;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
-
- __ mov(t6, fp); // Save frame pointer.
- __ mov(fp, a0); // Access struct T by fp.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, y)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, y4)) );
-
- __ addu(t1, t0, t3);
- __ subu(t4, t0, t3);
- __ nop();
- __ push(t0); // These instructions disappear after opt.
- __ Pop();
- __ addu(t0, t0, t0);
- __ nop();
- __ Pop(); // These instructions disappear after opt.
- __ push(t3);
- __ nop();
- __ push(t3); // These instructions disappear after opt.
- __ pop(t3);
- __ nop();
- __ push(t3);
- __ pop(t4);
- __ nop();
- __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ lw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ nop();
- __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
- __ nop();
- __ push(t1);
- __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
- __ pop(t1);
- __ nop();
- __ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
- __ pop(t1);
- __ nop();
- __ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
- __ pop(t2);
- __ nop();
- __ push(t2);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
- __ pop(t1);
- __ nop();
- __ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
- __ pop(t3);
- __ nop();
-
- __ mov(fp, t6);
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
- t.x = 1;
- t.y = 2;
- t.y1 = 3;
- t.y2 = 4;
- t.y3 = 0XBABA;
- t.y4 = 0xDEDA;
-
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(3, t.y1);
-}
-
-
-TEST(MIPS13) {
- // Test Cvt_d_uw and Trunc_uw_d macros.
- InitializeVM();
- v8::HandleScope scope;
-
- typedef struct {
- double cvt_big_out;
- double cvt_small_out;
- uint32_t trunc_big_out;
- uint32_t trunc_small_out;
- uint32_t cvt_big_in;
- uint32_t cvt_small_in;
- } T;
- T t;
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
-
- if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
-
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
- __ Cvt_d_uw(f10, t0, f22);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
-
- __ Trunc_uw_d(f10, f10, f22);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
-
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
- __ Cvt_d_uw(f8, t0, f22);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
-
- __ Trunc_uw_d(f8, f8, f22);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
-
- t.cvt_big_in = 0xFFFFFFFF;
- t.cvt_small_in = 333;
-
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
- CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
- CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
-
- CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
- CHECK_EQ(static_cast<int>(t.trunc_small_out),
- static_cast<int>(t.cvt_small_in));
- }
-}
-
-
-TEST(MIPS14) {
- // Test round, floor, ceil, trunc, cvt.
- InitializeVM();
- v8::HandleScope scope;
-
-#define ROUND_STRUCT_ELEMENT(x) \
- int32_t x##_up_out; \
- int32_t x##_down_out; \
- int32_t neg_##x##_up_out; \
- int32_t neg_##x##_down_out; \
- uint32_t x##_err1_out; \
- uint32_t x##_err2_out; \
- uint32_t x##_err3_out; \
- uint32_t x##_err4_out; \
- int32_t x##_invalid_result;
-
- typedef struct {
- double round_up_in;
- double round_down_in;
- double neg_round_up_in;
- double neg_round_down_in;
- double err1_in;
- double err2_in;
- double err3_in;
- double err4_in;
-
- ROUND_STRUCT_ELEMENT(round)
- ROUND_STRUCT_ELEMENT(floor)
- ROUND_STRUCT_ELEMENT(ceil)
- ROUND_STRUCT_ELEMENT(trunc)
- ROUND_STRUCT_ELEMENT(cvt)
- } T;
- T t;
-
-#undef ROUND_STRUCT_ELEMENT
-
- MacroAssembler assm(Isolate::Current(), NULL, 0);
-
- if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
-
- // Save FCSR.
- __ cfc1(a1, FCSR);
- // Disable FPU exceptions.
- __ ctc1(zero_reg, FCSR);
-#define RUN_ROUND_TEST(x) \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
- __ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
- __ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
- __ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
- __ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
- __ ctc1(zero_reg, FCSR); \
- __ x##_w_d(f0, f0); \
- __ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
- __ ctc1(zero_reg, FCSR); \
- __ x##_w_d(f0, f0); \
- __ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
- __ ctc1(zero_reg, FCSR); \
- __ x##_w_d(f0, f0); \
- __ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
- \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
- __ ctc1(zero_reg, FCSR); \
- __ x##_w_d(f0, f0); \
- __ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
-
- RUN_ROUND_TEST(round)
- RUN_ROUND_TEST(floor)
- RUN_ROUND_TEST(ceil)
- RUN_ROUND_TEST(trunc)
- RUN_ROUND_TEST(cvt)
-
- // Restore FCSR.
- __ ctc1(a1, FCSR);
-
- __ jr(ra);
- __ nop();
-
- CodeDesc desc;
- assm.GetCode(&desc);
- Object* code = HEAP->CreateCode(
- desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>())->ToObjectChecked();
- CHECK(code->IsCode());
- F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
-
- t.round_up_in = 123.51;
- t.round_down_in = 123.49;
- t.neg_round_up_in = -123.5;
- t.neg_round_down_in = -123.49;
- t.err1_in = 123.51;
- t.err2_in = 1;
- t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
- t.err4_in = NAN;
-
- Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
- USE(dummy);
-
-#define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
-#define CHECK_ROUND_RESULT(type) \
- CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
- CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
- CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
- CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
- CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result);
-
- CHECK_ROUND_RESULT(round);
- CHECK_ROUND_RESULT(floor);
- CHECK_ROUND_RESULT(ceil);
- CHECK_ROUND_RESULT(cvt);
- }
-}
-
-
-TEST(MIPS15) {
- // Test chaining of label usages within instructions (issue 1644).
- InitializeVM();
- v8::HandleScope scope;
- Assembler assm(Isolate::Current(), NULL, 0);
-
- Label target;
- __ beq(v0, v1, &target);
- __ nop();
- __ bne(v0, v1, &target);
- __ nop();
- __ bind(&target);
- __ nop();
-}
-
-#undef __