Commit a8ede8ba8be076ae56b7c9ce9b4f2a115589543a
1 parent
826461bb
div64 fix - raise_interrupt() fix - SSE fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1202 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
23 additions
and
28 deletions
target-i386/exec.h
... | ... | @@ -176,17 +176,13 @@ void do_interrupt(int intno, int is_int, int error_code, |
176 | 176 | void do_interrupt_user(int intno, int is_int, int error_code, |
177 | 177 | target_ulong next_eip); |
178 | 178 | void raise_interrupt(int intno, int is_int, int error_code, |
179 | - unsigned int next_eip); | |
179 | + int next_eip_addend); | |
180 | 180 | void raise_exception_err(int exception_index, int error_code); |
181 | 181 | void raise_exception(int exception_index); |
182 | 182 | void __hidden cpu_loop_exit(void); |
183 | 183 | |
184 | 184 | void OPPROTO op_movl_eflags_T0(void); |
185 | 185 | void OPPROTO op_movl_T0_eflags(void); |
186 | -void raise_interrupt(int intno, int is_int, int error_code, | |
187 | - unsigned int next_eip); | |
188 | -void raise_exception_err(int exception_index, int error_code); | |
189 | -void raise_exception(int exception_index); | |
190 | 186 | void helper_divl_EAX_T0(void); |
191 | 187 | void helper_idivl_EAX_T0(void); |
192 | 188 | void helper_mulq_EAX_T0(void); | ... | ... |
target-i386/helper.c
... | ... | @@ -1157,12 +1157,12 @@ void do_interrupt(int intno, int is_int, int error_code, |
1157 | 1157 | * is_int is TRUE. |
1158 | 1158 | */ |
1159 | 1159 | void raise_interrupt(int intno, int is_int, int error_code, |
1160 | - unsigned int next_eip) | |
1160 | + int next_eip_addend) | |
1161 | 1161 | { |
1162 | 1162 | env->exception_index = intno; |
1163 | 1163 | env->error_code = error_code; |
1164 | 1164 | env->exception_is_int = is_int; |
1165 | - env->exception_next_eip = next_eip; | |
1165 | + env->exception_next_eip = env->eip + next_eip_addend; | |
1166 | 1166 | cpu_loop_exit(); |
1167 | 1167 | } |
1168 | 1168 | |
... | ... | @@ -2929,14 +2929,14 @@ void helper_fxsave(target_ulong ptr, int data64) |
2929 | 2929 | } |
2930 | 2930 | |
2931 | 2931 | if (env->cr[4] & CR4_OSFXSR_MASK) { |
2932 | - /* XXX: finish it, endianness */ | |
2932 | + /* XXX: finish it */ | |
2933 | 2933 | stl(ptr + 0x18, 0); /* mxcsr */ |
2934 | 2934 | stl(ptr + 0x1c, 0); /* mxcsr_mask */ |
2935 | 2935 | nb_xmm_regs = 8 << data64; |
2936 | 2936 | addr = ptr + 0xa0; |
2937 | 2937 | for(i = 0; i < nb_xmm_regs; i++) { |
2938 | - stq(addr, env->xmm_regs[i].u.q[0]); | |
2939 | - stq(addr, env->xmm_regs[i].u.q[1]); | |
2938 | + stq(addr, env->xmm_regs[i].XMM_Q(0)); | |
2939 | + stq(addr + 8, env->xmm_regs[i].XMM_Q(1)); | |
2940 | 2940 | addr += 16; |
2941 | 2941 | } |
2942 | 2942 | } |
... | ... | @@ -2972,8 +2972,8 @@ void helper_fxrstor(target_ulong ptr, int data64) |
2972 | 2972 | nb_xmm_regs = 8 << data64; |
2973 | 2973 | addr = ptr + 0xa0; |
2974 | 2974 | for(i = 0; i < nb_xmm_regs; i++) { |
2975 | - env->xmm_regs[i].u.q[0] = ldq(addr); | |
2976 | - env->xmm_regs[i].u.q[1] = ldq(addr); | |
2975 | + env->xmm_regs[i].XMM_Q(0) = ldq(addr); | |
2976 | + env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8); | |
2977 | 2977 | addr += 16; |
2978 | 2978 | } |
2979 | 2979 | } |
... | ... | @@ -3099,6 +3099,7 @@ static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) |
3099 | 3099 | } |
3100 | 3100 | } |
3101 | 3101 | |
3102 | +/* XXX: overflow support */ | |
3102 | 3103 | static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) |
3103 | 3104 | { |
3104 | 3105 | uint64_t q, r, a1, a0; |
... | ... | @@ -3114,16 +3115,16 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) |
3114 | 3115 | } else { |
3115 | 3116 | /* XXX: use a better algorithm */ |
3116 | 3117 | for(i = 0; i < 64; i++) { |
3118 | + a1 = (a1 << 1) | (a0 >> 63); | |
3117 | 3119 | if (a1 >= b) { |
3118 | 3120 | a1 -= b; |
3119 | 3121 | qb = 1; |
3120 | 3122 | } else { |
3121 | 3123 | qb = 0; |
3122 | 3124 | } |
3123 | - a1 = (a1 << 1) | (a0 >> 63); | |
3124 | 3125 | a0 = (a0 << 1) | qb; |
3125 | 3126 | } |
3126 | -#if defined(DEBUG_MULDIV) || 1 | |
3127 | +#if defined(DEBUG_MULDIV) | |
3127 | 3128 | printf("div: 0x%016llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n", |
3128 | 3129 | *phigh, *plow, b, a0, a1); |
3129 | 3130 | #endif |
... | ... | @@ -3167,7 +3168,7 @@ void helper_imulq_EAX_T0(void) |
3167 | 3168 | EAX = r0; |
3168 | 3169 | EDX = r1; |
3169 | 3170 | CC_DST = r0; |
3170 | - CC_SRC = (r1 != (r0 >> 63)); | |
3171 | + CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); | |
3171 | 3172 | } |
3172 | 3173 | |
3173 | 3174 | void helper_imulq_T0_T1(void) | ... | ... |
target-i386/op.c
... | ... | @@ -611,11 +611,10 @@ void OPPROTO op_debug(void) |
611 | 611 | |
612 | 612 | void OPPROTO op_raise_interrupt(void) |
613 | 613 | { |
614 | - int intno; | |
615 | - unsigned int next_eip; | |
614 | + int intno, next_eip_addend; | |
616 | 615 | intno = PARAM1; |
617 | - next_eip = PARAM2; | |
618 | - raise_interrupt(intno, 1, 0, next_eip); | |
616 | + next_eip_addend = PARAM2; | |
617 | + raise_interrupt(intno, 1, 0, next_eip_addend); | |
619 | 618 | } |
620 | 619 | |
621 | 620 | void OPPROTO op_raise_exception(void) | ... | ... |
target-i386/ops_mem.h
... | ... | @@ -85,18 +85,16 @@ void OPPROTO glue(glue(op_ldo, MEMSUFFIX), _env_A0)(void) |
85 | 85 | { |
86 | 86 | XMMReg *p; |
87 | 87 | p = (XMMReg *)((char *)env + PARAM1); |
88 | - /* XXX: host endianness ? */ | |
89 | - p->u.q[0] = glue(ldq, MEMSUFFIX)(A0); | |
90 | - p->u.q[1] = glue(ldq, MEMSUFFIX)(A0 + 8); | |
88 | + p->XMM_Q(0) = glue(ldq, MEMSUFFIX)(A0); | |
89 | + p->XMM_Q(1) = glue(ldq, MEMSUFFIX)(A0 + 8); | |
91 | 90 | } |
92 | 91 | |
93 | 92 | void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void) |
94 | 93 | { |
95 | 94 | XMMReg *p; |
96 | 95 | p = (XMMReg *)((char *)env + PARAM1); |
97 | - /* XXX: host endianness ? */ | |
98 | - glue(stq, MEMSUFFIX)(A0, p->u.q[0]); | |
99 | - glue(stq, MEMSUFFIX)(A0 + 8, p->u.q[1]); | |
96 | + glue(stq, MEMSUFFIX)(A0, p->XMM_Q(0)); | |
97 | + glue(stq, MEMSUFFIX)(A0 + 8, p->XMM_Q(1)); | |
100 | 98 | } |
101 | 99 | |
102 | 100 | #ifdef TARGET_X86_64 | ... | ... |
target-i386/translate.c
... | ... | @@ -2119,7 +2119,7 @@ static void gen_interrupt(DisasContext *s, int intno, |
2119 | 2119 | if (s->cc_op != CC_OP_DYNAMIC) |
2120 | 2120 | gen_op_set_cc_op(s->cc_op); |
2121 | 2121 | gen_jmp_im(cur_eip); |
2122 | - gen_op_raise_interrupt(intno, next_eip); | |
2122 | + gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip)); | |
2123 | 2123 | s->is_jmp = 3; |
2124 | 2124 | } |
2125 | 2125 | |
... | ... | @@ -4452,7 +4452,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4452 | 4452 | goto illegal_op; |
4453 | 4453 | if (s->cc_op != CC_OP_DYNAMIC) |
4454 | 4454 | gen_op_set_cc_op(s->cc_op); |
4455 | - gen_op_into(s->pc - s->cs_base); | |
4455 | + gen_jmp_im(pc_start - s->cs_base); | |
4456 | + gen_op_into(s->pc - pc_start); | |
4456 | 4457 | break; |
4457 | 4458 | case 0xf1: /* icebp (undocumented, exits to external debugger) */ |
4458 | 4459 | #if 0 |
... | ... | @@ -4826,7 +4827,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4826 | 4827 | /* nothing to do */ |
4827 | 4828 | } |
4828 | 4829 | break; |
4829 | - case 0x1ae: /* sfence */ | |
4830 | + case 0x1ae: | |
4830 | 4831 | modrm = ldub_code(s->pc++); |
4831 | 4832 | mod = (modrm >> 6) & 3; |
4832 | 4833 | op = (modrm >> 3) & 7; | ... | ... |