Commit 313132138a91f90f270510a06db549c3fd7466bf

Authored by bellard
1 parent d057099a

x86_64 fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1324 c046a42c-6fe2-441c-8c8c-71466251a162
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, &reg_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: