Commit 313132138a91f90f270510a06db549c3fd7466bf
1 parent
d057099a
x86_64 fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1324 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
33 additions
and
18 deletions
target-i386/helper.c
| @@ -1012,7 +1012,8 @@ void helper_sysret(int dflag) | @@ -1012,7 +1012,8 @@ void helper_sysret(int dflag) | ||
| 1012 | DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | | 1012 | DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | |
| 1013 | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | | 1013 | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | |
| 1014 | DESC_W_MASK | DESC_A_MASK); | 1014 | DESC_W_MASK | DESC_A_MASK); |
| 1015 | - load_eflags((uint32_t)(env->regs[11]), 0xffffffff); | 1015 | + load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK | |
| 1016 | + IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK); | ||
| 1016 | cpu_x86_set_cpl(env, 3); | 1017 | cpu_x86_set_cpl(env, 3); |
| 1017 | } else { | 1018 | } else { |
| 1018 | cpu_x86_load_seg_cache(env, R_CS, selector | 3, | 1019 | cpu_x86_load_seg_cache(env, R_CS, selector | 3, |
| @@ -1209,7 +1210,7 @@ void helper_divl_EAX_T0(void) | @@ -1209,7 +1210,7 @@ void helper_divl_EAX_T0(void) | ||
| 1209 | unsigned int den, q, r; | 1210 | unsigned int den, q, r; |
| 1210 | uint64_t num; | 1211 | uint64_t num; |
| 1211 | 1212 | ||
| 1212 | - num = EAX | ((uint64_t)EDX << 32); | 1213 | + num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); |
| 1213 | den = T0; | 1214 | den = T0; |
| 1214 | if (den == 0) { | 1215 | if (den == 0) { |
| 1215 | raise_exception(EXCP00_DIVZ); | 1216 | raise_exception(EXCP00_DIVZ); |
| @@ -1229,7 +1230,7 @@ void helper_idivl_EAX_T0(void) | @@ -1229,7 +1230,7 @@ void helper_idivl_EAX_T0(void) | ||
| 1229 | int den, q, r; | 1230 | int den, q, r; |
| 1230 | int64_t num; | 1231 | int64_t num; |
| 1231 | 1232 | ||
| 1232 | - num = EAX | ((uint64_t)EDX << 32); | 1233 | + num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); |
| 1233 | den = T0; | 1234 | den = T0; |
| 1234 | if (den == 0) { | 1235 | if (den == 0) { |
| 1235 | raise_exception(EXCP00_DIVZ); | 1236 | raise_exception(EXCP00_DIVZ); |
| @@ -3003,7 +3004,7 @@ void helper_fxrstor(target_ulong ptr, int data64) | @@ -3003,7 +3004,7 @@ void helper_fxrstor(target_ulong ptr, int data64) | ||
| 3003 | } | 3004 | } |
| 3004 | 3005 | ||
| 3005 | if (env->cr[4] & CR4_OSFXSR_MASK) { | 3006 | if (env->cr[4] & CR4_OSFXSR_MASK) { |
| 3006 | - /* XXX: finish it, endianness */ | 3007 | + /* XXX: finish it */ |
| 3007 | env->mxcsr = ldl(ptr + 0x18); | 3008 | env->mxcsr = ldl(ptr + 0x18); |
| 3008 | //ldl(ptr + 0x1c); | 3009 | //ldl(ptr + 0x1c); |
| 3009 | nb_xmm_regs = 8 << data64; | 3010 | nb_xmm_regs = 8 << data64; |
| @@ -3170,7 +3171,7 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) | @@ -3170,7 +3171,7 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) | ||
| 3170 | } | 3171 | } |
| 3171 | } | 3172 | } |
| 3172 | 3173 | ||
| 3173 | -static void idiv64(uint64_t *plow, uint64_t *phigh, uint64_t b) | 3174 | +static void idiv64(uint64_t *plow, uint64_t *phigh, int64_t b) |
| 3174 | { | 3175 | { |
| 3175 | int sa, sb; | 3176 | int sa, sb; |
| 3176 | sa = ((int64_t)*phigh < 0); | 3177 | sa = ((int64_t)*phigh < 0); |
| @@ -3182,7 +3183,7 @@ static void idiv64(uint64_t *plow, uint64_t *phigh, uint64_t b) | @@ -3182,7 +3183,7 @@ static void idiv64(uint64_t *plow, uint64_t *phigh, uint64_t b) | ||
| 3182 | div64(plow, phigh, b); | 3183 | div64(plow, phigh, b); |
| 3183 | if (sa ^ sb) | 3184 | if (sa ^ sb) |
| 3184 | *plow = - *plow; | 3185 | *plow = - *plow; |
| 3185 | - if (sb) | 3186 | + if (sa) |
| 3186 | *phigh = - *phigh; | 3187 | *phigh = - *phigh; |
| 3187 | } | 3188 | } |
| 3188 | 3189 |
target-i386/op.c
| @@ -286,8 +286,8 @@ void OPPROTO op_imull_EAX_T0(void) | @@ -286,8 +286,8 @@ void OPPROTO op_imull_EAX_T0(void) | ||
| 286 | { | 286 | { |
| 287 | int64_t res; | 287 | int64_t res; |
| 288 | res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0); | 288 | res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0); |
| 289 | - EAX = res; | ||
| 290 | - EDX = res >> 32; | 289 | + EAX = (uint32_t)(res); |
| 290 | + EDX = (uint32_t)(res >> 32); | ||
| 291 | CC_DST = res; | 291 | CC_DST = res; |
| 292 | CC_SRC = (res != (int32_t)res); | 292 | CC_SRC = (res != (int32_t)res); |
| 293 | } | 293 | } |
target-i386/ops_template_mem.h
| @@ -160,7 +160,7 @@ void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void) | @@ -160,7 +160,7 @@ void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void) | ||
| 160 | eflags = cc_table[CC_OP].compute_all(); | 160 | eflags = cc_table[CC_OP].compute_all(); |
| 161 | T0 &= DATA_MASK; | 161 | T0 &= DATA_MASK; |
| 162 | src = T0; | 162 | src = T0; |
| 163 | - res = (T0 << count) | ((eflags & CC_C) << (count - 1)); | 163 | + res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1)); |
| 164 | if (count > 1) | 164 | if (count > 1) |
| 165 | res |= T0 >> (DATA_BITS + 1 - count); | 165 | res |= T0 >> (DATA_BITS + 1 - count); |
| 166 | T0 = res; | 166 | T0 = res; |
| @@ -191,7 +191,7 @@ void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void) | @@ -191,7 +191,7 @@ void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void) | ||
| 191 | eflags = cc_table[CC_OP].compute_all(); | 191 | eflags = cc_table[CC_OP].compute_all(); |
| 192 | T0 &= DATA_MASK; | 192 | T0 &= DATA_MASK; |
| 193 | src = T0; | 193 | src = T0; |
| 194 | - res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count)); | 194 | + res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count)); |
| 195 | if (count > 1) | 195 | if (count > 1) |
| 196 | res |= T0 << (DATA_BITS + 1 - count); | 196 | res |= T0 << (DATA_BITS + 1 - count); |
| 197 | T0 = res; | 197 | T0 = res; |
target-i386/translate.c
| @@ -600,12 +600,14 @@ static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = { | @@ -600,12 +600,14 @@ static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = { | ||
| 600 | {\ | 600 | {\ |
| 601 | gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | 601 | gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\ |
| 602 | gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | 602 | gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\ |
| 603 | - },\ | 603 | + },\ |
| 604 | {\ | 604 | {\ |
| 605 | gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | 605 | gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\ |
| 606 | gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | 606 | gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\ |
| 607 | },\ | 607 | },\ |
| 608 | {\ | 608 | {\ |
| 609 | +X86_64_DEF(gen_op_shldq ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | ||
| 610 | + gen_op_shrdq ## SUFFIX ## _T0_T1_ ## op ## _cc,)\ | ||
| 609 | }, | 611 | }, |
| 610 | 612 | ||
| 611 | static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = { | 613 | static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = { |
| @@ -2723,14 +2725,14 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) | @@ -2723,14 +2725,14 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) | ||
| 2723 | sse_op2(op2_offset, op1_offset); | 2725 | sse_op2(op2_offset, op1_offset); |
| 2724 | break; | 2726 | break; |
| 2725 | case 0x050: /* movmskps */ | 2727 | case 0x050: /* movmskps */ |
| 2726 | - gen_op_movmskps(offsetof(CPUX86State,xmm_regs[reg])); | ||
| 2727 | rm = (modrm & 7) | REX_B(s); | 2728 | rm = (modrm & 7) | REX_B(s); |
| 2728 | - gen_op_mov_reg_T0[OT_LONG][rm](); | 2729 | + gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm])); |
| 2730 | + gen_op_mov_reg_T0[OT_LONG][reg](); | ||
| 2729 | break; | 2731 | break; |
| 2730 | case 0x150: /* movmskpd */ | 2732 | case 0x150: /* movmskpd */ |
| 2731 | - gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[reg])); | ||
| 2732 | rm = (modrm & 7) | REX_B(s); | 2733 | rm = (modrm & 7) | REX_B(s); |
| 2733 | - gen_op_mov_reg_T0[OT_LONG][rm](); | 2734 | + gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm])); |
| 2735 | + gen_op_mov_reg_T0[OT_LONG][reg](); | ||
| 2734 | break; | 2736 | break; |
| 2735 | case 0x02a: /* cvtpi2ps */ | 2737 | case 0x02a: /* cvtpi2ps */ |
| 2736 | case 0x12a: /* cvtpi2pd */ | 2738 | case 0x12a: /* cvtpi2pd */ |
| @@ -2795,10 +2797,22 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) | @@ -2795,10 +2797,22 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) | ||
| 2795 | case 0x22d: /* cvtss2si */ | 2797 | case 0x22d: /* cvtss2si */ |
| 2796 | case 0x32d: /* cvtsd2si */ | 2798 | case 0x32d: /* cvtsd2si */ |
| 2797 | ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; | 2799 | ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; |
| 2798 | - op1_offset = offsetof(CPUX86State,xmm_regs[reg]); | 2800 | + if (mod != 3) { |
| 2801 | + gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | ||
| 2802 | + if ((b >> 8) & 1) { | ||
| 2803 | + gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0))); | ||
| 2804 | + } else { | ||
| 2805 | + gen_op_ld_T0_A0[OT_LONG + s->mem_index](); | ||
| 2806 | + gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0))); | ||
| 2807 | + } | ||
| 2808 | + op2_offset = offsetof(CPUX86State,xmm_t0); | ||
| 2809 | + } else { | ||
| 2810 | + rm = (modrm & 7) | REX_B(s); | ||
| 2811 | + op2_offset = offsetof(CPUX86State,xmm_regs[rm]); | ||
| 2812 | + } | ||
| 2799 | sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 + | 2813 | sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 + |
| 2800 | - (b & 1) * 4](op1_offset); | ||
| 2801 | - gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); | 2814 | + (b & 1) * 4](op2_offset); |
| 2815 | + gen_op_mov_reg_T0[ot][reg](); | ||
| 2802 | break; | 2816 | break; |
| 2803 | case 0xc4: /* pinsrw */ | 2817 | case 0xc4: /* pinsrw */ |
| 2804 | case 0x1c4: | 2818 | case 0x1c4: |