util/bufferiszero: Add simd acceleration for aarch64
[qemu/armbru.git] / tcg / tci.c
blob3afb2235285a0db910bcd7687fbb3633d00f52cb
1 /*
2 * Tiny Code Interpreter for QEMU
4 * Copyright (c) 2009, 2011, 2016 Stefan Weil
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.
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.
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/>.
20 #include "qemu/osdep.h"
21 #include "tcg/tcg.h"
22 #include "tcg/helper-info.h"
23 #include "tcg/tcg-ldst.h"
24 #include <ffi.h>
28 * Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
29 * Without assertions, the interpreter runs much faster.
31 #if defined(CONFIG_DEBUG_TCG)
32 # define tci_assert(cond) assert(cond)
33 #else
34 # define tci_assert(cond) ((void)(cond))
35 #endif
37 __thread uintptr_t tci_tb_ptr;
39 static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
40 uint32_t low_index, uint64_t value)
42 regs[low_index] = (uint32_t)value;
43 regs[high_index] = value >> 32;
46 /* Create a 64 bit value from two 32 bit values. */
47 static uint64_t tci_uint64(uint32_t high, uint32_t low)
49 return ((uint64_t)high << 32) + low;
53 * Load sets of arguments all at once. The naming convention is:
54 * tci_args_<arguments>
55 * where arguments is a sequence of
57 * b = immediate (bit position)
58 * c = condition (TCGCond)
59 * i = immediate (uint32_t)
60 * I = immediate (tcg_target_ulong)
61 * l = label or pointer
62 * m = immediate (MemOpIdx)
63 * n = immediate (call return length)
64 * r = register
65 * s = signed ldst offset
68 static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
70 int diff = sextract32(insn, 12, 20);
71 *l0 = diff ? (void *)tb_ptr + diff : NULL;
74 static void tci_args_r(uint32_t insn, TCGReg *r0)
76 *r0 = extract32(insn, 8, 4);
79 static void tci_args_nl(uint32_t insn, const void *tb_ptr,
80 uint8_t *n0, void **l1)
82 *n0 = extract32(insn, 8, 4);
83 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
86 static void tci_args_rl(uint32_t insn, const void *tb_ptr,
87 TCGReg *r0, void **l1)
89 *r0 = extract32(insn, 8, 4);
90 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
93 static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
95 *r0 = extract32(insn, 8, 4);
96 *r1 = extract32(insn, 12, 4);
99 static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
101 *r0 = extract32(insn, 8, 4);
102 *i1 = sextract32(insn, 12, 20);
105 static void tci_args_rrm(uint32_t insn, TCGReg *r0,
106 TCGReg *r1, MemOpIdx *m2)
108 *r0 = extract32(insn, 8, 4);
109 *r1 = extract32(insn, 12, 4);
110 *m2 = extract32(insn, 16, 16);
113 static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
115 *r0 = extract32(insn, 8, 4);
116 *r1 = extract32(insn, 12, 4);
117 *r2 = extract32(insn, 16, 4);
120 static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
122 *r0 = extract32(insn, 8, 4);
123 *r1 = extract32(insn, 12, 4);
124 *i2 = sextract32(insn, 16, 16);
127 static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
128 uint8_t *i2, uint8_t *i3)
130 *r0 = extract32(insn, 8, 4);
131 *r1 = extract32(insn, 12, 4);
132 *i2 = extract32(insn, 16, 6);
133 *i3 = extract32(insn, 22, 6);
136 static void tci_args_rrrc(uint32_t insn,
137 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
139 *r0 = extract32(insn, 8, 4);
140 *r1 = extract32(insn, 12, 4);
141 *r2 = extract32(insn, 16, 4);
142 *c3 = extract32(insn, 20, 4);
145 static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
146 TCGReg *r2, uint8_t *i3, uint8_t *i4)
148 *r0 = extract32(insn, 8, 4);
149 *r1 = extract32(insn, 12, 4);
150 *r2 = extract32(insn, 16, 4);
151 *i3 = extract32(insn, 20, 6);
152 *i4 = extract32(insn, 26, 6);
155 static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
156 TCGReg *r2, TCGReg *r3, TCGReg *r4)
158 *r0 = extract32(insn, 8, 4);
159 *r1 = extract32(insn, 12, 4);
160 *r2 = extract32(insn, 16, 4);
161 *r3 = extract32(insn, 20, 4);
162 *r4 = extract32(insn, 24, 4);
165 static void tci_args_rrrr(uint32_t insn,
166 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
168 *r0 = extract32(insn, 8, 4);
169 *r1 = extract32(insn, 12, 4);
170 *r2 = extract32(insn, 16, 4);
171 *r3 = extract32(insn, 20, 4);
174 static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
175 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
177 *r0 = extract32(insn, 8, 4);
178 *r1 = extract32(insn, 12, 4);
179 *r2 = extract32(insn, 16, 4);
180 *r3 = extract32(insn, 20, 4);
181 *r4 = extract32(insn, 24, 4);
182 *c5 = extract32(insn, 28, 4);
185 static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
186 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
188 *r0 = extract32(insn, 8, 4);
189 *r1 = extract32(insn, 12, 4);
190 *r2 = extract32(insn, 16, 4);
191 *r3 = extract32(insn, 20, 4);
192 *r4 = extract32(insn, 24, 4);
193 *r5 = extract32(insn, 28, 4);
196 static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
198 bool result = false;
199 int32_t i0 = u0;
200 int32_t i1 = u1;
201 switch (condition) {
202 case TCG_COND_EQ:
203 result = (u0 == u1);
204 break;
205 case TCG_COND_NE:
206 result = (u0 != u1);
207 break;
208 case TCG_COND_LT:
209 result = (i0 < i1);
210 break;
211 case TCG_COND_GE:
212 result = (i0 >= i1);
213 break;
214 case TCG_COND_LE:
215 result = (i0 <= i1);
216 break;
217 case TCG_COND_GT:
218 result = (i0 > i1);
219 break;
220 case TCG_COND_LTU:
221 result = (u0 < u1);
222 break;
223 case TCG_COND_GEU:
224 result = (u0 >= u1);
225 break;
226 case TCG_COND_LEU:
227 result = (u0 <= u1);
228 break;
229 case TCG_COND_GTU:
230 result = (u0 > u1);
231 break;
232 case TCG_COND_TSTEQ:
233 result = (u0 & u1) == 0;
234 break;
235 case TCG_COND_TSTNE:
236 result = (u0 & u1) != 0;
237 break;
238 default:
239 g_assert_not_reached();
241 return result;
244 static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
246 bool result = false;
247 int64_t i0 = u0;
248 int64_t i1 = u1;
249 switch (condition) {
250 case TCG_COND_EQ:
251 result = (u0 == u1);
252 break;
253 case TCG_COND_NE:
254 result = (u0 != u1);
255 break;
256 case TCG_COND_LT:
257 result = (i0 < i1);
258 break;
259 case TCG_COND_GE:
260 result = (i0 >= i1);
261 break;
262 case TCG_COND_LE:
263 result = (i0 <= i1);
264 break;
265 case TCG_COND_GT:
266 result = (i0 > i1);
267 break;
268 case TCG_COND_LTU:
269 result = (u0 < u1);
270 break;
271 case TCG_COND_GEU:
272 result = (u0 >= u1);
273 break;
274 case TCG_COND_LEU:
275 result = (u0 <= u1);
276 break;
277 case TCG_COND_GTU:
278 result = (u0 > u1);
279 break;
280 case TCG_COND_TSTEQ:
281 result = (u0 & u1) == 0;
282 break;
283 case TCG_COND_TSTNE:
284 result = (u0 & u1) != 0;
285 break;
286 default:
287 g_assert_not_reached();
289 return result;
292 static uint64_t tci_qemu_ld(CPUArchState *env, uint64_t taddr,
293 MemOpIdx oi, const void *tb_ptr)
295 MemOp mop = get_memop(oi);
296 uintptr_t ra = (uintptr_t)tb_ptr;
298 switch (mop & MO_SSIZE) {
299 case MO_UB:
300 return helper_ldub_mmu(env, taddr, oi, ra);
301 case MO_SB:
302 return helper_ldsb_mmu(env, taddr, oi, ra);
303 case MO_UW:
304 return helper_lduw_mmu(env, taddr, oi, ra);
305 case MO_SW:
306 return helper_ldsw_mmu(env, taddr, oi, ra);
307 case MO_UL:
308 return helper_ldul_mmu(env, taddr, oi, ra);
309 case MO_SL:
310 return helper_ldsl_mmu(env, taddr, oi, ra);
311 case MO_UQ:
312 return helper_ldq_mmu(env, taddr, oi, ra);
313 default:
314 g_assert_not_reached();
318 static void tci_qemu_st(CPUArchState *env, uint64_t taddr, uint64_t val,
319 MemOpIdx oi, const void *tb_ptr)
321 MemOp mop = get_memop(oi);
322 uintptr_t ra = (uintptr_t)tb_ptr;
324 switch (mop & MO_SIZE) {
325 case MO_UB:
326 helper_stb_mmu(env, taddr, val, oi, ra);
327 break;
328 case MO_UW:
329 helper_stw_mmu(env, taddr, val, oi, ra);
330 break;
331 case MO_UL:
332 helper_stl_mmu(env, taddr, val, oi, ra);
333 break;
334 case MO_UQ:
335 helper_stq_mmu(env, taddr, val, oi, ra);
336 break;
337 default:
338 g_assert_not_reached();
342 #if TCG_TARGET_REG_BITS == 64
343 # define CASE_32_64(x) \
344 case glue(glue(INDEX_op_, x), _i64): \
345 case glue(glue(INDEX_op_, x), _i32):
346 # define CASE_64(x) \
347 case glue(glue(INDEX_op_, x), _i64):
348 #else
349 # define CASE_32_64(x) \
350 case glue(glue(INDEX_op_, x), _i32):
351 # define CASE_64(x)
352 #endif
354 /* Interpret pseudo code in tb. */
356 * Disable CFI checks.
357 * One possible operation in the pseudo code is a call to binary code.
358 * Therefore, disable CFI checks in the interpreter function
360 uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
361 const void *v_tb_ptr)
363 const uint32_t *tb_ptr = v_tb_ptr;
364 tcg_target_ulong regs[TCG_TARGET_NB_REGS];
365 uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
366 / sizeof(uint64_t)];
368 regs[TCG_AREG0] = (tcg_target_ulong)env;
369 regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
370 tci_assert(tb_ptr);
372 for (;;) {
373 uint32_t insn;
374 TCGOpcode opc;
375 TCGReg r0, r1, r2, r3, r4, r5;
376 tcg_target_ulong t1;
377 TCGCond condition;
378 uint8_t pos, len;
379 uint32_t tmp32;
380 uint64_t tmp64, taddr;
381 uint64_t T1, T2;
382 MemOpIdx oi;
383 int32_t ofs;
384 void *ptr;
386 insn = *tb_ptr++;
387 opc = extract32(insn, 0, 8);
389 switch (opc) {
390 case INDEX_op_call:
392 void *call_slots[MAX_CALL_IARGS];
393 ffi_cif *cif;
394 void *func;
395 unsigned i, s, n;
397 tci_args_nl(insn, tb_ptr, &len, &ptr);
398 func = ((void **)ptr)[0];
399 cif = ((void **)ptr)[1];
401 n = cif->nargs;
402 for (i = s = 0; i < n; ++i) {
403 ffi_type *t = cif->arg_types[i];
404 call_slots[i] = &stack[s];
405 s += DIV_ROUND_UP(t->size, 8);
408 /* Helper functions may need to access the "return address" */
409 tci_tb_ptr = (uintptr_t)tb_ptr;
410 ffi_call(cif, func, stack, call_slots);
413 switch (len) {
414 case 0: /* void */
415 break;
416 case 1: /* uint32_t */
418 * The result winds up "left-aligned" in the stack[0] slot.
419 * Note that libffi has an odd special case in that it will
420 * always widen an integral result to ffi_arg.
422 if (sizeof(ffi_arg) == 8) {
423 regs[TCG_REG_R0] = (uint32_t)stack[0];
424 } else {
425 regs[TCG_REG_R0] = *(uint32_t *)stack;
427 break;
428 case 2: /* uint64_t */
430 * For TCG_TARGET_REG_BITS == 32, the register pair
431 * must stay in host memory order.
433 memcpy(&regs[TCG_REG_R0], stack, 8);
434 break;
435 case 3: /* Int128 */
436 memcpy(&regs[TCG_REG_R0], stack, 16);
437 break;
438 default:
439 g_assert_not_reached();
441 break;
443 case INDEX_op_br:
444 tci_args_l(insn, tb_ptr, &ptr);
445 tb_ptr = ptr;
446 continue;
447 case INDEX_op_setcond_i32:
448 tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
449 regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
450 break;
451 case INDEX_op_movcond_i32:
452 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
453 tmp32 = tci_compare32(regs[r1], regs[r2], condition);
454 regs[r0] = regs[tmp32 ? r3 : r4];
455 break;
456 #if TCG_TARGET_REG_BITS == 32
457 case INDEX_op_setcond2_i32:
458 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
459 T1 = tci_uint64(regs[r2], regs[r1]);
460 T2 = tci_uint64(regs[r4], regs[r3]);
461 regs[r0] = tci_compare64(T1, T2, condition);
462 break;
463 #elif TCG_TARGET_REG_BITS == 64
464 case INDEX_op_setcond_i64:
465 tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
466 regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
467 break;
468 case INDEX_op_movcond_i64:
469 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
470 tmp32 = tci_compare64(regs[r1], regs[r2], condition);
471 regs[r0] = regs[tmp32 ? r3 : r4];
472 break;
473 #endif
474 CASE_32_64(mov)
475 tci_args_rr(insn, &r0, &r1);
476 regs[r0] = regs[r1];
477 break;
478 case INDEX_op_tci_movi:
479 tci_args_ri(insn, &r0, &t1);
480 regs[r0] = t1;
481 break;
482 case INDEX_op_tci_movl:
483 tci_args_rl(insn, tb_ptr, &r0, &ptr);
484 regs[r0] = *(tcg_target_ulong *)ptr;
485 break;
487 /* Load/store operations (32 bit). */
489 CASE_32_64(ld8u)
490 tci_args_rrs(insn, &r0, &r1, &ofs);
491 ptr = (void *)(regs[r1] + ofs);
492 regs[r0] = *(uint8_t *)ptr;
493 break;
494 CASE_32_64(ld8s)
495 tci_args_rrs(insn, &r0, &r1, &ofs);
496 ptr = (void *)(regs[r1] + ofs);
497 regs[r0] = *(int8_t *)ptr;
498 break;
499 CASE_32_64(ld16u)
500 tci_args_rrs(insn, &r0, &r1, &ofs);
501 ptr = (void *)(regs[r1] + ofs);
502 regs[r0] = *(uint16_t *)ptr;
503 break;
504 CASE_32_64(ld16s)
505 tci_args_rrs(insn, &r0, &r1, &ofs);
506 ptr = (void *)(regs[r1] + ofs);
507 regs[r0] = *(int16_t *)ptr;
508 break;
509 case INDEX_op_ld_i32:
510 CASE_64(ld32u)
511 tci_args_rrs(insn, &r0, &r1, &ofs);
512 ptr = (void *)(regs[r1] + ofs);
513 regs[r0] = *(uint32_t *)ptr;
514 break;
515 CASE_32_64(st8)
516 tci_args_rrs(insn, &r0, &r1, &ofs);
517 ptr = (void *)(regs[r1] + ofs);
518 *(uint8_t *)ptr = regs[r0];
519 break;
520 CASE_32_64(st16)
521 tci_args_rrs(insn, &r0, &r1, &ofs);
522 ptr = (void *)(regs[r1] + ofs);
523 *(uint16_t *)ptr = regs[r0];
524 break;
525 case INDEX_op_st_i32:
526 CASE_64(st32)
527 tci_args_rrs(insn, &r0, &r1, &ofs);
528 ptr = (void *)(regs[r1] + ofs);
529 *(uint32_t *)ptr = regs[r0];
530 break;
532 /* Arithmetic operations (mixed 32/64 bit). */
534 CASE_32_64(add)
535 tci_args_rrr(insn, &r0, &r1, &r2);
536 regs[r0] = regs[r1] + regs[r2];
537 break;
538 CASE_32_64(sub)
539 tci_args_rrr(insn, &r0, &r1, &r2);
540 regs[r0] = regs[r1] - regs[r2];
541 break;
542 CASE_32_64(mul)
543 tci_args_rrr(insn, &r0, &r1, &r2);
544 regs[r0] = regs[r1] * regs[r2];
545 break;
546 CASE_32_64(and)
547 tci_args_rrr(insn, &r0, &r1, &r2);
548 regs[r0] = regs[r1] & regs[r2];
549 break;
550 CASE_32_64(or)
551 tci_args_rrr(insn, &r0, &r1, &r2);
552 regs[r0] = regs[r1] | regs[r2];
553 break;
554 CASE_32_64(xor)
555 tci_args_rrr(insn, &r0, &r1, &r2);
556 regs[r0] = regs[r1] ^ regs[r2];
557 break;
558 #if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64
559 CASE_32_64(andc)
560 tci_args_rrr(insn, &r0, &r1, &r2);
561 regs[r0] = regs[r1] & ~regs[r2];
562 break;
563 #endif
564 #if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64
565 CASE_32_64(orc)
566 tci_args_rrr(insn, &r0, &r1, &r2);
567 regs[r0] = regs[r1] | ~regs[r2];
568 break;
569 #endif
570 #if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64
571 CASE_32_64(eqv)
572 tci_args_rrr(insn, &r0, &r1, &r2);
573 regs[r0] = ~(regs[r1] ^ regs[r2]);
574 break;
575 #endif
576 #if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64
577 CASE_32_64(nand)
578 tci_args_rrr(insn, &r0, &r1, &r2);
579 regs[r0] = ~(regs[r1] & regs[r2]);
580 break;
581 #endif
582 #if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64
583 CASE_32_64(nor)
584 tci_args_rrr(insn, &r0, &r1, &r2);
585 regs[r0] = ~(regs[r1] | regs[r2]);
586 break;
587 #endif
589 /* Arithmetic operations (32 bit). */
591 case INDEX_op_div_i32:
592 tci_args_rrr(insn, &r0, &r1, &r2);
593 regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
594 break;
595 case INDEX_op_divu_i32:
596 tci_args_rrr(insn, &r0, &r1, &r2);
597 regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
598 break;
599 case INDEX_op_rem_i32:
600 tci_args_rrr(insn, &r0, &r1, &r2);
601 regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
602 break;
603 case INDEX_op_remu_i32:
604 tci_args_rrr(insn, &r0, &r1, &r2);
605 regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
606 break;
607 #if TCG_TARGET_HAS_clz_i32
608 case INDEX_op_clz_i32:
609 tci_args_rrr(insn, &r0, &r1, &r2);
610 tmp32 = regs[r1];
611 regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
612 break;
613 #endif
614 #if TCG_TARGET_HAS_ctz_i32
615 case INDEX_op_ctz_i32:
616 tci_args_rrr(insn, &r0, &r1, &r2);
617 tmp32 = regs[r1];
618 regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
619 break;
620 #endif
621 #if TCG_TARGET_HAS_ctpop_i32
622 case INDEX_op_ctpop_i32:
623 tci_args_rr(insn, &r0, &r1);
624 regs[r0] = ctpop32(regs[r1]);
625 break;
626 #endif
628 /* Shift/rotate operations (32 bit). */
630 case INDEX_op_shl_i32:
631 tci_args_rrr(insn, &r0, &r1, &r2);
632 regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
633 break;
634 case INDEX_op_shr_i32:
635 tci_args_rrr(insn, &r0, &r1, &r2);
636 regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
637 break;
638 case INDEX_op_sar_i32:
639 tci_args_rrr(insn, &r0, &r1, &r2);
640 regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
641 break;
642 #if TCG_TARGET_HAS_rot_i32
643 case INDEX_op_rotl_i32:
644 tci_args_rrr(insn, &r0, &r1, &r2);
645 regs[r0] = rol32(regs[r1], regs[r2] & 31);
646 break;
647 case INDEX_op_rotr_i32:
648 tci_args_rrr(insn, &r0, &r1, &r2);
649 regs[r0] = ror32(regs[r1], regs[r2] & 31);
650 break;
651 #endif
652 #if TCG_TARGET_HAS_deposit_i32
653 case INDEX_op_deposit_i32:
654 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
655 regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
656 break;
657 #endif
658 #if TCG_TARGET_HAS_extract_i32
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 #endif
664 #if TCG_TARGET_HAS_sextract_i32
665 case INDEX_op_sextract_i32:
666 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
667 regs[r0] = sextract32(regs[r1], pos, len);
668 break;
669 #endif
670 case INDEX_op_brcond_i32:
671 tci_args_rl(insn, tb_ptr, &r0, &ptr);
672 if ((uint32_t)regs[r0]) {
673 tb_ptr = ptr;
675 break;
676 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
677 case INDEX_op_add2_i32:
678 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
679 T1 = tci_uint64(regs[r3], regs[r2]);
680 T2 = tci_uint64(regs[r5], regs[r4]);
681 tci_write_reg64(regs, r1, r0, T1 + T2);
682 break;
683 #endif
684 #if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
685 case INDEX_op_sub2_i32:
686 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
687 T1 = tci_uint64(regs[r3], regs[r2]);
688 T2 = tci_uint64(regs[r5], regs[r4]);
689 tci_write_reg64(regs, r1, r0, T1 - T2);
690 break;
691 #endif
692 #if TCG_TARGET_HAS_mulu2_i32
693 case INDEX_op_mulu2_i32:
694 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
695 tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
696 tci_write_reg64(regs, r1, r0, tmp64);
697 break;
698 #endif
699 #if TCG_TARGET_HAS_muls2_i32
700 case INDEX_op_muls2_i32:
701 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
702 tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
703 tci_write_reg64(regs, r1, r0, tmp64);
704 break;
705 #endif
706 #if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
707 CASE_32_64(ext8s)
708 tci_args_rr(insn, &r0, &r1);
709 regs[r0] = (int8_t)regs[r1];
710 break;
711 #endif
712 #if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64 || \
713 TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
714 CASE_32_64(ext16s)
715 tci_args_rr(insn, &r0, &r1);
716 regs[r0] = (int16_t)regs[r1];
717 break;
718 #endif
719 #if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
720 CASE_32_64(ext8u)
721 tci_args_rr(insn, &r0, &r1);
722 regs[r0] = (uint8_t)regs[r1];
723 break;
724 #endif
725 #if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
726 CASE_32_64(ext16u)
727 tci_args_rr(insn, &r0, &r1);
728 regs[r0] = (uint16_t)regs[r1];
729 break;
730 #endif
731 #if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
732 CASE_32_64(bswap16)
733 tci_args_rr(insn, &r0, &r1);
734 regs[r0] = bswap16(regs[r1]);
735 break;
736 #endif
737 #if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
738 CASE_32_64(bswap32)
739 tci_args_rr(insn, &r0, &r1);
740 regs[r0] = bswap32(regs[r1]);
741 break;
742 #endif
743 #if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
744 CASE_32_64(not)
745 tci_args_rr(insn, &r0, &r1);
746 regs[r0] = ~regs[r1];
747 break;
748 #endif
749 CASE_32_64(neg)
750 tci_args_rr(insn, &r0, &r1);
751 regs[r0] = -regs[r1];
752 break;
753 #if TCG_TARGET_REG_BITS == 64
754 /* Load/store operations (64 bit). */
756 case INDEX_op_ld32s_i64:
757 tci_args_rrs(insn, &r0, &r1, &ofs);
758 ptr = (void *)(regs[r1] + ofs);
759 regs[r0] = *(int32_t *)ptr;
760 break;
761 case INDEX_op_ld_i64:
762 tci_args_rrs(insn, &r0, &r1, &ofs);
763 ptr = (void *)(regs[r1] + ofs);
764 regs[r0] = *(uint64_t *)ptr;
765 break;
766 case INDEX_op_st_i64:
767 tci_args_rrs(insn, &r0, &r1, &ofs);
768 ptr = (void *)(regs[r1] + ofs);
769 *(uint64_t *)ptr = regs[r0];
770 break;
772 /* Arithmetic operations (64 bit). */
774 case INDEX_op_div_i64:
775 tci_args_rrr(insn, &r0, &r1, &r2);
776 regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
777 break;
778 case INDEX_op_divu_i64:
779 tci_args_rrr(insn, &r0, &r1, &r2);
780 regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
781 break;
782 case INDEX_op_rem_i64:
783 tci_args_rrr(insn, &r0, &r1, &r2);
784 regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
785 break;
786 case INDEX_op_remu_i64:
787 tci_args_rrr(insn, &r0, &r1, &r2);
788 regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
789 break;
790 #if TCG_TARGET_HAS_clz_i64
791 case INDEX_op_clz_i64:
792 tci_args_rrr(insn, &r0, &r1, &r2);
793 regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
794 break;
795 #endif
796 #if TCG_TARGET_HAS_ctz_i64
797 case INDEX_op_ctz_i64:
798 tci_args_rrr(insn, &r0, &r1, &r2);
799 regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
800 break;
801 #endif
802 #if TCG_TARGET_HAS_ctpop_i64
803 case INDEX_op_ctpop_i64:
804 tci_args_rr(insn, &r0, &r1);
805 regs[r0] = ctpop64(regs[r1]);
806 break;
807 #endif
808 #if TCG_TARGET_HAS_mulu2_i64
809 case INDEX_op_mulu2_i64:
810 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
811 mulu64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
812 break;
813 #endif
814 #if TCG_TARGET_HAS_muls2_i64
815 case INDEX_op_muls2_i64:
816 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
817 muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
818 break;
819 #endif
820 #if TCG_TARGET_HAS_add2_i64
821 case INDEX_op_add2_i64:
822 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
823 T1 = regs[r2] + regs[r4];
824 T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
825 regs[r0] = T1;
826 regs[r1] = T2;
827 break;
828 #endif
829 #if TCG_TARGET_HAS_add2_i64
830 case INDEX_op_sub2_i64:
831 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
832 T1 = regs[r2] - regs[r4];
833 T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
834 regs[r0] = T1;
835 regs[r1] = T2;
836 break;
837 #endif
839 /* Shift/rotate operations (64 bit). */
841 case INDEX_op_shl_i64:
842 tci_args_rrr(insn, &r0, &r1, &r2);
843 regs[r0] = regs[r1] << (regs[r2] & 63);
844 break;
845 case INDEX_op_shr_i64:
846 tci_args_rrr(insn, &r0, &r1, &r2);
847 regs[r0] = regs[r1] >> (regs[r2] & 63);
848 break;
849 case INDEX_op_sar_i64:
850 tci_args_rrr(insn, &r0, &r1, &r2);
851 regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
852 break;
853 #if TCG_TARGET_HAS_rot_i64
854 case INDEX_op_rotl_i64:
855 tci_args_rrr(insn, &r0, &r1, &r2);
856 regs[r0] = rol64(regs[r1], regs[r2] & 63);
857 break;
858 case INDEX_op_rotr_i64:
859 tci_args_rrr(insn, &r0, &r1, &r2);
860 regs[r0] = ror64(regs[r1], regs[r2] & 63);
861 break;
862 #endif
863 #if TCG_TARGET_HAS_deposit_i64
864 case INDEX_op_deposit_i64:
865 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
866 regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
867 break;
868 #endif
869 #if TCG_TARGET_HAS_extract_i64
870 case INDEX_op_extract_i64:
871 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
872 regs[r0] = extract64(regs[r1], pos, len);
873 break;
874 #endif
875 #if TCG_TARGET_HAS_sextract_i64
876 case INDEX_op_sextract_i64:
877 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
878 regs[r0] = sextract64(regs[r1], pos, len);
879 break;
880 #endif
881 case INDEX_op_brcond_i64:
882 tci_args_rl(insn, tb_ptr, &r0, &ptr);
883 if (regs[r0]) {
884 tb_ptr = ptr;
886 break;
887 case INDEX_op_ext32s_i64:
888 case INDEX_op_ext_i32_i64:
889 tci_args_rr(insn, &r0, &r1);
890 regs[r0] = (int32_t)regs[r1];
891 break;
892 case INDEX_op_ext32u_i64:
893 case INDEX_op_extu_i32_i64:
894 tci_args_rr(insn, &r0, &r1);
895 regs[r0] = (uint32_t)regs[r1];
896 break;
897 #if TCG_TARGET_HAS_bswap64_i64
898 case INDEX_op_bswap64_i64:
899 tci_args_rr(insn, &r0, &r1);
900 regs[r0] = bswap64(regs[r1]);
901 break;
902 #endif
903 #endif /* TCG_TARGET_REG_BITS == 64 */
905 /* QEMU specific operations. */
907 case INDEX_op_exit_tb:
908 tci_args_l(insn, tb_ptr, &ptr);
909 return (uintptr_t)ptr;
911 case INDEX_op_goto_tb:
912 tci_args_l(insn, tb_ptr, &ptr);
913 tb_ptr = *(void **)ptr;
914 break;
916 case INDEX_op_goto_ptr:
917 tci_args_r(insn, &r0);
918 ptr = (void *)regs[r0];
919 if (!ptr) {
920 return 0;
922 tb_ptr = ptr;
923 break;
925 case INDEX_op_qemu_ld_a32_i32:
926 tci_args_rrm(insn, &r0, &r1, &oi);
927 taddr = (uint32_t)regs[r1];
928 goto do_ld_i32;
929 case INDEX_op_qemu_ld_a64_i32:
930 if (TCG_TARGET_REG_BITS == 64) {
931 tci_args_rrm(insn, &r0, &r1, &oi);
932 taddr = regs[r1];
933 } else {
934 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
935 taddr = tci_uint64(regs[r2], regs[r1]);
936 oi = regs[r3];
938 do_ld_i32:
939 regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
940 break;
942 case INDEX_op_qemu_ld_a32_i64:
943 if (TCG_TARGET_REG_BITS == 64) {
944 tci_args_rrm(insn, &r0, &r1, &oi);
945 taddr = (uint32_t)regs[r1];
946 } else {
947 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
948 taddr = (uint32_t)regs[r2];
949 oi = regs[r3];
951 goto do_ld_i64;
952 case INDEX_op_qemu_ld_a64_i64:
953 if (TCG_TARGET_REG_BITS == 64) {
954 tci_args_rrm(insn, &r0, &r1, &oi);
955 taddr = regs[r1];
956 } else {
957 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
958 taddr = tci_uint64(regs[r3], regs[r2]);
959 oi = regs[r4];
961 do_ld_i64:
962 tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
963 if (TCG_TARGET_REG_BITS == 32) {
964 tci_write_reg64(regs, r1, r0, tmp64);
965 } else {
966 regs[r0] = tmp64;
968 break;
970 case INDEX_op_qemu_st_a32_i32:
971 tci_args_rrm(insn, &r0, &r1, &oi);
972 taddr = (uint32_t)regs[r1];
973 goto do_st_i32;
974 case INDEX_op_qemu_st_a64_i32:
975 if (TCG_TARGET_REG_BITS == 64) {
976 tci_args_rrm(insn, &r0, &r1, &oi);
977 taddr = regs[r1];
978 } else {
979 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
980 taddr = tci_uint64(regs[r2], regs[r1]);
981 oi = regs[r3];
983 do_st_i32:
984 tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
985 break;
987 case INDEX_op_qemu_st_a32_i64:
988 if (TCG_TARGET_REG_BITS == 64) {
989 tci_args_rrm(insn, &r0, &r1, &oi);
990 tmp64 = regs[r0];
991 taddr = (uint32_t)regs[r1];
992 } else {
993 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
994 tmp64 = tci_uint64(regs[r1], regs[r0]);
995 taddr = (uint32_t)regs[r2];
996 oi = regs[r3];
998 goto do_st_i64;
999 case INDEX_op_qemu_st_a64_i64:
1000 if (TCG_TARGET_REG_BITS == 64) {
1001 tci_args_rrm(insn, &r0, &r1, &oi);
1002 tmp64 = regs[r0];
1003 taddr = regs[r1];
1004 } else {
1005 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1006 tmp64 = tci_uint64(regs[r1], regs[r0]);
1007 taddr = tci_uint64(regs[r3], regs[r2]);
1008 oi = regs[r4];
1010 do_st_i64:
1011 tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
1012 break;
1014 case INDEX_op_mb:
1015 /* Ensure ordering for all kinds */
1016 smp_mb();
1017 break;
1018 default:
1019 g_assert_not_reached();
1025 * Disassembler that matches the interpreter
1028 static const char *str_r(TCGReg r)
1030 static const char regs[TCG_TARGET_NB_REGS][4] = {
1031 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1032 "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
1035 QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
1036 QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
1038 assert((unsigned)r < TCG_TARGET_NB_REGS);
1039 return regs[r];
1042 static const char *str_c(TCGCond c)
1044 static const char cond[16][8] = {
1045 [TCG_COND_NEVER] = "never",
1046 [TCG_COND_ALWAYS] = "always",
1047 [TCG_COND_EQ] = "eq",
1048 [TCG_COND_NE] = "ne",
1049 [TCG_COND_LT] = "lt",
1050 [TCG_COND_GE] = "ge",
1051 [TCG_COND_LE] = "le",
1052 [TCG_COND_GT] = "gt",
1053 [TCG_COND_LTU] = "ltu",
1054 [TCG_COND_GEU] = "geu",
1055 [TCG_COND_LEU] = "leu",
1056 [TCG_COND_GTU] = "gtu",
1057 [TCG_COND_TSTEQ] = "tsteq",
1058 [TCG_COND_TSTNE] = "tstne",
1061 assert((unsigned)c < ARRAY_SIZE(cond));
1062 assert(cond[c][0] != 0);
1063 return cond[c];
1066 /* Disassemble TCI bytecode. */
1067 int print_insn_tci(bfd_vma addr, disassemble_info *info)
1069 const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
1070 const TCGOpDef *def;
1071 const char *op_name;
1072 uint32_t insn;
1073 TCGOpcode op;
1074 TCGReg r0, r1, r2, r3, r4, r5;
1075 tcg_target_ulong i1;
1076 int32_t s2;
1077 TCGCond c;
1078 MemOpIdx oi;
1079 uint8_t pos, len;
1080 void *ptr;
1082 /* TCI is always the host, so we don't need to load indirect. */
1083 insn = *tb_ptr++;
1085 info->fprintf_func(info->stream, "%08x ", insn);
1087 op = extract32(insn, 0, 8);
1088 def = &tcg_op_defs[op];
1089 op_name = def->name;
1091 switch (op) {
1092 case INDEX_op_br:
1093 case INDEX_op_exit_tb:
1094 case INDEX_op_goto_tb:
1095 tci_args_l(insn, tb_ptr, &ptr);
1096 info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
1097 break;
1099 case INDEX_op_goto_ptr:
1100 tci_args_r(insn, &r0);
1101 info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0));
1102 break;
1104 case INDEX_op_call:
1105 tci_args_nl(insn, tb_ptr, &len, &ptr);
1106 info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
1107 break;
1109 case INDEX_op_brcond_i32:
1110 case INDEX_op_brcond_i64:
1111 tci_args_rl(insn, tb_ptr, &r0, &ptr);
1112 info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
1113 op_name, str_r(r0), ptr);
1114 break;
1116 case INDEX_op_setcond_i32:
1117 case INDEX_op_setcond_i64:
1118 tci_args_rrrc(insn, &r0, &r1, &r2, &c);
1119 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1120 op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1121 break;
1123 case INDEX_op_tci_movi:
1124 tci_args_ri(insn, &r0, &i1);
1125 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1126 op_name, str_r(r0), i1);
1127 break;
1129 case INDEX_op_tci_movl:
1130 tci_args_rl(insn, tb_ptr, &r0, &ptr);
1131 info->fprintf_func(info->stream, "%-12s %s, %p",
1132 op_name, str_r(r0), ptr);
1133 break;
1135 case INDEX_op_ld8u_i32:
1136 case INDEX_op_ld8u_i64:
1137 case INDEX_op_ld8s_i32:
1138 case INDEX_op_ld8s_i64:
1139 case INDEX_op_ld16u_i32:
1140 case INDEX_op_ld16u_i64:
1141 case INDEX_op_ld16s_i32:
1142 case INDEX_op_ld16s_i64:
1143 case INDEX_op_ld32u_i64:
1144 case INDEX_op_ld32s_i64:
1145 case INDEX_op_ld_i32:
1146 case INDEX_op_ld_i64:
1147 case INDEX_op_st8_i32:
1148 case INDEX_op_st8_i64:
1149 case INDEX_op_st16_i32:
1150 case INDEX_op_st16_i64:
1151 case INDEX_op_st32_i64:
1152 case INDEX_op_st_i32:
1153 case INDEX_op_st_i64:
1154 tci_args_rrs(insn, &r0, &r1, &s2);
1155 info->fprintf_func(info->stream, "%-12s %s, %s, %d",
1156 op_name, str_r(r0), str_r(r1), s2);
1157 break;
1159 case INDEX_op_mov_i32:
1160 case INDEX_op_mov_i64:
1161 case INDEX_op_ext8s_i32:
1162 case INDEX_op_ext8s_i64:
1163 case INDEX_op_ext8u_i32:
1164 case INDEX_op_ext8u_i64:
1165 case INDEX_op_ext16s_i32:
1166 case INDEX_op_ext16s_i64:
1167 case INDEX_op_ext16u_i32:
1168 case INDEX_op_ext32s_i64:
1169 case INDEX_op_ext32u_i64:
1170 case INDEX_op_ext_i32_i64:
1171 case INDEX_op_extu_i32_i64:
1172 case INDEX_op_bswap16_i32:
1173 case INDEX_op_bswap16_i64:
1174 case INDEX_op_bswap32_i32:
1175 case INDEX_op_bswap32_i64:
1176 case INDEX_op_bswap64_i64:
1177 case INDEX_op_not_i32:
1178 case INDEX_op_not_i64:
1179 case INDEX_op_neg_i32:
1180 case INDEX_op_neg_i64:
1181 case INDEX_op_ctpop_i32:
1182 case INDEX_op_ctpop_i64:
1183 tci_args_rr(insn, &r0, &r1);
1184 info->fprintf_func(info->stream, "%-12s %s, %s",
1185 op_name, str_r(r0), str_r(r1));
1186 break;
1188 case INDEX_op_add_i32:
1189 case INDEX_op_add_i64:
1190 case INDEX_op_sub_i32:
1191 case INDEX_op_sub_i64:
1192 case INDEX_op_mul_i32:
1193 case INDEX_op_mul_i64:
1194 case INDEX_op_and_i32:
1195 case INDEX_op_and_i64:
1196 case INDEX_op_or_i32:
1197 case INDEX_op_or_i64:
1198 case INDEX_op_xor_i32:
1199 case INDEX_op_xor_i64:
1200 case INDEX_op_andc_i32:
1201 case INDEX_op_andc_i64:
1202 case INDEX_op_orc_i32:
1203 case INDEX_op_orc_i64:
1204 case INDEX_op_eqv_i32:
1205 case INDEX_op_eqv_i64:
1206 case INDEX_op_nand_i32:
1207 case INDEX_op_nand_i64:
1208 case INDEX_op_nor_i32:
1209 case INDEX_op_nor_i64:
1210 case INDEX_op_div_i32:
1211 case INDEX_op_div_i64:
1212 case INDEX_op_rem_i32:
1213 case INDEX_op_rem_i64:
1214 case INDEX_op_divu_i32:
1215 case INDEX_op_divu_i64:
1216 case INDEX_op_remu_i32:
1217 case INDEX_op_remu_i64:
1218 case INDEX_op_shl_i32:
1219 case INDEX_op_shl_i64:
1220 case INDEX_op_shr_i32:
1221 case INDEX_op_shr_i64:
1222 case INDEX_op_sar_i32:
1223 case INDEX_op_sar_i64:
1224 case INDEX_op_rotl_i32:
1225 case INDEX_op_rotl_i64:
1226 case INDEX_op_rotr_i32:
1227 case INDEX_op_rotr_i64:
1228 case INDEX_op_clz_i32:
1229 case INDEX_op_clz_i64:
1230 case INDEX_op_ctz_i32:
1231 case INDEX_op_ctz_i64:
1232 tci_args_rrr(insn, &r0, &r1, &r2);
1233 info->fprintf_func(info->stream, "%-12s %s, %s, %s",
1234 op_name, str_r(r0), str_r(r1), str_r(r2));
1235 break;
1237 case INDEX_op_deposit_i32:
1238 case INDEX_op_deposit_i64:
1239 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1240 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
1241 op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1242 break;
1244 case INDEX_op_extract_i32:
1245 case INDEX_op_extract_i64:
1246 case INDEX_op_sextract_i32:
1247 case INDEX_op_sextract_i64:
1248 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
1249 info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d",
1250 op_name, str_r(r0), str_r(r1), pos, len);
1251 break;
1253 case INDEX_op_movcond_i32:
1254 case INDEX_op_movcond_i64:
1255 case INDEX_op_setcond2_i32:
1256 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1257 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1258 op_name, str_r(r0), str_r(r1), str_r(r2),
1259 str_r(r3), str_r(r4), str_c(c));
1260 break;
1262 case INDEX_op_mulu2_i32:
1263 case INDEX_op_mulu2_i64:
1264 case INDEX_op_muls2_i32:
1265 case INDEX_op_muls2_i64:
1266 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1267 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1268 op_name, str_r(r0), str_r(r1),
1269 str_r(r2), str_r(r3));
1270 break;
1272 case INDEX_op_add2_i32:
1273 case INDEX_op_add2_i64:
1274 case INDEX_op_sub2_i32:
1275 case INDEX_op_sub2_i64:
1276 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1277 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1278 op_name, str_r(r0), str_r(r1), str_r(r2),
1279 str_r(r3), str_r(r4), str_r(r5));
1280 break;
1282 case INDEX_op_qemu_ld_a32_i32:
1283 case INDEX_op_qemu_st_a32_i32:
1284 len = 1 + 1;
1285 goto do_qemu_ldst;
1286 case INDEX_op_qemu_ld_a32_i64:
1287 case INDEX_op_qemu_st_a32_i64:
1288 case INDEX_op_qemu_ld_a64_i32:
1289 case INDEX_op_qemu_st_a64_i32:
1290 len = 1 + DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1291 goto do_qemu_ldst;
1292 case INDEX_op_qemu_ld_a64_i64:
1293 case INDEX_op_qemu_st_a64_i64:
1294 len = 2 * DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1295 goto do_qemu_ldst;
1296 do_qemu_ldst:
1297 switch (len) {
1298 case 2:
1299 tci_args_rrm(insn, &r0, &r1, &oi);
1300 info->fprintf_func(info->stream, "%-12s %s, %s, %x",
1301 op_name, str_r(r0), str_r(r1), oi);
1302 break;
1303 case 3:
1304 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1305 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1306 op_name, str_r(r0), str_r(r1),
1307 str_r(r2), str_r(r3));
1308 break;
1309 case 4:
1310 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1311 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
1312 op_name, str_r(r0), str_r(r1),
1313 str_r(r2), str_r(r3), str_r(r4));
1314 break;
1315 default:
1316 g_assert_not_reached();
1318 break;
1320 case 0:
1321 /* tcg_out_nop_fill uses zeros */
1322 if (insn == 0) {
1323 info->fprintf_func(info->stream, "align");
1324 break;
1326 /* fall through */
1328 default:
1329 info->fprintf_func(info->stream, "illegal opcode %d", op);
1330 break;
1333 return sizeof(insn);