diff options
author | Alec Roelke <ar4jc@virginia.edu> | 2018-02-19 12:21:33 -0500 |
---|---|---|
committer | Alec Roelke <ar4jc@virginia.edu> | 2018-02-19 20:31:33 +0000 |
commit | 7352324d4dda31ffb6fb5997e0fe2378c27e96b9 (patch) | |
tree | 09842cbeb5d3455fac31fa8c9297b37979fd6de3 /src/arch/riscv | |
parent | 72f15d3b8926432bed4740403d85a76549abb8bb (diff) | |
download | gem5-7352324d4dda31ffb6fb5997e0fe2378c27e96b9.tar.xz |
arch-riscv: Fix compressed branch op offset
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>
Diffstat (limited to 'src/arch/riscv')
-rw-r--r-- | src/arch/riscv/isa/decoder.isa | 20 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/compressed.isa | 19 |
2 files changed, 22 insertions, 17 deletions
diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index ecee16118..bbed650ca 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -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); diff --git a/src/arch/riscv/isa/formats/compressed.isa b/src/arch/riscv/isa/formats/compressed.isa index 03b7fb179..3ebc1c6ae 100644 --- a/src/arch/riscv/isa/formats/compressed.isa +++ b/src/arch/riscv/isa/formats/compressed.isa @@ -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) = \ |