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