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