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
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 §ion)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
@ -162,16 +164,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 §ion);
|
||||
|
||||
};
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
// cop-0/cop-1 system control register file
|
||||
typedef uint64_t MiscReg;
|
||||
|
@ -524,18 +588,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
|
||||
|
|
|
@ -42,7 +42,7 @@ createProcess(const string &nm, ObjectFile * objFile, System * system,
|
|||
vector<string> &argv, vector<string> &envp)
|
||||
{
|
||||
LiveProcess * process = NULL;
|
||||
if (objFile->getArch() != ObjectFile::MIPS)
|
||||
if (objFile->getArch() != ObjectFile::Mips)
|
||||
fatal("Object file does not match architecture.");
|
||||
switch (objFile->getOpSys()) {
|
||||
case ObjectFile::Linux:
|
||||
|
|
|
@ -92,7 +92,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 {
|
||||
|
@ -156,14 +156,49 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
|
|||
section = elf_getscn(elf, ++secIdx);
|
||||
} // 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);
|
||||
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,
|
||||
size_t _len, uint8_t *_data,
|
||||
size_t _len, uint8_t *_data,Addr global_ptr,
|
||||
Arch _arch, OpSys _opSys)
|
||||
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
||||
|
||||
|
@ -187,6 +222,8 @@ ElfObject::ElfObject(const string &_filename, int _fd,
|
|||
|
||||
entry = ehdr.e_entry;
|
||||
|
||||
globalPtr = global_ptr;
|
||||
|
||||
// initialize segment sizes to 0 in case they're not present
|
||||
text.size = data.size = bss.size = 0;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class ElfObject : public ObjectFile
|
|||
bool loadSomeSymbols(SymbolTable *symtab, int binding);
|
||||
|
||||
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);
|
||||
|
||||
public:
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -142,6 +142,7 @@ baseFlags = [
|
|||
'OoOCPU',
|
||||
'HWPrefetch',
|
||||
'Stack',
|
||||
'SimpleCPU',
|
||||
]
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue