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,12 +3,13 @@ Correctness issues:
3 - rework eflags optimization (will be a consequence of TCG port) 3 - rework eflags optimization (will be a consequence of TCG port)
4 - SVM: rework the implementation: simplify code, move most intercept 4 - SVM: rework the implementation: simplify code, move most intercept
5 tests as dynamic, correct segment access, verify exception safety, 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 - arpl eflags computation is invalid 7 - arpl eflags computation is invalid
8 - x86_64: fxsave/fxrestore intel/amd differences 8 - x86_64: fxsave/fxrestore intel/amd differences
9 - x86_64: lcall/ljmp intel/amd differences ? 9 - x86_64: lcall/ljmp intel/amd differences ?
10 - x86_64: cmpxchgl intel/amd differences ? 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 - x86: monitor invalid 13 - x86: monitor invalid
13 - better code fetch (different exception handling + CS.limit support) 14 - better code fetch (different exception handling + CS.limit support)
14 - user/kernel PUSHL/POPL in helper.c 15 - user/kernel PUSHL/POPL in helper.c
@@ -19,10 +20,18 @@ Correctness issues: @@ -19,10 +20,18 @@ Correctness issues:
19 - full support of segment limit/rights 20 - full support of segment limit/rights
20 - full x87 exception support 21 - full x87 exception support
21 - improve x87 bit exactness (use bochs code ?) 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 Optimizations/Features: 28 Optimizations/Features:
24 29
25 - finish TCG port 30 - finish TCG port
  31 +- add SVM nested paging support
  32 +- add VMX support
  33 +- add AVX support
  34 +- add SSE5 support
26 - evaluate x87 stack pointer statically 35 - evaluate x87 stack pointer statically
27 - find a way to avoid translating several time the same TB if CR0.TS 36 - find a way to avoid translating several time the same TB if CR0.TS
28 is set or not. 37 is set or not.
target-i386/exec.h
@@ -105,16 +105,6 @@ typedef struct CCTable { @@ -105,16 +105,6 @@ typedef struct CCTable {
105 105
106 extern CCTable cc_table[]; 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 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); 108 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
119 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); 109 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
120 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); 110 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
@@ -141,17 +131,10 @@ void OPPROTO op_movl_T0_eflags(void); @@ -141,17 +131,10 @@ void OPPROTO op_movl_T0_eflags(void);
141 131
142 #include "helper.h" 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 #if !defined(CONFIG_USER_ONLY) 139 #if !defined(CONFIG_USER_ONLY)
157 140
@@ -363,7 +346,6 @@ extern const CPU86_LDouble f15rk[7]; @@ -363,7 +346,6 @@ extern const CPU86_LDouble f15rk[7];
363 void fpu_raise_exception(void); 346 void fpu_raise_exception(void);
364 void restore_native_fp_state(CPUState *env); 347 void restore_native_fp_state(CPUState *env);
365 void save_native_fp_state(CPUState *env); 348 void save_native_fp_state(CPUState *env);
366 -void vmexit(uint64_t exit_code, uint64_t exit_info_1);  
367 349
368 extern const uint8_t parity_table[256]; 350 extern const uint8_t parity_table[256];
369 extern const uint8_t rclw_table[32]; 351 extern const uint8_t rclw_table[32];
target-i386/helper.c
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
17 * License along with this library; if not, write to the Free Software 17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
  20 +#define CPU_NO_GLOBAL_REGS
20 #include "exec.h" 21 #include "exec.h"
21 #include "host-utils.h" 22 #include "host-utils.h"
22 23
@@ -93,16 +94,16 @@ const CPU86_LDouble f15rk[7] = @@ -93,16 +94,16 @@ const CPU86_LDouble f15rk[7] =
93 3.32192809488736234781L, /*l2t*/ 94 3.32192809488736234781L, /*l2t*/
94 }; 95 };
95 96
96 -/* thread support */ 97 +/* broken thread support */
97 98
98 spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; 99 spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
99 100
100 -void cpu_lock(void) 101 +void helper_lock(void)
101 { 102 {
102 spin_lock(&global_cpu_lock); 103 spin_lock(&global_cpu_lock);
103 } 104 }
104 105
105 -void cpu_unlock(void) 106 +void helper_unlock(void)
106 { 107 {
107 spin_unlock(&global_cpu_lock); 108 spin_unlock(&global_cpu_lock);
108 } 109 }
@@ -508,34 +509,49 @@ static inline void check_io(int addr, int size) @@ -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 static inline unsigned int get_sp_mask(unsigned int e2) 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,7 +1291,7 @@ void raise_interrupt(int intno, int is_int, int error_code,
1275 int next_eip_addend) 1291 int next_eip_addend)
1276 { 1292 {
1277 if (!is_int) { 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 intno = check_exception(intno, &error_code); 1295 intno = check_exception(intno, &error_code);
1280 } 1296 }
1281 1297
@@ -1857,19 +1873,19 @@ void helper_das(void) @@ -1857,19 +1873,19 @@ void helper_das(void)
1857 FORCE_RET(); 1873 FORCE_RET();
1858 } 1874 }
1859 1875
1860 -void helper_cmpxchg8b(void) 1876 +void helper_cmpxchg8b(target_ulong a0)
1861 { 1877 {
1862 uint64_t d; 1878 uint64_t d;
1863 int eflags; 1879 int eflags;
1864 1880
1865 eflags = cc_table[CC_OP].compute_all(); 1881 eflags = cc_table[CC_OP].compute_all();
1866 - d = ldq(A0); 1882 + d = ldq(a0);
1867 if (d == (((uint64_t)EDX << 32) | EAX)) { 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 eflags |= CC_Z; 1885 eflags |= CC_Z;
1870 } else { 1886 } else {
1871 - EDX = d >> 32;  
1872 - EAX = d; 1887 + EDX = (uint32_t)(d >> 32);
  1888 + EAX = (uint32_t)d;
1873 eflags &= ~CC_Z; 1889 eflags &= ~CC_Z;
1874 } 1890 }
1875 CC_SRC = eflags; 1891 CC_SRC = eflags;
@@ -1986,7 +2002,7 @@ void helper_cpuid(void) @@ -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 target_ulong ssp; 2007 target_ulong ssp;
1992 uint32_t esp_mask, esp, ebp; 2008 uint32_t esp_mask, esp, ebp;
@@ -2004,7 +2020,7 @@ void helper_enter_level(int level, int data32) @@ -2004,7 +2020,7 @@ void helper_enter_level(int level, int data32)
2004 stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask))); 2020 stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
2005 } 2021 }
2006 esp -= 4; 2022 esp -= 4;
2007 - stl(ssp + (esp & esp_mask), T1); 2023 + stl(ssp + (esp & esp_mask), t1);
2008 } else { 2024 } else {
2009 /* 16 bit */ 2025 /* 16 bit */
2010 esp -= 2; 2026 esp -= 2;
@@ -2014,12 +2030,12 @@ void helper_enter_level(int level, int data32) @@ -2014,12 +2030,12 @@ void helper_enter_level(int level, int data32)
2014 stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask))); 2030 stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
2015 } 2031 }
2016 esp -= 2; 2032 esp -= 2;
2017 - stw(ssp + (esp & esp_mask), T1); 2033 + stw(ssp + (esp & esp_mask), t1);
2018 } 2034 }
2019 } 2035 }
2020 2036
2021 #ifdef TARGET_X86_64 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 target_ulong esp, ebp; 2040 target_ulong esp, ebp;
2025 ebp = EBP; 2041 ebp = EBP;
@@ -2034,7 +2050,7 @@ void helper_enter64_level(int level, int data64) @@ -2034,7 +2050,7 @@ void helper_enter64_level(int level, int data64)
2034 stq(esp, ldq(ebp)); 2050 stq(esp, ldq(ebp));
2035 } 2051 }
2036 esp -= 8; 2052 esp -= 8;
2037 - stq(esp, T1); 2053 + stq(esp, t1);
2038 } else { 2054 } else {
2039 /* 16 bit */ 2055 /* 16 bit */
2040 esp -= 2; 2056 esp -= 2;
@@ -2044,7 +2060,7 @@ void helper_enter64_level(int level, int data64) @@ -2044,7 +2060,7 @@ void helper_enter64_level(int level, int data64)
2044 stw(esp, lduw(ebp)); 2060 stw(esp, lduw(ebp));
2045 } 2061 }
2046 esp -= 2; 2062 esp -= 2;
2047 - stw(esp, T1); 2063 + stw(esp, t1);
2048 } 2064 }
2049 } 2065 }
2050 #endif 2066 #endif
@@ -2231,14 +2247,13 @@ void helper_load_seg(int seg_reg, int selector) @@ -2231,14 +2247,13 @@ void helper_load_seg(int seg_reg, int selector)
2231 } 2247 }
2232 2248
2233 /* protected mode jump */ 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 uint32_t e1, e2, cpl, dpl, rpl, limit; 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 if ((new_cs & 0xfffc) == 0) 2257 if ((new_cs & 0xfffc) == 0)
2243 raise_exception_err(EXCP0D_GPF, 0); 2258 raise_exception_err(EXCP0D_GPF, 0);
2244 if (load_segment(&e1, &e2, new_cs) != 0) 2259 if (load_segment(&e1, &e2, new_cs) != 0)
@@ -2322,14 +2337,14 @@ void helper_ljmp_protected_T0_T1(int next_eip_addend) @@ -2322,14 +2337,14 @@ void helper_ljmp_protected_T0_T1(int next_eip_addend)
2322 } 2337 }
2323 2338
2324 /* real mode call */ 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 uint32_t esp, esp_mask; 2344 uint32_t esp, esp_mask;
2329 target_ulong ssp; 2345 target_ulong ssp;
2330 2346
2331 - new_cs = T0;  
2332 - new_eip = T1; 2347 + new_eip = new_eip1;
2333 esp = ESP; 2348 esp = ESP;
2334 esp_mask = get_sp_mask(env->segs[R_SS].flags); 2349 esp_mask = get_sp_mask(env->segs[R_SS].flags);
2335 ssp = env->segs[R_SS].base; 2350 ssp = env->segs[R_SS].base;
@@ -2348,16 +2363,15 @@ void helper_lcall_real_T0_T1(int shift, int next_eip) @@ -2348,16 +2363,15 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
2348 } 2363 }
2349 2364
2350 /* protected mode call */ 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 uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count; 2370 uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
2355 uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask; 2371 uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
2356 uint32_t val, limit, old_sp_mask; 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 next_eip = env->eip + next_eip_addend; 2375 next_eip = env->eip + next_eip_addend;
2362 #ifdef DEBUG_PCALL 2376 #ifdef DEBUG_PCALL
2363 if (loglevel & CPU_LOG_PCALL) { 2377 if (loglevel & CPU_LOG_PCALL) {
@@ -2922,34 +2936,55 @@ void helper_sysexit(void) @@ -2922,34 +2936,55 @@ void helper_sysexit(void)
2922 #endif 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 #if !defined(CONFIG_USER_ONLY) 2941 #if !defined(CONFIG_USER_ONLY)
2928 switch(reg) { 2942 switch(reg) {
2929 case 0: 2943 case 0:
2930 - cpu_x86_update_cr0(env, T0); 2944 + cpu_x86_update_cr0(env, t0);
2931 break; 2945 break;
2932 case 3: 2946 case 3:
2933 - cpu_x86_update_cr3(env, T0); 2947 + cpu_x86_update_cr3(env, t0);
2934 break; 2948 break;
2935 case 4: 2949 case 4:
2936 - cpu_x86_update_cr4(env, T0); 2950 + cpu_x86_update_cr4(env, t0);
2937 break; 2951 break;
2938 case 8: 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 break; 2955 break;
2942 default: 2956 default:
2943 - env->cr[reg] = T0; 2957 + env->cr[reg] = t0;
2944 break; 2958 break;
2945 } 2959 }
2946 #endif 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 /* XXX: do more */ 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 void helper_invlpg(target_ulong addr) 2990 void helper_invlpg(target_ulong addr)
@@ -2975,10 +3010,10 @@ void helper_rdpmc(void) @@ -2975,10 +3010,10 @@ void helper_rdpmc(void)
2975 raise_exception(EXCP0D_GPF); 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 #if defined(CONFIG_USER_ONLY) 3019 #if defined(CONFIG_USER_ONLY)
@@ -3118,7 +3153,7 @@ void helper_rdmsr(void) @@ -3118,7 +3153,7 @@ void helper_rdmsr(void)
3118 } 3153 }
3119 #endif 3154 #endif
3120 3155
3121 -void helper_lsl(uint32_t selector) 3156 +uint32_t helper_lsl(uint32_t selector)
3122 { 3157 {
3123 unsigned int limit; 3158 unsigned int limit;
3124 uint32_t e1, e2, eflags; 3159 uint32_t e1, e2, eflags;
@@ -3153,15 +3188,15 @@ void helper_lsl(uint32_t selector) @@ -3153,15 +3188,15 @@ void helper_lsl(uint32_t selector)
3153 if (dpl < cpl || dpl < rpl) { 3188 if (dpl < cpl || dpl < rpl) {
3154 fail: 3189 fail:
3155 CC_SRC = eflags & ~CC_Z; 3190 CC_SRC = eflags & ~CC_Z;
3156 - return; 3191 + return 0;
3157 } 3192 }
3158 } 3193 }
3159 limit = get_seg_limit(e1, e2); 3194 limit = get_seg_limit(e1, e2);
3160 - T1 = limit;  
3161 CC_SRC = eflags | CC_Z; 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 uint32_t e1, e2, eflags; 3201 uint32_t e1, e2, eflags;
3167 int rpl, dpl, cpl, type; 3202 int rpl, dpl, cpl, type;
@@ -3200,11 +3235,11 @@ void helper_lar(uint32_t selector) @@ -3200,11 +3235,11 @@ void helper_lar(uint32_t selector)
3200 if (dpl < cpl || dpl < rpl) { 3235 if (dpl < cpl || dpl < rpl) {
3201 fail: 3236 fail:
3202 CC_SRC = eflags & ~CC_Z; 3237 CC_SRC = eflags & ~CC_Z;
3203 - return; 3238 + return 0;
3204 } 3239 }
3205 } 3240 }
3206 - T1 = e2 & 0x00f0ff00;  
3207 CC_SRC = eflags | CC_Z; 3241 CC_SRC = eflags | CC_Z;
  3242 + return e2 & 0x00f0ff00;
