translate.c (89527e3a75c714e12fa054efa6a80e5111d89354) | translate.c (f3141174dd990672e28db0d952e13ae19f08e825) |
---|---|
1/* 2 SPARC translation 3 4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> 5 Copyright (C) 2003-2005 Fabrice Bellard 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public --- 37 unchanged lines hidden (view full) --- 46# define gen_helper_fabsd(D, S) qemu_build_not_reached() 47# define gen_helper_flushw(E) qemu_build_not_reached() 48# define gen_helper_fnegd(D, S) qemu_build_not_reached() 49# define gen_helper_rdccr(D, E) qemu_build_not_reached() 50# define gen_helper_rdcwp(D, E) qemu_build_not_reached() 51# define gen_helper_restored(E) qemu_build_not_reached() 52# define gen_helper_retry(E) qemu_build_not_reached() 53# define gen_helper_saved(E) qemu_build_not_reached() | 1/* 2 SPARC translation 3 4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> 5 Copyright (C) 2003-2005 Fabrice Bellard 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public --- 37 unchanged lines hidden (view full) --- 46# define gen_helper_fabsd(D, S) qemu_build_not_reached() 47# define gen_helper_flushw(E) qemu_build_not_reached() 48# define gen_helper_fnegd(D, S) qemu_build_not_reached() 49# define gen_helper_rdccr(D, E) qemu_build_not_reached() 50# define gen_helper_rdcwp(D, E) qemu_build_not_reached() 51# define gen_helper_restored(E) qemu_build_not_reached() 52# define gen_helper_retry(E) qemu_build_not_reached() 53# define gen_helper_saved(E) qemu_build_not_reached() |
54# define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached() | |
55# define gen_helper_set_softint(E, S) qemu_build_not_reached() 56# define gen_helper_tick_get_count(D, E, T, C) qemu_build_not_reached() 57# define gen_helper_tick_set_count(P, S) qemu_build_not_reached() 58# define gen_helper_tick_set_limit(P, S) qemu_build_not_reached() | 54# define gen_helper_set_softint(E, S) qemu_build_not_reached() 55# define gen_helper_tick_get_count(D, E, T, C) qemu_build_not_reached() 56# define gen_helper_tick_set_count(P, S) qemu_build_not_reached() 57# define gen_helper_tick_set_limit(P, S) qemu_build_not_reached() |
59# define gen_helper_udivx(D, E, A, B) qemu_build_not_reached() | |
60# define gen_helper_wrccr(E, S) qemu_build_not_reached() 61# define gen_helper_wrcwp(E, S) qemu_build_not_reached() 62# define gen_helper_wrgl(E, S) qemu_build_not_reached() 63# define gen_helper_write_softint(E, S) qemu_build_not_reached() 64# define gen_helper_wrpil(E, S) qemu_build_not_reached() 65# define gen_helper_wrpstate(E, S) qemu_build_not_reached() 66# define gen_helper_fabsq ({ qemu_build_not_reached(); NULL; }) 67# define gen_helper_fcmpeq16 ({ qemu_build_not_reached(); NULL; }) --- 506 unchanged lines hidden (view full) --- 574} 575 576static void gen_op_smul(TCGv dst, TCGv src1, TCGv src2) 577{ 578 /* sign-extend truncated operands before multiplication */ 579 gen_op_multiply(dst, src1, src2, 1); 580} 581 | 58# define gen_helper_wrccr(E, S) qemu_build_not_reached() 59# define gen_helper_wrcwp(E, S) qemu_build_not_reached() 60# define gen_helper_wrgl(E, S) qemu_build_not_reached() 61# define gen_helper_write_softint(E, S) qemu_build_not_reached() 62# define gen_helper_wrpil(E, S) qemu_build_not_reached() 63# define gen_helper_wrpstate(E, S) qemu_build_not_reached() 64# define gen_helper_fabsq ({ qemu_build_not_reached(); NULL; }) 65# define gen_helper_fcmpeq16 ({ qemu_build_not_reached(); NULL; }) --- 506 unchanged lines hidden (view full) --- 572} 573 574static void gen_op_smul(TCGv dst, TCGv src1, TCGv src2) 575{ 576 /* sign-extend truncated operands before multiplication */ 577 gen_op_multiply(dst, src1, src2, 1); 578} 579 |
582static void gen_op_udivx(TCGv dst, TCGv src1, TCGv src2) 583{ 584 gen_helper_udivx(dst, tcg_env, src1, src2); 585} 586 587static void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2) 588{ 589 gen_helper_sdivx(dst, tcg_env, src1, src2); 590} 591 | |
592static void gen_op_udiv(TCGv dst, TCGv src1, TCGv src2) 593{ 594#ifdef TARGET_SPARC64 595 gen_helper_udiv(dst, tcg_env, src1, src2); 596 tcg_gen_ext32u_tl(dst, dst); 597#else 598 TCGv_i64 t64 = tcg_temp_new_i64(); 599 gen_helper_udiv(t64, tcg_env, src1, src2); --- 2975 unchanged lines hidden (view full) --- 3575TRANS(ORN, ALL, do_logic, a, tcg_gen_orc_tl, NULL) 3576TRANS(XORN, ALL, do_logic, a, tcg_gen_eqv_tl, NULL) 3577 3578TRANS(MULX, 64, do_arith, a, tcg_gen_mul_tl, tcg_gen_muli_tl, NULL) 3579TRANS(UMUL, MUL, do_logic, a, gen_op_umul, NULL) 3580TRANS(SMUL, MUL, do_logic, a, gen_op_smul, NULL) 3581TRANS(MULScc, ALL, do_arith, a, NULL, NULL, gen_op_mulscc) 3582 | 580static void gen_op_udiv(TCGv dst, TCGv src1, TCGv src2) 581{ 582#ifdef TARGET_SPARC64 583 gen_helper_udiv(dst, tcg_env, src1, src2); 584 tcg_gen_ext32u_tl(dst, dst); 585#else 586 TCGv_i64 t64 = tcg_temp_new_i64(); 587 gen_helper_udiv(t64, tcg_env, src1, src2); --- 2975 unchanged lines hidden (view full) --- 3563TRANS(ORN, ALL, do_logic, a, tcg_gen_orc_tl, NULL) 3564TRANS(XORN, ALL, do_logic, a, tcg_gen_eqv_tl, NULL) 3565 3566TRANS(MULX, 64, do_arith, a, tcg_gen_mul_tl, tcg_gen_muli_tl, NULL) 3567TRANS(UMUL, MUL, do_logic, a, gen_op_umul, NULL) 3568TRANS(SMUL, MUL, do_logic, a, gen_op_smul, NULL) 3569TRANS(MULScc, ALL, do_arith, a, NULL, NULL, gen_op_mulscc) 3570 |
3583TRANS(UDIVX, 64, do_arith, a, gen_op_udivx, NULL, NULL) 3584TRANS(SDIVX, 64, do_arith, a, gen_op_sdivx, NULL, NULL) | |
3585TRANS(UDIV, DIV, do_arith, a, gen_op_udiv, NULL, gen_op_udivcc) 3586TRANS(SDIV, DIV, do_arith, a, gen_op_sdiv, NULL, gen_op_sdivcc) 3587 3588/* TODO: Should have feature bit -- comes in with UltraSparc T2. */ 3589TRANS(POPC, 64, do_arith, a, gen_op_popc, NULL, NULL) 3590 3591static bool trans_OR(DisasContext *dc, arg_r_r_ri_cc *a) 3592{ --- 7 unchanged lines hidden (view full) --- 3600 } else { 3601 gen_store_gpr(dc, a->rd, cpu_regs[a->rs2_or_imm]); 3602 } 3603 return advance_pc(dc); 3604 } 3605 return do_logic(dc, a, tcg_gen_or_tl, tcg_gen_ori_tl); 3606} 3607 | 3571TRANS(UDIV, DIV, do_arith, a, gen_op_udiv, NULL, gen_op_udivcc) 3572TRANS(SDIV, DIV, do_arith, a, gen_op_sdiv, NULL, gen_op_sdivcc) 3573 3574/* TODO: Should have feature bit -- comes in with UltraSparc T2. */ 3575TRANS(POPC, 64, do_arith, a, gen_op_popc, NULL, NULL) 3576 3577static bool trans_OR(DisasContext *dc, arg_r_r_ri_cc *a) 3578{ --- 7 unchanged lines hidden (view full) --- 3586 } else { 3587 gen_store_gpr(dc, a->rd, cpu_regs[a->rs2_or_imm]); 3588 } 3589 return advance_pc(dc); 3590 } 3591 return do_logic(dc, a, tcg_gen_or_tl, tcg_gen_ori_tl); 3592} 3593 |
3594static bool trans_UDIVX(DisasContext *dc, arg_r_r_ri *a) 3595{ 3596 TCGv dst, src1, src2; 3597 3598 if (!avail_64(dc)) { 3599 return false; 3600 } 3601 /* For simplicity, we under-decoded the rs2 form. */ 3602 if (!a->imm && a->rs2_or_imm & ~0x1f) { 3603 return false; 3604 } 3605 3606 if (unlikely(a->rs2_or_imm == 0)) { 3607 gen_exception(dc, TT_DIV_ZERO); 3608 return true; 3609 } 3610 3611 if (a->imm) { 3612 src2 = tcg_constant_tl(a->rs2_or_imm); 3613 } else { 3614 TCGLabel *lab; 3615 3616 finishing_insn(dc); 3617 flush_cond(dc); 3618 3619 lab = delay_exception(dc, TT_DIV_ZERO); 3620 src2 = cpu_regs[a->rs2_or_imm]; 3621 tcg_gen_brcondi_tl(TCG_COND_EQ, src2, 0, lab); 3622 } 3623 3624 dst = gen_dest_gpr(dc, a->rd); 3625 src1 = gen_load_gpr(dc, a->rs1); 3626 3627 tcg_gen_divu_tl(dst, src1, src2); 3628 gen_store_gpr(dc, a->rd, dst); 3629 return advance_pc(dc); 3630} 3631 3632static bool trans_SDIVX(DisasContext *dc, arg_r_r_ri *a) 3633{ 3634 TCGv dst, src1, src2; 3635 3636 if (!avail_64(dc)) { 3637 return false; 3638 } 3639 /* For simplicity, we under-decoded the rs2 form. */ 3640 if (!a->imm && a->rs2_or_imm & ~0x1f) { 3641 return false; 3642 } 3643 3644 if (unlikely(a->rs2_or_imm == 0)) { 3645 gen_exception(dc, TT_DIV_ZERO); 3646 return true; 3647 } 3648 3649 dst = gen_dest_gpr(dc, a->rd); 3650 src1 = gen_load_gpr(dc, a->rs1); 3651 3652 if (a->imm) { 3653 if (unlikely(a->rs2_or_imm == -1)) { 3654 tcg_gen_neg_tl(dst, src1); 3655 gen_store_gpr(dc, a->rd, dst); 3656 return advance_pc(dc); 3657 } 3658 src2 = tcg_constant_tl(a->rs2_or_imm); 3659 } else { 3660 TCGLabel *lab; 3661 TCGv t1, t2; 3662 3663 finishing_insn(dc); 3664 flush_cond(dc); 3665 3666 lab = delay_exception(dc, TT_DIV_ZERO); 3667 src2 = cpu_regs[a->rs2_or_imm]; 3668 tcg_gen_brcondi_tl(TCG_COND_EQ, src2, 0, lab); 3669 3670 /* 3671 * Need to avoid INT64_MIN / -1, which will trap on x86 host. 3672 * Set SRC2 to 1 as a new divisor, to produce the correct result. 3673 */ 3674 t1 = tcg_temp_new(); 3675 t2 = tcg_temp_new(); 3676 tcg_gen_setcondi_tl(TCG_COND_EQ, t1, src1, (target_long)INT64_MIN); 3677 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, src2, -1); 3678 tcg_gen_and_tl(t1, t1, t2); 3679 tcg_gen_movcond_tl(TCG_COND_NE, t1, t1, tcg_constant_tl(0), 3680 tcg_constant_tl(1), src2); 3681 src2 = t1; 3682 } 3683 3684 tcg_gen_div_tl(dst, src1, src2); 3685 gen_store_gpr(dc, a->rd, dst); 3686 return advance_pc(dc); 3687} 3688 |
|
3608static bool gen_edge(DisasContext *dc, arg_r_r_r *a, 3609 int width, bool cc, bool left) 3610{ 3611 TCGv dst, s1, s2, lo1, lo2; 3612 uint64_t amask, tabl, tabr; 3613 int shift, imask, omask; 3614 3615 dst = gen_dest_gpr(dc, a->rd); --- 1683 unchanged lines hidden --- | 3689static bool gen_edge(DisasContext *dc, arg_r_r_r *a, 3690 int width, bool cc, bool left) 3691{ 3692 TCGv dst, s1, s2, lo1, lo2; 3693 uint64_t amask, tabl, tabr; 3694 int shift, imask, omask; 3695 3696 dst = gen_dest_gpr(dc, a->rd); --- 1683 unchanged lines hidden --- |