1f0984d40SFabiano Rosas /* 2f0984d40SFabiano Rosas * AArch64 SVE translation 3f0984d40SFabiano Rosas * 4f0984d40SFabiano Rosas * Copyright (c) 2018 Linaro, Ltd 5f0984d40SFabiano Rosas * 6f0984d40SFabiano Rosas * This library is free software; you can redistribute it and/or 7f0984d40SFabiano Rosas * modify it under the terms of the GNU Lesser General Public 8f0984d40SFabiano Rosas * License as published by the Free Software Foundation; either 9f0984d40SFabiano Rosas * version 2.1 of the License, or (at your option) any later version. 10f0984d40SFabiano Rosas * 11f0984d40SFabiano Rosas * This library is distributed in the hope that it will be useful, 12f0984d40SFabiano Rosas * but WITHOUT ANY WARRANTY; without even the implied warranty of 13f0984d40SFabiano Rosas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14f0984d40SFabiano Rosas * Lesser General Public License for more details. 15f0984d40SFabiano Rosas * 16f0984d40SFabiano Rosas * You should have received a copy of the GNU Lesser General Public 17f0984d40SFabiano Rosas * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18f0984d40SFabiano Rosas */ 19f0984d40SFabiano Rosas 20f0984d40SFabiano Rosas #include "qemu/osdep.h" 21f0984d40SFabiano Rosas #include "translate.h" 22f0984d40SFabiano Rosas #include "translate-a64.h" 23f0984d40SFabiano Rosas #include "fpu/softfloat.h" 24f0984d40SFabiano Rosas 25f0984d40SFabiano Rosas 26f0984d40SFabiano Rosas typedef void GVecGen2sFn(unsigned, uint32_t, uint32_t, 27f0984d40SFabiano Rosas TCGv_i64, uint32_t, uint32_t); 28f0984d40SFabiano Rosas 29f0984d40SFabiano Rosas typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr, 30f0984d40SFabiano Rosas TCGv_ptr, TCGv_i32); 31f0984d40SFabiano Rosas typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr, 32f0984d40SFabiano Rosas TCGv_ptr, TCGv_ptr, TCGv_i32); 33f0984d40SFabiano Rosas 34f0984d40SFabiano Rosas typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i32); 35f0984d40SFabiano Rosas typedef void gen_helper_gvec_mem_scatter(TCGv_env, TCGv_ptr, TCGv_ptr, 36f0984d40SFabiano Rosas TCGv_ptr, TCGv_i64, TCGv_i32); 37f0984d40SFabiano Rosas 38f0984d40SFabiano Rosas /* 39f0984d40SFabiano Rosas * Helpers for extracting complex instruction fields. 40f0984d40SFabiano Rosas */ 41f0984d40SFabiano Rosas 42f0984d40SFabiano Rosas /* See e.g. ASR (immediate, predicated). 43f0984d40SFabiano Rosas * Returns -1 for unallocated encoding; diagnose later. 44f0984d40SFabiano Rosas */ 45f0984d40SFabiano Rosas static int tszimm_esz(DisasContext *s, int x) 46f0984d40SFabiano Rosas { 47f0984d40SFabiano Rosas x >>= 3; /* discard imm3 */ 48f0984d40SFabiano Rosas return 31 - clz32(x); 49f0984d40SFabiano Rosas } 50f0984d40SFabiano Rosas 51f0984d40SFabiano Rosas static int tszimm_shr(DisasContext *s, int x) 52f0984d40SFabiano Rosas { 53f0984d40SFabiano Rosas return (16 << tszimm_esz(s, x)) - x; 54f0984d40SFabiano Rosas } 55f0984d40SFabiano Rosas 56f0984d40SFabiano Rosas /* See e.g. LSL (immediate, predicated). */ 57f0984d40SFabiano Rosas static int tszimm_shl(DisasContext *s, int x) 58f0984d40SFabiano Rosas { 59f0984d40SFabiano Rosas return x - (8 << tszimm_esz(s, x)); 60f0984d40SFabiano Rosas } 61f0984d40SFabiano Rosas 62f0984d40SFabiano Rosas /* The SH bit is in bit 8. Extract the low 8 and shift. */ 63f0984d40SFabiano Rosas static inline int expand_imm_sh8s(DisasContext *s, int x) 64f0984d40SFabiano Rosas { 65f0984d40SFabiano Rosas return (int8_t)x << (x & 0x100 ? 8 : 0); 66f0984d40SFabiano Rosas } 67f0984d40SFabiano Rosas 68f0984d40SFabiano Rosas static inline int expand_imm_sh8u(DisasContext *s, int x) 69f0984d40SFabiano Rosas { 70f0984d40SFabiano Rosas return (uint8_t)x << (x & 0x100 ? 8 : 0); 71f0984d40SFabiano Rosas } 72f0984d40SFabiano Rosas 73f0984d40SFabiano Rosas /* Convert a 2-bit memory size (msz) to a 4-bit data type (dtype) 74f0984d40SFabiano Rosas * with unsigned data. C.f. SVE Memory Contiguous Load Group. 75f0984d40SFabiano Rosas */ 76f0984d40SFabiano Rosas static inline int msz_dtype(DisasContext *s, int msz) 77f0984d40SFabiano Rosas { 78f0984d40SFabiano Rosas static const uint8_t dtype[4] = { 0, 5, 10, 15 }; 79f0984d40SFabiano Rosas return dtype[msz]; 80f0984d40SFabiano Rosas } 81f0984d40SFabiano Rosas 82f0984d40SFabiano Rosas /* 83f0984d40SFabiano Rosas * Include the generated decoder. 84f0984d40SFabiano Rosas */ 85f0984d40SFabiano Rosas 86f0984d40SFabiano Rosas #include "decode-sve.c.inc" 87f0984d40SFabiano Rosas 88f0984d40SFabiano Rosas /* 89f0984d40SFabiano Rosas * Implement all of the translator functions referenced by the decoder. 90f0984d40SFabiano Rosas */ 91f0984d40SFabiano Rosas 92f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 2 Zregs. */ 93f0984d40SFabiano Rosas static bool gen_gvec_ool_zz(DisasContext *s, gen_helper_gvec_2 *fn, 94f0984d40SFabiano Rosas int rd, int rn, int data) 95f0984d40SFabiano Rosas { 96f0984d40SFabiano Rosas if (fn == NULL) { 97f0984d40SFabiano Rosas return false; 98f0984d40SFabiano Rosas } 99f0984d40SFabiano Rosas if (sve_access_check(s)) { 100f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 101f0984d40SFabiano Rosas tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd), 102f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 103f0984d40SFabiano Rosas vsz, vsz, data, fn); 104f0984d40SFabiano Rosas } 105f0984d40SFabiano Rosas return true; 106f0984d40SFabiano Rosas } 107f0984d40SFabiano Rosas 108f0984d40SFabiano Rosas static bool gen_gvec_fpst_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn, 109f0984d40SFabiano Rosas int rd, int rn, int data, 110f0984d40SFabiano Rosas ARMFPStatusFlavour flavour) 111f0984d40SFabiano Rosas { 112f0984d40SFabiano Rosas if (fn == NULL) { 113f0984d40SFabiano Rosas return false; 114f0984d40SFabiano Rosas } 115f0984d40SFabiano Rosas if (sve_access_check(s)) { 116f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 117f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(flavour); 118f0984d40SFabiano Rosas 119f0984d40SFabiano Rosas tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd), 120f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 121f0984d40SFabiano Rosas status, vsz, vsz, data, fn); 122f0984d40SFabiano Rosas } 123f0984d40SFabiano Rosas return true; 124f0984d40SFabiano Rosas } 125f0984d40SFabiano Rosas 126f0984d40SFabiano Rosas static bool gen_gvec_fpst_arg_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn, 127f0984d40SFabiano Rosas arg_rr_esz *a, int data) 128f0984d40SFabiano Rosas { 129f0984d40SFabiano Rosas return gen_gvec_fpst_zz(s, fn, a->rd, a->rn, data, 130f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 131f0984d40SFabiano Rosas } 132f0984d40SFabiano Rosas 133f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 3 Zregs. */ 134f0984d40SFabiano Rosas static bool gen_gvec_ool_zzz(DisasContext *s, gen_helper_gvec_3 *fn, 135f0984d40SFabiano Rosas int rd, int rn, int rm, int data) 136f0984d40SFabiano Rosas { 137f0984d40SFabiano Rosas if (fn == NULL) { 138f0984d40SFabiano Rosas return false; 139f0984d40SFabiano Rosas } 140f0984d40SFabiano Rosas if (sve_access_check(s)) { 141f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 142f0984d40SFabiano Rosas tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd), 143f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 144f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 145f0984d40SFabiano Rosas vsz, vsz, data, fn); 146f0984d40SFabiano Rosas } 147f0984d40SFabiano Rosas return true; 148f0984d40SFabiano Rosas } 149f0984d40SFabiano Rosas 150f0984d40SFabiano Rosas static bool gen_gvec_ool_arg_zzz(DisasContext *s, gen_helper_gvec_3 *fn, 151f0984d40SFabiano Rosas arg_rrr_esz *a, int data) 152f0984d40SFabiano Rosas { 153f0984d40SFabiano Rosas return gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, data); 154f0984d40SFabiano Rosas } 155f0984d40SFabiano Rosas 156f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 3 Zregs, plus float_status. */ 157f0984d40SFabiano Rosas static bool gen_gvec_fpst_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn, 158f0984d40SFabiano Rosas int rd, int rn, int rm, 159f0984d40SFabiano Rosas int data, ARMFPStatusFlavour flavour) 160f0984d40SFabiano Rosas { 161f0984d40SFabiano Rosas if (fn == NULL) { 162f0984d40SFabiano Rosas return false; 163f0984d40SFabiano Rosas } 164f0984d40SFabiano Rosas if (sve_access_check(s)) { 165f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 166f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(flavour); 167f0984d40SFabiano Rosas 168f0984d40SFabiano Rosas tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), 169f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 170f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 171f0984d40SFabiano Rosas status, vsz, vsz, data, fn); 172f0984d40SFabiano Rosas } 173f0984d40SFabiano Rosas return true; 174f0984d40SFabiano Rosas } 175f0984d40SFabiano Rosas 176f0984d40SFabiano Rosas static bool gen_gvec_fpst_arg_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn, 177f0984d40SFabiano Rosas arg_rrr_esz *a, int data) 178f0984d40SFabiano Rosas { 179f0984d40SFabiano Rosas return gen_gvec_fpst_zzz(s, fn, a->rd, a->rn, a->rm, data, 180f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 181f0984d40SFabiano Rosas } 182f0984d40SFabiano Rosas 183f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 4 Zregs. */ 184f0984d40SFabiano Rosas static bool gen_gvec_ool_zzzz(DisasContext *s, gen_helper_gvec_4 *fn, 185f0984d40SFabiano Rosas int rd, int rn, int rm, int ra, int data) 186f0984d40SFabiano Rosas { 187f0984d40SFabiano Rosas if (fn == NULL) { 188f0984d40SFabiano Rosas return false; 189f0984d40SFabiano Rosas } 190f0984d40SFabiano Rosas if (sve_access_check(s)) { 191f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 192f0984d40SFabiano Rosas tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd), 193f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 194f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 195f0984d40SFabiano Rosas vec_full_reg_offset(s, ra), 196f0984d40SFabiano Rosas vsz, vsz, data, fn); 197f0984d40SFabiano Rosas } 198f0984d40SFabiano Rosas return true; 199f0984d40SFabiano Rosas } 200f0984d40SFabiano Rosas 201f0984d40SFabiano Rosas static bool gen_gvec_ool_arg_zzzz(DisasContext *s, gen_helper_gvec_4 *fn, 202f0984d40SFabiano Rosas arg_rrrr_esz *a, int data) 203f0984d40SFabiano Rosas { 204f0984d40SFabiano Rosas return gen_gvec_ool_zzzz(s, fn, a->rd, a->rn, a->rm, a->ra, data); 205f0984d40SFabiano Rosas } 206f0984d40SFabiano Rosas 207f0984d40SFabiano Rosas static bool gen_gvec_ool_arg_zzxz(DisasContext *s, gen_helper_gvec_4 *fn, 208f0984d40SFabiano Rosas arg_rrxr_esz *a) 209f0984d40SFabiano Rosas { 210f0984d40SFabiano Rosas return gen_gvec_ool_zzzz(s, fn, a->rd, a->rn, a->rm, a->ra, a->index); 211f0984d40SFabiano Rosas } 212f0984d40SFabiano Rosas 213f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 4 Zregs, plus a pointer. */ 214f0984d40SFabiano Rosas static bool gen_gvec_ptr_zzzz(DisasContext *s, gen_helper_gvec_4_ptr *fn, 215f0984d40SFabiano Rosas int rd, int rn, int rm, int ra, 216f0984d40SFabiano Rosas int data, TCGv_ptr ptr) 217f0984d40SFabiano Rosas { 218f0984d40SFabiano Rosas if (fn == NULL) { 219f0984d40SFabiano Rosas return false; 220f0984d40SFabiano Rosas } 221f0984d40SFabiano Rosas if (sve_access_check(s)) { 222f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 223f0984d40SFabiano Rosas tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd), 224f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 225f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 226f0984d40SFabiano Rosas vec_full_reg_offset(s, ra), 227f0984d40SFabiano Rosas ptr, vsz, vsz, data, fn); 228f0984d40SFabiano Rosas } 229f0984d40SFabiano Rosas return true; 230f0984d40SFabiano Rosas } 231f0984d40SFabiano Rosas 232f0984d40SFabiano Rosas static bool gen_gvec_fpst_zzzz(DisasContext *s, gen_helper_gvec_4_ptr *fn, 233f0984d40SFabiano Rosas int rd, int rn, int rm, int ra, 234f0984d40SFabiano Rosas int data, ARMFPStatusFlavour flavour) 235f0984d40SFabiano Rosas { 236f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(flavour); 237f0984d40SFabiano Rosas bool ret = gen_gvec_ptr_zzzz(s, fn, rd, rn, rm, ra, data, status); 238f0984d40SFabiano Rosas return ret; 239f0984d40SFabiano Rosas } 240f0984d40SFabiano Rosas 241f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 4 Zregs, 1 Preg, plus fpst. */ 242f0984d40SFabiano Rosas static bool gen_gvec_fpst_zzzzp(DisasContext *s, gen_helper_gvec_5_ptr *fn, 243f0984d40SFabiano Rosas int rd, int rn, int rm, int ra, int pg, 244f0984d40SFabiano Rosas int data, ARMFPStatusFlavour flavour) 245f0984d40SFabiano Rosas { 246f0984d40SFabiano Rosas if (fn == NULL) { 247f0984d40SFabiano Rosas return false; 248f0984d40SFabiano Rosas } 249f0984d40SFabiano Rosas if (sve_access_check(s)) { 250f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 251f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(flavour); 252f0984d40SFabiano Rosas 253f0984d40SFabiano Rosas tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, rd), 254f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 255f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 256f0984d40SFabiano Rosas vec_full_reg_offset(s, ra), 257f0984d40SFabiano Rosas pred_full_reg_offset(s, pg), 258f0984d40SFabiano Rosas status, vsz, vsz, data, fn); 259f0984d40SFabiano Rosas } 260f0984d40SFabiano Rosas return true; 261f0984d40SFabiano Rosas } 262f0984d40SFabiano Rosas 263f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 2 Zregs and a predicate. */ 264f0984d40SFabiano Rosas static bool gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn, 265f0984d40SFabiano Rosas int rd, int rn, int pg, int data) 266f0984d40SFabiano Rosas { 267f0984d40SFabiano Rosas if (fn == NULL) { 268f0984d40SFabiano Rosas return false; 269f0984d40SFabiano Rosas } 270f0984d40SFabiano Rosas if (sve_access_check(s)) { 271f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 272f0984d40SFabiano Rosas tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd), 273f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 274f0984d40SFabiano Rosas pred_full_reg_offset(s, pg), 275f0984d40SFabiano Rosas vsz, vsz, data, fn); 276f0984d40SFabiano Rosas } 277f0984d40SFabiano Rosas return true; 278f0984d40SFabiano Rosas } 279f0984d40SFabiano Rosas 280f0984d40SFabiano Rosas static bool gen_gvec_ool_arg_zpz(DisasContext *s, gen_helper_gvec_3 *fn, 281f0984d40SFabiano Rosas arg_rpr_esz *a, int data) 282f0984d40SFabiano Rosas { 283f0984d40SFabiano Rosas return gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, data); 284f0984d40SFabiano Rosas } 285f0984d40SFabiano Rosas 286f0984d40SFabiano Rosas static bool gen_gvec_ool_arg_zpzi(DisasContext *s, gen_helper_gvec_3 *fn, 287f0984d40SFabiano Rosas arg_rpri_esz *a) 288f0984d40SFabiano Rosas { 289f0984d40SFabiano Rosas return gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, a->imm); 290f0984d40SFabiano Rosas } 291f0984d40SFabiano Rosas 292f0984d40SFabiano Rosas static bool gen_gvec_fpst_zzp(DisasContext *s, gen_helper_gvec_3_ptr *fn, 293f0984d40SFabiano Rosas int rd, int rn, int pg, int data, 294f0984d40SFabiano Rosas ARMFPStatusFlavour flavour) 295f0984d40SFabiano Rosas { 296f0984d40SFabiano Rosas if (fn == NULL) { 297f0984d40SFabiano Rosas return false; 298f0984d40SFabiano Rosas } 299f0984d40SFabiano Rosas if (sve_access_check(s)) { 300f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 301f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(flavour); 302f0984d40SFabiano Rosas 303f0984d40SFabiano Rosas tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), 304f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 305f0984d40SFabiano Rosas pred_full_reg_offset(s, pg), 306f0984d40SFabiano Rosas status, vsz, vsz, data, fn); 307f0984d40SFabiano Rosas } 308f0984d40SFabiano Rosas return true; 309f0984d40SFabiano Rosas } 310f0984d40SFabiano Rosas 311f0984d40SFabiano Rosas static bool gen_gvec_fpst_arg_zpz(DisasContext *s, gen_helper_gvec_3_ptr *fn, 312f0984d40SFabiano Rosas arg_rpr_esz *a, int data, 313f0984d40SFabiano Rosas ARMFPStatusFlavour flavour) 314f0984d40SFabiano Rosas { 315f0984d40SFabiano Rosas return gen_gvec_fpst_zzp(s, fn, a->rd, a->rn, a->pg, data, flavour); 316f0984d40SFabiano Rosas } 317f0984d40SFabiano Rosas 318f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 3 Zregs and a predicate. */ 319f0984d40SFabiano Rosas static bool gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn, 320f0984d40SFabiano Rosas int rd, int rn, int rm, int pg, int data) 321f0984d40SFabiano Rosas { 322f0984d40SFabiano Rosas if (fn == NULL) { 323f0984d40SFabiano Rosas return false; 324f0984d40SFabiano Rosas } 325f0984d40SFabiano Rosas if (sve_access_check(s)) { 326f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 327f0984d40SFabiano Rosas tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd), 328f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 329f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 330f0984d40SFabiano Rosas pred_full_reg_offset(s, pg), 331f0984d40SFabiano Rosas vsz, vsz, data, fn); 332f0984d40SFabiano Rosas } 333f0984d40SFabiano Rosas return true; 334f0984d40SFabiano Rosas } 335f0984d40SFabiano Rosas 336f0984d40SFabiano Rosas static bool gen_gvec_ool_arg_zpzz(DisasContext *s, gen_helper_gvec_4 *fn, 337f0984d40SFabiano Rosas arg_rprr_esz *a, int data) 338f0984d40SFabiano Rosas { 339f0984d40SFabiano Rosas return gen_gvec_ool_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, data); 340f0984d40SFabiano Rosas } 341f0984d40SFabiano Rosas 342f0984d40SFabiano Rosas /* Invoke an out-of-line helper on 3 Zregs and a predicate. */ 343f0984d40SFabiano Rosas static bool gen_gvec_fpst_zzzp(DisasContext *s, gen_helper_gvec_4_ptr *fn, 344f0984d40SFabiano Rosas int rd, int rn, int rm, int pg, int data, 345f0984d40SFabiano Rosas ARMFPStatusFlavour flavour) 346f0984d40SFabiano Rosas { 347f0984d40SFabiano Rosas if (fn == NULL) { 348f0984d40SFabiano Rosas return false; 349f0984d40SFabiano Rosas } 350f0984d40SFabiano Rosas if (sve_access_check(s)) { 351f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 352f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(flavour); 353f0984d40SFabiano Rosas 354f0984d40SFabiano Rosas tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd), 355f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 356f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), 357f0984d40SFabiano Rosas pred_full_reg_offset(s, pg), 358f0984d40SFabiano Rosas status, vsz, vsz, data, fn); 359f0984d40SFabiano Rosas } 360f0984d40SFabiano Rosas return true; 361f0984d40SFabiano Rosas } 362f0984d40SFabiano Rosas 363f0984d40SFabiano Rosas static bool gen_gvec_fpst_arg_zpzz(DisasContext *s, gen_helper_gvec_4_ptr *fn, 364f0984d40SFabiano Rosas arg_rprr_esz *a) 365f0984d40SFabiano Rosas { 366f0984d40SFabiano Rosas return gen_gvec_fpst_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0, 367f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 368f0984d40SFabiano Rosas } 369f0984d40SFabiano Rosas 370f0984d40SFabiano Rosas /* Invoke a vector expander on two Zregs and an immediate. */ 371f0984d40SFabiano Rosas static bool gen_gvec_fn_zzi(DisasContext *s, GVecGen2iFn *gvec_fn, 372f0984d40SFabiano Rosas int esz, int rd, int rn, uint64_t imm) 373f0984d40SFabiano Rosas { 374f0984d40SFabiano Rosas if (gvec_fn == NULL) { 375f0984d40SFabiano Rosas return false; 376f0984d40SFabiano Rosas } 377f0984d40SFabiano Rosas if (sve_access_check(s)) { 378f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 379f0984d40SFabiano Rosas gvec_fn(esz, vec_full_reg_offset(s, rd), 380f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), imm, vsz, vsz); 381f0984d40SFabiano Rosas } 382f0984d40SFabiano Rosas return true; 383f0984d40SFabiano Rosas } 384f0984d40SFabiano Rosas 385f0984d40SFabiano Rosas static bool gen_gvec_fn_arg_zzi(DisasContext *s, GVecGen2iFn *gvec_fn, 386f0984d40SFabiano Rosas arg_rri_esz *a) 387f0984d40SFabiano Rosas { 388f0984d40SFabiano Rosas if (a->esz < 0) { 389f0984d40SFabiano Rosas /* Invalid tsz encoding -- see tszimm_esz. */ 390f0984d40SFabiano Rosas return false; 391f0984d40SFabiano Rosas } 392f0984d40SFabiano Rosas return gen_gvec_fn_zzi(s, gvec_fn, a->esz, a->rd, a->rn, a->imm); 393f0984d40SFabiano Rosas } 394f0984d40SFabiano Rosas 395f0984d40SFabiano Rosas /* Invoke a vector expander on three Zregs. */ 396f0984d40SFabiano Rosas static bool gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn, 397f0984d40SFabiano Rosas int esz, int rd, int rn, int rm) 398f0984d40SFabiano Rosas { 399f0984d40SFabiano Rosas if (gvec_fn == NULL) { 400f0984d40SFabiano Rosas return false; 401f0984d40SFabiano Rosas } 402f0984d40SFabiano Rosas if (sve_access_check(s)) { 403f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 404f0984d40SFabiano Rosas gvec_fn(esz, vec_full_reg_offset(s, rd), 405f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), 406f0984d40SFabiano Rosas vec_full_reg_offset(s, rm), vsz, vsz); 407f0984d40SFabiano Rosas } 408f0984d40SFabiano Rosas return true; 409f0984d40SFabiano Rosas } 410f0984d40SFabiano Rosas 411f0984d40SFabiano Rosas static bool gen_gvec_fn_arg_zzz(DisasContext *s, GVecGen3Fn *fn, 412f0984d40SFabiano Rosas arg_rrr_esz *a) 413f0984d40SFabiano Rosas { 414f0984d40SFabiano Rosas return gen_gvec_fn_zzz(s, fn, a->esz, a->rd, a->rn, a->rm); 415f0984d40SFabiano Rosas } 416f0984d40SFabiano Rosas 417f0984d40SFabiano Rosas /* Invoke a vector expander on four Zregs. */ 418f0984d40SFabiano Rosas static bool gen_gvec_fn_arg_zzzz(DisasContext *s, GVecGen4Fn *gvec_fn, 419f0984d40SFabiano Rosas arg_rrrr_esz *a) 420f0984d40SFabiano Rosas { 421f0984d40SFabiano Rosas if (gvec_fn == NULL) { 422f0984d40SFabiano Rosas return false; 423f0984d40SFabiano Rosas } 424f0984d40SFabiano Rosas if (sve_access_check(s)) { 425f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 426f0984d40SFabiano Rosas gvec_fn(a->esz, vec_full_reg_offset(s, a->rd), 427f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 428f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rm), 429f0984d40SFabiano Rosas vec_full_reg_offset(s, a->ra), vsz, vsz); 430f0984d40SFabiano Rosas } 431f0984d40SFabiano Rosas return true; 432f0984d40SFabiano Rosas } 433f0984d40SFabiano Rosas 434f0984d40SFabiano Rosas /* Invoke a vector move on two Zregs. */ 435f0984d40SFabiano Rosas static bool do_mov_z(DisasContext *s, int rd, int rn) 436f0984d40SFabiano Rosas { 437f0984d40SFabiano Rosas if (sve_access_check(s)) { 438f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 439f0984d40SFabiano Rosas tcg_gen_gvec_mov(MO_8, vec_full_reg_offset(s, rd), 440f0984d40SFabiano Rosas vec_full_reg_offset(s, rn), vsz, vsz); 441f0984d40SFabiano Rosas } 442f0984d40SFabiano Rosas return true; 443f0984d40SFabiano Rosas } 444f0984d40SFabiano Rosas 445f0984d40SFabiano Rosas /* Initialize a Zreg with replications of a 64-bit immediate. */ 446f0984d40SFabiano Rosas static void do_dupi_z(DisasContext *s, int rd, uint64_t word) 447f0984d40SFabiano Rosas { 448f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 449f0984d40SFabiano Rosas tcg_gen_gvec_dup_imm(MO_64, vec_full_reg_offset(s, rd), vsz, vsz, word); 450f0984d40SFabiano Rosas } 451f0984d40SFabiano Rosas 452f0984d40SFabiano Rosas /* Invoke a vector expander on three Pregs. */ 453f0984d40SFabiano Rosas static bool gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn, 454f0984d40SFabiano Rosas int rd, int rn, int rm) 455f0984d40SFabiano Rosas { 456f0984d40SFabiano Rosas if (sve_access_check(s)) { 457f0984d40SFabiano Rosas unsigned psz = pred_gvec_reg_size(s); 458f0984d40SFabiano Rosas gvec_fn(MO_64, pred_full_reg_offset(s, rd), 459f0984d40SFabiano Rosas pred_full_reg_offset(s, rn), 460f0984d40SFabiano Rosas pred_full_reg_offset(s, rm), psz, psz); 461f0984d40SFabiano Rosas } 462f0984d40SFabiano Rosas return true; 463f0984d40SFabiano Rosas } 464f0984d40SFabiano Rosas 465f0984d40SFabiano Rosas /* Invoke a vector move on two Pregs. */ 466f0984d40SFabiano Rosas static bool do_mov_p(DisasContext *s, int rd, int rn) 467f0984d40SFabiano Rosas { 468f0984d40SFabiano Rosas if (sve_access_check(s)) { 469f0984d40SFabiano Rosas unsigned psz = pred_gvec_reg_size(s); 470f0984d40SFabiano Rosas tcg_gen_gvec_mov(MO_8, pred_full_reg_offset(s, rd), 471f0984d40SFabiano Rosas pred_full_reg_offset(s, rn), psz, psz); 472f0984d40SFabiano Rosas } 473f0984d40SFabiano Rosas return true; 474f0984d40SFabiano Rosas } 475f0984d40SFabiano Rosas 476f0984d40SFabiano Rosas /* Set the cpu flags as per a return from an SVE helper. */ 477f0984d40SFabiano Rosas static void do_pred_flags(TCGv_i32 t) 478f0984d40SFabiano Rosas { 479f0984d40SFabiano Rosas tcg_gen_mov_i32(cpu_NF, t); 480f0984d40SFabiano Rosas tcg_gen_andi_i32(cpu_ZF, t, 2); 481f0984d40SFabiano Rosas tcg_gen_andi_i32(cpu_CF, t, 1); 482f0984d40SFabiano Rosas tcg_gen_movi_i32(cpu_VF, 0); 483f0984d40SFabiano Rosas } 484f0984d40SFabiano Rosas 485f0984d40SFabiano Rosas /* Subroutines computing the ARM PredTest psuedofunction. */ 486f0984d40SFabiano Rosas static void do_predtest1(TCGv_i64 d, TCGv_i64 g) 487f0984d40SFabiano Rosas { 488f0984d40SFabiano Rosas TCGv_i32 t = tcg_temp_new_i32(); 489f0984d40SFabiano Rosas 490f0984d40SFabiano Rosas gen_helper_sve_predtest1(t, d, g); 491f0984d40SFabiano Rosas do_pred_flags(t); 492f0984d40SFabiano Rosas } 493f0984d40SFabiano Rosas 494f0984d40SFabiano Rosas static void do_predtest(DisasContext *s, int dofs, int gofs, int words) 495f0984d40SFabiano Rosas { 496f0984d40SFabiano Rosas TCGv_ptr dptr = tcg_temp_new_ptr(); 497f0984d40SFabiano Rosas TCGv_ptr gptr = tcg_temp_new_ptr(); 498f0984d40SFabiano Rosas TCGv_i32 t = tcg_temp_new_i32(); 499f0984d40SFabiano Rosas 500*ad75a51eSRichard Henderson tcg_gen_addi_ptr(dptr, tcg_env, dofs); 501*ad75a51eSRichard Henderson tcg_gen_addi_ptr(gptr, tcg_env, gofs); 502f0984d40SFabiano Rosas 503f0984d40SFabiano Rosas gen_helper_sve_predtest(t, dptr, gptr, tcg_constant_i32(words)); 504f0984d40SFabiano Rosas 505f0984d40SFabiano Rosas do_pred_flags(t); 506f0984d40SFabiano Rosas } 507f0984d40SFabiano Rosas 508f0984d40SFabiano Rosas /* For each element size, the bits within a predicate word that are active. */ 509f0984d40SFabiano Rosas const uint64_t pred_esz_masks[5] = { 510f0984d40SFabiano Rosas 0xffffffffffffffffull, 0x5555555555555555ull, 511f0984d40SFabiano Rosas 0x1111111111111111ull, 0x0101010101010101ull, 512f0984d40SFabiano Rosas 0x0001000100010001ull, 513f0984d40SFabiano Rosas }; 514f0984d40SFabiano Rosas 515f0984d40SFabiano Rosas static bool trans_INVALID(DisasContext *s, arg_INVALID *a) 516f0984d40SFabiano Rosas { 517f0984d40SFabiano Rosas unallocated_encoding(s); 518f0984d40SFabiano Rosas return true; 519f0984d40SFabiano Rosas } 520f0984d40SFabiano Rosas 521f0984d40SFabiano Rosas /* 522f0984d40SFabiano Rosas *** SVE Logical - Unpredicated Group 523f0984d40SFabiano Rosas */ 524f0984d40SFabiano Rosas 525f0984d40SFabiano Rosas TRANS_FEAT(AND_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_and, a) 526f0984d40SFabiano Rosas TRANS_FEAT(ORR_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_or, a) 527f0984d40SFabiano Rosas TRANS_FEAT(EOR_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_xor, a) 528f0984d40SFabiano Rosas TRANS_FEAT(BIC_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_andc, a) 529f0984d40SFabiano Rosas 530f0984d40SFabiano Rosas static void gen_xar8_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh) 531f0984d40SFabiano Rosas { 532f0984d40SFabiano Rosas TCGv_i64 t = tcg_temp_new_i64(); 533f0984d40SFabiano Rosas uint64_t mask = dup_const(MO_8, 0xff >> sh); 534f0984d40SFabiano Rosas 535f0984d40SFabiano Rosas tcg_gen_xor_i64(t, n, m); 536f0984d40SFabiano Rosas tcg_gen_shri_i64(d, t, sh); 537f0984d40SFabiano Rosas tcg_gen_shli_i64(t, t, 8 - sh); 538f0984d40SFabiano Rosas tcg_gen_andi_i64(d, d, mask); 539f0984d40SFabiano Rosas tcg_gen_andi_i64(t, t, ~mask); 540f0984d40SFabiano Rosas tcg_gen_or_i64(d, d, t); 541f0984d40SFabiano Rosas } 542f0984d40SFabiano Rosas 543f0984d40SFabiano Rosas static void gen_xar16_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh) 544f0984d40SFabiano Rosas { 545f0984d40SFabiano Rosas TCGv_i64 t = tcg_temp_new_i64(); 546f0984d40SFabiano Rosas uint64_t mask = dup_const(MO_16, 0xffff >> sh); 547f0984d40SFabiano Rosas 548f0984d40SFabiano Rosas tcg_gen_xor_i64(t, n, m); 549f0984d40SFabiano Rosas tcg_gen_shri_i64(d, t, sh); 550f0984d40SFabiano Rosas tcg_gen_shli_i64(t, t, 16 - sh); 551f0984d40SFabiano Rosas tcg_gen_andi_i64(d, d, mask); 552f0984d40SFabiano Rosas tcg_gen_andi_i64(t, t, ~mask); 553f0984d40SFabiano Rosas tcg_gen_or_i64(d, d, t); 554f0984d40SFabiano Rosas } 555f0984d40SFabiano Rosas 556f0984d40SFabiano Rosas static void gen_xar_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, int32_t sh) 557f0984d40SFabiano Rosas { 558f0984d40SFabiano Rosas tcg_gen_xor_i32(d, n, m); 559f0984d40SFabiano Rosas tcg_gen_rotri_i32(d, d, sh); 560f0984d40SFabiano Rosas } 561f0984d40SFabiano Rosas 562f0984d40SFabiano Rosas static void gen_xar_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh) 563f0984d40SFabiano Rosas { 564f0984d40SFabiano Rosas tcg_gen_xor_i64(d, n, m); 565f0984d40SFabiano Rosas tcg_gen_rotri_i64(d, d, sh); 566f0984d40SFabiano Rosas } 567f0984d40SFabiano Rosas 568f0984d40SFabiano Rosas static void gen_xar_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 569f0984d40SFabiano Rosas TCGv_vec m, int64_t sh) 570f0984d40SFabiano Rosas { 571f0984d40SFabiano Rosas tcg_gen_xor_vec(vece, d, n, m); 572f0984d40SFabiano Rosas tcg_gen_rotri_vec(vece, d, d, sh); 573f0984d40SFabiano Rosas } 574f0984d40SFabiano Rosas 575f0984d40SFabiano Rosas void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, 576f0984d40SFabiano Rosas uint32_t rm_ofs, int64_t shift, 577f0984d40SFabiano Rosas uint32_t opr_sz, uint32_t max_sz) 578f0984d40SFabiano Rosas { 579f0984d40SFabiano Rosas static const TCGOpcode vecop[] = { INDEX_op_rotli_vec, 0 }; 580f0984d40SFabiano Rosas static const GVecGen3i ops[4] = { 581f0984d40SFabiano Rosas { .fni8 = gen_xar8_i64, 582f0984d40SFabiano Rosas .fniv = gen_xar_vec, 583f0984d40SFabiano Rosas .fno = gen_helper_sve2_xar_b, 584f0984d40SFabiano Rosas .opt_opc = vecop, 585f0984d40SFabiano Rosas .vece = MO_8 }, 586f0984d40SFabiano Rosas { .fni8 = gen_xar16_i64, 587f0984d40SFabiano Rosas .fniv = gen_xar_vec, 588f0984d40SFabiano Rosas .fno = gen_helper_sve2_xar_h, 589f0984d40SFabiano Rosas .opt_opc = vecop, 590f0984d40SFabiano Rosas .vece = MO_16 }, 591f0984d40SFabiano Rosas { .fni4 = gen_xar_i32, 592f0984d40SFabiano Rosas .fniv = gen_xar_vec, 593f0984d40SFabiano Rosas .fno = gen_helper_sve2_xar_s, 594f0984d40SFabiano Rosas .opt_opc = vecop, 595f0984d40SFabiano Rosas .vece = MO_32 }, 596f0984d40SFabiano Rosas { .fni8 = gen_xar_i64, 597f0984d40SFabiano Rosas .fniv = gen_xar_vec, 598f0984d40SFabiano Rosas .fno = gen_helper_gvec_xar_d, 599f0984d40SFabiano Rosas .opt_opc = vecop, 600f0984d40SFabiano Rosas .vece = MO_64 } 601f0984d40SFabiano Rosas }; 602f0984d40SFabiano Rosas int esize = 8 << vece; 603f0984d40SFabiano Rosas 604f0984d40SFabiano Rosas /* The SVE2 range is 1 .. esize; the AdvSIMD range is 0 .. esize-1. */ 605f0984d40SFabiano Rosas tcg_debug_assert(shift >= 0); 606f0984d40SFabiano Rosas tcg_debug_assert(shift <= esize); 607f0984d40SFabiano Rosas shift &= esize - 1; 608f0984d40SFabiano Rosas 609f0984d40SFabiano Rosas if (shift == 0) { 610f0984d40SFabiano Rosas /* xar with no rotate devolves to xor. */ 611f0984d40SFabiano Rosas tcg_gen_gvec_xor(vece, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz); 612f0984d40SFabiano Rosas } else { 613f0984d40SFabiano Rosas tcg_gen_gvec_3i(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 614f0984d40SFabiano Rosas shift, &ops[vece]); 615f0984d40SFabiano Rosas } 616f0984d40SFabiano Rosas } 617f0984d40SFabiano Rosas 618f0984d40SFabiano Rosas static bool trans_XAR(DisasContext *s, arg_rrri_esz *a) 619f0984d40SFabiano Rosas { 620f0984d40SFabiano Rosas if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) { 621f0984d40SFabiano Rosas return false; 622f0984d40SFabiano Rosas } 623f0984d40SFabiano Rosas if (sve_access_check(s)) { 624f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 625f0984d40SFabiano Rosas gen_gvec_xar(a->esz, vec_full_reg_offset(s, a->rd), 626f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 627f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rm), a->imm, vsz, vsz); 628f0984d40SFabiano Rosas } 629f0984d40SFabiano Rosas return true; 630f0984d40SFabiano Rosas } 631f0984d40SFabiano Rosas 632f0984d40SFabiano Rosas static void gen_eor3_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k) 633f0984d40SFabiano Rosas { 634f0984d40SFabiano Rosas tcg_gen_xor_i64(d, n, m); 635f0984d40SFabiano Rosas tcg_gen_xor_i64(d, d, k); 636f0984d40SFabiano Rosas } 637f0984d40SFabiano Rosas 638f0984d40SFabiano Rosas static void gen_eor3_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 639f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec k) 640f0984d40SFabiano Rosas { 641f0984d40SFabiano Rosas tcg_gen_xor_vec(vece, d, n, m); 642f0984d40SFabiano Rosas tcg_gen_xor_vec(vece, d, d, k); 643f0984d40SFabiano Rosas } 644f0984d40SFabiano Rosas 645f0984d40SFabiano Rosas static void gen_eor3(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 646f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 647f0984d40SFabiano Rosas { 648f0984d40SFabiano Rosas static const GVecGen4 op = { 649f0984d40SFabiano Rosas .fni8 = gen_eor3_i64, 650f0984d40SFabiano Rosas .fniv = gen_eor3_vec, 651f0984d40SFabiano Rosas .fno = gen_helper_sve2_eor3, 652f0984d40SFabiano Rosas .vece = MO_64, 653f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 654f0984d40SFabiano Rosas }; 655f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op); 656f0984d40SFabiano Rosas } 657f0984d40SFabiano Rosas 658f0984d40SFabiano Rosas TRANS_FEAT(EOR3, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_eor3, a) 659f0984d40SFabiano Rosas 660f0984d40SFabiano Rosas static void gen_bcax_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k) 661f0984d40SFabiano Rosas { 662f0984d40SFabiano Rosas tcg_gen_andc_i64(d, m, k); 663f0984d40SFabiano Rosas tcg_gen_xor_i64(d, d, n); 664f0984d40SFabiano Rosas } 665f0984d40SFabiano Rosas 666f0984d40SFabiano Rosas static void gen_bcax_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 667f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec k) 668f0984d40SFabiano Rosas { 669f0984d40SFabiano Rosas tcg_gen_andc_vec(vece, d, m, k); 670f0984d40SFabiano Rosas tcg_gen_xor_vec(vece, d, d, n); 671f0984d40SFabiano Rosas } 672f0984d40SFabiano Rosas 673f0984d40SFabiano Rosas static void gen_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 674f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 675f0984d40SFabiano Rosas { 676f0984d40SFabiano Rosas static const GVecGen4 op = { 677f0984d40SFabiano Rosas .fni8 = gen_bcax_i64, 678f0984d40SFabiano Rosas .fniv = gen_bcax_vec, 679f0984d40SFabiano Rosas .fno = gen_helper_sve2_bcax, 680f0984d40SFabiano Rosas .vece = MO_64, 681f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 682f0984d40SFabiano Rosas }; 683f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op); 684f0984d40SFabiano Rosas } 685f0984d40SFabiano Rosas 686f0984d40SFabiano Rosas TRANS_FEAT(BCAX, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_bcax, a) 687f0984d40SFabiano Rosas 688f0984d40SFabiano Rosas static void gen_bsl(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 689f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 690f0984d40SFabiano Rosas { 691f0984d40SFabiano Rosas /* BSL differs from the generic bitsel in argument ordering. */ 692f0984d40SFabiano Rosas tcg_gen_gvec_bitsel(vece, d, a, n, m, oprsz, maxsz); 693f0984d40SFabiano Rosas } 694f0984d40SFabiano Rosas 695f0984d40SFabiano Rosas TRANS_FEAT(BSL, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_bsl, a) 696f0984d40SFabiano Rosas 697f0984d40SFabiano Rosas static void gen_bsl1n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k) 698f0984d40SFabiano Rosas { 699f0984d40SFabiano Rosas tcg_gen_andc_i64(n, k, n); 700f0984d40SFabiano Rosas tcg_gen_andc_i64(m, m, k); 701f0984d40SFabiano Rosas tcg_gen_or_i64(d, n, m); 702f0984d40SFabiano Rosas } 703f0984d40SFabiano Rosas 704f0984d40SFabiano Rosas static void gen_bsl1n_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 705f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec k) 706f0984d40SFabiano Rosas { 707f0984d40SFabiano Rosas if (TCG_TARGET_HAS_bitsel_vec) { 708f0984d40SFabiano Rosas tcg_gen_not_vec(vece, n, n); 709f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, k, n, m); 710f0984d40SFabiano Rosas } else { 711f0984d40SFabiano Rosas tcg_gen_andc_vec(vece, n, k, n); 712f0984d40SFabiano Rosas tcg_gen_andc_vec(vece, m, m, k); 713f0984d40SFabiano Rosas tcg_gen_or_vec(vece, d, n, m); 714f0984d40SFabiano Rosas } 715f0984d40SFabiano Rosas } 716f0984d40SFabiano Rosas 717f0984d40SFabiano Rosas static void gen_bsl1n(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 718f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 719f0984d40SFabiano Rosas { 720f0984d40SFabiano Rosas static const GVecGen4 op = { 721f0984d40SFabiano Rosas .fni8 = gen_bsl1n_i64, 722f0984d40SFabiano Rosas .fniv = gen_bsl1n_vec, 723f0984d40SFabiano Rosas .fno = gen_helper_sve2_bsl1n, 724f0984d40SFabiano Rosas .vece = MO_64, 725f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 726f0984d40SFabiano Rosas }; 727f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op); 728f0984d40SFabiano Rosas } 729f0984d40SFabiano Rosas 730f0984d40SFabiano Rosas TRANS_FEAT(BSL1N, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_bsl1n, a) 731f0984d40SFabiano Rosas 732f0984d40SFabiano Rosas static void gen_bsl2n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k) 733f0984d40SFabiano Rosas { 734f0984d40SFabiano Rosas /* 735f0984d40SFabiano Rosas * Z[dn] = (n & k) | (~m & ~k) 736f0984d40SFabiano Rosas * = | ~(m | k) 737f0984d40SFabiano Rosas */ 738f0984d40SFabiano Rosas tcg_gen_and_i64(n, n, k); 739f0984d40SFabiano Rosas if (TCG_TARGET_HAS_orc_i64) { 740f0984d40SFabiano Rosas tcg_gen_or_i64(m, m, k); 741f0984d40SFabiano Rosas tcg_gen_orc_i64(d, n, m); 742f0984d40SFabiano Rosas } else { 743f0984d40SFabiano Rosas tcg_gen_nor_i64(m, m, k); 744f0984d40SFabiano Rosas tcg_gen_or_i64(d, n, m); 745f0984d40SFabiano Rosas } 746f0984d40SFabiano Rosas } 747f0984d40SFabiano Rosas 748f0984d40SFabiano Rosas static void gen_bsl2n_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 749f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec k) 750f0984d40SFabiano Rosas { 751f0984d40SFabiano Rosas if (TCG_TARGET_HAS_bitsel_vec) { 752f0984d40SFabiano Rosas tcg_gen_not_vec(vece, m, m); 753f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, k, n, m); 754f0984d40SFabiano Rosas } else { 755f0984d40SFabiano Rosas tcg_gen_and_vec(vece, n, n, k); 756f0984d40SFabiano Rosas tcg_gen_or_vec(vece, m, m, k); 757f0984d40SFabiano Rosas tcg_gen_orc_vec(vece, d, n, m); 758f0984d40SFabiano Rosas } 759f0984d40SFabiano Rosas } 760f0984d40SFabiano Rosas 761f0984d40SFabiano Rosas static void gen_bsl2n(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 762f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 763f0984d40SFabiano Rosas { 764f0984d40SFabiano Rosas static const GVecGen4 op = { 765f0984d40SFabiano Rosas .fni8 = gen_bsl2n_i64, 766f0984d40SFabiano Rosas .fniv = gen_bsl2n_vec, 767f0984d40SFabiano Rosas .fno = gen_helper_sve2_bsl2n, 768f0984d40SFabiano Rosas .vece = MO_64, 769f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 770f0984d40SFabiano Rosas }; 771f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op); 772f0984d40SFabiano Rosas } 773f0984d40SFabiano Rosas 774f0984d40SFabiano Rosas TRANS_FEAT(BSL2N, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_bsl2n, a) 775f0984d40SFabiano Rosas 776f0984d40SFabiano Rosas static void gen_nbsl_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k) 777f0984d40SFabiano Rosas { 778f0984d40SFabiano Rosas tcg_gen_and_i64(n, n, k); 779f0984d40SFabiano Rosas tcg_gen_andc_i64(m, m, k); 780f0984d40SFabiano Rosas tcg_gen_nor_i64(d, n, m); 781f0984d40SFabiano Rosas } 782f0984d40SFabiano Rosas 783f0984d40SFabiano Rosas static void gen_nbsl_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 784f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec k) 785f0984d40SFabiano Rosas { 786f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, k, n, m); 787f0984d40SFabiano Rosas tcg_gen_not_vec(vece, d, d); 788f0984d40SFabiano Rosas } 789f0984d40SFabiano Rosas 790f0984d40SFabiano Rosas static void gen_nbsl(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 791f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 792f0984d40SFabiano Rosas { 793f0984d40SFabiano Rosas static const GVecGen4 op = { 794f0984d40SFabiano Rosas .fni8 = gen_nbsl_i64, 795f0984d40SFabiano Rosas .fniv = gen_nbsl_vec, 796f0984d40SFabiano Rosas .fno = gen_helper_sve2_nbsl, 797f0984d40SFabiano Rosas .vece = MO_64, 798f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 799f0984d40SFabiano Rosas }; 800f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op); 801f0984d40SFabiano Rosas } 802f0984d40SFabiano Rosas 803f0984d40SFabiano Rosas TRANS_FEAT(NBSL, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_nbsl, a) 804f0984d40SFabiano Rosas 805f0984d40SFabiano Rosas /* 806f0984d40SFabiano Rosas *** SVE Integer Arithmetic - Unpredicated Group 807f0984d40SFabiano Rosas */ 808f0984d40SFabiano Rosas 809f0984d40SFabiano Rosas TRANS_FEAT(ADD_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_add, a) 810f0984d40SFabiano Rosas TRANS_FEAT(SUB_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_sub, a) 811f0984d40SFabiano Rosas TRANS_FEAT(SQADD_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_ssadd, a) 812f0984d40SFabiano Rosas TRANS_FEAT(SQSUB_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_sssub, a) 813f0984d40SFabiano Rosas TRANS_FEAT(UQADD_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_usadd, a) 814f0984d40SFabiano Rosas TRANS_FEAT(UQSUB_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_ussub, a) 815f0984d40SFabiano Rosas 816f0984d40SFabiano Rosas /* 817f0984d40SFabiano Rosas *** SVE Integer Arithmetic - Binary Predicated Group 818f0984d40SFabiano Rosas */ 819f0984d40SFabiano Rosas 820f0984d40SFabiano Rosas /* Select active elememnts from Zn and inactive elements from Zm, 821f0984d40SFabiano Rosas * storing the result in Zd. 822f0984d40SFabiano Rosas */ 823f0984d40SFabiano Rosas static bool do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz) 824f0984d40SFabiano Rosas { 825f0984d40SFabiano Rosas static gen_helper_gvec_4 * const fns[4] = { 826f0984d40SFabiano Rosas gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h, 827f0984d40SFabiano Rosas gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d 828f0984d40SFabiano Rosas }; 829f0984d40SFabiano Rosas return gen_gvec_ool_zzzp(s, fns[esz], rd, rn, rm, pg, 0); 830f0984d40SFabiano Rosas } 831f0984d40SFabiano Rosas 832f0984d40SFabiano Rosas #define DO_ZPZZ(NAME, FEAT, name) \ 833f0984d40SFabiano Rosas static gen_helper_gvec_4 * const name##_zpzz_fns[4] = { \ 834f0984d40SFabiano Rosas gen_helper_##name##_zpzz_b, gen_helper_##name##_zpzz_h, \ 835f0984d40SFabiano Rosas gen_helper_##name##_zpzz_s, gen_helper_##name##_zpzz_d, \ 836f0984d40SFabiano Rosas }; \ 837f0984d40SFabiano Rosas TRANS_FEAT(NAME, FEAT, gen_gvec_ool_arg_zpzz, \ 838f0984d40SFabiano Rosas name##_zpzz_fns[a->esz], a, 0) 839f0984d40SFabiano Rosas 840f0984d40SFabiano Rosas DO_ZPZZ(AND_zpzz, aa64_sve, sve_and) 841f0984d40SFabiano Rosas DO_ZPZZ(EOR_zpzz, aa64_sve, sve_eor) 842f0984d40SFabiano Rosas DO_ZPZZ(ORR_zpzz, aa64_sve, sve_orr) 843f0984d40SFabiano Rosas DO_ZPZZ(BIC_zpzz, aa64_sve, sve_bic) 844f0984d40SFabiano Rosas 845f0984d40SFabiano Rosas DO_ZPZZ(ADD_zpzz, aa64_sve, sve_add) 846f0984d40SFabiano Rosas DO_ZPZZ(SUB_zpzz, aa64_sve, sve_sub) 847f0984d40SFabiano Rosas 848f0984d40SFabiano Rosas DO_ZPZZ(SMAX_zpzz, aa64_sve, sve_smax) 849f0984d40SFabiano Rosas DO_ZPZZ(UMAX_zpzz, aa64_sve, sve_umax) 850f0984d40SFabiano Rosas DO_ZPZZ(SMIN_zpzz, aa64_sve, sve_smin) 851f0984d40SFabiano Rosas DO_ZPZZ(UMIN_zpzz, aa64_sve, sve_umin) 852f0984d40SFabiano Rosas DO_ZPZZ(SABD_zpzz, aa64_sve, sve_sabd) 853f0984d40SFabiano Rosas DO_ZPZZ(UABD_zpzz, aa64_sve, sve_uabd) 854f0984d40SFabiano Rosas 855f0984d40SFabiano Rosas DO_ZPZZ(MUL_zpzz, aa64_sve, sve_mul) 856f0984d40SFabiano Rosas DO_ZPZZ(SMULH_zpzz, aa64_sve, sve_smulh) 857f0984d40SFabiano Rosas DO_ZPZZ(UMULH_zpzz, aa64_sve, sve_umulh) 858f0984d40SFabiano Rosas 859f0984d40SFabiano Rosas DO_ZPZZ(ASR_zpzz, aa64_sve, sve_asr) 860f0984d40SFabiano Rosas DO_ZPZZ(LSR_zpzz, aa64_sve, sve_lsr) 861f0984d40SFabiano Rosas DO_ZPZZ(LSL_zpzz, aa64_sve, sve_lsl) 862f0984d40SFabiano Rosas 863f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sdiv_fns[4] = { 864f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve_sdiv_zpzz_s, gen_helper_sve_sdiv_zpzz_d 865f0984d40SFabiano Rosas }; 866f0984d40SFabiano Rosas TRANS_FEAT(SDIV_zpzz, aa64_sve, gen_gvec_ool_arg_zpzz, sdiv_fns[a->esz], a, 0) 867f0984d40SFabiano Rosas 868f0984d40SFabiano Rosas static gen_helper_gvec_4 * const udiv_fns[4] = { 869f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve_udiv_zpzz_s, gen_helper_sve_udiv_zpzz_d 870f0984d40SFabiano Rosas }; 871f0984d40SFabiano Rosas TRANS_FEAT(UDIV_zpzz, aa64_sve, gen_gvec_ool_arg_zpzz, udiv_fns[a->esz], a, 0) 872f0984d40SFabiano Rosas 873f0984d40SFabiano Rosas TRANS_FEAT(SEL_zpzz, aa64_sve, do_sel_z, a->rd, a->rn, a->rm, a->pg, a->esz) 874f0984d40SFabiano Rosas 875f0984d40SFabiano Rosas /* 876f0984d40SFabiano Rosas *** SVE Integer Arithmetic - Unary Predicated Group 877f0984d40SFabiano Rosas */ 878f0984d40SFabiano Rosas 879f0984d40SFabiano Rosas #define DO_ZPZ(NAME, FEAT, name) \ 880f0984d40SFabiano Rosas static gen_helper_gvec_3 * const name##_fns[4] = { \ 881f0984d40SFabiano Rosas gen_helper_##name##_b, gen_helper_##name##_h, \ 882f0984d40SFabiano Rosas gen_helper_##name##_s, gen_helper_##name##_d, \ 883f0984d40SFabiano Rosas }; \ 884f0984d40SFabiano Rosas TRANS_FEAT(NAME, FEAT, gen_gvec_ool_arg_zpz, name##_fns[a->esz], a, 0) 885f0984d40SFabiano Rosas 886f0984d40SFabiano Rosas DO_ZPZ(CLS, aa64_sve, sve_cls) 887f0984d40SFabiano Rosas DO_ZPZ(CLZ, aa64_sve, sve_clz) 888f0984d40SFabiano Rosas DO_ZPZ(CNT_zpz, aa64_sve, sve_cnt_zpz) 889f0984d40SFabiano Rosas DO_ZPZ(CNOT, aa64_sve, sve_cnot) 890f0984d40SFabiano Rosas DO_ZPZ(NOT_zpz, aa64_sve, sve_not_zpz) 891f0984d40SFabiano Rosas DO_ZPZ(ABS, aa64_sve, sve_abs) 892f0984d40SFabiano Rosas DO_ZPZ(NEG, aa64_sve, sve_neg) 893f0984d40SFabiano Rosas DO_ZPZ(RBIT, aa64_sve, sve_rbit) 894f0984d40SFabiano Rosas 895f0984d40SFabiano Rosas static gen_helper_gvec_3 * const fabs_fns[4] = { 896f0984d40SFabiano Rosas NULL, gen_helper_sve_fabs_h, 897f0984d40SFabiano Rosas gen_helper_sve_fabs_s, gen_helper_sve_fabs_d, 898f0984d40SFabiano Rosas }; 899f0984d40SFabiano Rosas TRANS_FEAT(FABS, aa64_sve, gen_gvec_ool_arg_zpz, fabs_fns[a->esz], a, 0) 900f0984d40SFabiano Rosas 901f0984d40SFabiano Rosas static gen_helper_gvec_3 * const fneg_fns[4] = { 902f0984d40SFabiano Rosas NULL, gen_helper_sve_fneg_h, 903f0984d40SFabiano Rosas gen_helper_sve_fneg_s, gen_helper_sve_fneg_d, 904f0984d40SFabiano Rosas }; 905f0984d40SFabiano Rosas TRANS_FEAT(FNEG, aa64_sve, gen_gvec_ool_arg_zpz, fneg_fns[a->esz], a, 0) 906f0984d40SFabiano Rosas 907f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sxtb_fns[4] = { 908f0984d40SFabiano Rosas NULL, gen_helper_sve_sxtb_h, 909f0984d40SFabiano Rosas gen_helper_sve_sxtb_s, gen_helper_sve_sxtb_d, 910f0984d40SFabiano Rosas }; 911f0984d40SFabiano Rosas TRANS_FEAT(SXTB, aa64_sve, gen_gvec_ool_arg_zpz, sxtb_fns[a->esz], a, 0) 912f0984d40SFabiano Rosas 913f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uxtb_fns[4] = { 914f0984d40SFabiano Rosas NULL, gen_helper_sve_uxtb_h, 915f0984d40SFabiano Rosas gen_helper_sve_uxtb_s, gen_helper_sve_uxtb_d, 916f0984d40SFabiano Rosas }; 917f0984d40SFabiano Rosas TRANS_FEAT(UXTB, aa64_sve, gen_gvec_ool_arg_zpz, uxtb_fns[a->esz], a, 0) 918f0984d40SFabiano Rosas 919f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sxth_fns[4] = { 920f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve_sxth_s, gen_helper_sve_sxth_d 921f0984d40SFabiano Rosas }; 922f0984d40SFabiano Rosas TRANS_FEAT(SXTH, aa64_sve, gen_gvec_ool_arg_zpz, sxth_fns[a->esz], a, 0) 923f0984d40SFabiano Rosas 924f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uxth_fns[4] = { 925f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve_uxth_s, gen_helper_sve_uxth_d 926f0984d40SFabiano Rosas }; 927f0984d40SFabiano Rosas TRANS_FEAT(UXTH, aa64_sve, gen_gvec_ool_arg_zpz, uxth_fns[a->esz], a, 0) 928f0984d40SFabiano Rosas 929f0984d40SFabiano Rosas TRANS_FEAT(SXTW, aa64_sve, gen_gvec_ool_arg_zpz, 930f0984d40SFabiano Rosas a->esz == 3 ? gen_helper_sve_sxtw_d : NULL, a, 0) 931f0984d40SFabiano Rosas TRANS_FEAT(UXTW, aa64_sve, gen_gvec_ool_arg_zpz, 932f0984d40SFabiano Rosas a->esz == 3 ? gen_helper_sve_uxtw_d : NULL, a, 0) 933f0984d40SFabiano Rosas 934f0984d40SFabiano Rosas /* 935f0984d40SFabiano Rosas *** SVE Integer Reduction Group 936f0984d40SFabiano Rosas */ 937f0984d40SFabiano Rosas 938f0984d40SFabiano Rosas typedef void gen_helper_gvec_reduc(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_i32); 939f0984d40SFabiano Rosas static bool do_vpz_ool(DisasContext *s, arg_rpr_esz *a, 940f0984d40SFabiano Rosas gen_helper_gvec_reduc *fn) 941f0984d40SFabiano Rosas { 942f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 943f0984d40SFabiano Rosas TCGv_ptr t_zn, t_pg; 944f0984d40SFabiano Rosas TCGv_i32 desc; 945f0984d40SFabiano Rosas TCGv_i64 temp; 946f0984d40SFabiano Rosas 947f0984d40SFabiano Rosas if (fn == NULL) { 948f0984d40SFabiano Rosas return false; 949f0984d40SFabiano Rosas } 950f0984d40SFabiano Rosas if (!sve_access_check(s)) { 951f0984d40SFabiano Rosas return true; 952f0984d40SFabiano Rosas } 953f0984d40SFabiano Rosas 954f0984d40SFabiano Rosas desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 955f0984d40SFabiano Rosas temp = tcg_temp_new_i64(); 956f0984d40SFabiano Rosas t_zn = tcg_temp_new_ptr(); 957f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 958f0984d40SFabiano Rosas 959*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn)); 960*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); 961f0984d40SFabiano Rosas fn(temp, t_zn, t_pg, desc); 962f0984d40SFabiano Rosas 963f0984d40SFabiano Rosas write_fp_dreg(s, a->rd, temp); 964f0984d40SFabiano Rosas return true; 965f0984d40SFabiano Rosas } 966f0984d40SFabiano Rosas 967f0984d40SFabiano Rosas #define DO_VPZ(NAME, name) \ 968f0984d40SFabiano Rosas static gen_helper_gvec_reduc * const name##_fns[4] = { \ 969f0984d40SFabiano Rosas gen_helper_sve_##name##_b, gen_helper_sve_##name##_h, \ 970f0984d40SFabiano Rosas gen_helper_sve_##name##_s, gen_helper_sve_##name##_d, \ 971f0984d40SFabiano Rosas }; \ 972f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, do_vpz_ool, a, name##_fns[a->esz]) 973f0984d40SFabiano Rosas 974f0984d40SFabiano Rosas DO_VPZ(ORV, orv) 975f0984d40SFabiano Rosas DO_VPZ(ANDV, andv) 976f0984d40SFabiano Rosas DO_VPZ(EORV, eorv) 977f0984d40SFabiano Rosas 978f0984d40SFabiano Rosas DO_VPZ(UADDV, uaddv) 979f0984d40SFabiano Rosas DO_VPZ(SMAXV, smaxv) 980f0984d40SFabiano Rosas DO_VPZ(UMAXV, umaxv) 981f0984d40SFabiano Rosas DO_VPZ(SMINV, sminv) 982f0984d40SFabiano Rosas DO_VPZ(UMINV, uminv) 983f0984d40SFabiano Rosas 984f0984d40SFabiano Rosas static gen_helper_gvec_reduc * const saddv_fns[4] = { 985f0984d40SFabiano Rosas gen_helper_sve_saddv_b, gen_helper_sve_saddv_h, 986f0984d40SFabiano Rosas gen_helper_sve_saddv_s, NULL 987f0984d40SFabiano Rosas }; 988f0984d40SFabiano Rosas TRANS_FEAT(SADDV, aa64_sve, do_vpz_ool, a, saddv_fns[a->esz]) 989f0984d40SFabiano Rosas 990f0984d40SFabiano Rosas #undef DO_VPZ 991f0984d40SFabiano Rosas 992f0984d40SFabiano Rosas /* 993f0984d40SFabiano Rosas *** SVE Shift by Immediate - Predicated Group 994f0984d40SFabiano Rosas */ 995f0984d40SFabiano Rosas 996f0984d40SFabiano Rosas /* 997f0984d40SFabiano Rosas * Copy Zn into Zd, storing zeros into inactive elements. 998f0984d40SFabiano Rosas * If invert, store zeros into the active elements. 999f0984d40SFabiano Rosas */ 1000f0984d40SFabiano Rosas static bool do_movz_zpz(DisasContext *s, int rd, int rn, int pg, 1001f0984d40SFabiano Rosas int esz, bool invert) 1002f0984d40SFabiano Rosas { 1003f0984d40SFabiano Rosas static gen_helper_gvec_3 * const fns[4] = { 1004f0984d40SFabiano Rosas gen_helper_sve_movz_b, gen_helper_sve_movz_h, 1005f0984d40SFabiano Rosas gen_helper_sve_movz_s, gen_helper_sve_movz_d, 1006f0984d40SFabiano Rosas }; 1007f0984d40SFabiano Rosas return gen_gvec_ool_zzp(s, fns[esz], rd, rn, pg, invert); 1008f0984d40SFabiano Rosas } 1009f0984d40SFabiano Rosas 1010f0984d40SFabiano Rosas static bool do_shift_zpzi(DisasContext *s, arg_rpri_esz *a, bool asr, 1011f0984d40SFabiano Rosas gen_helper_gvec_3 * const fns[4]) 1012f0984d40SFabiano Rosas { 1013f0984d40SFabiano Rosas int max; 1014f0984d40SFabiano Rosas 1015f0984d40SFabiano Rosas if (a->esz < 0) { 1016f0984d40SFabiano Rosas /* Invalid tsz encoding -- see tszimm_esz. */ 1017f0984d40SFabiano Rosas return false; 1018f0984d40SFabiano Rosas } 1019f0984d40SFabiano Rosas 1020f0984d40SFabiano Rosas /* 1021f0984d40SFabiano Rosas * Shift by element size is architecturally valid. 1022f0984d40SFabiano Rosas * For arithmetic right-shift, it's the same as by one less. 1023f0984d40SFabiano Rosas * For logical shifts and ASRD, it is a zeroing operation. 1024f0984d40SFabiano Rosas */ 1025f0984d40SFabiano Rosas max = 8 << a->esz; 1026f0984d40SFabiano Rosas if (a->imm >= max) { 1027f0984d40SFabiano Rosas if (asr) { 1028f0984d40SFabiano Rosas a->imm = max - 1; 1029f0984d40SFabiano Rosas } else { 1030f0984d40SFabiano Rosas return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true); 1031f0984d40SFabiano Rosas } 1032f0984d40SFabiano Rosas } 1033f0984d40SFabiano Rosas return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a); 1034f0984d40SFabiano Rosas } 1035f0984d40SFabiano Rosas 1036f0984d40SFabiano Rosas static gen_helper_gvec_3 * const asr_zpzi_fns[4] = { 1037f0984d40SFabiano Rosas gen_helper_sve_asr_zpzi_b, gen_helper_sve_asr_zpzi_h, 1038f0984d40SFabiano Rosas gen_helper_sve_asr_zpzi_s, gen_helper_sve_asr_zpzi_d, 1039f0984d40SFabiano Rosas }; 1040f0984d40SFabiano Rosas TRANS_FEAT(ASR_zpzi, aa64_sve, do_shift_zpzi, a, true, asr_zpzi_fns) 1041f0984d40SFabiano Rosas 1042f0984d40SFabiano Rosas static gen_helper_gvec_3 * const lsr_zpzi_fns[4] = { 1043f0984d40SFabiano Rosas gen_helper_sve_lsr_zpzi_b, gen_helper_sve_lsr_zpzi_h, 1044f0984d40SFabiano Rosas gen_helper_sve_lsr_zpzi_s, gen_helper_sve_lsr_zpzi_d, 1045f0984d40SFabiano Rosas }; 1046f0984d40SFabiano Rosas TRANS_FEAT(LSR_zpzi, aa64_sve, do_shift_zpzi, a, false, lsr_zpzi_fns) 1047f0984d40SFabiano Rosas 1048f0984d40SFabiano Rosas static gen_helper_gvec_3 * const lsl_zpzi_fns[4] = { 1049f0984d40SFabiano Rosas gen_helper_sve_lsl_zpzi_b, gen_helper_sve_lsl_zpzi_h, 1050f0984d40SFabiano Rosas gen_helper_sve_lsl_zpzi_s, gen_helper_sve_lsl_zpzi_d, 1051f0984d40SFabiano Rosas }; 1052f0984d40SFabiano Rosas TRANS_FEAT(LSL_zpzi, aa64_sve, do_shift_zpzi, a, false, lsl_zpzi_fns) 1053f0984d40SFabiano Rosas 1054f0984d40SFabiano Rosas static gen_helper_gvec_3 * const asrd_fns[4] = { 1055f0984d40SFabiano Rosas gen_helper_sve_asrd_b, gen_helper_sve_asrd_h, 1056f0984d40SFabiano Rosas gen_helper_sve_asrd_s, gen_helper_sve_asrd_d, 1057f0984d40SFabiano Rosas }; 1058f0984d40SFabiano Rosas TRANS_FEAT(ASRD, aa64_sve, do_shift_zpzi, a, false, asrd_fns) 1059f0984d40SFabiano Rosas 1060f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqshl_zpzi_fns[4] = { 1061f0984d40SFabiano Rosas gen_helper_sve2_sqshl_zpzi_b, gen_helper_sve2_sqshl_zpzi_h, 1062f0984d40SFabiano Rosas gen_helper_sve2_sqshl_zpzi_s, gen_helper_sve2_sqshl_zpzi_d, 1063f0984d40SFabiano Rosas }; 1064f0984d40SFabiano Rosas TRANS_FEAT(SQSHL_zpzi, aa64_sve2, gen_gvec_ool_arg_zpzi, 1065f0984d40SFabiano Rosas a->esz < 0 ? NULL : sqshl_zpzi_fns[a->esz], a) 1066f0984d40SFabiano Rosas 1067f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uqshl_zpzi_fns[4] = { 1068f0984d40SFabiano Rosas gen_helper_sve2_uqshl_zpzi_b, gen_helper_sve2_uqshl_zpzi_h, 1069f0984d40SFabiano Rosas gen_helper_sve2_uqshl_zpzi_s, gen_helper_sve2_uqshl_zpzi_d, 1070f0984d40SFabiano Rosas }; 1071f0984d40SFabiano Rosas TRANS_FEAT(UQSHL_zpzi, aa64_sve2, gen_gvec_ool_arg_zpzi, 1072f0984d40SFabiano Rosas a->esz < 0 ? NULL : uqshl_zpzi_fns[a->esz], a) 1073f0984d40SFabiano Rosas 1074f0984d40SFabiano Rosas static gen_helper_gvec_3 * const srshr_fns[4] = { 1075f0984d40SFabiano Rosas gen_helper_sve2_srshr_b, gen_helper_sve2_srshr_h, 1076f0984d40SFabiano Rosas gen_helper_sve2_srshr_s, gen_helper_sve2_srshr_d, 1077f0984d40SFabiano Rosas }; 1078f0984d40SFabiano Rosas TRANS_FEAT(SRSHR, aa64_sve2, gen_gvec_ool_arg_zpzi, 1079f0984d40SFabiano Rosas a->esz < 0 ? NULL : srshr_fns[a->esz], a) 1080f0984d40SFabiano Rosas 1081f0984d40SFabiano Rosas static gen_helper_gvec_3 * const urshr_fns[4] = { 1082f0984d40SFabiano Rosas gen_helper_sve2_urshr_b, gen_helper_sve2_urshr_h, 1083f0984d40SFabiano Rosas gen_helper_sve2_urshr_s, gen_helper_sve2_urshr_d, 1084f0984d40SFabiano Rosas }; 1085f0984d40SFabiano Rosas TRANS_FEAT(URSHR, aa64_sve2, gen_gvec_ool_arg_zpzi, 1086f0984d40SFabiano Rosas a->esz < 0 ? NULL : urshr_fns[a->esz], a) 1087f0984d40SFabiano Rosas 1088f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqshlu_fns[4] = { 1089f0984d40SFabiano Rosas gen_helper_sve2_sqshlu_b, gen_helper_sve2_sqshlu_h, 1090f0984d40SFabiano Rosas gen_helper_sve2_sqshlu_s, gen_helper_sve2_sqshlu_d, 1091f0984d40SFabiano Rosas }; 1092f0984d40SFabiano Rosas TRANS_FEAT(SQSHLU, aa64_sve2, gen_gvec_ool_arg_zpzi, 1093f0984d40SFabiano Rosas a->esz < 0 ? NULL : sqshlu_fns[a->esz], a) 1094f0984d40SFabiano Rosas 1095f0984d40SFabiano Rosas /* 1096f0984d40SFabiano Rosas *** SVE Bitwise Shift - Predicated Group 1097f0984d40SFabiano Rosas */ 1098f0984d40SFabiano Rosas 1099f0984d40SFabiano Rosas #define DO_ZPZW(NAME, name) \ 1100f0984d40SFabiano Rosas static gen_helper_gvec_4 * const name##_zpzw_fns[4] = { \ 1101f0984d40SFabiano Rosas gen_helper_sve_##name##_zpzw_b, gen_helper_sve_##name##_zpzw_h, \ 1102f0984d40SFabiano Rosas gen_helper_sve_##name##_zpzw_s, NULL \ 1103f0984d40SFabiano Rosas }; \ 1104f0984d40SFabiano Rosas TRANS_FEAT(NAME##_zpzw, aa64_sve, gen_gvec_ool_arg_zpzz, \ 1105f0984d40SFabiano Rosas a->esz < 0 ? NULL : name##_zpzw_fns[a->esz], a, 0) 1106f0984d40SFabiano Rosas 1107f0984d40SFabiano Rosas DO_ZPZW(ASR, asr) 1108f0984d40SFabiano Rosas DO_ZPZW(LSR, lsr) 1109f0984d40SFabiano Rosas DO_ZPZW(LSL, lsl) 1110f0984d40SFabiano Rosas 1111f0984d40SFabiano Rosas #undef DO_ZPZW 1112f0984d40SFabiano Rosas 1113f0984d40SFabiano Rosas /* 1114f0984d40SFabiano Rosas *** SVE Bitwise Shift - Unpredicated Group 1115f0984d40SFabiano Rosas */ 1116f0984d40SFabiano Rosas 1117f0984d40SFabiano Rosas static bool do_shift_imm(DisasContext *s, arg_rri_esz *a, bool asr, 1118f0984d40SFabiano Rosas void (*gvec_fn)(unsigned, uint32_t, uint32_t, 1119f0984d40SFabiano Rosas int64_t, uint32_t, uint32_t)) 1120f0984d40SFabiano Rosas { 1121f0984d40SFabiano Rosas if (a->esz < 0) { 1122f0984d40SFabiano Rosas /* Invalid tsz encoding -- see tszimm_esz. */ 1123f0984d40SFabiano Rosas return false; 1124f0984d40SFabiano Rosas } 1125f0984d40SFabiano Rosas if (sve_access_check(s)) { 1126f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 1127f0984d40SFabiano Rosas /* Shift by element size is architecturally valid. For 1128f0984d40SFabiano Rosas arithmetic right-shift, it's the same as by one less. 1129f0984d40SFabiano Rosas Otherwise it is a zeroing operation. */ 1130f0984d40SFabiano Rosas if (a->imm >= 8 << a->esz) { 1131f0984d40SFabiano Rosas if (asr) { 1132f0984d40SFabiano Rosas a->imm = (8 << a->esz) - 1; 1133f0984d40SFabiano Rosas } else { 1134f0984d40SFabiano Rosas do_dupi_z(s, a->rd, 0); 1135f0984d40SFabiano Rosas return true; 1136f0984d40SFabiano Rosas } 1137f0984d40SFabiano Rosas } 1138f0984d40SFabiano Rosas gvec_fn(a->esz, vec_full_reg_offset(s, a->rd), 1139f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), a->imm, vsz, vsz); 1140f0984d40SFabiano Rosas } 1141f0984d40SFabiano Rosas return true; 1142f0984d40SFabiano Rosas } 1143f0984d40SFabiano Rosas 1144f0984d40SFabiano Rosas TRANS_FEAT(ASR_zzi, aa64_sve, do_shift_imm, a, true, tcg_gen_gvec_sari) 1145f0984d40SFabiano Rosas TRANS_FEAT(LSR_zzi, aa64_sve, do_shift_imm, a, false, tcg_gen_gvec_shri) 1146f0984d40SFabiano Rosas TRANS_FEAT(LSL_zzi, aa64_sve, do_shift_imm, a, false, tcg_gen_gvec_shli) 1147f0984d40SFabiano Rosas 1148f0984d40SFabiano Rosas #define DO_ZZW(NAME, name) \ 1149f0984d40SFabiano Rosas static gen_helper_gvec_3 * const name##_zzw_fns[4] = { \ 1150f0984d40SFabiano Rosas gen_helper_sve_##name##_zzw_b, gen_helper_sve_##name##_zzw_h, \ 1151f0984d40SFabiano Rosas gen_helper_sve_##name##_zzw_s, NULL \ 1152f0984d40SFabiano Rosas }; \ 1153f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, gen_gvec_ool_arg_zzz, \ 1154f0984d40SFabiano Rosas name##_zzw_fns[a->esz], a, 0) 1155f0984d40SFabiano Rosas 1156f0984d40SFabiano Rosas DO_ZZW(ASR_zzw, asr) 1157f0984d40SFabiano Rosas DO_ZZW(LSR_zzw, lsr) 1158f0984d40SFabiano Rosas DO_ZZW(LSL_zzw, lsl) 1159f0984d40SFabiano Rosas 1160f0984d40SFabiano Rosas #undef DO_ZZW 1161f0984d40SFabiano Rosas 1162f0984d40SFabiano Rosas /* 1163f0984d40SFabiano Rosas *** SVE Integer Multiply-Add Group 1164f0984d40SFabiano Rosas */ 1165f0984d40SFabiano Rosas 1166f0984d40SFabiano Rosas static bool do_zpzzz_ool(DisasContext *s, arg_rprrr_esz *a, 1167f0984d40SFabiano Rosas gen_helper_gvec_5 *fn) 1168f0984d40SFabiano Rosas { 1169f0984d40SFabiano Rosas if (sve_access_check(s)) { 1170f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 1171f0984d40SFabiano Rosas tcg_gen_gvec_5_ool(vec_full_reg_offset(s, a->rd), 1172f0984d40SFabiano Rosas vec_full_reg_offset(s, a->ra), 1173f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 1174f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rm), 1175f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pg), 1176f0984d40SFabiano Rosas vsz, vsz, 0, fn); 1177f0984d40SFabiano Rosas } 1178f0984d40SFabiano Rosas return true; 1179f0984d40SFabiano Rosas } 1180f0984d40SFabiano Rosas 1181f0984d40SFabiano Rosas static gen_helper_gvec_5 * const mla_fns[4] = { 1182f0984d40SFabiano Rosas gen_helper_sve_mla_b, gen_helper_sve_mla_h, 1183f0984d40SFabiano Rosas gen_helper_sve_mla_s, gen_helper_sve_mla_d, 1184f0984d40SFabiano Rosas }; 1185f0984d40SFabiano Rosas TRANS_FEAT(MLA, aa64_sve, do_zpzzz_ool, a, mla_fns[a->esz]) 1186f0984d40SFabiano Rosas 1187f0984d40SFabiano Rosas static gen_helper_gvec_5 * const mls_fns[4] = { 1188f0984d40SFabiano Rosas gen_helper_sve_mls_b, gen_helper_sve_mls_h, 1189f0984d40SFabiano Rosas gen_helper_sve_mls_s, gen_helper_sve_mls_d, 1190f0984d40SFabiano Rosas }; 1191f0984d40SFabiano Rosas TRANS_FEAT(MLS, aa64_sve, do_zpzzz_ool, a, mls_fns[a->esz]) 1192f0984d40SFabiano Rosas 1193f0984d40SFabiano Rosas /* 1194f0984d40SFabiano Rosas *** SVE Index Generation Group 1195f0984d40SFabiano Rosas */ 1196f0984d40SFabiano Rosas 1197f0984d40SFabiano Rosas static bool do_index(DisasContext *s, int esz, int rd, 1198f0984d40SFabiano Rosas TCGv_i64 start, TCGv_i64 incr) 1199f0984d40SFabiano Rosas { 1200f0984d40SFabiano Rosas unsigned vsz; 1201f0984d40SFabiano Rosas TCGv_i32 desc; 1202f0984d40SFabiano Rosas TCGv_ptr t_zd; 1203f0984d40SFabiano Rosas 1204f0984d40SFabiano Rosas if (!sve_access_check(s)) { 1205f0984d40SFabiano Rosas return true; 1206f0984d40SFabiano Rosas } 1207f0984d40SFabiano Rosas 1208f0984d40SFabiano Rosas vsz = vec_full_reg_size(s); 1209f0984d40SFabiano Rosas desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 1210f0984d40SFabiano Rosas t_zd = tcg_temp_new_ptr(); 1211f0984d40SFabiano Rosas 1212*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zd, tcg_env, vec_full_reg_offset(s, rd)); 1213f0984d40SFabiano Rosas if (esz == 3) { 1214f0984d40SFabiano Rosas gen_helper_sve_index_d(t_zd, start, incr, desc); 1215f0984d40SFabiano Rosas } else { 1216f0984d40SFabiano Rosas typedef void index_fn(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32); 1217f0984d40SFabiano Rosas static index_fn * const fns[3] = { 1218f0984d40SFabiano Rosas gen_helper_sve_index_b, 1219f0984d40SFabiano Rosas gen_helper_sve_index_h, 1220f0984d40SFabiano Rosas gen_helper_sve_index_s, 1221f0984d40SFabiano Rosas }; 1222f0984d40SFabiano Rosas TCGv_i32 s32 = tcg_temp_new_i32(); 1223f0984d40SFabiano Rosas TCGv_i32 i32 = tcg_temp_new_i32(); 1224f0984d40SFabiano Rosas 1225f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(s32, start); 1226f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(i32, incr); 1227f0984d40SFabiano Rosas fns[esz](t_zd, s32, i32, desc); 1228f0984d40SFabiano Rosas } 1229f0984d40SFabiano Rosas return true; 1230f0984d40SFabiano Rosas } 1231f0984d40SFabiano Rosas 1232f0984d40SFabiano Rosas TRANS_FEAT(INDEX_ii, aa64_sve, do_index, a->esz, a->rd, 1233f0984d40SFabiano Rosas tcg_constant_i64(a->imm1), tcg_constant_i64(a->imm2)) 1234f0984d40SFabiano Rosas TRANS_FEAT(INDEX_ir, aa64_sve, do_index, a->esz, a->rd, 1235f0984d40SFabiano Rosas tcg_constant_i64(a->imm), cpu_reg(s, a->rm)) 1236f0984d40SFabiano Rosas TRANS_FEAT(INDEX_ri, aa64_sve, do_index, a->esz, a->rd, 1237f0984d40SFabiano Rosas cpu_reg(s, a->rn), tcg_constant_i64(a->imm)) 1238f0984d40SFabiano Rosas TRANS_FEAT(INDEX_rr, aa64_sve, do_index, a->esz, a->rd, 1239f0984d40SFabiano Rosas cpu_reg(s, a->rn), cpu_reg(s, a->rm)) 1240f0984d40SFabiano Rosas 1241f0984d40SFabiano Rosas /* 1242f0984d40SFabiano Rosas *** SVE Stack Allocation Group 1243f0984d40SFabiano Rosas */ 1244f0984d40SFabiano Rosas 1245f0984d40SFabiano Rosas static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a) 1246f0984d40SFabiano Rosas { 1247f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1248f0984d40SFabiano Rosas return false; 1249f0984d40SFabiano Rosas } 1250f0984d40SFabiano Rosas if (sve_access_check(s)) { 1251f0984d40SFabiano Rosas TCGv_i64 rd = cpu_reg_sp(s, a->rd); 1252f0984d40SFabiano Rosas TCGv_i64 rn = cpu_reg_sp(s, a->rn); 1253f0984d40SFabiano Rosas tcg_gen_addi_i64(rd, rn, a->imm * vec_full_reg_size(s)); 1254f0984d40SFabiano Rosas } 1255f0984d40SFabiano Rosas return true; 1256f0984d40SFabiano Rosas } 1257f0984d40SFabiano Rosas 1258f0984d40SFabiano Rosas static bool trans_ADDSVL(DisasContext *s, arg_ADDSVL *a) 1259f0984d40SFabiano Rosas { 1260f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sme, s)) { 1261f0984d40SFabiano Rosas return false; 1262f0984d40SFabiano Rosas } 1263f0984d40SFabiano Rosas if (sme_enabled_check(s)) { 1264f0984d40SFabiano Rosas TCGv_i64 rd = cpu_reg_sp(s, a->rd); 1265f0984d40SFabiano Rosas TCGv_i64 rn = cpu_reg_sp(s, a->rn); 1266f0984d40SFabiano Rosas tcg_gen_addi_i64(rd, rn, a->imm * streaming_vec_reg_size(s)); 1267f0984d40SFabiano Rosas } 1268f0984d40SFabiano Rosas return true; 1269f0984d40SFabiano Rosas } 1270f0984d40SFabiano Rosas 1271f0984d40SFabiano Rosas static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a) 1272f0984d40SFabiano Rosas { 1273f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1274f0984d40SFabiano Rosas return false; 1275f0984d40SFabiano Rosas } 1276f0984d40SFabiano Rosas if (sve_access_check(s)) { 1277f0984d40SFabiano Rosas TCGv_i64 rd = cpu_reg_sp(s, a->rd); 1278f0984d40SFabiano Rosas TCGv_i64 rn = cpu_reg_sp(s, a->rn); 1279f0984d40SFabiano Rosas tcg_gen_addi_i64(rd, rn, a->imm * pred_full_reg_size(s)); 1280f0984d40SFabiano Rosas } 1281f0984d40SFabiano Rosas return true; 1282f0984d40SFabiano Rosas } 1283f0984d40SFabiano Rosas 1284f0984d40SFabiano Rosas static bool trans_ADDSPL(DisasContext *s, arg_ADDSPL *a) 1285f0984d40SFabiano Rosas { 1286f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sme, s)) { 1287f0984d40SFabiano Rosas return false; 1288f0984d40SFabiano Rosas } 1289f0984d40SFabiano Rosas if (sme_enabled_check(s)) { 1290f0984d40SFabiano Rosas TCGv_i64 rd = cpu_reg_sp(s, a->rd); 1291f0984d40SFabiano Rosas TCGv_i64 rn = cpu_reg_sp(s, a->rn); 1292f0984d40SFabiano Rosas tcg_gen_addi_i64(rd, rn, a->imm * streaming_pred_reg_size(s)); 1293f0984d40SFabiano Rosas } 1294f0984d40SFabiano Rosas return true; 1295f0984d40SFabiano Rosas } 1296f0984d40SFabiano Rosas 1297f0984d40SFabiano Rosas static bool trans_RDVL(DisasContext *s, arg_RDVL *a) 1298f0984d40SFabiano Rosas { 1299f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1300f0984d40SFabiano Rosas return false; 1301f0984d40SFabiano Rosas } 1302f0984d40SFabiano Rosas if (sve_access_check(s)) { 1303f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 1304f0984d40SFabiano Rosas tcg_gen_movi_i64(reg, a->imm * vec_full_reg_size(s)); 1305f0984d40SFabiano Rosas } 1306f0984d40SFabiano Rosas return true; 1307f0984d40SFabiano Rosas } 1308f0984d40SFabiano Rosas 1309f0984d40SFabiano Rosas static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a) 1310f0984d40SFabiano Rosas { 1311f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sme, s)) { 1312f0984d40SFabiano Rosas return false; 1313f0984d40SFabiano Rosas } 1314f0984d40SFabiano Rosas if (sme_enabled_check(s)) { 1315f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 1316f0984d40SFabiano Rosas tcg_gen_movi_i64(reg, a->imm * streaming_vec_reg_size(s)); 1317f0984d40SFabiano Rosas } 1318f0984d40SFabiano Rosas return true; 1319f0984d40SFabiano Rosas } 1320f0984d40SFabiano Rosas 1321f0984d40SFabiano Rosas /* 1322f0984d40SFabiano Rosas *** SVE Compute Vector Address Group 1323f0984d40SFabiano Rosas */ 1324f0984d40SFabiano Rosas 1325f0984d40SFabiano Rosas static bool do_adr(DisasContext *s, arg_rrri *a, gen_helper_gvec_3 *fn) 1326f0984d40SFabiano Rosas { 1327f0984d40SFabiano Rosas return gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, a->imm); 1328f0984d40SFabiano Rosas } 1329f0984d40SFabiano Rosas 1330f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(ADR_p32, aa64_sve, do_adr, a, gen_helper_sve_adr_p32) 1331f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(ADR_p64, aa64_sve, do_adr, a, gen_helper_sve_adr_p64) 1332f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(ADR_s32, aa64_sve, do_adr, a, gen_helper_sve_adr_s32) 1333f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(ADR_u32, aa64_sve, do_adr, a, gen_helper_sve_adr_u32) 1334f0984d40SFabiano Rosas 1335f0984d40SFabiano Rosas /* 1336f0984d40SFabiano Rosas *** SVE Integer Misc - Unpredicated Group 1337f0984d40SFabiano Rosas */ 1338f0984d40SFabiano Rosas 1339f0984d40SFabiano Rosas static gen_helper_gvec_2 * const fexpa_fns[4] = { 1340f0984d40SFabiano Rosas NULL, gen_helper_sve_fexpa_h, 1341f0984d40SFabiano Rosas gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d, 1342f0984d40SFabiano Rosas }; 1343f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz, 1344f0984d40SFabiano Rosas fexpa_fns[a->esz], a->rd, a->rn, 0) 1345f0984d40SFabiano Rosas 1346f0984d40SFabiano Rosas static gen_helper_gvec_3 * const ftssel_fns[4] = { 1347f0984d40SFabiano Rosas NULL, gen_helper_sve_ftssel_h, 1348f0984d40SFabiano Rosas gen_helper_sve_ftssel_s, gen_helper_sve_ftssel_d, 1349f0984d40SFabiano Rosas }; 1350f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz, 1351f0984d40SFabiano Rosas ftssel_fns[a->esz], a, 0) 1352f0984d40SFabiano Rosas 1353f0984d40SFabiano Rosas /* 1354f0984d40SFabiano Rosas *** SVE Predicate Logical Operations Group 1355f0984d40SFabiano Rosas */ 1356f0984d40SFabiano Rosas 1357f0984d40SFabiano Rosas static bool do_pppp_flags(DisasContext *s, arg_rprr_s *a, 1358f0984d40SFabiano Rosas const GVecGen4 *gvec_op) 1359f0984d40SFabiano Rosas { 1360f0984d40SFabiano Rosas if (!sve_access_check(s)) { 1361f0984d40SFabiano Rosas return true; 1362f0984d40SFabiano Rosas } 1363f0984d40SFabiano Rosas 1364f0984d40SFabiano Rosas unsigned psz = pred_gvec_reg_size(s); 1365f0984d40SFabiano Rosas int dofs = pred_full_reg_offset(s, a->rd); 1366f0984d40SFabiano Rosas int nofs = pred_full_reg_offset(s, a->rn); 1367f0984d40SFabiano Rosas int mofs = pred_full_reg_offset(s, a->rm); 1368f0984d40SFabiano Rosas int gofs = pred_full_reg_offset(s, a->pg); 1369f0984d40SFabiano Rosas 1370f0984d40SFabiano Rosas if (!a->s) { 1371f0984d40SFabiano Rosas tcg_gen_gvec_4(dofs, nofs, mofs, gofs, psz, psz, gvec_op); 1372f0984d40SFabiano Rosas return true; 1373f0984d40SFabiano Rosas } 1374f0984d40SFabiano Rosas 1375f0984d40SFabiano Rosas if (psz == 8) { 1376f0984d40SFabiano Rosas /* Do the operation and the flags generation in temps. */ 1377f0984d40SFabiano Rosas TCGv_i64 pd = tcg_temp_new_i64(); 1378f0984d40SFabiano Rosas TCGv_i64 pn = tcg_temp_new_i64(); 1379f0984d40SFabiano Rosas TCGv_i64 pm = tcg_temp_new_i64(); 1380f0984d40SFabiano Rosas TCGv_i64 pg = tcg_temp_new_i64(); 1381f0984d40SFabiano Rosas 1382*ad75a51eSRichard Henderson tcg_gen_ld_i64(pn, tcg_env, nofs); 1383*ad75a51eSRichard Henderson tcg_gen_ld_i64(pm, tcg_env, mofs); 1384*ad75a51eSRichard Henderson tcg_gen_ld_i64(pg, tcg_env, gofs); 1385f0984d40SFabiano Rosas 1386f0984d40SFabiano Rosas gvec_op->fni8(pd, pn, pm, pg); 1387*ad75a51eSRichard Henderson tcg_gen_st_i64(pd, tcg_env, dofs); 1388f0984d40SFabiano Rosas 1389f0984d40SFabiano Rosas do_predtest1(pd, pg); 1390f0984d40SFabiano Rosas } else { 1391f0984d40SFabiano Rosas /* The operation and flags generation is large. The computation 1392f0984d40SFabiano Rosas * of the flags depends on the original contents of the guarding 1393f0984d40SFabiano Rosas * predicate. If the destination overwrites the guarding predicate, 1394f0984d40SFabiano Rosas * then the easiest way to get this right is to save a copy. 1395f0984d40SFabiano Rosas */ 1396f0984d40SFabiano Rosas int tofs = gofs; 1397f0984d40SFabiano Rosas if (a->rd == a->pg) { 1398f0984d40SFabiano Rosas tofs = offsetof(CPUARMState, vfp.preg_tmp); 1399f0984d40SFabiano Rosas tcg_gen_gvec_mov(0, tofs, gofs, psz, psz); 1400f0984d40SFabiano Rosas } 1401f0984d40SFabiano Rosas 1402f0984d40SFabiano Rosas tcg_gen_gvec_4(dofs, nofs, mofs, gofs, psz, psz, gvec_op); 1403f0984d40SFabiano Rosas do_predtest(s, dofs, tofs, psz / 8); 1404f0984d40SFabiano Rosas } 1405f0984d40SFabiano Rosas return true; 1406f0984d40SFabiano Rosas } 1407f0984d40SFabiano Rosas 1408f0984d40SFabiano Rosas static void gen_and_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1409f0984d40SFabiano Rosas { 1410f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pn, pm); 1411f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pd, pg); 1412f0984d40SFabiano Rosas } 1413f0984d40SFabiano Rosas 1414f0984d40SFabiano Rosas static void gen_and_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1415f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1416f0984d40SFabiano Rosas { 1417f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pn, pm); 1418f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pd, pg); 1419f0984d40SFabiano Rosas } 1420f0984d40SFabiano Rosas 1421f0984d40SFabiano Rosas static bool trans_AND_pppp(DisasContext *s, arg_rprr_s *a) 1422f0984d40SFabiano Rosas { 1423f0984d40SFabiano Rosas static const GVecGen4 op = { 1424f0984d40SFabiano Rosas .fni8 = gen_and_pg_i64, 1425f0984d40SFabiano Rosas .fniv = gen_and_pg_vec, 1426f0984d40SFabiano Rosas .fno = gen_helper_sve_and_pppp, 1427f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1428f0984d40SFabiano Rosas }; 1429f0984d40SFabiano Rosas 1430f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1431f0984d40SFabiano Rosas return false; 1432f0984d40SFabiano Rosas } 1433f0984d40SFabiano Rosas if (!a->s) { 1434f0984d40SFabiano Rosas if (a->rn == a->rm) { 1435f0984d40SFabiano Rosas if (a->pg == a->rn) { 1436f0984d40SFabiano Rosas return do_mov_p(s, a->rd, a->rn); 1437f0984d40SFabiano Rosas } 1438f0984d40SFabiano Rosas return gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg); 1439f0984d40SFabiano Rosas } else if (a->pg == a->rn || a->pg == a->rm) { 1440f0984d40SFabiano Rosas return gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm); 1441f0984d40SFabiano Rosas } 1442f0984d40SFabiano Rosas } 1443f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1444f0984d40SFabiano Rosas } 1445f0984d40SFabiano Rosas 1446f0984d40SFabiano Rosas static void gen_bic_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1447f0984d40SFabiano Rosas { 1448f0984d40SFabiano Rosas tcg_gen_andc_i64(pd, pn, pm); 1449f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pd, pg); 1450f0984d40SFabiano Rosas } 1451f0984d40SFabiano Rosas 1452f0984d40SFabiano Rosas static void gen_bic_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1453f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1454f0984d40SFabiano Rosas { 1455f0984d40SFabiano Rosas tcg_gen_andc_vec(vece, pd, pn, pm); 1456f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pd, pg); 1457f0984d40SFabiano Rosas } 1458f0984d40SFabiano Rosas 1459f0984d40SFabiano Rosas static bool trans_BIC_pppp(DisasContext *s, arg_rprr_s *a) 1460f0984d40SFabiano Rosas { 1461f0984d40SFabiano Rosas static const GVecGen4 op = { 1462f0984d40SFabiano Rosas .fni8 = gen_bic_pg_i64, 1463f0984d40SFabiano Rosas .fniv = gen_bic_pg_vec, 1464f0984d40SFabiano Rosas .fno = gen_helper_sve_bic_pppp, 1465f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1466f0984d40SFabiano Rosas }; 1467f0984d40SFabiano Rosas 1468f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1469f0984d40SFabiano Rosas return false; 1470f0984d40SFabiano Rosas } 1471f0984d40SFabiano Rosas if (!a->s && a->pg == a->rn) { 1472f0984d40SFabiano Rosas return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm); 1473f0984d40SFabiano Rosas } 1474f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1475f0984d40SFabiano Rosas } 1476f0984d40SFabiano Rosas 1477f0984d40SFabiano Rosas static void gen_eor_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1478f0984d40SFabiano Rosas { 1479f0984d40SFabiano Rosas tcg_gen_xor_i64(pd, pn, pm); 1480f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pd, pg); 1481f0984d40SFabiano Rosas } 1482f0984d40SFabiano Rosas 1483f0984d40SFabiano Rosas static void gen_eor_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1484f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1485f0984d40SFabiano Rosas { 1486f0984d40SFabiano Rosas tcg_gen_xor_vec(vece, pd, pn, pm); 1487f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pd, pg); 1488f0984d40SFabiano Rosas } 1489f0984d40SFabiano Rosas 1490f0984d40SFabiano Rosas static bool trans_EOR_pppp(DisasContext *s, arg_rprr_s *a) 1491f0984d40SFabiano Rosas { 1492f0984d40SFabiano Rosas static const GVecGen4 op = { 1493f0984d40SFabiano Rosas .fni8 = gen_eor_pg_i64, 1494f0984d40SFabiano Rosas .fniv = gen_eor_pg_vec, 1495f0984d40SFabiano Rosas .fno = gen_helper_sve_eor_pppp, 1496f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1497f0984d40SFabiano Rosas }; 1498f0984d40SFabiano Rosas 1499f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1500f0984d40SFabiano Rosas return false; 1501f0984d40SFabiano Rosas } 1502f0984d40SFabiano Rosas /* Alias NOT (predicate) is EOR Pd.B, Pg/Z, Pn.B, Pg.B */ 1503f0984d40SFabiano Rosas if (!a->s && a->pg == a->rm) { 1504f0984d40SFabiano Rosas return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->pg, a->rn); 1505f0984d40SFabiano Rosas } 1506f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1507f0984d40SFabiano Rosas } 1508f0984d40SFabiano Rosas 1509f0984d40SFabiano Rosas static bool trans_SEL_pppp(DisasContext *s, arg_rprr_s *a) 1510f0984d40SFabiano Rosas { 1511f0984d40SFabiano Rosas if (a->s || !dc_isar_feature(aa64_sve, s)) { 1512f0984d40SFabiano Rosas return false; 1513f0984d40SFabiano Rosas } 1514f0984d40SFabiano Rosas if (sve_access_check(s)) { 1515f0984d40SFabiano Rosas unsigned psz = pred_gvec_reg_size(s); 1516f0984d40SFabiano Rosas tcg_gen_gvec_bitsel(MO_8, pred_full_reg_offset(s, a->rd), 1517f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pg), 1518f0984d40SFabiano Rosas pred_full_reg_offset(s, a->rn), 1519f0984d40SFabiano Rosas pred_full_reg_offset(s, a->rm), psz, psz); 1520f0984d40SFabiano Rosas } 1521f0984d40SFabiano Rosas return true; 1522f0984d40SFabiano Rosas } 1523f0984d40SFabiano Rosas 1524f0984d40SFabiano Rosas static void gen_orr_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1525f0984d40SFabiano Rosas { 1526f0984d40SFabiano Rosas tcg_gen_or_i64(pd, pn, pm); 1527f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pd, pg); 1528f0984d40SFabiano Rosas } 1529f0984d40SFabiano Rosas 1530f0984d40SFabiano Rosas static void gen_orr_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1531f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1532f0984d40SFabiano Rosas { 1533f0984d40SFabiano Rosas tcg_gen_or_vec(vece, pd, pn, pm); 1534f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pd, pg); 1535f0984d40SFabiano Rosas } 1536f0984d40SFabiano Rosas 1537f0984d40SFabiano Rosas static bool trans_ORR_pppp(DisasContext *s, arg_rprr_s *a) 1538f0984d40SFabiano Rosas { 1539f0984d40SFabiano Rosas static const GVecGen4 op = { 1540f0984d40SFabiano Rosas .fni8 = gen_orr_pg_i64, 1541f0984d40SFabiano Rosas .fniv = gen_orr_pg_vec, 1542f0984d40SFabiano Rosas .fno = gen_helper_sve_orr_pppp, 1543f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1544f0984d40SFabiano Rosas }; 1545f0984d40SFabiano Rosas 1546f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1547f0984d40SFabiano Rosas return false; 1548f0984d40SFabiano Rosas } 1549f0984d40SFabiano Rosas if (!a->s && a->pg == a->rn && a->rn == a->rm) { 1550f0984d40SFabiano Rosas return do_mov_p(s, a->rd, a->rn); 1551f0984d40SFabiano Rosas } 1552f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1553f0984d40SFabiano Rosas } 1554f0984d40SFabiano Rosas 1555f0984d40SFabiano Rosas static void gen_orn_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1556f0984d40SFabiano Rosas { 1557f0984d40SFabiano Rosas tcg_gen_orc_i64(pd, pn, pm); 1558f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pd, pg); 1559f0984d40SFabiano Rosas } 1560f0984d40SFabiano Rosas 1561f0984d40SFabiano Rosas static void gen_orn_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1562f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1563f0984d40SFabiano Rosas { 1564f0984d40SFabiano Rosas tcg_gen_orc_vec(vece, pd, pn, pm); 1565f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pd, pg); 1566f0984d40SFabiano Rosas } 1567f0984d40SFabiano Rosas 1568f0984d40SFabiano Rosas static bool trans_ORN_pppp(DisasContext *s, arg_rprr_s *a) 1569f0984d40SFabiano Rosas { 1570f0984d40SFabiano Rosas static const GVecGen4 op = { 1571f0984d40SFabiano Rosas .fni8 = gen_orn_pg_i64, 1572f0984d40SFabiano Rosas .fniv = gen_orn_pg_vec, 1573f0984d40SFabiano Rosas .fno = gen_helper_sve_orn_pppp, 1574f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1575f0984d40SFabiano Rosas }; 1576f0984d40SFabiano Rosas 1577f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1578f0984d40SFabiano Rosas return false; 1579f0984d40SFabiano Rosas } 1580f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1581f0984d40SFabiano Rosas } 1582f0984d40SFabiano Rosas 1583f0984d40SFabiano Rosas static void gen_nor_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1584f0984d40SFabiano Rosas { 1585f0984d40SFabiano Rosas tcg_gen_or_i64(pd, pn, pm); 1586f0984d40SFabiano Rosas tcg_gen_andc_i64(pd, pg, pd); 1587f0984d40SFabiano Rosas } 1588f0984d40SFabiano Rosas 1589f0984d40SFabiano Rosas static void gen_nor_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1590f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1591f0984d40SFabiano Rosas { 1592f0984d40SFabiano Rosas tcg_gen_or_vec(vece, pd, pn, pm); 1593f0984d40SFabiano Rosas tcg_gen_andc_vec(vece, pd, pg, pd); 1594f0984d40SFabiano Rosas } 1595f0984d40SFabiano Rosas 1596f0984d40SFabiano Rosas static bool trans_NOR_pppp(DisasContext *s, arg_rprr_s *a) 1597f0984d40SFabiano Rosas { 1598f0984d40SFabiano Rosas static const GVecGen4 op = { 1599f0984d40SFabiano Rosas .fni8 = gen_nor_pg_i64, 1600f0984d40SFabiano Rosas .fniv = gen_nor_pg_vec, 1601f0984d40SFabiano Rosas .fno = gen_helper_sve_nor_pppp, 1602f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1603f0984d40SFabiano Rosas }; 1604f0984d40SFabiano Rosas 1605f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1606f0984d40SFabiano Rosas return false; 1607f0984d40SFabiano Rosas } 1608f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1609f0984d40SFabiano Rosas } 1610f0984d40SFabiano Rosas 1611f0984d40SFabiano Rosas static void gen_nand_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg) 1612f0984d40SFabiano Rosas { 1613f0984d40SFabiano Rosas tcg_gen_and_i64(pd, pn, pm); 1614f0984d40SFabiano Rosas tcg_gen_andc_i64(pd, pg, pd); 1615f0984d40SFabiano Rosas } 1616f0984d40SFabiano Rosas 1617f0984d40SFabiano Rosas static void gen_nand_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn, 1618f0984d40SFabiano Rosas TCGv_vec pm, TCGv_vec pg) 1619f0984d40SFabiano Rosas { 1620f0984d40SFabiano Rosas tcg_gen_and_vec(vece, pd, pn, pm); 1621f0984d40SFabiano Rosas tcg_gen_andc_vec(vece, pd, pg, pd); 1622f0984d40SFabiano Rosas } 1623f0984d40SFabiano Rosas 1624f0984d40SFabiano Rosas static bool trans_NAND_pppp(DisasContext *s, arg_rprr_s *a) 1625f0984d40SFabiano Rosas { 1626f0984d40SFabiano Rosas static const GVecGen4 op = { 1627f0984d40SFabiano Rosas .fni8 = gen_nand_pg_i64, 1628f0984d40SFabiano Rosas .fniv = gen_nand_pg_vec, 1629f0984d40SFabiano Rosas .fno = gen_helper_sve_nand_pppp, 1630f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 1631f0984d40SFabiano Rosas }; 1632f0984d40SFabiano Rosas 1633f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1634f0984d40SFabiano Rosas return false; 1635f0984d40SFabiano Rosas } 1636f0984d40SFabiano Rosas return do_pppp_flags(s, a, &op); 1637f0984d40SFabiano Rosas } 1638f0984d40SFabiano Rosas 1639f0984d40SFabiano Rosas /* 1640f0984d40SFabiano Rosas *** SVE Predicate Misc Group 1641f0984d40SFabiano Rosas */ 1642f0984d40SFabiano Rosas 1643f0984d40SFabiano Rosas static bool trans_PTEST(DisasContext *s, arg_PTEST *a) 1644f0984d40SFabiano Rosas { 1645f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1646f0984d40SFabiano Rosas return false; 1647f0984d40SFabiano Rosas } 1648f0984d40SFabiano Rosas if (sve_access_check(s)) { 1649f0984d40SFabiano Rosas int nofs = pred_full_reg_offset(s, a->rn); 1650f0984d40SFabiano Rosas int gofs = pred_full_reg_offset(s, a->pg); 1651f0984d40SFabiano Rosas int words = DIV_ROUND_UP(pred_full_reg_size(s), 8); 1652f0984d40SFabiano Rosas 1653f0984d40SFabiano Rosas if (words == 1) { 1654f0984d40SFabiano Rosas TCGv_i64 pn = tcg_temp_new_i64(); 1655f0984d40SFabiano Rosas TCGv_i64 pg = tcg_temp_new_i64(); 1656f0984d40SFabiano Rosas 1657*ad75a51eSRichard Henderson tcg_gen_ld_i64(pn, tcg_env, nofs); 1658*ad75a51eSRichard Henderson tcg_gen_ld_i64(pg, tcg_env, gofs); 1659f0984d40SFabiano Rosas do_predtest1(pn, pg); 1660f0984d40SFabiano Rosas } else { 1661f0984d40SFabiano Rosas do_predtest(s, nofs, gofs, words); 1662f0984d40SFabiano Rosas } 1663f0984d40SFabiano Rosas } 1664f0984d40SFabiano Rosas return true; 1665f0984d40SFabiano Rosas } 1666f0984d40SFabiano Rosas 1667f0984d40SFabiano Rosas /* See the ARM pseudocode DecodePredCount. */ 1668f0984d40SFabiano Rosas static unsigned decode_pred_count(unsigned fullsz, int pattern, int esz) 1669f0984d40SFabiano Rosas { 1670f0984d40SFabiano Rosas unsigned elements = fullsz >> esz; 1671f0984d40SFabiano Rosas unsigned bound; 1672f0984d40SFabiano Rosas 1673f0984d40SFabiano Rosas switch (pattern) { 1674f0984d40SFabiano Rosas case 0x0: /* POW2 */ 1675f0984d40SFabiano Rosas return pow2floor(elements); 1676f0984d40SFabiano Rosas case 0x1: /* VL1 */ 1677f0984d40SFabiano Rosas case 0x2: /* VL2 */ 1678f0984d40SFabiano Rosas case 0x3: /* VL3 */ 1679f0984d40SFabiano Rosas case 0x4: /* VL4 */ 1680f0984d40SFabiano Rosas case 0x5: /* VL5 */ 1681f0984d40SFabiano Rosas case 0x6: /* VL6 */ 1682f0984d40SFabiano Rosas case 0x7: /* VL7 */ 1683f0984d40SFabiano Rosas case 0x8: /* VL8 */ 1684f0984d40SFabiano Rosas bound = pattern; 1685f0984d40SFabiano Rosas break; 1686f0984d40SFabiano Rosas case 0x9: /* VL16 */ 1687f0984d40SFabiano Rosas case 0xa: /* VL32 */ 1688f0984d40SFabiano Rosas case 0xb: /* VL64 */ 1689f0984d40SFabiano Rosas case 0xc: /* VL128 */ 1690f0984d40SFabiano Rosas case 0xd: /* VL256 */ 1691f0984d40SFabiano Rosas bound = 16 << (pattern - 9); 1692f0984d40SFabiano Rosas break; 1693f0984d40SFabiano Rosas case 0x1d: /* MUL4 */ 1694f0984d40SFabiano Rosas return elements - elements % 4; 1695f0984d40SFabiano Rosas case 0x1e: /* MUL3 */ 1696f0984d40SFabiano Rosas return elements - elements % 3; 1697f0984d40SFabiano Rosas case 0x1f: /* ALL */ 1698f0984d40SFabiano Rosas return elements; 1699f0984d40SFabiano Rosas default: /* #uimm5 */ 1700f0984d40SFabiano Rosas return 0; 1701f0984d40SFabiano Rosas } 1702f0984d40SFabiano Rosas return elements >= bound ? bound : 0; 1703f0984d40SFabiano Rosas } 1704f0984d40SFabiano Rosas 1705f0984d40SFabiano Rosas /* This handles all of the predicate initialization instructions, 1706f0984d40SFabiano Rosas * PTRUE, PFALSE, SETFFR. For PFALSE, we will have set PAT == 32 1707f0984d40SFabiano Rosas * so that decode_pred_count returns 0. For SETFFR, we will have 1708f0984d40SFabiano Rosas * set RD == 16 == FFR. 1709f0984d40SFabiano Rosas */ 1710f0984d40SFabiano Rosas static bool do_predset(DisasContext *s, int esz, int rd, int pat, bool setflag) 1711f0984d40SFabiano Rosas { 1712f0984d40SFabiano Rosas if (!sve_access_check(s)) { 1713f0984d40SFabiano Rosas return true; 1714f0984d40SFabiano Rosas } 1715f0984d40SFabiano Rosas 1716f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 1717f0984d40SFabiano Rosas unsigned ofs = pred_full_reg_offset(s, rd); 1718f0984d40SFabiano Rosas unsigned numelem, setsz, i; 1719f0984d40SFabiano Rosas uint64_t word, lastword; 1720f0984d40SFabiano Rosas TCGv_i64 t; 1721f0984d40SFabiano Rosas 1722f0984d40SFabiano Rosas numelem = decode_pred_count(fullsz, pat, esz); 1723f0984d40SFabiano Rosas 1724f0984d40SFabiano Rosas /* Determine what we must store into each bit, and how many. */ 1725f0984d40SFabiano Rosas if (numelem == 0) { 1726f0984d40SFabiano Rosas lastword = word = 0; 1727f0984d40SFabiano Rosas setsz = fullsz; 1728f0984d40SFabiano Rosas } else { 1729f0984d40SFabiano Rosas setsz = numelem << esz; 1730f0984d40SFabiano Rosas lastword = word = pred_esz_masks[esz]; 1731f0984d40SFabiano Rosas if (setsz % 64) { 1732f0984d40SFabiano Rosas lastword &= MAKE_64BIT_MASK(0, setsz % 64); 1733f0984d40SFabiano Rosas } 1734f0984d40SFabiano Rosas } 1735f0984d40SFabiano Rosas 1736f0984d40SFabiano Rosas t = tcg_temp_new_i64(); 1737f0984d40SFabiano Rosas if (fullsz <= 64) { 1738f0984d40SFabiano Rosas tcg_gen_movi_i64(t, lastword); 1739*ad75a51eSRichard Henderson tcg_gen_st_i64(t, tcg_env, ofs); 1740f0984d40SFabiano Rosas goto done; 1741f0984d40SFabiano Rosas } 1742f0984d40SFabiano Rosas 1743f0984d40SFabiano Rosas if (word == lastword) { 1744f0984d40SFabiano Rosas unsigned maxsz = size_for_gvec(fullsz / 8); 1745f0984d40SFabiano Rosas unsigned oprsz = size_for_gvec(setsz / 8); 1746f0984d40SFabiano Rosas 1747f0984d40SFabiano Rosas if (oprsz * 8 == setsz) { 1748f0984d40SFabiano Rosas tcg_gen_gvec_dup_imm(MO_64, ofs, oprsz, maxsz, word); 1749f0984d40SFabiano Rosas goto done; 1750f0984d40SFabiano Rosas } 1751f0984d40SFabiano Rosas } 1752f0984d40SFabiano Rosas 1753f0984d40SFabiano Rosas setsz /= 8; 1754f0984d40SFabiano Rosas fullsz /= 8; 1755f0984d40SFabiano Rosas 1756f0984d40SFabiano Rosas tcg_gen_movi_i64(t, word); 1757f0984d40SFabiano Rosas for (i = 0; i < QEMU_ALIGN_DOWN(setsz, 8); i += 8) { 1758*ad75a51eSRichard Henderson tcg_gen_st_i64(t, tcg_env, ofs + i); 1759f0984d40SFabiano Rosas } 1760f0984d40SFabiano Rosas if (lastword != word) { 1761f0984d40SFabiano Rosas tcg_gen_movi_i64(t, lastword); 1762*ad75a51eSRichard Henderson tcg_gen_st_i64(t, tcg_env, ofs + i); 1763f0984d40SFabiano Rosas i += 8; 1764f0984d40SFabiano Rosas } 1765f0984d40SFabiano Rosas if (i < fullsz) { 1766f0984d40SFabiano Rosas tcg_gen_movi_i64(t, 0); 1767f0984d40SFabiano Rosas for (; i < fullsz; i += 8) { 1768*ad75a51eSRichard Henderson tcg_gen_st_i64(t, tcg_env, ofs + i); 1769f0984d40SFabiano Rosas } 1770f0984d40SFabiano Rosas } 1771f0984d40SFabiano Rosas 1772f0984d40SFabiano Rosas done: 1773f0984d40SFabiano Rosas /* PTRUES */ 1774f0984d40SFabiano Rosas if (setflag) { 1775f0984d40SFabiano Rosas tcg_gen_movi_i32(cpu_NF, -(word != 0)); 1776f0984d40SFabiano Rosas tcg_gen_movi_i32(cpu_CF, word == 0); 1777f0984d40SFabiano Rosas tcg_gen_movi_i32(cpu_VF, 0); 1778f0984d40SFabiano Rosas tcg_gen_mov_i32(cpu_ZF, cpu_NF); 1779f0984d40SFabiano Rosas } 1780f0984d40SFabiano Rosas return true; 1781f0984d40SFabiano Rosas } 1782f0984d40SFabiano Rosas 1783f0984d40SFabiano Rosas TRANS_FEAT(PTRUE, aa64_sve, do_predset, a->esz, a->rd, a->pat, a->s) 1784f0984d40SFabiano Rosas 1785f0984d40SFabiano Rosas /* Note pat == 31 is #all, to set all elements. */ 1786f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(SETFFR, aa64_sve, 1787f0984d40SFabiano Rosas do_predset, 0, FFR_PRED_NUM, 31, false) 1788f0984d40SFabiano Rosas 1789f0984d40SFabiano Rosas /* Note pat == 32 is #unimp, to set no elements. */ 1790f0984d40SFabiano Rosas TRANS_FEAT(PFALSE, aa64_sve, do_predset, 0, a->rd, 32, false) 1791f0984d40SFabiano Rosas 1792f0984d40SFabiano Rosas static bool trans_RDFFR_p(DisasContext *s, arg_RDFFR_p *a) 1793f0984d40SFabiano Rosas { 1794f0984d40SFabiano Rosas /* The path through do_pppp_flags is complicated enough to want to avoid 1795f0984d40SFabiano Rosas * duplication. Frob the arguments into the form of a predicated AND. 1796f0984d40SFabiano Rosas */ 1797f0984d40SFabiano Rosas arg_rprr_s alt_a = { 1798f0984d40SFabiano Rosas .rd = a->rd, .pg = a->pg, .s = a->s, 1799f0984d40SFabiano Rosas .rn = FFR_PRED_NUM, .rm = FFR_PRED_NUM, 1800f0984d40SFabiano Rosas }; 1801f0984d40SFabiano Rosas 1802f0984d40SFabiano Rosas s->is_nonstreaming = true; 1803f0984d40SFabiano Rosas return trans_AND_pppp(s, &alt_a); 1804f0984d40SFabiano Rosas } 1805f0984d40SFabiano Rosas 1806f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(RDFFR, aa64_sve, do_mov_p, a->rd, FFR_PRED_NUM) 1807f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(WRFFR, aa64_sve, do_mov_p, FFR_PRED_NUM, a->rn) 1808f0984d40SFabiano Rosas 1809f0984d40SFabiano Rosas static bool do_pfirst_pnext(DisasContext *s, arg_rr_esz *a, 1810f0984d40SFabiano Rosas void (*gen_fn)(TCGv_i32, TCGv_ptr, 1811f0984d40SFabiano Rosas TCGv_ptr, TCGv_i32)) 1812f0984d40SFabiano Rosas { 1813f0984d40SFabiano Rosas if (!sve_access_check(s)) { 1814f0984d40SFabiano Rosas return true; 1815f0984d40SFabiano Rosas } 1816f0984d40SFabiano Rosas 1817f0984d40SFabiano Rosas TCGv_ptr t_pd = tcg_temp_new_ptr(); 1818f0984d40SFabiano Rosas TCGv_ptr t_pg = tcg_temp_new_ptr(); 1819f0984d40SFabiano Rosas TCGv_i32 t; 1820f0984d40SFabiano Rosas unsigned desc = 0; 1821f0984d40SFabiano Rosas 1822f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pred_full_reg_size(s)); 1823f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz); 1824f0984d40SFabiano Rosas 1825*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pd, tcg_env, pred_full_reg_offset(s, a->rd)); 1826*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->rn)); 1827f0984d40SFabiano Rosas t = tcg_temp_new_i32(); 1828f0984d40SFabiano Rosas 1829f0984d40SFabiano Rosas gen_fn(t, t_pd, t_pg, tcg_constant_i32(desc)); 1830f0984d40SFabiano Rosas 1831f0984d40SFabiano Rosas do_pred_flags(t); 1832f0984d40SFabiano Rosas return true; 1833f0984d40SFabiano Rosas } 1834f0984d40SFabiano Rosas 1835f0984d40SFabiano Rosas TRANS_FEAT(PFIRST, aa64_sve, do_pfirst_pnext, a, gen_helper_sve_pfirst) 1836f0984d40SFabiano Rosas TRANS_FEAT(PNEXT, aa64_sve, do_pfirst_pnext, a, gen_helper_sve_pnext) 1837f0984d40SFabiano Rosas 1838f0984d40SFabiano Rosas /* 1839f0984d40SFabiano Rosas *** SVE Element Count Group 1840f0984d40SFabiano Rosas */ 1841f0984d40SFabiano Rosas 1842f0984d40SFabiano Rosas /* Perform an inline saturating addition of a 32-bit value within 1843f0984d40SFabiano Rosas * a 64-bit register. The second operand is known to be positive, 1844673d8215SMichael Tokarev * which halves the comparisons we must perform to bound the result. 1845f0984d40SFabiano Rosas */ 1846f0984d40SFabiano Rosas static void do_sat_addsub_32(TCGv_i64 reg, TCGv_i64 val, bool u, bool d) 1847f0984d40SFabiano Rosas { 1848f0984d40SFabiano Rosas int64_t ibound; 1849f0984d40SFabiano Rosas 1850f0984d40SFabiano Rosas /* Use normal 64-bit arithmetic to detect 32-bit overflow. */ 1851f0984d40SFabiano Rosas if (u) { 1852f0984d40SFabiano Rosas tcg_gen_ext32u_i64(reg, reg); 1853f0984d40SFabiano Rosas } else { 1854f0984d40SFabiano Rosas tcg_gen_ext32s_i64(reg, reg); 1855f0984d40SFabiano Rosas } 1856f0984d40SFabiano Rosas if (d) { 1857f0984d40SFabiano Rosas tcg_gen_sub_i64(reg, reg, val); 1858f0984d40SFabiano Rosas ibound = (u ? 0 : INT32_MIN); 1859f0984d40SFabiano Rosas tcg_gen_smax_i64(reg, reg, tcg_constant_i64(ibound)); 1860f0984d40SFabiano Rosas } else { 1861f0984d40SFabiano Rosas tcg_gen_add_i64(reg, reg, val); 1862f0984d40SFabiano Rosas ibound = (u ? UINT32_MAX : INT32_MAX); 1863f0984d40SFabiano Rosas tcg_gen_smin_i64(reg, reg, tcg_constant_i64(ibound)); 1864f0984d40SFabiano Rosas } 1865f0984d40SFabiano Rosas } 1866f0984d40SFabiano Rosas 1867f0984d40SFabiano Rosas /* Similarly with 64-bit values. */ 1868f0984d40SFabiano Rosas static void do_sat_addsub_64(TCGv_i64 reg, TCGv_i64 val, bool u, bool d) 1869f0984d40SFabiano Rosas { 1870f0984d40SFabiano Rosas TCGv_i64 t0 = tcg_temp_new_i64(); 1871f0984d40SFabiano Rosas TCGv_i64 t2; 1872f0984d40SFabiano Rosas 1873f0984d40SFabiano Rosas if (u) { 1874f0984d40SFabiano Rosas if (d) { 1875f0984d40SFabiano Rosas tcg_gen_sub_i64(t0, reg, val); 1876f0984d40SFabiano Rosas t2 = tcg_constant_i64(0); 1877f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_LTU, reg, reg, val, t2, t0); 1878f0984d40SFabiano Rosas } else { 1879f0984d40SFabiano Rosas tcg_gen_add_i64(t0, reg, val); 1880f0984d40SFabiano Rosas t2 = tcg_constant_i64(-1); 1881f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_LTU, reg, t0, reg, t2, t0); 1882f0984d40SFabiano Rosas } 1883f0984d40SFabiano Rosas } else { 1884f0984d40SFabiano Rosas TCGv_i64 t1 = tcg_temp_new_i64(); 1885f0984d40SFabiano Rosas if (d) { 1886f0984d40SFabiano Rosas /* Detect signed overflow for subtraction. */ 1887f0984d40SFabiano Rosas tcg_gen_xor_i64(t0, reg, val); 1888f0984d40SFabiano Rosas tcg_gen_sub_i64(t1, reg, val); 1889f0984d40SFabiano Rosas tcg_gen_xor_i64(reg, reg, t1); 1890f0984d40SFabiano Rosas tcg_gen_and_i64(t0, t0, reg); 1891f0984d40SFabiano Rosas 1892f0984d40SFabiano Rosas /* Bound the result. */ 1893f0984d40SFabiano Rosas tcg_gen_movi_i64(reg, INT64_MIN); 1894f0984d40SFabiano Rosas t2 = tcg_constant_i64(0); 1895f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_LT, reg, t0, t2, reg, t1); 1896f0984d40SFabiano Rosas } else { 1897f0984d40SFabiano Rosas /* Detect signed overflow for addition. */ 1898f0984d40SFabiano Rosas tcg_gen_xor_i64(t0, reg, val); 1899f0984d40SFabiano Rosas tcg_gen_add_i64(reg, reg, val); 1900f0984d40SFabiano Rosas tcg_gen_xor_i64(t1, reg, val); 1901f0984d40SFabiano Rosas tcg_gen_andc_i64(t0, t1, t0); 1902f0984d40SFabiano Rosas 1903f0984d40SFabiano Rosas /* Bound the result. */ 1904f0984d40SFabiano Rosas tcg_gen_movi_i64(t1, INT64_MAX); 1905f0984d40SFabiano Rosas t2 = tcg_constant_i64(0); 1906f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_LT, reg, t0, t2, t1, reg); 1907f0984d40SFabiano Rosas } 1908f0984d40SFabiano Rosas } 1909f0984d40SFabiano Rosas } 1910f0984d40SFabiano Rosas 1911f0984d40SFabiano Rosas /* Similarly with a vector and a scalar operand. */ 1912f0984d40SFabiano Rosas static void do_sat_addsub_vec(DisasContext *s, int esz, int rd, int rn, 1913f0984d40SFabiano Rosas TCGv_i64 val, bool u, bool d) 1914f0984d40SFabiano Rosas { 1915f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 1916f0984d40SFabiano Rosas TCGv_ptr dptr, nptr; 1917f0984d40SFabiano Rosas TCGv_i32 t32, desc; 1918f0984d40SFabiano Rosas TCGv_i64 t64; 1919f0984d40SFabiano Rosas 1920f0984d40SFabiano Rosas dptr = tcg_temp_new_ptr(); 1921f0984d40SFabiano Rosas nptr = tcg_temp_new_ptr(); 1922*ad75a51eSRichard Henderson tcg_gen_addi_ptr(dptr, tcg_env, vec_full_reg_offset(s, rd)); 1923*ad75a51eSRichard Henderson tcg_gen_addi_ptr(nptr, tcg_env, vec_full_reg_offset(s, rn)); 1924f0984d40SFabiano Rosas desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 1925f0984d40SFabiano Rosas 1926f0984d40SFabiano Rosas switch (esz) { 1927f0984d40SFabiano Rosas case MO_8: 1928f0984d40SFabiano Rosas t32 = tcg_temp_new_i32(); 1929f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(t32, val); 1930f0984d40SFabiano Rosas if (d) { 1931f0984d40SFabiano Rosas tcg_gen_neg_i32(t32, t32); 1932f0984d40SFabiano Rosas } 1933f0984d40SFabiano Rosas if (u) { 1934f0984d40SFabiano Rosas gen_helper_sve_uqaddi_b(dptr, nptr, t32, desc); 1935f0984d40SFabiano Rosas } else { 1936f0984d40SFabiano Rosas gen_helper_sve_sqaddi_b(dptr, nptr, t32, desc); 1937f0984d40SFabiano Rosas } 1938f0984d40SFabiano Rosas break; 1939f0984d40SFabiano Rosas 1940f0984d40SFabiano Rosas case MO_16: 1941f0984d40SFabiano Rosas t32 = tcg_temp_new_i32(); 1942f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(t32, val); 1943f0984d40SFabiano Rosas if (d) { 1944f0984d40SFabiano Rosas tcg_gen_neg_i32(t32, t32); 1945f0984d40SFabiano Rosas } 1946f0984d40SFabiano Rosas if (u) { 1947f0984d40SFabiano Rosas gen_helper_sve_uqaddi_h(dptr, nptr, t32, desc); 1948f0984d40SFabiano Rosas } else { 1949f0984d40SFabiano Rosas gen_helper_sve_sqaddi_h(dptr, nptr, t32, desc); 1950f0984d40SFabiano Rosas } 1951f0984d40SFabiano Rosas break; 1952f0984d40SFabiano Rosas 1953f0984d40SFabiano Rosas case MO_32: 1954f0984d40SFabiano Rosas t64 = tcg_temp_new_i64(); 1955f0984d40SFabiano Rosas if (d) { 1956f0984d40SFabiano Rosas tcg_gen_neg_i64(t64, val); 1957f0984d40SFabiano Rosas } else { 1958f0984d40SFabiano Rosas tcg_gen_mov_i64(t64, val); 1959f0984d40SFabiano Rosas } 1960f0984d40SFabiano Rosas if (u) { 1961f0984d40SFabiano Rosas gen_helper_sve_uqaddi_s(dptr, nptr, t64, desc); 1962f0984d40SFabiano Rosas } else { 1963f0984d40SFabiano Rosas gen_helper_sve_sqaddi_s(dptr, nptr, t64, desc); 1964f0984d40SFabiano Rosas } 1965f0984d40SFabiano Rosas break; 1966f0984d40SFabiano Rosas 1967f0984d40SFabiano Rosas case MO_64: 1968f0984d40SFabiano Rosas if (u) { 1969f0984d40SFabiano Rosas if (d) { 1970f0984d40SFabiano Rosas gen_helper_sve_uqsubi_d(dptr, nptr, val, desc); 1971f0984d40SFabiano Rosas } else { 1972f0984d40SFabiano Rosas gen_helper_sve_uqaddi_d(dptr, nptr, val, desc); 1973f0984d40SFabiano Rosas } 1974f0984d40SFabiano Rosas } else if (d) { 1975f0984d40SFabiano Rosas t64 = tcg_temp_new_i64(); 1976f0984d40SFabiano Rosas tcg_gen_neg_i64(t64, val); 1977f0984d40SFabiano Rosas gen_helper_sve_sqaddi_d(dptr, nptr, t64, desc); 1978f0984d40SFabiano Rosas } else { 1979f0984d40SFabiano Rosas gen_helper_sve_sqaddi_d(dptr, nptr, val, desc); 1980f0984d40SFabiano Rosas } 1981f0984d40SFabiano Rosas break; 1982f0984d40SFabiano Rosas 1983f0984d40SFabiano Rosas default: 1984f0984d40SFabiano Rosas g_assert_not_reached(); 1985f0984d40SFabiano Rosas } 1986f0984d40SFabiano Rosas } 1987f0984d40SFabiano Rosas 1988f0984d40SFabiano Rosas static bool trans_CNT_r(DisasContext *s, arg_CNT_r *a) 1989f0984d40SFabiano Rosas { 1990f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 1991f0984d40SFabiano Rosas return false; 1992f0984d40SFabiano Rosas } 1993f0984d40SFabiano Rosas if (sve_access_check(s)) { 1994f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 1995f0984d40SFabiano Rosas unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz); 1996f0984d40SFabiano Rosas tcg_gen_movi_i64(cpu_reg(s, a->rd), numelem * a->imm); 1997f0984d40SFabiano Rosas } 1998f0984d40SFabiano Rosas return true; 1999f0984d40SFabiano Rosas } 2000f0984d40SFabiano Rosas 2001f0984d40SFabiano Rosas static bool trans_INCDEC_r(DisasContext *s, arg_incdec_cnt *a) 2002f0984d40SFabiano Rosas { 2003f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2004f0984d40SFabiano Rosas return false; 2005f0984d40SFabiano Rosas } 2006f0984d40SFabiano Rosas if (sve_access_check(s)) { 2007f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 2008f0984d40SFabiano Rosas unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz); 2009f0984d40SFabiano Rosas int inc = numelem * a->imm * (a->d ? -1 : 1); 2010f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 2011f0984d40SFabiano Rosas 2012f0984d40SFabiano Rosas tcg_gen_addi_i64(reg, reg, inc); 2013f0984d40SFabiano Rosas } 2014f0984d40SFabiano Rosas return true; 2015f0984d40SFabiano Rosas } 2016f0984d40SFabiano Rosas 2017f0984d40SFabiano Rosas static bool trans_SINCDEC_r_32(DisasContext *s, arg_incdec_cnt *a) 2018f0984d40SFabiano Rosas { 2019f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2020f0984d40SFabiano Rosas return false; 2021f0984d40SFabiano Rosas } 2022f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2023f0984d40SFabiano Rosas return true; 2024f0984d40SFabiano Rosas } 2025f0984d40SFabiano Rosas 2026f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 2027f0984d40SFabiano Rosas unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz); 2028f0984d40SFabiano Rosas int inc = numelem * a->imm; 2029f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 2030f0984d40SFabiano Rosas 2031f0984d40SFabiano Rosas /* Use normal 64-bit arithmetic to detect 32-bit overflow. */ 2032f0984d40SFabiano Rosas if (inc == 0) { 2033f0984d40SFabiano Rosas if (a->u) { 2034f0984d40SFabiano Rosas tcg_gen_ext32u_i64(reg, reg); 2035f0984d40SFabiano Rosas } else { 2036f0984d40SFabiano Rosas tcg_gen_ext32s_i64(reg, reg); 2037f0984d40SFabiano Rosas } 2038f0984d40SFabiano Rosas } else { 2039f0984d40SFabiano Rosas do_sat_addsub_32(reg, tcg_constant_i64(inc), a->u, a->d); 2040f0984d40SFabiano Rosas } 2041f0984d40SFabiano Rosas return true; 2042f0984d40SFabiano Rosas } 2043f0984d40SFabiano Rosas 2044f0984d40SFabiano Rosas static bool trans_SINCDEC_r_64(DisasContext *s, arg_incdec_cnt *a) 2045f0984d40SFabiano Rosas { 2046f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2047f0984d40SFabiano Rosas return false; 2048f0984d40SFabiano Rosas } 2049f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2050f0984d40SFabiano Rosas return true; 2051f0984d40SFabiano Rosas } 2052f0984d40SFabiano Rosas 2053f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 2054f0984d40SFabiano Rosas unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz); 2055f0984d40SFabiano Rosas int inc = numelem * a->imm; 2056f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 2057f0984d40SFabiano Rosas 2058f0984d40SFabiano Rosas if (inc != 0) { 2059f0984d40SFabiano Rosas do_sat_addsub_64(reg, tcg_constant_i64(inc), a->u, a->d); 2060f0984d40SFabiano Rosas } 2061f0984d40SFabiano Rosas return true; 2062f0984d40SFabiano Rosas } 2063f0984d40SFabiano Rosas 2064f0984d40SFabiano Rosas static bool trans_INCDEC_v(DisasContext *s, arg_incdec2_cnt *a) 2065f0984d40SFabiano Rosas { 2066f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 2067f0984d40SFabiano Rosas return false; 2068f0984d40SFabiano Rosas } 2069f0984d40SFabiano Rosas 2070f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 2071f0984d40SFabiano Rosas unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz); 2072f0984d40SFabiano Rosas int inc = numelem * a->imm; 2073f0984d40SFabiano Rosas 2074f0984d40SFabiano Rosas if (inc != 0) { 2075f0984d40SFabiano Rosas if (sve_access_check(s)) { 2076f0984d40SFabiano Rosas tcg_gen_gvec_adds(a->esz, vec_full_reg_offset(s, a->rd), 2077f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 2078f0984d40SFabiano Rosas tcg_constant_i64(a->d ? -inc : inc), 2079f0984d40SFabiano Rosas fullsz, fullsz); 2080f0984d40SFabiano Rosas } 2081f0984d40SFabiano Rosas } else { 2082f0984d40SFabiano Rosas do_mov_z(s, a->rd, a->rn); 2083f0984d40SFabiano Rosas } 2084f0984d40SFabiano Rosas return true; 2085f0984d40SFabiano Rosas } 2086f0984d40SFabiano Rosas 2087f0984d40SFabiano Rosas static bool trans_SINCDEC_v(DisasContext *s, arg_incdec2_cnt *a) 2088f0984d40SFabiano Rosas { 2089f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 2090f0984d40SFabiano Rosas return false; 2091f0984d40SFabiano Rosas } 2092f0984d40SFabiano Rosas 2093f0984d40SFabiano Rosas unsigned fullsz = vec_full_reg_size(s); 2094f0984d40SFabiano Rosas unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz); 2095f0984d40SFabiano Rosas int inc = numelem * a->imm; 2096f0984d40SFabiano Rosas 2097f0984d40SFabiano Rosas if (inc != 0) { 2098f0984d40SFabiano Rosas if (sve_access_check(s)) { 2099f0984d40SFabiano Rosas do_sat_addsub_vec(s, a->esz, a->rd, a->rn, 2100f0984d40SFabiano Rosas tcg_constant_i64(inc), a->u, a->d); 2101f0984d40SFabiano Rosas } 2102f0984d40SFabiano Rosas } else { 2103f0984d40SFabiano Rosas do_mov_z(s, a->rd, a->rn); 2104f0984d40SFabiano Rosas } 2105f0984d40SFabiano Rosas return true; 2106f0984d40SFabiano Rosas } 2107f0984d40SFabiano Rosas 2108f0984d40SFabiano Rosas /* 2109f0984d40SFabiano Rosas *** SVE Bitwise Immediate Group 2110f0984d40SFabiano Rosas */ 2111f0984d40SFabiano Rosas 2112f0984d40SFabiano Rosas static bool do_zz_dbm(DisasContext *s, arg_rr_dbm *a, GVecGen2iFn *gvec_fn) 2113f0984d40SFabiano Rosas { 2114f0984d40SFabiano Rosas uint64_t imm; 2115f0984d40SFabiano Rosas if (!logic_imm_decode_wmask(&imm, extract32(a->dbm, 12, 1), 2116f0984d40SFabiano Rosas extract32(a->dbm, 0, 6), 2117f0984d40SFabiano Rosas extract32(a->dbm, 6, 6))) { 2118f0984d40SFabiano Rosas return false; 2119f0984d40SFabiano Rosas } 2120f0984d40SFabiano Rosas return gen_gvec_fn_zzi(s, gvec_fn, MO_64, a->rd, a->rn, imm); 2121f0984d40SFabiano Rosas } 2122f0984d40SFabiano Rosas 2123f0984d40SFabiano Rosas TRANS_FEAT(AND_zzi, aa64_sve, do_zz_dbm, a, tcg_gen_gvec_andi) 2124f0984d40SFabiano Rosas TRANS_FEAT(ORR_zzi, aa64_sve, do_zz_dbm, a, tcg_gen_gvec_ori) 2125f0984d40SFabiano Rosas TRANS_FEAT(EOR_zzi, aa64_sve, do_zz_dbm, a, tcg_gen_gvec_xori) 2126f0984d40SFabiano Rosas 2127f0984d40SFabiano Rosas static bool trans_DUPM(DisasContext *s, arg_DUPM *a) 2128f0984d40SFabiano Rosas { 2129f0984d40SFabiano Rosas uint64_t imm; 2130f0984d40SFabiano Rosas 2131f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2132f0984d40SFabiano Rosas return false; 2133f0984d40SFabiano Rosas } 2134f0984d40SFabiano Rosas if (!logic_imm_decode_wmask(&imm, extract32(a->dbm, 12, 1), 2135f0984d40SFabiano Rosas extract32(a->dbm, 0, 6), 2136f0984d40SFabiano Rosas extract32(a->dbm, 6, 6))) { 2137f0984d40SFabiano Rosas return false; 2138f0984d40SFabiano Rosas } 2139f0984d40SFabiano Rosas if (sve_access_check(s)) { 2140f0984d40SFabiano Rosas do_dupi_z(s, a->rd, imm); 2141f0984d40SFabiano Rosas } 2142f0984d40SFabiano Rosas return true; 2143f0984d40SFabiano Rosas } 2144f0984d40SFabiano Rosas 2145f0984d40SFabiano Rosas /* 2146f0984d40SFabiano Rosas *** SVE Integer Wide Immediate - Predicated Group 2147f0984d40SFabiano Rosas */ 2148f0984d40SFabiano Rosas 2149f0984d40SFabiano Rosas /* Implement all merging copies. This is used for CPY (immediate), 2150f0984d40SFabiano Rosas * FCPY, CPY (scalar), CPY (SIMD&FP scalar). 2151f0984d40SFabiano Rosas */ 2152f0984d40SFabiano Rosas static void do_cpy_m(DisasContext *s, int esz, int rd, int rn, int pg, 2153f0984d40SFabiano Rosas TCGv_i64 val) 2154f0984d40SFabiano Rosas { 2155f0984d40SFabiano Rosas typedef void gen_cpy(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i32); 2156f0984d40SFabiano Rosas static gen_cpy * const fns[4] = { 2157f0984d40SFabiano Rosas gen_helper_sve_cpy_m_b, gen_helper_sve_cpy_m_h, 2158f0984d40SFabiano Rosas gen_helper_sve_cpy_m_s, gen_helper_sve_cpy_m_d, 2159f0984d40SFabiano Rosas }; 2160f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2161f0984d40SFabiano Rosas TCGv_i32 desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 2162f0984d40SFabiano Rosas TCGv_ptr t_zd = tcg_temp_new_ptr(); 2163f0984d40SFabiano Rosas TCGv_ptr t_zn = tcg_temp_new_ptr(); 2164f0984d40SFabiano Rosas TCGv_ptr t_pg = tcg_temp_new_ptr(); 2165f0984d40SFabiano Rosas 2166*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zd, tcg_env, vec_full_reg_offset(s, rd)); 2167*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, rn)); 2168*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); 2169f0984d40SFabiano Rosas 2170f0984d40SFabiano Rosas fns[esz](t_zd, t_zn, t_pg, val, desc); 2171f0984d40SFabiano Rosas } 2172f0984d40SFabiano Rosas 2173f0984d40SFabiano Rosas static bool trans_FCPY(DisasContext *s, arg_FCPY *a) 2174f0984d40SFabiano Rosas { 2175f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 2176f0984d40SFabiano Rosas return false; 2177f0984d40SFabiano Rosas } 2178f0984d40SFabiano Rosas if (sve_access_check(s)) { 2179f0984d40SFabiano Rosas /* Decode the VFP immediate. */ 2180f0984d40SFabiano Rosas uint64_t imm = vfp_expand_imm(a->esz, a->imm); 2181f0984d40SFabiano Rosas do_cpy_m(s, a->esz, a->rd, a->rn, a->pg, tcg_constant_i64(imm)); 2182f0984d40SFabiano Rosas } 2183f0984d40SFabiano Rosas return true; 2184f0984d40SFabiano Rosas } 2185f0984d40SFabiano Rosas 2186f0984d40SFabiano Rosas static bool trans_CPY_m_i(DisasContext *s, arg_rpri_esz *a) 2187f0984d40SFabiano Rosas { 2188f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2189f0984d40SFabiano Rosas return false; 2190f0984d40SFabiano Rosas } 2191f0984d40SFabiano Rosas if (sve_access_check(s)) { 2192f0984d40SFabiano Rosas do_cpy_m(s, a->esz, a->rd, a->rn, a->pg, tcg_constant_i64(a->imm)); 2193f0984d40SFabiano Rosas } 2194f0984d40SFabiano Rosas return true; 2195f0984d40SFabiano Rosas } 2196f0984d40SFabiano Rosas 2197f0984d40SFabiano Rosas static bool trans_CPY_z_i(DisasContext *s, arg_CPY_z_i *a) 2198f0984d40SFabiano Rosas { 2199f0984d40SFabiano Rosas static gen_helper_gvec_2i * const fns[4] = { 2200f0984d40SFabiano Rosas gen_helper_sve_cpy_z_b, gen_helper_sve_cpy_z_h, 2201f0984d40SFabiano Rosas gen_helper_sve_cpy_z_s, gen_helper_sve_cpy_z_d, 2202f0984d40SFabiano Rosas }; 2203f0984d40SFabiano Rosas 2204f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2205f0984d40SFabiano Rosas return false; 2206f0984d40SFabiano Rosas } 2207f0984d40SFabiano Rosas if (sve_access_check(s)) { 2208f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2209f0984d40SFabiano Rosas tcg_gen_gvec_2i_ool(vec_full_reg_offset(s, a->rd), 2210f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pg), 2211f0984d40SFabiano Rosas tcg_constant_i64(a->imm), 2212f0984d40SFabiano Rosas vsz, vsz, 0, fns[a->esz]); 2213f0984d40SFabiano Rosas } 2214f0984d40SFabiano Rosas return true; 2215f0984d40SFabiano Rosas } 2216f0984d40SFabiano Rosas 2217f0984d40SFabiano Rosas /* 2218f0984d40SFabiano Rosas *** SVE Permute Extract Group 2219f0984d40SFabiano Rosas */ 2220f0984d40SFabiano Rosas 2221f0984d40SFabiano Rosas static bool do_EXT(DisasContext *s, int rd, int rn, int rm, int imm) 2222f0984d40SFabiano Rosas { 2223f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2224f0984d40SFabiano Rosas return true; 2225f0984d40SFabiano Rosas } 2226f0984d40SFabiano Rosas 2227f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2228f0984d40SFabiano Rosas unsigned n_ofs = imm >= vsz ? 0 : imm; 2229f0984d40SFabiano Rosas unsigned n_siz = vsz - n_ofs; 2230f0984d40SFabiano Rosas unsigned d = vec_full_reg_offset(s, rd); 2231f0984d40SFabiano Rosas unsigned n = vec_full_reg_offset(s, rn); 2232f0984d40SFabiano Rosas unsigned m = vec_full_reg_offset(s, rm); 2233f0984d40SFabiano Rosas 2234f0984d40SFabiano Rosas /* Use host vector move insns if we have appropriate sizes 2235f0984d40SFabiano Rosas * and no unfortunate overlap. 2236f0984d40SFabiano Rosas */ 2237f0984d40SFabiano Rosas if (m != d 2238f0984d40SFabiano Rosas && n_ofs == size_for_gvec(n_ofs) 2239f0984d40SFabiano Rosas && n_siz == size_for_gvec(n_siz) 2240f0984d40SFabiano Rosas && (d != n || n_siz <= n_ofs)) { 2241f0984d40SFabiano Rosas tcg_gen_gvec_mov(0, d, n + n_ofs, n_siz, n_siz); 2242f0984d40SFabiano Rosas if (n_ofs != 0) { 2243f0984d40SFabiano Rosas tcg_gen_gvec_mov(0, d + n_siz, m, n_ofs, n_ofs); 2244f0984d40SFabiano Rosas } 2245f0984d40SFabiano Rosas } else { 2246f0984d40SFabiano Rosas tcg_gen_gvec_3_ool(d, n, m, vsz, vsz, n_ofs, gen_helper_sve_ext); 2247f0984d40SFabiano Rosas } 2248f0984d40SFabiano Rosas return true; 2249f0984d40SFabiano Rosas } 2250f0984d40SFabiano Rosas 2251f0984d40SFabiano Rosas TRANS_FEAT(EXT, aa64_sve, do_EXT, a->rd, a->rn, a->rm, a->imm) 2252f0984d40SFabiano Rosas TRANS_FEAT(EXT_sve2, aa64_sve2, do_EXT, a->rd, a->rn, (a->rn + 1) % 32, a->imm) 2253f0984d40SFabiano Rosas 2254f0984d40SFabiano Rosas /* 2255f0984d40SFabiano Rosas *** SVE Permute - Unpredicated Group 2256f0984d40SFabiano Rosas */ 2257f0984d40SFabiano Rosas 2258f0984d40SFabiano Rosas static bool trans_DUP_s(DisasContext *s, arg_DUP_s *a) 2259f0984d40SFabiano Rosas { 2260f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2261f0984d40SFabiano Rosas return false; 2262f0984d40SFabiano Rosas } 2263f0984d40SFabiano Rosas if (sve_access_check(s)) { 2264f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2265f0984d40SFabiano Rosas tcg_gen_gvec_dup_i64(a->esz, vec_full_reg_offset(s, a->rd), 2266f0984d40SFabiano Rosas vsz, vsz, cpu_reg_sp(s, a->rn)); 2267f0984d40SFabiano Rosas } 2268f0984d40SFabiano Rosas return true; 2269f0984d40SFabiano Rosas } 2270f0984d40SFabiano Rosas 2271f0984d40SFabiano Rosas static bool trans_DUP_x(DisasContext *s, arg_DUP_x *a) 2272f0984d40SFabiano Rosas { 2273f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2274f0984d40SFabiano Rosas return false; 2275f0984d40SFabiano Rosas } 2276f0984d40SFabiano Rosas if ((a->imm & 0x1f) == 0) { 2277f0984d40SFabiano Rosas return false; 2278f0984d40SFabiano Rosas } 2279f0984d40SFabiano Rosas if (sve_access_check(s)) { 2280f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2281f0984d40SFabiano Rosas unsigned dofs = vec_full_reg_offset(s, a->rd); 2282f0984d40SFabiano Rosas unsigned esz, index; 2283f0984d40SFabiano Rosas 2284f0984d40SFabiano Rosas esz = ctz32(a->imm); 2285f0984d40SFabiano Rosas index = a->imm >> (esz + 1); 2286f0984d40SFabiano Rosas 2287f0984d40SFabiano Rosas if ((index << esz) < vsz) { 2288f0984d40SFabiano Rosas unsigned nofs = vec_reg_offset(s, a->rn, index, esz); 2289f0984d40SFabiano Rosas tcg_gen_gvec_dup_mem(esz, dofs, nofs, vsz, vsz); 2290f0984d40SFabiano Rosas } else { 2291f0984d40SFabiano Rosas /* 2292f0984d40SFabiano Rosas * While dup_mem handles 128-bit elements, dup_imm does not. 2293f0984d40SFabiano Rosas * Thankfully element size doesn't matter for splatting zero. 2294f0984d40SFabiano Rosas */ 2295f0984d40SFabiano Rosas tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0); 2296f0984d40SFabiano Rosas } 2297f0984d40SFabiano Rosas } 2298f0984d40SFabiano Rosas return true; 2299f0984d40SFabiano Rosas } 2300f0984d40SFabiano Rosas 2301f0984d40SFabiano Rosas static void do_insr_i64(DisasContext *s, arg_rrr_esz *a, TCGv_i64 val) 2302f0984d40SFabiano Rosas { 2303f0984d40SFabiano Rosas typedef void gen_insr(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i32); 2304f0984d40SFabiano Rosas static gen_insr * const fns[4] = { 2305f0984d40SFabiano Rosas gen_helper_sve_insr_b, gen_helper_sve_insr_h, 2306f0984d40SFabiano Rosas gen_helper_sve_insr_s, gen_helper_sve_insr_d, 2307f0984d40SFabiano Rosas }; 2308f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2309f0984d40SFabiano Rosas TCGv_i32 desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 2310f0984d40SFabiano Rosas TCGv_ptr t_zd = tcg_temp_new_ptr(); 2311f0984d40SFabiano Rosas TCGv_ptr t_zn = tcg_temp_new_ptr(); 2312f0984d40SFabiano Rosas 2313*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zd, tcg_env, vec_full_reg_offset(s, a->rd)); 2314*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn)); 2315f0984d40SFabiano Rosas 2316f0984d40SFabiano Rosas fns[a->esz](t_zd, t_zn, val, desc); 2317f0984d40SFabiano Rosas } 2318f0984d40SFabiano Rosas 2319f0984d40SFabiano Rosas static bool trans_INSR_f(DisasContext *s, arg_rrr_esz *a) 2320f0984d40SFabiano Rosas { 2321f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2322f0984d40SFabiano Rosas return false; 2323f0984d40SFabiano Rosas } 2324f0984d40SFabiano Rosas if (sve_access_check(s)) { 2325f0984d40SFabiano Rosas TCGv_i64 t = tcg_temp_new_i64(); 2326*ad75a51eSRichard Henderson tcg_gen_ld_i64(t, tcg_env, vec_reg_offset(s, a->rm, 0, MO_64)); 2327f0984d40SFabiano Rosas do_insr_i64(s, a, t); 2328f0984d40SFabiano Rosas } 2329f0984d40SFabiano Rosas return true; 2330f0984d40SFabiano Rosas } 2331f0984d40SFabiano Rosas 2332f0984d40SFabiano Rosas static bool trans_INSR_r(DisasContext *s, arg_rrr_esz *a) 2333f0984d40SFabiano Rosas { 2334f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2335f0984d40SFabiano Rosas return false; 2336f0984d40SFabiano Rosas } 2337f0984d40SFabiano Rosas if (sve_access_check(s)) { 2338f0984d40SFabiano Rosas do_insr_i64(s, a, cpu_reg(s, a->rm)); 2339f0984d40SFabiano Rosas } 2340f0984d40SFabiano Rosas return true; 2341f0984d40SFabiano Rosas } 2342f0984d40SFabiano Rosas 2343f0984d40SFabiano Rosas static gen_helper_gvec_2 * const rev_fns[4] = { 2344f0984d40SFabiano Rosas gen_helper_sve_rev_b, gen_helper_sve_rev_h, 2345f0984d40SFabiano Rosas gen_helper_sve_rev_s, gen_helper_sve_rev_d 2346f0984d40SFabiano Rosas }; 2347f0984d40SFabiano Rosas TRANS_FEAT(REV_v, aa64_sve, gen_gvec_ool_zz, rev_fns[a->esz], a->rd, a->rn, 0) 2348f0984d40SFabiano Rosas 2349f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sve_tbl_fns[4] = { 2350f0984d40SFabiano Rosas gen_helper_sve_tbl_b, gen_helper_sve_tbl_h, 2351f0984d40SFabiano Rosas gen_helper_sve_tbl_s, gen_helper_sve_tbl_d 2352f0984d40SFabiano Rosas }; 2353f0984d40SFabiano Rosas TRANS_FEAT(TBL, aa64_sve, gen_gvec_ool_arg_zzz, sve_tbl_fns[a->esz], a, 0) 2354f0984d40SFabiano Rosas 2355f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sve2_tbl_fns[4] = { 2356f0984d40SFabiano Rosas gen_helper_sve2_tbl_b, gen_helper_sve2_tbl_h, 2357f0984d40SFabiano Rosas gen_helper_sve2_tbl_s, gen_helper_sve2_tbl_d 2358f0984d40SFabiano Rosas }; 2359f0984d40SFabiano Rosas TRANS_FEAT(TBL_sve2, aa64_sve2, gen_gvec_ool_zzzz, sve2_tbl_fns[a->esz], 2360f0984d40SFabiano Rosas a->rd, a->rn, (a->rn + 1) % 32, a->rm, 0) 2361f0984d40SFabiano Rosas 2362f0984d40SFabiano Rosas static gen_helper_gvec_3 * const tbx_fns[4] = { 2363f0984d40SFabiano Rosas gen_helper_sve2_tbx_b, gen_helper_sve2_tbx_h, 2364f0984d40SFabiano Rosas gen_helper_sve2_tbx_s, gen_helper_sve2_tbx_d 2365f0984d40SFabiano Rosas }; 2366f0984d40SFabiano Rosas TRANS_FEAT(TBX, aa64_sve2, gen_gvec_ool_arg_zzz, tbx_fns[a->esz], a, 0) 2367f0984d40SFabiano Rosas 2368f0984d40SFabiano Rosas static bool trans_UNPK(DisasContext *s, arg_UNPK *a) 2369f0984d40SFabiano Rosas { 2370f0984d40SFabiano Rosas static gen_helper_gvec_2 * const fns[4][2] = { 2371f0984d40SFabiano Rosas { NULL, NULL }, 2372f0984d40SFabiano Rosas { gen_helper_sve_sunpk_h, gen_helper_sve_uunpk_h }, 2373f0984d40SFabiano Rosas { gen_helper_sve_sunpk_s, gen_helper_sve_uunpk_s }, 2374f0984d40SFabiano Rosas { gen_helper_sve_sunpk_d, gen_helper_sve_uunpk_d }, 2375f0984d40SFabiano Rosas }; 2376f0984d40SFabiano Rosas 2377f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 2378f0984d40SFabiano Rosas return false; 2379f0984d40SFabiano Rosas } 2380f0984d40SFabiano Rosas if (sve_access_check(s)) { 2381f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2382f0984d40SFabiano Rosas tcg_gen_gvec_2_ool(vec_full_reg_offset(s, a->rd), 2383f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn) 2384f0984d40SFabiano Rosas + (a->h ? vsz / 2 : 0), 2385f0984d40SFabiano Rosas vsz, vsz, 0, fns[a->esz][a->u]); 2386f0984d40SFabiano Rosas } 2387f0984d40SFabiano Rosas return true; 2388f0984d40SFabiano Rosas } 2389f0984d40SFabiano Rosas 2390f0984d40SFabiano Rosas /* 2391f0984d40SFabiano Rosas *** SVE Permute - Predicates Group 2392f0984d40SFabiano Rosas */ 2393f0984d40SFabiano Rosas 2394f0984d40SFabiano Rosas static bool do_perm_pred3(DisasContext *s, arg_rrr_esz *a, bool high_odd, 2395f0984d40SFabiano Rosas gen_helper_gvec_3 *fn) 2396f0984d40SFabiano Rosas { 2397f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2398f0984d40SFabiano Rosas return true; 2399f0984d40SFabiano Rosas } 2400f0984d40SFabiano Rosas 2401f0984d40SFabiano Rosas unsigned vsz = pred_full_reg_size(s); 2402f0984d40SFabiano Rosas 2403f0984d40SFabiano Rosas TCGv_ptr t_d = tcg_temp_new_ptr(); 2404f0984d40SFabiano Rosas TCGv_ptr t_n = tcg_temp_new_ptr(); 2405f0984d40SFabiano Rosas TCGv_ptr t_m = tcg_temp_new_ptr(); 2406f0984d40SFabiano Rosas uint32_t desc = 0; 2407f0984d40SFabiano Rosas 2408f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz); 2409f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz); 2410f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, DATA, high_odd); 2411f0984d40SFabiano Rosas 2412*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_d, tcg_env, pred_full_reg_offset(s, a->rd)); 2413*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_n, tcg_env, pred_full_reg_offset(s, a->rn)); 2414*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_m, tcg_env, pred_full_reg_offset(s, a->rm)); 2415f0984d40SFabiano Rosas 2416f0984d40SFabiano Rosas fn(t_d, t_n, t_m, tcg_constant_i32(desc)); 2417f0984d40SFabiano Rosas return true; 2418f0984d40SFabiano Rosas } 2419f0984d40SFabiano Rosas 2420f0984d40SFabiano Rosas static bool do_perm_pred2(DisasContext *s, arg_rr_esz *a, bool high_odd, 2421f0984d40SFabiano Rosas gen_helper_gvec_2 *fn) 2422f0984d40SFabiano Rosas { 2423f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2424f0984d40SFabiano Rosas return true; 2425f0984d40SFabiano Rosas } 2426f0984d40SFabiano Rosas 2427f0984d40SFabiano Rosas unsigned vsz = pred_full_reg_size(s); 2428f0984d40SFabiano Rosas TCGv_ptr t_d = tcg_temp_new_ptr(); 2429f0984d40SFabiano Rosas TCGv_ptr t_n = tcg_temp_new_ptr(); 2430f0984d40SFabiano Rosas uint32_t desc = 0; 2431f0984d40SFabiano Rosas 2432*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_d, tcg_env, pred_full_reg_offset(s, a->rd)); 2433*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_n, tcg_env, pred_full_reg_offset(s, a->rn)); 2434f0984d40SFabiano Rosas 2435f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz); 2436f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz); 2437f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, DATA, high_odd); 2438f0984d40SFabiano Rosas 2439f0984d40SFabiano Rosas fn(t_d, t_n, tcg_constant_i32(desc)); 2440f0984d40SFabiano Rosas return true; 2441f0984d40SFabiano Rosas } 2442f0984d40SFabiano Rosas 2443f0984d40SFabiano Rosas TRANS_FEAT(ZIP1_p, aa64_sve, do_perm_pred3, a, 0, gen_helper_sve_zip_p) 2444f0984d40SFabiano Rosas TRANS_FEAT(ZIP2_p, aa64_sve, do_perm_pred3, a, 1, gen_helper_sve_zip_p) 2445f0984d40SFabiano Rosas TRANS_FEAT(UZP1_p, aa64_sve, do_perm_pred3, a, 0, gen_helper_sve_uzp_p) 2446f0984d40SFabiano Rosas TRANS_FEAT(UZP2_p, aa64_sve, do_perm_pred3, a, 1, gen_helper_sve_uzp_p) 2447f0984d40SFabiano Rosas TRANS_FEAT(TRN1_p, aa64_sve, do_perm_pred3, a, 0, gen_helper_sve_trn_p) 2448f0984d40SFabiano Rosas TRANS_FEAT(TRN2_p, aa64_sve, do_perm_pred3, a, 1, gen_helper_sve_trn_p) 2449f0984d40SFabiano Rosas 2450f0984d40SFabiano Rosas TRANS_FEAT(REV_p, aa64_sve, do_perm_pred2, a, 0, gen_helper_sve_rev_p) 2451f0984d40SFabiano Rosas TRANS_FEAT(PUNPKLO, aa64_sve, do_perm_pred2, a, 0, gen_helper_sve_punpk_p) 2452f0984d40SFabiano Rosas TRANS_FEAT(PUNPKHI, aa64_sve, do_perm_pred2, a, 1, gen_helper_sve_punpk_p) 2453f0984d40SFabiano Rosas 2454f0984d40SFabiano Rosas /* 2455f0984d40SFabiano Rosas *** SVE Permute - Interleaving Group 2456f0984d40SFabiano Rosas */ 2457f0984d40SFabiano Rosas 2458f0984d40SFabiano Rosas static gen_helper_gvec_3 * const zip_fns[4] = { 2459f0984d40SFabiano Rosas gen_helper_sve_zip_b, gen_helper_sve_zip_h, 2460f0984d40SFabiano Rosas gen_helper_sve_zip_s, gen_helper_sve_zip_d, 2461f0984d40SFabiano Rosas }; 2462f0984d40SFabiano Rosas TRANS_FEAT(ZIP1_z, aa64_sve, gen_gvec_ool_arg_zzz, 2463f0984d40SFabiano Rosas zip_fns[a->esz], a, 0) 2464f0984d40SFabiano Rosas TRANS_FEAT(ZIP2_z, aa64_sve, gen_gvec_ool_arg_zzz, 2465f0984d40SFabiano Rosas zip_fns[a->esz], a, vec_full_reg_size(s) / 2) 2466f0984d40SFabiano Rosas 2467f0984d40SFabiano Rosas TRANS_FEAT(ZIP1_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz, 2468f0984d40SFabiano Rosas gen_helper_sve2_zip_q, a, 0) 2469f0984d40SFabiano Rosas TRANS_FEAT(ZIP2_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz, 2470f0984d40SFabiano Rosas gen_helper_sve2_zip_q, a, 2471f0984d40SFabiano Rosas QEMU_ALIGN_DOWN(vec_full_reg_size(s), 32) / 2) 2472f0984d40SFabiano Rosas 2473f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uzp_fns[4] = { 2474f0984d40SFabiano Rosas gen_helper_sve_uzp_b, gen_helper_sve_uzp_h, 2475f0984d40SFabiano Rosas gen_helper_sve_uzp_s, gen_helper_sve_uzp_d, 2476f0984d40SFabiano Rosas }; 2477f0984d40SFabiano Rosas 2478f0984d40SFabiano Rosas TRANS_FEAT(UZP1_z, aa64_sve, gen_gvec_ool_arg_zzz, 2479f0984d40SFabiano Rosas uzp_fns[a->esz], a, 0) 2480f0984d40SFabiano Rosas TRANS_FEAT(UZP2_z, aa64_sve, gen_gvec_ool_arg_zzz, 2481f0984d40SFabiano Rosas uzp_fns[a->esz], a, 1 << a->esz) 2482f0984d40SFabiano Rosas 2483f0984d40SFabiano Rosas TRANS_FEAT(UZP1_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz, 2484f0984d40SFabiano Rosas gen_helper_sve2_uzp_q, a, 0) 2485f0984d40SFabiano Rosas TRANS_FEAT(UZP2_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz, 2486f0984d40SFabiano Rosas gen_helper_sve2_uzp_q, a, 16) 2487f0984d40SFabiano Rosas 2488f0984d40SFabiano Rosas static gen_helper_gvec_3 * const trn_fns[4] = { 2489f0984d40SFabiano Rosas gen_helper_sve_trn_b, gen_helper_sve_trn_h, 2490f0984d40SFabiano Rosas gen_helper_sve_trn_s, gen_helper_sve_trn_d, 2491f0984d40SFabiano Rosas }; 2492f0984d40SFabiano Rosas 2493f0984d40SFabiano Rosas TRANS_FEAT(TRN1_z, aa64_sve, gen_gvec_ool_arg_zzz, 2494f0984d40SFabiano Rosas trn_fns[a->esz], a, 0) 2495f0984d40SFabiano Rosas TRANS_FEAT(TRN2_z, aa64_sve, gen_gvec_ool_arg_zzz, 2496f0984d40SFabiano Rosas trn_fns[a->esz], a, 1 << a->esz) 2497f0984d40SFabiano Rosas 2498f0984d40SFabiano Rosas TRANS_FEAT(TRN1_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz, 2499f0984d40SFabiano Rosas gen_helper_sve2_trn_q, a, 0) 2500f0984d40SFabiano Rosas TRANS_FEAT(TRN2_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz, 2501f0984d40SFabiano Rosas gen_helper_sve2_trn_q, a, 16) 2502f0984d40SFabiano Rosas 2503f0984d40SFabiano Rosas /* 2504f0984d40SFabiano Rosas *** SVE Permute Vector - Predicated Group 2505f0984d40SFabiano Rosas */ 2506f0984d40SFabiano Rosas 2507f0984d40SFabiano Rosas static gen_helper_gvec_3 * const compact_fns[4] = { 2508f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve_compact_s, gen_helper_sve_compact_d 2509f0984d40SFabiano Rosas }; 2510f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(COMPACT, aa64_sve, gen_gvec_ool_arg_zpz, 2511f0984d40SFabiano Rosas compact_fns[a->esz], a, 0) 2512f0984d40SFabiano Rosas 2513f0984d40SFabiano Rosas /* Call the helper that computes the ARM LastActiveElement pseudocode 2514f0984d40SFabiano Rosas * function, scaled by the element size. This includes the not found 2515f0984d40SFabiano Rosas * indication; e.g. not found for esz=3 is -8. 2516f0984d40SFabiano Rosas */ 2517f0984d40SFabiano Rosas static void find_last_active(DisasContext *s, TCGv_i32 ret, int esz, int pg) 2518f0984d40SFabiano Rosas { 2519f0984d40SFabiano Rosas /* Predicate sizes may be smaller and cannot use simd_desc. We cannot 2520f0984d40SFabiano Rosas * round up, as we do elsewhere, because we need the exact size. 2521f0984d40SFabiano Rosas */ 2522f0984d40SFabiano Rosas TCGv_ptr t_p = tcg_temp_new_ptr(); 2523f0984d40SFabiano Rosas unsigned desc = 0; 2524f0984d40SFabiano Rosas 2525f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pred_full_reg_size(s)); 2526f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, esz); 2527f0984d40SFabiano Rosas 2528*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_p, tcg_env, pred_full_reg_offset(s, pg)); 2529f0984d40SFabiano Rosas 2530f0984d40SFabiano Rosas gen_helper_sve_last_active_element(ret, t_p, tcg_constant_i32(desc)); 2531f0984d40SFabiano Rosas } 2532f0984d40SFabiano Rosas 2533f0984d40SFabiano Rosas /* Increment LAST to the offset of the next element in the vector, 2534f0984d40SFabiano Rosas * wrapping around to 0. 2535f0984d40SFabiano Rosas */ 2536f0984d40SFabiano Rosas static void incr_last_active(DisasContext *s, TCGv_i32 last, int esz) 2537f0984d40SFabiano Rosas { 2538f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2539f0984d40SFabiano Rosas 2540f0984d40SFabiano Rosas tcg_gen_addi_i32(last, last, 1 << esz); 2541f0984d40SFabiano Rosas if (is_power_of_2(vsz)) { 2542f0984d40SFabiano Rosas tcg_gen_andi_i32(last, last, vsz - 1); 2543f0984d40SFabiano Rosas } else { 2544f0984d40SFabiano Rosas TCGv_i32 max = tcg_constant_i32(vsz); 2545f0984d40SFabiano Rosas TCGv_i32 zero = tcg_constant_i32(0); 2546f0984d40SFabiano Rosas tcg_gen_movcond_i32(TCG_COND_GEU, last, last, max, zero, last); 2547f0984d40SFabiano Rosas } 2548f0984d40SFabiano Rosas } 2549f0984d40SFabiano Rosas 2550f0984d40SFabiano Rosas /* If LAST < 0, set LAST to the offset of the last element in the vector. */ 2551f0984d40SFabiano Rosas static void wrap_last_active(DisasContext *s, TCGv_i32 last, int esz) 2552f0984d40SFabiano Rosas { 2553f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 2554f0984d40SFabiano Rosas 2555f0984d40SFabiano Rosas if (is_power_of_2(vsz)) { 2556f0984d40SFabiano Rosas tcg_gen_andi_i32(last, last, vsz - 1); 2557f0984d40SFabiano Rosas } else { 2558f0984d40SFabiano Rosas TCGv_i32 max = tcg_constant_i32(vsz - (1 << esz)); 2559f0984d40SFabiano Rosas TCGv_i32 zero = tcg_constant_i32(0); 2560f0984d40SFabiano Rosas tcg_gen_movcond_i32(TCG_COND_LT, last, last, zero, max, last); 2561f0984d40SFabiano Rosas } 2562f0984d40SFabiano Rosas } 2563f0984d40SFabiano Rosas 2564f0984d40SFabiano Rosas /* Load an unsigned element of ESZ from BASE+OFS. */ 2565f0984d40SFabiano Rosas static TCGv_i64 load_esz(TCGv_ptr base, int ofs, int esz) 2566f0984d40SFabiano Rosas { 2567f0984d40SFabiano Rosas TCGv_i64 r = tcg_temp_new_i64(); 2568f0984d40SFabiano Rosas 2569f0984d40SFabiano Rosas switch (esz) { 2570f0984d40SFabiano Rosas case 0: 2571f0984d40SFabiano Rosas tcg_gen_ld8u_i64(r, base, ofs); 2572f0984d40SFabiano Rosas break; 2573f0984d40SFabiano Rosas case 1: 2574f0984d40SFabiano Rosas tcg_gen_ld16u_i64(r, base, ofs); 2575f0984d40SFabiano Rosas break; 2576f0984d40SFabiano Rosas case 2: 2577f0984d40SFabiano Rosas tcg_gen_ld32u_i64(r, base, ofs); 2578f0984d40SFabiano Rosas break; 2579f0984d40SFabiano Rosas case 3: 2580f0984d40SFabiano Rosas tcg_gen_ld_i64(r, base, ofs); 2581f0984d40SFabiano Rosas break; 2582f0984d40SFabiano Rosas default: 2583f0984d40SFabiano Rosas g_assert_not_reached(); 2584f0984d40SFabiano Rosas } 2585f0984d40SFabiano Rosas return r; 2586f0984d40SFabiano Rosas } 2587f0984d40SFabiano Rosas 2588f0984d40SFabiano Rosas /* Load an unsigned element of ESZ from RM[LAST]. */ 2589f0984d40SFabiano Rosas static TCGv_i64 load_last_active(DisasContext *s, TCGv_i32 last, 2590f0984d40SFabiano Rosas int rm, int esz) 2591f0984d40SFabiano Rosas { 2592f0984d40SFabiano Rosas TCGv_ptr p = tcg_temp_new_ptr(); 2593f0984d40SFabiano Rosas 2594f0984d40SFabiano Rosas /* Convert offset into vector into offset into ENV. 2595f0984d40SFabiano Rosas * The final adjustment for the vector register base 2596f0984d40SFabiano Rosas * is added via constant offset to the load. 2597f0984d40SFabiano Rosas */ 2598f0984d40SFabiano Rosas #if HOST_BIG_ENDIAN 2599f0984d40SFabiano Rosas /* Adjust for element ordering. See vec_reg_offset. */ 2600f0984d40SFabiano Rosas if (esz < 3) { 2601f0984d40SFabiano Rosas tcg_gen_xori_i32(last, last, 8 - (1 << esz)); 2602f0984d40SFabiano Rosas } 2603f0984d40SFabiano Rosas #endif 2604f0984d40SFabiano Rosas tcg_gen_ext_i32_ptr(p, last); 2605*ad75a51eSRichard Henderson tcg_gen_add_ptr(p, p, tcg_env); 2606f0984d40SFabiano Rosas 2607bd46e45aSRichard Henderson return load_esz(p, vec_full_reg_offset(s, rm), esz); 2608f0984d40SFabiano Rosas } 2609f0984d40SFabiano Rosas 2610f0984d40SFabiano Rosas /* Compute CLAST for a Zreg. */ 2611f0984d40SFabiano Rosas static bool do_clast_vector(DisasContext *s, arg_rprr_esz *a, bool before) 2612f0984d40SFabiano Rosas { 2613f0984d40SFabiano Rosas TCGv_i32 last; 2614f0984d40SFabiano Rosas TCGLabel *over; 2615f0984d40SFabiano Rosas TCGv_i64 ele; 2616f0984d40SFabiano Rosas unsigned vsz, esz = a->esz; 2617f0984d40SFabiano Rosas 2618f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2619f0984d40SFabiano Rosas return true; 2620f0984d40SFabiano Rosas } 2621f0984d40SFabiano Rosas 2622d4aa49acSRichard Henderson last = tcg_temp_new_i32(); 2623f0984d40SFabiano Rosas over = gen_new_label(); 2624f0984d40SFabiano Rosas 2625f0984d40SFabiano Rosas find_last_active(s, last, esz, a->pg); 2626f0984d40SFabiano Rosas 2627f0984d40SFabiano Rosas /* There is of course no movcond for a 2048-bit vector, 2628f0984d40SFabiano Rosas * so we must branch over the actual store. 2629f0984d40SFabiano Rosas */ 2630f0984d40SFabiano Rosas tcg_gen_brcondi_i32(TCG_COND_LT, last, 0, over); 2631f0984d40SFabiano Rosas 2632f0984d40SFabiano Rosas if (!before) { 2633f0984d40SFabiano Rosas incr_last_active(s, last, esz); 2634f0984d40SFabiano Rosas } 2635f0984d40SFabiano Rosas 2636f0984d40SFabiano Rosas ele = load_last_active(s, last, a->rm, esz); 2637f0984d40SFabiano Rosas 2638f0984d40SFabiano Rosas vsz = vec_full_reg_size(s); 2639f0984d40SFabiano Rosas tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd), vsz, vsz, ele); 2640f0984d40SFabiano Rosas 2641f0984d40SFabiano Rosas /* If this insn used MOVPRFX, we may need a second move. */ 2642f0984d40SFabiano Rosas if (a->rd != a->rn) { 2643f0984d40SFabiano Rosas TCGLabel *done = gen_new_label(); 2644f0984d40SFabiano Rosas tcg_gen_br(done); 2645f0984d40SFabiano Rosas 2646f0984d40SFabiano Rosas gen_set_label(over); 2647f0984d40SFabiano Rosas do_mov_z(s, a->rd, a->rn); 2648f0984d40SFabiano Rosas 2649f0984d40SFabiano Rosas gen_set_label(done); 2650f0984d40SFabiano Rosas } else { 2651f0984d40SFabiano Rosas gen_set_label(over); 2652f0984d40SFabiano Rosas } 2653f0984d40SFabiano Rosas return true; 2654f0984d40SFabiano Rosas } 2655f0984d40SFabiano Rosas 2656f0984d40SFabiano Rosas TRANS_FEAT(CLASTA_z, aa64_sve, do_clast_vector, a, false) 2657f0984d40SFabiano Rosas TRANS_FEAT(CLASTB_z, aa64_sve, do_clast_vector, a, true) 2658f0984d40SFabiano Rosas 2659f0984d40SFabiano Rosas /* Compute CLAST for a scalar. */ 2660f0984d40SFabiano Rosas static void do_clast_scalar(DisasContext *s, int esz, int pg, int rm, 2661f0984d40SFabiano Rosas bool before, TCGv_i64 reg_val) 2662f0984d40SFabiano Rosas { 2663f0984d40SFabiano Rosas TCGv_i32 last = tcg_temp_new_i32(); 2664f0984d40SFabiano Rosas TCGv_i64 ele, cmp; 2665f0984d40SFabiano Rosas 2666f0984d40SFabiano Rosas find_last_active(s, last, esz, pg); 2667f0984d40SFabiano Rosas 2668f0984d40SFabiano Rosas /* Extend the original value of last prior to incrementing. */ 2669f0984d40SFabiano Rosas cmp = tcg_temp_new_i64(); 2670f0984d40SFabiano Rosas tcg_gen_ext_i32_i64(cmp, last); 2671f0984d40SFabiano Rosas 2672f0984d40SFabiano Rosas if (!before) { 2673f0984d40SFabiano Rosas incr_last_active(s, last, esz); 2674f0984d40SFabiano Rosas } 2675f0984d40SFabiano Rosas 2676f0984d40SFabiano Rosas /* The conceit here is that while last < 0 indicates not found, after 2677*ad75a51eSRichard Henderson * adjusting for tcg_env->vfp.zregs[rm], it is still a valid address 2678f0984d40SFabiano Rosas * from which we can load garbage. We then discard the garbage with 2679f0984d40SFabiano Rosas * a conditional move. 2680f0984d40SFabiano Rosas */ 2681f0984d40SFabiano Rosas ele = load_last_active(s, last, rm, esz); 2682f0984d40SFabiano Rosas 2683f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_GE, reg_val, cmp, tcg_constant_i64(0), 2684f0984d40SFabiano Rosas ele, reg_val); 2685f0984d40SFabiano Rosas } 2686f0984d40SFabiano Rosas 2687f0984d40SFabiano Rosas /* Compute CLAST for a Vreg. */ 2688f0984d40SFabiano Rosas static bool do_clast_fp(DisasContext *s, arg_rpr_esz *a, bool before) 2689f0984d40SFabiano Rosas { 2690f0984d40SFabiano Rosas if (sve_access_check(s)) { 2691f0984d40SFabiano Rosas int esz = a->esz; 2692f0984d40SFabiano Rosas int ofs = vec_reg_offset(s, a->rd, 0, esz); 2693*ad75a51eSRichard Henderson TCGv_i64 reg = load_esz(tcg_env, ofs, esz); 2694f0984d40SFabiano Rosas 2695f0984d40SFabiano Rosas do_clast_scalar(s, esz, a->pg, a->rn, before, reg); 2696f0984d40SFabiano Rosas write_fp_dreg(s, a->rd, reg); 2697f0984d40SFabiano Rosas } 2698f0984d40SFabiano Rosas return true; 2699f0984d40SFabiano Rosas } 2700f0984d40SFabiano Rosas 2701f0984d40SFabiano Rosas TRANS_FEAT(CLASTA_v, aa64_sve, do_clast_fp, a, false) 2702f0984d40SFabiano Rosas TRANS_FEAT(CLASTB_v, aa64_sve, do_clast_fp, a, true) 2703f0984d40SFabiano Rosas 2704f0984d40SFabiano Rosas /* Compute CLAST for a Xreg. */ 2705f0984d40SFabiano Rosas static bool do_clast_general(DisasContext *s, arg_rpr_esz *a, bool before) 2706f0984d40SFabiano Rosas { 2707f0984d40SFabiano Rosas TCGv_i64 reg; 2708f0984d40SFabiano Rosas 2709f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2710f0984d40SFabiano Rosas return true; 2711f0984d40SFabiano Rosas } 2712f0984d40SFabiano Rosas 2713f0984d40SFabiano Rosas reg = cpu_reg(s, a->rd); 2714f0984d40SFabiano Rosas switch (a->esz) { 2715f0984d40SFabiano Rosas case 0: 2716f0984d40SFabiano Rosas tcg_gen_ext8u_i64(reg, reg); 2717f0984d40SFabiano Rosas break; 2718f0984d40SFabiano Rosas case 1: 2719f0984d40SFabiano Rosas tcg_gen_ext16u_i64(reg, reg); 2720f0984d40SFabiano Rosas break; 2721f0984d40SFabiano Rosas case 2: 2722f0984d40SFabiano Rosas tcg_gen_ext32u_i64(reg, reg); 2723f0984d40SFabiano Rosas break; 2724f0984d40SFabiano Rosas case 3: 2725f0984d40SFabiano Rosas break; 2726f0984d40SFabiano Rosas default: 2727f0984d40SFabiano Rosas g_assert_not_reached(); 2728f0984d40SFabiano Rosas } 2729f0984d40SFabiano Rosas 2730f0984d40SFabiano Rosas do_clast_scalar(s, a->esz, a->pg, a->rn, before, reg); 2731f0984d40SFabiano Rosas return true; 2732f0984d40SFabiano Rosas } 2733f0984d40SFabiano Rosas 2734f0984d40SFabiano Rosas TRANS_FEAT(CLASTA_r, aa64_sve, do_clast_general, a, false) 2735f0984d40SFabiano Rosas TRANS_FEAT(CLASTB_r, aa64_sve, do_clast_general, a, true) 2736f0984d40SFabiano Rosas 2737f0984d40SFabiano Rosas /* Compute LAST for a scalar. */ 2738f0984d40SFabiano Rosas static TCGv_i64 do_last_scalar(DisasContext *s, int esz, 2739f0984d40SFabiano Rosas int pg, int rm, bool before) 2740f0984d40SFabiano Rosas { 2741f0984d40SFabiano Rosas TCGv_i32 last = tcg_temp_new_i32(); 2742f0984d40SFabiano Rosas 2743f0984d40SFabiano Rosas find_last_active(s, last, esz, pg); 2744f0984d40SFabiano Rosas if (before) { 2745f0984d40SFabiano Rosas wrap_last_active(s, last, esz); 2746f0984d40SFabiano Rosas } else { 2747f0984d40SFabiano Rosas incr_last_active(s, last, esz); 2748f0984d40SFabiano Rosas } 2749f0984d40SFabiano Rosas 2750bd46e45aSRichard Henderson return load_last_active(s, last, rm, esz); 2751f0984d40SFabiano Rosas } 2752f0984d40SFabiano Rosas 2753f0984d40SFabiano Rosas /* Compute LAST for a Vreg. */ 2754f0984d40SFabiano Rosas static bool do_last_fp(DisasContext *s, arg_rpr_esz *a, bool before) 2755f0984d40SFabiano Rosas { 2756f0984d40SFabiano Rosas if (sve_access_check(s)) { 2757f0984d40SFabiano Rosas TCGv_i64 val = do_last_scalar(s, a->esz, a->pg, a->rn, before); 2758f0984d40SFabiano Rosas write_fp_dreg(s, a->rd, val); 2759f0984d40SFabiano Rosas } 2760f0984d40SFabiano Rosas return true; 2761f0984d40SFabiano Rosas } 2762f0984d40SFabiano Rosas 2763f0984d40SFabiano Rosas TRANS_FEAT(LASTA_v, aa64_sve, do_last_fp, a, false) 2764f0984d40SFabiano Rosas TRANS_FEAT(LASTB_v, aa64_sve, do_last_fp, a, true) 2765f0984d40SFabiano Rosas 2766f0984d40SFabiano Rosas /* Compute LAST for a Xreg. */ 2767f0984d40SFabiano Rosas static bool do_last_general(DisasContext *s, arg_rpr_esz *a, bool before) 2768f0984d40SFabiano Rosas { 2769f0984d40SFabiano Rosas if (sve_access_check(s)) { 2770f0984d40SFabiano Rosas TCGv_i64 val = do_last_scalar(s, a->esz, a->pg, a->rn, before); 2771f0984d40SFabiano Rosas tcg_gen_mov_i64(cpu_reg(s, a->rd), val); 2772f0984d40SFabiano Rosas } 2773f0984d40SFabiano Rosas return true; 2774f0984d40SFabiano Rosas } 2775f0984d40SFabiano Rosas 2776f0984d40SFabiano Rosas TRANS_FEAT(LASTA_r, aa64_sve, do_last_general, a, false) 2777f0984d40SFabiano Rosas TRANS_FEAT(LASTB_r, aa64_sve, do_last_general, a, true) 2778f0984d40SFabiano Rosas 2779f0984d40SFabiano Rosas static bool trans_CPY_m_r(DisasContext *s, arg_rpr_esz *a) 2780f0984d40SFabiano Rosas { 2781f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2782f0984d40SFabiano Rosas return false; 2783f0984d40SFabiano Rosas } 2784f0984d40SFabiano Rosas if (sve_access_check(s)) { 2785f0984d40SFabiano Rosas do_cpy_m(s, a->esz, a->rd, a->rd, a->pg, cpu_reg_sp(s, a->rn)); 2786f0984d40SFabiano Rosas } 2787f0984d40SFabiano Rosas return true; 2788f0984d40SFabiano Rosas } 2789f0984d40SFabiano Rosas 2790f0984d40SFabiano Rosas static bool trans_CPY_m_v(DisasContext *s, arg_rpr_esz *a) 2791f0984d40SFabiano Rosas { 2792f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 2793f0984d40SFabiano Rosas return false; 2794f0984d40SFabiano Rosas } 2795f0984d40SFabiano Rosas if (sve_access_check(s)) { 2796f0984d40SFabiano Rosas int ofs = vec_reg_offset(s, a->rn, 0, a->esz); 2797*ad75a51eSRichard Henderson TCGv_i64 t = load_esz(tcg_env, ofs, a->esz); 2798f0984d40SFabiano Rosas do_cpy_m(s, a->esz, a->rd, a->rd, a->pg, t); 2799f0984d40SFabiano Rosas } 2800f0984d40SFabiano Rosas return true; 2801f0984d40SFabiano Rosas } 2802f0984d40SFabiano Rosas 2803f0984d40SFabiano Rosas static gen_helper_gvec_3 * const revb_fns[4] = { 2804f0984d40SFabiano Rosas NULL, gen_helper_sve_revb_h, 2805f0984d40SFabiano Rosas gen_helper_sve_revb_s, gen_helper_sve_revb_d, 2806f0984d40SFabiano Rosas }; 2807f0984d40SFabiano Rosas TRANS_FEAT(REVB, aa64_sve, gen_gvec_ool_arg_zpz, revb_fns[a->esz], a, 0) 2808f0984d40SFabiano Rosas 2809f0984d40SFabiano Rosas static gen_helper_gvec_3 * const revh_fns[4] = { 2810f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve_revh_s, gen_helper_sve_revh_d, 2811f0984d40SFabiano Rosas }; 2812f0984d40SFabiano Rosas TRANS_FEAT(REVH, aa64_sve, gen_gvec_ool_arg_zpz, revh_fns[a->esz], a, 0) 2813f0984d40SFabiano Rosas 2814f0984d40SFabiano Rosas TRANS_FEAT(REVW, aa64_sve, gen_gvec_ool_arg_zpz, 2815f0984d40SFabiano Rosas a->esz == 3 ? gen_helper_sve_revw_d : NULL, a, 0) 2816f0984d40SFabiano Rosas 2817f0984d40SFabiano Rosas TRANS_FEAT(REVD, aa64_sme, gen_gvec_ool_arg_zpz, gen_helper_sme_revd_q, a, 0) 2818f0984d40SFabiano Rosas 2819f0984d40SFabiano Rosas TRANS_FEAT(SPLICE, aa64_sve, gen_gvec_ool_arg_zpzz, 2820f0984d40SFabiano Rosas gen_helper_sve_splice, a, a->esz) 2821f0984d40SFabiano Rosas 2822f0984d40SFabiano Rosas TRANS_FEAT(SPLICE_sve2, aa64_sve2, gen_gvec_ool_zzzp, gen_helper_sve_splice, 2823f0984d40SFabiano Rosas a->rd, a->rn, (a->rn + 1) % 32, a->pg, a->esz) 2824f0984d40SFabiano Rosas 2825f0984d40SFabiano Rosas /* 2826f0984d40SFabiano Rosas *** SVE Integer Compare - Vectors Group 2827f0984d40SFabiano Rosas */ 2828f0984d40SFabiano Rosas 2829f0984d40SFabiano Rosas static bool do_ppzz_flags(DisasContext *s, arg_rprr_esz *a, 2830f0984d40SFabiano Rosas gen_helper_gvec_flags_4 *gen_fn) 2831f0984d40SFabiano Rosas { 2832f0984d40SFabiano Rosas TCGv_ptr pd, zn, zm, pg; 2833f0984d40SFabiano Rosas unsigned vsz; 2834f0984d40SFabiano Rosas TCGv_i32 t; 2835f0984d40SFabiano Rosas 2836f0984d40SFabiano Rosas if (gen_fn == NULL) { 2837f0984d40SFabiano Rosas return false; 2838f0984d40SFabiano Rosas } 2839f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2840f0984d40SFabiano Rosas return true; 2841f0984d40SFabiano Rosas } 2842f0984d40SFabiano Rosas 2843f0984d40SFabiano Rosas vsz = vec_full_reg_size(s); 2844f0984d40SFabiano Rosas t = tcg_temp_new_i32(); 2845f0984d40SFabiano Rosas pd = tcg_temp_new_ptr(); 2846f0984d40SFabiano Rosas zn = tcg_temp_new_ptr(); 2847f0984d40SFabiano Rosas zm = tcg_temp_new_ptr(); 2848f0984d40SFabiano Rosas pg = tcg_temp_new_ptr(); 2849f0984d40SFabiano Rosas 2850*ad75a51eSRichard Henderson tcg_gen_addi_ptr(pd, tcg_env, pred_full_reg_offset(s, a->rd)); 2851*ad75a51eSRichard Henderson tcg_gen_addi_ptr(zn, tcg_env, vec_full_reg_offset(s, a->rn)); 2852*ad75a51eSRichard Henderson tcg_gen_addi_ptr(zm, tcg_env, vec_full_reg_offset(s, a->rm)); 2853*ad75a51eSRichard Henderson tcg_gen_addi_ptr(pg, tcg_env, pred_full_reg_offset(s, a->pg)); 2854f0984d40SFabiano Rosas 2855f0984d40SFabiano Rosas gen_fn(t, pd, zn, zm, pg, tcg_constant_i32(simd_desc(vsz, vsz, 0))); 2856f0984d40SFabiano Rosas 2857f0984d40SFabiano Rosas do_pred_flags(t); 2858f0984d40SFabiano Rosas return true; 2859f0984d40SFabiano Rosas } 2860f0984d40SFabiano Rosas 2861f0984d40SFabiano Rosas #define DO_PPZZ(NAME, name) \ 2862f0984d40SFabiano Rosas static gen_helper_gvec_flags_4 * const name##_ppzz_fns[4] = { \ 2863f0984d40SFabiano Rosas gen_helper_sve_##name##_ppzz_b, gen_helper_sve_##name##_ppzz_h, \ 2864f0984d40SFabiano Rosas gen_helper_sve_##name##_ppzz_s, gen_helper_sve_##name##_ppzz_d, \ 2865f0984d40SFabiano Rosas }; \ 2866f0984d40SFabiano Rosas TRANS_FEAT(NAME##_ppzz, aa64_sve, do_ppzz_flags, \ 2867f0984d40SFabiano Rosas a, name##_ppzz_fns[a->esz]) 2868f0984d40SFabiano Rosas 2869f0984d40SFabiano Rosas DO_PPZZ(CMPEQ, cmpeq) 2870f0984d40SFabiano Rosas DO_PPZZ(CMPNE, cmpne) 2871f0984d40SFabiano Rosas DO_PPZZ(CMPGT, cmpgt) 2872f0984d40SFabiano Rosas DO_PPZZ(CMPGE, cmpge) 2873f0984d40SFabiano Rosas DO_PPZZ(CMPHI, cmphi) 2874f0984d40SFabiano Rosas DO_PPZZ(CMPHS, cmphs) 2875f0984d40SFabiano Rosas 2876f0984d40SFabiano Rosas #undef DO_PPZZ 2877f0984d40SFabiano Rosas 2878f0984d40SFabiano Rosas #define DO_PPZW(NAME, name) \ 2879f0984d40SFabiano Rosas static gen_helper_gvec_flags_4 * const name##_ppzw_fns[4] = { \ 2880f0984d40SFabiano Rosas gen_helper_sve_##name##_ppzw_b, gen_helper_sve_##name##_ppzw_h, \ 2881f0984d40SFabiano Rosas gen_helper_sve_##name##_ppzw_s, NULL \ 2882f0984d40SFabiano Rosas }; \ 2883f0984d40SFabiano Rosas TRANS_FEAT(NAME##_ppzw, aa64_sve, do_ppzz_flags, \ 2884f0984d40SFabiano Rosas a, name##_ppzw_fns[a->esz]) 2885f0984d40SFabiano Rosas 2886f0984d40SFabiano Rosas DO_PPZW(CMPEQ, cmpeq) 2887f0984d40SFabiano Rosas DO_PPZW(CMPNE, cmpne) 2888f0984d40SFabiano Rosas DO_PPZW(CMPGT, cmpgt) 2889f0984d40SFabiano Rosas DO_PPZW(CMPGE, cmpge) 2890f0984d40SFabiano Rosas DO_PPZW(CMPHI, cmphi) 2891f0984d40SFabiano Rosas DO_PPZW(CMPHS, cmphs) 2892f0984d40SFabiano Rosas DO_PPZW(CMPLT, cmplt) 2893f0984d40SFabiano Rosas DO_PPZW(CMPLE, cmple) 2894f0984d40SFabiano Rosas DO_PPZW(CMPLO, cmplo) 2895f0984d40SFabiano Rosas DO_PPZW(CMPLS, cmpls) 2896f0984d40SFabiano Rosas 2897f0984d40SFabiano Rosas #undef DO_PPZW 2898f0984d40SFabiano Rosas 2899f0984d40SFabiano Rosas /* 2900f0984d40SFabiano Rosas *** SVE Integer Compare - Immediate Groups 2901f0984d40SFabiano Rosas */ 2902f0984d40SFabiano Rosas 2903f0984d40SFabiano Rosas static bool do_ppzi_flags(DisasContext *s, arg_rpri_esz *a, 2904f0984d40SFabiano Rosas gen_helper_gvec_flags_3 *gen_fn) 2905f0984d40SFabiano Rosas { 2906f0984d40SFabiano Rosas TCGv_ptr pd, zn, pg; 2907f0984d40SFabiano Rosas unsigned vsz; 2908f0984d40SFabiano Rosas TCGv_i32 t; 2909f0984d40SFabiano Rosas 2910f0984d40SFabiano Rosas if (gen_fn == NULL) { 2911f0984d40SFabiano Rosas return false; 2912f0984d40SFabiano Rosas } 2913f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2914f0984d40SFabiano Rosas return true; 2915f0984d40SFabiano Rosas } 2916f0984d40SFabiano Rosas 2917f0984d40SFabiano Rosas vsz = vec_full_reg_size(s); 2918f0984d40SFabiano Rosas t = tcg_temp_new_i32(); 2919f0984d40SFabiano Rosas pd = tcg_temp_new_ptr(); 2920f0984d40SFabiano Rosas zn = tcg_temp_new_ptr(); 2921f0984d40SFabiano Rosas pg = tcg_temp_new_ptr(); 2922f0984d40SFabiano Rosas 2923*ad75a51eSRichard Henderson tcg_gen_addi_ptr(pd, tcg_env, pred_full_reg_offset(s, a->rd)); 2924*ad75a51eSRichard Henderson tcg_gen_addi_ptr(zn, tcg_env, vec_full_reg_offset(s, a->rn)); 2925*ad75a51eSRichard Henderson tcg_gen_addi_ptr(pg, tcg_env, pred_full_reg_offset(s, a->pg)); 2926f0984d40SFabiano Rosas 2927f0984d40SFabiano Rosas gen_fn(t, pd, zn, pg, tcg_constant_i32(simd_desc(vsz, vsz, a->imm))); 2928f0984d40SFabiano Rosas 2929f0984d40SFabiano Rosas do_pred_flags(t); 2930f0984d40SFabiano Rosas return true; 2931f0984d40SFabiano Rosas } 2932f0984d40SFabiano Rosas 2933f0984d40SFabiano Rosas #define DO_PPZI(NAME, name) \ 2934f0984d40SFabiano Rosas static gen_helper_gvec_flags_3 * const name##_ppzi_fns[4] = { \ 2935f0984d40SFabiano Rosas gen_helper_sve_##name##_ppzi_b, gen_helper_sve_##name##_ppzi_h, \ 2936f0984d40SFabiano Rosas gen_helper_sve_##name##_ppzi_s, gen_helper_sve_##name##_ppzi_d, \ 2937f0984d40SFabiano Rosas }; \ 2938f0984d40SFabiano Rosas TRANS_FEAT(NAME##_ppzi, aa64_sve, do_ppzi_flags, a, \ 2939f0984d40SFabiano Rosas name##_ppzi_fns[a->esz]) 2940f0984d40SFabiano Rosas 2941f0984d40SFabiano Rosas DO_PPZI(CMPEQ, cmpeq) 2942f0984d40SFabiano Rosas DO_PPZI(CMPNE, cmpne) 2943f0984d40SFabiano Rosas DO_PPZI(CMPGT, cmpgt) 2944f0984d40SFabiano Rosas DO_PPZI(CMPGE, cmpge) 2945f0984d40SFabiano Rosas DO_PPZI(CMPHI, cmphi) 2946f0984d40SFabiano Rosas DO_PPZI(CMPHS, cmphs) 2947f0984d40SFabiano Rosas DO_PPZI(CMPLT, cmplt) 2948f0984d40SFabiano Rosas DO_PPZI(CMPLE, cmple) 2949f0984d40SFabiano Rosas DO_PPZI(CMPLO, cmplo) 2950f0984d40SFabiano Rosas DO_PPZI(CMPLS, cmpls) 2951f0984d40SFabiano Rosas 2952f0984d40SFabiano Rosas #undef DO_PPZI 2953f0984d40SFabiano Rosas 2954f0984d40SFabiano Rosas /* 2955f0984d40SFabiano Rosas *** SVE Partition Break Group 2956f0984d40SFabiano Rosas */ 2957f0984d40SFabiano Rosas 2958f0984d40SFabiano Rosas static bool do_brk3(DisasContext *s, arg_rprr_s *a, 2959f0984d40SFabiano Rosas gen_helper_gvec_4 *fn, gen_helper_gvec_flags_4 *fn_s) 2960f0984d40SFabiano Rosas { 2961f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2962f0984d40SFabiano Rosas return true; 2963f0984d40SFabiano Rosas } 2964f0984d40SFabiano Rosas 2965f0984d40SFabiano Rosas unsigned vsz = pred_full_reg_size(s); 2966f0984d40SFabiano Rosas 2967f0984d40SFabiano Rosas /* Predicate sizes may be smaller and cannot use simd_desc. */ 2968f0984d40SFabiano Rosas TCGv_ptr d = tcg_temp_new_ptr(); 2969f0984d40SFabiano Rosas TCGv_ptr n = tcg_temp_new_ptr(); 2970f0984d40SFabiano Rosas TCGv_ptr m = tcg_temp_new_ptr(); 2971f0984d40SFabiano Rosas TCGv_ptr g = tcg_temp_new_ptr(); 2972f0984d40SFabiano Rosas TCGv_i32 desc = tcg_constant_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz)); 2973f0984d40SFabiano Rosas 2974*ad75a51eSRichard Henderson tcg_gen_addi_ptr(d, tcg_env, pred_full_reg_offset(s, a->rd)); 2975*ad75a51eSRichard Henderson tcg_gen_addi_ptr(n, tcg_env, pred_full_reg_offset(s, a->rn)); 2976*ad75a51eSRichard Henderson tcg_gen_addi_ptr(m, tcg_env, pred_full_reg_offset(s, a->rm)); 2977*ad75a51eSRichard Henderson tcg_gen_addi_ptr(g, tcg_env, pred_full_reg_offset(s, a->pg)); 2978f0984d40SFabiano Rosas 2979f0984d40SFabiano Rosas if (a->s) { 2980f0984d40SFabiano Rosas TCGv_i32 t = tcg_temp_new_i32(); 2981f0984d40SFabiano Rosas fn_s(t, d, n, m, g, desc); 2982f0984d40SFabiano Rosas do_pred_flags(t); 2983f0984d40SFabiano Rosas } else { 2984f0984d40SFabiano Rosas fn(d, n, m, g, desc); 2985f0984d40SFabiano Rosas } 2986f0984d40SFabiano Rosas return true; 2987f0984d40SFabiano Rosas } 2988f0984d40SFabiano Rosas 2989f0984d40SFabiano Rosas static bool do_brk2(DisasContext *s, arg_rpr_s *a, 2990f0984d40SFabiano Rosas gen_helper_gvec_3 *fn, gen_helper_gvec_flags_3 *fn_s) 2991f0984d40SFabiano Rosas { 2992f0984d40SFabiano Rosas if (!sve_access_check(s)) { 2993f0984d40SFabiano Rosas return true; 2994f0984d40SFabiano Rosas } 2995f0984d40SFabiano Rosas 2996f0984d40SFabiano Rosas unsigned vsz = pred_full_reg_size(s); 2997f0984d40SFabiano Rosas 2998f0984d40SFabiano Rosas /* Predicate sizes may be smaller and cannot use simd_desc. */ 2999f0984d40SFabiano Rosas TCGv_ptr d = tcg_temp_new_ptr(); 3000f0984d40SFabiano Rosas TCGv_ptr n = tcg_temp_new_ptr(); 3001f0984d40SFabiano Rosas TCGv_ptr g = tcg_temp_new_ptr(); 3002f0984d40SFabiano Rosas TCGv_i32 desc = tcg_constant_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz)); 3003f0984d40SFabiano Rosas 3004*ad75a51eSRichard Henderson tcg_gen_addi_ptr(d, tcg_env, pred_full_reg_offset(s, a->rd)); 3005*ad75a51eSRichard Henderson tcg_gen_addi_ptr(n, tcg_env, pred_full_reg_offset(s, a->rn)); 3006*ad75a51eSRichard Henderson tcg_gen_addi_ptr(g, tcg_env, pred_full_reg_offset(s, a->pg)); 3007f0984d40SFabiano Rosas 3008f0984d40SFabiano Rosas if (a->s) { 3009f0984d40SFabiano Rosas TCGv_i32 t = tcg_temp_new_i32(); 3010f0984d40SFabiano Rosas fn_s(t, d, n, g, desc); 3011f0984d40SFabiano Rosas do_pred_flags(t); 3012f0984d40SFabiano Rosas } else { 3013f0984d40SFabiano Rosas fn(d, n, g, desc); 3014f0984d40SFabiano Rosas } 3015f0984d40SFabiano Rosas return true; 3016f0984d40SFabiano Rosas } 3017f0984d40SFabiano Rosas 3018f0984d40SFabiano Rosas TRANS_FEAT(BRKPA, aa64_sve, do_brk3, a, 3019f0984d40SFabiano Rosas gen_helper_sve_brkpa, gen_helper_sve_brkpas) 3020f0984d40SFabiano Rosas TRANS_FEAT(BRKPB, aa64_sve, do_brk3, a, 3021f0984d40SFabiano Rosas gen_helper_sve_brkpb, gen_helper_sve_brkpbs) 3022f0984d40SFabiano Rosas 3023f0984d40SFabiano Rosas TRANS_FEAT(BRKA_m, aa64_sve, do_brk2, a, 3024f0984d40SFabiano Rosas gen_helper_sve_brka_m, gen_helper_sve_brkas_m) 3025f0984d40SFabiano Rosas TRANS_FEAT(BRKB_m, aa64_sve, do_brk2, a, 3026f0984d40SFabiano Rosas gen_helper_sve_brkb_m, gen_helper_sve_brkbs_m) 3027f0984d40SFabiano Rosas 3028f0984d40SFabiano Rosas TRANS_FEAT(BRKA_z, aa64_sve, do_brk2, a, 3029f0984d40SFabiano Rosas gen_helper_sve_brka_z, gen_helper_sve_brkas_z) 3030f0984d40SFabiano Rosas TRANS_FEAT(BRKB_z, aa64_sve, do_brk2, a, 3031f0984d40SFabiano Rosas gen_helper_sve_brkb_z, gen_helper_sve_brkbs_z) 3032f0984d40SFabiano Rosas 3033f0984d40SFabiano Rosas TRANS_FEAT(BRKN, aa64_sve, do_brk2, a, 3034f0984d40SFabiano Rosas gen_helper_sve_brkn, gen_helper_sve_brkns) 3035f0984d40SFabiano Rosas 3036f0984d40SFabiano Rosas /* 3037f0984d40SFabiano Rosas *** SVE Predicate Count Group 3038f0984d40SFabiano Rosas */ 3039f0984d40SFabiano Rosas 3040f0984d40SFabiano Rosas static void do_cntp(DisasContext *s, TCGv_i64 val, int esz, int pn, int pg) 3041f0984d40SFabiano Rosas { 3042f0984d40SFabiano Rosas unsigned psz = pred_full_reg_size(s); 3043f0984d40SFabiano Rosas 3044f0984d40SFabiano Rosas if (psz <= 8) { 3045f0984d40SFabiano Rosas uint64_t psz_mask; 3046f0984d40SFabiano Rosas 3047*ad75a51eSRichard Henderson tcg_gen_ld_i64(val, tcg_env, pred_full_reg_offset(s, pn)); 3048f0984d40SFabiano Rosas if (pn != pg) { 3049f0984d40SFabiano Rosas TCGv_i64 g = tcg_temp_new_i64(); 3050*ad75a51eSRichard Henderson tcg_gen_ld_i64(g, tcg_env, pred_full_reg_offset(s, pg)); 3051f0984d40SFabiano Rosas tcg_gen_and_i64(val, val, g); 3052f0984d40SFabiano Rosas } 3053f0984d40SFabiano Rosas 3054f0984d40SFabiano Rosas /* Reduce the pred_esz_masks value simply to reduce the 3055f0984d40SFabiano Rosas * size of the code generated here. 3056f0984d40SFabiano Rosas */ 3057f0984d40SFabiano Rosas psz_mask = MAKE_64BIT_MASK(0, psz * 8); 3058f0984d40SFabiano Rosas tcg_gen_andi_i64(val, val, pred_esz_masks[esz] & psz_mask); 3059f0984d40SFabiano Rosas 3060f0984d40SFabiano Rosas tcg_gen_ctpop_i64(val, val); 3061f0984d40SFabiano Rosas } else { 3062f0984d40SFabiano Rosas TCGv_ptr t_pn = tcg_temp_new_ptr(); 3063f0984d40SFabiano Rosas TCGv_ptr t_pg = tcg_temp_new_ptr(); 3064f0984d40SFabiano Rosas unsigned desc = 0; 3065f0984d40SFabiano Rosas 3066f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, psz); 3067f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, esz); 3068f0984d40SFabiano Rosas 3069*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pn, tcg_env, pred_full_reg_offset(s, pn)); 3070*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); 3071f0984d40SFabiano Rosas 3072f0984d40SFabiano Rosas gen_helper_sve_cntp(val, t_pn, t_pg, tcg_constant_i32(desc)); 3073f0984d40SFabiano Rosas } 3074f0984d40SFabiano Rosas } 3075f0984d40SFabiano Rosas 3076f0984d40SFabiano Rosas static bool trans_CNTP(DisasContext *s, arg_CNTP *a) 3077f0984d40SFabiano Rosas { 3078f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3079f0984d40SFabiano Rosas return false; 3080f0984d40SFabiano Rosas } 3081f0984d40SFabiano Rosas if (sve_access_check(s)) { 3082f0984d40SFabiano Rosas do_cntp(s, cpu_reg(s, a->rd), a->esz, a->rn, a->pg); 3083f0984d40SFabiano Rosas } 3084f0984d40SFabiano Rosas return true; 3085f0984d40SFabiano Rosas } 3086f0984d40SFabiano Rosas 3087f0984d40SFabiano Rosas static bool trans_INCDECP_r(DisasContext *s, arg_incdec_pred *a) 3088f0984d40SFabiano Rosas { 3089f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3090f0984d40SFabiano Rosas return false; 3091f0984d40SFabiano Rosas } 3092f0984d40SFabiano Rosas if (sve_access_check(s)) { 3093f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 3094f0984d40SFabiano Rosas TCGv_i64 val = tcg_temp_new_i64(); 3095f0984d40SFabiano Rosas 3096f0984d40SFabiano Rosas do_cntp(s, val, a->esz, a->pg, a->pg); 3097f0984d40SFabiano Rosas if (a->d) { 3098f0984d40SFabiano Rosas tcg_gen_sub_i64(reg, reg, val); 3099f0984d40SFabiano Rosas } else { 3100f0984d40SFabiano Rosas tcg_gen_add_i64(reg, reg, val); 3101f0984d40SFabiano Rosas } 3102f0984d40SFabiano Rosas } 3103f0984d40SFabiano Rosas return true; 3104f0984d40SFabiano Rosas } 3105f0984d40SFabiano Rosas 3106f0984d40SFabiano Rosas static bool trans_INCDECP_z(DisasContext *s, arg_incdec2_pred *a) 3107f0984d40SFabiano Rosas { 3108f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 3109f0984d40SFabiano Rosas return false; 3110f0984d40SFabiano Rosas } 3111f0984d40SFabiano Rosas if (sve_access_check(s)) { 3112f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3113f0984d40SFabiano Rosas TCGv_i64 val = tcg_temp_new_i64(); 3114f0984d40SFabiano Rosas GVecGen2sFn *gvec_fn = a->d ? tcg_gen_gvec_subs : tcg_gen_gvec_adds; 3115f0984d40SFabiano Rosas 3116f0984d40SFabiano Rosas do_cntp(s, val, a->esz, a->pg, a->pg); 3117f0984d40SFabiano Rosas gvec_fn(a->esz, vec_full_reg_offset(s, a->rd), 3118f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), val, vsz, vsz); 3119f0984d40SFabiano Rosas } 3120f0984d40SFabiano Rosas return true; 3121f0984d40SFabiano Rosas } 3122f0984d40SFabiano Rosas 3123f0984d40SFabiano Rosas static bool trans_SINCDECP_r_32(DisasContext *s, arg_incdec_pred *a) 3124f0984d40SFabiano Rosas { 3125f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3126f0984d40SFabiano Rosas return false; 3127f0984d40SFabiano Rosas } 3128f0984d40SFabiano Rosas if (sve_access_check(s)) { 3129f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 3130f0984d40SFabiano Rosas TCGv_i64 val = tcg_temp_new_i64(); 3131f0984d40SFabiano Rosas 3132f0984d40SFabiano Rosas do_cntp(s, val, a->esz, a->pg, a->pg); 3133f0984d40SFabiano Rosas do_sat_addsub_32(reg, val, a->u, a->d); 3134f0984d40SFabiano Rosas } 3135f0984d40SFabiano Rosas return true; 3136f0984d40SFabiano Rosas } 3137f0984d40SFabiano Rosas 3138f0984d40SFabiano Rosas static bool trans_SINCDECP_r_64(DisasContext *s, arg_incdec_pred *a) 3139f0984d40SFabiano Rosas { 3140f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3141f0984d40SFabiano Rosas return false; 3142f0984d40SFabiano Rosas } 3143f0984d40SFabiano Rosas if (sve_access_check(s)) { 3144f0984d40SFabiano Rosas TCGv_i64 reg = cpu_reg(s, a->rd); 3145f0984d40SFabiano Rosas TCGv_i64 val = tcg_temp_new_i64(); 3146f0984d40SFabiano Rosas 3147f0984d40SFabiano Rosas do_cntp(s, val, a->esz, a->pg, a->pg); 3148f0984d40SFabiano Rosas do_sat_addsub_64(reg, val, a->u, a->d); 3149f0984d40SFabiano Rosas } 3150f0984d40SFabiano Rosas return true; 3151f0984d40SFabiano Rosas } 3152f0984d40SFabiano Rosas 3153f0984d40SFabiano Rosas static bool trans_SINCDECP_z(DisasContext *s, arg_incdec2_pred *a) 3154f0984d40SFabiano Rosas { 3155f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 3156f0984d40SFabiano Rosas return false; 3157f0984d40SFabiano Rosas } 3158f0984d40SFabiano Rosas if (sve_access_check(s)) { 3159f0984d40SFabiano Rosas TCGv_i64 val = tcg_temp_new_i64(); 3160f0984d40SFabiano Rosas do_cntp(s, val, a->esz, a->pg, a->pg); 3161f0984d40SFabiano Rosas do_sat_addsub_vec(s, a->esz, a->rd, a->rn, val, a->u, a->d); 3162f0984d40SFabiano Rosas } 3163f0984d40SFabiano Rosas return true; 3164f0984d40SFabiano Rosas } 3165f0984d40SFabiano Rosas 3166f0984d40SFabiano Rosas /* 3167f0984d40SFabiano Rosas *** SVE Integer Compare Scalars Group 3168f0984d40SFabiano Rosas */ 3169f0984d40SFabiano Rosas 3170f0984d40SFabiano Rosas static bool trans_CTERM(DisasContext *s, arg_CTERM *a) 3171f0984d40SFabiano Rosas { 3172f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3173f0984d40SFabiano Rosas return false; 3174f0984d40SFabiano Rosas } 3175f0984d40SFabiano Rosas if (!sve_access_check(s)) { 3176f0984d40SFabiano Rosas return true; 3177f0984d40SFabiano Rosas } 3178f0984d40SFabiano Rosas 3179f0984d40SFabiano Rosas TCGCond cond = (a->ne ? TCG_COND_NE : TCG_COND_EQ); 3180f0984d40SFabiano Rosas TCGv_i64 rn = read_cpu_reg(s, a->rn, a->sf); 3181f0984d40SFabiano Rosas TCGv_i64 rm = read_cpu_reg(s, a->rm, a->sf); 3182f0984d40SFabiano Rosas TCGv_i64 cmp = tcg_temp_new_i64(); 3183f0984d40SFabiano Rosas 3184f0984d40SFabiano Rosas tcg_gen_setcond_i64(cond, cmp, rn, rm); 3185f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(cpu_NF, cmp); 3186f0984d40SFabiano Rosas 3187f0984d40SFabiano Rosas /* VF = !NF & !CF. */ 3188f0984d40SFabiano Rosas tcg_gen_xori_i32(cpu_VF, cpu_NF, 1); 3189f0984d40SFabiano Rosas tcg_gen_andc_i32(cpu_VF, cpu_VF, cpu_CF); 3190f0984d40SFabiano Rosas 3191f0984d40SFabiano Rosas /* Both NF and VF actually look at bit 31. */ 3192f0984d40SFabiano Rosas tcg_gen_neg_i32(cpu_NF, cpu_NF); 3193f0984d40SFabiano Rosas tcg_gen_neg_i32(cpu_VF, cpu_VF); 3194f0984d40SFabiano Rosas return true; 3195f0984d40SFabiano Rosas } 3196f0984d40SFabiano Rosas 3197f0984d40SFabiano Rosas static bool trans_WHILE(DisasContext *s, arg_WHILE *a) 3198f0984d40SFabiano Rosas { 3199f0984d40SFabiano Rosas TCGv_i64 op0, op1, t0, t1, tmax; 3200f0984d40SFabiano Rosas TCGv_i32 t2; 3201f0984d40SFabiano Rosas TCGv_ptr ptr; 3202f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3203f0984d40SFabiano Rosas unsigned desc = 0; 3204f0984d40SFabiano Rosas TCGCond cond; 3205f0984d40SFabiano Rosas uint64_t maxval; 3206f0984d40SFabiano Rosas /* Note that GE/HS has a->eq == 0 and GT/HI has a->eq == 1. */ 3207f0984d40SFabiano Rosas bool eq = a->eq == a->lt; 3208f0984d40SFabiano Rosas 3209f0984d40SFabiano Rosas /* The greater-than conditions are all SVE2. */ 3210f0984d40SFabiano Rosas if (a->lt 3211f0984d40SFabiano Rosas ? !dc_isar_feature(aa64_sve, s) 3212f0984d40SFabiano Rosas : !dc_isar_feature(aa64_sve2, s)) { 3213f0984d40SFabiano Rosas return false; 3214f0984d40SFabiano Rosas } 3215f0984d40SFabiano Rosas if (!sve_access_check(s)) { 3216f0984d40SFabiano Rosas return true; 3217f0984d40SFabiano Rosas } 3218f0984d40SFabiano Rosas 3219f0984d40SFabiano Rosas op0 = read_cpu_reg(s, a->rn, 1); 3220f0984d40SFabiano Rosas op1 = read_cpu_reg(s, a->rm, 1); 3221f0984d40SFabiano Rosas 3222f0984d40SFabiano Rosas if (!a->sf) { 3223f0984d40SFabiano Rosas if (a->u) { 3224f0984d40SFabiano Rosas tcg_gen_ext32u_i64(op0, op0); 3225f0984d40SFabiano Rosas tcg_gen_ext32u_i64(op1, op1); 3226f0984d40SFabiano Rosas } else { 3227f0984d40SFabiano Rosas tcg_gen_ext32s_i64(op0, op0); 3228f0984d40SFabiano Rosas tcg_gen_ext32s_i64(op1, op1); 3229f0984d40SFabiano Rosas } 3230f0984d40SFabiano Rosas } 3231f0984d40SFabiano Rosas 3232f0984d40SFabiano Rosas /* For the helper, compress the different conditions into a computation 3233f0984d40SFabiano Rosas * of how many iterations for which the condition is true. 3234f0984d40SFabiano Rosas */ 3235f0984d40SFabiano Rosas t0 = tcg_temp_new_i64(); 3236f0984d40SFabiano Rosas t1 = tcg_temp_new_i64(); 3237f0984d40SFabiano Rosas 3238f0984d40SFabiano Rosas if (a->lt) { 3239f0984d40SFabiano Rosas tcg_gen_sub_i64(t0, op1, op0); 3240f0984d40SFabiano Rosas if (a->u) { 3241f0984d40SFabiano Rosas maxval = a->sf ? UINT64_MAX : UINT32_MAX; 3242f0984d40SFabiano Rosas cond = eq ? TCG_COND_LEU : TCG_COND_LTU; 3243f0984d40SFabiano Rosas } else { 3244f0984d40SFabiano Rosas maxval = a->sf ? INT64_MAX : INT32_MAX; 3245f0984d40SFabiano Rosas cond = eq ? TCG_COND_LE : TCG_COND_LT; 3246f0984d40SFabiano Rosas } 3247f0984d40SFabiano Rosas } else { 3248f0984d40SFabiano Rosas tcg_gen_sub_i64(t0, op0, op1); 3249f0984d40SFabiano Rosas if (a->u) { 3250f0984d40SFabiano Rosas maxval = 0; 3251f0984d40SFabiano Rosas cond = eq ? TCG_COND_GEU : TCG_COND_GTU; 3252f0984d40SFabiano Rosas } else { 3253f0984d40SFabiano Rosas maxval = a->sf ? INT64_MIN : INT32_MIN; 3254f0984d40SFabiano Rosas cond = eq ? TCG_COND_GE : TCG_COND_GT; 3255f0984d40SFabiano Rosas } 3256f0984d40SFabiano Rosas } 3257f0984d40SFabiano Rosas 3258f0984d40SFabiano Rosas tmax = tcg_constant_i64(vsz >> a->esz); 3259f0984d40SFabiano Rosas if (eq) { 3260f0984d40SFabiano Rosas /* Equality means one more iteration. */ 3261f0984d40SFabiano Rosas tcg_gen_addi_i64(t0, t0, 1); 3262f0984d40SFabiano Rosas 3263f0984d40SFabiano Rosas /* 3264f0984d40SFabiano Rosas * For the less-than while, if op1 is maxval (and the only time 3265f0984d40SFabiano Rosas * the addition above could overflow), then we produce an all-true 3266f0984d40SFabiano Rosas * predicate by setting the count to the vector length. This is 3267f0984d40SFabiano Rosas * because the pseudocode is described as an increment + compare 3268f0984d40SFabiano Rosas * loop, and the maximum integer would always compare true. 3269f0984d40SFabiano Rosas * Similarly, the greater-than while has the same issue with the 3270f0984d40SFabiano Rosas * minimum integer due to the decrement + compare loop. 3271f0984d40SFabiano Rosas */ 3272f0984d40SFabiano Rosas tcg_gen_movi_i64(t1, maxval); 3273f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_EQ, t0, op1, t1, tmax, t0); 3274f0984d40SFabiano Rosas } 3275f0984d40SFabiano Rosas 3276f0984d40SFabiano Rosas /* Bound to the maximum. */ 3277f0984d40SFabiano Rosas tcg_gen_umin_i64(t0, t0, tmax); 3278f0984d40SFabiano Rosas 3279f0984d40SFabiano Rosas /* Set the count to zero if the condition is false. */ 3280f0984d40SFabiano Rosas tcg_gen_movi_i64(t1, 0); 3281f0984d40SFabiano Rosas tcg_gen_movcond_i64(cond, t0, op0, op1, t0, t1); 3282f0984d40SFabiano Rosas 3283f0984d40SFabiano Rosas /* Since we're bounded, pass as a 32-bit type. */ 3284f0984d40SFabiano Rosas t2 = tcg_temp_new_i32(); 3285f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(t2, t0); 3286f0984d40SFabiano Rosas 3287f0984d40SFabiano Rosas /* Scale elements to bits. */ 3288f0984d40SFabiano Rosas tcg_gen_shli_i32(t2, t2, a->esz); 3289f0984d40SFabiano Rosas 3290f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8); 3291f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz); 3292f0984d40SFabiano Rosas 3293f0984d40SFabiano Rosas ptr = tcg_temp_new_ptr(); 3294*ad75a51eSRichard Henderson tcg_gen_addi_ptr(ptr, tcg_env, pred_full_reg_offset(s, a->rd)); 3295f0984d40SFabiano Rosas 3296f0984d40SFabiano Rosas if (a->lt) { 3297f0984d40SFabiano Rosas gen_helper_sve_whilel(t2, ptr, t2, tcg_constant_i32(desc)); 3298f0984d40SFabiano Rosas } else { 3299f0984d40SFabiano Rosas gen_helper_sve_whileg(t2, ptr, t2, tcg_constant_i32(desc)); 3300f0984d40SFabiano Rosas } 3301f0984d40SFabiano Rosas do_pred_flags(t2); 3302f0984d40SFabiano Rosas return true; 3303f0984d40SFabiano Rosas } 3304f0984d40SFabiano Rosas 3305f0984d40SFabiano Rosas static bool trans_WHILE_ptr(DisasContext *s, arg_WHILE_ptr *a) 3306f0984d40SFabiano Rosas { 3307f0984d40SFabiano Rosas TCGv_i64 op0, op1, diff, t1, tmax; 3308f0984d40SFabiano Rosas TCGv_i32 t2; 3309f0984d40SFabiano Rosas TCGv_ptr ptr; 3310f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3311f0984d40SFabiano Rosas unsigned desc = 0; 3312f0984d40SFabiano Rosas 3313f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve2, s)) { 3314f0984d40SFabiano Rosas return false; 3315f0984d40SFabiano Rosas } 3316f0984d40SFabiano Rosas if (!sve_access_check(s)) { 3317f0984d40SFabiano Rosas return true; 3318f0984d40SFabiano Rosas } 3319f0984d40SFabiano Rosas 3320f0984d40SFabiano Rosas op0 = read_cpu_reg(s, a->rn, 1); 3321f0984d40SFabiano Rosas op1 = read_cpu_reg(s, a->rm, 1); 3322f0984d40SFabiano Rosas 3323f0984d40SFabiano Rosas tmax = tcg_constant_i64(vsz); 3324f0984d40SFabiano Rosas diff = tcg_temp_new_i64(); 3325f0984d40SFabiano Rosas 3326f0984d40SFabiano Rosas if (a->rw) { 3327f0984d40SFabiano Rosas /* WHILERW */ 3328f0984d40SFabiano Rosas /* diff = abs(op1 - op0), noting that op0/1 are unsigned. */ 3329f0984d40SFabiano Rosas t1 = tcg_temp_new_i64(); 3330f0984d40SFabiano Rosas tcg_gen_sub_i64(diff, op0, op1); 3331f0984d40SFabiano Rosas tcg_gen_sub_i64(t1, op1, op0); 3332f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_GEU, diff, op0, op1, diff, t1); 3333f0984d40SFabiano Rosas /* Round down to a multiple of ESIZE. */ 3334f0984d40SFabiano Rosas tcg_gen_andi_i64(diff, diff, -1 << a->esz); 3335f0984d40SFabiano Rosas /* If op1 == op0, diff == 0, and the condition is always true. */ 3336f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_EQ, diff, op0, op1, tmax, diff); 3337f0984d40SFabiano Rosas } else { 3338f0984d40SFabiano Rosas /* WHILEWR */ 3339f0984d40SFabiano Rosas tcg_gen_sub_i64(diff, op1, op0); 3340f0984d40SFabiano Rosas /* Round down to a multiple of ESIZE. */ 3341f0984d40SFabiano Rosas tcg_gen_andi_i64(diff, diff, -1 << a->esz); 3342f0984d40SFabiano Rosas /* If op0 >= op1, diff <= 0, the condition is always true. */ 3343f0984d40SFabiano Rosas tcg_gen_movcond_i64(TCG_COND_GEU, diff, op0, op1, tmax, diff); 3344f0984d40SFabiano Rosas } 3345f0984d40SFabiano Rosas 3346f0984d40SFabiano Rosas /* Bound to the maximum. */ 3347f0984d40SFabiano Rosas tcg_gen_umin_i64(diff, diff, tmax); 3348f0984d40SFabiano Rosas 3349f0984d40SFabiano Rosas /* Since we're bounded, pass as a 32-bit type. */ 3350f0984d40SFabiano Rosas t2 = tcg_temp_new_i32(); 3351f0984d40SFabiano Rosas tcg_gen_extrl_i64_i32(t2, diff); 3352f0984d40SFabiano Rosas 3353f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8); 3354f0984d40SFabiano Rosas desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz); 3355f0984d40SFabiano Rosas 3356f0984d40SFabiano Rosas ptr = tcg_temp_new_ptr(); 3357*ad75a51eSRichard Henderson tcg_gen_addi_ptr(ptr, tcg_env, pred_full_reg_offset(s, a->rd)); 3358f0984d40SFabiano Rosas 3359f0984d40SFabiano Rosas gen_helper_sve_whilel(t2, ptr, t2, tcg_constant_i32(desc)); 3360f0984d40SFabiano Rosas do_pred_flags(t2); 3361f0984d40SFabiano Rosas return true; 3362f0984d40SFabiano Rosas } 3363f0984d40SFabiano Rosas 3364f0984d40SFabiano Rosas /* 3365f0984d40SFabiano Rosas *** SVE Integer Wide Immediate - Unpredicated Group 3366f0984d40SFabiano Rosas */ 3367f0984d40SFabiano Rosas 3368f0984d40SFabiano Rosas static bool trans_FDUP(DisasContext *s, arg_FDUP *a) 3369f0984d40SFabiano Rosas { 3370f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 3371f0984d40SFabiano Rosas return false; 3372f0984d40SFabiano Rosas } 3373f0984d40SFabiano Rosas if (sve_access_check(s)) { 3374f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3375f0984d40SFabiano Rosas int dofs = vec_full_reg_offset(s, a->rd); 3376f0984d40SFabiano Rosas uint64_t imm; 3377f0984d40SFabiano Rosas 3378f0984d40SFabiano Rosas /* Decode the VFP immediate. */ 3379f0984d40SFabiano Rosas imm = vfp_expand_imm(a->esz, a->imm); 3380f0984d40SFabiano Rosas tcg_gen_gvec_dup_imm(a->esz, dofs, vsz, vsz, imm); 3381f0984d40SFabiano Rosas } 3382f0984d40SFabiano Rosas return true; 3383f0984d40SFabiano Rosas } 3384f0984d40SFabiano Rosas 3385f0984d40SFabiano Rosas static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a) 3386f0984d40SFabiano Rosas { 3387f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3388f0984d40SFabiano Rosas return false; 3389f0984d40SFabiano Rosas } 3390f0984d40SFabiano Rosas if (sve_access_check(s)) { 3391f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3392f0984d40SFabiano Rosas int dofs = vec_full_reg_offset(s, a->rd); 3393f0984d40SFabiano Rosas tcg_gen_gvec_dup_imm(a->esz, dofs, vsz, vsz, a->imm); 3394f0984d40SFabiano Rosas } 3395f0984d40SFabiano Rosas return true; 3396f0984d40SFabiano Rosas } 3397f0984d40SFabiano Rosas 3398f0984d40SFabiano Rosas TRANS_FEAT(ADD_zzi, aa64_sve, gen_gvec_fn_arg_zzi, tcg_gen_gvec_addi, a) 3399f0984d40SFabiano Rosas 3400f0984d40SFabiano Rosas static bool trans_SUB_zzi(DisasContext *s, arg_rri_esz *a) 3401f0984d40SFabiano Rosas { 3402f0984d40SFabiano Rosas a->imm = -a->imm; 3403f0984d40SFabiano Rosas return trans_ADD_zzi(s, a); 3404f0984d40SFabiano Rosas } 3405f0984d40SFabiano Rosas 3406f0984d40SFabiano Rosas static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz *a) 3407f0984d40SFabiano Rosas { 3408f0984d40SFabiano Rosas static const TCGOpcode vecop_list[] = { INDEX_op_sub_vec, 0 }; 3409f0984d40SFabiano Rosas static const GVecGen2s op[4] = { 3410f0984d40SFabiano Rosas { .fni8 = tcg_gen_vec_sub8_i64, 3411f0984d40SFabiano Rosas .fniv = tcg_gen_sub_vec, 3412f0984d40SFabiano Rosas .fno = gen_helper_sve_subri_b, 3413f0984d40SFabiano Rosas .opt_opc = vecop_list, 3414f0984d40SFabiano Rosas .vece = MO_8, 3415f0984d40SFabiano Rosas .scalar_first = true }, 3416f0984d40SFabiano Rosas { .fni8 = tcg_gen_vec_sub16_i64, 3417f0984d40SFabiano Rosas .fniv = tcg_gen_sub_vec, 3418f0984d40SFabiano Rosas .fno = gen_helper_sve_subri_h, 3419f0984d40SFabiano Rosas .opt_opc = vecop_list, 3420f0984d40SFabiano Rosas .vece = MO_16, 3421f0984d40SFabiano Rosas .scalar_first = true }, 3422f0984d40SFabiano Rosas { .fni4 = tcg_gen_sub_i32, 3423f0984d40SFabiano Rosas .fniv = tcg_gen_sub_vec, 3424f0984d40SFabiano Rosas .fno = gen_helper_sve_subri_s, 3425f0984d40SFabiano Rosas .opt_opc = vecop_list, 3426f0984d40SFabiano Rosas .vece = MO_32, 3427f0984d40SFabiano Rosas .scalar_first = true }, 3428f0984d40SFabiano Rosas { .fni8 = tcg_gen_sub_i64, 3429f0984d40SFabiano Rosas .fniv = tcg_gen_sub_vec, 3430f0984d40SFabiano Rosas .fno = gen_helper_sve_subri_d, 3431f0984d40SFabiano Rosas .opt_opc = vecop_list, 3432f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64, 3433f0984d40SFabiano Rosas .vece = MO_64, 3434f0984d40SFabiano Rosas .scalar_first = true } 3435f0984d40SFabiano Rosas }; 3436f0984d40SFabiano Rosas 3437f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 3438f0984d40SFabiano Rosas return false; 3439f0984d40SFabiano Rosas } 3440f0984d40SFabiano Rosas if (sve_access_check(s)) { 3441f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3442f0984d40SFabiano Rosas tcg_gen_gvec_2s(vec_full_reg_offset(s, a->rd), 3443f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 3444f0984d40SFabiano Rosas vsz, vsz, tcg_constant_i64(a->imm), &op[a->esz]); 3445f0984d40SFabiano Rosas } 3446f0984d40SFabiano Rosas return true; 3447f0984d40SFabiano Rosas } 3448f0984d40SFabiano Rosas 3449f0984d40SFabiano Rosas TRANS_FEAT(MUL_zzi, aa64_sve, gen_gvec_fn_arg_zzi, tcg_gen_gvec_muli, a) 3450f0984d40SFabiano Rosas 3451f0984d40SFabiano Rosas static bool do_zzi_sat(DisasContext *s, arg_rri_esz *a, bool u, bool d) 3452f0984d40SFabiano Rosas { 3453f0984d40SFabiano Rosas if (sve_access_check(s)) { 3454f0984d40SFabiano Rosas do_sat_addsub_vec(s, a->esz, a->rd, a->rn, 3455f0984d40SFabiano Rosas tcg_constant_i64(a->imm), u, d); 3456f0984d40SFabiano Rosas } 3457f0984d40SFabiano Rosas return true; 3458f0984d40SFabiano Rosas } 3459f0984d40SFabiano Rosas 3460f0984d40SFabiano Rosas TRANS_FEAT(SQADD_zzi, aa64_sve, do_zzi_sat, a, false, false) 3461f0984d40SFabiano Rosas TRANS_FEAT(UQADD_zzi, aa64_sve, do_zzi_sat, a, true, false) 3462f0984d40SFabiano Rosas TRANS_FEAT(SQSUB_zzi, aa64_sve, do_zzi_sat, a, false, true) 3463f0984d40SFabiano Rosas TRANS_FEAT(UQSUB_zzi, aa64_sve, do_zzi_sat, a, true, true) 3464f0984d40SFabiano Rosas 3465f0984d40SFabiano Rosas static bool do_zzi_ool(DisasContext *s, arg_rri_esz *a, gen_helper_gvec_2i *fn) 3466f0984d40SFabiano Rosas { 3467f0984d40SFabiano Rosas if (sve_access_check(s)) { 3468f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3469f0984d40SFabiano Rosas tcg_gen_gvec_2i_ool(vec_full_reg_offset(s, a->rd), 3470f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 3471f0984d40SFabiano Rosas tcg_constant_i64(a->imm), vsz, vsz, 0, fn); 3472f0984d40SFabiano Rosas } 3473f0984d40SFabiano Rosas return true; 3474f0984d40SFabiano Rosas } 3475f0984d40SFabiano Rosas 3476f0984d40SFabiano Rosas #define DO_ZZI(NAME, name) \ 3477f0984d40SFabiano Rosas static gen_helper_gvec_2i * const name##i_fns[4] = { \ 3478f0984d40SFabiano Rosas gen_helper_sve_##name##i_b, gen_helper_sve_##name##i_h, \ 3479f0984d40SFabiano Rosas gen_helper_sve_##name##i_s, gen_helper_sve_##name##i_d, \ 3480f0984d40SFabiano Rosas }; \ 3481f0984d40SFabiano Rosas TRANS_FEAT(NAME##_zzi, aa64_sve, do_zzi_ool, a, name##i_fns[a->esz]) 3482f0984d40SFabiano Rosas 3483f0984d40SFabiano Rosas DO_ZZI(SMAX, smax) 3484f0984d40SFabiano Rosas DO_ZZI(UMAX, umax) 3485f0984d40SFabiano Rosas DO_ZZI(SMIN, smin) 3486f0984d40SFabiano Rosas DO_ZZI(UMIN, umin) 3487f0984d40SFabiano Rosas 3488f0984d40SFabiano Rosas #undef DO_ZZI 3489f0984d40SFabiano Rosas 3490f0984d40SFabiano Rosas static gen_helper_gvec_4 * const dot_fns[2][2] = { 3491f0984d40SFabiano Rosas { gen_helper_gvec_sdot_b, gen_helper_gvec_sdot_h }, 3492f0984d40SFabiano Rosas { gen_helper_gvec_udot_b, gen_helper_gvec_udot_h } 3493f0984d40SFabiano Rosas }; 3494f0984d40SFabiano Rosas TRANS_FEAT(DOT_zzzz, aa64_sve, gen_gvec_ool_zzzz, 3495f0984d40SFabiano Rosas dot_fns[a->u][a->sz], a->rd, a->rn, a->rm, a->ra, 0) 3496f0984d40SFabiano Rosas 3497f0984d40SFabiano Rosas /* 3498f0984d40SFabiano Rosas * SVE Multiply - Indexed 3499f0984d40SFabiano Rosas */ 3500f0984d40SFabiano Rosas 3501f0984d40SFabiano Rosas TRANS_FEAT(SDOT_zzxw_s, aa64_sve, gen_gvec_ool_arg_zzxz, 3502f0984d40SFabiano Rosas gen_helper_gvec_sdot_idx_b, a) 3503f0984d40SFabiano Rosas TRANS_FEAT(SDOT_zzxw_d, aa64_sve, gen_gvec_ool_arg_zzxz, 3504f0984d40SFabiano Rosas gen_helper_gvec_sdot_idx_h, a) 3505f0984d40SFabiano Rosas TRANS_FEAT(UDOT_zzxw_s, aa64_sve, gen_gvec_ool_arg_zzxz, 3506f0984d40SFabiano Rosas gen_helper_gvec_udot_idx_b, a) 3507f0984d40SFabiano Rosas TRANS_FEAT(UDOT_zzxw_d, aa64_sve, gen_gvec_ool_arg_zzxz, 3508f0984d40SFabiano Rosas gen_helper_gvec_udot_idx_h, a) 3509f0984d40SFabiano Rosas 3510f0984d40SFabiano Rosas TRANS_FEAT(SUDOT_zzxw_s, aa64_sve_i8mm, gen_gvec_ool_arg_zzxz, 3511f0984d40SFabiano Rosas gen_helper_gvec_sudot_idx_b, a) 3512f0984d40SFabiano Rosas TRANS_FEAT(USDOT_zzxw_s, aa64_sve_i8mm, gen_gvec_ool_arg_zzxz, 3513f0984d40SFabiano Rosas gen_helper_gvec_usdot_idx_b, a) 3514f0984d40SFabiano Rosas 3515f0984d40SFabiano Rosas #define DO_SVE2_RRX(NAME, FUNC) \ 3516f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, gen_gvec_ool_zzz, FUNC, \ 3517f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->index) 3518f0984d40SFabiano Rosas 3519f0984d40SFabiano Rosas DO_SVE2_RRX(MUL_zzx_h, gen_helper_gvec_mul_idx_h) 3520f0984d40SFabiano Rosas DO_SVE2_RRX(MUL_zzx_s, gen_helper_gvec_mul_idx_s) 3521f0984d40SFabiano Rosas DO_SVE2_RRX(MUL_zzx_d, gen_helper_gvec_mul_idx_d) 3522f0984d40SFabiano Rosas 3523f0984d40SFabiano Rosas DO_SVE2_RRX(SQDMULH_zzx_h, gen_helper_sve2_sqdmulh_idx_h) 3524f0984d40SFabiano Rosas DO_SVE2_RRX(SQDMULH_zzx_s, gen_helper_sve2_sqdmulh_idx_s) 3525f0984d40SFabiano Rosas DO_SVE2_RRX(SQDMULH_zzx_d, gen_helper_sve2_sqdmulh_idx_d) 3526f0984d40SFabiano Rosas 3527f0984d40SFabiano Rosas DO_SVE2_RRX(SQRDMULH_zzx_h, gen_helper_sve2_sqrdmulh_idx_h) 3528f0984d40SFabiano Rosas DO_SVE2_RRX(SQRDMULH_zzx_s, gen_helper_sve2_sqrdmulh_idx_s) 3529f0984d40SFabiano Rosas DO_SVE2_RRX(SQRDMULH_zzx_d, gen_helper_sve2_sqrdmulh_idx_d) 3530f0984d40SFabiano Rosas 3531f0984d40SFabiano Rosas #undef DO_SVE2_RRX 3532f0984d40SFabiano Rosas 3533f0984d40SFabiano Rosas #define DO_SVE2_RRX_TB(NAME, FUNC, TOP) \ 3534f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, gen_gvec_ool_zzz, FUNC, \ 3535f0984d40SFabiano Rosas a->rd, a->rn, a->rm, (a->index << 1) | TOP) 3536f0984d40SFabiano Rosas 3537f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SQDMULLB_zzx_s, gen_helper_sve2_sqdmull_idx_s, false) 3538f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SQDMULLB_zzx_d, gen_helper_sve2_sqdmull_idx_d, false) 3539f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SQDMULLT_zzx_s, gen_helper_sve2_sqdmull_idx_s, true) 3540f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SQDMULLT_zzx_d, gen_helper_sve2_sqdmull_idx_d, true) 3541f0984d40SFabiano Rosas 3542f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SMULLB_zzx_s, gen_helper_sve2_smull_idx_s, false) 3543f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SMULLB_zzx_d, gen_helper_sve2_smull_idx_d, false) 3544f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SMULLT_zzx_s, gen_helper_sve2_smull_idx_s, true) 3545f0984d40SFabiano Rosas DO_SVE2_RRX_TB(SMULLT_zzx_d, gen_helper_sve2_smull_idx_d, true) 3546f0984d40SFabiano Rosas 3547f0984d40SFabiano Rosas DO_SVE2_RRX_TB(UMULLB_zzx_s, gen_helper_sve2_umull_idx_s, false) 3548f0984d40SFabiano Rosas DO_SVE2_RRX_TB(UMULLB_zzx_d, gen_helper_sve2_umull_idx_d, false) 3549f0984d40SFabiano Rosas DO_SVE2_RRX_TB(UMULLT_zzx_s, gen_helper_sve2_umull_idx_s, true) 3550f0984d40SFabiano Rosas DO_SVE2_RRX_TB(UMULLT_zzx_d, gen_helper_sve2_umull_idx_d, true) 3551f0984d40SFabiano Rosas 3552f0984d40SFabiano Rosas #undef DO_SVE2_RRX_TB 3553f0984d40SFabiano Rosas 3554f0984d40SFabiano Rosas #define DO_SVE2_RRXR(NAME, FUNC) \ 3555f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve2, gen_gvec_ool_arg_zzxz, FUNC, a) 3556f0984d40SFabiano Rosas 3557f0984d40SFabiano Rosas DO_SVE2_RRXR(MLA_zzxz_h, gen_helper_gvec_mla_idx_h) 3558f0984d40SFabiano Rosas DO_SVE2_RRXR(MLA_zzxz_s, gen_helper_gvec_mla_idx_s) 3559f0984d40SFabiano Rosas DO_SVE2_RRXR(MLA_zzxz_d, gen_helper_gvec_mla_idx_d) 3560f0984d40SFabiano Rosas 3561f0984d40SFabiano Rosas DO_SVE2_RRXR(MLS_zzxz_h, gen_helper_gvec_mls_idx_h) 3562f0984d40SFabiano Rosas DO_SVE2_RRXR(MLS_zzxz_s, gen_helper_gvec_mls_idx_s) 3563f0984d40SFabiano Rosas DO_SVE2_RRXR(MLS_zzxz_d, gen_helper_gvec_mls_idx_d) 3564f0984d40SFabiano Rosas 3565f0984d40SFabiano Rosas DO_SVE2_RRXR(SQRDMLAH_zzxz_h, gen_helper_sve2_sqrdmlah_idx_h) 3566f0984d40SFabiano Rosas DO_SVE2_RRXR(SQRDMLAH_zzxz_s, gen_helper_sve2_sqrdmlah_idx_s) 3567f0984d40SFabiano Rosas DO_SVE2_RRXR(SQRDMLAH_zzxz_d, gen_helper_sve2_sqrdmlah_idx_d) 3568f0984d40SFabiano Rosas 3569f0984d40SFabiano Rosas DO_SVE2_RRXR(SQRDMLSH_zzxz_h, gen_helper_sve2_sqrdmlsh_idx_h) 3570f0984d40SFabiano Rosas DO_SVE2_RRXR(SQRDMLSH_zzxz_s, gen_helper_sve2_sqrdmlsh_idx_s) 3571f0984d40SFabiano Rosas DO_SVE2_RRXR(SQRDMLSH_zzxz_d, gen_helper_sve2_sqrdmlsh_idx_d) 3572f0984d40SFabiano Rosas 3573f0984d40SFabiano Rosas #undef DO_SVE2_RRXR 3574f0984d40SFabiano Rosas 3575f0984d40SFabiano Rosas #define DO_SVE2_RRXR_TB(NAME, FUNC, TOP) \ 3576f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve2, gen_gvec_ool_zzzz, FUNC, \ 3577f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, (a->index << 1) | TOP) 3578f0984d40SFabiano Rosas 3579f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLALB_zzxw_s, gen_helper_sve2_sqdmlal_idx_s, false) 3580f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLALB_zzxw_d, gen_helper_sve2_sqdmlal_idx_d, false) 3581f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLALT_zzxw_s, gen_helper_sve2_sqdmlal_idx_s, true) 3582f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLALT_zzxw_d, gen_helper_sve2_sqdmlal_idx_d, true) 3583f0984d40SFabiano Rosas 3584f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLSLB_zzxw_s, gen_helper_sve2_sqdmlsl_idx_s, false) 3585f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLSLB_zzxw_d, gen_helper_sve2_sqdmlsl_idx_d, false) 3586f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLSLT_zzxw_s, gen_helper_sve2_sqdmlsl_idx_s, true) 3587f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SQDMLSLT_zzxw_d, gen_helper_sve2_sqdmlsl_idx_d, true) 3588f0984d40SFabiano Rosas 3589f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLALB_zzxw_s, gen_helper_sve2_smlal_idx_s, false) 3590f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLALB_zzxw_d, gen_helper_sve2_smlal_idx_d, false) 3591f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLALT_zzxw_s, gen_helper_sve2_smlal_idx_s, true) 3592f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLALT_zzxw_d, gen_helper_sve2_smlal_idx_d, true) 3593f0984d40SFabiano Rosas 3594f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLALB_zzxw_s, gen_helper_sve2_umlal_idx_s, false) 3595f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLALB_zzxw_d, gen_helper_sve2_umlal_idx_d, false) 3596f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLALT_zzxw_s, gen_helper_sve2_umlal_idx_s, true) 3597f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLALT_zzxw_d, gen_helper_sve2_umlal_idx_d, true) 3598f0984d40SFabiano Rosas 3599f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLSLB_zzxw_s, gen_helper_sve2_smlsl_idx_s, false) 3600f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLSLB_zzxw_d, gen_helper_sve2_smlsl_idx_d, false) 3601f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLSLT_zzxw_s, gen_helper_sve2_smlsl_idx_s, true) 3602f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(SMLSLT_zzxw_d, gen_helper_sve2_smlsl_idx_d, true) 3603f0984d40SFabiano Rosas 3604f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLSLB_zzxw_s, gen_helper_sve2_umlsl_idx_s, false) 3605f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLSLB_zzxw_d, gen_helper_sve2_umlsl_idx_d, false) 3606f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLSLT_zzxw_s, gen_helper_sve2_umlsl_idx_s, true) 3607f0984d40SFabiano Rosas DO_SVE2_RRXR_TB(UMLSLT_zzxw_d, gen_helper_sve2_umlsl_idx_d, true) 3608f0984d40SFabiano Rosas 3609f0984d40SFabiano Rosas #undef DO_SVE2_RRXR_TB 3610f0984d40SFabiano Rosas 3611f0984d40SFabiano Rosas #define DO_SVE2_RRXR_ROT(NAME, FUNC) \ 3612f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve2, gen_gvec_ool_zzzz, FUNC, \ 3613f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, (a->index << 2) | a->rot) 3614f0984d40SFabiano Rosas 3615f0984d40SFabiano Rosas DO_SVE2_RRXR_ROT(CMLA_zzxz_h, gen_helper_sve2_cmla_idx_h) 3616f0984d40SFabiano Rosas DO_SVE2_RRXR_ROT(CMLA_zzxz_s, gen_helper_sve2_cmla_idx_s) 3617f0984d40SFabiano Rosas 3618f0984d40SFabiano Rosas DO_SVE2_RRXR_ROT(SQRDCMLAH_zzxz_h, gen_helper_sve2_sqrdcmlah_idx_h) 3619f0984d40SFabiano Rosas DO_SVE2_RRXR_ROT(SQRDCMLAH_zzxz_s, gen_helper_sve2_sqrdcmlah_idx_s) 3620f0984d40SFabiano Rosas 3621f0984d40SFabiano Rosas DO_SVE2_RRXR_ROT(CDOT_zzxw_s, gen_helper_sve2_cdot_idx_s) 3622f0984d40SFabiano Rosas DO_SVE2_RRXR_ROT(CDOT_zzxw_d, gen_helper_sve2_cdot_idx_d) 3623f0984d40SFabiano Rosas 3624f0984d40SFabiano Rosas #undef DO_SVE2_RRXR_ROT 3625f0984d40SFabiano Rosas 3626f0984d40SFabiano Rosas /* 3627f0984d40SFabiano Rosas *** SVE Floating Point Multiply-Add Indexed Group 3628f0984d40SFabiano Rosas */ 3629f0984d40SFabiano Rosas 3630f0984d40SFabiano Rosas static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub) 3631f0984d40SFabiano Rosas { 3632f0984d40SFabiano Rosas static gen_helper_gvec_4_ptr * const fns[4] = { 3633f0984d40SFabiano Rosas NULL, 3634f0984d40SFabiano Rosas gen_helper_gvec_fmla_idx_h, 3635f0984d40SFabiano Rosas gen_helper_gvec_fmla_idx_s, 3636f0984d40SFabiano Rosas gen_helper_gvec_fmla_idx_d, 3637f0984d40SFabiano Rosas }; 3638f0984d40SFabiano Rosas return gen_gvec_fpst_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, 3639f0984d40SFabiano Rosas (a->index << 1) | sub, 3640f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 3641f0984d40SFabiano Rosas } 3642f0984d40SFabiano Rosas 3643f0984d40SFabiano Rosas TRANS_FEAT(FMLA_zzxz, aa64_sve, do_FMLA_zzxz, a, false) 3644f0984d40SFabiano Rosas TRANS_FEAT(FMLS_zzxz, aa64_sve, do_FMLA_zzxz, a, true) 3645f0984d40SFabiano Rosas 3646f0984d40SFabiano Rosas /* 3647f0984d40SFabiano Rosas *** SVE Floating Point Multiply Indexed Group 3648f0984d40SFabiano Rosas */ 3649f0984d40SFabiano Rosas 3650f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const fmul_idx_fns[4] = { 3651f0984d40SFabiano Rosas NULL, gen_helper_gvec_fmul_idx_h, 3652f0984d40SFabiano Rosas gen_helper_gvec_fmul_idx_s, gen_helper_gvec_fmul_idx_d, 3653f0984d40SFabiano Rosas }; 3654f0984d40SFabiano Rosas TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz, 3655f0984d40SFabiano Rosas fmul_idx_fns[a->esz], a->rd, a->rn, a->rm, a->index, 3656f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 3657f0984d40SFabiano Rosas 3658f0984d40SFabiano Rosas /* 3659f0984d40SFabiano Rosas *** SVE Floating Point Fast Reduction Group 3660f0984d40SFabiano Rosas */ 3661f0984d40SFabiano Rosas 3662f0984d40SFabiano Rosas typedef void gen_helper_fp_reduce(TCGv_i64, TCGv_ptr, TCGv_ptr, 3663f0984d40SFabiano Rosas TCGv_ptr, TCGv_i32); 3664f0984d40SFabiano Rosas 3665f0984d40SFabiano Rosas static bool do_reduce(DisasContext *s, arg_rpr_esz *a, 3666f0984d40SFabiano Rosas gen_helper_fp_reduce *fn) 3667f0984d40SFabiano Rosas { 3668f0984d40SFabiano Rosas unsigned vsz, p2vsz; 3669f0984d40SFabiano Rosas TCGv_i32 t_desc; 3670f0984d40SFabiano Rosas TCGv_ptr t_zn, t_pg, status; 3671f0984d40SFabiano Rosas TCGv_i64 temp; 3672f0984d40SFabiano Rosas 3673f0984d40SFabiano Rosas if (fn == NULL) { 3674f0984d40SFabiano Rosas return false; 3675f0984d40SFabiano Rosas } 3676f0984d40SFabiano Rosas if (!sve_access_check(s)) { 3677f0984d40SFabiano Rosas return true; 3678f0984d40SFabiano Rosas } 3679f0984d40SFabiano Rosas 3680f0984d40SFabiano Rosas vsz = vec_full_reg_size(s); 3681f0984d40SFabiano Rosas p2vsz = pow2ceil(vsz); 3682f0984d40SFabiano Rosas t_desc = tcg_constant_i32(simd_desc(vsz, vsz, p2vsz)); 3683f0984d40SFabiano Rosas temp = tcg_temp_new_i64(); 3684f0984d40SFabiano Rosas t_zn = tcg_temp_new_ptr(); 3685f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 3686f0984d40SFabiano Rosas 3687*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn)); 3688*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); 3689f0984d40SFabiano Rosas status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 3690f0984d40SFabiano Rosas 3691f0984d40SFabiano Rosas fn(temp, t_zn, t_pg, status, t_desc); 3692f0984d40SFabiano Rosas 3693f0984d40SFabiano Rosas write_fp_dreg(s, a->rd, temp); 3694f0984d40SFabiano Rosas return true; 3695f0984d40SFabiano Rosas } 3696f0984d40SFabiano Rosas 3697f0984d40SFabiano Rosas #define DO_VPZ(NAME, name) \ 3698f0984d40SFabiano Rosas static gen_helper_fp_reduce * const name##_fns[4] = { \ 3699f0984d40SFabiano Rosas NULL, gen_helper_sve_##name##_h, \ 3700f0984d40SFabiano Rosas gen_helper_sve_##name##_s, gen_helper_sve_##name##_d, \ 3701f0984d40SFabiano Rosas }; \ 3702f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, do_reduce, a, name##_fns[a->esz]) 3703f0984d40SFabiano Rosas 3704f0984d40SFabiano Rosas DO_VPZ(FADDV, faddv) 3705f0984d40SFabiano Rosas DO_VPZ(FMINNMV, fminnmv) 3706f0984d40SFabiano Rosas DO_VPZ(FMAXNMV, fmaxnmv) 3707f0984d40SFabiano Rosas DO_VPZ(FMINV, fminv) 3708f0984d40SFabiano Rosas DO_VPZ(FMAXV, fmaxv) 3709f0984d40SFabiano Rosas 3710f0984d40SFabiano Rosas #undef DO_VPZ 3711f0984d40SFabiano Rosas 3712f0984d40SFabiano Rosas /* 3713f0984d40SFabiano Rosas *** SVE Floating Point Unary Operations - Unpredicated Group 3714f0984d40SFabiano Rosas */ 3715f0984d40SFabiano Rosas 3716f0984d40SFabiano Rosas static gen_helper_gvec_2_ptr * const frecpe_fns[] = { 3717f0984d40SFabiano Rosas NULL, gen_helper_gvec_frecpe_h, 3718f0984d40SFabiano Rosas gen_helper_gvec_frecpe_s, gen_helper_gvec_frecpe_d, 3719f0984d40SFabiano Rosas }; 3720f0984d40SFabiano Rosas TRANS_FEAT(FRECPE, aa64_sve, gen_gvec_fpst_arg_zz, frecpe_fns[a->esz], a, 0) 3721f0984d40SFabiano Rosas 3722f0984d40SFabiano Rosas static gen_helper_gvec_2_ptr * const frsqrte_fns[] = { 3723f0984d40SFabiano Rosas NULL, gen_helper_gvec_frsqrte_h, 3724f0984d40SFabiano Rosas gen_helper_gvec_frsqrte_s, gen_helper_gvec_frsqrte_d, 3725f0984d40SFabiano Rosas }; 3726f0984d40SFabiano Rosas TRANS_FEAT(FRSQRTE, aa64_sve, gen_gvec_fpst_arg_zz, frsqrte_fns[a->esz], a, 0) 3727f0984d40SFabiano Rosas 3728f0984d40SFabiano Rosas /* 3729f0984d40SFabiano Rosas *** SVE Floating Point Compare with Zero Group 3730f0984d40SFabiano Rosas */ 3731f0984d40SFabiano Rosas 3732f0984d40SFabiano Rosas static bool do_ppz_fp(DisasContext *s, arg_rpr_esz *a, 3733f0984d40SFabiano Rosas gen_helper_gvec_3_ptr *fn) 3734f0984d40SFabiano Rosas { 3735f0984d40SFabiano Rosas if (fn == NULL) { 3736f0984d40SFabiano Rosas return false; 3737f0984d40SFabiano Rosas } 3738f0984d40SFabiano Rosas if (sve_access_check(s)) { 3739f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3740f0984d40SFabiano Rosas TCGv_ptr status = 3741f0984d40SFabiano Rosas fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 3742f0984d40SFabiano Rosas 3743f0984d40SFabiano Rosas tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd), 3744f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 3745f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pg), 3746f0984d40SFabiano Rosas status, vsz, vsz, 0, fn); 3747f0984d40SFabiano Rosas } 3748f0984d40SFabiano Rosas return true; 3749f0984d40SFabiano Rosas } 3750f0984d40SFabiano Rosas 3751f0984d40SFabiano Rosas #define DO_PPZ(NAME, name) \ 3752f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const name##_fns[] = { \ 3753f0984d40SFabiano Rosas NULL, gen_helper_sve_##name##_h, \ 3754f0984d40SFabiano Rosas gen_helper_sve_##name##_s, gen_helper_sve_##name##_d, \ 3755f0984d40SFabiano Rosas }; \ 3756f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, do_ppz_fp, a, name##_fns[a->esz]) 3757f0984d40SFabiano Rosas 3758f0984d40SFabiano Rosas DO_PPZ(FCMGE_ppz0, fcmge0) 3759f0984d40SFabiano Rosas DO_PPZ(FCMGT_ppz0, fcmgt0) 3760f0984d40SFabiano Rosas DO_PPZ(FCMLE_ppz0, fcmle0) 3761f0984d40SFabiano Rosas DO_PPZ(FCMLT_ppz0, fcmlt0) 3762f0984d40SFabiano Rosas DO_PPZ(FCMEQ_ppz0, fcmeq0) 3763f0984d40SFabiano Rosas DO_PPZ(FCMNE_ppz0, fcmne0) 3764f0984d40SFabiano Rosas 3765f0984d40SFabiano Rosas #undef DO_PPZ 3766f0984d40SFabiano Rosas 3767f0984d40SFabiano Rosas /* 3768f0984d40SFabiano Rosas *** SVE floating-point trig multiply-add coefficient 3769f0984d40SFabiano Rosas */ 3770f0984d40SFabiano Rosas 3771f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const ftmad_fns[4] = { 3772f0984d40SFabiano Rosas NULL, gen_helper_sve_ftmad_h, 3773f0984d40SFabiano Rosas gen_helper_sve_ftmad_s, gen_helper_sve_ftmad_d, 3774f0984d40SFabiano Rosas }; 3775f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz, 3776f0984d40SFabiano Rosas ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm, 3777f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 3778f0984d40SFabiano Rosas 3779f0984d40SFabiano Rosas /* 3780f0984d40SFabiano Rosas *** SVE Floating Point Accumulating Reduction Group 3781f0984d40SFabiano Rosas */ 3782f0984d40SFabiano Rosas 3783f0984d40SFabiano Rosas static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a) 3784f0984d40SFabiano Rosas { 3785f0984d40SFabiano Rosas typedef void fadda_fn(TCGv_i64, TCGv_i64, TCGv_ptr, 3786f0984d40SFabiano Rosas TCGv_ptr, TCGv_ptr, TCGv_i32); 3787f0984d40SFabiano Rosas static fadda_fn * const fns[3] = { 3788f0984d40SFabiano Rosas gen_helper_sve_fadda_h, 3789f0984d40SFabiano Rosas gen_helper_sve_fadda_s, 3790f0984d40SFabiano Rosas gen_helper_sve_fadda_d, 3791f0984d40SFabiano Rosas }; 3792f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3793f0984d40SFabiano Rosas TCGv_ptr t_rm, t_pg, t_fpst; 3794f0984d40SFabiano Rosas TCGv_i64 t_val; 3795f0984d40SFabiano Rosas TCGv_i32 t_desc; 3796f0984d40SFabiano Rosas 3797f0984d40SFabiano Rosas if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) { 3798f0984d40SFabiano Rosas return false; 3799f0984d40SFabiano Rosas } 3800f0984d40SFabiano Rosas s->is_nonstreaming = true; 3801f0984d40SFabiano Rosas if (!sve_access_check(s)) { 3802f0984d40SFabiano Rosas return true; 3803f0984d40SFabiano Rosas } 3804f0984d40SFabiano Rosas 3805*ad75a51eSRichard Henderson t_val = load_esz(tcg_env, vec_reg_offset(s, a->rn, 0, a->esz), a->esz); 3806f0984d40SFabiano Rosas t_rm = tcg_temp_new_ptr(); 3807f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 3808*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_rm, tcg_env, vec_full_reg_offset(s, a->rm)); 3809*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); 3810f0984d40SFabiano Rosas t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 3811f0984d40SFabiano Rosas t_desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 3812f0984d40SFabiano Rosas 3813f0984d40SFabiano Rosas fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc); 3814f0984d40SFabiano Rosas 3815f0984d40SFabiano Rosas write_fp_dreg(s, a->rd, t_val); 3816f0984d40SFabiano Rosas return true; 3817f0984d40SFabiano Rosas } 3818f0984d40SFabiano Rosas 3819f0984d40SFabiano Rosas /* 3820f0984d40SFabiano Rosas *** SVE Floating Point Arithmetic - Unpredicated Group 3821f0984d40SFabiano Rosas */ 3822f0984d40SFabiano Rosas 3823f0984d40SFabiano Rosas #define DO_FP3(NAME, name) \ 3824f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const name##_fns[4] = { \ 3825f0984d40SFabiano Rosas NULL, gen_helper_gvec_##name##_h, \ 3826f0984d40SFabiano Rosas gen_helper_gvec_##name##_s, gen_helper_gvec_##name##_d \ 3827f0984d40SFabiano Rosas }; \ 3828f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_arg_zzz, name##_fns[a->esz], a, 0) 3829f0984d40SFabiano Rosas 3830f0984d40SFabiano Rosas DO_FP3(FADD_zzz, fadd) 3831f0984d40SFabiano Rosas DO_FP3(FSUB_zzz, fsub) 3832f0984d40SFabiano Rosas DO_FP3(FMUL_zzz, fmul) 3833f0984d40SFabiano Rosas DO_FP3(FRECPS, recps) 3834f0984d40SFabiano Rosas DO_FP3(FRSQRTS, rsqrts) 3835f0984d40SFabiano Rosas 3836f0984d40SFabiano Rosas #undef DO_FP3 3837f0984d40SFabiano Rosas 3838f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const ftsmul_fns[4] = { 3839f0984d40SFabiano Rosas NULL, gen_helper_gvec_ftsmul_h, 3840f0984d40SFabiano Rosas gen_helper_gvec_ftsmul_s, gen_helper_gvec_ftsmul_d 3841f0984d40SFabiano Rosas }; 3842f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(FTSMUL, aa64_sve, gen_gvec_fpst_arg_zzz, 3843f0984d40SFabiano Rosas ftsmul_fns[a->esz], a, 0) 3844f0984d40SFabiano Rosas 3845f0984d40SFabiano Rosas /* 3846f0984d40SFabiano Rosas *** SVE Floating Point Arithmetic - Predicated Group 3847f0984d40SFabiano Rosas */ 3848f0984d40SFabiano Rosas 3849f0984d40SFabiano Rosas #define DO_ZPZZ_FP(NAME, FEAT, name) \ 3850f0984d40SFabiano Rosas static gen_helper_gvec_4_ptr * const name##_zpzz_fns[4] = { \ 3851f0984d40SFabiano Rosas NULL, gen_helper_##name##_h, \ 3852f0984d40SFabiano Rosas gen_helper_##name##_s, gen_helper_##name##_d \ 3853f0984d40SFabiano Rosas }; \ 3854f0984d40SFabiano Rosas TRANS_FEAT(NAME, FEAT, gen_gvec_fpst_arg_zpzz, name##_zpzz_fns[a->esz], a) 3855f0984d40SFabiano Rosas 3856f0984d40SFabiano Rosas DO_ZPZZ_FP(FADD_zpzz, aa64_sve, sve_fadd) 3857f0984d40SFabiano Rosas DO_ZPZZ_FP(FSUB_zpzz, aa64_sve, sve_fsub) 3858f0984d40SFabiano Rosas DO_ZPZZ_FP(FMUL_zpzz, aa64_sve, sve_fmul) 3859f0984d40SFabiano Rosas DO_ZPZZ_FP(FMIN_zpzz, aa64_sve, sve_fmin) 3860f0984d40SFabiano Rosas DO_ZPZZ_FP(FMAX_zpzz, aa64_sve, sve_fmax) 3861f0984d40SFabiano Rosas DO_ZPZZ_FP(FMINNM_zpzz, aa64_sve, sve_fminnum) 3862f0984d40SFabiano Rosas DO_ZPZZ_FP(FMAXNM_zpzz, aa64_sve, sve_fmaxnum) 3863f0984d40SFabiano Rosas DO_ZPZZ_FP(FABD, aa64_sve, sve_fabd) 3864f0984d40SFabiano Rosas DO_ZPZZ_FP(FSCALE, aa64_sve, sve_fscalbn) 3865f0984d40SFabiano Rosas DO_ZPZZ_FP(FDIV, aa64_sve, sve_fdiv) 3866f0984d40SFabiano Rosas DO_ZPZZ_FP(FMULX, aa64_sve, sve_fmulx) 3867f0984d40SFabiano Rosas 3868f0984d40SFabiano Rosas typedef void gen_helper_sve_fp2scalar(TCGv_ptr, TCGv_ptr, TCGv_ptr, 3869f0984d40SFabiano Rosas TCGv_i64, TCGv_ptr, TCGv_i32); 3870f0984d40SFabiano Rosas 3871f0984d40SFabiano Rosas static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16, 3872f0984d40SFabiano Rosas TCGv_i64 scalar, gen_helper_sve_fp2scalar *fn) 3873f0984d40SFabiano Rosas { 3874f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3875f0984d40SFabiano Rosas TCGv_ptr t_zd, t_zn, t_pg, status; 3876f0984d40SFabiano Rosas TCGv_i32 desc; 3877f0984d40SFabiano Rosas 3878f0984d40SFabiano Rosas t_zd = tcg_temp_new_ptr(); 3879f0984d40SFabiano Rosas t_zn = tcg_temp_new_ptr(); 3880f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 3881*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zd, tcg_env, vec_full_reg_offset(s, zd)); 3882*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, zn)); 3883*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); 3884f0984d40SFabiano Rosas 3885f0984d40SFabiano Rosas status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); 3886f0984d40SFabiano Rosas desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); 3887f0984d40SFabiano Rosas fn(t_zd, t_zn, t_pg, scalar, status, desc); 3888f0984d40SFabiano Rosas } 3889f0984d40SFabiano Rosas 3890f0984d40SFabiano Rosas static bool do_fp_imm(DisasContext *s, arg_rpri_esz *a, uint64_t imm, 3891f0984d40SFabiano Rosas gen_helper_sve_fp2scalar *fn) 3892f0984d40SFabiano Rosas { 3893f0984d40SFabiano Rosas if (fn == NULL) { 3894f0984d40SFabiano Rosas return false; 3895f0984d40SFabiano Rosas } 3896f0984d40SFabiano Rosas if (sve_access_check(s)) { 3897f0984d40SFabiano Rosas do_fp_scalar(s, a->rd, a->rn, a->pg, a->esz == MO_16, 3898f0984d40SFabiano Rosas tcg_constant_i64(imm), fn); 3899f0984d40SFabiano Rosas } 3900f0984d40SFabiano Rosas return true; 3901f0984d40SFabiano Rosas } 3902f0984d40SFabiano Rosas 3903f0984d40SFabiano Rosas #define DO_FP_IMM(NAME, name, const0, const1) \ 3904f0984d40SFabiano Rosas static gen_helper_sve_fp2scalar * const name##_fns[4] = { \ 3905f0984d40SFabiano Rosas NULL, gen_helper_sve_##name##_h, \ 3906f0984d40SFabiano Rosas gen_helper_sve_##name##_s, \ 3907f0984d40SFabiano Rosas gen_helper_sve_##name##_d \ 3908f0984d40SFabiano Rosas }; \ 3909f0984d40SFabiano Rosas static uint64_t const name##_const[4][2] = { \ 3910f0984d40SFabiano Rosas { -1, -1 }, \ 3911f0984d40SFabiano Rosas { float16_##const0, float16_##const1 }, \ 3912f0984d40SFabiano Rosas { float32_##const0, float32_##const1 }, \ 3913f0984d40SFabiano Rosas { float64_##const0, float64_##const1 }, \ 3914f0984d40SFabiano Rosas }; \ 3915f0984d40SFabiano Rosas TRANS_FEAT(NAME##_zpzi, aa64_sve, do_fp_imm, a, \ 3916f0984d40SFabiano Rosas name##_const[a->esz][a->imm], name##_fns[a->esz]) 3917f0984d40SFabiano Rosas 3918f0984d40SFabiano Rosas DO_FP_IMM(FADD, fadds, half, one) 3919f0984d40SFabiano Rosas DO_FP_IMM(FSUB, fsubs, half, one) 3920f0984d40SFabiano Rosas DO_FP_IMM(FMUL, fmuls, half, two) 3921f0984d40SFabiano Rosas DO_FP_IMM(FSUBR, fsubrs, half, one) 3922f0984d40SFabiano Rosas DO_FP_IMM(FMAXNM, fmaxnms, zero, one) 3923f0984d40SFabiano Rosas DO_FP_IMM(FMINNM, fminnms, zero, one) 3924f0984d40SFabiano Rosas DO_FP_IMM(FMAX, fmaxs, zero, one) 3925f0984d40SFabiano Rosas DO_FP_IMM(FMIN, fmins, zero, one) 3926f0984d40SFabiano Rosas 3927f0984d40SFabiano Rosas #undef DO_FP_IMM 3928f0984d40SFabiano Rosas 3929f0984d40SFabiano Rosas static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a, 3930f0984d40SFabiano Rosas gen_helper_gvec_4_ptr *fn) 3931f0984d40SFabiano Rosas { 3932f0984d40SFabiano Rosas if (fn == NULL) { 3933f0984d40SFabiano Rosas return false; 3934f0984d40SFabiano Rosas } 3935f0984d40SFabiano Rosas if (sve_access_check(s)) { 3936f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 3937f0984d40SFabiano Rosas TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 3938f0984d40SFabiano Rosas tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd), 3939f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 3940f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rm), 3941f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pg), 3942f0984d40SFabiano Rosas status, vsz, vsz, 0, fn); 3943f0984d40SFabiano Rosas } 3944f0984d40SFabiano Rosas return true; 3945f0984d40SFabiano Rosas } 3946f0984d40SFabiano Rosas 3947f0984d40SFabiano Rosas #define DO_FPCMP(NAME, name) \ 3948f0984d40SFabiano Rosas static gen_helper_gvec_4_ptr * const name##_fns[4] = { \ 3949f0984d40SFabiano Rosas NULL, gen_helper_sve_##name##_h, \ 3950f0984d40SFabiano Rosas gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \ 3951f0984d40SFabiano Rosas }; \ 3952f0984d40SFabiano Rosas TRANS_FEAT(NAME##_ppzz, aa64_sve, do_fp_cmp, a, name##_fns[a->esz]) 3953f0984d40SFabiano Rosas 3954f0984d40SFabiano Rosas DO_FPCMP(FCMGE, fcmge) 3955f0984d40SFabiano Rosas DO_FPCMP(FCMGT, fcmgt) 3956f0984d40SFabiano Rosas DO_FPCMP(FCMEQ, fcmeq) 3957f0984d40SFabiano Rosas DO_FPCMP(FCMNE, fcmne) 3958f0984d40SFabiano Rosas DO_FPCMP(FCMUO, fcmuo) 3959f0984d40SFabiano Rosas DO_FPCMP(FACGE, facge) 3960f0984d40SFabiano Rosas DO_FPCMP(FACGT, facgt) 3961f0984d40SFabiano Rosas 3962f0984d40SFabiano Rosas #undef DO_FPCMP 3963f0984d40SFabiano Rosas 3964f0984d40SFabiano Rosas static gen_helper_gvec_4_ptr * const fcadd_fns[] = { 3965f0984d40SFabiano Rosas NULL, gen_helper_sve_fcadd_h, 3966f0984d40SFabiano Rosas gen_helper_sve_fcadd_s, gen_helper_sve_fcadd_d, 3967f0984d40SFabiano Rosas }; 3968f0984d40SFabiano Rosas TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz], 3969f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->pg, a->rot, 3970f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 3971f0984d40SFabiano Rosas 3972f0984d40SFabiano Rosas #define DO_FMLA(NAME, name) \ 3973f0984d40SFabiano Rosas static gen_helper_gvec_5_ptr * const name##_fns[4] = { \ 3974f0984d40SFabiano Rosas NULL, gen_helper_sve_##name##_h, \ 3975f0984d40SFabiano Rosas gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \ 3976f0984d40SFabiano Rosas }; \ 3977f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_zzzzp, name##_fns[a->esz], \ 3978f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, a->pg, 0, \ 3979f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 3980f0984d40SFabiano Rosas 3981f0984d40SFabiano Rosas DO_FMLA(FMLA_zpzzz, fmla_zpzzz) 3982f0984d40SFabiano Rosas DO_FMLA(FMLS_zpzzz, fmls_zpzzz) 3983f0984d40SFabiano Rosas DO_FMLA(FNMLA_zpzzz, fnmla_zpzzz) 3984f0984d40SFabiano Rosas DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz) 3985f0984d40SFabiano Rosas 3986f0984d40SFabiano Rosas #undef DO_FMLA 3987f0984d40SFabiano Rosas 3988f0984d40SFabiano Rosas static gen_helper_gvec_5_ptr * const fcmla_fns[4] = { 3989f0984d40SFabiano Rosas NULL, gen_helper_sve_fcmla_zpzzz_h, 3990f0984d40SFabiano Rosas gen_helper_sve_fcmla_zpzzz_s, gen_helper_sve_fcmla_zpzzz_d, 3991f0984d40SFabiano Rosas }; 3992f0984d40SFabiano Rosas TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_zzzzp, fcmla_fns[a->esz], 3993f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, a->pg, a->rot, 3994f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 3995f0984d40SFabiano Rosas 3996f0984d40SFabiano Rosas static gen_helper_gvec_4_ptr * const fcmla_idx_fns[4] = { 3997f0984d40SFabiano Rosas NULL, gen_helper_gvec_fcmlah_idx, gen_helper_gvec_fcmlas_idx, NULL 3998f0984d40SFabiano Rosas }; 3999f0984d40SFabiano Rosas TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_zzzz, fcmla_idx_fns[a->esz], 4000f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, a->index * 4 + a->rot, 4001f0984d40SFabiano Rosas a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 4002f0984d40SFabiano Rosas 4003f0984d40SFabiano Rosas /* 4004f0984d40SFabiano Rosas *** SVE Floating Point Unary Operations Predicated Group 4005f0984d40SFabiano Rosas */ 4006f0984d40SFabiano Rosas 4007f0984d40SFabiano Rosas TRANS_FEAT(FCVT_sh, aa64_sve, gen_gvec_fpst_arg_zpz, 4008f0984d40SFabiano Rosas gen_helper_sve_fcvt_sh, a, 0, FPST_FPCR) 4009f0984d40SFabiano Rosas TRANS_FEAT(FCVT_hs, aa64_sve, gen_gvec_fpst_arg_zpz, 4010f0984d40SFabiano Rosas gen_helper_sve_fcvt_hs, a, 0, FPST_FPCR) 4011f0984d40SFabiano Rosas 4012f0984d40SFabiano Rosas TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, 4013f0984d40SFabiano Rosas gen_helper_sve_bfcvt, a, 0, FPST_FPCR) 4014f0984d40SFabiano Rosas 4015f0984d40SFabiano Rosas TRANS_FEAT(FCVT_dh, aa64_sve, gen_gvec_fpst_arg_zpz, 4016f0984d40SFabiano Rosas gen_helper_sve_fcvt_dh, a, 0, FPST_FPCR) 4017f0984d40SFabiano Rosas TRANS_FEAT(FCVT_hd, aa64_sve, gen_gvec_fpst_arg_zpz, 4018f0984d40SFabiano Rosas gen_helper_sve_fcvt_hd, a, 0, FPST_FPCR) 4019f0984d40SFabiano Rosas TRANS_FEAT(FCVT_ds, aa64_sve, gen_gvec_fpst_arg_zpz, 4020f0984d40SFabiano Rosas gen_helper_sve_fcvt_ds, a, 0, FPST_FPCR) 4021f0984d40SFabiano Rosas TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz, 4022f0984d40SFabiano Rosas gen_helper_sve_fcvt_sd, a, 0, FPST_FPCR) 4023f0984d40SFabiano Rosas 4024f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_hh, aa64_sve, gen_gvec_fpst_arg_zpz, 4025f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_hh, a, 0, FPST_FPCR_F16) 4026f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_hh, aa64_sve, gen_gvec_fpst_arg_zpz, 4027f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_hh, a, 0, FPST_FPCR_F16) 4028f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_hs, aa64_sve, gen_gvec_fpst_arg_zpz, 4029f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_hs, a, 0, FPST_FPCR_F16) 4030f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_hs, aa64_sve, gen_gvec_fpst_arg_zpz, 4031f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_hs, a, 0, FPST_FPCR_F16) 4032f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_hd, aa64_sve, gen_gvec_fpst_arg_zpz, 4033f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_hd, a, 0, FPST_FPCR_F16) 4034f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_hd, aa64_sve, gen_gvec_fpst_arg_zpz, 4035f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_hd, a, 0, FPST_FPCR_F16) 4036f0984d40SFabiano Rosas 4037f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_ss, aa64_sve, gen_gvec_fpst_arg_zpz, 4038f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_ss, a, 0, FPST_FPCR) 4039f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_ss, aa64_sve, gen_gvec_fpst_arg_zpz, 4040f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_ss, a, 0, FPST_FPCR) 4041f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_sd, aa64_sve, gen_gvec_fpst_arg_zpz, 4042f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_sd, a, 0, FPST_FPCR) 4043f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_sd, aa64_sve, gen_gvec_fpst_arg_zpz, 4044f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_sd, a, 0, FPST_FPCR) 4045f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_ds, aa64_sve, gen_gvec_fpst_arg_zpz, 4046f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_ds, a, 0, FPST_FPCR) 4047f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_ds, aa64_sve, gen_gvec_fpst_arg_zpz, 4048f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_ds, a, 0, FPST_FPCR) 4049f0984d40SFabiano Rosas 4050f0984d40SFabiano Rosas TRANS_FEAT(FCVTZS_dd, aa64_sve, gen_gvec_fpst_arg_zpz, 4051f0984d40SFabiano Rosas gen_helper_sve_fcvtzs_dd, a, 0, FPST_FPCR) 4052f0984d40SFabiano Rosas TRANS_FEAT(FCVTZU_dd, aa64_sve, gen_gvec_fpst_arg_zpz, 4053f0984d40SFabiano Rosas gen_helper_sve_fcvtzu_dd, a, 0, FPST_FPCR) 4054f0984d40SFabiano Rosas 4055f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const frint_fns[] = { 4056f0984d40SFabiano Rosas NULL, 4057f0984d40SFabiano Rosas gen_helper_sve_frint_h, 4058f0984d40SFabiano Rosas gen_helper_sve_frint_s, 4059f0984d40SFabiano Rosas gen_helper_sve_frint_d 4060f0984d40SFabiano Rosas }; 4061f0984d40SFabiano Rosas TRANS_FEAT(FRINTI, aa64_sve, gen_gvec_fpst_arg_zpz, frint_fns[a->esz], 4062f0984d40SFabiano Rosas a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 4063f0984d40SFabiano Rosas 4064f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const frintx_fns[] = { 4065f0984d40SFabiano Rosas NULL, 4066f0984d40SFabiano Rosas gen_helper_sve_frintx_h, 4067f0984d40SFabiano Rosas gen_helper_sve_frintx_s, 4068f0984d40SFabiano Rosas gen_helper_sve_frintx_d 4069f0984d40SFabiano Rosas }; 4070f0984d40SFabiano Rosas TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, frintx_fns[a->esz], 4071f0984d40SFabiano Rosas a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 4072f0984d40SFabiano Rosas 4073f0984d40SFabiano Rosas static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, 407497584f2bSRichard Henderson ARMFPRounding mode, gen_helper_gvec_3_ptr *fn) 4075f0984d40SFabiano Rosas { 4076f0984d40SFabiano Rosas unsigned vsz; 4077f0984d40SFabiano Rosas TCGv_i32 tmode; 4078f0984d40SFabiano Rosas TCGv_ptr status; 4079f0984d40SFabiano Rosas 4080f0984d40SFabiano Rosas if (fn == NULL) { 4081f0984d40SFabiano Rosas return false; 4082f0984d40SFabiano Rosas } 4083f0984d40SFabiano Rosas if (!sve_access_check(s)) { 4084f0984d40SFabiano Rosas return true; 4085f0984d40SFabiano Rosas } 4086f0984d40SFabiano Rosas 4087f0984d40SFabiano Rosas vsz = vec_full_reg_size(s); 4088f0984d40SFabiano Rosas status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); 40898d1b02a6SRichard Henderson tmode = gen_set_rmode(mode, status); 4090f0984d40SFabiano Rosas 4091f0984d40SFabiano Rosas tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd), 4092f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 4093f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pg), 4094f0984d40SFabiano Rosas status, vsz, vsz, 0, fn); 4095f0984d40SFabiano Rosas 40968d1b02a6SRichard Henderson gen_restore_rmode(tmode, status); 4097f0984d40SFabiano Rosas return true; 4098f0984d40SFabiano Rosas } 4099f0984d40SFabiano Rosas 4100f0984d40SFabiano Rosas TRANS_FEAT(FRINTN, aa64_sve, do_frint_mode, a, 410197584f2bSRichard Henderson FPROUNDING_TIEEVEN, frint_fns[a->esz]) 4102f0984d40SFabiano Rosas TRANS_FEAT(FRINTP, aa64_sve, do_frint_mode, a, 410397584f2bSRichard Henderson FPROUNDING_POSINF, frint_fns[a->esz]) 4104f0984d40SFabiano Rosas TRANS_FEAT(FRINTM, aa64_sve, do_frint_mode, a, 410597584f2bSRichard Henderson FPROUNDING_NEGINF, frint_fns[a->esz]) 4106f0984d40SFabiano Rosas TRANS_FEAT(FRINTZ, aa64_sve, do_frint_mode, a, 410797584f2bSRichard Henderson FPROUNDING_ZERO, frint_fns[a->esz]) 4108f0984d40SFabiano Rosas TRANS_FEAT(FRINTA, aa64_sve, do_frint_mode, a, 410997584f2bSRichard Henderson FPROUNDING_TIEAWAY, frint_fns[a->esz]) 4110f0984d40SFabiano Rosas 4111f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const frecpx_fns[] = { 4112f0984d40SFabiano Rosas NULL, gen_helper_sve_frecpx_h, 4113f0984d40SFabiano Rosas gen_helper_sve_frecpx_s, gen_helper_sve_frecpx_d, 4114f0984d40SFabiano Rosas }; 4115f0984d40SFabiano Rosas TRANS_FEAT(FRECPX, aa64_sve, gen_gvec_fpst_arg_zpz, frecpx_fns[a->esz], 4116f0984d40SFabiano Rosas a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 4117f0984d40SFabiano Rosas 4118f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const fsqrt_fns[] = { 4119f0984d40SFabiano Rosas NULL, gen_helper_sve_fsqrt_h, 4120f0984d40SFabiano Rosas gen_helper_sve_fsqrt_s, gen_helper_sve_fsqrt_d, 4121f0984d40SFabiano Rosas }; 4122f0984d40SFabiano Rosas TRANS_FEAT(FSQRT, aa64_sve, gen_gvec_fpst_arg_zpz, fsqrt_fns[a->esz], 4123f0984d40SFabiano Rosas a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 4124f0984d40SFabiano Rosas 4125f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, 4126f0984d40SFabiano Rosas gen_helper_sve_scvt_hh, a, 0, FPST_FPCR_F16) 4127f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz, 4128f0984d40SFabiano Rosas gen_helper_sve_scvt_sh, a, 0, FPST_FPCR_F16) 4129f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, 4130f0984d40SFabiano Rosas gen_helper_sve_scvt_dh, a, 0, FPST_FPCR_F16) 4131f0984d40SFabiano Rosas 4132f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, 4133f0984d40SFabiano Rosas gen_helper_sve_scvt_ss, a, 0, FPST_FPCR) 4134f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz, 4135f0984d40SFabiano Rosas gen_helper_sve_scvt_ds, a, 0, FPST_FPCR) 4136f0984d40SFabiano Rosas 4137f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz, 4138f0984d40SFabiano Rosas gen_helper_sve_scvt_sd, a, 0, FPST_FPCR) 4139f0984d40SFabiano Rosas TRANS_FEAT(SCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, 4140f0984d40SFabiano Rosas gen_helper_sve_scvt_dd, a, 0, FPST_FPCR) 4141f0984d40SFabiano Rosas 4142f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, 4143f0984d40SFabiano Rosas gen_helper_sve_ucvt_hh, a, 0, FPST_FPCR_F16) 4144f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz, 4145f0984d40SFabiano Rosas gen_helper_sve_ucvt_sh, a, 0, FPST_FPCR_F16) 4146f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, 4147f0984d40SFabiano Rosas gen_helper_sve_ucvt_dh, a, 0, FPST_FPCR_F16) 4148f0984d40SFabiano Rosas 4149f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, 4150f0984d40SFabiano Rosas gen_helper_sve_ucvt_ss, a, 0, FPST_FPCR) 4151f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz, 4152f0984d40SFabiano Rosas gen_helper_sve_ucvt_ds, a, 0, FPST_FPCR) 4153f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz, 4154f0984d40SFabiano Rosas gen_helper_sve_ucvt_sd, a, 0, FPST_FPCR) 4155f0984d40SFabiano Rosas 4156f0984d40SFabiano Rosas TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, 4157f0984d40SFabiano Rosas gen_helper_sve_ucvt_dd, a, 0, FPST_FPCR) 4158f0984d40SFabiano Rosas 4159f0984d40SFabiano Rosas /* 4160f0984d40SFabiano Rosas *** SVE Memory - 32-bit Gather and Unsized Contiguous Group 4161f0984d40SFabiano Rosas */ 4162f0984d40SFabiano Rosas 4163f0984d40SFabiano Rosas /* Subroutine loading a vector register at VOFS of LEN bytes. 4164f0984d40SFabiano Rosas * The load should begin at the address Rn + IMM. 4165f0984d40SFabiano Rosas */ 4166f0984d40SFabiano Rosas 4167f0984d40SFabiano Rosas void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs, 4168f0984d40SFabiano Rosas int len, int rn, int imm) 4169f0984d40SFabiano Rosas { 4170e6dd5e78SRichard Henderson int len_align = QEMU_ALIGN_DOWN(len, 16); 4171e6dd5e78SRichard Henderson int len_remain = len % 16; 4172e6dd5e78SRichard Henderson int nparts = len / 16 + ctpop8(len_remain); 4173f0984d40SFabiano Rosas int midx = get_mem_index(s); 4174f0984d40SFabiano Rosas TCGv_i64 dirty_addr, clean_addr, t0, t1; 4175e6dd5e78SRichard Henderson TCGv_i128 t16; 4176f0984d40SFabiano Rosas 4177f0984d40SFabiano Rosas dirty_addr = tcg_temp_new_i64(); 4178f0984d40SFabiano Rosas tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm); 41793b97520cSRichard Henderson clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8); 4180f0984d40SFabiano Rosas 4181f0984d40SFabiano Rosas /* 4182f0984d40SFabiano Rosas * Note that unpredicated load/store of vector/predicate registers 4183f0984d40SFabiano Rosas * are defined as a stream of bytes, which equates to little-endian 4184f0984d40SFabiano Rosas * operations on larger quantities. 4185f0984d40SFabiano Rosas * Attempt to keep code expansion to a minimum by limiting the 4186f0984d40SFabiano Rosas * amount of unrolling done. 4187f0984d40SFabiano Rosas */ 4188f0984d40SFabiano Rosas if (nparts <= 4) { 4189f0984d40SFabiano Rosas int i; 4190f0984d40SFabiano Rosas 4191f0984d40SFabiano Rosas t0 = tcg_temp_new_i64(); 4192e6dd5e78SRichard Henderson t1 = tcg_temp_new_i64(); 4193e6dd5e78SRichard Henderson t16 = tcg_temp_new_i128(); 4194e6dd5e78SRichard Henderson 4195e6dd5e78SRichard Henderson for (i = 0; i < len_align; i += 16) { 4196e6dd5e78SRichard Henderson tcg_gen_qemu_ld_i128(t16, clean_addr, midx, 4197e6dd5e78SRichard Henderson MO_LE | MO_128 | MO_ATOM_NONE); 4198e6dd5e78SRichard Henderson tcg_gen_extr_i128_i64(t0, t1, t16); 4199f0984d40SFabiano Rosas tcg_gen_st_i64(t0, base, vofs + i); 4200e6dd5e78SRichard Henderson tcg_gen_st_i64(t1, base, vofs + i + 8); 4201e6dd5e78SRichard Henderson tcg_gen_addi_i64(clean_addr, clean_addr, 16); 4202f0984d40SFabiano Rosas } 4203f0984d40SFabiano Rosas } else { 4204f0984d40SFabiano Rosas TCGLabel *loop = gen_new_label(); 4205d6840b98SRichard Henderson TCGv_ptr tp, i = tcg_temp_new_ptr(); 4206f0984d40SFabiano Rosas 4207d6840b98SRichard Henderson tcg_gen_movi_ptr(i, 0); 4208f0984d40SFabiano Rosas gen_set_label(loop); 4209f0984d40SFabiano Rosas 4210e6dd5e78SRichard Henderson t16 = tcg_temp_new_i128(); 4211e6dd5e78SRichard Henderson tcg_gen_qemu_ld_i128(t16, clean_addr, midx, 4212e6dd5e78SRichard Henderson MO_LE | MO_128 | MO_ATOM_NONE); 4213e6dd5e78SRichard Henderson tcg_gen_addi_i64(clean_addr, clean_addr, 16); 4214f0984d40SFabiano Rosas 4215f0984d40SFabiano Rosas tp = tcg_temp_new_ptr(); 4216f0984d40SFabiano Rosas tcg_gen_add_ptr(tp, base, i); 4217e6dd5e78SRichard Henderson tcg_gen_addi_ptr(i, i, 16); 4218e6dd5e78SRichard Henderson 4219e6dd5e78SRichard Henderson t0 = tcg_temp_new_i64(); 4220e6dd5e78SRichard Henderson t1 = tcg_temp_new_i64(); 4221e6dd5e78SRichard Henderson tcg_gen_extr_i128_i64(t0, t1, t16); 4222e6dd5e78SRichard Henderson 4223f0984d40SFabiano Rosas tcg_gen_st_i64(t0, tp, vofs); 4224e6dd5e78SRichard Henderson tcg_gen_st_i64(t1, tp, vofs + 8); 4225f0984d40SFabiano Rosas 4226f0984d40SFabiano Rosas tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop); 4227f0984d40SFabiano Rosas } 4228f0984d40SFabiano Rosas 4229f0984d40SFabiano Rosas /* 4230f0984d40SFabiano Rosas * Predicate register loads can be any multiple of 2. 4231*ad75a51eSRichard Henderson * Note that we still store the entire 64-bit unit into tcg_env. 4232f0984d40SFabiano Rosas */ 4233e6dd5e78SRichard Henderson if (len_remain >= 8) { 4234e6dd5e78SRichard Henderson t0 = tcg_temp_new_i64(); 4235e6dd5e78SRichard Henderson tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE); 4236e6dd5e78SRichard Henderson tcg_gen_st_i64(t0, base, vofs + len_align); 4237e6dd5e78SRichard Henderson len_remain -= 8; 4238e6dd5e78SRichard Henderson len_align += 8; 4239e6dd5e78SRichard Henderson if (len_remain) { 4240e6dd5e78SRichard Henderson tcg_gen_addi_i64(clean_addr, clean_addr, 8); 4241e6dd5e78SRichard Henderson } 4242e6dd5e78SRichard Henderson } 4243f0984d40SFabiano Rosas if (len_remain) { 4244f0984d40SFabiano Rosas t0 = tcg_temp_new_i64(); 4245f0984d40SFabiano Rosas switch (len_remain) { 4246f0984d40SFabiano Rosas case 2: 4247f0984d40SFabiano Rosas case 4: 4248f0984d40SFabiano Rosas case 8: 4249f0984d40SFabiano Rosas tcg_gen_qemu_ld_i64(t0, clean_addr, midx, 4250e6dd5e78SRichard Henderson MO_LE | ctz32(len_remain) | MO_ATOM_NONE); 4251f0984d40SFabiano Rosas break; 4252f0984d40SFabiano Rosas 4253f0984d40SFabiano Rosas case 6: 4254f0984d40SFabiano Rosas t1 = tcg_temp_new_i64(); 4255e6dd5e78SRichard Henderson tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUL | MO_ATOM_NONE); 4256f0984d40SFabiano Rosas tcg_gen_addi_i64(clean_addr, clean_addr, 4); 4257e6dd5e78SRichard Henderson tcg_gen_qemu_ld_i64(t1, clean_addr, midx, MO_LEUW | MO_ATOM_NONE); 4258f0984d40SFabiano Rosas tcg_gen_deposit_i64(t0, t0, t1, 32, 32); 4259f0984d40SFabiano Rosas break; 4260f0984d40SFabiano Rosas 4261f0984d40SFabiano Rosas default: 4262f0984d40SFabiano Rosas g_assert_not_reached(); 4263f0984d40SFabiano Rosas } 4264f0984d40SFabiano Rosas tcg_gen_st_i64(t0, base, vofs + len_align); 4265f0984d40SFabiano Rosas } 4266f0984d40SFabiano Rosas } 4267f0984d40SFabiano Rosas 4268f0984d40SFabiano Rosas /* Similarly for stores. */ 4269f0984d40SFabiano Rosas void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs, 4270f0984d40SFabiano Rosas int len, int rn, int imm) 4271f0984d40SFabiano Rosas { 4272e6dd5e78SRichard Henderson int len_align = QEMU_ALIGN_DOWN(len, 16); 4273e6dd5e78SRichard Henderson int len_remain = len % 16; 4274e6dd5e78SRichard Henderson int nparts = len / 16 + ctpop8(len_remain); 4275f0984d40SFabiano Rosas int midx = get_mem_index(s); 4276e6dd5e78SRichard Henderson TCGv_i64 dirty_addr, clean_addr, t0, t1; 4277e6dd5e78SRichard Henderson TCGv_i128 t16; 4278f0984d40SFabiano Rosas 4279f0984d40SFabiano Rosas dirty_addr = tcg_temp_new_i64(); 4280f0984d40SFabiano Rosas tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm); 42813b97520cSRichard Henderson clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8); 4282f0984d40SFabiano Rosas 4283f0984d40SFabiano Rosas /* Note that unpredicated load/store of vector/predicate registers 4284f0984d40SFabiano Rosas * are defined as a stream of bytes, which equates to little-endian 4285f0984d40SFabiano Rosas * operations on larger quantities. There is no nice way to force 4286f0984d40SFabiano Rosas * a little-endian store for aarch64_be-linux-user out of line. 4287f0984d40SFabiano Rosas * 4288f0984d40SFabiano Rosas * Attempt to keep code expansion to a minimum by limiting the 4289f0984d40SFabiano Rosas * amount of unrolling done. 4290f0984d40SFabiano Rosas */ 4291f0984d40SFabiano Rosas if (nparts <= 4) { 4292f0984d40SFabiano Rosas int i; 4293f0984d40SFabiano Rosas 4294f0984d40SFabiano Rosas t0 = tcg_temp_new_i64(); 4295e6dd5e78SRichard Henderson t1 = tcg_temp_new_i64(); 4296e6dd5e78SRichard Henderson t16 = tcg_temp_new_i128(); 4297f0984d40SFabiano Rosas for (i = 0; i < len_align; i += 8) { 4298f0984d40SFabiano Rosas tcg_gen_ld_i64(t0, base, vofs + i); 4299e6dd5e78SRichard Henderson tcg_gen_ld_i64(t1, base, vofs + i + 8); 4300e6dd5e78SRichard Henderson tcg_gen_concat_i64_i128(t16, t0, t1); 4301e6dd5e78SRichard Henderson tcg_gen_qemu_st_i128(t16, clean_addr, midx, 4302e6dd5e78SRichard Henderson MO_LE | MO_128 | MO_ATOM_NONE); 4303e6dd5e78SRichard Henderson tcg_gen_addi_i64(clean_addr, clean_addr, 16); 4304f0984d40SFabiano Rosas } 4305f0984d40SFabiano Rosas } else { 4306f0984d40SFabiano Rosas TCGLabel *loop = gen_new_label(); 4307d6840b98SRichard Henderson TCGv_ptr tp, i = tcg_temp_new_ptr(); 4308f0984d40SFabiano Rosas 4309d6840b98SRichard Henderson tcg_gen_movi_ptr(i, 0); 4310f0984d40SFabiano Rosas gen_set_label(loop); 4311f0984d40SFabiano Rosas 4312f0984d40SFabiano Rosas t0 = tcg_temp_new_i64(); 4313e6dd5e78SRichard Henderson t1 = tcg_temp_new_i64(); 4314f0984d40SFabiano Rosas tp = tcg_temp_new_ptr(); 4315f0984d40SFabiano Rosas tcg_gen_add_ptr(tp, base, i); 4316f0984d40SFabiano Rosas tcg_gen_ld_i64(t0, tp, vofs); 4317e6dd5e78SRichard Henderson tcg_gen_ld_i64(t1, tp, vofs + 8); 4318e6dd5e78SRichard Henderson tcg_gen_addi_ptr(i, i, 16); 4319f0984d40SFabiano Rosas 4320e6dd5e78SRichard Henderson t16 = tcg_temp_new_i128(); 4321e6dd5e78SRichard Henderson tcg_gen_concat_i64_i128(t16, t0, t1); 4322e6dd5e78SRichard Henderson 4323e6dd5e78SRichard Henderson tcg_gen_qemu_st_i128(t16, clean_addr, midx, MO_LEUQ); 4324e6dd5e78SRichard Henderson tcg_gen_addi_i64(clean_addr, clean_addr, 16); 4325f0984d40SFabiano Rosas 4326f0984d40SFabiano Rosas tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop); 4327f0984d40SFabiano Rosas } 4328f0984d40SFabiano Rosas 4329f0984d40SFabiano Rosas /* Predicate register stores can be any multiple of 2. */ 4330e6dd5e78SRichard Henderson if (len_remain >= 8) { 4331e6dd5e78SRichard Henderson t0 = tcg_temp_new_i64(); 43327c347c73SRichard Henderson tcg_gen_ld_i64(t0, base, vofs + len_align); 4333e6dd5e78SRichard Henderson tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE); 4334e6dd5e78SRichard Henderson len_remain -= 8; 4335e6dd5e78SRichard Henderson len_align += 8; 4336e6dd5e78SRichard Henderson if (len_remain) { 4337e6dd5e78SRichard Henderson tcg_gen_addi_i64(clean_addr, clean_addr, 8); 4338e6dd5e78SRichard Henderson } 4339e6dd5e78SRichard Henderson } 4340f0984d40SFabiano Rosas if (len_remain) { 4341f0984d40SFabiano Rosas t0 = tcg_temp_new_i64(); 4342f0984d40SFabiano Rosas tcg_gen_ld_i64(t0, base, vofs + len_align); 4343f0984d40SFabiano Rosas 4344f0984d40SFabiano Rosas switch (len_remain) { 4345f0984d40SFabiano Rosas case 2: 4346f0984d40SFabiano Rosas case 4: 4347f0984d40SFabiano Rosas case 8: 4348f0984d40SFabiano Rosas tcg_gen_qemu_st_i64(t0, clean_addr, midx, 4349e6dd5e78SRichard Henderson MO_LE | ctz32(len_remain) | MO_ATOM_NONE); 4350f0984d40SFabiano Rosas break; 4351f0984d40SFabiano Rosas 4352f0984d40SFabiano Rosas case 6: 4353e6dd5e78SRichard Henderson tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUL | MO_ATOM_NONE); 4354f0984d40SFabiano Rosas tcg_gen_addi_i64(clean_addr, clean_addr, 4); 4355f0984d40SFabiano Rosas tcg_gen_shri_i64(t0, t0, 32); 4356e6dd5e78SRichard Henderson tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUW | MO_ATOM_NONE); 4357f0984d40SFabiano Rosas break; 4358f0984d40SFabiano Rosas 4359f0984d40SFabiano Rosas default: 4360f0984d40SFabiano Rosas g_assert_not_reached(); 4361f0984d40SFabiano Rosas } 4362f0984d40SFabiano Rosas } 4363f0984d40SFabiano Rosas } 4364f0984d40SFabiano Rosas 4365f0984d40SFabiano Rosas static bool trans_LDR_zri(DisasContext *s, arg_rri *a) 4366f0984d40SFabiano Rosas { 4367f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4368f0984d40SFabiano Rosas return false; 4369f0984d40SFabiano Rosas } 4370f0984d40SFabiano Rosas if (sve_access_check(s)) { 4371f0984d40SFabiano Rosas int size = vec_full_reg_size(s); 4372f0984d40SFabiano Rosas int off = vec_full_reg_offset(s, a->rd); 4373*ad75a51eSRichard Henderson gen_sve_ldr(s, tcg_env, off, size, a->rn, a->imm * size); 4374f0984d40SFabiano Rosas } 4375f0984d40SFabiano Rosas return true; 4376f0984d40SFabiano Rosas } 4377f0984d40SFabiano Rosas 4378f0984d40SFabiano Rosas static bool trans_LDR_pri(DisasContext *s, arg_rri *a) 4379f0984d40SFabiano Rosas { 4380f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4381f0984d40SFabiano Rosas return false; 4382f0984d40SFabiano Rosas } 4383f0984d40SFabiano Rosas if (sve_access_check(s)) { 4384f0984d40SFabiano Rosas int size = pred_full_reg_size(s); 4385f0984d40SFabiano Rosas int off = pred_full_reg_offset(s, a->rd); 4386*ad75a51eSRichard Henderson gen_sve_ldr(s, tcg_env, off, size, a->rn, a->imm * size); 4387f0984d40SFabiano Rosas } 4388f0984d40SFabiano Rosas return true; 4389f0984d40SFabiano Rosas } 4390f0984d40SFabiano Rosas 4391f0984d40SFabiano Rosas static bool trans_STR_zri(DisasContext *s, arg_rri *a) 4392f0984d40SFabiano Rosas { 4393f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4394f0984d40SFabiano Rosas return false; 4395f0984d40SFabiano Rosas } 4396f0984d40SFabiano Rosas if (sve_access_check(s)) { 4397f0984d40SFabiano Rosas int size = vec_full_reg_size(s); 4398f0984d40SFabiano Rosas int off = vec_full_reg_offset(s, a->rd); 4399*ad75a51eSRichard Henderson gen_sve_str(s, tcg_env, off, size, a->rn, a->imm * size); 4400f0984d40SFabiano Rosas } 4401f0984d40SFabiano Rosas return true; 4402f0984d40SFabiano Rosas } 4403f0984d40SFabiano Rosas 4404f0984d40SFabiano Rosas static bool trans_STR_pri(DisasContext *s, arg_rri *a) 4405f0984d40SFabiano Rosas { 4406f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4407f0984d40SFabiano Rosas return false; 4408f0984d40SFabiano Rosas } 4409f0984d40SFabiano Rosas if (sve_access_check(s)) { 4410f0984d40SFabiano Rosas int size = pred_full_reg_size(s); 4411f0984d40SFabiano Rosas int off = pred_full_reg_offset(s, a->rd); 4412*ad75a51eSRichard Henderson gen_sve_str(s, tcg_env, off, size, a->rn, a->imm * size); 4413f0984d40SFabiano Rosas } 4414f0984d40SFabiano Rosas return true; 4415f0984d40SFabiano Rosas } 4416f0984d40SFabiano Rosas 4417f0984d40SFabiano Rosas /* 4418f0984d40SFabiano Rosas *** SVE Memory - Contiguous Load Group 4419f0984d40SFabiano Rosas */ 4420f0984d40SFabiano Rosas 4421f0984d40SFabiano Rosas /* The memory mode of the dtype. */ 4422f0984d40SFabiano Rosas static const MemOp dtype_mop[16] = { 4423f0984d40SFabiano Rosas MO_UB, MO_UB, MO_UB, MO_UB, 4424f0984d40SFabiano Rosas MO_SL, MO_UW, MO_UW, MO_UW, 4425f0984d40SFabiano Rosas MO_SW, MO_SW, MO_UL, MO_UL, 4426f0984d40SFabiano Rosas MO_SB, MO_SB, MO_SB, MO_UQ 4427f0984d40SFabiano Rosas }; 4428f0984d40SFabiano Rosas 4429f0984d40SFabiano Rosas #define dtype_msz(x) (dtype_mop[x] & MO_SIZE) 4430f0984d40SFabiano Rosas 4431f0984d40SFabiano Rosas /* The vector element size of dtype. */ 4432f0984d40SFabiano Rosas static const uint8_t dtype_esz[16] = { 4433f0984d40SFabiano Rosas 0, 1, 2, 3, 4434f0984d40SFabiano Rosas 3, 1, 2, 3, 4435f0984d40SFabiano Rosas 3, 2, 2, 3, 4436f0984d40SFabiano Rosas 3, 2, 1, 3 4437f0984d40SFabiano Rosas }; 4438f0984d40SFabiano Rosas 4439f0984d40SFabiano Rosas static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, 4440f0984d40SFabiano Rosas int dtype, uint32_t mte_n, bool is_write, 4441f0984d40SFabiano Rosas gen_helper_gvec_mem *fn) 4442f0984d40SFabiano Rosas { 4443f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 4444f0984d40SFabiano Rosas TCGv_ptr t_pg; 4445f0984d40SFabiano Rosas int desc = 0; 4446f0984d40SFabiano Rosas 4447f0984d40SFabiano Rosas /* 4448f0984d40SFabiano Rosas * For e.g. LD4, there are not enough arguments to pass all 4 4449f0984d40SFabiano Rosas * registers as pointers, so encode the regno into the data field. 4450f0984d40SFabiano Rosas * For consistency, do this even for LD1. 4451f0984d40SFabiano Rosas */ 4452f0984d40SFabiano Rosas if (s->mte_active[0]) { 4453f0984d40SFabiano Rosas int msz = dtype_msz(dtype); 4454f0984d40SFabiano Rosas 4455f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s)); 4456f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid); 4457f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma); 4458f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write); 4459f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1); 4460f0984d40SFabiano Rosas desc <<= SVE_MTEDESC_SHIFT; 4461f0984d40SFabiano Rosas } else { 4462f0984d40SFabiano Rosas addr = clean_data_tbi(s, addr); 4463f0984d40SFabiano Rosas } 4464f0984d40SFabiano Rosas 4465f0984d40SFabiano Rosas desc = simd_desc(vsz, vsz, zt | desc); 4466f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 4467f0984d40SFabiano Rosas 4468*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); 4469*ad75a51eSRichard Henderson fn(tcg_env, t_pg, addr, tcg_constant_i32(desc)); 4470f0984d40SFabiano Rosas } 4471f0984d40SFabiano Rosas 4472f0984d40SFabiano Rosas /* Indexed by [mte][be][dtype][nreg] */ 4473f0984d40SFabiano Rosas static gen_helper_gvec_mem * const ldr_fns[2][2][16][4] = { 4474f0984d40SFabiano Rosas { /* mte inactive, little-endian */ 4475f0984d40SFabiano Rosas { { gen_helper_sve_ld1bb_r, gen_helper_sve_ld2bb_r, 4476f0984d40SFabiano Rosas gen_helper_sve_ld3bb_r, gen_helper_sve_ld4bb_r }, 4477f0984d40SFabiano Rosas { gen_helper_sve_ld1bhu_r, NULL, NULL, NULL }, 4478f0984d40SFabiano Rosas { gen_helper_sve_ld1bsu_r, NULL, NULL, NULL }, 4479f0984d40SFabiano Rosas { gen_helper_sve_ld1bdu_r, NULL, NULL, NULL }, 4480f0984d40SFabiano Rosas 4481f0984d40SFabiano Rosas { gen_helper_sve_ld1sds_le_r, NULL, NULL, NULL }, 4482f0984d40SFabiano Rosas { gen_helper_sve_ld1hh_le_r, gen_helper_sve_ld2hh_le_r, 4483f0984d40SFabiano Rosas gen_helper_sve_ld3hh_le_r, gen_helper_sve_ld4hh_le_r }, 4484f0984d40SFabiano Rosas { gen_helper_sve_ld1hsu_le_r, NULL, NULL, NULL }, 4485f0984d40SFabiano Rosas { gen_helper_sve_ld1hdu_le_r, NULL, NULL, NULL }, 4486f0984d40SFabiano Rosas 4487f0984d40SFabiano Rosas { gen_helper_sve_ld1hds_le_r, NULL, NULL, NULL }, 4488f0984d40SFabiano Rosas { gen_helper_sve_ld1hss_le_r, NULL, NULL, NULL }, 4489f0984d40SFabiano Rosas { gen_helper_sve_ld1ss_le_r, gen_helper_sve_ld2ss_le_r, 4490f0984d40SFabiano Rosas gen_helper_sve_ld3ss_le_r, gen_helper_sve_ld4ss_le_r }, 4491f0984d40SFabiano Rosas { gen_helper_sve_ld1sdu_le_r, NULL, NULL, NULL }, 4492f0984d40SFabiano Rosas 4493f0984d40SFabiano Rosas { gen_helper_sve_ld1bds_r, NULL, NULL, NULL }, 4494f0984d40SFabiano Rosas { gen_helper_sve_ld1bss_r, NULL, NULL, NULL }, 4495f0984d40SFabiano Rosas { gen_helper_sve_ld1bhs_r, NULL, NULL, NULL }, 4496f0984d40SFabiano Rosas { gen_helper_sve_ld1dd_le_r, gen_helper_sve_ld2dd_le_r, 4497f0984d40SFabiano Rosas gen_helper_sve_ld3dd_le_r, gen_helper_sve_ld4dd_le_r } }, 4498f0984d40SFabiano Rosas 4499f0984d40SFabiano Rosas /* mte inactive, big-endian */ 4500f0984d40SFabiano Rosas { { gen_helper_sve_ld1bb_r, gen_helper_sve_ld2bb_r, 4501f0984d40SFabiano Rosas gen_helper_sve_ld3bb_r, gen_helper_sve_ld4bb_r }, 4502f0984d40SFabiano Rosas { gen_helper_sve_ld1bhu_r, NULL, NULL, NULL }, 4503f0984d40SFabiano Rosas { gen_helper_sve_ld1bsu_r, NULL, NULL, NULL }, 4504f0984d40SFabiano Rosas { gen_helper_sve_ld1bdu_r, NULL, NULL, NULL }, 4505f0984d40SFabiano Rosas 4506f0984d40SFabiano Rosas { gen_helper_sve_ld1sds_be_r, NULL, NULL, NULL }, 4507f0984d40SFabiano Rosas { gen_helper_sve_ld1hh_be_r, gen_helper_sve_ld2hh_be_r, 4508f0984d40SFabiano Rosas gen_helper_sve_ld3hh_be_r, gen_helper_sve_ld4hh_be_r }, 4509f0984d40SFabiano Rosas { gen_helper_sve_ld1hsu_be_r, NULL, NULL, NULL }, 4510f0984d40SFabiano Rosas { gen_helper_sve_ld1hdu_be_r, NULL, NULL, NULL }, 4511f0984d40SFabiano Rosas 4512f0984d40SFabiano Rosas { gen_helper_sve_ld1hds_be_r, NULL, NULL, NULL }, 4513f0984d40SFabiano Rosas { gen_helper_sve_ld1hss_be_r, NULL, NULL, NULL }, 4514f0984d40SFabiano Rosas { gen_helper_sve_ld1ss_be_r, gen_helper_sve_ld2ss_be_r, 4515f0984d40SFabiano Rosas gen_helper_sve_ld3ss_be_r, gen_helper_sve_ld4ss_be_r }, 4516f0984d40SFabiano Rosas { gen_helper_sve_ld1sdu_be_r, NULL, NULL, NULL }, 4517f0984d40SFabiano Rosas 4518f0984d40SFabiano Rosas { gen_helper_sve_ld1bds_r, NULL, NULL, NULL }, 4519f0984d40SFabiano Rosas { gen_helper_sve_ld1bss_r, NULL, NULL, NULL }, 4520f0984d40SFabiano Rosas { gen_helper_sve_ld1bhs_r, NULL, NULL, NULL }, 4521f0984d40SFabiano Rosas { gen_helper_sve_ld1dd_be_r, gen_helper_sve_ld2dd_be_r, 4522f0984d40SFabiano Rosas gen_helper_sve_ld3dd_be_r, gen_helper_sve_ld4dd_be_r } } }, 4523f0984d40SFabiano Rosas 4524f0984d40SFabiano Rosas { /* mte active, little-endian */ 4525f0984d40SFabiano Rosas { { gen_helper_sve_ld1bb_r_mte, 4526f0984d40SFabiano Rosas gen_helper_sve_ld2bb_r_mte, 4527f0984d40SFabiano Rosas gen_helper_sve_ld3bb_r_mte, 4528f0984d40SFabiano Rosas gen_helper_sve_ld4bb_r_mte }, 4529f0984d40SFabiano Rosas { gen_helper_sve_ld1bhu_r_mte, NULL, NULL, NULL }, 4530f0984d40SFabiano Rosas { gen_helper_sve_ld1bsu_r_mte, NULL, NULL, NULL }, 4531f0984d40SFabiano Rosas { gen_helper_sve_ld1bdu_r_mte, NULL, NULL, NULL }, 4532f0984d40SFabiano Rosas 4533f0984d40SFabiano Rosas { gen_helper_sve_ld1sds_le_r_mte, NULL, NULL, NULL }, 4534f0984d40SFabiano Rosas { gen_helper_sve_ld1hh_le_r_mte, 4535f0984d40SFabiano Rosas gen_helper_sve_ld2hh_le_r_mte, 4536f0984d40SFabiano Rosas gen_helper_sve_ld3hh_le_r_mte, 4537f0984d40SFabiano Rosas gen_helper_sve_ld4hh_le_r_mte }, 4538f0984d40SFabiano Rosas { gen_helper_sve_ld1hsu_le_r_mte, NULL, NULL, NULL }, 4539f0984d40SFabiano Rosas { gen_helper_sve_ld1hdu_le_r_mte, NULL, NULL, NULL }, 4540f0984d40SFabiano Rosas 4541f0984d40SFabiano Rosas { gen_helper_sve_ld1hds_le_r_mte, NULL, NULL, NULL }, 4542f0984d40SFabiano Rosas { gen_helper_sve_ld1hss_le_r_mte, NULL, NULL, NULL }, 4543f0984d40SFabiano Rosas { gen_helper_sve_ld1ss_le_r_mte, 4544f0984d40SFabiano Rosas gen_helper_sve_ld2ss_le_r_mte, 4545f0984d40SFabiano Rosas gen_helper_sve_ld3ss_le_r_mte, 4546f0984d40SFabiano Rosas gen_helper_sve_ld4ss_le_r_mte }, 4547f0984d40SFabiano Rosas { gen_helper_sve_ld1sdu_le_r_mte, NULL, NULL, NULL }, 4548f0984d40SFabiano Rosas 4549f0984d40SFabiano Rosas { gen_helper_sve_ld1bds_r_mte, NULL, NULL, NULL }, 4550f0984d40SFabiano Rosas { gen_helper_sve_ld1bss_r_mte, NULL, NULL, NULL }, 4551f0984d40SFabiano Rosas { gen_helper_sve_ld1bhs_r_mte, NULL, NULL, NULL }, 4552f0984d40SFabiano Rosas { gen_helper_sve_ld1dd_le_r_mte, 4553f0984d40SFabiano Rosas gen_helper_sve_ld2dd_le_r_mte, 4554f0984d40SFabiano Rosas gen_helper_sve_ld3dd_le_r_mte, 4555f0984d40SFabiano Rosas gen_helper_sve_ld4dd_le_r_mte } }, 4556f0984d40SFabiano Rosas 4557f0984d40SFabiano Rosas /* mte active, big-endian */ 4558f0984d40SFabiano Rosas { { gen_helper_sve_ld1bb_r_mte, 4559f0984d40SFabiano Rosas gen_helper_sve_ld2bb_r_mte, 4560f0984d40SFabiano Rosas gen_helper_sve_ld3bb_r_mte, 4561f0984d40SFabiano Rosas gen_helper_sve_ld4bb_r_mte }, 4562f0984d40SFabiano Rosas { gen_helper_sve_ld1bhu_r_mte, NULL, NULL, NULL }, 4563f0984d40SFabiano Rosas { gen_helper_sve_ld1bsu_r_mte, NULL, NULL, NULL }, 4564f0984d40SFabiano Rosas { gen_helper_sve_ld1bdu_r_mte, NULL, NULL, NULL }, 4565f0984d40SFabiano Rosas 4566f0984d40SFabiano Rosas { gen_helper_sve_ld1sds_be_r_mte, NULL, NULL, NULL }, 4567f0984d40SFabiano Rosas { gen_helper_sve_ld1hh_be_r_mte, 4568f0984d40SFabiano Rosas gen_helper_sve_ld2hh_be_r_mte, 4569f0984d40SFabiano Rosas gen_helper_sve_ld3hh_be_r_mte, 4570f0984d40SFabiano Rosas gen_helper_sve_ld4hh_be_r_mte }, 4571f0984d40SFabiano Rosas { gen_helper_sve_ld1hsu_be_r_mte, NULL, NULL, NULL }, 4572f0984d40SFabiano Rosas { gen_helper_sve_ld1hdu_be_r_mte, NULL, NULL, NULL }, 4573f0984d40SFabiano Rosas 4574f0984d40SFabiano Rosas { gen_helper_sve_ld1hds_be_r_mte, NULL, NULL, NULL }, 4575f0984d40SFabiano Rosas { gen_helper_sve_ld1hss_be_r_mte, NULL, NULL, NULL }, 4576f0984d40SFabiano Rosas { gen_helper_sve_ld1ss_be_r_mte, 4577f0984d40SFabiano Rosas gen_helper_sve_ld2ss_be_r_mte, 4578f0984d40SFabiano Rosas gen_helper_sve_ld3ss_be_r_mte, 4579f0984d40SFabiano Rosas gen_helper_sve_ld4ss_be_r_mte }, 4580f0984d40SFabiano Rosas { gen_helper_sve_ld1sdu_be_r_mte, NULL, NULL, NULL }, 4581f0984d40SFabiano Rosas 4582f0984d40SFabiano Rosas { gen_helper_sve_ld1bds_r_mte, NULL, NULL, NULL }, 4583f0984d40SFabiano Rosas { gen_helper_sve_ld1bss_r_mte, NULL, NULL, NULL }, 4584f0984d40SFabiano Rosas { gen_helper_sve_ld1bhs_r_mte, NULL, NULL, NULL }, 4585f0984d40SFabiano Rosas { gen_helper_sve_ld1dd_be_r_mte, 4586f0984d40SFabiano Rosas gen_helper_sve_ld2dd_be_r_mte, 4587f0984d40SFabiano Rosas gen_helper_sve_ld3dd_be_r_mte, 4588f0984d40SFabiano Rosas gen_helper_sve_ld4dd_be_r_mte } } }, 4589f0984d40SFabiano Rosas }; 4590f0984d40SFabiano Rosas 4591f0984d40SFabiano Rosas static void do_ld_zpa(DisasContext *s, int zt, int pg, 4592f0984d40SFabiano Rosas TCGv_i64 addr, int dtype, int nreg) 4593f0984d40SFabiano Rosas { 4594f0984d40SFabiano Rosas gen_helper_gvec_mem *fn 4595f0984d40SFabiano Rosas = ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][nreg]; 4596f0984d40SFabiano Rosas 4597f0984d40SFabiano Rosas /* 4598f0984d40SFabiano Rosas * While there are holes in the table, they are not 4599f0984d40SFabiano Rosas * accessible via the instruction encoding. 4600f0984d40SFabiano Rosas */ 4601f0984d40SFabiano Rosas assert(fn != NULL); 4602f0984d40SFabiano Rosas do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn); 4603f0984d40SFabiano Rosas } 4604f0984d40SFabiano Rosas 4605f0984d40SFabiano Rosas static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a) 4606f0984d40SFabiano Rosas { 4607f0984d40SFabiano Rosas if (a->rm == 31 || !dc_isar_feature(aa64_sve, s)) { 4608f0984d40SFabiano Rosas return false; 4609f0984d40SFabiano Rosas } 4610f0984d40SFabiano Rosas if (sve_access_check(s)) { 46116980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4612f0984d40SFabiano Rosas tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype)); 4613f0984d40SFabiano Rosas tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); 4614f0984d40SFabiano Rosas do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg); 4615f0984d40SFabiano Rosas } 4616f0984d40SFabiano Rosas return true; 4617f0984d40SFabiano Rosas } 4618f0984d40SFabiano Rosas 4619f0984d40SFabiano Rosas static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a) 4620f0984d40SFabiano Rosas { 4621f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4622f0984d40SFabiano Rosas return false; 4623f0984d40SFabiano Rosas } 4624f0984d40SFabiano Rosas if (sve_access_check(s)) { 4625f0984d40SFabiano Rosas int vsz = vec_full_reg_size(s); 4626f0984d40SFabiano Rosas int elements = vsz >> dtype_esz[a->dtype]; 46276980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4628f0984d40SFabiano Rosas 4629f0984d40SFabiano Rosas tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), 4630f0984d40SFabiano Rosas (a->imm * elements * (a->nreg + 1)) 4631f0984d40SFabiano Rosas << dtype_msz(a->dtype)); 4632f0984d40SFabiano Rosas do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg); 4633f0984d40SFabiano Rosas } 4634f0984d40SFabiano Rosas return true; 4635f0984d40SFabiano Rosas } 4636f0984d40SFabiano Rosas 4637f0984d40SFabiano Rosas static bool trans_LDFF1_zprr(DisasContext *s, arg_rprr_load *a) 4638f0984d40SFabiano Rosas { 4639f0984d40SFabiano Rosas static gen_helper_gvec_mem * const fns[2][2][16] = { 4640f0984d40SFabiano Rosas { /* mte inactive, little-endian */ 4641f0984d40SFabiano Rosas { gen_helper_sve_ldff1bb_r, 4642f0984d40SFabiano Rosas gen_helper_sve_ldff1bhu_r, 4643f0984d40SFabiano Rosas gen_helper_sve_ldff1bsu_r, 4644f0984d40SFabiano Rosas gen_helper_sve_ldff1bdu_r, 4645f0984d40SFabiano Rosas 4646f0984d40SFabiano Rosas gen_helper_sve_ldff1sds_le_r, 4647f0984d40SFabiano Rosas gen_helper_sve_ldff1hh_le_r, 4648f0984d40SFabiano Rosas gen_helper_sve_ldff1hsu_le_r, 4649f0984d40SFabiano Rosas gen_helper_sve_ldff1hdu_le_r, 4650f0984d40SFabiano Rosas 4651f0984d40SFabiano Rosas gen_helper_sve_ldff1hds_le_r, 4652f0984d40SFabiano Rosas gen_helper_sve_ldff1hss_le_r, 4653f0984d40SFabiano Rosas gen_helper_sve_ldff1ss_le_r, 4654f0984d40SFabiano Rosas gen_helper_sve_ldff1sdu_le_r, 4655f0984d40SFabiano Rosas 4656f0984d40SFabiano Rosas gen_helper_sve_ldff1bds_r, 4657f0984d40SFabiano Rosas gen_helper_sve_ldff1bss_r, 4658f0984d40SFabiano Rosas gen_helper_sve_ldff1bhs_r, 4659f0984d40SFabiano Rosas gen_helper_sve_ldff1dd_le_r }, 4660f0984d40SFabiano Rosas 4661f0984d40SFabiano Rosas /* mte inactive, big-endian */ 4662f0984d40SFabiano Rosas { gen_helper_sve_ldff1bb_r, 4663f0984d40SFabiano Rosas gen_helper_sve_ldff1bhu_r, 4664f0984d40SFabiano Rosas gen_helper_sve_ldff1bsu_r, 4665f0984d40SFabiano Rosas gen_helper_sve_ldff1bdu_r, 4666f0984d40SFabiano Rosas 4667f0984d40SFabiano Rosas gen_helper_sve_ldff1sds_be_r, 4668f0984d40SFabiano Rosas gen_helper_sve_ldff1hh_be_r, 4669f0984d40SFabiano Rosas gen_helper_sve_ldff1hsu_be_r, 4670f0984d40SFabiano Rosas gen_helper_sve_ldff1hdu_be_r, 4671f0984d40SFabiano Rosas 4672f0984d40SFabiano Rosas gen_helper_sve_ldff1hds_be_r, 4673f0984d40SFabiano Rosas gen_helper_sve_ldff1hss_be_r, 4674f0984d40SFabiano Rosas gen_helper_sve_ldff1ss_be_r, 4675f0984d40SFabiano Rosas gen_helper_sve_ldff1sdu_be_r, 4676f0984d40SFabiano Rosas 4677f0984d40SFabiano Rosas gen_helper_sve_ldff1bds_r, 4678f0984d40SFabiano Rosas gen_helper_sve_ldff1bss_r, 4679f0984d40SFabiano Rosas gen_helper_sve_ldff1bhs_r, 4680f0984d40SFabiano Rosas gen_helper_sve_ldff1dd_be_r } }, 4681f0984d40SFabiano Rosas 4682f0984d40SFabiano Rosas { /* mte active, little-endian */ 4683f0984d40SFabiano Rosas { gen_helper_sve_ldff1bb_r_mte, 4684f0984d40SFabiano Rosas gen_helper_sve_ldff1bhu_r_mte, 4685f0984d40SFabiano Rosas gen_helper_sve_ldff1bsu_r_mte, 4686f0984d40SFabiano Rosas gen_helper_sve_ldff1bdu_r_mte, 4687f0984d40SFabiano Rosas 4688f0984d40SFabiano Rosas gen_helper_sve_ldff1sds_le_r_mte, 4689f0984d40SFabiano Rosas gen_helper_sve_ldff1hh_le_r_mte, 4690f0984d40SFabiano Rosas gen_helper_sve_ldff1hsu_le_r_mte, 4691f0984d40SFabiano Rosas gen_helper_sve_ldff1hdu_le_r_mte, 4692f0984d40SFabiano Rosas 4693f0984d40SFabiano Rosas gen_helper_sve_ldff1hds_le_r_mte, 4694f0984d40SFabiano Rosas gen_helper_sve_ldff1hss_le_r_mte, 4695f0984d40SFabiano Rosas gen_helper_sve_ldff1ss_le_r_mte, 4696f0984d40SFabiano Rosas gen_helper_sve_ldff1sdu_le_r_mte, 4697f0984d40SFabiano Rosas 4698f0984d40SFabiano Rosas gen_helper_sve_ldff1bds_r_mte, 4699f0984d40SFabiano Rosas gen_helper_sve_ldff1bss_r_mte, 4700f0984d40SFabiano Rosas gen_helper_sve_ldff1bhs_r_mte, 4701f0984d40SFabiano Rosas gen_helper_sve_ldff1dd_le_r_mte }, 4702f0984d40SFabiano Rosas 4703f0984d40SFabiano Rosas /* mte active, big-endian */ 4704f0984d40SFabiano Rosas { gen_helper_sve_ldff1bb_r_mte, 4705f0984d40SFabiano Rosas gen_helper_sve_ldff1bhu_r_mte, 4706f0984d40SFabiano Rosas gen_helper_sve_ldff1bsu_r_mte, 4707f0984d40SFabiano Rosas gen_helper_sve_ldff1bdu_r_mte, 4708f0984d40SFabiano Rosas 4709f0984d40SFabiano Rosas gen_helper_sve_ldff1sds_be_r_mte, 4710f0984d40SFabiano Rosas gen_helper_sve_ldff1hh_be_r_mte, 4711f0984d40SFabiano Rosas gen_helper_sve_ldff1hsu_be_r_mte, 4712f0984d40SFabiano Rosas gen_helper_sve_ldff1hdu_be_r_mte, 4713f0984d40SFabiano Rosas 4714f0984d40SFabiano Rosas gen_helper_sve_ldff1hds_be_r_mte, 4715f0984d40SFabiano Rosas gen_helper_sve_ldff1hss_be_r_mte, 4716f0984d40SFabiano Rosas gen_helper_sve_ldff1ss_be_r_mte, 4717f0984d40SFabiano Rosas gen_helper_sve_ldff1sdu_be_r_mte, 4718f0984d40SFabiano Rosas 4719f0984d40SFabiano Rosas gen_helper_sve_ldff1bds_r_mte, 4720f0984d40SFabiano Rosas gen_helper_sve_ldff1bss_r_mte, 4721f0984d40SFabiano Rosas gen_helper_sve_ldff1bhs_r_mte, 4722f0984d40SFabiano Rosas gen_helper_sve_ldff1dd_be_r_mte } }, 4723f0984d40SFabiano Rosas }; 4724f0984d40SFabiano Rosas 4725f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4726f0984d40SFabiano Rosas return false; 4727f0984d40SFabiano Rosas } 4728f0984d40SFabiano Rosas s->is_nonstreaming = true; 4729f0984d40SFabiano Rosas if (sve_access_check(s)) { 47306980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4731f0984d40SFabiano Rosas tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype)); 4732f0984d40SFabiano Rosas tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); 4733f0984d40SFabiano Rosas do_mem_zpa(s, a->rd, a->pg, addr, a->dtype, 1, false, 4734f0984d40SFabiano Rosas fns[s->mte_active[0]][s->be_data == MO_BE][a->dtype]); 4735f0984d40SFabiano Rosas } 4736f0984d40SFabiano Rosas return true; 4737f0984d40SFabiano Rosas } 4738f0984d40SFabiano Rosas 4739f0984d40SFabiano Rosas static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a) 4740f0984d40SFabiano Rosas { 4741f0984d40SFabiano Rosas static gen_helper_gvec_mem * const fns[2][2][16] = { 4742f0984d40SFabiano Rosas { /* mte inactive, little-endian */ 4743f0984d40SFabiano Rosas { gen_helper_sve_ldnf1bb_r, 4744f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhu_r, 4745f0984d40SFabiano Rosas gen_helper_sve_ldnf1bsu_r, 4746f0984d40SFabiano Rosas gen_helper_sve_ldnf1bdu_r, 4747f0984d40SFabiano Rosas 4748f0984d40SFabiano Rosas gen_helper_sve_ldnf1sds_le_r, 4749f0984d40SFabiano Rosas gen_helper_sve_ldnf1hh_le_r, 4750f0984d40SFabiano Rosas gen_helper_sve_ldnf1hsu_le_r, 4751f0984d40SFabiano Rosas gen_helper_sve_ldnf1hdu_le_r, 4752f0984d40SFabiano Rosas 4753f0984d40SFabiano Rosas gen_helper_sve_ldnf1hds_le_r, 4754f0984d40SFabiano Rosas gen_helper_sve_ldnf1hss_le_r, 4755f0984d40SFabiano Rosas gen_helper_sve_ldnf1ss_le_r, 4756f0984d40SFabiano Rosas gen_helper_sve_ldnf1sdu_le_r, 4757f0984d40SFabiano Rosas 4758f0984d40SFabiano Rosas gen_helper_sve_ldnf1bds_r, 4759f0984d40SFabiano Rosas gen_helper_sve_ldnf1bss_r, 4760f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhs_r, 4761f0984d40SFabiano Rosas gen_helper_sve_ldnf1dd_le_r }, 4762f0984d40SFabiano Rosas 4763f0984d40SFabiano Rosas /* mte inactive, big-endian */ 4764f0984d40SFabiano Rosas { gen_helper_sve_ldnf1bb_r, 4765f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhu_r, 4766f0984d40SFabiano Rosas gen_helper_sve_ldnf1bsu_r, 4767f0984d40SFabiano Rosas gen_helper_sve_ldnf1bdu_r, 4768f0984d40SFabiano Rosas 4769f0984d40SFabiano Rosas gen_helper_sve_ldnf1sds_be_r, 4770f0984d40SFabiano Rosas gen_helper_sve_ldnf1hh_be_r, 4771f0984d40SFabiano Rosas gen_helper_sve_ldnf1hsu_be_r, 4772f0984d40SFabiano Rosas gen_helper_sve_ldnf1hdu_be_r, 4773f0984d40SFabiano Rosas 4774f0984d40SFabiano Rosas gen_helper_sve_ldnf1hds_be_r, 4775f0984d40SFabiano Rosas gen_helper_sve_ldnf1hss_be_r, 4776f0984d40SFabiano Rosas gen_helper_sve_ldnf1ss_be_r, 4777f0984d40SFabiano Rosas gen_helper_sve_ldnf1sdu_be_r, 4778f0984d40SFabiano Rosas 4779f0984d40SFabiano Rosas gen_helper_sve_ldnf1bds_r, 4780f0984d40SFabiano Rosas gen_helper_sve_ldnf1bss_r, 4781f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhs_r, 4782f0984d40SFabiano Rosas gen_helper_sve_ldnf1dd_be_r } }, 4783f0984d40SFabiano Rosas 4784f0984d40SFabiano Rosas { /* mte inactive, little-endian */ 4785f0984d40SFabiano Rosas { gen_helper_sve_ldnf1bb_r_mte, 4786f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhu_r_mte, 4787f0984d40SFabiano Rosas gen_helper_sve_ldnf1bsu_r_mte, 4788f0984d40SFabiano Rosas gen_helper_sve_ldnf1bdu_r_mte, 4789f0984d40SFabiano Rosas 4790f0984d40SFabiano Rosas gen_helper_sve_ldnf1sds_le_r_mte, 4791f0984d40SFabiano Rosas gen_helper_sve_ldnf1hh_le_r_mte, 4792f0984d40SFabiano Rosas gen_helper_sve_ldnf1hsu_le_r_mte, 4793f0984d40SFabiano Rosas gen_helper_sve_ldnf1hdu_le_r_mte, 4794f0984d40SFabiano Rosas 4795f0984d40SFabiano Rosas gen_helper_sve_ldnf1hds_le_r_mte, 4796f0984d40SFabiano Rosas gen_helper_sve_ldnf1hss_le_r_mte, 4797f0984d40SFabiano Rosas gen_helper_sve_ldnf1ss_le_r_mte, 4798f0984d40SFabiano Rosas gen_helper_sve_ldnf1sdu_le_r_mte, 4799f0984d40SFabiano Rosas 4800f0984d40SFabiano Rosas gen_helper_sve_ldnf1bds_r_mte, 4801f0984d40SFabiano Rosas gen_helper_sve_ldnf1bss_r_mte, 4802f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhs_r_mte, 4803f0984d40SFabiano Rosas gen_helper_sve_ldnf1dd_le_r_mte }, 4804f0984d40SFabiano Rosas 4805f0984d40SFabiano Rosas /* mte inactive, big-endian */ 4806f0984d40SFabiano Rosas { gen_helper_sve_ldnf1bb_r_mte, 4807f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhu_r_mte, 4808f0984d40SFabiano Rosas gen_helper_sve_ldnf1bsu_r_mte, 4809f0984d40SFabiano Rosas gen_helper_sve_ldnf1bdu_r_mte, 4810f0984d40SFabiano Rosas 4811f0984d40SFabiano Rosas gen_helper_sve_ldnf1sds_be_r_mte, 4812f0984d40SFabiano Rosas gen_helper_sve_ldnf1hh_be_r_mte, 4813f0984d40SFabiano Rosas gen_helper_sve_ldnf1hsu_be_r_mte, 4814f0984d40SFabiano Rosas gen_helper_sve_ldnf1hdu_be_r_mte, 4815f0984d40SFabiano Rosas 4816f0984d40SFabiano Rosas gen_helper_sve_ldnf1hds_be_r_mte, 4817f0984d40SFabiano Rosas gen_helper_sve_ldnf1hss_be_r_mte, 4818f0984d40SFabiano Rosas gen_helper_sve_ldnf1ss_be_r_mte, 4819f0984d40SFabiano Rosas gen_helper_sve_ldnf1sdu_be_r_mte, 4820f0984d40SFabiano Rosas 4821f0984d40SFabiano Rosas gen_helper_sve_ldnf1bds_r_mte, 4822f0984d40SFabiano Rosas gen_helper_sve_ldnf1bss_r_mte, 4823f0984d40SFabiano Rosas gen_helper_sve_ldnf1bhs_r_mte, 4824f0984d40SFabiano Rosas gen_helper_sve_ldnf1dd_be_r_mte } }, 4825f0984d40SFabiano Rosas }; 4826f0984d40SFabiano Rosas 4827f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4828f0984d40SFabiano Rosas return false; 4829f0984d40SFabiano Rosas } 4830f0984d40SFabiano Rosas s->is_nonstreaming = true; 4831f0984d40SFabiano Rosas if (sve_access_check(s)) { 4832f0984d40SFabiano Rosas int vsz = vec_full_reg_size(s); 4833f0984d40SFabiano Rosas int elements = vsz >> dtype_esz[a->dtype]; 4834f0984d40SFabiano Rosas int off = (a->imm * elements) << dtype_msz(a->dtype); 48356980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4836f0984d40SFabiano Rosas 4837f0984d40SFabiano Rosas tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), off); 4838f0984d40SFabiano Rosas do_mem_zpa(s, a->rd, a->pg, addr, a->dtype, 1, false, 4839f0984d40SFabiano Rosas fns[s->mte_active[0]][s->be_data == MO_BE][a->dtype]); 4840f0984d40SFabiano Rosas } 4841f0984d40SFabiano Rosas return true; 4842f0984d40SFabiano Rosas } 4843f0984d40SFabiano Rosas 4844f0984d40SFabiano Rosas static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype) 4845f0984d40SFabiano Rosas { 4846f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 4847f0984d40SFabiano Rosas TCGv_ptr t_pg; 4848f0984d40SFabiano Rosas int poff; 4849f0984d40SFabiano Rosas 4850f0984d40SFabiano Rosas /* Load the first quadword using the normal predicated load helpers. */ 4851f0984d40SFabiano Rosas poff = pred_full_reg_offset(s, pg); 4852f0984d40SFabiano Rosas if (vsz > 16) { 4853f0984d40SFabiano Rosas /* 4854f0984d40SFabiano Rosas * Zero-extend the first 16 bits of the predicate into a temporary. 4855f0984d40SFabiano Rosas * This avoids triggering an assert making sure we don't have bits 4856f0984d40SFabiano Rosas * set within a predicate beyond VQ, but we have lowered VQ to 1 4857f0984d40SFabiano Rosas * for this load operation. 4858f0984d40SFabiano Rosas */ 4859f0984d40SFabiano Rosas TCGv_i64 tmp = tcg_temp_new_i64(); 4860f0984d40SFabiano Rosas #if HOST_BIG_ENDIAN 4861f0984d40SFabiano Rosas poff += 6; 4862f0984d40SFabiano Rosas #endif 4863*ad75a51eSRichard Henderson tcg_gen_ld16u_i64(tmp, tcg_env, poff); 4864f0984d40SFabiano Rosas 4865f0984d40SFabiano Rosas poff = offsetof(CPUARMState, vfp.preg_tmp); 4866*ad75a51eSRichard Henderson tcg_gen_st_i64(tmp, tcg_env, poff); 4867f0984d40SFabiano Rosas } 4868f0984d40SFabiano Rosas 4869f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 4870*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, poff); 4871f0984d40SFabiano Rosas 4872f0984d40SFabiano Rosas gen_helper_gvec_mem *fn 4873f0984d40SFabiano Rosas = ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0]; 4874*ad75a51eSRichard Henderson fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt))); 4875f0984d40SFabiano Rosas 4876f0984d40SFabiano Rosas /* Replicate that first quadword. */ 4877f0984d40SFabiano Rosas if (vsz > 16) { 4878f0984d40SFabiano Rosas int doff = vec_full_reg_offset(s, zt); 4879f0984d40SFabiano Rosas tcg_gen_gvec_dup_mem(4, doff + 16, doff, vsz - 16, vsz - 16); 4880f0984d40SFabiano Rosas } 4881f0984d40SFabiano Rosas } 4882f0984d40SFabiano Rosas 4883f0984d40SFabiano Rosas static bool trans_LD1RQ_zprr(DisasContext *s, arg_rprr_load *a) 4884f0984d40SFabiano Rosas { 4885f0984d40SFabiano Rosas if (a->rm == 31 || !dc_isar_feature(aa64_sve, s)) { 4886f0984d40SFabiano Rosas return false; 4887f0984d40SFabiano Rosas } 4888f0984d40SFabiano Rosas if (sve_access_check(s)) { 4889f0984d40SFabiano Rosas int msz = dtype_msz(a->dtype); 48906980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4891f0984d40SFabiano Rosas tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), msz); 4892f0984d40SFabiano Rosas tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); 4893f0984d40SFabiano Rosas do_ldrq(s, a->rd, a->pg, addr, a->dtype); 4894f0984d40SFabiano Rosas } 4895f0984d40SFabiano Rosas return true; 4896f0984d40SFabiano Rosas } 4897f0984d40SFabiano Rosas 4898f0984d40SFabiano Rosas static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a) 4899f0984d40SFabiano Rosas { 4900f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 4901f0984d40SFabiano Rosas return false; 4902f0984d40SFabiano Rosas } 4903f0984d40SFabiano Rosas if (sve_access_check(s)) { 49046980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4905f0984d40SFabiano Rosas tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 16); 4906f0984d40SFabiano Rosas do_ldrq(s, a->rd, a->pg, addr, a->dtype); 4907f0984d40SFabiano Rosas } 4908f0984d40SFabiano Rosas return true; 4909f0984d40SFabiano Rosas } 4910f0984d40SFabiano Rosas 4911f0984d40SFabiano Rosas static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype) 4912f0984d40SFabiano Rosas { 4913f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 4914f0984d40SFabiano Rosas unsigned vsz_r32; 4915f0984d40SFabiano Rosas TCGv_ptr t_pg; 4916f0984d40SFabiano Rosas int poff, doff; 4917f0984d40SFabiano Rosas 4918f0984d40SFabiano Rosas if (vsz < 32) { 4919f0984d40SFabiano Rosas /* 4920f0984d40SFabiano Rosas * Note that this UNDEFINED check comes after CheckSVEEnabled() 4921f0984d40SFabiano Rosas * in the ARM pseudocode, which is the sve_access_check() done 4922f0984d40SFabiano Rosas * in our caller. We should not now return false from the caller. 4923f0984d40SFabiano Rosas */ 4924f0984d40SFabiano Rosas unallocated_encoding(s); 4925f0984d40SFabiano Rosas return; 4926f0984d40SFabiano Rosas } 4927f0984d40SFabiano Rosas 4928f0984d40SFabiano Rosas /* Load the first octaword using the normal predicated load helpers. */ 4929f0984d40SFabiano Rosas 4930f0984d40SFabiano Rosas poff = pred_full_reg_offset(s, pg); 4931f0984d40SFabiano Rosas if (vsz > 32) { 4932f0984d40SFabiano Rosas /* 4933f0984d40SFabiano Rosas * Zero-extend the first 32 bits of the predicate into a temporary. 4934f0984d40SFabiano Rosas * This avoids triggering an assert making sure we don't have bits 4935f0984d40SFabiano Rosas * set within a predicate beyond VQ, but we have lowered VQ to 2 4936f0984d40SFabiano Rosas * for this load operation. 4937f0984d40SFabiano Rosas */ 4938f0984d40SFabiano Rosas TCGv_i64 tmp = tcg_temp_new_i64(); 4939f0984d40SFabiano Rosas #if HOST_BIG_ENDIAN 4940f0984d40SFabiano Rosas poff += 4; 4941f0984d40SFabiano Rosas #endif 4942*ad75a51eSRichard Henderson tcg_gen_ld32u_i64(tmp, tcg_env, poff); 4943f0984d40SFabiano Rosas 4944f0984d40SFabiano Rosas poff = offsetof(CPUARMState, vfp.preg_tmp); 4945*ad75a51eSRichard Henderson tcg_gen_st_i64(tmp, tcg_env, poff); 4946f0984d40SFabiano Rosas } 4947f0984d40SFabiano Rosas 4948f0984d40SFabiano Rosas t_pg = tcg_temp_new_ptr(); 4949*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, poff); 4950f0984d40SFabiano Rosas 4951f0984d40SFabiano Rosas gen_helper_gvec_mem *fn 4952f0984d40SFabiano Rosas = ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0]; 4953*ad75a51eSRichard Henderson fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt))); 4954f0984d40SFabiano Rosas 4955f0984d40SFabiano Rosas /* 4956f0984d40SFabiano Rosas * Replicate that first octaword. 4957f0984d40SFabiano Rosas * The replication happens in units of 32; if the full vector size 4958f0984d40SFabiano Rosas * is not a multiple of 32, the final bits are zeroed. 4959f0984d40SFabiano Rosas */ 4960f0984d40SFabiano Rosas doff = vec_full_reg_offset(s, zt); 4961f0984d40SFabiano Rosas vsz_r32 = QEMU_ALIGN_DOWN(vsz, 32); 4962f0984d40SFabiano Rosas if (vsz >= 64) { 4963f0984d40SFabiano Rosas tcg_gen_gvec_dup_mem(5, doff + 32, doff, vsz_r32 - 32, vsz_r32 - 32); 4964f0984d40SFabiano Rosas } 4965f0984d40SFabiano Rosas vsz -= vsz_r32; 4966f0984d40SFabiano Rosas if (vsz) { 4967f0984d40SFabiano Rosas tcg_gen_gvec_dup_imm(MO_64, doff + vsz_r32, vsz, vsz, 0); 4968f0984d40SFabiano Rosas } 4969f0984d40SFabiano Rosas } 4970f0984d40SFabiano Rosas 4971f0984d40SFabiano Rosas static bool trans_LD1RO_zprr(DisasContext *s, arg_rprr_load *a) 4972f0984d40SFabiano Rosas { 4973f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve_f64mm, s)) { 4974f0984d40SFabiano Rosas return false; 4975f0984d40SFabiano Rosas } 4976f0984d40SFabiano Rosas if (a->rm == 31) { 4977f0984d40SFabiano Rosas return false; 4978f0984d40SFabiano Rosas } 4979f0984d40SFabiano Rosas s->is_nonstreaming = true; 4980f0984d40SFabiano Rosas if (sve_access_check(s)) { 49816980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4982f0984d40SFabiano Rosas tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype)); 4983f0984d40SFabiano Rosas tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); 4984f0984d40SFabiano Rosas do_ldro(s, a->rd, a->pg, addr, a->dtype); 4985f0984d40SFabiano Rosas } 4986f0984d40SFabiano Rosas return true; 4987f0984d40SFabiano Rosas } 4988f0984d40SFabiano Rosas 4989f0984d40SFabiano Rosas static bool trans_LD1RO_zpri(DisasContext *s, arg_rpri_load *a) 4990f0984d40SFabiano Rosas { 4991f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve_f64mm, s)) { 4992f0984d40SFabiano Rosas return false; 4993f0984d40SFabiano Rosas } 4994f0984d40SFabiano Rosas s->is_nonstreaming = true; 4995f0984d40SFabiano Rosas if (sve_access_check(s)) { 49966980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 4997f0984d40SFabiano Rosas tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 32); 4998f0984d40SFabiano Rosas do_ldro(s, a->rd, a->pg, addr, a->dtype); 4999f0984d40SFabiano Rosas } 5000f0984d40SFabiano Rosas return true; 5001f0984d40SFabiano Rosas } 5002f0984d40SFabiano Rosas 5003f0984d40SFabiano Rosas /* Load and broadcast element. */ 5004f0984d40SFabiano Rosas static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a) 5005f0984d40SFabiano Rosas { 5006f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 5007f0984d40SFabiano Rosas unsigned psz = pred_full_reg_size(s); 5008f0984d40SFabiano Rosas unsigned esz = dtype_esz[a->dtype]; 5009f0984d40SFabiano Rosas unsigned msz = dtype_msz(a->dtype); 5010f0984d40SFabiano Rosas TCGLabel *over; 5011f0984d40SFabiano Rosas TCGv_i64 temp, clean_addr; 50120a909142SRichard Henderson MemOp memop; 5013f0984d40SFabiano Rosas 5014f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5015f0984d40SFabiano Rosas return false; 5016f0984d40SFabiano Rosas } 5017f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5018f0984d40SFabiano Rosas return true; 5019f0984d40SFabiano Rosas } 5020f0984d40SFabiano Rosas 5021f0984d40SFabiano Rosas over = gen_new_label(); 5022f0984d40SFabiano Rosas 5023f0984d40SFabiano Rosas /* If the guarding predicate has no bits set, no load occurs. */ 5024f0984d40SFabiano Rosas if (psz <= 8) { 5025f0984d40SFabiano Rosas /* Reduce the pred_esz_masks value simply to reduce the 5026f0984d40SFabiano Rosas * size of the code generated here. 5027f0984d40SFabiano Rosas */ 5028f0984d40SFabiano Rosas uint64_t psz_mask = MAKE_64BIT_MASK(0, psz * 8); 5029f0984d40SFabiano Rosas temp = tcg_temp_new_i64(); 5030*ad75a51eSRichard Henderson tcg_gen_ld_i64(temp, tcg_env, pred_full_reg_offset(s, a->pg)); 5031f0984d40SFabiano Rosas tcg_gen_andi_i64(temp, temp, pred_esz_masks[esz] & psz_mask); 5032f0984d40SFabiano Rosas tcg_gen_brcondi_i64(TCG_COND_EQ, temp, 0, over); 5033f0984d40SFabiano Rosas } else { 5034f0984d40SFabiano Rosas TCGv_i32 t32 = tcg_temp_new_i32(); 5035f0984d40SFabiano Rosas find_last_active(s, t32, esz, a->pg); 5036f0984d40SFabiano Rosas tcg_gen_brcondi_i32(TCG_COND_LT, t32, 0, over); 5037f0984d40SFabiano Rosas } 5038f0984d40SFabiano Rosas 5039f0984d40SFabiano Rosas /* Load the data. */ 5040f0984d40SFabiano Rosas temp = tcg_temp_new_i64(); 5041f0984d40SFabiano Rosas tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << msz); 5042f0984d40SFabiano Rosas 50430a909142SRichard Henderson memop = finalize_memop(s, dtype_mop[a->dtype]); 50440a909142SRichard Henderson clean_addr = gen_mte_check1(s, temp, false, true, memop); 50450a909142SRichard Henderson tcg_gen_qemu_ld_i64(temp, clean_addr, get_mem_index(s), memop); 5046f0984d40SFabiano Rosas 5047f0984d40SFabiano Rosas /* Broadcast to *all* elements. */ 5048f0984d40SFabiano Rosas tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd), 5049f0984d40SFabiano Rosas vsz, vsz, temp); 5050f0984d40SFabiano Rosas 5051f0984d40SFabiano Rosas /* Zero the inactive elements. */ 5052f0984d40SFabiano Rosas gen_set_label(over); 5053f0984d40SFabiano Rosas return do_movz_zpz(s, a->rd, a->rd, a->pg, esz, false); 5054f0984d40SFabiano Rosas } 5055f0984d40SFabiano Rosas 5056f0984d40SFabiano Rosas static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, 5057f0984d40SFabiano Rosas int msz, int esz, int nreg) 5058f0984d40SFabiano Rosas { 5059f0984d40SFabiano Rosas static gen_helper_gvec_mem * const fn_single[2][2][4][4] = { 5060f0984d40SFabiano Rosas { { { gen_helper_sve_st1bb_r, 5061f0984d40SFabiano Rosas gen_helper_sve_st1bh_r, 5062f0984d40SFabiano Rosas gen_helper_sve_st1bs_r, 5063f0984d40SFabiano Rosas gen_helper_sve_st1bd_r }, 5064f0984d40SFabiano Rosas { NULL, 5065f0984d40SFabiano Rosas gen_helper_sve_st1hh_le_r, 5066f0984d40SFabiano Rosas gen_helper_sve_st1hs_le_r, 5067f0984d40SFabiano Rosas gen_helper_sve_st1hd_le_r }, 5068f0984d40SFabiano Rosas { NULL, NULL, 5069f0984d40SFabiano Rosas gen_helper_sve_st1ss_le_r, 5070f0984d40SFabiano Rosas gen_helper_sve_st1sd_le_r }, 5071f0984d40SFabiano Rosas { NULL, NULL, NULL, 5072f0984d40SFabiano Rosas gen_helper_sve_st1dd_le_r } }, 5073f0984d40SFabiano Rosas { { gen_helper_sve_st1bb_r, 5074f0984d40SFabiano Rosas gen_helper_sve_st1bh_r, 5075f0984d40SFabiano Rosas gen_helper_sve_st1bs_r, 5076f0984d40SFabiano Rosas gen_helper_sve_st1bd_r }, 5077f0984d40SFabiano Rosas { NULL, 5078f0984d40SFabiano Rosas gen_helper_sve_st1hh_be_r, 5079f0984d40SFabiano Rosas gen_helper_sve_st1hs_be_r, 5080f0984d40SFabiano Rosas gen_helper_sve_st1hd_be_r }, 5081f0984d40SFabiano Rosas { NULL, NULL, 5082f0984d40SFabiano Rosas gen_helper_sve_st1ss_be_r, 5083f0984d40SFabiano Rosas gen_helper_sve_st1sd_be_r }, 5084f0984d40SFabiano Rosas { NULL, NULL, NULL, 5085f0984d40SFabiano Rosas gen_helper_sve_st1dd_be_r } } }, 5086f0984d40SFabiano Rosas 5087f0984d40SFabiano Rosas { { { gen_helper_sve_st1bb_r_mte, 5088f0984d40SFabiano Rosas gen_helper_sve_st1bh_r_mte, 5089f0984d40SFabiano Rosas gen_helper_sve_st1bs_r_mte, 5090f0984d40SFabiano Rosas gen_helper_sve_st1bd_r_mte }, 5091f0984d40SFabiano Rosas { NULL, 5092f0984d40SFabiano Rosas gen_helper_sve_st1hh_le_r_mte, 5093f0984d40SFabiano Rosas gen_helper_sve_st1hs_le_r_mte, 5094f0984d40SFabiano Rosas gen_helper_sve_st1hd_le_r_mte }, 5095f0984d40SFabiano Rosas { NULL, NULL, 5096f0984d40SFabiano Rosas gen_helper_sve_st1ss_le_r_mte, 5097f0984d40SFabiano Rosas gen_helper_sve_st1sd_le_r_mte }, 5098f0984d40SFabiano Rosas { NULL, NULL, NULL, 5099f0984d40SFabiano Rosas gen_helper_sve_st1dd_le_r_mte } }, 5100f0984d40SFabiano Rosas { { gen_helper_sve_st1bb_r_mte, 5101f0984d40SFabiano Rosas gen_helper_sve_st1bh_r_mte, 5102f0984d40SFabiano Rosas gen_helper_sve_st1bs_r_mte, 5103f0984d40SFabiano Rosas gen_helper_sve_st1bd_r_mte }, 5104f0984d40SFabiano Rosas { NULL, 5105f0984d40SFabiano Rosas gen_helper_sve_st1hh_be_r_mte, 5106f0984d40SFabiano Rosas gen_helper_sve_st1hs_be_r_mte, 5107f0984d40SFabiano Rosas gen_helper_sve_st1hd_be_r_mte }, 5108f0984d40SFabiano Rosas { NULL, NULL, 5109f0984d40SFabiano Rosas gen_helper_sve_st1ss_be_r_mte, 5110f0984d40SFabiano Rosas gen_helper_sve_st1sd_be_r_mte }, 5111f0984d40SFabiano Rosas { NULL, NULL, NULL, 5112f0984d40SFabiano Rosas gen_helper_sve_st1dd_be_r_mte } } }, 5113f0984d40SFabiano Rosas }; 5114f0984d40SFabiano Rosas static gen_helper_gvec_mem * const fn_multiple[2][2][3][4] = { 5115f0984d40SFabiano Rosas { { { gen_helper_sve_st2bb_r, 5116f0984d40SFabiano Rosas gen_helper_sve_st2hh_le_r, 5117f0984d40SFabiano Rosas gen_helper_sve_st2ss_le_r, 5118f0984d40SFabiano Rosas gen_helper_sve_st2dd_le_r }, 5119f0984d40SFabiano Rosas { gen_helper_sve_st3bb_r, 5120f0984d40SFabiano Rosas gen_helper_sve_st3hh_le_r, 5121f0984d40SFabiano Rosas gen_helper_sve_st3ss_le_r, 5122f0984d40SFabiano Rosas gen_helper_sve_st3dd_le_r }, 5123f0984d40SFabiano Rosas { gen_helper_sve_st4bb_r, 5124f0984d40SFabiano Rosas gen_helper_sve_st4hh_le_r, 5125f0984d40SFabiano Rosas gen_helper_sve_st4ss_le_r, 5126f0984d40SFabiano Rosas gen_helper_sve_st4dd_le_r } }, 5127f0984d40SFabiano Rosas { { gen_helper_sve_st2bb_r, 5128f0984d40SFabiano Rosas gen_helper_sve_st2hh_be_r, 5129f0984d40SFabiano Rosas gen_helper_sve_st2ss_be_r, 5130f0984d40SFabiano Rosas gen_helper_sve_st2dd_be_r }, 5131f0984d40SFabiano Rosas { gen_helper_sve_st3bb_r, 5132f0984d40SFabiano Rosas gen_helper_sve_st3hh_be_r, 5133f0984d40SFabiano Rosas gen_helper_sve_st3ss_be_r, 5134f0984d40SFabiano Rosas gen_helper_sve_st3dd_be_r }, 5135f0984d40SFabiano Rosas { gen_helper_sve_st4bb_r, 5136f0984d40SFabiano Rosas gen_helper_sve_st4hh_be_r, 5137f0984d40SFabiano Rosas gen_helper_sve_st4ss_be_r, 5138f0984d40SFabiano Rosas gen_helper_sve_st4dd_be_r } } }, 5139f0984d40SFabiano Rosas { { { gen_helper_sve_st2bb_r_mte, 5140f0984d40SFabiano Rosas gen_helper_sve_st2hh_le_r_mte, 5141f0984d40SFabiano Rosas gen_helper_sve_st2ss_le_r_mte, 5142f0984d40SFabiano Rosas gen_helper_sve_st2dd_le_r_mte }, 5143f0984d40SFabiano Rosas { gen_helper_sve_st3bb_r_mte, 5144f0984d40SFabiano Rosas gen_helper_sve_st3hh_le_r_mte, 5145f0984d40SFabiano Rosas gen_helper_sve_st3ss_le_r_mte, 5146f0984d40SFabiano Rosas gen_helper_sve_st3dd_le_r_mte }, 5147f0984d40SFabiano Rosas { gen_helper_sve_st4bb_r_mte, 5148f0984d40SFabiano Rosas gen_helper_sve_st4hh_le_r_mte, 5149f0984d40SFabiano Rosas gen_helper_sve_st4ss_le_r_mte, 5150f0984d40SFabiano Rosas gen_helper_sve_st4dd_le_r_mte } }, 5151f0984d40SFabiano Rosas { { gen_helper_sve_st2bb_r_mte, 5152f0984d40SFabiano Rosas gen_helper_sve_st2hh_be_r_mte, 5153f0984d40SFabiano Rosas gen_helper_sve_st2ss_be_r_mte, 5154f0984d40SFabiano Rosas gen_helper_sve_st2dd_be_r_mte }, 5155f0984d40SFabiano Rosas { gen_helper_sve_st3bb_r_mte, 5156f0984d40SFabiano Rosas gen_helper_sve_st3hh_be_r_mte, 5157f0984d40SFabiano Rosas gen_helper_sve_st3ss_be_r_mte, 5158f0984d40SFabiano Rosas gen_helper_sve_st3dd_be_r_mte }, 5159f0984d40SFabiano Rosas { gen_helper_sve_st4bb_r_mte, 5160f0984d40SFabiano Rosas gen_helper_sve_st4hh_be_r_mte, 5161f0984d40SFabiano Rosas gen_helper_sve_st4ss_be_r_mte, 5162f0984d40SFabiano Rosas gen_helper_sve_st4dd_be_r_mte } } }, 5163f0984d40SFabiano Rosas }; 5164f0984d40SFabiano Rosas gen_helper_gvec_mem *fn; 5165f0984d40SFabiano Rosas int be = s->be_data == MO_BE; 5166f0984d40SFabiano Rosas 5167f0984d40SFabiano Rosas if (nreg == 0) { 5168f0984d40SFabiano Rosas /* ST1 */ 5169f0984d40SFabiano Rosas fn = fn_single[s->mte_active[0]][be][msz][esz]; 5170f0984d40SFabiano Rosas nreg = 1; 5171f0984d40SFabiano Rosas } else { 5172f0984d40SFabiano Rosas /* ST2, ST3, ST4 -- msz == esz, enforced by encoding */ 5173f0984d40SFabiano Rosas assert(msz == esz); 5174f0984d40SFabiano Rosas fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz]; 5175f0984d40SFabiano Rosas } 5176f0984d40SFabiano Rosas assert(fn != NULL); 5177f0984d40SFabiano Rosas do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn); 5178f0984d40SFabiano Rosas } 5179f0984d40SFabiano Rosas 5180f0984d40SFabiano Rosas static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a) 5181f0984d40SFabiano Rosas { 5182f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5183f0984d40SFabiano Rosas return false; 5184f0984d40SFabiano Rosas } 5185f0984d40SFabiano Rosas if (a->rm == 31 || a->msz > a->esz) { 5186f0984d40SFabiano Rosas return false; 5187f0984d40SFabiano Rosas } 5188f0984d40SFabiano Rosas if (sve_access_check(s)) { 51896980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 5190f0984d40SFabiano Rosas tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->msz); 5191f0984d40SFabiano Rosas tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); 5192f0984d40SFabiano Rosas do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg); 5193f0984d40SFabiano Rosas } 5194f0984d40SFabiano Rosas return true; 5195f0984d40SFabiano Rosas } 5196f0984d40SFabiano Rosas 5197f0984d40SFabiano Rosas static bool trans_ST_zpri(DisasContext *s, arg_rpri_store *a) 5198f0984d40SFabiano Rosas { 5199f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5200f0984d40SFabiano Rosas return false; 5201f0984d40SFabiano Rosas } 5202f0984d40SFabiano Rosas if (a->msz > a->esz) { 5203f0984d40SFabiano Rosas return false; 5204f0984d40SFabiano Rosas } 5205f0984d40SFabiano Rosas if (sve_access_check(s)) { 5206f0984d40SFabiano Rosas int vsz = vec_full_reg_size(s); 5207f0984d40SFabiano Rosas int elements = vsz >> a->esz; 52086980b80dSRichard Henderson TCGv_i64 addr = tcg_temp_new_i64(); 5209f0984d40SFabiano Rosas 5210f0984d40SFabiano Rosas tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), 5211f0984d40SFabiano Rosas (a->imm * elements * (a->nreg + 1)) << a->msz); 5212f0984d40SFabiano Rosas do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg); 5213f0984d40SFabiano Rosas } 5214f0984d40SFabiano Rosas return true; 5215f0984d40SFabiano Rosas } 5216f0984d40SFabiano Rosas 5217f0984d40SFabiano Rosas /* 5218f0984d40SFabiano Rosas *** SVE gather loads / scatter stores 5219f0984d40SFabiano Rosas */ 5220f0984d40SFabiano Rosas 5221f0984d40SFabiano Rosas static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, 5222f0984d40SFabiano Rosas int scale, TCGv_i64 scalar, int msz, bool is_write, 5223f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn) 5224f0984d40SFabiano Rosas { 5225f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 5226f0984d40SFabiano Rosas TCGv_ptr t_zm = tcg_temp_new_ptr(); 5227f0984d40SFabiano Rosas TCGv_ptr t_pg = tcg_temp_new_ptr(); 5228f0984d40SFabiano Rosas TCGv_ptr t_zt = tcg_temp_new_ptr(); 5229f0984d40SFabiano Rosas int desc = 0; 5230f0984d40SFabiano Rosas 5231f0984d40SFabiano Rosas if (s->mte_active[0]) { 5232f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s)); 5233f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid); 5234f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma); 5235f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write); 5236f0984d40SFabiano Rosas desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1); 5237f0984d40SFabiano Rosas desc <<= SVE_MTEDESC_SHIFT; 5238f0984d40SFabiano Rosas } 5239f0984d40SFabiano Rosas desc = simd_desc(vsz, vsz, desc | scale); 5240f0984d40SFabiano Rosas 5241*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); 5242*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm)); 5243*ad75a51eSRichard Henderson tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt)); 5244*ad75a51eSRichard Henderson fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc)); 5245f0984d40SFabiano Rosas } 5246f0984d40SFabiano Rosas 5247f0984d40SFabiano Rosas /* Indexed by [mte][be][ff][xs][u][msz]. */ 5248f0984d40SFabiano Rosas static gen_helper_gvec_mem_scatter * const 5249f0984d40SFabiano Rosas gather_load_fn32[2][2][2][2][2][3] = { 5250f0984d40SFabiano Rosas { /* MTE Inactive */ 5251f0984d40SFabiano Rosas { /* Little-endian */ 5252f0984d40SFabiano Rosas { { { gen_helper_sve_ldbss_zsu, 5253f0984d40SFabiano Rosas gen_helper_sve_ldhss_le_zsu, 5254f0984d40SFabiano Rosas NULL, }, 5255f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zsu, 5256f0984d40SFabiano Rosas gen_helper_sve_ldhsu_le_zsu, 5257f0984d40SFabiano Rosas gen_helper_sve_ldss_le_zsu, } }, 5258f0984d40SFabiano Rosas { { gen_helper_sve_ldbss_zss, 5259f0984d40SFabiano Rosas gen_helper_sve_ldhss_le_zss, 5260f0984d40SFabiano Rosas NULL, }, 5261f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zss, 5262f0984d40SFabiano Rosas gen_helper_sve_ldhsu_le_zss, 5263f0984d40SFabiano Rosas gen_helper_sve_ldss_le_zss, } } }, 5264f0984d40SFabiano Rosas 5265f0984d40SFabiano Rosas /* First-fault */ 5266f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbss_zsu, 5267f0984d40SFabiano Rosas gen_helper_sve_ldffhss_le_zsu, 5268f0984d40SFabiano Rosas NULL, }, 5269f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zsu, 5270f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_le_zsu, 5271f0984d40SFabiano Rosas gen_helper_sve_ldffss_le_zsu, } }, 5272f0984d40SFabiano Rosas { { gen_helper_sve_ldffbss_zss, 5273f0984d40SFabiano Rosas gen_helper_sve_ldffhss_le_zss, 5274f0984d40SFabiano Rosas NULL, }, 5275f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zss, 5276f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_le_zss, 5277f0984d40SFabiano Rosas gen_helper_sve_ldffss_le_zss, } } } }, 5278f0984d40SFabiano Rosas 5279f0984d40SFabiano Rosas { /* Big-endian */ 5280f0984d40SFabiano Rosas { { { gen_helper_sve_ldbss_zsu, 5281f0984d40SFabiano Rosas gen_helper_sve_ldhss_be_zsu, 5282f0984d40SFabiano Rosas NULL, }, 5283f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zsu, 5284f0984d40SFabiano Rosas gen_helper_sve_ldhsu_be_zsu, 5285f0984d40SFabiano Rosas gen_helper_sve_ldss_be_zsu, } }, 5286f0984d40SFabiano Rosas { { gen_helper_sve_ldbss_zss, 5287f0984d40SFabiano Rosas gen_helper_sve_ldhss_be_zss, 5288f0984d40SFabiano Rosas NULL, }, 5289f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zss, 5290f0984d40SFabiano Rosas gen_helper_sve_ldhsu_be_zss, 5291f0984d40SFabiano Rosas gen_helper_sve_ldss_be_zss, } } }, 5292f0984d40SFabiano Rosas 5293f0984d40SFabiano Rosas /* First-fault */ 5294f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbss_zsu, 5295f0984d40SFabiano Rosas gen_helper_sve_ldffhss_be_zsu, 5296f0984d40SFabiano Rosas NULL, }, 5297f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zsu, 5298f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_be_zsu, 5299f0984d40SFabiano Rosas gen_helper_sve_ldffss_be_zsu, } }, 5300f0984d40SFabiano Rosas { { gen_helper_sve_ldffbss_zss, 5301f0984d40SFabiano Rosas gen_helper_sve_ldffhss_be_zss, 5302f0984d40SFabiano Rosas NULL, }, 5303f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zss, 5304f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_be_zss, 5305f0984d40SFabiano Rosas gen_helper_sve_ldffss_be_zss, } } } } }, 5306f0984d40SFabiano Rosas { /* MTE Active */ 5307f0984d40SFabiano Rosas { /* Little-endian */ 5308f0984d40SFabiano Rosas { { { gen_helper_sve_ldbss_zsu_mte, 5309f0984d40SFabiano Rosas gen_helper_sve_ldhss_le_zsu_mte, 5310f0984d40SFabiano Rosas NULL, }, 5311f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zsu_mte, 5312f0984d40SFabiano Rosas gen_helper_sve_ldhsu_le_zsu_mte, 5313f0984d40SFabiano Rosas gen_helper_sve_ldss_le_zsu_mte, } }, 5314f0984d40SFabiano Rosas { { gen_helper_sve_ldbss_zss_mte, 5315f0984d40SFabiano Rosas gen_helper_sve_ldhss_le_zss_mte, 5316f0984d40SFabiano Rosas NULL, }, 5317f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zss_mte, 5318f0984d40SFabiano Rosas gen_helper_sve_ldhsu_le_zss_mte, 5319f0984d40SFabiano Rosas gen_helper_sve_ldss_le_zss_mte, } } }, 5320f0984d40SFabiano Rosas 5321f0984d40SFabiano Rosas /* First-fault */ 5322f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbss_zsu_mte, 5323f0984d40SFabiano Rosas gen_helper_sve_ldffhss_le_zsu_mte, 5324f0984d40SFabiano Rosas NULL, }, 5325f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zsu_mte, 5326f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_le_zsu_mte, 5327f0984d40SFabiano Rosas gen_helper_sve_ldffss_le_zsu_mte, } }, 5328f0984d40SFabiano Rosas { { gen_helper_sve_ldffbss_zss_mte, 5329f0984d40SFabiano Rosas gen_helper_sve_ldffhss_le_zss_mte, 5330f0984d40SFabiano Rosas NULL, }, 5331f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zss_mte, 5332f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_le_zss_mte, 5333f0984d40SFabiano Rosas gen_helper_sve_ldffss_le_zss_mte, } } } }, 5334f0984d40SFabiano Rosas 5335f0984d40SFabiano Rosas { /* Big-endian */ 5336f0984d40SFabiano Rosas { { { gen_helper_sve_ldbss_zsu_mte, 5337f0984d40SFabiano Rosas gen_helper_sve_ldhss_be_zsu_mte, 5338f0984d40SFabiano Rosas NULL, }, 5339f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zsu_mte, 5340f0984d40SFabiano Rosas gen_helper_sve_ldhsu_be_zsu_mte, 5341f0984d40SFabiano Rosas gen_helper_sve_ldss_be_zsu_mte, } }, 5342f0984d40SFabiano Rosas { { gen_helper_sve_ldbss_zss_mte, 5343f0984d40SFabiano Rosas gen_helper_sve_ldhss_be_zss_mte, 5344f0984d40SFabiano Rosas NULL, }, 5345f0984d40SFabiano Rosas { gen_helper_sve_ldbsu_zss_mte, 5346f0984d40SFabiano Rosas gen_helper_sve_ldhsu_be_zss_mte, 5347f0984d40SFabiano Rosas gen_helper_sve_ldss_be_zss_mte, } } }, 5348f0984d40SFabiano Rosas 5349f0984d40SFabiano Rosas /* First-fault */ 5350f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbss_zsu_mte, 5351f0984d40SFabiano Rosas gen_helper_sve_ldffhss_be_zsu_mte, 5352f0984d40SFabiano Rosas NULL, }, 5353f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zsu_mte, 5354f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_be_zsu_mte, 5355f0984d40SFabiano Rosas gen_helper_sve_ldffss_be_zsu_mte, } }, 5356f0984d40SFabiano Rosas { { gen_helper_sve_ldffbss_zss_mte, 5357f0984d40SFabiano Rosas gen_helper_sve_ldffhss_be_zss_mte, 5358f0984d40SFabiano Rosas NULL, }, 5359f0984d40SFabiano Rosas { gen_helper_sve_ldffbsu_zss_mte, 5360f0984d40SFabiano Rosas gen_helper_sve_ldffhsu_be_zss_mte, 5361f0984d40SFabiano Rosas gen_helper_sve_ldffss_be_zss_mte, } } } } }, 5362f0984d40SFabiano Rosas }; 5363f0984d40SFabiano Rosas 5364f0984d40SFabiano Rosas /* Note that we overload xs=2 to indicate 64-bit offset. */ 5365f0984d40SFabiano Rosas static gen_helper_gvec_mem_scatter * const 5366f0984d40SFabiano Rosas gather_load_fn64[2][2][2][3][2][4] = { 5367f0984d40SFabiano Rosas { /* MTE Inactive */ 5368f0984d40SFabiano Rosas { /* Little-endian */ 5369f0984d40SFabiano Rosas { { { gen_helper_sve_ldbds_zsu, 5370f0984d40SFabiano Rosas gen_helper_sve_ldhds_le_zsu, 5371f0984d40SFabiano Rosas gen_helper_sve_ldsds_le_zsu, 5372f0984d40SFabiano Rosas NULL, }, 5373f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zsu, 5374f0984d40SFabiano Rosas gen_helper_sve_ldhdu_le_zsu, 5375f0984d40SFabiano Rosas gen_helper_sve_ldsdu_le_zsu, 5376f0984d40SFabiano Rosas gen_helper_sve_lddd_le_zsu, } }, 5377f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zss, 5378f0984d40SFabiano Rosas gen_helper_sve_ldhds_le_zss, 5379f0984d40SFabiano Rosas gen_helper_sve_ldsds_le_zss, 5380f0984d40SFabiano Rosas NULL, }, 5381f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zss, 5382f0984d40SFabiano Rosas gen_helper_sve_ldhdu_le_zss, 5383f0984d40SFabiano Rosas gen_helper_sve_ldsdu_le_zss, 5384f0984d40SFabiano Rosas gen_helper_sve_lddd_le_zss, } }, 5385f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zd, 5386f0984d40SFabiano Rosas gen_helper_sve_ldhds_le_zd, 5387f0984d40SFabiano Rosas gen_helper_sve_ldsds_le_zd, 5388f0984d40SFabiano Rosas NULL, }, 5389f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zd, 5390f0984d40SFabiano Rosas gen_helper_sve_ldhdu_le_zd, 5391f0984d40SFabiano Rosas gen_helper_sve_ldsdu_le_zd, 5392f0984d40SFabiano Rosas gen_helper_sve_lddd_le_zd, } } }, 5393f0984d40SFabiano Rosas 5394f0984d40SFabiano Rosas /* First-fault */ 5395f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbds_zsu, 5396f0984d40SFabiano Rosas gen_helper_sve_ldffhds_le_zsu, 5397f0984d40SFabiano Rosas gen_helper_sve_ldffsds_le_zsu, 5398f0984d40SFabiano Rosas NULL, }, 5399f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zsu, 5400f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_le_zsu, 5401f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_le_zsu, 5402f0984d40SFabiano Rosas gen_helper_sve_ldffdd_le_zsu, } }, 5403f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zss, 5404f0984d40SFabiano Rosas gen_helper_sve_ldffhds_le_zss, 5405f0984d40SFabiano Rosas gen_helper_sve_ldffsds_le_zss, 5406f0984d40SFabiano Rosas NULL, }, 5407f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zss, 5408f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_le_zss, 5409f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_le_zss, 5410f0984d40SFabiano Rosas gen_helper_sve_ldffdd_le_zss, } }, 5411f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zd, 5412f0984d40SFabiano Rosas gen_helper_sve_ldffhds_le_zd, 5413f0984d40SFabiano Rosas gen_helper_sve_ldffsds_le_zd, 5414f0984d40SFabiano Rosas NULL, }, 5415f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zd, 5416f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_le_zd, 5417f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_le_zd, 5418f0984d40SFabiano Rosas gen_helper_sve_ldffdd_le_zd, } } } }, 5419f0984d40SFabiano Rosas { /* Big-endian */ 5420f0984d40SFabiano Rosas { { { gen_helper_sve_ldbds_zsu, 5421f0984d40SFabiano Rosas gen_helper_sve_ldhds_be_zsu, 5422f0984d40SFabiano Rosas gen_helper_sve_ldsds_be_zsu, 5423f0984d40SFabiano Rosas NULL, }, 5424f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zsu, 5425f0984d40SFabiano Rosas gen_helper_sve_ldhdu_be_zsu, 5426f0984d40SFabiano Rosas gen_helper_sve_ldsdu_be_zsu, 5427f0984d40SFabiano Rosas gen_helper_sve_lddd_be_zsu, } }, 5428f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zss, 5429f0984d40SFabiano Rosas gen_helper_sve_ldhds_be_zss, 5430f0984d40SFabiano Rosas gen_helper_sve_ldsds_be_zss, 5431f0984d40SFabiano Rosas NULL, }, 5432f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zss, 5433f0984d40SFabiano Rosas gen_helper_sve_ldhdu_be_zss, 5434f0984d40SFabiano Rosas gen_helper_sve_ldsdu_be_zss, 5435f0984d40SFabiano Rosas gen_helper_sve_lddd_be_zss, } }, 5436f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zd, 5437f0984d40SFabiano Rosas gen_helper_sve_ldhds_be_zd, 5438f0984d40SFabiano Rosas gen_helper_sve_ldsds_be_zd, 5439f0984d40SFabiano Rosas NULL, }, 5440f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zd, 5441f0984d40SFabiano Rosas gen_helper_sve_ldhdu_be_zd, 5442f0984d40SFabiano Rosas gen_helper_sve_ldsdu_be_zd, 5443f0984d40SFabiano Rosas gen_helper_sve_lddd_be_zd, } } }, 5444f0984d40SFabiano Rosas 5445f0984d40SFabiano Rosas /* First-fault */ 5446f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbds_zsu, 5447f0984d40SFabiano Rosas gen_helper_sve_ldffhds_be_zsu, 5448f0984d40SFabiano Rosas gen_helper_sve_ldffsds_be_zsu, 5449f0984d40SFabiano Rosas NULL, }, 5450f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zsu, 5451f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_be_zsu, 5452f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_be_zsu, 5453f0984d40SFabiano Rosas gen_helper_sve_ldffdd_be_zsu, } }, 5454f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zss, 5455f0984d40SFabiano Rosas gen_helper_sve_ldffhds_be_zss, 5456f0984d40SFabiano Rosas gen_helper_sve_ldffsds_be_zss, 5457f0984d40SFabiano Rosas NULL, }, 5458f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zss, 5459f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_be_zss, 5460f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_be_zss, 5461f0984d40SFabiano Rosas gen_helper_sve_ldffdd_be_zss, } }, 5462f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zd, 5463f0984d40SFabiano Rosas gen_helper_sve_ldffhds_be_zd, 5464f0984d40SFabiano Rosas gen_helper_sve_ldffsds_be_zd, 5465f0984d40SFabiano Rosas NULL, }, 5466f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zd, 5467f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_be_zd, 5468f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_be_zd, 5469f0984d40SFabiano Rosas gen_helper_sve_ldffdd_be_zd, } } } } }, 5470f0984d40SFabiano Rosas { /* MTE Active */ 5471f0984d40SFabiano Rosas { /* Little-endian */ 5472f0984d40SFabiano Rosas { { { gen_helper_sve_ldbds_zsu_mte, 5473f0984d40SFabiano Rosas gen_helper_sve_ldhds_le_zsu_mte, 5474f0984d40SFabiano Rosas gen_helper_sve_ldsds_le_zsu_mte, 5475f0984d40SFabiano Rosas NULL, }, 5476f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zsu_mte, 5477f0984d40SFabiano Rosas gen_helper_sve_ldhdu_le_zsu_mte, 5478f0984d40SFabiano Rosas gen_helper_sve_ldsdu_le_zsu_mte, 5479f0984d40SFabiano Rosas gen_helper_sve_lddd_le_zsu_mte, } }, 5480f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zss_mte, 5481f0984d40SFabiano Rosas gen_helper_sve_ldhds_le_zss_mte, 5482f0984d40SFabiano Rosas gen_helper_sve_ldsds_le_zss_mte, 5483f0984d40SFabiano Rosas NULL, }, 5484f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zss_mte, 5485f0984d40SFabiano Rosas gen_helper_sve_ldhdu_le_zss_mte, 5486f0984d40SFabiano Rosas gen_helper_sve_ldsdu_le_zss_mte, 5487f0984d40SFabiano Rosas gen_helper_sve_lddd_le_zss_mte, } }, 5488f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zd_mte, 5489f0984d40SFabiano Rosas gen_helper_sve_ldhds_le_zd_mte, 5490f0984d40SFabiano Rosas gen_helper_sve_ldsds_le_zd_mte, 5491f0984d40SFabiano Rosas NULL, }, 5492f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zd_mte, 5493f0984d40SFabiano Rosas gen_helper_sve_ldhdu_le_zd_mte, 5494f0984d40SFabiano Rosas gen_helper_sve_ldsdu_le_zd_mte, 5495f0984d40SFabiano Rosas gen_helper_sve_lddd_le_zd_mte, } } }, 5496f0984d40SFabiano Rosas 5497f0984d40SFabiano Rosas /* First-fault */ 5498f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbds_zsu_mte, 5499f0984d40SFabiano Rosas gen_helper_sve_ldffhds_le_zsu_mte, 5500f0984d40SFabiano Rosas gen_helper_sve_ldffsds_le_zsu_mte, 5501f0984d40SFabiano Rosas NULL, }, 5502f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zsu_mte, 5503f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_le_zsu_mte, 5504f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_le_zsu_mte, 5505f0984d40SFabiano Rosas gen_helper_sve_ldffdd_le_zsu_mte, } }, 5506f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zss_mte, 5507f0984d40SFabiano Rosas gen_helper_sve_ldffhds_le_zss_mte, 5508f0984d40SFabiano Rosas gen_helper_sve_ldffsds_le_zss_mte, 5509f0984d40SFabiano Rosas NULL, }, 5510f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zss_mte, 5511f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_le_zss_mte, 5512f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_le_zss_mte, 5513f0984d40SFabiano Rosas gen_helper_sve_ldffdd_le_zss_mte, } }, 5514f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zd_mte, 5515f0984d40SFabiano Rosas gen_helper_sve_ldffhds_le_zd_mte, 5516f0984d40SFabiano Rosas gen_helper_sve_ldffsds_le_zd_mte, 5517f0984d40SFabiano Rosas NULL, }, 5518f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zd_mte, 5519f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_le_zd_mte, 5520f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_le_zd_mte, 5521f0984d40SFabiano Rosas gen_helper_sve_ldffdd_le_zd_mte, } } } }, 5522f0984d40SFabiano Rosas { /* Big-endian */ 5523f0984d40SFabiano Rosas { { { gen_helper_sve_ldbds_zsu_mte, 5524f0984d40SFabiano Rosas gen_helper_sve_ldhds_be_zsu_mte, 5525f0984d40SFabiano Rosas gen_helper_sve_ldsds_be_zsu_mte, 5526f0984d40SFabiano Rosas NULL, }, 5527f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zsu_mte, 5528f0984d40SFabiano Rosas gen_helper_sve_ldhdu_be_zsu_mte, 5529f0984d40SFabiano Rosas gen_helper_sve_ldsdu_be_zsu_mte, 5530f0984d40SFabiano Rosas gen_helper_sve_lddd_be_zsu_mte, } }, 5531f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zss_mte, 5532f0984d40SFabiano Rosas gen_helper_sve_ldhds_be_zss_mte, 5533f0984d40SFabiano Rosas gen_helper_sve_ldsds_be_zss_mte, 5534f0984d40SFabiano Rosas NULL, }, 5535f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zss_mte, 5536f0984d40SFabiano Rosas gen_helper_sve_ldhdu_be_zss_mte, 5537f0984d40SFabiano Rosas gen_helper_sve_ldsdu_be_zss_mte, 5538f0984d40SFabiano Rosas gen_helper_sve_lddd_be_zss_mte, } }, 5539f0984d40SFabiano Rosas { { gen_helper_sve_ldbds_zd_mte, 5540f0984d40SFabiano Rosas gen_helper_sve_ldhds_be_zd_mte, 5541f0984d40SFabiano Rosas gen_helper_sve_ldsds_be_zd_mte, 5542f0984d40SFabiano Rosas NULL, }, 5543f0984d40SFabiano Rosas { gen_helper_sve_ldbdu_zd_mte, 5544f0984d40SFabiano Rosas gen_helper_sve_ldhdu_be_zd_mte, 5545f0984d40SFabiano Rosas gen_helper_sve_ldsdu_be_zd_mte, 5546f0984d40SFabiano Rosas gen_helper_sve_lddd_be_zd_mte, } } }, 5547f0984d40SFabiano Rosas 5548f0984d40SFabiano Rosas /* First-fault */ 5549f0984d40SFabiano Rosas { { { gen_helper_sve_ldffbds_zsu_mte, 5550f0984d40SFabiano Rosas gen_helper_sve_ldffhds_be_zsu_mte, 5551f0984d40SFabiano Rosas gen_helper_sve_ldffsds_be_zsu_mte, 5552f0984d40SFabiano Rosas NULL, }, 5553f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zsu_mte, 5554f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_be_zsu_mte, 5555f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_be_zsu_mte, 5556f0984d40SFabiano Rosas gen_helper_sve_ldffdd_be_zsu_mte, } }, 5557f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zss_mte, 5558f0984d40SFabiano Rosas gen_helper_sve_ldffhds_be_zss_mte, 5559f0984d40SFabiano Rosas gen_helper_sve_ldffsds_be_zss_mte, 5560f0984d40SFabiano Rosas NULL, }, 5561f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zss_mte, 5562f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_be_zss_mte, 5563f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_be_zss_mte, 5564f0984d40SFabiano Rosas gen_helper_sve_ldffdd_be_zss_mte, } }, 5565f0984d40SFabiano Rosas { { gen_helper_sve_ldffbds_zd_mte, 5566f0984d40SFabiano Rosas gen_helper_sve_ldffhds_be_zd_mte, 5567f0984d40SFabiano Rosas gen_helper_sve_ldffsds_be_zd_mte, 5568f0984d40SFabiano Rosas NULL, }, 5569f0984d40SFabiano Rosas { gen_helper_sve_ldffbdu_zd_mte, 5570f0984d40SFabiano Rosas gen_helper_sve_ldffhdu_be_zd_mte, 5571f0984d40SFabiano Rosas gen_helper_sve_ldffsdu_be_zd_mte, 5572f0984d40SFabiano Rosas gen_helper_sve_ldffdd_be_zd_mte, } } } } }, 5573f0984d40SFabiano Rosas }; 5574f0984d40SFabiano Rosas 5575f0984d40SFabiano Rosas static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a) 5576f0984d40SFabiano Rosas { 5577f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn = NULL; 5578f0984d40SFabiano Rosas bool be = s->be_data == MO_BE; 5579f0984d40SFabiano Rosas bool mte = s->mte_active[0]; 5580f0984d40SFabiano Rosas 5581f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5582f0984d40SFabiano Rosas return false; 5583f0984d40SFabiano Rosas } 5584f0984d40SFabiano Rosas s->is_nonstreaming = true; 5585f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5586f0984d40SFabiano Rosas return true; 5587f0984d40SFabiano Rosas } 5588f0984d40SFabiano Rosas 5589f0984d40SFabiano Rosas switch (a->esz) { 5590f0984d40SFabiano Rosas case MO_32: 5591f0984d40SFabiano Rosas fn = gather_load_fn32[mte][be][a->ff][a->xs][a->u][a->msz]; 5592f0984d40SFabiano Rosas break; 5593f0984d40SFabiano Rosas case MO_64: 5594f0984d40SFabiano Rosas fn = gather_load_fn64[mte][be][a->ff][a->xs][a->u][a->msz]; 5595f0984d40SFabiano Rosas break; 5596f0984d40SFabiano Rosas } 5597f0984d40SFabiano Rosas assert(fn != NULL); 5598f0984d40SFabiano Rosas 5599f0984d40SFabiano Rosas do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz, 5600f0984d40SFabiano Rosas cpu_reg_sp(s, a->rn), a->msz, false, fn); 5601f0984d40SFabiano Rosas return true; 5602f0984d40SFabiano Rosas } 5603f0984d40SFabiano Rosas 5604f0984d40SFabiano Rosas static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a) 5605f0984d40SFabiano Rosas { 5606f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn = NULL; 5607f0984d40SFabiano Rosas bool be = s->be_data == MO_BE; 5608f0984d40SFabiano Rosas bool mte = s->mte_active[0]; 5609f0984d40SFabiano Rosas 5610f0984d40SFabiano Rosas if (a->esz < a->msz || (a->esz == a->msz && !a->u)) { 5611f0984d40SFabiano Rosas return false; 5612f0984d40SFabiano Rosas } 5613f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5614f0984d40SFabiano Rosas return false; 5615f0984d40SFabiano Rosas } 5616f0984d40SFabiano Rosas s->is_nonstreaming = true; 5617f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5618f0984d40SFabiano Rosas return true; 5619f0984d40SFabiano Rosas } 5620f0984d40SFabiano Rosas 5621f0984d40SFabiano Rosas switch (a->esz) { 5622f0984d40SFabiano Rosas case MO_32: 5623f0984d40SFabiano Rosas fn = gather_load_fn32[mte][be][a->ff][0][a->u][a->msz]; 5624f0984d40SFabiano Rosas break; 5625f0984d40SFabiano Rosas case MO_64: 5626f0984d40SFabiano Rosas fn = gather_load_fn64[mte][be][a->ff][2][a->u][a->msz]; 5627f0984d40SFabiano Rosas break; 5628f0984d40SFabiano Rosas } 5629f0984d40SFabiano Rosas assert(fn != NULL); 5630f0984d40SFabiano Rosas 5631f0984d40SFabiano Rosas /* Treat LD1_zpiz (zn[x] + imm) the same way as LD1_zprz (rn + zm[x]) 5632f0984d40SFabiano Rosas * by loading the immediate into the scalar parameter. 5633f0984d40SFabiano Rosas */ 5634f0984d40SFabiano Rosas do_mem_zpz(s, a->rd, a->pg, a->rn, 0, 5635f0984d40SFabiano Rosas tcg_constant_i64(a->imm << a->msz), a->msz, false, fn); 5636f0984d40SFabiano Rosas return true; 5637f0984d40SFabiano Rosas } 5638f0984d40SFabiano Rosas 5639f0984d40SFabiano Rosas static bool trans_LDNT1_zprz(DisasContext *s, arg_LD1_zprz *a) 5640f0984d40SFabiano Rosas { 5641f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn = NULL; 5642f0984d40SFabiano Rosas bool be = s->be_data == MO_BE; 5643f0984d40SFabiano Rosas bool mte = s->mte_active[0]; 5644f0984d40SFabiano Rosas 5645f0984d40SFabiano Rosas if (a->esz < a->msz + !a->u) { 5646f0984d40SFabiano Rosas return false; 5647f0984d40SFabiano Rosas } 5648f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve2, s)) { 5649f0984d40SFabiano Rosas return false; 5650f0984d40SFabiano Rosas } 5651f0984d40SFabiano Rosas s->is_nonstreaming = true; 5652f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5653f0984d40SFabiano Rosas return true; 5654f0984d40SFabiano Rosas } 5655f0984d40SFabiano Rosas 5656f0984d40SFabiano Rosas switch (a->esz) { 5657f0984d40SFabiano Rosas case MO_32: 5658f0984d40SFabiano Rosas fn = gather_load_fn32[mte][be][0][0][a->u][a->msz]; 5659f0984d40SFabiano Rosas break; 5660f0984d40SFabiano Rosas case MO_64: 5661f0984d40SFabiano Rosas fn = gather_load_fn64[mte][be][0][2][a->u][a->msz]; 5662f0984d40SFabiano Rosas break; 5663f0984d40SFabiano Rosas } 5664f0984d40SFabiano Rosas assert(fn != NULL); 5665f0984d40SFabiano Rosas 5666f0984d40SFabiano Rosas do_mem_zpz(s, a->rd, a->pg, a->rn, 0, 5667f0984d40SFabiano Rosas cpu_reg(s, a->rm), a->msz, false, fn); 5668f0984d40SFabiano Rosas return true; 5669f0984d40SFabiano Rosas } 5670f0984d40SFabiano Rosas 5671f0984d40SFabiano Rosas /* Indexed by [mte][be][xs][msz]. */ 5672f0984d40SFabiano Rosas static gen_helper_gvec_mem_scatter * const scatter_store_fn32[2][2][2][3] = { 5673f0984d40SFabiano Rosas { /* MTE Inactive */ 5674f0984d40SFabiano Rosas { /* Little-endian */ 5675f0984d40SFabiano Rosas { gen_helper_sve_stbs_zsu, 5676f0984d40SFabiano Rosas gen_helper_sve_sths_le_zsu, 5677f0984d40SFabiano Rosas gen_helper_sve_stss_le_zsu, }, 5678f0984d40SFabiano Rosas { gen_helper_sve_stbs_zss, 5679f0984d40SFabiano Rosas gen_helper_sve_sths_le_zss, 5680f0984d40SFabiano Rosas gen_helper_sve_stss_le_zss, } }, 5681f0984d40SFabiano Rosas { /* Big-endian */ 5682f0984d40SFabiano Rosas { gen_helper_sve_stbs_zsu, 5683f0984d40SFabiano Rosas gen_helper_sve_sths_be_zsu, 5684f0984d40SFabiano Rosas gen_helper_sve_stss_be_zsu, }, 5685f0984d40SFabiano Rosas { gen_helper_sve_stbs_zss, 5686f0984d40SFabiano Rosas gen_helper_sve_sths_be_zss, 5687f0984d40SFabiano Rosas gen_helper_sve_stss_be_zss, } } }, 5688f0984d40SFabiano Rosas { /* MTE Active */ 5689f0984d40SFabiano Rosas { /* Little-endian */ 5690f0984d40SFabiano Rosas { gen_helper_sve_stbs_zsu_mte, 5691f0984d40SFabiano Rosas gen_helper_sve_sths_le_zsu_mte, 5692f0984d40SFabiano Rosas gen_helper_sve_stss_le_zsu_mte, }, 5693f0984d40SFabiano Rosas { gen_helper_sve_stbs_zss_mte, 5694f0984d40SFabiano Rosas gen_helper_sve_sths_le_zss_mte, 5695f0984d40SFabiano Rosas gen_helper_sve_stss_le_zss_mte, } }, 5696f0984d40SFabiano Rosas { /* Big-endian */ 5697f0984d40SFabiano Rosas { gen_helper_sve_stbs_zsu_mte, 5698f0984d40SFabiano Rosas gen_helper_sve_sths_be_zsu_mte, 5699f0984d40SFabiano Rosas gen_helper_sve_stss_be_zsu_mte, }, 5700f0984d40SFabiano Rosas { gen_helper_sve_stbs_zss_mte, 5701f0984d40SFabiano Rosas gen_helper_sve_sths_be_zss_mte, 5702f0984d40SFabiano Rosas gen_helper_sve_stss_be_zss_mte, } } }, 5703f0984d40SFabiano Rosas }; 5704f0984d40SFabiano Rosas 5705f0984d40SFabiano Rosas /* Note that we overload xs=2 to indicate 64-bit offset. */ 5706f0984d40SFabiano Rosas static gen_helper_gvec_mem_scatter * const scatter_store_fn64[2][2][3][4] = { 5707f0984d40SFabiano Rosas { /* MTE Inactive */ 5708f0984d40SFabiano Rosas { /* Little-endian */ 5709f0984d40SFabiano Rosas { gen_helper_sve_stbd_zsu, 5710f0984d40SFabiano Rosas gen_helper_sve_sthd_le_zsu, 5711f0984d40SFabiano Rosas gen_helper_sve_stsd_le_zsu, 5712f0984d40SFabiano Rosas gen_helper_sve_stdd_le_zsu, }, 5713f0984d40SFabiano Rosas { gen_helper_sve_stbd_zss, 5714f0984d40SFabiano Rosas gen_helper_sve_sthd_le_zss, 5715f0984d40SFabiano Rosas gen_helper_sve_stsd_le_zss, 5716f0984d40SFabiano Rosas gen_helper_sve_stdd_le_zss, }, 5717f0984d40SFabiano Rosas { gen_helper_sve_stbd_zd, 5718f0984d40SFabiano Rosas gen_helper_sve_sthd_le_zd, 5719f0984d40SFabiano Rosas gen_helper_sve_stsd_le_zd, 5720f0984d40SFabiano Rosas gen_helper_sve_stdd_le_zd, } }, 5721f0984d40SFabiano Rosas { /* Big-endian */ 5722f0984d40SFabiano Rosas { gen_helper_sve_stbd_zsu, 5723f0984d40SFabiano Rosas gen_helper_sve_sthd_be_zsu, 5724f0984d40SFabiano Rosas gen_helper_sve_stsd_be_zsu, 5725f0984d40SFabiano Rosas gen_helper_sve_stdd_be_zsu, }, 5726f0984d40SFabiano Rosas { gen_helper_sve_stbd_zss, 5727f0984d40SFabiano Rosas gen_helper_sve_sthd_be_zss, 5728f0984d40SFabiano Rosas gen_helper_sve_stsd_be_zss, 5729f0984d40SFabiano Rosas gen_helper_sve_stdd_be_zss, }, 5730f0984d40SFabiano Rosas { gen_helper_sve_stbd_zd, 5731f0984d40SFabiano Rosas gen_helper_sve_sthd_be_zd, 5732f0984d40SFabiano Rosas gen_helper_sve_stsd_be_zd, 5733f0984d40SFabiano Rosas gen_helper_sve_stdd_be_zd, } } }, 5734f0984d40SFabiano Rosas { /* MTE Inactive */ 5735f0984d40SFabiano Rosas { /* Little-endian */ 5736f0984d40SFabiano Rosas { gen_helper_sve_stbd_zsu_mte, 5737f0984d40SFabiano Rosas gen_helper_sve_sthd_le_zsu_mte, 5738f0984d40SFabiano Rosas gen_helper_sve_stsd_le_zsu_mte, 5739f0984d40SFabiano Rosas gen_helper_sve_stdd_le_zsu_mte, }, 5740f0984d40SFabiano Rosas { gen_helper_sve_stbd_zss_mte, 5741f0984d40SFabiano Rosas gen_helper_sve_sthd_le_zss_mte, 5742f0984d40SFabiano Rosas gen_helper_sve_stsd_le_zss_mte, 5743f0984d40SFabiano Rosas gen_helper_sve_stdd_le_zss_mte, }, 5744f0984d40SFabiano Rosas { gen_helper_sve_stbd_zd_mte, 5745f0984d40SFabiano Rosas gen_helper_sve_sthd_le_zd_mte, 5746f0984d40SFabiano Rosas gen_helper_sve_stsd_le_zd_mte, 5747f0984d40SFabiano Rosas gen_helper_sve_stdd_le_zd_mte, } }, 5748f0984d40SFabiano Rosas { /* Big-endian */ 5749f0984d40SFabiano Rosas { gen_helper_sve_stbd_zsu_mte, 5750f0984d40SFabiano Rosas gen_helper_sve_sthd_be_zsu_mte, 5751f0984d40SFabiano Rosas gen_helper_sve_stsd_be_zsu_mte, 5752f0984d40SFabiano Rosas gen_helper_sve_stdd_be_zsu_mte, }, 5753f0984d40SFabiano Rosas { gen_helper_sve_stbd_zss_mte, 5754f0984d40SFabiano Rosas gen_helper_sve_sthd_be_zss_mte, 5755f0984d40SFabiano Rosas gen_helper_sve_stsd_be_zss_mte, 5756f0984d40SFabiano Rosas gen_helper_sve_stdd_be_zss_mte, }, 5757f0984d40SFabiano Rosas { gen_helper_sve_stbd_zd_mte, 5758f0984d40SFabiano Rosas gen_helper_sve_sthd_be_zd_mte, 5759f0984d40SFabiano Rosas gen_helper_sve_stsd_be_zd_mte, 5760f0984d40SFabiano Rosas gen_helper_sve_stdd_be_zd_mte, } } }, 5761f0984d40SFabiano Rosas }; 5762f0984d40SFabiano Rosas 5763f0984d40SFabiano Rosas static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a) 5764f0984d40SFabiano Rosas { 5765f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn; 5766f0984d40SFabiano Rosas bool be = s->be_data == MO_BE; 5767f0984d40SFabiano Rosas bool mte = s->mte_active[0]; 5768f0984d40SFabiano Rosas 5769f0984d40SFabiano Rosas if (a->esz < a->msz || (a->msz == 0 && a->scale)) { 5770f0984d40SFabiano Rosas return false; 5771f0984d40SFabiano Rosas } 5772f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5773f0984d40SFabiano Rosas return false; 5774f0984d40SFabiano Rosas } 5775f0984d40SFabiano Rosas s->is_nonstreaming = true; 5776f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5777f0984d40SFabiano Rosas return true; 5778f0984d40SFabiano Rosas } 5779f0984d40SFabiano Rosas switch (a->esz) { 5780f0984d40SFabiano Rosas case MO_32: 5781f0984d40SFabiano Rosas fn = scatter_store_fn32[mte][be][a->xs][a->msz]; 5782f0984d40SFabiano Rosas break; 5783f0984d40SFabiano Rosas case MO_64: 5784f0984d40SFabiano Rosas fn = scatter_store_fn64[mte][be][a->xs][a->msz]; 5785f0984d40SFabiano Rosas break; 5786f0984d40SFabiano Rosas default: 5787f0984d40SFabiano Rosas g_assert_not_reached(); 5788f0984d40SFabiano Rosas } 5789f0984d40SFabiano Rosas do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz, 5790f0984d40SFabiano Rosas cpu_reg_sp(s, a->rn), a->msz, true, fn); 5791f0984d40SFabiano Rosas return true; 5792f0984d40SFabiano Rosas } 5793f0984d40SFabiano Rosas 5794f0984d40SFabiano Rosas static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a) 5795f0984d40SFabiano Rosas { 5796f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn = NULL; 5797f0984d40SFabiano Rosas bool be = s->be_data == MO_BE; 5798f0984d40SFabiano Rosas bool mte = s->mte_active[0]; 5799f0984d40SFabiano Rosas 5800f0984d40SFabiano Rosas if (a->esz < a->msz) { 5801f0984d40SFabiano Rosas return false; 5802f0984d40SFabiano Rosas } 5803f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5804f0984d40SFabiano Rosas return false; 5805f0984d40SFabiano Rosas } 5806f0984d40SFabiano Rosas s->is_nonstreaming = true; 5807f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5808f0984d40SFabiano Rosas return true; 5809f0984d40SFabiano Rosas } 5810f0984d40SFabiano Rosas 5811f0984d40SFabiano Rosas switch (a->esz) { 5812f0984d40SFabiano Rosas case MO_32: 5813f0984d40SFabiano Rosas fn = scatter_store_fn32[mte][be][0][a->msz]; 5814f0984d40SFabiano Rosas break; 5815f0984d40SFabiano Rosas case MO_64: 5816f0984d40SFabiano Rosas fn = scatter_store_fn64[mte][be][2][a->msz]; 5817f0984d40SFabiano Rosas break; 5818f0984d40SFabiano Rosas } 5819f0984d40SFabiano Rosas assert(fn != NULL); 5820f0984d40SFabiano Rosas 5821f0984d40SFabiano Rosas /* Treat ST1_zpiz (zn[x] + imm) the same way as ST1_zprz (rn + zm[x]) 5822f0984d40SFabiano Rosas * by loading the immediate into the scalar parameter. 5823f0984d40SFabiano Rosas */ 5824f0984d40SFabiano Rosas do_mem_zpz(s, a->rd, a->pg, a->rn, 0, 5825f0984d40SFabiano Rosas tcg_constant_i64(a->imm << a->msz), a->msz, true, fn); 5826f0984d40SFabiano Rosas return true; 5827f0984d40SFabiano Rosas } 5828f0984d40SFabiano Rosas 5829f0984d40SFabiano Rosas static bool trans_STNT1_zprz(DisasContext *s, arg_ST1_zprz *a) 5830f0984d40SFabiano Rosas { 5831f0984d40SFabiano Rosas gen_helper_gvec_mem_scatter *fn; 5832f0984d40SFabiano Rosas bool be = s->be_data == MO_BE; 5833f0984d40SFabiano Rosas bool mte = s->mte_active[0]; 5834f0984d40SFabiano Rosas 5835f0984d40SFabiano Rosas if (a->esz < a->msz) { 5836f0984d40SFabiano Rosas return false; 5837f0984d40SFabiano Rosas } 5838f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve2, s)) { 5839f0984d40SFabiano Rosas return false; 5840f0984d40SFabiano Rosas } 5841f0984d40SFabiano Rosas s->is_nonstreaming = true; 5842f0984d40SFabiano Rosas if (!sve_access_check(s)) { 5843f0984d40SFabiano Rosas return true; 5844f0984d40SFabiano Rosas } 5845f0984d40SFabiano Rosas 5846f0984d40SFabiano Rosas switch (a->esz) { 5847f0984d40SFabiano Rosas case MO_32: 5848f0984d40SFabiano Rosas fn = scatter_store_fn32[mte][be][0][a->msz]; 5849f0984d40SFabiano Rosas break; 5850f0984d40SFabiano Rosas case MO_64: 5851f0984d40SFabiano Rosas fn = scatter_store_fn64[mte][be][2][a->msz]; 5852f0984d40SFabiano Rosas break; 5853f0984d40SFabiano Rosas default: 5854f0984d40SFabiano Rosas g_assert_not_reached(); 5855f0984d40SFabiano Rosas } 5856f0984d40SFabiano Rosas 5857f0984d40SFabiano Rosas do_mem_zpz(s, a->rd, a->pg, a->rn, 0, 5858f0984d40SFabiano Rosas cpu_reg(s, a->rm), a->msz, true, fn); 5859f0984d40SFabiano Rosas return true; 5860f0984d40SFabiano Rosas } 5861f0984d40SFabiano Rosas 5862f0984d40SFabiano Rosas /* 5863f0984d40SFabiano Rosas * Prefetches 5864f0984d40SFabiano Rosas */ 5865f0984d40SFabiano Rosas 5866f0984d40SFabiano Rosas static bool trans_PRF(DisasContext *s, arg_PRF *a) 5867f0984d40SFabiano Rosas { 5868f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5869f0984d40SFabiano Rosas return false; 5870f0984d40SFabiano Rosas } 5871f0984d40SFabiano Rosas /* Prefetch is a nop within QEMU. */ 5872f0984d40SFabiano Rosas (void)sve_access_check(s); 5873f0984d40SFabiano Rosas return true; 5874f0984d40SFabiano Rosas } 5875f0984d40SFabiano Rosas 5876f0984d40SFabiano Rosas static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a) 5877f0984d40SFabiano Rosas { 5878f0984d40SFabiano Rosas if (a->rm == 31 || !dc_isar_feature(aa64_sve, s)) { 5879f0984d40SFabiano Rosas return false; 5880f0984d40SFabiano Rosas } 5881f0984d40SFabiano Rosas /* Prefetch is a nop within QEMU. */ 5882f0984d40SFabiano Rosas (void)sve_access_check(s); 5883f0984d40SFabiano Rosas return true; 5884f0984d40SFabiano Rosas } 5885f0984d40SFabiano Rosas 5886f0984d40SFabiano Rosas static bool trans_PRF_ns(DisasContext *s, arg_PRF_ns *a) 5887f0984d40SFabiano Rosas { 5888f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve, s)) { 5889f0984d40SFabiano Rosas return false; 5890f0984d40SFabiano Rosas } 5891f0984d40SFabiano Rosas /* Prefetch is a nop within QEMU. */ 5892f0984d40SFabiano Rosas s->is_nonstreaming = true; 5893f0984d40SFabiano Rosas (void)sve_access_check(s); 5894f0984d40SFabiano Rosas return true; 5895f0984d40SFabiano Rosas } 5896f0984d40SFabiano Rosas 5897f0984d40SFabiano Rosas /* 5898f0984d40SFabiano Rosas * Move Prefix 5899f0984d40SFabiano Rosas * 5900f0984d40SFabiano Rosas * TODO: The implementation so far could handle predicated merging movprfx. 5901f0984d40SFabiano Rosas * The helper functions as written take an extra source register to 5902f0984d40SFabiano Rosas * use in the operation, but the result is only written when predication 5903f0984d40SFabiano Rosas * succeeds. For unpredicated movprfx, we need to rearrange the helpers 5904f0984d40SFabiano Rosas * to allow the final write back to the destination to be unconditional. 5905f0984d40SFabiano Rosas * For predicated zeroing movprfx, we need to rearrange the helpers to 5906f0984d40SFabiano Rosas * allow the final write back to zero inactives. 5907f0984d40SFabiano Rosas * 5908f0984d40SFabiano Rosas * In the meantime, just emit the moves. 5909f0984d40SFabiano Rosas */ 5910f0984d40SFabiano Rosas 5911f0984d40SFabiano Rosas TRANS_FEAT(MOVPRFX, aa64_sve, do_mov_z, a->rd, a->rn) 5912f0984d40SFabiano Rosas TRANS_FEAT(MOVPRFX_m, aa64_sve, do_sel_z, a->rd, a->rn, a->rd, a->pg, a->esz) 5913f0984d40SFabiano Rosas TRANS_FEAT(MOVPRFX_z, aa64_sve, do_movz_zpz, a->rd, a->rn, a->pg, a->esz, false) 5914f0984d40SFabiano Rosas 5915f0984d40SFabiano Rosas /* 5916f0984d40SFabiano Rosas * SVE2 Integer Multiply - Unpredicated 5917f0984d40SFabiano Rosas */ 5918f0984d40SFabiano Rosas 5919f0984d40SFabiano Rosas TRANS_FEAT(MUL_zzz, aa64_sve2, gen_gvec_fn_arg_zzz, tcg_gen_gvec_mul, a) 5920f0984d40SFabiano Rosas 5921f0984d40SFabiano Rosas static gen_helper_gvec_3 * const smulh_zzz_fns[4] = { 5922f0984d40SFabiano Rosas gen_helper_gvec_smulh_b, gen_helper_gvec_smulh_h, 5923f0984d40SFabiano Rosas gen_helper_gvec_smulh_s, gen_helper_gvec_smulh_d, 5924f0984d40SFabiano Rosas }; 5925f0984d40SFabiano Rosas TRANS_FEAT(SMULH_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 5926f0984d40SFabiano Rosas smulh_zzz_fns[a->esz], a, 0) 5927f0984d40SFabiano Rosas 5928f0984d40SFabiano Rosas static gen_helper_gvec_3 * const umulh_zzz_fns[4] = { 5929f0984d40SFabiano Rosas gen_helper_gvec_umulh_b, gen_helper_gvec_umulh_h, 5930f0984d40SFabiano Rosas gen_helper_gvec_umulh_s, gen_helper_gvec_umulh_d, 5931f0984d40SFabiano Rosas }; 5932f0984d40SFabiano Rosas TRANS_FEAT(UMULH_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 5933f0984d40SFabiano Rosas umulh_zzz_fns[a->esz], a, 0) 5934f0984d40SFabiano Rosas 5935f0984d40SFabiano Rosas TRANS_FEAT(PMUL_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 5936f0984d40SFabiano Rosas gen_helper_gvec_pmul_b, a, 0) 5937f0984d40SFabiano Rosas 5938f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqdmulh_zzz_fns[4] = { 5939f0984d40SFabiano Rosas gen_helper_sve2_sqdmulh_b, gen_helper_sve2_sqdmulh_h, 5940f0984d40SFabiano Rosas gen_helper_sve2_sqdmulh_s, gen_helper_sve2_sqdmulh_d, 5941f0984d40SFabiano Rosas }; 5942f0984d40SFabiano Rosas TRANS_FEAT(SQDMULH_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 5943f0984d40SFabiano Rosas sqdmulh_zzz_fns[a->esz], a, 0) 5944f0984d40SFabiano Rosas 5945f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqrdmulh_zzz_fns[4] = { 5946f0984d40SFabiano Rosas gen_helper_sve2_sqrdmulh_b, gen_helper_sve2_sqrdmulh_h, 5947f0984d40SFabiano Rosas gen_helper_sve2_sqrdmulh_s, gen_helper_sve2_sqrdmulh_d, 5948f0984d40SFabiano Rosas }; 5949f0984d40SFabiano Rosas TRANS_FEAT(SQRDMULH_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 5950f0984d40SFabiano Rosas sqrdmulh_zzz_fns[a->esz], a, 0) 5951f0984d40SFabiano Rosas 5952f0984d40SFabiano Rosas /* 5953f0984d40SFabiano Rosas * SVE2 Integer - Predicated 5954f0984d40SFabiano Rosas */ 5955f0984d40SFabiano Rosas 5956f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sadlp_fns[4] = { 5957f0984d40SFabiano Rosas NULL, gen_helper_sve2_sadalp_zpzz_h, 5958f0984d40SFabiano Rosas gen_helper_sve2_sadalp_zpzz_s, gen_helper_sve2_sadalp_zpzz_d, 5959f0984d40SFabiano Rosas }; 5960f0984d40SFabiano Rosas TRANS_FEAT(SADALP_zpzz, aa64_sve2, gen_gvec_ool_arg_zpzz, 5961f0984d40SFabiano Rosas sadlp_fns[a->esz], a, 0) 5962f0984d40SFabiano Rosas 5963f0984d40SFabiano Rosas static gen_helper_gvec_4 * const uadlp_fns[4] = { 5964f0984d40SFabiano Rosas NULL, gen_helper_sve2_uadalp_zpzz_h, 5965f0984d40SFabiano Rosas gen_helper_sve2_uadalp_zpzz_s, gen_helper_sve2_uadalp_zpzz_d, 5966f0984d40SFabiano Rosas }; 5967f0984d40SFabiano Rosas TRANS_FEAT(UADALP_zpzz, aa64_sve2, gen_gvec_ool_arg_zpzz, 5968f0984d40SFabiano Rosas uadlp_fns[a->esz], a, 0) 5969f0984d40SFabiano Rosas 5970f0984d40SFabiano Rosas /* 5971f0984d40SFabiano Rosas * SVE2 integer unary operations (predicated) 5972f0984d40SFabiano Rosas */ 5973f0984d40SFabiano Rosas 5974f0984d40SFabiano Rosas TRANS_FEAT(URECPE, aa64_sve2, gen_gvec_ool_arg_zpz, 5975f0984d40SFabiano Rosas a->esz == 2 ? gen_helper_sve2_urecpe_s : NULL, a, 0) 5976f0984d40SFabiano Rosas 5977f0984d40SFabiano Rosas TRANS_FEAT(URSQRTE, aa64_sve2, gen_gvec_ool_arg_zpz, 5978f0984d40SFabiano Rosas a->esz == 2 ? gen_helper_sve2_ursqrte_s : NULL, a, 0) 5979f0984d40SFabiano Rosas 5980f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqabs_fns[4] = { 5981f0984d40SFabiano Rosas gen_helper_sve2_sqabs_b, gen_helper_sve2_sqabs_h, 5982f0984d40SFabiano Rosas gen_helper_sve2_sqabs_s, gen_helper_sve2_sqabs_d, 5983f0984d40SFabiano Rosas }; 5984f0984d40SFabiano Rosas TRANS_FEAT(SQABS, aa64_sve2, gen_gvec_ool_arg_zpz, sqabs_fns[a->esz], a, 0) 5985f0984d40SFabiano Rosas 5986f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqneg_fns[4] = { 5987f0984d40SFabiano Rosas gen_helper_sve2_sqneg_b, gen_helper_sve2_sqneg_h, 5988f0984d40SFabiano Rosas gen_helper_sve2_sqneg_s, gen_helper_sve2_sqneg_d, 5989f0984d40SFabiano Rosas }; 5990f0984d40SFabiano Rosas TRANS_FEAT(SQNEG, aa64_sve2, gen_gvec_ool_arg_zpz, sqneg_fns[a->esz], a, 0) 5991f0984d40SFabiano Rosas 5992f0984d40SFabiano Rosas DO_ZPZZ(SQSHL, aa64_sve2, sve2_sqshl) 5993f0984d40SFabiano Rosas DO_ZPZZ(SQRSHL, aa64_sve2, sve2_sqrshl) 5994f0984d40SFabiano Rosas DO_ZPZZ(SRSHL, aa64_sve2, sve2_srshl) 5995f0984d40SFabiano Rosas 5996f0984d40SFabiano Rosas DO_ZPZZ(UQSHL, aa64_sve2, sve2_uqshl) 5997f0984d40SFabiano Rosas DO_ZPZZ(UQRSHL, aa64_sve2, sve2_uqrshl) 5998f0984d40SFabiano Rosas DO_ZPZZ(URSHL, aa64_sve2, sve2_urshl) 5999f0984d40SFabiano Rosas 6000f0984d40SFabiano Rosas DO_ZPZZ(SHADD, aa64_sve2, sve2_shadd) 6001f0984d40SFabiano Rosas DO_ZPZZ(SRHADD, aa64_sve2, sve2_srhadd) 6002f0984d40SFabiano Rosas DO_ZPZZ(SHSUB, aa64_sve2, sve2_shsub) 6003f0984d40SFabiano Rosas 6004f0984d40SFabiano Rosas DO_ZPZZ(UHADD, aa64_sve2, sve2_uhadd) 6005f0984d40SFabiano Rosas DO_ZPZZ(URHADD, aa64_sve2, sve2_urhadd) 6006f0984d40SFabiano Rosas DO_ZPZZ(UHSUB, aa64_sve2, sve2_uhsub) 6007f0984d40SFabiano Rosas 6008f0984d40SFabiano Rosas DO_ZPZZ(ADDP, aa64_sve2, sve2_addp) 6009f0984d40SFabiano Rosas DO_ZPZZ(SMAXP, aa64_sve2, sve2_smaxp) 6010f0984d40SFabiano Rosas DO_ZPZZ(UMAXP, aa64_sve2, sve2_umaxp) 6011f0984d40SFabiano Rosas DO_ZPZZ(SMINP, aa64_sve2, sve2_sminp) 6012f0984d40SFabiano Rosas DO_ZPZZ(UMINP, aa64_sve2, sve2_uminp) 6013f0984d40SFabiano Rosas 6014f0984d40SFabiano Rosas DO_ZPZZ(SQADD_zpzz, aa64_sve2, sve2_sqadd) 6015f0984d40SFabiano Rosas DO_ZPZZ(UQADD_zpzz, aa64_sve2, sve2_uqadd) 6016f0984d40SFabiano Rosas DO_ZPZZ(SQSUB_zpzz, aa64_sve2, sve2_sqsub) 6017f0984d40SFabiano Rosas DO_ZPZZ(UQSUB_zpzz, aa64_sve2, sve2_uqsub) 6018f0984d40SFabiano Rosas DO_ZPZZ(SUQADD, aa64_sve2, sve2_suqadd) 6019f0984d40SFabiano Rosas DO_ZPZZ(USQADD, aa64_sve2, sve2_usqadd) 6020f0984d40SFabiano Rosas 6021f0984d40SFabiano Rosas /* 6022f0984d40SFabiano Rosas * SVE2 Widening Integer Arithmetic 6023f0984d40SFabiano Rosas */ 6024f0984d40SFabiano Rosas 6025f0984d40SFabiano Rosas static gen_helper_gvec_3 * const saddl_fns[4] = { 6026f0984d40SFabiano Rosas NULL, gen_helper_sve2_saddl_h, 6027f0984d40SFabiano Rosas gen_helper_sve2_saddl_s, gen_helper_sve2_saddl_d, 6028f0984d40SFabiano Rosas }; 6029f0984d40SFabiano Rosas TRANS_FEAT(SADDLB, aa64_sve2, gen_gvec_ool_arg_zzz, 6030f0984d40SFabiano Rosas saddl_fns[a->esz], a, 0) 6031f0984d40SFabiano Rosas TRANS_FEAT(SADDLT, aa64_sve2, gen_gvec_ool_arg_zzz, 6032f0984d40SFabiano Rosas saddl_fns[a->esz], a, 3) 6033f0984d40SFabiano Rosas TRANS_FEAT(SADDLBT, aa64_sve2, gen_gvec_ool_arg_zzz, 6034f0984d40SFabiano Rosas saddl_fns[a->esz], a, 2) 6035f0984d40SFabiano Rosas 6036f0984d40SFabiano Rosas static gen_helper_gvec_3 * const ssubl_fns[4] = { 6037f0984d40SFabiano Rosas NULL, gen_helper_sve2_ssubl_h, 6038f0984d40SFabiano Rosas gen_helper_sve2_ssubl_s, gen_helper_sve2_ssubl_d, 6039f0984d40SFabiano Rosas }; 6040f0984d40SFabiano Rosas TRANS_FEAT(SSUBLB, aa64_sve2, gen_gvec_ool_arg_zzz, 6041f0984d40SFabiano Rosas ssubl_fns[a->esz], a, 0) 6042f0984d40SFabiano Rosas TRANS_FEAT(SSUBLT, aa64_sve2, gen_gvec_ool_arg_zzz, 6043f0984d40SFabiano Rosas ssubl_fns[a->esz], a, 3) 6044f0984d40SFabiano Rosas TRANS_FEAT(SSUBLBT, aa64_sve2, gen_gvec_ool_arg_zzz, 6045f0984d40SFabiano Rosas ssubl_fns[a->esz], a, 2) 6046f0984d40SFabiano Rosas TRANS_FEAT(SSUBLTB, aa64_sve2, gen_gvec_ool_arg_zzz, 6047f0984d40SFabiano Rosas ssubl_fns[a->esz], a, 1) 6048f0984d40SFabiano Rosas 6049f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sabdl_fns[4] = { 6050f0984d40SFabiano Rosas NULL, gen_helper_sve2_sabdl_h, 6051f0984d40SFabiano Rosas gen_helper_sve2_sabdl_s, gen_helper_sve2_sabdl_d, 6052f0984d40SFabiano Rosas }; 6053f0984d40SFabiano Rosas TRANS_FEAT(SABDLB, aa64_sve2, gen_gvec_ool_arg_zzz, 6054f0984d40SFabiano Rosas sabdl_fns[a->esz], a, 0) 6055f0984d40SFabiano Rosas TRANS_FEAT(SABDLT, aa64_sve2, gen_gvec_ool_arg_zzz, 6056f0984d40SFabiano Rosas sabdl_fns[a->esz], a, 3) 6057f0984d40SFabiano Rosas 6058f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uaddl_fns[4] = { 6059f0984d40SFabiano Rosas NULL, gen_helper_sve2_uaddl_h, 6060f0984d40SFabiano Rosas gen_helper_sve2_uaddl_s, gen_helper_sve2_uaddl_d, 6061f0984d40SFabiano Rosas }; 6062f0984d40SFabiano Rosas TRANS_FEAT(UADDLB, aa64_sve2, gen_gvec_ool_arg_zzz, 6063f0984d40SFabiano Rosas uaddl_fns[a->esz], a, 0) 6064f0984d40SFabiano Rosas TRANS_FEAT(UADDLT, aa64_sve2, gen_gvec_ool_arg_zzz, 6065f0984d40SFabiano Rosas uaddl_fns[a->esz], a, 3) 6066f0984d40SFabiano Rosas 6067f0984d40SFabiano Rosas static gen_helper_gvec_3 * const usubl_fns[4] = { 6068f0984d40SFabiano Rosas NULL, gen_helper_sve2_usubl_h, 6069f0984d40SFabiano Rosas gen_helper_sve2_usubl_s, gen_helper_sve2_usubl_d, 6070f0984d40SFabiano Rosas }; 6071f0984d40SFabiano Rosas TRANS_FEAT(USUBLB, aa64_sve2, gen_gvec_ool_arg_zzz, 6072f0984d40SFabiano Rosas usubl_fns[a->esz], a, 0) 6073f0984d40SFabiano Rosas TRANS_FEAT(USUBLT, aa64_sve2, gen_gvec_ool_arg_zzz, 6074f0984d40SFabiano Rosas usubl_fns[a->esz], a, 3) 6075f0984d40SFabiano Rosas 6076f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uabdl_fns[4] = { 6077f0984d40SFabiano Rosas NULL, gen_helper_sve2_uabdl_h, 6078f0984d40SFabiano Rosas gen_helper_sve2_uabdl_s, gen_helper_sve2_uabdl_d, 6079f0984d40SFabiano Rosas }; 6080f0984d40SFabiano Rosas TRANS_FEAT(UABDLB, aa64_sve2, gen_gvec_ool_arg_zzz, 6081f0984d40SFabiano Rosas uabdl_fns[a->esz], a, 0) 6082f0984d40SFabiano Rosas TRANS_FEAT(UABDLT, aa64_sve2, gen_gvec_ool_arg_zzz, 6083f0984d40SFabiano Rosas uabdl_fns[a->esz], a, 3) 6084f0984d40SFabiano Rosas 6085f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqdmull_fns[4] = { 6086f0984d40SFabiano Rosas NULL, gen_helper_sve2_sqdmull_zzz_h, 6087f0984d40SFabiano Rosas gen_helper_sve2_sqdmull_zzz_s, gen_helper_sve2_sqdmull_zzz_d, 6088f0984d40SFabiano Rosas }; 6089f0984d40SFabiano Rosas TRANS_FEAT(SQDMULLB_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 6090f0984d40SFabiano Rosas sqdmull_fns[a->esz], a, 0) 6091f0984d40SFabiano Rosas TRANS_FEAT(SQDMULLT_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 6092f0984d40SFabiano Rosas sqdmull_fns[a->esz], a, 3) 6093f0984d40SFabiano Rosas 6094f0984d40SFabiano Rosas static gen_helper_gvec_3 * const smull_fns[4] = { 6095f0984d40SFabiano Rosas NULL, gen_helper_sve2_smull_zzz_h, 6096f0984d40SFabiano Rosas gen_helper_sve2_smull_zzz_s, gen_helper_sve2_smull_zzz_d, 6097f0984d40SFabiano Rosas }; 6098f0984d40SFabiano Rosas TRANS_FEAT(SMULLB_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 6099f0984d40SFabiano Rosas smull_fns[a->esz], a, 0) 6100f0984d40SFabiano Rosas TRANS_FEAT(SMULLT_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 6101f0984d40SFabiano Rosas smull_fns[a->esz], a, 3) 6102f0984d40SFabiano Rosas 6103f0984d40SFabiano Rosas static gen_helper_gvec_3 * const umull_fns[4] = { 6104f0984d40SFabiano Rosas NULL, gen_helper_sve2_umull_zzz_h, 6105f0984d40SFabiano Rosas gen_helper_sve2_umull_zzz_s, gen_helper_sve2_umull_zzz_d, 6106f0984d40SFabiano Rosas }; 6107f0984d40SFabiano Rosas TRANS_FEAT(UMULLB_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 6108f0984d40SFabiano Rosas umull_fns[a->esz], a, 0) 6109f0984d40SFabiano Rosas TRANS_FEAT(UMULLT_zzz, aa64_sve2, gen_gvec_ool_arg_zzz, 6110f0984d40SFabiano Rosas umull_fns[a->esz], a, 3) 6111f0984d40SFabiano Rosas 6112f0984d40SFabiano Rosas static gen_helper_gvec_3 * const eoril_fns[4] = { 6113f0984d40SFabiano Rosas gen_helper_sve2_eoril_b, gen_helper_sve2_eoril_h, 6114f0984d40SFabiano Rosas gen_helper_sve2_eoril_s, gen_helper_sve2_eoril_d, 6115f0984d40SFabiano Rosas }; 6116f0984d40SFabiano Rosas TRANS_FEAT(EORBT, aa64_sve2, gen_gvec_ool_arg_zzz, eoril_fns[a->esz], a, 2) 6117f0984d40SFabiano Rosas TRANS_FEAT(EORTB, aa64_sve2, gen_gvec_ool_arg_zzz, eoril_fns[a->esz], a, 1) 6118f0984d40SFabiano Rosas 6119f0984d40SFabiano Rosas static bool do_trans_pmull(DisasContext *s, arg_rrr_esz *a, bool sel) 6120f0984d40SFabiano Rosas { 6121f0984d40SFabiano Rosas static gen_helper_gvec_3 * const fns[4] = { 6122f0984d40SFabiano Rosas gen_helper_gvec_pmull_q, gen_helper_sve2_pmull_h, 6123f0984d40SFabiano Rosas NULL, gen_helper_sve2_pmull_d, 6124f0984d40SFabiano Rosas }; 6125f0984d40SFabiano Rosas 6126f0984d40SFabiano Rosas if (a->esz == 0) { 6127f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sve2_pmull128, s)) { 6128f0984d40SFabiano Rosas return false; 6129f0984d40SFabiano Rosas } 6130f0984d40SFabiano Rosas s->is_nonstreaming = true; 6131f0984d40SFabiano Rosas } else if (!dc_isar_feature(aa64_sve, s)) { 6132f0984d40SFabiano Rosas return false; 6133f0984d40SFabiano Rosas } 6134f0984d40SFabiano Rosas return gen_gvec_ool_arg_zzz(s, fns[a->esz], a, sel); 6135f0984d40SFabiano Rosas } 6136f0984d40SFabiano Rosas 6137f0984d40SFabiano Rosas TRANS_FEAT(PMULLB, aa64_sve2, do_trans_pmull, a, false) 6138f0984d40SFabiano Rosas TRANS_FEAT(PMULLT, aa64_sve2, do_trans_pmull, a, true) 6139f0984d40SFabiano Rosas 6140f0984d40SFabiano Rosas static gen_helper_gvec_3 * const saddw_fns[4] = { 6141f0984d40SFabiano Rosas NULL, gen_helper_sve2_saddw_h, 6142f0984d40SFabiano Rosas gen_helper_sve2_saddw_s, gen_helper_sve2_saddw_d, 6143f0984d40SFabiano Rosas }; 6144f0984d40SFabiano Rosas TRANS_FEAT(SADDWB, aa64_sve2, gen_gvec_ool_arg_zzz, saddw_fns[a->esz], a, 0) 6145f0984d40SFabiano Rosas TRANS_FEAT(SADDWT, aa64_sve2, gen_gvec_ool_arg_zzz, saddw_fns[a->esz], a, 1) 6146f0984d40SFabiano Rosas 6147f0984d40SFabiano Rosas static gen_helper_gvec_3 * const ssubw_fns[4] = { 6148f0984d40SFabiano Rosas NULL, gen_helper_sve2_ssubw_h, 6149f0984d40SFabiano Rosas gen_helper_sve2_ssubw_s, gen_helper_sve2_ssubw_d, 6150f0984d40SFabiano Rosas }; 6151f0984d40SFabiano Rosas TRANS_FEAT(SSUBWB, aa64_sve2, gen_gvec_ool_arg_zzz, ssubw_fns[a->esz], a, 0) 6152f0984d40SFabiano Rosas TRANS_FEAT(SSUBWT, aa64_sve2, gen_gvec_ool_arg_zzz, ssubw_fns[a->esz], a, 1) 6153f0984d40SFabiano Rosas 6154f0984d40SFabiano Rosas static gen_helper_gvec_3 * const uaddw_fns[4] = { 6155f0984d40SFabiano Rosas NULL, gen_helper_sve2_uaddw_h, 6156f0984d40SFabiano Rosas gen_helper_sve2_uaddw_s, gen_helper_sve2_uaddw_d, 6157f0984d40SFabiano Rosas }; 6158f0984d40SFabiano Rosas TRANS_FEAT(UADDWB, aa64_sve2, gen_gvec_ool_arg_zzz, uaddw_fns[a->esz], a, 0) 6159f0984d40SFabiano Rosas TRANS_FEAT(UADDWT, aa64_sve2, gen_gvec_ool_arg_zzz, uaddw_fns[a->esz], a, 1) 6160f0984d40SFabiano Rosas 6161f0984d40SFabiano Rosas static gen_helper_gvec_3 * const usubw_fns[4] = { 6162f0984d40SFabiano Rosas NULL, gen_helper_sve2_usubw_h, 6163f0984d40SFabiano Rosas gen_helper_sve2_usubw_s, gen_helper_sve2_usubw_d, 6164f0984d40SFabiano Rosas }; 6165f0984d40SFabiano Rosas TRANS_FEAT(USUBWB, aa64_sve2, gen_gvec_ool_arg_zzz, usubw_fns[a->esz], a, 0) 6166f0984d40SFabiano Rosas TRANS_FEAT(USUBWT, aa64_sve2, gen_gvec_ool_arg_zzz, usubw_fns[a->esz], a, 1) 6167f0984d40SFabiano Rosas 6168f0984d40SFabiano Rosas static void gen_sshll_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t imm) 6169f0984d40SFabiano Rosas { 6170f0984d40SFabiano Rosas int top = imm & 1; 6171f0984d40SFabiano Rosas int shl = imm >> 1; 6172f0984d40SFabiano Rosas int halfbits = 4 << vece; 6173f0984d40SFabiano Rosas 6174f0984d40SFabiano Rosas if (top) { 6175f0984d40SFabiano Rosas if (shl == halfbits) { 6176f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6177f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(halfbits, halfbits)); 6178f0984d40SFabiano Rosas tcg_gen_and_vec(vece, d, n, t); 6179f0984d40SFabiano Rosas } else { 6180f0984d40SFabiano Rosas tcg_gen_sari_vec(vece, d, n, halfbits); 6181f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, d, d, shl); 6182f0984d40SFabiano Rosas } 6183f0984d40SFabiano Rosas } else { 6184f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, d, n, halfbits); 6185f0984d40SFabiano Rosas tcg_gen_sari_vec(vece, d, d, halfbits - shl); 6186f0984d40SFabiano Rosas } 6187f0984d40SFabiano Rosas } 6188f0984d40SFabiano Rosas 6189f0984d40SFabiano Rosas static void gen_ushll_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int imm) 6190f0984d40SFabiano Rosas { 6191f0984d40SFabiano Rosas int halfbits = 4 << vece; 6192f0984d40SFabiano Rosas int top = imm & 1; 6193f0984d40SFabiano Rosas int shl = (imm >> 1); 6194f0984d40SFabiano Rosas int shift; 6195f0984d40SFabiano Rosas uint64_t mask; 6196f0984d40SFabiano Rosas 6197f0984d40SFabiano Rosas mask = MAKE_64BIT_MASK(0, halfbits); 6198f0984d40SFabiano Rosas mask <<= shl; 6199f0984d40SFabiano Rosas mask = dup_const(vece, mask); 6200f0984d40SFabiano Rosas 6201f0984d40SFabiano Rosas shift = shl - top * halfbits; 6202f0984d40SFabiano Rosas if (shift < 0) { 6203f0984d40SFabiano Rosas tcg_gen_shri_i64(d, n, -shift); 6204f0984d40SFabiano Rosas } else { 6205f0984d40SFabiano Rosas tcg_gen_shli_i64(d, n, shift); 6206f0984d40SFabiano Rosas } 6207f0984d40SFabiano Rosas tcg_gen_andi_i64(d, d, mask); 6208f0984d40SFabiano Rosas } 6209f0984d40SFabiano Rosas 6210f0984d40SFabiano Rosas static void gen_ushll16_i64(TCGv_i64 d, TCGv_i64 n, int64_t imm) 6211f0984d40SFabiano Rosas { 6212f0984d40SFabiano Rosas gen_ushll_i64(MO_16, d, n, imm); 6213f0984d40SFabiano Rosas } 6214f0984d40SFabiano Rosas 6215f0984d40SFabiano Rosas static void gen_ushll32_i64(TCGv_i64 d, TCGv_i64 n, int64_t imm) 6216f0984d40SFabiano Rosas { 6217f0984d40SFabiano Rosas gen_ushll_i64(MO_32, d, n, imm); 6218f0984d40SFabiano Rosas } 6219f0984d40SFabiano Rosas 6220f0984d40SFabiano Rosas static void gen_ushll64_i64(TCGv_i64 d, TCGv_i64 n, int64_t imm) 6221f0984d40SFabiano Rosas { 6222f0984d40SFabiano Rosas gen_ushll_i64(MO_64, d, n, imm); 6223f0984d40SFabiano Rosas } 6224f0984d40SFabiano Rosas 6225f0984d40SFabiano Rosas static void gen_ushll_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t imm) 6226f0984d40SFabiano Rosas { 6227f0984d40SFabiano Rosas int halfbits = 4 << vece; 6228f0984d40SFabiano Rosas int top = imm & 1; 6229f0984d40SFabiano Rosas int shl = imm >> 1; 6230f0984d40SFabiano Rosas 6231f0984d40SFabiano Rosas if (top) { 6232f0984d40SFabiano Rosas if (shl == halfbits) { 6233f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6234f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(halfbits, halfbits)); 6235f0984d40SFabiano Rosas tcg_gen_and_vec(vece, d, n, t); 6236f0984d40SFabiano Rosas } else { 6237f0984d40SFabiano Rosas tcg_gen_shri_vec(vece, d, n, halfbits); 6238f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, d, d, shl); 6239f0984d40SFabiano Rosas } 6240f0984d40SFabiano Rosas } else { 6241f0984d40SFabiano Rosas if (shl == 0) { 6242f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6243f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6244f0984d40SFabiano Rosas tcg_gen_and_vec(vece, d, n, t); 6245f0984d40SFabiano Rosas } else { 6246f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, d, n, halfbits); 6247f0984d40SFabiano Rosas tcg_gen_shri_vec(vece, d, d, halfbits - shl); 6248f0984d40SFabiano Rosas } 6249f0984d40SFabiano Rosas } 6250f0984d40SFabiano Rosas } 6251f0984d40SFabiano Rosas 6252f0984d40SFabiano Rosas static bool do_shll_tb(DisasContext *s, arg_rri_esz *a, 6253f0984d40SFabiano Rosas const GVecGen2i ops[3], bool sel) 6254f0984d40SFabiano Rosas { 6255f0984d40SFabiano Rosas 6256f0984d40SFabiano Rosas if (a->esz < 0 || a->esz > 2) { 6257f0984d40SFabiano Rosas return false; 6258f0984d40SFabiano Rosas } 6259f0984d40SFabiano Rosas if (sve_access_check(s)) { 6260f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 6261f0984d40SFabiano Rosas tcg_gen_gvec_2i(vec_full_reg_offset(s, a->rd), 6262f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 6263f0984d40SFabiano Rosas vsz, vsz, (a->imm << 1) | sel, 6264f0984d40SFabiano Rosas &ops[a->esz]); 6265f0984d40SFabiano Rosas } 6266f0984d40SFabiano Rosas return true; 6267f0984d40SFabiano Rosas } 6268f0984d40SFabiano Rosas 6269f0984d40SFabiano Rosas static const TCGOpcode sshll_list[] = { 6270f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_sari_vec, 0 6271f0984d40SFabiano Rosas }; 6272f0984d40SFabiano Rosas static const GVecGen2i sshll_ops[3] = { 6273f0984d40SFabiano Rosas { .fniv = gen_sshll_vec, 6274f0984d40SFabiano Rosas .opt_opc = sshll_list, 6275f0984d40SFabiano Rosas .fno = gen_helper_sve2_sshll_h, 6276f0984d40SFabiano Rosas .vece = MO_16 }, 6277f0984d40SFabiano Rosas { .fniv = gen_sshll_vec, 6278f0984d40SFabiano Rosas .opt_opc = sshll_list, 6279f0984d40SFabiano Rosas .fno = gen_helper_sve2_sshll_s, 6280f0984d40SFabiano Rosas .vece = MO_32 }, 6281f0984d40SFabiano Rosas { .fniv = gen_sshll_vec, 6282f0984d40SFabiano Rosas .opt_opc = sshll_list, 6283f0984d40SFabiano Rosas .fno = gen_helper_sve2_sshll_d, 6284f0984d40SFabiano Rosas .vece = MO_64 } 6285f0984d40SFabiano Rosas }; 6286f0984d40SFabiano Rosas TRANS_FEAT(SSHLLB, aa64_sve2, do_shll_tb, a, sshll_ops, false) 6287f0984d40SFabiano Rosas TRANS_FEAT(SSHLLT, aa64_sve2, do_shll_tb, a, sshll_ops, true) 6288f0984d40SFabiano Rosas 6289f0984d40SFabiano Rosas static const TCGOpcode ushll_list[] = { 6290f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_shri_vec, 0 6291f0984d40SFabiano Rosas }; 6292f0984d40SFabiano Rosas static const GVecGen2i ushll_ops[3] = { 6293f0984d40SFabiano Rosas { .fni8 = gen_ushll16_i64, 6294f0984d40SFabiano Rosas .fniv = gen_ushll_vec, 6295f0984d40SFabiano Rosas .opt_opc = ushll_list, 6296f0984d40SFabiano Rosas .fno = gen_helper_sve2_ushll_h, 6297f0984d40SFabiano Rosas .vece = MO_16 }, 6298f0984d40SFabiano Rosas { .fni8 = gen_ushll32_i64, 6299f0984d40SFabiano Rosas .fniv = gen_ushll_vec, 6300f0984d40SFabiano Rosas .opt_opc = ushll_list, 6301f0984d40SFabiano Rosas .fno = gen_helper_sve2_ushll_s, 6302f0984d40SFabiano Rosas .vece = MO_32 }, 6303f0984d40SFabiano Rosas { .fni8 = gen_ushll64_i64, 6304f0984d40SFabiano Rosas .fniv = gen_ushll_vec, 6305f0984d40SFabiano Rosas .opt_opc = ushll_list, 6306f0984d40SFabiano Rosas .fno = gen_helper_sve2_ushll_d, 6307f0984d40SFabiano Rosas .vece = MO_64 }, 6308f0984d40SFabiano Rosas }; 6309f0984d40SFabiano Rosas TRANS_FEAT(USHLLB, aa64_sve2, do_shll_tb, a, ushll_ops, false) 6310f0984d40SFabiano Rosas TRANS_FEAT(USHLLT, aa64_sve2, do_shll_tb, a, ushll_ops, true) 6311f0984d40SFabiano Rosas 6312f0984d40SFabiano Rosas static gen_helper_gvec_3 * const bext_fns[4] = { 6313f0984d40SFabiano Rosas gen_helper_sve2_bext_b, gen_helper_sve2_bext_h, 6314f0984d40SFabiano Rosas gen_helper_sve2_bext_s, gen_helper_sve2_bext_d, 6315f0984d40SFabiano Rosas }; 6316f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(BEXT, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz, 6317f0984d40SFabiano Rosas bext_fns[a->esz], a, 0) 6318f0984d40SFabiano Rosas 6319f0984d40SFabiano Rosas static gen_helper_gvec_3 * const bdep_fns[4] = { 6320f0984d40SFabiano Rosas gen_helper_sve2_bdep_b, gen_helper_sve2_bdep_h, 6321f0984d40SFabiano Rosas gen_helper_sve2_bdep_s, gen_helper_sve2_bdep_d, 6322f0984d40SFabiano Rosas }; 6323f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(BDEP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz, 6324f0984d40SFabiano Rosas bdep_fns[a->esz], a, 0) 6325f0984d40SFabiano Rosas 6326f0984d40SFabiano Rosas static gen_helper_gvec_3 * const bgrp_fns[4] = { 6327f0984d40SFabiano Rosas gen_helper_sve2_bgrp_b, gen_helper_sve2_bgrp_h, 6328f0984d40SFabiano Rosas gen_helper_sve2_bgrp_s, gen_helper_sve2_bgrp_d, 6329f0984d40SFabiano Rosas }; 6330f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(BGRP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz, 6331f0984d40SFabiano Rosas bgrp_fns[a->esz], a, 0) 6332f0984d40SFabiano Rosas 6333f0984d40SFabiano Rosas static gen_helper_gvec_3 * const cadd_fns[4] = { 6334f0984d40SFabiano Rosas gen_helper_sve2_cadd_b, gen_helper_sve2_cadd_h, 6335f0984d40SFabiano Rosas gen_helper_sve2_cadd_s, gen_helper_sve2_cadd_d, 6336f0984d40SFabiano Rosas }; 6337f0984d40SFabiano Rosas TRANS_FEAT(CADD_rot90, aa64_sve2, gen_gvec_ool_arg_zzz, 6338f0984d40SFabiano Rosas cadd_fns[a->esz], a, 0) 6339f0984d40SFabiano Rosas TRANS_FEAT(CADD_rot270, aa64_sve2, gen_gvec_ool_arg_zzz, 6340f0984d40SFabiano Rosas cadd_fns[a->esz], a, 1) 6341f0984d40SFabiano Rosas 6342f0984d40SFabiano Rosas static gen_helper_gvec_3 * const sqcadd_fns[4] = { 6343f0984d40SFabiano Rosas gen_helper_sve2_sqcadd_b, gen_helper_sve2_sqcadd_h, 6344f0984d40SFabiano Rosas gen_helper_sve2_sqcadd_s, gen_helper_sve2_sqcadd_d, 6345f0984d40SFabiano Rosas }; 6346f0984d40SFabiano Rosas TRANS_FEAT(SQCADD_rot90, aa64_sve2, gen_gvec_ool_arg_zzz, 6347f0984d40SFabiano Rosas sqcadd_fns[a->esz], a, 0) 6348f0984d40SFabiano Rosas TRANS_FEAT(SQCADD_rot270, aa64_sve2, gen_gvec_ool_arg_zzz, 6349f0984d40SFabiano Rosas sqcadd_fns[a->esz], a, 1) 6350f0984d40SFabiano Rosas 6351f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sabal_fns[4] = { 6352f0984d40SFabiano Rosas NULL, gen_helper_sve2_sabal_h, 6353f0984d40SFabiano Rosas gen_helper_sve2_sabal_s, gen_helper_sve2_sabal_d, 6354f0984d40SFabiano Rosas }; 6355f0984d40SFabiano Rosas TRANS_FEAT(SABALB, aa64_sve2, gen_gvec_ool_arg_zzzz, sabal_fns[a->esz], a, 0) 6356f0984d40SFabiano Rosas TRANS_FEAT(SABALT, aa64_sve2, gen_gvec_ool_arg_zzzz, sabal_fns[a->esz], a, 1) 6357f0984d40SFabiano Rosas 6358f0984d40SFabiano Rosas static gen_helper_gvec_4 * const uabal_fns[4] = { 6359f0984d40SFabiano Rosas NULL, gen_helper_sve2_uabal_h, 6360f0984d40SFabiano Rosas gen_helper_sve2_uabal_s, gen_helper_sve2_uabal_d, 6361f0984d40SFabiano Rosas }; 6362f0984d40SFabiano Rosas TRANS_FEAT(UABALB, aa64_sve2, gen_gvec_ool_arg_zzzz, uabal_fns[a->esz], a, 0) 6363f0984d40SFabiano Rosas TRANS_FEAT(UABALT, aa64_sve2, gen_gvec_ool_arg_zzzz, uabal_fns[a->esz], a, 1) 6364f0984d40SFabiano Rosas 6365f0984d40SFabiano Rosas static bool do_adcl(DisasContext *s, arg_rrrr_esz *a, bool sel) 6366f0984d40SFabiano Rosas { 6367f0984d40SFabiano Rosas static gen_helper_gvec_4 * const fns[2] = { 6368f0984d40SFabiano Rosas gen_helper_sve2_adcl_s, 6369f0984d40SFabiano Rosas gen_helper_sve2_adcl_d, 6370f0984d40SFabiano Rosas }; 6371f0984d40SFabiano Rosas /* 6372f0984d40SFabiano Rosas * Note that in this case the ESZ field encodes both size and sign. 6373f0984d40SFabiano Rosas * Split out 'subtract' into bit 1 of the data field for the helper. 6374f0984d40SFabiano Rosas */ 6375f0984d40SFabiano Rosas return gen_gvec_ool_arg_zzzz(s, fns[a->esz & 1], a, (a->esz & 2) | sel); 6376f0984d40SFabiano Rosas } 6377f0984d40SFabiano Rosas 6378f0984d40SFabiano Rosas TRANS_FEAT(ADCLB, aa64_sve2, do_adcl, a, false) 6379f0984d40SFabiano Rosas TRANS_FEAT(ADCLT, aa64_sve2, do_adcl, a, true) 6380f0984d40SFabiano Rosas 6381f0984d40SFabiano Rosas TRANS_FEAT(SSRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_ssra, a) 6382f0984d40SFabiano Rosas TRANS_FEAT(USRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_usra, a) 6383f0984d40SFabiano Rosas TRANS_FEAT(SRSRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_srsra, a) 6384f0984d40SFabiano Rosas TRANS_FEAT(URSRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_ursra, a) 6385f0984d40SFabiano Rosas TRANS_FEAT(SRI, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_sri, a) 6386f0984d40SFabiano Rosas TRANS_FEAT(SLI, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_sli, a) 6387f0984d40SFabiano Rosas 6388f0984d40SFabiano Rosas TRANS_FEAT(SABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_saba, a) 6389f0984d40SFabiano Rosas TRANS_FEAT(UABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_uaba, a) 6390f0984d40SFabiano Rosas 6391f0984d40SFabiano Rosas static bool do_narrow_extract(DisasContext *s, arg_rri_esz *a, 6392f0984d40SFabiano Rosas const GVecGen2 ops[3]) 6393f0984d40SFabiano Rosas { 6394f0984d40SFabiano Rosas if (a->esz < 0 || a->esz > MO_32 || a->imm != 0) { 6395f0984d40SFabiano Rosas return false; 6396f0984d40SFabiano Rosas } 6397f0984d40SFabiano Rosas if (sve_access_check(s)) { 6398f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 6399f0984d40SFabiano Rosas tcg_gen_gvec_2(vec_full_reg_offset(s, a->rd), 6400f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 6401f0984d40SFabiano Rosas vsz, vsz, &ops[a->esz]); 6402f0984d40SFabiano Rosas } 6403f0984d40SFabiano Rosas return true; 6404f0984d40SFabiano Rosas } 6405f0984d40SFabiano Rosas 6406f0984d40SFabiano Rosas static const TCGOpcode sqxtn_list[] = { 6407f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0 6408f0984d40SFabiano Rosas }; 6409f0984d40SFabiano Rosas 6410f0984d40SFabiano Rosas static void gen_sqxtnb_vec(unsigned vece, TCGv_vec d, TCGv_vec n) 6411f0984d40SFabiano Rosas { 6412f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6413f0984d40SFabiano Rosas int halfbits = 4 << vece; 6414f0984d40SFabiano Rosas int64_t mask = (1ull << halfbits) - 1; 6415f0984d40SFabiano Rosas int64_t min = -1ull << (halfbits - 1); 6416f0984d40SFabiano Rosas int64_t max = -min - 1; 6417f0984d40SFabiano Rosas 6418f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, min); 6419f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, d, n, t); 6420f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6421f0984d40SFabiano Rosas tcg_gen_smin_vec(vece, d, d, t); 6422f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, mask); 6423f0984d40SFabiano Rosas tcg_gen_and_vec(vece, d, d, t); 6424f0984d40SFabiano Rosas } 6425f0984d40SFabiano Rosas 6426f0984d40SFabiano Rosas static const GVecGen2 sqxtnb_ops[3] = { 6427f0984d40SFabiano Rosas { .fniv = gen_sqxtnb_vec, 6428f0984d40SFabiano Rosas .opt_opc = sqxtn_list, 6429f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtnb_h, 6430f0984d40SFabiano Rosas .vece = MO_16 }, 6431f0984d40SFabiano Rosas { .fniv = gen_sqxtnb_vec, 6432f0984d40SFabiano Rosas .opt_opc = sqxtn_list, 6433f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtnb_s, 6434f0984d40SFabiano Rosas .vece = MO_32 }, 6435f0984d40SFabiano Rosas { .fniv = gen_sqxtnb_vec, 6436f0984d40SFabiano Rosas .opt_opc = sqxtn_list, 6437f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtnb_d, 6438f0984d40SFabiano Rosas .vece = MO_64 }, 6439f0984d40SFabiano Rosas }; 6440f0984d40SFabiano Rosas TRANS_FEAT(SQXTNB, aa64_sve2, do_narrow_extract, a, sqxtnb_ops) 6441f0984d40SFabiano Rosas 6442f0984d40SFabiano Rosas static void gen_sqxtnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n) 6443f0984d40SFabiano Rosas { 6444f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6445f0984d40SFabiano Rosas int halfbits = 4 << vece; 6446f0984d40SFabiano Rosas int64_t mask = (1ull << halfbits) - 1; 6447f0984d40SFabiano Rosas int64_t min = -1ull << (halfbits - 1); 6448f0984d40SFabiano Rosas int64_t max = -min - 1; 6449f0984d40SFabiano Rosas 6450f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, min); 6451f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, n, n, t); 6452f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6453f0984d40SFabiano Rosas tcg_gen_smin_vec(vece, n, n, t); 6454f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits); 6455f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, mask); 6456f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6457f0984d40SFabiano Rosas } 6458f0984d40SFabiano Rosas 6459f0984d40SFabiano Rosas static const GVecGen2 sqxtnt_ops[3] = { 6460f0984d40SFabiano Rosas { .fniv = gen_sqxtnt_vec, 6461f0984d40SFabiano Rosas .opt_opc = sqxtn_list, 6462f0984d40SFabiano Rosas .load_dest = true, 6463f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtnt_h, 6464f0984d40SFabiano Rosas .vece = MO_16 }, 6465f0984d40SFabiano Rosas { .fniv = gen_sqxtnt_vec, 6466f0984d40SFabiano Rosas .opt_opc = sqxtn_list, 6467f0984d40SFabiano Rosas .load_dest = true, 6468f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtnt_s, 6469f0984d40SFabiano Rosas .vece = MO_32 }, 6470f0984d40SFabiano Rosas { .fniv = gen_sqxtnt_vec, 6471f0984d40SFabiano Rosas .opt_opc = sqxtn_list, 6472f0984d40SFabiano Rosas .load_dest = true, 6473f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtnt_d, 6474f0984d40SFabiano Rosas .vece = MO_64 }, 6475f0984d40SFabiano Rosas }; 6476f0984d40SFabiano Rosas TRANS_FEAT(SQXTNT, aa64_sve2, do_narrow_extract, a, sqxtnt_ops) 6477f0984d40SFabiano Rosas 6478f0984d40SFabiano Rosas static const TCGOpcode uqxtn_list[] = { 6479f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_umin_vec, 0 6480f0984d40SFabiano Rosas }; 6481f0984d40SFabiano Rosas 6482f0984d40SFabiano Rosas static void gen_uqxtnb_vec(unsigned vece, TCGv_vec d, TCGv_vec n) 6483f0984d40SFabiano Rosas { 6484f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6485f0984d40SFabiano Rosas int halfbits = 4 << vece; 6486f0984d40SFabiano Rosas int64_t max = (1ull << halfbits) - 1; 6487f0984d40SFabiano Rosas 6488f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6489f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, d, n, t); 6490f0984d40SFabiano Rosas } 6491f0984d40SFabiano Rosas 6492f0984d40SFabiano Rosas static const GVecGen2 uqxtnb_ops[3] = { 6493f0984d40SFabiano Rosas { .fniv = gen_uqxtnb_vec, 6494f0984d40SFabiano Rosas .opt_opc = uqxtn_list, 6495f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqxtnb_h, 6496f0984d40SFabiano Rosas .vece = MO_16 }, 6497f0984d40SFabiano Rosas { .fniv = gen_uqxtnb_vec, 6498f0984d40SFabiano Rosas .opt_opc = uqxtn_list, 6499f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqxtnb_s, 6500f0984d40SFabiano Rosas .vece = MO_32 }, 6501f0984d40SFabiano Rosas { .fniv = gen_uqxtnb_vec, 6502f0984d40SFabiano Rosas .opt_opc = uqxtn_list, 6503f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqxtnb_d, 6504f0984d40SFabiano Rosas .vece = MO_64 }, 6505f0984d40SFabiano Rosas }; 6506f0984d40SFabiano Rosas TRANS_FEAT(UQXTNB, aa64_sve2, do_narrow_extract, a, uqxtnb_ops) 6507f0984d40SFabiano Rosas 6508f0984d40SFabiano Rosas static void gen_uqxtnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n) 6509f0984d40SFabiano Rosas { 6510f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6511f0984d40SFabiano Rosas int halfbits = 4 << vece; 6512f0984d40SFabiano Rosas int64_t max = (1ull << halfbits) - 1; 6513f0984d40SFabiano Rosas 6514f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6515f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, n, n, t); 6516f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits); 6517f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6518f0984d40SFabiano Rosas } 6519f0984d40SFabiano Rosas 6520f0984d40SFabiano Rosas static const GVecGen2 uqxtnt_ops[3] = { 6521f0984d40SFabiano Rosas { .fniv = gen_uqxtnt_vec, 6522f0984d40SFabiano Rosas .opt_opc = uqxtn_list, 6523f0984d40SFabiano Rosas .load_dest = true, 6524f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqxtnt_h, 6525f0984d40SFabiano Rosas .vece = MO_16 }, 6526f0984d40SFabiano Rosas { .fniv = gen_uqxtnt_vec, 6527f0984d40SFabiano Rosas .opt_opc = uqxtn_list, 6528f0984d40SFabiano Rosas .load_dest = true, 6529f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqxtnt_s, 6530f0984d40SFabiano Rosas .vece = MO_32 }, 6531f0984d40SFabiano Rosas { .fniv = gen_uqxtnt_vec, 6532f0984d40SFabiano Rosas .opt_opc = uqxtn_list, 6533f0984d40SFabiano Rosas .load_dest = true, 6534f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqxtnt_d, 6535f0984d40SFabiano Rosas .vece = MO_64 }, 6536f0984d40SFabiano Rosas }; 6537f0984d40SFabiano Rosas TRANS_FEAT(UQXTNT, aa64_sve2, do_narrow_extract, a, uqxtnt_ops) 6538f0984d40SFabiano Rosas 6539f0984d40SFabiano Rosas static const TCGOpcode sqxtun_list[] = { 6540f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_umin_vec, INDEX_op_smax_vec, 0 6541f0984d40SFabiano Rosas }; 6542f0984d40SFabiano Rosas 6543f0984d40SFabiano Rosas static void gen_sqxtunb_vec(unsigned vece, TCGv_vec d, TCGv_vec n) 6544f0984d40SFabiano Rosas { 6545f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6546f0984d40SFabiano Rosas int halfbits = 4 << vece; 6547f0984d40SFabiano Rosas int64_t max = (1ull << halfbits) - 1; 6548f0984d40SFabiano Rosas 6549f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, 0); 6550f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, d, n, t); 6551f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6552f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, d, d, t); 6553f0984d40SFabiano Rosas } 6554f0984d40SFabiano Rosas 6555f0984d40SFabiano Rosas static const GVecGen2 sqxtunb_ops[3] = { 6556f0984d40SFabiano Rosas { .fniv = gen_sqxtunb_vec, 6557f0984d40SFabiano Rosas .opt_opc = sqxtun_list, 6558f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtunb_h, 6559f0984d40SFabiano Rosas .vece = MO_16 }, 6560f0984d40SFabiano Rosas { .fniv = gen_sqxtunb_vec, 6561f0984d40SFabiano Rosas .opt_opc = sqxtun_list, 6562f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtunb_s, 6563f0984d40SFabiano Rosas .vece = MO_32 }, 6564f0984d40SFabiano Rosas { .fniv = gen_sqxtunb_vec, 6565f0984d40SFabiano Rosas .opt_opc = sqxtun_list, 6566f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtunb_d, 6567f0984d40SFabiano Rosas .vece = MO_64 }, 6568f0984d40SFabiano Rosas }; 6569f0984d40SFabiano Rosas TRANS_FEAT(SQXTUNB, aa64_sve2, do_narrow_extract, a, sqxtunb_ops) 6570f0984d40SFabiano Rosas 6571f0984d40SFabiano Rosas static void gen_sqxtunt_vec(unsigned vece, TCGv_vec d, TCGv_vec n) 6572f0984d40SFabiano Rosas { 6573f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6574f0984d40SFabiano Rosas int halfbits = 4 << vece; 6575f0984d40SFabiano Rosas int64_t max = (1ull << halfbits) - 1; 6576f0984d40SFabiano Rosas 6577f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, 0); 6578f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, n, n, t); 6579f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6580f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, n, n, t); 6581f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits); 6582f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6583f0984d40SFabiano Rosas } 6584f0984d40SFabiano Rosas 6585f0984d40SFabiano Rosas static const GVecGen2 sqxtunt_ops[3] = { 6586f0984d40SFabiano Rosas { .fniv = gen_sqxtunt_vec, 6587f0984d40SFabiano Rosas .opt_opc = sqxtun_list, 6588f0984d40SFabiano Rosas .load_dest = true, 6589f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtunt_h, 6590f0984d40SFabiano Rosas .vece = MO_16 }, 6591f0984d40SFabiano Rosas { .fniv = gen_sqxtunt_vec, 6592f0984d40SFabiano Rosas .opt_opc = sqxtun_list, 6593f0984d40SFabiano Rosas .load_dest = true, 6594f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtunt_s, 6595f0984d40SFabiano Rosas .vece = MO_32 }, 6596f0984d40SFabiano Rosas { .fniv = gen_sqxtunt_vec, 6597f0984d40SFabiano Rosas .opt_opc = sqxtun_list, 6598f0984d40SFabiano Rosas .load_dest = true, 6599f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqxtunt_d, 6600f0984d40SFabiano Rosas .vece = MO_64 }, 6601f0984d40SFabiano Rosas }; 6602f0984d40SFabiano Rosas TRANS_FEAT(SQXTUNT, aa64_sve2, do_narrow_extract, a, sqxtunt_ops) 6603f0984d40SFabiano Rosas 6604f0984d40SFabiano Rosas static bool do_shr_narrow(DisasContext *s, arg_rri_esz *a, 6605f0984d40SFabiano Rosas const GVecGen2i ops[3]) 6606f0984d40SFabiano Rosas { 6607f0984d40SFabiano Rosas if (a->esz < 0 || a->esz > MO_32) { 6608f0984d40SFabiano Rosas return false; 6609f0984d40SFabiano Rosas } 6610f0984d40SFabiano Rosas assert(a->imm > 0 && a->imm <= (8 << a->esz)); 6611f0984d40SFabiano Rosas if (sve_access_check(s)) { 6612f0984d40SFabiano Rosas unsigned vsz = vec_full_reg_size(s); 6613f0984d40SFabiano Rosas tcg_gen_gvec_2i(vec_full_reg_offset(s, a->rd), 6614f0984d40SFabiano Rosas vec_full_reg_offset(s, a->rn), 6615f0984d40SFabiano Rosas vsz, vsz, a->imm, &ops[a->esz]); 6616f0984d40SFabiano Rosas } 6617f0984d40SFabiano Rosas return true; 6618f0984d40SFabiano Rosas } 6619f0984d40SFabiano Rosas 6620f0984d40SFabiano Rosas static void gen_shrnb_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int shr) 6621f0984d40SFabiano Rosas { 6622f0984d40SFabiano Rosas int halfbits = 4 << vece; 6623f0984d40SFabiano Rosas uint64_t mask = dup_const(vece, MAKE_64BIT_MASK(0, halfbits)); 6624f0984d40SFabiano Rosas 6625f0984d40SFabiano Rosas tcg_gen_shri_i64(d, n, shr); 6626f0984d40SFabiano Rosas tcg_gen_andi_i64(d, d, mask); 6627f0984d40SFabiano Rosas } 6628f0984d40SFabiano Rosas 6629f0984d40SFabiano Rosas static void gen_shrnb16_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr) 6630f0984d40SFabiano Rosas { 6631f0984d40SFabiano Rosas gen_shrnb_i64(MO_16, d, n, shr); 6632f0984d40SFabiano Rosas } 6633f0984d40SFabiano Rosas 6634f0984d40SFabiano Rosas static void gen_shrnb32_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr) 6635f0984d40SFabiano Rosas { 6636f0984d40SFabiano Rosas gen_shrnb_i64(MO_32, d, n, shr); 6637f0984d40SFabiano Rosas } 6638f0984d40SFabiano Rosas 6639f0984d40SFabiano Rosas static void gen_shrnb64_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr) 6640f0984d40SFabiano Rosas { 6641f0984d40SFabiano Rosas gen_shrnb_i64(MO_64, d, n, shr); 6642f0984d40SFabiano Rosas } 6643f0984d40SFabiano Rosas 6644f0984d40SFabiano Rosas static void gen_shrnb_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t shr) 6645f0984d40SFabiano Rosas { 6646f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6647f0984d40SFabiano Rosas int halfbits = 4 << vece; 6648f0984d40SFabiano Rosas uint64_t mask = MAKE_64BIT_MASK(0, halfbits); 6649f0984d40SFabiano Rosas 6650f0984d40SFabiano Rosas tcg_gen_shri_vec(vece, n, n, shr); 6651f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, mask); 6652f0984d40SFabiano Rosas tcg_gen_and_vec(vece, d, n, t); 6653f0984d40SFabiano Rosas } 6654f0984d40SFabiano Rosas 6655f0984d40SFabiano Rosas static const TCGOpcode shrnb_vec_list[] = { INDEX_op_shri_vec, 0 }; 6656f0984d40SFabiano Rosas static const GVecGen2i shrnb_ops[3] = { 6657f0984d40SFabiano Rosas { .fni8 = gen_shrnb16_i64, 6658f0984d40SFabiano Rosas .fniv = gen_shrnb_vec, 6659f0984d40SFabiano Rosas .opt_opc = shrnb_vec_list, 6660f0984d40SFabiano Rosas .fno = gen_helper_sve2_shrnb_h, 6661f0984d40SFabiano Rosas .vece = MO_16 }, 6662f0984d40SFabiano Rosas { .fni8 = gen_shrnb32_i64, 6663f0984d40SFabiano Rosas .fniv = gen_shrnb_vec, 6664f0984d40SFabiano Rosas .opt_opc = shrnb_vec_list, 6665f0984d40SFabiano Rosas .fno = gen_helper_sve2_shrnb_s, 6666f0984d40SFabiano Rosas .vece = MO_32 }, 6667f0984d40SFabiano Rosas { .fni8 = gen_shrnb64_i64, 6668f0984d40SFabiano Rosas .fniv = gen_shrnb_vec, 6669f0984d40SFabiano Rosas .opt_opc = shrnb_vec_list, 6670f0984d40SFabiano Rosas .fno = gen_helper_sve2_shrnb_d, 6671f0984d40SFabiano Rosas .vece = MO_64 }, 6672f0984d40SFabiano Rosas }; 6673f0984d40SFabiano Rosas TRANS_FEAT(SHRNB, aa64_sve2, do_shr_narrow, a, shrnb_ops) 6674f0984d40SFabiano Rosas 6675f0984d40SFabiano Rosas static void gen_shrnt_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int shr) 6676f0984d40SFabiano Rosas { 6677f0984d40SFabiano Rosas int halfbits = 4 << vece; 6678f0984d40SFabiano Rosas uint64_t mask = dup_const(vece, MAKE_64BIT_MASK(0, halfbits)); 6679f0984d40SFabiano Rosas 6680f0984d40SFabiano Rosas tcg_gen_shli_i64(n, n, halfbits - shr); 6681f0984d40SFabiano Rosas tcg_gen_andi_i64(n, n, ~mask); 6682f0984d40SFabiano Rosas tcg_gen_andi_i64(d, d, mask); 6683f0984d40SFabiano Rosas tcg_gen_or_i64(d, d, n); 6684f0984d40SFabiano Rosas } 6685f0984d40SFabiano Rosas 6686f0984d40SFabiano Rosas static void gen_shrnt16_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr) 6687f0984d40SFabiano Rosas { 6688f0984d40SFabiano Rosas gen_shrnt_i64(MO_16, d, n, shr); 6689f0984d40SFabiano Rosas } 6690f0984d40SFabiano Rosas 6691f0984d40SFabiano Rosas static void gen_shrnt32_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr) 6692f0984d40SFabiano Rosas { 6693f0984d40SFabiano Rosas gen_shrnt_i64(MO_32, d, n, shr); 6694f0984d40SFabiano Rosas } 6695f0984d40SFabiano Rosas 6696f0984d40SFabiano Rosas static void gen_shrnt64_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr) 6697f0984d40SFabiano Rosas { 6698f0984d40SFabiano Rosas tcg_gen_shri_i64(n, n, shr); 6699f0984d40SFabiano Rosas tcg_gen_deposit_i64(d, d, n, 32, 32); 6700f0984d40SFabiano Rosas } 6701f0984d40SFabiano Rosas 6702f0984d40SFabiano Rosas static void gen_shrnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t shr) 6703f0984d40SFabiano Rosas { 6704f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6705f0984d40SFabiano Rosas int halfbits = 4 << vece; 6706f0984d40SFabiano Rosas uint64_t mask = MAKE_64BIT_MASK(0, halfbits); 6707f0984d40SFabiano Rosas 6708f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits - shr); 6709f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, mask); 6710f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6711f0984d40SFabiano Rosas } 6712f0984d40SFabiano Rosas 6713f0984d40SFabiano Rosas static const TCGOpcode shrnt_vec_list[] = { INDEX_op_shli_vec, 0 }; 6714f0984d40SFabiano Rosas static const GVecGen2i shrnt_ops[3] = { 6715f0984d40SFabiano Rosas { .fni8 = gen_shrnt16_i64, 6716f0984d40SFabiano Rosas .fniv = gen_shrnt_vec, 6717f0984d40SFabiano Rosas .opt_opc = shrnt_vec_list, 6718f0984d40SFabiano Rosas .load_dest = true, 6719f0984d40SFabiano Rosas .fno = gen_helper_sve2_shrnt_h, 6720f0984d40SFabiano Rosas .vece = MO_16 }, 6721f0984d40SFabiano Rosas { .fni8 = gen_shrnt32_i64, 6722f0984d40SFabiano Rosas .fniv = gen_shrnt_vec, 6723f0984d40SFabiano Rosas .opt_opc = shrnt_vec_list, 6724f0984d40SFabiano Rosas .load_dest = true, 6725f0984d40SFabiano Rosas .fno = gen_helper_sve2_shrnt_s, 6726f0984d40SFabiano Rosas .vece = MO_32 }, 6727f0984d40SFabiano Rosas { .fni8 = gen_shrnt64_i64, 6728f0984d40SFabiano Rosas .fniv = gen_shrnt_vec, 6729f0984d40SFabiano Rosas .opt_opc = shrnt_vec_list, 6730f0984d40SFabiano Rosas .load_dest = true, 6731f0984d40SFabiano Rosas .fno = gen_helper_sve2_shrnt_d, 6732f0984d40SFabiano Rosas .vece = MO_64 }, 6733f0984d40SFabiano Rosas }; 6734f0984d40SFabiano Rosas TRANS_FEAT(SHRNT, aa64_sve2, do_shr_narrow, a, shrnt_ops) 6735f0984d40SFabiano Rosas 6736f0984d40SFabiano Rosas static const GVecGen2i rshrnb_ops[3] = { 6737f0984d40SFabiano Rosas { .fno = gen_helper_sve2_rshrnb_h }, 6738f0984d40SFabiano Rosas { .fno = gen_helper_sve2_rshrnb_s }, 6739f0984d40SFabiano Rosas { .fno = gen_helper_sve2_rshrnb_d }, 6740f0984d40SFabiano Rosas }; 6741f0984d40SFabiano Rosas TRANS_FEAT(RSHRNB, aa64_sve2, do_shr_narrow, a, rshrnb_ops) 6742f0984d40SFabiano Rosas 6743f0984d40SFabiano Rosas static const GVecGen2i rshrnt_ops[3] = { 6744f0984d40SFabiano Rosas { .fno = gen_helper_sve2_rshrnt_h }, 6745f0984d40SFabiano Rosas { .fno = gen_helper_sve2_rshrnt_s }, 6746f0984d40SFabiano Rosas { .fno = gen_helper_sve2_rshrnt_d }, 6747f0984d40SFabiano Rosas }; 6748f0984d40SFabiano Rosas TRANS_FEAT(RSHRNT, aa64_sve2, do_shr_narrow, a, rshrnt_ops) 6749f0984d40SFabiano Rosas 6750f0984d40SFabiano Rosas static void gen_sqshrunb_vec(unsigned vece, TCGv_vec d, 6751f0984d40SFabiano Rosas TCGv_vec n, int64_t shr) 6752f0984d40SFabiano Rosas { 6753f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6754f0984d40SFabiano Rosas int halfbits = 4 << vece; 6755f0984d40SFabiano Rosas 6756f0984d40SFabiano Rosas tcg_gen_sari_vec(vece, n, n, shr); 6757f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, 0); 6758f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, n, n, t); 6759f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6760f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, d, n, t); 6761f0984d40SFabiano Rosas } 6762f0984d40SFabiano Rosas 6763f0984d40SFabiano Rosas static const TCGOpcode sqshrunb_vec_list[] = { 6764f0984d40SFabiano Rosas INDEX_op_sari_vec, INDEX_op_smax_vec, INDEX_op_umin_vec, 0 6765f0984d40SFabiano Rosas }; 6766f0984d40SFabiano Rosas static const GVecGen2i sqshrunb_ops[3] = { 6767f0984d40SFabiano Rosas { .fniv = gen_sqshrunb_vec, 6768f0984d40SFabiano Rosas .opt_opc = sqshrunb_vec_list, 6769f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrunb_h, 6770f0984d40SFabiano Rosas .vece = MO_16 }, 6771f0984d40SFabiano Rosas { .fniv = gen_sqshrunb_vec, 6772f0984d40SFabiano Rosas .opt_opc = sqshrunb_vec_list, 6773f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrunb_s, 6774f0984d40SFabiano Rosas .vece = MO_32 }, 6775f0984d40SFabiano Rosas { .fniv = gen_sqshrunb_vec, 6776f0984d40SFabiano Rosas .opt_opc = sqshrunb_vec_list, 6777f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrunb_d, 6778f0984d40SFabiano Rosas .vece = MO_64 }, 6779f0984d40SFabiano Rosas }; 6780f0984d40SFabiano Rosas TRANS_FEAT(SQSHRUNB, aa64_sve2, do_shr_narrow, a, sqshrunb_ops) 6781f0984d40SFabiano Rosas 6782f0984d40SFabiano Rosas static void gen_sqshrunt_vec(unsigned vece, TCGv_vec d, 6783f0984d40SFabiano Rosas TCGv_vec n, int64_t shr) 6784f0984d40SFabiano Rosas { 6785f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6786f0984d40SFabiano Rosas int halfbits = 4 << vece; 6787f0984d40SFabiano Rosas 6788f0984d40SFabiano Rosas tcg_gen_sari_vec(vece, n, n, shr); 6789f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, 0); 6790f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, n, n, t); 6791f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6792f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, n, n, t); 6793f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits); 6794f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6795f0984d40SFabiano Rosas } 6796f0984d40SFabiano Rosas 6797f0984d40SFabiano Rosas static const TCGOpcode sqshrunt_vec_list[] = { 6798f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_sari_vec, 6799f0984d40SFabiano Rosas INDEX_op_smax_vec, INDEX_op_umin_vec, 0 6800f0984d40SFabiano Rosas }; 6801f0984d40SFabiano Rosas static const GVecGen2i sqshrunt_ops[3] = { 6802f0984d40SFabiano Rosas { .fniv = gen_sqshrunt_vec, 6803f0984d40SFabiano Rosas .opt_opc = sqshrunt_vec_list, 6804f0984d40SFabiano Rosas .load_dest = true, 6805f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrunt_h, 6806f0984d40SFabiano Rosas .vece = MO_16 }, 6807f0984d40SFabiano Rosas { .fniv = gen_sqshrunt_vec, 6808f0984d40SFabiano Rosas .opt_opc = sqshrunt_vec_list, 6809f0984d40SFabiano Rosas .load_dest = true, 6810f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrunt_s, 6811f0984d40SFabiano Rosas .vece = MO_32 }, 6812f0984d40SFabiano Rosas { .fniv = gen_sqshrunt_vec, 6813f0984d40SFabiano Rosas .opt_opc = sqshrunt_vec_list, 6814f0984d40SFabiano Rosas .load_dest = true, 6815f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrunt_d, 6816f0984d40SFabiano Rosas .vece = MO_64 }, 6817f0984d40SFabiano Rosas }; 6818f0984d40SFabiano Rosas TRANS_FEAT(SQSHRUNT, aa64_sve2, do_shr_narrow, a, sqshrunt_ops) 6819f0984d40SFabiano Rosas 6820f0984d40SFabiano Rosas static const GVecGen2i sqrshrunb_ops[3] = { 6821f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrunb_h }, 6822f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrunb_s }, 6823f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrunb_d }, 6824f0984d40SFabiano Rosas }; 6825f0984d40SFabiano Rosas TRANS_FEAT(SQRSHRUNB, aa64_sve2, do_shr_narrow, a, sqrshrunb_ops) 6826f0984d40SFabiano Rosas 6827f0984d40SFabiano Rosas static const GVecGen2i sqrshrunt_ops[3] = { 6828f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrunt_h }, 6829f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrunt_s }, 6830f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrunt_d }, 6831f0984d40SFabiano Rosas }; 6832f0984d40SFabiano Rosas TRANS_FEAT(SQRSHRUNT, aa64_sve2, do_shr_narrow, a, sqrshrunt_ops) 6833f0984d40SFabiano Rosas 6834f0984d40SFabiano Rosas static void gen_sqshrnb_vec(unsigned vece, TCGv_vec d, 6835f0984d40SFabiano Rosas TCGv_vec n, int64_t shr) 6836f0984d40SFabiano Rosas { 6837f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6838f0984d40SFabiano Rosas int halfbits = 4 << vece; 6839f0984d40SFabiano Rosas int64_t max = MAKE_64BIT_MASK(0, halfbits - 1); 6840f0984d40SFabiano Rosas int64_t min = -max - 1; 6841f0984d40SFabiano Rosas 6842f0984d40SFabiano Rosas tcg_gen_sari_vec(vece, n, n, shr); 6843f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, min); 6844f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, n, n, t); 6845f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6846f0984d40SFabiano Rosas tcg_gen_smin_vec(vece, n, n, t); 6847f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6848f0984d40SFabiano Rosas tcg_gen_and_vec(vece, d, n, t); 6849f0984d40SFabiano Rosas } 6850f0984d40SFabiano Rosas 6851f0984d40SFabiano Rosas static const TCGOpcode sqshrnb_vec_list[] = { 6852f0984d40SFabiano Rosas INDEX_op_sari_vec, INDEX_op_smax_vec, INDEX_op_smin_vec, 0 6853f0984d40SFabiano Rosas }; 6854f0984d40SFabiano Rosas static const GVecGen2i sqshrnb_ops[3] = { 6855f0984d40SFabiano Rosas { .fniv = gen_sqshrnb_vec, 6856f0984d40SFabiano Rosas .opt_opc = sqshrnb_vec_list, 6857f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrnb_h, 6858f0984d40SFabiano Rosas .vece = MO_16 }, 6859f0984d40SFabiano Rosas { .fniv = gen_sqshrnb_vec, 6860f0984d40SFabiano Rosas .opt_opc = sqshrnb_vec_list, 6861f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrnb_s, 6862f0984d40SFabiano Rosas .vece = MO_32 }, 6863f0984d40SFabiano Rosas { .fniv = gen_sqshrnb_vec, 6864f0984d40SFabiano Rosas .opt_opc = sqshrnb_vec_list, 6865f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrnb_d, 6866f0984d40SFabiano Rosas .vece = MO_64 }, 6867f0984d40SFabiano Rosas }; 6868f0984d40SFabiano Rosas TRANS_FEAT(SQSHRNB, aa64_sve2, do_shr_narrow, a, sqshrnb_ops) 6869f0984d40SFabiano Rosas 6870f0984d40SFabiano Rosas static void gen_sqshrnt_vec(unsigned vece, TCGv_vec d, 6871f0984d40SFabiano Rosas TCGv_vec n, int64_t shr) 6872f0984d40SFabiano Rosas { 6873f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6874f0984d40SFabiano Rosas int halfbits = 4 << vece; 6875f0984d40SFabiano Rosas int64_t max = MAKE_64BIT_MASK(0, halfbits - 1); 6876f0984d40SFabiano Rosas int64_t min = -max - 1; 6877f0984d40SFabiano Rosas 6878f0984d40SFabiano Rosas tcg_gen_sari_vec(vece, n, n, shr); 6879f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, min); 6880f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, n, n, t); 6881f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, max); 6882f0984d40SFabiano Rosas tcg_gen_smin_vec(vece, n, n, t); 6883f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits); 6884f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6885f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6886f0984d40SFabiano Rosas } 6887f0984d40SFabiano Rosas 6888f0984d40SFabiano Rosas static const TCGOpcode sqshrnt_vec_list[] = { 6889f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_sari_vec, 6890f0984d40SFabiano Rosas INDEX_op_smax_vec, INDEX_op_smin_vec, 0 6891f0984d40SFabiano Rosas }; 6892f0984d40SFabiano Rosas static const GVecGen2i sqshrnt_ops[3] = { 6893f0984d40SFabiano Rosas { .fniv = gen_sqshrnt_vec, 6894f0984d40SFabiano Rosas .opt_opc = sqshrnt_vec_list, 6895f0984d40SFabiano Rosas .load_dest = true, 6896f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrnt_h, 6897f0984d40SFabiano Rosas .vece = MO_16 }, 6898f0984d40SFabiano Rosas { .fniv = gen_sqshrnt_vec, 6899f0984d40SFabiano Rosas .opt_opc = sqshrnt_vec_list, 6900f0984d40SFabiano Rosas .load_dest = true, 6901f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrnt_s, 6902f0984d40SFabiano Rosas .vece = MO_32 }, 6903f0984d40SFabiano Rosas { .fniv = gen_sqshrnt_vec, 6904f0984d40SFabiano Rosas .opt_opc = sqshrnt_vec_list, 6905f0984d40SFabiano Rosas .load_dest = true, 6906f0984d40SFabiano Rosas .fno = gen_helper_sve2_sqshrnt_d, 6907f0984d40SFabiano Rosas .vece = MO_64 }, 6908f0984d40SFabiano Rosas }; 6909f0984d40SFabiano Rosas TRANS_FEAT(SQSHRNT, aa64_sve2, do_shr_narrow, a, sqshrnt_ops) 6910f0984d40SFabiano Rosas 6911f0984d40SFabiano Rosas static const GVecGen2i sqrshrnb_ops[3] = { 6912f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrnb_h }, 6913f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrnb_s }, 6914f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrnb_d }, 6915f0984d40SFabiano Rosas }; 6916f0984d40SFabiano Rosas TRANS_FEAT(SQRSHRNB, aa64_sve2, do_shr_narrow, a, sqrshrnb_ops) 6917f0984d40SFabiano Rosas 6918f0984d40SFabiano Rosas static const GVecGen2i sqrshrnt_ops[3] = { 6919f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrnt_h }, 6920f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrnt_s }, 6921f0984d40SFabiano Rosas { .fno = gen_helper_sve2_sqrshrnt_d }, 6922f0984d40SFabiano Rosas }; 6923f0984d40SFabiano Rosas TRANS_FEAT(SQRSHRNT, aa64_sve2, do_shr_narrow, a, sqrshrnt_ops) 6924f0984d40SFabiano Rosas 6925f0984d40SFabiano Rosas static void gen_uqshrnb_vec(unsigned vece, TCGv_vec d, 6926f0984d40SFabiano Rosas TCGv_vec n, int64_t shr) 6927f0984d40SFabiano Rosas { 6928f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6929f0984d40SFabiano Rosas int halfbits = 4 << vece; 6930f0984d40SFabiano Rosas 6931f0984d40SFabiano Rosas tcg_gen_shri_vec(vece, n, n, shr); 6932f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6933f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, d, n, t); 6934f0984d40SFabiano Rosas } 6935f0984d40SFabiano Rosas 6936f0984d40SFabiano Rosas static const TCGOpcode uqshrnb_vec_list[] = { 6937f0984d40SFabiano Rosas INDEX_op_shri_vec, INDEX_op_umin_vec, 0 6938f0984d40SFabiano Rosas }; 6939f0984d40SFabiano Rosas static const GVecGen2i uqshrnb_ops[3] = { 6940f0984d40SFabiano Rosas { .fniv = gen_uqshrnb_vec, 6941f0984d40SFabiano Rosas .opt_opc = uqshrnb_vec_list, 6942f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqshrnb_h, 6943f0984d40SFabiano Rosas .vece = MO_16 }, 6944f0984d40SFabiano Rosas { .fniv = gen_uqshrnb_vec, 6945f0984d40SFabiano Rosas .opt_opc = uqshrnb_vec_list, 6946f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqshrnb_s, 6947f0984d40SFabiano Rosas .vece = MO_32 }, 6948f0984d40SFabiano Rosas { .fniv = gen_uqshrnb_vec, 6949f0984d40SFabiano Rosas .opt_opc = uqshrnb_vec_list, 6950f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqshrnb_d, 6951f0984d40SFabiano Rosas .vece = MO_64 }, 6952f0984d40SFabiano Rosas }; 6953f0984d40SFabiano Rosas TRANS_FEAT(UQSHRNB, aa64_sve2, do_shr_narrow, a, uqshrnb_ops) 6954f0984d40SFabiano Rosas 6955f0984d40SFabiano Rosas static void gen_uqshrnt_vec(unsigned vece, TCGv_vec d, 6956f0984d40SFabiano Rosas TCGv_vec n, int64_t shr) 6957f0984d40SFabiano Rosas { 6958f0984d40SFabiano Rosas TCGv_vec t = tcg_temp_new_vec_matching(d); 6959f0984d40SFabiano Rosas int halfbits = 4 << vece; 6960f0984d40SFabiano Rosas 6961f0984d40SFabiano Rosas tcg_gen_shri_vec(vece, n, n, shr); 6962f0984d40SFabiano Rosas tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits)); 6963f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, n, n, t); 6964f0984d40SFabiano Rosas tcg_gen_shli_vec(vece, n, n, halfbits); 6965f0984d40SFabiano Rosas tcg_gen_bitsel_vec(vece, d, t, d, n); 6966f0984d40SFabiano Rosas } 6967f0984d40SFabiano Rosas 6968f0984d40SFabiano Rosas static const TCGOpcode uqshrnt_vec_list[] = { 6969f0984d40SFabiano Rosas INDEX_op_shli_vec, INDEX_op_shri_vec, INDEX_op_umin_vec, 0 6970f0984d40SFabiano Rosas }; 6971f0984d40SFabiano Rosas static const GVecGen2i uqshrnt_ops[3] = { 6972f0984d40SFabiano Rosas { .fniv = gen_uqshrnt_vec, 6973f0984d40SFabiano Rosas .opt_opc = uqshrnt_vec_list, 6974f0984d40SFabiano Rosas .load_dest = true, 6975f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqshrnt_h, 6976f0984d40SFabiano Rosas .vece = MO_16 }, 6977f0984d40SFabiano Rosas { .fniv = gen_uqshrnt_vec, 6978f0984d40SFabiano Rosas .opt_opc = uqshrnt_vec_list, 6979f0984d40SFabiano Rosas .load_dest = true, 6980f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqshrnt_s, 6981f0984d40SFabiano Rosas .vece = MO_32 }, 6982f0984d40SFabiano Rosas { .fniv = gen_uqshrnt_vec, 6983f0984d40SFabiano Rosas .opt_opc = uqshrnt_vec_list, 6984f0984d40SFabiano Rosas .load_dest = true, 6985f0984d40SFabiano Rosas .fno = gen_helper_sve2_uqshrnt_d, 6986f0984d40SFabiano Rosas .vece = MO_64 }, 6987f0984d40SFabiano Rosas }; 6988f0984d40SFabiano Rosas TRANS_FEAT(UQSHRNT, aa64_sve2, do_shr_narrow, a, uqshrnt_ops) 6989f0984d40SFabiano Rosas 6990f0984d40SFabiano Rosas static const GVecGen2i uqrshrnb_ops[3] = { 6991f0984d40SFabiano Rosas { .fno = gen_helper_sve2_uqrshrnb_h }, 6992f0984d40SFabiano Rosas { .fno = gen_helper_sve2_uqrshrnb_s }, 6993f0984d40SFabiano Rosas { .fno = gen_helper_sve2_uqrshrnb_d }, 6994f0984d40SFabiano Rosas }; 6995f0984d40SFabiano Rosas TRANS_FEAT(UQRSHRNB, aa64_sve2, do_shr_narrow, a, uqrshrnb_ops) 6996f0984d40SFabiano Rosas 6997f0984d40SFabiano Rosas static const GVecGen2i uqrshrnt_ops[3] = { 6998f0984d40SFabiano Rosas { .fno = gen_helper_sve2_uqrshrnt_h }, 6999f0984d40SFabiano Rosas { .fno = gen_helper_sve2_uqrshrnt_s }, 7000f0984d40SFabiano Rosas { .fno = gen_helper_sve2_uqrshrnt_d }, 7001f0984d40SFabiano Rosas }; 7002f0984d40SFabiano Rosas TRANS_FEAT(UQRSHRNT, aa64_sve2, do_shr_narrow, a, uqrshrnt_ops) 7003f0984d40SFabiano Rosas 7004f0984d40SFabiano Rosas #define DO_SVE2_ZZZ_NARROW(NAME, name) \ 7005f0984d40SFabiano Rosas static gen_helper_gvec_3 * const name##_fns[4] = { \ 7006f0984d40SFabiano Rosas NULL, gen_helper_sve2_##name##_h, \ 7007f0984d40SFabiano Rosas gen_helper_sve2_##name##_s, gen_helper_sve2_##name##_d, \ 7008f0984d40SFabiano Rosas }; \ 7009f0984d40SFabiano Rosas TRANS_FEAT(NAME, aa64_sve2, gen_gvec_ool_arg_zzz, \ 7010f0984d40SFabiano Rosas name##_fns[a->esz], a, 0) 7011f0984d40SFabiano Rosas 7012f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(ADDHNB, addhnb) 7013f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(ADDHNT, addhnt) 7014f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(RADDHNB, raddhnb) 7015f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(RADDHNT, raddhnt) 7016f0984d40SFabiano Rosas 7017f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(SUBHNB, subhnb) 7018f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(SUBHNT, subhnt) 7019f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(RSUBHNB, rsubhnb) 7020f0984d40SFabiano Rosas DO_SVE2_ZZZ_NARROW(RSUBHNT, rsubhnt) 7021f0984d40SFabiano Rosas 7022f0984d40SFabiano Rosas static gen_helper_gvec_flags_4 * const match_fns[4] = { 7023f0984d40SFabiano Rosas gen_helper_sve2_match_ppzz_b, gen_helper_sve2_match_ppzz_h, NULL, NULL 7024f0984d40SFabiano Rosas }; 7025f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(MATCH, aa64_sve2, do_ppzz_flags, a, match_fns[a->esz]) 7026f0984d40SFabiano Rosas 7027f0984d40SFabiano Rosas static gen_helper_gvec_flags_4 * const nmatch_fns[4] = { 7028f0984d40SFabiano Rosas gen_helper_sve2_nmatch_ppzz_b, gen_helper_sve2_nmatch_ppzz_h, NULL, NULL 7029f0984d40SFabiano Rosas }; 7030f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(NMATCH, aa64_sve2, do_ppzz_flags, a, nmatch_fns[a->esz]) 7031f0984d40SFabiano Rosas 7032f0984d40SFabiano Rosas static gen_helper_gvec_4 * const histcnt_fns[4] = { 7033f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve2_histcnt_s, gen_helper_sve2_histcnt_d 7034f0984d40SFabiano Rosas }; 7035f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(HISTCNT, aa64_sve2, gen_gvec_ool_arg_zpzz, 7036f0984d40SFabiano Rosas histcnt_fns[a->esz], a, 0) 7037f0984d40SFabiano Rosas 7038f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz, 7039f0984d40SFabiano Rosas a->esz == 0 ? gen_helper_sve2_histseg : NULL, a, 0) 7040f0984d40SFabiano Rosas 7041f0984d40SFabiano Rosas DO_ZPZZ_FP(FADDP, aa64_sve2, sve2_faddp_zpzz) 7042f0984d40SFabiano Rosas DO_ZPZZ_FP(FMAXNMP, aa64_sve2, sve2_fmaxnmp_zpzz) 7043f0984d40SFabiano Rosas DO_ZPZZ_FP(FMINNMP, aa64_sve2, sve2_fminnmp_zpzz) 7044f0984d40SFabiano Rosas DO_ZPZZ_FP(FMAXP, aa64_sve2, sve2_fmaxp_zpzz) 7045f0984d40SFabiano Rosas DO_ZPZZ_FP(FMINP, aa64_sve2, sve2_fminp_zpzz) 7046f0984d40SFabiano Rosas 7047f0984d40SFabiano Rosas /* 7048f0984d40SFabiano Rosas * SVE Integer Multiply-Add (unpredicated) 7049f0984d40SFabiano Rosas */ 7050f0984d40SFabiano Rosas 7051f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz, 7052f0984d40SFabiano Rosas gen_helper_fmmla_s, a->rd, a->rn, a->rm, a->ra, 7053f0984d40SFabiano Rosas 0, FPST_FPCR) 7054f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz, 7055f0984d40SFabiano Rosas gen_helper_fmmla_d, a->rd, a->rn, a->rm, a->ra, 7056f0984d40SFabiano Rosas 0, FPST_FPCR) 7057f0984d40SFabiano Rosas 7058f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = { 7059f0984d40SFabiano Rosas NULL, gen_helper_sve2_sqdmlal_zzzw_h, 7060f0984d40SFabiano Rosas gen_helper_sve2_sqdmlal_zzzw_s, gen_helper_sve2_sqdmlal_zzzw_d, 7061f0984d40SFabiano Rosas }; 7062f0984d40SFabiano Rosas TRANS_FEAT(SQDMLALB_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7063f0984d40SFabiano Rosas sqdmlal_zzzw_fns[a->esz], a, 0) 7064f0984d40SFabiano Rosas TRANS_FEAT(SQDMLALT_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7065f0984d40SFabiano Rosas sqdmlal_zzzw_fns[a->esz], a, 3) 7066f0984d40SFabiano Rosas TRANS_FEAT(SQDMLALBT, aa64_sve2, gen_gvec_ool_arg_zzzz, 7067f0984d40SFabiano Rosas sqdmlal_zzzw_fns[a->esz], a, 2) 7068f0984d40SFabiano Rosas 7069f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sqdmlsl_zzzw_fns[] = { 7070f0984d40SFabiano Rosas NULL, gen_helper_sve2_sqdmlsl_zzzw_h, 7071f0984d40SFabiano Rosas gen_helper_sve2_sqdmlsl_zzzw_s, gen_helper_sve2_sqdmlsl_zzzw_d, 7072f0984d40SFabiano Rosas }; 7073f0984d40SFabiano Rosas TRANS_FEAT(SQDMLSLB_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7074f0984d40SFabiano Rosas sqdmlsl_zzzw_fns[a->esz], a, 0) 7075f0984d40SFabiano Rosas TRANS_FEAT(SQDMLSLT_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7076f0984d40SFabiano Rosas sqdmlsl_zzzw_fns[a->esz], a, 3) 7077f0984d40SFabiano Rosas TRANS_FEAT(SQDMLSLBT, aa64_sve2, gen_gvec_ool_arg_zzzz, 7078f0984d40SFabiano Rosas sqdmlsl_zzzw_fns[a->esz], a, 2) 7079f0984d40SFabiano Rosas 7080f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sqrdmlah_fns[] = { 7081f0984d40SFabiano Rosas gen_helper_sve2_sqrdmlah_b, gen_helper_sve2_sqrdmlah_h, 7082f0984d40SFabiano Rosas gen_helper_sve2_sqrdmlah_s, gen_helper_sve2_sqrdmlah_d, 7083f0984d40SFabiano Rosas }; 7084f0984d40SFabiano Rosas TRANS_FEAT(SQRDMLAH_zzzz, aa64_sve2, gen_gvec_ool_arg_zzzz, 7085f0984d40SFabiano Rosas sqrdmlah_fns[a->esz], a, 0) 7086f0984d40SFabiano Rosas 7087f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sqrdmlsh_fns[] = { 7088f0984d40SFabiano Rosas gen_helper_sve2_sqrdmlsh_b, gen_helper_sve2_sqrdmlsh_h, 7089f0984d40SFabiano Rosas gen_helper_sve2_sqrdmlsh_s, gen_helper_sve2_sqrdmlsh_d, 7090f0984d40SFabiano Rosas }; 7091f0984d40SFabiano Rosas TRANS_FEAT(SQRDMLSH_zzzz, aa64_sve2, gen_gvec_ool_arg_zzzz, 7092f0984d40SFabiano Rosas sqrdmlsh_fns[a->esz], a, 0) 7093f0984d40SFabiano Rosas 7094f0984d40SFabiano Rosas static gen_helper_gvec_4 * const smlal_zzzw_fns[] = { 7095f0984d40SFabiano Rosas NULL, gen_helper_sve2_smlal_zzzw_h, 7096f0984d40SFabiano Rosas gen_helper_sve2_smlal_zzzw_s, gen_helper_sve2_smlal_zzzw_d, 7097f0984d40SFabiano Rosas }; 7098f0984d40SFabiano Rosas TRANS_FEAT(SMLALB_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7099f0984d40SFabiano Rosas smlal_zzzw_fns[a->esz], a, 0) 7100f0984d40SFabiano Rosas TRANS_FEAT(SMLALT_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7101f0984d40SFabiano Rosas smlal_zzzw_fns[a->esz], a, 1) 7102f0984d40SFabiano Rosas 7103f0984d40SFabiano Rosas static gen_helper_gvec_4 * const umlal_zzzw_fns[] = { 7104f0984d40SFabiano Rosas NULL, gen_helper_sve2_umlal_zzzw_h, 7105f0984d40SFabiano Rosas gen_helper_sve2_umlal_zzzw_s, gen_helper_sve2_umlal_zzzw_d, 7106f0984d40SFabiano Rosas }; 7107f0984d40SFabiano Rosas TRANS_FEAT(UMLALB_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7108f0984d40SFabiano Rosas umlal_zzzw_fns[a->esz], a, 0) 7109f0984d40SFabiano Rosas TRANS_FEAT(UMLALT_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7110f0984d40SFabiano Rosas umlal_zzzw_fns[a->esz], a, 1) 7111f0984d40SFabiano Rosas 7112f0984d40SFabiano Rosas static gen_helper_gvec_4 * const smlsl_zzzw_fns[] = { 7113f0984d40SFabiano Rosas NULL, gen_helper_sve2_smlsl_zzzw_h, 7114f0984d40SFabiano Rosas gen_helper_sve2_smlsl_zzzw_s, gen_helper_sve2_smlsl_zzzw_d, 7115f0984d40SFabiano Rosas }; 7116f0984d40SFabiano Rosas TRANS_FEAT(SMLSLB_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7117f0984d40SFabiano Rosas smlsl_zzzw_fns[a->esz], a, 0) 7118f0984d40SFabiano Rosas TRANS_FEAT(SMLSLT_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7119f0984d40SFabiano Rosas smlsl_zzzw_fns[a->esz], a, 1) 7120f0984d40SFabiano Rosas 7121f0984d40SFabiano Rosas static gen_helper_gvec_4 * const umlsl_zzzw_fns[] = { 7122f0984d40SFabiano Rosas NULL, gen_helper_sve2_umlsl_zzzw_h, 7123f0984d40SFabiano Rosas gen_helper_sve2_umlsl_zzzw_s, gen_helper_sve2_umlsl_zzzw_d, 7124f0984d40SFabiano Rosas }; 7125f0984d40SFabiano Rosas TRANS_FEAT(UMLSLB_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7126f0984d40SFabiano Rosas umlsl_zzzw_fns[a->esz], a, 0) 7127f0984d40SFabiano Rosas TRANS_FEAT(UMLSLT_zzzw, aa64_sve2, gen_gvec_ool_arg_zzzz, 7128f0984d40SFabiano Rosas umlsl_zzzw_fns[a->esz], a, 1) 7129f0984d40SFabiano Rosas 7130f0984d40SFabiano Rosas static gen_helper_gvec_4 * const cmla_fns[] = { 7131f0984d40SFabiano Rosas gen_helper_sve2_cmla_zzzz_b, gen_helper_sve2_cmla_zzzz_h, 7132f0984d40SFabiano Rosas gen_helper_sve2_cmla_zzzz_s, gen_helper_sve2_cmla_zzzz_d, 7133f0984d40SFabiano Rosas }; 7134f0984d40SFabiano Rosas TRANS_FEAT(CMLA_zzzz, aa64_sve2, gen_gvec_ool_zzzz, 7135f0984d40SFabiano Rosas cmla_fns[a->esz], a->rd, a->rn, a->rm, a->ra, a->rot) 7136f0984d40SFabiano Rosas 7137f0984d40SFabiano Rosas static gen_helper_gvec_4 * const cdot_fns[] = { 7138f0984d40SFabiano Rosas NULL, NULL, gen_helper_sve2_cdot_zzzz_s, gen_helper_sve2_cdot_zzzz_d 7139f0984d40SFabiano Rosas }; 7140f0984d40SFabiano Rosas TRANS_FEAT(CDOT_zzzz, aa64_sve2, gen_gvec_ool_zzzz, 7141f0984d40SFabiano Rosas cdot_fns[a->esz], a->rd, a->rn, a->rm, a->ra, a->rot) 7142f0984d40SFabiano Rosas 7143f0984d40SFabiano Rosas static gen_helper_gvec_4 * const sqrdcmlah_fns[] = { 7144f0984d40SFabiano Rosas gen_helper_sve2_sqrdcmlah_zzzz_b, gen_helper_sve2_sqrdcmlah_zzzz_h, 7145f0984d40SFabiano Rosas gen_helper_sve2_sqrdcmlah_zzzz_s, gen_helper_sve2_sqrdcmlah_zzzz_d, 7146f0984d40SFabiano Rosas }; 7147f0984d40SFabiano Rosas TRANS_FEAT(SQRDCMLAH_zzzz, aa64_sve2, gen_gvec_ool_zzzz, 7148f0984d40SFabiano Rosas sqrdcmlah_fns[a->esz], a->rd, a->rn, a->rm, a->ra, a->rot) 7149f0984d40SFabiano Rosas 7150f0984d40SFabiano Rosas TRANS_FEAT(USDOT_zzzz, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz, 7151f0984d40SFabiano Rosas a->esz == 2 ? gen_helper_gvec_usdot_b : NULL, a, 0) 7152f0984d40SFabiano Rosas 7153f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(AESMC, aa64_sve2_aes, gen_gvec_ool_zz, 71540f23908cSRichard Henderson gen_helper_crypto_aesmc, a->rd, a->rd, 0) 71550f23908cSRichard Henderson TRANS_FEAT_NONSTREAMING(AESIMC, aa64_sve2_aes, gen_gvec_ool_zz, 71560f23908cSRichard Henderson gen_helper_crypto_aesimc, a->rd, a->rd, 0) 7157f0984d40SFabiano Rosas 7158f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(AESE, aa64_sve2_aes, gen_gvec_ool_arg_zzz, 71590f23908cSRichard Henderson gen_helper_crypto_aese, a, 0) 7160f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(AESD, aa64_sve2_aes, gen_gvec_ool_arg_zzz, 71610f23908cSRichard Henderson gen_helper_crypto_aesd, a, 0) 7162f0984d40SFabiano Rosas 7163f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(SM4E, aa64_sve2_sm4, gen_gvec_ool_arg_zzz, 7164f0984d40SFabiano Rosas gen_helper_crypto_sm4e, a, 0) 7165f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(SM4EKEY, aa64_sve2_sm4, gen_gvec_ool_arg_zzz, 7166f0984d40SFabiano Rosas gen_helper_crypto_sm4ekey, a, 0) 7167f0984d40SFabiano Rosas 7168f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz, 7169f0984d40SFabiano Rosas gen_gvec_rax1, a) 7170f0984d40SFabiano Rosas 7171f0984d40SFabiano Rosas TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz, 7172f0984d40SFabiano Rosas gen_helper_sve2_fcvtnt_sh, a, 0, FPST_FPCR) 7173f0984d40SFabiano Rosas TRANS_FEAT(FCVTNT_ds, aa64_sve2, gen_gvec_fpst_arg_zpz, 7174f0984d40SFabiano Rosas gen_helper_sve2_fcvtnt_ds, a, 0, FPST_FPCR) 7175f0984d40SFabiano Rosas 7176f0984d40SFabiano Rosas TRANS_FEAT(BFCVTNT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, 7177f0984d40SFabiano Rosas gen_helper_sve_bfcvtnt, a, 0, FPST_FPCR) 7178f0984d40SFabiano Rosas 7179f0984d40SFabiano Rosas TRANS_FEAT(FCVTLT_hs, aa64_sve2, gen_gvec_fpst_arg_zpz, 7180f0984d40SFabiano Rosas gen_helper_sve2_fcvtlt_hs, a, 0, FPST_FPCR) 7181f0984d40SFabiano Rosas TRANS_FEAT(FCVTLT_sd, aa64_sve2, gen_gvec_fpst_arg_zpz, 7182f0984d40SFabiano Rosas gen_helper_sve2_fcvtlt_sd, a, 0, FPST_FPCR) 7183f0984d40SFabiano Rosas 7184f0984d40SFabiano Rosas TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a, 718597584f2bSRichard Henderson FPROUNDING_ODD, gen_helper_sve_fcvt_ds) 7186f0984d40SFabiano Rosas TRANS_FEAT(FCVTXNT_ds, aa64_sve2, do_frint_mode, a, 718797584f2bSRichard Henderson FPROUNDING_ODD, gen_helper_sve2_fcvtnt_ds) 7188f0984d40SFabiano Rosas 7189f0984d40SFabiano Rosas static gen_helper_gvec_3_ptr * const flogb_fns[] = { 7190f0984d40SFabiano Rosas NULL, gen_helper_flogb_h, 7191f0984d40SFabiano Rosas gen_helper_flogb_s, gen_helper_flogb_d 7192f0984d40SFabiano Rosas }; 7193f0984d40SFabiano Rosas TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, flogb_fns[a->esz], 7194f0984d40SFabiano Rosas a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) 7195f0984d40SFabiano Rosas 7196f0984d40SFabiano Rosas static bool do_FMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sub, bool sel) 7197f0984d40SFabiano Rosas { 7198f0984d40SFabiano Rosas return gen_gvec_ptr_zzzz(s, gen_helper_sve2_fmlal_zzzw_s, 7199f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, 7200*ad75a51eSRichard Henderson (sel << 1) | sub, tcg_env); 7201f0984d40SFabiano Rosas } 7202f0984d40SFabiano Rosas 7203f0984d40SFabiano Rosas TRANS_FEAT(FMLALB_zzzw, aa64_sve2, do_FMLAL_zzzw, a, false, false) 7204f0984d40SFabiano Rosas TRANS_FEAT(FMLALT_zzzw, aa64_sve2, do_FMLAL_zzzw, a, false, true) 7205f0984d40SFabiano Rosas TRANS_FEAT(FMLSLB_zzzw, aa64_sve2, do_FMLAL_zzzw, a, true, false) 7206f0984d40SFabiano Rosas TRANS_FEAT(FMLSLT_zzzw, aa64_sve2, do_FMLAL_zzzw, a, true, true) 7207f0984d40SFabiano Rosas 7208f0984d40SFabiano Rosas static bool do_FMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sub, bool sel) 7209f0984d40SFabiano Rosas { 7210f0984d40SFabiano Rosas return gen_gvec_ptr_zzzz(s, gen_helper_sve2_fmlal_zzxw_s, 7211f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, 7212*ad75a51eSRichard Henderson (a->index << 2) | (sel << 1) | sub, tcg_env); 7213f0984d40SFabiano Rosas } 7214f0984d40SFabiano Rosas 7215f0984d40SFabiano Rosas TRANS_FEAT(FMLALB_zzxw, aa64_sve2, do_FMLAL_zzxw, a, false, false) 7216f0984d40SFabiano Rosas TRANS_FEAT(FMLALT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, false, true) 7217f0984d40SFabiano Rosas TRANS_FEAT(FMLSLB_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, false) 7218f0984d40SFabiano Rosas TRANS_FEAT(FMLSLT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, true) 7219f0984d40SFabiano Rosas 7220f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(SMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz, 7221f0984d40SFabiano Rosas gen_helper_gvec_smmla_b, a, 0) 7222f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(USMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz, 7223f0984d40SFabiano Rosas gen_helper_gvec_usmmla_b, a, 0) 7224f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(UMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz, 7225f0984d40SFabiano Rosas gen_helper_gvec_ummla_b, a, 0) 7226f0984d40SFabiano Rosas 7227f0984d40SFabiano Rosas TRANS_FEAT(BFDOT_zzzz, aa64_sve_bf16, gen_gvec_ool_arg_zzzz, 7228f0984d40SFabiano Rosas gen_helper_gvec_bfdot, a, 0) 7229f0984d40SFabiano Rosas TRANS_FEAT(BFDOT_zzxz, aa64_sve_bf16, gen_gvec_ool_arg_zzxz, 7230f0984d40SFabiano Rosas gen_helper_gvec_bfdot_idx, a) 7231f0984d40SFabiano Rosas 7232f0984d40SFabiano Rosas TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_ool_arg_zzzz, 7233f0984d40SFabiano Rosas gen_helper_gvec_bfmmla, a, 0) 7234f0984d40SFabiano Rosas 7235f0984d40SFabiano Rosas static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel) 7236f0984d40SFabiano Rosas { 7237f0984d40SFabiano Rosas return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal, 7238f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, sel, FPST_FPCR); 7239f0984d40SFabiano Rosas } 7240f0984d40SFabiano Rosas 7241f0984d40SFabiano Rosas TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false) 7242f0984d40SFabiano Rosas TRANS_FEAT(BFMLALT_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, true) 7243f0984d40SFabiano Rosas 7244f0984d40SFabiano Rosas static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel) 7245f0984d40SFabiano Rosas { 7246f0984d40SFabiano Rosas return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal_idx, 7247f0984d40SFabiano Rosas a->rd, a->rn, a->rm, a->ra, 7248f0984d40SFabiano Rosas (a->index << 1) | sel, FPST_FPCR); 7249f0984d40SFabiano Rosas } 7250f0984d40SFabiano Rosas 7251f0984d40SFabiano Rosas TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false) 7252f0984d40SFabiano Rosas TRANS_FEAT(BFMLALT_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, true) 7253f0984d40SFabiano Rosas 7254f0984d40SFabiano Rosas static bool trans_PSEL(DisasContext *s, arg_psel *a) 7255f0984d40SFabiano Rosas { 7256f0984d40SFabiano Rosas int vl = vec_full_reg_size(s); 7257f0984d40SFabiano Rosas int pl = pred_gvec_reg_size(s); 7258f0984d40SFabiano Rosas int elements = vl >> a->esz; 7259f0984d40SFabiano Rosas TCGv_i64 tmp, didx, dbit; 7260f0984d40SFabiano Rosas TCGv_ptr ptr; 7261f0984d40SFabiano Rosas 7262f0984d40SFabiano Rosas if (!dc_isar_feature(aa64_sme, s)) { 7263f0984d40SFabiano Rosas return false; 7264f0984d40SFabiano Rosas } 7265f0984d40SFabiano Rosas if (!sve_access_check(s)) { 7266f0984d40SFabiano Rosas return true; 7267f0984d40SFabiano Rosas } 7268f0984d40SFabiano Rosas 7269f0984d40SFabiano Rosas tmp = tcg_temp_new_i64(); 7270f0984d40SFabiano Rosas dbit = tcg_temp_new_i64(); 7271f0984d40SFabiano Rosas didx = tcg_temp_new_i64(); 7272f0984d40SFabiano Rosas ptr = tcg_temp_new_ptr(); 7273f0984d40SFabiano Rosas 7274f0984d40SFabiano Rosas /* Compute the predicate element. */ 7275f0984d40SFabiano Rosas tcg_gen_addi_i64(tmp, cpu_reg(s, a->rv), a->imm); 7276f0984d40SFabiano Rosas if (is_power_of_2(elements)) { 7277f0984d40SFabiano Rosas tcg_gen_andi_i64(tmp, tmp, elements - 1); 7278f0984d40SFabiano Rosas } else { 7279f0984d40SFabiano Rosas tcg_gen_remu_i64(tmp, tmp, tcg_constant_i64(elements)); 7280f0984d40SFabiano Rosas } 7281f0984d40SFabiano Rosas 7282f0984d40SFabiano Rosas /* Extract the predicate byte and bit indices. */ 7283f0984d40SFabiano Rosas tcg_gen_shli_i64(tmp, tmp, a->esz); 7284f0984d40SFabiano Rosas tcg_gen_andi_i64(dbit, tmp, 7); 7285f0984d40SFabiano Rosas tcg_gen_shri_i64(didx, tmp, 3); 7286f0984d40SFabiano Rosas if (HOST_BIG_ENDIAN) { 7287f0984d40SFabiano Rosas tcg_gen_xori_i64(didx, didx, 7); 7288f0984d40SFabiano Rosas } 7289f0984d40SFabiano Rosas 7290f0984d40SFabiano Rosas /* Load the predicate word. */ 7291f0984d40SFabiano Rosas tcg_gen_trunc_i64_ptr(ptr, didx); 7292*ad75a51eSRichard Henderson tcg_gen_add_ptr(ptr, ptr, tcg_env); 7293f0984d40SFabiano Rosas tcg_gen_ld8u_i64(tmp, ptr, pred_full_reg_offset(s, a->pm)); 7294f0984d40SFabiano Rosas 7295f0984d40SFabiano Rosas /* Extract the predicate bit and replicate to MO_64. */ 7296f0984d40SFabiano Rosas tcg_gen_shr_i64(tmp, tmp, dbit); 7297f0984d40SFabiano Rosas tcg_gen_andi_i64(tmp, tmp, 1); 7298f0984d40SFabiano Rosas tcg_gen_neg_i64(tmp, tmp); 7299f0984d40SFabiano Rosas 7300f0984d40SFabiano Rosas /* Apply to either copy the source, or write zeros. */ 7301f0984d40SFabiano Rosas tcg_gen_gvec_ands(MO_64, pred_full_reg_offset(s, a->pd), 7302f0984d40SFabiano Rosas pred_full_reg_offset(s, a->pn), tmp, pl, pl); 7303f0984d40SFabiano Rosas return true; 7304f0984d40SFabiano Rosas } 7305f0984d40SFabiano Rosas 7306f0984d40SFabiano Rosas static void gen_sclamp_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_i32 a) 7307f0984d40SFabiano Rosas { 7308f0984d40SFabiano Rosas tcg_gen_smax_i32(d, a, n); 7309f0984d40SFabiano Rosas tcg_gen_smin_i32(d, d, m); 7310f0984d40SFabiano Rosas } 7311f0984d40SFabiano Rosas 7312f0984d40SFabiano Rosas static void gen_sclamp_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 a) 7313f0984d40SFabiano Rosas { 7314f0984d40SFabiano Rosas tcg_gen_smax_i64(d, a, n); 7315f0984d40SFabiano Rosas tcg_gen_smin_i64(d, d, m); 7316f0984d40SFabiano Rosas } 7317f0984d40SFabiano Rosas 7318f0984d40SFabiano Rosas static void gen_sclamp_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 7319f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec a) 7320f0984d40SFabiano Rosas { 7321f0984d40SFabiano Rosas tcg_gen_smax_vec(vece, d, a, n); 7322f0984d40SFabiano Rosas tcg_gen_smin_vec(vece, d, d, m); 7323f0984d40SFabiano Rosas } 7324f0984d40SFabiano Rosas 7325f0984d40SFabiano Rosas static void gen_sclamp(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 7326f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 7327f0984d40SFabiano Rosas { 7328f0984d40SFabiano Rosas static const TCGOpcode vecop[] = { 7329f0984d40SFabiano Rosas INDEX_op_smin_vec, INDEX_op_smax_vec, 0 7330f0984d40SFabiano Rosas }; 7331f0984d40SFabiano Rosas static const GVecGen4 ops[4] = { 7332f0984d40SFabiano Rosas { .fniv = gen_sclamp_vec, 7333f0984d40SFabiano Rosas .fno = gen_helper_gvec_sclamp_b, 7334f0984d40SFabiano Rosas .opt_opc = vecop, 7335f0984d40SFabiano Rosas .vece = MO_8 }, 7336f0984d40SFabiano Rosas { .fniv = gen_sclamp_vec, 7337f0984d40SFabiano Rosas .fno = gen_helper_gvec_sclamp_h, 7338f0984d40SFabiano Rosas .opt_opc = vecop, 7339f0984d40SFabiano Rosas .vece = MO_16 }, 7340f0984d40SFabiano Rosas { .fni4 = gen_sclamp_i32, 7341f0984d40SFabiano Rosas .fniv = gen_sclamp_vec, 7342f0984d40SFabiano Rosas .fno = gen_helper_gvec_sclamp_s, 7343f0984d40SFabiano Rosas .opt_opc = vecop, 7344f0984d40SFabiano Rosas .vece = MO_32 }, 7345f0984d40SFabiano Rosas { .fni8 = gen_sclamp_i64, 7346f0984d40SFabiano Rosas .fniv = gen_sclamp_vec, 7347f0984d40SFabiano Rosas .fno = gen_helper_gvec_sclamp_d, 7348f0984d40SFabiano Rosas .opt_opc = vecop, 7349f0984d40SFabiano Rosas .vece = MO_64, 7350f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64 } 7351f0984d40SFabiano Rosas }; 7352f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &ops[vece]); 7353f0984d40SFabiano Rosas } 7354f0984d40SFabiano Rosas 7355f0984d40SFabiano Rosas TRANS_FEAT(SCLAMP, aa64_sme, gen_gvec_fn_arg_zzzz, gen_sclamp, a) 7356f0984d40SFabiano Rosas 7357f0984d40SFabiano Rosas static void gen_uclamp_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_i32 a) 7358f0984d40SFabiano Rosas { 7359f0984d40SFabiano Rosas tcg_gen_umax_i32(d, a, n); 7360f0984d40SFabiano Rosas tcg_gen_umin_i32(d, d, m); 7361f0984d40SFabiano Rosas } 7362f0984d40SFabiano Rosas 7363f0984d40SFabiano Rosas static void gen_uclamp_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 a) 7364f0984d40SFabiano Rosas { 7365f0984d40SFabiano Rosas tcg_gen_umax_i64(d, a, n); 7366f0984d40SFabiano Rosas tcg_gen_umin_i64(d, d, m); 7367f0984d40SFabiano Rosas } 7368f0984d40SFabiano Rosas 7369f0984d40SFabiano Rosas static void gen_uclamp_vec(unsigned vece, TCGv_vec d, TCGv_vec n, 7370f0984d40SFabiano Rosas TCGv_vec m, TCGv_vec a) 7371f0984d40SFabiano Rosas { 7372f0984d40SFabiano Rosas tcg_gen_umax_vec(vece, d, a, n); 7373f0984d40SFabiano Rosas tcg_gen_umin_vec(vece, d, d, m); 7374f0984d40SFabiano Rosas } 7375f0984d40SFabiano Rosas 7376f0984d40SFabiano Rosas static void gen_uclamp(unsigned vece, uint32_t d, uint32_t n, uint32_t m, 7377f0984d40SFabiano Rosas uint32_t a, uint32_t oprsz, uint32_t maxsz) 7378f0984d40SFabiano Rosas { 7379f0984d40SFabiano Rosas static const TCGOpcode vecop[] = { 7380f0984d40SFabiano Rosas INDEX_op_umin_vec, INDEX_op_umax_vec, 0 7381f0984d40SFabiano Rosas }; 7382f0984d40SFabiano Rosas static const GVecGen4 ops[4] = { 7383f0984d40SFabiano Rosas { .fniv = gen_uclamp_vec, 7384f0984d40SFabiano Rosas .fno = gen_helper_gvec_uclamp_b, 7385f0984d40SFabiano Rosas .opt_opc = vecop, 7386f0984d40SFabiano Rosas .vece = MO_8 }, 7387f0984d40SFabiano Rosas { .fniv = gen_uclamp_vec, 7388f0984d40SFabiano Rosas .fno = gen_helper_gvec_uclamp_h, 7389f0984d40SFabiano Rosas .opt_opc = vecop, 7390f0984d40SFabiano Rosas .vece = MO_16 }, 7391f0984d40SFabiano Rosas { .fni4 = gen_uclamp_i32, 7392f0984d40SFabiano Rosas .fniv = gen_uclamp_vec, 7393f0984d40SFabiano Rosas .fno = gen_helper_gvec_uclamp_s, 7394f0984d40SFabiano Rosas .opt_opc = vecop, 7395f0984d40SFabiano Rosas .vece = MO_32 }, 7396f0984d40SFabiano Rosas { .fni8 = gen_uclamp_i64, 7397f0984d40SFabiano Rosas .fniv = gen_uclamp_vec, 7398f0984d40SFabiano Rosas .fno = gen_helper_gvec_uclamp_d, 7399f0984d40SFabiano Rosas .opt_opc = vecop, 7400f0984d40SFabiano Rosas .vece = MO_64, 7401f0984d40SFabiano Rosas .prefer_i64 = TCG_TARGET_REG_BITS == 64 } 7402f0984d40SFabiano Rosas }; 7403f0984d40SFabiano Rosas tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &ops[vece]); 7404f0984d40SFabiano Rosas } 7405f0984d40SFabiano Rosas 7406f0984d40SFabiano Rosas TRANS_FEAT(UCLAMP, aa64_sme, gen_gvec_fn_arg_zzzz, gen_uclamp, a) 7407