From 61a5e71be7408ebd05df7778e58ea46d3fdb9e73 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:09 -0500 Subject: ARM: Decode the thumb version of the ldrd and strd instructions. --- src/arch/arm/isa/formats/mem.isa | 58 +++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'src/arch/arm/isa/formats/mem.isa') diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 1c69a5e00..b055b080f 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -263,8 +263,8 @@ def format Thumb32LdrStrDExTbh() {{ const uint32_t op3 = bits(machInst, 7, 4); const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); - /* This isn't used yet, and that makes gcc upset. */ - //const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const uint32_t imm8 = bits(machInst, 7, 0); if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { if (op1 == 0) { const uint32_t imm = bits(machInst, 7, 0) << 2; @@ -296,24 +296,70 @@ def format Thumb32LdrStrDExTbh() {{ case 0x5: return new %(ldrexh)s(machInst, rt, rn, true, 0); case 0x7: - return new WarnUnimplemented("ldrexd", machInst); + return new %(ldrexd)s(machInst, rt, rt2, rn, true, 0); default: return new Unknown(machInst); } } } } else { + const uint32_t puw = (bits(machInst, 24, 23) << 1) | + bits(machInst, 21); + const uint32_t dimm = imm8 << 2; if (bits(op2, 0) == 0) { - return new WarnUnimplemented("strd", machInst); + switch (puw) { + case 0x1: + return new %(strd_w)s(machInst, rt, rt2, rn, false, dimm); + case 0x3: + return new %(strd_uw)s(machInst, rt, rt2, rn, true, dimm); + case 0x4: + return new %(strd_p)s(machInst, rt, rt2, rn, false, dimm); + case 0x5: + return new %(strd_pw)s(machInst, rt, rt2, rn, false, dimm); + case 0x6: + return new %(strd_pu)s(machInst, rt, rt2, rn, true, dimm); + case 0x7: + return new %(strd_puw)s(machInst, rt, rt2, rn, true, dimm); + default: + return new Unknown(machInst); + } } else { - return new WarnUnimplemented("ldrd", machInst); + switch (puw) { + case 0x1: + return new %(ldrd_w)s(machInst, rt, rt2, rn, false, dimm); + case 0x3: + return new %(ldrd_uw)s(machInst, rt, rt2, rn, true, dimm); + case 0x4: + return new %(ldrd_p)s(machInst, rt, rt2, rn, false, dimm); + case 0x5: + return new %(ldrd_pw)s(machInst, rt, rt2, rn, false, dimm); + case 0x6: + return new %(ldrd_pu)s(machInst, rt, rt2, rn, true, dimm); + case 0x7: + return new %(ldrd_puw)s(machInst, rt, rt2, rn, true, dimm); + default: + return new Unknown(machInst); + } } } } ''' % { "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), - "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) + "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), + "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), + "ldrd_w" : loadDoubleImmClassName(True, False, True), + "ldrd_uw" : loadDoubleImmClassName(True, True, True), + "ldrd_p" : loadDoubleImmClassName(False, False, False), + "ldrd_pw" : loadDoubleImmClassName(False, False, True), + "ldrd_pu" : loadDoubleImmClassName(False, True, False), + "ldrd_puw" : loadDoubleImmClassName(False, True, True), + "strd_w" : storeDoubleImmClassName(True, False, True), + "strd_uw" : storeDoubleImmClassName(True, True, True), + "strd_p" : storeDoubleImmClassName(False, False, False), + "strd_pw" : storeDoubleImmClassName(False, False, True), + "strd_pu" : storeDoubleImmClassName(False, True, False), + "strd_puw" : storeDoubleImmClassName(False, True, True) } }}; -- cgit v1.2.3