MIPS: Fix simulator data trace for DSLL and BAL/BGEZAL.
authorIlija.Pavlovic <Ilija.Pavlovic@imgtec.com>
Thu, 23 Jul 2015 07:29:57 +0000 (00:29 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 23 Jul 2015 07:30:09 +0000 (07:30 +0000)
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
src/mips/simulator-mips.h
src/mips64/disasm-mips64.cc
src/mips64/simulator-mips64.cc
src/mips64/simulator-mips64.h
test/cctest/test-assembler-mips.cc
test/cctest/test-assembler-mips64.cc

index 48427c54558650e2e3d2a8402af116ac5ba8f227..1d505750a5026626ecf97708c61d36288a248c3f 100644 (file)
@@ -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;
index 00b79b3cfe24799322c7419f905e1f70673e4ed4..1459fbada3226e3dc68f024ca57088cafe455414 100644 (file)
@@ -378,6 +378,7 @@ class Simulator {
                instr->OpcodeValue());
     }
     InstructionDecode(instr);
+    SNPrintF(trace_buf_, " ");
   }
 
   // ICache.
index ee624db2f8cab4d92fb4df9d02e74baaeb11c558..0723190871959b507fff262f81c63f36a93ac270 100644 (file)
@@ -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;
index 2382f44fb8d731bcebb99e98f257abf8236b3113..16bc2128131f3eeb6ac5f70c839b360d3a928b7f 100644 (file)
@@ -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();
 
index 346d3584f44f4c3eb718623cf45b5c8d87d6fa47..5ac178df64e293f437b77ca18f6a5f63db8103bb 100644 (file)
@@ -411,6 +411,7 @@ class Simulator {
                instr->OpcodeValue());
     }
     InstructionDecode(instr);
+    SNPrintF(trace_buf_, " ");
   }
 
   // ICache.
index 13abbbb4470828d0444feb00b54dde71876060e0..514173e8209b5c0eb676822b3a1dbbb8febe74fe 100644 (file)
@@ -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> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+  F2 f = FUNCTION_CAST<F2>(code->entry());
+
+  uint32_t res =
+    reinterpret_cast<uint32_t>(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 __
index bb7b05ca768c09b897b04ce0e881e7c9f6416a5f..1fe7cfeb39e6f7b2ee2996923ac9cf172fb8381f 100644 (file)
@@ -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> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+  F2 f = FUNCTION_CAST<F2>(code->entry());
+
+  uint64_t res =
+    reinterpret_cast<uint64_t>(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> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+  F2 f = FUNCTION_CAST<F2>(code->entry());
+
+  uint64_t res =
+    reinterpret_cast<uint64_t>(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 __