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