3208 } 3243 }
3209 3244
3210 void helper_verr(uint32_t selector) 3245 void helper_verr(uint32_t selector)
@@ -4412,36 +4447,36 @@ static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b) @@ -4412,36 +4447,36 @@ static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
4412 return 0; 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 uint64_t r0, r1; 4452 uint64_t r0, r1;
4418 4453
4419 - mulu64(&r0, &r1, EAX, T0); 4454 + mulu64(&r0, &r1, EAX, t0);
4420 EAX = r0; 4455 EAX = r0;
4421 EDX = r1; 4456 EDX = r1;
4422 CC_DST = r0; 4457 CC_DST = r0;
4423 CC_SRC = r1; 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 uint64_t r0, r1; 4463 uint64_t r0, r1;
4429 4464
4430 - muls64(&r0, &r1, EAX, T0); 4465 + muls64(&r0, &r1, EAX, t0);
4431 EAX = r0; 4466 EAX = r0;
4432 EDX = r1; 4467 EDX = r1;
4433 CC_DST = r0; 4468 CC_DST = r0;
4434 CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); 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 uint64_t r0, r1; 4474 uint64_t r0, r1;
4440 4475
4441 - muls64(&r0, &r1, T0, T1);  
4442 - T0 = r0; 4476 + muls64(&r0, &r1, t0, t1);
4443 CC_DST = r0; 4477 CC_DST = r0;
4444 CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); 4478 CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
  4479 + return r0;
4445 } 4480 }
4446 4481
4447 void helper_divq_EAX(target_ulong t0) 4482 void helper_divq_EAX(target_ulong t0)
@@ -4553,24 +4588,23 @@ void helper_reset_inhibit_irq(void) @@ -4553,24 +4588,23 @@ void helper_reset_inhibit_irq(void)
4553 env->hflags &= ~HF_INHIBIT_IRQ_MASK; 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 if (v < low || v > high) { 4597 if (v < low || v > high) {
4563 raise_exception(EXCP05_BOUND); 4598 raise_exception(EXCP05_BOUND);
4564 } 4599 }
4565 FORCE_RET(); 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 if (v < low || v > high) { 4608 if (v < low || v > high) {
4575 raise_exception(EXCP05_BOUND); 4609 raise_exception(EXCP05_BOUND);
4576 } 4610 }
@@ -4661,18 +4695,35 @@ void helper_clgi(void) @@ -4661,18 +4695,35 @@ void helper_clgi(void)
4661 4695
4662 #if defined(CONFIG_USER_ONLY) 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 #else 4727 #else
4677 4728
4678 static inline uint32_t 4729 static inline uint32_t
@@ -4702,7 +4753,6 @@ void helper_vmrun(void) @@ -4702,7 +4753,6 @@ void helper_vmrun(void)
4702 fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr); 4753 fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr);
4703 4754
4704 env->vm_vmcb = addr; 4755 env->vm_vmcb = addr;
4705 - regs_to_env();  
4706 4756
4707 /* save the current CPU state in the hsave page */ 4757 /* save the current CPU state in the hsave page */
4708 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base); 4758 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);
@@ -4801,8 +4851,6 @@ void helper_vmrun(void) @@ -4801,8 +4851,6 @@ void helper_vmrun(void)
4801 4851
4802 helper_stgi(); 4852 helper_stgi();
4803 4853
4804 - regs_to_env();  
4805 -  
4806 /* maybe we need to inject an event */ 4854 /* maybe we need to inject an event */
4807 event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); 4855 event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
4808 if (event_inj & SVM_EVTINJ_VALID) { 4856 if (event_inj & SVM_EVTINJ_VALID) {
@@ -4927,95 +4975,98 @@ void helper_invlpga(void) @@ -4927,95 +4975,98 @@ void helper_invlpga(void)
4927 tlb_flush(env, 0); 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 switch(type) { 4980 switch(type) {
4933 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8: 4981 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
4934 if (INTERCEPTEDw(_cr_read, (1 << (type - SVM_EXIT_READ_CR0)))) { 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 break; 4985 break;
4939 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 8: 4986 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 8:
4940 if (INTERCEPTEDw(_dr_read, (1 << (type - SVM_EXIT_READ_DR0)))) { 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 break; 4990 break;
4945 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8: 4991 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
4946 if (INTERCEPTEDw(_cr_write, (1 << (type - SVM_EXIT_WRITE_CR0)))) { 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 break; 4995 break;
4951 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 8: 4996 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 8:
4952 if (INTERCEPTEDw(_dr_write, (1 << (type - SVM_EXIT_WRITE_DR0)))) { 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 break; 5000 break;
4957 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 16: 5001 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 16:
4958 if (INTERCEPTEDl(_exceptions, (1 << (type - SVM_EXIT_EXCP_BASE)))) { 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 break; 5005 break;
4963 case SVM_EXIT_IOIO: 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 break; 5007 break;
4974 5008
4975 case SVM_EXIT_MSR: 5009 case SVM_EXIT_MSR:
4976 if (INTERCEPTED(1ULL << INTERCEPT_MSR_PROT)) { 5010 if (INTERCEPTED(1ULL << INTERCEPT_MSR_PROT)) {
4977 /* FIXME: this should be read in at vmrun (faster this way?) */ 5011 /* FIXME: this should be read in at vmrun (faster this way?) */
4978 uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa)); 5012 uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa));
  5013 + uint32_t t0, t1;
4979 switch((uint32_t)ECX) { 5014 switch((uint32_t)ECX) {
4980 case 0 ... 0x1fff: 5015 case 0 ... 0x1fff:
4981 - T0 = (ECX * 2) % 8;  
4982 - T1 = ECX / 8; 5016 + t0 = (ECX * 2) % 8;
  5017 + t1 = ECX / 8;
4983 break; 5018 break;
4984 case 0xc0000000 ... 0xc0001fff: 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 break; 5023 break;
4989 case 0xc0010000 ... 0xc0011fff: 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 break; 5028 break;
4994 default: 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 break; 5038 break;
5003 default: 5039 default:
5004 if (INTERCEPTED((1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR)))) { 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 break; 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 uint32_t int_ctl; 5066 uint32_t int_ctl;
5016 5067
5017 if (loglevel & CPU_LOG_TB_IN_ASM) 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 exit_code, exit_info_1, 5070 exit_code, exit_info_1,
5020 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)), 5071 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
5021 EIP); 5072 EIP);
@@ -5105,8 +5156,7 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1) @@ -5105,8 +5156,7 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
5105 5156
5106 /* other setups */ 5157 /* other setups */
5107 cpu_x86_set_cpl(env, 0); 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 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1); 5160 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
5111 5161
5112 helper_clgi(); 5162 helper_clgi();
@@ -5137,7 +5187,6 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1) @@ -5137,7 +5187,6 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
5137 env->error_code = 0; 5187 env->error_code = 0;
5138 env->old_exception = -1; 5188 env->old_exception = -1;
5139 5189
5140 - regs_to_env();  
5141 cpu_loop_exit(); 5190 cpu_loop_exit();
5142 } 5191 }
5143 5192
target-i386/helper.h
1 #define TCG_HELPER_PROTO 1 #define TCG_HELPER_PROTO
2 2
  3 +void helper_lock(void);
  4 +void helper_unlock(void);
