]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/tcg.c
tcg: Replace asserts on tcg_jmp_insn_offset
[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
c896fe29 25/* define it to use liveness analysis (better code) */
8f2e8c07 26#define USE_TCG_OPTIMIZATIONS
c896fe29 27
757e725b 28#include "qemu/osdep.h"
cca82982 29
813da627
RH
30/* Define to jump the ELF file used to communicate with GDB. */
31#undef DEBUG_JIT
32
72fd2efb 33#include "qemu/error-report.h"
f348b6d1 34#include "qemu/cutils.h"
1de7afc9 35#include "qemu/host-utils.h"
d4c51a0a 36#include "qemu/qemu-print.h"
1de7afc9 37#include "qemu/timer.h"
084cfca1 38#include "qemu/cacheflush.h"
ad768e6f 39#include "qemu/cacheinfo.h"
c896fe29 40
c5d3c498 41/* Note: the long term plan is to reduce the dependencies on the QEMU
c896fe29
FB
42 CPU definitions. Currently they are used for qemu_ld/st
43 instructions */
44#define NO_CPU_IO_DEFS
c896fe29 45
63c91552 46#include "exec/exec-all.h"
dcb32f1d 47#include "tcg/tcg-op.h"
813da627 48
edee2579 49#if UINTPTR_MAX == UINT32_MAX
813da627 50# define ELF_CLASS ELFCLASS32
edee2579
RH
51#else
52# define ELF_CLASS ELFCLASS64
813da627 53#endif
e03b5686 54#if HOST_BIG_ENDIAN
813da627
RH
55# define ELF_DATA ELFDATA2MSB
56#else
57# define ELF_DATA ELFDATA2LSB
58#endif
59
c896fe29 60#include "elf.h"
508127e2 61#include "exec/log.h"
d2ba8026 62#include "tcg/tcg-ldst.h"
5ff7258c 63#include "tcg-internal.h"
5584e2db 64#include "accel/tcg/perf.h"
c896fe29 65
139c1837 66/* Forward declarations for functions declared in tcg-target.c.inc and
ce151109 67 used here. */
e4d58b41
RH
68static void tcg_target_init(TCGContext *s);
69static void tcg_target_qemu_prologue(TCGContext *s);
6ac17786 70static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
2ba7fae2 71 intptr_t value, intptr_t addend);
c896fe29 72
497a22eb
RH
73/* The CIE and FDE header definitions will be common to all hosts. */
74typedef struct {
75 uint32_t len __attribute__((aligned((sizeof(void *)))));
76 uint32_t id;
77 uint8_t version;
78 char augmentation[1];
79 uint8_t code_align;
80 uint8_t data_align;
81 uint8_t return_column;
82} DebugFrameCIE;
83
84typedef struct QEMU_PACKED {
85 uint32_t len __attribute__((aligned((sizeof(void *)))));
86 uint32_t cie_offset;
edee2579
RH
87 uintptr_t func_start;
88 uintptr_t func_len;
497a22eb
RH
89} DebugFrameFDEHeader;
90
2c90784a
RH
91typedef struct QEMU_PACKED {
92 DebugFrameCIE cie;
93 DebugFrameFDEHeader fde;
94} DebugFrameHeader;
95
755bf9e5 96static void tcg_register_jit_int(const void *buf, size_t size,
2c90784a
RH
97 const void *debug_frame,
98 size_t debug_frame_size)
813da627
RH
99 __attribute__((unused));
100
139c1837 101/* Forward declarations for functions declared and used in tcg-target.c.inc. */
2a534aff 102static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
a05b5b9b 103 intptr_t arg2);
78113e83 104static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
c0ad3001 105static void tcg_out_movi(TCGContext *s, TCGType type,
2a534aff 106 TCGReg ret, tcg_target_long arg);
b55a8d9d 107static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
5e8892db
MR
108static void tcg_out_op(TCGContext *s, TCGOpcode opc,
109 const TCGArg args[TCG_MAX_OP_ARGS],
110 const int const_args[TCG_MAX_OP_ARGS]);
d2fd745f 111#if TCG_TARGET_MAYBE_vec
e7632cfa
RH
112static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
113 TCGReg dst, TCGReg src);
d6ecb4a9
RH
114static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
115 TCGReg dst, TCGReg base, intptr_t offset);
4e186175
RH
116static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
117 TCGReg dst, int64_t arg);
5e8892db
MR
118static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
119 unsigned vecl, unsigned vece,
120 const TCGArg args[TCG_MAX_OP_ARGS],
121 const int const_args[TCG_MAX_OP_ARGS]);
d2fd745f 122#else
e7632cfa
RH
123static inline bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
124 TCGReg dst, TCGReg src)
125{
126 g_assert_not_reached();
127}
d6ecb4a9
RH
128static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
129 TCGReg dst, TCGReg base, intptr_t offset)
130{
131 g_assert_not_reached();
132}
4e186175
RH
133static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
134 TCGReg dst, int64_t arg)
e7632cfa
RH
135{
136 g_assert_not_reached();
137}
5e8892db
MR
138static inline void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
139 unsigned vecl, unsigned vece,
140 const TCGArg args[TCG_MAX_OP_ARGS],
141 const int const_args[TCG_MAX_OP_ARGS])
d2fd745f
RH
142{
143 g_assert_not_reached();
144}
145#endif
2a534aff 146static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
a05b5b9b 147 intptr_t arg2);
59d7c14e
RH
148static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
149 TCGReg base, intptr_t ofs);
7b7d8b2d 150static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
cee44b03 151 const TCGHelperInfo *info);
a4fbbd77 152static bool tcg_target_const_match(int64_t val, TCGType type, int ct);
659ef5cb 153#ifdef TCG_TARGET_NEED_LDST_LABELS
aeee05f5 154static int tcg_out_ldst_finalize(TCGContext *s);
659ef5cb 155#endif
c896fe29 156
42eb6dfc
RH
157TCGContext tcg_init_ctx;
158__thread TCGContext *tcg_ctx;
159
5ff7258c 160TCGContext **tcg_ctxs;
0e2d61cf
RH
161unsigned int tcg_cur_ctxs;
162unsigned int tcg_max_ctxs;
1c2adb95 163TCGv_env cpu_env = 0;
c8bc1168 164const void *tcg_code_gen_epilogue;
db0c51a3 165uintptr_t tcg_splitwx_diff;
df2cce29 166
b91ccb31
RH
167#ifndef CONFIG_TCG_INTERPRETER
168tcg_prologue_fn *tcg_qemu_tb_exec;
169#endif
170
d2fd745f 171static TCGRegSet tcg_target_available_regs[TCG_TYPE_COUNT];
b1d8e52e 172static TCGRegSet tcg_target_call_clobber_regs;
c896fe29 173
1813e175 174#if TCG_TARGET_INSN_UNIT_SIZE == 1
4196dca6 175static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
c896fe29
FB
176{
177 *s->code_ptr++ = v;
178}
179
4196dca6
PM
180static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
181 uint8_t v)
5c53bb81 182{
1813e175 183 *p = v;
5c53bb81 184}
1813e175 185#endif
5c53bb81 186
1813e175 187#if TCG_TARGET_INSN_UNIT_SIZE <= 2
4196dca6 188static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
c896fe29 189{
1813e175
RH
190 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
191 *s->code_ptr++ = v;
192 } else {
193 tcg_insn_unit *p = s->code_ptr;
194 memcpy(p, &v, sizeof(v));
195 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
196 }
c896fe29
FB
197}
198
4196dca6
PM
199static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
200 uint16_t v)
5c53bb81 201{
1813e175
RH
202 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
203 *p = v;
204 } else {
205 memcpy(p, &v, sizeof(v));
206 }
5c53bb81 207}
1813e175 208#endif
5c53bb81 209
1813e175 210#if TCG_TARGET_INSN_UNIT_SIZE <= 4
4196dca6 211static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
c896fe29 212{
1813e175
RH
213 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
214 *s->code_ptr++ = v;
215 } else {
216 tcg_insn_unit *p = s->code_ptr;
217 memcpy(p, &v, sizeof(v));
218 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
219 }
c896fe29
FB
220}
221
4196dca6
PM
222static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
223 uint32_t v)
5c53bb81 224{
1813e175
RH
225 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
226 *p = v;
227 } else {
228 memcpy(p, &v, sizeof(v));
229 }
5c53bb81 230}
1813e175 231#endif
5c53bb81 232
1813e175 233#if TCG_TARGET_INSN_UNIT_SIZE <= 8
4196dca6 234static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
ac26eb69 235{
1813e175
RH
236 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
237 *s->code_ptr++ = v;
238 } else {
239 tcg_insn_unit *p = s->code_ptr;
240 memcpy(p, &v, sizeof(v));
241 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
242 }
ac26eb69
RH
243}
244
4196dca6
PM
245static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
246 uint64_t v)
5c53bb81 247{
1813e175
RH
248 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
249 *p = v;
250 } else {
251 memcpy(p, &v, sizeof(v));
252 }
5c53bb81 253}
1813e175 254#endif
5c53bb81 255
c896fe29
FB
256/* label relocation processing */
257
1813e175 258static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
bec16311 259 TCGLabel *l, intptr_t addend)
c896fe29 260{
7ecd02a0 261 TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation));
c896fe29 262
7ecd02a0
RH
263 r->type = type;
264 r->ptr = code_ptr;
265 r->addend = addend;
266 QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
c896fe29
FB
267}
268
92ab8e7d 269static void tcg_out_label(TCGContext *s, TCGLabel *l)
c896fe29 270{
eabb7b91 271 tcg_debug_assert(!l->has_value);
c896fe29 272 l->has_value = 1;
92ab8e7d 273 l->u.value_ptr = tcg_splitwx_to_rx(s->code_ptr);
c896fe29
FB
274}
275
42a268c2 276TCGLabel *gen_new_label(void)
c896fe29 277{
b1311c4a 278 TCGContext *s = tcg_ctx;
51e3972c 279 TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
c896fe29 280
7ecd02a0
RH
281 memset(l, 0, sizeof(TCGLabel));
282 l->id = s->nb_labels++;
283 QSIMPLEQ_INIT(&l->relocs);
284
bef16ab4 285 QSIMPLEQ_INSERT_TAIL(&s->labels, l, next);
42a268c2
RH
286
287 return l;
c896fe29
FB
288}
289
7ecd02a0
RH
290static bool tcg_resolve_relocs(TCGContext *s)
291{
292 TCGLabel *l;
293
294 QSIMPLEQ_FOREACH(l, &s->labels, next) {
295 TCGRelocation *r;
296 uintptr_t value = l->u.value;
297
298 QSIMPLEQ_FOREACH(r, &l->relocs, next) {
299 if (!patch_reloc(r->ptr, r->type, value, r->addend)) {
300 return false;
301 }
302 }
303 }
304 return true;
305}
306
9f754620
RH
307static void set_jmp_reset_offset(TCGContext *s, int which)
308{
f14bed3f
RH
309 /*
310 * We will check for overflow at the end of the opcode loop in
311 * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
312 */
313 s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
9f754620
RH
314}
315
db6b7d0c 316/* Signal overflow, starting over with fewer guest insns. */
8905770b
MAL
317static G_NORETURN
318void tcg_raise_tb_overflow(TCGContext *s)
db6b7d0c
RH
319{
320 siglongjmp(s->jmp_trans, -2);
321}
322
4c22e840
RH
323#define C_PFX1(P, A) P##A
324#define C_PFX2(P, A, B) P##A##_##B
325#define C_PFX3(P, A, B, C) P##A##_##B##_##C
326#define C_PFX4(P, A, B, C, D) P##A##_##B##_##C##_##D
327#define C_PFX5(P, A, B, C, D, E) P##A##_##B##_##C##_##D##_##E
328#define C_PFX6(P, A, B, C, D, E, F) P##A##_##B##_##C##_##D##_##E##_##F
329
330/* Define an enumeration for the various combinations. */
331
332#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1),
333#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2),
334#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3),
335#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4),
336
337#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1),
338#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2),
339#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3),
340#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4),
341
342#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2),
343
344#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1),
345#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
346#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
347#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4),
348
349typedef enum {
350#include "tcg-target-con-set.h"
351} TCGConstraintSetIndex;
352
353static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
354
355#undef C_O0_I1
356#undef C_O0_I2
357#undef C_O0_I3
358#undef C_O0_I4
359#undef C_O1_I1
360#undef C_O1_I2
361#undef C_O1_I3
362#undef C_O1_I4
363#undef C_N1_I2
364#undef C_O2_I1
365#undef C_O2_I2
366#undef C_O2_I3
367#undef C_O2_I4
368
369/* Put all of the constraint sets into an array, indexed by the enum. */
370
371#define C_O0_I1(I1) { .args_ct_str = { #I1 } },
372#define C_O0_I2(I1, I2) { .args_ct_str = { #I1, #I2 } },
373#define C_O0_I3(I1, I2, I3) { .args_ct_str = { #I1, #I2, #I3 } },
374#define C_O0_I4(I1, I2, I3, I4) { .args_ct_str = { #I1, #I2, #I3, #I4 } },
375
376#define C_O1_I1(O1, I1) { .args_ct_str = { #O1, #I1 } },
377#define C_O1_I2(O1, I1, I2) { .args_ct_str = { #O1, #I1, #I2 } },
378#define C_O1_I3(O1, I1, I2, I3) { .args_ct_str = { #O1, #I1, #I2, #I3 } },
379#define C_O1_I4(O1, I1, I2, I3, I4) { .args_ct_str = { #O1, #I1, #I2, #I3, #I4 } },
380
381#define C_N1_I2(O1, I1, I2) { .args_ct_str = { "&" #O1, #I1, #I2 } },
382
383#define C_O2_I1(O1, O2, I1) { .args_ct_str = { #O1, #O2, #I1 } },
384#define C_O2_I2(O1, O2, I1, I2) { .args_ct_str = { #O1, #O2, #I1, #I2 } },
385#define C_O2_I3(O1, O2, I1, I2, I3) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3 } },
386#define C_O2_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3, #I4 } },
387
388static const TCGTargetOpDef constraint_sets[] = {
389#include "tcg-target-con-set.h"
390};
391
392
393#undef C_O0_I1
394#undef C_O0_I2
395#undef C_O0_I3
396#undef C_O0_I4
397#undef C_O1_I1
398#undef C_O1_I2
399#undef C_O1_I3
400#undef C_O1_I4
401#undef C_N1_I2
402#undef C_O2_I1
403#undef C_O2_I2
404#undef C_O2_I3
405#undef C_O2_I4
406
407/* Expand the enumerator to be returned from tcg_target_op_def(). */
408
409#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1)
410#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2)
411#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3)
412#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4)
413
414#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1)
415#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2)
416#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3)
417#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4)
418
419#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2)
420
421#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1)
422#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2)
423#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
424#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
425
139c1837 426#include "tcg-target.c.inc"
c896fe29 427
38b47b19
EC
428static void alloc_tcg_plugin_context(TCGContext *s)
429{
430#ifdef CONFIG_PLUGIN
431 s->plugin_tb = g_new0(struct qemu_plugin_tb, 1);
432 s->plugin_tb->insns =
433 g_ptr_array_new_with_free_func(qemu_plugin_insn_cleanup_fn);
434#endif
435}
436
3468b59e
EC
437/*
438 * All TCG threads except the parent (i.e. the one that called tcg_context_init
439 * and registered the target's TCG globals) must register with this function
440 * before initiating translation.
441 *
442 * In user-mode we just point tcg_ctx to tcg_init_ctx. See the documentation
443 * of tcg_region_init() for the reasoning behind this.
444 *
445 * In softmmu each caller registers its context in tcg_ctxs[]. Note that in
446 * softmmu tcg_ctxs[] does not track tcg_ctx_init, since the initial context
447 * is not used anymore for translation once this function is called.
448 *
449 * Not tracking tcg_init_ctx in tcg_ctxs[] in softmmu keeps code that iterates
450 * over the array (e.g. tcg_code_size() the same for both softmmu and user-mode.
451 */
452#ifdef CONFIG_USER_ONLY
453void tcg_register_thread(void)
454{
455 tcg_ctx = &tcg_init_ctx;
456}
457#else
458void tcg_register_thread(void)
459{
460 TCGContext *s = g_malloc(sizeof(*s));
461 unsigned int i, n;
3468b59e
EC
462
463 *s = tcg_init_ctx;
464
465 /* Relink mem_base. */
466 for (i = 0, n = tcg_init_ctx.nb_globals; i < n; ++i) {
467 if (tcg_init_ctx.temps[i].mem_base) {
468 ptrdiff_t b = tcg_init_ctx.temps[i].mem_base - tcg_init_ctx.temps;
469 tcg_debug_assert(b >= 0 && b < n);
470 s->temps[i].mem_base = &s->temps[b];
471 }
472 }
473
474 /* Claim an entry in tcg_ctxs */
0e2d61cf
RH
475 n = qatomic_fetch_inc(&tcg_cur_ctxs);
476 g_assert(n < tcg_max_ctxs);
d73415a3 477 qatomic_set(&tcg_ctxs[n], s);
3468b59e 478
38b47b19
EC
479 if (n > 0) {
480 alloc_tcg_plugin_context(s);
bf042e8e 481 tcg_region_initial_alloc(s);
38b47b19
EC
482 }
483
3468b59e 484 tcg_ctx = s;
e8feb96f 485}
3468b59e 486#endif /* !CONFIG_USER_ONLY */
e8feb96f 487
c896fe29
FB
488/* pool based memory allocation */
489void *tcg_malloc_internal(TCGContext *s, int size)
490{
491 TCGPool *p;
492 int pool_size;
a813e36f 493
c896fe29
FB
494 if (size > TCG_POOL_CHUNK_SIZE) {
495 /* big malloc: insert a new pool (XXX: could optimize) */
7267c094 496 p = g_malloc(sizeof(TCGPool) + size);
c896fe29 497 p->size = size;
4055299e
KB
498 p->next = s->pool_first_large;
499 s->pool_first_large = p;
500 return p->data;
c896fe29
FB
501 } else {
502 p = s->pool_current;
503 if (!p) {
504 p = s->pool_first;
505 if (!p)
506 goto new_pool;
507 } else {
508 if (!p->next) {
509 new_pool:
510 pool_size = TCG_POOL_CHUNK_SIZE;
7267c094 511 p = g_malloc(sizeof(TCGPool) + pool_size);
c896fe29
FB
512 p->size = pool_size;
513 p->next = NULL;
a813e36f 514 if (s->pool_current) {
c896fe29 515 s->pool_current->next = p;
a813e36f 516 } else {
c896fe29 517 s->pool_first = p;
a813e36f 518 }
c896fe29
FB
519 } else {
520 p = p->next;
521 }
522 }
523 }
524 s->pool_current = p;
525 s->pool_cur = p->data + size;
526 s->pool_end = p->data + p->size;
527 return p->data;
528}
529
530void tcg_pool_reset(TCGContext *s)
531{
4055299e
KB
532 TCGPool *p, *t;
533 for (p = s->pool_first_large; p; p = t) {
534 t = p->next;
535 g_free(p);
536 }
537 s->pool_first_large = NULL;
c896fe29
FB
538 s->pool_cur = s->pool_end = NULL;
539 s->pool_current = NULL;
540}
541
2ef6175a
RH
542#include "exec/helper-proto.h"
543
39004a71 544static TCGHelperInfo all_helpers[] = {
2ef6175a 545#include "exec/helper-tcg.h"
100b5e01 546};
619205fd 547static GHashTable *helper_table;
100b5e01 548
22f15579 549#ifdef CONFIG_TCG_INTERPRETER
c6ef8c7b
PMD
550static ffi_type *typecode_to_ffi(int argmask)
551{
552 switch (argmask) {
553 case dh_typecode_void:
554 return &ffi_type_void;
555 case dh_typecode_i32:
556 return &ffi_type_uint32;
557 case dh_typecode_s32:
558 return &ffi_type_sint32;
559 case dh_typecode_i64:
560 return &ffi_type_uint64;
561 case dh_typecode_s64:
562 return &ffi_type_sint64;
563 case dh_typecode_ptr:
564 return &ffi_type_pointer;
565 }
566 g_assert_not_reached();
567}
0c22e176
PMD
568
569static void init_ffi_layouts(void)
570{
571 /* g_direct_hash/equal for direct comparisons on uint32_t. */
f9c4bb80
RH
572 GHashTable *ffi_table = g_hash_table_new(NULL, NULL);
573
0c22e176 574 for (int i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
f9c4bb80
RH
575 TCGHelperInfo *info = &all_helpers[i];
576 unsigned typemask = info->typemask;
0c22e176
PMD
577 gpointer hash = (gpointer)(uintptr_t)typemask;
578 struct {
579 ffi_cif cif;
580 ffi_type *args[];
581 } *ca;
582 ffi_status status;
583 int nargs;
f9c4bb80 584 ffi_cif *cif;
0c22e176 585
f9c4bb80
RH
586 cif = g_hash_table_lookup(ffi_table, hash);
587 if (cif) {
588 info->cif = cif;
0c22e176
PMD
589 continue;
590 }
591
592 /* Ignoring the return type, find the last non-zero field. */
593 nargs = 32 - clz32(typemask >> 3);
594 nargs = DIV_ROUND_UP(nargs, 3);
595
596 ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
597 ca->cif.rtype = typecode_to_ffi(typemask & 7);
598 ca->cif.nargs = nargs;
599
600 if (nargs != 0) {
601 ca->cif.arg_types = ca->args;
602 for (int j = 0; j < nargs; ++j) {
603 int typecode = extract32(typemask, (j + 1) * 3, 3);
604 ca->args[j] = typecode_to_ffi(typecode);
605 }
606 }
607
608 status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
609 ca->cif.rtype, ca->cif.arg_types);
610 assert(status == FFI_OK);
611
f9c4bb80
RH
612 cif = &ca->cif;
613 info->cif = cif;
614 g_hash_table_insert(ffi_table, hash, (gpointer)cif);
0c22e176 615 }
f9c4bb80
RH
616
617 g_hash_table_destroy(ffi_table);
0c22e176
PMD
618}
619#endif /* CONFIG_TCG_INTERPRETER */
22f15579 620
39004a71
RH
621typedef struct TCGCumulativeArgs {
622 int arg_idx; /* tcg_gen_callN args[] */
623 int info_in_idx; /* TCGHelperInfo in[] */
624 int arg_slot; /* regs+stack slot */
625 int ref_slot; /* stack slots for references */
626} TCGCumulativeArgs;
627
628static void layout_arg_even(TCGCumulativeArgs *cum)
629{
630 cum->arg_slot += cum->arg_slot & 1;
631}
632
633static void layout_arg_1(TCGCumulativeArgs *cum, TCGHelperInfo *info,
634 TCGCallArgumentKind kind)
635{
636 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
637
638 *loc = (TCGCallArgumentLoc){
639 .kind = kind,
640 .arg_idx = cum->arg_idx,
641 .arg_slot = cum->arg_slot,
642 };
643 cum->info_in_idx++;
644 cum->arg_slot++;
645}
646
647static void layout_arg_normal_n(TCGCumulativeArgs *cum,
648 TCGHelperInfo *info, int n)
649{
650 TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
651
652 for (int i = 0; i < n; ++i) {
653 /* Layout all using the same arg_idx, adjusting the subindex. */
654 loc[i] = (TCGCallArgumentLoc){
655 .kind = TCG_CALL_ARG_NORMAL,
656 .arg_idx = cum->arg_idx,
657 .tmp_subindex = i,
658 .arg_slot = cum->arg_slot + i,
659 };
660 }
661 cum->info_in_idx += n;
662 cum->arg_slot += n;
663}
664
665static void init_call_layout(TCGHelperInfo *info)
666{
667 int max_reg_slots = ARRAY_SIZE(tcg_target_call_iarg_regs);
668 int max_stk_slots = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long);
669 unsigned typemask = info->typemask;
670 unsigned typecode;
671 TCGCumulativeArgs cum = { };
672
673 /*
674 * Parse and place any function return value.
675 */
676 typecode = typemask & 7;
677 switch (typecode) {
678 case dh_typecode_void:
679 info->nr_out = 0;
680 break;
681 case dh_typecode_i32:
682 case dh_typecode_s32:
683 case dh_typecode_ptr:
684 info->nr_out = 1;
685 info->out_kind = TCG_CALL_RET_NORMAL;
686 break;
687 case dh_typecode_i64:
688 case dh_typecode_s64:
689 info->nr_out = 64 / TCG_TARGET_REG_BITS;
690 info->out_kind = TCG_CALL_RET_NORMAL;
691 break;
692 default:
693 g_assert_not_reached();
694 }
695 assert(info->nr_out <= ARRAY_SIZE(tcg_target_call_oarg_regs));
696
697 /*
698 * Parse and place function arguments.
699 */
700 for (typemask >>= 3; typemask; typemask >>= 3, cum.arg_idx++) {
701 TCGCallArgumentKind kind;
702 TCGType type;
703
704 typecode = typemask & 7;
705 switch (typecode) {
706 case dh_typecode_i32:
707 case dh_typecode_s32:
708 type = TCG_TYPE_I32;
709 break;
710 case dh_typecode_i64:
711 case dh_typecode_s64:
712 type = TCG_TYPE_I64;
713 break;
714 case dh_typecode_ptr:
715 type = TCG_TYPE_PTR;
716 break;
717 default:
718 g_assert_not_reached();
719 }
720
721 switch (type) {
722 case TCG_TYPE_I32:
723 switch (TCG_TARGET_CALL_ARG_I32) {
724 case TCG_CALL_ARG_EVEN:
725 layout_arg_even(&cum);
726 /* fall through */
727 case TCG_CALL_ARG_NORMAL:
728 layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL);
729 break;
730 case TCG_CALL_ARG_EXTEND:
731 kind = TCG_CALL_ARG_EXTEND_U + (typecode & 1);
732 layout_arg_1(&cum, info, kind);
733 break;
734 default:
735 qemu_build_not_reached();
736 }
737 break;
738
739 case TCG_TYPE_I64:
740 switch (TCG_TARGET_CALL_ARG_I64) {
741 case TCG_CALL_ARG_EVEN:
742 layout_arg_even(&cum);
743 /* fall through */
744 case TCG_CALL_ARG_NORMAL:
745 if (TCG_TARGET_REG_BITS == 32) {
746 layout_arg_normal_n(&cum, info, 2);
747 } else {
748 layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL);
749 }
750 break;
751 default:
752 qemu_build_not_reached();
753 }
754 break;
755
756 default:
757 g_assert_not_reached();
758 }
759 }
760 info->nr_in = cum.info_in_idx;
761
762 /* Validate that we didn't overrun the input array. */
763 assert(cum.info_in_idx <= ARRAY_SIZE(info->in));
764 /* Validate the backend has enough argument space. */
765 assert(cum.arg_slot <= max_reg_slots + max_stk_slots);
766 assert(cum.ref_slot <= max_stk_slots);
767}
768
91478cef 769static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
f69d277e 770static void process_op_defs(TCGContext *s);
1c2adb95
RH
771static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
772 TCGReg reg, const char *name);
91478cef 773
43b972b7 774static void tcg_context_init(unsigned max_cpus)
c896fe29 775{
a76aabd3 776 TCGContext *s = &tcg_init_ctx;
100b5e01 777 int op, total_args, n, i;
c896fe29
FB
778 TCGOpDef *def;
779 TCGArgConstraint *args_ct;
1c2adb95 780 TCGTemp *ts;
c896fe29
FB
781
782 memset(s, 0, sizeof(*s));
c896fe29 783 s->nb_globals = 0;
c70fbf0a 784
c896fe29
FB
785 /* Count total number of arguments and allocate the corresponding
786 space */
787 total_args = 0;
788 for(op = 0; op < NB_OPS; op++) {
789 def = &tcg_op_defs[op];
790 n = def->nb_iargs + def->nb_oargs;
791 total_args += n;
792 }
793
bc2b17e6 794 args_ct = g_new0(TCGArgConstraint, total_args);
c896fe29
FB
795
796 for(op = 0; op < NB_OPS; op++) {
797 def = &tcg_op_defs[op];
798 def->args_ct = args_ct;
c896fe29 799 n = def->nb_iargs + def->nb_oargs;
c896fe29
FB
800 args_ct += n;
801 }
5cd8f621
RH
802
803 /* Register helpers. */
84fd9dd3 804 /* Use g_direct_hash/equal for direct pointer comparisons on func. */
619205fd 805 helper_table = g_hash_table_new(NULL, NULL);
84fd9dd3 806
100b5e01 807 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
39004a71 808 init_call_layout(&all_helpers[i]);
84fd9dd3 809 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
72866e82 810 (gpointer)&all_helpers[i]);
100b5e01 811 }
5cd8f621 812
22f15579 813#ifdef CONFIG_TCG_INTERPRETER
0c22e176 814 init_ffi_layouts();
22f15579
RH
815#endif
816
c896fe29 817 tcg_target_init(s);
f69d277e 818 process_op_defs(s);
91478cef
RH
819
820 /* Reverse the order of the saved registers, assuming they're all at
821 the start of tcg_target_reg_alloc_order. */
822 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
823 int r = tcg_target_reg_alloc_order[n];
824 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) {
825 break;
826 }
827 }
828 for (i = 0; i < n; ++i) {
829 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
830 }
831 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
832 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
833 }
b1311c4a 834
38b47b19
EC
835 alloc_tcg_plugin_context(s);
836
b1311c4a 837 tcg_ctx = s;
3468b59e
EC
838 /*
839 * In user-mode we simply share the init context among threads, since we
840 * use a single region. See the documentation tcg_region_init() for the
841 * reasoning behind this.
842 * In softmmu we will have at most max_cpus TCG threads.
843 */
844#ifdef CONFIG_USER_ONLY
df2cce29 845 tcg_ctxs = &tcg_ctx;
0e2d61cf
RH
846 tcg_cur_ctxs = 1;
847 tcg_max_ctxs = 1;
3468b59e 848#else
0e2d61cf
RH
849 tcg_max_ctxs = max_cpus;
850 tcg_ctxs = g_new0(TCGContext *, max_cpus);
3468b59e 851#endif
1c2adb95
RH
852
853 tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0));
854 ts = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, TCG_AREG0, "env");
855 cpu_env = temp_tcgv_ptr(ts);
9002ec79 856}
b03cce8e 857
43b972b7 858void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus)
a76aabd3 859{
43b972b7
RH
860 tcg_context_init(max_cpus);
861 tcg_region_init(tb_size, splitwx, max_cpus);
a76aabd3
RH
862}
863
6e3b2bfd
EC
864/*
865 * Allocate TBs right before their corresponding translated code, making
866 * sure that TBs and code are on different cache lines.
867 */
868TranslationBlock *tcg_tb_alloc(TCGContext *s)
869{
870 uintptr_t align = qemu_icache_linesize;
871 TranslationBlock *tb;
872 void *next;
873
e8feb96f 874 retry:
6e3b2bfd
EC
875 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
876 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
877
878 if (unlikely(next > s->code_gen_highwater)) {
e8feb96f
EC
879 if (tcg_region_alloc(s)) {
880 return NULL;
881 }
882 goto retry;
6e3b2bfd 883 }
d73415a3 884 qatomic_set(&s->code_gen_ptr, next);
57a26946 885 s->data_gen_ptr = NULL;
6e3b2bfd
EC
886 return tb;
887}
888
9002ec79
RH
889void tcg_prologue_init(TCGContext *s)
890{
b0a0794a 891 size_t prologue_size;
8163b749 892
b0a0794a
RH
893 s->code_ptr = s->code_gen_ptr;
894 s->code_buf = s->code_gen_ptr;
5b38ee31 895 s->data_gen_ptr = NULL;
b91ccb31
RH
896
897#ifndef CONFIG_TCG_INTERPRETER
b0a0794a 898 tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
b91ccb31 899#endif
8163b749 900
5b38ee31
RH
901#ifdef TCG_TARGET_NEED_POOL_LABELS
902 s->pool_labels = NULL;
903#endif
904
653b87eb 905 qemu_thread_jit_write();
8163b749 906 /* Generate the prologue. */
b03cce8e 907 tcg_target_qemu_prologue(s);
5b38ee31
RH
908
909#ifdef TCG_TARGET_NEED_POOL_LABELS
910 /* Allow the prologue to put e.g. guest_base into a pool entry. */
911 {
1768987b
RH
912 int result = tcg_out_pool_finalize(s);
913 tcg_debug_assert(result == 0);
5b38ee31
RH
914 }
915#endif
916
b0a0794a 917 prologue_size = tcg_current_code_size(s);
5584e2db 918 perf_report_prologue(s->code_gen_ptr, prologue_size);
b0a0794a 919
df5d2b16 920#ifndef CONFIG_TCG_INTERPRETER
b0a0794a
RH
921 flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
922 (uintptr_t)s->code_buf, prologue_size);
df5d2b16 923#endif
8163b749 924
d6b64b2b
RH
925#ifdef DEBUG_DISAS
926 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
c60f599b 927 FILE *logfile = qemu_log_trylock();
78b54858
RH
928 if (logfile) {
929 fprintf(logfile, "PROLOGUE: [size=%zu]\n", prologue_size);
930 if (s->data_gen_ptr) {
931 size_t code_size = s->data_gen_ptr - s->code_gen_ptr;
932 size_t data_size = prologue_size - code_size;
933 size_t i;
934
935 disas(logfile, s->code_gen_ptr, code_size);
936
937 for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
938 if (sizeof(tcg_target_ulong) == 8) {
939 fprintf(logfile,
940 "0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
941 (uintptr_t)s->data_gen_ptr + i,
942 *(uint64_t *)(s->data_gen_ptr + i));
943 } else {
944 fprintf(logfile,
945 "0x%08" PRIxPTR ": .long 0x%08x\n",
946 (uintptr_t)s->data_gen_ptr + i,
947 *(uint32_t *)(s->data_gen_ptr + i));
948 }
5b38ee31 949 }
78b54858
RH
950 } else {
951 disas(logfile, s->code_gen_ptr, prologue_size);
5b38ee31 952 }
78b54858 953 fprintf(logfile, "\n");
78b54858 954 qemu_log_unlock(logfile);
5b38ee31 955 }
d6b64b2b
RH
956 }
957#endif
cedbcb01 958
6eea0434
RH
959#ifndef CONFIG_TCG_INTERPRETER
960 /*
961 * Assert that goto_ptr is implemented completely, setting an epilogue.
962 * For tci, we use NULL as the signal to return from the interpreter,
963 * so skip this check.
964 */
f4e01e30 965 tcg_debug_assert(tcg_code_gen_epilogue != NULL);
6eea0434 966#endif
d1c74ab3
RH
967
968 tcg_region_prologue_set(s);
c896fe29
FB
969}
970
c896fe29
FB
971void tcg_func_start(TCGContext *s)
972{
973 tcg_pool_reset(s);
974 s->nb_temps = s->nb_globals;
0ec9eabc
RH
975
976 /* No temps have been previously allocated for size or locality. */
977 memset(s->free_temps, 0, sizeof(s->free_temps));
978
c0522136
RH
979 /* No constant temps have been previously allocated. */
980 for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
981 if (s->const_table[i]) {
982 g_hash_table_remove_all(s->const_table[i]);
983 }
984 }
985
abebf925 986 s->nb_ops = 0;
c896fe29
FB
987 s->nb_labels = 0;
988 s->current_frame_offset = s->frame_start;
989
0a209d4b
RH
990#ifdef CONFIG_DEBUG_TCG
991 s->goto_tb_issue_mask = 0;
992#endif
993
15fa08f8
RH
994 QTAILQ_INIT(&s->ops);
995 QTAILQ_INIT(&s->free_ops);
bef16ab4 996 QSIMPLEQ_INIT(&s->labels);
c896fe29
FB
997}
998
ae30e866 999static TCGTemp *tcg_temp_alloc(TCGContext *s)
7ca4b752
RH
1000{
1001 int n = s->nb_temps++;
ae30e866
RH
1002
1003 if (n >= TCG_MAX_TEMPS) {
db6b7d0c 1004 tcg_raise_tb_overflow(s);
ae30e866 1005 }
7ca4b752
RH
1006 return memset(&s->temps[n], 0, sizeof(TCGTemp));
1007}
1008
ae30e866 1009static TCGTemp *tcg_global_alloc(TCGContext *s)
7ca4b752 1010{
fa477d25
RH
1011 TCGTemp *ts;
1012
7ca4b752 1013 tcg_debug_assert(s->nb_globals == s->nb_temps);
ae30e866 1014 tcg_debug_assert(s->nb_globals < TCG_MAX_TEMPS);
7ca4b752 1015 s->nb_globals++;
fa477d25 1016 ts = tcg_temp_alloc(s);
ee17db83 1017 ts->kind = TEMP_GLOBAL;
fa477d25
RH
1018
1019 return ts;
c896fe29
FB
1020}
1021
085272b3
RH
1022static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
1023 TCGReg reg, const char *name)
c896fe29 1024{
c896fe29 1025 TCGTemp *ts;
c896fe29 1026
b3a62939 1027 if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
c896fe29 1028 tcg_abort();
b3a62939 1029 }
7ca4b752
RH
1030
1031 ts = tcg_global_alloc(s);
c896fe29
FB
1032 ts->base_type = type;
1033 ts->type = type;
ee17db83 1034 ts->kind = TEMP_FIXED;
c896fe29 1035 ts->reg = reg;
c896fe29 1036 ts->name = name;
c896fe29 1037 tcg_regset_set_reg(s->reserved_regs, reg);
7ca4b752 1038
085272b3 1039 return ts;
a7812ae4
PB
1040}
1041
b6638662 1042void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
b3a62939 1043{
b3a62939
RH
1044 s->frame_start = start;
1045 s->frame_end = start + size;
085272b3
RH
1046 s->frame_temp
1047 = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
b3a62939
RH
1048}
1049
085272b3
RH
1050TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
1051 intptr_t offset, const char *name)
c896fe29 1052{
b1311c4a 1053 TCGContext *s = tcg_ctx;
dc41aa7d 1054 TCGTemp *base_ts = tcgv_ptr_temp(base);
7ca4b752 1055 TCGTemp *ts = tcg_global_alloc(s);
aef85402 1056 int indirect_reg = 0;
c896fe29 1057
c0522136
RH
1058 switch (base_ts->kind) {
1059 case TEMP_FIXED:
1060 break;
1061 case TEMP_GLOBAL:
5a18407f
RH
1062 /* We do not support double-indirect registers. */
1063 tcg_debug_assert(!base_ts->indirect_reg);
b3915dbb 1064 base_ts->indirect_base = 1;
5a18407f
RH
1065 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
1066 ? 2 : 1);
1067 indirect_reg = 1;
c0522136
RH
1068 break;
1069 default:
1070 g_assert_not_reached();
b3915dbb
RH
1071 }
1072
7ca4b752
RH
1073 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1074 TCGTemp *ts2 = tcg_global_alloc(s);
c896fe29 1075 char buf[64];
7ca4b752
RH
1076
1077 ts->base_type = TCG_TYPE_I64;
c896fe29 1078 ts->type = TCG_TYPE_I32;
b3915dbb 1079 ts->indirect_reg = indirect_reg;
c896fe29 1080 ts->mem_allocated = 1;
b3a62939 1081 ts->mem_base = base_ts;
aef85402 1082 ts->mem_offset = offset;
c896fe29
FB
1083 pstrcpy(buf, sizeof(buf), name);
1084 pstrcat(buf, sizeof(buf), "_0");
1085 ts->name = strdup(buf);
c896fe29 1086
7ca4b752
RH
1087 tcg_debug_assert(ts2 == ts + 1);
1088 ts2->base_type = TCG_TYPE_I64;
1089 ts2->type = TCG_TYPE_I32;
b3915dbb 1090 ts2->indirect_reg = indirect_reg;
7ca4b752
RH
1091 ts2->mem_allocated = 1;
1092 ts2->mem_base = base_ts;
aef85402 1093 ts2->mem_offset = offset + 4;
fac87bd2 1094 ts2->temp_subindex = 1;
c896fe29
FB
1095 pstrcpy(buf, sizeof(buf), name);
1096 pstrcat(buf, sizeof(buf), "_1");
120c1084 1097 ts2->name = strdup(buf);
7ca4b752 1098 } else {
c896fe29
FB
1099 ts->base_type = type;
1100 ts->type = type;
b3915dbb 1101 ts->indirect_reg = indirect_reg;
c896fe29 1102 ts->mem_allocated = 1;
b3a62939 1103 ts->mem_base = base_ts;
c896fe29 1104 ts->mem_offset = offset;
c896fe29 1105 ts->name = name;
c896fe29 1106 }
085272b3 1107 return ts;
a7812ae4
PB
1108}
1109
5bfa8034 1110TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
c896fe29 1111{
b1311c4a 1112 TCGContext *s = tcg_ctx;
ee17db83 1113 TCGTempKind kind = temp_local ? TEMP_LOCAL : TEMP_NORMAL;
c896fe29 1114 TCGTemp *ts;
641d5fbe 1115 int idx, k;
c896fe29 1116
0ec9eabc
RH
1117 k = type + (temp_local ? TCG_TYPE_COUNT : 0);
1118 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
1119 if (idx < TCG_MAX_TEMPS) {
1120 /* There is already an available temp with the right type. */
1121 clear_bit(idx, s->free_temps[k].l);
1122
e8996ee0 1123 ts = &s->temps[idx];
e8996ee0 1124 ts->temp_allocated = 1;
7ca4b752 1125 tcg_debug_assert(ts->base_type == type);
ee17db83 1126 tcg_debug_assert(ts->kind == kind);
e8996ee0 1127 } else {
7ca4b752
RH
1128 ts = tcg_temp_alloc(s);
1129 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1130 TCGTemp *ts2 = tcg_temp_alloc(s);
1131
f6aa2f7d 1132 ts->base_type = type;
e8996ee0
FB
1133 ts->type = TCG_TYPE_I32;
1134 ts->temp_allocated = 1;
ee17db83 1135 ts->kind = kind;
7ca4b752
RH
1136
1137 tcg_debug_assert(ts2 == ts + 1);
1138 ts2->base_type = TCG_TYPE_I64;
1139 ts2->type = TCG_TYPE_I32;
1140 ts2->temp_allocated = 1;
fac87bd2 1141 ts2->temp_subindex = 1;
ee17db83 1142 ts2->kind = kind;
7ca4b752 1143 } else {
e8996ee0
FB
1144 ts->base_type = type;
1145 ts->type = type;
1146 ts->temp_allocated = 1;
ee17db83 1147 ts->kind = kind;
e8996ee0 1148 }
c896fe29 1149 }
27bfd83c
PM
1150
1151#if defined(CONFIG_DEBUG_TCG)
1152 s->temps_in_use++;
1153#endif
085272b3 1154 return ts;
c896fe29
FB
1155}
1156
d2fd745f
RH
1157TCGv_vec tcg_temp_new_vec(TCGType type)
1158{
1159 TCGTemp *t;
1160
1161#ifdef CONFIG_DEBUG_TCG
1162 switch (type) {
1163 case TCG_TYPE_V64:
1164 assert(TCG_TARGET_HAS_v64);
1165 break;
1166 case TCG_TYPE_V128:
1167 assert(TCG_TARGET_HAS_v128);
1168 break;
1169 case TCG_TYPE_V256:
1170 assert(TCG_TARGET_HAS_v256);
1171 break;
1172 default:
1173 g_assert_not_reached();
1174 }
1175#endif
1176
1177 t = tcg_temp_new_internal(type, 0);
1178 return temp_tcgv_vec(t);
1179}
1180
1181/* Create a new temp of the same type as an existing temp. */
1182TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
1183{
1184 TCGTemp *t = tcgv_vec_temp(match);
1185
1186 tcg_debug_assert(t->temp_allocated != 0);
1187
1188 t = tcg_temp_new_internal(t->base_type, 0);
1189 return temp_tcgv_vec(t);
1190}
1191
5bfa8034 1192void tcg_temp_free_internal(TCGTemp *ts)
c896fe29 1193{
b1311c4a 1194 TCGContext *s = tcg_ctx;
085272b3 1195 int k, idx;
c896fe29 1196
c7482438
RH
1197 switch (ts->kind) {
1198 case TEMP_CONST:
1199 /*
1200 * In order to simplify users of tcg_constant_*,
1201 * silently ignore free.
1202 */
c0522136 1203 return;
c7482438
RH
1204 case TEMP_NORMAL:
1205 case TEMP_LOCAL:
1206 break;
1207 default:
1208 g_assert_not_reached();
c0522136
RH
1209 }
1210
27bfd83c
PM
1211#if defined(CONFIG_DEBUG_TCG)
1212 s->temps_in_use--;
1213 if (s->temps_in_use < 0) {
1214 fprintf(stderr, "More temporaries freed than allocated!\n");
1215 }
1216#endif
1217
eabb7b91 1218 tcg_debug_assert(ts->temp_allocated != 0);
e8996ee0 1219 ts->temp_allocated = 0;
0ec9eabc 1220
085272b3 1221 idx = temp_idx(ts);
ee17db83 1222 k = ts->base_type + (ts->kind == TEMP_NORMAL ? 0 : TCG_TYPE_COUNT);
0ec9eabc 1223 set_bit(idx, s->free_temps[k].l);
c896fe29
FB
1224}
1225
c0522136
RH
1226TCGTemp *tcg_constant_internal(TCGType type, int64_t val)
1227{
1228 TCGContext *s = tcg_ctx;
1229 GHashTable *h = s->const_table[type];
1230 TCGTemp *ts;
1231
1232 if (h == NULL) {
1233 h = g_hash_table_new(g_int64_hash, g_int64_equal);
1234 s->const_table[type] = h;
1235 }
1236
1237 ts = g_hash_table_lookup(h, &val);
1238 if (ts == NULL) {
aef85402
RH
1239 int64_t *val_ptr;
1240
c0522136
RH
1241 ts = tcg_temp_alloc(s);
1242
1243 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1244 TCGTemp *ts2 = tcg_temp_alloc(s);
1245
aef85402
RH
1246 tcg_debug_assert(ts2 == ts + 1);
1247
c0522136
RH
1248 ts->base_type = TCG_TYPE_I64;
1249 ts->type = TCG_TYPE_I32;
1250 ts->kind = TEMP_CONST;
1251 ts->temp_allocated = 1;
c0522136 1252
c0522136
RH
1253 ts2->base_type = TCG_TYPE_I64;
1254 ts2->type = TCG_TYPE_I32;
1255 ts2->kind = TEMP_CONST;
1256 ts2->temp_allocated = 1;
fac87bd2 1257 ts2->temp_subindex = 1;
aef85402
RH
1258
1259 /*
1260 * Retain the full value of the 64-bit constant in the low
1261 * part, so that the hash table works. Actual uses will
1262 * truncate the value to the low part.
1263 */
1264 ts[HOST_BIG_ENDIAN].val = val;
1265 ts[!HOST_BIG_ENDIAN].val = val >> 32;
1266 val_ptr = &ts[HOST_BIG_ENDIAN].val;
c0522136
RH
1267 } else {
1268 ts->base_type = type;
1269 ts->type = type;
1270 ts->kind = TEMP_CONST;
1271 ts->temp_allocated = 1;
1272 ts->val = val;
aef85402 1273 val_ptr = &ts->val;
c0522136 1274 }
aef85402 1275 g_hash_table_insert(h, val_ptr, ts);
c0522136
RH
1276 }
1277
1278 return ts;
1279}
1280
1281TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val)
1282{
1283 val = dup_const(vece, val);
1284 return temp_tcgv_vec(tcg_constant_internal(type, val));
1285}
1286
88d4005b
RH
1287TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val)
1288{
1289 TCGTemp *t = tcgv_vec_temp(match);
1290
1291 tcg_debug_assert(t->temp_allocated != 0);
1292 return tcg_constant_vec(t->base_type, vece, val);
1293}
1294
a7812ae4 1295TCGv_i32 tcg_const_i32(int32_t val)
c896fe29 1296{
a7812ae4
PB
1297 TCGv_i32 t0;
1298 t0 = tcg_temp_new_i32();
e8996ee0
FB
1299 tcg_gen_movi_i32(t0, val);
1300 return t0;
1301}
c896fe29 1302
a7812ae4 1303TCGv_i64 tcg_const_i64(int64_t val)
e8996ee0 1304{
a7812ae4
PB
1305 TCGv_i64 t0;
1306 t0 = tcg_temp_new_i64();
e8996ee0
FB
1307 tcg_gen_movi_i64(t0, val);
1308 return t0;
c896fe29
FB
1309}
1310
a7812ae4 1311TCGv_i32 tcg_const_local_i32(int32_t val)
bdffd4a9 1312{
a7812ae4
PB
1313 TCGv_i32 t0;
1314 t0 = tcg_temp_local_new_i32();
bdffd4a9
AJ
1315 tcg_gen_movi_i32(t0, val);
1316 return t0;
1317}
1318
a7812ae4 1319TCGv_i64 tcg_const_local_i64(int64_t val)
bdffd4a9 1320{
a7812ae4
PB
1321 TCGv_i64 t0;
1322 t0 = tcg_temp_local_new_i64();
bdffd4a9
AJ
1323 tcg_gen_movi_i64(t0, val);
1324 return t0;
1325}
1326
27bfd83c
PM
1327#if defined(CONFIG_DEBUG_TCG)
1328void tcg_clear_temp_count(void)
1329{
b1311c4a 1330 TCGContext *s = tcg_ctx;
27bfd83c
PM
1331 s->temps_in_use = 0;
1332}
1333
1334int tcg_check_temp_count(void)
1335{
b1311c4a 1336 TCGContext *s = tcg_ctx;
27bfd83c
PM
1337 if (s->temps_in_use) {
1338 /* Clear the count so that we don't give another
1339 * warning immediately next time around.
1340 */
1341 s->temps_in_use = 0;
1342 return 1;
1343 }
1344 return 0;
1345}
1346#endif
1347
be0f34b5
RH
1348/* Return true if OP may appear in the opcode stream.
1349 Test the runtime variable that controls each opcode. */
1350bool tcg_op_supported(TCGOpcode op)
1351{
d2fd745f
RH
1352 const bool have_vec
1353 = TCG_TARGET_HAS_v64 | TCG_TARGET_HAS_v128 | TCG_TARGET_HAS_v256;
1354
be0f34b5
RH
1355 switch (op) {
1356 case INDEX_op_discard:
1357 case INDEX_op_set_label:
1358 case INDEX_op_call:
1359 case INDEX_op_br:
1360 case INDEX_op_mb:
1361 case INDEX_op_insn_start:
1362 case INDEX_op_exit_tb:
1363 case INDEX_op_goto_tb:
f4e01e30 1364 case INDEX_op_goto_ptr:
be0f34b5
RH
1365 case INDEX_op_qemu_ld_i32:
1366 case INDEX_op_qemu_st_i32:
1367 case INDEX_op_qemu_ld_i64:
1368 case INDEX_op_qemu_st_i64:
1369 return true;
1370
07ce0b05
RH
1371 case INDEX_op_qemu_st8_i32:
1372 return TCG_TARGET_HAS_qemu_st8_i32;
1373
be0f34b5 1374 case INDEX_op_mov_i32:
be0f34b5
RH
1375 case INDEX_op_setcond_i32:
1376 case INDEX_op_brcond_i32:
1377 case INDEX_op_ld8u_i32:
1378 case INDEX_op_ld8s_i32:
1379 case INDEX_op_ld16u_i32:
1380 case INDEX_op_ld16s_i32:
1381 case INDEX_op_ld_i32:
1382 case INDEX_op_st8_i32:
1383 case INDEX_op_st16_i32:
1384 case INDEX_op_st_i32:
1385 case INDEX_op_add_i32:
1386 case INDEX_op_sub_i32:
1387 case INDEX_op_mul_i32:
1388 case INDEX_op_and_i32:
1389 case INDEX_op_or_i32:
1390 case INDEX_op_xor_i32:
1391 case INDEX_op_shl_i32:
1392 case INDEX_op_shr_i32:
1393 case INDEX_op_sar_i32:
1394 return true;
1395
1396 case INDEX_op_movcond_i32:
1397 return TCG_TARGET_HAS_movcond_i32;
1398 case INDEX_op_div_i32:
1399 case INDEX_op_divu_i32:
1400 return TCG_TARGET_HAS_div_i32;
1401 case INDEX_op_rem_i32:
1402 case INDEX_op_remu_i32:
1403 return TCG_TARGET_HAS_rem_i32;
1404 case INDEX_op_div2_i32:
1405 case INDEX_op_divu2_i32:
1406 return TCG_TARGET_HAS_div2_i32;
1407 case INDEX_op_rotl_i32:
1408 case INDEX_op_rotr_i32:
1409 return TCG_TARGET_HAS_rot_i32;
1410 case INDEX_op_deposit_i32:
1411 return TCG_TARGET_HAS_deposit_i32;
1412 case INDEX_op_extract_i32:
1413 return TCG_TARGET_HAS_extract_i32;
1414 case INDEX_op_sextract_i32:
1415 return TCG_TARGET_HAS_sextract_i32;
fce1296f
RH
1416 case INDEX_op_extract2_i32:
1417 return TCG_TARGET_HAS_extract2_i32;
be0f34b5
RH
1418 case INDEX_op_add2_i32:
1419 return TCG_TARGET_HAS_add2_i32;
1420 case INDEX_op_sub2_i32:
1421 return TCG_TARGET_HAS_sub2_i32;
1422 case INDEX_op_mulu2_i32:
1423 return TCG_TARGET_HAS_mulu2_i32;
1424 case INDEX_op_muls2_i32:
1425 return TCG_TARGET_HAS_muls2_i32;
1426 case INDEX_op_muluh_i32:
1427 return TCG_TARGET_HAS_muluh_i32;
1428 case INDEX_op_mulsh_i32:
1429 return TCG_TARGET_HAS_mulsh_i32;
1430 case INDEX_op_ext8s_i32:
1431 return TCG_TARGET_HAS_ext8s_i32;
1432 case INDEX_op_ext16s_i32:
1433 return TCG_TARGET_HAS_ext16s_i32;
1434 case INDEX_op_ext8u_i32:
1435 return TCG_TARGET_HAS_ext8u_i32;
1436 case INDEX_op_ext16u_i32:
1437 return TCG_TARGET_HAS_ext16u_i32;
1438 case INDEX_op_bswap16_i32:
1439 return TCG_TARGET_HAS_bswap16_i32;
1440 case INDEX_op_bswap32_i32:
1441 return TCG_TARGET_HAS_bswap32_i32;
1442 case INDEX_op_not_i32:
1443 return TCG_TARGET_HAS_not_i32;
1444 case INDEX_op_neg_i32:
1445 return TCG_TARGET_HAS_neg_i32;
1446 case INDEX_op_andc_i32:
1447 return TCG_TARGET_HAS_andc_i32;
1448 case INDEX_op_orc_i32:
1449 return TCG_TARGET_HAS_orc_i32;
1450 case INDEX_op_eqv_i32:
1451 return TCG_TARGET_HAS_eqv_i32;
1452 case INDEX_op_nand_i32:
1453 return TCG_TARGET_HAS_nand_i32;
1454 case INDEX_op_nor_i32:
1455 return TCG_TARGET_HAS_nor_i32;
1456 case INDEX_op_clz_i32:
1457 return TCG_TARGET_HAS_clz_i32;
1458 case INDEX_op_ctz_i32:
1459 return TCG_TARGET_HAS_ctz_i32;
1460 case INDEX_op_ctpop_i32:
1461 return TCG_TARGET_HAS_ctpop_i32;
1462
1463 case INDEX_op_brcond2_i32:
1464 case INDEX_op_setcond2_i32:
1465 return TCG_TARGET_REG_BITS == 32;
1466
1467 case INDEX_op_mov_i64:
be0f34b5
RH
1468 case INDEX_op_setcond_i64:
1469 case INDEX_op_brcond_i64:
1470 case INDEX_op_ld8u_i64:
1471 case INDEX_op_ld8s_i64:
1472 case INDEX_op_ld16u_i64:
1473 case INDEX_op_ld16s_i64:
1474 case INDEX_op_ld32u_i64:
1475 case INDEX_op_ld32s_i64:
1476 case INDEX_op_ld_i64:
1477 case INDEX_op_st8_i64:
1478 case INDEX_op_st16_i64:
1479 case INDEX_op_st32_i64:
1480 case INDEX_op_st_i64:
1481 case INDEX_op_add_i64:
1482 case INDEX_op_sub_i64:
1483 case INDEX_op_mul_i64:
1484 case INDEX_op_and_i64:
1485 case INDEX_op_or_i64:
1486 case INDEX_op_xor_i64:
1487 case INDEX_op_shl_i64:
1488 case INDEX_op_shr_i64:
1489 case INDEX_op_sar_i64:
1490 case INDEX_op_ext_i32_i64:
1491 case INDEX_op_extu_i32_i64:
1492 return TCG_TARGET_REG_BITS == 64;
1493
1494 case INDEX_op_movcond_i64:
1495 return TCG_TARGET_HAS_movcond_i64;
1496 case INDEX_op_div_i64:
1497 case INDEX_op_divu_i64:
1498 return TCG_TARGET_HAS_div_i64;
1499 case INDEX_op_rem_i64:
1500 case INDEX_op_remu_i64:
1501 return TCG_TARGET_HAS_rem_i64;
1502 case INDEX_op_div2_i64:
1503 case INDEX_op_divu2_i64:
1504 return TCG_TARGET_HAS_div2_i64;
1505 case INDEX_op_rotl_i64:
1506 case INDEX_op_rotr_i64:
1507 return TCG_TARGET_HAS_rot_i64;
1508 case INDEX_op_deposit_i64:
1509 return TCG_TARGET_HAS_deposit_i64;
1510 case INDEX_op_extract_i64:
1511 return TCG_TARGET_HAS_extract_i64;
1512 case INDEX_op_sextract_i64:
1513 return TCG_TARGET_HAS_sextract_i64;
fce1296f
RH
1514 case INDEX_op_extract2_i64:
1515 return TCG_TARGET_HAS_extract2_i64;
be0f34b5
RH
1516 case INDEX_op_extrl_i64_i32:
1517 return TCG_TARGET_HAS_extrl_i64_i32;
1518 case INDEX_op_extrh_i64_i32:
1519 return TCG_TARGET_HAS_extrh_i64_i32;
1520 case INDEX_op_ext8s_i64:
1521 return TCG_TARGET_HAS_ext8s_i64;
1522 case INDEX_op_ext16s_i64:
1523 return TCG_TARGET_HAS_ext16s_i64;
1524 case INDEX_op_ext32s_i64:
1525 return TCG_TARGET_HAS_ext32s_i64;
1526 case INDEX_op_ext8u_i64:
1527 return TCG_TARGET_HAS_ext8u_i64;
1528 case INDEX_op_ext16u_i64:
1529 return TCG_TARGET_HAS_ext16u_i64;
1530 case INDEX_op_ext32u_i64:
1531 return TCG_TARGET_HAS_ext32u_i64;
1532 case INDEX_op_bswap16_i64:
1533 return TCG_TARGET_HAS_bswap16_i64;
1534 case INDEX_op_bswap32_i64:
1535 return TCG_TARGET_HAS_bswap32_i64;
1536 case INDEX_op_bswap64_i64:
1537 return TCG_TARGET_HAS_bswap64_i64;
1538 case INDEX_op_not_i64:
1539 return TCG_TARGET_HAS_not_i64;
1540 case INDEX_op_neg_i64:
1541 return TCG_TARGET_HAS_neg_i64;
1542 case INDEX_op_andc_i64:
1543 return TCG_TARGET_HAS_andc_i64;
1544 case INDEX_op_orc_i64:
1545 return TCG_TARGET_HAS_orc_i64;
1546 case INDEX_op_eqv_i64:
1547 return TCG_TARGET_HAS_eqv_i64;
1548 case INDEX_op_nand_i64:
1549 return TCG_TARGET_HAS_nand_i64;
1550 case INDEX_op_nor_i64:
1551 return TCG_TARGET_HAS_nor_i64;
1552 case INDEX_op_clz_i64:
1553 return TCG_TARGET_HAS_clz_i64;
1554 case INDEX_op_ctz_i64:
1555 return TCG_TARGET_HAS_ctz_i64;
1556 case INDEX_op_ctpop_i64:
1557 return TCG_TARGET_HAS_ctpop_i64;
1558 case INDEX_op_add2_i64:
1559 return TCG_TARGET_HAS_add2_i64;
1560 case INDEX_op_sub2_i64:
1561 return TCG_TARGET_HAS_sub2_i64;
1562 case INDEX_op_mulu2_i64:
1563 return TCG_TARGET_HAS_mulu2_i64;
1564 case INDEX_op_muls2_i64:
1565 return TCG_TARGET_HAS_muls2_i64;
1566 case INDEX_op_muluh_i64:
1567 return TCG_TARGET_HAS_muluh_i64;
1568 case INDEX_op_mulsh_i64:
1569 return TCG_TARGET_HAS_mulsh_i64;
1570
d2fd745f
RH
1571 case INDEX_op_mov_vec:
1572 case INDEX_op_dup_vec:
37ee55a0 1573 case INDEX_op_dupm_vec:
d2fd745f
RH
1574 case INDEX_op_ld_vec:
1575 case INDEX_op_st_vec:
1576 case INDEX_op_add_vec:
1577 case INDEX_op_sub_vec:
1578 case INDEX_op_and_vec:
1579 case INDEX_op_or_vec:
1580 case INDEX_op_xor_vec:
212be173 1581 case INDEX_op_cmp_vec:
d2fd745f
RH
1582 return have_vec;
1583 case INDEX_op_dup2_vec:
1584 return have_vec && TCG_TARGET_REG_BITS == 32;
1585 case INDEX_op_not_vec:
1586 return have_vec && TCG_TARGET_HAS_not_vec;
1587 case INDEX_op_neg_vec:
1588 return have_vec && TCG_TARGET_HAS_neg_vec;
bcefc902
RH
1589 case INDEX_op_abs_vec:
1590 return have_vec && TCG_TARGET_HAS_abs_vec;
d2fd745f
RH
1591 case INDEX_op_andc_vec:
1592 return have_vec && TCG_TARGET_HAS_andc_vec;
1593 case INDEX_op_orc_vec:
1594 return have_vec && TCG_TARGET_HAS_orc_vec;
ed523473
RH
1595 case INDEX_op_nand_vec:
1596 return have_vec && TCG_TARGET_HAS_nand_vec;
1597 case INDEX_op_nor_vec:
1598 return have_vec && TCG_TARGET_HAS_nor_vec;
1599 case INDEX_op_eqv_vec:
1600 return have_vec && TCG_TARGET_HAS_eqv_vec;
3774030a
RH
1601 case INDEX_op_mul_vec:
1602 return have_vec && TCG_TARGET_HAS_mul_vec;
d0ec9796
RH
1603 case INDEX_op_shli_vec:
1604 case INDEX_op_shri_vec:
1605 case INDEX_op_sari_vec:
1606 return have_vec && TCG_TARGET_HAS_shi_vec;
1607 case INDEX_op_shls_vec:
1608 case INDEX_op_shrs_vec:
1609 case INDEX_op_sars_vec:
1610 return have_vec && TCG_TARGET_HAS_shs_vec;
1611 case INDEX_op_shlv_vec:
1612 case INDEX_op_shrv_vec:
1613 case INDEX_op_sarv_vec:
1614 return have_vec && TCG_TARGET_HAS_shv_vec;
b0f7e744
RH
1615 case INDEX_op_rotli_vec:
1616 return have_vec && TCG_TARGET_HAS_roti_vec;
23850a74
RH
1617 case INDEX_op_rotls_vec:
1618 return have_vec && TCG_TARGET_HAS_rots_vec;
5d0ceda9
RH
1619 case INDEX_op_rotlv_vec:
1620 case INDEX_op_rotrv_vec:
1621 return have_vec && TCG_TARGET_HAS_rotv_vec;
8afaf050
RH
1622 case INDEX_op_ssadd_vec:
1623 case INDEX_op_usadd_vec:
1624 case INDEX_op_sssub_vec:
1625 case INDEX_op_ussub_vec:
1626 return have_vec && TCG_TARGET_HAS_sat_vec;
dd0a0fcd
RH
1627 case INDEX_op_smin_vec:
1628 case INDEX_op_umin_vec:
1629 case INDEX_op_smax_vec:
1630 case INDEX_op_umax_vec:
1631 return have_vec && TCG_TARGET_HAS_minmax_vec;
38dc1294
RH
1632 case INDEX_op_bitsel_vec:
1633 return have_vec && TCG_TARGET_HAS_bitsel_vec;
f75da298
RH
1634 case INDEX_op_cmpsel_vec:
1635 return have_vec && TCG_TARGET_HAS_cmpsel_vec;
d2fd745f 1636
db432672
RH
1637 default:
1638 tcg_debug_assert(op > INDEX_op_last_generic && op < NB_OPS);
1639 return true;
be0f34b5 1640 }
be0f34b5
RH
1641}
1642
39004a71
RH
1643static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs);
1644
ae8b75dc 1645void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
c896fe29 1646{
3e92aa34 1647 const TCGHelperInfo *info;
39004a71
RH
1648 TCGv_i64 extend_free[MAX_CALL_IARGS];
1649 int n_extend = 0;
75e8b9b7 1650 TCGOp *op;
39004a71 1651 int i, n, pi = 0, total_args;
afb49896 1652
619205fd 1653 info = g_hash_table_lookup(helper_table, (gpointer)func);
39004a71
RH
1654 total_args = info->nr_out + info->nr_in + 2;
1655 op = tcg_op_alloc(INDEX_op_call, total_args);
2bece2c8 1656
38b47b19
EC
1657#ifdef CONFIG_PLUGIN
1658 /* detect non-plugin helpers */
1659 if (tcg_ctx->plugin_insn && unlikely(strncmp(info->name, "plugin_", 7))) {
1660 tcg_ctx->plugin_insn->calls_helpers = true;
1661 }
1662#endif
1663
39004a71
RH
1664 TCGOP_CALLO(op) = n = info->nr_out;
1665 switch (n) {
1666 case 0:
1667 tcg_debug_assert(ret == NULL);
1668 break;
1669 case 1:
1670 tcg_debug_assert(ret != NULL);
1671 op->args[pi++] = temp_arg(ret);
1672 break;
1673 case 2:
1674 tcg_debug_assert(ret != NULL);
1675 tcg_debug_assert(ret->base_type == ret->type + 1);
1676 tcg_debug_assert(ret->temp_subindex == 0);
1677 op->args[pi++] = temp_arg(ret);
1678 op->args[pi++] = temp_arg(ret + 1);
1679 break;
1680 default:
1681 g_assert_not_reached();
1682 }
1683
1684 TCGOP_CALLI(op) = n = info->nr_in;
1685 for (i = 0; i < n; i++) {
1686 const TCGCallArgumentLoc *loc = &info->in[i];
1687 TCGTemp *ts = args[loc->arg_idx] + loc->tmp_subindex;
1688
1689 switch (loc->kind) {
1690 case TCG_CALL_ARG_NORMAL:
1691 op->args[pi++] = temp_arg(ts);
1692 break;
eb8b0224 1693
39004a71
RH
1694 case TCG_CALL_ARG_EXTEND_U:
1695 case TCG_CALL_ARG_EXTEND_S:
1696 {
eb8b0224 1697 TCGv_i64 temp = tcg_temp_new_i64();
39004a71
RH
1698 TCGv_i32 orig = temp_tcgv_i32(ts);
1699
1700 if (loc->kind == TCG_CALL_ARG_EXTEND_S) {
eb8b0224
RH
1701 tcg_gen_ext_i32_i64(temp, orig);
1702 } else {
1703 tcg_gen_extu_i32_i64(temp, orig);
1704 }
39004a71
RH
1705 op->args[pi++] = tcgv_i64_arg(temp);
1706 extend_free[n_extend++] = temp;
2bece2c8 1707 }
e2a9dd6b 1708 break;
7b7d8b2d 1709
e2a9dd6b
RH
1710 default:
1711 g_assert_not_reached();
c896fe29
FB
1712 }
1713 }
75e8b9b7 1714 op->args[pi++] = (uintptr_t)func;
3e92aa34 1715 op->args[pi++] = (uintptr_t)info;
39004a71 1716 tcg_debug_assert(pi == total_args);
a7812ae4 1717
39004a71 1718 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
7319d83a 1719
39004a71
RH
1720 tcg_debug_assert(n_extend < ARRAY_SIZE(extend_free));
1721 for (i = 0; i < n_extend; ++i) {
1722 tcg_temp_free_i64(extend_free[i]);
2bece2c8 1723 }
c896fe29 1724}
c896fe29 1725
8fcd3692 1726static void tcg_reg_alloc_start(TCGContext *s)
c896fe29 1727{
ac3b8891 1728 int i, n;
ac3b8891 1729
ee17db83
RH
1730 for (i = 0, n = s->nb_temps; i < n; i++) {
1731 TCGTemp *ts = &s->temps[i];
1732 TCGTempVal val = TEMP_VAL_MEM;
1733
1734 switch (ts->kind) {
c0522136
RH
1735 case TEMP_CONST:
1736 val = TEMP_VAL_CONST;
1737 break;
ee17db83
RH
1738 case TEMP_FIXED:
1739 val = TEMP_VAL_REG;
1740 break;
1741 case TEMP_GLOBAL:
1742 break;
1743 case TEMP_NORMAL:
c7482438 1744 case TEMP_EBB:
ee17db83
RH
1745 val = TEMP_VAL_DEAD;
1746 /* fall through */
1747 case TEMP_LOCAL:
1748 ts->mem_allocated = 0;
1749 break;
1750 default:
1751 g_assert_not_reached();
1752 }
1753 ts->val_type = val;
e8996ee0 1754 }
f8b2f202
RH
1755
1756 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
c896fe29
FB
1757}
1758
f8b2f202
RH
1759static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
1760 TCGTemp *ts)
c896fe29 1761{
1807f4c4 1762 int idx = temp_idx(ts);
ac56dd48 1763
ee17db83
RH
1764 switch (ts->kind) {
1765 case TEMP_FIXED:
1766 case TEMP_GLOBAL:
ac56dd48 1767 pstrcpy(buf, buf_size, ts->name);
ee17db83
RH
1768 break;
1769 case TEMP_LOCAL:
f8b2f202 1770 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
ee17db83 1771 break;
c7482438
RH
1772 case TEMP_EBB:
1773 snprintf(buf, buf_size, "ebb%d", idx - s->nb_globals);
1774 break;
ee17db83 1775 case TEMP_NORMAL:
f8b2f202 1776 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
ee17db83 1777 break;
c0522136
RH
1778 case TEMP_CONST:
1779 switch (ts->type) {
1780 case TCG_TYPE_I32:
1781 snprintf(buf, buf_size, "$0x%x", (int32_t)ts->val);
1782 break;
1783#if TCG_TARGET_REG_BITS > 32
1784 case TCG_TYPE_I64:
1785 snprintf(buf, buf_size, "$0x%" PRIx64, ts->val);
1786 break;
1787#endif
1788 case TCG_TYPE_V64:
1789 case TCG_TYPE_V128:
1790 case TCG_TYPE_V256:
1791 snprintf(buf, buf_size, "v%d$0x%" PRIx64,
1792 64 << (ts->type - TCG_TYPE_V64), ts->val);
1793 break;
1794 default:
1795 g_assert_not_reached();
1796 }
1797 break;
c896fe29
FB
1798 }
1799 return buf;
1800}
1801
43439139
RH
1802static char *tcg_get_arg_str(TCGContext *s, char *buf,
1803 int buf_size, TCGArg arg)
f8b2f202 1804{
43439139 1805 return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
f8b2f202
RH
1806}
1807
f48f3ede
BS
1808static const char * const cond_name[] =
1809{
0aed257f
RH
1810 [TCG_COND_NEVER] = "never",
1811 [TCG_COND_ALWAYS] = "always",
f48f3ede
BS
1812 [TCG_COND_EQ] = "eq",
1813 [TCG_COND_NE] = "ne",
1814 [TCG_COND_LT] = "lt",
1815 [TCG_COND_GE] = "ge",
1816 [TCG_COND_LE] = "le",
1817 [TCG_COND_GT] = "gt",
1818 [TCG_COND_LTU] = "ltu",
1819 [TCG_COND_GEU] = "geu",
1820 [TCG_COND_LEU] = "leu",
1821 [TCG_COND_GTU] = "gtu"
1822};
1823
f713d6ad
RH
1824static const char * const ldst_name[] =
1825{
1826 [MO_UB] = "ub",
1827 [MO_SB] = "sb",
1828 [MO_LEUW] = "leuw",
1829 [MO_LESW] = "lesw",
1830 [MO_LEUL] = "leul",
1831 [MO_LESL] = "lesl",
fc313c64 1832 [MO_LEUQ] = "leq",
f713d6ad
RH
1833 [MO_BEUW] = "beuw",
1834 [MO_BESW] = "besw",
1835 [MO_BEUL] = "beul",
1836 [MO_BESL] = "besl",
fc313c64 1837 [MO_BEUQ] = "beq",
f713d6ad
RH
1838};
1839
1f00b27f 1840static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
52bf9771 1841#ifdef TARGET_ALIGNED_ONLY
1f00b27f
SS
1842 [MO_UNALN >> MO_ASHIFT] = "un+",
1843 [MO_ALIGN >> MO_ASHIFT] = "",
1844#else
1845 [MO_UNALN >> MO_ASHIFT] = "",
1846 [MO_ALIGN >> MO_ASHIFT] = "al+",
1847#endif
1848 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+",
1849 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+",
1850 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+",
1851 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
1852 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
1853 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
1854};
1855
587195bd
RH
1856static const char bswap_flag_name[][6] = {
1857 [TCG_BSWAP_IZ] = "iz",
1858 [TCG_BSWAP_OZ] = "oz",
1859 [TCG_BSWAP_OS] = "os",
1860 [TCG_BSWAP_IZ | TCG_BSWAP_OZ] = "iz,oz",
1861 [TCG_BSWAP_IZ | TCG_BSWAP_OS] = "iz,os",
1862};
1863
b016486e
RH
1864static inline bool tcg_regset_single(TCGRegSet d)
1865{
1866 return (d & (d - 1)) == 0;
1867}
1868
1869static inline TCGReg tcg_regset_first(TCGRegSet d)
1870{
1871 if (TCG_TARGET_NB_REGS <= 32) {
1872 return ctz32(d);
1873 } else {
1874 return ctz64(d);
1875 }
1876}
1877
b7a83ff8
RH
1878/* Return only the number of characters output -- no error return. */
1879#define ne_fprintf(...) \
1880 ({ int ret_ = fprintf(__VA_ARGS__); ret_ >= 0 ? ret_ : 0; })
1881
1882static void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
c896fe29 1883{
c896fe29 1884 char buf[128];
c45cb8bb 1885 TCGOp *op;
c45cb8bb 1886
15fa08f8 1887 QTAILQ_FOREACH(op, &s->ops, link) {
c45cb8bb
RH
1888 int i, k, nb_oargs, nb_iargs, nb_cargs;
1889 const TCGOpDef *def;
c45cb8bb 1890 TCGOpcode c;
bdfb460e 1891 int col = 0;
c896fe29 1892
c45cb8bb 1893 c = op->opc;
c896fe29 1894 def = &tcg_op_defs[c];
c45cb8bb 1895
765b842a 1896 if (c == INDEX_op_insn_start) {
b016486e 1897 nb_oargs = 0;
b7a83ff8 1898 col += ne_fprintf(f, "\n ----");
9aef40ed
RH
1899
1900 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
1901 target_ulong a;
7e4597d7 1902#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
efee3746 1903 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]);
7e4597d7 1904#else
efee3746 1905 a = op->args[i];
7e4597d7 1906#endif
b7a83ff8 1907 col += ne_fprintf(f, " " TARGET_FMT_lx, a);
eeacee4d 1908 }
7e4597d7 1909 } else if (c == INDEX_op_call) {
3e92aa34 1910 const TCGHelperInfo *info = tcg_call_info(op);
fa52e660 1911 void *func = tcg_call_func(op);
3e92aa34 1912
c896fe29 1913 /* variable number of arguments */
cd9090aa
RH
1914 nb_oargs = TCGOP_CALLO(op);
1915 nb_iargs = TCGOP_CALLI(op);
c896fe29 1916 nb_cargs = def->nb_cargs;
c896fe29 1917
b7a83ff8 1918 col += ne_fprintf(f, " %s ", def->name);
3e92aa34
RH
1919
1920 /*
1921 * Print the function name from TCGHelperInfo, if available.
1922 * Note that plugins have a template function for the info,
1923 * but the actual function pointer comes from the plugin.
1924 */
3e92aa34 1925 if (func == info->func) {
b7a83ff8 1926 col += ne_fprintf(f, "%s", info->name);
3e92aa34 1927 } else {
b7a83ff8 1928 col += ne_fprintf(f, "plugin(%p)", func);
3e92aa34
RH
1929 }
1930
b7a83ff8 1931 col += ne_fprintf(f, ",$0x%x,$%d", info->flags, nb_oargs);
cf066674 1932 for (i = 0; i < nb_oargs; i++) {
b7a83ff8
RH
1933 col += ne_fprintf(f, ",%s", tcg_get_arg_str(s, buf, sizeof(buf),
1934 op->args[i]));
b03cce8e 1935 }
cf066674 1936 for (i = 0; i < nb_iargs; i++) {
efee3746 1937 TCGArg arg = op->args[nb_oargs + i];
39004a71 1938 const char *t = tcg_get_arg_str(s, buf, sizeof(buf), arg);
b7a83ff8 1939 col += ne_fprintf(f, ",%s", t);
e8996ee0 1940 }
b03cce8e 1941 } else {
b7a83ff8 1942 col += ne_fprintf(f, " %s ", def->name);
c45cb8bb
RH
1943
1944 nb_oargs = def->nb_oargs;
1945 nb_iargs = def->nb_iargs;
1946 nb_cargs = def->nb_cargs;
1947
d2fd745f 1948 if (def->flags & TCG_OPF_VECTOR) {
b7a83ff8
RH
1949 col += ne_fprintf(f, "v%d,e%d,", 64 << TCGOP_VECL(op),
1950 8 << TCGOP_VECE(op));
d2fd745f
RH
1951 }
1952
b03cce8e 1953 k = 0;
c45cb8bb 1954 for (i = 0; i < nb_oargs; i++) {
b7a83ff8
RH
1955 const char *sep = k ? "," : "";
1956 col += ne_fprintf(f, "%s%s", sep,
1957 tcg_get_arg_str(s, buf, sizeof(buf),
1958 op->args[k++]));
b03cce8e 1959 }
c45cb8bb 1960 for (i = 0; i < nb_iargs; i++) {
b7a83ff8
RH
1961 const char *sep = k ? "," : "";
1962 col += ne_fprintf(f, "%s%s", sep,
1963 tcg_get_arg_str(s, buf, sizeof(buf),
1964 op->args[k++]));
b03cce8e 1965 }
be210acb
RH
1966 switch (c) {
1967 case INDEX_op_brcond_i32:
be210acb 1968 case INDEX_op_setcond_i32:
ffc5ea09 1969 case INDEX_op_movcond_i32:
ffc5ea09 1970 case INDEX_op_brcond2_i32:
be210acb 1971 case INDEX_op_setcond2_i32:
ffc5ea09 1972 case INDEX_op_brcond_i64:
be210acb 1973 case INDEX_op_setcond_i64:
ffc5ea09 1974 case INDEX_op_movcond_i64:
212be173 1975 case INDEX_op_cmp_vec:
f75da298 1976 case INDEX_op_cmpsel_vec:
efee3746
RH
1977 if (op->args[k] < ARRAY_SIZE(cond_name)
1978 && cond_name[op->args[k]]) {
b7a83ff8 1979 col += ne_fprintf(f, ",%s", cond_name[op->args[k++]]);
eeacee4d 1980 } else {
b7a83ff8 1981 col += ne_fprintf(f, ",$0x%" TCG_PRIlx, op->args[k++]);
eeacee4d 1982 }
f48f3ede 1983 i = 1;
be210acb 1984 break;
f713d6ad
RH
1985 case INDEX_op_qemu_ld_i32:
1986 case INDEX_op_qemu_st_i32:
07ce0b05 1987 case INDEX_op_qemu_st8_i32:
f713d6ad
RH
1988 case INDEX_op_qemu_ld_i64:
1989 case INDEX_op_qemu_st_i64:
59227d5d 1990 {
9002ffcb 1991 MemOpIdx oi = op->args[k++];
14776ab5 1992 MemOp op = get_memop(oi);
59227d5d
RH
1993 unsigned ix = get_mmuidx(oi);
1994
59c4b7e8 1995 if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) {
b7a83ff8 1996 col += ne_fprintf(f, ",$0x%x,%u", op, ix);
59c4b7e8 1997 } else {
1f00b27f
SS
1998 const char *s_al, *s_op;
1999 s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT];
59c4b7e8 2000 s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];
b7a83ff8 2001 col += ne_fprintf(f, ",%s%s,%u", s_al, s_op, ix);
59227d5d
RH
2002 }
2003 i = 1;
f713d6ad 2004 }
f713d6ad 2005 break;
587195bd
RH
2006 case INDEX_op_bswap16_i32:
2007 case INDEX_op_bswap16_i64:
2008 case INDEX_op_bswap32_i32:
2009 case INDEX_op_bswap32_i64:
2010 case INDEX_op_bswap64_i64:
2011 {
2012 TCGArg flags = op->args[k];
2013 const char *name = NULL;
2014
2015 if (flags < ARRAY_SIZE(bswap_flag_name)) {
2016 name = bswap_flag_name[flags];
2017 }
2018 if (name) {
b7a83ff8 2019 col += ne_fprintf(f, ",%s", name);
587195bd 2020 } else {
b7a83ff8 2021 col += ne_fprintf(f, ",$0x%" TCG_PRIlx, flags);
587195bd
RH
2022 }
2023 i = k = 1;
2024 }
2025 break;
be210acb 2026 default:
f48f3ede 2027 i = 0;
be210acb
RH
2028 break;
2029 }
51e3972c
RH
2030 switch (c) {
2031 case INDEX_op_set_label:
2032 case INDEX_op_br:
2033 case INDEX_op_brcond_i32:
2034 case INDEX_op_brcond_i64:
2035 case INDEX_op_brcond2_i32:
b7a83ff8
RH
2036 col += ne_fprintf(f, "%s$L%d", k ? "," : "",
2037 arg_label(op->args[k])->id);
51e3972c
RH
2038 i++, k++;
2039 break;
2040 default:
2041 break;
2042 }
2043 for (; i < nb_cargs; i++, k++) {
b7a83ff8
RH
2044 col += ne_fprintf(f, "%s$0x%" TCG_PRIlx, k ? "," : "",
2045 op->args[k]);
bdfb460e
RH
2046 }
2047 }
bdfb460e 2048
1894f69a 2049 if (have_prefs || op->life) {
b7a83ff8
RH
2050 for (; col < 40; ++col) {
2051 putc(' ', f);
bdfb460e 2052 }
1894f69a
RH
2053 }
2054
2055 if (op->life) {
2056 unsigned life = op->life;
bdfb460e
RH
2057
2058 if (life & (SYNC_ARG * 3)) {
b7a83ff8 2059 ne_fprintf(f, " sync:");
bdfb460e
RH
2060 for (i = 0; i < 2; ++i) {
2061 if (life & (SYNC_ARG << i)) {
b7a83ff8 2062 ne_fprintf(f, " %d", i);
bdfb460e
RH
2063 }
2064 }
2065 }
2066 life /= DEAD_ARG;
2067 if (life) {
b7a83ff8 2068 ne_fprintf(f, " dead:");
bdfb460e
RH
2069 for (i = 0; life; ++i, life >>= 1) {
2070 if (life & 1) {
b7a83ff8 2071 ne_fprintf(f, " %d", i);
bdfb460e
RH
2072 }
2073 }
b03cce8e 2074 }
c896fe29 2075 }
1894f69a
RH
2076
2077 if (have_prefs) {
2078 for (i = 0; i < nb_oargs; ++i) {
31fd884b 2079 TCGRegSet set = output_pref(op, i);
1894f69a
RH
2080
2081 if (i == 0) {
b7a83ff8 2082 ne_fprintf(f, " pref=");
1894f69a 2083 } else {
b7a83ff8 2084 ne_fprintf(f, ",");
1894f69a
RH
2085 }
2086 if (set == 0) {
b7a83ff8 2087 ne_fprintf(f, "none");
1894f69a 2088 } else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) {
b7a83ff8 2089 ne_fprintf(f, "all");
1894f69a
RH
2090#ifdef CONFIG_DEBUG_TCG
2091 } else if (tcg_regset_single(set)) {
2092 TCGReg reg = tcg_regset_first(set);
b7a83ff8 2093 ne_fprintf(f, "%s", tcg_target_reg_names[reg]);
1894f69a
RH
2094#endif
2095 } else if (TCG_TARGET_NB_REGS <= 32) {
b7a83ff8 2096 ne_fprintf(f, "0x%x", (uint32_t)set);
1894f69a 2097 } else {
b7a83ff8 2098 ne_fprintf(f, "0x%" PRIx64, (uint64_t)set);
1894f69a
RH
2099 }
2100 }
2101 }
2102
b7a83ff8 2103 putc('\n', f);
c896fe29
FB
2104 }
2105}
2106
2107/* we give more priority to constraints with less registers */
2108static int get_constraint_priority(const TCGOpDef *def, int k)
2109{
74a11790 2110 const TCGArgConstraint *arg_ct = &def->args_ct[k];
29f5e925 2111 int n = ctpop64(arg_ct->regs);
c896fe29 2112
29f5e925
RH
2113 /*
2114 * Sort constraints of a single register first, which includes output
2115 * aliases (which must exactly match the input already allocated).
2116 */
2117 if (n == 1 || arg_ct->oalias) {
2118 return INT_MAX;
2119 }
2120
2121 /*
2122 * Sort register pairs next, first then second immediately after.
2123 * Arbitrarily sort multiple pairs by the index of the first reg;
2124 * there shouldn't be many pairs.
2125 */
2126 switch (arg_ct->pair) {
2127 case 1:
2128 case 3:
2129 return (k + 1) * 2;
2130 case 2:
2131 return (arg_ct->pair_index + 1) * 2 - 1;
c896fe29 2132 }
29f5e925
RH
2133
2134 /* Finally, sort by decreasing register count. */
2135 assert(n > 1);
2136 return -n;
c896fe29
FB
2137}
2138
2139/* sort from highest priority to lowest */
2140static void sort_constraints(TCGOpDef *def, int start, int n)
2141{
66792f90
RH
2142 int i, j;
2143 TCGArgConstraint *a = def->args_ct;
c896fe29 2144
66792f90
RH
2145 for (i = 0; i < n; i++) {
2146 a[start + i].sort_index = start + i;
2147 }
2148 if (n <= 1) {
c896fe29 2149 return;
66792f90
RH
2150 }
2151 for (i = 0; i < n - 1; i++) {
2152 for (j = i + 1; j < n; j++) {
2153 int p1 = get_constraint_priority(def, a[start + i].sort_index);
2154 int p2 = get_constraint_priority(def, a[start + j].sort_index);
c896fe29 2155 if (p1 < p2) {
66792f90
RH
2156 int tmp = a[start + i].sort_index;
2157 a[start + i].sort_index = a[start + j].sort_index;
2158 a[start + j].sort_index = tmp;
c896fe29
FB
2159 }
2160 }
2161 }
2162}
2163
f69d277e 2164static void process_op_defs(TCGContext *s)
c896fe29 2165{
a9751609 2166 TCGOpcode op;
c896fe29 2167
f69d277e
RH
2168 for (op = 0; op < NB_OPS; op++) {
2169 TCGOpDef *def = &tcg_op_defs[op];
2170 const TCGTargetOpDef *tdefs;
29f5e925
RH
2171 bool saw_alias_pair = false;
2172 int i, o, i2, o2, nb_args;
f69d277e
RH
2173
2174 if (def->flags & TCG_OPF_NOT_PRESENT) {
2175 continue;
2176 }
2177
c896fe29 2178 nb_args = def->nb_iargs + def->nb_oargs;
f69d277e
RH
2179 if (nb_args == 0) {
2180 continue;
2181 }
2182
4c22e840
RH
2183 /*
2184 * Macro magic should make it impossible, but double-check that
2185 * the array index is in range. Since the signness of an enum
2186 * is implementation defined, force the result to unsigned.
2187 */
2188 unsigned con_set = tcg_target_op_def(op);
2189 tcg_debug_assert(con_set < ARRAY_SIZE(constraint_sets));
2190 tdefs = &constraint_sets[con_set];
f69d277e
RH
2191
2192 for (i = 0; i < nb_args; i++) {
2193 const char *ct_str = tdefs->args_ct_str[i];
8940ea0d
PMD
2194 bool input_p = i >= def->nb_oargs;
2195
f69d277e 2196 /* Incomplete TCGTargetOpDef entry. */
eabb7b91 2197 tcg_debug_assert(ct_str != NULL);
f69d277e 2198
8940ea0d
PMD
2199 switch (*ct_str) {
2200 case '0' ... '9':
2201 o = *ct_str - '0';
2202 tcg_debug_assert(input_p);
2203 tcg_debug_assert(o < def->nb_oargs);
2204 tcg_debug_assert(def->args_ct[o].regs != 0);
2205 tcg_debug_assert(!def->args_ct[o].oalias);
2206 def->args_ct[i] = def->args_ct[o];
2207 /* The output sets oalias. */
2208 def->args_ct[o].oalias = 1;
2209 def->args_ct[o].alias_index = i;
2210 /* The input sets ialias. */
2211 def->args_ct[i].ialias = 1;
2212 def->args_ct[i].alias_index = o;
29f5e925
RH
2213 if (def->args_ct[i].pair) {
2214 saw_alias_pair = true;
2215 }
8940ea0d
PMD
2216 tcg_debug_assert(ct_str[1] == '\0');
2217 continue;
2218
2219 case '&':
2220 tcg_debug_assert(!input_p);
2221 def->args_ct[i].newreg = true;
2222 ct_str++;
2223 break;
29f5e925
RH
2224
2225 case 'p': /* plus */
2226 /* Allocate to the register after the previous. */
2227 tcg_debug_assert(i > (input_p ? def->nb_oargs : 0));
2228 o = i - 1;
2229 tcg_debug_assert(!def->args_ct[o].pair);
2230 tcg_debug_assert(!def->args_ct[o].ct);
2231 def->args_ct[i] = (TCGArgConstraint){
2232 .pair = 2,
2233 .pair_index = o,
2234 .regs = def->args_ct[o].regs << 1,
2235 };
2236 def->args_ct[o].pair = 1;
2237 def->args_ct[o].pair_index = i;
2238 tcg_debug_assert(ct_str[1] == '\0');
2239 continue;
2240
2241 case 'm': /* minus */
2242 /* Allocate to the register before the previous. */
2243 tcg_debug_assert(i > (input_p ? def->nb_oargs : 0));
2244 o = i - 1;
2245 tcg_debug_assert(!def->args_ct[o].pair);
2246 tcg_debug_assert(!def->args_ct[o].ct);
2247 def->args_ct[i] = (TCGArgConstraint){
2248 .pair = 1,
2249 .pair_index = o,
2250 .regs = def->args_ct[o].regs >> 1,
2251 };
2252 def->args_ct[o].pair = 2;
2253 def->args_ct[o].pair_index = i;
2254 tcg_debug_assert(ct_str[1] == '\0');
2255 continue;
8940ea0d
PMD
2256 }
2257
2258 do {
2259 switch (*ct_str) {
17280ff4
RH
2260 case 'i':
2261 def->args_ct[i].ct |= TCG_CT_CONST;
17280ff4 2262 break;
358b4923 2263
358b4923
RH
2264 /* Include all of the target-specific constraints. */
2265
2266#undef CONST
2267#define CONST(CASE, MASK) \
8940ea0d 2268 case CASE: def->args_ct[i].ct |= MASK; break;
358b4923 2269#define REGS(CASE, MASK) \
8940ea0d 2270 case CASE: def->args_ct[i].regs |= MASK; break;
358b4923
RH
2271
2272#include "tcg-target-con-str.h"
2273
2274#undef REGS
2275#undef CONST
17280ff4 2276 default:
8940ea0d
PMD
2277 case '0' ... '9':
2278 case '&':
29f5e925
RH
2279 case 'p':
2280 case 'm':
17280ff4 2281 /* Typo in TCGTargetOpDef constraint. */
358b4923 2282 g_assert_not_reached();
c896fe29 2283 }
8940ea0d 2284 } while (*++ct_str != '\0');
c896fe29
FB
2285 }
2286
c68aaa18 2287 /* TCGTargetOpDef entry with too much information? */
eabb7b91 2288 tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
c68aaa18 2289
29f5e925
RH
2290 /*
2291 * Fix up output pairs that are aliased with inputs.
2292 * When we created the alias, we copied pair from the output.
2293 * There are three cases:
2294 * (1a) Pairs of inputs alias pairs of outputs.
2295 * (1b) One input aliases the first of a pair of outputs.
2296 * (2) One input aliases the second of a pair of outputs.
2297 *
2298 * Case 1a is handled by making sure that the pair_index'es are
2299 * properly updated so that they appear the same as a pair of inputs.
2300 *
2301 * Case 1b is handled by setting the pair_index of the input to
2302 * itself, simply so it doesn't point to an unrelated argument.
2303 * Since we don't encounter the "second" during the input allocation
2304 * phase, nothing happens with the second half of the input pair.
2305 *
2306 * Case 2 is handled by setting the second input to pair=3, the
2307 * first output to pair=3, and the pair_index'es to match.
2308 */
2309 if (saw_alias_pair) {
2310 for (i = def->nb_oargs; i < nb_args; i++) {
2311 /*
2312 * Since [0-9pm] must be alone in the constraint string,
2313 * the only way they can both be set is if the pair comes
2314 * from the output alias.
2315 */
2316 if (!def->args_ct[i].ialias) {
2317 continue;
2318 }
2319 switch (def->args_ct[i].pair) {
2320 case 0:
2321 break;
2322 case 1:
2323 o = def->args_ct[i].alias_index;
2324 o2 = def->args_ct[o].pair_index;
2325 tcg_debug_assert(def->args_ct[o].pair == 1);
2326 tcg_debug_assert(def->args_ct[o2].pair == 2);
2327 if (def->args_ct[o2].oalias) {
2328 /* Case 1a */
2329 i2 = def->args_ct[o2].alias_index;
2330 tcg_debug_assert(def->args_ct[i2].pair == 2);
2331 def->args_ct[i2].pair_index = i;
2332 def->args_ct[i].pair_index = i2;
2333 } else {
2334 /* Case 1b */
2335 def->args_ct[i].pair_index = i;
2336 }
2337 break;
2338 case 2:
2339 o = def->args_ct[i].alias_index;
2340 o2 = def->args_ct[o].pair_index;
2341 tcg_debug_assert(def->args_ct[o].pair == 2);
2342 tcg_debug_assert(def->args_ct[o2].pair == 1);
2343 if (def->args_ct[o2].oalias) {
2344 /* Case 1a */
2345 i2 = def->args_ct[o2].alias_index;
2346 tcg_debug_assert(def->args_ct[i2].pair == 1);
2347 def->args_ct[i2].pair_index = i;
2348 def->args_ct[i].pair_index = i2;
2349 } else {
2350 /* Case 2 */
2351 def->args_ct[i].pair = 3;
2352 def->args_ct[o2].pair = 3;
2353 def->args_ct[i].pair_index = o2;
2354 def->args_ct[o2].pair_index = i;
2355 }
2356 break;
2357 default:
2358 g_assert_not_reached();
2359 }
2360 }
2361 }
2362
c896fe29
FB
2363 /* sort the constraints (XXX: this is just an heuristic) */
2364 sort_constraints(def, 0, def->nb_oargs);
2365 sort_constraints(def, def->nb_oargs, def->nb_iargs);
a9751609 2366 }
c896fe29
FB
2367}
2368
0c627cdc
RH
2369void tcg_op_remove(TCGContext *s, TCGOp *op)
2370{
d88a117e
RH
2371 TCGLabel *label;
2372
2373 switch (op->opc) {
2374 case INDEX_op_br:
2375 label = arg_label(op->args[0]);
2376 label->refs--;
2377 break;
2378 case INDEX_op_brcond_i32:
2379 case INDEX_op_brcond_i64:
2380 label = arg_label(op->args[3]);
2381 label->refs--;
2382 break;
2383 case INDEX_op_brcond2_i32:
2384 label = arg_label(op->args[5]);
2385 label->refs--;
2386 break;
2387 default:
2388 break;
2389 }
2390
15fa08f8
RH
2391 QTAILQ_REMOVE(&s->ops, op, link);
2392 QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
abebf925 2393 s->nb_ops--;
0c627cdc
RH
2394
2395#ifdef CONFIG_PROFILER
d73415a3 2396 qatomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
0c627cdc
RH
2397#endif
2398}
2399
a80cdd31
RH
2400void tcg_remove_ops_after(TCGOp *op)
2401{
2402 TCGContext *s = tcg_ctx;
2403
2404 while (true) {
2405 TCGOp *last = tcg_last_op();
2406 if (last == op) {
2407 return;
2408 }
2409 tcg_op_remove(s, last);
2410 }
2411}
2412
d4478943 2413static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
5a18407f 2414{
15fa08f8 2415 TCGContext *s = tcg_ctx;
cb10bc63
RH
2416 TCGOp *op = NULL;
2417
2418 if (unlikely(!QTAILQ_EMPTY(&s->free_ops))) {
2419 QTAILQ_FOREACH(op, &s->free_ops, link) {
2420 if (nargs <= op->nargs) {
2421 QTAILQ_REMOVE(&s->free_ops, op, link);
2422 nargs = op->nargs;
2423 goto found;
2424 }
2425 }
15fa08f8 2426 }
cb10bc63
RH
2427
2428 /* Most opcodes have 3 or 4 operands: reduce fragmentation. */
2429 nargs = MAX(4, nargs);
2430 op = tcg_malloc(sizeof(TCGOp) + sizeof(TCGArg) * nargs);
2431
2432 found:
15fa08f8
RH
2433 memset(op, 0, offsetof(TCGOp, link));
2434 op->opc = opc;
cb10bc63
RH
2435 op->nargs = nargs;
2436
2437 /* Check for bitfield overflow. */
2438 tcg_debug_assert(op->nargs == nargs);
5a18407f 2439
cb10bc63 2440 s->nb_ops++;
15fa08f8
RH
2441 return op;
2442}
2443
d4478943 2444TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs)
15fa08f8 2445{
d4478943 2446 TCGOp *op = tcg_op_alloc(opc, nargs);
15fa08f8
RH
2447 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
2448 return op;
2449}
5a18407f 2450
d4478943
PMD
2451TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
2452 TCGOpcode opc, unsigned nargs)
15fa08f8 2453{
d4478943 2454 TCGOp *new_op = tcg_op_alloc(opc, nargs);
15fa08f8 2455 QTAILQ_INSERT_BEFORE(old_op, new_op, link);
5a18407f
RH
2456 return new_op;
2457}
2458
d4478943
PMD
2459TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
2460 TCGOpcode opc, unsigned nargs)
5a18407f 2461{
d4478943 2462 TCGOp *new_op = tcg_op_alloc(opc, nargs);
15fa08f8 2463 QTAILQ_INSERT_AFTER(&s->ops, old_op, new_op, link);
5a18407f
RH
2464 return new_op;
2465}
2466
b4fc67c7
RH
2467/* Reachable analysis : remove unreachable code. */
2468static void reachable_code_pass(TCGContext *s)
2469{
2470 TCGOp *op, *op_next;
2471 bool dead = false;
2472
2473 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
2474 bool remove = dead;
2475 TCGLabel *label;
b4fc67c7
RH
2476
2477 switch (op->opc) {
2478 case INDEX_op_set_label:
2479 label = arg_label(op->args[0]);
2480 if (label->refs == 0) {
2481 /*
2482 * While there is an occasional backward branch, virtually
2483 * all branches generated by the translators are forward.
2484 * Which means that generally we will have already removed
2485 * all references to the label that will be, and there is
2486 * little to be gained by iterating.
2487 */
2488 remove = true;
2489 } else {
2490 /* Once we see a label, insns become live again. */
2491 dead = false;
2492 remove = false;
2493
2494 /*
2495 * Optimization can fold conditional branches to unconditional.
2496 * If we find a label with one reference which is preceded by
2497 * an unconditional branch to it, remove both. This needed to
2498 * wait until the dead code in between them was removed.
2499 */
2500 if (label->refs == 1) {
eae3eb3e 2501 TCGOp *op_prev = QTAILQ_PREV(op, link);
b4fc67c7
RH
2502 if (op_prev->opc == INDEX_op_br &&
2503 label == arg_label(op_prev->args[0])) {
2504 tcg_op_remove(s, op_prev);
2505 remove = true;
2506 }
2507 }
2508 }
2509 break;
2510
2511 case INDEX_op_br:
2512 case INDEX_op_exit_tb:
2513 case INDEX_op_goto_ptr:
2514 /* Unconditional branches; everything following is dead. */
2515 dead = true;
2516 break;
2517
2518 case INDEX_op_call:
2519 /* Notice noreturn helper calls, raising exceptions. */
90163900 2520 if (tcg_call_flags(op) & TCG_CALL_NO_RETURN) {
b4fc67c7
RH
2521 dead = true;
2522 }
2523 break;
2524
2525 case INDEX_op_insn_start:
2526 /* Never remove -- we need to keep these for unwind. */
2527 remove = false;
2528 break;
2529
2530 default:
2531 break;
2532 }
2533
2534 if (remove) {
2535 tcg_op_remove(s, op);
2536 }
2537 }
2538}
2539
c70fbf0a
RH
2540#define TS_DEAD 1
2541#define TS_MEM 2
2542
5a18407f
RH
2543#define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
2544#define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
2545
25f49c5f
RH
2546/* For liveness_pass_1, the register preferences for a given temp. */
2547static inline TCGRegSet *la_temp_pref(TCGTemp *ts)
2548{
2549 return ts->state_ptr;
2550}
2551
2552/* For liveness_pass_1, reset the preferences for a given temp to the
2553 * maximal regset for its type.
2554 */
2555static inline void la_reset_pref(TCGTemp *ts)
2556{
2557 *la_temp_pref(ts)
2558 = (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]);
2559}
2560
9c43b68d
AJ
2561/* liveness analysis: end of function: all temps are dead, and globals
2562 should be in memory. */
2616c808 2563static void la_func_end(TCGContext *s, int ng, int nt)
c896fe29 2564{
b83eabea
RH
2565 int i;
2566
2567 for (i = 0; i < ng; ++i) {
2568 s->temps[i].state = TS_DEAD | TS_MEM;
25f49c5f 2569 la_reset_pref(&s->temps[i]);
b83eabea
RH
2570 }
2571 for (i = ng; i < nt; ++i) {
2572 s->temps[i].state = TS_DEAD;
25f49c5f 2573 la_reset_pref(&s->temps[i]);
b83eabea 2574 }
c896fe29
FB
2575}
2576
9c43b68d
AJ
2577/* liveness analysis: end of basic block: all temps are dead, globals
2578 and local temps should be in memory. */
2616c808 2579static void la_bb_end(TCGContext *s, int ng, int nt)
641d5fbe 2580{
b83eabea 2581 int i;
641d5fbe 2582
ee17db83
RH
2583 for (i = 0; i < nt; ++i) {
2584 TCGTemp *ts = &s->temps[i];
2585 int state;
2586
2587 switch (ts->kind) {
2588 case TEMP_FIXED:
2589 case TEMP_GLOBAL:
2590 case TEMP_LOCAL:
2591 state = TS_DEAD | TS_MEM;
2592 break;
2593 case TEMP_NORMAL:
c7482438 2594 case TEMP_EBB:
c0522136 2595 case TEMP_CONST:
ee17db83
RH
2596 state = TS_DEAD;
2597 break;
2598 default:
2599 g_assert_not_reached();
2600 }
2601 ts->state = state;
2602 la_reset_pref(ts);
641d5fbe
FB
2603 }
2604}
2605
f65a061c
RH
2606/* liveness analysis: sync globals back to memory. */
2607static void la_global_sync(TCGContext *s, int ng)
2608{
2609 int i;
2610
2611 for (i = 0; i < ng; ++i) {
25f49c5f
RH
2612 int state = s->temps[i].state;
2613 s->temps[i].state = state | TS_MEM;
2614 if (state == TS_DEAD) {
2615 /* If the global was previously dead, reset prefs. */
2616 la_reset_pref(&s->temps[i]);
2617 }
f65a061c
RH
2618 }
2619}
2620
b4cb76e6 2621/*
c7482438
RH
2622 * liveness analysis: conditional branch: all temps are dead unless
2623 * explicitly live-across-conditional-branch, globals and local temps
2624 * should be synced.
b4cb76e6
RH
2625 */
2626static void la_bb_sync(TCGContext *s, int ng, int nt)
2627{
2628 la_global_sync(s, ng);
2629
2630 for (int i = ng; i < nt; ++i) {
c0522136
RH
2631 TCGTemp *ts = &s->temps[i];
2632 int state;
2633
2634 switch (ts->kind) {
2635 case TEMP_LOCAL:
2636 state = ts->state;
2637 ts->state = state | TS_MEM;
b4cb76e6
RH
2638 if (state != TS_DEAD) {
2639 continue;
2640 }
c0522136
RH
2641 break;
2642 case TEMP_NORMAL:
b4cb76e6 2643 s->temps[i].state = TS_DEAD;
c0522136 2644 break;
c7482438 2645 case TEMP_EBB:
c0522136
RH
2646 case TEMP_CONST:
2647 continue;
2648 default:
2649 g_assert_not_reached();
b4cb76e6
RH
2650 }
2651 la_reset_pref(&s->temps[i]);
2652 }
2653}
2654
f65a061c
RH
2655/* liveness analysis: sync globals back to memory and kill. */
2656static void la_global_kill(TCGContext *s, int ng)
2657{
2658 int i;
2659
2660 for (i = 0; i < ng; i++) {
2661 s->temps[i].state = TS_DEAD | TS_MEM;
25f49c5f
RH
2662 la_reset_pref(&s->temps[i]);
2663 }
2664}
2665
2666/* liveness analysis: note live globals crossing calls. */
2667static void la_cross_call(TCGContext *s, int nt)
2668{
2669 TCGRegSet mask = ~tcg_target_call_clobber_regs;
2670 int i;
2671
2672 for (i = 0; i < nt; i++) {
2673 TCGTemp *ts = &s->temps[i];
2674 if (!(ts->state & TS_DEAD)) {
2675 TCGRegSet *pset = la_temp_pref(ts);
2676 TCGRegSet set = *pset;
2677
2678 set &= mask;
2679 /* If the combination is not possible, restart. */
2680 if (set == 0) {
2681 set = tcg_target_available_regs[ts->type] & mask;
2682 }
2683 *pset = set;
2684 }
f65a061c
RH
2685 }
2686}
2687
a1b3c48d 2688/* Liveness analysis : update the opc_arg_life array to tell if a
c896fe29
FB
2689 given input arguments is dead. Instructions updating dead
2690 temporaries are removed. */
b83eabea 2691static void liveness_pass_1(TCGContext *s)
c896fe29 2692{
c70fbf0a 2693 int nb_globals = s->nb_globals;
2616c808 2694 int nb_temps = s->nb_temps;
15fa08f8 2695 TCGOp *op, *op_prev;
25f49c5f
RH
2696 TCGRegSet *prefs;
2697 int i;
2698
2699 prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps);
2700 for (i = 0; i < nb_temps; ++i) {
2701 s->temps[i].state_ptr = prefs + i;
2702 }
a1b3c48d 2703
ae36a246 2704 /* ??? Should be redundant with the exit_tb that ends the TB. */
2616c808 2705 la_func_end(s, nb_globals, nb_temps);
c896fe29 2706
eae3eb3e 2707 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, link, op_prev) {
25f49c5f 2708 int nb_iargs, nb_oargs;
c45cb8bb
RH
2709 TCGOpcode opc_new, opc_new2;
2710 bool have_opc_new2;
a1b3c48d 2711 TCGLifeData arg_life = 0;
25f49c5f 2712 TCGTemp *ts;
c45cb8bb
RH
2713 TCGOpcode opc = op->opc;
2714 const TCGOpDef *def = &tcg_op_defs[opc];
2715
c45cb8bb 2716 switch (opc) {
c896fe29 2717 case INDEX_op_call:
c6e113f5 2718 {
39004a71
RH
2719 const TCGHelperInfo *info = tcg_call_info(op);
2720 int call_flags = tcg_call_flags(op);
c896fe29 2721
cd9090aa
RH
2722 nb_oargs = TCGOP_CALLO(op);
2723 nb_iargs = TCGOP_CALLI(op);
c6e113f5 2724
c45cb8bb 2725 /* pure functions can be removed if their result is unused */
78505279 2726 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
cf066674 2727 for (i = 0; i < nb_oargs; i++) {
25f49c5f
RH
2728 ts = arg_temp(op->args[i]);
2729 if (ts->state != TS_DEAD) {
c6e113f5 2730 goto do_not_remove_call;
9c43b68d 2731 }
c6e113f5 2732 }
c45cb8bb 2733 goto do_remove;
152c35aa
RH
2734 }
2735 do_not_remove_call:
c896fe29 2736
25f49c5f 2737 /* Output args are dead. */
152c35aa 2738 for (i = 0; i < nb_oargs; i++) {
25f49c5f
RH
2739 ts = arg_temp(op->args[i]);
2740 if (ts->state & TS_DEAD) {
152c35aa
RH
2741 arg_life |= DEAD_ARG << i;
2742 }
25f49c5f 2743 if (ts->state & TS_MEM) {
152c35aa 2744 arg_life |= SYNC_ARG << i;
c6e113f5 2745 }
25f49c5f
RH
2746 ts->state = TS_DEAD;
2747 la_reset_pref(ts);
152c35aa 2748 }
78505279 2749
31fd884b
RH
2750 /* Not used -- it will be tcg_target_call_oarg_reg(). */
2751 memset(op->output_pref, 0, sizeof(op->output_pref));
2752
152c35aa
RH
2753 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
2754 TCG_CALL_NO_READ_GLOBALS))) {
f65a061c 2755 la_global_kill(s, nb_globals);
152c35aa 2756 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
f65a061c 2757 la_global_sync(s, nb_globals);
152c35aa 2758 }
b9c18f56 2759
25f49c5f 2760 /* Record arguments that die in this helper. */
152c35aa 2761 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
25f49c5f 2762 ts = arg_temp(op->args[i]);
39004a71 2763 if (ts->state & TS_DEAD) {
152c35aa 2764 arg_life |= DEAD_ARG << i;
c6e113f5 2765 }
152c35aa 2766 }
25f49c5f
RH
2767
2768 /* For all live registers, remove call-clobbered prefs. */
2769 la_cross_call(s, nb_temps);
2770
39004a71
RH
2771 /*
2772 * Input arguments are live for preceding opcodes.
2773 *
2774 * For those arguments that die, and will be allocated in
2775 * registers, clear the register set for that arg, to be
2776 * filled in below. For args that will be on the stack,
2777 * reset to any available reg. Process arguments in reverse
2778 * order so that if a temp is used more than once, the stack
2779 * reset to max happens before the register reset to 0.
2780 */
2781 for (i = nb_iargs - 1; i >= 0; i--) {
2782 const TCGCallArgumentLoc *loc = &info->in[i];
2783 ts = arg_temp(op->args[nb_oargs + i]);
25f49c5f 2784
39004a71
RH
2785 if (ts->state & TS_DEAD) {
2786 switch (loc->kind) {
2787 case TCG_CALL_ARG_NORMAL:
2788 case TCG_CALL_ARG_EXTEND_U:
2789 case TCG_CALL_ARG_EXTEND_S:
2790 if (REG_P(loc)) {
2791 *la_temp_pref(ts) = 0;
2792 break;
2793 }
2794 /* fall through */
2795 default:
2796 *la_temp_pref(ts) =
2797 tcg_target_available_regs[ts->type];
2798 break;
2799 }
25f49c5f
RH
2800 ts->state &= ~TS_DEAD;
2801 }
2802 }
2803
39004a71
RH
2804 /*
2805 * For each input argument, add its input register to prefs.
2806 * If a temp is used once, this produces a single set bit;
2807 * if a temp is used multiple times, this produces a set.
2808 */
2809 for (i = 0; i < nb_iargs; i++) {
2810 const TCGCallArgumentLoc *loc = &info->in[i];
2811 ts = arg_temp(op->args[nb_oargs + i]);
2812
2813 switch (loc->kind) {
2814 case TCG_CALL_ARG_NORMAL:
2815 case TCG_CALL_ARG_EXTEND_U:
2816 case TCG_CALL_ARG_EXTEND_S:
2817 if (REG_P(loc)) {
2818 tcg_regset_set_reg(*la_temp_pref(ts),
2819 tcg_target_call_iarg_regs[loc->arg_slot]);
2820 }
2821 break;
2822 default:
2823 break;
c19f47bf 2824 }
c896fe29 2825 }
c896fe29 2826 }
c896fe29 2827 break;
765b842a 2828 case INDEX_op_insn_start:
c896fe29 2829 break;
5ff9d6a4 2830 case INDEX_op_discard:
5ff9d6a4 2831 /* mark the temporary as dead */
25f49c5f
RH
2832 ts = arg_temp(op->args[0]);
2833 ts->state = TS_DEAD;
2834 la_reset_pref(ts);
5ff9d6a4 2835 break;
1305c451
RH
2836
2837 case INDEX_op_add2_i32:
c45cb8bb 2838 opc_new = INDEX_op_add_i32;
f1fae40c 2839 goto do_addsub2;
1305c451 2840 case INDEX_op_sub2_i32:
c45cb8bb 2841 opc_new = INDEX_op_sub_i32;
f1fae40c
RH
2842 goto do_addsub2;
2843 case INDEX_op_add2_i64:
c45cb8bb 2844 opc_new = INDEX_op_add_i64;
f1fae40c
RH
2845 goto do_addsub2;
2846 case INDEX_op_sub2_i64:
c45cb8bb 2847 opc_new = INDEX_op_sub_i64;
f1fae40c 2848 do_addsub2:
1305c451
RH
2849 nb_iargs = 4;
2850 nb_oargs = 2;
2851 /* Test if the high part of the operation is dead, but not
2852 the low part. The result can be optimized to a simple
2853 add or sub. This happens often for x86_64 guest when the
2854 cpu mode is set to 32 bit. */
b83eabea
RH
2855 if (arg_temp(op->args[1])->state == TS_DEAD) {
2856 if (arg_temp(op->args[0])->state == TS_DEAD) {
1305c451
RH
2857 goto do_remove;
2858 }
c45cb8bb
RH
2859 /* Replace the opcode and adjust the args in place,
2860 leaving 3 unused args at the end. */
2861 op->opc = opc = opc_new;
efee3746
RH
2862 op->args[1] = op->args[2];
2863 op->args[2] = op->args[4];
1305c451
RH
2864 /* Fall through and mark the single-word operation live. */
2865 nb_iargs = 2;
2866 nb_oargs = 1;
2867 }
2868 goto do_not_remove;
2869
1414968a 2870 case INDEX_op_mulu2_i32:
c45cb8bb
RH
2871 opc_new = INDEX_op_mul_i32;
2872 opc_new2 = INDEX_op_muluh_i32;
2873 have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
03271524 2874 goto do_mul2;
f1fae40c 2875 case INDEX_op_muls2_i32:
c45cb8bb
RH
2876 opc_new = INDEX_op_mul_i32;
2877 opc_new2 = INDEX_op_mulsh_i32;
2878 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
f1fae40c
RH
2879 goto do_mul2;
2880 case INDEX_op_mulu2_i64:
c45cb8bb
RH
2881 opc_new = INDEX_op_mul_i64;
2882 opc_new2 = INDEX_op_muluh_i64;
2883 have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
03271524 2884 goto do_mul2;
f1fae40c 2885 case INDEX_op_muls2_i64:
c45cb8bb
RH
2886 opc_new = INDEX_op_mul_i64;
2887 opc_new2 = INDEX_op_mulsh_i64;
2888 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
03271524 2889 goto do_mul2;
f1fae40c 2890 do_mul2:
1414968a
RH
2891 nb_iargs = 2;
2892 nb_oargs = 2;
b83eabea
RH
2893 if (arg_temp(op->args[1])->state == TS_DEAD) {
2894 if (arg_temp(op->args[0])->state == TS_DEAD) {
03271524 2895 /* Both parts of the operation are dead. */
1414968a
RH
2896 goto do_remove;
2897 }
03271524 2898 /* The high part of the operation is dead; generate the low. */
c45cb8bb 2899 op->opc = opc = opc_new;
efee3746
RH
2900 op->args[1] = op->args[2];
2901 op->args[2] = op->args[3];
b83eabea 2902 } else if (arg_temp(op->args[0])->state == TS_DEAD && have_opc_new2) {
c45cb8bb
RH
2903 /* The low part of the operation is dead; generate the high. */
2904 op->opc = opc = opc_new2;
efee3746
RH
2905 op->args[0] = op->args[1];
2906 op->args[1] = op->args[2];
2907 op->args[2] = op->args[3];
03271524
RH
2908 } else {
2909 goto do_not_remove;
1414968a 2910 }
03271524
RH
2911 /* Mark the single-word operation live. */
2912 nb_oargs = 1;
1414968a
RH
2913 goto do_not_remove;
2914
c896fe29 2915 default:
1305c451 2916 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
49516bc0
AJ
2917 nb_iargs = def->nb_iargs;
2918 nb_oargs = def->nb_oargs;
c896fe29 2919
49516bc0
AJ
2920 /* Test if the operation can be removed because all
2921 its outputs are dead. We assume that nb_oargs == 0
2922 implies side effects */
2923 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
c45cb8bb 2924 for (i = 0; i < nb_oargs; i++) {
b83eabea 2925 if (arg_temp(op->args[i])->state != TS_DEAD) {
49516bc0 2926 goto do_not_remove;
9c43b68d 2927 }
49516bc0 2928 }
152c35aa
RH
2929 goto do_remove;
2930 }
2931 goto do_not_remove;
49516bc0 2932
152c35aa
RH
2933 do_remove:
2934 tcg_op_remove(s, op);
2935 break;
2936
2937 do_not_remove:
152c35aa 2938 for (i = 0; i < nb_oargs; i++) {
25f49c5f
RH
2939 ts = arg_temp(op->args[i]);
2940
2941 /* Remember the preference of the uses that followed. */
31fd884b
RH
2942 if (i < ARRAY_SIZE(op->output_pref)) {
2943 op->output_pref[i] = *la_temp_pref(ts);
2944 }
25f49c5f
RH
2945
2946 /* Output args are dead. */
2947 if (ts->state & TS_DEAD) {
152c35aa 2948 arg_life |= DEAD_ARG << i;
49516bc0 2949 }
25f49c5f 2950 if (ts->state & TS_MEM) {
152c35aa
RH
2951 arg_life |= SYNC_ARG << i;
2952 }
25f49c5f
RH
2953 ts->state = TS_DEAD;
2954 la_reset_pref(ts);
152c35aa 2955 }
49516bc0 2956
25f49c5f 2957 /* If end of basic block, update. */
ae36a246
RH
2958 if (def->flags & TCG_OPF_BB_EXIT) {
2959 la_func_end(s, nb_globals, nb_temps);
b4cb76e6
RH
2960 } else if (def->flags & TCG_OPF_COND_BRANCH) {
2961 la_bb_sync(s, nb_globals, nb_temps);
ae36a246 2962 } else if (def->flags & TCG_OPF_BB_END) {
2616c808 2963 la_bb_end(s, nb_globals, nb_temps);
152c35aa 2964 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
f65a061c 2965 la_global_sync(s, nb_globals);
25f49c5f
RH
2966 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2967 la_cross_call(s, nb_temps);
2968 }
152c35aa
RH
2969 }
2970
25f49c5f 2971 /* Record arguments that die in this opcode. */
152c35aa 2972 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
25f49c5f
RH
2973 ts = arg_temp(op->args[i]);
2974 if (ts->state & TS_DEAD) {
152c35aa 2975 arg_life |= DEAD_ARG << i;
c896fe29 2976 }
c896fe29 2977 }
25f49c5f
RH
2978
2979 /* Input arguments are live for preceding opcodes. */
152c35aa 2980 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
25f49c5f
RH
2981 ts = arg_temp(op->args[i]);
2982 if (ts->state & TS_DEAD) {
2983 /* For operands that were dead, initially allow
2984 all regs for the type. */
2985 *la_temp_pref(ts) = tcg_target_available_regs[ts->type];
2986 ts->state &= ~TS_DEAD;
2987 }
2988 }
2989
2990 /* Incorporate constraints for this operand. */
2991 switch (opc) {
2992 case INDEX_op_mov_i32:
2993 case INDEX_op_mov_i64:
2994 /* Note that these are TCG_OPF_NOT_PRESENT and do not
2995 have proper constraints. That said, special case
2996 moves to propagate preferences backward. */
2997 if (IS_DEAD_ARG(1)) {
2998 *la_temp_pref(arg_temp(op->args[0]))
2999 = *la_temp_pref(arg_temp(op->args[1]));
3000 }
3001 break;
3002
3003 default:
3004 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
3005 const TCGArgConstraint *ct = &def->args_ct[i];
3006 TCGRegSet set, *pset;
3007
3008 ts = arg_temp(op->args[i]);
3009 pset = la_temp_pref(ts);
3010 set = *pset;
3011
9be0d080 3012 set &= ct->regs;
bc2b17e6 3013 if (ct->ialias) {
31fd884b 3014 set &= output_pref(op, ct->alias_index);
25f49c5f
RH
3015 }
3016 /* If the combination is not possible, restart. */
3017 if (set == 0) {
9be0d080 3018 set = ct->regs;
25f49c5f
RH
3019 }
3020 *pset = set;
3021 }
3022 break;
152c35aa 3023 }
c896fe29
FB
3024 break;
3025 }
bee158cb 3026 op->life = arg_life;
1ff0a2c5 3027 }
c896fe29 3028}
c896fe29 3029
5a18407f 3030/* Liveness analysis: Convert indirect regs to direct temporaries. */
b83eabea 3031static bool liveness_pass_2(TCGContext *s)
5a18407f
RH
3032{
3033 int nb_globals = s->nb_globals;
15fa08f8 3034 int nb_temps, i;
5a18407f 3035 bool changes = false;
15fa08f8 3036 TCGOp *op, *op_next;
5a18407f 3037
5a18407f
RH
3038 /* Create a temporary for each indirect global. */
3039 for (i = 0; i < nb_globals; ++i) {
3040 TCGTemp *its = &s->temps[i];
3041 if (its->indirect_reg) {
3042 TCGTemp *dts = tcg_temp_alloc(s);
3043 dts->type = its->type;
3044 dts->base_type = its->base_type;
c7482438 3045 dts->kind = TEMP_EBB;
b83eabea
RH
3046 its->state_ptr = dts;
3047 } else {
3048 its->state_ptr = NULL;
5a18407f 3049 }
b83eabea
RH
3050 /* All globals begin dead. */
3051 its->state = TS_DEAD;
3052 }
3053 for (nb_temps = s->nb_temps; i < nb_temps; ++i) {
3054 TCGTemp *its = &s->temps[i];
3055 its->state_ptr = NULL;
3056 its->state = TS_DEAD;
5a18407f 3057 }
5a18407f 3058
15fa08f8 3059 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
5a18407f
RH
3060 TCGOpcode opc = op->opc;
3061 const TCGOpDef *def = &tcg_op_defs[opc];
3062 TCGLifeData arg_life = op->life;
3063 int nb_iargs, nb_oargs, call_flags;
b83eabea 3064 TCGTemp *arg_ts, *dir_ts;
5a18407f 3065
5a18407f 3066 if (opc == INDEX_op_call) {
cd9090aa
RH
3067 nb_oargs = TCGOP_CALLO(op);
3068 nb_iargs = TCGOP_CALLI(op);
90163900 3069 call_flags = tcg_call_flags(op);
5a18407f
RH
3070 } else {
3071 nb_iargs = def->nb_iargs;
3072 nb_oargs = def->nb_oargs;
3073
3074 /* Set flags similar to how calls require. */
b4cb76e6
RH
3075 if (def->flags & TCG_OPF_COND_BRANCH) {
3076 /* Like reading globals: sync_globals */
3077 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
3078 } else if (def->flags & TCG_OPF_BB_END) {
5a18407f
RH
3079 /* Like writing globals: save_globals */
3080 call_flags = 0;
3081 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
3082 /* Like reading globals: sync_globals */
3083 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
3084 } else {
3085 /* No effect on globals. */
3086 call_flags = (TCG_CALL_NO_READ_GLOBALS |
3087 TCG_CALL_NO_WRITE_GLOBALS);
3088 }
3089 }
3090
3091 /* Make sure that input arguments are available. */
3092 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
b83eabea 3093 arg_ts = arg_temp(op->args[i]);
39004a71
RH
3094 dir_ts = arg_ts->state_ptr;
3095 if (dir_ts && arg_ts->state == TS_DEAD) {
3096 TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32
3097 ? INDEX_op_ld_i32
3098 : INDEX_op_ld_i64);
3099 TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
3100
3101 lop->args[0] = temp_arg(dir_ts);
3102 lop->args[1] = temp_arg(arg_ts->mem_base);
3103 lop->args[2] = arg_ts->mem_offset;
3104
3105 /* Loaded, but synced with memory. */
3106 arg_ts->state = TS_MEM;
5a18407f
RH
3107 }
3108 }
3109
3110 /* Perform input replacement, and mark inputs that became dead.
3111 No action is required except keeping temp_state up to date
3112 so that we reload when needed. */
3113 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
b83eabea 3114 arg_ts = arg_temp(op->args[i]);
39004a71
RH
3115 dir_ts = arg_ts->state_ptr;
3116 if (dir_ts) {
3117 op->args[i] = temp_arg(dir_ts);
3118 changes = true;
3119 if (IS_DEAD_ARG(i)) {
3120 arg_ts->state = TS_DEAD;
5a18407f
RH
3121 }
3122 }
3123 }
3124
3125 /* Liveness analysis should ensure that the following are
3126 all correct, for call sites and basic block end points. */
3127 if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
3128 /* Nothing to do */
3129 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
3130 for (i = 0; i < nb_globals; ++i) {
3131 /* Liveness should see that globals are synced back,
3132 that is, either TS_DEAD or TS_MEM. */
b83eabea
RH
3133 arg_ts = &s->temps[i];
3134 tcg_debug_assert(arg_ts->state_ptr == 0
3135 || arg_ts->state != 0);
5a18407f
RH
3136 }
3137 } else {
3138 for (i = 0; i < nb_globals; ++i) {
3139 /* Liveness should see that globals are saved back,
3140 that is, TS_DEAD, waiting to be reloaded. */
b83eabea
RH
3141 arg_ts = &s->temps[i];
3142 tcg_debug_assert(arg_ts->state_ptr == 0
3143 || arg_ts->state == TS_DEAD);
5a18407f
RH
3144 }
3145 }
3146
3147 /* Outputs become available. */
61f15c48
RH
3148 if (opc == INDEX_op_mov_i32 || opc == INDEX_op_mov_i64) {
3149 arg_ts = arg_temp(op->args[0]);
b83eabea 3150 dir_ts = arg_ts->state_ptr;
61f15c48
RH
3151 if (dir_ts) {
3152 op->args[0] = temp_arg(dir_ts);
3153 changes = true;
3154
3155 /* The output is now live and modified. */
3156 arg_ts->state = 0;
3157
3158 if (NEED_SYNC_ARG(0)) {
3159 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
3160 ? INDEX_op_st_i32
3161 : INDEX_op_st_i64);
d4478943 3162 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
61f15c48
RH
3163 TCGTemp *out_ts = dir_ts;
3164
3165 if (IS_DEAD_ARG(0)) {
3166 out_ts = arg_temp(op->args[1]);
3167 arg_ts->state = TS_DEAD;
3168 tcg_op_remove(s, op);
3169 } else {
3170 arg_ts->state = TS_MEM;
3171 }
3172
3173 sop->args[0] = temp_arg(out_ts);
3174 sop->args[1] = temp_arg(arg_ts->mem_base);
3175 sop->args[2] = arg_ts->mem_offset;
3176 } else {
3177 tcg_debug_assert(!IS_DEAD_ARG(0));
3178 }
5a18407f 3179 }
61f15c48
RH
3180 } else {
3181 for (i = 0; i < nb_oargs; i++) {
3182 arg_ts = arg_temp(op->args[i]);
3183 dir_ts = arg_ts->state_ptr;
3184 if (!dir_ts) {
3185 continue;
3186 }
3187 op->args[i] = temp_arg(dir_ts);
3188 changes = true;
5a18407f 3189
61f15c48
RH
3190 /* The output is now live and modified. */
3191 arg_ts->state = 0;
5a18407f 3192
61f15c48
RH
3193 /* Sync outputs upon their last write. */
3194 if (NEED_SYNC_ARG(i)) {
3195 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
3196 ? INDEX_op_st_i32
3197 : INDEX_op_st_i64);
d4478943 3198 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
5a18407f 3199
61f15c48
RH
3200 sop->args[0] = temp_arg(dir_ts);
3201 sop->args[1] = temp_arg(arg_ts->mem_base);
3202 sop->args[2] = arg_ts->mem_offset;
5a18407f 3203
61f15c48
RH
3204 arg_ts->state = TS_MEM;
3205 }
3206 /* Drop outputs that are dead. */
3207 if (IS_DEAD_ARG(i)) {
3208 arg_ts->state = TS_DEAD;
3209 }
5a18407f
RH
3210 }
3211 }
3212 }
3213
3214 return changes;
3215}
3216
2272e4a7 3217static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
c896fe29 3218{
31c96417
RH
3219 int size = tcg_type_size(ts->type);
3220 int align;
3221 intptr_t off;
c1c09194
RH
3222
3223 switch (ts->type) {
3224 case TCG_TYPE_I32:
31c96417 3225 align = 4;
c1c09194
RH
3226 break;
3227 case TCG_TYPE_I64:
3228 case TCG_TYPE_V64:
31c96417 3229 align = 8;
c1c09194
RH
3230 break;
3231 case TCG_TYPE_V128:
c1c09194
RH
3232 case TCG_TYPE_V256:
3233 /* Note that we do not require aligned storage for V256. */
31c96417 3234 align = 16;
c1c09194
RH
3235 break;
3236 default:
3237 g_assert_not_reached();
b591dc59 3238 }
c1c09194 3239
b9537d59
RH
3240 /*
3241 * Assume the stack is sufficiently aligned.
3242 * This affects e.g. ARM NEON, where we have 8 byte stack alignment
3243 * and do not require 16 byte vector alignment. This seems slightly
3244 * easier than fully parameterizing the above switch statement.
3245 */
3246 align = MIN(TCG_TARGET_STACK_ALIGN, align);
c1c09194 3247 off = ROUND_UP(s->current_frame_offset, align);
732d5897
RH
3248
3249 /* If we've exhausted the stack frame, restart with a smaller TB. */
3250 if (off + size > s->frame_end) {
3251 tcg_raise_tb_overflow(s);
3252 }
c1c09194
RH
3253 s->current_frame_offset = off + size;
3254
3255 ts->mem_offset = off;
9defd1bd
RH
3256#if defined(__sparc__)
3257 ts->mem_offset += TCG_TARGET_STACK_BIAS;
3258#endif
b3a62939 3259 ts->mem_base = s->frame_temp;
c896fe29 3260 ts->mem_allocated = 1;
c896fe29
FB
3261}
3262
098859f1
RH
3263/* Assign @reg to @ts, and update reg_to_temp[]. */
3264static void set_temp_val_reg(TCGContext *s, TCGTemp *ts, TCGReg reg)
3265{
3266 if (ts->val_type == TEMP_VAL_REG) {
3267 TCGReg old = ts->reg;
3268 tcg_debug_assert(s->reg_to_temp[old] == ts);
3269 if (old == reg) {
3270 return;
3271 }
3272 s->reg_to_temp[old] = NULL;
3273 }
3274 tcg_debug_assert(s->reg_to_temp[reg] == NULL);
3275 s->reg_to_temp[reg] = ts;
3276 ts->val_type = TEMP_VAL_REG;
3277 ts->reg = reg;
3278}
3279
3280/* Assign a non-register value type to @ts, and update reg_to_temp[]. */
3281static void set_temp_val_nonreg(TCGContext *s, TCGTemp *ts, TCGTempVal type)
3282{
3283 tcg_debug_assert(type != TEMP_VAL_REG);
3284 if (ts->val_type == TEMP_VAL_REG) {
3285 TCGReg reg = ts->reg;
3286 tcg_debug_assert(s->reg_to_temp[reg] == ts);
3287 s->reg_to_temp[reg] = NULL;
3288 }
3289 ts->val_type = type;
3290}
3291
b722452a 3292static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);
b3915dbb 3293
59d7c14e
RH
3294/* Mark a temporary as free or dead. If 'free_or_dead' is negative,
3295 mark it free; otherwise mark it dead. */
3296static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
7f6ceedf 3297{
c0522136
RH
3298 TCGTempVal new_type;
3299
3300 switch (ts->kind) {
3301 case TEMP_FIXED:
59d7c14e 3302 return;
c0522136
RH
3303 case TEMP_GLOBAL:
3304 case TEMP_LOCAL:
3305 new_type = TEMP_VAL_MEM;
3306 break;
3307 case TEMP_NORMAL:
c7482438 3308 case TEMP_EBB:
c0522136
RH
3309 new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD;
3310 break;
3311 case TEMP_CONST:
3312 new_type = TEMP_VAL_CONST;
3313 break;
3314 default:
3315 g_assert_not_reached();
59d7c14e 3316 }
098859f1 3317 set_temp_val_nonreg(s, ts, new_type);
59d7c14e 3318}
7f6ceedf 3319
59d7c14e
RH
3320/* Mark a temporary as dead. */
3321static inline void temp_dead(TCGContext *s, TCGTemp *ts)
3322{
3323 temp_free_or_dead(s, ts, 1);
3324}
3325
3326/* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
3327 registers needs to be allocated to store a constant. If 'free_or_dead'
3328 is non-zero, subsequently release the temporary; if it is positive, the
3329 temp is dead; if it is negative, the temp is free. */
98b4e186
RH
3330static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
3331 TCGRegSet preferred_regs, int free_or_dead)
59d7c14e 3332{
c0522136 3333 if (!temp_readonly(ts) && !ts->mem_coherent) {
7f6ceedf 3334 if (!ts->mem_allocated) {
2272e4a7 3335 temp_allocate_frame(s, ts);
59d7c14e 3336 }
59d7c14e
RH
3337 switch (ts->val_type) {
3338 case TEMP_VAL_CONST:
3339 /* If we're going to free the temp immediately, then we won't
3340 require it later in a register, so attempt to store the
3341 constant to memory directly. */
3342 if (free_or_dead
3343 && tcg_out_sti(s, ts->type, ts->val,
3344 ts->mem_base->reg, ts->mem_offset)) {
3345 break;
3346 }
3347 temp_load(s, ts, tcg_target_available_regs[ts->type],
98b4e186 3348 allocated_regs, preferred_regs);
59d7c14e
RH
3349 /* fallthrough */
3350
3351 case TEMP_VAL_REG:
3352 tcg_out_st(s, ts->type, ts->reg,
3353 ts->mem_base->reg, ts->mem_offset);
3354 break;
3355
3356 case TEMP_VAL_MEM:
3357 break;
3358
3359 case TEMP_VAL_DEAD:
3360 default:
3361 tcg_abort();
3362 }
3363 ts->mem_coherent = 1;
3364 }
3365 if (free_or_dead) {
3366 temp_free_or_dead(s, ts, free_or_dead);
7f6ceedf 3367 }
7f6ceedf
AJ
3368}
3369
c896fe29 3370/* free register 'reg' by spilling the corresponding temporary if necessary */
b3915dbb 3371static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
c896fe29 3372{
f8b2f202 3373 TCGTemp *ts = s->reg_to_temp[reg];
f8b2f202 3374 if (ts != NULL) {
98b4e186 3375 temp_sync(s, ts, allocated_regs, 0, -1);
c896fe29
FB
3376 }
3377}
3378
b016486e
RH
3379/**
3380 * tcg_reg_alloc:
3381 * @required_regs: Set of registers in which we must allocate.
3382 * @allocated_regs: Set of registers which must be avoided.
3383 * @preferred_regs: Set of registers we should prefer.
3384 * @rev: True if we search the registers in "indirect" order.
3385 *
3386 * The allocated register must be in @required_regs & ~@allocated_regs,
3387 * but if we can put it in @preferred_regs we may save a move later.
3388 */
3389static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
3390 TCGRegSet allocated_regs,
3391 TCGRegSet preferred_regs, bool rev)
c896fe29 3392{
b016486e
RH
3393 int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
3394 TCGRegSet reg_ct[2];
91478cef 3395 const int *order;
c896fe29 3396
b016486e
RH
3397 reg_ct[1] = required_regs & ~allocated_regs;
3398 tcg_debug_assert(reg_ct[1] != 0);
3399 reg_ct[0] = reg_ct[1] & preferred_regs;
3400
3401 /* Skip the preferred_regs option if it cannot be satisfied,
3402 or if the preference made no difference. */
3403 f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
3404
91478cef 3405 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
c896fe29 3406
b016486e
RH
3407 /* Try free registers, preferences first. */
3408 for (j = f; j < 2; j++) {
3409 TCGRegSet set = reg_ct[j];
3410
3411 if (tcg_regset_single(set)) {
3412 /* One register in the set. */
3413 TCGReg reg = tcg_regset_first(set);
3414 if (s->reg_to_temp[reg] == NULL) {
3415 return reg;
3416 }
3417 } else {
3418 for (i = 0; i < n; i++) {
3419 TCGReg reg = order[i];
3420 if (s->reg_to_temp[reg] == NULL &&
3421 tcg_regset_test_reg(set, reg)) {
3422 return reg;
3423 }
3424 }
3425 }
c896fe29
FB
3426 }
3427
b016486e
RH
3428 /* We must spill something. */
3429 for (j = f; j < 2; j++) {
3430 TCGRegSet set = reg_ct[j];
3431
3432 if (tcg_regset_single(set)) {
3433 /* One register in the set. */
3434 TCGReg reg = tcg_regset_first(set);
b3915dbb 3435 tcg_reg_free(s, reg, allocated_regs);
c896fe29 3436 return reg;
b016486e
RH
3437 } else {
3438 for (i = 0; i < n; i++) {
3439 TCGReg reg = order[i];
3440 if (tcg_regset_test_reg(set, reg)) {
3441 tcg_reg_free(s, reg, allocated_regs);
3442 return reg;
3443 }
3444 }
c896fe29
FB
3445 }
3446 }
3447
3448 tcg_abort();
3449}
3450
29f5e925
RH
3451static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs,
3452 TCGRegSet allocated_regs,
3453 TCGRegSet preferred_regs, bool rev)
3454{
3455 int i, j, k, fmin, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
3456 TCGRegSet reg_ct[2];
3457 const int *order;
3458
3459 /* Ensure that if I is not in allocated_regs, I+1 is not either. */
3460 reg_ct[1] = required_regs & ~(allocated_regs | (allocated_regs >> 1));
3461 tcg_debug_assert(reg_ct[1] != 0);
3462 reg_ct[0] = reg_ct[1] & preferred_regs;
3463
3464 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
3465
3466 /*
3467 * Skip the preferred_regs option if it cannot be satisfied,
3468 * or if the preference made no difference.
3469 */
3470 k = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
3471
3472 /*
3473 * Minimize the number of flushes by looking for 2 free registers first,
3474 * then a single flush, then two flushes.
3475 */
3476 for (fmin = 2; fmin >= 0; fmin--) {
3477 for (j = k; j < 2; j++) {
3478 TCGRegSet set = reg_ct[j];
3479
3480 for (i = 0; i < n; i++) {
3481 TCGReg reg = order[i];
3482
3483 if (tcg_regset_test_reg(set, reg)) {
3484 int f = !s->reg_to_temp[reg] + !s->reg_to_temp[reg + 1];
3485 if (f >= fmin) {
3486 tcg_reg_free(s, reg, allocated_regs);
3487 tcg_reg_free(s, reg + 1, allocated_regs);
3488 return reg;
3489 }
3490 }
3491 }
3492 }
3493 }
3494 tcg_abort();
3495}
3496
40ae5c62
RH
3497/* Make sure the temporary is in a register. If needed, allocate the register
3498 from DESIRED while avoiding ALLOCATED. */
3499static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
b722452a 3500 TCGRegSet allocated_regs, TCGRegSet preferred_regs)
40ae5c62
RH
3501{
3502 TCGReg reg;
3503
3504 switch (ts->val_type) {
3505 case TEMP_VAL_REG:
3506 return;
3507 case TEMP_VAL_CONST:
b016486e 3508 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
b722452a 3509 preferred_regs, ts->indirect_base);
0a6a8bc8
RH
3510 if (ts->type <= TCG_TYPE_I64) {
3511 tcg_out_movi(s, ts->type, reg, ts->val);
3512 } else {
4e186175
RH
3513 uint64_t val = ts->val;
3514 MemOp vece = MO_64;
3515
3516 /*
3517 * Find the minimal vector element that matches the constant.
3518 * The targets will, in general, have to do this search anyway,
3519 * do this generically.
3520 */
4e186175
RH
3521 if (val == dup_const(MO_8, val)) {
3522 vece = MO_8;
3523 } else if (val == dup_const(MO_16, val)) {
3524 vece = MO_16;
0b4286dd 3525 } else if (val == dup_const(MO_32, val)) {
4e186175
RH
3526 vece = MO_32;
3527 }
3528
3529 tcg_out_dupi_vec(s, ts->type, vece, reg, ts->val);
0a6a8bc8 3530 }
40ae5c62
RH
3531 ts->mem_coherent = 0;
3532 break;
3533 case TEMP_VAL_MEM:
b016486e 3534 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
b722452a 3535 preferred_regs, ts->indirect_base);
40ae5c62
RH
3536 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
3537 ts->mem_coherent = 1;
3538 break;
3539 case TEMP_VAL_DEAD:
3540 default:
3541 tcg_abort();
3542 }
098859f1 3543 set_temp_val_reg(s, ts, reg);
40ae5c62
RH
3544}
3545
59d7c14e
RH
3546/* Save a temporary to memory. 'allocated_regs' is used in case a
3547 temporary registers needs to be allocated to store a constant. */
3548static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
1ad80729 3549{
5a18407f
RH
3550 /* The liveness analysis already ensures that globals are back
3551 in memory. Keep an tcg_debug_assert for safety. */
e01fa97d 3552 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || temp_readonly(ts));
1ad80729
AJ
3553}
3554
9814dd27 3555/* save globals to their canonical location and assume they can be
e8996ee0
FB
3556 modified be the following code. 'allocated_regs' is used in case a
3557 temporary registers needs to be allocated to store a constant. */
3558static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
c896fe29 3559{
ac3b8891 3560 int i, n;
c896fe29 3561
ac3b8891 3562 for (i = 0, n = s->nb_globals; i < n; i++) {
b13eb728 3563 temp_save(s, &s->temps[i], allocated_regs);
c896fe29 3564 }
e5097dc8
FB
3565}
3566
3d5c5f87
AJ
3567/* sync globals to their canonical location and assume they can be
3568 read by the following code. 'allocated_regs' is used in case a
3569 temporary registers needs to be allocated to store a constant. */
3570static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
3571{
ac3b8891 3572 int i, n;
3d5c5f87 3573
ac3b8891 3574 for (i = 0, n = s->nb_globals; i < n; i++) {
12b9b11a 3575 TCGTemp *ts = &s->temps[i];
5a18407f 3576 tcg_debug_assert(ts->val_type != TEMP_VAL_REG
ee17db83 3577 || ts->kind == TEMP_FIXED
5a18407f 3578 || ts->mem_coherent);
3d5c5f87
AJ
3579 }
3580}
3581
e5097dc8 3582/* at the end of a basic block, we assume all temporaries are dead and
e8996ee0
FB
3583 all globals are stored at their canonical location. */
3584static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
e5097dc8 3585{
e5097dc8
FB
3586 int i;
3587
b13eb728
RH
3588 for (i = s->nb_globals; i < s->nb_temps; i++) {
3589 TCGTemp *ts = &s->temps[i];
c0522136
RH
3590
3591 switch (ts->kind) {
3592 case TEMP_LOCAL:
b13eb728 3593 temp_save(s, ts, allocated_regs);
c0522136
RH
3594 break;
3595 case TEMP_NORMAL:
c7482438 3596 case TEMP_EBB:
5a18407f
RH
3597 /* The liveness analysis already ensures that temps are dead.
3598 Keep an tcg_debug_assert for safety. */
3599 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
c0522136
RH
3600 break;
3601 case TEMP_CONST:
3602 /* Similarly, we should have freed any allocated register. */
3603 tcg_debug_assert(ts->val_type == TEMP_VAL_CONST);
3604 break;
3605 default:
3606 g_assert_not_reached();
c896fe29
FB
3607 }
3608 }
e8996ee0
FB
3609
3610 save_globals(s, allocated_regs);
c896fe29
FB
3611}
3612
b4cb76e6 3613/*
c7482438
RH
3614 * At a conditional branch, we assume all temporaries are dead unless
3615 * explicitly live-across-conditional-branch; all globals and local
3616 * temps are synced to their location.
b4cb76e6
RH
3617 */
3618static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
3619{
3620 sync_globals(s, allocated_regs);
3621
3622 for (int i = s->nb_globals; i < s->nb_temps; i++) {
3623 TCGTemp *ts = &s->temps[i];
3624 /*
3625 * The liveness analysis already ensures that temps are dead.
3626 * Keep tcg_debug_asserts for safety.
3627 */
c0522136
RH
3628 switch (ts->kind) {
3629 case TEMP_LOCAL:
b4cb76e6 3630 tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
c0522136
RH
3631 break;
3632 case TEMP_NORMAL:
b4cb76e6 3633 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
c0522136 3634 break;
c7482438 3635 case TEMP_EBB:
c0522136
RH
3636 case TEMP_CONST:
3637 break;
3638 default:
3639 g_assert_not_reached();
b4cb76e6
RH
3640 }
3641 }
3642}
3643
bab1671f 3644/*
c58f4c97 3645 * Specialized code generation for INDEX_op_mov_* with a constant.
bab1671f 3646 */
0fe4fca4 3647static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
ba87719c
RH
3648 tcg_target_ulong val, TCGLifeData arg_life,
3649 TCGRegSet preferred_regs)
e8996ee0 3650{
d63e3b6e 3651 /* ENV should not be modified. */
e01fa97d 3652 tcg_debug_assert(!temp_readonly(ots));
59d7c14e
RH
3653
3654 /* The movi is not explicitly generated here. */
098859f1 3655 set_temp_val_nonreg(s, ots, TEMP_VAL_CONST);
59d7c14e
RH
3656 ots->val = val;
3657 ots->mem_coherent = 0;
3658 if (NEED_SYNC_ARG(0)) {
ba87719c 3659 temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0));
59d7c14e 3660 } else if (IS_DEAD_ARG(0)) {
f8bf00f1 3661 temp_dead(s, ots);
4c4e1ab2 3662 }
e8996ee0
FB
3663}
3664
bab1671f
RH
3665/*
3666 * Specialized code generation for INDEX_op_mov_*.
3667 */
dd186292 3668static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
c896fe29 3669{
dd186292 3670 const TCGLifeData arg_life = op->life;
69e3706d 3671 TCGRegSet allocated_regs, preferred_regs;
c896fe29 3672 TCGTemp *ts, *ots;
450445d5 3673 TCGType otype, itype;
098859f1 3674 TCGReg oreg, ireg;
c896fe29 3675
d21369f5 3676 allocated_regs = s->reserved_regs;
31fd884b 3677 preferred_regs = output_pref(op, 0);
43439139
RH
3678 ots = arg_temp(op->args[0]);
3679 ts = arg_temp(op->args[1]);
450445d5 3680
d63e3b6e 3681 /* ENV should not be modified. */
e01fa97d 3682 tcg_debug_assert(!temp_readonly(ots));
d63e3b6e 3683
450445d5
RH
3684 /* Note that otype != itype for no-op truncation. */
3685 otype = ots->type;
3686 itype = ts->type;
c29c1d7e 3687
0fe4fca4
PB
3688 if (ts->val_type == TEMP_VAL_CONST) {
3689 /* propagate constant or generate sti */
3690 tcg_target_ulong val = ts->val;
3691 if (IS_DEAD_ARG(1)) {
3692 temp_dead(s, ts);
3693 }
69e3706d 3694 tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
0fe4fca4
PB
3695 return;
3696 }
3697
3698 /* If the source value is in memory we're going to be forced
3699 to have it in a register in order to perform the copy. Copy
3700 the SOURCE value into its own register first, that way we
3701 don't have to reload SOURCE the next time it is used. */
3702 if (ts->val_type == TEMP_VAL_MEM) {
69e3706d
RH
3703 temp_load(s, ts, tcg_target_available_regs[itype],
3704 allocated_regs, preferred_regs);
c29c1d7e 3705 }
0fe4fca4 3706 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
098859f1
RH
3707 ireg = ts->reg;
3708
d63e3b6e 3709 if (IS_DEAD_ARG(0)) {
c29c1d7e
AJ
3710 /* mov to a non-saved dead register makes no sense (even with
3711 liveness analysis disabled). */
eabb7b91 3712 tcg_debug_assert(NEED_SYNC_ARG(0));
c29c1d7e 3713 if (!ots->mem_allocated) {
2272e4a7 3714 temp_allocate_frame(s, ots);
c29c1d7e 3715 }
098859f1 3716 tcg_out_st(s, otype, ireg, ots->mem_base->reg, ots->mem_offset);
c29c1d7e 3717 if (IS_DEAD_ARG(1)) {
f8bf00f1 3718 temp_dead(s, ts);
c29c1d7e 3719 }
f8bf00f1 3720 temp_dead(s, ots);
098859f1
RH
3721 return;
3722 }
3723
3724 if (IS_DEAD_ARG(1) && ts->kind != TEMP_FIXED) {
3725 /*
3726 * The mov can be suppressed. Kill input first, so that it
3727 * is unlinked from reg_to_temp, then set the output to the
3728 * reg that we saved from the input.
3729 */
3730 temp_dead(s, ts);
3731 oreg = ireg;
c29c1d7e 3732 } else {
098859f1
RH
3733 if (ots->val_type == TEMP_VAL_REG) {
3734 oreg = ots->reg;
c896fe29 3735 } else {
098859f1
RH
3736 /* Make sure to not spill the input register during allocation. */
3737 oreg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
3738 allocated_regs | ((TCGRegSet)1 << ireg),
3739 preferred_regs, ots->indirect_base);
c896fe29 3740 }
098859f1
RH
3741 if (!tcg_out_mov(s, otype, oreg, ireg)) {
3742 /*
3743 * Cross register class move not supported.
3744 * Store the source register into the destination slot
3745 * and leave the destination temp as TEMP_VAL_MEM.
3746 */
3747 assert(!temp_readonly(ots));
3748 if (!ts->mem_allocated) {
3749 temp_allocate_frame(s, ots);
3750 }
3751 tcg_out_st(s, ts->type, ireg, ots->mem_base->reg, ots->mem_offset);
3752 set_temp_val_nonreg(s, ts, TEMP_VAL_MEM);
3753 ots->mem_coherent = 1;
3754 return;
c896fe29 3755 }
ec7a869d 3756 }
098859f1
RH
3757 set_temp_val_reg(s, ots, oreg);
3758 ots->mem_coherent = 0;
3759
3760 if (NEED_SYNC_ARG(0)) {
3761 temp_sync(s, ots, allocated_regs, 0, 0);
3762 }
c896fe29
FB
3763}
3764
bab1671f
RH
3765/*
3766 * Specialized code generation for INDEX_op_dup_vec.
3767 */
3768static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
3769{
3770 const TCGLifeData arg_life = op->life;
3771 TCGRegSet dup_out_regs, dup_in_regs;
3772 TCGTemp *its, *ots;
3773 TCGType itype, vtype;
3774 unsigned vece;
31c96417 3775 int lowpart_ofs;
bab1671f
RH
3776 bool ok;
3777
3778 ots = arg_temp(op->args[0]);
3779 its = arg_temp(op->args[1]);
3780
3781 /* ENV should not be modified. */
e01fa97d 3782 tcg_debug_assert(!temp_readonly(ots));
bab1671f
RH
3783
3784 itype = its->type;
3785 vece = TCGOP_VECE(op);
3786 vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
3787
3788 if (its->val_type == TEMP_VAL_CONST) {
3789 /* Propagate constant via movi -> dupi. */
3790 tcg_target_ulong val = its->val;
3791 if (IS_DEAD_ARG(1)) {
3792 temp_dead(s, its);
3793 }
31fd884b 3794 tcg_reg_alloc_do_movi(s, ots, val, arg_life, output_pref(op, 0));
bab1671f
RH
3795 return;
3796 }
3797
9be0d080
RH
3798 dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
3799 dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs;
bab1671f
RH
3800
3801 /* Allocate the output register now. */
3802 if (ots->val_type != TEMP_VAL_REG) {
3803 TCGRegSet allocated_regs = s->reserved_regs;
098859f1 3804 TCGReg oreg;
bab1671f
RH
3805
3806 if (!IS_DEAD_ARG(1) && its->val_type == TEMP_VAL_REG) {
3807 /* Make sure to not spill the input register. */
3808 tcg_regset_set_reg(allocated_regs, its->reg);
3809 }
098859f1 3810 oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
31fd884b 3811 output_pref(op, 0), ots->indirect_base);
098859f1 3812 set_temp_val_reg(s, ots, oreg);
bab1671f
RH
3813 }
3814
3815 switch (its->val_type) {
3816 case TEMP_VAL_REG:
3817 /*
3818 * The dup constriaints must be broad, covering all possible VECE.
3819 * However, tcg_op_dup_vec() gets to see the VECE and we allow it
3820 * to fail, indicating that extra moves are required for that case.
3821 */
3822 if (tcg_regset_test_reg(dup_in_regs, its->reg)) {
3823 if (tcg_out_dup_vec(s, vtype, vece, ots->reg, its->reg)) {
3824 goto done;
3825 }
3826 /* Try again from memory or a vector input register. */
3827 }
3828 if (!its->mem_coherent) {
3829 /*
3830 * The input register is not synced, and so an extra store
3831 * would be required to use memory. Attempt an integer-vector
3832 * register move first. We do not have a TCGRegSet for this.
3833 */
3834 if (tcg_out_mov(s, itype, ots->reg, its->reg)) {
3835 break;
3836 }
3837 /* Sync the temp back to its slot and load from there. */
3838 temp_sync(s, its, s->reserved_regs, 0, 0);
3839 }
3840 /* fall through */
3841
3842 case TEMP_VAL_MEM:
31c96417
RH
3843 lowpart_ofs = 0;
3844 if (HOST_BIG_ENDIAN) {
3845 lowpart_ofs = tcg_type_size(itype) - (1 << vece);
3846 }
d6ecb4a9 3847 if (tcg_out_dupm_vec(s, vtype, vece, ots->reg, its->mem_base->reg,
31c96417 3848 its->mem_offset + lowpart_ofs)) {
d6ecb4a9
RH
3849 goto done;
3850 }
098859f1 3851 /* Load the input into the destination vector register. */
bab1671f
RH
3852 tcg_out_ld(s, itype, ots->reg, its->mem_base->reg, its->mem_offset);
3853 break;
3854
3855 default:
3856 g_assert_not_reached();
3857 }
3858
3859 /* We now have a vector input register, so dup must succeed. */
3860 ok = tcg_out_dup_vec(s, vtype, vece, ots->reg, ots->reg);
3861 tcg_debug_assert(ok);
3862
3863 done:
36f5539c 3864 ots->mem_coherent = 0;
bab1671f
RH
3865 if (IS_DEAD_ARG(1)) {
3866 temp_dead(s, its);
3867 }
3868 if (NEED_SYNC_ARG(0)) {
3869 temp_sync(s, ots, s->reserved_regs, 0, 0);
3870 }
3871 if (IS_DEAD_ARG(0)) {
3872 temp_dead(s, ots);
3873 }
3874}
3875
dd186292 3876static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
c896fe29 3877{
dd186292
RH
3878 const TCGLifeData arg_life = op->life;
3879 const TCGOpDef * const def = &tcg_op_defs[op->opc];
82790a87
RH
3880 TCGRegSet i_allocated_regs;
3881 TCGRegSet o_allocated_regs;
b6638662
RH
3882 int i, k, nb_iargs, nb_oargs;
3883 TCGReg reg;
c896fe29
FB
3884 TCGArg arg;
3885 const TCGArgConstraint *arg_ct;
3886 TCGTemp *ts;
3887 TCGArg new_args[TCG_MAX_OP_ARGS];
3888 int const_args[TCG_MAX_OP_ARGS];
3889
3890 nb_oargs = def->nb_oargs;
3891 nb_iargs = def->nb_iargs;
3892
3893 /* copy constants */
a813e36f 3894 memcpy(new_args + nb_oargs + nb_iargs,
dd186292 3895 op->args + nb_oargs + nb_iargs,
c896fe29
FB
3896 sizeof(TCGArg) * def->nb_cargs);
3897
d21369f5
RH
3898 i_allocated_regs = s->reserved_regs;
3899 o_allocated_regs = s->reserved_regs;
82790a87 3900
a813e36f 3901 /* satisfy input constraints */
dd186292 3902 for (k = 0; k < nb_iargs; k++) {
29f5e925
RH
3903 TCGRegSet i_preferred_regs, i_required_regs;
3904 bool allocate_new_reg, copyto_new_reg;
3905 TCGTemp *ts2;
3906 int i1, i2;
d62816f2 3907
66792f90 3908 i = def->args_ct[nb_oargs + k].sort_index;
dd186292 3909 arg = op->args[i];
c896fe29 3910 arg_ct = &def->args_ct[i];
43439139 3911 ts = arg_temp(arg);
40ae5c62
RH
3912
3913 if (ts->val_type == TEMP_VAL_CONST
a4fbbd77 3914 && tcg_target_const_match(ts->val, ts->type, arg_ct->ct)) {
40ae5c62
RH
3915 /* constant is OK for instruction */
3916 const_args[i] = 1;
3917 new_args[i] = ts->val;
d62816f2 3918 continue;
c896fe29 3919 }
40ae5c62 3920
1c1824dc
RH
3921 reg = ts->reg;
3922 i_preferred_regs = 0;
29f5e925 3923 i_required_regs = arg_ct->regs;
1c1824dc 3924 allocate_new_reg = false;
29f5e925
RH
3925 copyto_new_reg = false;
3926
3927 switch (arg_ct->pair) {
3928 case 0: /* not paired */
3929 if (arg_ct->ialias) {
31fd884b 3930 i_preferred_regs = output_pref(op, arg_ct->alias_index);
29f5e925
RH
3931
3932 /*
3933 * If the input is readonly, then it cannot also be an
3934 * output and aliased to itself. If the input is not
3935 * dead after the instruction, we must allocate a new
3936 * register and move it.
3937 */
3938 if (temp_readonly(ts) || !IS_DEAD_ARG(i)) {
3939 allocate_new_reg = true;
3940 } else if (ts->val_type == TEMP_VAL_REG) {
3941 /*
3942 * Check if the current register has already been
3943 * allocated for another input.
3944 */
3945 allocate_new_reg =
3946 tcg_regset_test_reg(i_allocated_regs, reg);
3947 }
3948 }
3949 if (!allocate_new_reg) {
3950 temp_load(s, ts, i_required_regs, i_allocated_regs,
3951 i_preferred_regs);
3952 reg = ts->reg;
3953 allocate_new_reg = !tcg_regset_test_reg(i_required_regs, reg);
3954 }
3955 if (allocate_new_reg) {
3956 /*
3957 * Allocate a new register matching the constraint
3958 * and move the temporary register into it.
3959 */
3960 temp_load(s, ts, tcg_target_available_regs[ts->type],
3961 i_allocated_regs, 0);
3962 reg = tcg_reg_alloc(s, i_required_regs, i_allocated_regs,
3963 i_preferred_regs, ts->indirect_base);
3964 copyto_new_reg = true;
3965 }
3966 break;
3967
3968 case 1:
3969 /* First of an input pair; if i1 == i2, the second is an output. */
3970 i1 = i;
3971 i2 = arg_ct->pair_index;
3972 ts2 = i1 != i2 ? arg_temp(op->args[i2]) : NULL;
3973
3974 /*
3975 * It is easier to default to allocating a new pair
3976 * and to identify a few cases where it's not required.
3977 */
3978 if (arg_ct->ialias) {
31fd884b 3979 i_preferred_regs = output_pref(op, arg_ct->alias_index);
29f5e925
RH
3980 if (IS_DEAD_ARG(i1) &&
3981 IS_DEAD_ARG(i2) &&
3982 !temp_readonly(ts) &&
3983 ts->val_type == TEMP_VAL_REG &&
3984 ts->reg < TCG_TARGET_NB_REGS - 1 &&
3985 tcg_regset_test_reg(i_required_regs, reg) &&
3986 !tcg_regset_test_reg(i_allocated_regs, reg) &&
3987 !tcg_regset_test_reg(i_allocated_regs, reg + 1) &&
3988 (ts2
3989 ? ts2->val_type == TEMP_VAL_REG &&
3990 ts2->reg == reg + 1 &&
3991 !temp_readonly(ts2)
3992 : s->reg_to_temp[reg + 1] == NULL)) {
3993 break;
3994 }
3995 } else {
3996 /* Without aliasing, the pair must also be an input. */
3997 tcg_debug_assert(ts2);
3998 if (ts->val_type == TEMP_VAL_REG &&
3999 ts2->val_type == TEMP_VAL_REG &&
4000 ts2->reg == reg + 1 &&
4001 tcg_regset_test_reg(i_required_regs, reg)) {
4002 break;
4003 }
4004 }
4005 reg = tcg_reg_alloc_pair(s, i_required_regs, i_allocated_regs,
4006 0, ts->indirect_base);
4007 goto do_pair;
4008
4009 case 2: /* pair second */
4010 reg = new_args[arg_ct->pair_index] + 1;
4011 goto do_pair;
1c1824dc 4012
29f5e925
RH
4013 case 3: /* ialias with second output, no first input */
4014 tcg_debug_assert(arg_ct->ialias);
31fd884b 4015 i_preferred_regs = output_pref(op, arg_ct->alias_index);
d62816f2 4016
29f5e925
RH
4017 if (IS_DEAD_ARG(i) &&
4018 !temp_readonly(ts) &&
4019 ts->val_type == TEMP_VAL_REG &&
4020 reg > 0 &&
4021 s->reg_to_temp[reg - 1] == NULL &&
4022 tcg_regset_test_reg(i_required_regs, reg) &&
4023 !tcg_regset_test_reg(i_allocated_regs, reg) &&
4024 !tcg_regset_test_reg(i_allocated_regs, reg - 1)) {
4025 tcg_regset_set_reg(i_allocated_regs, reg - 1);
4026 break;
4027 }
4028 reg = tcg_reg_alloc_pair(s, i_required_regs >> 1,
4029 i_allocated_regs, 0,
4030 ts->indirect_base);
4031 tcg_regset_set_reg(i_allocated_regs, reg);
4032 reg += 1;
4033 goto do_pair;
4034
4035 do_pair:
c0522136 4036 /*
29f5e925
RH
4037 * If an aliased input is not dead after the instruction,
4038 * we must allocate a new register and move it.
c0522136 4039 */
29f5e925
RH
4040 if (arg_ct->ialias && (!IS_DEAD_ARG(i) || temp_readonly(ts))) {
4041 TCGRegSet t_allocated_regs = i_allocated_regs;
4042
1c1824dc 4043 /*
29f5e925
RH
4044 * Because of the alias, and the continued life, make sure
4045 * that the temp is somewhere *other* than the reg pair,
4046 * and we get a copy in reg.
1c1824dc 4047 */
29f5e925
RH
4048 tcg_regset_set_reg(t_allocated_regs, reg);
4049 tcg_regset_set_reg(t_allocated_regs, reg + 1);
4050 if (ts->val_type == TEMP_VAL_REG && ts->reg == reg) {
4051 /* If ts was already in reg, copy it somewhere else. */
4052 TCGReg nr;
4053 bool ok;
4054
4055 tcg_debug_assert(ts->kind != TEMP_FIXED);
4056 nr = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
4057 t_allocated_regs, 0, ts->indirect_base);
4058 ok = tcg_out_mov(s, ts->type, nr, reg);
4059 tcg_debug_assert(ok);
4060
4061 set_temp_val_reg(s, ts, nr);
4062 } else {
4063 temp_load(s, ts, tcg_target_available_regs[ts->type],
4064 t_allocated_regs, 0);
4065 copyto_new_reg = true;
4066 }
4067 } else {
4068 /* Preferably allocate to reg, otherwise copy. */
4069 i_required_regs = (TCGRegSet)1 << reg;
4070 temp_load(s, ts, i_required_regs, i_allocated_regs,
4071 i_preferred_regs);
4072 copyto_new_reg = ts->reg != reg;
5ff9d6a4 4073 }
29f5e925 4074 break;
d62816f2 4075
29f5e925
RH
4076 default:
4077 g_assert_not_reached();
1c1824dc 4078 }
d62816f2 4079
29f5e925 4080 if (copyto_new_reg) {
78113e83 4081 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
240c08d0
RH
4082 /*
4083 * Cross register class move not supported. Sync the
4084 * temp back to its slot and load from there.
4085 */
4086 temp_sync(s, ts, i_allocated_regs, 0, 0);
4087 tcg_out_ld(s, ts->type, reg,
4088 ts->mem_base->reg, ts->mem_offset);
78113e83 4089 }
c896fe29 4090 }
c896fe29
FB
4091 new_args[i] = reg;
4092 const_args[i] = 0;
82790a87 4093 tcg_regset_set_reg(i_allocated_regs, reg);
c896fe29 4094 }
a813e36f 4095
a52ad07e
AJ
4096 /* mark dead temporaries and free the associated registers */
4097 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
4098 if (IS_DEAD_ARG(i)) {
43439139 4099 temp_dead(s, arg_temp(op->args[i]));
a52ad07e
AJ
4100 }
4101 }
4102
b4cb76e6
RH
4103 if (def->flags & TCG_OPF_COND_BRANCH) {
4104 tcg_reg_alloc_cbranch(s, i_allocated_regs);
4105 } else if (def->flags & TCG_OPF_BB_END) {
82790a87 4106 tcg_reg_alloc_bb_end(s, i_allocated_regs);
e8996ee0 4107 } else {
e8996ee0 4108 if (def->flags & TCG_OPF_CALL_CLOBBER) {
a813e36f 4109 /* XXX: permit generic clobber register list ? */
c8074023
RH
4110 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
4111 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
82790a87 4112 tcg_reg_free(s, i, i_allocated_regs);
e8996ee0 4113 }
c896fe29 4114 }
3d5c5f87
AJ
4115 }
4116 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
4117 /* sync globals if the op has side effects and might trigger
4118 an exception. */
82790a87 4119 sync_globals(s, i_allocated_regs);
c896fe29 4120 }
a813e36f 4121
e8996ee0 4122 /* satisfy the output constraints */
e8996ee0 4123 for(k = 0; k < nb_oargs; k++) {
66792f90 4124 i = def->args_ct[k].sort_index;
dd186292 4125 arg = op->args[i];
e8996ee0 4126 arg_ct = &def->args_ct[i];
43439139 4127 ts = arg_temp(arg);
d63e3b6e
RH
4128
4129 /* ENV should not be modified. */
e01fa97d 4130 tcg_debug_assert(!temp_readonly(ts));
d63e3b6e 4131
29f5e925
RH
4132 switch (arg_ct->pair) {
4133 case 0: /* not paired */
4134 if (arg_ct->oalias && !const_args[arg_ct->alias_index]) {
4135 reg = new_args[arg_ct->alias_index];
4136 } else if (arg_ct->newreg) {
4137 reg = tcg_reg_alloc(s, arg_ct->regs,
4138 i_allocated_regs | o_allocated_regs,
31fd884b 4139 output_pref(op, k), ts->indirect_base);
29f5e925
RH
4140 } else {
4141 reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs,
31fd884b 4142 output_pref(op, k), ts->indirect_base);
29f5e925
RH
4143 }
4144 break;
4145
4146 case 1: /* first of pair */
4147 tcg_debug_assert(!arg_ct->newreg);
4148 if (arg_ct->oalias) {
4149 reg = new_args[arg_ct->alias_index];
4150 break;
4151 }
4152 reg = tcg_reg_alloc_pair(s, arg_ct->regs, o_allocated_regs,
31fd884b 4153 output_pref(op, k), ts->indirect_base);
29f5e925
RH
4154 break;
4155
4156 case 2: /* second of pair */
4157 tcg_debug_assert(!arg_ct->newreg);
4158 if (arg_ct->oalias) {
4159 reg = new_args[arg_ct->alias_index];
4160 } else {
4161 reg = new_args[arg_ct->pair_index] + 1;
4162 }
4163 break;
4164
4165 case 3: /* first of pair, aliasing with a second input */
4166 tcg_debug_assert(!arg_ct->newreg);
4167 reg = new_args[arg_ct->pair_index] - 1;
4168 break;
4169
4170 default:
4171 g_assert_not_reached();
c896fe29 4172 }
82790a87 4173 tcg_regset_set_reg(o_allocated_regs, reg);
098859f1 4174 set_temp_val_reg(s, ts, reg);
d63e3b6e 4175 ts->mem_coherent = 0;
e8996ee0 4176 new_args[i] = reg;
c896fe29 4177 }
c896fe29
FB
4178 }
4179
c896fe29 4180 /* emit instruction */
d2fd745f
RH
4181 if (def->flags & TCG_OPF_VECTOR) {
4182 tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
4183 new_args, const_args);
4184 } else {
4185 tcg_out_op(s, op->opc, new_args, const_args);
4186 }
4187
c896fe29
FB
4188 /* move the outputs in the correct register if needed */
4189 for(i = 0; i < nb_oargs; i++) {
43439139 4190 ts = arg_temp(op->args[i]);
d63e3b6e
RH
4191
4192 /* ENV should not be modified. */
e01fa97d 4193 tcg_debug_assert(!temp_readonly(ts));
d63e3b6e 4194
ec7a869d 4195 if (NEED_SYNC_ARG(i)) {
98b4e186 4196 temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
59d7c14e 4197 } else if (IS_DEAD_ARG(i)) {
f8bf00f1 4198 temp_dead(s, ts);
ec7a869d 4199 }
c896fe29
FB
4200 }
4201}
4202
efe86b21
RH
4203static bool tcg_reg_alloc_dup2(TCGContext *s, const TCGOp *op)
4204{
4205 const TCGLifeData arg_life = op->life;
4206 TCGTemp *ots, *itsl, *itsh;
4207 TCGType vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
4208
4209 /* This opcode is only valid for 32-bit hosts, for 64-bit elements. */
4210 tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
4211 tcg_debug_assert(TCGOP_VECE(op) == MO_64);
4212
4213 ots = arg_temp(op->args[0]);
4214 itsl = arg_temp(op->args[1]);
4215 itsh = arg_temp(op->args[2]);
4216
4217 /* ENV should not be modified. */
4218 tcg_debug_assert(!temp_readonly(ots));
4219
4220 /* Allocate the output register now. */
4221 if (ots->val_type != TEMP_VAL_REG) {
4222 TCGRegSet allocated_regs = s->reserved_regs;
4223 TCGRegSet dup_out_regs =
4224 tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
098859f1 4225 TCGReg oreg;
efe86b21
RH
4226
4227 /* Make sure to not spill the input registers. */
4228 if (!IS_DEAD_ARG(1) && itsl->val_type == TEMP_VAL_REG) {
4229 tcg_regset_set_reg(allocated_regs, itsl->reg);
4230 }
4231 if (!IS_DEAD_ARG(2) && itsh->val_type == TEMP_VAL_REG) {
4232 tcg_regset_set_reg(allocated_regs, itsh->reg);
4233 }
4234
098859f1 4235 oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
31fd884b 4236 output_pref(op, 0), ots->indirect_base);
098859f1 4237 set_temp_val_reg(s, ots, oreg);
efe86b21
RH
4238 }
4239
4240 /* Promote dup2 of immediates to dupi_vec. */
4241 if (itsl->val_type == TEMP_VAL_CONST && itsh->val_type == TEMP_VAL_CONST) {
4242 uint64_t val = deposit64(itsl->val, 32, 32, itsh->val);
4243 MemOp vece = MO_64;
4244
4245 if (val == dup_const(MO_8, val)) {
4246 vece = MO_8;
4247 } else if (val == dup_const(MO_16, val)) {
4248 vece = MO_16;
4249 } else if (val == dup_const(MO_32, val)) {
4250 vece = MO_32;
4251 }
4252
4253 tcg_out_dupi_vec(s, vtype, vece, ots->reg, val);
4254 goto done;
4255 }
4256
4257 /* If the two inputs form one 64-bit value, try dupm_vec. */
aef85402
RH
4258 if (itsl->temp_subindex == HOST_BIG_ENDIAN &&
4259 itsh->temp_subindex == !HOST_BIG_ENDIAN &&
4260 itsl == itsh + (HOST_BIG_ENDIAN ? 1 : -1)) {
4261 TCGTemp *its = itsl - HOST_BIG_ENDIAN;
4262
4263 temp_sync(s, its + 0, s->reserved_regs, 0, 0);
4264 temp_sync(s, its + 1, s->reserved_regs, 0, 0);
4265
efe86b21
RH
4266 if (tcg_out_dupm_vec(s, vtype, MO_64, ots->reg,
4267 its->mem_base->reg, its->mem_offset)) {
4268 goto done;
4269 }
4270 }
4271
4272 /* Fall back to generic expansion. */
4273 return false;
4274
4275 done:
36f5539c 4276 ots->mem_coherent = 0;
efe86b21
RH
4277 if (IS_DEAD_ARG(1)) {
4278 temp_dead(s, itsl);
4279 }
4280 if (IS_DEAD_ARG(2)) {
4281 temp_dead(s, itsh);
4282 }
4283 if (NEED_SYNC_ARG(0)) {
4284 temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
4285 } else if (IS_DEAD_ARG(0)) {
4286 temp_dead(s, ots);
4287 }
4288 return true;
4289}
4290
39004a71
RH
4291static void load_arg_reg(TCGContext *s, TCGReg reg, TCGTemp *ts,
4292 TCGRegSet allocated_regs)
c896fe29 4293{
39004a71
RH
4294 if (ts->val_type == TEMP_VAL_REG) {
4295 if (ts->reg != reg) {
4296 tcg_reg_free(s, reg, allocated_regs);
4297 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
4298 /*
4299 * Cross register class move not supported. Sync the
4300 * temp back to its slot and load from there.
4301 */
4302 temp_sync(s, ts, allocated_regs, 0, 0);
4303 tcg_out_ld(s, ts->type, reg,
4304 ts->mem_base->reg, ts->mem_offset);
4305 }
4306 }
4307 } else {
4308 TCGRegSet arg_set = 0;
c896fe29 4309
39004a71
RH
4310 tcg_reg_free(s, reg, allocated_regs);
4311 tcg_regset_set_reg(arg_set, reg);
4312 temp_load(s, ts, arg_set, allocated_regs, 0);
b03cce8e 4313 }
39004a71 4314}
39cf05d3 4315
39004a71
RH
4316static void load_arg_stk(TCGContext *s, int stk_slot, TCGTemp *ts,
4317 TCGRegSet allocated_regs)
4318{
4319 /*
4320 * When the destination is on the stack, load up the temp and store.
4321 * If there are many call-saved registers, the temp might live to
4322 * see another use; otherwise it'll be discarded.
4323 */
4324 temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs, 0);
4325 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK,
4326 TCG_TARGET_CALL_STACK_OFFSET +
4327 stk_slot * sizeof(tcg_target_long));
4328}
a813e36f 4329
39004a71
RH
4330static void load_arg_normal(TCGContext *s, const TCGCallArgumentLoc *l,
4331 TCGTemp *ts, TCGRegSet *allocated_regs)
4332{
4333 if (REG_P(l)) {
4334 TCGReg reg = tcg_target_call_iarg_regs[l->arg_slot];
4335 load_arg_reg(s, reg, ts, *allocated_regs);
4336 tcg_regset_set_reg(*allocated_regs, reg);
4337 } else {
4338 load_arg_stk(s, l->arg_slot - ARRAY_SIZE(tcg_target_call_iarg_regs),
4339 ts, *allocated_regs);
4340 }
4341}
40ae5c62 4342
39004a71
RH
4343static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
4344{
4345 const int nb_oargs = TCGOP_CALLO(op);
4346 const int nb_iargs = TCGOP_CALLI(op);
4347 const TCGLifeData arg_life = op->life;
4348 const TCGHelperInfo *info = tcg_call_info(op);
4349 TCGRegSet allocated_regs = s->reserved_regs;
4350 int i;
40ae5c62 4351
39004a71
RH
4352 /*
4353 * Move inputs into place in reverse order,
4354 * so that we place stacked arguments first.
4355 */
4356 for (i = nb_iargs - 1; i >= 0; --i) {
4357 const TCGCallArgumentLoc *loc = &info->in[i];
4358 TCGTemp *ts = arg_temp(op->args[nb_oargs + i]);
40ae5c62 4359
39004a71
RH
4360 switch (loc->kind) {
4361 case TCG_CALL_ARG_NORMAL:
4362 case TCG_CALL_ARG_EXTEND_U:
4363 case TCG_CALL_ARG_EXTEND_S:
4364 load_arg_normal(s, loc, ts, &allocated_regs);
4365 break;
4366 default:
4367 g_assert_not_reached();
c896fe29 4368 }
c896fe29 4369 }
a813e36f 4370
39004a71 4371 /* Mark dead temporaries and free the associated registers. */
dd186292 4372 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 4373 if (IS_DEAD_ARG(i)) {
43439139 4374 temp_dead(s, arg_temp(op->args[i]));
c896fe29
FB
4375 }
4376 }
a813e36f 4377
39004a71 4378 /* Clobber call registers. */
c8074023
RH
4379 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
4380 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
b3915dbb 4381 tcg_reg_free(s, i, allocated_regs);
c896fe29
FB
4382 }
4383 }
78505279 4384
39004a71
RH
4385 /*
4386 * Save globals if they might be written by the helper,
4387 * sync them if they might be read.
4388 */
4389 if (info->flags & TCG_CALL_NO_READ_GLOBALS) {
78505279 4390 /* Nothing to do */
39004a71 4391 } else if (info->flags & TCG_CALL_NO_WRITE_GLOBALS) {
78505279
AJ
4392 sync_globals(s, allocated_regs);
4393 } else {
b9c18f56
AJ
4394 save_globals(s, allocated_regs);
4395 }
c896fe29 4396
cee44b03 4397 tcg_out_call(s, tcg_call_func(op), info);
c896fe29 4398
39004a71
RH
4399 /* Assign output registers and emit moves if needed. */
4400 switch (info->out_kind) {
4401 case TCG_CALL_RET_NORMAL:
4402 for (i = 0; i < nb_oargs; i++) {
4403 TCGTemp *ts = arg_temp(op->args[i]);
4404 TCGReg reg = tcg_target_call_oarg_regs[i];
d63e3b6e 4405
39004a71
RH
4406 /* ENV should not be modified. */
4407 tcg_debug_assert(!temp_readonly(ts));
d63e3b6e 4408
39004a71
RH
4409 set_temp_val_reg(s, ts, reg);
4410 ts->mem_coherent = 0;
4411 }
4412 break;
4413 default:
4414 g_assert_not_reached();
4415 }
4416
4417 /* Flush or discard output registers as needed. */
4418 for (i = 0; i < nb_oargs; i++) {
4419 TCGTemp *ts = arg_temp(op->args[i]);
d63e3b6e 4420 if (NEED_SYNC_ARG(i)) {
39004a71 4421 temp_sync(s, ts, s->reserved_regs, 0, IS_DEAD_ARG(i));
d63e3b6e
RH
4422 } else if (IS_DEAD_ARG(i)) {
4423 temp_dead(s, ts);
c896fe29
FB
4424 }
4425 }
c896fe29
FB
4426}
4427
4428#ifdef CONFIG_PROFILER
4429
c3fac113
EC
4430/* avoid copy/paste errors */
4431#define PROF_ADD(to, from, field) \
4432 do { \
d73415a3 4433 (to)->field += qatomic_read(&((from)->field)); \
c3fac113
EC
4434 } while (0)
4435
4436#define PROF_MAX(to, from, field) \
4437 do { \
d73415a3 4438 typeof((from)->field) val__ = qatomic_read(&((from)->field)); \
c3fac113
EC
4439 if (val__ > (to)->field) { \
4440 (to)->field = val__; \
4441 } \
4442 } while (0)
4443
4444/* Pass in a zero'ed @prof */
4445static inline
4446void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
4447{
0e2d61cf 4448 unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
c3fac113
EC
4449 unsigned int i;
4450
3468b59e 4451 for (i = 0; i < n_ctxs; i++) {
d73415a3 4452 TCGContext *s = qatomic_read(&tcg_ctxs[i]);
3468b59e 4453 const TCGProfile *orig = &s->prof;
c3fac113
EC
4454
4455 if (counters) {
72fd2efb 4456 PROF_ADD(prof, orig, cpu_exec_time);
c3fac113
EC
4457 PROF_ADD(prof, orig, tb_count1);
4458 PROF_ADD(prof, orig, tb_count);
4459 PROF_ADD(prof, orig, op_count);
4460 PROF_MAX(prof, orig, op_count_max);
4461 PROF_ADD(prof, orig, temp_count);
4462 PROF_MAX(prof, orig, temp_count_max);
4463 PROF_ADD(prof, orig, del_op_count);
4464 PROF_ADD(prof, orig, code_in_len);
4465 PROF_ADD(prof, orig, code_out_len);
4466 PROF_ADD(prof, orig, search_out_len);
4467 PROF_ADD(prof, orig, interm_time);
4468 PROF_ADD(prof, orig, code_time);
4469 PROF_ADD(prof, orig, la_time);
4470 PROF_ADD(prof, orig, opt_time);
4471 PROF_ADD(prof, orig, restore_count);
4472 PROF_ADD(prof, orig, restore_time);
4473 }
4474 if (table) {
4475 int i;
4476
4477 for (i = 0; i < NB_OPS; i++) {
4478 PROF_ADD(prof, orig, table_op_count[i]);
4479 }
4480 }
4481 }
4482}
4483
4484#undef PROF_ADD
4485#undef PROF_MAX
4486
4487static void tcg_profile_snapshot_counters(TCGProfile *prof)
4488{
4489 tcg_profile_snapshot(prof, true, false);
4490}
4491
4492static void tcg_profile_snapshot_table(TCGProfile *prof)
4493{
4494 tcg_profile_snapshot(prof, false, true);
4495}
c896fe29 4496
b6a7f3e0 4497void tcg_dump_op_count(GString *buf)
c896fe29 4498{
c3fac113 4499 TCGProfile prof = {};
c896fe29 4500 int i;
d70724ce 4501
c3fac113 4502 tcg_profile_snapshot_table(&prof);
15fc7daa 4503 for (i = 0; i < NB_OPS; i++) {
b6a7f3e0
DB
4504 g_string_append_printf(buf, "%s %" PRId64 "\n", tcg_op_defs[i].name,
4505 prof.table_op_count[i]);
c896fe29 4506 }
c896fe29 4507}
72fd2efb
EC
4508
4509int64_t tcg_cpu_exec_time(void)
4510{
0e2d61cf 4511 unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
72fd2efb
EC
4512 unsigned int i;
4513 int64_t ret = 0;
4514
4515 for (i = 0; i < n_ctxs; i++) {
d73415a3 4516 const TCGContext *s = qatomic_read(&tcg_ctxs[i]);
72fd2efb
EC
4517 const TCGProfile *prof = &s->prof;
4518
d73415a3 4519 ret += qatomic_read(&prof->cpu_exec_time);
72fd2efb
EC
4520 }
4521 return ret;
4522}
246ae24d 4523#else
b6a7f3e0 4524void tcg_dump_op_count(GString *buf)
246ae24d 4525{
b6a7f3e0 4526 g_string_append_printf(buf, "[TCG profiler not compiled]\n");
246ae24d 4527}
72fd2efb
EC
4528
4529int64_t tcg_cpu_exec_time(void)
4530{
4531 error_report("%s: TCG profiler not compiled", __func__);
4532 exit(EXIT_FAILURE);
4533}
c896fe29
FB
4534#endif
4535
4536
fbf59aad 4537int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start)
c896fe29 4538{
c3fac113
EC
4539#ifdef CONFIG_PROFILER
4540 TCGProfile *prof = &s->prof;
4541#endif
15fa08f8
RH
4542 int i, num_insns;
4543 TCGOp *op;
c896fe29 4544
04fe6400
RH
4545#ifdef CONFIG_PROFILER
4546 {
c1f543b7 4547 int n = 0;
04fe6400 4548
15fa08f8
RH
4549 QTAILQ_FOREACH(op, &s->ops, link) {
4550 n++;
4551 }
d73415a3 4552 qatomic_set(&prof->op_count, prof->op_count + n);
c3fac113 4553 if (n > prof->op_count_max) {
d73415a3 4554 qatomic_set(&prof->op_count_max, n);
04fe6400
RH
4555 }
4556
4557 n = s->nb_temps;
d73415a3 4558 qatomic_set(&prof->temp_count, prof->temp_count + n);
c3fac113 4559 if (n > prof->temp_count_max) {
d73415a3 4560 qatomic_set(&prof->temp_count_max, n);
04fe6400
RH
4561 }
4562 }
4563#endif
4564
c896fe29 4565#ifdef DEBUG_DISAS
d977e1c2 4566 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
fbf59aad 4567 && qemu_log_in_addr_range(pc_start))) {
c60f599b 4568 FILE *logfile = qemu_log_trylock();
78b54858
RH
4569 if (logfile) {
4570 fprintf(logfile, "OP:\n");
b7a83ff8 4571 tcg_dump_ops(s, logfile, false);
78b54858
RH
4572 fprintf(logfile, "\n");
4573 qemu_log_unlock(logfile);
4574 }
c896fe29
FB
4575 }
4576#endif
4577
bef16ab4
RH
4578#ifdef CONFIG_DEBUG_TCG
4579 /* Ensure all labels referenced have been emitted. */
4580 {
4581 TCGLabel *l;
4582 bool error = false;
4583
4584 QSIMPLEQ_FOREACH(l, &s->labels, next) {
4585 if (unlikely(!l->present) && l->refs) {
4586 qemu_log_mask(CPU_LOG_TB_OP,
4587 "$L%d referenced but not present.\n", l->id);
4588 error = true;
4589 }
4590 }
4591 assert(!error);
4592 }
4593#endif
4594
c5cc28ff 4595#ifdef CONFIG_PROFILER
d73415a3 4596 qatomic_set(&prof->opt_time, prof->opt_time - profile_getclock());
c5cc28ff
AJ
4597#endif
4598
8f2e8c07 4599#ifdef USE_TCG_OPTIMIZATIONS
c45cb8bb 4600 tcg_optimize(s);
8f2e8c07
KB
4601#endif
4602
a23a9ec6 4603#ifdef CONFIG_PROFILER
d73415a3
SH
4604 qatomic_set(&prof->opt_time, prof->opt_time + profile_getclock());
4605 qatomic_set(&prof->la_time, prof->la_time - profile_getclock());
a23a9ec6 4606#endif
c5cc28ff 4607
b4fc67c7 4608 reachable_code_pass(s);
b83eabea 4609 liveness_pass_1(s);
5a18407f 4610
b83eabea 4611 if (s->nb_indirects > 0) {
5a18407f 4612#ifdef DEBUG_DISAS
b83eabea 4613 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
fbf59aad 4614 && qemu_log_in_addr_range(pc_start))) {
c60f599b 4615 FILE *logfile = qemu_log_trylock();
78b54858
RH
4616 if (logfile) {
4617 fprintf(logfile, "OP before indirect lowering:\n");
b7a83ff8 4618 tcg_dump_ops(s, logfile, false);
78b54858
RH
4619 fprintf(logfile, "\n");
4620 qemu_log_unlock(logfile);
4621 }
b83eabea 4622 }
5a18407f 4623#endif
b83eabea
RH
4624 /* Replace indirect temps with direct temps. */
4625 if (liveness_pass_2(s)) {
4626 /* If changes were made, re-run liveness. */
4627 liveness_pass_1(s);
5a18407f
RH
4628 }
4629 }
c5cc28ff 4630
a23a9ec6 4631#ifdef CONFIG_PROFILER
d73415a3 4632 qatomic_set(&prof->la_time, prof->la_time + profile_getclock());
a23a9ec6 4633#endif
c896fe29
FB
4634
4635#ifdef DEBUG_DISAS
d977e1c2 4636 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
fbf59aad 4637 && qemu_log_in_addr_range(pc_start))) {
c60f599b 4638 FILE *logfile = qemu_log_trylock();
78b54858
RH
4639 if (logfile) {
4640 fprintf(logfile, "OP after optimization and liveness analysis:\n");
b7a83ff8 4641 tcg_dump_ops(s, logfile, true);
78b54858
RH
4642 fprintf(logfile, "\n");
4643 qemu_log_unlock(logfile);
4644 }
c896fe29
FB
4645 }
4646#endif
4647
35abb009
RH
4648 /* Initialize goto_tb jump offsets. */
4649 tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID;
4650 tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID;
4651 tcg_ctx->tb_jmp_reset_offset = tb->jmp_reset_offset;
4652 if (TCG_TARGET_HAS_direct_jump) {
4653 tcg_ctx->tb_jmp_insn_offset = tb->jmp_target_arg;
4654 tcg_ctx->tb_jmp_target_addr = NULL;
4655 } else {
4656 tcg_ctx->tb_jmp_insn_offset = NULL;
4657 tcg_ctx->tb_jmp_target_addr = tb->jmp_target_arg;
4658 }
4659
c896fe29
FB
4660 tcg_reg_alloc_start(s);
4661
db0c51a3
RH
4662 /*
4663 * Reset the buffer pointers when restarting after overflow.
4664 * TODO: Move this into translate-all.c with the rest of the
4665 * buffer management. Having only this done here is confusing.
4666 */
4667 s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
4668 s->code_ptr = s->code_buf;
c896fe29 4669
659ef5cb 4670#ifdef TCG_TARGET_NEED_LDST_LABELS
6001f772 4671 QSIMPLEQ_INIT(&s->ldst_labels);
659ef5cb 4672#endif
57a26946
RH
4673#ifdef TCG_TARGET_NEED_POOL_LABELS
4674 s->pool_labels = NULL;
4675#endif
9ecefc84 4676
fca8a500 4677 num_insns = -1;
15fa08f8 4678 QTAILQ_FOREACH(op, &s->ops, link) {
c45cb8bb 4679 TCGOpcode opc = op->opc;
b3db8758 4680
c896fe29 4681#ifdef CONFIG_PROFILER
d73415a3 4682 qatomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1);
c896fe29 4683#endif
c45cb8bb
RH
4684
4685 switch (opc) {
c896fe29 4686 case INDEX_op_mov_i32:
c896fe29 4687 case INDEX_op_mov_i64:
d2fd745f 4688 case INDEX_op_mov_vec:
dd186292 4689 tcg_reg_alloc_mov(s, op);
c896fe29 4690 break;
bab1671f
RH
4691 case INDEX_op_dup_vec:
4692 tcg_reg_alloc_dup(s, op);
4693 break;
765b842a 4694 case INDEX_op_insn_start:
fca8a500 4695 if (num_insns >= 0) {
9f754620
RH
4696 size_t off = tcg_current_code_size(s);
4697 s->gen_insn_end_off[num_insns] = off;
4698 /* Assert that we do not overflow our stored offset. */
4699 assert(s->gen_insn_end_off[num_insns] == off);
fca8a500
RH
4700 }
4701 num_insns++;
bad729e2
RH
4702 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
4703 target_ulong a;
4704#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
efee3746 4705 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]);
bad729e2 4706#else
efee3746 4707 a = op->args[i];
bad729e2 4708#endif
fca8a500 4709 s->gen_insn_data[num_insns][i] = a;
bad729e2 4710 }
c896fe29 4711 break;
5ff9d6a4 4712 case INDEX_op_discard:
43439139 4713 temp_dead(s, arg_temp(op->args[0]));
5ff9d6a4 4714 break;
c896fe29 4715 case INDEX_op_set_label:
e8996ee0 4716 tcg_reg_alloc_bb_end(s, s->reserved_regs);
92ab8e7d 4717 tcg_out_label(s, arg_label(op->args[0]));
c896fe29
FB
4718 break;
4719 case INDEX_op_call:
dd186292 4720 tcg_reg_alloc_call(s, op);
c45cb8bb 4721 break;
b55a8d9d
RH
4722 case INDEX_op_exit_tb:
4723 tcg_out_exit_tb(s, op->args[0]);
4724 break;
efe86b21
RH
4725 case INDEX_op_dup2_vec:
4726 if (tcg_reg_alloc_dup2(s, op)) {
4727 break;
4728 }
4729 /* fall through */
c896fe29 4730 default:
25c4d9cc 4731 /* Sanity check that we've not introduced any unhandled opcodes. */
be0f34b5 4732 tcg_debug_assert(tcg_op_supported(opc));
c896fe29
FB
4733 /* Note: in order to speed up the code, it would be much
4734 faster to have specialized register allocator functions for
4735 some common argument patterns */
dd186292 4736 tcg_reg_alloc_op(s, op);
c896fe29
FB
4737 break;
4738 }
b125f9dc
RH
4739 /* Test for (pending) buffer overflow. The assumption is that any
4740 one operation beginning below the high water mark cannot overrun
4741 the buffer completely. Thus we can test for overflow after
4742 generating code without having to check during generation. */
644da9b3 4743 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
b125f9dc
RH
4744 return -1;
4745 }
6e6c4efe
RH
4746 /* Test for TB overflow, as seen by gen_insn_end_off. */
4747 if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) {
4748 return -2;
4749 }
c896fe29 4750 }
fca8a500
RH
4751 tcg_debug_assert(num_insns >= 0);
4752 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
c45cb8bb 4753
b76f0d8c 4754 /* Generate TB finalization at the end of block */
659ef5cb 4755#ifdef TCG_TARGET_NEED_LDST_LABELS
aeee05f5
RH
4756 i = tcg_out_ldst_finalize(s);
4757 if (i < 0) {
4758 return i;
23dceda6 4759 }
659ef5cb 4760#endif
57a26946 4761#ifdef TCG_TARGET_NEED_POOL_LABELS
1768987b
RH
4762 i = tcg_out_pool_finalize(s);
4763 if (i < 0) {
4764 return i;
57a26946
RH
4765 }
4766#endif
7ecd02a0
RH
4767 if (!tcg_resolve_relocs(s)) {
4768 return -2;
4769 }
c896fe29 4770
df5d2b16 4771#ifndef CONFIG_TCG_INTERPRETER
c896fe29 4772 /* flush instruction cache */
db0c51a3
RH
4773 flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
4774 (uintptr_t)s->code_buf,
1da8de39 4775 tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
df5d2b16 4776#endif
2aeabc08 4777
1813e175 4778 return tcg_current_code_size(s);
c896fe29
FB
4779}
4780
a23a9ec6 4781#ifdef CONFIG_PROFILER
3a841ab5 4782void tcg_dump_info(GString *buf)
a23a9ec6 4783{
c3fac113
EC
4784 TCGProfile prof = {};
4785 const TCGProfile *s;
4786 int64_t tb_count;
4787 int64_t tb_div_count;
4788 int64_t tot;
4789
4790 tcg_profile_snapshot_counters(&prof);
4791 s = &prof;
4792 tb_count = s->tb_count;
4793 tb_div_count = tb_count ? tb_count : 1;
4794 tot = s->interm_time + s->code_time;
a23a9ec6 4795
3a841ab5
DB
4796 g_string_append_printf(buf, "JIT cycles %" PRId64
4797 " (%0.3f s at 2.4 GHz)\n",
4798 tot, tot / 2.4e9);
4799 g_string_append_printf(buf, "translated TBs %" PRId64
4800 " (aborted=%" PRId64 " %0.1f%%)\n",
4801 tb_count, s->tb_count1 - tb_count,
4802 (double)(s->tb_count1 - s->tb_count)
4803 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
4804 g_string_append_printf(buf, "avg ops/TB %0.1f max=%d\n",
4805 (double)s->op_count / tb_div_count, s->op_count_max);
4806 g_string_append_printf(buf, "deleted ops/TB %0.2f\n",
4807 (double)s->del_op_count / tb_div_count);
4808 g_string_append_printf(buf, "avg temps/TB %0.2f max=%d\n",
4809 (double)s->temp_count / tb_div_count,
4810 s->temp_count_max);
4811 g_string_append_printf(buf, "avg host code/TB %0.1f\n",
4812 (double)s->code_out_len / tb_div_count);
4813 g_string_append_printf(buf, "avg search data/TB %0.1f\n",
4814 (double)s->search_out_len / tb_div_count);
a813e36f 4815
3a841ab5
DB
4816 g_string_append_printf(buf, "cycles/op %0.1f\n",
4817 s->op_count ? (double)tot / s->op_count : 0);
4818 g_string_append_printf(buf, "cycles/in byte %0.1f\n",
4819 s->code_in_len ? (double)tot / s->code_in_len : 0);
4820 g_string_append_printf(buf, "cycles/out byte %0.1f\n",
4821 s->code_out_len ? (double)tot / s->code_out_len : 0);
4822 g_string_append_printf(buf, "cycles/search byte %0.1f\n",
4823 s->search_out_len ?
4824 (double)tot / s->search_out_len : 0);
fca8a500 4825 if (tot == 0) {
a23a9ec6 4826 tot = 1;
fca8a500 4827 }
3a841ab5
DB
4828 g_string_append_printf(buf, " gen_interm time %0.1f%%\n",
4829 (double)s->interm_time / tot * 100.0);
4830 g_string_append_printf(buf, " gen_code time %0.1f%%\n",
4831 (double)s->code_time / tot * 100.0);
4832 g_string_append_printf(buf, "optim./code time %0.1f%%\n",
4833 (double)s->opt_time / (s->code_time ?
4834 s->code_time : 1)
4835 * 100.0);
4836 g_string_append_printf(buf, "liveness/code time %0.1f%%\n",
4837 (double)s->la_time / (s->code_time ?
4838 s->code_time : 1) * 100.0);
4839 g_string_append_printf(buf, "cpu_restore count %" PRId64 "\n",
4840 s->restore_count);
4841 g_string_append_printf(buf, " avg cycles %0.1f\n",
4842 s->restore_count ?
4843 (double)s->restore_time / s->restore_count : 0);
a23a9ec6
FB
4844}
4845#else
3a841ab5 4846void tcg_dump_info(GString *buf)
a23a9ec6 4847{
3a841ab5 4848 g_string_append_printf(buf, "[TCG profiler not compiled]\n");
a23a9ec6
FB
4849}
4850#endif
813da627
RH
4851
4852#ifdef ELF_HOST_MACHINE
5872bbf2
RH
4853/* In order to use this feature, the backend needs to do three things:
4854
4855 (1) Define ELF_HOST_MACHINE to indicate both what value to
4856 put into the ELF image and to indicate support for the feature.
4857
4858 (2) Define tcg_register_jit. This should create a buffer containing
4859 the contents of a .debug_frame section that describes the post-
4860 prologue unwind info for the tcg machine.
4861
4862 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
4863*/
813da627
RH
4864
4865/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
4866typedef enum {
4867 JIT_NOACTION = 0,
4868 JIT_REGISTER_FN,
4869 JIT_UNREGISTER_FN
4870} jit_actions_t;
4871
4872struct jit_code_entry {
4873 struct jit_code_entry *next_entry;
4874 struct jit_code_entry *prev_entry;
4875 const void *symfile_addr;
4876 uint64_t symfile_size;
4877};
4878
4879struct jit_descriptor {
4880 uint32_t version;
4881 uint32_t action_flag;
4882 struct jit_code_entry *relevant_entry;
4883 struct jit_code_entry *first_entry;
4884};
4885
4886void __jit_debug_register_code(void) __attribute__((noinline));
4887void __jit_debug_register_code(void)
4888{
4889 asm("");
4890}
4891
4892/* Must statically initialize the version, because GDB may check
4893 the version before we can set it. */
4894struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
4895
4896/* End GDB interface. */
4897
4898static int find_string(const char *strtab, const char *str)
4899{
4900 const char *p = strtab + 1;
4901
4902 while (1) {
4903 if (strcmp(p, str) == 0) {
4904 return p - strtab;
4905 }
4906 p += strlen(p) + 1;
4907 }
4908}
4909
755bf9e5 4910static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size,
2c90784a
RH
4911 const void *debug_frame,
4912 size_t debug_frame_size)
813da627 4913{
5872bbf2
RH
4914 struct __attribute__((packed)) DebugInfo {
4915 uint32_t len;
4916 uint16_t version;
4917 uint32_t abbrev;
4918 uint8_t ptr_size;
4919 uint8_t cu_die;
4920 uint16_t cu_lang;
4921 uintptr_t cu_low_pc;
4922 uintptr_t cu_high_pc;
4923 uint8_t fn_die;
4924 char fn_name[16];
4925 uintptr_t fn_low_pc;
4926 uintptr_t fn_high_pc;
4927 uint8_t cu_eoc;
4928 };
813da627
RH
4929
4930 struct ElfImage {
4931 ElfW(Ehdr) ehdr;
4932 ElfW(Phdr) phdr;
5872bbf2
RH
4933 ElfW(Shdr) shdr[7];
4934 ElfW(Sym) sym[2];
4935 struct DebugInfo di;
4936 uint8_t da[24];
4937 char str[80];
4938 };
4939
4940 struct ElfImage *img;
4941
4942 static const struct ElfImage img_template = {
4943 .ehdr = {
4944 .e_ident[EI_MAG0] = ELFMAG0,
4945 .e_ident[EI_MAG1] = ELFMAG1,
4946 .e_ident[EI_MAG2] = ELFMAG2,
4947 .e_ident[EI_MAG3] = ELFMAG3,
4948 .e_ident[EI_CLASS] = ELF_CLASS,
4949 .e_ident[EI_DATA] = ELF_DATA,
4950 .e_ident[EI_VERSION] = EV_CURRENT,
4951 .e_type = ET_EXEC,
4952 .e_machine = ELF_HOST_MACHINE,
4953 .e_version = EV_CURRENT,
4954 .e_phoff = offsetof(struct ElfImage, phdr),
4955 .e_shoff = offsetof(struct ElfImage, shdr),
4956 .e_ehsize = sizeof(ElfW(Shdr)),
4957 .e_phentsize = sizeof(ElfW(Phdr)),
4958 .e_phnum = 1,
4959 .e_shentsize = sizeof(ElfW(Shdr)),
4960 .e_shnum = ARRAY_SIZE(img->shdr),
4961 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
abbb3eae
RH
4962#ifdef ELF_HOST_FLAGS
4963 .e_flags = ELF_HOST_FLAGS,
4964#endif
4965#ifdef ELF_OSABI
4966 .e_ident[EI_OSABI] = ELF_OSABI,
4967#endif
5872bbf2
RH
4968 },
4969 .phdr = {
4970 .p_type = PT_LOAD,
4971 .p_flags = PF_X,
4972 },
4973 .shdr = {
4974 [0] = { .sh_type = SHT_NULL },
4975 /* Trick: The contents of code_gen_buffer are not present in
4976 this fake ELF file; that got allocated elsewhere. Therefore
4977 we mark .text as SHT_NOBITS (similar to .bss) so that readers
4978 will not look for contents. We can record any address. */
4979 [1] = { /* .text */
4980 .sh_type = SHT_NOBITS,
4981 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
4982 },
4983 [2] = { /* .debug_info */
4984 .sh_type = SHT_PROGBITS,
4985 .sh_offset = offsetof(struct ElfImage, di),
4986 .sh_size = sizeof(struct DebugInfo),
4987 },
4988 [3] = { /* .debug_abbrev */
4989 .sh_type = SHT_PROGBITS,
4990 .sh_offset = offsetof(struct ElfImage, da),
4991 .sh_size = sizeof(img->da),
4992 },
4993 [4] = { /* .debug_frame */
4994 .sh_type = SHT_PROGBITS,
4995 .sh_offset = sizeof(struct ElfImage),
4996 },
4997 [5] = { /* .symtab */
4998 .sh_type = SHT_SYMTAB,
4999 .sh_offset = offsetof(struct ElfImage, sym),
5000 .sh_size = sizeof(img->sym),
5001 .sh_info = 1,
5002 .sh_link = ARRAY_SIZE(img->shdr) - 1,
5003 .sh_entsize = sizeof(ElfW(Sym)),
5004 },
5005 [6] = { /* .strtab */
5006 .sh_type = SHT_STRTAB,
5007 .sh_offset = offsetof(struct ElfImage, str),
5008 .sh_size = sizeof(img->str),
5009 }
5010 },
5011 .sym = {
5012 [1] = { /* code_gen_buffer */
5013 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
5014 .st_shndx = 1,
5015 }
5016 },
5017 .di = {
5018 .len = sizeof(struct DebugInfo) - 4,
5019 .version = 2,
5020 .ptr_size = sizeof(void *),
5021 .cu_die = 1,
5022 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
5023 .fn_die = 2,
5024 .fn_name = "code_gen_buffer"
5025 },
5026 .da = {
5027 1, /* abbrev number (the cu) */
5028 0x11, 1, /* DW_TAG_compile_unit, has children */
5029 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
5030 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
5031 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
5032 0, 0, /* end of abbrev */
5033 2, /* abbrev number (the fn) */
5034 0x2e, 0, /* DW_TAG_subprogram, no children */
5035 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
5036 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
5037 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
5038 0, 0, /* end of abbrev */
5039 0 /* no more abbrev */
5040 },
5041 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
5042 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
813da627
RH
5043 };
5044
5045 /* We only need a single jit entry; statically allocate it. */
5046 static struct jit_code_entry one_entry;
5047
5872bbf2 5048 uintptr_t buf = (uintptr_t)buf_ptr;
813da627 5049 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2c90784a 5050 DebugFrameHeader *dfh;
813da627 5051
5872bbf2
RH
5052 img = g_malloc(img_size);
5053 *img = img_template;
813da627 5054
5872bbf2
RH
5055 img->phdr.p_vaddr = buf;
5056 img->phdr.p_paddr = buf;
5057 img->phdr.p_memsz = buf_size;
813da627 5058
813da627 5059 img->shdr[1].sh_name = find_string(img->str, ".text");
5872bbf2 5060 img->shdr[1].sh_addr = buf;
813da627
RH
5061 img->shdr[1].sh_size = buf_size;
5062
5872bbf2
RH
5063 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
5064 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
5065
5066 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
5067 img->shdr[4].sh_size = debug_frame_size;
5068
5069 img->shdr[5].sh_name = find_string(img->str, ".symtab");
5070 img->shdr[6].sh_name = find_string(img->str, ".strtab");
5071
5072 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
5073 img->sym[1].st_value = buf;
5074 img->sym[1].st_size = buf_size;
813da627 5075
5872bbf2 5076 img->di.cu_low_pc = buf;
45aba097 5077 img->di.cu_high_pc = buf + buf_size;
5872bbf2 5078 img->di.fn_low_pc = buf;
45aba097 5079 img->di.fn_high_pc = buf + buf_size;
813da627 5080
2c90784a
RH
5081 dfh = (DebugFrameHeader *)(img + 1);
5082 memcpy(dfh, debug_frame, debug_frame_size);
5083 dfh->fde.func_start = buf;
5084 dfh->fde.func_len = buf_size;
5085
813da627
RH
5086#ifdef DEBUG_JIT
5087 /* Enable this block to be able to debug the ELF image file creation.
5088 One can use readelf, objdump, or other inspection utilities. */
5089 {
eb6b2edf
BM
5090 g_autofree char *jit = g_strdup_printf("%s/qemu.jit", g_get_tmp_dir());
5091 FILE *f = fopen(jit, "w+b");
813da627 5092 if (f) {
5872bbf2 5093 if (fwrite(img, img_size, 1, f) != img_size) {
813da627
RH
5094 /* Avoid stupid unused return value warning for fwrite. */
5095 }
5096 fclose(f);
5097 }
5098 }
5099#endif
5100
5101 one_entry.symfile_addr = img;
5102 one_entry.symfile_size = img_size;
5103
5104 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
5105 __jit_debug_descriptor.relevant_entry = &one_entry;
5106 __jit_debug_descriptor.first_entry = &one_entry;
5107 __jit_debug_register_code();
5108}
5109#else
5872bbf2
RH
5110/* No support for the feature. Provide the entry point expected by exec.c,
5111 and implement the internal function we declared earlier. */
813da627 5112
755bf9e5 5113static void tcg_register_jit_int(const void *buf, size_t size,
2c90784a
RH
5114 const void *debug_frame,
5115 size_t debug_frame_size)
813da627
RH
5116{
5117}
5118
755bf9e5 5119void tcg_register_jit(const void *buf, size_t buf_size)
813da627
RH
5120{
5121}
5122#endif /* ELF_HOST_MACHINE */
db432672
RH
5123
5124#if !TCG_TARGET_MAYBE_vec
5125void tcg_expand_vec_op(TCGOpcode o, TCGType t, unsigned e, TCGArg a0, ...)
5126{
5127 g_assert_not_reached();
5128}
5129#endif