]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/tci.c
tcg/tci: Remove the qemu_ld/st_type macros
[mirror_qemu.git] / tcg / tci.c
CommitLineData
7657f4bf
SW
1/*
2 * Tiny Code Interpreter for QEMU
3 *
3ccdbecf 4 * Copyright (c) 2009, 2011, 2016 Stefan Weil
7657f4bf
SW
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
d38ea87a 20#include "qemu/osdep.h"
7657f4bf 21#include "qemu-common.h"
65603e2f 22#include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
f08b6170 23#include "exec/cpu_ldst.h"
dcb32f1d 24#include "tcg/tcg-op.h"
c905a368 25#include "qemu/compiler.h"
7b7d8b2d 26#include <ffi.h>
7657f4bf 27
7b7d8b2d
RH
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)
7657f4bf 35#else
7b7d8b2d 36# define tci_assert(cond) ((void)(cond))
7657f4bf
SW
37#endif
38
13e71f08
RH
39__thread uintptr_t tci_tb_ptr;
40
5e75150c
EC
41static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
42 uint32_t low_index, uint64_t value)
7657f4bf 43{
f6db0d8d 44 regs[low_index] = (uint32_t)value;
7e00a080 45 regs[high_index] = value >> 32;
7657f4bf 46}
7657f4bf 47
7657f4bf
SW
48/* Create a 64 bit value from two 32 bit values. */
49static uint64_t tci_uint64(uint32_t high, uint32_t low)
50{
51 return ((uint64_t)high << 32) + low;
52}
7657f4bf 53
cdd9799b
RH
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 *
79dd3a4f 59 * b = immediate (bit position)
963e9fa2 60 * c = condition (TCGCond)
b95aa12e
RH
61 * i = immediate (uint32_t)
62 * I = immediate (tcg_target_ulong)
f28ca03e 63 * l = label or pointer
63041ed2 64 * m = immediate (TCGMemOpIdx)
7b7d8b2d 65 * n = immediate (call return length)
cdd9799b
RH
66 * r = register
67 * s = signed ldst offset
68 */
69
65089889 70static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
92bc4fad 71{
65089889
RH
72 int diff = sextract32(insn, 12, 20);
73 *l0 = diff ? (void *)tb_ptr + diff : NULL;
92bc4fad
RH
74}
75
6eea0434
RH
76static void tci_args_r(uint32_t insn, TCGReg *r0)
77{
78 *r0 = extract32(insn, 8, 4);
79}
80
65089889
RH
81static void tci_args_nl(uint32_t insn, const void *tb_ptr,
82 uint8_t *n0, void **l1)
f28ca03e 83{
65089889
RH
84 *n0 = extract32(insn, 8, 4);
85 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
f28ca03e
RH
86}
87
65089889
RH
88static void tci_args_rl(uint32_t insn, const void *tb_ptr,
89 TCGReg *r0, void **l1)
7b7d8b2d 90{
65089889
RH
91 *r0 = extract32(insn, 8, 4);
92 *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
7b7d8b2d
RH
93}
94
65089889 95static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
fc8ec9e1 96{
65089889
RH
97 *r0 = extract32(insn, 8, 4);
98 *r1 = extract32(insn, 12, 4);
fc8ec9e1
RH
99}
100
65089889 101static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
fc4a62f6 102{
65089889
RH
103 *r0 = extract32(insn, 8, 4);
104 *i1 = sextract32(insn, 12, 20);
fc4a62f6
RH
105}
106
65089889
RH
107static void tci_args_rrm(uint32_t insn, TCGReg *r0,
108 TCGReg *r1, TCGMemOpIdx *m2)
b95aa12e 109{
65089889
RH
110 *r0 = extract32(insn, 8, 4);
111 *r1 = extract32(insn, 12, 4);
112 *m2 = extract32(insn, 20, 12);
b95aa12e
RH
113}
114
65089889 115static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
b95aa12e 116{
65089889
RH
117 *r0 = extract32(insn, 8, 4);
118 *r1 = extract32(insn, 12, 4);
119 *r2 = extract32(insn, 16, 4);
b95aa12e 120}
b95aa12e 121
65089889 122static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
63041ed2 123{
65089889
RH
124 *r0 = extract32(insn, 8, 4);
125 *r1 = extract32(insn, 12, 4);
126 *i2 = sextract32(insn, 16, 16);
63041ed2
RH
127}
128
0f10d7c5
RH
129static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
130 uint8_t *i2, uint8_t *i3)
131{
132 *r0 = extract32(insn, 8, 4);
133 *r1 = extract32(insn, 12, 4);
134 *i2 = extract32(insn, 16, 6);
135 *i3 = extract32(insn, 22, 6);
136}
137
65089889 138static void tci_args_rrrc(uint32_t insn,
963e9fa2
RH
139 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
140{
65089889
RH
141 *r0 = extract32(insn, 8, 4);
142 *r1 = extract32(insn, 12, 4);
143 *r2 = extract32(insn, 16, 4);
144 *c3 = extract32(insn, 20, 4);
963e9fa2
RH
145}
146
65089889 147static void tci_args_rrrm(uint32_t insn,
63041ed2
RH
148 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
149{
65089889
RH
150 *r0 = extract32(insn, 8, 4);
151 *r1 = extract32(insn, 12, 4);
152 *r2 = extract32(insn, 16, 4);
153 *m3 = extract32(insn, 20, 12);
63041ed2
RH
154}
155
65089889 156static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
79dd3a4f
RH
157 TCGReg *r2, uint8_t *i3, uint8_t *i4)
158{
65089889
RH
159 *r0 = extract32(insn, 8, 4);
160 *r1 = extract32(insn, 12, 4);
161 *r2 = extract32(insn, 16, 4);
162 *i3 = extract32(insn, 20, 6);
163 *i4 = extract32(insn, 26, 6);
79dd3a4f
RH
164}
165
65089889
RH
166static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
167 TCGReg *r2, TCGReg *r3, TCGReg *r4)
63041ed2 168{
65089889
RH
169 *r0 = extract32(insn, 8, 4);
170 *r1 = extract32(insn, 12, 4);
171 *r2 = extract32(insn, 16, 4);
172 *r3 = extract32(insn, 20, 4);
173 *r4 = extract32(insn, 24, 4);
63041ed2
RH
174}
175
65089889 176static void tci_args_rrrr(uint32_t insn,
cbe87131
RH
177 TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
178{
65089889
RH
179 *r0 = extract32(insn, 8, 4);
180 *r1 = extract32(insn, 12, 4);
181 *r2 = extract32(insn, 16, 4);
182 *r3 = extract32(insn, 20, 4);
cbe87131
RH
183}
184
65089889 185static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
817cadd6
RH
186 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
187{
65089889
RH
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 *c5 = extract32(insn, 28, 4);
817cadd6 194}
120402b5 195
65089889 196static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
120402b5
RH
197 TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
198{
65089889
RH
199 *r0 = extract32(insn, 8, 4);
200 *r1 = extract32(insn, 12, 4);
201 *r2 = extract32(insn, 16, 4);
202 *r3 = extract32(insn, 20, 4);
203 *r4 = extract32(insn, 24, 4);
204 *r5 = extract32(insn, 28, 4);
120402b5 205}
817cadd6 206
7657f4bf
SW
207static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
208{
209 bool result = false;
210 int32_t i0 = u0;
211 int32_t i1 = u1;
212 switch (condition) {
213 case TCG_COND_EQ:
214 result = (u0 == u1);
215 break;
216 case TCG_COND_NE:
217 result = (u0 != u1);
218 break;
219 case TCG_COND_LT:
220 result = (i0 < i1);
221 break;
222 case TCG_COND_GE:
223 result = (i0 >= i1);
224 break;
225 case TCG_COND_LE:
226 result = (i0 <= i1);
227 break;
228 case TCG_COND_GT:
229 result = (i0 > i1);
230 break;
231 case TCG_COND_LTU:
232 result = (u0 < u1);
233 break;
234 case TCG_COND_GEU:
235 result = (u0 >= u1);
236 break;
237 case TCG_COND_LEU:
238 result = (u0 <= u1);
239 break;
240 case TCG_COND_GTU:
241 result = (u0 > u1);
242 break;
243 default:
f6996f99 244 g_assert_not_reached();
7657f4bf
SW
245 }
246 return result;
247}
248
249static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
250{
251 bool result = false;
252 int64_t i0 = u0;
253 int64_t i1 = u1;
254 switch (condition) {
255 case TCG_COND_EQ:
256 result = (u0 == u1);
257 break;
258 case TCG_COND_NE:
259 result = (u0 != u1);
260 break;
261 case TCG_COND_LT:
262 result = (i0 < i1);
263 break;
264 case TCG_COND_GE:
265 result = (i0 >= i1);
266 break;
267 case TCG_COND_LE:
268 result = (i0 <= i1);
269 break;
270 case TCG_COND_GT:
271 result = (i0 > i1);
272 break;
273 case TCG_COND_LTU:
274 result = (u0 < u1);
275 break;
276 case TCG_COND_GEU:
277 result = (u0 >= u1);
278 break;
279 case TCG_COND_LEU:
280 result = (u0 <= u1);
281 break;
282 case TCG_COND_GTU:
283 result = (u0 > u1);
284 break;
285 default:
f6996f99 286 g_assert_not_reached();
7657f4bf
SW
287 }
288 return result;
289}
290
69acc02a
RH
291static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
292 TCGMemOpIdx oi, const void *tb_ptr)
293{
294 MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
295
d1b1348c
RH
296#ifdef CONFIG_SOFTMMU
297 uintptr_t ra = (uintptr_t)tb_ptr;
298
299 switch (mop) {
300 case MO_UB:
301 return helper_ret_ldub_mmu(env, taddr, oi, ra);
302 case MO_SB:
303 return helper_ret_ldsb_mmu(env, taddr, oi, ra);
304 case MO_LEUW:
305 return helper_le_lduw_mmu(env, taddr, oi, ra);
306 case MO_LESW:
307 return helper_le_ldsw_mmu(env, taddr, oi, ra);
308 case MO_LEUL:
309 return helper_le_ldul_mmu(env, taddr, oi, ra);
310 case MO_LESL:
311 return helper_le_ldsl_mmu(env, taddr, oi, ra);
312 case MO_LEQ:
313 return helper_le_ldq_mmu(env, taddr, oi, ra);
314 case MO_BEUW:
315 return helper_be_lduw_mmu(env, taddr, oi, ra);
316 case MO_BESW:
317 return helper_be_ldsw_mmu(env, taddr, oi, ra);
318 case MO_BEUL:
319 return helper_be_ldul_mmu(env, taddr, oi, ra);
320 case MO_BESL:
321 return helper_be_ldsl_mmu(env, taddr, oi, ra);
322 case MO_BEQ:
323 return helper_be_ldq_mmu(env, taddr, oi, ra);
324 default:
325 g_assert_not_reached();
326 }
327#else
328 void *haddr = g2h(env_cpu(env), taddr);
329 uint64_t ret;
330
69acc02a
RH
331 switch (mop) {
332 case MO_UB:
d1b1348c
RH
333 ret = ldub_p(haddr);
334 break;
69acc02a 335 case MO_SB:
d1b1348c
RH
336 ret = ldsb_p(haddr);
337 break;
69acc02a 338 case MO_LEUW:
d1b1348c
RH
339 ret = lduw_le_p(haddr);
340 break;
69acc02a 341 case MO_LESW:
d1b1348c
RH
342 ret = ldsw_le_p(haddr);
343 break;
69acc02a 344 case MO_LEUL:
d1b1348c
RH
345 ret = (uint32_t)ldl_le_p(haddr);
346 break;
69acc02a 347 case MO_LESL:
d1b1348c
RH
348 ret = (int32_t)ldl_le_p(haddr);
349 break;
69acc02a 350 case MO_LEQ:
d1b1348c
RH
351 ret = ldq_le_p(haddr);
352 break;
69acc02a 353 case MO_BEUW:
d1b1348c
RH
354 ret = lduw_be_p(haddr);
355 break;
69acc02a 356 case MO_BESW:
d1b1348c
RH
357 ret = ldsw_be_p(haddr);
358 break;
69acc02a 359 case MO_BEUL:
d1b1348c
RH
360 ret = (uint32_t)ldl_be_p(haddr);
361 break;
69acc02a 362 case MO_BESL:
d1b1348c
RH
363 ret = (int32_t)ldl_be_p(haddr);
364 break;
69acc02a 365 case MO_BEQ:
d1b1348c
RH
366 ret = ldq_be_p(haddr);
367 break;
69acc02a
RH
368 default:
369 g_assert_not_reached();
370 }
d1b1348c
RH
371 return ret;
372#endif
69acc02a
RH
373}
374
375static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
376 TCGMemOpIdx oi, const void *tb_ptr)
377{
378 MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
379
d1b1348c
RH
380#ifdef CONFIG_SOFTMMU
381 uintptr_t ra = (uintptr_t)tb_ptr;
382
383 switch (mop) {
384 case MO_UB:
385 helper_ret_stb_mmu(env, taddr, val, oi, ra);
386 break;
387 case MO_LEUW:
388 helper_le_stw_mmu(env, taddr, val, oi, ra);
389 break;
390 case MO_LEUL:
391 helper_le_stl_mmu(env, taddr, val, oi, ra);
392 break;
393 case MO_LEQ:
394 helper_le_stq_mmu(env, taddr, val, oi, ra);
395 break;
396 case MO_BEUW:
397 helper_be_stw_mmu(env, taddr, val, oi, ra);
398 break;
399 case MO_BEUL:
400 helper_be_stl_mmu(env, taddr, val, oi, ra);
401 break;
402 case MO_BEQ:
403 helper_be_stq_mmu(env, taddr, val, oi, ra);
404 break;
405 default:
406 g_assert_not_reached();
407 }
408#else
409 void *haddr = g2h(env_cpu(env), taddr);
410
69acc02a
RH
411 switch (mop) {
412 case MO_UB:
d1b1348c 413 stb_p(haddr, val);
69acc02a
RH
414 break;
415 case MO_LEUW:
d1b1348c 416 stw_le_p(haddr, val);
69acc02a
RH
417 break;
418 case MO_LEUL:
d1b1348c 419 stl_le_p(haddr, val);
69acc02a
RH
420 break;
421 case MO_LEQ:
d1b1348c 422 stq_le_p(haddr, val);
69acc02a
RH
423 break;
424 case MO_BEUW:
d1b1348c 425 stw_be_p(haddr, val);
69acc02a
RH
426 break;
427 case MO_BEUL:
d1b1348c 428 stl_be_p(haddr, val);
69acc02a
RH
429 break;
430 case MO_BEQ:
d1b1348c 431 stq_be_p(haddr, val);
69acc02a
RH
432 break;
433 default:
434 g_assert_not_reached();
435 }
d1b1348c 436#endif
69acc02a
RH
437}
438
7f33f5cd
RH
439#if TCG_TARGET_REG_BITS == 64
440# define CASE_32_64(x) \
441 case glue(glue(INDEX_op_, x), _i64): \
442 case glue(glue(INDEX_op_, x), _i32):
443# define CASE_64(x) \
444 case glue(glue(INDEX_op_, x), _i64):
445#else
446# define CASE_32_64(x) \
447 case glue(glue(INDEX_op_, x), _i32):
448# define CASE_64(x)
449#endif
450
7657f4bf 451/* Interpret pseudo code in tb. */
c905a368
DB
452/*
453 * Disable CFI checks.
454 * One possible operation in the pseudo code is a call to binary code.
455 * Therefore, disable CFI checks in the interpreter function
456 */
db0c51a3
RH
457uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
458 const void *v_tb_ptr)
7657f4bf 459{
65089889 460 const uint32_t *tb_ptr = v_tb_ptr;
5e75150c 461 tcg_target_ulong regs[TCG_TARGET_NB_REGS];
7b7d8b2d
RH
462 uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
463 / sizeof(uint64_t)];
464 void *call_slots[TCG_STATIC_CALL_ARGS_SIZE / sizeof(uint64_t)];
7657f4bf 465
5e75150c 466 regs[TCG_AREG0] = (tcg_target_ulong)env;
7b7d8b2d
RH
467 regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
468 /* Other call_slots entries initialized at first use (see below). */
469 call_slots[0] = NULL;
3ccdbecf 470 tci_assert(tb_ptr);
7657f4bf
SW
471
472 for (;;) {
65089889
RH
473 uint32_t insn;
474 TCGOpcode opc;
08096b1a 475 TCGReg r0, r1, r2, r3, r4, r5;
7657f4bf 476 tcg_target_ulong t1;
7657f4bf
SW
477 TCGCond condition;
478 target_ulong taddr;
79dd3a4f 479 uint8_t pos, len;
7657f4bf
SW
480 uint32_t tmp32;
481 uint64_t tmp64;
5a0adf34 482 uint64_t T1, T2;
59227d5d 483 TCGMemOpIdx oi;
cdd9799b 484 int32_t ofs;
65089889 485 void *ptr;
7657f4bf 486
65089889
RH
487 insn = *tb_ptr++;
488 opc = extract32(insn, 0, 8);
7657f4bf
SW
489
490 switch (opc) {
7657f4bf 491 case INDEX_op_call:
7b7d8b2d
RH
492 /*
493 * Set up the ffi_avalue array once, delayed until now
494 * because many TB's do not make any calls. In tcg_gen_callN,
495 * we arranged for every real argument to be "left-aligned"
496 * in each 64-bit slot.
497 */
498 if (unlikely(call_slots[0] == NULL)) {
499 for (int i = 0; i < ARRAY_SIZE(call_slots); ++i) {
500 call_slots[i] = &stack[i];
501 }
502 }
503
65089889 504 tci_args_nl(insn, tb_ptr, &len, &ptr);
7b7d8b2d
RH
505
506 /* Helper functions may need to access the "return address" */
13e71f08 507 tci_tb_ptr = (uintptr_t)tb_ptr;
7b7d8b2d 508
65089889
RH
509 {
510 void **pptr = ptr;
511 ffi_call(pptr[1], pptr[0], stack, call_slots);
512 }
7b7d8b2d
RH
513
514 /* Any result winds up "left-aligned" in the stack[0] slot. */
515 switch (len) {
516 case 0: /* void */
517 break;
518 case 1: /* uint32_t */
519 /*
520 * Note that libffi has an odd special case in that it will
521 * always widen an integral result to ffi_arg.
522 */
523 if (sizeof(ffi_arg) == 4) {
524 regs[TCG_REG_R0] = *(uint32_t *)stack;
525 break;
526 }
527 /* fall through */
528 case 2: /* uint64_t */
529 if (TCG_TARGET_REG_BITS == 32) {
530 tci_write_reg64(regs, TCG_REG_R1, TCG_REG_R0, stack[0]);
531 } else {
532 regs[TCG_REG_R0] = stack[0];
533 }
534 break;
535 default:
536 g_assert_not_reached();
537 }
7657f4bf 538 break;
7b7d8b2d 539
7657f4bf 540 case INDEX_op_br:
65089889 541 tci_args_l(insn, tb_ptr, &ptr);
f28ca03e 542 tb_ptr = ptr;
7657f4bf
SW
543 continue;
544 case INDEX_op_setcond_i32:
65089889 545 tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
963e9fa2 546 regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
7657f4bf 547 break;
df093c19
RH
548 case INDEX_op_movcond_i32:
549 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
550 tmp32 = tci_compare32(regs[r1], regs[r2], condition);
551 regs[r0] = regs[tmp32 ? r3 : r4];
552 break;
7657f4bf
SW
553#if TCG_TARGET_REG_BITS == 32
554 case INDEX_op_setcond2_i32:
65089889 555 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
817cadd6
RH
556 T1 = tci_uint64(regs[r2], regs[r1]);
557 T2 = tci_uint64(regs[r4], regs[r3]);
558 regs[r0] = tci_compare64(T1, T2, condition);
7657f4bf
SW
559 break;
560#elif TCG_TARGET_REG_BITS == 64
561 case INDEX_op_setcond_i64:
65089889 562 tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
963e9fa2 563 regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
7657f4bf 564 break;
df093c19
RH
565 case INDEX_op_movcond_i64:
566 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
567 tmp32 = tci_compare64(regs[r1], regs[r2], condition);
568 regs[r0] = regs[tmp32 ? r3 : r4];
569 break;
7657f4bf 570#endif
9e9acb7b 571 CASE_32_64(mov)
65089889 572 tci_args_rr(insn, &r0, &r1);
fc4a62f6 573 regs[r0] = regs[r1];
7657f4bf 574 break;
65089889
RH
575 case INDEX_op_tci_movi:
576 tci_args_ri(insn, &r0, &t1);
b95aa12e 577 regs[r0] = t1;
7657f4bf 578 break;
65089889
RH
579 case INDEX_op_tci_movl:
580 tci_args_rl(insn, tb_ptr, &r0, &ptr);
581 regs[r0] = *(tcg_target_ulong *)ptr;
582 break;
7657f4bf
SW
583
584 /* Load/store operations (32 bit). */
585
7f33f5cd 586 CASE_32_64(ld8u)
65089889 587 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
588 ptr = (void *)(regs[r1] + ofs);
589 regs[r0] = *(uint8_t *)ptr;
7657f4bf 590 break;
850163eb 591 CASE_32_64(ld8s)
65089889 592 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
593 ptr = (void *)(regs[r1] + ofs);
594 regs[r0] = *(int8_t *)ptr;
2f160e0f 595 break;
77c38c7c 596 CASE_32_64(ld16u)
65089889 597 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
598 ptr = (void *)(regs[r1] + ofs);
599 regs[r0] = *(uint16_t *)ptr;
7657f4bf 600 break;
b09d78bf 601 CASE_32_64(ld16s)
65089889 602 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
603 ptr = (void *)(regs[r1] + ofs);
604 regs[r0] = *(int16_t *)ptr;
7657f4bf
SW
605 break;
606 case INDEX_op_ld_i32:
c1d77e94 607 CASE_64(ld32u)
65089889 608 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
609 ptr = (void *)(regs[r1] + ofs);
610 regs[r0] = *(uint32_t *)ptr;
7657f4bf 611 break;
ba9a80c1 612 CASE_32_64(st8)
65089889 613 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
614 ptr = (void *)(regs[r1] + ofs);
615 *(uint8_t *)ptr = regs[r0];
7657f4bf 616 break;
90be4dde 617 CASE_32_64(st16)
65089889 618 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
619 ptr = (void *)(regs[r1] + ofs);
620 *(uint16_t *)ptr = regs[r0];
7657f4bf
SW
621 break;
622 case INDEX_op_st_i32:
b4d5bf0f 623 CASE_64(st32)
65089889 624 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
625 ptr = (void *)(regs[r1] + ofs);
626 *(uint32_t *)ptr = regs[r0];
7657f4bf
SW
627 break;
628
dd2bb20e 629 /* Arithmetic operations (mixed 32/64 bit). */
7657f4bf 630
dd2bb20e 631 CASE_32_64(add)
65089889 632 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 633 regs[r0] = regs[r1] + regs[r2];
7657f4bf 634 break;
dd2bb20e 635 CASE_32_64(sub)
65089889 636 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 637 regs[r0] = regs[r1] - regs[r2];
7657f4bf 638 break;
dd2bb20e 639 CASE_32_64(mul)
65089889 640 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 641 regs[r0] = regs[r1] * regs[r2];
7657f4bf 642 break;
dd2bb20e 643 CASE_32_64(and)
65089889 644 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 645 regs[r0] = regs[r1] & regs[r2];
7657f4bf 646 break;
dd2bb20e 647 CASE_32_64(or)
65089889 648 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 649 regs[r0] = regs[r1] | regs[r2];
7657f4bf 650 break;
dd2bb20e 651 CASE_32_64(xor)
65089889 652 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 653 regs[r0] = regs[r1] ^ regs[r2];
7657f4bf 654 break;
a81520b9
RH
655#if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64
656 CASE_32_64(andc)
657 tci_args_rrr(insn, &r0, &r1, &r2);
658 regs[r0] = regs[r1] & ~regs[r2];
659 break;
660#endif
661#if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64
662 CASE_32_64(orc)
663 tci_args_rrr(insn, &r0, &r1, &r2);
664 regs[r0] = regs[r1] | ~regs[r2];
665 break;
666#endif
667#if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64
668 CASE_32_64(eqv)
669 tci_args_rrr(insn, &r0, &r1, &r2);
670 regs[r0] = ~(regs[r1] ^ regs[r2]);
671 break;
672#endif
673#if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64
674 CASE_32_64(nand)
675 tci_args_rrr(insn, &r0, &r1, &r2);
676 regs[r0] = ~(regs[r1] & regs[r2]);
677 break;
678#endif
679#if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64
680 CASE_32_64(nor)
681 tci_args_rrr(insn, &r0, &r1, &r2);
682 regs[r0] = ~(regs[r1] | regs[r2]);
683 break;
684#endif
dd2bb20e
RH
685
686 /* Arithmetic operations (32 bit). */
687
688 case INDEX_op_div_i32:
65089889 689 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 690 regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
7657f4bf 691 break;
dd2bb20e 692 case INDEX_op_divu_i32:
65089889 693 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 694 regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
7657f4bf 695 break;
dd2bb20e 696 case INDEX_op_rem_i32:
65089889 697 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 698 regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
7657f4bf 699 break;
dd2bb20e 700 case INDEX_op_remu_i32:
65089889 701 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 702 regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
7657f4bf 703 break;
5255f48c
RH
704#if TCG_TARGET_HAS_clz_i32
705 case INDEX_op_clz_i32:
706 tci_args_rrr(insn, &r0, &r1, &r2);
707 tmp32 = regs[r1];
708 regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
709 break;
710#endif
711#if TCG_TARGET_HAS_ctz_i32
712 case INDEX_op_ctz_i32:
713 tci_args_rrr(insn, &r0, &r1, &r2);
714 tmp32 = regs[r1];
715 regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
716 break;
717#endif
718#if TCG_TARGET_HAS_ctpop_i32
719 case INDEX_op_ctpop_i32:
720 tci_args_rr(insn, &r0, &r1);
721 regs[r0] = ctpop32(regs[r1]);
722 break;
723#endif
7657f4bf
SW
724
725 /* Shift/rotate operations (32 bit). */
726
727 case INDEX_op_shl_i32:
65089889 728 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 729 regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
7657f4bf
SW
730 break;
731 case INDEX_op_shr_i32:
65089889 732 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 733 regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
7657f4bf
SW
734 break;
735 case INDEX_op_sar_i32:
65089889 736 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 737 regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
7657f4bf
SW
738 break;
739#if TCG_TARGET_HAS_rot_i32
740 case INDEX_op_rotl_i32:
65089889 741 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 742 regs[r0] = rol32(regs[r1], regs[r2] & 31);
7657f4bf
SW
743 break;
744 case INDEX_op_rotr_i32:
65089889 745 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 746 regs[r0] = ror32(regs[r1], regs[r2] & 31);
7657f4bf 747 break;
e24dc9fe
SW
748#endif
749#if TCG_TARGET_HAS_deposit_i32
750 case INDEX_op_deposit_i32:
65089889 751 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
79dd3a4f 752 regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
e24dc9fe 753 break;
0f10d7c5
RH
754#endif
755#if TCG_TARGET_HAS_extract_i32
756 case INDEX_op_extract_i32:
757 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
758 regs[r0] = extract32(regs[r1], pos, len);
759 break;
760#endif
761#if TCG_TARGET_HAS_sextract_i32
762 case INDEX_op_sextract_i32:
763 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
764 regs[r0] = sextract32(regs[r1], pos, len);
765 break;
7657f4bf
SW
766#endif
767 case INDEX_op_brcond_i32:
65089889 768 tci_args_rl(insn, tb_ptr, &r0, &ptr);
fc8ec9e1 769 if ((uint32_t)regs[r0]) {
5a0adf34 770 tb_ptr = ptr;
7657f4bf
SW
771 }
772 break;
08096b1a 773#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
7657f4bf 774 case INDEX_op_add2_i32:
65089889 775 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
120402b5
RH
776 T1 = tci_uint64(regs[r3], regs[r2]);
777 T2 = tci_uint64(regs[r5], regs[r4]);
778 tci_write_reg64(regs, r1, r0, T1 + T2);
7657f4bf 779 break;
08096b1a
RH
780#endif
781#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
7657f4bf 782 case INDEX_op_sub2_i32:
65089889 783 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
120402b5
RH
784 T1 = tci_uint64(regs[r3], regs[r2]);
785 T2 = tci_uint64(regs[r5], regs[r4]);
786 tci_write_reg64(regs, r1, r0, T1 - T2);
7657f4bf 787 break;
08096b1a 788#endif
f6db0d8d 789#if TCG_TARGET_HAS_mulu2_i32
7657f4bf 790 case INDEX_op_mulu2_i32:
65089889 791 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
f6db0d8d
RH
792 tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
793 tci_write_reg64(regs, r1, r0, tmp64);
7657f4bf 794 break;
f6db0d8d
RH
795#endif
796#if TCG_TARGET_HAS_muls2_i32
797 case INDEX_op_muls2_i32:
798 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
799 tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
800 tci_write_reg64(regs, r1, r0, tmp64);
801 break;
802#endif
13a1d640
RH
803#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
804 CASE_32_64(ext8s)
65089889 805 tci_args_rr(insn, &r0, &r1);
fc4a62f6 806 regs[r0] = (int8_t)regs[r1];
7657f4bf
SW
807 break;
808#endif
13a1d640
RH
809#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64
810 CASE_32_64(ext16s)
65089889 811 tci_args_rr(insn, &r0, &r1);
fc4a62f6 812 regs[r0] = (int16_t)regs[r1];
7657f4bf
SW
813 break;
814#endif
13a1d640
RH
815#if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
816 CASE_32_64(ext8u)
65089889 817 tci_args_rr(insn, &r0, &r1);
fc4a62f6 818 regs[r0] = (uint8_t)regs[r1];
7657f4bf
SW
819 break;
820#endif
13a1d640
RH
821#if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
822 CASE_32_64(ext16u)
65089889 823 tci_args_rr(insn, &r0, &r1);
fc4a62f6 824 regs[r0] = (uint16_t)regs[r1];
7657f4bf
SW
825 break;
826#endif
fe2b13bb
RH
827#if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
828 CASE_32_64(bswap16)
65089889 829 tci_args_rr(insn, &r0, &r1);
fc4a62f6 830 regs[r0] = bswap16(regs[r1]);
7657f4bf
SW
831 break;
832#endif
fe2b13bb
RH
833#if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
834 CASE_32_64(bswap32)
65089889 835 tci_args_rr(insn, &r0, &r1);
fc4a62f6 836 regs[r0] = bswap32(regs[r1]);
7657f4bf
SW
837 break;
838#endif
9e9acb7b
RH
839#if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
840 CASE_32_64(not)
65089889 841 tci_args_rr(insn, &r0, &r1);
fc4a62f6 842 regs[r0] = ~regs[r1];
7657f4bf
SW
843 break;
844#endif
9e9acb7b
RH
845#if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64
846 CASE_32_64(neg)
65089889 847 tci_args_rr(insn, &r0, &r1);
fc4a62f6 848 regs[r0] = -regs[r1];
7657f4bf
SW
849 break;
850#endif
851#if TCG_TARGET_REG_BITS == 64
7657f4bf
SW
852 /* Load/store operations (64 bit). */
853
7657f4bf 854 case INDEX_op_ld32s_i64:
65089889 855 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
856 ptr = (void *)(regs[r1] + ofs);
857 regs[r0] = *(int32_t *)ptr;
7657f4bf
SW
858 break;
859 case INDEX_op_ld_i64:
65089889 860 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
861 ptr = (void *)(regs[r1] + ofs);
862 regs[r0] = *(uint64_t *)ptr;
7657f4bf 863 break;
7657f4bf 864 case INDEX_op_st_i64:
65089889 865 tci_args_rrs(insn, &r0, &r1, &ofs);
cdd9799b
RH
866 ptr = (void *)(regs[r1] + ofs);
867 *(uint64_t *)ptr = regs[r0];
7657f4bf
SW
868 break;
869
870 /* Arithmetic operations (64 bit). */
871
7657f4bf 872 case INDEX_op_div_i64:
65089889 873 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 874 regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
ae40c098 875 break;
7657f4bf 876 case INDEX_op_divu_i64:
65089889 877 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 878 regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
ae40c098 879 break;
7657f4bf 880 case INDEX_op_rem_i64:
65089889 881 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 882 regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
ae40c098 883 break;
7657f4bf 884 case INDEX_op_remu_i64:
65089889 885 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 886 regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
7657f4bf 887 break;
5255f48c
RH
888#if TCG_TARGET_HAS_clz_i64
889 case INDEX_op_clz_i64:
890 tci_args_rrr(insn, &r0, &r1, &r2);
891 regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
892 break;
893#endif
894#if TCG_TARGET_HAS_ctz_i64
895 case INDEX_op_ctz_i64:
896 tci_args_rrr(insn, &r0, &r1, &r2);
897 regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
898 break;
899#endif
900#if TCG_TARGET_HAS_ctpop_i64
901 case INDEX_op_ctpop_i64:
902 tci_args_rr(insn, &r0, &r1);
903 regs[r0] = ctpop64(regs[r1]);
904 break;
905#endif
f6db0d8d
RH
906#if TCG_TARGET_HAS_mulu2_i64
907 case INDEX_op_mulu2_i64:
908 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
909 mulu64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
910 break;
911#endif
912#if TCG_TARGET_HAS_muls2_i64
913 case INDEX_op_muls2_i64:
914 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
915 muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
916 break;
917#endif
08096b1a
RH
918#if TCG_TARGET_HAS_add2_i64
919 case INDEX_op_add2_i64:
920 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
921 T1 = regs[r2] + regs[r4];
922 T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
923 regs[r0] = T1;
924 regs[r1] = T2;
925 break;
926#endif
927#if TCG_TARGET_HAS_add2_i64
928 case INDEX_op_sub2_i64:
929 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
930 T1 = regs[r2] - regs[r4];
931 T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
932 regs[r0] = T1;
933 regs[r1] = T2;
934 break;
935#endif
7657f4bf
SW
936
937 /* Shift/rotate operations (64 bit). */
938
939 case INDEX_op_shl_i64:
65089889 940 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 941 regs[r0] = regs[r1] << (regs[r2] & 63);
7657f4bf
SW
942 break;
943 case INDEX_op_shr_i64:
65089889 944 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 945 regs[r0] = regs[r1] >> (regs[r2] & 63);
7657f4bf
SW
946 break;
947 case INDEX_op_sar_i64:
65089889 948 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 949 regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
7657f4bf
SW
950 break;
951#if TCG_TARGET_HAS_rot_i64
952 case INDEX_op_rotl_i64:
65089889 953 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 954 regs[r0] = rol64(regs[r1], regs[r2] & 63);
d285bf78 955 break;
7657f4bf 956 case INDEX_op_rotr_i64:
65089889 957 tci_args_rrr(insn, &r0, &r1, &r2);
e85e4b8f 958 regs[r0] = ror64(regs[r1], regs[r2] & 63);
7657f4bf 959 break;
e24dc9fe
SW
960#endif
961#if TCG_TARGET_HAS_deposit_i64
962 case INDEX_op_deposit_i64:
65089889 963 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
79dd3a4f 964 regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
e24dc9fe 965 break;
0f10d7c5
RH
966#endif
967#if TCG_TARGET_HAS_extract_i64
968 case INDEX_op_extract_i64:
969 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
970 regs[r0] = extract64(regs[r1], pos, len);
971 break;
972#endif
973#if TCG_TARGET_HAS_sextract_i64
974 case INDEX_op_sextract_i64:
975 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
976 regs[r0] = sextract64(regs[r1], pos, len);
977 break;
7657f4bf
SW
978#endif
979 case INDEX_op_brcond_i64:
65089889 980 tci_args_rl(insn, tb_ptr, &r0, &ptr);
fc8ec9e1 981 if (regs[r0]) {
5a0adf34 982 tb_ptr = ptr;
7657f4bf
SW
983 }
984 break;
7657f4bf 985 case INDEX_op_ext32s_i64:
4f2331e5 986 case INDEX_op_ext_i32_i64:
65089889 987 tci_args_rr(insn, &r0, &r1);
fc4a62f6 988 regs[r0] = (int32_t)regs[r1];
7657f4bf 989 break;
7657f4bf 990 case INDEX_op_ext32u_i64:
4f2331e5 991 case INDEX_op_extu_i32_i64:
65089889 992 tci_args_rr(insn, &r0, &r1);
fc4a62f6 993 regs[r0] = (uint32_t)regs[r1];
7657f4bf 994 break;
7657f4bf
SW
995#if TCG_TARGET_HAS_bswap64_i64
996 case INDEX_op_bswap64_i64:
65089889 997 tci_args_rr(insn, &r0, &r1);
fc4a62f6 998 regs[r0] = bswap64(regs[r1]);
7657f4bf
SW
999 break;
1000#endif
7657f4bf
SW
1001#endif /* TCG_TARGET_REG_BITS == 64 */
1002
1003 /* QEMU specific operations. */
1004
7657f4bf 1005 case INDEX_op_exit_tb:
65089889 1006 tci_args_l(insn, tb_ptr, &ptr);
158d3873
RH
1007 return (uintptr_t)ptr;
1008
7657f4bf 1009 case INDEX_op_goto_tb:
65089889 1010 tci_args_l(insn, tb_ptr, &ptr);
1670a2b9 1011 tb_ptr = *(void **)ptr;
92bc4fad 1012 break;
1670a2b9 1013
6eea0434
RH
1014 case INDEX_op_goto_ptr:
1015 tci_args_r(insn, &r0);
1016 ptr = (void *)regs[r0];
1017 if (!ptr) {
1018 return 0;
1019 }
1020 tb_ptr = ptr;
1021 break;
1022
76782fab 1023 case INDEX_op_qemu_ld_i32:
63041ed2 1024 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
65089889 1025 tci_args_rrm(insn, &r0, &r1, &oi);
63041ed2
RH
1026 taddr = regs[r1];
1027 } else {
65089889 1028 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
63041ed2
RH
1029 taddr = tci_uint64(regs[r2], regs[r1]);
1030 }
69acc02a 1031 tmp32 = tci_qemu_ld(env, taddr, oi, tb_ptr);
63041ed2 1032 regs[r0] = tmp32;
7657f4bf 1033 break;
63041ed2 1034
76782fab 1035 case INDEX_op_qemu_ld_i64:
63041ed2 1036 if (TCG_TARGET_REG_BITS == 64) {
65089889 1037 tci_args_rrm(insn, &r0, &r1, &oi);
63041ed2
RH
1038 taddr = regs[r1];
1039 } else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
65089889 1040 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
63041ed2
RH
1041 taddr = regs[r2];
1042 } else {
65089889 1043 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
63041ed2 1044 taddr = tci_uint64(regs[r3], regs[r2]);
65089889 1045 oi = regs[r4];
76782fab 1046 }
69acc02a 1047 tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
76782fab 1048 if (TCG_TARGET_REG_BITS == 32) {
63041ed2
RH
1049 tci_write_reg64(regs, r1, r0, tmp64);
1050 } else {
1051 regs[r0] = tmp64;
76782fab 1052 }
7657f4bf 1053 break;
63041ed2 1054
76782fab 1055 case INDEX_op_qemu_st_i32:
63041ed2 1056 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
65089889 1057 tci_args_rrm(insn, &r0, &r1, &oi);
63041ed2
RH
1058 taddr = regs[r1];
1059 } else {
65089889 1060 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
63041ed2
RH
1061 taddr = tci_uint64(regs[r2], regs[r1]);
1062 }
1063 tmp32 = regs[r0];
69acc02a 1064 tci_qemu_st(env, taddr, tmp32, oi, tb_ptr);
7657f4bf 1065 break;
63041ed2 1066
76782fab 1067 case INDEX_op_qemu_st_i64:
63041ed2 1068 if (TCG_TARGET_REG_BITS == 64) {
65089889 1069 tci_args_rrm(insn, &r0, &r1, &oi);
63041ed2
RH
1070 taddr = regs[r1];
1071 tmp64 = regs[r0];
1072 } else {
1073 if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
65089889 1074 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
63041ed2
RH
1075 taddr = regs[r2];
1076 } else {
65089889 1077 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
63041ed2 1078 taddr = tci_uint64(regs[r3], regs[r2]);
65089889 1079 oi = regs[r4];
63041ed2
RH
1080 }
1081 tmp64 = tci_uint64(regs[r1], regs[r0]);
1082 }
69acc02a 1083 tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
7657f4bf 1084 break;
63041ed2 1085
a1e69e2f
PK
1086 case INDEX_op_mb:
1087 /* Ensure ordering for all kinds */
1088 smp_mb();
1089 break;
7657f4bf 1090 default:
f6996f99 1091 g_assert_not_reached();
7657f4bf 1092 }
7657f4bf 1093 }
7657f4bf 1094}
59964b4f
RH
1095
1096/*
1097 * Disassembler that matches the interpreter
1098 */
1099
1100static const char *str_r(TCGReg r)
1101{
1102 static const char regs[TCG_TARGET_NB_REGS][4] = {
1103 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1104 "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
1105 };
1106
1107 QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
1108 QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
1109
1110 assert((unsigned)r < TCG_TARGET_NB_REGS);
1111 return regs[r];
1112}
1113
1114static const char *str_c(TCGCond c)
1115{
1116 static const char cond[16][8] = {
1117 [TCG_COND_NEVER] = "never",
1118 [TCG_COND_ALWAYS] = "always",
1119 [TCG_COND_EQ] = "eq",
1120 [TCG_COND_NE] = "ne",
1121 [TCG_COND_LT] = "lt",
1122 [TCG_COND_GE] = "ge",
1123 [TCG_COND_LE] = "le",
1124 [TCG_COND_GT] = "gt",
1125 [TCG_COND_LTU] = "ltu",
1126 [TCG_COND_GEU] = "geu",
1127 [TCG_COND_LEU] = "leu",
1128 [TCG_COND_GTU] = "gtu",
1129 };
1130
1131 assert((unsigned)c < ARRAY_SIZE(cond));
1132 assert(cond[c][0] != 0);
1133 return cond[c];
1134}
1135
1136/* Disassemble TCI bytecode. */
1137int print_insn_tci(bfd_vma addr, disassemble_info *info)
1138{
65089889 1139 const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
59964b4f
RH
1140 const TCGOpDef *def;
1141 const char *op_name;
65089889 1142 uint32_t insn;
59964b4f 1143 TCGOpcode op;
08096b1a 1144 TCGReg r0, r1, r2, r3, r4, r5;
59964b4f
RH
1145 tcg_target_ulong i1;
1146 int32_t s2;
1147 TCGCond c;
1148 TCGMemOpIdx oi;
1149 uint8_t pos, len;
65089889 1150 void *ptr;
59964b4f 1151
65089889
RH
1152 /* TCI is always the host, so we don't need to load indirect. */
1153 insn = *tb_ptr++;
59964b4f 1154
65089889 1155 info->fprintf_func(info->stream, "%08x ", insn);
59964b4f 1156
65089889 1157 op = extract32(insn, 0, 8);
59964b4f
RH
1158 def = &tcg_op_defs[op];
1159 op_name = def->name;
59964b4f
RH
1160
1161 switch (op) {
1162 case INDEX_op_br:
59964b4f
RH
1163 case INDEX_op_exit_tb:
1164 case INDEX_op_goto_tb:
65089889 1165 tci_args_l(insn, tb_ptr, &ptr);
59964b4f
RH
1166 info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
1167 break;
1168
6eea0434
RH
1169 case INDEX_op_goto_ptr:
1170 tci_args_r(insn, &r0);
1171 info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0));
1172 break;
1173
7b7d8b2d 1174 case INDEX_op_call:
65089889
RH
1175 tci_args_nl(insn, tb_ptr, &len, &ptr);
1176 info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
7b7d8b2d
RH
1177 break;
1178
59964b4f
RH
1179 case INDEX_op_brcond_i32:
1180 case INDEX_op_brcond_i64:
65089889 1181 tci_args_rl(insn, tb_ptr, &r0, &ptr);
fc8ec9e1
RH
1182 info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
1183 op_name, str_r(r0), ptr);
59964b4f
RH
1184 break;
1185
1186 case INDEX_op_setcond_i32:
1187 case INDEX_op_setcond_i64:
65089889 1188 tci_args_rrrc(insn, &r0, &r1, &r2, &c);
59964b4f
RH
1189 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1190 op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1191 break;
1192
65089889
RH
1193 case INDEX_op_tci_movi:
1194 tci_args_ri(insn, &r0, &i1);
59964b4f
RH
1195 info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1196 op_name, str_r(r0), i1);
1197 break;
1198
65089889
RH
1199 case INDEX_op_tci_movl:
1200 tci_args_rl(insn, tb_ptr, &r0, &ptr);
1201 info->fprintf_func(info->stream, "%-12s %s, %p",
1202 op_name, str_r(r0), ptr);
59964b4f 1203 break;
59964b4f
RH
1204
1205 case INDEX_op_ld8u_i32:
1206 case INDEX_op_ld8u_i64:
1207 case INDEX_op_ld8s_i32:
1208 case INDEX_op_ld8s_i64:
1209 case INDEX_op_ld16u_i32:
1210 case INDEX_op_ld16u_i64:
1211 case INDEX_op_ld16s_i32:
1212 case INDEX_op_ld16s_i64:
1213 case INDEX_op_ld32u_i64:
1214 case INDEX_op_ld32s_i64:
1215 case INDEX_op_ld_i32:
1216 case INDEX_op_ld_i64:
1217 case INDEX_op_st8_i32:
1218 case INDEX_op_st8_i64:
1219 case INDEX_op_st16_i32:
1220 case INDEX_op_st16_i64:
1221 case INDEX_op_st32_i64:
1222 case INDEX_op_st_i32:
1223 case INDEX_op_st_i64:
65089889 1224 tci_args_rrs(insn, &r0, &r1, &s2);
59964b4f
RH
1225 info->fprintf_func(info->stream, "%-12s %s, %s, %d",
1226 op_name, str_r(r0), str_r(r1), s2);
1227 break;
1228
1229 case INDEX_op_mov_i32:
1230 case INDEX_op_mov_i64:
1231 case INDEX_op_ext8s_i32:
1232 case INDEX_op_ext8s_i64:
1233 case INDEX_op_ext8u_i32:
1234 case INDEX_op_ext8u_i64:
1235 case INDEX_op_ext16s_i32:
1236 case INDEX_op_ext16s_i64:
1237 case INDEX_op_ext16u_i32:
1238 case INDEX_op_ext32s_i64:
1239 case INDEX_op_ext32u_i64:
1240 case INDEX_op_ext_i32_i64:
1241 case INDEX_op_extu_i32_i64:
1242 case INDEX_op_bswap16_i32:
1243 case INDEX_op_bswap16_i64:
1244 case INDEX_op_bswap32_i32:
1245 case INDEX_op_bswap32_i64:
1246 case INDEX_op_bswap64_i64:
1247 case INDEX_op_not_i32:
1248 case INDEX_op_not_i64:
1249 case INDEX_op_neg_i32:
1250 case INDEX_op_neg_i64:
5255f48c
RH
1251 case INDEX_op_ctpop_i32:
1252 case INDEX_op_ctpop_i64:
65089889 1253 tci_args_rr(insn, &r0, &r1);
59964b4f
RH
1254 info->fprintf_func(info->stream, "%-12s %s, %s",
1255 op_name, str_r(r0), str_r(r1));
1256 break;
1257
1258 case INDEX_op_add_i32:
1259 case INDEX_op_add_i64:
1260 case INDEX_op_sub_i32:
1261 case INDEX_op_sub_i64:
1262 case INDEX_op_mul_i32:
1263 case INDEX_op_mul_i64:
1264 case INDEX_op_and_i32:
1265 case INDEX_op_and_i64:
1266 case INDEX_op_or_i32:
1267 case INDEX_op_or_i64:
1268 case INDEX_op_xor_i32:
1269 case INDEX_op_xor_i64:
a81520b9
RH
1270 case INDEX_op_andc_i32:
1271 case INDEX_op_andc_i64:
1272 case INDEX_op_orc_i32:
1273 case INDEX_op_orc_i64:
1274 case INDEX_op_eqv_i32:
1275 case INDEX_op_eqv_i64:
1276 case INDEX_op_nand_i32:
1277 case INDEX_op_nand_i64:
1278 case INDEX_op_nor_i32:
1279 case INDEX_op_nor_i64:
59964b4f
RH
1280 case INDEX_op_div_i32:
1281 case INDEX_op_div_i64:
1282 case INDEX_op_rem_i32:
1283 case INDEX_op_rem_i64:
1284 case INDEX_op_divu_i32:
1285 case INDEX_op_divu_i64:
1286 case INDEX_op_remu_i32:
1287 case INDEX_op_remu_i64:
1288 case INDEX_op_shl_i32:
1289 case INDEX_op_shl_i64:
1290 case INDEX_op_shr_i32:
1291 case INDEX_op_shr_i64:
1292 case INDEX_op_sar_i32:
1293 case INDEX_op_sar_i64:
1294 case INDEX_op_rotl_i32:
1295 case INDEX_op_rotl_i64:
1296 case INDEX_op_rotr_i32:
1297 case INDEX_op_rotr_i64:
5255f48c
RH
1298 case INDEX_op_clz_i32:
1299 case INDEX_op_clz_i64:
1300 case INDEX_op_ctz_i32:
1301 case INDEX_op_ctz_i64:
65089889 1302 tci_args_rrr(insn, &r0, &r1, &r2);
59964b4f
RH
1303 info->fprintf_func(info->stream, "%-12s %s, %s, %s",
1304 op_name, str_r(r0), str_r(r1), str_r(r2));
1305 break;
1306
1307 case INDEX_op_deposit_i32:
1308 case INDEX_op_deposit_i64:
65089889 1309 tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
59964b4f
RH
1310 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
1311 op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1312 break;
1313
0f10d7c5
RH
1314 case INDEX_op_extract_i32:
1315 case INDEX_op_extract_i64:
1316 case INDEX_op_sextract_i32:
1317 case INDEX_op_sextract_i64:
1318 tci_args_rrbb(insn, &r0, &r1, &pos, &len);
1319 info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d",
1320 op_name, str_r(r0), str_r(r1), pos, len);
1321 break;
1322
df093c19
RH
1323 case INDEX_op_movcond_i32:
1324 case INDEX_op_movcond_i64:
59964b4f 1325 case INDEX_op_setcond2_i32:
65089889 1326 tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
59964b4f
RH
1327 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1328 op_name, str_r(r0), str_r(r1), str_r(r2),
1329 str_r(r3), str_r(r4), str_c(c));
1330 break;
1331
59964b4f 1332 case INDEX_op_mulu2_i32:
f6db0d8d
RH
1333 case INDEX_op_mulu2_i64:
1334 case INDEX_op_muls2_i32:
1335 case INDEX_op_muls2_i64:
65089889 1336 tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
59964b4f
RH
1337 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1338 op_name, str_r(r0), str_r(r1),
1339 str_r(r2), str_r(r3));
1340 break;
1341
1342 case INDEX_op_add2_i32:
08096b1a 1343 case INDEX_op_add2_i64:
59964b4f 1344 case INDEX_op_sub2_i32:
08096b1a 1345 case INDEX_op_sub2_i64:
65089889 1346 tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
59964b4f
RH
1347 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1348 op_name, str_r(r0), str_r(r1), str_r(r2),
1349 str_r(r3), str_r(r4), str_r(r5));
1350 break;
59964b4f
RH
1351
1352 case INDEX_op_qemu_ld_i64:
1353 case INDEX_op_qemu_st_i64:
1354 len = DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1355 goto do_qemu_ldst;
1356 case INDEX_op_qemu_ld_i32:
1357 case INDEX_op_qemu_st_i32:
1358 len = 1;
1359 do_qemu_ldst:
1360 len += DIV_ROUND_UP(TARGET_LONG_BITS, TCG_TARGET_REG_BITS);
1361 switch (len) {
1362 case 2:
65089889 1363 tci_args_rrm(insn, &r0, &r1, &oi);
59964b4f
RH
1364 info->fprintf_func(info->stream, "%-12s %s, %s, %x",
1365 op_name, str_r(r0), str_r(r1), oi);
1366 break;
1367 case 3:
65089889 1368 tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
59964b4f
RH
1369 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %x",
1370 op_name, str_r(r0), str_r(r1), str_r(r2), oi);
1371 break;
1372 case 4:
65089889
RH
1373 tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1374 info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
59964b4f 1375 op_name, str_r(r0), str_r(r1),
65089889 1376 str_r(r2), str_r(r3), str_r(r4));
59964b4f
RH
1377 break;
1378 default:
1379 g_assert_not_reached();
1380 }
1381 break;
1382
65089889
RH
1383 case 0:
1384 /* tcg_out_nop_fill uses zeros */
1385 if (insn == 0) {
1386 info->fprintf_func(info->stream, "align");
1387 break;
1388 }
1389 /* fall through */
1390
59964b4f
RH
1391 default:
1392 info->fprintf_func(info->stream, "illegal opcode %d", op);
1393 break;
1394 }
1395
65089889 1396 return sizeof(insn);
59964b4f 1397}