xref: /openbmc/qemu/tcg/tci.c (revision 0dd07ee1122abaf1adb4f1e00a8e0b89937f53bd)
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 #if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
694         CASE_32_64(bswap32)
695             tci_args_rr(insn, &r0, &r1);
696             regs[r0] = bswap32(regs[r1]);
697             break;
698 #endif
699 #if TCG_TARGET_REG_BITS == 64
700             /* Load/store operations (64 bit). */
701 
702         case INDEX_op_ld32s_i64:
703             tci_args_rrs(insn, &r0, &r1, &ofs);
704             ptr = (void *)(regs[r1] + ofs);
705             regs[r0] = *(int32_t *)ptr;
706             break;
707         case INDEX_op_ld_i64:
708             tci_args_rrs(insn, &r0, &r1, &ofs);
709             ptr = (void *)(regs[r1] + ofs);
710             regs[r0] = *(uint64_t *)ptr;
711             break;
712         case INDEX_op_st_i64:
713             tci_args_rrs(insn, &r0, &r1, &ofs);
714             ptr = (void *)(regs[r1] + ofs);
715             *(uint64_t *)ptr = regs[r0];
716             break;
717 
718             /* Arithmetic operations (64 bit). */
719 
720         case INDEX_op_divs:
721             tci_args_rrr(insn, &r0, &r1, &r2);
722             regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
723             break;
724         case INDEX_op_divu:
725             tci_args_rrr(insn, &r0, &r1, &r2);
726             regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
727             break;
728         case INDEX_op_rems:
729             tci_args_rrr(insn, &r0, &r1, &r2);
730             regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
731             break;
732         case INDEX_op_remu:
733             tci_args_rrr(insn, &r0, &r1, &r2);
734             regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
735             break;
736         case INDEX_op_clz:
737             tci_args_rrr(insn, &r0, &r1, &r2);
738             regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
739             break;
740         case INDEX_op_ctz:
741             tci_args_rrr(insn, &r0, &r1, &r2);
742             regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
743             break;
744 #if TCG_TARGET_HAS_add2_i64
745         case INDEX_op_add2_i64:
746             tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
747             T1 = regs[r2] + regs[r4];
748             T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
749             regs[r0] = T1;
750             regs[r1] = T2;
751             break;
752 #endif
753 #if TCG_TARGET_HAS_add2_i64
754         case INDEX_op_sub2_i64:
755             tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
756             T1 = regs[r2] - regs[r4];
757             T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
758             regs[r0] = T1;
759             regs[r1] = T2;
760             break;
761 #endif
762 
763             /* Shift/rotate operations (64 bit). */
764 
765         case INDEX_op_rotl:
766             tci_args_rrr(insn, &r0, &r1, &r2);
767             regs[r0] = rol64(regs[r1], regs[r2] & 63);
768             break;
769         case INDEX_op_rotr:
770             tci_args_rrr(insn, &r0, &r1, &r2);
771             regs[r0] = ror64(regs[r1], regs[r2] & 63);
772             break;
773         case INDEX_op_deposit_i64:
774             tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
775             regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
776             break;
777         case INDEX_op_extract_i64:
778             tci_args_rrbb(insn, &r0, &r1, &pos, &len);
779             regs[r0] = extract64(regs[r1], pos, len);
780             break;
781         case INDEX_op_sextract_i64:
782             tci_args_rrbb(insn, &r0, &r1, &pos, &len);
783             regs[r0] = sextract64(regs[r1], pos, len);
784             break;
785         case INDEX_op_ext_i32_i64:
786             tci_args_rr(insn, &r0, &r1);
787             regs[r0] = (int32_t)regs[r1];
788             break;
789         case INDEX_op_extu_i32_i64:
790             tci_args_rr(insn, &r0, &r1);
791             regs[r0] = (uint32_t)regs[r1];
792             break;
793 #if TCG_TARGET_HAS_bswap64_i64
794         case INDEX_op_bswap64_i64:
795             tci_args_rr(insn, &r0, &r1);
796             regs[r0] = bswap64(regs[r1]);
797             break;
798 #endif
799 #endif /* TCG_TARGET_REG_BITS == 64 */
800 
801             /* QEMU specific operations. */
802 
803         case INDEX_op_exit_tb:
804             tci_args_l(insn, tb_ptr, &ptr);
805             return (uintptr_t)ptr;
806 
807         case INDEX_op_goto_tb:
808             tci_args_l(insn, tb_ptr, &ptr);
809             tb_ptr = *(void **)ptr;
810             break;
811 
812         case INDEX_op_goto_ptr:
813             tci_args_r(insn, &r0);
814             ptr = (void *)regs[r0];
815             if (!ptr) {
816                 return 0;
817             }
818             tb_ptr = ptr;
819             break;
820 
821         case INDEX_op_qemu_ld_i32:
822             tci_args_rrm(insn, &r0, &r1, &oi);
823             taddr = regs[r1];
824             regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
825             break;
826 
827         case INDEX_op_qemu_ld_i64:
828             if (TCG_TARGET_REG_BITS == 64) {
829                 tci_args_rrm(insn, &r0, &r1, &oi);
830                 taddr = regs[r1];
831             } else {
832                 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
833                 taddr = regs[r2];
834                 oi = regs[r3];
835             }
836             tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
837             if (TCG_TARGET_REG_BITS == 32) {
838                 tci_write_reg64(regs, r1, r0, tmp64);
839             } else {
840                 regs[r0] = tmp64;
841             }
842             break;
843 
844         case INDEX_op_qemu_st_i32:
845             tci_args_rrm(insn, &r0, &r1, &oi);
846             taddr = regs[r1];
847             tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
848             break;
849 
850         case INDEX_op_qemu_st_i64:
851             if (TCG_TARGET_REG_BITS == 64) {
852                 tci_args_rrm(insn, &r0, &r1, &oi);
853                 tmp64 = regs[r0];
854                 taddr = regs[r1];
855             } else {
856                 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
857                 tmp64 = tci_uint64(regs[r1], regs[r0]);
858                 taddr = regs[r2];
859                 oi = regs[r3];
860             }
861             tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
862             break;
863 
864         case INDEX_op_mb:
865             /* Ensure ordering for all kinds */
866             smp_mb();
867             break;
868         default:
869             g_assert_not_reached();
870         }
871     }
872 }
873 
874 /*
875  * Disassembler that matches the interpreter
876  */
877 
878 static const char *str_r(TCGReg r)
879 {
880     static const char regs[TCG_TARGET_NB_REGS][4] = {
881         "r0", "r1", "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
882         "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
883     };
884 
885     QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
886     QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
887 
888     assert((unsigned)r < TCG_TARGET_NB_REGS);
889     return regs[r];
890 }
891 
892 static const char *str_c(TCGCond c)
893 {
894     static const char cond[16][8] = {
895         [TCG_COND_NEVER] = "never",
896         [TCG_COND_ALWAYS] = "always",
897         [TCG_COND_EQ] = "eq",
898         [TCG_COND_NE] = "ne",
899         [TCG_COND_LT] = "lt",
900         [TCG_COND_GE] = "ge",
901         [TCG_COND_LE] = "le",
902         [TCG_COND_GT] = "gt",
903         [TCG_COND_LTU] = "ltu",
904         [TCG_COND_GEU] = "geu",
905         [TCG_COND_LEU] = "leu",
906         [TCG_COND_GTU] = "gtu",
907         [TCG_COND_TSTEQ] = "tsteq",
908         [TCG_COND_TSTNE] = "tstne",
909     };
910 
911     assert((unsigned)c < ARRAY_SIZE(cond));
912     assert(cond[c][0] != 0);
913     return cond[c];
914 }
915 
916 /* Disassemble TCI bytecode. */
917 int print_insn_tci(bfd_vma addr, disassemble_info *info)
918 {
919     const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
920     const TCGOpDef *def;
921     const char *op_name;
922     uint32_t insn;
923     TCGOpcode op;
924     TCGReg r0, r1, r2, r3, r4, r5;
925     tcg_target_ulong i1;
926     int32_t s2;
927     TCGCond c;
928     MemOpIdx oi;
929     uint8_t pos, len;
930     void *ptr;
931 
932     /* TCI is always the host, so we don't need to load indirect. */
933     insn = *tb_ptr++;
934 
935     info->fprintf_func(info->stream, "%08x  ", insn);
936 
937     op = extract32(insn, 0, 8);
938     def = &tcg_op_defs[op];
939     op_name = def->name;
940 
941     switch (op) {
942     case INDEX_op_br:
943     case INDEX_op_exit_tb:
944     case INDEX_op_goto_tb:
945         tci_args_l(insn, tb_ptr, &ptr);
946         info->fprintf_func(info->stream, "%-12s  %p", op_name, ptr);
947         break;
948 
949     case INDEX_op_goto_ptr:
950         tci_args_r(insn, &r0);
951         info->fprintf_func(info->stream, "%-12s  %s", op_name, str_r(r0));
952         break;
953 
954     case INDEX_op_call:
955         tci_args_nl(insn, tb_ptr, &len, &ptr);
956         info->fprintf_func(info->stream, "%-12s  %d, %p", op_name, len, ptr);
957         break;
958 
959     case INDEX_op_brcond:
960         tci_args_rl(insn, tb_ptr, &r0, &ptr);
961         info->fprintf_func(info->stream, "%-12s  %s, 0, ne, %p",
962                            op_name, str_r(r0), ptr);
963         break;
964 
965     case INDEX_op_setcond:
966     case INDEX_op_tci_setcond32:
967         tci_args_rrrc(insn, &r0, &r1, &r2, &c);
968         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
969                            op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
970         break;
971 
972     case INDEX_op_tci_movi:
973         tci_args_ri(insn, &r0, &i1);
974         info->fprintf_func(info->stream, "%-12s  %s, 0x%" TCG_PRIlx,
975                            op_name, str_r(r0), i1);
976         break;
977 
978     case INDEX_op_tci_movl:
979         tci_args_rl(insn, tb_ptr, &r0, &ptr);
980         info->fprintf_func(info->stream, "%-12s  %s, %p",
981                            op_name, str_r(r0), ptr);
982         break;
983 
984     case INDEX_op_ld8u_i32:
985     case INDEX_op_ld8u_i64:
986     case INDEX_op_ld8s_i32:
987     case INDEX_op_ld8s_i64:
988     case INDEX_op_ld16u_i32:
989     case INDEX_op_ld16u_i64:
990     case INDEX_op_ld16s_i32:
991     case INDEX_op_ld16s_i64:
992     case INDEX_op_ld32u_i64:
993     case INDEX_op_ld32s_i64:
994     case INDEX_op_ld_i32:
995     case INDEX_op_ld_i64:
996     case INDEX_op_st8_i32:
997     case INDEX_op_st8_i64:
998     case INDEX_op_st16_i32:
999     case INDEX_op_st16_i64:
1000     case INDEX_op_st32_i64:
1001     case INDEX_op_st_i32:
1002     case INDEX_op_st_i64:
1003         tci_args_rrs(insn, &r0, &r1, &s2);
1004         info->fprintf_func(info->stream, "%-12s  %s, %s, %d",
1005                            op_name, str_r(r0), str_r(r1), s2);
1006         break;
1007 
1008     case INDEX_op_bswap16:
1009     case INDEX_op_ctpop:
1010     case INDEX_op_mov:
1011     case INDEX_op_neg:
1012     case INDEX_op_not:
1013     case INDEX_op_ext_i32_i64:
1014     case INDEX_op_extu_i32_i64:
1015     case INDEX_op_bswap32_i32:
1016     case INDEX_op_bswap32_i64:
1017     case INDEX_op_bswap64_i64:
1018         tci_args_rr(insn, &r0, &r1);
1019         info->fprintf_func(info->stream, "%-12s  %s, %s",
1020                            op_name, str_r(r0), str_r(r1));
1021         break;
1022 
1023     case INDEX_op_add:
1024     case INDEX_op_and:
1025     case INDEX_op_andc:
1026     case INDEX_op_clz:
1027     case INDEX_op_ctz:
1028     case INDEX_op_divs:
1029     case INDEX_op_divu:
1030     case INDEX_op_eqv:
1031     case INDEX_op_mul:
1032     case INDEX_op_nand:
1033     case INDEX_op_nor:
1034     case INDEX_op_or:
1035     case INDEX_op_orc:
1036     case INDEX_op_rems:
1037     case INDEX_op_remu:
1038     case INDEX_op_rotl:
1039     case INDEX_op_rotr:
1040     case INDEX_op_sar:
1041     case INDEX_op_shl:
1042     case INDEX_op_shr:
1043     case INDEX_op_sub:
1044     case INDEX_op_xor:
1045     case INDEX_op_tci_ctz32:
1046     case INDEX_op_tci_clz32:
1047     case INDEX_op_tci_divs32:
1048     case INDEX_op_tci_divu32:
1049     case INDEX_op_tci_rems32:
1050     case INDEX_op_tci_remu32:
1051     case INDEX_op_tci_rotl32:
1052     case INDEX_op_tci_rotr32:
1053         tci_args_rrr(insn, &r0, &r1, &r2);
1054         info->fprintf_func(info->stream, "%-12s  %s, %s, %s",
1055                            op_name, str_r(r0), str_r(r1), str_r(r2));
1056         break;
1057 
1058     case INDEX_op_deposit_i32:
1059     case INDEX_op_deposit_i64:
1060         tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1061         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %d, %d",
1062                            op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1063         break;
1064 
1065     case INDEX_op_extract_i32:
1066     case INDEX_op_extract_i64:
1067     case INDEX_op_sextract_i32:
1068     case INDEX_op_sextract_i64:
1069         tci_args_rrbb(insn, &r0, &r1, &pos, &len);
1070         info->fprintf_func(info->stream, "%-12s  %s,%s,%d,%d",
1071                            op_name, str_r(r0), str_r(r1), pos, len);
1072         break;
1073 
1074     case INDEX_op_tci_movcond32:
1075     case INDEX_op_movcond:
1076     case INDEX_op_setcond2_i32:
1077         tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1078         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1079                            op_name, str_r(r0), str_r(r1), str_r(r2),
1080                            str_r(r3), str_r(r4), str_c(c));
1081         break;
1082 
1083     case INDEX_op_muls2:
1084     case INDEX_op_mulu2:
1085         tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1086         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1087                            op_name, str_r(r0), str_r(r1),
1088                            str_r(r2), str_r(r3));
1089         break;
1090 
1091     case INDEX_op_add2_i32:
1092     case INDEX_op_add2_i64:
1093     case INDEX_op_sub2_i32:
1094     case INDEX_op_sub2_i64:
1095         tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1096         info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1097                            op_name, str_r(r0), str_r(r1), str_r(r2),
1098                            str_r(r3), str_r(r4), str_r(r5));
1099         break;
1100 
1101     case INDEX_op_qemu_ld_i64:
1102     case INDEX_op_qemu_st_i64:
1103         if (TCG_TARGET_REG_BITS == 32) {
1104             tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1105             info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1106                                op_name, str_r(r0), str_r(r1),
1107                                str_r(r2), str_r(r3));
1108             break;
1109         }
1110         /* fall through */
1111     case INDEX_op_qemu_ld_i32:
1112     case INDEX_op_qemu_st_i32:
1113         tci_args_rrm(insn, &r0, &r1, &oi);
1114         info->fprintf_func(info->stream, "%-12s  %s, %s, %x",
1115                            op_name, str_r(r0), str_r(r1), oi);
1116         break;
1117 
1118     case 0:
1119         /* tcg_out_nop_fill uses zeros */
1120         if (insn == 0) {
1121             info->fprintf_func(info->stream, "align");
1122             break;
1123         }
1124         /* fall through */
1125 
1126     default:
1127         info->fprintf_func(info->stream, "illegal opcode %d", op);
1128         break;
1129     }
1130 
1131     return sizeof(insn);
1132 }
1133