summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/faults.cc4
-rw-r--r--arch/mips/isa/base.isa25
-rw-r--r--arch/mips/isa/decoder.isa26
-rw-r--r--arch/mips/isa/formats/branch.isa6
-rw-r--r--arch/mips/isa_traits.cc18
-rw-r--r--arch/mips/isa_traits.hh117
-rw-r--r--arch/mips/process.cc2
-rw-r--r--base/loader/elf_object.cc4
-rw-r--r--base/loader/object_file.hh4
-rw-r--r--base/traceflags.py1
-rwxr-xr-xconfigs/test/hello_mipsbin0 -> 623837 bytes
-rw-r--r--cpu/simple/cpu.cc7
-rw-r--r--cpu/static_inst.hh11
13 files changed, 158 insertions, 67 deletions
diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc
index 142328c40..1b31dfa69 100644
--- a/arch/mips/faults.cc
+++ b/arch/mips/faults.cc
@@ -34,11 +34,11 @@
namespace MipsISA
{
-FaultName MachineCheckFault::_name = "mchk";
+FaultName MachineCheckFault::_name = "Machine Check";
FaultVect MachineCheckFault::_vect = 0x0401;
FaultStat MachineCheckFault::_count;
-FaultName AlignmentFault::_name = "unalign";
+FaultName AlignmentFault::_name = "Alignment";
FaultVect AlignmentFault::_vect = 0x0301;
FaultStat AlignmentFault::_count;
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
index 4125b5101..89837c136 100644
--- a/arch/mips/isa/base.isa
+++ b/arch/mips/isa/base.isa
@@ -66,27 +66,24 @@ output decoder {{
ccprintf(ss, "%-10s ", mnemonic);
- // just print the first two source regs... if there's
- // a third one, it's a read-modify-write dest (Rc),
- // e.g. for CMOVxx
- if(_numSrcRegs > 0)
- {
+ if(_numDestRegs > 0){
+ if(_numSrcRegs > 0)
+ ss << ",";
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
- if(_numSrcRegs > 1)
- {
+ if(_numSrcRegs > 1) {
ss << ",";
printReg(ss, _srcRegIdx[1]);
}
- // just print the first dest... if there's a second one,
- // it's generally implicit
- if(_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- ss << ",";
- printReg(ss, _destRegIdx[0]);
+
+ if(mnemonic == "sll"){
+ ccprintf(ss," %d",SA);
}
return ss.str();
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 93e7238f8..2e5f8e536 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -28,19 +28,19 @@ decode OPCODE_HI default Unknown::unknown() {
format BasicOp {
//Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
- //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
-
+ //are used to distinguish among the SLL, NOP, SSNOP and EHB functions.
0x0: decode RS {
- 0x0: decode RT {
- 0x0: decode RD default Nop::nop() {
+ 0x0: decode RT { //fix Nop traditional vs. Nop converted disassembly later
+ 0x0: decode RD default Nop::nop(){
0x0: decode SA {
- 0x1: ssnop({{ ; }}); //really sll r0,r0,1
- 0x3: ehb({{ ; }}); //really sll r0,r0,3
+ 0x1: ssnop({{ ; }}); //really sll r0,r0,1
+ 0x3: ehb({{ ; }}); //really sll r0,r0,3
}
}
+
+ default: sll({{ Rd = Rt.uw << SA; }});
}
- default: sll({{ Rd = Rt.uw << SA; }});
}
0x2: decode SRL {
@@ -77,9 +77,9 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x1: decode HINT {
- 0: jalr({{ NNPC = Rs; }},IsCall,IsReturn);
+ 0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn);
- 1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
+ 1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
}
}
@@ -866,7 +866,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: lb({{ Rt.sw = Mem.sb; }});
0x1: lh({{ Rt.sw = Mem.sh; }});
0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign);
- 0x3: lw({{ Rt.sw = Mem.sb; }});
+ 0x3: lw({{ Rt.sw = Mem.sw; }});
0x4: lbu({{ Rt.uw = Mem.ub; }});
0x5: lhu({{ Rt.uw = Mem.uh; }});
0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign);
@@ -879,9 +879,9 @@ decode OPCODE_HI default Unknown::unknown() {
format StoreMemory {
0x0: sb({{ Mem.ub = Rt<7:0>; }});
0x1: sh({{ Mem.uh = Rt<15:0>; }});
- 0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
- 0x3: sw({{ Mem.ub = Rt<31:0>; }});
- 0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
+ 0x2: swl({{ Mem.uw = Rt<31:0>; }});//,WordAlign);
+ 0x3: sw({{ Mem.uw = Rt<31:0>; }});
+ 0x6: swr({{ Mem.uw = Rt<31:0>; }});//,WordAlign);
}
format WarnUnimpl {
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index ce84f4b51..cb0f4ac9c 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -187,6 +187,12 @@ output decoder {{
else
ccprintf(ss, "0x%x", target);
+ string inst_name = mnemonic;
+
+ if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){
+ ccprintf(ss, " (r31=0x%x)",pc+8);
+ }
+
return ss.str();
}
diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc
index 58d974448..849d3311d 100644
--- a/arch/mips/isa_traits.cc
+++ b/arch/mips/isa_traits.cc
@@ -34,6 +34,20 @@
using namespace MipsISA;
+
+void
+MipsISA::copyRegs(ExecContext *src, ExecContext *dest)
+{
+ /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
+ uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
+ lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
+ lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
+
+#if FULL_SYSTEM
+ copyIprs(xc);
+ #endif*/
+}
+
void
MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc)
{
@@ -264,7 +278,7 @@ void
RegFile::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(intRegFile, NumIntRegs);
- SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
+ //SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
//SERIALIZE_SCALAR(miscRegs.fpcr);
//SERIALIZE_SCALAR(miscRegs.uniq);
//SERIALIZE_SCALAR(miscRegs.lock_flag);
@@ -285,7 +299,7 @@ void
RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
- UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
+ //UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
//UNSERIALIZE_SCALAR(miscRegs.uniq);
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 833d3cc63..1a982c237 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -40,6 +40,7 @@
class FastCPU;
class FullCPU;
class Checkpoint;
+class ExecContext;
namespace LittleEndianGuest {};
using namespace LittleEndianGuest;
@@ -119,22 +120,23 @@ namespace MipsISA
const int MaxInstDestRegs = 2;
// semantically meaningful register indices
- const int ZeroReg = 31; // architecturally meaningful
- // the rest of these depend on the ABI
- const int StackPointerReg = 30;
- const int GlobalPointerReg = 29;
- const int ProcedureValueReg = 27;
- const int ReturnAddressReg = 26;
- const int ReturnValueReg = 0;
- const int FramePointerReg = 15;
- const int ArgumentReg0 = 16;
- const int ArgumentReg1 = 17;
- const int ArgumentReg2 = 18;
- const int ArgumentReg3 = 19;
- const int ArgumentReg4 = 20;
- const int ArgumentReg5 = 21;
- const int SyscallNumReg = ReturnValueReg;
- const int SyscallPseudoReturnReg = ArgumentReg4;
+ const int ZeroReg = 0;
+ const int AssemblerReg = 1;
+ const int ReturnValueReg1 = 2;
+ const int ReturnValueReg2 = 3;
+ const int ArgumentReg0 = 4;
+ const int ArgumentReg1 = 5;
+ const int ArgumentReg2 = 6;
+ const int ArgumentReg3 = 7;
+ const int KernelReg0 = 26;
+ const int KernelReg1 = 27;
+ const int GlobalPointerReg = 28;
+ const int StackPointerReg = 29;
+ const int FramePointerReg = 30;
+ const int ReturnAddressReg = 31;
+
+ const int SyscallNumReg = ReturnValueReg1;
+ const int SyscallPseudoReturnReg = ArgumentReg3;
const int SyscallSuccessReg = 19;
const int LogVMPageSize = 13; // 8K bytes
@@ -163,16 +165,78 @@ namespace MipsISA
typedef uint64_t IntReg;
typedef IntReg IntRegFile[NumIntRegs];
- // floating point register file entry type
+/* floating point register file entry type
typedef union {
uint64_t q;
double d;
- } FloatReg;
+ } FloatReg;*/
- typedef union {
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+
+/*typedef union {
uint64_t q[NumFloatRegs]; // integer qword view
double d[NumFloatRegs]; // double-precision floating point view
- } FloatRegFile;
+ } FloatRegFile;*/
+
+ class FloatRegFile
+ {
+ protected:
+
+ FloatRegBits q[NumFloatRegs]; // integer qword view
+ double d[NumFloatRegs]; // double-precision floating point view
+
+ public:
+
+ FloatReg readReg(int floatReg)
+ {
+ return d[floatReg];
+ }
+
+ FloatReg readReg(int floatReg, int width)
+ {
+ return readReg(floatReg);
+ }
+
+ FloatRegBits readRegBits(int floatReg)
+ {
+ return q[floatReg];
+ }
+
+ FloatRegBits readRegBits(int floatReg, int width)
+ {
+ return readRegBits(floatReg);
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val)
+ {
+ d[floatReg] = val;
+ return NoFault;
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val, int width)
+ {
+ return setReg(floatReg, val);
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val)
+ {
+ q[floatReg] = val;
+ return NoFault;
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ return setRegBits(floatReg, val);
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ };
+
+ void copyRegs(ExecContext *src, ExecContext *dest);
// cop-0/cop-1 system control register file
typedef uint64_t MiscReg;
@@ -525,18 +589,7 @@ extern const Addr PageOffset;
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
- // check for error condition. SPARC syscall convention is to
- // indicate success/failure in reg the carry bit of the ccr
- // and put the return value itself in the standard return value reg ().
- if (return_value.successful()) {
- // no error
- //regs->miscRegFile.ccrFields.iccFields.c = 0;
- regs->intRegFile[ReturnValueReg] = return_value.value();
- } else {
- // got an error, return details
- //regs->miscRegFile.ccrFields.iccFields.c = 1;
- regs->intRegFile[ReturnValueReg] = -return_value.value();
- }
+ panic("Returning from syscall\n");
}
// Machine operations
diff --git a/arch/mips/process.cc b/arch/mips/process.cc
index a4ce3f5f1..3f24fc68f 100644
--- a/arch/mips/process.cc
+++ b/arch/mips/process.cc
@@ -52,7 +52,7 @@ MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
}
- if (objFile->getArch() != ObjectFile::MIPS)
+ if (objFile->getArch() != ObjectFile::Mips)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc
index 844a0bea8..58029bc3e 100644
--- a/base/loader/elf_object.cc
+++ b/base/loader/elf_object.cc
@@ -91,7 +91,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
arch = ObjectFile::SPARC;
} else if (ehdr.e_machine == EM_MIPS
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
- arch = ObjectFile::MIPS;
+ arch = ObjectFile::Mips;
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
arch = ObjectFile::Alpha;
} else {
@@ -155,6 +155,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
section = elf_getscn(elf, ++secIdx);
} // while sections
}
+
elf_end(elf);
return new ElfObject(fname, fd, len, data, arch, opSys);
}
@@ -186,6 +187,7 @@ ElfObject::ElfObject(const string &_filename, int _fd,
entry = ehdr.e_entry;
+
// initialize segment sizes to 0 in case they're not present
text.size = data.size = bss.size = 0;
diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh
index 08a51863e..309089728 100644
--- a/base/loader/object_file.hh
+++ b/base/loader/object_file.hh
@@ -44,7 +44,7 @@ class ObjectFile
UnknownArch,
Alpha,
SPARC,
- MIPS
+ Mips
};
enum OpSys {
@@ -95,9 +95,11 @@ class ObjectFile
Section bss;
bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys);
+ void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
public:
Addr entryPoint() const { return entry; }
+
Addr globalPointer() const { return globalPtr; }
Addr textBase() const { return text.baseAddr; }
diff --git a/base/traceflags.py b/base/traceflags.py
index e814a00fb..c3b878027 100644
--- a/base/traceflags.py
+++ b/base/traceflags.py
@@ -142,6 +142,7 @@ baseFlags = [
'OoOCPU',
'HWPrefetch',
'Stack',
+ 'SimpleCPU',
]
#
diff --git a/configs/test/hello_mips b/configs/test/hello_mips
new file mode 100755
index 000000000..182182b4f
--- /dev/null
+++ b/configs/test/hello_mips
Binary files differ
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index a135f45d6..d188074d4 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -889,6 +889,8 @@ SimpleCPU::post_interrupt(int int_num, int index)
void
SimpleCPU::tick()
{
+ DPRINTF(SimpleCPU,"\n\n");
+
numCycles++;
traceData = NULL;
@@ -961,7 +963,7 @@ SimpleCPU::tick()
#define IFETCH_FLAGS(pc) 0
#endif
- DPRINTF(Fetch,"Fetching PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(),
+ DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(),
cpuXC->readNextPC(),cpuXC->readNextNPC());
#if SIMPLE_CPU_MEM_TIMING
@@ -1033,6 +1035,9 @@ SimpleCPU::tick()
traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst,
cpuXC->readPC());
+ DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
+ curStaticInst->getName(),curStaticInst->getOpcode(), curStaticInst->machInst);
+
#if FULL_SYSTEM
cpuXC->setInst(inst);
#endif // FULL_SYSTEM
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 764020577..a200e2849 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -391,6 +391,17 @@ class StaticInst : public StaticInstBase
/// @retval A pointer to the corresponding StaticInst object.
//This is defined as inline below.
static StaticInstPtr decode(ExtMachInst mach_inst);
+
+ //MIPS Decoder Debug Functions
+ int getOpcode() { return (machInst & 0xFC000000) >> 26 ; }//31..26
+ int getRs() { return (machInst & 0x03E00000) >> 21; } //25...21
+ int getRt() { return (machInst & 0x001F0000) >> 16; } //20...16
+ int getRd() { return (machInst & 0x0000F800) >> 11; } //15...11
+ int getOpname(){ return (machInst & 0x0000003F); }//5...0
+ int getBranch(){ return (machInst & 0x0000FFFF); }//5...0
+ int getJump(){ return (machInst & 0x03FFFFFF); }//5...0
+ int getHint(){ return (machInst & 0x000007C0) >> 6; } //10...6
+ std::string getName() { return mnemonic; }
};
typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;