Index: test/cctest/test-macro-assembler-mips.cc |
diff --git a/test/cctest/test-macro-assembler-mips.cc b/test/cctest/test-macro-assembler-mips.cc |
index 696ca010caa4a068fafa5131261485546ee71cee..665a56c5a555870b84c58c2a1c5b01e133f55c69 100644 |
--- a/test/cctest/test-macro-assembler-mips.cc |
+++ b/test/cctest/test-macro-assembler-mips.cc |
@@ -279,23 +279,21 @@ TEST(jump_tables5) { |
Label labels[kNumCases]; |
Label done; |
- __ addiu(sp, sp, -4); |
- __ sw(ra, MemOperand(sp)); |
+ __ Push(ra); |
{ |
- __ BlockTrampolinePoolFor(kNumCases * 2 + 7 + 1); |
+ __ BlockTrampolinePoolFor(kNumCases + 6 + 1); |
PredictableCodeSizeScope predictable( |
- masm, kNumCases * kPointerSize + ((7 + 1) * Assembler::kInstrSize)); |
- Label here; |
+ masm, kNumCases * kPointerSize + ((6 + 1) * Assembler::kInstrSize)); |
- __ bal(&here); |
- __ sll(at, a0, 2); // In delay slot. |
- __ bind(&here); |
- __ addu(at, at, ra); |
- __ lw(at, MemOperand(at, 6 * Assembler::kInstrSize)); |
+ __ addiupc(at, 6 + 1); |
+ __ lsa(at, at, a0, 2); |
+ __ lw(at, MemOperand(at)); |
__ jalr(at); |
__ nop(); // Branch delay slot nop. |
__ bc(&done); |
+ // A nop instruction must be generated by the forbidden slot guard |
+ // (Assembler::dd(Label*)). |
for (int i = 0; i < kNumCases; ++i) { |
__ dd(&labels[i]); |
} |
@@ -303,15 +301,13 @@ TEST(jump_tables5) { |
for (int i = 0; i < kNumCases; ++i) { |
__ bind(&labels[i]); |
- __ lui(v0, (values[i] >> 16) & 0xffff); |
- __ ori(v0, v0, values[i] & 0xffff); |
+ __ li(v0, values[i]); |
__ jr(ra); |
__ nop(); |
} |
__ bind(&done); |
- __ lw(ra, MemOperand(sp)); |
- __ addiu(sp, sp, 4); |
+ __ Pop(ra); |
__ jr(ra); |
__ nop(); |
@@ -413,4 +409,54 @@ TEST(Lsa) { |
} |
} |
+ |
+static uint32_t run_addiupc(int32_t imm21, uint32_t& PC) { |
+ Isolate* isolate = CcTest::i_isolate(); |
+ HandleScope scope(isolate); |
+ |
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
+ MacroAssembler* masm = &assm; |
+ |
+ __ Addiupc(v0, imm21); |
+ __ jr(ra); |
+ __ nop(); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+ |
+ ::F f = FUNCTION_CAST<::F>(code->entry()); |
+ PC = reinterpret_cast<uint32_t>(f); // Set the program counter. |
+ |
+ uint32_t rs = reinterpret_cast<uint32_t>( |
+ CALL_GENERATED_CODE(isolate, f, imm21, 0, 0, 0, 0)); |
+ |
+ return rs; |
+} |
+ |
+ |
+TEST(Addiupc) { |
+ if (!IsMipsArchVariant(kMips32r6)) return; |
+ |
+ CcTest::InitializeVM(); |
+ |
+ int32_t tc[] = { |
+ INT32_MIN >> 11, // Min. int21. |
+ -4, // -1 instruction. |
+ 0, // 0 offset. |
+ 4, // 1 instruction. |
+ ((1 << 20) - 1) & ~3 // Max. int21. |
+ }; |
+ |
+ size_t nr_test_cases = sizeof(tc) / sizeof(int32_t); |
+ uint32_t PC = 0; |
+ for (size_t i = 0; i < nr_test_cases; ++i) { |
+ uint32_t res = run_addiupc(tc[i], PC); |
+ // Now, the program_counter (PC) is set. |
+ uint32_t expected_res = PC + tc[i]; |
+ CHECK_EQ(expected_res, res); |
+ } |
+} |
+ |
#undef __ |