(cpu64) Merged bit.cc.
This commit is contained in:
parent
918442ae4a
commit
a6ea6659ab
@ -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
|
||||
|
613
bochs/cpu/bit.cc
613
bochs/cpu/bit.cc
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user