Commit b8b6a50b552e1ddb9f0c563cbfb6f67aa0330b64

Authored by bellard
1 parent 6e01bdae

converted more helpers to TCG - fixed some SVM issues

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4459 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/TODO
... ... @@ -3,12 +3,13 @@ Correctness issues:
3 3 - rework eflags optimization (will be a consequence of TCG port)
4 4 - SVM: rework the implementation: simplify code, move most intercept
5 5 tests as dynamic, correct segment access, verify exception safety,
6   - remove most of the added CPU state.
  6 + cpu save/restore, SMM save/restore.
7 7 - arpl eflags computation is invalid
8 8 - x86_64: fxsave/fxrestore intel/amd differences
9 9 - x86_64: lcall/ljmp intel/amd differences ?
10 10 - x86_64: cmpxchgl intel/amd differences ?
11   -- x86_64: cmovl bug intel/amd differences ?
  11 +- x86_64: cmovl intel/amd differences ?
  12 +- cmpxchg16b + cmpxchg8b cpuid test
12 13 - x86: monitor invalid
13 14 - better code fetch (different exception handling + CS.limit support)
14 15 - user/kernel PUSHL/POPL in helper.c
... ... @@ -19,10 +20,18 @@ Correctness issues:
19 20 - full support of segment limit/rights
20 21 - full x87 exception support
21 22 - improve x87 bit exactness (use bochs code ?)
  23 +- DRx register support
  24 +- CR0.AC emulation
  25 +- SSE alignment checks
  26 +- fix SSE min/max with nans
22 27  
23 28 Optimizations/Features:
24 29  
25 30 - finish TCG port
  31 +- add SVM nested paging support
  32 +- add VMX support
  33 +- add AVX support
  34 +- add SSE5 support
26 35 - evaluate x87 stack pointer statically
27 36 - find a way to avoid translating several time the same TB if CR0.TS
28 37 is set or not.
... ...
target-i386/exec.h
... ... @@ -105,16 +105,6 @@ typedef struct CCTable {
105 105  
106 106 extern CCTable cc_table[];
107 107  
108   -void helper_load_seg(int seg_reg, int selector);
109   -void helper_ljmp_protected_T0_T1(int next_eip);
110   -void helper_lcall_real_T0_T1(int shift, int next_eip);
111   -void helper_lcall_protected_T0_T1(int shift, int next_eip);
112   -void helper_iret_real(int shift);
113   -void helper_iret_protected(int shift, int next_eip);
114   -void helper_lret_protected(int shift, int addend);
115   -void helper_movl_crN_T0(int reg);
116   -void helper_movl_drN_T0(int reg);
117   -void helper_invlpg(target_ulong addr);
118 108 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
119 109 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
120 110 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
... ... @@ -141,17 +131,10 @@ void OPPROTO op_movl_T0_eflags(void);
141 131  
142 132 #include "helper.h"
143 133  
144   -void helper_mulq_EAX_T0(void);
145   -void helper_imulq_EAX_T0(void);
146   -void helper_imulq_T0_T1(void);
147   -void helper_cmpxchg8b(void);
148   -
149   -void check_iob_T0(void);
150   -void check_iow_T0(void);
151   -void check_iol_T0(void);
152   -void check_iob_DX(void);
153   -void check_iow_DX(void);
154   -void check_iol_DX(void);
  134 +static inline void svm_check_intercept(uint32_t type)
  135 +{
  136 + helper_svm_check_intercept_param(type, 0);
  137 +}
155 138  
156 139 #if !defined(CONFIG_USER_ONLY)
157 140  
... ... @@ -363,7 +346,6 @@ extern const CPU86_LDouble f15rk[7];
363 346 void fpu_raise_exception(void);
364 347 void restore_native_fp_state(CPUState *env);
365 348 void save_native_fp_state(CPUState *env);
366   -void vmexit(uint64_t exit_code, uint64_t exit_info_1);
367 349  
368 350 extern const uint8_t parity_table[256];
369 351 extern const uint8_t rclw_table[32];
... ...
target-i386/helper.c
... ... @@ -17,6 +17,7 @@
17 17 * License along with this library; if not, write to the Free Software
18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19 */
  20 +#define CPU_NO_GLOBAL_REGS
20 21 #include "exec.h"
21 22 #include "host-utils.h"
22 23  
... ... @@ -93,16 +94,16 @@ const CPU86_LDouble f15rk[7] =
93 94 3.32192809488736234781L, /*l2t*/
94 95 };
95 96  
96   -/* thread support */
  97 +/* broken thread support */
97 98  
98 99 spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
99 100  
100   -void cpu_lock(void)
  101 +void helper_lock(void)
101 102 {
102 103 spin_lock(&global_cpu_lock);
103 104 }
104 105  
105   -void cpu_unlock(void)
  106 +void helper_unlock(void)
106 107 {
107 108 spin_unlock(&global_cpu_lock);
108 109 }
... ... @@ -508,34 +509,49 @@ static inline void check_io(int addr, int size)
508 509 }
509 510 }
510 511  
511   -void check_iob_T0(void)
  512 +void helper_check_iob(uint32_t t0)
512 513 {
513   - check_io(T0, 1);
  514 + check_io(t0, 1);
514 515 }
515 516  
516   -void check_iow_T0(void)
  517 +void helper_check_iow(uint32_t t0)
517 518 {
518   - check_io(T0, 2);
  519 + check_io(t0, 2);
519 520 }
520 521  
521   -void check_iol_T0(void)
  522 +void helper_check_iol(uint32_t t0)
522 523 {
523   - check_io(T0, 4);
  524 + check_io(t0, 4);
524 525 }
525 526  
526   -void check_iob_DX(void)
  527 +void helper_outb(uint32_t port, uint32_t data)
527 528 {
528   - check_io(EDX & 0xffff, 1);
  529 + cpu_outb(env, port, data & 0xff);
529 530 }
530 531  
531   -void check_iow_DX(void)
  532 +target_ulong helper_inb(uint32_t port)
532 533 {
533   - check_io(EDX & 0xffff, 2);
  534 + return cpu_inb(env, port);
534 535 }
535 536  
536   -void check_iol_DX(void)
  537 +void helper_outw(uint32_t port, uint32_t data)
537 538 {
538   - check_io(EDX & 0xffff, 4);
  539 + cpu_outw(env, port, data & 0xffff);
  540 +}
  541 +
  542 +target_ulong helper_inw(uint32_t port)
  543 +{
  544 + return cpu_inw(env, port);
  545 +}
  546 +
  547 +void helper_outl(uint32_t port, uint32_t data)
  548 +{
  549 + cpu_outl(env, port, data);
  550 +}
  551 +
  552 +target_ulong helper_inl(uint32_t port)
  553 +{
  554 + return cpu_inl(env, port);
539 555 }
540 556  
541 557 static inline unsigned int get_sp_mask(unsigned int e2)
... ... @@ -1275,7 +1291,7 @@ void raise_interrupt(int intno, int is_int, int error_code,
1275 1291 int next_eip_addend)
1276 1292 {
1277 1293 if (!is_int) {
1278   - svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code);
  1294 + helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code);
1279 1295 intno = check_exception(intno, &error_code);
1280 1296 }
1281 1297  
... ... @@ -1857,19 +1873,19 @@ void helper_das(void)
1857 1873 FORCE_RET();
1858 1874 }
1859 1875  
1860   -void helper_cmpxchg8b(void)
  1876 +void helper_cmpxchg8b(target_ulong a0)
1861 1877 {
1862 1878 uint64_t d;
1863 1879 int eflags;
1864 1880  
1865 1881 eflags = cc_table[CC_OP].compute_all();
1866   - d = ldq(A0);
  1882 + d = ldq(a0);
1867 1883 if (d == (((uint64_t)EDX << 32) | EAX)) {
1868   - stq(A0, ((uint64_t)ECX << 32) | EBX);
  1884 + stq(a0, ((uint64_t)ECX << 32) | EBX);
1869 1885 eflags |= CC_Z;
1870 1886 } else {
1871   - EDX = d >> 32;
1872   - EAX = d;
  1887 + EDX = (uint32_t)(d >> 32);
  1888 + EAX = (uint32_t)d;
1873 1889 eflags &= ~CC_Z;
1874 1890 }
1875 1891 CC_SRC = eflags;
... ... @@ -1986,7 +2002,7 @@ void helper_cpuid(void)
1986 2002 }
1987 2003 }
1988 2004  
1989   -void helper_enter_level(int level, int data32)
  2005 +void helper_enter_level(int level, int data32, target_ulong t1)
1990 2006 {
1991 2007 target_ulong ssp;
1992 2008 uint32_t esp_mask, esp, ebp;
... ... @@ -2004,7 +2020,7 @@ void helper_enter_level(int level, int data32)
2004 2020 stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
2005 2021 }
2006 2022 esp -= 4;
2007   - stl(ssp + (esp & esp_mask), T1);
  2023 + stl(ssp + (esp & esp_mask), t1);
