summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-macro-assembler-mips64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/test-macro-assembler-mips64.cc')
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-mips64.cc277
1 files changed, 259 insertions, 18 deletions
diff --git a/deps/v8/test/cctest/test-macro-assembler-mips64.cc b/deps/v8/test/cctest/test-macro-assembler-mips64.cc
index fadd45f43b..684b554236 100644
--- a/deps/v8/test/cctest/test-macro-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-mips64.cc
@@ -63,7 +63,7 @@ static bool all_zeroes(const byte* beg, const byte* end) {
TEST(CopyBytes) {
CcTest::InitializeVM();
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
const int data_size = 1 * KB;
@@ -83,7 +83,8 @@ TEST(CopyBytes) {
byte* a0_;
byte* a1_;
- MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
// Code to be generated: The stuff in CopyBytes followed by a store of a0 and
@@ -114,9 +115,8 @@ TEST(CopyBytes) {
for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) {
memset(dest_buffer, 0, data_size);
CHECK(dest + size < dest_buffer + data_size);
- (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(src),
- reinterpret_cast<int64_t>(dest),
- size, 0, 0);
+ (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int64_t>(src),
+ reinterpret_cast<int64_t>(dest), size, 0, 0);
// a0 and a1 should point at the first byte after the copied data.
CHECK_EQ(src + size, a0_);
CHECK_EQ(dest + size, a1_);
@@ -138,7 +138,7 @@ TEST(CopyBytes) {
TEST(LoadConstants) {
CcTest::InitializeVM();
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
int64_t refConstants[64];
@@ -149,7 +149,8 @@ TEST(LoadConstants) {
refConstants[i] = ~(mask << i);
}
- MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
__ mov(a4, a0);
@@ -169,8 +170,8 @@ TEST(LoadConstants) {
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
::F f = FUNCTION_CAST< ::F>(code->entry());
- (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(result),
- 0, 0, 0, 0);
+ (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int64_t>(result), 0, 0,
+ 0, 0);
// Check results.
for (int i = 0; i < 64; i++) {
CHECK(refConstants[i] == result[i]);
@@ -180,10 +181,11 @@ TEST(LoadConstants) {
TEST(LoadAddress) {
CcTest::InitializeVM();
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
- MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
Label to_jump, skip;
__ mov(a4, a0);
@@ -213,7 +215,7 @@ TEST(LoadAddress) {
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
::F f = FUNCTION_CAST< ::F>(code->entry());
- (void) CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0);
+ (void)CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0);
// Check results.
}
@@ -226,7 +228,8 @@ TEST(jump_tables4) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
- MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
const int kNumCases = 512;
@@ -237,9 +240,6 @@ TEST(jump_tables4) {
__ daddiu(sp, sp, -8);
__ sd(ra, MemOperand(sp));
- if ((masm->pc_offset() & 7) == 0) {
- __ nop();
- }
__ mov(v0, zero_reg);
@@ -252,6 +252,7 @@ TEST(jump_tables4) {
__ addiu(v0, v0, 1);
}
+ __ Align(8);
Label done;
{
__ BlockTrampolinePoolFor(kNumCases * 2 + 6);
@@ -296,11 +297,251 @@ TEST(jump_tables4) {
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
for (int i = 0; i < kNumCases; ++i) {
- int64_t res =
- reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
::printf("f(%d) = %" PRId64 "\n", i, res);
CHECK_EQ(values[i], res);
}
}
+
+TEST(jump_tables5) {
+ if (kArchVariant != kMips64r6) return;
+
+ // Similar to test-assembler-mips jump_tables1, with extra test for emitting a
+ // compact branch instruction before emission of the dd table.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ const int kNumCases = 512;
+ int values[kNumCases];
+ isolate->random_number_generator()->NextBytes(values, sizeof(values));
+ Label labels[kNumCases];
+ Label done;
+
+ __ daddiu(sp, sp, -8);
+ __ sd(ra, MemOperand(sp));
+
+ __ Align(8);
+ {
+ __ BlockTrampolinePoolFor(kNumCases * 2 + 7 + 1);
+ PredictableCodeSizeScope predictable(
+ masm, kNumCases * kPointerSize + ((7 + 1) * Assembler::kInstrSize));
+ Label here;
+
+ __ bal(&here);
+ __ dsll(at, a0, 3); // In delay slot.
+ __ bind(&here);
+ __ daddu(at, at, ra);
+ __ ld(at, MemOperand(at, 6 * Assembler::kInstrSize));
+ __ jalr(at);
+ __ nop(); // Branch delay slot nop.
+ __ bc(&done);
+ // A nop instruction must be generated by the forbidden slot guard
+ // (Assembler::dd(Label*)) so the first label goes to an 8 bytes aligned
+ // location.
+ for (int i = 0; i < kNumCases; ++i) {
+ __ dd(&labels[i]);
+ }
+ }
+
+ for (int i = 0; i < kNumCases; ++i) {
+ __ bind(&labels[i]);
+ __ lui(v0, (values[i] >> 16) & 0xffff);
+ __ ori(v0, v0, values[i] & 0xffff);
+ __ jr(ra);
+ __ nop();
+ }
+
+ __ bind(&done);
+ __ ld(ra, MemOperand(sp));
+ __ daddiu(sp, sp, 8);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ for (int i = 0; i < kNumCases; ++i) {
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %" PRId64 "\n", i, res);
+ CHECK_EQ(values[i], res);
+ }
+}
+
+
+static uint64_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ __ Lsa(v0, a0, a1, sa);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assembler.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+
+ uint64_t res = reinterpret_cast<uint64_t>(
+ CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(Lsa) {
+ CcTest::InitializeVM();
+ struct TestCaseLsa {
+ int32_t rt;
+ int32_t rs;
+ uint8_t sa;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res
+ {0x4, 0x1, 1, 0x6},
+ {0x4, 0x1, 2, 0x8},
+ {0x4, 0x1, 3, 0xc},
+ {0x4, 0x1, 4, 0x14},
+ {0x4, 0x1, 5, 0x24},
+ {0x0, 0x1, 1, 0x2},
+ {0x0, 0x1, 2, 0x4},
+ {0x0, 0x1, 3, 0x8},
+ {0x0, 0x1, 4, 0x10},
+ {0x0, 0x1, 5, 0x20},
+ {0x4, 0x0, 1, 0x4},
+ {0x4, 0x0, 2, 0x4},
+ {0x4, 0x0, 3, 0x4},
+ {0x4, 0x0, 4, 0x4},
+ {0x4, 0x0, 5, 0x4},
+
+ // Shift overflow.
+ {0x4, INT32_MAX, 1, 0x2},
+ {0x4, INT32_MAX >> 1, 2, 0x0},
+ {0x4, INT32_MAX >> 2, 3, 0xfffffffffffffffc},
+ {0x4, INT32_MAX >> 3, 4, 0xfffffffffffffff4},
+ {0x4, INT32_MAX >> 4, 5, 0xffffffffffffffe4},
+
+ // Signed addition overflow.
+ {INT32_MAX - 1, 0x1, 1, 0xffffffff80000000},
+ {INT32_MAX - 3, 0x1, 2, 0xffffffff80000000},
+ {INT32_MAX - 7, 0x1, 3, 0xffffffff80000000},
+ {INT32_MAX - 15, 0x1, 4, 0xffffffff80000000},
+ {INT32_MAX - 31, 0x1, 5, 0xffffffff80000000},
+
+ // Addition overflow.
+ {-2, 0x1, 1, 0x0},
+ {-4, 0x1, 2, 0x0},
+ {-8, 0x1, 3, 0x0},
+ {-16, 0x1, 4, 0x0},
+ {-32, 0x1, 5, 0x0}};
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa);
+ PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Lsa(v0, %x, %x, %hhu)\n",
+ tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+}
+
+
+static uint64_t run_dlsa(uint64_t rt, uint64_t rs, int8_t sa) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ __ Dlsa(v0, a0, a1, sa);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assembler.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ ::F f = FUNCTION_CAST<::F>(code->entry());
+
+ uint64_t res = reinterpret_cast<uint64_t>(
+ CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(Dlsa) {
+ CcTest::InitializeVM();
+ struct TestCaseLsa {
+ int64_t rt;
+ int64_t rs;
+ uint8_t sa;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res
+ {0x4, 0x1, 1, 0x6},
+ {0x4, 0x1, 2, 0x8},
+ {0x4, 0x1, 3, 0xc},
+ {0x4, 0x1, 4, 0x14},
+ {0x4, 0x1, 5, 0x24},
+ {0x0, 0x1, 1, 0x2},
+ {0x0, 0x1, 2, 0x4},
+ {0x0, 0x1, 3, 0x8},
+ {0x0, 0x1, 4, 0x10},
+ {0x0, 0x1, 5, 0x20},
+ {0x4, 0x0, 1, 0x4},
+ {0x4, 0x0, 2, 0x4},
+ {0x4, 0x0, 3, 0x4},
+ {0x4, 0x0, 4, 0x4},
+ {0x4, 0x0, 5, 0x4},
+
+ // Shift overflow.
+ {0x4, INT64_MAX, 1, 0x2},
+ {0x4, INT64_MAX >> 1, 2, 0x0},
+ {0x4, INT64_MAX >> 2, 3, 0xfffffffffffffffc},
+ {0x4, INT64_MAX >> 3, 4, 0xfffffffffffffff4},
+ {0x4, INT64_MAX >> 4, 5, 0xffffffffffffffe4},
+
+ // Signed addition overflow.
+ {INT64_MAX - 1, 0x1, 1, 0x8000000000000000},
+ {INT64_MAX - 3, 0x1, 2, 0x8000000000000000},
+ {INT64_MAX - 7, 0x1, 3, 0x8000000000000000},
+ {INT64_MAX - 15, 0x1, 4, 0x8000000000000000},
+ {INT64_MAX - 31, 0x1, 5, 0x8000000000000000},
+
+ // Addition overflow.
+ {-2, 0x1, 1, 0x0},
+ {-4, 0x1, 2, 0x0},
+ {-8, 0x1, 3, 0x0},
+ {-16, 0x1, 4, 0x0},
+ {-32, 0x1, 5, 0x0}};
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa);
+ PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64
+ ", %hhu)\n",
+ tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+}
+
#undef __