1625e3dd4SPeter Maydell /* 2625e3dd4SPeter Maydell * ARM translation: AArch32 Neon instructions 3625e3dd4SPeter Maydell * 4625e3dd4SPeter Maydell * Copyright (c) 2003 Fabrice Bellard 5625e3dd4SPeter Maydell * Copyright (c) 2005-2007 CodeSourcery 6625e3dd4SPeter Maydell * Copyright (c) 2007 OpenedHand, Ltd. 7625e3dd4SPeter Maydell * Copyright (c) 2020 Linaro, Ltd. 8625e3dd4SPeter Maydell * 9625e3dd4SPeter Maydell * This library is free software; you can redistribute it and/or 10625e3dd4SPeter Maydell * modify it under the terms of the GNU Lesser General Public 11625e3dd4SPeter Maydell * License as published by the Free Software Foundation; either 12625e3dd4SPeter Maydell * version 2 of the License, or (at your option) any later version. 13625e3dd4SPeter Maydell * 14625e3dd4SPeter Maydell * This library is distributed in the hope that it will be useful, 15625e3dd4SPeter Maydell * but WITHOUT ANY WARRANTY; without even the implied warranty of 16625e3dd4SPeter Maydell * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17625e3dd4SPeter Maydell * Lesser General Public License for more details. 18625e3dd4SPeter Maydell * 19625e3dd4SPeter Maydell * You should have received a copy of the GNU Lesser General Public 20625e3dd4SPeter Maydell * License along with this library; if not, see <http://www.gnu.org/licenses/>. 21625e3dd4SPeter Maydell */ 22625e3dd4SPeter Maydell 23625e3dd4SPeter Maydell /* 24625e3dd4SPeter Maydell * This file is intended to be included from translate.c; it uses 25625e3dd4SPeter Maydell * some macros and definitions provided by that file. 26625e3dd4SPeter Maydell * It might be possible to convert it to a standalone .c file eventually. 27625e3dd4SPeter Maydell */ 28625e3dd4SPeter Maydell 29625e3dd4SPeter Maydell /* Include the generated Neon decoder */ 30625e3dd4SPeter Maydell #include "decode-neon-dp.inc.c" 31625e3dd4SPeter Maydell #include "decode-neon-ls.inc.c" 32625e3dd4SPeter Maydell #include "decode-neon-shared.inc.c" 33afff8de0SPeter Maydell 34afff8de0SPeter Maydell static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a) 35afff8de0SPeter Maydell { 36afff8de0SPeter Maydell int opr_sz; 37afff8de0SPeter Maydell TCGv_ptr fpst; 38afff8de0SPeter Maydell gen_helper_gvec_3_ptr *fn_gvec_ptr; 39afff8de0SPeter Maydell 40afff8de0SPeter Maydell if (!dc_isar_feature(aa32_vcma, s) 41afff8de0SPeter Maydell || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) { 42afff8de0SPeter Maydell return false; 43afff8de0SPeter Maydell } 44afff8de0SPeter Maydell 45afff8de0SPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 46afff8de0SPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 47afff8de0SPeter Maydell ((a->vd | a->vn | a->vm) & 0x10)) { 48afff8de0SPeter Maydell return false; 49afff8de0SPeter Maydell } 50afff8de0SPeter Maydell 51afff8de0SPeter Maydell if ((a->vn | a->vm | a->vd) & a->q) { 52afff8de0SPeter Maydell return false; 53afff8de0SPeter Maydell } 54afff8de0SPeter Maydell 55afff8de0SPeter Maydell if (!vfp_access_check(s)) { 56afff8de0SPeter Maydell return true; 57afff8de0SPeter Maydell } 58afff8de0SPeter Maydell 59afff8de0SPeter Maydell opr_sz = (1 + a->q) * 8; 60afff8de0SPeter Maydell fpst = get_fpstatus_ptr(1); 61afff8de0SPeter Maydell fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah; 62afff8de0SPeter Maydell tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd), 63afff8de0SPeter Maydell vfp_reg_offset(1, a->vn), 64afff8de0SPeter Maydell vfp_reg_offset(1, a->vm), 65afff8de0SPeter Maydell fpst, opr_sz, opr_sz, a->rot, 66afff8de0SPeter Maydell fn_gvec_ptr); 67afff8de0SPeter Maydell tcg_temp_free_ptr(fpst); 68afff8de0SPeter Maydell return true; 69afff8de0SPeter Maydell } 7094d5eb7bSPeter Maydell 7194d5eb7bSPeter Maydell static bool trans_VCADD(DisasContext *s, arg_VCADD *a) 7294d5eb7bSPeter Maydell { 7394d5eb7bSPeter Maydell int opr_sz; 7494d5eb7bSPeter Maydell TCGv_ptr fpst; 7594d5eb7bSPeter Maydell gen_helper_gvec_3_ptr *fn_gvec_ptr; 7694d5eb7bSPeter Maydell 7794d5eb7bSPeter Maydell if (!dc_isar_feature(aa32_vcma, s) 7894d5eb7bSPeter Maydell || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) { 7994d5eb7bSPeter Maydell return false; 8094d5eb7bSPeter Maydell } 8194d5eb7bSPeter Maydell 8294d5eb7bSPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 8394d5eb7bSPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 8494d5eb7bSPeter Maydell ((a->vd | a->vn | a->vm) & 0x10)) { 8594d5eb7bSPeter Maydell return false; 8694d5eb7bSPeter Maydell } 8794d5eb7bSPeter Maydell 8894d5eb7bSPeter Maydell if ((a->vn | a->vm | a->vd) & a->q) { 8994d5eb7bSPeter Maydell return false; 9094d5eb7bSPeter Maydell } 9194d5eb7bSPeter Maydell 9294d5eb7bSPeter Maydell if (!vfp_access_check(s)) { 9394d5eb7bSPeter Maydell return true; 9494d5eb7bSPeter Maydell } 9594d5eb7bSPeter Maydell 9694d5eb7bSPeter Maydell opr_sz = (1 + a->q) * 8; 9794d5eb7bSPeter Maydell fpst = get_fpstatus_ptr(1); 9894d5eb7bSPeter Maydell fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh; 9994d5eb7bSPeter Maydell tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd), 10094d5eb7bSPeter Maydell vfp_reg_offset(1, a->vn), 10194d5eb7bSPeter Maydell vfp_reg_offset(1, a->vm), 10294d5eb7bSPeter Maydell fpst, opr_sz, opr_sz, a->rot, 10394d5eb7bSPeter Maydell fn_gvec_ptr); 10494d5eb7bSPeter Maydell tcg_temp_free_ptr(fpst); 10594d5eb7bSPeter Maydell return true; 10694d5eb7bSPeter Maydell } 10732da0e33SPeter Maydell 10832da0e33SPeter Maydell static bool trans_VDOT(DisasContext *s, arg_VDOT *a) 10932da0e33SPeter Maydell { 11032da0e33SPeter Maydell int opr_sz; 11132da0e33SPeter Maydell gen_helper_gvec_3 *fn_gvec; 11232da0e33SPeter Maydell 11332da0e33SPeter Maydell if (!dc_isar_feature(aa32_dp, s)) { 11432da0e33SPeter Maydell return false; 11532da0e33SPeter Maydell } 11632da0e33SPeter Maydell 11732da0e33SPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 11832da0e33SPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 11932da0e33SPeter Maydell ((a->vd | a->vn | a->vm) & 0x10)) { 12032da0e33SPeter Maydell return false; 12132da0e33SPeter Maydell } 12232da0e33SPeter Maydell 12332da0e33SPeter Maydell if ((a->vn | a->vm | a->vd) & a->q) { 12432da0e33SPeter Maydell return false; 12532da0e33SPeter Maydell } 12632da0e33SPeter Maydell 12732da0e33SPeter Maydell if (!vfp_access_check(s)) { 12832da0e33SPeter Maydell return true; 12932da0e33SPeter Maydell } 13032da0e33SPeter Maydell 13132da0e33SPeter Maydell opr_sz = (1 + a->q) * 8; 13232da0e33SPeter Maydell fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b; 13332da0e33SPeter Maydell tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd), 13432da0e33SPeter Maydell vfp_reg_offset(1, a->vn), 13532da0e33SPeter Maydell vfp_reg_offset(1, a->vm), 13632da0e33SPeter Maydell opr_sz, opr_sz, 0, fn_gvec); 13732da0e33SPeter Maydell return true; 13832da0e33SPeter Maydell } 1399a107e7bSPeter Maydell 1409a107e7bSPeter Maydell static bool trans_VFML(DisasContext *s, arg_VFML *a) 1419a107e7bSPeter Maydell { 1429a107e7bSPeter Maydell int opr_sz; 1439a107e7bSPeter Maydell 1449a107e7bSPeter Maydell if (!dc_isar_feature(aa32_fhm, s)) { 1459a107e7bSPeter Maydell return false; 1469a107e7bSPeter Maydell } 1479a107e7bSPeter Maydell 1489a107e7bSPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 1499a107e7bSPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 1509a107e7bSPeter Maydell (a->vd & 0x10)) { 1519a107e7bSPeter Maydell return false; 1529a107e7bSPeter Maydell } 1539a107e7bSPeter Maydell 1549a107e7bSPeter Maydell if (a->vd & a->q) { 1559a107e7bSPeter Maydell return false; 1569a107e7bSPeter Maydell } 1579a107e7bSPeter Maydell 1589a107e7bSPeter Maydell if (!vfp_access_check(s)) { 1599a107e7bSPeter Maydell return true; 1609a107e7bSPeter Maydell } 1619a107e7bSPeter Maydell 1629a107e7bSPeter Maydell opr_sz = (1 + a->q) * 8; 1639a107e7bSPeter Maydell tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd), 1649a107e7bSPeter Maydell vfp_reg_offset(a->q, a->vn), 1659a107e7bSPeter Maydell vfp_reg_offset(a->q, a->vm), 1669a107e7bSPeter Maydell cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */ 1679a107e7bSPeter Maydell gen_helper_gvec_fmlal_a32); 1689a107e7bSPeter Maydell return true; 1699a107e7bSPeter Maydell } 1707e1b5d61SPeter Maydell 1717e1b5d61SPeter Maydell static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a) 1727e1b5d61SPeter Maydell { 1737e1b5d61SPeter Maydell gen_helper_gvec_3_ptr *fn_gvec_ptr; 1747e1b5d61SPeter Maydell int opr_sz; 1757e1b5d61SPeter Maydell TCGv_ptr fpst; 1767e1b5d61SPeter Maydell 1777e1b5d61SPeter Maydell if (!dc_isar_feature(aa32_vcma, s)) { 1787e1b5d61SPeter Maydell return false; 1797e1b5d61SPeter Maydell } 1807e1b5d61SPeter Maydell if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) { 1817e1b5d61SPeter Maydell return false; 1827e1b5d61SPeter Maydell } 1837e1b5d61SPeter Maydell 1847e1b5d61SPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 1857e1b5d61SPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 1867e1b5d61SPeter Maydell ((a->vd | a->vn | a->vm) & 0x10)) { 1877e1b5d61SPeter Maydell return false; 1887e1b5d61SPeter Maydell } 1897e1b5d61SPeter Maydell 1907e1b5d61SPeter Maydell if ((a->vd | a->vn) & a->q) { 1917e1b5d61SPeter Maydell return false; 1927e1b5d61SPeter Maydell } 1937e1b5d61SPeter Maydell 1947e1b5d61SPeter Maydell if (!vfp_access_check(s)) { 1957e1b5d61SPeter Maydell return true; 1967e1b5d61SPeter Maydell } 1977e1b5d61SPeter Maydell 1987e1b5d61SPeter Maydell fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx 1997e1b5d61SPeter Maydell : gen_helper_gvec_fcmlah_idx); 2007e1b5d61SPeter Maydell opr_sz = (1 + a->q) * 8; 2017e1b5d61SPeter Maydell fpst = get_fpstatus_ptr(1); 2027e1b5d61SPeter Maydell tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd), 2037e1b5d61SPeter Maydell vfp_reg_offset(1, a->vn), 2047e1b5d61SPeter Maydell vfp_reg_offset(1, a->vm), 2057e1b5d61SPeter Maydell fpst, opr_sz, opr_sz, 2067e1b5d61SPeter Maydell (a->index << 2) | a->rot, fn_gvec_ptr); 2077e1b5d61SPeter Maydell tcg_temp_free_ptr(fpst); 2087e1b5d61SPeter Maydell return true; 2097e1b5d61SPeter Maydell } 21035f5d4d1SPeter Maydell 21135f5d4d1SPeter Maydell static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a) 21235f5d4d1SPeter Maydell { 21335f5d4d1SPeter Maydell gen_helper_gvec_3 *fn_gvec; 21435f5d4d1SPeter Maydell int opr_sz; 21535f5d4d1SPeter Maydell TCGv_ptr fpst; 21635f5d4d1SPeter Maydell 21735f5d4d1SPeter Maydell if (!dc_isar_feature(aa32_dp, s)) { 21835f5d4d1SPeter Maydell return false; 21935f5d4d1SPeter Maydell } 22035f5d4d1SPeter Maydell 22135f5d4d1SPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 22235f5d4d1SPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 22335f5d4d1SPeter Maydell ((a->vd | a->vn) & 0x10)) { 22435f5d4d1SPeter Maydell return false; 22535f5d4d1SPeter Maydell } 22635f5d4d1SPeter Maydell 22735f5d4d1SPeter Maydell if ((a->vd | a->vn) & a->q) { 22835f5d4d1SPeter Maydell return false; 22935f5d4d1SPeter Maydell } 23035f5d4d1SPeter Maydell 23135f5d4d1SPeter Maydell if (!vfp_access_check(s)) { 23235f5d4d1SPeter Maydell return true; 23335f5d4d1SPeter Maydell } 23435f5d4d1SPeter Maydell 23535f5d4d1SPeter Maydell fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b; 23635f5d4d1SPeter Maydell opr_sz = (1 + a->q) * 8; 23735f5d4d1SPeter Maydell fpst = get_fpstatus_ptr(1); 23835f5d4d1SPeter Maydell tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd), 23935f5d4d1SPeter Maydell vfp_reg_offset(1, a->vn), 24035f5d4d1SPeter Maydell vfp_reg_offset(1, a->rm), 24135f5d4d1SPeter Maydell opr_sz, opr_sz, a->index, fn_gvec); 24235f5d4d1SPeter Maydell tcg_temp_free_ptr(fpst); 24335f5d4d1SPeter Maydell return true; 24435f5d4d1SPeter Maydell } 245d27e82f7SPeter Maydell 246d27e82f7SPeter Maydell static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a) 247d27e82f7SPeter Maydell { 248d27e82f7SPeter Maydell int opr_sz; 249d27e82f7SPeter Maydell 250d27e82f7SPeter Maydell if (!dc_isar_feature(aa32_fhm, s)) { 251d27e82f7SPeter Maydell return false; 252d27e82f7SPeter Maydell } 253d27e82f7SPeter Maydell 254d27e82f7SPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist. */ 255d27e82f7SPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && 256d27e82f7SPeter Maydell ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) { 257d27e82f7SPeter Maydell return false; 258d27e82f7SPeter Maydell } 259d27e82f7SPeter Maydell 260d27e82f7SPeter Maydell if (a->vd & a->q) { 261d27e82f7SPeter Maydell return false; 262d27e82f7SPeter Maydell } 263d27e82f7SPeter Maydell 264d27e82f7SPeter Maydell if (!vfp_access_check(s)) { 265d27e82f7SPeter Maydell return true; 266d27e82f7SPeter Maydell } 267d27e82f7SPeter Maydell 268d27e82f7SPeter Maydell opr_sz = (1 + a->q) * 8; 269d27e82f7SPeter Maydell tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd), 270d27e82f7SPeter Maydell vfp_reg_offset(a->q, a->vn), 271d27e82f7SPeter Maydell vfp_reg_offset(a->q, a->rm), 272d27e82f7SPeter Maydell cpu_env, opr_sz, opr_sz, 273d27e82f7SPeter Maydell (a->index << 2) | a->s, /* is_2 == 0 */ 274d27e82f7SPeter Maydell gen_helper_gvec_fmlal_idx_a32); 275d27e82f7SPeter Maydell return true; 276d27e82f7SPeter Maydell } 277a27b4630SPeter Maydell 278a27b4630SPeter Maydell static struct { 279a27b4630SPeter Maydell int nregs; 280a27b4630SPeter Maydell int interleave; 281a27b4630SPeter Maydell int spacing; 282a27b4630SPeter Maydell } const neon_ls_element_type[11] = { 283a27b4630SPeter Maydell {1, 4, 1}, 284a27b4630SPeter Maydell {1, 4, 2}, 285a27b4630SPeter Maydell {4, 1, 1}, 286a27b4630SPeter Maydell {2, 2, 2}, 287a27b4630SPeter Maydell {1, 3, 1}, 288a27b4630SPeter Maydell {1, 3, 2}, 289a27b4630SPeter Maydell {3, 1, 1}, 290a27b4630SPeter Maydell {1, 1, 1}, 291a27b4630SPeter Maydell {1, 2, 1}, 292a27b4630SPeter Maydell {1, 2, 2}, 293a27b4630SPeter Maydell {2, 1, 1} 294a27b4630SPeter Maydell }; 295a27b4630SPeter Maydell 296a27b4630SPeter Maydell static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn, 297a27b4630SPeter Maydell int stride) 298a27b4630SPeter Maydell { 299a27b4630SPeter Maydell if (rm != 15) { 300a27b4630SPeter Maydell TCGv_i32 base; 301a27b4630SPeter Maydell 302a27b4630SPeter Maydell base = load_reg(s, rn); 303a27b4630SPeter Maydell if (rm == 13) { 304a27b4630SPeter Maydell tcg_gen_addi_i32(base, base, stride); 305a27b4630SPeter Maydell } else { 306a27b4630SPeter Maydell TCGv_i32 index; 307a27b4630SPeter Maydell index = load_reg(s, rm); 308a27b4630SPeter Maydell tcg_gen_add_i32(base, base, index); 309a27b4630SPeter Maydell tcg_temp_free_i32(index); 310a27b4630SPeter Maydell } 311a27b4630SPeter Maydell store_reg(s, rn, base); 312a27b4630SPeter Maydell } 313a27b4630SPeter Maydell } 314a27b4630SPeter Maydell 315a27b4630SPeter Maydell static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a) 316a27b4630SPeter Maydell { 317a27b4630SPeter Maydell /* Neon load/store multiple structures */ 318a27b4630SPeter Maydell int nregs, interleave, spacing, reg, n; 319a27b4630SPeter Maydell MemOp endian = s->be_data; 320a27b4630SPeter Maydell int mmu_idx = get_mem_index(s); 321a27b4630SPeter Maydell int size = a->size; 322a27b4630SPeter Maydell TCGv_i64 tmp64; 323a27b4630SPeter Maydell TCGv_i32 addr, tmp; 324a27b4630SPeter Maydell 325a27b4630SPeter Maydell if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { 326a27b4630SPeter Maydell return false; 327a27b4630SPeter Maydell } 328a27b4630SPeter Maydell 329a27b4630SPeter Maydell /* UNDEF accesses to D16-D31 if they don't exist */ 330a27b4630SPeter Maydell if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) { 331a27b4630SPeter Maydell return false; 332a27b4630SPeter Maydell } 333a27b4630SPeter Maydell if (a->itype > 10) { 334a27b4630SPeter Maydell return false; 335a27b4630SPeter Maydell } 336a27b4630SPeter Maydell /* Catch UNDEF cases for bad values of align field */ 337a27b4630SPeter Maydell switch (a->itype & 0xc) { 338a27b4630SPeter Maydell case 4: 339a27b4630SPeter Maydell if (a->align >= 2) { 340a27b4630SPeter Maydell return false; 341a27b4630SPeter Maydell } 342a27b4630SPeter Maydell break; 343a27b4630SPeter Maydell case 8: 344a27b4630SPeter Maydell if (a->align == 3) { 345a27b4630SPeter Maydell return false; 346a27b4630SPeter Maydell } 347a27b4630SPeter Maydell break; 348a27b4630SPeter Maydell default: 349a27b4630SPeter Maydell break; 350a27b4630SPeter Maydell } 351a27b4630SPeter Maydell nregs = neon_ls_element_type[a->itype].nregs; 352a27b4630SPeter Maydell interleave = neon_ls_element_type[a->itype].interleave; 353a27b4630SPeter Maydell spacing = neon_ls_element_type[a->itype].spacing; 354a27b4630SPeter Maydell if (size == 3 && (interleave | spacing) != 1) { 355a27b4630SPeter Maydell return false; 356a27b4630SPeter Maydell } 357a27b4630SPeter Maydell 358a27b4630SPeter Maydell if (!vfp_access_check(s)) { 359a27b4630SPeter Maydell return true; 360a27b4630SPeter Maydell } 361a27b4630SPeter Maydell 362a27b4630SPeter Maydell /* For our purposes, bytes are always little-endian. */ 363a27b4630SPeter Maydell if (size == 0) { 364a27b4630SPeter Maydell endian = MO_LE; 365a27b4630SPeter Maydell } 366a27b4630SPeter Maydell /* 367a27b4630SPeter Maydell * Consecutive little-endian elements from a single register 368a27b4630SPeter Maydell * can be promoted to a larger little-endian operation. 369a27b4630SPeter Maydell */ 370a27b4630SPeter Maydell if (interleave == 1 && endian == MO_LE) { 371a27b4630SPeter Maydell size = 3; 372a27b4630SPeter Maydell } 373a27b4630SPeter Maydell tmp64 = tcg_temp_new_i64(); 374a27b4630SPeter Maydell addr = tcg_temp_new_i32(); 375a27b4630SPeter Maydell tmp = tcg_const_i32(1 << size); 376a27b4630SPeter Maydell load_reg_var(s, addr, a->rn); 377a27b4630SPeter Maydell for (reg = 0; reg < nregs; reg++) { 378a27b4630SPeter Maydell for (n = 0; n < 8 >> size; n++) { 379a27b4630SPeter Maydell int xs; 380a27b4630SPeter Maydell for (xs = 0; xs < interleave; xs++) { 381a27b4630SPeter Maydell int tt = a->vd + reg + spacing * xs; 382a27b4630SPeter Maydell 383a27b4630SPeter Maydell if (a->l) { 384a27b4630SPeter Maydell gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size); 385a27b4630SPeter Maydell neon_store_element64(tt, n, size, tmp64); 386a27b4630SPeter Maydell } else { 387a27b4630SPeter Maydell neon_load_element64(tmp64, tt, n, size); 388a27b4630SPeter Maydell gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size); 389a27b4630SPeter Maydell } 390a27b4630SPeter Maydell tcg_gen_add_i32(addr, addr, tmp); 391a27b4630SPeter Maydell } 392a27b4630SPeter Maydell } 393a27b4630SPeter Maydell } 394a27b4630SPeter Maydell tcg_temp_free_i32(addr); 395a27b4630SPeter Maydell tcg_temp_free_i32(tmp); 396a27b4630SPeter Maydell tcg_temp_free_i64(tmp64); 397a27b4630SPeter Maydell 398a27b4630SPeter Maydell gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8); 399a27b4630SPeter Maydell return true; 400a27b4630SPeter Maydell } 401