qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

trans_rvb.c.inc (15990B)


      1 /*
      2  * RISC-V translation routines for the Zb[abcs] and Zbk[bcx] Standard Extension.
      3  *
      4  * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com
      5  * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com
      6  * Copyright (c) 2021 Philipp Tomsich, philipp.tomsich@vrull.eu
      7  *
      8  * This program is free software; you can redistribute it and/or modify it
      9  * under the terms and conditions of the GNU General Public License,
     10  * version 2 or later, as published by the Free Software Foundation.
     11  *
     12  * This program is distributed in the hope it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along with
     18  * this program.  If not, see <http://www.gnu.org/licenses/>.
     19  */
     20 
     21 #define REQUIRE_ZBA(ctx) do {                    \
     22     if (!ctx->cfg_ptr->ext_zba) {                \
     23         return false;                            \
     24     }                                            \
     25 } while (0)
     26 
     27 #define REQUIRE_ZBB(ctx) do {                    \
     28     if (!ctx->cfg_ptr->ext_zbb) {                \
     29         return false;                            \
     30     }                                            \
     31 } while (0)
     32 
     33 #define REQUIRE_ZBC(ctx) do {                    \
     34     if (!ctx->cfg_ptr->ext_zbc) {                \
     35         return false;                            \
     36     }                                            \
     37 } while (0)
     38 
     39 #define REQUIRE_ZBS(ctx) do {                    \
     40     if (!ctx->cfg_ptr->ext_zbs) {                \
     41         return false;                            \
     42     }                                            \
     43 } while (0)
     44 
     45 #define REQUIRE_ZBKB(ctx) do {                   \
     46     if (!ctx->cfg_ptr->ext_zbkb) {               \
     47         return false;                            \
     48     }                                            \
     49 } while (0)
     50 
     51 #define REQUIRE_ZBKX(ctx) do {                   \
     52     if (!ctx->cfg_ptr->ext_zbkx) {               \
     53         return false;                            \
     54     }                                            \
     55 } while (0)
     56 
     57 static void gen_clz(TCGv ret, TCGv arg1)
     58 {
     59     tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
     60 }
     61 
     62 static void gen_clzw(TCGv ret, TCGv arg1)
     63 {
     64     TCGv t = tcg_temp_new();
     65     tcg_gen_shli_tl(t, arg1, 32);
     66     tcg_gen_clzi_tl(ret, t, 32);
     67     tcg_temp_free(t);
     68 }
     69 
     70 static bool trans_clz(DisasContext *ctx, arg_clz *a)
     71 {
     72     REQUIRE_ZBB(ctx);
     73     return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw);
     74 }
     75 
     76 static void gen_ctz(TCGv ret, TCGv arg1)
     77 {
     78     tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
     79 }
     80 
     81 static void gen_ctzw(TCGv ret, TCGv arg1)
     82 {
     83     tcg_gen_ctzi_tl(ret, arg1, 32);
     84 }
     85 
     86 static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
     87 {
     88     REQUIRE_ZBB(ctx);
     89     return gen_unary_per_ol(ctx, a, EXT_ZERO, gen_ctz, gen_ctzw);
     90 }
     91 
     92 static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
     93 {
     94     REQUIRE_ZBB(ctx);
     95     return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
     96 }
     97 
     98 static bool trans_andn(DisasContext *ctx, arg_andn *a)
     99 {
    100     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    101     return gen_logic(ctx, a, tcg_gen_andc_tl);
    102 }
    103 
    104 static bool trans_orn(DisasContext *ctx, arg_orn *a)
    105 {
    106     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    107     return gen_logic(ctx, a, tcg_gen_orc_tl);
    108 }
    109 
    110 static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
    111 {
    112     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    113     return gen_logic(ctx, a, tcg_gen_eqv_tl);
    114 }
    115 
    116 static bool trans_min(DisasContext *ctx, arg_min *a)
    117 {
    118     REQUIRE_ZBB(ctx);
    119     return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smin_tl, NULL);
    120 }
    121 
    122 static bool trans_max(DisasContext *ctx, arg_max *a)
    123 {
    124     REQUIRE_ZBB(ctx);
    125     return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smax_tl, NULL);
    126 }
    127 
    128 static bool trans_minu(DisasContext *ctx, arg_minu *a)
    129 {
    130     REQUIRE_ZBB(ctx);
    131     return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umin_tl, NULL);
    132 }
    133 
    134 static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
    135 {
    136     REQUIRE_ZBB(ctx);
    137     return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umax_tl, NULL);
    138 }
    139 
    140 static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a)
    141 {
    142     REQUIRE_ZBB(ctx);
    143     return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
    144 }
    145 
    146 static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
    147 {
    148     REQUIRE_ZBB(ctx);
    149     return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
    150 }
    151 
    152 static void gen_sbop_mask(TCGv ret, TCGv shamt)
    153 {
    154     tcg_gen_movi_tl(ret, 1);
    155     tcg_gen_shl_tl(ret, ret, shamt);
    156 }
    157 
    158 static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
    159 {
    160     TCGv t = tcg_temp_new();
    161 
    162     gen_sbop_mask(t, shamt);
    163     tcg_gen_or_tl(ret, arg1, t);
    164 
    165     tcg_temp_free(t);
    166 }
    167 
    168 static bool trans_bset(DisasContext *ctx, arg_bset *a)
    169 {
    170     REQUIRE_ZBS(ctx);
    171     return gen_shift(ctx, a, EXT_NONE, gen_bset, NULL);
    172 }
    173 
    174 static bool trans_bseti(DisasContext *ctx, arg_bseti *a)
    175 {
    176     REQUIRE_ZBS(ctx);
    177     return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bset);
    178 }
    179 
    180 static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
    181 {
    182     TCGv t = tcg_temp_new();
    183 
    184     gen_sbop_mask(t, shamt);
    185     tcg_gen_andc_tl(ret, arg1, t);
    186 
    187     tcg_temp_free(t);
    188 }
    189 
    190 static bool trans_bclr(DisasContext *ctx, arg_bclr *a)
    191 {
    192     REQUIRE_ZBS(ctx);
    193     return gen_shift(ctx, a, EXT_NONE, gen_bclr, NULL);
    194 }
    195 
    196 static bool trans_bclri(DisasContext *ctx, arg_bclri *a)
    197 {
    198     REQUIRE_ZBS(ctx);
    199     return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bclr);
    200 }
    201 
    202 static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
    203 {
    204     TCGv t = tcg_temp_new();
    205 
    206     gen_sbop_mask(t, shamt);
    207     tcg_gen_xor_tl(ret, arg1, t);
    208 
    209     tcg_temp_free(t);
    210 }
    211 
    212 static bool trans_binv(DisasContext *ctx, arg_binv *a)
    213 {
    214     REQUIRE_ZBS(ctx);
    215     return gen_shift(ctx, a, EXT_NONE, gen_binv, NULL);
    216 }
    217 
    218 static bool trans_binvi(DisasContext *ctx, arg_binvi *a)
    219 {
    220     REQUIRE_ZBS(ctx);
    221     return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_binv);
    222 }
    223 
    224 static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
    225 {
    226     tcg_gen_shr_tl(ret, arg1, shamt);
    227     tcg_gen_andi_tl(ret, ret, 1);
    228 }
    229 
    230 static bool trans_bext(DisasContext *ctx, arg_bext *a)
    231 {
    232     REQUIRE_ZBS(ctx);
    233     return gen_shift(ctx, a, EXT_NONE, gen_bext, NULL);
    234 }
    235 
    236 static bool trans_bexti(DisasContext *ctx, arg_bexti *a)
    237 {
    238     REQUIRE_ZBS(ctx);
    239     return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
    240 }
    241 
    242 static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
    243 {
    244     TCGv_i32 t1 = tcg_temp_new_i32();
    245     TCGv_i32 t2 = tcg_temp_new_i32();
    246 
    247     /* truncate to 32-bits */
    248     tcg_gen_trunc_tl_i32(t1, arg1);
    249     tcg_gen_trunc_tl_i32(t2, arg2);
    250 
    251     tcg_gen_rotr_i32(t1, t1, t2);
    252 
    253     /* sign-extend 64-bits */
    254     tcg_gen_ext_i32_tl(ret, t1);
    255 
    256     tcg_temp_free_i32(t1);
    257     tcg_temp_free_i32(t2);
    258 }
    259 
    260 static bool trans_ror(DisasContext *ctx, arg_ror *a)
    261 {
    262     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    263     return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw, NULL);
    264 }
    265 
    266 static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt)
    267 {
    268     TCGv_i32 t1 = tcg_temp_new_i32();
    269 
    270     tcg_gen_trunc_tl_i32(t1, arg1);
    271     tcg_gen_rotri_i32(t1, t1, shamt);
    272     tcg_gen_ext_i32_tl(ret, t1);
    273 
    274     tcg_temp_free_i32(t1);
    275 }
    276 
    277 static bool trans_rori(DisasContext *ctx, arg_rori *a)
    278 {
    279     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    280     return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
    281                                    tcg_gen_rotri_tl, gen_roriw, NULL);
    282 }
    283 
    284 static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
    285 {
    286     TCGv_i32 t1 = tcg_temp_new_i32();
    287     TCGv_i32 t2 = tcg_temp_new_i32();
    288 
    289     /* truncate to 32-bits */
    290     tcg_gen_trunc_tl_i32(t1, arg1);
    291     tcg_gen_trunc_tl_i32(t2, arg2);
    292 
    293     tcg_gen_rotl_i32(t1, t1, t2);
    294 
    295     /* sign-extend 64-bits */
    296     tcg_gen_ext_i32_tl(ret, t1);
    297 
    298     tcg_temp_free_i32(t1);
    299     tcg_temp_free_i32(t2);
    300 }
    301 
    302 static bool trans_rol(DisasContext *ctx, arg_rol *a)
    303 {
    304     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    305     return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw, NULL);
    306 }
    307 
    308 static void gen_rev8_32(TCGv ret, TCGv src1)
    309 {
    310     tcg_gen_bswap32_tl(ret, src1, TCG_BSWAP_OS);
    311 }
    312 
    313 static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 *a)
    314 {
    315     REQUIRE_32BIT(ctx);
    316     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    317     return gen_unary(ctx, a, EXT_NONE, gen_rev8_32);
    318 }
    319 
    320 static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a)
    321 {
    322     REQUIRE_64BIT(ctx);
    323     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    324     return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl);
    325 }
    326 
    327 static void gen_orc_b(TCGv ret, TCGv source1)
    328 {
    329     TCGv  tmp = tcg_temp_new();
    330     TCGv  low7 = tcg_constant_tl(dup_const_tl(MO_8, 0x7f));
    331 
    332     /* Set msb in each byte if the byte was non-zero. */
    333     tcg_gen_and_tl(tmp, source1, low7);
    334     tcg_gen_add_tl(tmp, tmp, low7);
    335     tcg_gen_or_tl(tmp, tmp, source1);
    336 
    337     /* Extract the msb to the lsb in each byte */
    338     tcg_gen_andc_tl(tmp, tmp, low7);
    339     tcg_gen_shri_tl(tmp, tmp, 7);
    340 
    341     /* Replicate the lsb of each byte across the byte. */
    342     tcg_gen_muli_tl(ret, tmp, 0xff);
    343 
    344     tcg_temp_free(tmp);
    345 }
    346 
    347 static bool trans_orc_b(DisasContext *ctx, arg_orc_b *a)
    348 {
    349     REQUIRE_ZBB(ctx);
    350     return gen_unary(ctx, a, EXT_ZERO, gen_orc_b);
    351 }
    352 
    353 #define GEN_SHADD(SHAMT)                                       \
    354 static void gen_sh##SHAMT##add(TCGv ret, TCGv arg1, TCGv arg2) \
    355 {                                                              \
    356     TCGv t = tcg_temp_new();                                   \
    357                                                                \
    358     tcg_gen_shli_tl(t, arg1, SHAMT);                           \
    359     tcg_gen_add_tl(ret, t, arg2);                              \
    360                                                                \
    361     tcg_temp_free(t);                                          \
    362 }
    363 
    364 GEN_SHADD(1)
    365 GEN_SHADD(2)
    366 GEN_SHADD(3)
    367 
    368 #define GEN_TRANS_SHADD(SHAMT)                                             \
    369 static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \
    370 {                                                                          \
    371     REQUIRE_ZBA(ctx);                                                      \
    372     return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add, NULL);          \
    373 }
    374 
    375 GEN_TRANS_SHADD(1)
    376 GEN_TRANS_SHADD(2)
    377 GEN_TRANS_SHADD(3)
    378 
    379 static bool trans_zext_h_32(DisasContext *ctx, arg_zext_h_32 *a)
    380 {
    381     REQUIRE_32BIT(ctx);
    382     REQUIRE_ZBB(ctx);
    383     return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
    384 }
    385 
    386 static bool trans_zext_h_64(DisasContext *ctx, arg_zext_h_64 *a)
    387 {
    388     REQUIRE_64BIT(ctx);
    389     REQUIRE_ZBB(ctx);
    390     return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
    391 }
    392 
    393 static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
    394 {
    395     REQUIRE_64BIT(ctx);
    396     REQUIRE_ZBB(ctx);
    397     return gen_unary(ctx, a, EXT_NONE, gen_clzw);
    398 }
    399 
    400 static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
    401 {
    402     REQUIRE_64BIT(ctx);
    403     REQUIRE_ZBB(ctx);
    404     return gen_unary(ctx, a, EXT_ZERO, gen_ctzw);
    405 }
    406 
    407 static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
    408 {
    409     REQUIRE_64BIT(ctx);
    410     REQUIRE_ZBB(ctx);
    411     ctx->ol = MXL_RV32;
    412     return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
    413 }
    414 
    415 static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
    416 {
    417     REQUIRE_64BIT(ctx);
    418     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    419     ctx->ol = MXL_RV32;
    420     return gen_shift(ctx, a, EXT_NONE, gen_rorw, NULL);
    421 }
    422 
    423 static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
    424 {
    425     REQUIRE_64BIT(ctx);
    426     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    427     ctx->ol = MXL_RV32;
    428     return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
    429 }
    430 
    431 static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
    432 {
    433     REQUIRE_64BIT(ctx);
    434     REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    435     ctx->ol = MXL_RV32;
    436     return gen_shift(ctx, a, EXT_NONE, gen_rolw, NULL);
    437 }
    438 
    439 #define GEN_SHADD_UW(SHAMT)                                       \
    440 static void gen_sh##SHAMT##add_uw(TCGv ret, TCGv arg1, TCGv arg2) \
    441 {                                                                 \
    442     TCGv t = tcg_temp_new();                                      \
    443                                                                   \
    444     tcg_gen_ext32u_tl(t, arg1);                                   \
    445                                                                   \
    446     tcg_gen_shli_tl(t, t, SHAMT);                                 \
    447     tcg_gen_add_tl(ret, t, arg2);                                 \
    448                                                                   \
    449     tcg_temp_free(t);                                             \
    450 }
    451 
    452 GEN_SHADD_UW(1)
    453 GEN_SHADD_UW(2)
    454 GEN_SHADD_UW(3)
    455 
    456 #define GEN_TRANS_SHADD_UW(SHAMT)                             \
    457 static bool trans_sh##SHAMT##add_uw(DisasContext *ctx,        \
    458                                     arg_sh##SHAMT##add_uw *a) \
    459 {                                                             \
    460     REQUIRE_64BIT(ctx);                                       \
    461     REQUIRE_ZBA(ctx);                                         \
    462     return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add_uw, NULL); \
    463 }
    464 
    465 GEN_TRANS_SHADD_UW(1)
    466 GEN_TRANS_SHADD_UW(2)
    467 GEN_TRANS_SHADD_UW(3)
    468 
    469 static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
    470 {
    471     TCGv t = tcg_temp_new();
    472     tcg_gen_ext32u_tl(t, arg1);
    473     tcg_gen_add_tl(ret, t, arg2);
    474     tcg_temp_free(t);
    475 }
    476 
    477 static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a)
    478 {
    479     REQUIRE_64BIT(ctx);
    480     REQUIRE_ZBA(ctx);
    481     return gen_arith(ctx, a, EXT_NONE, gen_add_uw, NULL);
    482 }
    483 
    484 static void gen_slli_uw(TCGv dest, TCGv src, target_long shamt)
    485 {
    486     tcg_gen_deposit_z_tl(dest, src, shamt, MIN(32, TARGET_LONG_BITS - shamt));
    487 }
    488 
    489 static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
    490 {
    491     REQUIRE_64BIT(ctx);
    492     REQUIRE_ZBA(ctx);
    493     return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_slli_uw, NULL);
    494 }
    495 
    496 static bool trans_clmul(DisasContext *ctx, arg_clmul *a)
    497 {
    498     REQUIRE_EITHER_EXT(ctx, zbc, zbkc);
    499     return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul, NULL);
    500 }
    501 
    502 static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2)
    503 {
    504      gen_helper_clmulr(dst, src1, src2);
    505      tcg_gen_shri_tl(dst, dst, 1);
    506 }
    507 
    508 static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a)
    509 {
    510     REQUIRE_EITHER_EXT(ctx, zbc, zbkc);
    511     return gen_arith(ctx, a, EXT_NONE, gen_clmulh, NULL);
    512 }
    513 
    514 static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a)
    515 {
    516     REQUIRE_ZBC(ctx);
    517     return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr, NULL);
    518 }
    519 
    520 static void gen_pack(TCGv ret, TCGv src1, TCGv src2)
    521 {
    522     tcg_gen_deposit_tl(ret, src1, src2,
    523                        TARGET_LONG_BITS / 2,
    524                        TARGET_LONG_BITS / 2);
    525 }
    526 
    527 static void gen_packh(TCGv ret, TCGv src1, TCGv src2)
    528 {
    529     TCGv t = tcg_temp_new();
    530 
    531     tcg_gen_ext8u_tl(t, src2);
    532     tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8);
    533     tcg_temp_free(t);
    534 }
    535 
    536 static void gen_packw(TCGv ret, TCGv src1, TCGv src2)
    537 {
    538     TCGv t = tcg_temp_new();
    539 
    540     tcg_gen_ext16s_tl(t, src2);
    541     tcg_gen_deposit_tl(ret, src1, t, 16, TARGET_LONG_BITS - 16);
    542     tcg_temp_free(t);
    543 }
    544 
    545 static bool trans_brev8(DisasContext *ctx, arg_brev8 *a)
    546 {
    547     REQUIRE_ZBKB(ctx);
    548     return gen_unary(ctx, a, EXT_NONE, gen_helper_brev8);
    549 }
    550 
    551 static bool trans_pack(DisasContext *ctx, arg_pack *a)
    552 {
    553     REQUIRE_ZBKB(ctx);
    554     return gen_arith(ctx, a, EXT_NONE, gen_pack, NULL);
    555 }
    556 
    557 static bool trans_packh(DisasContext *ctx, arg_packh *a)
    558 {
    559     REQUIRE_ZBKB(ctx);
    560     return gen_arith(ctx, a, EXT_NONE, gen_packh, NULL);
    561 }
    562 
    563 static bool trans_packw(DisasContext *ctx, arg_packw *a)
    564 {
    565     REQUIRE_64BIT(ctx);
    566     REQUIRE_ZBKB(ctx);
    567     return gen_arith(ctx, a, EXT_NONE, gen_packw, NULL);
    568 }
    569 
    570 static bool trans_unzip(DisasContext *ctx, arg_unzip *a)
    571 {
    572     REQUIRE_32BIT(ctx);
    573     REQUIRE_ZBKB(ctx);
    574     return gen_unary(ctx, a, EXT_NONE, gen_helper_unzip);
    575 }
    576 
    577 static bool trans_zip(DisasContext *ctx, arg_zip *a)
    578 {
    579     REQUIRE_32BIT(ctx);
    580     REQUIRE_ZBKB(ctx);
    581     return gen_unary(ctx, a, EXT_NONE, gen_helper_zip);
    582 }
    583 
    584 static bool trans_xperm4(DisasContext *ctx, arg_xperm4 *a)
    585 {
    586     REQUIRE_ZBKX(ctx);
    587     return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm4, NULL);
    588 }
    589 
    590 static bool trans_xperm8(DisasContext *ctx, arg_xperm8 *a)
    591 {
    592     REQUIRE_ZBKX(ctx);
    593     return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm8, NULL);
    594 }