(cpu64) Merged 4 more files.
This commit is contained in:
parent
55510b1e17
commit
6d4b3e0e4d
@ -50,7 +50,6 @@ EXT_DEBUG_OBJS = @EXT_DEBUG_OBJS@
|
||||
# are not used for the x86-64 compile because they have not
|
||||
# been synced yet.
|
||||
OBJS32 = \
|
||||
exception.o \
|
||||
ctrl_xfer_pro.o \
|
||||
flag_ctrl_pro.o \
|
||||
segment_ctrl_pro.o \
|
||||
@ -60,10 +59,7 @@ OBJS32 = \
|
||||
debugstuff.o \
|
||||
arith32.o \
|
||||
mult32.o \
|
||||
data_xfer32.o \
|
||||
stack32.o \
|
||||
ctrl_xfer8.o \
|
||||
data_xfer16.o \
|
||||
bit.o \
|
||||
flag_ctrl.o \
|
||||
io.o \
|
||||
@ -104,6 +100,10 @@ OBJSXX = \
|
||||
logical32.o \
|
||||
arith16.o \
|
||||
segment_ctrl.o \
|
||||
ctrl_xfer8.o \
|
||||
data_xfer16.o \
|
||||
data_xfer32.o \
|
||||
exception.o \
|
||||
|
||||
|
||||
# Objects which are only used for x86-64 code, but which have been
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.51 2002-09-13 21:08:54 kevinlawton Exp $
|
||||
// $Id: cpu.h,v 1.52 2002-09-14 17:29:47 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -668,6 +668,9 @@ typedef struct BxInstruction_tag {
|
||||
Bit64u Iq; // for MOV Rx,imm64
|
||||
unsigned os_64, as_64; // OperandSize/AddressSize is 64bit (overrides os_32/as_32)
|
||||
unsigned extend8bit;
|
||||
#else
|
||||
static const unsigned os_64=0, as_64=0; // x86-32: hardcode to 0.
|
||||
//static const unsigned extend8bit=0; // x86-32: hardcode to 0.
|
||||
#endif
|
||||
unsigned ilen; // instruction length
|
||||
unsigned flags_in, flags_out; // flags needed, flags modified
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer8.cc,v 1.7 2002-09-13 00:15:23 kevinlawton Exp $
|
||||
// $Id: ctrl_xfer8.cc,v 1.8 2002-09-14 17:29:47 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -32,41 +32,61 @@
|
||||
|
||||
|
||||
|
||||
#if BX_SUPPORT_X86_64==0
|
||||
// Make life a little easier for the 64/32-bit merge.
|
||||
#define RCX ECX
|
||||
#define RIP EIP
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::JCXZ_Jb(BxInstruction_t *i)
|
||||
{
|
||||
Bit32u temp_ECX;
|
||||
|
||||
if (i->as_32)
|
||||
temp_ECX = ECX;
|
||||
else
|
||||
temp_ECX = CX;
|
||||
|
||||
if ( temp_ECX == 0 ) {
|
||||
Bit32u new_EIP;
|
||||
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
if (protected_mode()) {
|
||||
if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
|
||||
BX_PANIC(("jcxz_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
if (i->as_64) {
|
||||
if ( RCX == 0 ) {
|
||||
RIP += (Bit32s) i->Id;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_RIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
Bit32u temp_ECX;
|
||||
|
||||
if (i->as_32)
|
||||
temp_ECX = ECX;
|
||||
else
|
||||
temp_ECX = CX;
|
||||
|
||||
if ( temp_ECX == 0 ) {
|
||||
Bit32u new_EIP;
|
||||
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
if (protected_mode()) {
|
||||
if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
|
||||
BX_PANIC(("jcxz_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -74,119 +94,167 @@ BX_CPU_C::JCXZ_Jb(BxInstruction_t *i)
|
||||
void
|
||||
BX_CPU_C::LOOPNE_Jb(BxInstruction_t *i)
|
||||
{
|
||||
Bit32u count, new_EIP;
|
||||
if (i->as_64) {
|
||||
|
||||
if ( ((--RCX)!=0) && (get_ZF()==0) ) {
|
||||
|
||||
RIP += (Bit32s) i->Id;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(RIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
Bit32u count, new_EIP;
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
if (i->as_32)
|
||||
count = ECX;
|
||||
else
|
||||
if (i->as_32)
|
||||
count = ECX;
|
||||
else
|
||||
#endif /* BX_CPU_LEVEL >= 3 */
|
||||
count = CX;
|
||||
count = CX;
|
||||
|
||||
count--;
|
||||
if ( (count!=0) && (get_ZF()==0) ) {
|
||||
count--;
|
||||
if ( (count!=0) && (get_ZF()==0) ) {
|
||||
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
if (protected_mode()) {
|
||||
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_PANIC(("loopne_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
if (protected_mode()) {
|
||||
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_PANIC(("loopne_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i->as_32)
|
||||
ECX--;
|
||||
else
|
||||
CX--;
|
||||
if (i->as_32)
|
||||
RCX = ECX - 1; // zero extend
|
||||
else
|
||||
CX--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::LOOPE_Jb(BxInstruction_t *i)
|
||||
{
|
||||
Bit32u count, new_EIP;
|
||||
if (i->as_64) {
|
||||
|
||||
if ( ((--RCX)!=0) && (get_ZF()) ) {
|
||||
|
||||
RIP += (Bit32s) i->Id;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(RIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
Bit32u count, new_EIP;
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
if (i->as_32)
|
||||
count = ECX;
|
||||
else
|
||||
if (i->as_32)
|
||||
count = ECX;
|
||||
else
|
||||
#endif /* BX_CPU_LEVEL >= 3 */
|
||||
count = CX;
|
||||
count = CX;
|
||||
|
||||
count--;
|
||||
if ( (count!=0) && get_ZF()) {
|
||||
count--;
|
||||
if ( (count!=0) && get_ZF()) {
|
||||
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
if (protected_mode()) {
|
||||
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_PANIC(("loope_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
if (protected_mode()) {
|
||||
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_PANIC(("loope_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i->as_32)
|
||||
ECX--;
|
||||
else
|
||||
CX--;
|
||||
if (i->as_32)
|
||||
RCX = ECX - 1; // zero extend
|
||||
else
|
||||
CX--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::LOOP_Jb(BxInstruction_t *i)
|
||||
{
|
||||
Bit32u count, new_EIP;
|
||||
if (i->as_64) {
|
||||
|
||||
if ( ((--RCX)!=0) ) {
|
||||
|
||||
RIP += (Bit32s) i->Id;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(RIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
Bit32u count, new_EIP;
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
if (i->as_32)
|
||||
count = ECX;
|
||||
else
|
||||
if (i->as_32)
|
||||
count = ECX;
|
||||
else
|
||||
#endif /* BX_CPU_LEVEL >= 3 */
|
||||
count = CX;
|
||||
count = CX;
|
||||
|
||||
count--;
|
||||
if (count != 0) {
|
||||
count--;
|
||||
if (count != 0) {
|
||||
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
if (protected_mode()) {
|
||||
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_PANIC(("loop_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
new_EIP = EIP + (Bit32s) i->Id;
|
||||
if (i->os_32==0)
|
||||
new_EIP &= 0x0000ffff;
|
||||
if (protected_mode()) {
|
||||
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_PANIC(("loop_jb: offset outside of CS limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
EIP = new_EIP;
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
|
||||
revalidate_prefetch_q();
|
||||
}
|
||||
#if BX_INSTRUMENTATION
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
else {
|
||||
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i->as_32)
|
||||
ECX--;
|
||||
else
|
||||
CX--;
|
||||
if (i->as_32)
|
||||
RCX = ECX - 1; // zero extend
|
||||
else
|
||||
CX--;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: data_xfer16.cc,v 1.8 2002-09-06 21:54:57 kevinlawton Exp $
|
||||
// $Id: data_xfer16.cc,v 1.9 2002-09-14 17:29:47 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -37,7 +37,11 @@
|
||||
void
|
||||
BX_CPU_C::MOV_RXIw(BxInstruction_t *i)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_CPU_THIS_PTR gen_reg[i->nnn].word.rx = i->Iw;
|
||||
#else
|
||||
BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = i->Iw;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -46,8 +50,13 @@ BX_CPU_C::XCHG_RXAX(BxInstruction_t *i)
|
||||
Bit16u temp16;
|
||||
|
||||
temp16 = AX;
|
||||
#if BX_SUPPORT_X86_64
|
||||
AX = BX_CPU_THIS_PTR gen_reg[i->nnn].word.rx;
|
||||
BX_CPU_THIS_PTR gen_reg[i->nnn].word.rx = temp16;
|
||||
#else
|
||||
AX = BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
|
||||
BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = temp16;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +109,7 @@ BX_CPU_C::MOV_EwSw(BxInstruction_t *i)
|
||||
if (i->mod == 0xc0) {
|
||||
// ??? BX_WRITE_16BIT_REG(mem_addr, seg_reg);
|
||||
if ( i->os_32 ) {
|
||||
BX_WRITE_32BIT_REG(i->rm, seg_reg);
|
||||
BX_WRITE_32BIT_REGZ(i->rm, seg_reg);
|
||||
}
|
||||
else {
|
||||
BX_WRITE_16BIT_REG(i->rm, seg_reg);
|
||||
@ -157,17 +166,17 @@ BX_CPU_C::LEA_GwM(BxInstruction_t *i)
|
||||
BX_CPU_C::MOV_AXOw(BxInstruction_t *i)
|
||||
{
|
||||
Bit16u temp_16;
|
||||
Bit32u addr_32;
|
||||
bx_address addr;
|
||||
|
||||
addr_32 = i->Id;
|
||||
addr = i->Id;
|
||||
|
||||
/* read from memory address */
|
||||
|
||||
if (!BX_NULL_SEG_REG(i->seg)) {
|
||||
read_virtual_word(i->seg, addr_32, &temp_16);
|
||||
read_virtual_word(i->seg, addr, &temp_16);
|
||||
}
|
||||
else {
|
||||
read_virtual_word(BX_SEG_REG_DS, addr_32, &temp_16);
|
||||
read_virtual_word(BX_SEG_REG_DS, addr, &temp_16);
|
||||
}
|
||||
|
||||
/* write to register */
|
||||
@ -179,19 +188,19 @@ BX_CPU_C::MOV_AXOw(BxInstruction_t *i)
|
||||
BX_CPU_C::MOV_OwAX(BxInstruction_t *i)
|
||||
{
|
||||
Bit16u temp_16;
|
||||
Bit32u addr_32;
|
||||
bx_address addr;
|
||||
|
||||
addr_32 = i->Id;
|
||||
addr = i->Id;
|
||||
|
||||
/* read from register */
|
||||
temp_16 = AX;
|
||||
|
||||
/* write to memory address */
|
||||
if (!BX_NULL_SEG_REG(i->seg)) {
|
||||
write_virtual_word(i->seg, addr_32, &temp_16);
|
||||
write_virtual_word(i->seg, addr, &temp_16);
|
||||
}
|
||||
else {
|
||||
write_virtual_word(BX_SEG_REG_DS, addr_32, &temp_16);
|
||||
write_virtual_word(BX_SEG_REG_DS, addr, &temp_16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +232,7 @@ BX_CPU_C::MOVZX_GwEb(BxInstruction_t *i)
|
||||
Bit8u op2_8;
|
||||
|
||||
if (i->mod == 0xc0) {
|
||||
op2_8 = BX_READ_8BIT_REG(i->rm);
|
||||
op2_8 = BX_READ_8BIT_REGx(i->rm,i->extend8bit);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
@ -265,7 +274,7 @@ BX_CPU_C::MOVSX_GwEb(BxInstruction_t *i)
|
||||
Bit8u op2_8;
|
||||
|
||||
if (i->mod == 0xc0) {
|
||||
op2_8 = BX_READ_8BIT_REG(i->rm);
|
||||
op2_8 = BX_READ_8BIT_REGx(i->rm,i->extend8bit);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: data_xfer32.cc,v 1.9 2002-09-13 00:15:23 kevinlawton Exp $
|
||||
// $Id: data_xfer32.cc,v 1.10 2002-09-14 17:29:47 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -41,14 +41,23 @@ BX_CPU_C::XCHG_ERXEAX(BxInstruction_t *i)
|
||||
Bit32u temp32;
|
||||
|
||||
temp32 = EAX;
|
||||
#if BX_SUPPORT_X86_64
|
||||
RAX = BX_CPU_THIS_PTR gen_reg[i->nnn].dword.erx;
|
||||
BX_CPU_THIS_PTR gen_reg[i->nnn].dword.erx = temp32;
|
||||
#else
|
||||
EAX = BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].dword.erx;
|
||||
BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].dword.erx = temp32;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::MOV_ERXId(BxInstruction_t *i)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_CPU_THIS_PTR gen_reg[i->nnn].rrx = i->Id;
|
||||
#else
|
||||
BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].dword.erx = i->Id;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -62,7 +71,7 @@ BX_CPU_C::MOV_EdGd(BxInstruction_t *i)
|
||||
/* op1_32 is a register or memory reference */
|
||||
/* now write op2 to op1 */
|
||||
if (i->mod == 0xc0) {
|
||||
BX_WRITE_32BIT_REG(i->rm, op2_32);
|
||||
BX_WRITE_32BIT_REGZ(i->rm, op2_32);
|
||||
}
|
||||
else {
|
||||
write_virtual_dword(i->seg, i->rm_addr, &op2_32);
|
||||
@ -83,7 +92,7 @@ BX_CPU_C::MOV_GdEd(BxInstruction_t *i)
|
||||
read_virtual_dword(i->seg, i->rm_addr, &op2_32);
|
||||
}
|
||||
|
||||
BX_WRITE_32BIT_REG(i->nnn, op2_32);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, op2_32);
|
||||
}
|
||||
|
||||
|
||||
@ -97,7 +106,7 @@ BX_CPU_C::LEA_GdM(BxInstruction_t *i)
|
||||
}
|
||||
|
||||
/* write effective address of op2 in op1 */
|
||||
BX_WRITE_32BIT_REG(i->nnn, i->rm_addr);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, i->rm_addr);
|
||||
}
|
||||
|
||||
|
||||
@ -105,21 +114,25 @@ BX_CPU_C::LEA_GdM(BxInstruction_t *i)
|
||||
BX_CPU_C::MOV_EAXOd(BxInstruction_t *i)
|
||||
{
|
||||
Bit32u temp_32;
|
||||
Bit32u addr_32;
|
||||
bx_address addr;
|
||||
|
||||
addr_32 = i->Id;
|
||||
addr = i->Id;
|
||||
|
||||
/* read from memory address */
|
||||
|
||||
if (!BX_NULL_SEG_REG(i->seg)) {
|
||||
read_virtual_dword(i->seg, addr_32, &temp_32);
|
||||
read_virtual_dword(i->seg, addr, &temp_32);
|
||||
}
|
||||
else {
|
||||
read_virtual_dword(BX_SEG_REG_DS, addr_32, &temp_32);
|
||||
read_virtual_dword(BX_SEG_REG_DS, addr, &temp_32);
|
||||
}
|
||||
|
||||
/* write to register */
|
||||
#if BX_SUPPORT_X86_64
|
||||
RAX = temp_32;
|
||||
#else
|
||||
EAX = temp_32;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -127,19 +140,19 @@ BX_CPU_C::MOV_EAXOd(BxInstruction_t *i)
|
||||
BX_CPU_C::MOV_OdEAX(BxInstruction_t *i)
|
||||
{
|
||||
Bit32u temp_32;
|
||||
Bit32u addr_32;
|
||||
bx_address addr;
|
||||
|
||||
addr_32 = i->Id;
|
||||
addr = i->Id;
|
||||
|
||||
/* read from register */
|
||||
temp_32 = EAX;
|
||||
|
||||
/* write to memory address */
|
||||
if (!BX_NULL_SEG_REG(i->seg)) {
|
||||
write_virtual_dword(i->seg, addr_32, &temp_32);
|
||||
write_virtual_dword(i->seg, addr, &temp_32);
|
||||
}
|
||||
else {
|
||||
write_virtual_dword(BX_SEG_REG_DS, addr_32, &temp_32);
|
||||
write_virtual_dword(BX_SEG_REG_DS, addr, &temp_32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +167,7 @@ BX_CPU_C::MOV_EdId(BxInstruction_t *i)
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->mod == 0xc0) {
|
||||
BX_WRITE_32BIT_REG(i->rm, op2_32);
|
||||
BX_WRITE_32BIT_REGZ(i->rm, op2_32);
|
||||
}
|
||||
else {
|
||||
write_virtual_dword(i->seg, i->rm_addr, &op2_32);
|
||||
@ -171,7 +184,7 @@ BX_CPU_C::MOVZX_GdEb(BxInstruction_t *i)
|
||||
Bit8u op2_8;
|
||||
|
||||
if (i->mod == 0xc0) {
|
||||
op2_8 = BX_READ_8BIT_REG(i->rm);
|
||||
op2_8 = BX_READ_8BIT_REGx(i->rm,i->extend8bit);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
@ -179,7 +192,7 @@ BX_CPU_C::MOVZX_GdEb(BxInstruction_t *i)
|
||||
}
|
||||
|
||||
/* zero extend byte op2 into dword op1 */
|
||||
BX_WRITE_32BIT_REG(i->nnn, (Bit32u) op2_8);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, (Bit32u) op2_8);
|
||||
#endif /* BX_CPU_LEVEL < 3 */
|
||||
}
|
||||
|
||||
@ -200,7 +213,7 @@ BX_CPU_C::MOVZX_GdEw(BxInstruction_t *i)
|
||||
}
|
||||
|
||||
/* zero extend word op2 into dword op1 */
|
||||
BX_WRITE_32BIT_REG(i->nnn, (Bit32u) op2_16);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, (Bit32u) op2_16);
|
||||
#endif /* BX_CPU_LEVEL < 3 */
|
||||
}
|
||||
|
||||
@ -213,7 +226,7 @@ BX_CPU_C::MOVSX_GdEb(BxInstruction_t *i)
|
||||
Bit8u op2_8;
|
||||
|
||||
if (i->mod == 0xc0) {
|
||||
op2_8 = BX_READ_8BIT_REG(i->rm);
|
||||
op2_8 = BX_READ_8BIT_REGx(i->rm,i->extend8bit);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
@ -221,7 +234,7 @@ BX_CPU_C::MOVSX_GdEb(BxInstruction_t *i)
|
||||
}
|
||||
|
||||
/* sign extend byte op2 into dword op1 */
|
||||
BX_WRITE_32BIT_REG(i->nnn, (Bit8s) op2_8);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, (Bit8s) op2_8);
|
||||
#endif /* BX_CPU_LEVEL < 3 */
|
||||
}
|
||||
|
||||
@ -242,7 +255,7 @@ BX_CPU_C::MOVSX_GdEw(BxInstruction_t *i)
|
||||
}
|
||||
|
||||
/* sign extend word op2 into dword op1 */
|
||||
BX_WRITE_32BIT_REG(i->nnn, (Bit16s) op2_16);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, (Bit16s) op2_16);
|
||||
#endif /* BX_CPU_LEVEL < 3 */
|
||||
}
|
||||
|
||||
@ -258,7 +271,7 @@ BX_CPU_C::XCHG_EdGd(BxInstruction_t *i)
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->mod == 0xc0) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm);
|
||||
BX_WRITE_32BIT_REG(i->rm, op2_32);
|
||||
BX_WRITE_32BIT_REGZ(i->rm, op2_32);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
@ -266,7 +279,7 @@ BX_CPU_C::XCHG_EdGd(BxInstruction_t *i)
|
||||
Write_RMW_virtual_dword(op2_32);
|
||||
}
|
||||
|
||||
BX_WRITE_32BIT_REG(i->nnn, op1_32);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, op1_32);
|
||||
}
|
||||
|
||||
|
||||
@ -314,7 +327,7 @@ BX_CPU_C::CMOV_GdEd(BxInstruction_t *i)
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
BX_WRITE_32BIT_REG(i->nnn, op2_32);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn, op2_32);
|
||||
}
|
||||
#else
|
||||
BX_INFO(("cmov_gded called"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: exception.cc,v 1.15 2002-09-13 00:15:23 kevinlawton Exp $
|
||||
// $Id: exception.cc,v 1.16 2002-09-14 17:29:47 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -30,7 +30,9 @@
|
||||
#include "bochs.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
|
||||
#if BX_EXTERNAL_DEBUGGER
|
||||
#include "cpu/extdb.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Exception classes. These are used as indexes into the 'is_exception_OK'
|
||||
@ -90,6 +92,238 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
||||
|
||||
// prev_errno = BX_CPU_THIS_PTR errorno;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR msr.lma) {
|
||||
// long mode interrupt
|
||||
|
||||
Bit64u idtindex;
|
||||
Bit32u save_upper;
|
||||
Bit32u dword1, dword2, dword3;
|
||||
|
||||
bx_descriptor_t gate_descriptor, cs_descriptor;
|
||||
bx_selector_t cs_selector;
|
||||
|
||||
Bit16u gate_dest_selector;
|
||||
Bit64u gate_dest_offset;
|
||||
|
||||
// interrupt vector must be within IDT table limits,
|
||||
// else #GP(vector number*16 + 2 + EXT)
|
||||
idtindex = vector*16;
|
||||
if ( (idtindex + 15) > BX_CPU_THIS_PTR idtr.limit) {
|
||||
BX_DEBUG(("IDT.limit = %04x", (unsigned) BX_CPU_THIS_PTR idtr.limit));
|
||||
BX_DEBUG(("IDT.base = %06x", (unsigned) BX_CPU_THIS_PTR idtr.base));
|
||||
BX_DEBUG(("interrupt vector must be within IDT table limits"));
|
||||
BX_DEBUG(("bailing"));
|
||||
BX_DEBUG(("interrupt(): vector > idtr.limit"));
|
||||
|
||||
exception(BX_GP_EXCEPTION, vector*16 + 2, 0);
|
||||
}
|
||||
// descriptor AR byte must indicate interrupt gate, trap gate,
|
||||
// or task gate, else #GP(vector*8 + 2 + EXT)
|
||||
|
||||
idtindex += BX_CPU_THIS_PTR idtr.base;
|
||||
|
||||
access_linear(idtindex, 4, 0,
|
||||
BX_READ, &dword1);
|
||||
access_linear(idtindex + 4, 4, 0,
|
||||
BX_READ, &dword2);
|
||||
access_linear(idtindex + 8, 4, 0,
|
||||
BX_READ, &dword3);
|
||||
|
||||
parse_descriptor(dword1, dword2, &gate_descriptor);
|
||||
|
||||
if ( (gate_descriptor.valid==0) || gate_descriptor.segment) {
|
||||
BX_DEBUG(("interrupt(): gate descriptor is not valid sys seg"));
|
||||
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
||||
}
|
||||
switch (gate_descriptor.type) {
|
||||
//case 5: // task gate
|
||||
//case 6: // 286 interrupt gate
|
||||
//case 7: // 286 trap gate
|
||||
case 14: // 386 interrupt gate
|
||||
case 15: // 386 trap gate
|
||||
break;
|
||||
default:
|
||||
BX_DEBUG(("interrupt(): gate.type(%u) != {5,6,7,14,15}",
|
||||
(unsigned) gate_descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// if software interrupt, then gate descripor DPL must be >= CPL,
|
||||
// else #GP(vector * 8 + 2 + EXT)
|
||||
if (is_INT && (gate_descriptor.dpl < CPL)) {
|
||||
/* ??? */
|
||||
BX_DEBUG(("interrupt(): is_INT && (dpl < CPL)"));
|
||||
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Gate must be present, else #NP(vector * 8 + 2 + EXT)
|
||||
if (gate_descriptor.p == 0) {
|
||||
BX_DEBUG(("interrupt(): p == 0"));
|
||||
exception(BX_NP_EXCEPTION, vector*8 + 2, 0);
|
||||
}
|
||||
gate_dest_selector = gate_descriptor.u.gate386.dest_selector;
|
||||
gate_dest_offset = ((Bit64u)dword3 << 32) +
|
||||
gate_descriptor.u.gate386.dest_offset;
|
||||
|
||||
// examine CS selector and descriptor given in gate descriptor
|
||||
// selector must be non-null else #GP(EXT)
|
||||
if ( (gate_dest_selector & 0xfffc) == 0 ) {
|
||||
BX_PANIC(("int_trap_gate(): selector null"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
parse_selector(gate_dest_selector, &cs_selector);
|
||||
|
||||
// selector must be within its descriptor table limits
|
||||
// else #GP(selector+EXT)
|
||||
fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
|
||||
BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &cs_descriptor);
|
||||
|
||||
// descriptor AR byte must indicate code seg
|
||||
// and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
|
||||
if ( cs_descriptor.valid==0 ||
|
||||
cs_descriptor.segment==0 ||
|
||||
cs_descriptor.u.segment.executable==0 ||
|
||||
cs_descriptor.dpl>CPL
|
||||
) {
|
||||
BX_DEBUG(("interrupt(): not code segment"));
|
||||
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
|
||||
}
|
||||
// check that it's a 64 bit segment
|
||||
if ( cs_descriptor.u.segment.l == 0 ||
|
||||
cs_descriptor.u.segment.d_b == 1) {
|
||||
BX_DEBUG(("interrupt(): must be 64 bit segment"));
|
||||
exception(BX_GP_EXCEPTION, vector, 0);
|
||||
}
|
||||
|
||||
// segment must be present, else #NP(selector + EXT)
|
||||
if ( cs_descriptor.p==0 ) {
|
||||
BX_DEBUG(("interrupt(): segment not present"));
|
||||
exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// if code segment is non-conforming and DPL < CPL then
|
||||
// INTERRUPT TO INNER PRIVILEGE:
|
||||
if ( cs_descriptor.u.segment.c_ed==0 && cs_descriptor.dpl<CPL ) {
|
||||
Bit16u old_SS, old_CS;
|
||||
Bit64u RSP_for_cpl_x, old_RIP, old_RSP;
|
||||
bx_descriptor_t ss_descriptor;
|
||||
bx_selector_t ss_selector;
|
||||
int bytes;
|
||||
|
||||
BX_DEBUG(("interrupt(): INTERRUPT TO INNER PRIVILEGE"));
|
||||
|
||||
// check selector and descriptor for new stack in current TSS
|
||||
get_RSP_from_TSS(cs_descriptor.dpl,&RSP_for_cpl_x);
|
||||
// set up a null descriptor
|
||||
parse_selector(0,&ss_selector);
|
||||
parse_descriptor(0,0,&ss_descriptor);
|
||||
|
||||
|
||||
// 386 int/trap gate
|
||||
// new stack must have room for 40|48 bytes, else #SS(0)
|
||||
//if ( is_error_code )
|
||||
// bytes = 48;
|
||||
//else
|
||||
// bytes = 40;
|
||||
|
||||
|
||||
old_RSP = RSP;
|
||||
|
||||
// load new RSP values from TSS
|
||||
|
||||
load_ss_null(&ss_selector, &ss_descriptor, cs_descriptor.dpl);
|
||||
|
||||
RSP = RSP_for_cpl_x;
|
||||
|
||||
// load new CS:IP values from gate
|
||||
// set CPL to new code segment DPL
|
||||
// set RPL of CS to CPL
|
||||
|
||||
// push long pointer to old stack onto new stack
|
||||
|
||||
// align ESP
|
||||
|
||||
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
|
||||
push_64(old_RSP);
|
||||
|
||||
// push EFLAGS
|
||||
push_64(read_eflags());
|
||||
|
||||
// push long pointer to return address onto new stack
|
||||
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_64(RIP);
|
||||
if ( is_error_code )
|
||||
push_64(error_code);
|
||||
|
||||
load_cs(&cs_selector, &cs_descriptor, cs_descriptor.dpl);
|
||||
RIP = gate_dest_offset;
|
||||
|
||||
|
||||
// if INTERRUPT GATE set IF to 0
|
||||
if ( !(gate_descriptor.type & 1) ) // even is int-gate
|
||||
BX_CPU_THIS_PTR clear_IF ();
|
||||
BX_CPU_THIS_PTR clear_TF ();
|
||||
BX_CPU_THIS_PTR clear_VM ();
|
||||
BX_CPU_THIS_PTR clear_RF ();
|
||||
BX_CPU_THIS_PTR clear_NT ();
|
||||
return;
|
||||
}
|
||||
|
||||
// if code segment is conforming OR code segment DPL = CPL then
|
||||
// INTERRUPT TO SAME PRIVILEGE LEVEL:
|
||||
if ( cs_descriptor.u.segment.c_ed==1 || cs_descriptor.dpl==CPL ) {
|
||||
Bit64u old_RSP;
|
||||
|
||||
|
||||
BX_DEBUG(("int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE"));
|
||||
|
||||
old_RSP = RSP;
|
||||
// align stack
|
||||
RSP = RSP & BX_CONST64(0xfffffffffffffff0);
|
||||
|
||||
// push flags onto stack
|
||||
// push current CS selector onto stack
|
||||
// push return offset onto stack
|
||||
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
|
||||
push_64(old_RSP);
|
||||
push_64(read_eflags());
|
||||
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_64(RIP);
|
||||
if ( is_error_code )
|
||||
push_64(error_code);
|
||||
|
||||
// load CS:IP from gate
|
||||
// load CS descriptor
|
||||
// set the RPL field of CS to CPL
|
||||
load_cs(&cs_selector, &cs_descriptor, CPL);
|
||||
RIP = gate_dest_offset;
|
||||
|
||||
// if interrupt gate then set IF to 0
|
||||
if ( !(gate_descriptor.type & 1) ) // even is int-gate
|
||||
BX_CPU_THIS_PTR clear_IF ();
|
||||
BX_CPU_THIS_PTR clear_TF ();
|
||||
BX_CPU_THIS_PTR clear_VM ();
|
||||
BX_CPU_THIS_PTR clear_RF ();
|
||||
BX_CPU_THIS_PTR clear_NT ();
|
||||
return;
|
||||
}
|
||||
|
||||
// else #GP(CS selector + ext)
|
||||
BX_DEBUG(("interrupt: bad descriptor"));
|
||||
BX_DEBUG(("c_ed=%u, descriptor.dpl=%u, CPL=%u",
|
||||
(unsigned) cs_descriptor.u.segment.c_ed,
|
||||
(unsigned) cs_descriptor.dpl,
|
||||
(unsigned) CPL));
|
||||
BX_DEBUG(("cs.segment = %u", (unsigned) cs_descriptor.segment));
|
||||
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
|
||||
}
|
||||
else
|
||||
#endif // #if BX_SUPPORT_X86_64
|
||||
if(!real_mode()) {
|
||||
Bit32u dword1, dword2;
|
||||
bx_descriptor_t gate_descriptor, cs_descriptor;
|
||||
@ -583,7 +817,11 @@ BX_CPU_C::exception(unsigned vector, Bit16u error_code, Boolean is_INT)
|
||||
}
|
||||
#endif
|
||||
|
||||
//BX_DEBUG(( "::exception(%u)", vector ));
|
||||
//BX_DEBUG (("Exception(%u) code=%08x @%08x%08x", vector, error_code,(Bit32u)(BX_CPU_THIS_PTR prev_eip >>32),(Bit32u)(BX_CPU_THIS_PTR prev_eip)));
|
||||
#if BX_EXTERNAL_DEBUGGER
|
||||
// trap_debugger(1);
|
||||
#endif
|
||||
|
||||
|
||||
BX_INSTR_EXCEPTION(vector);
|
||||
invalidate_prefetch_q();
|
||||
|
Loading…
x
Reference in New Issue
Block a user