Make disassembled x86 register indices reflect their size.

This doesn't handle high byte register accesses. It also highlights the fact that address size isn't actually being calculated, and that the size a microop uses needs to be overridable from the microassembly.

--HG--
extra : convert_revision : d495ac4f5756dc55a5f71953ff6963b3c030e6cb
This commit is contained in:
Gabe Black 2007-07-17 18:12:33 -07:00
parent 2e80f71dcd
commit e524240d68
5 changed files with 55 additions and 44 deletions

View file

@ -66,13 +66,13 @@ namespace X86ISA
std::stringstream response; std::stringstream response;
printMnemonic(response, instMnem, mnemonic); printMnemonic(response, instMnem, mnemonic);
printReg(response, data); printReg(response, data, dataSize);
response << ", "; response << ", ";
printSegment(response, segment); printSegment(response, segment);
ccprintf(response, ":[%d*", scale); ccprintf(response, ":[%d*", scale);
printReg(response, index); printReg(response, index, addressSize);
response << " + "; response << " + ";
printReg(response, base); printReg(response, base, addressSize);
ccprintf(response, " + %#x]", disp); ccprintf(response, " + %#x]", disp);
return response.str(); return response.str();
} }

View file

@ -165,11 +165,11 @@ namespace X86ISA
std::stringstream response; std::stringstream response;
printMnemonic(response, instMnem, mnemonic); printMnemonic(response, instMnem, mnemonic);
printReg(response, dest); printReg(response, dest, dataSize);
response << ", "; response << ", ";
printReg(response, src1); printReg(response, src1, dataSize);
response << ", "; response << ", ";
printReg(response, src2); printReg(response, src2, dataSize);
return response.str(); return response.str();
} }
@ -179,9 +179,9 @@ namespace X86ISA
std::stringstream response; std::stringstream response;
printMnemonic(response, instMnem, mnemonic); printMnemonic(response, instMnem, mnemonic);
printReg(response, dest); printReg(response, dest, dataSize);
response << ", "; response << ", ";
printReg(response, src1); printReg(response, src1, dataSize);
ccprintf(response, ", %#x", imm8); ccprintf(response, ", %#x", imm8);
return response.str(); return response.str();
} }

View file

