class ExecContext;
namespace LittleEndianGuest {};
-using namespace LittleEndianGuest;
#define TARGET_MIPS
namespace MipsISA
{
+ using namespace LittleEndianGuest;
+
typedef uint32_t MachInst;
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
const int ReturnAddressReg = 31;
const int SyscallNumReg = ReturnValueReg1;
- const int SyscallPseudoReturnReg = ArgumentReg3;
- const int SyscallSuccessReg = 19;
+ const int SyscallPseudoReturnReg = ReturnValueReg1;
+ const int SyscallSuccessReg = ReturnValueReg1;
const int LogVMPageSize = 13; // 8K bytes
const int VMPageSize = (1 << LogVMPageSize);
};
typedef uint64_t IntReg;
- typedef IntReg IntRegFile[NumIntRegs];
+
+ class IntRegFile
+ {
+ protected:
+ IntReg regs[NumIntRegs];
+
+ public:
+ IntReg readReg(int intReg)
+ {
+ return regs[intReg];
+ }
+
+ Fault setReg(int intReg, const IntReg &val)
+ {
+ regs[intReg] = val;
+ return NoFault;
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string §ion);
+
+ };
/* floating point register file entry type
typedef union {
MiscReg ctrlreg;
} AnyReg;
- struct RegFile {
+ class RegFile {
+ protected:
IntRegFile intRegFile; // (signed) integer register file
FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegs; // control register file
+ MiscRegFile miscRegFile; // control register file
+
+ public:
+
+ void clear()
+ {
+ bzero(&intRegFile, sizeof(intRegFile));
+ bzero(&floatRegFile, sizeof(floatRegFile));
+ bzero(&miscRegFile, sizeof(miscRegFile));
+ }
+
+ MiscReg readMiscReg(int miscReg)
+ {
+ return miscRegFile.readReg(miscReg);
+ }
+
+ MiscReg readMiscRegWithEffect(int miscReg,
+ Fault &fault, ExecContext *xc)
+ {
+ fault = NoFault;
+ return miscRegFile.readRegWithEffect(miscReg, fault, xc);
+ }
+
+ Fault setMiscReg(int miscReg, const MiscReg &val)
+ {
+ return miscRegFile.setReg(miscReg, val);
+ }
+
+ Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ ExecContext * xc)
+ {
+ return miscRegFile.setRegWithEffect(miscReg, val, xc);
+ }
+
+ FloatReg readFloatReg(int floatReg)
+ {
+ return floatRegFile.readReg(floatReg);
+ }
+
+ FloatReg readFloatReg(int floatReg, int width)
+ {
+ return readFloatReg(floatReg);
+ }
+
+ FloatRegBits readFloatRegBits(int floatReg)
+ {
+ return floatRegFile.readRegBits(floatReg);
+ }
+ FloatRegBits readFloatRegBits(int floatReg, int width)
+ {
+ return readFloatRegBits(floatReg);
+ }
+
+ Fault setFloatReg(int floatReg, const FloatReg &val)
+ {
+ return floatRegFile.setReg(floatReg, val);
+ }
+
+ Fault setFloatReg(int floatReg, const FloatReg &val, int width)
+ {
+ return setFloatReg(floatReg, val);
+ }
+
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
+ {
+ return floatRegFile.setRegBits(floatReg, val);
+ }
+
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ return setFloatRegBits(floatReg, val);
+ }
+
+ IntReg readIntReg(int intReg)
+ {
+ return intRegFile.readReg(intReg);
+ }
+
+ Fault setIntReg(int intReg, const IntReg &val)
+ {
+ return intRegFile.setReg(intReg, val);
+ }
+ protected:
Addr pc; // program counter
Addr npc; // next-cycle program counter
Addr nnpc; // next-next-cycle program counter
// used to implement branch delay slot
// not real register
+ public:
+ Addr readPC()
+ {
+ return pc;
+ }
+
+ void setPC(Addr val)
+ {
+ pc = val;
+ }
+
+ Addr readNextPC()
+ {
+ return npc;
+ }
+
+ void setNextPC(Addr val)
+ {
+ npc = val;
+ }
+
+ Addr readNextNPC()
+ {
+ return nnpc;
+ }
+
+ void setNextNPC(Addr val)
+ {
+ nnpc = val;
+ }
MiscReg hi; // MIPS HI Register
MiscReg lo; // MIPS LO Register
void createCP0Regs();
void coldReset();
+
+ typedef int ContextParam;
+ typedef int ContextVal;
+
+ void changeContext(ContextParam param, ContextVal val)
+ {
+ }
};
StaticInstPtr decodeInst(ExtMachInst);
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
- regs->intRegFile[ReturnValueReg1] = 1;
+ // check for error condition. Alpha syscall convention is to
+ // indicate success/failure in reg a3 (r19) and put the
+ // return value itself in the standard return value reg (v0).
+ if (return_value.successful()) {
+ // no error
+ regs->setIntReg(ReturnValueReg1, 0);
+ regs->setIntReg(ReturnValueReg2, return_value.value());
+ } else {
+ // got an error, return details
+ regs->setIntReg(ReturnValueReg1, (IntReg) -1);
+ regs->setIntReg(ReturnValueReg2, -return_value.value());
+ }
+
+ //regs->intRegFile[ReturnValueReg1] = (IntReg)return_value;
//panic("Returning from syscall\n");
}