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