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
This commit is contained in:
		
							parent
							
								
									6e01bdaedc
								
							
						
					
					
						commit
						b8b6a50b55
					
				@ -3,12 +3,13 @@ Correctness issues:
 | 
				
			|||||||
- rework eflags optimization (will be a consequence of TCG port)
 | 
					- rework eflags optimization (will be a consequence of TCG port)
 | 
				
			||||||
- SVM: rework the implementation: simplify code, move most intercept
 | 
					- SVM: rework the implementation: simplify code, move most intercept
 | 
				
			||||||
  tests as dynamic, correct segment access, verify exception safety,
 | 
					  tests as dynamic, correct segment access, verify exception safety,
 | 
				
			||||||
  remove most of the added CPU state.
 | 
					  cpu save/restore, SMM save/restore. 
 | 
				
			||||||
- arpl eflags computation is invalid
 | 
					- arpl eflags computation is invalid
 | 
				
			||||||
- x86_64: fxsave/fxrestore intel/amd differences
 | 
					- x86_64: fxsave/fxrestore intel/amd differences
 | 
				
			||||||
- x86_64: lcall/ljmp intel/amd differences ?
 | 
					- x86_64: lcall/ljmp intel/amd differences ?
 | 
				
			||||||
- x86_64: cmpxchgl intel/amd differences ?
 | 
					- x86_64: cmpxchgl intel/amd differences ?
 | 
				
			||||||
- x86_64: cmovl bug intel/amd differences ?
 | 
					- x86_64: cmovl intel/amd differences ?
 | 
				
			||||||
 | 
					- cmpxchg16b + cmpxchg8b cpuid test
 | 
				
			||||||
- x86: monitor invalid 
 | 
					- x86: monitor invalid 
 | 
				
			||||||
- better code fetch (different exception handling + CS.limit support)
 | 
					- better code fetch (different exception handling + CS.limit support)
 | 
				
			||||||
- user/kernel PUSHL/POPL in helper.c
 | 
					- user/kernel PUSHL/POPL in helper.c
 | 
				
			||||||
@ -19,10 +20,18 @@ Correctness issues:
 | 
				
			|||||||
- full support of segment limit/rights 
 | 
					- full support of segment limit/rights 
 | 
				
			||||||
- full x87 exception support
 | 
					- full x87 exception support
 | 
				
			||||||
- improve x87 bit exactness (use bochs code ?)
 | 
					- improve x87 bit exactness (use bochs code ?)
 | 
				
			||||||
 | 
					- DRx register support
 | 
				
			||||||
 | 
					- CR0.AC emulation
 | 
				
			||||||
 | 
					- SSE alignment checks
 | 
				
			||||||
 | 
					- fix SSE min/max with nans
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Optimizations/Features:
 | 
					Optimizations/Features:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- finish TCG port
 | 
					- finish TCG port
 | 
				
			||||||
 | 
					- add SVM nested paging support
 | 
				
			||||||
 | 
					- add VMX support
 | 
				
			||||||
 | 
					- add AVX support
 | 
				
			||||||
 | 
					- add SSE5 support
 | 
				
			||||||
- evaluate x87 stack pointer statically
 | 
					- evaluate x87 stack pointer statically
 | 
				
			||||||
- find a way to avoid translating several time the same TB if CR0.TS
 | 
					- find a way to avoid translating several time the same TB if CR0.TS
 | 
				
			||||||
  is set or not.
 | 
					  is set or not.
 | 
				
			||||||
 | 
				
			|||||||
