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:
Gabe Black 2007-06-18 14:15:00 +00:00
parent 3ceb0a46ae
commit 6c12577937
4 changed files with 187 additions and 31 deletions

View file

@ -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);

View file

@ -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)
}}; }};

View file

@ -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)

View file

@ -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