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