infinitesimal small baby steps toward MIPS actually working
arch/mips/isa/formats/branch.isa: let user know that we alter r31 in disassembly arch/mips/isa_traits.cc: add copyRegs function ... comment out serialize float code for now arch/mips/isa_traits.hh: make FloatRegFile a class ... change values of architectural regs arch/mips/process.cc: change MIPS to Mips base/loader/elf_object.cc: get global pointer initialized to a value base/loader/elf_object.hh: Add global_ptr to elf_object constructor base/loader/object_file.hh: MIPS to Mips base/traceflags.py: SimpleCPU trace flag cpu/simple/cpu.cc: DPRINTF flags for SimpleCPU cpu/static_inst.hh: Add Decoder functions to static_inst.hh --HG-- extra : convert_revision : 0544a8524d3fe4229428cb06822f7da208c72459
This commit is contained in:
parent
0d8cfed042
commit
c32b4ecac1
10 changed files with 170 additions and 41 deletions
|
@ -187,6 +187,12 @@ output decoder {{
|
||||||
else
|
else
|
||||||
ccprintf(ss, "0x%x", target);
|
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();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,20 @@
|
||||||
using namespace MipsISA;
|
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
|
void
|
||||||
MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc)
|
MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc)
|
||||||
{
|
{
|
||||||
|
@ -264,7 +278,7 @@ void
|
||||||
RegFile::serialize(std::ostream &os)
|
RegFile::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
SERIALIZE_ARRAY(intRegFile, NumIntRegs);
|
SERIALIZE_ARRAY(intRegFile, NumIntRegs);
|
||||||
SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
//SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
||||||
//SERIALIZE_SCALAR(miscRegs.fpcr);
|
//SERIALIZE_SCALAR(miscRegs.fpcr);
|
||||||
//SERIALIZE_SCALAR(miscRegs.uniq);
|
//SERIALIZE_SCALAR(miscRegs.uniq);
|
||||||
//SERIALIZE_SCALAR(miscRegs.lock_flag);
|
//SERIALIZE_SCALAR(miscRegs.lock_flag);
|
||||||
|
@ -285,7 +299,7 @@ void
|
||||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
|
UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
|
||||||
UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
//UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
||||||
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
|
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
|
||||||
//UNSERIALIZE_SCALAR(miscRegs.uniq);
|
//UNSERIALIZE_SCALAR(miscRegs.uniq);
|
||||||
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
|
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
class FastCPU;
|
class FastCPU;
|
||||||
class FullCPU;
|
class FullCPU;
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
|
class ExecContext;
|
||||||
|
|
||||||
namespace LittleEndianGuest {};
|
namespace LittleEndianGuest {};
|
||||||
using namespace LittleEndianGuest;
|
using namespace LittleEndianGuest;
|
||||||
|
@ -119,22 +120,23 @@ namespace MipsISA
|
||||||
const int MaxInstDestRegs = 2;
|
const int MaxInstDestRegs = 2;
|
||||||
|
|
||||||
// semantically meaningful register indices
|
// semantically meaningful register indices
|
||||||
const int ZeroReg = 31; // architecturally meaningful
|
const int ZeroReg = 0;
|
||||||
// the rest of these depend on the ABI
|
const int AssemblerReg = 1;
|
||||||
const int StackPointerReg = 30;
|
const int ReturnValueReg1 = 2;
|
||||||
const int GlobalPointerReg = 29;
|
const int ReturnValueReg2 = 3;
|
||||||
const int ProcedureValueReg = 27;
|
const int ArgumentReg0 = 4;
|
||||||
const int ReturnAddressReg = 26;
|
const int ArgumentReg1 = 5;
|
||||||
const int ReturnValueReg = 0;
|
const int ArgumentReg2 = 6;
|
||||||
const int FramePointerReg = 15;
|
const int ArgumentReg3 = 7;
|
||||||
const int ArgumentReg0 = 16;
|
const int KernelReg0 = 26;
|
||||||
const int ArgumentReg1 = 17;
|
const int KernelReg1 = 27;
|
||||||
const int ArgumentReg2 = 18;
|
const int GlobalPointerReg = 28;
|
||||||
const int ArgumentReg3 = 19;
|
const int StackPointerReg = 29;
|
||||||
const int ArgumentReg4 = 20;
|
const int FramePointerReg = 30;
|
||||||
const int ArgumentReg5 = 21;
|
const int ReturnAddressReg = 31;
|
||||||
const int SyscallNumReg = ReturnValueReg;
|
|
||||||
const int SyscallPseudoReturnReg = ArgumentReg4;
|
const int SyscallNumReg = ReturnValueReg1;
|
||||||
|
const int SyscallPseudoReturnReg = ArgumentReg3;
|
||||||
const int SyscallSuccessReg = 19;
|
const int SyscallSuccessReg = 19;
|
||||||
|
|
||||||
const int LogVMPageSize = 13; // 8K bytes
|
const int LogVMPageSize = 13; // 8K bytes
|
||||||
|
@ -162,16 +164,78 @@ namespace MipsISA
|
||||||
typedef uint64_t IntReg;
|
typedef uint64_t IntReg;
|
||||||
typedef IntReg IntRegFile[NumIntRegs];
|
typedef IntReg IntRegFile[NumIntRegs];
|
||||||
|
|
||||||
// floating point register file entry type
|
/* floating point register file entry type
|
||||||
typedef union {
|
typedef union {
|
||||||
uint64_t q;
|
uint64_t q;
|
||||||
double d;
|
double d;
|
||||||
} FloatReg;
|
} FloatReg;*/
|
||||||
|
|
||||||
typedef union {
|
typedef double FloatReg;
|
||||||
|
typedef uint64_t FloatRegBits;
|
||||||
|
|
||||||
|
/*typedef union {
|
||||||
uint64_t q[NumFloatRegs]; // integer qword view
|
uint64_t q[NumFloatRegs]; // integer qword view
|
||||||
double d[NumFloatRegs]; // double-precision floating point 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 §ion);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||||
|
|
||||||
// cop-0/cop-1 system control register file
|
// cop-0/cop-1 system control register file
|
||||||
typedef uint64_t MiscReg;
|
typedef uint64_t MiscReg;
|
||||||
|
@ -524,18 +588,7 @@ extern const Addr PageOffset;
|
||||||
|
|
||||||
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
|
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
|
||||||
{
|
{
|
||||||
// check for error condition. SPARC syscall convention is to
|
panic("Returning from syscall\n");
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Machine operations
|
// Machine operations
|
||||||
|
|
|
@ -42,7 +42,7 @@ createProcess(const string &nm, ObjectFile * objFile, System * system,
|
||||||
vector<string> &argv, vector<string> &envp)
|
vector<string> &argv, vector<string> &envp)
|
||||||
{
|
{
|
||||||
LiveProcess * process = NULL;
|
LiveProcess * process = NULL;
|
||||||
if (objFile->getArch() != ObjectFile::MIPS)
|
if (objFile->getArch() != ObjectFile::Mips)
|
||||||
fatal("Object file does not match architecture.");
|
fatal("Object file does not match architecture.");
|
||||||
switch (objFile->getOpSys()) {
|
switch (objFile->getOpSys()) {
|
||||||
case ObjectFile::Linux:
|
case ObjectFile::Linux:
|
||||||
|
|
|
@ -92,7 +92,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
|
||||||
arch = ObjectFile::SPARC;
|
arch = ObjectFile::SPARC;
|
||||||
} else if (ehdr.e_machine == EM_MIPS
|
} else if (ehdr.e_machine == EM_MIPS
|
||||||
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
|
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
|
||||||
arch = ObjectFile::MIPS;
|
arch = ObjectFile::Mips;
|
||||||
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
|
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
|
||||||
arch = ObjectFile::Alpha;
|
arch = ObjectFile::Alpha;
|
||||||
} else {
|
} else {
|
||||||
|
@ -156,14 +156,49 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
|
||||||
section = elf_getscn(elf, ++secIdx);
|
section = elf_getscn(elf, ++secIdx);
|
||||||
} // while sections
|
} // while sections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t global_ptr;
|
||||||
|
if (arch == ObjectFile::Mips) {
|
||||||
|
Elf_Scn *section;
|
||||||
|
GElf_Shdr shdr;
|
||||||
|
Elf_Data *rdata;
|
||||||
|
int secIdx = 1;
|
||||||
|
|
||||||
|
// Get the first section
|
||||||
|
section = elf_getscn(elf, secIdx);
|
||||||
|
|
||||||
|
// While there are no more sections
|
||||||
|
while (section != NULL) {
|
||||||
|
gelf_getshdr(section, &shdr);
|
||||||
|
/*shdr.sh_type == SHT_MIPS_REGINFO && */
|
||||||
|
if (!strcmp(".reginfo",elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) {
|
||||||
|
// We have found MIPS reginfo section:
|
||||||
|
// -------------------------------
|
||||||
|
// Check the 6th 32bit word for the initialized global pointer value
|
||||||
|
// -------------------------------
|
||||||
|
rdata = elf_rawdata(section, NULL);
|
||||||
|
assert(rdata->d_buf);
|
||||||
|
|
||||||
|
if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
|
||||||
|
global_ptr = htole(((int32_t*)rdata->d_buf)[5]);
|
||||||
|
else
|
||||||
|
global_ptr = htobe(((int32_t*)rdata->d_buf)[5]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
section = elf_getscn(elf, ++secIdx);
|
||||||
|
} // if section found
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
elf_end(elf);
|
elf_end(elf);
|
||||||
return new ElfObject(fname, fd, len, data, arch, opSys);
|
return new ElfObject(fname, fd, len, data, global_ptr,arch, opSys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ElfObject::ElfObject(const string &_filename, int _fd,
|
ElfObject::ElfObject(const string &_filename, int _fd,
|
||||||
size_t _len, uint8_t *_data,
|
size_t _len, uint8_t *_data,Addr global_ptr,
|
||||||
Arch _arch, OpSys _opSys)
|
Arch _arch, OpSys _opSys)
|
||||||
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
||||||
|
|
||||||
|
@ -187,6 +222,8 @@ ElfObject::ElfObject(const string &_filename, int _fd,
|
||||||
|
|
||||||
entry = ehdr.e_entry;
|
entry = ehdr.e_entry;
|
||||||
|
|
||||||
|
globalPtr = global_ptr;
|
||||||
|
|
||||||
// initialize segment sizes to 0 in case they're not present
|
// initialize segment sizes to 0 in case they're not present
|
||||||
text.size = data.size = bss.size = 0;
|
text.size = data.size = bss.size = 0;
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class ElfObject : public ObjectFile
|
||||||
bool loadSomeSymbols(SymbolTable *symtab, int binding);
|
bool loadSomeSymbols(SymbolTable *symtab, int binding);
|
||||||
|
|
||||||
ElfObject(const std::string &_filename, int _fd,
|
ElfObject(const std::string &_filename, int _fd,
|
||||||
size_t _len, uint8_t *_data,
|
size_t _len, uint8_t *_data,Addr global_ptr,
|
||||||
Arch _arch, OpSys _opSys);
|
Arch _arch, OpSys _opSys);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -44,7 +44,7 @@ class ObjectFile
|
||||||
UnknownArch,
|
UnknownArch,
|
||||||
Alpha,
|
Alpha,
|
||||||
SPARC,
|
SPARC,
|
||||||
MIPS
|
Mips
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OpSys {
|
enum OpSys {
|
||||||
|
@ -95,9 +95,11 @@ class ObjectFile
|
||||||
Section bss;
|
Section bss;
|
||||||
|
|
||||||
bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys);
|
bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys);
|
||||||
|
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr entryPoint() const { return entry; }
|
Addr entryPoint() const { return entry; }
|
||||||
|
|
||||||
Addr globalPointer() const { return globalPtr; }
|
Addr globalPointer() const { return globalPtr; }
|
||||||
|
|
||||||
Addr textBase() const { return text.baseAddr; }
|
Addr textBase() const { return text.baseAddr; }
|
||||||
|
|
|
@ -142,6 +142,7 @@ baseFlags = [
|
||||||
'OoOCPU',
|
'OoOCPU',
|
||||||
'HWPrefetch',
|
'HWPrefetch',
|
||||||
'Stack',
|
'Stack',
|
||||||
|
'SimpleCPU',
|
||||||
]
|
]
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -889,6 +889,8 @@ SimpleCPU::post_interrupt(int int_num, int index)
|
||||||
void
|
void
|
||||||
SimpleCPU::tick()
|
SimpleCPU::tick()
|
||||||
{
|
{
|
||||||
|
DPRINTF(SimpleCPU,"\n\n");
|
||||||
|
|
||||||
numCycles++;
|
numCycles++;
|
||||||
|
|
||||||
traceData = NULL;
|
traceData = NULL;
|
||||||
|
@ -961,7 +963,7 @@ SimpleCPU::tick()
|
||||||
#define IFETCH_FLAGS(pc) 0
|
#define IFETCH_FLAGS(pc) 0
|
||||||
#endif
|
#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());
|
cpuXC->readNextPC(),cpuXC->readNextNPC());
|
||||||
|
|
||||||
#if SIMPLE_CPU_MEM_TIMING
|
#if SIMPLE_CPU_MEM_TIMING
|
||||||
|
@ -1033,6 +1035,9 @@ SimpleCPU::tick()
|
||||||
traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst,
|
traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst,
|
||||||
cpuXC->readPC());
|
cpuXC->readPC());
|
||||||
|
|
||||||
|
DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
|
||||||
|
curStaticInst->getName(),curStaticInst->getOpcode(), curStaticInst->machInst);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
cpuXC->setInst(inst);
|
cpuXC->setInst(inst);
|
||||||
#endif // FULL_SYSTEM
|
#endif // FULL_SYSTEM
|
||||||
|
|
|
@ -391,6 +391,17 @@ class StaticInst : public StaticInstBase
|
||||||
/// @retval A pointer to the corresponding StaticInst object.
|
/// @retval A pointer to the corresponding StaticInst object.
|
||||||
//This is defined as inline below.
|
//This is defined as inline below.
|
||||||
static StaticInstPtr decode(ExtMachInst mach_inst);
|
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;
|
typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
|
||||||
|
|
Loading…
Reference in a new issue