Revision 49f7ee80 target-s390x/translate.c
b/target-s390x/translate.c | ||
---|---|---|
993 | 993 |
TCGv_i64 addr1; |
994 | 994 |
} DisasOps; |
995 | 995 |
|
996 |
/* Instructions can place constraints on their operands, raising specification |
|
997 |
exceptions if they are violated. To make this easy to automate, each "in1", |
|
998 |
"in2", "prep", "wout" helper will have a SPEC_<name> define that equals one |
|
999 |
of the following, or 0. To make this easy to document, we'll put the |
|
1000 |
SPEC_<name> defines next to <name>. */ |
|
1001 |
|
|
1002 |
#define SPEC_r1_even 1 |
|
1003 |
#define SPEC_r2_even 2 |
|
1004 |
#define SPEC_r1_f128 4 |
|
1005 |
#define SPEC_r2_f128 8 |
|
1006 |
|
|
996 | 1007 |
/* Return values from translate_one, indicating the state of the TB. */ |
997 | 1008 |
typedef enum { |
998 | 1009 |
/* Continue the TB. */ |
... | ... | |
1038 | 1049 |
unsigned opc:16; |
1039 | 1050 |
DisasFormat fmt:6; |
1040 | 1051 |
DisasFacility fac:6; |
1052 |
unsigned spec:4; |
|
1041 | 1053 |
|
1042 | 1054 |
const char *name; |
1043 | 1055 |
|
... | ... | |
3561 | 3573 |
{ |
3562 | 3574 |
o->out = tcg_temp_new_i64(); |
3563 | 3575 |
} |
3576 |
#define SPEC_prep_new 0 |
|
3564 | 3577 |
|
3565 | 3578 |
static void prep_new_P(DisasContext *s, DisasFields *f, DisasOps *o) |
3566 | 3579 |
{ |
3567 | 3580 |
o->out = tcg_temp_new_i64(); |
3568 | 3581 |
o->out2 = tcg_temp_new_i64(); |
3569 | 3582 |
} |
3583 |
#define SPEC_prep_new_P 0 |
|
3570 | 3584 |
|
3571 | 3585 |
static void prep_r1(DisasContext *s, DisasFields *f, DisasOps *o) |
3572 | 3586 |
{ |
3573 | 3587 |
o->out = regs[get_field(f, r1)]; |
3574 | 3588 |
o->g_out = true; |
3575 | 3589 |
} |
3590 |
#define SPEC_prep_r1 0 |
|
3576 | 3591 |
|
3577 | 3592 |
static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o) |
3578 | 3593 |
{ |
3579 |
/* ??? Specification exception: r1 must be even. */ |
|
3580 | 3594 |
int r1 = get_field(f, r1); |
3581 | 3595 |
o->out = regs[r1]; |
3582 |
o->out2 = regs[(r1 + 1) & 15];
|
|
3596 |
o->out2 = regs[r1 + 1];
|
|
3583 | 3597 |
o->g_out = o->g_out2 = true; |
3584 | 3598 |
} |
3599 |
#define SPEC_prep_r1_P SPEC_r1_even |
|
3585 | 3600 |
|
3586 | 3601 |
static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o) |
3587 | 3602 |
{ |
3588 | 3603 |
o->out = fregs[get_field(f, r1)]; |
3589 | 3604 |
o->g_out = true; |
3590 | 3605 |
} |
3606 |
#define SPEC_prep_f1 0 |
|
3591 | 3607 |
|
3592 | 3608 |
static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o) |
3593 | 3609 |
{ |
3594 |
/* ??? Specification exception: r1 must be < 14. */ |
|
3595 | 3610 |
int r1 = get_field(f, r1); |
3596 | 3611 |
o->out = fregs[r1]; |
3597 |
o->out2 = fregs[(r1 + 2) & 15];
|
|
3612 |
o->out2 = fregs[r1 + 2];
|
|
3598 | 3613 |
o->g_out = o->g_out2 = true; |
3599 | 3614 |
} |
3615 |
#define SPEC_prep_x1 SPEC_r1_f128 |
|
3600 | 3616 |
|
3601 | 3617 |
/* ====================================================================== */ |
3602 | 3618 |
/* The "Write OUTput" generators. These generally perform some non-trivial |
... | ... | |
3608 | 3624 |
{ |
3609 | 3625 |
store_reg(get_field(f, r1), o->out); |
3610 | 3626 |
} |
3627 |
#define SPEC_wout_r1 0 |
|
3611 | 3628 |
|
3612 | 3629 |
static void wout_r1_8(DisasContext *s, DisasFields *f, DisasOps *o) |
3613 | 3630 |
{ |
3614 | 3631 |
int r1 = get_field(f, r1); |
3615 | 3632 |
tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8); |
3616 | 3633 |
} |
3634 |
#define SPEC_wout_r1_8 0 |
|
3617 | 3635 |
|
3618 | 3636 |
static void wout_r1_16(DisasContext *s, DisasFields *f, DisasOps *o) |
3619 | 3637 |
{ |
3620 | 3638 |
int r1 = get_field(f, r1); |
3621 | 3639 |
tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16); |
3622 | 3640 |
} |
3641 |
#define SPEC_wout_r1_16 0 |
|
3623 | 3642 |
|
3624 | 3643 |
static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o) |
3625 | 3644 |
{ |
3626 | 3645 |
store_reg32_i64(get_field(f, r1), o->out); |
3627 | 3646 |
} |
3647 |
#define SPEC_wout_r1_32 0 |
|
3628 | 3648 |
|
3629 | 3649 |
static void wout_r1_P32(DisasContext *s, DisasFields *f, DisasOps *o) |
3630 | 3650 |
{ |
3631 |
/* ??? Specification exception: r1 must be even. */ |
|
3632 | 3651 |
int r1 = get_field(f, r1); |
3633 | 3652 |
store_reg32_i64(r1, o->out); |
3634 |
store_reg32_i64((r1 + 1) & 15, o->out2);
|
|
3653 |
store_reg32_i64(r1 + 1, o->out2);
|
|
3635 | 3654 |
} |
3655 |
#define SPEC_wout_r1_P32 SPEC_r1_even |
|
3636 | 3656 |
|
3637 | 3657 |
static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o) |
3638 | 3658 |
{ |
3639 |
/* ??? Specification exception: r1 must be even. */ |
|
3640 | 3659 |
int r1 = get_field(f, r1); |
3641 |
store_reg32_i64((r1 + 1) & 15, o->out);
|
|
3660 |
store_reg32_i64(r1 + 1, o->out);
|
|
3642 | 3661 |
tcg_gen_shri_i64(o->out, o->out, 32); |
3643 | 3662 |
store_reg32_i64(r1, o->out); |
3644 | 3663 |
} |
3664 |
#define SPEC_wout_r1_D32 SPEC_r1_even |
|
3645 | 3665 |
|
3646 | 3666 |
static void wout_e1(DisasContext *s, DisasFields *f, DisasOps *o) |
3647 | 3667 |
{ |
3648 | 3668 |
store_freg32_i64(get_field(f, r1), o->out); |
3649 | 3669 |
} |
3670 |
#define SPEC_wout_e1 0 |
|
3650 | 3671 |
|
3651 | 3672 |
static void wout_f1(DisasContext *s, DisasFields *f, DisasOps *o) |
3652 | 3673 |
{ |
3653 | 3674 |
store_freg(get_field(f, r1), o->out); |
3654 | 3675 |
} |
3676 |
#define SPEC_wout_f1 0 |
|
3655 | 3677 |
|
3656 | 3678 |
static void wout_x1(DisasContext *s, DisasFields *f, DisasOps *o) |
3657 | 3679 |
{ |
3658 |
/* ??? Specification exception: r1 must be < 14. */ |
|
3659 | 3680 |
int f1 = get_field(s->fields, r1); |
3660 | 3681 |
store_freg(f1, o->out); |
3661 |
store_freg((f1 + 2) & 15, o->out2);
|
|
3682 |
store_freg(f1 + 2, o->out2);
|
|
3662 | 3683 |
} |
3684 |
#define SPEC_wout_x1 SPEC_r1_f128 |
|
3663 | 3685 |
|
3664 | 3686 |
static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o) |
3665 | 3687 |
{ |
... | ... | |
3667 | 3689 |
store_reg32_i64(get_field(f, r1), o->out); |
3668 | 3690 |
} |
3669 | 3691 |
} |
3692 |
#define SPEC_wout_cond_r1r2_32 0 |
|
3670 | 3693 |
|
3671 | 3694 |
static void wout_cond_e1e2(DisasContext *s, DisasFields *f, DisasOps *o) |
3672 | 3695 |
{ |
... | ... | |
3674 | 3697 |
store_freg32_i64(get_field(f, r1), o->out); |
3675 | 3698 |
} |
3676 | 3699 |
} |
3700 |
#define SPEC_wout_cond_e1e2 0 |
|
3677 | 3701 |
|
3678 | 3702 |
static void wout_m1_8(DisasContext *s, DisasFields *f, DisasOps *o) |
3679 | 3703 |
{ |
3680 | 3704 |
tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s)); |
3681 | 3705 |
} |
3706 |
#define SPEC_wout_m1_8 0 |
|
3682 | 3707 |
|
3683 | 3708 |
static void wout_m1_16(DisasContext *s, DisasFields *f, DisasOps *o) |
3684 | 3709 |
{ |
3685 | 3710 |
tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s)); |
3686 | 3711 |
} |
3712 |
#define SPEC_wout_m1_16 0 |
|
3687 | 3713 |
|
3688 | 3714 |
static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o) |
3689 | 3715 |
{ |
3690 | 3716 |
tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s)); |
3691 | 3717 |
} |
3718 |
#define SPEC_wout_m1_32 0 |
|
3692 | 3719 |
|
3693 | 3720 |
static void wout_m1_64(DisasContext *s, DisasFields *f, DisasOps *o) |
3694 | 3721 |
{ |
3695 | 3722 |
tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s)); |
3696 | 3723 |
} |
3724 |
#define SPEC_wout_m1_64 0 |
|
3697 | 3725 |
|
3698 | 3726 |
static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o) |
3699 | 3727 |
{ |
3700 | 3728 |
tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s)); |
3701 | 3729 |
} |
3730 |
#define SPEC_wout_m2_32 0 |
|
3702 | 3731 |
|
3703 | 3732 |
/* ====================================================================== */ |
3704 | 3733 |
/* The "INput 1" generators. These load the first operand to an insn. */ |
... | ... | |
3707 | 3736 |
{ |
3708 | 3737 |
o->in1 = load_reg(get_field(f, r1)); |
3709 | 3738 |
} |
3739 |
#define SPEC_in1_r1 0 |
|
3710 | 3740 |
|
3711 | 3741 |
static void in1_r1_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3712 | 3742 |
{ |
3713 | 3743 |
o->in1 = regs[get_field(f, r1)]; |
3714 | 3744 |
o->g_in1 = true; |
3715 | 3745 |
} |
3746 |
#define SPEC_in1_r1_o 0 |
|
3716 | 3747 |
|
3717 | 3748 |
static void in1_r1_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
3718 | 3749 |
{ |
3719 | 3750 |
o->in1 = tcg_temp_new_i64(); |
3720 | 3751 |
tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1)]); |
3721 | 3752 |
} |
3753 |
#define SPEC_in1_r1_32s 0 |
|
3722 | 3754 |
|
3723 | 3755 |
static void in1_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
3724 | 3756 |
{ |
3725 | 3757 |
o->in1 = tcg_temp_new_i64(); |
3726 | 3758 |
tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1)]); |
3727 | 3759 |
} |
3760 |
#define SPEC_in1_r1_32u 0 |
|
3728 | 3761 |
|
3729 | 3762 |
static void in1_r1_sr32(DisasContext *s, DisasFields *f, DisasOps *o) |
3730 | 3763 |
{ |
3731 | 3764 |
o->in1 = tcg_temp_new_i64(); |
3732 | 3765 |
tcg_gen_shri_i64(o->in1, regs[get_field(f, r1)], 32); |
3733 | 3766 |
} |
3767 |
#define SPEC_in1_r1_sr32 0 |
|
3734 | 3768 |
|
3735 | 3769 |
static void in1_r1p1(DisasContext *s, DisasFields *f, DisasOps *o) |
3736 | 3770 |
{ |
3737 |
/* ??? Specification exception: r1 must be even. */ |
|
3738 |
int r1 = get_field(f, r1); |
|
3739 |
o->in1 = load_reg((r1 + 1) & 15); |
|
3771 |
o->in1 = load_reg(get_field(f, r1) + 1); |
|
3740 | 3772 |
} |
3773 |
#define SPEC_in1_r1p1 SPEC_r1_even |
|
3741 | 3774 |
|
3742 | 3775 |
static void in1_r1p1_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
3743 | 3776 |
{ |
3744 |
/* ??? Specification exception: r1 must be even. */ |
|
3745 |
int r1 = get_field(f, r1); |
|
3746 | 3777 |
o->in1 = tcg_temp_new_i64(); |
3747 |
tcg_gen_ext32s_i64(o->in1, regs[(r1 + 1) & 15]);
|
|
3778 |
tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1) + 1]);
|
|
3748 | 3779 |
} |
3780 |
#define SPEC_in1_r1p1_32s SPEC_r1_even |
|
3749 | 3781 |
|
3750 | 3782 |
static void in1_r1p1_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
3751 | 3783 |
{ |
3752 |
/* ??? Specification exception: r1 must be even. */ |
|
3753 |
int r1 = get_field(f, r1); |
|
3754 | 3784 |
o->in1 = tcg_temp_new_i64(); |
3755 |
tcg_gen_ext32u_i64(o->in1, regs[(r1 + 1) & 15]);
|
|
3785 |
tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1) + 1]);
|
|
3756 | 3786 |
} |
3787 |
#define SPEC_in1_r1p1_32u SPEC_r1_even |
|
3757 | 3788 |
|
3758 | 3789 |
static void in1_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o) |
3759 | 3790 |
{ |
3760 |
/* ??? Specification exception: r1 must be even. */ |
|
3761 | 3791 |
int r1 = get_field(f, r1); |
3762 | 3792 |
o->in1 = tcg_temp_new_i64(); |
3763 | 3793 |
tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]); |
3764 | 3794 |
} |
3795 |
#define SPEC_in1_r1_D32 SPEC_r1_even |
|
3765 | 3796 |
|
3766 | 3797 |
static void in1_r2(DisasContext *s, DisasFields *f, DisasOps *o) |
3767 | 3798 |
{ |
3768 | 3799 |
o->in1 = load_reg(get_field(f, r2)); |
3769 | 3800 |
} |
3801 |
#define SPEC_in1_r2 0 |
|
3770 | 3802 |
|
3771 | 3803 |
static void in1_r3(DisasContext *s, DisasFields *f, DisasOps *o) |
3772 | 3804 |
{ |
3773 | 3805 |
o->in1 = load_reg(get_field(f, r3)); |
3774 | 3806 |
} |
3807 |
#define SPEC_in1_r3 0 |
|
3775 | 3808 |
|
3776 | 3809 |
static void in1_r3_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3777 | 3810 |
{ |
3778 | 3811 |
o->in1 = regs[get_field(f, r3)]; |
3779 | 3812 |
o->g_in1 = true; |
3780 | 3813 |
} |
3814 |
#define SPEC_in1_r3_o 0 |
|
3781 | 3815 |
|
3782 | 3816 |
static void in1_r3_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
3783 | 3817 |
{ |
3784 | 3818 |
o->in1 = tcg_temp_new_i64(); |
3785 | 3819 |
tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r3)]); |
3786 | 3820 |
} |
3821 |
#define SPEC_in1_r3_32s 0 |
|
3787 | 3822 |
|
3788 | 3823 |
static void in1_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
3789 | 3824 |
{ |
3790 | 3825 |
o->in1 = tcg_temp_new_i64(); |
3791 | 3826 |
tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r3)]); |
3792 | 3827 |
} |
3828 |
#define SPEC_in1_r3_32u 0 |
|
3793 | 3829 |
|
3794 | 3830 |
static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o) |
3795 | 3831 |
{ |
3796 | 3832 |
o->in1 = load_freg32_i64(get_field(f, r1)); |
3797 | 3833 |
} |
3834 |
#define SPEC_in1_e1 0 |
|
3798 | 3835 |
|
3799 | 3836 |
static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3800 | 3837 |
{ |
3801 | 3838 |
o->in1 = fregs[get_field(f, r1)]; |
3802 | 3839 |
o->g_in1 = true; |
3803 | 3840 |
} |
3841 |
#define SPEC_in1_f1_o 0 |
|
3804 | 3842 |
|
3805 | 3843 |
static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3806 | 3844 |
{ |
3807 |
/* ??? Specification exception: r1 must be < 14. */ |
|
3808 | 3845 |
int r1 = get_field(f, r1); |
3809 | 3846 |
o->out = fregs[r1]; |
3810 |
o->out2 = fregs[(r1 + 2) & 15];
|
|
3847 |
o->out2 = fregs[r1 + 2];
|
|
3811 | 3848 |
o->g_out = o->g_out2 = true; |
3812 | 3849 |
} |
3850 |
#define SPEC_in1_x1_o SPEC_r1_f128 |
|
3813 | 3851 |
|
3814 | 3852 |
static void in1_f3_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3815 | 3853 |
{ |
3816 | 3854 |
o->in1 = fregs[get_field(f, r3)]; |
3817 | 3855 |
o->g_in1 = true; |
3818 | 3856 |
} |
3857 |
#define SPEC_in1_f3_o 0 |
|
3819 | 3858 |
|
3820 | 3859 |
static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o) |
3821 | 3860 |
{ |
3822 | 3861 |
o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1)); |
3823 | 3862 |
} |
3863 |
#define SPEC_in1_la1 0 |
|
3824 | 3864 |
|
3825 | 3865 |
static void in1_la2(DisasContext *s, DisasFields *f, DisasOps *o) |
3826 | 3866 |
{ |
3827 | 3867 |
int x2 = have_field(f, x2) ? get_field(f, x2) : 0; |
3828 | 3868 |
o->addr1 = get_address(s, x2, get_field(f, b2), get_field(f, d2)); |
3829 | 3869 |
} |
3870 |
#define SPEC_in1_la2 0 |
|
3830 | 3871 |
|
3831 | 3872 |
static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o) |
3832 | 3873 |
{ |
... | ... | |
3834 | 3875 |
o->in1 = tcg_temp_new_i64(); |
3835 | 3876 |
tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s)); |
3836 | 3877 |
} |
3878 |
#define SPEC_in1_m1_8u 0 |
|
3837 | 3879 |
|
3838 | 3880 |
static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o) |
3839 | 3881 |
{ |
... | ... | |
3841 | 3883 |
o->in1 = tcg_temp_new_i64(); |
3842 | 3884 |
tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s)); |
3843 | 3885 |
} |
3886 |
#define SPEC_in1_m1_16s 0 |
|
3844 | 3887 |
|
3845 | 3888 |
static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o) |
3846 | 3889 |
{ |
... | ... | |
3848 | 3891 |
o->in1 = tcg_temp_new_i64(); |
3849 | 3892 |
tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s)); |
3850 | 3893 |
} |
3894 |
#define SPEC_in1_m1_16u 0 |
|
3851 | 3895 |
|
3852 | 3896 |
static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
3853 | 3897 |
{ |
... | ... | |
3855 | 3899 |
o->in1 = tcg_temp_new_i64(); |
3856 | 3900 |
tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s)); |
3857 | 3901 |
} |
3902 |
#define SPEC_in1_m1_32s 0 |
|
3858 | 3903 |
|
3859 | 3904 |
static void in1_m1_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
3860 | 3905 |
{ |
... | ... | |
3862 | 3907 |
o->in1 = tcg_temp_new_i64(); |
3863 | 3908 |
tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s)); |
3864 | 3909 |
} |
3910 |
#define SPEC_in1_m1_32u 0 |
|
3865 | 3911 |
|
3866 | 3912 |
static void in1_m1_64(DisasContext *s, DisasFields *f, DisasOps *o) |
3867 | 3913 |
{ |
... | ... | |
3869 | 3915 |
o->in1 = tcg_temp_new_i64(); |
3870 | 3916 |
tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s)); |
3871 | 3917 |
} |
3918 |
#define SPEC_in1_m1_64 0 |
|
3872 | 3919 |
|
3873 | 3920 |
/* ====================================================================== */ |
3874 | 3921 |
/* The "INput 2" generators. These load the second operand to an insn. */ |
... | ... | |
3878 | 3925 |
o->in2 = regs[get_field(f, r1)]; |
3879 | 3926 |
o->g_in2 = true; |
3880 | 3927 |
} |
3928 |
#define SPEC_in2_r1_o 0 |
|
3881 | 3929 |
|
3882 | 3930 |
static void in2_r1_16u(DisasContext *s, DisasFields *f, DisasOps *o) |
3883 | 3931 |
{ |
3884 | 3932 |
o->in2 = tcg_temp_new_i64(); |
3885 | 3933 |
tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r1)]); |
3886 | 3934 |
} |
3935 |
#define SPEC_in2_r1_16u 0 |
|
3887 | 3936 |
|
3888 | 3937 |
static void in2_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
3889 | 3938 |
{ |
3890 | 3939 |
o->in2 = tcg_temp_new_i64(); |
3891 | 3940 |
tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r1)]); |
3892 | 3941 |
} |
3942 |
#define SPEC_in2_r1_32u 0 |
|
3893 | 3943 |
|
3894 | 3944 |
static void in2_r2(DisasContext *s, DisasFields *f, DisasOps *o) |
3895 | 3945 |
{ |
3896 | 3946 |
o->in2 = load_reg(get_field(f, r2)); |
3897 | 3947 |
} |
3948 |
#define SPEC_in2_r2 0 |
|
3898 | 3949 |
|
3899 | 3950 |
static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3900 | 3951 |
{ |
3901 | 3952 |
o->in2 = regs[get_field(f, r2)]; |
3902 | 3953 |
o->g_in2 = true; |
3903 | 3954 |
} |
3955 |
#define SPEC_in2_r2_o 0 |
|
3904 | 3956 |
|
3905 | 3957 |
static void in2_r2_nz(DisasContext *s, DisasFields *f, DisasOps *o) |
3906 | 3958 |
{ |
... | ... | |
3909 | 3961 |
o->in2 = load_reg(r2); |
3910 | 3962 |
} |
3911 | 3963 |
} |
3964 |
#define SPEC_in2_r2_nz 0 |
|
3912 | 3965 |
|
3913 | 3966 |
static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o) |
3914 | 3967 |
{ |
3915 | 3968 |
o->in2 = tcg_temp_new_i64(); |
3916 | 3969 |
tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]); |
3917 | 3970 |
} |
3971 |
#define SPEC_in2_r2_8s 0 |
|
3918 | 3972 |
|
3919 | 3973 |
static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o) |
3920 | 3974 |
{ |
3921 | 3975 |
o->in2 = tcg_temp_new_i64(); |
3922 | 3976 |
tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]); |
3923 | 3977 |
} |
3978 |
#define SPEC_in2_r2_8u 0 |
|
3924 | 3979 |
|
3925 | 3980 |
static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o) |
3926 | 3981 |
{ |
3927 | 3982 |
o->in2 = tcg_temp_new_i64(); |
3928 | 3983 |
tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]); |
3929 | 3984 |
} |
3985 |
#define SPEC_in2_r2_16s 0 |
|
3930 | 3986 |
|
3931 | 3987 |
static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o) |
3932 | 3988 |
{ |
3933 | 3989 |
o->in2 = tcg_temp_new_i64(); |
3934 | 3990 |
tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]); |
3935 | 3991 |
} |
3992 |
#define SPEC_in2_r2_16u 0 |
|
3936 | 3993 |
|
3937 | 3994 |
static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o) |
3938 | 3995 |
{ |
3939 | 3996 |
o->in2 = load_reg(get_field(f, r3)); |
3940 | 3997 |
} |
3998 |
#define SPEC_in2_r3 0 |
|
3941 | 3999 |
|
3942 | 4000 |
static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
3943 | 4001 |
{ |
3944 | 4002 |
o->in2 = tcg_temp_new_i64(); |
3945 | 4003 |
tcg_gen_ext32s_i64(o->in2, regs[get_field(f, r2)]); |
3946 | 4004 |
} |
4005 |
#define SPEC_in2_r2_32s 0 |
|
3947 | 4006 |
|
3948 | 4007 |
static void in2_r2_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
3949 | 4008 |
{ |
3950 | 4009 |
o->in2 = tcg_temp_new_i64(); |
3951 | 4010 |
tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r2)]); |
3952 | 4011 |
} |
4012 |
#define SPEC_in2_r2_32u 0 |
|
3953 | 4013 |
|
3954 | 4014 |
static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o) |
3955 | 4015 |
{ |
3956 | 4016 |
o->in2 = load_freg32_i64(get_field(f, r2)); |
3957 | 4017 |
} |
4018 |
#define SPEC_in2_e2 0 |
|
3958 | 4019 |
|
3959 | 4020 |
static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3960 | 4021 |
{ |
3961 | 4022 |
o->in2 = fregs[get_field(f, r2)]; |
3962 | 4023 |
o->g_in2 = true; |
3963 | 4024 |
} |
4025 |
#define SPEC_in2_f2_o 0 |
|
3964 | 4026 |
|
3965 | 4027 |
static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o) |
3966 | 4028 |
{ |
3967 |
/* ??? Specification exception: r1 must be < 14. */ |
|
3968 | 4029 |
int r2 = get_field(f, r2); |
3969 | 4030 |
o->in1 = fregs[r2]; |
3970 |
o->in2 = fregs[(r2 + 2) & 15];
|
|
4031 |
o->in2 = fregs[r2 + 2];
|
|
3971 | 4032 |
o->g_in1 = o->g_in2 = true; |
3972 | 4033 |
} |
4034 |
#define SPEC_in2_x2_o SPEC_r2_f128 |
|
3973 | 4035 |
|
3974 | 4036 |
static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o) |
3975 | 4037 |
{ |
3976 | 4038 |
o->in2 = get_address(s, 0, get_field(f, r2), 0); |
3977 | 4039 |
} |
4040 |
#define SPEC_in2_ra2 0 |
|
3978 | 4041 |
|
3979 | 4042 |
static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o) |
3980 | 4043 |
{ |
3981 | 4044 |
int x2 = have_field(f, x2) ? get_field(f, x2) : 0; |
3982 | 4045 |
o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2)); |
3983 | 4046 |
} |
4047 |
#define SPEC_in2_a2 0 |
|
3984 | 4048 |
|
3985 | 4049 |
static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o) |
3986 | 4050 |
{ |
3987 | 4051 |
o->in2 = tcg_const_i64(s->pc + (int64_t)get_field(f, i2) * 2); |
3988 | 4052 |
} |
4053 |
#define SPEC_in2_ri2 0 |
|
3989 | 4054 |
|
3990 | 4055 |
static void in2_sh32(DisasContext *s, DisasFields *f, DisasOps *o) |
3991 | 4056 |
{ |
3992 | 4057 |
help_l2_shift(s, f, o, 31); |
3993 | 4058 |
} |
4059 |
#define SPEC_in2_sh32 0 |
|
3994 | 4060 |
|
3995 | 4061 |
static void in2_sh64(DisasContext *s, DisasFields *f, DisasOps *o) |
3996 | 4062 |
{ |
3997 | 4063 |
help_l2_shift(s, f, o, 63); |
3998 | 4064 |
} |
4065 |
#define SPEC_in2_sh64 0 |
|
3999 | 4066 |
|
4000 | 4067 |
static void in2_m2_8u(DisasContext *s, DisasFields *f, DisasOps *o) |
4001 | 4068 |
{ |
4002 | 4069 |
in2_a2(s, f, o); |
4003 | 4070 |
tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s)); |
4004 | 4071 |
} |
4072 |
#define SPEC_in2_m2_8u 0 |
|
4005 | 4073 |
|
4006 | 4074 |
static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o) |
4007 | 4075 |
{ |
4008 | 4076 |
in2_a2(s, f, o); |
4009 | 4077 |
tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s)); |
4010 | 4078 |
} |
4079 |
#define SPEC_in2_m2_16s 0 |
|
4011 | 4080 |
|
4012 | 4081 |
static void in2_m2_16u(DisasContext *s, DisasFields *f, DisasOps *o) |
4013 | 4082 |
{ |
4014 | 4083 |
in2_a2(s, f, o); |
4015 | 4084 |
tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s)); |
4016 | 4085 |
} |
4086 |
#define SPEC_in2_m2_16u 0 |
|
4017 | 4087 |
|
4018 | 4088 |
static void in2_m2_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
4019 | 4089 |
{ |
4020 | 4090 |
in2_a2(s, f, o); |
4021 | 4091 |
tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s)); |
4022 | 4092 |
} |
4093 |
#define SPEC_in2_m2_32s 0 |
|
4023 | 4094 |
|
4024 | 4095 |
static void in2_m2_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
4025 | 4096 |
{ |
4026 | 4097 |
in2_a2(s, f, o); |
4027 | 4098 |
tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s)); |
4028 | 4099 |
} |
4100 |
#define SPEC_in2_m2_32u 0 |
|
4029 | 4101 |
|
4030 | 4102 |
static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o) |
4031 | 4103 |
{ |
4032 | 4104 |
in2_a2(s, f, o); |
4033 | 4105 |
tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s)); |
4034 | 4106 |
} |
4107 |
#define SPEC_in2_m2_64 0 |
|
4035 | 4108 |
|
4036 | 4109 |
static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o) |
4037 | 4110 |
{ |
4038 | 4111 |
in2_ri2(s, f, o); |
4039 | 4112 |
tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s)); |
4040 | 4113 |
} |
4114 |
#define SPEC_in2_mri2_16u 0 |
|
4041 | 4115 |
|
4042 | 4116 |
static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o) |
4043 | 4117 |
{ |
4044 | 4118 |
in2_ri2(s, f, o); |
4045 | 4119 |
tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s)); |
4046 | 4120 |
} |
4121 |
#define SPEC_in2_mri2_32s 0 |
|
4047 | 4122 |
|
4048 | 4123 |
static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
4049 | 4124 |
{ |
4050 | 4125 |
in2_ri2(s, f, o); |
4051 | 4126 |
tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s)); |
4052 | 4127 |
} |
4128 |
#define SPEC_in2_mri2_32u 0 |
|
4053 | 4129 |
|
4054 | 4130 |
static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o) |
4055 | 4131 |
{ |
4056 | 4132 |
in2_ri2(s, f, o); |
4057 | 4133 |
tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s)); |
4058 | 4134 |
} |
4135 |
#define SPEC_in2_mri2_64 0 |
|
4059 | 4136 |
|
4060 | 4137 |
static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o) |
4061 | 4138 |
{ |
4062 | 4139 |
o->in2 = tcg_const_i64(get_field(f, i2)); |
4063 | 4140 |
} |
4141 |
#define SPEC_in2_i2 0 |
|
4064 | 4142 |
|
4065 | 4143 |
static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o) |
4066 | 4144 |
{ |
4067 | 4145 |
o->in2 = tcg_const_i64((uint8_t)get_field(f, i2)); |
4068 | 4146 |
} |
4147 |
#define SPEC_in2_i2_8u 0 |
|
4069 | 4148 |
|
4070 | 4149 |
static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o) |
4071 | 4150 |
{ |
4072 | 4151 |
o->in2 = tcg_const_i64((uint16_t)get_field(f, i2)); |
4073 | 4152 |
} |
4153 |
#define SPEC_in2_i2_16u 0 |
|
4074 | 4154 |
|
4075 | 4155 |
static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o) |
4076 | 4156 |
{ |
4077 | 4157 |
o->in2 = tcg_const_i64((uint32_t)get_field(f, i2)); |
4078 | 4158 |
} |
4159 |
#define SPEC_in2_i2_32u 0 |
|
4079 | 4160 |
|
4080 | 4161 |
static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o) |
4081 | 4162 |
{ |
4082 | 4163 |
uint64_t i2 = (uint16_t)get_field(f, i2); |
4083 | 4164 |
o->in2 = tcg_const_i64(i2 << s->insn->data); |
4084 | 4165 |
} |
4166 |
#define SPEC_in2_i2_16u_shl 0 |
|
4085 | 4167 |
|
4086 | 4168 |
static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o) |
4087 | 4169 |
{ |
4088 | 4170 |
uint64_t i2 = (uint32_t)get_field(f, i2); |
4089 | 4171 |
o->in2 = tcg_const_i64(i2 << s->insn->data); |
4090 | 4172 |
} |
4173 |
#define SPEC_in2_i2_32u_shl 0 |
|
4091 | 4174 |
|
4092 | 4175 |
/* ====================================================================== */ |
4093 | 4176 |
|
... | ... | |
4106 | 4189 |
}; |
4107 | 4190 |
|
4108 | 4191 |
#undef D |
4109 |
#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \ |
|
4110 |
.opc = OPC, \ |
|
4111 |
.fmt = FMT_##FT, \ |
|
4112 |
.fac = FAC_##FC, \ |
|
4113 |
.name = #NM, \ |
|
4114 |
.help_in1 = in1_##I1, \ |
|
4115 |
.help_in2 = in2_##I2, \ |
|
4116 |
.help_prep = prep_##P, \ |
|
4117 |
.help_wout = wout_##W, \ |
|
4118 |
.help_cout = cout_##CC, \ |
|
4119 |
.help_op = op_##OP, \ |
|
4120 |
.data = D \ |
|
4192 |
#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \ |
|
4193 |
.opc = OPC, \ |
|
4194 |
.fmt = FMT_##FT, \ |
|
4195 |
.fac = FAC_##FC, \ |
|
4196 |
.spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \ |
|
4197 |
.name = #NM, \ |
|
4198 |
.help_in1 = in1_##I1, \ |
|
4199 |
.help_in2 = in2_##I2, \ |
|
4200 |
.help_prep = prep_##P, \ |
|
4201 |
.help_wout = wout_##W, \ |
|
4202 |
.help_cout = cout_##CC, \ |
|
4203 |
.help_op = op_##OP, \ |
|
4204 |
.data = D \ |
|
4121 | 4205 |
}, |
4122 | 4206 |
|
4123 | 4207 |
/* Allow 0 to be used for NULL in the table below. */ |
... | ... | |
4128 | 4212 |
#define cout_0 NULL |
4129 | 4213 |
#define op_0 NULL |
4130 | 4214 |
|
4215 |
#define SPEC_in1_0 0 |
|
4216 |
#define SPEC_in2_0 0 |
|
4217 |
#define SPEC_prep_0 0 |
|
4218 |
#define SPEC_wout_0 0 |
|
4219 |
|
|
4131 | 4220 |
static const DisasInsn insn_info[] = { |
4132 | 4221 |
#include "insn-data.def" |
4133 | 4222 |
}; |
... | ... | |
4295 | 4384 |
return EXIT_NORETURN; |
4296 | 4385 |
} |
4297 | 4386 |
|
4387 |
/* Check for insn specification exceptions. */ |
|
4388 |
if (insn->spec) { |
|
4389 |
int spec = insn->spec, excp = 0, r; |
|
4390 |
|
|
4391 |
if (spec & SPEC_r1_even) { |
|
4392 |
r = get_field(&f, r1); |
|
4393 |
if (r & 1) { |
|
4394 |
excp = PGM_SPECIFICATION; |
|
4395 |
} |
|
4396 |
} |
|
4397 |
if (spec & SPEC_r2_even) { |
|
4398 |
r = get_field(&f, r2); |
|
4399 |
if (r & 1) { |
|
4400 |
excp = PGM_SPECIFICATION; |
|
4401 |
} |
|
4402 |
} |
|
4403 |
if (spec & SPEC_r1_f128) { |
|
4404 |
r = get_field(&f, r1); |
|
4405 |
if (r > 13) { |
|
4406 |
excp = PGM_SPECIFICATION; |
|
4407 |
} |
|
4408 |
} |
|
4409 |
if (spec & SPEC_r2_f128) { |
|
4410 |
r = get_field(&f, r2); |
|
4411 |
if (r > 13) { |
|
4412 |
excp = PGM_SPECIFICATION; |
|
4413 |
} |
|
4414 |
} |
|
4415 |
if (excp) { |
|
4416 |
gen_program_exception(s, excp); |
|
4417 |
return EXIT_NORETURN; |
|
4418 |
} |
|
4419 |
} |
|
4420 |
|
|
4298 | 4421 |
/* Set up the strutures we use to communicate with the helpers. */ |
4299 | 4422 |
s->insn = insn; |
4300 | 4423 |
s->fields = &f; |
Also available in: Unified diff