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,17 +176,13 @@ void do_interrupt(int intno, int is_int, int error_code, | ||
176 | void do_interrupt_user(int intno, int is_int, int error_code, | 176 | void do_interrupt_user(int intno, int is_int, int error_code, |
177 | target_ulong next_eip); | 177 | target_ulong next_eip); |
178 | void raise_interrupt(int intno, int is_int, int error_code, | 178 | void raise_interrupt(int intno, int is_int, int error_code, |
179 | - unsigned int next_eip); | 179 | + int next_eip_addend); |
180 | void raise_exception_err(int exception_index, int error_code); | 180 | void raise_exception_err(int exception_index, int error_code); |
181 | void raise_exception(int exception_index); | 181 | void raise_exception(int exception_index); |
182 | void __hidden cpu_loop_exit(void); | 182 | void __hidden cpu_loop_exit(void); |
183 | 183 | ||
184 | void OPPROTO op_movl_eflags_T0(void); | 184 | void OPPROTO op_movl_eflags_T0(void); |
185 | void OPPROTO op_movl_T0_eflags(void); | 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 | void helper_divl_EAX_T0(void); | 186 | void helper_divl_EAX_T0(void); |
191 | void helper_idivl_EAX_T0(void); | 187 | void helper_idivl_EAX_T0(void); |
192 | void helper_mulq_EAX_T0(void); | 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,12 +1157,12 @@ void do_interrupt(int intno, int is_int, int error_code, | ||
1157 | * is_int is TRUE. | 1157 | * is_int is TRUE. |
1158 | */ | 1158 | */ |
1159 | void raise_interrupt(int intno, int is_int, int error_code, | 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 | env->exception_index = intno; | 1162 | env->exception_index = intno; |
1163 | env->error_code = error_code; | 1163 | env->error_code = error_code; |
1164 | env->exception_is_int = is_int; | 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 | cpu_loop_exit(); | 1166 | cpu_loop_exit(); |
1167 | } | 1167 | } |
1168 | 1168 | ||
@@ -2929,14 +2929,14 @@ void helper_fxsave(target_ulong ptr, int data64) | @@ -2929,14 +2929,14 @@ void helper_fxsave(target_ulong ptr, int data64) | ||
2929 | } | 2929 | } |
2930 | 2930 | ||
2931 | if (env->cr[4] & CR4_OSFXSR_MASK) { | 2931 | if (env->cr[4] & CR4_OSFXSR_MASK) { |
2932 | - /* XXX: finish it, endianness */ | 2932 | + /* XXX: finish it */ |
2933 | stl(ptr + 0x18, 0); /* mxcsr */ | 2933 | stl(ptr + 0x18, 0); /* mxcsr */ |
2934 | stl(ptr + 0x1c, 0); /* mxcsr_mask */ | 2934 | stl(ptr + 0x1c, 0); /* mxcsr_mask */ |
2935 | nb_xmm_regs = 8 << data64; | 2935 | nb_xmm_regs = 8 << data64; |
2936 | addr = ptr + 0xa0; | 2936 | addr = ptr + 0xa0; |
2937 | for(i = 0; i < nb_xmm_regs; i++) { | 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 | addr += 16; | 2940 | addr += 16; |
2941 | } | 2941 | } |
2942 | } | 2942 | } |
@@ -2972,8 +2972,8 @@ void helper_fxrstor(target_ulong ptr, int data64) | @@ -2972,8 +2972,8 @@ void helper_fxrstor(target_ulong ptr, int data64) | ||
2972 | nb_xmm_regs = 8 << data64; | 2972 | nb_xmm_regs = 8 << data64; |
2973 | addr = ptr + 0xa0; | 2973 | addr = ptr + 0xa0; |
2974 | for(i = 0; i < nb_xmm_regs; i++) { | 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 | addr += 16; | 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,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 | static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) | 3103 | static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) |
3103 | { | 3104 | { |
3104 | uint64_t q, r, a1, a0; | 3105 | uint64_t q, r, a1, a0; |
@@ -3114,16 +3115,16 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) | @@ -3114,16 +3115,16 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) | ||
3114 | } else { | 3115 | } else { |
3115 | /* XXX: use a better algorithm */ | 3116 | /* XXX: use a better algorithm */ |
3116 | for(i = 0; i < 64; i++) { | 3117 | for(i = 0; i < 64; i++) { |
3118 | + a1 = (a1 << 1) | (a0 >> 63); | ||
3117 | if (a1 >= b) { | 3119 | if (a1 >= b) { |
3118 | a1 -= b; | 3120 | a1 -= b; |
3119 | qb = 1; | 3121 | qb = 1; |
3120 | } else { | 3122 | } else { |
3121 | qb = 0; | 3123 | qb = 0; |
3122 | } | 3124 | } |
3123 | - a1 = (a1 << 1) | (a0 >> 63); | ||
3124 | a0 = (a0 << 1) | qb; | 3125 | a0 = (a0 << 1) | qb; |
3125 | } | 3126 | } |
3126 | -#if defined(DEBUG_MULDIV) || 1 | 3127 | +#if defined(DEBUG_MULDIV) |
3127 | printf("div: 0x%016llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n", | 3128 | printf("div: 0x%016llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n", |
3128 | *phigh, *plow, b, a0, a1); | 3129 | *phigh, *plow, b, a0, a1); |
3129 | #endif | 3130 | #endif |
@@ -3167,7 +3168,7 @@ void helper_imulq_EAX_T0(void) | @@ -3167,7 +3168,7 @@ void helper_imulq_EAX_T0(void) | ||
3167 | EAX = r0; | 3168 | EAX = r0; |
3168 | EDX = r1; | 3169 | EDX = r1; |
3169 | CC_DST = r0; | 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 | void helper_imulq_T0_T1(void) | 3174 | void helper_imulq_T0_T1(void) |
target-i386/op.c
@@ -611,11 +611,10 @@ void OPPROTO op_debug(void) | @@ -611,11 +611,10 @@ void OPPROTO op_debug(void) | ||
611 | 611 | ||
612 | void OPPROTO op_raise_interrupt(void) | 612 | void OPPROTO op_raise_interrupt(void) |
613 | { | 613 | { |
614 | - int intno; | ||
615 | - unsigned int next_eip; | 614 | + int intno, next_eip_addend; |
616 | intno = PARAM1; | 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 | void OPPROTO op_raise_exception(void) | 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,18 +85,16 @@ void OPPROTO glue(glue(op_ldo, MEMSUFFIX), _env_A0)(void) | ||
85 | { | 85 | { |
86 | XMMReg *p; | 86 | XMMReg *p; |
87 | p = (XMMReg *)((char *)env + PARAM1); | 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 | void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void) | 92 | void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void) |
94 | { | 93 | { |
95 | XMMReg *p; | 94 | XMMReg *p; |
96 | p = (XMMReg *)((char *)env + PARAM1); | 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 | #ifdef TARGET_X86_64 | 100 | #ifdef TARGET_X86_64 |
target-i386/translate.c
@@ -2119,7 +2119,7 @@ static void gen_interrupt(DisasContext *s, int intno, | @@ -2119,7 +2119,7 @@ static void gen_interrupt(DisasContext *s, int intno, | ||
2119 | if (s->cc_op != CC_OP_DYNAMIC) | 2119 | if (s->cc_op != CC_OP_DYNAMIC) |
2120 | gen_op_set_cc_op(s->cc_op); | 2120 | gen_op_set_cc_op(s->cc_op); |
2121 | gen_jmp_im(cur_eip); | 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 | s->is_jmp = 3; | 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,7 +4452,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
4452 | goto illegal_op; | 4452 | goto illegal_op; |
4453 | if (s->cc_op != CC_OP_DYNAMIC) | 4453 | if (s->cc_op != CC_OP_DYNAMIC) |
4454 | gen_op_set_cc_op(s->cc_op); | 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 | break; | 4457 | break; |
4457 | case 0xf1: /* icebp (undocumented, exits to external debugger) */ | 4458 | case 0xf1: /* icebp (undocumented, exits to external debugger) */ |
4458 | #if 0 | 4459 | #if 0 |
@@ -4826,7 +4827,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -4826,7 +4827,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
4826 | /* nothing to do */ | 4827 | /* nothing to do */ |
4827 | } | 4828 | } |
4828 | break; | 4829 | break; |
4829 | - case 0x1ae: /* sfence */ | 4830 | + case 0x1ae: |
4830 | modrm = ldub_code(s->pc++); | 4831 | modrm = ldub_code(s->pc++); |
4831 | mod = (modrm >> 6) & 3; | 4832 | mod = (modrm >> 6) & 3; |
4832 | op = (modrm >> 3) & 7; | 4833 | op = (modrm >> 3) & 7; |