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,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 }