Commit eb44b959de4a888d0441f05483ced589b64b4d1f
1 parent
330c483b
target-ppc: update nip before calling an helper in FP instructions
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6045 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
32 additions
and
2 deletions
target-ppc/translate.c
... | ... | @@ -2072,6 +2072,8 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \ |
2072 | 2072 | gen_exception(ctx, POWERPC_EXCP_FPU); \ |
2073 | 2073 | return; \ |
2074 | 2074 | } \ |
2075 | + /* NIP cannot be restored if the memory exception comes from an helper */ \ | |
2076 | + gen_update_nip(ctx, ctx->nip - 4); \ | |
2075 | 2077 | gen_reset_fpstatus(); \ |
2076 | 2078 | gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)], \ |
2077 | 2079 | cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \ |
... | ... | @@ -2093,6 +2095,8 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \ |
2093 | 2095 | gen_exception(ctx, POWERPC_EXCP_FPU); \ |
2094 | 2096 | return; \ |
2095 | 2097 | } \ |
2098 | + /* NIP cannot be restored if the memory exception comes from an helper */ \ | |
2099 | + gen_update_nip(ctx, ctx->nip - 4); \ | |
2096 | 2100 | gen_reset_fpstatus(); \ |
2097 | 2101 | gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)], \ |
2098 | 2102 | cpu_fpr[rB(ctx->opcode)]); \ |
... | ... | @@ -2113,6 +2117,8 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \ |
2113 | 2117 | gen_exception(ctx, POWERPC_EXCP_FPU); \ |
2114 | 2118 | return; \ |
2115 | 2119 | } \ |
2120 | + /* NIP cannot be restored if the memory exception comes from an helper */ \ | |
2121 | + gen_update_nip(ctx, ctx->nip - 4); \ | |
2116 | 2122 | gen_reset_fpstatus(); \ |
2117 | 2123 | gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)], \ |
2118 | 2124 | cpu_fpr[rC(ctx->opcode)]); \ |
... | ... | @@ -2133,6 +2139,8 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \ |
2133 | 2139 | gen_exception(ctx, POWERPC_EXCP_FPU); \ |
2134 | 2140 | return; \ |
2135 | 2141 | } \ |
2142 | + /* NIP cannot be restored if the memory exception comes from an helper */ \ | |
2143 | + gen_update_nip(ctx, ctx->nip - 4); \ | |
2136 | 2144 | gen_reset_fpstatus(); \ |
2137 | 2145 | gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \ |
2138 | 2146 | gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], \ |
... | ... | @@ -2146,6 +2154,8 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \ |
2146 | 2154 | gen_exception(ctx, POWERPC_EXCP_FPU); \ |
2147 | 2155 | return; \ |
2148 | 2156 | } \ |
2157 | + /* NIP cannot be restored if the memory exception comes from an helper */ \ | |
2158 | + gen_update_nip(ctx, ctx->nip - 4); \ | |
2149 | 2159 | gen_reset_fpstatus(); \ |
2150 | 2160 | gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \ |
2151 | 2161 | gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], \ |
... | ... | @@ -2175,6 +2185,8 @@ GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES) |
2175 | 2185 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2176 | 2186 | return; |
2177 | 2187 | } |
2188 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2189 | + gen_update_nip(ctx, ctx->nip - 4); | |
2178 | 2190 | gen_reset_fpstatus(); |
2179 | 2191 | gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); |
2180 | 2192 | gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]); |
... | ... | @@ -2193,6 +2205,8 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) |
2193 | 2205 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2194 | 2206 | return; |
2195 | 2207 | } |
2208 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2209 | + gen_update_nip(ctx, ctx->nip - 4); | |
2196 | 2210 | gen_reset_fpstatus(); |
2197 | 2211 | gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); |
2198 | 2212 | gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0); |
... | ... | @@ -2204,6 +2218,8 @@ GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) |
2204 | 2218 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2205 | 2219 | return; |
2206 | 2220 | } |
2221 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2222 | + gen_update_nip(ctx, ctx->nip - 4); | |
2207 | 2223 | gen_reset_fpstatus(); |
2208 | 2224 | gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); |
2209 | 2225 | gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]); |
... | ... | @@ -2254,6 +2270,8 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) |
2254 | 2270 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2255 | 2271 | return; |
2256 | 2272 | } |
2273 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2274 | + gen_update_nip(ctx, ctx->nip - 4); | |
2257 | 2275 | gen_reset_fpstatus(); |
2258 | 2276 | crf = tcg_const_i32(crfD(ctx->opcode)); |
2259 | 2277 | gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf); |
... | ... | @@ -2269,6 +2287,8 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) |
2269 | 2287 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2270 | 2288 | return; |
2271 | 2289 | } |
2290 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2291 | + gen_update_nip(ctx, ctx->nip - 4); | |
2272 | 2292 | gen_reset_fpstatus(); |
2273 | 2293 | crf = tcg_const_i32(crfD(ctx->opcode)); |
2274 | 2294 | gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf); |
... | ... | @@ -2340,7 +2360,10 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) |
2340 | 2360 | crb = 31 - crbD(ctx->opcode); |
2341 | 2361 | gen_reset_fpstatus(); |
2342 | 2362 | if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) { |
2343 | - TCGv_i32 t0 = tcg_const_i32(crb); | |
2363 | + TCGv_i32 t0; | |
2364 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2365 | + gen_update_nip(ctx, ctx->nip - 4); | |
2366 | + t0 = tcg_const_i32(crb); | |
2344 | 2367 | gen_helper_fpscr_clrbit(t0); |
2345 | 2368 | tcg_temp_free_i32(t0); |
2346 | 2369 | } |
... | ... | @@ -2362,7 +2385,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) |
2362 | 2385 | gen_reset_fpstatus(); |
2363 | 2386 | /* XXX: we pretend we can only do IEEE floating-point computations */ |
2364 | 2387 | if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) { |
2365 | - TCGv_i32 t0 = tcg_const_i32(crb); | |
2388 | + TCGv_i32 t0; | |
2389 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2390 | + gen_update_nip(ctx, ctx->nip - 4); | |
2391 | + t0 = tcg_const_i32(crb); | |
2366 | 2392 | gen_helper_fpscr_setbit(t0); |
2367 | 2393 | tcg_temp_free_i32(t0); |
2368 | 2394 | } |
... | ... | @@ -2382,6 +2408,8 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) |
2382 | 2408 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2383 | 2409 | return; |
2384 | 2410 | } |
2411 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2412 | + gen_update_nip(ctx, ctx->nip - 4); | |
2385 | 2413 | gen_reset_fpstatus(); |
2386 | 2414 | t0 = tcg_const_i32(FM(ctx->opcode)); |
2387 | 2415 | gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0); |
... | ... | @@ -2406,6 +2434,8 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) |
2406 | 2434 | } |
2407 | 2435 | bf = crbD(ctx->opcode) >> 2; |
2408 | 2436 | sh = 7 - bf; |
2437 | + /* NIP cannot be restored if the memory exception comes from an helper */ | |
2438 | + gen_update_nip(ctx, ctx->nip - 4); | |
2409 | 2439 | gen_reset_fpstatus(); |
2410 | 2440 | t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh)); |
2411 | 2441 | t1 = tcg_const_i32(1 << sh); | ... | ... |