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>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) = \
|
||||
|
||||
Reference in New Issue
Block a user