qemu/tcg/tci.c
<<
>>
Prefs
   1/*
   2 * Tiny Code Interpreter for QEMU
   3 *
   4 * Copyright (c) 2009, 2011, 2016 Stefan Weil
   5 *
   6 * This program is free software: you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation, either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "tcg/tcg.h"           /* MAX_OPC_PARAM_IARGS */
  22#include "exec/cpu_ldst.h"
  23#include "tcg/tcg-op.h"
  24#include "tcg/tcg-ldst.h"
  25#include "qemu/compiler.h"
  26#include <ffi.h>
  27
  28
  29/*
  30 * Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
  31 * Without assertions, the interpreter runs much faster.
  32 */
  33#if defined(CONFIG_DEBUG_TCG)
  34# define tci_assert(cond) assert(cond)
  35#else
  36# define tci_assert(cond) ((void)(cond))
  37#endif
  38
  39__thread uintptr_t tci_tb_ptr;
  40
  41static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
  42                            uint32_t low_index, uint64_t value)
  43{
  44    regs[low_index] = (uint32_t)value;
  45    regs[high_index] = value >> 32;
  46}
  47
  48/* Create a 64 bit value from two 32 bit values. */
  49static uint64_t tci_uint64(uint32_t high, uint32_t low)
  50{
  51    return ((uint64_t)high << 32) + low;
  52}
  53
  54/*
  55 * Load sets of arguments all at once.  The naming convention is:
  56 *   tci_args_<arguments>
  57 * where arguments is a sequence of
  58 *
  59 *   b = immediate (bit position)
  60 *   c = condition (TCGCond)
  61 *   i = immediate (uint32_t)
  62 *   I = immediate (tcg_target_ulong)
  63 *   l = label or pointer
  64 *   m = immediate (MemOpIdx)
  65 *   n = immediate (call return length)
  66 *   r = register
  67 *   s = signed ldst offset
  68 */
  69
  70static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
  71{
  72    int diff = sextract32(insn, 12, 20);
  73    *l0 = diff ? (void *)tb_ptr + diff : NULL;
  74}
  75
  76static void tci_args_r(uint32_t insn, TCGReg *r0)
  77{
  78    *r0 = extract32(insn, 8, 4);
  79}
  80
  81static void tci_args_nl(uint32_t insn, const void *tb_ptr,
  82                        uint8_t *n0, void **l1)
  83{
  84    *n0 = extract32(insn, 8, 4);
  85    *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
  86}
  87
  88static void tci_args_rl(uint32_t insn, const void *tb_ptr,
  89                        TCGReg *r0, void **l1)
  90{
  91    *r0 = extract32(insn, 8, 4);
  92    *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
  93}
  94
  95static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
  96{
  97    *r0 = extract32(insn, 8, 4);
  98    *r1 = extract32(insn, 12, 4);
  99}
 100
 101static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
 102{
 103    *r0 = extract32(insn, 8, 4);
 104    *i1 = sextract32(insn, 12, 20);
 105}
 106
 107static void tci_args_rrm(uint32_t insn, TCGReg *r0,
 108                         TCGReg *r1, MemOpIdx *m2)
 109{
 110    *r0 = extract32(insn, 8, 4);
 111    *r1 = extract32(insn, 12, 4);
 112    *m2 = extract32(insn, 20, 12);
 113}
 114
 115static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
 116{
 117    *r0 = extract32(insn, 8, 4);
 118    *r1 = extract32(insn, 12, 4);
 119    *r2 = extract32(insn, 16, 4);
 120}
 121
 122static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
 123{
 124    *r0 = extract32(insn, 8, 4);
 125    *r1 = extract32(insn, 12, 4);
 126    *i2 = sextract32(insn, 16, 16);
 127}
 128
 129static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
 130                          uint8_t *i2, uint8_t *i3)
 131{
 132    *r0 = extract32(insn, 8, 4);
 133    *r1 = extract32(insn, 12, 4);
 134    *i2 = extract32(insn, 16, 6);
 135    *i3 = extract32(insn, 22, 6);
 136}
 137
 138static void tci_args_rrrc(uint32_t insn,
 139                          TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
 140{
 141    *r0 = extract32(insn, 8, 4);
 142    *r1 = extract32(insn, 12, 4);
 143    *r2 = extract32(insn, 16, 4);
 144    *c3 = extract32(insn, 20, 4);
 145}
 146
 147static void tci_args_rrrm(uint32_t insn,
 148                          TCGReg *r0, TCGReg *r1, TCGReg *r2, MemOpIdx *m3)
 149{
 150    *r0 = extract32(insn, 8, 4);
 151    *r1 = extract32(insn, 12, 4);
 152    *r2 = extract32(insn, 16, 4);
 153    *m3 = extract32(insn, 20, 12);
 154}
 155
 156static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
 157                           TCGReg *r2, uint8_t *i3, uint8_t *i4)
 158{
 159    *r0 = extract32(insn, 8, 4);
 160    *r1 = extract32(insn, 12, 4);
 161    *r2 = extract32(insn, 16, 4);
 162    *i3 = extract32(insn, 20, 6);
 163    *i4 = extract32(insn, 26, 6);
 164}
 165
 166static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
 167                           TCGReg *r2, TCGReg *r3, TCGReg *r4)
 168{
 169    *r0 = extract32(insn, 8, 4);
 170    *r1 = extract32(insn, 12, 4);
 171    *r2 = extract32(insn, 16, 4);
 172    *r3 = extract32(insn, 20, 4);
 173    *r4 = extract32(insn, 24, 4);
 174}
 175
 176static void tci_args_rrrr(uint32_t insn,
 177                          TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
 178{
 179    *r0 = extract32(insn, 8, 4);
 180    *r1 = extract32(insn, 12, 4);
 181    *r2 = extract32(insn, 16, 4);
 182    *r3 = extract32(insn, 20, 4);
 183}
 184
 185static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
 186                            TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
 187{
 188    *r0 = extract32(insn, 8, 4);
 189    *r1 = extract32(insn, 12, 4);
 190    *r2 = extract32(insn, 16, 4);
 191    *r3 = extract32(insn, 20, 4);
 192    *r4 = extract32(insn, 24, 4);
 193    *c5 = extract32(insn, 28, 4);
 194}
 195
 196static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
 197                            TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
 198{
 199    *r0 = extract32(insn, 8, 4);
 200    *r1 = extract32(insn, 12, 4);
 201    *r2 = extract32(insn, 16, 4);
 202    *r3 = extract32(insn, 20, 4);
 203    *r4 = extract32(insn, 24, 4);
 204    *r5 = extract32(insn, 28, 4);
 205}
 206
 207static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
 208{
 209    bool result = false;
 210    int32_t i0 = u0;
 211    int32_t i1 = u1;
 212    switch (condition) {
 213    case TCG_COND_EQ:
 214        result = (u0 == u1);
 215        break;
 216    case TCG_COND_NE:
 217        result = (u0 != u1);
 218        break;
 219    case TCG_COND_LT:
 220        result = (i0 < i1);
 221        break;
 222    case TCG_COND_GE:
 223        result = (i0 >= i1);
 224        break;
 225    case TCG_COND_LE:
 226        result = (i0 <= i1);
 227        break;
 228    case TCG_COND_GT:
 229        result = (i0 > i1);
 230        break;
 231    case TCG_COND_LTU:
 232        result = (u0 < u1);
 233        break;
 234    case TCG_COND_GEU:
 235        result = (u0 >= u1);
 236        break;
 237    case TCG_COND_LEU:
 238        result = (u0 <= u1);
 239        break;
 240    case TCG_COND_GTU:
 241        result = (u0 > u1);
 242        break;
 243    default:
 244        g_assert_not_reached();
 245    }
 246    return result;
 247}
 248
 249static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
 250{
 251    bool result = false;
 252    int64_t i0 = u0;
 253    int64_t i1 = u1;
 254    switch (condition) {
 255    case TCG_COND_EQ:
 256        result = (u0 == u1);
 257        break;
 258    case TCG_COND_NE:
 259        result = (u0 != u1);
 260        break;
 261    case TCG_COND_LT:
 262        result = (i0 < i1);
 263        break;
 264    case TCG_COND_GE:
 265        result = (i0 >= i1);
 266        break;
 267    case TCG_COND_LE:
 268        result = (i0 <= i1);
 269        break;
 270    case TCG_COND_GT:
 271        result = (i0 > i1);
 272        break;
 273    case TCG_COND_LTU:
 274        result = (u0 < u1);
 275        break;
 276    case TCG_COND_GEU:
 277        result = (u0 >= u1);
 278        break;
 279    case TCG_COND_LEU:
 280        result = (u0 <= u1);
 281        break;
 282    case TCG_COND_GTU:
 283        result = (u0 > u1);
 284        break;
 285    default:
 286        g_assert_not_reached();
 287    }
 288    return result;
 289}
 290
 291static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
 292                            MemOpIdx oi, const void *tb_ptr)
 293{
 294    MemOp mop = get_memop(oi);
 295    uintptr_t ra = (uintptr_t)tb_ptr;
 296
 297#ifdef CONFIG_SOFTMMU
 298    switch (mop & (MO_BSWAP | MO_SSIZE)) {
 299    case MO_UB:
 300        return helper_ret_ldub_mmu(env, taddr, oi, ra);
 301    case MO_SB:
 302        return helper_ret_ldsb_mmu(env, taddr, oi, ra);
 303    case MO_LEUW:
 304        return helper_le_lduw_mmu(env, taddr, oi, ra);
 305    case MO_LESW:
 306        return helper_le_ldsw_mmu(env, taddr, oi, ra);
 307    case MO_LEUL:
 308        return helper_le_ldul_mmu(env, taddr, oi, ra);
 309    case MO_LESL:
 310        return helper_le_ldsl_mmu(env, taddr, oi, ra);
 311    case MO_LEUQ:
 312        return helper_le_ldq_mmu(env, taddr, oi, ra);
 313    case MO_BEUW:
 314        return helper_be_lduw_mmu(env, taddr, oi, ra);
 315    case MO_BESW:
 316        return helper_be_ldsw_mmu(env, taddr, oi, ra);
 317    case MO_BEUL:
 318        return helper_be_ldul_mmu(env, taddr, oi, ra);
 319    case MO_BESL:
 320        return helper_be_ldsl_mmu(env, taddr, oi, ra);
 321    case MO_BEUQ:
 322        return helper_be_ldq_mmu(env, taddr, oi, ra);
 323    default:
 324        g_assert_not_reached();
 325    }
 326#else
 327    void *haddr = g2h(env_cpu(env), taddr);
 328    unsigned a_mask = (1u << get_alignment_bits(mop)) - 1;
 329    uint64_t ret;
 330
 331    set_helper_retaddr(ra);
 332    if (taddr & a_mask) {
 333        helper_unaligned_ld(env, taddr);
 334    }
 335    switch (mop & (MO_BSWAP | MO_SSIZE)) {
 336    case MO_UB:
 337        ret = ldub_p(haddr);
 338        break;
 339    case MO_SB:
 340        ret = ldsb_p(haddr);
 341        break;
 342    case MO_LEUW:
 343        ret = lduw_le_p(haddr);
 344        break;
 345    case MO_LESW:
 346        ret = ldsw_le_p(haddr);
 347        break;
 348    case MO_LEUL:
 349        ret = (uint32_t)ldl_le_p(haddr);
 350        break;
 351    case MO_LESL:
 352        ret = (int32_t)ldl_le_p(haddr);
 353        break;
 354    case MO_LEUQ:
 355        ret = ldq_le_p(haddr);
 356        break;
 357    case MO_BEUW:
 358        ret = lduw_be_p(haddr);
 359        break;
 360    case MO_BESW:
 361        ret = ldsw_be_p(haddr);
 362        break;
 363    case MO_BEUL:
 364        ret = (uint32_t)ldl_be_p(haddr);
 365        break;
 366    case MO_BESL:
 367        ret = (int32_t)ldl_be_p(haddr);
 368        break;
 369    case MO_BEUQ:
 370        ret = ldq_be_p(haddr);
 371        break;
 372    default:
 373        g_assert_not_reached();
 374    }
 375    clear_helper_retaddr();
 376    return ret;
 377#endif
 378}
 379
 380static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
 381                        MemOpIdx oi, const void *tb_ptr)
 382{
 383    MemOp mop = get_memop(oi);
 384    uintptr_t ra = (uintptr_t)tb_ptr;
 385
 386#ifdef CONFIG_SOFTMMU
 387    switch (mop & (MO_BSWAP | MO_SIZE)) {
 388    case MO_UB:
 389        helper_ret_stb_mmu(env, taddr, val, oi, ra);
 390        break;
 391    case MO_LEUW:
 392        helper_le_stw_mmu(env, taddr, val, oi, ra);
 393        break;
 394    case MO_LEUL:
 395        helper_le_stl_mmu(env, taddr, val, oi, ra);
 396        break;
 397    case MO_LEUQ:
 398        helper_le_stq_mmu(env, taddr, val, oi, ra);
 399        break;
 400    case MO_BEUW:
 401        helper_be_stw_mmu(env, taddr, val, oi, ra);
 402        break;
 403    case MO_BEUL:
 404        helper_be_stl_mmu(env, taddr, val, oi, ra);
 405        break;
 406    case MO_BEUQ:
 407        helper_be_stq_mmu(env, taddr, val, oi, ra);
 408        break;
 409    default:
 410        g_assert_not_reached();
 411    }
 412#else
 413    void *haddr = g2h(env_cpu(env), taddr);
 414    unsigned a_mask = (1u << get_alignment_bits(mop)) - 1;
 415
 416    set_helper_retaddr(ra);
 417    if (taddr & a_mask) {
 418        helper_unaligned_st(env, taddr);
 419    }
 420    switch (mop & (MO_BSWAP | MO_SIZE)) {
 421    case MO_UB:
 422        stb_p(haddr, val);
 423        break;
 424    case MO_LEUW:
 425        stw_le_p(haddr, val);
 426        break;
 427    case MO_LEUL:
 428        stl_le_p(haddr, val);
 429        break;
 430    case MO_LEUQ:
 431        stq_le_p(haddr, val);
 432        break;
 433    case MO_BEUW:
 434        stw_be_p(haddr, val);
 435        break;
 436    case MO_BEUL:
 437        stl_be_p(haddr, val);
 438        break;
 439    case MO_BEUQ:
 440        stq_be_p(haddr, val);
 441        break;
 442    default:
 443        g_assert_not_reached();
 444    }
 445    clear_helper_retaddr();
 446#endif
 447}
 448
 449#if TCG_TARGET_REG_BITS == 64
 450# define CASE_32_64(x) \
 451        case glue(glue(INDEX_op_, x), _i64): \
 452        case glue(glue(INDEX_op_, x), _i32):
 453# define CASE_64(x) \
 454        case glue(glue(INDEX_op_, x), _i64):
 455#else
 456# define CASE_32_64(x) \
 457        case glue(glue(INDEX_op_, x), _i32):
 458# define CASE_64(x)
 459#endif
 460
 461/* Interpret pseudo code in tb. */
 462/*
 463 * Disable CFI checks.
 464 * One possible operation in the pseudo code is a call to binary code.
 465 * Therefore, disable CFI checks in the interpreter function
 466 */
 467uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
 468                                            const void *v_tb_ptr)
 469{
 470    const uint32_t *tb_ptr = v_tb_ptr;
 471    tcg_target_ulong regs[TCG_TARGET_NB_REGS];
 472    uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
 473                   / sizeof(uint64_t)];
 474    void *call_slots[TCG_STATIC_CALL_ARGS_SIZE / sizeof(uint64_t)];
 475
 476    regs[TCG_AREG0] = (tcg_target_ulong)env;
 477    regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
 478    /* Other call_slots entries initialized at first use (see below). */
 479    call_slots[0] = NULL;
 480    tci_assert(tb_ptr);
 481
 482    for (;;) {
 483        uint32_t insn;
 484        TCGOpcode opc;
 485        TCGReg r0, r1, r2, r3, r4, r5;
 486        tcg_target_ulong t1;
 487        TCGCond condition;
 488        target_ulong taddr;
 489        uint8_t pos, len;
 490        uint32_t tmp32;
 491        uint64_t tmp64;
 492        uint64_t T1, T2;
 493        MemOpIdx oi;
 494        int32_t ofs;
 495        void *ptr;
 496
 497        insn = *tb_ptr++;
 498        opc = extract32(insn, 0, 8);
 499
 500        switch (opc) {
 501        case INDEX_op_call:
 502            /*
 503             * Set up the ffi_avalue array once, delayed until now
 504             * because many TB's do not make any calls. In tcg_gen_callN,
 505             * we arranged for every real argument to be "left-aligned"
 506             * in each 64-bit slot.
 507             */
 508            if (unlikely(call_slots[0] == NULL)) {
 509                for (int i = 0; i < ARRAY_SIZE(call_slots); ++i) {
 510                    call_slots[i] = &stack[i];
 511                }
 512            }
 513
 514            tci_args_nl(insn, tb_ptr, &len, &ptr);
 515
 516            /* Helper functions may need to access the "return address" */
 517            tci_tb_ptr = (uintptr_t)tb_ptr;
 518
 519            {
 520                void **pptr = ptr;
 521                ffi_call(pptr[1], pptr[0], stack, call_slots);
 522            }
 523
 524            /* Any result winds up "left-aligned" in the stack[0] slot. */
 525            switch (len) {
 526            case 0: /* void */
 527                break;
 528            case 1: /* uint32_t */
 529                /*
 530                 * Note that libffi has an odd special case in that it will
 531                 * always widen an integral result to ffi_arg.
 532                 */
 533                if (sizeof(ffi_arg) == 4) {
 534                    regs[TCG_REG_R0] = *(uint32_t *)stack;
 535                    break;
 536                }
 537                /* fall through */
 538            case 2: /* uint64_t */
 539                if (TCG_TARGET_REG_BITS == 32) {
 540                    tci_write_reg64(regs, TCG_REG_R1, TCG_REG_R0, stack[0]);
 541                } else {
 542                    regs[TCG_REG_R0] = stack[0];
 543                }
 544                break;
 545            default:
 546                g_assert_not_reached();
 547            }
 548            break;
 549
 550        case INDEX_op_br:
 551            tci_args_l(insn, tb_ptr, &ptr);
 552            tb_ptr = ptr;
 553            continue;
 554        case INDEX_op_setcond_i32:
 555            tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
 556            regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
 557            break;
 558        case INDEX_op_movcond_i32:
 559            tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
 560            tmp32 = tci_compare32(regs[r1], regs[r2], condition);
 561            regs[r0] = regs[tmp32 ? r3 : r4];
 562            break;
 563#if TCG_TARGET_REG_BITS == 32
 564        case INDEX_op_setcond2_i32:
 565            tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
 566            T1 = tci_uint64(regs[r2], regs[r1]);
 567            T2 = tci_uint64(regs[r4], regs[r3]);
 568            regs[r0] = tci_compare64(T1, T2, condition);
 569            break;
 570#elif TCG_TARGET_REG_BITS == 64
 571        case INDEX_op_setcond_i64:
 572            tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
 573            regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
 574            break;
 575        case INDEX_op_movcond_i64:
 576            tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
 577            tmp32 = tci_compare64(regs[r1], regs[r2], condition);
 578            regs[r0] = regs[tmp32 ? r3 : r4];
 579            break;
 580#endif
 581        CASE_32_64(mov)
 582            tci_args_rr(insn, &r0, &r1);
 583            regs[r0] = regs[r1];
 584            break;
 585        case INDEX_op_tci_movi:
 586            tci_args_ri(insn, &r0, &t1);
 587            regs[r0] = t1;
 588            break;
 589        case INDEX_op_tci_movl:
 590            tci_args_rl(insn, tb_ptr, &r0, &ptr);
 591            regs[r0] = *(tcg_target_ulong *)ptr;
 592            break;
 593
 594            /* Load/store operations (32 bit). */
 595
 596        CASE_32_64(ld8u)
 597            tci_args_rrs(insn, &r0, &r1, &ofs);
 598            ptr = (void *)(regs[r1] + ofs);
 599            regs[r0] = *(uint8_t *)ptr;
 600            break;
 601        CASE_32_64(ld8s)
 602            tci_args_rrs(insn, &r0, &r1, &ofs);
 603            ptr = (void *)(regs[r1] + ofs);
 604            regs[r0] = *(int8_t *)ptr;
 605            break;
 606        CASE_32_64(ld16u)
 607            tci_args_rrs(insn, &r0, &r1, &ofs);
 608            ptr = (void *)(regs[r1] + ofs);
 609            regs[r0] = *(uint16_t *)ptr;
 610            break;
 611        CASE_32_64(ld16s)
 612            tci_args_rrs(insn, &r0, &r1, &ofs);
 613            ptr = (void *)(regs[r1] + ofs);
 614            regs[r0] = *(int16_t *)ptr;
 615            break;
 616        case INDEX_op_ld_i32:
 617        CASE_64(ld32u)
 618            tci_args_rrs(insn, &r0, &r1, &ofs);
 619            ptr = (void *)(regs[r1] + ofs);
 620            regs[r0] = *(uint32_t *)ptr;
 621            break;
 622        CASE_32_64(st8)
 623            tci_args_rrs(insn, &r0, &r1, &ofs);
 624            ptr = (void *)(regs[r1] + ofs);
 625            *(uint8_t *)ptr = regs[r0];
 626            break;
 627        CASE_32_64(st16)
 628            tci_args_rrs(insn, &r0, &r1, &ofs);
 629            ptr = (void *)(regs[r1] + ofs);
 630            *(uint16_t *)ptr = regs[r0];
 631            break;
 632        case INDEX_op_st_i32:
 633        CASE_64(st32)
 634            tci_args_rrs(insn, &r0, &r1, &ofs);
 635            ptr = (void *)(regs[r1] + ofs);
 636            *(uint32_t *)ptr = regs[r0];
 637            break;
 638
 639            /* Arithmetic operations (mixed 32/64 bit). */
 640
 641        CASE_32_64(add)
 642            tci_args_rrr(insn, &r0, &r1, &r2);
 643            regs[r0] = regs[r1] + regs[r2];
 644            break;
 645        CASE_32_64(sub)
 646            tci_args_rrr(insn, &r0, &r1, &r2);
 647            regs[r0] = regs[r1] - regs[r2];
 648            break;
 649        CASE_32_64(mul)
 650            tci_args_rrr(insn, &r0, &r1, &r2);
 651            regs[r0] = regs[r1] * regs[r2];
 652            break;
 653        CASE_32_64(and)
 654            tci_args_rrr(insn, &r0, &r1, &r2);
 655            regs[r0] = regs[r1] & regs[r2];
 656            break;
 657        CASE_32_64(or)
 658            tci_args_rrr(insn, &r0, &r1, &r2);
 659            regs[r0] = regs[r1] | regs[r2];
 660            break;
 661        CASE_32_64(xor)
 662            tci_args_rrr(insn, &r0, &r1, &r2);
 663            regs[r0] = regs[r1] ^ regs[r2];
 664            break;
 665#if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64
 666        CASE_32_64(andc)
 667            tci_args_rrr(insn, &r0, &r1, &r2);
 668            regs[r0] = regs[r1] & ~regs[r2];
 669            break;
 670#endif
 671#if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64
 672        CASE_32_64(orc)
 673            tci_args_rrr(insn, &r0, &r1, &r2);
 674            regs[r0] = regs[r1] | ~regs[r2];
 675            break;
 676#endif
 677#if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64
 678        CASE_32_64(eqv)
 679            tci_args_rrr(insn, &r0, &r1, &r2);
 680            regs[r0] = ~(regs[r1] ^ regs[r2]);
 681            break;
 682#endif
 683#if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64
 684        CASE_32_64(nand)
 685            tci_args_rrr(insn, &r0, &r1, &r2);
 686            regs[r0] = ~(regs[r1] & regs[r2]);
 687            break;
 688#endif
 689#if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64
 690        CASE_32_64(nor)
 691            tci_args_rrr(insn, &r0, &r1, &r2);
 692            regs[r0] = ~(regs[r1] | regs[r2]);
 693            break;
 694#endif
 695
 696            /* Arithmetic operations (32 bit). */
 697
 698        case INDEX_op_div_i32:
 699            tci_args_rrr(insn, &r0, &r1, &r2);
 700            regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
 701            break;
 702        case INDEX_op_divu_i32:
 703            tci_args_rrr(insn, &r0, &r1, &r2);
 704            regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
 705            break;
 706        case INDEX_op_rem_i32:
 707            tci_args_rrr(insn, &r0, &r1, &r2);
 708            regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
 709            break;
 710        case INDEX_op_remu_i32:
 711            tci_args_rrr(insn, &r0, &r1, &r2);
 712            regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
 713            break;
 714#if TCG_TARGET_HAS_clz_i32
 715        case INDEX_op_clz_i32:
 716            tci_args_rrr(insn, &r0, &r1, &r2);
 717            tmp32 = regs[r1];
 718            regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
 719            break;
 720#endif
 721#if TCG_TARGET_HAS_ctz_i32
 722        case INDEX_op_ctz_i32:
 723            tci_args_rrr(insn, &r0, &r1, &r2);
 724            tmp32 = regs[r1];
 725            regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
 726            break;
 727#endif
 728#if TCG_TARGET_HAS_ctpop_i32
 729        case INDEX_op_ctpop_i32:
 730            tci_args_rr(insn, &r0, &r1);
 731            regs[r0] = ctpop32(regs[r1]);
 732            break;
 733#endif
 734
 735            /* Shift/rotate operations (32 bit). */
 736
 737        case INDEX_op_shl_i32:
 738            tci_args_rrr(insn, &r0, &r1, &r2);
 739            regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
 740            break;
 741        case INDEX_op_shr_i32:
 742            tci_args_rrr(insn, &r0, &r1, &r2);
 743            regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
 744            break;
 745        case INDEX_op_sar_i32:
 746            tci_args_rrr(insn, &r0, &r1, &r2);
 747            regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
 748            break;
 749#if TCG_TARGET_HAS_rot_i32
 750        case INDEX_op_rotl_i32:
 751            tci_args_rrr(insn, &r0, &r1, &r2);
 752            regs[r0] = rol32(regs[r1], regs[r2] & 31);
 753            break;
 754        case INDEX_op_rotr_i32:
 755            tci_args_rrr(insn, &r0, &r1, &r2);
 756            regs[r0] = ror32(regs[r1], regs[r2] & 31);
 757            break;
 758#endif
 759#if TCG_TARGET_HAS_deposit_i32
 760        case INDEX_op_deposit_i32:
 761            tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
 762            regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
 763            break;
 764#endif
 765#if TCG_TARGET_HAS_extract_i32
 766        case INDEX_op_extract_i32:
 767            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
 768            regs[r0] = extract32(regs[r1], pos, len);
 769            break;
 770#endif
 771#if TCG_TARGET_HAS_sextract_i32
 772        case INDEX_op_sextract_i32:
 773            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
 774            regs[r0] = sextract32(regs[r1], pos, len);
 775            break;
 776#endif
 777        case INDEX_op_brcond_i32:
 778            tci_args_rl(insn, tb_ptr, &r0, &ptr);
 779            if ((uint32_t)regs[r0]) {
 780                tb_ptr = ptr;
 781            }
 782            break;
 783#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
 784        case INDEX_op_add2_i32:
 785            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
 786            T1 = tci_uint64(regs[r3], regs[r2]);
 787            T2 = tci_uint64(regs[r5], regs[r4]);
 788            tci_write_reg64(regs, r1, r0, T1 + T2);
 789            break;
 790#endif
 791#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
 792        case INDEX_op_sub2_i32:
 793            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
 794            T1 = tci_uint64(regs[r3], regs[r2]);
 795            T2 = tci_uint64(regs[r5], regs[r4]);
 796            tci_write_reg64(regs, r1, r0, T1 - T2);
 797            break;
 798#endif
 799#if TCG_TARGET_HAS_mulu2_i32
 800        case INDEX_op_mulu2_i32:
 801            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
 802            tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
 803            tci_write_reg64(regs, r1, r0, tmp64);
 804            break;
 805#endif
 806#if TCG_TARGET_HAS_muls2_i32
 807        case INDEX_op_muls2_i32:
 808            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
 809            tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
 810            tci_write_reg64(regs, r1, r0, tmp64);
 811            break;
 812#endif
 813#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
 814        CASE_32_64(ext8s)
 815            tci_args_rr(insn, &r0, &r1);
 816            regs[r0] = (int8_t)regs[r1];
 817            break;
 818#endif
 819#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64 || \
 820    TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
 821        CASE_32_64(ext16s)
 822            tci_args_rr(insn, &r0, &r1);
 823            regs[r0] = (int16_t)regs[r1];
 824            break;
 825#endif
 826#if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
 827        CASE_32_64(ext8u)
 828            tci_args_rr(insn, &r0, &r1);
 829            regs[r0] = (uint8_t)regs[r1];
 830            break;
 831#endif
 832#if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
 833        CASE_32_64(ext16u)
 834            tci_args_rr(insn, &r0, &r1);
 835            regs[r0] = (uint16_t)regs[r1];
 836            break;
 837#endif
 838#if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
 839        CASE_32_64(bswap16)
 840            tci_args_rr(insn, &r0, &r1);
 841            regs[r0] = bswap16(regs[r1]);
 842            break;
 843#endif
 844#if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
 845        CASE_32_64(bswap32)
 846            tci_args_rr(insn, &r0, &r1);
 847            regs[r0] = bswap32(regs[r1]);
 848            break;
 849#endif
 850#if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
 851        CASE_32_64(not)
 852            tci_args_rr(insn, &r0, &r1);
 853            regs[r0] = ~regs[r1];
 854            break;
 855#endif
 856#if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64
 857        CASE_32_64(neg)
 858            tci_args_rr(insn, &r0, &r1);
 859            regs[r0] = -regs[r1];
 860            break;
 861#endif
 862#if TCG_TARGET_REG_BITS == 64
 863            /* Load/store operations (64 bit). */
 864
 865        case INDEX_op_ld32s_i64:
 866            tci_args_rrs(insn, &r0, &r1, &ofs);
 867            ptr = (void *)(regs[r1] + ofs);
 868            regs[r0] = *(int32_t *)ptr;
 869            break;
 870        case INDEX_op_ld_i64:
 871            tci_args_rrs(insn, &r0, &r1, &ofs);
 872            ptr = (void *)(regs[r1] + ofs);
 873            regs[r0] = *(uint64_t *)ptr;
 874            break;
 875        case INDEX_op_st_i64:
 876            tci_args_rrs(insn, &r0, &r1, &ofs);
 877            ptr = (void *)(regs[r1] + ofs);
 878            *(uint64_t *)ptr = regs[r0];
 879            break;
 880
 881            /* Arithmetic operations (64 bit). */
 882
 883        case INDEX_op_div_i64:
 884            tci_args_rrr(insn, &r0, &r1, &r2);
 885            regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
 886            break;
 887        case INDEX_op_divu_i64:
 888            tci_args_rrr(insn, &r0, &r1, &r2);
 889            regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
 890            break;
 891        case INDEX_op_rem_i64:
 892            tci_args_rrr(insn, &r0, &r1, &r2);
 893            regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
 894            break;
 895        case INDEX_op_remu_i64:
 896            tci_args_rrr(insn, &r0, &r1, &r2);
 897            regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
 898            break;
 899#if TCG_TARGET_HAS_clz_i64
 900        case INDEX_op_clz_i64:
 901            tci_args_rrr(insn, &r0, &r1, &r2);
 902            regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
 903            break;
 904#endif
 905#if TCG_TARGET_HAS_ctz_i64
 906        case INDEX_op_ctz_i64:
 907            tci_args_rrr(insn, &r0, &r1, &r2);
 908            regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
 909            break;
 910#endif
 911#if TCG_TARGET_HAS_ctpop_i64
 912        case INDEX_op_ctpop_i64:
 913            tci_args_rr(insn, &r0, &r1);
 914            regs[r0] = ctpop64(regs[r1]);
 915            break;
 916#endif
 917#if TCG_TARGET_HAS_mulu2_i64
 918        case INDEX_op_mulu2_i64:
 919            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
 920            mulu64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
 921            break;
 922#endif
 923#if TCG_TARGET_HAS_muls2_i64
 924        case INDEX_op_muls2_i64:
 925            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
 926            muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
 927            break;
 928#endif
 929#if TCG_TARGET_HAS_add2_i64
 930        case INDEX_op_add2_i64:
 931            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
 932            T1 = regs[r2] + regs[r4];
 933            T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
 934            regs[r0] = T1;
 935            regs[r1] = T2;
 936            break;
 937#endif
 938#if TCG_TARGET_HAS_add2_i64
 939        case INDEX_op_sub2_i64:
 940            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
 941            T1 = regs[r2] - regs[r4];
 942            T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
 943            regs[r0] = T1;
 944            regs[r1] = T2;
 945            break;
 946#endif
 947
 948            /* Shift/rotate operations (64 bit). */
 949
 950        case INDEX_op_shl_i64:
 951            tci_args_rrr(insn, &r0, &r1, &r2);
 952            regs[r0] = regs[r1] << (regs[r2] & 63);
 953            break;
 954        case INDEX_op_shr_i64:
 955            tci_args_rrr(insn, &r0, &r1, &r2);
 956            regs[r0] = regs[r1] >> (regs[r2] & 63);
 957            break;
 958        case INDEX_op_sar_i64:
 959            tci_args_rrr(insn, &r0, &r1, &r2);
 960            regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
 961            break;
 962#if TCG_TARGET_HAS_rot_i64
 963        case INDEX_op_rotl_i64:
 964            tci_args_rrr(insn, &r0, &r1, &r2);
 965            regs[r0] = rol64(regs[r1], regs[r2] & 63);
 966            break;
 967        case INDEX_op_rotr_i64:
 968            tci_args_rrr(insn, &r0, &r1, &r2);
 969            regs[r0] = ror64(regs[r1], regs[r2] & 63);
 970            break;
 971#endif
 972#if TCG_TARGET_HAS_deposit_i64
 973        case INDEX_op_deposit_i64:
 974            tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
 975            regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
 976            break;
 977#endif
 978#if TCG_TARGET_HAS_extract_i64
 979        case INDEX_op_extract_i64:
 980            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
 981            regs[r0] = extract64(regs[r1], pos, len);
 982            break;
 983#endif
 984#if TCG_TARGET_HAS_sextract_i64
 985        case INDEX_op_sextract_i64:
 986            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
 987            regs[r0] = sextract64(regs[r1], pos, len);
 988            break;
 989#endif
 990        case INDEX_op_brcond_i64:
 991            tci_args_rl(insn, tb_ptr, &r0, &ptr);
 992            if (regs[r0]) {
 993                tb_ptr = ptr;
 994            }
 995            break;
 996        case INDEX_op_ext32s_i64:
 997        case INDEX_op_ext_i32_i64:
 998            tci_args_rr(insn, &r0, &r1);
 999            regs[r0] = (int32_t)regs[r1];
1000            break;
1001        case INDEX_op_ext32u_i64:
1002        case INDEX_op_extu_i32_i64:
1003            tci_args_rr(insn, &r0, &r1);
1004            regs[r0] = (uint32_t)regs[r1];
1005            break;
1006#if TCG_TARGET_HAS_bswap64_i64
1007        case INDEX_op_bswap64_i64:
1008            tci_args_rr(insn, &r0, &r1);
1009            regs[r0] = bswap64(regs[r1]);
1010            break;
1011#endif
1012#endif /* TCG_TARGET_REG_BITS == 64 */
1013
1014            /* QEMU specific operations. */
1015
1016        case INDEX_op_exit_tb:
1017            tci_args_l(insn, tb_ptr, &ptr);
1018            return (uintptr_t)ptr;
1019
1020        case INDEX_op_goto_tb:
1021            tci_args_l(insn, tb_ptr, &ptr);
1022            tb_ptr = *(void **)ptr;
1023            break;
1024
1025        case INDEX_op_goto_ptr:
1026            tci_args_r(insn, &r0);
1027            ptr = (void *)regs[r0];
1028            if (!ptr) {
1029                return 0;
1030            }
1031            tb_ptr = ptr;
1032            break;
1033
1034        case INDEX_op_qemu_ld_i32:
1035            if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
1036                tci_args_rrm(insn, &r0, &r1, &oi);
1037                taddr = regs[r1];
1038            } else {
1039                tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1040                taddr = tci_uint64(regs[r2], regs[r1]);
1041            }
1042            tmp32 = tci_qemu_ld(env, taddr, oi, tb_ptr);
1043            regs[r0] = tmp32;
1044            break;
1045
1046        case INDEX_op_qemu_ld_i64:
1047            if (TCG_TARGET_REG_BITS == 64) {
1048                tci_args_rrm(insn, &r0, &r1, &oi);
1049                taddr = regs[r1];
1050            } else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
1051                tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1052                taddr = regs[r2];
1053            } else {
1054                tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1055                taddr = tci_uint64(regs[r3], regs[r2]);
1056                oi = regs[r4];
1057            }
1058            tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
1059            if (TCG_TARGET_REG_BITS == 32) {
1060                tci_write_reg64(regs, r1, r0, tmp64);
1061            } else {
1062                regs[r0] = tmp64;
1063            }
1064            break;
1065
1066        case INDEX_op_qemu_st_i32:
1067            if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
1068                tci_args_rrm(insn, &r0, &r1, &oi);
1069                taddr = regs[r1];
1070            } else {
1071                tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1072                taddr = tci_uint64(regs[r2], regs[r1]);
1073            }
1074            tmp32 = regs[r0];
1075            tci_qemu_st(env, taddr, tmp32, oi, tb_ptr);
1076            break;
1077
1078        case INDEX_op_qemu_st_i64:
1079            if (TCG_TARGET_REG_BITS == 64) {
1080                tci_args_rrm(insn, &r0, &r1, &oi);
1081                taddr = regs[r1];
1082                tmp64 = regs[r0];
1083            } else {
1084                if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
1085                    tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1086                    taddr = regs[r2];
1087                } else {
1088                    tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1089                    taddr = tci_uint64(regs[r3], regs[r2]);
1090                    oi = regs[r4];
1091                }
1092                tmp64 = tci_uint64(regs[r1], regs[r0]);
1093            }
1094            tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
1095            break;
1096
1097        case INDEX_op_mb:
1098            /* Ensure ordering for all kinds */
1099            smp_mb();
1100            break;
1101        default:
1102            g_assert_not_reached();
1103        }
1104    }
1105}
1106
1107/*
1108 * Disassembler that matches the interpreter
1109 */
1110
1111static const char *str_r(TCGReg r)
1112{
1113    static const char regs[TCG_TARGET_NB_REGS][4] = {
1114        "r0", "r1", "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
1115        "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
1116    };
1117
1118    QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
1119    QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
1120
1121    assert((unsigned)r < TCG_TARGET_NB_REGS);
1122    return regs[r];
1123}
1124
1125static const char *str_c(TCGCond c)
1126{
1127    static const char cond[16][8] = {
1128        [TCG_COND_NEVER] = "never",
1129        [TCG_COND_ALWAYS] = "always",
1130        [TCG_COND_EQ] = "eq",
1131        [TCG_COND_NE] = "ne",
1132        [TCG_COND_LT] = "lt",
1133        [TCG_COND_GE] = "ge",
1134        [TCG_COND_LE] = "le",
1135        [TCG_COND_GT] = "gt",
1136        [TCG_COND_LTU] = "ltu",
1137        [TCG_COND_GEU] = "geu",
1138        [TCG_COND_LEU] = "leu",
1139        [TCG_COND_GTU] = "gtu",
1140    };
1141
1142    assert((unsigned)c < ARRAY_SIZE(cond));
1143    assert(cond[c][0] != 0);
1144    return cond[c];
1145}
1146
1147/* Disassemble TCI bytecode. */
1148int print_insn_tci(bfd_vma addr, disassemble_info *info)
1149{
1150    const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
1151    const TCGOpDef *def;
1152    const char *op_name;
1153    uint32_t insn;
1154    TCGOpcode op;
1155    TCGReg r0, r1, r2, r3, r4, r5;
1156    tcg_target_ulong i1;
1157    int32_t s2;
1158    TCGCond c;
1159    MemOpIdx oi;
1160    uint8_t pos, len;
1161    void *ptr;
1162
1163    /* TCI is always the host, so we don't need to load indirect. */
1164    insn = *tb_ptr++;
1165
1166    info->fprintf_func(info->stream, "%08x  ", insn);
1167
1168    op = extract32(insn, 0, 8);
1169    def = &tcg_op_defs[op];
1170    op_name = def->name;
1171
1172    switch (op) {
1173    case INDEX_op_br:
1174    case INDEX_op_exit_tb:
1175    case INDEX_op_goto_tb:
1176        tci_args_l(insn, tb_ptr, &ptr);
1177        info->fprintf_func(info->stream, "%-12s  %p", op_name, ptr);
1178        break;
1179
1180    case INDEX_op_goto_ptr:
1181        tci_args_r(insn, &r0);
1182        info->fprintf_func(info->stream, "%-12s  %s", op_name, str_r(r0));
1183        break;
1184
1185    case INDEX_op_call:
1186        tci_args_nl(insn, tb_ptr, &len, &ptr);
1187        info->fprintf_func(info->stream, "%-12s  %d, %p", op_name, len, ptr);
1188        break;
1189
1190    case INDEX_op_brcond_i32:
1191    case INDEX_op_brcond_i64:
1192        tci_args_rl(insn, tb_ptr, &r0, &ptr);
1193        info->fprintf_func(info->stream, "%-12s  %s, 0, ne, %p",
1194                           op_name, str_r(r0), ptr);
1195        break;
1196
1197    case INDEX_op_setcond_i32:
1198    case INDEX_op_setcond_i64:
1199        tci_args_rrrc(insn, &r0, &r1, &r2, &c);
1200        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1201                           op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1202        break;
1203
1204    case INDEX_op_tci_movi:
1205        tci_args_ri(insn, &r0, &i1);
1206        info->fprintf_func(info->stream, "%-12s  %s, 0x%" TCG_PRIlx,
1207                           op_name, str_r(r0), i1);
1208        break;
1209
1210    case INDEX_op_tci_movl:
1211        tci_args_rl(insn, tb_ptr, &r0, &ptr);
1212        info->fprintf_func(info->stream, "%-12s  %s, %p",
1213                           op_name, str_r(r0), ptr);
1214        break;
1215
1216    case INDEX_op_ld8u_i32:
1217    case INDEX_op_ld8u_i64:
1218    case INDEX_op_ld8s_i32:
1219    case INDEX_op_ld8s_i64:
1220    case INDEX_op_ld16u_i32:
1221    case INDEX_op_ld16u_i64:
1222    case INDEX_op_ld16s_i32:
1223    case INDEX_op_ld16s_i64:
1224    case INDEX_op_ld32u_i64:
1225    case INDEX_op_ld32s_i64:
1226    case INDEX_op_ld_i32:
1227    case INDEX_op_ld_i64:
1228    case INDEX_op_st8_i32:
1229    case INDEX_op_st8_i64:
1230    case INDEX_op_st16_i32:
1231    case INDEX_op_st16_i64:
1232    case INDEX_op_st32_i64:
1233    case INDEX_op_st_i32:
1234    case INDEX_op_st_i64:
1235        tci_args_rrs(insn, &r0, &r1, &s2);
1236        info->fprintf_func(info->stream, "%-12s  %s, %s, %d",
1237                           op_name, str_r(r0), str_r(r1), s2);
1238        break;
1239
1240    case INDEX_op_mov_i32:
1241    case INDEX_op_mov_i64:
1242    case INDEX_op_ext8s_i32:
1243    case INDEX_op_ext8s_i64:
1244    case INDEX_op_ext8u_i32:
1245    case INDEX_op_ext8u_i64:
1246    case INDEX_op_ext16s_i32:
1247    case INDEX_op_ext16s_i64:
1248    case INDEX_op_ext16u_i32:
1249    case INDEX_op_ext32s_i64:
1250    case INDEX_op_ext32u_i64:
1251    case INDEX_op_ext_i32_i64:
1252    case INDEX_op_extu_i32_i64:
1253    case INDEX_op_bswap16_i32:
1254    case INDEX_op_bswap16_i64:
1255    case INDEX_op_bswap32_i32:
1256    case INDEX_op_bswap32_i64:
1257    case INDEX_op_bswap64_i64:
1258    case INDEX_op_not_i32:
1259    case INDEX_op_not_i64:
1260    case INDEX_op_neg_i32:
1261    case INDEX_op_neg_i64:
1262    case INDEX_op_ctpop_i32:
1263    case INDEX_op_ctpop_i64:
1264        tci_args_rr(insn, &r0, &r1);
1265        info->fprintf_func(info->stream, "%-12s  %s, %s",
1266                           op_name, str_r(r0), str_r(r1));
1267        break;
1268
1269    case INDEX_op_add_i32:
1270    case INDEX_op_add_i64:
1271    case INDEX_op_sub_i32:
1272    case INDEX_op_sub_i64:
1273    case INDEX_op_mul_i32:
1274    case INDEX_op_mul_i64:
1275    case INDEX_op_and_i32:
1276    case INDEX_op_and_i64:
1277    case INDEX_op_or_i32:
1278    case INDEX_op_or_i64:
1279    case INDEX_op_xor_i32:
1280    case INDEX_op_xor_i64:
1281    case INDEX_op_andc_i32:
1282    case INDEX_op_andc_i64:
1283    case INDEX_op_orc_i32:
1284    case INDEX_op_orc_i64:
1285    case INDEX_op_eqv_i32:
1286    case INDEX_op_eqv_i64:
1287    case INDEX_op_nand_i32:
1288    case INDEX_op_nand_i64:
1289    case INDEX_op_nor_i32:
1290    case INDEX_op_nor_i64:
1291    case INDEX_op_div_i32:
1292    case INDEX_op_div_i64:
1293    case INDEX_op_rem_i32:
1294    case INDEX_op_rem_i64:
1295    case INDEX_op_divu_i32:
1296    case INDEX_op_divu_i64:
1297    case INDEX_op_remu_i32:
1298    case INDEX_op_remu_i64:
1299    case INDEX_op_shl_i32:
1300    case INDEX_op_shl_i64:
1301    case INDEX_op_shr_i32:
1302    case INDEX_op_shr_i64:
1303    case INDEX_op_sar_i32:
1304    case INDEX_op_sar_i64:
1305    case INDEX_op_rotl_i32:
1306    case INDEX_op_rotl_i64:
1307    case INDEX_op_rotr_i32:
1308    case INDEX_op_rotr_i64:
1309    case INDEX_op_clz_i32:
1310    case INDEX_op_clz_i64:
1311    case INDEX_op_ctz_i32:
1312    case INDEX_op_ctz_i64:
1313        tci_args_rrr(insn, &r0, &r1, &r2);
1314        info->fprintf_func(info->stream, "%-12s  %s, %s, %s",
1315                           op_name, str_r(r0), str_r(r1), str_r(r2));
1316        break;
1317
1318    case INDEX_op_deposit_i32:
1319    case INDEX_op_deposit_i64:
1320        tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1321        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %d, %d",
1322                           op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1323        break;
1324
1325    case INDEX_op_extract_i32:
1326    case INDEX_op_extract_i64:
1327    case INDEX_op_sextract_i32:
1328    case INDEX_op_sextract_i64:
1329        tci_args_rrbb(insn, &r0, &r1, &pos, &len);
1330        info->fprintf_func(info->stream, "%-12s  %s,%s,%d,%d",
1331                           op_name, str_r(r0), str_r(r1), pos, len);
1332        break;
1333
1334    case INDEX_op_movcond_i32:
1335    case INDEX_op_movcond_i64:
1336    case INDEX_op_setcond2_i32:
1337        tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1338        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1339                           op_name, str_r(r0), str_r(r1), str_r(r2),
1340                           str_r(r3), str_r(r4), str_c(c));
1341        break;
1342
1343    case INDEX_op_mulu2_i32:
1344    case INDEX_op_mulu2_i64:
1345    case INDEX_op_muls2_i32:
1346    case INDEX_op_muls2_i64:
1347        tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1348        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1349                           op_name, str_r(r0), str_r(r1),
1350                           str_r(r2), str_r(r3));
1351        break;
1352
1353    case INDEX_op_add2_i32:
1354    case INDEX_op_add2_i64:
1355    case INDEX_op_sub2_i32:
1356    case INDEX_op_sub2_i64:
1357        tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1358        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1359                           op_name, str_r(r0), str_r(r1), str_r(r2),
1360                           str_r(r3), str_r(r4), str_r(r5));
1361        break;
1362
1363    case INDEX_op_qemu_ld_i64:
1364    case INDEX_op_qemu_st_i64:
1365        len = DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1366        goto do_qemu_ldst;
1367    case INDEX_op_qemu_ld_i32:
1368    case INDEX_op_qemu_st_i32:
1369        len = 1;
1370    do_qemu_ldst:
1371        len += DIV_ROUND_UP(TARGET_LONG_BITS, TCG_TARGET_REG_BITS);
1372        switch (len) {
1373        case 2:
1374            tci_args_rrm(insn, &r0, &r1, &oi);
1375            info->fprintf_func(info->stream, "%-12s  %s, %s, %x",
1376                               op_name, str_r(r0), str_r(r1), oi);
1377            break;
1378        case 3:
1379            tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1380            info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %x",
1381                               op_name, str_r(r0), str_r(r1), str_r(r2), oi);
1382            break;
1383        case 4:
1384            tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1385            info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s",
1386                               op_name, str_r(r0), str_r(r1),
1387                               str_r(r2), str_r(r3), str_r(r4));
1388            break;
1389        default:
1390            g_assert_not_reached();
1391        }
1392        break;
1393
1394    case 0:
1395        /* tcg_out_nop_fill uses zeros */
1396        if (insn == 0) {
1397            info->fprintf_func(info->stream, "align");
1398            break;
1399        }
1400        /* fall through */
1401
1402    default:
1403        info->fprintf_func(info->stream, "illegal opcode %d", op);
1404        break;
1405    }
1406
1407    return sizeof(insn);
1408}
1409