2008 2024 } else {
2009 2025 /* 16 bit */
2010 2026 esp -= 2;
... ... @@ -2014,12 +2030,12 @@ void helper_enter_level(int level, int data32)
2014 2030 stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
2015 2031 }
2016 2032 esp -= 2;
2017   - stw(ssp + (esp & esp_mask), T1);
  2033 + stw(ssp + (esp & esp_mask), t1);
2018 2034 }
2019 2035 }
2020 2036  
2021 2037 #ifdef TARGET_X86_64
2022   -void helper_enter64_level(int level, int data64)
  2038 +void helper_enter64_level(int level, int data64, target_ulong t1)
2023 2039 {
2024 2040 target_ulong esp, ebp;
2025 2041 ebp = EBP;
... ... @@ -2034,7 +2050,7 @@ void helper_enter64_level(int level, int data64)
2034 2050 stq(esp, ldq(ebp));
2035 2051 }
2036 2052 esp -= 8;
2037   - stq(esp, T1);
  2053 + stq(esp, t1);
2038 2054 } else {
2039 2055 /* 16 bit */
2040 2056 esp -= 2;
... ... @@ -2044,7 +2060,7 @@ void helper_enter64_level(int level, int data64)
2044 2060 stw(esp, lduw(ebp));
2045 2061 }
2046 2062 esp -= 2;
2047   - stw(esp, T1);
  2063 + stw(esp, t1);
2048 2064 }
2049 2065 }
2050 2066 #endif
... ... @@ -2231,14 +2247,13 @@ void helper_load_seg(int seg_reg, int selector)
2231 2247 }
2232 2248  
2233 2249 /* protected mode jump */
2234   -void helper_ljmp_protected_T0_T1(int next_eip_addend)
  2250 +void helper_ljmp_protected(int new_cs, target_ulong new_eip,
  2251 + int next_eip_addend)
2235 2252 {
2236   - int new_cs, gate_cs, type;
  2253 + int gate_cs, type;
2237 2254 uint32_t e1, e2, cpl, dpl, rpl, limit;
2238   - target_ulong new_eip, next_eip;
  2255 + target_ulong next_eip;
2239 2256  
2240   - new_cs = T0;
2241   - new_eip = T1;
2242 2257 if ((new_cs & 0xfffc) == 0)
2243 2258 raise_exception_err(EXCP0D_GPF, 0);
2244 2259 if (load_segment(&e1, &e2, new_cs) != 0)
... ... @@ -2322,14 +2337,14 @@ void helper_ljmp_protected_T0_T1(int next_eip_addend)
2322 2337 }
2323 2338  
2324 2339 /* real mode call */
2325   -void helper_lcall_real_T0_T1(int shift, int next_eip)
  2340 +void helper_lcall_real(int new_cs, target_ulong new_eip1,
  2341 + int shift, int next_eip)
2326 2342 {
2327   - int new_cs, new_eip;
  2343 + int new_eip;
2328 2344 uint32_t esp, esp_mask;
2329 2345 target_ulong ssp;
2330 2346  
2331   - new_cs = T0;
2332   - new_eip = T1;
  2347 + new_eip = new_eip1;
2333 2348 esp = ESP;
2334 2349 esp_mask = get_sp_mask(env->segs[R_SS].flags);
2335 2350 ssp = env->segs[R_SS].base;
... ... @@ -2348,16 +2363,15 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
2348 2363 }
2349 2364  
2350 2365 /* protected mode call */
2351   -void helper_lcall_protected_T0_T1(int shift, int next_eip_addend)
  2366 +void helper_lcall_protected(int new_cs, target_ulong new_eip,
  2367 + int shift, int next_eip_addend)
2352 2368 {
2353   - int new_cs, new_stack, i;
  2369 + int new_stack, i;
2354 2370 uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
2355 2371 uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
2356 2372 uint32_t val, limit, old_sp_mask;
2357   - target_ulong ssp, old_ssp, next_eip, new_eip;
  2373 + target_ulong ssp, old_ssp, next_eip;
2358 2374  
2359   - new_cs = T0;
2360   - new_eip = T1;
2361 2375 next_eip = env->eip + next_eip_addend;
2362 2376 #ifdef DEBUG_PCALL
2363 2377 if (loglevel & CPU_LOG_PCALL) {
... ... @@ -2922,34 +2936,55 @@ void helper_sysexit(void)
2922 2936 #endif
2923 2937 }
2924 2938  
2925   -void helper_movl_crN_T0(int reg)
  2939 +void helper_movl_crN_T0(int reg, target_ulong t0)
2926 2940 {
2927 2941 #if !defined(CONFIG_USER_ONLY)
2928 2942 switch(reg) {
2929 2943 case 0:
2930   - cpu_x86_update_cr0(env, T0);
  2944 + cpu_x86_update_cr0(env, t0);
2931 2945 break;
2932 2946 case 3:
2933   - cpu_x86_update_cr3(env, T0);
  2947 + cpu_x86_update_cr3(env, t0);
2934 2948 break;
2935 2949 case 4:
2936   - cpu_x86_update_cr4(env, T0);
  2950 + cpu_x86_update_cr4(env, t0);
2937 2951 break;
2938 2952 case 8:
2939   - cpu_set_apic_tpr(env, T0);
2940   - env->cr[8] = T0;
  2953 + cpu_set_apic_tpr(env, t0);
  2954 + env->cr[8] = t0;
2941 2955 break;
2942 2956 default:
2943   - env->cr[reg] = T0;
  2957 + env->cr[reg] = t0;
2944 2958 break;
2945 2959 }
2946 2960 #endif
2947 2961 }
2948 2962  
  2963 +void helper_lmsw(target_ulong t0)
  2964 +{
  2965 + /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
  2966 + if already set to one. */
  2967 + t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
  2968 + helper_movl_crN_T0(0, t0);
  2969 +}
  2970 +
  2971 +void helper_clts(void)
  2972 +{
  2973 + env->cr[0] &= ~CR0_TS_MASK;
  2974 + env->hflags &= ~HF_TS_MASK;
  2975 +}
  2976 +
  2977 +#if !defined(CONFIG_USER_ONLY)
  2978 +target_ulong helper_movtl_T0_cr8(void)
  2979 +{
  2980 + return cpu_get_apic_tpr(env);
  2981 +}
  2982 +#endif
  2983 +
2949 2984 /* XXX: do more */
2950   -void helper_movl_drN_T0(int reg)
  2985 +void helper_movl_drN_T0(int reg, target_ulong t0)
2951 2986 {
2952   - env->dr[reg] = T0;
  2987 + env->dr[reg] = t0;
2953 2988 }
2954 2989  
2955 2990 void helper_invlpg(target_ulong addr)
... ... @@ -2975,10 +3010,10 @@ void helper_rdpmc(void)
2975 3010 raise_exception(EXCP0D_GPF);
2976 3011 }
2977 3012  
2978   - if (!svm_check_intercept_param(SVM_EXIT_RDPMC, 0)) {
2979   - /* currently unimplemented */
2980   - raise_exception_err(EXCP06_ILLOP, 0);
2981   - }
  3013 + helper_svm_check_intercept_param(SVM_EXIT_RDPMC, 0);
  3014 +
  3015 + /* currently unimplemented */
  3016 + raise_exception_err(EXCP06_ILLOP, 0);
2982 3017 }
2983 3018  
2984 3019 #if defined(CONFIG_USER_ONLY)
... ... @@ -3118,7 +3153,7 @@ void helper_rdmsr(void)
3118 3153 }
3119 3154 #endif
3120 3155  
3121   -void helper_lsl(uint32_t selector)
  3156 +uint32_t helper_lsl(uint32_t selector)
3122 3157 {
3123 3158 unsigned int limit;
3124 3159 uint32_t e1, e2, eflags;
... ... @@ -3153,15 +3188,15 @@ void helper_lsl(uint32_t selector)
3153 3188 if (dpl < cpl || dpl < rpl) {
3154 3189 fail:
3155 3190 CC_SRC = eflags & ~CC_Z;
3156   - return;
  3191 + return 0;
3157 3192 }
3158 3193 }
3159 3194 limit = get_seg_limit(e1, e2);
3160   - T1 = limit;
3161 3195 CC_SRC = eflags | CC_Z;
  3196 + return limit;
3162 3197 }
3163 3198  
3164   -void helper_lar(uint32_t selector)
  3199 +uint32_t helper_lar(uint32_t selector)
3165 3200 {
3166 3201 uint32_t e1, e2, eflags;
3167 3202 int rpl, dpl, cpl, type;
... ... @@ -3200,11 +3235,11 @@ void helper_lar(uint32_t selector)
3200 3235 if (dpl < cpl || dpl < rpl) {
3201 3236 fail:
3202 3237 CC_SRC = eflags & ~CC_Z;
3203   - return;
  3238 + return 0;
3204 3239 }
3205 3240 }
3206   - T1 = e2 & 0x00f0ff00;
3207 3241 CC_SRC = eflags | CC_Z;
  3242 + return e2 & 0x00f0ff00;
