mirror of
https://github.com/qemu/qemu.git
synced 2025-01-21 13:03:26 +08:00
x86_64 fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1324 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
d057099aa8
commit
313132138a
@ -1012,7 +1012,8 @@ void helper_sysret(int dflag)
|
||||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
||||
DESC_W_MASK | DESC_A_MASK);
|
||||
load_eflags((uint32_t)(env->regs[11]), 0xffffffff);
|
||||
load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
|
||||
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
|
||||
cpu_x86_set_cpl(env, 3);
|
||||
} else {
|
||||
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
|
||||
@ -1209,7 +1210,7 @@ void helper_divl_EAX_T0(void)
|
||||
unsigned int den, q, r;
|
||||
uint64_t num;
|
||||
|
||||
num = EAX | ((uint64_t)EDX << 32);
|
||||
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
|
||||
den = T0;
|
||||
if (den == 0) {
|
||||
raise_exception(EXCP00_DIVZ);
|
||||
@ -1229,7 +1230,7 @@ void helper_idivl_EAX_T0(void)
|
||||
int den, q, r;
|
||||
int64_t num;
|
||||
|
||||
num = EAX | ((uint64_t)EDX << 32);
|
||||
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
|
||||
den = T0;
|
||||
if (den == 0) {
|
||||
raise_exception(EXCP00_DIVZ);
|
||||
@ -3003,7 +3004,7 @@ void helper_fxrstor(target_ulong ptr, int data64)
|
||||
}
|
||||
|
||||
if (env->cr[4] & CR4_OSFXSR_MASK) {
|
||||
/* XXX: finish it, endianness */
|
||||
/* XXX: finish it */
|
||||
env->mxcsr = ldl(ptr + 0x18);
|
||||
//ldl(ptr + 0x1c);
|
||||
nb_xmm_regs = 8 << data64;
|
||||
@ -3170,7 +3171,7 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
|
||||
}
|
||||
}
|
||||
|
||||
static void idiv64(uint64_t *plow, uint64_t *phigh, uint64_t b)
|
||||
static void idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
|
||||
{
|
||||
int sa, sb;
|
||||
sa = ((int64_t)*phigh < 0);
|
||||
@ -3182,7 +3183,7 @@ static void idiv64(uint64_t *plow, uint64_t *phigh, uint64_t b)
|
||||
div64(plow, phigh, b);
|
||||
if (sa ^ sb)
|
||||
*plow = - *plow;
|
||||
if (sb)
|
||||
if (sa)
|
||||
*phigh = - *phigh;
|
||||
}
|
||||
|
||||
|
@ -286,8 +286,8 @@ void OPPROTO op_imull_EAX_T0(void)
|
||||
{
|
||||
int64_t res;
|
||||
res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
|
||||
EAX = res;
|
||||
EDX = res >> 32;
|
||||
EAX = (uint32_t)(res);
|
||||
EDX = (uint32_t)(res >> 32);
|
||||
CC_DST = res;
|
||||
CC_SRC = (res != (int32_t)res);
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
T0 &= DATA_MASK;
|
||||
src = T0;
|
||||
res = (T0 << count) | ((eflags & CC_C) << (count - 1));
|
||||
res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
|
||||
if (count > 1)
|
||||
res |= T0 >> (DATA_BITS + 1 - count);
|
||||
T0 = res;
|
||||
@ -191,7 +191,7 @@ void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
T0 &= DATA_MASK;
|
||||
src = T0;
|
||||
res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
|
||||
res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
|
||||
if (count > 1)
|
||||
res |= T0 << (DATA_BITS + 1 - count);
|
||||
T0 = res;
|
||||
|
@ -600,12 +600,14 @@ static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {
|
||||
{\
|
||||
gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
|
||||
gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
|
||||
},\
|
||||
},\
|
||||
{\
|
||||
gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
|
||||
gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
|
||||
},\
|
||||
{\
|
||||
X86_64_DEF(gen_op_shldq ## SUFFIX ## _T0_T1_ ## op ## _cc,\
|
||||
gen_op_shrdq ## SUFFIX ## _T0_T1_ ## op ## _cc,)\
|
||||
},
|
||||
|
||||
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)
|
||||
sse_op2(op2_offset, op1_offset);
|
||||
break;
|
||||
case 0x050: /* movmskps */
|
||||
gen_op_movmskps(offsetof(CPUX86State,xmm_regs[reg]));
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
gen_op_mov_reg_T0[OT_LONG][rm]();
|
||||
gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
|
||||
gen_op_mov_reg_T0[OT_LONG][reg]();
|
||||
break;
|
||||
case 0x150: /* movmskpd */
|
||||
gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[reg]));
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
gen_op_mov_reg_T0[OT_LONG][rm]();
|
||||
gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
|
||||
gen_op_mov_reg_T0[OT_LONG][reg]();
|
||||
break;
|
||||
case 0x02a: /* cvtpi2ps */
|
||||
case 0x12a: /* cvtpi2pd */
|
||||
@ -2795,10 +2797,22 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
|
||||
case 0x22d: /* cvtss2si */
|
||||
case 0x32d: /* cvtsd2si */
|
||||
ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
|
||||
op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
|
||||
if (mod != 3) {
|
||||
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
||||
if ((b >> 8) & 1) {
|
||||
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
|
||||
} else {
|
||||
gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
|
||||
gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
|
||||
}
|
||||
op2_offset = offsetof(CPUX86State,xmm_t0);
|
||||
} else {
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
|
||||
}
|
||||
sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
|
||||
(b & 1) * 4](op1_offset);
|
||||
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
|
||||
(b & 1) * 4](op2_offset);
|
||||
gen_op_mov_reg_T0[ot][reg]();
|
||||
break;
|
||||
case 0xc4: /* pinsrw */
|
||||
case 0x1c4:
|
||||
|
Loading…
Reference in New Issue
Block a user