diff --git a/bochs/CHANGES b/bochs/CHANGES index 0a1c3cb93..96b14f8a7 100644 --- a/bochs/CHANGES +++ b/bochs/CHANGES @@ -32,6 +32,11 @@ Changes in 2.1 (November 27, 2003): - 64-bit addressing support for x86-64 mode (Christophe Bothamy) - implemented FCMOVcc instructions +- Disassembler + - replaced Bochs disassember. new table-based disassembler fully supports + all IA-32 instruction sets including FPU/MMX/XMM/SSE/SSE2/SSE3 opcodes. + + More Details: [+] Added emulation of AMD 3DNow! instructions set. @@ -239,6 +244,7 @@ Patches applied: - these S.F. bugs were fixed // CB : I ran the request on SF, these bugs have definitely been closed // since 2.0.2). There might have been others, during 2.0 to 2.0.2 times + #859768 cpuid #843433 cdrom.cc on MacOSX: wrong const names #851331 .cvsignore files in tarball #787005 Some MOV instructions are not implemented!!! diff --git a/bochs/disasm/resolve.cc b/bochs/disasm/resolve.cc index 1c47ee8e5..a063ecffd 100755 --- a/bochs/disasm/resolve.cc +++ b/bochs/disasm/resolve.cc @@ -1,374 +1,374 @@ -#include "disasm.h" - -extern const char *general_16bit_reg_name[8]; -extern const char *general_32bit_reg_name[8]; - -static const char *sreg_mod01_rm32[8] = { - "ds", "ds", "ds", "ds", "??", "ss", "ds", "ds" -}; - -static const char *sreg_mod10_rm32[8] = { - "ds", "ds", "ds", "ds", "??", "ss", "ds", "ds" -}; - -static const char *sreg_mod00_base32[8] = { - "ds", "ds", "ds", "ds", "ss", "ds", "ds", "ds" -}; - -static const char *sreg_mod01_base32[8] = { - "ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds" -}; - -static const char *sreg_mod10_base32[8] = { - "ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds" -}; - -static const char *sreg_mod00_rm16[8] = { - "ds", "ds", "ss", "ss", "ds", "ds", "ds", "ds" -}; - -static const char *sreg_mod01_rm16[8] = { - "ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds" -}; - -static const char *sreg_mod10_rm16[8] = { - "ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds" -}; - -static const char *intel_index16[8] = { - "bx+si", - "bx+di", - "bp+si", - "bp+di", - "si", - "di", - "bp", - "bx" -}; - -static const char *index_name32[8] = { - "eax", "ecx", "edx", "ebx", "???", "ebp", "esi", "edi" -}; - -void disassembler::decode_modrm() -{ - modrm = fetch_byte(); - BX_DECODE_MODRM(modrm, mod, nnn, rm); - - if (i32bit_addrsize) - { - /* use 32bit addressing modes. orthogonal base & index registers, - scaling available, etc. */ - if (mod == 3) { - /* mod, reg, reg */ - return; - } - else { /* mod != 3 */ - if (rm != 4) { /* rm != 100b, no s-i-b byte */ - // one byte modrm - switch (mod) { - case 0: - resolve_modrm = &disassembler::resolve32_mod0; - if (rm == 5) /* no reg, 32-bit displacement */ - displacement.displ32 = fetch_dword(); - break; - case 1: - /* reg, 8-bit displacement, sign extend */ - resolve_modrm = &disassembler::resolve32_mod1; - displacement.displ32 = (Bit8s) fetch_byte(); - break; - case 2: - /* reg, 32-bit displacement */ - resolve_modrm = &disassembler::resolve32_mod2; - displacement.displ32 = fetch_dword(); - break; - } /* switch (mod) */ - } /* if (rm != 4) */ - else { /* rm == 4, s-i-b byte follows */ - sib = fetch_byte(); - BX_DECODE_SIB(sib, scale, index, base); - - switch (mod) { - case 0: - resolve_modrm = &disassembler::resolve32_mod0_rm4; - if (base == 5) - displacement.displ32 = fetch_dword(); - break; - case 1: - resolve_modrm = &disassembler::resolve32_mod1_rm4; - displacement.displ8 = fetch_byte(); - break; - case 2: - resolve_modrm = &disassembler::resolve32_mod2_rm4; - displacement.displ32 = fetch_dword(); - break; - } - } /* s-i-b byte follows */ - } /* if (mod != 3) */ - } - else { - /* 16 bit addressing modes. */ - switch (mod) { - case 0: - resolve_modrm = &disassembler::resolve16_mod0; - if(rm == 6) - displacement.displ16 = fetch_word(); - break; - case 1: - /* reg, 8-bit displacement, sign extend */ - resolve_modrm = &disassembler::resolve16_mod1; - displacement.displ16 = (Bit8s) fetch_byte(); - break; - case 2: - resolve_modrm = &disassembler::resolve16_mod2; - displacement.displ16 = fetch_word(); - break; - case 3: - /* mod, reg, reg */ - return; - - } /* switch (mod) ... */ - } -} - -void disassembler::print_datasize(unsigned mode) -{ - switch(mode) - { - case B_MODE: - dis_sprintf("byte ptr "); - break; - case W_MODE: - dis_sprintf("word ptr "); - break; - case D_MODE: - dis_sprintf("dword ptr "); - break; - case V_MODE: - if (i32bit_opsize) - dis_sprintf("dword ptr "); - else - dis_sprintf("word ptr "); - break; - case Q_MODE: - dis_sprintf("qword ptr "); - break; - case O_MODE: - dis_sprintf("oword ptr "); - break; - case T_MODE: - dis_sprintf("tword ptr "); - break; - case X_MODE: - break; - }; -} - -void disassembler::resolve16_mod0(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod00_rm16[rm]; - - print_datasize(mode); - - if(rm == 6) - { - dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, (unsigned) displacement.displ16); - } - else - { - dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]); - } -} - -void disassembler::resolve16_mod1(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod01_rm16[rm]; - - print_datasize(mode); - - if (displacement.displ16) - { - dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, - intel_index16[rm], (unsigned) displacement.displ16); - } - else - { - dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]); - } -} - -void disassembler::resolve16_mod2(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod10_rm16[rm]; - - print_datasize(mode); - - if (displacement.displ16) - { - dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, - intel_index16[rm], (unsigned) displacement.displ16); - } - else - { - dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]); - } -} - -void disassembler::resolve32_mod0(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = "ds"; - - print_datasize(mode); - - if (rm == 5) { /* no reg, 32-bit displacement */ - dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, displacement.displ32); - } - else { - dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]); - } -} - -void disassembler::resolve32_mod1(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod01_rm32[rm]; - - print_datasize(mode); - - /* reg, 8-bit displacement, sign extend */ - if (displacement.displ32) - { - dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, - general_32bit_reg_name[rm], (unsigned) displacement.displ32); - } - else - { - dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]); - } -} - -void disassembler::resolve32_mod2(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod10_rm32[rm]; - - print_datasize(mode); - - /* reg, 32-bit displacement */ - if (displacement.displ32) - { - dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, - general_32bit_reg_name[rm], (unsigned) displacement.displ32); - } - else - { - dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]); - } -} - -void disassembler::resolve32_mod0_rm4(unsigned mode) -{ - const char *mod_rm_seg_reg; - - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod00_base32[base]; - - print_datasize(mode); - - dis_sprintf("%s:[", mod_rm_seg_reg); - if (base != 5) - dis_sprintf("%s+", general_32bit_reg_name[base]); - - if (index != 4) - { - dis_sprintf("%s", index_name32[index]); - if (scale) - dis_sprintf("*%u", 1 << scale); - if (base == 5) dis_sprintf("+"); - } - - if (base == 5) - dis_sprintf("0x%x", (unsigned) displacement.displ32); - - dis_sprintf("]"); -} - -void disassembler::resolve32_mod1_rm4(unsigned mode) -{ - const char *mod_rm_seg_reg; - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod01_base32[base]; - - print_datasize(mode); - - dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]); - - if (index != 4) - { - dis_sprintf("+%s", index_name32[index]); - if (scale) - dis_sprintf("*%u", 1 << scale); - } - - if (displacement.displ8) - dis_sprintf("+0x%x", (unsigned) displacement.displ8); - - dis_sprintf("]"); -} - -void disassembler::resolve32_mod2_rm4(unsigned mode) -{ - const char *mod_rm_seg_reg; - if (seg_override) - mod_rm_seg_reg = seg_override; - else - mod_rm_seg_reg = sreg_mod10_base32[base]; - - print_datasize(mode); - - dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]); - - if (index != 4) - { - dis_sprintf("+%s", index_name32[index]); - if (scale) - dis_sprintf("*%u", 1 << scale); - } - - if (displacement.displ32) - dis_sprintf("+0x%x", (unsigned) displacement.displ32); - - dis_sprintf("]"); -} +#include "disasm.h" + +extern const char *general_16bit_reg_name[8]; +extern const char *general_32bit_reg_name[8]; + +static const char *sreg_mod01_rm32[8] = { + "ds", "ds", "ds", "ds", "??", "ss", "ds", "ds" +}; + +static const char *sreg_mod10_rm32[8] = { + "ds", "ds", "ds", "ds", "??", "ss", "ds", "ds" +}; + +static const char *sreg_mod00_base32[8] = { + "ds", "ds", "ds", "ds", "ss", "ds", "ds", "ds" +}; + +static const char *sreg_mod01_base32[8] = { + "ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds" +}; + +static const char *sreg_mod10_base32[8] = { + "ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds" +}; + +static const char *sreg_mod00_rm16[8] = { + "ds", "ds", "ss", "ss", "ds", "ds", "ds", "ds" +}; + +static const char *sreg_mod01_rm16[8] = { + "ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds" +}; + +static const char *sreg_mod10_rm16[8] = { + "ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds" +}; + +static const char *intel_index16[8] = { + "bx+si", + "bx+di", + "bp+si", + "bp+di", + "si", + "di", + "bp", + "bx" +}; + +static const char *index_name32[8] = { + "eax", "ecx", "edx", "ebx", "???", "ebp", "esi", "edi" +}; + +void disassembler::decode_modrm() +{ + modrm = fetch_byte(); + BX_DECODE_MODRM(modrm, mod, nnn, rm); + + if (i32bit_addrsize) + { + /* use 32bit addressing modes. orthogonal base & index registers, + scaling available, etc. */ + if (mod == 3) { + /* mod, reg, reg */ + return; + } + else { /* mod != 3 */ + if (rm != 4) { /* rm != 100b, no s-i-b byte */ + // one byte modrm + switch (mod) { + case 0: + resolve_modrm = &disassembler::resolve32_mod0; + if (rm == 5) /* no reg, 32-bit displacement */ + displacement.displ32 = fetch_dword(); + break; + case 1: + /* reg, 8-bit displacement, sign extend */ + resolve_modrm = &disassembler::resolve32_mod1; + displacement.displ32 = (Bit8s) fetch_byte(); + break; + case 2: + /* reg, 32-bit displacement */ + resolve_modrm = &disassembler::resolve32_mod2; + displacement.displ32 = fetch_dword(); + break; + } /* switch (mod) */ + } /* if (rm != 4) */ + else { /* rm == 4, s-i-b byte follows */ + sib = fetch_byte(); + BX_DECODE_SIB(sib, scale, index, base); + + switch (mod) { + case 0: + resolve_modrm = &disassembler::resolve32_mod0_rm4; + if (base == 5) + displacement.displ32 = fetch_dword(); + break; + case 1: + resolve_modrm = &disassembler::resolve32_mod1_rm4; + displacement.displ8 = fetch_byte(); + break; + case 2: + resolve_modrm = &disassembler::resolve32_mod2_rm4; + displacement.displ32 = fetch_dword(); + break; + } + } /* s-i-b byte follows */ + } /* if (mod != 3) */ + } + else { + /* 16 bit addressing modes. */ + switch (mod) { + case 0: + resolve_modrm = &disassembler::resolve16_mod0; + if(rm == 6) + displacement.displ16 = fetch_word(); + break; + case 1: + /* reg, 8-bit displacement, sign extend */ + resolve_modrm = &disassembler::resolve16_mod1; + displacement.displ16 = (Bit8s) fetch_byte(); + break; + case 2: + resolve_modrm = &disassembler::resolve16_mod2; + displacement.displ16 = fetch_word(); + break; + case 3: + /* mod, reg, reg */ + return; + + } /* switch (mod) ... */ + } +} + +void disassembler::print_datasize(unsigned mode) +{ + switch(mode) + { + case B_MODE: + dis_sprintf("byte ptr "); + break; + case W_MODE: + dis_sprintf("word ptr "); + break; + case D_MODE: + dis_sprintf("dword ptr "); + break; + case V_MODE: + if (i32bit_opsize) + dis_sprintf("dword ptr "); + else + dis_sprintf("word ptr "); + break; + case Q_MODE: + dis_sprintf("qword ptr "); + break; + case O_MODE: + dis_sprintf("oword ptr "); + break; + case T_MODE: + dis_sprintf("tword ptr "); + break; + case X_MODE: + break; + }; +} + +void disassembler::resolve16_mod0(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod00_rm16[rm]; + + print_datasize(mode); + + if(rm == 6) + { + dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, (unsigned) displacement.displ16); + } + else + { + dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]); + } +} + +void disassembler::resolve16_mod1(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod01_rm16[rm]; + + print_datasize(mode); + + if (displacement.displ16) + { + dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, + intel_index16[rm], (unsigned) displacement.displ16); + } + else + { + dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]); + } +} + +void disassembler::resolve16_mod2(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod10_rm16[rm]; + + print_datasize(mode); + + if (displacement.displ16) + { + dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, + intel_index16[rm], (unsigned) displacement.displ16); + } + else + { + dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]); + } +} + +void disassembler::resolve32_mod0(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = "ds"; + + print_datasize(mode); + + if (rm == 5) { /* no reg, 32-bit displacement */ + dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, displacement.displ32); + } + else { + dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]); + } +} + +void disassembler::resolve32_mod1(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod01_rm32[rm]; + + print_datasize(mode); + + /* reg, 8-bit displacement, sign extend */ + if (displacement.displ32) + { + dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, + general_32bit_reg_name[rm], (unsigned) displacement.displ32); + } + else + { + dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]); + } +} + +void disassembler::resolve32_mod2(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod10_rm32[rm]; + + print_datasize(mode); + + /* reg, 32-bit displacement */ + if (displacement.displ32) + { + dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg, + general_32bit_reg_name[rm], (unsigned) displacement.displ32); + } + else + { + dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]); + } +} + +void disassembler::resolve32_mod0_rm4(unsigned mode) +{ + const char *mod_rm_seg_reg; + + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod00_base32[base]; + + print_datasize(mode); + + dis_sprintf("%s:[", mod_rm_seg_reg); + if (base != 5) + dis_sprintf("%s+", general_32bit_reg_name[base]); + + if (index != 4) + { + dis_sprintf("%s", index_name32[index]); + if (scale) + dis_sprintf("*%u", 1 << scale); + if (base == 5) dis_sprintf("+"); + } + + if (base == 5) + dis_sprintf("0x%x", (unsigned) displacement.displ32); + + dis_sprintf("]"); +} + +void disassembler::resolve32_mod1_rm4(unsigned mode) +{ + const char *mod_rm_seg_reg; + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod01_base32[base]; + + print_datasize(mode); + + dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]); + + if (index != 4) + { + dis_sprintf("+%s", index_name32[index]); + if (scale) + dis_sprintf("*%u", 1 << scale); + } + + if (displacement.displ8) + dis_sprintf("+0x%x", (unsigned) displacement.displ8); + + dis_sprintf("]"); +} + +void disassembler::resolve32_mod2_rm4(unsigned mode) +{ + const char *mod_rm_seg_reg; + if (seg_override) + mod_rm_seg_reg = seg_override; + else + mod_rm_seg_reg = sreg_mod10_base32[base]; + + print_datasize(mode); + + dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]); + + if (index != 4) + { + dis_sprintf("+%s", index_name32[index]); + if (scale) + dis_sprintf("*%u", 1 << scale); + } + + if (displacement.displ32) + dis_sprintf("+0x%x", (unsigned) displacement.displ32); + + dis_sprintf("]"); +}