summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/formats
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/isa/formats')
-rw-r--r--src/arch/arm/isa/formats/branch.isa4
-rw-r--r--src/arch/arm/isa/formats/fp.isa4
-rw-r--r--src/arch/arm/isa/formats/macromem.isa126
-rw-r--r--src/arch/arm/isa/formats/pred.isa90
-rw-r--r--src/arch/arm/isa/formats/unimp.isa2
-rw-r--r--src/arch/arm/isa/formats/unknown.isa2
-rw-r--r--src/arch/arm/isa/formats/util.isa6
7 files changed, 136 insertions, 98 deletions
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index 95f4f14e1..5f1b541ff 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{
else:
inst_flags += ('IsCondControl', )
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = NPC + 4 + disp;\n'
icode += '} else {\n'
@@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{
#Condition code
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
icode += '} else {\n'
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index e88531580..e79529615 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -119,8 +119,8 @@ let {{
_ic = %(fReg1)s >= %(fReg2)s;
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
'''
}};
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index 355a67ea9..c834c22cb 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -72,6 +72,18 @@ let {{
'predicate_test': predicateTest},
['IsMicroop'])
+ microLdrRetUopCode = '''
+ Ra = Mem;
+ Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
+ '''
+ microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
+ 'MicroMemOp',
+ {'memacc_code': microLdrRetUopCode,
+ 'ea_code':
+ 'EA = Rb + (UP ? imm : -imm);',
+ 'predicate_test': predicateTest},
+ ['IsMicroop'])
+
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
'MicroMemOp',
{'memacc_code': 'Mem = Ra;',
@@ -80,14 +92,19 @@ let {{
['IsMicroop'])
header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+ MicroMemDeclare.subst(microLdrRetUopIop) + \
MicroMemDeclare.subst(microStrUopIop)
decoder_output = MicroConstructor.subst(microLdrUopIop) + \
+ MicroConstructor.subst(microLdrRetUopIop) + \
MicroConstructor.subst(microStrUopIop)
exec_output = LoadExecute.subst(microLdrUopIop) + \
+ LoadExecute.subst(microLdrRetUopIop) + \
StoreExecute.subst(microStrUopIop) + \
LoadInitiateAcc.subst(microLdrUopIop) + \
+ LoadInitiateAcc.subst(microLdrRetUopIop) + \
StoreInitiateAcc.subst(microStrUopIop) + \
LoadCompleteAcc.subst(microLdrUopIop) + \
+ LoadCompleteAcc.subst(microLdrRetUopIop) + \
StoreCompleteAcc.subst(microStrUopIop)
}};
@@ -178,73 +195,64 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
- uint32_t regs_to_handle = reglist;
- uint32_t start_addr = 0;
+ uint32_t regs = reglist;
+ uint32_t addr = 0;
+ bool up = machInst.puswl.up;
- switch (puswl)
- {
- case 0x00: // stmda
- case 0x01: // L ldmda_l
- case 0x02: // W stmda_w
- case 0x03: // WL ldmda_wl
- start_addr = (ones << 2) - 4;
- break;
- case 0x08: // U stmia_u
- case 0x09: // U L ldmia_ul
- case 0x0a: // U W stmia
- case 0x0b: // U WL ldmia
- start_addr = 0;
- break;
- case 0x10: // P stmdb
- case 0x11: // P L ldmdb
- case 0x12: // P W stmdb
- case 0x13: // P WL ldmdb
- start_addr = (ones << 2); // U-bit is already 0 for subtract
- break;
- case 0x18: // PU stmib
- case 0x19: // PU L ldmib
- case 0x1a: // PU W stmib
- case 0x1b: // PU WL ldmib
- start_addr = 4;
- break;
- default:
- panic("Unhandled Load/Store Multiple Instruction, "
- "puswl = 0x%x", (unsigned) puswl);
- break;
- }
+ if (!up)
+ addr = (ones << 2) - 4;
+
+ if (machInst.puswl.prepost)
+ addr += 4;
- // Add 0 to Rn and stick it in Raddr (register 17).
+ // Add 0 to Rn and stick it in ureg0.
// This is equivalent to a move.
- microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
+ microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
- unsigned j = 0;
- for (int i = 1; i < ones+1; i++) {
- // Get next available bit for transfer
- while (! ( regs_to_handle & (1<<j)))
- j++;
- regs_to_handle &= ~(1<<j);
+ unsigned reg = 0;
+ bool force_user = machInst.puswl.psruser & !OPCODE_15;
+ bool exception_ret = machInst.puswl.psruser & OPCODE_15;
- if (loadop)
- microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
- else
- microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
+ for (int i = 1; i < ones + 1; i++) {
+ // Find the next register.
+ while (!bits(regs, reg))
+ reg++;
+ replaceBits(regs, reg, 0);
+
+ unsigned regIdx = reg;
+ if (force_user) {
+ regIdx = intRegForceUser(regIdx);
+ }
+
+ if (machInst.puswl.loadOp) {
+ if (reg == INTREG_PC && exception_ret) {
+ // This must be the exception return form of ldm.
+ microOps[i] =
+ new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
+ } else {
+ microOps[i] =
+ new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
+ } else {
+ microOps[i] =
+ new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
if (up)
- start_addr += 4;
+ addr += 4;
else
- start_addr -= 4;
+ addr -= 4;
}
- if (writeback) {
+ StaticInstPtr &lastUop = microOps[numMicroops - 1];
+ if (machInst.puswl.writeback) {
if (up) {
- microOps[numMicroops-1] =
- new MicroAddiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
} else {
- microOps[numMicroops-1] =
- new MicroSubiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ lastUop->setLastMicroop();
}
}};
@@ -285,14 +293,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback)
{
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
@@ -316,14 +324,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback) {
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
index e90788c91..0d6ee32f7 100644
--- a/src/arch/arm/isa/formats/pred.isa
+++ b/src/arch/arm/isa/formats/pred.isa
@@ -34,7 +34,7 @@
//
let {{
- predicateTest = 'testPredicate(Cpsr, condCode)'
+ predicateTest = 'testPredicate(CondCodes, condCode)'
}};
def template PredOpExecute {{
@@ -81,32 +81,45 @@ def template DataImmDecode {{
}};
let {{
+
+ calcCcCode = '''
+ if (%(canOverflow)s){
+ cprintf("canOverflow: %%d\\n", Rd < resTemp);
+ replaceBits(CondCodes, 27, Rd < resTemp);
+ } else {
+ uint16_t _ic, _iv, _iz, _in;
+ _in = (resTemp >> %(negBit)d) & 1;
+ _iz = (resTemp == 0);
+ _iv = %(ivValue)s & 1;
+ _ic = %(icValue)s & 1;
+
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
- calcCcCode = '''
- uint16_t _ic, _iv, _iz, _in;
-
- _in = (resTemp >> 31) & 1;
- _iz = (resTemp == 0);
- _iv = %(ivValue)s & 1;
- _ic = %(icValue)s & 1;
-
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
-
- DPRINTF(Arm, "in = %%d\\n", _in);
- DPRINTF(Arm, "iz = %%d\\n", _iz);
- DPRINTF(Arm, "ic = %%d\\n", _ic);
- DPRINTF(Arm, "iv = %%d\\n", _iv);
+ DPRINTF(Arm, "in = %%d\\n", _in);
+ DPRINTF(Arm, "iz = %%d\\n", _iz);
+ DPRINTF(Arm, "ic = %%d\\n", _ic);
+ DPRINTF(Arm, "iv = %%d\\n", _iv);
+ }
'''
-
}};
let {{
def getCcCode(flagtype):
icReg = icImm = iv = ''
+ negBit = 31
+ canOverflow = 'false'
+
if flagtype == "none":
- icReg = icImm = 'Cpsr<29:>'
- iv = 'Cpsr<28:>'
+ icReg = icImm = 'CondCodes<29:>'
+ iv = 'CondCodes<28:>'
+ elif flagtype == "llbit":
+ icReg = icImm = 'CondCodes<29:>'
+ iv = 'CondCodes<28:>'
+ negBit = 63
+ elif flagtype == "overflow":
+ canOverflow = "true"
+ icReg = icImm = iv = '0'
elif flagtype == "add":
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
iv = 'findOverflow(32, resTemp, Rn, op2)'
@@ -117,17 +130,32 @@ let {{
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
else:
- icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)'
- icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)'
- iv = 'Cpsr<28:>'
- return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
- calcCcCode % {"icValue" : icImm, "ivValue" : iv})
+ icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
+ icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
+ iv = 'CondCodes<28:>'
+ return (calcCcCode % {"icValue" : icReg,
+ "ivValue" : iv,
+ "negBit" : negBit,
+ "canOverflow" : canOverflow },
+ calcCcCode % {"icValue" : icImm,
+ "ivValue" : iv,
+ "negBit" : negBit,
+ "canOverflow" : canOverflow })
def getImmCcCode(flagtype):
ivValue = icValue = ''
+ negBit = 31
+ canOverflow = 'false'
if flagtype == "none":
- icValue = 'Cpsr<29:>'
- ivValue = 'Cpsr<28:>'
+ icValue = 'CondCodes<29:>'
+ ivValue = 'CondCodes<28:>'
+ elif flagtype == "llbit":
+ icValue = 'CondCodes<29:>'
+ ivValue = 'CondCodes<28:>'
+ negBit = 63
+ elif flagtype == "overflow":
+ icVaule = ivValue = '0'
+ canOverflow = "true"
elif flagtype == "add":
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
@@ -138,18 +166,18 @@ let {{
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
else:
- icValue = '(rotate ? rotated_carry:Cpsr<29:>)'
- ivValue = 'Cpsr<28:>'
+ icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
+ ivValue = 'CondCodes<28:>'
return calcCcCode % vars()
}};
def format DataOp(code, flagtype = logic) {{
(regCcCode, immCcCode) = getCcCode(flagtype)
- regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
- shift, Cpsr<29:0>);
+ regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
+ shift, CondCodes<29:>);
op2 = op2;''' + code
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
- shift, Cpsr<29:0>);
+ shift, CondCodes<29:>);
op2 = op2;''' + code
regIop = InstObjParams(name, Name, 'PredIntOp',
{"code": regCode,
diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa
index c82bb41c6..6909c3f85 100644
--- a/src/arch/arm/isa/formats/unimp.isa
+++ b/src/arch/arm/isa/formats/unimp.isa
@@ -115,7 +115,7 @@ output exec {{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
Fault
diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa
index 2ad7a2506..97a0caa6b 100644
--- a/src/arch/arm/isa/formats/unknown.isa
+++ b/src/arch/arm/isa/formats/unknown.isa
@@ -74,7 +74,7 @@ output exec {{
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
}};
diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa
index b5efec568..d42ffb147 100644
--- a/src/arch/arm/isa/formats/util.isa
+++ b/src/arch/arm/isa/formats/util.isa
@@ -33,8 +33,10 @@ let {{
# Generic substitutions for Arm instructions
def ArmGenericCodeSubs(code):
# Substitute in the shifted portion of operations
- new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code)
- new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code)
+ new_code = re.sub(r'Rm_Imm',
+ 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code)
+ new_code = re.sub(r'Rm_Rs',
+ 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code)
return new_code
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,