Get rid of the immediate and displacement components of the EmulEnv struct and use them directly out of the instruction. The extra copies are conceptually realistic but are just innefficient as implemented. Also don't use the zeroeth microcode register for general storage since it's now the zero register, and implement a load and a store microops.
--HG-- extra : convert_revision : 0686296ca8b72940d961ecc6051063bfda1e932d
This commit is contained in:
parent
8caef7d25a
commit
6e286cddfa
9 changed files with 349 additions and 46 deletions
|
@ -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