]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/tcg.c
tcg: Pass TCGHelperInfo to tcg_gen_callN
[mirror_qemu.git] / tcg / tcg.c
CommitLineData
c896fe29
FB
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
757e725b 25#include "qemu/osdep.h"
cca82982 26
813da627
RH
27/* Define to jump the ELF file used to communicate with GDB. */
28#undef DEBUG_JIT
29
72fd2efb 30#include "qemu/error-report.h"
f348b6d1 31#include "qemu/cutils.h"
1de7afc9 32#include "qemu/host-utils.h"
d4c51a0a 33#include "qemu/qemu-print.h"
084cfca1 34#include "qemu/cacheflush.h"
ad768e6f 35#include "qemu/cacheinfo.h"
533206f0 36#include "qemu/timer.h"
c896fe29 37
c5d3c498 38/* Note: the long term plan is to reduce the dependencies on the QEMU
c896fe29
FB
39 CPU definitions. Currently they are used for qemu_ld/st
40 instructions */
41#define NO_CPU_IO_DEFS
c896fe29 42
63c91552 43#include "exec/exec-all.h"
d0a9bb5e 44#include "exec/tlb-common.h"
ad3d0e4d 45#include "tcg/tcg-op-common.h"
813da627 46
edee2579 47#if UINTPTR_MAX == UINT32_MAX
813da627 48# define ELF_CLASS ELFCLASS32
edee2579
RH
49#else
50# define ELF_CLASS ELFCLASS64
813da627 51#endif
e03b5686 52#if HOST_BIG_ENDIAN
813da627
RH
53# define ELF_DATA ELFDATA2MSB
54#else
55# define ELF_DATA ELFDATA2LSB
56#endif
57
c896fe29 58#include "elf.h"
508127e2 59#include "exec/log.h"
d2ba8026 60#include "tcg/tcg-ldst.h"
47f7313d 61#include "tcg/tcg-temp-internal.h"
5ff7258c 62#include "tcg-internal.h"
5584e2db 63#include "accel/tcg/perf.h"
7d478306
RH
64#ifdef CONFIG_USER_ONLY
65#include "exec/user/guest-base.h"
66#endif
c896fe29 67
139c1837 68/* Forward declarations for functions declared in tcg-target.c.inc and
ce151109 69 used here. */
e4d58b41
RH
70static void tcg_target_init(TCGContext *s);
71static void tcg_target_qemu_prologue(TCGContext *s);
6ac17786 72static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
2ba7fae2 73 intptr_t value, intptr_t addend);
c896fe29 74
497a22eb
RH
75/* The CIE and FDE header definitions will be common to all hosts. */
76typedef struct {
77 uint32_t len __attribute__((aligned((sizeof(void *)))));
78 uint32_t id;
79 uint8_t version;
80 char augmentation[1];
81 uint8_t code_align;
82 uint8_t data_align;
83 uint8_t return_column;
84} DebugFrameCIE;
85
86typedef struct QEMU_PACKED {
87 uint32_t len __attribute__((aligned((sizeof(void *)))));
88 uint32_t cie_offset;
edee2579
RH
89 uintptr_t func_start;
90 uintptr_t func_len;
497a22eb
RH
91} DebugFrameFDEHeader;
92
2c90784a
RH
93typedef struct QEMU_PACKED {
94 DebugFrameCIE cie;
95 DebugFrameFDEHeader fde;
96} DebugFrameHeader;
97
2528f771
RH
98typedef struct TCGLabelQemuLdst {
99 bool is_ld; /* qemu_ld: true, qemu_st: false */
100 MemOpIdx oi;
101 TCGType type; /* result type of a load */
102 TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */
103 TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */
104 TCGReg datalo_reg; /* reg index for low word to be loaded or stored */
105 TCGReg datahi_reg; /* reg index for high word to be loaded or stored */
106 const tcg_insn_unit *raddr; /* addr of the next IR of qemu_ld/st IR */
107 tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */
108 QSIMPLEQ_ENTRY(TCGLabelQemuLdst) next;
109} TCGLabelQemuLdst;
110
755bf9e5 111static void tcg_register_jit_int(const void *buf, size_t size,
2c90784a
RH
112 const void *debug_frame,
113 size_t debug_frame_size)
813da627
RH
114 __attribute__((unused));
115
139c1837 116/* Forward declarations for functions declared and used in tcg-target.c.inc. */
2a534aff 117static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
a05b5b9b 118 intptr_t arg2);
78113e83 119static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
c0ad3001 120static void tcg_out_movi(TCGContext *s, TCGType type,
2a534aff 121 TCGReg ret, tcg_target_long arg);
678155b2 122static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
753e42ea 123static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
d0e66c89 124static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
379afdff 125static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
52bf3398 126static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
9ecf5f61 127static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg);
9c6aa274 128static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
b9bfe000 129static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
b8b94ac6 130static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg);
313bdea8 131static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
129f1f9e 132static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2);
b55a8d9d 133static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
cf7d6b8e 134static void tcg_out_goto_tb(TCGContext *s, int which);
5e8892db
MR
135static void tcg_out_op(TCGContext *s, TCGOpcode opc,
136 const TCGArg args[TCG_MAX_OP_ARGS],
137 const int const_args[TCG_MAX_OP_ARGS]);
d2fd745f 138#if TCG_TARGET_MAYBE_vec
e7632cfa
RH
139static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
140 TCGReg dst, TCGReg src);
d6ecb4a9
RH
141static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
142 TCGReg dst, TCGReg base, intptr_t offset);
4e186175
RH
143static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
144 TCGReg dst, int64_t arg);
5e8892db
MR
145static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
146 unsigned vecl, unsigned vece,
147 const TCGArg args[TCG_MAX_OP_ARGS],
148 const int const_args[TCG_MAX_OP_ARGS]);
d2fd745f 149#else
e7632cfa
RH
150static inline bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
151 TCGReg dst, TCGReg src)
152{
153 g_assert_not_reached();
154}
d6ecb4a9
RH
155static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
156 TCGReg dst, TCGReg base, intptr_t offset)
157{
158 g_assert_not_reached();
159}
4e186175
RH
160static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
161 TCGReg dst, int64_t arg)
e7632cfa
RH
162{
163 g_assert_not_reached();
164}
5e8892db
MR
165static inline void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
166 unsigned vecl, unsigned vece,
167 const TCGArg args[TCG_MAX_OP_ARGS],
168 const int const_args[TCG_MAX_OP_ARGS])
d2fd745f
RH
169{
170 g_assert_not_reached();
171}
172#endif
2a534aff 173static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
a05b5b9b 174 intptr_t arg2);
59d7c14e
RH
175static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
176 TCGReg base, intptr_t ofs);
7b7d8b2d 177static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
cee44b03 178 const TCGHelperInfo *info);
5e3d0c19 179static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot);
a4fbbd77 180static bool tcg_target_const_match(int64_t val, TCGType type, int ct);
659ef5cb 181#ifdef TCG_TARGET_NEED_LDST_LABELS
aeee05f5 182static int tcg_out_ldst_finalize(TCGContext *s);
659ef5cb 183#endif
c896fe29 184
8429a1ca
RH
185typedef struct TCGLdstHelperParam {
186 TCGReg (*ra_gen)(TCGContext *s, const TCGLabelQemuLdst *l, int arg_reg);
187 unsigned ntmp;
188 int tmp[3];
189} TCGLdstHelperParam;
190
191static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *l,
192 const TCGLdstHelperParam *p)
193 __attribute__((unused));
194static void tcg_out_ld_helper_ret(TCGContext *s, const TCGLabelQemuLdst *l,
195 bool load_sign, const TCGLdstHelperParam *p)
196 __attribute__((unused));
197static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *l,
198 const TCGLdstHelperParam *p)
199 __attribute__((unused));
200
de95016d 201static void * const qemu_ld_helpers[MO_SSIZE + 1] __attribute__((unused)) = {
0cadc1ed
RH
202 [MO_UB] = helper_ldub_mmu,
203 [MO_SB] = helper_ldsb_mmu,
204 [MO_UW] = helper_lduw_mmu,
205 [MO_SW] = helper_ldsw_mmu,
206 [MO_UL] = helper_ldul_mmu,
207 [MO_UQ] = helper_ldq_mmu,
208#if TCG_TARGET_REG_BITS == 64
209 [MO_SL] = helper_ldsl_mmu,
ebebea53 210 [MO_128] = helper_ld16_mmu,
0cadc1ed
RH
211#endif
212};
213
de95016d 214static void * const qemu_st_helpers[MO_SIZE + 1] __attribute__((unused)) = {
0cadc1ed
RH
215 [MO_8] = helper_stb_mmu,
216 [MO_16] = helper_stw_mmu,
217 [MO_32] = helper_stl_mmu,
218 [MO_64] = helper_stq_mmu,
ebebea53
RH
219#if TCG_TARGET_REG_BITS == 64
220 [MO_128] = helper_st16_mmu,
221#endif
0cadc1ed 222};
0cadc1ed 223
e63b8a29
RH
224typedef struct {
225 MemOp atom; /* lg2 bits of atomicity required */
226 MemOp align; /* lg2 bits of alignment to use */
227} TCGAtomAlign;
228
229static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc,
230 MemOp host_atom, bool allow_two_ops)
231 __attribute__((unused));
232
42eb6dfc
RH
233TCGContext tcg_init_ctx;
234__thread TCGContext *tcg_ctx;
235
5ff7258c 236TCGContext **tcg_ctxs;
0e2d61cf
RH
237unsigned int tcg_cur_ctxs;
238unsigned int tcg_max_ctxs;
1c2adb95 239TCGv_env cpu_env = 0;
c8bc1168 240const void *tcg_code_gen_epilogue;
db0c51a3 241uintptr_t tcg_splitwx_diff;
df2cce29 242
b91ccb31
RH
243#ifndef CONFIG_TCG_INTERPRETER
244tcg_prologue_fn *tcg_qemu_tb_exec;
245#endif
246
d2fd745f 247static TCGRegSet tcg_target_available_regs[TCG_TYPE_COUNT];
b1d8e52e 248static TCGRegSet tcg_target_call_clobber_regs;
c896fe29 249
1813e175 250#if TCG_TARGET_INSN_UNIT_SIZE == 1
4196dca6 251static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
c896fe29
FB
252{
253 *s->code_ptr++ = v;
254}
255
4196dca6
PM
256static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
257 uint8_t v)
5c53bb81 258{
1813e175 259 *p = v;
5c53bb81 260}
1813e175 261#endif
5c53bb81 262
1813e175 263#if TCG_TARGET_INSN_UNIT_SIZE <= 2
4196dca6 264static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
c896fe29 265{
1813e175
RH
266 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
267 *s->code_ptr++ = v;
268 } else {
269 tcg_insn_unit *p = s->code_ptr;
270 memcpy(p, &v, sizeof(v));
271 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
272 }
c896fe29
FB
273}
274
4196dca6
PM
275static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
276 uint16_t v)
5c53bb81 277{
1813e175
RH
278 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
279 *p = v;
280 } else {
281 memcpy(p, &v, sizeof(v));
282 }
5c53bb81 283}
1813e175 284#endif
5c53bb81 285
1813e175 286#if TCG_TARGET_INSN_UNIT_SIZE <= 4
4196dca6 287static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
c896fe29 288{
1813e175
RH
289 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
290 *s->code_ptr++ = v;
291 } else {
292 tcg_insn_unit *p = s->code_ptr;
293 memcpy(p, &v, sizeof(v));
294 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
295 }
c896fe29
FB
296}
297
4196dca6
PM
298static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
299 uint32_t v)
5c53bb81 300{
1813e175
RH
301 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
302 *p = v;
303 } else {
304 memcpy(p, &v, sizeof(v));
305 }
5c53bb81 306}
1813e175 307#endif
5c53bb81 308
1813e175 309#if TCG_TARGET_INSN_UNIT_SIZE <= 8
4196dca6 310static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
ac26eb69 311{
1813e175
RH
312 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
313 *s->code_ptr++ = v;
314 } else {
315 tcg_insn_unit *p = s->code_ptr;
316 memcpy(p, &v, sizeof(v));
317 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
318 }
ac26eb69
RH
319}
320
4196dca6
PM
321static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
322 uint64_t v)
5c53bb81 323{
1813e175
RH
324 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
325 *p = v;
326 } else {
327 memcpy(p, &v, sizeof(v));
328 }
5c53bb81 329}
1813e175 330#endif
5c53bb81 331
c896fe29
FB
332/* label relocation processing */
333
1813e175 334static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
bec16311 335 TCGLabel *l, intptr_t addend)
c896fe29 336{
7ecd02a0 337 TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation));
c896fe29 338
7ecd02a0
RH
339 r->type = type;
340 r->ptr = code_ptr;
341 r->addend = addend;
342 QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
c896fe29
FB
343}
344
92ab8e7d 345static void tcg_out_label(TCGContext *s, TCGLabel *l)
c896fe29 346{
eabb7b91 347 tcg_debug_assert(!l->has_value);
c896fe29 348 l->has_value = 1;
92ab8e7d 349 l->u.value_ptr = tcg_splitwx_to_rx(s->code_ptr);
c896fe29
FB
350}
351
42a268c2 352TCGLabel *gen_new_label(void)
c896fe29 353{
b1311c4a 354 TCGContext *s = tcg_ctx;
51e3972c 355 TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
c896fe29 356
7ecd02a0
RH
357 memset(l, 0, sizeof(TCGLabel));
358 l->id = s->nb_labels++;
f85b1fc4 359 QSIMPLEQ_INIT(&l->branches);
7ecd02a0
RH
360 QSIMPLEQ_INIT(&l->relocs);
361
bef16ab4 362 QSIMPLEQ_INSERT_TAIL(&s->labels, l, next);
42a268c2
RH
363
364 return l;
c896fe29
FB
365}
366
7ecd02a0
RH
367static bool tcg_resolve_relocs(TCGContext *s)
368{
369 TCGLabel *l;
370
371 QSIMPLEQ_FOREACH(l, &s->labels, next) {
372 TCGRelocation *r;
373 uintptr_t value = l->u.value;
374
375 QSIMPLEQ_FOREACH(r, &l->relocs, next) {
376 if (!patch_reloc(r->ptr, r->type, value, r->addend)) {
377 return false;
378 }
379 }
380 }
381 return true;
382}
383
9f754620
RH
384static void set_jmp_reset_offset(TCGContext *s, int which)
385{
f14bed3f
RH
386 /*
387 * We will check for overflow at the end of the opcode loop in
388 * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
389 */
b7e4afbd 390 s->gen_tb->jmp_reset_offset[which] = tcg_current_code_size(s);
9f754620
RH
391}
392
b52a2c03
RH
393static void G_GNUC_UNUSED set_jmp_insn_offset(TCGContext *s, int which)
394{
395 /*
396 * We will check for overflow at the end of the opcode loop in
397 * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
398 */
9da6079b 399 s->gen_tb->jmp_insn_offset[which] = tcg_current_code_size(s);
b52a2c03
RH
400}
401
becc452a
RH
402static uintptr_t G_GNUC_UNUSED get_jmp_target_addr(TCGContext *s, int which)
403{
404 /*
405 * Return the read-execute version of the pointer, for the benefit
406 * of any pc-relative addressing mode.
407 */
9da6079b 408 return (uintptr_t)tcg_splitwx_to_rx(&s->gen_tb->jmp_target_addr[which]);
becc452a
RH
409}
410
d0a9bb5e
RH
411#if defined(CONFIG_SOFTMMU) && !defined(CONFIG_TCG_INTERPRETER)
412static int tlb_mask_table_ofs(TCGContext *s, int which)
413{
414 return s->tlb_fast_offset + which * sizeof(CPUTLBDescFast);
415}
416#endif
417
db6b7d0c 418/* Signal overflow, starting over with fewer guest insns. */
8905770b
MAL
419static G_NORETURN
420void tcg_raise_tb_overflow(TCGContext *s)
db6b7d0c
RH
421{
422 siglongjmp(s->jmp_trans, -2);
423}
424
8429a1ca
RH
425/*
426 * Used by tcg_out_movext{1,2} to hold the arguments for tcg_out_movext.
427 * By the time we arrive at tcg_out_movext1, @dst is always a TCGReg.
428 *
429 * However, tcg_out_helper_load_slots reuses this field to hold an
430 * argument slot number (which may designate a argument register or an
431 * argument stack slot), converting to TCGReg once all arguments that
432 * are destined for the stack are processed.
433 */
129f1f9e 434typedef struct TCGMovExtend {
8429a1ca 435 unsigned dst;
129f1f9e
RH
436 TCGReg src;
437 TCGType dst_type;
438 TCGType src_type;
439 MemOp src_ext;
440} TCGMovExtend;
441
b3dfd5fc
RH
442/**
443 * tcg_out_movext -- move and extend
444 * @s: tcg context
445 * @dst_type: integral type for destination
446 * @dst: destination register
447 * @src_type: integral type for source
448 * @src_ext: extension to apply to source
449 * @src: source register
450 *
451 * Move or extend @src into @dst, depending on @src_ext and the types.
452 */
129f1f9e
RH
453static void tcg_out_movext(TCGContext *s, TCGType dst_type, TCGReg dst,
454 TCGType src_type, MemOp src_ext, TCGReg src)
b3dfd5fc
RH
455{
456 switch (src_ext) {
457 case MO_UB:
458 tcg_out_ext8u(s, dst, src);
459 break;
460 case MO_SB:
461 tcg_out_ext8s(s, dst_type, dst, src);
462 break;
463 case MO_UW:
464 tcg_out_ext16u(s, dst, src);
465 break;
466 case MO_SW:
467 tcg_out_ext16s(s, dst_type, dst, src);
468 break;
469 case MO_UL:
470 case MO_SL:
471 if (dst_type == TCG_TYPE_I32) {
472 if (src_type == TCG_TYPE_I32) {
473 tcg_out_mov(s, TCG_TYPE_I32, dst, src);
474 } else {
475 tcg_out_extrl_i64_i32(s, dst, src);
476 }
477 } else if (src_type == TCG_TYPE_I32) {
478 if (src_ext & MO_SIGN) {
479 tcg_out_exts_i32_i64(s, dst, src);
480 } else {
481 tcg_out_extu_i32_i64(s, dst, src);
482 }
483 } else {
484 if (src_ext & MO_SIGN) {
485 tcg_out_ext32s(s, dst, src);
486 } else {
487 tcg_out_ext32u(s, dst, src);
488 }
489 }
490 break;
491 case MO_UQ:
492 tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
493 if (dst_type == TCG_TYPE_I32) {
494 tcg_out_extrl_i64_i32(s, dst, src);
495 } else {
496 tcg_out_mov(s, TCG_TYPE_I64, dst, src);
497 }
498 break;
499 default:
500 g_assert_not_reached();
501 }
502}
503
129f1f9e
RH
504/* Minor variations on a theme, using a structure. */
505static void tcg_out_movext1_new_src(TCGContext *s, const TCGMovExtend *i,
506 TCGReg src)
507{
508 tcg_out_movext(s, i->dst_type, i->dst, i->src_type, i->src_ext, src);
509}
510
511static void tcg_out_movext1(TCGContext *s, const TCGMovExtend *i)
512{
513 tcg_out_movext1_new_src(s, i, i->src);
514}
515
516/**
517 * tcg_out_movext2 -- move and extend two pair
518 * @s: tcg context
519 * @i1: first move description
520 * @i2: second move description
521 * @scratch: temporary register, or -1 for none
522 *
523 * As tcg_out_movext, for both @i1 and @i2, caring for overlap
524 * between the sources and destinations.
525 */
526
8429a1ca
RH
527static void tcg_out_movext2(TCGContext *s, const TCGMovExtend *i1,
528 const TCGMovExtend *i2, int scratch)
129f1f9e
RH
529{
530 TCGReg src1 = i1->src;
531 TCGReg src2 = i2->src;
532
533 if (i1->dst != src2) {
534 tcg_out_movext1(s, i1);
535 tcg_out_movext1(s, i2);
536 return;
537 }
538 if (i2->dst == src1) {
539 TCGType src1_type = i1->src_type;
540 TCGType src2_type = i2->src_type;
541
542 if (tcg_out_xchg(s, MAX(src1_type, src2_type), src1, src2)) {
543 /* The data is now in the correct registers, now extend. */
544 src1 = i2->src;
545 src2 = i1->src;
546 } else {
547 tcg_debug_assert(scratch >= 0);
548 tcg_out_mov(s, src1_type, scratch, src1);
549 src1 = scratch;
550 }
551 }
552 tcg_out_movext1_new_src(s, i2, src2);
553 tcg_out_movext1_new_src(s, i1, src1);
554}
555
2462e30e
RH
556/**
557 * tcg_out_movext3 -- move and extend three pair
558 * @s: tcg context
559 * @i1: first move description
560 * @i2: second move description
561 * @i3: third move description
562 * @scratch: temporary register, or -1 for none
563 *
564 * As tcg_out_movext, for all of @i1, @i2 and @i3, caring for overlap
565 * between the sources and destinations.
566 */
567
568static void tcg_out_movext3(TCGContext *s, const TCGMovExtend *i1,
569 const TCGMovExtend *i2, const TCGMovExtend *i3,
570 int scratch)
571{
572 TCGReg src1 = i1->src;
573 TCGReg src2 = i2->src;
574 TCGReg src3 = i3->src;
575
576 if (i1->dst != src2 && i1->dst != src3) {
577 tcg_out_movext1(s, i1);
578 tcg_out_movext2(s, i2, i3, scratch);
579 return;
580 }
581 if (i2->dst != src1 && i2->dst != src3) {
582 tcg_out_movext1(s, i2);
583 tcg_out_movext2(s, i1, i3, scratch);
584 return;
585 }
586 if (i3->dst != src1 && i3->dst != src2) {
587 tcg_out_movext1(s, i3);
588 tcg_out_movext2(s, i1, i2, scratch);
589 return;
590 }
591
592 /*
593 * There is a cycle. Since there are only 3 nodes, the cycle is
594 * either "clockwise" or "anti-clockwise", and can be solved with
595 * a single scratch or two xchg.
596 */
597 if (i1->dst == src2 && i2->dst == src3 && i3->dst == src1) {
598 /* "Clockwise" */
599 if (tcg_out_xchg(s, MAX(i1->src_type, i2->src_type), src1, src2)) {
600 tcg_out_xchg(s, MAX(i2->src_type, i3->src_type), src2, src3);
601 /* The data is now in the correct registers, now extend. */
602 tcg_out_movext1_new_src(s, i1, i1->dst);
603 tcg_out_movext1_new_src(s, i2, i2->dst);
604 tcg_out_movext1_new_src(s, i3, i3->dst);
605 } else {
606 tcg_debug_assert(scratch >= 0);
607 tcg_out_mov(s, i1->src_type, scratch, src1);
608 tcg_out_movext1(s, i3);
609 tcg_out_movext1(s, i2);
610 tcg_out_movext1_new_src(s, i1, scratch);
611 }
612 } else if (i1->dst == src3 && i2->dst == src1 && i3->dst == src2) {
613 /* "Anti-clockwise" */
614 if (tcg_out_xchg(s, MAX(i2->src_type, i3->src_type), src2, src3)) {
615 tcg_out_xchg(s, MAX(i1->src_type, i2->src_type), src1, src2);
616 /* The data is now in the correct registers, now extend. */
617 tcg_out_movext1_new_src(s, i1, i1->dst);
618 tcg_out_movext1_new_src(s, i2, i2->dst);
619 tcg_out_movext1_new_src(s, i3, i3->dst);
620 } else {
621 tcg_debug_assert(scratch >= 0);
622 tcg_out_mov(s, i1->src_type, scratch, src1);
623 tcg_out_movext1(s, i2);
624 tcg_out_movext1(s, i3);
625 tcg_out_movext1_new_src(s, i1, scratch);
626 }
627 } else {
628 g_assert_not_reached();
629 }
630}
631
4c22e840
RH
632#define C_PFX1(P, A) P##A
633#define C_PFX2(P, A, B) P##A##_##B
634#define C_PFX3(P, A, B, C) P##A##_##B##_##C
635#define C_PFX4(P, A, B, C, D) P##A##_##B##_##C##_##D
636#define C_PFX5(P, A, B, C, D, E) P##A##_##B##_##C##_##D##_##E
637#define C_PFX6(P, A, B, C, D, E, F) P##A##_##B##_##C##_##D##_##E##_##F
638
639/* Define an enumeration for the various combinations. */
640
641#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1),
642#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2),
643#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3),
644#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4),
645
646#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1),
647#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2),
648#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3),
649#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4),
650
651#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2),
652
653#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1),
654#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
655#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
656#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4),
657
658typedef enum {
659#include "tcg-target-con-set.h"
660} TCGConstraintSetIndex;
661
662static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
663
664#undef C_O0_I1
665#undef C_O0_I2
666#undef C_O0_I3
667#undef C_O0_I4
668#undef C_O1_I1
669#undef C_O1_I2
670#undef C_O1_I3
671#undef C_O1_I4
672#undef C_N1_I2
673#undef C_O2_I1
674#undef C_O2_I2
675#undef C_O2_I3
676#undef C_O2_I4
677
678/* Put all of the constraint sets into an array, indexed by the enum. */
679
680#define C_O0_I1(I1) { .args_ct_str = { #I1 } },
681#define C_O0_I2(I1, I2) { .args_ct_str = { #I1, #I2 } },
682#define C_O0_I3(I1, I2, I3) { .args_ct_str = { #I1, #I2, #I3 } },
683#define C_O0_I4(I1, I2, I3, I4) { .args_ct_str = { #I1, #I2, #I3, #I4 } },
684
685#define C_O1_I1(O1, I1) { .args_ct_str = { #O1, #I1 } },
686#define C_O1_I2(O1, I1, I2) { .args_ct_str = { #O1, #I1, #I2 } },
687#define C_O1_I3(O1, I1, I2, I3) { .args_ct_str = { #O1, #I1, #I2, #I3 } },
688#define C_O1_I4(O1, I1, I2, I3, I4) { .args_ct_str = { #O1, #I1, #I2, #I3, #I4 } },
689
690#define C_N1_I2(O1, I1, I2) { .args_ct_str = { "&" #O1, #I1, #I2 } },
691
692#define C_O2_I1(O1, O2, I1) { .args_ct_str = { #O1, #O2, #I1 } },
693#define C_O2_I2(O1, O2, I1, I2) { .args_ct_str = { #O1, #O2, #I1, #I2 } },
694#define C_O2_I3(O1, O2, I1, I2, I3) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3 } },
695#define C_O2_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3, #I4 } },
696
697static const TCGTargetOpDef constraint_sets[] = {
698#include "tcg-target-con-set.h"
699};
700
701
702#undef C_O0_I1
703#undef C_O0_I2
704#undef C_O0_I3
705#undef C_O0_I4
706#undef C_O1_I1
707#undef C_O1_I2
708#undef C_O1_I3
709#undef C_O1_I4
710#undef C_N1_I2
711#undef C_O2_I1
712#undef C_O2_I2
713#undef C_O2_I3
714#undef C_O2_I4
715
716/* Expand the enumerator to be returned from tcg_target_op_def(). */
717
718#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1)
719#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2)
720#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3)
721#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4)
722
723#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1)
724#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2)
725#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3)
726#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4)
727
728#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2)
729
730#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1)
731#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2)
732#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
733#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
734
139c1837 735#include "tcg-target.c.inc"
c896fe29 736
38b47b19
EC
737static void alloc_tcg_plugin_context(TCGContext *s)
738{
739#ifdef CONFIG_PLUGIN
740 s->plugin_tb = g_new0(struct qemu_plugin_tb, 1);
741 s->plugin_tb->insns =
742 g_ptr_array_new_with_free_func(qemu_plugin_insn_cleanup_fn);
743#endif
744}
745
3468b59e
EC
746/*
747 * All TCG threads except the parent (i.e. the one that called tcg_context_init
748 * and registered the target's TCG globals) must register with this function
749 * before initiating translation.
750 *
751 * In user-mode we just point tcg_ctx to tcg_init_ctx. See the documentation
752 * of tcg_region_init() for the reasoning behind this.
753 *
754 * In softmmu each caller registers its context in tcg_ctxs[]. Note that in
755 * softmmu tcg_ctxs[] does not track tcg_ctx_init, since the initial context
756 * is not used anymore for translation once this function is called.
757 *
758 * Not tracking tcg_init_ctx in tcg_ctxs[] in softmmu keeps code that iterates
759 * over the array (e.g. tcg_code_size() the same for both softmmu and user-mode.
760 */
761#ifdef CONFIG_USER_ONLY
762void tcg_register_thread(void)
763{
764 tcg_ctx = &tcg_init_ctx;
765}
766#else
767void tcg_register_thread(void)
768{
769 TCGContext *s = g_malloc(sizeof(*s));
770 unsigned int i, n;
3468b59e
EC
771
772 *s = tcg_init_ctx;
773
774 /* Relink mem_base. */
775 for (i = 0, n = tcg_init_ctx.nb_globals; i < n; ++i) {
776 if (tcg_init_ctx.temps[i].mem_base) {
777 ptrdiff_t b = tcg_init_ctx.temps[i].mem_base - tcg_init_ctx.temps;
778 tcg_debug_assert(b >= 0 && b < n);
779 s->temps[i].mem_base = &s->temps[b];
780 }
781 }
782
783 /* Claim an entry in tcg_ctxs */
0e2d61cf
RH
784 n = qatomic_fetch_inc(&tcg_cur_ctxs);
785 g_assert(n < tcg_max_ctxs);
d73415a3 786 qatomic_set(&tcg_ctxs[n], s);
3468b59e 787
38b47b19
EC
788 if (n > 0) {
789 alloc_tcg_plugin_context(s);
bf042e8e 790 tcg_region_initial_alloc(s);
38b47b19
EC
791 }
792
3468b59e 793 tcg_ctx = s;
e8feb96f 794}
3468b59e 795#endif /* !CONFIG_USER_ONLY */
e8feb96f 796
c896fe29
FB
797/* pool based memory allocation */
798void *tcg_malloc_internal(TCGContext *s, int size)
799{
800 TCGPool *p;
801 int pool_size;
a813e36f 802
c896fe29
FB
803 if (size > TCG_POOL_CHUNK_SIZE) {
804 /* big malloc: insert a new pool (XXX: could optimize) */
7267c094 805 p = g_malloc(sizeof(TCGPool) + size);
c896fe29 806 p->size = size;
4055299e
KB
807 p->next = s->pool_first_large;
808 s->pool_first_large = p;
809 return p->data;
c896fe29
FB
810 } else {
811 p = s->pool_current;
812 if (!p) {
813 p = s->pool_first;
814 if (!p)
815 goto new_pool;
816 } else {
817 if (!p->next) {
818 new_pool:
819 pool_size = TCG_POOL_CHUNK_SIZE;
7267c094 820 p = g_malloc(sizeof(TCGPool) + pool_size);
c896fe29
FB
821 p->size = pool_size;
822 p->next = NULL;
a813e36f 823 if (s->pool_current) {
c896fe29 824 s->pool_current->next = p;
a813e36f 825 } else {
c896fe29 826 s->pool_first = p;
a813e36f 827 }
c896fe29
FB
828 } else {
829 p = p->next;
830 }
831 }
832 }
833 s->pool_current = p;
834 s->pool_cur = p->data + size;
835 s->pool_end = p->data + p->size;
836 return p->data;
837}
838
839void tcg_pool_reset(TCGContext *s)
840{
4055299e
KB
841 TCGPool *p, *t;
842 for (p = s->pool_first_large; p; p = t) {
843 t = p->next;
844 g_free(p);
845 }
846 s->pool_first_large = NULL;
c896fe29
FB
847 s->pool_cur = s->pool_end = NULL;
848 s->pool_current = NULL;
849}
850
8429a1ca
RH
851/*
852 * Create TCGHelperInfo structures for "tcg/tcg-ldst.h" functions,
853 * akin to what "exec/helper-tcg.h" does with DEF_HELPER_FLAGS_N.
854 * We only use these for layout in tcg_out_ld_helper_ret and
855 * tcg_out_st_helper_args, and share them between several of
856 * the helpers, with the end result that it's easier to build manually.
857 */
858
859#if TCG_TARGET_REG_BITS == 32
860# define dh_typecode_ttl dh_typecode_i32
861#else
862# define dh_typecode_ttl dh_typecode_i64
863#endif
864
865static TCGHelperInfo info_helper_ld32_mmu = {
866 .flags = TCG_CALL_NO_WG,
867 .typemask = dh_typemask(ttl, 0) /* return tcg_target_ulong */
868 | dh_typemask(env, 1)
24e46e6c 869 | dh_typemask(i64, 2) /* uint64_t addr */
8429a1ca
RH
870 | dh_typemask(i32, 3) /* unsigned oi */
871 | dh_typemask(ptr, 4) /* uintptr_t ra */
872};
873
874static TCGHelperInfo info_helper_ld64_mmu = {
875 .flags = TCG_CALL_NO_WG,
876 .typemask = dh_typemask(i64, 0) /* return uint64_t */
877 | dh_typemask(env, 1)
24e46e6c 878 | dh_typemask(i64, 2) /* uint64_t addr */
8429a1ca
RH
879 | dh_typemask(i32, 3) /* unsigned oi */
880 | dh_typemask(ptr, 4) /* uintptr_t ra */
881};
882
ebebea53
RH
883static TCGHelperInfo info_helper_ld128_mmu = {
884 .flags = TCG_CALL_NO_WG,
885 .typemask = dh_typemask(i128, 0) /* return Int128 */
886 | dh_typemask(env, 1)
24e46e6c 887 | dh_typemask(i64, 2) /* uint64_t addr */
ebebea53
RH
888 | dh_typemask(i32, 3) /* unsigned oi */
889 | dh_typemask(ptr, 4) /* uintptr_t ra */
890};
891
8429a1ca
RH
892static TCGHelperInfo info_helper_st32_mmu = {
893 .flags = TCG_CALL_NO_WG,
894 .typemask = dh_typemask(void, 0)
895 | dh_typemask(env, 1)
24e46e6c 896 | dh_typemask(i64, 2) /* uint64_t addr */
8429a1ca
RH
897 | dh_typemask(i32, 3) /* uint32_t data */
898 | dh_typemask(i32, 4) /* unsigned oi */
899 | dh_typemask(ptr, 5) /* uintptr_t ra */
900};
901
902static TCGHelperInfo info_helper_st64_mmu = {
903 .flags = TCG_CALL_NO_WG,
904 .typemask = dh_typemask(void, 0)
905 | dh_typemask(env, 1)
24e46e6c 906 | dh_typemask(i64, 2) /* uint64_t addr */
8429a1ca
RH
907 | dh_typemask(i64, 3) /* uint64_t data */
908 | dh_typemask(i32, 4) /* unsigned oi */
909 | dh_typemask(ptr, 5) /* uintptr_t ra */
910};
911
ebebea53
RH
912static TCGHelperInfo info_helper_st128_mmu = {
913 .flags = TCG_CALL_NO_WG,
914 .typemask = dh_typemask(void, 0)
915 | dh_typemask(env, 1)
24e46e6c 916 | dh_typemask(i64, 2) /* uint64_t addr */
ebebea53
RH
917 | dh_typemask(i128, 3) /* Int128 data */
918 | dh_typemask(i32, 4) /* unsigned oi */
919 | dh_typemask(ptr, 5) /* uintptr_t ra */
920};
921
22f15579 922#ifdef CONFIG_TCG_INTERPRETER
c6ef8c7b
PMD
923static ffi_type *typecode_to_ffi(int argmask)
924{
e9709e17
RH
925 /*
926 * libffi does not support __int128_t, so we have forced Int128
927 * to use the structure definition instead of the builtin type.
928 */
929 static ffi_type *ffi_type_i128_elements[3] = {
930 &ffi_type_uint64,
931 &ffi_type_uint64,
932 NULL
933 };
934 static ffi_type ffi_type_i128 = {
935 .size = 16,
936 .alignment = __alignof__(Int128),
937 .type = FFI_TYPE_STRUCT,
938 .elements = ffi_type_i128_elements,
939 };
940
c6ef8c7b
PMD
941 switch (argmask) {
942 case dh_typecode_void:
943 return &ffi_type_void;
944 case dh_typecode_i32:
945 return &ffi_type_uint32;
946 case dh_typecode_s32:
947 return &ffi_type_sint32;
948 case dh_typecode_i64:
949 return &ffi_type_uint64;
950 case dh_typecode_s64:
951 return &ffi_type_sint64;
952 case dh_typecode_ptr:
953 return &ffi_type_pointer;
e9709e17
RH
954 case dh_typecode_i128:
955 return &ffi_type_i128;
c6ef8c7b
PMD
956 }
957 g_assert_not_reached();
958}
0c22e176 959
d53106c9 960static ffi_cif *init_ffi_layout(TCGHelperInfo *info)
0c22e176 961{
d53106c9
RH
962 unsigned typemask = info->typemask;
963 struct {
964 ffi_cif cif;
965 ffi_type *args[];
966 } *ca;
967 ffi_status status;
968 int nargs;
969
970 /* Ignoring the return type, find the last non-zero field. */
971 nargs = 32 - clz32(typemask >> 3);
972 nargs = DIV_ROUND_UP(nargs, 3);
973 assert(nargs <= MAX_CALL_IARGS);
974
975 ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
976 ca->cif.rtype = typecode_to_ffi(typemask & 7);
977 ca->cif.nargs = nargs;
978
979 if (nargs != 0) {
980 ca->cif.arg_types = ca->args;
981 for (int j = 0; j < nargs; ++j) {
982 int typecode = extract32(typemask, (j + 1) * 3, 3);
983 ca->args[j] = typecode_to_ffi(typecode);
0c22e176 984 }
0c22e176 985 }
f9c4bb80 986
d53106c9
RH
987 status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
988 ca->cif.rtype, ca->cif.arg_types);
989 assert(status == FFI_OK);
990
991 return &ca->cif;
0c22e176 992}
d53106c9
RH
993
994#define HELPER_INFO_INIT(I) (&(I)->cif)
995#define HELPER_INFO_INIT_VAL(I) init_ffi_layout(I)
996#else
997#define HELPER_INFO_INIT(I) (&(I)->init)
998#define HELPER_INFO_INIT_VAL(I) 1
0c22e176 999#endif /* CONFIG_TCG_INTERPRETER */
22f15579 1000
338b61e9
RH
1001static inline bool arg_slot_reg_p(unsigned arg_slot)
1002{
1003 /*
1004 * Split the sizeof away from the comparison to avoid Werror from
1005 * "unsigned < 0 is always false", when iarg_regs is empty.
1006 */
1007 unsigned nreg = ARRAY_SIZE(tcg_target_call_iarg_regs);
1008 return arg_slot < nreg;
1009}
1010
d78e4a4f
RH
1011static inline int arg_slot_stk_ofs(unsigned arg_slot)
1012{
1013 unsigned max = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long);
1014 unsigned stk_slot = arg_slot - ARRAY_SIZE(tcg_target_call_iarg_regs);
1015
1016 tcg_debug_assert(stk_slot < max);
1017 return TCG_TARGET_CALL_STACK_OFFSET + stk_slot * sizeof(tcg_target_long);
1018}
1019
39004a71
RH
1020typedef struct TCGCumulativeArgs {
1021 int arg_idx; /* tcg_gen_callN args[] */
1022 int info_in_idx; /* TCGHelperInfo in[] */
1023 int arg_slot; /* regs+stack slot */
1024 int ref_slot; /* stack slots for references */
1025} TCGCumulativeArgs;
1026
1027static void layout_arg_even(TCGCumulativeArgs *cum)
1028{
1029 cum->arg_slot += cum->arg_slot & 1;
1030}
1031
1032static void layout_arg_1(TCGCumulativeArgs *cum, TCGHelperInfo *info,
1033 TCGCallArgumentKind kind)
1034{
1035 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
1036
1037 *loc = (TCGCallArgumentLoc){
1038 .kind = kind,
1039 .arg_idx = cum->arg_idx,
1040 .arg_slot = cum->arg_slot,
1041 };
1042 cum->info_in_idx++;
1043 cum->arg_slot++;
1044}
1045
1046static void layout_arg_normal_n(TCGCumulativeArgs *cum,
1047 TCGHelperInfo *info, int n)
1048{
1049 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
1050
1051 for (int i = 0; i < n; ++i) {
1052 /* Layout all using the same arg_idx, adjusting the subindex. */
1053 loc[i] = (TCGCallArgumentLoc){
1054 .kind = TCG_CALL_ARG_NORMAL,
1055 .arg_idx = cum->arg_idx,
1056 .tmp_subindex = i,
1057 .arg_slot = cum->arg_slot + i,
1058 };
1059 }
1060 cum->info_in_idx += n;
1061 cum->arg_slot += n;
1062}
1063
313bdea8
RH
1064static void layout_arg_by_ref(TCGCumulativeArgs *cum, TCGHelperInfo *info)
1065{
1066 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
1067 int n = 128 / TCG_TARGET_REG_BITS;
1068
1069 /* The first subindex carries the pointer. */
1070 layout_arg_1(cum, info, TCG_CALL_ARG_BY_REF);
1071
1072 /*
1073 * The callee is allowed to clobber memory associated with
1074 * structure pass by-reference. Therefore we must make copies.
1075 * Allocate space from "ref_slot", which will be adjusted to
1076 * follow the parameters on the stack.
1077 */
1078 loc[0].ref_slot = cum->ref_slot;
1079
1080 /*
1081 * Subsequent words also go into the reference slot, but
1082 * do not accumulate into the regular arguments.
1083 */
1084 for (int i = 1; i < n; ++i) {
1085 loc[i] = (TCGCallArgumentLoc){
1086 .kind = TCG_CALL_ARG_BY_REF_N,
1087 .arg_idx = cum->arg_idx,
1088 .tmp_subindex = i,
1089 .ref_slot = cum->ref_slot + i,
1090 };
1091 }
1092 cum->info_in_idx += n;
1093 cum->ref_slot += n;
1094}
1095
39004a71
RH
1096static void init_call_layout(TCGHelperInfo *info)
1097{
1098 int max_reg_slots = ARRAY_SIZE(tcg_target_call_iarg_regs);
1099 int max_stk_slots = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long);
1100 unsigned typemask = info->typemask;
1101 unsigned typecode;
1102 TCGCumulativeArgs cum = { };
1103
1104 /*
1105 * Parse and place any function return value.
1106 */
1107 typecode = typemask & 7;
1108 switch (typecode) {
1109 case dh_typecode_void:
1110 info->nr_out = 0;
1111 break;
1112 case dh_typecode_i32:
1113 case dh_typecode_s32:
1114 case dh_typecode_ptr:
1115 info->nr_out = 1;
1116 info->out_kind = TCG_CALL_RET_NORMAL;
1117 break;
1118 case dh_typecode_i64:
1119 case dh_typecode_s64:
1120 info->nr_out = 64 / TCG_TARGET_REG_BITS;
1121 info->out_kind = TCG_CALL_RET_NORMAL;
5e3d0c19
RH
1122 /* Query the last register now to trigger any assert early. */
1123 tcg_target_call_oarg_reg(info->out_kind, info->nr_out - 1);
466d3759
RH
1124 break;
1125 case dh_typecode_i128:
1126 info->nr_out = 128 / TCG_TARGET_REG_BITS;
5427a9a7
RH
1127 info->out_kind = TCG_TARGET_CALL_RET_I128;
1128 switch (TCG_TARGET_CALL_RET_I128) {
466d3759 1129 case TCG_CALL_RET_NORMAL:
5e3d0c19
RH
1130 /* Query the last register now to trigger any assert early. */
1131 tcg_target_call_oarg_reg(info->out_kind, info->nr_out - 1);
466d3759 1132 break;
c6556aa0
RH
1133 case TCG_CALL_RET_BY_VEC:
1134 /* Query the single register now to trigger any assert early. */
1135 tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0);
1136 break;
313bdea8
RH
1137 case TCG_CALL_RET_BY_REF:
1138 /*
1139 * Allocate the first argument to the output.
1140 * We don't need to store this anywhere, just make it
1141 * unavailable for use in the input loop below.
1142 */
1143 cum.arg_slot = 1;
1144 break;
466d3759
RH
1145 default:
1146 qemu_build_not_reached();
1147 }
39004a71
RH
1148 break;
1149 default:
1150 g_assert_not_reached();
1151 }
39004a71
RH
1152
1153 /*
1154 * Parse and place function arguments.
1155 */
1156 for (typemask >>= 3; typemask; typemask >>= 3, cum.arg_idx++) {
1157 TCGCallArgumentKind kind;
1158 TCGType type;
1159
1160 typecode = typemask & 7;
1161 switch (typecode) {
1162 case dh_typecode_i32:
1163 case dh_typecode_s32:
1164 type = TCG_TYPE_I32;
1165 break;
1166 case dh_typecode_i64:
1167 case dh_typecode_s64:
1168 type = TCG_TYPE_I64;
1169 break;
1170 case dh_typecode_ptr:
1171 type = TCG_TYPE_PTR;
1172 break;
466d3759
RH
1173 case dh_typecode_i128:
1174 type = TCG_TYPE_I128;
1175 break;
39004a71
RH
1176 default:
1177 g_assert_not_reached();
1178 }
1179
1180 switch (type) {
1181 case TCG_TYPE_I32:
1182 switch (TCG_TARGET_CALL_ARG_I32) {
1183 case TCG_CALL_ARG_EVEN:
1184 layout_arg_even(&cum);
1185 /* fall through */
1186 case TCG_CALL_ARG_NORMAL:
1187 layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL);
1188 break;
1189 case TCG_CALL_ARG_EXTEND:
1190 kind = TCG_CALL_ARG_EXTEND_U + (typecode & 1);
1191 layout_arg_1(&cum, info, kind);
1192 break;
1193 default:
1194 qemu_build_not_reached();
1195 }
1196 break;
1197
1198 case TCG_TYPE_I64:
1199 switch (TCG_TARGET_CALL_ARG_I64) {
1200 case TCG_CALL_ARG_EVEN:
1201 layout_arg_even(&cum);
1202 /* fall through */
1203 case TCG_CALL_ARG_NORMAL:
1204 if (TCG_TARGET_REG_BITS == 32) {
1205 layout_arg_normal_n(&cum, info, 2);
1206 } else {
1207 layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL);
1208 }
1209 break;
1210 default:
1211 qemu_build_not_reached();
1212 }
1213 break;
1214
466d3759 1215 case TCG_TYPE_I128:
5427a9a7 1216 switch (TCG_TARGET_CALL_ARG_I128) {
466d3759
RH
1217 case TCG_CALL_ARG_EVEN:
1218 layout_arg_even(&cum);
1219 /* fall through */
1220 case TCG_CALL_ARG_NORMAL:
1221 layout_arg_normal_n(&cum, info, 128 / TCG_TARGET_REG_BITS);
1222 break;
313bdea8
RH
1223 case TCG_CALL_ARG_BY_REF:
1224 layout_arg_by_ref(&cum, info);
1225 break;
466d3759
RH
1226 default:
1227 qemu_build_not_reached();
1228 }
1229 break;
1230
39004a71
RH
1231 default:
1232 g_assert_not_reached();
1233 }
1234 }
1235 info->nr_in = cum.info_in_idx;
1236
1237 /* Validate that we didn't overrun the input array. */
1238 assert(cum.info_in_idx <= ARRAY_SIZE(info->in));
1239 /* Validate the backend has enough argument space. */
1240 assert(cum.arg_slot <= max_reg_slots + max_stk_slots);
313bdea8
RH
1241
1242 /*
1243 * Relocate the "ref_slot" area to the end of the parameters.
1244 * Minimizing this stack offset helps code size for x86,
1245 * which has a signed 8-bit offset encoding.
1246 */
1247 if (cum.ref_slot != 0) {
1248 int ref_base = 0;
1249
1250 if (cum.arg_slot > max_reg_slots) {
1251 int align = __alignof(Int128) / sizeof(tcg_target_long);
1252
1253 ref_base = cum.arg_slot - max_reg_slots;
1254 if (align > 1) {
1255 ref_base = ROUND_UP(ref_base, align);
1256 }
1257 }
1258 assert(ref_base + cum.ref_slot <= max_stk_slots);
d78e4a4f 1259 ref_base += max_reg_slots;
313bdea8
RH
1260
1261 if (ref_base != 0) {
1262 for (int i = cum.info_in_idx - 1; i >= 0; --i) {
1263 TCGCallArgumentLoc *loc = &info->in[i];
1264 switch (loc->kind) {
1265 case TCG_CALL_ARG_BY_REF:
1266 case TCG_CALL_ARG_BY_REF_N:
1267 loc->ref_slot += ref_base;
1268 break;
1269 default:
1270 break;
1271 }
1272 }
1273 }
1274 }
39004a71
RH
1275}
1276
91478cef 1277static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
f69d277e 1278static void process_op_defs(TCGContext *s);
1c2adb95
RH
1279static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
1280 TCGReg reg, const char *name);
91478cef 1281
43b972b7 1282static void tcg_context_init(unsigned max_cpus)
c896fe29 1283{
a76aabd3 1284 TCGContext *s = &tcg_init_ctx;
100b5e01 1285 int op, total_args, n, i;
c896fe29
FB
1286 TCGOpDef *def;
1287 TCGArgConstraint *args_ct;
1c2adb95 1288 TCGTemp *ts;
c896fe29
FB
1289
1290 memset(s, 0, sizeof(*s));
c896fe29 1291 s->nb_globals = 0;
c70fbf0a 1292
c896fe29
FB
1293 /* Count total number of arguments and allocate the corresponding
1294 space */
1295 total_args = 0;
1296 for(op = 0; op < NB_OPS; op++) {
1297 def = &tcg_op_defs[op];
1298 n = def->nb_iargs + def->nb_oargs;
1299 total_args += n;
1300 }
1301
bc2b17e6 1302 args_ct = g_new0(TCGArgConstraint, total_args);
c896fe29
FB
1303
1304 for(op = 0; op < NB_OPS; op++) {
1305 def = &tcg_op_defs[op];
1306 def->args_ct = args_ct;
c896fe29 1307 n = def->nb_iargs + def->nb_oargs;
c896fe29
FB
1308 args_ct += n;
1309 }
5cd8f621 1310
8429a1ca
RH
1311 init_call_layout(&info_helper_ld32_mmu);
1312 init_call_layout(&info_helper_ld64_mmu);
ebebea53 1313 init_call_layout(&info_helper_ld128_mmu);
8429a1ca
RH
1314 init_call_layout(&info_helper_st32_mmu);
1315 init_call_layout(&info_helper_st64_mmu);
ebebea53 1316 init_call_layout(&info_helper_st128_mmu);
8429a1ca 1317
c896fe29 1318 tcg_target_init(s);
f69d277e 1319 process_op_defs(s);
91478cef
RH
1320
1321 /* Reverse the order of the saved registers, assuming they're all at
1322 the start of tcg_target_reg_alloc_order. */
1323 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
1324 int r = tcg_target_reg_alloc_order[n];
1325 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) {
1326 break;
1327 }
1328 }
1329 for (i = 0; i < n; ++i) {
1330 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
1331 }
1332 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
1333 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
1334 }
b1311c4a 1335
38b47b19
EC
1336 alloc_tcg_plugin_context(s);
1337
b1311c4a 1338 tcg_ctx = s;
3468b59e
EC
1339 /*
1340 * In user-mode we simply share the init context among threads, since we
1341 * use a single region. See the documentation tcg_region_init() for the
1342 * reasoning behind this.
1343 * In softmmu we will have at most max_cpus TCG threads.
1344 */
1345#ifdef CONFIG_USER_ONLY
df2cce29 1346 tcg_ctxs = &tcg_ctx;
0e2d61cf
RH
1347 tcg_cur_ctxs = 1;
1348 tcg_max_ctxs = 1;
3468b59e 1349#else
0e2d61cf
RH
1350 tcg_max_ctxs = max_cpus;
1351 tcg_ctxs = g_new0(TCGContext *, max_cpus);
3468b59e 1352#endif
1c2adb95
RH
1353
1354 tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0));
1355 ts = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, TCG_AREG0, "env");
1356 cpu_env = temp_tcgv_ptr(ts);
9002ec79 1357}
b03cce8e 1358
43b972b7 1359void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus)
a76aabd3 1360{
43b972b7
RH
1361 tcg_context_init(max_cpus);
1362 tcg_region_init(tb_size, splitwx, max_cpus);
a76aabd3
RH
1363}
1364
6e3b2bfd
EC
1365/*
1366 * Allocate TBs right before their corresponding translated code, making
1367 * sure that TBs and code are on different cache lines.
1368 */
1369TranslationBlock *tcg_tb_alloc(TCGContext *s)
1370{
1371 uintptr_t align = qemu_icache_linesize;
1372 TranslationBlock *tb;
1373 void *next;
1374
e8feb96f 1375 retry:
6e3b2bfd
EC
1376 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
1377 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
1378
1379 if (unlikely(next > s->code_gen_highwater)) {
e8feb96f
EC
1380 if (tcg_region_alloc(s)) {
1381 return NULL;
1382 }
1383 goto retry;
6e3b2bfd 1384 }
d73415a3 1385 qatomic_set(&s->code_gen_ptr, next);
57a26946 1386 s->data_gen_ptr = NULL;
6e3b2bfd
EC
1387 return tb;
1388}
1389
9002ec79
RH
1390void tcg_prologue_init(TCGContext *s)
1391{
b0a0794a 1392 size_t prologue_size;
8163b749 1393
b0a0794a
RH
1394 s->code_ptr = s->code_gen_ptr;
1395 s->code_buf = s->code_gen_ptr;
5b38ee31 1396 s->data_gen_ptr = NULL;
b91ccb31
RH
1397
1398#ifndef CONFIG_TCG_INTERPRETER
b0a0794a 1399 tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
b91ccb31 1400#endif
8163b749 1401
5b38ee31
RH
1402#ifdef TCG_TARGET_NEED_POOL_LABELS
1403 s->pool_labels = NULL;
1404#endif
1405
653b87eb 1406 qemu_thread_jit_write();
8163b749 1407 /* Generate the prologue. */
b03cce8e 1408 tcg_target_qemu_prologue(s);
5b38ee31
RH
1409
1410#ifdef TCG_TARGET_NEED_POOL_LABELS
1411 /* Allow the prologue to put e.g. guest_base into a pool entry. */
1412 {
1768987b
RH
1413 int result = tcg_out_pool_finalize(s);
1414 tcg_debug_assert(result == 0);
5b38ee31
RH
1415 }
1416#endif
1417
b0a0794a 1418 prologue_size = tcg_current_code_size(s);
5584e2db 1419 perf_report_prologue(s->code_gen_ptr, prologue_size);
b0a0794a 1420
df5d2b16 1421#ifndef CONFIG_TCG_INTERPRETER
b0a0794a
RH
1422 flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
1423 (uintptr_t)s->code_buf, prologue_size);
df5d2b16 1424#endif
8163b749 1425
d6b64b2b 1426 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
c60f599b 1427 FILE *logfile = qemu_log_trylock();
78b54858
RH
1428 if (logfile) {
1429 fprintf(logfile, "PROLOGUE: [size=%zu]\n", prologue_size);
1430 if (s->data_gen_ptr) {
1431 size_t code_size = s->data_gen_ptr - s->code_gen_ptr;
1432 size_t data_size = prologue_size - code_size;
1433 size_t i;
1434
1435 disas(logfile, s->code_gen_ptr, code_size);
1436
1437 for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
1438 if (sizeof(tcg_target_ulong) == 8) {
1439 fprintf(logfile,
1440 "0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
1441 (uintptr_t)s->data_gen_ptr + i,
1442 *(uint64_t *)(s->data_gen_ptr + i));
1443 } else {
1444 fprintf(logfile,
1445 "0x%08" PRIxPTR ": .long 0x%08x\n",
1446 (uintptr_t)s->data_gen_ptr + i,
1447 *(uint32_t *)(s->data_gen_ptr + i));
1448 }
5b38ee31 1449 }
78b54858
RH
1450 } else {
1451 disas(logfile, s->code_gen_ptr, prologue_size);
5b38ee31 1452 }
78b54858 1453 fprintf(logfile, "\n");
78b54858 1454 qemu_log_unlock(logfile);
5b38ee31 1455 }
d6b64b2b 1456 }
cedbcb01 1457
6eea0434
RH
1458#ifndef CONFIG_TCG_INTERPRETER
1459 /*
1460 * Assert that goto_ptr is implemented completely, setting an epilogue.
1461 * For tci, we use NULL as the signal to return from the interpreter,
1462 * so skip this check.
1463 */
f4e01e30 1464 tcg_debug_assert(tcg_code_gen_epilogue != NULL);
6eea0434 1465#endif
d1c74ab3
RH
1466
1467 tcg_region_prologue_set(s);
c896fe29
FB
1468}
1469
c896fe29
FB
1470void tcg_func_start(TCGContext *s)
1471{
1472 tcg_pool_reset(s);
1473 s->nb_temps = s->nb_globals;
0ec9eabc
RH
1474
1475 /* No temps have been previously allocated for size or locality. */
1476 memset(s->free_temps, 0, sizeof(s->free_temps));
1477
c0522136
RH
1478 /* No constant temps have been previously allocated. */
1479 for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
1480 if (s->const_table[i]) {
1481 g_hash_table_remove_all(s->const_table[i]);
1482 }
1483 }
1484
abebf925 1485 s->nb_ops = 0;
c896fe29
FB
1486 s->nb_labels = 0;
1487 s->current_frame_offset = s->frame_start;
1488
0a209d4b
RH
1489#ifdef CONFIG_DEBUG_TCG
1490 s->goto_tb_issue_mask = 0;
1491#endif
1492
15fa08f8
RH
1493 QTAILQ_INIT(&s->ops);
1494 QTAILQ_INIT(&s->free_ops);
bef16ab4 1495 QSIMPLEQ_INIT(&s->labels);
4baf3978
RH
1496
1497 tcg_debug_assert(s->addr_type == TCG_TYPE_I32 ||
1498 s->addr_type == TCG_TYPE_I64);
d0a9bb5e
RH
1499
1500#if defined(CONFIG_SOFTMMU) && !defined(CONFIG_TCG_INTERPRETER)
1501 tcg_debug_assert(s->tlb_fast_offset < 0);
1502 tcg_debug_assert(s->tlb_fast_offset >= MIN_TLB_MASK_TABLE_OFS);
1503#endif
c896fe29
FB
1504}
1505
ae30e866 1506static TCGTemp *tcg_temp_alloc(TCGContext *s)
7ca4b752
RH
1507{
1508 int n = s->nb_temps++;
ae30e866
RH
1509
1510 if (n >= TCG_MAX_TEMPS) {
db6b7d0c 1511 tcg_raise_tb_overflow(s);
ae30e866 1512 }
7ca4b752
RH
1513 return memset(&s->temps[n], 0, sizeof(TCGTemp));
1514}
1515
ae30e866 1516static TCGTemp *tcg_global_alloc(TCGContext *s)
7ca4b752 1517{
fa477d25
RH
1518 TCGTemp *ts;
1519
7ca4b752 1520 tcg_debug_assert(s->nb_globals == s->nb_temps);
ae30e866 1521 tcg_debug_assert(s->nb_globals < TCG_MAX_TEMPS);
7ca4b752 1522 s->nb_globals++;
fa477d25 1523 ts = tcg_temp_alloc(s);
ee17db83 1524 ts->kind = TEMP_GLOBAL;
fa477d25
RH
1525
1526 return ts;
c896fe29
FB
1527}
1528
085272b3
RH
1529static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
1530 TCGReg reg, const char *name)
c896fe29 1531{
c896fe29 1532 TCGTemp *ts;
c896fe29 1533
1a057554 1534 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
7ca4b752
RH
1535
1536 ts = tcg_global_alloc(s);
c896fe29
FB
1537 ts->base_type = type;
1538 ts->type = type;
ee17db83 1539 ts->kind = TEMP_FIXED;
c896fe29 1540 ts->reg = reg;
c896fe29 1541 ts->name = name;
c896fe29 1542 tcg_regset_set_reg(s->reserved_regs, reg);
7ca4b752 1543
085272b3 1544 return ts;
a7812ae4
PB
1545}
1546
b6638662 1547void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
b3a62939 1548{
b3a62939
RH
1549 s->frame_start = start;
1550 s->frame_end = start + size;
085272b3
RH
1551 s->frame_temp
1552 = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
b3a62939
RH
1553}
1554
085272b3
RH
1555TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
1556 intptr_t offset, const char *name)
c896fe29 1557{
b1311c4a 1558 TCGContext *s = tcg_ctx;
dc41aa7d 1559 TCGTemp *base_ts = tcgv_ptr_temp(base);
7ca4b752 1560 TCGTemp *ts = tcg_global_alloc(s);
aef85402 1561 int indirect_reg = 0;
c896fe29 1562
c0522136
RH
1563 switch (base_ts->kind) {
1564 case TEMP_FIXED:
1565 break;
1566 case TEMP_GLOBAL:
5a18407f
RH
1567 /* We do not support double-indirect registers. */
1568 tcg_debug_assert(!base_ts->indirect_reg);
b3915dbb 1569 base_ts->indirect_base = 1;
5a18407f
RH
1570 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
1571 ? 2 : 1);
1572 indirect_reg = 1;
c0522136
RH
1573 break;
1574 default:
1575 g_assert_not_reached();
b3915dbb
RH
1576 }
1577
7ca4b752
RH
1578 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1579 TCGTemp *ts2 = tcg_global_alloc(s);
c896fe29 1580 char buf[64];
7ca4b752
RH
1581
1582 ts->base_type = TCG_TYPE_I64;
c896fe29 1583 ts->type = TCG_TYPE_I32;
b3915dbb 1584 ts->indirect_reg = indirect_reg;
c896fe29 1585 ts->mem_allocated = 1;
b3a62939 1586 ts->mem_base = base_ts;
aef85402 1587 ts->mem_offset = offset;
c896fe29
FB
1588 pstrcpy(buf, sizeof(buf), name);
1589 pstrcat(buf, sizeof(buf), "_0");
1590 ts->name = strdup(buf);
c896fe29 1591
7ca4b752
RH
1592 tcg_debug_assert(ts2 == ts + 1);
1593 ts2->base_type = TCG_TYPE_I64;
1594 ts2->type = TCG_TYPE_I32;
b3915dbb 1595 ts2->indirect_reg = indirect_reg;
7ca4b752
RH
1596 ts2->mem_allocated = 1;
1597 ts2->mem_base = base_ts;
aef85402 1598 ts2->mem_offset = offset + 4;
fac87bd2 1599 ts2->temp_subindex = 1;
c896fe29
FB
1600 pstrcpy(buf, sizeof(buf), name);
1601 pstrcat(buf, sizeof(buf), "_1");
120c1084 1602 ts2->name = strdup(buf);
7ca4b752 1603 } else {
c896fe29
FB
1604 ts->base_type = type;
1605 ts->type = type;
b3915dbb 1606 ts->indirect_reg = indirect_reg;
c896fe29 1607 ts->mem_allocated = 1;
b3a62939 1608 ts->mem_base = base_ts;
c896fe29 1609 ts->mem_offset = offset;
c896fe29 1610 ts->name = name;
c896fe29 1611 }
085272b3 1612 return ts;
a7812ae4
PB
1613}
1614
bbf989bf 1615TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
c896fe29 1616{
b1311c4a 1617 TCGContext *s = tcg_ctx;
c896fe29 1618 TCGTemp *ts;
e1c08b00 1619 int n;
7ca4b752 1620
e1c08b00
RH
1621 if (kind == TEMP_EBB) {
1622 int idx = find_first_bit(s->free_temps[type].l, TCG_MAX_TEMPS);
1623
1624 if (idx < TCG_MAX_TEMPS) {
1625 /* There is already an available temp with the right type. */
1626 clear_bit(idx, s->free_temps[type].l);
1627
1628 ts = &s->temps[idx];
1629 ts->temp_allocated = 1;
1630 tcg_debug_assert(ts->base_type == type);
1631 tcg_debug_assert(ts->kind == kind);
2f2e911d 1632 return ts;
43eef72f 1633 }
e1c08b00
RH
1634 } else {
1635 tcg_debug_assert(kind == TEMP_TB);
1636 }
7ca4b752 1637
e1c08b00
RH
1638 switch (type) {
1639 case TCG_TYPE_I32:
1640 case TCG_TYPE_V64:
1641 case TCG_TYPE_V128:
1642 case TCG_TYPE_V256:
1643 n = 1;
1644 break;
1645 case TCG_TYPE_I64:
1646 n = 64 / TCG_TARGET_REG_BITS;
1647 break;
1648 case TCG_TYPE_I128:
1649 n = 128 / TCG_TARGET_REG_BITS;
1650 break;
1651 default:
1652 g_assert_not_reached();
1653 }
43eef72f 1654
e1c08b00
RH
1655 ts = tcg_temp_alloc(s);
1656 ts->base_type = type;
1657 ts->temp_allocated = 1;
1658 ts->kind = kind;
1659
1660 if (n == 1) {
1661 ts->type = type;
1662 } else {
1663 ts->type = TCG_TYPE_REG;
43eef72f 1664
e1c08b00
RH
1665 for (int i = 1; i < n; ++i) {
1666 TCGTemp *ts2 = tcg_temp_alloc(s);
43eef72f 1667
e1c08b00
RH
1668 tcg_debug_assert(ts2 == ts + i);
1669 ts2->base_type = type;
1670 ts2->type = TCG_TYPE_REG;
1671 ts2->temp_allocated = 1;
1672 ts2->temp_subindex = i;
1673 ts2->kind = kind;
e8996ee0 1674 }
c896fe29 1675 }
085272b3 1676 return ts;
c896fe29
FB
1677}
1678
d2fd745f
RH
1679TCGv_vec tcg_temp_new_vec(TCGType type)
1680{
1681 TCGTemp *t;
1682
1683#ifdef CONFIG_DEBUG_TCG
1684 switch (type) {
1685 case TCG_TYPE_V64:
1686 assert(TCG_TARGET_HAS_v64);
1687 break;
1688 case TCG_TYPE_V128:
1689 assert(TCG_TARGET_HAS_v128);
1690 break;
1691 case TCG_TYPE_V256:
1692 assert(TCG_TARGET_HAS_v256);
1693 break;
1694 default:
1695 g_assert_not_reached();
1696 }
1697#endif
1698
bbf989bf 1699 t = tcg_temp_new_internal(type, TEMP_EBB);
d2fd745f
RH
1700 return temp_tcgv_vec(t);
1701}
1702
1703/* Create a new temp of the same type as an existing temp. */
1704TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
1705{
1706 TCGTemp *t = tcgv_vec_temp(match);
1707
1708 tcg_debug_assert(t->temp_allocated != 0);
1709
bbf989bf 1710 t = tcg_temp_new_internal(t->base_type, TEMP_EBB);
d2fd745f
RH
1711 return temp_tcgv_vec(t);
1712}
1713
5bfa8034 1714void tcg_temp_free_internal(TCGTemp *ts)
c896fe29 1715{
b1311c4a 1716 TCGContext *s = tcg_ctx;
c896fe29 1717
c7482438
RH
1718 switch (ts->kind) {
1719 case TEMP_CONST:
f57c6915 1720 case TEMP_TB:
2f2e911d
RH
1721 /* Silently ignore free. */
1722 break;
1723 case TEMP_EBB:
1724 tcg_debug_assert(ts->temp_allocated != 0);
1725 ts->temp_allocated = 0;
1726 set_bit(temp_idx(ts), s->free_temps[ts->base_type].l);
c7482438
RH
1727 break;
1728 default:
2f2e911d 1729 /* It never made sense to free TEMP_FIXED or TEMP_GLOBAL. */
c7482438 1730 g_assert_not_reached();
c0522136 1731 }
c896fe29
FB
1732}
1733
c0522136
RH
1734TCGTemp *tcg_constant_internal(TCGType type, int64_t val)
1735{
1736 TCGContext *s = tcg_ctx;
1737 GHashTable *h = s->const_table[type];
1738 TCGTemp *ts;
1739
1740 if (h == NULL) {
1741 h = g_hash_table_new(g_int64_hash, g_int64_equal);
1742 s->const_table[type] = h;
1743 }
1744
1745 ts = g_hash_table_lookup(h, &val);
1746 if (ts == NULL) {
aef85402
RH
1747 int64_t *val_ptr;
1748
c0522136
RH
1749 ts = tcg_temp_alloc(s);
1750
1751 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1752 TCGTemp *ts2 = tcg_temp_alloc(s);
1753
aef85402
RH
1754 tcg_debug_assert(ts2 == ts + 1);
1755
c0522136
RH
1756 ts->base_type = TCG_TYPE_I64;
1757 ts->type = TCG_TYPE_I32;
1758 ts->kind = TEMP_CONST;
1759 ts->temp_allocated = 1;
c0522136 1760
c0522136
RH
1761 ts2->base_type = TCG_TYPE_I64;
1762 ts2->type = TCG_TYPE_I32;
1763 ts2->kind = TEMP_CONST;
1764 ts2->temp_allocated = 1;
fac87bd2 1765 ts2->temp_subindex = 1;
aef85402
RH
1766
1767 /*
1768 * Retain the full value of the 64-bit constant in the low
1769 * part, so that the hash table works. Actual uses will
1770 * truncate the value to the low part.
1771 */
1772 ts[HOST_BIG_ENDIAN].val = val;
1773 ts[!HOST_BIG_ENDIAN].val = val >> 32;
1774 val_ptr = &ts[HOST_BIG_ENDIAN].val;
c0522136
RH
1775 } else {
1776 ts->base_type = type;
1777 ts->type = type;
1778 ts->kind = TEMP_CONST;
1779 ts->temp_allocated = 1;
1780 ts->val = val;
aef85402 1781 val_ptr = &ts->val;
c0522136 1782 }
aef85402 1783 g_hash_table_insert(h, val_ptr, ts);
c0522136
RH
1784 }
1785
1786 return ts;
1787}
1788
1789TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val)
1790{
1791 val = dup_const(vece, val);
1792 return temp_tcgv_vec(tcg_constant_internal(type, val));
1793}
1794
88d4005b
RH
1795TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val)
1796{
1797 TCGTemp *t = tcgv_vec_temp(match);
1798
1799 tcg_debug_assert(t->temp_allocated != 0);
1800 return tcg_constant_vec(t->base_type, vece, val);
1801}
1802
be0f34b5
RH
1803/* Return true if OP may appear in the opcode stream.
1804 Test the runtime variable that controls each opcode. */
1805bool tcg_op_supported(TCGOpcode op)
1806{
d2fd745f
RH
1807 const bool have_vec
1808 = TCG_TARGET_HAS_v64 | TCG_TARGET_HAS_v128 | TCG_TARGET_HAS_v256;
1809
be0f34b5
RH
1810 switch (op) {
1811 case INDEX_op_discard:
1812 case INDEX_op_set_label:
1813 case INDEX_op_call:
1814 case INDEX_op_br:
1815 case INDEX_op_mb:
1816 case INDEX_op_insn_start:
1817 case INDEX_op_exit_tb:
1818 case INDEX_op_goto_tb:
f4e01e30 1819 case INDEX_op_goto_ptr:
fecccfcc
RH
1820 case INDEX_op_qemu_ld_a32_i32:
1821 case INDEX_op_qemu_ld_a64_i32:
1822 case INDEX_op_qemu_st_a32_i32:
1823 case INDEX_op_qemu_st_a64_i32:
1824 case INDEX_op_qemu_ld_a32_i64:
1825 case INDEX_op_qemu_ld_a64_i64:
1826 case INDEX_op_qemu_st_a32_i64:
1827 case INDEX_op_qemu_st_a64_i64:
be0f34b5
RH
1828 return true;
1829
fecccfcc
RH
1830 case INDEX_op_qemu_st8_a32_i32:
1831 case INDEX_op_qemu_st8_a64_i32:
07ce0b05
RH
1832 return TCG_TARGET_HAS_qemu_st8_i32;
1833
fecccfcc
RH
1834 case INDEX_op_qemu_ld_a32_i128:
1835 case INDEX_op_qemu_ld_a64_i128:
1836 case INDEX_op_qemu_st_a32_i128:
1837 case INDEX_op_qemu_st_a64_i128:
12fde9bc
RH
1838 return TCG_TARGET_HAS_qemu_ldst_i128;
1839
be0f34b5 1840 case INDEX_op_mov_i32:
be0f34b5
RH
1841 case INDEX_op_setcond_i32:
1842 case INDEX_op_brcond_i32:
1843 case INDEX_op_ld8u_i32:
1844 case INDEX_op_ld8s_i32:
1845 case INDEX_op_ld16u_i32:
1846 case INDEX_op_ld16s_i32:
1847 case INDEX_op_ld_i32:
1848 case INDEX_op_st8_i32:
1849 case INDEX_op_st16_i32:
1850 case INDEX_op_st_i32:
1851 case INDEX_op_add_i32:
1852 case INDEX_op_sub_i32:
1853 case INDEX_op_mul_i32:
1854 case INDEX_op_and_i32:
1855 case INDEX_op_or_i32:
1856 case INDEX_op_xor_i32:
1857 case INDEX_op_shl_i32:
1858 case INDEX_op_shr_i32:
1859 case INDEX_op_sar_i32:
1860 return true;
1861
1862 case INDEX_op_movcond_i32:
1863 return TCG_TARGET_HAS_movcond_i32;
1864 case INDEX_op_div_i32:
1865 case INDEX_op_divu_i32:
1866 return TCG_TARGET_HAS_div_i32;
1867 case INDEX_op_rem_i32:
1868 case INDEX_op_remu_i32:
1869 return TCG_TARGET_HAS_rem_i32;
1870 case INDEX_op_div2_i32:
1871 case INDEX_op_divu2_i32:
1872 return TCG_TARGET_HAS_div2_i32;
1873 case INDEX_op_rotl_i32:
1874 case INDEX_op_rotr_i32:
1875 return TCG_TARGET_HAS_rot_i32;
1876 case INDEX_op_deposit_i32:
1877 return TCG_TARGET_HAS_deposit_i32;
1878 case INDEX_op_extract_i32:
1879 return TCG_TARGET_HAS_extract_i32;
1880 case INDEX_op_sextract_i32:
1881 return TCG_TARGET_HAS_sextract_i32;
fce1296f
RH
1882 case INDEX_op_extract2_i32:
1883 return TCG_TARGET_HAS_extract2_i32;
be0f34b5
RH
1884 case INDEX_op_add2_i32:
1885 return TCG_TARGET_HAS_add2_i32;
1886 case INDEX_op_sub2_i32:
1887 return TCG_TARGET_HAS_sub2_i32;
1888 case INDEX_op_mulu2_i32:
1889 return TCG_TARGET_HAS_mulu2_i32;
1890 case INDEX_op_muls2_i32:
1891 return TCG_TARGET_HAS_muls2_i32;
1892 case INDEX_op_muluh_i32:
1893 return TCG_TARGET_HAS_muluh_i32;
1894 case INDEX_op_mulsh_i32:
1895 return TCG_TARGET_HAS_mulsh_i32;
1896 case INDEX_op_ext8s_i32:
1897 return TCG_TARGET_HAS_ext8s_i32;
1898 case INDEX_op_ext16s_i32:
1899 return TCG_TARGET_HAS_ext16s_i32;
1900 case INDEX_op_ext8u_i32:
1901 return TCG_TARGET_HAS_ext8u_i32;
1902 case INDEX_op_ext16u_i32:
1903 return TCG_TARGET_HAS_ext16u_i32;
1904 case INDEX_op_bswap16_i32:
1905 return TCG_TARGET_HAS_bswap16_i32;
1906 case INDEX_op_bswap32_i32:
1907 return TCG_TARGET_HAS_bswap32_i32;
1908 case INDEX_op_not_i32:
1909 return TCG_TARGET_HAS_not_i32;
1910 case INDEX_op_neg_i32:
1911 return TCG_TARGET_HAS_neg_i32;
1912 case INDEX_op_andc_i32:
1913 return TCG_TARGET_HAS_andc_i32;
1914 case INDEX_op_orc_i32:
1915 return TCG_TARGET_HAS_orc_i32;
1916 case INDEX_op_eqv_i32:
1917 return TCG_TARGET_HAS_eqv_i32;
1918 case INDEX_op_nand_i32:
1919 return TCG_TARGET_HAS_nand_i32;
1920 case INDEX_op_nor_i32:
1921 return TCG_TARGET_HAS_nor_i32;
1922 case INDEX_op_clz_i32:
1923 return TCG_TARGET_HAS_clz_i32;
1924 case INDEX_op_ctz_i32:
1925 return TCG_TARGET_HAS_ctz_i32;
1926 case INDEX_op_ctpop_i32:
1927 return TCG_TARGET_HAS_ctpop_i32;
1928
1929 case INDEX_op_brcond2_i32:
1930 case INDEX_op_setcond2_i32:
1931 return TCG_TARGET_REG_BITS == 32;
1932
1933 case INDEX_op_mov_i64:
be0f34b5
RH
1934 case INDEX_op_setcond_i64:
1935 case INDEX_op_brcond_i64:
1936 case INDEX_op_ld8u_i64:
1937 case INDEX_op_ld8s_i64:
1938 case INDEX_op_ld16u_i64:
1939 case INDEX_op_ld16s_i64:
1940 case INDEX_op_ld32u_i64:
1941 case INDEX_op_ld32s_i64:
1942 case INDEX_op_ld_i64:
1943 case INDEX_op_st8_i64:
1944 case INDEX_op_st16_i64:
1945 case INDEX_op_st32_i64:
1946 case INDEX_op_st_i64:
1947 case INDEX_op_add_i64:
1948 case INDEX_op_sub_i64:
1949 case INDEX_op_mul_i64:
1950 case INDEX_op_and_i64:
1951 case INDEX_op_or_i64:
1952 case INDEX_op_xor_i64:
1953 case INDEX_op_shl_i64:
1954 case INDEX_op_shr_i64:
1955 case INDEX_op_sar_i64:
1956 case INDEX_op_ext_i32_i64:
1957 case INDEX_op_extu_i32_i64:
1958 return TCG_TARGET_REG_BITS == 64;
1959
1960 case INDEX_op_movcond_i64:
1961 return TCG_TARGET_HAS_movcond_i64;
1962 case INDEX_op_div_i64:
1963 case INDEX_op_divu_i64:
1964 return TCG_TARGET_HAS_div_i64;
1965 case INDEX_op_rem_i64:
1966 case INDEX_op_remu_i64:
1967 return TCG_TARGET_HAS_rem_i64;
1968 case INDEX_op_div2_i64:
1969 case INDEX_op_divu2_i64:
1970 return TCG_TARGET_HAS_div2_i64;
1971 case INDEX_op_rotl_i64:
1972 case INDEX_op_rotr_i64:
1973 return TCG_TARGET_HAS_rot_i64;
1974 case INDEX_op_deposit_i64:
1975 return TCG_TARGET_HAS_deposit_i64;
1976 case INDEX_op_extract_i64:
1977 return TCG_TARGET_HAS_extract_i64;
1978 case INDEX_op_sextract_i64:
1979 return TCG_TARGET_HAS_sextract_i64;
fce1296f
RH
1980 case INDEX_op_extract2_i64:
1981 return TCG_TARGET_HAS_extract2_i64;
be0f34b5
RH
1982 case INDEX_op_extrl_i64_i32:
1983 return TCG_TARGET_HAS_extrl_i64_i32;
1984 case INDEX_op_extrh_i64_i32:
1985 return TCG_TARGET_HAS_extrh_i64_i32;
1986 case INDEX_op_ext8s_i64:
1987 return TCG_TARGET_HAS_ext8s_i64;
1988 case INDEX_op_ext16s_i64:
1989 return TCG_TARGET_HAS_ext16s_i64;
1990 case INDEX_op_ext32s_i64:
1991 return TCG_TARGET_HAS_ext32s_i64;
1992 case INDEX_op_ext8u_i64:
1993 return TCG_TARGET_HAS_ext8u_i64;
1994 case INDEX_op_ext16u_i64:
1995 return TCG_TARGET_HAS_ext16u_i64;
1996 case INDEX_op_ext32u_i64:
1997 return TCG_TARGET_HAS_ext32u_i64;
1998 case INDEX_op_bswap16_i64:
1999 return TCG_TARGET_HAS_bswap16_i64;
2000 case INDEX_op_bswap32_i64:
2001 return TCG_TARGET_HAS_bswap32_i64;
2002 case INDEX_op_bswap64_i64:
2003 return TCG_TARGET_HAS_bswap64_i64;
2004 case INDEX_op_not_i64:
2005 return TCG_TARGET_HAS_not_i64;
2006 case INDEX_op_neg_i64:
2007 return TCG_TARGET_HAS_neg_i64;
2008 case INDEX_op_andc_i64:
2009 return TCG_TARGET_HAS_andc_i64;
2010 case INDEX_op_orc_i64:
2011 return TCG_TARGET_HAS_orc_i64;
2012 case INDEX_op_eqv_i64:
2013 return TCG_TARGET_HAS_eqv_i64;
2014 case INDEX_op_nand_i64:
2015 return TCG_TARGET_HAS_nand_i64;
2016 case INDEX_op_nor_i64:
2017 return TCG_TARGET_HAS_nor_i64;
2018 case INDEX_op_clz_i64:
2019 return TCG_TARGET_HAS_clz_i64;
2020 case INDEX_op_ctz_i64:
2021 return TCG_TARGET_HAS_ctz_i64;
2022 case INDEX_op_ctpop_i64:
2023 return TCG_TARGET_HAS_ctpop_i64;
2024 case INDEX_op_add2_i64:
2025 return TCG_TARGET_HAS_add2_i64;
2026 case INDEX_op_sub2_i64:
2027 return TCG_TARGET_HAS_sub2_i64;
2028 case INDEX_op_mulu2_i64:
2029 return TCG_TARGET_HAS_mulu2_i64;
2030 case INDEX_op_muls2_i64:
2031 return TCG_TARGET_HAS_muls2_i64;
2032 case INDEX_op_muluh_i64:
2033 return TCG_TARGET_HAS_muluh_i64;
2034 case INDEX_op_mulsh_i64:
2035 return TCG_TARGET_HAS_mulsh_i64;
2036
d2fd745f
RH
2037 case INDEX_op_mov_vec:
2038 case INDEX_op_dup_vec:
37ee55a0 2039 case INDEX_op_dupm_vec:
d2fd745f
RH
2040 case INDEX_op_ld_vec:
2041 case INDEX_op_st_vec:
2042 case INDEX_op_add_vec:
2043 case INDEX_op_sub_vec:
2044 case INDEX_op_and_vec:
2045 case INDEX_op_or_vec:
2046 case INDEX_op_xor_vec:
212be173 2047 case INDEX_op_cmp_vec:
d2fd745f
RH
2048 return have_vec;
2049 case INDEX_op_dup2_vec:
2050 return have_vec && TCG_TARGET_REG_BITS == 32;
2051 case INDEX_op_not_vec:
2052 return have_vec && TCG_TARGET_HAS_not_vec;
2053 case INDEX_op_neg_vec:
2054 return have_vec && TCG_TARGET_HAS_neg_vec;
bcefc902
RH
2055 case INDEX_op_abs_vec:
2056 return have_vec && TCG_TARGET_HAS_abs_vec;
d2fd745f
RH
2057 case INDEX_op_andc_vec:
2058 return have_vec && TCG_TARGET_HAS_andc_vec;
2059 case INDEX_op_orc_vec:
2060 return have_vec && TCG_TARGET_HAS_orc_vec;
ed523473
RH
2061 case INDEX_op_nand_vec:
2062 return have_vec && TCG_TARGET_HAS_nand_vec;
2063 case INDEX_op_nor_vec:
2064 return have_vec && TCG_TARGET_HAS_nor_vec;
2065 case INDEX_op_eqv_vec:
2066 return have_vec && TCG_TARGET_HAS_eqv_vec;
3774030a
RH
2067 case INDEX_op_mul_vec:
2068 return have_vec && TCG_TARGET_HAS_mul_vec;
d0ec9796
RH
2069 case INDEX_op_shli_vec:
2070 case INDEX_op_shri_vec:
2071 case INDEX_op_sari_vec:
2072 return have_vec && TCG_TARGET_HAS_shi_vec;
2073 case INDEX_op_shls_vec:
2074 case INDEX_op_shrs_vec:
2075 case INDEX_op_sars_vec:
2076 return have_vec && TCG_TARGET_HAS_shs_vec;
2077 case INDEX_op_shlv_vec:
2078 case INDEX_op_shrv_vec:
2079 case INDEX_op_sarv_vec:
2080 return have_vec && TCG_TARGET_HAS_shv_vec;
b0f7e744
RH
2081 case INDEX_op_rotli_vec:
2082 return have_vec && TCG_TARGET_HAS_roti_vec;
23850a74
RH
2083 case INDEX_op_rotls_vec:
2084 return have_vec && TCG_TARGET_HAS_rots_vec;
5d0ceda9
RH
2085 case INDEX_op_rotlv_vec:
2086 case INDEX_op_rotrv_vec:
2087 return have_vec && TCG_TARGET_HAS_rotv_vec;
8afaf050
RH
2088 case INDEX_op_ssadd_vec:
2089 case INDEX_op_usadd_vec:
2090 case INDEX_op_sssub_vec:
2091 case INDEX_op_ussub_vec:
2092 return have_vec && TCG_TARGET_HAS_sat_vec;
dd0a0fcd
RH
2093 case INDEX_op_smin_vec:
2094 case INDEX_op_umin_vec:
2095 case INDEX_op_smax_vec:
2096 case INDEX_op_umax_vec:
2097 return have_vec && TCG_TARGET_HAS_minmax_vec;
38dc1294
RH
2098 case INDEX_op_bitsel_vec:
2099 return have_vec && TCG_TARGET_HAS_bitsel_vec;
f75da298
RH
2100 case INDEX_op_cmpsel_vec:
2101 return have_vec && TCG_TARGET_HAS_cmpsel_vec;
d2fd745f 2102
db432672
RH
2103 default:
2104 tcg_debug_assert(op > INDEX_op_last_generic && op < NB_OPS);
2105 return true;
be0f34b5 2106 }
be0f34b5
RH
2107}
2108
39004a71
RH
2109static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs);
2110
d53106c9 2111void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, int nargs, TCGTemp **args)
c896fe29 2112{
39004a71
RH
2113 TCGv_i64 extend_free[MAX_CALL_IARGS];
2114 int n_extend = 0;
75e8b9b7 2115 TCGOp *op;
39004a71 2116 int i, n, pi = 0, total_args;
afb49896 2117
d53106c9
RH
2118 if (unlikely(g_once_init_enter(HELPER_INFO_INIT(info)))) {
2119 init_call_layout(info);
2120 g_once_init_leave(HELPER_INFO_INIT(info), HELPER_INFO_INIT_VAL(info));
2121 }
2122
39004a71
RH
2123 total_args = info->nr_out + info->nr_in + 2;
2124 op = tcg_op_alloc(INDEX_op_call, total_args);
2bece2c8 2125
38b47b19 2126#ifdef CONFIG_PLUGIN
17083f6f
EC
2127 /* Flag helpers that may affect guest state */
2128 if (tcg_ctx->plugin_insn &&
2129 !(info->flags & TCG_CALL_PLUGIN) &&
2130 !(info->flags & TCG_CALL_NO_SIDE_EFFECTS)) {
38b47b19
EC
2131 tcg_ctx->plugin_insn->calls_helpers = true;
2132 }
2133#endif
2134
39004a71
RH
2135 TCGOP_CALLO(op) = n = info->nr_out;
2136 switch (n) {
2137 case 0:
2138 tcg_debug_assert(ret == NULL);
2139 break;
2140 case 1:
2141 tcg_debug_assert(ret != NULL);
2142 op->args[pi++] = temp_arg(ret);
2143 break;
2144 case 2:
466d3759 2145 case 4:
39004a71 2146 tcg_debug_assert(ret != NULL);
466d3759 2147 tcg_debug_assert(ret->base_type == ret->type + ctz32(n));
39004a71 2148 tcg_debug_assert(ret->temp_subindex == 0);
466d3759
RH
2149 for (i = 0; i < n; ++i) {
2150 op->args[pi++] = temp_arg(ret + i);
2151 }
39004a71
RH
2152 break;
2153 default:
2154 g_assert_not_reached();
2155 }
2156
2157 TCGOP_CALLI(op) = n = info->nr_in;
2158 for (i = 0; i < n; i++) {
2159 const TCGCallArgumentLoc *loc = &info->in[i];
2160 TCGTemp *ts = args[loc->arg_idx] + loc->tmp_subindex;
2161
2162 switch (loc->kind) {
2163 case TCG_CALL_ARG_NORMAL:
313bdea8
RH
2164 case TCG_CALL_ARG_BY_REF:
2165 case TCG_CALL_ARG_BY_REF_N:
39004a71
RH
2166 op->args[pi++] = temp_arg(ts);
2167 break;
eb8b0224 2168
39004a71
RH
2169 case TCG_CALL_ARG_EXTEND_U:
2170 case TCG_CALL_ARG_EXTEND_S:
2171 {
5dd48602 2172 TCGv_i64 temp = tcg_temp_ebb_new_i64();
39004a71
RH
2173 TCGv_i32 orig = temp_tcgv_i32(ts);
2174
2175 if (loc->kind == TCG_CALL_ARG_EXTEND_S) {
eb8b0224
RH
2176 tcg_gen_ext_i32_i64(temp, orig);
2177 } else {
2178 tcg_gen_extu_i32_i64(temp, orig);
2179 }
39004a71
RH
2180 op->args[pi++] = tcgv_i64_arg(temp);
2181 extend_free[n_extend++] = temp;
2bece2c8 2182 }
e2a9dd6b 2183 break;
7b7d8b2d 2184
e2a9dd6b
RH
2185 default:
2186 g_assert_not_reached();
c896fe29
FB
2187 }
2188 }
d53106c9 2189 op->args[pi++] = (uintptr_t)info->func;
3e92aa34 2190 op->args[pi++] = (uintptr_t)info;
39004a71 2191 tcg_debug_assert(pi == total_args);
a7812ae4 2192
39004a71 2193 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
7319d83a 2194
39004a71
RH
2195 tcg_debug_assert(n_extend < ARRAY_SIZE(extend_free));
2196 for (i = 0; i < n_extend; ++i) {
2197 tcg_temp_free_i64(extend_free[i]);
2bece2c8 2198 }
c896fe29 2199}
c896fe29 2200
8fcd3692 2201static void tcg_reg_alloc_start(TCGContext *s)
c896fe29 2202{
ac3b8891 2203 int i, n;
ac3b8891 2204
ee17db83
RH
2205 for (i = 0, n = s->nb_temps; i < n; i++) {
2206 TCGTemp *ts = &s->temps[i];
2207 TCGTempVal val = TEMP_VAL_MEM;
2208
2209 switch (ts->kind) {
c0522136
RH
2210 case TEMP_CONST:
2211 val = TEMP_VAL_CONST;
2212 break;
ee17db83
RH
2213 case TEMP_FIXED:
2214 val = TEMP_VAL_REG;
2215 break;
2216 case TEMP_GLOBAL:
2217 break;
c7482438 2218 case TEMP_EBB:
ee17db83
RH
2219 val = TEMP_VAL_DEAD;
2220 /* fall through */
f57c6915 2221 case TEMP_TB:
ee17db83
RH
2222 ts->mem_allocated = 0;
2223 break;
2224 default:
2225 g_assert_not_reached();
2226 }
2227 ts->val_type = val;
e8996ee0 2228 }
f8b2f202
RH
2229
2230 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
c896fe29
FB
2231}
2232
f8b2f202
RH
2233static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
2234 TCGTemp *ts)
c896fe29 2235{
1807f4c4 2236 int idx = temp_idx(ts);
ac56dd48 2237
ee17db83
RH
2238 switch (ts->kind) {
2239 case TEMP_FIXED:
2240 case TEMP_GLOBAL:
ac56dd48 2241 pstrcpy(buf, buf_size, ts->name);
ee17db83 2242 break;
f57c6915 2243 case TEMP_TB:
f8b2f202 2244 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
ee17db83 2245 break;
c7482438 2246 case TEMP_EBB:
f8b2f202 2247 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
ee17db83 2248 break;
c0522136
RH
2249 case TEMP_CONST:
2250 switch (ts->type) {
2251 case TCG_TYPE_I32:
2252 snprintf(buf, buf_size, "$0x%x", (int32_t)ts->val);
2253 break;
2254#if TCG_TARGET_REG_BITS > 32
2255 case TCG_TYPE_I64:
2256 snprintf(buf, buf_size, "$0x%" PRIx64, ts->val);
2257 break;
2258#endif
2259 case TCG_TYPE_V64:
2260 case TCG_TYPE_V128:
2261 case TCG_TYPE_V256:
2262 snprintf(buf, buf_size, "v%d$0x%" PRIx64,
2263 64 << (ts->type - TCG_TYPE_V64), ts->val);
2264 break;
2265 default:
2266 g_assert_not_reached();
2267 }
2268 break;
c896fe29
FB
2269 }
2270 return buf;
2271}
2272
43439139
RH
2273static char *tcg_get_arg_str(TCGContext *s, char *buf,
2274 int buf_size, TCGArg arg)
f8b2f202 2275{
43439139 2276 return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
f8b2f202
RH
2277}
2278
f48f3ede
BS
2279static const char * const cond_name[] =
2280{
0aed257f
RH
2281 [TCG_COND_NEVER] = "never",
2282 [TCG_COND_ALWAYS] = "always",
f48f3ede
BS
2283 [TCG_COND_EQ] = "eq",
2284 [TCG_COND_NE] = "ne",
2285 [TCG_COND_LT] = "lt",
2286 [TCG_COND_GE] = "ge",
2287 [TCG_COND_LE] = "le",
2288 [TCG_COND_GT] = "gt",
2289 [TCG_COND_LTU] = "ltu",
2290 [TCG_COND_GEU] = "geu",
2291 [TCG_COND_LEU] = "leu",
2292 [TCG_COND_GTU] = "gtu"
2293};
2294
12fde9bc 2295static const char * const ldst_name[(MO_BSWAP | MO_SSIZE) + 1] =
f713d6ad
RH
2296{
2297 [MO_UB] = "ub",
2298 [MO_SB] = "sb",
2299 [MO_LEUW] = "leuw",
2300 [MO_LESW] = "lesw",
2301 [MO_LEUL] = "leul",
2302 [MO_LESL] = "lesl",
fc313c64 2303 [MO_LEUQ] = "leq",
f713d6ad
RH
2304 [MO_BEUW] = "beuw",
2305 [MO_BESW] = "besw",
2306 [MO_BEUL] = "beul",
2307 [MO_BESL] = "besl",
fc313c64 2308 [MO_BEUQ] = "beq",
12fde9bc
RH
2309 [MO_128 + MO_BE] = "beo",
2310 [MO_128 + MO_LE] = "leo",
f713d6ad
RH
2311};
2312
1f00b27f 2313static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
1f00b27f 2314 [MO_UNALN >> MO_ASHIFT] = "un+",
1f00b27f 2315 [MO_ALIGN >> MO_ASHIFT] = "al+",
1f00b27f
SS
2316 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+",
2317 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+",
2318 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+",
2319 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
2320 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
2321 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
2322};
2323
37031fef
RH
2324static const char * const atom_name[(MO_ATOM_MASK >> MO_ATOM_SHIFT) + 1] = {
2325 [MO_ATOM_IFALIGN >> MO_ATOM_SHIFT] = "",
2326 [MO_ATOM_IFALIGN_PAIR >> MO_ATOM_SHIFT] = "pair+",
2327 [MO_ATOM_WITHIN16 >> MO_ATOM_SHIFT] = "w16+",
2328 [MO_ATOM_WITHIN16_PAIR >> MO_ATOM_SHIFT] = "w16p+",
2329 [MO_ATOM_SUBALIGN >> MO_ATOM_SHIFT] = "sub+",
2330 [MO_ATOM_NONE >> MO_ATOM_SHIFT] = "noat+",
2331};
2332
587195bd
RH
2333static const char bswap_flag_name[][6] = {
2334 [TCG_BSWAP_IZ] = "iz",
2335 [TCG_BSWAP_OZ] = "oz",
2336 [TCG_BSWAP_OS] = "os",
2337 [TCG_BSWAP_IZ | TCG_BSWAP_OZ] = "iz,oz",
2338 [TCG_BSWAP_IZ | TCG_BSWAP_OS] = "iz,os",
2339};
2340
b016486e
RH
2341static inline bool tcg_regset_single(TCGRegSet d)
2342{
2343 return (d & (d - 1)) == 0;
2344}
2345
2346static inline TCGReg tcg_regset_first(TCGRegSet d)
2347{
2348 if (TCG_TARGET_NB_REGS <= 32) {
2349 return ctz32(d);
2350 } else {
2351 return ctz64(d);
2352 }
2353}
2354
b7a83ff8
RH
2355/* Return only the number of characters output -- no error return. */
2356#define ne_fprintf(...) \
2357 ({ int ret_ = fprintf(__VA_ARGS__); ret_ >= 0 ? ret_ : 0; })
2358
2359static void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
c896fe29 2360{
c896fe29 2361 char buf[128];
c45cb8bb 2362 TCGOp *op;
c45cb8bb 2363
15fa08f8 2364 QTAILQ_FOREACH(op, &s->ops, link) {
c45cb8bb
RH
2365 int i, k, nb_oargs, nb_iargs, nb_cargs;
2366 const TCGOpDef *def;
c45cb8bb 2367 TCGOpcode c;
bdfb460e 2368 int col = 0;
c896fe29 2369
c45cb8bb 2370 c = op->opc;
c896fe29 2371 def = &tcg_op_defs[c];
c45cb8bb 2372
765b842a 2373 if (c == INDEX_op_insn_start) {
b016486e 2374 nb_oargs = 0;
b7a83ff8 2375 col += ne_fprintf(f, "\n ----");
9aef40ed
RH
2376
2377 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
c9ad8d27
RH
2378 col += ne_fprintf(f, " %016" PRIx64,
2379 tcg_get_insn_start_param(op, i));
eeacee4d 2380 }
7e4597d7 2381 } else if (c == INDEX_op_call) {
3e92aa34 2382 const TCGHelperInfo *info = tcg_call_info(op);
fa52e660 2383 void *func = tcg_call_func(op);
3e92aa34 2384
c896fe29 2385 /* variable number of arguments */
cd9090aa
RH
2386 nb_oargs = TCGOP_CALLO(op);
2387 nb_iargs = TCGOP_CALLI(op);
c896fe29 2388 nb_cargs = def->nb_cargs;
c896fe29 2389
b7a83ff8 2390 col += ne_fprintf(f, " %s ", def->name);
3e92aa34
RH
2391
2392 /*
2393 * Print the function name from TCGHelperInfo, if available.
2394 * Note that plugins have a template function for the info,
2395 * but the actual function pointer comes from the plugin.
2396 */
3e92aa34 2397 if (func == info->func) {
b7a83ff8 2398 col += ne_fprintf(f, "%s", info->name);
3e92aa34 2399 } else {
b7a83ff8 2400 col += ne_fprintf(f, "plugin(%p)", func);
3e92aa34
RH
2401 }
2402
b7a83ff8 2403 col += ne_fprintf(f, ",$0x%x,$%d", info->flags, nb_oargs);
cf066674 2404 for (i = 0; i < nb_oargs; i++) {
b7a83ff8
RH
2405 col += ne_fprintf(f, ",%s", tcg_get_arg_str(s, buf, sizeof(buf),
2406 op->args[i]));
b03cce8e 2407 }
cf066674 2408 for (i = 0; i < nb_iargs; i++) {
efee3746 2409 TCGArg arg = op->args[nb_oargs + i];
39004a71 2410 const char *t = tcg_get_arg_str(s, buf, sizeof(buf), arg);
b7a83ff8 2411 col += ne_fprintf(f, ",%s", t);
e8996ee0 2412 }
b03cce8e 2413 } else {
b7a83ff8 2414 col += ne_fprintf(f, " %s ", def->name);
c45cb8bb
RH
2415
2416 nb_oargs = def->nb_oargs;
2417 nb_iargs = def->nb_iargs;
2418 nb_cargs = def->nb_cargs;
2419
d2fd745f 2420 if (def->flags & TCG_OPF_VECTOR) {
b7a83ff8
RH
2421 col += ne_fprintf(f, "v%d,e%d,", 64 << TCGOP_VECL(op),
2422 8 << TCGOP_VECE(op));
d2fd745f
RH
2423 }
2424
b03cce8e 2425 k = 0;
c45cb8bb 2426 for (i = 0; i < nb_oargs; i++) {
b7a83ff8
RH
2427 const char *sep = k ? "," : "";
2428 col += ne_fprintf(f, "%s%s", sep,
2429 tcg_get_arg_str(s, buf, sizeof(buf),
2430 op->args[k++]));
b03cce8e 2431 }
c45cb8bb 2432 for (i = 0; i < nb_iargs; i++) {
b7a83ff8
RH
2433 const char *sep = k ? "," : "";
2434 col += ne_fprintf(f, "%s%s", sep,
2435 tcg_get_arg_str(s, buf, sizeof(buf),
2436 op->args[k++]));
b03cce8e 2437 }
be210acb
RH
2438 switch (c) {
2439 case INDEX_op_brcond_i32:
be210acb 2440 case INDEX_op_setcond_i32:
ffc5ea09 2441 case INDEX_op_movcond_i32:
ffc5ea09 2442 case INDEX_op_brcond2_i32:
be210acb 2443 case INDEX_op_setcond2_i32:
ffc5ea09 2444 case INDEX_op_brcond_i64:
be210acb 2445 case INDEX_op_setcond_i64:
ffc5ea09 2446 case INDEX_op_movcond_i64:
212be173 2447 case INDEX_op_cmp_vec:
f75da298 2448 case INDEX_op_cmpsel_vec:
efee3746
RH
2449 if (op->args[k] < ARRAY_SIZE(cond_name)
2450 && cond_name[op->args[k]]) {
b7a83ff8 2451 col += ne_fprintf(f, ",%s", cond_name[op->args[k++]]);
eeacee4d 2452 } else {
b7a83ff8 2453 col += ne_fprintf(f, ",$0x%" TCG_PRIlx, op->args[k++]);
eeacee4d 2454 }
f48f3ede 2455 i = 1;
be210acb 2456 break;
fecccfcc
RH
2457 case INDEX_op_qemu_ld_a32_i32:
2458 case INDEX_op_qemu_ld_a64_i32:
2459 case INDEX_op_qemu_st_a32_i32:
2460 case INDEX_op_qemu_st_a64_i32:
2461 case INDEX_op_qemu_st8_a32_i32:
2462 case INDEX_op_qemu_st8_a64_i32:
2463 case INDEX_op_qemu_ld_a32_i64:
2464 case INDEX_op_qemu_ld_a64_i64:
2465 case INDEX_op_qemu_st_a32_i64:
2466 case INDEX_op_qemu_st_a64_i64:
2467 case INDEX_op_qemu_ld_a32_i128:
2468 case INDEX_op_qemu_ld_a64_i128:
2469 case INDEX_op_qemu_st_a32_i128:
2470 case INDEX_op_qemu_st_a64_i128:
59227d5d 2471 {
37031fef 2472 const char *s_al, *s_op, *s_at;
9002ffcb 2473 MemOpIdx oi = op->args[k++];
14776ab5 2474 MemOp op = get_memop(oi);
59227d5d
RH
2475 unsigned ix = get_mmuidx(oi);
2476
37031fef
RH
2477 s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT];
2478 s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];
2479 s_at = atom_name[(op & MO_ATOM_MASK) >> MO_ATOM_SHIFT];
2480 op &= ~(MO_AMASK | MO_BSWAP | MO_SSIZE | MO_ATOM_MASK);
2481
2482 /* If all fields are accounted for, print symbolically. */
2483 if (!op && s_al && s_op && s_at) {
2484 col += ne_fprintf(f, ",%s%s%s,%u",
2485 s_at, s_al, s_op, ix);
59c4b7e8 2486 } else {
37031fef
RH
2487 op = get_memop(oi);
2488 col += ne_fprintf(f, ",$0x%x,%u", op, ix);
59227d5d
RH
2489 }
2490 i = 1;
f713d6ad 2491 }
f713d6ad 2492 break;
587195bd
RH
2493 case INDEX_op_bswap16_i32:
2494 case INDEX_op_bswap16_i64:
2495 case INDEX_op_bswap32_i32:
2496 case INDEX_op_bswap32_i64:
2497 case INDEX_op_bswap64_i64:
2498 {
2499 TCGArg flags = op->args[k];
2500 const char *name = NULL;
2501
2502 if (flags < ARRAY_SIZE(bswap_flag_name)) {
2503 name = bswap_flag_name[flags];
2504 }
2505 if (name) {
b7a83ff8 2506 col += ne_fprintf(f, ",%s", name);
587195bd 2507 } else {
b7a83ff8 2508 col += ne_fprintf(f, ",$0x%" TCG_PRIlx, flags);
587195bd
RH
2509 }
2510 i = k = 1;
2511 }
2512 break;
be210acb 2513 default:
f48f3ede 2514 i = 0;
be210acb
RH
2515 break;
2516 }
51e3972c
RH
2517 switch (c) {
2518 case INDEX_op_set_label:
2519 case INDEX_op_br:
2520 case INDEX_op_brcond_i32:
2521 case INDEX_op_brcond_i64:
2522 case INDEX_op_brcond2_i32:
b7a83ff8
RH
2523 col += ne_fprintf(f, "%s$L%d", k ? "," : "",
2524 arg_label(op->args[k])->id);
51e3972c
RH
2525 i++, k++;
2526 break;
3470867b
RH
2527 case INDEX_op_mb:
2528 {
2529 TCGBar membar = op->args[k];
2530 const char *b_op, *m_op;
2531
2532 switch (membar & TCG_BAR_SC) {
2533 case 0:
2534 b_op = "none";
2535 break;
2536 case TCG_BAR_LDAQ:
2537 b_op = "acq";
2538 break;
2539 case TCG_BAR_STRL:
2540 b_op = "rel";
2541 break;
2542 case TCG_BAR_SC:
2543 b_op = "seq";
2544 break;
2545 default:
2546 g_assert_not_reached();
2547 }
2548
2549 switch (membar & TCG_MO_ALL) {
2550 case 0:
2551 m_op = "none";
2552 break;
2553 case TCG_MO_LD_LD:
2554 m_op = "rr";
2555 break;
2556 case TCG_MO_LD_ST:
2557 m_op = "rw";
2558 break;
2559 case TCG_MO_ST_LD:
2560 m_op = "wr";
2561 break;
2562 case TCG_MO_ST_ST:
2563 m_op = "ww";
2564 break;
2565 case TCG_MO_LD_LD | TCG_MO_LD_ST:
2566 m_op = "rr+rw";
2567 break;
2568 case TCG_MO_LD_LD | TCG_MO_ST_LD:
2569 m_op = "rr+wr";
2570 break;
2571 case TCG_MO_LD_LD | TCG_MO_ST_ST:
2572 m_op = "rr+ww";
2573 break;
2574 case TCG_MO_LD_ST | TCG_MO_ST_LD:
2575 m_op = "rw+wr";
2576 break;
2577 case TCG_MO_LD_ST | TCG_MO_ST_ST:
2578 m_op = "rw+ww";
2579 break;
2580 case TCG_MO_ST_LD | TCG_MO_ST_ST:
2581 m_op = "wr+ww";
2582 break;
2583 case TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_LD:
2584 m_op = "rr+rw+wr";
2585 break;
2586 case TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST:
2587 m_op = "rr+rw+ww";
2588 break;
2589 case TCG_MO_LD_LD | TCG_MO_ST_LD | TCG_MO_ST_ST:
2590 m_op = "rr+wr+ww";
2591 break;
2592 case TCG_MO_LD_ST | TCG_MO_ST_LD | TCG_MO_ST_ST:
2593 m_op = "rw+wr+ww";
2594 break;
2595 case TCG_MO_ALL:
2596 m_op = "all";
2597 break;
2598 default:
2599 g_assert_not_reached();
2600 }
2601
2602 col += ne_fprintf(f, "%s%s:%s", (k ? "," : ""), b_op, m_op);
2603 i++, k++;
2604 }
2605 break;
51e3972c
RH
2606 default:
2607 break;
2608 }
2609 for (; i < nb_cargs; i++, k++) {
b7a83ff8
RH
2610 col += ne_fprintf(f, "%s$0x%" TCG_PRIlx, k ? "," : "",
2611 op->args[k]);
bdfb460e
RH
2612 }
2613 }
bdfb460e 2614
1894f69a 2615 if (have_prefs || op->life) {
b7a83ff8
RH
2616 for (; col < 40; ++col) {
2617 putc(' ', f);
bdfb460e 2618 }
1894f69a
RH
2619 }
2620
2621 if (op->life) {
2622 unsigned life = op->life;
bdfb460e
RH
2623
2624 if (life & (SYNC_ARG * 3)) {
b7a83ff8 2625 ne_fprintf(f, " sync:");
bdfb460e
RH
2626 for (i = 0; i < 2; ++i) {
2627 if (life & (SYNC_ARG << i)) {
b7a83ff8 2628 ne_fprintf(f, " %d", i);
bdfb460e
RH
2629 }
2630 }
2631 }
2632 life /= DEAD_ARG;
2633 if (life) {
b7a83ff8 2634 ne_fprintf(f, " dead:");
bdfb460e
RH
2635 for (i = 0; life; ++i, life >>= 1) {
2636 if (life & 1) {
b7a83ff8 2637 ne_fprintf(f, " %d", i);
bdfb460e
RH
2638 }
2639 }
b03cce8e 2640 }
c896fe29 2641 }
1894f69a
RH
2642
2643 if (have_prefs) {
2644 for (i = 0; i < nb_oargs; ++i) {
31fd884b 2645 TCGRegSet set = output_pref(op, i);
1894f69a
RH
2646
2647 if (i == 0) {
b7a83ff8 2648 ne_fprintf(f, " pref=");
1894f69a 2649 } else {
b7a83ff8 2650 ne_fprintf(f, ",");
1894f69a
RH
2651 }
2652 if (set == 0) {
b7a83ff8 2653 ne_fprintf(f, "none");
1894f69a 2654 } else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) {
b7a83ff8 2655 ne_fprintf(f, "all");
1894f69a
RH
2656#ifdef CONFIG_DEBUG_TCG
2657 } else if (tcg_regset_single(set)) {
2658 TCGReg reg = tcg_regset_first(set);
b7a83ff8 2659 ne_fprintf(f, "%s", tcg_target_reg_names[reg]);
1894f69a
RH
2660#endif
2661 } else if (TCG_TARGET_NB_REGS <= 32) {
b7a83ff8 2662 ne_fprintf(f, "0x%x", (uint32_t)set);
1894f69a 2663 } else {
b7a83ff8 2664 ne_fprintf(f, "0x%" PRIx64, (uint64_t)set);
1894f69a
RH
2665 }
2666 }
2667 }
2668
b7a83ff8 2669 putc('\n', f);
c896fe29
FB
2670 }
2671}
2672
2673/* we give more priority to constraints with less registers */
2674static int get_constraint_priority(const TCGOpDef *def, int k)
2675{
74a11790 2676 const TCGArgConstraint *arg_ct = &def->args_ct[k];
29f5e925 2677 int n = ctpop64(arg_ct->regs);
c896fe29 2678
29f5e925
RH
2679 /*
2680 * Sort constraints of a single register first, which includes output
2681 * aliases (which must exactly match the input already allocated).
2682 */
2683 if (n == 1 || arg_ct->oalias) {
2684 return INT_MAX;
2685 }
2686
2687 /*
2688 * Sort register pairs next, first then second immediately after.
2689 * Arbitrarily sort multiple pairs by the index of the first reg;
2690 * there shouldn't be many pairs.
2691 */
2692 switch (arg_ct->pair) {
2693 case 1:
2694 case 3:
2695 return (k + 1) * 2;
2696 case 2:
2697 return (arg_ct->pair_index + 1) * 2 - 1;
c896fe29 2698 }
29f5e925
RH
2699
2700 /* Finally, sort by decreasing register count. */
2701 assert(n > 1);
2702 return -n;
c896fe29
FB
2703}
2704
2705/* sort from highest priority to lowest */
2706static void sort_constraints(TCGOpDef *def, int start, int n)
2707{
66792f90
RH
2708 int i, j;
2709 TCGArgConstraint *a = def->args_ct;
c896fe29 2710
66792f90
RH
2711 for (i = 0; i < n; i++) {
2712 a[start + i].sort_index = start + i;
2713 }
2714 if (n <= 1) {
c896fe29 2715 return;
66792f90
RH
2716 }
2717 for (i = 0; i < n - 1; i++) {
2718 for (j = i + 1; j < n; j++) {
2719 int p1 = get_constraint_priority(def, a[start + i].sort_index);
2720 int p2 = get_constraint_priority(def, a[start + j].sort_index);
c896fe29 2721 if (p1 < p2) {
66792f90
RH
2722 int tmp = a[start + i].sort_index;
2723 a[start + i].sort_index = a[start + j].sort_index;
2724 a[start + j].sort_index = tmp;
c896fe29
FB
2725 }
2726 }
2727 }
2728}
2729
f69d277e 2730static void process_op_defs(TCGContext *s)
c896fe29 2731{
a9751609 2732 TCGOpcode op;
c896fe29 2733
f69d277e
RH
2734 for (op = 0; op < NB_OPS; op++) {
2735 TCGOpDef *def = &tcg_op_defs[op];
2736 const TCGTargetOpDef *tdefs;
29f5e925
RH
2737 bool saw_alias_pair = false;
2738 int i, o, i2, o2, nb_args;
f69d277e
RH
2739
2740 if (def->flags & TCG_OPF_NOT_PRESENT) {
2741 continue;
2742 }
2743
c896fe29 2744 nb_args = def->nb_iargs + def->nb_oargs;
f69d277e
RH
2745 if (nb_args == 0) {
2746 continue;
2747 }
2748
4c22e840
RH
2749 /*
2750 * Macro magic should make it impossible, but double-check that
2751 * the array index is in range. Since the signness of an enum
2752 * is implementation defined, force the result to unsigned.
2753 */
2754 unsigned con_set = tcg_target_op_def(op);
2755 tcg_debug_assert(con_set < ARRAY_SIZE(constraint_sets));
2756 tdefs = &constraint_sets[con_set];
f69d277e
RH
2757
2758 for (i = 0; i < nb_args; i++) {
2759 const char *ct_str = tdefs->args_ct_str[i];
8940ea0d
PMD
2760 bool input_p = i >= def->nb_oargs;
2761
f69d277e 2762 /* Incomplete TCGTargetOpDef entry. */
eabb7b91 2763 tcg_debug_assert(ct_str != NULL);
f69d277e 2764
8940ea0d
PMD
2765 switch (*ct_str) {
2766 case '0' ... '9':
2767 o = *ct_str - '0';
2768 tcg_debug_assert(input_p);
2769 tcg_debug_assert(o < def->nb_oargs);
2770 tcg_debug_assert(def->args_ct[o].regs != 0);
2771 tcg_debug_assert(!def->args_ct[o].oalias);
2772 def->args_ct[i] = def->args_ct[o];
2773 /* The output sets oalias. */
2774 def->args_ct[o].oalias = 1;
2775 def->args_ct[o].alias_index = i;
2776 /* The input sets ialias. */
2777 def->args_ct[i].ialias = 1;
2778 def->args_ct[i].alias_index = o;
29f5e925
RH
2779 if (def->args_ct[i].pair) {
2780 saw_alias_pair = true;
2781 }
8940ea0d
PMD
2782 tcg_debug_assert(ct_str[1] == '\0');
2783 continue;
2784
2785 case '&':
2786 tcg_debug_assert(!input_p);
2787 def->args_ct[i].newreg = true;
2788 ct_str++;
2789 break;
29f5e925
RH
2790
2791 case 'p': /* plus */
2792 /* Allocate to the register after the previous. */
2793 tcg_debug_assert(i > (input_p ? def->nb_oargs : 0));
2794 o = i - 1;
2795 tcg_debug_assert(!def->args_ct[o].pair);
2796 tcg_debug_assert(!def->args_ct[o].ct);
2797 def->args_ct[i] = (TCGArgConstraint){
2798 .pair = 2,
2799 .pair_index = o,
2800 .regs = def->args_ct[o].regs << 1,
2801 };
2802 def->args_ct[o].pair = 1;
2803 def->args_ct[o].pair_index = i;
2804 tcg_debug_assert(ct_str[1] == '\0');
2805 continue;
2806
2807 case 'm': /* minus */
2808 /* Allocate to the register before the previous. */
2809 tcg_debug_assert(i > (input_p ? def->nb_oargs : 0));
2810 o = i - 1;
2811 tcg_debug_assert(!def->args_ct[o].pair);
2812 tcg_debug_assert(!def->args_ct[o].ct);
2813 def->args_ct[i] = (TCGArgConstraint){
2814 .pair = 1,
2815 .pair_index = o,
2816 .regs = def->args_ct[o].regs >> 1,
2817 };
2818 def->args_ct[o].pair = 2;
2819 def->args_ct[o].pair_index = i;
2820 tcg_debug_assert(ct_str[1] == '\0');
2821 continue;
8940ea0d
PMD
2822 }
2823
2824 do {
2825 switch (*ct_str) {
17280ff4
RH
2826 case 'i':
2827 def->args_ct[i].ct |= TCG_CT_CONST;
17280ff4 2828 break;
358b4923 2829
358b4923
RH
2830 /* Include all of the target-specific constraints. */
2831
2832#undef CONST
2833#define CONST(CASE, MASK) \
8940ea0d 2834 case CASE: def->args_ct[i].ct |= MASK; break;
358b4923 2835#define REGS(CASE, MASK) \
8940ea0d 2836 case CASE: def->args_ct[i].regs |= MASK; break;
358b4923
RH
2837
2838#include "tcg-target-con-str.h"
2839
2840#undef REGS
2841#undef CONST
17280ff4 2842 default:
8940ea0d
PMD
2843 case '0' ... '9':
2844 case '&':
29f5e925
RH
2845 case 'p':
2846 case 'm':
17280ff4 2847 /* Typo in TCGTargetOpDef constraint. */
358b4923 2848 g_assert_not_reached();
c896fe29 2849 }
8940ea0d 2850 } while (*++ct_str != '\0');
c896fe29
FB
2851 }
2852
c68aaa18 2853 /* TCGTargetOpDef entry with too much information? */
eabb7b91 2854 tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
c68aaa18 2855
29f5e925
RH
2856 /*
2857 * Fix up output pairs that are aliased with inputs.
2858 * When we created the alias, we copied pair from the output.
2859 * There are three cases:
2860 * (1a) Pairs of inputs alias pairs of outputs.
2861 * (1b) One input aliases the first of a pair of outputs.
2862 * (2) One input aliases the second of a pair of outputs.
2863 *
2864 * Case 1a is handled by making sure that the pair_index'es are
2865 * properly updated so that they appear the same as a pair of inputs.
2866 *
2867 * Case 1b is handled by setting the pair_index of the input to
2868 * itself, simply so it doesn't point to an unrelated argument.
2869 * Since we don't encounter the "second" during the input allocation
2870 * phase, nothing happens with the second half of the input pair.
2871 *
2872 * Case 2 is handled by setting the second input to pair=3, the
2873 * first output to pair=3, and the pair_index'es to match.
2874 */
2875 if (saw_alias_pair) {
2876 for (i = def->nb_oargs; i < nb_args; i++) {
2877 /*
2878 * Since [0-9pm] must be alone in the constraint string,
2879 * the only way they can both be set is if the pair comes
2880 * from the output alias.
2881 */
2882 if (!def->args_ct[i].ialias) {
2883 continue;
2884 }
2885 switch (def->args_ct[i].pair) {
2886 case 0:
2887 break;
2888 case 1:
2889 o = def->args_ct[i].alias_index;
2890 o2 = def->args_ct[o].pair_index;
2891 tcg_debug_assert(def->args_ct[o].pair == 1);
2892 tcg_debug_assert(def->args_ct[o2].pair == 2);
2893 if (def->args_ct[o2].oalias) {
2894 /* Case 1a */
2895 i2 = def->args_ct[o2].alias_index;
2896 tcg_debug_assert(def->args_ct[i2].pair == 2);
2897 def->args_ct[i2].pair_index = i;
2898 def->args_ct[i].pair_index = i2;
2899 } else {
2900 /* Case 1b */
2901 def->args_ct[i].pair_index = i;
2902 }
2903 break;
2904 case 2:
2905 o = def->args_ct[i].alias_index;
2906 o2 = def->args_ct[o].pair_index;
2907 tcg_debug_assert(def->args_ct[o].pair == 2);
2908 tcg_debug_assert(def->args_ct[o2].pair == 1);
2909 if (def->args_ct[o2].oalias) {
2910 /* Case 1a */
2911 i2 = def->args_ct[o2].alias_index;
2912 tcg_debug_assert(def->args_ct[i2].pair == 1);
2913 def->args_ct[i2].pair_index = i;
2914 def->args_ct[i].pair_index = i2;
2915 } else {
2916 /* Case 2 */
2917 def->args_ct[i].pair = 3;
2918 def->args_ct[o2].pair = 3;
2919 def->args_ct[i].pair_index = o2;
2920 def->args_ct[o2].pair_index = i;
2921 }
2922 break;
2923 default:
2924 g_assert_not_reached();
2925 }
2926 }
2927 }
2928
c896fe29
FB
2929 /* sort the constraints (XXX: this is just an heuristic) */
2930 sort_constraints(def, 0, def->nb_oargs);
2931 sort_constraints(def, def->nb_oargs, def->nb_iargs);
a9751609 2932 }
c896fe29
FB
2933}
2934
f85b1fc4 2935static void remove_label_use(TCGOp *op, int idx)
0c627cdc 2936{
f85b1fc4
RH
2937 TCGLabel *label = arg_label(op->args[idx]);
2938 TCGLabelUse *use;
d88a117e 2939
f85b1fc4
RH
2940 QSIMPLEQ_FOREACH(use, &label->branches, next) {
2941 if (use->op == op) {
2942 QSIMPLEQ_REMOVE(&label->branches, use, TCGLabelUse, next);
2943 return;
2944 }
2945 }
2946 g_assert_not_reached();
2947}
2948
2949void tcg_op_remove(TCGContext *s, TCGOp *op)
2950{
d88a117e
RH
2951 switch (op->opc) {
2952 case INDEX_op_br:
f85b1fc4 2953 remove_label_use(op, 0);
d88a117e
RH
2954 break;
2955 case INDEX_op_brcond_i32:
2956 case INDEX_op_brcond_i64:
f85b1fc4 2957 remove_label_use(op, 3);
d88a117e
RH
2958 break;
2959 case INDEX_op_brcond2_i32:
f85b1fc4 2960 remove_label_use(op, 5);
d88a117e
RH
2961 break;
2962 default:
2963 break;
2964 }
2965
15fa08f8
RH
2966 QTAILQ_REMOVE(&s->ops, op, link);
2967 QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
abebf925 2968 s->nb_ops--;
0c627cdc
RH
2969
2970#ifdef CONFIG_PROFILER
d73415a3 2971 qatomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
0c627cdc
RH
2972#endif
2973}
2974
a80cdd31
RH
2975void tcg_remove_ops_after(TCGOp *op)
2976{
2977 TCGContext *s = tcg_ctx;
2978
2979 while (true) {
2980 TCGOp *last = tcg_last_op();
2981 if (last == op) {
2982 return;
2983 }
2984 tcg_op_remove(s, last);
2985 }
2986}
2987
d4478943 2988static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
5a18407f 2989{
15fa08f8 2990 TCGContext *s = tcg_ctx;
cb10bc63
RH
2991 TCGOp *op = NULL;
2992
2993 if (unlikely(!QTAILQ_EMPTY(&s->free_ops))) {
2994 QTAILQ_FOREACH(op, &s->free_ops, link) {
2995 if (nargs <= op->nargs) {
2996 QTAILQ_REMOVE(&s->free_ops, op, link);
2997 nargs = op->nargs;
2998 goto found;
2999 }
3000 }
15fa08f8 3001 }
cb10bc63
RH
3002
3003 /* Most opcodes have 3 or 4 operands: reduce fragmentation. */
3004 nargs = MAX(4, nargs);
3005 op = tcg_malloc(sizeof(TCGOp) + sizeof(TCGArg) * nargs);
3006
3007 found:
15fa08f8
RH
3008 memset(op, 0, offsetof(TCGOp, link));
3009 op->opc = opc;
cb10bc63
RH
3010 op->nargs = nargs;
3011
3012 /* Check for bitfield overflow. */
3013 tcg_debug_assert(op->nargs == nargs);
5a18407f 3014
cb10bc63 3015 s->nb_ops++;
15fa08f8
RH
3016 return op;
3017}
3018
d4478943 3019TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs)
15fa08f8 3020{
d4478943 3021 TCGOp *op = tcg_op_alloc(opc, nargs);
15fa08f8
RH
3022 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
3023 return op;
3024}
5a18407f 3025
d4478943
PMD
3026TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
3027 TCGOpcode opc, unsigned nargs)
15fa08f8 3028{
d4478943 3029 TCGOp *new_op = tcg_op_alloc(opc, nargs);
15fa08f8 3030 QTAILQ_INSERT_BEFORE(old_op, new_op, link);
5a18407f
RH
3031 return new_op;
3032}
3033
d4478943
PMD
3034TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
3035 TCGOpcode opc, unsigned nargs)
5a18407f 3036{
d4478943 3037 TCGOp *new_op = tcg_op_alloc(opc, nargs);
15fa08f8 3038 QTAILQ_INSERT_AFTER(&s->ops, old_op, new_op, link);
5a18407f
RH
3039 return new_op;
3040}
3041
968f305e
RH
3042static void move_label_uses(TCGLabel *to, TCGLabel *from)
3043{
3044 TCGLabelUse *u;
3045
3046 QSIMPLEQ_FOREACH(u, &from->branches, next) {
3047 TCGOp *op = u->op;
3048 switch (op->opc) {
3049 case INDEX_op_br:
3050 op->args[0] = label_arg(to);
3051 break;
3052 case INDEX_op_brcond_i32:
3053 case INDEX_op_brcond_i64:
3054 op->args[3] = label_arg(to);
3055 break;
3056 case INDEX_op_brcond2_i32:
3057 op->args[5] = label_arg(to);
3058 break;
3059 default:
3060 g_assert_not_reached();
3061 }
3062 }
3063
3064 QSIMPLEQ_CONCAT(&to->branches, &from->branches);
3065}
3066
b4fc67c7 3067/* Reachable analysis : remove unreachable code. */
9bbee4c0
RH
3068static void __attribute__((noinline))
3069reachable_code_pass(TCGContext *s)
b4fc67c7 3070{
4d89d0bb 3071 TCGOp *op, *op_next, *op_prev;
b4fc67c7
RH
3072 bool dead = false;
3073
3074 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
3075 bool remove = dead;
3076 TCGLabel *label;
b4fc67c7
RH
3077
3078 switch (op->opc) {
3079 case INDEX_op_set_label:
3080 label = arg_label(op->args[0]);
4d89d0bb 3081
968f305e
RH
3082 /*
3083 * Note that the first op in the TB is always a load,
3084 * so there is always something before a label.
3085 */
3086 op_prev = QTAILQ_PREV(op, link);
3087
3088 /*
3089 * If we find two sequential labels, move all branches to
3090 * reference the second label and remove the first label.
3091 * Do this before branch to next optimization, so that the
3092 * middle label is out of the way.
3093 */
3094 if (op_prev->opc == INDEX_op_set_label) {
3095 move_label_uses(label, arg_label(op_prev->args[0]));
3096 tcg_op_remove(s, op_prev);
3097 op_prev = QTAILQ_PREV(op, link);
3098 }
3099
4d89d0bb
RH
3100 /*
3101 * Optimization can fold conditional branches to unconditional.
3102 * If we find a label which is preceded by an unconditional
3103 * branch to next, remove the branch. We couldn't do this when
3104 * processing the branch because any dead code between the branch
3105 * and label had not yet been removed.
3106 */
4d89d0bb
RH
3107 if (op_prev->opc == INDEX_op_br &&
3108 label == arg_label(op_prev->args[0])) {
3109 tcg_op_remove(s, op_prev);
3110 /* Fall through means insns become live again. */
3111 dead = false;
3112 }
3113
f85b1fc4 3114 if (QSIMPLEQ_EMPTY(&label->branches)) {
b4fc67c7
RH
3115 /*
3116 * While there is an occasional backward branch, virtually
3117 * all branches generated by the translators are forward.
3118 * Which means that generally we will have already removed
3119 * all references to the label that will be, and there is
3120 * little to be gained by iterating.
3121 */
3122 remove = true;
3123 } else {
3124 /* Once we see a label, insns become live again. */
3125 dead = false;
3126 remove = false;
b4fc67c7
RH
3127 }
3128 break;
3129
3130 case INDEX_op_br:
3131 case INDEX_op_exit_tb:
3132 case INDEX_op_goto_ptr:
3133 /* Unconditional branches; everything following is dead. */
3134 dead = true;
3135 break;
3136
3137 case INDEX_op_call:
3138 /* Notice noreturn helper calls, raising exceptions. */
90163900 3139 if (tcg_call_flags(op) & TCG_CALL_NO_RETURN) {
b4fc67c7
RH
3140 dead = true;
3141 }
3142 break;
3143
3144 case INDEX_op_insn_start:
3145 /* Never remove -- we need to keep these for unwind. */
3146 remove = false;
3147 break;
3148
3149 default:
3150 break;
3151 }
3152
3153 if (remove) {
3154 tcg_op_remove(s, op);
3155 }
3156 }
3157}
3158
c70fbf0a
RH
3159#define TS_DEAD 1
3160#define TS_MEM 2
3161
5a18407f
RH
3162#define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
3163#define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
3164
25f49c5f
RH
3165/* For liveness_pass_1, the register preferences for a given temp. */
3166static inline TCGRegSet *la_temp_pref(TCGTemp *ts)
3167{
3168 return ts->state_ptr;
3169}
3170
3171/* For liveness_pass_1, reset the preferences for a given temp to the
3172 * maximal regset for its type.
3173 */
3174static inline void la_reset_pref(TCGTemp *ts)
3175{
3176 *la_temp_pref(ts)
3177 = (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]);
3178}
3179
9c43b68d
AJ
3180/* liveness analysis: end of function: all temps are dead, and globals
3181 should be in memory. */
2616c808 3182static void la_func_end(TCGContext *s, int ng, int nt)
c896fe29 3183{
b83eabea
RH
3184 int i;
3185
3186 for (i = 0; i < ng; ++i) {
3187 s->temps[i].state = TS_DEAD | TS_MEM;
25f49c5f 3188 la_reset_pref(&s->temps[i]);
b83eabea
RH
3189 }
3190 for (i = ng; i < nt; ++i) {
3191 s->temps[i].state = TS_DEAD;
25f49c5f 3192 la_reset_pref(&s->temps[i]);
b83eabea 3193 }
c896fe29
FB
3194}
3195
9c43b68d
AJ
3196/* liveness analysis: end of basic block: all temps are dead, globals
3197 and local temps should be in memory. */
2616c808 3198static void la_bb_end(TCGContext *s, int ng, int nt)
641d5fbe 3199{
b83eabea 3200 int i;
641d5fbe 3201
ee17db83
RH
3202 for (i = 0; i < nt; ++i) {
3203 TCGTemp *ts = &s->temps[i];
3204 int state;
3205
3206 switch (ts->kind) {
3207 case TEMP_FIXED:
3208 case TEMP_GLOBAL:
f57c6915 3209 case TEMP_TB:
ee17db83
RH
3210 state = TS_DEAD | TS_MEM;
3211 break;
c7482438 3212 case TEMP_EBB:
c0522136 3213 case TEMP_CONST:
ee17db83
RH
3214 state = TS_DEAD;
3215 break;
3216 default:
3217 g_assert_not_reached();
3218 }
3219 ts->state = state;
3220 la_reset_pref(ts);
641d5fbe
FB
3221 }
3222}
3223
f65a061c
RH
3224/* liveness analysis: sync globals back to memory. */
3225static void la_global_sync(TCGContext *s, int ng)
3226{
3227 int i;
3228
3229 for (i = 0; i < ng; ++i) {
25f49c5f
RH
3230 int state = s->temps[i].state;
3231 s->temps[i].state = state | TS_MEM;
3232 if (state == TS_DEAD) {
3233 /* If the global was previously dead, reset prefs. */
3234 la_reset_pref(&s->temps[i]);
3235 }
f65a061c
RH
3236 }
3237}
3238
b4cb76e6 3239/*
c7482438
RH
3240 * liveness analysis: conditional branch: all temps are dead unless
3241 * explicitly live-across-conditional-branch, globals and local temps
3242 * should be synced.
b4cb76e6
RH
3243 */
3244static void la_bb_sync(TCGContext *s, int ng, int nt)
3245{
3246 la_global_sync(s, ng);
3247
3248 for (int i = ng; i < nt; ++i) {
c0522136
RH
3249 TCGTemp *ts = &s->temps[i];
3250 int state;
3251
3252 switch (ts->kind) {
f57c6915 3253 case TEMP_TB:
c0522136
RH
3254 state = ts->state;
3255 ts->state = state | TS_MEM;
b4cb76e6
RH
3256 if (state != TS_DEAD) {
3257 continue;
3258 }
c0522136 3259 break;
c7482438 3260 case TEMP_EBB:
c0522136
RH
3261 case TEMP_CONST:
3262 continue;
3263 default:
3264 g_assert_not_reached();
b4cb76e6
RH
3265 }
3266 la_reset_pref(&s->temps[i]);
3267 }
3268}
3269
f65a061c
RH
3270/* liveness analysis: sync globals back to memory and kill. */
3271static void la_global_kill(TCGContext *s, int ng)
3272{
3273 int i;
3274
3275 for (i = 0; i < ng; i++) {
3276 s->temps[i].state = TS_DEAD | TS_MEM;
25f49c5f
RH
3277 la_reset_pref(&s->temps[i]);
3278 }
3279}
3280
3281/* liveness analysis: note live globals crossing calls. */
3282static void la_cross_call(TCGContext *s, int nt)
3283{
3284 TCGRegSet mask = ~tcg_target_call_clobber_regs;
3285 int i;
3286
3287 for (i = 0; i < nt; i++) {
3288 TCGTemp *ts = &s->temps[i];
3289 if (!(ts->state & TS_DEAD)) {
3290 TCGRegSet *pset = la_temp_pref(ts);
3291 TCGRegSet set = *pset;
3292
3293 set &= mask;
3294 /* If the combination is not possible, restart. */
3295 if (set == 0) {
3296 set = tcg_target_available_regs[ts->type] & mask;
3297 }
3298 *pset = set;
3299 }
f65a061c
RH
3300 }
3301}
3302
874b8574
RH
3303/*
3304 * Liveness analysis: Verify the lifetime of TEMP_TB, and reduce
3305 * to TEMP_EBB, if possible.
3306 */
3307static void __attribute__((noinline))
3308liveness_pass_0(TCGContext *s)
3309{
3310 void * const multiple_ebb = (void *)(uintptr_t)-1;
3311 int nb_temps = s->nb_temps;
3312 TCGOp *op, *ebb;
3313
3314 for (int i = s->nb_globals; i < nb_temps; ++i) {
3315 s->temps[i].state_ptr = NULL;
3316 }
3317
3318 /*
3319 * Represent each EBB by the op at which it begins. In the case of
3320 * the first EBB, this is the first op, otherwise it is a label.
3321 * Collect the uses of each TEMP_TB: NULL for unused, EBB for use
3322 * within a single EBB, else MULTIPLE_EBB.
3323 */
3324 ebb = QTAILQ_FIRST(&s->ops);
3325 QTAILQ_FOREACH(op, &s->ops, link) {
3326 const TCGOpDef *def;
3327 int nb_oargs, nb_iargs;
3328
3329 switch (op->opc) {
3330 case INDEX_op_set_label:
3331 ebb = op;
3332 continue;
3333 case INDEX_op_discard:
3334 continue;
3335 case INDEX_op_call:
3336 nb_oargs = TCGOP_CALLO(op);
3337 nb_iargs = TCGOP_CALLI(op);
3338 break;
3339 default:
3340 def = &tcg_op_defs[op->opc];
3341 nb_oargs = def->nb_oargs;
3342 nb_iargs = def->nb_iargs;
3343 break;
3344 }
3345
3346 for (int i = 0; i < nb_oargs + nb_iargs; ++i) {
3347 TCGTemp *ts = arg_temp(op->args[i]);
3348
3349 if (ts->kind != TEMP_TB) {
3350 continue;
3351 }
3352 if (ts->state_ptr == NULL) {
3353 ts->state_ptr = ebb;
3354 } else if (ts->state_ptr != ebb) {
3355 ts->state_ptr = multiple_ebb;
3356 }
3357 }
3358 }
3359
3360 /*
3361 * For TEMP_TB that turned out not to be used beyond one EBB,
3362 * reduce the liveness to TEMP_EBB.
3363 */
3364 for (int i = s->nb_globals; i < nb_temps; ++i) {
3365 TCGTemp *ts = &s->temps[i];
3366 if (ts->kind == TEMP_TB && ts->state_ptr != multiple_ebb) {
3367 ts->kind = TEMP_EBB;
3368 }
3369 }
3370}
3371
a1b3c48d 3372/* Liveness analysis : update the opc_arg_life array to tell if a
c896fe29
FB
3373 given input arguments is dead. Instructions updating dead
3374 temporaries are removed. */
9bbee4c0
RH
3375static void __attribute__((noinline))
3376liveness_pass_1(TCGContext *s)
c896fe29 3377{
c70fbf0a 3378 int nb_globals = s->nb_globals;
2616c808 3379 int nb_temps = s->nb_temps;
15fa08f8 3380 TCGOp *op, *op_prev;
25f49c5f
RH
3381 TCGRegSet *prefs;
3382 int i;
3383
3384 prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps);
3385 for (i = 0; i < nb_temps; ++i) {
3386 s->temps[i].state_ptr = prefs + i;
3387 }
a1b3c48d 3388
ae36a246 3389 /* ??? Should be redundant with the exit_tb that ends the TB. */
2616c808 3390 la_func_end(s, nb_globals, nb_temps);
c896fe29 3391
eae3eb3e 3392 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, link, op_prev) {
25f49c5f 3393 int nb_iargs, nb_oargs;
c45cb8bb
RH
3394 TCGOpcode opc_new, opc_new2;
3395 bool have_opc_new2;
a1b3c48d 3396 TCGLifeData arg_life = 0;
25f49c5f 3397 TCGTemp *ts;
c45cb8bb
RH
3398 TCGOpcode opc = op->opc;
3399 const TCGOpDef *def = &tcg_op_defs[opc];
3400
c45cb8bb 3401 switch (opc) {
c896fe29 3402 case INDEX_op_call:
c6e113f5 3403 {
39004a71
RH
3404 const TCGHelperInfo *info = tcg_call_info(op);
3405 int call_flags = tcg_call_flags(op);
c896fe29 3406
cd9090aa
RH
3407 nb_oargs = TCGOP_CALLO(op);
3408 nb_iargs = TCGOP_CALLI(op);
c6e113f5 3409
c45cb8bb 3410 /* pure functions can be removed if their result is unused */
78505279 3411 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
cf066674 3412 for (i = 0; i < nb_oargs; i++) {
25f49c5f
RH
3413 ts = arg_temp(op->args[i]);
3414 if (ts->state != TS_DEAD) {
c6e113f5 3415 goto do_not_remove_call;
9c43b68d 3416 }
c6e113f5 3417 }
c45cb8bb 3418 goto do_remove;
152c35aa
RH
3419 }
3420 do_not_remove_call:
c896fe29 3421
25f49c5f 3422 /* Output args are dead. */
152c35aa 3423 for (i = 0; i < nb_oargs; i++) {
25f49c5f
RH
3424 ts = arg_temp(op->args[i]);
3425 if (ts->state & TS_DEAD) {
152c35aa
RH
3426 arg_life |= DEAD_ARG << i;
3427 }
25f49c5f 3428 if (ts->state & TS_MEM) {
152c35aa 3429 arg_life |= SYNC_ARG << i;
c6e113f5 3430 }
25f49c5f
RH
3431 ts->state = TS_DEAD;
3432 la_reset_pref(ts);
152c35aa 3433 }
78505279 3434
31fd884b
RH
3435 /* Not used -- it will be tcg_target_call_oarg_reg(). */
3436 memset(op->output_pref, 0, sizeof(op->output_pref));
3437
152c35aa
RH
3438 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
3439 TCG_CALL_NO_READ_GLOBALS))) {
f65a061c 3440 la_global_kill(s, nb_globals);
152c35aa 3441 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
f65a061c 3442 la_global_sync(s, nb_globals);
152c35aa 3443 }
b9c18f56 3444
25f49c5f 3445 /* Record arguments that die in this helper. */
152c35aa 3446 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
25f49c5f 3447 ts = arg_temp(op->args[i]);
39004a71 3448 if (ts->state & TS_DEAD) {
152c35aa 3449 arg_life |= DEAD_ARG << i;
c6e113f5 3450 }
152c35aa 3451 }
25f49c5f
RH
3452
3453 /* For all live registers, remove call-clobbered prefs. */
3454 la_cross_call(s, nb_temps);
3455
39004a71
RH
3456 /*
3457 * Input arguments are live for preceding opcodes.
3458 *
3459 * For those arguments that die, and will be allocated in
3460 * registers, clear the register set for that arg, to be
3461 * filled in below. For args that will be on the stack,
3462 * reset to any available reg. Process arguments in reverse
3463 * order so that if a temp is used more than once, the stack
3464 * reset to max happens before the register reset to 0.
3465 */
3466 for (i = nb_iargs - 1; i >= 0; i--) {
3467 const TCGCallArgumentLoc *loc = &info->in[i];
3468 ts = arg_temp(op->args[nb_oargs + i]);
25f49c5f 3469
39004a71
RH
3470 if (ts->state & TS_DEAD) {
3471 switch (loc->kind) {
3472 case TCG_CALL_ARG_NORMAL:
3473 case TCG_CALL_ARG_EXTEND_U:
3474 case TCG_CALL_ARG_EXTEND_S:
338b61e9 3475 if (arg_slot_reg_p(loc->arg_slot)) {
39004a71
RH
3476 *la_temp_pref(ts) = 0;
3477 break;
3478 }
3479 /* fall through */
3480 default:
3481 *la_temp_pref(ts) =
3482 tcg_target_available_regs[ts->type];
3483 break;
3484 }
25f49c5f
RH
3485 ts->state &= ~TS_DEAD;
3486 }
3487 }
3488
39004a71
RH
3489 /*
3490 * For each input argument, add its input register to prefs.
3491 * If a temp is used once, this produces a single set bit;
3492 * if a temp is used multiple times, this produces a set.
3493 */
3494 for (i = 0; i < nb_iargs; i++) {
3495 const TCGCallArgumentLoc *loc = &info->in[i];
3496 ts = arg_temp(op->args[nb_oargs + i]);
3497
3498 switch (loc->kind) {
3499 case TCG_CALL_ARG_NORMAL:
3500 case TCG_CALL_ARG_EXTEND_U:
3501 case TCG_CALL_ARG_EXTEND_S:
338b61e9 3502 if (arg_slot_reg_p(loc->arg_slot)) {
39004a71
RH
3503 tcg_regset_set_reg(*la_temp_pref(ts),
3504 tcg_target_call_iarg_regs[loc->arg_slot]);
3505 }
3506 break;
3507 default:
3508 break;
c19f47bf 3509 }
c896fe29 3510 }
c896fe29 3511 }
c896fe29 3512 break;
765b842a 3513 case INDEX_op_insn_start:
c896fe29 3514 break;
5ff9d6a4 3515 case INDEX_op_discard:
5ff9d6a4 3516 /* mark the temporary as dead */
25f49c5f
RH
3517 ts = arg_temp(op->args[0]);
3518 ts->state = TS_DEAD;
3519 la_reset_pref(ts);
5ff9d6a4 3520 break;
1305c451
RH
3521
3522 case INDEX_op_add2_i32:
c45cb8bb 3523 opc_new = INDEX_op_add_i32;
f1fae40c 3524 goto do_addsub2;
1305c451 3525 case INDEX_op_sub2_i32:
c45cb8bb 3526 opc_new = INDEX_op_sub_i32;
f1fae40c
RH
3527 goto do_addsub2;
3528 case INDEX_op_add2_i64:
c45cb8bb 3529 opc_new = INDEX_op_add_i64;
f1fae40c
RH
3530 goto do_addsub2;
3531 case INDEX_op_sub2_i64:
c45cb8bb 3532 opc_new = INDEX_op_sub_i64;
f1fae40c 3533 do_addsub2:
1305c451
RH
3534 nb_iargs = 4;
3535 nb_oargs = 2;
3536 /* Test if the high part of the operation is dead, but not
3537 the low part. The result can be optimized to a simple
3538 add or sub. This happens often for x86_64 guest when the
3539 cpu mode is set to 32 bit. */
b83eabea
RH
3540 if (arg_temp(op->args[1])->state == TS_DEAD) {
3541 if (arg_temp(op->args[0])->state == TS_DEAD) {
1305c451
RH
3542 goto do_remove;
3543 }
c45cb8bb
RH
3544 /* Replace the opcode and adjust the args in place,
3545 leaving 3 unused args at the end. */
3546 op->opc = opc = opc_new;
efee3746
RH
3547 op->args[1] = op->args[2];
3548 op->args[2] = op->args[4];
1305c451
RH
3549 /* Fall through and mark the single-word operation live. */
3550 nb_iargs = 2;
3551 nb_oargs = 1;
3552 }
3553 goto do_not_remove;
3554
1414968a 3555 case INDEX_op_mulu2_i32:
c45cb8bb
RH
3556 opc_new = INDEX_op_mul_i32;
3557 opc_new2 = INDEX_op_muluh_i32;
3558 have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
03271524 3559 goto do_mul2;
f1fae40c 3560 case INDEX_op_muls2_i32:
c45cb8bb
RH
3561 opc_new = INDEX_op_mul_i32;
3562 opc_new2 = INDEX_op_mulsh_i32;
3563 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
f1fae40c
RH
3564 goto do_mul2;
3565 case INDEX_op_mulu2_i64:
c45cb8bb
RH
3566 opc_new = INDEX_op_mul_i64;
3567 opc_new2 = INDEX_op_muluh_i64;
3568 have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
03271524 3569 goto do_mul2;
f1fae40c 3570 case INDEX_op_muls2_i64:
c45cb8bb
RH
3571 opc_new = INDEX_op_mul_i64;
3572 opc_new2 = INDEX_op_mulsh_i64;
3573 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
03271524 3574 goto do_mul2;
f1fae40c 3575 do_mul2:
1414968a
RH
3576 nb_iargs = 2;
3577 nb_oargs = 2;
b83eabea
RH
3578 if (arg_temp(op->args[1])->state == TS_DEAD) {
3579 if (arg_temp(op->args[0])->state == TS_DEAD) {
03271524 3580 /* Both parts of the operation are dead. */
1414968a
RH
3581 goto do_remove;
3582 }
03271524 3583 /* The high part of the operation is dead; generate the low. */
c45cb8bb 3584 op->opc = opc = opc_new;
efee3746
RH
3585 op->args[1] = op->args[2];
3586 op->args[2] = op->args[3];
b83eabea 3587 } else if (arg_temp(op->args[0])->state == TS_DEAD && have_opc_new2) {
c45cb8bb
RH
3588 /* The low part of the operation is dead; generate the high. */
3589 op->opc = opc = opc_new2;
efee3746
RH
3590 op->args[0] = op->args[1];
3591 op->args[1] = op->args[2];
3592 op->args[2] = op->args[3];
03271524
RH
3593 } else {
3594 goto do_not_remove;
1414968a 3595 }
03271524
RH
3596 /* Mark the single-word operation live. */
3597 nb_oargs = 1;
1414968a
RH
3598 goto do_not_remove;
3599
c896fe29 3600 default:
1305c451 3601 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
49516bc0
AJ
3602 nb_iargs = def->nb_iargs;
3603 nb_oargs = def->nb_oargs;
c896fe29 3604
49516bc0
AJ
3605 /* Test if the operation can be removed because all
3606 its outputs are dead. We assume that nb_oargs == 0
3607 implies side effects */
3608 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
c45cb8bb 3609 for (i = 0; i < nb_oargs; i++) {
b83eabea 3610 if (arg_temp(op->args[i])->state != TS_DEAD) {
49516bc0 3611 goto do_not_remove;
9c43b68d 3612 }
49516bc0 3613 }
152c35aa
RH
3614 goto do_remove;
3615 }
3616 goto do_not_remove;
49516bc0 3617
152c35aa
RH
3618 do_remove:
3619 tcg_op_remove(s, op);
3620 break;
3621
3622 do_not_remove:
152c35aa 3623 for (i = 0; i < nb_oargs; i++) {
25f49c5f
RH
3624 ts = arg_temp(op->args[i]);
3625
3626 /* Remember the preference of the uses that followed. */
31fd884b
RH
3627 if (i < ARRAY_SIZE(op->output_pref)) {
3628 op->output_pref[i] = *la_temp_pref(ts);
3629 }
25f49c5f
RH
3630
3631 /* Output args are dead. */
3632 if (ts->state & TS_DEAD) {
152c35aa 3633 arg_life |= DEAD_ARG << i;
49516bc0 3634 }
25f49c5f 3635 if (ts->state & TS_MEM) {
152c35aa
RH
3636 arg_life |= SYNC_ARG << i;
3637 }
25f49c5f
RH
3638 ts->state = TS_DEAD;
3639 la_reset_pref(ts);
152c35aa 3640 }
49516bc0 3641
25f49c5f 3642 /* If end of basic block, update. */
ae36a246
RH
3643 if (def->flags & TCG_OPF_BB_EXIT) {
3644 la_func_end(s, nb_globals, nb_temps);
b4cb76e6
RH
3645 } else if (def->flags & TCG_OPF_COND_BRANCH) {
3646 la_bb_sync(s, nb_globals, nb_temps);
ae36a246 3647 } else if (def->flags & TCG_OPF_BB_END) {
2616c808 3648 la_bb_end(s, nb_globals, nb_temps);
152c35aa 3649 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
f65a061c 3650 la_global_sync(s, nb_globals);
25f49c5f
RH
3651 if (def->flags & TCG_OPF_CALL_CLOBBER) {
3652 la_cross_call(s, nb_temps);
3653 }
152c35aa
RH
3654 }
3655
25f49c5f 3656 /* Record arguments that die in this opcode. */
152c35aa 3657 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
25f49c5f
RH
3658 ts = arg_temp(op->args[i]);
3659 if (ts->state & TS_DEAD) {
152c35aa 3660 arg_life |= DEAD_ARG << i;
c896fe29 3661 }
c896fe29 3662 }
25f49c5f
RH
3663
3664 /* Input arguments are live for preceding opcodes. */
152c35aa 3665 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
25f49c5f
RH
3666 ts = arg_temp(op->args[i]);
3667 if (ts->state & TS_DEAD) {
3668 /* For operands that were dead, initially allow
3669 all regs for the type. */
3670 *la_temp_pref(ts) = tcg_target_available_regs[ts->type];
3671 ts->state &= ~TS_DEAD;
3672 }
3673 }
3674
3675 /* Incorporate constraints for this operand. */
3676 switch (opc) {
3677 case INDEX_op_mov_i32:
3678 case INDEX_op_mov_i64:
3679 /* Note that these are TCG_OPF_NOT_PRESENT and do not
3680 have proper constraints. That said, special case
3681 moves to propagate preferences backward. */
3682 if (IS_DEAD_ARG(1)) {
3683 *la_temp_pref(arg_temp(op->args[0]))
3684 = *la_temp_pref(arg_temp(op->args[1]));
3685 }
3686 break;
3687
3688 default:
3689 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
3690 const TCGArgConstraint *ct = &def->args_ct[i];
3691 TCGRegSet set, *pset;
3692
3693 ts = arg_temp(op->args[i]);
3694 pset = la_temp_pref(ts);
3695 set = *pset;
3696
9be0d080 3697 set &= ct->regs;
bc2b17e6 3698 if (ct->ialias) {
31fd884b 3699 set &= output_pref(op, ct->alias_index);
25f49c5f
RH
3700 }
3701 /* If the combination is not possible, restart. */
3702 if (set == 0) {
9be0d080 3703 set = ct->regs;
25f49c5f
RH
3704 }
3705 *pset = set;
3706 }
3707 break;
152c35aa 3708 }
c896fe29
FB
3709 break;
3710 }
bee158cb 3711 op->life = arg_life;
1ff0a2c5 3712 }
c896fe29 3713}
c896fe29 3714
5a18407f 3715/* Liveness analysis: Convert indirect regs to direct temporaries. */
9bbee4c0
RH
3716static bool __attribute__((noinline))
3717liveness_pass_2(TCGContext *s)
5a18407f
RH
3718{
3719 int nb_globals = s->nb_globals;
15fa08f8 3720 int nb_temps, i;
5a18407f 3721 bool changes = false;
15fa08f8 3722 TCGOp *op, *op_next;
5a18407f 3723
5a18407f
RH
3724 /* Create a temporary for each indirect global. */
3725 for (i = 0; i < nb_globals; ++i) {
3726 TCGTemp *its = &s->temps[i];
3727 if (its->indirect_reg) {
3728 TCGTemp *dts = tcg_temp_alloc(s);
3729 dts->type = its->type;
3730 dts->base_type = its->base_type;
e1e64652 3731 dts->temp_subindex = its->temp_subindex;
c7482438 3732 dts->kind = TEMP_EBB;
b83eabea
RH
3733 its->state_ptr = dts;
3734 } else {
3735 its->state_ptr = NULL;
5a18407f 3736 }
b83eabea
RH
3737 /* All globals begin dead. */
3738 its->state = TS_DEAD;
3739 }
3740 for (nb_temps = s->nb_temps; i < nb_temps; ++i) {
3741 TCGTemp *its = &s->temps[i];
3742 its->state_ptr = NULL;
3743 its->state = TS_DEAD;
5a18407f 3744 }
5a18407f 3745
15fa08f8 3746 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
5a18407f
RH
3747 TCGOpcode opc = op->opc;
3748 const TCGOpDef *def = &tcg_op_defs[opc];
3749 TCGLifeData arg_life = op->life;
3750 int nb_iargs, nb_oargs, call_flags;
b83eabea 3751 TCGTemp *arg_ts, *dir_ts;
5a18407f 3752
5a18407f 3753 if (opc == INDEX_op_call) {
cd9090aa
RH
3754 nb_oargs = TCGOP_CALLO(op);
3755 nb_iargs = TCGOP_CALLI(op);
90163900 3756 call_flags = tcg_call_flags(op);
5a18407f
RH
3757 } else {
3758 nb_iargs = def->nb_iargs;
3759 nb_oargs = def->nb_oargs;
3760
3761 /* Set flags similar to how calls require. */
b4cb76e6
RH
3762 if (def->flags & TCG_OPF_COND_BRANCH) {
3763 /* Like reading globals: sync_globals */
3764 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
3765 } else if (def->flags & TCG_OPF_BB_END) {
5a18407f
RH
3766 /* Like writing globals: save_globals */
3767 call_flags = 0;
3768 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
3769 /* Like reading globals: sync_globals */
3770 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
3771 } else {
3772 /* No effect on globals. */
3773 call_flags = (TCG_CALL_NO_READ_GLOBALS |
3774 TCG_CALL_NO_WRITE_GLOBALS);
3775 }
3776 }
3777
3778 /* Make sure that input arguments are available. */
3779 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
b83eabea 3780 arg_ts = arg_temp(op->args[i]);
39004a71
RH
3781 dir_ts = arg_ts->state_ptr;
3782 if (dir_ts && arg_ts->state == TS_DEAD) {
3783 TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32
3784 ? INDEX_op_ld_i32
3785 : INDEX_op_ld_i64);
3786 TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
3787
3788 lop->args[0] = temp_arg(dir_ts);
3789 lop->args[1] = temp_arg(arg_ts->mem_base);
3790 lop->args[2] = arg_ts->mem_offset;
3791
3792 /* Loaded, but synced with memory. */
3793 arg_ts->state = TS_MEM;
5a18407f
RH
3794 }
3795 }
3796
3797 /* Perform input replacement, and mark inputs that became dead.
3798 No action is required except keeping temp_state up to date
3799 so that we reload when needed. */
3800 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
b83eabea 3801 arg_ts = arg_temp(op->args[i]);
39004a71
RH
3802 dir_ts = arg_ts->state_ptr;
3803 if (dir_ts) {
3804 op->args[i] = temp_arg(dir_ts);
3805 changes = true;
3806 if (IS_DEAD_ARG(i)) {
3807 arg_ts->state = TS_DEAD;
5a18407f
RH
3808 }
3809 }
3810 }
3811
3812 /* Liveness analysis should ensure that the following are
3813 all correct, for call sites and basic block end points. */
3814 if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
3815 /* Nothing to do */
3816 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
3817 for (i = 0; i < nb_globals; ++i) {
3818 /* Liveness should see that globals are synced back,
3819 that is, either TS_DEAD or TS_MEM. */
b83eabea
RH
3820 arg_ts = &s->temps[i];
3821 tcg_debug_assert(arg_ts->state_ptr == 0
3822 || arg_ts->state != 0);
5a18407f
RH
3823 }
3824 } else {
3825 for (i = 0; i < nb_globals; ++i) {
3826 /* Liveness should see that globals are saved back,
3827 that is, TS_DEAD, waiting to be reloaded. */
b83eabea
RH
3828 arg_ts = &s->temps[i];
3829 tcg_debug_assert(arg_ts->state_ptr == 0
3830 || arg_ts->state == TS_DEAD);
5a18407f
RH
3831 }
3832 }
3833
3834 /* Outputs become available. */
61f15c48
RH
3835 if (opc == INDEX_op_mov_i32 || opc == INDEX_op_mov_i64) {
3836 arg_ts = arg_temp(op->args[0]);
b83eabea 3837 dir_ts = arg_ts->state_ptr;
61f15c48
RH
3838 if (dir_ts) {
3839 op->args[0] = temp_arg(dir_ts);
3840 changes = true;
3841
3842 /* The output is now live and modified. */
3843 arg_ts->state = 0;
3844
3845 if (NEED_SYNC_ARG(0)) {
3846 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
3847 ? INDEX_op_st_i32
3848 : INDEX_op_st_i64);
d4478943 3849 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
61f15c48
RH
3850 TCGTemp *out_ts = dir_ts;
3851
3852 if (IS_DEAD_ARG(0)) {
3853 out_ts = arg_temp(op->args[1]);
3854 arg_ts->state = TS_DEAD;
3855 tcg_op_remove(s, op);
3856 } else {
3857 arg_ts->state = TS_MEM;
3858 }
3859
3860 sop->args[0] = temp_arg(out_ts);
3861 sop->args[1] = temp_arg(arg_ts->mem_base);
3862 sop->args[2] = arg_ts->mem_offset;
3863 } else {
3864 tcg_debug_assert(!IS_DEAD_ARG(0));
3865 }
5a18407f 3866 }
61f15c48
RH
3867 } else {
3868 for (i = 0; i < nb_oargs; i++) {
3869 arg_ts = arg_temp(op->args[i]);
3870 dir_ts = arg_ts->state_ptr;
3871 if (!dir_ts) {
3872 continue;
3873 }
3874 op->args[i] = temp_arg(dir_ts);
3875 changes = true;
5a18407f 3876
61f15c48
RH
3877 /* The output is now live and modified. */
3878 arg_ts->state = 0;
5a18407f 3879
61f15c48
RH
3880 /* Sync outputs upon their last write. */
3881 if (NEED_SYNC_ARG(i)) {
3882 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
3883 ? INDEX_op_st_i32
3884 : INDEX_op_st_i64);
d4478943 3885 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
5a18407f 3886
61f15c48
RH
3887 sop->args[0] = temp_arg(dir_ts);
3888 sop->args[1] = temp_arg(arg_ts->mem_base);
3889 sop->args[2] = arg_ts->mem_offset;
5a18407f 3890
61f15c48
RH
3891 arg_ts->state = TS_MEM;
3892 }
3893 /* Drop outputs that are dead. */
3894 if (IS_DEAD_ARG(i)) {
3895 arg_ts->state = TS_DEAD;
3896 }
5a18407f
RH
3897 }
3898 }
3899 }
3900
3901 return changes;
3902}
3903
2272e4a7 3904static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
c896fe29 3905{
31c96417 3906 intptr_t off;
273eb50c 3907 int size, align;
c1c09194 3908
273eb50c
RH
3909 /* When allocating an object, look at the full type. */
3910 size = tcg_type_size(ts->base_type);
3911 switch (ts->base_type) {
c1c09194 3912 case TCG_TYPE_I32:
31c96417 3913 align = 4;
c1c09194
RH
3914 break;
3915 case TCG_TYPE_I64:
3916 case TCG_TYPE_V64:
31c96417 3917 align = 8;
c1c09194 3918 break;
43eef72f 3919 case TCG_TYPE_I128:
c1c09194 3920 case TCG_TYPE_V128:
c1c09194 3921 case TCG_TYPE_V256:
43eef72f
RH
3922 /*
3923 * Note that we do not require aligned storage for V256,
3924 * and that we provide alignment for I128 to match V128,
3925 * even if that's above what the host ABI requires.
3926 */
31c96417 3927 align = 16;
c1c09194
RH
3928 break;
3929 default:
3930 g_assert_not_reached();
b591dc59 3931 }
c1c09194 3932
b9537d59
RH
3933 /*
3934 * Assume the stack is sufficiently aligned.
3935 * This affects e.g. ARM NEON, where we have 8 byte stack alignment
3936 * and do not require 16 byte vector alignment. This seems slightly
3937 * easier than fully parameterizing the above switch statement.
3938 */
3939 align = MIN(TCG_TARGET_STACK_ALIGN, align);
c1c09194 3940 off = ROUND_UP(s->current_frame_offset, align);
732d5897
RH
3941
3942 /* If we've exhausted the stack frame, restart with a smaller TB. */
3943 if (off + size > s->frame_end) {
3944 tcg_raise_tb_overflow(s);
3945 }
c1c09194 3946 s->current_frame_offset = off + size;
9defd1bd 3947#if defined(__sparc__)
273eb50c 3948 off += TCG_TARGET_STACK_BIAS;
9defd1bd 3949#endif
273eb50c
RH
3950
3951 /* If the object was subdivided, assign memory to all the parts. */
3952 if (ts->base_type != ts->type) {
3953 int part_size = tcg_type_size(ts->type);
3954 int part_count = size / part_size;
3955
3956 /*
3957 * Each part is allocated sequentially in tcg_temp_new_internal.
3958 * Jump back to the first part by subtracting the current index.
3959 */
3960 ts -= ts->temp_subindex;
3961 for (int i = 0; i < part_count; ++i) {
3962 ts[i].mem_offset = off + i * part_size;
3963 ts[i].mem_base = s->frame_temp;
3964 ts[i].mem_allocated = 1;
3965 }
3966 } else {
3967 ts->mem_offset = off;
3968 ts->mem_base = s->frame_temp;
3969 ts->mem_allocated = 1;
3970 }
c896fe29
FB
3971}
3972
098859f1
RH
3973/* Assign @reg to @ts, and update reg_to_temp[]. */
3974static void set_temp_val_reg(TCGContext *s, TCGTemp *ts, TCGReg reg)
3975{
3976 if (ts->val_type == TEMP_VAL_REG) {
3977 TCGReg old = ts->reg;
3978 tcg_debug_assert(s->reg_to_temp[old] == ts);
3979 if (old == reg) {
3980 return;
3981 }
3982 s->reg_to_temp[old] = NULL;
3983 }
3984 tcg_debug_assert(s->reg_to_temp[reg] == NULL);
3985 s->reg_to_temp[reg] = ts;
3986 ts->val_type = TEMP_VAL_REG;
3987 ts->reg = reg;
3988}
3989
3990/* Assign a non-register value type to @ts, and update reg_to_temp[]. */
3991static void set_temp_val_nonreg(TCGContext *s, TCGTemp *ts, TCGTempVal type)
3992{
3993 tcg_debug_assert(type != TEMP_VAL_REG);
3994 if (ts->val_type == TEMP_VAL_REG) {
3995 TCGReg reg = ts->reg;
3996 tcg_debug_assert(s->reg_to_temp[reg] == ts);
3997 s->reg_to_temp[reg] = NULL;
3998 }
3999 ts->val_type = type;
4000}
4001
b722452a 4002static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);
b3915dbb 4003
59d7c14e
RH
4004/* Mark a temporary as free or dead. If 'free_or_dead' is negative,
4005 mark it free; otherwise mark it dead. */
4006static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
7f6ceedf 4007{
c0522136
RH
4008 TCGTempVal new_type;
4009
4010 switch (ts->kind) {
4011 case TEMP_FIXED:
59d7c14e 4012 return;
c0522136 4013 case TEMP_GLOBAL:
f57c6915 4014 case TEMP_TB:
c0522136
RH
4015 new_type = TEMP_VAL_MEM;
4016 break;
c7482438 4017 case TEMP_EBB:
c0522136
RH
4018 new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD;
4019 break;
4020 case TEMP_CONST:
4021 new_type = TEMP_VAL_CONST;
4022 break;
4023 default:
4024 g_assert_not_reached();
59d7c14e 4025 }
098859f1 4026 set_temp_val_nonreg(s, ts, new_type);
59d7c14e 4027}
7f6ceedf 4028
59d7c14e
RH
4029/* Mark a temporary as dead. */
4030static inline void temp_dead(TCGContext *s, TCGTemp *ts)
4031{
4032 temp_free_or_dead(s, ts, 1);
4033}
4034
4035/* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
4036 registers needs to be allocated to store a constant. If 'free_or_dead'
4037 is non-zero, subsequently release the temporary; if it is positive, the
4038 temp is dead; if it is negative, the temp is free. */
98b4e186
RH
4039static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
4040 TCGRegSet preferred_regs, int free_or_dead)
59d7c14e 4041{
c0522136 4042 if (!temp_readonly(ts) && !ts->mem_coherent) {
7f6ceedf 4043 if (!ts->mem_allocated) {
2272e4a7 4044 temp_allocate_frame(s, ts);
59d7c14e 4045 }
59d7c14e
RH
4046 switch (ts->val_type) {
4047 case TEMP_VAL_CONST:
4048 /* If we're going to free the temp immediately, then we won't
4049 require it later in a register, so attempt to store the
4050 constant to memory directly. */
4051 if (free_or_dead
4052 && tcg_out_sti(s, ts->type, ts->val,
4053 ts->mem_base->reg, ts->mem_offset)) {
4054 break;
4055 }
4056 temp_load(s, ts, tcg_target_available_regs[ts->type],
98b4e186 4057 allocated_regs, preferred_regs);
59d7c14e
RH
4058 /* fallthrough */
4059
4060 case TEMP_VAL_REG:
4061 tcg_out_st(s, ts->type, ts->reg,
4062 ts->mem_base->reg, ts->mem_offset);
4063 break;
4064
4065 case TEMP_VAL_MEM:
4066 break;
4067
4068 case TEMP_VAL_DEAD:
4069 default:
732e89f4 4070 g_assert_not_reached();
59d7c14e
RH
4071 }
4072 ts->mem_coherent = 1;
4073 }
4074 if (free_or_dead) {
4075 temp_free_or_dead(s, ts, free_or_dead);
7f6ceedf 4076 }
7f6ceedf
AJ
4077}
4078
c896fe29 4079/* free register 'reg' by spilling the corresponding temporary if necessary */
b3915dbb 4080static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
c896fe29 4081{
f8b2f202 4082 TCGTemp *ts = s->reg_to_temp[reg];
f8b2f202 4083 if (ts != NULL) {
98b4e186 4084 temp_sync(s, ts, allocated_regs, 0, -1);
c896fe29
FB
4085 }
4086}
4087
b016486e
RH
4088/**
4089 * tcg_reg_alloc:
4090 * @required_regs: Set of registers in which we must allocate.
4091 * @allocated_regs: Set of registers which must be avoided.
4092 * @preferred_regs: Set of registers we should prefer.
4093 * @rev: True if we search the registers in "indirect" order.
4094 *
4095 * The allocated register must be in @required_regs & ~@allocated_regs,
4096 * but if we can put it in @preferred_regs we may save a move later.
4097 */
4098static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
4099 TCGRegSet allocated_regs,
4100 TCGRegSet preferred_regs, bool rev)
c896fe29 4101{
b016486e
RH
4102 int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
4103 TCGRegSet reg_ct[2];
91478cef 4104 const int *order;
c896fe29 4105
b016486e
RH
4106 reg_ct[1] = required_regs & ~allocated_regs;
4107 tcg_debug_assert(reg_ct[1] != 0);
4108 reg_ct[0] = reg_ct[1] & preferred_regs;
4109
4110 /* Skip the preferred_regs option if it cannot be satisfied,
4111 or if the preference made no difference. */
4112 f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
4113
91478cef 4114 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
c896fe29 4115
b016486e
RH
4116 /* Try free registers, preferences first. */
4117 for (j = f; j < 2; j++) {
4118 TCGRegSet set = reg_ct[j];
4119
4120 if (tcg_regset_single(set)) {
4121 /* One register in the set. */
4122 TCGReg reg = tcg_regset_first(set);
4123 if (s->reg_to_temp[reg] == NULL) {
4124 return reg;
4125 }
4126 } else {
4127 for (i = 0; i < n; i++) {
4128 TCGReg reg = order[i];
4129 if (s->reg_to_temp[reg] == NULL &&
4130 tcg_regset_test_reg(set, reg)) {
4131 return reg;
4132 }
4133 }
4134 }
c896fe29
FB
4135 }
4136
b016486e
RH
4137 /* We must spill something. */
4138 for (j = f; j < 2; j++) {
4139 TCGRegSet set = reg_ct[j];
4140
4141 if (tcg_regset_single(set)) {
4142 /* One register in the set. */
4143 TCGReg reg = tcg_regset_first(set);
b3915dbb 4144 tcg_reg_free(s, reg, allocated_regs);
c896fe29 4145 return reg;
b016486e
RH
4146 } else {
4147 for (i = 0; i < n; i++) {
4148 TCGReg reg = order[i];
4149 if (tcg_regset_test_reg(set, reg)) {
4150 tcg_reg_free(s, reg, allocated_regs);
4151 return reg;
4152 }
4153 }
c896fe29
FB
4154 }
4155 }
4156
732e89f4 4157 g_assert_not_reached();
c896fe29
FB
4158}
4159
29f5e925
RH
4160static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs,
4161 TCGRegSet allocated_regs,
4162 TCGRegSet preferred_regs, bool rev)
4163{
4164 int i, j, k, fmin, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
4165 TCGRegSet reg_ct[2];
4166 const int *order;
4167
4168 /* Ensure that if I is not in allocated_regs, I+1 is not either. */
4169 reg_ct[1] = required_regs & ~(allocated_regs | (allocated_regs >> 1));
4170 tcg_debug_assert(reg_ct[1] != 0);
4171 reg_ct[0] = reg_ct[1] & preferred_regs;
4172
4173 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
4174
4175 /*
4176 * Skip the preferred_regs option if it cannot be satisfied,
4177 * or if the preference made no difference.
4178 */
4179 k = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
4180
4181 /*
4182 * Minimize the number of flushes by looking for 2 free registers first,
4183 * then a single flush, then two flushes.
4184 */
4185 for (fmin = 2; fmin >= 0; fmin--) {
4186 for (j = k; j < 2; j++) {
4187 TCGRegSet set = reg_ct[j];
4188
4189 for (i = 0; i < n; i++) {
4190 TCGReg reg = order[i];
4191
4192 if (tcg_regset_test_reg(set, reg)) {
4193 int f = !s->reg_to_temp[reg] + !s->reg_to_temp[reg + 1];
4194 if (f >= fmin) {
4195 tcg_reg_free(s, reg, allocated_regs);
4196 tcg_reg_free(s, reg + 1, allocated_regs);
4197 return reg;
4198 }
4199 }
4200 }
4201 }
4202 }
732e89f4 4203 g_assert_not_reached();
29f5e925
RH
4204}
4205
40ae5c62
RH
4206/* Make sure the temporary is in a register. If needed, allocate the register
4207 from DESIRED while avoiding ALLOCATED. */
4208static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
b722452a 4209 TCGRegSet allocated_regs, TCGRegSet preferred_regs)
40ae5c62
RH
4210{
4211 TCGReg reg;
4212
4213 switch (ts->val_type) {
4214 case TEMP_VAL_REG:
4215 return;
4216 case TEMP_VAL_CONST:
b016486e 4217 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
b722452a 4218 preferred_regs, ts->indirect_base);
0a6a8bc8
RH
4219 if (ts->type <= TCG_TYPE_I64) {
4220 tcg_out_movi(s, ts->type, reg, ts->val);
4221 } else {
4e186175
RH
4222 uint64_t val = ts->val;
4223 MemOp vece = MO_64;
4224
4225 /*
4226 * Find the minimal vector element that matches the constant.
4227 * The targets will, in general, have to do this search anyway,
4228 * do this generically.
4229 */
4e186175
RH
4230 if (val == dup_const(MO_8, val)) {
4231 vece = MO_8;
4232 } else if (val == dup_const(MO_16, val)) {
4233 vece = MO_16;
0b4286dd 4234 } else if (val == dup_const(MO_32, val)) {
4e186175
RH
4235 vece = MO_32;
4236 }
4237
4238 tcg_out_dupi_vec(s, ts->type, vece, reg, ts->val);
0a6a8bc8 4239 }
40ae5c62
RH
4240 ts->mem_coherent = 0;
4241 break;
4242 case TEMP_VAL_MEM:
b016486e 4243 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
b722452a 4244 preferred_regs, ts->indirect_base);
40ae5c62
RH
4245 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
4246 ts->mem_coherent = 1;
4247 break;
4248 case TEMP_VAL_DEAD:
4249 default:
732e89f4 4250 g_assert_not_reached();
40ae5c62 4251 }
098859f1 4252 set_temp_val_reg(s, ts, reg);
40ae5c62
RH
4253}
4254
59d7c14e
RH
4255/* Save a temporary to memory. 'allocated_regs' is used in case a
4256 temporary registers needs to be allocated to store a constant. */
4257static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
1ad80729 4258{
5a18407f
RH
4259 /* The liveness analysis already ensures that globals are back
4260 in memory. Keep an tcg_debug_assert for safety. */
e01fa97d 4261 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || temp_readonly(ts));
1ad80729
AJ
4262}
4263
9814dd27 4264/* save globals to their canonical location and assume they can be
e8996ee0
FB
4265 modified be the following code. 'allocated_regs' is used in case a
4266 temporary registers needs to be allocated to store a constant. */
4267static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
c896fe29 4268{
ac3b8891 4269 int i, n;
c896fe29 4270
ac3b8891 4271 for (i = 0, n = s->nb_globals; i < n; i++) {
b13eb728 4272 temp_save(s, &s->temps[i], allocated_regs);
c896fe29 4273 }
e5097dc8
FB
4274}
4275
3d5c5f87
AJ
4276/* sync globals to their canonical location and assume they can be
4277 read by the following code. 'allocated_regs' is used in case a
4278 temporary registers needs to be allocated to store a constant. */
4279static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
4280{
ac3b8891 4281 int i, n;
3d5c5f87 4282
ac3b8891 4283 for (i = 0, n = s->nb_globals; i < n; i++) {
12b9b11a 4284 TCGTemp *ts = &s->temps[i];
5a18407f 4285 tcg_debug_assert(ts->val_type != TEMP_VAL_REG
ee17db83 4286 || ts->kind == TEMP_FIXED
5a18407f 4287 || ts->mem_coherent);
3d5c5f87
AJ
4288 }
4289}
4290
e5097dc8 4291/* at the end of a basic block, we assume all temporaries are dead and
e8996ee0
FB
4292 all globals are stored at their canonical location. */
4293static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
e5097dc8 4294{
e5097dc8
FB
4295 int i;
4296
b13eb728
RH
4297 for (i = s->nb_globals; i < s->nb_temps; i++) {
4298 TCGTemp *ts = &s->temps[i];
c0522136
RH
4299
4300 switch (ts->kind) {
f57c6915 4301 case TEMP_TB:
b13eb728 4302 temp_save(s, ts, allocated_regs);
c0522136 4303 break;
c7482438 4304 case TEMP_EBB:
5a18407f
RH
4305 /* The liveness analysis already ensures that temps are dead.
4306 Keep an tcg_debug_assert for safety. */
4307 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
c0522136
RH
4308 break;
4309 case TEMP_CONST:
4310 /* Similarly, we should have freed any allocated register. */
4311 tcg_debug_assert(ts->val_type == TEMP_VAL_CONST);
4312 break;
4313 default:
4314 g_assert_not_reached();
c896fe29
FB
4315 }
4316 }
e8996ee0
FB
4317
4318 save_globals(s, allocated_regs);
c896fe29
FB
4319}
4320
b4cb76e6 4321/*
c7482438
RH
4322 * At a conditional branch, we assume all temporaries are dead unless
4323 * explicitly live-across-conditional-branch; all globals and local
4324 * temps are synced to their location.
b4cb76e6
RH
4325 */
4326static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
4327{
4328 sync_globals(s, allocated_regs);
4329
4330 for (int i = s->nb_globals; i < s->nb_temps; i++) {
4331 TCGTemp *ts = &s->temps[i];
4332 /*
4333 * The liveness analysis already ensures that temps are dead.
4334 * Keep tcg_debug_asserts for safety.
4335 */
c0522136 4336 switch (ts->kind) {
f57c6915 4337 case TEMP_TB:
b4cb76e6 4338 tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
c0522136 4339 break;
c7482438 4340 case TEMP_EBB:
c0522136
RH
4341 case TEMP_CONST:
4342 break;
4343 default:
4344 g_assert_not_reached();
b4cb76e6
RH
4345 }
4346 }
4347}
4348
bab1671f 4349/*
c58f4c97 4350 * Specialized code generation for INDEX_op_mov_* with a constant.
bab1671f 4351 */
0fe4fca4 4352static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
ba87719c
RH
4353 tcg_target_ulong val, TCGLifeData arg_life,
4354 TCGRegSet preferred_regs)
e8996ee0 4355{
d63e3b6e 4356 /* ENV should not be modified. */
e01fa97d 4357 tcg_debug_assert(!temp_readonly(ots));
59d7c14e
RH
4358
4359 /* The movi is not explicitly generated here. */
098859f1 4360 set_temp_val_nonreg(s, ots, TEMP_VAL_CONST);
59d7c14e
RH
4361 ots->val = val;
4362 ots->mem_coherent = 0;
4363 if (NEED_SYNC_ARG(0)) {
ba87719c 4364 temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0));
59d7c14e 4365 } else if (IS_DEAD_ARG(0)) {
f8bf00f1 4366 temp_dead(s, ots);
4c4e1ab2 4367 }
e8996ee0
FB
4368}
4369
bab1671f
RH
4370/*
4371 * Specialized code generation for INDEX_op_mov_*.
4372 */
dd186292 4373static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
c896fe29 4374{
dd186292 4375 const TCGLifeData arg_life = op->life;
69e3706d 4376 TCGRegSet allocated_regs, preferred_regs;
c896fe29 4377 TCGTemp *ts, *ots;
450445d5 4378 TCGType otype, itype;
098859f1 4379 TCGReg oreg, ireg;
c896fe29 4380
d21369f5 4381 allocated_regs = s->reserved_regs;
31fd884b 4382 preferred_regs = output_pref(op, 0);
43439139
RH
4383 ots = arg_temp(op->args[0]);
4384 ts = arg_temp(op->args[1]);
450445d5 4385
d63e3b6e 4386 /* ENV should not be modified. */
e01fa97d 4387 tcg_debug_assert(!temp_readonly(ots));
d63e3b6e 4388
450445d5
RH
4389 /* Note that otype != itype for no-op truncation. */
4390 otype = ots->type;
4391 itype = ts->type;
c29c1d7e 4392
0fe4fca4
PB
4393 if (ts->val_type == TEMP_VAL_CONST) {
4394 /* propagate constant or generate sti */
4395 tcg_target_ulong val = ts->val;
4396 if (IS_DEAD_ARG(1)) {
4397 temp_dead(s, ts);
4398 }
69e3706d 4399 tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
0fe4fca4
PB
4400 return;
4401 }
4402
4403 /* If the source value is in memory we're going to be forced
4404 to have it in a register in order to perform the copy. Copy
4405 the SOURCE value into its own register first, that way we
4406 don't have to reload SOURCE the next time it is used. */
4407 if (ts->val_type == TEMP_VAL_MEM) {
69e3706d
RH
4408 temp_load(s, ts, tcg_target_available_regs[itype],
4409 allocated_regs, preferred_regs);
c29c1d7e 4410 }
0fe4fca4 4411 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
098859f1
RH
4412 ireg = ts->reg;
4413
d63e3b6e 4414 if (IS_DEAD_ARG(0)) {
c29c1d7e
AJ
4415 /* mov to a non-saved dead register makes no sense (even with
4416 liveness analysis disabled). */
eabb7b91 4417 tcg_debug_assert(NEED_SYNC_ARG(0));
c29c1d7e 4418 if (!ots->mem_allocated) {
2272e4a7 4419 temp_allocate_frame(s, ots);
c29c1d7e 4420 }
098859f1 4421 tcg_out_st(s, otype, ireg, ots->mem_base->reg, ots->mem_offset);
c29c1d7e 4422 if (IS_DEAD_ARG(1)) {
f8bf00f1 4423 temp_dead(s, ts);
c29c1d7e 4424 }
f8bf00f1 4425 temp_dead(s, ots);
098859f1
RH
4426 return;
4427 }
4428
4429 if (IS_DEAD_ARG(1) && ts->kind != TEMP_FIXED) {
4430 /*
4431 * The mov can be suppressed. Kill input first, so that it
4432 * is unlinked from reg_to_temp, then set the output to the
4433 * reg that we saved from the input.
4434 */
4435 temp_dead(s, ts);
4436 oreg = ireg;
c29c1d7e 4437 } else {
098859f1
RH
4438 if (ots->val_type == TEMP_VAL_REG) {
4439 oreg = ots->reg;
c896fe29 4440 } else {
098859f1
RH
4441 /* Make sure to not spill the input register during allocation. */
4442 oreg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
4443 allocated_regs | ((TCGRegSet)1 << ireg),
4444 preferred_regs, ots->indirect_base);
c896fe29 4445 }
098859f1
RH
4446 if (!tcg_out_mov(s, otype, oreg, ireg)) {
4447 /*
4448 * Cross register class move not supported.
4449 * Store the source register into the destination slot
4450 * and leave the destination temp as TEMP_VAL_MEM.
4451 */
4452 assert(!temp_readonly(ots));
4453 if (!ts->mem_allocated) {
4454 temp_allocate_frame(s, ots);
4455 }
4456 tcg_out_st(s, ts->type, ireg, ots->mem_base->reg, ots->mem_offset);
4457 set_temp_val_nonreg(s, ts, TEMP_VAL_MEM);
4458 ots->mem_coherent = 1;
4459 return;
c896fe29 4460 }
ec7a869d 4461 }
098859f1
RH
4462 set_temp_val_reg(s, ots, oreg);
4463 ots->mem_coherent = 0;
4464
4465 if (NEED_SYNC_ARG(0)) {
4466 temp_sync(s, ots, allocated_regs, 0, 0);
4467 }
c896fe29
FB
4468}
4469
bab1671f
RH
4470/*
4471 * Specialized code generation for INDEX_op_dup_vec.
4472 */
4473static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
4474{
4475 const TCGLifeData arg_life = op->life;
4476 TCGRegSet dup_out_regs, dup_in_regs;
4477 TCGTemp *its, *ots;
4478 TCGType itype, vtype;
4479 unsigned vece;
31c96417 4480 int lowpart_ofs;
bab1671f
RH
4481 bool ok;
4482
4483 ots = arg_temp(op->args[0]);
4484 its = arg_temp(op->args[1]);
4485
4486 /* ENV should not be modified. */
e01fa97d 4487 tcg_debug_assert(!temp_readonly(ots));
bab1671f
RH
4488
4489 itype = its->type;
4490 vece = TCGOP_VECE(op);
4491 vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
4492
4493 if (its->val_type == TEMP_VAL_CONST) {
4494 /* Propagate constant via movi -> dupi. */
4495 tcg_target_ulong val = its->val;
4496 if (IS_DEAD_ARG(1)) {
4497 temp_dead(s, its);
4498 }
31fd884b 4499 tcg_reg_alloc_do_movi(s, ots, val, arg_life, output_pref(op, 0));
bab1671f
RH
4500 return;
4501 }
4502
9be0d080
RH
4503 dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
4504 dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs;
bab1671f
RH
4505
4506 /* Allocate the output register now. */
4507 if (ots->val_type != TEMP_VAL_REG) {
4508 TCGRegSet allocated_regs = s->reserved_regs;
098859f1 4509 TCGReg oreg;
bab1671f
RH
4510
4511 if (!IS_DEAD_ARG(1) && its->val_type == TEMP_VAL_REG) {
4512 /* Make sure to not spill the input register. */
4513 tcg_regset_set_reg(allocated_regs, its->reg);
4514 }
098859f1 4515 oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
31fd884b 4516 output_pref(op, 0), ots->indirect_base);
098859f1 4517 set_temp_val_reg(s, ots, oreg);
bab1671f
RH
4518 }
4519
4520 switch (its->val_type) {
4521 case TEMP_VAL_REG:
4522 /*
4523 * The dup constriaints must be broad, covering all possible VECE.
4524 * However, tcg_op_dup_vec() gets to see the VECE and we allow it
4525 * to fail, indicating that extra moves are required for that case.
4526 */
4527 if (tcg_regset_test_reg(dup_in_regs, its->reg)) {
4528 if (tcg_out_dup_vec(s, vtype, vece, ots->reg, its->reg)) {
4529 goto done;
4530 }
4531 /* Try again from memory or a vector input register. */
4532 }
4533 if (!its->mem_coherent) {
4534 /*
4535 * The input register is not synced, and so an extra store
4536 * would be required to use memory. Attempt an integer-vector
4537 * register move first. We do not have a TCGRegSet for this.
4538 */
4539 if (tcg_out_mov(s, itype, ots->reg, its->reg)) {
4540 break;
4541 }
4542 /* Sync the temp back to its slot and load from there. */
4543 temp_sync(s, its, s->reserved_regs, 0, 0);
4544 }
4545 /* fall through */
4546
4547 case TEMP_VAL_MEM:
31c96417
RH
4548 lowpart_ofs = 0;
4549 if (HOST_BIG_ENDIAN) {
4550 lowpart_ofs = tcg_type_size(itype) - (1 << vece);
4551 }
d6ecb4a9 4552 if (tcg_out_dupm_vec(s, vtype, vece, ots->reg, its->mem_base->reg,
31c96417 4553 its->mem_offset + lowpart_ofs)) {
d6ecb4a9
RH
4554 goto done;
4555 }
098859f1 4556 /* Load the input into the destination vector register. */
bab1671f
RH
4557 tcg_out_ld(s, itype, ots->reg, its->mem_base->reg, its->mem_offset);
4558 break;
4559
4560 default:
4561 g_assert_not_reached();
4562 }
4563
4564 /* We now have a vector input register, so dup must succeed. */
4565 ok = tcg_out_dup_vec(s, vtype, vece, ots->reg, ots->reg);
4566 tcg_debug_assert(ok);
4567
4568 done:
36f5539c 4569 ots->mem_coherent = 0;
bab1671f
RH
4570 if (IS_DEAD_ARG(1)) {
4571 temp_dead(s, its);
4572 }
4573 if (NEED_SYNC_ARG(0)) {
4574 temp_sync(s, ots, s->reserved_regs, 0, 0);
4575 }
4576 if (IS_DEAD_ARG(0)) {
4577 temp_dead(s, ots);
4578 }
4579}
4580
dd186292 4581static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
c896fe29 4582{
dd186292
RH
4583 const TCGLifeData arg_life = op->life;
4584 const TCGOpDef * const def = &tcg_op_defs[op->opc];
82790a87
RH
4585 TCGRegSet i_allocated_regs;
4586 TCGRegSet o_allocated_regs;
b6638662
RH
4587 int i, k, nb_iargs, nb_oargs;
4588 TCGReg reg;
c896fe29
FB
4589 TCGArg arg;
4590 const TCGArgConstraint *arg_ct;
4591 TCGTemp *ts;
4592 TCGArg new_args[TCG_MAX_OP_ARGS];
4593 int const_args[TCG_MAX_OP_ARGS];
4594
4595 nb_oargs = def->nb_oargs;
4596 nb_iargs = def->nb_iargs;
4597
4598 /* copy constants */
a813e36f 4599 memcpy(new_args + nb_oargs + nb_iargs,
dd186292 4600 op->args + nb_oargs + nb_iargs,
c896fe29
FB
4601 sizeof(TCGArg) * def->nb_cargs);
4602
d21369f5
RH
4603 i_allocated_regs = s->reserved_regs;
4604 o_allocated_regs = s->reserved_regs;
82790a87 4605
a813e36f 4606 /* satisfy input constraints */
dd186292 4607 for (k = 0; k < nb_iargs; k++) {
29f5e925
RH
4608 TCGRegSet i_preferred_regs, i_required_regs;
4609 bool allocate_new_reg, copyto_new_reg;
4610 TCGTemp *ts2;
4611 int i1, i2;
d62816f2 4612
66792f90 4613 i = def->args_ct[nb_oargs + k].sort_index;
dd186292 4614 arg = op->args[i];
c896fe29 4615 arg_ct = &def->args_ct[i];
43439139 4616 ts = arg_temp(arg);
40ae5c62
RH
4617
4618 if (ts->val_type == TEMP_VAL_CONST
a4fbbd77 4619 && tcg_target_const_match(ts->val, ts->type, arg_ct->ct)) {
40ae5c62
RH
4620 /* constant is OK for instruction */
4621 const_args[i] = 1;
4622 new_args[i] = ts->val;
d62816f2 4623 continue;
c896fe29 4624 }
40ae5c62 4625
1c1824dc
RH
4626 reg = ts->reg;
4627 i_preferred_regs = 0;
29f5e925 4628 i_required_regs = arg_ct->regs;
1c1824dc 4629 allocate_new_reg = false;
29f5e925
RH
4630 copyto_new_reg = false;
4631
4632 switch (arg_ct->pair) {
4633 case 0: /* not paired */
4634 if (arg_ct->ialias) {
31fd884b 4635 i_preferred_regs = output_pref(op, arg_ct->alias_index);
29f5e925
RH
4636
4637 /*
4638 * If the input is readonly, then it cannot also be an
4639 * output and aliased to itself. If the input is not
4640 * dead after the instruction, we must allocate a new
4641 * register and move it.
4642 */
4643 if (temp_readonly(ts) || !IS_DEAD_ARG(i)) {
4644 allocate_new_reg = true;
4645 } else if (ts->val_type == TEMP_VAL_REG) {
4646 /*
4647 * Check if the current register has already been
4648 * allocated for another input.
4649 */
4650 allocate_new_reg =
4651 tcg_regset_test_reg(i_allocated_regs, reg);
4652 }
4653 }
4654 if (!allocate_new_reg) {
4655 temp_load(s, ts, i_required_regs, i_allocated_regs,
4656 i_preferred_regs);
4657 reg = ts->reg;
4658 allocate_new_reg = !tcg_regset_test_reg(i_required_regs, reg);
4659 }
4660 if (allocate_new_reg) {
4661 /*
4662 * Allocate a new register matching the constraint
4663 * and move the temporary register into it.
4664 */
4665 temp_load(s, ts, tcg_target_available_regs[ts->type],
4666 i_allocated_regs, 0);
4667 reg = tcg_reg_alloc(s, i_required_regs, i_allocated_regs,
4668 i_preferred_regs, ts->indirect_base);
4669 copyto_new_reg = true;
4670 }
4671 break;
4672
4673 case 1:
4674 /* First of an input pair; if i1 == i2, the second is an output. */
4675 i1 = i;
4676 i2 = arg_ct->pair_index;
4677 ts2 = i1 != i2 ? arg_temp(op->args[i2]) : NULL;
4678
4679 /*
4680 * It is easier to default to allocating a new pair
4681 * and to identify a few cases where it's not required.
4682 */
4683 if (arg_ct->ialias) {
31fd884b 4684 i_preferred_regs = output_pref(op, arg_ct->alias_index);
29f5e925
RH
4685 if (IS_DEAD_ARG(i1) &&
4686 IS_DEAD_ARG(i2) &&
4687 !temp_readonly(ts) &&
4688 ts->val_type == TEMP_VAL_REG &&
4689 ts->reg < TCG_TARGET_NB_REGS - 1 &&
4690 tcg_regset_test_reg(i_required_regs, reg) &&
4691 !tcg_regset_test_reg(i_allocated_regs, reg) &&
4692 !tcg_regset_test_reg(i_allocated_regs, reg + 1) &&
4693 (ts2
4694 ? ts2->val_type == TEMP_VAL_REG &&
4695 ts2->reg == reg + 1 &&
4696 !temp_readonly(ts2)
4697 : s->reg_to_temp[reg + 1] == NULL)) {
4698 break;
4699 }
4700 } else {
4701 /* Without aliasing, the pair must also be an input. */
4702 tcg_debug_assert(ts2);
4703 if (ts->val_type == TEMP_VAL_REG &&
4704 ts2->val_type == TEMP_VAL_REG &&
4705 ts2->reg == reg + 1 &&
4706 tcg_regset_test_reg(i_required_regs, reg)) {
4707 break;
4708 }
4709 }
4710 reg = tcg_reg_alloc_pair(s, i_required_regs, i_allocated_regs,
4711 0, ts->indirect_base);
4712 goto do_pair;
4713
4714 case 2: /* pair second */
4715 reg = new_args[arg_ct->pair_index] + 1;
4716 goto do_pair;
1c1824dc 4717
29f5e925
RH
4718 case 3: /* ialias with second output, no first input */
4719 tcg_debug_assert(arg_ct->ialias);
31fd884b 4720 i_preferred_regs = output_pref(op, arg_ct->alias_index);
d62816f2 4721
29f5e925
RH
4722 if (IS_DEAD_ARG(i) &&
4723 !temp_readonly(ts) &&
4724 ts->val_type == TEMP_VAL_REG &&
4725 reg > 0 &&
4726 s->reg_to_temp[reg - 1] == NULL &&
4727 tcg_regset_test_reg(i_required_regs, reg) &&
4728 !tcg_regset_test_reg(i_allocated_regs, reg) &&
4729 !tcg_regset_test_reg(i_allocated_regs, reg - 1)) {
4730 tcg_regset_set_reg(i_allocated_regs, reg - 1);
4731 break;
4732 }
4733 reg = tcg_reg_alloc_pair(s, i_required_regs >> 1,
4734 i_allocated_regs, 0,
4735 ts->indirect_base);
4736 tcg_regset_set_reg(i_allocated_regs, reg);
4737 reg += 1;
4738 goto do_pair;
4739
4740 do_pair:
c0522136 4741 /*
29f5e925
RH
4742 * If an aliased input is not dead after the instruction,
4743 * we must allocate a new register and move it.
c0522136 4744 */
29f5e925
RH
4745 if (arg_ct->ialias && (!IS_DEAD_ARG(i) || temp_readonly(ts))) {
4746 TCGRegSet t_allocated_regs = i_allocated_regs;
4747
1c1824dc 4748 /*
29f5e925
RH
4749 * Because of the alias, and the continued life, make sure
4750 * that the temp is somewhere *other* than the reg pair,
4751 * and we get a copy in reg.
1c1824dc 4752 */
29f5e925
RH
4753 tcg_regset_set_reg(t_allocated_regs, reg);
4754 tcg_regset_set_reg(t_allocated_regs, reg + 1);
4755 if (ts->val_type == TEMP_VAL_REG && ts->reg == reg) {
4756 /* If ts was already in reg, copy it somewhere else. */
4757 TCGReg nr;
4758 bool ok;
4759
4760 tcg_debug_assert(ts->kind != TEMP_FIXED);
4761 nr = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
4762 t_allocated_regs, 0, ts->indirect_base);
4763 ok = tcg_out_mov(s, ts->type, nr, reg);
4764 tcg_debug_assert(ok);
4765
4766 set_temp_val_reg(s, ts, nr);
4767 } else {
4768 temp_load(s, ts, tcg_target_available_regs[ts->type],
4769 t_allocated_regs, 0);
4770 copyto_new_reg = true;
4771 }
4772 } else {
4773 /* Preferably allocate to reg, otherwise copy. */
4774 i_required_regs = (TCGRegSet)1 << reg;
4775 temp_load(s, ts, i_required_regs, i_allocated_regs,
4776 i_preferred_regs);
4777 copyto_new_reg = ts->reg != reg;
5ff9d6a4 4778 }
29f5e925 4779 break;
d62816f2 4780
29f5e925
RH
4781 default:
4782 g_assert_not_reached();
1c1824dc 4783 }
d62816f2 4784
29f5e925 4785 if (copyto_new_reg) {
78113e83 4786 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
240c08d0
RH
4787 /*
4788 * Cross register class move not supported. Sync the
4789 * temp back to its slot and load from there.
4790 */
4791 temp_sync(s, ts, i_allocated_regs, 0, 0);
4792 tcg_out_ld(s, ts->type, reg,
4793 ts->mem_base->reg, ts->mem_offset);
78113e83 4794 }
c896fe29 4795 }
c896fe29
FB
4796 new_args[i] = reg;
4797 const_args[i] = 0;
82790a87 4798 tcg_regset_set_reg(i_allocated_regs, reg);
c896fe29 4799 }
a813e36f 4800
a52ad07e
AJ
4801 /* mark dead temporaries and free the associated registers */
4802 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
4803 if (IS_DEAD_ARG(i)) {
43439139 4804 temp_dead(s, arg_temp(op->args[i]));
a52ad07e
AJ
4805 }
4806 }
4807
b4cb76e6
RH
4808 if (def->flags & TCG_OPF_COND_BRANCH) {
4809 tcg_reg_alloc_cbranch(s, i_allocated_regs);
4810 } else if (def->flags & TCG_OPF_BB_END) {
82790a87 4811 tcg_reg_alloc_bb_end(s, i_allocated_regs);
e8996ee0 4812 } else {
e8996ee0 4813 if (def->flags & TCG_OPF_CALL_CLOBBER) {
a813e36f 4814 /* XXX: permit generic clobber register list ? */
c8074023
RH
4815 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
4816 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
82790a87 4817 tcg_reg_free(s, i, i_allocated_regs);
e8996ee0 4818 }
c896fe29 4819 }
3d5c5f87
AJ
4820 }
4821 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
4822 /* sync globals if the op has side effects and might trigger
4823 an exception. */
82790a87 4824 sync_globals(s, i_allocated_regs);
c896fe29 4825 }
a813e36f 4826
e8996ee0 4827 /* satisfy the output constraints */
e8996ee0 4828 for(k = 0; k < nb_oargs; k++) {
66792f90 4829 i = def->args_ct[k].sort_index;
dd186292 4830 arg = op->args[i];
e8996ee0 4831 arg_ct = &def->args_ct[i];
43439139 4832 ts = arg_temp(arg);
d63e3b6e
RH
4833
4834 /* ENV should not be modified. */
e01fa97d 4835 tcg_debug_assert(!temp_readonly(ts));
d63e3b6e 4836
29f5e925
RH
4837 switch (arg_ct->pair) {
4838 case 0: /* not paired */
4839 if (arg_ct->oalias && !const_args[arg_ct->alias_index]) {
4840 reg = new_args[arg_ct->alias_index];
4841 } else if (arg_ct->newreg) {
4842 reg = tcg_reg_alloc(s, arg_ct->regs,
4843 i_allocated_regs | o_allocated_regs,
31fd884b 4844 output_pref(op, k), ts->indirect_base);
29f5e925
RH
4845 } else {
4846 reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs,
31fd884b 4847 output_pref(op, k), ts->indirect_base);
29f5e925
RH
4848 }
4849 break;
4850
4851 case 1: /* first of pair */
4852 tcg_debug_assert(!arg_ct->newreg);
4853 if (arg_ct->oalias) {
4854 reg = new_args[arg_ct->alias_index];
4855 break;
4856 }
4857 reg = tcg_reg_alloc_pair(s, arg_ct->regs, o_allocated_regs,
31fd884b 4858 output_pref(op, k), ts->indirect_base);
29f5e925
RH
4859 break;
4860
4861 case 2: /* second of pair */
4862 tcg_debug_assert(!arg_ct->newreg);
4863 if (arg_ct->oalias) {
4864 reg = new_args[arg_ct->alias_index];
4865 } else {
4866 reg = new_args[arg_ct->pair_index] + 1;
4867 }
4868 break;
4869
4870 case 3: /* first of pair, aliasing with a second input */
4871 tcg_debug_assert(!arg_ct->newreg);
4872 reg = new_args[arg_ct->pair_index] - 1;
4873 break;
4874
4875 default:
4876 g_assert_not_reached();
c896fe29 4877 }
82790a87 4878 tcg_regset_set_reg(o_allocated_regs, reg);
098859f1 4879 set_temp_val_reg(s, ts, reg);
d63e3b6e 4880 ts->mem_coherent = 0;
e8996ee0 4881 new_args[i] = reg;
c896fe29 4882 }
c896fe29
FB
4883 }
4884
c896fe29 4885 /* emit instruction */
678155b2
RH
4886 switch (op->opc) {
4887 case INDEX_op_ext8s_i32:
4888 tcg_out_ext8s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
4889 break;
4890 case INDEX_op_ext8s_i64:
4891 tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
4892 break;
d0e66c89
RH
4893 case INDEX_op_ext8u_i32:
4894 case INDEX_op_ext8u_i64:
4895 tcg_out_ext8u(s, new_args[0], new_args[1]);
4896 break;
753e42ea
RH
4897 case INDEX_op_ext16s_i32:
4898 tcg_out_ext16s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
4899 break;
4900 case INDEX_op_ext16s_i64:
4901 tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
4902 break;
379afdff
RH
4903 case INDEX_op_ext16u_i32:
4904 case INDEX_op_ext16u_i64:
4905 tcg_out_ext16u(s, new_args[0], new_args[1]);
4906 break;
52bf3398
RH
4907 case INDEX_op_ext32s_i64:
4908 tcg_out_ext32s(s, new_args[0], new_args[1]);
4909 break;
9ecf5f61
RH
4910 case INDEX_op_ext32u_i64:
4911 tcg_out_ext32u(s, new_args[0], new_args[1]);
4912 break;
9c6aa274
RH
4913 case INDEX_op_ext_i32_i64:
4914 tcg_out_exts_i32_i64(s, new_args[0], new_args[1]);
4915 break;
b9bfe000
RH
4916 case INDEX_op_extu_i32_i64:
4917 tcg_out_extu_i32_i64(s, new_args[0], new_args[1]);
4918 break;
b8b94ac6
RH
4919 case INDEX_op_extrl_i64_i32:
4920 tcg_out_extrl_i64_i32(s, new_args[0], new_args[1]);
4921 break;
678155b2
RH
4922 default:
4923 if (def->flags & TCG_OPF_VECTOR) {
4924 tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
4925 new_args, const_args);
4926 } else {
4927 tcg_out_op(s, op->opc, new_args, const_args);
4928 }
4929 break;
d2fd745f
RH
4930 }
4931
c896fe29
FB
4932 /* move the outputs in the correct register if needed */
4933 for(i = 0; i < nb_oargs; i++) {
43439139 4934 ts = arg_temp(op->args[i]);
d63e3b6e
RH
4935
4936 /* ENV should not be modified. */
e01fa97d 4937 tcg_debug_assert(!temp_readonly(ts));
d63e3b6e 4938
ec7a869d 4939 if (NEED_SYNC_ARG(i)) {
98b4e186 4940 temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
59d7c14e 4941 } else if (IS_DEAD_ARG(i)) {
f8bf00f1 4942 temp_dead(s, ts);
ec7a869d 4943 }
c896fe29
FB
4944 }
4945}
4946
efe86b21
RH
4947static bool tcg_reg_alloc_dup2(TCGContext *s, const TCGOp *op)
4948{
4949 const TCGLifeData arg_life = op->life;
4950 TCGTemp *ots, *itsl, *itsh;
4951 TCGType vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
4952
4953 /* This opcode is only valid for 32-bit hosts, for 64-bit elements. */
4954 tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
4955 tcg_debug_assert(TCGOP_VECE(op) == MO_64);
4956
4957 ots = arg_temp(op->args[0]);
4958 itsl = arg_temp(op->args[1]);
4959 itsh = arg_temp(op->args[2]);
4960
4961 /* ENV should not be modified. */
4962 tcg_debug_assert(!temp_readonly(ots));
4963
4964 /* Allocate the output register now. */
4965 if (ots->val_type != TEMP_VAL_REG) {
4966 TCGRegSet allocated_regs = s->reserved_regs;
4967 TCGRegSet dup_out_regs =
4968 tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
098859f1 4969 TCGReg oreg;
efe86b21
RH
4970
4971 /* Make sure to not spill the input registers. */
4972 if (!IS_DEAD_ARG(1) && itsl->val_type == TEMP_VAL_REG) {
4973 tcg_regset_set_reg(allocated_regs, itsl->reg);
4974 }
4975 if (!IS_DEAD_ARG(2) && itsh->val_type == TEMP_VAL_REG) {
4976 tcg_regset_set_reg(allocated_regs, itsh->reg);
4977 }
4978
098859f1 4979 oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
31fd884b 4980 output_pref(op, 0), ots->indirect_base);
098859f1 4981 set_temp_val_reg(s, ots, oreg);
efe86b21
RH
4982 }
4983
4984 /* Promote dup2 of immediates to dupi_vec. */
4985 if (itsl->val_type == TEMP_VAL_CONST && itsh->val_type == TEMP_VAL_CONST) {
4986 uint64_t val = deposit64(itsl->val, 32, 32, itsh->val);
4987 MemOp vece = MO_64;
4988
4989 if (val == dup_const(MO_8, val)) {
4990 vece = MO_8;
4991 } else if (val == dup_const(MO_16, val)) {
4992 vece = MO_16;
4993 } else if (val == dup_const(MO_32, val)) {
4994 vece = MO_32;
4995 }
4996
4997 tcg_out_dupi_vec(s, vtype, vece, ots->reg, val);
4998 goto done;
4999 }
5000
5001 /* If the two inputs form one 64-bit value, try dupm_vec. */
aef85402
RH
5002 if (itsl->temp_subindex == HOST_BIG_ENDIAN &&
5003 itsh->temp_subindex == !HOST_BIG_ENDIAN &&
5004 itsl == itsh + (HOST_BIG_ENDIAN ? 1 : -1)) {
5005 TCGTemp *its = itsl - HOST_BIG_ENDIAN;
5006
5007 temp_sync(s, its + 0, s->reserved_regs, 0, 0);
5008 temp_sync(s, its + 1, s->reserved_regs, 0, 0);
5009
efe86b21
RH
5010 if (tcg_out_dupm_vec(s, vtype, MO_64, ots->reg,
5011 its->mem_base->reg, its->mem_offset)) {
5012 goto done;
5013 }
5014 }
5015
5016 /* Fall back to generic expansion. */
5017 return false;
5018
5019 done:
36f5539c 5020 ots->mem_coherent = 0;
efe86b21
RH
5021 if (IS_DEAD_ARG(1)) {
5022 temp_dead(s, itsl);
5023 }
5024 if (IS_DEAD_ARG(2)) {
5025 temp_dead(s, itsh);
5026 }
5027 if (NEED_SYNC_ARG(0)) {
5028 temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
5029 } else if (IS_DEAD_ARG(0)) {
5030 temp_dead(s, ots);
5031 }
5032 return true;
5033}
5034
39004a71
RH
5035static void load_arg_reg(TCGContext *s, TCGReg reg, TCGTemp *ts,
5036 TCGRegSet allocated_regs)
c896fe29 5037{
39004a71
RH
5038 if (ts->val_type == TEMP_VAL_REG) {
5039 if (ts->reg != reg) {
5040 tcg_reg_free(s, reg, allocated_regs);
5041 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
5042 /*
5043 * Cross register class move not supported. Sync the
5044 * temp back to its slot and load from there.
5045 */
5046 temp_sync(s, ts, allocated_regs, 0, 0);
5047 tcg_out_ld(s, ts->type, reg,
5048 ts->mem_base->reg, ts->mem_offset);
5049 }
5050 }
5051 } else {
5052 TCGRegSet arg_set = 0;
c896fe29 5053
39004a71
RH
5054 tcg_reg_free(s, reg, allocated_regs);
5055 tcg_regset_set_reg(arg_set, reg);
5056 temp_load(s, ts, arg_set, allocated_regs, 0);
b03cce8e 5057 }
39004a71 5058}
39cf05d3 5059
d78e4a4f 5060static void load_arg_stk(TCGContext *s, unsigned arg_slot, TCGTemp *ts,
39004a71
RH
5061 TCGRegSet allocated_regs)
5062{
5063 /*
5064 * When the destination is on the stack, load up the temp and store.
5065 * If there are many call-saved registers, the temp might live to
5066 * see another use; otherwise it'll be discarded.
5067 */
5068 temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs, 0);
5069 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK,
d78e4a4f 5070 arg_slot_stk_ofs(arg_slot));
39004a71 5071}
a813e36f 5072
39004a71
RH
5073static void load_arg_normal(TCGContext *s, const TCGCallArgumentLoc *l,
5074 TCGTemp *ts, TCGRegSet *allocated_regs)
5075{
338b61e9 5076 if (arg_slot_reg_p(l->arg_slot)) {
39004a71
RH
5077 TCGReg reg = tcg_target_call_iarg_regs[l->arg_slot];
5078 load_arg_reg(s, reg, ts, *allocated_regs);
5079 tcg_regset_set_reg(*allocated_regs, reg);
5080 } else {
d78e4a4f 5081 load_arg_stk(s, l->arg_slot, ts, *allocated_regs);
39004a71
RH
5082 }
5083}
40ae5c62 5084
d78e4a4f 5085static void load_arg_ref(TCGContext *s, unsigned arg_slot, TCGReg ref_base,
313bdea8
RH
5086 intptr_t ref_off, TCGRegSet *allocated_regs)
5087{
5088 TCGReg reg;
313bdea8 5089
d78e4a4f 5090 if (arg_slot_reg_p(arg_slot)) {
313bdea8
RH
5091 reg = tcg_target_call_iarg_regs[arg_slot];
5092 tcg_reg_free(s, reg, *allocated_regs);
5093 tcg_out_addi_ptr(s, reg, ref_base, ref_off);
5094 tcg_regset_set_reg(*allocated_regs, reg);
5095 } else {
5096 reg = tcg_reg_alloc(s, tcg_target_available_regs[TCG_TYPE_PTR],
5097 *allocated_regs, 0, false);
5098 tcg_out_addi_ptr(s, reg, ref_base, ref_off);
5099 tcg_out_st(s, TCG_TYPE_PTR, reg, TCG_REG_CALL_STACK,
d78e4a4f 5100 arg_slot_stk_ofs(arg_slot));
313bdea8
RH
5101 }
5102}
5103
39004a71
RH
5104static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
5105{
5106 const int nb_oargs = TCGOP_CALLO(op);
5107 const int nb_iargs = TCGOP_CALLI(op);
5108 const TCGLifeData arg_life = op->life;
5109 const TCGHelperInfo *info = tcg_call_info(op);
5110 TCGRegSet allocated_regs = s->reserved_regs;
5111 int i;
40ae5c62 5112
39004a71
RH
5113 /*
5114 * Move inputs into place in reverse order,
5115 * so that we place stacked arguments first.
5116 */
5117 for (i = nb_iargs - 1; i >= 0; --i) {
5118 const TCGCallArgumentLoc *loc = &info->in[i];
5119 TCGTemp *ts = arg_temp(op->args[nb_oargs + i]);
40ae5c62 5120
39004a71
RH
5121 switch (loc->kind) {
5122 case TCG_CALL_ARG_NORMAL:
5123 case TCG_CALL_ARG_EXTEND_U:
5124 case TCG_CALL_ARG_EXTEND_S:
5125 load_arg_normal(s, loc, ts, &allocated_regs);
5126 break;
313bdea8
RH
5127 case TCG_CALL_ARG_BY_REF:
5128 load_arg_stk(s, loc->ref_slot, ts, allocated_regs);
5129 load_arg_ref(s, loc->arg_slot, TCG_REG_CALL_STACK,
d78e4a4f 5130 arg_slot_stk_ofs(loc->ref_slot),
313bdea8
RH
5131 &allocated_regs);
5132 break;
5133 case TCG_CALL_ARG_BY_REF_N:
5134 load_arg_stk(s, loc->ref_slot, ts, allocated_regs);
5135 break;
39004a71
RH
5136 default:
5137 g_assert_not_reached();
c896fe29 5138 }
c896fe29 5139 }
a813e36f 5140
39004a71 5141 /* Mark dead temporaries and free the associated registers. */
dd186292 5142 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 5143 if (IS_DEAD_ARG(i)) {
43439139 5144 temp_dead(s, arg_temp(op->args[i]));
c896fe29
FB
5145 }
5146 }
a813e36f 5147
39004a71 5148 /* Clobber call registers. */
c8074023
RH
5149 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
5150 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
b3915dbb 5151 tcg_reg_free(s, i, allocated_regs);
c896fe29
FB
5152 }
5153 }
78505279 5154
39004a71
RH
5155 /*
5156 * Save globals if they might be written by the helper,
5157 * sync them if they might be read.
5158 */
5159 if (info->flags & TCG_CALL_NO_READ_GLOBALS) {
78505279 5160 /* Nothing to do */
39004a71 5161 } else if (info->flags & TCG_CALL_NO_WRITE_GLOBALS) {
78505279
AJ
5162 sync_globals(s, allocated_regs);
5163 } else {
b9c18f56
AJ
5164 save_globals(s, allocated_regs);
5165 }
c896fe29 5166
313bdea8
RH
5167 /*
5168 * If the ABI passes a pointer to the returned struct as the first
5169 * argument, load that now. Pass a pointer to the output home slot.
5170 */
5171 if (info->out_kind == TCG_CALL_RET_BY_REF) {
5172 TCGTemp *ts = arg_temp(op->args[0]);
5173
5174 if (!ts->mem_allocated) {
5175 temp_allocate_frame(s, ts);
5176 }
5177 load_arg_ref(s, 0, ts->mem_base->reg, ts->mem_offset, &allocated_regs);
5178 }
5179
cee44b03 5180 tcg_out_call(s, tcg_call_func(op), info);
c896fe29 5181
39004a71
RH
5182 /* Assign output registers and emit moves if needed. */
5183 switch (info->out_kind) {
5184 case TCG_CALL_RET_NORMAL:
5185 for (i = 0; i < nb_oargs; i++) {
5186 TCGTemp *ts = arg_temp(op->args[i]);
5e3d0c19 5187 TCGReg reg = tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, i);
d63e3b6e 5188
39004a71
RH
5189 /* ENV should not be modified. */
5190 tcg_debug_assert(!temp_readonly(ts));
d63e3b6e 5191
39004a71
RH
5192 set_temp_val_reg(s, ts, reg);
5193 ts->mem_coherent = 0;
5194 }
5195 break;
313bdea8 5196
c6556aa0
RH
5197 case TCG_CALL_RET_BY_VEC:
5198 {
5199 TCGTemp *ts = arg_temp(op->args[0]);
5200
5201 tcg_debug_assert(ts->base_type == TCG_TYPE_I128);
5202 tcg_debug_assert(ts->temp_subindex == 0);
5203 if (!ts->mem_allocated) {
5204 temp_allocate_frame(s, ts);
5205 }
5206 tcg_out_st(s, TCG_TYPE_V128,
5207 tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0),
5208 ts->mem_base->reg, ts->mem_offset);
5209 }
5210 /* fall through to mark all parts in memory */
5211
313bdea8
RH
5212 case TCG_CALL_RET_BY_REF:
5213 /* The callee has performed a write through the reference. */
5214 for (i = 0; i < nb_oargs; i++) {
5215 TCGTemp *ts = arg_temp(op->args[i]);
5216 ts->val_type = TEMP_VAL_MEM;
5217 }
5218 break;
5219
39004a71
RH
5220 default:
5221 g_assert_not_reached();
5222 }
5223
5224 /* Flush or discard output registers as needed. */
5225 for (i = 0; i < nb_oargs; i++) {
5226 TCGTemp *ts = arg_temp(op->args[i]);
d63e3b6e 5227 if (NEED_SYNC_ARG(i)) {
39004a71 5228 temp_sync(s, ts, s->reserved_regs, 0, IS_DEAD_ARG(i));
d63e3b6e
RH
5229 } else if (IS_DEAD_ARG(i)) {
5230 temp_dead(s, ts);
c896fe29
FB
5231 }
5232 }
c896fe29
FB
5233}
5234
e63b8a29
RH
5235/**
5236 * atom_and_align_for_opc:
5237 * @s: tcg context
5238 * @opc: memory operation code
5239 * @host_atom: MO_ATOM_{IFALIGN,WITHIN16,SUBALIGN} for host operations
5240 * @allow_two_ops: true if we are prepared to issue two operations
5241 *
5242 * Return the alignment and atomicity to use for the inline fast path
5243 * for the given memory operation. The alignment may be larger than
5244 * that specified in @opc, and the correct alignment will be diagnosed
5245 * by the slow path helper.
5246 *
5247 * If @allow_two_ops, the host is prepared to test for 2x alignment,
5248 * and issue two loads or stores for subalignment.
5249 */
5250static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc,
5251 MemOp host_atom, bool allow_two_ops)
5252{
5253 MemOp align = get_alignment_bits(opc);
5254 MemOp size = opc & MO_SIZE;
5255 MemOp half = size ? size - 1 : 0;
5256 MemOp atmax;
5257 MemOp atom;
5258
5259 /* When serialized, no further atomicity required. */
5260 if (s->gen_tb->cflags & CF_PARALLEL) {
5261 atom = opc & MO_ATOM_MASK;
5262 } else {
5263 atom = MO_ATOM_NONE;
5264 }
5265
5266 switch (atom) {
5267 case MO_ATOM_NONE:
5268 /* The operation requires no specific atomicity. */
5269 atmax = MO_8;
5270 break;
5271
5272 case MO_ATOM_IFALIGN:
5273 atmax = size;
5274 break;
5275
5276 case MO_ATOM_IFALIGN_PAIR:
5277 atmax = half;
5278 break;
5279
5280 case MO_ATOM_WITHIN16:
5281 atmax = size;
5282 if (size == MO_128) {
5283 /* Misalignment implies !within16, and therefore no atomicity. */
5284 } else if (host_atom != MO_ATOM_WITHIN16) {
5285 /* The host does not implement within16, so require alignment. */
5286 align = MAX(align, size);
5287 }
5288 break;
5289
5290 case MO_ATOM_WITHIN16_PAIR:
5291 atmax = size;
5292 /*
5293 * Misalignment implies !within16, and therefore half atomicity.
5294 * Any host prepared for two operations can implement this with
5295 * half alignment.
5296 */
5297 if (host_atom != MO_ATOM_WITHIN16 && allow_two_ops) {
5298 align = MAX(align, half);
5299 }
5300 break;
5301
5302 case MO_ATOM_SUBALIGN:
5303 atmax = size;
5304 if (host_atom != MO_ATOM_SUBALIGN) {
5305 /* If unaligned but not odd, there are subobjects up to half. */
5306 if (allow_two_ops) {
5307 align = MAX(align, half);
5308 } else {
5309 align = MAX(align, size);
5310 }
5311 }
5312 break;
5313
5314 default:
5315 g_assert_not_reached();
5316 }
5317
5318 return (TCGAtomAlign){ .atom = atmax, .align = align };
5319}
5320
8429a1ca
RH
5321/*
5322 * Similarly for qemu_ld/st slow path helpers.
5323 * We must re-implement tcg_gen_callN and tcg_reg_alloc_call simultaneously,
5324 * using only the provided backend tcg_out_* functions.
5325 */
5326
5327static int tcg_out_helper_stk_ofs(TCGType type, unsigned slot)
5328{
5329 int ofs = arg_slot_stk_ofs(slot);
5330
5331 /*
5332 * Each stack slot is TCG_TARGET_LONG_BITS. If the host does not
5333 * require extension to uint64_t, adjust the address for uint32_t.
5334 */
5335 if (HOST_BIG_ENDIAN &&
5336 TCG_TARGET_REG_BITS == 64 &&
5337 type == TCG_TYPE_I32) {
5338 ofs += 4;
5339 }
5340 return ofs;
5341}
5342
8d314041
RH
5343static void tcg_out_helper_load_slots(TCGContext *s,
5344 unsigned nmov, TCGMovExtend *mov,
5345 const TCGLdstHelperParam *parm)
8429a1ca 5346{
8d314041 5347 unsigned i;
2462e30e
RH
5348 TCGReg dst3;
5349
8d314041
RH
5350 /*
5351 * Start from the end, storing to the stack first.
5352 * This frees those registers, so we need not consider overlap.
5353 */
5354 for (i = nmov; i-- > 0; ) {
5355 unsigned slot = mov[i].dst;
5356
5357 if (arg_slot_reg_p(slot)) {
5358 goto found_reg;
5359 }
5360
5361 TCGReg src = mov[i].src;
5362 TCGType dst_type = mov[i].dst_type;
5363 MemOp dst_mo = dst_type == TCG_TYPE_I32 ? MO_32 : MO_64;
5364
5365 /* The argument is going onto the stack; extend into scratch. */
5366 if ((mov[i].src_ext & MO_SIZE) != dst_mo) {
5367 tcg_debug_assert(parm->ntmp != 0);
5368 mov[i].dst = src = parm->tmp[0];
5369 tcg_out_movext1(s, &mov[i]);
5370 }
5371
5372 tcg_out_st(s, dst_type, src, TCG_REG_CALL_STACK,
5373 tcg_out_helper_stk_ofs(dst_type, slot));
5374 }
5375 return;
5376
5377 found_reg:
5378 /*
5379 * The remaining arguments are in registers.
5380 * Convert slot numbers to argument registers.
5381 */
5382 nmov = i + 1;
5383 for (i = 0; i < nmov; ++i) {
5384 mov[i].dst = tcg_target_call_iarg_regs[mov[i].dst];
5385 }
5386
8429a1ca 5387 switch (nmov) {
2462e30e 5388 case 4:
8429a1ca 5389 /* The backend must have provided enough temps for the worst case. */
2462e30e 5390 tcg_debug_assert(parm->ntmp >= 2);
8429a1ca 5391
2462e30e
RH
5392 dst3 = mov[3].dst;
5393 for (unsigned j = 0; j < 3; ++j) {
5394 if (dst3 == mov[j].src) {
5395 /*
5396 * Conflict. Copy the source to a temporary, perform the
5397 * remaining moves, then the extension from our scratch
5398 * on the way out.
5399 */
5400 TCGReg scratch = parm->tmp[1];
8429a1ca 5401
2462e30e
RH
5402 tcg_out_mov(s, mov[3].src_type, scratch, mov[3].src);
5403 tcg_out_movext3(s, mov, mov + 1, mov + 2, parm->tmp[0]);
5404 tcg_out_movext1_new_src(s, &mov[3], scratch);
5405 break;
8429a1ca 5406 }
8429a1ca 5407 }
8429a1ca 5408
2462e30e
RH
5409 /* No conflicts: perform this move and continue. */
5410 tcg_out_movext1(s, &mov[3]);
5411 /* fall through */
5412
5413 case 3:
5414 tcg_out_movext3(s, mov, mov + 1, mov + 2,
5415 parm->ntmp ? parm->tmp[0] : -1);
5416 break;
8429a1ca 5417 case 2:
2462e30e
RH
5418 tcg_out_movext2(s, mov, mov + 1,
5419 parm->ntmp ? parm->tmp[0] : -1);
5420 break;
8429a1ca
RH
5421 case 1:
5422 tcg_out_movext1(s, mov);
2462e30e
RH
5423 break;
5424 default:
8429a1ca
RH
5425 g_assert_not_reached();
5426 }
5427}
5428
8429a1ca
RH
5429static void tcg_out_helper_load_imm(TCGContext *s, unsigned slot,
5430 TCGType type, tcg_target_long imm,
5431 const TCGLdstHelperParam *parm)
5432{
5433 if (arg_slot_reg_p(slot)) {
5434 tcg_out_movi(s, type, tcg_target_call_iarg_regs[slot], imm);
5435 } else {
5436 int ofs = tcg_out_helper_stk_ofs(type, slot);
5437 if (!tcg_out_sti(s, type, imm, TCG_REG_CALL_STACK, ofs)) {
5438 tcg_debug_assert(parm->ntmp != 0);
5439 tcg_out_movi(s, type, parm->tmp[0], imm);
5440 tcg_out_st(s, type, parm->tmp[0], TCG_REG_CALL_STACK, ofs);
5441 }
5442 }
5443}
5444
5445static void tcg_out_helper_load_common_args(TCGContext *s,
5446 const TCGLabelQemuLdst *ldst,
5447 const TCGLdstHelperParam *parm,
5448 const TCGHelperInfo *info,
5449 unsigned next_arg)
5450{
5451 TCGMovExtend ptr_mov = {
5452 .dst_type = TCG_TYPE_PTR,
5453 .src_type = TCG_TYPE_PTR,
5454 .src_ext = sizeof(void *) == 4 ? MO_32 : MO_64
5455 };
5456 const TCGCallArgumentLoc *loc = &info->in[0];
5457 TCGType type;
5458 unsigned slot;
5459 tcg_target_ulong imm;
5460
5461 /*
5462 * Handle env, which is always first.
5463 */
5464 ptr_mov.dst = loc->arg_slot;
5465 ptr_mov.src = TCG_AREG0;
5466 tcg_out_helper_load_slots(s, 1, &ptr_mov, parm);
5467
5468 /*
5469 * Handle oi.
5470 */
5471 imm = ldst->oi;
5472 loc = &info->in[next_arg];
5473 type = TCG_TYPE_I32;
5474 switch (loc->kind) {
5475 case TCG_CALL_ARG_NORMAL:
5476 break;
5477 case TCG_CALL_ARG_EXTEND_U:
5478 case TCG_CALL_ARG_EXTEND_S:
5479 /* No extension required for MemOpIdx. */
5480 tcg_debug_assert(imm <= INT32_MAX);
5481 type = TCG_TYPE_REG;
5482 break;
5483 default:
5484 g_assert_not_reached();
5485 }
5486 tcg_out_helper_load_imm(s, loc->arg_slot, type, imm, parm);
5487 next_arg++;
5488
5489 /*
5490 * Handle ra.
5491 */
5492 loc = &info->in[next_arg];
5493 slot = loc->arg_slot;
5494 if (parm->ra_gen) {
5495 int arg_reg = -1;
5496 TCGReg ra_reg;
5497
5498 if (arg_slot_reg_p(slot)) {
5499 arg_reg = tcg_target_call_iarg_regs[slot];
5500 }
5501 ra_reg = parm->ra_gen(s, ldst, arg_reg);
5502
5503 ptr_mov.dst = slot;
5504 ptr_mov.src = ra_reg;
5505 tcg_out_helper_load_slots(s, 1, &ptr_mov, parm);
5506 } else {
5507 imm = (uintptr_t)ldst->raddr;
5508 tcg_out_helper_load_imm(s, slot, TCG_TYPE_PTR, imm, parm);
5509 }
5510}
5511
5512static unsigned tcg_out_helper_add_mov(TCGMovExtend *mov,
5513 const TCGCallArgumentLoc *loc,
5514 TCGType dst_type, TCGType src_type,
5515 TCGReg lo, TCGReg hi)
5516{
ebebea53
RH
5517 MemOp reg_mo;
5518
8429a1ca
RH
5519 if (dst_type <= TCG_TYPE_REG) {
5520 MemOp src_ext;
5521
5522 switch (loc->kind) {
5523 case TCG_CALL_ARG_NORMAL:
5524 src_ext = src_type == TCG_TYPE_I32 ? MO_32 : MO_64;
5525 break;
5526 case TCG_CALL_ARG_EXTEND_U:
5527 dst_type = TCG_TYPE_REG;
5528 src_ext = MO_UL;
5529 break;
5530 case TCG_CALL_ARG_EXTEND_S:
5531 dst_type = TCG_TYPE_REG;
5532 src_ext = MO_SL;
5533 break;
5534 default:
5535 g_assert_not_reached();
5536 }
5537
5538 mov[0].dst = loc->arg_slot;
5539 mov[0].dst_type = dst_type;
5540 mov[0].src = lo;
5541 mov[0].src_type = src_type;
5542 mov[0].src_ext = src_ext;
5543 return 1;
5544 }
5545
ebebea53
RH
5546 if (TCG_TARGET_REG_BITS == 32) {
5547 assert(dst_type == TCG_TYPE_I64);
5548 reg_mo = MO_32;
5549 } else {
5550 assert(dst_type == TCG_TYPE_I128);
5551 reg_mo = MO_64;
5552 }
8429a1ca
RH
5553
5554 mov[0].dst = loc[HOST_BIG_ENDIAN].arg_slot;
5555 mov[0].src = lo;
ebebea53
RH
5556 mov[0].dst_type = TCG_TYPE_REG;
5557 mov[0].src_type = TCG_TYPE_REG;
5558 mov[0].src_ext = reg_mo;
8429a1ca
RH
5559
5560 mov[1].dst = loc[!HOST_BIG_ENDIAN].arg_slot;
5561 mov[1].src = hi;
ebebea53
RH
5562 mov[1].dst_type = TCG_TYPE_REG;
5563 mov[1].src_type = TCG_TYPE_REG;
5564 mov[1].src_ext = reg_mo;
8429a1ca
RH
5565
5566 return 2;
5567}
5568
5569static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
5570 const TCGLdstHelperParam *parm)
5571{
5572 const TCGHelperInfo *info;
5573 const TCGCallArgumentLoc *loc;
5574 TCGMovExtend mov[2];
5575 unsigned next_arg, nmov;
5576 MemOp mop = get_memop(ldst->oi);
5577
5578 switch (mop & MO_SIZE) {
5579 case MO_8:
5580 case MO_16:
5581 case MO_32:
5582 info = &info_helper_ld32_mmu;
5583 break;
5584 case MO_64:
5585 info = &info_helper_ld64_mmu;
5586 break;
ebebea53
RH
5587 case MO_128:
5588 info = &info_helper_ld128_mmu;
5589 break;
8429a1ca
RH
5590 default:
5591 g_assert_not_reached();
5592 }
5593
5594 /* Defer env argument. */
5595 next_arg = 1;
5596
5597 loc = &info->in[next_arg];
c31e5fa4 5598 if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
24e46e6c
RH
5599 /*
5600 * 32-bit host with 32-bit guest: zero-extend the guest address
5601 * to 64-bits for the helper by storing the low part, then
5602 * load a zero for the high part.
5603 */
5604 tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
5605 TCG_TYPE_I32, TCG_TYPE_I32,
5606 ldst->addrlo_reg, -1);
5607 tcg_out_helper_load_slots(s, 1, mov, parm);
8429a1ca 5608
24e46e6c
RH
5609 tcg_out_helper_load_imm(s, loc[!HOST_BIG_ENDIAN].arg_slot,
5610 TCG_TYPE_I32, 0, parm);
5611 next_arg += 2;
c31e5fa4
RH
5612 } else {
5613 nmov = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
5614 ldst->addrlo_reg, ldst->addrhi_reg);
5615 tcg_out_helper_load_slots(s, nmov, mov, parm);
5616 next_arg += nmov;
24e46e6c 5617 }
8429a1ca 5618
ebebea53
RH
5619 switch (info->out_kind) {
5620 case TCG_CALL_RET_NORMAL:
5621 case TCG_CALL_RET_BY_VEC:
5622 break;
5623 case TCG_CALL_RET_BY_REF:
5624 /*
5625 * The return reference is in the first argument slot.
5626 * We need memory in which to return: re-use the top of stack.
5627 */
5628 {
5629 int ofs_slot0 = TCG_TARGET_CALL_STACK_OFFSET;
5630
5631 if (arg_slot_reg_p(0)) {
5632 tcg_out_addi_ptr(s, tcg_target_call_iarg_regs[0],
5633 TCG_REG_CALL_STACK, ofs_slot0);
5634 } else {
5635 tcg_debug_assert(parm->ntmp != 0);
5636 tcg_out_addi_ptr(s, parm->tmp[0],
5637 TCG_REG_CALL_STACK, ofs_slot0);
5638 tcg_out_st(s, TCG_TYPE_PTR, parm->tmp[0],
5639 TCG_REG_CALL_STACK, ofs_slot0);
5640 }
5641 }
5642 break;
5643 default:
5644 g_assert_not_reached();
5645 }
8429a1ca
RH
5646
5647 tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg);
5648}
5649
5650static void tcg_out_ld_helper_ret(TCGContext *s, const TCGLabelQemuLdst *ldst,
5651 bool load_sign,
5652 const TCGLdstHelperParam *parm)
5653{
ebebea53 5654 MemOp mop = get_memop(ldst->oi);
8429a1ca 5655 TCGMovExtend mov[2];
ebebea53 5656 int ofs_slot0;
8429a1ca 5657
ebebea53
RH
5658 switch (ldst->type) {
5659 case TCG_TYPE_I64:
5660 if (TCG_TARGET_REG_BITS == 32) {
5661 break;
5662 }
5663 /* fall through */
8429a1ca 5664
ebebea53 5665 case TCG_TYPE_I32:
8429a1ca
RH
5666 mov[0].dst = ldst->datalo_reg;
5667 mov[0].src = tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, 0);
5668 mov[0].dst_type = ldst->type;
5669 mov[0].src_type = TCG_TYPE_REG;
5670
5671 /*
5672 * If load_sign, then we allowed the helper to perform the
5673 * appropriate sign extension to tcg_target_ulong, and all
5674 * we need now is a plain move.
5675 *
5676 * If they do not, then we expect the relevant extension
5677 * instruction to be no more expensive than a move, and
5678 * we thus save the icache etc by only using one of two
5679 * helper functions.
5680 */
5681 if (load_sign || !(mop & MO_SIGN)) {
5682 if (TCG_TARGET_REG_BITS == 32 || ldst->type == TCG_TYPE_I32) {
5683 mov[0].src_ext = MO_32;
5684 } else {
5685 mov[0].src_ext = MO_64;
5686 }
5687 } else {
5688 mov[0].src_ext = mop & MO_SSIZE;
5689 }
5690 tcg_out_movext1(s, mov);
ebebea53 5691 return;
8429a1ca 5692
ebebea53
RH
5693 case TCG_TYPE_I128:
5694 tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
5695 ofs_slot0 = TCG_TARGET_CALL_STACK_OFFSET;
5696 switch (TCG_TARGET_CALL_RET_I128) {
5697 case TCG_CALL_RET_NORMAL:
5698 break;
5699 case TCG_CALL_RET_BY_VEC:
5700 tcg_out_st(s, TCG_TYPE_V128,
5701 tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0),
5702 TCG_REG_CALL_STACK, ofs_slot0);
5703 /* fall through */
5704 case TCG_CALL_RET_BY_REF:
5705 tcg_out_ld(s, TCG_TYPE_I64, ldst->datalo_reg,
5706 TCG_REG_CALL_STACK, ofs_slot0 + 8 * HOST_BIG_ENDIAN);
5707 tcg_out_ld(s, TCG_TYPE_I64, ldst->datahi_reg,
5708 TCG_REG_CALL_STACK, ofs_slot0 + 8 * !HOST_BIG_ENDIAN);
5709 return;
5710 default:
5711 g_assert_not_reached();
5712 }
5713 break;
8429a1ca 5714
ebebea53
RH
5715 default:
5716 g_assert_not_reached();
8429a1ca 5717 }
ebebea53
RH
5718
5719 mov[0].dst = ldst->datalo_reg;
5720 mov[0].src =
5721 tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, HOST_BIG_ENDIAN);
723d3a27
RH
5722 mov[0].dst_type = TCG_TYPE_REG;
5723 mov[0].src_type = TCG_TYPE_REG;
ebebea53
RH
5724 mov[0].src_ext = TCG_TARGET_REG_BITS == 32 ? MO_32 : MO_64;
5725
5726 mov[1].dst = ldst->datahi_reg;
5727 mov[1].src =
5728 tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, !HOST_BIG_ENDIAN);
5729 mov[1].dst_type = TCG_TYPE_REG;
5730 mov[1].src_type = TCG_TYPE_REG;
5731 mov[1].src_ext = TCG_TARGET_REG_BITS == 32 ? MO_32 : MO_64;
5732
5733 tcg_out_movext2(s, mov, mov + 1, parm->ntmp ? parm->tmp[0] : -1);
8429a1ca
RH
5734}
5735
5736static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
5737 const TCGLdstHelperParam *parm)
5738{
5739 const TCGHelperInfo *info;
5740 const TCGCallArgumentLoc *loc;
5741 TCGMovExtend mov[4];
5742 TCGType data_type;
5743 unsigned next_arg, nmov, n;
5744 MemOp mop = get_memop(ldst->oi);
5745
5746 switch (mop & MO_SIZE) {
5747 case MO_8:
5748 case MO_16:
5749 case MO_32:
5750 info = &info_helper_st32_mmu;
5751 data_type = TCG_TYPE_I32;
5752 break;
5753 case MO_64:
5754 info = &info_helper_st64_mmu;
5755 data_type = TCG_TYPE_I64;
5756 break;
ebebea53
RH
5757 case MO_128:
5758 info = &info_helper_st128_mmu;
5759 data_type = TCG_TYPE_I128;
5760 break;
8429a1ca
RH
5761 default:
5762 g_assert_not_reached();
5763 }
5764
5765 /* Defer env argument. */
5766 next_arg = 1;
5767 nmov = 0;
5768
5769 /* Handle addr argument. */
5770 loc = &info->in[next_arg];
c31e5fa4 5771 if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
24e46e6c
RH
5772 /*
5773 * 32-bit host with 32-bit guest: zero-extend the guest address
5774 * to 64-bits for the helper by storing the low part. Later,
5775 * after we have processed the register inputs, we will load a
5776 * zero for the high part.
5777 */
5778 tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
5779 TCG_TYPE_I32, TCG_TYPE_I32,
5780 ldst->addrlo_reg, -1);
5781 next_arg += 2;
5782 nmov += 1;
c31e5fa4
RH
5783 } else {
5784 n = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
5785 ldst->addrlo_reg, ldst->addrhi_reg);
5786 next_arg += n;
5787 nmov += n;
24e46e6c 5788 }
8429a1ca
RH
5789
5790 /* Handle data argument. */
5791 loc = &info->in[next_arg];
ebebea53
RH
5792 switch (loc->kind) {
5793 case TCG_CALL_ARG_NORMAL:
5794 case TCG_CALL_ARG_EXTEND_U:
5795 case TCG_CALL_ARG_EXTEND_S:
5796 n = tcg_out_helper_add_mov(mov + nmov, loc, data_type, ldst->type,
5797 ldst->datalo_reg, ldst->datahi_reg);
5798 next_arg += n;
5799 nmov += n;
5800 tcg_out_helper_load_slots(s, nmov, mov, parm);
5801 break;
5802
5803 case TCG_CALL_ARG_BY_REF:
5804 tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
5805 tcg_debug_assert(data_type == TCG_TYPE_I128);
5806 tcg_out_st(s, TCG_TYPE_I64,
5807 HOST_BIG_ENDIAN ? ldst->datahi_reg : ldst->datalo_reg,
5808 TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc[0].ref_slot));
5809 tcg_out_st(s, TCG_TYPE_I64,
5810 HOST_BIG_ENDIAN ? ldst->datalo_reg : ldst->datahi_reg,
5811 TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc[1].ref_slot));
5812
5813 tcg_out_helper_load_slots(s, nmov, mov, parm);
5814
5815 if (arg_slot_reg_p(loc->arg_slot)) {
5816 tcg_out_addi_ptr(s, tcg_target_call_iarg_regs[loc->arg_slot],
5817 TCG_REG_CALL_STACK,
5818 arg_slot_stk_ofs(loc->ref_slot));
5819 } else {
5820 tcg_debug_assert(parm->ntmp != 0);
5821 tcg_out_addi_ptr(s, parm->tmp[0], TCG_REG_CALL_STACK,
5822 arg_slot_stk_ofs(loc->ref_slot));
5823 tcg_out_st(s, TCG_TYPE_PTR, parm->tmp[0],
5824 TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc->arg_slot));
5825 }
5826 next_arg += 2;
5827 break;
5828
5829 default:
5830 g_assert_not_reached();
5831 }
8429a1ca 5832
c31e5fa4
RH
5833 if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
5834 /* Zero extend the address by loading a zero for the high part. */
24e46e6c
RH
5835 loc = &info->in[1 + !HOST_BIG_ENDIAN];
5836 tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm);
5837 }
5838
8429a1ca
RH
5839 tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg);
5840}
5841
c896fe29
FB
5842#ifdef CONFIG_PROFILER
5843
c3fac113
EC
5844/* avoid copy/paste errors */
5845#define PROF_ADD(to, from, field) \
5846 do { \
d73415a3 5847 (to)->field += qatomic_read(&((from)->field)); \
c3fac113
EC
5848 } while (0)
5849
5850#define PROF_MAX(to, from, field) \
5851 do { \
d73415a3 5852 typeof((from)->field) val__ = qatomic_read(&((from)->field)); \
c3fac113
EC
5853 if (val__ > (to)->field) { \
5854 (to)->field = val__; \
5855 } \
5856 } while (0)
5857
5858/* Pass in a zero'ed @prof */
5859static inline
5860void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
5861{
0e2d61cf 5862 unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
c3fac113
EC
5863 unsigned int i;
5864
3468b59e 5865 for (i = 0; i < n_ctxs; i++) {
d73415a3 5866 TCGContext *s = qatomic_read(&tcg_ctxs[i]);
3468b59e 5867 const TCGProfile *orig = &s->prof;
c3fac113
EC
5868
5869 if (counters) {
72fd2efb 5870 PROF_ADD(prof, orig, cpu_exec_time);
c3fac113
EC
5871 PROF_ADD(prof, orig, tb_count1);
5872 PROF_ADD(prof, orig, tb_count);
5873 PROF_ADD(prof, orig, op_count);
5874 PROF_MAX(prof, orig, op_count_max);
5875 PROF_ADD(prof, orig, temp_count);
5876 PROF_MAX(prof, orig, temp_count_max);
5877 PROF_ADD(prof, orig, del_op_count);
5878 PROF_ADD(prof, orig, code_in_len);
5879 PROF_ADD(prof, orig, code_out_len);
5880 PROF_ADD(prof, orig, search_out_len);
5881 PROF_ADD(prof, orig, interm_time);
5882 PROF_ADD(prof, orig, code_time);
5883 PROF_ADD(prof, orig, la_time);
5884 PROF_ADD(prof, orig, opt_time);
5885 PROF_ADD(prof, orig, restore_count);
5886 PROF_ADD(prof, orig, restore_time);
5887 }
5888 if (table) {
5889 int i;
5890
5891 for (i = 0; i < NB_OPS; i++) {
5892 PROF_ADD(prof, orig, table_op_count[i]);
5893 }
5894 }
5895 }
5896}
5897
5898#undef PROF_ADD
5899#undef PROF_MAX
5900
5901static void tcg_profile_snapshot_counters(TCGProfile *prof)
5902{
5903 tcg_profile_snapshot(prof, true, false);
5904}
5905
5906static void tcg_profile_snapshot_table(TCGProfile *prof)
5907{
5908 tcg_profile_snapshot(prof, false, true);
5909}
c896fe29 5910
b6a7f3e0 5911void tcg_dump_op_count(GString *buf)
c896fe29 5912{
c3fac113 5913 TCGProfile prof = {};
c896fe29 5914 int i;
d70724ce 5915
c3fac113 5916 tcg_profile_snapshot_table(&prof);
15fc7daa 5917 for (i = 0; i < NB_OPS; i++) {
b6a7f3e0
DB
5918 g_string_append_printf(buf, "%s %" PRId64 "\n", tcg_op_defs[i].name,
5919 prof.table_op_count[i]);
c896fe29 5920 }
c896fe29 5921}
72fd2efb
EC
5922
5923int64_t tcg_cpu_exec_time(void)
5924{
0e2d61cf 5925 unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
72fd2efb
EC
5926 unsigned int i;
5927 int64_t ret = 0;
5928
5929 for (i = 0; i < n_ctxs; i++) {
d73415a3 5930 const TCGContext *s = qatomic_read(&tcg_ctxs[i]);
72fd2efb
EC
5931 const TCGProfile *prof = &s->prof;
5932
d73415a3 5933 ret += qatomic_read(&prof->cpu_exec_time);
72fd2efb
EC
5934 }
5935 return ret;
5936}
246ae24d 5937#else
b6a7f3e0 5938void tcg_dump_op_count(GString *buf)
246ae24d 5939{
b6a7f3e0 5940 g_string_append_printf(buf, "[TCG profiler not compiled]\n");
246ae24d 5941}
72fd2efb
EC
5942
5943int64_t tcg_cpu_exec_time(void)
5944{
5945 error_report("%s: TCG profiler not compiled", __func__);
5946 exit(EXIT_FAILURE);
5947}
c896fe29
FB
5948#endif
5949
5950
76cef4b2 5951int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
c896fe29 5952{
c3fac113
EC
5953#ifdef CONFIG_PROFILER
5954 TCGProfile *prof = &s->prof;
5955#endif
15fa08f8
RH
5956 int i, num_insns;
5957 TCGOp *op;
c896fe29 5958
04fe6400
RH
5959#ifdef CONFIG_PROFILER
5960 {
c1f543b7 5961 int n = 0;
04fe6400 5962
15fa08f8
RH
5963 QTAILQ_FOREACH(op, &s->ops, link) {
5964 n++;
5965 }
d73415a3 5966 qatomic_set(&prof->op_count, prof->op_count + n);
c3fac113 5967 if (n > prof->op_count_max) {
d73415a3 5968 qatomic_set(&prof->op_count_max, n);
04fe6400
RH
5969 }
5970
5971 n = s->nb_temps;
d73415a3 5972 qatomic_set(&prof->temp_count, prof->temp_count + n);
c3fac113 5973 if (n > prof->temp_count_max) {
d73415a3 5974 qatomic_set(&prof->temp_count_max, n);
04fe6400
RH
5975 }
5976 }
5977#endif
5978
d977e1c2 5979 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
fbf59aad 5980 && qemu_log_in_addr_range(pc_start))) {
c60f599b 5981 FILE *logfile = qemu_log_trylock();
78b54858
RH
5982 if (logfile) {
5983 fprintf(logfile, "OP:\n");
b7a83ff8 5984 tcg_dump_ops(s, logfile, false);
78b54858
RH
5985 fprintf(logfile, "\n");
5986 qemu_log_unlock(logfile);
5987 }
c896fe29 5988 }
c896fe29 5989
bef16ab4
RH
5990#ifdef CONFIG_DEBUG_TCG
5991 /* Ensure all labels referenced have been emitted. */
5992 {
5993 TCGLabel *l;
5994 bool error = false;
5995
5996 QSIMPLEQ_FOREACH(l, &s->labels, next) {
f85b1fc4 5997 if (unlikely(!l->present) && !QSIMPLEQ_EMPTY(&l->branches)) {
bef16ab4
RH
5998 qemu_log_mask(CPU_LOG_TB_OP,
5999 "$L%d referenced but not present.\n", l->id);
6000 error = true;
6001 }
6002 }
6003 assert(!error);
6004 }
6005#endif
6006
c5cc28ff 6007#ifdef CONFIG_PROFILER
d73415a3 6008 qatomic_set(&prof->opt_time, prof->opt_time - profile_getclock());
c5cc28ff
AJ
6009#endif
6010
c45cb8bb 6011 tcg_optimize(s);
8f2e8c07 6012
a23a9ec6 6013#ifdef CONFIG_PROFILER
d73415a3
SH
6014 qatomic_set(&prof->opt_time, prof->opt_time + profile_getclock());
6015 qatomic_set(&prof->la_time, prof->la_time - profile_getclock());
a23a9ec6 6016#endif
c5cc28ff 6017
b4fc67c7 6018 reachable_code_pass(s);
874b8574 6019 liveness_pass_0(s);
b83eabea 6020 liveness_pass_1(s);
5a18407f 6021
b83eabea 6022 if (s->nb_indirects > 0) {
b83eabea 6023 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
fbf59aad 6024 && qemu_log_in_addr_range(pc_start))) {
c60f599b 6025 FILE *logfile = qemu_log_trylock();
78b54858
RH
6026 if (logfile) {
6027 fprintf(logfile, "OP before indirect lowering:\n");
b7a83ff8 6028 tcg_dump_ops(s, logfile, false);
78b54858
RH
6029 fprintf(logfile, "\n");
6030 qemu_log_unlock(logfile);
6031 }
b83eabea 6032 }
645e3a81 6033
b83eabea
RH
6034 /* Replace indirect temps with direct temps. */
6035 if (liveness_pass_2(s)) {
6036 /* If changes were made, re-run liveness. */
6037 liveness_pass_1(s);
5a18407f
RH
6038 }
6039 }
c5cc28ff 6040
a23a9ec6 6041#ifdef CONFIG_PROFILER
d73415a3 6042 qatomic_set(&prof->la_time, prof->la_time + profile_getclock());
a23a9ec6 6043#endif
c896fe29 6044
d977e1c2 6045 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
fbf59aad 6046 && qemu_log_in_addr_range(pc_start))) {
c60f599b 6047 FILE *logfile = qemu_log_trylock();
78b54858
RH
6048 if (logfile) {
6049 fprintf(logfile, "OP after optimization and liveness analysis:\n");
b7a83ff8 6050 tcg_dump_ops(s, logfile, true);
78b54858
RH
6051 fprintf(logfile, "\n");
6052 qemu_log_unlock(logfile);
6053 }
c896fe29 6054 }
c896fe29 6055
35abb009 6056 /* Initialize goto_tb jump offsets. */
3a50f424
RH
6057 tb->jmp_reset_offset[0] = TB_JMP_OFFSET_INVALID;
6058 tb->jmp_reset_offset[1] = TB_JMP_OFFSET_INVALID;
9da6079b
RH
6059 tb->jmp_insn_offset[0] = TB_JMP_OFFSET_INVALID;
6060 tb->jmp_insn_offset[1] = TB_JMP_OFFSET_INVALID;
35abb009 6061
c896fe29
FB
6062 tcg_reg_alloc_start(s);
6063
db0c51a3
RH
6064 /*
6065 * Reset the buffer pointers when restarting after overflow.
6066 * TODO: Move this into translate-all.c with the rest of the
6067 * buffer management. Having only this done here is confusing.
6068 */
6069 s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
6070 s->code_ptr = s->code_buf;
c896fe29 6071
659ef5cb 6072#ifdef TCG_TARGET_NEED_LDST_LABELS
6001f772 6073 QSIMPLEQ_INIT(&s->ldst_labels);
659ef5cb 6074#endif
57a26946
RH
6075#ifdef TCG_TARGET_NEED_POOL_LABELS
6076 s->pool_labels = NULL;
6077#endif
9ecefc84 6078
fca8a500 6079 num_insns = -1;
15fa08f8 6080 QTAILQ_FOREACH(op, &s->ops, link) {
c45cb8bb 6081 TCGOpcode opc = op->opc;
b3db8758 6082
c896fe29 6083#ifdef CONFIG_PROFILER
d73415a3 6084 qatomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1);
c896fe29 6085#endif
c45cb8bb
RH
6086
6087 switch (opc) {
c896fe29 6088 case INDEX_op_mov_i32:
c896fe29 6089 case INDEX_op_mov_i64:
d2fd745f 6090 case INDEX_op_mov_vec:
dd186292 6091 tcg_reg_alloc_mov(s, op);
c896fe29 6092 break;
bab1671f
RH
6093 case INDEX_op_dup_vec:
6094 tcg_reg_alloc_dup(s, op);
6095 break;
765b842a 6096 case INDEX_op_insn_start:
fca8a500 6097 if (num_insns >= 0) {
9f754620
RH
6098 size_t off = tcg_current_code_size(s);
6099 s->gen_insn_end_off[num_insns] = off;
6100 /* Assert that we do not overflow our stored offset. */
6101 assert(s->gen_insn_end_off[num_insns] == off);
fca8a500
RH
6102 }
6103 num_insns++;
bad729e2 6104 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
c9ad8d27
RH
6105 s->gen_insn_data[num_insns][i] =
6106 tcg_get_insn_start_param(op, i);
bad729e2 6107 }
c896fe29 6108 break;
5ff9d6a4 6109 case INDEX_op_discard:
43439139 6110 temp_dead(s, arg_temp(op->args[0]));
5ff9d6a4 6111 break;
c896fe29 6112 case INDEX_op_set_label:
e8996ee0 6113 tcg_reg_alloc_bb_end(s, s->reserved_regs);
92ab8e7d 6114 tcg_out_label(s, arg_label(op->args[0]));
c896fe29
FB
6115 break;
6116 case INDEX_op_call:
dd186292 6117 tcg_reg_alloc_call(s, op);
c45cb8bb 6118 break;
b55a8d9d
RH
6119 case INDEX_op_exit_tb:
6120 tcg_out_exit_tb(s, op->args[0]);
6121 break;
cf7d6b8e
RH
6122 case INDEX_op_goto_tb:
6123 tcg_out_goto_tb(s, op->args[0]);
6124 break;
efe86b21
RH
6125 case INDEX_op_dup2_vec:
6126 if (tcg_reg_alloc_dup2(s, op)) {
6127 break;
6128 }
6129 /* fall through */
c896fe29 6130 default:
25c4d9cc 6131 /* Sanity check that we've not introduced any unhandled opcodes. */
be0f34b5 6132 tcg_debug_assert(tcg_op_supported(opc));
c896fe29
FB
6133 /* Note: in order to speed up the code, it would be much
6134 faster to have specialized register allocator functions for
6135 some common argument patterns */
dd186292 6136 tcg_reg_alloc_op(s, op);
c896fe29
FB
6137 break;
6138 }
b125f9dc
RH
6139 /* Test for (pending) buffer overflow. The assumption is that any
6140 one operation beginning below the high water mark cannot overrun
6141 the buffer completely. Thus we can test for overflow after
6142 generating code without having to check during generation. */
644da9b3 6143 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
b125f9dc
RH
6144 return -1;
6145 }
6e6c4efe
RH
6146 /* Test for TB overflow, as seen by gen_insn_end_off. */
6147 if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) {
6148 return -2;
6149 }
c896fe29 6150 }
fca8a500
RH
6151 tcg_debug_assert(num_insns >= 0);
6152 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
c45cb8bb 6153
b76f0d8c 6154 /* Generate TB finalization at the end of block */
659ef5cb 6155#ifdef TCG_TARGET_NEED_LDST_LABELS
aeee05f5
RH
6156 i = tcg_out_ldst_finalize(s);
6157 if (i < 0) {
6158 return i;
23dceda6 6159 }
659ef5cb 6160#endif
57a26946 6161#ifdef TCG_TARGET_NEED_POOL_LABELS
1768987b
RH
6162 i = tcg_out_pool_finalize(s);
6163 if (i < 0) {
6164 return i;
57a26946
RH
6165 }
6166#endif
7ecd02a0
RH
6167 if (!tcg_resolve_relocs(s)) {
6168 return -2;
6169 }
c896fe29 6170
df5d2b16 6171#ifndef CONFIG_TCG_INTERPRETER
c896fe29 6172 /* flush instruction cache */
db0c51a3
RH
6173 flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
6174 (uintptr_t)s->code_buf,
1da8de39 6175 tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
df5d2b16 6176#endif
2aeabc08 6177
1813e175 6178 return tcg_current_code_size(s);
c896fe29
FB
6179}
6180
a23a9ec6 6181#ifdef CONFIG_PROFILER
3a841ab5 6182void tcg_dump_info(GString *buf)
a23a9ec6 6183{
c3fac113
EC
6184 TCGProfile prof = {};
6185 const TCGProfile *s;
6186 int64_t tb_count;
6187 int64_t tb_div_count;
6188 int64_t tot;
6189
6190 tcg_profile_snapshot_counters(&prof);
6191 s = &prof;
6192 tb_count = s->tb_count;
6193 tb_div_count = tb_count ? tb_count : 1;
6194 tot = s->interm_time + s->code_time;
a23a9ec6 6195
3a841ab5
DB
6196 g_string_append_printf(buf, "JIT cycles %" PRId64
6197 " (%0.3f s at 2.4 GHz)\n",
6198 tot, tot / 2.4e9);
6199 g_string_append_printf(buf, "translated TBs %" PRId64
6200 " (aborted=%" PRId64 " %0.1f%%)\n",
6201 tb_count, s->tb_count1 - tb_count,
6202 (double)(s->tb_count1 - s->tb_count)
6203 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
6204 g_string_append_printf(buf, "avg ops/TB %0.1f max=%d\n",
6205 (double)s->op_count / tb_div_count, s->op_count_max);
6206 g_string_append_printf(buf, "deleted ops/TB %0.2f\n",
6207 (double)s->del_op_count / tb_div_count);
6208 g_string_append_printf(buf, "avg temps/TB %0.2f max=%d\n",
6209 (double)s->temp_count / tb_div_count,
6210 s->temp_count_max);
6211 g_string_append_printf(buf, "avg host code/TB %0.1f\n",
6212 (double)s->code_out_len / tb_div_count);
6213 g_string_append_printf(buf, "avg search data/TB %0.1f\n",
6214 (double)s->search_out_len / tb_div_count);
a813e36f 6215
3a841ab5
DB
6216 g_string_append_printf(buf, "cycles/op %0.1f\n",
6217 s->op_count ? (double)tot / s->op_count : 0);
6218 g_string_append_printf(buf, "cycles/in byte %0.1f\n",
6219 s->code_in_len ? (double)tot / s->code_in_len : 0);
6220 g_string_append_printf(buf, "cycles/out byte %0.1f\n",
6221 s->code_out_len ? (double)tot / s->code_out_len : 0);
6222 g_string_append_printf(buf, "cycles/search byte %0.1f\n",
6223 s->search_out_len ?
6224 (double)tot / s->search_out_len : 0);
fca8a500 6225 if (tot == 0) {
a23a9ec6 6226 tot = 1;
fca8a500 6227 }
3a841ab5
DB
6228 g_string_append_printf(buf, " gen_interm time %0.1f%%\n",
6229 (double)s->interm_time / tot * 100.0);
6230 g_string_append_printf(buf, " gen_code time %0.1f%%\n",
6231 (double)s->code_time / tot * 100.0);
6232 g_string_append_printf(buf, "optim./code time %0.1f%%\n",
6233 (double)s->opt_time / (s->code_time ?
6234 s->code_time : 1)
6235 * 100.0);
6236 g_string_append_printf(buf, "liveness/code time %0.1f%%\n",
6237 (double)s->la_time / (s->code_time ?
6238 s->code_time : 1) * 100.0);
6239 g_string_append_printf(buf, "cpu_restore count %" PRId64 "\n",
6240 s->restore_count);
6241 g_string_append_printf(buf, " avg cycles %0.1f\n",
6242 s->restore_count ?
6243 (double)s->restore_time / s->restore_count : 0);
a23a9ec6
FB
6244}
6245#else
3a841ab5 6246void tcg_dump_info(GString *buf)
a23a9ec6 6247{
3a841ab5 6248 g_string_append_printf(buf, "[TCG profiler not compiled]\n");
a23a9ec6
FB
6249}
6250#endif
813da627
RH
6251
6252#ifdef ELF_HOST_MACHINE
5872bbf2
RH
6253/* In order to use this feature, the backend needs to do three things:
6254
6255 (1) Define ELF_HOST_MACHINE to indicate both what value to
6256 put into the ELF image and to indicate support for the feature.
6257
6258 (2) Define tcg_register_jit. This should create a buffer containing
6259 the contents of a .debug_frame section that describes the post-
6260 prologue unwind info for the tcg machine.
6261
6262 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
6263*/
813da627
RH
6264
6265/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
6266typedef enum {
6267 JIT_NOACTION = 0,
6268 JIT_REGISTER_FN,
6269 JIT_UNREGISTER_FN
6270} jit_actions_t;
6271
6272struct jit_code_entry {
6273 struct jit_code_entry *next_entry;
6274 struct jit_code_entry *prev_entry;
6275 const void *symfile_addr;
6276 uint64_t symfile_size;
6277};
6278
6279struct jit_descriptor {
6280 uint32_t version;
6281 uint32_t action_flag;
6282 struct jit_code_entry *relevant_entry;
6283 struct jit_code_entry *first_entry;
6284};
6285
6286void __jit_debug_register_code(void) __attribute__((noinline));
6287void __jit_debug_register_code(void)
6288{
6289 asm("");
6290}
6291
6292/* Must statically initialize the version, because GDB may check
6293 the version before we can set it. */
6294struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
6295
6296/* End GDB interface. */
6297
6298static int find_string(const char *strtab, const char *str)
6299{
6300 const char *p = strtab + 1;
6301
6302 while (1) {
6303 if (strcmp(p, str) == 0) {
6304 return p - strtab;
6305 }
6306 p += strlen(p) + 1;
6307 }
6308}
6309
755bf9e5 6310static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size,
2c90784a
RH
6311 const void *debug_frame,
6312 size_t debug_frame_size)
813da627 6313{
5872bbf2
RH
6314 struct __attribute__((packed)) DebugInfo {
6315 uint32_t len;
6316 uint16_t version;
6317 uint32_t abbrev;
6318 uint8_t ptr_size;
6319 uint8_t cu_die;
6320 uint16_t cu_lang;
6321 uintptr_t cu_low_pc;
6322 uintptr_t cu_high_pc;
6323 uint8_t fn_die;
6324 char fn_name[16];
6325 uintptr_t fn_low_pc;
6326 uintptr_t fn_high_pc;
6327 uint8_t cu_eoc;
6328 };
813da627
RH
6329
6330 struct ElfImage {
6331 ElfW(Ehdr) ehdr;
6332 ElfW(Phdr) phdr;
5872bbf2
RH
6333 ElfW(Shdr) shdr[7];
6334 ElfW(Sym) sym[2];
6335 struct DebugInfo di;
6336 uint8_t da[24];
6337 char str[80];
6338 };
6339
6340 struct ElfImage *img;
6341
6342 static const struct ElfImage img_template = {
6343 .ehdr = {
6344 .e_ident[EI_MAG0] = ELFMAG0,
6345 .e_ident[EI_MAG1] = ELFMAG1,
6346 .e_ident[EI_MAG2] = ELFMAG2,
6347 .e_ident[EI_MAG3] = ELFMAG3,
6348 .e_ident[EI_CLASS] = ELF_CLASS,
6349 .e_ident[EI_DATA] = ELF_DATA,
6350 .e_ident[EI_VERSION] = EV_CURRENT,
6351 .e_type = ET_EXEC,
6352 .e_machine = ELF_HOST_MACHINE,
6353 .e_version = EV_CURRENT,
6354 .e_phoff = offsetof(struct ElfImage, phdr),
6355 .e_shoff = offsetof(struct ElfImage, shdr),
6356 .e_ehsize = sizeof(ElfW(Shdr)),
6357 .e_phentsize = sizeof(ElfW(Phdr)),
6358 .e_phnum = 1,
6359 .e_shentsize = sizeof(ElfW(Shdr)),
6360 .e_shnum = ARRAY_SIZE(img->shdr),
6361 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
abbb3eae
RH
6362#ifdef ELF_HOST_FLAGS
6363 .e_flags = ELF_HOST_FLAGS,
6364#endif
6365#ifdef ELF_OSABI
6366 .e_ident[EI_OSABI] = ELF_OSABI,
6367#endif
5872bbf2
RH
6368 },
6369 .phdr = {
6370 .p_type = PT_LOAD,
6371 .p_flags = PF_X,
6372 },
6373 .shdr = {
6374 [0] = { .sh_type = SHT_NULL },
6375 /* Trick: The contents of code_gen_buffer are not present in
6376 this fake ELF file; that got allocated elsewhere. Therefore
6377 we mark .text as SHT_NOBITS (similar to .bss) so that readers
6378 will not look for contents. We can record any address. */
6379 [1] = { /* .text */
6380 .sh_type = SHT_NOBITS,
6381 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
6382 },
6383 [2] = { /* .debug_info */
6384 .sh_type = SHT_PROGBITS,
6385 .sh_offset = offsetof(struct ElfImage, di),
6386 .sh_size = sizeof(struct DebugInfo),
6387 },
6388 [3] = { /* .debug_abbrev */
6389 .sh_type = SHT_PROGBITS,
6390 .sh_offset = offsetof(struct ElfImage, da),
6391 .sh_size = sizeof(img->da),
6392 },
6393 [4] = { /* .debug_frame */
6394 .sh_type = SHT_PROGBITS,
6395 .sh_offset = sizeof(struct ElfImage),
6396 },
6397 [5] = { /* .symtab */
6398 .sh_type = SHT_SYMTAB,
6399 .sh_offset = offsetof(struct ElfImage, sym),
6400 .sh_size = sizeof(img->sym),
6401 .sh_info = 1,
6402 .sh_link = ARRAY_SIZE(img->shdr) - 1,
6403 .sh_entsize = sizeof(ElfW(Sym)),
6404 },
6405 [6] = { /* .strtab */
6406 .sh_type = SHT_STRTAB,
6407 .sh_offset = offsetof(struct ElfImage, str),
6408 .sh_size = sizeof(img->str),
6409 }
6410 },
6411 .sym = {
6412 [1] = { /* code_gen_buffer */
6413 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
6414 .st_shndx = 1,
6415 }
6416 },
6417 .di = {
6418 .len = sizeof(struct DebugInfo) - 4,
6419 .version = 2,
6420 .ptr_size = sizeof(void *),
6421 .cu_die = 1,
6422 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
6423 .fn_die = 2,
6424 .fn_name = "code_gen_buffer"
6425 },
6426 .da = {
6427 1, /* abbrev number (the cu) */
6428 0x11, 1, /* DW_TAG_compile_unit, has children */
6429 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
6430 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
6431 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
6432 0, 0, /* end of abbrev */
6433 2, /* abbrev number (the fn) */
6434 0x2e, 0, /* DW_TAG_subprogram, no children */
6435 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
6436 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
6437 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
6438 0, 0, /* end of abbrev */
6439 0 /* no more abbrev */
6440 },
6441 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
6442 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
813da627
RH
6443 };
6444
6445 /* We only need a single jit entry; statically allocate it. */
6446 static struct jit_code_entry one_entry;
6447
5872bbf2 6448 uintptr_t buf = (uintptr_t)buf_ptr;
813da627 6449 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2c90784a 6450 DebugFrameHeader *dfh;
813da627 6451
5872bbf2
RH
6452 img = g_malloc(img_size);
6453 *img = img_template;
813da627 6454
5872bbf2
RH
6455 img->phdr.p_vaddr = buf;
6456 img->phdr.p_paddr = buf;
6457 img->phdr.p_memsz = buf_size;
813da627 6458
813da627 6459 img->shdr[1].sh_name = find_string(img->str, ".text");
5872bbf2 6460 img->shdr[1].sh_addr = buf;
813da627
RH
6461 img->shdr[1].sh_size = buf_size;
6462
5872bbf2
RH
6463 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
6464 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
6465
6466 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
6467 img->shdr[4].sh_size = debug_frame_size;
6468
6469 img->shdr[5].sh_name = find_string(img->str, ".symtab");
6470 img->shdr[6].sh_name = find_string(img->str, ".strtab");
6471
6472 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
6473 img->sym[1].st_value = buf;
6474 img->sym[1].st_size = buf_size;
813da627 6475
5872bbf2 6476 img->di.cu_low_pc = buf;
45aba097 6477 img->di.cu_high_pc = buf + buf_size;
5872bbf2 6478 img->di.fn_low_pc = buf;
45aba097 6479 img->di.fn_high_pc = buf + buf_size;
813da627 6480
2c90784a
RH
6481 dfh = (DebugFrameHeader *)(img + 1);
6482 memcpy(dfh, debug_frame, debug_frame_size);
6483 dfh->fde.func_start = buf;
6484 dfh->fde.func_len = buf_size;
6485
813da627
RH
6486#ifdef DEBUG_JIT
6487 /* Enable this block to be able to debug the ELF image file creation.
6488 One can use readelf, objdump, or other inspection utilities. */
6489 {
eb6b2edf
BM
6490 g_autofree char *jit = g_strdup_printf("%s/qemu.jit", g_get_tmp_dir());
6491 FILE *f = fopen(jit, "w+b");
813da627 6492 if (f) {
5872bbf2 6493 if (fwrite(img, img_size, 1, f) != img_size) {
813da627
RH
6494 /* Avoid stupid unused return value warning for fwrite. */
6495 }
6496 fclose(f);
6497 }
6498 }
6499#endif
6500
6501 one_entry.symfile_addr = img;
6502 one_entry.symfile_size = img_size;
6503
6504 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
6505 __jit_debug_descriptor.relevant_entry = &one_entry;
6506 __jit_debug_descriptor.first_entry = &one_entry;
6507 __jit_debug_register_code();
6508}
6509#else
5872bbf2
RH
6510/* No support for the feature. Provide the entry point expected by exec.c,
6511 and implement the internal function we declared earlier. */
813da627 6512
755bf9e5 6513static void tcg_register_jit_int(const void *buf, size_t size,
2c90784a
RH
6514 const void *debug_frame,
6515 size_t debug_frame_size)
813da627
RH
6516{
6517}
6518
755bf9e5 6519void tcg_register_jit(const void *buf, size_t buf_size)
813da627
RH
6520{
6521}
6522#endif /* ELF_HOST_MACHINE */
db432672
RH
6523
6524#if !TCG_TARGET_MAYBE_vec
6525void tcg_expand_vec_op(TCGOpcode o, TCGType t, unsigned e, TCGArg a0, ...)
6526{
6527 g_assert_not_reached();
6528}
6529#endif