diff --git a/bochs/bxdisasm_new.cc b/bochs/bxdisasm_new.cc index 875367444..c17f0dbe8 100644 --- a/bochs/bxdisasm_new.cc +++ b/bochs/bxdisasm_new.cc @@ -55,8 +55,6 @@ void hex2bin(Bit8u* target, const char* src, unsigned len) } } -extern char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxInstruction_c *i, bx_address cs_base = 0, bx_address rip = 0); - int main(int argn, const char **argv) { char disbuf[256]; @@ -98,10 +96,13 @@ int main(int argn, const char **argv) printf("instruction bytes:"); for (int i=0;i<16;i++) - printf("%02x ", ibuf[i]); + printf("%02x", ibuf[i]); printf("\n"); bxInstruction_c i; - disasm(ibuf, is_32, is_64, disbuf, &i, 0, 0); + disasm(ibuf, is_32, is_64, disbuf, &i, 0, 0, BX_DISASM_INTEL); + printf("disasm: %s (opcode handler=%s)\n", disbuf, i.getIaOpcodeName()); + + disasm(ibuf, is_32, is_64, disbuf, &i, 0, 0, BX_DISASM_GAS); printf("disasm: %s (opcode handler=%s)\n", disbuf, i.getIaOpcodeName()); } diff --git a/bochs/bxdisasm_old.cc b/bochs/bxdisasm_old.cc index 633ae8074..59f99ef81 100644 --- a/bochs/bxdisasm_old.cc +++ b/bochs/bxdisasm_old.cc @@ -97,7 +97,7 @@ int main(int argn, const char **argv) printf("instruction bytes:"); for (int i=0;i<16;i++) - printf("%02x ", ibuf[i]); + printf("%02x", ibuf[i]); printf("\n"); bx_disassemble.set_syntax_intel(); diff --git a/bochs/cpu/decoder/disasm.cc b/bochs/cpu/decoder/disasm.cc index 7a7d234fa..3ecb531c6 100644 --- a/bochs/cpu/decoder/disasm.cc +++ b/bochs/cpu/decoder/disasm.cc @@ -69,38 +69,38 @@ char* dis_putc(char *disbufptr, char symbol) return disbufptr; } -static const char *intel_general_16bit_regname[16] = { +static const char *general_16bit_regname[16] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" }; -static const char *intel_general_32bit_regname[17] = { +static const char *general_32bit_regname[17] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d", "eip" }; -static const char *intel_general_64bit_regname[17] = { +static const char *general_64bit_regname[17] = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rip" }; #if BX_SUPPORT_X86_64 -static const char *intel_general_8bit_regname_rex[16] = { +static const char *general_8bit_regname_rex[16] = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }; #endif -static const char *intel_general_8bit_regname[8] = { +static const char *general_8bit_regname[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }; -static const char *intel_segment_name[8] = { +static const char *segment_name[8] = { "es", "cs", "ss", "ds", "fs", "gs", "??", "??" }; #if BX_SUPPORT_AVX -static const char *intel_vector_reg_name[4] = { +static const char *vector_reg_name[4] = { "xmm", "ymm", "???", "zmm" }; #endif @@ -113,13 +113,13 @@ static const char *rounding_mode[4] = { #define BX_JUMP_TARGET_NOT_REQ ((bx_address)(-1)) -char *resolve_sib_scale(char *disbufptr, const bxInstruction_c *i, const char *regname[], unsigned src_index) +char *resolve_sib_scale_intel(char *disbufptr, const bxInstruction_c *i, const char *regname[], unsigned src_index) { unsigned sib_index = i->sibIndex(), sib_scale = i->sibScale(); #if BX_SUPPORT_AVX if (src_index == BX_SRC_VSIB) - disbufptr = dis_sprintf(disbufptr, "%s%d", intel_vector_reg_name[i->getVL() - 1], sib_index); + disbufptr = dis_sprintf(disbufptr, "%s%d", vector_reg_name[i->getVL() - 1], sib_index); else #endif disbufptr = dis_sprintf(disbufptr, "%s", regname[sib_index]); @@ -130,7 +130,24 @@ char *resolve_sib_scale(char *disbufptr, const bxInstruction_c *i, const char *r return disbufptr; } -char *resolve_memref(char *disbufptr, const bxInstruction_c *i, const char *regname[], unsigned src_index) +char *resolve_sib_scale_gas(char *disbufptr, const bxInstruction_c *i, const char *regname[], unsigned src_index) +{ + unsigned sib_index = i->sibIndex(), sib_scale = i->sibScale(); + +#if BX_SUPPORT_AVX + if (src_index == BX_SRC_VSIB) + disbufptr = dis_sprintf(disbufptr, "%%%s%d", vector_reg_name[i->getVL() - 1], sib_index); + else +#endif + disbufptr = dis_sprintf(disbufptr, "%%%s", regname[sib_index]); + + if (sib_scale) + disbufptr = dis_sprintf(disbufptr, ",%d", 1 << sib_scale); + + return disbufptr; +} + +char *resolve_memref_intel(char *disbufptr, const bxInstruction_c *i, const char *regname[], unsigned src_index) { unsigned sib_base = i->sibBase(), sib_index = i->sibIndex(); @@ -157,14 +174,14 @@ char *resolve_memref(char *disbufptr, const bxInstruction_c *i, const char *regn } disbufptr = dis_putc(disbufptr, '['); - disbufptr = resolve_sib_scale(disbufptr, i, regname, src_index); + disbufptr = resolve_sib_scale_intel(disbufptr, i, regname, src_index); } else { disbufptr = dis_sprintf(disbufptr, "[%s", regname[i->sibBase()]); if (sib_index != BX_NIL_REGISTER) { disbufptr = dis_putc(disbufptr, '+'); - disbufptr = resolve_sib_scale(disbufptr, i, regname, src_index); + disbufptr = resolve_sib_scale_intel(disbufptr, i, regname, src_index); } } @@ -183,6 +200,59 @@ char *resolve_memref(char *disbufptr, const bxInstruction_c *i, const char *regn return disbufptr; } +char *resolve_memref_gas(char *disbufptr, const bxInstruction_c *i, const char *regname[], unsigned src_index) +{ + unsigned sib_base = i->sibBase(), sib_index = i->sibIndex(); + + if (sib_index == 4 && src_index != BX_SRC_VSIB) + sib_index = BX_NIL_REGISTER; + + if (sib_base != BX_NIL_REGISTER || sib_index != BX_NIL_REGISTER) { + if (i->displ32s() != 0) { + if (i->as32L()) { + disbufptr = dis_sprintf(disbufptr, "0x%x", (Bit32u) i->displ32s()); + } + else { + disbufptr = dis_sprintf(disbufptr, "0x%x", (Bit32u) (Bit16u) i->displ16s()); + } + } + } + + if (sib_base == BX_NIL_REGISTER) + { + if (sib_index == BX_NIL_REGISTER) + { +#if BX_SUPPORT_X86_64 + if (i->as64L()) { + disbufptr = dis_sprintf(disbufptr, "0x" FMT_ADDRX, (Bit64u) i->displ32s()); + return disbufptr; + } +#endif + if (i->as32L()) { + disbufptr = dis_sprintf(disbufptr, "0x%x", (Bit32u) i->displ32s()); + } + else { + disbufptr = dis_sprintf(disbufptr, "0x%x", (Bit32u) (Bit16u) i->displ16s()); + } + return disbufptr; + } + + disbufptr = dis_sprintf(disbufptr, "(,"); + disbufptr = resolve_sib_scale_gas(disbufptr, i, regname, src_index); + } + else { + disbufptr = dis_sprintf(disbufptr, "(%%%s", regname[i->sibBase()]); + + if (sib_index != BX_NIL_REGISTER) { + disbufptr = dis_putc(disbufptr, ','); + disbufptr = resolve_sib_scale_gas(disbufptr, i, regname, src_index); + } + } + + disbufptr = dis_putc(disbufptr, ')'); + return disbufptr; +} + char *resolve_memsize(char *disbufptr, const bxInstruction_c *i, unsigned src_index, unsigned src_type) { if (src_index == BX_SRC_VECTOR_RM) { @@ -253,7 +323,7 @@ char *resolve_memsize(char *disbufptr, const bxInstruction_c *i, unsigned src_in case BX_VMM_REG: #if BX_SUPPORT_AVX if (i->getVL() > BX_NO_VL) - disbufptr = dis_sprintf(disbufptr, "%sword ptr ", intel_vector_reg_name[i->getVL() - 1]); + disbufptr = dis_sprintf(disbufptr, "%sword ptr ", vector_reg_name[i->getVL() - 1]); else #endif disbufptr = dis_sprintf(disbufptr, "xmmword ptr "); @@ -265,7 +335,7 @@ char *resolve_memsize(char *disbufptr, const bxInstruction_c *i, unsigned src_in } #if BX_SUPPORT_AVX else if (src_index == BX_SRC_VSIB) { - disbufptr = dis_sprintf(disbufptr, "%sword ptr ", intel_vector_reg_name[i->getVL() - 1]); + disbufptr = dis_sprintf(disbufptr, "%sword ptr ", vector_reg_name[i->getVL() - 1]); } #endif @@ -273,52 +343,72 @@ char *resolve_memsize(char *disbufptr, const bxInstruction_c *i, unsigned src_in } // disasembly of memory reference -char *resolve_memref(char *disbufptr, const bxInstruction_c *i, unsigned src_index, unsigned src_type) +char *resolve_memref_intel(char *disbufptr, const bxInstruction_c *i, unsigned src_index, unsigned src_type) { disbufptr = resolve_memsize(disbufptr, i, src_index, src_type); // seg:[base + index*scale + disp] - disbufptr = dis_sprintf(disbufptr, "%s:", intel_segment_name[i->seg()]); + disbufptr = dis_sprintf(disbufptr, "%s:", segment_name[i->seg()]); if (i->as64L()) { - disbufptr = resolve_memref(disbufptr, i, intel_general_64bit_regname, src_index); + disbufptr = resolve_memref_intel(disbufptr, i, general_64bit_regname, src_index); } else if (i->as32L()) { - disbufptr = resolve_memref(disbufptr, i, intel_general_32bit_regname, src_index); + disbufptr = resolve_memref_intel(disbufptr, i, general_32bit_regname, src_index); } else { - disbufptr = resolve_memref(disbufptr, i, intel_general_16bit_regname, src_index); + disbufptr = resolve_memref_intel(disbufptr, i, general_16bit_regname, src_index); + } + return disbufptr; +} + +char *resolve_memref_gas(char *disbufptr, const bxInstruction_c *i, unsigned src_index, unsigned src_type) +{ + // %%seg: $disp[base, index, scale) + disbufptr = dis_sprintf(disbufptr, "%%%s:", segment_name[i->seg()]); + if (i->as64L()) { + disbufptr = resolve_memref_gas(disbufptr, i, general_64bit_regname, src_index); + } + else if (i->as32L()) { + disbufptr = resolve_memref_gas(disbufptr, i, general_32bit_regname, src_index); + } + else { + disbufptr = resolve_memref_gas(disbufptr, i, general_16bit_regname, src_index); } return disbufptr; } // disasembly of register reference -char *disasm_regref(char *disbufptr, const bxInstruction_c *i, unsigned src_num, unsigned src_type) +char *disasm_regref(char *disbufptr, const bxInstruction_c *i, unsigned src_num, unsigned src_type, BxDisasmStyle style) { unsigned srcreg = i->getSrcReg(src_num); + if (style == BX_DISASM_GAS) + if (src_type != BX_KMASK_REG_PAIR && src_type != BX_NO_REGISTER) + disbufptr = dis_sprintf(disbufptr, "%%"); + switch(src_type) { case BX_GPR8: #if BX_SUPPORT_X86_64 if (i->extend8bitL()) - disbufptr = dis_sprintf(disbufptr, "%s", intel_general_8bit_regname_rex[srcreg]); + disbufptr = dis_sprintf(disbufptr, "%s", general_8bit_regname_rex[srcreg]); else #endif - disbufptr = dis_sprintf(disbufptr, "%s", intel_general_8bit_regname[srcreg]); + disbufptr = dis_sprintf(disbufptr, "%s", general_8bit_regname[srcreg]); break; case BX_GPR16: - disbufptr = dis_sprintf(disbufptr, "%s", intel_general_16bit_regname[srcreg]); + disbufptr = dis_sprintf(disbufptr, "%s", general_16bit_regname[srcreg]); break; case BX_GPR32: case BX_GPR32_MEM8: // 8-bit memory ref but 32-bit GPR case BX_GPR32_MEM16: // 16-bit memory ref but 32-bit GPR - disbufptr = dis_sprintf(disbufptr, "%s", intel_general_32bit_regname[srcreg]); + disbufptr = dis_sprintf(disbufptr, "%s", general_32bit_regname[srcreg]); break; #if BX_SUPPORT_X86_64 case BX_GPR64: - disbufptr = dis_sprintf(disbufptr, "%s", intel_general_64bit_regname[srcreg]); + disbufptr = dis_sprintf(disbufptr, "%s", general_64bit_regname[srcreg]); break; #endif @@ -334,7 +424,7 @@ char *disasm_regref(char *disbufptr, const bxInstruction_c *i, unsigned src_num, case BX_VMM_REG: #if BX_SUPPORT_AVX if (i->getVL() > BX_NO_VL) { - disbufptr = dis_sprintf(disbufptr, "%s%d", intel_vector_reg_name[i->getVL() - 1], srcreg); + disbufptr = dis_sprintf(disbufptr, "%s%d", vector_reg_name[i->getVL() - 1], srcreg); #if BX_SUPPORT_EVEX if (src_num == 0 && i->opmask()) { disbufptr = dis_sprintf(disbufptr, "{k%d}%s", i->opmask(), @@ -354,19 +444,24 @@ char *disasm_regref(char *disbufptr, const bxInstruction_c *i, unsigned src_num, disbufptr = dis_sprintf(disbufptr, "k%d", srcreg); assert(srcreg < 8); if (src_num == 0 && i->opmask()) { - disbufptr = dis_sprintf(disbufptr, "{k%d}%s", i->opmask(), + disbufptr = dis_sprintf(disbufptr, "{%sk%d}%s", (style == BX_DISASM_GAS) ? "%" : "", + i->opmask(), i->isZeroMasking() ? "{z}" : ""); } break; case BX_KMASK_REG_PAIR: - disbufptr = dis_sprintf(disbufptr, "[k%d, k%d]", srcreg & ~1, 1 + (srcreg & ~1)); + disbufptr = dis_sprintf(disbufptr, "[%sk%d, %sk%d]", + (style == BX_DISASM_GAS) ? "%" : "", + srcreg & ~1, + (style == BX_DISASM_GAS) ? "%" : "", + 1 + (srcreg & ~1)); assert(srcreg < 8); break; #endif case BX_SEGREG: - disbufptr = dis_sprintf(disbufptr, "%s", intel_segment_name[srcreg]); + disbufptr = dis_sprintf(disbufptr, "%s", segment_name[srcreg]); break; case BX_CREG: @@ -386,7 +481,7 @@ char *disasm_regref(char *disbufptr, const bxInstruction_c *i, unsigned src_num, return disbufptr; } -char *disasm_immediate(char *disbufptr, const bxInstruction_c *i, unsigned src_type) +char *disasm_immediate(char *disbufptr, const bxInstruction_c *i, unsigned src_type, BxDisasmStyle style) { switch(src_type) { case BX_DIRECT_MEMREF_B: @@ -404,6 +499,10 @@ char *disasm_immediate(char *disbufptr, const bxInstruction_c *i, unsigned src_t default: break; }; + if (style == BX_DISASM_GAS) + if(src_type != BX_DIRECT_MEMREF_B && src_type != BX_DIRECT_MEMREF_W && src_type != BX_DIRECT_MEMREF_D && src_type != BX_DIRECT_MEMREF_Q) + disbufptr = dis_sprintf(disbufptr, "$"); + switch(src_type) { case BX_IMM1: disbufptr = dis_sprintf(disbufptr, "0x01"); @@ -469,7 +568,8 @@ char *disasm_immediate(char *disbufptr, const bxInstruction_c *i, unsigned src_t case BX_DIRECT_MEMREF_W: case BX_DIRECT_MEMREF_D: case BX_DIRECT_MEMREF_Q: - disbufptr = dis_sprintf(disbufptr, "%s:", intel_segment_name[i->seg()]); + disbufptr = dis_sprintf(disbufptr, "%s%s:", + (style == BX_DISASM_GAS) ? "%" : "", segment_name[i->seg()]); #if BX_SUPPORT_X86_64 if (i->as64L()) disbufptr = dis_sprintf(disbufptr, "0x" FMT_ADDRX, i->Iq()); @@ -488,7 +588,7 @@ char *disasm_immediate(char *disbufptr, const bxInstruction_c *i, unsigned src_t return disbufptr; } -char *disasm_branch_target(char *disbufptr, const bxInstruction_c *i, unsigned src_type, bx_address cs_base, bx_address rip) +char *disasm_branch_target(char *disbufptr, const bxInstruction_c *i, unsigned src_type, bx_address cs_base, bx_address rip, BxDisasmStyle style) { bx_address target; Bit16s imm16; @@ -533,104 +633,163 @@ char *disasm_branch_target(char *disbufptr, const bxInstruction_c *i, unsigned s return disbufptr; } -char *disasm_implicit_src(char *disbufptr, const bxInstruction_c *i, unsigned src_type) +char *disasm_implicit_src(char *disbufptr, const bxInstruction_c *i, unsigned src_type, BxDisasmStyle style) { - switch(src_type) { - case BX_RSIREF_B: - case BX_RDIREF_B: - disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR8); - break; - case BX_RSIREF_W: - case BX_RDIREF_W: - disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR16); - break; - case BX_RSIREF_D: - case BX_RDIREF_D: - disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR32); - break; - case BX_RSIREF_Q: - case BX_RDIREF_Q: - case BX_MMX_RDIREF: - disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR64); - break; - case BX_VEC_RDIREF: - disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_VMM_REG); - break; - default: break; - }; + if (style == BX_DISASM_INTEL) { + switch(src_type) { + case BX_RSIREF_B: + case BX_RDIREF_B: + disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR8); + break; + case BX_RSIREF_W: + case BX_RDIREF_W: + disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR16); + break; + case BX_RSIREF_D: + case BX_RDIREF_D: + disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR32); + break; + case BX_RSIREF_Q: + case BX_RDIREF_Q: + case BX_MMX_RDIREF: + disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_GPR64); + break; + case BX_VEC_RDIREF: + disbufptr = resolve_memsize(disbufptr, i, BX_SRC_RM, BX_VMM_REG); + break; + default: break; + }; + } - switch(src_type) { - case BX_RSIREF_B: - case BX_RSIREF_W: - case BX_RSIREF_D: - case BX_RSIREF_Q: - disbufptr = dis_sprintf(disbufptr, "%s:", intel_segment_name[i->seg()]); -#if BX_SUPPORT_X86_64 - if (i->as64L()) { - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_64bit_regname[BX_64BIT_REG_RSI]); - } - else -#endif - { - if (i->as32L()) - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_32bit_regname[BX_32BIT_REG_ESI]); - else - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_16bit_regname[BX_16BIT_REG_SI]); - } - break; - - case BX_RDIREF_B: - case BX_RDIREF_W: - case BX_RDIREF_D: - case BX_RDIREF_Q: - disbufptr = dis_sprintf(disbufptr, "%s:", intel_segment_name[BX_SEG_REG_ES]); -#if BX_SUPPORT_X86_64 - if (i->as64L()) { - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_64bit_regname[BX_64BIT_REG_RDI]); - } - else -#endif - { - if (i->as32L()) - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_32bit_regname[BX_32BIT_REG_EDI]); - else - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_16bit_regname[BX_16BIT_REG_DI]); - } - break; - - case BX_MMX_RDIREF: - case BX_VEC_RDIREF: - disbufptr = dis_sprintf(disbufptr, "%s:", intel_segment_name[i->seg()]); -#if BX_SUPPORT_X86_64 - if (i->as64L()) { - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_64bit_regname[BX_64BIT_REG_RDI]); - } - else -#endif - { - if (i->as32L()) - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_32bit_regname[BX_32BIT_REG_EDI]); - else - disbufptr = dis_sprintf(disbufptr, "[%s]", intel_general_16bit_regname[BX_16BIT_REG_DI]); - } - break; - - case BX_USECL: + if (src_type == BX_USECL) { + if (style == BX_DISASM_GAS) disbufptr = dis_putc(disbufptr, '%'); disbufptr = dis_sprintf(disbufptr, "cl"); + return disbufptr; + } + + if (src_type ==BX_USEDX) { + if (style == BX_DISASM_GAS) disbufptr = dis_putc(disbufptr, '%'); + disbufptr = dis_sprintf(disbufptr, "dx"); + return disbufptr; + } + + const char *regname = NULL; + unsigned seg = BX_SEG_REG_NULL; + + switch(src_type) { + case BX_RSIREF_B: + case BX_RSIREF_W: + case BX_RSIREF_D: + case BX_RSIREF_Q: + seg = i->seg(); + disbufptr = dis_sprintf(disbufptr, "%s:", segment_name[i->seg()]); +#if BX_SUPPORT_X86_64 + if (i->as64L()) { + regname = general_64bit_regname[BX_64BIT_REG_RSI]; + } + else +#endif + { + if (i->as32L()) + regname = general_32bit_regname[BX_32BIT_REG_ESI]; + else + regname = general_16bit_regname[BX_16BIT_REG_SI]; + } break; - case BX_USEDX: - disbufptr = dis_sprintf(disbufptr, "dx"); + case BX_RDIREF_B: + case BX_RDIREF_W: + case BX_RDIREF_D: + case BX_RDIREF_Q: + seg = BX_SEG_REG_ES; +#if BX_SUPPORT_X86_64 + if (i->as64L()) { + regname = general_64bit_regname[BX_64BIT_REG_RDI]; + } + else +#endif + { + if (i->as32L()) + regname = general_32bit_regname[BX_32BIT_REG_EDI]; + else + regname = general_16bit_regname[BX_16BIT_REG_DI]; + } + break; + + case BX_MMX_RDIREF: + case BX_VEC_RDIREF: + seg = i->seg(); +#if BX_SUPPORT_X86_64 + if (i->as64L()) { + regname = general_64bit_regname[BX_64BIT_REG_RDI]; + } + else +#endif + { + if (i->as32L()) + regname = general_32bit_regname[BX_32BIT_REG_EDI]; + else + regname = general_16bit_regname[BX_16BIT_REG_DI]; + } break; default: disbufptr = dis_sprintf(disbufptr, "(unknown implicit source for disasm %d)", src_type); } - + + if (style == BX_DISASM_INTEL) { + disbufptr = dis_sprintf(disbufptr, "%s:[%s]", segment_name[seg], regname); + } + else { + disbufptr = dis_sprintf(disbufptr, "%%%s:(%%%s)", segment_name[seg], regname); + } + return disbufptr; } -char* disasm(char *disbufptr, const bxInstruction_c *i, bx_address cs_base, bx_address rip) +char* disasm_source(char *disbufptr, unsigned n, bool srcs_used, const bxInstruction_c *i, bx_address cs_base, bx_address rip, BxDisasmStyle style) +{ + Bit16u ia_opcode = i->getIaOpcode(); + unsigned src = (unsigned) BxOpcodesTable[ia_opcode].src[n]; + unsigned src_type = BX_DISASM_SRC_TYPE(src); + unsigned src_index = BX_DISASM_SRC_ORIGIN(src); + + if (! src_type && src_index != BX_SRC_RM && src_index != BX_SRC_VECTOR_RM) return disbufptr; + + if (srcs_used) disbufptr = dis_sprintf(disbufptr, ", "); + + if (! i->modC0() && (src_index == BX_SRC_RM || src_index == BX_SRC_VECTOR_RM || src_index == BX_SRC_VSIB)) { + disbufptr = (style == BX_DISASM_INTEL) ? resolve_memref_intel(disbufptr, i, src_index, src_type) : resolve_memref_gas(disbufptr, i, src_index, src_type); +#if BX_SUPPORT_EVEX + if (n == 0 && (src_index == BX_SRC_VECTOR_RM || src_index == BX_SRC_VSIB || src_type == BX_VMM_REG) && i->opmask()) { + disbufptr = dis_sprintf(disbufptr, "{k%d}", i->opmask()); + } +#endif + } + else { + if (src_index == BX_SRC_VECTOR_RM) src_type = BX_VMM_REG; + + if (src_index == BX_SRC_IMM) { + // this is immediate value + disbufptr = disasm_immediate(disbufptr, i, src_type, style); + } + else if (src_index == BX_SRC_BRANCH_OFFSET) { + // this is immediate value used as branch target + disbufptr = disasm_branch_target(disbufptr, i, src_type, cs_base, rip, style); + } + else if (src_index == BX_SRC_IMPLICIT) { + // this is implicit register or memory reference + disbufptr = disasm_implicit_src(disbufptr, i, src_type, style); + } + else { + // this is register reference + disbufptr = disasm_regref(disbufptr, i, n, src_type, style); + } + } + return disbufptr; +} + +char* disasm(char *disbufptr, const bxInstruction_c *i, bx_address cs_base, bx_address rip, BxDisasmStyle style) { #if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS if (i->getIaOpcode() == BX_INSERTED_OPCODE) { @@ -652,7 +811,7 @@ char* disasm(char *disbufptr, const bxInstruction_c *i, bx_address cs_base, bx_a #endif const char *opname = i->getIaOpcodeNameShort(); // skip the "BX_IA_" - unsigned n; + int n; #if BX_SUPPORT_EVEX bx_bool is_vector = false; #endif @@ -680,51 +839,29 @@ char* disasm(char *disbufptr, const bxInstruction_c *i, bx_address cs_base, bx_a } // Step 2: print opcode name - unsigned opname_len = strlen(opname); - for (n=0;n < opname_len; n++) { - if (opname[n] == '_') break; - disbufptr = dis_putc(disbufptr, tolower(opname[n])); + Bit16u ia_opcode = i->getIaOpcode(); + if (style == BX_DISASM_GAS) { + disbufptr = dis_sprintf(disbufptr, "%s", get_gas_disasm_opcode_name(ia_opcode)); + } + else { + disbufptr = dis_sprintf(disbufptr, "%s", get_intel_disasm_opcode_name(ia_opcode)); } disbufptr = dis_putc(disbufptr, ' '); // Step 3: print sources - Bit16u ia_opcode = i->getIaOpcode(); - unsigned srcs_used = 0; - for (n = 0; n <= 3; n++) { - unsigned src = (unsigned) BxOpcodesTable[ia_opcode].src[n]; - unsigned src_type = BX_DISASM_SRC_TYPE(src); - unsigned src_index = BX_DISASM_SRC_ORIGIN(src); - if (! src_type && src_index != BX_SRC_RM && src_index != BX_SRC_VECTOR_RM) continue; - if (srcs_used++ > 0) - disbufptr = dis_sprintf(disbufptr, ", "); - - if (! i->modC0() && (src_index == BX_SRC_RM || src_index == BX_SRC_VECTOR_RM || src_index == BX_SRC_VSIB)) { - disbufptr = resolve_memref(disbufptr, i, src_index, src_type); -#if BX_SUPPORT_EVEX - if (n == 0 && (src_index == BX_SRC_VECTOR_RM || src_index == BX_SRC_VSIB || src_type == BX_VMM_REG) && i->opmask()) { - disbufptr = dis_sprintf(disbufptr, "{k%d}", i->opmask()); - } -#endif + bool srcs_used = 0; + if (style == BX_DISASM_INTEL) { + for (n = 0; n <= 3; n++) { + char *disbufptrtmp = disasm_source(disbufptr, n, srcs_used, i, cs_base, rip, style); + if (disbufptrtmp != disbufptr) srcs_used=1; + disbufptr = disbufptrtmp; } - else { - if (src_index == BX_SRC_VECTOR_RM) src_type = BX_VMM_REG; - - if (src_index == BX_SRC_IMM) { - // this is immediate value - disbufptr = disasm_immediate(disbufptr, i, src_type); - } - else if (src_index == BX_SRC_BRANCH_OFFSET) { - // this is immediate value used as branch target - disbufptr = disasm_branch_target(disbufptr, i, src_type, cs_base, rip); - } - else if (src_index == BX_SRC_IMPLICIT) { - // this is implicit register or memory reference - disbufptr = disasm_implicit_src(disbufptr, i, src_type); - } - else { - // this is register reference - disbufptr = disasm_regref(disbufptr, i, n, src_type); - } + } + else { + for (n = 3; n >= 0; n--) { + char *disbufptrtmp = disasm_source(disbufptr, n, srcs_used, i, cs_base, rip, style); + if (disbufptrtmp != disbufptr) srcs_used=1; + disbufptr = disbufptrtmp; } } @@ -740,7 +877,7 @@ char* disasm(char *disbufptr, const bxInstruction_c *i, bx_address cs_base, bx_a return disbufptr; } -char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxInstruction_c *i, bx_address cs_base, bx_address rip) +char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxInstruction_c *i, bx_address cs_base, bx_address rip, BxDisasmStyle style) { int ret; @@ -754,7 +891,7 @@ char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxIns if (ret < 0) sprintf(disbufptr, "decode failed"); else - ::disasm(disbufptr, i, cs_base, rip); + ::disasm(disbufptr, i, cs_base, rip, style); return disbufptr; } diff --git a/bochs/cpu/decoder/fetchdecode32.cc b/bochs/cpu/decoder/fetchdecode32.cc index e87502f63..ce4e89381 100644 --- a/bochs/cpu/decoder/fetchdecode32.cc +++ b/bochs/cpu/decoder/fetchdecode32.cc @@ -2679,3 +2679,28 @@ const char *get_bx_opcode_name(Bit16u ia_opcode) return (ia_opcode < BX_IA_LAST) ? BxOpcodeNamesTable[ia_opcode] : 0; } + +const char *get_intel_disasm_opcode_name(Bit16u ia_opcode) +{ + static const char* BxOpcodeNamesTable[BX_IA_LAST] = + { +#define bx_define_opcode(a, b, c, d, e, f, s1, s2, s3, s4, g) b, +#include "ia_opcodes.def" + }; +#undef bx_define_opcode + + return (ia_opcode < BX_IA_LAST) ? BxOpcodeNamesTable[ia_opcode] : 0; +} + +const char *get_gas_disasm_opcode_name(Bit16u ia_opcode) +{ + static const char* BxOpcodeNamesTable[BX_IA_LAST] = + { +#define bx_define_opcode(a, b, c, d, e, f, s1, s2, s3, s4, g) c, +#include "ia_opcodes.def" + }; +#undef bx_define_opcode + + return (ia_opcode < BX_IA_LAST) ? BxOpcodeNamesTable[ia_opcode] : 0; +} + diff --git a/bochs/cpu/decoder/instr.h b/bochs/cpu/decoder/instr.h index 8245d2f2b..984ffe61b 100644 --- a/bochs/cpu/decoder/instr.h +++ b/bochs/cpu/decoder/instr.h @@ -27,6 +27,8 @@ extern bx_address bx_asize_mask[]; const char *get_bx_opcode_name(Bit16u ia_opcode); +const char *get_intel_disasm_opcode_name(Bit16u ia_opcode); +const char *get_gas_disasm_opcode_name(Bit16u ia_opcode); class BX_CPU_C; class bxInstruction_c; @@ -408,4 +410,11 @@ public: }; // +enum BxDisasmStyle { + BX_DISASM_INTEL, + BX_DISASM_GAS +}; + +extern char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxInstruction_c *i, bx_address cs_base, bx_address rip, BxDisasmStyle style = BX_DISASM_INTEL); + #endif