Revisión | 505fce5060eac5daf04abbdc0f347ddd53a73c66 (tree) |
---|---|
Tiempo | 2021-05-26 00:01:44 |
Autor | Richard Henderson <richard.henderson@lina...> |
Commiter | Peter Maydell |
target/arm: Split out do_neon_ddda_fpst
Split out a helper that can handle the 4-register
format for helpers shared with SVE.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210525010358.152808-85-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
@@ -151,24 +151,21 @@ static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var) | ||
151 | 151 | } |
152 | 152 | } |
153 | 153 | |
154 | -static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a) | |
154 | +static bool do_neon_ddda_fpst(DisasContext *s, int q, int vd, int vn, int vm, | |
155 | + int data, ARMFPStatusFlavour fp_flavour, | |
156 | + gen_helper_gvec_4_ptr *fn_gvec_ptr) | |
155 | 157 | { |
156 | - int opr_sz; | |
157 | - TCGv_ptr fpst; | |
158 | - gen_helper_gvec_4_ptr *fn_gvec_ptr; | |
159 | - | |
160 | - if (!dc_isar_feature(aa32_vcma, s) | |
161 | - || (a->size == MO_16 && !dc_isar_feature(aa32_fp16_arith, s))) { | |
162 | - return false; | |
163 | - } | |
164 | - | |
165 | 158 | /* UNDEF accesses to D16-D31 if they don't exist. */ |
166 | - if (!dc_isar_feature(aa32_simd_r32, s) && | |
167 | - ((a->vd | a->vn | a->vm) & 0x10)) { | |
159 | + if (((vd | vn | vm) & 0x10) && !dc_isar_feature(aa32_simd_r32, s)) { | |
168 | 160 | return false; |
169 | 161 | } |
170 | 162 | |
171 | - if ((a->vn | a->vm | a->vd) & a->q) { | |
163 | + /* | |
164 | + * UNDEF accesses to odd registers for each bit of Q. | |
165 | + * Q will be 0b111 for all Q-reg instructions, otherwise | |
166 | + * when we have mixed Q- and D-reg inputs. | |
167 | + */ | |
168 | + if (((vd & 1) * 4 | (vn & 1) * 2 | (vm & 1)) & q) { | |
172 | 169 | return false; |
173 | 170 | } |
174 | 171 |
@@ -176,20 +173,34 @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a) | ||
176 | 173 | return true; |
177 | 174 | } |
178 | 175 | |
179 | - opr_sz = (1 + a->q) * 8; | |
180 | - fpst = fpstatus_ptr(a->size == MO_16 ? FPST_STD_F16 : FPST_STD); | |
181 | - fn_gvec_ptr = (a->size == MO_16) ? | |
182 | - gen_helper_gvec_fcmlah : gen_helper_gvec_fcmlas; | |
183 | - tcg_gen_gvec_4_ptr(vfp_reg_offset(1, a->vd), | |
184 | - vfp_reg_offset(1, a->vn), | |
185 | - vfp_reg_offset(1, a->vm), | |
186 | - vfp_reg_offset(1, a->vd), | |
187 | - fpst, opr_sz, opr_sz, a->rot, | |
188 | - fn_gvec_ptr); | |
176 | + int opr_sz = q ? 16 : 8; | |
177 | + TCGv_ptr fpst = fpstatus_ptr(fp_flavour); | |
178 | + | |
179 | + tcg_gen_gvec_4_ptr(vfp_reg_offset(1, vd), | |
180 | + vfp_reg_offset(1, vn), | |
181 | + vfp_reg_offset(1, vm), | |
182 | + vfp_reg_offset(1, vd), | |
183 | + fpst, opr_sz, opr_sz, data, fn_gvec_ptr); | |
189 | 184 | tcg_temp_free_ptr(fpst); |
190 | 185 | return true; |
191 | 186 | } |
192 | 187 | |
188 | +static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a) | |
189 | +{ | |
190 | + if (!dc_isar_feature(aa32_vcma, s)) { | |
191 | + return false; | |
192 | + } | |
193 | + if (a->size == MO_16) { | |
194 | + if (!dc_isar_feature(aa32_fp16_arith, s)) { | |
195 | + return false; | |
196 | + } | |
197 | + return do_neon_ddda_fpst(s, a->q * 7, a->vd, a->vn, a->vm, a->rot, | |
198 | + FPST_STD_F16, gen_helper_gvec_fcmlah); | |
199 | + } | |
200 | + return do_neon_ddda_fpst(s, a->q * 7, a->vd, a->vn, a->vm, a->rot, | |
201 | + FPST_STD, gen_helper_gvec_fcmlas); | |
202 | +} | |
203 | + | |
193 | 204 | static bool trans_VCADD(DisasContext *s, arg_VCADD *a) |
194 | 205 | { |
195 | 206 | int opr_sz; |
@@ -294,43 +305,20 @@ static bool trans_VFML(DisasContext *s, arg_VFML *a) | ||
294 | 305 | |
295 | 306 | static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a) |
296 | 307 | { |
297 | - gen_helper_gvec_4_ptr *fn_gvec_ptr; | |
298 | - int opr_sz; | |
299 | - TCGv_ptr fpst; | |
308 | + int data = (a->index << 2) | a->rot; | |
300 | 309 | |
301 | 310 | if (!dc_isar_feature(aa32_vcma, s)) { |
302 | 311 | return false; |
303 | 312 | } |
304 | - if (a->size == MO_16 && !dc_isar_feature(aa32_fp16_arith, s)) { | |
305 | - return false; | |
306 | - } | |
307 | - | |
308 | - /* UNDEF accesses to D16-D31 if they don't exist. */ | |
309 | - if (!dc_isar_feature(aa32_simd_r32, s) && | |
310 | - ((a->vd | a->vn | a->vm) & 0x10)) { | |
311 | - return false; | |
312 | - } | |
313 | - | |
314 | - if ((a->vd | a->vn) & a->q) { | |
315 | - return false; | |
316 | - } | |
317 | - | |
318 | - if (!vfp_access_check(s)) { | |
319 | - return true; | |
313 | + if (a->size == MO_16) { | |
314 | + if (!dc_isar_feature(aa32_fp16_arith, s)) { | |
315 | + return false; | |
316 | + } | |
317 | + return do_neon_ddda_fpst(s, a->q * 6, a->vd, a->vn, a->vm, data, | |
318 | + FPST_STD_F16, gen_helper_gvec_fcmlah_idx); | |
320 | 319 | } |
321 | - | |
322 | - fn_gvec_ptr = (a->size == MO_16) ? | |
323 | - gen_helper_gvec_fcmlah_idx : gen_helper_gvec_fcmlas_idx; | |
324 | - opr_sz = (1 + a->q) * 8; | |
325 | - fpst = fpstatus_ptr(a->size == MO_16 ? FPST_STD_F16 : FPST_STD); | |
326 | - tcg_gen_gvec_4_ptr(vfp_reg_offset(1, a->vd), | |
327 | - vfp_reg_offset(1, a->vn), | |
328 | - vfp_reg_offset(1, a->vm), | |
329 | - vfp_reg_offset(1, a->vd), | |
330 | - fpst, opr_sz, opr_sz, | |
331 | - (a->index << 2) | a->rot, fn_gvec_ptr); | |
332 | - tcg_temp_free_ptr(fpst); | |
333 | - return true; | |
320 | + return do_neon_ddda_fpst(s, a->q * 6, a->vd, a->vn, a->vm, data, | |
321 | + FPST_STD, gen_helper_gvec_fcmlas_idx); | |
334 | 322 | } |
335 | 323 | |
336 | 324 | static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a) |