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 | 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 | 329 | /*** Integer arithmetic ***/ |
| 490 | 330 | /* add */ |
| 491 | 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 | 3276 | { |
| 3277 | 3277 | TranslationBlock *tb; |
| 3278 | 3278 | tb = ctx->tb; |
| 3279 | +#if defined(TARGET_PPC64) | |
| 3280 | + if (!ctx->sf_mode) | |
| 3281 | + dest = (uint32_t) dest; | |
| 3282 | +#endif | |
| 3279 | 3283 | if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && |
| 3280 | 3284 | likely(!ctx->singlestep_enabled)) { |
| 3281 | 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 | 3287 | tcg_gen_exit_tb((long)tb + n); |
| 3290 | 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 | 3290 | if (unlikely(ctx->singlestep_enabled)) { |
| 3299 | 3291 | if ((ctx->singlestep_enabled & |
| 3300 | 3292 | (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) && |
| ... | ... | @@ -3316,11 +3308,11 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, |
| 3316 | 3308 | static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip) |
| 3317 | 3309 | { |
| 3318 | 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 | 3313 | else |
| 3322 | 3314 | #endif |
| 3323 | - gen_op_setlr(ctx->nip); | |
| 3315 | + tcg_gen_movi_tl(cpu_lr, nip); | |
| 3324 | 3316 | } |
| 3325 | 3317 | |
| 3326 | 3318 | /* b ba bl bla */ |
| ... | ... | @@ -3340,10 +3332,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) |
| 3340 | 3332 | target = ctx->nip + li - 4; |
| 3341 | 3333 | else |
| 3342 | 3334 | target = li; |
| 3343 | -#if defined(TARGET_PPC64) | |
| 3344 | - if (!ctx->sf_mode) | |
| 3345 | - target = (uint32_t)target; | |
| 3346 | -#endif | |
| 3347 | 3335 | if (LK(ctx->opcode)) |
| 3348 | 3336 | gen_setlr(ctx, ctx->nip); |
| 3349 | 3337 | gen_goto_tb(ctx, 0, target); |
| ... | ... | @@ -3355,141 +3343,80 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) |
| 3355 | 3343 | |
| 3356 | 3344 | static always_inline void gen_bcond (DisasContext *ctx, int type) |
| 3357 | 3345 | { |
| 3358 | - target_ulong target = 0; | |
| 3359 | - target_ulong li; | |
| 3360 | 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 | 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 | 3358 | if (LK(ctx->opcode)) |
| 3389 | 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 | 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 | 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 | 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 | 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 | 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 | 3403 | gen_set_label(l1); |
| 3484 | 3404 | gen_goto_tb(ctx, 1, ctx->nip); |
| 3485 | 3405 | } else { |
| 3486 | 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 | 3417 | else |
| 3490 | 3418 | #endif |
| 3491 | - gen_op_btest_T1(ctx->nip); | |
| 3492 | - no_test: | |
| 3419 | + tcg_gen_movi_tl(cpu_nip, ctx->nip); | |
| 3493 | 3420 | tcg_gen_exit_tb(0); |
| 3494 | 3421 | } |
| 3495 | 3422 | } | ... | ... |