(cpu64) Merged bit.cc.

This commit is contained in:
Kevin Lawton 2002-09-15 03:38:52 +00:00
parent 918442ae4a
commit a6ea6659ab
2 changed files with 571 additions and 44 deletions

View File

@ -51,7 +51,6 @@ EXT_DEBUG_OBJS = @EXT_DEBUG_OBJS@
# been synced yet.
OBJS32 = \
paging.o \
bit.o \
string.o \
$(EXT_DEBUG_OBJS) \
@ -104,6 +103,7 @@ OBJSXX = \
ctrl_xfer_pro.o \
segment_ctrl_pro.o \
io.o \
bit.o \
# Objects which are only used for x86-64 code, but which have been

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: bit.cc,v 1.7 2002-09-06 21:54:57 kevinlawton Exp $
// $Id: bit.cc,v 1.8 2002-09-15 03:38:52 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -34,6 +34,19 @@
#if BX_SUPPORT_X86_64==0
// Make life easier merging cpu64 and cpu code.
#define RAX EAX
#define RBX EBX
#define RCX ECX
#define RDX EDX
#define RSP ESP
#define RSI ESI
#define RDI EDI
#define RBP EBP
#endif
void
BX_CPU_C::SETO_Eb(BxInstruction_t *i)
{
@ -50,7 +63,7 @@ BX_CPU_C::SETO_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -74,7 +87,7 @@ BX_CPU_C::SETNO_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -98,7 +111,7 @@ BX_CPU_C::SETB_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -122,7 +135,7 @@ BX_CPU_C::SETNB_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -146,7 +159,7 @@ BX_CPU_C::SETZ_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -170,7 +183,7 @@ BX_CPU_C::SETNZ_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -194,7 +207,7 @@ BX_CPU_C::SETBE_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -218,7 +231,7 @@ BX_CPU_C::SETNBE_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -242,7 +255,7 @@ BX_CPU_C::SETS_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -266,7 +279,7 @@ BX_CPU_C::SETNS_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -290,7 +303,7 @@ BX_CPU_C::SETP_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -314,7 +327,7 @@ BX_CPU_C::SETNP_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -338,7 +351,7 @@ BX_CPU_C::SETL_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -362,7 +375,7 @@ BX_CPU_C::SETNL_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -386,7 +399,7 @@ BX_CPU_C::SETLE_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -410,7 +423,7 @@ BX_CPU_C::SETNLE_Eb(BxInstruction_t *i)
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_8BIT_REG(i->rm, result_8);
BX_WRITE_8BIT_REGx(i->rm, i->extend8bit, result_8);
}
else {
write_virtual_byte(i->seg, i->rm_addr, &result_8);
@ -427,6 +440,38 @@ BX_CPU_C::BSF_GvEv(BxInstruction_t *i)
#else
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64;
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
if (op2_64 == 0) {
set_ZF(1);
/* op1_64 undefined */
return;
}
op1_64 = 0;
while ( (op2_64 & 0x01) == 0 ) {
op1_64++;
op2_64 >>= 1;
}
set_ZF(0);
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn, op1_64);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, op2_32;
@ -454,7 +499,7 @@ BX_CPU_C::BSF_GvEv(BxInstruction_t *i)
set_ZF(0);
/* now write result back to destination */
BX_WRITE_32BIT_REG(i->nnn, op1_32);
BX_WRITE_32BIT_REGZ(i->nnn, op1_32);
}
else { /* 16 bit operand size mode */
Bit16u op1_16, op2_16;
@ -495,6 +540,38 @@ BX_CPU_C::BSR_GvEv(BxInstruction_t *i)
#else
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64;
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
if (op2_64 == 0) {
set_ZF(1);
/* op1_64 undefined */
return;
}
op1_64 = 63;
while ( (op2_64 & BX_CONST64(0x8000000000000000)) == 0 ) {
op1_64--;
op2_64 <<= 1;
}
set_ZF(0);
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn, op1_64);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, op2_32;
@ -522,7 +599,7 @@ BX_CPU_C::BSR_GvEv(BxInstruction_t *i)
set_ZF(0);
/* now write result back to destination */
BX_WRITE_32BIT_REG(i->nnn, op1_32);
BX_WRITE_32BIT_REGZ(i->nnn, op1_32);
}
else { /* 16 bit operand size mode */
Bit16u op1_16, op2_16;
@ -569,7 +646,7 @@ BX_CPU_C::BSWAP_EAX(BxInstruction_t *i)
b2 = eax & 0xff; eax >>= 8;
b3 = eax;
EAX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RAX = (b0<<24) | (b1<<16) | (b2<<8) | b3; // zero extended
#else
BX_PANIC(("BSWAP_EAX: not implemented CPU <= 3"));
#endif
@ -588,7 +665,7 @@ BX_CPU_C::BSWAP_ECX(BxInstruction_t *i)
b2 = ecx & 0xff; ecx >>= 8;
b3 = ecx;
ECX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RCX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_ECX: not implemented CPU <= 3"));
#endif
@ -606,7 +683,7 @@ BX_CPU_C::BSWAP_EDX(BxInstruction_t *i)
b2 = edx & 0xff; edx >>= 8;
b3 = edx;
EDX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RDX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_EDX: not implemented CPU <= 3"));
#endif
@ -624,7 +701,7 @@ BX_CPU_C::BSWAP_EBX(BxInstruction_t *i)
b2 = ebx & 0xff; ebx >>= 8;
b3 = ebx;
EBX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RBX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_EBX: not implemented CPU <= 3"));
#endif
@ -642,7 +719,7 @@ BX_CPU_C::BSWAP_ESP(BxInstruction_t *i)
b2 = esp & 0xff; esp >>= 8;
b3 = esp;
ESP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RSP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_ESP: not implemented CPU <= 3"));
#endif
@ -660,7 +737,7 @@ BX_CPU_C::BSWAP_EBP(BxInstruction_t *i)
b2 = ebp & 0xff; ebp >>= 8;
b3 = ebp;
EBP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RBP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_EBP: not implemented CPU <= 3"));
#endif
@ -678,7 +755,7 @@ BX_CPU_C::BSWAP_ESI(BxInstruction_t *i)
b2 = esi & 0xff; esi >>= 8;
b3 = esi;
ESI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RSI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_ESI: not implemented CPU <= 3"));
#endif
@ -696,21 +773,231 @@ BX_CPU_C::BSWAP_EDI(BxInstruction_t *i)
b2 = edi & 0xff; edi >>= 8;
b3 = edi;
EDI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
RDI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
#else
BX_PANIC(("BSWAP_EDI: not implemented CPU <= 3"));
#endif
}
#if BX_SUPPORT_X86_64
void
BX_CPU_C::BSWAP_RAX(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rax, b0, b1, b2, b3, b4, b5, b6, b7;
rax = RAX;
b0 = rax & 0xff; rax >>= 8;
b1 = rax & 0xff; rax >>= 8;
b2 = rax & 0xff; rax >>= 8;
b3 = rax & 0xff; rax >>= 8;
b4 = rax & 0xff; rax >>= 8;
b5 = rax & 0xff; rax >>= 8;
b6 = rax & 0xff; rax >>= 8;
b7 = rax;
RAX = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b4<<16) | (b4<<8) | b7;
#else
BX_PANIC(("BSWAP_RAX: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RCX(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rcx, b0, b1, b2, b3, b4, b5, b6, b7;
rcx = RCX;
b0 = rcx & 0xff; rcx >>= 8;
b1 = rcx & 0xff; rcx >>= 8;
b2 = rcx & 0xff; rcx >>= 8;
b3 = rcx & 0xff; rcx >>= 8;
b4 = rcx & 0xff; rcx >>= 8;
b5 = rcx & 0xff; rcx >>= 8;
b6 = rcx & 0xff; rcx >>= 8;
b7 = rcx;
RCX = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_ECX: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RDX(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rdx, b0, b1, b2, b3, b4, b5, b6, b7;
rdx = RDX;
b0 = rdx & 0xff; rdx >>= 8;
b1 = rdx & 0xff; rdx >>= 8;
b2 = rdx & 0xff; rdx >>= 8;
b3 = rdx & 0xff; rdx >>= 8;
b4 = rdx & 0xff; rdx >>= 8;
b5 = rdx & 0xff; rdx >>= 8;
b6 = rdx & 0xff; rdx >>= 8;
b7 = rdx;
RDX = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_EDX: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RBX(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rbx, b0, b1, b2, b3, b4, b5, b6, b7;
rbx = RBX;
b0 = rbx & 0xff; rbx >>= 8;
b1 = rbx & 0xff; rbx >>= 8;
b2 = rbx & 0xff; rbx >>= 8;
b3 = rbx & 0xff; rbx >>= 8;
b4 = rbx & 0xff; rbx >>= 8;
b5 = rbx & 0xff; rbx >>= 8;
b6 = rbx & 0xff; rbx >>= 8;
b7 = rbx;
RBX = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_EBX: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RSP(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rsp, b0, b1, b2, b3, b4, b5, b6, b7;
rsp = RSP;
b0 = rsp & 0xff; rsp >>= 8;
b1 = rsp & 0xff; rsp >>= 8;
b2 = rsp & 0xff; rsp >>= 8;
b3 = rsp & 0xff; rsp >>= 8;
b4 = rsp & 0xff; rsp >>= 8;
b5 = rsp & 0xff; rsp >>= 8;
b6 = rsp & 0xff; rsp >>= 8;
b7 = rsp;
RSP = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_ESP: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RBP(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rbp, b0, b1, b2, b3, b4, b5, b6, b7;
rbp = RBP;
b0 = rbp & 0xff; rbp >>= 8;
b1 = rbp & 0xff; rbp >>= 8;
b2 = rbp & 0xff; rbp >>= 8;
b3 = rbp & 0xff; rbp >>= 8;
b4 = rbp & 0xff; rbp >>= 8;
b5 = rbp & 0xff; rbp >>= 8;
b6 = rbp & 0xff; rbp >>= 8;
b7 = rbp;
RBP = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_EBP: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RSI(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rsi, b0, b1, b2, b3, b4, b5, b6, b7;
rsi = RSI;
b0 = rsi & 0xff; rsi >>= 8;
b1 = rsi & 0xff; rsi >>= 8;
b2 = rsi & 0xff; rsi >>= 8;
b3 = rsi & 0xff; rsi >>= 8;
b4 = rsi & 0xff; rsi >>= 8;
b5 = rsi & 0xff; rsi >>= 8;
b6 = rsi & 0xff; rsi >>= 8;
b7 = rsi;
RSI = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_ESI: not implemented CPU <= 3"));
#endif
}
void
BX_CPU_C::BSWAP_RDI(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u rdi, b0, b1, b2, b3, b4, b5, b6, b7;
rdi = RDI;
b0 = rdi & 0xff; rdi >>= 8;
b1 = rdi & 0xff; rdi >>= 8;
b2 = rdi & 0xff; rdi >>= 8;
b3 = rdi & 0xff; rdi >>= 8;
b4 = rdi & 0xff; rdi >>= 8;
b5 = rdi & 0xff; rdi >>= 8;
b6 = rdi & 0xff; rdi >>= 8;
b7 = rdi;
RDI = (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7;
#else
BX_PANIC(("BSWAP_EDI: not implemented CPU <= 3"));
#endif
}
#endif // #if BX_SUPPORT_X86_64
void
BX_CPU_C::BT_EvGv(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("BT_EvGv: not available on <386"));
#else
Bit32u op1_addr;
bx_address op1_addr;
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64;
Bit64s displacement64;
Bit64u index;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
op2_64 &= 0x3f;
set_CF((op1_64 >> op2_64) & 0x01);
return;
}
index = op2_64 & 0x3f;
displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
op1_addr = i->rm_addr + 8 * displacement64;
/* pointer, segment address pair */
read_virtual_qword(i->seg, op1_addr, &op1_64);
set_CF((op1_64 >> index) & 0x01);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, op2_32, index;
@ -769,8 +1056,46 @@ BX_CPU_C::BTS_EvGv(BxInstruction_t *i)
#if BX_CPU_LEVEL < 3
BX_PANIC(("BTS_EvGv: not available on <386"));
#else
Bit32u op1_addr;
bx_address op1_addr;
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, index;
Bit64s displacement64;
Bit64u bit_i;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
op2_64 &= 0x3f;
set_CF((op1_64 >> op2_64) & 0x01);
op1_64 |= (((Bit64u) 1) << op2_64);
/* now write diff back to destination */
BX_WRITE_64BIT_REG(i->rm, op1_64);
return;
}
index = op2_64 & 0x3f;
displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
op1_addr = i->rm_addr + 8 * displacement64;
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, op1_addr, &op1_64);
bit_i = (op1_64 >> index) & 0x01;
op1_64 |= (((Bit64u) 1) << index);
Write_RMW_virtual_qword(op1_64);
set_CF(bit_i);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, op2_32, bit_i, index;
@ -787,7 +1112,7 @@ BX_CPU_C::BTS_EvGv(BxInstruction_t *i)
op1_32 |= (((Bit32u) 1) << op2_32);
/* now write diff back to destination */
BX_WRITE_32BIT_REG(i->rm, op1_32);
BX_WRITE_32BIT_REGZ(i->rm, op1_32);
return;
}
@ -847,9 +1172,48 @@ BX_CPU_C::BTR_EvGv(BxInstruction_t *i)
#if BX_CPU_LEVEL < 3
BX_PANIC(("BTR_EvGv: not available on <386"));
#else
Bit32u op1_addr;
bx_address op1_addr;
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, index;
Bit64s displacement64;
Bit64u temp_cf;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
op2_64 &= 0x3f;
set_CF((op1_64 >> op2_64) & 0x01);
op1_64 &= ~(((Bit64u) 1) << op2_64);
/* now write diff back to destination */
BX_WRITE_64BIT_REG(i->rm, op1_64);
return;
}
index = op2_64 & 0x3f;
displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
op1_addr = i->rm_addr + 8 * displacement64;
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, op1_addr, &op1_64);
temp_cf = (op1_64 >> index) & 0x01;
op1_64 &= ~(((Bit64u) 1) << index);
/* now write back to destination */
Write_RMW_virtual_qword(op1_64);
set_CF(temp_cf);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, op2_32, index, temp_cf;
@ -866,7 +1230,7 @@ BX_CPU_C::BTR_EvGv(BxInstruction_t *i)
op1_32 &= ~(((Bit32u) 1) << op2_32);
/* now write diff back to destination */
BX_WRITE_32BIT_REG(i->rm, op1_32);
BX_WRITE_32BIT_REGZ(i->rm, op1_32);
return;
}
@ -928,8 +1292,49 @@ BX_CPU_C::BTC_EvGv(BxInstruction_t *i)
#if BX_CPU_LEVEL < 3
BX_PANIC(("BTC_EvGv: not available on <386"));
#else
Bit32u op1_addr;
bx_address op1_addr;
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64;
Bit64s displacement64;
Bit64u temp_CF, index;
op2_64 = BX_READ_64BIT_REG(i->nnn);
index = op2_64 & 0x3f;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
op1_addr = 0; // keep compiler happy
}
else {
displacement64 = ((Bit64s) (op2_64 & BX_CONST64(0xffffffffffffffc0))) / 64;
op1_addr = i->rm_addr + 8 * displacement64;
read_RMW_virtual_qword(i->seg, op1_addr, &op1_64);
}
temp_CF = (op1_64 >> index) & 0x01;
// old code not as efficient???
op1_64 &= ~(((Bit64u) 1) << index); /* clear out bit */
op1_64 |= (((Bit64u) !temp_CF) << index); /* set to complement */
//op1_64 ^= (((Bit64u) 1) << index); /* toggle bit wrong??? */
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op1_64);
}
else {
Write_RMW_virtual_qword(op1_64);
}
set_CF(temp_CF);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, op2_32, index_32, temp_CF;
@ -955,7 +1360,7 @@ BX_CPU_C::BTC_EvGv(BxInstruction_t *i)
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_32BIT_REG(i->rm, op1_32);
BX_WRITE_32BIT_REGZ(i->rm, op1_32);
}
else {
Write_RMW_virtual_dword(op1_32);
@ -1003,6 +1408,28 @@ BX_CPU_C::BT_EvIb(BxInstruction_t *i)
BX_PANIC(("BT_EvIb: not available on <386"));
#else
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64;
Bit8u op2_8;
op2_8 = i->Ib & 0x3f;
op2_8 %= 64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
set_CF((op1_64 >> op2_8) & 0x01);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32;
@ -1051,6 +1478,38 @@ BX_CPU_C::BTS_EvIb(BxInstruction_t *i)
BX_PANIC(("BTS_EvIb: not available on <386"));
#else
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, temp_CF;
Bit8u op2_8;
op2_8 = i->Ib;
op2_8 %= 64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
temp_CF = (op1_64 >> op2_8) & 0x01;
op1_64 |= (((Bit64u) 1) << op2_8);
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op1_64);
}
else {
Write_RMW_virtual_qword(op1_64);
}
set_CF(temp_CF);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, temp_CF;
@ -1073,10 +1532,10 @@ BX_CPU_C::BTS_EvIb(BxInstruction_t *i)
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_32BIT_REG(i->rm, op1_32);
BX_WRITE_32BIT_REGZ(i->rm, op1_32);
}
else {
Write_RMW_virtual_dword(op1_32);
write_RMW_virtual_dword(op1_32);
}
set_CF(temp_CF);
}
@ -1105,7 +1564,7 @@ BX_CPU_C::BTS_EvIb(BxInstruction_t *i)
BX_WRITE_16BIT_REG(i->rm, op1_16);
}
else {
Write_RMW_virtual_word(op1_16);
write_RMW_virtual_word(op1_16);
}
set_CF(temp_CF);
}
@ -1119,6 +1578,42 @@ BX_CPU_C::BTC_EvIb(BxInstruction_t *i)
BX_PANIC(("BTC_EvIb: not available on <386"));
#else
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, temp_CF;
Bit8u op2_8;
op2_8 = i->Ib;
op2_8 %= 64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
temp_CF = (op1_64 >> op2_8) & 0x01;
op1_64 &= ~(((Bit64u) 1) << op2_8); /* clear out bit */
op1_64 |= (((Bit64u) !temp_CF) << op2_8); /* set to complement */
//op1_64 ^= (((Bit64u) 1) << op2_8); /* toggle bit */
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op1_64);
}
else {
Write_RMW_virtual_qword(op1_64);
}
set_CF(temp_CF);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, temp_CF;
@ -1143,10 +1638,10 @@ BX_CPU_C::BTC_EvIb(BxInstruction_t *i)
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_32BIT_REG(i->rm, op1_32);
BX_WRITE_32BIT_REGZ(i->rm, op1_32);
}
else {
Write_RMW_virtual_dword(op1_32);
write_RMW_virtual_dword(op1_32);
}
set_CF(temp_CF);
}
@ -1176,7 +1671,7 @@ BX_CPU_C::BTC_EvIb(BxInstruction_t *i)
BX_WRITE_16BIT_REG(i->rm, op1_16);
}
else {
Write_RMW_virtual_word(op1_16);
write_RMW_virtual_word(op1_16);
}
set_CF(temp_CF);
}
@ -1190,6 +1685,38 @@ BX_CPU_C::BTR_EvIb(BxInstruction_t *i)
BX_PANIC(("BTR_EvIb: not available on <386"));
#else
#if BX_SUPPORT_X86_64
if (i->os_64) { /* 64 bit operand size mode */
/* for 64 bit operand size mode */
Bit64u op1_64, temp_CF;
Bit8u op2_8;
op2_8 = i->Ib;
op2_8 %= 64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
temp_CF = (op1_64 >> op2_8) & 0x01;
op1_64 &= ~(((Bit64u) 1) << op2_8);
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op1_64);
}
else {
Write_RMW_virtual_qword(op1_64);
}
set_CF(temp_CF);
}
else
#endif // #if BX_SUPPORT_X86_64
if (i->os_32) { /* 32 bit operand size mode */
/* for 32 bit operand size mode */
Bit32u op1_32, temp_CF;
@ -1212,10 +1739,10 @@ BX_CPU_C::BTR_EvIb(BxInstruction_t *i)
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_32BIT_REG(i->rm, op1_32);
BX_WRITE_32BIT_REGZ(i->rm, op1_32);
}
else {
Write_RMW_virtual_dword(op1_32);
write_RMW_virtual_dword(op1_32);
}
set_CF(temp_CF);
}
@ -1244,7 +1771,7 @@ BX_CPU_C::BTR_EvIb(BxInstruction_t *i)
BX_WRITE_16BIT_REG(i->rm, op1_16);
}
else {
Write_RMW_virtual_word(op1_16);
write_RMW_virtual_word(op1_16);
}
set_CF(temp_CF);
}