arch-riscv: Fix disassembling for fence and fence.i
authorIan Jiang <ianjiang.ict@gmail.com>
Thu, 14 Nov 2019 08:41:25 +0000 (16:41 +0800)
committerIan Jiang <ianjiang.ict@gmail.com>
Tue, 26 Nov 2019 03:38:22 +0000 (03:38 +0000)
The original Gem5 does not give correct disassembly for instruction fence
and fence.i. This patch fixes the problem by adding two bitfields PRED and
SUCC and a new format FenceOp and a template FenceExecute, in which
operands are generated based on PRED and SUCC in the disassembling
function.

Change-Id: I78dbf125fef86ce40785c498a318ffb1569da46c
Signed-off-by: Ian Jiang <ianjiang.ict@gmail.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22569
Reviewed-by: Alec Roelke <alec.roelke@gmail.com>
Maintainer: Alec Roelke <alec.roelke@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/riscv/isa/bitfields.isa
src/arch/riscv/isa/decoder.isa
src/arch/riscv/isa/formats/standard.isa

index 20f1fc0defd910fdebfed97f40a2c4182c5d0941..fcda90cf70ce61bac88769d4ec100abfa29e8497 100644 (file)
@@ -54,6 +54,10 @@ def bitfield SHAMT6 <25:20>;
 // I-Type
 def bitfield IMM12  <31:20>;
 
+// Sync
+def bitfield SUCC  <23:20>;
+def bitfield PRED  <27:24>;
+
 // S-Type
 def bitfield IMM5   <11:7>;
 def bitfield IMM7   <31:25>;
index fd9c574e13110cdea4359155568c265491a91d66..c5342034748ebcd86c9baf40f3bea2d657c3592a 100644 (file)
@@ -400,7 +400,7 @@ decode QUADRANT default Unknown::unknown() {
         }
 
         0x03: decode FUNCT3 {
-            format IOp {
+            format FenceOp {
                 0x0: fence({{
                 }}, uint64_t, IsMemBarrier, No_OpClass);
                 0x1: fence_i({{
index e67fdfcbde912c19c207b4df1ffc485fddc44bb1..78d8144f8e16b15af52a70c7b51a0e4012bb0e55 100644 (file)
@@ -90,6 +90,54 @@ def template ImmExecute {{
     }
 }};
 
+def template FenceExecute {{
+    Fault
+    %(class_name)s::execute(
+        ExecContext *xc, Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+
+        %(op_decl)s;
+        %(op_rd)s;
+        if (fault == NoFault) {
+            %(code)s;
+            if (fault == NoFault) {
+                %(op_wb)s;
+            }
+        }
+        return fault;
+    }
+
+    std::string
+    %(class_name)s::generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+        ss << mnemonic;
+        if (!FUNCT3) {
+            ss << ' ';
+            if (PRED & 0x8)
+                ss << 'i';
+            if (PRED & 0x4)
+                ss << 'o';
+            if (PRED & 0x2)
+                ss << 'r';
+            if (PRED & 0x1)
+                ss << 'w';
+            ss << ", ";
+            if (SUCC & 0x8)
+                ss << 'i';
+            if (SUCC & 0x4)
+                ss << 'o';
+            if (SUCC & 0x2)
+                ss << 'r';
+            if (SUCC & 0x1)
+                ss << 'w';
+        }
+        return ss.str();
+    }
+}};
+
 def template BranchDeclare {{
     //
     // Static instruction class for "%(mnemonic)s".
@@ -307,6 +355,17 @@ def format IOp(code, imm_type='int64_t', *opt_flags) {{
     exec_output = ImmExecute.subst(iop)
 }};
 
+def format FenceOp(code, imm_type='int64_t', *opt_flags) {{
+    regs = ['_destRegIdx[0]','_srcRegIdx[0]']
+    iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
+        {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
+         'regs': ','.join(regs)}, opt_flags)
+    header_output = ImmDeclare.subst(iop)
+    decoder_output = ImmConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = FenceExecute.subst(iop)
+}};
+
 def format BOp(code, *opt_flags) {{
     imm_code = """
                 imm = BIMM12BITS4TO1 << 1  |