Merge zizzer.eecs.umich.edu:/bk/newmem
into ahchoo.blinky.homelinux.org:/home/gblack/m5/newmem-x86 --HG-- extra : convert_revision : 2dfc24b0720b3b378858a289e4bb6f4ee7132b3d
This commit is contained in:
commit
053c715f21
11 changed files with 381 additions and 46 deletions
|
@ -182,6 +182,33 @@ output decoder {{
|
||||||
ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
|
ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printSegment(std::ostream &os, int segment)
|
||||||
|
{
|
||||||
|
switch (segment)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ccprintf(os, "ES");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ccprintf(os, "CS");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ccprintf(os, "SS");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ccprintf(os, "DS");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ccprintf(os, "FS");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ccprintf(os, "GS");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Unrecognized segment %d\n", segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86StaticInst::printSrcReg(std::ostream &os, int reg) const
|
X86StaticInst::printSrcReg(std::ostream &os, int reg) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,3 +100,8 @@ def bitfield SIB_BASE sib.base;
|
||||||
|
|
||||||
def bitfield OPSIZE opSize;
|
def bitfield OPSIZE opSize;
|
||||||
def bitfield ADDRSIZE addrSize;
|
def bitfield ADDRSIZE addrSize;
|
||||||
|
def bitfield STACKSIZE stackSize;
|
||||||
|
|
||||||
|
def bitfield MODE mode;
|
||||||
|
def bitfield MODE_MODE mode.mode;
|
||||||
|
def bitfield MODE_SUBMODE mode.submode;
|
||||||
|
|
|
@ -67,11 +67,11 @@ def macroop MOV_R_M {
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop MOV_R_I {
|
def macroop MOV_R_I {
|
||||||
limm "env.reg", "env.immediate"
|
limm "env.reg", "IMMEDIATE"
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop MOV_M_I {
|
def macroop MOV_M_I {
|
||||||
limm "env.reg", "env.immediate"
|
limm "env.reg", "IMMEDIATE"
|
||||||
#Do a store to put the register operand into memory
|
#Do a store to put the register operand into memory
|
||||||
};
|
};
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -55,15 +55,21 @@
|
||||||
|
|
||||||
microcode = '''
|
microcode = '''
|
||||||
def macroop POP_R {
|
def macroop POP_R {
|
||||||
|
|
||||||
|
# Make the default data size of pops 64 bits in 64 bit mode
|
||||||
.adjust_env "if(machInst.mode.submode == SixtyFourBitMode && env.dataSize == 4) env.dataSize = 8\;"
|
.adjust_env "if(machInst.mode.submode == SixtyFourBitMode && env.dataSize == 4) env.dataSize = 8\;"
|
||||||
# There needs to be a load here to actually "pop" the data
|
|
||||||
|
ld "env.reg", 2, [0, "NUM_INTREGS", "INTREG_RSP"]
|
||||||
addi "INTREG_RSP", "INTREG_RSP", "env.dataSize"
|
addi "INTREG_RSP", "INTREG_RSP", "env.dataSize"
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop PUSH_R {
|
def macroop PUSH_R {
|
||||||
|
|
||||||
|
# Make the default data size of pops 64 bits in 64 bit mode
|
||||||
.adjust_env "if(machInst.mode.submode == SixtyFourBitMode && env.dataSize == 4) env.dataSize = 8\;"
|
.adjust_env "if(machInst.mode.submode == SixtyFourBitMode && env.dataSize == 4) env.dataSize = 8\;"
|
||||||
|
|
||||||
subi "INTREG_RSP", "INTREG_RSP", "env.dataSize"
|
subi "INTREG_RSP", "INTREG_RSP", "env.dataSize"
|
||||||
# There needs to be a store here to actually "push" the data
|
st "env.reg", 2, [0, "NUM_INTREGS", "INTREG_RSP"]
|
||||||
};
|
};
|
||||||
'''
|
'''
|
||||||
#let {{
|
#let {{
|
||||||
|
|
|
@ -61,34 +61,34 @@ def macroop XOR_R_R
|
||||||
|
|
||||||
def macroop XOR_R_I
|
def macroop XOR_R_I
|
||||||
{
|
{
|
||||||
limm "NUM_INTREGS", "env.immediate"
|
limm "NUM_INTREGS+1", "IMMEDIATE"
|
||||||
xor "env.reg", "env.reg", "NUM_INTREGS"
|
xor "env.reg", "env.reg", "NUM_INTREGS+1"
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop XOR_M_R
|
def macroop XOR_M_R
|
||||||
{
|
{
|
||||||
#Do a load to get one of the sources
|
#Do a load to get one of the sources
|
||||||
xor "NUM_INTREGS", "NUM_INTREGS", "env.reg"
|
xor "NUM_INTREGS+1", "NUM_INTREGS+1", "env.reg"
|
||||||
#Do a store to write the destination
|
#Do a store to write the destination
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop XOR_R_M
|
def macroop XOR_R_M
|
||||||
{
|
{
|
||||||
#Do a load to get one of the sources
|
#Do a load to get one of the sources
|
||||||
xor "env.reg", "env.reg", "NUM_INTREGS"
|
xor "env.reg", "env.reg", "NUM_INTREGS+1"
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop AND_R_I
|
def macroop AND_R_I
|
||||||
{
|
{
|
||||||
limm "NUM_INTREGS", "env.immediate"
|
limm "NUM_INTREGS+1", "IMMEDIATE"
|
||||||
and "env.reg", "env.reg", "NUM_INTREGS"
|
and "env.reg", "env.reg", "NUM_INTREGS+1"
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop AND_M_I
|
def macroop AND_M_I
|
||||||
{
|
{
|
||||||
#Do a load to get one of the sources
|
#Do a load to get one of the sources
|
||||||
limm "NUM_INTREGS", "env.immediate"
|
limm "NUM_INTREGS+1", "IMMEDIATE"
|
||||||
and "NUM_INTREGS", "NUM_INTREGS", "NUM_INTREGS+1"
|
and "NUM_INTREGS+1", "NUM_INTREGS+1", "NUM_INTREGS+2"
|
||||||
#Do a store to write the destination
|
#Do a store to write the destination
|
||||||
};
|
};
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -189,17 +189,18 @@ output header {{
|
||||||
{
|
{
|
||||||
X86ISA::RegIndex reg;
|
X86ISA::RegIndex reg;
|
||||||
X86ISA::RegIndex regm;
|
X86ISA::RegIndex regm;
|
||||||
uint64_t immediate;
|
uint8_t scale;
|
||||||
uint64_t displacement;
|
X86ISA::RegIndex index;
|
||||||
int addressSize;
|
X86ISA::RegIndex base;
|
||||||
int dataSize;
|
int dataSize;
|
||||||
|
int addressSize;
|
||||||
|
int stackSize;
|
||||||
|
|
||||||
EmulEnv(X86ISA::RegIndex _reg, X86ISA::RegIndex _regm,
|
EmulEnv(X86ISA::RegIndex _reg, X86ISA::RegIndex _regm,
|
||||||
uint64_t _immediate, uint64_t _displacement,
|
int _dataSize, int _addressSize, int _stackSize) :
|
||||||
int _addressSize, int _dataSize) :
|
|
||||||
reg(_reg), regm(_regm),
|
reg(_reg), regm(_regm),
|
||||||
immediate(_immediate), displacement(_displacement),
|
dataSize(_dataSize), addressSize(_addressSize),
|
||||||
addressSize(_addressSize), dataSize(_dataSize)
|
stackSize(_stackSize)
|
||||||
{;}
|
{;}
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
@ -211,17 +212,15 @@ let {{
|
||||||
self.regUsed = False
|
self.regUsed = False
|
||||||
self.regm = "0"
|
self.regm = "0"
|
||||||
self.regmUsed = False
|
self.regmUsed = False
|
||||||
self.immediate = "IMMEDIATE"
|
|
||||||
self.displacement = "DISPLACEMENT"
|
|
||||||
self.addressSize = "ADDRSIZE"
|
self.addressSize = "ADDRSIZE"
|
||||||
self.dataSize = "OPSIZE"
|
self.dataSize = "OPSIZE"
|
||||||
|
self.stackSize = "STACKSIZE"
|
||||||
def getAllocator(self):
|
def getAllocator(self):
|
||||||
return '''EmulEnv(%(reg)s,
|
return '''EmulEnv(%(reg)s,
|
||||||
%(regm)s,
|
%(regm)s,
|
||||||
%(immediate)s,
|
%(dataSize)s,
|
||||||
%(displacement)s,
|
|
||||||
%(addressSize)s,
|
%(addressSize)s,
|
||||||
%(dataSize)s)''' % \
|
%(stackSize)s)''' % \
|
||||||
self.__dict__
|
self.__dict__
|
||||||
def addReg(self, reg):
|
def addReg(self, reg):
|
||||||
if not self.regUsed:
|
if not self.regUsed:
|
||||||
|
|
|
@ -59,8 +59,14 @@
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
def template MicroLdStOpDeclare {{
|
|
||||||
class %(class_name)s : public X86MicroopBase
|
// Load templates
|
||||||
|
|
||||||
|
output header {{
|
||||||
|
/**
|
||||||
|
* Base class for load and store ops
|
||||||
|
*/
|
||||||
|
class LdStOp : public X86MicroopBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const uint8_t scale;
|
const uint8_t scale;
|
||||||
|
@ -71,6 +77,195 @@ def template MicroLdStOpDeclare {{
|
||||||
const RegIndex data;
|
const RegIndex data;
|
||||||
const uint8_t dataSize;
|
const uint8_t dataSize;
|
||||||
const uint8_t addressSize;
|
const uint8_t addressSize;
|
||||||
|
|
||||||
|
//Constructor
|
||||||
|
LdStOp(ExtMachInst _machInst,
|
||||||
|
const char * mnem, const char * _instMnem,
|
||||||
|
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||||
|
uint8_t _scale, RegIndex _index, RegIndex _base,
|
||||||
|
uint64_t _disp, uint8_t _segment,
|
||||||
|
RegIndex _data,
|
||||||
|
uint8_t _dataSize, uint8_t _addressSize,
|
||||||
|
OpClass __opClass) :
|
||||||
|
X86MicroopBase(machInst, mnem, _instMnem,
|
||||||
|
isMicro, isDelayed, isFirst, isLast, __opClass),
|
||||||
|
scale(_scale), index(_index), base(_base),
|
||||||
|
disp(_disp), segment(_segment),
|
||||||
|
data(_data),
|
||||||
|
dataSize(_dataSize), addressSize(_addressSize)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
|
||||||
|
output decoder {{
|
||||||
|
std::string LdStOp::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream response;
|
||||||
|
|
||||||
|
printMnemonic(response, instMnem, mnemonic);
|
||||||
|
printReg(response, data);
|
||||||
|
response << ", ";
|
||||||
|
printSegment(response, segment);
|
||||||
|
ccprintf(response, ":[%d*", scale);
|
||||||
|
printReg(response, index);
|
||||||
|
response << " + ";
|
||||||
|
printReg(response, base);
|
||||||
|
ccprintf(response, " + %#x]", disp);
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MicroLoadExecute {{
|
||||||
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
|
Trace::InstRecord *traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
Addr EA;
|
||||||
|
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||||
|
|
||||||
|
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
%(code)s;
|
||||||
|
}
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MicroLoadInitiateAcc {{
|
||||||
|
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
Addr EA;
|
||||||
|
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||||
|
|
||||||
|
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
|
||||||
|
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MicroLoadCompleteAcc {{
|
||||||
|
Fault %(class_name)s::completeAcc(PacketPtr pkt,
|
||||||
|
%(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
|
||||||
|
Mem = pkt->get<typeof(Mem)>();
|
||||||
|
%(code)s;
|
||||||
|
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
// Store templates
|
||||||
|
|
||||||
|
def template MicroStoreExecute {{
|
||||||
|
Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord *traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
|
||||||
|
Addr EA;
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||||
|
|
||||||
|
%(code)s;
|
||||||
|
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||||
|
EA, 0, 0);
|
||||||
|
}
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MicroStoreInitiateAcc {{
|
||||||
|
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
|
||||||
|
Addr EA;
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||||
|
|
||||||
|
%(code)s;
|
||||||
|
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||||
|
EA, 0, 0);
|
||||||
|
}
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MicroStoreCompleteAcc {{
|
||||||
|
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
return NoFault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
// Common templates
|
||||||
|
|
||||||
|
//This delcares the initiateAcc function in memory operations
|
||||||
|
def template InitiateAccDeclare {{
|
||||||
|
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||||
|
}};
|
||||||
|
|
||||||
|
//This declares the completeAcc function in memory operations
|
||||||
|
def template CompleteAccDeclare {{
|
||||||
|
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MicroLdStOpDeclare {{
|
||||||
|
class %(class_name)s : public %(base_class)s
|
||||||
|
{
|
||||||
|
protected:
|
||||||
void buildMe();
|
void buildMe();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -90,6 +285,10 @@ def template MicroLdStOpDeclare {{
|
||||||
uint8_t _dataSize, uint8_t _addressSize);
|
uint8_t _dataSize, uint8_t _addressSize);
|
||||||
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
|
|
||||||
|
%(InitiateAccDeclare)s
|
||||||
|
|
||||||
|
%(CompleteAccDeclare)s
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -107,11 +306,10 @@ def template MicroLdStOpConstructor {{
|
||||||
RegIndex _data,
|
RegIndex _data,
|
||||||
uint8_t _dataSize, uint8_t _addressSize) :
|
uint8_t _dataSize, uint8_t _addressSize) :
|
||||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||||
false, false, false, false, %(op_class)s),
|
false, false, false, false,
|
||||||
scale(_scale), index(_index), base(_base),
|
_scale, _index, _base,
|
||||||
disp(_disp), segment(_segment),
|
_disp, _segment, _data,
|
||||||
data(_data),
|
_dataSize, _addressSize, %(op_class)s)
|
||||||
dataSize(_dataSize), addressSize(_addressSize)
|
|
||||||
{
|
{
|
||||||
buildMe();
|
buildMe();
|
||||||
}
|
}
|
||||||
|
@ -120,17 +318,106 @@ def template MicroLdStOpConstructor {{
|
||||||
ExtMachInst machInst, const char * instMnem,
|
ExtMachInst machInst, const char * instMnem,
|
||||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||||
uint8_t _scale, RegIndex _index, RegIndex _base,
|
uint8_t _scale, RegIndex _index, RegIndex _base,
|
||||||
uint64_t _disp, uint8_t segment,
|
uint64_t _disp, uint8_t _segment,
|
||||||
RegIndex data,
|
RegIndex _data,
|
||||||
uint8_t dataSize, uint8_t addressSize) :
|
uint8_t _dataSize, uint8_t _addressSize) :
|
||||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||||
isMicro, isDelayed, isFirst, isLast, %(op_class)s),
|
isMicro, isDelayed, isFirst, isLast,
|
||||||
scale(_scale), index(_index), base(_base),
|
_scale, _index, _base,
|
||||||
disp(_disp), segment(_segment),
|
_disp, _segment, _data,
|
||||||
data(_data),
|
_dataSize, _addressSize, %(op_class)s)
|
||||||
dataSize(_dataSize), addressSize(_addressSize)
|
|
||||||
{
|
{
|
||||||
buildMe();
|
buildMe();
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
let {{
|
||||||
|
class LdStOp(X86Microop):
|
||||||
|
def __init__(self, data, segment, addr, disp):
|
||||||
|
self.data = data
|
||||||
|
[self.scale, self.index, self.base] = addr
|
||||||
|
self.disp = disp
|
||||||
|
self.segment = segment
|
||||||
|
self.dataSize = "env.dataSize"
|
||||||
|
self.addressSize = "env.addressSize"
|
||||||
|
|
||||||
|
def getAllocator(self, *microFlags):
|
||||||
|
allocator = '''new %(class_name)s(machInst, mnemonic
|
||||||
|
%(flags)s, %(scale)s, %(index)s, %(base)s,
|
||||||
|
%(disp)s, %(segment)s, %(data)s,
|
||||||
|
%(dataSize)s, %(addressSize)s)''' % {
|
||||||
|
"class_name" : self.className,
|
||||||
|
"flags" : self.microFlagsText(microFlags),
|
||||||
|
"scale" : self.scale, "index" : self.index,
|
||||||
|
"base" : self.base,
|
||||||
|
"disp" : self.disp,
|
||||||
|
"segment" : self.segment, "data" : self.data,
|
||||||
|
"dataSize" : self.dataSize, "addressSize" : self.addressSize}
|
||||||
|
return allocator
|
||||||
|
}};
|
||||||
|
|
||||||
|
let {{
|
||||||
|
|
||||||
|
# Make these empty strings so that concatenating onto
|
||||||
|
# them will always work.
|
||||||
|
header_output = ""
|
||||||
|
decoder_output = ""
|
||||||
|
exec_output = ""
|
||||||
|
|
||||||
|
calculateEA = "EA = scale * Index + Base + disp;"
|
||||||
|
|
||||||
|
def defineMicroLoadOp(mnemonic, code):
|
||||||
|
global header_output
|
||||||
|
global decoder_output
|
||||||
|
global exec_output
|
||||||
|
global microopClasses
|
||||||
|
Name = mnemonic
|
||||||
|
name = mnemonic.lower()
|
||||||
|
|
||||||
|
# Build up the all register version of this micro op
|
||||||
|
iop = InstObjParams(name, Name, 'LdStOp',
|
||||||
|
{"code": code, "ea_code": calculateEA})
|
||||||
|
header_output += MicroLdStOpDeclare.subst(iop)
|
||||||
|
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||||
|
exec_output += MicroLoadExecute.subst(iop)
|
||||||
|
exec_output += MicroLoadInitiateAcc.subst(iop)
|
||||||
|
exec_output += MicroLoadCompleteAcc.subst(iop)
|
||||||
|
|
||||||
|
class LoadOp(LdStOp):
|
||||||
|
def __init__(self, data, segment, addr, disp = 0):
|
||||||
|
super(LoadOp, self).__init__(data, segment, addr, disp)
|
||||||
|
self.className = Name
|
||||||
|
self.mnemonic = name
|
||||||
|
|
||||||
|
microopClasses[name] = LoadOp
|
||||||
|
|
||||||
|
defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
|
||||||
|
|
||||||
|
def defineMicroStoreOp(mnemonic, code):
|
||||||
|
global header_output
|
||||||
|
global decoder_output
|
||||||
|
global exec_output
|
||||||
|
global microopClasses
|
||||||
|
Name = mnemonic
|
||||||
|
name = mnemonic.lower()
|
||||||
|
|
||||||
|
# Build up the all register version of this micro op
|
||||||
|
iop = InstObjParams(name, Name, 'LdStOp',
|
||||||
|
{"code": code, "ea_code": calculateEA})
|
||||||
|
header_output += MicroLdStOpDeclare.subst(iop)
|
||||||
|
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||||
|
exec_output += MicroStoreExecute.subst(iop)
|
||||||
|
exec_output += MicroStoreInitiateAcc.subst(iop)
|
||||||
|
exec_output += MicroStoreCompleteAcc.subst(iop)
|
||||||
|
|
||||||
|
class StoreOp(LdStOp):
|
||||||
|
def __init__(self, data, addr, segment):
|
||||||
|
super(LoadOp, self).__init__(data, addr, segment)
|
||||||
|
self.className = Name
|
||||||
|
self.mnemonic = name
|
||||||
|
|
||||||
|
microopClasses[name] = StoreOp
|
||||||
|
|
||||||
|
defineMicroLoadOp('St', 'Mem = Data;')
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,9 @@ def operands {{
|
||||||
'DestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 1),
|
'DestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 1),
|
||||||
'SrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 2),
|
'SrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 2),
|
||||||
'SrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 3),
|
'SrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 3),
|
||||||
'IntRegOp0': ('IntReg', 'udw', 'param0', 'IsInteger', 1),
|
'Base': ('IntReg', 'uqw', 'base', 'IsInteger', 4),
|
||||||
'IntRegOp1': ('IntReg', 'udw', 'param1', 'IsInteger', 2),
|
'Index': ('IntReg', 'uqw', 'index', 'IsInteger', 5),
|
||||||
'IntRegOp2': ('IntReg', 'udw', 'param2', 'IsInteger', 2),
|
'Data': ('IntReg', 'uqw', 'data', 'IsInteger', 6),
|
||||||
|
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10),
|
||||||
|
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace X86ISA
|
||||||
|
|
||||||
// semantically meaningful register indices
|
// semantically meaningful register indices
|
||||||
//There is no such register in X86
|
//There is no such register in X86
|
||||||
const int ZeroReg = 0;
|
const int ZeroReg = NUM_INTREGS;
|
||||||
const int StackPointerReg = INTREG_RSP;
|
const int StackPointerReg = INTREG_RSP;
|
||||||
//X86 doesn't seem to have a link register
|
//X86 doesn't seem to have a link register
|
||||||
const int ReturnAddressReg = 0;
|
const int ReturnAddressReg = 0;
|
||||||
|
|
|
@ -169,6 +169,8 @@ namespace X86ISA
|
||||||
uint8_t opSize;
|
uint8_t opSize;
|
||||||
//The effective address size.
|
//The effective address size.
|
||||||
uint8_t addrSize;
|
uint8_t addrSize;
|
||||||
|
//The effective stack size.
|
||||||
|
uint8_t stackSize;
|
||||||
|
|
||||||
//Mode information
|
//Mode information
|
||||||
OperatingMode mode;
|
OperatingMode mode;
|
||||||
|
@ -193,8 +195,6 @@ namespace X86ISA
|
||||||
inline static bool
|
inline static bool
|
||||||
operator == (const ExtMachInst &emi1, const ExtMachInst &emi2)
|
operator == (const ExtMachInst &emi1, const ExtMachInst &emi2)
|
||||||
{
|
{
|
||||||
if(emi1.mode != emi2.mode)
|
|
||||||
return false;
|
|
||||||
if(emi1.legacy != emi2.legacy)
|
if(emi1.legacy != emi2.legacy)
|
||||||
return false;
|
return false;
|
||||||
if(emi1.rex != emi2.rex)
|
if(emi1.rex != emi2.rex)
|
||||||
|
@ -215,6 +215,14 @@ namespace X86ISA
|
||||||
return false;
|
return false;
|
||||||
if(emi1.displacement != emi2.displacement)
|
if(emi1.displacement != emi2.displacement)
|
||||||
return false;
|
return false;
|
||||||
|
if(emi1.mode != emi2.mode)
|
||||||
|
return false;
|
||||||
|
if(emi1.opSize != emi2.opSize)
|
||||||
|
return false;
|
||||||
|
if(emi1.addrSize != emi2.addrSize)
|
||||||
|
return false;
|
||||||
|
if(emi1.stackSize != emi2.stackSize)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,8 @@ namespace __hash_namespace {
|
||||||
((uint64_t)emi.opcode.prefixB << 8) |
|
((uint64_t)emi.opcode.prefixB << 8) |
|
||||||
((uint64_t)emi.opcode.op)) ^
|
((uint64_t)emi.opcode.op)) ^
|
||||||
emi.immediate ^ emi.displacement ^
|
emi.immediate ^ emi.displacement ^
|
||||||
emi.mode ^ emi.opSize;
|
emi.mode ^
|
||||||
|
emi.opSize ^ emi.addrSize ^ emi.stackSize;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue