Commit a2ffb81204ccfb497908773729f8d2f1048a65c4

Authored by aurel32
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
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 }
... ...