xref: /openbmc/qemu/tcg/tci.c (revision 3ad5d4ccb4bdebdff4e90957bb2b8a93e5e418e2)
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"
22 #include "tcg/helper-info.h"
23 #include "tcg/tcg-ldst.h"
24 #include "disas/dis-asm.h"
25 #include "tcg-has.h"
26 #include <ffi.h>
27 
28 
29 #define ctpop_tr    glue(ctpop, TCG_TARGET_REG_BITS)
30 
31 /*
32  * Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
33  * Without assertions, the interpreter runs much faster.
34  */
35 #if defined(CONFIG_DEBUG_TCG)
36 # define tci_assert(cond) assert(cond)
37 #else
38 # define tci_assert(cond) ((void)(cond))
39 #endif
40 
41 __thread uintptr_t tci_tb_ptr;
42 
43 static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
44                             uint32_t low_index, uint64_t value)
45 {
46     regs[low_index] = (uint32_t)value;
47     regs[high_index] = value >> 32;
48 }
49 
50 /* Create a 64 bit value from two 32 bit values. */
51 static uint64_t tci_uint64(uint32_t high, uint32_t low)
52 {
53     return ((uint64_t)high << 32) + low;
54 }
55 
56 /*
57  * Load sets of arguments all at once.  The naming convention is:
58  *   tci_args_<arguments>
59  * where arguments is a sequence of
60  *
61  *   b = immediate (bit position)
62  *   c = condition (TCGCond)
63  *   i = immediate (uint32_t)
64  *   I = immediate (tcg_target_ulong)
65  *   l = label or pointer
66  *   m = immediate (MemOpIdx)
67  *   n = immediate (call return length)
68  *   r = register
69  *   s = signed ldst offset
70  */
71 
72 static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
73 {
74     int diff = sextract32(insn, 12, 20);
75     *l0 = diff ? (void *)tb_ptr + diff : NULL;
76 }
77 
78 static void tci_args_r(uint32_t insn, TCGReg *r0)
79 {
80     *r0 = extract32(insn, 8, 4);
81 }
82 
83 static void tci_args_nl(uint32_t insn, const void *tb_ptr,
84                         uint8_t *n0, void **l1)
85 {
86     *n0 = extract32(insn, 8, 4);
87     *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
88 }
89 
90 static void tci_args_rl(uint32_t insn, const void *tb_ptr,
91                         TCGReg *r0, void **l1)
92 {
93     *r0 = extract32(insn, 8, 4);
94     *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
95 }
96 
97 static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
98 {
99     *r0 = extract32(insn, 8, 4);
100     *r1 = extract32(insn, 12, 4);
101 }
102 
103 static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
104 {
105     *r0 = extract32(insn, 8, 4);
106     *i1 = sextract32(insn, 12, 20);
107 }
108 
109 static void tci_args_rrm(uint32_t insn, TCGReg *r0,
110                          TCGReg *r1, MemOpIdx *m2)
111 {
112     *r0 = extract32(insn, 8, 4);
113     *r1 = extract32(insn, 12, 4);
114     *m2 = extract32(insn, 16, 16);
115 }
116 
117 static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
118 {
119     *r0 = extract32(insn, 8, 4);
120     *r1 = extract32(insn, 12, 4);
121     *r2 = extract32(insn, 16, 4);
122 }
123 
124 static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
125 {
126     *r0 = extract32(insn, 8, 4);
127     *r1 = extract32(insn, 12, 4);
128     *i2 = sextract32(insn, 16, 16);
129 }
130 
131 static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
132                           uint8_t *i2, uint8_t *i3)
133 {
134     *r0 = extract32(insn, 8, 4);
135     *r1 = extract32(insn, 12, 4);
136     *i2 = extract32(insn, 16, 6);
137     *i3 = extract32(insn, 22, 6);
138 }
139 
140 static void tci_args_rrrc(uint32_t insn,
141                           TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
142 {
143     *r0 = extract32(insn, 8, 4);
144     *r1 = extract32(insn, 12, 4);
145     *r2 = extract32(insn, 16, 4);
146     *c3 = extract32(insn, 20, 4);
147 }
148 
149 static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
150                            TCGReg *r2, uint8_t *i3, uint8_t *i4)
151 {
152     *r0 = extract32(insn, 8, 4);
153     *r1 = extract32(insn, 12, 4);
154     *r2 = extract32(insn, 16, 4);
155     *i3 = extract32(insn, 20, 6);
156     *i4 = extract32(insn, 26, 6);
157 }
158 
159 static void tci_args_rrrr(uint32_t insn,
160                           TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
161 {
162     *r0 = extract32(insn, 8, 4);
163     *r1 = extract32(insn, 12, 4);
164     *r2 = extract32(insn, 16, 4);
165     *r3 = extract32(insn, 20, 4);
166 }
167 
168 static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
169                             TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
170 {
171     *r0 = extract32(insn, 8, 4);
172     *r1 = extract32(insn, 12, 4);
173     *r2 = extract32(insn, 16, 4);
174     *r3 = extract32(insn, 20, 4);
175     *r4 = extract32(insn, 24, 4);
176     *c5 = extract32(insn, 28, 4);
177 }
178 
179 static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
180                             TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
181 {
182     *r0 = extract32(insn, 8, 4);
183     *r1 = extract32(insn, 12, 4);
184     *r2 = extract32(insn, 16, 4);
185     *r3 = extract32(insn, 20, 4);
186     *r4 = extract32(insn, 24, 4);
187     *r5 = extract32(insn, 28, 4);
188 }
189 
190 static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
191 {
192     bool result = false;
193     int32_t i0 = u0;
194     int32_t i1 = u1;
195     switch (condition) {
196     case TCG_COND_EQ:
197         result = (u0 == u1);
198         break;
199     case TCG_COND_NE:
200         result = (u0 != u1);
201         break;
202     case TCG_COND_LT:
203         result = (i0 < i1);
204         break;
205     case TCG_COND_GE:
206         result = (i0 >= i1);
207         break;
208     case TCG_COND_LE:
209         result = (i0 <= i1);
210         break;
211     case TCG_COND_GT:
212         result = (i0 > i1);
213         break;
214     case TCG_COND_LTU:
215         result = (u0 < u1);
216         break;
217     case TCG_COND_GEU:
218         result = (u0 >= u1);
219         break;
220     case TCG_COND_LEU:
221         result = (u0 <= u1);
222         break;
223     case TCG_COND_GTU:
224         result = (u0 > u1);
225         break;
226     case TCG_COND_TSTEQ:
227         result = (u0 & u1) == 0;
228         break;
229     case TCG_COND_TSTNE:
230         result = (u0 & u1) != 0;
231         break;
232     default:
233         g_assert_not_reached();
234     }
235     return result;
236 }
237 
238 static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
239 {
240     bool result = false;
241     int64_t i0 = u0;
242     int64_t i1 = u1;
243     switch (condition) {
244     case TCG_COND_EQ:
245         result = (u0 == u1);
246         break;
247     case TCG_COND_NE:
248         result = (u0 != u1);
249         break;
250     case TCG_COND_LT:
251         result = (i0 < i1);
252         break;
253     case TCG_COND_GE:
254         result = (i0 >= i1);
255         break;
256     case TCG_COND_LE:
257         result = (i0 <= i1);
258         break;
259     case TCG_COND_GT:
260         result = (i0 > i1);
261         break;
262     case TCG_COND_LTU:
263         result = (u0 < u1);
264         break;
265     case TCG_COND_GEU:
266         result = (u0 >= u1);
267         break;
268     case TCG_COND_LEU:
269         result = (u0 <= u1);
270         break;
271     case TCG_COND_GTU:
272         result = (u0 > u1);
273         break;
274     case TCG_COND_TSTEQ:
275         result = (u0 & u1) == 0;
276         break;
277     case TCG_COND_TSTNE:
278         result = (u0 & u1) != 0;
279         break;
280     default:
281         g_assert_not_reached();
282     }
283     return result;
284 }
285 
286 static uint64_t tci_qemu_ld(CPUArchState *env, uint64_t taddr,
287                             MemOpIdx oi, const void *tb_ptr)
288 {
289     MemOp mop = get_memop(oi);
290     uintptr_t ra = (uintptr_t)tb_ptr;
291 
292     switch (mop & MO_SSIZE) {
293     case MO_UB:
294         return helper_ldub_mmu(env, taddr, oi, ra);
295     case MO_SB:
296         return helper_ldsb_mmu(env, taddr, oi, ra);
297     case MO_UW:
298         return helper_lduw_mmu(env, taddr, oi, ra);
299     case MO_SW:
300         return helper_ldsw_mmu(env, taddr, oi, ra);
301     case MO_UL:
302         return helper_ldul_mmu(env, taddr, oi, ra);
303     case MO_SL:
304         return helper_ldsl_mmu(env, taddr, oi, ra);
305     case MO_UQ:
306         return helper_ldq_mmu(env, taddr, oi, ra);
307     default:
308         g_assert_not_reached();
309     }
310 }
311 
312 static void tci_qemu_st(CPUArchState *env, uint64_t taddr, uint64_t val,
313                         MemOpIdx oi, const void *tb_ptr)
314 {
315     MemOp mop = get_memop(oi);
316     uintptr_t ra = (uintptr_t)tb_ptr;
317 
318     switch (mop & MO_SIZE) {
319     case MO_UB:
320         helper_stb_mmu(env, taddr, val, oi, ra);
321         break;
322     case MO_UW:
323         helper_stw_mmu(env, taddr, val, oi, ra);
324         break;
325     case MO_UL:
326         helper_stl_mmu(env, taddr, val, oi, ra);
327         break;
328     case MO_UQ:
329         helper_stq_mmu(env, taddr, val, oi, ra);
330         break;
331     default:
332         g_assert_not_reached();
333     }
334 }
335 
336 #if TCG_TARGET_REG_BITS == 64
337 # define CASE_32_64(x) \
338         case glue(glue(INDEX_op_, x), _i64): \
339         case glue(glue(INDEX_op_, x), _i32):
340 # define CASE_64(x) \
341         case glue(glue(INDEX_op_, x), _i64):
342 #else
343 # define CASE_32_64(x) \
344         case glue(glue(INDEX_op_, x), _i32):
345 # define CASE_64(x)
346 #endif
347 
348 /* Interpret pseudo code in tb. */
349 /*
350  * Disable CFI checks.
351  * One possible operation in the pseudo code is a call to binary code.
352  * Therefore, disable CFI checks in the interpreter function
353  */
354 uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
355                                             const void *v_tb_ptr)
356 {
357     const uint32_t *tb_ptr = v_tb_ptr;
358     tcg_target_ulong regs[TCG_TARGET_NB_REGS];
359     uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
360                    / sizeof(uint64_t)];
361 
362     regs[TCG_AREG0] = (tcg_target_ulong)env;
363     regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
364     tci_assert(tb_ptr);
365 
366     for (;;) {
367         uint32_t insn;
368         TCGOpcode opc;
369         TCGReg r0, r1, r2, r3, r4, r5;
370         tcg_target_ulong t1;
371         TCGCond condition;
372         uint8_t pos, len;
373         uint32_t tmp32;
374         uint64_t tmp64, taddr;
375         uint64_t T1, T2;
376         MemOpIdx oi;
377         int32_t ofs;
378         void *ptr;
379 
380         insn = *tb_ptr++;
381         opc = extract32(insn, 0, 8);
382 
383         switch (opc) {
384         case INDEX_op_call:
385             {
386                 void *call_slots[MAX_CALL_IARGS];
387                 ffi_cif *cif;
388                 void *func;
389                 unsigned i, s, n;
390 
391                 tci_args_nl(insn, tb_ptr, &len, &ptr);
392                 func = ((void **)ptr)[0];
393                 cif = ((void **)ptr)[1];
394 
395                 n = cif->nargs;
396                 for (i = s = 0; i < n; ++i) {
397                     ffi_type *t = cif->arg_types[i];
398                     call_slots[i] = &stack[s];
399                     s += DIV_ROUND_UP(t->size, 8);
400                 }
401 
402                 /* Helper functions may need to access the "return address" */
403                 tci_tb_ptr = (uintptr_t)tb_ptr;
404                 ffi_call(cif, func, stack, call_slots);
405             }
406 
407             switch (len) {
408             case 0: /* void */
409                 break;
410             case 1: /* uint32_t */
411                 /*
412                  * The result winds up "left-aligned" in the stack[0] slot.
413                  * Note that libffi has an odd special case in that it will
414                  * always widen an integral result to ffi_arg.
415                  */
416                 if (sizeof(ffi_arg) == 8) {
417                     regs[TCG_REG_R0] = (uint32_t)stack[0];
418                 } else {
419                     regs[TCG_REG_R0] = *(uint32_t *)stack;
420                 }
421                 break;
422             case 2: /* uint64_t */
423                 /*
424                  * For TCG_TARGET_REG_BITS == 32, the register pair
425                  * must stay in host memory order.
426                  */
427                 memcpy(&regs[TCG_REG_R0], stack, 8);
428                 break;
429             case 3: /* Int128 */
430                 memcpy(&regs[TCG_REG_R0], stack, 16);
431                 break;
432             default:
433                 g_assert_not_reached();
434             }
435             break;
436 
437         case INDEX_op_br:
438             tci_args_l(insn, tb_ptr, &ptr);
439             tb_ptr = ptr;
440             continue;
441 #if TCG_TARGET_REG_BITS == 32
442         case INDEX_op_setcond2_i32:
443             tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
444             T1 = tci_uint64(regs[r2], regs[r1]);
445             T2 = tci_uint64(regs[r4], regs[r3]);
446             regs[r0] = tci_compare64(T1, T2, condition);
447             break;
448 #elif TCG_TARGET_REG_BITS == 64
449         case INDEX_op_setcond:
450             tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
451             regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
452             break;
453         case INDEX_op_movcond:
454             tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
455             tmp32 = tci_compare64(regs[r1], regs[r2], condition);
456             regs[r0] = regs[tmp32 ? r3 : r4];
457             break;
458 #endif
459         case INDEX_op_mov:
460             tci_args_rr(insn, &r0, &r1);
461             regs[r0] = regs[r1];
462             break;
463         case INDEX_op_tci_movi:
464             tci_args_ri(insn, &r0, &t1);
465             regs[r0] = t1;
466             break;
467         case INDEX_op_tci_movl:
468             tci_args_rl(insn, tb_ptr, &r0, &ptr);
469             regs[r0] = *(tcg_target_ulong *)ptr;
470             break;
471 
472             /* Load/store operations (32 bit). */
473 
474         CASE_32_64(ld8u)
475             tci_args_rrs(insn, &r0, &r1, &ofs);
476             ptr = (void *)(regs[r1] + ofs);
477             regs[r0] = *(uint8_t *)ptr;
478             break;
479         CASE_32_64(ld8s)
480             tci_args_rrs(insn, &r0, &r1, &ofs);
481             ptr = (void *)(regs[r1] + ofs);
482             regs[r0] = *(int8_t *)ptr;
483             break;
484         CASE_32_64(ld16u)
485             tci_args_rrs(insn, &r0, &r1, &ofs);
486             ptr = (void *)(regs[r1] + ofs);
487             regs[r0] = *(uint16_t *)ptr;
488             break;
489         CASE_32_64(ld16s)
490             tci_args_rrs(insn, &r0, &r1, &ofs);
491             ptr = (void *)(regs[r1] + ofs);
492             regs[r0] = *(int16_t *)ptr;
493             break;
494         case INDEX_op_ld_i32:
495         CASE_64(ld32u)
496             tci_args_rrs(insn, &r0, &r1, &ofs);
497             ptr = (void *)(regs[r1] + ofs);
498             regs[r0] = *(uint32_t *)ptr;
499             break;
500         CASE_32_64(st8)
501             tci_args_rrs(insn, &r0, &r1, &ofs);
502             ptr = (void *)(regs[r1] + ofs);
503             *(uint8_t *)ptr = regs[r0];
504             break;
505         CASE_32_64(st16)
506             tci_args_rrs(insn, &r0, &r1, &ofs);
507             ptr = (void *)(regs[r1] + ofs);
508             *(uint16_t *)ptr = regs[r0];
509             break;
510         case INDEX_op_st_i32:
511         CASE_64(st32)
512             tci_args_rrs(insn, &r0, &r1, &ofs);
513             ptr = (void *)(regs[r1] + ofs);
514             *(uint32_t *)ptr = regs[r0];
515             break;
516 
517             /* Arithmetic operations (mixed 32/64 bit). */
518 
519         case INDEX_op_add:
520             tci_args_rrr(insn, &r0, &r1, &r2);
521             regs[r0] = regs[r1] + regs[r2];
522             break;
523         case INDEX_op_sub:
524             tci_args_rrr(insn, &r0, &r1, &r2);
525             regs[r0] = regs[r1] - regs[r2];
526             break;
527         case INDEX_op_mul:
528             tci_args_rrr(insn, &r0, &r1, &r2);
529             regs[r0] = regs[r1] * regs[r2];
530             break;
531         case INDEX_op_and:
532             tci_args_rrr(insn, &r0, &r1, &r2);
533             regs[r0] = regs[r1] & regs[r2];
534             break;
535         case INDEX_op_or:
536             tci_args_rrr(insn, &r0, &r1, &r2);
537             regs[r0] = regs[r1] | regs[r2];
538             break;
539         case INDEX_op_xor:
540             tci_args_rrr(insn, &r0, &r1, &r2);
541             regs[r0] = regs[r1] ^ regs[r2];
542             break;
543         case INDEX_op_andc:
544             tci_args_rrr(insn, &r0, &r1, &r2);
545             regs[r0] = regs[r1] & ~regs[r2];
546             break;
547         case INDEX_op_orc:
548             tci_args_rrr(insn, &r0, &r1, &r2);
549             regs[r0] = regs[r1] | ~regs[r2];
550             break;
551         case INDEX_op_eqv:
552             tci_args_rrr(insn, &r0, &r1, &r2);
553             regs[r0] = ~(regs[r1] ^ regs[r2]);
554             break;
555         case INDEX_op_nand:
556             tci_args_rrr(insn, &r0, &r1, &r2);
557             regs[r0] = ~(regs[r1] & regs[r2]);
558             break;
559         case INDEX_op_nor:
560             tci_args_rrr(insn, &r0, &r1, &r2);
561             regs[r0] = ~(regs[r1] | regs[r2]);
562             break;
563         case INDEX_op_neg:
564             tci_args_rr(insn, &r0, &r1);
565             regs[r0] = -regs[r1];
566             break;
567         case INDEX_op_not:
568             tci_args_rr(insn, &r0, &r1);
569             regs[r0] = ~regs[r1];
570             break;
571         case INDEX_op_ctpop:
572             tci_args_rr(insn, &r0, &r1);
573             regs[r0] = ctpop_tr(regs[r1]);
574             break;
575         case INDEX_op_muls2:
576             tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
577 #if TCG_TARGET_REG_BITS == 32
578             tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
579             tci_write_reg64(regs, r1, r0, tmp64);
580 #else
581             muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
582 #endif
583             break;
584         case INDEX_op_mulu2:
585             tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
586 #if TCG_TARGET_REG_BITS == 32
587             tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
588             tci_write_reg64(regs, r1, r0, tmp64);
589 #else
590             mulu64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
591 #endif
592             break;
593 
594             /* Arithmetic operations (32 bit). */
595 
596         case INDEX_op_tci_divs32:
597             tci_args_rrr(insn, &r0, &r1, &r2);
598             regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
599             break;
600         case INDEX_op_tci_divu32:
601             tci_args_rrr(insn, &r0, &r1, &r2);
602             regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
603             break;
604         case INDEX_op_tci_rems32:
605             tci_args_rrr(insn, &r0, &r1, &r2);
606             regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
607             break;
608         case INDEX_op_tci_remu32:
609             tci_args_rrr(insn, &r0, &r1, &r2);
610             regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
611             break;
612         case INDEX_op_tci_clz32:
613             tci_args_rrr(insn, &r0, &r1, &r2);
614             tmp32 = regs[r1];
615             regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
616             break;
617         case INDEX_op_tci_ctz32:
618             tci_args_rrr(insn, &r0, &r1, &r2);
619             tmp32 = regs[r1];
620             regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
621             break;
622         case INDEX_op_tci_setcond32:
623             tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
624             regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
625             break;
626         case INDEX_op_tci_movcond32:
627             tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
628             tmp32 = tci_compare32(regs[r1], regs[r2], condition);
629             regs[r0] = regs[tmp32 ? r3 : r4];
630             break;
631 
632             /* Shift/rotate operations. */
633 
634         case INDEX_op_shl:
635             tci_args_rrr(insn, &r0, &r1, &r2);
636             regs[r0] = regs[r1] << (regs[r2] % TCG_TARGET_REG_BITS);
637             break;
638         case INDEX_op_shr:
639             tci_args_rrr(insn, &r0, &r1, &r2);
640             regs[r0] = regs[r1] >> (regs[r2] % TCG_TARGET_REG_BITS);
641             break;
642         case INDEX_op_sar:
643             tci_args_rrr(insn, &r0, &r1, &r2);
644             regs[r0] = ((tcg_target_long)regs[r1]
645                         >> (regs[r2] % TCG_TARGET_REG_BITS));
646             break;
647         case INDEX_op_tci_rotl32:
648             tci_args_rrr(insn, &r0, &r1, &r2);
649             regs[r0] = rol32(regs[r1], regs[r2] & 31);
650             break;
651         case INDEX_op_tci_rotr32:
652             tci_args_rrr(insn, &r0, &r1, &r2);
653             regs[r0] = ror32(regs[r1], regs[r2] & 31);
654             break;
655         case INDEX_op_deposit_i32:
656             tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
657             regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
658             break;
659         case INDEX_op_extract_i32:
660             tci_args_rrbb(insn, &r0, &r1, &pos, &len);
661             regs[r0] = extract32(regs[r1], pos, len);
662             break;
663         case INDEX_op_sextract_i32:
664             tci_args_rrbb(insn, &r0, &r1, &pos, &len);
665             regs[r0] = sextract32(regs[r1], pos, len);
666             break;
667         case INDEX_op_brcond:
668             tci_args_rl(insn, tb_ptr, &r0, &ptr);
669             if (regs[r0]) {
670                 tb_ptr = ptr;
671             }
672             break;
673 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
674         case INDEX_op_add2_i32:
675             tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
676             T1 = tci_uint64(regs[r3], regs[r2]);
677             T2 = tci_uint64(regs[r5], regs[r4]);
678             tci_write_reg64(regs, r1, r0, T1 + T2);
679             break;
680 #endif
681 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
682         case INDEX_op_sub2_i32:
683             tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
684             T1 = tci_uint64(regs[r3], regs[r2]);
685             T2 = tci_uint64(regs[r5], regs[r4]);
686             tci_write_reg64(regs, r1, r0, T1 - T2);
687             break;
688 #endif
689         case INDEX_op_bswap16:
690             tci_args_rr(insn, &r0, &r1);
691             regs[r0] = bswap16(regs[r1]);
692             break;
693         case INDEX_op_bswap32:
694             tci_args_rr(insn, &r0, &r1);
695             regs[r0] = bswap32(regs[r1]);
696             break;
697 #if TCG_TARGET_REG_BITS == 64
698             /* Load/store operations (64 bit). */
699 
700         case INDEX_op_ld32s_i64:
701             tci_args_rrs(insn, &r0, &r1, &ofs);
702             ptr = (void *)(regs[r1] + ofs);
703             regs[r0] = *(int32_t *)ptr;
704             break;
705         case INDEX_op_ld_i64:
706             tci_args_rrs(insn, &r0, &r1, &ofs);
707             ptr = (void *)(regs[r1] + ofs);
708             regs[r0] = *(uint64_t *)ptr;
709             break;
710         case INDEX_op_st_i64:
711             tci_args_rrs(insn, &r0, &r1, &ofs);
712             ptr = (void *)(regs[r1] + ofs);
713             *(uint64_t *)ptr = regs[r0];
714             break;
715 
716             /* Arithmetic operations (64 bit). */
717 
718         case INDEX_op_divs:
719             tci_args_rrr(insn, &r0, &r1, &r2);
720             regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
721             break;
722         case INDEX_op_divu:
723             tci_args_rrr(insn, &r0, &r1, &r2);
724             regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
725             break;
726         case INDEX_op_rems:
727             tci_args_rrr(insn, &r0, &r1, &r2);
728             regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
729             break;
730         case INDEX_op_remu:
731             tci_args_rrr(insn, &r0, &r1, &r2);
732             regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
733             break;
734         case INDEX_op_clz:
735             tci_args_rrr(insn, &r0, &r1, &r2);
736             regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
737             break;
738         case INDEX_op_ctz:
739             tci_args_rrr(insn, &r0, &r1, &r2);
740             regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
741             break;
742 #if TCG_TARGET_HAS_add2_i64
743         case INDEX_op_add2_i64:
744             tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
745             T1 = regs[r2] + regs[r4];
746             T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
747             regs[r0] = T1;
748             regs[r1] = T2;
749             break;
750 #endif
751 #if TCG_TARGET_HAS_add2_i64
752         case INDEX_op_sub2_i64:
753             tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
754             T1 = regs[r2] - regs[r4];
755             T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
756             regs[r0] = T1;
757             regs[r1] = T2;
758             break;
759 #endif
760 
761             /* Shift/rotate operations (64 bit). */
762 
763         case INDEX_op_rotl:
764             tci_args_rrr(insn, &r0, &r1, &r2);
765             regs[r0] = rol64(regs[r1], regs[r2] & 63);
766             break;
767         case INDEX_op_rotr:
768             tci_args_rrr(insn, &r0, &r1, &r2);
769             regs[r0] = ror64(regs[r1], regs[r2] & 63);
770             break;
771         case INDEX_op_deposit_i64:
772             tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
773             regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
774             break;
775         case INDEX_op_extract_i64:
776             tci_args_rrbb(insn, &r0, &r1, &pos, &len);
777             regs[r0] = extract64(regs[r1], pos, len);
778             break;
779         case INDEX_op_sextract_i64:
780             tci_args_rrbb(insn, &r0, &r1, &pos, &len);
781             regs[r0] = sextract64(regs[r1], pos, len);
782             break;
783         case INDEX_op_ext_i32_i64:
784             tci_args_rr(insn, &r0, &r1);
785             regs[r0] = (int32_t)regs[r1];
786             break;
787         case INDEX_op_extu_i32_i64:
788             tci_args_rr(insn, &r0, &r1);
789             regs[r0] = (uint32_t)regs[r1];
790             break;
791         case INDEX_op_bswap64:
792             tci_args_rr(insn, &r0, &r1);
793             regs[r0] = bswap64(regs[r1]);
794             break;
795 #endif /* TCG_TARGET_REG_BITS == 64 */
796 
797             /* QEMU specific operations. */
798 
799         case INDEX_op_exit_tb:
800             tci_args_l(insn, tb_ptr, &ptr);
801             return (uintptr_t)ptr;
802 
803         case INDEX_op_goto_tb:
804             tci_args_l(insn, tb_ptr, &ptr);
805             tb_ptr = *(void **)ptr;
806             break;
807 
808         case INDEX_op_goto_ptr:
809             tci_args_r(insn, &r0);
810             ptr = (void *)regs[r0];
811             if (!ptr) {
812                 return 0;
813             }
814             tb_ptr = ptr;
815             break;
816 
817         case INDEX_op_qemu_ld_i32:
818             tci_args_rrm(insn, &r0, &r1, &oi);
819             taddr = regs[r1];
820             regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
821             break;
822 
823         case INDEX_op_qemu_ld_i64:
824             if (TCG_TARGET_REG_BITS == 64) {
825                 tci_args_rrm(insn, &r0, &r1, &oi);
826                 taddr = regs[r1];
827             } else {
828                 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
829                 taddr = regs[r2];
830                 oi = regs[r3];
831             }
832             tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
833             if (TCG_TARGET_REG_BITS == 32) {
834                 tci_write_reg64(regs, r1, r0, tmp64);
835             } else {
836                 regs[r0] = tmp64;
837             }
838             break;
839 
840         case INDEX_op_qemu_st_i32:
841             tci_args_rrm(insn, &r0, &r1, &oi);
842             taddr = regs[r1];
843             tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
844             break;
845 
846         case INDEX_op_qemu_st_i64:
847             if (TCG_TARGET_REG_BITS == 64) {
848                 tci_args_rrm(insn, &r0, &r1, &oi);
849                 tmp64 = regs[r0];
850                 taddr = regs[r1];
851             } else {
852                 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
853                 tmp64 = tci_uint64(regs[r1], regs[r0]);
854                 taddr = regs[r2];
855                 oi = regs[r3];
856             }
857             tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
858             break;
859 
860         case INDEX_op_mb:
861             /* Ensure ordering for all kinds */
862             smp_mb();
863             break;
864         default:
865             g_assert_not_reached();
866         }
867     }
868 }
869 
870 /*
871  * Disassembler that matches the interpreter
872  */
873 
874 static const char *str_r(TCGReg r)
875 {
876     static const char regs[TCG_TARGET_NB_REGS][4] = {
877         "r0", "r1", "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
878         "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
879     };
880 
881     QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
882     QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
883 
884     assert((unsigned)r < TCG_TARGET_NB_REGS);
885     return regs[r];
886 }
887 
888 static const char *str_c(TCGCond c)
889 {
890     static const char cond[16][8] = {
891         [TCG_COND_NEVER] = "never",
892         [TCG_COND_ALWAYS] = "always",
893         [TCG_COND_EQ] = "eq",
894         [TCG_COND_NE] = "ne",
895         [TCG_COND_LT] = "lt",
896         [TCG_COND_GE] = "ge",
897         [TCG_COND_LE] = "le",
898         [TCG_COND_GT] = "gt",
899         [TCG_COND_LTU] = "ltu",
900         [TCG_COND_GEU] = "geu",
901         [TCG_COND_LEU] = "leu",
902         [TCG_COND_GTU] = "gtu",
903         [TCG_COND_TSTEQ] = "tsteq",
904         [TCG_COND_TSTNE] = "tstne",
905     };
906 
907     assert((unsigned)c < ARRAY_SIZE(cond));
908     assert(cond[c][0] != 0);
909     return cond[c];
910 }
911 
912 /* Disassemble TCI bytecode. */
913 int print_insn_tci(bfd_vma addr, disassemble_info *info)
914 {
915     const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
916     const TCGOpDef *def;
917     const char *op_name;
918     uint32_t insn;
919     TCGOpcode op;
920     TCGReg r0, r1, r2, r3, r4, r5;
921     tcg_target_ulong i1;
922     int32_t s2;
923     TCGCond c;
924     MemOpIdx oi;
925     uint8_t pos, len;
926     void *ptr;
927 
928     /* TCI is always the host, so we don't need to load indirect. */
929     insn = *tb_ptr++;
930 
931     info->fprintf_func(info->stream, "%08x  ", insn);
932 
933     op = extract32(insn, 0, 8);
934     def = &tcg_op_defs[op];
935     op_name = def->name;
936 
937     switch (op) {
938     case INDEX_op_br:
939     case INDEX_op_exit_tb:
940     case INDEX_op_goto_tb:
941         tci_args_l(insn, tb_ptr, &ptr);
942         info->fprintf_func(info->stream, "%-12s  %p", op_name, ptr);
943         break;
944 
945     case INDEX_op_goto_ptr:
946         tci_args_r(insn, &r0);
947         info->fprintf_func(info->stream, "%-12s  %s", op_name, str_r(r0));
948         break;
949 
950     case INDEX_op_call:
951         tci_args_nl(insn, tb_ptr, &len, &ptr);
952         info->fprintf_func(info->stream, "%-12s  %d, %p", op_name, len, ptr);
953         break;
954 
955     case INDEX_op_brcond:
956         tci_args_rl(insn, tb_ptr, &r0, &ptr);
957         info->fprintf_func(info->stream, "%-12s  %s, 0, ne, %p",
958                            op_name, str_r(r0), ptr);
959         break;
960 
961     case INDEX_op_setcond:
962     case INDEX_op_tci_setcond32:
963         tci_args_rrrc(insn, &r0, &r1, &r2, &c);
964         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
965                            op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
966         break;
967 
968     case INDEX_op_tci_movi:
969         tci_args_ri(insn, &r0, &i1);
970         info->fprintf_func(info->stream, "%-12s  %s, 0x%" TCG_PRIlx,
971                            op_name, str_r(r0), i1);
972         break;
973 
974     case INDEX_op_tci_movl:
975         tci_args_rl(insn, tb_ptr, &r0, &ptr);
976         info->fprintf_func(info->stream, "%-12s  %s, %p",
977                            op_name, str_r(r0), ptr);
978         break;
979 
980     case INDEX_op_ld8u_i32:
981     case INDEX_op_ld8u_i64:
982     case INDEX_op_ld8s_i32:
983     case INDEX_op_ld8s_i64:
984     case INDEX_op_ld16u_i32:
985     case INDEX_op_ld16u_i64:
986     case INDEX_op_ld16s_i32:
987     case INDEX_op_ld16s_i64:
988     case INDEX_op_ld32u_i64:
989     case INDEX_op_ld32s_i64:
990     case INDEX_op_ld_i32:
991     case INDEX_op_ld_i64:
992     case INDEX_op_st8_i32:
993     case INDEX_op_st8_i64:
994     case INDEX_op_st16_i32:
995     case INDEX_op_st16_i64:
996     case INDEX_op_st32_i64:
997     case INDEX_op_st_i32:
998     case INDEX_op_st_i64:
999         tci_args_rrs(insn, &r0, &r1, &s2);
1000         info->fprintf_func(info->stream, "%-12s  %s, %s, %d",
1001                            op_name, str_r(r0), str_r(r1), s2);
1002         break;
1003 
1004     case INDEX_op_bswap16:
1005     case INDEX_op_bswap32:
1006     case INDEX_op_ctpop:
1007     case INDEX_op_mov:
1008     case INDEX_op_neg:
1009     case INDEX_op_not:
1010     case INDEX_op_ext_i32_i64:
1011     case INDEX_op_extu_i32_i64:
1012     case INDEX_op_bswap64:
1013         tci_args_rr(insn, &r0, &r1);
1014         info->fprintf_func(info->stream, "%-12s  %s, %s",
1015                            op_name, str_r(r0), str_r(r1));
1016         break;
1017 
1018     case INDEX_op_add:
1019     case INDEX_op_and:
1020     case INDEX_op_andc:
1021     case INDEX_op_clz:
1022     case INDEX_op_ctz:
1023     case INDEX_op_divs:
1024     case INDEX_op_divu:
1025     case INDEX_op_eqv:
1026     case INDEX_op_mul:
1027     case INDEX_op_nand:
1028     case INDEX_op_nor:
1029     case INDEX_op_or:
1030     case INDEX_op_orc:
1031     case INDEX_op_rems:
1032     case INDEX_op_remu:
1033     case INDEX_op_rotl:
1034     case INDEX_op_rotr:
1035     case INDEX_op_sar:
1036     case INDEX_op_shl:
1037     case INDEX_op_shr:
1038     case INDEX_op_sub:
1039     case INDEX_op_xor:
1040     case INDEX_op_tci_ctz32:
1041     case INDEX_op_tci_clz32:
1042     case INDEX_op_tci_divs32:
1043     case INDEX_op_tci_divu32:
1044     case INDEX_op_tci_rems32:
1045     case INDEX_op_tci_remu32:
1046     case INDEX_op_tci_rotl32:
1047     case INDEX_op_tci_rotr32:
1048         tci_args_rrr(insn, &r0, &r1, &r2);
1049         info->fprintf_func(info->stream, "%-12s  %s, %s, %s",
1050                            op_name, str_r(r0), str_r(r1), str_r(r2));
1051         break;
1052 
1053     case INDEX_op_deposit_i32:
1054     case INDEX_op_deposit_i64:
1055         tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1056         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %d, %d",
1057                            op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1058         break;
1059 
1060     case INDEX_op_extract_i32:
1061     case INDEX_op_extract_i64:
1062     case INDEX_op_sextract_i32:
1063     case INDEX_op_sextract_i64:
1064         tci_args_rrbb(insn, &r0, &r1, &pos, &len);
1065         info->fprintf_func(info->stream, "%-12s  %s,%s,%d,%d",
1066                            op_name, str_r(r0), str_r(r1), pos, len);
1067         break;
1068 
1069     case INDEX_op_tci_movcond32:
1070     case INDEX_op_movcond:
1071     case INDEX_op_setcond2_i32:
1072         tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1073         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1074                            op_name, str_r(r0), str_r(r1), str_r(r2),
1075                            str_r(r3), str_r(r4), str_c(c));
1076         break;
1077 
1078     case INDEX_op_muls2:
1079     case INDEX_op_mulu2:
1080         tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1081         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1082                            op_name, str_r(r0), str_r(r1),
1083                            str_r(r2), str_r(r3));
1084         break;
1085 
1086     case INDEX_op_add2_i32:
1087     case INDEX_op_add2_i64:
1088     case INDEX_op_sub2_i32:
1089     case INDEX_op_sub2_i64:
1090         tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1091         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1092                            op_name, str_r(r0), str_r(r1), str_r(r2),
1093                            str_r(r3), str_r(r4), str_r(r5));
1094         break;
1095 
1096     case INDEX_op_qemu_ld_i64:
1097     case INDEX_op_qemu_st_i64:
1098         if (TCG_TARGET_REG_BITS == 32) {
1099             tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1100             info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1101                                op_name, str_r(r0), str_r(r1),
1102                                str_r(r2), str_r(r3));
1103             break;
1104         }
1105         /* fall through */
1106     case INDEX_op_qemu_ld_i32:
1107     case INDEX_op_qemu_st_i32:
1108         tci_args_rrm(insn, &r0, &r1, &oi);
1109         info->fprintf_func(info->stream, "%-12s  %s, %s, %x",
1110                            op_name, str_r(r0), str_r(r1), oi);
1111         break;
1112 
1113     case 0:
1114         /* tcg_out_nop_fill uses zeros */
1115         if (insn == 0) {
1116             info->fprintf_func(info->stream, "align");
1117             break;
1118         }
1119         /* fall through */
1120 
1121     default:
1122         info->fprintf_func(info->stream, "illegal opcode %d", op);
1123         break;
1124     }
1125 
1126     return sizeof(insn);
1127 }
1128