qemu

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

tcg-op.c (105789B)


      1 /*
      2  * Tiny Code Generator for QEMU
      3  *
      4  * Copyright (c) 2008 Fabrice Bellard
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22  * THE SOFTWARE.
     23  */
     24 
     25 #include "qemu/osdep.h"
     26 #include "exec/exec-all.h"
     27 #include "tcg/tcg.h"
     28 #include "tcg/tcg-op.h"
     29 #include "tcg/tcg-mo.h"
     30 #include "exec/plugin-gen.h"
     31 
     32 /* Reduce the number of ifdefs below.  This assumes that all uses of
     33    TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
     34    the compiler can eliminate.  */
     35 #if TCG_TARGET_REG_BITS == 64
     36 extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64);
     37 extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64);
     38 #define TCGV_LOW  TCGV_LOW_link_error
     39 #define TCGV_HIGH TCGV_HIGH_link_error
     40 #endif
     41 
     42 void tcg_gen_op1(TCGOpcode opc, TCGArg a1)
     43 {
     44     TCGOp *op = tcg_emit_op(opc);
     45     op->args[0] = a1;
     46 }
     47 
     48 void tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
     49 {
     50     TCGOp *op = tcg_emit_op(opc);
     51     op->args[0] = a1;
     52     op->args[1] = a2;
     53 }
     54 
     55 void tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
     56 {
     57     TCGOp *op = tcg_emit_op(opc);
     58     op->args[0] = a1;
     59     op->args[1] = a2;
     60     op->args[2] = a3;
     61 }
     62 
     63 void tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, TCGArg a4)
     64 {
     65     TCGOp *op = tcg_emit_op(opc);
     66     op->args[0] = a1;
     67     op->args[1] = a2;
     68     op->args[2] = a3;
     69     op->args[3] = a4;
     70 }
     71 
     72 void tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
     73                  TCGArg a4, TCGArg a5)
     74 {
     75     TCGOp *op = tcg_emit_op(opc);
     76     op->args[0] = a1;
     77     op->args[1] = a2;
     78     op->args[2] = a3;
     79     op->args[3] = a4;
     80     op->args[4] = a5;
     81 }
     82 
     83 void tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
     84                  TCGArg a4, TCGArg a5, TCGArg a6)
     85 {
     86     TCGOp *op = tcg_emit_op(opc);
     87     op->args[0] = a1;
     88     op->args[1] = a2;
     89     op->args[2] = a3;
     90     op->args[3] = a4;
     91     op->args[4] = a5;
     92     op->args[5] = a6;
     93 }
     94 
     95 void tcg_gen_mb(TCGBar mb_type)
     96 {
     97     if (tcg_ctx->tb_cflags & CF_PARALLEL) {
     98         tcg_gen_op1(INDEX_op_mb, mb_type);
     99     }
    100 }
    101 
    102 /* 32 bit ops */
    103 
    104 void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
    105 {
    106     tcg_gen_mov_i32(ret, tcg_constant_i32(arg));
    107 }
    108 
    109 void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    110 {
    111     /* some cases can be optimized here */
    112     if (arg2 == 0) {
    113         tcg_gen_mov_i32(ret, arg1);
    114     } else {
    115         tcg_gen_add_i32(ret, arg1, tcg_constant_i32(arg2));
    116     }
    117 }
    118 
    119 void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
    120 {
    121     if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) {
    122         /* Don't recurse with tcg_gen_neg_i32.  */
    123         tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2);
    124     } else {
    125         tcg_gen_sub_i32(ret, tcg_constant_i32(arg1), arg2);
    126     }
    127 }
    128 
    129 void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    130 {
    131     /* some cases can be optimized here */
    132     if (arg2 == 0) {
    133         tcg_gen_mov_i32(ret, arg1);
    134     } else {
    135         tcg_gen_sub_i32(ret, arg1, tcg_constant_i32(arg2));
    136     }
    137 }
    138 
    139 void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    140 {
    141     /* Some cases can be optimized here.  */
    142     switch (arg2) {
    143     case 0:
    144         tcg_gen_movi_i32(ret, 0);
    145         return;
    146     case -1:
    147         tcg_gen_mov_i32(ret, arg1);
    148         return;
    149     case 0xff:
    150         /* Don't recurse with tcg_gen_ext8u_i32.  */
    151         if (TCG_TARGET_HAS_ext8u_i32) {
    152             tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
    153             return;
    154         }
    155         break;
    156     case 0xffff:
    157         if (TCG_TARGET_HAS_ext16u_i32) {
    158             tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
    159             return;
    160         }
    161         break;
    162     }
    163 
    164     tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2));
    165 }
    166 
    167 void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    168 {
    169     /* Some cases can be optimized here.  */
    170     if (arg2 == -1) {
    171         tcg_gen_movi_i32(ret, -1);
    172     } else if (arg2 == 0) {
    173         tcg_gen_mov_i32(ret, arg1);
    174     } else {
    175         tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2));
    176     }
    177 }
    178 
    179 void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    180 {
    181     /* Some cases can be optimized here.  */
    182     if (arg2 == 0) {
    183         tcg_gen_mov_i32(ret, arg1);
    184     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
    185         /* Don't recurse with tcg_gen_not_i32.  */
    186         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
    187     } else {
    188         tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2));
    189     }
    190 }
    191 
    192 void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    193 {
    194     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
    195     if (arg2 == 0) {
    196         tcg_gen_mov_i32(ret, arg1);
    197     } else {
    198         tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2));
    199     }
    200 }
    201 
    202 void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    203 {
    204     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
    205     if (arg2 == 0) {
    206         tcg_gen_mov_i32(ret, arg1);
    207     } else {
    208         tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2));
    209     }
    210 }
    211 
    212 void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    213 {
    214     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
    215     if (arg2 == 0) {
    216         tcg_gen_mov_i32(ret, arg1);
    217     } else {
    218         tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2));
    219     }
    220 }
    221 
    222 void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
    223 {
    224     if (cond == TCG_COND_ALWAYS) {
    225         tcg_gen_br(l);
    226     } else if (cond != TCG_COND_NEVER) {
    227         l->refs++;
    228         tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
    229     }
    230 }
    231 
    232 void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
    233 {
    234     if (cond == TCG_COND_ALWAYS) {
    235         tcg_gen_br(l);
    236     } else if (cond != TCG_COND_NEVER) {
    237         tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l);
    238     }
    239 }
    240 
    241 void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
    242                          TCGv_i32 arg1, TCGv_i32 arg2)
    243 {
    244     if (cond == TCG_COND_ALWAYS) {
    245         tcg_gen_movi_i32(ret, 1);
    246     } else if (cond == TCG_COND_NEVER) {
    247         tcg_gen_movi_i32(ret, 0);
    248     } else {
    249         tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
    250     }
    251 }
    252 
    253 void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
    254                           TCGv_i32 arg1, int32_t arg2)
    255 {
    256     tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
    257 }
    258 
    259 void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    260 {
    261     if (arg2 == 0) {
    262         tcg_gen_movi_i32(ret, 0);
    263     } else if (is_power_of_2(arg2)) {
    264         tcg_gen_shli_i32(ret, arg1, ctz32(arg2));
    265     } else {
    266         tcg_gen_mul_i32(ret, arg1, tcg_constant_i32(arg2));
    267     }
    268 }
    269 
    270 void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    271 {
    272     if (TCG_TARGET_HAS_div_i32) {
    273         tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
    274     } else if (TCG_TARGET_HAS_div2_i32) {
    275         TCGv_i32 t0 = tcg_temp_new_i32();
    276         tcg_gen_sari_i32(t0, arg1, 31);
    277         tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
    278         tcg_temp_free_i32(t0);
    279     } else {
    280         gen_helper_div_i32(ret, arg1, arg2);
    281     }
    282 }
    283 
    284 void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    285 {
    286     if (TCG_TARGET_HAS_rem_i32) {
    287         tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
    288     } else if (TCG_TARGET_HAS_div_i32) {
    289         TCGv_i32 t0 = tcg_temp_new_i32();
    290         tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
    291         tcg_gen_mul_i32(t0, t0, arg2);
    292         tcg_gen_sub_i32(ret, arg1, t0);
    293         tcg_temp_free_i32(t0);
    294     } else if (TCG_TARGET_HAS_div2_i32) {
    295         TCGv_i32 t0 = tcg_temp_new_i32();
    296         tcg_gen_sari_i32(t0, arg1, 31);
    297         tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
    298         tcg_temp_free_i32(t0);
    299     } else {
    300         gen_helper_rem_i32(ret, arg1, arg2);
    301     }
    302 }
    303 
    304 void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    305 {
    306     if (TCG_TARGET_HAS_div_i32) {
    307         tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
    308     } else if (TCG_TARGET_HAS_div2_i32) {
    309         TCGv_i32 t0 = tcg_temp_new_i32();
    310         tcg_gen_movi_i32(t0, 0);
    311         tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
    312         tcg_temp_free_i32(t0);
    313     } else {
    314         gen_helper_divu_i32(ret, arg1, arg2);
    315     }
    316 }
    317 
    318 void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    319 {
    320     if (TCG_TARGET_HAS_rem_i32) {
    321         tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
    322     } else if (TCG_TARGET_HAS_div_i32) {
    323         TCGv_i32 t0 = tcg_temp_new_i32();
    324         tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
    325         tcg_gen_mul_i32(t0, t0, arg2);
    326         tcg_gen_sub_i32(ret, arg1, t0);
    327         tcg_temp_free_i32(t0);
    328     } else if (TCG_TARGET_HAS_div2_i32) {
    329         TCGv_i32 t0 = tcg_temp_new_i32();
    330         tcg_gen_movi_i32(t0, 0);
    331         tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
    332         tcg_temp_free_i32(t0);
    333     } else {
    334         gen_helper_remu_i32(ret, arg1, arg2);
    335     }
    336 }
    337 
    338 void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    339 {
    340     if (TCG_TARGET_HAS_andc_i32) {
    341         tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
    342     } else {
    343         TCGv_i32 t0 = tcg_temp_new_i32();
    344         tcg_gen_not_i32(t0, arg2);
    345         tcg_gen_and_i32(ret, arg1, t0);
    346         tcg_temp_free_i32(t0);
    347     }
    348 }
    349 
    350 void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    351 {
    352     if (TCG_TARGET_HAS_eqv_i32) {
    353         tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
    354     } else {
    355         tcg_gen_xor_i32(ret, arg1, arg2);
    356         tcg_gen_not_i32(ret, ret);
    357     }
    358 }
    359 
    360 void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    361 {
    362     if (TCG_TARGET_HAS_nand_i32) {
    363         tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
    364     } else {
    365         tcg_gen_and_i32(ret, arg1, arg2);
    366         tcg_gen_not_i32(ret, ret);
    367     }
    368 }
    369 
    370 void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    371 {
    372     if (TCG_TARGET_HAS_nor_i32) {
    373         tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
    374     } else {
    375         tcg_gen_or_i32(ret, arg1, arg2);
    376         tcg_gen_not_i32(ret, ret);
    377     }
    378 }
    379 
    380 void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    381 {
    382     if (TCG_TARGET_HAS_orc_i32) {
    383         tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
    384     } else {
    385         TCGv_i32 t0 = tcg_temp_new_i32();
    386         tcg_gen_not_i32(t0, arg2);
    387         tcg_gen_or_i32(ret, arg1, t0);
    388         tcg_temp_free_i32(t0);
    389     }
    390 }
    391 
    392 void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    393 {
    394     if (TCG_TARGET_HAS_clz_i32) {
    395         tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
    396     } else if (TCG_TARGET_HAS_clz_i64) {
    397         TCGv_i64 t1 = tcg_temp_new_i64();
    398         TCGv_i64 t2 = tcg_temp_new_i64();
    399         tcg_gen_extu_i32_i64(t1, arg1);
    400         tcg_gen_extu_i32_i64(t2, arg2);
    401         tcg_gen_addi_i64(t2, t2, 32);
    402         tcg_gen_clz_i64(t1, t1, t2);
    403         tcg_gen_extrl_i64_i32(ret, t1);
    404         tcg_temp_free_i64(t1);
    405         tcg_temp_free_i64(t2);
    406         tcg_gen_subi_i32(ret, ret, 32);
    407     } else {
    408         gen_helper_clz_i32(ret, arg1, arg2);
    409     }
    410 }
    411 
    412 void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
    413 {
    414     tcg_gen_clz_i32(ret, arg1, tcg_constant_i32(arg2));
    415 }
    416 
    417 void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    418 {
    419     if (TCG_TARGET_HAS_ctz_i32) {
    420         tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
    421     } else if (TCG_TARGET_HAS_ctz_i64) {
    422         TCGv_i64 t1 = tcg_temp_new_i64();
    423         TCGv_i64 t2 = tcg_temp_new_i64();
    424         tcg_gen_extu_i32_i64(t1, arg1);
    425         tcg_gen_extu_i32_i64(t2, arg2);
    426         tcg_gen_ctz_i64(t1, t1, t2);
    427         tcg_gen_extrl_i64_i32(ret, t1);
    428         tcg_temp_free_i64(t1);
    429         tcg_temp_free_i64(t2);
    430     } else if (TCG_TARGET_HAS_ctpop_i32
    431                || TCG_TARGET_HAS_ctpop_i64
    432                || TCG_TARGET_HAS_clz_i32
    433                || TCG_TARGET_HAS_clz_i64) {
    434         TCGv_i32 z, t = tcg_temp_new_i32();
    435 
    436         if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
    437             tcg_gen_subi_i32(t, arg1, 1);
    438             tcg_gen_andc_i32(t, t, arg1);
    439             tcg_gen_ctpop_i32(t, t);
    440         } else {
    441             /* Since all non-x86 hosts have clz(0) == 32, don't fight it.  */
    442             tcg_gen_neg_i32(t, arg1);
    443             tcg_gen_and_i32(t, t, arg1);
    444             tcg_gen_clzi_i32(t, t, 32);
    445             tcg_gen_xori_i32(t, t, 31);
    446         }
    447         z = tcg_constant_i32(0);
    448         tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t);
    449         tcg_temp_free_i32(t);
    450     } else {
    451         gen_helper_ctz_i32(ret, arg1, arg2);
    452     }
    453 }
    454 
    455 void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
    456 {
    457     if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
    458         /* This equivalence has the advantage of not requiring a fixup.  */
    459         TCGv_i32 t = tcg_temp_new_i32();
    460         tcg_gen_subi_i32(t, arg1, 1);
    461         tcg_gen_andc_i32(t, t, arg1);
    462         tcg_gen_ctpop_i32(ret, t);
    463         tcg_temp_free_i32(t);
    464     } else {
    465         tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2));
    466     }
    467 }
    468 
    469 void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
    470 {
    471     if (TCG_TARGET_HAS_clz_i32) {
    472         TCGv_i32 t = tcg_temp_new_i32();
    473         tcg_gen_sari_i32(t, arg, 31);
    474         tcg_gen_xor_i32(t, t, arg);
    475         tcg_gen_clzi_i32(t, t, 32);
    476         tcg_gen_subi_i32(ret, t, 1);
    477         tcg_temp_free_i32(t);
    478     } else {
    479         gen_helper_clrsb_i32(ret, arg);
    480     }
    481 }
    482 
    483 void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
    484 {
    485     if (TCG_TARGET_HAS_ctpop_i32) {
    486         tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
    487     } else if (TCG_TARGET_HAS_ctpop_i64) {
    488         TCGv_i64 t = tcg_temp_new_i64();
    489         tcg_gen_extu_i32_i64(t, arg1);
    490         tcg_gen_ctpop_i64(t, t);
    491         tcg_gen_extrl_i64_i32(ret, t);
    492         tcg_temp_free_i64(t);
    493     } else {
    494         gen_helper_ctpop_i32(ret, arg1);
    495     }
    496 }
    497 
    498 void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    499 {
    500     if (TCG_TARGET_HAS_rot_i32) {
    501         tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
    502     } else {
    503         TCGv_i32 t0, t1;
    504 
    505         t0 = tcg_temp_new_i32();
    506         t1 = tcg_temp_new_i32();
    507         tcg_gen_shl_i32(t0, arg1, arg2);
    508         tcg_gen_subfi_i32(t1, 32, arg2);
    509         tcg_gen_shr_i32(t1, arg1, t1);
    510         tcg_gen_or_i32(ret, t0, t1);
    511         tcg_temp_free_i32(t0);
    512         tcg_temp_free_i32(t1);
    513     }
    514 }
    515 
    516 void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    517 {
    518     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
    519     /* some cases can be optimized here */
    520     if (arg2 == 0) {
    521         tcg_gen_mov_i32(ret, arg1);
    522     } else if (TCG_TARGET_HAS_rot_i32) {
    523         tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
    524     } else {
    525         TCGv_i32 t0, t1;
    526         t0 = tcg_temp_new_i32();
    527         t1 = tcg_temp_new_i32();
    528         tcg_gen_shli_i32(t0, arg1, arg2);
    529         tcg_gen_shri_i32(t1, arg1, 32 - arg2);
    530         tcg_gen_or_i32(ret, t0, t1);
    531         tcg_temp_free_i32(t0);
    532         tcg_temp_free_i32(t1);
    533     }
    534 }
    535 
    536 void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
    537 {
    538     if (TCG_TARGET_HAS_rot_i32) {
    539         tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
    540     } else {
    541         TCGv_i32 t0, t1;
    542 
    543         t0 = tcg_temp_new_i32();
    544         t1 = tcg_temp_new_i32();
    545         tcg_gen_shr_i32(t0, arg1, arg2);
    546         tcg_gen_subfi_i32(t1, 32, arg2);
    547         tcg_gen_shl_i32(t1, arg1, t1);
    548         tcg_gen_or_i32(ret, t0, t1);
    549         tcg_temp_free_i32(t0);
    550         tcg_temp_free_i32(t1);
    551     }
    552 }
    553 
    554 void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
    555 {
    556     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
    557     /* some cases can be optimized here */
    558     if (arg2 == 0) {
    559         tcg_gen_mov_i32(ret, arg1);
    560     } else {
    561         tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
    562     }
    563 }
    564 
    565 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
    566                          unsigned int ofs, unsigned int len)
    567 {
    568     uint32_t mask;
    569     TCGv_i32 t1;
    570 
    571     tcg_debug_assert(ofs < 32);
    572     tcg_debug_assert(len > 0);
    573     tcg_debug_assert(len <= 32);
    574     tcg_debug_assert(ofs + len <= 32);
    575 
    576     if (len == 32) {
    577         tcg_gen_mov_i32(ret, arg2);
    578         return;
    579     }
    580     if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
    581         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
    582         return;
    583     }
    584 
    585     t1 = tcg_temp_new_i32();
    586 
    587     if (TCG_TARGET_HAS_extract2_i32) {
    588         if (ofs + len == 32) {
    589             tcg_gen_shli_i32(t1, arg1, len);
    590             tcg_gen_extract2_i32(ret, t1, arg2, len);
    591             goto done;
    592         }
    593         if (ofs == 0) {
    594             tcg_gen_extract2_i32(ret, arg1, arg2, len);
    595             tcg_gen_rotli_i32(ret, ret, len);
    596             goto done;
    597         }
    598     }
    599 
    600     mask = (1u << len) - 1;
    601     if (ofs + len < 32) {
    602         tcg_gen_andi_i32(t1, arg2, mask);
    603         tcg_gen_shli_i32(t1, t1, ofs);
    604     } else {
    605         tcg_gen_shli_i32(t1, arg2, ofs);
    606     }
    607     tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
    608     tcg_gen_or_i32(ret, ret, t1);
    609  done:
    610     tcg_temp_free_i32(t1);
    611 }
    612 
    613 void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
    614                            unsigned int ofs, unsigned int len)
    615 {
    616     tcg_debug_assert(ofs < 32);
    617     tcg_debug_assert(len > 0);
    618     tcg_debug_assert(len <= 32);
    619     tcg_debug_assert(ofs + len <= 32);
    620 
    621     if (ofs + len == 32) {
    622         tcg_gen_shli_i32(ret, arg, ofs);
    623     } else if (ofs == 0) {
    624         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
    625     } else if (TCG_TARGET_HAS_deposit_i32
    626                && TCG_TARGET_deposit_i32_valid(ofs, len)) {
    627         TCGv_i32 zero = tcg_constant_i32(0);
    628         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
    629     } else {
    630         /* To help two-operand hosts we prefer to zero-extend first,
    631            which allows ARG to stay live.  */
    632         switch (len) {
    633         case 16:
    634             if (TCG_TARGET_HAS_ext16u_i32) {
    635                 tcg_gen_ext16u_i32(ret, arg);
    636                 tcg_gen_shli_i32(ret, ret, ofs);
    637                 return;
    638             }
    639             break;
    640         case 8:
    641             if (TCG_TARGET_HAS_ext8u_i32) {
    642                 tcg_gen_ext8u_i32(ret, arg);
    643                 tcg_gen_shli_i32(ret, ret, ofs);
    644                 return;
    645             }
    646             break;
    647         }
    648         /* Otherwise prefer zero-extension over AND for code size.  */
    649         switch (ofs + len) {
    650         case 16:
    651             if (TCG_TARGET_HAS_ext16u_i32) {
    652                 tcg_gen_shli_i32(ret, arg, ofs);
    653                 tcg_gen_ext16u_i32(ret, ret);
    654                 return;
    655             }
    656             break;
    657         case 8:
    658             if (TCG_TARGET_HAS_ext8u_i32) {
    659                 tcg_gen_shli_i32(ret, arg, ofs);
    660                 tcg_gen_ext8u_i32(ret, ret);
    661                 return;
    662             }
    663             break;
    664         }
    665         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
    666         tcg_gen_shli_i32(ret, ret, ofs);
    667     }
    668 }
    669 
    670 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
    671                          unsigned int ofs, unsigned int len)
    672 {
    673     tcg_debug_assert(ofs < 32);
    674     tcg_debug_assert(len > 0);
    675     tcg_debug_assert(len <= 32);
    676     tcg_debug_assert(ofs + len <= 32);
    677 
    678     /* Canonicalize certain special cases, even if extract is supported.  */
    679     if (ofs + len == 32) {
    680         tcg_gen_shri_i32(ret, arg, 32 - len);
    681         return;
    682     }
    683     if (ofs == 0) {
    684         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
    685         return;
    686     }
    687 
    688     if (TCG_TARGET_HAS_extract_i32
    689         && TCG_TARGET_extract_i32_valid(ofs, len)) {
    690         tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
    691         return;
    692     }
    693 
    694     /* Assume that zero-extension, if available, is cheaper than a shift.  */
    695     switch (ofs + len) {
    696     case 16:
    697         if (TCG_TARGET_HAS_ext16u_i32) {
    698             tcg_gen_ext16u_i32(ret, arg);
    699             tcg_gen_shri_i32(ret, ret, ofs);
    700             return;
    701         }
    702         break;
    703     case 8:
    704         if (TCG_TARGET_HAS_ext8u_i32) {
    705             tcg_gen_ext8u_i32(ret, arg);
    706             tcg_gen_shri_i32(ret, ret, ofs);
    707             return;
    708         }
    709         break;
    710     }
    711 
    712     /* ??? Ideally we'd know what values are available for immediate AND.
    713        Assume that 8 bits are available, plus the special case of 16,
    714        so that we get ext8u, ext16u.  */
    715     switch (len) {
    716     case 1 ... 8: case 16:
    717         tcg_gen_shri_i32(ret, arg, ofs);
    718         tcg_gen_andi_i32(ret, ret, (1u << len) - 1);
    719         break;
    720     default:
    721         tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
    722         tcg_gen_shri_i32(ret, ret, 32 - len);
    723         break;
    724     }
    725 }
    726 
    727 void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
    728                           unsigned int ofs, unsigned int len)
    729 {
    730     tcg_debug_assert(ofs < 32);
    731     tcg_debug_assert(len > 0);
    732     tcg_debug_assert(len <= 32);
    733     tcg_debug_assert(ofs + len <= 32);
    734 
    735     /* Canonicalize certain special cases, even if extract is supported.  */
    736     if (ofs + len == 32) {
    737         tcg_gen_sari_i32(ret, arg, 32 - len);
    738         return;
    739     }
    740     if (ofs == 0) {
    741         switch (len) {
    742         case 16:
    743             tcg_gen_ext16s_i32(ret, arg);
    744             return;
    745         case 8:
    746             tcg_gen_ext8s_i32(ret, arg);
    747             return;
    748         }
    749     }
    750 
    751     if (TCG_TARGET_HAS_sextract_i32
    752         && TCG_TARGET_extract_i32_valid(ofs, len)) {
    753         tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
    754         return;
    755     }
    756 
    757     /* Assume that sign-extension, if available, is cheaper than a shift.  */
    758     switch (ofs + len) {
    759     case 16:
    760         if (TCG_TARGET_HAS_ext16s_i32) {
    761             tcg_gen_ext16s_i32(ret, arg);
    762             tcg_gen_sari_i32(ret, ret, ofs);
    763             return;
    764         }
    765         break;
    766     case 8:
    767         if (TCG_TARGET_HAS_ext8s_i32) {
    768             tcg_gen_ext8s_i32(ret, arg);
    769             tcg_gen_sari_i32(ret, ret, ofs);
    770             return;
    771         }
    772         break;
    773     }
    774     switch (len) {
    775     case 16:
    776         if (TCG_TARGET_HAS_ext16s_i32) {
    777             tcg_gen_shri_i32(ret, arg, ofs);
    778             tcg_gen_ext16s_i32(ret, ret);
    779             return;
    780         }
    781         break;
    782     case 8:
    783         if (TCG_TARGET_HAS_ext8s_i32) {
    784             tcg_gen_shri_i32(ret, arg, ofs);
    785             tcg_gen_ext8s_i32(ret, ret);
    786             return;
    787         }
    788         break;
    789     }
    790 
    791     tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
    792     tcg_gen_sari_i32(ret, ret, 32 - len);
    793 }
    794 
    795 /*
    796  * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
    797  * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
    798  */
    799 void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
    800                           unsigned int ofs)
    801 {
    802     tcg_debug_assert(ofs <= 32);
    803     if (ofs == 0) {
    804         tcg_gen_mov_i32(ret, al);
    805     } else if (ofs == 32) {
    806         tcg_gen_mov_i32(ret, ah);
    807     } else if (al == ah) {
    808         tcg_gen_rotri_i32(ret, al, ofs);
    809     } else if (TCG_TARGET_HAS_extract2_i32) {
    810         tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
    811     } else {
    812         TCGv_i32 t0 = tcg_temp_new_i32();
    813         tcg_gen_shri_i32(t0, al, ofs);
    814         tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
    815         tcg_temp_free_i32(t0);
    816     }
    817 }
    818 
    819 void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
    820                          TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
    821 {
    822     if (cond == TCG_COND_ALWAYS) {
    823         tcg_gen_mov_i32(ret, v1);
    824     } else if (cond == TCG_COND_NEVER) {
    825         tcg_gen_mov_i32(ret, v2);
    826     } else if (TCG_TARGET_HAS_movcond_i32) {
    827         tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
    828     } else {
    829         TCGv_i32 t0 = tcg_temp_new_i32();
    830         TCGv_i32 t1 = tcg_temp_new_i32();
    831         tcg_gen_setcond_i32(cond, t0, c1, c2);
    832         tcg_gen_neg_i32(t0, t0);
    833         tcg_gen_and_i32(t1, v1, t0);
    834         tcg_gen_andc_i32(ret, v2, t0);
    835         tcg_gen_or_i32(ret, ret, t1);
    836         tcg_temp_free_i32(t0);
    837         tcg_temp_free_i32(t1);
    838     }
    839 }
    840 
    841 void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
    842                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
    843 {
    844     if (TCG_TARGET_HAS_add2_i32) {
    845         tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
    846     } else {
    847         TCGv_i64 t0 = tcg_temp_new_i64();
    848         TCGv_i64 t1 = tcg_temp_new_i64();
    849         tcg_gen_concat_i32_i64(t0, al, ah);
    850         tcg_gen_concat_i32_i64(t1, bl, bh);
    851         tcg_gen_add_i64(t0, t0, t1);
    852         tcg_gen_extr_i64_i32(rl, rh, t0);
    853         tcg_temp_free_i64(t0);
    854         tcg_temp_free_i64(t1);
    855     }
    856 }
    857 
    858 void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
    859                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
    860 {
    861     if (TCG_TARGET_HAS_sub2_i32) {
    862         tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
    863     } else {
    864         TCGv_i64 t0 = tcg_temp_new_i64();
    865         TCGv_i64 t1 = tcg_temp_new_i64();
    866         tcg_gen_concat_i32_i64(t0, al, ah);
    867         tcg_gen_concat_i32_i64(t1, bl, bh);
    868         tcg_gen_sub_i64(t0, t0, t1);
    869         tcg_gen_extr_i64_i32(rl, rh, t0);
    870         tcg_temp_free_i64(t0);
    871         tcg_temp_free_i64(t1);
    872     }
    873 }
    874 
    875 void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
    876 {
    877     if (TCG_TARGET_HAS_mulu2_i32) {
    878         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
    879     } else if (TCG_TARGET_HAS_muluh_i32) {
    880         TCGv_i32 t = tcg_temp_new_i32();
    881         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
    882         tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
    883         tcg_gen_mov_i32(rl, t);
    884         tcg_temp_free_i32(t);
    885     } else {
    886         TCGv_i64 t0 = tcg_temp_new_i64();
    887         TCGv_i64 t1 = tcg_temp_new_i64();
    888         tcg_gen_extu_i32_i64(t0, arg1);
    889         tcg_gen_extu_i32_i64(t1, arg2);
    890         tcg_gen_mul_i64(t0, t0, t1);
    891         tcg_gen_extr_i64_i32(rl, rh, t0);
    892         tcg_temp_free_i64(t0);
    893         tcg_temp_free_i64(t1);
    894     }
    895 }
    896 
    897 void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
    898 {
    899     if (TCG_TARGET_HAS_muls2_i32) {
    900         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
    901     } else if (TCG_TARGET_HAS_mulsh_i32) {
    902         TCGv_i32 t = tcg_temp_new_i32();
    903         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
    904         tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
    905         tcg_gen_mov_i32(rl, t);
    906         tcg_temp_free_i32(t);
    907     } else if (TCG_TARGET_REG_BITS == 32) {
    908         TCGv_i32 t0 = tcg_temp_new_i32();
    909         TCGv_i32 t1 = tcg_temp_new_i32();
    910         TCGv_i32 t2 = tcg_temp_new_i32();
    911         TCGv_i32 t3 = tcg_temp_new_i32();
    912         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
    913         /* Adjust for negative inputs.  */
    914         tcg_gen_sari_i32(t2, arg1, 31);
    915         tcg_gen_sari_i32(t3, arg2, 31);
    916         tcg_gen_and_i32(t2, t2, arg2);
    917         tcg_gen_and_i32(t3, t3, arg1);
    918         tcg_gen_sub_i32(rh, t1, t2);
    919         tcg_gen_sub_i32(rh, rh, t3);
    920         tcg_gen_mov_i32(rl, t0);
    921         tcg_temp_free_i32(t0);
    922         tcg_temp_free_i32(t1);
    923         tcg_temp_free_i32(t2);
    924         tcg_temp_free_i32(t3);
    925     } else {
    926         TCGv_i64 t0 = tcg_temp_new_i64();
    927         TCGv_i64 t1 = tcg_temp_new_i64();
    928         tcg_gen_ext_i32_i64(t0, arg1);
    929         tcg_gen_ext_i32_i64(t1, arg2);
    930         tcg_gen_mul_i64(t0, t0, t1);
    931         tcg_gen_extr_i64_i32(rl, rh, t0);
    932         tcg_temp_free_i64(t0);
    933         tcg_temp_free_i64(t1);
    934     }
    935 }
    936 
    937 void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
    938 {
    939     if (TCG_TARGET_REG_BITS == 32) {
    940         TCGv_i32 t0 = tcg_temp_new_i32();
    941         TCGv_i32 t1 = tcg_temp_new_i32();
    942         TCGv_i32 t2 = tcg_temp_new_i32();
    943         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
    944         /* Adjust for negative input for the signed arg1.  */
    945         tcg_gen_sari_i32(t2, arg1, 31);
    946         tcg_gen_and_i32(t2, t2, arg2);
    947         tcg_gen_sub_i32(rh, t1, t2);
    948         tcg_gen_mov_i32(rl, t0);
    949         tcg_temp_free_i32(t0);
    950         tcg_temp_free_i32(t1);
    951         tcg_temp_free_i32(t2);
    952     } else {
    953         TCGv_i64 t0 = tcg_temp_new_i64();
    954         TCGv_i64 t1 = tcg_temp_new_i64();
    955         tcg_gen_ext_i32_i64(t0, arg1);
    956         tcg_gen_extu_i32_i64(t1, arg2);
    957         tcg_gen_mul_i64(t0, t0, t1);
    958         tcg_gen_extr_i64_i32(rl, rh, t0);
    959         tcg_temp_free_i64(t0);
    960         tcg_temp_free_i64(t1);
    961     }
    962 }
    963 
    964 void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
    965 {
    966     if (TCG_TARGET_HAS_ext8s_i32) {
    967         tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
    968     } else {
    969         tcg_gen_shli_i32(ret, arg, 24);
    970         tcg_gen_sari_i32(ret, ret, 24);
    971     }
    972 }
    973 
    974 void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
    975 {
    976     if (TCG_TARGET_HAS_ext16s_i32) {
    977         tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
    978     } else {
    979         tcg_gen_shli_i32(ret, arg, 16);
    980         tcg_gen_sari_i32(ret, ret, 16);
    981     }
    982 }
    983 
    984 void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
    985 {
    986     if (TCG_TARGET_HAS_ext8u_i32) {
    987         tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
    988     } else {
    989         tcg_gen_andi_i32(ret, arg, 0xffu);
    990     }
    991 }
    992 
    993 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
    994 {
    995     if (TCG_TARGET_HAS_ext16u_i32) {
    996         tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
    997     } else {
    998         tcg_gen_andi_i32(ret, arg, 0xffffu);
    999     }
   1000 }
   1001 
   1002 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags)
   1003 {
   1004     /* Only one extension flag may be present. */
   1005     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
   1006 
   1007     if (TCG_TARGET_HAS_bswap16_i32) {
   1008         tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
   1009     } else {
   1010         TCGv_i32 t0 = tcg_temp_new_i32();
   1011         TCGv_i32 t1 = tcg_temp_new_i32();
   1012 
   1013         tcg_gen_shri_i32(t0, arg, 8);
   1014         if (!(flags & TCG_BSWAP_IZ)) {
   1015             tcg_gen_ext8u_i32(t0, t0);
   1016         }
   1017 
   1018         if (flags & TCG_BSWAP_OS) {
   1019             tcg_gen_shli_i32(t1, arg, 24);
   1020             tcg_gen_sari_i32(t1, t1, 16);
   1021         } else if (flags & TCG_BSWAP_OZ) {
   1022             tcg_gen_ext8u_i32(t1, arg);
   1023             tcg_gen_shli_i32(t1, t1, 8);
   1024         } else {
   1025             tcg_gen_shli_i32(t1, arg, 8);
   1026         }
   1027 
   1028         tcg_gen_or_i32(ret, t0, t1);
   1029         tcg_temp_free_i32(t0);
   1030         tcg_temp_free_i32(t1);
   1031     }
   1032 }
   1033 
   1034 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
   1035 {
   1036     if (TCG_TARGET_HAS_bswap32_i32) {
   1037         tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
   1038     } else {
   1039         TCGv_i32 t0 = tcg_temp_new_i32();
   1040         TCGv_i32 t1 = tcg_temp_new_i32();
   1041         TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
   1042 
   1043                                         /* arg = abcd */
   1044         tcg_gen_shri_i32(t0, arg, 8);   /*  t0 = .abc */
   1045         tcg_gen_and_i32(t1, arg, t2);   /*  t1 = .b.d */
   1046         tcg_gen_and_i32(t0, t0, t2);    /*  t0 = .a.c */
   1047         tcg_gen_shli_i32(t1, t1, 8);    /*  t1 = b.d. */
   1048         tcg_gen_or_i32(ret, t0, t1);    /* ret = badc */
   1049 
   1050         tcg_gen_shri_i32(t0, ret, 16);  /*  t0 = ..ba */
   1051         tcg_gen_shli_i32(t1, ret, 16);  /*  t1 = dc.. */
   1052         tcg_gen_or_i32(ret, t0, t1);    /* ret = dcba */
   1053 
   1054         tcg_temp_free_i32(t0);
   1055         tcg_temp_free_i32(t1);
   1056     }
   1057 }
   1058 
   1059 void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg)
   1060 {
   1061     /* Swapping 2 16-bit elements is a rotate. */
   1062     tcg_gen_rotli_i32(ret, arg, 16);
   1063 }
   1064 
   1065 void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
   1066 {
   1067     tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
   1068 }
   1069 
   1070 void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
   1071 {
   1072     tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
   1073 }
   1074 
   1075 void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
   1076 {
   1077     tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
   1078 }
   1079 
   1080 void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
   1081 {
   1082     tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
   1083 }
   1084 
   1085 void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
   1086 {
   1087     TCGv_i32 t = tcg_temp_new_i32();
   1088 
   1089     tcg_gen_sari_i32(t, a, 31);
   1090     tcg_gen_xor_i32(ret, a, t);
   1091     tcg_gen_sub_i32(ret, ret, t);
   1092     tcg_temp_free_i32(t);
   1093 }
   1094 
   1095 /* 64-bit ops */
   1096 
   1097 #if TCG_TARGET_REG_BITS == 32
   1098 /* These are all inline for TCG_TARGET_REG_BITS == 64.  */
   1099 
   1100 void tcg_gen_discard_i64(TCGv_i64 arg)
   1101 {
   1102     tcg_gen_discard_i32(TCGV_LOW(arg));
   1103     tcg_gen_discard_i32(TCGV_HIGH(arg));
   1104 }
   1105 
   1106 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
   1107 {
   1108     TCGTemp *ts = tcgv_i64_temp(arg);
   1109 
   1110     /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */
   1111     if (ts->kind == TEMP_CONST) {
   1112         tcg_gen_movi_i64(ret, ts->val);
   1113     } else {
   1114         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1115         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
   1116     }
   1117 }
   1118 
   1119 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
   1120 {
   1121     tcg_gen_movi_i32(TCGV_LOW(ret), arg);
   1122     tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
   1123 }
   1124 
   1125 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1126 {
   1127     tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
   1128     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1129 }
   1130 
   1131 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1132 {
   1133     tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
   1134     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1135 }
   1136 
   1137 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1138 {
   1139     tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
   1140     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1141 }
   1142 
   1143 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1144 {
   1145     tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
   1146     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1147 }
   1148 
   1149 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1150 {
   1151     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
   1152     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1153 }
   1154 
   1155 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1156 {
   1157     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
   1158     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1159 }
   1160 
   1161 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
   1162 {
   1163     /* Since arg2 and ret have different types,
   1164        they cannot be the same temporary */
   1165 #if HOST_BIG_ENDIAN
   1166     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
   1167     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
   1168 #else
   1169     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
   1170     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
   1171 #endif
   1172 }
   1173 
   1174 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
   1175 {
   1176 #if HOST_BIG_ENDIAN
   1177     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
   1178     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
   1179 #else
   1180     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
   1181     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
   1182 #endif
   1183 }
   1184 
   1185 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1186 {
   1187     tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1188     tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1189 }
   1190 
   1191 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1192 {
   1193     tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1194     tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1195 }
   1196 
   1197 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1198 {
   1199     tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1200     tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1201 }
   1202 
   1203 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1204 {
   1205     gen_helper_shl_i64(ret, arg1, arg2);
   1206 }
   1207 
   1208 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1209 {
   1210     gen_helper_shr_i64(ret, arg1, arg2);
   1211 }
   1212 
   1213 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1214 {
   1215     gen_helper_sar_i64(ret, arg1, arg2);
   1216 }
   1217 
   1218 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1219 {
   1220     TCGv_i64 t0;
   1221     TCGv_i32 t1;
   1222 
   1223     t0 = tcg_temp_new_i64();
   1224     t1 = tcg_temp_new_i32();
   1225 
   1226     tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
   1227                       TCGV_LOW(arg1), TCGV_LOW(arg2));
   1228 
   1229     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
   1230     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
   1231     tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
   1232     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
   1233 
   1234     tcg_gen_mov_i64(ret, t0);
   1235     tcg_temp_free_i64(t0);
   1236     tcg_temp_free_i32(t1);
   1237 }
   1238 
   1239 #else
   1240 
   1241 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
   1242 {
   1243     tcg_gen_mov_i64(ret, tcg_constant_i64(arg));
   1244 }
   1245 
   1246 #endif /* TCG_TARGET_REG_SIZE == 32 */
   1247 
   1248 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1249 {
   1250     /* some cases can be optimized here */
   1251     if (arg2 == 0) {
   1252         tcg_gen_mov_i64(ret, arg1);
   1253     } else if (TCG_TARGET_REG_BITS == 64) {
   1254         tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2));
   1255     } else {
   1256         tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
   1257                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
   1258                          tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
   1259     }
   1260 }
   1261 
   1262 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
   1263 {
   1264     if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) {
   1265         /* Don't recurse with tcg_gen_neg_i64.  */
   1266         tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2);
   1267     } else if (TCG_TARGET_REG_BITS == 64) {
   1268         tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2);
   1269     } else {
   1270         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
   1271                          tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32),
   1272                          TCGV_LOW(arg2), TCGV_HIGH(arg2));
   1273     }
   1274 }
   1275 
   1276 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1277 {
   1278     /* some cases can be optimized here */
   1279     if (arg2 == 0) {
   1280         tcg_gen_mov_i64(ret, arg1);
   1281     } else if (TCG_TARGET_REG_BITS == 64) {
   1282         tcg_gen_sub_i64(ret, arg1, tcg_constant_i64(arg2));
   1283     } else {
   1284         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
   1285                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
   1286                          tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
   1287     }
   1288 }
   1289 
   1290 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1291 {
   1292     if (TCG_TARGET_REG_BITS == 32) {
   1293         tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
   1294         tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
   1295         return;
   1296     }
   1297 
   1298     /* Some cases can be optimized here.  */
   1299     switch (arg2) {
   1300     case 0:
   1301         tcg_gen_movi_i64(ret, 0);
   1302         return;
   1303     case -1:
   1304         tcg_gen_mov_i64(ret, arg1);
   1305         return;
   1306     case 0xff:
   1307         /* Don't recurse with tcg_gen_ext8u_i64.  */
   1308         if (TCG_TARGET_HAS_ext8u_i64) {
   1309             tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
   1310             return;
   1311         }
   1312         break;
   1313     case 0xffff:
   1314         if (TCG_TARGET_HAS_ext16u_i64) {
   1315             tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
   1316             return;
   1317         }
   1318         break;
   1319     case 0xffffffffu:
   1320         if (TCG_TARGET_HAS_ext32u_i64) {
   1321             tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
   1322             return;
   1323         }
   1324         break;
   1325     }
   1326 
   1327     tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2));
   1328 }
   1329 
   1330 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1331 {
   1332     if (TCG_TARGET_REG_BITS == 32) {
   1333         tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
   1334         tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
   1335         return;
   1336     }
   1337     /* Some cases can be optimized here.  */
   1338     if (arg2 == -1) {
   1339         tcg_gen_movi_i64(ret, -1);
   1340     } else if (arg2 == 0) {
   1341         tcg_gen_mov_i64(ret, arg1);
   1342     } else {
   1343         tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2));
   1344     }
   1345 }
   1346 
   1347 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1348 {
   1349     if (TCG_TARGET_REG_BITS == 32) {
   1350         tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
   1351         tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
   1352         return;
   1353     }
   1354     /* Some cases can be optimized here.  */
   1355     if (arg2 == 0) {
   1356         tcg_gen_mov_i64(ret, arg1);
   1357     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
   1358         /* Don't recurse with tcg_gen_not_i64.  */
   1359         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
   1360     } else {
   1361         tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2));
   1362     }
   1363 }
   1364 
   1365 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
   1366                                       unsigned c, bool right, bool arith)
   1367 {
   1368     tcg_debug_assert(c < 64);
   1369     if (c == 0) {
   1370         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
   1371         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
   1372     } else if (c >= 32) {
   1373         c -= 32;
   1374         if (right) {
   1375             if (arith) {
   1376                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
   1377                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
   1378             } else {
   1379                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
   1380                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1381             }
   1382         } else {
   1383             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
   1384             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
   1385         }
   1386     } else if (right) {
   1387         if (TCG_TARGET_HAS_extract2_i32) {
   1388             tcg_gen_extract2_i32(TCGV_LOW(ret),
   1389                                  TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
   1390         } else {
   1391             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
   1392             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret),
   1393                                 TCGV_HIGH(arg1), 32 - c, c);
   1394         }
   1395         if (arith) {
   1396             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
   1397         } else {
   1398             tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
   1399         }
   1400     } else {
   1401         if (TCG_TARGET_HAS_extract2_i32) {
   1402             tcg_gen_extract2_i32(TCGV_HIGH(ret),
   1403                                  TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
   1404         } else {
   1405             TCGv_i32 t0 = tcg_temp_new_i32();
   1406             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
   1407             tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
   1408                                 TCGV_HIGH(arg1), c, 32 - c);
   1409             tcg_temp_free_i32(t0);
   1410         }
   1411         tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
   1412     }
   1413 }
   1414 
   1415 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1416 {
   1417     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
   1418     if (TCG_TARGET_REG_BITS == 32) {
   1419         tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
   1420     } else if (arg2 == 0) {
   1421         tcg_gen_mov_i64(ret, arg1);
   1422     } else {
   1423         tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2));
   1424     }
   1425 }
   1426 
   1427 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1428 {
   1429     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
   1430     if (TCG_TARGET_REG_BITS == 32) {
   1431         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
   1432     } else if (arg2 == 0) {
   1433         tcg_gen_mov_i64(ret, arg1);
   1434     } else {
   1435         tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2));
   1436     }
   1437 }
   1438 
   1439 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1440 {
   1441     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
   1442     if (TCG_TARGET_REG_BITS == 32) {
   1443         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
   1444     } else if (arg2 == 0) {
   1445         tcg_gen_mov_i64(ret, arg1);
   1446     } else {
   1447         tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2));
   1448     }
   1449 }
   1450 
   1451 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
   1452 {
   1453     if (cond == TCG_COND_ALWAYS) {
   1454         tcg_gen_br(l);
   1455     } else if (cond != TCG_COND_NEVER) {
   1456         l->refs++;
   1457         if (TCG_TARGET_REG_BITS == 32) {
   1458             tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
   1459                               TCGV_HIGH(arg1), TCGV_LOW(arg2),
   1460                               TCGV_HIGH(arg2), cond, label_arg(l));
   1461         } else {
   1462             tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
   1463                               label_arg(l));
   1464         }
   1465     }
   1466 }
   1467 
   1468 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
   1469 {
   1470     if (TCG_TARGET_REG_BITS == 64) {
   1471         tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l);
   1472     } else if (cond == TCG_COND_ALWAYS) {
   1473         tcg_gen_br(l);
   1474     } else if (cond != TCG_COND_NEVER) {
   1475         l->refs++;
   1476         tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
   1477                           TCGV_LOW(arg1), TCGV_HIGH(arg1),
   1478                           tcg_constant_i32(arg2),
   1479                           tcg_constant_i32(arg2 >> 32),
   1480                           cond, label_arg(l));
   1481     }
   1482 }
   1483 
   1484 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
   1485                          TCGv_i64 arg1, TCGv_i64 arg2)
   1486 {
   1487     if (cond == TCG_COND_ALWAYS) {
   1488         tcg_gen_movi_i64(ret, 1);
   1489     } else if (cond == TCG_COND_NEVER) {
   1490         tcg_gen_movi_i64(ret, 0);
   1491     } else {
   1492         if (TCG_TARGET_REG_BITS == 32) {
   1493             tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
   1494                              TCGV_LOW(arg1), TCGV_HIGH(arg1),
   1495                              TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
   1496             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1497         } else {
   1498             tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
   1499         }
   1500     }
   1501 }
   1502 
   1503 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
   1504                           TCGv_i64 arg1, int64_t arg2)
   1505 {
   1506     if (TCG_TARGET_REG_BITS == 64) {
   1507         tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
   1508     } else if (cond == TCG_COND_ALWAYS) {
   1509         tcg_gen_movi_i64(ret, 1);
   1510     } else if (cond == TCG_COND_NEVER) {
   1511         tcg_gen_movi_i64(ret, 0);
   1512     } else {
   1513         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
   1514                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
   1515                          tcg_constant_i32(arg2),
   1516                          tcg_constant_i32(arg2 >> 32), cond);
   1517         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1518     }
   1519 }
   1520 
   1521 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   1522 {
   1523     if (arg2 == 0) {
   1524         tcg_gen_movi_i64(ret, 0);
   1525     } else if (is_power_of_2(arg2)) {
   1526         tcg_gen_shli_i64(ret, arg1, ctz64(arg2));
   1527     } else {
   1528         TCGv_i64 t0 = tcg_const_i64(arg2);
   1529         tcg_gen_mul_i64(ret, arg1, t0);
   1530         tcg_temp_free_i64(t0);
   1531     }
   1532 }
   1533 
   1534 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1535 {
   1536     if (TCG_TARGET_HAS_div_i64) {
   1537         tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
   1538     } else if (TCG_TARGET_HAS_div2_i64) {
   1539         TCGv_i64 t0 = tcg_temp_new_i64();
   1540         tcg_gen_sari_i64(t0, arg1, 63);
   1541         tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
   1542         tcg_temp_free_i64(t0);
   1543     } else {
   1544         gen_helper_div_i64(ret, arg1, arg2);
   1545     }
   1546 }
   1547 
   1548 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1549 {
   1550     if (TCG_TARGET_HAS_rem_i64) {
   1551         tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
   1552     } else if (TCG_TARGET_HAS_div_i64) {
   1553         TCGv_i64 t0 = tcg_temp_new_i64();
   1554         tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
   1555         tcg_gen_mul_i64(t0, t0, arg2);
   1556         tcg_gen_sub_i64(ret, arg1, t0);
   1557         tcg_temp_free_i64(t0);
   1558     } else if (TCG_TARGET_HAS_div2_i64) {
   1559         TCGv_i64 t0 = tcg_temp_new_i64();
   1560         tcg_gen_sari_i64(t0, arg1, 63);
   1561         tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
   1562         tcg_temp_free_i64(t0);
   1563     } else {
   1564         gen_helper_rem_i64(ret, arg1, arg2);
   1565     }
   1566 }
   1567 
   1568 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1569 {
   1570     if (TCG_TARGET_HAS_div_i64) {
   1571         tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
   1572     } else if (TCG_TARGET_HAS_div2_i64) {
   1573         TCGv_i64 t0 = tcg_temp_new_i64();
   1574         tcg_gen_movi_i64(t0, 0);
   1575         tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
   1576         tcg_temp_free_i64(t0);
   1577     } else {
   1578         gen_helper_divu_i64(ret, arg1, arg2);
   1579     }
   1580 }
   1581 
   1582 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1583 {
   1584     if (TCG_TARGET_HAS_rem_i64) {
   1585         tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
   1586     } else if (TCG_TARGET_HAS_div_i64) {
   1587         TCGv_i64 t0 = tcg_temp_new_i64();
   1588         tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
   1589         tcg_gen_mul_i64(t0, t0, arg2);
   1590         tcg_gen_sub_i64(ret, arg1, t0);
   1591         tcg_temp_free_i64(t0);
   1592     } else if (TCG_TARGET_HAS_div2_i64) {
   1593         TCGv_i64 t0 = tcg_temp_new_i64();
   1594         tcg_gen_movi_i64(t0, 0);
   1595         tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
   1596         tcg_temp_free_i64(t0);
   1597     } else {
   1598         gen_helper_remu_i64(ret, arg1, arg2);
   1599     }
   1600 }
   1601 
   1602 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
   1603 {
   1604     if (TCG_TARGET_REG_BITS == 32) {
   1605         tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1606         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1607     } else if (TCG_TARGET_HAS_ext8s_i64) {
   1608         tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
   1609     } else {
   1610         tcg_gen_shli_i64(ret, arg, 56);
   1611         tcg_gen_sari_i64(ret, ret, 56);
   1612     }
   1613 }
   1614 
   1615 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
   1616 {
   1617     if (TCG_TARGET_REG_BITS == 32) {
   1618         tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1619         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1620     } else if (TCG_TARGET_HAS_ext16s_i64) {
   1621         tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
   1622     } else {
   1623         tcg_gen_shli_i64(ret, arg, 48);
   1624         tcg_gen_sari_i64(ret, ret, 48);
   1625     }
   1626 }
   1627 
   1628 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
   1629 {
   1630     if (TCG_TARGET_REG_BITS == 32) {
   1631         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1632         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1633     } else if (TCG_TARGET_HAS_ext32s_i64) {
   1634         tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
   1635     } else {
   1636         tcg_gen_shli_i64(ret, arg, 32);
   1637         tcg_gen_sari_i64(ret, ret, 32);
   1638     }
   1639 }
   1640 
   1641 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
   1642 {
   1643     if (TCG_TARGET_REG_BITS == 32) {
   1644         tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1645         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1646     } else if (TCG_TARGET_HAS_ext8u_i64) {
   1647         tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
   1648     } else {
   1649         tcg_gen_andi_i64(ret, arg, 0xffu);
   1650     }
   1651 }
   1652 
   1653 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
   1654 {
   1655     if (TCG_TARGET_REG_BITS == 32) {
   1656         tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1657         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1658     } else if (TCG_TARGET_HAS_ext16u_i64) {
   1659         tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
   1660     } else {
   1661         tcg_gen_andi_i64(ret, arg, 0xffffu);
   1662     }
   1663 }
   1664 
   1665 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
   1666 {
   1667     if (TCG_TARGET_REG_BITS == 32) {
   1668         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1669         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1670     } else if (TCG_TARGET_HAS_ext32u_i64) {
   1671         tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
   1672     } else {
   1673         tcg_gen_andi_i64(ret, arg, 0xffffffffu);
   1674     }
   1675 }
   1676 
   1677 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
   1678 {
   1679     /* Only one extension flag may be present. */
   1680     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
   1681 
   1682     if (TCG_TARGET_REG_BITS == 32) {
   1683         tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags);
   1684         if (flags & TCG_BSWAP_OS) {
   1685             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1686         } else {
   1687             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1688         }
   1689     } else if (TCG_TARGET_HAS_bswap16_i64) {
   1690         tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
   1691     } else {
   1692         TCGv_i64 t0 = tcg_temp_new_i64();
   1693         TCGv_i64 t1 = tcg_temp_new_i64();
   1694 
   1695         tcg_gen_shri_i64(t0, arg, 8);
   1696         if (!(flags & TCG_BSWAP_IZ)) {
   1697             tcg_gen_ext8u_i64(t0, t0);
   1698         }
   1699 
   1700         if (flags & TCG_BSWAP_OS) {
   1701             tcg_gen_shli_i64(t1, arg, 56);
   1702             tcg_gen_sari_i64(t1, t1, 48);
   1703         } else if (flags & TCG_BSWAP_OZ) {
   1704             tcg_gen_ext8u_i64(t1, arg);
   1705             tcg_gen_shli_i64(t1, t1, 8);
   1706         } else {
   1707             tcg_gen_shli_i64(t1, arg, 8);
   1708         }
   1709 
   1710         tcg_gen_or_i64(ret, t0, t1);
   1711         tcg_temp_free_i64(t0);
   1712         tcg_temp_free_i64(t1);
   1713     }
   1714 }
   1715 
   1716 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
   1717 {
   1718     /* Only one extension flag may be present. */
   1719     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
   1720 
   1721     if (TCG_TARGET_REG_BITS == 32) {
   1722         tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1723         if (flags & TCG_BSWAP_OS) {
   1724             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   1725         } else {
   1726             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1727         }
   1728     } else if (TCG_TARGET_HAS_bswap32_i64) {
   1729         tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
   1730     } else {
   1731         TCGv_i64 t0 = tcg_temp_new_i64();
   1732         TCGv_i64 t1 = tcg_temp_new_i64();
   1733         TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
   1734 
   1735                                             /* arg = xxxxabcd */
   1736         tcg_gen_shri_i64(t0, arg, 8);       /*  t0 = .xxxxabc */
   1737         tcg_gen_and_i64(t1, arg, t2);       /*  t1 = .....b.d */
   1738         tcg_gen_and_i64(t0, t0, t2);        /*  t0 = .....a.c */
   1739         tcg_gen_shli_i64(t1, t1, 8);        /*  t1 = ....b.d. */
   1740         tcg_gen_or_i64(ret, t0, t1);        /* ret = ....badc */
   1741 
   1742         tcg_gen_shli_i64(t1, ret, 48);      /*  t1 = dc...... */
   1743         tcg_gen_shri_i64(t0, ret, 16);      /*  t0 = ......ba */
   1744         if (flags & TCG_BSWAP_OS) {
   1745             tcg_gen_sari_i64(t1, t1, 32);   /*  t1 = ssssdc.. */
   1746         } else {
   1747             tcg_gen_shri_i64(t1, t1, 32);   /*  t1 = ....dc.. */
   1748         }
   1749         tcg_gen_or_i64(ret, t0, t1);        /* ret = ssssdcba */
   1750 
   1751         tcg_temp_free_i64(t0);
   1752         tcg_temp_free_i64(t1);
   1753     }
   1754 }
   1755 
   1756 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
   1757 {
   1758     if (TCG_TARGET_REG_BITS == 32) {
   1759         TCGv_i32 t0, t1;
   1760         t0 = tcg_temp_new_i32();
   1761         t1 = tcg_temp_new_i32();
   1762 
   1763         tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
   1764         tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
   1765         tcg_gen_mov_i32(TCGV_LOW(ret), t1);
   1766         tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
   1767         tcg_temp_free_i32(t0);
   1768         tcg_temp_free_i32(t1);
   1769     } else if (TCG_TARGET_HAS_bswap64_i64) {
   1770         tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
   1771     } else {
   1772         TCGv_i64 t0 = tcg_temp_new_i64();
   1773         TCGv_i64 t1 = tcg_temp_new_i64();
   1774         TCGv_i64 t2 = tcg_temp_new_i64();
   1775 
   1776                                         /* arg = abcdefgh */
   1777         tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
   1778         tcg_gen_shri_i64(t0, arg, 8);   /*  t0 = .abcdefg */
   1779         tcg_gen_and_i64(t1, arg, t2);   /*  t1 = .b.d.f.h */
   1780         tcg_gen_and_i64(t0, t0, t2);    /*  t0 = .a.c.e.g */
   1781         tcg_gen_shli_i64(t1, t1, 8);    /*  t1 = b.d.f.h. */
   1782         tcg_gen_or_i64(ret, t0, t1);    /* ret = badcfehg */
   1783 
   1784         tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull);
   1785         tcg_gen_shri_i64(t0, ret, 16);  /*  t0 = ..badcfe */
   1786         tcg_gen_and_i64(t1, ret, t2);   /*  t1 = ..dc..hg */
   1787         tcg_gen_and_i64(t0, t0, t2);    /*  t0 = ..ba..fe */
   1788         tcg_gen_shli_i64(t1, t1, 16);   /*  t1 = dc..hg.. */
   1789         tcg_gen_or_i64(ret, t0, t1);    /* ret = dcbahgfe */
   1790 
   1791         tcg_gen_shri_i64(t0, ret, 32);  /*  t0 = ....dcba */
   1792         tcg_gen_shli_i64(t1, ret, 32);  /*  t1 = hgfe.... */
   1793         tcg_gen_or_i64(ret, t0, t1);    /* ret = hgfedcba */
   1794 
   1795         tcg_temp_free_i64(t0);
   1796         tcg_temp_free_i64(t1);
   1797         tcg_temp_free_i64(t2);
   1798     }
   1799 }
   1800 
   1801 void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
   1802 {
   1803     uint64_t m = 0x0000ffff0000ffffull;
   1804     TCGv_i64 t0 = tcg_temp_new_i64();
   1805     TCGv_i64 t1 = tcg_temp_new_i64();
   1806 
   1807     /* See include/qemu/bitops.h, hswap64. */
   1808     tcg_gen_rotli_i64(t1, arg, 32);
   1809     tcg_gen_andi_i64(t0, t1, m);
   1810     tcg_gen_shli_i64(t0, t0, 16);
   1811     tcg_gen_shri_i64(t1, t1, 16);
   1812     tcg_gen_andi_i64(t1, t1, m);
   1813     tcg_gen_or_i64(ret, t0, t1);
   1814 
   1815     tcg_temp_free_i64(t0);
   1816     tcg_temp_free_i64(t1);
   1817 }
   1818 
   1819 void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg)
   1820 {
   1821     /* Swapping 2 32-bit elements is a rotate. */
   1822     tcg_gen_rotli_i64(ret, arg, 32);
   1823 }
   1824 
   1825 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
   1826 {
   1827     if (TCG_TARGET_REG_BITS == 32) {
   1828         tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   1829         tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
   1830     } else if (TCG_TARGET_HAS_not_i64) {
   1831         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
   1832     } else {
   1833         tcg_gen_xori_i64(ret, arg, -1);
   1834     }
   1835 }
   1836 
   1837 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1838 {
   1839     if (TCG_TARGET_REG_BITS == 32) {
   1840         tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1841         tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1842     } else if (TCG_TARGET_HAS_andc_i64) {
   1843         tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
   1844     } else {
   1845         TCGv_i64 t0 = tcg_temp_new_i64();
   1846         tcg_gen_not_i64(t0, arg2);
   1847         tcg_gen_and_i64(ret, arg1, t0);
   1848         tcg_temp_free_i64(t0);
   1849     }
   1850 }
   1851 
   1852 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1853 {
   1854     if (TCG_TARGET_REG_BITS == 32) {
   1855         tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1856         tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1857     } else if (TCG_TARGET_HAS_eqv_i64) {
   1858         tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
   1859     } else {
   1860         tcg_gen_xor_i64(ret, arg1, arg2);
   1861         tcg_gen_not_i64(ret, ret);
   1862     }
   1863 }
   1864 
   1865 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1866 {
   1867     if (TCG_TARGET_REG_BITS == 32) {
   1868         tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1869         tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1870     } else if (TCG_TARGET_HAS_nand_i64) {
   1871         tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
   1872     } else {
   1873         tcg_gen_and_i64(ret, arg1, arg2);
   1874         tcg_gen_not_i64(ret, ret);
   1875     }
   1876 }
   1877 
   1878 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1879 {
   1880     if (TCG_TARGET_REG_BITS == 32) {
   1881         tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1882         tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1883     } else if (TCG_TARGET_HAS_nor_i64) {
   1884         tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
   1885     } else {
   1886         tcg_gen_or_i64(ret, arg1, arg2);
   1887         tcg_gen_not_i64(ret, ret);
   1888     }
   1889 }
   1890 
   1891 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1892 {
   1893     if (TCG_TARGET_REG_BITS == 32) {
   1894         tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
   1895         tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
   1896     } else if (TCG_TARGET_HAS_orc_i64) {
   1897         tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
   1898     } else {
   1899         TCGv_i64 t0 = tcg_temp_new_i64();
   1900         tcg_gen_not_i64(t0, arg2);
   1901         tcg_gen_or_i64(ret, arg1, t0);
   1902         tcg_temp_free_i64(t0);
   1903     }
   1904 }
   1905 
   1906 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1907 {
   1908     if (TCG_TARGET_HAS_clz_i64) {
   1909         tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2);
   1910     } else {
   1911         gen_helper_clz_i64(ret, arg1, arg2);
   1912     }
   1913 }
   1914 
   1915 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
   1916 {
   1917     if (TCG_TARGET_REG_BITS == 32
   1918         && TCG_TARGET_HAS_clz_i32
   1919         && arg2 <= 0xffffffffu) {
   1920         TCGv_i32 t = tcg_temp_new_i32();
   1921         tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
   1922         tcg_gen_addi_i32(t, t, 32);
   1923         tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
   1924         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1925         tcg_temp_free_i32(t);
   1926     } else {
   1927         TCGv_i64 t0 = tcg_const_i64(arg2);
   1928         tcg_gen_clz_i64(ret, arg1, t0);
   1929         tcg_temp_free_i64(t0);
   1930     }
   1931 }
   1932 
   1933 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   1934 {
   1935     if (TCG_TARGET_HAS_ctz_i64) {
   1936         tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
   1937     } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
   1938         TCGv_i64 z, t = tcg_temp_new_i64();
   1939 
   1940         if (TCG_TARGET_HAS_ctpop_i64) {
   1941             tcg_gen_subi_i64(t, arg1, 1);
   1942             tcg_gen_andc_i64(t, t, arg1);
   1943             tcg_gen_ctpop_i64(t, t);
   1944         } else {
   1945             /* Since all non-x86 hosts have clz(0) == 64, don't fight it.  */
   1946             tcg_gen_neg_i64(t, arg1);
   1947             tcg_gen_and_i64(t, t, arg1);
   1948             tcg_gen_clzi_i64(t, t, 64);
   1949             tcg_gen_xori_i64(t, t, 63);
   1950         }
   1951         z = tcg_constant_i64(0);
   1952         tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t);
   1953         tcg_temp_free_i64(t);
   1954         tcg_temp_free_i64(z);
   1955     } else {
   1956         gen_helper_ctz_i64(ret, arg1, arg2);
   1957     }
   1958 }
   1959 
   1960 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
   1961 {
   1962     if (TCG_TARGET_REG_BITS == 32
   1963         && TCG_TARGET_HAS_ctz_i32
   1964         && arg2 <= 0xffffffffu) {
   1965         TCGv_i32 t32 = tcg_temp_new_i32();
   1966         tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
   1967         tcg_gen_addi_i32(t32, t32, 32);
   1968         tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
   1969         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   1970         tcg_temp_free_i32(t32);
   1971     } else if (!TCG_TARGET_HAS_ctz_i64
   1972                && TCG_TARGET_HAS_ctpop_i64
   1973                && arg2 == 64) {
   1974         /* This equivalence has the advantage of not requiring a fixup.  */
   1975         TCGv_i64 t = tcg_temp_new_i64();
   1976         tcg_gen_subi_i64(t, arg1, 1);
   1977         tcg_gen_andc_i64(t, t, arg1);
   1978         tcg_gen_ctpop_i64(ret, t);
   1979         tcg_temp_free_i64(t);
   1980     } else {
   1981         TCGv_i64 t0 = tcg_const_i64(arg2);
   1982         tcg_gen_ctz_i64(ret, arg1, t0);
   1983         tcg_temp_free_i64(t0);
   1984     }
   1985 }
   1986 
   1987 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
   1988 {
   1989     if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
   1990         TCGv_i64 t = tcg_temp_new_i64();
   1991         tcg_gen_sari_i64(t, arg, 63);
   1992         tcg_gen_xor_i64(t, t, arg);
   1993         tcg_gen_clzi_i64(t, t, 64);
   1994         tcg_gen_subi_i64(ret, t, 1);
   1995         tcg_temp_free_i64(t);
   1996     } else {
   1997         gen_helper_clrsb_i64(ret, arg);
   1998     }
   1999 }
   2000 
   2001 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1)
   2002 {
   2003     if (TCG_TARGET_HAS_ctpop_i64) {
   2004         tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1);
   2005     } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) {
   2006         tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
   2007         tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
   2008         tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret));
   2009         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   2010     } else {
   2011         gen_helper_ctpop_i64(ret, arg1);
   2012     }
   2013 }
   2014 
   2015 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   2016 {
   2017     if (TCG_TARGET_HAS_rot_i64) {
   2018         tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
   2019     } else {
   2020         TCGv_i64 t0, t1;
   2021         t0 = tcg_temp_new_i64();
   2022         t1 = tcg_temp_new_i64();
   2023         tcg_gen_shl_i64(t0, arg1, arg2);
   2024         tcg_gen_subfi_i64(t1, 64, arg2);
   2025         tcg_gen_shr_i64(t1, arg1, t1);
   2026         tcg_gen_or_i64(ret, t0, t1);
   2027         tcg_temp_free_i64(t0);
   2028         tcg_temp_free_i64(t1);
   2029     }
   2030 }
   2031 
   2032 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   2033 {
   2034     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
   2035     /* some cases can be optimized here */
   2036     if (arg2 == 0) {
   2037         tcg_gen_mov_i64(ret, arg1);
   2038     } else if (TCG_TARGET_HAS_rot_i64) {
   2039         tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
   2040     } else {
   2041         TCGv_i64 t0, t1;
   2042         t0 = tcg_temp_new_i64();
   2043         t1 = tcg_temp_new_i64();
   2044         tcg_gen_shli_i64(t0, arg1, arg2);
   2045         tcg_gen_shri_i64(t1, arg1, 64 - arg2);
   2046         tcg_gen_or_i64(ret, t0, t1);
   2047         tcg_temp_free_i64(t0);
   2048         tcg_temp_free_i64(t1);
   2049     }
   2050 }
   2051 
   2052 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
   2053 {
   2054     if (TCG_TARGET_HAS_rot_i64) {
   2055         tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
   2056     } else {
   2057         TCGv_i64 t0, t1;
   2058         t0 = tcg_temp_new_i64();
   2059         t1 = tcg_temp_new_i64();
   2060         tcg_gen_shr_i64(t0, arg1, arg2);
   2061         tcg_gen_subfi_i64(t1, 64, arg2);
   2062         tcg_gen_shl_i64(t1, arg1, t1);
   2063         tcg_gen_or_i64(ret, t0, t1);
   2064         tcg_temp_free_i64(t0);
   2065         tcg_temp_free_i64(t1);
   2066     }
   2067 }
   2068 
   2069 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
   2070 {
   2071     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
   2072     /* some cases can be optimized here */
   2073     if (arg2 == 0) {
   2074         tcg_gen_mov_i64(ret, arg1);
   2075     } else {
   2076         tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
   2077     }
   2078 }
   2079 
   2080 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
   2081                          unsigned int ofs, unsigned int len)
   2082 {
   2083     uint64_t mask;
   2084     TCGv_i64 t1;
   2085 
   2086     tcg_debug_assert(ofs < 64);
   2087     tcg_debug_assert(len > 0);
   2088     tcg_debug_assert(len <= 64);
   2089     tcg_debug_assert(ofs + len <= 64);
   2090 
   2091     if (len == 64) {
   2092         tcg_gen_mov_i64(ret, arg2);
   2093         return;
   2094     }
   2095     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
   2096         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
   2097         return;
   2098     }
   2099 
   2100     if (TCG_TARGET_REG_BITS == 32) {
   2101         if (ofs >= 32) {
   2102             tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
   2103                                 TCGV_LOW(arg2), ofs - 32, len);
   2104             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
   2105             return;
   2106         }
   2107         if (ofs + len <= 32) {
   2108             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
   2109                                 TCGV_LOW(arg2), ofs, len);
   2110             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
   2111             return;
   2112         }
   2113     }
   2114 
   2115     t1 = tcg_temp_new_i64();
   2116 
   2117     if (TCG_TARGET_HAS_extract2_i64) {
   2118         if (ofs + len == 64) {
   2119             tcg_gen_shli_i64(t1, arg1, len);
   2120             tcg_gen_extract2_i64(ret, t1, arg2, len);
   2121             goto done;
   2122         }
   2123         if (ofs == 0) {
   2124             tcg_gen_extract2_i64(ret, arg1, arg2, len);
   2125             tcg_gen_rotli_i64(ret, ret, len);
   2126             goto done;
   2127         }
   2128     }
   2129 
   2130     mask = (1ull << len) - 1;
   2131     if (ofs + len < 64) {
   2132         tcg_gen_andi_i64(t1, arg2, mask);
   2133         tcg_gen_shli_i64(t1, t1, ofs);
   2134     } else {
   2135         tcg_gen_shli_i64(t1, arg2, ofs);
   2136     }
   2137     tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
   2138     tcg_gen_or_i64(ret, ret, t1);
   2139  done:
   2140     tcg_temp_free_i64(t1);
   2141 }
   2142 
   2143 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
   2144                            unsigned int ofs, unsigned int len)
   2145 {
   2146     tcg_debug_assert(ofs < 64);
   2147     tcg_debug_assert(len > 0);
   2148     tcg_debug_assert(len <= 64);
   2149     tcg_debug_assert(ofs + len <= 64);
   2150 
   2151     if (ofs + len == 64) {
   2152         tcg_gen_shli_i64(ret, arg, ofs);
   2153     } else if (ofs == 0) {
   2154         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
   2155     } else if (TCG_TARGET_HAS_deposit_i64
   2156                && TCG_TARGET_deposit_i64_valid(ofs, len)) {
   2157         TCGv_i64 zero = tcg_constant_i64(0);
   2158         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
   2159     } else {
   2160         if (TCG_TARGET_REG_BITS == 32) {
   2161             if (ofs >= 32) {
   2162                 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg),
   2163                                       ofs - 32, len);
   2164                 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
   2165                 return;
   2166             }
   2167             if (ofs + len <= 32) {
   2168                 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
   2169                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   2170                 return;
   2171             }
   2172         }
   2173         /* To help two-operand hosts we prefer to zero-extend first,
   2174            which allows ARG to stay live.  */
   2175         switch (len) {
   2176         case 32:
   2177             if (TCG_TARGET_HAS_ext32u_i64) {
   2178                 tcg_gen_ext32u_i64(ret, arg);
   2179                 tcg_gen_shli_i64(ret, ret, ofs);
   2180                 return;
   2181             }
   2182             break;
   2183         case 16:
   2184             if (TCG_TARGET_HAS_ext16u_i64) {
   2185                 tcg_gen_ext16u_i64(ret, arg);
   2186                 tcg_gen_shli_i64(ret, ret, ofs);
   2187                 return;
   2188             }
   2189             break;
   2190         case 8:
   2191             if (TCG_TARGET_HAS_ext8u_i64) {
   2192                 tcg_gen_ext8u_i64(ret, arg);
   2193                 tcg_gen_shli_i64(ret, ret, ofs);
   2194                 return;
   2195             }
   2196             break;
   2197         }
   2198         /* Otherwise prefer zero-extension over AND for code size.  */
   2199         switch (ofs + len) {
   2200         case 32:
   2201             if (TCG_TARGET_HAS_ext32u_i64) {
   2202                 tcg_gen_shli_i64(ret, arg, ofs);
   2203                 tcg_gen_ext32u_i64(ret, ret);
   2204                 return;
   2205             }
   2206             break;
   2207         case 16:
   2208             if (TCG_TARGET_HAS_ext16u_i64) {
   2209                 tcg_gen_shli_i64(ret, arg, ofs);
   2210                 tcg_gen_ext16u_i64(ret, ret);
   2211                 return;
   2212             }
   2213             break;
   2214         case 8:
   2215             if (TCG_TARGET_HAS_ext8u_i64) {
   2216                 tcg_gen_shli_i64(ret, arg, ofs);
   2217                 tcg_gen_ext8u_i64(ret, ret);
   2218                 return;
   2219             }
   2220             break;
   2221         }
   2222         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
   2223         tcg_gen_shli_i64(ret, ret, ofs);
   2224     }
   2225 }
   2226 
   2227 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
   2228                          unsigned int ofs, unsigned int len)
   2229 {
   2230     tcg_debug_assert(ofs < 64);
   2231     tcg_debug_assert(len > 0);
   2232     tcg_debug_assert(len <= 64);
   2233     tcg_debug_assert(ofs + len <= 64);
   2234 
   2235     /* Canonicalize certain special cases, even if extract is supported.  */
   2236     if (ofs + len == 64) {
   2237         tcg_gen_shri_i64(ret, arg, 64 - len);
   2238         return;
   2239     }
   2240     if (ofs == 0) {
   2241         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
   2242         return;
   2243     }
   2244 
   2245     if (TCG_TARGET_REG_BITS == 32) {
   2246         /* Look for a 32-bit extract within one of the two words.  */
   2247         if (ofs >= 32) {
   2248             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
   2249             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   2250             return;
   2251         }
   2252         if (ofs + len <= 32) {
   2253             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
   2254             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   2255             return;
   2256         }
   2257         /* The field is split across two words.  One double-word
   2258            shift is better than two double-word shifts.  */
   2259         goto do_shift_and;
   2260     }
   2261 
   2262     if (TCG_TARGET_HAS_extract_i64
   2263         && TCG_TARGET_extract_i64_valid(ofs, len)) {
   2264         tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
   2265         return;
   2266     }
   2267 
   2268     /* Assume that zero-extension, if available, is cheaper than a shift.  */
   2269     switch (ofs + len) {
   2270     case 32:
   2271         if (TCG_TARGET_HAS_ext32u_i64) {
   2272             tcg_gen_ext32u_i64(ret, arg);
   2273             tcg_gen_shri_i64(ret, ret, ofs);
   2274             return;
   2275         }
   2276         break;
   2277     case 16:
   2278         if (TCG_TARGET_HAS_ext16u_i64) {
   2279             tcg_gen_ext16u_i64(ret, arg);
   2280             tcg_gen_shri_i64(ret, ret, ofs);
   2281             return;
   2282         }
   2283         break;
   2284     case 8:
   2285         if (TCG_TARGET_HAS_ext8u_i64) {
   2286             tcg_gen_ext8u_i64(ret, arg);
   2287             tcg_gen_shri_i64(ret, ret, ofs);
   2288             return;
   2289         }
   2290         break;
   2291     }
   2292 
   2293     /* ??? Ideally we'd know what values are available for immediate AND.
   2294        Assume that 8 bits are available, plus the special cases of 16 and 32,
   2295        so that we get ext8u, ext16u, and ext32u.  */
   2296     switch (len) {
   2297     case 1 ... 8: case 16: case 32:
   2298     do_shift_and:
   2299         tcg_gen_shri_i64(ret, arg, ofs);
   2300         tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
   2301         break;
   2302     default:
   2303         tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
   2304         tcg_gen_shri_i64(ret, ret, 64 - len);
   2305         break;
   2306     }
   2307 }
   2308 
   2309 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
   2310                           unsigned int ofs, unsigned int len)
   2311 {
   2312     tcg_debug_assert(ofs < 64);
   2313     tcg_debug_assert(len > 0);
   2314     tcg_debug_assert(len <= 64);
   2315     tcg_debug_assert(ofs + len <= 64);
   2316 
   2317     /* Canonicalize certain special cases, even if sextract is supported.  */
   2318     if (ofs + len == 64) {
   2319         tcg_gen_sari_i64(ret, arg, 64 - len);
   2320         return;
   2321     }
   2322     if (ofs == 0) {
   2323         switch (len) {
   2324         case 32:
   2325             tcg_gen_ext32s_i64(ret, arg);
   2326             return;
   2327         case 16:
   2328             tcg_gen_ext16s_i64(ret, arg);
   2329             return;
   2330         case 8:
   2331             tcg_gen_ext8s_i64(ret, arg);
   2332             return;
   2333         }
   2334     }
   2335 
   2336     if (TCG_TARGET_REG_BITS == 32) {
   2337         /* Look for a 32-bit extract within one of the two words.  */
   2338         if (ofs >= 32) {
   2339             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
   2340         } else if (ofs + len <= 32) {
   2341             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
   2342         } else if (ofs == 0) {
   2343             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
   2344             tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
   2345             return;
   2346         } else if (len > 32) {
   2347             TCGv_i32 t = tcg_temp_new_i32();
   2348             /* Extract the bits for the high word normally.  */
   2349             tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
   2350             /* Shift the field down for the low part.  */
   2351             tcg_gen_shri_i64(ret, arg, ofs);
   2352             /* Overwrite the shift into the high part.  */
   2353             tcg_gen_mov_i32(TCGV_HIGH(ret), t);
   2354             tcg_temp_free_i32(t);
   2355             return;
   2356         } else {
   2357             /* Shift the field down for the low part, such that the
   2358                field sits at the MSB.  */
   2359             tcg_gen_shri_i64(ret, arg, ofs + len - 32);
   2360             /* Shift the field down from the MSB, sign extending.  */
   2361             tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len);
   2362         }
   2363         /* Sign-extend the field from 32 bits.  */
   2364         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   2365         return;
   2366     }
   2367 
   2368     if (TCG_TARGET_HAS_sextract_i64
   2369         && TCG_TARGET_extract_i64_valid(ofs, len)) {
   2370         tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
   2371         return;
   2372     }
   2373 
   2374     /* Assume that sign-extension, if available, is cheaper than a shift.  */
   2375     switch (ofs + len) {
   2376     case 32:
   2377         if (TCG_TARGET_HAS_ext32s_i64) {
   2378             tcg_gen_ext32s_i64(ret, arg);
   2379             tcg_gen_sari_i64(ret, ret, ofs);
   2380             return;
   2381         }
   2382         break;
   2383     case 16:
   2384         if (TCG_TARGET_HAS_ext16s_i64) {
   2385             tcg_gen_ext16s_i64(ret, arg);
   2386             tcg_gen_sari_i64(ret, ret, ofs);
   2387             return;
   2388         }
   2389         break;
   2390     case 8:
   2391         if (TCG_TARGET_HAS_ext8s_i64) {
   2392             tcg_gen_ext8s_i64(ret, arg);
   2393             tcg_gen_sari_i64(ret, ret, ofs);
   2394             return;
   2395         }
   2396         break;
   2397     }
   2398     switch (len) {
   2399     case 32:
   2400         if (TCG_TARGET_HAS_ext32s_i64) {
   2401             tcg_gen_shri_i64(ret, arg, ofs);
   2402             tcg_gen_ext32s_i64(ret, ret);
   2403             return;
   2404         }
   2405         break;
   2406     case 16:
   2407         if (TCG_TARGET_HAS_ext16s_i64) {
   2408             tcg_gen_shri_i64(ret, arg, ofs);
   2409             tcg_gen_ext16s_i64(ret, ret);
   2410             return;
   2411         }
   2412         break;
   2413     case 8:
   2414         if (TCG_TARGET_HAS_ext8s_i64) {
   2415             tcg_gen_shri_i64(ret, arg, ofs);
   2416             tcg_gen_ext8s_i64(ret, ret);
   2417             return;
   2418         }
   2419         break;
   2420     }
   2421     tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
   2422     tcg_gen_sari_i64(ret, ret, 64 - len);
   2423 }
   2424 
   2425 /*
   2426  * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
   2427  * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
   2428  */
   2429 void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
   2430                           unsigned int ofs)
   2431 {
   2432     tcg_debug_assert(ofs <= 64);
   2433     if (ofs == 0) {
   2434         tcg_gen_mov_i64(ret, al);
   2435     } else if (ofs == 64) {
   2436         tcg_gen_mov_i64(ret, ah);
   2437     } else if (al == ah) {
   2438         tcg_gen_rotri_i64(ret, al, ofs);
   2439     } else if (TCG_TARGET_HAS_extract2_i64) {
   2440         tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
   2441     } else {
   2442         TCGv_i64 t0 = tcg_temp_new_i64();
   2443         tcg_gen_shri_i64(t0, al, ofs);
   2444         tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
   2445         tcg_temp_free_i64(t0);
   2446     }
   2447 }
   2448 
   2449 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
   2450                          TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
   2451 {
   2452     if (cond == TCG_COND_ALWAYS) {
   2453         tcg_gen_mov_i64(ret, v1);
   2454     } else if (cond == TCG_COND_NEVER) {
   2455         tcg_gen_mov_i64(ret, v2);
   2456     } else if (TCG_TARGET_REG_BITS == 32) {
   2457         TCGv_i32 t0 = tcg_temp_new_i32();
   2458         TCGv_i32 t1 = tcg_temp_new_i32();
   2459         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
   2460                          TCGV_LOW(c1), TCGV_HIGH(c1),
   2461                          TCGV_LOW(c2), TCGV_HIGH(c2), cond);
   2462 
   2463         if (TCG_TARGET_HAS_movcond_i32) {
   2464             tcg_gen_movi_i32(t1, 0);
   2465             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1,
   2466                                 TCGV_LOW(v1), TCGV_LOW(v2));
   2467             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1,
   2468                                 TCGV_HIGH(v1), TCGV_HIGH(v2));
   2469         } else {
   2470             tcg_gen_neg_i32(t0, t0);
   2471 
   2472             tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
   2473             tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
   2474             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
   2475 
   2476             tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
   2477             tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
   2478             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
   2479         }
   2480         tcg_temp_free_i32(t0);
   2481         tcg_temp_free_i32(t1);
   2482     } else if (TCG_TARGET_HAS_movcond_i64) {
   2483         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
   2484     } else {
   2485         TCGv_i64 t0 = tcg_temp_new_i64();
   2486         TCGv_i64 t1 = tcg_temp_new_i64();
   2487         tcg_gen_setcond_i64(cond, t0, c1, c2);
   2488         tcg_gen_neg_i64(t0, t0);
   2489         tcg_gen_and_i64(t1, v1, t0);
   2490         tcg_gen_andc_i64(ret, v2, t0);
   2491         tcg_gen_or_i64(ret, ret, t1);
   2492         tcg_temp_free_i64(t0);
   2493         tcg_temp_free_i64(t1);
   2494     }
   2495 }
   2496 
   2497 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
   2498                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
   2499 {
   2500     if (TCG_TARGET_HAS_add2_i64) {
   2501         tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
   2502     } else {
   2503         TCGv_i64 t0 = tcg_temp_new_i64();
   2504         TCGv_i64 t1 = tcg_temp_new_i64();
   2505         tcg_gen_add_i64(t0, al, bl);
   2506         tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
   2507         tcg_gen_add_i64(rh, ah, bh);
   2508         tcg_gen_add_i64(rh, rh, t1);
   2509         tcg_gen_mov_i64(rl, t0);
   2510         tcg_temp_free_i64(t0);
   2511         tcg_temp_free_i64(t1);
   2512     }
   2513 }
   2514 
   2515 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
   2516                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
   2517 {
   2518     if (TCG_TARGET_HAS_sub2_i64) {
   2519         tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
   2520     } else {
   2521         TCGv_i64 t0 = tcg_temp_new_i64();
   2522         TCGv_i64 t1 = tcg_temp_new_i64();
   2523         tcg_gen_sub_i64(t0, al, bl);
   2524         tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
   2525         tcg_gen_sub_i64(rh, ah, bh);
   2526         tcg_gen_sub_i64(rh, rh, t1);
   2527         tcg_gen_mov_i64(rl, t0);
   2528         tcg_temp_free_i64(t0);
   2529         tcg_temp_free_i64(t1);
   2530     }
   2531 }
   2532 
   2533 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
   2534 {
   2535     if (TCG_TARGET_HAS_mulu2_i64) {
   2536         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
   2537     } else if (TCG_TARGET_HAS_muluh_i64) {
   2538         TCGv_i64 t = tcg_temp_new_i64();
   2539         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
   2540         tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
   2541         tcg_gen_mov_i64(rl, t);
   2542         tcg_temp_free_i64(t);
   2543     } else {
   2544         TCGv_i64 t0 = tcg_temp_new_i64();
   2545         tcg_gen_mul_i64(t0, arg1, arg2);
   2546         gen_helper_muluh_i64(rh, arg1, arg2);
   2547         tcg_gen_mov_i64(rl, t0);
   2548         tcg_temp_free_i64(t0);
   2549     }
   2550 }
   2551 
   2552 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
   2553 {
   2554     if (TCG_TARGET_HAS_muls2_i64) {
   2555         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
   2556     } else if (TCG_TARGET_HAS_mulsh_i64) {
   2557         TCGv_i64 t = tcg_temp_new_i64();
   2558         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
   2559         tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
   2560         tcg_gen_mov_i64(rl, t);
   2561         tcg_temp_free_i64(t);
   2562     } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
   2563         TCGv_i64 t0 = tcg_temp_new_i64();
   2564         TCGv_i64 t1 = tcg_temp_new_i64();
   2565         TCGv_i64 t2 = tcg_temp_new_i64();
   2566         TCGv_i64 t3 = tcg_temp_new_i64();
   2567         tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
   2568         /* Adjust for negative inputs.  */
   2569         tcg_gen_sari_i64(t2, arg1, 63);
   2570         tcg_gen_sari_i64(t3, arg2, 63);
   2571         tcg_gen_and_i64(t2, t2, arg2);
   2572         tcg_gen_and_i64(t3, t3, arg1);
   2573         tcg_gen_sub_i64(rh, t1, t2);
   2574         tcg_gen_sub_i64(rh, rh, t3);
   2575         tcg_gen_mov_i64(rl, t0);
   2576         tcg_temp_free_i64(t0);
   2577         tcg_temp_free_i64(t1);
   2578         tcg_temp_free_i64(t2);
   2579         tcg_temp_free_i64(t3);
   2580     } else {
   2581         TCGv_i64 t0 = tcg_temp_new_i64();
   2582         tcg_gen_mul_i64(t0, arg1, arg2);
   2583         gen_helper_mulsh_i64(rh, arg1, arg2);
   2584         tcg_gen_mov_i64(rl, t0);
   2585         tcg_temp_free_i64(t0);
   2586     }
   2587 }
   2588 
   2589 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
   2590 {
   2591     TCGv_i64 t0 = tcg_temp_new_i64();
   2592     TCGv_i64 t1 = tcg_temp_new_i64();
   2593     TCGv_i64 t2 = tcg_temp_new_i64();
   2594     tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
   2595     /* Adjust for negative input for the signed arg1.  */
   2596     tcg_gen_sari_i64(t2, arg1, 63);
   2597     tcg_gen_and_i64(t2, t2, arg2);
   2598     tcg_gen_sub_i64(rh, t1, t2);
   2599     tcg_gen_mov_i64(rl, t0);
   2600     tcg_temp_free_i64(t0);
   2601     tcg_temp_free_i64(t1);
   2602     tcg_temp_free_i64(t2);
   2603 }
   2604 
   2605 void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
   2606 {
   2607     tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
   2608 }
   2609 
   2610 void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
   2611 {
   2612     tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
   2613 }
   2614 
   2615 void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
   2616 {
   2617     tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
   2618 }
   2619 
   2620 void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
   2621 {
   2622     tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
   2623 }
   2624 
   2625 void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
   2626 {
   2627     TCGv_i64 t = tcg_temp_new_i64();
   2628 
   2629     tcg_gen_sari_i64(t, a, 63);
   2630     tcg_gen_xor_i64(ret, a, t);
   2631     tcg_gen_sub_i64(ret, ret, t);
   2632     tcg_temp_free_i64(t);
   2633 }
   2634 
   2635 /* Size changing operations.  */
   2636 
   2637 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
   2638 {
   2639     if (TCG_TARGET_REG_BITS == 32) {
   2640         tcg_gen_mov_i32(ret, TCGV_LOW(arg));
   2641     } else if (TCG_TARGET_HAS_extrl_i64_i32) {
   2642         tcg_gen_op2(INDEX_op_extrl_i64_i32,
   2643                     tcgv_i32_arg(ret), tcgv_i64_arg(arg));
   2644     } else {
   2645         tcg_gen_mov_i32(ret, (TCGv_i32)arg);
   2646     }
   2647 }
   2648 
   2649 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
   2650 {
   2651     if (TCG_TARGET_REG_BITS == 32) {
   2652         tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
   2653     } else if (TCG_TARGET_HAS_extrh_i64_i32) {
   2654         tcg_gen_op2(INDEX_op_extrh_i64_i32,
   2655                     tcgv_i32_arg(ret), tcgv_i64_arg(arg));
   2656     } else {
   2657         TCGv_i64 t = tcg_temp_new_i64();
   2658         tcg_gen_shri_i64(t, arg, 32);
   2659         tcg_gen_mov_i32(ret, (TCGv_i32)t);
   2660         tcg_temp_free_i64(t);
   2661     }
   2662 }
   2663 
   2664 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
   2665 {
   2666     if (TCG_TARGET_REG_BITS == 32) {
   2667         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
   2668         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
   2669     } else {
   2670         tcg_gen_op2(INDEX_op_extu_i32_i64,
   2671                     tcgv_i64_arg(ret), tcgv_i32_arg(arg));
   2672     }
   2673 }
   2674 
   2675 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
   2676 {
   2677     if (TCG_TARGET_REG_BITS == 32) {
   2678         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
   2679         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
   2680     } else {
   2681         tcg_gen_op2(INDEX_op_ext_i32_i64,
   2682                     tcgv_i64_arg(ret), tcgv_i32_arg(arg));
   2683     }
   2684 }
   2685 
   2686 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
   2687 {
   2688     TCGv_i64 tmp;
   2689 
   2690     if (TCG_TARGET_REG_BITS == 32) {
   2691         tcg_gen_mov_i32(TCGV_LOW(dest), low);
   2692         tcg_gen_mov_i32(TCGV_HIGH(dest), high);
   2693         return;
   2694     }
   2695 
   2696     tmp = tcg_temp_new_i64();
   2697     /* These extensions are only needed for type correctness.
   2698        We may be able to do better given target specific information.  */
   2699     tcg_gen_extu_i32_i64(tmp, high);
   2700     tcg_gen_extu_i32_i64(dest, low);
   2701     /* If deposit is available, use it.  Otherwise use the extra
   2702        knowledge that we have of the zero-extensions above.  */
   2703     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
   2704         tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
   2705     } else {
   2706         tcg_gen_shli_i64(tmp, tmp, 32);
   2707         tcg_gen_or_i64(dest, dest, tmp);
   2708     }
   2709     tcg_temp_free_i64(tmp);
   2710 }
   2711 
   2712 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
   2713 {
   2714     if (TCG_TARGET_REG_BITS == 32) {
   2715         tcg_gen_mov_i32(lo, TCGV_LOW(arg));
   2716         tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
   2717     } else {
   2718         tcg_gen_extrl_i64_i32(lo, arg);
   2719         tcg_gen_extrh_i64_i32(hi, arg);
   2720     }
   2721 }
   2722 
   2723 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
   2724 {
   2725     tcg_gen_ext32u_i64(lo, arg);
   2726     tcg_gen_shri_i64(hi, arg, 32);
   2727 }
   2728 
   2729 /* QEMU specific operations.  */
   2730 
   2731 void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
   2732 {
   2733     /*
   2734      * Let the jit code return the read-only version of the
   2735      * TranslationBlock, so that we minimize the pc-relative
   2736      * distance of the address of the exit_tb code to TB.
   2737      * This will improve utilization of pc-relative address loads.
   2738      *
   2739      * TODO: Move this to translator_loop, so that all const
   2740      * TranslationBlock pointers refer to read-only memory.
   2741      * This requires coordination with targets that do not use
   2742      * the translator_loop.
   2743      */
   2744     uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx;
   2745 
   2746     if (tb == NULL) {
   2747         tcg_debug_assert(idx == 0);
   2748     } else if (idx <= TB_EXIT_IDXMAX) {
   2749 #ifdef CONFIG_DEBUG_TCG
   2750         /* This is an exit following a goto_tb.  Verify that we have
   2751            seen this numbered exit before, via tcg_gen_goto_tb.  */
   2752         tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
   2753 #endif
   2754     } else {
   2755         /* This is an exit via the exitreq label.  */
   2756         tcg_debug_assert(idx == TB_EXIT_REQUESTED);
   2757     }
   2758 
   2759     plugin_gen_disable_mem_helpers();
   2760     tcg_gen_op1i(INDEX_op_exit_tb, val);
   2761 }
   2762 
   2763 void tcg_gen_goto_tb(unsigned idx)
   2764 {
   2765     /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
   2766     tcg_debug_assert(!(tcg_ctx->tb_cflags & CF_NO_GOTO_TB));
   2767     /* We only support two chained exits.  */
   2768     tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
   2769 #ifdef CONFIG_DEBUG_TCG
   2770     /* Verify that we haven't seen this numbered exit before.  */
   2771     tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
   2772     tcg_ctx->goto_tb_issue_mask |= 1 << idx;
   2773 #endif
   2774     plugin_gen_disable_mem_helpers();
   2775     tcg_gen_op1i(INDEX_op_goto_tb, idx);
   2776 }
   2777 
   2778 void tcg_gen_lookup_and_goto_ptr(void)
   2779 {
   2780     TCGv_ptr ptr;
   2781 
   2782     if (tcg_ctx->tb_cflags & CF_NO_GOTO_PTR) {
   2783         tcg_gen_exit_tb(NULL, 0);
   2784         return;
   2785     }
   2786 
   2787     plugin_gen_disable_mem_helpers();
   2788     ptr = tcg_temp_new_ptr();
   2789     gen_helper_lookup_tb_ptr(ptr, cpu_env);
   2790     tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
   2791     tcg_temp_free_ptr(ptr);
   2792 }
   2793 
   2794 static inline MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
   2795 {
   2796     /* Trigger the asserts within as early as possible.  */
   2797     unsigned a_bits = get_alignment_bits(op);
   2798 
   2799     /* Prefer MO_ALIGN+MO_XX over MO_ALIGN_XX+MO_XX */
   2800     if (a_bits == (op & MO_SIZE)) {
   2801         op = (op & ~MO_AMASK) | MO_ALIGN;
   2802     }
   2803 
   2804     switch (op & MO_SIZE) {
   2805     case MO_8:
   2806         op &= ~MO_BSWAP;
   2807         break;
   2808     case MO_16:
   2809         break;
   2810     case MO_32:
   2811         if (!is64) {
   2812             op &= ~MO_SIGN;
   2813         }
   2814         break;
   2815     case MO_64:
   2816         if (is64) {
   2817             op &= ~MO_SIGN;
   2818             break;
   2819         }
   2820         /* fall through */
   2821     default:
   2822         g_assert_not_reached();
   2823     }
   2824     if (st) {
   2825         op &= ~MO_SIGN;
   2826     }
   2827     return op;
   2828 }
   2829 
   2830 static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr,
   2831                          MemOp memop, TCGArg idx)
   2832 {
   2833     MemOpIdx oi = make_memop_idx(memop, idx);
   2834 #if TARGET_LONG_BITS == 32
   2835     tcg_gen_op3i_i32(opc, val, addr, oi);
   2836 #else
   2837     if (TCG_TARGET_REG_BITS == 32) {
   2838         tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi);
   2839     } else {
   2840         tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_i64_arg(addr), oi);
   2841     }
   2842 #endif
   2843 }
   2844 
   2845 static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr,
   2846                          MemOp memop, TCGArg idx)
   2847 {
   2848     MemOpIdx oi = make_memop_idx(memop, idx);
   2849 #if TARGET_LONG_BITS == 32
   2850     if (TCG_TARGET_REG_BITS == 32) {
   2851         tcg_gen_op4i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), addr, oi);
   2852     } else {
   2853         tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_i32_arg(addr), oi);
   2854     }
   2855 #else
   2856     if (TCG_TARGET_REG_BITS == 32) {
   2857         tcg_gen_op5i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val),
   2858                          TCGV_LOW(addr), TCGV_HIGH(addr), oi);
   2859     } else {
   2860         tcg_gen_op3i_i64(opc, val, addr, oi);
   2861     }
   2862 #endif
   2863 }
   2864 
   2865 static void tcg_gen_req_mo(TCGBar type)
   2866 {
   2867 #ifdef TCG_GUEST_DEFAULT_MO
   2868     type &= TCG_GUEST_DEFAULT_MO;
   2869 #endif
   2870     type &= ~TCG_TARGET_DEFAULT_MO;
   2871     if (type) {
   2872         tcg_gen_mb(type | TCG_BAR_SC);
   2873     }
   2874 }
   2875 
   2876 static inline TCGv plugin_prep_mem_callbacks(TCGv vaddr)
   2877 {
   2878 #ifdef CONFIG_PLUGIN
   2879     if (tcg_ctx->plugin_insn != NULL) {
   2880         /* Save a copy of the vaddr for use after a load.  */
   2881         TCGv temp = tcg_temp_new();
   2882         tcg_gen_mov_tl(temp, vaddr);
   2883         return temp;
   2884     }
   2885 #endif
   2886     return vaddr;
   2887 }
   2888 
   2889 static void plugin_gen_mem_callbacks(TCGv vaddr, MemOpIdx oi,
   2890                                      enum qemu_plugin_mem_rw rw)
   2891 {
   2892 #ifdef CONFIG_PLUGIN
   2893     if (tcg_ctx->plugin_insn != NULL) {
   2894         qemu_plugin_meminfo_t info = make_plugin_meminfo(oi, rw);
   2895         plugin_gen_empty_mem_callback(vaddr, info);
   2896         tcg_temp_free(vaddr);
   2897     }
   2898 #endif
   2899 }
   2900 
   2901 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
   2902 {
   2903     MemOp orig_memop;
   2904     MemOpIdx oi;
   2905 
   2906     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
   2907     memop = tcg_canonicalize_memop(memop, 0, 0);
   2908     oi = make_memop_idx(memop, idx);
   2909 
   2910     orig_memop = memop;
   2911     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
   2912         memop &= ~MO_BSWAP;
   2913         /* The bswap primitive benefits from zero-extended input.  */
   2914         if ((memop & MO_SSIZE) == MO_SW) {
   2915             memop &= ~MO_SIGN;
   2916         }
   2917     }
   2918 
   2919     addr = plugin_prep_mem_callbacks(addr);
   2920     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
   2921     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_R);
   2922 
   2923     if ((orig_memop ^ memop) & MO_BSWAP) {
   2924         switch (orig_memop & MO_SIZE) {
   2925         case MO_16:
   2926             tcg_gen_bswap16_i32(val, val, (orig_memop & MO_SIGN
   2927                                            ? TCG_BSWAP_IZ | TCG_BSWAP_OS
   2928                                            : TCG_BSWAP_IZ | TCG_BSWAP_OZ));
   2929             break;
   2930         case MO_32:
   2931             tcg_gen_bswap32_i32(val, val);
   2932             break;
   2933         default:
   2934             g_assert_not_reached();
   2935         }
   2936     }
   2937 }
   2938 
   2939 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
   2940 {
   2941     TCGv_i32 swap = NULL;
   2942     MemOpIdx oi;
   2943 
   2944     tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
   2945     memop = tcg_canonicalize_memop(memop, 0, 1);
   2946     oi = make_memop_idx(memop, idx);
   2947 
   2948     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
   2949         swap = tcg_temp_new_i32();
   2950         switch (memop & MO_SIZE) {
   2951         case MO_16:
   2952             tcg_gen_bswap16_i32(swap, val, 0);
   2953             break;
   2954         case MO_32:
   2955             tcg_gen_bswap32_i32(swap, val);
   2956             break;
   2957         default:
   2958             g_assert_not_reached();
   2959         }
   2960         val = swap;
   2961         memop &= ~MO_BSWAP;
   2962     }
   2963 
   2964     addr = plugin_prep_mem_callbacks(addr);
   2965     if (TCG_TARGET_HAS_qemu_st8_i32 && (memop & MO_SIZE) == MO_8) {
   2966         gen_ldst_i32(INDEX_op_qemu_st8_i32, val, addr, memop, idx);
   2967     } else {
   2968         gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
   2969     }
   2970     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_W);
   2971 
   2972     if (swap) {
   2973         tcg_temp_free_i32(swap);
   2974     }
   2975 }
   2976 
   2977 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
   2978 {
   2979     MemOp orig_memop;
   2980     MemOpIdx oi;
   2981 
   2982     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
   2983         tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
   2984         if (memop & MO_SIGN) {
   2985             tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
   2986         } else {
   2987             tcg_gen_movi_i32(TCGV_HIGH(val), 0);
   2988         }
   2989         return;
   2990     }
   2991 
   2992     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
   2993     memop = tcg_canonicalize_memop(memop, 1, 0);
   2994     oi = make_memop_idx(memop, idx);
   2995 
   2996     orig_memop = memop;
   2997     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
   2998         memop &= ~MO_BSWAP;
   2999         /* The bswap primitive benefits from zero-extended input.  */
   3000         if ((memop & MO_SIGN) && (memop & MO_SIZE) < MO_64) {
   3001             memop &= ~MO_SIGN;
   3002         }
   3003     }
   3004 
   3005     addr = plugin_prep_mem_callbacks(addr);
   3006     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx);
   3007     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_R);
   3008 
   3009     if ((orig_memop ^ memop) & MO_BSWAP) {
   3010         int flags = (orig_memop & MO_SIGN
   3011                      ? TCG_BSWAP_IZ | TCG_BSWAP_OS
   3012                      : TCG_BSWAP_IZ | TCG_BSWAP_OZ);
   3013         switch (orig_memop & MO_SIZE) {
   3014         case MO_16:
   3015             tcg_gen_bswap16_i64(val, val, flags);
   3016             break;
   3017         case MO_32:
   3018             tcg_gen_bswap32_i64(val, val, flags);
   3019             break;
   3020         case MO_64:
   3021             tcg_gen_bswap64_i64(val, val);
   3022             break;
   3023         default:
   3024             g_assert_not_reached();
   3025         }
   3026     }
   3027 }
   3028 
   3029 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
   3030 {
   3031     TCGv_i64 swap = NULL;
   3032     MemOpIdx oi;
   3033 
   3034     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
   3035         tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
   3036         return;
   3037     }
   3038 
   3039     tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
   3040     memop = tcg_canonicalize_memop(memop, 1, 1);
   3041     oi = make_memop_idx(memop, idx);
   3042 
   3043     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
   3044         swap = tcg_temp_new_i64();
   3045         switch (memop & MO_SIZE) {
   3046         case MO_16:
   3047             tcg_gen_bswap16_i64(swap, val, 0);
   3048             break;
   3049         case MO_32:
   3050             tcg_gen_bswap32_i64(swap, val, 0);
   3051             break;
   3052         case MO_64:
   3053             tcg_gen_bswap64_i64(swap, val);
   3054             break;
   3055         default:
   3056             g_assert_not_reached();
   3057         }
   3058         val = swap;
   3059         memop &= ~MO_BSWAP;
   3060     }
   3061 
   3062     addr = plugin_prep_mem_callbacks(addr);
   3063     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx);
   3064     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_W);
   3065 
   3066     if (swap) {
   3067         tcg_temp_free_i64(swap);
   3068     }
   3069 }
   3070 
   3071 static void tcg_gen_ext_i32(TCGv_i32 ret, TCGv_i32 val, MemOp opc)
   3072 {
   3073     switch (opc & MO_SSIZE) {
   3074     case MO_SB:
   3075         tcg_gen_ext8s_i32(ret, val);
   3076         break;
   3077     case MO_UB:
   3078         tcg_gen_ext8u_i32(ret, val);
   3079         break;
   3080     case MO_SW:
   3081         tcg_gen_ext16s_i32(ret, val);
   3082         break;
   3083     case MO_UW:
   3084         tcg_gen_ext16u_i32(ret, val);
   3085         break;
   3086     default:
   3087         tcg_gen_mov_i32(ret, val);
   3088         break;
   3089     }
   3090 }
   3091 
   3092 static void tcg_gen_ext_i64(TCGv_i64 ret, TCGv_i64 val, MemOp opc)
   3093 {
   3094     switch (opc & MO_SSIZE) {
   3095     case MO_SB:
   3096         tcg_gen_ext8s_i64(ret, val);
   3097         break;
   3098     case MO_UB:
   3099         tcg_gen_ext8u_i64(ret, val);
   3100         break;
   3101     case MO_SW:
   3102         tcg_gen_ext16s_i64(ret, val);
   3103         break;
   3104     case MO_UW:
   3105         tcg_gen_ext16u_i64(ret, val);
   3106         break;
   3107     case MO_SL:
   3108         tcg_gen_ext32s_i64(ret, val);
   3109         break;
   3110     case MO_UL:
   3111         tcg_gen_ext32u_i64(ret, val);
   3112         break;
   3113     default:
   3114         tcg_gen_mov_i64(ret, val);
   3115         break;
   3116     }
   3117 }
   3118 
   3119 typedef void (*gen_atomic_cx_i32)(TCGv_i32, TCGv_env, TCGv,
   3120                                   TCGv_i32, TCGv_i32, TCGv_i32);
   3121 typedef void (*gen_atomic_cx_i64)(TCGv_i64, TCGv_env, TCGv,
   3122                                   TCGv_i64, TCGv_i64, TCGv_i32);
   3123 typedef void (*gen_atomic_op_i32)(TCGv_i32, TCGv_env, TCGv,
   3124                                   TCGv_i32, TCGv_i32);
   3125 typedef void (*gen_atomic_op_i64)(TCGv_i64, TCGv_env, TCGv,
   3126                                   TCGv_i64, TCGv_i32);
   3127 
   3128 #ifdef CONFIG_ATOMIC64
   3129 # define WITH_ATOMIC64(X) X,
   3130 #else
   3131 # define WITH_ATOMIC64(X)
   3132 #endif
   3133 
   3134 static void * const table_cmpxchg[(MO_SIZE | MO_BSWAP) + 1] = {
   3135     [MO_8] = gen_helper_atomic_cmpxchgb,
   3136     [MO_16 | MO_LE] = gen_helper_atomic_cmpxchgw_le,
   3137     [MO_16 | MO_BE] = gen_helper_atomic_cmpxchgw_be,
   3138     [MO_32 | MO_LE] = gen_helper_atomic_cmpxchgl_le,
   3139     [MO_32 | MO_BE] = gen_helper_atomic_cmpxchgl_be,
   3140     WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_cmpxchgq_le)
   3141     WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_cmpxchgq_be)
   3142 };
   3143 
   3144 void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
   3145                                 TCGv_i32 newv, TCGArg idx, MemOp memop)
   3146 {
   3147     memop = tcg_canonicalize_memop(memop, 0, 0);
   3148 
   3149     if (!(tcg_ctx->tb_cflags & CF_PARALLEL)) {
   3150         TCGv_i32 t1 = tcg_temp_new_i32();
   3151         TCGv_i32 t2 = tcg_temp_new_i32();
   3152 
   3153         tcg_gen_ext_i32(t2, cmpv, memop & MO_SIZE);
   3154 
   3155         tcg_gen_qemu_ld_i32(t1, addr, idx, memop & ~MO_SIGN);
   3156         tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, t2, newv, t1);
   3157         tcg_gen_qemu_st_i32(t2, addr, idx, memop);
   3158         tcg_temp_free_i32(t2);
   3159 
   3160         if (memop & MO_SIGN) {
   3161             tcg_gen_ext_i32(retv, t1, memop);
   3162         } else {
   3163             tcg_gen_mov_i32(retv, t1);
   3164         }
   3165         tcg_temp_free_i32(t1);
   3166     } else {
   3167         gen_atomic_cx_i32 gen;
   3168         MemOpIdx oi;
   3169 
   3170         gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
   3171         tcg_debug_assert(gen != NULL);
   3172 
   3173         oi = make_memop_idx(memop & ~MO_SIGN, idx);
   3174         gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
   3175 
   3176         if (memop & MO_SIGN) {
   3177             tcg_gen_ext_i32(retv, retv, memop);
   3178         }
   3179     }
   3180 }
   3181 
   3182 void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, TCGv_i64 cmpv,
   3183                                 TCGv_i64 newv, TCGArg idx, MemOp memop)
   3184 {
   3185     memop = tcg_canonicalize_memop(memop, 1, 0);
   3186 
   3187     if (!(tcg_ctx->tb_cflags & CF_PARALLEL)) {
   3188         TCGv_i64 t1 = tcg_temp_new_i64();
   3189         TCGv_i64 t2 = tcg_temp_new_i64();
   3190 
   3191         tcg_gen_ext_i64(t2, cmpv, memop & MO_SIZE);
   3192 
   3193         tcg_gen_qemu_ld_i64(t1, addr, idx, memop & ~MO_SIGN);
   3194         tcg_gen_movcond_i64(TCG_COND_EQ, t2, t1, t2, newv, t1);
   3195         tcg_gen_qemu_st_i64(t2, addr, idx, memop);
   3196         tcg_temp_free_i64(t2);
   3197 
   3198         if (memop & MO_SIGN) {
   3199             tcg_gen_ext_i64(retv, t1, memop);
   3200         } else {
   3201             tcg_gen_mov_i64(retv, t1);
   3202         }
   3203         tcg_temp_free_i64(t1);
   3204     } else if ((memop & MO_SIZE) == MO_64) {
   3205 #ifdef CONFIG_ATOMIC64
   3206         gen_atomic_cx_i64 gen;
   3207         MemOpIdx oi;
   3208 
   3209         gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
   3210         tcg_debug_assert(gen != NULL);
   3211 
   3212         oi = make_memop_idx(memop, idx);
   3213         gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
   3214 #else
   3215         gen_helper_exit_atomic(cpu_env);
   3216         /* Produce a result, so that we have a well-formed opcode stream
   3217            with respect to uses of the result in the (dead) code following.  */
   3218         tcg_gen_movi_i64(retv, 0);
   3219 #endif /* CONFIG_ATOMIC64 */
   3220     } else {
   3221         TCGv_i32 c32 = tcg_temp_new_i32();
   3222         TCGv_i32 n32 = tcg_temp_new_i32();
   3223         TCGv_i32 r32 = tcg_temp_new_i32();
   3224 
   3225         tcg_gen_extrl_i64_i32(c32, cmpv);
   3226         tcg_gen_extrl_i64_i32(n32, newv);
   3227         tcg_gen_atomic_cmpxchg_i32(r32, addr, c32, n32, idx, memop & ~MO_SIGN);
   3228         tcg_temp_free_i32(c32);
   3229         tcg_temp_free_i32(n32);
   3230 
   3231         tcg_gen_extu_i32_i64(retv, r32);
   3232         tcg_temp_free_i32(r32);
   3233 
   3234         if (memop & MO_SIGN) {
   3235             tcg_gen_ext_i64(retv, retv, memop);
   3236         }
   3237     }
   3238 }
   3239 
   3240 static void do_nonatomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
   3241                                 TCGArg idx, MemOp memop, bool new_val,
   3242                                 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
   3243 {
   3244     TCGv_i32 t1 = tcg_temp_new_i32();
   3245     TCGv_i32 t2 = tcg_temp_new_i32();
   3246 
   3247     memop = tcg_canonicalize_memop(memop, 0, 0);
   3248 
   3249     tcg_gen_qemu_ld_i32(t1, addr, idx, memop);
   3250     tcg_gen_ext_i32(t2, val, memop);
   3251     gen(t2, t1, t2);
   3252     tcg_gen_qemu_st_i32(t2, addr, idx, memop);
   3253 
   3254     tcg_gen_ext_i32(ret, (new_val ? t2 : t1), memop);
   3255     tcg_temp_free_i32(t1);
   3256     tcg_temp_free_i32(t2);
   3257 }
   3258 
   3259 static void do_atomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
   3260                              TCGArg idx, MemOp memop, void * const table[])
   3261 {
   3262     gen_atomic_op_i32 gen;
   3263     MemOpIdx oi;
   3264 
   3265     memop = tcg_canonicalize_memop(memop, 0, 0);
   3266 
   3267     gen = table[memop & (MO_SIZE | MO_BSWAP)];
   3268     tcg_debug_assert(gen != NULL);
   3269 
   3270     oi = make_memop_idx(memop & ~MO_SIGN, idx);
   3271     gen(ret, cpu_env, addr, val, tcg_constant_i32(oi));
   3272 
   3273     if (memop & MO_SIGN) {
   3274         tcg_gen_ext_i32(ret, ret, memop);
   3275     }
   3276 }
   3277 
   3278 static void do_nonatomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
   3279                                 TCGArg idx, MemOp memop, bool new_val,
   3280                                 void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
   3281 {
   3282     TCGv_i64 t1 = tcg_temp_new_i64();
   3283     TCGv_i64 t2 = tcg_temp_new_i64();
   3284 
   3285     memop = tcg_canonicalize_memop(memop, 1, 0);
   3286 
   3287     tcg_gen_qemu_ld_i64(t1, addr, idx, memop);
   3288     tcg_gen_ext_i64(t2, val, memop);
   3289     gen(t2, t1, t2);
   3290     tcg_gen_qemu_st_i64(t2, addr, idx, memop);
   3291 
   3292     tcg_gen_ext_i64(ret, (new_val ? t2 : t1), memop);
   3293     tcg_temp_free_i64(t1);
   3294     tcg_temp_free_i64(t2);
   3295 }
   3296 
   3297 static void do_atomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
   3298                              TCGArg idx, MemOp memop, void * const table[])
   3299 {
   3300     memop = tcg_canonicalize_memop(memop, 1, 0);
   3301 
   3302     if ((memop & MO_SIZE) == MO_64) {
   3303 #ifdef CONFIG_ATOMIC64
   3304         gen_atomic_op_i64 gen;
   3305         MemOpIdx oi;
   3306 
   3307         gen = table[memop & (MO_SIZE | MO_BSWAP)];
   3308         tcg_debug_assert(gen != NULL);
   3309 
   3310         oi = make_memop_idx(memop & ~MO_SIGN, idx);
   3311         gen(ret, cpu_env, addr, val, tcg_constant_i32(oi));
   3312 #else
   3313         gen_helper_exit_atomic(cpu_env);
   3314         /* Produce a result, so that we have a well-formed opcode stream
   3315            with respect to uses of the result in the (dead) code following.  */
   3316         tcg_gen_movi_i64(ret, 0);
   3317 #endif /* CONFIG_ATOMIC64 */
   3318     } else {
   3319         TCGv_i32 v32 = tcg_temp_new_i32();
   3320         TCGv_i32 r32 = tcg_temp_new_i32();
   3321 
   3322         tcg_gen_extrl_i64_i32(v32, val);
   3323         do_atomic_op_i32(r32, addr, v32, idx, memop & ~MO_SIGN, table);
   3324         tcg_temp_free_i32(v32);
   3325 
   3326         tcg_gen_extu_i32_i64(ret, r32);
   3327         tcg_temp_free_i32(r32);
   3328 
   3329         if (memop & MO_SIGN) {
   3330             tcg_gen_ext_i64(ret, ret, memop);
   3331         }
   3332     }
   3333 }
   3334 
   3335 #define GEN_ATOMIC_HELPER(NAME, OP, NEW)                                \
   3336 static void * const table_##NAME[(MO_SIZE | MO_BSWAP) + 1] = {          \
   3337     [MO_8] = gen_helper_atomic_##NAME##b,                               \
   3338     [MO_16 | MO_LE] = gen_helper_atomic_##NAME##w_le,                   \
   3339     [MO_16 | MO_BE] = gen_helper_atomic_##NAME##w_be,                   \
   3340     [MO_32 | MO_LE] = gen_helper_atomic_##NAME##l_le,                   \
   3341     [MO_32 | MO_BE] = gen_helper_atomic_##NAME##l_be,                   \
   3342     WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_##NAME##q_le)     \
   3343     WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_##NAME##q_be)     \
   3344 };                                                                      \
   3345 void tcg_gen_atomic_##NAME##_i32                                        \
   3346     (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, MemOp memop)    \
   3347 {                                                                       \
   3348     if (tcg_ctx->tb_cflags & CF_PARALLEL) {                             \
   3349         do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME);     \
   3350     } else {                                                            \
   3351         do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW,            \
   3352                             tcg_gen_##OP##_i32);                        \
   3353     }                                                                   \
   3354 }                                                                       \
   3355 void tcg_gen_atomic_##NAME##_i64                                        \
   3356     (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, MemOp memop)    \
   3357 {                                                                       \
   3358     if (tcg_ctx->tb_cflags & CF_PARALLEL) {                             \
   3359         do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME);     \
   3360     } else {                                                            \
   3361         do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW,            \
   3362                             tcg_gen_##OP##_i64);                        \
   3363     }                                                                   \
   3364 }
   3365 
   3366 GEN_ATOMIC_HELPER(fetch_add, add, 0)
   3367 GEN_ATOMIC_HELPER(fetch_and, and, 0)
   3368 GEN_ATOMIC_HELPER(fetch_or, or, 0)
   3369 GEN_ATOMIC_HELPER(fetch_xor, xor, 0)
   3370 GEN_ATOMIC_HELPER(fetch_smin, smin, 0)
   3371 GEN_ATOMIC_HELPER(fetch_umin, umin, 0)
   3372 GEN_ATOMIC_HELPER(fetch_smax, smax, 0)
   3373 GEN_ATOMIC_HELPER(fetch_umax, umax, 0)
   3374 
   3375 GEN_ATOMIC_HELPER(add_fetch, add, 1)
   3376 GEN_ATOMIC_HELPER(and_fetch, and, 1)
   3377 GEN_ATOMIC_HELPER(or_fetch, or, 1)
   3378 GEN_ATOMIC_HELPER(xor_fetch, xor, 1)
   3379 GEN_ATOMIC_HELPER(smin_fetch, smin, 1)
   3380 GEN_ATOMIC_HELPER(umin_fetch, umin, 1)
   3381 GEN_ATOMIC_HELPER(smax_fetch, smax, 1)
   3382 GEN_ATOMIC_HELPER(umax_fetch, umax, 1)
   3383 
   3384 static void tcg_gen_mov2_i32(TCGv_i32 r, TCGv_i32 a, TCGv_i32 b)
   3385 {
   3386     tcg_gen_mov_i32(r, b);
   3387 }
   3388 
   3389 static void tcg_gen_mov2_i64(TCGv_i64 r, TCGv_i64 a, TCGv_i64 b)
   3390 {
   3391     tcg_gen_mov_i64(r, b);
   3392 }
   3393 
   3394 GEN_ATOMIC_HELPER(xchg, mov2, 0)
   3395 
   3396 #undef GEN_ATOMIC_HELPER