3208 3243 }
3209 3244  
3210 3245 void helper_verr(uint32_t selector)
... ... @@ -4412,36 +4447,36 @@ static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
4412 4447 return 0;
4413 4448 }
4414 4449  
4415   -void helper_mulq_EAX_T0(void)
  4450 +void helper_mulq_EAX_T0(target_ulong t0)
4416 4451 {
4417 4452 uint64_t r0, r1;
4418 4453  
4419   - mulu64(&r0, &r1, EAX, T0);
  4454 + mulu64(&r0, &r1, EAX, t0);
4420 4455 EAX = r0;
4421 4456 EDX = r1;
4422 4457 CC_DST = r0;
4423 4458 CC_SRC = r1;
4424 4459 }
4425 4460  
4426   -void helper_imulq_EAX_T0(void)
  4461 +void helper_imulq_EAX_T0(target_ulong t0)
4427 4462 {
4428 4463 uint64_t r0, r1;
4429 4464  
4430   - muls64(&r0, &r1, EAX, T0);
  4465 + muls64(&r0, &r1, EAX, t0);
4431 4466 EAX = r0;
4432 4467 EDX = r1;
4433 4468 CC_DST = r0;
4434 4469 CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
4435 4470 }
4436 4471  
4437   -void helper_imulq_T0_T1(void)
  4472 +target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1)
4438 4473 {
4439 4474 uint64_t r0, r1;
4440 4475  
4441   - muls64(&r0, &r1, T0, T1);
4442   - T0 = r0;
  4476 + muls64(&r0, &r1, t0, t1);
4443 4477 CC_DST = r0;
4444 4478 CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
  4479 + return r0;
4445 4480 }
4446 4481  
4447 4482 void helper_divq_EAX(target_ulong t0)
... ... @@ -4553,24 +4588,23 @@ void helper_reset_inhibit_irq(void)
4553 4588 env->hflags &= ~HF_INHIBIT_IRQ_MASK;
4554 4589 }
4555 4590  
4556   -void helper_boundw(void)
  4591 +void helper_boundw(target_ulong a0, int v)
4557 4592 {
4558   - int low, high, v;
4559   - low = ldsw(A0);
4560   - high = ldsw(A0 + 2);
4561   - v = (int16_t)T0;
  4593 + int low, high;
  4594 + low = ldsw(a0);
  4595 + high = ldsw(a0 + 2);
  4596 + v = (int16_t)v;
4562 4597 if (v < low || v > high) {
4563 4598 raise_exception(EXCP05_BOUND);
4564 4599 }
4565 4600 FORCE_RET();
4566 4601 }
4567 4602  
4568   -void helper_boundl(void)
  4603 +void helper_boundl(target_ulong a0, int v)
4569 4604 {
4570   - int low, high, v;
4571   - low = ldl(A0);
4572   - high = ldl(A0 + 4);
4573   - v = T0;
  4605 + int low, high;
  4606 + low = ldl(a0);
  4607 + high = ldl(a0 + 4);
4574 4608 if (v < low || v > high) {
4575 4609 raise_exception(EXCP05_BOUND);
4576 4610 }
... ... @@ -4661,18 +4695,35 @@ void helper_clgi(void)
4661 4695  
4662 4696 #if defined(CONFIG_USER_ONLY)
4663 4697  
4664   -void helper_vmrun(void) { }
4665   -void helper_vmmcall(void) { }
4666   -void helper_vmload(void) { }
4667   -void helper_vmsave(void) { }
4668   -void helper_skinit(void) { }
4669   -void helper_invlpga(void) { }
4670   -void vmexit(uint64_t exit_code, uint64_t exit_info_1) { }
4671   -int svm_check_intercept_param(uint32_t type, uint64_t param)
  4698 +void helper_vmrun(void)
  4699 +{
  4700 +}
  4701 +void helper_vmmcall(void)
  4702 +{
  4703 +}
  4704 +void helper_vmload(void)
  4705 +{
  4706 +}
  4707 +void helper_vmsave(void)
  4708 +{
  4709 +}
  4710 +void helper_skinit(void)
  4711 +{
  4712 +}
  4713 +void helper_invlpga(void)
  4714 +{
  4715 +}
  4716 +void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
  4717 +{
  4718 +}
  4719 +void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
4672 4720 {
4673   - return 0;
4674 4721 }
4675 4722  
  4723 +void helper_svm_check_io(uint32_t port, uint32_t param,
  4724 + uint32_t next_eip_addend)
  4725 +{
  4726 +}
4676 4727 #else
4677 4728  
4678 4729 static inline uint32_t
... ... @@ -4702,7 +4753,6 @@ void helper_vmrun(void)
4702 4753 fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr);
4703 4754  
4704 4755 env->vm_vmcb = addr;
4705   - regs_to_env();
4706 4756  
4707 4757 /* save the current CPU state in the hsave page */
4708 4758 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);
... ... @@ -4801,8 +4851,6 @@ void helper_vmrun(void)
4801 4851  
4802 4852 helper_stgi();
4803 4853  
4804   - regs_to_env();
4805   -
4806 4854 /* maybe we need to inject an event */
4807 4855 event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
4808 4856 if (event_inj & SVM_EVTINJ_VALID) {
... ... @@ -4927,95 +4975,98 @@ void helper_invlpga(void)
4927 4975 tlb_flush(env, 0);
4928 4976 }
4929 4977  
4930   -int svm_check_intercept_param(uint32_t type, uint64_t param)
  4978 +void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
4931 4979 {
4932 4980 switch(type) {
4933 4981 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
4934 4982 if (INTERCEPTEDw(_cr_read, (1 << (type - SVM_EXIT_READ_CR0)))) {
4935   - vmexit(type, param);
4936   - return 1;
  4983 + helper_vmexit(type, param);
4937 4984 }
4938 4985 break;
4939 4986 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 8:
4940 4987 if (INTERCEPTEDw(_dr_read, (1 << (type - SVM_EXIT_READ_DR0)))) {
4941   - vmexit(type, param);
4942   - return 1;
  4988 + helper_vmexit(type, param);
4943 4989 }
4944 4990 break;
4945 4991 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
4946 4992 if (INTERCEPTEDw(_cr_write, (1 << (type - SVM_EXIT_WRITE_CR0)))) {
4947   - vmexit(type, param);
4948   - return 1;
  4993 + helper_vmexit(type, param);
4949 4994 }
4950 4995 break;
4951 4996 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 8:
4952 4997 if (INTERCEPTEDw(_dr_write, (1 << (type - SVM_EXIT_WRITE_DR0)))) {
4953   - vmexit(type, param);
4954   - return 1;
  4998 + helper_vmexit(type, param);
4955 4999 }
4956 5000 break;
4957 5001 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 16:
4958 5002 if (INTERCEPTEDl(_exceptions, (1 << (type - SVM_EXIT_EXCP_BASE)))) {
4959   - vmexit(type, param);
4960   - return 1;
  5003 + helper_vmexit(type, param);
4961 5004 }
4962 5005 break;
4963 5006 case SVM_EXIT_IOIO:
4964   - if (INTERCEPTED(1ULL << INTERCEPT_IOIO_PROT)) {
4965   - /* FIXME: this should be read in at vmrun (faster this way?) */
4966   - uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
4967   - uint16_t port = (uint16_t) (param >> 16);
4968   -
4969   - uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
4970   - if(lduw_phys(addr + port / 8) & (mask << (port & 7)))
4971   - vmexit(type, param);
4972   - }
4973 5007 break;
4974 5008  
4975 5009 case SVM_EXIT_MSR:
4976 5010 if (INTERCEPTED(1ULL << INTERCEPT_MSR_PROT)) {
4977 5011 /* FIXME: this should be read in at vmrun (faster this way?) */
4978 5012 uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa));
  5013 + uint32_t t0, t1;
4979 5014 switch((uint32_t)ECX) {
4980 5015 case 0 ... 0x1fff:
4981   - T0 = (ECX * 2) % 8;
4982   - T1 = ECX / 8;
  5016 + t0 = (ECX * 2) % 8;
  5017 + t1 = ECX / 8;
4983 5018 break;
4984 5019 case 0xc0000000 ... 0xc0001fff:
4985   - T0 = (8192 + ECX - 0xc0000000) * 2;
4986   - T1 = (T0 / 8);
4987   - T0 %= 8;
  5020 + t0 = (8192 + ECX - 0xc0000000) * 2;
  5021 + t1 = (t0 / 8);
  5022 + t0 %= 8;
4988 5023 break;
4989 5024 case 0xc0010000 ... 0xc0011fff:
4990   - T0 = (16384 + ECX - 0xc0010000) * 2;
4991   - T1 = (T0 / 8);
4992   - T0 %= 8;
  5025 + t0 = (16384 + ECX - 0xc0010000) * 2;
  5026 + t1 = (t0 / 8);
  5027 + t0 %= 8;
4993 5028 break;
4994 5029 default:
4995   - vmexit(type, param);
4996   - return 1;
  5030 + helper_vmexit(type, param);
  5031 + t0 = 0;
  5032 + t1 = 0;
  5033 + break;
4997 5034 }
4998   - if (ldub_phys(addr + T1) & ((1 << param) << T0))
4999   - vmexit(type, param);
5000   - return 1;
  5035 + if (ldub_phys(addr + t1) & ((1 << param) << t0))
  5036 + helper_vmexit(type, param);
5001 5037 }
5002 5038 break;
5003 5039 default:
5004 5040 if (INTERCEPTED((1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR)))) {
5005   - vmexit(type, param);
5006   - return 1;
  5041 + helper_vmexit(type, param);
5007 5042 }
5008 5043 break;
5009 5044 }
5010   - return 0;
5011 5045 }
5012 5046  
5013   -void vmexit(uint64_t exit_code, uint64_t exit_info_1)
  5047 +void helper_svm_check_io(uint32_t port, uint32_t param,
  5048 + uint32_t next_eip_addend)
  5049 +{
  5050 + if (INTERCEPTED(1ULL << INTERCEPT_IOIO_PROT)) {
  5051 + /* FIXME: this should be read in at vmrun (faster this way?) */
  5052 + uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
  5053 + uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
  5054 + if(lduw_phys(addr + port / 8) & (mask << (port & 7))) {
  5055 + /* next EIP */
  5056 + stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
  5057 + env->eip + next_eip_addend);
  5058 + helper_vmexit(SVM_EXIT_IOIO, param | (port << 16));
  5059 + }
  5060 + }
  5061 +}
  5062 +
  5063 +/* Note: currently only 32 bits of exit_code are used */
  5064 +void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
5014 5065 {
5015 5066 uint32_t int_ctl;
5016 5067  
5017 5068 if (loglevel & CPU_LOG_TB_IN_ASM)
5018   - fprintf(logfile,"vmexit(%016" PRIx64 ", %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
  5069 + fprintf(logfile,"vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
5019 5070 exit_code, exit_info_1,
5020 5071 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
5021 5072 EIP);
... ... @@ -5105,8 +5156,7 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
5105 5156  
5106 5157 /* other setups */
5107 5158 cpu_x86_set_cpl(env, 0);
5108   - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code_hi), (uint32_t)(exit_code >> 32));
5109   - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
  5159 + stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
5110 5160 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
5111 5161  
5112 5162 helper_clgi();
... ... @@ -5137,7 +5187,6 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
5137 5187 env->error_code = 0;
5138 5188 env->old_exception = -1;
5139 5189  
5140   - regs_to_env();
5141 5190 cpu_loop_exit();
5142 5191 }
5143 5192  
... ...
target-i386/helper.h
1 1 #define TCG_HELPER_PROTO
2 2  
  3 +void helper_lock(void);
  4 +void helper_unlock(void);
3 5 void helper_divb_AL(target_ulong t0);
4 6 void helper_idivb_AL(target_ulong t0);
5 7 void helper_divw_AX(target_ulong t0);
... ... @@ -7,6 +9,9 @@ void helper_idivw_AX(target_ulong t0);
7 9 void helper_divl_EAX(target_ulong t0);
8 10 void helper_idivl_EAX(target_ulong t0);
9 11 #ifdef TARGET_X86_64
  12 +void helper_mulq_EAX_T0(target_ulong t0);
  13 +void helper_imulq_EAX_T0(target_ulong t0);
  14 +target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1);
10 15 void helper_divq_EAX(target_ulong t0);
11 16 void helper_idivq_EAX(target_ulong t0);
12 17 #endif
... ... @@ -18,26 +23,34 @@ void helper_aas(void);
18 23 void helper_daa(void);
19 24 void helper_das(void);
20 25  
21   -void helper_lsl(uint32_t selector);
22   -void helper_lar(uint32_t selector);
  26 +uint32_t helper_lsl(uint32_t selector);
  27 +uint32_t helper_lar(uint32_t selector);
23 28 void helper_verr(uint32_t selector);
24 29 void helper_verw(uint32_t selector);
25 30 void helper_lldt(int selector);
26 31 void helper_ltr(int selector);
27 32 void helper_load_seg(int seg_reg, int selector);
28   -void helper_ljmp_protected_T0_T1(int next_eip);
29   -void helper_lcall_real_T0_T1(int shift, int next_eip);
30   -void helper_lcall_protected_T0_T1(int shift, int next_eip);
  33 +void helper_ljmp_protected(int new_cs, target_ulong new_eip,
  34 + int next_eip_addend);
  35 +void helper_lcall_real(int new_cs, target_ulong new_eip1,
  36 + int shift, int next_eip);
  37 +void helper_lcall_protected(int new_cs, target_ulong new_eip,
  38 + int shift, int next_eip_addend);
31 39 void helper_iret_real(int shift);
32 40 void helper_iret_protected(int shift, int next_eip);
33 41 void helper_lret_protected(int shift, int addend);
34   -void helper_movl_crN_T0(int reg);
35   -void helper_movl_drN_T0(int reg);
  42 +void helper_movl_crN_T0(int reg, target_ulong t0);
  43 +void helper_lmsw(target_ulong t0);
  44 +void helper_clts(void);
  45 +#if !defined(CONFIG_USER_ONLY)
  46 +target_ulong helper_movtl_T0_cr8(void);
  47 +#endif
  48 +void helper_movl_drN_T0(int reg, target_ulong t0);
36 49 void helper_invlpg(target_ulong addr);
37 50  
38   -void helper_enter_level(int level, int data32);
  51 +void helper_enter_level(int level, int data32, target_ulong t1);
39 52 #ifdef TARGET_X86_64
40   -void helper_enter64_level(int level, int data64);
  53 +void helper_enter64_level(int level, int data64, target_ulong t1);
41 54 #endif
42 55 void helper_sysenter(void);
43 56 void helper_sysexit(void);
... ... @@ -55,9 +68,10 @@ void helper_cli(void);
55 68 void helper_sti(void);
56 69 void helper_set_inhibit_irq(void);
57 70 void helper_reset_inhibit_irq(void);
58   -void helper_boundw(void);
59   -void helper_boundl(void);
  71 +void helper_boundw(target_ulong a0, int v);
  72 +void helper_boundl(target_ulong a0, int v);
60 73 void helper_rsm(void);
  74 +void helper_cmpxchg8b(target_ulong a0);
61 75 void helper_single_step(void);
62 76 void helper_cpuid(void);
63 77 void helper_rdtsc(void);
... ... @@ -65,6 +79,20 @@ void helper_rdpmc(void);
65 79 void helper_rdmsr(void);
66 80 void helper_wrmsr(void);
67 81  
  82 +void helper_check_iob(uint32_t t0);
  83 +void helper_check_iow(uint32_t t0);
  84 +void helper_check_iol(uint32_t t0);
  85 +void helper_outb(uint32_t port, uint32_t data);
  86 +target_ulong helper_inb(uint32_t port);
  87 +void helper_outw(uint32_t port, uint32_t data);
  88 +target_ulong helper_inw(uint32_t port);
  89 +void helper_outl(uint32_t port, uint32_t data);
  90 +target_ulong helper_inl(uint32_t port);
  91 +
  92 +void helper_svm_check_intercept_param(uint32_t type, uint64_t param);
  93 +void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1);
  94 +void helper_svm_check_io(uint32_t port, uint32_t param,
  95 + uint32_t next_eip_addend);
