#ifndef _X86_H_ #define _X86_H_ #define EAX cpu_state.regs[0].l #define ECX cpu_state.regs[1].l #define EDX cpu_state.regs[2].l #define EBX cpu_state.regs[3].l #define ESP cpu_state.regs[4].l #define EBP cpu_state.regs[5].l #define ESI cpu_state.regs[6].l #define EDI cpu_state.regs[7].l #define AX cpu_state.regs[0].w #define CX cpu_state.regs[1].w #define DX cpu_state.regs[2].w #define BX cpu_state.regs[3].w #define SP cpu_state.regs[4].w #define BP cpu_state.regs[5].w #define SI cpu_state.regs[6].w #define DI cpu_state.regs[7].w #define AL cpu_state.regs[0].b.l #define AH cpu_state.regs[0].b.h #define CL cpu_state.regs[1].b.l #define CH cpu_state.regs[1].b.h #define DL cpu_state.regs[2].b.l #define DH cpu_state.regs[2].b.h #define BL cpu_state.regs[3].b.l #define BH cpu_state.regs[3].b.h typedef union { uint32_t l; uint16_t w; struct { uint8_t l,h; } b; } x86reg; typedef struct { uint32_t base; uint32_t limit; uint8_t access; uint16_t seg; uint32_t limit_low, limit_high; int checked; /*Non-zero if selector is known to be valid*/ } x86seg; typedef union MMX_REG { uint64_t q; int64_t sq; uint32_t l[2]; int32_t sl[2]; uint16_t w[4]; int16_t sw[4]; uint8_t b[8]; int8_t sb[8]; float f[2]; } MMX_REG; struct { x86reg regs[8]; uint8_t tag[8]; x86seg *ea_seg; uint32_t eaaddr; int flags_op; uint32_t flags_res; uint32_t flags_op1, flags_op2; uint32_t pc; uint32_t oldpc; uint32_t op32; int TOP; union { struct { int8_t rm, mod, reg; } rm_mod_reg; uint32_t rm_mod_reg_data; } rm_data; int8_t ssegs; int8_t ismmx; int8_t abrt; int _cycles; int cpu_recomp_ins; uint16_t npxs, npxc; double ST[8]; uint16_t MM_w4[8]; MMX_REG MM[8]; uint32_t old_fp_control, new_fp_control; #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ uint16_t old_fp_control2, new_fp_control2; #endif #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ uint32_t trunc_fp_control; #endif x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; union { uint32_t l; uint16_t w; } CR0; uint16_t flags, eflags; } cpu_state; #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) #define cycles cpu_state._cycles #define cr0 cpu_state.CR0.l #define msw cpu_state.CR0.w /*Segments - _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data cs,ds,es,ss are defines to the bases*/ #define CS cpu_state.seg_cs.seg #define DS cpu_state.seg_ds.seg #define ES cpu_state.seg_es.seg #define SS cpu_state.seg_ss.seg #define FS cpu_state.seg_fs.seg #define GS cpu_state.seg_gs.seg #define cs cpu_state.seg_cs.base #define ds cpu_state.seg_ds.base #define es cpu_state.seg_es.base #define ss cpu_state.seg_ss.base //#define seg_fs _fs.base #define gs cpu_state.seg_gs.base #define CPL ((cpu_state.seg_cs.access>>5)&3) #define C_FLAG 0x0001 #define P_FLAG 0x0004 #define A_FLAG 0x0010 #define Z_FLAG 0x0040 #define N_FLAG 0x0080 #define T_FLAG 0x0100 #define I_FLAG 0x0200 #define D_FLAG 0x0400 #define V_FLAG 0x0800 #define NT_FLAG 0x4000 #define VM_FLAG 0x0002 /*In EFLAGS*/ #define VIF_FLAG 0x0008 /*In EFLAGS*/ #define VIP_FLAG 0x0010 /*In EFLAGS*/ #define WP_FLAG 0x10000 /*In CR0*/ #define CR4_VME (1 << 0) #define CR4_PVI (1 << 1) #define CR4_PSE (1 << 4) #define IOPL ((cpu_state.flags >> 12) & 3) #define IOPLp ((!(msw&1)) || (CPL<=IOPL)) extern x86seg gdt, ldt, idt, tr; extern uint32_t cr2, cr3, cr4; extern uint32_t dr[8]; extern uint16_t cpu_cur_status; /*The flags below must match in both cpu_cur_status and block->status for a block to be valid*/ #define CPU_STATUS_USE32 (1 << 0) #define CPU_STATUS_STACK32 (1 << 1) #define CPU_STATUS_PMODE (1 << 2) #define CPU_STATUS_V86 (1 << 3) #define CPU_STATUS_FLAGS 0xff /*If the flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ #define CPU_STATUS_NOTFLATDS (1 << 8) #define CPU_STATUS_NOTFLATSS (1 << 9) #define CPU_STATUS_MASK 0xff00 extern uint32_t rmdat; #define fetchdat rmdat extern uint32_t easeg; extern uint32_t *eal_r, *eal_w; extern int oldcpl; extern uint32_t oldss; extern int nmi_enable; extern int trap; extern uint32_t use32; extern int stack32; extern uint8_t znptable8[256]; extern uint16_t *mod1add[2][8]; extern uint32_t *mod1seg[8]; extern int cgate16, cgate32; extern int cpl_override; extern int x86_was_reset; extern int insc; extern int fpucount; extern float mips,flops; #define setznp168 setznp16 #define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l) #define getr16(r) cpu_state.regs[r].w #define getr32(r) cpu_state.regs[r].l #define setr8(r,v) if (r&4) cpu_state.regs[r&3].b.h=v; \ else cpu_state.regs[r&3].b.l=v; #define setr16(r,v) cpu_state.regs[r].w=v #define setr32(r,v) cpu_state.regs[r].l=v #define fetchea() { rmdat=readmemb(cs+pc); pc++; \ reg=(rmdat>>3)&7; \ mod=(rmdat>>6)&3; \ rm=rmdat&7; \ if (mod!=3) fetcheal(); } extern int optype; #define JMP 1 #define CALL 2 #define IRET 3 #define OPTYPE_INT 4 enum { ABRT_NONE = 0, ABRT_GEN, ABRT_TS = 0xA, ABRT_NP = 0xB, ABRT_SS = 0xC, ABRT_GPF = 0xD, ABRT_PF = 0xE }; extern uint32_t abrt_error; void x86_doabrt(int x86_abrt); extern int codegen_flat_ds; extern int codegen_flat_ss; extern uint32_t pccache; extern uint8_t *pccache2; void x86illegal(); void x86seg_reset(); void x86gpf(char *s, uint16_t error); void resetx86(); void softresetx86(); void refreshread(); void dumpregs(); void execx86(int cycs); void exec386(int cycs); void exec386_dynarec(int cycs); void pmodeint(int num, int soft); int loadseg(uint16_t seg, x86seg *s); void loadcs(uint16_t seg); void loadcscall(uint16_t seg, uint32_t old_pc); void loadcsjmp(uint16_t seg, uint32_t old_pc); void pmoderetf(int is32, uint16_t off); void pmodeiret(int is32); void x86_int(int num); void x86_int_sw(int num); int x86_int_sw_rm(int num); int divl(uint32_t val); int idivl(int32_t val); #endif