]> git.proxmox.com Git - mirror_qemu.git/blob - tcg/tci.c
tcg/tci: Implement goto_ptr
[mirror_qemu.git] / tcg / tci.c
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 "qemu-common.h"
22 #include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
23 #include "exec/cpu_ldst.h"
24 #include "tcg/tcg-op.h"
25 #include "qemu/compiler.h"
26 #include <ffi.h>
27
28
29 /*
30 * Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
31 * Without assertions, the interpreter runs much faster.
32 */
33 #if defined(CONFIG_DEBUG_TCG)
34 # define tci_assert(cond) assert(cond)
35 #else
36 # define tci_assert(cond) ((void)(cond))
37 #endif
38
39 __thread uintptr_t tci_tb_ptr;
40
41 static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
42 uint32_t low_index, uint64_t value)
43 {
44 regs[low_index] = value;
45 regs[high_index] = value >> 32;
46 }
47
48 /* Create a 64 bit value from two 32 bit values. */
49 static uint64_t tci_uint64(uint32_t high, uint32_t low)
50 {
51 return ((uint64_t)high << 32) + low;
52 }
53
54 /*
55 * Load sets of arguments all at once. The naming convention is:
56 * tci_args_<arguments>
57 * where arguments is a sequence of
58 *
59 * b = immediate (bit position)
60 * c = condition (TCGCond)
61 * i = immediate (uint32_t)
62 * I = immediate (tcg_target_ulong)
63 * l = label or pointer
64 * m = immediate (TCGMemOpIdx)
65 * n = immediate (call return length)
66 * r = register
67 * s = signed ldst offset
68 */
69
70 static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
71 {
72 int diff = sextract32(insn, 12, 20);
73 *l0 = diff ? (void *)tb_ptr + diff : NULL;
74 }
75
76 static void tci_args_r(uint32_t insn, TCGReg *r0)
77 {
78 *r0 = extract32(insn, 8, 4);
79 }
80
81 static void tci_args_nl(uint32_t insn, const void *tb_ptr,
82 uint8_t *n0, void **l1)
83 {
84 *n0 = extract32(insn, 8, 4);
85 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
86 }
87
88 static void tci_args_rl(uint32_t insn, const void *tb_ptr,
89 TCGReg *r0, void **l1)
90 {
91 *r0 = extract32(insn, 8, 4);
92 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
93 }
94
95 static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
96 {
97 *r0 = extract32(insn, 8, 4);
98 *r1 = extract32(insn, 12, 4);
99 }
100
101 static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
102 {
103 *r0 = extract32(insn, 8, 4);
104 *i1 = sextract32(insn, 12, 20);
105 }
106
107 static void tci_args_rrm(uint32_t insn, TCGReg *r0,
108 TCGReg *r1, TCGMemOpIdx *m2)
109 {
110 *r0 = extract32(insn, 8, 4);
111 *r1 = extract32(insn, 12, 4);
112 *m2 = extract32(insn, 20, 12);
113 }
114
115 static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
116 {
117 *r0 = extract32(insn, 8, 4);
118 *r1 = extract32(insn, 12, 4);
119 *r2 = extract32(insn, 16, 4);
120 }
121
122 static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
123 {
124 *r0 = extract32(insn, 8, 4);
125 *r1 = extract32(insn, 12, 4);
126 *i2 = sextract32(insn, 16, 16);
127 }
128
129 static void tci_args_rrrc(uint32_t insn,
130 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
131 {
132 *r0 = extract32(insn, 8, 4);
133 *r1 = extract32(insn, 12, 4);
134 *r2 = extract32(insn, 16, 4);
135 *c3 = extract32(insn, 20, 4);
136 }
137
138 static void tci_args_rrrm(uint32_t insn,
139 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
140 {
141 *r0 = extract32(insn, 8, 4);
142 *r1 = extract32(insn, 12, 4);
143 *r2 = extract32(insn, 16, 4);
144 *m3 = extract32(insn, 20, 12);
145 }
146
147 static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
148 TCGReg *r2, uint8_t *i3, uint8_t *i4)
149 {
150 *r0 = extract32(insn, 8, 4);
151 *r1 = extract32(insn, 12, 4);
152 *r2 = extract32(insn, 16, 4);
153 *i3 = extract32(insn, 20, 6);
154 *i4 = extract32(insn, 26, 6);
155 }
156
157 static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
158 TCGReg *r2, TCGReg *r3, TCGReg *r4)
159 {
160 *r0 = extract32(insn, 8, 4);
161 *r1 = extract32(insn, 12, 4);
162 *r2 = extract32(insn, 16, 4);
163 *r3 = extract32(insn, 20, 4);
164 *r4 = extract32(insn, 24, 4);
165 }
166
167 #if TCG_TARGET_REG_BITS == 32
168 static void tci_args_rrrr(uint32_t insn,
169 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
170 {
171 *r0 = extract32(insn, 8, 4);
172 *r1 = extract32(insn, 12, 4);
173 *r2 = extract32(insn, 16, 4);
174 *r3 = extract32(insn, 20, 4);
175 }
176
177 static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
178 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
179 {
180 *r0 = extract32(insn, 8, 4);
181 *r1 = extract32(insn, 12, 4);
182 *r2 = extract32(insn, 16, 4);
183 *r3 = extract32(insn, 20, 4);
184 *r4 = extract32(insn, 24, 4);
185 *c5 = extract32(insn, 28, 4);
186 }
187
188 static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
189 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
190 {
191 *r0 = extract32(insn, 8, 4);
192 *r1 = extract32(insn, 12, 4);
193 *r2 = extract32(insn, 16, 4);
194 *r3 = extract32(insn, 20, 4);
195 *r4 = extract32(insn, 24, 4);
196 *r5 = extract32(insn, 28, 4);
197 }
198 #endif
199
200 static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
201 {
202 bool result = false;
203 int32_t i0 = u0;
204 int32_t i1 = u1;
205 switch (condition) {
206 case TCG_COND_EQ:
207 result = (u0 == u1);
208 break;
209 case TCG_COND_NE:
210 result = (u0 != u1);
211 break;
212 case TCG_COND_LT:
213 result = (i0 < i1);
214 break;
215 case TCG_COND_GE:
216 result = (i0 >= i1);
217 break;
218 case TCG_COND_LE:
219 result = (i0 <= i1);
220 break;
221 case TCG_COND_GT:
222 result = (i0 > i1);
223 break;
224 case TCG_COND_LTU:
225 result = (u0 < u1);
226 break;
227 case TCG_COND_GEU:
228 result = (u0 >= u1);
229 break;
230 case TCG_COND_LEU:
231 result = (u0 <= u1);
232 break;
233 case TCG_COND_GTU:
234 result = (u0 > u1);
235 break;
236 default:
237 g_assert_not_reached();
238 }
239 return result;
240 }
241
242 static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
243 {
244 bool result = false;
245 int64_t i0 = u0;
246 int64_t i1 = u1;
247 switch (condition) {
248 case TCG_COND_EQ:
249 result = (u0 == u1);
250 break;
251 case TCG_COND_NE:
252 result = (u0 != u1);
253 break;
254 case TCG_COND_LT:
255 result = (i0 < i1);
256 break;
257 case TCG_COND_GE:
258 result = (i0 >= i1);
259 break;
260 case TCG_COND_LE:
261 result = (i0 <= i1);
262 break;
263 case TCG_COND_GT:
264 result = (i0 > i1);
265 break;
266 case TCG_COND_LTU:
267 result = (u0 < u1);
268 break;
269 case TCG_COND_GEU:
270 result = (u0 >= u1);
271 break;
272 case TCG_COND_LEU:
273 result = (u0 <= u1);
274 break;
275 case TCG_COND_GTU:
276 result = (u0 > u1);
277 break;
278 default:
279 g_assert_not_reached();
280 }
281 return result;
282 }
283
284 #define qemu_ld_ub \
285 cpu_ldub_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
286 #define qemu_ld_leuw \
287 cpu_lduw_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
288 #define qemu_ld_leul \
289 cpu_ldl_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
290 #define qemu_ld_leq \
291 cpu_ldq_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
292 #define qemu_ld_beuw \
293 cpu_lduw_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
294 #define qemu_ld_beul \
295 cpu_ldl_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
296 #define qemu_ld_beq \
297 cpu_ldq_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
298 #define qemu_st_b(X) \
299 cpu_stb_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
300 #define qemu_st_lew(X) \
301 cpu_stw_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
302 #define qemu_st_lel(X) \
303 cpu_stl_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
304 #define qemu_st_leq(X) \
305 cpu_stq_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
306 #define qemu_st_bew(X) \
307 cpu_stw_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
308 #define qemu_st_bel(X) \
309 cpu_stl_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
310 #define qemu_st_beq(X) \
311 cpu_stq_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
312
313 #if TCG_TARGET_REG_BITS == 64
314 # define CASE_32_64(x) \
315 case glue(glue(INDEX_op_, x), _i64): \
316 case glue(glue(INDEX_op_, x), _i32):
317 # define CASE_64(x) \
318 case glue(glue(INDEX_op_, x), _i64):
319 #else
320 # define CASE_32_64(x) \
321 case glue(glue(INDEX_op_, x), _i32):
322 # define CASE_64(x)
323 #endif
324
325 /* Interpret pseudo code in tb. */
326 /*
327 * Disable CFI checks.
328 * One possible operation in the pseudo code is a call to binary code.
329 * Therefore, disable CFI checks in the interpreter function
330 */
331 uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
332 const void *v_tb_ptr)
333 {
334 const uint32_t *tb_ptr = v_tb_ptr;
335 tcg_target_ulong regs[TCG_TARGET_NB_REGS];
336 uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
337 / sizeof(uint64_t)];
338 void *call_slots[TCG_STATIC_CALL_ARGS_SIZE / sizeof(uint64_t)];
339
340 regs[TCG_AREG0] = (tcg_target_ulong)env;
341 regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
342 /* Other call_slots entries initialized at first use (see below). */
343 call_slots[0] = NULL;
344 tci_assert(tb_ptr);
345
346 for (;;) {
347 uint32_t insn;
348 TCGOpcode opc;
349 TCGReg r0, r1, r2, r3, r4;
350 tcg_target_ulong t1;
351 TCGCond condition;
352 target_ulong taddr;
353 uint8_t pos, len;
354 uint32_t tmp32;
355 uint64_t tmp64;
356 #if TCG_TARGET_REG_BITS == 32
357 TCGReg r5;
358 uint64_t T1, T2;
359 #endif
360 TCGMemOpIdx oi;
361 int32_t ofs;
362 void *ptr;
363
364 insn = *tb_ptr++;
365 opc = extract32(insn, 0, 8);
366
367 switch (opc) {
368 case INDEX_op_call:
369 /*
370 * Set up the ffi_avalue array once, delayed until now
371 * because many TB's do not make any calls. In tcg_gen_callN,
372 * we arranged for every real argument to be "left-aligned"
373 * in each 64-bit slot.
374 */
375 if (unlikely(call_slots[0] == NULL)) {
376 for (int i = 0; i < ARRAY_SIZE(call_slots); ++i) {
377 call_slots[i] = &stack[i];
378 }
379 }
380
381 tci_args_nl(insn, tb_ptr, &len, &ptr);
382
383 /* Helper functions may need to access the "return address" */
384 tci_tb_ptr = (uintptr_t)tb_ptr;
385
386 {
387 void **pptr = ptr;
388 ffi_call(pptr[1], pptr[0], stack, call_slots);
389 }
390
391 /* Any result winds up "left-aligned" in the stack[0] slot. */
392 switch (len) {
393 case 0: /* void */
394 break;
395 case 1: /* uint32_t */
396 /*
397 * Note that libffi has an odd special case in that it will
398 * always widen an integral result to ffi_arg.
399 */
400 if (sizeof(ffi_arg) == 4) {
401 regs[TCG_REG_R0] = *(uint32_t *)stack;
402 break;
403 }
404 /* fall through */
405 case 2: /* uint64_t */
406 if (TCG_TARGET_REG_BITS == 32) {
407 tci_write_reg64(regs, TCG_REG_R1, TCG_REG_R0, stack[0]);
408 } else {
409 regs[TCG_REG_R0] = stack[0];
410 }
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 case INDEX_op_setcond_i32:
422 tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
423 regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
424 break;
425 #if TCG_TARGET_REG_BITS == 32
426 case INDEX_op_setcond2_i32:
427 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
428 T1 = tci_uint64(regs[r2], regs[r1]);
429 T2 = tci_uint64(regs[r4], regs[r3]);
430 regs[r0] = tci_compare64(T1, T2, condition);
431 break;
432 #elif TCG_TARGET_REG_BITS == 64
433 case INDEX_op_setcond_i64:
434 tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
435 regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
436 break;
437 #endif
438 CASE_32_64(mov)
439 tci_args_rr(insn, &r0, &r1);
440 regs[r0] = regs[r1];
441 break;
442 case INDEX_op_tci_movi:
443 tci_args_ri(insn, &r0, &t1);
444 regs[r0] = t1;
445 break;
446 case INDEX_op_tci_movl:
447 tci_args_rl(insn, tb_ptr, &r0, &ptr);
448 regs[r0] = *(tcg_target_ulong *)ptr;
449 break;
450
451 /* Load/store operations (32 bit). */
452
453 CASE_32_64(ld8u)
454 tci_args_rrs(insn, &r0, &r1, &ofs);
455 ptr = (void *)(regs[r1] + ofs);
456 regs[r0] = *(uint8_t *)ptr;
457 break;
458 CASE_32_64(ld8s)
459 tci_args_rrs(insn, &r0, &r1, &ofs);
460 ptr = (void *)(regs[r1] + ofs);
461 regs[r0] = *(int8_t *)ptr;
462 break;
463 CASE_32_64(ld16u)
464 tci_args_rrs(insn, &r0, &r1, &ofs);
465 ptr = (void *)(regs[r1] + ofs);
466 regs[r0] = *(uint16_t *)ptr;
467 break;
468 CASE_32_64(ld16s)
469 tci_args_rrs(insn, &r0, &r1, &ofs);
470 ptr = (void *)(regs[r1] + ofs);
471 regs[r0] = *(int16_t *)ptr;
472 break;
473 case INDEX_op_ld_i32:
474 CASE_64(ld32u)
475 tci_args_rrs(insn, &r0, &r1, &ofs);
476 ptr = (void *)(regs[r1] + ofs);
477 regs[r0] = *(uint32_t *)ptr;
478 break;
479 CASE_32_64(st8)
480 tci_args_rrs(insn, &r0, &r1, &ofs);
481 ptr = (void *)(regs[r1] + ofs);
482 *(uint8_t *)ptr = regs[r0];
483 break;
484 CASE_32_64(st16)
485 tci_args_rrs(insn, &r0, &r1, &ofs);
486 ptr = (void *)(regs[r1] + ofs);
487 *(uint16_t *)ptr = regs[r0];
488 break;
489 case INDEX_op_st_i32:
490 CASE_64(st32)
491 tci_args_rrs(insn, &r0, &r1, &ofs);
492 ptr = (void *)(regs[r1] + ofs);
493 *(uint32_t *)ptr = regs[r0];
494 break;
495
496 /* Arithmetic operations (mixed 32/64 bit). */
497
498 CASE_32_64(add)
499 tci_args_rrr(insn, &r0, &r1, &r2);
500 regs[r0] = regs[r1] + regs[r2];
501 break;
502 CASE_32_64(sub)
503 tci_args_rrr(insn, &r0, &r1, &r2);
504 regs[r0] = regs[r1] - regs[r2];
505 break;
506 CASE_32_64(mul)
507 tci_args_rrr(insn, &r0, &r1, &r2);
508 regs[r0] = regs[r1] * regs[r2];
509 break;
510 CASE_32_64(and)
511 tci_args_rrr(insn, &r0, &r1, &r2);
512 regs[r0] = regs[r1] & regs[r2];
513 break;
514 CASE_32_64(or)
515 tci_args_rrr(insn, &r0, &r1, &r2);
516 regs[r0] = regs[r1] | regs[r2];
517 break;
518 CASE_32_64(xor)
519 tci_args_rrr(insn, &r0, &r1, &r2);
520 regs[r0] = regs[r1] ^ regs[r2];
521 break;
522
523 /* Arithmetic operations (32 bit). */
524
525 case INDEX_op_div_i32:
526 tci_args_rrr(insn, &r0, &r1, &r2);
527 regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
528 break;
529 case INDEX_op_divu_i32:
530 tci_args_rrr(insn, &r0, &r1, &r2);
531 regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
532 break;
533 case INDEX_op_rem_i32:
534 tci_args_rrr(insn, &r0, &r1, &r2);
535 regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
536 break;
537 case INDEX_op_remu_i32:
538 tci_args_rrr(insn, &r0, &r1, &r2);
539 regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
540 break;
541
542 /* Shift/rotate operations (32 bit). */
543
544 case INDEX_op_shl_i32:
545 tci_args_rrr(insn, &r0, &r1, &r2);
546 regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
547 break;
548 case INDEX_op_shr_i32:
549 tci_args_rrr(insn, &r0, &r1, &r2);
550 regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
551 break;
552 case INDEX_op_sar_i32:
553 tci_args_rrr(insn, &r0, &r1, &r2);
554 regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
555 break;
556 #if TCG_TARGET_HAS_rot_i32
557 case INDEX_op_rotl_i32:
558 tci_args_rrr(insn, &r0, &r1, &r2);
559 regs[r0] = rol32(regs[r1], regs[r2] & 31);
560 break;
561 case INDEX_op_rotr_i32:
562 tci_args_rrr(insn, &r0, &r1, &r2);
563 regs[r0] = ror32(regs[r1], regs[r2] & 31);
564 break;
565 #endif
566 #if TCG_TARGET_HAS_deposit_i32
567 case INDEX_op_deposit_i32:
568 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
569 regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
570 break;
571 #endif
572 case INDEX_op_brcond_i32:
573 tci_args_rl(insn, tb_ptr, &r0, &ptr);
574 if ((uint32_t)regs[r0]) {
575 tb_ptr = ptr;
576 }
577 break;
578 #if TCG_TARGET_REG_BITS == 32
579 case INDEX_op_add2_i32:
580 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
581 T1 = tci_uint64(regs[r3], regs[r2]);
582 T2 = tci_uint64(regs[r5], regs[r4]);
583 tci_write_reg64(regs, r1, r0, T1 + T2);
584 break;
585 case INDEX_op_sub2_i32:
586 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
587 T1 = tci_uint64(regs[r3], regs[r2]);
588 T2 = tci_uint64(regs[r5], regs[r4]);
589 tci_write_reg64(regs, r1, r0, T1 - T2);
590 break;
591 case INDEX_op_mulu2_i32:
592 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
593 tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
594 break;
595 #endif /* TCG_TARGET_REG_BITS == 32 */
596 #if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
597 CASE_32_64(ext8s)
598 tci_args_rr(insn, &r0, &r1);
599 regs[r0] = (int8_t)regs[r1];
600 break;
601 #endif
602 #if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64
603 CASE_32_64(ext16s)
604 tci_args_rr(insn, &r0, &r1);
605 regs[r0] = (int16_t)regs[r1];
606 break;
607 #endif
608 #if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
609 CASE_32_64(ext8u)
610 tci_args_rr(insn, &r0, &r1);
611 regs[r0] = (uint8_t)regs[r1];
612 break;
613 #endif
614 #if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
615 CASE_32_64(ext16u)
616 tci_args_rr(insn, &r0, &r1);
617 regs[r0] = (uint16_t)regs[r1];
618 break;
619 #endif
620 #if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
621 CASE_32_64(bswap16)
622 tci_args_rr(insn, &r0, &r1);
623 regs[r0] = bswap16(regs[r1]);
624 break;
625 #endif
626 #if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
627 CASE_32_64(bswap32)
628 tci_args_rr(insn, &r0, &r1);
629 regs[r0] = bswap32(regs[r1]);
630 break;
631 #endif
632 #if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
633 CASE_32_64(not)
634 tci_args_rr(insn, &r0, &r1);
635 regs[r0] = ~regs[r1];
636 break;
637 #endif
638 #if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64
639 CASE_32_64(neg)
640 tci_args_rr(insn, &r0, &r1);
641 regs[r0] = -regs[r1];
642 break;
643 #endif
644 #if TCG_TARGET_REG_BITS == 64
645 /* Load/store operations (64 bit). */
646
647 case INDEX_op_ld32s_i64:
648 tci_args_rrs(insn, &r0, &r1, &ofs);
649 ptr = (void *)(regs[r1] + ofs);
650 regs[r0] = *(int32_t *)ptr;
651 break;
652 case INDEX_op_ld_i64:
653 tci_args_rrs(insn, &r0, &r1, &ofs);
654 ptr = (void *)(regs[r1] + ofs);
655 regs[r0] = *(uint64_t *)ptr;
656 break;
657 case INDEX_op_st_i64:
658 tci_args_rrs(insn, &r0, &r1, &ofs);
659 ptr = (void *)(regs[r1] + ofs);
660 *(uint64_t *)ptr = regs[r0];
661 break;
662
663 /* Arithmetic operations (64 bit). */
664
665 case INDEX_op_div_i64:
666 tci_args_rrr(insn, &r0, &r1, &r2);
667 regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
668 break;
669 case INDEX_op_divu_i64:
670 tci_args_rrr(insn, &r0, &r1, &r2);
671 regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
672 break;
673 case INDEX_op_rem_i64:
674 tci_args_rrr(insn, &r0, &r1, &r2);
675 regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
676 break;
677 case INDEX_op_remu_i64:
678 tci_args_rrr(insn, &r0, &r1, &r2);
679 regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
680 break;
681
682 /* Shift/rotate operations (64 bit). */
683
684 case INDEX_op_shl_i64:
685 tci_args_rrr(insn, &r0, &r1, &r2);
686 regs[r0] = regs[r1] << (regs[r2] & 63);
687 break;
688 case INDEX_op_shr_i64:
689 tci_args_rrr(insn, &r0, &r1, &r2);
690 regs[r0] = regs[r1] >> (regs[r2] & 63);
691 break;
692 case INDEX_op_sar_i64:
693 tci_args_rrr(insn, &r0, &r1, &r2);
694 regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
695 break;
696 #if TCG_TARGET_HAS_rot_i64
697 case INDEX_op_rotl_i64:
698 tci_args_rrr(insn, &r0, &r1, &r2);
699 regs[r0] = rol64(regs[r1], regs[r2] & 63);
700 break;
701 case INDEX_op_rotr_i64:
702 tci_args_rrr(insn, &r0, &r1, &r2);
703 regs[r0] = ror64(regs[r1], regs[r2] & 63);
704 break;
705 #endif
706 #if TCG_TARGET_HAS_deposit_i64
707 case INDEX_op_deposit_i64:
708 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
709 regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
710 break;
711 #endif
712 case INDEX_op_brcond_i64:
713 tci_args_rl(insn, tb_ptr, &r0, &ptr);
714 if (regs[r0]) {
715 tb_ptr = ptr;
716 }
717 break;
718 case INDEX_op_ext32s_i64:
719 case INDEX_op_ext_i32_i64:
720 tci_args_rr(insn, &r0, &r1);
721 regs[r0] = (int32_t)regs[r1];
722 break;
723 case INDEX_op_ext32u_i64:
724 case INDEX_op_extu_i32_i64:
725 tci_args_rr(insn, &r0, &r1);
726 regs[r0] = (uint32_t)regs[r1];
727 break;
728 #if TCG_TARGET_HAS_bswap64_i64
729 case INDEX_op_bswap64_i64:
730 tci_args_rr(insn, &r0, &r1);
731 regs[r0] = bswap64(regs[r1]);
732 break;
733 #endif
734 #endif /* TCG_TARGET_REG_BITS == 64 */
735
736 /* QEMU specific operations. */
737
738 case INDEX_op_exit_tb:
739 tci_args_l(insn, tb_ptr, &ptr);
740 return (uintptr_t)ptr;
741
742 case INDEX_op_goto_tb:
743 tci_args_l(insn, tb_ptr, &ptr);
744 tb_ptr = *(void **)ptr;
745 break;
746
747 case INDEX_op_goto_ptr:
748 tci_args_r(insn, &r0);
749 ptr = (void *)regs[r0];
750 if (!ptr) {
751 return 0;
752 }
753 tb_ptr = ptr;
754 break;
755
756 case INDEX_op_qemu_ld_i32:
757 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
758 tci_args_rrm(insn, &r0, &r1, &oi);
759 taddr = regs[r1];
760 } else {
761 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
762 taddr = tci_uint64(regs[r2], regs[r1]);
763 }
764 switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
765 case MO_UB:
766 tmp32 = qemu_ld_ub;
767 break;
768 case MO_SB:
769 tmp32 = (int8_t)qemu_ld_ub;
770 break;
771 case MO_LEUW:
772 tmp32 = qemu_ld_leuw;
773 break;
774 case MO_LESW:
775 tmp32 = (int16_t)qemu_ld_leuw;
776 break;
777 case MO_LEUL:
778 tmp32 = qemu_ld_leul;
779 break;
780 case MO_BEUW:
781 tmp32 = qemu_ld_beuw;
782 break;
783 case MO_BESW:
784 tmp32 = (int16_t)qemu_ld_beuw;
785 break;
786 case MO_BEUL:
787 tmp32 = qemu_ld_beul;
788 break;
789 default:
790 g_assert_not_reached();
791 }
792 regs[r0] = tmp32;
793 break;
794
795 case INDEX_op_qemu_ld_i64:
796 if (TCG_TARGET_REG_BITS == 64) {
797 tci_args_rrm(insn, &r0, &r1, &oi);
798 taddr = regs[r1];
799 } else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
800 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
801 taddr = regs[r2];
802 } else {
803 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
804 taddr = tci_uint64(regs[r3], regs[r2]);
805 oi = regs[r4];
806 }
807 switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
808 case MO_UB:
809 tmp64 = qemu_ld_ub;
810 break;
811 case MO_SB:
812 tmp64 = (int8_t)qemu_ld_ub;
813 break;
814 case MO_LEUW:
815 tmp64 = qemu_ld_leuw;
816 break;
817 case MO_LESW:
818 tmp64 = (int16_t)qemu_ld_leuw;
819 break;
820 case MO_LEUL:
821 tmp64 = qemu_ld_leul;
822 break;
823 case MO_LESL:
824 tmp64 = (int32_t)qemu_ld_leul;
825 break;
826 case MO_LEQ:
827 tmp64 = qemu_ld_leq;
828 break;
829 case MO_BEUW:
830 tmp64 = qemu_ld_beuw;
831 break;
832 case MO_BESW:
833 tmp64 = (int16_t)qemu_ld_beuw;
834 break;
835 case MO_BEUL:
836 tmp64 = qemu_ld_beul;
837 break;
838 case MO_BESL:
839 tmp64 = (int32_t)qemu_ld_beul;
840 break;
841 case MO_BEQ:
842 tmp64 = qemu_ld_beq;
843 break;
844 default:
845 g_assert_not_reached();
846 }
847 if (TCG_TARGET_REG_BITS == 32) {
848 tci_write_reg64(regs, r1, r0, tmp64);
849 } else {
850 regs[r0] = tmp64;
851 }
852 break;
853
854 case INDEX_op_qemu_st_i32:
855 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
856 tci_args_rrm(insn, &r0, &r1, &oi);
857 taddr = regs[r1];
858 } else {
859 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
860 taddr = tci_uint64(regs[r2], regs[r1]);
861 }
862 tmp32 = regs[r0];
863 switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
864 case MO_UB:
865 qemu_st_b(tmp32);
866 break;
867 case MO_LEUW:
868 qemu_st_lew(tmp32);
869 break;
870 case MO_LEUL:
871 qemu_st_lel(tmp32);
872 break;
873 case MO_BEUW:
874 qemu_st_bew(tmp32);
875 break;
876 case MO_BEUL:
877 qemu_st_bel(tmp32);
878 break;
879 default:
880 g_assert_not_reached();
881 }
882 break;
883
884 case INDEX_op_qemu_st_i64:
885 if (TCG_TARGET_REG_BITS == 64) {
886 tci_args_rrm(insn, &r0, &r1, &oi);
887 taddr = regs[r1];
888 tmp64 = regs[r0];
889 } else {
890 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
891 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
892 taddr = regs[r2];
893 } else {
894 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
895 taddr = tci_uint64(regs[r3], regs[r2]);
896 oi = regs[r4];
897 }
898 tmp64 = tci_uint64(regs[r1], regs[r0]);
899 }
900 switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
901 case MO_UB:
902 qemu_st_b(tmp64);
903 break;
904 case MO_LEUW:
905 qemu_st_lew(tmp64);
906 break;
907 case MO_LEUL:
908 qemu_st_lel(tmp64);
909 break;
910 case MO_LEQ:
911 qemu_st_leq(tmp64);
912 break;
913 case MO_BEUW:
914 qemu_st_bew(tmp64);
915 break;
916 case MO_BEUL:
917 qemu_st_bel(tmp64);
918 break;
919 case MO_BEQ:
920 qemu_st_beq(tmp64);
921 break;
922 default:
923 g_assert_not_reached();
924 }
925 break;
926
927 case INDEX_op_mb:
928 /* Ensure ordering for all kinds */
929 smp_mb();
930 break;
931 default:
932 g_assert_not_reached();
933 }
934 }
935 }
936
937 /*
938 * Disassembler that matches the interpreter
939 */
940
941 static const char *str_r(TCGReg r)
942 {
943 static const char regs[TCG_TARGET_NB_REGS][4] = {
944 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
945 "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
946 };
947
948 QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
949 QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
950
951 assert((unsigned)r < TCG_TARGET_NB_REGS);
952 return regs[r];
953 }
954
955 static const char *str_c(TCGCond c)
956 {
957 static const char cond[16][8] = {
958 [TCG_COND_NEVER] = "never",
959 [TCG_COND_ALWAYS] = "always",
960 [TCG_COND_EQ] = "eq",
961 [TCG_COND_NE] = "ne",
962 [TCG_COND_LT] = "lt",
963 [TCG_COND_GE] = "ge",
964 [TCG_COND_LE] = "le",
965 [TCG_COND_GT] = "gt",
966 [TCG_COND_LTU] = "ltu",
967 [TCG_COND_GEU] = "geu",
968 [TCG_COND_LEU] = "leu",
969 [TCG_COND_GTU] = "gtu",
970 };
971
972 assert((unsigned)c < ARRAY_SIZE(cond));
973 assert(cond[c][0] != 0);
974 return cond[c];
975 }
976
977 /* Disassemble TCI bytecode. */
978 int print_insn_tci(bfd_vma addr, disassemble_info *info)
979 {
980 const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
981 const TCGOpDef *def;
982 const char *op_name;
983 uint32_t insn;
984 TCGOpcode op;
985 TCGReg r0, r1, r2, r3, r4;
986 #if TCG_TARGET_REG_BITS == 32
987 TCGReg r5;
988 #endif
989 tcg_target_ulong i1;
990 int32_t s2;
991 TCGCond c;
992 TCGMemOpIdx oi;
993 uint8_t pos, len;
994 void *ptr;
995
996 /* TCI is always the host, so we don't need to load indirect. */
997 insn = *tb_ptr++;
998
999 info->fprintf_func(info->stream, "%08x ", insn);
1000
1001 op = extract32(insn, 0, 8);
1002 def = &tcg_op_defs[op];
1003 op_name = def->name;
1004
1005 switch (op) {
1006 case INDEX_op_br:
1007 case INDEX_op_exit_tb:
1008 case INDEX_op_goto_tb:
1009 tci_args_l(insn, tb_ptr, &ptr);
1010 info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
1011 break;
1012
1013 case INDEX_op_goto_ptr:
1014 tci_args_r(insn, &r0);
1015 info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0));
1016 break;
1017
1018 case INDEX_op_call:
1019 tci_args_nl(insn, tb_ptr, &len, &ptr);
1020 info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
1021 break;
1022
1023 case INDEX_op_brcond_i32:
1024 case INDEX_op_brcond_i64:
1025 tci_args_rl(insn, tb_ptr, &r0, &ptr);
1026 info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
1027 op_name, str_r(r0), ptr);
1028 break;
1029
1030 case INDEX_op_setcond_i32:
1031 case INDEX_op_setcond_i64:
1032 tci_args_rrrc(insn, &r0, &r1, &r2, &c);
1033 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1034 op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1035 break;
1036
1037 case INDEX_op_tci_movi:
1038 tci_args_ri(insn, &r0, &i1);
1039 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1040 op_name, str_r(r0), i1);
1041 break;
1042
1043 case INDEX_op_tci_movl:
1044 tci_args_rl(insn, tb_ptr, &r0, &ptr);
1045 info->fprintf_func(info->stream, "%-12s %s, %p",
1046 op_name, str_r(r0), ptr);
1047 break;
1048
1049 case INDEX_op_ld8u_i32:
1050 case INDEX_op_ld8u_i64:
1051 case INDEX_op_ld8s_i32:
1052 case INDEX_op_ld8s_i64:
1053 case INDEX_op_ld16u_i32:
1054 case INDEX_op_ld16u_i64:
1055 case INDEX_op_ld16s_i32:
1056 case INDEX_op_ld16s_i64:
1057 case INDEX_op_ld32u_i64:
1058 case INDEX_op_ld32s_i64:
1059 case INDEX_op_ld_i32:
1060 case INDEX_op_ld_i64:
1061 case INDEX_op_st8_i32:
1062 case INDEX_op_st8_i64:
1063 case INDEX_op_st16_i32:
1064 case INDEX_op_st16_i64:
1065 case INDEX_op_st32_i64:
1066 case INDEX_op_st_i32:
1067 case INDEX_op_st_i64:
1068 tci_args_rrs(insn, &r0, &r1, &s2);
1069 info->fprintf_func(info->stream, "%-12s %s, %s, %d",
1070 op_name, str_r(r0), str_r(r1), s2);
1071 break;
1072
1073 case INDEX_op_mov_i32:
1074 case INDEX_op_mov_i64:
1075 case INDEX_op_ext8s_i32:
1076 case INDEX_op_ext8s_i64:
1077 case INDEX_op_ext8u_i32:
1078 case INDEX_op_ext8u_i64:
1079 case INDEX_op_ext16s_i32:
1080 case INDEX_op_ext16s_i64:
1081 case INDEX_op_ext16u_i32:
1082 case INDEX_op_ext32s_i64:
1083 case INDEX_op_ext32u_i64:
1084 case INDEX_op_ext_i32_i64:
1085 case INDEX_op_extu_i32_i64:
1086 case INDEX_op_bswap16_i32:
1087 case INDEX_op_bswap16_i64:
1088 case INDEX_op_bswap32_i32:
1089 case INDEX_op_bswap32_i64:
1090 case INDEX_op_bswap64_i64:
1091 case INDEX_op_not_i32:
1092 case INDEX_op_not_i64:
1093 case INDEX_op_neg_i32:
1094 case INDEX_op_neg_i64:
1095 tci_args_rr(insn, &r0, &r1);
1096 info->fprintf_func(info->stream, "%-12s %s, %s",
1097 op_name, str_r(r0), str_r(r1));
1098 break;
1099
1100 case INDEX_op_add_i32:
1101 case INDEX_op_add_i64:
1102 case INDEX_op_sub_i32:
1103 case INDEX_op_sub_i64:
1104 case INDEX_op_mul_i32:
1105 case INDEX_op_mul_i64:
1106 case INDEX_op_and_i32:
1107 case INDEX_op_and_i64:
1108 case INDEX_op_or_i32:
1109 case INDEX_op_or_i64:
1110 case INDEX_op_xor_i32:
1111 case INDEX_op_xor_i64:
1112 case INDEX_op_div_i32:
1113 case INDEX_op_div_i64:
1114 case INDEX_op_rem_i32:
1115 case INDEX_op_rem_i64:
1116 case INDEX_op_divu_i32:
1117 case INDEX_op_divu_i64:
1118 case INDEX_op_remu_i32:
1119 case INDEX_op_remu_i64:
1120 case INDEX_op_shl_i32:
1121 case INDEX_op_shl_i64:
1122 case INDEX_op_shr_i32:
1123 case INDEX_op_shr_i64:
1124 case INDEX_op_sar_i32:
1125 case INDEX_op_sar_i64:
1126 case INDEX_op_rotl_i32:
1127 case INDEX_op_rotl_i64:
1128 case INDEX_op_rotr_i32:
1129 case INDEX_op_rotr_i64:
1130 tci_args_rrr(insn, &r0, &r1, &r2);
1131 info->fprintf_func(info->stream, "%-12s %s, %s, %s",
1132 op_name, str_r(r0), str_r(r1), str_r(r2));
1133 break;
1134
1135 case INDEX_op_deposit_i32:
1136 case INDEX_op_deposit_i64:
1137 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1138 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
1139 op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1140 break;
1141
1142 #if TCG_TARGET_REG_BITS == 32
1143 case INDEX_op_setcond2_i32:
1144 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1145 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1146 op_name, str_r(r0), str_r(r1), str_r(r2),
1147 str_r(r3), str_r(r4), str_c(c));
1148 break;
1149
1150 case INDEX_op_mulu2_i32:
1151 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1152 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1153 op_name, str_r(r0), str_r(r1),
1154 str_r(r2), str_r(r3));
1155 break;
1156
1157 case INDEX_op_add2_i32:
1158 case INDEX_op_sub2_i32:
1159 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1160 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1161 op_name, str_r(r0), str_r(r1), str_r(r2),
1162 str_r(r3), str_r(r4), str_r(r5));
1163 break;
1164 #endif
1165
1166 case INDEX_op_qemu_ld_i64:
1167 case INDEX_op_qemu_st_i64:
1168 len = DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1169 goto do_qemu_ldst;
1170 case INDEX_op_qemu_ld_i32:
1171 case INDEX_op_qemu_st_i32:
1172 len = 1;
1173 do_qemu_ldst:
1174 len += DIV_ROUND_UP(TARGET_LONG_BITS, TCG_TARGET_REG_BITS);
1175 switch (len) {
1176 case 2:
1177 tci_args_rrm(insn, &r0, &r1, &oi);
1178 info->fprintf_func(info->stream, "%-12s %s, %s, %x",
1179 op_name, str_r(r0), str_r(r1), oi);
1180 break;
1181 case 3:
1182 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1183 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %x",
1184 op_name, str_r(r0), str_r(r1), str_r(r2), oi);
1185 break;
1186 case 4:
1187 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1188 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
1189 op_name, str_r(r0), str_r(r1),
1190 str_r(r2), str_r(r3), str_r(r4));
1191 break;
1192 default:
1193 g_assert_not_reached();
1194 }
1195 break;
1196
1197 case 0:
1198 /* tcg_out_nop_fill uses zeros */
1199 if (insn == 0) {
1200 info->fprintf_func(info->stream, "align");
1201 break;
1202 }
1203 /* fall through */
1204
1205 default:
1206 info->fprintf_func(info->stream, "illegal opcode %d", op);
1207 break;
1208 }
1209
1210 return sizeof(insn);
1211 }