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