mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
better 16 bit code support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@38 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
- overrides/16bit for string ops
|
||||
- optimize translated cache chaining (DLL PLT-like system)
|
||||
- 64 bit syscalls
|
||||
- signals
|
||||
|
||||
+6
-4
@@ -141,7 +141,7 @@ typedef struct SegmentDescriptorTable {
|
||||
typedef struct CPUX86State {
|
||||
/* standard registers */
|
||||
uint32_t regs[8];
|
||||
uint32_t pc; /* cs_case + eip value */
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
|
||||
/* emulator internal eflags handling */
|
||||
@@ -392,10 +392,12 @@ void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
|
||||
|
||||
#define GEN_FLAG_CODE32_SHIFT 0
|
||||
#define GEN_FLAG_ADDSEG_SHIFT 1
|
||||
#define GEN_FLAG_ST_SHIFT 2
|
||||
#define GEN_FLAG_SS32_SHIFT 2
|
||||
#define GEN_FLAG_ST_SHIFT 3
|
||||
|
||||
int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
|
||||
int *gen_code_size_ptr, uint8_t *pc_start,
|
||||
int flags);
|
||||
int *gen_code_size_ptr,
|
||||
uint8_t *pc_start, uint8_t *cs_base, int flags);
|
||||
void cpu_x86_tblocks_init(void);
|
||||
|
||||
#endif /* CPU_I386_H */
|
||||
|
||||
+12
-5
@@ -38,7 +38,8 @@
|
||||
#define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS)
|
||||
|
||||
typedef struct TranslationBlock {
|
||||
unsigned long pc; /* simulated PC corresponding to this block */
|
||||
unsigned long pc; /* simulated PC corresponding to this block (EIP + CS base) */
|
||||
unsigned long cs_base; /* CS base for this block */
|
||||
unsigned int flags; /* flags defining in which context the code was generated */
|
||||
uint8_t *tc_ptr; /* pointer to the translated code */
|
||||
struct TranslationBlock *hash_next; /* next matching block */
|
||||
@@ -140,6 +141,7 @@ static void tb_flush(void)
|
||||
/* find a translation block in the translation cache. If not found,
|
||||
allocate a new one */
|
||||
static inline TranslationBlock *tb_find_and_alloc(unsigned long pc,
|
||||
unsigned long cs_base,
|
||||
unsigned int flags)
|
||||
{
|
||||
TranslationBlock **ptb, *tb;
|
||||
@@ -151,7 +153,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc,
|
||||
tb = *ptb;
|
||||
if (!tb)
|
||||
break;
|
||||
if (tb->pc == pc && tb->flags == flags)
|
||||
if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
|
||||
return tb;
|
||||
ptb = &tb->hash_next;
|
||||
}
|
||||
@@ -161,6 +163,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc,
|
||||
tb = &tbs[nb_tbs++];
|
||||
*ptb = tb;
|
||||
tb->pc = pc;
|
||||
tb->cs_base = cs_base;
|
||||
tb->flags = flags;
|
||||
tb->tc_ptr = NULL;
|
||||
tb->hash_next = NULL;
|
||||
@@ -198,7 +201,7 @@ int cpu_x86_exec(CPUX86State *env1)
|
||||
int code_gen_size, ret;
|
||||
void (*gen_func)(void);
|
||||
TranslationBlock *tb;
|
||||
uint8_t *tc_ptr;
|
||||
uint8_t *tc_ptr, *cs_base, *pc;
|
||||
unsigned int flags;
|
||||
|
||||
/* first we save global registers */
|
||||
@@ -251,17 +254,21 @@ int cpu_x86_exec(CPUX86State *env1)
|
||||
/* we compute the CPU state. We assume it will not
|
||||
change during the whole generated block. */
|
||||
flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT;
|
||||
flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT;
|
||||
flags |= (((unsigned long)env->seg_cache[R_DS].base |
|
||||
(unsigned long)env->seg_cache[R_ES].base |
|
||||
(unsigned long)env->seg_cache[R_SS].base) != 0) <<
|
||||
GEN_FLAG_ADDSEG_SHIFT;
|
||||
tb = tb_find_and_alloc((unsigned long)env->pc, flags);
|
||||
cs_base = env->seg_cache[R_CS].base;
|
||||
pc = cs_base + env->eip;
|
||||
tb = tb_find_and_alloc((unsigned long)pc, (unsigned long)cs_base,
|
||||
flags);
|
||||
tc_ptr = tb->tc_ptr;
|
||||
if (!tb->tc_ptr) {
|
||||
/* if no translated code available, then translate it now */
|
||||
tc_ptr = code_gen_ptr;
|
||||
cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE,
|
||||
&code_gen_size, (uint8_t *)env->pc, flags);
|
||||
&code_gen_size, pc, cs_base, flags);
|
||||
tb->tc_ptr = tc_ptr;
|
||||
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
|
||||
}
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ register struct CPUX86State *env asm("l3");
|
||||
#ifndef reg_EDI
|
||||
#define EDI (env->regs[R_EDI])
|
||||
#endif
|
||||
#define PC (env->pc)
|
||||
#define EIP (env->eip)
|
||||
#define DF (env->df)
|
||||
|
||||
#define CC_SRC (env->cc_src)
|
||||
|
||||
+4
-4
@@ -179,7 +179,7 @@ int main(int argc, char **argv)
|
||||
env->regs[R_EDI] = regs->edi;
|
||||
env->regs[R_EBP] = regs->ebp;
|
||||
env->regs[R_ESP] = regs->esp;
|
||||
env->pc = regs->eip;
|
||||
env->eip = regs->eip;
|
||||
|
||||
/* linux segment setup */
|
||||
env->gdt.base = (void *)gdt_table;
|
||||
@@ -198,12 +198,12 @@ int main(int argc, char **argv)
|
||||
uint8_t *pc;
|
||||
|
||||
err = cpu_x86_exec(env);
|
||||
pc = env->seg_cache[R_CS].base + env->eip;
|
||||
switch(err) {
|
||||
case EXCP0D_GPF:
|
||||
pc = (uint8_t *)env->pc;
|
||||
if (pc[0] == 0xcd && pc[1] == 0x80) {
|
||||
/* syscall */
|
||||
env->pc += 2;
|
||||
env->eip += 2;
|
||||
env->regs[R_EAX] = do_syscall(env,
|
||||
env->regs[R_EAX],
|
||||
env->regs[R_EBX],
|
||||
@@ -219,7 +219,7 @@ int main(int argc, char **argv)
|
||||
default:
|
||||
trap_error:
|
||||
fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n",
|
||||
(long)env->pc, err);
|
||||
(long)pc, err);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
+28
-9
@@ -53,6 +53,7 @@
|
||||
#include <linux/cdrom.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/soundcard.h>
|
||||
#include <linux/dirent.h>
|
||||
|
||||
#include "gemu.h"
|
||||
|
||||
@@ -63,13 +64,6 @@
|
||||
#define PAGE_MASK ~(PAGE_SIZE - 1)
|
||||
#endif
|
||||
|
||||
struct dirent {
|
||||
long d_ino;
|
||||
long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[256]; /* We must not include limits.h! */
|
||||
};
|
||||
|
||||
//#include <linux/msdos_fs.h>
|
||||
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
|
||||
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
|
||||
@@ -86,6 +80,7 @@ struct dirent {
|
||||
#define __NR_sys_statfs __NR_statfs
|
||||
#define __NR_sys_fstatfs __NR_fstatfs
|
||||
#define __NR_sys_getdents __NR_getdents
|
||||
#define __NR_sys_getdents64 __NR_getdents64
|
||||
|
||||
#ifdef __NR_gettid
|
||||
_syscall0(int, gettid)
|
||||
@@ -97,6 +92,7 @@ static int gettid(void) {
|
||||
_syscall1(int,sys_uname,struct new_utsname *,buf)
|
||||
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
|
||||
_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
|
||||
_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
|
||||
_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
|
||||
loff_t *, res, uint, wh);
|
||||
_syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
|
||||
@@ -1005,7 +1001,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
ret = get_errno(setsid());
|
||||
break;
|
||||
case TARGET_NR_sigaction:
|
||||
#if 0
|
||||
#if 1
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
@@ -1336,6 +1332,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
{
|
||||
struct dirent *dirp = (void *)arg2;
|
||||
long count = arg3;
|
||||
|
||||
ret = get_errno(sys_getdents(arg1, dirp, count));
|
||||
if (!is_error(ret)) {
|
||||
struct dirent *de;
|
||||
@@ -1355,6 +1352,29 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_getdents64:
|
||||
{
|
||||
struct dirent64 *dirp = (void *)arg2;
|
||||
long count = arg3;
|
||||
ret = get_errno(sys_getdents64(arg1, dirp, count));
|
||||
if (!is_error(ret)) {
|
||||
struct dirent64 *de;
|
||||
int len = ret;
|
||||
int reclen;
|
||||
de = dirp;
|
||||
while (len > 0) {
|
||||
reclen = tswap16(de->d_reclen);
|
||||
if (reclen > len)
|
||||
break;
|
||||
de->d_reclen = reclen;
|
||||
tswap64s(&de->d_ino);
|
||||
tswap64s(&de->d_off);
|
||||
de = (struct dirent64 *)((char *)de + reclen);
|
||||
len -= reclen;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TARGET_NR__newselect:
|
||||
ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4,
|
||||
(void *)arg5);
|
||||
@@ -1519,7 +1539,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
case TARGET_NR_pivot_root:
|
||||
case TARGET_NR_mincore:
|
||||
case TARGET_NR_madvise:
|
||||
case TARGET_NR_getdents64:
|
||||
goto unimplemented;
|
||||
#if TARGET_LONG_BITS == 32
|
||||
case TARGET_NR_fcntl64:
|
||||
|
||||
@@ -75,6 +75,22 @@ struct kernel_statfs {
|
||||
int f_spare[6];
|
||||
};
|
||||
|
||||
struct target_dirent {
|
||||
target_long d_ino;
|
||||
target_long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[256]; /* We must not include limits.h! */
|
||||
};
|
||||
|
||||
struct target_dirent64 {
|
||||
uint64_t d_ino;
|
||||
int64_t d_off;
|
||||
unsigned short d_reclen;
|
||||
unsigned char d_type;
|
||||
char d_name[256];
|
||||
};
|
||||
|
||||
|
||||
/* mostly generic signal stuff */
|
||||
#define TARGET_SIG_DFL ((target_long)0) /* default signal handling */
|
||||
#define TARGET_SIG_IGN ((target_long)1) /* ignore signal */
|
||||
|
||||
@@ -464,18 +464,43 @@ void OPPROTO op_idivl_EAX_T0(void)
|
||||
EDX = r;
|
||||
}
|
||||
|
||||
/* constant load */
|
||||
/* constant load & misc op */
|
||||
|
||||
void OPPROTO op_movl_T0_im(void)
|
||||
{
|
||||
T0 = PARAM1;
|
||||
}
|
||||
|
||||
void OPPROTO op_addl_T0_im(void)
|
||||
{
|
||||
T0 += PARAM1;
|
||||
}
|
||||
|
||||
void OPPROTO op_andl_T0_ffff(void)
|
||||
{
|
||||
T0 = T0 & 0xffff;
|
||||
}
|
||||
|
||||
void OPPROTO op_movl_T0_T1(void)
|
||||
{
|
||||
T0 = T1;
|
||||
}
|
||||
|
||||
void OPPROTO op_movl_T1_im(void)
|
||||
{
|
||||
T1 = PARAM1;
|
||||
}
|
||||
|
||||
void OPPROTO op_addl_T1_im(void)
|
||||
{
|
||||
T1 += PARAM1;
|
||||
}
|
||||
|
||||
void OPPROTO op_movl_T1_A0(void)
|
||||
{
|
||||
T1 = A0;
|
||||
}
|
||||
|
||||
void OPPROTO op_movl_A0_im(void)
|
||||
{
|
||||
A0 = PARAM1;
|
||||
@@ -574,23 +599,23 @@ void OPPROTO op_add_bitl_A0_T1(void)
|
||||
|
||||
void OPPROTO op_jmp_T0(void)
|
||||
{
|
||||
PC = T0;
|
||||
EIP = T0;
|
||||
}
|
||||
|
||||
void OPPROTO op_jmp_im(void)
|
||||
{
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
}
|
||||
|
||||
void OPPROTO op_int_im(void)
|
||||
{
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
|
||||
void OPPROTO op_int3(void)
|
||||
{
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
raise_exception(EXCP03_INT3);
|
||||
}
|
||||
|
||||
@@ -599,10 +624,10 @@ void OPPROTO op_into(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (eflags & CC_O) {
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
raise_exception(EXCP04_INTO);
|
||||
} else {
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,7 +690,6 @@ void OPPROTO op_movswl_DX_AX(void)
|
||||
}
|
||||
|
||||
/* push/pop */
|
||||
/* XXX: add 16 bit operand/16 bit seg variants */
|
||||
|
||||
void op_pushl_T0(void)
|
||||
{
|
||||
@@ -676,107 +700,110 @@ void op_pushl_T0(void)
|
||||
ESP = offset;
|
||||
}
|
||||
|
||||
void op_pushl_T1(void)
|
||||
void op_pushw_T0(void)
|
||||
{
|
||||
uint32_t offset;
|
||||
offset = ESP - 4;
|
||||
stl((void *)offset, T1);
|
||||
offset = ESP - 2;
|
||||
stw((void *)offset, T0);
|
||||
/* modify ESP after to handle exceptions correctly */
|
||||
ESP = offset;
|
||||
}
|
||||
|
||||
void op_pushl_ss32_T0(void)
|
||||
{
|
||||
uint32_t offset;
|
||||
offset = ESP - 4;
|
||||
stl(env->seg_cache[R_SS].base + offset, T0);
|
||||
/* modify ESP after to handle exceptions correctly */
|
||||
ESP = offset;
|
||||
}
|
||||
|
||||
void op_pushw_ss32_T0(void)
|
||||
{
|
||||
uint32_t offset;
|
||||
offset = ESP - 2;
|
||||
stw(env->seg_cache[R_SS].base + offset, T0);
|
||||
/* modify ESP after to handle exceptions correctly */
|
||||
ESP = offset;
|
||||
}
|
||||
|
||||
void op_pushl_ss16_T0(void)
|
||||
{
|
||||
uint32_t offset;
|
||||
offset = (ESP - 4) & 0xffff;
|
||||
stl(env->seg_cache[R_SS].base + offset, T0);
|
||||
/* modify ESP after to handle exceptions correctly */
|
||||
ESP = (ESP & ~0xffff) | offset;
|
||||
}
|
||||
|
||||
void op_pushw_ss16_T0(void)
|
||||
{
|
||||
uint32_t offset;
|
||||
offset = (ESP - 2) & 0xffff;
|
||||
stw(env->seg_cache[R_SS].base + offset, T0);
|
||||
/* modify ESP after to handle exceptions correctly */
|
||||
ESP = (ESP & ~0xffff) | offset;
|
||||
}
|
||||
|
||||
/* NOTE: ESP update is done after */
|
||||
void op_popl_T0(void)
|
||||
{
|
||||
T0 = ldl((void *)ESP);
|
||||
}
|
||||
|
||||
void op_popw_T0(void)
|
||||
{
|
||||
T0 = lduw((void *)ESP);
|
||||
}
|
||||
|
||||
void op_popl_ss32_T0(void)
|
||||
{
|
||||
T0 = ldl(env->seg_cache[R_SS].base + ESP);
|
||||
}
|
||||
|
||||
void op_popw_ss32_T0(void)
|
||||
{
|
||||
T0 = lduw(env->seg_cache[R_SS].base + ESP);
|
||||
}
|
||||
|
||||
void op_popl_ss16_T0(void)
|
||||
{
|
||||
T0 = ldl(env->seg_cache[R_SS].base + (ESP & 0xffff));
|
||||
}
|
||||
|
||||
void op_popw_ss16_T0(void)
|
||||
{
|
||||
T0 = lduw(env->seg_cache[R_SS].base + (ESP & 0xffff));
|
||||
}
|
||||
|
||||
void op_addl_ESP_4(void)
|
||||
{
|
||||
ESP += 4;
|
||||
}
|
||||
|
||||
void op_addl_ESP_2(void)
|
||||
{
|
||||
ESP += 2;
|
||||
}
|
||||
|
||||
void op_addw_ESP_4(void)
|
||||
{
|
||||
ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);
|
||||
}
|
||||
|
||||
void op_addw_ESP_2(void)
|
||||
{
|
||||
ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);
|
||||
}
|
||||
|
||||
void op_addl_ESP_im(void)
|
||||
{
|
||||
ESP += PARAM1;
|
||||
}
|
||||
|
||||
void op_pushal(void)
|
||||
void op_addw_ESP_im(void)
|
||||
{
|
||||
uint8_t *sp;
|
||||
sp = (void *)(ESP - 32);
|
||||
stl(sp, EDI);
|
||||
stl(sp + 4, ESI);
|
||||
stl(sp + 8, EBP);
|
||||
stl(sp + 12, ESP);
|
||||
stl(sp + 16, EBX);
|
||||
stl(sp + 20, EDX);
|
||||
stl(sp + 24, ECX);
|
||||
stl(sp + 28, EAX);
|
||||
ESP = (unsigned long)sp;
|
||||
}
|
||||
|
||||
void op_pushaw(void)
|
||||
{
|
||||
uint8_t *sp;
|
||||
sp = (void *)(ESP - 16);
|
||||
stw(sp, EDI);
|
||||
stw(sp + 2, ESI);
|
||||
stw(sp + 4, EBP);
|
||||
stw(sp + 6, ESP);
|
||||
stw(sp + 8, EBX);
|
||||
stw(sp + 10, EDX);
|
||||
stw(sp + 12, ECX);
|
||||
stw(sp + 14, EAX);
|
||||
ESP = (unsigned long)sp;
|
||||
}
|
||||
|
||||
void op_popal(void)
|
||||
{
|
||||
uint8_t *sp;
|
||||
sp = (void *)ESP;
|
||||
EDI = ldl(sp);
|
||||
ESI = ldl(sp + 4);
|
||||
EBP = ldl(sp + 8);
|
||||
EBX = ldl(sp + 16);
|
||||
EDX = ldl(sp + 20);
|
||||
ECX = ldl(sp + 24);
|
||||
EAX = ldl(sp + 28);
|
||||
ESP = (unsigned long)sp + 32;
|
||||
}
|
||||
|
||||
void op_popaw(void)
|
||||
{
|
||||
uint8_t *sp;
|
||||
sp = (void *)ESP;
|
||||
EDI = ldl(sp);
|
||||
ESI = ldl(sp + 2);
|
||||
EBP = ldl(sp + 4);
|
||||
EBX = ldl(sp + 8);
|
||||
EDX = ldl(sp + 10);
|
||||
ECX = ldl(sp + 12);
|
||||
EAX = ldl(sp + 14);
|
||||
ESP = (unsigned long)sp + 16;
|
||||
}
|
||||
|
||||
void op_enterl(void)
|
||||
{
|
||||
unsigned int bp, frame_temp, level;
|
||||
uint8_t *sp;
|
||||
|
||||
sp = (void *)ESP;
|
||||
bp = EBP;
|
||||
sp -= 4;
|
||||
stl(sp, bp);
|
||||
frame_temp = (unsigned int)sp;
|
||||
level = PARAM2;
|
||||
if (level) {
|
||||
while (level--) {
|
||||
bp -= 4;
|
||||
sp -= 4;
|
||||
stl(sp, bp);
|
||||
}
|
||||
sp -= 4;
|
||||
stl(sp, frame_temp);
|
||||
}
|
||||
EBP = frame_temp;
|
||||
sp -= PARAM1;
|
||||
ESP = (int)sp;
|
||||
ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
|
||||
}
|
||||
|
||||
/* rdtsc */
|
||||
@@ -988,18 +1015,18 @@ void OPPROTO op_jo_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (eflags & CC_O)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_jb_cc(void)
|
||||
{
|
||||
if (cc_table[CC_OP].compute_c())
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -1008,9 +1035,9 @@ void OPPROTO op_jz_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (eflags & CC_Z)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -1019,9 +1046,9 @@ void OPPROTO op_jbe_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (eflags & (CC_Z | CC_C))
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -1030,9 +1057,9 @@ void OPPROTO op_js_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (eflags & CC_S)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -1041,9 +1068,9 @@ void OPPROTO op_jp_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (eflags & CC_P)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -1052,9 +1079,9 @@ void OPPROTO op_jl_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if ((eflags ^ (eflags >> 4)) & 0x80)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -1063,9 +1090,9 @@ void OPPROTO op_jle_cc(void)
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
|
||||
+20
-6
@@ -202,7 +202,12 @@ DEF(idivw_AX_T0)
|
||||
DEF(divl_EAX_T0)
|
||||
DEF(idivl_EAX_T0)
|
||||
DEF(movl_T0_im)
|
||||
DEF(addl_T0_im)
|
||||
DEF(andl_T0_ffff)
|
||||
DEF(movl_T0_T1)
|
||||
DEF(movl_T1_im)
|
||||
DEF(addl_T1_im)
|
||||
DEF(movl_T1_A0)
|
||||
DEF(movl_A0_im)
|
||||
DEF(addl_A0_im)
|
||||
DEF(andl_A0_ffff)
|
||||
@@ -398,14 +403,23 @@ DEF(movsbw_AX_AL)
|
||||
DEF(movslq_EDX_EAX)
|
||||
DEF(movswl_DX_AX)
|
||||
DEF(pushl_T0)
|
||||
DEF(pushl_T1)
|
||||
DEF(pushw_T0)
|
||||
DEF(pushl_ss32_T0)
|
||||
DEF(pushw_ss32_T0)
|
||||
DEF(pushl_ss16_T0)
|
||||
DEF(pushw_ss16_T0)
|
||||
DEF(popl_T0)
|
||||
DEF(popw_T0)
|
||||
DEF(popl_ss32_T0)
|
||||
DEF(popw_ss32_T0)
|
||||
DEF(popl_ss16_T0)
|
||||
DEF(popw_ss16_T0)
|
||||
DEF(addl_ESP_4)
|
||||
DEF(addl_ESP_2)
|
||||
DEF(addw_ESP_4)
|
||||
DEF(addw_ESP_2)
|
||||
DEF(addl_ESP_im)
|
||||
DEF(pushal)
|
||||
DEF(pushaw)
|
||||
DEF(popal)
|
||||
DEF(popaw)
|
||||
DEF(enterl)
|
||||
DEF(addw_ESP_im)
|
||||
DEF(rdtsc)
|
||||
DEF(aam)
|
||||
DEF(aad)
|
||||
|
||||
+20
-20
@@ -214,18 +214,18 @@ void OPPROTO glue(op_jb_sub, SUFFIX)(void)
|
||||
src2 = CC_SRC - CC_DST;
|
||||
|
||||
if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
|
||||
{
|
||||
if ((DATA_TYPE)CC_DST == 0)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -236,18 +236,18 @@ void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
|
||||
src2 = CC_SRC - CC_DST;
|
||||
|
||||
if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_js_sub, SUFFIX)(void)
|
||||
{
|
||||
if (CC_DST & SIGN_MASK)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -258,9 +258,9 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void)
|
||||
src2 = CC_SRC - CC_DST;
|
||||
|
||||
if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -271,9 +271,9 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void)
|
||||
src2 = CC_SRC - CC_DST;
|
||||
|
||||
if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -289,9 +289,9 @@ void OPPROTO glue(op_loopnz, SUFFIX)(void)
|
||||
tmp = (ECX - 1) & DATA_MASK;
|
||||
ECX = (ECX & ~DATA_MASK) | tmp;
|
||||
if (tmp != 0 && !(eflags & CC_Z))
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -303,9 +303,9 @@ void OPPROTO glue(op_loopz, SUFFIX)(void)
|
||||
tmp = (ECX - 1) & DATA_MASK;
|
||||
ECX = (ECX & ~DATA_MASK) | tmp;
|
||||
if (tmp != 0 && (eflags & CC_Z))
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@@ -315,18 +315,18 @@ void OPPROTO glue(op_loop, SUFFIX)(void)
|
||||
tmp = (ECX - 1) & DATA_MASK;
|
||||
ECX = (ECX & ~DATA_MASK) | tmp;
|
||||
if (tmp != 0)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_jecxz, SUFFIX)(void)
|
||||
{
|
||||
if ((DATA_TYPE)ECX == 0)
|
||||
PC = PARAM1;
|
||||
EIP = PARAM1;
|
||||
else
|
||||
PC = PARAM2;
|
||||
EIP = PARAM2;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
|
||||
+355
-62
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user