ARM: Further break up condition code into NZ, C, V bits.

Break up the condition code bits into NZ, C, V registers. These are individually
written and this removes some incorrect dependencies between instructions.
This commit is contained in:
Ali Saidi 2011-05-13 17:27:01 -05:00
parent e097c4fb18
commit 401165c778
18 changed files with 206 additions and 117 deletions

View file

@ -106,9 +106,12 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) | CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR);
tc->readIntReg(INTREG_CONDCODES_F) | saved_cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ);
tc->readIntReg(INTREG_CONDCODES_GE); saved_cpsr.c = tc->readIntReg(INTREG_CONDCODES_C);
saved_cpsr.v = tc->readIntReg(INTREG_CONDCODES_V);
saved_cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE);
Addr curPc M5_VAR_USED = tc->pcState().pc(); Addr curPc M5_VAR_USED = tc->pcState().pc();
ITSTATE it = tc->pcState().itstate(); ITSTATE it = tc->pcState().itstate();
saved_cpsr.it2 = it.top6; saved_cpsr.it2 = it.top6;

View file

@ -112,7 +112,9 @@ enum IntRegIndex
INTREG_UREG0, INTREG_UREG0,
INTREG_UREG1, INTREG_UREG1,
INTREG_UREG2, INTREG_UREG2,
INTREG_CONDCODES_F, INTREG_CONDCODES_NZ,
INTREG_CONDCODES_C,
INTREG_CONDCODES_V,
INTREG_CONDCODES_GE, INTREG_CONDCODES_GE,
INTREG_FPCONDCODES, INTREG_FPCONDCODES,

View file

