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:
parent
e097c4fb18
commit
401165c778
18 changed files with 206 additions and 117 deletions
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 + '''
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {{
|
||||||
|
|
|
@ -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 {{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue