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;
}
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;
}
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;
}
{
}
- 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;
{
}
- 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;
# 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
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
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 = '''
{
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;
}
{
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;
{
Addr EA;
Fault fault = NoFault;
+ Msr msr = xc->readMiscReg(MISCREG_MSR);
%(op_decl)s;
%(op_rd)s;
}
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) {
{
Addr EA;
Fault fault = NoFault;
+ Msr msr = xc->readMiscReg(MISCREG_MSR);
%(op_decl)s;
%(op_rd)s;
}
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
'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),
MISCREG_LR,
MISCREG_CTR,
MISCREG_TAR,
+ MISCREG_MSR,
NUM_MISCREGS
};
"XER",
"LR",
"CTR",
- "TAR"
+ "TAR",
+ "MSR"
};
BitUnion32(Cr)
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__
//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.