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