Boris Shingarov has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/40943 )
Change subject: arch-power: Add MSR and associated dependencies
......................................................................
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 <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40943
Reviewed-by: Boris Shingarov <[email protected]>
Maintainer: Boris Shingarov <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/arch/power/insts/branch.cc
M src/arch/power/insts/branch.hh
M src/arch/power/isa/formats/branch.isa
M src/arch/power/isa/formats/integer.isa
M src/arch/power/isa/formats/mem.isa
M src/arch/power/isa/operands.isa
M src/arch/power/process.cc
M src/arch/power/regs/int.hh
M src/arch/power/regs/misc.hh
9 files changed, 127 insertions(+), 41 deletions(-)
Approvals:
Boris Shingarov: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc
index ca52d83..a1b6d8c 100644
--- a/src/arch/power/insts/branch.cc
+++ b/src/arch/power/insts/branch.cc
@@ -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 @@
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 @@
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 @@
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;
}
diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh
index 5c5982c..cad91c2 100644
--- a/src/arch/power/insts/branch.hh
+++ b/src/arch/power/insts/branch.hh
@@ -87,7 +87,7 @@
{
}
- 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 @@
{
}
- 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 b970bc0..efb5f06 100644
--- a/src/arch/power/isa/formats/branch.isa
+++ b/src/arch/power/isa/formats/branch.isa
@@ -87,11 +87,11 @@
# 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 @@
# 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
diff --git a/src/arch/power/isa/formats/integer.isa
b/src/arch/power/isa/formats/integer.isa
index 5f195d7..9c2804d 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -38,38 +38,60 @@
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 = '''
diff --git a/src/arch/power/isa/formats/mem.isa
b/src/arch/power/isa/formats/mem.isa
index 4886296..d499903 100644
--- a/src/arch/power/isa/formats/mem.isa
+++ b/src/arch/power/isa/formats/mem.isa
@@ -68,13 +68,16 @@
{
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 @@
{
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 @@
{
Addr EA;
Fault fault = NoFault;
+ Msr msr = xc->tcBase()->readIntReg(INTREG_MSR);
%(op_decl)s;
%(op_rd)s;
@@ -151,8 +159,11 @@
}
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 @@
{
Addr EA;
Fault fault = NoFault;
+ Msr msr = xc->tcBase()->readIntReg(INTREG_MSR);
%(op_decl)s;
%(op_rd)s;
@@ -180,8 +192,11 @@
}
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 7d85749..d168970 100644
--- a/src/arch/power/isa/operands.isa
+++ b/src/arch/power/isa/operands.isa
@@ -67,6 +67,7 @@
'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),
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index bc63146..688cc1e 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -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 @@
//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.
diff --git a/src/arch/power/regs/int.hh b/src/arch/power/regs/int.hh
index 27acb62..11999e5 100644
--- a/src/arch/power/regs/int.hh
+++ b/src/arch/power/regs/int.hh
@@ -38,9 +38,9 @@
// 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 @@
INTREG_CTR,
INTREG_TAR,
INTREG_FPSCR,
+ INTREG_MSR,
INTREG_RSV,
INTREG_RSV_LEN,
INTREG_RSV_ADDR
diff --git a/src/arch/power/regs/misc.hh b/src/arch/power/regs/misc.hh
index 7659180..febc8a5 100644
--- a/src/arch/power/regs/misc.hh
+++ b/src/arch/power/regs/misc.hh
@@ -99,6 +99,27 @@
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
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40943
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: If9ac69415ca85b0c873bd8579e7d1bd2219eac62
Gerrit-Change-Number: 40943
Gerrit-PatchSet: 11
Gerrit-Owner: Sandipan Das <[email protected]>
Gerrit-Reviewer: Boris Shingarov <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s