*/
#include "arch/x86/insts/static_inst.hh"
+#include "arch/x86/segmentregs.hh"
namespace X86ISA
{
void X86StaticInst::printMnemonic(std::ostream &os,
const char * mnemonic) const
{
- ccprintf(os, "\t%s ", mnemonic);
+ ccprintf(os, " %s ", mnemonic);
}
void X86StaticInst::printMnemonic(std::ostream &os,
const char * instMnemonic, const char * mnemonic) const
{
- ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
+ ccprintf(os, " %s : %s ", instMnemonic, mnemonic);
}
void X86StaticInst::printSegment(std::ostream &os, int segment) const
{
switch (segment)
{
- case 0:
+ case SEGMENT_REG_ES:
ccprintf(os, "ES");
break;
- case 1:
+ case SEGMENT_REG_CS:
ccprintf(os, "CS");
break;
- case 2:
+ case SEGMENT_REG_SS:
ccprintf(os, "SS");
break;
- case 3:
+ case SEGMENT_REG_DS:
ccprintf(os, "DS");
break;
- case 4:
+ case SEGMENT_REG_FS:
ccprintf(os, "FS");
break;
- case 5:
+ case SEGMENT_REG_GS:
ccprintf(os, "GS");
break;
+ case SEGMENT_REG_HS:
+ ccprintf(os, "HS");
+ break;
+ case SEGMENT_REG_TSL:
+ ccprintf(os, "TSL");
+ break;
+ case SEGMENT_REG_TSG:
+ ccprintf(os, "TSG");
+ break;
+ case SEGMENT_REG_LS:
+ ccprintf(os, "LS");
+ break;
+ case SEGMENT_REG_MS:
+ ccprintf(os, "MS");
+ break;
+ case SYS_SEGMENT_REG_TR:
+ ccprintf(os, "TR");
+ break;
+ case SYS_SEGMENT_REG_IDTR:
+ ccprintf(os, "IDTR");
+ break;
default:
panic("Unrecognized segment %d\n", segment);
}
}
void
- X86StaticInst::printSrcReg(std::ostream &os, int reg) const
+ X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
{
if(_numSrcRegs > reg)
- printReg(os, _srcRegIdx[reg]);
+ printReg(os, _srcRegIdx[reg], size);
}
void
- X86StaticInst::printDestReg(std::ostream &os, int reg) const
+ X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
{
if(_numDestRegs > reg)
- printReg(os, _destRegIdx[reg]);
+ printReg(os, _destRegIdx[reg], size);
}
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] =
+ {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"};
+ static const char * piFormats[9] =
+ {"", "%s", "%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) {
- //FIXME These should print differently depending on the
- //mode etc, but for now this will get the point across
+ const char * suffix = "";
+ bool fold = reg & (1 << 6);
+ reg &= ~(1 << 6);
+
+ if(fold)
+ {
+ suffix = "h";
+ reg -= 4;
+ }
+ else if(reg < 8 && size == 1)
+ suffix = "l";
+
switch (reg) {
case INTREG_RAX:
- ccprintf(os, "rax");
+ ccprintf(os, abcdFormats[size], "a");
break;
case INTREG_RBX:
- ccprintf(os, "rbx");
+ ccprintf(os, abcdFormats[size], "b");
break;
case INTREG_RCX:
- ccprintf(os, "rcx");
+ ccprintf(os, abcdFormats[size], "c");
break;
case INTREG_RDX:
- ccprintf(os, "rdx");
+ ccprintf(os, abcdFormats[size], "d");
break;
case INTREG_RSP:
- ccprintf(os, "rsp");
+ ccprintf(os, piFormats[size], "sp");
break;
case INTREG_RBP:
- ccprintf(os, "rbp");
+ ccprintf(os, piFormats[size], "bp");
break;
case INTREG_RSI:
- ccprintf(os, "rsi");
+ ccprintf(os, piFormats[size], "si");
break;
case INTREG_RDI:
- ccprintf(os, "rdi");
+ ccprintf(os, piFormats[size], "di");
break;
case INTREG_R8W:
- ccprintf(os, "r8");
+ ccprintf(os, longFormats[size], "8");
break;
case INTREG_R9W:
- ccprintf(os, "r9");
+ ccprintf(os, longFormats[size], "9");
break;
case INTREG_R10W:
- ccprintf(os, "r10");
+ ccprintf(os, longFormats[size], "10");
break;
case INTREG_R11W:
- ccprintf(os, "r11");
+ ccprintf(os, longFormats[size], "11");
break;
case INTREG_R12W:
- ccprintf(os, "r12");
+ ccprintf(os, longFormats[size], "12");
break;
case INTREG_R13W:
- ccprintf(os, "r13");
+ ccprintf(os, longFormats[size], "13");
break;
case INTREG_R14W:
- ccprintf(os, "r14");
+ ccprintf(os, longFormats[size], "14");
break;
case INTREG_R15W:
- ccprintf(os, "r15");
+ ccprintf(os, longFormats[size], "15");
break;
default:
- ccprintf(os, "t%d", reg - NUM_INTREGS);
+ ccprintf(os, microFormats[size], reg - NUM_INTREGS);
}
+ ccprintf(os, suffix);
} else if (reg < Ctrl_Base_DepTag) {
- ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+ int fpindex = reg - FP_Base_DepTag;
+ if(fpindex < NumMMXRegs) {
+ ccprintf(os, "%%mmx%d", reg - FP_Base_DepTag);
+ return;
+ }
+ fpindex -= NumMMXRegs;
+ if(fpindex < NumXMMRegs * 2) {
+ ccprintf(os, "%%xmm%d_%s", fpindex / 2,
+ (fpindex % 2) ? "high": "low");
+ return;
+ }
+ fpindex -= NumXMMRegs * 2;
+ if(fpindex < NumMicroFpRegs) {
+ ccprintf(os, "%%ufp%d", fpindex);
+ return;
+ }
+ fpindex -= NumMicroFpRegs;
+ ccprintf(os, "%%st(%d)", fpindex);
} else {
switch (reg - Ctrl_Base_DepTag) {
default:
}
}
+ void X86StaticInst::printMem(std::ostream &os, uint8_t segment,
+ uint8_t scale, RegIndex index, RegIndex base,
+ uint64_t disp, uint8_t addressSize, bool rip) const
+ {
+ bool someAddr = false;
+ printSegment(os, segment);
+ os << ":[";
+ if (rip) {
+ os << "rip";
+ someAddr = true;
+ } else {
+ if (scale != 0 && index != ZeroReg)
+ {
+ if(scale != 1)
+ ccprintf(os, "%d*", scale);
+ printReg(os, index, addressSize);
+ someAddr = true;
+ }
+ if (base != ZeroReg)
+ {
+ if(someAddr)
+ os << " + ";
+ printReg(os, base, addressSize);
+ someAddr = true;
+ }
+ }
+ if (disp != 0)
+ {
+ if(someAddr)
+ os << " + ";
+ ccprintf(os, "%#x", disp);
+ someAddr = true;
+ }
+ if (!someAddr)
+ os << "0";
+ os << "]";
+ }
+
std::string X86StaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{