qemu/tcg/tci/tcg-target.c
<<
>>
Prefs
   1/*
   2 * Tiny Code Generator for QEMU
   3 *
   4 * Copyright (c) 2009, 2011 Stefan Weil
   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/* TODO list:
  26 * - See TODO comments in code.
  27 */
  28
  29/* Marker for missing code. */
  30#define TODO() \
  31    do { \
  32        fprintf(stderr, "TODO %s:%u: %s()\n", \
  33                __FILE__, __LINE__, __func__); \
  34        tcg_abort(); \
  35    } while (0)
  36
  37/* Single bit n. */
  38#define BIT(n) (1 << (n))
  39
  40/* Bitfield n...m (in 32 bit value). */
  41#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
  42
  43/* Used for function call generation. */
  44#define TCG_REG_CALL_STACK              TCG_REG_R4
  45#define TCG_TARGET_STACK_ALIGN          16
  46#define TCG_TARGET_CALL_STACK_OFFSET    0
  47
  48/* TODO: documentation. */
  49static uint8_t *tb_ret_addr;
  50
  51/* Macros used in tcg_target_op_defs. */
  52#define R       "r"
  53#define RI      "ri"
  54#if TCG_TARGET_REG_BITS == 32
  55# define R64    "r", "r"
  56#else
  57# define R64    "r"
  58#endif
  59#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
  60# define L      "L", "L"
  61# define S      "S", "S"
  62#else
  63# define L      "L"
  64# define S      "S"
  65#endif
  66
  67/* TODO: documentation. */
  68static const TCGTargetOpDef tcg_target_op_defs[] = {
  69    { INDEX_op_exit_tb, { NULL } },
  70    { INDEX_op_goto_tb, { NULL } },
  71    { INDEX_op_call, { RI } },
  72    { INDEX_op_jmp, { RI } },
  73    { INDEX_op_br, { NULL } },
  74
  75    { INDEX_op_mov_i32, { R, R } },
  76    { INDEX_op_movi_i32, { R } },
  77
  78    { INDEX_op_ld8u_i32, { R, R } },
  79    { INDEX_op_ld8s_i32, { R, R } },
  80    { INDEX_op_ld16u_i32, { R, R } },
  81    { INDEX_op_ld16s_i32, { R, R } },
  82    { INDEX_op_ld_i32, { R, R } },
  83    { INDEX_op_st8_i32, { R, R } },
  84    { INDEX_op_st16_i32, { R, R } },
  85    { INDEX_op_st_i32, { R, R } },
  86
  87    { INDEX_op_add_i32, { R, RI, RI } },
  88    { INDEX_op_sub_i32, { R, RI, RI } },
  89    { INDEX_op_mul_i32, { R, RI, RI } },
  90#if TCG_TARGET_HAS_div_i32
  91    { INDEX_op_div_i32, { R, R, R } },
  92    { INDEX_op_divu_i32, { R, R, R } },
  93    { INDEX_op_rem_i32, { R, R, R } },
  94    { INDEX_op_remu_i32, { R, R, R } },
  95#elif TCG_TARGET_HAS_div2_i32
  96    { INDEX_op_div2_i32, { R, R, "0", "1", R } },
  97    { INDEX_op_divu2_i32, { R, R, "0", "1", R } },
  98#endif
  99    /* TODO: Does R, RI, RI result in faster code than R, R, RI?
 100       If both operands are constants, we can optimize. */
 101    { INDEX_op_and_i32, { R, RI, RI } },
 102#if TCG_TARGET_HAS_andc_i32
 103    { INDEX_op_andc_i32, { R, RI, RI } },
 104#endif
 105#if TCG_TARGET_HAS_eqv_i32
 106    { INDEX_op_eqv_i32, { R, RI, RI } },
 107#endif
 108#if TCG_TARGET_HAS_nand_i32
 109    { INDEX_op_nand_i32, { R, RI, RI } },
 110#endif
 111#if TCG_TARGET_HAS_nor_i32
 112    { INDEX_op_nor_i32, { R, RI, RI } },
 113#endif
 114    { INDEX_op_or_i32, { R, RI, RI } },
 115#if TCG_TARGET_HAS_orc_i32
 116    { INDEX_op_orc_i32, { R, RI, RI } },
 117#endif
 118    { INDEX_op_xor_i32, { R, RI, RI } },
 119    { INDEX_op_shl_i32, { R, RI, RI } },
 120    { INDEX_op_shr_i32, { R, RI, RI } },
 121    { INDEX_op_sar_i32, { R, RI, RI } },
 122#if TCG_TARGET_HAS_rot_i32
 123    { INDEX_op_rotl_i32, { R, RI, RI } },
 124    { INDEX_op_rotr_i32, { R, RI, RI } },
 125#endif
 126
 127    { INDEX_op_brcond_i32, { R, RI } },
 128
 129    { INDEX_op_setcond_i32, { R, R, RI } },
 130#if TCG_TARGET_REG_BITS == 64
 131    { INDEX_op_setcond_i64, { R, R, RI } },
 132#endif /* TCG_TARGET_REG_BITS == 64 */
 133
 134#if TCG_TARGET_REG_BITS == 32
 135    /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
 136    { INDEX_op_add2_i32, { R, R, R, R, R, R } },
 137    { INDEX_op_sub2_i32, { R, R, R, R, R, R } },
 138    { INDEX_op_brcond2_i32, { R, R, RI, RI } },
 139    { INDEX_op_mulu2_i32, { R, R, R, R } },
 140    { INDEX_op_setcond2_i32, { R, R, R, RI, RI } },
 141#endif
 142
 143#if TCG_TARGET_HAS_not_i32
 144    { INDEX_op_not_i32, { R, R } },
 145#endif
 146#if TCG_TARGET_HAS_neg_i32
 147    { INDEX_op_neg_i32, { R, R } },
 148#endif
 149
 150#if TCG_TARGET_REG_BITS == 64
 151    { INDEX_op_mov_i64, { R, R } },
 152    { INDEX_op_movi_i64, { R } },
 153
 154    { INDEX_op_ld8u_i64, { R, R } },
 155    { INDEX_op_ld8s_i64, { R, R } },
 156    { INDEX_op_ld16u_i64, { R, R } },
 157    { INDEX_op_ld16s_i64, { R, R } },
 158    { INDEX_op_ld32u_i64, { R, R } },
 159    { INDEX_op_ld32s_i64, { R, R } },
 160    { INDEX_op_ld_i64, { R, R } },
 161
 162    { INDEX_op_st8_i64, { R, R } },
 163    { INDEX_op_st16_i64, { R, R } },
 164    { INDEX_op_st32_i64, { R, R } },
 165    { INDEX_op_st_i64, { R, R } },
 166
 167    { INDEX_op_add_i64, { R, RI, RI } },
 168    { INDEX_op_sub_i64, { R, RI, RI } },
 169    { INDEX_op_mul_i64, { R, RI, RI } },
 170#if TCG_TARGET_HAS_div_i64
 171    { INDEX_op_div_i64, { R, R, R } },
 172    { INDEX_op_divu_i64, { R, R, R } },
 173    { INDEX_op_rem_i64, { R, R, R } },
 174    { INDEX_op_remu_i64, { R, R, R } },
 175#elif TCG_TARGET_HAS_div2_i64
 176    { INDEX_op_div2_i64, { R, R, "0", "1", R } },
 177    { INDEX_op_divu2_i64, { R, R, "0", "1", R } },
 178#endif
 179    { INDEX_op_and_i64, { R, RI, RI } },
 180#if TCG_TARGET_HAS_andc_i64
 181    { INDEX_op_andc_i64, { R, RI, RI } },
 182#endif
 183#if TCG_TARGET_HAS_eqv_i64
 184    { INDEX_op_eqv_i64, { R, RI, RI } },
 185#endif
 186#if TCG_TARGET_HAS_nand_i64
 187    { INDEX_op_nand_i64, { R, RI, RI } },
 188#endif
 189#if TCG_TARGET_HAS_nor_i64
 190    { INDEX_op_nor_i64, { R, RI, RI } },
 191#endif
 192    { INDEX_op_or_i64, { R, RI, RI } },
 193#if TCG_TARGET_HAS_orc_i64
 194    { INDEX_op_orc_i64, { R, RI, RI } },
 195#endif
 196    { INDEX_op_xor_i64, { R, RI, RI } },
 197    { INDEX_op_shl_i64, { R, RI, RI } },
 198    { INDEX_op_shr_i64, { R, RI, RI } },
 199    { INDEX_op_sar_i64, { R, RI, RI } },
 200#if TCG_TARGET_HAS_rot_i64
 201    { INDEX_op_rotl_i64, { R, RI, RI } },
 202    { INDEX_op_rotr_i64, { R, RI, RI } },
 203#endif
 204    { INDEX_op_brcond_i64, { R, RI } },
 205
 206#if TCG_TARGET_HAS_ext8s_i64
 207    { INDEX_op_ext8s_i64, { R, R } },
 208#endif
 209#if TCG_TARGET_HAS_ext16s_i64
 210    { INDEX_op_ext16s_i64, { R, R } },
 211#endif
 212#if TCG_TARGET_HAS_ext32s_i64
 213    { INDEX_op_ext32s_i64, { R, R } },
 214#endif
 215#if TCG_TARGET_HAS_ext8u_i64
 216    { INDEX_op_ext8u_i64, { R, R } },
 217#endif
 218#if TCG_TARGET_HAS_ext16u_i64
 219    { INDEX_op_ext16u_i64, { R, R } },
 220#endif
 221#if TCG_TARGET_HAS_ext32u_i64
 222    { INDEX_op_ext32u_i64, { R, R } },
 223#endif
 224#if TCG_TARGET_HAS_bswap16_i64
 225    { INDEX_op_bswap16_i64, { R, R } },
 226#endif
 227#if TCG_TARGET_HAS_bswap32_i64
 228    { INDEX_op_bswap32_i64, { R, R } },
 229#endif
 230#if TCG_TARGET_HAS_bswap64_i64
 231    { INDEX_op_bswap64_i64, { R, R } },
 232#endif
 233#if TCG_TARGET_HAS_not_i64
 234    { INDEX_op_not_i64, { R, R } },
 235#endif
 236#if TCG_TARGET_HAS_neg_i64
 237    { INDEX_op_neg_i64, { R, R } },
 238#endif
 239#endif /* TCG_TARGET_REG_BITS == 64 */
 240
 241    { INDEX_op_qemu_ld8u, { R, L } },
 242    { INDEX_op_qemu_ld8s, { R, L } },
 243    { INDEX_op_qemu_ld16u, { R, L } },
 244    { INDEX_op_qemu_ld16s, { R, L } },
 245    { INDEX_op_qemu_ld32, { R, L } },
 246#if TCG_TARGET_REG_BITS == 64
 247    { INDEX_op_qemu_ld32u, { R, L } },
 248    { INDEX_op_qemu_ld32s, { R, L } },
 249#endif
 250    { INDEX_op_qemu_ld64, { R64, L } },
 251
 252    { INDEX_op_qemu_st8, { R, S } },
 253    { INDEX_op_qemu_st16, { R, S } },
 254    { INDEX_op_qemu_st32, { R, S } },
 255    { INDEX_op_qemu_st64, { R64, S } },
 256
 257#if TCG_TARGET_HAS_ext8s_i32
 258    { INDEX_op_ext8s_i32, { R, R } },
 259#endif
 260#if TCG_TARGET_HAS_ext16s_i32
 261    { INDEX_op_ext16s_i32, { R, R } },
 262#endif
 263#if TCG_TARGET_HAS_ext8u_i32
 264    { INDEX_op_ext8u_i32, { R, R } },
 265#endif
 266#if TCG_TARGET_HAS_ext16u_i32
 267    { INDEX_op_ext16u_i32, { R, R } },
 268#endif
 269
 270#if TCG_TARGET_HAS_bswap16_i32
 271    { INDEX_op_bswap16_i32, { R, R } },
 272#endif
 273#if TCG_TARGET_HAS_bswap32_i32
 274    { INDEX_op_bswap32_i32, { R, R } },
 275#endif
 276
 277    { -1 },
 278};
 279
 280static const int tcg_target_reg_alloc_order[] = {
 281    TCG_REG_R0,
 282    TCG_REG_R1,
 283    TCG_REG_R2,
 284    TCG_REG_R3,
 285#if 0 /* used for TCG_REG_CALL_STACK */
 286    TCG_REG_R4,
 287#endif
 288    TCG_REG_R5,
 289    TCG_REG_R6,
 290    TCG_REG_R7,
 291#if TCG_TARGET_NB_REGS >= 16
 292    TCG_REG_R8,
 293    TCG_REG_R9,
 294    TCG_REG_R10,
 295    TCG_REG_R11,
 296    TCG_REG_R12,
 297    TCG_REG_R13,
 298    TCG_REG_R14,
 299    TCG_REG_R15,
 300#endif
 301};
 302
 303#if MAX_OPC_PARAM_IARGS != 4
 304# error Fix needed, number of supported input arguments changed!
 305#endif
 306
 307static const int tcg_target_call_iarg_regs[] = {
 308    TCG_REG_R0,
 309    TCG_REG_R1,
 310    TCG_REG_R2,
 311    TCG_REG_R3,
 312#if TCG_TARGET_REG_BITS == 32
 313    /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
 314#if 0 /* used for TCG_REG_CALL_STACK */
 315    TCG_REG_R4,
 316#endif
 317    TCG_REG_R5,
 318    TCG_REG_R6,
 319    TCG_REG_R7,
 320#if TCG_TARGET_NB_REGS >= 16
 321    TCG_REG_R8,
 322#else
 323# error Too few input registers available
 324#endif
 325#endif
 326};
 327
 328static const int tcg_target_call_oarg_regs[] = {
 329    TCG_REG_R0,
 330#if TCG_TARGET_REG_BITS == 32
 331    TCG_REG_R1
 332#endif
 333};
 334
 335#ifndef NDEBUG
 336static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 337    "r00",
 338    "r01",
 339    "r02",
 340    "r03",
 341    "r04",
 342    "r05",
 343    "r06",
 344    "r07",
 345#if TCG_TARGET_NB_REGS >= 16
 346    "r08",
 347    "r09",
 348    "r10",
 349    "r11",
 350    "r12",
 351    "r13",
 352    "r14",
 353    "r15",
 354#if TCG_TARGET_NB_REGS >= 32
 355    "r16",
 356    "r17",
 357    "r18",
 358    "r19",
 359    "r20",
 360    "r21",
 361    "r22",
 362    "r23",
 363    "r24",
 364    "r25",
 365    "r26",
 366    "r27",
 367    "r28",
 368    "r29",
 369    "r30",
 370    "r31"
 371#endif
 372#endif
 373};
 374#endif
 375
 376static void patch_reloc(uint8_t *code_ptr, int type,
 377                        tcg_target_long value, tcg_target_long addend)
 378{
 379    /* tcg_out_reloc always uses the same type, addend. */
 380    assert(type == sizeof(tcg_target_long));
 381    assert(addend == 0);
 382    assert(value != 0);
 383    *(tcg_target_long *)code_ptr = value;
 384}
 385
 386/* Parse target specific constraints. */
 387static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 388{
 389    const char *ct_str = *pct_str;
 390    switch (ct_str[0]) {
 391    case 'r':
 392    case 'L':                   /* qemu_ld constraint */
 393    case 'S':                   /* qemu_st constraint */
 394        ct->ct |= TCG_CT_REG;
 395        tcg_regset_set32(ct->u.regs, 0, BIT(TCG_TARGET_NB_REGS) - 1);
 396        break;
 397    default:
 398        return -1;
 399    }
 400    ct_str++;
 401    *pct_str = ct_str;
 402    return 0;
 403}
 404
 405#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
 406/* Show current bytecode. Used by tcg interpreter. */
 407void tci_disas(uint8_t opc)
 408{
 409    const TCGOpDef *def = &tcg_op_defs[opc];
 410    fprintf(stderr, "TCG %s %u, %u, %u\n",
 411            def->name, def->nb_oargs, def->nb_iargs, def->nb_cargs);
 412}
 413#endif
 414
 415/* Write value (native size). */
 416static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
 417{
 418    *(tcg_target_ulong *)s->code_ptr = v;
 419    s->code_ptr += sizeof(tcg_target_ulong);
 420}
 421
 422/* Write 64 bit value. */
 423static void tcg_out64(TCGContext *s, uint64_t v)
 424{
 425    *(uint64_t *)s->code_ptr = v;
 426    s->code_ptr += sizeof(v);
 427}
 428
 429/* Write opcode. */
 430static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
 431{
 432    tcg_out8(s, op);
 433    tcg_out8(s, 0);
 434}
 435
 436/* Write register. */
 437static void tcg_out_r(TCGContext *s, TCGArg t0)
 438{
 439    assert(t0 < TCG_TARGET_NB_REGS);
 440    tcg_out8(s, t0);
 441}
 442
 443/* Write register or constant (native size). */
 444static void tcg_out_ri(TCGContext *s, int const_arg, TCGArg arg)
 445{
 446    if (const_arg) {
 447        assert(const_arg == 1);
 448        tcg_out8(s, TCG_CONST);
 449        tcg_out_i(s, arg);
 450    } else {
 451        tcg_out_r(s, arg);
 452    }
 453}
 454
 455/* Write register or constant (32 bit). */
 456static void tcg_out_ri32(TCGContext *s, int const_arg, TCGArg arg)
 457{
 458    if (const_arg) {
 459        assert(const_arg == 1);
 460        tcg_out8(s, TCG_CONST);
 461        tcg_out32(s, arg);
 462    } else {
 463        tcg_out_r(s, arg);
 464    }
 465}
 466
 467#if TCG_TARGET_REG_BITS == 64
 468/* Write register or constant (64 bit). */
 469static void tcg_out_ri64(TCGContext *s, int const_arg, TCGArg arg)
 470{
 471    if (const_arg) {
 472        assert(const_arg == 1);
 473        tcg_out8(s, TCG_CONST);
 474        tcg_out64(s, arg);
 475    } else {
 476        tcg_out_r(s, arg);
 477    }
 478}
 479#endif
 480
 481/* Write label. */
 482static void tci_out_label(TCGContext *s, TCGArg arg)
 483{
 484    TCGLabel *label = &s->labels[arg];
 485    if (label->has_value) {
 486        tcg_out_i(s, label->u.value);
 487        assert(label->u.value);
 488    } else {
 489        tcg_out_reloc(s, s->code_ptr, sizeof(tcg_target_ulong), arg, 0);
 490        tcg_out_i(s, 0);
 491    }
 492}
 493
 494static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
 495                       tcg_target_long arg2)
 496{
 497    uint8_t *old_code_ptr = s->code_ptr;
 498    if (type == TCG_TYPE_I32) {
 499        tcg_out_op_t(s, INDEX_op_ld_i32);
 500        tcg_out_r(s, ret);
 501        tcg_out_r(s, arg1);
 502        tcg_out32(s, arg2);
 503    } else {
 504        assert(type == TCG_TYPE_I64);
 505#if TCG_TARGET_REG_BITS == 64
 506        tcg_out_op_t(s, INDEX_op_ld_i64);
 507        tcg_out_r(s, ret);
 508        tcg_out_r(s, arg1);
 509        assert(arg2 == (uint32_t)arg2);
 510        tcg_out32(s, arg2);
 511#else
 512        TODO();
 513#endif
 514    }
 515    old_code_ptr[1] = s->code_ptr - old_code_ptr;
 516}
 517
 518static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 519{
 520    uint8_t *old_code_ptr = s->code_ptr;
 521    assert(ret != arg);
 522#if TCG_TARGET_REG_BITS == 32
 523    tcg_out_op_t(s, INDEX_op_mov_i32);
 524#else
 525    tcg_out_op_t(s, INDEX_op_mov_i64);
 526#endif
 527    tcg_out_r(s, ret);
 528    tcg_out_r(s, arg);
 529    old_code_ptr[1] = s->code_ptr - old_code_ptr;
 530}
 531
 532static void tcg_out_movi(TCGContext *s, TCGType type,
 533                         TCGReg t0, tcg_target_long arg)
 534{
 535    uint8_t *old_code_ptr = s->code_ptr;
 536    uint32_t arg32 = arg;
 537    if (type == TCG_TYPE_I32 || arg == arg32) {
 538        tcg_out_op_t(s, INDEX_op_movi_i32);
 539        tcg_out_r(s, t0);
 540        tcg_out32(s, arg32);
 541    } else {
 542        assert(type == TCG_TYPE_I64);
 543#if TCG_TARGET_REG_BITS == 64
 544        tcg_out_op_t(s, INDEX_op_movi_i64);
 545        tcg_out_r(s, t0);
 546        tcg_out64(s, arg);
 547#else
 548        TODO();
 549#endif
 550    }
 551    old_code_ptr[1] = s->code_ptr - old_code_ptr;
 552}
 553
 554static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
 555                       const int *const_args)
 556{
 557    uint8_t *old_code_ptr = s->code_ptr;
 558
 559    tcg_out_op_t(s, opc);
 560
 561    switch (opc) {
 562    case INDEX_op_exit_tb:
 563        tcg_out64(s, args[0]);
 564        break;
 565    case INDEX_op_goto_tb:
 566        if (s->tb_jmp_offset) {
 567            /* Direct jump method. */
 568            assert(args[0] < ARRAY_SIZE(s->tb_jmp_offset));
 569            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
 570            tcg_out32(s, 0);
 571        } else {
 572            /* Indirect jump method. */
 573            TODO();
 574        }
 575        assert(args[0] < ARRAY_SIZE(s->tb_next_offset));
 576        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
 577        break;
 578    case INDEX_op_br:
 579        tci_out_label(s, args[0]);
 580        break;
 581    case INDEX_op_call:
 582        tcg_out_ri(s, const_args[0], args[0]);
 583        break;
 584    case INDEX_op_jmp:
 585        TODO();
 586        break;
 587    case INDEX_op_setcond_i32:
 588        tcg_out_r(s, args[0]);
 589        tcg_out_r(s, args[1]);
 590        tcg_out_ri32(s, const_args[2], args[2]);
 591        tcg_out8(s, args[3]);   /* condition */
 592        break;
 593#if TCG_TARGET_REG_BITS == 32
 594    case INDEX_op_setcond2_i32:
 595        /* setcond2_i32 cond, t0, t1_low, t1_high, t2_low, t2_high */
 596        tcg_out_r(s, args[0]);
 597        tcg_out_r(s, args[1]);
 598        tcg_out_r(s, args[2]);
 599        tcg_out_ri32(s, const_args[3], args[3]);
 600        tcg_out_ri32(s, const_args[4], args[4]);
 601        tcg_out8(s, args[5]);   /* condition */
 602        break;
 603#elif TCG_TARGET_REG_BITS == 64
 604    case INDEX_op_setcond_i64:
 605        tcg_out_r(s, args[0]);
 606        tcg_out_r(s, args[1]);
 607        tcg_out_ri64(s, const_args[2], args[2]);
 608        tcg_out8(s, args[3]);   /* condition */
 609        break;
 610#endif
 611    case INDEX_op_movi_i32:
 612        TODO(); /* Handled by tcg_out_movi? */
 613        break;
 614    case INDEX_op_ld8u_i32:
 615    case INDEX_op_ld8s_i32:
 616    case INDEX_op_ld16u_i32:
 617    case INDEX_op_ld16s_i32:
 618    case INDEX_op_ld_i32:
 619    case INDEX_op_st8_i32:
 620    case INDEX_op_st16_i32:
 621    case INDEX_op_st_i32:
 622    case INDEX_op_ld8u_i64:
 623    case INDEX_op_ld8s_i64:
 624    case INDEX_op_ld16u_i64:
 625    case INDEX_op_ld16s_i64:
 626    case INDEX_op_ld32u_i64:
 627    case INDEX_op_ld32s_i64:
 628    case INDEX_op_ld_i64:
 629    case INDEX_op_st8_i64:
 630    case INDEX_op_st16_i64:
 631    case INDEX_op_st32_i64:
 632    case INDEX_op_st_i64:
 633        tcg_out_r(s, args[0]);
 634        tcg_out_r(s, args[1]);
 635        assert(args[2] == (uint32_t)args[2]);
 636        tcg_out32(s, args[2]);
 637        break;
 638    case INDEX_op_add_i32:
 639    case INDEX_op_sub_i32:
 640    case INDEX_op_mul_i32:
 641    case INDEX_op_and_i32:
 642    case INDEX_op_andc_i32:     /* Optional (TCG_TARGET_HAS_andc_i32). */
 643    case INDEX_op_eqv_i32:      /* Optional (TCG_TARGET_HAS_eqv_i32). */
 644    case INDEX_op_nand_i32:     /* Optional (TCG_TARGET_HAS_nand_i32). */
 645    case INDEX_op_nor_i32:      /* Optional (TCG_TARGET_HAS_nor_i32). */
 646    case INDEX_op_or_i32:
 647    case INDEX_op_orc_i32:      /* Optional (TCG_TARGET_HAS_orc_i32). */
 648    case INDEX_op_xor_i32:
 649    case INDEX_op_shl_i32:
 650    case INDEX_op_shr_i32:
 651    case INDEX_op_sar_i32:
 652    case INDEX_op_rotl_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */
 653    case INDEX_op_rotr_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */
 654        tcg_out_r(s, args[0]);
 655        tcg_out_ri32(s, const_args[1], args[1]);
 656        tcg_out_ri32(s, const_args[2], args[2]);
 657        break;
 658
 659#if TCG_TARGET_REG_BITS == 64
 660    case INDEX_op_mov_i64:
 661    case INDEX_op_movi_i64:
 662        TODO();
 663        break;
 664    case INDEX_op_add_i64:
 665    case INDEX_op_sub_i64:
 666    case INDEX_op_mul_i64:
 667    case INDEX_op_and_i64:
 668    case INDEX_op_andc_i64:     /* Optional (TCG_TARGET_HAS_andc_i64). */
 669    case INDEX_op_eqv_i64:      /* Optional (TCG_TARGET_HAS_eqv_i64). */
 670    case INDEX_op_nand_i64:     /* Optional (TCG_TARGET_HAS_nand_i64). */
 671    case INDEX_op_nor_i64:      /* Optional (TCG_TARGET_HAS_nor_i64). */
 672    case INDEX_op_or_i64:
 673    case INDEX_op_orc_i64:      /* Optional (TCG_TARGET_HAS_orc_i64). */
 674    case INDEX_op_xor_i64:
 675    case INDEX_op_shl_i64:
 676    case INDEX_op_shr_i64:
 677    case INDEX_op_sar_i64:
 678        /* TODO: Implementation of rotl_i64, rotr_i64 missing in tci.c. */
 679    case INDEX_op_rotl_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */
 680    case INDEX_op_rotr_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */
 681        tcg_out_r(s, args[0]);
 682        tcg_out_ri64(s, const_args[1], args[1]);
 683        tcg_out_ri64(s, const_args[2], args[2]);
 684        break;
 685    case INDEX_op_div_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
 686    case INDEX_op_divu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
 687    case INDEX_op_rem_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
 688    case INDEX_op_remu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
 689        TODO();
 690        break;
 691    case INDEX_op_div2_i64:     /* Optional (TCG_TARGET_HAS_div2_i64). */
 692    case INDEX_op_divu2_i64:    /* Optional (TCG_TARGET_HAS_div2_i64). */
 693        TODO();
 694        break;
 695    case INDEX_op_brcond_i64:
 696        tcg_out_r(s, args[0]);
 697        tcg_out_ri64(s, const_args[1], args[1]);
 698        tcg_out8(s, args[2]);           /* condition */
 699        tci_out_label(s, args[3]);
 700        break;
 701    case INDEX_op_bswap16_i64:  /* Optional (TCG_TARGET_HAS_bswap16_i64). */
 702    case INDEX_op_bswap32_i64:  /* Optional (TCG_TARGET_HAS_bswap32_i64). */
 703    case INDEX_op_bswap64_i64:  /* Optional (TCG_TARGET_HAS_bswap64_i64). */
 704    case INDEX_op_not_i64:      /* Optional (TCG_TARGET_HAS_not_i64). */
 705    case INDEX_op_neg_i64:      /* Optional (TCG_TARGET_HAS_neg_i64). */
 706    case INDEX_op_ext8s_i64:    /* Optional (TCG_TARGET_HAS_ext8s_i64). */
 707    case INDEX_op_ext8u_i64:    /* Optional (TCG_TARGET_HAS_ext8u_i64). */
 708    case INDEX_op_ext16s_i64:   /* Optional (TCG_TARGET_HAS_ext16s_i64). */
 709    case INDEX_op_ext16u_i64:   /* Optional (TCG_TARGET_HAS_ext16u_i64). */
 710    case INDEX_op_ext32s_i64:   /* Optional (TCG_TARGET_HAS_ext32s_i64). */
 711    case INDEX_op_ext32u_i64:   /* Optional (TCG_TARGET_HAS_ext32u_i64). */
 712#endif /* TCG_TARGET_REG_BITS == 64 */
 713    case INDEX_op_neg_i32:      /* Optional (TCG_TARGET_HAS_neg_i32). */
 714    case INDEX_op_not_i32:      /* Optional (TCG_TARGET_HAS_not_i32). */
 715    case INDEX_op_ext8s_i32:    /* Optional (TCG_TARGET_HAS_ext8s_i32). */
 716    case INDEX_op_ext16s_i32:   /* Optional (TCG_TARGET_HAS_ext16s_i32). */
 717    case INDEX_op_ext8u_i32:    /* Optional (TCG_TARGET_HAS_ext8u_i32). */
 718    case INDEX_op_ext16u_i32:   /* Optional (TCG_TARGET_HAS_ext16u_i32). */
 719    case INDEX_op_bswap16_i32:  /* Optional (TCG_TARGET_HAS_bswap16_i32). */
 720    case INDEX_op_bswap32_i32:  /* Optional (TCG_TARGET_HAS_bswap32_i32). */
 721        tcg_out_r(s, args[0]);
 722        tcg_out_r(s, args[1]);
 723        break;
 724    case INDEX_op_div_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */
 725    case INDEX_op_divu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */
 726    case INDEX_op_rem_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */
 727    case INDEX_op_remu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */
 728        tcg_out_r(s, args[0]);
 729        tcg_out_ri32(s, const_args[1], args[1]);
 730        tcg_out_ri32(s, const_args[2], args[2]);
 731        break;
 732    case INDEX_op_div2_i32:     /* Optional (TCG_TARGET_HAS_div2_i32). */
 733    case INDEX_op_divu2_i32:    /* Optional (TCG_TARGET_HAS_div2_i32). */
 734        TODO();
 735        break;
 736#if TCG_TARGET_REG_BITS == 32
 737    case INDEX_op_add2_i32:
 738    case INDEX_op_sub2_i32:
 739        tcg_out_r(s, args[0]);
 740        tcg_out_r(s, args[1]);
 741        tcg_out_r(s, args[2]);
 742        tcg_out_r(s, args[3]);
 743        tcg_out_r(s, args[4]);
 744        tcg_out_r(s, args[5]);
 745        break;
 746    case INDEX_op_brcond2_i32:
 747        tcg_out_r(s, args[0]);
 748        tcg_out_r(s, args[1]);
 749        tcg_out_ri32(s, const_args[2], args[2]);
 750        tcg_out_ri32(s, const_args[3], args[3]);
 751        tcg_out8(s, args[4]);           /* condition */
 752        tci_out_label(s, args[5]);
 753        break;
 754    case INDEX_op_mulu2_i32:
 755        tcg_out_r(s, args[0]);
 756        tcg_out_r(s, args[1]);
 757        tcg_out_r(s, args[2]);
 758        tcg_out_r(s, args[3]);
 759        break;
 760#endif
 761    case INDEX_op_brcond_i32:
 762        tcg_out_r(s, args[0]);
 763        tcg_out_ri32(s, const_args[1], args[1]);
 764        tcg_out8(s, args[2]);           /* condition */
 765        tci_out_label(s, args[3]);
 766        break;
 767    case INDEX_op_qemu_ld8u:
 768    case INDEX_op_qemu_ld8s:
 769    case INDEX_op_qemu_ld16u:
 770    case INDEX_op_qemu_ld16s:
 771    case INDEX_op_qemu_ld32:
 772#if TCG_TARGET_REG_BITS == 64
 773    case INDEX_op_qemu_ld32s:
 774    case INDEX_op_qemu_ld32u:
 775#endif
 776        tcg_out_r(s, *args++);
 777        tcg_out_r(s, *args++);
 778#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
 779        tcg_out_r(s, *args++);
 780#endif
 781#ifdef CONFIG_SOFTMMU
 782        tcg_out_i(s, *args);
 783#endif
 784        break;
 785    case INDEX_op_qemu_ld64:
 786        tcg_out_r(s, *args++);
 787#if TCG_TARGET_REG_BITS == 32
 788        tcg_out_r(s, *args++);
 789#endif
 790        tcg_out_r(s, *args++);
 791#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
 792        tcg_out_r(s, *args++);
 793#endif
 794#ifdef CONFIG_SOFTMMU
 795        tcg_out_i(s, *args);
 796#endif
 797        break;
 798    case INDEX_op_qemu_st8:
 799    case INDEX_op_qemu_st16:
 800    case INDEX_op_qemu_st32:
 801#ifdef CONFIG_TCG_PASS_AREG0
 802        tcg_out_r(s, TCG_AREG0);
 803#endif
 804        tcg_out_r(s, *args++);
 805        tcg_out_r(s, *args++);
 806#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
 807        tcg_out_r(s, *args++);
 808#endif
 809#ifdef CONFIG_SOFTMMU
 810        tcg_out_i(s, *args);
 811#endif
 812        break;
 813    case INDEX_op_qemu_st64:
 814#ifdef CONFIG_TCG_PASS_AREG0
 815        tcg_out_r(s, TCG_AREG0);
 816#endif
 817        tcg_out_r(s, *args++);
 818#if TCG_TARGET_REG_BITS == 32
 819        tcg_out_r(s, *args++);
 820#endif
 821        tcg_out_r(s, *args++);
 822#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
 823        tcg_out_r(s, *args++);
 824#endif
 825#ifdef CONFIG_SOFTMMU
 826        tcg_out_i(s, *args);
 827#endif
 828        break;
 829    case INDEX_op_end:
 830        TODO();
 831        break;
 832    default:
 833        fprintf(stderr, "Missing: %s\n", tcg_op_defs[opc].name);
 834        tcg_abort();
 835    }
 836    old_code_ptr[1] = s->code_ptr - old_code_ptr;
 837}
 838
 839static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
 840                       tcg_target_long arg2)
 841{
 842    uint8_t *old_code_ptr = s->code_ptr;
 843    if (type == TCG_TYPE_I32) {
 844        tcg_out_op_t(s, INDEX_op_st_i32);
 845        tcg_out_r(s, arg);
 846        tcg_out_r(s, arg1);
 847        tcg_out32(s, arg2);
 848    } else {
 849        assert(type == TCG_TYPE_I64);
 850#if TCG_TARGET_REG_BITS == 64
 851        tcg_out_op_t(s, INDEX_op_st_i64);
 852        tcg_out_r(s, arg);
 853        tcg_out_r(s, arg1);
 854        tcg_out32(s, arg2);
 855#else
 856        TODO();
 857#endif
 858    }
 859    old_code_ptr[1] = s->code_ptr - old_code_ptr;
 860}
 861
 862/* Test if a constant matches the constraint. */
 863static int tcg_target_const_match(tcg_target_long val,
 864                                  const TCGArgConstraint *arg_ct)
 865{
 866    /* No need to return 0 or 1, 0 or != 0 is good enough. */
 867    return arg_ct->ct & TCG_CT_CONST;
 868}
 869
 870/* Maximum number of register used for input function arguments. */
 871static int tcg_target_get_call_iarg_regs_count(int flags)
 872{
 873    return ARRAY_SIZE(tcg_target_call_iarg_regs);
 874}
 875
 876static void tcg_target_init(TCGContext *s)
 877{
 878#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
 879    const char *envval = getenv("DEBUG_TCG");
 880    if (envval) {
 881        loglevel = strtol(envval, NULL, 0);
 882    }
 883#endif
 884
 885    /* The current code uses uint8_t for tcg operations. */
 886    assert(ARRAY_SIZE(tcg_op_defs) <= UINT8_MAX);
 887
 888    /* Registers available for 32 bit operations. */
 889    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0,
 890                     BIT(TCG_TARGET_NB_REGS) - 1);
 891    /* Registers available for 64 bit operations. */
 892    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0,
 893                     BIT(TCG_TARGET_NB_REGS) - 1);
 894    /* TODO: Which registers should be set here? */
 895    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
 896                     BIT(TCG_TARGET_NB_REGS) - 1);
 897    tcg_regset_clear(s->reserved_regs);
 898    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
 899    tcg_add_target_add_op_defs(tcg_target_op_defs);
 900    tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
 901                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 902}
 903
 904/* Generate global QEMU prologue and epilogue code. */
 905static void tcg_target_qemu_prologue(TCGContext *s)
 906{
 907    tb_ret_addr = s->code_ptr;
 908}
 909