1e67cd1caSRichard Henderson /* 2e67cd1caSRichard Henderson * AArch64 SME translation 3e67cd1caSRichard Henderson * 4e67cd1caSRichard Henderson * Copyright (c) 2022 Linaro, Ltd 5e67cd1caSRichard Henderson * 6e67cd1caSRichard Henderson * This library is free software; you can redistribute it and/or 7e67cd1caSRichard Henderson * modify it under the terms of the GNU Lesser General Public 8e67cd1caSRichard Henderson * License as published by the Free Software Foundation; either 9e67cd1caSRichard Henderson * version 2.1 of the License, or (at your option) any later version. 10e67cd1caSRichard Henderson * 11e67cd1caSRichard Henderson * This library is distributed in the hope that it will be useful, 12e67cd1caSRichard Henderson * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e67cd1caSRichard Henderson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14e67cd1caSRichard Henderson * Lesser General Public License for more details. 15e67cd1caSRichard Henderson * 16e67cd1caSRichard Henderson * You should have received a copy of the GNU Lesser General Public 17e67cd1caSRichard Henderson * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18e67cd1caSRichard Henderson */ 19e67cd1caSRichard Henderson 20e67cd1caSRichard Henderson #include "qemu/osdep.h" 21e67cd1caSRichard Henderson #include "cpu.h" 22e67cd1caSRichard Henderson #include "tcg/tcg-op.h" 23e67cd1caSRichard Henderson #include "tcg/tcg-op-gvec.h" 24e67cd1caSRichard Henderson #include "tcg/tcg-gvec-desc.h" 25e67cd1caSRichard Henderson #include "translate.h" 26e67cd1caSRichard Henderson #include "exec/helper-gen.h" 27e67cd1caSRichard Henderson #include "translate-a64.h" 28e67cd1caSRichard Henderson #include "fpu/softfloat.h" 29e67cd1caSRichard Henderson 30e67cd1caSRichard Henderson 31e67cd1caSRichard Henderson /* 32e67cd1caSRichard Henderson * Include the generated decoder. 33e67cd1caSRichard Henderson */ 34e67cd1caSRichard Henderson 35e67cd1caSRichard Henderson #include "decode-sme.c.inc" 36ad939afbSRichard Henderson 37ad939afbSRichard Henderson 38e9ad3ef1SRichard Henderson /* 39e9ad3ef1SRichard Henderson * Resolve tile.size[index] to a host pointer, where tile and index 40e9ad3ef1SRichard Henderson * are always decoded together, dependent on the element size. 41e9ad3ef1SRichard Henderson */ 42e9ad3ef1SRichard Henderson static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs, 43e9ad3ef1SRichard Henderson int tile_index, bool vertical) 44e9ad3ef1SRichard Henderson { 45e9ad3ef1SRichard Henderson int tile = tile_index >> (4 - esz); 46e9ad3ef1SRichard Henderson int index = esz == MO_128 ? 0 : extract32(tile_index, 0, 4 - esz); 47e9ad3ef1SRichard Henderson int pos, len, offset; 48e9ad3ef1SRichard Henderson TCGv_i32 tmp; 49e9ad3ef1SRichard Henderson TCGv_ptr addr; 50e9ad3ef1SRichard Henderson 51e9ad3ef1SRichard Henderson /* Compute the final index, which is Rs+imm. */ 52e9ad3ef1SRichard Henderson tmp = tcg_temp_new_i32(); 53e9ad3ef1SRichard Henderson tcg_gen_trunc_tl_i32(tmp, cpu_reg(s, rs)); 54e9ad3ef1SRichard Henderson tcg_gen_addi_i32(tmp, tmp, index); 55e9ad3ef1SRichard Henderson 56e9ad3ef1SRichard Henderson /* Prepare a power-of-two modulo via extraction of @len bits. */ 57e9ad3ef1SRichard Henderson len = ctz32(streaming_vec_reg_size(s)) - esz; 58e9ad3ef1SRichard Henderson 59e9ad3ef1SRichard Henderson if (vertical) { 60e9ad3ef1SRichard Henderson /* 61e9ad3ef1SRichard Henderson * Compute the byte offset of the index within the tile: 62e9ad3ef1SRichard Henderson * (index % (svl / size)) * size 63e9ad3ef1SRichard Henderson * = (index % (svl >> esz)) << esz 64e9ad3ef1SRichard Henderson * Perform the power-of-two modulo via extraction of the low @len bits. 65e9ad3ef1SRichard Henderson * Perform the multiply by shifting left by @pos bits. 66e9ad3ef1SRichard Henderson * Perform these operations simultaneously via deposit into zero. 67e9ad3ef1SRichard Henderson */ 68e9ad3ef1SRichard Henderson pos = esz; 69e9ad3ef1SRichard Henderson tcg_gen_deposit_z_i32(tmp, tmp, pos, len); 70e9ad3ef1SRichard Henderson 71e9ad3ef1SRichard Henderson /* 72e9ad3ef1SRichard Henderson * For big-endian, adjust the indexed column byte offset within 73e9ad3ef1SRichard Henderson * the uint64_t host words that make up env->zarray[]. 74e9ad3ef1SRichard Henderson */ 75e9ad3ef1SRichard Henderson if (HOST_BIG_ENDIAN && esz < MO_64) { 76e9ad3ef1SRichard Henderson tcg_gen_xori_i32(tmp, tmp, 8 - (1 << esz)); 77e9ad3ef1SRichard Henderson } 78e9ad3ef1SRichard Henderson } else { 79e9ad3ef1SRichard Henderson /* 80e9ad3ef1SRichard Henderson * Compute the byte offset of the index within the tile: 81e9ad3ef1SRichard Henderson * (index % (svl / size)) * (size * sizeof(row)) 82e9ad3ef1SRichard Henderson * = (index % (svl >> esz)) << (esz + log2(sizeof(row))) 83e9ad3ef1SRichard Henderson */ 84e9ad3ef1SRichard Henderson pos = esz + ctz32(sizeof(ARMVectorReg)); 85e9ad3ef1SRichard Henderson tcg_gen_deposit_z_i32(tmp, tmp, pos, len); 86e9ad3ef1SRichard Henderson 87e9ad3ef1SRichard Henderson /* Row slices are always aligned and need no endian adjustment. */ 88e9ad3ef1SRichard Henderson } 89e9ad3ef1SRichard Henderson 90e9ad3ef1SRichard Henderson /* The tile byte offset within env->zarray is the row. */ 91e9ad3ef1SRichard Henderson offset = tile * sizeof(ARMVectorReg); 92e9ad3ef1SRichard Henderson 93e9ad3ef1SRichard Henderson /* Include the byte offset of zarray to make this relative to env. */ 94e9ad3ef1SRichard Henderson offset += offsetof(CPUARMState, zarray); 95e9ad3ef1SRichard Henderson tcg_gen_addi_i32(tmp, tmp, offset); 96e9ad3ef1SRichard Henderson 97e9ad3ef1SRichard Henderson /* Add the byte offset to env to produce the final pointer. */ 98e9ad3ef1SRichard Henderson addr = tcg_temp_new_ptr(); 99e9ad3ef1SRichard Henderson tcg_gen_ext_i32_ptr(addr, tmp); 100e9ad3ef1SRichard Henderson tcg_temp_free_i32(tmp); 101e9ad3ef1SRichard Henderson tcg_gen_add_ptr(addr, addr, cpu_env); 102e9ad3ef1SRichard Henderson 103e9ad3ef1SRichard Henderson return addr; 104e9ad3ef1SRichard Henderson } 105e9ad3ef1SRichard Henderson 106ad939afbSRichard Henderson static bool trans_ZERO(DisasContext *s, arg_ZERO *a) 107ad939afbSRichard Henderson { 108ad939afbSRichard Henderson if (!dc_isar_feature(aa64_sme, s)) { 109ad939afbSRichard Henderson return false; 110ad939afbSRichard Henderson } 111ad939afbSRichard Henderson if (sme_za_enabled_check(s)) { 112ad939afbSRichard Henderson gen_helper_sme_zero(cpu_env, tcg_constant_i32(a->imm), 113ad939afbSRichard Henderson tcg_constant_i32(streaming_vec_reg_size(s))); 114ad939afbSRichard Henderson } 115ad939afbSRichard Henderson return true; 116ad939afbSRichard Henderson } 117e9ad3ef1SRichard Henderson 118e9ad3ef1SRichard Henderson static bool trans_MOVA(DisasContext *s, arg_MOVA *a) 119e9ad3ef1SRichard Henderson { 120e9ad3ef1SRichard Henderson static gen_helper_gvec_4 * const h_fns[5] = { 121e9ad3ef1SRichard Henderson gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h, 122e9ad3ef1SRichard Henderson gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d, 123e9ad3ef1SRichard Henderson gen_helper_sve_sel_zpzz_q 124e9ad3ef1SRichard Henderson }; 125e9ad3ef1SRichard Henderson static gen_helper_gvec_3 * const cz_fns[5] = { 126e9ad3ef1SRichard Henderson gen_helper_sme_mova_cz_b, gen_helper_sme_mova_cz_h, 127e9ad3ef1SRichard Henderson gen_helper_sme_mova_cz_s, gen_helper_sme_mova_cz_d, 128e9ad3ef1SRichard Henderson gen_helper_sme_mova_cz_q, 129e9ad3ef1SRichard Henderson }; 130e9ad3ef1SRichard Henderson static gen_helper_gvec_3 * const zc_fns[5] = { 131e9ad3ef1SRichard Henderson gen_helper_sme_mova_zc_b, gen_helper_sme_mova_zc_h, 132e9ad3ef1SRichard Henderson gen_helper_sme_mova_zc_s, gen_helper_sme_mova_zc_d, 133e9ad3ef1SRichard Henderson gen_helper_sme_mova_zc_q, 134e9ad3ef1SRichard Henderson }; 135e9ad3ef1SRichard Henderson 136e9ad3ef1SRichard Henderson TCGv_ptr t_za, t_zr, t_pg; 137e9ad3ef1SRichard Henderson TCGv_i32 t_desc; 138e9ad3ef1SRichard Henderson int svl; 139e9ad3ef1SRichard Henderson 140e9ad3ef1SRichard Henderson if (!dc_isar_feature(aa64_sme, s)) { 141e9ad3ef1SRichard Henderson return false; 142e9ad3ef1SRichard Henderson } 143e9ad3ef1SRichard Henderson if (!sme_smza_enabled_check(s)) { 144e9ad3ef1SRichard Henderson return true; 145e9ad3ef1SRichard Henderson } 146e9ad3ef1SRichard Henderson 147e9ad3ef1SRichard Henderson t_za = get_tile_rowcol(s, a->esz, a->rs, a->za_imm, a->v); 148e9ad3ef1SRichard Henderson t_zr = vec_full_reg_ptr(s, a->zr); 149e9ad3ef1SRichard Henderson t_pg = pred_full_reg_ptr(s, a->pg); 150e9ad3ef1SRichard Henderson 151e9ad3ef1SRichard Henderson svl = streaming_vec_reg_size(s); 152e9ad3ef1SRichard Henderson t_desc = tcg_constant_i32(simd_desc(svl, svl, 0)); 153e9ad3ef1SRichard Henderson 154e9ad3ef1SRichard Henderson if (a->v) { 155e9ad3ef1SRichard Henderson /* Vertical slice -- use sme mova helpers. */ 156e9ad3ef1SRichard Henderson if (a->to_vec) { 157e9ad3ef1SRichard Henderson zc_fns[a->esz](t_zr, t_za, t_pg, t_desc); 158e9ad3ef1SRichard Henderson } else { 159e9ad3ef1SRichard Henderson cz_fns[a->esz](t_za, t_zr, t_pg, t_desc); 160e9ad3ef1SRichard Henderson } 161e9ad3ef1SRichard Henderson } else { 162e9ad3ef1SRichard Henderson /* Horizontal slice -- reuse sve sel helpers. */ 163e9ad3ef1SRichard Henderson if (a->to_vec) { 164e9ad3ef1SRichard Henderson h_fns[a->esz](t_zr, t_za, t_zr, t_pg, t_desc); 165e9ad3ef1SRichard Henderson } else { 166e9ad3ef1SRichard Henderson h_fns[a->esz](t_za, t_zr, t_za, t_pg, t_desc); 167e9ad3ef1SRichard Henderson } 168e9ad3ef1SRichard Henderson } 169e9ad3ef1SRichard Henderson 170e9ad3ef1SRichard Henderson tcg_temp_free_ptr(t_za); 171e9ad3ef1SRichard Henderson tcg_temp_free_ptr(t_zr); 172e9ad3ef1SRichard Henderson tcg_temp_free_ptr(t_pg); 173e9ad3ef1SRichard Henderson 174e9ad3ef1SRichard Henderson return true; 175e9ad3ef1SRichard Henderson } 1767390e0e9SRichard Henderson 1777390e0e9SRichard Henderson static bool trans_LDST1(DisasContext *s, arg_LDST1 *a) 1787390e0e9SRichard Henderson { 1797390e0e9SRichard Henderson typedef void GenLdSt1(TCGv_env, TCGv_ptr, TCGv_ptr, TCGv, TCGv_i32); 1807390e0e9SRichard Henderson 1817390e0e9SRichard Henderson /* 1827390e0e9SRichard Henderson * Indexed by [esz][be][v][mte][st], which is (except for load/store) 1837390e0e9SRichard Henderson * also the order in which the elements appear in the function names, 1847390e0e9SRichard Henderson * and so how we must concatenate the pieces. 1857390e0e9SRichard Henderson */ 1867390e0e9SRichard Henderson 1877390e0e9SRichard Henderson #define FN_LS(F) { gen_helper_sme_ld1##F, gen_helper_sme_st1##F } 1887390e0e9SRichard Henderson #define FN_MTE(F) { FN_LS(F), FN_LS(F##_mte) } 1897390e0e9SRichard Henderson #define FN_HV(F) { FN_MTE(F##_h), FN_MTE(F##_v) } 1907390e0e9SRichard Henderson #define FN_END(L, B) { FN_HV(L), FN_HV(B) } 1917390e0e9SRichard Henderson 1927390e0e9SRichard Henderson static GenLdSt1 * const fns[5][2][2][2][2] = { 1937390e0e9SRichard Henderson FN_END(b, b), 1947390e0e9SRichard Henderson FN_END(h_le, h_be), 1957390e0e9SRichard Henderson FN_END(s_le, s_be), 1967390e0e9SRichard Henderson FN_END(d_le, d_be), 1977390e0e9SRichard Henderson FN_END(q_le, q_be), 1987390e0e9SRichard Henderson }; 1997390e0e9SRichard Henderson 2007390e0e9SRichard Henderson #undef FN_LS 2017390e0e9SRichard Henderson #undef FN_MTE 2027390e0e9SRichard Henderson #undef FN_HV 2037390e0e9SRichard Henderson #undef FN_END 2047390e0e9SRichard Henderson 2057390e0e9SRichard Henderson TCGv_ptr t_za, t_pg; 2067390e0e9SRichard Henderson TCGv_i64 addr; 2077390e0e9SRichard Henderson int svl, desc = 0; 2087390e0e9SRichard Henderson bool be = s->be_data == MO_BE; 2097390e0e9SRichard Henderson bool mte = s->mte_active[0]; 2107390e0e9SRichard Henderson 2117390e0e9SRichard Henderson if (!dc_isar_feature(aa64_sme, s)) { 2127390e0e9SRichard Henderson return false; 2137390e0e9SRichard Henderson } 2147390e0e9SRichard Henderson if (!sme_smza_enabled_check(s)) { 2157390e0e9SRichard Henderson return true; 2167390e0e9SRichard Henderson } 2177390e0e9SRichard Henderson 2187390e0e9SRichard Henderson t_za = get_tile_rowcol(s, a->esz, a->rs, a->za_imm, a->v); 2197390e0e9SRichard Henderson t_pg = pred_full_reg_ptr(s, a->pg); 2207390e0e9SRichard Henderson addr = tcg_temp_new_i64(); 2217390e0e9SRichard Henderson 2227390e0e9SRichard Henderson tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz); 2237390e0e9SRichard Henderson tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); 2247390e0e9SRichard Henderson 2257390e0e9SRichard Henderson if (mte) { 2267390e0e9SRichard Henderson desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s)); 2277390e0e9SRichard Henderson desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid); 2287390e0e9SRichard Henderson desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma); 2297390e0e9SRichard Henderson desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st); 2307390e0e9SRichard Henderson desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1); 2317390e0e9SRichard Henderson desc <<= SVE_MTEDESC_SHIFT; 2327390e0e9SRichard Henderson } else { 2337390e0e9SRichard Henderson addr = clean_data_tbi(s, addr); 2347390e0e9SRichard Henderson } 2357390e0e9SRichard Henderson svl = streaming_vec_reg_size(s); 2367390e0e9SRichard Henderson desc = simd_desc(svl, svl, desc); 2377390e0e9SRichard Henderson 2387390e0e9SRichard Henderson fns[a->esz][be][a->v][mte][a->st](cpu_env, t_za, t_pg, addr, 2397390e0e9SRichard Henderson tcg_constant_i32(desc)); 2407390e0e9SRichard Henderson 2417390e0e9SRichard Henderson tcg_temp_free_ptr(t_za); 2427390e0e9SRichard Henderson tcg_temp_free_ptr(t_pg); 2437390e0e9SRichard Henderson tcg_temp_free_i64(addr); 2447390e0e9SRichard Henderson return true; 2457390e0e9SRichard Henderson } 2464c46a5f1SRichard Henderson 2474c46a5f1SRichard Henderson typedef void GenLdStR(DisasContext *, TCGv_ptr, int, int, int, int); 2484c46a5f1SRichard Henderson 2494c46a5f1SRichard Henderson static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn) 2504c46a5f1SRichard Henderson { 2514c46a5f1SRichard Henderson int svl = streaming_vec_reg_size(s); 2524c46a5f1SRichard Henderson int imm = a->imm; 2534c46a5f1SRichard Henderson TCGv_ptr base; 2544c46a5f1SRichard Henderson 2554c46a5f1SRichard Henderson if (!sme_za_enabled_check(s)) { 2564c46a5f1SRichard Henderson return true; 2574c46a5f1SRichard Henderson } 2584c46a5f1SRichard Henderson 2594c46a5f1SRichard Henderson /* ZA[n] equates to ZA0H.B[n]. */ 2604c46a5f1SRichard Henderson base = get_tile_rowcol(s, MO_8, a->rv, imm, false); 2614c46a5f1SRichard Henderson 2624c46a5f1SRichard Henderson fn(s, base, 0, svl, a->rn, imm * svl); 2634c46a5f1SRichard Henderson 2644c46a5f1SRichard Henderson tcg_temp_free_ptr(base); 2654c46a5f1SRichard Henderson return true; 2664c46a5f1SRichard Henderson } 2674c46a5f1SRichard Henderson 2684c46a5f1SRichard Henderson TRANS_FEAT(LDR, aa64_sme, do_ldst_r, a, gen_sve_ldr) 2694c46a5f1SRichard Henderson TRANS_FEAT(STR, aa64_sme, do_ldst_r, a, gen_sve_str) 270bc4420d9SRichard Henderson 271bc4420d9SRichard Henderson static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz, 272bc4420d9SRichard Henderson gen_helper_gvec_4 *fn) 273bc4420d9SRichard Henderson { 274bc4420d9SRichard Henderson int svl = streaming_vec_reg_size(s); 275bc4420d9SRichard Henderson uint32_t desc = simd_desc(svl, svl, 0); 276bc4420d9SRichard Henderson TCGv_ptr za, zn, pn, pm; 277bc4420d9SRichard Henderson 278bc4420d9SRichard Henderson if (!sme_smza_enabled_check(s)) { 279bc4420d9SRichard Henderson return true; 280bc4420d9SRichard Henderson } 281bc4420d9SRichard Henderson 282bc4420d9SRichard Henderson /* Sum XZR+zad to find ZAd. */ 283bc4420d9SRichard Henderson za = get_tile_rowcol(s, esz, 31, a->zad, false); 284bc4420d9SRichard Henderson zn = vec_full_reg_ptr(s, a->zn); 285bc4420d9SRichard Henderson pn = pred_full_reg_ptr(s, a->pn); 286bc4420d9SRichard Henderson pm = pred_full_reg_ptr(s, a->pm); 287bc4420d9SRichard Henderson 288bc4420d9SRichard Henderson fn(za, zn, pn, pm, tcg_constant_i32(desc)); 289bc4420d9SRichard Henderson 290bc4420d9SRichard Henderson tcg_temp_free_ptr(za); 291bc4420d9SRichard Henderson tcg_temp_free_ptr(zn); 292bc4420d9SRichard Henderson tcg_temp_free_ptr(pn); 293bc4420d9SRichard Henderson tcg_temp_free_ptr(pm); 294bc4420d9SRichard Henderson return true; 295bc4420d9SRichard Henderson } 296bc4420d9SRichard Henderson 297bc4420d9SRichard Henderson TRANS_FEAT(ADDHA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addha_s) 298bc4420d9SRichard Henderson TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s) 299bc4420d9SRichard Henderson TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d) 300bc4420d9SRichard Henderson TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d) 301*558e956cSRichard Henderson 302*558e956cSRichard Henderson static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz, 303*558e956cSRichard Henderson gen_helper_gvec_5_ptr *fn) 304*558e956cSRichard Henderson { 305*558e956cSRichard Henderson int svl = streaming_vec_reg_size(s); 306*558e956cSRichard Henderson uint32_t desc = simd_desc(svl, svl, a->sub); 307*558e956cSRichard Henderson TCGv_ptr za, zn, zm, pn, pm, fpst; 308*558e956cSRichard Henderson 309*558e956cSRichard Henderson if (!sme_smza_enabled_check(s)) { 310*558e956cSRichard Henderson return true; 311*558e956cSRichard Henderson } 312*558e956cSRichard Henderson 313*558e956cSRichard Henderson /* Sum XZR+zad to find ZAd. */ 314*558e956cSRichard Henderson za = get_tile_rowcol(s, esz, 31, a->zad, false); 315*558e956cSRichard Henderson zn = vec_full_reg_ptr(s, a->zn); 316*558e956cSRichard Henderson zm = vec_full_reg_ptr(s, a->zm); 317*558e956cSRichard Henderson pn = pred_full_reg_ptr(s, a->pn); 318*558e956cSRichard Henderson pm = pred_full_reg_ptr(s, a->pm); 319*558e956cSRichard Henderson fpst = fpstatus_ptr(FPST_FPCR); 320*558e956cSRichard Henderson 321*558e956cSRichard Henderson fn(za, zn, zm, pn, pm, fpst, tcg_constant_i32(desc)); 322*558e956cSRichard Henderson 323*558e956cSRichard Henderson tcg_temp_free_ptr(za); 324*558e956cSRichard Henderson tcg_temp_free_ptr(zn); 325*558e956cSRichard Henderson tcg_temp_free_ptr(pn); 326*558e956cSRichard Henderson tcg_temp_free_ptr(pm); 327*558e956cSRichard Henderson tcg_temp_free_ptr(fpst); 328*558e956cSRichard Henderson return true; 329*558e956cSRichard Henderson } 330*558e956cSRichard Henderson 331*558e956cSRichard Henderson TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s) 332*558e956cSRichard Henderson TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d) 333