Commit a2ffb81204ccfb497908773729f8d2f1048a65c4
1 parent
22babebb
target-ppc: convert branch related instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5508 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
63 additions
and
296 deletions
target-ppc/op.c
@@ -326,166 +326,6 @@ void OPPROTO op_store_fpscr (void) | @@ -326,166 +326,6 @@ void OPPROTO op_store_fpscr (void) | ||
326 | RETURN(); | 326 | RETURN(); |
327 | } | 327 | } |
328 | 328 | ||
329 | -/* Branch */ | ||
330 | -void OPPROTO op_setlr (void) | ||
331 | -{ | ||
332 | - env->lr = (uint32_t)PARAM1; | ||
333 | - RETURN(); | ||
334 | -} | ||
335 | - | ||
336 | -#if defined (TARGET_PPC64) | ||
337 | -void OPPROTO op_setlr_64 (void) | ||
338 | -{ | ||
339 | - env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2; | ||
340 | - RETURN(); | ||
341 | -} | ||
342 | -#endif | ||
343 | - | ||
344 | -void OPPROTO op_jz_T0 (void) | ||
345 | -{ | ||
346 | - if (!T0) | ||
347 | - GOTO_LABEL_PARAM(1); | ||
348 | - RETURN(); | ||
349 | -} | ||
350 | - | ||
351 | -void OPPROTO op_btest_T1 (void) | ||
352 | -{ | ||
353 | - if (T0) { | ||
354 | - env->nip = (uint32_t)(T1 & ~3); | ||
355 | - } else { | ||
356 | - env->nip = (uint32_t)PARAM1; | ||
357 | - } | ||
358 | - RETURN(); | ||
359 | -} | ||
360 | - | ||
361 | -#if defined (TARGET_PPC64) | ||
362 | -void OPPROTO op_btest_T1_64 (void) | ||
363 | -{ | ||
364 | - if (T0) { | ||
365 | - env->nip = (uint64_t)(T1 & ~3); | ||
366 | - } else { | ||
367 | - env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2; | ||
368 | - } | ||
369 | - RETURN(); | ||
370 | -} | ||
371 | -#endif | ||
372 | - | ||
373 | -void OPPROTO op_movl_T1_ctr (void) | ||
374 | -{ | ||
375 | - T1 = env->ctr; | ||
376 | - RETURN(); | ||
377 | -} | ||
378 | - | ||
379 | -void OPPROTO op_movl_T1_lr (void) | ||
380 | -{ | ||
381 | - T1 = env->lr; | ||
382 | - RETURN(); | ||
383 | -} | ||
384 | - | ||
385 | -/* tests with result in T0 */ | ||
386 | -void OPPROTO op_test_ctr (void) | ||
387 | -{ | ||
388 | - T0 = (uint32_t)env->ctr; | ||
389 | - RETURN(); | ||
390 | -} | ||
391 | - | ||
392 | -#if defined(TARGET_PPC64) | ||
393 | -void OPPROTO op_test_ctr_64 (void) | ||
394 | -{ | ||
395 | - T0 = (uint64_t)env->ctr; | ||
396 | - RETURN(); | ||
397 | -} | ||
398 | -#endif | ||
399 | - | ||
400 | -void OPPROTO op_test_ctr_true (void) | ||
401 | -{ | ||
402 | - T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0); | ||
403 | - RETURN(); | ||
404 | -} | ||
405 | - | ||
406 | -#if defined(TARGET_PPC64) | ||
407 | -void OPPROTO op_test_ctr_true_64 (void) | ||
408 | -{ | ||
409 | - T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0); | ||
410 | - RETURN(); | ||
411 | -} | ||
412 | -#endif | ||
413 | - | ||
414 | -void OPPROTO op_test_ctr_false (void) | ||
415 | -{ | ||
416 | - T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0); | ||
417 | - RETURN(); | ||
418 | -} | ||
419 | - | ||
420 | -#if defined(TARGET_PPC64) | ||
421 | -void OPPROTO op_test_ctr_false_64 (void) | ||
422 | -{ | ||
423 | - T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0); | ||
424 | - RETURN(); | ||
425 | -} | ||
426 | -#endif | ||
427 | - | ||
428 | -void OPPROTO op_test_ctrz (void) | ||
429 | -{ | ||
430 | - T0 = ((uint32_t)env->ctr == 0); | ||
431 | - RETURN(); | ||
432 | -} | ||
433 | - | ||
434 | -#if defined(TARGET_PPC64) | ||
435 | -void OPPROTO op_test_ctrz_64 (void) | ||
436 | -{ | ||
437 | - T0 = ((uint64_t)env->ctr == 0); | ||
438 | - RETURN(); | ||
439 | -} | ||
440 | -#endif | ||
441 | - | ||
442 | -void OPPROTO op_test_ctrz_true (void) | ||
443 | -{ | ||
444 | - T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0); | ||
445 | - RETURN(); | ||
446 | -} | ||
447 | - | ||
448 | -#if defined(TARGET_PPC64) | ||
449 | -void OPPROTO op_test_ctrz_true_64 (void) | ||
450 | -{ | ||
451 | - T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0); | ||
452 | - RETURN(); | ||
453 | -} | ||
454 | -#endif | ||
455 | - | ||
456 | -void OPPROTO op_test_ctrz_false (void) | ||
457 | -{ | ||
458 | - T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0); | ||
459 | - RETURN(); | ||
460 | -} | ||
461 | - | ||
462 | -#if defined(TARGET_PPC64) | ||
463 | -void OPPROTO op_test_ctrz_false_64 (void) | ||
464 | -{ | ||
465 | - T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0); | ||
466 | - RETURN(); | ||
467 | -} | ||
468 | -#endif | ||
469 | - | ||
470 | -void OPPROTO op_test_true (void) | ||
471 | -{ | ||
472 | - T0 = (T0 & PARAM1); | ||
473 | - RETURN(); | ||
474 | -} | ||
475 | - | ||
476 | -void OPPROTO op_test_false (void) | ||
477 | -{ | ||
478 | - T0 = ((T0 & PARAM1) == 0); | ||
479 | - RETURN(); | ||
480 | -} | ||
481 | - | ||
482 | -/* CTR maintenance */ | ||
483 | -void OPPROTO op_dec_ctr (void) | ||
484 | -{ | ||
485 | - env->ctr--; | ||
486 | - RETURN(); | ||
487 | -} | ||
488 | - | ||
489 | /*** Integer arithmetic ***/ | 329 | /*** Integer arithmetic ***/ |
490 | /* add */ | 330 | /* add */ |
491 | void OPPROTO op_check_addo (void) | 331 | void OPPROTO op_check_addo (void) |
target-ppc/translate.c
@@ -3276,25 +3276,17 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, | @@ -3276,25 +3276,17 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, | ||
3276 | { | 3276 | { |
3277 | TranslationBlock *tb; | 3277 | TranslationBlock *tb; |
3278 | tb = ctx->tb; | 3278 | tb = ctx->tb; |
3279 | +#if defined(TARGET_PPC64) | ||
3280 | + if (!ctx->sf_mode) | ||
3281 | + dest = (uint32_t) dest; | ||
3282 | +#endif | ||
3279 | if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && | 3283 | if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && |
3280 | likely(!ctx->singlestep_enabled)) { | 3284 | likely(!ctx->singlestep_enabled)) { |
3281 | tcg_gen_goto_tb(n); | 3285 | tcg_gen_goto_tb(n); |
3282 | - tcg_gen_movi_tl(cpu_T[1], dest); | ||
3283 | -#if defined(TARGET_PPC64) | ||
3284 | - if (ctx->sf_mode) | ||
3285 | - tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3); | ||
3286 | - else | ||
3287 | -#endif | ||
3288 | - tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3); | 3286 | + tcg_gen_movi_tl(cpu_nip, dest & ~3); |
3289 | tcg_gen_exit_tb((long)tb + n); | 3287 | tcg_gen_exit_tb((long)tb + n); |
3290 | } else { | 3288 | } else { |
3291 | - tcg_gen_movi_tl(cpu_T[1], dest); | ||
3292 | -#if defined(TARGET_PPC64) | ||
3293 | - if (ctx->sf_mode) | ||
3294 | - tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3); | ||
3295 | - else | ||
3296 | -#endif | ||
3297 | - tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3); | 3289 | + tcg_gen_movi_tl(cpu_nip, dest & ~3); |
3298 | if (unlikely(ctx->singlestep_enabled)) { | 3290 | if (unlikely(ctx->singlestep_enabled)) { |
3299 | if ((ctx->singlestep_enabled & | 3291 | if ((ctx->singlestep_enabled & |
3300 | (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) && | 3292 | (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) && |
@@ -3316,11 +3308,11 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, | @@ -3316,11 +3308,11 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, | ||
3316 | static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip) | 3308 | static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip) |
3317 | { | 3309 | { |
3318 | #if defined(TARGET_PPC64) | 3310 | #if defined(TARGET_PPC64) |
3319 | - if (ctx->sf_mode != 0 && (nip >> 32)) | ||
3320 | - gen_op_setlr_64(ctx->nip >> 32, ctx->nip); | 3311 | + if (ctx->sf_mode == 0) |
3312 | + tcg_gen_movi_tl(cpu_lr, (uint32_t)nip); | ||
3321 | else | 3313 | else |
3322 | #endif | 3314 | #endif |
3323 | - gen_op_setlr(ctx->nip); | 3315 | + tcg_gen_movi_tl(cpu_lr, nip); |
3324 | } | 3316 | } |
3325 | 3317 | ||
3326 | /* b ba bl bla */ | 3318 | /* b ba bl bla */ |
@@ -3340,10 +3332,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) | @@ -3340,10 +3332,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) | ||
3340 | target = ctx->nip + li - 4; | 3332 | target = ctx->nip + li - 4; |
3341 | else | 3333 | else |
3342 | target = li; | 3334 | target = li; |
3343 | -#if defined(TARGET_PPC64) | ||
3344 | - if (!ctx->sf_mode) | ||
3345 | - target = (uint32_t)target; | ||
3346 | -#endif | ||
3347 | if (LK(ctx->opcode)) | 3335 | if (LK(ctx->opcode)) |
3348 | gen_setlr(ctx, ctx->nip); | 3336 | gen_setlr(ctx, ctx->nip); |
3349 | gen_goto_tb(ctx, 0, target); | 3337 | gen_goto_tb(ctx, 0, target); |
@@ -3355,141 +3343,80 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) | @@ -3355,141 +3343,80 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) | ||
3355 | 3343 | ||
3356 | static always_inline void gen_bcond (DisasContext *ctx, int type) | 3344 | static always_inline void gen_bcond (DisasContext *ctx, int type) |
3357 | { | 3345 | { |
3358 | - target_ulong target = 0; | ||
3359 | - target_ulong li; | ||
3360 | uint32_t bo = BO(ctx->opcode); | 3346 | uint32_t bo = BO(ctx->opcode); |
3361 | - uint32_t bi = BI(ctx->opcode); | ||
3362 | - uint32_t mask; | 3347 | + int l1 = gen_new_label(); |
3348 | + TCGv target; | ||
3363 | 3349 | ||
3364 | ctx->exception = POWERPC_EXCP_BRANCH; | 3350 | ctx->exception = POWERPC_EXCP_BRANCH; |
3365 | - if ((bo & 0x4) == 0) | ||
3366 | - gen_op_dec_ctr(); | ||
3367 | - switch(type) { | ||
3368 | - case BCOND_IM: | ||
3369 | - li = (target_long)((int16_t)(BD(ctx->opcode))); | ||
3370 | - if (likely(AA(ctx->opcode) == 0)) { | ||
3371 | - target = ctx->nip + li - 4; | ||
3372 | - } else { | ||
3373 | - target = li; | ||
3374 | - } | ||
3375 | -#if defined(TARGET_PPC64) | ||
3376 | - if (!ctx->sf_mode) | ||
3377 | - target = (uint32_t)target; | ||
3378 | -#endif | ||
3379 | - break; | ||
3380 | - case BCOND_CTR: | ||
3381 | - gen_op_movl_T1_ctr(); | ||
3382 | - break; | ||
3383 | - default: | ||
3384 | - case BCOND_LR: | ||
3385 | - gen_op_movl_T1_lr(); | ||
3386 | - break; | 3351 | + if (type == BCOND_LR || type == BCOND_CTR) { |
3352 | + target = tcg_temp_local_new(TCG_TYPE_TL); | ||
3353 | + if (type == BCOND_CTR) | ||
3354 | + tcg_gen_mov_tl(target, cpu_ctr); | ||
3355 | + else | ||
3356 | + tcg_gen_mov_tl(target, cpu_lr); | ||
3387 | } | 3357 | } |
3388 | if (LK(ctx->opcode)) | 3358 | if (LK(ctx->opcode)) |
3389 | gen_setlr(ctx, ctx->nip); | 3359 | gen_setlr(ctx, ctx->nip); |
3390 | - if (bo & 0x10) { | ||
3391 | - /* No CR condition */ | ||
3392 | - switch (bo & 0x6) { | ||
3393 | - case 0: | ||
3394 | -#if defined(TARGET_PPC64) | ||
3395 | - if (ctx->sf_mode) | ||
3396 | - gen_op_test_ctr_64(); | ||
3397 | - else | ||
3398 | -#endif | ||
3399 | - gen_op_test_ctr(); | ||
3400 | - break; | ||
3401 | - case 2: | ||
3402 | -#if defined(TARGET_PPC64) | ||
3403 | - if (ctx->sf_mode) | ||
3404 | - gen_op_test_ctrz_64(); | ||
3405 | - else | ||
3406 | -#endif | ||
3407 | - gen_op_test_ctrz(); | ||
3408 | - break; | ||
3409 | - default: | ||
3410 | - case 4: | ||
3411 | - case 6: | ||
3412 | - if (type == BCOND_IM) { | ||
3413 | - gen_goto_tb(ctx, 0, target); | ||
3414 | - return; | ||
3415 | - } else { | 3360 | + l1 = gen_new_label(); |
3361 | + if ((bo & 0x4) == 0) { | ||
3362 | + /* Decrement and test CTR */ | ||
3363 | + TCGv temp = tcg_temp_new(TCG_TYPE_TL); | ||
3364 | + if (unlikely(type == BCOND_CTR)) { | ||
3365 | + GEN_EXCP_INVAL(ctx); | ||
3366 | + return; | ||
3367 | + } | ||
3368 | + tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); | ||
3416 | #if defined(TARGET_PPC64) | 3369 | #if defined(TARGET_PPC64) |
3417 | - if (ctx->sf_mode) | ||
3418 | - tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3); | ||
3419 | - else | 3370 | + if (!ctx->sf_mode) |
3371 | + tcg_gen_ext32u_tl(temp, cpu_ctr); | ||
3372 | + else | ||
3420 | #endif | 3373 | #endif |
3421 | - tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3); | ||
3422 | - goto no_test; | ||
3423 | - } | ||
3424 | - break; | 3374 | + tcg_gen_mov_tl(temp, cpu_ctr); |
3375 | + if (bo & 0x2) { | ||
3376 | + tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1); | ||
3377 | + } else { | ||
3378 | + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1); | ||
3425 | } | 3379 | } |
3426 | - } else { | ||
3427 | - mask = 1 << (3 - (bi & 0x03)); | ||
3428 | - tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]); | 3380 | + } |
3381 | + if ((bo & 0x10) == 0) { | ||
3382 | + /* Test CR */ | ||
3383 | + uint32_t bi = BI(ctx->opcode); | ||
3384 | + uint32_t mask = 1 << (3 - (bi & 0x03)); | ||
3385 | + TCGv temp = tcg_temp_new(TCG_TYPE_I32); | ||
3386 | + | ||
3429 | if (bo & 0x8) { | 3387 | if (bo & 0x8) { |
3430 | - switch (bo & 0x6) { | ||
3431 | - case 0: | ||
3432 | -#if defined(TARGET_PPC64) | ||
3433 | - if (ctx->sf_mode) | ||
3434 | - gen_op_test_ctr_true_64(mask); | ||
3435 | - else | ||
3436 | -#endif | ||
3437 | - gen_op_test_ctr_true(mask); | ||
3438 | - break; | ||
3439 | - case 2: | ||
3440 | -#if defined(TARGET_PPC64) | ||
3441 | - if (ctx->sf_mode) | ||
3442 | - gen_op_test_ctrz_true_64(mask); | ||
3443 | - else | ||
3444 | -#endif | ||
3445 | - gen_op_test_ctrz_true(mask); | ||
3446 | - break; | ||
3447 | - default: | ||
3448 | - case 4: | ||
3449 | - case 6: | ||
3450 | - gen_op_test_true(mask); | ||
3451 | - break; | ||
3452 | - } | 3388 | + tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); |
3389 | + tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1); | ||
3453 | } else { | 3390 | } else { |
3454 | - switch (bo & 0x6) { | ||
3455 | - case 0: | ||
3456 | -#if defined(TARGET_PPC64) | ||
3457 | - if (ctx->sf_mode) | ||
3458 | - gen_op_test_ctr_false_64(mask); | ||
3459 | - else | ||
3460 | -#endif | ||
3461 | - gen_op_test_ctr_false(mask); | ||
3462 | - break; | ||
3463 | - case 2: | ||
3464 | -#if defined(TARGET_PPC64) | ||
3465 | - if (ctx->sf_mode) | ||
3466 | - gen_op_test_ctrz_false_64(mask); | ||
3467 | - else | ||
3468 | -#endif | ||
3469 | - gen_op_test_ctrz_false(mask); | ||
3470 | - break; | ||
3471 | - default: | ||
3472 | - case 4: | ||
3473 | - case 6: | ||
3474 | - gen_op_test_false(mask); | ||
3475 | - break; | ||
3476 | - } | 3391 | + tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); |
3392 | + tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1); | ||
3477 | } | 3393 | } |
3478 | } | 3394 | } |
3479 | if (type == BCOND_IM) { | 3395 | if (type == BCOND_IM) { |
3480 | - int l1 = gen_new_label(); | ||
3481 | - gen_op_jz_T0(l1); | ||
3482 | - gen_goto_tb(ctx, 0, target); | 3396 | + |
3397 | + target_ulong li = (target_long)((int16_t)(BD(ctx->opcode))); | ||
3398 | + if (likely(AA(ctx->opcode) == 0)) { | ||
3399 | + gen_goto_tb(ctx, 0, ctx->nip + li - 4); | ||
3400 | + } else { | ||
3401 | + gen_goto_tb(ctx, 0, li); | ||
3402 | + } | ||
3483 | gen_set_label(l1); | 3403 | gen_set_label(l1); |
3484 | gen_goto_tb(ctx, 1, ctx->nip); | 3404 | gen_goto_tb(ctx, 1, ctx->nip); |
3485 | } else { | 3405 | } else { |
3486 | #if defined(TARGET_PPC64) | 3406 | #if defined(TARGET_PPC64) |
3487 | - if (ctx->sf_mode) | ||
3488 | - gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip); | 3407 | + if (!(ctx->sf_mode)) |
3408 | + tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3); | ||
3409 | + else | ||
3410 | +#endif | ||
3411 | + tcg_gen_andi_tl(cpu_nip, target, ~3); | ||
3412 | + tcg_gen_exit_tb(0); | ||
3413 | + gen_set_label(l1); | ||
3414 | +#if defined(TARGET_PPC64) | ||
3415 | + if (!(ctx->sf_mode)) | ||
3416 | + tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip); | ||
3489 | else | 3417 | else |
3490 | #endif | 3418 | #endif |
3491 | - gen_op_btest_T1(ctx->nip); | ||
3492 | - no_test: | 3419 | + tcg_gen_movi_tl(cpu_nip, ctx->nip); |
3493 | tcg_gen_exit_tb(0); | 3420 | tcg_gen_exit_tb(0); |
3494 | } | 3421 | } |
3495 | } | 3422 | } |