From 7a9dcdf99f4d33fc24f9b7a41155f4cc7cd835bd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:09 -0500 Subject: [PATCH] ARM: Decode the load halfword, memory hints instructions for 32 bit Thumb. --- src/arch/arm/isa/decoder/thumb.isa | 2 +- src/arch/arm/isa/formats/mem.isa | 174 +++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa index e8e2d5919..ab431303c 100644 --- a/src/arch/arm/isa/decoder/thumb.isa +++ b/src/arch/arm/isa/decoder/thumb.isa @@ -140,7 +140,7 @@ } 0x1: decode HTOPCODE_6_5 { 0x0: WarnUnimpl::Load_byte_memory_hints(); - 0x1: WarnUnimpl::Load_halfword_memory_hints(); + 0x1: LoadHalfwordMemoryHints::loadHalfwordMemoryHints(); 0x2: Thumb32LoadWord::thumb32LoadWord(); 0x3: WarnUnimpl::undefined(); } diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 6b36e39fb..6b511362f 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -468,6 +468,180 @@ def format Thumb32StoreSingle() {{ decode_block = decode % classNames }}; +def format LoadHalfwordMemoryHints() {{ + decode = ''' + { + const uint32_t op1 = bits(machInst, 24, 23); + const uint32_t op2 = bits(machInst, 11, 6); + const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); + const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); + const uint32_t imm12 = bits(machInst, 11, 0); + const uint32_t imm8 = bits(machInst, 7, 0); + bool pldw = bits(machInst, 21); + const uint32_t imm2 = bits(machInst, 5, 4); + if (rn == 0xf) { + if (rt == 0xf) { + if (bits(op1, 1) == 1) { + // Unallocated memory hint + return new NopInst(machInst); + } else { + return new Unknown(machInst); + } + } else { + if (bits(op1, 1) == 1) { + if (bits(machInst, 23)) { + return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, + true, imm12); + } else { + return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, + false, imm12); + } + } else { + if (bits(machInst, 23)) { + return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, + true, imm12); + } else { + return new %(ldrh_lit)s(machInst, rt, INTREG_PC, + false, imm12); + } + } + } + } else if (rt == 0xf) { + switch (op1) { + case 0x0: + if (op2 == 0x0) { + if (pldw) { + return new %(pldw_radd)s(machInst, INTREG_ZERO, + rn, true, imm2, LSL, rm); + } else { + return new %(pld_radd)s(machInst, INTREG_ZERO, + rn, true, imm2, LSL, rm); + } + } else if (bits(op2, 5, 2) == 0xc) { + if (pldw) { + return new %(pldw_isub)s(machInst, INTREG_ZERO, + rn, false, imm8); + } else { + return new %(pld_isub)s(machInst, INTREG_ZERO, + rn, false, imm8); + } + } + break; + case 0x1: + if (pldw) { + return new %(pldw_iadd)s(machInst, INTREG_ZERO, + rn, true, imm12); + } else { + return new %(pld_iadd)s(machInst, INTREG_ZERO, + rn, true, imm12); + } + case 0x2: + if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { + // Unallocated memory hint + return new NopInst(machInst); + } + break; + case 0x3: + return new NopInst(machInst); + } + return new Unknown(machInst); + } else { + switch (op1) { + case 0x0: + if (op2 == 0) { + return new %(ldrh_radd)s(machInst, rt, rn, true, + imm2, LSL, rm); + } else if (bits(op2, 5, 2) == 0xe) { + return new %(ldrht)s(machInst, rt, rn, true, imm8); + } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { + const uint32_t puw = bits(machInst, 10, 8); + switch (puw) { + case 0x1: + return new %(ldrh_iw)s(machInst, rt, + rn, false, imm8); + case 0x3: + return new %(ldrh_iuw)s(machInst, rt, + rn, true, imm8); + case 0x4: + return new %(ldrh_ip)s(machInst, rt, + rn, false, imm8); + case 0x5: + return new %(ldrh_ipw)s(machInst, rt, + rn, false, imm8); + case 0x7: + return new %(ldrh_ipuw)s(machInst, rt, + rn, true, imm8); + } + } + break; + case 0x1: + return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); + case 0x2: + if (op2 == 0) { + return new %(ldrsh_radd)s(machInst, rt, rn, true, + imm2, LSL, rm); + } else if (bits(op2, 5, 2) == 0xe) { + return new %(ldrsht)s(machInst, rt, rn, true, imm8); + } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { + const uint32_t puw = bits(machInst, 10, 8); + switch (puw) { + case 0x1: + return new %(ldrsh_iw)s(machInst, rt, + rn, false, imm8); + case 0x3: + return new %(ldrsh_iuw)s(machInst, rt, + rn, true, imm8); + case 0x4: + return new %(ldrsh_ip)s(machInst, rt, + rn, false, imm8); + case 0x5: + return new %(ldrsh_ipw)s(machInst, rt, + rn, false, imm8); + case 0x7: + return new %(ldrsh_ipuw)s(machInst, rt, + rn, true, imm8); + } + } + break; + case 0x3: + return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); + } + return new Unknown(machInst); + } + } + ''' + substDict = { + "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), + "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), + "ldrh_lit_u" : loadImmClassName(False, True, False, 2), + "ldrh_lit" : loadImmClassName(False, False, False, 2), + "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), + "ldrh_radd" : loadRegClassName(False, True, False, 2), + "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), + "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), + "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), + "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), + "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), + "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), + "ldrh_iw" : loadImmClassName(True, False, True, 2), + "ldrh_iuw" : loadImmClassName(True, True, True, 2), + "ldrh_ip" : loadImmClassName(False, False, False, 2), + "ldrh_ipw" : loadImmClassName(False, False, True, 2), + "ldrh_ipuw" : loadImmClassName(False, True, True, 2), + "ldrh_iadd" : loadImmClassName(False, True, False, 2), + "ldrht" : loadImmClassName(False, True, False, 2, user=True), + "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), + "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), + "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), + "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), + "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), + "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), + "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) + } + decode_block = decode % substDict +}}; + def format Thumb16MemReg() {{ decode = ''' {