68 96 void helper_vmrun(void);
69 97 void helper_vmmcall(void);
70 98 void helper_vmload(void);
... ...
target-i386/op.c
... ... @@ -276,17 +276,17 @@ void OPPROTO op_imull_T0_T1(void)
276 276 #ifdef TARGET_X86_64
277 277 void OPPROTO op_mulq_EAX_T0(void)
278 278 {
279   - helper_mulq_EAX_T0();
  279 + helper_mulq_EAX_T0(T0);
280 280 }
281 281  
282 282 void OPPROTO op_imulq_EAX_T0(void)
283 283 {
284   - helper_imulq_EAX_T0();
  284 + helper_imulq_EAX_T0(T0);
285 285 }
286 286  
287 287 void OPPROTO op_imulq_T0_T1(void)
288 288 {
289   - helper_imulq_T0_T1();
  289 + T0 = helper_imulq_T0_T1(T0, T1);
290 290 }
291 291 #endif
292 292  
... ... @@ -351,7 +351,7 @@ void OPPROTO op_into(void)
351 351  
352 352 void OPPROTO op_cmpxchg8b(void)
353 353 {
354   - helper_cmpxchg8b();
  354 + helper_cmpxchg8b(A0);
355 355 }
356 356  
357 357 /* multiple size ops */
... ... @@ -522,12 +522,6 @@ void OPPROTO op_das(void)
522 522  
523 523 /* segment handling */
524 524  
525   -/* never use it with R_CS */
526   -void OPPROTO op_movl_seg_T0(void)
527   -{
528   - helper_load_seg(PARAM1, T0);
529   -}
530   -
531 525 /* faster VM86 version */
532 526 void OPPROTO op_movl_seg_T0_vm(void)
533 527 {
... ... @@ -548,12 +542,20 @@ void OPPROTO op_movl_T0_seg(void)
548 542  
549 543 void OPPROTO op_lsl(void)
550 544 {
551   - helper_lsl(T0);
  545 + uint32_t val;
  546 + val = helper_lsl(T0);
  547 + if (CC_SRC & CC_Z)
  548 + T1 = val;
  549 + FORCE_RET();
552 550 }
553 551  
554 552 void OPPROTO op_lar(void)
555 553 {
556   - helper_lar(T0);
  554 + uint32_t val;
  555 + val = helper_lar(T0);
  556 + if (CC_SRC & CC_Z)
  557 + T1 = val;
  558 + FORCE_RET();
557 559 }
558 560  
559 561 void OPPROTO op_verr(void)
... ... @@ -585,104 +587,6 @@ void OPPROTO op_arpl_update(void)
585 587 CC_SRC = (eflags & ~CC_Z) | T1;
586 588 }
587 589  
588   -/* T0: segment, T1:eip */
589   -void OPPROTO op_ljmp_protected_T0_T1(void)
590   -{
591   - helper_ljmp_protected_T0_T1(PARAM1);
592   -}
593   -
594   -void OPPROTO op_lcall_real_T0_T1(void)
595   -{
596   - helper_lcall_real_T0_T1(PARAM1, PARAM2);
597   -}
598   -
599   -void OPPROTO op_lcall_protected_T0_T1(void)
600   -{
601   - helper_lcall_protected_T0_T1(PARAM1, PARAM2);
602   -}
603   -
604   -void OPPROTO op_iret_real(void)
605   -{
606   - helper_iret_real(PARAM1);
607   -}
608   -
609   -void OPPROTO op_iret_protected(void)
610   -{
611   - helper_iret_protected(PARAM1, PARAM2);
612   -}
613   -
614   -void OPPROTO op_lret_protected(void)
615   -{
616   - helper_lret_protected(PARAM1, PARAM2);
617   -}
618   -
619   -/* CR registers access. */
620   -void OPPROTO op_movl_crN_T0(void)
621   -{
622   - helper_movl_crN_T0(PARAM1);
623   -}
624   -
625   -/* These pseudo-opcodes check for SVM intercepts. */
626   -void OPPROTO op_svm_check_intercept(void)
627   -{
628   - A0 = PARAM1 & PARAM2;
629   - svm_check_intercept(PARAMQ1);
630   -}
631   -
632   -void OPPROTO op_svm_check_intercept_param(void)
633   -{
634   - A0 = PARAM1 & PARAM2;
635   - svm_check_intercept_param(PARAMQ1, T1);
636   -}
637   -
638   -void OPPROTO op_svm_vmexit(void)
639   -{
640   - A0 = PARAM1 & PARAM2;
641   - vmexit(PARAMQ1, T1);
642   -}
643   -
644   -void OPPROTO op_geneflags(void)
645   -{
646   - CC_SRC = cc_table[CC_OP].compute_all();
647   -}
648   -
649   -/* This pseudo-opcode checks for IO intercepts. */
650   -#if !defined(CONFIG_USER_ONLY)
651   -void OPPROTO op_svm_check_intercept_io(void)
652   -{
653   - A0 = PARAM1 & PARAM2;
654   - /* PARAMQ1 = TYPE (0 = OUT, 1 = IN; 4 = STRING; 8 = REP)
655   - T0 = PORT
656   - T1 = next eip */
657   - stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), T1);
658   - /* ASIZE does not appear on real hw */
659   - svm_check_intercept_param(SVM_EXIT_IOIO,
660   - (PARAMQ1 & ~SVM_IOIO_ASIZE_MASK) |
661   - ((T0 & 0xffff) << 16));
662   -}
663   -#endif
664   -
665   -#if !defined(CONFIG_USER_ONLY)
666   -void OPPROTO op_movtl_T0_cr8(void)
667   -{
668   - T0 = cpu_get_apic_tpr(env);
669   -}
670   -#endif
671   -
672   -/* DR registers access */
673   -void OPPROTO op_movl_drN_T0(void)
674   -{
675   - helper_movl_drN_T0(PARAM1);
676   -}
677   -
678   -void OPPROTO op_lmsw_T0(void)
679   -{
680   - /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
681   - if already set to one. */
682   - T0 = (env->cr[0] & ~0xe) | (T0 & 0xf);
683   - helper_movl_crN_T0(0);
684   -}
685   -
686 590 void OPPROTO op_movl_T0_env(void)
687 591 {
688 592 T0 = *(uint32_t *)((char *)env + PARAM1);
... ... @@ -718,12 +622,6 @@ void OPPROTO op_movtl_env_T1(void)
718 622 *(target_ulong *)((char *)env + PARAM1) = T1;
719 623 }
720 624  
721   -void OPPROTO op_clts(void)
722   -{
723   - env->cr[0] &= ~CR0_TS_MASK;
724   - env->hflags &= ~HF_TS_MASK;
725   -}
726   -
727 625 /* flags handling */
728 626  
729 627 void OPPROTO op_jmp_label(void)
... ... @@ -1028,17 +926,6 @@ void OPPROTO op_fcomi_dummy(void)
1028 926 T0 = 0;
1029 927 }
1030 928  
1031   -/* threading support */
1032   -void OPPROTO op_lock(void)
1033   -{
1034   - cpu_lock();
1035   -}
1036   -
1037   -void OPPROTO op_unlock(void)
1038   -{
1039   - cpu_unlock();
1040   -}
1041   -
1042 929 /* SSE support */
1043 930 void OPPROTO op_com_dummy(void)
1044 931 {
... ...
target-i386/ops_sse.h
... ... @@ -471,12 +471,12 @@ void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s)
471 471 #endif
472 472 }
473 473  
474   -void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s)
  474 +void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0)
475 475 {
476 476 int i;
477 477 for(i = 0; i < (8 << SHIFT); i++) {
478 478 if (s->B(i) & 0x80)
479   - stb(A0 + i, d->B(i));
  479 + stb(a0 + i, d->B(i));
480 480 }
481 481 FORCE_RET();
482 482 }
... ...
target-i386/ops_sse_header.h
... ... @@ -104,7 +104,7 @@ void glue(helper_pmuludq, SUFFIX) (Reg *d, Reg *s);
104 104 void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s);
105 105  
106 106 void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s);
107   -void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s);
  107 +void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0);
108 108 void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val);
109 109 #ifdef TARGET_X86_64
110 110 void glue(helper_movq_mm_T0, SUFFIX) (Reg *d, uint64_t val);
... ...
target-i386/ops_template.h
... ... @@ -554,39 +554,6 @@ void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
554 554 T0 = DF << SHIFT;
555 555 }
556 556  
557   -/* port I/O */
558   -#if DATA_BITS <= 32
559   -void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
560   -{
561   - glue(cpu_out, SUFFIX)(env, T0, T1 & DATA_MASK);
562   -}
563   -
564   -void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
565   -{
566   - T1 = glue(cpu_in, SUFFIX)(env, T0);
567   -}
568   -
569   -void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
570   -{
571   - T0 = glue(cpu_in, SUFFIX)(env, EDX & 0xffff);
572   -}
573   -
574   -void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
575   -{
576   - glue(cpu_out, SUFFIX)(env, EDX & 0xffff, T0);
577   -}
578   -
579   -void OPPROTO glue(glue(op_check_io, SUFFIX), _T0)(void)
580   -{
581   - glue(glue(check_io, SUFFIX), _T0)();
582   -}
583   -
584   -void OPPROTO glue(glue(op_check_io, SUFFIX), _DX)(void)
585   -{
586   - glue(glue(check_io, SUFFIX), _DX)();
587   -}
588   -#endif
589   -
590 557 #undef DATA_BITS
591 558 #undef SHIFT_MASK
592 559 #undef SHIFT1_MASK
... ...
target-i386/svm.h
... ... @@ -71,8 +71,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
71 71 uint32_t int_vector;
72 72 uint32_t int_state;
73 73 uint8_t reserved_3[4];
74   - uint32_t exit_code;
75   - uint32_t exit_code_hi;
  74 + uint64_t exit_code;
