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