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