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