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 <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40943
Reviewed-by: Boris Shingarov <shingarov@labware.com>
Maintainer: Boris Shingarov <shingarov@labware.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Sandipan Das
2021-02-06 17:27:58 +05:30
committed by Boris Shingarov
parent 0e8238d717
commit be3a57e68a
9 changed files with 127 additions and 41 deletions

View File

@@ -27,6 +27,8 @@
*/
#include "arch/power/insts/branch.hh"
#include "arch/power/regs/int.hh"
#include "arch/power/regs/misc.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
@@ -54,12 +56,17 @@ PCDependentDisassembly::disassemble(
PowerISA::PCState
BranchOp::branchTarget(const PowerISA::PCState &pc) const
BranchOp::branchTarget(ThreadContext *tc) const
{
Msr msr = tc->readIntReg(INTREG_MSR);
Addr addr;
if (aa)
return li;
addr = li;
else
return pc.pc() + li;
addr = tc->pcState().pc() + li;
return msr.sf ? addr : addr & UINT32_MAX;
}
@@ -97,13 +104,17 @@ BranchOp::generateDisassembly(
PowerISA::PCState
BranchDispCondOp::branchTarget(const PowerISA::PCState &pc) const
BranchDispCondOp::branchTarget(ThreadContext *tc) const
{
if (aa) {
return bd;
} else {
return pc.pc() + bd;
}
Msr msr = tc->readIntReg(INTREG_MSR);
Addr addr;
if (aa)
addr = bd;
else
addr = tc->pcState().pc() + bd;
return msr.sf ? addr : addr & UINT32_MAX;
}
@@ -146,8 +157,9 @@ BranchDispCondOp::generateDisassembly(
PowerISA::PCState
BranchRegCondOp::branchTarget(ThreadContext *tc) const
{
Addr addr = tc->readIntReg(srcRegIdx(_numSrcRegs - 1).index());
return addr & -4ULL;
Msr msr = tc->readIntReg(INTREG_MSR);
Addr addr = tc->readIntReg(srcRegIdx(_numSrcRegs - 1).index()) & -4ULL;
return msr.sf ? addr : addr & UINT32_MAX;
}

View File

@@ -87,7 +87,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;
@@ -158,7 +158,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;

View File

@@ -87,11 +87,11 @@ let {{
# Check the condition register (CR) allows the branch to be taken.
def GetCondCode(br_code):
cond_code = 'if (condOk(CR)) {\n'
cond_code = 'Msr msr = MSR;\n'
cond_code += 'if (condOk(CR)) {\n'
cond_code += ' ' + br_code + '\n'
cond_code += '} else {\n'
cond_code += ' NIA = NIA;\n'
cond_code += '}\n'
cond_code += 'NIA = msr.sf ? NIA : NIA & UINT32_MAX;\n'
return cond_code
# Check the condition register (CR) and count register (CTR) allow the
@@ -99,11 +99,11 @@ def GetCondCode(br_code):
# register too. This takes place in ctrOk within BranchCondOp classes.
def GetCtrCondCode(br_code):
cond_code = 'uint64_t ctr = CTR;\n'
cond_code += 'Msr msr = MSR;\n'
cond_code += 'if (ctrOk(ctr) && condOk(CR)) {\n'
cond_code += ' ' + br_code + '\n'
cond_code += '} else {\n'
cond_code += ' NIA = NIA;\n'
cond_code += '}\n'
cond_code += 'NIA = msr.sf ? NIA : NIA & UINT32_MAX;\n'
cond_code += 'CTR = ctr;\n'
return cond_code

View File

@@ -38,38 +38,60 @@ readXERCode = 'GEM5_VAR_USED Xer xer = XER;'
setXERCode = 'XER = xer;'
computeCR0Code = '''
PowerISA::Cr cr = CR;
cr.cr0 = makeCRFieldSigned(%(result)s, 0, xer.so);
{
Cr cr = CR;
Msr msr = MSR;
cr.cr0 = msr.sf ?
makeCRFieldSigned((int64_t)%(result)s, 0, xer.so) :
makeCRFieldSigned((int32_t)%(result)s, 0, xer.so);
CR = cr;
}
'''
computeCACode = '''
if (findCarry(64, %(result)s, %(inputa)s, %(inputb)s)) {
xer.ca = 1;
} else {
xer.ca = 0;
}
{
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 (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)) {
xer.ov = 1;
xer.so = 1;
} else {
xer.ov = 0;
}
{
Msr msr = MSR;
if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
xer.ov = 1;
xer.ov32 = 1;
} else {
xer.ov = 0;
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 = '''

View File

@@ -68,13 +68,16 @@ def template LoadExecute {{
{
Addr EA;
Fault fault = NoFault;
Msr msr = xc->tcBase()->readIntReg(INTREG_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 {{
{
GEM5_VAR_USED Addr EA;
Fault fault = NoFault;
Msr msr = xc->tcBase()->readIntReg(INTREG_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->tcBase()->readIntReg(INTREG_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->tcBase()->readIntReg(INTREG_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

View File

@@ -67,6 +67,7 @@ def operands {{
'CTR': ('IntReg', 'ud', 'INTREG_CTR', 'IsInteger', 9),
'TAR': ('IntReg', 'ud', 'INTREG_TAR', 'IsInteger', 9),
'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9),
'MSR': ('IntReg', 'ud', 'INTREG_MSR', 'IsInteger', 9),
# Setting as IntReg so things are stored as an integer, not double
'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9),

View File

@@ -31,6 +31,7 @@
#include "arch/power/page_size.hh"
#include "arch/power/regs/int.hh"
#include "arch/power/regs/misc.hh"
#include "arch/power/types.hh"
#include "base/loader/elf_object.hh"
#include "base/loader/object_file.hh"
@@ -279,6 +280,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->setIntReg(INTREG_MSR, msr);
tc->pcState(getStartPC());
//Align the "stack_min" to a page boundary.

View File

@@ -38,9 +38,9 @@ namespace PowerISA
// Constants Related to the number of registers
const int NumIntArchRegs = 32;
// CR, XER, LR, CTR, TAR, FPSCR, RSV, RSV-LEN, RSV-ADDR
// CR, XER, LR, CTR, TAR, FPSCR, MSR, RSV, RSV-LEN, RSV-ADDR
// and zero register, which doesn't actually exist but needs a number
const int NumIntSpecialRegs = 10;
const int NumIntSpecialRegs = 11;
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
@@ -62,6 +62,7 @@ enum MiscIntRegNums
INTREG_CTR,
INTREG_TAR,
INTREG_FPSCR,
INTREG_MSR,
INTREG_RSV,
INTREG_RSV_LEN,
INTREG_RSV_ADDR

View File

@@ -99,6 +99,27 @@ 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
} // namespace gem5