From a5f5f5801440e6b4d25be37441a65af2add9a7ef Mon Sep 17 00:00:00 2001 From: "Ilija.Pavlovic" Date: Thu, 23 Jul 2015 00:29:57 -0700 Subject: [PATCH] MIPS: Fix simulator data trace for DSLL and BAL/BGEZAL. In simulator data trace, DSLL did not print result and BAL/BGEZAL omitted result from an instruction executed in delay slot. TEST=cctest/test-assembler-mips[64] BUG= Review URL: https://codereview.chromium.org/1245173002 Cr-Commit-Position: refs/heads/master@{#29796} --- src/mips/disasm-mips.cc | 8 ++- src/mips/simulator-mips.h | 1 + src/mips64/disasm-mips64.cc | 8 ++- src/mips64/simulator-mips64.cc | 2 +- src/mips64/simulator-mips64.h | 1 + test/cctest/test-assembler-mips.cc | 52 ++++++++++++++ test/cctest/test-assembler-mips64.cc | 100 +++++++++++++++++++++++++++ 7 files changed, 167 insertions(+), 5 deletions(-) diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc index 48427c545..1d505750a 100644 --- a/src/mips/disasm-mips.cc +++ b/src/mips/disasm-mips.cc @@ -1346,9 +1346,13 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { case BGEZ: Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); break; - case BGEZAL: - Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); + case BGEZAL: { + if (instr->RsValue() == 0) + Format(instr, "bal 'imm16s -> 'imm16p4s2"); + else + Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); break; + } case BGEZALL: Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); break; diff --git a/src/mips/simulator-mips.h b/src/mips/simulator-mips.h index 00b79b3cf..1459fbada 100644 --- a/src/mips/simulator-mips.h +++ b/src/mips/simulator-mips.h @@ -378,6 +378,7 @@ class Simulator { instr->OpcodeValue()); } InstructionDecode(instr); + SNPrintF(trace_buf_, " "); } // ICache. diff --git a/src/mips64/disasm-mips64.cc b/src/mips64/disasm-mips64.cc index ee624db2f..072319087 100644 --- a/src/mips64/disasm-mips64.cc +++ b/src/mips64/disasm-mips64.cc @@ -1510,9 +1510,13 @@ void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { case BGEZ: Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); break; - case BGEZAL: - Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); + case BGEZAL: { + if (instr->RsValue() == 0) + Format(instr, "bal 'imm16s -> 'imm16p4s2"); + else + Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); break; + } case BGEZALL: Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); break; diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc index 2382f44fb..16bc21281 100644 --- a/src/mips64/simulator-mips64.cc +++ b/src/mips64/simulator-mips64.cc @@ -3791,6 +3791,7 @@ void Simulator::DecodeTypeRegisterSPECIAL( break; case DSLL: set_register(rd_reg, alu_out); + TraceRegWr(alu_out); break; case DIV: case DDIV: @@ -4412,7 +4413,6 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) { UNREACHABLE(); } - // ---------- Raise exceptions triggered. SignalExceptions(); diff --git a/src/mips64/simulator-mips64.h b/src/mips64/simulator-mips64.h index 346d3584f..5ac178df6 100644 --- a/src/mips64/simulator-mips64.h +++ b/src/mips64/simulator-mips64.h @@ -411,6 +411,7 @@ class Simulator { instr->OpcodeValue()); } InstructionDecode(instr); + SNPrintF(trace_buf_, " "); } // ICache. diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc index 13abbbb44..514173e82 100644 --- a/test/cctest/test-assembler-mips.cc +++ b/test/cctest/test-assembler-mips.cc @@ -5059,4 +5059,56 @@ TEST(r6_balc) { } +uint32_t run_bal(int16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0); + + __ mov(t0, ra); + __ bal(offset); // Equivalent for "BGEZAL zero_reg, offset". + __ nop(); + + __ mov(ra, t0); + __ jr(ra); + __ nop(); + + __ li(v0, 1); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle()); + + F2 f = FUNCTION_CAST(code->entry()); + + uint32_t res = + reinterpret_cast(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + + return res; +} + + +TEST(bal) { + CcTest::InitializeVM(); + + struct TestCaseBal { + int16_t offset; + uint32_t expected_res; + }; + + struct TestCaseBal tc[] = { + // offset, expected_res + { 4, 1 }, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBal); + for (size_t i = 0; i < nr_test_cases; ++i) { + CHECK_EQ(tc[i].expected_res, run_bal(tc[i].offset)); + } +} + + #undef __ diff --git a/test/cctest/test-assembler-mips64.cc b/test/cctest/test-assembler-mips64.cc index bb7b05ca7..1fe7cfeb3 100644 --- a/test/cctest/test-assembler-mips64.cc +++ b/test/cctest/test-assembler-mips64.cc @@ -5366,4 +5366,104 @@ TEST(r6_balc) { } +uint64_t run_dsll(uint64_t rt_value, uint16_t sa_value) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0); + + __ dsll(v0, a0, sa_value); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle()); + + F2 f = FUNCTION_CAST(code->entry()); + + uint64_t res = + reinterpret_cast(CALL_GENERATED_CODE(f, rt_value, 0, 0, 0, 0)); + + return res; +} + + +TEST(dsll) { + CcTest::InitializeVM(); + + struct TestCaseDsll { + uint64_t rt_value; + uint16_t sa_value; + uint64_t expected_res; + }; + + struct TestCaseDsll tc[] = { + // rt_value, sa_value, expected_res + { 0xffffffffffffffff, 0, 0xffffffffffffffff }, + { 0xffffffffffffffff, 16, 0xffffffffffff0000 }, + { 0xffffffffffffffff, 31, 0xffffffff80000000 }, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDsll); + for (size_t i = 0; i < nr_test_cases; ++i) { + CHECK_EQ(tc[i].expected_res, + run_dsll(tc[i].rt_value, tc[i].sa_value)); + } +} + + +uint64_t run_bal(int16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0); + + __ mov(t0, ra); + __ bal(offset); // Equivalent for "BGEZAL zero_reg, offset". + __ nop(); + + __ mov(ra, t0); + __ jr(ra); + __ nop(); + + __ li(v0, 1); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle()); + + F2 f = FUNCTION_CAST(code->entry()); + + uint64_t res = + reinterpret_cast(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + + return res; +} + + +TEST(bal) { + CcTest::InitializeVM(); + + struct TestCaseBal { + int16_t offset; + uint64_t expected_res; + }; + + struct TestCaseBal tc[] = { + // offset, expected_res + { 4, 1 }, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBal); + for (size_t i = 0; i < nr_test_cases; ++i) { + CHECK_EQ(tc[i].expected_res, run_bal(tc[i].offset)); + } +} + + #undef __ -- 2.34.1