Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20210413...
[qemu/ar7.git] / tcg / tci.c
blobd68c5a4e55e049f7255617bbff32356c96b519f1
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"
22 /* Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
23 * Without assertions, the interpreter runs much faster. */
24 #if defined(CONFIG_DEBUG_TCG)
25 # define tci_assert(cond) assert(cond)
26 #else
27 # define tci_assert(cond) ((void)(cond))
28 #endif
30 #include "qemu-common.h"
31 #include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
32 #include "exec/cpu_ldst.h"
33 #include "tcg/tcg-op.h"
34 #include "qemu/compiler.h"
36 #if MAX_OPC_PARAM_IARGS != 6
37 # error Fix needed, number of supported input arguments changed!
38 #endif
39 #if TCG_TARGET_REG_BITS == 32
40 typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
41 tcg_target_ulong, tcg_target_ulong,
42 tcg_target_ulong, tcg_target_ulong,
43 tcg_target_ulong, tcg_target_ulong,
44 tcg_target_ulong, tcg_target_ulong,
45 tcg_target_ulong, tcg_target_ulong);
46 #else
47 typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
48 tcg_target_ulong, tcg_target_ulong,
49 tcg_target_ulong, tcg_target_ulong);
50 #endif
52 __thread uintptr_t tci_tb_ptr;
54 static tcg_target_ulong tci_read_reg(const tcg_target_ulong *regs, TCGReg index)
56 tci_assert(index < TCG_TARGET_NB_REGS);
57 return regs[index];
60 static void
61 tci_write_reg(tcg_target_ulong *regs, TCGReg index, tcg_target_ulong value)
63 tci_assert(index < TCG_TARGET_NB_REGS);
64 tci_assert(index != TCG_AREG0);
65 tci_assert(index != TCG_REG_CALL_STACK);
66 regs[index] = value;
69 static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
70 uint32_t low_index, uint64_t value)
72 tci_write_reg(regs, low_index, value);
73 tci_write_reg(regs, high_index, value >> 32);
76 /* Create a 64 bit value from two 32 bit values. */
77 static uint64_t tci_uint64(uint32_t high, uint32_t low)
79 return ((uint64_t)high << 32) + low;
82 /* Read constant byte from bytecode. */
83 static uint8_t tci_read_b(const uint8_t **tb_ptr)
85 return *(tb_ptr[0]++);
88 /* Read register number from bytecode. */
89 static TCGReg tci_read_r(const uint8_t **tb_ptr)
91 uint8_t regno = tci_read_b(tb_ptr);
92 tci_assert(regno < TCG_TARGET_NB_REGS);
93 return regno;
96 /* Read constant (native size) from bytecode. */
97 static tcg_target_ulong tci_read_i(const uint8_t **tb_ptr)
99 tcg_target_ulong value = *(const tcg_target_ulong *)(*tb_ptr);
100 *tb_ptr += sizeof(value);
101 return value;
104 /* Read unsigned constant (32 bit) from bytecode. */
105 static uint32_t tci_read_i32(const uint8_t **tb_ptr)
107 uint32_t value = *(const uint32_t *)(*tb_ptr);
108 *tb_ptr += sizeof(value);
109 return value;
112 /* Read signed constant (32 bit) from bytecode. */
113 static int32_t tci_read_s32(const uint8_t **tb_ptr)
115 int32_t value = *(const int32_t *)(*tb_ptr);
116 *tb_ptr += sizeof(value);
117 return value;
120 static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
122 return tci_read_i(tb_ptr);
126 * Load sets of arguments all at once. The naming convention is:
127 * tci_args_<arguments>
128 * where arguments is a sequence of
130 * b = immediate (bit position)
131 * c = condition (TCGCond)
132 * i = immediate (uint32_t)
133 * I = immediate (tcg_target_ulong)
134 * l = label or pointer
135 * m = immediate (TCGMemOpIdx)
136 * r = register
137 * s = signed ldst offset
140 static void check_size(const uint8_t *start, const uint8_t **tb_ptr)
142 const uint8_t *old_code_ptr = start - 2;
143 uint8_t op_size = old_code_ptr[1];
144 tci_assert(*tb_ptr == old_code_ptr + op_size);
147 static void tci_args_l(const uint8_t **tb_ptr, void **l0)
149 const uint8_t *start = *tb_ptr;
151 *l0 = (void *)tci_read_label(tb_ptr);
153 check_size(start, tb_ptr);
156 static void tci_args_rr(const uint8_t **tb_ptr,
157 TCGReg *r0, TCGReg *r1)
159 const uint8_t *start = *tb_ptr;
161 *r0 = tci_read_r(tb_ptr);
162 *r1 = tci_read_r(tb_ptr);
164 check_size(start, tb_ptr);
167 static void tci_args_ri(const uint8_t **tb_ptr,
168 TCGReg *r0, tcg_target_ulong *i1)
170 const uint8_t *start = *tb_ptr;
172 *r0 = tci_read_r(tb_ptr);
173 *i1 = tci_read_i32(tb_ptr);
175 check_size(start, tb_ptr);
178 #if TCG_TARGET_REG_BITS == 64
179 static void tci_args_rI(const uint8_t **tb_ptr,
180 TCGReg *r0, tcg_target_ulong *i1)
182 const uint8_t *start = *tb_ptr;
184 *r0 = tci_read_r(tb_ptr);
185 *i1 = tci_read_i(tb_ptr);
187 check_size(start, tb_ptr);
189 #endif
191 static void tci_args_rrm(const uint8_t **tb_ptr,
192 TCGReg *r0, TCGReg *r1, TCGMemOpIdx *m2)
194 const uint8_t *start = *tb_ptr;
196 *r0 = tci_read_r(tb_ptr);
197 *r1 = tci_read_r(tb_ptr);
198 *m2 = tci_read_i32(tb_ptr);
200 check_size(start, tb_ptr);
203 static void tci_args_rrr(const uint8_t **tb_ptr,
204 TCGReg *r0, TCGReg *r1, TCGReg *r2)
206 const uint8_t *start = *tb_ptr;
208 *r0 = tci_read_r(tb_ptr);
209 *r1 = tci_read_r(tb_ptr);
210 *r2 = tci_read_r(tb_ptr);
212 check_size(start, tb_ptr);
215 static void tci_args_rrs(const uint8_t **tb_ptr,
216 TCGReg *r0, TCGReg *r1, int32_t *i2)
218 const uint8_t *start = *tb_ptr;
220 *r0 = tci_read_r(tb_ptr);
221 *r1 = tci_read_r(tb_ptr);
222 *i2 = tci_read_s32(tb_ptr);
224 check_size(start, tb_ptr);
227 static void tci_args_rrcl(const uint8_t **tb_ptr,
228 TCGReg *r0, TCGReg *r1, TCGCond *c2, void **l3)
230 const uint8_t *start = *tb_ptr;
232 *r0 = tci_read_r(tb_ptr);
233 *r1 = tci_read_r(tb_ptr);
234 *c2 = tci_read_b(tb_ptr);
235 *l3 = (void *)tci_read_label(tb_ptr);
237 check_size(start, tb_ptr);
240 static void tci_args_rrrc(const uint8_t **tb_ptr,
241 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
243 const uint8_t *start = *tb_ptr;
245 *r0 = tci_read_r(tb_ptr);
246 *r1 = tci_read_r(tb_ptr);
247 *r2 = tci_read_r(tb_ptr);
248 *c3 = tci_read_b(tb_ptr);
250 check_size(start, tb_ptr);
253 static void tci_args_rrrm(const uint8_t **tb_ptr,
254 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
256 const uint8_t *start = *tb_ptr;
258 *r0 = tci_read_r(tb_ptr);
259 *r1 = tci_read_r(tb_ptr);
260 *r2 = tci_read_r(tb_ptr);
261 *m3 = tci_read_i32(tb_ptr);
263 check_size(start, tb_ptr);
266 static void tci_args_rrrbb(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
267 TCGReg *r2, uint8_t *i3, uint8_t *i4)
269 const uint8_t *start = *tb_ptr;
271 *r0 = tci_read_r(tb_ptr);
272 *r1 = tci_read_r(tb_ptr);
273 *r2 = tci_read_r(tb_ptr);
274 *i3 = tci_read_b(tb_ptr);
275 *i4 = tci_read_b(tb_ptr);
277 check_size(start, tb_ptr);
280 static void tci_args_rrrrm(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
281 TCGReg *r2, TCGReg *r3, TCGMemOpIdx *m4)
283 const uint8_t *start = *tb_ptr;
285 *r0 = tci_read_r(tb_ptr);
286 *r1 = tci_read_r(tb_ptr);
287 *r2 = tci_read_r(tb_ptr);
288 *r3 = tci_read_r(tb_ptr);
289 *m4 = tci_read_i32(tb_ptr);
291 check_size(start, tb_ptr);
294 #if TCG_TARGET_REG_BITS == 32
295 static void tci_args_rrrr(const uint8_t **tb_ptr,
296 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
298 const uint8_t *start = *tb_ptr;
300 *r0 = tci_read_r(tb_ptr);
301 *r1 = tci_read_r(tb_ptr);
302 *r2 = tci_read_r(tb_ptr);
303 *r3 = tci_read_r(tb_ptr);
305 check_size(start, tb_ptr);
308 static void tci_args_rrrrcl(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
309 TCGReg *r2, TCGReg *r3, TCGCond *c4, void **l5)
311 const uint8_t *start = *tb_ptr;
313 *r0 = tci_read_r(tb_ptr);
314 *r1 = tci_read_r(tb_ptr);
315 *r2 = tci_read_r(tb_ptr);
316 *r3 = tci_read_r(tb_ptr);
317 *c4 = tci_read_b(tb_ptr);
318 *l5 = (void *)tci_read_label(tb_ptr);
320 check_size(start, tb_ptr);
323 static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
324 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
326 const uint8_t *start = *tb_ptr;
328 *r0 = tci_read_r(tb_ptr);
329 *r1 = tci_read_r(tb_ptr);
330 *r2 = tci_read_r(tb_ptr);
331 *r3 = tci_read_r(tb_ptr);
332 *r4 = tci_read_r(tb_ptr);
333 *c5 = tci_read_b(tb_ptr);
335 check_size(start, tb_ptr);
338 static void tci_args_rrrrrr(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
339 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
341 const uint8_t *start = *tb_ptr;
343 *r0 = tci_read_r(tb_ptr);
344 *r1 = tci_read_r(tb_ptr);
345 *r2 = tci_read_r(tb_ptr);
346 *r3 = tci_read_r(tb_ptr);
347 *r4 = tci_read_r(tb_ptr);
348 *r5 = tci_read_r(tb_ptr);
350 check_size(start, tb_ptr);
352 #endif
354 static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
356 bool result = false;
357 int32_t i0 = u0;
358 int32_t i1 = u1;
359 switch (condition) {
360 case TCG_COND_EQ:
361 result = (u0 == u1);
362 break;
363 case TCG_COND_NE:
364 result = (u0 != u1);
365 break;
366 case TCG_COND_LT:
367 result = (i0 < i1);
368 break;
369 case TCG_COND_GE:
370 result = (i0 >= i1);
371 break;
372 case TCG_COND_LE:
373 result = (i0 <= i1);
374 break;
375 case TCG_COND_GT:
376 result = (i0 > i1);
377 break;
378 case TCG_COND_LTU:
379 result = (u0 < u1);
380 break;
381 case TCG_COND_GEU:
382 result = (u0 >= u1);
383 break;
384 case TCG_COND_LEU:
385 result = (u0 <= u1);
386 break;
387 case TCG_COND_GTU:
388 result = (u0 > u1);
389 break;
390 default:
391 g_assert_not_reached();
393 return result;
396 static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
398 bool result = false;
399 int64_t i0 = u0;
400 int64_t i1 = u1;
401 switch (condition) {
402 case TCG_COND_EQ:
403 result = (u0 == u1);
404 break;
405 case TCG_COND_NE:
406 result = (u0 != u1);
407 break;
408 case TCG_COND_LT:
409 result = (i0 < i1);
410 break;
411 case TCG_COND_GE:
412 result = (i0 >= i1);
413 break;
414 case TCG_COND_LE:
415 result = (i0 <= i1);
416 break;
417 case TCG_COND_GT:
418 result = (i0 > i1);
419 break;
420 case TCG_COND_LTU:
421 result = (u0 < u1);
422 break;
423 case TCG_COND_GEU:
424 result = (u0 >= u1);
425 break;
426 case TCG_COND_LEU:
427 result = (u0 <= u1);
428 break;
429 case TCG_COND_GTU:
430 result = (u0 > u1);
431 break;
432 default:
433 g_assert_not_reached();
435 return result;
438 #define qemu_ld_ub \
439 cpu_ldub_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
440 #define qemu_ld_leuw \
441 cpu_lduw_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
442 #define qemu_ld_leul \
443 cpu_ldl_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
444 #define qemu_ld_leq \
445 cpu_ldq_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
446 #define qemu_ld_beuw \
447 cpu_lduw_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
448 #define qemu_ld_beul \
449 cpu_ldl_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
450 #define qemu_ld_beq \
451 cpu_ldq_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
452 #define qemu_st_b(X) \
453 cpu_stb_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
454 #define qemu_st_lew(X) \
455 cpu_stw_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
456 #define qemu_st_lel(X) \
457 cpu_stl_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
458 #define qemu_st_leq(X) \
459 cpu_stq_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
460 #define qemu_st_bew(X) \
461 cpu_stw_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
462 #define qemu_st_bel(X) \
463 cpu_stl_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
464 #define qemu_st_beq(X) \
465 cpu_stq_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
467 #if TCG_TARGET_REG_BITS == 64
468 # define CASE_32_64(x) \
469 case glue(glue(INDEX_op_, x), _i64): \
470 case glue(glue(INDEX_op_, x), _i32):
471 # define CASE_64(x) \
472 case glue(glue(INDEX_op_, x), _i64):
473 #else
474 # define CASE_32_64(x) \
475 case glue(glue(INDEX_op_, x), _i32):
476 # define CASE_64(x)
477 #endif
479 /* Interpret pseudo code in tb. */
481 * Disable CFI checks.
482 * One possible operation in the pseudo code is a call to binary code.
483 * Therefore, disable CFI checks in the interpreter function
485 uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
486 const void *v_tb_ptr)
488 const uint8_t *tb_ptr = v_tb_ptr;
489 tcg_target_ulong regs[TCG_TARGET_NB_REGS];
490 long tcg_temps[CPU_TEMP_BUF_NLONGS];
491 uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
493 regs[TCG_AREG0] = (tcg_target_ulong)env;
494 regs[TCG_REG_CALL_STACK] = sp_value;
495 tci_assert(tb_ptr);
497 for (;;) {
498 TCGOpcode opc = tb_ptr[0];
499 TCGReg r0, r1, r2, r3;
500 tcg_target_ulong t1;
501 TCGCond condition;
502 target_ulong taddr;
503 uint8_t pos, len;
504 uint32_t tmp32;
505 uint64_t tmp64;
506 #if TCG_TARGET_REG_BITS == 32
507 TCGReg r4, r5;
508 uint64_t T1, T2;
509 #endif
510 TCGMemOpIdx oi;
511 int32_t ofs;
512 void *ptr;
514 /* Skip opcode and size entry. */
515 tb_ptr += 2;
517 switch (opc) {
518 case INDEX_op_call:
519 tci_args_l(&tb_ptr, &ptr);
520 tci_tb_ptr = (uintptr_t)tb_ptr;
521 #if TCG_TARGET_REG_BITS == 32
522 tmp64 = ((helper_function)ptr)(tci_read_reg(regs, TCG_REG_R0),
523 tci_read_reg(regs, TCG_REG_R1),
524 tci_read_reg(regs, TCG_REG_R2),
525 tci_read_reg(regs, TCG_REG_R3),
526 tci_read_reg(regs, TCG_REG_R4),
527 tci_read_reg(regs, TCG_REG_R5),
528 tci_read_reg(regs, TCG_REG_R6),
529 tci_read_reg(regs, TCG_REG_R7),
530 tci_read_reg(regs, TCG_REG_R8),
531 tci_read_reg(regs, TCG_REG_R9),
532 tci_read_reg(regs, TCG_REG_R10),
533 tci_read_reg(regs, TCG_REG_R11));
534 tci_write_reg(regs, TCG_REG_R0, tmp64);
535 tci_write_reg(regs, TCG_REG_R1, tmp64 >> 32);
536 #else
537 tmp64 = ((helper_function)ptr)(tci_read_reg(regs, TCG_REG_R0),
538 tci_read_reg(regs, TCG_REG_R1),
539 tci_read_reg(regs, TCG_REG_R2),
540 tci_read_reg(regs, TCG_REG_R3),
541 tci_read_reg(regs, TCG_REG_R4),
542 tci_read_reg(regs, TCG_REG_R5));
543 tci_write_reg(regs, TCG_REG_R0, tmp64);
544 #endif
545 break;
546 case INDEX_op_br:
547 tci_args_l(&tb_ptr, &ptr);
548 tb_ptr = ptr;
549 continue;
550 case INDEX_op_setcond_i32:
551 tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &condition);
552 regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
553 break;
554 #if TCG_TARGET_REG_BITS == 32
555 case INDEX_op_setcond2_i32:
556 tci_args_rrrrrc(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &condition);
557 T1 = tci_uint64(regs[r2], regs[r1]);
558 T2 = tci_uint64(regs[r4], regs[r3]);
559 regs[r0] = tci_compare64(T1, T2, condition);
560 break;
561 #elif TCG_TARGET_REG_BITS == 64
562 case INDEX_op_setcond_i64:
563 tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &condition);
564 regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
565 break;
566 #endif
567 CASE_32_64(mov)
568 tci_args_rr(&tb_ptr, &r0, &r1);
569 regs[r0] = regs[r1];
570 break;
571 case INDEX_op_tci_movi_i32:
572 tci_args_ri(&tb_ptr, &r0, &t1);
573 regs[r0] = t1;
574 break;
576 /* Load/store operations (32 bit). */
578 CASE_32_64(ld8u)
579 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
580 ptr = (void *)(regs[r1] + ofs);
581 regs[r0] = *(uint8_t *)ptr;
582 break;
583 CASE_32_64(ld8s)
584 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
585 ptr = (void *)(regs[r1] + ofs);
586 regs[r0] = *(int8_t *)ptr;
587 break;
588 CASE_32_64(ld16u)
589 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
590 ptr = (void *)(regs[r1] + ofs);
591 regs[r0] = *(uint16_t *)ptr;
592 break;
593 CASE_32_64(ld16s)
594 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
595 ptr = (void *)(regs[r1] + ofs);
596 regs[r0] = *(int16_t *)ptr;
597 break;
598 case INDEX_op_ld_i32:
599 CASE_64(ld32u)
600 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
601 ptr = (void *)(regs[r1] + ofs);
602 regs[r0] = *(uint32_t *)ptr;
603 break;
604 CASE_32_64(st8)
605 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
606 ptr = (void *)(regs[r1] + ofs);
607 *(uint8_t *)ptr = regs[r0];
608 break;
609 CASE_32_64(st16)
610 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
611 ptr = (void *)(regs[r1] + ofs);
612 *(uint16_t *)ptr = regs[r0];
613 break;
614 case INDEX_op_st_i32:
615 CASE_64(st32)
616 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
617 ptr = (void *)(regs[r1] + ofs);
618 *(uint32_t *)ptr = regs[r0];
619 break;
621 /* Arithmetic operations (mixed 32/64 bit). */
623 CASE_32_64(add)
624 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
625 regs[r0] = regs[r1] + regs[r2];
626 break;
627 CASE_32_64(sub)
628 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
629 regs[r0] = regs[r1] - regs[r2];
630 break;
631 CASE_32_64(mul)
632 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
633 regs[r0] = regs[r1] * regs[r2];
634 break;
635 CASE_32_64(and)
636 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
637 regs[r0] = regs[r1] & regs[r2];
638 break;
639 CASE_32_64(or)
640 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
641 regs[r0] = regs[r1] | regs[r2];
642 break;
643 CASE_32_64(xor)
644 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
645 regs[r0] = regs[r1] ^ regs[r2];
646 break;
648 /* Arithmetic operations (32 bit). */
650 case INDEX_op_div_i32:
651 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
652 regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
653 break;
654 case INDEX_op_divu_i32:
655 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
656 regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
657 break;
658 case INDEX_op_rem_i32:
659 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
660 regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
661 break;
662 case INDEX_op_remu_i32:
663 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
664 regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
665 break;
667 /* Shift/rotate operations (32 bit). */
669 case INDEX_op_shl_i32:
670 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
671 regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
672 break;
673 case INDEX_op_shr_i32:
674 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
675 regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
676 break;
677 case INDEX_op_sar_i32:
678 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
679 regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
680 break;
681 #if TCG_TARGET_HAS_rot_i32
682 case INDEX_op_rotl_i32:
683 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
684 regs[r0] = rol32(regs[r1], regs[r2] & 31);
685 break;
686 case INDEX_op_rotr_i32:
687 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
688 regs[r0] = ror32(regs[r1], regs[r2] & 31);
689 break;
690 #endif
691 #if TCG_TARGET_HAS_deposit_i32
692 case INDEX_op_deposit_i32:
693 tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
694 regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
695 break;
696 #endif
697 case INDEX_op_brcond_i32:
698 tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
699 if (tci_compare32(regs[r0], regs[r1], condition)) {
700 tb_ptr = ptr;
702 break;
703 #if TCG_TARGET_REG_BITS == 32
704 case INDEX_op_add2_i32:
705 tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
706 T1 = tci_uint64(regs[r3], regs[r2]);
707 T2 = tci_uint64(regs[r5], regs[r4]);
708 tci_write_reg64(regs, r1, r0, T1 + T2);
709 break;
710 case INDEX_op_sub2_i32:
711 tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
712 T1 = tci_uint64(regs[r3], regs[r2]);
713 T2 = tci_uint64(regs[r5], regs[r4]);
714 tci_write_reg64(regs, r1, r0, T1 - T2);
715 break;
716 case INDEX_op_brcond2_i32:
717 tci_args_rrrrcl(&tb_ptr, &r0, &r1, &r2, &r3, &condition, &ptr);
718 T1 = tci_uint64(regs[r1], regs[r0]);
719 T2 = tci_uint64(regs[r3], regs[r2]);
720 if (tci_compare64(T1, T2, condition)) {
721 tb_ptr = ptr;
722 continue;
724 break;
725 case INDEX_op_mulu2_i32:
726 tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
727 tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
728 break;
729 #endif /* TCG_TARGET_REG_BITS == 32 */
730 #if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
731 CASE_32_64(ext8s)
732 tci_args_rr(&tb_ptr, &r0, &r1);
733 regs[r0] = (int8_t)regs[r1];
734 break;
735 #endif
736 #if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64
737 CASE_32_64(ext16s)
738 tci_args_rr(&tb_ptr, &r0, &r1);
739 regs[r0] = (int16_t)regs[r1];
740 break;
741 #endif
742 #if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
743 CASE_32_64(ext8u)
744 tci_args_rr(&tb_ptr, &r0, &r1);
745 regs[r0] = (uint8_t)regs[r1];
746 break;
747 #endif
748 #if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
749 CASE_32_64(ext16u)
750 tci_args_rr(&tb_ptr, &r0, &r1);
751 regs[r0] = (uint16_t)regs[r1];
752 break;
753 #endif
754 #if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
755 CASE_32_64(bswap16)
756 tci_args_rr(&tb_ptr, &r0, &r1);
757 regs[r0] = bswap16(regs[r1]);
758 break;
759 #endif
760 #if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
761 CASE_32_64(bswap32)
762 tci_args_rr(&tb_ptr, &r0, &r1);
763 regs[r0] = bswap32(regs[r1]);
764 break;
765 #endif
766 #if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
767 CASE_32_64(not)
768 tci_args_rr(&tb_ptr, &r0, &r1);
769 regs[r0] = ~regs[r1];
770 break;
771 #endif
772 #if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64
773 CASE_32_64(neg)
774 tci_args_rr(&tb_ptr, &r0, &r1);
775 regs[r0] = -regs[r1];
776 break;
777 #endif
778 #if TCG_TARGET_REG_BITS == 64
779 case INDEX_op_tci_movi_i64:
780 tci_args_rI(&tb_ptr, &r0, &t1);
781 regs[r0] = t1;
782 break;
784 /* Load/store operations (64 bit). */
786 case INDEX_op_ld32s_i64:
787 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
788 ptr = (void *)(regs[r1] + ofs);
789 regs[r0] = *(int32_t *)ptr;
790 break;
791 case INDEX_op_ld_i64:
792 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
793 ptr = (void *)(regs[r1] + ofs);
794 regs[r0] = *(uint64_t *)ptr;
795 break;
796 case INDEX_op_st_i64:
797 tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
798 ptr = (void *)(regs[r1] + ofs);
799 *(uint64_t *)ptr = regs[r0];
800 break;
802 /* Arithmetic operations (64 bit). */
804 case INDEX_op_div_i64:
805 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
806 regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
807 break;
808 case INDEX_op_divu_i64:
809 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
810 regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
811 break;
812 case INDEX_op_rem_i64:
813 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
814 regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
815 break;
816 case INDEX_op_remu_i64:
817 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
818 regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
819 break;
821 /* Shift/rotate operations (64 bit). */
823 case INDEX_op_shl_i64:
824 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
825 regs[r0] = regs[r1] << (regs[r2] & 63);
826 break;
827 case INDEX_op_shr_i64:
828 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
829 regs[r0] = regs[r1] >> (regs[r2] & 63);
830 break;
831 case INDEX_op_sar_i64:
832 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
833 regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
834 break;
835 #if TCG_TARGET_HAS_rot_i64
836 case INDEX_op_rotl_i64:
837 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
838 regs[r0] = rol64(regs[r1], regs[r2] & 63);
839 break;
840 case INDEX_op_rotr_i64:
841 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
842 regs[r0] = ror64(regs[r1], regs[r2] & 63);
843 break;
844 #endif
845 #if TCG_TARGET_HAS_deposit_i64
846 case INDEX_op_deposit_i64:
847 tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
848 regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
849 break;
850 #endif
851 case INDEX_op_brcond_i64:
852 tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
853 if (tci_compare64(regs[r0], regs[r1], condition)) {
854 tb_ptr = ptr;
856 break;
857 case INDEX_op_ext32s_i64:
858 case INDEX_op_ext_i32_i64:
859 tci_args_rr(&tb_ptr, &r0, &r1);
860 regs[r0] = (int32_t)regs[r1];
861 break;
862 case INDEX_op_ext32u_i64:
863 case INDEX_op_extu_i32_i64:
864 tci_args_rr(&tb_ptr, &r0, &r1);
865 regs[r0] = (uint32_t)regs[r1];
866 break;
867 #if TCG_TARGET_HAS_bswap64_i64
868 case INDEX_op_bswap64_i64:
869 tci_args_rr(&tb_ptr, &r0, &r1);
870 regs[r0] = bswap64(regs[r1]);
871 break;
872 #endif
873 #endif /* TCG_TARGET_REG_BITS == 64 */
875 /* QEMU specific operations. */
877 case INDEX_op_exit_tb:
878 tci_args_l(&tb_ptr, &ptr);
879 return (uintptr_t)ptr;
881 case INDEX_op_goto_tb:
882 tci_args_l(&tb_ptr, &ptr);
883 tb_ptr = *(void **)ptr;
884 break;
886 case INDEX_op_qemu_ld_i32:
887 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
888 tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
889 taddr = regs[r1];
890 } else {
891 tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
892 taddr = tci_uint64(regs[r2], regs[r1]);
894 switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
895 case MO_UB:
896 tmp32 = qemu_ld_ub;
897 break;
898 case MO_SB:
899 tmp32 = (int8_t)qemu_ld_ub;
900 break;
901 case MO_LEUW:
902 tmp32 = qemu_ld_leuw;
903 break;
904 case MO_LESW:
905 tmp32 = (int16_t)qemu_ld_leuw;
906 break;
907 case MO_LEUL:
908 tmp32 = qemu_ld_leul;
909 break;
910 case MO_BEUW:
911 tmp32 = qemu_ld_beuw;
912 break;
913 case MO_BESW:
914 tmp32 = (int16_t)qemu_ld_beuw;
915 break;
916 case MO_BEUL:
917 tmp32 = qemu_ld_beul;
918 break;
919 default:
920 g_assert_not_reached();
922 regs[r0] = tmp32;
923 break;
925 case INDEX_op_qemu_ld_i64:
926 if (TCG_TARGET_REG_BITS == 64) {
927 tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
928 taddr = regs[r1];
929 } else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
930 tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
931 taddr = regs[r2];
932 } else {
933 tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
934 taddr = tci_uint64(regs[r3], regs[r2]);
936 switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
937 case MO_UB:
938 tmp64 = qemu_ld_ub;
939 break;
940 case MO_SB:
941 tmp64 = (int8_t)qemu_ld_ub;
942 break;
943 case MO_LEUW:
944 tmp64 = qemu_ld_leuw;
945 break;
946 case MO_LESW:
947 tmp64 = (int16_t)qemu_ld_leuw;
948 break;
949 case MO_LEUL:
950 tmp64 = qemu_ld_leul;
951 break;
952 case MO_LESL:
953 tmp64 = (int32_t)qemu_ld_leul;
954 break;
955 case MO_LEQ:
956 tmp64 = qemu_ld_leq;
957 break;
958 case MO_BEUW:
959 tmp64 = qemu_ld_beuw;
960 break;
961 case MO_BESW:
962 tmp64 = (int16_t)qemu_ld_beuw;
963 break;
964 case MO_BEUL:
965 tmp64 = qemu_ld_beul;
966 break;
967 case MO_BESL:
968 tmp64 = (int32_t)qemu_ld_beul;
969 break;
970 case MO_BEQ:
971 tmp64 = qemu_ld_beq;
972 break;
973 default:
974 g_assert_not_reached();
976 if (TCG_TARGET_REG_BITS == 32) {
977 tci_write_reg64(regs, r1, r0, tmp64);
978 } else {
979 regs[r0] = tmp64;
981 break;
983 case INDEX_op_qemu_st_i32:
984 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
985 tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
986 taddr = regs[r1];
987 } else {
988 tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
989 taddr = tci_uint64(regs[r2], regs[r1]);
991 tmp32 = regs[r0];
992 switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
993 case MO_UB:
994 qemu_st_b(tmp32);
995 break;
996 case MO_LEUW:
997 qemu_st_lew(tmp32);
998 break;
999 case MO_LEUL:
1000 qemu_st_lel(tmp32);
1001 break;
1002 case MO_BEUW:
1003 qemu_st_bew(tmp32);
1004 break;
1005 case MO_BEUL:
1006 qemu_st_bel(tmp32);
1007 break;
1008 default:
1009 g_assert_not_reached();
1011 break;
1013 case INDEX_op_qemu_st_i64:
1014 if (TCG_TARGET_REG_BITS == 64) {
1015 tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
1016 taddr = regs[r1];
1017 tmp64 = regs[r0];
1018 } else {
1019 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
1020 tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
1021 taddr = regs[r2];
1022 } else {
1023 tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
1024 taddr = tci_uint64(regs[r3], regs[r2]);
1026 tmp64 = tci_uint64(regs[r1], regs[r0]);
1028 switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
1029 case MO_UB:
1030 qemu_st_b(tmp64);
1031 break;
1032 case MO_LEUW:
1033 qemu_st_lew(tmp64);
1034 break;
1035 case MO_LEUL:
1036 qemu_st_lel(tmp64);
1037 break;
1038 case MO_LEQ:
1039 qemu_st_leq(tmp64);
1040 break;
1041 case MO_BEUW:
1042 qemu_st_bew(tmp64);
1043 break;
1044 case MO_BEUL:
1045 qemu_st_bel(tmp64);
1046 break;
1047 case MO_BEQ:
1048 qemu_st_beq(tmp64);
1049 break;
1050 default:
1051 g_assert_not_reached();
1053 break;
1055 case INDEX_op_mb:
1056 /* Ensure ordering for all kinds */
1057 smp_mb();
1058 break;
1059 default:
1060 g_assert_not_reached();
1066 * Disassembler that matches the interpreter
1069 static const char *str_r(TCGReg r)
1071 static const char regs[TCG_TARGET_NB_REGS][4] = {
1072 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1073 "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
1076 QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
1077 QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
1079 assert((unsigned)r < TCG_TARGET_NB_REGS);
1080 return regs[r];
1083 static const char *str_c(TCGCond c)
1085 static const char cond[16][8] = {
1086 [TCG_COND_NEVER] = "never",
1087 [TCG_COND_ALWAYS] = "always",
1088 [TCG_COND_EQ] = "eq",
1089 [TCG_COND_NE] = "ne",
1090 [TCG_COND_LT] = "lt",
1091 [TCG_COND_GE] = "ge",
1092 [TCG_COND_LE] = "le",
1093 [TCG_COND_GT] = "gt",
1094 [TCG_COND_LTU] = "ltu",
1095 [TCG_COND_GEU] = "geu",
1096 [TCG_COND_LEU] = "leu",
1097 [TCG_COND_GTU] = "gtu",
1100 assert((unsigned)c < ARRAY_SIZE(cond));
1101 assert(cond[c][0] != 0);
1102 return cond[c];
1105 /* Disassemble TCI bytecode. */
1106 int print_insn_tci(bfd_vma addr, disassemble_info *info)
1108 uint8_t buf[256];
1109 int length, status;
1110 const TCGOpDef *def;
1111 const char *op_name;
1112 TCGOpcode op;
1113 TCGReg r0, r1, r2, r3;
1114 #if TCG_TARGET_REG_BITS == 32
1115 TCGReg r4, r5;
1116 #endif
1117 tcg_target_ulong i1;
1118 int32_t s2;
1119 TCGCond c;
1120 TCGMemOpIdx oi;
1121 uint8_t pos, len;
1122 void *ptr;
1123 const uint8_t *tb_ptr;
1125 status = info->read_memory_func(addr, buf, 2, info);
1126 if (status != 0) {
1127 info->memory_error_func(status, addr, info);
1128 return -1;
1130 op = buf[0];
1131 length = buf[1];
1133 if (length < 2) {
1134 info->fprintf_func(info->stream, "invalid length %d", length);
1135 return 1;
1138 status = info->read_memory_func(addr + 2, buf + 2, length - 2, info);
1139 if (status != 0) {
1140 info->memory_error_func(status, addr + 2, info);
1141 return -1;
1144 def = &tcg_op_defs[op];
1145 op_name = def->name;
1146 tb_ptr = buf + 2;
1148 switch (op) {
1149 case INDEX_op_br:
1150 case INDEX_op_call:
1151 case INDEX_op_exit_tb:
1152 case INDEX_op_goto_tb:
1153 tci_args_l(&tb_ptr, &ptr);
1154 info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
1155 break;
1157 case INDEX_op_brcond_i32:
1158 case INDEX_op_brcond_i64:
1159 tci_args_rrcl(&tb_ptr, &r0, &r1, &c, &ptr);
1160 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %p",
1161 op_name, str_r(r0), str_r(r1), str_c(c), ptr);
1162 break;
1164 case INDEX_op_setcond_i32:
1165 case INDEX_op_setcond_i64:
1166 tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &c);
1167 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1168 op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1169 break;
1171 case INDEX_op_tci_movi_i32:
1172 tci_args_ri(&tb_ptr, &r0, &i1);
1173 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1174 op_name, str_r(r0), i1);
1175 break;
1177 #if TCG_TARGET_REG_BITS == 64
1178 case INDEX_op_tci_movi_i64:
1179 tci_args_rI(&tb_ptr, &r0, &i1);
1180 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1181 op_name, str_r(r0), i1);
1182 break;
1183 #endif
1185 case INDEX_op_ld8u_i32:
1186 case INDEX_op_ld8u_i64:
1187 case INDEX_op_ld8s_i32:
1188 case INDEX_op_ld8s_i64:
1189 case INDEX_op_ld16u_i32:
1190 case INDEX_op_ld16u_i64:
1191 case INDEX_op_ld16s_i32:
1192 case INDEX_op_ld16s_i64:
1193 case INDEX_op_ld32u_i64:
1194 case INDEX_op_ld32s_i64:
1195 case INDEX_op_ld_i32:
1196 case INDEX_op_ld_i64:
1197 case INDEX_op_st8_i32:
1198 case INDEX_op_st8_i64:
1199 case INDEX_op_st16_i32:
1200 case INDEX_op_st16_i64:
1201 case INDEX_op_st32_i64:
1202 case INDEX_op_st_i32:
1203 case INDEX_op_st_i64:
1204 tci_args_rrs(&tb_ptr, &r0, &r1, &s2);
1205 info->fprintf_func(info->stream, "%-12s %s, %s, %d",
1206 op_name, str_r(r0), str_r(r1), s2);
1207 break;
1209 case INDEX_op_mov_i32:
1210 case INDEX_op_mov_i64:
1211 case INDEX_op_ext8s_i32:
1212 case INDEX_op_ext8s_i64:
1213 case INDEX_op_ext8u_i32:
1214 case INDEX_op_ext8u_i64:
1215 case INDEX_op_ext16s_i32:
1216 case INDEX_op_ext16s_i64:
1217 case INDEX_op_ext16u_i32:
1218 case INDEX_op_ext32s_i64:
1219 case INDEX_op_ext32u_i64:
1220 case INDEX_op_ext_i32_i64:
1221 case INDEX_op_extu_i32_i64:
1222 case INDEX_op_bswap16_i32:
1223 case INDEX_op_bswap16_i64:
1224 case INDEX_op_bswap32_i32:
1225 case INDEX_op_bswap32_i64:
1226 case INDEX_op_bswap64_i64:
1227 case INDEX_op_not_i32:
1228 case INDEX_op_not_i64:
1229 case INDEX_op_neg_i32:
1230 case INDEX_op_neg_i64:
1231 tci_args_rr(&tb_ptr, &r0, &r1);
1232 info->fprintf_func(info->stream, "%-12s %s, %s",
1233 op_name, str_r(r0), str_r(r1));
1234 break;
1236 case INDEX_op_add_i32:
1237 case INDEX_op_add_i64:
1238 case INDEX_op_sub_i32:
1239 case INDEX_op_sub_i64:
1240 case INDEX_op_mul_i32:
1241 case INDEX_op_mul_i64:
1242 case INDEX_op_and_i32:
1243 case INDEX_op_and_i64:
1244 case INDEX_op_or_i32:
1245 case INDEX_op_or_i64:
1246 case INDEX_op_xor_i32:
1247 case INDEX_op_xor_i64:
1248 case INDEX_op_div_i32:
1249 case INDEX_op_div_i64:
1250 case INDEX_op_rem_i32:
1251 case INDEX_op_rem_i64:
1252 case INDEX_op_divu_i32:
1253 case INDEX_op_divu_i64:
1254 case INDEX_op_remu_i32:
1255 case INDEX_op_remu_i64:
1256 case INDEX_op_shl_i32:
1257 case INDEX_op_shl_i64:
1258 case INDEX_op_shr_i32:
1259 case INDEX_op_shr_i64:
1260 case INDEX_op_sar_i32:
1261 case INDEX_op_sar_i64:
1262 case INDEX_op_rotl_i32:
1263 case INDEX_op_rotl_i64:
1264 case INDEX_op_rotr_i32:
1265 case INDEX_op_rotr_i64:
1266 tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
1267 info->fprintf_func(info->stream, "%-12s %s, %s, %s",
1268 op_name, str_r(r0), str_r(r1), str_r(r2));
1269 break;
1271 case INDEX_op_deposit_i32:
1272 case INDEX_op_deposit_i64:
1273 tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
1274 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
1275 op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1276 break;
1278 #if TCG_TARGET_REG_BITS == 32
1279 case INDEX_op_setcond2_i32:
1280 tci_args_rrrrrc(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &c);
1281 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1282 op_name, str_r(r0), str_r(r1), str_r(r2),
1283 str_r(r3), str_r(r4), str_c(c));
1284 break;
1286 case INDEX_op_brcond2_i32:
1287 tci_args_rrrrcl(&tb_ptr, &r0, &r1, &r2, &r3, &c, &ptr);
1288 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %p",
1289 op_name, str_r(r0), str_r(r1),
1290 str_r(r2), str_r(r3), str_c(c), ptr);
1291 break;
1293 case INDEX_op_mulu2_i32:
1294 tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
1295 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1296 op_name, str_r(r0), str_r(r1),
1297 str_r(r2), str_r(r3));
1298 break;
1300 case INDEX_op_add2_i32:
1301 case INDEX_op_sub2_i32:
1302 tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
1303 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1304 op_name, str_r(r0), str_r(r1), str_r(r2),
1305 str_r(r3), str_r(r4), str_r(r5));
1306 break;
1307 #endif
1309 case INDEX_op_qemu_ld_i64:
1310 case INDEX_op_qemu_st_i64:
1311 len = DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1312 goto do_qemu_ldst;
1313 case INDEX_op_qemu_ld_i32:
1314 case INDEX_op_qemu_st_i32:
1315 len = 1;
1316 do_qemu_ldst:
1317 len += DIV_ROUND_UP(TARGET_LONG_BITS, TCG_TARGET_REG_BITS);
1318 switch (len) {
1319 case 2:
1320 tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
1321 info->fprintf_func(info->stream, "%-12s %s, %s, %x",
1322 op_name, str_r(r0), str_r(r1), oi);
1323 break;
1324 case 3:
1325 tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
1326 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %x",
1327 op_name, str_r(r0), str_r(r1), str_r(r2), oi);
1328 break;
1329 case 4:
1330 tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
1331 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %x",
1332 op_name, str_r(r0), str_r(r1),
1333 str_r(r2), str_r(r3), oi);
1334 break;
1335 default:
1336 g_assert_not_reached();
1338 break;
1340 default:
1341 info->fprintf_func(info->stream, "illegal opcode %d", op);
1342 break;
1345 return length;