Commit 8dd4983c4e0c4e4f2ed87060a770ba99e03f3b9e
1 parent
71be0fc3
fixed lsw[ix] / stsw[ix] potential exception bug - mtcrf workaround for Mac OS X…
… 10.4 - use direct jump at page boundary git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1441 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
16 additions
and
3 deletions
target-ppc/translate.c
@@ -1370,6 +1370,8 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER) | @@ -1370,6 +1370,8 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER) | ||
1370 | gen_op_load_gpr_T0(ra); | 1370 | gen_op_load_gpr_T0(ra); |
1371 | } | 1371 | } |
1372 | gen_op_set_T1(nb); | 1372 | gen_op_set_T1(nb); |
1373 | + /* NIP cannot be restored if the memory exception comes from an helper */ | ||
1374 | + gen_op_update_nip((ctx)->nip - 4); | ||
1373 | op_ldsts(lswi, start); | 1375 | op_ldsts(lswi, start); |
1374 | } | 1376 | } |
1375 | 1377 | ||
@@ -1388,6 +1390,8 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER) | @@ -1388,6 +1390,8 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER) | ||
1388 | gen_op_add(); | 1390 | gen_op_add(); |
1389 | } | 1391 | } |
1390 | gen_op_load_xer_bc(); | 1392 | gen_op_load_xer_bc(); |
1393 | + /* NIP cannot be restored if the memory exception comes from an helper */ | ||
1394 | + gen_op_update_nip((ctx)->nip - 4); | ||
1391 | op_ldstsx(lswx, rD(ctx->opcode), ra, rb); | 1395 | op_ldstsx(lswx, rD(ctx->opcode), ra, rb); |
1392 | } | 1396 | } |
1393 | 1397 | ||
@@ -1404,6 +1408,8 @@ GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER) | @@ -1404,6 +1408,8 @@ GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER) | ||
1404 | if (nb == 0) | 1408 | if (nb == 0) |
1405 | nb = 32; | 1409 | nb = 32; |
1406 | gen_op_set_T1(nb); | 1410 | gen_op_set_T1(nb); |
1411 | + /* NIP cannot be restored if the memory exception comes from an helper */ | ||
1412 | + gen_op_update_nip((ctx)->nip - 4); | ||
1407 | op_ldsts(stsw, rS(ctx->opcode)); | 1413 | op_ldsts(stsw, rS(ctx->opcode)); |
1408 | } | 1414 | } |
1409 | 1415 | ||
@@ -1421,6 +1427,8 @@ GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER) | @@ -1421,6 +1427,8 @@ GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER) | ||
1421 | gen_op_add(); | 1427 | gen_op_add(); |
1422 | } | 1428 | } |
1423 | gen_op_load_xer_bc(); | 1429 | gen_op_load_xer_bc(); |
1430 | + /* NIP cannot be restored if the memory exception comes from an helper */ | ||
1431 | + gen_op_update_nip((ctx)->nip - 4); | ||
1424 | op_ldsts(stsw, rS(ctx->opcode)); | 1432 | op_ldsts(stsw, rS(ctx->opcode)); |
1425 | } | 1433 | } |
1426 | 1434 | ||
@@ -2123,7 +2131,8 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC) | @@ -2123,7 +2131,8 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC) | ||
2123 | } | 2131 | } |
2124 | 2132 | ||
2125 | /* mtcrf */ | 2133 | /* mtcrf */ |
2126 | -GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC) | 2134 | +/* The mask should be 0x00100801, but Mac OS X 10.4 use an alternate form */ |
2135 | +GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC) | ||
2127 | { | 2136 | { |
2128 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 2137 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
2129 | gen_op_store_cr(CRM(ctx->opcode)); | 2138 | gen_op_store_cr(CRM(ctx->opcode)); |
@@ -3312,10 +3321,14 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -3312,10 +3321,14 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
3312 | ctx.exception != EXCP_TRAP)) { | 3321 | ctx.exception != EXCP_TRAP)) { |
3313 | RET_EXCP(ctxp, EXCP_TRACE, 0); | 3322 | RET_EXCP(ctxp, EXCP_TRACE, 0); |
3314 | } | 3323 | } |
3324 | + if (ctx.exception != EXCP_NONE) | ||
3325 | + break; | ||
3315 | /* if we reach a page boundary, stop generation */ | 3326 | /* if we reach a page boundary, stop generation */ |
3316 | if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) { | 3327 | if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) { |
3317 | - RET_EXCP(ctxp, EXCP_BRANCH, 0); | ||
3318 | - } | 3328 | + gen_op_b((long)ctx.tb, ctx.nip); |
3329 | + ctx.exception = EXCP_BRANCH; | ||
3330 | + break; | ||
3331 | + } | ||
3319 | } | 3332 | } |
3320 | if (ctx.exception == EXCP_NONE) { | 3333 | if (ctx.exception == EXCP_NONE) { |
3321 | gen_op_b((unsigned long)ctx.tb, ctx.nip); | 3334 | gen_op_b((unsigned long)ctx.tb, ctx.nip); |