76 75 uint64_t exit_info_1;
77 76 uint64_t exit_info_2;
78 77 uint32_t exit_int_info;
... ... @@ -323,14 +322,6 @@ struct __attribute__ ((__packed__)) vmcb {
323 322  
324 323 /* function references */
325 324  
326   -void helper_stgi(void);
327   -void vmexit(uint64_t exit_code, uint64_t exit_info_1);
328   -int svm_check_intercept_param(uint32_t type, uint64_t param);
329   -static inline int svm_check_intercept(unsigned int type) {
330   - return svm_check_intercept_param(type, 0);
331   -}
332   -
333   -
334 325 #define INTERCEPTED(mask) (env->intercept & mask)
335 326 #define INTERCEPTEDw(var, mask) (env->intercept ## var & mask)
336 327 #define INTERCEPTEDl(var, mask) (env->intercept ## var & mask)
... ...
target-i386/translate.c
... ... @@ -60,7 +60,7 @@
60 60 /* global register indexes */
61 61 static TCGv cpu_env, cpu_T[2], cpu_A0;
62 62 /* local register indexes (only used inside old micro ops) */
63   -static TCGv cpu_tmp0, cpu_tmp1, cpu_tmp2, cpu_ptr0, cpu_ptr1;
  63 +static TCGv cpu_tmp0, cpu_tmp1, cpu_tmp2, cpu_tmp3, cpu_ptr0, cpu_ptr1;
64 64  
65 65 #ifdef TARGET_X86_64
66 66 static int x86_64_hregs;
... ... @@ -903,52 +903,54 @@ static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {
903 903 },
904 904 };
905 905  
906   -static GenOpFunc *gen_op_in_DX_T0[3] = {
907   - gen_op_inb_DX_T0,
908   - gen_op_inw_DX_T0,
909   - gen_op_inl_DX_T0,
  906 +static void *helper_in_func[3] = {
  907 + helper_inb,
  908 + helper_inw,
  909 + helper_inl,
910 910 };
911 911  
912   -static GenOpFunc *gen_op_out_DX_T0[3] = {
913   - gen_op_outb_DX_T0,
914   - gen_op_outw_DX_T0,
915   - gen_op_outl_DX_T0,
  912 +static void *helper_out_func[3] = {
  913 + helper_outb,
  914 + helper_outw,
  915 + helper_outl,
916 916 };
917 917  
918   -static GenOpFunc *gen_op_in[3] = {
919   - gen_op_inb_T0_T1,
920   - gen_op_inw_T0_T1,
921   - gen_op_inl_T0_T1,
  918 +static void *gen_check_io_func[3] = {
  919 + helper_check_iob,
  920 + helper_check_iow,
  921 + helper_check_iol,
922 922 };
923 923  
924   -static GenOpFunc *gen_op_out[3] = {
925   - gen_op_outb_T0_T1,
926   - gen_op_outw_T0_T1,
927   - gen_op_outl_T0_T1,
928   -};
929   -
930   -static GenOpFunc *gen_check_io_T0[3] = {
931   - gen_op_check_iob_T0,
932   - gen_op_check_iow_T0,
933   - gen_op_check_iol_T0,
934   -};
935   -
936   -static GenOpFunc *gen_check_io_DX[3] = {
937   - gen_op_check_iob_DX,
938   - gen_op_check_iow_DX,
939   - gen_op_check_iol_DX,
940   -};
941   -
942   -static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip)
  924 +static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
  925 + uint32_t svm_flags)
943 926 {
  927 + int state_saved;
  928 + target_ulong next_eip;
  929 +
  930 + state_saved = 0;
944 931 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
945 932 if (s->cc_op != CC_OP_DYNAMIC)
946 933 gen_op_set_cc_op(s->cc_op);
947 934 gen_jmp_im(cur_eip);
948   - if (use_dx)
949   - gen_check_io_DX[ot]();
950   - else
951   - gen_check_io_T0[ot]();
  935 + state_saved = 1;
  936 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  937 + tcg_gen_helper_0_1(gen_check_io_func[ot],
  938 + cpu_tmp2);
  939 + }
  940 + if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {
  941 + if (!state_saved) {
  942 + if (s->cc_op != CC_OP_DYNAMIC)
  943 + gen_op_set_cc_op(s->cc_op);
  944 + gen_jmp_im(cur_eip);
  945 + state_saved = 1;
  946 + }
  947 + svm_flags |= (1 << (4 + ot));
  948 + next_eip = s->pc - s->cs_base;
  949 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  950 + tcg_gen_helper_0_3(helper_svm_check_io,
  951 + cpu_tmp2,
  952 + tcg_const_i32(svm_flags),
  953 + tcg_const_i32(next_eip - cur_eip));
952 954 }
953 955 }
954 956  
... ... @@ -1080,7 +1082,10 @@ static inline void gen_ins(DisasContext *s, int ot)
1080 1082 gen_string_movl_A0_EDI(s);
1081 1083 gen_op_movl_T0_0();
1082 1084 gen_op_st_T0_A0(ot + s->mem_index);
1083   - gen_op_in_DX_T0[ot]();
  1085 + gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
  1086 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[1]);
  1087 + tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
  1088 + tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2);
1084 1089 gen_op_st_T0_A0(ot + s->mem_index);
1085 1090 gen_op_movl_T0_Dshift[ot]();
1086 1091 #ifdef TARGET_X86_64
... ... @@ -1099,7 +1104,13 @@ static inline void gen_outs(DisasContext *s, int ot)
1099 1104 {
1100 1105 gen_string_movl_A0_ESI(s);
1101 1106 gen_op_ld_T0_A0(ot + s->mem_index);
1102   - gen_op_out_DX_T0[ot]();
  1107 +
  1108 + gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
  1109 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[1]);
  1110 + tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
  1111 + tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[0]);
  1112 + tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
  1113 +
1103 1114 gen_op_movl_T0_Dshift[ot]();
1104 1115 #ifdef TARGET_X86_64
1105 1116 if (s->aflag == 2) {
... ... @@ -1976,7 +1987,8 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
1976 1987 if (s->cc_op != CC_OP_DYNAMIC)
1977 1988 gen_op_set_cc_op(s->cc_op);
1978 1989 gen_jmp_im(cur_eip);
1979   - gen_op_movl_seg_T0(seg_reg);
  1990 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  1991 + tcg_gen_helper_0_2(helper_load_seg, tcg_const_i32(seg_reg), cpu_tmp2);
1980 1992 /* abort translation because the addseg value may change or
1981 1993 because ss32 may change. For R_SS, translation must always
1982 1994 stop as a special handling must be done to disable hardware
... ... @@ -1990,28 +2002,6 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
1990 2002 }
1991 2003 }
1992 2004  
1993   -#define SVM_movq_T1_im(x) gen_movtl_T1_im(x)
1994   -
1995   -static inline int
1996   -gen_svm_check_io(DisasContext *s, target_ulong pc_start, uint64_t type)
1997   -{
1998   -#if !defined(CONFIG_USER_ONLY)
1999   - if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {
2000   - if (s->cc_op != CC_OP_DYNAMIC)
2001   - gen_op_set_cc_op(s->cc_op);
2002   - SVM_movq_T1_im(s->pc - s->cs_base);
2003   - gen_jmp_im(pc_start - s->cs_base);
2004   - gen_op_geneflags();
2005   - gen_op_svm_check_intercept_io((uint32_t)(type >> 32), (uint32_t)type);
2006   - s->cc_op = CC_OP_DYNAMIC;
2007   - /* FIXME: maybe we could move the io intercept vector to the TB as well
2008   - so we know if this is an EOB or not ... let's assume it's not
2009   - for now. */
2010   - }
2011   -#endif
2012   - return 0;
2013   -}
2014   -
2015 2005 static inline int svm_is_rep(int prefixes)
2016 2006 {
2017 2007 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
... ... @@ -2019,7 +2009,7 @@ static inline int svm_is_rep(int prefixes)
2019 2009  
2020 2010 static inline int
2021 2011 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2022   - uint64_t type, uint64_t param)
  2012 + uint32_t type, uint64_t param)
