Next step in lazy flags optimization by Darek MihockA -
get rid of shifts from lazy flags code
This commit is contained in:
parent
d739cca282
commit
6fcc7d34ab
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: lazy_flags.cc,v 1.41 2007-12-06 16:57:59 sshwarts Exp $
|
||||
// $Id: lazy_flags.cc,v 1.42 2007-12-06 20:39:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -158,55 +158,6 @@ bx_bool BX_CPU_C::get_CFLazy(void)
|
||||
#endif
|
||||
cf = 0;
|
||||
break;
|
||||
case BX_INSTR_SHR8:
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_8 >>
|
||||
(BX_CPU_THIS_PTR oszapc.op2_8 - 1)) & 0x01;
|
||||
break;
|
||||
case BX_INSTR_SHR16:
|
||||
case BX_INSTR_SHRD16:
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_16 >>
|
||||
(BX_CPU_THIS_PTR oszapc.op2_16 - 1)) & 0x01;
|
||||
break;
|
||||
case BX_INSTR_SHR32:
|
||||
case BX_INSTR_SHRD32:
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_32 >>
|
||||
(BX_CPU_THIS_PTR oszapc.op2_32 - 1)) & 0x01;
|
||||
break;
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_INSTR_SHR64:
|
||||
case BX_INSTR_SHRD64:
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_64 >>
|
||||
(BX_CPU_THIS_PTR oszapc.op2_64 - 1)) & 0x01;
|
||||
break;
|
||||
#endif
|
||||
case BX_INSTR_SHL8:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_8 <= 8) {
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_8 >>
|
||||
(8 - BX_CPU_THIS_PTR oszapc.op2_8)) & 0x01;
|
||||
}
|
||||
else {
|
||||
cf = 0;
|
||||
}
|
||||
break;
|
||||
case BX_INSTR_SHL16:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_16 <= 16) {
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_16 >>
|
||||
(16 - BX_CPU_THIS_PTR oszapc.op2_16)) & 0x01;
|
||||
}
|
||||
else {
|
||||
cf = 0;
|
||||
}
|
||||
break;
|
||||
case BX_INSTR_SHL32:
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_32 >>
|
||||
(32 - BX_CPU_THIS_PTR oszapc.op2_32)) & 0x01;
|
||||
break;
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_INSTR_SHL64:
|
||||
cf = (BX_CPU_THIS_PTR oszapc.op1_64 >>
|
||||
(64 - BX_CPU_THIS_PTR oszapc.op2_64)) & 0x01;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cf = 0; // Keep compiler quiet.
|
||||
BX_PANIC(("get_CF: OSZAPC: unknown instr %u",
|
||||
@ -280,18 +231,7 @@ bx_bool BX_CPU_C::get_AFLazy(void)
|
||||
case BX_INSTR_LOGIC32:
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_INSTR_LOGIC64:
|
||||
case BX_INSTR_SHR64:
|
||||
case BX_INSTR_SHRD64:
|
||||
case BX_INSTR_SHL64:
|
||||
#endif
|
||||
case BX_INSTR_SHR8:
|
||||
case BX_INSTR_SHR16:
|
||||
case BX_INSTR_SHR32:
|
||||
case BX_INSTR_SHRD16:
|
||||
case BX_INSTR_SHRD32:
|
||||
case BX_INSTR_SHL8:
|
||||
case BX_INSTR_SHL16:
|
||||
case BX_INSTR_SHL32:
|
||||
af = 0;
|
||||
break;
|
||||
default:
|
||||
@ -383,76 +323,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
|
||||
#endif
|
||||
of = 0;
|
||||
break;
|
||||
case BX_INSTR_SHR8:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
|
||||
of = (BX_CPU_THIS_PTR oszapc.op1_8 >= 0x80);
|
||||
else
|
||||
of = 0; /* undocumented, but hardware really does it */
|
||||
break;
|
||||
case BX_INSTR_SHR16:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
|
||||
of = (BX_CPU_THIS_PTR oszapc.op1_16 >= 0x8000);
|
||||
else
|
||||
of = 0; /* undocumented, but hardware really does it */
|
||||
break;
|
||||
case BX_INSTR_SHR32:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
|
||||
of = (BX_CPU_THIS_PTR oszapc.op1_32 >= 0x80000000);
|
||||
else
|
||||
of = 0; /* undocumented, but hardware really does it */
|
||||
break;
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_INSTR_SHR64:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_64 == 1)
|
||||
of = (BX_CPU_THIS_PTR oszapc.op1_64 >= BX_CONST64(0x8000000000000000));
|
||||
else
|
||||
of = 0; /* undocumented, but hardware really does it */
|
||||
break;
|
||||
#endif
|
||||
case BX_INSTR_SHRD16:
|
||||
/* undocumented, but this formula works right for any shift count */
|
||||
of = (((result_16 << 1) ^ result_16) & 0x8000) > 0;
|
||||
break;
|
||||
case BX_INSTR_SHRD32:
|
||||
/* undocumented, but this formula works right for any shift count */
|
||||
of = (((result_32 << 1) ^ result_32) & 0x80000000) > 0;
|
||||
break;
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_INSTR_SHRD64:
|
||||
/* undocumented, but this formula works right for any shift count */
|
||||
of = (((result_64 << 1) ^ result_64) & BX_CONST64(0x8000000000000000)) > 0;
|
||||
break;
|
||||
#endif
|
||||
case BX_INSTR_SHL8:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
|
||||
of = ((BX_CPU_THIS_PTR oszapc.op1_8 ^ result_8) & 0x80) > 0;
|
||||
else
|
||||
of = (((BX_CPU_THIS_PTR oszapc.op1_8 <<
|
||||
(BX_CPU_THIS_PTR oszapc.op2_8 - 1)) ^ result_8) & 0x80) > 0;
|
||||
break;
|
||||
case BX_INSTR_SHL16:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
|
||||
of = ((BX_CPU_THIS_PTR oszapc.op1_16 ^ result_16) & 0x8000) > 0;
|
||||
else
|
||||
of = (((BX_CPU_THIS_PTR oszapc.op1_16 <<
|
||||
(BX_CPU_THIS_PTR oszapc.op2_16 - 1)) ^ result_16) & 0x8000) > 0;
|
||||
break;
|
||||
case BX_INSTR_SHL32:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
|
||||
of = ((BX_CPU_THIS_PTR oszapc.op1_32 ^ result_32) & 0x80000000) > 0;
|
||||
else
|
||||
of = (((BX_CPU_THIS_PTR oszapc.op1_32 <<
|
||||
(BX_CPU_THIS_PTR oszapc.op2_32 - 1)) ^ result_32) & 0x80000000) > 0;
|
||||
break;
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_INSTR_SHL64:
|
||||
if (BX_CPU_THIS_PTR oszapc.op2_64 == 1)
|
||||
of = ((BX_CPU_THIS_PTR oszapc.op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0;
|
||||
else
|
||||
of = (((BX_CPU_THIS_PTR oszapc.op1_64 <<
|
||||
(BX_CPU_THIS_PTR oszapc.op2_64 - 1)) ^ result_64) & BX_CONST64(0x8000000000000000)) > 0;
|
||||
break;
|
||||
#endif
|
||||
case BX_INSTR_NEG8:
|
||||
case BX_INSTR_INC8:
|
||||
of = (result_8 == 0x80);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: lazy_flags.h,v 1.28 2007-12-06 16:57:59 sshwarts Exp $
|
||||
// $Id: lazy_flags.h,v 1.29 2007-12-06 20:39:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -79,21 +79,6 @@
|
||||
#define BX_INSTR_LOGIC32 31
|
||||
#define BX_INSTR_LOGIC64 32
|
||||
|
||||
// BX_INSTR_SHRD8 not exists, leave number for alignment
|
||||
#define BX_INSTR_SHRD16 34
|
||||
#define BX_INSTR_SHRD32 35
|
||||
#define BX_INSTR_SHRD64 36
|
||||
|
||||
#define BX_INSTR_SHL8 37
|
||||
#define BX_INSTR_SHL16 38
|
||||
#define BX_INSTR_SHL32 39
|
||||
#define BX_INSTR_SHL64 40
|
||||
|
||||
#define BX_INSTR_SHR8 41
|
||||
#define BX_INSTR_SHR16 42
|
||||
#define BX_INSTR_SHR32 43
|
||||
#define BX_INSTR_SHR64 44
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
#define BX_LF_SIGN_BIT 63
|
||||
#else
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: shift16.cc,v 1.37 2007-12-06 18:35:33 sshwarts Exp $
|
||||
// $Id: shift16.cc,v 1.38 2007-12-06 20:39:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -37,6 +37,7 @@ void BX_CPU_C::SHLD_EwGw(bxInstruction_c *i)
|
||||
Bit16u op1_16, op2_16, result_16;
|
||||
Bit32u temp_32, result_32;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
/* op1:op2 << count. result stored in op1 */
|
||||
if (i->b1() == 0x1a4)
|
||||
@ -56,13 +57,14 @@ void BX_CPU_C::SHLD_EwGw(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (!count) return;
|
||||
// count is 1..31
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* count < 32, since only lower 5 bits used */
|
||||
temp_32 = ((Bit32u)(op1_16) << 16) | (op2_16); // double formed by op1:op2
|
||||
result_32 = temp_32 << count;
|
||||
// Hack to act like x86 SHLD when count > 16
|
||||
|
||||
// hack to act like x86 SHLD when count > 16
|
||||
if (count > 16) {
|
||||
// when count > 16 actually shifting op1:op2:op2 << count,
|
||||
// it is the same as shifting op2:op2 by count-16
|
||||
@ -79,10 +81,11 @@ void BX_CPU_C::SHLD_EwGw(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* SHLD count affects the following flags: O,S,Z,A,P,C
|
||||
*/
|
||||
SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHL16);
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle SF, ZF and AF flags */
|
||||
|
||||
cf = (temp_32 >> (32 - count)) & 0x1;
|
||||
of = cf ^ (result_16 >> 15); // of = cf ^ result15
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHRD_EwGw(bxInstruction_c *i)
|
||||
@ -90,6 +93,7 @@ void BX_CPU_C::SHRD_EwGw(bxInstruction_c *i)
|
||||
Bit16u op1_16, op2_16, result_16;
|
||||
Bit32u temp_32, result_32;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0x1ac)
|
||||
count = i->Ib();
|
||||
@ -108,13 +112,14 @@ void BX_CPU_C::SHRD_EwGw(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (!count) return;
|
||||
// count is 1..31
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
// Hack to act like x86 SHLD when count > 16
|
||||
/* count < 32, since only lower 5 bits used */
|
||||
temp_32 = (op2_16 << 16) | op1_16; // double formed by op2:op1
|
||||
result_32 = temp_32 >> count;
|
||||
|
||||
// hack to act like x86 SHRD when count > 16
|
||||
if (count > 16) {
|
||||
// when count > 16 actually shifting op2:op2:op1 >> count,
|
||||
// it is the same as shifting op2:op2 by count-16
|
||||
@ -131,10 +136,11 @@ void BX_CPU_C::SHRD_EwGw(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* SHRD count affects the following flags: O,S,Z,A,P,C
|
||||
*/
|
||||
SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHRD16);
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle SF, ZF and AF flags */
|
||||
|
||||
cf = (op1_16 >> (count - 1)) & 0x1;
|
||||
of = ((result_16 << 1) ^ result_16) >> 15; // of = result14 ^ result15
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ROL_Ew(bxInstruction_c *i)
|
||||
@ -163,7 +169,7 @@ void BX_CPU_C::ROL_Ew(bxInstruction_c *i)
|
||||
if (count & 0x10) {
|
||||
bit0 = (op1_16 & 0x1);
|
||||
bit15 = (op1_16 >> 15);
|
||||
|
||||
// of = cf ^ result15
|
||||
SET_FLAGS_OxxxxC(bit0 ^ bit15, bit0);
|
||||
}
|
||||
return;
|
||||
@ -181,12 +187,9 @@ void BX_CPU_C::ROL_Ew(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* ROL count affects the following flags: C, O
|
||||
*/
|
||||
bit0 = (result_16 & 0x1);
|
||||
bit15 = (result_16 >> 15);
|
||||
|
||||
// of = cf ^ result15
|
||||
SET_FLAGS_OxxxxC(bit0 ^ bit15, bit0);
|
||||
}
|
||||
|
||||
@ -212,11 +215,11 @@ void BX_CPU_C::ROR_Ew(bxInstruction_c *i)
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if ( (count & 0x0f) == 0 ) {
|
||||
if ( count & 0x10 ) {
|
||||
if ((count & 0x0f) == 0) {
|
||||
if (count & 0x10) {
|
||||
bit14 = (op1_16 >> 14) & 1;
|
||||
bit15 = (op1_16 >> 15) & 1;
|
||||
|
||||
// of = result14 ^ result15
|
||||
SET_FLAGS_OxxxxC(bit14 ^ bit15, bit15);
|
||||
}
|
||||
return;
|
||||
@ -234,12 +237,9 @@ void BX_CPU_C::ROR_Ew(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* ROR count affects the following flags: C, O
|
||||
*/
|
||||
bit14 = (result_16 >> 14) & 1;
|
||||
bit15 = (result_16 >> 15) & 1;
|
||||
|
||||
// of = result14 ^ result15
|
||||
SET_FLAGS_OxxxxC(bit14 ^ bit15, bit15);
|
||||
}
|
||||
|
||||
@ -247,10 +247,11 @@ void BX_CPU_C::RCL_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, result_16;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
if ( i->b1() == 0xc1 )
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib();
|
||||
else if ( i->b1() == 0xd1 )
|
||||
else if (i->b1() == 0xd1)
|
||||
count = 1;
|
||||
else // 0xd3
|
||||
count = CL;
|
||||
@ -287,19 +288,16 @@ void BX_CPU_C::RCL_Ew(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCL count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool temp_CF = (op1_16 >> (16 - count)) & 0x01;
|
||||
|
||||
set_CF(temp_CF);
|
||||
set_OF(temp_CF ^ (result_16 >> 15));
|
||||
cf = (op1_16 >> (16 - count)) & 0x1;
|
||||
of = cf ^ (result_16 >> 15); // of = cf ^ result15
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::RCR_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, result_16;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib();
|
||||
@ -332,18 +330,16 @@ void BX_CPU_C::RCR_Ew(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCR count affects the following flags: C, O
|
||||
*/
|
||||
|
||||
set_CF((op1_16 >> (count - 1)) & 0x01);
|
||||
set_OF((((result_16 << 1) ^ result_16) & 0x8000) > 0);
|
||||
cf = (op1_16 >> (count - 1)) & 0x1;
|
||||
of = ((result_16 << 1) ^ result_16) >> 15; // of = result15 ^ result14
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHL_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, result_16;
|
||||
unsigned count;
|
||||
unsigned of = 0, cf = 0;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib();
|
||||
@ -365,7 +361,14 @@ void BX_CPU_C::SHL_Ew(bxInstruction_c *i)
|
||||
|
||||
if (!count) return;
|
||||
|
||||
result_16 = (op1_16 << count);
|
||||
if (count <= 16) {
|
||||
result_16 = (op1_16 << count);
|
||||
cf = (op1_16 >> (16 - count)) & 0x1;
|
||||
of = cf ^ (result_16 >> 15); // of = cf ^ result15
|
||||
}
|
||||
else {
|
||||
result_16 = 0;
|
||||
}
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
@ -375,13 +378,15 @@ void BX_CPU_C::SHL_Ew(bxInstruction_c *i)
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHL16);
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHR_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, result_16;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib();
|
||||
@ -404,7 +409,6 @@ void BX_CPU_C::SHR_Ew(bxInstruction_c *i)
|
||||
if (!count) return;
|
||||
|
||||
result_16 = (op1_16 >> count);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHR16);
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
@ -413,12 +417,20 @@ void BX_CPU_C::SHR_Ew(bxInstruction_c *i)
|
||||
else {
|
||||
write_RMW_virtual_word(result_16);
|
||||
}
|
||||
|
||||
cf = (op1_16 >> (count - 1)) & 0x1;
|
||||
// note, that of == result15 if count == 1 and
|
||||
// of == 0 if count >= 2
|
||||
of = ((result_16 << 1) ^ result_16) >> 15;
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SAR_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, result_16;
|
||||
unsigned count;
|
||||
unsigned count, cf;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib();
|
||||
@ -448,8 +460,7 @@ void BX_CPU_C::SAR_Ew(bxInstruction_c *i)
|
||||
result_16 = (op1_16 >> count);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle undefined SF, ZF and AF flags */
|
||||
set_CF((op1_16 >> (count - 1)) & 0x1);
|
||||
cf = (op1_16 >> (count - 1)) & 0x1;
|
||||
}
|
||||
else {
|
||||
if (op1_16 & 0x8000) {
|
||||
@ -459,11 +470,12 @@ void BX_CPU_C::SAR_Ew(bxInstruction_c *i)
|
||||
result_16 = 0;
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle undefined SF, ZF and AF flags */
|
||||
set_CF(result_16 & 0x1);
|
||||
cf = (result_16 & 0x1);
|
||||
}
|
||||
|
||||
clear_OF(); /* signed overflow cannot happen in SAR instruction */
|
||||
SET_FLAGS_OSZAPC_LOGIC_16(result_16); /* handle SF, ZF and AF flags */
|
||||
/* signed overflow cannot happen in SAR instruction */
|
||||
SET_FLAGS_OxxxxC(0, cf);
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: shift32.cc,v 1.36 2007-12-06 16:57:59 sshwarts Exp $
|
||||
// $Id: shift32.cc,v 1.37 2007-12-06 20:39:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -36,8 +36,7 @@ void BX_CPU_C::SHLD_EdGd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, op2_32, result_32;
|
||||
unsigned count;
|
||||
|
||||
/* op1:op2 << count. result stored in op1 */
|
||||
unsigned of, cf;
|
||||
|
||||
if (i->b1() == 0x1a4)
|
||||
count = i->Ib();
|
||||
@ -69,16 +68,18 @@ void BX_CPU_C::SHLD_EdGd(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* SHLD count affects the following flags: O,S,Z,A,P,C
|
||||
*/
|
||||
SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHL32);
|
||||
SET_FLAGS_OSZAPC_LOGIC_32(result_32); /* handle SF, ZF and AF flags */
|
||||
|
||||
cf = (op1_32 >> (32 - count)) & 0x1;
|
||||
of = cf ^ (result_32 >> 31); // of = cf ^ result31
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHRD_EdGd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, op2_32, result_32;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0x1ac)
|
||||
count = i->Ib();
|
||||
@ -110,16 +111,18 @@ void BX_CPU_C::SHRD_EdGd(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* SHRD count affects the following flags: O,S,Z,A,P,C
|
||||
*/
|
||||
SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHRD32);
|
||||
SET_FLAGS_OSZAPC_LOGIC_32(result_32); /* handle SF, ZF and AF flags */
|
||||
|
||||
cf = (op1_32 >> (count - 1)) & 0x1;
|
||||
of = ((result_32 << 1) ^ result_32) >> 31; // of = result30 ^ result31
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ROL_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, result_32;
|
||||
unsigned count;
|
||||
unsigned bit0, bit31;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x1f;
|
||||
@ -149,19 +152,17 @@ void BX_CPU_C::ROL_Ed(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* ROL count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool temp_CF = (result_32 & 0x01);
|
||||
|
||||
set_CF(temp_CF);
|
||||
set_OF(temp_CF ^ (result_32 >> 31));
|
||||
bit0 = (result_32 & 0x1);
|
||||
bit31 = (result_32 >> 31);
|
||||
// of = cf ^ result31
|
||||
SET_FLAGS_OxxxxC(bit0 ^ bit31, bit0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ROR_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, result_32;
|
||||
unsigned count;
|
||||
unsigned bit31, bit30;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x1f;
|
||||
@ -191,20 +192,17 @@ void BX_CPU_C::ROR_Ed(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* ROR count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool result_b31 = (result_32 & 0x80000000) != 0;
|
||||
bx_bool result_b30 = (result_32 & 0x40000000) != 0;
|
||||
|
||||
set_CF(result_b31);
|
||||
set_OF(result_b31 ^ result_b30);
|
||||
bit31 = (result_32 >> 31) & 1;
|
||||
bit30 = (result_32 >> 30) & 1;
|
||||
// of = result30 ^ result31
|
||||
SET_FLAGS_OxxxxC(bit30 ^ bit31, bit31);
|
||||
}
|
||||
|
||||
void BX_CPU_C::RCL_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, result_32;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x1f;
|
||||
@ -240,19 +238,16 @@ void BX_CPU_C::RCL_Ed(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCL count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool temp_CF = (op1_32 >> (32 - count)) & 0x01;
|
||||
|
||||
set_CF(temp_CF);
|
||||
set_OF(temp_CF ^ (result_32 >> 31));
|
||||
cf = (op1_32 >> (32 - count)) & 0x1;
|
||||
of = cf ^ (result_32 >> 31); // of = cf ^ result31
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::RCR_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, result_32;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x1f;
|
||||
@ -288,18 +283,17 @@ void BX_CPU_C::RCR_Ed(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCR count affects the following flags: C, O
|
||||
*/
|
||||
cf = (op1_32 >> (count - 1)) & 0x1;
|
||||
of = ((result_32 << 1) ^ result_32) >> 31; // of = result30 ^ result31
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
|
||||
set_CF((op1_32 >> (count - 1)) & 0x01);
|
||||
set_OF((((result_32 << 1) ^ result_32) & 0x80000000) > 0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHL_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, result_32;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x1f;
|
||||
@ -319,7 +313,10 @@ void BX_CPU_C::SHL_Ed(bxInstruction_c *i)
|
||||
|
||||
if (!count) return;
|
||||
|
||||
/* count < 32, since only lower 5 bits used */
|
||||
result_32 = (op1_32 << count);
|
||||
cf = (op1_32 >> (32 - count)) & 0x1;
|
||||
of = cf ^ (result_32 >> 31);
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
@ -329,13 +326,15 @@ void BX_CPU_C::SHL_Ed(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHL32);
|
||||
SET_FLAGS_OSZAPC_LOGIC_32(result_32); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHR_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, result_32;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x1f;
|
||||
@ -356,7 +355,6 @@ void BX_CPU_C::SHR_Ed(bxInstruction_c *i)
|
||||
if (!count) return;
|
||||
|
||||
result_32 = (op1_32 >> count);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHR32);
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
@ -365,6 +363,14 @@ void BX_CPU_C::SHR_Ed(bxInstruction_c *i)
|
||||
else {
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
cf = (op1_32 >> (count - 1)) & 0x1;
|
||||
// note, that of == result31 if count == 1 and
|
||||
// of == 0 if count >= 2
|
||||
of = ((result_32 << 1) ^ result_32) >> 31;
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_32(result_32); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SAR_Ed(bxInstruction_c *i)
|
||||
@ -406,7 +412,7 @@ void BX_CPU_C::SAR_Ed(bxInstruction_c *i)
|
||||
write_RMW_virtual_dword(result_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_32(result_32); /* handle undefined SF, ZF and AF flags */
|
||||
SET_FLAGS_OSZAPC_LOGIC_32(result_32); /* handle SF, ZF and AF flags */
|
||||
set_CF((op1_32 >> (count - 1)) & 1);
|
||||
clear_OF(); /* signed overflow cannot happen in SAR instruction */
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: shift64.cc,v 1.26 2007-12-06 18:35:33 sshwarts Exp $
|
||||
// $Id: shift64.cc,v 1.27 2007-12-06 20:39:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -38,8 +38,7 @@ void BX_CPU_C::SHLD_EqGq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, op2_64, result_64;
|
||||
unsigned count;
|
||||
|
||||
/* op1:op2 << count. result stored in op1 */
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0x1a4)
|
||||
count = i->Ib();
|
||||
@ -71,16 +70,18 @@ void BX_CPU_C::SHLD_EqGq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* SHLD count affects the following flags: O,S,Z,A,P,C
|
||||
*/
|
||||
SET_FLAGS_OSZAPC_64(op1_64, count, result_64, BX_INSTR_SHL64);
|
||||
SET_FLAGS_OSZAPC_LOGIC_64(result_64); /* handle SF, ZF and AF flags */
|
||||
|
||||
cf = (op1_64 >> (64 - count)) & 0x1;
|
||||
of = cf ^ (result_64 >> 63); // of = cf ^ result63
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHRD_EqGq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, op2_64, result_64;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0x1ac)
|
||||
count = i->Ib();
|
||||
@ -112,16 +113,18 @@ void BX_CPU_C::SHRD_EqGq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* SHRD count affects the following flags: O,S,Z,A,P,C
|
||||
*/
|
||||
SET_FLAGS_OSZAPC_64(op1_64, count, result_64, BX_INSTR_SHRD64);
|
||||
SET_FLAGS_OSZAPC_LOGIC_64(result_64); /* handle SF, ZF and AF flags */
|
||||
|
||||
cf = (op1_64 >> (count - 1)) & 0x1;
|
||||
of = ((result_64 << 1) ^ result_64) >> 63; // of = result62 ^ result63
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ROL_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, result_64;
|
||||
unsigned count;
|
||||
unsigned bit0, bit63;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x3f;
|
||||
@ -151,19 +154,17 @@ void BX_CPU_C::ROL_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* ROL count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool temp_CF = (result_64 & 0x01);
|
||||
|
||||
set_CF(temp_CF);
|
||||
set_OF(temp_CF ^ (result_64 >> 63));
|
||||
bit0 = (result_64 & 0x1);
|
||||
bit63 = (result_64 >> 63);
|
||||
// of = cf ^ result63
|
||||
SET_FLAGS_OxxxxC(bit0 ^ bit63, bit0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ROR_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, result_64;
|
||||
Bit64u op1_64, result_64;
|
||||
unsigned count;
|
||||
unsigned bit62, bit63;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x3f;
|
||||
@ -193,20 +194,17 @@ void BX_CPU_C::ROR_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* ROR count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool result_b63 = (result_64 & BX_CONST64(0x8000000000000000)) != 0;
|
||||
bx_bool result_b62 = (result_64 & BX_CONST64(0x4000000000000000)) != 0;
|
||||
|
||||
set_CF(result_b63);
|
||||
set_OF(result_b63 ^ result_b62);
|
||||
bit63 = (result_64 >> 63) & 1;
|
||||
bit62 = (result_64 >> 62) & 1;
|
||||
// of = result62 ^ result63
|
||||
SET_FLAGS_OxxxxC(bit62 ^ bit63, bit63);
|
||||
}
|
||||
|
||||
void BX_CPU_C::RCL_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, result_64;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x3f;
|
||||
@ -242,19 +240,16 @@ void BX_CPU_C::RCL_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCL count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool temp_CF = (op1_64 >> (64 - count)) & 0x01;
|
||||
|
||||
set_CF(temp_CF);
|
||||
set_OF(temp_CF ^ (result_64 >> 63));
|
||||
cf = (op1_64 >> (64 - count)) & 0x1;
|
||||
of = cf ^ (result_64 >> 63); // of = cf ^ result63
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::RCR_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, result_64;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x3f;
|
||||
@ -290,18 +285,16 @@ void BX_CPU_C::RCR_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCR count affects the following flags: C, O
|
||||
*/
|
||||
|
||||
set_CF((op1_64 >> (count - 1)) & 0x01);
|
||||
set_OF((((result_64 << 1) ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
|
||||
cf = (op1_64 >> (count - 1)) & 0x1;
|
||||
of = ((result_64 << 1) ^ result_64) >> 63;
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHL_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, result_64;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x3f;
|
||||
@ -321,7 +314,10 @@ void BX_CPU_C::SHL_Eq(bxInstruction_c *i)
|
||||
|
||||
if (!count) return;
|
||||
|
||||
/* count < 64, since only lower 6 bits used */
|
||||
result_64 = (op1_64 << count);
|
||||
cf = (op1_64 >> (64 - count)) & 0x1;
|
||||
of = cf ^ (result_64 >> 63);
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
@ -331,13 +327,15 @@ void BX_CPU_C::SHL_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_64(op1_64, count, result_64, BX_INSTR_SHL64);
|
||||
SET_FLAGS_OSZAPC_LOGIC_64(result_64); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHR_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64, result_64;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc1)
|
||||
count = i->Ib() & 0x3f;
|
||||
@ -367,7 +365,13 @@ void BX_CPU_C::SHR_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_64(op1_64, count, result_64, BX_INSTR_SHR64);
|
||||
cf = (op1_64 >> (count - 1)) & 0x1;
|
||||
// note, that of == result63 if count == 1 and
|
||||
// of == 0 if count >= 2
|
||||
of = ((result_64 << 1) ^ result_64) >> 63;
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_64(result_64); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SAR_Eq(bxInstruction_c *i)
|
||||
@ -393,7 +397,7 @@ void BX_CPU_C::SAR_Eq(bxInstruction_c *i)
|
||||
|
||||
if (!count) return;
|
||||
|
||||
/* count < 64, since only lower 5 bits used */
|
||||
/* count < 64, since only lower 6 bits used */
|
||||
if (op1_64 & BX_CONST64(0x8000000000000000)) {
|
||||
result_64 = (op1_64 >> count) | (BX_CONST64(0xffffffffffffffff) << (64 - count));
|
||||
}
|
||||
@ -409,7 +413,7 @@ void BX_CPU_C::SAR_Eq(bxInstruction_c *i)
|
||||
write_RMW_virtual_qword(result_64);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_64(result_64); /* handle undefined SF, ZF and AF flags */
|
||||
SET_FLAGS_OSZAPC_LOGIC_64(result_64); /* handle SF, ZF and AF flags */
|
||||
set_CF((op1_64 >> (count - 1)) & 1);
|
||||
clear_OF(); /* signed overflow cannot happen in SAR instruction */
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: shift8.cc,v 1.30 2007-12-06 18:35:33 sshwarts Exp $
|
||||
// $Id: shift8.cc,v 1.31 2007-12-06 20:39:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -63,7 +63,7 @@ void BX_CPU_C::ROL_Eb(bxInstruction_c *i)
|
||||
return;
|
||||
}
|
||||
|
||||
count &= 0x07; // use only lowest 3 bits
|
||||
count &= 0x7; // use only lowest 3 bits
|
||||
|
||||
result_8 = (op1_8 << count) | (op1_8 >> (8 - count));
|
||||
|
||||
@ -116,7 +116,8 @@ void BX_CPU_C::ROR_Eb(bxInstruction_c *i)
|
||||
}
|
||||
return;
|
||||
}
|
||||
count &= 0x07; /* use only bottom 3 bits */
|
||||
|
||||
count &= 0x7; /* use only bottom 3 bits */
|
||||
|
||||
result_8 = (op1_8 >> count) | (op1_8 << (8 - count));
|
||||
|
||||
@ -142,6 +143,7 @@ void BX_CPU_C::RCL_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, result_8;
|
||||
unsigned count;
|
||||
unsigned of, cf;
|
||||
|
||||
if (i->b1() == 0xc0)
|
||||
count = i->Ib();
|
||||
@ -179,19 +181,16 @@ void BX_CPU_C::RCL_Eb(bxInstruction_c *i)
|
||||
write_RMW_virtual_byte(result_8);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCL count affects the following flags: C, O
|
||||
*/
|
||||
bx_bool temp_CF = (op1_8 >> (8 - count)) & 0x01;
|
||||
|
||||
set_CF(temp_CF);
|
||||
set_OF(temp_CF ^ (result_8 >> 7));
|
||||
cf = (op1_8 >> (8 - count)) & 0x01;
|
||||
of = cf ^ (result_8 >> 7); // of = cf ^ result7
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::RCR_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, result_8;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc0)
|
||||
count = i->Ib();
|
||||
@ -224,18 +223,16 @@ void BX_CPU_C::RCR_Eb(bxInstruction_c *i)
|
||||
write_RMW_virtual_byte(result_8);
|
||||
}
|
||||
|
||||
/* set eflags:
|
||||
* RCR count affects the following flags: C, O
|
||||
*/
|
||||
|
||||
set_CF((op1_8 >> (count - 1)) & 0x01);
|
||||
set_OF((((result_8 << 1) ^ result_8) & 0x80) > 0);
|
||||
cf = (op1_8 >> (count - 1)) & 0x1;
|
||||
of = ((result_8 << 1) ^ result_8) >> 7; // of = result6 ^ result7
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SHL_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, result_8;
|
||||
unsigned count;
|
||||
unsigned of = 0, cf = 0;
|
||||
|
||||
if (i->b1() == 0xc0)
|
||||
count = i->Ib();
|
||||
@ -257,7 +254,14 @@ void BX_CPU_C::SHL_Eb(bxInstruction_c *i)
|
||||
|
||||
if (!count) return;
|
||||
|
||||
result_8 = (op1_8 << count);
|
||||
if (count <= 8) {
|
||||
result_8 = (op1_8 << count);
|
||||
cf = (op1_8 >> (8 - count)) & 0x1;
|
||||
of = cf ^ (result_8 >> 7);
|
||||
}
|
||||
else {
|
||||
result_8 = 0;
|
||||
}
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
@ -267,14 +271,15 @@ void BX_CPU_C::SHL_Eb(bxInstruction_c *i)
|
||||
write_RMW_virtual_byte(result_8);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SHL8);
|
||||
SET_FLAGS_OSZAPC_LOGIC_8(result_8); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
|
||||
void BX_CPU_C::SHR_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, result_8;
|
||||
unsigned count;
|
||||
unsigned cf, of;
|
||||
|
||||
if (i->b1() == 0xc0)
|
||||
count = i->Ib();
|
||||
@ -306,13 +311,19 @@ void BX_CPU_C::SHR_Eb(bxInstruction_c *i)
|
||||
write_RMW_virtual_byte(result_8);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SHR8);
|
||||
cf = (op1_8 >> (count - 1)) & 0x1;
|
||||
// note, that of == result7 if count == 1 and
|
||||
// of == 0 if count >= 2
|
||||
of = ((result_8 << 1) ^ result_8) >> 7;
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_8(result_8); /* handle SF, ZF and AF flags */
|
||||
SET_FLAGS_OxxxxC(of, cf);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SAR_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, result_8;
|
||||
unsigned count;
|
||||
unsigned count, cf;
|
||||
|
||||
if (i->b1() == 0xc0)
|
||||
count = i->Ib();
|
||||
@ -342,8 +353,7 @@ void BX_CPU_C::SAR_Eb(bxInstruction_c *i)
|
||||
result_8 = (op1_8 >> count);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_8(result_8); /* handle undefined SF, ZF and AF flags */
|
||||
set_CF((op1_8 >> (count - 1)) & 0x1);
|
||||
cf = (op1_8 >> (count - 1)) & 0x1;
|
||||
}
|
||||
else {
|
||||
if (op1_8 & 0x80) {
|
||||
@ -353,11 +363,12 @@ void BX_CPU_C::SAR_Eb(bxInstruction_c *i)
|
||||
result_8 = 0;
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_LOGIC_8(result_8); /* handle undefined SF, ZF and AF flags */
|
||||
set_CF(result_8 & 0x1);
|
||||
cf = (result_8 & 0x1);
|
||||
}
|
||||
|
||||
clear_OF(); /* signed overflow cannot happen in SAR instruction */
|
||||
SET_FLAGS_OSZAPC_LOGIC_8(result_8); /* handle SF, ZF and AF flags */
|
||||
/* signed overflow cannot happen in SAR instruction */
|
||||
SET_FLAGS_OxxxxC(0, cf);
|
||||
|
||||
/* now write result back to destination */
|
||||
if (i->modC0()) {
|
||||
|
Loading…
Reference in New Issue
Block a user