From: Ali Saidi Date: Fri, 13 May 2011 22:27:01 +0000 (-0500) Subject: ARM: Break up condition codes into normal flags, saturation, and simd. X-Git-Tag: stable_2012_02_02~323 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2178859b76bb13b1d225fc4dffa04d43d2db2e14;p=gem5.git 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. --- diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 03a65ea88..4b58a7144 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -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; diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 9da910106..412efc92b 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -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, diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index 18b128836..5ec65c01b 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -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); diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index 18df8491c..89fcd9ca9 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -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, diff --git a/src/arch/arm/isa/insts/data.isa b/src/arch/arm/isa/insts/data.isa index 5b1526e41..a6d4c7daa 100644 --- a/src/arch/arm/isa/insts/data.isa +++ b/src/arch/arm/isa/insts/data.isa @@ -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) diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index 4911d50f1..53d0b3413 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -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, diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa index bfa94103f..bf8034a9e 100644 --- a/src/arch/arm/isa/insts/ldr.isa +++ b/src/arch/arm/isa/insts/ldr.isa @@ -106,7 +106,7 @@ let {{ wbDiff = 8 accCode = ''' CPSR cpsr = Cpsr; - URc = cpsr | CondCodes; + URc = cpsr | CondCodesF | CondCodesQ | CondCodesGE; URa = cSwap(Mem.ud, cpsr.e); URb = cSwap(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); diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index 67d8da572..5007c85e5 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -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', diff --git a/src/arch/arm/isa/insts/mem.isa b/src/arch/arm/isa/insts/mem.isa index ca0d701d3..0ebd34ad4 100644 --- a/src/arch/arm/isa/insts/mem.isa +++ b/src/arch/arm/isa/insts/mem.isa @@ -120,7 +120,7 @@ let {{ def pickPredicate(blobs): for val in blobs.values(): - if re.search('(?(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; diff --git a/src/arch/arm/isa/insts/mult.isa b/src/arch/arm/isa/insts/mult.isa index b3a9fca5f..b02386c63 100644 --- a/src/arch/arm/isa/insts/mult.isa +++ b/src/arch/arm/isa/insts/mult.isa @@ -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); ''' diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index e5d47c28f..312bcac16 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -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); diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index b497564b7..9053f6e92 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -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 diff --git a/src/arch/arm/isa/templates/pred.isa b/src/arch/arm/isa/templates/pred.isa index 4ab1335e0..a0f811f6d 100644 --- a/src/arch/arm/isa/templates/pred.isa +++ b/src/arch/arm/isa/templates/pred.isa @@ -46,8 +46,8 @@ // let {{ - predicateTest = 'testPredicate(OptCondCodes, condCode)' - condPredicateTest = 'testPredicate(CondCodes, condCode)' + predicateTest = 'testPredicate(OptCondCodesF, condCode)' + condPredicateTest = 'testPredicate(CondCodesF, condCode)' }}; def template DataImmDeclare {{ diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index c506455f8..813b98b69 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -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 diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index a8d01a0f2..4fc4a0ed2 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -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) {