2023 2013 {
2024 2014 if(!(s->flags & (INTERCEPT_SVM_MASK)))
2025 2015 /* no SVM activated */
... ... @@ -2029,12 +2019,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2029 2019 case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1:
2030 2020 if (s->cc_op != CC_OP_DYNAMIC) {
2031 2021 gen_op_set_cc_op(s->cc_op);
2032   - s->cc_op = CC_OP_DYNAMIC;
2033 2022 }
2034 2023 gen_jmp_im(pc_start - s->cs_base);
2035   - SVM_movq_T1_im(param);
2036   - gen_op_geneflags();
2037   - gen_op_svm_check_intercept_param((uint32_t)(type >> 32), (uint32_t)type);
  2024 + tcg_gen_helper_0_2(helper_svm_check_intercept_param,
  2025 + tcg_const_i32(type), tcg_const_i64(param));
2038 2026 /* this is a special case as we do not know if the interception occurs
2039 2027 so we assume there was none */
2040 2028 return 0;
... ... @@ -2042,12 +2030,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2042 2030 if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) {
2043 2031 if (s->cc_op != CC_OP_DYNAMIC) {
2044 2032 gen_op_set_cc_op(s->cc_op);
2045   - s->cc_op = CC_OP_DYNAMIC;
2046 2033 }
2047 2034 gen_jmp_im(pc_start - s->cs_base);
2048   - SVM_movq_T1_im(param);
2049   - gen_op_geneflags();
2050   - gen_op_svm_check_intercept_param((uint32_t)(type >> 32), (uint32_t)type);
  2035 + tcg_gen_helper_0_2(helper_svm_check_intercept_param,
  2036 + tcg_const_i32(type), tcg_const_i64(param));
2051 2037 /* this is a special case as we do not know if the interception occurs
2052 2038 so we assume there was none */
2053 2039 return 0;
... ... @@ -2057,12 +2043,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2057 2043 if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) {
2058 2044 if (s->cc_op != CC_OP_DYNAMIC) {
2059 2045 gen_op_set_cc_op(s->cc_op);
2060   - s->cc_op = CC_OP_EFLAGS;
2061 2046 }
2062 2047 gen_jmp_im(pc_start - s->cs_base);
2063   - SVM_movq_T1_im(param);
2064   - gen_op_geneflags();
2065   - gen_op_svm_vmexit(type >> 32, type);
  2048 + tcg_gen_helper_0_2(helper_vmexit,
  2049 + tcg_const_i32(type), tcg_const_i64(param));
2066 2050 /* we can optimize this one so TBs don't get longer
2067 2051 than up to vmexit */
2068 2052 gen_eob(s);
... ... @@ -2276,9 +2260,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
2276 2260 gen_op_st_T0_A0(ot + s->mem_index);
2277 2261 if (level) {
2278 2262 /* XXX: must save state */
2279   - tcg_gen_helper_0_2(helper_enter64_level,
  2263 + tcg_gen_helper_0_3(helper_enter64_level,
2280 2264 tcg_const_i32(level),
2281   - tcg_const_i32((ot == OT_QUAD)));
  2265 + tcg_const_i32((ot == OT_QUAD)),
  2266 + cpu_T[1]);
2282 2267 }
2283 2268 gen_op_mov_reg_T1(ot, R_EBP);
2284 2269 gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
... ... @@ -2301,9 +2286,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
2301 2286 gen_op_st_T0_A0(ot + s->mem_index);
2302 2287 if (level) {
2303 2288 /* XXX: must save state */
2304   - tcg_gen_helper_0_2(helper_enter_level,
  2289 + tcg_gen_helper_0_3(helper_enter_level,
2305 2290 tcg_const_i32(level),
2306   - tcg_const_i32(s->dflag));
  2291 + tcg_const_i32(s->dflag),
  2292 + cpu_T[1]);
2307 2293 }
2308 2294 gen_op_mov_reg_T1(ot, R_EBP);
2309 2295 gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
... ... @@ -3208,22 +3194,6 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3208 3194 } else {
3209 3195 /* generic MMX or SSE operation */
3210 3196 switch(b) {
3211   - case 0xf7:
3212   - /* maskmov : we must prepare A0 */
3213   - if (mod != 3)
3214   - goto illegal_op;
3215   -#ifdef TARGET_X86_64
3216   - if (s->aflag == 2) {
3217   - gen_op_movq_A0_reg(R_EDI);
3218   - } else
3219   -#endif
3220   - {
3221   - gen_op_movl_A0_reg(R_EDI);
3222   - if (s->aflag == 0)
3223   - gen_op_andl_A0_ffff();
3224   - }
3225   - gen_add_A0_ds_seg(s);
3226   - break;
3227 3197 case 0x70: /* pshufx insn */
3228 3198 case 0xc6: /* pshufx insn */
3229 3199 case 0xc2: /* compare insns */
... ... @@ -3295,6 +3265,26 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3295 3265 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3296 3266 tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
3297 3267 break;
  3268 + case 0xf7:
  3269 + /* maskmov : we must prepare A0 */
  3270 + if (mod != 3)
  3271 + goto illegal_op;
  3272 +#ifdef TARGET_X86_64
  3273 + if (s->aflag == 2) {
  3274 + gen_op_movq_A0_reg(R_EDI);
  3275 + } else
  3276 +#endif
  3277 + {
  3278 + gen_op_movl_A0_reg(R_EDI);
  3279 + if (s->aflag == 0)
  3280 + gen_op_andl_A0_ffff();
  3281 + }
  3282 + gen_add_A0_ds_seg(s);
  3283 +
  3284 + tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
  3285 + tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
  3286 + tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, cpu_A0);
  3287 + break;
3298 3288 default:
3299 3289 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3300 3290 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
... ... @@ -3440,7 +3430,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3440 3430  
3441 3431 /* lock generation */
3442 3432 if (prefixes & PREFIX_LOCK)
3443   - gen_op_lock();
  3433 + tcg_gen_helper_0_0(helper_lock);
3444 3434  
3445 3435 /* now check op code */
3446 3436 reswitch:
... ... @@ -3783,9 +3773,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3783 3773 if (s->cc_op != CC_OP_DYNAMIC)
3784 3774 gen_op_set_cc_op(s->cc_op);
3785 3775 gen_jmp_im(pc_start - s->cs_base);
3786   - gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
  3776 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  3777 + tcg_gen_helper_0_4(helper_lcall_protected,
  3778 + cpu_tmp2, cpu_T[1],
  3779 + tcg_const_i32(dflag),
  3780 + tcg_const_i32(s->pc - pc_start));
3787 3781 } else {
3788   - gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
  3782 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  3783 + tcg_gen_helper_0_4(helper_lcall_real,
  3784 + cpu_tmp2, cpu_T[1],
  3785 + tcg_const_i32(dflag),
  3786 + tcg_const_i32(s->pc - s->cs_base));
3789 3787 }
3790 3788 gen_eob(s);
3791 3789 break;
... ... @@ -3804,7 +3802,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3804 3802 if (s->cc_op != CC_OP_DYNAMIC)
3805 3803 gen_op_set_cc_op(s->cc_op);
3806 3804 gen_jmp_im(pc_start - s->cs_base);
3807   - gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
  3805 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  3806 + tcg_gen_helper_0_3(helper_ljmp_protected,
  3807 + cpu_tmp2,
  3808 + cpu_T[1],
  3809 + tcg_const_i32(s->pc - pc_start));
3808 3810 } else {
3809 3811 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3810 3812 gen_op_movl_T0_T1();
... ... @@ -4355,11 +4357,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
4355 4357 gen_op_mov_TN_reg(ot, 0, reg);
4356 4358 /* for xchg, lock is implicit */
4357 4359 if (!(prefixes & PREFIX_LOCK))
4358   - gen_op_lock();
  4360 + tcg_gen_helper_0_0(helper_lock);
4359 4361 gen_op_ld_T1_A0(ot + s->mem_index);
4360 4362 gen_op_st_T0_A0(ot + s->mem_index);
4361 4363 if (!(prefixes & PREFIX_LOCK))
4362   - gen_op_unlock();
  4364 + tcg_gen_helper_0_0(helper_unlock);
4363 4365 gen_op_mov_reg_T1(ot, reg);
4364 4366 }
4365 4367 break;
... ... @@ -5117,13 +5119,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5117 5119 ot = OT_BYTE;
5118 5120 else
5119 5121 ot = dflag ? OT_LONG : OT_WORD;
5120   - gen_check_io(s, ot, 1, pc_start - s->cs_base);
5121 5122 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5122 5123 gen_op_andl_T0_ffff();
5123   - if (gen_svm_check_io(s, pc_start,
5124   - SVM_IOIO_TYPE_MASK | (1 << (4+ot)) |
5125   - svm_is_rep(prefixes) | 4 | (1 << (7+s->aflag))))
5126   - break;
  5124 + gen_check_io(s, ot, pc_start - s->cs_base,
  5125 + SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
5127 5126 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5128 5127 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5129 5128 } else {
... ... @@ -5136,13 +5135,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5136 5135 ot = OT_BYTE;
5137 5136 else
5138 5137 ot = dflag ? OT_LONG : OT_WORD;
5139   - gen_check_io(s, ot, 1, pc_start - s->cs_base);
5140 5138 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5141 5139 gen_op_andl_T0_ffff();
5142   - if (gen_svm_check_io(s, pc_start,
5143   - (1 << (4+ot)) | svm_is_rep(prefixes) |
5144   - 4 | (1 << (7+s->aflag))))
5145   - break;
  5140 + gen_check_io(s, ot, pc_start - s->cs_base,
  5141 + svm_is_rep(prefixes) | 4);
5146 5142 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5147 5143 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5148 5144 } else {
... ... @@ -5161,12 +5157,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5161 5157 ot = dflag ? OT_LONG : OT_WORD;
5162 5158 val = ldub_code(s->pc++);
5163 5159 gen_op_movl_T0_im(val);
5164   - gen_check_io(s, ot, 0, pc_start - s->cs_base);
5165   - if (gen_svm_check_io(s, pc_start,
5166   - SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) |
5167   - (1 << (4+ot))))
5168   - break;
5169   - gen_op_in[ot]();
  5160 + gen_check_io(s, ot, pc_start - s->cs_base,
  5161 + SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
  5162 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  5163 + tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2);
