From: Sandipan Das Date: Sat, 6 Feb 2021 11:57:58 +0000 (+0530) Subject: arch-power: Add MSR and associated dependencies X-Git-Tag: develop-gem5-snapshot~8 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a284c23127728ed9fa0f0c27ddb2ca1ac73094a4;p=gem5.git arch-power: Add MSR and associated dependencies This adds the definition of the Machine State Register (MSR) in preparation for multi-mode support. The MSR has bits that define the state of the processor. This defines all the bitfields and sets the ones that are typically used for userspace environments. In preparation for multi-mode support, the SF and LE bits are used by instructions to check if the simulation is running in 64-bit mode and if memory accesses are to be performed in little endian byte order respectively. This introduces changes in areas such as target address computation for branch instructions, carry and overflow computation for arithmetic instructions, etc. Change-Id: If9ac69415ca85b0c873bd8579e7d1bd2219eac62 Signed-off-by: Sandipan Das --- diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc index 3747bf1b7..f54185aef 100644 --- a/src/arch/power/insts/branch.cc +++ b/src/arch/power/insts/branch.cc @@ -54,13 +54,18 @@ PCDependentDisassembly::disassemble( PowerISA::PCState -BranchOp::branchTarget(const PowerISA::PCState &pc) const +BranchOp::branchTarget(ThreadContext *tc) const { + Msr msr = tc->readMiscReg(MISCREG_MSR); + Addr addr; + if (aaSet) { - return disp; + addr = disp; } else { - return pc.pc() + disp; + addr = tc->pcState().pc() + disp; } + + return msr.sf ? addr : addr & UINT32_MAX; } @@ -96,13 +101,18 @@ BranchOp::generateDisassembly( PowerISA::PCState -BranchDispCondOp::branchTarget(const PowerISA::PCState &pc) const +BranchDispCondOp::branchTarget(ThreadContext *tc) const { + Msr msr = tc->readMiscReg(MISCREG_MSR); + Addr addr; + if (aaSet) { - return disp; + addr = disp; } else { - return pc.pc() + disp; + addr = tc->pcState().pc() + disp; } + + return msr.sf ? addr : addr & UINT32_MAX; } @@ -143,8 +153,9 @@ BranchDispCondOp::generateDisassembly( PowerISA::PCState BranchRegCondOp::branchTarget(ThreadContext *tc) const { - Addr addr = tc->readIntReg(srcRegIdx(_numSrcRegs - 1).index()); - return addr & -4ULL; + Msr msr = tc->readMiscReg(MISCREG_MSR); + Addr addr = tc->readIntReg(srcRegIdx(_numSrcRegs - 1).index()) & -4ULL; + return msr.sf ? addr : addr & UINT32_MAX; } diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh index 8c311a2e3..40555aaac 100644 --- a/src/arch/power/insts/branch.hh +++ b/src/arch/power/insts/branch.hh @@ -84,7 +84,7 @@ class BranchOp : public PCDependentDisassembly { } - PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override; + PowerISA::PCState branchTarget(ThreadContext *tc) const override; /// Explicitly import the otherwise hidden branchTarget using StaticInst::branchTarget; @@ -163,7 +163,7 @@ class BranchDispCondOp : public BranchCondOp { } - PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override; + PowerISA::PCState branchTarget(ThreadContext *tc) const override; /// Explicitly import the otherwise hidden branchTarget using StaticInst::branchTarget; diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa index b107cb34a..29f1df3b9 100644 --- a/src/arch/power/isa/formats/branch.isa +++ b/src/arch/power/isa/formats/branch.isa @@ -125,10 +125,12 @@ let {{ # Check the condition register (CR) allows the branch to be taken. def GetCondCode(br_code): - cond_code = 'if (checkCond(CR)) {\n' + cond_code = 'Msr msr = MSR;\n' + cond_code += 'if (checkCond(CR)) {\n' cond_code += ' ' + br_code + '\n' + cond_code += ' NIA = msr.sf ? NIA : NIA & UINT32_MAX;\n' cond_code += '} else {\n' - cond_code += ' NIA = NIA;\n' + cond_code += ' NIA = msr.sf ? NIA : NIA & UINT32_MAX;\n' cond_code += '}\n' return cond_code @@ -139,10 +141,12 @@ def GetCtrCondCode(br_code): cond_code = 'uint64_t ctr = CTR;\n' cond_code += 'bool ctrOk = checkCtr(ctr);\n' cond_code += 'bool condOk = checkCond(CR);\n' + cond_code += 'Msr msr = MSR;\n' cond_code += 'if (ctrOk && condOk) {\n' cond_code += ' ' + br_code + '\n' + cond_code += ' NIA = msr.sf ? NIA : NIA & UINT32_MAX;\n' cond_code += '} else {\n' - cond_code += ' NIA = NIA;\n' + cond_code += ' NIA = msr.sf ? NIA : NIA & UINT32_MAX;\n' cond_code += '}\n' cond_code += 'CTR = ctr;\n' return cond_code diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index 3ab9ad923..5a353d0ae 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -76,38 +76,60 @@ readXERCode = 'M5_VAR_USED Xer xer = XER;' setXERCode = 'XER = xer;' computeCR0Code = ''' +{ Cr cr = CR; - cr.cr0 = makeCRField((int64_t)%(result)s, (int64_t)0, xer.so); + Msr msr = MSR; + cr.cr0 = msr.sf ? + makeCRField((int64_t)%(result)s, (int64_t)0, xer.so) : + makeCRField((int32_t)%(result)s, (int32_t)0, xer.so); CR = cr; +} ''' computeCACode = ''' - if (findCarry(64, %(result)s, %(inputa)s, %(inputb)s)) { +{ + Msr msr = MSR; + if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) { xer.ca = 1; + xer.ca32 = 1; } else { xer.ca = 0; + xer.ca32 = 0; } - if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) { - xer.ca32 = 1; - } else { - xer.ca32 = 0; + if (msr.sf) { + if (findCarry(64, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ca = 1; + } else { + xer.ca = 0; + } } +} ''' computeOVCode = ''' - if (findOverflow(64, %(result)s, %(inputa)s, %(inputb)s)) { +{ + Msr msr = MSR; + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { xer.ov = 1; - xer.so = 1; + xer.ov32 = 1; } else { xer.ov = 0; + xer.ov32 = 0; } - if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { - xer.ov32 = 1; - } else { - xer.ov32 = 0; + if (msr.sf) { + if (findOverflow(64, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + } else { + xer.ov = 0; + } + } + + if (xer.ov) { + xer.so = 1; } +} ''' setCACode = ''' diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa index 1cddc409a..743ac6123 100644 --- a/src/arch/power/isa/formats/mem.isa +++ b/src/arch/power/isa/formats/mem.isa @@ -68,13 +68,16 @@ def template LoadExecute {{ { Addr EA; Fault fault = NoFault; + Msr msr = xc->readMiscReg(MISCREG_MSR); %(op_decl)s; %(op_rd)s; %(ea_code)s; if (fault == NoFault) { - fault = readMemAtomicBE(xc, traceData, EA, Mem, memAccessFlags); + fault = msr.le ? + readMemAtomicLE(xc, traceData, EA, Mem, memAccessFlags) : + readMemAtomicBE(xc, traceData, EA, Mem, memAccessFlags); %(memacc_code)s; } @@ -114,13 +117,17 @@ def template LoadCompleteAcc {{ { M5_VAR_USED Addr EA; Fault fault = NoFault; + Msr msr = xc->readMiscReg(MISCREG_MSR); %(op_decl)s; %(op_rd)s; EA = pkt->req->getVaddr(); - getMemBE(pkt, Mem, traceData); + if (msr.le) + getMemLE(pkt, Mem, traceData); + else + getMemBE(pkt, Mem, traceData); if (fault == NoFault) { %(memacc_code)s; @@ -141,6 +148,7 @@ def template StoreExecute {{ { Addr EA; Fault fault = NoFault; + Msr msr = xc->readMiscReg(MISCREG_MSR); %(op_decl)s; %(op_rd)s; @@ -151,8 +159,11 @@ def template StoreExecute {{ } if (fault == NoFault) { - fault = writeMemAtomicBE(xc, traceData, Mem, EA, memAccessFlags, - NULL); + fault = msr.le ? + writeMemAtomicLE(xc, traceData, Mem, EA, memAccessFlags, + NULL) : + writeMemAtomicBE(xc, traceData, Mem, EA, memAccessFlags, + NULL); } if (fault == NoFault) { @@ -170,6 +181,7 @@ def template StoreInitiateAcc {{ { Addr EA; Fault fault = NoFault; + Msr msr = xc->readMiscReg(MISCREG_MSR); %(op_decl)s; %(op_rd)s; @@ -180,8 +192,11 @@ def template StoreInitiateAcc {{ } if (fault == NoFault) { - fault = writeMemTimingBE(xc, traceData, Mem, EA, memAccessFlags, - NULL); + fault = msr.le ? + writeMemTimingLE(xc, traceData, Mem, EA, memAccessFlags, + NULL) : + writeMemTimingBE(xc, traceData, Mem, EA, memAccessFlags, + NULL); } // Need to write back any potential address register update diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa index bdd594843..2b4fb27bf 100644 --- a/src/arch/power/isa/operands.isa +++ b/src/arch/power/isa/operands.isa @@ -67,6 +67,7 @@ def operands {{ 'LR': ('ControlReg', 'ud', 'MISCREG_LR', 'IsInteger', 9), 'CTR': ('ControlReg', 'ud', 'MISCREG_CTR', 'IsInteger', 9), 'TAR': ('ControlReg', 'ud', 'MISCREG_TAR', 'IsInteger', 9), + 'MSR': ('ControlReg', 'ud', 'MISCREG_MSR', 'IsInteger', 9), # Setting as ControlReg so things are stored as an integer, not double 'FPSCR': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsFloating', 9), diff --git a/src/arch/power/miscregs.hh b/src/arch/power/miscregs.hh index 1c9746b90..1eae96819 100644 --- a/src/arch/power/miscregs.hh +++ b/src/arch/power/miscregs.hh @@ -41,6 +41,7 @@ enum MiscRegIndex { MISCREG_LR, MISCREG_CTR, MISCREG_TAR, + MISCREG_MSR, NUM_MISCREGS }; @@ -50,7 +51,8 @@ const char * const miscRegName[NUM_MISCREGS] = { "XER", "LR", "CTR", - "TAR" + "TAR", + "MSR" }; BitUnion32(Cr) @@ -107,6 +109,26 @@ BitUnion32(Fpscr) Bitfield<2,1> rn; EndBitUnion(Fpscr) +BitUnion64(Msr) + Bitfield<63> sf; + Bitfield<60> hv; + Bitfield<34, 33> ts; + Bitfield<32> tm; + Bitfield<25> vec; + Bitfield<23> vsx; + Bitfield<15> ee; + Bitfield<14> pr; + Bitfield<13> fp; + Bitfield<12> me; + Bitfield<11> fe0; + Bitfield<10, 9> te; + Bitfield<8> fe1; + Bitfield<5> ir; + Bitfield<4> dr; + Bitfield<2> pmm; + Bitfield<1> ri; + Bitfield<0> le; +EndBitUnion(Msr) } // namespace PowerISA #endif // __ARCH_POWER_MISCREGS_HH__ diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index c81d12ec5..409f980ae 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -274,6 +274,19 @@ PowerProcess::argsInit(int pageSize) //Set the stack pointer register tc->setIntReg(StackPointerReg, stack_min); + //Set the machine status for a typical userspace + Msr msr = 0; + msr.sf = (intSize == 8); + msr.hv = 1; + msr.ee = 1; + msr.pr = 1; + msr.me = 1; + msr.ir = 1; + msr.dr = 1; + msr.ri = 1; + msr.le = (byteOrder == ByteOrder::little); + tc->setMiscReg(MISCREG_MSR, msr); + tc->pcState(getStartPC()); //Align the "stack_min" to a page boundary.