ARM: Break up condition codes into normal flags, saturation, and simd.
This change splits out the condcodes from being one monolithic register into three blocks that are updated independently. This allows CPUs to not have to do RMW operations on the flags registers for instructions that don't write all flags.
This commit is contained in:
parent
4bf48a11ef
commit
2178859b76
16 changed files with 94 additions and 82 deletions
|
@ -107,7 +107,9 @@ 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);
|
tc->readIntReg(INTREG_CONDCODES_F) |
|
||||||
|
tc->readIntReg(INTREG_CONDCODES_Q) |
|
||||||
|
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,
|
INTREG_CONDCODES_F,
|
||||||
|
INTREG_CONDCODES_Q,
|
||||||
|
INTREG_CONDCODES_GE,
|
||||||
INTREG_FPCONDCODES,
|
INTREG_FPCONDCODES,
|
||||||
|
|
||||||
NUM_INTREGS,
|
NUM_INTREGS,
|
||||||
|
|
|
@ -2074,11 +2074,10 @@ let {{
|
||||||
cpsrMask.c = 1;
|
cpsrMask.c = 1;
|
||||||
cpsrMask.v = 1;
|
cpsrMask.v = 1;
|
||||||
if (specReg == MISCREG_FPSCR) {
|
if (specReg == MISCREG_FPSCR) {
|
||||||
return new VmrsApsrFpscr(machInst, INTREG_CONDCODES,
|
return new VmrsApsrFpscr(machInst, INTREG_CONDCODES_F,
|
||||||
(IntRegIndex)specReg, (uint32_t)cpsrMask);
|
(IntRegIndex)specReg, (uint32_t)cpsrMask);
|
||||||
} else {
|
} else {
|
||||||
return new VmrsApsr(machInst, INTREG_CONDCODES,
|
return new Unknown(machInst);
|
||||||
(IntRegIndex)specReg, (uint32_t)cpsrMask);
|
|
||||||
}
|
}
|
||||||
} else if (specReg == MISCREG_FPSCR) {
|
} else if (specReg == MISCREG_FPSCR) {
|
||||||
return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
|
return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
|
||||||
|
|
|
@ -45,7 +45,7 @@ let {{
|
||||||
calcCcCode = '''
|
calcCcCode = '''
|
||||||
if (%(canOverflow)s){
|
if (%(canOverflow)s){
|
||||||
cprintf("canOverflow: %%d\\n", Rd < resTemp);
|
cprintf("canOverflow: %%d\\n", Rd < resTemp);
|
||||||
replaceBits(CondCodes, 27, Rd < resTemp);
|
CpsrQ = (Rd < resTemp) ? 1 << 27 : 0;
|
||||||
} else {
|
} else {
|
||||||
uint16_t _ic, _iv, _iz, _in;
|
uint16_t _ic, _iv, _iz, _in;
|
||||||
_in = (resTemp >> %(negBit)d) & 1;
|
_in = (resTemp >> %(negBit)d) & 1;
|
||||||
|
@ -53,8 +53,7 @@ let {{
|
||||||
_iv = %(ivValue)s & 1;
|
_iv = %(ivValue)s & 1;
|
||||||
_ic = %(icValue)s & 1;
|
_ic = %(icValue)s & 1;
|
||||||
|
|
||||||
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
CondCodesF = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28;
|
||||||
(CondCodes & 0x0FFFFFFF);
|
|
||||||
|
|
||||||
DPRINTF(Arm, "in = %%d\\n", _in);
|
DPRINTF(Arm, "in = %%d\\n", _in);
|
||||||
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
||||||
|
@ -71,11 +70,11 @@ let {{
|
||||||
canOverflow = 'false'
|
canOverflow = 'false'
|
||||||
|
|
||||||
if flagtype == "none":
|
if flagtype == "none":
|
||||||
icReg = icImm = 'CondCodes<29:>'
|
icReg = icImm = 'CondCodesF<29:>'
|
||||||
iv = 'CondCodes<28:>'
|
iv = 'CondCodesF<28:>'
|
||||||
elif flagtype == "llbit":
|
elif flagtype == "llbit":
|
||||||
icReg = icImm = 'CondCodes<29:>'
|
icReg = icImm = 'CondCodesF<29:>'
|
||||||
iv = 'CondCodes<28:>'
|
iv = 'CondCodesF<28:>'
|
||||||
negBit = 63
|
negBit = 63
|
||||||
elif flagtype == "overflow":
|
elif flagtype == "overflow":
|
||||||
canOverflow = "true"
|
canOverflow = "true"
|
||||||
|
@ -90,9 +89,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, CondCodes<29:>)'
|
icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodesF<29:>)'
|
||||||
icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
|
icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodesF<29:>)'
|
||||||
iv = 'CondCodes<28:>'
|
iv = 'CondCodesF<28:>'
|
||||||
return (calcCcCode % {"icValue" : icReg,
|
return (calcCcCode % {"icValue" : icReg,
|
||||||
"ivValue" : iv,
|
"ivValue" : iv,
|
||||||
"negBit" : negBit,
|
"negBit" : negBit,
|
||||||
|
@ -107,11 +106,11 @@ let {{
|
||||||
negBit = 31
|
negBit = 31
|
||||||
canOverflow = 'false'
|
canOverflow = 'false'
|
||||||
if flagtype == "none":
|
if flagtype == "none":
|
||||||
icValue = 'CondCodes<29:>'
|
icValue = 'CondCodesF<29:>'
|
||||||
ivValue = 'CondCodes<28:>'
|
ivValue = 'CondCodesF<28:>'
|
||||||
elif flagtype == "llbit":
|
elif flagtype == "llbit":
|
||||||
icValue = 'CondCodes<29:>'
|
icValue = 'CondCodesF<29:>'
|
||||||
ivValue = 'CondCodes<28:>'
|
ivValue = 'CondCodesF<28:>'
|
||||||
negBit = 63
|
negBit = 63
|
||||||
elif flagtype == "overflow":
|
elif flagtype == "overflow":
|
||||||
icVaule = ivValue = '0'
|
icVaule = ivValue = '0'
|
||||||
|
@ -127,20 +126,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 = 'CondCodes<28:>'
|
ivValue = 'CondCodesF<28:>'
|
||||||
else:
|
else:
|
||||||
icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
|
icValue = '(rotate ? rotated_carry:CondCodesF<29:>)'
|
||||||
ivValue = 'CondCodes<28:>'
|
ivValue = 'CondCodesF<28:>'
|
||||||
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, CondCodes<29:>);
|
shift, CondCodesF<29:>);
|
||||||
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, CondCodes<29:>);
|
shift, CondCodesF<29:>);
|
||||||
op2 = op2;''' + code
|
op2 = op2;''' + code
|
||||||
regIop = InstObjParams(name, Name, 'PredIntOp',
|
regIop = InstObjParams(name, Name, 'PredIntOp',
|
||||||
{"code": regCode,
|
{"code": regCode,
|
||||||
|
|
|
@ -44,11 +44,11 @@ let {{
|
||||||
exec_output = ""
|
exec_output = ""
|
||||||
|
|
||||||
calcGECode = '''
|
calcGECode = '''
|
||||||
CondCodes = insertBits(CondCodes, 19, 16, resTemp);
|
CondCodesGE = insertBits(0, 19, 16, resTemp);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
calcQCode = '''
|
calcQCode = '''
|
||||||
CondCodes = CondCodes | ((resTemp & 1) << 27);
|
CondCodesQ = CondCodesQ | ((resTemp & 1) << 27);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
calcCcCode = '''
|
calcCcCode = '''
|
||||||
|
@ -58,16 +58,15 @@ let {{
|
||||||
_iv = %(ivValue)s & 1;
|
_iv = %(ivValue)s & 1;
|
||||||
_ic = %(icValue)s & 1;
|
_ic = %(icValue)s & 1;
|
||||||
|
|
||||||
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
CondCodesF = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28;
|
||||||
(CondCodes & 0x0FFFFFFF);
|
|
||||||
|
|
||||||
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 = 'CondCodes<29:>'
|
oldC = 'CondCodesF<29:>'
|
||||||
oldV = 'CondCodes<28:>'
|
oldV = 'CondCodesF<28:>'
|
||||||
carryCode = {
|
carryCode = {
|
||||||
"none": (oldC, oldC, oldC),
|
"none": (oldC, oldC, oldC),
|
||||||
"llbit": (oldC, oldC, oldC),
|
"llbit": (oldC, oldC, oldC),
|
||||||
|
@ -102,8 +101,8 @@ let {{
|
||||||
|
|
||||||
secondOpRe = re.compile("secondOp")
|
secondOpRe = re.compile("secondOp")
|
||||||
immOp2 = "imm"
|
immOp2 = "imm"
|
||||||
regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodes<29:>)"
|
regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodesF<29:>)"
|
||||||
regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodes<29:>)"
|
regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodesF<29:>)"
|
||||||
|
|
||||||
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 = []):
|
||||||
|
@ -240,9 +239,12 @@ let {{
|
||||||
code += '''
|
code += '''
|
||||||
SCTLR sctlr = Sctlr;
|
SCTLR sctlr = Sctlr;
|
||||||
uint32_t newCpsr =
|
uint32_t newCpsr =
|
||||||
cpsrWriteByInstr(Cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi);
|
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesQ | CondCodesGE,
|
||||||
|
Spsr, 0xF, true, sctlr.nmfi);
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodesF = CondCodesMaskF & newCpsr;
|
||||||
|
CondCodesQ = CondCodesMaskQ & newCpsr;
|
||||||
|
CondCodesGE = CondCodesMaskGE & newCpsr;
|
||||||
NextThumb = ((CPSR)newCpsr).t;
|
NextThumb = ((CPSR)newCpsr).t;
|
||||||
NextJazelle = ((CPSR)newCpsr).j;
|
NextJazelle = ((CPSR)newCpsr).j;
|
||||||
NextItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
|
NextItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
|
||||||
|
|
|
@ -235,21 +235,8 @@ let {{
|
||||||
decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
|
decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
|
||||||
exec_output += PredOpExecute.subst(vmrsFpscrIop);
|
exec_output += PredOpExecute.subst(vmrsFpscrIop);
|
||||||
|
|
||||||
vmrsApsrCode = vmrsEnabledCheckCode + '''
|
|
||||||
Dest = (MiscOp1 & imm) | (Dest & ~imm);
|
|
||||||
'''
|
|
||||||
vmrsApsrIop = InstObjParams("vmrs", "VmrsApsr", "FpRegRegImmOp",
|
|
||||||
{ "code": vmrsApsrCode,
|
|
||||||
"predicate_test": predicateTest,
|
|
||||||
"op_class": "SimdFloatMiscOp" },
|
|
||||||
["IsSerializeBefore"])
|
|
||||||
header_output += FpRegRegImmOpDeclare.subst(vmrsApsrIop);
|
|
||||||
decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrIop);
|
|
||||||
exec_output += PredOpExecute.subst(vmrsApsrIop);
|
|
||||||
|
|
||||||
vmrsApsrFpscrCode = vmrsEnabledCheckCode + '''
|
vmrsApsrFpscrCode = vmrsEnabledCheckCode + '''
|
||||||
assert((imm & ~FpCondCodesMask) == 0);
|
Dest = FpCondCodes & FpCondCodesMask;
|
||||||
Dest = (FpCondCodes & imm) | (Dest & ~imm);
|
|
||||||
'''
|
'''
|
||||||
vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "FpRegRegImmOp",
|
vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "FpRegRegImmOp",
|
||||||
{ "code": vmrsApsrFpscrCode,
|
{ "code": vmrsApsrFpscrCode,
|
||||||
|
|
|
@ -106,7 +106,7 @@ let {{
|
||||||
wbDiff = 8
|
wbDiff = 8
|
||||||
accCode = '''
|
accCode = '''
|
||||||
CPSR cpsr = Cpsr;
|
CPSR cpsr = Cpsr;
|
||||||
URc = cpsr | CondCodes;
|
URc = cpsr | CondCodesF | CondCodesQ | CondCodesGE;
|
||||||
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 +137,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, CondCodes<29:>)"
|
" shiftType, CondCodesF<29:>)"
|
||||||
if self.add:
|
if self.add:
|
||||||
self.wbDecl = '''
|
self.wbDecl = '''
|
||||||
MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
|
MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
|
||||||
|
|
|
@ -90,9 +90,12 @@ let {{
|
||||||
CPSR cpsr = Cpsr;
|
CPSR cpsr = Cpsr;
|
||||||
SCTLR sctlr = Sctlr;
|
SCTLR sctlr = Sctlr;
|
||||||
uint32_t newCpsr =
|
uint32_t newCpsr =
|
||||||
cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi);
|
cpsrWriteByInstr(cpsr | CondCodesF | CondCodesQ | CondCodesGE,
|
||||||
|
Spsr, 0xF, true, sctlr.nmfi);
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodesF = CondCodesMaskF & newCpsr;
|
||||||
|
CondCodesQ = CondCodesMaskQ & newCpsr;
|
||||||
|
CondCodesGE = CondCodesMaskGE & newCpsr;
|
||||||
IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
|
IWNPC = cSwap(%s, 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);
|
||||||
|
@ -585,7 +588,7 @@ let {{
|
||||||
{'code':
|
{'code':
|
||||||
'''URa = URb + shift_rm_imm(URc, shiftAmt,
|
'''URa = URb + shift_rm_imm(URc, shiftAmt,
|
||||||
shiftType,
|
shiftType,
|
||||||
CondCodes<29:>);
|
CondCodesF<29:>);
|
||||||
''',
|
''',
|
||||||
'predicate_test': predicateTest},
|
'predicate_test': predicateTest},
|
||||||
['IsMicroop'])
|
['IsMicroop'])
|
||||||
|
@ -601,7 +604,7 @@ let {{
|
||||||
{'code':
|
{'code':
|
||||||
'''URa = URb - shift_rm_imm(URc, shiftAmt,
|
'''URa = URb - shift_rm_imm(URc, shiftAmt,
|
||||||
shiftType,
|
shiftType,
|
||||||
CondCodes<29:>);
|
CondCodesF<29:>);
|
||||||
''',
|
''',
|
||||||
'predicate_test': predicateTest},
|
'predicate_test': predicateTest},
|
||||||
['IsMicroop'])
|
['IsMicroop'])
|
||||||
|
@ -631,7 +634,9 @@ let {{
|
||||||
NextJazelle = ((CPSR)newCpsr).j;
|
NextJazelle = ((CPSR)newCpsr).j;
|
||||||
NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
|
NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
|
||||||
| (((CPSR)URb).it1 & 0x3);
|
| (((CPSR)URb).it1 & 0x3);
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodesF = CondCodesMaskF & newCpsr;
|
||||||
|
CondCodesQ = CondCodesMaskQ & newCpsr;
|
||||||
|
CondCodesGE = CondCodesMaskGE & newCpsr;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',
|
microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',
|
||||||
|
|
|
@ -120,7 +120,7 @@ let {{
|
||||||
|
|
||||||
def pickPredicate(blobs):
|
def pickPredicate(blobs):
|
||||||
for val in blobs.values():
|
for val in blobs.values():
|
||||||
if re.search('(?<!Opt)CondCodes', val):
|
if re.search('(?<!Opt)CondCodesF', val):
|
||||||
return condPredicateTest
|
return condPredicateTest
|
||||||
return predicateTest
|
return predicateTest
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,10 @@ let {{
|
||||||
|
|
||||||
header_output = decoder_output = exec_output = ""
|
header_output = decoder_output = exec_output = ""
|
||||||
|
|
||||||
mrsCpsrCode = "Dest = (Cpsr | CondCodes) & 0xF8FF03DF"
|
mrsCpsrCode = '''
|
||||||
|
Dest = (Cpsr | CondCodesF | CondCodesQ | CondCodesGE) & 0xF8FF03DF
|
||||||
|
'''
|
||||||
|
|
||||||
mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
|
mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
|
||||||
{ "code": mrsCpsrCode,
|
{ "code": mrsCpsrCode,
|
||||||
"predicate_test": condPredicateTest },
|
"predicate_test": condPredicateTest },
|
||||||
|
@ -81,9 +84,12 @@ let {{
|
||||||
msrCpsrRegCode = '''
|
msrCpsrRegCode = '''
|
||||||
SCTLR sctlr = Sctlr;
|
SCTLR sctlr = Sctlr;
|
||||||
uint32_t newCpsr =
|
uint32_t newCpsr =
|
||||||
cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false, sctlr.nmfi);
|
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesQ | CondCodesGE, Op1,
|
||||||
|
byteMask, false, sctlr.nmfi);
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodesF = CondCodesMaskF & newCpsr;
|
||||||
|
CondCodesQ = CondCodesMaskQ & newCpsr;
|
||||||
|
CondCodesGE = CondCodesMaskGE & newCpsr;
|
||||||
'''
|
'''
|
||||||
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
|
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
|
||||||
{ "code": msrCpsrRegCode,
|
{ "code": msrCpsrRegCode,
|
||||||
|
@ -105,9 +111,12 @@ let {{
|
||||||
msrCpsrImmCode = '''
|
msrCpsrImmCode = '''
|
||||||
SCTLR sctlr = Sctlr;
|
SCTLR sctlr = Sctlr;
|
||||||
uint32_t newCpsr =
|
uint32_t newCpsr =
|
||||||
cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false, sctlr.nmfi);
|
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesQ | CondCodesGE, imm,
|
||||||
|
byteMask, false, sctlr.nmfi);
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodesF = CondCodesMaskF & newCpsr;
|
||||||
|
CondCodesQ = CondCodesMaskQ & newCpsr;
|
||||||
|
CondCodesGE = CondCodesMaskGE & newCpsr;
|
||||||
'''
|
'''
|
||||||
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
|
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
|
||||||
{ "code": msrCpsrImmCode,
|
{ "code": msrCpsrImmCode,
|
||||||
|
@ -196,9 +205,9 @@ let {{
|
||||||
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
|
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
|
||||||
int32_t res;
|
int32_t res;
|
||||||
if (satInt(res, operand, imm))
|
if (satInt(res, operand, imm))
|
||||||
CondCodes = CondCodes | (1 << 27);
|
CondCodesQ = CondCodesQ | (1 << 27);
|
||||||
else
|
else
|
||||||
CondCodes = CondCodes;
|
CondCodesQ = CondCodesQ;
|
||||||
Dest = res;
|
Dest = res;
|
||||||
'''
|
'''
|
||||||
ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
|
ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
|
||||||
|
@ -212,9 +221,9 @@ let {{
|
||||||
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
|
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
|
||||||
int32_t res;
|
int32_t res;
|
||||||
if (uSatInt(res, operand, imm))
|
if (uSatInt(res, operand, imm))
|
||||||
CondCodes = CondCodes | (1 << 27);
|
CondCodesQ = CondCodesQ | (1 << 27);
|
||||||
else
|
else
|
||||||
CondCodes = CondCodes;
|
CondCodesQ = CondCodesQ;
|
||||||
Dest = res;
|
Dest = res;
|
||||||
'''
|
'''
|
||||||
usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
|
usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
|
||||||
|
@ -227,14 +236,14 @@ let {{
|
||||||
ssat16Code = '''
|
ssat16Code = '''
|
||||||
int32_t res;
|
int32_t res;
|
||||||
uint32_t resTemp = 0;
|
uint32_t resTemp = 0;
|
||||||
CondCodes = CondCodes;
|
CondCodesQ = CondCodesQ;
|
||||||
int32_t argLow = sext<16>(bits(Op1, 15, 0));
|
int32_t argLow = sext<16>(bits(Op1, 15, 0));
|
||||||
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
|
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
|
||||||
if (satInt(res, argLow, imm))
|
if (satInt(res, argLow, imm))
|
||||||
CondCodes = CondCodes | (1 << 27);
|
CondCodesQ = CondCodesQ | (1 << 27);
|
||||||
replaceBits(resTemp, 15, 0, res);
|
replaceBits(resTemp, 15, 0, res);
|
||||||
if (satInt(res, argHigh, imm))
|
if (satInt(res, argHigh, imm))
|
||||||
CondCodes = CondCodes | (1 << 27);
|
CondCodesQ = CondCodesQ | (1 << 27);
|
||||||
replaceBits(resTemp, 31, 16, res);
|
replaceBits(resTemp, 31, 16, res);
|
||||||
Dest = resTemp;
|
Dest = resTemp;
|
||||||
'''
|
'''
|
||||||
|
@ -248,14 +257,14 @@ let {{
|
||||||
usat16Code = '''
|
usat16Code = '''
|
||||||
int32_t res;
|
int32_t res;
|
||||||
uint32_t resTemp = 0;
|
uint32_t resTemp = 0;
|
||||||
CondCodes = CondCodes;
|
CondCodesQ = CondCodesQ;
|
||||||
int32_t argLow = sext<16>(bits(Op1, 15, 0));
|
int32_t argLow = sext<16>(bits(Op1, 15, 0));
|
||||||
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
|
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
|
||||||
if (uSatInt(res, argLow, imm))
|
if (uSatInt(res, argLow, imm))
|
||||||
CondCodes = CondCodes | (1 << 27);
|
CondCodesQ = CondCodesQ | (1 << 27);
|
||||||
replaceBits(resTemp, 15, 0, res);
|
replaceBits(resTemp, 15, 0, res);
|
||||||
if (uSatInt(res, argHigh, imm))
|
if (uSatInt(res, argHigh, imm))
|
||||||
CondCodes = CondCodes | (1 << 27);
|
CondCodesQ = CondCodesQ | (1 << 27);
|
||||||
replaceBits(resTemp, 31, 16, res);
|
replaceBits(resTemp, 31, 16, res);
|
||||||
Dest = resTemp;
|
Dest = resTemp;
|
||||||
'''
|
'''
|
||||||
|
@ -414,7 +423,7 @@ 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(CondCodes, 16 + i) ?
|
bits(CondCodesGE, 16 + i) ?
|
||||||
bits(Op1, high, low) : bits(Op2, high, low));
|
bits(Op1, high, low) : bits(Op2, high, low));
|
||||||
}
|
}
|
||||||
Dest = resTemp;
|
Dest = resTemp;
|
||||||
|
|
|
@ -44,7 +44,7 @@ let {{
|
||||||
exec_output = ""
|
exec_output = ""
|
||||||
|
|
||||||
calcQCode = '''
|
calcQCode = '''
|
||||||
CondCodes = CondCodes | ((resTemp & 1) << 27);
|
CondCodesQ = CondCodesQ | ((resTemp & 1) << 27);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
calcCcCode = '''
|
calcCcCode = '''
|
||||||
|
@ -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);
|
||||||
|
|
||||||
CondCodes = _in << 31 | _iz << 30 | (CondCodes & 0x3FFFFFFF);
|
CondCodesF = _in << 31 | _iz << 30 | (CondCodesF & 0x3FFFFFFF);
|
||||||
|
|
||||||
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, CondCodes<29:>)"
|
" shiftType, CondCodesF<29:>)"
|
||||||
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,10 +156,12 @@ def operands {{
|
||||||
'R3': intRegNPC('3'),
|
'R3': intRegNPC('3'),
|
||||||
|
|
||||||
#Pseudo integer condition code registers
|
#Pseudo integer condition code registers
|
||||||
'CondCodes': intRegCC('INTREG_CONDCODES'),
|
'CondCodesF': intRegCC('INTREG_CONDCODES_F'),
|
||||||
'OptCondCodes': intRegCC(
|
'CondCodesQ': intRegCC('INTREG_CONDCODES_Q'),
|
||||||
|
'CondCodesGE': intRegCC('INTREG_CONDCODES_GE'),
|
||||||
|
'OptCondCodesF': intRegCC(
|
||||||
'''(condCode == COND_AL || condCode == COND_UC) ?
|
'''(condCode == COND_AL || condCode == COND_UC) ?
|
||||||
INTREG_ZERO : INTREG_CONDCODES'''),
|
INTREG_ZERO : INTREG_CONDCODES_F'''),
|
||||||
'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(OptCondCodes, condCode)'
|
predicateTest = 'testPredicate(OptCondCodesF, condCode)'
|
||||||
condPredicateTest = 'testPredicate(CondCodes, condCode)'
|
condPredicateTest = 'testPredicate(CondCodesF, condCode)'
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template DataImmDeclare {{
|
def template DataImmDeclare {{
|
||||||
|
|
|
@ -269,7 +269,10 @@ 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 = 0xF80F0000;
|
static const uint32_t CondCodesMask = 0xF80F0000;
|
||||||
|
static const uint32_t CondCodesMaskF = 0xF0000000;
|
||||||
|
static const uint32_t CondCodesMaskQ = 0x08000000;
|
||||||
|
static const uint32_t CondCodesMaskGE = 0x000F0000;
|
||||||
|
|
||||||
BitUnion32(SCTLR)
|
BitUnion32(SCTLR)
|
||||||
Bitfield<31> ie; // Instruction endianness
|
Bitfield<31> ie; // Instruction endianness
|
||||||
|
|
|
@ -116,7 +116,9 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
|
||||||
|
|
||||||
//CPSR
|
//CPSR
|
||||||
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
|
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
|
||||||
tc->readIntReg(INTREG_CONDCODES);
|
tc->readIntReg(INTREG_CONDCODES_F) |
|
||||||
|
tc->readIntReg(INTREG_CONDCODES_Q) |
|
||||||
|
tc->readIntReg(INTREG_CONDCODES_GE);
|
||||||
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) {
|
||||||
|
|
Loading…
Reference in a new issue