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:
Ali Saidi 2011-05-13 17:27:01 -05:00
parent 4bf48a11ef
commit 2178859b76
16 changed files with 94 additions and 82 deletions

View file

@ -107,7 +107,9 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
CPSR 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();
ITSTATE it = tc->pcState().itstate();
saved_cpsr.it2 = it.top6;

View file

@ -112,7 +112,9 @@ enum IntRegIndex
INTREG_UREG0,
INTREG_UREG1,
INTREG_UREG2,
INTREG_CONDCODES,
INTREG_CONDCODES_F,
INTREG_CONDCODES_Q,
INTREG_CONDCODES_GE,
INTREG_FPCONDCODES,
NUM_INTREGS,

View file

@ -2074,11 +2074,10 @@ let {{
cpsrMask.c = 1;
cpsrMask.v = 1;
if (specReg == MISCREG_FPSCR) {
return new VmrsApsrFpscr(machInst, INTREG_CONDCODES,
return new VmrsApsrFpscr(machInst, INTREG_CONDCODES_F,
(IntRegIndex)specReg, (uint32_t)cpsrMask);
} else {
return new VmrsApsr(machInst, INTREG_CONDCODES,
(IntRegIndex)specReg, (uint32_t)cpsrMask);
return new Unknown(machInst);
}
} else if (specReg == MISCREG_FPSCR) {
return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);

View file

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

View file

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

View file

@ -235,21 +235,8 @@ let {{
decoder_output += FpRegRegOpConstructor.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 + '''
assert((imm & ~FpCondCodesMask) == 0);
Dest = (FpCondCodes & imm) | (Dest & ~imm);
Dest = FpCondCodes & FpCondCodesMask;
'''
vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "FpRegRegImmOp",
{ "code": vmrsApsrFpscrCode,

View file

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

View file

@ -90,9 +90,12 @@ let {{
CPSR cpsr = Cpsr;
SCTLR sctlr = Sctlr;
uint32_t newCpsr =
cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi);
cpsrWriteByInstr(cpsr | CondCodesF | CondCodesQ | CondCodesGE,
Spsr, 0xF, true, sctlr.nmfi);
Cpsr = ~CondCodesMask & newCpsr;
CondCodes = CondCodesMask & newCpsr;
CondCodesF = CondCodesMaskF & newCpsr;
CondCodesQ = CondCodesMaskQ & newCpsr;
CondCodesGE = CondCodesMaskGE & newCpsr;
IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
| (((CPSR)Spsr).it1 & 0x3);
@ -585,7 +588,7 @@ let {{
{'code':
'''URa = URb + shift_rm_imm(URc, shiftAmt,
shiftType,
CondCodes<29:>);
CondCodesF<29:>);
''',
'predicate_test': predicateTest},
['IsMicroop'])
@ -601,7 +604,7 @@ let {{
{'code':
'''URa = URb - shift_rm_imm(URc, shiftAmt,
shiftType,
CondCodes<29:>);
CondCodesF<29:>);
''',
'predicate_test': predicateTest},
['IsMicroop'])
@ -631,7 +634,9 @@ let {{
NextJazelle = ((CPSR)newCpsr).j;
NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
| (((CPSR)URb).it1 & 0x3);
CondCodes = CondCodesMask & newCpsr;
CondCodesF = CondCodesMaskF & newCpsr;
CondCodesQ = CondCodesMaskQ & newCpsr;
CondCodesGE = CondCodesMaskGE & newCpsr;
'''
microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',

View file

@ -120,7 +120,7 @@ let {{
def pickPredicate(blobs):
for val in blobs.values():
if re.search('(?<!Opt)CondCodes', val):
if re.search('(?<!Opt)CondCodesF', val):
return condPredicateTest
return predicateTest

View file

@ -60,7 +60,10 @@ let {{
header_output = decoder_output = exec_output = ""
mrsCpsrCode = "Dest = (Cpsr | CondCodes) & 0xF8FF03DF"
mrsCpsrCode = '''
Dest = (Cpsr | CondCodesF | CondCodesQ | CondCodesGE) & 0xF8FF03DF
'''
mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
{ "code": mrsCpsrCode,
"predicate_test": condPredicateTest },
@ -81,9 +84,12 @@ let {{
msrCpsrRegCode = '''
SCTLR sctlr = Sctlr;
uint32_t newCpsr =
cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false, sctlr.nmfi);
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesQ | CondCodesGE, Op1,
byteMask, false, sctlr.nmfi);
Cpsr = ~CondCodesMask & newCpsr;
CondCodes = CondCodesMask & newCpsr;
CondCodesF = CondCodesMaskF & newCpsr;
CondCodesQ = CondCodesMaskQ & newCpsr;
CondCodesGE = CondCodesMaskGE & newCpsr;
'''
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
{ "code": msrCpsrRegCode,
@ -105,9 +111,12 @@ let {{
msrCpsrImmCode = '''
SCTLR sctlr = Sctlr;
uint32_t newCpsr =
cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false, sctlr.nmfi);
cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesQ | CondCodesGE, imm,
byteMask, false, sctlr.nmfi);
Cpsr = ~CondCodesMask & newCpsr;
CondCodes = CondCodesMask & newCpsr;
CondCodesF = CondCodesMaskF & newCpsr;
CondCodesQ = CondCodesMaskQ & newCpsr;
CondCodesGE = CondCodesMaskGE & newCpsr;
'''
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
{ "code": msrCpsrImmCode,
@ -196,9 +205,9 @@ let {{
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
int32_t res;
if (satInt(res, operand, imm))
CondCodes = CondCodes | (1 << 27);
CondCodesQ = CondCodesQ | (1 << 27);
else
CondCodes = CondCodes;
CondCodesQ = CondCodesQ;
Dest = res;
'''
ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
@ -212,9 +221,9 @@ let {{
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
int32_t res;
if (uSatInt(res, operand, imm))
CondCodes = CondCodes | (1 << 27);
CondCodesQ = CondCodesQ | (1 << 27);
else
CondCodes = CondCodes;
CondCodesQ = CondCodesQ;
Dest = res;
'''
usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
@ -227,14 +236,14 @@ let {{
ssat16Code = '''
int32_t res;
uint32_t resTemp = 0;
CondCodes = CondCodes;
CondCodesQ = CondCodesQ;
int32_t argLow = sext<16>(bits(Op1, 15, 0));
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
if (satInt(res, argLow, imm))
CondCodes = CondCodes | (1 << 27);
CondCodesQ = CondCodesQ | (1 << 27);
replaceBits(resTemp, 15, 0, res);
if (satInt(res, argHigh, imm))
CondCodes = CondCodes | (1 << 27);
CondCodesQ = CondCodesQ | (1 << 27);
replaceBits(resTemp, 31, 16, res);
Dest = resTemp;
'''
@ -248,14 +257,14 @@ let {{
usat16Code = '''
int32_t res;
uint32_t resTemp = 0;
CondCodes = CondCodes;
CondCodesQ = CondCodesQ;
int32_t argLow = sext<16>(bits(Op1, 15, 0));
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
if (uSatInt(res, argLow, imm))
CondCodes = CondCodes | (1 << 27);
CondCodesQ = CondCodesQ | (1 << 27);
replaceBits(resTemp, 15, 0, res);
if (uSatInt(res, argHigh, imm))
CondCodes = CondCodes | (1 << 27);
CondCodesQ = CondCodesQ | (1 << 27);
replaceBits(resTemp, 31, 16, res);
Dest = resTemp;
'''
@ -414,7 +423,7 @@ let {{
int low = i * 8;
int high = low + 7;
replaceBits(resTemp, high, low,
bits(CondCodes, 16 + i) ?
bits(CondCodesGE, 16 + i) ?
bits(Op1, high, low) : bits(Op2, high, low));
}
Dest = resTemp;

View file

@ -44,7 +44,7 @@ let {{
exec_output = ""
calcQCode = '''
CondCodes = CondCodes | ((resTemp & 1) << 27);
CondCodesQ = CondCodesQ | ((resTemp & 1) << 27);
'''
calcCcCode = '''
@ -52,7 +52,7 @@ let {{
_in = (resTemp >> %(negBit)d) & 1;
_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);
'''

View file

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

View file

@ -156,10 +156,12 @@ def operands {{
'R3': intRegNPC('3'),
#Pseudo integer condition code registers
'CondCodes': intRegCC('INTREG_CONDCODES'),
'OptCondCodes': intRegCC(
'CondCodesF': intRegCC('INTREG_CONDCODES_F'),
'CondCodesQ': intRegCC('INTREG_CONDCODES_Q'),
'CondCodesGE': intRegCC('INTREG_CONDCODES_GE'),
'OptCondCodesF': intRegCC(
'''(condCode == COND_AL || condCode == COND_UC) ?
INTREG_ZERO : INTREG_CONDCODES'''),
INTREG_ZERO : INTREG_CONDCODES_F'''),
'FpCondCodes': intRegCC('INTREG_FPCONDCODES'),
#Abstracted floating point reg operands

View file

@ -46,8 +46,8 @@
//
let {{
predicateTest = 'testPredicate(OptCondCodes, condCode)'
condPredicateTest = 'testPredicate(CondCodes, condCode)'
predicateTest = 'testPredicate(OptCondCodesF, condCode)'
condPredicateTest = 'testPredicate(CondCodesF, condCode)'
}};
def template DataImmDeclare {{

View file

@ -269,7 +269,10 @@ namespace ArmISA
// This mask selects bits of the CPSR that actually go in the CondCodes
// 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)
Bitfield<31> ie; // Instruction endianness

View file

@ -116,7 +116,9 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
//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]);
for (int i = 0; i < NumFloatArchRegs; i += 2) {