Loading target-i386/cpu.h +8 −0 Original line number Diff line number Diff line Loading @@ -476,6 +476,7 @@ typedef struct CPUX86State { /* temporaries if we cannot store them in host registers */ target_ulong t0, t1, t2; #endif target_ulong t3; /* standard registers */ target_ulong regs[CPU_NB_REGS]; Loading Loading @@ -727,6 +728,13 @@ static inline int cpu_mmu_index (CPUState *env) return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; } typedef struct CCTable { int (*compute_all)(void); /* return all the flags */ int (*compute_c)(void); /* return the C flag */ } CCTable; extern CCTable cc_table[]; #include "cpu-all.h" #include "svm.h" Loading target-i386/exec.h +9 −7 Original line number Diff line number Diff line Loading @@ -98,13 +98,6 @@ extern int loglevel; #include "cpu.h" #include "exec-all.h" typedef struct CCTable { int (*compute_all)(void); /* return all the flags */ int (*compute_c)(void); /* return the C flag */ } CCTable; extern CCTable cc_table[]; 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_cr4(CPUX86State *env, uint32_t new_cr4); Loading @@ -129,6 +122,15 @@ void __hidden cpu_loop_exit(void); void OPPROTO op_movl_eflags_T0(void); void OPPROTO op_movl_T0_eflags(void); /* n must be a constant to be efficient */ static inline target_long lshift(target_long x, int n) { if (n >= 0) return x << n; else return x >> (-n); } #include "helper.h" static inline void svm_check_intercept(uint32_t type) Loading target-i386/helper.c +19 −0 Original line number Diff line number Diff line Loading @@ -5220,3 +5220,22 @@ void helper_movq(uint64_t *d, uint64_t *s) #define SHIFT 1 #include "ops_sse.h" #define SHIFT 0 #include "helper_template.h" #undef SHIFT #define SHIFT 1 #include "helper_template.h" #undef SHIFT #define SHIFT 2 #include "helper_template.h" #undef SHIFT #ifdef TARGET_X86_64 #define SHIFT 3 #include "helper_template.h" #undef SHIFT #endif target-i386/helper.h +11 −0 Original line number Diff line number Diff line Loading @@ -199,3 +199,14 @@ void TCG_HELPER_PROTO helper_movq(uint64_t *d, uint64_t *s); #define SHIFT 1 #include "ops_sse_header.h" target_ulong helper_rclb(target_ulong t0, target_ulong t1); target_ulong helper_rclw(target_ulong t0, target_ulong t1); target_ulong helper_rcll(target_ulong t0, target_ulong t1); target_ulong helper_rcrb(target_ulong t0, target_ulong t1); target_ulong helper_rcrw(target_ulong t0, target_ulong t1); target_ulong helper_rcrl(target_ulong t0, target_ulong t1); #ifdef TARGET_X86_64 target_ulong helper_rclq(target_ulong t0, target_ulong t1); target_ulong helper_rcrq(target_ulong t0, target_ulong t1); #endif target-i386/helper_template.h 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * i386 helpers * * Copyright (c) 2008 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define DATA_BITS (1 << (3 + SHIFT)) #define SHIFT_MASK (DATA_BITS - 1) #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1)) #if DATA_BITS <= 32 #define SHIFT1_MASK 0x1f #else #define SHIFT1_MASK 0x3f #endif #if DATA_BITS == 8 #define SUFFIX b #define DATA_TYPE uint8_t #define DATA_STYPE int8_t #define DATA_MASK 0xff #elif DATA_BITS == 16 #define SUFFIX w #define DATA_TYPE uint16_t #define DATA_STYPE int16_t #define DATA_MASK 0xffff #elif DATA_BITS == 32 #define SUFFIX l #define DATA_TYPE uint32_t #define DATA_STYPE int32_t #define DATA_MASK 0xffffffff #elif DATA_BITS == 64 #define SUFFIX q #define DATA_TYPE uint64_t #define DATA_STYPE int64_t #define DATA_MASK 0xffffffffffffffffULL #else #error unhandled operand size #endif target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1) { int count, eflags; target_ulong src; target_long res; count = t1 & SHIFT1_MASK; #if DATA_BITS == 16 count = rclw_table[count]; #elif DATA_BITS == 8 count = rclb_table[count]; #endif if (count) { eflags = cc_table[CC_OP].compute_all(); t0 &= DATA_MASK; src = t0; res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1)); if (count > 1) res |= t0 >> (DATA_BITS + 1 - count); t0 = res; env->t3 = (eflags & ~(CC_C | CC_O)) | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | ((src >> (DATA_BITS - count)) & CC_C); } else { env->t3 = -1; } return t0; } target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1) { int count, eflags; target_ulong src; target_long res; count = t1 & SHIFT1_MASK; #if DATA_BITS == 16 count = rclw_table[count]; #elif DATA_BITS == 8 count = rclb_table[count]; #endif if (count) { eflags = cc_table[CC_OP].compute_all(); t0 &= DATA_MASK; src = t0; res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count)); if (count > 1) res |= t0 << (DATA_BITS + 1 - count); t0 = res; env->t3 = (eflags & ~(CC_C | CC_O)) | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | ((src >> (count - 1)) & CC_C); } else { env->t3 = -1; } return t0; } #undef DATA_BITS #undef SHIFT_MASK #undef SHIFT1_MASK #undef SIGN_MASK #undef DATA_TYPE #undef DATA_STYPE #undef DATA_MASK #undef SUFFIX Loading
target-i386/cpu.h +8 −0 Original line number Diff line number Diff line Loading @@ -476,6 +476,7 @@ typedef struct CPUX86State { /* temporaries if we cannot store them in host registers */ target_ulong t0, t1, t2; #endif target_ulong t3; /* standard registers */ target_ulong regs[CPU_NB_REGS]; Loading Loading @@ -727,6 +728,13 @@ static inline int cpu_mmu_index (CPUState *env) return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; } typedef struct CCTable { int (*compute_all)(void); /* return all the flags */ int (*compute_c)(void); /* return the C flag */ } CCTable; extern CCTable cc_table[]; #include "cpu-all.h" #include "svm.h" Loading
target-i386/exec.h +9 −7 Original line number Diff line number Diff line Loading @@ -98,13 +98,6 @@ extern int loglevel; #include "cpu.h" #include "exec-all.h" typedef struct CCTable { int (*compute_all)(void); /* return all the flags */ int (*compute_c)(void); /* return the C flag */ } CCTable; extern CCTable cc_table[]; 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_cr4(CPUX86State *env, uint32_t new_cr4); Loading @@ -129,6 +122,15 @@ void __hidden cpu_loop_exit(void); void OPPROTO op_movl_eflags_T0(void); void OPPROTO op_movl_T0_eflags(void); /* n must be a constant to be efficient */ static inline target_long lshift(target_long x, int n) { if (n >= 0) return x << n; else return x >> (-n); } #include "helper.h" static inline void svm_check_intercept(uint32_t type) Loading
target-i386/helper.c +19 −0 Original line number Diff line number Diff line Loading @@ -5220,3 +5220,22 @@ void helper_movq(uint64_t *d, uint64_t *s) #define SHIFT 1 #include "ops_sse.h" #define SHIFT 0 #include "helper_template.h" #undef SHIFT #define SHIFT 1 #include "helper_template.h" #undef SHIFT #define SHIFT 2 #include "helper_template.h" #undef SHIFT #ifdef TARGET_X86_64 #define SHIFT 3 #include "helper_template.h" #undef SHIFT #endif
target-i386/helper.h +11 −0 Original line number Diff line number Diff line Loading @@ -199,3 +199,14 @@ void TCG_HELPER_PROTO helper_movq(uint64_t *d, uint64_t *s); #define SHIFT 1 #include "ops_sse_header.h" target_ulong helper_rclb(target_ulong t0, target_ulong t1); target_ulong helper_rclw(target_ulong t0, target_ulong t1); target_ulong helper_rcll(target_ulong t0, target_ulong t1); target_ulong helper_rcrb(target_ulong t0, target_ulong t1); target_ulong helper_rcrw(target_ulong t0, target_ulong t1); target_ulong helper_rcrl(target_ulong t0, target_ulong t1); #ifdef TARGET_X86_64 target_ulong helper_rclq(target_ulong t0, target_ulong t1); target_ulong helper_rcrq(target_ulong t0, target_ulong t1); #endif
target-i386/helper_template.h 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * i386 helpers * * Copyright (c) 2008 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define DATA_BITS (1 << (3 + SHIFT)) #define SHIFT_MASK (DATA_BITS - 1) #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1)) #if DATA_BITS <= 32 #define SHIFT1_MASK 0x1f #else #define SHIFT1_MASK 0x3f #endif #if DATA_BITS == 8 #define SUFFIX b #define DATA_TYPE uint8_t #define DATA_STYPE int8_t #define DATA_MASK 0xff #elif DATA_BITS == 16 #define SUFFIX w #define DATA_TYPE uint16_t #define DATA_STYPE int16_t #define DATA_MASK 0xffff #elif DATA_BITS == 32 #define SUFFIX l #define DATA_TYPE uint32_t #define DATA_STYPE int32_t #define DATA_MASK 0xffffffff #elif DATA_BITS == 64 #define SUFFIX q #define DATA_TYPE uint64_t #define DATA_STYPE int64_t #define DATA_MASK 0xffffffffffffffffULL #else #error unhandled operand size #endif target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1) { int count, eflags; target_ulong src; target_long res; count = t1 & SHIFT1_MASK; #if DATA_BITS == 16 count = rclw_table[count]; #elif DATA_BITS == 8 count = rclb_table[count]; #endif if (count) { eflags = cc_table[CC_OP].compute_all(); t0 &= DATA_MASK; src = t0; res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1)); if (count > 1) res |= t0 >> (DATA_BITS + 1 - count); t0 = res; env->t3 = (eflags & ~(CC_C | CC_O)) | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | ((src >> (DATA_BITS - count)) & CC_C); } else { env->t3 = -1; } return t0; } target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1) { int count, eflags; target_ulong src; target_long res; count = t1 & SHIFT1_MASK; #if DATA_BITS == 16 count = rclw_table[count]; #elif DATA_BITS == 8 count = rclb_table[count]; #endif if (count) { eflags = cc_table[CC_OP].compute_all(); t0 &= DATA_MASK; src = t0; res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count)); if (count > 1) res |= t0 << (DATA_BITS + 1 - count); t0 = res; env->t3 = (eflags & ~(CC_C | CC_O)) | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | ((src >> (count - 1)) & CC_C); } else { env->t3 = -1; } return t0; } #undef DATA_BITS #undef SHIFT_MASK #undef SHIFT1_MASK #undef SIGN_MASK #undef DATA_TYPE #undef DATA_STYPE #undef DATA_MASK #undef SUFFIX