mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-12 23:58:38 +00:00
correct eflags evaluation order for all operations - fixed important CPU state restoring bug in some exception cases - disabled unsafe inc flags optimisation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@303 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b118d61e55
commit
e477b8b81b
2
Makefile
2
Makefile
@ -174,7 +174,7 @@ op-$(TARGET_ARCH).o: op-$(TARGET_ARCH).c
|
||||
helper-$(TARGET_ARCH).o: helper-$(TARGET_ARCH).c
|
||||
$(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
op-i386.o: op-i386.c opreg_template.h ops_template.h
|
||||
op-i386.o: op-i386.c opreg_template.h ops_template.h ops_template_mem.h
|
||||
|
||||
op-arm.o: op-arm.c op-arm-template.h
|
||||
|
||||
|
8
dyngen.c
8
dyngen.c
@ -1200,11 +1200,11 @@ int load_elf(const char *filename, FILE *outfile, int out_type)
|
||||
}
|
||||
|
||||
if (out_type == OUT_INDEX_OP) {
|
||||
fprintf(outfile, "DEF(nop1, 0, 0)\n");
|
||||
fprintf(outfile, "DEF(nop2, 0, 0)\n");
|
||||
fprintf(outfile, "DEF(nop3, 0, 0)\n");
|
||||
fprintf(outfile, "DEF(nop, 0, 0)\n");
|
||||
fprintf(outfile, "DEF(end, 0, 0)\n");
|
||||
fprintf(outfile, "DEF(nop, 0, 0)\n");
|
||||
fprintf(outfile, "DEF(nop1, 1, 0)\n");
|
||||
fprintf(outfile, "DEF(nop2, 2, 0)\n");
|
||||
fprintf(outfile, "DEF(nop3, 3, 0)\n");
|
||||
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
|
||||
const char *name, *p;
|
||||
name = strtab + sym->st_name;
|
||||
|
321
ops_template.h
321
ops_template.h
@ -406,127 +406,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
|
||||
|
||||
/* shifts */
|
||||
|
||||
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
|
||||
src = T0;
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
|
||||
CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
(T0 & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
|
||||
src = T0;
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
|
||||
CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
((T0 >> (DATA_BITS - 1)) & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, res, eflags;
|
||||
unsigned int src;
|
||||
|
||||
count = T1 & 0x1f;
|
||||
#if DATA_BITS == 16
|
||||
count = rclw_table[count];
|
||||
#elif DATA_BITS == 8
|
||||
count = rclb_table[count];
|
||||
#endif
|
||||
if (count) {
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
T0 &= DATA_MASK;
|
||||
src = T0;
|
||||
res = (T0 << count) | ((eflags & CC_C) << (count - 1));
|
||||
if (count > 1)
|
||||
res |= T0 >> (DATA_BITS + 1 - count);
|
||||
T0 = res;
|
||||
CC_SRC = (eflags & ~(CC_C | CC_O)) |
|
||||
(lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
((src >> (DATA_BITS - count)) & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, res, eflags;
|
||||
unsigned int src;
|
||||
|
||||
count = T1 & 0x1f;
|
||||
#if DATA_BITS == 16
|
||||
count = rclw_table[count];
|
||||
#elif DATA_BITS == 8
|
||||
count = rclb_table[count];
|
||||
#endif
|
||||
if (count) {
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
T0 &= DATA_MASK;
|
||||
src = T0;
|
||||
res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
|
||||
if (count > 1)
|
||||
res |= T0 << (DATA_BITS + 1 - count);
|
||||
T0 = res;
|
||||
CC_SRC = (eflags & ~(CC_C | CC_O)) |
|
||||
(lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
((src >> (count - 1)) & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & 0x1f;
|
||||
if (count) {
|
||||
CC_SRC = (DATA_TYPE)T0 << (count - 1);
|
||||
T0 = T0 << count;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SHLB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count;
|
||||
@ -535,20 +414,6 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & 0x1f;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
CC_SRC = T0 >> (count - 1);
|
||||
T0 = T0 >> count;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count;
|
||||
@ -558,20 +423,6 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & 0x1f;
|
||||
if (count) {
|
||||
src = (DATA_STYPE)T0;
|
||||
CC_SRC = src >> (count - 1);
|
||||
T0 = src >> count;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count, src;
|
||||
@ -581,162 +432,11 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#if DATA_BITS == 16
|
||||
/* XXX: overflow flag might be incorrect in some cases in shldw */
|
||||
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res;
|
||||
count = PARAM1;
|
||||
T1 &= 0xffff;
|
||||
res = T1 | (T0 << 16);
|
||||
CC_SRC = res >> (32 - count);
|
||||
res <<= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (count - 16);
|
||||
T0 = res >> 16;
|
||||
CC_DST = T0;
|
||||
}
|
||||
#undef MEM_WRITE
|
||||
#include "ops_template_mem.h"
|
||||
|
||||
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res;
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
T1 &= 0xffff;
|
||||
res = T1 | (T0 << 16);
|
||||
CC_SRC = res >> (32 - count);
|
||||
res <<= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (count - 16);
|
||||
T0 = res >> 16;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res;
|
||||
|
||||
count = PARAM1;
|
||||
res = (T0 & 0xffff) | (T1 << 16);
|
||||
CC_SRC = res >> (count - 1);
|
||||
res >>= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (32 - count);
|
||||
T0 = res;
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res;
|
||||
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
res = (T0 & 0xffff) | (T1 << 16);
|
||||
CC_SRC = res >> (count - 1);
|
||||
res >>= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (32 - count);
|
||||
T0 = res;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DATA_BITS == 32
|
||||
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = PARAM1;
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
CC_SRC = T0 << (count - 1);
|
||||
T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
CC_SRC = T0 << (count - 1);
|
||||
T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SHLB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = PARAM1;
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
CC_SRC = T0 >> (count - 1);
|
||||
T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
CC_SRC = T0 >> (count - 1);
|
||||
T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* carry add/sub (we only need to set CC_OP differently) */
|
||||
|
||||
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int cf;
|
||||
cf = cc_table[CC_OP].compute_c();
|
||||
T0 = T0 + T1 + cf;
|
||||
CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int cf;
|
||||
cf = cc_table[CC_OP].compute_c();
|
||||
T0 = T0 - T1 - cf;
|
||||
CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
|
||||
{
|
||||
CC_SRC = T0;
|
||||
CC_DST = EAX - T0;
|
||||
if ((DATA_TYPE)CC_DST == 0) {
|
||||
T0 = T1;
|
||||
} else {
|
||||
EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#define MEM_WRITE
|
||||
#include "ops_template_mem.h"
|
||||
|
||||
/* bit operations */
|
||||
#if DATA_BITS >= 16
|
||||
@ -752,7 +452,7 @@ void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
CC_SRC = T0 >> count;
|
||||
T1 = T0 >> count;
|
||||
T0 |= (1 << count);
|
||||
}
|
||||
|
||||
@ -760,7 +460,7 @@ void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
CC_SRC = T0 >> count;
|
||||
T1 = T0 >> count;
|
||||
T0 &= ~(1 << count);
|
||||
}
|
||||
|
||||
@ -768,7 +468,7 @@ void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
CC_SRC = T0 >> count;
|
||||
T1 = T0 >> count;
|
||||
T0 ^= (1 << count);
|
||||
}
|
||||
|
||||
@ -810,6 +510,13 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
|
||||
|
||||
#endif
|
||||
|
||||
#if DATA_BITS == 32
|
||||
void OPPROTO op_update_bt_cc(void)
|
||||
{
|
||||
CC_SRC = T1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* string operations */
|
||||
/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
|
||||
|
||||
|
423
ops_template_mem.h
Normal file
423
ops_template_mem.h
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* i386 micro operations (included several times to generate
|
||||
* different operand sizes)
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifdef MEM_WRITE
|
||||
|
||||
#if DATA_BITS == 8
|
||||
#define MEM_SUFFIX b_mem
|
||||
#elif DATA_BITS == 16
|
||||
#define MEM_SUFFIX w_mem
|
||||
#elif DATA_BITS == 32
|
||||
#define MEM_SUFFIX l_mem
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define MEM_SUFFIX SUFFIX
|
||||
|
||||
#endif
|
||||
|
||||
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
src = T0;
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
|
||||
(lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
(T0 & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
src = T0;
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
|
||||
(lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
((T0 >> (DATA_BITS - 1)) & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
|
||||
{
|
||||
int count;
|
||||
count = T1 & SHIFT_MASK;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, res, eflags;
|
||||
unsigned int src;
|
||||
|
||||
count = T1 & 0x1f;
|
||||
#if DATA_BITS == 16
|
||||
count = rclw_table[count];
|
||||
#elif DATA_BITS == 8
|
||||
count = rclb_table[count];
|
||||
#endif
|
||||
if (count) {
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
T0 &= DATA_MASK;
|
||||
src = T0;
|
||||
res = (T0 << count) | ((eflags & CC_C) << (count - 1));
|
||||
if (count > 1)
|
||||
res |= T0 >> (DATA_BITS + 1 - count);
|
||||
T0 = res;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = (eflags & ~(CC_C | CC_O)) |
|
||||
(lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
((src >> (DATA_BITS - count)) & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, res, eflags;
|
||||
unsigned int src;
|
||||
|
||||
count = T1 & 0x1f;
|
||||
#if DATA_BITS == 16
|
||||
count = rclw_table[count];
|
||||
#elif DATA_BITS == 8
|
||||
count = rclb_table[count];
|
||||
#endif
|
||||
if (count) {
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
T0 &= DATA_MASK;
|
||||
src = T0;
|
||||
res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
|
||||
if (count > 1)
|
||||
res |= T0 << (DATA_BITS + 1 - count);
|
||||
T0 = res;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = (eflags & ~(CC_C | CC_O)) |
|
||||
(lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
|
||||
((src >> (count - 1)) & CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & 0x1f;
|
||||
if (count) {
|
||||
src = (DATA_TYPE)T0 << (count - 1);
|
||||
T0 = T0 << count;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = src;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SHLB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & 0x1f;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
src = T0 >> (count - 1);
|
||||
T0 = T0 >> count;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = src;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int count, src;
|
||||
count = T1 & 0x1f;
|
||||
if (count) {
|
||||
src = (DATA_STYPE)T0;
|
||||
T0 = src >> count;
|
||||
src = src >> (count - 1);
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = src;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#if DATA_BITS == 16
|
||||
/* XXX: overflow flag might be incorrect in some cases in shldw */
|
||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res, tmp;
|
||||
count = PARAM1;
|
||||
T1 &= 0xffff;
|
||||
res = T1 | (T0 << 16);
|
||||
tmp = res >> (32 - count);
|
||||
res <<= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (count - 16);
|
||||
T0 = res >> 16;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res, tmp;
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
T1 &= 0xffff;
|
||||
res = T1 | (T0 << 16);
|
||||
tmp = res >> (32 - count);
|
||||
res <<= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (count - 16);
|
||||
T0 = res >> 16;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res, tmp;
|
||||
|
||||
count = PARAM1;
|
||||
res = (T0 & 0xffff) | (T1 << 16);
|
||||
tmp = res >> (count - 1);
|
||||
res >>= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (32 - count);
|
||||
T0 = res;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int res, tmp;
|
||||
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
res = (T0 & 0xffff) | (T1 << 16);
|
||||
tmp = res >> (count - 1);
|
||||
res >>= count;
|
||||
if (count > 16)
|
||||
res |= T1 << (32 - count);
|
||||
T0 = res;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DATA_BITS == 32
|
||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count, tmp;
|
||||
count = PARAM1;
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
tmp = T0 << (count - 1);
|
||||
T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count, tmp;
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
tmp = T0 << (count - 1);
|
||||
T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SHLB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
|
||||
{
|
||||
int count, tmp;
|
||||
count = PARAM1;
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
tmp = T0 >> (count - 1);
|
||||
T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
}
|
||||
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
{
|
||||
int count, tmp;
|
||||
count = ECX & 0x1f;
|
||||
if (count) {
|
||||
T0 &= DATA_MASK;
|
||||
T1 &= DATA_MASK;
|
||||
tmp = T0 >> (count - 1);
|
||||
T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = tmp;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* carry add/sub (we only need to set CC_OP differently) */
|
||||
|
||||
void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int cf;
|
||||
cf = cc_table[CC_OP].compute_c();
|
||||
T0 = T0 + T1 + cf;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = T1;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
{
|
||||
int cf;
|
||||
cf = cc_table[CC_OP].compute_c();
|
||||
T0 = T0 - T1 - cf;
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = T1;
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
|
||||
{
|
||||
unsigned int src, dst;
|
||||
|
||||
src = T0;
|
||||
dst = EAX - T0;
|
||||
if ((DATA_TYPE)dst == 0) {
|
||||
T0 = T1;
|
||||
} else {
|
||||
EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
|
||||
}
|
||||
#ifdef MEM_WRITE
|
||||
glue(st, SUFFIX)((uint8_t *)A0, T0);
|
||||
#endif
|
||||
CC_SRC = src;
|
||||
CC_DST = dst;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#undef MEM_SUFFIX
|
||||
#undef MEM_WRITE
|
221
translate-i386.c
221
translate-i386.c
@ -390,6 +390,21 @@ static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
|
||||
},
|
||||
};
|
||||
|
||||
static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3][2] = {
|
||||
[OT_BYTE] = {
|
||||
gen_op_adcb_mem_T0_T1_cc,
|
||||
gen_op_sbbb_mem_T0_T1_cc,
|
||||
},
|
||||
[OT_WORD] = {
|
||||
gen_op_adcw_mem_T0_T1_cc,
|
||||
gen_op_sbbw_mem_T0_T1_cc,
|
||||
},
|
||||
[OT_LONG] = {
|
||||
gen_op_adcl_mem_T0_T1_cc,
|
||||
gen_op_sbbl_mem_T0_T1_cc,
|
||||
},
|
||||
};
|
||||
|
||||
static const int cc_op_arithb[8] = {
|
||||
CC_OP_ADDB,
|
||||
CC_OP_LOGICB,
|
||||
@ -407,6 +422,12 @@ static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = {
|
||||
gen_op_cmpxchgl_T0_T1_EAX_cc,
|
||||
};
|
||||
|
||||
static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3] = {
|
||||
gen_op_cmpxchgb_mem_T0_T1_EAX_cc,
|
||||
gen_op_cmpxchgw_mem_T0_T1_EAX_cc,
|
||||
gen_op_cmpxchgl_mem_T0_T1_EAX_cc,
|
||||
};
|
||||
|
||||
static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
|
||||
[OT_BYTE] = {
|
||||
gen_op_rolb_T0_T1_cc,
|
||||
@ -440,6 +461,39 @@ static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
|
||||
},
|
||||
};
|
||||
|
||||
static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3][8] = {
|
||||
[OT_BYTE] = {
|
||||
gen_op_rolb_mem_T0_T1_cc,
|
||||
gen_op_rorb_mem_T0_T1_cc,
|
||||
gen_op_rclb_mem_T0_T1_cc,
|
||||
gen_op_rcrb_mem_T0_T1_cc,
|
||||
gen_op_shlb_mem_T0_T1_cc,
|
||||
gen_op_shrb_mem_T0_T1_cc,
|
||||
gen_op_shlb_mem_T0_T1_cc,
|
||||
gen_op_sarb_mem_T0_T1_cc,
|
||||
},
|
||||
[OT_WORD] = {
|
||||
gen_op_rolw_mem_T0_T1_cc,
|
||||
gen_op_rorw_mem_T0_T1_cc,
|
||||
gen_op_rclw_mem_T0_T1_cc,
|
||||
gen_op_rcrw_mem_T0_T1_cc,
|
||||
gen_op_shlw_mem_T0_T1_cc,
|
||||
gen_op_shrw_mem_T0_T1_cc,
|
||||
gen_op_shlw_mem_T0_T1_cc,
|
||||
gen_op_sarw_mem_T0_T1_cc,
|
||||
},
|
||||
[OT_LONG] = {
|
||||
gen_op_roll_mem_T0_T1_cc,
|
||||
gen_op_rorl_mem_T0_T1_cc,
|
||||
gen_op_rcll_mem_T0_T1_cc,
|
||||
gen_op_rcrl_mem_T0_T1_cc,
|
||||
gen_op_shll_mem_T0_T1_cc,
|
||||
gen_op_shrl_mem_T0_T1_cc,
|
||||
gen_op_shll_mem_T0_T1_cc,
|
||||
gen_op_sarl_mem_T0_T1_cc,
|
||||
},
|
||||
};
|
||||
|
||||
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
|
||||
[0] = {
|
||||
gen_op_shldw_T0_T1_im_cc,
|
||||
@ -462,6 +516,28 @@ static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
|
||||
},
|
||||
};
|
||||
|
||||
static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[2][2] = {
|
||||
[0] = {
|
||||
gen_op_shldw_mem_T0_T1_im_cc,
|
||||
gen_op_shrdw_mem_T0_T1_im_cc,
|
||||
},
|
||||
[1] = {
|
||||
gen_op_shldl_mem_T0_T1_im_cc,
|
||||
gen_op_shrdl_mem_T0_T1_im_cc,
|
||||
},
|
||||
};
|
||||
|
||||
static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[2][2] = {
|
||||
[0] = {
|
||||
gen_op_shldw_mem_T0_T1_ECX_cc,
|
||||
gen_op_shrdw_mem_T0_T1_ECX_cc,
|
||||
},
|
||||
[1] = {
|
||||
gen_op_shldl_mem_T0_T1_ECX_cc,
|
||||
gen_op_shrdl_mem_T0_T1_ECX_cc,
|
||||
},
|
||||
};
|
||||
|
||||
static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
|
||||
[0] = {
|
||||
gen_op_btw_T0_T1_cc,
|
||||
@ -763,11 +839,14 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
|
||||
case OP_SBBL:
|
||||
if (s1->cc_op != CC_OP_DYNAMIC)
|
||||
gen_op_set_cc_op(s1->cc_op);
|
||||
gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
|
||||
if (d != OR_TMP0) {
|
||||
gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
|
||||
gen_op_mov_reg_T0[ot][d]();
|
||||
} else {
|
||||
gen_op_arithc_mem_T0_T1_cc[ot][op - OP_ADCL]();
|
||||
}
|
||||
s1->cc_op = CC_OP_DYNAMIC;
|
||||
/* XXX: incorrect: CC_OP must also be modified AFTER memory access */
|
||||
gen_update_cc = gen_op_update2_cc;
|
||||
break;
|
||||
goto the_end;
|
||||
case OP_ADDL:
|
||||
gen_op_addl_T0_T1();
|
||||
s1->cc_op = CC_OP_ADDB + ot;
|
||||
@ -802,6 +881,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
|
||||
exception support) */
|
||||
if (gen_update_cc)
|
||||
gen_update_cc();
|
||||
the_end: ;
|
||||
}
|
||||
|
||||
/* if d == OR_TMP0, it means memory operand (address in A0) */
|
||||
@ -831,14 +911,18 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
|
||||
{
|
||||
if (d != OR_TMP0)
|
||||
gen_op_mov_TN_reg[ot][0][d]();
|
||||
else
|
||||
gen_op_ld_T0_A0[ot]();
|
||||
if (s != OR_TMP1)
|
||||
gen_op_mov_TN_reg[ot][1][s]();
|
||||
/* for zero counts, flags are not updated, so must do it dynamically */
|
||||
if (s1->cc_op != CC_OP_DYNAMIC)
|
||||
gen_op_set_cc_op(s1->cc_op);
|
||||
|
||||
gen_op_shift_T0_T1_cc[ot][op]();
|
||||
|
||||
|
||||
if (d != OR_TMP0)
|
||||
gen_op_shift_T0_T1_cc[ot][op]();
|
||||
else
|
||||
gen_op_shift_mem_T0_T1_cc[ot][op]();
|
||||
if (d != OR_TMP0)
|
||||
gen_op_mov_reg_T0[ot][d]();
|
||||
s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
|
||||
@ -1885,8 +1969,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
} else {
|
||||
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
||||
gen_op_ld_T0_A0[ot]();
|
||||
gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
|
||||
gen_op_st_T0_A0[ot]();
|
||||
gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot]();
|
||||
}
|
||||
s->cc_op = CC_OP_SUBB + ot;
|
||||
break;
|
||||
@ -2264,7 +2347,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
|
||||
if (mod != 3) {
|
||||
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
||||
gen_op_ld_T0_A0[ot]();
|
||||
opreg = OR_TMP0;
|
||||
} else {
|
||||
opreg = rm + OR_EAX;
|
||||
@ -2279,10 +2361,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
}
|
||||
gen_shifti(s, op, ot, opreg, shift);
|
||||
}
|
||||
|
||||
if (mod != 3) {
|
||||
gen_op_st_T0_A0[ot]();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xd0:
|
||||
@ -2330,7 +2408,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
val = ldub(s->pc++);
|
||||
val &= 0x1f;
|
||||
if (val) {
|
||||
gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
|
||||
if (mod == 3)
|
||||
gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
|
||||
else
|
||||
gen_op_shiftd_mem_T0_T1_im_cc[ot - OT_WORD][op](val);
|
||||
if (op == 0 && ot != OT_WORD)
|
||||
s->cc_op = CC_OP_SHLB + ot;
|
||||
else
|
||||
@ -2339,12 +2420,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
} else {
|
||||
if (s->cc_op != CC_OP_DYNAMIC)
|
||||
gen_op_set_cc_op(s->cc_op);
|
||||
gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
|
||||
if (mod == 3)
|
||||
gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
|
||||
else
|
||||
gen_op_shiftd_mem_T0_T1_ECX_cc[ot - OT_WORD][op]();
|
||||
s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
|
||||
}
|
||||
if (mod != 3) {
|
||||
gen_op_st_T0_A0[ot]();
|
||||
} else {
|
||||
if (mod == 3) {
|
||||
gen_op_mov_reg_T0[ot][rm]();
|
||||
}
|
||||
break;
|
||||
@ -3202,6 +3284,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
gen_op_st_T0_A0[ot]();
|
||||
else
|
||||
gen_op_mov_reg_T0[ot][rm]();
|
||||
gen_op_update_bt_cc();
|
||||
}
|
||||
break;
|
||||
case 0x1a3: /* bt Gv, Ev */
|
||||
@ -3240,6 +3323,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
gen_op_st_T0_A0[ot]();
|
||||
else
|
||||
gen_op_mov_reg_T0[ot][rm]();
|
||||
gen_op_update_bt_cc();
|
||||
}
|
||||
break;
|
||||
case 0x1bc: /* bsf */
|
||||
@ -3640,6 +3724,13 @@ static uint16_t opc_read_flags[NB_OPS] = {
|
||||
[INDEX_op_sbbw_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_sbbl_T0_T1_cc] = CC_C,
|
||||
|
||||
[INDEX_op_adcb_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_adcw_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_adcl_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_sbbb_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_sbbw_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_sbbl_mem_T0_T1_cc] = CC_C,
|
||||
|
||||
/* subtle: due to the incl/decl implementation, C is used */
|
||||
[INDEX_op_update_inc_cc] = CC_C,
|
||||
|
||||
@ -3717,23 +3808,38 @@ static uint16_t opc_read_flags[NB_OPS] = {
|
||||
[INDEX_op_rcrb_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rcrw_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rcrl_T0_T1_cc] = CC_C,
|
||||
|
||||
[INDEX_op_rclb_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rclw_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rcll_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rcrb_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rcrw_mem_T0_T1_cc] = CC_C,
|
||||
[INDEX_op_rcrl_mem_T0_T1_cc] = CC_C,
|
||||
};
|
||||
|
||||
/* flags written by an operation */
|
||||
static uint16_t opc_write_flags[NB_OPS] = {
|
||||
[INDEX_op_update2_cc] = CC_OSZAPC,
|
||||
[INDEX_op_update1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_update_neg_cc] = CC_OSZAPC,
|
||||
/* subtle: due to the incl/decl implementation, C is used */
|
||||
[INDEX_op_update_inc_cc] = CC_OSZAPC,
|
||||
[INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_update_neg_cc] = CC_OSZAPC,
|
||||
/* subtle: due to the incl/decl implementation, C is used */
|
||||
[INDEX_op_update_inc_cc] = CC_OSZAPC,
|
||||
[INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_adcb_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_adcw_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_adcl_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sbbb_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sbbw_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sbbl_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_mulb_AL_T0] = CC_OSZAPC,
|
||||
[INDEX_op_imulb_AL_T0] = CC_OSZAPC,
|
||||
@ -3795,6 +3901,42 @@ static uint16_t opc_write_flags[NB_OPS] = {
|
||||
[INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_rolb_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rolw_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_roll_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rorb_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rorw_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rorl_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
|
||||
[INDEX_op_rclb_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rclw_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rcll_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rcrb_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rcrw_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
[INDEX_op_rcrl_mem_T0_T1_cc] = CC_O | CC_C,
|
||||
|
||||
[INDEX_op_shlb_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shlw_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shll_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_shrb_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shrw_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shrl_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_sarb_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sarw_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_sarl_mem_T0_T1_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_shldw_mem_T0_T1_ECX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shldl_mem_T0_T1_ECX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shldw_mem_T0_T1_im_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shldl_mem_T0_T1_im_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_shrdw_mem_T0_T1_ECX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shrdl_mem_T0_T1_ECX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shrdw_mem_T0_T1_im_cc] = CC_OSZAPC,
|
||||
[INDEX_op_shrdl_mem_T0_T1_im_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
|
||||
[INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
|
||||
@ -3832,6 +3974,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
|
||||
[INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_cmpxchgb_mem_T0_T1_EAX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_cmpxchgw_mem_T0_T1_EAX_cc] = CC_OSZAPC,
|
||||
[INDEX_op_cmpxchgl_mem_T0_T1_EAX_cc] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_cmpxchg8b] = CC_Z,
|
||||
[INDEX_op_lar] = CC_Z,
|
||||
[INDEX_op_lsl] = CC_Z,
|
||||
@ -3844,8 +3990,10 @@ static uint16_t opc_simpler[NB_OPS] = {
|
||||
[INDEX_op_update2_cc] = INDEX_op_nop,
|
||||
[INDEX_op_update1_cc] = INDEX_op_nop,
|
||||
[INDEX_op_update_neg_cc] = INDEX_op_nop,
|
||||
#if 0
|
||||
/* broken: CC_OP logic must be rewritten */
|
||||
[INDEX_op_update_inc_cc] = INDEX_op_nop,
|
||||
|
||||
#endif
|
||||
[INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
|
||||
[INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,
|
||||
[INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1,
|
||||
@ -3854,6 +4002,14 @@ static uint16_t opc_simpler[NB_OPS] = {
|
||||
[INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1,
|
||||
[INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1,
|
||||
|
||||
[INDEX_op_rolb_mem_T0_T1_cc] = INDEX_op_rolb_mem_T0_T1,
|
||||
[INDEX_op_rolw_mem_T0_T1_cc] = INDEX_op_rolw_mem_T0_T1,
|
||||
[INDEX_op_roll_mem_T0_T1_cc] = INDEX_op_roll_mem_T0_T1,
|
||||
|
||||
[INDEX_op_rorb_mem_T0_T1_cc] = INDEX_op_rorb_mem_T0_T1,
|
||||
[INDEX_op_rorw_mem_T0_T1_cc] = INDEX_op_rorw_mem_T0_T1,
|
||||
[INDEX_op_rorl_mem_T0_T1_cc] = INDEX_op_rorl_mem_T0_T1,
|
||||
|
||||
[INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
|
||||
[INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
|
||||
[INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
|
||||
@ -3971,6 +4127,10 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc
|
||||
break;
|
||||
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
|
||||
(pc_ptr - pc_start) < (TARGET_PAGE_SIZE - 32));
|
||||
if (!dc->tf && dc->is_jmp == DISAS_NEXT) {
|
||||
gen_jmp(dc, ret - (unsigned long)dc->cs_base);
|
||||
}
|
||||
|
||||
/* we must store the eflags state if it is not already done */
|
||||
if (dc->is_jmp != DISAS_TB_JUMP) {
|
||||
if (dc->cc_op != CC_OP_DYNAMIC)
|
||||
@ -3983,12 +4143,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc
|
||||
if (dc->tf) {
|
||||
gen_op_raise_exception(EXCP01_SSTP);
|
||||
}
|
||||
if (dc->is_jmp != 3) {
|
||||
if (dc->is_jmp != DISAS_TB_JUMP) {
|
||||
/* indicate that the hash table must be used to find the next TB */
|
||||
gen_op_movl_T0_0();
|
||||
}
|
||||
*gen_opc_ptr = INDEX_op_end;
|
||||
|
||||
/* we don't forget to fill the last values */
|
||||
if (search_pc) {
|
||||
j = gen_opc_ptr - gen_opc_buf;
|
||||
lj++;
|
||||
while (lj <= j)
|
||||
gen_opc_instr_start[lj++] = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DISAS
|
||||
if (loglevel) {
|
||||
fprintf(logfile, "----------------\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user