3 void helper_divb_AL(target_ulong t0); 5 void helper_divb_AL(target_ulong t0);
4 void helper_idivb_AL(target_ulong t0); 6 void helper_idivb_AL(target_ulong t0);
5 void helper_divw_AX(target_ulong t0); 7 void helper_divw_AX(target_ulong t0);
@@ -7,6 +9,9 @@ void helper_idivw_AX(target_ulong t0); @@ -7,6 +9,9 @@ void helper_idivw_AX(target_ulong t0);
7 void helper_divl_EAX(target_ulong t0); 9 void helper_divl_EAX(target_ulong t0);
8 void helper_idivl_EAX(target_ulong t0); 10 void helper_idivl_EAX(target_ulong t0);
9 #ifdef TARGET_X86_64 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 void helper_divq_EAX(target_ulong t0); 15 void helper_divq_EAX(target_ulong t0);
11 void helper_idivq_EAX(target_ulong t0); 16 void helper_idivq_EAX(target_ulong t0);
12 #endif 17 #endif
@@ -18,26 +23,34 @@ void helper_aas(void); @@ -18,26 +23,34 @@ void helper_aas(void);
18 void helper_daa(void); 23 void helper_daa(void);
19 void helper_das(void); 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 void helper_verr(uint32_t selector); 28 void helper_verr(uint32_t selector);
24 void helper_verw(uint32_t selector); 29 void helper_verw(uint32_t selector);
25 void helper_lldt(int selector); 30 void helper_lldt(int selector);
26 void helper_ltr(int selector); 31 void helper_ltr(int selector);
27 void helper_load_seg(int seg_reg, int selector); 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 void helper_iret_real(int shift); 39 void helper_iret_real(int shift);
32 void helper_iret_protected(int shift, int next_eip); 40 void helper_iret_protected(int shift, int next_eip);
33 void helper_lret_protected(int shift, int addend); 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 void helper_invlpg(target_ulong addr); 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 #ifdef TARGET_X86_64 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 #endif 54 #endif
42 void helper_sysenter(void); 55 void helper_sysenter(void);
43 void helper_sysexit(void); 56 void helper_sysexit(void);
@@ -55,9 +68,10 @@ void helper_cli(void); @@ -55,9 +68,10 @@ void helper_cli(void);
55 void helper_sti(void); 68 void helper_sti(void);
56 void helper_set_inhibit_irq(void); 69 void helper_set_inhibit_irq(void);
57 void helper_reset_inhibit_irq(void); 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 void helper_rsm(void); 73 void helper_rsm(void);
  74 +void helper_cmpxchg8b(target_ulong a0);