@ -99,76 +99,84 @@ namespace X86ISA
} }
void void
X86StaticInst::printSrcReg(std::ostream &os, int reg) const X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
{ {
if(_numSrcRegs > reg) if(_numSrcRegs > reg)
printReg(os, _srcRegIdx[reg]); printReg(os, _srcRegIdx[reg], size);
} }
void void
X86StaticInst::printDestReg(std::ostream &os, int reg) const X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
{ {
if(_numDestRegs > reg) if(_numDestRegs > reg)
printReg(os, _destRegIdx[reg]); printReg(os, _destRegIdx[reg], size);
} }
void void
X86StaticInst::printReg(std::ostream &os, int reg) const X86StaticInst::printReg(std::ostream &os, int reg, int size) const
{ {
assert(size == 1 || size == 2 || size == 4 || size == 8);
static const char * abcdFormats[9] =
{"", "%sl", "%sx", "", "e%sx", "", "", "", "r%sx"};
static const char * piFormats[9] =
{"", "%sl", "%s", "", "e%s", "", "", "", "r%s"};
static const char * longFormats[9] =
{"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
static const char * microFormats[9] =
{"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
if (reg < FP_Base_DepTag) { if (reg < FP_Base_DepTag) {
//FIXME These should print differently depending on the
//mode etc, but for now this will get the point across
switch (reg) { switch (reg) {
case INTREG_RAX: case INTREG_RAX:
ccprintf(os, "rax"); ccprintf(os, abcdFormats[size], "a");
break; break;
case INTREG_RBX: case INTREG_RBX:
ccprintf(os, "rbx"); ccprintf(os, abcdFormats[size], "b");
break; break;
case INTREG_RCX: case INTREG_RCX:
ccprintf(os, "rcx"); ccprintf(os, abcdFormats[size], "c");
break; break;
case INTREG_RDX: case INTREG_RDX:
ccprintf(os, "rdx"); ccprintf(os, abcdFormats[size], "d");
break; break;
case INTREG_RSP: case INTREG_RSP:
ccprintf(os, "rsp"); ccprintf(os, piFormats[size], "sp");
break; break;
case INTREG_RBP: case INTREG_RBP:
ccprintf(os, "rbp"); ccprintf(os, piFormats[size], "bp");
break; break;
case INTREG_RSI: case INTREG_RSI:
ccprintf(os, "rsi"); ccprintf(os, piFormats[size], "si");
break; break;
case INTREG_RDI: case INTREG_RDI:
ccprintf(os, "rdi"); ccprintf(os, piFormats[size], "di");
break; break;
case INTREG_R8W: case INTREG_R8W:
ccprintf(os, "r8"); ccprintf(os, longFormats[size], "8");
break; break;
case INTREG_R9W: case INTREG_R9W:
ccprintf(os, "r9"); ccprintf(os, longFormats[size], "9");
break; break;
case INTREG_R10W: case INTREG_R10W:
ccprintf(os, "r10"); ccprintf(os, longFormats[size], "10");
break; break;
case INTREG_R11W: case INTREG_R11W:
ccprintf(os, "r11"); ccprintf(os, longFormats[size], "11");
break; break;
case INTREG_R12W: case INTREG_R12W:
ccprintf(os, "r12"); ccprintf(os, longFormats[size], "12");
break; break;
case INTREG_R13W: case INTREG_R13W:
ccprintf(os, "r13"); ccprintf(os, longFormats[size], "13");
break; break;
case INTREG_R14W: case INTREG_R14W:
ccprintf(os, "r14"); ccprintf(os, longFormats[size], "14");
break; break;
case INTREG_R15W: case INTREG_R15W:
ccprintf(os, "r15"); ccprintf(os, longFormats[size], "15");
break; break;
default: default:
ccprintf(os, "t%d", reg - NUM_INTREGS); ccprintf(os, microFormats[size], 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

@ -85,9 +85,9 @@ namespace X86ISA
void printSegment(std::ostream &os, int segment) const; void printSegment(std::ostream &os, int segment) const;
void printReg(std::ostream &os, int reg) const; void printReg(std::ostream &os, int reg, int size) const;
void printSrcReg(std::ostream &os, int reg) const; void printSrcReg(std::ostream &os, int reg, int size) const;
void printDestReg(std::ostream &os, int reg) const; void printDestReg(std::ostream &os, int reg, int size) const;
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
{ {

View file

@ -77,6 +77,7 @@ def template MicroLimmOpDeclare {{
protected: protected:
const RegIndex dest; const RegIndex dest;
const uint64_t imm; const uint64_t imm;
const uint8_t dataSize;
void buildMe(); void buildMe();
std::string generateDisassembly(Addr pc, std::string generateDisassembly(Addr pc,
@ -86,11 +87,11 @@ def template MicroLimmOpDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _dest, uint64_t _imm); RegIndex _dest, uint64_t _imm, uint8_t _dataSize);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
RegIndex _dest, uint64_t _imm); RegIndex _dest, uint64_t _imm, uint8_t _dataSize);
%(BasicExecDeclare)s %(BasicExecDeclare)s
}; };
@ -103,7 +104,7 @@ def template MicroLimmOpDisassembly {{
std::stringstream response; std::stringstream response;
printMnemonic(response, instMnem, mnemonic); printMnemonic(response, instMnem, mnemonic);
printReg(response, dest); printReg(response, dest, dataSize);
response << ", "; response << ", ";
ccprintf(response, "%#x", imm); ccprintf(response, "%#x", imm);
return response.str(); return response.str();
@ -119,10 +120,10 @@ def template MicroLimmOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
RegIndex _dest, uint64_t _imm) : RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
%(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, %(op_class)s),
dest(_dest), imm(_imm) dest(_dest), imm(_imm), dataSize(_dataSize)
{ {
buildMe(); buildMe();
} }
@ -130,10 +131,10 @@ def template MicroLimmOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
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,
RegIndex _dest, uint64_t _imm) : RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
%(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, %(op_class)s),
dest(_dest), imm(_imm) dest(_dest), imm(_imm), dataSize(_dataSize)
{ {
buildMe(); buildMe();
} }
@ -146,14 +147,16 @@ let {{
self.mnemonic = "limm" self.mnemonic = "limm"
self.dest = dest self.dest = dest
self.imm = imm self.imm = imm
self.dataSize = "env.dataSize"
def getAllocator(self, *microFlags): def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, mnemonic allocator = '''new %(class_name)s(machInst, mnemonic
%(flags)s, %(dest)s, %(imm)s)''' % { %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
"class_name" : self.className, "class_name" : self.className,
"mnemonic" : self.mnemonic, "mnemonic" : self.mnemonic,
"flags" : self.microFlagsText(microFlags), "flags" : self.microFlagsText(microFlags),
"dest" : self.dest, "imm" : self.imm } "dest" : self.dest, "imm" : self.imm,
"dataSize" : self.dataSize}
return allocator return allocator
microopClasses["limm"] = LimmOp microopClasses["limm"] = LimmOp