// Decode MIPS MT MFTR instruction into sub-instructions
0x8: decode MT_U {
0x0: mftc0({{
- data = xc->readRegOtherThread(RegId(MiscRegClass,
+ data = readRegOtherThread(xc, RegId(MiscRegClass,
(RT << 3 | SEL)));
}});
0x1: decode SEL {
0x0: mftgpr({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, RT));
}});
0x1: decode RT {
0x0: mftlo_dsp0({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO0));
}});
0x1: mfthi_dsp0({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI0));
}});
0x2: mftacx_dsp0({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX0));
}});
0x4: mftlo_dsp1({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO1));
}});
0x5: mfthi_dsp1({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI1));
}});
0x6: mftacx_dsp1({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX1));
}});
0x8: mftlo_dsp2({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO2));
}});
0x9: mfthi_dsp2({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI2));
}});
0x10: mftacx_dsp2({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX2));
}});
0x12: mftlo_dsp3({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO3));
}});
0x13: mfthi_dsp3({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI3));
}});
0x14: mftacx_dsp3({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX3));
}});
0x16: mftdsp({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_CONTROL));
}});
default: CP0Unimpl::unknown();
}
0x2: decode MT_H {
0x0: mftc1({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(FloatRegClass, RT));
}});
0x1: mfthc1({{
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(FloatRegClass, RT));
}});
}
0x3: cftc1({{
- uint32_t fcsr_val = xc->readRegOtherThread(
+ uint32_t fcsr_val = readRegOtherThread(xc,
RegId(FloatRegClass, FLOATREG_FCSR));
switch (RT) {
case 0:
- data = xc->readRegOtherThread(
+ data = readRegOtherThread(xc,
RegId(MiscRegClass, FLOATREG_FIR));
break;
case 25:
format MT_MTTR {
// Decode MIPS MT MTTR instruction into sub-instructions
0xC: decode MT_U {
- 0x0: mttc0({{ xc->setRegOtherThread(
+ 0x0: mttc0({{ setRegOtherThread(xc,
RegId(MiscRegClass, (RD << 3 | SEL)), Rt);
}});
0x1: decode SEL {
- 0x0: mttgpr({{ xc->setRegOtherThread(
+ 0x0: mttgpr({{ setRegOtherThread(xc,
RegId(IntRegClass, RD), Rt);
}});
0x1: decode RT {
- 0x0: mttlo_dsp0({{ xc->setRegOtherThread(
+ 0x0: mttlo_dsp0({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO0), Rt);
}});
- 0x1: mtthi_dsp0({{ xc->setRegOtherThread(
+ 0x1: mtthi_dsp0({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI0), Rt);
}});
- 0x2: mttacx_dsp0({{ xc->setRegOtherThread(
+ 0x2: mttacx_dsp0({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX0), Rt);
}});
- 0x4: mttlo_dsp1({{ xc->setRegOtherThread(
+ 0x4: mttlo_dsp1({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO1), Rt);
}});
- 0x5: mtthi_dsp1({{ xc->setRegOtherThread(
+ 0x5: mtthi_dsp1({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI1), Rt);
}});
- 0x6: mttacx_dsp1({{ xc->setRegOtherThread(
+ 0x6: mttacx_dsp1({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX1), Rt);
}});
- 0x8: mttlo_dsp2({{ xc->setRegOtherThread(
+ 0x8: mttlo_dsp2({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO2), Rt);
}});
- 0x9: mtthi_dsp2({{ xc->setRegOtherThread(
+ 0x9: mtthi_dsp2({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI2), Rt);
}});
- 0x10: mttacx_dsp2({{ xc->setRegOtherThread(
+ 0x10: mttacx_dsp2({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX2), Rt);
}});
- 0x12: mttlo_dsp3({{ xc->setRegOtherThread(
+ 0x12: mttlo_dsp3({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_LO3), Rt);
}});
- 0x13: mtthi_dsp3({{ xc->setRegOtherThread(
+ 0x13: mtthi_dsp3({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_HI3), Rt);
}});
- 0x14: mttacx_dsp3({{ xc->setRegOtherThread(
+ 0x14: mttacx_dsp3({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_ACX3), Rt);
}});
- 0x16: mttdsp({{ xc->setRegOtherThread(
+ 0x16: mttdsp({{ setRegOtherThread(xc,
RegId(IntRegClass, INTREG_DSP_CONTROL), Rt);
}});
default: CP0Unimpl::unknown();
}
0x2: mttc1({{
- uint64_t data = xc->readRegOtherThread(
+ uint64_t data = readRegOtherThread(xc,
RegId(FloatRegClass, RD));
data = insertBits(data, MT_H ? 63 : 31,
MT_H ? 32 : 0, Rt);
- xc->setRegOtherThread(RegId(FloatRegClass, RD),
+ setRegOtherThread(xc, RegId(FloatRegClass, RD),
data);
}});
0x3: cttc1({{
"Access to Floating Control "
"S""tatus Register", FS);
}
- xc->setRegOtherThread(
+ setRegOtherThread(xc,
RegId(FloatRegClass, FLOATREG_FCSR), data);
}});
default: CP0Unimpl::unknown();
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "base/trace.hh"
+#include "cpu/exec_context.hh"
namespace MipsISA
{
+static inline RegVal
+readRegOtherThread(ThreadContext *tc, const RegId ®,
+ ThreadID tid=InvalidThreadID)
+{
+ ThreadContext *otc = nullptr;
+ if (tid != InvalidThreadID)
+ otc = tc->getCpuPtr()->getContext(tid);
+ else
+ otc = tc;
+
+ switch (reg.classValue()) {
+ case IntRegClass:
+ return otc->readIntReg(reg.index());
+ break;
+ case FloatRegClass:
+ return otc->readFloatReg(reg.index());
+ break;
+ case MiscRegClass:
+ return otc->readMiscReg(reg.index());
+ default:
+ panic("Unexpected reg class! (%s)", reg.className());
+ }
+}
+
+static inline void
+setRegOtherThread(ThreadContext *tc, const RegId& reg, RegVal val,
+ ThreadID tid=InvalidThreadID)
+{
+ ThreadContext *otc = nullptr;
+ if (tid != InvalidThreadID)
+ otc = tc->getCpuPtr()->getContext(tid);
+ else
+ otc = tc;
+
+ switch (reg.classValue()) {
+ case IntRegClass:
+ return otc->setIntReg(reg.index(), val);
+ break;
+ case FloatRegClass:
+ return otc->setFloatReg(reg.index(), val);
+ break;
+ case MiscRegClass:
+ return otc->setMiscReg(reg.index(), val);
+ default:
+ panic("Unexpected reg class! (%s)", reg.className());
+ }
+}
+
+static inline RegVal
+readRegOtherThread(ExecContext *xc, const RegId ®,
+ ThreadID tid=InvalidThreadID)
+{
+ return readRegOtherThread(xc->tcBase(), reg, tid);
+}
+
+static inline void
+setRegOtherThread(ExecContext *xc, const RegId& reg, RegVal val,
+ ThreadID tid=InvalidThreadID)
+{
+ setRegOtherThread(xc->tcBase(), reg, val, tid);
+}
+
template <class TC>
inline unsigned
getVirtProcNum(TC *tc)
int success = 0;
for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
TCBindReg tidTCBind =
- tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_BIND), tid);
+ readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_BIND), tid);
TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
if (tidTCBind.curVPE == tcBind.curVPE) {
TCStatusReg tidTCStatus =
- tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+ readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_STATUS),
tid);
TCHaltReg tidTCHalt =
- tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_HALT),
+ readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_HALT),
tid);
if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
tidTCStatus.a == 0 && success == 0) {
- tc->setRegOtherThread(RegId(MiscRegClass, MISCREG_TC_RESTART),
+ setRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_RESTART),
Rs, tid);
- tc->setRegOtherThread(RegId(IntRegClass, Rd_bits), Rt, tid);
+ setRegOtherThread(tc, RegId(IntRegClass, Rd_bits), Rt, tid);
StatusReg status = tc->readMiscReg(MISCREG_STATUS);
TCStatusReg tcStatus = tc->readMiscReg(MISCREG_TC_STATUS);
tidTCStatus.asid = tcStatus.asid;
// Write Status Register
- tc->setRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+ setRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_STATUS),
tidTCStatus, tid);
// Mark As Successful Fork
for (ThreadID tid = 0; tid < num_threads; tid++) {
TCStatusReg tidTCStatus =
- tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+ readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_STATUS),
tid);
TCHaltReg tidTCHalt =
- tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_HALT),
+ readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_HALT),
tid);
TCBindReg tidTCBind =
- tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_BIND),
+ readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_BIND),
tid);
if (tidTCBind.curVPE == tcBind.curVPE &&