ARM: Split the condition codes out of the CPSR.
This allows those bits to be renamed while allowing the other fields to control the behavior of the processor.
This commit is contained in:
@@ -104,6 +104,7 @@ enum IntRegIndex
|
||||
INTREG_UREG0,
|
||||
INTREG_RHI,
|
||||
INTREG_RLO,
|
||||
INTREG_CONDCODES,
|
||||
|
||||
NUM_INTREGS,
|
||||
NUM_ARCH_INTREGS = INTREG_PC + 1,
|
||||
|
||||
@@ -91,9 +91,9 @@ format DataOp {
|
||||
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
|
||||
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
|
||||
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
|
||||
0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add);
|
||||
0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub);
|
||||
0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb);
|
||||
0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add);
|
||||
0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub);
|
||||
0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb);
|
||||
0x8: tst({{ resTemp = Rn & op2; }});
|
||||
0x9: teq({{ resTemp = Rn ^ op2; }});
|
||||
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
|
||||
@@ -163,9 +163,15 @@ format DataOp {
|
||||
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
|
||||
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
|
||||
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
|
||||
0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add);
|
||||
0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub);
|
||||
0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb);
|
||||
0x5: adci({{
|
||||
Rd = resTemp = Rn + rotated_imm + CondCodes<29:>;
|
||||
}}, add);
|
||||
0x6: sbci({{
|
||||
Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>;
|
||||
}}, sub);
|
||||
0x7: rsci({{
|
||||
Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>;
|
||||
}}, rsb);
|
||||
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
|
||||
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
|
||||
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
|
||||
@@ -437,7 +443,7 @@ format DataOp {
|
||||
}
|
||||
format PredOp {
|
||||
// ARM System Call (SoftWare Interrupt)
|
||||
1: swi({{ if (testPredicate(Cpsr, condCode))
|
||||
1: swi({{ if (testPredicate(CondCodes, condCode))
|
||||
{
|
||||
if (IMMED_23_0)
|
||||
xc->syscall(IMMED_23_0);
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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);
|
||||
'''
|
||||
}};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
//
|
||||
|
||||
let {{
|
||||
predicateTest = 'testPredicate(Cpsr, condCode)'
|
||||
predicateTest = 'testPredicate(CondCodes, condCode)'
|
||||
}};
|
||||
|
||||
def template PredOpExecute {{
|
||||
@@ -90,8 +90,8 @@ let {{
|
||||
_iv = %(ivValue)s & 1;
|
||||
_ic = %(icValue)s & 1;
|
||||
|
||||
Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
||||
(Cpsr & 0x0FFFFFFF);
|
||||
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
||||
(CondCodes & 0x0FFFFFFF);
|
||||
|
||||
DPRINTF(Arm, "in = %%d\\n", _in);
|
||||
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
||||
@@ -105,8 +105,8 @@ let {{
|
||||
def getCcCode(flagtype):
|
||||
icReg = icImm = iv = ''
|
||||
if flagtype == "none":
|
||||
icReg = icImm = 'Cpsr<29:>'
|
||||
iv = 'Cpsr<28:>'
|
||||
icReg = icImm = 'CondCodes<29:>'
|
||||
iv = 'CondCodes<28:>'
|
||||
elif flagtype == "add":
|
||||
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
|
||||
iv = 'findOverflow(32, resTemp, Rn, op2)'
|
||||
@@ -117,17 +117,17 @@ 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:>'
|
||||
icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)'
|
||||
icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
|
||||
iv = 'CondCodes<28:>'
|
||||
return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
|
||||
calcCcCode % {"icValue" : icImm, "ivValue" : iv})
|
||||
|
||||
def getImmCcCode(flagtype):
|
||||
ivValue = icValue = ''
|
||||
if flagtype == "none":
|
||||
icValue = 'Cpsr<29:>'
|
||||
ivValue = 'Cpsr<28:>'
|
||||
icValue = 'CondCodes<29:>'
|
||||
ivValue = 'CondCodes<28:>'
|
||||
elif flagtype == "add":
|
||||
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
|
||||
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
|
||||
@@ -138,18 +138,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>);
|
||||
shift, CondCodes<29:0>);
|
||||
op2 = op2;''' + code
|
||||
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
|
||||
shift, Cpsr<29:0>);
|
||||
shift, CondCodes<29:0>);
|
||||
op2 = op2;''' + code
|
||||
regIop = InstObjParams(name, Name, 'PredIntOp',
|
||||
{"code": regCode,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -66,6 +66,7 @@ def operands {{
|
||||
'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7),
|
||||
'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8),
|
||||
'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
|
||||
'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10),
|
||||
|
||||
#Register fields for microops
|
||||
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
|
||||
|
||||
@@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
|
||||
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
|
||||
|
||||
//CPSR
|
||||
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
|
||||
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
|
||||
tc->readIntReg(INTREG_CONDCODES);
|
||||
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user