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