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