]> Git Repo - qemu.git/blame - tcg/tcg.c
tcg: Rearrange ldst label tracking
[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
f348b6d1 33#include "qemu/cutils.h"
1de7afc9
PB
34#include "qemu/host-utils.h"
35#include "qemu/timer.h"
c896fe29 36
c5d3c498 37/* Note: the long term plan is to reduce the dependencies on the QEMU
c896fe29
FB
38 CPU definitions. Currently they are used for qemu_ld/st
39 instructions */
40#define NO_CPU_IO_DEFS
41#include "cpu.h"
c896fe29 42
63c91552
PB
43#include "exec/cpu-common.h"
44#include "exec/exec-all.h"
45
c896fe29 46#include "tcg-op.h"
813da627 47
edee2579 48#if UINTPTR_MAX == UINT32_MAX
813da627 49# define ELF_CLASS ELFCLASS32
edee2579
RH
50#else
51# define ELF_CLASS ELFCLASS64
813da627
RH
52#endif
53#ifdef HOST_WORDS_BIGENDIAN
54# define ELF_DATA ELFDATA2MSB
55#else
56# define ELF_DATA ELFDATA2LSB
57#endif
58
c896fe29 59#include "elf.h"
508127e2 60#include "exec/log.h"
c896fe29 61
ce151109
PM
62/* Forward declarations for functions declared in tcg-target.inc.c and
63 used here. */
e4d58b41 64static void tcg_target_init(TCGContext *s);
f69d277e 65static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
e4d58b41 66static void tcg_target_qemu_prologue(TCGContext *s);
1813e175 67static void patch_reloc(tcg_insn_unit *code_ptr, int type,
2ba7fae2 68 intptr_t value, intptr_t addend);
c896fe29 69
497a22eb
RH
70/* The CIE and FDE header definitions will be common to all hosts. */
71typedef struct {
72 uint32_t len __attribute__((aligned((sizeof(void *)))));
73 uint32_t id;
74 uint8_t version;
75 char augmentation[1];
76 uint8_t code_align;
77 uint8_t data_align;
78 uint8_t return_column;
79} DebugFrameCIE;
80
81typedef struct QEMU_PACKED {
82 uint32_t len __attribute__((aligned((sizeof(void *)))));
83 uint32_t cie_offset;
edee2579
RH
84 uintptr_t func_start;
85 uintptr_t func_len;
497a22eb
RH
86} DebugFrameFDEHeader;
87
2c90784a
RH
88typedef struct QEMU_PACKED {
89 DebugFrameCIE cie;
90 DebugFrameFDEHeader fde;
91} DebugFrameHeader;
92
813da627 93static void tcg_register_jit_int(void *buf, size_t size,
2c90784a
RH
94 const void *debug_frame,
95 size_t debug_frame_size)
813da627
RH
96 __attribute__((unused));
97
ce151109 98/* Forward declarations for functions declared and used in tcg-target.inc.c. */
069ea736
RH
99static const char *target_parse_constraint(TCGArgConstraint *ct,
100 const char *ct_str, TCGType type);
2a534aff 101static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
a05b5b9b 102 intptr_t arg2);
2a534aff 103static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
c0ad3001 104static void tcg_out_movi(TCGContext *s, TCGType type,
2a534aff 105 TCGReg ret, tcg_target_long arg);
c0ad3001
SW
106static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
107 const int *const_args);
2a534aff 108static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
a05b5b9b 109 intptr_t arg2);
59d7c14e
RH
110static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
111 TCGReg base, intptr_t ofs);
cf066674 112static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
f6c6afc1 113static int tcg_target_const_match(tcg_target_long val, TCGType type,
c0ad3001 114 const TCGArgConstraint *arg_ct);
659ef5cb
RH
115#ifdef TCG_TARGET_NEED_LDST_LABELS
116static bool tcg_out_ldst_finalize(TCGContext *s);
117#endif
c896fe29 118
b1d8e52e
BS
119static TCGRegSet tcg_target_available_regs[2];
120static TCGRegSet tcg_target_call_clobber_regs;
c896fe29 121
1813e175 122#if TCG_TARGET_INSN_UNIT_SIZE == 1
4196dca6 123static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
c896fe29
FB
124{
125 *s->code_ptr++ = v;
126}
127
4196dca6
PM
128static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
129 uint8_t v)
5c53bb81 130{
1813e175 131 *p = v;
5c53bb81 132}
1813e175 133#endif
5c53bb81 134
1813e175 135#if TCG_TARGET_INSN_UNIT_SIZE <= 2
4196dca6 136static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
c896fe29 137{
1813e175
RH
138 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
139 *s->code_ptr++ = v;
140 } else {
141 tcg_insn_unit *p = s->code_ptr;
142 memcpy(p, &v, sizeof(v));
143 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
144 }
c896fe29
FB
145}
146
4196dca6
PM
147static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
148 uint16_t v)
5c53bb81 149{
1813e175
RH
150 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
151 *p = v;
152 } else {
153 memcpy(p, &v, sizeof(v));
154 }
5c53bb81 155}
1813e175 156#endif
5c53bb81 157
1813e175 158#if TCG_TARGET_INSN_UNIT_SIZE <= 4
4196dca6 159static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
c896fe29 160{
1813e175
RH
161 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
162 *s->code_ptr++ = v;
163 } else {
164 tcg_insn_unit *p = s->code_ptr;
165 memcpy(p, &v, sizeof(v));
166 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
167 }
c896fe29
FB
168}
169
4196dca6
PM
170static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
171 uint32_t v)
5c53bb81 172{
1813e175
RH
173 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
174 *p = v;
175 } else {
176 memcpy(p, &v, sizeof(v));
177 }
5c53bb81 178}
1813e175 179#endif
5c53bb81 180
1813e175 181#if TCG_TARGET_INSN_UNIT_SIZE <= 8
4196dca6 182static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
ac26eb69 183{
1813e175
RH
184 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
185 *s->code_ptr++ = v;
186 } else {
187 tcg_insn_unit *p = s->code_ptr;
188 memcpy(p, &v, sizeof(v));
189 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
190 }
ac26eb69
RH
191}
192
4196dca6
PM
193static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
194 uint64_t v)
5c53bb81 195{
1813e175
RH
196 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
197 *p = v;
198 } else {
199 memcpy(p, &v, sizeof(v));
200 }
5c53bb81 201}
1813e175 202#endif
5c53bb81 203
c896fe29
FB
204/* label relocation processing */
205
1813e175 206static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
bec16311 207 TCGLabel *l, intptr_t addend)
c896fe29 208{
c896fe29
FB
209 TCGRelocation *r;
210
c896fe29 211 if (l->has_value) {
623e265c
PB
212 /* FIXME: This may break relocations on RISC targets that
213 modify instruction fields in place. The caller may not have
214 written the initial value. */
f54b3f92 215 patch_reloc(code_ptr, type, l->u.value, addend);
c896fe29
FB
216 } else {
217 /* add a new relocation entry */
218 r = tcg_malloc(sizeof(TCGRelocation));
219 r->type = type;
220 r->ptr = code_ptr;
221 r->addend = addend;
222 r->next = l->u.first_reloc;
223 l->u.first_reloc = r;
224 }
225}
226
bec16311 227static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
c896fe29 228{
2ba7fae2 229 intptr_t value = (intptr_t)ptr;
1813e175 230 TCGRelocation *r;
c896fe29 231
eabb7b91 232 tcg_debug_assert(!l->has_value);
1813e175
RH
233
234 for (r = l->u.first_reloc; r != NULL; r = r->next) {
f54b3f92 235 patch_reloc(r->ptr, r->type, value, r->addend);
c896fe29 236 }
1813e175 237
c896fe29 238 l->has_value = 1;
1813e175 239 l->u.value_ptr = ptr;
c896fe29
FB
240}
241
42a268c2 242TCGLabel *gen_new_label(void)
c896fe29
FB
243{
244 TCGContext *s = &tcg_ctx;
51e3972c 245 TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
c896fe29 246
51e3972c
RH
247 *l = (TCGLabel){
248 .id = s->nb_labels++
249 };
42a268c2
RH
250
251 return l;
c896fe29
FB
252}
253
ce151109 254#include "tcg-target.inc.c"
c896fe29 255
c896fe29
FB
256/* pool based memory allocation */
257void *tcg_malloc_internal(TCGContext *s, int size)
258{
259 TCGPool *p;
260 int pool_size;
261
262 if (size > TCG_POOL_CHUNK_SIZE) {
263 /* big malloc: insert a new pool (XXX: could optimize) */
7267c094 264 p = g_malloc(sizeof(TCGPool) + size);
c896fe29 265 p->size = size;
4055299e
KB
266 p->next = s->pool_first_large;
267 s->pool_first_large = p;
268 return p->data;
c896fe29
FB
269 } else {
270 p = s->pool_current;
271 if (!p) {
272 p = s->pool_first;
273 if (!p)
274 goto new_pool;
275 } else {
276 if (!p->next) {
277 new_pool:
278 pool_size = TCG_POOL_CHUNK_SIZE;
7267c094 279 p = g_malloc(sizeof(TCGPool) + pool_size);
c896fe29
FB
280 p->size = pool_size;
281 p->next = NULL;
282 if (s->pool_current)
283 s->pool_current->next = p;
284 else
285 s->pool_first = p;
286 } else {
287 p = p->next;
288 }
289 }
290 }
291 s->pool_current = p;
292 s->pool_cur = p->data + size;
293 s->pool_end = p->data + p->size;
294 return p->data;
295}
296
297void tcg_pool_reset(TCGContext *s)
298{
4055299e
KB
299 TCGPool *p, *t;
300 for (p = s->pool_first_large; p; p = t) {
301 t = p->next;
302 g_free(p);
303 }
304 s->pool_first_large = NULL;
c896fe29
FB
305 s->pool_cur = s->pool_end = NULL;
306 s->pool_current = NULL;
307}
308
100b5e01
RH
309typedef struct TCGHelperInfo {
310 void *func;
311 const char *name;
afb49896
RH
312 unsigned flags;
313 unsigned sizemask;
100b5e01
RH
314} TCGHelperInfo;
315
2ef6175a
RH
316#include "exec/helper-proto.h"
317
100b5e01 318static const TCGHelperInfo all_helpers[] = {
2ef6175a 319#include "exec/helper-tcg.h"
100b5e01
RH
320};
321
91478cef 322static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
f69d277e 323static void process_op_defs(TCGContext *s);
91478cef 324
c896fe29
FB
325void tcg_context_init(TCGContext *s)
326{
100b5e01 327 int op, total_args, n, i;
c896fe29
FB
328 TCGOpDef *def;
329 TCGArgConstraint *args_ct;
330 int *sorted_args;
84fd9dd3 331 GHashTable *helper_table;
c896fe29
FB
332
333 memset(s, 0, sizeof(*s));
c896fe29 334 s->nb_globals = 0;
c70fbf0a 335
c896fe29
FB
336 /* Count total number of arguments and allocate the corresponding
337 space */
338 total_args = 0;
339 for(op = 0; op < NB_OPS; op++) {
340 def = &tcg_op_defs[op];
341 n = def->nb_iargs + def->nb_oargs;
342 total_args += n;
343 }
344
7267c094
AL
345 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
346 sorted_args = g_malloc(sizeof(int) * total_args);
c896fe29
FB
347
348 for(op = 0; op < NB_OPS; op++) {
349 def = &tcg_op_defs[op];
350 def->args_ct = args_ct;
351 def->sorted_args = sorted_args;
352 n = def->nb_iargs + def->nb_oargs;
353 sorted_args += n;
354 args_ct += n;
355 }
5cd8f621
RH
356
357 /* Register helpers. */
84fd9dd3
RH
358 /* Use g_direct_hash/equal for direct pointer comparisons on func. */
359 s->helpers = helper_table = g_hash_table_new(NULL, NULL);
360
100b5e01 361 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
84fd9dd3 362 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
72866e82 363 (gpointer)&all_helpers[i]);
100b5e01 364 }
5cd8f621 365
c896fe29 366 tcg_target_init(s);
f69d277e 367 process_op_defs(s);
91478cef
RH
368
369 /* Reverse the order of the saved registers, assuming they're all at
370 the start of tcg_target_reg_alloc_order. */
371 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
372 int r = tcg_target_reg_alloc_order[n];
373 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) {
374 break;
375 }
376 }
377 for (i = 0; i < n; ++i) {
378 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
379 }
380 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
381 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
382 }
9002ec79 383}
b03cce8e 384
6e3b2bfd
EC
385/*
386 * Allocate TBs right before their corresponding translated code, making
387 * sure that TBs and code are on different cache lines.
388 */
389TranslationBlock *tcg_tb_alloc(TCGContext *s)
390{
391 uintptr_t align = qemu_icache_linesize;
392 TranslationBlock *tb;
393 void *next;
394
395 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
396 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
397
398 if (unlikely(next > s->code_gen_highwater)) {
399 return NULL;
400 }
401 s->code_gen_ptr = next;
402 return tb;
403}
404
9002ec79
RH
405void tcg_prologue_init(TCGContext *s)
406{
8163b749
RH
407 size_t prologue_size, total_size;
408 void *buf0, *buf1;
409
410 /* Put the prologue at the beginning of code_gen_buffer. */
411 buf0 = s->code_gen_buffer;
412 s->code_ptr = buf0;
413 s->code_buf = buf0;
414 s->code_gen_prologue = buf0;
415
416 /* Generate the prologue. */
b03cce8e 417 tcg_target_qemu_prologue(s);
8163b749
RH
418 buf1 = s->code_ptr;
419 flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1);
420
421 /* Deduct the prologue from the buffer. */
422 prologue_size = tcg_current_code_size(s);
423 s->code_gen_ptr = buf1;
424 s->code_gen_buffer = buf1;
425 s->code_buf = buf1;
426 total_size = s->code_gen_buffer_size - prologue_size;
427 s->code_gen_buffer_size = total_size;
428
b125f9dc
RH
429 /* Compute a high-water mark, at which we voluntarily flush the buffer
430 and start over. The size here is arbitrary, significantly larger
431 than we expect the code generation for any one opcode to require. */
23dceda6 432 s->code_gen_highwater = s->code_gen_buffer + (total_size - 1024);
8163b749
RH
433
434 tcg_register_jit(s->code_gen_buffer, total_size);
d6b64b2b
RH
435
436#ifdef DEBUG_DISAS
437 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
1ee73216 438 qemu_log_lock();
8163b749
RH
439 qemu_log("PROLOGUE: [size=%zu]\n", prologue_size);
440 log_disas(buf0, prologue_size);
d6b64b2b
RH
441 qemu_log("\n");
442 qemu_log_flush();
1ee73216 443 qemu_log_unlock();
d6b64b2b
RH
444 }
445#endif
cedbcb01
EC
446
447 /* Assert that goto_ptr is implemented completely. */
448 if (TCG_TARGET_HAS_goto_ptr) {
449 tcg_debug_assert(s->code_gen_epilogue != NULL);
450 }
c896fe29
FB
451}
452
c896fe29
FB
453void tcg_func_start(TCGContext *s)
454{
455 tcg_pool_reset(s);
456 s->nb_temps = s->nb_globals;
0ec9eabc
RH
457
458 /* No temps have been previously allocated for size or locality. */
459 memset(s->free_temps, 0, sizeof(s->free_temps));
460
c896fe29
FB
461 s->nb_labels = 0;
462 s->current_frame_offset = s->frame_start;
463
0a209d4b
RH
464#ifdef CONFIG_DEBUG_TCG
465 s->goto_tb_issue_mask = 0;
466#endif
467
dcb8e758
RH
468 s->gen_op_buf[0].next = 1;
469 s->gen_op_buf[0].prev = 0;
470 s->gen_next_op_idx = 1;
c45cb8bb 471 s->gen_next_parm_idx = 0;
c896fe29
FB
472}
473
7ca4b752 474static inline int temp_idx(TCGContext *s, TCGTemp *ts)
c896fe29 475{
7ca4b752
RH
476 ptrdiff_t n = ts - s->temps;
477 tcg_debug_assert(n >= 0 && n < s->nb_temps);
478 return n;
479}
480
481static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
482{
483 int n = s->nb_temps++;
484 tcg_debug_assert(n < TCG_MAX_TEMPS);
485 return memset(&s->temps[n], 0, sizeof(TCGTemp));
486}
487
488static inline TCGTemp *tcg_global_alloc(TCGContext *s)
489{
490 tcg_debug_assert(s->nb_globals == s->nb_temps);
491 s->nb_globals++;
492 return tcg_temp_alloc(s);
c896fe29
FB
493}
494
b3a62939 495static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
b6638662 496 TCGReg reg, const char *name)
c896fe29 497{
c896fe29 498 TCGTemp *ts;
c896fe29 499
b3a62939 500 if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
c896fe29 501 tcg_abort();
b3a62939 502 }
7ca4b752
RH
503
504 ts = tcg_global_alloc(s);
c896fe29
FB
505 ts->base_type = type;
506 ts->type = type;
507 ts->fixed_reg = 1;
508 ts->reg = reg;
c896fe29 509 ts->name = name;
c896fe29 510 tcg_regset_set_reg(s->reserved_regs, reg);
7ca4b752
RH
511
512 return temp_idx(s, ts);
a7812ae4
PB
513}
514
b6638662 515void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
b3a62939
RH
516{
517 int idx;
518 s->frame_start = start;
519 s->frame_end = start + size;
520 idx = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
521 s->frame_temp = &s->temps[idx];
522}
523
b6638662 524TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name)
a7812ae4 525{
b3a62939 526 TCGContext *s = &tcg_ctx;
a7812ae4
PB
527 int idx;
528
b3a62939
RH
529 if (tcg_regset_test_reg(s->reserved_regs, reg)) {
530 tcg_abort();
531 }
532 idx = tcg_global_reg_new_internal(s, TCG_TYPE_I32, reg, name);
a7812ae4
PB
533 return MAKE_TCGV_I32(idx);
534}
535
b6638662 536TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name)
a7812ae4 537{
b3a62939 538 TCGContext *s = &tcg_ctx;
a7812ae4
PB
539 int idx;
540
b3a62939
RH
541 if (tcg_regset_test_reg(s->reserved_regs, reg)) {
542 tcg_abort();
543 }
544 idx = tcg_global_reg_new_internal(s, TCG_TYPE_I64, reg, name);
a7812ae4 545 return MAKE_TCGV_I64(idx);
c896fe29
FB
546}
547
e1ccc054
RH
548int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
549 intptr_t offset, const char *name)
c896fe29
FB
550{
551 TCGContext *s = &tcg_ctx;
7ca4b752
RH
552 TCGTemp *base_ts = &s->temps[GET_TCGV_PTR(base)];
553 TCGTemp *ts = tcg_global_alloc(s);
b3915dbb 554 int indirect_reg = 0, bigendian = 0;
7ca4b752
RH
555#ifdef HOST_WORDS_BIGENDIAN
556 bigendian = 1;
557#endif
c896fe29 558
b3915dbb 559 if (!base_ts->fixed_reg) {
5a18407f
RH
560 /* We do not support double-indirect registers. */
561 tcg_debug_assert(!base_ts->indirect_reg);
b3915dbb 562 base_ts->indirect_base = 1;
5a18407f
RH
563 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
564 ? 2 : 1);
565 indirect_reg = 1;
b3915dbb
RH
566 }
567
7ca4b752
RH
568 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
569 TCGTemp *ts2 = tcg_global_alloc(s);
c896fe29 570 char buf[64];
7ca4b752
RH
571
572 ts->base_type = TCG_TYPE_I64;
c896fe29 573 ts->type = TCG_TYPE_I32;
b3915dbb 574 ts->indirect_reg = indirect_reg;
c896fe29 575 ts->mem_allocated = 1;
b3a62939 576 ts->mem_base = base_ts;
7ca4b752 577 ts->mem_offset = offset + bigendian * 4;
c896fe29
FB
578 pstrcpy(buf, sizeof(buf), name);
579 pstrcat(buf, sizeof(buf), "_0");
580 ts->name = strdup(buf);
c896fe29 581
7ca4b752
RH
582 tcg_debug_assert(ts2 == ts + 1);
583 ts2->base_type = TCG_TYPE_I64;
584 ts2->type = TCG_TYPE_I32;
b3915dbb 585 ts2->indirect_reg = indirect_reg;
7ca4b752
RH
586 ts2->mem_allocated = 1;
587 ts2->mem_base = base_ts;
588 ts2->mem_offset = offset + (1 - bigendian) * 4;
c896fe29
FB
589 pstrcpy(buf, sizeof(buf), name);
590 pstrcat(buf, sizeof(buf), "_1");
120c1084 591 ts2->name = strdup(buf);
7ca4b752 592 } else {
c896fe29
FB
593 ts->base_type = type;
594 ts->type = type;
b3915dbb 595 ts->indirect_reg = indirect_reg;
c896fe29 596 ts->mem_allocated = 1;
b3a62939 597 ts->mem_base = base_ts;
c896fe29 598 ts->mem_offset = offset;
c896fe29 599 ts->name = name;
c896fe29 600 }
7ca4b752 601 return temp_idx(s, ts);
a7812ae4
PB
602}
603
7ca4b752 604static int tcg_temp_new_internal(TCGType type, int temp_local)
c896fe29
FB
605{
606 TCGContext *s = &tcg_ctx;
607 TCGTemp *ts;
641d5fbe 608 int idx, k;
c896fe29 609
0ec9eabc
RH
610 k = type + (temp_local ? TCG_TYPE_COUNT : 0);
611 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
612 if (idx < TCG_MAX_TEMPS) {
613 /* There is already an available temp with the right type. */
614 clear_bit(idx, s->free_temps[k].l);
615
e8996ee0 616 ts = &s->temps[idx];
e8996ee0 617 ts->temp_allocated = 1;
7ca4b752
RH
618 tcg_debug_assert(ts->base_type == type);
619 tcg_debug_assert(ts->temp_local == temp_local);
e8996ee0 620 } else {
7ca4b752
RH
621 ts = tcg_temp_alloc(s);
622 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
623 TCGTemp *ts2 = tcg_temp_alloc(s);
624
f6aa2f7d 625 ts->base_type = type;
e8996ee0
FB
626 ts->type = TCG_TYPE_I32;
627 ts->temp_allocated = 1;
641d5fbe 628 ts->temp_local = temp_local;
7ca4b752
RH
629
630 tcg_debug_assert(ts2 == ts + 1);
631 ts2->base_type = TCG_TYPE_I64;
632 ts2->type = TCG_TYPE_I32;
633 ts2->temp_allocated = 1;
634 ts2->temp_local = temp_local;
635 } else {
e8996ee0
FB
636 ts->base_type = type;
637 ts->type = type;
638 ts->temp_allocated = 1;
641d5fbe 639 ts->temp_local = temp_local;
e8996ee0 640 }
7ca4b752 641 idx = temp_idx(s, ts);
c896fe29 642 }
27bfd83c
PM
643
644#if defined(CONFIG_DEBUG_TCG)
645 s->temps_in_use++;
646#endif
a7812ae4 647 return idx;
c896fe29
FB
648}
649
a7812ae4
PB
650TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
651{
652 int idx;
653
654 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
655 return MAKE_TCGV_I32(idx);
656}
657
658TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
659{
660 int idx;
661
662 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
663 return MAKE_TCGV_I64(idx);
664}
665
0ec9eabc 666static void tcg_temp_free_internal(int idx)
c896fe29
FB
667{
668 TCGContext *s = &tcg_ctx;
669 TCGTemp *ts;
641d5fbe 670 int k;
c896fe29 671
27bfd83c
PM
672#if defined(CONFIG_DEBUG_TCG)
673 s->temps_in_use--;
674 if (s->temps_in_use < 0) {
675 fprintf(stderr, "More temporaries freed than allocated!\n");
676 }
677#endif
678
eabb7b91 679 tcg_debug_assert(idx >= s->nb_globals && idx < s->nb_temps);
c896fe29 680 ts = &s->temps[idx];
eabb7b91 681 tcg_debug_assert(ts->temp_allocated != 0);
e8996ee0 682 ts->temp_allocated = 0;
0ec9eabc 683
18d13fa2 684 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0);
0ec9eabc 685 set_bit(idx, s->free_temps[k].l);
c896fe29
FB
686}
687
a7812ae4
PB
688void tcg_temp_free_i32(TCGv_i32 arg)
689{
690 tcg_temp_free_internal(GET_TCGV_I32(arg));
691}
692
693void tcg_temp_free_i64(TCGv_i64 arg)
694{
695 tcg_temp_free_internal(GET_TCGV_I64(arg));
696}
e8996ee0 697
a7812ae4 698TCGv_i32 tcg_const_i32(int32_t val)
c896fe29 699{
a7812ae4
PB
700 TCGv_i32 t0;
701 t0 = tcg_temp_new_i32();
e8996ee0
FB
702 tcg_gen_movi_i32(t0, val);
703 return t0;
704}
c896fe29 705
a7812ae4 706TCGv_i64 tcg_const_i64(int64_t val)
e8996ee0 707{
a7812ae4
PB
708 TCGv_i64 t0;
709 t0 = tcg_temp_new_i64();
e8996ee0
FB
710 tcg_gen_movi_i64(t0, val);
711 return t0;
c896fe29
FB
712}
713
a7812ae4 714TCGv_i32 tcg_const_local_i32(int32_t val)
bdffd4a9 715{
a7812ae4
PB
716 TCGv_i32 t0;
717 t0 = tcg_temp_local_new_i32();
bdffd4a9
AJ
718 tcg_gen_movi_i32(t0, val);
719 return t0;
720}
721
a7812ae4 722TCGv_i64 tcg_const_local_i64(int64_t val)
bdffd4a9 723{
a7812ae4
PB
724 TCGv_i64 t0;
725 t0 = tcg_temp_local_new_i64();
bdffd4a9
AJ
726 tcg_gen_movi_i64(t0, val);
727 return t0;
728}
729
27bfd83c
PM
730#if defined(CONFIG_DEBUG_TCG)
731void tcg_clear_temp_count(void)
732{
733 TCGContext *s = &tcg_ctx;
734 s->temps_in_use = 0;
735}
736
737int tcg_check_temp_count(void)
738{
739 TCGContext *s = &tcg_ctx;
740 if (s->temps_in_use) {
741 /* Clear the count so that we don't give another
742 * warning immediately next time around.
743 */
744 s->temps_in_use = 0;
745 return 1;
746 }
747 return 0;
748}
749#endif
750
39cf05d3
FB
751/* Note: we convert the 64 bit args to 32 bit and do some alignment
752 and endian swap. Maybe it would be better to do the alignment
753 and endian swap in tcg_reg_alloc_call(). */
bbb8a1b4
RH
754void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
755 int nargs, TCGArg *args)
c896fe29 756{
c45cb8bb 757 int i, real_args, nb_rets, pi, pi_first;
bbb8a1b4 758 unsigned sizemask, flags;
afb49896
RH
759 TCGHelperInfo *info;
760
761 info = g_hash_table_lookup(s->helpers, (gpointer)func);
bbb8a1b4
RH
762 flags = info->flags;
763 sizemask = info->sizemask;
2bece2c8 764
34b1a49c
RH
765#if defined(__sparc__) && !defined(__arch64__) \
766 && !defined(CONFIG_TCG_INTERPRETER)
767 /* We have 64-bit values in one register, but need to pass as two
768 separate parameters. Split them. */
769 int orig_sizemask = sizemask;
770 int orig_nargs = nargs;
771 TCGv_i64 retl, reth;
772
773 TCGV_UNUSED_I64(retl);
774 TCGV_UNUSED_I64(reth);
775 if (sizemask != 0) {
776 TCGArg *split_args = __builtin_alloca(sizeof(TCGArg) * nargs * 2);
777 for (i = real_args = 0; i < nargs; ++i) {
778 int is_64bit = sizemask & (1 << (i+1)*2);
779 if (is_64bit) {
780 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
781 TCGv_i32 h = tcg_temp_new_i32();
782 TCGv_i32 l = tcg_temp_new_i32();
783 tcg_gen_extr_i64_i32(l, h, orig);
784 split_args[real_args++] = GET_TCGV_I32(h);
785 split_args[real_args++] = GET_TCGV_I32(l);
786 } else {
787 split_args[real_args++] = args[i];
788 }
789 }
790 nargs = real_args;
791 args = split_args;
792 sizemask = 0;
793 }
794#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
2bece2c8
RH
795 for (i = 0; i < nargs; ++i) {
796 int is_64bit = sizemask & (1 << (i+1)*2);
797 int is_signed = sizemask & (2 << (i+1)*2);
798 if (!is_64bit) {
799 TCGv_i64 temp = tcg_temp_new_i64();
800 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
801 if (is_signed) {
802 tcg_gen_ext32s_i64(temp, orig);
803 } else {
804 tcg_gen_ext32u_i64(temp, orig);
805 }
806 args[i] = GET_TCGV_I64(temp);
807 }
808 }
809#endif /* TCG_TARGET_EXTEND_ARGS */
810
c45cb8bb 811 pi_first = pi = s->gen_next_parm_idx;
a7812ae4 812 if (ret != TCG_CALL_DUMMY_ARG) {
34b1a49c
RH
813#if defined(__sparc__) && !defined(__arch64__) \
814 && !defined(CONFIG_TCG_INTERPRETER)
815 if (orig_sizemask & 1) {
816 /* The 32-bit ABI is going to return the 64-bit value in
817 the %o0/%o1 register pair. Prepare for this by using
818 two return temporaries, and reassemble below. */
819 retl = tcg_temp_new_i64();
820 reth = tcg_temp_new_i64();
c45cb8bb
RH
821 s->gen_opparam_buf[pi++] = GET_TCGV_I64(reth);
822 s->gen_opparam_buf[pi++] = GET_TCGV_I64(retl);
34b1a49c
RH
823 nb_rets = 2;
824 } else {
c45cb8bb 825 s->gen_opparam_buf[pi++] = ret;
34b1a49c
RH
826 nb_rets = 1;
827 }
828#else
829 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
02eb19d0 830#ifdef HOST_WORDS_BIGENDIAN
c45cb8bb
RH
831 s->gen_opparam_buf[pi++] = ret + 1;
832 s->gen_opparam_buf[pi++] = ret;
39cf05d3 833#else
c45cb8bb
RH
834 s->gen_opparam_buf[pi++] = ret;
835 s->gen_opparam_buf[pi++] = ret + 1;
39cf05d3 836#endif
a7812ae4 837 nb_rets = 2;
34b1a49c 838 } else {
c45cb8bb 839 s->gen_opparam_buf[pi++] = ret;
a7812ae4 840 nb_rets = 1;
c896fe29 841 }
34b1a49c 842#endif
a7812ae4
PB
843 } else {
844 nb_rets = 0;
c896fe29 845 }
a7812ae4
PB
846 real_args = 0;
847 for (i = 0; i < nargs; i++) {
2bece2c8 848 int is_64bit = sizemask & (1 << (i+1)*2);
bbb8a1b4 849 if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
39cf05d3
FB
850#ifdef TCG_TARGET_CALL_ALIGN_ARGS
851 /* some targets want aligned 64 bit args */
ebd486d5 852 if (real_args & 1) {
c45cb8bb 853 s->gen_opparam_buf[pi++] = TCG_CALL_DUMMY_ARG;
ebd486d5 854 real_args++;
39cf05d3
FB
855 }
856#endif
c70fbf0a
RH
857 /* If stack grows up, then we will be placing successive
858 arguments at lower addresses, which means we need to
859 reverse the order compared to how we would normally
860 treat either big or little-endian. For those arguments
861 that will wind up in registers, this still works for
862 HPPA (the only current STACK_GROWSUP target) since the
863 argument registers are *also* allocated in decreasing
864 order. If another such target is added, this logic may
865 have to get more complicated to differentiate between
866 stack arguments and register arguments. */
02eb19d0 867#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
c45cb8bb
RH
868 s->gen_opparam_buf[pi++] = args[i] + 1;
869 s->gen_opparam_buf[pi++] = args[i];
c896fe29 870#else
c45cb8bb
RH
871 s->gen_opparam_buf[pi++] = args[i];
872 s->gen_opparam_buf[pi++] = args[i] + 1;
c896fe29 873#endif
a7812ae4 874 real_args += 2;
2bece2c8 875 continue;
c896fe29 876 }
2bece2c8 877
c45cb8bb 878 s->gen_opparam_buf[pi++] = args[i];
2bece2c8 879 real_args++;
c896fe29 880 }
c45cb8bb
RH
881 s->gen_opparam_buf[pi++] = (uintptr_t)func;
882 s->gen_opparam_buf[pi++] = flags;
a7812ae4 883
c45cb8bb
RH
884 i = s->gen_next_op_idx;
885 tcg_debug_assert(i < OPC_BUF_SIZE);
886 tcg_debug_assert(pi <= OPPARAM_BUF_SIZE);
a7812ae4 887
c45cb8bb
RH
888 /* Set links for sequential allocation during translation. */
889 s->gen_op_buf[i] = (TCGOp){
890 .opc = INDEX_op_call,
891 .callo = nb_rets,
892 .calli = real_args,
893 .args = pi_first,
894 .prev = i - 1,
895 .next = i + 1
896 };
897
898 /* Make sure the calli field didn't overflow. */
899 tcg_debug_assert(s->gen_op_buf[i].calli == real_args);
900
dcb8e758 901 s->gen_op_buf[0].prev = i;
c45cb8bb
RH
902 s->gen_next_op_idx = i + 1;
903 s->gen_next_parm_idx = pi;
2bece2c8 904
34b1a49c
RH
905#if defined(__sparc__) && !defined(__arch64__) \
906 && !defined(CONFIG_TCG_INTERPRETER)
907 /* Free all of the parts we allocated above. */
908 for (i = real_args = 0; i < orig_nargs; ++i) {
909 int is_64bit = orig_sizemask & (1 << (i+1)*2);
910 if (is_64bit) {
911 TCGv_i32 h = MAKE_TCGV_I32(args[real_args++]);
912 TCGv_i32 l = MAKE_TCGV_I32(args[real_args++]);
913 tcg_temp_free_i32(h);
914 tcg_temp_free_i32(l);
915 } else {
916 real_args++;
917 }
918 }
919 if (orig_sizemask & 1) {
920 /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
921 Note that describing these as TCGv_i64 eliminates an unnecessary
922 zero-extension that tcg_gen_concat_i32_i64 would create. */
923 tcg_gen_concat32_i64(MAKE_TCGV_I64(ret), retl, reth);
924 tcg_temp_free_i64(retl);
925 tcg_temp_free_i64(reth);
926 }
927#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
2bece2c8
RH
928 for (i = 0; i < nargs; ++i) {
929 int is_64bit = sizemask & (1 << (i+1)*2);
930 if (!is_64bit) {
931 TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
932 tcg_temp_free_i64(temp);
933 }
934 }
935#endif /* TCG_TARGET_EXTEND_ARGS */
c896fe29 936}
c896fe29 937
8fcd3692 938static void tcg_reg_alloc_start(TCGContext *s)
c896fe29
FB
939{
940 int i;
941 TCGTemp *ts;
942 for(i = 0; i < s->nb_globals; i++) {
943 ts = &s->temps[i];
944 if (ts->fixed_reg) {
945 ts->val_type = TEMP_VAL_REG;
946 } else {
947 ts->val_type = TEMP_VAL_MEM;
948 }
949 }
e8996ee0
FB
950 for(i = s->nb_globals; i < s->nb_temps; i++) {
951 ts = &s->temps[i];
7dfd8c6a
AJ
952 if (ts->temp_local) {
953 ts->val_type = TEMP_VAL_MEM;
954 } else {
955 ts->val_type = TEMP_VAL_DEAD;
956 }
e8996ee0
FB
957 ts->mem_allocated = 0;
958 ts->fixed_reg = 0;
959 }
f8b2f202
RH
960
961 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
c896fe29
FB
962}
963
f8b2f202
RH
964static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
965 TCGTemp *ts)
c896fe29 966{
f8b2f202 967 int idx = temp_idx(s, ts);
ac56dd48 968
ac56dd48
PB
969 if (idx < s->nb_globals) {
970 pstrcpy(buf, buf_size, ts->name);
f8b2f202
RH
971 } else if (ts->temp_local) {
972 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
c896fe29 973 } else {
f8b2f202 974 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
c896fe29
FB
975 }
976 return buf;
977}
978
f8b2f202
RH
979static char *tcg_get_arg_str_idx(TCGContext *s, char *buf,
980 int buf_size, int idx)
981{
eabb7b91 982 tcg_debug_assert(idx >= 0 && idx < s->nb_temps);
f8b2f202
RH
983 return tcg_get_arg_str_ptr(s, buf, buf_size, &s->temps[idx]);
984}
985
6e085f72
RH
986/* Find helper name. */
987static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
4dc81f28 988{
6e085f72
RH
989 const char *ret = NULL;
990 if (s->helpers) {
72866e82
RH
991 TCGHelperInfo *info = g_hash_table_lookup(s->helpers, (gpointer)val);
992 if (info) {
993 ret = info->name;
994 }
4dc81f28 995 }
6e085f72 996 return ret;
4dc81f28
FB
997}
998
f48f3ede
BS
999static const char * const cond_name[] =
1000{
0aed257f
RH
1001 [TCG_COND_NEVER] = "never",
1002 [TCG_COND_ALWAYS] = "always",
f48f3ede
BS
1003 [TCG_COND_EQ] = "eq",
1004 [TCG_COND_NE] = "ne",
1005 [TCG_COND_LT] = "lt",
1006 [TCG_COND_GE] = "ge",
1007 [TCG_COND_LE] = "le",
1008 [TCG_COND_GT] = "gt",
1009 [TCG_COND_LTU] = "ltu",
1010 [TCG_COND_GEU] = "geu",
1011 [TCG_COND_LEU] = "leu",
1012 [TCG_COND_GTU] = "gtu"
1013};
1014
f713d6ad
RH
1015static const char * const ldst_name[] =
1016{
1017 [MO_UB] = "ub",
1018 [MO_SB] = "sb",
1019 [MO_LEUW] = "leuw",
1020 [MO_LESW] = "lesw",
1021 [MO_LEUL] = "leul",
1022 [MO_LESL] = "lesl",
1023 [MO_LEQ] = "leq",
1024 [MO_BEUW] = "beuw",
1025 [MO_BESW] = "besw",
1026 [MO_BEUL] = "beul",
1027 [MO_BESL] = "besl",
1028 [MO_BEQ] = "beq",
1029};
1030
1f00b27f
SS
1031static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
1032#ifdef ALIGNED_ONLY
1033 [MO_UNALN >> MO_ASHIFT] = "un+",
1034 [MO_ALIGN >> MO_ASHIFT] = "",
1035#else
1036 [MO_UNALN >> MO_ASHIFT] = "",
1037 [MO_ALIGN >> MO_ASHIFT] = "al+",
1038#endif
1039 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+",
1040 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+",
1041 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+",
1042 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
1043 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
1044 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
1045};
1046
eeacee4d 1047void tcg_dump_ops(TCGContext *s)
c896fe29 1048{
c896fe29 1049 char buf[128];
c45cb8bb
RH
1050 TCGOp *op;
1051 int oi;
1052
dcb8e758 1053 for (oi = s->gen_op_buf[0].next; oi != 0; oi = op->next) {
c45cb8bb
RH
1054 int i, k, nb_oargs, nb_iargs, nb_cargs;
1055 const TCGOpDef *def;
1056 const TCGArg *args;
1057 TCGOpcode c;
bdfb460e 1058 int col = 0;
c896fe29 1059
c45cb8bb
RH
1060 op = &s->gen_op_buf[oi];
1061 c = op->opc;
c896fe29 1062 def = &tcg_op_defs[c];
c45cb8bb
RH
1063 args = &s->gen_opparam_buf[op->args];
1064
765b842a 1065 if (c == INDEX_op_insn_start) {
bdfb460e 1066 col += qemu_log("%s ----", oi != s->gen_op_buf[0].next ? "\n" : "");
9aef40ed
RH
1067
1068 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
1069 target_ulong a;
7e4597d7 1070#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
9aef40ed 1071 a = ((target_ulong)args[i * 2 + 1] << 32) | args[i * 2];
7e4597d7 1072#else
9aef40ed 1073 a = args[i];
7e4597d7 1074#endif
bdfb460e 1075 col += qemu_log(" " TARGET_FMT_lx, a);
eeacee4d 1076 }
7e4597d7 1077 } else if (c == INDEX_op_call) {
c896fe29 1078 /* variable number of arguments */
c45cb8bb
RH
1079 nb_oargs = op->callo;
1080 nb_iargs = op->calli;
c896fe29 1081 nb_cargs = def->nb_cargs;
c896fe29 1082
cf066674 1083 /* function name, flags, out args */
bdfb460e
RH
1084 col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
1085 tcg_find_helper(s, args[nb_oargs + nb_iargs]),
1086 args[nb_oargs + nb_iargs + 1], nb_oargs);
cf066674 1087 for (i = 0; i < nb_oargs; i++) {
bdfb460e
RH
1088 col += qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1089 args[i]));
b03cce8e 1090 }
cf066674
RH
1091 for (i = 0; i < nb_iargs; i++) {
1092 TCGArg arg = args[nb_oargs + i];
1093 const char *t = "<dummy>";
1094 if (arg != TCG_CALL_DUMMY_ARG) {
1095 t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);
eeacee4d 1096 }
bdfb460e 1097 col += qemu_log(",%s", t);
e8996ee0 1098 }
b03cce8e 1099 } else {
bdfb460e 1100 col += qemu_log(" %s ", def->name);
c45cb8bb
RH
1101
1102 nb_oargs = def->nb_oargs;
1103 nb_iargs = def->nb_iargs;
1104 nb_cargs = def->nb_cargs;
1105
b03cce8e 1106 k = 0;
c45cb8bb 1107 for (i = 0; i < nb_oargs; i++) {
eeacee4d 1108 if (k != 0) {
bdfb460e 1109 col += qemu_log(",");
eeacee4d 1110 }
bdfb460e
RH
1111 col += qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1112 args[k++]));
b03cce8e 1113 }
c45cb8bb 1114 for (i = 0; i < nb_iargs; i++) {
eeacee4d 1115 if (k != 0) {
bdfb460e 1116 col += qemu_log(",");
eeacee4d 1117 }
bdfb460e
RH
1118 col += qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1119 args[k++]));
b03cce8e 1120 }
be210acb
RH
1121 switch (c) {
1122 case INDEX_op_brcond_i32:
be210acb 1123 case INDEX_op_setcond_i32:
ffc5ea09 1124 case INDEX_op_movcond_i32:
ffc5ea09 1125 case INDEX_op_brcond2_i32:
be210acb 1126 case INDEX_op_setcond2_i32:
ffc5ea09 1127 case INDEX_op_brcond_i64:
be210acb 1128 case INDEX_op_setcond_i64:
ffc5ea09 1129 case INDEX_op_movcond_i64:
eeacee4d 1130 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
bdfb460e 1131 col += qemu_log(",%s", cond_name[args[k++]]);
eeacee4d 1132 } else {
bdfb460e 1133 col += qemu_log(",$0x%" TCG_PRIlx, args[k++]);
eeacee4d 1134 }
f48f3ede 1135 i = 1;
be210acb 1136 break;
f713d6ad
RH
1137 case INDEX_op_qemu_ld_i32:
1138 case INDEX_op_qemu_st_i32:
1139 case INDEX_op_qemu_ld_i64:
1140 case INDEX_op_qemu_st_i64:
59227d5d
RH
1141 {
1142 TCGMemOpIdx oi = args[k++];
1143 TCGMemOp op = get_memop(oi);
1144 unsigned ix = get_mmuidx(oi);
1145
59c4b7e8 1146 if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) {
bdfb460e 1147 col += qemu_log(",$0x%x,%u", op, ix);
59c4b7e8 1148 } else {
1f00b27f
SS
1149 const char *s_al, *s_op;
1150 s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT];
59c4b7e8 1151 s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];
bdfb460e 1152 col += qemu_log(",%s%s,%u", s_al, s_op, ix);
59227d5d
RH
1153 }
1154 i = 1;
f713d6ad 1155 }
f713d6ad 1156 break;
be210acb 1157 default:
f48f3ede 1158 i = 0;
be210acb
RH
1159 break;
1160 }
51e3972c
RH
1161 switch (c) {
1162 case INDEX_op_set_label:
1163 case INDEX_op_br:
1164 case INDEX_op_brcond_i32:
1165 case INDEX_op_brcond_i64:
1166 case INDEX_op_brcond2_i32:
bdfb460e 1167 col += qemu_log("%s$L%d", k ? "," : "", arg_label(args[k])->id);
51e3972c
RH
1168 i++, k++;
1169 break;
1170 default:
1171 break;
1172 }
1173 for (; i < nb_cargs; i++, k++) {
bdfb460e
RH
1174 col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", args[k]);
1175 }
1176 }
1177 if (op->life) {
1178 unsigned life = op->life;
1179
1180 for (; col < 48; ++col) {
1181 putc(' ', qemu_logfile);
1182 }
1183
1184 if (life & (SYNC_ARG * 3)) {
1185 qemu_log(" sync:");
1186 for (i = 0; i < 2; ++i) {
1187 if (life & (SYNC_ARG << i)) {
1188 qemu_log(" %d", i);
1189 }
1190 }
1191 }
1192 life /= DEAD_ARG;
1193 if (life) {
1194 qemu_log(" dead:");
1195 for (i = 0; life; ++i, life >>= 1) {
1196 if (life & 1) {
1197 qemu_log(" %d", i);
1198 }
1199 }
b03cce8e 1200 }
c896fe29 1201 }
eeacee4d 1202 qemu_log("\n");
c896fe29
FB
1203 }
1204}
1205
1206/* we give more priority to constraints with less registers */
1207static int get_constraint_priority(const TCGOpDef *def, int k)
1208{
1209 const TCGArgConstraint *arg_ct;
1210
1211 int i, n;
1212 arg_ct = &def->args_ct[k];
1213 if (arg_ct->ct & TCG_CT_ALIAS) {
1214 /* an alias is equivalent to a single register */
1215 n = 1;
1216 } else {
1217 if (!(arg_ct->ct & TCG_CT_REG))
1218 return 0;
1219 n = 0;
1220 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1221 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1222 n++;
1223 }
1224 }
1225 return TCG_TARGET_NB_REGS - n + 1;
1226}
1227
1228/* sort from highest priority to lowest */
1229static void sort_constraints(TCGOpDef *def, int start, int n)
1230{
1231 int i, j, p1, p2, tmp;
1232
1233 for(i = 0; i < n; i++)
1234 def->sorted_args[start + i] = start + i;
1235 if (n <= 1)
1236 return;
1237 for(i = 0; i < n - 1; i++) {
1238 for(j = i + 1; j < n; j++) {
1239 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1240 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1241 if (p1 < p2) {
1242 tmp = def->sorted_args[start + i];
1243 def->sorted_args[start + i] = def->sorted_args[start + j];
1244 def->sorted_args[start + j] = tmp;
1245 }
1246 }
1247 }
1248}
1249
f69d277e 1250static void process_op_defs(TCGContext *s)
c896fe29 1251{
a9751609 1252 TCGOpcode op;
c896fe29 1253
f69d277e
RH
1254 for (op = 0; op < NB_OPS; op++) {
1255 TCGOpDef *def = &tcg_op_defs[op];
1256 const TCGTargetOpDef *tdefs;
069ea736
RH
1257 TCGType type;
1258 int i, nb_args;
f69d277e
RH
1259
1260 if (def->flags & TCG_OPF_NOT_PRESENT) {
1261 continue;
1262 }
1263
c896fe29 1264 nb_args = def->nb_iargs + def->nb_oargs;
f69d277e
RH
1265 if (nb_args == 0) {
1266 continue;
1267 }
1268
1269 tdefs = tcg_target_op_def(op);
1270 /* Missing TCGTargetOpDef entry. */
1271 tcg_debug_assert(tdefs != NULL);
1272
069ea736 1273 type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
f69d277e
RH
1274 for (i = 0; i < nb_args; i++) {
1275 const char *ct_str = tdefs->args_ct_str[i];
1276 /* Incomplete TCGTargetOpDef entry. */
eabb7b91 1277 tcg_debug_assert(ct_str != NULL);
f69d277e 1278
c896fe29
FB
1279 tcg_regset_clear(def->args_ct[i].u.regs);
1280 def->args_ct[i].ct = 0;
17280ff4
RH
1281 while (*ct_str != '\0') {
1282 switch(*ct_str) {
1283 case '0' ... '9':
1284 {
1285 int oarg = *ct_str - '0';
1286 tcg_debug_assert(ct_str == tdefs->args_ct_str[i]);
1287 tcg_debug_assert(oarg < def->nb_oargs);
1288 tcg_debug_assert(def->args_ct[oarg].ct & TCG_CT_REG);
1289 /* TCG_CT_ALIAS is for the output arguments.
1290 The input is tagged with TCG_CT_IALIAS. */
1291 def->args_ct[i] = def->args_ct[oarg];
1292 def->args_ct[oarg].ct |= TCG_CT_ALIAS;
1293 def->args_ct[oarg].alias_index = i;
1294 def->args_ct[i].ct |= TCG_CT_IALIAS;
1295 def->args_ct[i].alias_index = oarg;
c896fe29 1296 }
17280ff4
RH
1297 ct_str++;
1298 break;
1299 case '&':
1300 def->args_ct[i].ct |= TCG_CT_NEWREG;
1301 ct_str++;
1302 break;
1303 case 'i':
1304 def->args_ct[i].ct |= TCG_CT_CONST;
1305 ct_str++;
1306 break;
1307 default:
1308 ct_str = target_parse_constraint(&def->args_ct[i],
1309 ct_str, type);
1310 /* Typo in TCGTargetOpDef constraint. */
1311 tcg_debug_assert(ct_str != NULL);
c896fe29
FB
1312 }
1313 }
1314 }
1315
c68aaa18 1316 /* TCGTargetOpDef entry with too much information? */
eabb7b91 1317 tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
c68aaa18 1318
c896fe29
FB
1319 /* sort the constraints (XXX: this is just an heuristic) */
1320 sort_constraints(def, 0, def->nb_oargs);
1321 sort_constraints(def, def->nb_oargs, def->nb_iargs);
a9751609 1322 }
c896fe29
FB
1323}
1324
0c627cdc
RH
1325void tcg_op_remove(TCGContext *s, TCGOp *op)
1326{
1327 int next = op->next;
1328 int prev = op->prev;
1329
dcb8e758
RH
1330 /* We should never attempt to remove the list terminator. */
1331 tcg_debug_assert(op != &s->gen_op_buf[0]);
1332
1333 s->gen_op_buf[next].prev = prev;
1334 s->gen_op_buf[prev].next = next;
0c627cdc 1335
dcb8e758 1336 memset(op, 0, sizeof(*op));
0c627cdc
RH
1337
1338#ifdef CONFIG_PROFILER
1339 s->del_op_count++;
1340#endif
1341}
1342
5a18407f
RH
1343TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
1344 TCGOpcode opc, int nargs)
1345{
1346 int oi = s->gen_next_op_idx;
1347 int pi = s->gen_next_parm_idx;
1348 int prev = old_op->prev;
1349 int next = old_op - s->gen_op_buf;
1350 TCGOp *new_op;
1351
1352 tcg_debug_assert(oi < OPC_BUF_SIZE);
1353 tcg_debug_assert(pi + nargs <= OPPARAM_BUF_SIZE);
1354 s->gen_next_op_idx = oi + 1;
1355 s->gen_next_parm_idx = pi + nargs;
1356
1357 new_op = &s->gen_op_buf[oi];
1358 *new_op = (TCGOp){
1359 .opc = opc,
1360 .args = pi,
1361 .prev = prev,
1362 .next = next
1363 };
1364 s->gen_op_buf[prev].next = oi;
1365 old_op->prev = oi;
1366
1367 return new_op;
1368}
1369
1370TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
1371 TCGOpcode opc, int nargs)
1372{
1373 int oi = s->gen_next_op_idx;
1374 int pi = s->gen_next_parm_idx;
1375 int prev = old_op - s->gen_op_buf;
1376 int next = old_op->next;
1377 TCGOp *new_op;
1378
1379 tcg_debug_assert(oi < OPC_BUF_SIZE);
1380 tcg_debug_assert(pi + nargs <= OPPARAM_BUF_SIZE);
1381 s->gen_next_op_idx = oi + 1;
1382 s->gen_next_parm_idx = pi + nargs;
1383
1384 new_op = &s->gen_op_buf[oi];
1385 *new_op = (TCGOp){
1386 .opc = opc,
1387 .args = pi,
1388 .prev = prev,
1389 .next = next
1390 };
1391 s->gen_op_buf[next].prev = oi;
1392 old_op->next = oi;
1393
1394 return new_op;
1395}
1396
c70fbf0a
RH
1397#define TS_DEAD 1
1398#define TS_MEM 2
1399
5a18407f
RH
1400#define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
1401#define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
1402
9c43b68d
AJ
1403/* liveness analysis: end of function: all temps are dead, and globals
1404 should be in memory. */
c70fbf0a 1405static inline void tcg_la_func_end(TCGContext *s, uint8_t *temp_state)
c896fe29 1406{
c70fbf0a
RH
1407 memset(temp_state, TS_DEAD | TS_MEM, s->nb_globals);
1408 memset(temp_state + s->nb_globals, TS_DEAD, s->nb_temps - s->nb_globals);
c896fe29
FB
1409}
1410
9c43b68d
AJ
1411/* liveness analysis: end of basic block: all temps are dead, globals
1412 and local temps should be in memory. */
c70fbf0a 1413static inline void tcg_la_bb_end(TCGContext *s, uint8_t *temp_state)
641d5fbe 1414{
c70fbf0a 1415 int i, n;
641d5fbe 1416
c70fbf0a
RH
1417 tcg_la_func_end(s, temp_state);
1418 for (i = s->nb_globals, n = s->nb_temps; i < n; i++) {
1419 if (s->temps[i].temp_local) {
1420 temp_state[i] |= TS_MEM;
1421 }
641d5fbe
FB
1422 }
1423}
1424
a1b3c48d 1425/* Liveness analysis : update the opc_arg_life array to tell if a
c896fe29
FB
1426 given input arguments is dead. Instructions updating dead
1427 temporaries are removed. */
5a18407f 1428static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
c896fe29 1429{
c70fbf0a 1430 int nb_globals = s->nb_globals;
5a18407f 1431 int oi, oi_prev;
a1b3c48d 1432
c70fbf0a 1433 tcg_la_func_end(s, temp_state);
c896fe29 1434
dcb8e758 1435 for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) {
c45cb8bb
RH
1436 int i, nb_iargs, nb_oargs;
1437 TCGOpcode opc_new, opc_new2;
1438 bool have_opc_new2;
a1b3c48d 1439 TCGLifeData arg_life = 0;
c45cb8bb
RH
1440 TCGArg arg;
1441
1442 TCGOp * const op = &s->gen_op_buf[oi];
1443 TCGArg * const args = &s->gen_opparam_buf[op->args];
1444 TCGOpcode opc = op->opc;
1445 const TCGOpDef *def = &tcg_op_defs[opc];
1446
1447 oi_prev = op->prev;
1448
1449 switch (opc) {
c896fe29 1450 case INDEX_op_call:
c6e113f5
FB
1451 {
1452 int call_flags;
c896fe29 1453
c45cb8bb
RH
1454 nb_oargs = op->callo;
1455 nb_iargs = op->calli;
cf066674 1456 call_flags = args[nb_oargs + nb_iargs + 1];
c6e113f5 1457
c45cb8bb 1458 /* pure functions can be removed if their result is unused */
78505279 1459 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
cf066674 1460 for (i = 0; i < nb_oargs; i++) {
c6e113f5 1461 arg = args[i];
c70fbf0a 1462 if (temp_state[arg] != TS_DEAD) {
c6e113f5 1463 goto do_not_remove_call;
9c43b68d 1464 }
c6e113f5 1465 }
c45cb8bb 1466 goto do_remove;
c6e113f5
FB
1467 } else {
1468 do_not_remove_call:
c896fe29 1469
c6e113f5 1470 /* output args are dead */
cf066674 1471 for (i = 0; i < nb_oargs; i++) {
c6e113f5 1472 arg = args[i];
c70fbf0a 1473 if (temp_state[arg] & TS_DEAD) {
a1b3c48d 1474 arg_life |= DEAD_ARG << i;
6b64b624 1475 }
c70fbf0a 1476 if (temp_state[arg] & TS_MEM) {
a1b3c48d 1477 arg_life |= SYNC_ARG << i;
9c43b68d 1478 }
c70fbf0a 1479 temp_state[arg] = TS_DEAD;
c6e113f5 1480 }
78505279 1481
78505279
AJ
1482 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1483 TCG_CALL_NO_READ_GLOBALS))) {
9c43b68d 1484 /* globals should go back to memory */
c70fbf0a
RH
1485 memset(temp_state, TS_DEAD | TS_MEM, nb_globals);
1486 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1487 /* globals should be synced to memory */
1488 for (i = 0; i < nb_globals; i++) {
1489 temp_state[i] |= TS_MEM;
1490 }
b9c18f56
AJ
1491 }
1492
c19f47bf 1493 /* record arguments that die in this helper */
cf066674 1494 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 1495 arg = args[i];
39cf05d3 1496 if (arg != TCG_CALL_DUMMY_ARG) {
c70fbf0a 1497 if (temp_state[arg] & TS_DEAD) {
a1b3c48d 1498 arg_life |= DEAD_ARG << i;
39cf05d3 1499 }
c6e113f5 1500 }
c6e113f5 1501 }
67cc32eb 1502 /* input arguments are live for preceding opcodes */
c70fbf0a 1503 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
c19f47bf 1504 arg = args[i];
c70fbf0a
RH
1505 if (arg != TCG_CALL_DUMMY_ARG) {
1506 temp_state[arg] &= ~TS_DEAD;
1507 }
c19f47bf 1508 }
c896fe29 1509 }
c896fe29 1510 }
c896fe29 1511 break;
765b842a 1512 case INDEX_op_insn_start:
c896fe29 1513 break;
5ff9d6a4 1514 case INDEX_op_discard:
5ff9d6a4 1515 /* mark the temporary as dead */
c70fbf0a 1516 temp_state[args[0]] = TS_DEAD;
5ff9d6a4 1517 break;
1305c451
RH
1518
1519 case INDEX_op_add2_i32:
c45cb8bb 1520 opc_new = INDEX_op_add_i32;
f1fae40c 1521 goto do_addsub2;
1305c451 1522 case INDEX_op_sub2_i32:
c45cb8bb 1523 opc_new = INDEX_op_sub_i32;
f1fae40c
RH
1524 goto do_addsub2;
1525 case INDEX_op_add2_i64:
c45cb8bb 1526 opc_new = INDEX_op_add_i64;
f1fae40c
RH
1527 goto do_addsub2;
1528 case INDEX_op_sub2_i64:
c45cb8bb 1529 opc_new = INDEX_op_sub_i64;
f1fae40c 1530 do_addsub2:
1305c451
RH
1531 nb_iargs = 4;
1532 nb_oargs = 2;
1533 /* Test if the high part of the operation is dead, but not
1534 the low part. The result can be optimized to a simple
1535 add or sub. This happens often for x86_64 guest when the
1536 cpu mode is set to 32 bit. */
c70fbf0a
RH
1537 if (temp_state[args[1]] == TS_DEAD) {
1538 if (temp_state[args[0]] == TS_DEAD) {
1305c451
RH
1539 goto do_remove;
1540 }
c45cb8bb
RH
1541 /* Replace the opcode and adjust the args in place,
1542 leaving 3 unused args at the end. */
1543 op->opc = opc = opc_new;
1305c451
RH
1544 args[1] = args[2];
1545 args[2] = args[4];
1305c451
RH
1546 /* Fall through and mark the single-word operation live. */
1547 nb_iargs = 2;
1548 nb_oargs = 1;
1549 }
1550 goto do_not_remove;
1551
1414968a 1552 case INDEX_op_mulu2_i32:
c45cb8bb
RH
1553 opc_new = INDEX_op_mul_i32;
1554 opc_new2 = INDEX_op_muluh_i32;
1555 have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
03271524 1556 goto do_mul2;
f1fae40c 1557 case INDEX_op_muls2_i32:
c45cb8bb
RH
1558 opc_new = INDEX_op_mul_i32;
1559 opc_new2 = INDEX_op_mulsh_i32;
1560 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
f1fae40c
RH
1561 goto do_mul2;
1562 case INDEX_op_mulu2_i64:
c45cb8bb
RH
1563 opc_new = INDEX_op_mul_i64;
1564 opc_new2 = INDEX_op_muluh_i64;
1565 have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
03271524 1566 goto do_mul2;
f1fae40c 1567 case INDEX_op_muls2_i64:
c45cb8bb
RH
1568 opc_new = INDEX_op_mul_i64;
1569 opc_new2 = INDEX_op_mulsh_i64;
1570 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
03271524 1571 goto do_mul2;
f1fae40c 1572 do_mul2:
1414968a
RH
1573 nb_iargs = 2;
1574 nb_oargs = 2;
c70fbf0a
RH
1575 if (temp_state[args[1]] == TS_DEAD) {
1576 if (temp_state[args[0]] == TS_DEAD) {
03271524 1577 /* Both parts of the operation are dead. */
1414968a
RH
1578 goto do_remove;
1579 }
03271524 1580 /* The high part of the operation is dead; generate the low. */
c45cb8bb 1581 op->opc = opc = opc_new;
1414968a
RH
1582 args[1] = args[2];
1583 args[2] = args[3];
c70fbf0a 1584 } else if (temp_state[args[0]] == TS_DEAD && have_opc_new2) {
c45cb8bb
RH
1585 /* The low part of the operation is dead; generate the high. */
1586 op->opc = opc = opc_new2;
03271524
RH
1587 args[0] = args[1];
1588 args[1] = args[2];
1589 args[2] = args[3];
1590 } else {
1591 goto do_not_remove;
1414968a 1592 }
03271524
RH
1593 /* Mark the single-word operation live. */
1594 nb_oargs = 1;
1414968a
RH
1595 goto do_not_remove;
1596
c896fe29 1597 default:
1305c451 1598 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
49516bc0
AJ
1599 nb_iargs = def->nb_iargs;
1600 nb_oargs = def->nb_oargs;
c896fe29 1601
49516bc0
AJ
1602 /* Test if the operation can be removed because all
1603 its outputs are dead. We assume that nb_oargs == 0
1604 implies side effects */
1605 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
c45cb8bb 1606 for (i = 0; i < nb_oargs; i++) {
c70fbf0a 1607 if (temp_state[args[i]] != TS_DEAD) {
49516bc0 1608 goto do_not_remove;
9c43b68d 1609 }
49516bc0 1610 }
1305c451 1611 do_remove:
0c627cdc 1612 tcg_op_remove(s, op);
49516bc0
AJ
1613 } else {
1614 do_not_remove:
49516bc0 1615 /* output args are dead */
c45cb8bb 1616 for (i = 0; i < nb_oargs; i++) {
49516bc0 1617 arg = args[i];
c70fbf0a 1618 if (temp_state[arg] & TS_DEAD) {
a1b3c48d 1619 arg_life |= DEAD_ARG << i;
6b64b624 1620 }
c70fbf0a 1621 if (temp_state[arg] & TS_MEM) {
a1b3c48d 1622 arg_life |= SYNC_ARG << i;
9c43b68d 1623 }
c70fbf0a 1624 temp_state[arg] = TS_DEAD;
49516bc0
AJ
1625 }
1626
1627 /* if end of basic block, update */
1628 if (def->flags & TCG_OPF_BB_END) {
c70fbf0a 1629 tcg_la_bb_end(s, temp_state);
3d5c5f87
AJ
1630 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1631 /* globals should be synced to memory */
c70fbf0a
RH
1632 for (i = 0; i < nb_globals; i++) {
1633 temp_state[i] |= TS_MEM;
1634 }
49516bc0
AJ
1635 }
1636
c19f47bf 1637 /* record arguments that die in this opcode */
c45cb8bb 1638 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
866cb6cb 1639 arg = args[i];
c70fbf0a 1640 if (temp_state[arg] & TS_DEAD) {
a1b3c48d 1641 arg_life |= DEAD_ARG << i;
c896fe29 1642 }
c19f47bf 1643 }
67cc32eb 1644 /* input arguments are live for preceding opcodes */
c19f47bf 1645 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
c70fbf0a 1646 temp_state[args[i]] &= ~TS_DEAD;
c896fe29 1647 }
c896fe29
FB
1648 }
1649 break;
1650 }
bee158cb 1651 op->life = arg_life;
1ff0a2c5 1652 }
c896fe29 1653}
c896fe29 1654
5a18407f
RH
1655/* Liveness analysis: Convert indirect regs to direct temporaries. */
1656static bool liveness_pass_2(TCGContext *s, uint8_t *temp_state)
1657{
1658 int nb_globals = s->nb_globals;
1659 int16_t *dir_temps;
1660 int i, oi, oi_next;
1661 bool changes = false;
1662
1663 dir_temps = tcg_malloc(nb_globals * sizeof(int16_t));
1664 memset(dir_temps, 0, nb_globals * sizeof(int16_t));
1665
1666 /* Create a temporary for each indirect global. */
1667 for (i = 0; i < nb_globals; ++i) {
1668 TCGTemp *its = &s->temps[i];
1669 if (its->indirect_reg) {
1670 TCGTemp *dts = tcg_temp_alloc(s);
1671 dts->type = its->type;
1672 dts->base_type = its->base_type;
1673 dir_temps[i] = temp_idx(s, dts);
1674 }
1675 }
1676
1677 memset(temp_state, TS_DEAD, nb_globals);
1678
1679 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
1680 TCGOp *op = &s->gen_op_buf[oi];
1681 TCGArg *args = &s->gen_opparam_buf[op->args];
1682 TCGOpcode opc = op->opc;
1683 const TCGOpDef *def = &tcg_op_defs[opc];
1684 TCGLifeData arg_life = op->life;
1685 int nb_iargs, nb_oargs, call_flags;
1686 TCGArg arg, dir;
1687
1688 oi_next = op->next;
1689
1690 if (opc == INDEX_op_call) {
1691 nb_oargs = op->callo;
1692 nb_iargs = op->calli;
1693 call_flags = args[nb_oargs + nb_iargs + 1];
1694 } else {
1695 nb_iargs = def->nb_iargs;
1696 nb_oargs = def->nb_oargs;
1697
1698 /* Set flags similar to how calls require. */
1699 if (def->flags & TCG_OPF_BB_END) {
1700 /* Like writing globals: save_globals */
1701 call_flags = 0;
1702 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1703 /* Like reading globals: sync_globals */
1704 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
1705 } else {
1706 /* No effect on globals. */
1707 call_flags = (TCG_CALL_NO_READ_GLOBALS |
1708 TCG_CALL_NO_WRITE_GLOBALS);
1709 }
1710 }
1711
1712 /* Make sure that input arguments are available. */
1713 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1714 arg = args[i];
1715 /* Note this unsigned test catches TCG_CALL_ARG_DUMMY too. */
1716 if (arg < nb_globals) {
1717 dir = dir_temps[arg];
1718 if (dir != 0 && temp_state[arg] == TS_DEAD) {
1719 TCGTemp *its = &s->temps[arg];
1720 TCGOpcode lopc = (its->type == TCG_TYPE_I32
1721 ? INDEX_op_ld_i32
1722 : INDEX_op_ld_i64);
1723 TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
1724 TCGArg *largs = &s->gen_opparam_buf[lop->args];
1725
1726 largs[0] = dir;
1727 largs[1] = temp_idx(s, its->mem_base);
1728 largs[2] = its->mem_offset;
1729
1730 /* Loaded, but synced with memory. */
1731 temp_state[arg] = TS_MEM;
1732 }
1733 }
1734 }
1735
1736 /* Perform input replacement, and mark inputs that became dead.
1737 No action is required except keeping temp_state up to date
1738 so that we reload when needed. */
1739 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1740 arg = args[i];
1741 if (arg < nb_globals) {
1742 dir = dir_temps[arg];
1743 if (dir != 0) {
1744 args[i] = dir;
1745 changes = true;
1746 if (IS_DEAD_ARG(i)) {
1747 temp_state[arg] = TS_DEAD;
1748 }
1749 }
1750 }
1751 }
1752
1753 /* Liveness analysis should ensure that the following are
1754 all correct, for call sites and basic block end points. */
1755 if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
1756 /* Nothing to do */
1757 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
1758 for (i = 0; i < nb_globals; ++i) {
1759 /* Liveness should see that globals are synced back,
1760 that is, either TS_DEAD or TS_MEM. */
1761 tcg_debug_assert(dir_temps[i] == 0
1762 || temp_state[i] != 0);
1763 }
1764 } else {
1765 for (i = 0; i < nb_globals; ++i) {
1766 /* Liveness should see that globals are saved back,
1767 that is, TS_DEAD, waiting to be reloaded. */
1768 tcg_debug_assert(dir_temps[i] == 0
1769 || temp_state[i] == TS_DEAD);
1770 }
1771 }
1772
1773 /* Outputs become available. */
1774 for (i = 0; i < nb_oargs; i++) {
1775 arg = args[i];
1776 if (arg >= nb_globals) {
1777 continue;
1778 }
1779 dir = dir_temps[arg];
1780 if (dir == 0) {
1781 continue;
1782 }
1783 args[i] = dir;
1784 changes = true;
1785
1786 /* The output is now live and modified. */
1787 temp_state[arg] = 0;
1788
1789 /* Sync outputs upon their last write. */
1790 if (NEED_SYNC_ARG(i)) {
1791 TCGTemp *its = &s->temps[arg];
1792 TCGOpcode sopc = (its->type == TCG_TYPE_I32
1793 ? INDEX_op_st_i32
1794 : INDEX_op_st_i64);
1795 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
1796 TCGArg *sargs = &s->gen_opparam_buf[sop->args];
1797
1798 sargs[0] = dir;
1799 sargs[1] = temp_idx(s, its->mem_base);
1800 sargs[2] = its->mem_offset;
1801
1802 temp_state[arg] = TS_MEM;
1803 }
1804 /* Drop outputs that are dead. */
1805 if (IS_DEAD_ARG(i)) {
1806 temp_state[arg] = TS_DEAD;
1807 }
1808 }
1809 }
1810
1811 return changes;
1812}
1813
8d8fdbae 1814#ifdef CONFIG_DEBUG_TCG
c896fe29
FB
1815static void dump_regs(TCGContext *s)
1816{
1817 TCGTemp *ts;
1818 int i;
1819 char buf[64];
1820
1821 for(i = 0; i < s->nb_temps; i++) {
1822 ts = &s->temps[i];
ac56dd48 1823 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
c896fe29
FB
1824 switch(ts->val_type) {
1825 case TEMP_VAL_REG:
1826 printf("%s", tcg_target_reg_names[ts->reg]);
1827 break;
1828 case TEMP_VAL_MEM:
b3a62939
RH
1829 printf("%d(%s)", (int)ts->mem_offset,
1830 tcg_target_reg_names[ts->mem_base->reg]);
c896fe29
FB
1831 break;
1832 case TEMP_VAL_CONST:
1833 printf("$0x%" TCG_PRIlx, ts->val);
1834 break;
1835 case TEMP_VAL_DEAD:
1836 printf("D");
1837 break;
1838 default:
1839 printf("???");
1840 break;
1841 }
1842 printf("\n");
1843 }
1844
1845 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
f8b2f202 1846 if (s->reg_to_temp[i] != NULL) {
c896fe29
FB
1847 printf("%s: %s\n",
1848 tcg_target_reg_names[i],
f8b2f202 1849 tcg_get_arg_str_ptr(s, buf, sizeof(buf), s->reg_to_temp[i]));
c896fe29
FB
1850 }
1851 }
1852}
1853
1854static void check_regs(TCGContext *s)
1855{
869938ae 1856 int reg;
b6638662 1857 int k;
c896fe29
FB
1858 TCGTemp *ts;
1859 char buf[64];
1860
f8b2f202
RH
1861 for (reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1862 ts = s->reg_to_temp[reg];
1863 if (ts != NULL) {
1864 if (ts->val_type != TEMP_VAL_REG || ts->reg != reg) {
c896fe29
FB
1865 printf("Inconsistency for register %s:\n",
1866 tcg_target_reg_names[reg]);
b03cce8e 1867 goto fail;
c896fe29
FB
1868 }
1869 }
1870 }
f8b2f202 1871 for (k = 0; k < s->nb_temps; k++) {
c896fe29 1872 ts = &s->temps[k];
f8b2f202
RH
1873 if (ts->val_type == TEMP_VAL_REG && !ts->fixed_reg
1874 && s->reg_to_temp[ts->reg] != ts) {
1875 printf("Inconsistency for temp %s:\n",
1876 tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
b03cce8e 1877 fail:
f8b2f202
RH
1878 printf("reg state:\n");
1879 dump_regs(s);
1880 tcg_abort();
c896fe29
FB
1881 }
1882 }
1883}
1884#endif
1885
1886static void temp_allocate_frame(TCGContext *s, int temp)
1887{
1888 TCGTemp *ts;
1889 ts = &s->temps[temp];
9b9c37c3
RH
1890#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1891 /* Sparc64 stack is accessed with offset of 2047 */
b591dc59
BS
1892 s->current_frame_offset = (s->current_frame_offset +
1893 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1894 ~(sizeof(tcg_target_long) - 1);
f44c9960 1895#endif
b591dc59
BS
1896 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1897 s->frame_end) {
5ff9d6a4 1898 tcg_abort();
b591dc59 1899 }
c896fe29 1900 ts->mem_offset = s->current_frame_offset;
b3a62939 1901 ts->mem_base = s->frame_temp;
c896fe29 1902 ts->mem_allocated = 1;
e2c6d1b4 1903 s->current_frame_offset += sizeof(tcg_target_long);
c896fe29
FB
1904}
1905
b3915dbb
RH
1906static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
1907
59d7c14e
RH
1908/* Mark a temporary as free or dead. If 'free_or_dead' is negative,
1909 mark it free; otherwise mark it dead. */
1910static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
7f6ceedf 1911{
59d7c14e
RH
1912 if (ts->fixed_reg) {
1913 return;
1914 }
1915 if (ts->val_type == TEMP_VAL_REG) {
1916 s->reg_to_temp[ts->reg] = NULL;
1917 }
1918 ts->val_type = (free_or_dead < 0
1919 || ts->temp_local
1920 || temp_idx(s, ts) < s->nb_globals
1921 ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
1922}
7f6ceedf 1923
59d7c14e
RH
1924/* Mark a temporary as dead. */
1925static inline void temp_dead(TCGContext *s, TCGTemp *ts)
1926{
1927 temp_free_or_dead(s, ts, 1);
1928}
1929
1930/* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
1931 registers needs to be allocated to store a constant. If 'free_or_dead'
1932 is non-zero, subsequently release the temporary; if it is positive, the
1933 temp is dead; if it is negative, the temp is free. */
1934static void temp_sync(TCGContext *s, TCGTemp *ts,
1935 TCGRegSet allocated_regs, int free_or_dead)
1936{
1937 if (ts->fixed_reg) {
1938 return;
1939 }
1940 if (!ts->mem_coherent) {
7f6ceedf 1941 if (!ts->mem_allocated) {
f8b2f202 1942 temp_allocate_frame(s, temp_idx(s, ts));
59d7c14e 1943 }
59d7c14e
RH
1944 switch (ts->val_type) {
1945 case TEMP_VAL_CONST:
1946 /* If we're going to free the temp immediately, then we won't
1947 require it later in a register, so attempt to store the
1948 constant to memory directly. */
1949 if (free_or_dead
1950 && tcg_out_sti(s, ts->type, ts->val,
1951 ts->mem_base->reg, ts->mem_offset)) {
1952 break;
1953 }
1954 temp_load(s, ts, tcg_target_available_regs[ts->type],
1955 allocated_regs);
1956 /* fallthrough */
1957
1958 case TEMP_VAL_REG:
1959 tcg_out_st(s, ts->type, ts->reg,
1960 ts->mem_base->reg, ts->mem_offset);
1961 break;
1962
1963 case TEMP_VAL_MEM:
1964 break;
1965
1966 case TEMP_VAL_DEAD:
1967 default:
1968 tcg_abort();
1969 }
1970 ts->mem_coherent = 1;
1971 }
1972 if (free_or_dead) {
1973 temp_free_or_dead(s, ts, free_or_dead);
7f6ceedf 1974 }
7f6ceedf
AJ
1975}
1976
c896fe29 1977/* free register 'reg' by spilling the corresponding temporary if necessary */
b3915dbb 1978static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
c896fe29 1979{
f8b2f202 1980 TCGTemp *ts = s->reg_to_temp[reg];
f8b2f202 1981 if (ts != NULL) {
59d7c14e 1982 temp_sync(s, ts, allocated_regs, -1);
c896fe29
FB
1983 }
1984}
1985
1986/* Allocate a register belonging to reg1 & ~reg2 */
b3915dbb 1987static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
91478cef 1988 TCGRegSet allocated_regs, bool rev)
c896fe29 1989{
91478cef
RH
1990 int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
1991 const int *order;
b6638662 1992 TCGReg reg;
c896fe29
FB
1993 TCGRegSet reg_ct;
1994
b3915dbb 1995 tcg_regset_andnot(reg_ct, desired_regs, allocated_regs);
91478cef 1996 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
c896fe29
FB
1997
1998 /* first try free registers */
91478cef
RH
1999 for(i = 0; i < n; i++) {
2000 reg = order[i];
f8b2f202 2001 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
c896fe29
FB
2002 return reg;
2003 }
2004
2005 /* XXX: do better spill choice */
91478cef
RH
2006 for(i = 0; i < n; i++) {
2007 reg = order[i];
c896fe29 2008 if (tcg_regset_test_reg(reg_ct, reg)) {
b3915dbb 2009 tcg_reg_free(s, reg, allocated_regs);
c896fe29
FB
2010 return reg;
2011 }
2012 }
2013
2014 tcg_abort();
2015}
2016
40ae5c62
RH
2017/* Make sure the temporary is in a register. If needed, allocate the register
2018 from DESIRED while avoiding ALLOCATED. */
2019static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
2020 TCGRegSet allocated_regs)
2021{
2022 TCGReg reg;
2023
2024 switch (ts->val_type) {
2025 case TEMP_VAL_REG:
2026 return;
2027 case TEMP_VAL_CONST:
91478cef 2028 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
40ae5c62
RH
2029 tcg_out_movi(s, ts->type, reg, ts->val);
2030 ts->mem_coherent = 0;
2031 break;
2032 case TEMP_VAL_MEM:
91478cef 2033 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
40ae5c62
RH
2034 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
2035 ts->mem_coherent = 1;
2036 break;
2037 case TEMP_VAL_DEAD:
2038 default:
2039 tcg_abort();
2040 }
2041 ts->reg = reg;
2042 ts->val_type = TEMP_VAL_REG;
2043 s->reg_to_temp[reg] = ts;
2044}
2045
59d7c14e
RH
2046/* Save a temporary to memory. 'allocated_regs' is used in case a
2047 temporary registers needs to be allocated to store a constant. */
2048static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
1ad80729 2049{
5a18407f
RH
2050 /* The liveness analysis already ensures that globals are back
2051 in memory. Keep an tcg_debug_assert for safety. */
2052 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
1ad80729
AJ
2053}
2054
9814dd27 2055/* save globals to their canonical location and assume they can be
e8996ee0
FB
2056 modified be the following code. 'allocated_regs' is used in case a
2057 temporary registers needs to be allocated to store a constant. */
2058static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
c896fe29 2059{
641d5fbe 2060 int i;
c896fe29 2061
b13eb728
RH
2062 for (i = 0; i < s->nb_globals; i++) {
2063 temp_save(s, &s->temps[i], allocated_regs);
c896fe29 2064 }
e5097dc8
FB
2065}
2066
3d5c5f87
AJ
2067/* sync globals to their canonical location and assume they can be
2068 read by the following code. 'allocated_regs' is used in case a
2069 temporary registers needs to be allocated to store a constant. */
2070static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
2071{
2072 int i;
2073
2074 for (i = 0; i < s->nb_globals; i++) {
12b9b11a 2075 TCGTemp *ts = &s->temps[i];
5a18407f
RH
2076 tcg_debug_assert(ts->val_type != TEMP_VAL_REG
2077 || ts->fixed_reg
2078 || ts->mem_coherent);
3d5c5f87
AJ
2079 }
2080}
2081
e5097dc8 2082/* at the end of a basic block, we assume all temporaries are dead and
e8996ee0
FB
2083 all globals are stored at their canonical location. */
2084static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
e5097dc8 2085{
e5097dc8
FB
2086 int i;
2087
b13eb728
RH
2088 for (i = s->nb_globals; i < s->nb_temps; i++) {
2089 TCGTemp *ts = &s->temps[i];
641d5fbe 2090 if (ts->temp_local) {
b13eb728 2091 temp_save(s, ts, allocated_regs);
641d5fbe 2092 } else {
5a18407f
RH
2093 /* The liveness analysis already ensures that temps are dead.
2094 Keep an tcg_debug_assert for safety. */
2095 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
c896fe29
FB
2096 }
2097 }
e8996ee0
FB
2098
2099 save_globals(s, allocated_regs);
c896fe29
FB
2100}
2101
0fe4fca4
PB
2102static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
2103 tcg_target_ulong val, TCGLifeData arg_life)
e8996ee0 2104{
e8996ee0 2105 if (ots->fixed_reg) {
59d7c14e 2106 /* For fixed registers, we do not do any constant propagation. */
e8996ee0 2107 tcg_out_movi(s, ots->type, ots->reg, val);
59d7c14e 2108 return;
e8996ee0 2109 }
59d7c14e
RH
2110
2111 /* The movi is not explicitly generated here. */
2112 if (ots->val_type == TEMP_VAL_REG) {
2113 s->reg_to_temp[ots->reg] = NULL;
ec7a869d 2114 }
59d7c14e
RH
2115 ots->val_type = TEMP_VAL_CONST;
2116 ots->val = val;
2117 ots->mem_coherent = 0;
2118 if (NEED_SYNC_ARG(0)) {
2119 temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0));
2120 } else if (IS_DEAD_ARG(0)) {
f8bf00f1 2121 temp_dead(s, ots);
4c4e1ab2 2122 }
e8996ee0
FB
2123}
2124
0fe4fca4
PB
2125static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
2126 TCGLifeData arg_life)
2127{
2128 TCGTemp *ots = &s->temps[args[0]];
2129 tcg_target_ulong val = args[1];
2130
2131 tcg_reg_alloc_do_movi(s, ots, val, arg_life);
2132}
2133
c896fe29 2134static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
a1b3c48d 2135 const TCGArg *args, TCGLifeData arg_life)
c896fe29 2136{
c29c1d7e 2137 TCGRegSet allocated_regs;
c896fe29 2138 TCGTemp *ts, *ots;
450445d5 2139 TCGType otype, itype;
c896fe29 2140
c29c1d7e 2141 tcg_regset_set(allocated_regs, s->reserved_regs);
c896fe29
FB
2142 ots = &s->temps[args[0]];
2143 ts = &s->temps[args[1]];
450445d5
RH
2144
2145 /* Note that otype != itype for no-op truncation. */
2146 otype = ots->type;
2147 itype = ts->type;
c29c1d7e 2148
0fe4fca4
PB
2149 if (ts->val_type == TEMP_VAL_CONST) {
2150 /* propagate constant or generate sti */
2151 tcg_target_ulong val = ts->val;
2152 if (IS_DEAD_ARG(1)) {
2153 temp_dead(s, ts);
2154 }
2155 tcg_reg_alloc_do_movi(s, ots, val, arg_life);
2156 return;
2157 }
2158
2159 /* If the source value is in memory we're going to be forced
2160 to have it in a register in order to perform the copy. Copy
2161 the SOURCE value into its own register first, that way we
2162 don't have to reload SOURCE the next time it is used. */
2163 if (ts->val_type == TEMP_VAL_MEM) {
40ae5c62 2164 temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs);
c29c1d7e 2165 }
c896fe29 2166
0fe4fca4 2167 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
c29c1d7e
AJ
2168 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
2169 /* mov to a non-saved dead register makes no sense (even with
2170 liveness analysis disabled). */
eabb7b91 2171 tcg_debug_assert(NEED_SYNC_ARG(0));
c29c1d7e
AJ
2172 if (!ots->mem_allocated) {
2173 temp_allocate_frame(s, args[0]);
2174 }
b3a62939 2175 tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
c29c1d7e 2176 if (IS_DEAD_ARG(1)) {
f8bf00f1 2177 temp_dead(s, ts);
c29c1d7e 2178 }
f8bf00f1 2179 temp_dead(s, ots);
c29c1d7e 2180 } else {
866cb6cb 2181 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
c896fe29 2182 /* the mov can be suppressed */
c29c1d7e 2183 if (ots->val_type == TEMP_VAL_REG) {
f8b2f202 2184 s->reg_to_temp[ots->reg] = NULL;
c29c1d7e
AJ
2185 }
2186 ots->reg = ts->reg;
f8bf00f1 2187 temp_dead(s, ts);
c896fe29 2188 } else {
c29c1d7e
AJ
2189 if (ots->val_type != TEMP_VAL_REG) {
2190 /* When allocating a new register, make sure to not spill the
2191 input one. */
2192 tcg_regset_set_reg(allocated_regs, ts->reg);
450445d5 2193 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
91478cef 2194 allocated_regs, ots->indirect_base);
c896fe29 2195 }
450445d5 2196 tcg_out_mov(s, otype, ots->reg, ts->reg);
c896fe29 2197 }
c29c1d7e
AJ
2198 ots->val_type = TEMP_VAL_REG;
2199 ots->mem_coherent = 0;
f8b2f202 2200 s->reg_to_temp[ots->reg] = ots;
c29c1d7e 2201 if (NEED_SYNC_ARG(0)) {
59d7c14e 2202 temp_sync(s, ots, allocated_regs, 0);
c896fe29 2203 }
ec7a869d 2204 }
c896fe29
FB
2205}
2206
2207static void tcg_reg_alloc_op(TCGContext *s,
a9751609 2208 const TCGOpDef *def, TCGOpcode opc,
a1b3c48d 2209 const TCGArg *args, TCGLifeData arg_life)
c896fe29 2210{
82790a87
RH
2211 TCGRegSet i_allocated_regs;
2212 TCGRegSet o_allocated_regs;
b6638662
RH
2213 int i, k, nb_iargs, nb_oargs;
2214 TCGReg reg;
c896fe29
FB
2215 TCGArg arg;
2216 const TCGArgConstraint *arg_ct;
2217 TCGTemp *ts;
2218 TCGArg new_args[TCG_MAX_OP_ARGS];
2219 int const_args[TCG_MAX_OP_ARGS];
2220
2221 nb_oargs = def->nb_oargs;
2222 nb_iargs = def->nb_iargs;
2223
2224 /* copy constants */
2225 memcpy(new_args + nb_oargs + nb_iargs,
2226 args + nb_oargs + nb_iargs,
2227 sizeof(TCGArg) * def->nb_cargs);
2228
82790a87
RH
2229 tcg_regset_set(i_allocated_regs, s->reserved_regs);
2230 tcg_regset_set(o_allocated_regs, s->reserved_regs);
2231
c896fe29 2232 /* satisfy input constraints */
c896fe29
FB
2233 for(k = 0; k < nb_iargs; k++) {
2234 i = def->sorted_args[nb_oargs + k];
2235 arg = args[i];
2236 arg_ct = &def->args_ct[i];
2237 ts = &s->temps[arg];
40ae5c62
RH
2238
2239 if (ts->val_type == TEMP_VAL_CONST
2240 && tcg_target_const_match(ts->val, ts->type, arg_ct)) {
2241 /* constant is OK for instruction */
2242 const_args[i] = 1;
2243 new_args[i] = ts->val;
2244 goto iarg_end;
c896fe29 2245 }
40ae5c62 2246
82790a87 2247 temp_load(s, ts, arg_ct->u.regs, i_allocated_regs);
40ae5c62 2248
5ff9d6a4
FB
2249 if (arg_ct->ct & TCG_CT_IALIAS) {
2250 if (ts->fixed_reg) {
2251 /* if fixed register, we must allocate a new register
2252 if the alias is not the same register */
2253 if (arg != args[arg_ct->alias_index])
2254 goto allocate_in_reg;
2255 } else {
2256 /* if the input is aliased to an output and if it is
2257 not dead after the instruction, we must allocate
2258 a new register and move it */
866cb6cb 2259 if (!IS_DEAD_ARG(i)) {
5ff9d6a4 2260 goto allocate_in_reg;
866cb6cb 2261 }
7e1df267
AJ
2262 /* check if the current register has already been allocated
2263 for another input aliased to an output */
2264 int k2, i2;
2265 for (k2 = 0 ; k2 < k ; k2++) {
2266 i2 = def->sorted_args[nb_oargs + k2];
2267 if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
2268 (new_args[i2] == ts->reg)) {
2269 goto allocate_in_reg;
2270 }
2271 }
5ff9d6a4 2272 }
c896fe29
FB
2273 }
2274 reg = ts->reg;
2275 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2276 /* nothing to do : the constraint is satisfied */
2277 } else {
2278 allocate_in_reg:
2279 /* allocate a new register matching the constraint
2280 and move the temporary register into it */
82790a87 2281 reg = tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs,
91478cef 2282 ts->indirect_base);
3b6dac34 2283 tcg_out_mov(s, ts->type, reg, ts->reg);
c896fe29 2284 }
c896fe29
FB
2285 new_args[i] = reg;
2286 const_args[i] = 0;
82790a87 2287 tcg_regset_set_reg(i_allocated_regs, reg);
c896fe29
FB
2288 iarg_end: ;
2289 }
2290
a52ad07e
AJ
2291 /* mark dead temporaries and free the associated registers */
2292 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2293 if (IS_DEAD_ARG(i)) {
f8bf00f1 2294 temp_dead(s, &s->temps[args[i]]);
a52ad07e
AJ
2295 }
2296 }
2297
e8996ee0 2298 if (def->flags & TCG_OPF_BB_END) {
82790a87 2299 tcg_reg_alloc_bb_end(s, i_allocated_regs);
e8996ee0 2300 } else {
e8996ee0
FB
2301 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2302 /* XXX: permit generic clobber register list ? */
c8074023
RH
2303 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
2304 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
82790a87 2305 tcg_reg_free(s, i, i_allocated_regs);
e8996ee0 2306 }
c896fe29 2307 }
3d5c5f87
AJ
2308 }
2309 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2310 /* sync globals if the op has side effects and might trigger
2311 an exception. */
82790a87 2312 sync_globals(s, i_allocated_regs);
c896fe29 2313 }
e8996ee0
FB
2314
2315 /* satisfy the output constraints */
e8996ee0
FB
2316 for(k = 0; k < nb_oargs; k++) {
2317 i = def->sorted_args[k];
2318 arg = args[i];
2319 arg_ct = &def->args_ct[i];
2320 ts = &s->temps[arg];
17280ff4
RH
2321 if ((arg_ct->ct & TCG_CT_ALIAS)
2322 && !const_args[arg_ct->alias_index]) {
e8996ee0 2323 reg = new_args[arg_ct->alias_index];
82790a87
RH
2324 } else if (arg_ct->ct & TCG_CT_NEWREG) {
2325 reg = tcg_reg_alloc(s, arg_ct->u.regs,
2326 i_allocated_regs | o_allocated_regs,
2327 ts->indirect_base);
e8996ee0
FB
2328 } else {
2329 /* if fixed register, we try to use it */
2330 reg = ts->reg;
2331 if (ts->fixed_reg &&
2332 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2333 goto oarg_end;
2334 }
82790a87 2335 reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
91478cef 2336 ts->indirect_base);
c896fe29 2337 }
82790a87 2338 tcg_regset_set_reg(o_allocated_regs, reg);
e8996ee0
FB
2339 /* if a fixed register is used, then a move will be done afterwards */
2340 if (!ts->fixed_reg) {
ec7a869d 2341 if (ts->val_type == TEMP_VAL_REG) {
f8b2f202 2342 s->reg_to_temp[ts->reg] = NULL;
ec7a869d
AJ
2343 }
2344 ts->val_type = TEMP_VAL_REG;
2345 ts->reg = reg;
2346 /* temp value is modified, so the value kept in memory is
2347 potentially not the same */
2348 ts->mem_coherent = 0;
f8b2f202 2349 s->reg_to_temp[reg] = ts;
e8996ee0
FB
2350 }
2351 oarg_end:
2352 new_args[i] = reg;
c896fe29 2353 }
c896fe29
FB
2354 }
2355
c896fe29
FB
2356 /* emit instruction */
2357 tcg_out_op(s, opc, new_args, const_args);
2358
2359 /* move the outputs in the correct register if needed */
2360 for(i = 0; i < nb_oargs; i++) {
2361 ts = &s->temps[args[i]];
2362 reg = new_args[i];
2363 if (ts->fixed_reg && ts->reg != reg) {
3b6dac34 2364 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29 2365 }
ec7a869d 2366 if (NEED_SYNC_ARG(i)) {
82790a87 2367 temp_sync(s, ts, o_allocated_regs, IS_DEAD_ARG(i));
59d7c14e 2368 } else if (IS_DEAD_ARG(i)) {
f8bf00f1 2369 temp_dead(s, ts);
ec7a869d 2370 }
c896fe29
FB
2371 }
2372}
2373
b03cce8e
FB
2374#ifdef TCG_TARGET_STACK_GROWSUP
2375#define STACK_DIR(x) (-(x))
2376#else
2377#define STACK_DIR(x) (x)
2378#endif
2379
c45cb8bb 2380static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
a1b3c48d 2381 const TCGArg * const args, TCGLifeData arg_life)
c896fe29 2382{
b6638662
RH
2383 int flags, nb_regs, i;
2384 TCGReg reg;
cf066674 2385 TCGArg arg;
c896fe29 2386 TCGTemp *ts;
d3452f1f
RH
2387 intptr_t stack_offset;
2388 size_t call_stack_size;
cf066674
RH
2389 tcg_insn_unit *func_addr;
2390 int allocate_args;
c896fe29 2391 TCGRegSet allocated_regs;
c896fe29 2392
cf066674
RH
2393 func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs];
2394 flags = args[nb_oargs + nb_iargs + 1];
c896fe29 2395
6e17d0c5 2396 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
c45cb8bb
RH
2397 if (nb_regs > nb_iargs) {
2398 nb_regs = nb_iargs;
cf066674 2399 }
c896fe29
FB
2400
2401 /* assign stack slots first */
c45cb8bb 2402 call_stack_size = (nb_iargs - nb_regs) * sizeof(tcg_target_long);
c896fe29
FB
2403 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2404 ~(TCG_TARGET_STACK_ALIGN - 1);
b03cce8e
FB
2405 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2406 if (allocate_args) {
345649c0
BS
2407 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2408 preallocate call stack */
2409 tcg_abort();
b03cce8e 2410 }
39cf05d3
FB
2411
2412 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
c45cb8bb 2413 for(i = nb_regs; i < nb_iargs; i++) {
c896fe29 2414 arg = args[nb_oargs + i];
39cf05d3
FB
2415#ifdef TCG_TARGET_STACK_GROWSUP
2416 stack_offset -= sizeof(tcg_target_long);
2417#endif
2418 if (arg != TCG_CALL_DUMMY_ARG) {
2419 ts = &s->temps[arg];
40ae5c62
RH
2420 temp_load(s, ts, tcg_target_available_regs[ts->type],
2421 s->reserved_regs);
2422 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
c896fe29 2423 }
39cf05d3
FB
2424#ifndef TCG_TARGET_STACK_GROWSUP
2425 stack_offset += sizeof(tcg_target_long);
2426#endif
c896fe29
FB
2427 }
2428
2429 /* assign input registers */
2430 tcg_regset_set(allocated_regs, s->reserved_regs);
2431 for(i = 0; i < nb_regs; i++) {
2432 arg = args[nb_oargs + i];
39cf05d3
FB
2433 if (arg != TCG_CALL_DUMMY_ARG) {
2434 ts = &s->temps[arg];
2435 reg = tcg_target_call_iarg_regs[i];
b3915dbb 2436 tcg_reg_free(s, reg, allocated_regs);
40ae5c62 2437
39cf05d3
FB
2438 if (ts->val_type == TEMP_VAL_REG) {
2439 if (ts->reg != reg) {
3b6dac34 2440 tcg_out_mov(s, ts->type, reg, ts->reg);
39cf05d3 2441 }
39cf05d3 2442 } else {
40ae5c62
RH
2443 TCGRegSet arg_set;
2444
2445 tcg_regset_clear(arg_set);
2446 tcg_regset_set_reg(arg_set, reg);
2447 temp_load(s, ts, arg_set, allocated_regs);
c896fe29 2448 }
40ae5c62 2449
39cf05d3 2450 tcg_regset_set_reg(allocated_regs, reg);
c896fe29 2451 }
c896fe29
FB
2452 }
2453
c896fe29 2454 /* mark dead temporaries and free the associated registers */
866cb6cb 2455 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 2456 if (IS_DEAD_ARG(i)) {
f8bf00f1 2457 temp_dead(s, &s->temps[args[i]]);
c896fe29
FB
2458 }
2459 }
2460
2461 /* clobber call registers */
c8074023
RH
2462 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
2463 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
b3915dbb 2464 tcg_reg_free(s, i, allocated_regs);
c896fe29
FB
2465 }
2466 }
78505279
AJ
2467
2468 /* Save globals if they might be written by the helper, sync them if
2469 they might be read. */
2470 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2471 /* Nothing to do */
2472 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2473 sync_globals(s, allocated_regs);
2474 } else {
b9c18f56
AJ
2475 save_globals(s, allocated_regs);
2476 }
c896fe29 2477
cf066674 2478 tcg_out_call(s, func_addr);
c896fe29
FB
2479
2480 /* assign output registers and emit moves if needed */
2481 for(i = 0; i < nb_oargs; i++) {
2482 arg = args[i];
2483 ts = &s->temps[arg];
2484 reg = tcg_target_call_oarg_regs[i];
eabb7b91 2485 tcg_debug_assert(s->reg_to_temp[reg] == NULL);
34b1a49c 2486
c896fe29
FB
2487 if (ts->fixed_reg) {
2488 if (ts->reg != reg) {
3b6dac34 2489 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29
FB
2490 }
2491 } else {
ec7a869d 2492 if (ts->val_type == TEMP_VAL_REG) {
f8b2f202 2493 s->reg_to_temp[ts->reg] = NULL;
ec7a869d
AJ
2494 }
2495 ts->val_type = TEMP_VAL_REG;
2496 ts->reg = reg;
2497 ts->mem_coherent = 0;
f8b2f202 2498 s->reg_to_temp[reg] = ts;
ec7a869d 2499 if (NEED_SYNC_ARG(i)) {
59d7c14e
RH
2500 temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
2501 } else if (IS_DEAD_ARG(i)) {
f8bf00f1 2502 temp_dead(s, ts);
8c11ad25 2503 }
c896fe29
FB
2504 }
2505 }
c896fe29
FB
2506}
2507
2508#ifdef CONFIG_PROFILER
2509
54604f74 2510static int64_t tcg_table_op_count[NB_OPS];
c896fe29 2511
246ae24d 2512void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
c896fe29
FB
2513{
2514 int i;
d70724ce 2515
15fc7daa 2516 for (i = 0; i < NB_OPS; i++) {
246ae24d
MF
2517 cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name,
2518 tcg_table_op_count[i]);
c896fe29 2519 }
c896fe29 2520}
246ae24d
MF
2521#else
2522void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
2523{
2524 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2525}
c896fe29
FB
2526#endif
2527
2528
5bd2ec3d 2529int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
c896fe29 2530{
fca8a500 2531 int i, oi, oi_next, num_insns;
c896fe29 2532
04fe6400
RH
2533#ifdef CONFIG_PROFILER
2534 {
2535 int n;
2536
dcb8e758 2537 n = s->gen_op_buf[0].prev + 1;
04fe6400
RH
2538 s->op_count += n;
2539 if (n > s->op_count_max) {
2540 s->op_count_max = n;
2541 }
2542
2543 n = s->nb_temps;
2544 s->temp_count += n;
2545 if (n > s->temp_count_max) {
2546 s->temp_count_max = n;
2547 }
2548 }
2549#endif
2550
c896fe29 2551#ifdef DEBUG_DISAS
d977e1c2
AB
2552 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
2553 && qemu_log_in_addr_range(tb->pc))) {
1ee73216 2554 qemu_log_lock();
93fcfe39 2555 qemu_log("OP:\n");
eeacee4d 2556 tcg_dump_ops(s);
93fcfe39 2557 qemu_log("\n");
1ee73216 2558 qemu_log_unlock();
c896fe29
FB
2559 }
2560#endif
2561
c5cc28ff
AJ
2562#ifdef CONFIG_PROFILER
2563 s->opt_time -= profile_getclock();
2564#endif
2565
8f2e8c07 2566#ifdef USE_TCG_OPTIMIZATIONS
c45cb8bb 2567 tcg_optimize(s);
8f2e8c07
KB
2568#endif
2569
a23a9ec6 2570#ifdef CONFIG_PROFILER
c5cc28ff 2571 s->opt_time += profile_getclock();
a23a9ec6
FB
2572 s->la_time -= profile_getclock();
2573#endif
c5cc28ff 2574
5a18407f
RH
2575 {
2576 uint8_t *temp_state = tcg_malloc(s->nb_temps + s->nb_indirects);
2577
2578 liveness_pass_1(s, temp_state);
2579
2580 if (s->nb_indirects > 0) {
2581#ifdef DEBUG_DISAS
2582 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
2583 && qemu_log_in_addr_range(tb->pc))) {
1ee73216 2584 qemu_log_lock();
5a18407f
RH
2585 qemu_log("OP before indirect lowering:\n");
2586 tcg_dump_ops(s);
2587 qemu_log("\n");
1ee73216 2588 qemu_log_unlock();
5a18407f
RH
2589 }
2590#endif
2591 /* Replace indirect temps with direct temps. */
2592 if (liveness_pass_2(s, temp_state)) {
2593 /* If changes were made, re-run liveness. */
2594 liveness_pass_1(s, temp_state);
2595 }
2596 }
2597 }
c5cc28ff 2598
a23a9ec6
FB
2599#ifdef CONFIG_PROFILER
2600 s->la_time += profile_getclock();
2601#endif
c896fe29
FB
2602
2603#ifdef DEBUG_DISAS
d977e1c2
AB
2604 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
2605 && qemu_log_in_addr_range(tb->pc))) {
1ee73216 2606 qemu_log_lock();
c5cc28ff 2607 qemu_log("OP after optimization and liveness analysis:\n");
eeacee4d 2608 tcg_dump_ops(s);
93fcfe39 2609 qemu_log("\n");
1ee73216 2610 qemu_log_unlock();
c896fe29
FB
2611 }
2612#endif
2613
2614 tcg_reg_alloc_start(s);
2615
5bd2ec3d
AB
2616 s->code_buf = tb->tc_ptr;
2617 s->code_ptr = tb->tc_ptr;
c896fe29 2618
659ef5cb
RH
2619#ifdef TCG_TARGET_NEED_LDST_LABELS
2620 s->ldst_labels = NULL;
2621#endif
9ecefc84 2622
fca8a500 2623 num_insns = -1;
dcb8e758 2624 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
c45cb8bb
RH
2625 TCGOp * const op = &s->gen_op_buf[oi];
2626 TCGArg * const args = &s->gen_opparam_buf[op->args];
2627 TCGOpcode opc = op->opc;
2628 const TCGOpDef *def = &tcg_op_defs[opc];
bee158cb 2629 TCGLifeData arg_life = op->life;
b3db8758 2630
c45cb8bb 2631 oi_next = op->next;
c896fe29 2632#ifdef CONFIG_PROFILER
54604f74 2633 tcg_table_op_count[opc]++;
c896fe29 2634#endif
c45cb8bb
RH
2635
2636 switch (opc) {
c896fe29 2637 case INDEX_op_mov_i32:
c896fe29 2638 case INDEX_op_mov_i64:
a1b3c48d 2639 tcg_reg_alloc_mov(s, def, args, arg_life);
c896fe29 2640 break;
e8996ee0 2641 case INDEX_op_movi_i32:
e8996ee0 2642 case INDEX_op_movi_i64:
a1b3c48d 2643 tcg_reg_alloc_movi(s, args, arg_life);
e8996ee0 2644 break;
765b842a 2645 case INDEX_op_insn_start:
fca8a500
RH
2646 if (num_insns >= 0) {
2647 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
2648 }
2649 num_insns++;
bad729e2
RH
2650 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
2651 target_ulong a;
2652#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
2653 a = ((target_ulong)args[i * 2 + 1] << 32) | args[i * 2];
2654#else
2655 a = args[i];
2656#endif
fca8a500 2657 s->gen_insn_data[num_insns][i] = a;
bad729e2 2658 }
c896fe29 2659 break;
5ff9d6a4 2660 case INDEX_op_discard:
f8bf00f1 2661 temp_dead(s, &s->temps[args[0]]);
5ff9d6a4 2662 break;
c896fe29 2663 case INDEX_op_set_label:
e8996ee0 2664 tcg_reg_alloc_bb_end(s, s->reserved_regs);
bec16311 2665 tcg_out_label(s, arg_label(args[0]), s->code_ptr);
c896fe29
FB
2666 break;
2667 case INDEX_op_call:
a1b3c48d 2668 tcg_reg_alloc_call(s, op->callo, op->calli, args, arg_life);
c45cb8bb 2669 break;
c896fe29 2670 default:
25c4d9cc
RH
2671 /* Sanity check that we've not introduced any unhandled opcodes. */
2672 if (def->flags & TCG_OPF_NOT_PRESENT) {
2673 tcg_abort();
2674 }
c896fe29
FB
2675 /* Note: in order to speed up the code, it would be much
2676 faster to have specialized register allocator functions for
2677 some common argument patterns */
a1b3c48d 2678 tcg_reg_alloc_op(s, def, opc, args, arg_life);
c896fe29
FB
2679 break;
2680 }
8d8fdbae 2681#ifdef CONFIG_DEBUG_TCG
c896fe29
FB
2682 check_regs(s);
2683#endif
b125f9dc
RH
2684 /* Test for (pending) buffer overflow. The assumption is that any
2685 one operation beginning below the high water mark cannot overrun
2686 the buffer completely. Thus we can test for overflow after
2687 generating code without having to check during generation. */
644da9b3 2688 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
b125f9dc
RH
2689 return -1;
2690 }
c896fe29 2691 }
fca8a500
RH
2692 tcg_debug_assert(num_insns >= 0);
2693 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
c45cb8bb 2694
b76f0d8c 2695 /* Generate TB finalization at the end of block */
659ef5cb
RH
2696#ifdef TCG_TARGET_NEED_LDST_LABELS
2697 if (!tcg_out_ldst_finalize(s)) {
23dceda6
RH
2698 return -1;
2699 }
659ef5cb 2700#endif
c896fe29
FB
2701
2702 /* flush instruction cache */
1813e175 2703 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
2aeabc08 2704
1813e175 2705 return tcg_current_code_size(s);
c896fe29
FB
2706}
2707
a23a9ec6 2708#ifdef CONFIG_PROFILER
405cf9ff 2709void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6
FB
2710{
2711 TCGContext *s = &tcg_ctx;
fca8a500
RH
2712 int64_t tb_count = s->tb_count;
2713 int64_t tb_div_count = tb_count ? tb_count : 1;
2714 int64_t tot = s->interm_time + s->code_time;
a23a9ec6 2715
a23a9ec6
FB
2716 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2717 tot, tot / 2.4e9);
2718 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
fca8a500
RH
2719 tb_count, s->tb_count1 - tb_count,
2720 (double)(s->tb_count1 - s->tb_count)
2721 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
a23a9ec6 2722 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
fca8a500 2723 (double)s->op_count / tb_div_count, s->op_count_max);
a23a9ec6 2724 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
fca8a500 2725 (double)s->del_op_count / tb_div_count);
a23a9ec6 2726 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
fca8a500
RH
2727 (double)s->temp_count / tb_div_count, s->temp_count_max);
2728 cpu_fprintf(f, "avg host code/TB %0.1f\n",
2729 (double)s->code_out_len / tb_div_count);
2730 cpu_fprintf(f, "avg search data/TB %0.1f\n",
2731 (double)s->search_out_len / tb_div_count);
a23a9ec6
FB
2732
2733 cpu_fprintf(f, "cycles/op %0.1f\n",
2734 s->op_count ? (double)tot / s->op_count : 0);
2735 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2736 s->code_in_len ? (double)tot / s->code_in_len : 0);
2737 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2738 s->code_out_len ? (double)tot / s->code_out_len : 0);
fca8a500
RH
2739 cpu_fprintf(f, "cycles/search byte %0.1f\n",
2740 s->search_out_len ? (double)tot / s->search_out_len : 0);
2741 if (tot == 0) {
a23a9ec6 2742 tot = 1;
fca8a500 2743 }
a23a9ec6
FB
2744 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2745 (double)s->interm_time / tot * 100.0);
2746 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2747 (double)s->code_time / tot * 100.0);
c5cc28ff
AJ
2748 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2749 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2750 * 100.0);
a23a9ec6
FB
2751 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2752 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2753 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2754 s->restore_count);
2755 cpu_fprintf(f, " avg cycles %0.1f\n",
2756 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
a23a9ec6
FB
2757}
2758#else
405cf9ff 2759void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6 2760{
24bf7b3a 2761 cpu_fprintf(f, "[TCG profiler not compiled]\n");
a23a9ec6
FB
2762}
2763#endif
813da627
RH
2764
2765#ifdef ELF_HOST_MACHINE
5872bbf2
RH
2766/* In order to use this feature, the backend needs to do three things:
2767
2768 (1) Define ELF_HOST_MACHINE to indicate both what value to
2769 put into the ELF image and to indicate support for the feature.
2770
2771 (2) Define tcg_register_jit. This should create a buffer containing
2772 the contents of a .debug_frame section that describes the post-
2773 prologue unwind info for the tcg machine.
2774
2775 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2776*/
813da627
RH
2777
2778/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2779typedef enum {
2780 JIT_NOACTION = 0,
2781 JIT_REGISTER_FN,
2782 JIT_UNREGISTER_FN
2783} jit_actions_t;
2784
2785struct jit_code_entry {
2786 struct jit_code_entry *next_entry;
2787 struct jit_code_entry *prev_entry;
2788 const void *symfile_addr;
2789 uint64_t symfile_size;
2790};
2791
2792struct jit_descriptor {
2793 uint32_t version;
2794 uint32_t action_flag;
2795 struct jit_code_entry *relevant_entry;
2796 struct jit_code_entry *first_entry;
2797};
2798
2799void __jit_debug_register_code(void) __attribute__((noinline));
2800void __jit_debug_register_code(void)
2801{
2802 asm("");
2803}
2804
2805/* Must statically initialize the version, because GDB may check
2806 the version before we can set it. */
2807struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2808
2809/* End GDB interface. */
2810
2811static int find_string(const char *strtab, const char *str)
2812{
2813 const char *p = strtab + 1;
2814
2815 while (1) {
2816 if (strcmp(p, str) == 0) {
2817 return p - strtab;
2818 }
2819 p += strlen(p) + 1;
2820 }
2821}
2822
5872bbf2 2823static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2c90784a
RH
2824 const void *debug_frame,
2825 size_t debug_frame_size)
813da627 2826{
5872bbf2
RH
2827 struct __attribute__((packed)) DebugInfo {
2828 uint32_t len;
2829 uint16_t version;
2830 uint32_t abbrev;
2831 uint8_t ptr_size;
2832 uint8_t cu_die;
2833 uint16_t cu_lang;
2834 uintptr_t cu_low_pc;
2835 uintptr_t cu_high_pc;
2836 uint8_t fn_die;
2837 char fn_name[16];
2838 uintptr_t fn_low_pc;
2839 uintptr_t fn_high_pc;
2840 uint8_t cu_eoc;
2841 };
813da627
RH
2842
2843 struct ElfImage {
2844 ElfW(Ehdr) ehdr;
2845 ElfW(Phdr) phdr;
5872bbf2
RH
2846 ElfW(Shdr) shdr[7];
2847 ElfW(Sym) sym[2];
2848 struct DebugInfo di;
2849 uint8_t da[24];
2850 char str[80];
2851 };
2852
2853 struct ElfImage *img;
2854
2855 static const struct ElfImage img_template = {
2856 .ehdr = {
2857 .e_ident[EI_MAG0] = ELFMAG0,
2858 .e_ident[EI_MAG1] = ELFMAG1,
2859 .e_ident[EI_MAG2] = ELFMAG2,
2860 .e_ident[EI_MAG3] = ELFMAG3,
2861 .e_ident[EI_CLASS] = ELF_CLASS,
2862 .e_ident[EI_DATA] = ELF_DATA,
2863 .e_ident[EI_VERSION] = EV_CURRENT,
2864 .e_type = ET_EXEC,
2865 .e_machine = ELF_HOST_MACHINE,
2866 .e_version = EV_CURRENT,
2867 .e_phoff = offsetof(struct ElfImage, phdr),
2868 .e_shoff = offsetof(struct ElfImage, shdr),
2869 .e_ehsize = sizeof(ElfW(Shdr)),
2870 .e_phentsize = sizeof(ElfW(Phdr)),
2871 .e_phnum = 1,
2872 .e_shentsize = sizeof(ElfW(Shdr)),
2873 .e_shnum = ARRAY_SIZE(img->shdr),
2874 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
abbb3eae
RH
2875#ifdef ELF_HOST_FLAGS
2876 .e_flags = ELF_HOST_FLAGS,
2877#endif
2878#ifdef ELF_OSABI
2879 .e_ident[EI_OSABI] = ELF_OSABI,
2880#endif
5872bbf2
RH
2881 },
2882 .phdr = {
2883 .p_type = PT_LOAD,
2884 .p_flags = PF_X,
2885 },
2886 .shdr = {
2887 [0] = { .sh_type = SHT_NULL },
2888 /* Trick: The contents of code_gen_buffer are not present in
2889 this fake ELF file; that got allocated elsewhere. Therefore
2890 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2891 will not look for contents. We can record any address. */
2892 [1] = { /* .text */
2893 .sh_type = SHT_NOBITS,
2894 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2895 },
2896 [2] = { /* .debug_info */
2897 .sh_type = SHT_PROGBITS,
2898 .sh_offset = offsetof(struct ElfImage, di),
2899 .sh_size = sizeof(struct DebugInfo),
2900 },
2901 [3] = { /* .debug_abbrev */
2902 .sh_type = SHT_PROGBITS,
2903 .sh_offset = offsetof(struct ElfImage, da),
2904 .sh_size = sizeof(img->da),
2905 },
2906 [4] = { /* .debug_frame */
2907 .sh_type = SHT_PROGBITS,
2908 .sh_offset = sizeof(struct ElfImage),
2909 },
2910 [5] = { /* .symtab */
2911 .sh_type = SHT_SYMTAB,
2912 .sh_offset = offsetof(struct ElfImage, sym),
2913 .sh_size = sizeof(img->sym),
2914 .sh_info = 1,
2915 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2916 .sh_entsize = sizeof(ElfW(Sym)),
2917 },
2918 [6] = { /* .strtab */
2919 .sh_type = SHT_STRTAB,
2920 .sh_offset = offsetof(struct ElfImage, str),
2921 .sh_size = sizeof(img->str),
2922 }
2923 },
2924 .sym = {
2925 [1] = { /* code_gen_buffer */
2926 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2927 .st_shndx = 1,
2928 }
2929 },
2930 .di = {
2931 .len = sizeof(struct DebugInfo) - 4,
2932 .version = 2,
2933 .ptr_size = sizeof(void *),
2934 .cu_die = 1,
2935 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2936 .fn_die = 2,
2937 .fn_name = "code_gen_buffer"
2938 },
2939 .da = {
2940 1, /* abbrev number (the cu) */
2941 0x11, 1, /* DW_TAG_compile_unit, has children */
2942 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2943 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2944 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2945 0, 0, /* end of abbrev */
2946 2, /* abbrev number (the fn) */
2947 0x2e, 0, /* DW_TAG_subprogram, no children */
2948 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2949 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2950 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2951 0, 0, /* end of abbrev */
2952 0 /* no more abbrev */
2953 },
2954 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2955 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
813da627
RH
2956 };
2957
2958 /* We only need a single jit entry; statically allocate it. */
2959 static struct jit_code_entry one_entry;
2960
5872bbf2 2961 uintptr_t buf = (uintptr_t)buf_ptr;
813da627 2962 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2c90784a 2963 DebugFrameHeader *dfh;
813da627 2964
5872bbf2
RH
2965 img = g_malloc(img_size);
2966 *img = img_template;
813da627 2967
5872bbf2
RH
2968 img->phdr.p_vaddr = buf;
2969 img->phdr.p_paddr = buf;
2970 img->phdr.p_memsz = buf_size;
813da627 2971
813da627 2972 img->shdr[1].sh_name = find_string(img->str, ".text");
5872bbf2 2973 img->shdr[1].sh_addr = buf;
813da627
RH
2974 img->shdr[1].sh_size = buf_size;
2975
5872bbf2
RH
2976 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2977 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2978
2979 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2980 img->shdr[4].sh_size = debug_frame_size;
2981
2982 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2983 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2984
2985 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2986 img->sym[1].st_value = buf;
2987 img->sym[1].st_size = buf_size;
813da627 2988
5872bbf2 2989 img->di.cu_low_pc = buf;
45aba097 2990 img->di.cu_high_pc = buf + buf_size;
5872bbf2 2991 img->di.fn_low_pc = buf;
45aba097 2992 img->di.fn_high_pc = buf + buf_size;
813da627 2993
2c90784a
RH
2994 dfh = (DebugFrameHeader *)(img + 1);
2995 memcpy(dfh, debug_frame, debug_frame_size);
2996 dfh->fde.func_start = buf;
2997 dfh->fde.func_len = buf_size;
2998
813da627
RH
2999#ifdef DEBUG_JIT
3000 /* Enable this block to be able to debug the ELF image file creation.
3001 One can use readelf, objdump, or other inspection utilities. */
3002 {
3003 FILE *f = fopen("/tmp/qemu.jit", "w+b");
3004 if (f) {
5872bbf2 3005 if (fwrite(img, img_size, 1, f) != img_size) {
813da627
RH
3006 /* Avoid stupid unused return value warning for fwrite. */
3007 }
3008 fclose(f);
3009 }
3010 }
3011#endif
3012
3013 one_entry.symfile_addr = img;
3014 one_entry.symfile_size = img_size;
3015
3016 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
3017 __jit_debug_descriptor.relevant_entry = &one_entry;
3018 __jit_debug_descriptor.first_entry = &one_entry;
3019 __jit_debug_register_code();
3020}
3021#else
5872bbf2
RH
3022/* No support for the feature. Provide the entry point expected by exec.c,
3023 and implement the internal function we declared earlier. */
813da627
RH
3024
3025static void tcg_register_jit_int(void *buf, size_t size,
2c90784a
RH
3026 const void *debug_frame,
3027 size_t debug_frame_size)
813da627
RH
3028{
3029}
3030
3031void tcg_register_jit(void *buf, size_t buf_size)
3032{
3033}
3034#endif /* ELF_HOST_MACHINE */
This page took 1.381177 seconds and 4 git commands to generate.