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

Too many changes to show.

To preserve performance only 9 of 11 files are displayed.

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);
... ...