61 void helper_single_step(void); 75 void helper_single_step(void);
62 void helper_cpuid(void); 76 void helper_cpuid(void);
63 void helper_rdtsc(void); 77 void helper_rdtsc(void);
@@ -65,6 +79,20 @@ void helper_rdpmc(void); @@ -65,6 +79,20 @@ void helper_rdpmc(void);
65 void helper_rdmsr(void); 79 void helper_rdmsr(void);
66 void helper_wrmsr(void); 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 void helper_vmrun(void); 96 void helper_vmrun(void);
69 void helper_vmmcall(void); 97 void helper_vmmcall(void);
70 void helper_vmload(void); 98 void helper_vmload(void);
target-i386/op.c
@@ -276,17 +276,17 @@ void OPPROTO op_imull_T0_T1(void) @@ -276,17 +276,17 @@ void OPPROTO op_imull_T0_T1(void)
276 #ifdef TARGET_X86_64 276 #ifdef TARGET_X86_64
277 void OPPROTO op_mulq_EAX_T0(void) 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 void OPPROTO op_imulq_EAX_T0(void) 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 void OPPROTO op_imulq_T0_T1(void) 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 #endif 291 #endif
292 292
@@ -351,7 +351,7 @@ void OPPROTO op_into(void) @@ -351,7 +351,7 @@ void OPPROTO op_into(void)
351 351
352 void OPPROTO op_cmpxchg8b(void) 352 void OPPROTO op_cmpxchg8b(void)
353 { 353 {
354 - helper_cmpxchg8b(); 354 + helper_cmpxchg8b(A0);
355 } 355 }
356 356
357 /* multiple size ops */ 357 /* multiple size ops */
@@ -522,12 +522,6 @@ void OPPROTO op_das(void) @@ -522,12 +522,6 @@ void OPPROTO op_das(void)
522 522
523 /* segment handling */ 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 /* faster VM86 version */ 525 /* faster VM86 version */
532 void OPPROTO op_movl_seg_T0_vm(void) 526 void OPPROTO op_movl_seg_T0_vm(void)
533 { 527 {
@@ -548,12 +542,20 @@ void OPPROTO op_movl_T0_seg(void) @@ -548,12 +542,20 @@ void OPPROTO op_movl_T0_seg(void)
548 542
549 void OPPROTO op_lsl(void) 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 void OPPROTO op_lar(void) 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 void OPPROTO op_verr(void) 561 void OPPROTO op_verr(void)
@@ -585,104 +587,6 @@ void OPPROTO op_arpl_update(void) @@ -585,104 +587,6 @@ void OPPROTO op_arpl_update(void)
585 CC_SRC = (eflags & ~CC_Z) | T1; 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 void OPPROTO op_movl_T0_env(void) 590 void OPPROTO op_movl_T0_env(void)
687 { 591 {
688 T0 = *(uint32_t *)((char *)env + PARAM1); 592 T0 = *(uint32_t *)((char *)env + PARAM1);
@@ -718,12 +622,6 @@ void OPPROTO op_movtl_env_T1(void) @@ -718,12 +622,6 @@ void OPPROTO op_movtl_env_T1(void)
718 *(target_ulong *)((char *)env + PARAM1) = T1; 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 /* flags handling */ 625 /* flags handling */
728 626
729 void OPPROTO op_jmp_label(void) 627 void OPPROTO op_jmp_label(void)
@@ -1028,17 +926,6 @@ void OPPROTO op_fcomi_dummy(void) @@ -1028,17 +926,6 @@ void OPPROTO op_fcomi_dummy(void)
1028 T0 = 0; 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 /* SSE support */ 929 /* SSE support */
1043 void OPPROTO op_com_dummy(void) 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,12 +471,12 @@ void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s)
471 #endif 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 int i; 476 int i;
477 for(i = 0; i < (8 << SHIFT); i++) { 477 for(i = 0; i < (8 << SHIFT); i++) {
478 if (s->B(i) & 0x80) 478 if (s->B(i) & 0x80)
479 - stb(A0 + i, d->B(i)); 479 + stb(a0 + i, d->B(i));
480 } 480 }
481 FORCE_RET(); 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,7 +104,7 @@ void glue(helper_pmuludq, SUFFIX) (Reg *d, Reg *s);
104 void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s); 104 void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s);
105 105
106 void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s); 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 void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val); 108 void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val);
109 #ifdef TARGET_X86_64 109 #ifdef TARGET_X86_64
110 void glue(helper_movq_mm_T0, SUFFIX) (Reg *d, uint64_t val); 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,39 +554,6 @@ void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
554 T0 = DF << SHIFT; 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 #undef DATA_BITS 557 #undef DATA_BITS
591 #undef SHIFT_MASK 558 #undef SHIFT_MASK
592 #undef SHIFT1_MASK 559 #undef SHIFT1_MASK
target-i386/svm.h
@@ -71,8 +71,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area { @@ -71,8 +71,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
71 uint32_t int_vector; 71 uint32_t int_vector;
72 uint32_t int_state; 72 uint32_t int_state;
73 uint8_t reserved_3[4]; 73 uint8_t reserved_3[4];
74 - uint32_t exit_code;  
75 - uint32_t exit_code_hi; 74 + uint64_t exit_code;
76 uint64_t exit_info_1; 75 uint64_t exit_info_1;
77 uint64_t exit_info_2; 76 uint64_t exit_info_2;
78 uint32_t exit_int_info; 77 uint32_t exit_int_info;
@@ -323,14 +322,6 @@ struct __attribute__ ((__packed__)) vmcb { @@ -323,14 +322,6 @@ struct __attribute__ ((__packed__)) vmcb {
323 322
324 /* function references */ 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 #define INTERCEPTED(mask) (env->intercept & mask) 325 #define INTERCEPTED(mask) (env->intercept & mask)
335 #define INTERCEPTEDw(var, mask) (env->intercept ## var & mask) 326 #define INTERCEPTEDw(var, mask) (env->intercept ## var & mask)
336 #define INTERCEPTEDl(var, mask) (env->intercept ## var & mask) 327 #define INTERCEPTEDl(var, mask) (env->intercept ## var & mask)
target-i386/translate.c
@@ -60,7 +60,7 @@ @@ -60,7 +60,7 @@
60 /* global register indexes */ 60 /* global register indexes */
61 static TCGv cpu_env, cpu_T[2], cpu_A0; 61 static TCGv cpu_env, cpu_T[2], cpu_A0;
62 /* local register indexes (only used inside old micro ops) */ 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 #ifdef TARGET_X86_64 65 #ifdef TARGET_X86_64
66 static int x86_64_hregs; 66 static int x86_64_hregs;
@@ -903,52 +903,54 @@ static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = { @@ -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 if (s->pe && (s->cpl > s->iopl || s->vm86)) { 931 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
945 if (s->cc_op != CC_OP_DYNAMIC) 932 if (s->cc_op != CC_OP_DYNAMIC)
946 gen_op_set_cc_op(s->cc_op); 933 gen_op_set_cc_op(s->cc_op);
947 gen_jmp_im(cur_eip); 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,7 +1082,10 @@ static inline void gen_ins(DisasContext *s, int ot)
1080 gen_string_movl_A0_EDI(s); 1082 gen_string_movl_A0_EDI(s);
1081 gen_op_movl_T0_0(); 1083 gen_op_movl_T0_0();
1082 gen_op_st_T0_A0(ot + s->mem_index); 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 gen_op_st_T0_A0(ot + s->mem_index); 1089 gen_op_st_T0_A0(ot + s->mem_index);
1085 gen_op_movl_T0_Dshift[ot](); 1090 gen_op_movl_T0_Dshift[ot]();
1086 #ifdef TARGET_X86_64 1091 #ifdef TARGET_X86_64
@@ -1099,7 +1104,13 @@ static inline void gen_outs(DisasContext *s, int ot) @@ -1099,7 +1104,13 @@ static inline void gen_outs(DisasContext *s, int ot)
1099 { 1104 {
1100 gen_string_movl_A0_ESI(s); 1105 gen_string_movl_A0_ESI(s);
1101 gen_op_ld_T0_A0(ot + s->mem_index); 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 gen_op_movl_T0_Dshift[ot](); 1114 gen_op_movl_T0_Dshift[ot]();
1104 #ifdef TARGET_X86_64 1115 #ifdef TARGET_X86_64
1105 if (s->aflag == 2) { 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,7 +1987,8 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
1976 if (s->cc_op != CC_OP_DYNAMIC) 1987 if (s->cc_op != CC_OP_DYNAMIC)
1977 gen_op_set_cc_op(s->cc_op); 1988 gen_op_set_cc_op(s->cc_op);
1978 gen_jmp_im(cur_eip); 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 /* abort translation because the addseg value may change or 1992 /* abort translation because the addseg value may change or
1981 because ss32 may change. For R_SS, translation must always 1993 because ss32 may change. For R_SS, translation must always
1982 stop as a special handling must be done to disable hardware 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,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 static inline int svm_is_rep(int prefixes) 2005 static inline int svm_is_rep(int prefixes)
2016 { 2006 {
2017 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0); 2007 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
@@ -2019,7 +2009,7 @@ static inline int svm_is_rep(int prefixes) @@ -2019,7 +2009,7 @@ static inline int svm_is_rep(int prefixes)
2019 2009
2020 static inline int 2010 static inline int
2021 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start, 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 if(!(s->flags & (INTERCEPT_SVM_MASK))) 2014 if(!(s->flags & (INTERCEPT_SVM_MASK)))
2025 /* no SVM activated */ 2015 /* no SVM activated */
@@ -2029,12 +2019,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start, @@ -2029,12 +2019,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2029 case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1: 2019 case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1:
2030 if (s->cc_op != CC_OP_DYNAMIC) { 2020 if (s->cc_op != CC_OP_DYNAMIC) {
2031 gen_op_set_cc_op(s->cc_op); 2021 gen_op_set_cc_op(s->cc_op);
2032 - s->cc_op = CC_OP_DYNAMIC;  
2033 } 2022 }
2034 gen_jmp_im(pc_start - s->cs_base); 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 /* this is a special case as we do not know if the interception occurs 2026 /* this is a special case as we do not know if the interception occurs
2039 so we assume there was none */ 2027 so we assume there was none */
2040 return 0; 2028 return 0;
@@ -2042,12 +2030,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start, @@ -2042,12 +2030,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2042 if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) { 2030 if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) {
2043 if (s->cc_op != CC_OP_DYNAMIC) { 2031 if (s->cc_op != CC_OP_DYNAMIC) {
2044 gen_op_set_cc_op(s->cc_op); 2032 gen_op_set_cc_op(s->cc_op);
2045 - s->cc_op = CC_OP_DYNAMIC;  
2046 } 2033 }
2047 gen_jmp_im(pc_start - s->cs_base); 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 /* this is a special case as we do not know if the interception occurs 2037 /* this is a special case as we do not know if the interception occurs
2052 so we assume there was none */ 2038 so we assume there was none */
2053 return 0; 2039 return 0;
@@ -2057,12 +2043,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start, @@ -2057,12 +2043,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2057 if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) { 2043 if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) {
2058 if (s->cc_op != CC_OP_DYNAMIC) { 2044 if (s->cc_op != CC_OP_DYNAMIC) {
2059 gen_op_set_cc_op(s->cc_op); 2045 gen_op_set_cc_op(s->cc_op);
2060 - s->cc_op = CC_OP_EFLAGS;  
2061 } 2046 }
2062 gen_jmp_im(pc_start - s->cs_base); 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 /* we can optimize this one so TBs don't get longer 2050 /* we can optimize this one so TBs don't get longer
2067 than up to vmexit */ 2051 than up to vmexit */
2068 gen_eob(s); 2052 gen_eob(s);
@@ -2276,9 +2260,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) @@ -2276,9 +2260,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
2276 gen_op_st_T0_A0(ot + s->mem_index); 2260 gen_op_st_T0_A0(ot + s->mem_index);
2277 if (level) { 2261 if (level) {
2278 /* XXX: must save state */ 2262 /* XXX: must save state */
2279 - tcg_gen_helper_0_2(helper_enter64_level, 2263 + tcg_gen_helper_0_3(helper_enter64_level,
2280 tcg_const_i32(level), 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 gen_op_mov_reg_T1(ot, R_EBP); 2268 gen_op_mov_reg_T1(ot, R_EBP);
2284 gen_op_addl_T1_im( -esp_addend + (-opsize * level) ); 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,9 +2286,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
2301 gen_op_st_T0_A0(ot + s->mem_index); 2286 gen_op_st_T0_A0(ot + s->mem_index);
2302 if (level) { 2287 if (level) {
2303 /* XXX: must save state */ 2288 /* XXX: must save state */
2304 - tcg_gen_helper_0_2(helper_enter_level, 2289 + tcg_gen_helper_0_3(helper_enter_level,
2305 tcg_const_i32(level), 2290 tcg_const_i32(level),
2306 - tcg_const_i32(s->dflag)); 2291 + tcg_const_i32(s->dflag),
  2292 + cpu_T[1]);
2307 } 2293 }
2308 gen_op_mov_reg_T1(ot, R_EBP); 2294 gen_op_mov_reg_T1(ot, R_EBP);
2309 gen_op_addl_T1_im( -esp_addend + (-opsize * level) ); 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,22 +3194,6 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3208 } else { 3194 } else {
3209 /* generic MMX or SSE operation */ 3195 /* generic MMX or SSE operation */
3210 switch(b) { 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 case 0x70: /* pshufx insn */ 3197 case 0x70: /* pshufx insn */
3228 case 0xc6: /* pshufx insn */ 3198 case 0xc6: /* pshufx insn */
3229 case 0xc2: /* compare insns */ 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,6 +3265,26 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3295 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 3265 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3296 tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1); 3266 tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
3297 break; 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 default: 3288 default:
3299 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 3289 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3300 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 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,7 +3430,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3440 3430
3441 /* lock generation */ 3431 /* lock generation */
3442 if (prefixes & PREFIX_LOCK) 3432 if (prefixes & PREFIX_LOCK)
3443 - gen_op_lock(); 3433 + tcg_gen_helper_0_0(helper_lock);
3444 3434
3445 /* now check op code */ 3435 /* now check op code */
3446 reswitch: 3436 reswitch:
@@ -3783,9 +3773,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -3783,9 +3773,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3783 if (s->cc_op != CC_OP_DYNAMIC) 3773 if (s->cc_op != CC_OP_DYNAMIC)
3784 gen_op_set_cc_op(s->cc_op); 3774 gen_op_set_cc_op(s->cc_op);
3785 gen_jmp_im(pc_start - s->cs_base); 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 } else { 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 gen_eob(s); 3788 gen_eob(s);
3791 break; 3789 break;
@@ -3804,7 +3802,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -3804,7 +3802,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3804 if (s->cc_op != CC_OP_DYNAMIC) 3802 if (s->cc_op != CC_OP_DYNAMIC)
3805 gen_op_set_cc_op(s->cc_op); 3803 gen_op_set_cc_op(s->cc_op);
3806 gen_jmp_im(pc_start - s->cs_base); 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 } else { 3810 } else {
3809 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); 3811 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3810 gen_op_movl_T0_T1(); 3812 gen_op_movl_T0_T1();
@@ -4355,11 +4357,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -4355,11 +4357,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
4355 gen_op_mov_TN_reg(ot, 0, reg); 4357 gen_op_mov_TN_reg(ot, 0, reg);
4356 /* for xchg, lock is implicit */ 4358 /* for xchg, lock is implicit */
4357 if (!(prefixes & PREFIX_LOCK)) 4359 if (!(prefixes & PREFIX_LOCK))
4358 - gen_op_lock(); 4360 + tcg_gen_helper_0_0(helper_lock);
4359 gen_op_ld_T1_A0(ot + s->mem_index); 4361 gen_op_ld_T1_A0(ot + s->mem_index);
4360 gen_op_st_T0_A0(ot + s->mem_index); 4362 gen_op_st_T0_A0(ot + s->mem_index);
4361 if (!(prefixes & PREFIX_LOCK)) 4363 if (!(prefixes & PREFIX_LOCK))
4362 - gen_op_unlock(); 4364 + tcg_gen_helper_0_0(helper_unlock);
4363 gen_op_mov_reg_T1(ot, reg); 4365 gen_op_mov_reg_T1(ot, reg);
4364 } 4366 }
4365 break; 4367 break;
@@ -5117,13 +5119,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5117,13 +5119,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5117 ot = OT_BYTE; 5119 ot = OT_BYTE;
5118 else 5120 else
5119 ot = dflag ? OT_LONG : OT_WORD; 5121 ot = dflag ? OT_LONG : OT_WORD;
5120 - gen_check_io(s, ot, 1, pc_start - s->cs_base);  
5121 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 5122 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5122 gen_op_andl_T0_ffff(); 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 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 5126 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5128 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 5127 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5129 } else { 5128 } else {
@@ -5136,13 +5135,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5136,13 +5135,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5136 ot = OT_BYTE; 5135 ot = OT_BYTE;
5137 else 5136 else
5138 ot = dflag ? OT_LONG : OT_WORD; 5137 ot = dflag ? OT_LONG : OT_WORD;
5139 - gen_check_io(s, ot, 1, pc_start - s->cs_base);  
5140 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 5138 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5141 gen_op_andl_T0_ffff(); 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 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 5142 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5147 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 5143 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5148 } else { 5144 } else {
@@ -5161,12 +5157,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5161,12 +5157,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5161 ot = dflag ? OT_LONG : OT_WORD; 5157 ot = dflag ? OT_LONG : OT_WORD;
5162 val = ldub_code(s->pc++); 5158 val = ldub_code(s->pc++);
5163 gen_op_movl_T0_im(val); 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 gen_op_mov_reg_T1(ot, R_EAX); 5164 gen_op_mov_reg_T1(ot, R_EAX);
5171 break; 5165 break;
5172 case 0xe6: 5166 case 0xe6:
@@ -5177,12 +5171,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5177,12 +5171,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5177 ot = dflag ? OT_LONG : OT_WORD; 5171 ot = dflag ? OT_LONG : OT_WORD;
5178 val = ldub_code(s->pc++); 5172 val = ldub_code(s->pc++);
5179 gen_op_movl_T0_im(val); 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 gen_op_mov_TN_reg(ot, 1, R_EAX); 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 break; 5182 break;
5187 case 0xec: 5183 case 0xec:
5188 case 0xed: 5184 case 0xed:
@@ -5192,12 +5188,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5192,12 +5188,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5192 ot = dflag ? OT_LONG : OT_WORD; 5188 ot = dflag ? OT_LONG : OT_WORD;
5193 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 5189 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5194 gen_op_andl_T0_ffff(); 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 gen_op_mov_reg_T1(ot, R_EAX); 5195 gen_op_mov_reg_T1(ot, R_EAX);
5202 break; 5196 break;
5203 case 0xee: 5197 case 0xee:
@@ -5208,12 +5202,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5208,12 +5202,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5208 ot = dflag ? OT_LONG : OT_WORD; 5202 ot = dflag ? OT_LONG : OT_WORD;
5209 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 5203 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5210 gen_op_andl_T0_ffff(); 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 gen_op_mov_TN_reg(ot, 1, R_EAX); 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 break; 5213 break;
5218 5214
5219 /************************/ 5215 /************************/
@@ -5246,7 +5242,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5246,7 +5242,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5246 if (s->cc_op != CC_OP_DYNAMIC) 5242 if (s->cc_op != CC_OP_DYNAMIC)
5247 gen_op_set_cc_op(s->cc_op); 5243 gen_op_set_cc_op(s->cc_op);
5248 gen_jmp_im(pc_start - s->cs_base); 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 } else { 5248 } else {
5251 gen_stack_A0(s); 5249 gen_stack_A0(s);
5252 /* pop offset */ 5250 /* pop offset */
@@ -5273,20 +5271,22 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5273,20 +5271,22 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5273 break; 5271 break;
5274 if (!s->pe) { 5272 if (!s->pe) {
5275 /* real mode */ 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 s->cc_op = CC_OP_EFLAGS; 5275 s->cc_op = CC_OP_EFLAGS;
5278 } else if (s->vm86) { 5276 } else if (s->vm86) {
5279 if (s->iopl != 3) { 5277 if (s->iopl != 3) {
5280 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 5278 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5281 } else { 5279 } else {
5282 - gen_op_iret_real(s->dflag); 5280 + tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5283 s->cc_op = CC_OP_EFLAGS; 5281 s->cc_op = CC_OP_EFLAGS;
5284 } 5282 }
5285 } else { 5283 } else {
5286 if (s->cc_op != CC_OP_DYNAMIC) 5284 if (s->cc_op != CC_OP_DYNAMIC)
5287 gen_op_set_cc_op(s->cc_op); 5285 gen_op_set_cc_op(s->cc_op);
5288 gen_jmp_im(pc_start - s->cs_base); 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 s->cc_op = CC_OP_EFLAGS; 5290 s->cc_op = CC_OP_EFLAGS;
5291 } 5291 }
5292 gen_eob(s); 5292 gen_eob(s);
@@ -5723,10 +5723,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5723,10 +5723,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5723 gen_op_mov_TN_reg(ot, 0, reg); 5723 gen_op_mov_TN_reg(ot, 0, reg);
5724 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 5724 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5725 gen_jmp_im(pc_start - s->cs_base); 5725 gen_jmp_im(pc_start - s->cs_base);
  5726 + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
5726 if (ot == OT_WORD) 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 else 5729 else
5729 - tcg_gen_helper_0_0(helper_boundl); 5730 + tcg_gen_helper_0_2(helper_boundl, cpu_A0, cpu_tmp2);
5730 break; 5731 break;
5731 case 0x1c8 ... 0x1cf: /* bswap reg */ 5732 case 0x1c8 ... 0x1cf: /* bswap reg */
5732 reg = (b & 7) | REX_B(s); 5733 reg = (b & 7) | REX_B(s);
@@ -6134,7 +6135,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6134,7 +6135,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6134 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0)) 6135 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
6135 break; 6136 break;
6136 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0); 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 gen_jmp_im(s->pc - s->cs_base); 6139 gen_jmp_im(s->pc - s->cs_base);
6139 gen_eob(s); 6140 gen_eob(s);
6140 } 6141 }
@@ -6223,6 +6224,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6223,6 +6224,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6223 } else { 6224 } else {
6224 gen_op_mov_TN_reg(ot, 0, rm); 6225 gen_op_mov_TN_reg(ot, 0, rm);
6225 } 6226 }
  6227 + gen_op_mov_TN_reg(ot, 1, reg);
6226 if (s->cc_op != CC_OP_DYNAMIC) 6228 if (s->cc_op != CC_OP_DYNAMIC)
6227 gen_op_set_cc_op(s->cc_op); 6229 gen_op_set_cc_op(s->cc_op);
6228 gen_op_arpl(); 6230 gen_op_arpl();
@@ -6299,14 +6301,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6299,14 +6301,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6299 if (b & 2) { 6301 if (b & 2) {
6300 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg); 6302 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
6301 gen_op_mov_TN_reg(ot, 0, rm); 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 gen_jmp_im(s->pc - s->cs_base); 6306 gen_jmp_im(s->pc - s->cs_base);
6304 gen_eob(s); 6307 gen_eob(s);
6305 } else { 6308 } else {
6306 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg); 6309 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
6307 #if !defined(CONFIG_USER_ONLY) 6310 #if !defined(CONFIG_USER_ONLY)
6308 if (reg == 8) 6311 if (reg == 8)
6309 - gen_op_movtl_T0_cr8(); 6312 + tcg_gen_helper_1_0(helper_movtl_T0_cr8, cpu_T[0]);
6310 else 6313 else
6311 #endif 6314 #endif
6312 gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg])); 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,7 +6341,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6338 if (b & 2) { 6341 if (b & 2) {
6339 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg); 6342 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
6340 gen_op_mov_TN_reg(ot, 0, rm); 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 gen_jmp_im(s->pc - s->cs_base); 6346 gen_jmp_im(s->pc - s->cs_base);
6343 gen_eob(s); 6347 gen_eob(s);
6344 } else { 6348 } else {
@@ -6353,7 +6357,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6353,7 +6357,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6353 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6357 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6354 } else { 6358 } else {
6355 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0); 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 /* abort block because static cpu state changed */ 6361 /* abort block because static cpu state changed */
6358 gen_jmp_im(s->pc - s->cs_base); 6362 gen_jmp_im(s->pc - s->cs_base);
6359 gen_eob(s); 6363 gen_eob(s);
@@ -6485,11 +6489,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6485,11 +6489,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6485 } 6489 }
6486 /* lock generation */ 6490 /* lock generation */
6487 if (s->prefix & PREFIX_LOCK) 6491 if (s->prefix & PREFIX_LOCK)
6488 - gen_op_unlock(); 6492 + tcg_gen_helper_0_0(helper_unlock);
6489 return s->pc; 6493 return s->pc;
6490 illegal_op: 6494 illegal_op:
6491 if (s->prefix & PREFIX_LOCK) 6495 if (s->prefix & PREFIX_LOCK)
6492 - gen_op_unlock(); 6496 + tcg_gen_helper_0_0(helper_unlock);
6493 /* XXX: ensure that no lock was generated */ 6497 /* XXX: ensure that no lock was generated */
6494 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base); 6498 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
6495 return s->pc; 6499 return s->pc;
@@ -6861,7 +6865,8 @@ void optimize_flags_init(void) @@ -6861,7 +6865,8 @@ void optimize_flags_init(void)
6861 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); 6865 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
6862 cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0"); 6866 cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
6863 #endif 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 cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1"); 6870 cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
6866 #endif 6871 #endif
6867 } 6872 }
@@ -6957,10 +6962,11 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -6957,10 +6962,11 @@ static inline int gen_intermediate_code_internal(CPUState *env,
6957 #endif 6962 #endif
6958 6963
6959 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL); 6964 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
6960 -#if !defined(__i386__) 6965 +#if !(defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS))
6961 cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64); 6966 cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64);
6962 #endif 6967 #endif
6963 cpu_tmp2 = tcg_temp_new(TCG_TYPE_I32); 6968 cpu_tmp2 = tcg_temp_new(TCG_TYPE_I32);
  6969 + cpu_tmp3 = tcg_temp_new(TCG_TYPE_I32);
6964 cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR); 6970 cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
6965 cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR); 6971 cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
6966 6972