summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/isa/formats/data.isa49
-rw-r--r--src/arch/arm/isa/insts/data.isa4
2 files changed, 43 insertions, 10 deletions
diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa
index 3643fa88f..45dedff2c 100644
--- a/src/arch/arm/isa/formats/data.isa
+++ b/src/arch/arm/isa/formats/data.isa
@@ -103,7 +103,6 @@ def format ArmDataProcReg() {{
def format ArmDataProcImm() {{
instDecode = '''
- case %(opcode)#x:
if (setCc) {
return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
imm, rotC);
@@ -116,10 +115,30 @@ def format ArmDataProcImm() {{
def instCode(opcode, mnem, dest="rd", op1="rn"):
global instDecode
- return instDecode % { "className": mnem.capitalize(),
- "opcode": opcode,
- "dest": dest,
- "op1": op1 }
+ code = '''
+ case %(opcode)#x:
+ ''' + instDecode
+ return code % { "className": mnem.capitalize(),
+ "opcode": opcode,
+ "dest": dest,
+ "op1": op1 }
+
+ 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 }
decode_block = '''
{
@@ -134,9 +153,9 @@ def format ArmDataProcImm() {{
'''
decode_block += instCode(0x0, "and")
decode_block += instCode(0x1, "eor")
- decode_block += instCode(0x2, "sub")
+ decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
decode_block += instCode(0x3, "rsb")
- decode_block += instCode(0x4, "add")
+ decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
decode_block += instCode(0x5, "adc")
decode_block += instCode(0x6, "sbc")
decode_block += instCode(0x7, "rsc")
@@ -274,7 +293,7 @@ def format Thumb16Adr() {{
{
const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
const uint32_t imm8 = bits(machInst, 7, 0) << 2;
- return new AddImm(machInst, rd, INTREG_PC, imm8, true);
+ return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
}
'''
}};
@@ -491,7 +510,12 @@ def format Thumb32DataProcPlainBin() {{
const uint32_t imm = bits(machInst, 7, 0) |
(bits(machInst, 14, 12) << 8) |
(bits(machInst, 26) << 11);
- return new AddImm(machInst, rd, rn, imm, true);
+ if (rn == 0xf) {
+ return new AdrImm(machInst, rd, (IntRegIndex)1,
+ imm, false);
+ } else {
+ return new AddImm(machInst, rd, rn, imm, true);
+ }
}
case 0x4:
{
@@ -506,7 +530,12 @@ def format Thumb32DataProcPlainBin() {{
const uint32_t imm = bits(machInst, 7, 0) |
(bits(machInst, 14, 12) << 8) |
(bits(machInst, 26) << 11);
- return new SubImm(machInst, rd, rn, imm, true);
+ if (rn == 0xf) {
+ return new AdrImm(machInst, rd, (IntRegIndex)0,
+ imm, false);
+ } else {
+ return new SubImm(machInst, rd, rn, imm, true);
+ }
}
case 0xc:
{
diff --git a/src/arch/arm/isa/insts/data.isa b/src/arch/arm/isa/insts/data.isa
index a3418edf0..02ecd6b4c 100644
--- a/src/arch/arm/isa/insts/data.isa
+++ b/src/arch/arm/isa/insts/data.isa
@@ -200,6 +200,10 @@ let {{
buildDataInst("sub", "AIWDest = resTemp = Op1 - secondOp;", "sub")
buildDataInst("rsb", "AIWDest = resTemp = secondOp - Op1;", "rsb")
buildDataInst("add", "AIWDest = resTemp = Op1 + secondOp;", "add")
+ buildImmDataInst("adr", '''
+ AIWDest = resTemp = (readPC(xc) & ~0x3) +
+ (op1 ? secondOp : -secondOp);
+ ''')
buildDataInst("adc", "AIWDest = resTemp = Op1 + secondOp + %s;" % oldC,
"add")
buildDataInst("sbc", "AIWDest = resTemp = Op1 - secondOp - !%s;" % oldC,