5170 5164 gen_op_mov_reg_T1(ot, R_EAX);
5171 5165 break;
5172 5166 case 0xe6:
... ... @@ -5177,12 +5171,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5177 5171 ot = dflag ? OT_LONG : OT_WORD;
5178 5172 val = ldub_code(s->pc++);
5179 5173 gen_op_movl_T0_im(val);
5180   - gen_check_io(s, ot, 0, pc_start - s->cs_base);
5181   - if (gen_svm_check_io(s, pc_start, svm_is_rep(prefixes) |
5182   - (1 << (4+ot))))
5183   - break;
  5174 + gen_check_io(s, ot, pc_start - s->cs_base,
  5175 + svm_is_rep(prefixes));
5184 5176 gen_op_mov_TN_reg(ot, 1, R_EAX);
5185   - gen_op_out[ot]();
  5177 +
  5178 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  5179 + tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
  5180 + tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[1]);
  5181 + tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
5186 5182 break;
5187 5183 case 0xec:
5188 5184 case 0xed:
... ... @@ -5192,12 +5188,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5192 5188 ot = dflag ? OT_LONG : OT_WORD;
5193 5189 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5194 5190 gen_op_andl_T0_ffff();
5195   - gen_check_io(s, ot, 0, pc_start - s->cs_base);
5196   - if (gen_svm_check_io(s, pc_start,
5197   - SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) |
5198   - (1 << (4+ot))))
5199   - break;
5200   - gen_op_in[ot]();
  5191 + gen_check_io(s, ot, pc_start - s->cs_base,
  5192 + SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
  5193 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  5194 + tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2);
5201 5195 gen_op_mov_reg_T1(ot, R_EAX);
5202 5196 break;
5203 5197 case 0xee:
... ... @@ -5208,12 +5202,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5208 5202 ot = dflag ? OT_LONG : OT_WORD;
5209 5203 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5210 5204 gen_op_andl_T0_ffff();
5211   - gen_check_io(s, ot, 0, pc_start - s->cs_base);
5212   - if (gen_svm_check_io(s, pc_start,
5213   - svm_is_rep(prefixes) | (1 << (4+ot))))
5214   - break;
  5205 + gen_check_io(s, ot, pc_start - s->cs_base,
  5206 + svm_is_rep(prefixes));
5215 5207 gen_op_mov_TN_reg(ot, 1, R_EAX);
5216   - gen_op_out[ot]();
  5208 +
  5209 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
  5210 + tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
  5211 + tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[1]);
  5212 + tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
5217 5213 break;
5218 5214  
5219 5215 /************************/
... ... @@ -5246,7 +5242,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5246 5242 if (s->cc_op != CC_OP_DYNAMIC)
5247 5243 gen_op_set_cc_op(s->cc_op);
5248 5244 gen_jmp_im(pc_start - s->cs_base);
5249   - gen_op_lret_protected(s->dflag, val);
  5245 + tcg_gen_helper_0_2(helper_lret_protected,
  5246 + tcg_const_i32(s->dflag),
  5247 + tcg_const_i32(val));
5250 5248 } else {
5251 5249 gen_stack_A0(s);
5252 5250 /* pop offset */
... ... @@ -5273,20 +5271,22 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5273 5271 break;
5274 5272 if (!s->pe) {
5275 5273 /* real mode */
5276   - gen_op_iret_real(s->dflag);
  5274 + tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5277 5275 s->cc_op = CC_OP_EFLAGS;
5278 5276 } else if (s->vm86) {
5279 5277 if (s->iopl != 3) {
5280 5278 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5281 5279 } else {
5282   - gen_op_iret_real(s->dflag);
  5280 + tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5283 5281 s->cc_op = CC_OP_EFLAGS;
5284 5282 }
5285 5283 } else {
5286 5284 if (s->cc_op != CC_OP_DYNAMIC)
5287 5285 gen_op_set_cc_op(s->cc_op);
5288 5286 gen_jmp_im(pc_start - s->cs_base);
5289   - gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
  5287 + tcg_gen_helper_0_2(helper_iret_protected,
  5288 + tcg_const_i32(s->dflag),
  5289 + tcg_const_i32(s->pc - s->cs_base));
5290 5290 s->cc_op = CC_OP_EFLAGS;
5291 5291 }
5292 5292 gen_eob(s);
... ... @@ -5723,10 +5723,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5723 5723 gen_op_mov_TN_reg(ot, 0, reg);
5724 5724 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5725 5725 gen_jmp_im(pc_start - s->cs_base);
  5726 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
5726 5727 if (ot == OT_WORD)
5727   - tcg_gen_helper_0_0(helper_boundw);
  5728 + tcg_gen_helper_0_2(helper_boundw, cpu_A0, cpu_tmp2);
5728 5729 else
5729   - tcg_gen_helper_0_0(helper_boundl);
  5730 + tcg_gen_helper_0_2(helper_boundl, cpu_A0, cpu_tmp2);
5730 5731 break;
5731 5732 case 0x1c8 ... 0x1cf: /* bswap reg */
5732 5733 reg = (b & 7) | REX_B(s);
... ... @@ -6134,7 +6135,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6134 6135 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
6135 6136 break;
6136 6137 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6137   - gen_op_lmsw_T0();
  6138 + tcg_gen_helper_0_1(helper_lmsw, cpu_T[0]);
6138 6139 gen_jmp_im(s->pc - s->cs_base);
6139 6140 gen_eob(s);
6140 6141 }
... ... @@ -6223,6 +6224,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6223 6224 } else {
6224 6225 gen_op_mov_TN_reg(ot, 0, rm);
6225 6226 }
  6227 + gen_op_mov_TN_reg(ot, 1, reg);
6226 6228 if (s->cc_op != CC_OP_DYNAMIC)
6227 6229 gen_op_set_cc_op(s->cc_op);
6228 6230 gen_op_arpl();
... ... @@ -6299,14 +6301,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6299 6301 if (b & 2) {
6300 6302 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
6301 6303 gen_op_mov_TN_reg(ot, 0, rm);
6302   - gen_op_movl_crN_T0(reg);
  6304 + tcg_gen_helper_0_2(helper_movl_crN_T0,
  6305 + tcg_const_i32(reg), cpu_T[0]);
6303 6306 gen_jmp_im(s->pc - s->cs_base);
6304 6307 gen_eob(s);
6305 6308 } else {
6306 6309 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
6307 6310 #if !defined(CONFIG_USER_ONLY)
6308 6311 if (reg == 8)
6309   - gen_op_movtl_T0_cr8();
  6312 + tcg_gen_helper_1_0(helper_movtl_T0_cr8, cpu_T[0]);
6310 6313 else
6311 6314 #endif
6312 6315 gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
... ... @@ -6338,7 +6341,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6338 6341 if (b & 2) {
6339 6342 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
6340 6343 gen_op_mov_TN_reg(ot, 0, rm);
6341   - gen_op_movl_drN_T0(reg);
  6344 + tcg_gen_helper_0_2(helper_movl_drN_T0,
  6345 + tcg_const_i32(reg), cpu_T[0]);
6342 6346 gen_jmp_im(s->pc - s->cs_base);
6343 6347 gen_eob(s);
6344 6348 } else {
... ... @@ -6353,7 +6357,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6353 6357 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6354 6358 } else {
6355 6359 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
6356   - gen_op_clts();
  6360 + tcg_gen_helper_0_0(helper_clts);
6357 6361 /* abort block because static cpu state changed */
6358 6362 gen_jmp_im(s->pc - s->cs_base);
6359 6363 gen_eob(s);
... ... @@ -6485,11 +6489,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6485 6489 }
6486 6490 /* lock generation */
6487 6491 if (s->prefix & PREFIX_LOCK)
6488   - gen_op_unlock();
  6492 + tcg_gen_helper_0_0(helper_unlock);
6489 6493 return s->pc;
6490 6494 illegal_op:
6491 6495 if (s->prefix & PREFIX_LOCK)
6492   - gen_op_unlock();
  6496 + tcg_gen_helper_0_0(helper_unlock);
6493 6497 /* XXX: ensure that no lock was generated */
6494 6498 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
6495 6499 return s->pc;
... ... @@ -6861,7 +6865,8 @@ void optimize_flags_init(void)
6861 6865 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
6862 6866 cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
6863 6867 #endif
6864   -#if defined(__i386__)
  6868 +#if defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS)
  6869 + /* XXX: must be suppressed once there are less fixed registers */
6865 6870 cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
6866 6871 #endif
6867 6872 }
... ... @@ -6957,10 +6962,11 @@ static inline int gen_intermediate_code_internal(CPUState *env,
6957 6962 #endif
6958 6963  
6959 6964 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
6960   -#if !defined(__i386__)
  6965 +#if !(defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS))
6961 6966 cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64);
6962 6967 #endif
6963 6968 cpu_tmp2 = tcg_temp_new(TCG_TYPE_I32);
  6969 + cpu_tmp3 = tcg_temp_new(TCG_TYPE_I32);
6964 6970 cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
6965 6971 cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
6966 6972  
... ...