@ -105,16 +105,6 @@ typedef struct CCTable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern CCTable cc_table[];
 | 
					extern CCTable cc_table[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_load_seg(int seg_reg, int selector);
 | 
					 | 
				
			||||||
void helper_ljmp_protected_T0_T1(int next_eip);
 | 
					 | 
				
			||||||
void helper_lcall_real_T0_T1(int shift, int next_eip);
 | 
					 | 
				
			||||||
void helper_lcall_protected_T0_T1(int shift, int next_eip);
 | 
					 | 
				
			||||||
void helper_iret_real(int shift);
 | 
					 | 
				
			||||||
void helper_iret_protected(int shift, int next_eip);
 | 
					 | 
				
			||||||
void helper_lret_protected(int shift, int addend);
 | 
					 | 
				
			||||||
void helper_movl_crN_T0(int reg);
 | 
					 | 
				
			||||||
void helper_movl_drN_T0(int reg);
 | 
					 | 
				
			||||||
void helper_invlpg(target_ulong addr);
 | 
					 | 
				
			||||||
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
 | 
					void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
 | 
				
			||||||
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
 | 
					void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
 | 
				
			||||||
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 | 
					void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 | 
				
			||||||
@ -141,17 +131,10 @@ void OPPROTO op_movl_T0_eflags(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "helper.h"
 | 
					#include "helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_mulq_EAX_T0(void);
 | 
					static inline void svm_check_intercept(uint32_t type)
 | 
				
			||||||
void helper_imulq_EAX_T0(void);
 | 
					{
 | 
				
			||||||
void helper_imulq_T0_T1(void);
 | 
					    helper_svm_check_intercept_param(type, 0);
 | 
				
			||||||
void helper_cmpxchg8b(void);
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void check_iob_T0(void);
 | 
					 | 
				
			||||||
void check_iow_T0(void);
 | 
					 | 
				
			||||||
void check_iol_T0(void);
 | 
					 | 
				
			||||||
void check_iob_DX(void);
 | 
					 | 
				
			||||||
void check_iow_DX(void);
 | 
					 | 
				
			||||||
void check_iol_DX(void);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -363,7 +346,6 @@ extern const CPU86_LDouble f15rk[7];
 | 
				
			|||||||
void fpu_raise_exception(void);
 | 
					void fpu_raise_exception(void);
 | 
				
			||||||
void restore_native_fp_state(CPUState *env);
 | 
					void restore_native_fp_state(CPUState *env);
 | 
				
			||||||
void save_native_fp_state(CPUState *env);
 | 
					void save_native_fp_state(CPUState *env);
 | 
				
			||||||
void vmexit(uint64_t exit_code, uint64_t exit_info_1);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const uint8_t parity_table[256];
 | 
					extern const uint8_t parity_table[256];
 | 
				
			||||||
extern const uint8_t rclw_table[32];
 | 
					extern const uint8_t rclw_table[32];
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@
 | 
				
			|||||||
 * License along with this library; if not, write to the Free Software
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#define CPU_NO_GLOBAL_REGS
 | 
				
			||||||
#include "exec.h"
 | 
					#include "exec.h"
 | 
				
			||||||
#include "host-utils.h"
 | 
					#include "host-utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,16 +94,16 @@ const CPU86_LDouble f15rk[7] =
 | 
				
			|||||||
    3.32192809488736234781L,  /*l2t*/
 | 
					    3.32192809488736234781L,  /*l2t*/
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* thread support */
 | 
					/* broken thread support */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
 | 
					spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_lock(void)
 | 
					void helper_lock(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    spin_lock(&global_cpu_lock);
 | 
					    spin_lock(&global_cpu_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_unlock(void)
 | 
					void helper_unlock(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    spin_unlock(&global_cpu_lock);
 | 
					    spin_unlock(&global_cpu_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -508,34 +509,49 @@ static inline void check_io(int addr, int size)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_iob_T0(void)
 | 
					void helper_check_iob(uint32_t t0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    check_io(T0, 1);
 | 
					    check_io(t0, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_iow_T0(void)
 | 
					void helper_check_iow(uint32_t t0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    check_io(T0, 2);
 | 
					    check_io(t0, 2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_iol_T0(void)
 | 
					void helper_check_iol(uint32_t t0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    check_io(T0, 4);
 | 
					    check_io(t0, 4);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_iob_DX(void)
 | 
					void helper_outb(uint32_t port, uint32_t data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    check_io(EDX & 0xffff, 1);
 | 
					    cpu_outb(env, port, data & 0xff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_iow_DX(void)
 | 
					target_ulong helper_inb(uint32_t port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    check_io(EDX & 0xffff, 2);
 | 
					    return cpu_inb(env, port);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_iol_DX(void)
 | 
					void helper_outw(uint32_t port, uint32_t data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    check_io(EDX & 0xffff, 4);
 | 
					    cpu_outw(env, port, data & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_ulong helper_inw(uint32_t port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return cpu_inw(env, port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_outl(uint32_t port, uint32_t data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    cpu_outl(env, port, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_ulong helper_inl(uint32_t port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return cpu_inl(env, port);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned int get_sp_mask(unsigned int e2)
 | 
					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,
 | 
				
			|||||||
                     int next_eip_addend)
 | 
					                     int next_eip_addend)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!is_int) {
 | 
					    if (!is_int) {
 | 
				
			||||||
        svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code);
 | 
					        helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code);
 | 
				
			||||||
        intno = check_exception(intno, &error_code);
 | 
					        intno = check_exception(intno, &error_code);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1857,19 +1873,19 @@ void helper_das(void)
 | 
				
			|||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_cmpxchg8b(void)
 | 
					void helper_cmpxchg8b(target_ulong a0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t d;
 | 
					    uint64_t d;
 | 
				
			||||||
    int eflags;
 | 
					    int eflags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eflags = cc_table[CC_OP].compute_all();
 | 
					    eflags = cc_table[CC_OP].compute_all();
 | 
				
			||||||
    d = ldq(A0);
 | 
					    d = ldq(a0);
 | 
				
			||||||
    if (d == (((uint64_t)EDX << 32) | EAX)) {
 | 
					    if (d == (((uint64_t)EDX << 32) | EAX)) {
 | 
				
			||||||
        stq(A0, ((uint64_t)ECX << 32) | EBX);
 | 
					        stq(a0, ((uint64_t)ECX << 32) | EBX);
 | 
				
			||||||
        eflags |= CC_Z;
 | 
					        eflags |= CC_Z;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        EDX = d >> 32;
 | 
					        EDX = (uint32_t)(d >> 32);
 | 
				
			||||||
        EAX = d;
 | 
					        EAX = (uint32_t)d;
 | 
				
			||||||
        eflags &= ~CC_Z;
 | 
					        eflags &= ~CC_Z;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    CC_SRC = eflags;
 | 
					    CC_SRC = eflags;
 | 
				
			||||||
@ -1986,7 +2002,7 @@ void helper_cpuid(void)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_enter_level(int level, int data32)
 | 
					void helper_enter_level(int level, int data32, target_ulong t1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    target_ulong ssp;
 | 
					    target_ulong ssp;
 | 
				
			||||||
    uint32_t esp_mask, esp, ebp;
 | 
					    uint32_t esp_mask, esp, ebp;
 | 
				
			||||||
@ -2004,7 +2020,7 @@ void helper_enter_level(int level, int data32)
 | 
				
			|||||||
            stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
 | 
					            stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        esp -= 4;
 | 
					        esp -= 4;
 | 
				
			||||||
        stl(ssp + (esp & esp_mask), T1);
 | 
					        stl(ssp + (esp & esp_mask), t1);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* 16 bit */
 | 
					        /* 16 bit */
 | 
				
			||||||
        esp -= 2;
 | 
					        esp -= 2;
 | 
				
			||||||
@ -2014,12 +2030,12 @@ void helper_enter_level(int level, int data32)
 | 
				
			|||||||
            stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
 | 
					            stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        esp -= 2;
 | 
					        esp -= 2;
 | 
				
			||||||
        stw(ssp + (esp & esp_mask), T1);
 | 
					        stw(ssp + (esp & esp_mask), t1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
void helper_enter64_level(int level, int data64)
 | 
					void helper_enter64_level(int level, int data64, target_ulong t1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    target_ulong esp, ebp;
 | 
					    target_ulong esp, ebp;
 | 
				
			||||||
    ebp = EBP;
 | 
					    ebp = EBP;
 | 
				
			||||||
@ -2034,7 +2050,7 @@ void helper_enter64_level(int level, int data64)
 | 
				
			|||||||
            stq(esp, ldq(ebp));
 | 
					            stq(esp, ldq(ebp));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        esp -= 8;
 | 
					        esp -= 8;
 | 
				
			||||||
        stq(esp, T1);
 | 
					        stq(esp, t1);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* 16 bit */
 | 
					        /* 16 bit */
 | 
				
			||||||
        esp -= 2;
 | 
					        esp -= 2;
 | 
				
			||||||
@ -2044,7 +2060,7 @@ void helper_enter64_level(int level, int data64)
 | 
				
			|||||||
            stw(esp, lduw(ebp));
 | 
					            stw(esp, lduw(ebp));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        esp -= 2;
 | 
					        esp -= 2;
 | 
				
			||||||
        stw(esp, T1);
 | 
					        stw(esp, t1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -2231,14 +2247,13 @@ void helper_load_seg(int seg_reg, int selector)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* protected mode jump */
 | 
					/* protected mode jump */
 | 
				
			||||||
void helper_ljmp_protected_T0_T1(int next_eip_addend)
 | 
					void helper_ljmp_protected(int new_cs, target_ulong new_eip,
 | 
				
			||||||
 | 
					                           int next_eip_addend)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int new_cs, gate_cs, type;
 | 
					    int gate_cs, type;
 | 
				
			||||||
    uint32_t e1, e2, cpl, dpl, rpl, limit;
 | 
					    uint32_t e1, e2, cpl, dpl, rpl, limit;
 | 
				
			||||||
    target_ulong new_eip, next_eip;
 | 
					    target_ulong next_eip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new_cs = T0;
 | 
					 | 
				
			||||||
    new_eip = T1;
 | 
					 | 
				
			||||||
    if ((new_cs & 0xfffc) == 0)
 | 
					    if ((new_cs & 0xfffc) == 0)
 | 
				
			||||||
        raise_exception_err(EXCP0D_GPF, 0);
 | 
					        raise_exception_err(EXCP0D_GPF, 0);
 | 
				
			||||||
    if (load_segment(&e1, &e2, new_cs) != 0)
 | 
					    if (load_segment(&e1, &e2, new_cs) != 0)
 | 
				
			||||||
@ -2322,14 +2337,14 @@ void helper_ljmp_protected_T0_T1(int next_eip_addend)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* real mode call */
 | 
					/* real mode call */
 | 
				
			||||||
void helper_lcall_real_T0_T1(int shift, int next_eip)
 | 
					void helper_lcall_real(int new_cs, target_ulong new_eip1,
 | 
				
			||||||
 | 
					                       int shift, int next_eip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int new_cs, new_eip;
 | 
					    int new_eip;
 | 
				
			||||||
    uint32_t esp, esp_mask;
 | 
					    uint32_t esp, esp_mask;
 | 
				
			||||||
    target_ulong ssp;
 | 
					    target_ulong ssp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new_cs = T0;
 | 
					    new_eip = new_eip1;
 | 
				
			||||||
    new_eip = T1;
 | 
					 | 
				
			||||||
    esp = ESP;
 | 
					    esp = ESP;
 | 
				
			||||||
    esp_mask = get_sp_mask(env->segs[R_SS].flags);
 | 
					    esp_mask = get_sp_mask(env->segs[R_SS].flags);
 | 
				
			||||||
    ssp = env->segs[R_SS].base;
 | 
					    ssp = env->segs[R_SS].base;
 | 
				
			||||||
@ -2348,16 +2363,15 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* protected mode call */
 | 
					/* protected mode call */
 | 
				
			||||||
void helper_lcall_protected_T0_T1(int shift, int next_eip_addend)
 | 
					void helper_lcall_protected(int new_cs, target_ulong new_eip, 
 | 
				
			||||||
 | 
					                            int shift, int next_eip_addend)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int new_cs, new_stack, i;
 | 
					    int new_stack, i;
 | 
				
			||||||
    uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
 | 
					    uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
 | 
				
			||||||
    uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
 | 
					    uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
 | 
				
			||||||
    uint32_t val, limit, old_sp_mask;
 | 
					    uint32_t val, limit, old_sp_mask;
 | 
				
			||||||
    target_ulong ssp, old_ssp, next_eip, new_eip;
 | 
					    target_ulong ssp, old_ssp, next_eip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new_cs = T0;
 | 
					 | 
				
			||||||
    new_eip = T1;
 | 
					 | 
				
			||||||
    next_eip = env->eip + next_eip_addend;
 | 
					    next_eip = env->eip + next_eip_addend;
 | 
				
			||||||
#ifdef DEBUG_PCALL
 | 
					#ifdef DEBUG_PCALL
 | 
				
			||||||
    if (loglevel & CPU_LOG_PCALL) {
 | 
					    if (loglevel & CPU_LOG_PCALL) {
 | 
				
			||||||
@ -2922,34 +2936,55 @@ void helper_sysexit(void)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_movl_crN_T0(int reg)
 | 
					void helper_movl_crN_T0(int reg, target_ulong t0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
    switch(reg) {
 | 
					    switch(reg) {
 | 
				
			||||||
    case 0:
 | 
					    case 0:
 | 
				
			||||||
        cpu_x86_update_cr0(env, T0);
 | 
					        cpu_x86_update_cr0(env, t0);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 3:
 | 
					    case 3:
 | 
				
			||||||
        cpu_x86_update_cr3(env, T0);
 | 
					        cpu_x86_update_cr3(env, t0);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 4:
 | 
					    case 4:
 | 
				
			||||||
        cpu_x86_update_cr4(env, T0);
 | 
					        cpu_x86_update_cr4(env, t0);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 8:
 | 
					    case 8:
 | 
				
			||||||
        cpu_set_apic_tpr(env, T0);
 | 
					        cpu_set_apic_tpr(env, t0);
 | 
				
			||||||
        env->cr[8] = T0;
 | 
					        env->cr[8] = t0;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        env->cr[reg] = T0;
 | 
					        env->cr[reg] = t0;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* XXX: do more */
 | 
					void helper_lmsw(target_ulong t0)
 | 
				
			||||||
void helper_movl_drN_T0(int reg)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    env->dr[reg] = T0;
 | 
					    /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
 | 
				
			||||||
 | 
					       if already set to one. */
 | 
				
			||||||
 | 
					    t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
 | 
				
			||||||
 | 
					    helper_movl_crN_T0(0, t0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_clts(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    env->cr[0] &= ~CR0_TS_MASK;
 | 
				
			||||||
 | 
					    env->hflags &= ~HF_TS_MASK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					target_ulong helper_movtl_T0_cr8(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return cpu_get_apic_tpr(env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* XXX: do more */
 | 
				
			||||||
 | 
					void helper_movl_drN_T0(int reg, target_ulong t0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    env->dr[reg] = t0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_invlpg(target_ulong addr)
 | 
					void helper_invlpg(target_ulong addr)
 | 
				
			||||||
@ -2975,10 +3010,10 @@ void helper_rdpmc(void)
 | 
				
			|||||||
        raise_exception(EXCP0D_GPF);
 | 
					        raise_exception(EXCP0D_GPF);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!svm_check_intercept_param(SVM_EXIT_RDPMC, 0)) {
 | 
					    helper_svm_check_intercept_param(SVM_EXIT_RDPMC, 0);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    /* currently unimplemented */
 | 
					    /* currently unimplemented */
 | 
				
			||||||
    raise_exception_err(EXCP06_ILLOP, 0);
 | 
					    raise_exception_err(EXCP06_ILLOP, 0);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_USER_ONLY)
 | 
					#if defined(CONFIG_USER_ONLY)
 | 
				
			||||||
@ -3118,7 +3153,7 @@ void helper_rdmsr(void)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_lsl(uint32_t selector)
 | 
					uint32_t helper_lsl(uint32_t selector)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned int limit;
 | 
					    unsigned int limit;
 | 
				
			||||||
    uint32_t e1, e2, eflags;
 | 
					    uint32_t e1, e2, eflags;
 | 
				
			||||||
@ -3153,15 +3188,15 @@ void helper_lsl(uint32_t selector)
 | 
				
			|||||||
        if (dpl < cpl || dpl < rpl) {
 | 
					        if (dpl < cpl || dpl < rpl) {
 | 
				
			||||||
        fail:
 | 
					        fail:
 | 
				
			||||||
            CC_SRC = eflags & ~CC_Z;
 | 
					            CC_SRC = eflags & ~CC_Z;
 | 
				
			||||||
            return;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    limit = get_seg_limit(e1, e2);
 | 
					    limit = get_seg_limit(e1, e2);
 | 
				
			||||||
    T1 = limit;
 | 
					 | 
				
			||||||
    CC_SRC = eflags | CC_Z;
 | 
					    CC_SRC = eflags | CC_Z;
 | 
				
			||||||
 | 
					    return limit;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_lar(uint32_t selector)
 | 
					uint32_t helper_lar(uint32_t selector)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t e1, e2, eflags;
 | 
					    uint32_t e1, e2, eflags;
 | 
				
			||||||
    int rpl, dpl, cpl, type;
 | 
					    int rpl, dpl, cpl, type;
 | 
				
			||||||
@ -3200,11 +3235,11 @@ void helper_lar(uint32_t selector)
 | 
				
			|||||||
        if (dpl < cpl || dpl < rpl) {
 | 
					        if (dpl < cpl || dpl < rpl) {
 | 
				
			||||||
        fail:
 | 
					        fail:
 | 
				
			||||||
            CC_SRC = eflags & ~CC_Z;
 | 
					            CC_SRC = eflags & ~CC_Z;
 | 
				
			||||||
            return;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    T1 = e2 & 0x00f0ff00;
 | 
					 | 
				
			||||||
    CC_SRC = eflags | CC_Z;
 | 
					    CC_SRC = eflags | CC_Z;
 | 
				
			||||||
 | 
					    return e2 & 0x00f0ff00;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_verr(uint32_t selector)
 | 
					void helper_verr(uint32_t selector)
 | 
				
			||||||
@ -4412,36 +4447,36 @@ static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_mulq_EAX_T0(void)
 | 
					void helper_mulq_EAX_T0(target_ulong t0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t r0, r1;
 | 
					    uint64_t r0, r1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mulu64(&r0, &r1, EAX, T0);
 | 
					    mulu64(&r0, &r1, EAX, t0);
 | 
				
			||||||
    EAX = r0;
 | 
					    EAX = r0;
 | 
				
			||||||
    EDX = r1;
 | 
					    EDX = r1;
 | 
				
			||||||
    CC_DST = r0;
 | 
					    CC_DST = r0;
 | 
				
			||||||
    CC_SRC = r1;
 | 
					    CC_SRC = r1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_imulq_EAX_T0(void)
 | 
					void helper_imulq_EAX_T0(target_ulong t0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t r0, r1;
 | 
					    uint64_t r0, r1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    muls64(&r0, &r1, EAX, T0);
 | 
					    muls64(&r0, &r1, EAX, t0);
 | 
				
			||||||
    EAX = r0;
 | 
					    EAX = r0;
 | 
				
			||||||
    EDX = r1;
 | 
					    EDX = r1;
 | 
				
			||||||
    CC_DST = r0;
 | 
					    CC_DST = r0;
 | 
				
			||||||
    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
 | 
					    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_imulq_T0_T1(void)
 | 
					target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t r0, r1;
 | 
					    uint64_t r0, r1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    muls64(&r0, &r1, T0, T1);
 | 
					    muls64(&r0, &r1, t0, t1);
 | 
				
			||||||
    T0 = r0;
 | 
					 | 
				
			||||||
    CC_DST = r0;
 | 
					    CC_DST = r0;
 | 
				
			||||||
    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
 | 
					    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
 | 
				
			||||||
 | 
					    return r0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_divq_EAX(target_ulong t0)
 | 
					void helper_divq_EAX(target_ulong t0)
 | 
				
			||||||
@ -4553,24 +4588,23 @@ void helper_reset_inhibit_irq(void)
 | 
				
			|||||||
    env->hflags &= ~HF_INHIBIT_IRQ_MASK;
 | 
					    env->hflags &= ~HF_INHIBIT_IRQ_MASK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_boundw(void)
 | 
					void helper_boundw(target_ulong a0, int v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int low, high, v;
 | 
					    int low, high;
 | 
				
			||||||
    low = ldsw(A0);
 | 
					    low = ldsw(a0);
 | 
				
			||||||
    high = ldsw(A0 + 2);
 | 
					    high = ldsw(a0 + 2);
 | 
				
			||||||
    v = (int16_t)T0;
 | 
					    v = (int16_t)v;
 | 
				
			||||||
    if (v < low || v > high) {
 | 
					    if (v < low || v > high) {
 | 
				
			||||||
        raise_exception(EXCP05_BOUND);
 | 
					        raise_exception(EXCP05_BOUND);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_boundl(void)
 | 
					void helper_boundl(target_ulong a0, int v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int low, high, v;
 | 
					    int low, high;
 | 
				
			||||||
    low = ldl(A0);
 | 
					    low = ldl(a0);
 | 
				
			||||||
    high = ldl(A0 + 4);
 | 
					    high = ldl(a0 + 4);
 | 
				
			||||||
    v = T0;
 | 
					 | 
				
			||||||
    if (v < low || v > high) {
 | 
					    if (v < low || v > high) {
 | 
				
			||||||
        raise_exception(EXCP05_BOUND);
 | 
					        raise_exception(EXCP05_BOUND);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -4661,18 +4695,35 @@ void helper_clgi(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_USER_ONLY)
 | 
					#if defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_vmrun(void) { }
 | 
					void helper_vmrun(void) 
 | 
				
			||||||
void helper_vmmcall(void) { }
 | 
					{ 
 | 
				
			||||||
void helper_vmload(void) { }
 | 
					}
 | 
				
			||||||
void helper_vmsave(void) { }
 | 
					void helper_vmmcall(void) 
 | 
				
			||||||
void helper_skinit(void) { }
 | 
					{ 
 | 
				
			||||||
void helper_invlpga(void) { }
 | 
					}
 | 
				
			||||||
void vmexit(uint64_t exit_code, uint64_t exit_info_1) { }
 | 
					void helper_vmload(void) 
 | 
				
			||||||
int svm_check_intercept_param(uint32_t type, uint64_t param)
 | 
					{ 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void helper_vmsave(void) 
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void helper_skinit(void) 
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void helper_invlpga(void) 
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) 
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_svm_check_io(uint32_t port, uint32_t param, 
 | 
				
			||||||
 | 
					                         uint32_t next_eip_addend)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline uint32_t
 | 
					static inline uint32_t
 | 
				
			||||||
@ -4702,7 +4753,6 @@ void helper_vmrun(void)
 | 
				
			|||||||
        fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr);
 | 
					        fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    env->vm_vmcb = addr;
 | 
					    env->vm_vmcb = addr;
 | 
				
			||||||
    regs_to_env();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* save the current CPU state in the hsave page */
 | 
					    /* save the current CPU state in the hsave page */
 | 
				
			||||||
    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);
 | 
					    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);
 | 
				
			||||||
@ -4801,8 +4851,6 @@ void helper_vmrun(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    helper_stgi();
 | 
					    helper_stgi();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    regs_to_env();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* maybe we need to inject an event */
 | 
					    /* maybe we need to inject an event */
 | 
				
			||||||
    event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
 | 
					    event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
 | 
				
			||||||
    if (event_inj & SVM_EVTINJ_VALID) {
 | 
					    if (event_inj & SVM_EVTINJ_VALID) {
 | 
				
			||||||
@ -4927,95 +4975,98 @@ void helper_invlpga(void)
 | 
				
			|||||||
    tlb_flush(env, 0);
 | 
					    tlb_flush(env, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int svm_check_intercept_param(uint32_t type, uint64_t param)
 | 
					void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch(type) {
 | 
					    switch(type) {
 | 
				
			||||||
    case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
 | 
					    case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
 | 
				
			||||||
        if (INTERCEPTEDw(_cr_read, (1 << (type - SVM_EXIT_READ_CR0)))) {
 | 
					        if (INTERCEPTEDw(_cr_read, (1 << (type - SVM_EXIT_READ_CR0)))) {
 | 
				
			||||||
            vmexit(type, param);
 | 
					            helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 8:
 | 
					    case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 8:
 | 
				
			||||||
        if (INTERCEPTEDw(_dr_read, (1 << (type - SVM_EXIT_READ_DR0)))) {
 | 
					        if (INTERCEPTEDw(_dr_read, (1 << (type - SVM_EXIT_READ_DR0)))) {
 | 
				
			||||||
            vmexit(type, param);
 | 
					            helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
 | 
					    case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
 | 
				
			||||||
        if (INTERCEPTEDw(_cr_write, (1 << (type - SVM_EXIT_WRITE_CR0)))) {
 | 
					        if (INTERCEPTEDw(_cr_write, (1 << (type - SVM_EXIT_WRITE_CR0)))) {
 | 
				
			||||||
            vmexit(type, param);
 | 
					            helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 8:
 | 
					    case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 8:
 | 
				
			||||||
        if (INTERCEPTEDw(_dr_write, (1 << (type - SVM_EXIT_WRITE_DR0)))) {
 | 
					        if (INTERCEPTEDw(_dr_write, (1 << (type - SVM_EXIT_WRITE_DR0)))) {
 | 
				
			||||||
            vmexit(type, param);
 | 
					            helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 16:
 | 
					    case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 16:
 | 
				
			||||||
        if (INTERCEPTEDl(_exceptions, (1 << (type - SVM_EXIT_EXCP_BASE)))) {
 | 
					        if (INTERCEPTEDl(_exceptions, (1 << (type - SVM_EXIT_EXCP_BASE)))) {
 | 
				
			||||||
            vmexit(type, param);
 | 
					            helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case SVM_EXIT_IOIO:
 | 
					    case SVM_EXIT_IOIO:
 | 
				
			||||||
        if (INTERCEPTED(1ULL << INTERCEPT_IOIO_PROT)) {
 | 
					 | 
				
			||||||
            /* FIXME: this should be read in at vmrun (faster this way?) */
 | 
					 | 
				
			||||||
            uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
 | 
					 | 
				
			||||||
            uint16_t port = (uint16_t) (param >> 16);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
 | 
					 | 
				
			||||||
            if(lduw_phys(addr + port / 8) & (mask << (port & 7)))
 | 
					 | 
				
			||||||
                vmexit(type, param);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case SVM_EXIT_MSR:
 | 
					    case SVM_EXIT_MSR:
 | 
				
			||||||
        if (INTERCEPTED(1ULL << INTERCEPT_MSR_PROT)) {
 | 
					        if (INTERCEPTED(1ULL << INTERCEPT_MSR_PROT)) {
 | 
				
			||||||
            /* FIXME: this should be read in at vmrun (faster this way?) */
 | 
					            /* FIXME: this should be read in at vmrun (faster this way?) */
 | 
				
			||||||
            uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa));
 | 
					            uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa));
 | 
				
			||||||
 | 
					            uint32_t t0, t1;
 | 
				
			||||||
            switch((uint32_t)ECX) {
 | 
					            switch((uint32_t)ECX) {
 | 
				
			||||||
            case 0 ... 0x1fff:
 | 
					            case 0 ... 0x1fff:
 | 
				
			||||||
                T0 = (ECX * 2) % 8;
 | 
					                t0 = (ECX * 2) % 8;
 | 
				
			||||||
                T1 = ECX / 8;
 | 
					                t1 = ECX / 8;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0xc0000000 ... 0xc0001fff:
 | 
					            case 0xc0000000 ... 0xc0001fff:
 | 
				
			||||||
                T0 = (8192 + ECX - 0xc0000000) * 2;
 | 
					                t0 = (8192 + ECX - 0xc0000000) * 2;
 | 
				
			||||||
                T1 = (T0 / 8);
 | 
					                t1 = (t0 / 8);
 | 
				
			||||||
                T0 %= 8;
 | 
					                t0 %= 8;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0xc0010000 ... 0xc0011fff:
 | 
					            case 0xc0010000 ... 0xc0011fff:
 | 
				
			||||||
                T0 = (16384 + ECX - 0xc0010000) * 2;
 | 
					                t0 = (16384 + ECX - 0xc0010000) * 2;
 | 
				
			||||||
                T1 = (T0 / 8);
 | 
					                t1 = (t0 / 8);
 | 
				
			||||||
                T0 %= 8;
 | 
					                t0 %= 8;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                vmexit(type, param);
 | 
					                helper_vmexit(type, param);
 | 
				
			||||||
                return 1;
 | 
					                t0 = 0;
 | 
				
			||||||
 | 
					                t1 = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (ldub_phys(addr + T1) & ((1 << param) << T0))
 | 
					            if (ldub_phys(addr + t1) & ((1 << param) << t0))
 | 
				
			||||||
                vmexit(type, param);
 | 
					                helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        if (INTERCEPTED((1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR)))) {
 | 
					        if (INTERCEPTED((1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR)))) {
 | 
				
			||||||
            vmexit(type, param);
 | 
					            helper_vmexit(type, param);
 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vmexit(uint64_t exit_code, uint64_t exit_info_1)
 | 
					void helper_svm_check_io(uint32_t port, uint32_t param, 
 | 
				
			||||||
 | 
					                         uint32_t next_eip_addend)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (INTERCEPTED(1ULL << INTERCEPT_IOIO_PROT)) {
 | 
				
			||||||
 | 
					        /* FIXME: this should be read in at vmrun (faster this way?) */
 | 
				
			||||||
 | 
					        uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
 | 
				
			||||||
 | 
					        uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
 | 
				
			||||||
 | 
					        if(lduw_phys(addr + port / 8) & (mask << (port & 7))) {
 | 
				
			||||||
 | 
					            /* next EIP */
 | 
				
			||||||
 | 
					            stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
 | 
				
			||||||
 | 
					                     env->eip + next_eip_addend);
 | 
				
			||||||
 | 
					            helper_vmexit(SVM_EXIT_IOIO, param | (port << 16));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Note: currently only 32 bits of exit_code are used */
 | 
				
			||||||
 | 
					void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t int_ctl;
 | 
					    uint32_t int_ctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (loglevel & CPU_LOG_TB_IN_ASM)
 | 
					    if (loglevel & CPU_LOG_TB_IN_ASM)
 | 
				
			||||||
        fprintf(logfile,"vmexit(%016" PRIx64 ", %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
 | 
					        fprintf(logfile,"vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
 | 
				
			||||||
                exit_code, exit_info_1,
 | 
					                exit_code, exit_info_1,
 | 
				
			||||||
                ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
 | 
					                ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
 | 
				
			||||||
                EIP);
 | 
					                EIP);
 | 
				
			||||||
@ -5105,8 +5156,7 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* other setups */
 | 
					    /* other setups */
 | 
				
			||||||
    cpu_x86_set_cpl(env, 0);
 | 
					    cpu_x86_set_cpl(env, 0);
 | 
				
			||||||
    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code_hi), (uint32_t)(exit_code >> 32));
 | 
					    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
 | 
				
			||||||
    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
 | 
					 | 
				
			||||||
    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
 | 
					    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    helper_clgi();
 | 
					    helper_clgi();
 | 
				
			||||||
@ -5137,7 +5187,6 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
 | 
				
			|||||||
    env->error_code = 0;
 | 
					    env->error_code = 0;
 | 
				
			||||||
    env->old_exception = -1;
 | 
					    env->old_exception = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    regs_to_env();
 | 
					 | 
				
			||||||
    cpu_loop_exit();
 | 
					    cpu_loop_exit();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
#define TCG_HELPER_PROTO
 | 
					#define TCG_HELPER_PROTO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_lock(void);
 | 
				
			||||||
 | 
					void helper_unlock(void);
 | 
				
			||||||
void helper_divb_AL(target_ulong t0);
 | 
					void helper_divb_AL(target_ulong t0);
 | 
				
			||||||
void helper_idivb_AL(target_ulong t0);
 | 
					void helper_idivb_AL(target_ulong t0);
 | 
				
			||||||
void helper_divw_AX(target_ulong t0);
 | 
					void helper_divw_AX(target_ulong t0);
 | 
				
			||||||
@ -7,6 +9,9 @@ void helper_idivw_AX(target_ulong t0);
 | 
				
			|||||||
void helper_divl_EAX(target_ulong t0);
 | 
					void helper_divl_EAX(target_ulong t0);
 | 
				
			||||||
void helper_idivl_EAX(target_ulong t0);
 | 
					void helper_idivl_EAX(target_ulong t0);
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
 | 
					void helper_mulq_EAX_T0(target_ulong t0);
 | 
				
			||||||
 | 
					void helper_imulq_EAX_T0(target_ulong t0);
 | 
				
			||||||
 | 
					target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1);
 | 
				
			||||||
void helper_divq_EAX(target_ulong t0);
 | 
					void helper_divq_EAX(target_ulong t0);
 | 
				
			||||||
void helper_idivq_EAX(target_ulong t0);
 | 
					void helper_idivq_EAX(target_ulong t0);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -18,26 +23,34 @@ void helper_aas(void);
 | 
				
			|||||||
void helper_daa(void);
 | 
					void helper_daa(void);
 | 
				
			||||||
void helper_das(void);
 | 
					void helper_das(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_lsl(uint32_t selector);
 | 
					uint32_t helper_lsl(uint32_t selector);
 | 
				
			||||||
void helper_lar(uint32_t selector);
 | 
					uint32_t helper_lar(uint32_t selector);
 | 
				
			||||||
void helper_verr(uint32_t selector);
 | 
					void helper_verr(uint32_t selector);
 | 
				
			||||||
void helper_verw(uint32_t selector);
 | 
					void helper_verw(uint32_t selector);
 | 
				
			||||||
void helper_lldt(int selector);
 | 
					void helper_lldt(int selector);
 | 
				
			||||||
void helper_ltr(int selector);
 | 
					void helper_ltr(int selector);
 | 
				
			||||||
void helper_load_seg(int seg_reg, int selector);
 | 
					void helper_load_seg(int seg_reg, int selector);
 | 
				
			||||||
void helper_ljmp_protected_T0_T1(int next_eip);
 | 
					void helper_ljmp_protected(int new_cs, target_ulong new_eip,
 | 
				
			||||||
void helper_lcall_real_T0_T1(int shift, int next_eip);
 | 
					                           int next_eip_addend);
 | 
				
			||||||
void helper_lcall_protected_T0_T1(int shift, int next_eip);
 | 
					void helper_lcall_real(int new_cs, target_ulong new_eip1,
 | 
				
			||||||
 | 
					                       int shift, int next_eip);
 | 
				
			||||||
 | 
					void helper_lcall_protected(int new_cs, target_ulong new_eip, 
 | 
				
			||||||
 | 
					                            int shift, int next_eip_addend);
 | 
				
			||||||
void helper_iret_real(int shift);
 | 
					void helper_iret_real(int shift);
 | 
				
			||||||
void helper_iret_protected(int shift, int next_eip);
 | 
					void helper_iret_protected(int shift, int next_eip);
 | 
				
			||||||
void helper_lret_protected(int shift, int addend);
 | 
					void helper_lret_protected(int shift, int addend);
 | 
				
			||||||
void helper_movl_crN_T0(int reg);
 | 
					void helper_movl_crN_T0(int reg, target_ulong t0);
 | 
				
			||||||
void helper_movl_drN_T0(int reg);
 | 
					void helper_lmsw(target_ulong t0);
 | 
				
			||||||
 | 
					void helper_clts(void);
 | 
				
			||||||
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					target_ulong helper_movtl_T0_cr8(void);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					void helper_movl_drN_T0(int reg, target_ulong t0);
 | 
				
			||||||
void helper_invlpg(target_ulong addr);
 | 
					void helper_invlpg(target_ulong addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_enter_level(int level, int data32);
 | 
					void helper_enter_level(int level, int data32, target_ulong t1);
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
void helper_enter64_level(int level, int data64);
 | 
					void helper_enter64_level(int level, int data64, target_ulong t1);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
void helper_sysenter(void);
 | 
					void helper_sysenter(void);
 | 
				
			||||||
void helper_sysexit(void);
 | 
					void helper_sysexit(void);
 | 
				
			||||||
@ -55,9 +68,10 @@ void helper_cli(void);
 | 
				
			|||||||
void helper_sti(void);
 | 
					void helper_sti(void);
 | 
				
			||||||
void helper_set_inhibit_irq(void);
 | 
					void helper_set_inhibit_irq(void);
 | 
				
			||||||
void helper_reset_inhibit_irq(void);
 | 
					void helper_reset_inhibit_irq(void);
 | 
				
			||||||
void helper_boundw(void);
 | 
					void helper_boundw(target_ulong a0, int v);
 | 
				
			||||||
void helper_boundl(void);
 | 
					void helper_boundl(target_ulong a0, int v);
 | 
				
			||||||
void helper_rsm(void);
 | 
					void helper_rsm(void);
 | 
				
			||||||
 | 
					void helper_cmpxchg8b(target_ulong a0);
 | 
				
			||||||
void helper_single_step(void);
 | 
					void helper_single_step(void);
 | 
				
			||||||
void helper_cpuid(void);
 | 
					void helper_cpuid(void);
 | 
				
			||||||
void helper_rdtsc(void);
 | 
					void helper_rdtsc(void);
 | 
				
			||||||
@ -65,6 +79,20 @@ void helper_rdpmc(void);
 | 
				
			|||||||
void helper_rdmsr(void);
 | 
					void helper_rdmsr(void);
 | 
				
			||||||
void helper_wrmsr(void);
 | 
					void helper_wrmsr(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_check_iob(uint32_t t0);
 | 
				
			||||||
 | 
					void helper_check_iow(uint32_t t0);
 | 
				
			||||||
 | 
					void helper_check_iol(uint32_t t0);
 | 
				
			||||||
 | 
					void helper_outb(uint32_t port, uint32_t data);
 | 
				
			||||||
 | 
					target_ulong helper_inb(uint32_t port);
 | 
				
			||||||
 | 
					void helper_outw(uint32_t port, uint32_t data);
 | 
				
			||||||
 | 
					target_ulong helper_inw(uint32_t port);
 | 
				
			||||||
 | 
					void helper_outl(uint32_t port, uint32_t data);
 | 
				
			||||||
 | 
					target_ulong helper_inl(uint32_t port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_svm_check_intercept_param(uint32_t type, uint64_t param);
 | 
				
			||||||
 | 
					void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1);
 | 
				
			||||||
 | 
					void helper_svm_check_io(uint32_t port, uint32_t param, 
 | 
				
			||||||
 | 
					                         uint32_t next_eip_addend);
 | 
				
			||||||
void helper_vmrun(void);
 | 
					void helper_vmrun(void);
 | 
				
			||||||
void helper_vmmcall(void);
 | 
					void helper_vmmcall(void);
 | 
				
			||||||
void helper_vmload(void);
 | 
					void helper_vmload(void);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										141
									
								
								target-i386/op.c
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								target-i386/op.c
									
									
									
									
									
								
							@ -276,17 +276,17 @@ void OPPROTO op_imull_T0_T1(void)
 | 
				
			|||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
void OPPROTO op_mulq_EAX_T0(void)
 | 
					void OPPROTO op_mulq_EAX_T0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_mulq_EAX_T0();
 | 
					    helper_mulq_EAX_T0(T0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_imulq_EAX_T0(void)
 | 
					void OPPROTO op_imulq_EAX_T0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_imulq_EAX_T0();
 | 
					    helper_imulq_EAX_T0(T0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_imulq_T0_T1(void)
 | 
					void OPPROTO op_imulq_T0_T1(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_imulq_T0_T1();
 | 
					    T0 = helper_imulq_T0_T1(T0, T1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -351,7 +351,7 @@ void OPPROTO op_into(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_cmpxchg8b(void)
 | 
					void OPPROTO op_cmpxchg8b(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_cmpxchg8b();
 | 
					    helper_cmpxchg8b(A0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* multiple size ops */
 | 
					/* multiple size ops */
 | 
				
			||||||
@ -522,12 +522,6 @@ void OPPROTO op_das(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* segment handling */
 | 
					/* segment handling */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* never use it with R_CS */
 | 
					 | 
				
			||||||
void OPPROTO op_movl_seg_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_load_seg(PARAM1, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* faster VM86 version */
 | 
					/* faster VM86 version */
 | 
				
			||||||
void OPPROTO op_movl_seg_T0_vm(void)
 | 
					void OPPROTO op_movl_seg_T0_vm(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -548,12 +542,20 @@ void OPPROTO op_movl_T0_seg(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_lsl(void)
 | 
					void OPPROTO op_lsl(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_lsl(T0);
 | 
					    uint32_t val;
 | 
				
			||||||
 | 
					    val = helper_lsl(T0);
 | 
				
			||||||
 | 
					    if (CC_SRC & CC_Z)
 | 
				
			||||||
 | 
					        T1 = val;
 | 
				
			||||||
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_lar(void)
 | 
					void OPPROTO op_lar(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_lar(T0);
 | 
					    uint32_t val;
 | 
				
			||||||
 | 
					    val = helper_lar(T0);
 | 
				
			||||||
 | 
					    if (CC_SRC & CC_Z)
 | 
				
			||||||
 | 
					        T1 = val;
 | 
				
			||||||
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_verr(void)
 | 
					void OPPROTO op_verr(void)
 | 
				
			||||||
@ -585,104 +587,6 @@ void OPPROTO op_arpl_update(void)
 | 
				
			|||||||
    CC_SRC = (eflags & ~CC_Z) | T1;
 | 
					    CC_SRC = (eflags & ~CC_Z) | T1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* T0: segment, T1:eip */
 | 
					 | 
				
			||||||
void OPPROTO op_ljmp_protected_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_ljmp_protected_T0_T1(PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_lcall_real_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_lcall_real_T0_T1(PARAM1, PARAM2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_lcall_protected_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_lcall_protected_T0_T1(PARAM1, PARAM2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_iret_real(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_iret_real(PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_iret_protected(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_iret_protected(PARAM1, PARAM2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_lret_protected(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_lret_protected(PARAM1, PARAM2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* CR registers access. */
 | 
					 | 
				
			||||||
void OPPROTO op_movl_crN_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_movl_crN_T0(PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* These pseudo-opcodes check for SVM intercepts. */
 | 
					 | 
				
			||||||
void OPPROTO op_svm_check_intercept(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 = PARAM1 & PARAM2;
 | 
					 | 
				
			||||||
    svm_check_intercept(PARAMQ1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_svm_check_intercept_param(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 = PARAM1 & PARAM2;
 | 
					 | 
				
			||||||
    svm_check_intercept_param(PARAMQ1, T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_svm_vmexit(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 = PARAM1 & PARAM2;
 | 
					 | 
				
			||||||
    vmexit(PARAMQ1, T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_geneflags(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CC_SRC = cc_table[CC_OP].compute_all();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* This pseudo-opcode checks for IO intercepts. */
 | 
					 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					 | 
				
			||||||
void OPPROTO op_svm_check_intercept_io(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 = PARAM1 & PARAM2;
 | 
					 | 
				
			||||||
    /* PARAMQ1 = TYPE (0 = OUT, 1 = IN; 4 = STRING; 8 = REP)
 | 
					 | 
				
			||||||
       T0      = PORT
 | 
					 | 
				
			||||||
       T1      = next eip */
 | 
					 | 
				
			||||||
    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), T1);
 | 
					 | 
				
			||||||
    /* ASIZE does not appear on real hw */
 | 
					 | 
				
			||||||
    svm_check_intercept_param(SVM_EXIT_IOIO,
 | 
					 | 
				
			||||||
                              (PARAMQ1 & ~SVM_IOIO_ASIZE_MASK) |
 | 
					 | 
				
			||||||
                              ((T0 & 0xffff) << 16));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					 | 
				
			||||||
void OPPROTO op_movtl_T0_cr8(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = cpu_get_apic_tpr(env);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* DR registers access */
 | 
					 | 
				
			||||||
void OPPROTO op_movl_drN_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_movl_drN_T0(PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_lmsw_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
 | 
					 | 
				
			||||||
       if already set to one. */
 | 
					 | 
				
			||||||
    T0 = (env->cr[0] & ~0xe) | (T0 & 0xf);
 | 
					 | 
				
			||||||
    helper_movl_crN_T0(0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T0_env(void)
 | 
					void OPPROTO op_movl_T0_env(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    T0 = *(uint32_t *)((char *)env + PARAM1);
 | 
					    T0 = *(uint32_t *)((char *)env + PARAM1);
 | 
				
			||||||
@ -718,12 +622,6 @@ void OPPROTO op_movtl_env_T1(void)
 | 
				
			|||||||
    *(target_ulong *)((char *)env + PARAM1) = T1;
 | 
					    *(target_ulong *)((char *)env + PARAM1) = T1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_clts(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->cr[0] &= ~CR0_TS_MASK;
 | 
					 | 
				
			||||||
    env->hflags &= ~HF_TS_MASK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* flags handling */
 | 
					/* flags handling */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_jmp_label(void)
 | 
					void OPPROTO op_jmp_label(void)
 | 
				
			||||||
@ -1028,17 +926,6 @@ void OPPROTO op_fcomi_dummy(void)
 | 
				
			|||||||
    T0 = 0;
 | 
					    T0 = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* threading support */
 | 
					 | 
				
			||||||
void OPPROTO op_lock(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    cpu_lock();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_unlock(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    cpu_unlock();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SSE support */
 | 
					/* SSE support */
 | 
				
			||||||
void OPPROTO op_com_dummy(void)
 | 
					void OPPROTO op_com_dummy(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -471,12 +471,12 @@ void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s)
 | 
					void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    for(i = 0; i < (8 << SHIFT); i++) {
 | 
					    for(i = 0; i < (8 << SHIFT); i++) {
 | 
				
			||||||
        if (s->B(i) & 0x80)
 | 
					        if (s->B(i) & 0x80)
 | 
				
			||||||
            stb(A0 + i, d->B(i));
 | 
					            stb(a0 + i, d->B(i));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -104,7 +104,7 @@ void glue(helper_pmuludq, SUFFIX) (Reg *d, Reg *s);
 | 
				
			|||||||
void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s);
 | 
					void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s);
 | 
					void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s);
 | 
				
			||||||
void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s);
 | 
					void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0);
 | 
				
			||||||
void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val);
 | 
					void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val);
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
void glue(helper_movq_mm_T0, SUFFIX) (Reg *d, uint64_t val);
 | 
					void glue(helper_movq_mm_T0, SUFFIX) (Reg *d, uint64_t val);
 | 
				
			||||||
 | 
				
			|||||||
@ -554,39 +554,6 @@ void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
 | 
				
			|||||||
    T0 = DF << SHIFT;
 | 
					    T0 = DF << SHIFT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* port I/O */
 | 
					 | 
				
			||||||
#if DATA_BITS <= 32
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(cpu_out, SUFFIX)(env, T0, T1 & DATA_MASK);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = glue(cpu_in, SUFFIX)(env, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = glue(cpu_in, SUFFIX)(env, EDX & 0xffff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(cpu_out, SUFFIX)(env, EDX & 0xffff, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_check_io, SUFFIX), _T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(glue(check_io, SUFFIX), _T0)();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_check_io, SUFFIX), _DX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(glue(check_io, SUFFIX), _DX)();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef DATA_BITS
 | 
					#undef DATA_BITS
 | 
				
			||||||
#undef SHIFT_MASK
 | 
					#undef SHIFT_MASK
 | 
				
			||||||
#undef SHIFT1_MASK
 | 
					#undef SHIFT1_MASK
 | 
				
			||||||
 | 
				
			|||||||
@ -71,8 +71,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 | 
				
			|||||||
	uint32_t int_vector;
 | 
						uint32_t int_vector;
 | 
				
			||||||
	uint32_t int_state;
 | 
						uint32_t int_state;
 | 
				
			||||||
	uint8_t reserved_3[4];
 | 
						uint8_t reserved_3[4];
 | 
				
			||||||
	uint32_t exit_code;
 | 
						uint64_t exit_code;
 | 
				
			||||||
	uint32_t exit_code_hi;
 | 
					 | 
				
			||||||
	uint64_t exit_info_1;
 | 
						uint64_t exit_info_1;
 | 
				
			||||||
	uint64_t exit_info_2;
 | 
						uint64_t exit_info_2;
 | 
				
			||||||
	uint32_t exit_int_info;
 | 
						uint32_t exit_int_info;
 | 
				
			||||||
@ -323,14 +322,6 @@ struct __attribute__ ((__packed__)) vmcb {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* function references */
 | 
					/* function references */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_stgi(void);
 | 
					 | 
				
			||||||
void vmexit(uint64_t exit_code, uint64_t exit_info_1);
 | 
					 | 
				
			||||||
int svm_check_intercept_param(uint32_t type, uint64_t param);
 | 
					 | 
				
			||||||
static inline int svm_check_intercept(unsigned int type) {
 | 
					 | 
				
			||||||
    return svm_check_intercept_param(type, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define INTERCEPTED(mask) (env->intercept & mask)
 | 
					#define INTERCEPTED(mask) (env->intercept & mask)
 | 
				
			||||||
#define INTERCEPTEDw(var, mask) (env->intercept ## var & mask)
 | 
					#define INTERCEPTEDw(var, mask) (env->intercept ## var & mask)
 | 
				
			||||||
#define INTERCEPTEDl(var, mask) (env->intercept ## var & mask)
 | 
					#define INTERCEPTEDl(var, mask) (env->intercept ## var & mask)
 | 
				
			||||||
 | 
				
			|||||||
@ -60,7 +60,7 @@
 | 
				
			|||||||
/* global register indexes */
 | 
					/* global register indexes */
 | 
				
			||||||
static TCGv cpu_env, cpu_T[2], cpu_A0;
 | 
					static TCGv cpu_env, cpu_T[2], cpu_A0;
 | 
				
			||||||
/* local register indexes (only used inside old micro ops) */
 | 
					/* local register indexes (only used inside old micro ops) */
 | 
				
			||||||
static TCGv cpu_tmp0, cpu_tmp1, cpu_tmp2, cpu_ptr0, cpu_ptr1;
 | 
					static TCGv cpu_tmp0, cpu_tmp1, cpu_tmp2, cpu_tmp3, cpu_ptr0, cpu_ptr1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
static int x86_64_hregs;
 | 
					static int x86_64_hregs;
 | 
				
			||||||
@ -903,52 +903,54 @@ static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GenOpFunc *gen_op_in_DX_T0[3] = {
 | 
					static void *helper_in_func[3] = {
 | 
				
			||||||
    gen_op_inb_DX_T0,
 | 
					    helper_inb,
 | 
				
			||||||
    gen_op_inw_DX_T0,
 | 
					    helper_inw,
 | 
				
			||||||
    gen_op_inl_DX_T0,
 | 
					    helper_inl,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GenOpFunc *gen_op_out_DX_T0[3] = {
 | 
					static void *helper_out_func[3] = {
 | 
				
			||||||
    gen_op_outb_DX_T0,
 | 
					    helper_outb,
 | 
				
			||||||
    gen_op_outw_DX_T0,
 | 
					    helper_outw,
 | 
				
			||||||
    gen_op_outl_DX_T0,
 | 
					    helper_outl,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GenOpFunc *gen_op_in[3] = {
 | 
					static void *gen_check_io_func[3] = {
 | 
				
			||||||
    gen_op_inb_T0_T1,
 | 
					    helper_check_iob,
 | 
				
			||||||
    gen_op_inw_T0_T1,
 | 
					    helper_check_iow,
 | 
				
			||||||
    gen_op_inl_T0_T1,
 | 
					    helper_check_iol,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GenOpFunc *gen_op_out[3] = {
 | 
					static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
 | 
				
			||||||
    gen_op_outb_T0_T1,
 | 
					                         uint32_t svm_flags)
 | 
				
			||||||
    gen_op_outw_T0_T1,
 | 
					 | 
				
			||||||
    gen_op_outl_T0_T1,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc *gen_check_io_T0[3] = {
 | 
					 | 
				
			||||||
    gen_op_check_iob_T0,
 | 
					 | 
				
			||||||
    gen_op_check_iow_T0,
 | 
					 | 
				
			||||||
    gen_op_check_iol_T0,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc *gen_check_io_DX[3] = {
 | 
					 | 
				
			||||||
    gen_op_check_iob_DX,
 | 
					 | 
				
			||||||
    gen_op_check_iow_DX,
 | 
					 | 
				
			||||||
    gen_op_check_iol_DX,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int state_saved;
 | 
				
			||||||
 | 
					    target_ulong next_eip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state_saved = 0;
 | 
				
			||||||
    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
 | 
					    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
 | 
				
			||||||
        if (s->cc_op != CC_OP_DYNAMIC)
 | 
					        if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
            gen_op_set_cc_op(s->cc_op);
 | 
					            gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
        gen_jmp_im(cur_eip);
 | 
					        gen_jmp_im(cur_eip);
 | 
				
			||||||
        if (use_dx)
 | 
					        state_saved = 1;
 | 
				
			||||||
            gen_check_io_DX[ot]();
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
        else
 | 
					        tcg_gen_helper_0_1(gen_check_io_func[ot],
 | 
				
			||||||
            gen_check_io_T0[ot]();
 | 
					                           cpu_tmp2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {
 | 
				
			||||||
 | 
					        if (!state_saved) {
 | 
				
			||||||
 | 
					            if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
 | 
					                gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
 | 
					            gen_jmp_im(cur_eip);
 | 
				
			||||||
 | 
					            state_saved = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        svm_flags |= (1 << (4 + ot));
 | 
				
			||||||
 | 
					        next_eip = s->pc - s->cs_base;
 | 
				
			||||||
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					        tcg_gen_helper_0_3(helper_svm_check_io,
 | 
				
			||||||
 | 
					                           cpu_tmp2,
 | 
				
			||||||
 | 
					                           tcg_const_i32(svm_flags),
 | 
				
			||||||
 | 
					                           tcg_const_i32(next_eip - cur_eip));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1080,7 +1082,10 @@ static inline void gen_ins(DisasContext *s, int ot)
 | 
				
			|||||||
    gen_string_movl_A0_EDI(s);
 | 
					    gen_string_movl_A0_EDI(s);
 | 
				
			||||||
    gen_op_movl_T0_0();
 | 
					    gen_op_movl_T0_0();
 | 
				
			||||||
    gen_op_st_T0_A0(ot + s->mem_index);
 | 
					    gen_op_st_T0_A0(ot + s->mem_index);
 | 
				
			||||||
    gen_op_in_DX_T0[ot]();
 | 
					    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
 | 
				
			||||||
 | 
					    tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[1]);
 | 
				
			||||||
 | 
					    tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
 | 
				
			||||||
 | 
					    tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2);
 | 
				
			||||||
    gen_op_st_T0_A0(ot + s->mem_index);
 | 
					    gen_op_st_T0_A0(ot + s->mem_index);
 | 
				
			||||||
    gen_op_movl_T0_Dshift[ot]();
 | 
					    gen_op_movl_T0_Dshift[ot]();
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
@ -1099,7 +1104,13 @@ static inline void gen_outs(DisasContext *s, int ot)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    gen_string_movl_A0_ESI(s);
 | 
					    gen_string_movl_A0_ESI(s);
 | 
				
			||||||
    gen_op_ld_T0_A0(ot + s->mem_index);
 | 
					    gen_op_ld_T0_A0(ot + s->mem_index);
 | 
				
			||||||
    gen_op_out_DX_T0[ot]();
 | 
					
 | 
				
			||||||
 | 
					    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
 | 
				
			||||||
 | 
					    tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[1]);
 | 
				
			||||||
 | 
					    tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
 | 
				
			||||||
 | 
					    tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[0]);
 | 
				
			||||||
 | 
					    tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gen_op_movl_T0_Dshift[ot]();
 | 
					    gen_op_movl_T0_Dshift[ot]();
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
    if (s->aflag == 2) {
 | 
					    if (s->aflag == 2) {
 | 
				
			||||||
@ -1976,7 +1987,8 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
 | 
				
			|||||||
        if (s->cc_op != CC_OP_DYNAMIC)
 | 
					        if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
            gen_op_set_cc_op(s->cc_op);
 | 
					            gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
        gen_jmp_im(cur_eip);
 | 
					        gen_jmp_im(cur_eip);
 | 
				
			||||||
        gen_op_movl_seg_T0(seg_reg);
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					        tcg_gen_helper_0_2(helper_load_seg, tcg_const_i32(seg_reg), cpu_tmp2);
 | 
				
			||||||
        /* abort translation because the addseg value may change or
 | 
					        /* abort translation because the addseg value may change or
 | 
				
			||||||
           because ss32 may change. For R_SS, translation must always
 | 
					           because ss32 may change. For R_SS, translation must always
 | 
				
			||||||
           stop as a special handling must be done to disable hardware
 | 
					           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)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SVM_movq_T1_im(x) gen_movtl_T1_im(x)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int
 | 
					 | 
				
			||||||
gen_svm_check_io(DisasContext *s, target_ulong pc_start, uint64_t type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					 | 
				
			||||||
    if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {
 | 
					 | 
				
			||||||
        if (s->cc_op != CC_OP_DYNAMIC)
 | 
					 | 
				
			||||||
            gen_op_set_cc_op(s->cc_op);
 | 
					 | 
				
			||||||
        SVM_movq_T1_im(s->pc - s->cs_base);
 | 
					 | 
				
			||||||
        gen_jmp_im(pc_start - s->cs_base);
 | 
					 | 
				
			||||||
        gen_op_geneflags();
 | 
					 | 
				
			||||||
        gen_op_svm_check_intercept_io((uint32_t)(type >> 32), (uint32_t)type);
 | 
					 | 
				
			||||||
        s->cc_op = CC_OP_DYNAMIC;
 | 
					 | 
				
			||||||
        /* FIXME: maybe we could move the io intercept vector to the TB as well
 | 
					 | 
				
			||||||
                  so we know if this is an EOB or not ... let's assume it's not
 | 
					 | 
				
			||||||
                  for now. */
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int svm_is_rep(int prefixes)
 | 
					static inline int svm_is_rep(int prefixes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
 | 
					    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
 | 
				
			||||||
@ -2019,7 +2009,7 @@ static inline int svm_is_rep(int prefixes)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static inline int
 | 
					static inline int
 | 
				
			||||||
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
 | 
					gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
 | 
				
			||||||
                              uint64_t type, uint64_t param)
 | 
					                              uint32_t type, uint64_t param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(!(s->flags & (INTERCEPT_SVM_MASK)))
 | 
					    if(!(s->flags & (INTERCEPT_SVM_MASK)))
 | 
				
			||||||
	/* no SVM activated */
 | 
						/* no SVM activated */
 | 
				
			||||||
@ -2029,12 +2019,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
 | 
				
			|||||||
        case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1:
 | 
					        case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1:
 | 
				
			||||||
            if (s->cc_op != CC_OP_DYNAMIC) {
 | 
					            if (s->cc_op != CC_OP_DYNAMIC) {
 | 
				
			||||||
                gen_op_set_cc_op(s->cc_op);
 | 
					                gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
                s->cc_op = CC_OP_DYNAMIC;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            gen_jmp_im(pc_start - s->cs_base);
 | 
					            gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
            SVM_movq_T1_im(param);
 | 
					            tcg_gen_helper_0_2(helper_svm_check_intercept_param, 
 | 
				
			||||||
            gen_op_geneflags();
 | 
					                               tcg_const_i32(type), tcg_const_i64(param));
 | 
				
			||||||
            gen_op_svm_check_intercept_param((uint32_t)(type >> 32), (uint32_t)type);
 | 
					 | 
				
			||||||
            /* this is a special case as we do not know if the interception occurs
 | 
					            /* this is a special case as we do not know if the interception occurs
 | 
				
			||||||
               so we assume there was none */
 | 
					               so we assume there was none */
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
@ -2042,12 +2030,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
 | 
				
			|||||||
            if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) {
 | 
					            if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) {
 | 
				
			||||||
                if (s->cc_op != CC_OP_DYNAMIC) {
 | 
					                if (s->cc_op != CC_OP_DYNAMIC) {
 | 
				
			||||||
                    gen_op_set_cc_op(s->cc_op);
 | 
					                    gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
                    s->cc_op = CC_OP_DYNAMIC;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                gen_jmp_im(pc_start - s->cs_base);
 | 
					                gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
                SVM_movq_T1_im(param);
 | 
					                tcg_gen_helper_0_2(helper_svm_check_intercept_param,
 | 
				
			||||||
                gen_op_geneflags();
 | 
					                                   tcg_const_i32(type), tcg_const_i64(param));
 | 
				
			||||||
                gen_op_svm_check_intercept_param((uint32_t)(type >> 32), (uint32_t)type);
 | 
					 | 
				
			||||||
                /* this is a special case as we do not know if the interception occurs
 | 
					                /* this is a special case as we do not know if the interception occurs
 | 
				
			||||||
                   so we assume there was none */
 | 
					                   so we assume there was none */
 | 
				
			||||||
                return 0;
 | 
					                return 0;
 | 
				
			||||||
@ -2057,12 +2043,10 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
 | 
				
			|||||||
            if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) {
 | 
					            if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) {
 | 
				
			||||||
                if (s->cc_op != CC_OP_DYNAMIC) {
 | 
					                if (s->cc_op != CC_OP_DYNAMIC) {
 | 
				
			||||||
                    gen_op_set_cc_op(s->cc_op);
 | 
					                    gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
		    s->cc_op = CC_OP_EFLAGS;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                gen_jmp_im(pc_start - s->cs_base);
 | 
					                gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
                SVM_movq_T1_im(param);
 | 
					                tcg_gen_helper_0_2(helper_vmexit,
 | 
				
			||||||
                gen_op_geneflags();
 | 
					                                   tcg_const_i32(type), tcg_const_i64(param));
 | 
				
			||||||
                gen_op_svm_vmexit(type >> 32, type);
 | 
					 | 
				
			||||||
                /* we can optimize this one so TBs don't get longer
 | 
					                /* we can optimize this one so TBs don't get longer
 | 
				
			||||||
                   than up to vmexit */
 | 
					                   than up to vmexit */
 | 
				
			||||||
                gen_eob(s);
 | 
					                gen_eob(s);
 | 
				
			||||||
@ -2276,9 +2260,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
 | 
				
			|||||||
        gen_op_st_T0_A0(ot + s->mem_index);
 | 
					        gen_op_st_T0_A0(ot + s->mem_index);
 | 
				
			||||||
        if (level) {
 | 
					        if (level) {
 | 
				
			||||||
            /* XXX: must save state */
 | 
					            /* XXX: must save state */
 | 
				
			||||||
            tcg_gen_helper_0_2(helper_enter64_level,
 | 
					            tcg_gen_helper_0_3(helper_enter64_level,
 | 
				
			||||||
                               tcg_const_i32(level),
 | 
					                               tcg_const_i32(level),
 | 
				
			||||||
                               tcg_const_i32((ot == OT_QUAD)));
 | 
					                               tcg_const_i32((ot == OT_QUAD)),
 | 
				
			||||||
 | 
					                               cpu_T[1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        gen_op_mov_reg_T1(ot, R_EBP);
 | 
					        gen_op_mov_reg_T1(ot, R_EBP);
 | 
				
			||||||
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
 | 
					        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
 | 
				
			||||||
@ -2301,9 +2286,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
 | 
				
			|||||||
        gen_op_st_T0_A0(ot + s->mem_index);
 | 
					        gen_op_st_T0_A0(ot + s->mem_index);
 | 
				
			||||||
        if (level) {
 | 
					        if (level) {
 | 
				
			||||||
            /* XXX: must save state */
 | 
					            /* XXX: must save state */
 | 
				
			||||||
            tcg_gen_helper_0_2(helper_enter_level,
 | 
					            tcg_gen_helper_0_3(helper_enter_level,
 | 
				
			||||||
                               tcg_const_i32(level),
 | 
					                               tcg_const_i32(level),
 | 
				
			||||||
                               tcg_const_i32(s->dflag));
 | 
					                               tcg_const_i32(s->dflag),
 | 
				
			||||||
 | 
					                               cpu_T[1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        gen_op_mov_reg_T1(ot, R_EBP);
 | 
					        gen_op_mov_reg_T1(ot, R_EBP);
 | 
				
			||||||
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
 | 
					        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)
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* generic MMX or SSE operation */
 | 
					        /* generic MMX or SSE operation */
 | 
				
			||||||
        switch(b) {
 | 
					        switch(b) {
 | 
				
			||||||
        case 0xf7:
 | 
					 | 
				
			||||||
            /* maskmov : we must prepare A0 */
 | 
					 | 
				
			||||||
            if (mod != 3)
 | 
					 | 
				
			||||||
                goto illegal_op;
 | 
					 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					 | 
				
			||||||
            if (s->aflag == 2) {
 | 
					 | 
				
			||||||
                gen_op_movq_A0_reg(R_EDI);
 | 
					 | 
				
			||||||
            } else
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                gen_op_movl_A0_reg(R_EDI);
 | 
					 | 
				
			||||||
                if (s->aflag == 0)
 | 
					 | 
				
			||||||
                    gen_op_andl_A0_ffff();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            gen_add_A0_ds_seg(s);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x70: /* pshufx insn */
 | 
					        case 0x70: /* pshufx insn */
 | 
				
			||||||
        case 0xc6: /* pshufx insn */
 | 
					        case 0xc6: /* pshufx insn */
 | 
				
			||||||
        case 0xc2: /* compare insns */
 | 
					        case 0xc2: /* compare insns */
 | 
				
			||||||
@ -3295,6 +3265,26 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
 | 
				
			|||||||
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 | 
					            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 | 
				
			||||||
            tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
 | 
					            tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case 0xf7:
 | 
				
			||||||
 | 
					            /* maskmov : we must prepare A0 */
 | 
				
			||||||
 | 
					            if (mod != 3)
 | 
				
			||||||
 | 
					                goto illegal_op;
 | 
				
			||||||
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
 | 
					            if (s->aflag == 2) {
 | 
				
			||||||
 | 
					                gen_op_movq_A0_reg(R_EDI);
 | 
				
			||||||
 | 
					            } else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                gen_op_movl_A0_reg(R_EDI);
 | 
				
			||||||
 | 
					                if (s->aflag == 0)
 | 
				
			||||||
 | 
					                    gen_op_andl_A0_ffff();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            gen_add_A0_ds_seg(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 | 
				
			||||||
 | 
					            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 | 
				
			||||||
 | 
					            tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, cpu_A0);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 | 
					            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 | 
				
			||||||
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 | 
					            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)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* lock generation */
 | 
					    /* lock generation */
 | 
				
			||||||
    if (prefixes & PREFIX_LOCK)
 | 
					    if (prefixes & PREFIX_LOCK)
 | 
				
			||||||
        gen_op_lock();
 | 
					        tcg_gen_helper_0_0(helper_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* now check op code */
 | 
					    /* now check op code */
 | 
				
			||||||
 reswitch:
 | 
					 reswitch:
 | 
				
			||||||
@ -3783,9 +3773,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
                if (s->cc_op != CC_OP_DYNAMIC)
 | 
					                if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
                    gen_op_set_cc_op(s->cc_op);
 | 
					                    gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
                gen_jmp_im(pc_start - s->cs_base);
 | 
					                gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
                gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
 | 
					                tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					                tcg_gen_helper_0_4(helper_lcall_protected,
 | 
				
			||||||
 | 
					                                   cpu_tmp2, cpu_T[1],
 | 
				
			||||||
 | 
					                                   tcg_const_i32(dflag), 
 | 
				
			||||||
 | 
					                                   tcg_const_i32(s->pc - pc_start));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
 | 
					                tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					                tcg_gen_helper_0_4(helper_lcall_real,
 | 
				
			||||||
 | 
					                                   cpu_tmp2, cpu_T[1],
 | 
				
			||||||
 | 
					                                   tcg_const_i32(dflag), 
 | 
				
			||||||
 | 
					                                   tcg_const_i32(s->pc - s->cs_base));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            gen_eob(s);
 | 
					            gen_eob(s);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@ -3804,7 +3802,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
                if (s->cc_op != CC_OP_DYNAMIC)
 | 
					                if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
                    gen_op_set_cc_op(s->cc_op);
 | 
					                    gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
                gen_jmp_im(pc_start - s->cs_base);
 | 
					                gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
                gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
 | 
					                tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					                tcg_gen_helper_0_3(helper_ljmp_protected,
 | 
				
			||||||
 | 
					                                   cpu_tmp2,
 | 
				
			||||||
 | 
					                                   cpu_T[1],
 | 
				
			||||||
 | 
					                                   tcg_const_i32(s->pc - pc_start));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
 | 
					                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
 | 
				
			||||||
                gen_op_movl_T0_T1();
 | 
					                gen_op_movl_T0_T1();
 | 
				
			||||||
@ -4355,11 +4357,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            gen_op_mov_TN_reg(ot, 0, reg);
 | 
					            gen_op_mov_TN_reg(ot, 0, reg);
 | 
				
			||||||
            /* for xchg, lock is implicit */
 | 
					            /* for xchg, lock is implicit */
 | 
				
			||||||
            if (!(prefixes & PREFIX_LOCK))
 | 
					            if (!(prefixes & PREFIX_LOCK))
 | 
				
			||||||
                gen_op_lock();
 | 
					                tcg_gen_helper_0_0(helper_lock);
 | 
				
			||||||
            gen_op_ld_T1_A0(ot + s->mem_index);
 | 
					            gen_op_ld_T1_A0(ot + s->mem_index);
 | 
				
			||||||
            gen_op_st_T0_A0(ot + s->mem_index);
 | 
					            gen_op_st_T0_A0(ot + s->mem_index);
 | 
				
			||||||
            if (!(prefixes & PREFIX_LOCK))
 | 
					            if (!(prefixes & PREFIX_LOCK))
 | 
				
			||||||
                gen_op_unlock();
 | 
					                tcg_gen_helper_0_0(helper_unlock);
 | 
				
			||||||
            gen_op_mov_reg_T1(ot, reg);
 | 
					            gen_op_mov_reg_T1(ot, reg);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -5117,13 +5119,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            ot = OT_BYTE;
 | 
					            ot = OT_BYTE;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            ot = dflag ? OT_LONG : OT_WORD;
 | 
					            ot = dflag ? OT_LONG : OT_WORD;
 | 
				
			||||||
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
 | 
					 | 
				
			||||||
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
					        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
				
			||||||
        gen_op_andl_T0_ffff();
 | 
					        gen_op_andl_T0_ffff();
 | 
				
			||||||
        if (gen_svm_check_io(s, pc_start,
 | 
					        gen_check_io(s, ot, pc_start - s->cs_base, 
 | 
				
			||||||
                             SVM_IOIO_TYPE_MASK | (1 << (4+ot)) |
 | 
					                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
 | 
				
			||||||
                             svm_is_rep(prefixes) | 4 | (1 << (7+s->aflag))))
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 | 
					        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 | 
				
			||||||
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 | 
					            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -5136,13 +5135,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            ot = OT_BYTE;
 | 
					            ot = OT_BYTE;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            ot = dflag ? OT_LONG : OT_WORD;
 | 
					            ot = dflag ? OT_LONG : OT_WORD;
 | 
				
			||||||
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
 | 
					 | 
				
			||||||
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
					        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
				
			||||||
        gen_op_andl_T0_ffff();
 | 
					        gen_op_andl_T0_ffff();
 | 
				
			||||||
        if (gen_svm_check_io(s, pc_start,
 | 
					        gen_check_io(s, ot, pc_start - s->cs_base,
 | 
				
			||||||
                             (1 << (4+ot)) | svm_is_rep(prefixes) |
 | 
					                     svm_is_rep(prefixes) | 4);
 | 
				
			||||||
                             4 | (1 << (7+s->aflag))))
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 | 
					        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 | 
				
			||||||
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 | 
					            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -5161,12 +5157,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            ot = dflag ? OT_LONG : OT_WORD;
 | 
					            ot = dflag ? OT_LONG : OT_WORD;
 | 
				
			||||||
        val = ldub_code(s->pc++);
 | 
					        val = ldub_code(s->pc++);
 | 
				
			||||||
        gen_op_movl_T0_im(val);
 | 
					        gen_op_movl_T0_im(val);
 | 
				
			||||||
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
 | 
					        gen_check_io(s, ot, pc_start - s->cs_base,
 | 
				
			||||||
        if (gen_svm_check_io(s, pc_start,
 | 
					                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
 | 
				
			||||||
                             SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) |
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
                             (1 << (4+ot))))
 | 
					        tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2);
 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        gen_op_in[ot]();
 | 
					 | 
				
			||||||
        gen_op_mov_reg_T1(ot, R_EAX);
 | 
					        gen_op_mov_reg_T1(ot, R_EAX);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 0xe6:
 | 
					    case 0xe6:
 | 
				
			||||||
@ -5177,12 +5171,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            ot = dflag ? OT_LONG : OT_WORD;
 | 
					            ot = dflag ? OT_LONG : OT_WORD;
 | 
				
			||||||
        val = ldub_code(s->pc++);
 | 
					        val = ldub_code(s->pc++);
 | 
				
			||||||
        gen_op_movl_T0_im(val);
 | 
					        gen_op_movl_T0_im(val);
 | 
				
			||||||
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
 | 
					        gen_check_io(s, ot, pc_start - s->cs_base,
 | 
				
			||||||
        if (gen_svm_check_io(s, pc_start, svm_is_rep(prefixes) |
 | 
					                     svm_is_rep(prefixes));
 | 
				
			||||||
                             (1 << (4+ot))))
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        gen_op_mov_TN_reg(ot, 1, R_EAX);
 | 
					        gen_op_mov_TN_reg(ot, 1, R_EAX);
 | 
				
			||||||
        gen_op_out[ot]();
 | 
					
 | 
				
			||||||
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					        tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
 | 
				
			||||||
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[1]);
 | 
				
			||||||
 | 
					        tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 0xec:
 | 
					    case 0xec:
 | 
				
			||||||
    case 0xed:
 | 
					    case 0xed:
 | 
				
			||||||
@ -5192,12 +5188,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            ot = dflag ? OT_LONG : OT_WORD;
 | 
					            ot = dflag ? OT_LONG : OT_WORD;
 | 
				
			||||||
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
					        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
				
			||||||
        gen_op_andl_T0_ffff();
 | 
					        gen_op_andl_T0_ffff();
 | 
				
			||||||
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
 | 
					        gen_check_io(s, ot, pc_start - s->cs_base,
 | 
				
			||||||
        if (gen_svm_check_io(s, pc_start,
 | 
					                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
 | 
				
			||||||
                             SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) |
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
                             (1 << (4+ot))))
 | 
					        tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2);
 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        gen_op_in[ot]();
 | 
					 | 
				
			||||||
        gen_op_mov_reg_T1(ot, R_EAX);
 | 
					        gen_op_mov_reg_T1(ot, R_EAX);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 0xee:
 | 
					    case 0xee:
 | 
				
			||||||
@ -5208,12 +5202,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            ot = dflag ? OT_LONG : OT_WORD;
 | 
					            ot = dflag ? OT_LONG : OT_WORD;
 | 
				
			||||||
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
					        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 | 
				
			||||||
        gen_op_andl_T0_ffff();
 | 
					        gen_op_andl_T0_ffff();
 | 
				
			||||||
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
 | 
					        gen_check_io(s, ot, pc_start - s->cs_base,
 | 
				
			||||||
        if (gen_svm_check_io(s, pc_start,
 | 
					                     svm_is_rep(prefixes));
 | 
				
			||||||
                             svm_is_rep(prefixes) | (1 << (4+ot))))
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        gen_op_mov_TN_reg(ot, 1, R_EAX);
 | 
					        gen_op_mov_TN_reg(ot, 1, R_EAX);
 | 
				
			||||||
        gen_op_out[ot]();
 | 
					
 | 
				
			||||||
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
 | 
					        tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
 | 
				
			||||||
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[1]);
 | 
				
			||||||
 | 
					        tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /************************/
 | 
					        /************************/
 | 
				
			||||||
@ -5246,7 +5242,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            if (s->cc_op != CC_OP_DYNAMIC)
 | 
					            if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
                gen_op_set_cc_op(s->cc_op);
 | 
					                gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
            gen_jmp_im(pc_start - s->cs_base);
 | 
					            gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
            gen_op_lret_protected(s->dflag, val);
 | 
					            tcg_gen_helper_0_2(helper_lret_protected,
 | 
				
			||||||
 | 
					                               tcg_const_i32(s->dflag), 
 | 
				
			||||||
 | 
					                               tcg_const_i32(val));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            gen_stack_A0(s);
 | 
					            gen_stack_A0(s);
 | 
				
			||||||
            /* pop offset */
 | 
					            /* pop offset */
 | 
				
			||||||
@ -5273,20 +5271,22 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
        if (!s->pe) {
 | 
					        if (!s->pe) {
 | 
				
			||||||
            /* real mode */
 | 
					            /* real mode */
 | 
				
			||||||
            gen_op_iret_real(s->dflag);
 | 
					            tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
 | 
				
			||||||
            s->cc_op = CC_OP_EFLAGS;
 | 
					            s->cc_op = CC_OP_EFLAGS;
 | 
				
			||||||
        } else if (s->vm86) {
 | 
					        } else if (s->vm86) {
 | 
				
			||||||
            if (s->iopl != 3) {
 | 
					            if (s->iopl != 3) {
 | 
				
			||||||
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 | 
					                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                gen_op_iret_real(s->dflag);
 | 
					                tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
 | 
				
			||||||
                s->cc_op = CC_OP_EFLAGS;
 | 
					                s->cc_op = CC_OP_EFLAGS;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (s->cc_op != CC_OP_DYNAMIC)
 | 
					            if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
                gen_op_set_cc_op(s->cc_op);
 | 
					                gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
            gen_jmp_im(pc_start - s->cs_base);
 | 
					            gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
            gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
 | 
					            tcg_gen_helper_0_2(helper_iret_protected,
 | 
				
			||||||
 | 
					                               tcg_const_i32(s->dflag), 
 | 
				
			||||||
 | 
					                               tcg_const_i32(s->pc - s->cs_base));
 | 
				
			||||||
            s->cc_op = CC_OP_EFLAGS;
 | 
					            s->cc_op = CC_OP_EFLAGS;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        gen_eob(s);
 | 
					        gen_eob(s);
 | 
				
			||||||
@ -5723,10 +5723,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
        gen_op_mov_TN_reg(ot, 0, reg);
 | 
					        gen_op_mov_TN_reg(ot, 0, reg);
 | 
				
			||||||
        gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
 | 
					        gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
 | 
				
			||||||
        gen_jmp_im(pc_start - s->cs_base);
 | 
					        gen_jmp_im(pc_start - s->cs_base);
 | 
				
			||||||
 | 
					        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
 | 
				
			||||||
        if (ot == OT_WORD)
 | 
					        if (ot == OT_WORD)
 | 
				
			||||||
            tcg_gen_helper_0_0(helper_boundw);
 | 
					            tcg_gen_helper_0_2(helper_boundw, cpu_A0, cpu_tmp2);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            tcg_gen_helper_0_0(helper_boundl);
 | 
					            tcg_gen_helper_0_2(helper_boundl, cpu_A0, cpu_tmp2);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 0x1c8 ... 0x1cf: /* bswap reg */
 | 
					    case 0x1c8 ... 0x1cf: /* bswap reg */
 | 
				
			||||||
        reg = (b & 7) | REX_B(s);
 | 
					        reg = (b & 7) | REX_B(s);
 | 
				
			||||||
@ -6134,7 +6135,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
                if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
 | 
					                if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 | 
					                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 | 
				
			||||||
                gen_op_lmsw_T0();
 | 
					                tcg_gen_helper_0_1(helper_lmsw, cpu_T[0]);
 | 
				
			||||||
                gen_jmp_im(s->pc - s->cs_base);
 | 
					                gen_jmp_im(s->pc - s->cs_base);
 | 
				
			||||||
                gen_eob(s);
 | 
					                gen_eob(s);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -6223,6 +6224,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                gen_op_mov_TN_reg(ot, 0, rm);
 | 
					                gen_op_mov_TN_reg(ot, 0, rm);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            gen_op_mov_TN_reg(ot, 1, reg);
 | 
				
			||||||
            if (s->cc_op != CC_OP_DYNAMIC)
 | 
					            if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
                gen_op_set_cc_op(s->cc_op);
 | 
					                gen_op_set_cc_op(s->cc_op);
 | 
				
			||||||
            gen_op_arpl();
 | 
					            gen_op_arpl();
 | 
				
			||||||
@ -6299,14 +6301,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
                if (b & 2) {
 | 
					                if (b & 2) {
 | 
				
			||||||
                    gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
 | 
					                    gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
 | 
				
			||||||
                    gen_op_mov_TN_reg(ot, 0, rm);
 | 
					                    gen_op_mov_TN_reg(ot, 0, rm);
 | 
				
			||||||
                    gen_op_movl_crN_T0(reg);
 | 
					                    tcg_gen_helper_0_2(helper_movl_crN_T0, 
 | 
				
			||||||
 | 
					                                       tcg_const_i32(reg), cpu_T[0]);
 | 
				
			||||||
                    gen_jmp_im(s->pc - s->cs_base);
 | 
					                    gen_jmp_im(s->pc - s->cs_base);
 | 
				
			||||||
                    gen_eob(s);
 | 
					                    gen_eob(s);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
 | 
					                    gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
                    if (reg == 8)
 | 
					                    if (reg == 8)
 | 
				
			||||||
                        gen_op_movtl_T0_cr8();
 | 
					                        tcg_gen_helper_1_0(helper_movtl_T0_cr8, cpu_T[0]);
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                        gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
 | 
					                        gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
 | 
				
			||||||
@ -6338,7 +6341,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            if (b & 2) {
 | 
					            if (b & 2) {
 | 
				
			||||||
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
 | 
					                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
 | 
				
			||||||
                gen_op_mov_TN_reg(ot, 0, rm);
 | 
					                gen_op_mov_TN_reg(ot, 0, rm);
 | 
				
			||||||
                gen_op_movl_drN_T0(reg);
 | 
					                tcg_gen_helper_0_2(helper_movl_drN_T0,
 | 
				
			||||||
 | 
					                                   tcg_const_i32(reg), cpu_T[0]);
 | 
				
			||||||
                gen_jmp_im(s->pc - s->cs_base);
 | 
					                gen_jmp_im(s->pc - s->cs_base);
 | 
				
			||||||
                gen_eob(s);
 | 
					                gen_eob(s);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
@ -6353,7 +6357,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 | 
					            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
 | 
					            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
 | 
				
			||||||
            gen_op_clts();
 | 
					            tcg_gen_helper_0_0(helper_clts);
 | 
				
			||||||
            /* abort block because static cpu state changed */
 | 
					            /* abort block because static cpu state changed */
 | 
				
			||||||
            gen_jmp_im(s->pc - s->cs_base);
 | 
					            gen_jmp_im(s->pc - s->cs_base);
 | 
				
			||||||
            gen_eob(s);
 | 
					            gen_eob(s);
 | 
				
			||||||
@ -6485,11 +6489,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    /* lock generation */
 | 
					    /* lock generation */
 | 
				
			||||||
    if (s->prefix & PREFIX_LOCK)
 | 
					    if (s->prefix & PREFIX_LOCK)
 | 
				
			||||||
        gen_op_unlock();
 | 
					        tcg_gen_helper_0_0(helper_unlock);
 | 
				
			||||||
    return s->pc;
 | 
					    return s->pc;
 | 
				
			||||||
 illegal_op:
 | 
					 illegal_op:
 | 
				
			||||||
    if (s->prefix & PREFIX_LOCK)
 | 
					    if (s->prefix & PREFIX_LOCK)
 | 
				
			||||||
        gen_op_unlock();
 | 
					        tcg_gen_helper_0_0(helper_unlock);
 | 
				
			||||||
    /* XXX: ensure that no lock was generated */
 | 
					    /* XXX: ensure that no lock was generated */
 | 
				
			||||||
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
 | 
					    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
 | 
				
			||||||
    return s->pc;
 | 
					    return s->pc;
 | 
				
			||||||
@ -6861,7 +6865,8 @@ void optimize_flags_init(void)
 | 
				
			|||||||
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
 | 
					    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
 | 
				
			||||||
    cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
 | 
					    cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#if defined(__i386__)
 | 
					#if defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS)
 | 
				
			||||||
 | 
					    /* XXX: must be suppressed once there are less fixed registers */
 | 
				
			||||||
    cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
 | 
					    cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -6957,10 +6962,11 @@ static inline int gen_intermediate_code_internal(CPUState *env,
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
 | 
					    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
 | 
				
			||||||
#if !defined(__i386__)
 | 
					#if !(defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS))
 | 
				
			||||||
    cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64);
 | 
					    cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    cpu_tmp2 = tcg_temp_new(TCG_TYPE_I32);
 | 
					    cpu_tmp2 = tcg_temp_new(TCG_TYPE_I32);
 | 
				
			||||||
 | 
					    cpu_tmp3 = tcg_temp_new(TCG_TYPE_I32);
 | 
				
			||||||
    cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
 | 
					    cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
 | 
				
			||||||
    cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
 | 
					    cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user