arch-riscv: Fix compressed branch op offset
authorAlec Roelke <ar4jc@virginia.edu>
Mon, 19 Feb 2018 17:21:33 +0000 (12:21 -0500)
committerAlec Roelke <ar4jc@virginia.edu>
Mon, 19 Feb 2018 20:31:33 +0000 (20:31 +0000)
There is a bug in RISC-V's compressed branch instructions where the
offsets are not stored in ImmOp's immediate field, causing incorrect
branchTarget() return values.  This patch adds a new compressed branch
op format, CBOp, which correctly stores the offset.

Change-Id: Iac6e9b091d63f3dce4717ee5a9ec31a7cbd6c377
Reviewed-on: https://gem5-review.googlesource.com/8441
Reviewed-by: Tuan Ta <qtt2@cornell.edu>
Maintainer: Alec Roelke <ar4jc@virginia.edu>

src/arch/riscv/isa/decoder.isa
src/arch/riscv/isa/formats/compressed.isa

index ecee16118b9215cf7370d43c6d6507b01362bd34..bbed650ca9af63d50be7cbb8087fb053d8ae97d9 100644 (file)
@@ -212,30 +212,16 @@ decode QUADRANT default Unknown::unknown() {
                 offset |= ~((int64_t)0x7FF);
             NPC = PC + offset;
         }}, IsIndirectControl, IsUncondControl, IsCall);
-        format BOp {
+        format CBOp {
             0x6: c_beqz({{
-                int64_t offset = CIMM5<2:1> << 1 |
-                                 CIMM3<1:0> << 3 |
-                                 CIMM5<0:0> << 5 |
-                                 CIMM5<4:3> << 6;
-                if (CIMM3<2:2> > 0)
-                    offset |= ~((int64_t)0xFF);
-
                 if (Rp1 == 0)
-                    NPC = PC + offset;
+                    NPC = PC + imm;
                 else
                     NPC = NPC;
             }}, IsDirectControl, IsCondControl);
             0x7: c_bnez({{
-                int64_t offset = CIMM5<2:1> << 1 |
-                                 CIMM3<1:0> << 3 |
-                                 CIMM5<0:0> << 5 |
-                                 CIMM5<4:3> << 6;
-                if (CIMM3<2:2> > 0)
-                    offset |= ~((int64_t)0xFF);
-
                 if (Rp1 != 0)
-                    NPC = PC + offset;
+                    NPC = PC + imm;
                 else
                     NPC = NPC;
             }}, IsDirectControl, IsCondControl);
index 03b7fb179295541d341028ccb4d0caa2a253909f..3ebc1c6ae7baaa756433bba4d82b4f977a58a67a 100644 (file)
@@ -47,6 +47,25 @@ def format CIOp(imm_code, code, imm_type='int64_t', *opt_flags) {{
     exec_output = ImmExecute.subst(iop)
 }};
 
+def format CBOp(code, *opt_flags) {{
+    imm_code = """
+                imm = CIMM5<2:1> << 1 |
+                      CIMM3<1:0> << 3 |
+                      CIMM5<0:0> << 5 |
+                      CIMM5<4:3> << 6;
+                if (CIMM3<2:2> > 0)
+                    imm |= ~((int64_t)0xFF);
+               """
+    regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
+    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
+        {'code': code, 'imm_code': imm_code,
+         'regs': ','.join(regs)}, opt_flags)
+    header_output = BranchDeclare.subst(iop)
+    decoder_output = ImmConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BranchExecute.subst(iop)
+}};
+
 def format CompressedLoad(ldisp_code, memacc_code,
         ea_code, mem_flags=[], inst_flags=[]) {{
     (header_output, decoder_output, decode_block, exec_output) = \