qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

target/arm: Convert Neon VTRN to decodetree

Convert the Neon VTRN insn to decodetree. This is the last insn in the
Neon data-processing group, so we can remove all the now-unused old
decoder framework.

It's possible that there's a more efficient implementation of
VTRN, but for this conversion we just copy the existing approach.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200616170844.13318-21-peter.maydell@linaro.org

+93 -362
+1 -1
target/arm/neon-dp.decode
··· 489 489 VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc 490 490 491 491 VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc 492 - 492 + VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc 493 493 VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc 494 494 VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc 495 495
+90
target/arm/translate-neon.inc.c
··· 3968 3968 3969 3969 return true; 3970 3970 } 3971 + static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1) 3972 + { 3973 + TCGv_i32 rd, tmp; 3974 + 3975 + rd = tcg_temp_new_i32(); 3976 + tmp = tcg_temp_new_i32(); 3977 + 3978 + tcg_gen_shli_i32(rd, t0, 8); 3979 + tcg_gen_andi_i32(rd, rd, 0xff00ff00); 3980 + tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); 3981 + tcg_gen_or_i32(rd, rd, tmp); 3982 + 3983 + tcg_gen_shri_i32(t1, t1, 8); 3984 + tcg_gen_andi_i32(t1, t1, 0x00ff00ff); 3985 + tcg_gen_andi_i32(tmp, t0, 0xff00ff00); 3986 + tcg_gen_or_i32(t1, t1, tmp); 3987 + tcg_gen_mov_i32(t0, rd); 3988 + 3989 + tcg_temp_free_i32(tmp); 3990 + tcg_temp_free_i32(rd); 3991 + } 3992 + 3993 + static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1) 3994 + { 3995 + TCGv_i32 rd, tmp; 3996 + 3997 + rd = tcg_temp_new_i32(); 3998 + tmp = tcg_temp_new_i32(); 3999 + 4000 + tcg_gen_shli_i32(rd, t0, 16); 4001 + tcg_gen_andi_i32(tmp, t1, 0xffff); 4002 + tcg_gen_or_i32(rd, rd, tmp); 4003 + tcg_gen_shri_i32(t1, t1, 16); 4004 + tcg_gen_andi_i32(tmp, t0, 0xffff0000); 4005 + tcg_gen_or_i32(t1, t1, tmp); 4006 + tcg_gen_mov_i32(t0, rd); 4007 + 4008 + tcg_temp_free_i32(tmp); 4009 + tcg_temp_free_i32(rd); 4010 + } 4011 + 4012 + static bool trans_VTRN(DisasContext *s, arg_2misc *a) 4013 + { 4014 + TCGv_i32 tmp, tmp2; 4015 + int pass; 4016 + 4017 + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 4018 + return false; 4019 + } 4020 + 4021 + /* UNDEF accesses to D16-D31 if they don't exist. */ 4022 + if (!dc_isar_feature(aa32_simd_r32, s) && 4023 + ((a->vd | a->vm) & 0x10)) { 4024 + return false; 4025 + } 4026 + 4027 + if ((a->vd | a->vm) & a->q) { 4028 + return false; 4029 + } 4030 + 4031 + if (a->size == 3) { 4032 + return false; 4033 + } 4034 + 4035 + if (!vfp_access_check(s)) { 4036 + return true; 4037 + } 4038 + 4039 + if (a->size == 2) { 4040 + for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) { 4041 + tmp = neon_load_reg(a->vm, pass); 4042 + tmp2 = neon_load_reg(a->vd, pass + 1); 4043 + neon_store_reg(a->vm, pass, tmp2); 4044 + neon_store_reg(a->vd, pass + 1, tmp); 4045 + } 4046 + } else { 4047 + for (pass = 0; pass < (a->q ? 4 : 2); pass++) { 4048 + tmp = neon_load_reg(a->vm, pass); 4049 + tmp2 = neon_load_reg(a->vd, pass); 4050 + if (a->size == 0) { 4051 + gen_neon_trn_u8(tmp, tmp2); 4052 + } else { 4053 + gen_neon_trn_u16(tmp, tmp2); 4054 + } 4055 + neon_store_reg(a->vm, pass, tmp2); 4056 + neon_store_reg(a->vd, pass, tmp); 4057 + } 4058 + } 4059 + return true; 4060 + }
+2 -361
target/arm/translate.c
··· 2934 2934 gen_rfe(s, pc, load_cpu_field(spsr)); 2935 2935 } 2936 2936 2937 - static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1) 2938 - { 2939 - TCGv_i32 rd, tmp; 2940 - 2941 - rd = tcg_temp_new_i32(); 2942 - tmp = tcg_temp_new_i32(); 2943 - 2944 - tcg_gen_shli_i32(rd, t0, 8); 2945 - tcg_gen_andi_i32(rd, rd, 0xff00ff00); 2946 - tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); 2947 - tcg_gen_or_i32(rd, rd, tmp); 2948 - 2949 - tcg_gen_shri_i32(t1, t1, 8); 2950 - tcg_gen_andi_i32(t1, t1, 0x00ff00ff); 2951 - tcg_gen_andi_i32(tmp, t0, 0xff00ff00); 2952 - tcg_gen_or_i32(t1, t1, tmp); 2953 - tcg_gen_mov_i32(t0, rd); 2954 - 2955 - tcg_temp_free_i32(tmp); 2956 - tcg_temp_free_i32(rd); 2957 - } 2958 - 2959 - static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1) 2960 - { 2961 - TCGv_i32 rd, tmp; 2962 - 2963 - rd = tcg_temp_new_i32(); 2964 - tmp = tcg_temp_new_i32(); 2965 - 2966 - tcg_gen_shli_i32(rd, t0, 16); 2967 - tcg_gen_andi_i32(tmp, t1, 0xffff); 2968 - tcg_gen_or_i32(rd, rd, tmp); 2969 - tcg_gen_shri_i32(t1, t1, 16); 2970 - tcg_gen_andi_i32(tmp, t0, 0xffff0000); 2971 - tcg_gen_or_i32(t1, t1, tmp); 2972 - tcg_gen_mov_i32(t0, rd); 2973 - 2974 - tcg_temp_free_i32(tmp); 2975 - tcg_temp_free_i32(rd); 2976 - } 2977 - 2978 - /* Symbolic constants for op fields for Neon 2-register miscellaneous. 2979 - * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B 2980 - * table A7-13. 2981 - */ 2982 - #define NEON_2RM_VREV64 0 2983 - #define NEON_2RM_VREV32 1 2984 - #define NEON_2RM_VREV16 2 2985 - #define NEON_2RM_VPADDL 4 2986 - #define NEON_2RM_VPADDL_U 5 2987 - #define NEON_2RM_AESE 6 /* Includes AESD */ 2988 - #define NEON_2RM_AESMC 7 /* Includes AESIMC */ 2989 - #define NEON_2RM_VCLS 8 2990 - #define NEON_2RM_VCLZ 9 2991 - #define NEON_2RM_VCNT 10 2992 - #define NEON_2RM_VMVN 11 2993 - #define NEON_2RM_VPADAL 12 2994 - #define NEON_2RM_VPADAL_U 13 2995 - #define NEON_2RM_VQABS 14 2996 - #define NEON_2RM_VQNEG 15 2997 - #define NEON_2RM_VCGT0 16 2998 - #define NEON_2RM_VCGE0 17 2999 - #define NEON_2RM_VCEQ0 18 3000 - #define NEON_2RM_VCLE0 19 3001 - #define NEON_2RM_VCLT0 20 3002 - #define NEON_2RM_SHA1H 21 3003 - #define NEON_2RM_VABS 22 3004 - #define NEON_2RM_VNEG 23 3005 - #define NEON_2RM_VCGT0_F 24 3006 - #define NEON_2RM_VCGE0_F 25 3007 - #define NEON_2RM_VCEQ0_F 26 3008 - #define NEON_2RM_VCLE0_F 27 3009 - #define NEON_2RM_VCLT0_F 28 3010 - #define NEON_2RM_VABS_F 30 3011 - #define NEON_2RM_VNEG_F 31 3012 - #define NEON_2RM_VSWP 32 3013 - #define NEON_2RM_VTRN 33 3014 - #define NEON_2RM_VUZP 34 3015 - #define NEON_2RM_VZIP 35 3016 - #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ 3017 - #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ 3018 - #define NEON_2RM_VSHLL 38 3019 - #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */ 3020 - #define NEON_2RM_VRINTN 40 3021 - #define NEON_2RM_VRINTX 41 3022 - #define NEON_2RM_VRINTA 42 3023 - #define NEON_2RM_VRINTZ 43 3024 - #define NEON_2RM_VCVT_F16_F32 44 3025 - #define NEON_2RM_VRINTM 45 3026 - #define NEON_2RM_VCVT_F32_F16 46 3027 - #define NEON_2RM_VRINTP 47 3028 - #define NEON_2RM_VCVTAU 48 3029 - #define NEON_2RM_VCVTAS 49 3030 - #define NEON_2RM_VCVTNU 50 3031 - #define NEON_2RM_VCVTNS 51 3032 - #define NEON_2RM_VCVTPU 52 3033 - #define NEON_2RM_VCVTPS 53 3034 - #define NEON_2RM_VCVTMU 54 3035 - #define NEON_2RM_VCVTMS 55 3036 - #define NEON_2RM_VRECPE 56 3037 - #define NEON_2RM_VRSQRTE 57 3038 - #define NEON_2RM_VRECPE_F 58 3039 - #define NEON_2RM_VRSQRTE_F 59 3040 - #define NEON_2RM_VCVT_FS 60 3041 - #define NEON_2RM_VCVT_FU 61 3042 - #define NEON_2RM_VCVT_SF 62 3043 - #define NEON_2RM_VCVT_UF 63 3044 - 3045 - /* Each entry in this array has bit n set if the insn allows 3046 - * size value n (otherwise it will UNDEF). Since unallocated 3047 - * op values will have no bits set they always UNDEF. 3048 - */ 3049 - static const uint8_t neon_2rm_sizes[] = { 3050 - [NEON_2RM_VREV64] = 0x7, 3051 - [NEON_2RM_VREV32] = 0x3, 3052 - [NEON_2RM_VREV16] = 0x1, 3053 - [NEON_2RM_VPADDL] = 0x7, 3054 - [NEON_2RM_VPADDL_U] = 0x7, 3055 - [NEON_2RM_AESE] = 0x1, 3056 - [NEON_2RM_AESMC] = 0x1, 3057 - [NEON_2RM_VCLS] = 0x7, 3058 - [NEON_2RM_VCLZ] = 0x7, 3059 - [NEON_2RM_VCNT] = 0x1, 3060 - [NEON_2RM_VMVN] = 0x1, 3061 - [NEON_2RM_VPADAL] = 0x7, 3062 - [NEON_2RM_VPADAL_U] = 0x7, 3063 - [NEON_2RM_VQABS] = 0x7, 3064 - [NEON_2RM_VQNEG] = 0x7, 3065 - [NEON_2RM_VCGT0] = 0x7, 3066 - [NEON_2RM_VCGE0] = 0x7, 3067 - [NEON_2RM_VCEQ0] = 0x7, 3068 - [NEON_2RM_VCLE0] = 0x7, 3069 - [NEON_2RM_VCLT0] = 0x7, 3070 - [NEON_2RM_SHA1H] = 0x4, 3071 - [NEON_2RM_VABS] = 0x7, 3072 - [NEON_2RM_VNEG] = 0x7, 3073 - [NEON_2RM_VCGT0_F] = 0x4, 3074 - [NEON_2RM_VCGE0_F] = 0x4, 3075 - [NEON_2RM_VCEQ0_F] = 0x4, 3076 - [NEON_2RM_VCLE0_F] = 0x4, 3077 - [NEON_2RM_VCLT0_F] = 0x4, 3078 - [NEON_2RM_VABS_F] = 0x4, 3079 - [NEON_2RM_VNEG_F] = 0x4, 3080 - [NEON_2RM_VSWP] = 0x1, 3081 - [NEON_2RM_VTRN] = 0x7, 3082 - [NEON_2RM_VUZP] = 0x7, 3083 - [NEON_2RM_VZIP] = 0x7, 3084 - [NEON_2RM_VMOVN] = 0x7, 3085 - [NEON_2RM_VQMOVN] = 0x7, 3086 - [NEON_2RM_VSHLL] = 0x7, 3087 - [NEON_2RM_SHA1SU1] = 0x4, 3088 - [NEON_2RM_VRINTN] = 0x4, 3089 - [NEON_2RM_VRINTX] = 0x4, 3090 - [NEON_2RM_VRINTA] = 0x4, 3091 - [NEON_2RM_VRINTZ] = 0x4, 3092 - [NEON_2RM_VCVT_F16_F32] = 0x2, 3093 - [NEON_2RM_VRINTM] = 0x4, 3094 - [NEON_2RM_VCVT_F32_F16] = 0x2, 3095 - [NEON_2RM_VRINTP] = 0x4, 3096 - [NEON_2RM_VCVTAU] = 0x4, 3097 - [NEON_2RM_VCVTAS] = 0x4, 3098 - [NEON_2RM_VCVTNU] = 0x4, 3099 - [NEON_2RM_VCVTNS] = 0x4, 3100 - [NEON_2RM_VCVTPU] = 0x4, 3101 - [NEON_2RM_VCVTPS] = 0x4, 3102 - [NEON_2RM_VCVTMU] = 0x4, 3103 - [NEON_2RM_VCVTMS] = 0x4, 3104 - [NEON_2RM_VRECPE] = 0x4, 3105 - [NEON_2RM_VRSQRTE] = 0x4, 3106 - [NEON_2RM_VRECPE_F] = 0x4, 3107 - [NEON_2RM_VRSQRTE_F] = 0x4, 3108 - [NEON_2RM_VCVT_FS] = 0x4, 3109 - [NEON_2RM_VCVT_FU] = 0x4, 3110 - [NEON_2RM_VCVT_SF] = 0x4, 3111 - [NEON_2RM_VCVT_UF] = 0x4, 3112 - }; 3113 - 3114 2937 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs, 3115 2938 uint32_t opr_sz, uint32_t max_sz, 3116 2939 gen_helper_gvec_3_ptr *fn) ··· 4820 4643 .vece = MO_64 }, 4821 4644 }; 4822 4645 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]); 4823 - } 4824 - 4825 - /* Translate a NEON data processing instruction. Return nonzero if the 4826 - instruction is invalid. 4827 - We process data in a mixture of 32-bit and 64-bit chunks. 4828 - Mostly we use 32-bit chunks so we can use normal scalar instructions. */ 4829 - 4830 - static int disas_neon_data_insn(DisasContext *s, uint32_t insn) 4831 - { 4832 - int op; 4833 - int q; 4834 - int rd, rm; 4835 - int size; 4836 - int pass; 4837 - int u; 4838 - TCGv_i32 tmp, tmp2; 4839 - 4840 - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 4841 - return 1; 4842 - } 4843 - 4844 - /* FIXME: this access check should not take precedence over UNDEF 4845 - * for invalid encodings; we will generate incorrect syndrome information 4846 - * for attempts to execute invalid vfp/neon encodings with FP disabled. 4847 - */ 4848 - if (s->fp_excp_el) { 4849 - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, 4850 - syn_simd_access_trap(1, 0xe, false), s->fp_excp_el); 4851 - return 0; 4852 - } 4853 - 4854 - if (!s->vfp_enabled) 4855 - return 1; 4856 - q = (insn & (1 << 6)) != 0; 4857 - u = (insn >> 24) & 1; 4858 - VFP_DREG_D(rd, insn); 4859 - VFP_DREG_M(rm, insn); 4860 - size = (insn >> 20) & 3; 4861 - 4862 - if ((insn & (1 << 23)) == 0) { 4863 - /* Three register same length: handled by decodetree */ 4864 - return 1; 4865 - } else if (insn & (1 << 4)) { 4866 - /* Two registers and shift or reg and imm: handled by decodetree */ 4867 - return 1; 4868 - } else { /* (insn & 0x00800010 == 0x00800000) */ 4869 - if (size != 3) { 4870 - /* 4871 - * Three registers of different lengths, or two registers and 4872 - * a scalar: handled by decodetree 4873 - */ 4874 - return 1; 4875 - } else { /* size == 3 */ 4876 - if (!u) { 4877 - /* Extract: handled by decodetree */ 4878 - return 1; 4879 - } else if ((insn & (1 << 11)) == 0) { 4880 - /* Two register misc. */ 4881 - op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf); 4882 - size = (insn >> 18) & 3; 4883 - /* UNDEF for unknown op values and bad op-size combinations */ 4884 - if ((neon_2rm_sizes[op] & (1 << size)) == 0) { 4885 - return 1; 4886 - } 4887 - if (q && ((rm | rd) & 1)) { 4888 - return 1; 4889 - } 4890 - switch (op) { 4891 - case NEON_2RM_VREV64: 4892 - case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U: 4893 - case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U: 4894 - case NEON_2RM_VUZP: 4895 - case NEON_2RM_VZIP: 4896 - case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN: 4897 - case NEON_2RM_VSHLL: 4898 - case NEON_2RM_VCVT_F16_F32: 4899 - case NEON_2RM_VCVT_F32_F16: 4900 - case NEON_2RM_VMVN: 4901 - case NEON_2RM_VNEG: 4902 - case NEON_2RM_VABS: 4903 - case NEON_2RM_VCEQ0: 4904 - case NEON_2RM_VCGT0: 4905 - case NEON_2RM_VCLE0: 4906 - case NEON_2RM_VCGE0: 4907 - case NEON_2RM_VCLT0: 4908 - case NEON_2RM_AESE: case NEON_2RM_AESMC: 4909 - case NEON_2RM_SHA1H: 4910 - case NEON_2RM_SHA1SU1: 4911 - case NEON_2RM_VREV32: 4912 - case NEON_2RM_VREV16: 4913 - case NEON_2RM_VCLS: 4914 - case NEON_2RM_VCLZ: 4915 - case NEON_2RM_VCNT: 4916 - case NEON_2RM_VABS_F: 4917 - case NEON_2RM_VNEG_F: 4918 - case NEON_2RM_VRECPE: 4919 - case NEON_2RM_VRSQRTE: 4920 - case NEON_2RM_VQABS: 4921 - case NEON_2RM_VQNEG: 4922 - case NEON_2RM_VRECPE_F: 4923 - case NEON_2RM_VRSQRTE_F: 4924 - case NEON_2RM_VCVT_FS: 4925 - case NEON_2RM_VCVT_FU: 4926 - case NEON_2RM_VCVT_SF: 4927 - case NEON_2RM_VCVT_UF: 4928 - case NEON_2RM_VRINTX: 4929 - case NEON_2RM_VCGT0_F: 4930 - case NEON_2RM_VCGE0_F: 4931 - case NEON_2RM_VCEQ0_F: 4932 - case NEON_2RM_VCLE0_F: 4933 - case NEON_2RM_VCLT0_F: 4934 - case NEON_2RM_VRINTN: 4935 - case NEON_2RM_VRINTA: 4936 - case NEON_2RM_VRINTM: 4937 - case NEON_2RM_VRINTP: 4938 - case NEON_2RM_VRINTZ: 4939 - case NEON_2RM_VCVTAU: 4940 - case NEON_2RM_VCVTAS: 4941 - case NEON_2RM_VCVTNU: 4942 - case NEON_2RM_VCVTNS: 4943 - case NEON_2RM_VCVTPU: 4944 - case NEON_2RM_VCVTPS: 4945 - case NEON_2RM_VCVTMU: 4946 - case NEON_2RM_VCVTMS: 4947 - case NEON_2RM_VSWP: 4948 - /* handled by decodetree */ 4949 - return 1; 4950 - case NEON_2RM_VTRN: 4951 - if (size == 2) { 4952 - int n; 4953 - for (n = 0; n < (q ? 4 : 2); n += 2) { 4954 - tmp = neon_load_reg(rm, n); 4955 - tmp2 = neon_load_reg(rd, n + 1); 4956 - neon_store_reg(rm, n, tmp2); 4957 - neon_store_reg(rd, n + 1, tmp); 4958 - } 4959 - } else { 4960 - goto elementwise; 4961 - } 4962 - break; 4963 - 4964 - default: 4965 - elementwise: 4966 - for (pass = 0; pass < (q ? 4 : 2); pass++) { 4967 - tmp = neon_load_reg(rm, pass); 4968 - switch (op) { 4969 - case NEON_2RM_VTRN: 4970 - tmp2 = neon_load_reg(rd, pass); 4971 - switch (size) { 4972 - case 0: gen_neon_trn_u8(tmp, tmp2); break; 4973 - case 1: gen_neon_trn_u16(tmp, tmp2); break; 4974 - default: abort(); 4975 - } 4976 - neon_store_reg(rm, pass, tmp2); 4977 - break; 4978 - default: 4979 - /* Reserved op values were caught by the 4980 - * neon_2rm_sizes[] check earlier. 4981 - */ 4982 - abort(); 4983 - } 4984 - neon_store_reg(rd, pass, tmp); 4985 - } 4986 - break; 4987 - } 4988 - } else { 4989 - /* VTBL, VTBX, VDUP: handled by decodetree */ 4990 - return 1; 4991 - } 4992 - } 4993 - } 4994 - return 0; 4995 4646 } 4996 4647 4997 4648 static int disas_coproc_insn(DisasContext *s, uint32_t insn) ··· 8694 8345 } 8695 8346 /* fall back to legacy decoder */ 8696 8347 8697 - if (((insn >> 25) & 7) == 1) { 8698 - /* NEON Data processing. */ 8699 - if (disas_neon_data_insn(s, insn)) { 8700 - goto illegal_op; 8701 - } 8702 - return; 8703 - } 8704 8348 if ((insn & 0x0e000f00) == 0x0c000100) { 8705 8349 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { 8706 8350 /* iWMMXt register transfer. */ ··· 8888 8532 break; 8889 8533 } 8890 8534 if (((insn >> 24) & 3) == 3) { 8891 - /* Translate into the equivalent ARM encoding. */ 8892 - insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); 8893 - if (disas_neon_data_insn(s, insn)) { 8894 - goto illegal_op; 8895 - } 8535 + /* Neon DP, but failed disas_neon_dp() */ 8536 + goto illegal_op; 8896 8537 } else if (((insn >> 8) & 0xe) == 10) { 8897 8538 /* VFP, but failed disas_vfp. */ 8898 8539 goto illegal_op;