diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/arm/isa/decoder/thumb.isa | 5 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/mem.isa | 30 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/uncond.isa | 38 |
3 files changed, 67 insertions, 6 deletions
diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa index 231796281..23c33df48 100644 --- a/src/arch/arm/isa/decoder/thumb.isa +++ b/src/arch/arm/isa/decoder/thumb.isa @@ -70,10 +70,7 @@ 0x1: decode HTOPCODE_10_9 { 0x0: decode HTOPCODE_6 { 0x0: decode HTOPCODE_8_7 { - 0x0, 0x3: decode HTOPCODE_4 { - 0x0: WarnUnimpl::srs(); - 0x1: WarnUnimpl::rfe(); - } + 0x0, 0x3: Thumb32SrsRfe::thumb32SrsRfe(); // This uses the same encoding as regular ARM. default: ArmMacroMem::armMacroMem(); } diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 41706c48d..5d389458c 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -255,6 +255,36 @@ def format ArmSyncMem() {{ } }}; +def format Thumb32SrsRfe() {{ + decode_block = ''' + { + if (bits(machInst, 20) == 1) { + const bool add = (bits(machInst, 24, 23) == 0x3); + // post == add + const bool wb = (bits(machInst, 21) == 1); + const IntRegIndex rn = + (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + if (!add && !wb) { + return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb); + } else if (add && !wb) { + return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb); + } else if (!add && wb) { + return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb); + } else { + return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb); + } + } else { + return new WarnUnimplemented("srs", machInst); + } + } + ''' % { + "rfe" : "RFE_" + loadImmClassName(False, False, False, 8), + "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8), + "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8), + "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8) + } +}}; + def format Thumb32LdrStrDExTbh() {{ decode_block = ''' { diff --git a/src/arch/arm/isa/formats/uncond.isa b/src/arch/arm/isa/formats/uncond.isa index cd041f21b..d305ee996 100644 --- a/src/arch/arm/isa/formats/uncond.isa +++ b/src/arch/arm/isa/formats/uncond.isa @@ -165,7 +165,33 @@ def format ArmUnconditional() {{ if (val == 0x4) { return new WarnUnimplemented("srs", machInst); } else if (val == 0x1) { - return new WarnUnimplemented("rfe", machInst); + switch (bits(machInst, 24, 21)) { + case 0x0: + return new %(rfe)s(machInst, rn, + RfeOp::DecrementAfter, false); + case 0x1: + return new %(rfe_w)s(machInst, rn, + RfeOp::DecrementAfter, true); + case 0x4: + return new %(rfe_u)s(machInst, rn, + RfeOp::IncrementAfter, false); + case 0x5: + return new %(rfe_uw)s(machInst, rn, + RfeOp::IncrementAfter, true); + case 0x8: + return new %(rfe_p)s(machInst, rn, + RfeOp::DecrementBefore, false); + case 0x9: + return new %(rfe_pw)s(machInst, rn, + RfeOp::DecrementBefore, true); + case 0xc: + return new %(rfe_pu)s(machInst, rn, + RfeOp::IncrementBefore, false); + case 0xd: + return new %(rfe_puw)s(machInst, rn, + RfeOp::IncrementBefore, true); + } + return new Unknown(machInst); } } break; @@ -232,6 +258,14 @@ def format ArmUnconditional() {{ "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), "pld_rsub" : "PLD_" + loadRegClassName(False, False, False, 1), "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), - "pldw_rsub" : "PLDW_" + loadRegClassName(False, False, False, 1) + "pldw_rsub" : "PLDW_" + loadRegClassName(False, False, False, 1), + "rfe" : "RFE_" + loadImmClassName(True, False, False, 8), + "rfe_w" : "RFE_" + loadImmClassName(True, False, True, 8), + "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8), + "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8), + "rfe_p" : "RFE_" + loadImmClassName(False, False, False, 8), + "rfe_pw" : "RFE_" + loadImmClassName(False, False, True, 8), + "rfe_pu" : "RFE_" + loadImmClassName(False, True, False, 8), + "rfe_puw" : "RFE_" + loadImmClassName(False, True, True, 8) }; }}; |