summaryrefslogtreecommitdiff
path: root/src
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
parent2419903dc0c100b1eb3111a5e0fc9b186c79e6ed (diff)
downloadgem5-aa45fafb2e3667f907a2dcc491c57b9e83f8e940.tar.xz
ARM: Add support for "SUBS PC, LR and related instructions".
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa/formats/branch.isa7
-rw-r--r--src/arch/arm/isa/formats/data.isa148
-rw-r--r--src/arch/arm/isa/insts/data.isa151
3 files changed, 193 insertions, 113 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);
diff --git a/src/arch/arm/isa/insts/data.isa b/src/arch/arm/isa/insts/data.isa
index 02ecd6b4c..69e813d25 100644
--- a/src/arch/arm/isa/insts/data.isa
+++ b/src/arch/arm/isa/insts/data.isa
@@ -98,8 +98,8 @@ let {{
regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodes<29:>)"
regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodes<29:>)"
- def buildImmDataInst(mnem, code, flagType = "logic"):
- global header_output, decoder_output, exec_output
+ def buildImmDataInst(mnem, code, flagType = "logic", \
+ suffix = "Imm", buildCc = True):
cCode = carryCode[flagType]
vCode = overflowCode[flagType]
negBit = 31
@@ -114,22 +114,26 @@ let {{
"negBit": negBit
}
immCode = secondOpRe.sub(immOp2, code)
- immIop = InstObjParams(mnem, mnem.capitalize() + "Imm", "DataImmOp",
+ immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp",
{"code" : immCode,
"predicate_test": predicateTest})
- immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "ImmCc",
+ immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
"DataImmOp",
{"code" : immCode + immCcCode,
"predicate_test": predicateTest})
- header_output += DataImmDeclare.subst(immIop) + \
- DataImmDeclare.subst(immIopCc)
- decoder_output += DataImmConstructor.subst(immIop) + \
- DataImmConstructor.subst(immIopCc)
- exec_output += PredOpExecute.subst(immIop) + \
- PredOpExecute.subst(immIopCc)
-
- def buildRegDataInst(mnem, code, flagType = "logic"):
- global header_output, decoder_output, exec_output
+
+ def subst(iop):
+ global header_output, decoder_output, exec_output
+ header_output += DataImmDeclare.subst(iop)
+ decoder_output += DataImmConstructor.subst(iop)
+ exec_output += PredOpExecute.subst(iop)
+
+ subst(immIop)
+ if buildCc:
+ subst(immIopCc)
+
+ def buildRegDataInst(mnem, code, flagType = "logic", \
+ suffix = "Reg", buildCc = True):
cCode = carryCode[flagType]
vCode = overflowCode[flagType]
negBit = 31
@@ -144,22 +148,26 @@ let {{
"negBit": negBit
}
regCode = secondOpRe.sub(regOp2, code)
- regIop = InstObjParams(mnem, mnem.capitalize() + "Reg", "DataRegOp",
+ regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp",
{"code" : regCode,
"predicate_test": predicateTest})
- regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "RegCc",
+ regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
"DataRegOp",
{"code" : regCode + regCcCode,
"predicate_test": predicateTest})
- header_output += DataRegDeclare.subst(regIop) + \
- DataRegDeclare.subst(regIopCc)
- decoder_output += DataRegConstructor.subst(regIop) + \
- DataRegConstructor.subst(regIopCc)
- exec_output += PredOpExecute.subst(regIop) + \
- PredOpExecute.subst(regIopCc)
-
- def buildRegRegDataInst(mnem, code, flagType = "logic"):
- global header_output, decoder_output, exec_output
+
+ def subst(iop):
+ global header_output, decoder_output, exec_output
+ header_output += DataRegDeclare.subst(iop)
+ decoder_output += DataRegConstructor.subst(iop)
+ exec_output += PredOpExecute.subst(iop)
+
+ subst(regIop)
+ if buildCc:
+ subst(regIopCc)
+
+ def buildRegRegDataInst(mnem, code, flagType = "logic", \
+ suffix = "RegReg", buildCc = True):
cCode = carryCode[flagType]
vCode = overflowCode[flagType]
negBit = 31
@@ -174,53 +182,72 @@ let {{
"negBit": negBit
}
regRegCode = secondOpRe.sub(regRegOp2, code)
- regRegIop = InstObjParams(mnem, mnem.capitalize() + "RegReg",
+ regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix,
"DataRegRegOp",
{"code" : regRegCode,
"predicate_test": predicateTest})
regRegIopCc = InstObjParams(mnem + "s",
- mnem.capitalize() + "RegRegCc",
+ mnem.capitalize() + suffix + "Cc",
"DataRegRegOp",
{"code" : regRegCode + regRegCcCode,
"predicate_test": predicateTest})
- header_output += DataRegRegDeclare.subst(regRegIop) + \
- DataRegRegDeclare.subst(regRegIopCc)
- decoder_output += DataRegRegConstructor.subst(regRegIop) + \
- DataRegRegConstructor.subst(regRegIopCc)
- exec_output += PredOpExecute.subst(regRegIop) + \
- PredOpExecute.subst(regRegIopCc)
-
- def buildDataInst(mnem, code, flagType = "logic"):
- buildImmDataInst(mnem, code, flagType)
- buildRegDataInst(mnem, code, flagType)
- buildRegRegDataInst(mnem, code, flagType)
-
- buildDataInst("and", "AIWDest = resTemp = Op1 & secondOp;")
- buildDataInst("eor", "AIWDest = resTemp = Op1 ^ secondOp;")
- buildDataInst("sub", "AIWDest = resTemp = Op1 - secondOp;", "sub")
- buildDataInst("rsb", "AIWDest = resTemp = secondOp - Op1;", "rsb")
- buildDataInst("add", "AIWDest = resTemp = Op1 + secondOp;", "add")
+
+ def subst(iop):
+ global header_output, decoder_output, exec_output
+ header_output += DataRegRegDeclare.subst(iop)
+ decoder_output += DataRegRegConstructor.subst(iop)
+ exec_output += PredOpExecute.subst(iop)
+
+ subst(regRegIop)
+ if buildCc:
+ subst(regRegIopCc)
+
+ def buildDataInst(mnem, code, flagType = "logic", \
+ aiw = True, regRegAiw = True,
+ subsPcLr = True):
+ regRegCode = instCode = code
+ if aiw:
+ instCode = "AIW" + instCode
+ if regRegAiw:
+ regRegCode = "AIW" + regRegCode
+
+ buildImmDataInst(mnem, instCode, flagType)
+ buildRegDataInst(mnem, instCode, flagType)
+ buildRegRegDataInst(mnem, regRegCode, flagType)
+ if subsPcLr:
+ code += '''
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes, Spsr, 0xF, true);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ '''
+ buildImmDataInst(mnem + 's', code, flagType,
+ suffix = "ImmPclr", buildCc = False)
+ buildRegDataInst(mnem + 's', code, flagType,
+ suffix = "RegPclr", buildCc = False)
+
+ buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
+ buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
+ buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub")
+ buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
+ buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add")
buildImmDataInst("adr", '''
- AIWDest = resTemp = (readPC(xc) & ~0x3) +
+ Dest = resTemp = (readPC(xc) & ~0x3) +
(op1 ? secondOp : -secondOp);
''')
- buildDataInst("adc", "AIWDest = resTemp = Op1 + secondOp + %s;" % oldC,
- "add")
- buildDataInst("sbc", "AIWDest = resTemp = Op1 - secondOp - !%s;" % oldC,
- "sub")
- buildDataInst("rsc", "AIWDest = resTemp = secondOp - Op1 - !%s;" % oldC,
- "rsb")
- buildDataInst("tst", "resTemp = Op1 & secondOp;")
- buildDataInst("teq", "resTemp = Op1 ^ secondOp;")
- buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub")
- buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add")
- buildDataInst("orr", "AIWDest = resTemp = Op1 | secondOp;")
- buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;")
- buildImmDataInst("mov", "AIWDest = resTemp = secondOp;")
- buildRegDataInst("mov", "AIWDest = resTemp = secondOp;")
- buildRegRegDataInst("mov", "Dest = resTemp = secondOp;")
- buildDataInst("bic", "AIWDest = resTemp = Op1 & ~secondOp;")
- buildDataInst("mvn", "AIWDest = resTemp = ~secondOp;")
+ buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
+ buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
+ buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
+ buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False)
+ buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False)
+ buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False)
+ buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False)
+ buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
+ buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False)
+ buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False)
+ buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
+ buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
buildDataInst("movt",
- "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);")
+ "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);",
+ aiw = False)
}};