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