| Index: src/disasm-ia32.cc
|
| ===================================================================
|
| --- src/disasm-ia32.cc (revision 1097)
|
| +++ src/disasm-ia32.cc (working copy)
|
| @@ -116,6 +116,14 @@
|
| };
|
|
|
|
|
| +static const char* set_conditional_mnem[] = {
|
| + /*0*/ "seto", "setno", "setc", "setnc",
|
| + /*4*/ "setz", "setnz", "setna", "seta",
|
| + /*8*/ "sets", "setns", "setpe", "setpo",
|
| + /*12*/ "setl", "setnl", "setng", "setg"
|
| +};
|
| +
|
| +
|
| enum InstructionType {
|
| NO_INSTR,
|
| ZERO_OPERANDS_INSTR,
|
| @@ -261,6 +269,11 @@
|
| }
|
|
|
|
|
| + const char* NameOfByteCPURegister(int reg) const {
|
| + return converter_.NameOfByteCPURegister(reg);
|
| + }
|
| +
|
| +
|
| const char* NameOfXMMRegister(int reg) const {
|
| return converter_.NameOfXMMRegister(reg);
|
| }
|
| @@ -285,8 +298,11 @@
|
| *base = data & 7;
|
| }
|
|
|
| + typedef const char* (DisassemblerIA32::*RegisterNameMapping)(int reg) const;
|
|
|
| + int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name);
|
| int PrintRightOperand(byte* modrmp);
|
| + int PrintRightByteOperand(byte* modrmp);
|
| int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);
|
| int PrintImmediateOp(byte* data);
|
| int F7Instruction(byte* data);
|
| @@ -318,10 +334,9 @@
|
| tmp_buffer_pos_ += result;
|
| }
|
|
|
| -
|
| -// Returns number of bytes used including the current *modrmp.
|
| -// Writes instruction's right operand to 'tmp_buffer_'.
|
| -int DisassemblerIA32::PrintRightOperand(byte* modrmp) {
|
| +int DisassemblerIA32::PrintRightOperandHelper(
|
| + byte* modrmp,
|
| + RegisterNameMapping register_name) {
|
| int mod, regop, rm;
|
| get_modrm(*modrmp, &mod, ®op, &rm);
|
| switch (mod) {
|
| @@ -335,20 +350,20 @@
|
| int scale, index, base;
|
| get_sib(sib, &scale, &index, &base);
|
| if (index == esp && base == esp && scale == 0 /*times_1*/) {
|
| - AppendToBuffer("[%s]", NameOfCPURegister(rm));
|
| + AppendToBuffer("[%s]", (this->*register_name)(rm));
|
| return 2;
|
| } else if (base == ebp) {
|
| int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
|
| AppendToBuffer("[%s*%d+0x%x]",
|
| - NameOfCPURegister(index),
|
| + (this->*register_name)(index),
|
| 1 << scale,
|
| disp);
|
| return 6;
|
| } else if (index != esp && base != ebp) {
|
| // [base+index*scale]
|
| AppendToBuffer("[%s+%s*%d]",
|
| - NameOfCPURegister(base),
|
| - NameOfCPURegister(index),
|
| + (this->*register_name)(base),
|
| + (this->*register_name)(index),
|
| 1 << scale);
|
| return 2;
|
| } else {
|
| @@ -356,7 +371,7 @@
|
| return 1;
|
| }
|
| } else {
|
| - AppendToBuffer("[%s]", NameOfCPURegister(rm));
|
| + AppendToBuffer("[%s]", (this->*register_name)(rm));
|
| return 1;
|
| }
|
| break;
|
| @@ -369,11 +384,11 @@
|
| int disp =
|
| mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2) : *(modrmp + 2);
|
| if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) {
|
| - AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);
|
| + AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp);
|
| } else {
|
| AppendToBuffer("[%s+%s*%d+0x%x]",
|
| - NameOfCPURegister(base),
|
| - NameOfCPURegister(index),
|
| + (this->*register_name)(base),
|
| + (this->*register_name)(index),
|
| 1 << scale,
|
| disp);
|
| }
|
| @@ -382,12 +397,12 @@
|
| // No sib.
|
| int disp =
|
| mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1) : *(modrmp + 1);
|
| - AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);
|
| + AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp);
|
| return mod == 2 ? 5 : 2;
|
| }
|
| break;
|
| case 3:
|
| - AppendToBuffer("%s", NameOfCPURegister(rm));
|
| + AppendToBuffer("%s", (this->*register_name)(rm));
|
| return 1;
|
| default:
|
| UnimplementedInstruction();
|
| @@ -397,6 +412,17 @@
|
| }
|
|
|
|
|
| +int DisassemblerIA32::PrintRightOperand(byte* modrmp) {
|
| + return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfCPURegister);
|
| +}
|
| +
|
| +
|
| +int DisassemblerIA32::PrintRightByteOperand(byte* modrmp) {
|
| + return PrintRightOperandHelper(modrmp,
|
| + &DisassemblerIA32::NameOfByteCPURegister);
|
| +}
|
| +
|
| +
|
| // Returns number of bytes used including the current *data.
|
| // Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
|
| int DisassemblerIA32::PrintOperands(const char* mnem,
|
| @@ -581,9 +607,9 @@
|
| int DisassemblerIA32::SetCC(byte* data) {
|
| assert(*data == 0x0F);
|
| byte cond = *(data+1) & 0x0F;
|
| - const char* mnem = jump_conditional_mnem[cond];
|
| - AppendToBuffer("set%s ", mnem);
|
| - PrintRightOperand(data+2);
|
| + const char* mnem = set_conditional_mnem[cond];
|
| + AppendToBuffer("%s ", mnem);
|
| + PrintRightByteOperand(data+2);
|
| return 3; // includes 0x0F
|
| }
|
|
|
| @@ -1069,12 +1095,17 @@
|
|
|
|
|
| static const char* cpu_regs[8] = {
|
| - "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
| + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
|
| };
|
|
|
|
|
| +static const char* byte_cpu_regs[8] = {
|
| + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
|
| +};
|
| +
|
| +
|
| static const char* xmm_regs[8] = {
|
| - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
| + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
|
| };
|
|
|
|
|
| @@ -1096,6 +1127,12 @@
|
| }
|
|
|
|
|
| +const char* NameConverter::NameOfByteCPURegister(int reg) const {
|
| + if (0 <= reg && reg < 8) return byte_cpu_regs[reg];
|
| + return "noreg";
|
| +}
|
| +
|
| +
|
| const char* NameConverter::NameOfXMMRegister(int reg) const {
|
| if (0 <= reg && reg < 8) return xmm_regs[reg];
|
| return "noxmmreg";
|
|
|