Fixes in 64-bit decoding
This commit is contained in:
parent
6d50341985
commit
3ce7764fce
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.301 2006-06-25 21:44:46 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.302 2006-08-11 17:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2569,7 +2569,6 @@ public: // for now...
|
||||
BX_SMF void Resolve64Mod0Rm9(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod0Rm10(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod0Rm11(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod0Rm12(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod0Rm13(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod0Rm14(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod0Rm15(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
@ -2585,7 +2584,6 @@ public: // for now...
|
||||
BX_SMF void Resolve64Mod1or2Rm9(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod1or2Rm10(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod1or2Rm11(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod1or2Rm12(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod1or2Rm13(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod1or2Rm14(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void Resolve64Mod1or2Rm15(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.99 2006-06-26 21:07:44 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.100 2006-08-11 17:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -125,7 +125,7 @@ static BxExecutePtr_tR BxResolve64Mod0[16] = {
|
||||
&BX_CPU_C::Resolve64Mod0Rm9,
|
||||
&BX_CPU_C::Resolve64Mod0Rm10,
|
||||
&BX_CPU_C::Resolve64Mod0Rm11,
|
||||
&BX_CPU_C::Resolve64Mod0Rm12,
|
||||
NULL, // escape to 2-byte
|
||||
&BX_CPU_C::Resolve64Mod0Rm13,
|
||||
&BX_CPU_C::Resolve64Mod0Rm14,
|
||||
&BX_CPU_C::Resolve64Mod0Rm15
|
||||
@ -144,7 +144,7 @@ static BxExecutePtr_tR BxResolve64Mod1or2[16] = {
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm9,
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm10,
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm11,
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm12,
|
||||
NULL, // escape to 2-byte
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm13,
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm14,
|
||||
&BX_CPU_C::Resolve64Mod1or2Rm15
|
||||
@ -2146,7 +2146,7 @@ BX_CPU_C::fetchDecode64(Bit8u *iptr, bxInstruction_c *instruction, unsigned rema
|
||||
// remain must be at least 1
|
||||
|
||||
unsigned b1, b2, ilen=0, attr, lock=0;
|
||||
unsigned imm_mode, offset, rex_r,rex_x,rex_b;
|
||||
unsigned imm_mode, offset, rex_r = 0, rex_x = 0, rex_b = 0;
|
||||
unsigned rm = 0, mod = 0, nnn = 0;
|
||||
#if BX_SUPPORT_SSE >= 4
|
||||
unsigned b3 = 0;
|
||||
@ -2158,9 +2158,6 @@ BX_CPU_C::fetchDecode64(Bit8u *iptr, bxInstruction_c *instruction, unsigned rema
|
||||
unsigned sse_prefix = SSE_PREFIX_NONE;
|
||||
|
||||
offset = 512*1;
|
||||
rex_r = 0;
|
||||
rex_x = 0;
|
||||
rex_b = 0;
|
||||
instruction->ResolveModrm = NULL;
|
||||
instruction->initMetaInfo(BX_SEG_REG_NULL,
|
||||
/*os32*/ 1, // operand size 32 override defaults to 1
|
||||
@ -2306,7 +2303,7 @@ fetch_b1:
|
||||
mod = b2 & 0xc0;
|
||||
nnn = ((b2 >> 3) & 0x07) | rex_r;
|
||||
rm = b2 & 0x07;
|
||||
instruction->modRMForm.modRMData = (b2<<20);
|
||||
instruction->modRMForm.modRMData = (b2<<20);
|
||||
instruction->modRMForm.modRMData |= mod;
|
||||
instruction->modRMForm.modRMData |= (nnn<<8);
|
||||
|
||||
@ -2325,12 +2322,12 @@ fetch_b1:
|
||||
instruction->modRMForm.modRMData |= rm;
|
||||
if (instruction->as64L()) {
|
||||
// 64-bit addressing modes; note that mod==11b handled above
|
||||
if (rm != 4) { // no s-i-b byte
|
||||
if ((rm & 0x7) != 4) { // no s-i-b byte
|
||||
if (mod == 0x00) { // mod == 00b
|
||||
instruction->ResolveModrm = BxResolve64Mod0[rm];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
if (rm == 5) {
|
||||
if ((rm & 0x7) == 5) {
|
||||
if ((ilen+3) < remain) {
|
||||
instruction->modRMForm.displ32u = FetchDWORD(iptr);
|
||||
iptr += 4;
|
||||
@ -2377,7 +2374,7 @@ get_32bit_displ_1:
|
||||
else {
|
||||
return(0);
|
||||
}
|
||||
base = (sib & 0x07) | rex_b; sib >>= 3;
|
||||
base = (sib & 0x07) | rex_b; sib >>= 3;
|
||||
index = (sib & 0x07) | rex_x; sib >>= 3;
|
||||
scale = sib;
|
||||
instruction->modRMForm.modRMData |= (base<<12);
|
||||
@ -2387,7 +2384,7 @@ get_32bit_displ_1:
|
||||
instruction->ResolveModrm = BxResolve64Mod0Base[base];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod0_base32[base]);
|
||||
if (base == 0x05)
|
||||
if ((base & 0x7) == 5)
|
||||
goto get_32bit_displ_1;
|
||||
// mod==00b, rm==4, base!=5
|
||||
goto modrm_done;
|
||||
@ -2406,13 +2403,13 @@ get_32bit_displ_1:
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 32-bit addressing modes; note that mod==11b handled above
|
||||
if (rm != 4) { // no s-i-b byte
|
||||
// 32-bit addressing modes; note that mod==11b handled above
|
||||
if ((rm & 0x7) != 4) { // no s-i-b byte
|
||||
if (mod == 0x00) { // mod == 00b
|
||||
instruction->ResolveModrm = BxResolve32Mod0[rm];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
if (rm == 5) {
|
||||
if ((rm & 0x7) == 5) {
|
||||
if ((ilen+3) < remain) {
|
||||
instruction->modRMForm.displ32u = FetchDWORD(iptr);
|
||||
iptr += 4;
|
||||
@ -2469,7 +2466,7 @@ get_32bit_displ:
|
||||
instruction->ResolveModrm = BxResolve32Mod0Base[base];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod0_base32[base]);
|
||||
if (base == 0x05)
|
||||
if ((base & 0x7) == 5)
|
||||
goto get_32bit_displ;
|
||||
// mod==00b, rm==4, base!=5
|
||||
goto modrm_done;
|
||||
@ -2511,10 +2508,10 @@ modrm_done:
|
||||
|
||||
switch(Group) {
|
||||
case BxGroupN:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn & 0x7]);
|
||||
break;
|
||||
case BxRMGroup:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[rm]);
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[rm & 0x7]);
|
||||
break;
|
||||
#if BX_SUPPORT_SSE >= 4
|
||||
case Bx3ByteOpTable:
|
||||
@ -2540,7 +2537,7 @@ modrm_done:
|
||||
break;
|
||||
case BxFPGroup:
|
||||
if (mod != 0xc0) // mod != 11b
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn & 0x7]);
|
||||
else
|
||||
{
|
||||
int index = (b1-0xD8)*64 + (0x3f & b2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.155 2006-06-26 21:07:44 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.156 2006-08-11 17:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -95,7 +95,8 @@ void BX_CPU_C::HLT(bxInstruction_c *i)
|
||||
BX_PANIC(("HALT instruction encountered in the BIOS ROM"));
|
||||
|
||||
if (!real_mode() && CPL!=0) {
|
||||
BX_ERROR(("HLT: priveledge check failed, generate #GP(0)"));
|
||||
BX_ERROR(("HLT: %s priveledge check failed, CPL=%d, generate #GP(0)",
|
||||
cpu_mode_string(BX_CPU_THIS_PTR cpu_mode), CPL));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: resolve64.cc,v 1.8 2006-03-06 22:03:02 sshwarts Exp $
|
||||
// $Id: resolve64.cc,v 1.9 2006-08-11 17:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -90,22 +90,16 @@ BX_CPU_C::Resolve64Mod0Rm11(bxInstruction_c *i)
|
||||
RMAddr(i) = R11;
|
||||
}
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod0Rm12(bxInstruction_c *i)
|
||||
{
|
||||
RMAddr(i) = R12;
|
||||
}
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod0Rm13(bxInstruction_c *i)
|
||||
{
|
||||
RMAddr(i) = R13;
|
||||
// eip hasn't been bumped yet when this is called. must choose the saved value.
|
||||
RMAddr(i) = BX_CPU_THIS_PTR prev_eip + i->ilen() + (Bit32s)i->displ32u();
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod0Rm14(bxInstruction_c *i)
|
||||
{
|
||||
RMAddr(i) = R14;
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod0Rm15(bxInstruction_c *i)
|
||||
{
|
||||
@ -169,11 +163,6 @@ BX_CPU_C::Resolve64Mod1or2Rm11(bxInstruction_c *i)
|
||||
RMAddr(i) = R11 + (Bit32s) i->displ32u();
|
||||
}
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod1or2Rm12(bxInstruction_c *i)
|
||||
{
|
||||
RMAddr(i) = R12 + (Bit32s) i->displ32u();
|
||||
}
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod1or2Rm13(bxInstruction_c *i)
|
||||
{
|
||||
RMAddr(i) = R13 + (Bit32s) i->displ32u();
|
||||
@ -190,7 +179,6 @@ BX_CPU_C::Resolve64Mod1or2Rm15(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod0Base0(bxInstruction_c *i)
|
||||
{
|
||||
@ -234,9 +222,8 @@ BX_CPU_C::Resolve64Mod0Base4(bxInstruction_c *i)
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::Resolve64Mod0Base5(bxInstruction_c *i)
|
||||
{
|
||||
if (i->sibIndex() != 4) {
|
||||
if (i->sibIndex() != 4)
|
||||
RMAddr(i) = (BX_READ_64BIT_REG(i->sibIndex()) << i->sibScale()) + (Bit32s) i->displ32u();
|
||||
}
|
||||
else
|
||||
RMAddr(i) = (Bit32s) i->displ32u();
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: resolve.cc,v 1.12 2006-06-26 21:06:26 sshwarts Exp $
|
||||
// $Id: resolve.cc,v 1.13 2006-08-11 17:22:43 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "disasm.h"
|
||||
|
||||
void disassembler::decode_modrm(x86_insn *insn)
|
||||
@ -27,7 +28,7 @@ void disassembler::decode_modrm(x86_insn *insn)
|
||||
switch (insn->mod) {
|
||||
case 0:
|
||||
resolve_modrm = &disassembler::resolve64_mod0;
|
||||
if (insn->rm == 5) /* no reg, 32-bit displacement */
|
||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||
insn->displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
case 1:
|
||||
@ -45,11 +46,13 @@ void disassembler::decode_modrm(x86_insn *insn)
|
||||
else { /* rm == 4, s-i-b byte follows */
|
||||
insn->sib = fetch_byte();
|
||||
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
|
||||
insn->base |= insn->rex_b;
|
||||
insn->index |= insn->rex_x;
|
||||
|
||||
switch (insn->mod) {
|
||||
case 0:
|
||||
resolve_modrm = &disassembler::resolve64_mod0_rm4;
|
||||
if (insn->base == 5)
|
||||
if ((insn->base & 7) == 5)
|
||||
insn->displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
case 1:
|
||||
@ -73,7 +76,7 @@ void disassembler::decode_modrm(x86_insn *insn)
|
||||
switch (insn->mod) {
|
||||
case 0:
|
||||
resolve_modrm = &disassembler::resolve32_mod0;
|
||||
if (insn->rm == 5) /* no reg, 32-bit displacement */
|
||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||
insn->displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
case 1:
|
||||
@ -97,7 +100,7 @@ void disassembler::decode_modrm(x86_insn *insn)
|
||||
switch (insn->mod) {
|
||||
case 0:
|
||||
resolve_modrm = &disassembler::resolve32_mod0_rm4;
|
||||
if (insn->base == 5)
|
||||
if ((insn->base & 7) == 5)
|
||||
insn->displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
case 1:
|
||||
@ -112,6 +115,9 @@ void disassembler::decode_modrm(x86_insn *insn)
|
||||
} /* s-i-b byte follows */
|
||||
}
|
||||
else {
|
||||
assert(insn->rex_b == 0);
|
||||
assert(insn->rex_x == 0);
|
||||
assert(insn->rex_r == 0);
|
||||
/* 16 bit addressing modes. */
|
||||
switch (insn->mod) {
|
||||
case 0:
|
||||
@ -169,7 +175,7 @@ void disassembler::resolve32_mod0(const x86_insn *insn, unsigned mode)
|
||||
else
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
if (insn->rm == 5) /* no reg, 32-bit displacement */
|
||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||
print_memory_access(mode, seg, NULL, NULL, 0, insn->displacement.displ32);
|
||||
else
|
||||
print_memory_access(mode, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
|
||||
@ -198,15 +204,13 @@ void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned mode)
|
||||
else
|
||||
seg = sreg_mod00_base32[insn->base];
|
||||
|
||||
if (insn->base != 5)
|
||||
if ((insn->base & 7) != 5)
|
||||
base = general_32bit_regname[insn->base];
|
||||
else
|
||||
disp32 = insn->displacement.displ32;
|
||||
|
||||
if (insn->index != 4)
|
||||
{
|
||||
index = general_32bit_regname[insn->index];
|
||||
}
|
||||
|
||||
print_memory_access(mode, seg, base, index, insn->scale, disp32);
|
||||
}
|
||||
@ -221,9 +225,7 @@ void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode)
|
||||
seg = sreg_mod01or10_base32[insn->base];
|
||||
|
||||
if (insn->index != 4)
|
||||
{
|
||||
index = general_32bit_regname[insn->index];
|
||||
}
|
||||
|
||||
print_memory_access(mode, seg,
|
||||
general_32bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
|
||||
@ -241,7 +243,7 @@ void disassembler::resolve64_mod0(const x86_insn *insn, unsigned mode)
|
||||
if (intel_mode) rip_regname = "rip";
|
||||
else rip_regname = "%rip";
|
||||
|
||||
if (insn->rm == 5) /* no reg, 32-bit displacement */
|
||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||
print_memory_access(mode, seg, rip_regname, NULL, 0, insn->displacement.displ32);
|
||||
else
|
||||
print_memory_access(mode, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
|
||||
@ -270,15 +272,13 @@ void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned mode)
|
||||
else
|
||||
seg = sreg_mod00_base32[insn->base];
|
||||
|
||||
if (insn->base != 5)
|
||||
if ((insn->base & 7) != 5)
|
||||
base = general_64bit_regname[insn->base];
|
||||
else
|
||||
disp32 = insn->displacement.displ32;
|
||||
|
||||
if (insn->index != 4)
|
||||
{
|
||||
index = general_64bit_regname[insn->index];
|
||||
}
|
||||
|
||||
print_memory_access(mode, seg, base, index, insn->scale, disp32);
|
||||
}
|
||||
@ -293,9 +293,7 @@ void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode)
|
||||
seg = sreg_mod01or10_base32[insn->base];
|
||||
|
||||
if (insn->index != 4)
|
||||
{
|
||||
index = general_64bit_regname[insn->index];
|
||||
}
|
||||
|
||||
print_memory_access(mode, seg,
|
||||
general_64bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
|
||||
|
Loading…
Reference in New Issue
Block a user