Add in incomplete pick and merge functions which read and write pieces of registers, and fill out microcode disassembly.
--HG-- extra : convert_revision : 56332b3999a9079b1bd305ee2826abdf593367e1
This commit is contained in:
parent
3ceb0a46ae
commit
6c12577937
4 changed files with 187 additions and 31 deletions
|
@ -95,6 +95,14 @@ output header {{
|
||||||
/**
|
/**
|
||||||
* Base class for all X86 static instructions.
|
* Base class for all X86 static instructions.
|
||||||
*/
|
*/
|
||||||
|
BitUnion64(X86IntReg)
|
||||||
|
Bitfield<63,0> R;
|
||||||
|
Bitfield<31,0> E;
|
||||||
|
Bitfield<15,0> X;
|
||||||
|
Bitfield<15,8> H;
|
||||||
|
Bitfield<7, 0> L;
|
||||||
|
EndBitUnion(X86IntReg)
|
||||||
|
|
||||||
class X86StaticInst : public StaticInst
|
class X86StaticInst : public StaticInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -114,10 +122,50 @@ output header {{
|
||||||
|
|
||||||
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
|
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
|
||||||
{
|
{
|
||||||
//FIXME This needs to be significantly more sophisticated
|
X86IntReg reg;
|
||||||
|
reg = into;
|
||||||
|
//FIXME This needs to be handle high bytes as well
|
||||||
|
switch(size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
reg.L = val;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
reg.X = val;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
//XXX Check if this should be zeroed or sign extended
|
||||||
|
reg = 0;
|
||||||
|
reg.E = val;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
reg.R = val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Tried to merge with unrecognized size %d.\n", size);
|
||||||
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint64_t pick(uint64_t from, int size)
|
||||||
|
{
|
||||||
|
X86IntReg reg;
|
||||||
|
reg = from;
|
||||||
|
switch(size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return reg.L;
|
||||||
|
case 2:
|
||||||
|
return reg.E;
|
||||||
|
case 4:
|
||||||
|
return reg.X;
|
||||||
|
case 8:
|
||||||
|
return reg.R;
|
||||||
|
default:
|
||||||
|
panic("Tried to pick with unrecognized size %d.\n", size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -128,6 +176,12 @@ output decoder {{
|
||||||
ccprintf(os, "\t%s ", mnemonic);
|
ccprintf(os, "\t%s ", mnemonic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void printMnemonic(std::ostream &os,
|
||||||
|
const char * instMnemonic, const char * mnemonic)
|
||||||
|
{
|
||||||
|
ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86StaticInst::printSrcReg(std::ostream &os, int reg) const
|
X86StaticInst::printSrcReg(std::ostream &os, int reg) const
|
||||||
{
|
{
|
||||||
|
@ -197,6 +251,8 @@ output decoder {{
|
||||||
case INTREG_R15W:
|
case INTREG_R15W:
|
||||||
ccprintf(os, "r15");
|
ccprintf(os, "r15");
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
ccprintf(os, "t%d", reg - NUM_INTREGS);
|
||||||
}
|
}
|
||||||
} else if (reg < Ctrl_Base_DepTag) {
|
} else if (reg < Ctrl_Base_DepTag) {
|
||||||
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
|
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
|
||||||
|
|
|
@ -79,6 +79,9 @@ def template MicroLimmOpDeclare {{
|
||||||
const uint64_t imm;
|
const uint64_t imm;
|
||||||
void buildMe();
|
void buildMe();
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
%(class_name)s(ExtMachInst _machInst,
|
%(class_name)s(ExtMachInst _machInst,
|
||||||
const char * instMnem,
|
const char * instMnem,
|
||||||
|
@ -93,6 +96,20 @@ def template MicroLimmOpDeclare {{
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
def template MicroLimmOpDisassembly {{
|
||||||
|
std::string %(class_name)s::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream response;
|
||||||
|
|
||||||
|
printMnemonic(response, instMnem, mnemonic);
|
||||||
|
printReg(response, dest);
|
||||||
|
response << ", ";
|
||||||
|
ccprintf(response, "%#x", imm);
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
def template MicroLimmOpConstructor {{
|
def template MicroLimmOpConstructor {{
|
||||||
|
|
||||||
inline void %(class_name)s::buildMe()
|
inline void %(class_name)s::buildMe()
|
||||||
|
@ -148,5 +165,6 @@ let {{
|
||||||
{"code" : "DestReg = imm;"})
|
{"code" : "DestReg = imm;"})
|
||||||
header_output += MicroLimmOpDeclare.subst(iop)
|
header_output += MicroLimmOpDeclare.subst(iop)
|
||||||
decoder_output += MicroLimmOpConstructor.subst(iop)
|
decoder_output += MicroLimmOpConstructor.subst(iop)
|
||||||
|
decoder_output += MicroLimmOpDisassembly.subst(iop)
|
||||||
exec_output += MicroLimmOpExecute.subst(iop)
|
exec_output += MicroLimmOpExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -59,6 +59,100 @@
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
output header {{
|
||||||
|
/**
|
||||||
|
* Base classes for RegOps which provides a generateDisassembly method.
|
||||||
|
*/
|
||||||
|
class RegOp : public X86MicroopBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const RegIndex src1;
|
||||||
|
const RegIndex src2;
|
||||||
|
const RegIndex dest;
|
||||||
|
const bool setStatus;
|
||||||
|
const uint8_t dataSize;
|
||||||
|
const uint8_t ext;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
RegOp(ExtMachInst _machInst,
|
||||||
|
const char *mnem, const char *_instMnem,
|
||||||
|
bool isMicro, bool isDelayed,
|
||||||
|
bool isFirst, bool isLast,
|
||||||
|
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||||
|
bool _setStatus, uint8_t _dataSize, uint8_t _ext,
|
||||||
|
OpClass __opClass) :
|
||||||
|
X86MicroopBase(_machInst, mnem, _instMnem,
|
||||||
|
isMicro, isDelayed, isFirst, isLast,
|
||||||
|
__opClass),
|
||||||
|
src1(_src1), src2(_src2), dest(_dest),
|
||||||
|
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RegOpImm : public X86MicroopBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const RegIndex src1;
|
||||||
|
const uint8_t imm8;
|
||||||
|
const RegIndex dest;
|
||||||
|
const bool setStatus;
|
||||||
|
const uint8_t dataSize;
|
||||||
|
const uint8_t ext;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
RegOpImm(ExtMachInst _machInst,
|
||||||
|
const char * mnem, const char *_instMnem,
|
||||||
|
bool isMicro, bool isDelayed,
|
||||||
|
bool isFirst, bool isLast,
|
||||||
|
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||||
|
bool _setStatus, uint8_t _dataSize, uint8_t _ext,
|
||||||
|
OpClass __opClass) :
|
||||||
|
X86MicroopBase(_machInst, mnem, _instMnem,
|
||||||
|
isMicro, isDelayed, isFirst, isLast,
|
||||||
|
__opClass),
|
||||||
|
src1(_src1), imm8(_imm8), dest(_dest),
|
||||||
|
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
|
||||||
|
output decoder {{
|
||||||
|
std::string RegOp::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream response;
|
||||||
|
|
||||||
|
printMnemonic(response, instMnem, mnemonic);
|
||||||
|
printReg(response, dest);
|
||||||
|
response << ", ";
|
||||||
|
printReg(response, src1);
|
||||||
|
response << ", ";
|
||||||
|
printReg(response, src2);
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RegOpImm::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream response;
|
||||||
|
|
||||||
|
printMnemonic(response, instMnem, mnemonic);
|
||||||
|
printReg(response, dest);
|
||||||
|
response << ", ";
|
||||||
|
printReg(response, src1);
|
||||||
|
ccprintf(response, ", %#x", imm8);
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
def template MicroRegOpExecute {{
|
def template MicroRegOpExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
|
@ -101,12 +195,6 @@ def template MicroRegOpDeclare {{
|
||||||
class %(class_name)s : public %(base_class)s
|
class %(class_name)s : public %(base_class)s
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const RegIndex src1;
|
|
||||||
const RegIndex src2;
|
|
||||||
const RegIndex dest;
|
|
||||||
const bool setStatus;
|
|
||||||
const uint8_t dataSize;
|
|
||||||
const uint8_t ext;
|
|
||||||
void buildMe();
|
void buildMe();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -130,12 +218,6 @@ def template MicroRegOpImmDeclare {{
|
||||||
class %(class_name)sImm : public %(base_class)s
|
class %(class_name)sImm : public %(base_class)s
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const RegIndex src1;
|
|
||||||
const uint8_t imm8;
|
|
||||||
const RegIndex dest;
|
|
||||||
const bool setStatus;
|
|
||||||
const uint8_t dataSize;
|
|
||||||
const uint8_t ext;
|
|
||||||
void buildMe();
|
void buildMe();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -166,9 +248,9 @@ def template MicroRegOpConstructor {{
|
||||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||||
%(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,
|
||||||
src1(_src1), src2(_src2), dest(_dest),
|
_src1, _src2, _dest, _setStatus, _dataSize, _ext,
|
||||||
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
%(op_class)s)
|
||||||
{
|
{
|
||||||
buildMe();
|
buildMe();
|
||||||
}
|
}
|
||||||
|
@ -179,9 +261,9 @@ def template MicroRegOpConstructor {{
|
||||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||||
%(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,
|
||||||
src1(_src1), src2(_src2), dest(_dest),
|
_src1, _src2, _dest, _setStatus, _dataSize, _ext,
|
||||||
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
%(op_class)s)
|
||||||
{
|
{
|
||||||
buildMe();
|
buildMe();
|
||||||
}
|
}
|
||||||
|
@ -199,9 +281,9 @@ def template MicroRegOpImmConstructor {{
|
||||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||||
%(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,
|
||||||
src1(_src1), imm8(_imm8), dest(_dest),
|
_src1, _imm8, _dest, _setStatus, _dataSize, _ext,
|
||||||
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
%(op_class)s)
|
||||||
{
|
{
|
||||||
buildMe();
|
buildMe();
|
||||||
}
|
}
|
||||||
|
@ -212,9 +294,9 @@ def template MicroRegOpImmConstructor {{
|
||||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||||
%(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,
|
||||||
src1(_src1), imm8(_imm8), dest(_dest),
|
_src1, _imm8, _dest, _setStatus, _dataSize, _ext,
|
||||||
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
%(op_class)s)
|
||||||
{
|
{
|
||||||
buildMe();
|
buildMe();
|
||||||
}
|
}
|
||||||
|
@ -227,7 +309,7 @@ let {{
|
||||||
self.src1 = src1
|
self.src1 = src1
|
||||||
self.src2 = src2
|
self.src2 = src2
|
||||||
self.setStatus = False
|
self.setStatus = False
|
||||||
self.dataSize = 1
|
self.dataSize = "env.dataSize"
|
||||||
self.ext = 0
|
self.ext = 0
|
||||||
|
|
||||||
def getAllocator(self, *microFlags):
|
def getAllocator(self, *microFlags):
|
||||||
|
@ -249,7 +331,7 @@ let {{
|
||||||
self.src1 = src1
|
self.src1 = src1
|
||||||
self.imm8 = imm8
|
self.imm8 = imm8
|
||||||
self.setStatus = False
|
self.setStatus = False
|
||||||
self.dataSize = 1
|
self.dataSize = "env.dataSize"
|
||||||
self.ext = 0
|
self.ext = 0
|
||||||
|
|
||||||
def getAllocator(self, *microFlags):
|
def getAllocator(self, *microFlags):
|
||||||
|
@ -290,7 +372,7 @@ let {{
|
||||||
immCode = matcher.sub("imm8", code)
|
immCode = matcher.sub("imm8", code)
|
||||||
|
|
||||||
# Build up the all register version of this micro op
|
# Build up the all register version of this micro op
|
||||||
iop = InstObjParams(name, Name, 'X86MicroopBase', {"code" : regCode})
|
iop = InstObjParams(name, Name, 'RegOp', {"code" : regCode})
|
||||||
header_output += MicroRegOpDeclare.subst(iop)
|
header_output += MicroRegOpDeclare.subst(iop)
|
||||||
decoder_output += MicroRegOpConstructor.subst(iop)
|
decoder_output += MicroRegOpConstructor.subst(iop)
|
||||||
exec_output += MicroRegOpExecute.subst(iop)
|
exec_output += MicroRegOpExecute.subst(iop)
|
||||||
|
@ -305,7 +387,7 @@ let {{
|
||||||
|
|
||||||
# Build up the immediate version of this micro op
|
# Build up the immediate version of this micro op
|
||||||
iop = InstObjParams(name + "i", Name,
|
iop = InstObjParams(name + "i", Name,
|
||||||
'X86MicroopBase', {"code" : immCode})
|
'RegOpImm', {"code" : immCode})
|
||||||
header_output += MicroRegOpImmDeclare.subst(iop)
|
header_output += MicroRegOpImmDeclare.subst(iop)
|
||||||
decoder_output += MicroRegOpImmConstructor.subst(iop)
|
decoder_output += MicroRegOpImmConstructor.subst(iop)
|
||||||
exec_output += MicroRegOpImmExecute.subst(iop)
|
exec_output += MicroRegOpImmExecute.subst(iop)
|
||||||
|
|
|
@ -81,8 +81,8 @@ namespace X86ISA
|
||||||
|
|
||||||
// These enumerate all the registers for dependence tracking.
|
// These enumerate all the registers for dependence tracking.
|
||||||
enum DependenceTags {
|
enum DependenceTags {
|
||||||
//The number of microcode registers needs to be added to this
|
//There are 16 microcode registers at the moment
|
||||||
FP_Base_DepTag = 16,
|
FP_Base_DepTag = 32,
|
||||||
Ctrl_Base_DepTag =
|
Ctrl_Base_DepTag =
|
||||||
FP_Base_DepTag +
|
FP_Base_DepTag +
|
||||||
//mmx/x87 registers
|
//mmx/x87 registers
|
||||||
|
|
Loading…
Reference in a new issue