Commit 14ce26e755135e80f3726d42a5a887723d615291

Authored by bellard
1 parent c4687878

x86_64 target support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1197 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/cpu.h
... ... @@ -20,7 +20,13 @@
20 20 #ifndef CPU_I386_H
21 21 #define CPU_I386_H
22 22  
  23 +#include "config.h"
  24 +
  25 +#ifdef TARGET_X86_64
  26 +#define TARGET_LONG_BITS 64
  27 +#else
23 28 #define TARGET_LONG_BITS 32
  29 +#endif
24 30  
25 31 /* target supports implicit self modifying code */
26 32 #define TARGET_HAS_SMC
... ... @@ -63,6 +69,8 @@
63 69 #define DESC_G_MASK (1 << 23)
64 70 #define DESC_B_SHIFT 22
65 71 #define DESC_B_MASK (1 << DESC_B_SHIFT)
  72 +#define DESC_L_SHIFT 21 /* x86_64 only : 64 bit code segment */
  73 +#define DESC_L_MASK (1 << DESC_L_SHIFT)
66 74 #define DESC_AVL_MASK (1 << 20)
67 75 #define DESC_P_MASK (1 << 15)
68 76 #define DESC_DPL_SHIFT 13
... ... @@ -125,6 +133,8 @@
125 133 #define HF_EM_SHIFT 10
126 134 #define HF_TS_SHIFT 11
127 135 #define HF_IOPL_SHIFT 12 /* must be same as eflags */
  136 +#define HF_LMA_SHIFT 14 /* only used on x86_64: long mode active */
  137 +#define HF_CS64_SHIFT 15 /* only used on x86_64: 64 bit code segment */
128 138 #define HF_VM_SHIFT 17 /* must be same as eflags */
129 139  
130 140 #define HF_CPL_MASK (3 << HF_CPL_SHIFT)
... ... @@ -138,6 +148,8 @@
138 148 #define HF_MP_MASK (1 << HF_MP_SHIFT)
139 149 #define HF_EM_MASK (1 << HF_EM_SHIFT)
140 150 #define HF_TS_MASK (1 << HF_TS_SHIFT)
  151 +#define HF_LMA_MASK (1 << HF_LMA_SHIFT)
  152 +#define HF_CS64_MASK (1 << HF_CS64_SHIFT)
141 153  
142 154 #define CR0_PE_MASK (1 << 0)
143 155 #define CR0_MP_MASK (1 << 1)
... ... @@ -156,6 +168,9 @@
156 168 #define CR4_PSE_MASK (1 << 4)
157 169 #define CR4_PAE_MASK (1 << 5)
158 170 #define CR4_PGE_MASK (1 << 7)
  171 +#define CR4_PCE_MASK (1 << 8)
  172 +#define CR4_OSFXSR_MASK (1 << 9)
  173 +#define CR4_OSXMMEXCPT_MASK (1 << 10)
159 174  
160 175 #define PG_PRESENT_BIT 0
161 176 #define PG_RW_BIT 1
... ... @@ -193,6 +208,44 @@
193 208 #define MSR_IA32_SYSENTER_ESP 0x175
194 209 #define MSR_IA32_SYSENTER_EIP 0x176
195 210  
  211 +#define MSR_EFER 0xc0000080
  212 +
  213 +#define MSR_EFER_SCE (1 << 0)
  214 +#define MSR_EFER_LME (1 << 8)
  215 +#define MSR_EFER_LMA (1 << 10)
  216 +#define MSR_EFER_NXE (1 << 11)
  217 +#define MSR_EFER_FFXSR (1 << 14)
  218 +
  219 +#define MSR_STAR 0xc0000081
  220 +#define MSR_LSTAR 0xc0000082
  221 +#define MSR_CSTAR 0xc0000083
  222 +#define MSR_FMASK 0xc0000084
  223 +#define MSR_FSBASE 0xc0000100
  224 +#define MSR_GSBASE 0xc0000101
  225 +#define MSR_KERNELGSBASE 0xc0000102
  226 +
  227 +/* cpuid_features bits */
  228 +#define CPUID_FP87 (1 << 0)
  229 +#define CPUID_VME (1 << 1)
  230 +#define CPUID_DE (1 << 2)
  231 +#define CPUID_PSE (1 << 3)
  232 +#define CPUID_TSC (1 << 4)
  233 +#define CPUID_MSR (1 << 5)
  234 +#define CPUID_PAE (1 << 6)
  235 +#define CPUID_MCE (1 << 7)
  236 +#define CPUID_CX8 (1 << 8)
  237 +#define CPUID_APIC (1 << 9)
  238 +#define CPUID_SEP (1 << 11) /* sysenter/sysexit */
  239 +#define CPUID_MTRR (1 << 12)
  240 +#define CPUID_PGE (1 << 13)
  241 +#define CPUID_MCA (1 << 14)
  242 +#define CPUID_CMOV (1 << 15)
  243 +/* ... */
  244 +#define CPUID_MMX (1 << 23)
  245 +#define CPUID_FXSR (1 << 24)
  246 +#define CPUID_SSE (1 << 25)
  247 +#define CPUID_SSE2 (1 << 26)
  248 +
196 249 #define EXCP00_DIVZ 0
197 250 #define EXCP01_SSTP 1
198 251 #define EXCP02_NMI 2
... ... @@ -219,42 +272,52 @@ enum {
219 272 CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */
220 273 CC_OP_MULW,
221 274 CC_OP_MULL,
  275 + CC_OP_MULQ,
222 276  
223 277 CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
224 278 CC_OP_ADDW,
225 279 CC_OP_ADDL,
  280 + CC_OP_ADDQ,
226 281  
227 282 CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
228 283 CC_OP_ADCW,
229 284 CC_OP_ADCL,
  285 + CC_OP_ADCQ,
230 286  
231 287 CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
232 288 CC_OP_SUBW,
233 289 CC_OP_SUBL,
  290 + CC_OP_SUBQ,
234 291  
235 292 CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
236 293 CC_OP_SBBW,
237 294 CC_OP_SBBL,
  295 + CC_OP_SBBQ,
238 296  
239 297 CC_OP_LOGICB, /* modify all flags, CC_DST = res */
240 298 CC_OP_LOGICW,
241 299 CC_OP_LOGICL,
  300 + CC_OP_LOGICQ,
242 301  
243 302 CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */
244 303 CC_OP_INCW,
245 304 CC_OP_INCL,
  305 + CC_OP_INCQ,
246 306  
247 307 CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */
248 308 CC_OP_DECW,
249 309 CC_OP_DECL,
  310 + CC_OP_DECQ,
250 311  
251 312 CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.msb = C */
252 313 CC_OP_SHLW,
253 314 CC_OP_SHLL,
  315 + CC_OP_SHLQ,
254 316  
255 317 CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
256 318 CC_OP_SARW,
257 319 CC_OP_SARL,
  320 + CC_OP_SARQ,
258 321  
259 322 CC_OP_NB,
260 323 };
... ... @@ -271,22 +334,42 @@ typedef double CPU86_LDouble;
271 334  
272 335 typedef struct SegmentCache {
273 336 uint32_t selector;
274   - uint8_t *base;
  337 + target_ulong base;
275 338 uint32_t limit;
276 339 uint32_t flags;
277 340 } SegmentCache;
278 341  
  342 +typedef struct {
  343 + union {
  344 + uint8_t b[16];
  345 + uint16_t w[8];
  346 + uint32_t l[4];
  347 + uint64_t q[2];
  348 + } u;
  349 +} XMMReg;
  350 +
  351 +#ifdef TARGET_X86_64
  352 +#define CPU_NB_REGS 16
  353 +#else
  354 +#define CPU_NB_REGS 8
  355 +#endif
  356 +
279 357 typedef struct CPUX86State {
  358 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  359 + /* temporaries if we cannot store them in host registers */
  360 + target_ulong t0, t1, t2;
  361 +#endif
  362 +
280 363 /* standard registers */
281   - uint32_t regs[8];
282   - uint32_t eip;
283   - uint32_t eflags; /* eflags register. During CPU emulation, CC
  364 + target_ulong regs[CPU_NB_REGS];
  365 + target_ulong eip;
  366 + target_ulong eflags; /* eflags register. During CPU emulation, CC
284 367 flags and DF are set to zero because they are
285 368 stored elsewhere */
286 369  
287 370 /* emulator internal eflags handling */
288   - uint32_t cc_src;
289   - uint32_t cc_dst;
  371 + target_ulong cc_src;
  372 + target_ulong cc_dst;
290 373 uint32_t cc_op;
291 374 int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
292 375 uint32_t hflags; /* hidden flags, see HF_xxx constants */
... ... @@ -314,10 +397,21 @@ typedef struct CPUX86State {
314 397 SegmentCache gdt; /* only base and limit are used */
315 398 SegmentCache idt; /* only base and limit are used */
316 399  
  400 + XMMReg xmm_regs[CPU_NB_REGS];
  401 + XMMReg xmm_t0;
  402 +
317 403 /* sysenter registers */
318 404 uint32_t sysenter_cs;
319 405 uint32_t sysenter_esp;
320 406 uint32_t sysenter_eip;
  407 +#ifdef TARGET_X86_64
  408 + target_ulong efer;
  409 + target_ulong star;
  410 + target_ulong lstar;
  411 + target_ulong cstar;
  412 + target_ulong fmask;
  413 + target_ulong kernelgsbase;
  414 +#endif
321 415  
322 416 /* temporary data for USE_CODE_COPY mode */
323 417 #ifdef USE_CODE_COPY
... ... @@ -333,8 +427,8 @@ typedef struct CPUX86State {
333 427 int exception_is_int;
334 428 int exception_next_eip;
335 429 struct TranslationBlock *current_tb; /* currently executing TB */
336   - uint32_t cr[5]; /* NOTE: cr1 is unused */
337   - uint32_t dr[8]; /* debug registers */
  430 + target_ulong cr[5]; /* NOTE: cr1 is unused */
  431 + target_ulong dr[8]; /* debug registers */
338 432 int interrupt_request;
339 433 int user_mode_only; /* user mode only simulation */
340 434  
... ... @@ -346,18 +440,28 @@ typedef struct CPUX86State {
346 440 context) */
347 441 unsigned long mem_write_pc; /* host pc at which the memory was
348 442 written */
349   - unsigned long mem_write_vaddr; /* target virtual addr at which the
350   - memory was written */
  443 + target_ulong mem_write_vaddr; /* target virtual addr at which the
  444 + memory was written */
351 445 /* 0 = kernel, 1 = user */
352 446 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
353 447 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
354 448  
355 449 /* from this point: preserved by CPU reset */
356 450 /* ice debug support */
357   - uint32_t breakpoints[MAX_BREAKPOINTS];
  451 + target_ulong breakpoints[MAX_BREAKPOINTS];
358 452 int nb_breakpoints;
359 453 int singlestep_enabled;
360 454  
  455 + /* processor features (e.g. for CPUID insn) */
  456 + uint32_t cpuid_vendor1;
  457 + uint32_t cpuid_vendor2;
  458 + uint32_t cpuid_vendor3;
  459 + uint32_t cpuid_version;
  460 + uint32_t cpuid_features;
  461 +
  462 + /* in order to simplify APIC support, we leave this pointer to the
  463 + user */
  464 + struct APICState *apic_state;
361 465 /* user data */
362 466 void *opaque;
363 467 } CPUX86State;
... ... @@ -382,7 +486,7 @@ void cpu_set_ferr(CPUX86State *s);
382 486 cache: it synchronizes the hflags with the segment cache values */
383 487 static inline void cpu_x86_load_seg_cache(CPUX86State *env,
384 488 int seg_reg, unsigned int selector,
385   - uint8_t *base, unsigned int limit,
  489 + uint32_t base, unsigned int limit,
386 490 unsigned int flags)
387 491 {
388 492 SegmentCache *sc;
... ... @@ -395,27 +499,45 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
395 499 sc->flags = flags;
396 500  
397 501 /* update the hidden flags */
398   - new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
399   - >> (DESC_B_SHIFT - HF_CS32_SHIFT);
400   - new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
401   - >> (DESC_B_SHIFT - HF_SS32_SHIFT);
402   - if (!(env->cr[0] & CR0_PE_MASK) ||
403   - (env->eflags & VM_MASK) ||
404   - !(new_hflags & HF_CS32_MASK)) {
405   - /* XXX: try to avoid this test. The problem comes from the
406   - fact that is real mode or vm86 mode we only modify the
407   - 'base' and 'selector' fields of the segment cache to go
408   - faster. A solution may be to force addseg to one in
409   - translate-i386.c. */
410   - new_hflags |= HF_ADDSEG_MASK;
411   - } else {
412   - new_hflags |= (((unsigned long)env->segs[R_DS].base |
413   - (unsigned long)env->segs[R_ES].base |
414   - (unsigned long)env->segs[R_SS].base) != 0) <<
415   - HF_ADDSEG_SHIFT;
  502 + {
  503 + if (seg_reg == R_CS) {
  504 +#ifdef TARGET_X86_64
  505 + if ((env->hflags & HF_LMA_MASK) && (flags & DESC_L_MASK)) {
  506 + /* long mode */
  507 + env->hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
  508 + env->hflags &= ~(HF_ADDSEG_MASK);
  509 + } else
  510 +#endif
  511 + {
  512 + /* legacy / compatibility case */
  513 + new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
  514 + >> (DESC_B_SHIFT - HF_CS32_SHIFT);
  515 + env->hflags = (env->hflags & ~(HF_CS32_MASK | HF_CS64_MASK)) |
  516 + new_hflags;
  517 + }
  518 + }
  519 + new_hflags = (env->segs[R_SS].flags & DESC_B_MASK)
  520 + >> (DESC_B_SHIFT - HF_SS32_SHIFT);
  521 + if (env->hflags & HF_CS64_MASK) {
  522 + /* zero base assumed for DS, ES and SS in long mode */
  523 + } else if (!(env->cr[0] & CR0_PE_MASK) ||
  524 + (env->eflags & VM_MASK) ||
  525 + !(new_hflags & HF_CS32_MASK)) {
  526 + /* XXX: try to avoid this test. The problem comes from the
  527 + fact that is real mode or vm86 mode we only modify the
  528 + 'base' and 'selector' fields of the segment cache to go
  529 + faster. A solution may be to force addseg to one in
  530 + translate-i386.c. */
  531 + new_hflags |= HF_ADDSEG_MASK;
  532 + } else {
  533 + new_hflags |= (((unsigned long)env->segs[R_DS].base |
  534 + (unsigned long)env->segs[R_ES].base |
  535 + (unsigned long)env->segs[R_SS].base) != 0) <<
  536 + HF_ADDSEG_SHIFT;
  537 + }
  538 + env->hflags = (env->hflags &
  539 + ~(HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;
416 540 }
417   - env->hflags = (env->hflags &
418   - ~(HF_CS32_MASK | HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;
419 541 }
420 542  
421 543 /* wrapper, just in case memory mappings must be changed */
... ... @@ -448,6 +570,9 @@ void cpu_x86_set_a20(CPUX86State *env, int a20_state);
448 570  
449 571 uint64_t cpu_get_tsc(CPUX86State *env);
450 572  
  573 +void cpu_set_apic_base(CPUX86State *env, uint64_t val);
  574 +uint64_t cpu_get_apic_base(CPUX86State *env);
  575 +
451 576 /* will be suppressed */
452 577 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
453 578  
... ...
target-i386/exec.h
... ... @@ -20,14 +20,29 @@
20 20 #include "config.h"
21 21 #include "dyngen-exec.h"
22 22  
  23 +/* XXX: factorize this mess */
  24 +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
  25 +#define HOST_LONG_BITS 64
  26 +#else
  27 +#define HOST_LONG_BITS 32
  28 +#endif
  29 +
  30 +#ifdef TARGET_X86_64
  31 +#define TARGET_LONG_BITS 64
  32 +#else
  33 +#define TARGET_LONG_BITS 32
  34 +#endif
  35 +
23 36 /* at least 4 register variables are defined */
24 37 register struct CPUX86State *env asm(AREG0);
  38 +
  39 +/* XXX: use 64 bit regs if HOST_LONG_BITS == 64 */
  40 +#if TARGET_LONG_BITS == 32
  41 +
25 42 register uint32_t T0 asm(AREG1);
26 43 register uint32_t T1 asm(AREG2);
27 44 register uint32_t T2 asm(AREG3);
28 45  
29   -#define A0 T2
30   -
31 46 /* if more registers are available, we define some registers too */
32 47 #ifdef AREG4
33 48 register uint32_t EAX asm(AREG4);
... ... @@ -69,6 +84,17 @@ register uint32_t EDI asm(AREG11);
69 84 #define reg_EDI
70 85 #endif
71 86  
  87 +#else
  88 +
  89 +/* no registers can be used */
  90 +#define T0 (env->t0)
  91 +#define T1 (env->t1)
  92 +#define T2 (env->t2)
  93 +
  94 +#endif
  95 +
  96 +#define A0 T2
  97 +
72 98 extern FILE *logfile;
73 99 extern int loglevel;
74 100  
... ... @@ -136,26 +162,24 @@ void helper_movl_crN_T0(int reg);
136 162 void helper_movl_drN_T0(int reg);
137 163 void helper_invlpg(unsigned int addr);
138 164 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
139   -void cpu_x86_update_cr3(CPUX86State *env, uint32_t new_cr3);
  165 +void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
140 166 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
141 167 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
142   -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
  168 +int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
143 169 int is_write, int is_user, int is_softmmu);
144   -void tlb_fill(unsigned long addr, int is_write, int is_user,
  170 +void tlb_fill(target_ulong addr, int is_write, int is_user,
145 171 void *retaddr);
146 172 void __hidden cpu_lock(void);
147 173 void __hidden cpu_unlock(void);
148 174 void do_interrupt(int intno, int is_int, int error_code,
149   - unsigned int next_eip, int is_hw);
  175 + target_ulong next_eip, int is_hw);
150 176 void do_interrupt_user(int intno, int is_int, int error_code,
151   - unsigned int next_eip);
  177 + target_ulong next_eip);
152 178 void raise_interrupt(int intno, int is_int, int error_code,
153 179 unsigned int next_eip);
154 180 void raise_exception_err(int exception_index, int error_code);
155 181 void raise_exception(int exception_index);
156 182 void __hidden cpu_loop_exit(void);
157   -void helper_fsave(uint8_t *ptr, int data32);
158   -void helper_frstor(uint8_t *ptr, int data32);
159 183  
160 184 void OPPROTO op_movl_eflags_T0(void);
161 185 void OPPROTO op_movl_T0_eflags(void);
... ... @@ -163,13 +187,20 @@ void raise_interrupt(int intno, int is_int, int error_code,
163 187 unsigned int next_eip);
164 188 void raise_exception_err(int exception_index, int error_code);
165 189 void raise_exception(int exception_index);
166   -void helper_divl_EAX_T0(uint32_t eip);
167   -void helper_idivl_EAX_T0(uint32_t eip);
  190 +void helper_divl_EAX_T0(void);
  191 +void helper_idivl_EAX_T0(void);
  192 +void helper_mulq_EAX_T0(void);
  193 +void helper_imulq_EAX_T0(void);
  194 +void helper_imulq_T0_T1(void);
  195 +void helper_divq_EAX_T0(void);
  196 +void helper_idivq_EAX_T0(void);
168 197 void helper_cmpxchg8b(void);
169 198 void helper_cpuid(void);
170 199 void helper_enter_level(int level, int data32);
171 200 void helper_sysenter(void);
172 201 void helper_sysexit(void);
  202 +void helper_syscall(void);
  203 +void helper_sysret(int dflag);
173 204 void helper_rdtsc(void);
174 205 void helper_rdmsr(void);
175 206 void helper_wrmsr(void);
... ... @@ -252,7 +283,7 @@ void check_iol_DX(void);
252 283 #define stl(p, v) stl_data(p, v)
253 284 #define stq(p, v) stq_data(p, v)
254 285  
255   -static inline double ldfq(void *ptr)
  286 +static inline double ldfq(target_ulong ptr)
256 287 {
257 288 union {
258 289 double d;
... ... @@ -262,7 +293,7 @@ static inline double ldfq(void *ptr)
262 293 return u.d;
263 294 }
264 295  
265   -static inline void stfq(void *ptr, double v)
  296 +static inline void stfq(target_ulong ptr, double v)
266 297 {
267 298 union {
268 299 double d;
... ... @@ -272,7 +303,7 @@ static inline void stfq(void *ptr, double v)
272 303 stq(ptr, u.i);
273 304 }
274 305  
275   -static inline float ldfl(void *ptr)
  306 +static inline float ldfl(target_ulong ptr)
276 307 {
277 308 union {
278 309 float f;
... ... @@ -282,7 +313,7 @@ static inline float ldfl(void *ptr)
282 313 return u.f;
283 314 }
284 315  
285   -static inline void stfl(void *ptr, float v)
  316 +static inline void stfl(target_ulong ptr, float v)
286 317 {
287 318 union {
288 319 float f;
... ... @@ -411,7 +442,7 @@ static inline void fpop(void)
411 442 }
412 443  
413 444 #ifndef USE_X86LDOUBLE
414   -static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
  445 +static inline CPU86_LDouble helper_fldt(target_ulong ptr)
415 446 {
416 447 CPU86_LDoubleU temp;
417 448 int upper, e;
... ... @@ -451,12 +482,12 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
451 482  
452 483 #ifdef CONFIG_USER_ONLY
453 484  
454   -static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
  485 +static inline CPU86_LDouble helper_fldt(target_ulong ptr)
455 486 {
456 487 return *(CPU86_LDouble *)ptr;
457 488 }
458 489  
459   -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
  490 +static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
460 491 {
461 492 *(CPU86_LDouble *)ptr = f;
462 493 }
... ... @@ -465,7 +496,7 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
465 496  
466 497 /* we use memory access macros */
467 498  
468   -static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
  499 +static inline CPU86_LDouble helper_fldt(target_ulong ptr)
469 500 {
470 501 CPU86_LDoubleU temp;
471 502  
... ... @@ -474,7 +505,7 @@ static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
474 505 return temp.d;
475 506 }
476 507  
477   -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
  508 +static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
478 509 {
479 510 CPU86_LDoubleU temp;
480 511  
... ... @@ -522,10 +553,12 @@ void helper_fscale(void);
522 553 void helper_fsin(void);
523 554 void helper_fcos(void);
524 555 void helper_fxam_ST0(void);
525   -void helper_fstenv(uint8_t *ptr, int data32);
526   -void helper_fldenv(uint8_t *ptr, int data32);
527   -void helper_fsave(uint8_t *ptr, int data32);
528   -void helper_frstor(uint8_t *ptr, int data32);
  556 +void helper_fstenv(target_ulong ptr, int data32);
  557 +void helper_fldenv(target_ulong ptr, int data32);
  558 +void helper_fsave(target_ulong ptr, int data32);
  559 +void helper_frstor(target_ulong ptr, int data32);
  560 +void helper_fxsave(target_ulong ptr, int data64);
  561 +void helper_fxrstor(target_ulong ptr, int data64);
529 562 void restore_native_fp_state(CPUState *env);
530 563 void save_native_fp_state(CPUState *env);
531 564  
... ...
target-i386/helper.c
... ... @@ -119,7 +119,7 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
119 119 {
120 120 SegmentCache *dt;
121 121 int index;
122   - uint8_t *ptr;
  122 + target_ulong ptr;
123 123  
124 124 if (selector & 0x4)
125 125 dt = &env->ldt;
... ... @@ -143,9 +143,9 @@ static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2)
143 143 return limit;
144 144 }
145 145  
146   -static inline uint8_t *get_seg_base(uint32_t e1, uint32_t e2)
  146 +static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2)
147 147 {
148   - return (uint8_t *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
  148 + return ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
149 149 }
150 150  
151 151 static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2)
... ... @@ -160,7 +160,7 @@ static inline void load_seg_vm(int seg, int selector)
160 160 {
161 161 selector &= 0xffff;
162 162 cpu_x86_load_seg_cache(env, seg, selector,
163   - (uint8_t *)(selector << 4), 0xffff, 0);
  163 + (selector << 4), 0xffff, 0);
164 164 }
165 165  
166 166 static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
... ... @@ -258,13 +258,13 @@ static void switch_tss(int tss_selector,
258 258 uint32_t next_eip)
259 259 {
260 260 int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i;
261   - uint8_t *tss_base;
  261 + target_ulong tss_base;
262 262 uint32_t new_regs[8], new_segs[6];
263 263 uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap;
264 264 uint32_t old_eflags, eflags_mask;
265 265 SegmentCache *dt;
266 266 int index;
267   - uint8_t *ptr;
  267 + target_ulong ptr;
268 268  
269 269 type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
270 270 #ifdef DEBUG_PCALL
... ... @@ -345,7 +345,7 @@ static void switch_tss(int tss_selector,
345 345  
346 346 /* clear busy bit (it is restartable) */
347 347 if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {
348   - uint8_t *ptr;
  348 + target_ulong ptr;
349 349 uint32_t e2;
350 350 ptr = env->gdt.base + (env->tr.selector & ~7);
351 351 e2 = ldl_kernel(ptr + 4);
... ... @@ -397,7 +397,7 @@ static void switch_tss(int tss_selector,
397 397  
398 398 /* set busy bit */
399 399 if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) {
400   - uint8_t *ptr;
  400 + target_ulong ptr;
401 401 uint32_t e2;
402 402 ptr = env->gdt.base + (tss_selector & ~7);
403 403 e2 = ldl_kernel(ptr + 4);
... ... @@ -445,11 +445,11 @@ static void switch_tss(int tss_selector,
445 445 cpu_x86_set_cpl(env, new_segs[R_CS] & 3);
446 446 /* first just selectors as the rest may trigger exceptions */
447 447 for(i = 0; i < 6; i++)
448   - cpu_x86_load_seg_cache(env, i, new_segs[i], NULL, 0, 0);
  448 + cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0);
449 449 }
450 450  
451 451 env->ldt.selector = new_ldt & ~4;
452   - env->ldt.base = NULL;
  452 + env->ldt.base = 0;
453 453 env->ldt.limit = 0;
454 454 env->ldt.flags = 0;
455 455  
... ... @@ -573,7 +573,7 @@ static inline unsigned int get_sp_mask(unsigned int e2)
573 573  
574 574 #define POPL(ssp, sp, sp_mask, val)\
575 575 {\
576   - val = ldl_kernel((ssp) + (sp & (sp_mask)));\
  576 + val = (uint32_t)ldl_kernel((ssp) + (sp & (sp_mask)));\
577 577 sp += 4;\
578 578 }
579 579  
... ... @@ -582,7 +582,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
582 582 unsigned int next_eip, int is_hw)
583 583 {
584 584 SegmentCache *dt;
585   - uint8_t *ptr, *ssp;
  585 + target_ulong ptr, ssp;
586 586 int type, dpl, selector, ss_dpl, cpl, sp_mask;
587 587 int has_error_code, new_stack, shift;
588 588 uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2;
... ... @@ -703,7 +703,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
703 703 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
704 704 new_stack = 0; /* avoid warning */
705 705 sp_mask = 0; /* avoid warning */
706   - ssp = NULL; /* avoid warning */
  706 + ssp = 0; /* avoid warning */
707 707 esp = 0; /* avoid warning */
708 708 }
709 709  
... ... @@ -754,10 +754,10 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
754 754  
755 755 if (new_stack) {
756 756 if (env->eflags & VM_MASK) {
757   - cpu_x86_load_seg_cache(env, R_ES, 0, NULL, 0, 0);
758   - cpu_x86_load_seg_cache(env, R_DS, 0, NULL, 0, 0);
759   - cpu_x86_load_seg_cache(env, R_FS, 0, NULL, 0, 0);
760   - cpu_x86_load_seg_cache(env, R_GS, 0, NULL, 0, 0);
  757 + cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
  758 + cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0);
  759 + cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0);
  760 + cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0);
761 761 }
762 762 ss = (ss & ~3) | dpl;
763 763 cpu_x86_load_seg_cache(env, R_SS, ss,
... ... @@ -780,12 +780,264 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
780 780 env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
781 781 }
782 782  
  783 +#ifdef TARGET_X86_64
  784 +
  785 +#define PUSHQ(sp, val)\
  786 +{\
  787 + sp -= 8;\
  788 + stq_kernel(sp, (val));\
  789 +}
  790 +
  791 +#define POPQ(sp, val)\
  792 +{\
  793 + val = ldq_kernel(sp);\
  794 + sp += 8;\
  795 +}
  796 +
  797 +static inline target_ulong get_rsp_from_tss(int level)
  798 +{
  799 + int index;
  800 +
  801 +#if 0
  802 + printf("TR: base=" TARGET_FMT_lx " limit=%x\n",
  803 + env->tr.base, env->tr.limit);
  804 +#endif
  805 +
  806 + if (!(env->tr.flags & DESC_P_MASK))
  807 + cpu_abort(env, "invalid tss");
  808 + index = 8 * level + 4;
  809 + if ((index + 7) > env->tr.limit)
  810 + raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
  811 + return ldq_kernel(env->tr.base + index);
  812 +}
  813 +
  814 +/* 64 bit interrupt */
  815 +static void do_interrupt64(int intno, int is_int, int error_code,
  816 + target_ulong next_eip, int is_hw)
  817 +{
  818 + SegmentCache *dt;
  819 + target_ulong ptr;
  820 + int type, dpl, selector, cpl, ist;
  821 + int has_error_code, new_stack;
  822 + uint32_t e1, e2, e3, ss;
  823 + target_ulong old_eip, esp, offset;
  824 +
  825 + has_error_code = 0;
  826 + if (!is_int && !is_hw) {
  827 + switch(intno) {
  828 + case 8:
  829 + case 10:
  830 + case 11:
  831 + case 12:
  832 + case 13:
  833 + case 14:
  834 + case 17:
  835 + has_error_code = 1;
  836 + break;
  837 + }
  838 + }
  839 + if (is_int)
  840 + old_eip = next_eip;
  841 + else
  842 + old_eip = env->eip;
  843 +
  844 + dt = &env->idt;
  845 + if (intno * 16 + 15 > dt->limit)
  846 + raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
  847 + ptr = dt->base + intno * 16;
  848 + e1 = ldl_kernel(ptr);
  849 + e2 = ldl_kernel(ptr + 4);
  850 + e3 = ldl_kernel(ptr + 8);
  851 + /* check gate type */
  852 + type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
  853 + switch(type) {
  854 + case 14: /* 386 interrupt gate */
  855 + case 15: /* 386 trap gate */
  856 + break;
  857 + default:
  858 + raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
  859 + break;
  860 + }
  861 + dpl = (e2 >> DESC_DPL_SHIFT) & 3;
  862 + cpl = env->hflags & HF_CPL_MASK;
  863 + /* check privledge if software int */
  864 + if (is_int && dpl < cpl)
  865 + raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
  866 + /* check valid bit */
  867 + if (!(e2 & DESC_P_MASK))
  868 + raise_exception_err(EXCP0B_NOSEG, intno * 16 + 2);
  869 + selector = e1 >> 16;
  870 + offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);
  871 + ist = e2 & 7;
  872 + if ((selector & 0xfffc) == 0)
  873 + raise_exception_err(EXCP0D_GPF, 0);
  874 +
  875 + if (load_segment(&e1, &e2, selector) != 0)
  876 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  877 + if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
  878 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  879 + dpl = (e2 >> DESC_DPL_SHIFT) & 3;
  880 + if (dpl > cpl)
  881 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  882 + if (!(e2 & DESC_P_MASK))
  883 + raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
  884 + if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK))
  885 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  886 + if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
  887 + /* to inner priviledge */
  888 + if (ist != 0)
  889 + esp = get_rsp_from_tss(ist + 3);
  890 + else
  891 + esp = get_rsp_from_tss(dpl);
  892 + ss = 0;
  893 + new_stack = 1;
  894 + } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
  895 + /* to same priviledge */
  896 + if (env->eflags & VM_MASK)
  897 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  898 + new_stack = 0;
  899 + esp = ESP & ~0xf; /* align stack */
  900 + dpl = cpl;
  901 + } else {
  902 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  903 + new_stack = 0; /* avoid warning */
  904 + esp = 0; /* avoid warning */
  905 + }
  906 +
  907 + PUSHQ(esp, env->segs[R_SS].selector);
  908 + PUSHQ(esp, ESP);
  909 + PUSHQ(esp, compute_eflags());
  910 + PUSHQ(esp, env->segs[R_CS].selector);
  911 + PUSHQ(esp, old_eip);
  912 + if (has_error_code) {
  913 + PUSHQ(esp, error_code);
  914 + }
  915 +
  916 + if (new_stack) {
  917 + ss = 0 | dpl;
  918 + cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
  919 + }
  920 + ESP = esp;
  921 +
  922 + selector = (selector & ~3) | dpl;
  923 + cpu_x86_load_seg_cache(env, R_CS, selector,
  924 + get_seg_base(e1, e2),
  925 + get_seg_limit(e1, e2),
  926 + e2);
  927 + cpu_x86_set_cpl(env, dpl);
  928 + env->eip = offset;
  929 +
  930 + /* interrupt gate clear IF mask */
  931 + if ((type & 1) == 0) {
  932 + env->eflags &= ~IF_MASK;
  933 + }
  934 + env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
  935 +}
  936 +
  937 +void helper_syscall(void)
  938 +{
  939 + int selector;
  940 +
  941 + if (!(env->efer & MSR_EFER_SCE)) {
  942 + raise_exception_err(EXCP06_ILLOP, 0);
  943 + }
  944 + selector = (env->star >> 32) & 0xffff;
  945 + if (env->hflags & HF_LMA_MASK) {
  946 + ECX = env->eip;
  947 + env->regs[11] = compute_eflags();
  948 +
  949 + cpu_x86_set_cpl(env, 0);
  950 + cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
  951 + 0, 0xffffffff,
  952 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  953 + DESC_S_MASK |
  954 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
  955 + cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
  956 + 0, 0xffffffff,
  957 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  958 + DESC_S_MASK |
  959 + DESC_W_MASK | DESC_A_MASK);
  960 + env->eflags &= ~env->fmask;
  961 + if (env->hflags & HF_CS64_MASK)
  962 + env->eip = env->lstar;
  963 + else
  964 + env->eip = env->cstar;
  965 + } else {
  966 + ECX = (uint32_t)env->eip;
  967 +
  968 + cpu_x86_set_cpl(env, 0);
  969 + cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
  970 + 0, 0xffffffff,
  971 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  972 + DESC_S_MASK |
  973 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
  974 + cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
  975 + 0, 0xffffffff,
  976 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  977 + DESC_S_MASK |
  978 + DESC_W_MASK | DESC_A_MASK);
  979 + env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
  980 + env->eip = (uint32_t)env->star;
  981 + }
  982 +}
  983 +
  984 +void helper_sysret(int dflag)
  985 +{
  986 + int cpl, selector;
  987 +
  988 + cpl = env->hflags & HF_CPL_MASK;
  989 + if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) {
  990 + raise_exception_err(EXCP0D_GPF, 0);
  991 + }
  992 + selector = (env->star >> 48) & 0xffff;
  993 + if (env->hflags & HF_LMA_MASK) {
  994 + if (dflag == 2) {
  995 + cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
  996 + 0, 0xffffffff,
  997 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  998 + DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
  999 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
  1000 + DESC_L_MASK);
  1001 + env->eip = ECX;
  1002 + } else {
  1003 + cpu_x86_load_seg_cache(env, R_CS, selector | 3,
  1004 + 0, 0xffffffff,
  1005 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  1006 + DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
  1007 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
  1008 + env->eip = (uint32_t)ECX;
  1009 + }
  1010 + cpu_x86_load_seg_cache(env, R_SS, selector + 8,
  1011 + 0, 0xffffffff,
  1012 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  1013 + DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
  1014 + DESC_W_MASK | DESC_A_MASK);
  1015 + load_eflags((uint32_t)(env->regs[11]), 0xffffffff);
  1016 + cpu_x86_set_cpl(env, 3);
  1017 + } else {
  1018 + cpu_x86_load_seg_cache(env, R_CS, selector | 3,
  1019 + 0, 0xffffffff,
  1020 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  1021 + DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
  1022 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
  1023 + env->eip = (uint32_t)ECX;
  1024 + cpu_x86_load_seg_cache(env, R_SS, selector + 8,
  1025 + 0, 0xffffffff,
  1026 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  1027 + DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
  1028 + DESC_W_MASK | DESC_A_MASK);
  1029 + env->eflags |= IF_MASK;
  1030 + cpu_x86_set_cpl(env, 3);
  1031 + }
  1032 +}
  1033 +#endif
  1034 +
783 1035 /* real mode interrupt */
784 1036 static void do_interrupt_real(int intno, int is_int, int error_code,
785 1037 unsigned int next_eip)
786 1038 {
787 1039 SegmentCache *dt;
788   - uint8_t *ptr, *ssp;
  1040 + target_ulong ptr, ssp;
789 1041 int selector;
790 1042 uint32_t offset, esp;
791 1043 uint32_t old_cs, old_eip;
... ... @@ -813,16 +1065,16 @@ static void do_interrupt_real(int intno, int is_int, int error_code,
813 1065 ESP = (ESP & ~0xffff) | (esp & 0xffff);
814 1066 env->eip = offset;
815 1067 env->segs[R_CS].selector = selector;
816   - env->segs[R_CS].base = (uint8_t *)(selector << 4);
  1068 + env->segs[R_CS].base = (selector << 4);
817 1069 env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
818 1070 }
819 1071  
820 1072 /* fake user mode interrupt */
821 1073 void do_interrupt_user(int intno, int is_int, int error_code,
822   - unsigned int next_eip)
  1074 + target_ulong next_eip)
823 1075 {
824 1076 SegmentCache *dt;
825   - uint8_t *ptr;
  1077 + target_ulong ptr;
826 1078 int dpl, cpl;
827 1079 uint32_t e2;
828 1080  
... ... @@ -849,26 +1101,26 @@ void do_interrupt_user(int intno, int is_int, int error_code,
849 1101 * instruction. It is only relevant if is_int is TRUE.
850 1102 */
851 1103 void do_interrupt(int intno, int is_int, int error_code,
852   - unsigned int next_eip, int is_hw)
  1104 + target_ulong next_eip, int is_hw)
853 1105 {
854 1106 #ifdef DEBUG_PCALL
855 1107 if (loglevel & (CPU_LOG_PCALL | CPU_LOG_INT)) {
856 1108 if ((env->cr[0] & CR0_PE_MASK)) {
857 1109 static int count;
858   - fprintf(logfile, "%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:%08x pc=%08x SP=%04x:%08x",
  1110 + fprintf(logfile, "%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
859 1111 count, intno, error_code, is_int,
860 1112 env->hflags & HF_CPL_MASK,
861 1113 env->segs[R_CS].selector, EIP,
862 1114 (int)env->segs[R_CS].base + EIP,
863 1115 env->segs[R_SS].selector, ESP);
864 1116 if (intno == 0x0e) {
865   - fprintf(logfile, " CR2=%08x", env->cr[2]);
  1117 + fprintf(logfile, " CR2=" TARGET_FMT_lx, env->cr[2]);
866 1118 } else {
867   - fprintf(logfile, " EAX=%08x", EAX);
  1119 + fprintf(logfile, " EAX=" TARGET_FMT_lx, EAX);
868 1120 }
869 1121 fprintf(logfile, "\n");
870   -#if 0
871 1122 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
  1123 +#if 0
872 1124 {
873 1125 int i;
874 1126 uint8_t *ptr;
... ... @@ -885,7 +1137,14 @@ void do_interrupt(int intno, int is_int, int error_code,
885 1137 }
886 1138 #endif
887 1139 if (env->cr[0] & CR0_PE_MASK) {
888   - do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
  1140 +#if TARGET_X86_64
  1141 + if (env->hflags & HF_LMA_MASK) {
  1142 + do_interrupt64(intno, is_int, error_code, next_eip, is_hw);
  1143 + } else
  1144 +#endif
  1145 + {
  1146 + do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
  1147 + }
889 1148 } else {
890 1149 do_interrupt_real(intno, is_int, error_code, next_eip);
891 1150 }
... ... @@ -932,20 +1191,20 @@ void raise_exception(int exception_index)
932 1191 #ifdef BUGGY_GCC_DIV64
933 1192 /* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we
934 1193 call it from another function */
935   -uint32_t div64(uint32_t *q_ptr, uint64_t num, uint32_t den)
  1194 +uint32_t div32(uint32_t *q_ptr, uint64_t num, uint32_t den)
936 1195 {
937 1196 *q_ptr = num / den;
938 1197 return num % den;
939 1198 }
940 1199  
941   -int32_t idiv64(int32_t *q_ptr, int64_t num, int32_t den)
  1200 +int32_t idiv32(int32_t *q_ptr, int64_t num, int32_t den)
942 1201 {
943 1202 *q_ptr = num / den;
944 1203 return num % den;
945 1204 }
946 1205 #endif
947 1206  
948   -void helper_divl_EAX_T0(uint32_t eip)
  1207 +void helper_divl_EAX_T0(void)
949 1208 {
950 1209 unsigned int den, q, r;
951 1210 uint64_t num;
... ... @@ -953,20 +1212,19 @@ void helper_divl_EAX_T0(uint32_t eip)
953 1212 num = EAX | ((uint64_t)EDX << 32);
954 1213 den = T0;
955 1214 if (den == 0) {
956   - EIP = eip;
957 1215 raise_exception(EXCP00_DIVZ);
958 1216 }
959 1217 #ifdef BUGGY_GCC_DIV64
960   - r = div64(&q, num, den);
  1218 + r = div32(&q, num, den);
961 1219 #else
962 1220 q = (num / den);
963 1221 r = (num % den);
964 1222 #endif
965   - EAX = q;
966   - EDX = r;
  1223 + EAX = (uint32_t)q;
  1224 + EDX = (uint32_t)r;
967 1225 }
968 1226  
969   -void helper_idivl_EAX_T0(uint32_t eip)
  1227 +void helper_idivl_EAX_T0(void)
970 1228 {
971 1229 int den, q, r;
972 1230 int64_t num;
... ... @@ -974,17 +1232,16 @@ void helper_idivl_EAX_T0(uint32_t eip)
974 1232 num = EAX | ((uint64_t)EDX << 32);
975 1233 den = T0;
976 1234 if (den == 0) {
977   - EIP = eip;
978 1235 raise_exception(EXCP00_DIVZ);
979 1236 }
980 1237 #ifdef BUGGY_GCC_DIV64
981   - r = idiv64(&q, num, den);
  1238 + r = idiv32(&q, num, den);
982 1239 #else
983 1240 q = (num / den);
984 1241 r = (num % den);
985 1242 #endif
986   - EAX = q;
987   - EDX = r;
  1243 + EAX = (uint32_t)q;
  1244 + EDX = (uint32_t)r;
988 1245 }
989 1246  
990 1247 void helper_cmpxchg8b(void)
... ... @@ -993,9 +1250,9 @@ void helper_cmpxchg8b(void)
993 1250 int eflags;
994 1251  
995 1252 eflags = cc_table[CC_OP].compute_all();
996   - d = ldq((uint8_t *)A0);
  1253 + d = ldq(A0);
997 1254 if (d == (((uint64_t)EDX << 32) | EAX)) {
998   - stq((uint8_t *)A0, ((uint64_t)ECX << 32) | EBX);
  1255 + stq(A0, ((uint64_t)ECX << 32) | EBX);
999 1256 eflags |= CC_Z;
1000 1257 } else {
1001 1258 EDX = d >> 32;
... ... @@ -1005,58 +1262,20 @@ void helper_cmpxchg8b(void)
1005 1262 CC_SRC = eflags;
1006 1263 }
1007 1264  
1008   -#define CPUID_FP87 (1 << 0)
1009   -#define CPUID_VME (1 << 1)
1010   -#define CPUID_DE (1 << 2)
1011   -#define CPUID_PSE (1 << 3)
1012   -#define CPUID_TSC (1 << 4)
1013   -#define CPUID_MSR (1 << 5)
1014   -#define CPUID_PAE (1 << 6)
1015   -#define CPUID_MCE (1 << 7)
1016   -#define CPUID_CX8 (1 << 8)
1017   -#define CPUID_APIC (1 << 9)
1018   -#define CPUID_SEP (1 << 11) /* sysenter/sysexit */
1019   -#define CPUID_MTRR (1 << 12)
1020   -#define CPUID_PGE (1 << 13)
1021   -#define CPUID_MCA (1 << 14)
1022   -#define CPUID_CMOV (1 << 15)
1023   -/* ... */
1024   -#define CPUID_MMX (1 << 23)
1025   -#define CPUID_FXSR (1 << 24)
1026   -#define CPUID_SSE (1 << 25)
1027   -#define CPUID_SSE2 (1 << 26)
1028   -
1029 1265 void helper_cpuid(void)
1030 1266 {
1031   - switch(EAX) {
  1267 + switch((uint32_t)EAX) {
1032 1268 case 0:
1033 1269 EAX = 2; /* max EAX index supported */
1034   - EBX = 0x756e6547;
1035   - ECX = 0x6c65746e;
1036   - EDX = 0x49656e69;
  1270 + EBX = env->cpuid_vendor1;
  1271 + EDX = env->cpuid_vendor2;
  1272 + ECX = env->cpuid_vendor3;
1037 1273 break;
1038 1274 case 1:
1039   - {
1040   - int family, model, stepping;
1041   - /* EAX = 1 info */
1042   -#if 0
1043   - /* pentium 75-200 */
1044   - family = 5;
1045   - model = 2;
1046   - stepping = 11;
1047   -#else
1048   - /* pentium pro */
1049   - family = 6;
1050   - model = 1;
1051   - stepping = 3;
1052   -#endif
1053   - EAX = (family << 8) | (model << 4) | stepping;
1054   - EBX = 0;
1055   - ECX = 0;
1056   - EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE |
1057   - CPUID_TSC | CPUID_MSR | CPUID_MCE |
1058   - CPUID_CX8 | CPUID_PGE | CPUID_CMOV;
1059   - }
  1275 + EAX = env->cpuid_version;
  1276 + EBX = 0;
  1277 + ECX = 0;
  1278 + EDX = env->cpuid_features;
1060 1279 break;
1061 1280 default:
1062 1281 /* cache info: needed for Pentium Pro compatibility */
... ... @@ -1065,12 +1284,34 @@ void helper_cpuid(void)
1065 1284 ECX = 0;
1066 1285 EDX = 0;
1067 1286 break;
  1287 +#ifdef TARGET_X86_64
  1288 + case 0x80000000:
  1289 + EAX = 0x80000008;
  1290 + EBX = env->cpuid_vendor1;
  1291 + EDX = env->cpuid_vendor2;
  1292 + ECX = env->cpuid_vendor3;
  1293 + break;
  1294 + case 0x80000001:
  1295 + EAX = env->cpuid_features;
  1296 + EBX = 0;
  1297 + ECX = 0;
  1298 + /* long mode + syscall/sysret features */
  1299 + EDX = (env->cpuid_features & 0x0183F3FF) | (1 << 29) | (1 << 11);
  1300 + break;
  1301 + case 0x80000008:
  1302 + /* virtual & phys address size in low 2 bytes. */
  1303 + EAX = 0x00003028;
  1304 + EBX = 0;
  1305 + ECX = 0;
  1306 + EDX = 0;
  1307 + break;
  1308 +#endif
1068 1309 }
1069 1310 }
1070 1311  
1071 1312 void helper_enter_level(int level, int data32)
1072 1313 {
1073   - uint8_t *ssp;
  1314 + target_ulong ssp;
1074 1315 uint32_t esp_mask, esp, ebp;
1075 1316  
1076 1317 esp_mask = get_sp_mask(env->segs[R_SS].flags);
... ... @@ -1105,20 +1346,26 @@ void helper_lldt_T0(void)
1105 1346 int selector;
1106 1347 SegmentCache *dt;
1107 1348 uint32_t e1, e2;
1108   - int index;
1109   - uint8_t *ptr;
  1349 + int index, entry_limit;
  1350 + target_ulong ptr;
1110 1351  
1111 1352 selector = T0 & 0xffff;
1112 1353 if ((selector & 0xfffc) == 0) {
1113 1354 /* XXX: NULL selector case: invalid LDT */
1114   - env->ldt.base = NULL;
  1355 + env->ldt.base = 0;
1115 1356 env->ldt.limit = 0;
1116 1357 } else {
1117 1358 if (selector & 0x4)
1118 1359 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1119 1360 dt = &env->gdt;
1120 1361 index = selector & ~7;
1121   - if ((index + 7) > dt->limit)
  1362 +#ifdef TARGET_X86_64
  1363 + if (env->hflags & HF_LMA_MASK)
  1364 + entry_limit = 15;
  1365 + else
  1366 +#endif
  1367 + entry_limit = 7;
  1368 + if ((index + entry_limit) > dt->limit)
1122 1369 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1123 1370 ptr = dt->base + index;
1124 1371 e1 = ldl_kernel(ptr);
... ... @@ -1127,7 +1374,17 @@ void helper_lldt_T0(void)
1127 1374 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1128 1375 if (!(e2 & DESC_P_MASK))
1129 1376 raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
1130   - load_seg_cache_raw_dt(&env->ldt, e1, e2);
  1377 +#ifdef TARGET_X86_64
  1378 + if (env->hflags & HF_LMA_MASK) {
  1379 + uint32_t e3;
  1380 + e3 = ldl_kernel(ptr + 8);
  1381 + load_seg_cache_raw_dt(&env->ldt, e1, e2);
  1382 + env->ldt.base |= (target_ulong)e3 << 32;
  1383 + } else
  1384 +#endif
  1385 + {
  1386 + load_seg_cache_raw_dt(&env->ldt, e1, e2);
  1387 + }
1131 1388 }
1132 1389 env->ldt.selector = selector;
1133 1390 }
... ... @@ -1137,13 +1394,13 @@ void helper_ltr_T0(void)
1137 1394 int selector;
1138 1395 SegmentCache *dt;
1139 1396 uint32_t e1, e2;
1140   - int index, type;
1141   - uint8_t *ptr;
  1397 + int index, type, entry_limit;
  1398 + target_ulong ptr;
1142 1399  
1143 1400 selector = T0 & 0xffff;
1144 1401 if ((selector & 0xfffc) == 0) {
1145   - /* NULL selector case: invalid LDT */
1146   - env->tr.base = NULL;
  1402 + /* NULL selector case: invalid TR */
  1403 + env->tr.base = 0;
1147 1404 env->tr.limit = 0;
1148 1405 env->tr.flags = 0;
1149 1406 } else {
... ... @@ -1151,7 +1408,13 @@ void helper_ltr_T0(void)
1151 1408 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1152 1409 dt = &env->gdt;
1153 1410 index = selector & ~7;
1154   - if ((index + 7) > dt->limit)
  1411 +#ifdef TARGET_X86_64
  1412 + if (env->hflags & HF_LMA_MASK)
  1413 + entry_limit = 15;
  1414 + else
  1415 +#endif
  1416 + entry_limit = 7;
  1417 + if ((index + entry_limit) > dt->limit)
1155 1418 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1156 1419 ptr = dt->base + index;
1157 1420 e1 = ldl_kernel(ptr);
... ... @@ -1162,7 +1425,17 @@ void helper_ltr_T0(void)
1162 1425 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1163 1426 if (!(e2 & DESC_P_MASK))
1164 1427 raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
1165   - load_seg_cache_raw_dt(&env->tr, e1, e2);
  1428 +#ifdef TARGET_X86_64
  1429 + if (env->hflags & HF_LMA_MASK) {
  1430 + uint32_t e3;
  1431 + e3 = ldl_kernel(ptr + 8);
  1432 + load_seg_cache_raw_dt(&env->tr, e1, e2);
  1433 + env->tr.base |= (target_ulong)e3 << 32;
  1434 + } else
  1435 +#endif
  1436 + {
  1437 + load_seg_cache_raw_dt(&env->tr, e1, e2);
  1438 + }
1166 1439 e2 |= DESC_TSS_BUSY_MASK;
1167 1440 stl_kernel(ptr + 4, e2);
1168 1441 }
... ... @@ -1176,14 +1449,14 @@ void load_seg(int seg_reg, int selector)
1176 1449 int cpl, dpl, rpl;
1177 1450 SegmentCache *dt;
1178 1451 int index;
1179   - uint8_t *ptr;
  1452 + target_ulong ptr;
1180 1453  
1181 1454 selector &= 0xffff;
1182 1455 if ((selector & 0xfffc) == 0) {
1183 1456 /* null selector case */
1184 1457 if (seg_reg == R_SS)
1185 1458 raise_exception_err(EXCP0D_GPF, 0);
1186   - cpu_x86_load_seg_cache(env, seg_reg, selector, NULL, 0, 0);
  1459 + cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
1187 1460 } else {
1188 1461  
1189 1462 if (selector & 0x4)
... ... @@ -1196,7 +1469,7 @@ void load_seg(int seg_reg, int selector)
1196 1469 ptr = dt->base + index;
1197 1470 e1 = ldl_kernel(ptr);
1198 1471 e2 = ldl_kernel(ptr + 4);
1199   -
  1472 +
1200 1473 if (!(e2 & DESC_S_MASK))
1201 1474 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1202 1475 rpl = selector & 3;
... ... @@ -1247,9 +1520,10 @@ void load_seg(int seg_reg, int selector)
1247 1520 /* protected mode jump */
1248 1521 void helper_ljmp_protected_T0_T1(int next_eip)
1249 1522 {
1250   - int new_cs, new_eip, gate_cs, type;
  1523 + int new_cs, gate_cs, type;
1251 1524 uint32_t e1, e2, cpl, dpl, rpl, limit;
1252   -
  1525 + target_ulong new_eip;
  1526 +
1253 1527 new_cs = T0;
1254 1528 new_eip = T1;
1255 1529 if ((new_cs & 0xfffc) == 0)
... ... @@ -1312,7 +1586,7 @@ void helper_ljmp_protected_T0_T1(int next_eip)
1312 1586 if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) !=
1313 1587 (DESC_S_MASK | DESC_CS_MASK)))
1314 1588 raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
1315   - if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
  1589 + if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
1316 1590 (!(e2 & DESC_C_MASK) && (dpl != cpl)))
1317 1591 raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
1318 1592 if (!(e2 & DESC_P_MASK))
... ... @@ -1336,7 +1610,7 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
1336 1610 {
1337 1611 int new_cs, new_eip;
1338 1612 uint32_t esp, esp_mask;
1339   - uint8_t *ssp;
  1613 + target_ulong ssp;
1340 1614  
1341 1615 new_cs = T0;
1342 1616 new_eip = T1;
... ... @@ -1354,7 +1628,7 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
1354 1628 ESP = (ESP & ~esp_mask) | (esp & esp_mask);
1355 1629 env->eip = new_eip;
1356 1630 env->segs[R_CS].selector = new_cs;
1357   - env->segs[R_CS].base = (uint8_t *)(new_cs << 4);
  1631 + env->segs[R_CS].base = (new_cs << 4);
1358 1632 }
1359 1633  
1360 1634 /* protected mode call */
... ... @@ -1364,7 +1638,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1364 1638 uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
1365 1639 uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
1366 1640 uint32_t val, limit, old_sp_mask;
1367   - uint8_t *ssp, *old_ssp;
  1641 + target_ulong ssp, old_ssp;
1368 1642  
1369 1643 new_cs = T0;
1370 1644 new_eip = T1;
... ... @@ -1471,7 +1745,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1471 1745 get_ss_esp_from_tss(&ss, &sp, dpl);
1472 1746 #ifdef DEBUG_PCALL
1473 1747 if (loglevel & CPU_LOG_PCALL)
1474   - fprintf(logfile, "new ss:esp=%04x:%08x param_count=%d ESP=%x\n",
  1748 + fprintf(logfile, "new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
1475 1749 ss, sp, param_count, ESP);
1476 1750 #endif
1477 1751 if ((ss & 0xfffc) == 0)
... ... @@ -1555,7 +1829,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1555 1829 void helper_iret_real(int shift)
1556 1830 {
1557 1831 uint32_t sp, new_cs, new_eip, new_eflags, sp_mask;
1558   - uint8_t *ssp;
  1832 + target_ulong ssp;
1559 1833 int eflags_mask;
1560 1834  
1561 1835 sp_mask = 0xffff; /* XXXX: use SS segment size ? */
... ... @@ -1595,7 +1869,7 @@ static inline void validate_seg(int seg_reg, int cpl)
1595 1869 if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
1596 1870 /* data or non conforming code segment */
1597 1871 if (dpl < cpl) {
1598   - cpu_x86_load_seg_cache(env, seg_reg, 0, NULL, 0, 0);
  1872 + cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0);
1599 1873 }
1600 1874 }
1601 1875 }
... ... @@ -1603,16 +1877,31 @@ static inline void validate_seg(int seg_reg, int cpl)
1603 1877 /* protected mode iret */
1604 1878 static inline void helper_ret_protected(int shift, int is_iret, int addend)
1605 1879 {
1606   - uint32_t sp, new_cs, new_eip, new_eflags, new_esp, new_ss, sp_mask;
  1880 + uint32_t new_cs, new_eflags, new_ss;
1607 1881 uint32_t new_es, new_ds, new_fs, new_gs;
1608 1882 uint32_t e1, e2, ss_e1, ss_e2;
1609 1883 int cpl, dpl, rpl, eflags_mask, iopl;
1610   - uint8_t *ssp;
  1884 + target_ulong ssp, sp, new_eip, new_esp, sp_mask;
1611 1885  
1612   - sp_mask = get_sp_mask(env->segs[R_SS].flags);
  1886 +#ifdef TARGET_X86_64
  1887 + if (shift == 2)
  1888 + sp_mask = -1;
  1889 + else
  1890 +#endif
  1891 + sp_mask = get_sp_mask(env->segs[R_SS].flags);
1613 1892 sp = ESP;
1614 1893 ssp = env->segs[R_SS].base;
1615 1894 new_eflags = 0; /* avoid warning */
  1895 +#ifdef TARGET_X86_64
  1896 + if (shift == 2) {
  1897 + POPQ(sp, new_eip);
  1898 + POPQ(sp, new_cs);
  1899 + new_cs &= 0xffff;
  1900 + if (is_iret) {
  1901 + POPQ(sp, new_eflags);
  1902 + }
  1903 + } else
  1904 +#endif
1616 1905 if (shift == 1) {
1617 1906 /* 32 bits */
1618 1907 POPL(ssp, sp, sp_mask, new_eip);
... ... @@ -1632,7 +1921,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1632 1921 }
1633 1922 #ifdef DEBUG_PCALL
1634 1923 if (loglevel & CPU_LOG_PCALL) {
1635   - fprintf(logfile, "lret new %04x:%08x s=%d addend=0x%x\n",
  1924 + fprintf(logfile, "lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
1636 1925 new_cs, new_eip, shift, addend);
1637 1926 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
1638 1927 }
... ... @@ -1660,7 +1949,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1660 1949 raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
1661 1950  
1662 1951 sp += addend;
1663   - if (rpl == cpl) {
  1952 + if (rpl == cpl && !(env->hflags & HF_CS64_MASK)) {
1664 1953 /* return to same priledge level */
1665 1954 cpu_x86_load_seg_cache(env, R_CS, new_cs,
1666 1955 get_seg_base(e1, e2),
... ... @@ -1668,6 +1957,13 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1668 1957 e2);
1669 1958 } else {
1670 1959 /* return to different priviledge level */
  1960 +#ifdef TARGET_X86_64
  1961 + if (shift == 2) {
  1962 + POPQ(sp, new_esp);
  1963 + POPQ(sp, new_ss);
  1964 + new_ss &= 0xffff;
  1965 + } else
  1966 +#endif
1671 1967 if (shift == 1) {
1672 1968 /* 32 bits */
1673 1969 POPL(ssp, sp, sp_mask, new_esp);
... ... @@ -1680,36 +1976,49 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1680 1976 }
1681 1977 #ifdef DEBUG_PCALL
1682 1978 if (loglevel & CPU_LOG_PCALL) {
1683   - fprintf(logfile, "new ss:esp=%04x:%08x\n",
  1979 + fprintf(logfile, "new ss:esp=%04x:" TARGET_FMT_lx "\n",
1684 1980 new_ss, new_esp);
1685 1981 }
1686 1982 #endif
1687   -
1688   - if ((new_ss & 3) != rpl)
1689   - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
1690   - if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)
1691   - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
1692   - if (!(ss_e2 & DESC_S_MASK) ||
1693   - (ss_e2 & DESC_CS_MASK) ||
1694   - !(ss_e2 & DESC_W_MASK))
1695   - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
1696   - dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
1697   - if (dpl != rpl)
1698   - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
1699   - if (!(ss_e2 & DESC_P_MASK))
1700   - raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
  1983 + if ((env->hflags & HF_LMA_MASK) && (new_ss & 0xfffc) == 0) {
  1984 + /* NULL ss is allowed in long mode */
  1985 + cpu_x86_load_seg_cache(env, R_SS, new_ss,
  1986 + 0, 0xffffffff,
  1987 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  1988 + DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
  1989 + DESC_W_MASK | DESC_A_MASK);
  1990 + } else {
  1991 + if ((new_ss & 3) != rpl)
  1992 + raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
  1993 + if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)
  1994 + raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
  1995 + if (!(ss_e2 & DESC_S_MASK) ||
  1996 + (ss_e2 & DESC_CS_MASK) ||
  1997 + !(ss_e2 & DESC_W_MASK))
  1998 + raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
  1999 + dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
  2000 + if (dpl != rpl)
  2001 + raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
  2002 + if (!(ss_e2 & DESC_P_MASK))
  2003 + raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
  2004 + cpu_x86_load_seg_cache(env, R_SS, new_ss,
  2005 + get_seg_base(ss_e1, ss_e2),
  2006 + get_seg_limit(ss_e1, ss_e2),
  2007 + ss_e2);
  2008 + }
1701 2009  
1702 2010 cpu_x86_load_seg_cache(env, R_CS, new_cs,
1703 2011 get_seg_base(e1, e2),
1704 2012 get_seg_limit(e1, e2),
1705 2013 e2);
1706   - cpu_x86_load_seg_cache(env, R_SS, new_ss,
1707   - get_seg_base(ss_e1, ss_e2),
1708   - get_seg_limit(ss_e1, ss_e2),
1709   - ss_e2);
1710 2014 cpu_x86_set_cpl(env, rpl);
1711 2015 sp = new_esp;
1712   - sp_mask = get_sp_mask(ss_e2);
  2016 +#ifdef TARGET_X86_64
  2017 + if (shift == 2)
  2018 + sp_mask = -1;
  2019 + else
  2020 +#endif
  2021 + sp_mask = get_sp_mask(ss_e2);
1713 2022  
1714 2023 /* validate data segments */
1715 2024 validate_seg(R_ES, cpl);
... ... @@ -1765,6 +2074,10 @@ void helper_iret_protected(int shift, int next_eip)
1765 2074  
1766 2075 /* specific case for TSS */
1767 2076 if (env->eflags & NT_MASK) {
  2077 +#ifdef TARGET_X86_64
  2078 + if (env->hflags & HF_LMA_MASK)
  2079 + raise_exception_err(EXCP0D_GPF, 0);
  2080 +#endif
1768 2081 tss_selector = lduw_kernel(env->tr.base + 0);
1769 2082 if (tss_selector & 4)
1770 2083 raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
... ... @@ -1793,12 +2106,12 @@ void helper_sysenter(void)
1793 2106 env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
1794 2107 cpu_x86_set_cpl(env, 0);
1795 2108 cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc,
1796   - NULL, 0xffffffff,
  2109 + 0, 0xffffffff,
1797 2110 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1798 2111 DESC_S_MASK |
1799 2112 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
1800 2113 cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc,
1801   - NULL, 0xffffffff,
  2114 + 0, 0xffffffff,
1802 2115 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1803 2116 DESC_S_MASK |
1804 2117 DESC_W_MASK | DESC_A_MASK);
... ... @@ -1816,12 +2129,12 @@ void helper_sysexit(void)
1816 2129 }
1817 2130 cpu_x86_set_cpl(env, 3);
1818 2131 cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3,
1819   - NULL, 0xffffffff,
  2132 + 0, 0xffffffff,
1820 2133 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1821 2134 DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1822 2135 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
1823 2136 cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3,
1824   - NULL, 0xffffffff,
  2137 + 0, 0xffffffff,
1825 2138 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1826 2139 DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1827 2140 DESC_W_MASK | DESC_A_MASK);
... ... @@ -1863,22 +2176,67 @@ void helper_rdtsc(void)
1863 2176 uint64_t val;
1864 2177  
1865 2178 val = cpu_get_tsc(env);
1866   - EAX = val;
1867   - EDX = val >> 32;
  2179 + EAX = (uint32_t)(val);
  2180 + EDX = (uint32_t)(val >> 32);
  2181 +}
  2182 +
  2183 +#if defined(CONFIG_USER_ONLY)
  2184 +void helper_wrmsr(void)
  2185 +{
1868 2186 }
1869 2187  
  2188 +void helper_rdmsr(void)
  2189 +{
  2190 +}
  2191 +#else
1870 2192 void helper_wrmsr(void)
1871 2193 {
1872   - switch(ECX) {
  2194 + uint64_t val;
  2195 +
  2196 + val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
  2197 +
  2198 + switch((uint32_t)ECX) {
1873 2199 case MSR_IA32_SYSENTER_CS:
1874   - env->sysenter_cs = EAX & 0xffff;
  2200 + env->sysenter_cs = val & 0xffff;
1875 2201 break;
1876 2202 case MSR_IA32_SYSENTER_ESP:
1877   - env->sysenter_esp = EAX;
  2203 + env->sysenter_esp = val;
1878 2204 break;
1879 2205 case MSR_IA32_SYSENTER_EIP:
1880   - env->sysenter_eip = EAX;
  2206 + env->sysenter_eip = val;
  2207 + break;
  2208 + case MSR_IA32_APICBASE:
  2209 + cpu_set_apic_base(env, val);
  2210 + break;
  2211 +#ifdef TARGET_X86_64
  2212 + case MSR_EFER:
  2213 +#define MSR_EFER_UPDATE_MASK (MSR_EFER_SCE | MSR_EFER_LME | \
  2214 + MSR_EFER_NXE | MSR_EFER_FFXSR)
  2215 + env->efer = (env->efer & ~MSR_EFER_UPDATE_MASK) |
  2216 + (val & MSR_EFER_UPDATE_MASK);
1881 2217 break;
  2218 + case MSR_STAR:
  2219 + env->star = val;
  2220 + break;
  2221 + case MSR_LSTAR:
  2222 + env->lstar = val;
  2223 + break;
  2224 + case MSR_CSTAR:
  2225 + env->cstar = val;
  2226 + break;
  2227 + case MSR_FMASK:
  2228 + env->fmask = val;
  2229 + break;
  2230 + case MSR_FSBASE:
  2231 + env->segs[R_FS].base = val;
  2232 + break;
  2233 + case MSR_GSBASE:
  2234 + env->segs[R_GS].base = val;
  2235 + break;
  2236 + case MSR_KERNELGSBASE:
  2237 + env->kernelgsbase = val;
  2238 + break;
  2239 +#endif
1882 2240 default:
1883 2241 /* XXX: exception ? */
1884 2242 break;
... ... @@ -1887,24 +2245,55 @@ void helper_wrmsr(void)
1887 2245  
1888 2246 void helper_rdmsr(void)
1889 2247 {
1890   - switch(ECX) {
  2248 + uint64_t val;
  2249 + switch((uint32_t)ECX) {
1891 2250 case MSR_IA32_SYSENTER_CS:
1892   - EAX = env->sysenter_cs;
1893   - EDX = 0;
  2251 + val = env->sysenter_cs;
1894 2252 break;
1895 2253 case MSR_IA32_SYSENTER_ESP:
1896   - EAX = env->sysenter_esp;
1897   - EDX = 0;
  2254 + val = env->sysenter_esp;
1898 2255 break;
1899 2256 case MSR_IA32_SYSENTER_EIP:
1900   - EAX = env->sysenter_eip;
1901   - EDX = 0;
  2257 + val = env->sysenter_eip;
  2258 + break;
  2259 + case MSR_IA32_APICBASE:
  2260 + val = cpu_get_apic_base(env);
  2261 + break;
  2262 +#ifdef TARGET_X86_64
  2263 + case MSR_EFER:
  2264 + val = env->efer;
  2265 + break;
  2266 + case MSR_STAR:
  2267 + val = env->star;
  2268 + break;
  2269 + case MSR_LSTAR:
  2270 + val = env->lstar;
  2271 + break;
  2272 + case MSR_CSTAR:
  2273 + val = env->cstar;
  2274 + break;
  2275 + case MSR_FMASK:
  2276 + val = env->fmask;
  2277 + break;
  2278 + case MSR_FSBASE:
  2279 + val = env->segs[R_FS].base;
  2280 + break;
  2281 + case MSR_GSBASE:
  2282 + val = env->segs[R_GS].base;
1902 2283 break;
  2284 + case MSR_KERNELGSBASE:
  2285 + val = env->kernelgsbase;
  2286 + break;
  2287 +#endif
1903 2288 default:
1904 2289 /* XXX: exception ? */
  2290 + val = 0;
1905 2291 break;
1906 2292 }
  2293 + EAX = (uint32_t)(val);
  2294 + EDX = (uint32_t)(val >> 32);
1907 2295 }
  2296 +#endif
1908 2297  
1909 2298 void helper_lsl(void)
1910 2299 {
... ... @@ -2055,14 +2444,14 @@ void helper_fldt_ST0_A0(void)
2055 2444 {
2056 2445 int new_fpstt;
2057 2446 new_fpstt = (env->fpstt - 1) & 7;
2058   - env->fpregs[new_fpstt] = helper_fldt((uint8_t *)A0);
  2447 + env->fpregs[new_fpstt] = helper_fldt(A0);
2059 2448 env->fpstt = new_fpstt;
2060 2449 env->fptags[new_fpstt] = 0; /* validate stack entry */
2061 2450 }
2062 2451  
2063 2452 void helper_fstt_ST0_A0(void)
2064 2453 {
2065   - helper_fstt(ST0, (uint8_t *)A0);
  2454 + helper_fstt(ST0, A0);
2066 2455 }
2067 2456  
2068 2457 void fpu_set_exception(int mask)
... ... @@ -2102,11 +2491,11 @@ void helper_fbld_ST0_A0(void)
2102 2491  
2103 2492 val = 0;
2104 2493 for(i = 8; i >= 0; i--) {
2105   - v = ldub((uint8_t *)A0 + i);
  2494 + v = ldub(A0 + i);
2106 2495 val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
2107 2496 }
2108 2497 tmp = val;
2109   - if (ldub((uint8_t *)A0 + 9) & 0x80)
  2498 + if (ldub(A0 + 9) & 0x80)
2110 2499 tmp = -tmp;
2111 2500 fpush();
2112 2501 ST0 = tmp;
... ... @@ -2116,12 +2505,12 @@ void helper_fbst_ST0_A0(void)
2116 2505 {
2117 2506 CPU86_LDouble tmp;
2118 2507 int v;
2119   - uint8_t *mem_ref, *mem_end;
  2508 + target_ulong mem_ref, mem_end;
2120 2509 int64_t val;
2121 2510  
2122 2511 tmp = rint(ST0);
2123 2512 val = (int64_t)tmp;
2124   - mem_ref = (uint8_t *)A0;
  2513 + mem_ref = A0;
2125 2514 mem_end = mem_ref + 9;
2126 2515 if (val < 0) {
2127 2516 stb(mem_end, 0x80);
... ... @@ -2402,7 +2791,7 @@ void helper_fxam_ST0(void)
2402 2791 }
2403 2792 }
2404 2793  
2405   -void helper_fstenv(uint8_t *ptr, int data32)
  2794 +void helper_fstenv(target_ulong ptr, int data32)
2406 2795 {
2407 2796 int fpus, fptag, exp, i;
2408 2797 uint64_t mant;
... ... @@ -2452,7 +2841,7 @@ void helper_fstenv(uint8_t *ptr, int data32)
2452 2841 }
2453 2842 }
2454 2843  
2455   -void helper_fldenv(uint8_t *ptr, int data32)
  2844 +void helper_fldenv(target_ulong ptr, int data32)
2456 2845 {
2457 2846 int i, fpus, fptag;
2458 2847  
... ... @@ -2474,7 +2863,7 @@ void helper_fldenv(uint8_t *ptr, int data32)
2474 2863 }
2475 2864 }
2476 2865  
2477   -void helper_fsave(uint8_t *ptr, int data32)
  2866 +void helper_fsave(target_ulong ptr, int data32)
2478 2867 {
2479 2868 CPU86_LDouble tmp;
2480 2869 int i;
... ... @@ -2502,7 +2891,7 @@ void helper_fsave(uint8_t *ptr, int data32)
2502 2891 env->fptags[7] = 1;
2503 2892 }
2504 2893  
2505   -void helper_frstor(uint8_t *ptr, int data32)
  2894 +void helper_frstor(target_ulong ptr, int data32)
2506 2895 {
2507 2896 CPU86_LDouble tmp;
2508 2897 int i;
... ... @@ -2517,7 +2906,78 @@ void helper_frstor(uint8_t *ptr, int data32)
2517 2906 }
2518 2907 }
2519 2908  
2520   -/* XXX: merge with helper_fstt ? */
  2909 +void helper_fxsave(target_ulong ptr, int data64)
  2910 +{
  2911 + int fpus, fptag, i, nb_xmm_regs;
  2912 + CPU86_LDouble tmp;
  2913 + target_ulong addr;
  2914 +
  2915 + fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
  2916 + fptag = 0;
  2917 + for(i = 0; i < 8; i++) {
  2918 + fptag |= ((!env->fptags[(env->fpstt + i) & 7]) << i);
  2919 + }
  2920 + stw(ptr, env->fpuc);
  2921 + stw(ptr + 2, fpus);
  2922 + stw(ptr + 4, fptag);
  2923 +
  2924 + addr = ptr + 0x20;
  2925 + for(i = 0;i < 8; i++) {
  2926 + tmp = ST(i);
  2927 + helper_fstt(tmp, addr);
  2928 + addr += 16;
  2929 + }
  2930 +
  2931 + if (env->cr[4] & CR4_OSFXSR_MASK) {
  2932 + /* XXX: finish it, endianness */
  2933 + stl(ptr + 0x18, 0); /* mxcsr */
  2934 + stl(ptr + 0x1c, 0); /* mxcsr_mask */
  2935 + nb_xmm_regs = 8 << data64;
  2936 + addr = ptr + 0xa0;
  2937 + for(i = 0; i < nb_xmm_regs; i++) {
  2938 + stq(addr, env->xmm_regs[i].u.q[0]);
  2939 + stq(addr, env->xmm_regs[i].u.q[1]);
  2940 + addr += 16;
  2941 + }
  2942 + }
  2943 +}
  2944 +
  2945 +void helper_fxrstor(target_ulong ptr, int data64)
  2946 +{
  2947 + int i, fpus, fptag, nb_xmm_regs;
  2948 + CPU86_LDouble tmp;
  2949 + target_ulong addr;
  2950 +
  2951 + env->fpuc = lduw(ptr);
  2952 + fpus = lduw(ptr + 2);
  2953 + fptag = ldub(ptr + 4);
  2954 + env->fpstt = (fpus >> 11) & 7;
  2955 + env->fpus = fpus & ~0x3800;
  2956 + fptag ^= 0xff;
  2957 + for(i = 0;i < 8; i++) {
  2958 + env->fptags[(env->fpstt + i) & 7] = ((fptag >> i) & 1);
  2959 + }
  2960 +
  2961 + addr = ptr + 0x20;
  2962 + for(i = 0;i < 8; i++) {
  2963 + tmp = helper_fldt(addr);
  2964 + ST(i) = tmp;
  2965 + addr += 16;
  2966 + }
  2967 +
  2968 + if (env->cr[4] & CR4_OSFXSR_MASK) {
  2969 + /* XXX: finish it, endianness */
  2970 + //ldl(ptr + 0x18);
  2971 + //ldl(ptr + 0x1c);
  2972 + nb_xmm_regs = 8 << data64;
  2973 + addr = ptr + 0xa0;
  2974 + for(i = 0; i < nb_xmm_regs; i++) {
  2975 + env->xmm_regs[i].u.q[0] = ldq(addr);
  2976 + env->xmm_regs[i].u.q[1] = ldq(addr);
  2977 + addr += 16;
  2978 + }
  2979 + }
  2980 +}
2521 2981  
2522 2982 #ifndef USE_X86LDOUBLE
2523 2983  
... ... @@ -2575,6 +3035,179 @@ CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
2575 3035 }
2576 3036 #endif
2577 3037  
  3038 +#ifdef TARGET_X86_64
  3039 +
  3040 +//#define DEBUG_MULDIV
  3041 +
  3042 +static void add128(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
  3043 +{
  3044 + *plow += a;
  3045 + /* carry test */
  3046 + if (*plow < a)
  3047 + (*phigh)++;
  3048 + *phigh += b;
  3049 +}
  3050 +
  3051 +static void neg128(uint64_t *plow, uint64_t *phigh)
  3052 +{
  3053 + *plow = ~ *plow;
  3054 + *phigh = ~ *phigh;
  3055 + add128(plow, phigh, 1, 0);
  3056 +}
  3057 +
  3058 +static void mul64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
  3059 +{
  3060 + uint32_t a0, a1, b0, b1;
  3061 + uint64_t v;
  3062 +
  3063 + a0 = a;
  3064 + a1 = a >> 32;
  3065 +
  3066 + b0 = b;
  3067 + b1 = b >> 32;
  3068 +
  3069 + v = (uint64_t)a0 * (uint64_t)b0;
  3070 + *plow = v;
  3071 + *phigh = 0;
  3072 +
  3073 + v = (uint64_t)a0 * (uint64_t)b1;
  3074 + add128(plow, phigh, v << 32, v >> 32);
  3075 +
  3076 + v = (uint64_t)a1 * (uint64_t)b0;
  3077 + add128(plow, phigh, v << 32, v >> 32);
  3078 +
  3079 + v = (uint64_t)a1 * (uint64_t)b1;
  3080 + *phigh += v;
  3081 +#ifdef DEBUG_MULDIV
  3082 + printf("mul: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
  3083 + a, b, *phigh, *plow);
  3084 +#endif
  3085 +}
  3086 +
  3087 +static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
  3088 +{
  3089 + int sa, sb;
  3090 + sa = (a < 0);
  3091 + if (sa)
  3092 + a = -a;
  3093 + sb = (b < 0);
  3094 + if (sb)
  3095 + b = -b;
  3096 + mul64(plow, phigh, a, b);
  3097 + if (sa ^ sb) {
  3098 + neg128(plow, phigh);
  3099 + }
  3100 +}
  3101 +
  3102 +static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
  3103 +{
  3104 + uint64_t q, r, a1, a0;
  3105 + int i, qb;
  3106 +
  3107 + a0 = *plow;
  3108 + a1 = *phigh;
  3109 + if (a1 == 0) {
  3110 + q = a0 / b;
  3111 + r = a0 % b;
  3112 + *plow = q;
  3113 + *phigh = r;
  3114 + } else {
  3115 + /* XXX: use a better algorithm */
  3116 + for(i = 0; i < 64; i++) {
  3117 + if (a1 >= b) {
  3118 + a1 -= b;
  3119 + qb = 1;
  3120 + } else {
  3121 + qb = 0;
  3122 + }
  3123 + a1 = (a1 << 1) | (a0 >> 63);
  3124 + a0 = (a0 << 1) | qb;
  3125 + }
  3126 +#if defined(DEBUG_MULDIV) || 1
  3127 + printf("div: 0x%016llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n",
  3128 + *phigh, *plow, b, a0, a1);
  3129 +#endif
  3130 + *plow = a0;
  3131 + *phigh = a1;
  3132 + }
  3133 +}
  3134 +
  3135 +static void idiv64(uint64_t *plow, uint64_t *phigh, uint64_t b)
  3136 +{
  3137 + int sa, sb;
  3138 + sa = ((int64_t)*phigh < 0);
  3139 + if (sa)
  3140 + neg128(plow, phigh);
  3141 + sb = (b < 0);
  3142 + if (sb)
  3143 + b = -b;
  3144 + div64(plow, phigh, b);
  3145 + if (sa ^ sb)
  3146 + *plow = - *plow;
  3147 + if (sb)
  3148 + *phigh = - *phigh;
  3149 +}
  3150 +
  3151 +void helper_mulq_EAX_T0(void)
  3152 +{
  3153 + uint64_t r0, r1;
  3154 +
  3155 + mul64(&r0, &r1, EAX, T0);
  3156 + EAX = r0;
  3157 + EDX = r1;
  3158 + CC_DST = r0;
  3159 + CC_SRC = r1;
  3160 +}
  3161 +
  3162 +void helper_imulq_EAX_T0(void)
  3163 +{
  3164 + uint64_t r0, r1;
  3165 +
  3166 + imul64(&r0, &r1, EAX, T0);
  3167 + EAX = r0;
  3168 + EDX = r1;
  3169 + CC_DST = r0;
  3170 + CC_SRC = (r1 != (r0 >> 63));
  3171 +}
  3172 +
  3173 +void helper_imulq_T0_T1(void)
  3174 +{
  3175 + uint64_t r0, r1;
  3176 +
  3177 + imul64(&r0, &r1, T0, T1);
  3178 + T0 = r0;
  3179 + CC_DST = r0;
  3180 + CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
  3181 +}
  3182 +
  3183 +void helper_divq_EAX_T0(void)
  3184 +{
  3185 + uint64_t r0, r1;
  3186 + if (T0 == 0) {
  3187 + raise_exception(EXCP00_DIVZ);
  3188 + }
  3189 + r0 = EAX;
  3190 + r1 = EDX;
  3191 + div64(&r0, &r1, T0);
  3192 + EAX = r0;
  3193 + EDX = r1;
  3194 +}
  3195 +
  3196 +void helper_idivq_EAX_T0(void)
  3197 +{
  3198 + uint64_t r0, r1;
  3199 + if (T0 == 0) {
  3200 + raise_exception(EXCP00_DIVZ);
  3201 + }
  3202 + r0 = EAX;
  3203 + r1 = EDX;
  3204 + idiv64(&r0, &r1, T0);
  3205 + EAX = r0;
  3206 + EDX = r1;
  3207 +}
  3208 +
  3209 +#endif
  3210 +
2578 3211 #if !defined(CONFIG_USER_ONLY)
2579 3212  
2580 3213 #define MMUSUFFIX _mmu
... ... @@ -2598,7 +3231,7 @@ CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
2598 3231 NULL, it means that the function was called in C code (i.e. not
2599 3232 from generated code or from helper.c) */
2600 3233 /* XXX: fix it to restore all registers */
2601   -void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
  3234 +void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
2602 3235 {
2603 3236 TranslationBlock *tb;
2604 3237 int ret;
... ...
target-i386/helper2.c
... ... @@ -77,6 +77,41 @@ CPUX86State *cpu_x86_init(void)
77 77 asm volatile ("movl %0, %%fs" : : "r" ((1 << 3) | 7));
78 78 }
79 79 #endif
  80 + {
  81 + int family, model, stepping;
  82 +#ifdef TARGET_X86_64
  83 + env->cpuid_vendor1 = 0x68747541; /* "Auth" */
  84 + env->cpuid_vendor2 = 0x69746e65; /* "enti" */
  85 + env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
  86 + family = 6;
  87 + model = 2;
  88 + stepping = 3;
  89 +#else
  90 + env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
  91 + env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
  92 + env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
  93 +#if 0
  94 + /* pentium 75-200 */
  95 + family = 5;
  96 + model = 2;
  97 + stepping = 11;
  98 +#else
  99 + /* pentium pro */
  100 + family = 6;
  101 + model = 1;
  102 + stepping = 3;
  103 +#endif
  104 +#endif
  105 + env->cpuid_version = (family << 8) | (model << 4) | stepping;
  106 + env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
  107 + CPUID_TSC | CPUID_MSR | CPUID_MCE |
  108 + CPUID_CX8 | CPUID_PGE | CPUID_CMOV);
  109 +#ifdef TARGET_X86_64
  110 + /* currently not enabled for std i386 because not fully tested */
  111 + env->cpuid_features |= CPUID_APIC | CPUID_FXSR | CPUID_PAE |
  112 + CPUID_SSE | CPUID_SSE2;
  113 +#endif
  114 + }
80 115 cpu_single_env = env;
81 116 cpu_reset(env);
82 117 return env;
... ... @@ -107,12 +142,12 @@ void cpu_reset(CPUX86State *env)
107 142 env->tr.limit = 0xffff;
108 143 env->tr.flags = DESC_P_MASK;
109 144  
110   - cpu_x86_load_seg_cache(env, R_CS, 0xf000, (uint8_t *)0xffff0000, 0xffff, 0);
111   - cpu_x86_load_seg_cache(env, R_DS, 0, NULL, 0xffff, 0);
112   - cpu_x86_load_seg_cache(env, R_ES, 0, NULL, 0xffff, 0);
113   - cpu_x86_load_seg_cache(env, R_SS, 0, NULL, 0xffff, 0);
114   - cpu_x86_load_seg_cache(env, R_FS, 0, NULL, 0xffff, 0);
115   - cpu_x86_load_seg_cache(env, R_GS, 0, NULL, 0xffff, 0);
  145 + cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0);
  146 + cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0);
  147 + cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0);
  148 + cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0);
  149 + cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0);
  150 + cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0);
116 151  
117 152 env->eip = 0xfff0;
118 153 env->regs[R_EDX] = 0x600; /* indicate P6 processor */
... ... @@ -136,36 +171,56 @@ void cpu_x86_close(CPUX86State *env)
136 171 static const char *cc_op_str[] = {
137 172 "DYNAMIC",
138 173 "EFLAGS",
  174 +
139 175 "MULB",
140 176 "MULW",
141 177 "MULL",
  178 + "MULQ",
  179 +
142 180 "ADDB",
143 181 "ADDW",
144 182 "ADDL",
  183 + "ADDQ",
  184 +
145 185 "ADCB",
146 186 "ADCW",
147 187 "ADCL",
  188 + "ADCQ",
  189 +
148 190 "SUBB",
149 191 "SUBW",
150 192 "SUBL",
  193 + "SUBQ",
  194 +
151 195 "SBBB",
152 196 "SBBW",
153 197 "SBBL",
  198 + "SBBQ",
  199 +
154 200 "LOGICB",
155 201 "LOGICW",
156 202 "LOGICL",
  203 + "LOGICQ",
  204 +
157 205 "INCB",
158 206 "INCW",
159 207 "INCL",
  208 + "INCQ",
  209 +
160 210 "DECB",
161 211 "DECW",
162 212 "DECL",
  213 + "DECQ",
  214 +
163 215 "SHLB",
164 216 "SHLW",
165 217 "SHLL",
  218 + "SHLQ",
  219 +
166 220 "SARB",
167 221 "SARW",
168 222 "SARL",
  223 + "SARQ",
169 224 };
170 225  
171 226 void cpu_dump_state(CPUState *env, FILE *f,
... ... @@ -177,55 +232,147 @@ void cpu_dump_state(CPUState *env, FILE *f,
177 232 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
178 233  
179 234 eflags = env->eflags;
180   - cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
181   - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
182   - "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d\n",
183   - env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX],
184   - env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP],
185   - env->eip, eflags,
186   - eflags & DF_MASK ? 'D' : '-',
187   - eflags & CC_O ? 'O' : '-',
188   - eflags & CC_S ? 'S' : '-',
189   - eflags & CC_Z ? 'Z' : '-',
190   - eflags & CC_A ? 'A' : '-',
191   - eflags & CC_P ? 'P' : '-',
192   - eflags & CC_C ? 'C' : '-',
193   - env->hflags & HF_CPL_MASK,
194   - (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
195   - (env->a20_mask >> 20) & 1);
196   - for(i = 0; i < 6; i++) {
197   - SegmentCache *sc = &env->segs[i];
198   - cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
199   - seg_name[i],
200   - sc->selector,
201   - (int)sc->base,
202   - sc->limit,
203   - sc->flags);
  235 +#ifdef TARGET_X86_64
  236 + if (env->hflags & HF_CS64_MASK) {
  237 + cpu_fprintf(f,
  238 + "RAX=%016llx RBX=%016llx RCX=%016llx RDX=%016llx\n"
  239 + "RSI=%016llx RDI=%016llx RBP=%016llx RSP=%016llx\n"
  240 + "R8 =%016llx R9 =%016llx R10=%016llx R11=%016llx\n"
  241 + "R12=%016llx R13=%016llx R14=%016llx R15=%016llx\n"
  242 + "RIP=%016llx RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d\n",
  243 + env->regs[R_EAX],
  244 + env->regs[R_EBX],
  245 + env->regs[R_ECX],
  246 + env->regs[R_EDX],
  247 + env->regs[R_ESI],
  248 + env->regs[R_EDI],
  249 + env->regs[R_EBP],
  250 + env->regs[R_ESP],
  251 + env->regs[8],
  252 + env->regs[9],
  253 + env->regs[10],
  254 + env->regs[11],
  255 + env->regs[12],
  256 + env->regs[13],
  257 + env->regs[14],
  258 + env->regs[15],
  259 + env->eip, eflags,
  260 + eflags & DF_MASK ? 'D' : '-',
  261 + eflags & CC_O ? 'O' : '-',
  262 + eflags & CC_S ? 'S' : '-',
  263 + eflags & CC_Z ? 'Z' : '-',
  264 + eflags & CC_A ? 'A' : '-',
  265 + eflags & CC_P ? 'P' : '-',
  266 + eflags & CC_C ? 'C' : '-',
  267 + env->hflags & HF_CPL_MASK,
  268 + (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
  269 + (env->a20_mask >> 20) & 1);
  270 + } else
  271 +#endif
  272 + {
  273 + cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
  274 + "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
  275 + "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d\n",
  276 + (uint32_t)env->regs[R_EAX],
  277 + (uint32_t)env->regs[R_EBX],
  278 + (uint32_t)env->regs[R_ECX],
  279 + (uint32_t)env->regs[R_EDX],
  280 + (uint32_t)env->regs[R_ESI],
  281 + (uint32_t)env->regs[R_EDI],
  282 + (uint32_t)env->regs[R_EBP],
  283 + (uint32_t)env->regs[R_ESP],
  284 + (uint32_t)env->eip, eflags,
  285 + eflags & DF_MASK ? 'D' : '-',
  286 + eflags & CC_O ? 'O' : '-',
  287 + eflags & CC_S ? 'S' : '-',
  288 + eflags & CC_Z ? 'Z' : '-',
  289 + eflags & CC_A ? 'A' : '-',
  290 + eflags & CC_P ? 'P' : '-',
  291 + eflags & CC_C ? 'C' : '-',
  292 + env->hflags & HF_CPL_MASK,
  293 + (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
  294 + (env->a20_mask >> 20) & 1);
  295 + }
  296 +
  297 +#ifdef TARGET_X86_64
  298 + if (env->hflags & HF_LMA_MASK) {
  299 + for(i = 0; i < 6; i++) {
  300 + SegmentCache *sc = &env->segs[i];
  301 + cpu_fprintf(f, "%s =%04x %016llx %08x %08x\n",
  302 + seg_name[i],
  303 + sc->selector,
  304 + sc->base,
  305 + sc->limit,
  306 + sc->flags);
  307 + }
  308 + cpu_fprintf(f, "LDT=%04x %016llx %08x %08x\n",
  309 + env->ldt.selector,
  310 + env->ldt.base,
  311 + env->ldt.limit,
  312 + env->ldt.flags);
  313 + cpu_fprintf(f, "TR =%04x %016llx %08x %08x\n",
  314 + env->tr.selector,
  315 + env->tr.base,
  316 + env->tr.limit,
  317 + env->tr.flags);
  318 + cpu_fprintf(f, "GDT= %016llx %08x\n",
  319 + env->gdt.base, env->gdt.limit);
  320 + cpu_fprintf(f, "IDT= %016llx %08x\n",
  321 + env->idt.base, env->idt.limit);
  322 + cpu_fprintf(f, "CR0=%08x CR2=%016llx CR3=%016llx CR4=%08x\n",
  323 + (uint32_t)env->cr[0],
  324 + env->cr[2],
  325 + env->cr[3],
  326 + (uint32_t)env->cr[4]);
  327 + } else
  328 +#endif
  329 + {
  330 + for(i = 0; i < 6; i++) {
  331 + SegmentCache *sc = &env->segs[i];
  332 + cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
  333 + seg_name[i],
  334 + sc->selector,
  335 + (uint32_t)sc->base,
  336 + sc->limit,
  337 + sc->flags);
  338 + }
  339 + cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
  340 + env->ldt.selector,
  341 + (uint32_t)env->ldt.base,
  342 + env->ldt.limit,
  343 + env->ldt.flags);
  344 + cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
  345 + env->tr.selector,
  346 + (uint32_t)env->tr.base,
  347 + env->tr.limit,
  348 + env->tr.flags);
  349 + cpu_fprintf(f, "GDT= %08x %08x\n",
  350 + (uint32_t)env->gdt.base, env->gdt.limit);
  351 + cpu_fprintf(f, "IDT= %08x %08x\n",
  352 + (uint32_t)env->idt.base, env->idt.limit);
  353 + cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
  354 + (uint32_t)env->cr[0],
  355 + (uint32_t)env->cr[2],
  356 + (uint32_t)env->cr[3],
  357 + (uint32_t)env->cr[4]);
204 358 }
205   - cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
206   - env->ldt.selector,
207   - (int)env->ldt.base,
208   - env->ldt.limit,
209   - env->ldt.flags);
210   - cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
211   - env->tr.selector,
212   - (int)env->tr.base,
213   - env->tr.limit,
214   - env->tr.flags);
215   - cpu_fprintf(f, "GDT= %08x %08x\n",
216   - (int)env->gdt.base, env->gdt.limit);
217   - cpu_fprintf(f, "IDT= %08x %08x\n",
218   - (int)env->idt.base, env->idt.limit);
219   - cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
220   - env->cr[0], env->cr[2], env->cr[3], env->cr[4]);
221   -
222 359 if (flags & X86_DUMP_CCOP) {
223 360 if ((unsigned)env->cc_op < CC_OP_NB)
224 361 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
225 362 else
226 363 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
227   - cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
228   - env->cc_src, env->cc_dst, cc_op_name);
  364 +#ifdef TARGET_X86_64
  365 + if (env->hflags & HF_CS64_MASK) {
  366 + cpu_fprintf(f, "CCS=%016llx CCD=%016llx CCO=%-8s\n",
  367 + env->cc_src, env->cc_dst,
  368 + cc_op_name);
  369 + } else
  370 +#endif
  371 + {
  372 + cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
  373 + (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
  374 + cc_op_name);
  375 + }
229 376 }
230 377 if (flags & X86_DUMP_FPU) {
231 378 cpu_fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
... ... @@ -274,6 +421,24 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
274 421 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
275 422 tlb_flush(env, 1);
276 423 }
  424 +
  425 +#ifdef TARGET_X86_64
  426 + if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
  427 + (env->efer & MSR_EFER_LME)) {
  428 + /* enter in long mode */
  429 + /* XXX: generate an exception */
  430 + if (!(env->cr[4] & CR4_PAE_MASK))
  431 + return;
  432 + env->efer |= MSR_EFER_LMA;
  433 + env->hflags |= HF_LMA_MASK;
  434 + } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
  435 + (env->efer & MSR_EFER_LMA)) {
  436 + /* exit long mode */
  437 + env->efer &= ~MSR_EFER_LMA;
  438 + env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
  439 + env->eip &= 0xffffffff;
  440 + }
  441 +#endif
277 442 env->cr[0] = new_cr0 | CR0_ET_MASK;
278 443  
279 444 /* update PE flag in hidden flags */
... ... @@ -286,12 +451,12 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
286 451 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
287 452 }
288 453  
289   -void cpu_x86_update_cr3(CPUX86State *env, uint32_t new_cr3)
  454 +void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
290 455 {
291 456 env->cr[3] = new_cr3;
292 457 if (env->cr[0] & CR0_PG_MASK) {
293 458 #if defined(DEBUG_MMU)
294   - printf("CR3 update: CR3=%08x\n", new_cr3);
  459 + printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
295 460 #endif
296 461 tlb_flush(env, 0);
297 462 }
... ... @@ -300,7 +465,7 @@ void cpu_x86_update_cr3(CPUX86State *env, uint32_t new_cr3)
300 465 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
301 466 {
302 467 #if defined(DEBUG_MMU)
303   - printf("CR4 update: CR4=%08x\n", env->cr[4]);
  468 + printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
304 469 #endif
305 470 if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
306 471 (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
... ... @@ -315,22 +480,51 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
315 480 tlb_flush_page(env, addr);
316 481 }
317 482  
  483 +static inline uint8_t *get_phys_mem_ptr(target_phys_addr_t addr)
  484 +{
  485 + /* XXX: incorrect */
  486 + return phys_ram_base + addr;
  487 +}
  488 +
  489 +/* WARNING: addr must be aligned */
  490 +uint32_t ldl_phys_aligned(target_phys_addr_t addr)
  491 +{
  492 + uint8_t *ptr;
  493 + uint32_t val;
  494 + ptr = get_phys_mem_ptr(addr);
  495 + if (!ptr)
  496 + val = 0;
  497 + else
  498 + val = ldl_raw(ptr);
  499 + return val;
  500 +}
  501 +
  502 +void stl_phys_aligned(target_phys_addr_t addr, uint32_t val)
  503 +{
  504 + uint8_t *ptr;
  505 + ptr = get_phys_mem_ptr(addr);
  506 + if (!ptr)
  507 + return;
  508 + stl_raw(ptr, val);
  509 +}
  510 +
318 511 /* return value:
319 512 -1 = cannot handle fault
320 513 0 = nothing more to do
321 514 1 = generate PF fault
322 515 2 = soft MMU activation required for this block
323 516 */
324   -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
  517 +int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
325 518 int is_write, int is_user, int is_softmmu)
326 519 {
327   - uint8_t *pde_ptr, *pte_ptr;
328   - uint32_t pde, pte, virt_addr, ptep;
  520 + uint32_t pdpe_addr, pde_addr, pte_addr;
  521 + uint32_t pde, pte, ptep, pdpe;
329 522 int error_code, is_dirty, prot, page_size, ret;
330   - unsigned long paddr, vaddr, page_offset;
  523 + unsigned long paddr, page_offset;
  524 + target_ulong vaddr, virt_addr;
331 525  
332 526 #if defined(DEBUG_MMU)
333   - printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n",
  527 + printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
334 528 addr, is_write, is_user, env->eip);
335 529 #endif
336 530 is_write &= 1;
... ... @@ -349,90 +543,166 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
349 543 goto do_mapping;
350 544 }
351 545  
352   - /* page directory entry */
353   - pde_ptr = phys_ram_base +
354   - (((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask);
355   - pde = ldl_raw(pde_ptr);
356   - if (!(pde & PG_PRESENT_MASK)) {
357   - error_code = 0;
358   - goto do_fault;
359   - }
360   - /* if PSE bit is set, then we use a 4MB page */
361   - if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
362   - if (is_user) {
363   - if (!(pde & PG_USER_MASK))
364   - goto do_fault_protect;
365   - if (is_write && !(pde & PG_RW_MASK))
366   - goto do_fault_protect;
367   - } else {
368   - if ((env->cr[0] & CR0_WP_MASK) &&
369   - is_write && !(pde & PG_RW_MASK))
370   - goto do_fault_protect;
  546 +
  547 + if (env->cr[4] & CR4_PAE_MASK) {
  548 + /* XXX: we only use 32 bit physical addresses */
  549 +#ifdef TARGET_X86_64
  550 + if (env->hflags & HF_LMA_MASK) {
  551 + uint32_t pml4e_addr, pml4e;
  552 + int32_t sext;
  553 +
  554 + /* XXX: handle user + rw rights */
  555 + /* XXX: handle NX flag */
  556 + /* test virtual address sign extension */
  557 + sext = (int64_t)addr >> 47;
  558 + if (sext != 0 && sext != -1) {
  559 + error_code = 0;
  560 + goto do_fault;
  561 + }
  562 +
  563 + pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
  564 + env->a20_mask;
  565 + pml4e = ldl_phys_aligned(pml4e_addr);
  566 + if (!(pml4e & PG_PRESENT_MASK)) {
  567 + error_code = 0;
  568 + goto do_fault;
  569 + }
  570 + if (!(pml4e & PG_ACCESSED_MASK)) {
  571 + pml4e |= PG_ACCESSED_MASK;
  572 + stl_phys_aligned(pml4e_addr, pml4e);
  573 + }
  574 +
  575 + pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
  576 + env->a20_mask;
  577 + pdpe = ldl_phys_aligned(pdpe_addr);
  578 + if (!(pdpe & PG_PRESENT_MASK)) {
  579 + error_code = 0;
  580 + goto do_fault;
  581 + }
  582 + if (!(pdpe & PG_ACCESSED_MASK)) {
  583 + pdpe |= PG_ACCESSED_MASK;
  584 + stl_phys_aligned(pdpe_addr, pdpe);
  585 + }
  586 + } else
  587 +#endif
  588 + {
  589 + pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
  590 + env->a20_mask;
  591 + pdpe = ldl_phys_aligned(pdpe_addr);
  592 + if (!(pdpe & PG_PRESENT_MASK)) {
  593 + error_code = 0;
  594 + goto do_fault;
  595 + }
371 596 }
372   - is_dirty = is_write && !(pde & PG_DIRTY_MASK);
373   - if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
374   - pde |= PG_ACCESSED_MASK;
375   - if (is_dirty)
376   - pde |= PG_DIRTY_MASK;
377   - stl_raw(pde_ptr, pde);
  597 +
  598 + pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
  599 + env->a20_mask;
  600 + pde = ldl_phys_aligned(pde_addr);
  601 + if (!(pde & PG_PRESENT_MASK)) {
  602 + error_code = 0;
  603 + goto do_fault;
378 604 }
379   -
380   - pte = pde & ~0x003ff000; /* align to 4MB */
381   - ptep = pte;
382   - page_size = 4096 * 1024;
383   - virt_addr = addr & ~0x003fffff;
384   - } else {
385   - if (!(pde & PG_ACCESSED_MASK)) {
386   - pde |= PG_ACCESSED_MASK;
387   - stl_raw(pde_ptr, pde);
  605 + if (pde & PG_PSE_MASK) {
  606 + /* 2 MB page */
  607 + page_size = 2048 * 1024;
  608 + goto handle_big_page;
  609 + } else {
  610 + /* 4 KB page */
  611 + if (!(pde & PG_ACCESSED_MASK)) {
  612 + pde |= PG_ACCESSED_MASK;
  613 + stl_phys_aligned(pde_addr, pde);
  614 + }
  615 + pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
  616 + env->a20_mask;
  617 + goto handle_4k_page;
388 618 }
389   -
  619 + } else {
390 620 /* page directory entry */
391   - pte_ptr = phys_ram_base +
392   - (((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask);
393   - pte = ldl_raw(pte_ptr);
394   - if (!(pte & PG_PRESENT_MASK)) {
  621 + pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) &
  622 + env->a20_mask;
  623 + pde = ldl_phys_aligned(pde_addr);
  624 + if (!(pde & PG_PRESENT_MASK)) {
395 625 error_code = 0;
396 626 goto do_fault;
397 627 }
398   - /* combine pde and pte user and rw protections */
399   - ptep = pte & pde;
400   - if (is_user) {
401   - if (!(ptep & PG_USER_MASK))
402   - goto do_fault_protect;
403   - if (is_write && !(ptep & PG_RW_MASK))
404   - goto do_fault_protect;
  628 + /* if PSE bit is set, then we use a 4MB page */
  629 + if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
  630 + page_size = 4096 * 1024;
  631 + handle_big_page:
  632 + if (is_user) {
  633 + if (!(pde & PG_USER_MASK))
  634 + goto do_fault_protect;
  635 + if (is_write && !(pde & PG_RW_MASK))
  636 + goto do_fault_protect;
  637 + } else {
  638 + if ((env->cr[0] & CR0_WP_MASK) &&
  639 + is_write && !(pde & PG_RW_MASK))
  640 + goto do_fault_protect;
  641 + }
  642 + is_dirty = is_write && !(pde & PG_DIRTY_MASK);
  643 + if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
  644 + pde |= PG_ACCESSED_MASK;
  645 + if (is_dirty)
  646 + pde |= PG_DIRTY_MASK;
  647 + stl_phys_aligned(pde_addr, pde);
  648 + }
  649 +
  650 + pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
  651 + ptep = pte;
  652 + virt_addr = addr & ~(page_size - 1);
405 653 } else {
406   - if ((env->cr[0] & CR0_WP_MASK) &&
407   - is_write && !(ptep & PG_RW_MASK))
408   - goto do_fault_protect;
409   - }
410   - is_dirty = is_write && !(pte & PG_DIRTY_MASK);
411   - if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
412   - pte |= PG_ACCESSED_MASK;
413   - if (is_dirty)
414   - pte |= PG_DIRTY_MASK;
415   - stl_raw(pte_ptr, pte);
  654 + if (!(pde & PG_ACCESSED_MASK)) {
  655 + pde |= PG_ACCESSED_MASK;
  656 + stl_phys_aligned(pde_addr, pde);
  657 + }
  658 +
  659 + /* page directory entry */
  660 + pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
  661 + env->a20_mask;
  662 + handle_4k_page:
  663 + pte = ldl_phys_aligned(pte_addr);
  664 + if (!(pte & PG_PRESENT_MASK)) {
  665 + error_code = 0;
  666 + goto do_fault;
  667 + }
  668 + /* combine pde and pte user and rw protections */
  669 + ptep = pte & pde;
  670 + if (is_user) {
  671 + if (!(ptep & PG_USER_MASK))
  672 + goto do_fault_protect;
  673 + if (is_write && !(ptep & PG_RW_MASK))
  674 + goto do_fault_protect;
  675 + } else {
  676 + if ((env->cr[0] & CR0_WP_MASK) &&
  677 + is_write && !(ptep & PG_RW_MASK))
  678 + goto do_fault_protect;
  679 + }
  680 + is_dirty = is_write && !(pte & PG_DIRTY_MASK);
  681 + if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
  682 + pte |= PG_ACCESSED_MASK;
  683 + if (is_dirty)
  684 + pte |= PG_DIRTY_MASK;
  685 + stl_phys_aligned(pte_addr, pte);
  686 + }
  687 + page_size = 4096;
  688 + virt_addr = addr & ~0xfff;
416 689 }
417   - page_size = 4096;
418   - virt_addr = addr & ~0xfff;
419   - }
420 690  
421   - /* the page can be put in the TLB */
422   - prot = PAGE_READ;
423   - if (pte & PG_DIRTY_MASK) {
424   - /* only set write access if already dirty... otherwise wait
425   - for dirty access */
426   - if (is_user) {
427   - if (ptep & PG_RW_MASK)
428   - prot |= PAGE_WRITE;
429   - } else {
430   - if (!(env->cr[0] & CR0_WP_MASK) ||
431   - (ptep & PG_RW_MASK))
432   - prot |= PAGE_WRITE;
  691 + /* the page can be put in the TLB */
  692 + prot = PAGE_READ;
  693 + if (pte & PG_DIRTY_MASK) {
  694 + /* only set write access if already dirty... otherwise wait
  695 + for dirty access */
  696 + if (is_user) {
  697 + if (ptep & PG_RW_MASK)
  698 + prot |= PAGE_WRITE;
  699 + } else {
  700 + if (!(env->cr[0] & CR0_WP_MASK) ||
  701 + (ptep & PG_RW_MASK))
  702 + prot |= PAGE_WRITE;
  703 + }
433 704 }
434 705 }
435   -
436 706 do_mapping:
437 707 pte = pte & env->a20_mask;
438 708  
... ...
target-i386/op.c
... ... @@ -22,7 +22,7 @@
22 22 #include "exec.h"
23 23  
24 24 /* n must be a constant to be efficient */
25   -static inline int lshift(int x, int n)
  25 +static inline target_long lshift(target_long x, int n)
26 26 {
27 27 if (n >= 0)
28 28 return x << n;
... ... @@ -80,6 +80,58 @@ static inline int lshift(int x, int n)
80 80 #undef REG
81 81 #undef REGNAME
82 82  
  83 +#ifdef TARGET_X86_64
  84 +
  85 +#define REG (env->regs[8])
  86 +#define REGNAME _R8
  87 +#include "opreg_template.h"
  88 +#undef REG
  89 +#undef REGNAME
  90 +
  91 +#define REG (env->regs[9])
  92 +#define REGNAME _R9
  93 +#include "opreg_template.h"
  94 +#undef REG
  95 +#undef REGNAME
  96 +
  97 +#define REG (env->regs[10])
  98 +#define REGNAME _R10
  99 +#include "opreg_template.h"
  100 +#undef REG
  101 +#undef REGNAME
  102 +
  103 +#define REG (env->regs[11])
  104 +#define REGNAME _R11
  105 +#include "opreg_template.h"
  106 +#undef REG
  107 +#undef REGNAME
  108 +
  109 +#define REG (env->regs[12])
  110 +#define REGNAME _R12
  111 +#include "opreg_template.h"
  112 +#undef REG
  113 +#undef REGNAME
  114 +
  115 +#define REG (env->regs[13])
  116 +#define REGNAME _R13
  117 +#include "opreg_template.h"
  118 +#undef REG
  119 +#undef REGNAME
  120 +
  121 +#define REG (env->regs[14])
  122 +#define REGNAME _R14
  123 +#include "opreg_template.h"
  124 +#undef REG
  125 +#undef REGNAME
  126 +
  127 +#define REG (env->regs[15])
  128 +#define REGNAME _R15
  129 +#include "opreg_template.h"
  130 +#undef REG
  131 +#undef REGNAME
  132 +
  133 +#endif
  134 +
83 135 /* operations with flags */
84 136  
85 137 /* update flags with T0 and T1 (add/sub case) */
... ... @@ -170,6 +222,13 @@ void OPPROTO op_bswapl_T0(void)
170 222 T0 = bswap32(T0);
171 223 }
172 224  
  225 +#ifdef TARGET_X86_64
  226 +void OPPROTO op_bswapq_T0(void)
  227 +{
  228 + T0 = bswap64(T0);
  229 +}
  230 +#endif
  231 +
173 232 /* multiply/divide */
174 233  
175 234 /* XXX: add eflags optimizations */
... ... @@ -179,7 +238,7 @@ void OPPROTO op_mulb_AL_T0(void)
179 238 {
180 239 unsigned int res;
181 240 res = (uint8_t)EAX * (uint8_t)T0;
182   - EAX = (EAX & 0xffff0000) | res;
  241 + EAX = (EAX & ~0xffff) | res;
183 242 CC_DST = res;
184 243 CC_SRC = (res & 0xff00);
185 244 }
... ... @@ -188,7 +247,7 @@ void OPPROTO op_imulb_AL_T0(void)
188 247 {
189 248 int res;
190 249 res = (int8_t)EAX * (int8_t)T0;
191   - EAX = (EAX & 0xffff0000) | (res & 0xffff);
  250 + EAX = (EAX & ~0xffff) | (res & 0xffff);
192 251 CC_DST = res;
193 252 CC_SRC = (res != (int8_t)res);
194 253 }
... ... @@ -197,8 +256,8 @@ void OPPROTO op_mulw_AX_T0(void)
197 256 {
198 257 unsigned int res;
199 258 res = (uint16_t)EAX * (uint16_t)T0;
200   - EAX = (EAX & 0xffff0000) | (res & 0xffff);
201   - EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
  259 + EAX = (EAX & ~0xffff) | (res & 0xffff);
  260 + EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
202 261 CC_DST = res;
203 262 CC_SRC = res >> 16;
204 263 }
... ... @@ -207,8 +266,8 @@ void OPPROTO op_imulw_AX_T0(void)
207 266 {
208 267 int res;
209 268 res = (int16_t)EAX * (int16_t)T0;
210   - EAX = (EAX & 0xffff0000) | (res & 0xffff);
211   - EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
  269 + EAX = (EAX & ~0xffff) | (res & 0xffff);
  270 + EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
212 271 CC_DST = res;
213 272 CC_SRC = (res != (int16_t)res);
214 273 }
... ... @@ -217,10 +276,10 @@ void OPPROTO op_mull_EAX_T0(void)
217 276 {
218 277 uint64_t res;
219 278 res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
220   - EAX = res;
221   - EDX = res >> 32;
222   - CC_DST = res;
223   - CC_SRC = res >> 32;
  279 + EAX = (uint32_t)res;
  280 + EDX = (uint32_t)(res >> 32);
  281 + CC_DST = (uint32_t)res;
  282 + CC_SRC = (uint32_t)(res >> 32);
224 283 }
225 284  
226 285 void OPPROTO op_imull_EAX_T0(void)
... ... @@ -251,6 +310,23 @@ void OPPROTO op_imull_T0_T1(void)
251 310 CC_SRC = (res != (int32_t)res);
252 311 }
253 312  
  313 +#ifdef TARGET_X86_64
  314 +void OPPROTO op_mulq_EAX_T0(void)
  315 +{
  316 + helper_mulq_EAX_T0();
  317 +}
  318 +
  319 +void OPPROTO op_imulq_EAX_T0(void)
  320 +{
  321 + helper_imulq_EAX_T0();
  322 +}
  323 +
  324 +void OPPROTO op_imulq_T0_T1(void)
  325 +{
  326 + helper_imulq_T0_T1();
  327 +}
  328 +#endif
  329 +
254 330 /* division, flags are undefined */
255 331 /* XXX: add exceptions for overflow */
256 332  
... ... @@ -261,12 +337,11 @@ void OPPROTO op_divb_AL_T0(void)
261 337 num = (EAX & 0xffff);
262 338 den = (T0 & 0xff);
263 339 if (den == 0) {
264   - EIP = PARAM1;
265 340 raise_exception(EXCP00_DIVZ);
266 341 }
267 342 q = (num / den) & 0xff;
268 343 r = (num % den) & 0xff;
269   - EAX = (EAX & 0xffff0000) | (r << 8) | q;
  344 + EAX = (EAX & ~0xffff) | (r << 8) | q;
270 345 }
271 346  
272 347 void OPPROTO op_idivb_AL_T0(void)
... ... @@ -276,12 +351,11 @@ void OPPROTO op_idivb_AL_T0(void)
276 351 num = (int16_t)EAX;
277 352 den = (int8_t)T0;
278 353 if (den == 0) {
279   - EIP = PARAM1;
280 354 raise_exception(EXCP00_DIVZ);
281 355 }
282 356 q = (num / den) & 0xff;
283 357 r = (num % den) & 0xff;
284   - EAX = (EAX & 0xffff0000) | (r << 8) | q;
  358 + EAX = (EAX & ~0xffff) | (r << 8) | q;
285 359 }
286 360  
287 361 void OPPROTO op_divw_AX_T0(void)
... ... @@ -291,13 +365,12 @@ void OPPROTO op_divw_AX_T0(void)
291 365 num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
292 366 den = (T0 & 0xffff);
293 367 if (den == 0) {
294   - EIP = PARAM1;
295 368 raise_exception(EXCP00_DIVZ);
296 369 }
297 370 q = (num / den) & 0xffff;
298 371 r = (num % den) & 0xffff;
299   - EAX = (EAX & 0xffff0000) | q;
300   - EDX = (EDX & 0xffff0000) | r;
  372 + EAX = (EAX & ~0xffff) | q;
  373 + EDX = (EDX & ~0xffff) | r;
301 374 }
302 375  
303 376 void OPPROTO op_idivw_AX_T0(void)
... ... @@ -307,30 +380,47 @@ void OPPROTO op_idivw_AX_T0(void)
307 380 num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
308 381 den = (int16_t)T0;
309 382 if (den == 0) {
310   - EIP = PARAM1;
311 383 raise_exception(EXCP00_DIVZ);
312 384 }
313 385 q = (num / den) & 0xffff;
314 386 r = (num % den) & 0xffff;
315   - EAX = (EAX & 0xffff0000) | q;
316   - EDX = (EDX & 0xffff0000) | r;
  387 + EAX = (EAX & ~0xffff) | q;
  388 + EDX = (EDX & ~0xffff) | r;
317 389 }
318 390  
319 391 void OPPROTO op_divl_EAX_T0(void)
320 392 {
321   - helper_divl_EAX_T0(PARAM1);
  393 + helper_divl_EAX_T0();
322 394 }
323 395  
324 396 void OPPROTO op_idivl_EAX_T0(void)
325 397 {
326   - helper_idivl_EAX_T0(PARAM1);
  398 + helper_idivl_EAX_T0();
327 399 }
328 400  
  401 +#ifdef TARGET_X86_64
  402 +void OPPROTO op_divq_EAX_T0(void)
  403 +{
  404 + helper_divq_EAX_T0();
  405 +}
  406 +
  407 +void OPPROTO op_idivq_EAX_T0(void)
  408 +{
  409 + helper_idivq_EAX_T0();
  410 +}
  411 +#endif
  412 +
329 413 /* constant load & misc op */
330 414  
  415 +/* XXX: consistent names */
  416 +void OPPROTO op_movl_T0_imu(void)
  417 +{
  418 + T0 = (uint32_t)PARAM1;
  419 +}
  420 +
331 421 void OPPROTO op_movl_T0_im(void)
332 422 {
333   - T0 = PARAM1;
  423 + T0 = (int32_t)PARAM1;
334 424 }
335 425  
336 426 void OPPROTO op_addl_T0_im(void)
... ... @@ -353,9 +443,14 @@ void OPPROTO op_movl_T0_T1(void)
353 443 T0 = T1;
354 444 }
355 445  
  446 +void OPPROTO op_movl_T1_imu(void)
  447 +{
  448 + T1 = (uint32_t)PARAM1;
  449 +}
  450 +
356 451 void OPPROTO op_movl_T1_im(void)
357 452 {
358   - T1 = PARAM1;
  453 + T1 = (int32_t)PARAM1;
359 454 }
360 455  
361 456 void OPPROTO op_addl_T1_im(void)
... ... @@ -370,19 +465,95 @@ void OPPROTO op_movl_T1_A0(void)
370 465  
371 466 void OPPROTO op_movl_A0_im(void)
372 467 {
373   - A0 = PARAM1;
  468 + A0 = (uint32_t)PARAM1;
374 469 }
375 470  
376 471 void OPPROTO op_addl_A0_im(void)
377 472 {
378   - A0 += PARAM1;
  473 + A0 = (uint32_t)(A0 + PARAM1);
  474 +}
  475 +
  476 +void OPPROTO op_movl_A0_seg(void)
  477 +{
  478 + A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);
  479 +}
  480 +
  481 +void OPPROTO op_addl_A0_seg(void)
  482 +{
  483 + A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));
379 484 }
380 485  
381 486 void OPPROTO op_addl_A0_AL(void)
382 487 {
383   - A0 += (EAX & 0xff);
  488 + A0 = (uint32_t)(A0 + (EAX & 0xff));
  489 +}
  490 +
  491 +#ifdef WORDS_BIGENDIAN
  492 +typedef union UREG64 {
  493 + struct { uint16_t v3, v2, v1, v0; } w;
  494 + struct { uint32_t v1, v0; } l;
  495 + uint64_t q;
  496 +} UREG64;
  497 +#else
  498 +typedef union UREG64 {
  499 + struct { uint16_t v0, v1, v2, v3; } w;
  500 + struct { uint32_t v0, v1; } l;
  501 + uint64_t q;
  502 +} UREG64;
  503 +#endif
  504 +
  505 +#ifdef TARGET_X86_64
  506 +
  507 +#define PARAMQ1 \
  508 +({\
  509 + UREG64 __p;\
  510 + __p.l.v1 = PARAM1;\
  511 + __p.l.v0 = PARAM2;\
  512 + __p.q;\
  513 +})
  514 +
  515 +void OPPROTO op_movq_T0_im64(void)
  516 +{
  517 + T0 = PARAMQ1;
384 518 }
385 519  
  520 +void OPPROTO op_movq_A0_im(void)
  521 +{
  522 + A0 = (int32_t)PARAM1;
  523 +}
  524 +
  525 +void OPPROTO op_movq_A0_im64(void)
  526 +{
  527 + A0 = PARAMQ1;
  528 +}
  529 +
  530 +void OPPROTO op_addq_A0_im(void)
  531 +{
  532 + A0 = (A0 + (int32_t)PARAM1);
  533 +}
  534 +
  535 +void OPPROTO op_addq_A0_im64(void)
  536 +{
  537 + A0 = (A0 + PARAMQ1);
  538 +}
  539 +
  540 +void OPPROTO op_movq_A0_seg(void)
  541 +{
  542 + A0 = *(target_ulong *)((char *)env + PARAM1);
  543 +}
  544 +
  545 +void OPPROTO op_addq_A0_seg(void)
  546 +{
  547 + A0 += *(target_ulong *)((char *)env + PARAM1);
  548 +}
  549 +
  550 +void OPPROTO op_addq_A0_AL(void)
  551 +{
  552 + A0 = (A0 + (EAX & 0xff));
  553 +}
  554 +
  555 +#endif
  556 +
386 557 void OPPROTO op_andl_A0_ffff(void)
387 558 {
388 559 A0 = A0 & 0xffff;
... ... @@ -401,29 +572,29 @@ void OPPROTO op_andl_A0_ffff(void)
401 572 #include "ops_mem.h"
402 573 #endif
403 574  
404   -/* used for bit operations */
  575 +/* indirect jump */
405 576  
406   -void OPPROTO op_add_bitw_A0_T1(void)
  577 +void OPPROTO op_jmp_T0(void)
407 578 {
408   - A0 += ((int16_t)T1 >> 4) << 1;
  579 + EIP = T0;
409 580 }
410 581  
411   -void OPPROTO op_add_bitl_A0_T1(void)
  582 +void OPPROTO op_movl_eip_im(void)
412 583 {
413   - A0 += ((int32_t)T1 >> 5) << 2;
  584 + EIP = (uint32_t)PARAM1;
414 585 }
415 586  
416   -/* indirect jump */
417   -
418   -void OPPROTO op_jmp_T0(void)
  587 +#ifdef TARGET_X86_64
  588 +void OPPROTO op_movq_eip_im(void)
419 589 {
420   - EIP = T0;
  590 + EIP = (int32_t)PARAM1;
421 591 }
422 592  
423   -void OPPROTO op_jmp_im(void)
  593 +void OPPROTO op_movq_eip_im64(void)
424 594 {
425   - EIP = PARAM1;
  595 + EIP = PARAMQ1;
426 596 }
  597 +#endif
427 598  
428 599 void OPPROTO op_hlt(void)
429 600 {
... ... @@ -505,11 +676,10 @@ void OPPROTO op_sti_vm(void)
505 676 void OPPROTO op_boundw(void)
506 677 {
507 678 int low, high, v;
508   - low = ldsw((uint8_t *)A0);
509   - high = ldsw((uint8_t *)A0 + 2);
  679 + low = ldsw(A0);
  680 + high = ldsw(A0 + 2);
510 681 v = (int16_t)T0;
511 682 if (v < low || v > high) {
512   - EIP = PARAM1;
513 683 raise_exception(EXCP05_BOUND);
514 684 }
515 685 FORCE_RET();
... ... @@ -518,11 +688,10 @@ void OPPROTO op_boundw(void)
518 688 void OPPROTO op_boundl(void)
519 689 {
520 690 int low, high, v;
521   - low = ldl((uint8_t *)A0);
522   - high = ldl((uint8_t *)A0 + 4);
  691 + low = ldl(A0);
  692 + high = ldl(A0 + 4);
523 693 v = T0;
524 694 if (v < low || v > high) {
525   - EIP = PARAM1;
526 695 raise_exception(EXCP05_BOUND);
527 696 }
528 697 FORCE_RET();
... ... @@ -533,11 +702,6 @@ void OPPROTO op_cmpxchg8b(void)
533 702 helper_cmpxchg8b();
534 703 }
535 704  
536   -void OPPROTO op_jmp(void)
537   -{
538   - JUMP_TB(op_jmp, PARAM1, 0, PARAM2);
539   -}
540   -
541 705 void OPPROTO op_movl_T0_0(void)
542 706 {
543 707 T0 = 0;
... ... @@ -564,6 +728,14 @@ void OPPROTO op_exit_tb(void)
564 728 #include "ops_template.h"
565 729 #undef SHIFT
566 730  
  731 +#ifdef TARGET_X86_64
  732 +
  733 +#define SHIFT 3
  734 +#include "ops_template.h"
  735 +#undef SHIFT
  736 +
  737 +#endif
  738 +
567 739 /* sign extend */
568 740  
569 741 void OPPROTO op_movsbl_T0_T0(void)
... ... @@ -581,6 +753,11 @@ void OPPROTO op_movswl_T0_T0(void)
581 753 T0 = (int16_t)T0;
582 754 }
583 755  
  756 +void OPPROTO op_movslq_T0_T0(void)
  757 +{
  758 + T0 = (int32_t)T0;
  759 +}
  760 +
584 761 void OPPROTO op_movzwl_T0_T0(void)
585 762 {
586 763 T0 = (uint16_t)T0;
... ... @@ -591,9 +768,16 @@ void OPPROTO op_movswl_EAX_AX(void)
591 768 EAX = (int16_t)EAX;
592 769 }
593 770  
  771 +#ifdef TARGET_X86_64
  772 +void OPPROTO op_movslq_RAX_EAX(void)
  773 +{
  774 + EAX = (int32_t)EAX;
  775 +}
  776 +#endif
  777 +
594 778 void OPPROTO op_movsbw_AX_AL(void)
595 779 {
596   - EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
  780 + EAX = (EAX & ~0xffff) | ((int8_t)EAX & 0xffff);
597 781 }
598 782  
599 783 void OPPROTO op_movslq_EDX_EAX(void)
... ... @@ -603,14 +787,21 @@ void OPPROTO op_movslq_EDX_EAX(void)
603 787  
604 788 void OPPROTO op_movswl_DX_AX(void)
605 789 {
606   - EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
  790 + EDX = (EDX & ~0xffff) | (((int16_t)EAX >> 15) & 0xffff);
  791 +}
  792 +
  793 +#ifdef TARGET_X86_64
  794 +void OPPROTO op_movsqo_RDX_RAX(void)
  795 +{
  796 + EDX = (int64_t)EAX >> 63;
607 797 }
  798 +#endif
608 799  
609 800 /* string ops helpers */
610 801  
611 802 void OPPROTO op_addl_ESI_T0(void)
612 803 {
613   - ESI += T0;
  804 + ESI = (uint32_t)(ESI + T0);
614 805 }
615 806  
616 807 void OPPROTO op_addw_ESI_T0(void)
... ... @@ -620,7 +811,7 @@ void OPPROTO op_addw_ESI_T0(void)
620 811  
621 812 void OPPROTO op_addl_EDI_T0(void)
622 813 {
623   - EDI += T0;
  814 + EDI = (uint32_t)(EDI + T0);
624 815 }
625 816  
626 817 void OPPROTO op_addw_EDI_T0(void)
... ... @@ -630,7 +821,7 @@ void OPPROTO op_addw_EDI_T0(void)
630 821  
631 822 void OPPROTO op_decl_ECX(void)
632 823 {
633   - ECX--;
  824 + ECX = (uint32_t)(ECX - 1);
634 825 }
635 826  
636 827 void OPPROTO op_decw_ECX(void)
... ... @@ -638,6 +829,23 @@ void OPPROTO op_decw_ECX(void)
638 829 ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);
639 830 }
640 831  
  832 +#ifdef TARGET_X86_64
  833 +void OPPROTO op_addq_ESI_T0(void)
  834 +{
  835 + ESI = (ESI + T0);
  836 +}
  837 +
  838 +void OPPROTO op_addq_EDI_T0(void)
  839 +{
  840 + EDI = (EDI + T0);
  841 +}
  842 +
  843 +void OPPROTO op_decq_ECX(void)
  844 +{
  845 + ECX--;
  846 +}
  847 +#endif
  848 +
641 849 /* push/pop utils */
642 850  
643 851 void op_addl_A0_SS(void)
... ... @@ -647,22 +855,22 @@ void op_addl_A0_SS(void)
647 855  
648 856 void op_subl_A0_2(void)
649 857 {
650   - A0 -= 2;
  858 + A0 = (uint32_t)(A0 - 2);
651 859 }
652 860  
653 861 void op_subl_A0_4(void)
654 862 {
655   - A0 -= 4;
  863 + A0 = (uint32_t)(A0 - 4);
656 864 }
657 865  
658 866 void op_addl_ESP_4(void)
659 867 {
660   - ESP += 4;
  868 + ESP = (uint32_t)(ESP + 4);
661 869 }
662 870  
663 871 void op_addl_ESP_2(void)
664 872 {
665   - ESP += 2;
  873 + ESP = (uint32_t)(ESP + 2);
666 874 }
667 875  
668 876 void op_addw_ESP_4(void)
... ... @@ -677,7 +885,7 @@ void op_addw_ESP_2(void)
677 885  
678 886 void op_addl_ESP_im(void)
679 887 {
680   - ESP += PARAM1;
  888 + ESP = (uint32_t)(ESP + PARAM1);
681 889 }
682 890  
683 891 void op_addw_ESP_im(void)
... ... @@ -685,6 +893,23 @@ void op_addw_ESP_im(void)
685 893 ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
686 894 }
687 895  
  896 +#ifdef TARGET_X86_64
  897 +void op_subq_A0_8(void)
  898 +{
  899 + A0 -= 8;
  900 +}
  901 +
  902 +void op_addq_ESP_8(void)
  903 +{
  904 + ESP += 8;
  905 +}
  906 +
  907 +void op_addq_ESP_im(void)
  908 +{
  909 + ESP += PARAM1;
  910 +}
  911 +#endif
  912 +
688 913 void OPPROTO op_rdtsc(void)
689 914 {
690 915 helper_rdtsc();
... ... @@ -710,6 +935,18 @@ void OPPROTO op_sysexit(void)
710 935 helper_sysexit();
711 936 }
712 937  
  938 +#ifdef TARGET_X86_64
  939 +void OPPROTO op_syscall(void)
  940 +{
  941 + helper_syscall();
  942 +}
  943 +
  944 +void OPPROTO op_sysret(void)
  945 +{
  946 + helper_sysret(PARAM1);
  947 +}
  948 +#endif
  949 +
713 950 void OPPROTO op_rdmsr(void)
714 951 {
715 952 helper_rdmsr();
... ... @@ -868,7 +1105,7 @@ void OPPROTO op_movl_seg_T0_vm(void)
868 1105 /* env->segs[] access */
869 1106 sc = (SegmentCache *)((char *)env + PARAM1);
870 1107 sc->selector = selector;
871   - sc->base = (void *)(selector << 4);
  1108 + sc->base = (selector << 4);
872 1109 }
873 1110  
874 1111 void OPPROTO op_movl_T0_seg(void)
... ... @@ -876,16 +1113,6 @@ void OPPROTO op_movl_T0_seg(void)
876 1113 T0 = env->segs[PARAM1].selector;
877 1114 }
878 1115  
879   -void OPPROTO op_movl_A0_seg(void)
880   -{
881   - A0 = *(unsigned long *)((char *)env + PARAM1);
882   -}
883   -
884   -void OPPROTO op_addl_A0_seg(void)
885   -{
886   - A0 += *(unsigned long *)((char *)env + PARAM1);
887   -}
888   -
889 1116 void OPPROTO op_lsl(void)
890 1117 {
891 1118 helper_lsl();
... ... @@ -1006,6 +1233,26 @@ void OPPROTO op_movl_env_T1(void)
1006 1233 *(uint32_t *)((char *)env + PARAM1) = T1;
1007 1234 }
1008 1235  
  1236 +void OPPROTO op_movtl_T0_env(void)
  1237 +{
  1238 + T0 = *(target_ulong *)((char *)env + PARAM1);
  1239 +}
  1240 +
  1241 +void OPPROTO op_movtl_env_T0(void)
  1242 +{
  1243 + *(target_ulong *)((char *)env + PARAM1) = T0;
  1244 +}
  1245 +
  1246 +void OPPROTO op_movtl_T1_env(void)
  1247 +{
  1248 + T1 = *(target_ulong *)((char *)env + PARAM1);
  1249 +}
  1250 +
  1251 +void OPPROTO op_movtl_env_T1(void)
  1252 +{
  1253 + *(target_ulong *)((char *)env + PARAM1) = T1;
  1254 +}
  1255 +
1009 1256 void OPPROTO op_clts(void)
1010 1257 {
1011 1258 env->cr[0] &= ~CR0_TS_MASK;
... ... @@ -1014,25 +1261,31 @@ void OPPROTO op_clts(void)
1014 1261  
1015 1262 /* flags handling */
1016 1263  
1017   -/* slow jumps cases : in order to avoid calling a function with a
1018   - pointer (which can generate a stack frame on PowerPC), we use
1019   - op_setcc to set T0 and then call op_jcc. */
1020   -void OPPROTO op_jcc(void)
  1264 +void OPPROTO op_goto_tb0(void)
1021 1265 {
1022   - if (T0)
1023   - JUMP_TB(op_jcc, PARAM1, 0, PARAM2);
1024   - else
1025   - JUMP_TB(op_jcc, PARAM1, 1, PARAM3);
1026   - FORCE_RET();
  1266 + GOTO_TB(op_goto_tb0, 0);
  1267 +}
  1268 +
  1269 +void OPPROTO op_goto_tb1(void)
  1270 +{
  1271 + GOTO_TB(op_goto_tb1, 1);
  1272 +}
  1273 +
  1274 +void OPPROTO op_jmp_label(void)
  1275 +{
  1276 + GOTO_LABEL_PARAM(1);
1027 1277 }
1028 1278  
1029   -void OPPROTO op_jcc_im(void)
  1279 +void OPPROTO op_jnz_T0_label(void)
1030 1280 {
1031 1281 if (T0)
1032   - EIP = PARAM1;
1033   - else
1034   - EIP = PARAM2;
1035   - FORCE_RET();
  1282 + GOTO_LABEL_PARAM(1);
  1283 +}
  1284 +
  1285 +void OPPROTO op_jz_T0_label(void)
  1286 +{
  1287 + if (!T0)
  1288 + GOTO_LABEL_PARAM(1);
1036 1289 }
1037 1290  
1038 1291 /* slow set cases (compute x86 flags) */
... ... @@ -1299,6 +1552,28 @@ CCTable cc_table[CC_OP_NB] = {
1299 1552 [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl },
1300 1553 [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl },
1301 1554 [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl },
  1555 +
  1556 +#ifdef TARGET_X86_64
  1557 + [CC_OP_MULQ] = { compute_all_mulq, compute_c_mull },
  1558 +
  1559 + [CC_OP_ADDQ] = { compute_all_addq, compute_c_addq },
  1560 +
  1561 + [CC_OP_ADCQ] = { compute_all_adcq, compute_c_adcq },
  1562 +
  1563 + [CC_OP_SUBQ] = { compute_all_subq, compute_c_subq },
  1564 +
  1565 + [CC_OP_SBBQ] = { compute_all_sbbq, compute_c_sbbq },
  1566 +
  1567 + [CC_OP_LOGICQ] = { compute_all_logicq, compute_c_logicq },
  1568 +
  1569 + [CC_OP_INCQ] = { compute_all_incq, compute_c_incl },
  1570 +
  1571 + [CC_OP_DECQ] = { compute_all_decq, compute_c_incl },
  1572 +
  1573 + [CC_OP_SHLQ] = { compute_all_shlq, compute_c_shlq },
  1574 +
  1575 + [CC_OP_SARQ] = { compute_all_sarq, compute_c_sarl },
  1576 +#endif
1302 1577 };
1303 1578  
1304 1579 /* floating point support. Some of the code for complicated x87
... ... @@ -1330,20 +1605,20 @@ double qemu_rint(double x)
1330 1605 void OPPROTO op_flds_FT0_A0(void)
1331 1606 {
1332 1607 #ifdef USE_FP_CONVERT
1333   - FP_CONVERT.i32 = ldl((void *)A0);
  1608 + FP_CONVERT.i32 = ldl(A0);
1334 1609 FT0 = FP_CONVERT.f;
1335 1610 #else
1336   - FT0 = ldfl((void *)A0);
  1611 + FT0 = ldfl(A0);
1337 1612 #endif
1338 1613 }
1339 1614  
1340 1615 void OPPROTO op_fldl_FT0_A0(void)
1341 1616 {
1342 1617 #ifdef USE_FP_CONVERT
1343   - FP_CONVERT.i64 = ldq((void *)A0);
  1618 + FP_CONVERT.i64 = ldq(A0);
1344 1619 FT0 = FP_CONVERT.d;
1345 1620 #else
1346   - FT0 = ldfq((void *)A0);
  1621 + FT0 = ldfq(A0);
1347 1622 #endif
1348 1623 }
1349 1624  
... ... @@ -1352,17 +1627,17 @@ void OPPROTO op_fldl_FT0_A0(void)
1352 1627  
1353 1628 void helper_fild_FT0_A0(void)
1354 1629 {
1355   - FT0 = (CPU86_LDouble)ldsw((void *)A0);
  1630 + FT0 = (CPU86_LDouble)ldsw(A0);
1356 1631 }
1357 1632  
1358 1633 void helper_fildl_FT0_A0(void)
1359 1634 {
1360   - FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1635 + FT0 = (CPU86_LDouble)((int32_t)ldl(A0));
1361 1636 }
1362 1637  
1363 1638 void helper_fildll_FT0_A0(void)
1364 1639 {
1365   - FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1640 + FT0 = (CPU86_LDouble)((int64_t)ldq(A0));
1366 1641 }
1367 1642  
1368 1643 void OPPROTO op_fild_FT0_A0(void)
... ... @@ -1385,30 +1660,30 @@ void OPPROTO op_fildll_FT0_A0(void)
1385 1660 void OPPROTO op_fild_FT0_A0(void)
1386 1661 {
1387 1662 #ifdef USE_FP_CONVERT
1388   - FP_CONVERT.i32 = ldsw((void *)A0);
  1663 + FP_CONVERT.i32 = ldsw(A0);
1389 1664 FT0 = (CPU86_LDouble)FP_CONVERT.i32;
1390 1665 #else
1391   - FT0 = (CPU86_LDouble)ldsw((void *)A0);
  1666 + FT0 = (CPU86_LDouble)ldsw(A0);
1392 1667 #endif
1393 1668 }
1394 1669  
1395 1670 void OPPROTO op_fildl_FT0_A0(void)
1396 1671 {
1397 1672 #ifdef USE_FP_CONVERT
1398   - FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
  1673 + FP_CONVERT.i32 = (int32_t) ldl(A0);
1399 1674 FT0 = (CPU86_LDouble)FP_CONVERT.i32;
1400 1675 #else
1401   - FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1676 + FT0 = (CPU86_LDouble)((int32_t)ldl(A0));
1402 1677 #endif
1403 1678 }
1404 1679  
1405 1680 void OPPROTO op_fildll_FT0_A0(void)
1406 1681 {
1407 1682 #ifdef USE_FP_CONVERT
1408   - FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
  1683 + FP_CONVERT.i64 = (int64_t) ldq(A0);
1409 1684 FT0 = (CPU86_LDouble)FP_CONVERT.i64;
1410 1685 #else
1411   - FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1686 + FT0 = (CPU86_LDouble)((int64_t)ldq(A0));
1412 1687 #endif
1413 1688 }
1414 1689 #endif
... ... @@ -1420,10 +1695,10 @@ void OPPROTO op_flds_ST0_A0(void)
1420 1695 int new_fpstt;
1421 1696 new_fpstt = (env->fpstt - 1) & 7;
1422 1697 #ifdef USE_FP_CONVERT
1423   - FP_CONVERT.i32 = ldl((void *)A0);
  1698 + FP_CONVERT.i32 = ldl(A0);
1424 1699 env->fpregs[new_fpstt] = FP_CONVERT.f;
1425 1700 #else
1426   - env->fpregs[new_fpstt] = ldfl((void *)A0);
  1701 + env->fpregs[new_fpstt] = ldfl(A0);
1427 1702 #endif
1428 1703 env->fpstt = new_fpstt;
1429 1704 env->fptags[new_fpstt] = 0; /* validate stack entry */
... ... @@ -1434,10 +1709,10 @@ void OPPROTO op_fldl_ST0_A0(void)
1434 1709 int new_fpstt;
1435 1710 new_fpstt = (env->fpstt - 1) & 7;
1436 1711 #ifdef USE_FP_CONVERT
1437   - FP_CONVERT.i64 = ldq((void *)A0);
  1712 + FP_CONVERT.i64 = ldq(A0);
1438 1713 env->fpregs[new_fpstt] = FP_CONVERT.d;
1439 1714 #else
1440   - env->fpregs[new_fpstt] = ldfq((void *)A0);
  1715 + env->fpregs[new_fpstt] = ldfq(A0);
1441 1716 #endif
1442 1717 env->fpstt = new_fpstt;
1443 1718 env->fptags[new_fpstt] = 0; /* validate stack entry */
... ... @@ -1455,7 +1730,7 @@ void helper_fild_ST0_A0(void)
1455 1730 {
1456 1731 int new_fpstt;
1457 1732 new_fpstt = (env->fpstt - 1) & 7;
1458   - env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
  1733 + env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw(A0);
1459 1734 env->fpstt = new_fpstt;
1460 1735 env->fptags[new_fpstt] = 0; /* validate stack entry */
1461 1736 }
... ... @@ -1464,7 +1739,7 @@ void helper_fildl_ST0_A0(void)
1464 1739 {
1465 1740 int new_fpstt;
1466 1741 new_fpstt = (env->fpstt - 1) & 7;
1467   - env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1742 + env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl(A0));
1468 1743 env->fpstt = new_fpstt;
1469 1744 env->fptags[new_fpstt] = 0; /* validate stack entry */
1470 1745 }
... ... @@ -1473,7 +1748,7 @@ void helper_fildll_ST0_A0(void)
1473 1748 {
1474 1749 int new_fpstt;
1475 1750 new_fpstt = (env->fpstt - 1) & 7;
1476   - env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1751 + env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq(A0));
1477 1752 env->fpstt = new_fpstt;
1478 1753 env->fptags[new_fpstt] = 0; /* validate stack entry */
1479 1754 }
... ... @@ -1500,10 +1775,10 @@ void OPPROTO op_fild_ST0_A0(void)
1500 1775 int new_fpstt;
1501 1776 new_fpstt = (env->fpstt - 1) & 7;
1502 1777 #ifdef USE_FP_CONVERT
1503   - FP_CONVERT.i32 = ldsw((void *)A0);
  1778 + FP_CONVERT.i32 = ldsw(A0);
1504 1779 env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
1505 1780 #else
1506   - env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
  1781 + env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw(A0);
1507 1782 #endif
1508 1783 env->fpstt = new_fpstt;
1509 1784 env->fptags[new_fpstt] = 0; /* validate stack entry */
... ... @@ -1514,10 +1789,10 @@ void OPPROTO op_fildl_ST0_A0(void)
1514 1789 int new_fpstt;
1515 1790 new_fpstt = (env->fpstt - 1) & 7;
1516 1791 #ifdef USE_FP_CONVERT
1517   - FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
  1792 + FP_CONVERT.i32 = (int32_t) ldl(A0);
1518 1793 env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
1519 1794 #else
1520   - env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1795 + env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl(A0));
1521 1796 #endif
1522 1797 env->fpstt = new_fpstt;
1523 1798 env->fptags[new_fpstt] = 0; /* validate stack entry */
... ... @@ -1528,10 +1803,10 @@ void OPPROTO op_fildll_ST0_A0(void)
1528 1803 int new_fpstt;
1529 1804 new_fpstt = (env->fpstt - 1) & 7;
1530 1805 #ifdef USE_FP_CONVERT
1531   - FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
  1806 + FP_CONVERT.i64 = (int64_t) ldq(A0);
1532 1807 env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i64;
1533 1808 #else
1534   - env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1809 + env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq(A0));
1535 1810 #endif
1536 1811 env->fpstt = new_fpstt;
1537 1812 env->fptags[new_fpstt] = 0; /* validate stack entry */
... ... @@ -1545,15 +1820,15 @@ void OPPROTO op_fsts_ST0_A0(void)
1545 1820 {
1546 1821 #ifdef USE_FP_CONVERT
1547 1822 FP_CONVERT.f = (float)ST0;
1548   - stfl((void *)A0, FP_CONVERT.f);
  1823 + stfl(A0, FP_CONVERT.f);
1549 1824 #else
1550   - stfl((void *)A0, (float)ST0);
  1825 + stfl(A0, (float)ST0);
1551 1826 #endif
1552 1827 }
1553 1828  
1554 1829 void OPPROTO op_fstl_ST0_A0(void)
1555 1830 {
1556   - stfq((void *)A0, (double)ST0);
  1831 + stfq(A0, (double)ST0);
1557 1832 }
1558 1833  
1559 1834 void OPPROTO op_fstt_ST0_A0(void)
... ... @@ -1574,7 +1849,7 @@ void OPPROTO op_fist_ST0_A0(void)
1574 1849 val = lrint(d);
1575 1850 if (val != (int16_t)val)
1576 1851 val = -32768;
1577   - stw((void *)A0, val);
  1852 + stw(A0, val);
1578 1853 }
1579 1854  
1580 1855 void OPPROTO op_fistl_ST0_A0(void)
... ... @@ -1588,7 +1863,7 @@ void OPPROTO op_fistl_ST0_A0(void)
1588 1863  
1589 1864 d = ST0;
1590 1865 val = lrint(d);
1591   - stl((void *)A0, val);
  1866 + stl(A0, val);
1592 1867 }
1593 1868  
1594 1869 void OPPROTO op_fistll_ST0_A0(void)
... ... @@ -1602,7 +1877,7 @@ void OPPROTO op_fistll_ST0_A0(void)
1602 1877  
1603 1878 d = ST0;
1604 1879 val = llrint(d);
1605   - stq((void *)A0, val);
  1880 + stq(A0, val);
1606 1881 }
1607 1882  
1608 1883 void OPPROTO op_fbld_ST0_A0(void)
... ... @@ -1934,25 +2209,25 @@ void OPPROTO op_fnstsw_A0(void)
1934 2209 {
1935 2210 int fpus;
1936 2211 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1937   - stw((void *)A0, fpus);
  2212 + stw(A0, fpus);
1938 2213 }
1939 2214  
1940 2215 void OPPROTO op_fnstsw_EAX(void)
1941 2216 {
1942 2217 int fpus;
1943 2218 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1944   - EAX = (EAX & 0xffff0000) | fpus;
  2219 + EAX = (EAX & ~0xffff) | fpus;
1945 2220 }
1946 2221  
1947 2222 void OPPROTO op_fnstcw_A0(void)
1948 2223 {
1949   - stw((void *)A0, env->fpuc);
  2224 + stw(A0, env->fpuc);
1950 2225 }
1951 2226  
1952 2227 void OPPROTO op_fldcw_A0(void)
1953 2228 {
1954 2229 int rnd_type;
1955   - env->fpuc = lduw((void *)A0);
  2230 + env->fpuc = lduw(A0);
1956 2231 /* set rounding mode */
1957 2232 switch(env->fpuc & RC_MASK) {
1958 2233 default:
... ... @@ -2001,22 +2276,22 @@ void OPPROTO op_fninit(void)
2001 2276  
2002 2277 void OPPROTO op_fnstenv_A0(void)
2003 2278 {
2004   - helper_fstenv((uint8_t *)A0, PARAM1);
  2279 + helper_fstenv(A0, PARAM1);
2005 2280 }
2006 2281  
2007 2282 void OPPROTO op_fldenv_A0(void)
2008 2283 {
2009   - helper_fldenv((uint8_t *)A0, PARAM1);
  2284 + helper_fldenv(A0, PARAM1);
2010 2285 }
2011 2286  
2012 2287 void OPPROTO op_fnsave_A0(void)
2013 2288 {
2014   - helper_fsave((uint8_t *)A0, PARAM1);
  2289 + helper_fsave(A0, PARAM1);
2015 2290 }
2016 2291  
2017 2292 void OPPROTO op_frstor_A0(void)
2018 2293 {
2019   - helper_frstor((uint8_t *)A0, PARAM1);
  2294 + helper_frstor(A0, PARAM1);
2020 2295 }
2021 2296  
2022 2297 /* threading support */
... ... @@ -2030,3 +2305,30 @@ void OPPROTO op_unlock(void)
2030 2305 cpu_unlock();
2031 2306 }
2032 2307  
  2308 +/* SSE support */
  2309 +static inline void memcpy16(void *d, void *s)
  2310 +{
  2311 + ((uint32_t *)d)[0] = ((uint32_t *)s)[0];
  2312 + ((uint32_t *)d)[1] = ((uint32_t *)s)[1];
  2313 + ((uint32_t *)d)[2] = ((uint32_t *)s)[2];
  2314 + ((uint32_t *)d)[3] = ((uint32_t *)s)[3];
  2315 +}
  2316 +
  2317 +void OPPROTO op_movo(void)
  2318 +{
  2319 + /* XXX: badly generated code */
  2320 + XMMReg *d, *s;
  2321 + d = (XMMReg *)((char *)env + PARAM1);
  2322 + s = (XMMReg *)((char *)env + PARAM2);
  2323 + memcpy16(d, s);
  2324 +}
  2325 +
  2326 +void OPPROTO op_fxsave_A0(void)
  2327 +{
  2328 + helper_fxsave(A0, PARAM1);
  2329 +}
  2330 +
  2331 +void OPPROTO op_fxrstor_A0(void)
  2332 +{
  2333 + helper_fxrstor(A0, PARAM1);
  2334 +}
... ...
target-i386/opreg_template.h
... ... @@ -20,29 +20,56 @@
20 20 */
21 21 void OPPROTO glue(op_movl_A0,REGNAME)(void)
22 22 {
23   - A0 = REG;
  23 + A0 = (uint32_t)REG;
24 24 }
25 25  
26 26 void OPPROTO glue(op_addl_A0,REGNAME)(void)
27 27 {
28   - A0 += REG;
  28 + A0 = (uint32_t)(A0 + REG);
29 29 }
30 30  
31 31 void OPPROTO glue(glue(op_addl_A0,REGNAME),_s1)(void)
32 32 {
33   - A0 += REG << 1;
  33 + A0 = (uint32_t)(A0 + (REG << 1));
34 34 }
35 35  
36 36 void OPPROTO glue(glue(op_addl_A0,REGNAME),_s2)(void)
37 37 {
38   - A0 += REG << 2;
  38 + A0 = (uint32_t)(A0 + (REG << 2));
39 39 }
40 40  
41 41 void OPPROTO glue(glue(op_addl_A0,REGNAME),_s3)(void)
42 42 {
43   - A0 += REG << 3;
  43 + A0 = (uint32_t)(A0 + (REG << 3));
  44 +}
  45 +
  46 +#ifdef TARGET_X86_64
  47 +void OPPROTO glue(op_movq_A0,REGNAME)(void)
  48 +{
  49 + A0 = REG;
  50 +}
  51 +
  52 +void OPPROTO glue(op_addq_A0,REGNAME)(void)
  53 +{
  54 + A0 = (A0 + REG);
  55 +}
  56 +
  57 +void OPPROTO glue(glue(op_addq_A0,REGNAME),_s1)(void)
  58 +{
  59 + A0 = (A0 + (REG << 1));
  60 +}
  61 +
  62 +void OPPROTO glue(glue(op_addq_A0,REGNAME),_s2)(void)
  63 +{
  64 + A0 = (A0 + (REG << 2));
44 65 }
45 66  
  67 +void OPPROTO glue(glue(op_addq_A0,REGNAME),_s3)(void)
  68 +{
  69 + A0 = (A0 + (REG << 3));
  70 +}
  71 +#endif
  72 +
46 73 void OPPROTO glue(op_movl_T0,REGNAME)(void)
47 74 {
48 75 T0 = REG;
... ... @@ -65,72 +92,99 @@ void OPPROTO glue(op_movh_T1,REGNAME)(void)
65 92  
66 93 void OPPROTO glue(glue(op_movl,REGNAME),_T0)(void)
67 94 {
68   - REG = T0;
  95 + REG = (uint32_t)T0;
69 96 }
70 97  
71 98 void OPPROTO glue(glue(op_movl,REGNAME),_T1)(void)
72 99 {
73   - REG = T1;
  100 + REG = (uint32_t)T1;
74 101 }
75 102  
76 103 void OPPROTO glue(glue(op_movl,REGNAME),_A0)(void)
77 104 {
  105 + REG = (uint32_t)A0;
  106 +}
  107 +
  108 +#ifdef TARGET_X86_64
  109 +void OPPROTO glue(glue(op_movq,REGNAME),_T0)(void)
  110 +{
  111 + REG = T0;
  112 +}
  113 +
  114 +void OPPROTO glue(glue(op_movq,REGNAME),_T1)(void)
  115 +{
  116 + REG = T1;
  117 +}
  118 +
  119 +void OPPROTO glue(glue(op_movq,REGNAME),_A0)(void)
  120 +{
78 121 REG = A0;
79 122 }
  123 +#endif
80 124  
81 125 /* mov T1 to REG if T0 is true */
82 126 void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
83 127 {
84 128 if (T0)
85   - REG = (REG & 0xffff0000) | (T1 & 0xffff);
  129 + REG = (REG & ~0xffff) | (T1 & 0xffff);
86 130 FORCE_RET();
87 131 }
88 132  
89 133 void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
90 134 {
91 135 if (T0)
  136 + REG = (uint32_t)T1;
  137 + FORCE_RET();
  138 +}
  139 +
  140 +#ifdef TARGET_X86_64
  141 +void OPPROTO glue(glue(op_cmovq,REGNAME),_T1_T0)(void)
  142 +{
  143 + if (T0)
92 144 REG = T1;
93 145 FORCE_RET();
94 146 }
  147 +#endif
95 148  
96 149 /* NOTE: T0 high order bits are ignored */
97 150 void OPPROTO glue(glue(op_movw,REGNAME),_T0)(void)
98 151 {
99   - REG = (REG & 0xffff0000) | (T0 & 0xffff);
  152 + REG = (REG & ~0xffff) | (T0 & 0xffff);
100 153 }
101 154  
102 155 /* NOTE: T0 high order bits are ignored */
103 156 void OPPROTO glue(glue(op_movw,REGNAME),_T1)(void)
104 157 {
105   - REG = (REG & 0xffff0000) | (T1 & 0xffff);
  158 + REG = (REG & ~0xffff) | (T1 & 0xffff);
106 159 }
107 160  
108 161 /* NOTE: A0 high order bits are ignored */
109 162 void OPPROTO glue(glue(op_movw,REGNAME),_A0)(void)
110 163 {
111   - REG = (REG & 0xffff0000) | (A0 & 0xffff);
  164 + REG = (REG & ~0xffff) | (A0 & 0xffff);
112 165 }
113 166  
114 167 /* NOTE: T0 high order bits are ignored */
115 168 void OPPROTO glue(glue(op_movb,REGNAME),_T0)(void)
116 169 {
117   - REG = (REG & 0xffffff00) | (T0 & 0xff);
  170 + REG = (REG & ~0xff) | (T0 & 0xff);
118 171 }
119 172  
120 173 /* NOTE: T0 high order bits are ignored */
121 174 void OPPROTO glue(glue(op_movh,REGNAME),_T0)(void)
122 175 {
123   - REG = (REG & 0xffff00ff) | ((T0 & 0xff) << 8);
  176 + REG = (REG & ~0xff00) | ((T0 & 0xff) << 8);
124 177 }
125 178  
126 179 /* NOTE: T1 high order bits are ignored */
127 180 void OPPROTO glue(glue(op_movb,REGNAME),_T1)(void)
128 181 {
129   - REG = (REG & 0xffffff00) | (T1 & 0xff);
  182 + REG = (REG & ~0xff) | (T1 & 0xff);
130 183 }
131 184  
132 185 /* NOTE: T1 high order bits are ignored */
133 186 void OPPROTO glue(glue(op_movh,REGNAME),_T1)(void)
134 187 {
135   - REG = (REG & 0xffff00ff) | ((T1 & 0xff) << 8);
  188 + REG = (REG & ~0xff00) | ((T1 & 0xff) << 8);
136 189 }
  190 +
... ...
target-i386/ops_mem.h
1 1 void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T0_A0)(void)
2 2 {
3   - T0 = glue(ldub, MEMSUFFIX)((uint8_t *)A0);
  3 + T0 = glue(ldub, MEMSUFFIX)(A0);
4 4 }
5 5  
6 6 void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T0_A0)(void)
7 7 {
8   - T0 = glue(ldsb, MEMSUFFIX)((int8_t *)A0);
  8 + T0 = glue(ldsb, MEMSUFFIX)(A0);
9 9 }
10 10  
11 11 void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T0_A0)(void)
12 12 {
13   - T0 = glue(lduw, MEMSUFFIX)((uint8_t *)A0);
  13 + T0 = glue(lduw, MEMSUFFIX)(A0);
14 14 }
15 15  
16 16 void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T0_A0)(void)
17 17 {
18   - T0 = glue(ldsw, MEMSUFFIX)((int8_t *)A0);
  18 + T0 = glue(ldsw, MEMSUFFIX)(A0);
19 19 }
20 20  
21 21 void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T0_A0)(void)
22 22 {
23   - T0 = glue(ldl, MEMSUFFIX)((uint8_t *)A0);
  23 + T0 = (uint32_t)glue(ldl, MEMSUFFIX)(A0);
24 24 }
25 25  
26 26 void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T1_A0)(void)
27 27 {
28   - T1 = glue(ldub, MEMSUFFIX)((uint8_t *)A0);
  28 + T1 = glue(ldub, MEMSUFFIX)(A0);
29 29 }
30 30  
31 31 void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T1_A0)(void)
32 32 {
33   - T1 = glue(ldsb, MEMSUFFIX)((int8_t *)A0);
  33 + T1 = glue(ldsb, MEMSUFFIX)(A0);
34 34 }
35 35  
36 36 void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T1_A0)(void)
37 37 {
38   - T1 = glue(lduw, MEMSUFFIX)((uint8_t *)A0);
  38 + T1 = glue(lduw, MEMSUFFIX)(A0);
39 39 }
40 40  
41 41 void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T1_A0)(void)
42 42 {
43   - T1 = glue(ldsw, MEMSUFFIX)((int8_t *)A0);
  43 + T1 = glue(ldsw, MEMSUFFIX)(A0);
44 44 }
45 45  
46 46 void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T1_A0)(void)
47 47 {
48   - T1 = glue(ldl, MEMSUFFIX)((uint8_t *)A0);
  48 + T1 = glue(ldl, MEMSUFFIX)(A0);
49 49 }
50 50  
51 51 void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T0_A0)(void)
52 52 {
53   - glue(stb, MEMSUFFIX)((uint8_t *)A0, T0);
  53 + glue(stb, MEMSUFFIX)(A0, T0);
54 54 }
55 55  
56 56 void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T0_A0)(void)
57 57 {
58   - glue(stw, MEMSUFFIX)((uint8_t *)A0, T0);
  58 + glue(stw, MEMSUFFIX)(A0, T0);
59 59 }
60 60  
61 61 void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void)
62 62 {
63   - glue(stl, MEMSUFFIX)((uint8_t *)A0, T0);
  63 + glue(stl, MEMSUFFIX)(A0, T0);
64 64 }
65 65  
66 66 #if 0
67 67 void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T1_A0)(void)
68 68 {
69   - glue(stb, MEMSUFFIX)((uint8_t *)A0, T1);
  69 + glue(stb, MEMSUFFIX)(A0, T1);
70 70 }
71 71 #endif
72 72  
73 73 void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T1_A0)(void)
74 74 {
75   - glue(stw, MEMSUFFIX)((uint8_t *)A0, T1);
  75 + glue(stw, MEMSUFFIX)(A0, T1);
76 76 }
77 77  
78 78 void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T1_A0)(void)
79 79 {
80   - glue(stl, MEMSUFFIX)((uint8_t *)A0, T1);
  80 + glue(stl, MEMSUFFIX)(A0, T1);
81 81 }
82 82  
  83 +/* SSE support */
  84 +void OPPROTO glue(glue(op_ldo, MEMSUFFIX), _env_A0)(void)
  85 +{
  86 + XMMReg *p;
  87 + p = (XMMReg *)((char *)env + PARAM1);
  88 + /* XXX: host endianness ? */
  89 + p->u.q[0] = glue(ldq, MEMSUFFIX)(A0);
  90 + p->u.q[1] = glue(ldq, MEMSUFFIX)(A0 + 8);
  91 +}
  92 +
  93 +void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void)
  94 +{
  95 + XMMReg *p;
  96 + p = (XMMReg *)((char *)env + PARAM1);
  97 + /* XXX: host endianness ? */
  98 + glue(stq, MEMSUFFIX)(A0, p->u.q[0]);
  99 + glue(stq, MEMSUFFIX)(A0 + 8, p->u.q[1]);
  100 +}
  101 +
  102 +#ifdef TARGET_X86_64
  103 +void OPPROTO glue(glue(op_ldsl, MEMSUFFIX), _T0_A0)(void)
  104 +{
  105 + T0 = (int32_t)glue(ldl, MEMSUFFIX)(A0);
  106 +}
  107 +
  108 +void OPPROTO glue(glue(op_ldsl, MEMSUFFIX), _T1_A0)(void)
  109 +{
  110 + T1 = (int32_t)glue(ldl, MEMSUFFIX)(A0);
  111 +}
  112 +
  113 +void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _T0_A0)(void)
  114 +{
  115 + T0 = glue(ldq, MEMSUFFIX)(A0);
  116 +}
  117 +
  118 +void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _T1_A0)(void)
  119 +{
  120 + T1 = glue(ldq, MEMSUFFIX)(A0);
  121 +}
  122 +
  123 +void OPPROTO glue(glue(op_stq, MEMSUFFIX), _T0_A0)(void)
  124 +{
  125 + glue(stq, MEMSUFFIX)(A0, T0);
  126 +}
  127 +
  128 +void OPPROTO glue(glue(op_stq, MEMSUFFIX), _T1_A0)(void)
  129 +{
  130 + glue(stq, MEMSUFFIX)(A0, T1);
  131 +}
  132 +#endif
  133 +
83 134 #undef MEMSUFFIX
... ...
target-i386/ops_template.h
... ... @@ -20,7 +20,12 @@
20 20 */
21 21 #define DATA_BITS (1 << (3 + SHIFT))
22 22 #define SHIFT_MASK (DATA_BITS - 1)
23   -#define SIGN_MASK (1 << (DATA_BITS - 1))
  23 +#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
  24 +#if DATA_BITS <= 32
  25 +#define SHIFT1_MASK 0x1f
  26 +#else
  27 +#define SHIFT1_MASK 0x3f
  28 +#endif
24 29  
25 30 #if DATA_BITS == 8
26 31 #define SUFFIX b
... ... @@ -37,6 +42,11 @@
37 42 #define DATA_TYPE uint32_t
38 43 #define DATA_STYPE int32_t
39 44 #define DATA_MASK 0xffffffff
  45 +#elif DATA_BITS == 64
  46 +#define SUFFIX q
  47 +#define DATA_TYPE uint64_t
  48 +#define DATA_STYPE int64_t
  49 +#define DATA_MASK 0xffffffffffffffff
40 50 #else
41 51 #error unhandled operand size
42 52 #endif
... ... @@ -46,7 +56,7 @@
46 56 static int glue(compute_all_add, SUFFIX)(void)
47 57 {
48 58 int cf, pf, af, zf, sf, of;
49   - int src1, src2;
  59 + target_long src1, src2;
50 60 src1 = CC_SRC;
51 61 src2 = CC_DST - CC_SRC;
52 62 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
... ... @@ -60,7 +70,8 @@ static int glue(compute_all_add, SUFFIX)(void)
60 70  
61 71 static int glue(compute_c_add, SUFFIX)(void)
62 72 {
63   - int src1, cf;
  73 + int cf;
  74 + target_long src1;
64 75 src1 = CC_SRC;
65 76 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
66 77 return cf;
... ... @@ -69,7 +80,7 @@ static int glue(compute_c_add, SUFFIX)(void)
69 80 static int glue(compute_all_adc, SUFFIX)(void)
70 81 {
71 82 int cf, pf, af, zf, sf, of;
72   - int src1, src2;
  83 + target_long src1, src2;
73 84 src1 = CC_SRC;
74 85 src2 = CC_DST - CC_SRC - 1;
75 86 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
... ... @@ -83,7 +94,8 @@ static int glue(compute_all_adc, SUFFIX)(void)
83 94  
84 95 static int glue(compute_c_adc, SUFFIX)(void)
85 96 {
86   - int src1, cf;
  97 + int cf;
  98 + target_long src1;
87 99 src1 = CC_SRC;
88 100 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
89 101 return cf;
... ... @@ -92,7 +104,7 @@ static int glue(compute_c_adc, SUFFIX)(void)
92 104 static int glue(compute_all_sub, SUFFIX)(void)
93 105 {
94 106 int cf, pf, af, zf, sf, of;
95   - int src1, src2;
  107 + target_long src1, src2;
96 108 src1 = CC_DST + CC_SRC;
97 109 src2 = CC_SRC;
98 110 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
... ... @@ -106,7 +118,8 @@ static int glue(compute_all_sub, SUFFIX)(void)
106 118  
107 119 static int glue(compute_c_sub, SUFFIX)(void)
108 120 {
109   - int src1, src2, cf;
  121 + int cf;
  122 + target_long src1, src2;
110 123 src1 = CC_DST + CC_SRC;
111 124 src2 = CC_SRC;
112 125 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
... ... @@ -116,7 +129,7 @@ static int glue(compute_c_sub, SUFFIX)(void)
116 129 static int glue(compute_all_sbb, SUFFIX)(void)
117 130 {
118 131 int cf, pf, af, zf, sf, of;
119   - int src1, src2;
  132 + target_long src1, src2;
120 133 src1 = CC_DST + CC_SRC + 1;
121 134 src2 = CC_SRC;
122 135 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
... ... @@ -130,7 +143,8 @@ static int glue(compute_all_sbb, SUFFIX)(void)
130 143  
131 144 static int glue(compute_c_sbb, SUFFIX)(void)
132 145 {
133   - int src1, src2, cf;
  146 + int cf;
  147 + target_long src1, src2;
134 148 src1 = CC_DST + CC_SRC + 1;
135 149 src2 = CC_SRC;
136 150 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
... ... @@ -157,7 +171,7 @@ static int glue(compute_c_logic, SUFFIX)(void)
157 171 static int glue(compute_all_inc, SUFFIX)(void)
158 172 {
159 173 int cf, pf, af, zf, sf, of;
160   - int src1, src2;
  174 + target_long src1, src2;
161 175 src1 = CC_DST - 1;
162 176 src2 = 1;
163 177 cf = CC_SRC;
... ... @@ -179,7 +193,7 @@ static int glue(compute_c_inc, SUFFIX)(void)
179 193 static int glue(compute_all_dec, SUFFIX)(void)
180 194 {
181 195 int cf, pf, af, zf, sf, of;
182   - int src1, src2;
  196 + target_long src1, src2;
183 197 src1 = CC_DST + 1;
184 198 src2 = 1;
185 199 cf = CC_SRC;
... ... @@ -187,7 +201,7 @@ static int glue(compute_all_dec, SUFFIX)(void)
187 201 af = (CC_DST ^ src1 ^ src2) & 0x10;
188 202 zf = ((DATA_TYPE)CC_DST == 0) << 6;
189 203 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
190   - of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
  204 + of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
191 205 return cf | pf | af | zf | sf | of;
192 206 }
193 207  
... ... @@ -256,71 +270,66 @@ static int glue(compute_all_mul, SUFFIX)(void)
256 270  
257 271 void OPPROTO glue(op_jb_sub, SUFFIX)(void)
258 272 {
259   - int src1, src2;
  273 + target_long src1, src2;
260 274 src1 = CC_DST + CC_SRC;
261 275 src2 = CC_SRC;
262 276  
263 277 if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
264   - JUMP_TB(glue(op_jb_sub, SUFFIX), PARAM1, 0, PARAM2);
265   - else
266   - JUMP_TB(glue(op_jb_sub, SUFFIX), PARAM1, 1, PARAM3);
  278 + GOTO_LABEL_PARAM(1);
267 279 FORCE_RET();
268 280 }
269 281  
270 282 void OPPROTO glue(op_jz_sub, SUFFIX)(void)
271 283 {
272 284 if ((DATA_TYPE)CC_DST == 0)
273   - JUMP_TB(glue(op_jz_sub, SUFFIX), PARAM1, 0, PARAM2);
274   - else
275   - JUMP_TB(glue(op_jz_sub, SUFFIX), PARAM1, 1, PARAM3);
  285 + GOTO_LABEL_PARAM(1);
  286 + FORCE_RET();
  287 +}
  288 +
  289 +void OPPROTO glue(op_jnz_sub, SUFFIX)(void)
  290 +{
  291 + if ((DATA_TYPE)CC_DST != 0)
  292 + GOTO_LABEL_PARAM(1);
276 293 FORCE_RET();
277 294 }
278 295  
279 296 void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
280 297 {
281   - int src1, src2;
  298 + target_long src1, src2;
282 299 src1 = CC_DST + CC_SRC;
283 300 src2 = CC_SRC;
284 301  
285 302 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
286   - JUMP_TB(glue(op_jbe_sub, SUFFIX), PARAM1, 0, PARAM2);
287   - else
288   - JUMP_TB(glue(op_jbe_sub, SUFFIX), PARAM1, 1, PARAM3);
  303 + GOTO_LABEL_PARAM(1);
289 304 FORCE_RET();
290 305 }
291 306  
292 307 void OPPROTO glue(op_js_sub, SUFFIX)(void)
293 308 {
294 309 if (CC_DST & SIGN_MASK)
295   - JUMP_TB(glue(op_js_sub, SUFFIX), PARAM1, 0, PARAM2);
296   - else
297   - JUMP_TB(glue(op_js_sub, SUFFIX), PARAM1, 1, PARAM3);
  310 + GOTO_LABEL_PARAM(1);
298 311 FORCE_RET();
299 312 }
300 313  
301 314 void OPPROTO glue(op_jl_sub, SUFFIX)(void)
302 315 {
303   - int src1, src2;
  316 + target_long src1, src2;
304 317 src1 = CC_DST + CC_SRC;
305 318 src2 = CC_SRC;
306 319  
307 320 if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
308   - JUMP_TB(glue(op_jl_sub, SUFFIX), PARAM1, 0, PARAM2);
309   - else
310   - JUMP_TB(glue(op_jl_sub, SUFFIX), PARAM1, 1, PARAM3);
  321 + GOTO_LABEL_PARAM(1);
311 322 FORCE_RET();
312 323 }
313 324  
314 325 void OPPROTO glue(op_jle_sub, SUFFIX)(void)
315 326 {
316   - int src1, src2;
  327 + target_long src1, src2;
317 328 src1 = CC_DST + CC_SRC;
318 329 src2 = CC_SRC;
319 330  
320 331 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
321   - JUMP_TB(glue(op_jle_sub, SUFFIX), PARAM1, 0, PARAM2);
322   - else
323   - JUMP_TB(glue(op_jle_sub, SUFFIX), PARAM1, 1, PARAM3);
  332 + GOTO_LABEL_PARAM(1);
324 333 FORCE_RET();
325 334 }
326 335  
... ... @@ -330,50 +339,33 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void)
330 339  
331 340 void OPPROTO glue(op_loopnz, SUFFIX)(void)
332 341 {
333   - unsigned int tmp;
334 342 int eflags;
335 343 eflags = cc_table[CC_OP].compute_all();
336   - tmp = (ECX - 1) & DATA_MASK;
337   - ECX = (ECX & ~DATA_MASK) | tmp;
338   - if (tmp != 0 && !(eflags & CC_Z))
339   - EIP = PARAM1;
340   - else
341   - EIP = PARAM2;
  344 + if ((DATA_TYPE)ECX != 0 && !(eflags & CC_Z))
  345 + GOTO_LABEL_PARAM(1);
342 346 FORCE_RET();
343 347 }
344 348  
345 349 void OPPROTO glue(op_loopz, SUFFIX)(void)
346 350 {
347   - unsigned int tmp;
348 351 int eflags;
349 352 eflags = cc_table[CC_OP].compute_all();
350   - tmp = (ECX - 1) & DATA_MASK;
351   - ECX = (ECX & ~DATA_MASK) | tmp;
352   - if (tmp != 0 && (eflags & CC_Z))
353   - EIP = PARAM1;
354   - else
355   - EIP = PARAM2;
  353 + if ((DATA_TYPE)ECX != 0 && (eflags & CC_Z))
  354 + GOTO_LABEL_PARAM(1);
356 355 FORCE_RET();
357 356 }
358 357  
359   -void OPPROTO glue(op_loop, SUFFIX)(void)
  358 +void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
360 359 {
361   - unsigned int tmp;
362   - tmp = (ECX - 1) & DATA_MASK;
363   - ECX = (ECX & ~DATA_MASK) | tmp;
364   - if (tmp != 0)
365   - EIP = PARAM1;
366   - else
367   - EIP = PARAM2;
  360 + if ((DATA_TYPE)ECX == 0)
  361 + GOTO_LABEL_PARAM(1);
368 362 FORCE_RET();
369 363 }
370 364  
371   -void OPPROTO glue(op_jecxz, SUFFIX)(void)
  365 +void OPPROTO glue(op_jnz_ecx, SUFFIX)(void)
372 366 {
373   - if ((DATA_TYPE)ECX == 0)
374   - EIP = PARAM1;
375   - else
376   - EIP = PARAM2;
  367 + if ((DATA_TYPE)ECX != 0)
  368 + GOTO_LABEL_PARAM(1);
377 369 FORCE_RET();
378 370 }
379 371  
... ... @@ -383,7 +375,7 @@ void OPPROTO glue(op_jecxz, SUFFIX)(void)
383 375  
384 376 void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
385 377 {
386   - int src1, src2;
  378 + target_long src1, src2;
387 379 src1 = CC_DST + CC_SRC;
388 380 src2 = CC_SRC;
389 381  
... ... @@ -397,7 +389,7 @@ void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
397 389  
398 390 void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
399 391 {
400   - int src1, src2;
  392 + target_long src1, src2;
401 393 src1 = CC_DST + CC_SRC;
402 394 src2 = CC_SRC;
403 395  
... ... @@ -411,7 +403,7 @@ void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
411 403  
412 404 void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
413 405 {
414   - int src1, src2;
  406 + target_long src1, src2;
415 407 src1 = CC_DST + CC_SRC;
416 408 src2 = CC_SRC;
417 409  
... ... @@ -420,7 +412,7 @@ void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
420 412  
421 413 void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
422 414 {
423   - int src1, src2;
  415 + target_long src1, src2;
424 416 src1 = CC_DST + CC_SRC;
425 417 src2 = CC_SRC;
426 418  
... ... @@ -432,7 +424,7 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
432 424 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
433 425 {
434 426 int count;
435   - count = T1 & 0x1f;
  427 + count = T1 & SHIFT1_MASK;
436 428 T0 = T0 << count;
437 429 FORCE_RET();
438 430 }
... ... @@ -440,7 +432,7 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
440 432 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
441 433 {
442 434 int count;
443   - count = T1 & 0x1f;
  435 + count = T1 & SHIFT1_MASK;
444 436 T0 &= DATA_MASK;
445 437 T0 = T0 >> count;
446 438 FORCE_RET();
... ... @@ -448,8 +440,10 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
448 440  
449 441 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
450 442 {
451   - int count, src;
452   - count = T1 & 0x1f;
  443 + int count;
  444 + target_long src;
  445 +
  446 + count = T1 & SHIFT1_MASK;
453 447 src = (DATA_STYPE)T0;
454 448 T0 = src >> count;
455 449 FORCE_RET();
... ... @@ -484,7 +478,7 @@ void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
484 478 int count;
485 479 count = T1 & SHIFT_MASK;
486 480 T1 = T0 >> count;
487   - T0 |= (1 << count);
  481 + T0 |= (((target_long)1) << count);
488 482 }
489 483  
490 484 void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
... ... @@ -492,7 +486,7 @@ void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
492 486 int count;
493 487 count = T1 & SHIFT_MASK;
494 488 T1 = T0 >> count;
495   - T0 &= ~(1 << count);
  489 + T0 &= ~(((target_long)1) << count);
496 490 }
497 491  
498 492 void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
... ... @@ -500,12 +494,19 @@ void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
500 494 int count;
501 495 count = T1 & SHIFT_MASK;
502 496 T1 = T0 >> count;
503   - T0 ^= (1 << count);
  497 + T0 ^= (((target_long)1) << count);
  498 +}
  499 +
  500 +void OPPROTO glue(glue(op_add_bit, SUFFIX), _A0_T1)(void)
  501 +{
  502 + A0 += ((DATA_STYPE)T1 >> (3 + SHIFT)) << SHIFT;
504 503 }
505 504  
506 505 void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
507 506 {
508   - int res, count;
  507 + int count;
  508 + target_long res;
  509 +
509 510 res = T0 & DATA_MASK;
510 511 if (res != 0) {
511 512 count = 0;
... ... @@ -523,7 +524,9 @@ void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
523 524  
524 525 void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
525 526 {
526   - int res, count;
  527 + int count;
  528 + target_long res;
  529 +
527 530 res = T0 & DATA_MASK;
528 531 if (res != 0) {
529 532 count = DATA_BITS - 1;
... ... @@ -555,70 +558,8 @@ void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
555 558 T0 = DF << SHIFT;
556 559 }
557 560  
558   -void OPPROTO glue(op_string_jz_sub, SUFFIX)(void)
559   -{
560   - if ((DATA_TYPE)CC_DST == 0)
561   - JUMP_TB2(glue(op_string_jz_sub, SUFFIX), PARAM1, 3);
562   - FORCE_RET();
563   -}
564   -
565   -void OPPROTO glue(op_string_jnz_sub, SUFFIX)(void)
566   -{
567   - if ((DATA_TYPE)CC_DST != 0)
568   - JUMP_TB2(glue(op_string_jnz_sub, SUFFIX), PARAM1, 3);
569   - FORCE_RET();
570   -}
571   -
572   -void OPPROTO glue(glue(op_string_jz_sub, SUFFIX), _im)(void)
573   -{
574   - if ((DATA_TYPE)CC_DST == 0) {
575   - EIP = PARAM1;
576   - if (env->eflags & TF_MASK) {
577   - raise_exception(EXCP01_SSTP);
578   - }
579   - T0 = 0;
580   - EXIT_TB();
581   - }
582   - FORCE_RET();
583   -}
584   -
585   -void OPPROTO glue(glue(op_string_jnz_sub, SUFFIX), _im)(void)
586   -{
587   - if ((DATA_TYPE)CC_DST != 0) {
588   - EIP = PARAM1;
589   - if (env->eflags & TF_MASK) {
590   - raise_exception(EXCP01_SSTP);
591   - }
592   - T0 = 0;
593   - EXIT_TB();
594   - }
595   - FORCE_RET();
596   -}
597   -
598   -#if DATA_BITS >= 16
599   -void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
600   -{
601   - if ((DATA_TYPE)ECX == 0)
602   - JUMP_TB(glue(op_jz_ecx, SUFFIX), PARAM1, 1, PARAM2);
603   - FORCE_RET();
604   -}
605   -
606   -void OPPROTO glue(glue(op_jz_ecx, SUFFIX), _im)(void)
607   -{
608   - if ((DATA_TYPE)ECX == 0) {
609   - EIP = PARAM1;
610   - if (env->eflags & TF_MASK) {
611   - raise_exception(EXCP01_SSTP);
612   - }
613   - T0 = 0;
614   - EXIT_TB();
615   - }
616   - FORCE_RET();
617   -}
618   -#endif
619   -
620 561 /* port I/O */
621   -
  562 +#if DATA_BITS <= 32
622 563 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
623 564 {
624 565 glue(cpu_out, SUFFIX)(env, T0, T1 & DATA_MASK);
... ... @@ -648,9 +589,11 @@ void OPPROTO glue(glue(op_check_io, SUFFIX), _DX)(void)
648 589 {
649 590 glue(glue(check_io, SUFFIX), _DX)();
650 591 }
  592 +#endif
651 593  
652 594 #undef DATA_BITS
653 595 #undef SHIFT_MASK
  596 +#undef SHIFT1_MASK
654 597 #undef SIGN_MASK
655 598 #undef DATA_TYPE
656 599 #undef DATA_STYPE
... ...
target-i386/ops_template_mem.h
... ... @@ -28,6 +28,8 @@
28 28 #define MEM_SUFFIX w_raw
29 29 #elif DATA_BITS == 32
30 30 #define MEM_SUFFIX l_raw
  31 +#elif DATA_BITS == 64
  32 +#define MEM_SUFFIX q_raw
31 33 #endif
32 34  
33 35 #elif MEM_WRITE == 1
... ... @@ -38,6 +40,8 @@
38 40 #define MEM_SUFFIX w_kernel
39 41 #elif DATA_BITS == 32
40 42 #define MEM_SUFFIX l_kernel
  43 +#elif DATA_BITS == 64
  44 +#define MEM_SUFFIX q_kernel
41 45 #endif
42 46  
43 47 #elif MEM_WRITE == 2
... ... @@ -48,6 +52,8 @@
48 52 #define MEM_SUFFIX w_user
49 53 #elif DATA_BITS == 32
50 54 #define MEM_SUFFIX l_user
  55 +#elif DATA_BITS == 64
  56 +#define MEM_SUFFIX q_user
51 57 #endif
52 58  
53 59 #else
... ... @@ -64,14 +70,16 @@
64 70  
65 71 void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
66 72 {
67   - int count, src;
  73 + int count;
  74 + target_long src;
  75 +
68 76 count = T1 & SHIFT_MASK;
69 77 if (count) {
70 78 src = T0;
71 79 T0 &= DATA_MASK;
72 80 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
73 81 #ifdef MEM_WRITE
74   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  82 + glue(st, MEM_SUFFIX)(A0, T0);
75 83 #else
76 84 /* gcc 3.2 workaround. This is really a bug in gcc. */
77 85 asm volatile("" : : "r" (T0));
... ... @@ -86,14 +94,16 @@ void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
86 94  
87 95 void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
88 96 {
89   - int count, src;
  97 + int count;
  98 + target_long src;
  99 +
90 100 count = T1 & SHIFT_MASK;
91 101 if (count) {
92 102 src = T0;
93 103 T0 &= DATA_MASK;
94 104 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
95 105 #ifdef MEM_WRITE
96   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  106 + glue(st, MEM_SUFFIX)(A0, T0);
97 107 #else
98 108 /* gcc 3.2 workaround. This is really a bug in gcc. */
99 109 asm volatile("" : : "r" (T0));
... ... @@ -114,7 +124,7 @@ void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
114 124 T0 &= DATA_MASK;
115 125 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
116 126 #ifdef MEM_WRITE
117   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  127 + glue(st, MEM_SUFFIX)(A0, T0);
118 128 #endif
119 129 }
120 130 FORCE_RET();
... ... @@ -128,7 +138,7 @@ void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
128 138 T0 &= DATA_MASK;
129 139 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
130 140 #ifdef MEM_WRITE
131   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  141 + glue(st, MEM_SUFFIX)(A0, T0);
132 142 #endif
133 143 }
134 144 FORCE_RET();
... ... @@ -136,10 +146,11 @@ void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
136 146  
137 147 void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
138 148 {
139   - int count, res, eflags;
140   - unsigned int src;
  149 + int count, eflags;
  150 + target_ulong src;
  151 + target_long res;
141 152  
142   - count = T1 & 0x1f;
  153 + count = T1 & SHIFT1_MASK;
143 154 #if DATA_BITS == 16
144 155 count = rclw_table[count];
145 156 #elif DATA_BITS == 8
... ... @@ -154,7 +165,7 @@ void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
154 165 res |= T0 >> (DATA_BITS + 1 - count);
155 166 T0 = res;
156 167 #ifdef MEM_WRITE
157   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  168 + glue(st, MEM_SUFFIX)(A0, T0);
158 169 #endif
159 170 CC_SRC = (eflags & ~(CC_C | CC_O)) |
160 171 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
... ... @@ -166,10 +177,11 @@ void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
166 177  
167 178 void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
168 179 {
169   - int count, res, eflags;
170   - unsigned int src;
  180 + int count, eflags;
  181 + target_ulong src;
  182 + target_long res;
171 183  
172   - count = T1 & 0x1f;
  184 + count = T1 & SHIFT1_MASK;
173 185 #if DATA_BITS == 16
174 186 count = rclw_table[count];
175 187 #elif DATA_BITS == 8
... ... @@ -184,7 +196,7 @@ void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
184 196 res |= T0 << (DATA_BITS + 1 - count);
185 197 T0 = res;
186 198 #ifdef MEM_WRITE
187   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  199 + glue(st, MEM_SUFFIX)(A0, T0);
188 200 #endif
189 201 CC_SRC = (eflags & ~(CC_C | CC_O)) |
190 202 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
... ... @@ -196,13 +208,15 @@ void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
196 208  
197 209 void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
198 210 {
199   - int count, src;
200   - count = T1 & 0x1f;
  211 + int count;
  212 + target_long src;
  213 +
  214 + count = T1 & SHIFT1_MASK;
201 215 if (count) {
202 216 src = (DATA_TYPE)T0 << (count - 1);
203 217 T0 = T0 << count;
204 218 #ifdef MEM_WRITE
205   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  219 + glue(st, MEM_SUFFIX)(A0, T0);
206 220 #endif
207 221 CC_SRC = src;
208 222 CC_DST = T0;
... ... @@ -213,14 +227,16 @@ void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
213 227  
214 228 void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
215 229 {
216   - int count, src;
217   - count = T1 & 0x1f;
  230 + int count;
  231 + target_long src;
  232 +
  233 + count = T1 & SHIFT1_MASK;
218 234 if (count) {
219 235 T0 &= DATA_MASK;
220 236 src = T0 >> (count - 1);
221 237 T0 = T0 >> count;
222 238 #ifdef MEM_WRITE
223   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  239 + glue(st, MEM_SUFFIX)(A0, T0);
224 240 #endif
225 241 CC_SRC = src;
226 242 CC_DST = T0;
... ... @@ -231,14 +247,16 @@ void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
231 247  
232 248 void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
233 249 {
234   - int count, src;
235   - count = T1 & 0x1f;
  250 + int count;
  251 + target_long src;
  252 +
  253 + count = T1 & SHIFT1_MASK;
236 254 if (count) {
237 255 src = (DATA_STYPE)T0;
238 256 T0 = src >> count;
239 257 src = src >> (count - 1);
240 258 #ifdef MEM_WRITE
241   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  259 + glue(st, MEM_SUFFIX)(A0, T0);
242 260 #endif
243 261 CC_SRC = src;
244 262 CC_DST = T0;
... ... @@ -262,7 +280,7 @@ void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
262 280 res |= T1 << (count - 16);
263 281 T0 = res >> 16;
264 282 #ifdef MEM_WRITE
265   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  283 + glue(st, MEM_SUFFIX)(A0, T0);
266 284 #endif
267 285 CC_SRC = tmp;
268 286 CC_DST = T0;
... ... @@ -282,7 +300,7 @@ void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
282 300 res |= T1 << (count - 16);
283 301 T0 = res >> 16;
284 302 #ifdef MEM_WRITE
285   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  303 + glue(st, MEM_SUFFIX)(A0, T0);
286 304 #endif
287 305 CC_SRC = tmp;
288 306 CC_DST = T0;
... ... @@ -304,7 +322,7 @@ void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
304 322 res |= T1 << (32 - count);
305 323 T0 = res;
306 324 #ifdef MEM_WRITE
307   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  325 + glue(st, MEM_SUFFIX)(A0, T0);
308 326 #endif
309 327 CC_SRC = tmp;
310 328 CC_DST = T0;
... ... @@ -325,7 +343,7 @@ void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
325 343 res |= T1 << (32 - count);
326 344 T0 = res;
327 345 #ifdef MEM_WRITE
328   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  346 + glue(st, MEM_SUFFIX)(A0, T0);
329 347 #endif
330 348 CC_SRC = tmp;
331 349 CC_DST = T0;
... ... @@ -335,17 +353,19 @@ void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
335 353 }
336 354 #endif
337 355  
338   -#if DATA_BITS == 32
  356 +#if DATA_BITS >= 32
339 357 void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
340 358 {
341   - int count, tmp;
  359 + int count;
  360 + target_long tmp;
  361 +
342 362 count = PARAM1;
343 363 T0 &= DATA_MASK;
344 364 T1 &= DATA_MASK;
345 365 tmp = T0 << (count - 1);
346 366 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
347 367 #ifdef MEM_WRITE
348   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  368 + glue(st, MEM_SUFFIX)(A0, T0);
349 369 #endif
350 370 CC_SRC = tmp;
351 371 CC_DST = T0;
... ... @@ -353,15 +373,17 @@ void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
353 373  
354 374 void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
355 375 {
356   - int count, tmp;
357   - count = ECX & 0x1f;
  376 + int count;
  377 + target_long tmp;
  378 +
  379 + count = ECX & SHIFT1_MASK;
358 380 if (count) {
359 381 T0 &= DATA_MASK;
360 382 T1 &= DATA_MASK;
361 383 tmp = T0 << (count - 1);
362 384 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
363 385 #ifdef MEM_WRITE
364   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  386 + glue(st, MEM_SUFFIX)(A0, T0);
365 387 #endif
366 388 CC_SRC = tmp;
367 389 CC_DST = T0;
... ... @@ -372,14 +394,16 @@ void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
372 394  
373 395 void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
374 396 {
375   - int count, tmp;
  397 + int count;
  398 + target_long tmp;
  399 +
376 400 count = PARAM1;
377 401 T0 &= DATA_MASK;
378 402 T1 &= DATA_MASK;
379 403 tmp = T0 >> (count - 1);
380 404 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
381 405 #ifdef MEM_WRITE
382   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  406 + glue(st, MEM_SUFFIX)(A0, T0);
383 407 #endif
384 408 CC_SRC = tmp;
385 409 CC_DST = T0;
... ... @@ -388,15 +412,17 @@ void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
388 412  
389 413 void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
390 414 {
391   - int count, tmp;
392   - count = ECX & 0x1f;
  415 + int count;
  416 + target_long tmp;
  417 +
  418 + count = ECX & SHIFT1_MASK;
393 419 if (count) {
394 420 T0 &= DATA_MASK;
395 421 T1 &= DATA_MASK;
396 422 tmp = T0 >> (count - 1);
397 423 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
398 424 #ifdef MEM_WRITE
399   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  425 + glue(st, MEM_SUFFIX)(A0, T0);
400 426 #endif
401 427 CC_SRC = tmp;
402 428 CC_DST = T0;
... ... @@ -414,11 +440,11 @@ void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
414 440 cf = cc_table[CC_OP].compute_c();
415 441 T0 = T0 + T1 + cf;
416 442 #ifdef MEM_WRITE
417   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  443 + glue(st, MEM_SUFFIX)(A0, T0);
418 444 #endif
419 445 CC_SRC = T1;
420 446 CC_DST = T0;
421   - CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
  447 + CC_OP = CC_OP_ADDB + SHIFT + cf * 4;
422 448 }
423 449  
424 450 void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
... ... @@ -427,23 +453,23 @@ void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
427 453 cf = cc_table[CC_OP].compute_c();
428 454 T0 = T0 - T1 - cf;
429 455 #ifdef MEM_WRITE
430   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  456 + glue(st, MEM_SUFFIX)(A0, T0);
431 457 #endif
432 458 CC_SRC = T1;
433 459 CC_DST = T0;
434   - CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
  460 + CC_OP = CC_OP_SUBB + SHIFT + cf * 4;
435 461 }
436 462  
437 463 void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
438 464 {
439   - unsigned int src, dst;
  465 + target_ulong src, dst;
440 466  
441 467 src = T0;
442 468 dst = EAX - T0;
443 469 if ((DATA_TYPE)dst == 0) {
444 470 T0 = T1;
445 471 #ifdef MEM_WRITE
446   - glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
  472 + glue(st, MEM_SUFFIX)(A0, T0);
447 473 #endif
448 474 } else {
449 475 EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
... ...
target-i386/translate-copy.c
... ... @@ -57,7 +57,7 @@ typedef struct DisasContext {
57 57 int override; /* -1 if no override */
58 58 int prefix;
59 59 int aflag, dflag;
60   - uint8_t *pc; /* pc = eip + cs_base */
  60 + target_ulong pc; /* pc = eip + cs_base */
61 61 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
62 62 static state change (stop translation) */
63 63 /* code output */
... ... @@ -65,7 +65,7 @@ typedef struct DisasContext {
65 65 uint8_t *gen_code_start;
66 66  
67 67 /* current block context */
68   - uint8_t *cs_base; /* base of CS segment */
  68 + target_ulong cs_base; /* base of CS segment */
69 69 int pe; /* protected mode */
70 70 int code32; /* 32 bit code segment */
71 71 int f_st; /* currently unused */
... ... @@ -277,7 +277,7 @@ static inline uint32_t insn_get(DisasContext *s, int ot)
277 277 be stopped. */
278 278 static int disas_insn(DisasContext *s)
279 279 {
280   - uint8_t *pc_start, *pc_tmp, *pc_start_insn;
  280 + target_ulong pc_start, pc_tmp, pc_start_insn;
281 281 int b, prefixes, aflag, dflag, next_eip, val;
282 282 int ot;
283 283 int modrm, mod, op, rm;
... ... @@ -789,6 +789,8 @@ static int disas_insn(DisasContext *s)
789 789 break;
790 790 case 0x1e: /* fcomi */
791 791 break;
  792 + case 0x28: /* ffree sti */
  793 + break;
792 794 case 0x2a: /* fst sti */
793 795 break;
794 796 case 0x2b: /* fstp sti */
... ... @@ -1176,9 +1178,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
1176 1178 uint8_t *tc_ptr)
1177 1179 {
1178 1180 DisasContext dc1, *dc = &dc1;
1179   - uint8_t *pc_insn, *pc_start, *gen_code_end;
  1181 + target_ulong pc_insn, pc_start, cs_base;
  1182 + uint8_t *gen_code_end;
1180 1183 int flags, ret;
1181   - uint8_t *cs_base;
1182 1184  
1183 1185 if (env->nb_breakpoints > 0 ||
1184 1186 env->singlestep_enabled)
... ... @@ -1197,8 +1199,8 @@ static inline int gen_intermediate_code_internal(CPUState *env,
1197 1199 dc->gen_code_start = gen_code_ptr;
1198 1200  
1199 1201 /* generate intermediate code */
1200   - pc_start = (uint8_t *)tb->pc;
1201   - cs_base = (uint8_t *)tb->cs_base;
  1202 + pc_start = tb->pc;
  1203 + cs_base = tb->cs_base;
1202 1204 dc->pc = pc_start;
1203 1205 dc->cs_base = cs_base;
1204 1206 dc->pe = (flags >> HF_PE_SHIFT) & 1;
... ... @@ -1249,7 +1251,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
1249 1251 fprintf(logfile, "IN: COPY: %s fpu=%d\n",
1250 1252 lookup_symbol(pc_start),
1251 1253 tb->cflags & CF_TB_FP_USED ? 1 : 0);
1252   - disas(logfile, pc_start, dc->pc - pc_start, 0, !dc->code32);
  1254 + target_disas(logfile, pc_start, dc->pc - pc_start, !dc->code32);
1253 1255 fprintf(logfile, "\n");
1254 1256 }
1255 1257 #endif
... ...
target-i386/translate.c
... ... @@ -39,18 +39,45 @@ static uint32_t *gen_opparam_ptr;
39 39 #define PREFIX_DATA 0x08
40 40 #define PREFIX_ADR 0x10
41 41  
  42 +#ifdef TARGET_X86_64
  43 +#define X86_64_ONLY(x) x
  44 +#define X86_64_DEF(x...) x
  45 +#define CODE64(s) ((s)->code64)
  46 +#define REX_X(s) ((s)->rex_x)
  47 +#define REX_B(s) ((s)->rex_b)
  48 +/* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
  49 +#if 1
  50 +#define BUGGY_64(x) NULL
  51 +#endif
  52 +#else
  53 +#define X86_64_ONLY(x) NULL
  54 +#define X86_64_DEF(x...)
  55 +#define CODE64(s) 0
  56 +#define REX_X(s) 0
  57 +#define REX_B(s) 0
  58 +#endif
  59 +
  60 +#ifdef TARGET_X86_64
  61 +static int x86_64_hregs;
  62 +#endif
  63 +
42 64 typedef struct DisasContext {
43 65 /* current insn context */
44 66 int override; /* -1 if no override */
45 67 int prefix;
46 68 int aflag, dflag;
47   - uint8_t *pc; /* pc = eip + cs_base */
  69 + target_ulong pc; /* pc = eip + cs_base */
48 70 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
49 71 static state change (stop translation) */
50 72 /* current block context */
51   - uint8_t *cs_base; /* base of CS segment */
  73 + target_ulong cs_base; /* base of CS segment */
52 74 int pe; /* protected mode */
53 75 int code32; /* 32 bit code segment */
  76 +#ifdef TARGET_X86_64
  77 + int lma; /* long mode active */
  78 + int code64; /* 64 bit code segment */
  79 + int rex_x, rex_b;
  80 +#endif
54 81 int ss32; /* 32 bit stack segment */
55 82 int cc_op; /* current CC operation */
56 83 int addseg; /* non zero if either DS/ES/SS have a non zero base */
... ... @@ -65,10 +92,13 @@ typedef struct DisasContext {
65 92 int flags; /* all execution flags */
66 93 struct TranslationBlock *tb;
67 94 int popl_esp_hack; /* for correct popl with esp base handling */
  95 + int rip_offset; /* only used in x86_64, but left for simplicity */
  96 + int cpuid_features;
68 97 } DisasContext;
69 98  
70 99 static void gen_eob(DisasContext *s);
71   -static void gen_jmp(DisasContext *s, unsigned int eip);
  100 +static void gen_jmp(DisasContext *s, target_ulong eip);
  101 +static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
72 102  
73 103 /* i386 arith/logic operations */
74 104 enum {
... ... @@ -121,103 +151,182 @@ enum {
121 151 OR_EBP,
122 152 OR_ESI,
123 153 OR_EDI,
124   - OR_TMP0, /* temporary operand register */
  154 +
  155 + OR_TMP0 = 16, /* temporary operand register */
125 156 OR_TMP1,
126 157 OR_A0, /* temporary register used when doing address evaluation */
127   - OR_ZERO, /* fixed zero register */
128   - NB_OREGS,
129 158 };
130 159  
131   -static GenOpFunc *gen_op_mov_reg_T0[3][8] = {
  160 +#ifdef TARGET_X86_64
  161 +
  162 +#define NB_OP_SIZES 4
  163 +
  164 +#define DEF_REGS(prefix, suffix) \
  165 + prefix ## EAX ## suffix,\
  166 + prefix ## ECX ## suffix,\
  167 + prefix ## EDX ## suffix,\
  168 + prefix ## EBX ## suffix,\
  169 + prefix ## ESP ## suffix,\
  170 + prefix ## EBP ## suffix,\
  171 + prefix ## ESI ## suffix,\
  172 + prefix ## EDI ## suffix,\
  173 + prefix ## R8 ## suffix,\
  174 + prefix ## R9 ## suffix,\
  175 + prefix ## R10 ## suffix,\
  176 + prefix ## R11 ## suffix,\
  177 + prefix ## R12 ## suffix,\
  178 + prefix ## R13 ## suffix,\
  179 + prefix ## R14 ## suffix,\
  180 + prefix ## R15 ## suffix,
  181 +
  182 +#define DEF_BREGS(prefixb, prefixh, suffix) \
  183 + \
  184 +static void prefixb ## ESP ## suffix ## _wrapper(void) \
  185 +{ \
  186 + if (x86_64_hregs) \
  187 + prefixb ## ESP ## suffix (); \
  188 + else \
  189 + prefixh ## EAX ## suffix (); \
  190 +} \
  191 + \
  192 +static void prefixb ## EBP ## suffix ## _wrapper(void) \
  193 +{ \
  194 + if (x86_64_hregs) \
  195 + prefixb ## EBP ## suffix (); \
  196 + else \
  197 + prefixh ## ECX ## suffix (); \
  198 +} \
  199 + \
  200 +static void prefixb ## ESI ## suffix ## _wrapper(void) \
  201 +{ \
  202 + if (x86_64_hregs) \
  203 + prefixb ## ESI ## suffix (); \
  204 + else \
  205 + prefixh ## EDX ## suffix (); \
  206 +} \
  207 + \
  208 +static void prefixb ## EDI ## suffix ## _wrapper(void) \
  209 +{ \
  210 + if (x86_64_hregs) \
  211 + prefixb ## EDI ## suffix (); \
  212 + else \
  213 + prefixh ## EBX ## suffix (); \
  214 +}
  215 +
  216 +DEF_BREGS(gen_op_movb_, gen_op_movh_, _T0)
  217 +DEF_BREGS(gen_op_movb_, gen_op_movh_, _T1)
  218 +DEF_BREGS(gen_op_movl_T0_, gen_op_movh_T0_, )
  219 +DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
  220 +
  221 +#else /* !TARGET_X86_64 */
  222 +
  223 +#define NB_OP_SIZES 3
  224 +
  225 +#define DEF_REGS(prefix, suffix) \
  226 + prefix ## EAX ## suffix,\
  227 + prefix ## ECX ## suffix,\
  228 + prefix ## EDX ## suffix,\
  229 + prefix ## EBX ## suffix,\
  230 + prefix ## ESP ## suffix,\
  231 + prefix ## EBP ## suffix,\
  232 + prefix ## ESI ## suffix,\
  233 + prefix ## EDI ## suffix,
  234 +
  235 +#endif /* !TARGET_X86_64 */
  236 +
  237 +static GenOpFunc *gen_op_mov_reg_T0[NB_OP_SIZES][CPU_NB_REGS] = {
132 238 [OT_BYTE] = {
133 239 gen_op_movb_EAX_T0,
134 240 gen_op_movb_ECX_T0,
135 241 gen_op_movb_EDX_T0,
136 242 gen_op_movb_EBX_T0,
  243 +#ifdef TARGET_X86_64
  244 + gen_op_movb_ESP_T0_wrapper,
  245 + gen_op_movb_EBP_T0_wrapper,
  246 + gen_op_movb_ESI_T0_wrapper,
  247 + gen_op_movb_EDI_T0_wrapper,
  248 + gen_op_movb_R8_T0,
  249 + gen_op_movb_R9_T0,
  250 + gen_op_movb_R10_T0,
  251 + gen_op_movb_R11_T0,
  252 + gen_op_movb_R12_T0,
  253 + gen_op_movb_R13_T0,
  254 + gen_op_movb_R14_T0,
  255 + gen_op_movb_R15_T0,
  256 +#else
137 257 gen_op_movh_EAX_T0,
138 258 gen_op_movh_ECX_T0,
139 259 gen_op_movh_EDX_T0,
140 260 gen_op_movh_EBX_T0,
  261 +#endif
141 262 },
142 263 [OT_WORD] = {
143   - gen_op_movw_EAX_T0,
144   - gen_op_movw_ECX_T0,
145   - gen_op_movw_EDX_T0,
146   - gen_op_movw_EBX_T0,
147   - gen_op_movw_ESP_T0,
148   - gen_op_movw_EBP_T0,
149   - gen_op_movw_ESI_T0,
150   - gen_op_movw_EDI_T0,
  264 + DEF_REGS(gen_op_movw_, _T0)
151 265 },
152 266 [OT_LONG] = {
153   - gen_op_movl_EAX_T0,
154   - gen_op_movl_ECX_T0,
155   - gen_op_movl_EDX_T0,
156   - gen_op_movl_EBX_T0,
157   - gen_op_movl_ESP_T0,
158   - gen_op_movl_EBP_T0,
159   - gen_op_movl_ESI_T0,
160   - gen_op_movl_EDI_T0,
  267 + DEF_REGS(gen_op_movl_, _T0)
161 268 },
  269 +#ifdef TARGET_X86_64
  270 + [OT_QUAD] = {
  271 + DEF_REGS(gen_op_movq_, _T0)
  272 + },
  273 +#endif
162 274 };
163 275  
164   -static GenOpFunc *gen_op_mov_reg_T1[3][8] = {
  276 +static GenOpFunc *gen_op_mov_reg_T1[NB_OP_SIZES][CPU_NB_REGS] = {
165 277 [OT_BYTE] = {
166 278 gen_op_movb_EAX_T1,
167 279 gen_op_movb_ECX_T1,
168 280 gen_op_movb_EDX_T1,
169 281 gen_op_movb_EBX_T1,
  282 +#ifdef TARGET_X86_64
  283 + gen_op_movb_ESP_T1_wrapper,
  284 + gen_op_movb_EBP_T1_wrapper,
  285 + gen_op_movb_ESI_T1_wrapper,
  286 + gen_op_movb_EDI_T1_wrapper,
  287 + gen_op_movb_R8_T1,
  288 + gen_op_movb_R9_T1,
  289 + gen_op_movb_R10_T1,
  290 + gen_op_movb_R11_T1,
  291 + gen_op_movb_R12_T1,
  292 + gen_op_movb_R13_T1,
  293 + gen_op_movb_R14_T1,
  294 + gen_op_movb_R15_T1,
  295 +#else
170 296 gen_op_movh_EAX_T1,
171 297 gen_op_movh_ECX_T1,
172 298 gen_op_movh_EDX_T1,
173 299 gen_op_movh_EBX_T1,
  300 +#endif
174 301 },
175 302 [OT_WORD] = {
176   - gen_op_movw_EAX_T1,
177   - gen_op_movw_ECX_T1,
178   - gen_op_movw_EDX_T1,
179   - gen_op_movw_EBX_T1,
180   - gen_op_movw_ESP_T1,
181   - gen_op_movw_EBP_T1,
182   - gen_op_movw_ESI_T1,
183   - gen_op_movw_EDI_T1,
  303 + DEF_REGS(gen_op_movw_, _T1)
184 304 },
185 305 [OT_LONG] = {
186   - gen_op_movl_EAX_T1,
187   - gen_op_movl_ECX_T1,
188   - gen_op_movl_EDX_T1,
189   - gen_op_movl_EBX_T1,
190   - gen_op_movl_ESP_T1,
191   - gen_op_movl_EBP_T1,
192   - gen_op_movl_ESI_T1,
193   - gen_op_movl_EDI_T1,
  306 + DEF_REGS(gen_op_movl_, _T1)
  307 + },
  308 +#ifdef TARGET_X86_64
  309 + [OT_QUAD] = {
  310 + DEF_REGS(gen_op_movq_, _T1)
194 311 },
  312 +#endif
195 313 };
196 314  
197   -static GenOpFunc *gen_op_mov_reg_A0[2][8] = {
  315 +static GenOpFunc *gen_op_mov_reg_A0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
198 316 [0] = {
199   - gen_op_movw_EAX_A0,
200   - gen_op_movw_ECX_A0,
201   - gen_op_movw_EDX_A0,
202   - gen_op_movw_EBX_A0,
203   - gen_op_movw_ESP_A0,
204   - gen_op_movw_EBP_A0,
205   - gen_op_movw_ESI_A0,
206   - gen_op_movw_EDI_A0,
  317 + DEF_REGS(gen_op_movw_, _A0)
207 318 },
208 319 [1] = {
209   - gen_op_movl_EAX_A0,
210   - gen_op_movl_ECX_A0,
211   - gen_op_movl_EDX_A0,
212   - gen_op_movl_EBX_A0,
213   - gen_op_movl_ESP_A0,
214   - gen_op_movl_EBP_A0,
215   - gen_op_movl_ESI_A0,
216   - gen_op_movl_EDI_A0,
  320 + DEF_REGS(gen_op_movl_, _A0)
  321 + },
  322 +#ifdef TARGET_X86_64
  323 + [2] = {
  324 + DEF_REGS(gen_op_movq_, _A0)
217 325 },
  326 +#endif
218 327 };
219 328  
220   -static GenOpFunc *gen_op_mov_TN_reg[3][2][8] =
  329 +static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] =
221 330 {
222 331 [OT_BYTE] = {
223 332 {
... ... @@ -225,144 +334,133 @@ static GenOpFunc *gen_op_mov_TN_reg[3][2][8] =
225 334 gen_op_movl_T0_ECX,
226 335 gen_op_movl_T0_EDX,
227 336 gen_op_movl_T0_EBX,
  337 +#ifdef TARGET_X86_64
  338 + gen_op_movl_T0_ESP_wrapper,
  339 + gen_op_movl_T0_EBP_wrapper,
  340 + gen_op_movl_T0_ESI_wrapper,
  341 + gen_op_movl_T0_EDI_wrapper,
  342 + gen_op_movl_T0_R8,
  343 + gen_op_movl_T0_R9,
  344 + gen_op_movl_T0_R10,
  345 + gen_op_movl_T0_R11,
  346 + gen_op_movl_T0_R12,
  347 + gen_op_movl_T0_R13,
  348 + gen_op_movl_T0_R14,
  349 + gen_op_movl_T0_R15,
  350 +#else
228 351 gen_op_movh_T0_EAX,
229 352 gen_op_movh_T0_ECX,
230 353 gen_op_movh_T0_EDX,
231 354 gen_op_movh_T0_EBX,
  355 +#endif
232 356 },
233 357 {
234 358 gen_op_movl_T1_EAX,
235 359 gen_op_movl_T1_ECX,
236 360 gen_op_movl_T1_EDX,
237 361 gen_op_movl_T1_EBX,
  362 +#ifdef TARGET_X86_64
  363 + gen_op_movl_T1_ESP_wrapper,
  364 + gen_op_movl_T1_EBP_wrapper,
  365 + gen_op_movl_T1_ESI_wrapper,
  366 + gen_op_movl_T1_EDI_wrapper,
  367 + gen_op_movl_T1_R8,
  368 + gen_op_movl_T1_R9,
  369 + gen_op_movl_T1_R10,
  370 + gen_op_movl_T1_R11,
  371 + gen_op_movl_T1_R12,
  372 + gen_op_movl_T1_R13,
  373 + gen_op_movl_T1_R14,
  374 + gen_op_movl_T1_R15,
  375 +#else
238 376 gen_op_movh_T1_EAX,
239 377 gen_op_movh_T1_ECX,
240 378 gen_op_movh_T1_EDX,
241 379 gen_op_movh_T1_EBX,
  380 +#endif
242 381 },
243 382 },
244 383 [OT_WORD] = {
245 384 {
246   - gen_op_movl_T0_EAX,
247   - gen_op_movl_T0_ECX,
248   - gen_op_movl_T0_EDX,
249   - gen_op_movl_T0_EBX,
250   - gen_op_movl_T0_ESP,
251   - gen_op_movl_T0_EBP,
252   - gen_op_movl_T0_ESI,
253   - gen_op_movl_T0_EDI,
  385 + DEF_REGS(gen_op_movl_T0_, )
254 386 },
255 387 {
256   - gen_op_movl_T1_EAX,
257   - gen_op_movl_T1_ECX,
258   - gen_op_movl_T1_EDX,
259   - gen_op_movl_T1_EBX,
260   - gen_op_movl_T1_ESP,
261   - gen_op_movl_T1_EBP,
262   - gen_op_movl_T1_ESI,
263   - gen_op_movl_T1_EDI,
  388 + DEF_REGS(gen_op_movl_T1_, )
264 389 },
265 390 },
266 391 [OT_LONG] = {
267 392 {
268   - gen_op_movl_T0_EAX,
269   - gen_op_movl_T0_ECX,
270   - gen_op_movl_T0_EDX,
271   - gen_op_movl_T0_EBX,
272   - gen_op_movl_T0_ESP,
273   - gen_op_movl_T0_EBP,
274   - gen_op_movl_T0_ESI,
275   - gen_op_movl_T0_EDI,
  393 + DEF_REGS(gen_op_movl_T0_, )
276 394 },
277 395 {
278   - gen_op_movl_T1_EAX,
279   - gen_op_movl_T1_ECX,
280   - gen_op_movl_T1_EDX,
281   - gen_op_movl_T1_EBX,
282   - gen_op_movl_T1_ESP,
283   - gen_op_movl_T1_EBP,
284   - gen_op_movl_T1_ESI,
285   - gen_op_movl_T1_EDI,
  396 + DEF_REGS(gen_op_movl_T1_, )
286 397 },
287 398 },
  399 +#ifdef TARGET_X86_64
  400 + [OT_QUAD] = {
  401 + {
  402 + DEF_REGS(gen_op_movl_T0_, )
  403 + },
  404 + {
  405 + DEF_REGS(gen_op_movl_T1_, )
  406 + },
  407 + },
  408 +#endif
288 409 };
289 410  
290   -static GenOpFunc *gen_op_movl_A0_reg[8] = {
291   - gen_op_movl_A0_EAX,
292   - gen_op_movl_A0_ECX,
293   - gen_op_movl_A0_EDX,
294   - gen_op_movl_A0_EBX,
295   - gen_op_movl_A0_ESP,
296   - gen_op_movl_A0_EBP,
297   - gen_op_movl_A0_ESI,
298   - gen_op_movl_A0_EDI,
  411 +static GenOpFunc *gen_op_movl_A0_reg[CPU_NB_REGS] = {
  412 + DEF_REGS(gen_op_movl_A0_, )
299 413 };
300 414  
301   -static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
  415 +static GenOpFunc *gen_op_addl_A0_reg_sN[4][CPU_NB_REGS] = {
302 416 [0] = {
303   - gen_op_addl_A0_EAX,
304   - gen_op_addl_A0_ECX,
305   - gen_op_addl_A0_EDX,
306   - gen_op_addl_A0_EBX,
307   - gen_op_addl_A0_ESP,
308   - gen_op_addl_A0_EBP,
309   - gen_op_addl_A0_ESI,
310   - gen_op_addl_A0_EDI,
  417 + DEF_REGS(gen_op_addl_A0_, )
311 418 },
312 419 [1] = {
313   - gen_op_addl_A0_EAX_s1,
314   - gen_op_addl_A0_ECX_s1,
315   - gen_op_addl_A0_EDX_s1,
316   - gen_op_addl_A0_EBX_s1,
317   - gen_op_addl_A0_ESP_s1,
318   - gen_op_addl_A0_EBP_s1,
319   - gen_op_addl_A0_ESI_s1,
320   - gen_op_addl_A0_EDI_s1,
  420 + DEF_REGS(gen_op_addl_A0_, _s1)
321 421 },
322 422 [2] = {
323   - gen_op_addl_A0_EAX_s2,
324   - gen_op_addl_A0_ECX_s2,
325   - gen_op_addl_A0_EDX_s2,
326   - gen_op_addl_A0_EBX_s2,
327   - gen_op_addl_A0_ESP_s2,
328   - gen_op_addl_A0_EBP_s2,
329   - gen_op_addl_A0_ESI_s2,
330   - gen_op_addl_A0_EDI_s2,
  423 + DEF_REGS(gen_op_addl_A0_, _s2)
331 424 },
332 425 [3] = {
333   - gen_op_addl_A0_EAX_s3,
334   - gen_op_addl_A0_ECX_s3,
335   - gen_op_addl_A0_EDX_s3,
336   - gen_op_addl_A0_EBX_s3,
337   - gen_op_addl_A0_ESP_s3,
338   - gen_op_addl_A0_EBP_s3,
339   - gen_op_addl_A0_ESI_s3,
340   - gen_op_addl_A0_EDI_s3,
  426 + DEF_REGS(gen_op_addl_A0_, _s3)
341 427 },
342 428 };
343 429  
344   -static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = {
  430 +#ifdef TARGET_X86_64
  431 +static GenOpFunc *gen_op_movq_A0_reg[CPU_NB_REGS] = {
  432 + DEF_REGS(gen_op_movq_A0_, )
  433 +};
  434 +
  435 +static GenOpFunc *gen_op_addq_A0_reg_sN[4][CPU_NB_REGS] = {
345 436 [0] = {
346   - gen_op_cmovw_EAX_T1_T0,
347   - gen_op_cmovw_ECX_T1_T0,
348   - gen_op_cmovw_EDX_T1_T0,
349   - gen_op_cmovw_EBX_T1_T0,
350   - gen_op_cmovw_ESP_T1_T0,
351   - gen_op_cmovw_EBP_T1_T0,
352   - gen_op_cmovw_ESI_T1_T0,
353   - gen_op_cmovw_EDI_T1_T0,
  437 + DEF_REGS(gen_op_addq_A0_, )
354 438 },
355 439 [1] = {
356   - gen_op_cmovl_EAX_T1_T0,
357   - gen_op_cmovl_ECX_T1_T0,
358   - gen_op_cmovl_EDX_T1_T0,
359   - gen_op_cmovl_EBX_T1_T0,
360   - gen_op_cmovl_ESP_T1_T0,
361   - gen_op_cmovl_EBP_T1_T0,
362   - gen_op_cmovl_ESI_T1_T0,
363   - gen_op_cmovl_EDI_T1_T0,
  440 + DEF_REGS(gen_op_addq_A0_, _s1)
  441 + },
  442 + [2] = {
  443 + DEF_REGS(gen_op_addq_A0_, _s2)
  444 + },
  445 + [3] = {
  446 + DEF_REGS(gen_op_addq_A0_, _s3)
364 447 },
365 448 };
  449 +#endif
  450 +
  451 +static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
  452 + [0] = {
  453 + DEF_REGS(gen_op_cmovw_, _T1_T0)
  454 + },
  455 + [1] = {
  456 + DEF_REGS(gen_op_cmovl_, _T1_T0)
  457 + },
  458 +#ifdef TARGET_X86_64
  459 + [2] = {
  460 + DEF_REGS(gen_op_cmovq_, _T1_T0)
  461 + },
  462 +#endif
  463 +};
366 464  
367 465 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
368 466 NULL,
... ... @@ -387,13 +485,17 @@ static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
387 485 {\
388 486 gen_op_adcl ## SUFFIX ## _T0_T1_cc,\
389 487 gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\
  488 + },\
  489 + {\
  490 + X86_64_ONLY(gen_op_adcq ## SUFFIX ## _T0_T1_cc),\
  491 + X86_64_ONLY(gen_op_sbbq ## SUFFIX ## _T0_T1_cc),\
390 492 },
391 493  
392   -static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
  494 +static GenOpFunc *gen_op_arithc_T0_T1_cc[4][2] = {
393 495 DEF_ARITHC( )
394 496 };
395 497  
396   -static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[9][2] = {
  498 +static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3 * 4][2] = {
397 499 DEF_ARITHC(_raw)
398 500 #ifndef CONFIG_USER_ONLY
399 501 DEF_ARITHC(_kernel)
... ... @@ -415,14 +517,14 @@ static const int cc_op_arithb[8] = {
415 517 #define DEF_CMPXCHG(SUFFIX)\
416 518 gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\
417 519 gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\
418   - gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,
419   -
  520 + gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,\
  521 + X86_64_ONLY(gen_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc),
420 522  
421   -static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = {
  523 +static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[4] = {
422 524 DEF_CMPXCHG( )
423 525 };
424 526  
425   -static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[9] = {
  527 +static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3 * 4] = {
426 528 DEF_CMPXCHG(_raw)
427 529 #ifndef CONFIG_USER_ONLY
428 530 DEF_CMPXCHG(_kernel)
... ... @@ -460,13 +562,23 @@ static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[9] = {
460 562 gen_op_shrl ## SUFFIX ## _T0_T1_cc,\
461 563 gen_op_shll ## SUFFIX ## _T0_T1_cc,\
462 564 gen_op_sarl ## SUFFIX ## _T0_T1_cc,\
  565 + },\
  566 + {\
  567 + X86_64_ONLY(gen_op_rolq ## SUFFIX ## _T0_T1_cc),\
  568 + X86_64_ONLY(gen_op_rorq ## SUFFIX ## _T0_T1_cc),\
  569 + X86_64_ONLY(gen_op_rclq ## SUFFIX ## _T0_T1_cc),\
  570 + X86_64_ONLY(gen_op_rcrq ## SUFFIX ## _T0_T1_cc),\
  571 + X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
  572 + X86_64_ONLY(gen_op_shrq ## SUFFIX ## _T0_T1_cc),\
  573 + X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
  574 + X86_64_ONLY(gen_op_sarq ## SUFFIX ## _T0_T1_cc),\
463 575 },
464 576  
465   -static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
  577 +static GenOpFunc *gen_op_shift_T0_T1_cc[4][8] = {
466 578 DEF_SHIFT( )
467 579 };
468 580  
469   -static GenOpFunc *gen_op_shift_mem_T0_T1_cc[9][8] = {
  581 +static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {
470 582 DEF_SHIFT(_raw)
471 583 #ifndef CONFIG_USER_ONLY
472 584 DEF_SHIFT(_kernel)
... ... @@ -486,18 +598,19 @@ static GenOpFunc *gen_op_shift_mem_T0_T1_cc[9][8] = {
486 598 {\
487 599 gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
488 600 gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
  601 + },\
  602 + {\
489 603 },
490 604  
491   -
492   -static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[3][2] = {
  605 +static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = {
493 606 DEF_SHIFTD(, im)
494 607 };
495 608  
496   -static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[3][2] = {
  609 +static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[4][2] = {
497 610 DEF_SHIFTD(, ECX)
498 611 };
499 612  
500   -static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[9][2] = {
  613 +static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[3 * 4][2] = {
501 614 DEF_SHIFTD(_raw, im)
502 615 #ifndef CONFIG_USER_ONLY
503 616 DEF_SHIFTD(_kernel, im)
... ... @@ -505,7 +618,7 @@ static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[9][2] = {
505 618 #endif
506 619 };
507 620  
508   -static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[9][2] = {
  621 +static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[3 * 4][2] = {
509 622 DEF_SHIFTD(_raw, ECX)
510 623 #ifndef CONFIG_USER_ONLY
511 624 DEF_SHIFTD(_kernel, ECX)
... ... @@ -513,7 +626,7 @@ static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[9][2] = {
513 626 #endif
514 627 };
515 628  
516   -static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
  629 +static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {
517 630 [0] = {
518 631 gen_op_btw_T0_T1_cc,
519 632 gen_op_btsw_T0_T1_cc,
... ... @@ -526,9 +639,23 @@ static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
526 639 gen_op_btrl_T0_T1_cc,
527 640 gen_op_btcl_T0_T1_cc,
528 641 },
  642 +#ifdef TARGET_X86_64
  643 + [2] = {
  644 + gen_op_btq_T0_T1_cc,
  645 + gen_op_btsq_T0_T1_cc,
  646 + gen_op_btrq_T0_T1_cc,
  647 + gen_op_btcq_T0_T1_cc,
  648 + },
  649 +#endif
  650 +};
  651 +
  652 +static GenOpFunc *gen_op_add_bit_A0_T1[3] = {
  653 + gen_op_add_bitw_A0_T1,
  654 + gen_op_add_bitl_A0_T1,
  655 + X86_64_ONLY(gen_op_add_bitq_A0_T1),
529 656 };
530 657  
531   -static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
  658 +static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
532 659 [0] = {
533 660 gen_op_bsfw_T0_cc,
534 661 gen_op_bsrw_T0_cc,
... ... @@ -537,109 +664,158 @@ static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
537 664 gen_op_bsfl_T0_cc,
538 665 gen_op_bsrl_T0_cc,
539 666 },
  667 +#ifdef TARGET_X86_64
  668 + [2] = {
  669 + gen_op_bsfq_T0_cc,
  670 + gen_op_bsrq_T0_cc,
  671 + },
  672 +#endif
540 673 };
541 674  
542   -static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = {
  675 +static GenOpFunc *gen_op_lds_T0_A0[3 * 4] = {
543 676 gen_op_ldsb_raw_T0_A0,
544 677 gen_op_ldsw_raw_T0_A0,
  678 + X86_64_ONLY(gen_op_ldsl_raw_T0_A0),
545 679 NULL,
546 680 #ifndef CONFIG_USER_ONLY
547 681 gen_op_ldsb_kernel_T0_A0,
548 682 gen_op_ldsw_kernel_T0_A0,
  683 + X86_64_ONLY(gen_op_ldsl_kernel_T0_A0),
549 684 NULL,
550 685  
551 686 gen_op_ldsb_user_T0_A0,
552 687 gen_op_ldsw_user_T0_A0,
  688 + X86_64_ONLY(gen_op_ldsl_user_T0_A0),
553 689 NULL,
554 690 #endif
555 691 };
556 692  
557   -static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = {
  693 +static GenOpFunc *gen_op_ldu_T0_A0[3 * 4] = {
558 694 gen_op_ldub_raw_T0_A0,
559 695 gen_op_lduw_raw_T0_A0,
560 696 NULL,
  697 + NULL,
561 698  
562 699 #ifndef CONFIG_USER_ONLY
563 700 gen_op_ldub_kernel_T0_A0,
564 701 gen_op_lduw_kernel_T0_A0,
565 702 NULL,
  703 + NULL,
566 704  
567 705 gen_op_ldub_user_T0_A0,
568 706 gen_op_lduw_user_T0_A0,
569 707 NULL,
  708 + NULL,
570 709 #endif
571 710 };
572 711  
573 712 /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
574   -static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = {
  713 +static GenOpFunc *gen_op_ld_T0_A0[3 * 4] = {
575 714 gen_op_ldub_raw_T0_A0,
576 715 gen_op_lduw_raw_T0_A0,
577 716 gen_op_ldl_raw_T0_A0,
  717 + X86_64_ONLY(gen_op_ldq_raw_T0_A0),
578 718  
579 719 #ifndef CONFIG_USER_ONLY
580 720 gen_op_ldub_kernel_T0_A0,
581 721 gen_op_lduw_kernel_T0_A0,
582 722 gen_op_ldl_kernel_T0_A0,
  723 + X86_64_ONLY(gen_op_ldq_kernel_T0_A0),
583 724  
584 725 gen_op_ldub_user_T0_A0,
585 726 gen_op_lduw_user_T0_A0,
586 727 gen_op_ldl_user_T0_A0,
  728 + X86_64_ONLY(gen_op_ldq_user_T0_A0),
587 729 #endif
588 730 };
589 731  
590   -static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = {
  732 +static GenOpFunc *gen_op_ld_T1_A0[3 * 4] = {
591 733 gen_op_ldub_raw_T1_A0,
592 734 gen_op_lduw_raw_T1_A0,
593 735 gen_op_ldl_raw_T1_A0,
  736 + X86_64_ONLY(gen_op_ldq_raw_T1_A0),
594 737  
595 738 #ifndef CONFIG_USER_ONLY
596 739 gen_op_ldub_kernel_T1_A0,
597 740 gen_op_lduw_kernel_T1_A0,
598 741 gen_op_ldl_kernel_T1_A0,
  742 + X86_64_ONLY(gen_op_ldq_kernel_T1_A0),
599 743  
600 744 gen_op_ldub_user_T1_A0,
601 745 gen_op_lduw_user_T1_A0,
602 746 gen_op_ldl_user_T1_A0,
  747 + X86_64_ONLY(gen_op_ldq_user_T1_A0),
603 748 #endif
604 749 };
605 750  
606   -static GenOpFunc *gen_op_st_T0_A0[3 * 3] = {
  751 +static GenOpFunc *gen_op_st_T0_A0[3 * 4] = {
607 752 gen_op_stb_raw_T0_A0,
608 753 gen_op_stw_raw_T0_A0,
609 754 gen_op_stl_raw_T0_A0,
  755 + X86_64_ONLY(gen_op_stq_raw_T0_A0),
610 756  
611 757 #ifndef CONFIG_USER_ONLY
612 758 gen_op_stb_kernel_T0_A0,
613 759 gen_op_stw_kernel_T0_A0,
614 760 gen_op_stl_kernel_T0_A0,
  761 + X86_64_ONLY(gen_op_stq_kernel_T0_A0),
615 762  
616 763 gen_op_stb_user_T0_A0,
617 764 gen_op_stw_user_T0_A0,
618 765 gen_op_stl_user_T0_A0,
  766 + X86_64_ONLY(gen_op_stq_user_T0_A0),
619 767 #endif
620 768 };
621 769  
622   -static GenOpFunc *gen_op_st_T1_A0[3 * 3] = {
  770 +static GenOpFunc *gen_op_st_T1_A0[3 * 4] = {
623 771 NULL,
624 772 gen_op_stw_raw_T1_A0,
625 773 gen_op_stl_raw_T1_A0,
  774 + X86_64_ONLY(gen_op_stq_raw_T1_A0),
626 775  
627 776 #ifndef CONFIG_USER_ONLY
628 777 NULL,
629 778 gen_op_stw_kernel_T1_A0,
630 779 gen_op_stl_kernel_T1_A0,
  780 + X86_64_ONLY(gen_op_stq_kernel_T1_A0),
631 781  
632 782 NULL,
633 783 gen_op_stw_user_T1_A0,
634 784 gen_op_stl_user_T1_A0,
  785 + X86_64_ONLY(gen_op_stq_user_T1_A0),
635 786 #endif
636 787 };
637 788  
  789 +static inline void gen_jmp_im(target_ulong pc)
  790 +{
  791 +#ifdef TARGET_X86_64
  792 + if (pc == (uint32_t)pc) {
  793 + gen_op_movl_eip_im(pc);
  794 + } else if (pc == (int32_t)pc) {
  795 + gen_op_movq_eip_im(pc);
  796 + } else {
  797 + gen_op_movq_eip_im64(pc >> 32, pc);
  798 + }
  799 +#else
  800 + gen_op_movl_eip_im(pc);
  801 +#endif
  802 +}
  803 +
638 804 static inline void gen_string_movl_A0_ESI(DisasContext *s)
639 805 {
640 806 int override;
641 807  
642 808 override = s->override;
  809 +#ifdef TARGET_X86_64
  810 + if (s->aflag == 2) {
  811 + if (override >= 0) {
  812 + gen_op_movq_A0_seg(offsetof(CPUX86State,segs[override].base));
  813 + gen_op_addq_A0_reg_sN[0][R_ESI]();
  814 + } else {
  815 + gen_op_movq_A0_reg[R_ESI]();
  816 + }
  817 + } else
  818 +#endif
643 819 if (s->aflag) {
644 820 /* 32 bit address */
645 821 if (s->addseg && override < 0)
... ... @@ -662,6 +838,11 @@ static inline void gen_string_movl_A0_ESI(DisasContext *s)
662 838  
663 839 static inline void gen_string_movl_A0_EDI(DisasContext *s)
664 840 {
  841 +#ifdef TARGET_X86_64
  842 + if (s->aflag == 2) {
  843 + gen_op_movq_A0_reg[R_EDI]();
  844 + } else
  845 +#endif
665 846 if (s->aflag) {
666 847 if (s->addseg) {
667 848 gen_op_movl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
... ... @@ -676,58 +857,43 @@ static inline void gen_string_movl_A0_EDI(DisasContext *s)
676 857 }
677 858 }
678 859  
679   -static GenOpFunc *gen_op_movl_T0_Dshift[3] = {
  860 +static GenOpFunc *gen_op_movl_T0_Dshift[4] = {
680 861 gen_op_movl_T0_Dshiftb,
681 862 gen_op_movl_T0_Dshiftw,
682 863 gen_op_movl_T0_Dshiftl,
  864 + X86_64_ONLY(gen_op_movl_T0_Dshiftq),
683 865 };
684 866  
685   -static GenOpFunc2 *gen_op_jz_ecx[2] = {
686   - gen_op_jz_ecxw,
687   - gen_op_jz_ecxl,
  867 +static GenOpFunc1 *gen_op_jnz_ecx[3] = {
  868 + gen_op_jnz_ecxw,
  869 + gen_op_jnz_ecxl,
  870 + X86_64_ONLY(gen_op_jnz_ecxq),
688 871 };
689 872  
690   -static GenOpFunc1 *gen_op_jz_ecx_im[2] = {
691   - gen_op_jz_ecxw_im,
692   - gen_op_jz_ecxl_im,
  873 +static GenOpFunc1 *gen_op_jz_ecx[3] = {
  874 + gen_op_jz_ecxw,
  875 + gen_op_jz_ecxl,
  876 + X86_64_ONLY(gen_op_jz_ecxq),
693 877 };
694 878  
695   -static GenOpFunc *gen_op_dec_ECX[2] = {
  879 +static GenOpFunc *gen_op_dec_ECX[3] = {
696 880 gen_op_decw_ECX,
697 881 gen_op_decl_ECX,
  882 + X86_64_ONLY(gen_op_decq_ECX),
698 883 };
699 884  
700   -#ifdef USE_DIRECT_JUMP
701   -typedef GenOpFunc GenOpFuncTB2;
702   -#define gen_op_string_jnz_sub(nz, ot, tb) gen_op_string_jnz_sub2[nz][ot]()
703   -#else
704   -typedef GenOpFunc1 GenOpFuncTB2;
705   -#define gen_op_string_jnz_sub(nz, ot, tb) gen_op_string_jnz_sub2[nz][ot](tb)
706   -#endif
707   -
708   -static GenOpFuncTB2 *gen_op_string_jnz_sub2[2][3] = {
  885 +static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {
709 886 {
710   - gen_op_string_jnz_subb,
711   - gen_op_string_jnz_subw,
712   - gen_op_string_jnz_subl,
  887 + gen_op_jnz_subb,
  888 + gen_op_jnz_subw,
  889 + gen_op_jnz_subl,
  890 + X86_64_ONLY(gen_op_jnz_subq),
713 891 },
714 892 {
715   - gen_op_string_jz_subb,
716   - gen_op_string_jz_subw,
717   - gen_op_string_jz_subl,
718   - },
719   -};
720   -
721   -static GenOpFunc1 *gen_op_string_jnz_sub_im[2][3] = {
722   - {
723   - gen_op_string_jnz_subb_im,
724   - gen_op_string_jnz_subw_im,
725   - gen_op_string_jnz_subl_im,
726   - },
727   - {
728   - gen_op_string_jz_subb_im,
729   - gen_op_string_jz_subw_im,
730   - gen_op_string_jz_subl_im,
  893 + gen_op_jz_subb,
  894 + gen_op_jz_subw,
  895 + gen_op_jz_subl,
  896 + X86_64_ONLY(gen_op_jz_subq),
731 897 },
732 898 };
733 899  
... ... @@ -767,12 +933,12 @@ static GenOpFunc *gen_check_io_DX[3] = {
767 933 gen_op_check_iol_DX,
768 934 };
769 935  
770   -static void gen_check_io(DisasContext *s, int ot, int use_dx, int cur_eip)
  936 +static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip)
771 937 {
772 938 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
773 939 if (s->cc_op != CC_OP_DYNAMIC)
774 940 gen_op_set_cc_op(s->cc_op);
775   - gen_op_jmp_im(cur_eip);
  941 + gen_jmp_im(cur_eip);
776 942 if (use_dx)
777 943 gen_check_io_DX[ot]();
778 944 else
... ... @@ -787,6 +953,12 @@ static inline void gen_movs(DisasContext *s, int ot)
787 953 gen_string_movl_A0_EDI(s);
788 954 gen_op_st_T0_A0[ot + s->mem_index]();
789 955 gen_op_movl_T0_Dshift[ot]();
  956 +#ifdef TARGET_X86_64
  957 + if (s->aflag == 2) {
  958 + gen_op_addq_ESI_T0();
  959 + gen_op_addq_EDI_T0();
  960 + } else
  961 +#endif
790 962 if (s->aflag) {
791 963 gen_op_addl_ESI_T0();
792 964 gen_op_addl_EDI_T0();
... ... @@ -804,15 +976,19 @@ static inline void gen_update_cc_op(DisasContext *s)
804 976 }
805 977 }
806 978  
807   -static inline void gen_jz_ecx_string(DisasContext *s, unsigned int next_eip)
  979 +/* XXX: does not work with gdbstub "ice" single step - not a
  980 + serious problem */
  981 +static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
808 982 {
809   - if (s->jmp_opt) {
810   - gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
811   - } else {
812   - /* XXX: does not work with gdbstub "ice" single step - not a
813   - serious problem */
814   - gen_op_jz_ecx_im[s->aflag](next_eip);
815   - }
  983 + int l1, l2;
  984 +
  985 + l1 = gen_new_label();
  986 + l2 = gen_new_label();
  987 + gen_op_jnz_ecx[s->aflag](l1);
  988 + gen_set_label(l2);
  989 + gen_jmp_tb(s, next_eip, 1);
  990 + gen_set_label(l1);
  991 + return l2;
816 992 }
817 993  
818 994 static inline void gen_stos(DisasContext *s, int ot)
... ... @@ -821,6 +997,11 @@ static inline void gen_stos(DisasContext *s, int ot)
821 997 gen_string_movl_A0_EDI(s);
822 998 gen_op_st_T0_A0[ot + s->mem_index]();
823 999 gen_op_movl_T0_Dshift[ot]();
  1000 +#ifdef TARGET_X86_64
  1001 + if (s->aflag == 2) {
  1002 + gen_op_addq_EDI_T0();
  1003 + } else
  1004 +#endif
824 1005 if (s->aflag) {
825 1006 gen_op_addl_EDI_T0();
826 1007 } else {
... ... @@ -834,6 +1015,11 @@ static inline void gen_lods(DisasContext *s, int ot)
834 1015 gen_op_ld_T0_A0[ot + s->mem_index]();
835 1016 gen_op_mov_reg_T0[ot][R_EAX]();
836 1017 gen_op_movl_T0_Dshift[ot]();
  1018 +#ifdef TARGET_X86_64
  1019 + if (s->aflag == 2) {
  1020 + gen_op_addq_ESI_T0();
  1021 + } else
  1022 +#endif
837 1023 if (s->aflag) {
838 1024 gen_op_addl_ESI_T0();
839 1025 } else {
... ... @@ -848,6 +1034,11 @@ static inline void gen_scas(DisasContext *s, int ot)
848 1034 gen_op_ld_T1_A0[ot + s->mem_index]();
849 1035 gen_op_cmpl_T0_T1_cc();
850 1036 gen_op_movl_T0_Dshift[ot]();
  1037 +#ifdef TARGET_X86_64
  1038 + if (s->aflag == 2) {
  1039 + gen_op_addq_EDI_T0();
  1040 + } else
  1041 +#endif
851 1042 if (s->aflag) {
852 1043 gen_op_addl_EDI_T0();
853 1044 } else {
... ... @@ -863,6 +1054,12 @@ static inline void gen_cmps(DisasContext *s, int ot)
863 1054 gen_op_ld_T1_A0[ot + s->mem_index]();
864 1055 gen_op_cmpl_T0_T1_cc();
865 1056 gen_op_movl_T0_Dshift[ot]();
  1057 +#ifdef TARGET_X86_64
  1058 + if (s->aflag == 2) {
  1059 + gen_op_addq_ESI_T0();
  1060 + gen_op_addq_EDI_T0();
  1061 + } else
  1062 +#endif
866 1063 if (s->aflag) {
867 1064 gen_op_addl_ESI_T0();
868 1065 gen_op_addl_EDI_T0();
... ... @@ -880,6 +1077,11 @@ static inline void gen_ins(DisasContext *s, int ot)
880 1077 gen_op_in_DX_T0[ot]();
881 1078 gen_op_st_T0_A0[ot + s->mem_index]();
882 1079 gen_op_movl_T0_Dshift[ot]();
  1080 +#ifdef TARGET_X86_64
  1081 + if (s->aflag == 2) {
  1082 + gen_op_addq_EDI_T0();
  1083 + } else
  1084 +#endif
883 1085 if (s->aflag) {
884 1086 gen_op_addl_EDI_T0();
885 1087 } else {
... ... @@ -893,6 +1095,11 @@ static inline void gen_outs(DisasContext *s, int ot)
893 1095 gen_op_ld_T0_A0[ot + s->mem_index]();
894 1096 gen_op_out_DX_T0[ot]();
895 1097 gen_op_movl_T0_Dshift[ot]();
  1098 +#ifdef TARGET_X86_64
  1099 + if (s->aflag == 2) {
  1100 + gen_op_addq_ESI_T0();
  1101 + } else
  1102 +#endif
896 1103 if (s->aflag) {
897 1104 gen_op_addl_ESI_T0();
898 1105 } else {
... ... @@ -904,36 +1111,35 @@ static inline void gen_outs(DisasContext *s, int ot)
904 1111 instruction */
905 1112 #define GEN_REPZ(op) \
906 1113 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
907   - unsigned int cur_eip, unsigned int next_eip) \
  1114 + target_ulong cur_eip, target_ulong next_eip) \
908 1115 { \
  1116 + int l2;\
909 1117 gen_update_cc_op(s); \
910   - gen_jz_ecx_string(s, next_eip); \
  1118 + l2 = gen_jz_ecx_string(s, next_eip); \
911 1119 gen_ ## op(s, ot); \
912 1120 gen_op_dec_ECX[s->aflag](); \
913 1121 /* a loop would cause two single step exceptions if ECX = 1 \
914 1122 before rep string_insn */ \
915 1123 if (!s->jmp_opt) \
916   - gen_op_jz_ecx_im[s->aflag](next_eip); \
  1124 + gen_op_jz_ecx[s->aflag](l2); \
917 1125 gen_jmp(s, cur_eip); \
918 1126 }
919 1127  
920 1128 #define GEN_REPZ2(op) \
921 1129 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
922   - unsigned int cur_eip, \
923   - unsigned int next_eip, \
  1130 + target_ulong cur_eip, \
  1131 + target_ulong next_eip, \
924 1132 int nz) \
925 1133 { \
  1134 + int l2;\
926 1135 gen_update_cc_op(s); \
927   - gen_jz_ecx_string(s, next_eip); \
  1136 + l2 = gen_jz_ecx_string(s, next_eip); \
928 1137 gen_ ## op(s, ot); \
929 1138 gen_op_dec_ECX[s->aflag](); \
930 1139 gen_op_set_cc_op(CC_OP_SUBB + ot); \
  1140 + gen_op_string_jnz_sub[nz][ot](l2);\
931 1141 if (!s->jmp_opt) \
932   - gen_op_string_jnz_sub_im[nz][ot](next_eip); \
933   - else \
934   - gen_op_string_jnz_sub(nz, ot, (long)s->tb); \
935   - if (!s->jmp_opt) \
936   - gen_op_jz_ecx_im[s->aflag](next_eip); \
  1142 + gen_op_jz_ecx[s->aflag](l2); \
937 1143 gen_jmp(s, cur_eip); \
938 1144 }
939 1145  
... ... @@ -956,7 +1162,7 @@ enum {
956 1162 JCC_LE,
957 1163 };
958 1164  
959   -static GenOpFunc3 *gen_jcc_sub[3][8] = {
  1165 +static GenOpFunc1 *gen_jcc_sub[4][8] = {
960 1166 [OT_BYTE] = {
961 1167 NULL,
962 1168 gen_op_jb_subb,
... ... @@ -987,20 +1193,37 @@ static GenOpFunc3 *gen_jcc_sub[3][8] = {
987 1193 gen_op_jl_subl,
988 1194 gen_op_jle_subl,
989 1195 },
  1196 +#ifdef TARGET_X86_64
  1197 + [OT_QUAD] = {
  1198 + NULL,
  1199 + BUGGY_64(gen_op_jb_subq),
  1200 + gen_op_jz_subq,
  1201 + BUGGY_64(gen_op_jbe_subq),
  1202 + gen_op_js_subq,
  1203 + NULL,
  1204 + BUGGY_64(gen_op_jl_subq),
  1205 + BUGGY_64(gen_op_jle_subq),
  1206 + },
  1207 +#endif
990 1208 };
991   -static GenOpFunc2 *gen_op_loop[2][4] = {
  1209 +static GenOpFunc1 *gen_op_loop[3][4] = {
992 1210 [0] = {
993 1211 gen_op_loopnzw,
994 1212 gen_op_loopzw,
995   - gen_op_loopw,
996   - gen_op_jecxzw,
  1213 + gen_op_jnz_ecxw,
997 1214 },
998 1215 [1] = {
999 1216 gen_op_loopnzl,
1000 1217 gen_op_loopzl,
1001   - gen_op_loopl,
1002   - gen_op_jecxzl,
  1218 + gen_op_jnz_ecxl,
  1219 + },
  1220 +#ifdef TARGET_X86_64
  1221 + [2] = {
  1222 + gen_op_loopnzq,
  1223 + gen_op_loopzq,
  1224 + gen_op_jnz_ecxq,
1003 1225 },
  1226 +#endif
1004 1227 };
1005 1228  
1006 1229 static GenOpFunc *gen_setcc_slow[8] = {
... ... @@ -1014,7 +1237,7 @@ static GenOpFunc *gen_setcc_slow[8] = {
1014 1237 gen_op_setle_T0_cc,
1015 1238 };
1016 1239  
1017   -static GenOpFunc *gen_setcc_sub[3][8] = {
  1240 +static GenOpFunc *gen_setcc_sub[4][8] = {
1018 1241 [OT_BYTE] = {
1019 1242 NULL,
1020 1243 gen_op_setb_T0_subb,
... ... @@ -1045,6 +1268,18 @@ static GenOpFunc *gen_setcc_sub[3][8] = {
1045 1268 gen_op_setl_T0_subl,
1046 1269 gen_op_setle_T0_subl,
1047 1270 },
  1271 +#ifdef TARGET_X86_64
  1272 + [OT_QUAD] = {
  1273 + NULL,
  1274 + gen_op_setb_T0_subq,
  1275 + gen_op_setz_T0_subq,
  1276 + gen_op_setbe_T0_subq,
  1277 + gen_op_sets_T0_subq,
  1278 + NULL,
  1279 + gen_op_setl_T0_subq,
  1280 + gen_op_setle_T0_subq,
  1281 + },
  1282 +#endif
1048 1283 };
1049 1284  
1050 1285 static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
... ... @@ -1183,8 +1418,9 @@ static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1183 1418  
1184 1419 static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1185 1420 {
  1421 + target_long disp;
1186 1422 int havesib;
1187   - int base, disp;
  1423 + int base;
1188 1424 int index;
1189 1425 int scale;
1190 1426 int opreg;
... ... @@ -1208,16 +1444,20 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1208 1444 havesib = 1;
1209 1445 code = ldub_code(s->pc++);
1210 1446 scale = (code >> 6) & 3;
1211   - index = (code >> 3) & 7;
1212   - base = code & 7;
  1447 + index = ((code >> 3) & 7) | REX_X(s);
  1448 + base = (code & 7);
1213 1449 }
  1450 + base |= REX_B(s);
1214 1451  
1215 1452 switch (mod) {
1216 1453 case 0:
1217   - if (base == 5) {
  1454 + if ((base & 7) == 5) {
1218 1455 base = -1;
1219   - disp = ldl_code(s->pc);
  1456 + disp = (int32_t)ldl_code(s->pc);
1220 1457 s->pc += 4;
  1458 + if (CODE64(s) && !havesib) {
  1459 + disp += s->pc + s->rip_offset;
  1460 + }
1221 1461 } else {
1222 1462 disp = 0;
1223 1463 }
... ... @@ -1236,15 +1476,45 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1236 1476 /* for correct popl handling with esp */
1237 1477 if (base == 4 && s->popl_esp_hack)
1238 1478 disp += s->popl_esp_hack;
1239   - gen_op_movl_A0_reg[base]();
1240   - if (disp != 0)
1241   - gen_op_addl_A0_im(disp);
  1479 +#ifdef TARGET_X86_64
  1480 + if (s->aflag == 2) {
  1481 + gen_op_movq_A0_reg[base]();
  1482 + if (disp != 0) {
  1483 + if ((int32_t)disp == disp)
  1484 + gen_op_addq_A0_im(disp);
  1485 + else
  1486 + gen_op_addq_A0_im64(disp >> 32, disp);
  1487 + }
  1488 + } else
  1489 +#endif
  1490 + {
  1491 + gen_op_movl_A0_reg[base]();
  1492 + if (disp != 0)
  1493 + gen_op_addl_A0_im(disp);
  1494 + }
1242 1495 } else {
1243   - gen_op_movl_A0_im(disp);
  1496 +#ifdef TARGET_X86_64
  1497 + if (s->aflag == 2) {
  1498 + if ((int32_t)disp == disp)
  1499 + gen_op_movq_A0_im(disp);
  1500 + else
  1501 + gen_op_movq_A0_im64(disp >> 32, disp);
  1502 + } else
  1503 +#endif
  1504 + {
  1505 + gen_op_movl_A0_im(disp);
  1506 + }
1244 1507 }
1245 1508 /* XXX: index == 4 is always invalid */
1246 1509 if (havesib && (index != 4 || scale != 0)) {
1247   - gen_op_addl_A0_reg_sN[scale][index]();
  1510 +#ifdef TARGET_X86_64
  1511 + if (s->aflag == 2) {
  1512 + gen_op_addq_A0_reg_sN[scale][index]();
  1513 + } else
  1514 +#endif
  1515 + {
  1516 + gen_op_addl_A0_reg_sN[scale][index]();
  1517 + }
1248 1518 }
1249 1519 if (must_add_seg) {
1250 1520 if (override < 0) {
... ... @@ -1253,7 +1523,14 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1253 1523 else
1254 1524 override = R_DS;
1255 1525 }
1256   - gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
  1526 +#ifdef TARGET_X86_64
  1527 + if (s->aflag == 2) {
  1528 + gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
  1529 + } else
  1530 +#endif
  1531 + {
  1532 + gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
  1533 + }
1257 1534 }
1258 1535 } else {
1259 1536 switch (mod) {
... ... @@ -1336,7 +1613,7 @@ static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_s
1336 1613 int mod, rm, opreg, disp;
1337 1614  
1338 1615 mod = (modrm >> 6) & 3;
1339   - rm = modrm & 7;
  1616 + rm = (modrm & 7) | REX_B(s);
1340 1617 if (mod == 3) {
1341 1618 if (is_store) {
1342 1619 if (reg != OR_TMP0)
... ... @@ -1383,11 +1660,22 @@ static inline uint32_t insn_get(DisasContext *s, int ot)
1383 1660 return ret;
1384 1661 }
1385 1662  
1386   -static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip)
  1663 +static inline int insn_const_size(unsigned int ot)
  1664 +{
  1665 + if (ot <= OT_LONG)
  1666 + return 1 << ot;
  1667 + else
  1668 + return 4;
  1669 +}
  1670 +
  1671 +static inline void gen_jcc(DisasContext *s, int b,
  1672 + target_ulong val, target_ulong next_eip)
1387 1673 {
1388 1674 TranslationBlock *tb;
1389 1675 int inv, jcc_op;
1390   - GenOpFunc3 *func;
  1676 + GenOpFunc1 *func;
  1677 + target_ulong tmp;
  1678 + int l1, l2;
1391 1679  
1392 1680 inv = b & 1;
1393 1681 jcc_op = (b >> 1) & 7;
... ... @@ -1398,6 +1686,7 @@ static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip)
1398 1686 case CC_OP_SUBB:
1399 1687 case CC_OP_SUBW:
1400 1688 case CC_OP_SUBL:
  1689 + case CC_OP_SUBQ:
1401 1690 func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1402 1691 break;
1403 1692  
... ... @@ -1405,33 +1694,48 @@ static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip)
1405 1694 case CC_OP_ADDB:
1406 1695 case CC_OP_ADDW:
1407 1696 case CC_OP_ADDL:
  1697 + case CC_OP_ADDQ:
  1698 +
1408 1699 case CC_OP_ADCB:
1409 1700 case CC_OP_ADCW:
1410 1701 case CC_OP_ADCL:
  1702 + case CC_OP_ADCQ:
  1703 +
1411 1704 case CC_OP_SBBB:
1412 1705 case CC_OP_SBBW:
1413 1706 case CC_OP_SBBL:
  1707 + case CC_OP_SBBQ:
  1708 +
1414 1709 case CC_OP_LOGICB:
1415 1710 case CC_OP_LOGICW:
1416 1711 case CC_OP_LOGICL:
  1712 + case CC_OP_LOGICQ:
  1713 +
1417 1714 case CC_OP_INCB:
1418 1715 case CC_OP_INCW:
1419 1716 case CC_OP_INCL:
  1717 + case CC_OP_INCQ:
  1718 +
1420 1719 case CC_OP_DECB:
1421 1720 case CC_OP_DECW:
1422 1721 case CC_OP_DECL:
  1722 + case CC_OP_DECQ:
  1723 +
1423 1724 case CC_OP_SHLB:
1424 1725 case CC_OP_SHLW:
1425 1726 case CC_OP_SHLL:
  1727 + case CC_OP_SHLQ:
  1728 +
1426 1729 case CC_OP_SARB:
1427 1730 case CC_OP_SARW:
1428 1731 case CC_OP_SARL:
  1732 + case CC_OP_SARQ:
1429 1733 switch(jcc_op) {
1430 1734 case JCC_Z:
1431   - func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
  1735 + func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1432 1736 break;
1433 1737 case JCC_S:
1434   - func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
  1738 + func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1435 1739 break;
1436 1740 default:
1437 1741 func = NULL;
... ... @@ -1448,27 +1752,51 @@ static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip)
1448 1752  
1449 1753 if (!func) {
1450 1754 gen_setcc_slow[jcc_op]();
1451   - func = gen_op_jcc;
  1755 + func = gen_op_jnz_T0_label;
1452 1756 }
1453 1757  
1454   - tb = s->tb;
1455   - if (!inv) {
1456   - func((long)tb, val, next_eip);
1457   - } else {
1458   - func((long)tb, next_eip, val);
  1758 + if (inv) {
  1759 + tmp = val;
  1760 + val = next_eip;
  1761 + next_eip = tmp;
1459 1762 }
  1763 + tb = s->tb;
  1764 +
  1765 + l1 = gen_new_label();
  1766 + func(l1);
  1767 +
  1768 + gen_op_goto_tb0();
  1769 + gen_jmp_im(next_eip);
  1770 + gen_op_movl_T0_im((long)tb + 0);
  1771 + gen_op_exit_tb();
  1772 +
  1773 + gen_set_label(l1);
  1774 + gen_op_goto_tb1();
  1775 + gen_jmp_im(val);
  1776 + gen_op_movl_T0_im((long)tb + 1);
  1777 + gen_op_exit_tb();
  1778 +
1460 1779 s->is_jmp = 3;
1461 1780 } else {
  1781 +
1462 1782 if (s->cc_op != CC_OP_DYNAMIC) {
1463 1783 gen_op_set_cc_op(s->cc_op);
1464 1784 s->cc_op = CC_OP_DYNAMIC;
1465 1785 }
1466 1786 gen_setcc_slow[jcc_op]();
1467   - if (!inv) {
1468   - gen_op_jcc_im(val, next_eip);
1469   - } else {
1470   - gen_op_jcc_im(next_eip, val);
  1787 + if (inv) {
  1788 + tmp = val;
  1789 + val = next_eip;
  1790 + next_eip = tmp;
1471 1791 }
  1792 + l1 = gen_new_label();
  1793 + l2 = gen_new_label();
  1794 + gen_op_jnz_T0_label(l1);
  1795 + gen_jmp_im(next_eip);
  1796 + gen_op_jmp_label(l2);
  1797 + gen_set_label(l1);
  1798 + gen_jmp_im(val);
  1799 + gen_set_label(l2);
1472 1800 gen_eob(s);
1473 1801 }
1474 1802 }
... ... @@ -1485,6 +1813,7 @@ static void gen_setcc(DisasContext *s, int b)
1485 1813 case CC_OP_SUBB:
1486 1814 case CC_OP_SUBW:
1487 1815 case CC_OP_SUBL:
  1816 + case CC_OP_SUBQ:
1488 1817 func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1489 1818 if (!func)
1490 1819 goto slow_jcc;
... ... @@ -1494,24 +1823,33 @@ static void gen_setcc(DisasContext *s, int b)
1494 1823 case CC_OP_ADDB:
1495 1824 case CC_OP_ADDW:
1496 1825 case CC_OP_ADDL:
  1826 + case CC_OP_ADDQ:
  1827 +
1497 1828 case CC_OP_LOGICB:
1498 1829 case CC_OP_LOGICW:
1499 1830 case CC_OP_LOGICL:
  1831 + case CC_OP_LOGICQ:
  1832 +
1500 1833 case CC_OP_INCB:
1501 1834 case CC_OP_INCW:
1502 1835 case CC_OP_INCL:
  1836 + case CC_OP_INCQ:
  1837 +
1503 1838 case CC_OP_DECB:
1504 1839 case CC_OP_DECW:
1505 1840 case CC_OP_DECL:
  1841 + case CC_OP_DECQ:
  1842 +
1506 1843 case CC_OP_SHLB:
1507 1844 case CC_OP_SHLW:
1508 1845 case CC_OP_SHLL:
  1846 + case CC_OP_SHLQ:
1509 1847 switch(jcc_op) {
1510 1848 case JCC_Z:
1511   - func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
  1849 + func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1512 1850 break;
1513 1851 case JCC_S:
1514   - func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
  1852 + func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1515 1853 break;
1516 1854 default:
1517 1855 goto slow_jcc;
... ... @@ -1532,13 +1870,13 @@ static void gen_setcc(DisasContext *s, int b)
1532 1870  
1533 1871 /* move T0 to seg_reg and compute if the CPU state may change. Never
1534 1872 call this function with seg_reg == R_CS */
1535   -static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)
  1873 +static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
1536 1874 {
1537 1875 if (s->pe && !s->vm86) {
1538 1876 /* XXX: optimize by finding processor state dynamically */
1539 1877 if (s->cc_op != CC_OP_DYNAMIC)
1540 1878 gen_op_set_cc_op(s->cc_op);
1541   - gen_op_jmp_im(cur_eip);
  1879 + gen_jmp_im(cur_eip);
1542 1880 gen_op_movl_seg_T0(seg_reg);
1543 1881 /* abort translation because the addseg value may change or
1544 1882 because ss32 may change. For R_SS, translation must always
... ... @@ -1555,6 +1893,14 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)
1555 1893  
1556 1894 static inline void gen_stack_update(DisasContext *s, int addend)
1557 1895 {
  1896 +#ifdef TARGET_X86_64
  1897 + if (CODE64(s)) {
  1898 + if (addend == 8)
  1899 + gen_op_addq_ESP_8();
  1900 + else
  1901 + gen_op_addq_ESP_im(addend);
  1902 + } else
  1903 +#endif
1558 1904 if (s->ss32) {
1559 1905 if (addend == 2)
1560 1906 gen_op_addl_ESP_2();
... ... @@ -1575,70 +1921,108 @@ static inline void gen_stack_update(DisasContext *s, int addend)
1575 1921 /* generate a push. It depends on ss32, addseg and dflag */
1576 1922 static void gen_push_T0(DisasContext *s)
1577 1923 {
1578   - gen_op_movl_A0_reg[R_ESP]();
1579   - if (!s->dflag)
1580   - gen_op_subl_A0_2();
1581   - else
1582   - gen_op_subl_A0_4();
1583   - if (s->ss32) {
1584   - if (s->addseg) {
  1924 +#ifdef TARGET_X86_64
  1925 + if (CODE64(s)) {
  1926 + /* XXX: check 16 bit behaviour */
  1927 + gen_op_movq_A0_reg[R_ESP]();
  1928 + gen_op_subq_A0_8();
  1929 + gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
  1930 + gen_op_movq_ESP_A0();
  1931 + } else
  1932 +#endif
  1933 + {
  1934 + gen_op_movl_A0_reg[R_ESP]();
  1935 + if (!s->dflag)
  1936 + gen_op_subl_A0_2();
  1937 + else
  1938 + gen_op_subl_A0_4();
  1939 + if (s->ss32) {
  1940 + if (s->addseg) {
  1941 + gen_op_movl_T1_A0();
  1942 + gen_op_addl_A0_SS();
  1943 + }
  1944 + } else {
  1945 + gen_op_andl_A0_ffff();
1585 1946 gen_op_movl_T1_A0();
1586 1947 gen_op_addl_A0_SS();
1587 1948 }
1588   - } else {
1589   - gen_op_andl_A0_ffff();
1590   - gen_op_movl_T1_A0();
1591   - gen_op_addl_A0_SS();
  1949 + gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
  1950 + if (s->ss32 && !s->addseg)
  1951 + gen_op_movl_ESP_A0();
  1952 + else
  1953 + gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
1592 1954 }
1593   - gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
1594   - if (s->ss32 && !s->addseg)
1595   - gen_op_movl_ESP_A0();
1596   - else
1597   - gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
1598 1955 }
1599 1956  
1600 1957 /* generate a push. It depends on ss32, addseg and dflag */
1601 1958 /* slower version for T1, only used for call Ev */
1602 1959 static void gen_push_T1(DisasContext *s)
1603 1960 {
1604   - gen_op_movl_A0_reg[R_ESP]();
1605   - if (!s->dflag)
1606   - gen_op_subl_A0_2();
1607   - else
1608   - gen_op_subl_A0_4();
1609   - if (s->ss32) {
1610   - if (s->addseg) {
  1961 +#ifdef TARGET_X86_64
  1962 + if (CODE64(s)) {
  1963 + /* XXX: check 16 bit behaviour */
  1964 + gen_op_movq_A0_reg[R_ESP]();
  1965 + gen_op_subq_A0_8();
  1966 + gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
  1967 + gen_op_movq_ESP_A0();
  1968 + } else
  1969 +#endif
  1970 + {
  1971 + gen_op_movl_A0_reg[R_ESP]();
  1972 + if (!s->dflag)
  1973 + gen_op_subl_A0_2();
  1974 + else
  1975 + gen_op_subl_A0_4();
  1976 + if (s->ss32) {
  1977 + if (s->addseg) {
  1978 + gen_op_addl_A0_SS();
  1979 + }
  1980 + } else {
  1981 + gen_op_andl_A0_ffff();
1611 1982 gen_op_addl_A0_SS();
1612 1983 }
1613   - } else {
1614   - gen_op_andl_A0_ffff();
1615   - gen_op_addl_A0_SS();
  1984 + gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
  1985 +
  1986 + if (s->ss32 && !s->addseg)
  1987 + gen_op_movl_ESP_A0();
  1988 + else
  1989 + gen_stack_update(s, (-2) << s->dflag);
1616 1990 }
1617   - gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
1618   -
1619   - if (s->ss32 && !s->addseg)
1620   - gen_op_movl_ESP_A0();
1621   - else
1622   - gen_stack_update(s, (-2) << s->dflag);
1623 1991 }
1624 1992  
1625 1993 /* two step pop is necessary for precise exceptions */
1626 1994 static void gen_pop_T0(DisasContext *s)
1627 1995 {
1628   - gen_op_movl_A0_reg[R_ESP]();
1629   - if (s->ss32) {
1630   - if (s->addseg)
  1996 +#ifdef TARGET_X86_64
  1997 + if (CODE64(s)) {
  1998 + /* XXX: check 16 bit behaviour */
  1999 + gen_op_movq_A0_reg[R_ESP]();
  2000 + gen_op_ld_T0_A0[OT_QUAD + s->mem_index]();
  2001 + } else
  2002 +#endif
  2003 + {
  2004 + gen_op_movl_A0_reg[R_ESP]();
  2005 + if (s->ss32) {
  2006 + if (s->addseg)
  2007 + gen_op_addl_A0_SS();
  2008 + } else {
  2009 + gen_op_andl_A0_ffff();
1631 2010 gen_op_addl_A0_SS();
1632   - } else {
1633   - gen_op_andl_A0_ffff();
1634   - gen_op_addl_A0_SS();
  2011 + }
  2012 + gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
1635 2013 }
1636   - gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
1637 2014 }
1638 2015  
1639 2016 static void gen_pop_update(DisasContext *s)
1640 2017 {
1641   - gen_stack_update(s, 2 << s->dflag);
  2018 +#ifdef TARGET_X86_64
  2019 + if (CODE64(s)) {
  2020 + gen_stack_update(s, 8);
  2021 + } else
  2022 +#endif
  2023 + {
  2024 + gen_stack_update(s, 2 << s->dflag);
  2025 + }
1642 2026 }
1643 2027  
1644 2028 static void gen_stack_A0(DisasContext *s)
... ... @@ -1718,11 +2102,11 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
1718 2102 gen_op_mov_reg_T1[ot][R_ESP]();
1719 2103 }
1720 2104  
1721   -static void gen_exception(DisasContext *s, int trapno, unsigned int cur_eip)
  2105 +static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
1722 2106 {
1723 2107 if (s->cc_op != CC_OP_DYNAMIC)
1724 2108 gen_op_set_cc_op(s->cc_op);
1725   - gen_op_jmp_im(cur_eip);
  2109 + gen_jmp_im(cur_eip);
1726 2110 gen_op_raise_exception(trapno);
1727 2111 s->is_jmp = 3;
1728 2112 }
... ... @@ -1730,20 +2114,20 @@ static void gen_exception(DisasContext *s, int trapno, unsigned int cur_eip)
1730 2114 /* an interrupt is different from an exception because of the
1731 2115 priviledge checks */
1732 2116 static void gen_interrupt(DisasContext *s, int intno,
1733   - unsigned int cur_eip, unsigned int next_eip)
  2117 + target_ulong cur_eip, target_ulong next_eip)
1734 2118 {
1735 2119 if (s->cc_op != CC_OP_DYNAMIC)
1736 2120 gen_op_set_cc_op(s->cc_op);
1737   - gen_op_jmp_im(cur_eip);
  2121 + gen_jmp_im(cur_eip);
1738 2122 gen_op_raise_interrupt(intno, next_eip);
1739 2123 s->is_jmp = 3;
1740 2124 }
1741 2125  
1742   -static void gen_debug(DisasContext *s, unsigned int cur_eip)
  2126 +static void gen_debug(DisasContext *s, target_ulong cur_eip)
1743 2127 {
1744 2128 if (s->cc_op != CC_OP_DYNAMIC)
1745 2129 gen_op_set_cc_op(s->cc_op);
1746   - gen_op_jmp_im(cur_eip);
  2130 + gen_jmp_im(cur_eip);
1747 2131 gen_op_debug();
1748 2132 s->is_jmp = 3;
1749 2133 }
... ... @@ -1770,80 +2154,186 @@ static void gen_eob(DisasContext *s)
1770 2154  
1771 2155 /* generate a jump to eip. No segment change must happen before as a
1772 2156 direct call to the next block may occur */
1773   -static void gen_jmp(DisasContext *s, unsigned int eip)
  2157 +static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
1774 2158 {
1775 2159 TranslationBlock *tb = s->tb;
1776 2160  
1777 2161 if (s->jmp_opt) {
1778 2162 if (s->cc_op != CC_OP_DYNAMIC)
1779 2163 gen_op_set_cc_op(s->cc_op);
1780   - gen_op_jmp((long)tb, eip);
  2164 + if (tb_num)
  2165 + gen_op_goto_tb1();
  2166 + else
  2167 + gen_op_goto_tb0();
  2168 + gen_jmp_im(eip);
  2169 + gen_op_movl_T0_im((long)tb + tb_num);
  2170 + gen_op_exit_tb();
1781 2171 s->is_jmp = 3;
1782 2172 } else {
1783   - gen_op_jmp_im(eip);
  2173 + gen_jmp_im(eip);
1784 2174 gen_eob(s);
1785 2175 }
1786 2176 }
1787 2177  
  2178 +static void gen_jmp(DisasContext *s, target_ulong eip)
  2179 +{
  2180 + gen_jmp_tb(s, eip, 0);
  2181 +}
  2182 +
  2183 +static void gen_movtl_T0_im(target_ulong val)
  2184 +{
  2185 +#ifdef TARGET_X86_64
  2186 + if ((int32_t)val == val) {
  2187 + gen_op_movl_T0_im(val);
  2188 + } else {
  2189 + gen_op_movq_T0_im64(val >> 32, val);
  2190 + }
  2191 +#else
  2192 + gen_op_movl_T0_im(val);
  2193 +#endif
  2194 +}
  2195 +
  2196 +static GenOpFunc1 *gen_ldo_env_A0[3] = {
  2197 + gen_op_ldo_raw_env_A0,
  2198 +#ifndef CONFIG_USER_ONLY
  2199 + gen_op_ldo_kernel_env_A0,
  2200 + gen_op_ldo_user_env_A0,
  2201 +#endif
  2202 +};
  2203 +
  2204 +static GenOpFunc1 *gen_sto_env_A0[3] = {
  2205 + gen_op_sto_raw_env_A0,
  2206 +#ifndef CONFIG_USER_ONLY
  2207 + gen_op_sto_kernel_env_A0,
  2208 + gen_op_sto_user_env_A0,
  2209 +#endif
  2210 +};
  2211 +
1788 2212 /* convert one instruction. s->is_jmp is set if the translation must
1789 2213 be stopped. Return the next pc value */
1790   -static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
  2214 +static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
1791 2215 {
1792 2216 int b, prefixes, aflag, dflag;
1793 2217 int shift, ot;
1794 2218 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
1795   - unsigned int next_eip;
  2219 + target_ulong next_eip, tval;
  2220 + int rex_w, rex_r;
1796 2221  
1797 2222 s->pc = pc_start;
1798 2223 prefixes = 0;
1799 2224 aflag = s->code32;
1800 2225 dflag = s->code32;
1801 2226 s->override = -1;
  2227 + rex_w = -1;
  2228 + rex_r = 0;
  2229 +#ifdef TARGET_X86_64
  2230 + s->rex_x = 0;
  2231 + s->rex_b = 0;
  2232 + x86_64_hregs = 0;
  2233 +#endif
  2234 + s->rip_offset = 0; /* for relative ip address */
1802 2235 next_byte:
1803 2236 b = ldub_code(s->pc);
1804 2237 s->pc++;
1805 2238 /* check prefixes */
1806   - switch (b) {
1807   - case 0xf3:
1808   - prefixes |= PREFIX_REPZ;
1809   - goto next_byte;
1810   - case 0xf2:
1811   - prefixes |= PREFIX_REPNZ;
1812   - goto next_byte;
1813   - case 0xf0:
1814   - prefixes |= PREFIX_LOCK;
1815   - goto next_byte;
1816   - case 0x2e:
1817   - s->override = R_CS;
1818   - goto next_byte;
1819   - case 0x36:
1820   - s->override = R_SS;
1821   - goto next_byte;
1822   - case 0x3e:
1823   - s->override = R_DS;
1824   - goto next_byte;
1825   - case 0x26:
1826   - s->override = R_ES;
1827   - goto next_byte;
1828   - case 0x64:
1829   - s->override = R_FS;
1830   - goto next_byte;
1831   - case 0x65:
1832   - s->override = R_GS;
1833   - goto next_byte;
1834   - case 0x66:
1835   - prefixes |= PREFIX_DATA;
1836   - goto next_byte;
1837   - case 0x67:
1838   - prefixes |= PREFIX_ADR;
1839   - goto next_byte;
  2239 +#ifdef TARGET_X86_64
  2240 + if (CODE64(s)) {
  2241 + switch (b) {
  2242 + case 0xf3:
  2243 + prefixes |= PREFIX_REPZ;
  2244 + goto next_byte;
  2245 + case 0xf2:
  2246 + prefixes |= PREFIX_REPNZ;
  2247 + goto next_byte;
  2248 + case 0xf0:
  2249 + prefixes |= PREFIX_LOCK;
  2250 + goto next_byte;
  2251 + case 0x2e:
  2252 + s->override = R_CS;
  2253 + goto next_byte;
  2254 + case 0x36:
  2255 + s->override = R_SS;
  2256 + goto next_byte;
  2257 + case 0x3e:
  2258 + s->override = R_DS;
  2259 + goto next_byte;
  2260 + case 0x26:
  2261 + s->override = R_ES;
  2262 + goto next_byte;
  2263 + case 0x64:
  2264 + s->override = R_FS;
  2265 + goto next_byte;
  2266 + case 0x65:
  2267 + s->override = R_GS;
  2268 + goto next_byte;
  2269 + case 0x66:
  2270 + prefixes |= PREFIX_DATA;
  2271 + goto next_byte;
  2272 + case 0x67:
  2273 + prefixes |= PREFIX_ADR;
  2274 + goto next_byte;
  2275 + case 0x40 ... 0x4f:
  2276 + /* REX prefix */
  2277 + rex_w = (b >> 3) & 1;
  2278 + rex_r = (b & 0x4) << 1;
  2279 + s->rex_x = (b & 0x2) << 2;
  2280 + REX_B(s) = (b & 0x1) << 3;
  2281 + x86_64_hregs = 1; /* select uniform byte register addressing */
  2282 + goto next_byte;
  2283 + }
  2284 + if (rex_w == 1) {
  2285 + /* 0x66 is ignored if rex.w is set */
  2286 + dflag = 2;
  2287 + } else {
  2288 + if (prefixes & PREFIX_DATA)
  2289 + dflag ^= 1;
  2290 + }
  2291 + if (!(prefixes & PREFIX_ADR))
  2292 + aflag = 2;
  2293 + } else
  2294 +#endif
  2295 + {
  2296 + switch (b) {
  2297 + case 0xf3:
  2298 + prefixes |= PREFIX_REPZ;
  2299 + goto next_byte;
  2300 + case 0xf2:
  2301 + prefixes |= PREFIX_REPNZ;
  2302 + goto next_byte;
  2303 + case 0xf0:
  2304 + prefixes |= PREFIX_LOCK;
  2305 + goto next_byte;
  2306 + case 0x2e:
  2307 + s->override = R_CS;
  2308 + goto next_byte;
  2309 + case 0x36:
  2310 + s->override = R_SS;
  2311 + goto next_byte;
  2312 + case 0x3e:
  2313 + s->override = R_DS;
  2314 + goto next_byte;
  2315 + case 0x26:
  2316 + s->override = R_ES;
  2317 + goto next_byte;
  2318 + case 0x64:
  2319 + s->override = R_FS;
  2320 + goto next_byte;
  2321 + case 0x65:
  2322 + s->override = R_GS;
  2323 + goto next_byte;
  2324 + case 0x66:
  2325 + prefixes |= PREFIX_DATA;
  2326 + goto next_byte;
  2327 + case 0x67:
  2328 + prefixes |= PREFIX_ADR;
  2329 + goto next_byte;
  2330 + }
  2331 + if (prefixes & PREFIX_DATA)
  2332 + dflag ^= 1;
  2333 + if (prefixes & PREFIX_ADR)
  2334 + aflag ^= 1;
1840 2335 }
1841 2336  
1842   - if (prefixes & PREFIX_DATA)
1843   - dflag ^= 1;
1844   - if (prefixes & PREFIX_ADR)
1845   - aflag ^= 1;
1846   -
1847 2337 s->prefix = prefixes;
1848 2338 s->aflag = aflag;
1849 2339 s->dflag = dflag;
... ... @@ -1879,14 +2369,14 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1879 2369 if ((b & 1) == 0)
1880 2370 ot = OT_BYTE;
1881 2371 else
1882   - ot = dflag ? OT_LONG : OT_WORD;
  2372 + ot = dflag + OT_WORD;
1883 2373  
1884 2374 switch(f) {
1885 2375 case 0: /* OP Ev, Gv */
1886 2376 modrm = ldub_code(s->pc++);
1887   - reg = ((modrm >> 3) & 7);
  2377 + reg = ((modrm >> 3) & 7) | rex_r;
1888 2378 mod = (modrm >> 6) & 3;
1889   - rm = modrm & 7;
  2379 + rm = (modrm & 7) | REX_B(s);
1890 2380 if (mod != 3) {
1891 2381 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1892 2382 opreg = OR_TMP0;
... ... @@ -1907,8 +2397,8 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1907 2397 case 1: /* OP Gv, Ev */
1908 2398 modrm = ldub_code(s->pc++);
1909 2399 mod = (modrm >> 6) & 3;
1910   - reg = ((modrm >> 3) & 7);
1911   - rm = modrm & 7;
  2400 + reg = ((modrm >> 3) & 7) | rex_r;
  2401 + rm = (modrm & 7) | REX_B(s);
1912 2402 if (mod != 3) {
1913 2403 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1914 2404 gen_op_ld_T1_A0[ot + s->mem_index]();
... ... @@ -1938,18 +2428,22 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1938 2428 if ((b & 1) == 0)
1939 2429 ot = OT_BYTE;
1940 2430 else
1941   - ot = dflag ? OT_LONG : OT_WORD;
  2431 + ot = dflag + OT_WORD;
1942 2432  
1943 2433 modrm = ldub_code(s->pc++);
1944 2434 mod = (modrm >> 6) & 3;
1945   - rm = modrm & 7;
  2435 + rm = (modrm & 7) | REX_B(s);
1946 2436 op = (modrm >> 3) & 7;
1947 2437  
1948 2438 if (mod != 3) {
  2439 + if (b == 0x83)
  2440 + s->rip_offset = 1;
  2441 + else
  2442 + s->rip_offset = insn_const_size(ot);
1949 2443 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1950 2444 opreg = OR_TMP0;
1951 2445 } else {
1952   - opreg = rm + OR_EAX;
  2446 + opreg = rm;
1953 2447 }
1954 2448  
1955 2449 switch(b) {
... ... @@ -1983,13 +2477,15 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1983 2477 if ((b & 1) == 0)
1984 2478 ot = OT_BYTE;
1985 2479 else
1986   - ot = dflag ? OT_LONG : OT_WORD;
  2480 + ot = dflag + OT_WORD;
1987 2481  
1988 2482 modrm = ldub_code(s->pc++);
1989 2483 mod = (modrm >> 6) & 3;
1990   - rm = modrm & 7;
  2484 + rm = (modrm & 7) | REX_B(s);
1991 2485 op = (modrm >> 3) & 7;
1992 2486 if (mod != 3) {
  2487 + if (op == 0)
  2488 + s->rip_offset = insn_const_size(ot);
1993 2489 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1994 2490 gen_op_ld_T0_A0[ot + s->mem_index]();
1995 2491 } else {
... ... @@ -2036,6 +2532,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2036 2532 gen_op_mull_EAX_T0();
2037 2533 s->cc_op = CC_OP_MULL;
2038 2534 break;
  2535 +#ifdef TARGET_X86_64
  2536 + case OT_QUAD:
  2537 + gen_op_mulq_EAX_T0();
  2538 + s->cc_op = CC_OP_MULQ;
  2539 + break;
  2540 +#endif
2039 2541 }
2040 2542 break;
2041 2543 case 5: /* imul */
... ... @@ -2053,34 +2555,58 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2053 2555 gen_op_imull_EAX_T0();
2054 2556 s->cc_op = CC_OP_MULL;
2055 2557 break;
  2558 +#ifdef TARGET_X86_64
  2559 + case OT_QUAD:
  2560 + gen_op_imulq_EAX_T0();
  2561 + s->cc_op = CC_OP_MULQ;
  2562 + break;
  2563 +#endif
2056 2564 }
2057 2565 break;
2058 2566 case 6: /* div */
2059 2567 switch(ot) {
2060 2568 case OT_BYTE:
2061   - gen_op_divb_AL_T0(pc_start - s->cs_base);
  2569 + gen_jmp_im(pc_start - s->cs_base);
  2570 + gen_op_divb_AL_T0();
2062 2571 break;
2063 2572 case OT_WORD:
2064   - gen_op_divw_AX_T0(pc_start - s->cs_base);
  2573 + gen_jmp_im(pc_start - s->cs_base);
  2574 + gen_op_divw_AX_T0();
2065 2575 break;
2066 2576 default:
2067 2577 case OT_LONG:
2068   - gen_op_divl_EAX_T0(pc_start - s->cs_base);
  2578 + gen_jmp_im(pc_start - s->cs_base);
  2579 + gen_op_divl_EAX_T0();
  2580 + break;
  2581 +#ifdef TARGET_X86_64
  2582 + case OT_QUAD:
  2583 + gen_jmp_im(pc_start - s->cs_base);
  2584 + gen_op_divq_EAX_T0();
2069 2585 break;
  2586 +#endif
2070 2587 }
2071 2588 break;
2072 2589 case 7: /* idiv */
2073 2590 switch(ot) {
2074 2591 case OT_BYTE:
2075   - gen_op_idivb_AL_T0(pc_start - s->cs_base);
  2592 + gen_jmp_im(pc_start - s->cs_base);
  2593 + gen_op_idivb_AL_T0();
2076 2594 break;
2077 2595 case OT_WORD:
2078   - gen_op_idivw_AX_T0(pc_start - s->cs_base);
  2596 + gen_jmp_im(pc_start - s->cs_base);
  2597 + gen_op_idivw_AX_T0();
2079 2598 break;
2080 2599 default:
2081 2600 case OT_LONG:
2082   - gen_op_idivl_EAX_T0(pc_start - s->cs_base);
  2601 + gen_jmp_im(pc_start - s->cs_base);
  2602 + gen_op_idivl_EAX_T0();
  2603 + break;
  2604 +#ifdef TARGET_X86_64
  2605 + case OT_QUAD:
  2606 + gen_jmp_im(pc_start - s->cs_base);
  2607 + gen_op_idivq_EAX_T0();
2083 2608 break;
  2609 +#endif
2084 2610 }
2085 2611 break;
2086 2612 default:
... ... @@ -2093,15 +2619,24 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2093 2619 if ((b & 1) == 0)
2094 2620 ot = OT_BYTE;
2095 2621 else
2096   - ot = dflag ? OT_LONG : OT_WORD;
  2622 + ot = dflag + OT_WORD;
2097 2623  
2098 2624 modrm = ldub_code(s->pc++);
2099 2625 mod = (modrm >> 6) & 3;
2100   - rm = modrm & 7;
  2626 + rm = (modrm & 7) | REX_B(s);
2101 2627 op = (modrm >> 3) & 7;
2102 2628 if (op >= 2 && b == 0xfe) {
2103 2629 goto illegal_op;
2104 2630 }
  2631 + if (CODE64(s)) {
  2632 + if (op >= 2 && op <= 5) {
  2633 + /* operand size for jumps is 64 bit */
  2634 + ot = OT_QUAD;
  2635 + } else if (op == 6) {
  2636 + /* default push size is 64 bit */
  2637 + ot = dflag ? OT_QUAD : OT_WORD;
  2638 + }
  2639 + }
2105 2640 if (mod != 3) {
2106 2641 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2107 2642 if (op >= 2 && op != 3 && op != 5)
... ... @@ -2143,7 +2678,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2143 2678 if (s->pe && !s->vm86) {
2144 2679 if (s->cc_op != CC_OP_DYNAMIC)
2145 2680 gen_op_set_cc_op(s->cc_op);
2146   - gen_op_jmp_im(pc_start - s->cs_base);
  2681 + gen_jmp_im(pc_start - s->cs_base);
2147 2682 gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base);
2148 2683 } else {
2149 2684 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
... ... @@ -2164,7 +2699,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2164 2699 if (s->pe && !s->vm86) {
2165 2700 if (s->cc_op != CC_OP_DYNAMIC)
2166 2701 gen_op_set_cc_op(s->cc_op);
2167   - gen_op_jmp_im(pc_start - s->cs_base);
  2702 + gen_jmp_im(pc_start - s->cs_base);
2168 2703 gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
2169 2704 } else {
2170 2705 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
... ... @@ -2186,15 +2721,15 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2186 2721 if ((b & 1) == 0)
2187 2722 ot = OT_BYTE;
2188 2723 else
2189   - ot = dflag ? OT_LONG : OT_WORD;
  2724 + ot = dflag + OT_WORD;
2190 2725  
2191 2726 modrm = ldub_code(s->pc++);
2192 2727 mod = (modrm >> 6) & 3;
2193   - rm = modrm & 7;
2194   - reg = (modrm >> 3) & 7;
  2728 + rm = (modrm & 7) | REX_B(s);
  2729 + reg = ((modrm >> 3) & 7) | rex_r;
2195 2730  
2196 2731 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2197   - gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
  2732 + gen_op_mov_TN_reg[ot][1][reg]();
2198 2733 gen_op_testl_T0_T1_cc();
2199 2734 s->cc_op = CC_OP_LOGICB + ot;
2200 2735 break;
... ... @@ -2204,7 +2739,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2204 2739 if ((b & 1) == 0)
2205 2740 ot = OT_BYTE;
2206 2741 else
2207   - ot = dflag ? OT_LONG : OT_WORD;
  2742 + ot = dflag + OT_WORD;
2208 2743 val = insn_get(s, ot);
2209 2744  
2210 2745 gen_op_mov_TN_reg[ot][0][OR_EAX]();
... ... @@ -2214,13 +2749,23 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2214 2749 break;
2215 2750  
2216 2751 case 0x98: /* CWDE/CBW */
2217   - if (dflag)
  2752 +#ifdef TARGET_X86_64
  2753 + if (dflag == 2) {
  2754 + gen_op_movslq_RAX_EAX();
  2755 + } else
  2756 +#endif
  2757 + if (dflag == 1)
2218 2758 gen_op_movswl_EAX_AX();
2219 2759 else
2220 2760 gen_op_movsbw_AX_AL();
2221 2761 break;
2222 2762 case 0x99: /* CDQ/CWD */
2223   - if (dflag)
  2763 +#ifdef TARGET_X86_64
  2764 + if (dflag == 2) {
  2765 + gen_op_movsqo_RDX_RAX();
  2766 + } else
  2767 +#endif
  2768 + if (dflag == 1)
2224 2769 gen_op_movslq_EDX_EAX();
2225 2770 else
2226 2771 gen_op_movswl_DX_AX();
... ... @@ -2228,9 +2773,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2228 2773 case 0x1af: /* imul Gv, Ev */
2229 2774 case 0x69: /* imul Gv, Ev, I */
2230 2775 case 0x6b:
2231   - ot = dflag ? OT_LONG : OT_WORD;
  2776 + ot = dflag + OT_WORD;
2232 2777 modrm = ldub_code(s->pc++);
2233   - reg = ((modrm >> 3) & 7) + OR_EAX;
  2778 + reg = ((modrm >> 3) & 7) | rex_r;
  2779 + if (b == 0x69)
  2780 + s->rip_offset = insn_const_size(ot);
  2781 + else if (b == 0x6b)
  2782 + s->rip_offset = 1;
2234 2783 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2235 2784 if (b == 0x69) {
2236 2785 val = insn_get(s, ot);
... ... @@ -2242,6 +2791,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2242 2791 gen_op_mov_TN_reg[ot][1][reg]();
2243 2792 }
2244 2793  
  2794 +#ifdef TARGET_X86_64
  2795 + if (ot == OT_QUAD) {
  2796 + gen_op_imulq_T0_T1();
  2797 + } else
  2798 +#endif
2245 2799 if (ot == OT_LONG) {
2246 2800 gen_op_imull_T0_T1();
2247 2801 } else {
... ... @@ -2255,12 +2809,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2255 2809 if ((b & 1) == 0)
2256 2810 ot = OT_BYTE;
2257 2811 else
2258   - ot = dflag ? OT_LONG : OT_WORD;
  2812 + ot = dflag + OT_WORD;
2259 2813 modrm = ldub_code(s->pc++);
2260   - reg = (modrm >> 3) & 7;
  2814 + reg = ((modrm >> 3) & 7) | rex_r;
2261 2815 mod = (modrm >> 6) & 3;
2262 2816 if (mod == 3) {
2263   - rm = modrm & 7;
  2817 + rm = (modrm & 7) | REX_B(s);
2264 2818 gen_op_mov_TN_reg[ot][0][reg]();
2265 2819 gen_op_mov_TN_reg[ot][1][rm]();
2266 2820 gen_op_addl_T0_T1();
... ... @@ -2282,13 +2836,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2282 2836 if ((b & 1) == 0)
2283 2837 ot = OT_BYTE;
2284 2838 else
2285   - ot = dflag ? OT_LONG : OT_WORD;
  2839 + ot = dflag + OT_WORD;
2286 2840 modrm = ldub_code(s->pc++);
2287   - reg = (modrm >> 3) & 7;
  2841 + reg = ((modrm >> 3) & 7) | rex_r;
2288 2842 mod = (modrm >> 6) & 3;
2289 2843 gen_op_mov_TN_reg[ot][1][reg]();
2290 2844 if (mod == 3) {
2291   - rm = modrm & 7;
  2845 + rm = (modrm & 7) | REX_B(s);
2292 2846 gen_op_mov_TN_reg[ot][0][rm]();
2293 2847 gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
2294 2848 gen_op_mov_reg_T0[ot][rm]();
... ... @@ -2314,25 +2868,37 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2314 2868 /**************************/
2315 2869 /* push/pop */
2316 2870 case 0x50 ... 0x57: /* push */
2317   - gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
  2871 + gen_op_mov_TN_reg[OT_LONG][0][(b & 7) | REX_B(s)]();
2318 2872 gen_push_T0(s);
2319 2873 break;
2320 2874 case 0x58 ... 0x5f: /* pop */
2321   - ot = dflag ? OT_LONG : OT_WORD;
  2875 + if (CODE64(s)) {
  2876 + ot = dflag ? OT_QUAD : OT_WORD;
  2877 + } else {
  2878 + ot = dflag + OT_WORD;
  2879 + }
2322 2880 gen_pop_T0(s);
2323 2881 /* NOTE: order is important for pop %sp */
2324 2882 gen_pop_update(s);
2325   - gen_op_mov_reg_T0[ot][b & 7]();
  2883 + gen_op_mov_reg_T0[ot][(b & 7) | REX_B(s)]();
2326 2884 break;
2327 2885 case 0x60: /* pusha */
  2886 + if (CODE64(s))
  2887 + goto illegal_op;
2328 2888 gen_pusha(s);
2329 2889 break;
2330 2890 case 0x61: /* popa */
  2891 + if (CODE64(s))
  2892 + goto illegal_op;
2331 2893 gen_popa(s);
2332 2894 break;
2333 2895 case 0x68: /* push Iv */
2334 2896 case 0x6a:
2335   - ot = dflag ? OT_LONG : OT_WORD;
  2897 + if (CODE64(s)) {
  2898 + ot = dflag ? OT_QUAD : OT_WORD;
  2899 + } else {
  2900 + ot = dflag + OT_WORD;
  2901 + }
2336 2902 if (b == 0x68)
2337 2903 val = insn_get(s, ot);
2338 2904 else
... ... @@ -2341,18 +2907,22 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2341 2907 gen_push_T0(s);
2342 2908 break;
2343 2909 case 0x8f: /* pop Ev */
2344   - ot = dflag ? OT_LONG : OT_WORD;
  2910 + if (CODE64(s)) {
  2911 + ot = dflag ? OT_QUAD : OT_WORD;
  2912 + } else {
  2913 + ot = dflag + OT_WORD;
  2914 + }
2345 2915 modrm = ldub_code(s->pc++);
2346 2916 mod = (modrm >> 6) & 3;
2347 2917 gen_pop_T0(s);
2348 2918 if (mod == 3) {
2349 2919 /* NOTE: order is important for pop %sp */
2350 2920 gen_pop_update(s);
2351   - rm = modrm & 7;
  2921 + rm = (modrm & 7) | REX_B(s);
2352 2922 gen_op_mov_reg_T0[ot][rm]();
2353 2923 } else {
2354 2924 /* NOTE: order is important too for MMU exceptions */
2355   - s->popl_esp_hack = 2 << dflag;
  2925 + s->popl_esp_hack = 1 << ot;
2356 2926 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
2357 2927 s->popl_esp_hack = 0;
2358 2928 gen_pop_update(s);
... ... @@ -2360,6 +2930,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2360 2930 break;
2361 2931 case 0xc8: /* enter */
2362 2932 {
  2933 + /* XXX: long mode support */
2363 2934 int level;
2364 2935 val = lduw_code(s->pc);
2365 2936 s->pc += 2;
... ... @@ -2369,7 +2940,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2369 2940 break;
2370 2941 case 0xc9: /* leave */
2371 2942 /* XXX: exception not precise (ESP is updated before potential exception) */
2372   - if (s->ss32) {
  2943 + /* XXX: may be invalid for 16 bit in long mode */
  2944 + if (CODE64(s)) {
  2945 + gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
  2946 + gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
  2947 + } else if (s->ss32) {
2373 2948 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2374 2949 gen_op_mov_reg_T0[OT_LONG][R_ESP]();
2375 2950 } else {
... ... @@ -2377,7 +2952,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2377 2952 gen_op_mov_reg_T0[OT_WORD][R_ESP]();
2378 2953 }
2379 2954 gen_pop_T0(s);
2380   - ot = dflag ? OT_LONG : OT_WORD;
  2955 + if (CODE64(s)) {
  2956 + ot = dflag ? OT_QUAD : OT_WORD;
  2957 + } else {
  2958 + ot = dflag + OT_WORD;
  2959 + }
2381 2960 gen_op_mov_reg_T0[ot][R_EBP]();
2382 2961 gen_pop_update(s);
2383 2962 break;
... ... @@ -2385,6 +2964,8 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2385 2964 case 0x0e: /* push cs */
2386 2965 case 0x16: /* push ss */
2387 2966 case 0x1e: /* push ds */
  2967 + if (CODE64(s))
  2968 + goto illegal_op;
2388 2969 gen_op_movl_T0_seg(b >> 3);
2389 2970 gen_push_T0(s);
2390 2971 break;
... ... @@ -2396,6 +2977,8 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2396 2977 case 0x07: /* pop es */
2397 2978 case 0x17: /* pop ss */
2398 2979 case 0x1f: /* pop ds */
  2980 + if (CODE64(s))
  2981 + goto illegal_op;
2399 2982 reg = b >> 3;
2400 2983 gen_pop_T0(s);
2401 2984 gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
... ... @@ -2409,7 +2992,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2409 2992 s->tf = 0;
2410 2993 }
2411 2994 if (s->is_jmp) {
2412   - gen_op_jmp_im(s->pc - s->cs_base);
  2995 + gen_jmp_im(s->pc - s->cs_base);
2413 2996 gen_eob(s);
2414 2997 }
2415 2998 break;
... ... @@ -2419,7 +3002,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2419 3002 gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
2420 3003 gen_pop_update(s);
2421 3004 if (s->is_jmp) {
2422   - gen_op_jmp_im(s->pc - s->cs_base);
  3005 + gen_jmp_im(s->pc - s->cs_base);
2423 3006 gen_eob(s);
2424 3007 }
2425 3008 break;
... ... @@ -2431,38 +3014,40 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2431 3014 if ((b & 1) == 0)
2432 3015 ot = OT_BYTE;
2433 3016 else
2434   - ot = dflag ? OT_LONG : OT_WORD;
  3017 + ot = dflag + OT_WORD;
2435 3018 modrm = ldub_code(s->pc++);
2436   - reg = (modrm >> 3) & 7;
  3019 + reg = ((modrm >> 3) & 7) | rex_r;
2437 3020  
2438 3021 /* generate a generic store */
2439   - gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
  3022 + gen_ldst_modrm(s, modrm, ot, reg, 1);
2440 3023 break;
2441 3024 case 0xc6:
2442 3025 case 0xc7: /* mov Ev, Iv */
2443 3026 if ((b & 1) == 0)
2444 3027 ot = OT_BYTE;
2445 3028 else
2446   - ot = dflag ? OT_LONG : OT_WORD;
  3029 + ot = dflag + OT_WORD;
2447 3030 modrm = ldub_code(s->pc++);
2448 3031 mod = (modrm >> 6) & 3;
2449   - if (mod != 3)
  3032 + if (mod != 3) {
  3033 + s->rip_offset = insn_const_size(ot);
2450 3034 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  3035 + }
2451 3036 val = insn_get(s, ot);
2452 3037 gen_op_movl_T0_im(val);
2453 3038 if (mod != 3)
2454 3039 gen_op_st_T0_A0[ot + s->mem_index]();
2455 3040 else
2456   - gen_op_mov_reg_T0[ot][modrm & 7]();
  3041 + gen_op_mov_reg_T0[ot][(modrm & 7) | REX_B(s)]();
2457 3042 break;
2458 3043 case 0x8a:
2459 3044 case 0x8b: /* mov Ev, Gv */
2460 3045 if ((b & 1) == 0)
2461 3046 ot = OT_BYTE;
2462 3047 else
2463   - ot = dflag ? OT_LONG : OT_WORD;
  3048 + ot = OT_WORD + dflag;
2464 3049 modrm = ldub_code(s->pc++);
2465   - reg = (modrm >> 3) & 7;
  3050 + reg = ((modrm >> 3) & 7) | rex_r;
2466 3051  
2467 3052 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2468 3053 gen_op_mov_reg_T0[ot][reg]();
... ... @@ -2483,7 +3068,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2483 3068 s->tf = 0;
2484 3069 }
2485 3070 if (s->is_jmp) {
2486   - gen_op_jmp_im(s->pc - s->cs_base);
  3071 + gen_jmp_im(s->pc - s->cs_base);
2487 3072 gen_eob(s);
2488 3073 }
2489 3074 break;
... ... @@ -2494,9 +3079,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2494 3079 if (reg >= 6)
2495 3080 goto illegal_op;
2496 3081 gen_op_movl_T0_seg(reg);
2497   - ot = OT_WORD;
2498   - if (mod == 3 && dflag)
2499   - ot = OT_LONG;
  3082 + if (mod == 3)
  3083 + ot = OT_WORD + dflag;
  3084 + else
  3085 + ot = OT_WORD;
2500 3086 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
2501 3087 break;
2502 3088  
... ... @@ -2511,9 +3097,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2511 3097 /* ot is the size of source */
2512 3098 ot = (b & 1) + OT_BYTE;
2513 3099 modrm = ldub_code(s->pc++);
2514   - reg = ((modrm >> 3) & 7) + OR_EAX;
  3100 + reg = ((modrm >> 3) & 7) | rex_r;
2515 3101 mod = (modrm >> 6) & 3;
2516   - rm = modrm & 7;
  3102 + rm = (modrm & 7) | REX_B(s);
2517 3103  
2518 3104 if (mod == 3) {
2519 3105 gen_op_mov_TN_reg[ot][0][rm]();
... ... @@ -2546,12 +3132,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2546 3132 break;
2547 3133  
2548 3134 case 0x8d: /* lea */
2549   - ot = dflag ? OT_LONG : OT_WORD;
  3135 + ot = dflag + OT_WORD;
2550 3136 modrm = ldub_code(s->pc++);
2551 3137 mod = (modrm >> 6) & 3;
2552 3138 if (mod == 3)
2553 3139 goto illegal_op;
2554   - reg = (modrm >> 3) & 7;
  3140 + reg = ((modrm >> 3) & 7) | rex_r;
2555 3141 /* we must ensure that no segment is added */
2556 3142 s->override = -1;
2557 3143 val = s->addseg;
... ... @@ -2565,42 +3151,67 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2565 3151 case 0xa1:
2566 3152 case 0xa2: /* mov Ov, EAX */
2567 3153 case 0xa3:
2568   - if ((b & 1) == 0)
2569   - ot = OT_BYTE;
2570   - else
2571   - ot = dflag ? OT_LONG : OT_WORD;
2572   - if (s->aflag)
2573   - offset_addr = insn_get(s, OT_LONG);
2574   - else
2575   - offset_addr = insn_get(s, OT_WORD);
2576   - gen_op_movl_A0_im(offset_addr);
2577   - /* handle override */
2578 3154 {
2579   - int override, must_add_seg;
2580   - must_add_seg = s->addseg;
2581   - if (s->override >= 0) {
2582   - override = s->override;
2583   - must_add_seg = 1;
2584   - } else {
2585   - override = R_DS;
  3155 + target_ulong offset_addr;
  3156 +
  3157 + if ((b & 1) == 0)
  3158 + ot = OT_BYTE;
  3159 + else
  3160 + ot = dflag + OT_WORD;
  3161 +#ifdef TARGET_X86_64
  3162 + if (CODE64(s)) {
  3163 + offset_addr = ldq_code(s->pc);
  3164 + s->pc += 8;
  3165 + if (offset_addr == (int32_t)offset_addr)
  3166 + gen_op_movq_A0_im(offset_addr);
  3167 + else
  3168 + gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
  3169 + } else
  3170 +#endif
  3171 + {
  3172 + if (s->aflag) {
  3173 + offset_addr = insn_get(s, OT_LONG);
  3174 + } else {
  3175 + offset_addr = insn_get(s, OT_WORD);
  3176 + }
  3177 + gen_op_movl_A0_im(offset_addr);
  3178 + }
  3179 + /* handle override */
  3180 + {
  3181 + int override, must_add_seg;
  3182 + must_add_seg = s->addseg;
  3183 + if (s->override >= 0) {
  3184 + override = s->override;
  3185 + must_add_seg = 1;
  3186 + } else {
  3187 + override = R_DS;
  3188 + }
  3189 + if (must_add_seg) {
  3190 + gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
  3191 + }
2586 3192 }
2587   - if (must_add_seg) {
2588   - gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
  3193 + if ((b & 2) == 0) {
  3194 + gen_op_ld_T0_A0[ot + s->mem_index]();
  3195 + gen_op_mov_reg_T0[ot][R_EAX]();
  3196 + } else {
  3197 + gen_op_mov_TN_reg[ot][0][R_EAX]();
  3198 + gen_op_st_T0_A0[ot + s->mem_index]();
2589 3199 }
2590 3200 }
2591   - if ((b & 2) == 0) {
2592   - gen_op_ld_T0_A0[ot + s->mem_index]();
2593   - gen_op_mov_reg_T0[ot][R_EAX]();
2594   - } else {
2595   - gen_op_mov_TN_reg[ot][0][R_EAX]();
2596   - gen_op_st_T0_A0[ot + s->mem_index]();
2597   - }
2598 3201 break;
2599 3202 case 0xd7: /* xlat */
2600   - gen_op_movl_A0_reg[R_EBX]();
2601   - gen_op_addl_A0_AL();
2602   - if (s->aflag == 0)
2603   - gen_op_andl_A0_ffff();
  3203 +#ifdef TARGET_X86_64
  3204 + if (CODE64(s)) {
  3205 + gen_op_movq_A0_reg[R_EBX]();
  3206 + gen_op_addq_A0_AL();
  3207 + } else
  3208 +#endif
  3209 + {
  3210 + gen_op_movl_A0_reg[R_EBX]();
  3211 + gen_op_addl_A0_AL();
  3212 + if (s->aflag == 0)
  3213 + gen_op_andl_A0_ffff();
  3214 + }
2604 3215 /* handle override */
2605 3216 {
2606 3217 int override, must_add_seg;
... ... @@ -2622,19 +3233,32 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2622 3233 case 0xb0 ... 0xb7: /* mov R, Ib */
2623 3234 val = insn_get(s, OT_BYTE);
2624 3235 gen_op_movl_T0_im(val);
2625   - gen_op_mov_reg_T0[OT_BYTE][b & 7]();
  3236 + gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
2626 3237 break;
2627 3238 case 0xb8 ... 0xbf: /* mov R, Iv */
2628   - ot = dflag ? OT_LONG : OT_WORD;
2629   - val = insn_get(s, ot);
2630   - reg = OR_EAX + (b & 7);
2631   - gen_op_movl_T0_im(val);
2632   - gen_op_mov_reg_T0[ot][reg]();
  3239 +#ifdef TARGET_X86_64
  3240 + if (dflag == 2) {
  3241 + uint64_t tmp;
  3242 + /* 64 bit case */
  3243 + tmp = ldq_code(s->pc);
  3244 + s->pc += 8;
  3245 + reg = (b & 7) | REX_B(s);
  3246 + gen_movtl_T0_im(tmp);
  3247 + gen_op_mov_reg_T0[OT_QUAD][reg]();
  3248 + } else
  3249 +#endif
  3250 + {
  3251 + ot = dflag ? OT_LONG : OT_WORD;
  3252 + val = insn_get(s, ot);
  3253 + reg = (b & 7) | REX_B(s);
  3254 + gen_op_movl_T0_im(val);
  3255 + gen_op_mov_reg_T0[ot][reg]();
  3256 + }
2633 3257 break;
2634 3258  
2635 3259 case 0x91 ... 0x97: /* xchg R, EAX */
2636   - ot = dflag ? OT_LONG : OT_WORD;
2637   - reg = b & 7;
  3260 + ot = dflag + OT_WORD;
  3261 + reg = (b & 7) | REX_B(s);
2638 3262 rm = R_EAX;
2639 3263 goto do_xchg_reg;
2640 3264 case 0x86:
... ... @@ -2642,12 +3266,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2642 3266 if ((b & 1) == 0)
2643 3267 ot = OT_BYTE;
2644 3268 else
2645   - ot = dflag ? OT_LONG : OT_WORD;
  3269 + ot = dflag + OT_WORD;
2646 3270 modrm = ldub_code(s->pc++);
2647   - reg = (modrm >> 3) & 7;
  3271 + reg = ((modrm >> 3) & 7) | rex_r;
2648 3272 mod = (modrm >> 6) & 3;
2649 3273 if (mod == 3) {
2650   - rm = modrm & 7;
  3274 + rm = (modrm & 7) | REX_B(s);
2651 3275 do_xchg_reg:
2652 3276 gen_op_mov_TN_reg[ot][0][reg]();
2653 3277 gen_op_mov_TN_reg[ot][1][rm]();
... ... @@ -2667,9 +3291,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2667 3291 }
2668 3292 break;
2669 3293 case 0xc4: /* les Gv */
  3294 + if (CODE64(s))
  3295 + goto illegal_op;
2670 3296 op = R_ES;
2671 3297 goto do_lxx;
2672 3298 case 0xc5: /* lds Gv */
  3299 + if (CODE64(s))
  3300 + goto illegal_op;
2673 3301 op = R_DS;
2674 3302 goto do_lxx;
2675 3303 case 0x1b2: /* lss Gv */
... ... @@ -2683,7 +3311,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2683 3311 do_lxx:
2684 3312 ot = dflag ? OT_LONG : OT_WORD;
2685 3313 modrm = ldub_code(s->pc++);
2686   - reg = (modrm >> 3) & 7;
  3314 + reg = ((modrm >> 3) & 7) | rex_r;
2687 3315 mod = (modrm >> 6) & 3;
2688 3316 if (mod == 3)
2689 3317 goto illegal_op;
... ... @@ -2696,7 +3324,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2696 3324 /* then put the data */
2697 3325 gen_op_mov_reg_T1[ot][reg]();
2698 3326 if (s->is_jmp) {
2699   - gen_op_jmp_im(s->pc - s->cs_base);
  3327 + gen_jmp_im(s->pc - s->cs_base);
2700 3328 gen_eob(s);
2701 3329 }
2702 3330 break;
... ... @@ -2712,18 +3340,20 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2712 3340 if ((b & 1) == 0)
2713 3341 ot = OT_BYTE;
2714 3342 else
2715   - ot = dflag ? OT_LONG : OT_WORD;
  3343 + ot = dflag + OT_WORD;
2716 3344  
2717 3345 modrm = ldub_code(s->pc++);
2718 3346 mod = (modrm >> 6) & 3;
2719   - rm = modrm & 7;
2720 3347 op = (modrm >> 3) & 7;
2721 3348  
2722 3349 if (mod != 3) {
  3350 + if (shift == 2) {
  3351 + s->rip_offset = 1;
  3352 + }
2723 3353 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2724 3354 opreg = OR_TMP0;
2725 3355 } else {
2726   - opreg = rm + OR_EAX;
  3356 + opreg = (modrm & 7) | REX_B(s);
2727 3357 }
2728 3358  
2729 3359 /* simpler op */
... ... @@ -2764,11 +3394,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2764 3394 op = 1;
2765 3395 shift = 0;
2766 3396 do_shiftd:
2767   - ot = dflag ? OT_LONG : OT_WORD;
  3397 + ot = dflag + OT_WORD;
2768 3398 modrm = ldub_code(s->pc++);
2769 3399 mod = (modrm >> 6) & 3;
2770   - rm = modrm & 7;
2771   - reg = (modrm >> 3) & 7;
  3400 + rm = (modrm & 7) | REX_B(s);
  3401 + reg = ((modrm >> 3) & 7) | rex_r;
2772 3402  
2773 3403 if (mod != 3) {
2774 3404 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
... ... @@ -2780,7 +3410,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2780 3410  
2781 3411 if (shift) {
2782 3412 val = ldub_code(s->pc++);
2783   - val &= 0x1f;
  3413 + if (ot == OT_QUAD)
  3414 + val &= 0x3f;
  3415 + else
  3416 + val &= 0x1f;
2784 3417 if (val) {
2785 3418 if (mod == 3)
2786 3419 gen_op_shiftd_T0_T1_im_cc[ot][op](val);
... ... @@ -2970,7 +3603,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2970 3603 /* check exceptions (FreeBSD FPU probe) */
2971 3604 if (s->cc_op != CC_OP_DYNAMIC)
2972 3605 gen_op_set_cc_op(s->cc_op);
2973   - gen_op_jmp_im(pc_start - s->cs_base);
  3606 + gen_jmp_im(pc_start - s->cs_base);
2974 3607 gen_op_fwait();
2975 3608 break;
2976 3609 default:
... ... @@ -3257,7 +3890,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3257 3890 if ((b & 1) == 0)
3258 3891 ot = OT_BYTE;
3259 3892 else
3260   - ot = dflag ? OT_LONG : OT_WORD;
  3893 + ot = dflag + OT_WORD;
3261 3894  
3262 3895 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
3263 3896 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
... ... @@ -3271,7 +3904,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3271 3904 if ((b & 1) == 0)
3272 3905 ot = OT_BYTE;
3273 3906 else
3274   - ot = dflag ? OT_LONG : OT_WORD;
  3907 + ot = dflag + OT_WORD;
3275 3908  
3276 3909 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
3277 3910 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
... ... @@ -3284,7 +3917,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3284 3917 if ((b & 1) == 0)
3285 3918 ot = OT_BYTE;
3286 3919 else
3287   - ot = dflag ? OT_LONG : OT_WORD;
  3920 + ot = dflag + OT_WORD;
3288 3921 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
3289 3922 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
3290 3923 } else {
... ... @@ -3296,7 +3929,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3296 3929 if ((b & 1) == 0)
3297 3930 ot = OT_BYTE;
3298 3931 else
3299   - ot = dflag ? OT_LONG : OT_WORD;
  3932 + ot = dflag + OT_WORD;
3300 3933 if (prefixes & PREFIX_REPNZ) {
3301 3934 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
3302 3935 } else if (prefixes & PREFIX_REPZ) {
... ... @@ -3312,7 +3945,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3312 3945 if ((b & 1) == 0)
3313 3946 ot = OT_BYTE;
3314 3947 else
3315   - ot = dflag ? OT_LONG : OT_WORD;
  3948 + ot = dflag + OT_WORD;
3316 3949 if (prefixes & PREFIX_REPNZ) {
3317 3950 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
3318 3951 } else if (prefixes & PREFIX_REPZ) {
... ... @@ -3427,7 +4060,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3427 4060 if (s->pe && !s->vm86) {
3428 4061 if (s->cc_op != CC_OP_DYNAMIC)
3429 4062 gen_op_set_cc_op(s->cc_op);
3430   - gen_op_jmp_im(pc_start - s->cs_base);
  4063 + gen_jmp_im(pc_start - s->cs_base);
3431 4064 gen_op_lret_protected(s->dflag, val);
3432 4065 } else {
3433 4066 gen_stack_A0(s);
... ... @@ -3465,7 +4098,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3465 4098 } else {
3466 4099 if (s->cc_op != CC_OP_DYNAMIC)
3467 4100 gen_op_set_cc_op(s->cc_op);
3468   - gen_op_jmp_im(pc_start - s->cs_base);
  4101 + gen_jmp_im(pc_start - s->cs_base);
3469 4102 gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
3470 4103 s->cc_op = CC_OP_EFLAGS;
3471 4104 }
... ... @@ -3473,72 +4106,79 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3473 4106 break;
3474 4107 case 0xe8: /* call im */
3475 4108 {
3476   - unsigned int next_eip;
3477   - ot = dflag ? OT_LONG : OT_WORD;
3478   - val = insn_get(s, ot);
  4109 + if (dflag)
  4110 + tval = (int32_t)insn_get(s, OT_LONG);
  4111 + else
  4112 + tval = (int16_t)insn_get(s, OT_WORD);
3479 4113 next_eip = s->pc - s->cs_base;
3480   - val += next_eip;
  4114 + tval += next_eip;
3481 4115 if (s->dflag == 0)
3482   - val &= 0xffff;
3483   - gen_op_movl_T0_im(next_eip);
  4116 + tval &= 0xffff;
  4117 + gen_movtl_T0_im(next_eip);
3484 4118 gen_push_T0(s);
3485   - gen_jmp(s, val);
  4119 + gen_jmp(s, tval);
3486 4120 }
3487 4121 break;
3488 4122 case 0x9a: /* lcall im */
3489 4123 {
3490 4124 unsigned int selector, offset;
3491   -
  4125 +
  4126 + if (CODE64(s))
  4127 + goto illegal_op;
3492 4128 ot = dflag ? OT_LONG : OT_WORD;
3493 4129 offset = insn_get(s, ot);
3494 4130 selector = insn_get(s, OT_WORD);
3495 4131  
3496 4132 gen_op_movl_T0_im(selector);
3497   - gen_op_movl_T1_im(offset);
  4133 + gen_op_movl_T1_imu(offset);
3498 4134 }
3499 4135 goto do_lcall;
3500 4136 case 0xe9: /* jmp */
3501   - ot = dflag ? OT_LONG : OT_WORD;
3502   - val = insn_get(s, ot);
3503   - val += s->pc - s->cs_base;
  4137 + if (dflag)
  4138 + tval = (int32_t)insn_get(s, OT_LONG);
  4139 + else
  4140 + tval = (int16_t)insn_get(s, OT_WORD);
  4141 + tval += s->pc - s->cs_base;
3504 4142 if (s->dflag == 0)
3505   - val = val & 0xffff;
3506   - gen_jmp(s, val);
  4143 + tval &= 0xffff;
  4144 + gen_jmp(s, tval);
3507 4145 break;
3508 4146 case 0xea: /* ljmp im */
3509 4147 {
3510 4148 unsigned int selector, offset;
3511 4149  
  4150 + if (CODE64(s))
  4151 + goto illegal_op;
3512 4152 ot = dflag ? OT_LONG : OT_WORD;
3513 4153 offset = insn_get(s, ot);
3514 4154 selector = insn_get(s, OT_WORD);
3515 4155  
3516 4156 gen_op_movl_T0_im(selector);
3517   - gen_op_movl_T1_im(offset);
  4157 + gen_op_movl_T1_imu(offset);
3518 4158 }
3519 4159 goto do_ljmp;
3520 4160 case 0xeb: /* jmp Jb */
3521   - val = (int8_t)insn_get(s, OT_BYTE);
3522   - val += s->pc - s->cs_base;
  4161 + tval = (int8_t)insn_get(s, OT_BYTE);
  4162 + tval += s->pc - s->cs_base;
3523 4163 if (s->dflag == 0)
3524   - val = val & 0xffff;
3525   - gen_jmp(s, val);
  4164 + tval &= 0xffff;
  4165 + gen_jmp(s, tval);
3526 4166 break;
3527 4167 case 0x70 ... 0x7f: /* jcc Jb */
3528   - val = (int8_t)insn_get(s, OT_BYTE);
  4168 + tval = (int8_t)insn_get(s, OT_BYTE);
3529 4169 goto do_jcc;
3530 4170 case 0x180 ... 0x18f: /* jcc Jv */
3531 4171 if (dflag) {
3532   - val = insn_get(s, OT_LONG);
  4172 + tval = (int32_t)insn_get(s, OT_LONG);
3533 4173 } else {
3534   - val = (int16_t)insn_get(s, OT_WORD);
  4174 + tval = (int16_t)insn_get(s, OT_WORD);
3535 4175 }
3536 4176 do_jcc:
3537 4177 next_eip = s->pc - s->cs_base;
3538   - val += next_eip;
  4178 + tval += next_eip;
3539 4179 if (s->dflag == 0)
3540   - val &= 0xffff;
3541   - gen_jcc(s, b, val, next_eip);
  4180 + tval &= 0xffff;
  4181 + gen_jcc(s, b, tval, next_eip);
3542 4182 break;
3543 4183  
3544 4184 case 0x190 ... 0x19f: /* setcc Gv */
... ... @@ -3547,16 +4187,16 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3547 4187 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
3548 4188 break;
3549 4189 case 0x140 ... 0x14f: /* cmov Gv, Ev */
3550   - ot = dflag ? OT_LONG : OT_WORD;
  4190 + ot = dflag + OT_WORD;
3551 4191 modrm = ldub_code(s->pc++);
3552   - reg = (modrm >> 3) & 7;
  4192 + reg = ((modrm >> 3) & 7) | rex_r;
3553 4193 mod = (modrm >> 6) & 3;
3554 4194 gen_setcc(s, b);
3555 4195 if (mod != 3) {
3556 4196 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3557 4197 gen_op_ld_T1_A0[ot + s->mem_index]();
3558 4198 } else {
3559   - rm = modrm & 7;
  4199 + rm = (modrm & 7) | REX_B(s);
3560 4200 gen_op_mov_TN_reg[ot][1][rm]();
3561 4201 }
3562 4202 gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
... ... @@ -3603,11 +4243,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3603 4243 gen_pop_update(s);
3604 4244 s->cc_op = CC_OP_EFLAGS;
3605 4245 /* abort translation because TF flag may change */
3606   - gen_op_jmp_im(s->pc - s->cs_base);
  4246 + gen_jmp_im(s->pc - s->cs_base);
3607 4247 gen_eob(s);
3608 4248 }
3609 4249 break;
3610 4250 case 0x9e: /* sahf */
  4251 + if (CODE64(s))
  4252 + goto illegal_op;
3611 4253 gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
3612 4254 if (s->cc_op != CC_OP_DYNAMIC)
3613 4255 gen_op_set_cc_op(s->cc_op);
... ... @@ -3615,6 +4257,8 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3615 4257 s->cc_op = CC_OP_EFLAGS;
3616 4258 break;
3617 4259 case 0x9f: /* lahf */
  4260 + if (CODE64(s))
  4261 + goto illegal_op;
3618 4262 if (s->cc_op != CC_OP_DYNAMIC)
3619 4263 gen_op_set_cc_op(s->cc_op);
3620 4264 gen_op_movl_T0_eflags();
... ... @@ -3648,12 +4292,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3648 4292 /************************/
3649 4293 /* bit operations */
3650 4294 case 0x1ba: /* bt/bts/btr/btc Gv, im */
3651   - ot = dflag ? OT_LONG : OT_WORD;
  4295 + ot = dflag + OT_WORD;
3652 4296 modrm = ldub_code(s->pc++);
3653   - op = (modrm >> 3) & 7;
  4297 + op = ((modrm >> 3) & 7) | rex_r;
3654 4298 mod = (modrm >> 6) & 3;
3655   - rm = modrm & 7;
  4299 + rm = (modrm & 7) | REX_B(s);
3656 4300 if (mod != 3) {
  4301 + s->rip_offset = 1;
3657 4302 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3658 4303 gen_op_ld_T0_A0[ot + s->mem_index]();
3659 4304 } else {
... ... @@ -3687,19 +4332,16 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3687 4332 case 0x1bb: /* btc */
3688 4333 op = 3;
3689 4334 do_btx:
3690   - ot = dflag ? OT_LONG : OT_WORD;
  4335 + ot = dflag + OT_WORD;
3691 4336 modrm = ldub_code(s->pc++);
3692   - reg = (modrm >> 3) & 7;
  4337 + reg = ((modrm >> 3) & 7) | rex_r;
3693 4338 mod = (modrm >> 6) & 3;
3694   - rm = modrm & 7;
  4339 + rm = (modrm & 7) | REX_B(s);
3695 4340 gen_op_mov_TN_reg[OT_LONG][1][reg]();
3696 4341 if (mod != 3) {
3697 4342 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3698 4343 /* specific case: we need to add a displacement */
3699   - if (ot == OT_WORD)
3700   - gen_op_add_bitw_A0_T1();
3701   - else
3702   - gen_op_add_bitl_A0_T1();
  4344 + gen_op_add_bit_A0_T1[ot - OT_WORD]();
3703 4345 gen_op_ld_T0_A0[ot + s->mem_index]();
3704 4346 } else {
3705 4347 gen_op_mov_TN_reg[ot][0][rm]();
... ... @@ -3716,9 +4358,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3716 4358 break;
3717 4359 case 0x1bc: /* bsf */
3718 4360 case 0x1bd: /* bsr */
3719   - ot = dflag ? OT_LONG : OT_WORD;
  4361 + ot = dflag + OT_WORD;
3720 4362 modrm = ldub_code(s->pc++);
3721   - reg = (modrm >> 3) & 7;
  4363 + reg = ((modrm >> 3) & 7) | rex_r;
3722 4364 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3723 4365 /* NOTE: in order to handle the 0 case, we must load the
3724 4366 result. It could be optimized with a generated jump */
... ... @@ -3730,35 +4372,47 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3730 4372 /************************/
3731 4373 /* bcd */
3732 4374 case 0x27: /* daa */
  4375 + if (CODE64(s))
  4376 + goto illegal_op;
3733 4377 if (s->cc_op != CC_OP_DYNAMIC)
3734 4378 gen_op_set_cc_op(s->cc_op);
3735 4379 gen_op_daa();
3736 4380 s->cc_op = CC_OP_EFLAGS;
3737 4381 break;
3738 4382 case 0x2f: /* das */
  4383 + if (CODE64(s))
  4384 + goto illegal_op;
3739 4385 if (s->cc_op != CC_OP_DYNAMIC)
3740 4386 gen_op_set_cc_op(s->cc_op);
3741 4387 gen_op_das();
3742 4388 s->cc_op = CC_OP_EFLAGS;
3743 4389 break;
3744 4390 case 0x37: /* aaa */
  4391 + if (CODE64(s))
  4392 + goto illegal_op;
3745 4393 if (s->cc_op != CC_OP_DYNAMIC)
3746 4394 gen_op_set_cc_op(s->cc_op);
3747 4395 gen_op_aaa();
3748 4396 s->cc_op = CC_OP_EFLAGS;
3749 4397 break;
3750 4398 case 0x3f: /* aas */
  4399 + if (CODE64(s))
  4400 + goto illegal_op;
3751 4401 if (s->cc_op != CC_OP_DYNAMIC)
3752 4402 gen_op_set_cc_op(s->cc_op);
3753 4403 gen_op_aas();
3754 4404 s->cc_op = CC_OP_EFLAGS;
3755 4405 break;
3756 4406 case 0xd4: /* aam */
  4407 + if (CODE64(s))
  4408 + goto illegal_op;
3757 4409 val = ldub_code(s->pc++);
3758 4410 gen_op_aam(val);
3759 4411 s->cc_op = CC_OP_LOGICB;
3760 4412 break;
3761 4413 case 0xd5: /* aad */
  4414 + if (CODE64(s))
  4415 + goto illegal_op;
3762 4416 val = ldub_code(s->pc++);
3763 4417 gen_op_aad(val);
3764 4418 s->cc_op = CC_OP_LOGICB;
... ... @@ -3766,6 +4420,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3766 4420 /************************/
3767 4421 /* misc */
3768 4422 case 0x90: /* nop */
  4423 + /* XXX: xchg + rex handling */
3769 4424 /* XXX: correct lock test for all insn */
3770 4425 if (prefixes & PREFIX_LOCK)
3771 4426 goto illegal_op;
... ... @@ -3777,7 +4432,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3777 4432 } else {
3778 4433 if (s->cc_op != CC_OP_DYNAMIC)
3779 4434 gen_op_set_cc_op(s->cc_op);
3780   - gen_op_jmp_im(pc_start - s->cs_base);
  4435 + gen_jmp_im(pc_start - s->cs_base);
3781 4436 gen_op_fwait();
3782 4437 }
3783 4438 break;
... ... @@ -3793,12 +4448,19 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3793 4448 }
3794 4449 break;
3795 4450 case 0xce: /* into */
  4451 + if (CODE64(s))
  4452 + goto illegal_op;
3796 4453 if (s->cc_op != CC_OP_DYNAMIC)
3797 4454 gen_op_set_cc_op(s->cc_op);
3798 4455 gen_op_into(s->pc - s->cs_base);
3799 4456 break;
3800 4457 case 0xf1: /* icebp (undocumented, exits to external debugger) */
  4458 +#if 0
3801 4459 gen_debug(s, pc_start - s->cs_base);
  4460 +#else
  4461 + /* test ! */
  4462 + cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_PCALL);
  4463 +#endif
3802 4464 break;
3803 4465 case 0xfa: /* cli */
3804 4466 if (!s->vm86) {
... ... @@ -3826,7 +4488,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3826 4488 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
3827 4489 gen_op_set_inhibit_irq();
3828 4490 /* give a chance to handle pending irqs */
3829   - gen_op_jmp_im(s->pc - s->cs_base);
  4491 + gen_jmp_im(s->pc - s->cs_base);
3830 4492 gen_eob(s);
3831 4493 } else {
3832 4494 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
... ... @@ -3840,6 +4502,8 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3840 4502 }
3841 4503 break;
3842 4504 case 0x62: /* bound */
  4505 + if (CODE64(s))
  4506 + goto illegal_op;
3843 4507 ot = dflag ? OT_LONG : OT_WORD;
3844 4508 modrm = ldub_code(s->pc++);
3845 4509 reg = (modrm >> 3) & 7;
... ... @@ -3848,18 +4512,30 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3848 4512 goto illegal_op;
3849 4513 gen_op_mov_TN_reg[ot][0][reg]();
3850 4514 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  4515 + gen_jmp_im(pc_start - s->cs_base);
3851 4516 if (ot == OT_WORD)
3852   - gen_op_boundw(pc_start - s->cs_base);
  4517 + gen_op_boundw();
3853 4518 else
3854   - gen_op_boundl(pc_start - s->cs_base);
  4519 + gen_op_boundl();
3855 4520 break;
3856 4521 case 0x1c8 ... 0x1cf: /* bswap reg */
3857   - reg = b & 7;
3858   - gen_op_mov_TN_reg[OT_LONG][0][reg]();
3859   - gen_op_bswapl_T0();
3860   - gen_op_mov_reg_T0[OT_LONG][reg]();
  4522 + reg = (b & 7) | REX_B(s);
  4523 +#ifdef TARGET_X86_64
  4524 + if (dflag == 2) {
  4525 + gen_op_mov_TN_reg[OT_QUAD][0][reg]();
  4526 + gen_op_bswapq_T0();
  4527 + gen_op_mov_reg_T0[OT_QUAD][reg]();
  4528 + } else
  4529 +#endif
  4530 + {
  4531 + gen_op_mov_TN_reg[OT_LONG][0][reg]();
  4532 + gen_op_bswapl_T0();
  4533 + gen_op_mov_reg_T0[OT_LONG][reg]();
  4534 + }
3861 4535 break;
3862 4536 case 0xd6: /* salc */
  4537 + if (CODE64(s))
  4538 + goto illegal_op;
3863 4539 if (s->cc_op != CC_OP_DYNAMIC)
3864 4540 gen_op_set_cc_op(s->cc_op);
3865 4541 gen_op_salc();
... ... @@ -3871,13 +4547,32 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3871 4547 /* FALL THRU */
3872 4548 case 0xe2: /* loop */
3873 4549 case 0xe3: /* jecxz */
3874   - val = (int8_t)insn_get(s, OT_BYTE);
3875   - next_eip = s->pc - s->cs_base;
3876   - val += next_eip;
3877   - if (s->dflag == 0)
3878   - val &= 0xffff;
3879   - gen_op_loop[s->aflag][b & 3](val, next_eip);
3880   - gen_eob(s);
  4550 + {
  4551 + int l1, l2;
  4552 +
  4553 + tval = (int8_t)insn_get(s, OT_BYTE);
  4554 + next_eip = s->pc - s->cs_base;
  4555 + tval += next_eip;
  4556 + if (s->dflag == 0)
  4557 + tval &= 0xffff;
  4558 +
  4559 + l1 = gen_new_label();
  4560 + l2 = gen_new_label();
  4561 + b &= 3;
  4562 + if (b == 3) {
  4563 + gen_op_jz_ecx[s->aflag](l1);
  4564 + } else {
  4565 + gen_op_dec_ECX[s->aflag]();
  4566 + gen_op_loop[s->aflag][b](l1);
  4567 + }
  4568 +
  4569 + gen_jmp_im(next_eip);
  4570 + gen_op_jmp_label(l2);
  4571 + gen_set_label(l1);
  4572 + gen_jmp_im(tval);
  4573 + gen_set_label(l2);
  4574 + gen_eob(s);
  4575 + }
3881 4576 break;
3882 4577 case 0x130: /* wrmsr */
3883 4578 case 0x132: /* rdmsr */
... ... @@ -3894,6 +4589,8 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3894 4589 gen_op_rdtsc();
3895 4590 break;
3896 4591 case 0x134: /* sysenter */
  4592 + if (CODE64(s))
  4593 + goto illegal_op;
3897 4594 if (!s->pe) {
3898 4595 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3899 4596 } else {
... ... @@ -3901,12 +4598,14 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3901 4598 gen_op_set_cc_op(s->cc_op);
3902 4599 s->cc_op = CC_OP_DYNAMIC;
3903 4600 }
3904   - gen_op_jmp_im(pc_start - s->cs_base);
  4601 + gen_jmp_im(pc_start - s->cs_base);
3905 4602 gen_op_sysenter();
3906 4603 gen_eob(s);
3907 4604 }
3908 4605 break;
3909 4606 case 0x135: /* sysexit */
  4607 + if (CODE64(s))
  4608 + goto illegal_op;
3910 4609 if (!s->pe) {
3911 4610 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3912 4611 } else {
... ... @@ -3914,11 +4613,36 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3914 4613 gen_op_set_cc_op(s->cc_op);
3915 4614 s->cc_op = CC_OP_DYNAMIC;
3916 4615 }
3917   - gen_op_jmp_im(pc_start - s->cs_base);
  4616 + gen_jmp_im(pc_start - s->cs_base);
3918 4617 gen_op_sysexit();
3919 4618 gen_eob(s);
3920 4619 }
3921 4620 break;
  4621 +#ifdef TARGET_X86_64
  4622 + case 0x105: /* syscall */
  4623 + /* XXX: is it usable in real mode ? */
  4624 + if (s->cc_op != CC_OP_DYNAMIC) {
  4625 + gen_op_set_cc_op(s->cc_op);
  4626 + s->cc_op = CC_OP_DYNAMIC;
  4627 + }
  4628 + gen_jmp_im(pc_start - s->cs_base);
  4629 + gen_op_syscall();
  4630 + gen_eob(s);
  4631 + break;
  4632 + case 0x107: /* sysret */
  4633 + if (!s->pe) {
  4634 + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
  4635 + } else {
  4636 + if (s->cc_op != CC_OP_DYNAMIC) {
  4637 + gen_op_set_cc_op(s->cc_op);
  4638 + s->cc_op = CC_OP_DYNAMIC;
  4639 + }
  4640 + gen_jmp_im(pc_start - s->cs_base);
  4641 + gen_op_sysret(s->dflag);
  4642 + gen_eob(s);
  4643 + }
  4644 + break;
  4645 +#endif
3922 4646 case 0x1a2: /* cpuid */
3923 4647 gen_op_cpuid();
3924 4648 break;
... ... @@ -3928,7 +4652,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3928 4652 } else {
3929 4653 if (s->cc_op != CC_OP_DYNAMIC)
3930 4654 gen_op_set_cc_op(s->cc_op);
3931   - gen_op_jmp_im(s->pc - s->cs_base);
  4655 + gen_jmp_im(s->pc - s->cs_base);
3932 4656 gen_op_hlt();
3933 4657 s->is_jmp = 3;
3934 4658 }
... ... @@ -3954,7 +4678,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3954 4678 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3955 4679 } else {
3956 4680 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3957   - gen_op_jmp_im(pc_start - s->cs_base);
  4681 + gen_jmp_im(pc_start - s->cs_base);
3958 4682 gen_op_lldt_T0();
3959 4683 }
3960 4684 break;
... ... @@ -3974,7 +4698,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3974 4698 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3975 4699 } else {
3976 4700 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3977   - gen_op_jmp_im(pc_start - s->cs_base);
  4701 + gen_jmp_im(pc_start - s->cs_base);
3978 4702 gen_op_ltr_T0();
3979 4703 }
3980 4704 break;
... ... @@ -4010,14 +4734,19 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4010 4734 else
4011 4735 gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit));
4012 4736 gen_op_st_T0_A0[OT_WORD + s->mem_index]();
4013   - gen_op_addl_A0_im(2);
  4737 +#ifdef TARGET_X86_64
  4738 + if (CODE64(s))
  4739 + gen_op_addq_A0_im(2);
  4740 + else
  4741 +#endif
  4742 + gen_op_addl_A0_im(2);
4014 4743 if (op == 0)
4015   - gen_op_movl_T0_env(offsetof(CPUX86State,gdt.base));
  4744 + gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base));
4016 4745 else
4017   - gen_op_movl_T0_env(offsetof(CPUX86State,idt.base));
  4746 + gen_op_movtl_T0_env(offsetof(CPUX86State,idt.base));
4018 4747 if (!s->dflag)
4019 4748 gen_op_andl_T0_im(0xffffff);
4020   - gen_op_st_T0_A0[OT_LONG + s->mem_index]();
  4749 + gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
4021 4750 break;
4022 4751 case 2: /* lgdt */
4023 4752 case 3: /* lidt */
... ... @@ -4028,15 +4757,20 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4028 4757 } else {
4029 4758 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4030 4759 gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
4031   - gen_op_addl_A0_im(2);
4032   - gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
  4760 +#ifdef TARGET_X86_64
  4761 + if (CODE64(s))
  4762 + gen_op_addq_A0_im(2);
  4763 + else
  4764 +#endif
  4765 + gen_op_addl_A0_im(2);
  4766 + gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
4033 4767 if (!s->dflag)
4034 4768 gen_op_andl_T0_im(0xffffff);
4035 4769 if (op == 2) {
4036   - gen_op_movl_env_T0(offsetof(CPUX86State,gdt.base));
  4770 + gen_op_movtl_env_T0(offsetof(CPUX86State,gdt.base));
4037 4771 gen_op_movl_env_T1(offsetof(CPUX86State,gdt.limit));
4038 4772 } else {
4039   - gen_op_movl_env_T0(offsetof(CPUX86State,idt.base));
  4773 + gen_op_movtl_env_T0(offsetof(CPUX86State,idt.base));
4040 4774 gen_op_movl_env_T1(offsetof(CPUX86State,idt.limit));
4041 4775 }
4042 4776 }
... ... @@ -4051,7 +4785,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4051 4785 } else {
4052 4786 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
4053 4787 gen_op_lmsw_T0();
4054   - gen_op_jmp_im(s->pc - s->cs_base);
  4788 + gen_jmp_im(s->pc - s->cs_base);
4055 4789 gen_eob(s);
4056 4790 }
4057 4791 break;
... ... @@ -4059,12 +4793,25 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4059 4793 if (s->cpl != 0) {
4060 4794 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4061 4795 } else {
4062   - if (mod == 3)
4063   - goto illegal_op;
4064   - gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4065   - gen_op_invlpg_A0();
4066   - gen_op_jmp_im(s->pc - s->cs_base);
4067   - gen_eob(s);
  4796 + if (mod == 3) {
  4797 +#ifdef TARGET_X86_64
  4798 + if (CODE64(s) && (modrm & 7) == 0) {
  4799 + /* swapgs */
  4800 + gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
  4801 + gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
  4802 + gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
  4803 + gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
  4804 + } else
  4805 +#endif
  4806 + {
  4807 + goto illegal_op;
  4808 + }
  4809 + } else {
  4810 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  4811 + gen_op_invlpg_A0();
  4812 + gen_jmp_im(s->pc - s->cs_base);
  4813 + gen_eob(s);
  4814 + }
4068 4815 }
4069 4816 break;
4070 4817 default:
... ... @@ -4079,30 +4826,87 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4079 4826 /* nothing to do */
4080 4827 }
4081 4828 break;
4082   - case 0x63: /* arpl */
4083   - if (!s->pe || s->vm86)
4084   - goto illegal_op;
4085   - ot = dflag ? OT_LONG : OT_WORD;
  4829 + case 0x1ae: /* sfence */
4086 4830 modrm = ldub_code(s->pc++);
4087   - reg = (modrm >> 3) & 7;
4088 4831 mod = (modrm >> 6) & 3;
4089   - rm = modrm & 7;
4090   - if (mod != 3) {
  4832 + op = (modrm >> 3) & 7;
  4833 + switch(op) {
  4834 + case 0: /* fxsave */
  4835 + if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
  4836 + goto illegal_op;
4091 4837 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4092   - gen_op_ld_T0_A0[ot + s->mem_index]();
4093   - } else {
4094   - gen_op_mov_TN_reg[ot][0][rm]();
  4838 + gen_op_fxsave_A0((s->dflag == 2));
  4839 + break;
  4840 + case 1: /* fxrstor */
  4841 + if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
  4842 + goto illegal_op;
  4843 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  4844 + gen_op_fxrstor_A0((s->dflag == 2));
  4845 + break;
  4846 + case 5: /* lfence */
  4847 + case 6: /* mfence */
  4848 + case 7: /* sfence */
  4849 + if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
  4850 + goto illegal_op;
  4851 + break;
  4852 + default:
  4853 + goto illegal_op;
4095 4854 }
4096   - if (s->cc_op != CC_OP_DYNAMIC)
4097   - gen_op_set_cc_op(s->cc_op);
4098   - gen_op_arpl();
4099   - s->cc_op = CC_OP_EFLAGS;
4100   - if (mod != 3) {
4101   - gen_op_st_T0_A0[ot + s->mem_index]();
4102   - } else {
4103   - gen_op_mov_reg_T0[ot][rm]();
  4855 + break;
  4856 + case 0x63: /* arpl or movslS (x86_64) */
  4857 +#ifdef TARGET_X86_64
  4858 + if (CODE64(s)) {
  4859 + int d_ot;
  4860 + /* d_ot is the size of destination */
  4861 + d_ot = dflag + OT_WORD;
  4862 +
  4863 + modrm = ldub_code(s->pc++);
  4864 + reg = ((modrm >> 3) & 7) | rex_r;
  4865 + mod = (modrm >> 6) & 3;
  4866 + rm = (modrm & 7) | REX_B(s);
  4867 +
  4868 + if (mod == 3) {
  4869 + gen_op_mov_TN_reg[OT_LONG][0][rm]();
  4870 + /* sign extend */
  4871 + if (d_ot == OT_QUAD)
  4872 + gen_op_movslq_T0_T0();
  4873 + gen_op_mov_reg_T0[d_ot][reg]();
  4874 + } else {
  4875 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  4876 + if (d_ot == OT_QUAD) {
  4877 + gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
  4878 + } else {
  4879 + gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
  4880 + }
  4881 + gen_op_mov_reg_T0[d_ot][reg]();
  4882 + }
  4883 + } else
  4884 +#endif
  4885 + {
  4886 + if (!s->pe || s->vm86)
  4887 + goto illegal_op;
  4888 + ot = dflag ? OT_LONG : OT_WORD;
  4889 + modrm = ldub_code(s->pc++);
  4890 + reg = (modrm >> 3) & 7;
  4891 + mod = (modrm >> 6) & 3;
  4892 + rm = modrm & 7;
  4893 + if (mod != 3) {
  4894 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  4895 + gen_op_ld_T0_A0[ot + s->mem_index]();
  4896 + } else {
  4897 + gen_op_mov_TN_reg[ot][0][rm]();
  4898 + }
  4899 + if (s->cc_op != CC_OP_DYNAMIC)
  4900 + gen_op_set_cc_op(s->cc_op);
  4901 + gen_op_arpl();
  4902 + s->cc_op = CC_OP_EFLAGS;
  4903 + if (mod != 3) {
  4904 + gen_op_st_T0_A0[ot + s->mem_index]();
  4905 + } else {
  4906 + gen_op_mov_reg_T0[ot][rm]();
  4907 + }
  4908 + gen_op_arpl_update();
4104 4909 }
4105   - gen_op_arpl_update();
4106 4910 break;
4107 4911 case 0x102: /* lar */
4108 4912 case 0x103: /* lsl */
... ... @@ -4110,7 +4914,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4110 4914 goto illegal_op;
4111 4915 ot = dflag ? OT_LONG : OT_WORD;
4112 4916 modrm = ldub_code(s->pc++);
4113   - reg = (modrm >> 3) & 7;
  4917 + reg = ((modrm >> 3) & 7) | rex_r;
4114 4918 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4115 4919 gen_op_mov_TN_reg[ot][1][reg]();
4116 4920 if (s->cc_op != CC_OP_DYNAMIC)
... ... @@ -4148,23 +4952,28 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4148 4952 modrm = ldub_code(s->pc++);
4149 4953 if ((modrm & 0xc0) != 0xc0)
4150 4954 goto illegal_op;
4151   - rm = modrm & 7;
4152   - reg = (modrm >> 3) & 7;
  4955 + rm = (modrm & 7) | REX_B(s);
  4956 + reg = ((modrm >> 3) & 7) | rex_r;
  4957 + if (CODE64(s))
  4958 + ot = OT_QUAD;
  4959 + else
  4960 + ot = OT_LONG;
4153 4961 switch(reg) {
4154 4962 case 0:
4155 4963 case 2:
4156 4964 case 3:
4157 4965 case 4:
4158 4966 if (b & 2) {
4159   - gen_op_mov_TN_reg[OT_LONG][0][rm]();
  4967 + gen_op_mov_TN_reg[ot][0][rm]();
4160 4968 gen_op_movl_crN_T0(reg);
4161   - gen_op_jmp_im(s->pc - s->cs_base);
  4969 + gen_jmp_im(s->pc - s->cs_base);
4162 4970 gen_eob(s);
4163 4971 } else {
4164   - gen_op_movl_T0_env(offsetof(CPUX86State,cr[reg]));
4165   - gen_op_mov_reg_T0[OT_LONG][rm]();
  4972 + gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
  4973 + gen_op_mov_reg_T0[ot][rm]();
4166 4974 }
4167 4975 break;
  4976 + /* XXX: add CR8 for x86_64 */
4168 4977 default:
4169 4978 goto illegal_op;
4170 4979 }
... ... @@ -4178,19 +4987,23 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4178 4987 modrm = ldub_code(s->pc++);
4179 4988 if ((modrm & 0xc0) != 0xc0)
4180 4989 goto illegal_op;
4181   - rm = modrm & 7;
4182   - reg = (modrm >> 3) & 7;
  4990 + rm = (modrm & 7) | REX_B(s);
  4991 + reg = ((modrm >> 3) & 7) | rex_r;
  4992 + if (CODE64(s))
  4993 + ot = OT_QUAD;
  4994 + else
  4995 + ot = OT_LONG;
4183 4996 /* XXX: do it dynamically with CR4.DE bit */
4184   - if (reg == 4 || reg == 5)
  4997 + if (reg == 4 || reg == 5 || reg >= 8)
4185 4998 goto illegal_op;
4186 4999 if (b & 2) {
4187   - gen_op_mov_TN_reg[OT_LONG][0][rm]();
  5000 + gen_op_mov_TN_reg[ot][0][rm]();
4188 5001 gen_op_movl_drN_T0(reg);
4189   - gen_op_jmp_im(s->pc - s->cs_base);
  5002 + gen_jmp_im(s->pc - s->cs_base);
4190 5003 gen_eob(s);
4191 5004 } else {
4192   - gen_op_movl_T0_env(offsetof(CPUX86State,dr[reg]));
4193   - gen_op_mov_reg_T0[OT_LONG][rm]();
  5005 + gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
  5006 + gen_op_mov_reg_T0[ot][rm]();
4194 5007 }
4195 5008 }
4196 5009 break;
... ... @@ -4200,10 +5013,69 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4200 5013 } else {
4201 5014 gen_op_clts();
4202 5015 /* abort block because static cpu state changed */
4203   - gen_op_jmp_im(s->pc - s->cs_base);
  5016 + gen_jmp_im(s->pc - s->cs_base);
4204 5017 gen_eob(s);
4205 5018 }
4206 5019 break;
  5020 + /* SSE support */
  5021 + case 0x16f:
  5022 + if (prefixes & PREFIX_DATA) {
  5023 + /* movdqa xmm1, xmm2/mem128 */
  5024 + if (!(s->cpuid_features & CPUID_SSE))
  5025 + goto illegal_op;
  5026 + modrm = ldub_code(s->pc++);
  5027 + reg = ((modrm >> 3) & 7) | rex_r;
  5028 + mod = (modrm >> 6) & 3;
  5029 + if (mod != 3) {
  5030 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  5031 + gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
  5032 + } else {
  5033 + rm = (modrm & 7) | REX_B(s);
  5034 + gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
  5035 + offsetof(CPUX86State,xmm_regs[rm]));
  5036 + }
  5037 + } else {
  5038 + goto illegal_op;
  5039 + }
  5040 + break;
  5041 + case 0x1e7:
  5042 + if (prefixes & PREFIX_DATA) {
  5043 + /* movntdq mem128, xmm1 */
  5044 + if (!(s->cpuid_features & CPUID_SSE))
  5045 + goto illegal_op;
  5046 + modrm = ldub_code(s->pc++);
  5047 + reg = ((modrm >> 3) & 7) | rex_r;
  5048 + mod = (modrm >> 6) & 3;
  5049 + if (mod != 3) {
  5050 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  5051 + gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
  5052 + } else {
  5053 + goto illegal_op;
  5054 + }
  5055 + } else {
  5056 + goto illegal_op;
  5057 + }
  5058 + break;
  5059 + case 0x17f:
  5060 + if (prefixes & PREFIX_DATA) {
  5061 + /* movdqa xmm2/mem128, xmm1 */
  5062 + if (!(s->cpuid_features & CPUID_SSE))
  5063 + goto illegal_op;
  5064 + modrm = ldub_code(s->pc++);
  5065 + reg = ((modrm >> 3) & 7) | rex_r;
  5066 + mod = (modrm >> 6) & 3;
  5067 + if (mod != 3) {
  5068 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
  5069 + gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
  5070 + } else {
  5071 + rm = (modrm & 7) | REX_B(s);
  5072 + gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
  5073 + offsetof(CPUX86State,xmm_regs[reg]));
  5074 + }
  5075 + } else {
  5076 + goto illegal_op;
  5077 + }
  5078 + break;
4207 5079 default:
4208 5080 goto illegal_op;
4209 5081 }
... ... @@ -4301,26 +5173,51 @@ static uint16_t opc_read_flags[NB_OPS] = {
4301 5173 [INDEX_op_salc] = CC_C,
4302 5174  
4303 5175 /* needed for correct flag optimisation before string ops */
  5176 + [INDEX_op_jnz_ecxw] = CC_OSZAPC,
  5177 + [INDEX_op_jnz_ecxl] = CC_OSZAPC,
4304 5178 [INDEX_op_jz_ecxw] = CC_OSZAPC,
4305 5179 [INDEX_op_jz_ecxl] = CC_OSZAPC,
4306   - [INDEX_op_jz_ecxw_im] = CC_OSZAPC,
4307   - [INDEX_op_jz_ecxl_im] = CC_OSZAPC,
  5180 +
  5181 +#ifdef TARGET_X86_64
  5182 + [INDEX_op_jb_subq] = CC_C,
  5183 + [INDEX_op_jz_subq] = CC_Z,
  5184 + [INDEX_op_jbe_subq] = CC_Z | CC_C,
  5185 + [INDEX_op_js_subq] = CC_S,
  5186 + [INDEX_op_jl_subq] = CC_O | CC_S,
  5187 + [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
  5188 +
  5189 + [INDEX_op_loopnzq] = CC_Z,
  5190 + [INDEX_op_loopzq] = CC_Z,
  5191 +
  5192 + [INDEX_op_setb_T0_subq] = CC_C,
  5193 + [INDEX_op_setz_T0_subq] = CC_Z,
  5194 + [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
  5195 + [INDEX_op_sets_T0_subq] = CC_S,
  5196 + [INDEX_op_setl_T0_subq] = CC_O | CC_S,
  5197 + [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
  5198 +
  5199 + [INDEX_op_jnz_ecxq] = CC_OSZAPC,
  5200 + [INDEX_op_jz_ecxq] = CC_OSZAPC,
  5201 +#endif
4308 5202  
4309 5203 #define DEF_READF(SUFFIX)\
4310 5204 [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
4311 5205 [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
4312 5206 [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
  5207 + X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
4313 5208 [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
4314 5209 [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
4315 5210 [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
  5211 + X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
4316 5212 \
4317 5213 [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
4318 5214 [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
4319 5215 [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
  5216 + X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
4320 5217 [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
4321 5218 [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
4322   - [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,
4323   -
  5219 + [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
  5220 + X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
4324 5221  
4325 5222 DEF_READF( )
4326 5223 DEF_READF(_raw)
... ... @@ -4341,14 +5238,17 @@ static uint16_t opc_write_flags[NB_OPS] = {
4341 5238 [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
4342 5239  
4343 5240 [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
4344   - [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
4345 5241 [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
4346   - [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
4347 5242 [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
  5243 + X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
  5244 + [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
  5245 + [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
4348 5246 [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
  5247 + X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
4349 5248 [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
4350 5249 [INDEX_op_imull_T0_T1] = CC_OSZAPC,
4351   -
  5250 + X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
  5251 +
4352 5252 /* bcd */
4353 5253 [INDEX_op_aam] = CC_OSZAPC,
4354 5254 [INDEX_op_aad] = CC_OSZAPC,
... ... @@ -4370,21 +5270,28 @@ static uint16_t opc_write_flags[NB_OPS] = {
4370 5270  
4371 5271 [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
4372 5272 [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
  5273 + X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
4373 5274 [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
4374 5275 [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
  5276 + X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
4375 5277 [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
4376 5278 [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
  5279 + X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
4377 5280 [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
4378 5281 [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
  5282 + X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
4379 5283  
4380 5284 [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
4381 5285 [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
  5286 + X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
4382 5287 [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
4383 5288 [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
  5289 + X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
4384 5290  
4385 5291 [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
4386 5292 [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
4387 5293 [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
  5294 + X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
4388 5295  
4389 5296 [INDEX_op_cmpxchg8b] = CC_Z,
4390 5297 [INDEX_op_lar] = CC_Z,
... ... @@ -4396,49 +5303,63 @@ static uint16_t opc_write_flags[NB_OPS] = {
4396 5303 [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4397 5304 [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4398 5305 [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
  5306 + X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
4399 5307 [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4400 5308 [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4401 5309 [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
  5310 + X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
4402 5311 \
4403 5312 [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4404 5313 [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4405 5314 [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
  5315 + X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
4406 5316 [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4407 5317 [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4408 5318 [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
  5319 + X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
4409 5320 \
4410 5321 [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4411 5322 [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4412 5323 [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
  5324 + X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
4413 5325 [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4414 5326 [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
4415 5327 [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
  5328 + X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
4416 5329 \
4417 5330 [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4418 5331 [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4419 5332 [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
  5333 + X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
4420 5334 \
4421 5335 [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4422 5336 [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4423 5337 [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
  5338 + X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
4424 5339 \
4425 5340 [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4426 5341 [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
4427 5342 [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
  5343 + X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
4428 5344 \
4429 5345 [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
4430 5346 [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
  5347 + X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
4431 5348 [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
4432 5349 [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
  5350 + X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
4433 5351 \
4434 5352 [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
4435 5353 [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
  5354 + X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
4436 5355 [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
4437 5356 [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
  5357 + X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
4438 5358 \
4439 5359 [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
4440 5360 [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
4441   - [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,
  5361 + [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
  5362 + X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
4442 5363  
4443 5364  
4444 5365 DEF_WRITEF( )
... ... @@ -4462,23 +5383,28 @@ static uint16_t opc_simpler[NB_OPS] = {
4462 5383 [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
4463 5384 [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
4464 5385 [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
  5386 + X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
4465 5387  
4466 5388 [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
4467 5389 [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
4468 5390 [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
  5391 + X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
4469 5392  
4470 5393 [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
4471 5394 [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
4472 5395 [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
  5396 + X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
4473 5397  
4474 5398 #define DEF_SIMPLER(SUFFIX)\
4475 5399 [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
4476 5400 [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
4477 5401 [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
  5402 + X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
4478 5403 \
4479 5404 [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
4480 5405 [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
4481   - [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,
  5406 + [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
  5407 + X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
4482 5408  
4483 5409 DEF_SIMPLER( )
4484 5410 DEF_SIMPLER(_raw)
... ... @@ -4533,15 +5459,15 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4533 5459 int search_pc)
4534 5460 {
4535 5461 DisasContext dc1, *dc = &dc1;
4536   - uint8_t *pc_ptr;
  5462 + target_ulong pc_ptr;
4537 5463 uint16_t *gen_opc_end;
4538 5464 int flags, j, lj, cflags;
4539   - uint8_t *pc_start;
4540   - uint8_t *cs_base;
  5465 + target_ulong pc_start;
  5466 + target_ulong cs_base;
4541 5467  
4542 5468 /* generate intermediate code */
4543   - pc_start = (uint8_t *)tb->pc;
4544   - cs_base = (uint8_t *)tb->cs_base;
  5469 + pc_start = tb->pc;
  5470 + cs_base = tb->cs_base;
4545 5471 flags = tb->flags;
4546 5472 cflags = tb->cflags;
4547 5473  
... ... @@ -4563,10 +5489,15 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4563 5489 dc->mem_index = 0;
4564 5490 if (flags & HF_SOFTMMU_MASK) {
4565 5491 if (dc->cpl == 3)
4566   - dc->mem_index = 6;
  5492 + dc->mem_index = 2 * 4;
4567 5493 else
4568   - dc->mem_index = 3;
  5494 + dc->mem_index = 1 * 4;
4569 5495 }
  5496 + dc->cpuid_features = env->cpuid_features;
  5497 +#ifdef TARGET_X86_64
  5498 + dc->lma = (flags >> HF_LMA_SHIFT) & 1;
  5499 + dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
  5500 +#endif
4570 5501 dc->flags = flags;
4571 5502 dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
4572 5503 (flags & HF_INHIBIT_IRQ_MASK)
... ... @@ -4583,6 +5514,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4583 5514 gen_opc_ptr = gen_opc_buf;
4584 5515 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4585 5516 gen_opparam_ptr = gen_opparam_buf;
  5517 + nb_gen_labels = 0;
4586 5518  
4587 5519 dc->is_jmp = DISAS_NEXT;
4588 5520 pc_ptr = pc_start;
... ... @@ -4591,7 +5523,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4591 5523 for(;;) {
4592 5524 if (env->nb_breakpoints > 0) {
4593 5525 for(j = 0; j < env->nb_breakpoints; j++) {
4594   - if (env->breakpoints[j] == (unsigned long)pc_ptr) {
  5526 + if (env->breakpoints[j] == pc_ptr) {
4595 5527 gen_debug(dc, pc_ptr - dc->cs_base);
4596 5528 break;
4597 5529 }
... ... @@ -4604,7 +5536,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4604 5536 while (lj < j)
4605 5537 gen_opc_instr_start[lj++] = 0;
4606 5538 }
4607   - gen_opc_pc[lj] = (uint32_t)pc_ptr;
  5539 + gen_opc_pc[lj] = pc_ptr;
4608 5540 gen_opc_cc_op[lj] = dc->cc_op;
4609 5541 gen_opc_instr_start[lj] = 1;
4610 5542 }
... ... @@ -4620,14 +5552,14 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4620 5552 if (dc->tf || dc->singlestep_enabled ||
4621 5553 (flags & HF_INHIBIT_IRQ_MASK) ||
4622 5554 (cflags & CF_SINGLE_INSN)) {
4623   - gen_op_jmp_im(pc_ptr - dc->cs_base);
  5555 + gen_jmp_im(pc_ptr - dc->cs_base);
4624 5556 gen_eob(dc);
4625 5557 break;
4626 5558 }
4627 5559 /* if too long translation, stop generation too */
4628 5560 if (gen_opc_ptr >= gen_opc_end ||
4629 5561 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
4630   - gen_op_jmp_im(pc_ptr - dc->cs_base);
  5562 + gen_jmp_im(pc_ptr - dc->cs_base);
4631 5563 gen_eob(dc);
4632 5564 break;
4633 5565 }
... ... @@ -4646,9 +5578,16 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4646 5578 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
4647 5579 }
4648 5580 if (loglevel & CPU_LOG_TB_IN_ASM) {
  5581 + int disas_flags;
4649 5582 fprintf(logfile, "----------------\n");
4650 5583 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4651   - disas(logfile, pc_start, pc_ptr - pc_start, 0, !dc->code32);
  5584 +#ifdef TARGET_X86_64
  5585 + if (dc->code64)
  5586 + disas_flags = 2;
  5587 + else
  5588 +#endif
  5589 + disas_flags = !dc->code32;
  5590 + target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
4652 5591 fprintf(logfile, "\n");
4653 5592 if (loglevel & CPU_LOG_TB_OP) {
4654 5593 fprintf(logfile, "OP:\n");
... ...