From 462cf6f49b388558d1fe7aa7731500d0e9abcdef Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:01 -0500 Subject: ARM: Make single stores decode to the new external store instructions. --- src/arch/arm/isa/decoder/thumb.isa | 27 +----------- src/arch/arm/isa/formats/mem.isa | 90 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 26 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa index ba29d9fec..1518b04ea 100644 --- a/src/arch/arm/isa/decoder/thumb.isa +++ b/src/arch/arm/isa/decoder/thumb.isa @@ -388,32 +388,7 @@ 0x3: decode HTOPCODE_10_9 { 0x0: decode HTOPCODE_4 { 0x0: decode HTOPCODE_8 { - 0x0: decode HTOPCODE_7_5 { - 0x0: decode LTOPCODE_11_8 { - 0x0: decode LTOPCODE_7_6 { - 0x0: WarnUnimpl::strb(); // register - } - 0x9, 0xb, 0xc, 0xd, 0xf: WarnUnimpl::strb(); // immediate thumb - 0xe: WarnUnimpl::strbt(); - } - 0x1: decode LTOPCODE_11_8 { - 0x0: decode LTOPCODE_7_6 { - 0x0: WarnUnimpl::strh(); // register - } - 0x9, 0xb, 0xc, 0xd, 0xf: WarnUnimpl::strh(); // immediate thumb - 0xe: WarnUnimpl::strht(); - } - 0x2: decode LTOPCODE_11_8 { - 0x0: decode LTOPCODE_7_6 { - 0x0: WarnUnimpl::str(); // register - } - 0x9, 0xb, 0xc, 0xd, 0xf: WarnUnimpl::str(); // immediate thumb - 0xe: WarnUnimpl::strt(); - } - 0x4: WarnUnimpl::strb(); // immediate, thumb - 0x5: WarnUnimpl::strh(); // immediate, thumb - 0x6: WarnUnimpl::str(); // immediate, thumb - } + 0x0: Thumb32StoreSingle::thumb32StoreSingle(); 0x1: WarnUnimpl::Advanced_SIMD_or_structure_load_store(); } 0x1: decode HTOPCODE_6_5 { diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index f72d344aa..bc3c1f720 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -268,6 +268,96 @@ def format Thumb32LoadWord() {{ decode_block = decode % classNames }}; +def format Thumb32StoreSingle() {{ + def buildPuwDecode(size): + puwDecode = ''' + { + uint32_t puw = bits(machInst, 10, 8); + uint32_t imm = IMMED_7_0; + switch (puw) { + case 0: + case 2: + // If we're here, either P or W must have been set. + panic("Neither P or W set, but that " + "shouldn't be possible.\\n"); + case 1: + return new %(imm_w)s(machInst, RT, RN, false, imm); + case 3: + return new %(imm_uw)s(machInst, RT, RN, true, imm); + case 4: + return new %(imm_p)s(machInst, RT, RN, false, imm); + case 5: + return new %(imm_pw)s(machInst, RT, RN, false, imm); + case 6: + return new %(imm_pu)s(machInst, RT, RN, true, imm); + case 7: + return new %(imm_puw)s(machInst, RT, RN, true, imm); + } + } + ''' + return puwDecode % { + "imm_w" : storeImmClassName(True, False, True, size=size), + "imm_uw" : storeImmClassName(True, True, True, size=size), + "imm_p" : storeImmClassName(False, False, False, size=size), + "imm_pw" : storeImmClassName(False, False, True, size=size), + "imm_pu" : storeImmClassName(False, True, False, size=size), + "imm_puw" : storeImmClassName(False, True, True, size=size) + } + decode = ''' + { + uint32_t op1 = bits(machInst, 23, 21); + uint32_t op2 = bits(machInst, 11, 6); + bool op2Puw = ((op2 & 0x24) == 0x24 || + (op2 & 0x3c) == 0x30); + if (op1 == 4) { + return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); + } else if (op1 == 0 && op2Puw) { + %(strb_puw)s; + } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { + return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); + } else if (op1 == 0 && op2 == 0) { + return new %(strb_reg)s(machInst, RT, RN, true, + bits(machInst, 5, 4), LSL, RM); + } else if (op1 == 5) { + return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); + } else if (op1 == 1 && op2Puw) { + %(strh_puw)s; + } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { + return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); + } else if (op1 == 1 && op2 == 0) { + return new %(strh_reg)s(machInst, RT, RN, true, + bits(machInst, 5, 4), LSL, RM); + } else if (op1 == 6) { + return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); + } else if (op1 == 2 && op2Puw) { + %(str_puw)s; + } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { + return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); + } else if (op1 == 2 && op2 == 0) { + return new %(str_reg)s(machInst, RT, RN, true, + bits(machInst, 5, 4), LSL, RM); + } else { + return new Unknown(machInst); + } + } + ''' + classNames = { + "strb_imm" : storeImmClassName(False, True, False, size=1), + "strb_puw" : buildPuwDecode(1), + "strbt" : storeImmClassName(False, True, False, user=True, size=1), + "strb_reg" : storeRegClassName(False, True, False, size=1), + "strh_imm" : storeImmClassName(False, True, False, size=2), + "strh_puw" : buildPuwDecode(2), + "strht" : storeImmClassName(False, True, False, user=True, size=2), + "strh_reg" : storeRegClassName(False, True, False, size=2), + "str_imm" : storeImmClassName(False, True, False), + "str_puw" : buildPuwDecode(4), + "strt" : storeImmClassName(False, True, False, user=True), + "str_reg" : storeRegClassName(False, True, False) + } + decode_block = decode % classNames +}}; + def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, mem_flags = [], inst_flags = []) {{ ea_code = ArmGenericCodeSubs(ea_code) -- cgit v1.2.3