Changes method of resolving opcode/attributes from group table
New method more flexible and easy to understanding. Reorganizing fetchdecode code and make it more easy and understandable
This commit is contained in:
parent
9c9b054ef9
commit
254ad17328
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: bochs.h,v 1.126 2003-08-25 16:46:18 vruppert Exp $
|
||||
// $Id: bochs.h,v 1.127 2003-08-28 19:25:23 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -232,16 +232,8 @@ int bx_begin_simulation (int argc, char *argv[]);
|
||||
# define BX_DBG_UCMEM_REPORT(addr, size, op, val)
|
||||
#endif // #if BX_DEBUGGER
|
||||
|
||||
extern Bit8u DTPageDirty[];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
# define BX_DYN_DIRTY_PAGE(page) DTPageDirty[page] = 1;
|
||||
#else
|
||||
# define BX_DYN_DIRTY_PAGE(page)
|
||||
#endif
|
||||
|
||||
#define MAGIC_LOGNUM 0x12345678
|
||||
|
||||
|
||||
typedef class BOCHSAPI logfunctions {
|
||||
char *prefix;
|
||||
int type;
|
||||
@ -429,12 +421,6 @@ int bx_gdbstub_check(unsigned int eip);
|
||||
# include "disasm/disasm.h"
|
||||
#endif
|
||||
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
# include "dynamic/dynamic.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
bx_bool floppy;
|
||||
bx_bool keyboard;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.143 2003-08-17 18:55:16 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.144 2003-08-28 19:25:23 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1182,10 +1182,6 @@ class BX_MEM_C;
|
||||
#include "cpu/xmm.h"
|
||||
#endif
|
||||
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
typedef void (*BxDTShim_t)(void);
|
||||
#endif
|
||||
|
||||
class BOCHSAPI BX_CPU_C : public logfunctions {
|
||||
|
||||
public: // for now...
|
||||
@ -1236,30 +1232,8 @@ union {
|
||||
// each fetch/execute cycle.
|
||||
bx_address prev_eip;
|
||||
#endif
|
||||
// A few pointer to functions for use by the dynamic translation
|
||||
// code. Keep them close to the gen_reg declaration, so I can
|
||||
// use an 8bit offset to access them.
|
||||
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
BxDTShim_t DTWrite8vShim;
|
||||
BxDTShim_t DTWrite16vShim;
|
||||
BxDTShim_t DTWrite32vShim;
|
||||
BxDTShim_t DTRead8vShim;
|
||||
BxDTShim_t DTRead16vShim;
|
||||
BxDTShim_t DTRead32vShim;
|
||||
BxDTShim_t DTReadRMW8vShim;
|
||||
BxDTShim_t DTReadRMW16vShim;
|
||||
BxDTShim_t DTReadRMW32vShim;
|
||||
BxDTShim_t DTWriteRMW8vShim;
|
||||
BxDTShim_t DTWriteRMW16vShim;
|
||||
BxDTShim_t DTWriteRMW32vShim;
|
||||
BxDTShim_t DTSetFlagsOSZAPCPtr;
|
||||
BxDTShim_t DTIndBrHandler;
|
||||
BxDTShim_t DTDirBrHandler;
|
||||
#endif
|
||||
|
||||
// status and control flags register set
|
||||
Bit32u lf_flags_status;
|
||||
Bit32u lf_flags_status;
|
||||
bx_flags_reg_t eflags;
|
||||
|
||||
bx_lf_flags_entry oszapc;
|
||||
@ -3130,14 +3104,20 @@ IMPLEMENT_EFLAG_ACCESSOR (TF, 8)
|
||||
#define BxImmediate_Iq 0x000A // 64 bit override
|
||||
#endif
|
||||
|
||||
#define BxPrefix 0x0010 // bit 4
|
||||
#define BxAnother 0x0020 // bit 5
|
||||
#define BxSplitMod11b 0x0040 // bit 6
|
||||
#define BxPrefixSSE 0x0080 // bit 7
|
||||
#define BxLockable 0x0200 // bit 9
|
||||
#define BxRepeatable 0x0800 // bit 11 (pass through to metaInfo field)
|
||||
#define BxRepeatableZF 0x1000 // bit 12 (pass through to metaInfo field)
|
||||
#define BxGroupN 0x0100 // bits 8
|
||||
// Lookup for opcode and attributes in another opcode tables
|
||||
// Totally 7 opcode groups supported
|
||||
#define BxGroupX 0x0070 // bits 6..4: opcode groups definition
|
||||
#define BxGroupN 0x0010 // Group encoding: 001
|
||||
#define BxPrefixSSE 0x0020 // Group encoding: 010
|
||||
#define BxSplitMod11b 0x0030 // Group encoding: 011
|
||||
|
||||
#define BxPrefix 0x0080 // bit 7
|
||||
#define BxAnother 0x0100 // bit 8
|
||||
#define BxLockable 0x0200 // bit 9
|
||||
|
||||
#define BxRepeatable 0x0800 // bit 11 (pass through to metaInfo field)
|
||||
#define BxRepeatableZF 0x1000 // bit 12 (pass through to metaInfo field)
|
||||
|
||||
#define BxGroup1 BxGroupN
|
||||
#define BxGroup2 BxGroupN
|
||||
#define BxGroup3 BxGroupN
|
||||
@ -3156,10 +3136,10 @@ IMPLEMENT_EFLAG_ACCESSOR (TF, 8)
|
||||
|
||||
#if BX_DEBUGGER
|
||||
typedef enum _show_flags {
|
||||
Flag_call = 0x1,
|
||||
Flag_ret = 0x2,
|
||||
Flag_int = 0x4,
|
||||
Flag_iret = 0x8,
|
||||
Flag_call = 0x1,
|
||||
Flag_ret = 0x2,
|
||||
Flag_int = 0x4,
|
||||
Flag_iret = 0x8,
|
||||
Flag_intsig = 0x10
|
||||
} show_flags_t;
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.56 2003-08-15 13:08:23 sshwarts Exp $
|
||||
// $Id: fetchdecode.cc,v 1.57 2003-08-28 19:25:23 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -39,7 +39,6 @@
|
||||
///////////////////////////
|
||||
|
||||
|
||||
|
||||
// sign extended to osize:
|
||||
// 6a push ib
|
||||
// 6b imul gvevib
|
||||
@ -64,7 +63,6 @@
|
||||
// maybe move 16bit only i's like MOV_EwSw, MOV_SwEw
|
||||
// to 32 bit modules.
|
||||
|
||||
// use 0F as a prefix too?
|
||||
|
||||
/* *********** */
|
||||
// LOCK PREFIX //
|
||||
@ -85,22 +83,6 @@
|
||||
|
||||
void BxResolveError(bxInstruction_c *);
|
||||
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
// For 16-bit address mode, this matrix describes the registers
|
||||
// used to formulate the offset, indexed by the RM field.
|
||||
// This info is needed by the dynamic translation code for dataflow.
|
||||
static unsigned BxMemRegsUsed16[8] = {
|
||||
(1<<3) | (1<<6), // BX + SI
|
||||
(1<<3) | (1<<7), // BX + DI
|
||||
(1<<5) | (1<<6), // BP + SI
|
||||
(1<<5) | (1<<7), // BP + DI
|
||||
(1<<6), // SI
|
||||
(1<<7), // DI
|
||||
(1<<5), // BP
|
||||
(1<<3) // BX
|
||||
};
|
||||
#endif
|
||||
|
||||
static BxExecutePtr_tR BxResolve16Mod0[8] = {
|
||||
&BX_CPU_C::Resolve16Mod0Rm0,
|
||||
&BX_CPU_C::Resolve16Mod0Rm1,
|
||||
@ -189,43 +171,43 @@ static BxOpcodeInfo_t opcodesADD_EdId[2] = {
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::ADD_GwEEw },
|
||||
{ 0, &BX_CPU_C::ADD_GwEGw }
|
||||
{ 0, &BX_CPU_C::ADD_GwEEw },
|
||||
{ 0, &BX_CPU_C::ADD_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::ADD_GdEEd },
|
||||
{ 0, &BX_CPU_C::ADD_GdEGd }
|
||||
{ 0, &BX_CPU_C::ADD_GdEEd },
|
||||
{ 0, &BX_CPU_C::ADD_GdEGd }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GbEb[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GbEEb },
|
||||
{ 0, &BX_CPU_C::MOV_GbEGb }
|
||||
{ 0, &BX_CPU_C::MOV_GbEEb },
|
||||
{ 0, &BX_CPU_C::MOV_GbEGb }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GwEEw },
|
||||
{ 0, &BX_CPU_C::MOV_GwEGw }
|
||||
{ 0, &BX_CPU_C::MOV_GwEEw },
|
||||
{ 0, &BX_CPU_C::MOV_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GdEEd },
|
||||
{ 0, &BX_CPU_C::MOV_GdEGd }
|
||||
{ 0, &BX_CPU_C::MOV_GdEEd },
|
||||
{ 0, &BX_CPU_C::MOV_GdEGd }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EbGb[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEbGb },
|
||||
{ 0, &BX_CPU_C::MOV_EGbGb }
|
||||
{ 0, &BX_CPU_C::MOV_EEbGb },
|
||||
{ 0, &BX_CPU_C::MOV_EGbGb }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EwGw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEwGw },
|
||||
{ 0, &BX_CPU_C::MOV_EGwGw }
|
||||
{ 0, &BX_CPU_C::MOV_EEwGw },
|
||||
{ 0, &BX_CPU_C::MOV_EGwGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EdGd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEdGd },
|
||||
{ 0, &BX_CPU_C::MOV_EGdGd }
|
||||
{ 0, &BX_CPU_C::MOV_EEdGd },
|
||||
{ 0, &BX_CPU_C::MOV_EGdGd }
|
||||
};
|
||||
|
||||
|
||||
@ -1549,9 +1531,6 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
/* 0F FF */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
BX_CPU_C::fetchDecode(Bit8u *iptr, bxInstruction_c *instruction,
|
||||
unsigned remain)
|
||||
@ -1563,6 +1542,7 @@ BX_CPU_C::fetchDecode(Bit8u *iptr, bxInstruction_c *instruction,
|
||||
unsigned imm_mode, offset;
|
||||
unsigned rm, mod=0, nnn=0;
|
||||
unsigned sse_prefix;
|
||||
|
||||
#define SSE_PREFIX_NONE 0
|
||||
#define SSE_PREFIX_66 1
|
||||
#define SSE_PREFIX_F2 2
|
||||
@ -1589,29 +1569,7 @@ another_byte:
|
||||
attr = BxOpcodeInfo[b1+offset].Attr;
|
||||
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
|
||||
|
||||
if ( !(attr & BxAnother) ) {
|
||||
// Opcode does not require a MODRM byte.
|
||||
// Note that a 2-byte opcode (0F XX) will jump to before
|
||||
// the if() above after fetching the 2nd byte, so this path is
|
||||
// taken in all cases if a modrm byte is NOT required.
|
||||
instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
|
||||
instruction->IxForm.opcodeReg = b1 & 7;
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
|
||||
instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
|
||||
#endif
|
||||
// Simple instruction, nothing left to do.
|
||||
if (attr == 0) {
|
||||
if (lock) {
|
||||
BX_INFO(("LOCK prefix unallowed (op1=0x%x, attr=0x%x, mod=0x%x, nnn=%u)", b1, attr, mod, nnn));
|
||||
UndefinedOpcode(instruction);
|
||||
}
|
||||
instruction->setB1(b1);
|
||||
instruction->setILen(ilen);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (attr & BxAnother) {
|
||||
if (attr & BxPrefix) {
|
||||
switch (b1) {
|
||||
case 0x66: // OpSize
|
||||
@ -1713,10 +1671,11 @@ another_byte:
|
||||
return(0);
|
||||
|
||||
default:
|
||||
BX_PANIC(("fetch_decode: prefix default = 0x%02x", b1));
|
||||
BX_PANIC(("fetch_decode: prefix default = 0x%02x", b1));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
// opcode requires another byte
|
||||
if (ilen < remain) {
|
||||
ilen++;
|
||||
@ -1747,14 +1706,8 @@ BX_PANIC(("fetch_decode: prefix default = 0x%02x", b1));
|
||||
if (instruction->as32L()) {
|
||||
// 32-bit addressing modes; note that mod==11b handled above
|
||||
if (rm != 4) { // no s-i-b byte
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
|
||||
#endif
|
||||
if (mod == 0x00) { // mod == 00b
|
||||
instruction->ResolveModrm = BxResolve32Mod0[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
if (rm == 5) {
|
||||
@ -1762,9 +1715,6 @@ BX_PANIC(("fetch_decode: prefix default = 0x%02x", b1));
|
||||
instruction->modRMForm.displ32u = FetchDWORD(iptr);
|
||||
iptr += 4;
|
||||
ilen += 4;
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = 0;
|
||||
#endif
|
||||
goto modrm_done;
|
||||
}
|
||||
else return(0);
|
||||
@ -1774,9 +1724,6 @@ BX_PANIC(("fetch_decode: prefix default = 0x%02x", b1));
|
||||
}
|
||||
if (mod == 0x40) { // mod == 01b
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod01_rm32[rm]);
|
||||
get_8bit_displ:
|
||||
@ -1790,9 +1737,6 @@ get_8bit_displ:
|
||||
}
|
||||
// (mod == 0x80) mod == 10b
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod10_rm32[rm]);
|
||||
get_32bit_displ:
|
||||
@ -1819,46 +1763,23 @@ get_32bit_displ:
|
||||
instruction->modRMForm.modRMData |= (base<<12);
|
||||
instruction->modRMForm.modRMData |= (index<<16);
|
||||
instruction->modRMForm.modRMData |= (scale<<4);
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
if (index == 0x04) // 100b
|
||||
instruction->DTMemRegsUsed = 0;
|
||||
else
|
||||
instruction->DTMemRegsUsed = 1<<index;
|
||||
#endif
|
||||
if (mod == 0x00) { // mod==00b, rm==4
|
||||
instruction->ResolveModrm = BxResolve32Mod0Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod0_base32[base]);
|
||||
if (base == 0x05) {
|
||||
if (base == 0x05)
|
||||
goto get_32bit_displ;
|
||||
}
|
||||
// mod==00b, rm==4, base!=5
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed |= 1<<base;
|
||||
#endif
|
||||
goto modrm_done;
|
||||
}
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
// for remaining 32bit cases
|
||||
instruction->DTMemRegsUsed |= 1<<base;
|
||||
#endif
|
||||
if (mod == 0x40) { // mod==01b, rm==4
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod1or2_base32[base]);
|
||||
goto get_8bit_displ;
|
||||
}
|
||||
// (mod == 0x80), mod==10b, rm==4
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod1or2_base32[base]);
|
||||
goto get_32bit_displ;
|
||||
@ -1868,14 +1789,8 @@ get_32bit_displ:
|
||||
// 16-bit addressing modes, mod==11b handled above
|
||||
if (mod == 0x40) { // mod == 01b
|
||||
instruction->ResolveModrm = BxResolve16Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod01_rm16[rm]);
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
|
||||
#endif
|
||||
if (ilen < remain) {
|
||||
// 8 sign extended to 16
|
||||
instruction->modRMForm.displ16u = (Bit8s) *iptr++;
|
||||
@ -1886,14 +1801,8 @@ get_32bit_displ:
|
||||
}
|
||||
if (mod == 0x80) { // mod == 10b
|
||||
instruction->ResolveModrm = BxResolve16Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod10_rm16[rm]);
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
|
||||
#endif
|
||||
if ((ilen+1) < remain) {
|
||||
instruction->modRMForm.displ16u = FetchWORD(iptr);
|
||||
iptr += 2;
|
||||
@ -1904,9 +1813,6 @@ get_32bit_displ:
|
||||
}
|
||||
// mod must be 00b at this point
|
||||
instruction->ResolveModrm = BxResolve16Mod0[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod0[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod00_rm16[rm]);
|
||||
if (rm == 0x06) {
|
||||
@ -1919,76 +1825,59 @@ get_32bit_displ:
|
||||
else return(0);
|
||||
}
|
||||
// mod=00b rm!=6
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
|
||||
#endif
|
||||
}
|
||||
|
||||
modrm_done:
|
||||
if (attr & BxGroupN) {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
|
||||
// get additional attributes from group table
|
||||
attr |= OpcodeInfoPtr[nnn].Attr;
|
||||
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTAttr = 0; // for now
|
||||
#endif
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3 */
|
||||
if (attr & BxPrefixSSE) {
|
||||
int op = sse_prefix_index[sse_prefix];
|
||||
if(op < 0) BX_PANIC(("fetchdecode: SSE opcode with two or more prefixes"));
|
||||
else {
|
||||
OpcodeInfoPtr = OpcodeInfoPtr[nnn].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[op].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[op].Attr;
|
||||
}
|
||||
}
|
||||
// For high frequency opcodes, two variants of the instruction are
|
||||
// implemented; one for the mod=11b case (Reg-Reg), and one for
|
||||
// the other cases (Reg-Mem). If this is one of those cases,
|
||||
// we need to dereference to get to the execute pointer.
|
||||
else { // ! BxPrefixSSE
|
||||
if (attr & BxSplitMod11b) {
|
||||
OpcodeInfoPtr = OpcodeInfoPtr[nnn].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[mod==0xc0].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[mod==0xc0].Attr;
|
||||
}
|
||||
else {
|
||||
instruction->execute = OpcodeInfoPtr[nnn].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[nnn].Attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
|
||||
instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
|
||||
#endif
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3 */
|
||||
if (attr & BxPrefixSSE) {
|
||||
int op = sse_prefix_index[sse_prefix];
|
||||
if(op < 0) BX_PANIC(("fetchdecode: SSE opcode with two or more prefixes"));
|
||||
else {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[op].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[op].Attr;
|
||||
}
|
||||
}
|
||||
// (See note immediately above for comment)
|
||||
else {
|
||||
if (attr & BxSplitMod11b) {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[mod==0xc0].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[mod==0xc0].Attr;
|
||||
}
|
||||
else {
|
||||
instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
|
||||
attr |= BxOpcodeInfo[b1+offset].Attr;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve ExecutePtr and additional opcode Attr
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = &(BxOpcodeInfo[b1+offset]);
|
||||
while(attr & BxGroupX)
|
||||
{
|
||||
Bit32u Group = attr & BxGroupX;
|
||||
attr &= ~BxGroupX;
|
||||
|
||||
switch(Group) {
|
||||
case BxGroupN:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
|
||||
break;
|
||||
case BxPrefixSSE:
|
||||
{
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3) */
|
||||
int op = sse_prefix_index[sse_prefix];
|
||||
if (op < 0) {
|
||||
BX_INFO(("fetchdecode: SSE opcode with two or more prefixes"));
|
||||
UndefinedOpcode(instruction);
|
||||
}
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[op]);
|
||||
break;
|
||||
}
|
||||
case BxSplitMod11b:
|
||||
/* For high frequency opcodes, two variants of the instruction are
|
||||
* implemented; one for the mod=11b case (Reg-Reg), and one for
|
||||
* the other cases (Reg-Mem). If this is one of those cases,
|
||||
* we need to dereference to get to the execute pointer.
|
||||
*/
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[mod==0xc0]);
|
||||
break;
|
||||
default:
|
||||
BX_PANIC(("fetchdecode: Unknown opcode group"));
|
||||
}
|
||||
|
||||
/* get additional attributes from group table */
|
||||
attr |= OpcodeInfoPtr->Attr;
|
||||
}
|
||||
|
||||
instruction->execute = OpcodeInfoPtr->ExecutePtr;
|
||||
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
|
||||
}
|
||||
else {
|
||||
// Opcode does not require a MODRM byte.
|
||||
// Note that a 2-byte opcode (0F XX) will jump to before
|
||||
// the if() above after fetching the 2nd byte, so this path is
|
||||
// taken in all cases if a modrm byte is NOT required.
|
||||
instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
|
||||
instruction->IxForm.opcodeReg = b1 & 7;
|
||||
}
|
||||
|
||||
if (lock) { // lock prefix invalid opcode
|
||||
@ -2000,7 +1889,6 @@ modrm_done:
|
||||
}
|
||||
|
||||
imm_mode = attr & BxImmediate;
|
||||
|
||||
if (imm_mode) {
|
||||
switch (imm_mode) {
|
||||
case BxImmediate_Ib:
|
||||
@ -2113,7 +2001,7 @@ modrm_done:
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BX_INFO(("b1 was %x", b1));
|
||||
BX_INFO(("b1 was %x", b1));
|
||||
BX_PANIC(("fetchdecode: imm_mode = %u", imm_mode));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.54 2003-08-15 13:17:16 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.55 2003-08-28 19:25:23 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -85,22 +85,6 @@
|
||||
|
||||
void BxResolveError(bxInstruction_c *);
|
||||
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
// For 16-bit address mode, this matrix describes the registers
|
||||
// used to formulate the offset, indexed by the RM field.
|
||||
// This info is needed by the dynamic translation code for dataflow.
|
||||
static unsigned BxMemRegsUsed16[8] = {
|
||||
(1<<3) | (1<<6), // BX + SI
|
||||
(1<<3) | (1<<7), // BX + DI
|
||||
(1<<5) | (1<<6), // BP + SI
|
||||
(1<<5) | (1<<7), // BP + DI
|
||||
(1<<6), // SI
|
||||
(1<<7), // DI
|
||||
(1<<5), // BP
|
||||
(1<<3) // BX
|
||||
};
|
||||
#endif
|
||||
|
||||
static BxExecutePtr_tR BxResolve32Mod0[8] = {
|
||||
&BX_CPU_C::Resolve32Mod0Rm0,
|
||||
&BX_CPU_C::Resolve32Mod0Rm1,
|
||||
@ -243,43 +227,43 @@ static BxOpcodeInfo_t opcodesADD_EdId[2] = {
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::ADD_GwEEw },
|
||||
{ 0, &BX_CPU_C::ADD_GwEGw }
|
||||
{ 0, &BX_CPU_C::ADD_GwEEw },
|
||||
{ 0, &BX_CPU_C::ADD_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::ADD_GdEEd },
|
||||
{ 0, &BX_CPU_C::ADD_GdEGd }
|
||||
{ 0, &BX_CPU_C::ADD_GdEEd },
|
||||
{ 0, &BX_CPU_C::ADD_GdEGd }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GbEb[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GbEEb },
|
||||
{ 0, &BX_CPU_C::MOV_GbEGb }
|
||||
{ 0, &BX_CPU_C::MOV_GbEEb },
|
||||
{ 0, &BX_CPU_C::MOV_GbEGb }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GwEEw },
|
||||
{ 0, &BX_CPU_C::MOV_GwEGw }
|
||||
{ 0, &BX_CPU_C::MOV_GwEEw },
|
||||
{ 0, &BX_CPU_C::MOV_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GdEEd },
|
||||
{ 0, &BX_CPU_C::MOV_GdEGd }
|
||||
{ 0, &BX_CPU_C::MOV_GdEEd },
|
||||
{ 0, &BX_CPU_C::MOV_GdEGd }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EbGb[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEbGb },
|
||||
{ 0, &BX_CPU_C::MOV_EGbGb }
|
||||
{ 0, &BX_CPU_C::MOV_EEbGb },
|
||||
{ 0, &BX_CPU_C::MOV_EGbGb }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EwGw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEwGw },
|
||||
{ 0, &BX_CPU_C::MOV_EGwGw }
|
||||
{ 0, &BX_CPU_C::MOV_EEwGw },
|
||||
{ 0, &BX_CPU_C::MOV_EGwGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EdGd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEdGd },
|
||||
{ 0, &BX_CPU_C::MOV_EGdGd }
|
||||
{ 0, &BX_CPU_C::MOV_EEdGd },
|
||||
{ 0, &BX_CPU_C::MOV_EGdGd }
|
||||
};
|
||||
|
||||
|
||||
@ -2379,14 +2363,8 @@ BX_PANIC(("fetch_decode: prefix default = 0x%02x", b1));
|
||||
if (instruction->as64L()) {
|
||||
// 64-bit addressing modes; note that mod==11b handled above
|
||||
if (rm != 4) { // no s-i-b byte
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
|
||||
#endif
|
||||
if (mod == 0x00) { // mod == 00b
|
||||
instruction->ResolveModrm = BxResolve64Mod0[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
ExtendedFieldCheck((rm&8) && ((rm&7)==5)); // KPL
|
||||
@ -2395,9 +2373,6 @@ ExtendedFieldCheck((rm&8) && ((rm&7)==5)); // KPL
|
||||
instruction->modRMForm.displ32u = FetchDWORD(iptr);
|
||||
iptr += 4;
|
||||
ilen += 4;
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = 0;
|
||||
#endif
|
||||
goto modrm_done;
|
||||
}
|
||||
else return(0);
|
||||
@ -2407,9 +2382,6 @@ ExtendedFieldCheck((rm&8) && ((rm&7)==5)); // KPL
|
||||
}
|
||||
if (mod == 0x40) { // mod == 01b
|
||||
instruction->ResolveModrm = BxResolve64Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod01_rm32[rm]);
|
||||
get_8bit_displ_1:
|
||||
@ -2423,9 +2395,6 @@ get_8bit_displ_1:
|
||||
}
|
||||
// (mod == 0x80) mod == 10b
|
||||
instruction->ResolveModrm = BxResolve64Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod10_rm32[rm]);
|
||||
get_32bit_displ_1:
|
||||
@ -2452,47 +2421,24 @@ get_32bit_displ_1:
|
||||
instruction->modRMForm.modRMData |= (base<<12);
|
||||
instruction->modRMForm.modRMData |= (index<<16);
|
||||
instruction->modRMForm.modRMData |= (scale<<4);
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
if (instruction->modRMForm.index == 0x04) // 100b
|
||||
instruction->DTMemRegsUsed = 0;
|
||||
else
|
||||
instruction->DTMemRegsUsed = 1<<instruction->modRMForm.index;
|
||||
#endif
|
||||
if (mod == 0x00) { // mod==00b, rm==4
|
||||
instruction->ResolveModrm = BxResolve64Mod0Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod0_base32[base]);
|
||||
ExtendedFieldCheck((base&8) && ((base&7)==5)); // KPL
|
||||
if (base == 0x05) {
|
||||
if (base == 0x05)
|
||||
goto get_32bit_displ_1;
|
||||
}
|
||||
// mod==00b, rm==4, base!=5
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed |= 1<<base;
|
||||
#endif
|
||||
goto modrm_done;
|
||||
}
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
// for remaining 32bit cases
|
||||
instruction->DTMemRegsUsed |= 1<<base;
|
||||
#endif
|
||||
if (mod == 0x40) { // mod==01b, rm==4
|
||||
instruction->ResolveModrm = BxResolve64Mod1or2Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod1or2_base32[base]);
|
||||
goto get_8bit_displ_1;
|
||||
}
|
||||
// (mod == 0x80), mod==10b, rm==4
|
||||
instruction->ResolveModrm = BxResolve64Mod1or2Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod1or2_base32[base]);
|
||||
goto get_32bit_displ_1;
|
||||
@ -2501,15 +2447,9 @@ ExtendedFieldCheck((base&8) && ((base&7)==5)); // KPL
|
||||
else {
|
||||
// 32-bit addressing modes; note that mod==11b handled above
|
||||
if (rm != 4) { // no s-i-b byte
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
|
||||
#endif
|
||||
if (mod == 0x00) { // mod == 00b
|
||||
ExtendedFieldCheck(rm&8); // KPL
|
||||
instruction->ResolveModrm = BxResolve32Mod0[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
ExtendedFieldCheck((rm&8) && ((rm&7)==5)); // KPL
|
||||
@ -2518,9 +2458,6 @@ ExtendedFieldCheck((rm&8) && ((rm&7)==5)); // KPL
|
||||
instruction->modRMForm.displ32u = FetchDWORD(iptr);
|
||||
iptr += 4;
|
||||
ilen += 4;
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed = 0;
|
||||
#endif
|
||||
goto modrm_done;
|
||||
}
|
||||
else return(0);
|
||||
@ -2531,9 +2468,6 @@ ExtendedFieldCheck((rm&8) && ((rm&7)==5)); // KPL
|
||||
if (mod == 0x40) { // mod == 01b
|
||||
ExtendedFieldCheck(rm&8); // KPL
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod01_rm32[rm]);
|
||||
get_8bit_displ:
|
||||
@ -2548,9 +2482,6 @@ get_8bit_displ:
|
||||
// (mod == 0x80) mod == 10b
|
||||
ExtendedFieldCheck(rm&8); // KPL
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2[rm];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod10_rm32[rm]);
|
||||
get_32bit_displ:
|
||||
@ -2577,40 +2508,20 @@ get_32bit_displ:
|
||||
instruction->modRMForm.modRMData |= (base<<12);
|
||||
instruction->modRMForm.modRMData |= (index<<16);
|
||||
instruction->modRMForm.modRMData |= (scale<<4);
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
if (instruction->modRMForm.index == 0x04) // 100b
|
||||
instruction->DTMemRegsUsed = 0;
|
||||
else
|
||||
instruction->DTMemRegsUsed = 1<<instruction->modRMForm.index;
|
||||
#endif
|
||||
if (mod == 0x00) { // mod==00b, rm==4
|
||||
ExtendedFieldCheck(base&8); // KPL
|
||||
instruction->ResolveModrm = BxResolve32Mod0Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod0_base32[base]);
|
||||
ExtendedFieldCheck((base&8) && ((base&7)==5)); // KPL
|
||||
if (base == 0x05) {
|
||||
if (base == 0x05)
|
||||
goto get_32bit_displ;
|
||||
}
|
||||
// mod==00b, rm==4, base!=5
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTMemRegsUsed |= 1<<base;
|
||||
#endif
|
||||
goto modrm_done;
|
||||
}
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
// for remaining 32bit cases
|
||||
instruction->DTMemRegsUsed |= 1<<base;
|
||||
#endif
|
||||
if (mod == 0x40) { // mod==01b, rm==4
|
||||
ExtendedFieldCheck(base&8); // KPL
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod1or2_base32[base]);
|
||||
goto get_8bit_displ;
|
||||
@ -2618,9 +2529,6 @@ ExtendedFieldCheck(base&8); // KPL
|
||||
// (mod == 0x80), mod==10b, rm==4
|
||||
ExtendedFieldCheck(base&8); // KPL
|
||||
instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
|
||||
#endif
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_CPU_THIS_PTR sreg_mod1or2_base32[base]);
|
||||
goto get_32bit_displ;
|
||||
@ -2628,6 +2536,7 @@ ExtendedFieldCheck(base&8); // KPL
|
||||
}
|
||||
|
||||
modrm_done:
|
||||
|
||||
/*
|
||||
BX_DEBUG (("as_64=%d os_64=%d as_32=%d os_32=%d b1=%04x b2=%04x ofs=%4d rm=%d mod=%d nnn=%d",
|
||||
instruction->as64L(),
|
||||
@ -2640,69 +2549,48 @@ modrm_done:
|
||||
nnn
|
||||
));
|
||||
*/
|
||||
if (attr & BxGroupN) {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = BxOpcodeInfo64[b1+offset].AnotherArray;
|
||||
ExtendedFieldCheck(nnn&8); // KPL
|
||||
// get additional attributes from group table
|
||||
attr |= OpcodeInfoPtr[nnn].Attr;
|
||||
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTAttr = 0; // for now
|
||||
#endif
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3 */
|
||||
if (attr & BxPrefixSSE) {
|
||||
int op = sse_prefix_index[sse_prefix];
|
||||
if(op < 0) BX_PANIC(("fetchdecode: SSE opcode with two or more prefixes"));
|
||||
else {
|
||||
OpcodeInfoPtr = OpcodeInfoPtr[nnn].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[op].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[op].Attr;
|
||||
}
|
||||
}
|
||||
// For high frequency opcodes, two variants of the instruction are
|
||||
// implemented; one for the mod=11b case (Reg-Reg), and one for
|
||||
// the other cases (Reg-Mem). If this is one of those cases,
|
||||
// we need to dereference to get to the execute pointer.
|
||||
else {
|
||||
if (attr & BxSplitMod11b) {
|
||||
OpcodeInfoPtr = OpcodeInfoPtr[nnn].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[mod==0xc0].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[mod==0xc0].Attr;
|
||||
}
|
||||
else {
|
||||
instruction->execute = OpcodeInfoPtr[nnn].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[nnn].Attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
|
||||
instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
|
||||
#endif
|
||||
if (attr & BxPrefixSSE) {
|
||||
int op = sse_prefix_index[sse_prefix];
|
||||
if(op < 0) BX_PANIC(("fetchdecode: SSE opcode with two or more prefixes"));
|
||||
else {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = BxOpcodeInfo64[b1+offset].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[op].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[op].Attr;
|
||||
}
|
||||
}
|
||||
// (See note immediately above for comment)
|
||||
else {
|
||||
if (attr & BxSplitMod11b) {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = BxOpcodeInfo64[b1+offset].AnotherArray;
|
||||
instruction->execute = OpcodeInfoPtr[mod==0xc0].ExecutePtr;
|
||||
attr |= OpcodeInfoPtr[mod==0xc0].Attr;
|
||||
}
|
||||
else {
|
||||
instruction->execute = BxOpcodeInfo64[b1+offset].ExecutePtr;
|
||||
attr |= BxOpcodeInfo64[b1+offset].Attr;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve ExecutePtr and additional opcode Attr
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr = &(BxOpcodeInfo64[b1+offset]);
|
||||
while(attr & BxGroupX)
|
||||
{
|
||||
Bit32u Group = attr & BxGroupX;
|
||||
attr &= ~BxGroupX;
|
||||
|
||||
switch(Group) {
|
||||
case BxGroupN:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
|
||||
break;
|
||||
case BxPrefixSSE:
|
||||
{
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3) */
|
||||
int op = sse_prefix_index[sse_prefix];
|
||||
if (op < 0) {
|
||||
BX_INFO(("fetchdecode: SSE opcode with two or more prefixes"));
|
||||
UndefinedOpcode(instruction);
|
||||
}
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[op]);
|
||||
break;
|
||||
}
|
||||
case BxSplitMod11b:
|
||||
/* For high frequency opcodes, two variants of the instruction are
|
||||
* implemented; one for the mod=11b case (Reg-Reg), and one for
|
||||
* the other cases (Reg-Mem). If this is one of those cases,
|
||||
* we need to dereference to get to the execute pointer.
|
||||
*/
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[mod==0xc0]);
|
||||
break;
|
||||
default:
|
||||
BX_PANIC(("fetchdecode: Unknown opcode group"));
|
||||
}
|
||||
|
||||
/* get additional attributes from group table */
|
||||
attr |= OpcodeInfoPtr->Attr;
|
||||
}
|
||||
|
||||
instruction->execute = OpcodeInfoPtr->ExecutePtr;
|
||||
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
|
||||
}
|
||||
else {
|
||||
// Opcode does not require a MODRM byte.
|
||||
@ -2711,10 +2599,6 @@ ExtendedFieldCheck(nnn&8); // KPL
|
||||
// taken in all cases if a modrm byte is NOT required.
|
||||
instruction->execute = BxOpcodeInfo64[b1+offset].ExecutePtr;
|
||||
instruction->IxForm.opcodeReg = (b1 & 7) | rex_b;
|
||||
#if BX_DYNAMIC_TRANSLATION
|
||||
instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
|
||||
instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (lock) { // lock prefix invalid opcode
|
||||
@ -2726,7 +2610,6 @@ ExtendedFieldCheck(nnn&8); // KPL
|
||||
}
|
||||
|
||||
imm_mode = attr & BxImmediate;
|
||||
|
||||
if (imm_mode) {
|
||||
switch (imm_mode) {
|
||||
case BxImmediate_Ib:
|
||||
@ -2851,7 +2734,7 @@ ExtendedFieldCheck(nnn&8); // KPL
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BX_INFO(("b1 was %x", b1));
|
||||
BX_INFO(("b1 was %x", b1));
|
||||
BX_PANIC(("fetchdecode: imm_mode = %u", imm_mode));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*---------------------------------------------------------------------------+
|
||||
| errors.c |
|
||||
| $Id: errors.c,v 1.10 2003-08-07 18:54:03 sshwarts Exp $
|
||||
| $Id: errors.c,v 1.11 2003-08-28 19:25:23 sshwarts Exp $
|
||||
| |
|
||||
| The error handling functions for wm-FPU-emu |
|
||||
| |
|
||||
@ -29,6 +29,8 @@
|
||||
#include "reg_constant.h"
|
||||
#include "version.h"
|
||||
|
||||
int printk(const char * fmt, ...);
|
||||
|
||||
/* */
|
||||
#undef PRINT_MESSAGES
|
||||
/* */
|
||||
@ -42,7 +44,6 @@ void FPU_illegal(void)
|
||||
math_abort(NULL, SIGILL);
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_WITH_CPU_SIM
|
||||
void FPU_printall(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user