@ -2068,14 +2068,8 @@ let {{
return new Unknown(machInst); return new Unknown(machInst);
} }
if (rt == 0xf) { if (rt == 0xf) {
CPSR cpsrMask = 0;
cpsrMask.n = 1;
cpsrMask.z = 1;
cpsrMask.c = 1;
cpsrMask.v = 1;
if (specReg == MISCREG_FPSCR) { if (specReg == MISCREG_FPSCR) {
return new VmrsApsrFpscr(machInst, INTREG_CONDCODES_F, return new VmrsApsrFpscr(machInst);
(IntRegIndex)specReg, (uint32_t)cpsrMask);
} else { } else {
return new Unknown(machInst); return new Unknown(machInst);
} }

View file

@ -53,7 +53,9 @@ let {{
_iv = %(ivValue)s & 1; _iv = %(ivValue)s & 1;
_ic = %(icValue)s & 1; _ic = %(icValue)s & 1;
CondCodesF = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28; CondCodesNZ = (_in << 1) | (_iz);
CondCodesC = _ic;
CondCodesV = _iv;
DPRINTF(Arm, "in = %%d\\n", _in); DPRINTF(Arm, "in = %%d\\n", _in);
DPRINTF(Arm, "iz = %%d\\n", _iz); DPRINTF(Arm, "iz = %%d\\n", _iz);
@ -70,11 +72,11 @@ let {{
canOverflow = 'false' canOverflow = 'false'
if flagtype == "none": if flagtype == "none":
icReg = icImm = 'CondCodesF<29:>' icReg = icImm = 'CondCodesC'
iv = 'CondCodesF<28:>' iv = 'CondCodesV'
elif flagtype == "llbit": elif flagtype == "llbit":
icReg = icImm = 'CondCodesF<29:>' icReg = icImm = 'CondCodesC'
iv = 'CondCodesF<28:>' iv = 'CondCodesV'
negBit = 63 negBit = 63
elif flagtype == "overflow": elif flagtype == "overflow":
canOverflow = "true" canOverflow = "true"
@ -89,9 +91,9 @@ let {{
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)' icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
iv = 'findOverflow(32, resTemp, op2, ~Rn)' iv = 'findOverflow(32, resTemp, op2, ~Rn)'
else: else:
icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodesF<29:>)' icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodesC)'
icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodesF<29:>)' icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodesC)'
iv = 'CondCodesF<28:>' iv = 'CondCodesV'
return (calcCcCode % {"icValue" : icReg, return (calcCcCode % {"icValue" : icReg,
"ivValue" : iv, "ivValue" : iv,
"negBit" : negBit, "negBit" : negBit,
@ -106,11 +108,11 @@ let {{
negBit = 31 negBit = 31
canOverflow = 'false' canOverflow = 'false'
if flagtype == "none": if flagtype == "none":
icValue = 'CondCodesF<29:>' icValue = 'CondCodesC'
ivValue = 'CondCodesF<28:>' ivValue = 'CondCodesV'
elif flagtype == "llbit": elif flagtype == "llbit":
icValue = 'CondCodesF<29:>' icValue = 'CondCodesC'
ivValue = 'CondCodesF<28:>' ivValue = 'CondCodesV'
negBit = 63 negBit = 63
elif flagtype == "overflow": elif flagtype == "overflow":
icVaule = ivValue = '0' icVaule = ivValue = '0'
@ -126,20 +128,20 @@ let {{
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)' ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
elif flagtype == "modImm": elif flagtype == "modImm":
icValue = 'rotated_carry' icValue = 'rotated_carry'
ivValue = 'CondCodesF<28:>' ivValue = 'CondCodesV'
else: else:
icValue = '(rotate ? rotated_carry:CondCodesF<29:>)' icValue = '(rotate ? rotated_carry:CondCodesC)'
ivValue = 'CondCodesF<28:>' ivValue = 'CondCodesV'
return calcCcCode % vars() return calcCcCode % vars()
}}; }};
def format DataOp(code, flagtype = logic) {{ def format DataOp(code, flagtype = logic) {{
(regCcCode, immCcCode) = getCcCode(flagtype) (regCcCode, immCcCode) = getCcCode(flagtype)
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>, regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
shift, CondCodesF<29:>); shift, CondCodesC);
op2 = op2;''' + code op2 = op2;''' + code
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size, immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
shift, CondCodesF<29:>); shift, CondCodesC);
op2 = op2;''' + code op2 = op2;''' + code
regIop = InstObjParams(name, Name, 'PredIntOp', regIop = InstObjParams(name, Name, 'PredIntOp',
{"code": regCode, {"code": regCode,

View file

@ -44,7 +44,7 @@ let {{
exec_output = "" exec_output = ""
calcGECode = ''' calcGECode = '''
CondCodesGE = insertBits(0, 19, 16, resTemp); CondCodesGE = resTemp;
''' '''
calcQCode = ''' calcQCode = '''
@ -58,15 +58,17 @@ let {{
_iv = %(ivValue)s & 1; _iv = %(ivValue)s & 1;
_ic = %(icValue)s & 1; _ic = %(icValue)s & 1;
CondCodesF = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28; CondCodesNZ = (_in << 1) | _iz;
CondCodesC = _ic;
CondCodesV = _iv;
DPRINTF(Arm, "(in, iz, ic, iv) = (%%d, %%d, %%d, %%d)\\n", DPRINTF(Arm, "(in, iz, ic, iv) = (%%d, %%d, %%d, %%d)\\n",
_in, _iz, _ic, _iv); _in, _iz, _ic, _iv);
''' '''
# Dict of code to set the carry flag. (imm, reg, reg-reg) # Dict of code to set the carry flag. (imm, reg, reg-reg)
oldC = 'CondCodesF<29:>' oldC = 'CondCodesC'
oldV = 'CondCodesF<28:>' oldV = 'CondCodesV'
carryCode = { carryCode = {
"none": (oldC, oldC, oldC), "none": (oldC, oldC, oldC),
"llbit": (oldC, oldC, oldC), "llbit": (oldC, oldC, oldC),
@ -101,8 +103,8 @@ let {{
secondOpRe = re.compile("secondOp") secondOpRe = re.compile("secondOp")
immOp2 = "imm" immOp2 = "imm"
regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodesF<29:>)" regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodesC)"
regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodesF<29:>)" regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodesC)"
def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \ def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \
buildCc = True, buildNonCc = True, instFlags = []): buildCc = True, buildNonCc = True, instFlags = []):
@ -238,16 +240,24 @@ let {{
if subsPcLr: if subsPcLr:
code += ''' code += '''
SCTLR sctlr = Sctlr; SCTLR sctlr = Sctlr;
uint32_t newCpsr = CPSR old_cpsr = Cpsr;
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesGE, old_cpsr.nz = CondCodesNZ;
Spsr, 0xF, true, sctlr.nmfi); old_cpsr.c = CondCodesC;
Cpsr = ~CondCodesMask & newCpsr; old_cpsr.v = CondCodesV;
CondCodesF = CondCodesMaskF & newCpsr; old_cpsr.ge = CondCodesGE;
CondCodesGE = CondCodesMaskGE & newCpsr;
NextThumb = ((CPSR)newCpsr).t; CPSR new_cpsr =
NextJazelle = ((CPSR)newCpsr).j; cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
NextItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC) Cpsr = ~CondCodesMask & new_cpsr;
| (((CPSR)newCpsr).it1 & 0x3); CondCodesNZ = new_cpsr.nz;
CondCodesC = new_cpsr.c;
CondCodesV = new_cpsr.v;
CondCodesGE = new_cpsr.ge;
NextThumb = (new_cpsr).t;
NextJazelle = (new_cpsr).j;
NextItState = (((new_cpsr).it2 << 2) & 0xFC)
| ((new_cpsr).it1 & 0x3);
SevMailbox = 1; SevMailbox = 1;
''' '''
buildImmDataInst(mnem + 's', code, flagType, buildImmDataInst(mnem + 's', code, flagType,

View file

@ -235,16 +235,18 @@ let {{
decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop); decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
exec_output += PredOpExecute.subst(vmrsFpscrIop); exec_output += PredOpExecute.subst(vmrsFpscrIop);
vmrsApsrFpscrCode = vmrsEnabledCheckCode + ''' vmrsApsrFpscrCode = vmrsApsrEnabledCheckCode + '''
Dest = FpCondCodes & FpCondCodesMask; FPSCR fpscr = FpCondCodes;
CondCodesNZ = (fpscr.n << 1) | fpscr.z;
CondCodesC = fpscr.c;
CondCodesV = fpscr.v;
''' '''
vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "FpRegRegImmOp", vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "PredOp",
{ "code": vmrsApsrFpscrCode, { "code": vmrsApsrFpscrCode,
"predicate_test": predicateTest, "predicate_test": predicateTest,
"op_class": "SimdFloatMiscOp" }, "op_class": "SimdFloatMiscOp" })
["IsSerializeBefore"]) header_output += BasicDeclare.subst(vmrsApsrFpscrIop);
header_output += FpRegRegImmOpDeclare.subst(vmrsApsrFpscrIop); decoder_output += BasicConstructor.subst(vmrsApsrFpscrIop);
decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrFpscrIop);
exec_output += PredOpExecute.subst(vmrsApsrFpscrIop); exec_output += PredOpExecute.subst(vmrsApsrFpscrIop);
vmovImmSCode = vfpEnabledCheckCode + ''' vmovImmSCode = vfpEnabledCheckCode + '''

View file

@ -106,7 +106,11 @@ let {{
wbDiff = 8 wbDiff = 8
accCode = ''' accCode = '''
CPSR cpsr = Cpsr; CPSR cpsr = Cpsr;
URc = cpsr | CondCodesF | CondCodesGE; cpsr.nz = CondCodesNZ;
cpsr.c = CondCodesC;
cpsr.v = CondCodesV;
cpsr.ge = CondCodesGE;
URc = cpsr;
URa = cSwap<uint32_t>(Mem.ud, cpsr.e); URa = cSwap<uint32_t>(Mem.ud, cpsr.e);
URb = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e); URb = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
''' '''
@ -137,7 +141,7 @@ let {{
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
super(LoadRegInst, self).__init__(*args, **kargs) super(LoadRegInst, self).__init__(*args, **kargs)
self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
" shiftType, CondCodesF<29:>)" " shiftType, CondCodesC)"
if self.add: if self.add:
self.wbDecl = ''' self.wbDecl = '''
MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);

View file

@ -87,15 +87,21 @@ let {{
['IsMicroop']) ['IsMicroop'])
microRetUopCode = ''' microRetUopCode = '''
CPSR cpsr = Cpsr; CPSR old_cpsr = Cpsr;
SCTLR sctlr = Sctlr; SCTLR sctlr = Sctlr;
uint32_t newCpsr = old_cpsr.nz = CondCodesNZ;
cpsrWriteByInstr(cpsr | CondCodesF | CondCodesGE, old_cpsr.c = CondCodesC;
Spsr, 0xF, true, sctlr.nmfi); old_cpsr.v = CondCodesV;
Cpsr = ~CondCodesMask & newCpsr; old_cpsr.ge = CondCodesGE;
CondCodesF = CondCodesMaskF & newCpsr;
CondCodesGE = CondCodesMaskGE & newCpsr; CPSR new_cpsr =
IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0); cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
Cpsr = ~CondCodesMask & new_cpsr;
CondCodesNZ = new_cpsr.nz;
CondCodesC = new_cpsr.c;
CondCodesV = new_cpsr.v;
CondCodesGE = new_cpsr.ge;
IWNPC = cSwap(%s, old_cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
| (((CPSR)Spsr).it1 & 0x3); | (((CPSR)Spsr).it1 & 0x3);
SevMailbox = 1; SevMailbox = 1;
@ -587,7 +593,7 @@ let {{
{'code': {'code':
'''URa = URb + shift_rm_imm(URc, shiftAmt, '''URa = URb + shift_rm_imm(URc, shiftAmt,
shiftType, shiftType,
CondCodesF<29:>); CondCodesC);
''', ''',
'predicate_test': predicateTest}, 'predicate_test': predicateTest},
['IsMicroop']) ['IsMicroop'])
@ -603,7 +609,7 @@ let {{
{'code': {'code':
'''URa = URb - shift_rm_imm(URc, shiftAmt, '''URa = URb - shift_rm_imm(URc, shiftAmt,
shiftType, shiftType,
CondCodesF<29:>); CondCodesC);
''', ''',
'predicate_test': predicateTest}, 'predicate_test': predicateTest},
['IsMicroop']) ['IsMicroop'])
@ -625,16 +631,18 @@ let {{
CPSR cpsrOrCondCodes = URc; CPSR cpsrOrCondCodes = URc;
SCTLR sctlr = Sctlr; SCTLR sctlr = Sctlr;
pNPC = URa; pNPC = URa;
uint32_t newCpsr = CPSR new_cpsr =
cpsrWriteByInstr(cpsrOrCondCodes, URb, cpsrWriteByInstr(cpsrOrCondCodes, URb,
0xF, true, sctlr.nmfi); 0xF, true, sctlr.nmfi);
Cpsr = ~CondCodesMask & newCpsr; Cpsr = ~CondCodesMask & new_cpsr;
NextThumb = ((CPSR)newCpsr).t; NextThumb = new_cpsr.t;
NextJazelle = ((CPSR)newCpsr).j; NextJazelle = new_cpsr.j;
NextItState = ((((CPSR)URb).it2 << 2) & 0xFC) NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
| (((CPSR)URb).it1 & 0x3); | (((CPSR)URb).it1 & 0x3);
CondCodesF = CondCodesMaskF & newCpsr; CondCodesNZ = new_cpsr.nz;
CondCodesGE = CondCodesMaskGE & newCpsr; CondCodesC = new_cpsr.c;
CondCodesV = new_cpsr.v;
CondCodesGE = new_cpsr.ge;
''' '''
microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR', microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',

View file

@ -119,10 +119,35 @@ let {{
return (header_output, decoder_output, exec_output) return (header_output, decoder_output, exec_output)
def pickPredicate(blobs): def pickPredicate(blobs):
opt_nz = True
opt_c = True
opt_v = True
for val in blobs.values(): for val in blobs.values():
if re.search('(?<!Opt)CondCodesF', val): if re.search('(?<!Opt)CondCodesNZ', val):
return condPredicateTest opt_nz = False
return predicateTest if re.search('(?<!Opt)CondCodesC', val):
opt_c = False
if re.search('(?<!Opt)CondCodesV', val):
opt_v = False
# Build up the predicate piece by piece depending on which
# flags the instruction needs
predicate = 'testPredicate('
if opt_nz:
predicate += 'OptCondCodesNZ, '
else:
predicate += 'CondCodesNZ, '
if opt_c:
predicate += 'OptCondCodesC, '
else:
predicate += 'CondCodesC, '
if opt_v:
predicate += 'OptCondCodesV, '
else:
predicate += 'CondCodesV, '
predicate += 'condCode)'
return predicate
def memClassName(base, post, add, writeback, \ def memClassName(base, post, add, writeback, \
size=4, sign=False, user=False): size=4, sign=False, user=False):

View file

@ -61,7 +61,12 @@ let {{
header_output = decoder_output = exec_output = "" header_output = decoder_output = exec_output = ""
mrsCpsrCode = ''' mrsCpsrCode = '''
Dest = (Cpsr | CondCodesF | CondCodesGE) & 0xF8FF03DF CPSR cpsr = Cpsr;
cpsr.nz = CondCodesNZ;
cpsr.c = CondCodesC;
cpsr.v = CondCodesV;
cpsr.ge = CondCodesGE;
Dest = cpsr & 0xF8FF03DF
''' '''
mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp", mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
@ -83,12 +88,19 @@ let {{
msrCpsrRegCode = ''' msrCpsrRegCode = '''
SCTLR sctlr = Sctlr; SCTLR sctlr = Sctlr;
uint32_t newCpsr = CPSR old_cpsr = Cpsr;
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesGE, Op1, old_cpsr.nz = CondCodesNZ;
byteMask, false, sctlr.nmfi); old_cpsr.c = CondCodesC;
Cpsr = ~CondCodesMask & newCpsr; old_cpsr.v = CondCodesV;
CondCodesF = CondCodesMaskF & newCpsr; old_cpsr.ge = CondCodesGE;
CondCodesGE = CondCodesMaskGE & newCpsr;
CPSR new_cpsr =
cpsrWriteByInstr(old_cpsr, Op1, byteMask, false, sctlr.nmfi);
Cpsr = ~CondCodesMask & new_cpsr;
CondCodesNZ = new_cpsr.nz;
CondCodesC = new_cpsr.c;
CondCodesV = new_cpsr.v;
CondCodesGE = new_cpsr.ge;
''' '''
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp", msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
{ "code": msrCpsrRegCode, { "code": msrCpsrRegCode,
@ -109,12 +121,18 @@ let {{
msrCpsrImmCode = ''' msrCpsrImmCode = '''
SCTLR sctlr = Sctlr; SCTLR sctlr = Sctlr;
uint32_t newCpsr = CPSR old_cpsr = Cpsr;
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesGE, imm, old_cpsr.nz = CondCodesNZ;
byteMask, false, sctlr.nmfi); old_cpsr.c = CondCodesC;
Cpsr = ~CondCodesMask & newCpsr; old_cpsr.v = CondCodesV;
CondCodesF = CondCodesMaskF & newCpsr; old_cpsr.ge = CondCodesGE;
CondCodesGE = CondCodesMaskGE & newCpsr; CPSR new_cpsr =
cpsrWriteByInstr(old_cpsr, imm, byteMask, false, sctlr.nmfi);
Cpsr = ~CondCodesMask & new_cpsr;
CondCodesNZ = new_cpsr.nz;
CondCodesC = new_cpsr.c;
CondCodesV = new_cpsr.v;
CondCodesGE = new_cpsr.ge;
''' '''
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp", msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
{ "code": msrCpsrImmCode, { "code": msrCpsrImmCode,
@ -415,14 +433,14 @@ let {{
int low = i * 8; int low = i * 8;
int high = low + 7; int high = low + 7;
replaceBits(resTemp, high, low, replaceBits(resTemp, high, low,
bits(CondCodesGE, 16 + i) ? bits(CondCodesGE, i) ?
bits(Op1, high, low) : bits(Op2, high, low)); bits(Op1, high, low) : bits(Op2, high, low));
} }
Dest = resTemp; Dest = resTemp;
''' '''
selIop = InstObjParams("sel", "Sel", "RegRegRegOp", selIop = InstObjParams("sel", "Sel", "RegRegRegOp",
{ "code": selCode, { "code": selCode,
"predicate_test": condPredicateTest }, []) "predicate_test": predicateTest }, [])
header_output += RegRegRegOpDeclare.subst(selIop) header_output += RegRegRegOpDeclare.subst(selIop)
decoder_output += RegRegRegOpConstructor.subst(selIop) decoder_output += RegRegRegOpConstructor.subst(selIop)
exec_output += PredOpExecute.subst(selIop) exec_output += PredOpExecute.subst(selIop)

View file

@ -52,7 +52,7 @@ let {{
_in = (resTemp >> %(negBit)d) & 1; _in = (resTemp >> %(negBit)d) & 1;
_iz = ((%(zType)s)resTemp == 0); _iz = ((%(zType)s)resTemp == 0);
CondCodesF = _in << 31 | _iz << 30 | (CondCodesF & 0x3FFFFFFF); CondCodesNZ = (_in << 1) | _iz;
DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz); DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz);
''' '''

View file

@ -152,7 +152,7 @@ let {{
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
super(StoreRegInst, self).__init__(*args, **kargs) super(StoreRegInst, self).__init__(*args, **kargs)
self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
" shiftType, CondCodesF<29:>)" " shiftType, CondCodesC)"
if self.add: if self.add:
self.wbDecl = ''' self.wbDecl = '''
MicroAddUop(machInst, base, base, index, shiftAmt, shiftType); MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);

View file

@ -156,11 +156,24 @@ def operands {{
'R3': intRegNPC('3'), 'R3': intRegNPC('3'),
#Pseudo integer condition code registers #Pseudo integer condition code registers
'CondCodesF': intRegCC('INTREG_CONDCODES_F'), 'CondCodesNZ': intRegCC('INTREG_CONDCODES_NZ'),
'CondCodesC': intRegCC('INTREG_CONDCODES_C'),
'CondCodesV': intRegCC('INTREG_CONDCODES_V'),
'CondCodesGE': intRegCC('INTREG_CONDCODES_GE'), 'CondCodesGE': intRegCC('INTREG_CONDCODES_GE'),
'OptCondCodesF': intRegCC( 'OptCondCodesNZ': intRegCC(
'''(condCode == COND_AL || condCode == COND_UC) ? '''(condCode == COND_AL || condCode == COND_UC ||
INTREG_ZERO : INTREG_CONDCODES_F'''), condCode == COND_CC || condCode == COND_CS ||
condCode == COND_VS || condCode == COND_VC) ?
INTREG_ZERO : INTREG_CONDCODES_NZ'''),
'OptCondCodesC': intRegCC(
'''(condCode == COND_HI || condCode == COND_LS ||
condCode == COND_CS || condCode == COND_CC) ?
INTREG_CONDCODES_C : INTREG_ZERO'''),
'OptCondCodesV': intRegCC(
'''(condCode == COND_VS || condCode == COND_VC ||
condCode == COND_GE || condCode == COND_LT ||
condCode == COND_GT || condCode == COND_LE) ?
INTREG_CONDCODES_V : INTREG_ZERO'''),
'FpCondCodes': intRegCC('INTREG_FPCONDCODES'), 'FpCondCodes': intRegCC('INTREG_FPCONDCODES'),
#Abstracted floating point reg operands #Abstracted floating point reg operands

View file

@ -46,8 +46,8 @@
// //
let {{ let {{
predicateTest = 'testPredicate(OptCondCodesF, condCode)' predicateTest = 'testPredicate(OptCondCodesNZ, OptCondCodesC, OptCondCodesV, condCode)'
condPredicateTest = 'testPredicate(CondCodesF, condCode)' condPredicateTest = 'testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)'
}}; }};
def template DataImmDeclare {{ def template DataImmDeclare {{

View file

@ -62,6 +62,10 @@ let {{
if (op1 != (int)MISCREG_FPSCR) if (op1 != (int)MISCREG_FPSCR)
return disabledFault(); return disabledFault();
''' '''
vmrsApsrEnabledCheckCode = '''
if (!vfpEnabled(Cpacr, Cpsr))
return disabledFault();
'''
}}; }};
def template FpRegRegOpDeclare {{ def template FpRegRegOpDeclare {{

View file

@ -251,8 +251,7 @@ namespace ArmISA
}; };
BitUnion32(CPSR) BitUnion32(CPSR)
Bitfield<31> n; Bitfield<31,30> nz;
Bitfield<30> z;
Bitfield<29> c; Bitfield<29> c;
Bitfield<28> v; Bitfield<28> v;
Bitfield<27> q; Bitfield<27> q;
@ -271,9 +270,7 @@ namespace ArmISA
// This mask selects bits of the CPSR that actually go in the CondCodes // This mask selects bits of the CPSR that actually go in the CondCodes
// integer register to allow renaming. // integer register to allow renaming.
static const uint32_t CondCodesMask = 0xF00F0000; static const uint32_t CondCodesMask = 0xF00F0000;
static const uint32_t CondCodesMaskF = 0xF0000000;
static const uint32_t CpsrMaskQ = 0x08000000; static const uint32_t CpsrMaskQ = 0x08000000;
static const uint32_t CondCodesMaskGE = 0x000F0000;
BitUnion32(SCTLR) BitUnion32(SCTLR)
Bitfield<31> ie; // Instruction endianness Bitfield<31> ie; // Instruction endianness

View file

@ -115,9 +115,13 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
//CPSR //CPSR
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) | CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
tc->readIntReg(INTREG_CONDCODES_F) | cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ);
tc->readIntReg(INTREG_CONDCODES_GE); cpsr.c = tc->readIntReg(INTREG_CONDCODES_C);
cpsr.v = tc->readIntReg(INTREG_CONDCODES_V);
cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE);
newState[STATE_CPSR] = cpsr;
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
for (int i = 0; i < NumFloatArchRegs; i += 2) { for (int i = 0; i < NumFloatArchRegs; i += 2) {

View file

@ -65,24 +65,27 @@ buildRetPC(const PCState &curPC, const PCState &callPC)
} }
inline bool inline bool
testPredicate(CPSR cpsr, ConditionCode code) testPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code)
{ {
bool n = (nz & 0x2);
bool z = (nz & 0x1);
switch (code) switch (code)
{ {
case COND_EQ: return cpsr.z; case COND_EQ: return z;
case COND_NE: return !cpsr.z; case COND_NE: return !z;
case COND_CS: return cpsr.c; case COND_CS: return c;
case COND_CC: return !cpsr.c; case COND_CC: return !c;
case COND_MI: return cpsr.n; case COND_MI: return n;
case COND_PL: return !cpsr.n; case COND_PL: return !n;
case COND_VS: return cpsr.v; case COND_VS: return v;
case COND_VC: return !cpsr.v; case COND_VC: return !v;
case COND_HI: return (cpsr.c && !cpsr.z); case COND_HI: return (c && !z);
case COND_LS: return !(cpsr.c && !cpsr.z); case COND_LS: return !(c && !z);
case COND_GE: return !(cpsr.n ^ cpsr.v); case COND_GE: return !(n ^ v);
case COND_LT: return (cpsr.n ^ cpsr.v); case COND_LT: return (n ^ v);
case COND_GT: return !(cpsr.n ^ cpsr.v || cpsr.z); case COND_GT: return !(n ^ v || z);
case COND_LE: return (cpsr.n ^ cpsr.v || cpsr.z); case COND_LE: return (n ^ v || z);
case COND_AL: return true; case COND_AL: return true;
case COND_UC: return true; case COND_UC: return true;
default: default: