summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/formats
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:04 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:04 -0500
commitaa45fafb2e3667f907a2dcc491c57b9e83f8e940 (patch)
treebeefa346fd762e82f5b9c60f0da1ed554250a8b9 /src/arch/arm/isa/formats
parent2419903dc0c100b1eb3111a5e0fc9b186c79e6ed (diff)
downloadgem5-aa45fafb2e3667f907a2dcc491c57b9e83f8e940.tar.xz
ARM: Add support for "SUBS PC, LR and related instructions".
Diffstat (limited to 'src/arch/arm/isa/formats')
-rw-r--r--src/arch/arm/isa/formats/branch.isa7
-rw-r--r--src/arch/arm/isa/formats/data.isa148
2 files changed, 104 insertions, 51 deletions
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index caf6f6227..45464018e 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -192,8 +192,11 @@ def format Thumb32BranchesAndMiscCtrl() {{
case 0x3c:
return new WarnUnimplemented("bxj", machInst);
case 0x3d:
- return new WarnUnimplemented("subs_pc_lr_and_rel_insts",
- machInst);
+ {
+ const uint32_t imm32 = bits(machInst, 7, 0);
+ return new SubsImmPclr(machInst, INTREG_PC, INTREG_LR,
+ imm32, false);
+ }
case 0x3e:
case 0x3f:
return new WarnUnimplemented("mrs", machInst);
diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa
index 45dedff2c..eb36699c2 100644
--- a/src/arch/arm/isa/formats/data.isa
+++ b/src/arch/arm/isa/formats/data.isa
@@ -36,12 +36,21 @@
// Authors: Gabe Black
def format ArmDataProcReg() {{
+ pclr = '''
+ return new %(className)ssRegPclr(machInst, %(dest)s,
+ %(op1)s, rm, imm5,
+ type);
+ '''
instDecode = '''
case %(opcode)#x:
if (immShift) {
if (setCc) {
- return new %(className)sRegCc(machInst, %(dest)s, %(op1)s,
- rm, imm5, type);
+ if (%(dest)s == INTREG_PC) {
+ %(pclr)s
+ } else {
+ return new %(className)sRegCc(machInst, %(dest)s,
+ %(op1)s, rm, imm5, type);
+ }
} else {
return new %(className)sReg(machInst, %(dest)s, %(op1)s,
rm, imm5, type);
@@ -58,12 +67,26 @@ def format ArmDataProcReg() {{
break;
'''
- def instCode(opcode, mnem, dest="rd", op1="rn"):
- global instDecode
- return instDecode % { "className": mnem.capitalize(),
- "opcode": opcode,
- "dest": dest,
- "op1": op1 }
+ def instCode(opcode, mnem, useDest = True, useOp1 = True):
+ global pclr
+ if useDest:
+ dest = "rd"
+ else:
+ dest = "INTREG_ZERO"
+ if useOp1:
+ op1 = "rn"
+ else:
+ op1 = "INTREG_ZERO"
+ global instDecode, pclrCode
+ substDict = { "className": mnem.capitalize(),
+ "opcode": opcode,
+ "dest": dest,
+ "op1": op1 }
+ if useDest:
+ substDict["pclr"] = pclr % substDict
+ else:
+ substDict["pclr"] = ""
+ return instDecode % substDict
decode_block = '''
{
@@ -85,14 +108,14 @@ def format ArmDataProcReg() {{
decode_block += instCode(0x5, "adc")
decode_block += instCode(0x6, "sbc")
decode_block += instCode(0x7, "rsc")
- decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
- decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
- decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
- decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
+ decode_block += instCode(0x8, "tst", useDest = False)
+ decode_block += instCode(0x9, "teq", useDest = False)
+ decode_block += instCode(0xa, "cmp", useDest = False)
+ decode_block += instCode(0xb, "cmn", useDest = False)
decode_block += instCode(0xc, "orr")
- decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
+ decode_block += instCode(0xd, "mov", useOp1 = False)
decode_block += instCode(0xe, "bic")
- decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
+ decode_block += instCode(0xf, "mvn", useOp1 = False)
decode_block += '''
default:
return new Unknown(machInst);
@@ -102,43 +125,70 @@ def format ArmDataProcReg() {{
}};
def format ArmDataProcImm() {{
+ pclr = '''
+ return new %(className)ssImmPclr(machInst, %(dest)s,
+ %(op1)s, imm, false);
+ '''
+ adr = '''
+ return new AdrImm(machInst, %(dest)s, %(add)s,
+ imm, false);
+ '''
instDecode = '''
+ case %(opcode)#x:
if (setCc) {
- return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
- imm, rotC);
+ if (%(pclrInst)s && %(dest)s == INTREG_PC) {
+ %(pclr)s
+ } else {
+ return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
+ imm, rotC);
+ }
} else {
- return new %(className)sImm(machInst, %(dest)s, %(op1)s,
- imm, rotC);
+ if (%(adrInst)s && %(op1)s == INTREG_PC) {
+ %(adr)s
+ } else {
+ return new %(className)sImm(machInst, %(dest)s, %(op1)s,
+ imm, rotC);
+ }
}
break;
'''
- def instCode(opcode, mnem, dest="rd", op1="rn"):
- global instDecode
- code = '''
- case %(opcode)#x:
- ''' + instDecode
- return code % { "className": mnem.capitalize(),
- "opcode": opcode,
- "dest": dest,
- "op1": op1 }
+ def instCode(opcode, mnem, useDest = True, useOp1 = True):
+ global instDecode, pclr, adr
+ if useDest:
+ dest = "rd"
+ else:
+ dest = "INTREG_ZERO"
+ if useOp1:
+ op1 = "rn"
+ else:
+ op1 = "INTREG_ZERO"
+ substDict = { "className": mnem.capitalize(),
+ "opcode": opcode,
+ "dest": dest,
+ "op1": op1,
+ "adr": "",
+ "adrInst": "false" }
+ if useDest:
+ substDict["pclrInst"] = "true"
+ substDict["pclr"] = pclr % substDict
+ else:
+ substDict["pclrInst"] = "false"
+ substDict["pclr"] = ""
+ return instDecode % substDict
- def adrCode(opcode, mnem, dest="rd", op1="rn", add="1"):
- global instDecode
- code = '''
- case %(opcode)#x:
- if (rn == 0xf) {
- return new AdrImm(machInst, %(dest)s, %(add)s,
- imm, false);
- } else {
- ''' + instDecode + '''
- }
- '''
- return code % { "className": mnem.capitalize(),
- "opcode": opcode,
- "dest": dest,
- "add": add,
- "op1": op1 }
+ def adrCode(opcode, mnem, add="1"):
+ global instDecode, pclr, adr
+ substDict = { "className": mnem.capitalize(),
+ "opcode": opcode,
+ "dest": "rd",
+ "op1": "rn",
+ "add": add,
+ "pclrInst": "true",
+ "adrInst": "true" }
+ substDict["pclr"] = pclr % substDict
+ substDict["adr"] = adr % substDict
+ return instDecode % substDict
decode_block = '''
{
@@ -159,14 +209,14 @@ def format ArmDataProcImm() {{
decode_block += instCode(0x5, "adc")
decode_block += instCode(0x6, "sbc")
decode_block += instCode(0x7, "rsc")
- decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
- decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
- decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
- decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
+ decode_block += instCode(0x8, "tst", useDest = False)
+ decode_block += instCode(0x9, "teq", useDest = False)
+ decode_block += instCode(0xa, "cmp", useDest = False)
+ decode_block += instCode(0xb, "cmn", useDest = False)
decode_block += instCode(0xc, "orr")
- decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
+ decode_block += instCode(0xd, "mov", useOp1 = False)
decode_block += instCode(0xe, "bic")
- decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
+ decode_block += instCode(0xf, "mvn", useOp1 = False)
decode_block += '''
default:
return new Unknown(machInst);