]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/tcg.c
tcg: Reorg TCGOp chaining
[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;
c45cb8bb 1345 int oi, oi_prev, nb_ops;
c896fe29 1346
c45cb8bb 1347 nb_ops = s->gen_next_op_idx;
a1b3c48d
RH
1348 s->op_arg_life = tcg_malloc(nb_ops * sizeof(TCGLifeData));
1349
c896fe29 1350 dead_temps = tcg_malloc(s->nb_temps);
9c43b68d
AJ
1351 mem_temps = tcg_malloc(s->nb_temps);
1352 tcg_la_func_end(s, dead_temps, mem_temps);
c896fe29 1353
dcb8e758 1354 for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) {
c45cb8bb
RH
1355 int i, nb_iargs, nb_oargs;
1356 TCGOpcode opc_new, opc_new2;
1357 bool have_opc_new2;
a1b3c48d 1358 TCGLifeData arg_life = 0;
c45cb8bb
RH
1359 TCGArg arg;
1360
1361 TCGOp * const op = &s->gen_op_buf[oi];
1362 TCGArg * const args = &s->gen_opparam_buf[op->args];
1363 TCGOpcode opc = op->opc;
1364 const TCGOpDef *def = &tcg_op_defs[opc];
1365
1366 oi_prev = op->prev;
1367
1368 switch (opc) {
c896fe29 1369 case INDEX_op_call:
c6e113f5
FB
1370 {
1371 int call_flags;
c896fe29 1372
c45cb8bb
RH
1373 nb_oargs = op->callo;
1374 nb_iargs = op->calli;
cf066674 1375 call_flags = args[nb_oargs + nb_iargs + 1];
c6e113f5 1376
c45cb8bb 1377 /* pure functions can be removed if their result is unused */
78505279 1378 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
cf066674 1379 for (i = 0; i < nb_oargs; i++) {
c6e113f5 1380 arg = args[i];
9c43b68d 1381 if (!dead_temps[arg] || mem_temps[arg]) {
c6e113f5 1382 goto do_not_remove_call;
9c43b68d 1383 }
c6e113f5 1384 }
c45cb8bb 1385 goto do_remove;
c6e113f5
FB
1386 } else {
1387 do_not_remove_call:
c896fe29 1388
c6e113f5 1389 /* output args are dead */
cf066674 1390 for (i = 0; i < nb_oargs; i++) {
c6e113f5 1391 arg = args[i];
6b64b624 1392 if (dead_temps[arg]) {
a1b3c48d 1393 arg_life |= DEAD_ARG << i;
6b64b624 1394 }
9c43b68d 1395 if (mem_temps[arg]) {
a1b3c48d 1396 arg_life |= SYNC_ARG << i;
9c43b68d 1397 }
c6e113f5 1398 dead_temps[arg] = 1;
9c43b68d 1399 mem_temps[arg] = 0;
c6e113f5 1400 }
78505279
AJ
1401
1402 if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1403 /* globals should be synced to memory */
1404 memset(mem_temps, 1, s->nb_globals);
1405 }
1406 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1407 TCG_CALL_NO_READ_GLOBALS))) {
9c43b68d
AJ
1408 /* globals should go back to memory */
1409 memset(dead_temps, 1, s->nb_globals);
b9c18f56
AJ
1410 }
1411
c19f47bf 1412 /* record arguments that die in this helper */
cf066674 1413 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 1414 arg = args[i];
39cf05d3
FB
1415 if (arg != TCG_CALL_DUMMY_ARG) {
1416 if (dead_temps[arg]) {
a1b3c48d 1417 arg_life |= DEAD_ARG << i;
39cf05d3 1418 }
c6e113f5 1419 }
c6e113f5 1420 }
67cc32eb 1421 /* input arguments are live for preceding opcodes */
c19f47bf
AJ
1422 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1423 arg = args[i];
1424 dead_temps[arg] = 0;
1425 }
c896fe29 1426 }
c896fe29 1427 }
c896fe29 1428 break;
765b842a 1429 case INDEX_op_insn_start:
c896fe29 1430 break;
5ff9d6a4 1431 case INDEX_op_discard:
5ff9d6a4
FB
1432 /* mark the temporary as dead */
1433 dead_temps[args[0]] = 1;
9c43b68d 1434 mem_temps[args[0]] = 0;
5ff9d6a4 1435 break;
1305c451
RH
1436
1437 case INDEX_op_add2_i32:
c45cb8bb 1438 opc_new = INDEX_op_add_i32;
f1fae40c 1439 goto do_addsub2;
1305c451 1440 case INDEX_op_sub2_i32:
c45cb8bb 1441 opc_new = INDEX_op_sub_i32;
f1fae40c
RH
1442 goto do_addsub2;
1443 case INDEX_op_add2_i64:
c45cb8bb 1444 opc_new = INDEX_op_add_i64;
f1fae40c
RH
1445 goto do_addsub2;
1446 case INDEX_op_sub2_i64:
c45cb8bb 1447 opc_new = INDEX_op_sub_i64;
f1fae40c 1448 do_addsub2:
1305c451
RH
1449 nb_iargs = 4;
1450 nb_oargs = 2;
1451 /* Test if the high part of the operation is dead, but not
1452 the low part. The result can be optimized to a simple
1453 add or sub. This happens often for x86_64 guest when the
1454 cpu mode is set to 32 bit. */
3c5645fa
KB
1455 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1456 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1305c451
RH
1457 goto do_remove;
1458 }
c45cb8bb
RH
1459 /* Replace the opcode and adjust the args in place,
1460 leaving 3 unused args at the end. */
1461 op->opc = opc = opc_new;
1305c451
RH
1462 args[1] = args[2];
1463 args[2] = args[4];
1305c451
RH
1464 /* Fall through and mark the single-word operation live. */
1465 nb_iargs = 2;
1466 nb_oargs = 1;
1467 }
1468 goto do_not_remove;
1469
1414968a 1470 case INDEX_op_mulu2_i32:
c45cb8bb
RH
1471 opc_new = INDEX_op_mul_i32;
1472 opc_new2 = INDEX_op_muluh_i32;
1473 have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
03271524 1474 goto do_mul2;
f1fae40c 1475 case INDEX_op_muls2_i32:
c45cb8bb
RH
1476 opc_new = INDEX_op_mul_i32;
1477 opc_new2 = INDEX_op_mulsh_i32;
1478 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
f1fae40c
RH
1479 goto do_mul2;
1480 case INDEX_op_mulu2_i64:
c45cb8bb
RH
1481 opc_new = INDEX_op_mul_i64;
1482 opc_new2 = INDEX_op_muluh_i64;
1483 have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
03271524 1484 goto do_mul2;
f1fae40c 1485 case INDEX_op_muls2_i64:
c45cb8bb
RH
1486 opc_new = INDEX_op_mul_i64;
1487 opc_new2 = INDEX_op_mulsh_i64;
1488 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
03271524 1489 goto do_mul2;
f1fae40c 1490 do_mul2:
1414968a
RH
1491 nb_iargs = 2;
1492 nb_oargs = 2;
3c5645fa
KB
1493 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1494 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
03271524 1495 /* Both parts of the operation are dead. */
1414968a
RH
1496 goto do_remove;
1497 }
03271524 1498 /* The high part of the operation is dead; generate the low. */
c45cb8bb 1499 op->opc = opc = opc_new;
1414968a
RH
1500 args[1] = args[2];
1501 args[2] = args[3];
c45cb8bb 1502 } else if (have_opc_new2 && dead_temps[args[0]]
03271524 1503 && !mem_temps[args[0]]) {
c45cb8bb
RH
1504 /* The low part of the operation is dead; generate the high. */
1505 op->opc = opc = opc_new2;
03271524
RH
1506 args[0] = args[1];
1507 args[1] = args[2];
1508 args[2] = args[3];
1509 } else {
1510 goto do_not_remove;
1414968a 1511 }
03271524
RH
1512 /* Mark the single-word operation live. */
1513 nb_oargs = 1;
1414968a
RH
1514 goto do_not_remove;
1515
c896fe29 1516 default:
1305c451 1517 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
49516bc0
AJ
1518 nb_iargs = def->nb_iargs;
1519 nb_oargs = def->nb_oargs;
c896fe29 1520
49516bc0
AJ
1521 /* Test if the operation can be removed because all
1522 its outputs are dead. We assume that nb_oargs == 0
1523 implies side effects */
1524 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
c45cb8bb 1525 for (i = 0; i < nb_oargs; i++) {
49516bc0 1526 arg = args[i];
9c43b68d 1527 if (!dead_temps[arg] || mem_temps[arg]) {
49516bc0 1528 goto do_not_remove;
9c43b68d 1529 }
49516bc0 1530 }
1305c451 1531 do_remove:
0c627cdc 1532 tcg_op_remove(s, op);
49516bc0
AJ
1533 } else {
1534 do_not_remove:
49516bc0 1535 /* output args are dead */
c45cb8bb 1536 for (i = 0; i < nb_oargs; i++) {
49516bc0 1537 arg = args[i];
6b64b624 1538 if (dead_temps[arg]) {
a1b3c48d 1539 arg_life |= DEAD_ARG << i;
6b64b624 1540 }
9c43b68d 1541 if (mem_temps[arg]) {
a1b3c48d 1542 arg_life |= SYNC_ARG << i;
9c43b68d 1543 }
49516bc0 1544 dead_temps[arg] = 1;
9c43b68d 1545 mem_temps[arg] = 0;
49516bc0
AJ
1546 }
1547
1548 /* if end of basic block, update */
1549 if (def->flags & TCG_OPF_BB_END) {
9c43b68d 1550 tcg_la_bb_end(s, dead_temps, mem_temps);
3d5c5f87
AJ
1551 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1552 /* globals should be synced to memory */
9c43b68d 1553 memset(mem_temps, 1, s->nb_globals);
49516bc0
AJ
1554 }
1555
c19f47bf 1556 /* record arguments that die in this opcode */
c45cb8bb 1557 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
866cb6cb 1558 arg = args[i];
49516bc0 1559 if (dead_temps[arg]) {
a1b3c48d 1560 arg_life |= DEAD_ARG << i;
c896fe29 1561 }
c19f47bf 1562 }
67cc32eb 1563 /* input arguments are live for preceding opcodes */
c19f47bf
AJ
1564 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1565 arg = args[i];
49516bc0 1566 dead_temps[arg] = 0;
c896fe29 1567 }
c896fe29
FB
1568 }
1569 break;
1570 }
a1b3c48d 1571 s->op_arg_life[oi] = arg_life;
1ff0a2c5 1572 }
c896fe29
FB
1573}
1574#else
1575/* dummy liveness analysis */
655feed5 1576static void tcg_liveness_analysis(TCGContext *s)
c896fe29 1577{
20157705 1578 int nb_ops = s->gen_next_op_idx;
c896fe29 1579
866cb6cb
AJ
1580 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1581 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
ec7a869d
AJ
1582 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1583 memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
c896fe29
FB
1584}
1585#endif
1586
8d8fdbae 1587#ifdef CONFIG_DEBUG_TCG
c896fe29
FB
1588static void dump_regs(TCGContext *s)
1589{
1590 TCGTemp *ts;
1591 int i;
1592 char buf[64];
1593
1594 for(i = 0; i < s->nb_temps; i++) {
1595 ts = &s->temps[i];
ac56dd48 1596 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
c896fe29
FB
1597 switch(ts->val_type) {
1598 case TEMP_VAL_REG:
1599 printf("%s", tcg_target_reg_names[ts->reg]);
1600 break;
1601 case TEMP_VAL_MEM:
b3a62939
RH
1602 printf("%d(%s)", (int)ts->mem_offset,
1603 tcg_target_reg_names[ts->mem_base->reg]);
c896fe29
FB
1604 break;
1605 case TEMP_VAL_CONST:
1606 printf("$0x%" TCG_PRIlx, ts->val);
1607 break;
1608 case TEMP_VAL_DEAD:
1609 printf("D");
1610 break;
1611 default:
1612 printf("???");
1613 break;
1614 }
1615 printf("\n");
1616 }
1617
1618 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
f8b2f202 1619 if (s->reg_to_temp[i] != NULL) {
c896fe29
FB
1620 printf("%s: %s\n",
1621 tcg_target_reg_names[i],
f8b2f202 1622 tcg_get_arg_str_ptr(s, buf, sizeof(buf), s->reg_to_temp[i]));
c896fe29
FB
1623 }
1624 }
1625}
1626
1627static void check_regs(TCGContext *s)
1628{
869938ae 1629 int reg;
b6638662 1630 int k;
c896fe29
FB
1631 TCGTemp *ts;
1632 char buf[64];
1633
f8b2f202
RH
1634 for (reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1635 ts = s->reg_to_temp[reg];
1636 if (ts != NULL) {
1637 if (ts->val_type != TEMP_VAL_REG || ts->reg != reg) {
c896fe29
FB
1638 printf("Inconsistency for register %s:\n",
1639 tcg_target_reg_names[reg]);
b03cce8e 1640 goto fail;
c896fe29
FB
1641 }
1642 }
1643 }
f8b2f202 1644 for (k = 0; k < s->nb_temps; k++) {
c896fe29 1645 ts = &s->temps[k];
f8b2f202
RH
1646 if (ts->val_type == TEMP_VAL_REG && !ts->fixed_reg
1647 && s->reg_to_temp[ts->reg] != ts) {
1648 printf("Inconsistency for temp %s:\n",
1649 tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
b03cce8e 1650 fail:
f8b2f202
RH
1651 printf("reg state:\n");
1652 dump_regs(s);
1653 tcg_abort();
c896fe29
FB
1654 }
1655 }
1656}
1657#endif
1658
1659static void temp_allocate_frame(TCGContext *s, int temp)
1660{
1661 TCGTemp *ts;
1662 ts = &s->temps[temp];
9b9c37c3
RH
1663#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1664 /* Sparc64 stack is accessed with offset of 2047 */
b591dc59
BS
1665 s->current_frame_offset = (s->current_frame_offset +
1666 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1667 ~(sizeof(tcg_target_long) - 1);
f44c9960 1668#endif
b591dc59
BS
1669 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1670 s->frame_end) {
5ff9d6a4 1671 tcg_abort();
b591dc59 1672 }
c896fe29 1673 ts->mem_offset = s->current_frame_offset;
b3a62939 1674 ts->mem_base = s->frame_temp;
c896fe29 1675 ts->mem_allocated = 1;
e2c6d1b4 1676 s->current_frame_offset += sizeof(tcg_target_long);
c896fe29
FB
1677}
1678
b3915dbb
RH
1679static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
1680
59d7c14e
RH
1681/* Mark a temporary as free or dead. If 'free_or_dead' is negative,
1682 mark it free; otherwise mark it dead. */
1683static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
7f6ceedf 1684{
59d7c14e
RH
1685 if (ts->fixed_reg) {
1686 return;
1687 }
1688 if (ts->val_type == TEMP_VAL_REG) {
1689 s->reg_to_temp[ts->reg] = NULL;
1690 }
1691 ts->val_type = (free_or_dead < 0
1692 || ts->temp_local
1693 || temp_idx(s, ts) < s->nb_globals
1694 ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
1695}
7f6ceedf 1696
59d7c14e
RH
1697/* Mark a temporary as dead. */
1698static inline void temp_dead(TCGContext *s, TCGTemp *ts)
1699{
1700 temp_free_or_dead(s, ts, 1);
1701}
1702
1703/* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
1704 registers needs to be allocated to store a constant. If 'free_or_dead'
1705 is non-zero, subsequently release the temporary; if it is positive, the
1706 temp is dead; if it is negative, the temp is free. */
1707static void temp_sync(TCGContext *s, TCGTemp *ts,
1708 TCGRegSet allocated_regs, int free_or_dead)
1709{
1710 if (ts->fixed_reg) {
1711 return;
1712 }
1713 if (!ts->mem_coherent) {
7f6ceedf 1714 if (!ts->mem_allocated) {
f8b2f202 1715 temp_allocate_frame(s, temp_idx(s, ts));
59d7c14e
RH
1716 }
1717 if (ts->indirect_reg) {
1718 if (ts->val_type == TEMP_VAL_REG) {
1719 tcg_regset_set_reg(allocated_regs, ts->reg);
1720 }
b3915dbb
RH
1721 temp_load(s, ts->mem_base,
1722 tcg_target_available_regs[TCG_TYPE_PTR],
1723 allocated_regs);
7f6ceedf 1724 }
59d7c14e
RH
1725 switch (ts->val_type) {
1726 case TEMP_VAL_CONST:
1727 /* If we're going to free the temp immediately, then we won't
1728 require it later in a register, so attempt to store the
1729 constant to memory directly. */
1730 if (free_or_dead
1731 && tcg_out_sti(s, ts->type, ts->val,
1732 ts->mem_base->reg, ts->mem_offset)) {
1733 break;
1734 }
1735 temp_load(s, ts, tcg_target_available_regs[ts->type],
1736 allocated_regs);
1737 /* fallthrough */
1738
1739 case TEMP_VAL_REG:
1740 tcg_out_st(s, ts->type, ts->reg,
1741 ts->mem_base->reg, ts->mem_offset);
1742 break;
1743
1744 case TEMP_VAL_MEM:
1745 break;
1746
1747 case TEMP_VAL_DEAD:
1748 default:
1749 tcg_abort();
1750 }
1751 ts->mem_coherent = 1;
1752 }
1753 if (free_or_dead) {
1754 temp_free_or_dead(s, ts, free_or_dead);
7f6ceedf 1755 }
7f6ceedf
AJ
1756}
1757
c896fe29 1758/* free register 'reg' by spilling the corresponding temporary if necessary */
b3915dbb 1759static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
c896fe29 1760{
f8b2f202 1761 TCGTemp *ts = s->reg_to_temp[reg];
f8b2f202 1762 if (ts != NULL) {
59d7c14e 1763 temp_sync(s, ts, allocated_regs, -1);
c896fe29
FB
1764 }
1765}
1766
1767/* Allocate a register belonging to reg1 & ~reg2 */
b3915dbb 1768static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
91478cef 1769 TCGRegSet allocated_regs, bool rev)
c896fe29 1770{
91478cef
RH
1771 int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
1772 const int *order;
b6638662 1773 TCGReg reg;
c896fe29
FB
1774 TCGRegSet reg_ct;
1775
b3915dbb 1776 tcg_regset_andnot(reg_ct, desired_regs, allocated_regs);
91478cef 1777 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
c896fe29
FB
1778
1779 /* first try free registers */
91478cef
RH
1780 for(i = 0; i < n; i++) {
1781 reg = order[i];
f8b2f202 1782 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
c896fe29
FB
1783 return reg;
1784 }
1785
1786 /* XXX: do better spill choice */
91478cef
RH
1787 for(i = 0; i < n; i++) {
1788 reg = order[i];
c896fe29 1789 if (tcg_regset_test_reg(reg_ct, reg)) {
b3915dbb 1790 tcg_reg_free(s, reg, allocated_regs);
c896fe29
FB
1791 return reg;
1792 }
1793 }
1794
1795 tcg_abort();
1796}
1797
40ae5c62
RH
1798/* Make sure the temporary is in a register. If needed, allocate the register
1799 from DESIRED while avoiding ALLOCATED. */
1800static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
1801 TCGRegSet allocated_regs)
1802{
1803 TCGReg reg;
1804
1805 switch (ts->val_type) {
1806 case TEMP_VAL_REG:
1807 return;
1808 case TEMP_VAL_CONST:
91478cef 1809 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
40ae5c62
RH
1810 tcg_out_movi(s, ts->type, reg, ts->val);
1811 ts->mem_coherent = 0;
1812 break;
1813 case TEMP_VAL_MEM:
91478cef 1814 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
b3915dbb
RH
1815 if (ts->indirect_reg) {
1816 tcg_regset_set_reg(allocated_regs, reg);
1817 temp_load(s, ts->mem_base,
1818 tcg_target_available_regs[TCG_TYPE_PTR],
1819 allocated_regs);
1820 }
40ae5c62
RH
1821 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
1822 ts->mem_coherent = 1;
1823 break;
1824 case TEMP_VAL_DEAD:
1825 default:
1826 tcg_abort();
1827 }
1828 ts->reg = reg;
1829 ts->val_type = TEMP_VAL_REG;
1830 s->reg_to_temp[reg] = ts;
1831}
1832
59d7c14e
RH
1833/* Save a temporary to memory. 'allocated_regs' is used in case a
1834 temporary registers needs to be allocated to store a constant. */
1835static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
1ad80729 1836{
2c0366f0 1837#ifdef USE_LIVENESS_ANALYSIS
b3915dbb
RH
1838 /* ??? Liveness does not yet incorporate indirect bases. */
1839 if (!ts->indirect_base) {
1840 /* The liveness analysis already ensures that globals are back
eabb7b91 1841 in memory. Keep an tcg_debug_assert for safety. */
b3915dbb
RH
1842 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
1843 return;
1844 }
1845#endif
59d7c14e 1846 temp_sync(s, ts, allocated_regs, 1);
1ad80729
AJ
1847}
1848
9814dd27 1849/* save globals to their canonical location and assume they can be
e8996ee0
FB
1850 modified be the following code. 'allocated_regs' is used in case a
1851 temporary registers needs to be allocated to store a constant. */
1852static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
c896fe29 1853{
641d5fbe 1854 int i;
c896fe29 1855
b13eb728
RH
1856 for (i = 0; i < s->nb_globals; i++) {
1857 temp_save(s, &s->temps[i], allocated_regs);
c896fe29 1858 }
e5097dc8
FB
1859}
1860
3d5c5f87
AJ
1861/* sync globals to their canonical location and assume they can be
1862 read by the following code. 'allocated_regs' is used in case a
1863 temporary registers needs to be allocated to store a constant. */
1864static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1865{
1866 int i;
1867
1868 for (i = 0; i < s->nb_globals; i++) {
12b9b11a 1869 TCGTemp *ts = &s->temps[i];
3d5c5f87 1870#ifdef USE_LIVENESS_ANALYSIS
b3915dbb
RH
1871 /* ??? Liveness does not yet incorporate indirect bases. */
1872 if (!ts->indirect_base) {
1873 tcg_debug_assert(ts->val_type != TEMP_VAL_REG
1874 || ts->fixed_reg
1875 || ts->mem_coherent);
1876 continue;
1877 }
3d5c5f87 1878#endif
59d7c14e 1879 temp_sync(s, ts, allocated_regs, 0);
3d5c5f87
AJ
1880 }
1881}
1882
e5097dc8 1883/* at the end of a basic block, we assume all temporaries are dead and
e8996ee0
FB
1884 all globals are stored at their canonical location. */
1885static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
e5097dc8 1886{
e5097dc8
FB
1887 int i;
1888
b13eb728
RH
1889 for (i = s->nb_globals; i < s->nb_temps; i++) {
1890 TCGTemp *ts = &s->temps[i];
641d5fbe 1891 if (ts->temp_local) {
b13eb728 1892 temp_save(s, ts, allocated_regs);
641d5fbe 1893 } else {
2c0366f0 1894#ifdef USE_LIVENESS_ANALYSIS
b3915dbb
RH
1895 /* ??? Liveness does not yet incorporate indirect bases. */
1896 if (!ts->indirect_base) {
1897 /* The liveness analysis already ensures that temps are dead.
eabb7b91
AJ
1898 Keep an tcg_debug_assert for safety. */
1899 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
b3915dbb
RH
1900 continue;
1901 }
2c0366f0 1902#endif
b3915dbb 1903 temp_dead(s, ts);
c896fe29
FB
1904 }
1905 }
e8996ee0
FB
1906
1907 save_globals(s, allocated_regs);
c896fe29
FB
1908}
1909
a1b3c48d
RH
1910#define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
1911#define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
c896fe29 1912
ec7a869d 1913static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
a1b3c48d 1914 TCGLifeData arg_life)
e8996ee0
FB
1915{
1916 TCGTemp *ots;
1917 tcg_target_ulong val;
1918
1919 ots = &s->temps[args[0]];
1920 val = args[1];
1921
1922 if (ots->fixed_reg) {
59d7c14e 1923 /* For fixed registers, we do not do any constant propagation. */
e8996ee0 1924 tcg_out_movi(s, ots->type, ots->reg, val);
59d7c14e 1925 return;
e8996ee0 1926 }
59d7c14e
RH
1927
1928 /* The movi is not explicitly generated here. */
1929 if (ots->val_type == TEMP_VAL_REG) {
1930 s->reg_to_temp[ots->reg] = NULL;
ec7a869d 1931 }
59d7c14e
RH
1932 ots->val_type = TEMP_VAL_CONST;
1933 ots->val = val;
1934 ots->mem_coherent = 0;
1935 if (NEED_SYNC_ARG(0)) {
1936 temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0));
1937 } else if (IS_DEAD_ARG(0)) {
f8bf00f1 1938 temp_dead(s, ots);
4c4e1ab2 1939 }
e8996ee0
FB
1940}
1941
c896fe29 1942static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
a1b3c48d 1943 const TCGArg *args, TCGLifeData arg_life)
c896fe29 1944{
c29c1d7e 1945 TCGRegSet allocated_regs;
c896fe29 1946 TCGTemp *ts, *ots;
450445d5 1947 TCGType otype, itype;
c896fe29 1948
c29c1d7e 1949 tcg_regset_set(allocated_regs, s->reserved_regs);
c896fe29
FB
1950 ots = &s->temps[args[0]];
1951 ts = &s->temps[args[1]];
450445d5
RH
1952
1953 /* Note that otype != itype for no-op truncation. */
1954 otype = ots->type;
1955 itype = ts->type;
c29c1d7e
AJ
1956
1957 /* If the source value is not in a register, and we're going to be
1958 forced to have it in a register in order to perform the copy,
1959 then copy the SOURCE value into its own register first. That way
1960 we don't have to reload SOURCE the next time it is used. */
1961 if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
1962 || ts->val_type == TEMP_VAL_MEM) {
40ae5c62 1963 temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs);
c29c1d7e 1964 }
c896fe29 1965
c29c1d7e
AJ
1966 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
1967 /* mov to a non-saved dead register makes no sense (even with
1968 liveness analysis disabled). */
eabb7b91 1969 tcg_debug_assert(NEED_SYNC_ARG(0));
c29c1d7e 1970 /* The code above should have moved the temp to a register. */
eabb7b91 1971 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
c29c1d7e
AJ
1972 if (!ots->mem_allocated) {
1973 temp_allocate_frame(s, args[0]);
1974 }
b3915dbb
RH
1975 if (ots->indirect_reg) {
1976 tcg_regset_set_reg(allocated_regs, ts->reg);
1977 temp_load(s, ots->mem_base,
1978 tcg_target_available_regs[TCG_TYPE_PTR],
1979 allocated_regs);
1980 }
b3a62939 1981 tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
c29c1d7e 1982 if (IS_DEAD_ARG(1)) {
f8bf00f1 1983 temp_dead(s, ts);
c29c1d7e 1984 }
f8bf00f1 1985 temp_dead(s, ots);
c29c1d7e
AJ
1986 } else if (ts->val_type == TEMP_VAL_CONST) {
1987 /* propagate constant */
1988 if (ots->val_type == TEMP_VAL_REG) {
f8b2f202 1989 s->reg_to_temp[ots->reg] = NULL;
c29c1d7e
AJ
1990 }
1991 ots->val_type = TEMP_VAL_CONST;
1992 ots->val = ts->val;
7df69dea 1993 if (IS_DEAD_ARG(1)) {
f8bf00f1 1994 temp_dead(s, ts);
7df69dea 1995 }
c29c1d7e
AJ
1996 } else {
1997 /* The code in the first if block should have moved the
1998 temp to a register. */
eabb7b91 1999 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
866cb6cb 2000 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
c896fe29 2001 /* the mov can be suppressed */
c29c1d7e 2002 if (ots->val_type == TEMP_VAL_REG) {
f8b2f202 2003 s->reg_to_temp[ots->reg] = NULL;
c29c1d7e
AJ
2004 }
2005 ots->reg = ts->reg;
f8bf00f1 2006 temp_dead(s, ts);
c896fe29 2007 } else {
c29c1d7e
AJ
2008 if (ots->val_type != TEMP_VAL_REG) {
2009 /* When allocating a new register, make sure to not spill the
2010 input one. */
2011 tcg_regset_set_reg(allocated_regs, ts->reg);
450445d5 2012 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
91478cef 2013 allocated_regs, ots->indirect_base);
c896fe29 2014 }
450445d5 2015 tcg_out_mov(s, otype, ots->reg, ts->reg);
c896fe29 2016 }
c29c1d7e
AJ
2017 ots->val_type = TEMP_VAL_REG;
2018 ots->mem_coherent = 0;
f8b2f202 2019 s->reg_to_temp[ots->reg] = ots;
c29c1d7e 2020 if (NEED_SYNC_ARG(0)) {
59d7c14e 2021 temp_sync(s, ots, allocated_regs, 0);
c896fe29 2022 }
ec7a869d 2023 }
c896fe29
FB
2024}
2025
2026static void tcg_reg_alloc_op(TCGContext *s,
a9751609 2027 const TCGOpDef *def, TCGOpcode opc,
a1b3c48d 2028 const TCGArg *args, TCGLifeData arg_life)
c896fe29
FB
2029{
2030 TCGRegSet allocated_regs;
b6638662
RH
2031 int i, k, nb_iargs, nb_oargs;
2032 TCGReg reg;
c896fe29
FB
2033 TCGArg arg;
2034 const TCGArgConstraint *arg_ct;
2035 TCGTemp *ts;
2036 TCGArg new_args[TCG_MAX_OP_ARGS];
2037 int const_args[TCG_MAX_OP_ARGS];
2038
2039 nb_oargs = def->nb_oargs;
2040 nb_iargs = def->nb_iargs;
2041
2042 /* copy constants */
2043 memcpy(new_args + nb_oargs + nb_iargs,
2044 args + nb_oargs + nb_iargs,
2045 sizeof(TCGArg) * def->nb_cargs);
2046
2047 /* satisfy input constraints */
2048 tcg_regset_set(allocated_regs, s->reserved_regs);
2049 for(k = 0; k < nb_iargs; k++) {
2050 i = def->sorted_args[nb_oargs + k];
2051 arg = args[i];
2052 arg_ct = &def->args_ct[i];
2053 ts = &s->temps[arg];
40ae5c62
RH
2054
2055 if (ts->val_type == TEMP_VAL_CONST
2056 && tcg_target_const_match(ts->val, ts->type, arg_ct)) {
2057 /* constant is OK for instruction */
2058 const_args[i] = 1;
2059 new_args[i] = ts->val;
2060 goto iarg_end;
c896fe29 2061 }
40ae5c62
RH
2062
2063 temp_load(s, ts, arg_ct->u.regs, allocated_regs);
2064
5ff9d6a4
FB
2065 if (arg_ct->ct & TCG_CT_IALIAS) {
2066 if (ts->fixed_reg) {
2067 /* if fixed register, we must allocate a new register
2068 if the alias is not the same register */
2069 if (arg != args[arg_ct->alias_index])
2070 goto allocate_in_reg;
2071 } else {
2072 /* if the input is aliased to an output and if it is
2073 not dead after the instruction, we must allocate
2074 a new register and move it */
866cb6cb 2075 if (!IS_DEAD_ARG(i)) {
5ff9d6a4 2076 goto allocate_in_reg;
866cb6cb 2077 }
7e1df267
AJ
2078 /* check if the current register has already been allocated
2079 for another input aliased to an output */
2080 int k2, i2;
2081 for (k2 = 0 ; k2 < k ; k2++) {
2082 i2 = def->sorted_args[nb_oargs + k2];
2083 if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
2084 (new_args[i2] == ts->reg)) {
2085 goto allocate_in_reg;
2086 }
2087 }
5ff9d6a4 2088 }
c896fe29
FB
2089 }
2090 reg = ts->reg;
2091 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2092 /* nothing to do : the constraint is satisfied */
2093 } else {
2094 allocate_in_reg:
2095 /* allocate a new register matching the constraint
2096 and move the temporary register into it */
91478cef
RH
2097 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs,
2098 ts->indirect_base);
3b6dac34 2099 tcg_out_mov(s, ts->type, reg, ts->reg);
c896fe29 2100 }
c896fe29
FB
2101 new_args[i] = reg;
2102 const_args[i] = 0;
2103 tcg_regset_set_reg(allocated_regs, reg);
2104 iarg_end: ;
2105 }
2106
a52ad07e
AJ
2107 /* mark dead temporaries and free the associated registers */
2108 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2109 if (IS_DEAD_ARG(i)) {
f8bf00f1 2110 temp_dead(s, &s->temps[args[i]]);
a52ad07e
AJ
2111 }
2112 }
2113
e8996ee0
FB
2114 if (def->flags & TCG_OPF_BB_END) {
2115 tcg_reg_alloc_bb_end(s, allocated_regs);
2116 } else {
e8996ee0
FB
2117 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2118 /* XXX: permit generic clobber register list ? */
c8074023
RH
2119 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
2120 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
b3915dbb 2121 tcg_reg_free(s, i, allocated_regs);
e8996ee0 2122 }
c896fe29 2123 }
3d5c5f87
AJ
2124 }
2125 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2126 /* sync globals if the op has side effects and might trigger
2127 an exception. */
2128 sync_globals(s, allocated_regs);
c896fe29 2129 }
e8996ee0
FB
2130
2131 /* satisfy the output constraints */
2132 tcg_regset_set(allocated_regs, s->reserved_regs);
2133 for(k = 0; k < nb_oargs; k++) {
2134 i = def->sorted_args[k];
2135 arg = args[i];
2136 arg_ct = &def->args_ct[i];
2137 ts = &s->temps[arg];
2138 if (arg_ct->ct & TCG_CT_ALIAS) {
2139 reg = new_args[arg_ct->alias_index];
2140 } else {
2141 /* if fixed register, we try to use it */
2142 reg = ts->reg;
2143 if (ts->fixed_reg &&
2144 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2145 goto oarg_end;
2146 }
91478cef
RH
2147 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs,
2148 ts->indirect_base);
c896fe29 2149 }
e8996ee0
FB
2150 tcg_regset_set_reg(allocated_regs, reg);
2151 /* if a fixed register is used, then a move will be done afterwards */
2152 if (!ts->fixed_reg) {
ec7a869d 2153 if (ts->val_type == TEMP_VAL_REG) {
f8b2f202 2154 s->reg_to_temp[ts->reg] = NULL;
ec7a869d
AJ
2155 }
2156 ts->val_type = TEMP_VAL_REG;
2157 ts->reg = reg;
2158 /* temp value is modified, so the value kept in memory is
2159 potentially not the same */
2160 ts->mem_coherent = 0;
f8b2f202 2161 s->reg_to_temp[reg] = ts;
e8996ee0
FB
2162 }
2163 oarg_end:
2164 new_args[i] = reg;
c896fe29 2165 }
c896fe29
FB
2166 }
2167
c896fe29
FB
2168 /* emit instruction */
2169 tcg_out_op(s, opc, new_args, const_args);
2170
2171 /* move the outputs in the correct register if needed */
2172 for(i = 0; i < nb_oargs; i++) {
2173 ts = &s->temps[args[i]];
2174 reg = new_args[i];
2175 if (ts->fixed_reg && ts->reg != reg) {
3b6dac34 2176 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29 2177 }
ec7a869d 2178 if (NEED_SYNC_ARG(i)) {
59d7c14e
RH
2179 temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
2180 } else if (IS_DEAD_ARG(i)) {
f8bf00f1 2181 temp_dead(s, ts);
ec7a869d 2182 }
c896fe29
FB
2183 }
2184}
2185
b03cce8e
FB
2186#ifdef TCG_TARGET_STACK_GROWSUP
2187#define STACK_DIR(x) (-(x))
2188#else
2189#define STACK_DIR(x) (x)
2190#endif
2191
c45cb8bb 2192static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
a1b3c48d 2193 const TCGArg * const args, TCGLifeData arg_life)
c896fe29 2194{
b6638662
RH
2195 int flags, nb_regs, i;
2196 TCGReg reg;
cf066674 2197 TCGArg arg;
c896fe29 2198 TCGTemp *ts;
d3452f1f
RH
2199 intptr_t stack_offset;
2200 size_t call_stack_size;
cf066674
RH
2201 tcg_insn_unit *func_addr;
2202 int allocate_args;
c896fe29 2203 TCGRegSet allocated_regs;
c896fe29 2204
cf066674
RH
2205 func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs];
2206 flags = args[nb_oargs + nb_iargs + 1];
c896fe29 2207
6e17d0c5 2208 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
c45cb8bb
RH
2209 if (nb_regs > nb_iargs) {
2210 nb_regs = nb_iargs;
cf066674 2211 }
c896fe29
FB
2212
2213 /* assign stack slots first */
c45cb8bb 2214 call_stack_size = (nb_iargs - nb_regs) * sizeof(tcg_target_long);
c896fe29
FB
2215 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2216 ~(TCG_TARGET_STACK_ALIGN - 1);
b03cce8e
FB
2217 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2218 if (allocate_args) {
345649c0
BS
2219 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2220 preallocate call stack */
2221 tcg_abort();
b03cce8e 2222 }
39cf05d3
FB
2223
2224 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
c45cb8bb 2225 for(i = nb_regs; i < nb_iargs; i++) {
c896fe29 2226 arg = args[nb_oargs + i];
39cf05d3
FB
2227#ifdef TCG_TARGET_STACK_GROWSUP
2228 stack_offset -= sizeof(tcg_target_long);
2229#endif
2230 if (arg != TCG_CALL_DUMMY_ARG) {
2231 ts = &s->temps[arg];
40ae5c62
RH
2232 temp_load(s, ts, tcg_target_available_regs[ts->type],
2233 s->reserved_regs);
2234 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
c896fe29 2235 }
39cf05d3
FB
2236#ifndef TCG_TARGET_STACK_GROWSUP
2237 stack_offset += sizeof(tcg_target_long);
2238#endif
c896fe29
FB
2239 }
2240
2241 /* assign input registers */
2242 tcg_regset_set(allocated_regs, s->reserved_regs);
2243 for(i = 0; i < nb_regs; i++) {
2244 arg = args[nb_oargs + i];
39cf05d3
FB
2245 if (arg != TCG_CALL_DUMMY_ARG) {
2246 ts = &s->temps[arg];
2247 reg = tcg_target_call_iarg_regs[i];
b3915dbb 2248 tcg_reg_free(s, reg, allocated_regs);
40ae5c62 2249
39cf05d3
FB
2250 if (ts->val_type == TEMP_VAL_REG) {
2251 if (ts->reg != reg) {
3b6dac34 2252 tcg_out_mov(s, ts->type, reg, ts->reg);
39cf05d3 2253 }
39cf05d3 2254 } else {
40ae5c62
RH
2255 TCGRegSet arg_set;
2256
2257 tcg_regset_clear(arg_set);
2258 tcg_regset_set_reg(arg_set, reg);
2259 temp_load(s, ts, arg_set, allocated_regs);
c896fe29 2260 }
40ae5c62 2261
39cf05d3 2262 tcg_regset_set_reg(allocated_regs, reg);
c896fe29 2263 }
c896fe29
FB
2264 }
2265
c896fe29 2266 /* mark dead temporaries and free the associated registers */
866cb6cb 2267 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 2268 if (IS_DEAD_ARG(i)) {
f8bf00f1 2269 temp_dead(s, &s->temps[args[i]]);
c896fe29
FB
2270 }
2271 }
2272
2273 /* clobber call registers */
c8074023
RH
2274 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
2275 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
b3915dbb 2276 tcg_reg_free(s, i, allocated_regs);
c896fe29
FB
2277 }
2278 }
78505279
AJ
2279
2280 /* Save globals if they might be written by the helper, sync them if
2281 they might be read. */
2282 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2283 /* Nothing to do */
2284 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2285 sync_globals(s, allocated_regs);
2286 } else {
b9c18f56
AJ
2287 save_globals(s, allocated_regs);
2288 }
c896fe29 2289
cf066674 2290 tcg_out_call(s, func_addr);
c896fe29
FB
2291
2292 /* assign output registers and emit moves if needed */
2293 for(i = 0; i < nb_oargs; i++) {
2294 arg = args[i];
2295 ts = &s->temps[arg];
2296 reg = tcg_target_call_oarg_regs[i];
eabb7b91 2297 tcg_debug_assert(s->reg_to_temp[reg] == NULL);
34b1a49c 2298
c896fe29
FB
2299 if (ts->fixed_reg) {
2300 if (ts->reg != reg) {
3b6dac34 2301 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29
FB
2302 }
2303 } else {
ec7a869d 2304 if (ts->val_type == TEMP_VAL_REG) {
f8b2f202 2305 s->reg_to_temp[ts->reg] = NULL;
ec7a869d
AJ
2306 }
2307 ts->val_type = TEMP_VAL_REG;
2308 ts->reg = reg;
2309 ts->mem_coherent = 0;
f8b2f202 2310 s->reg_to_temp[reg] = ts;
ec7a869d 2311 if (NEED_SYNC_ARG(i)) {
59d7c14e
RH
2312 temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
2313 } else if (IS_DEAD_ARG(i)) {
f8bf00f1 2314 temp_dead(s, ts);
8c11ad25 2315 }
c896fe29
FB
2316 }
2317 }
c896fe29
FB
2318}
2319
2320#ifdef CONFIG_PROFILER
2321
54604f74 2322static int64_t tcg_table_op_count[NB_OPS];
c896fe29 2323
246ae24d 2324void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
c896fe29
FB
2325{
2326 int i;
d70724ce 2327
15fc7daa 2328 for (i = 0; i < NB_OPS; i++) {
246ae24d
MF
2329 cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name,
2330 tcg_table_op_count[i]);
c896fe29 2331 }
c896fe29 2332}
246ae24d
MF
2333#else
2334void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
2335{
2336 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2337}
c896fe29
FB
2338#endif
2339
2340
5bd2ec3d 2341int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
c896fe29 2342{
fca8a500 2343 int i, oi, oi_next, num_insns;
c896fe29 2344
04fe6400
RH
2345#ifdef CONFIG_PROFILER
2346 {
2347 int n;
2348
dcb8e758 2349 n = s->gen_op_buf[0].prev + 1;
04fe6400
RH
2350 s->op_count += n;
2351 if (n > s->op_count_max) {
2352 s->op_count_max = n;
2353 }
2354
2355 n = s->nb_temps;
2356 s->temp_count += n;
2357 if (n > s->temp_count_max) {
2358 s->temp_count_max = n;
2359 }
2360 }
2361#endif
2362
c896fe29 2363#ifdef DEBUG_DISAS
d977e1c2
AB
2364 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
2365 && qemu_log_in_addr_range(tb->pc))) {
93fcfe39 2366 qemu_log("OP:\n");
eeacee4d 2367 tcg_dump_ops(s);
93fcfe39 2368 qemu_log("\n");
c896fe29
FB
2369 }
2370#endif
2371
c5cc28ff
AJ
2372#ifdef CONFIG_PROFILER
2373 s->opt_time -= profile_getclock();
2374#endif
2375
8f2e8c07 2376#ifdef USE_TCG_OPTIMIZATIONS
c45cb8bb 2377 tcg_optimize(s);
8f2e8c07
KB
2378#endif
2379
a23a9ec6 2380#ifdef CONFIG_PROFILER
c5cc28ff 2381 s->opt_time += profile_getclock();
a23a9ec6
FB
2382 s->la_time -= profile_getclock();
2383#endif
c5cc28ff 2384
c896fe29 2385 tcg_liveness_analysis(s);
c5cc28ff 2386
a23a9ec6
FB
2387#ifdef CONFIG_PROFILER
2388 s->la_time += profile_getclock();
2389#endif
c896fe29
FB
2390
2391#ifdef DEBUG_DISAS
d977e1c2
AB
2392 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
2393 && qemu_log_in_addr_range(tb->pc))) {
c5cc28ff 2394 qemu_log("OP after optimization and liveness analysis:\n");
eeacee4d 2395 tcg_dump_ops(s);
93fcfe39 2396 qemu_log("\n");
c896fe29
FB
2397 }
2398#endif
2399
2400 tcg_reg_alloc_start(s);
2401
5bd2ec3d
AB
2402 s->code_buf = tb->tc_ptr;
2403 s->code_ptr = tb->tc_ptr;
c896fe29 2404
9ecefc84
RH
2405 tcg_out_tb_init(s);
2406
fca8a500 2407 num_insns = -1;
dcb8e758 2408 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
c45cb8bb
RH
2409 TCGOp * const op = &s->gen_op_buf[oi];
2410 TCGArg * const args = &s->gen_opparam_buf[op->args];
2411 TCGOpcode opc = op->opc;
2412 const TCGOpDef *def = &tcg_op_defs[opc];
a1b3c48d 2413 TCGLifeData arg_life = s->op_arg_life[oi];
b3db8758 2414
c45cb8bb 2415 oi_next = op->next;
c896fe29 2416#ifdef CONFIG_PROFILER
54604f74 2417 tcg_table_op_count[opc]++;
c896fe29 2418#endif
c45cb8bb
RH
2419
2420 switch (opc) {
c896fe29 2421 case INDEX_op_mov_i32:
c896fe29 2422 case INDEX_op_mov_i64:
a1b3c48d 2423 tcg_reg_alloc_mov(s, def, args, arg_life);
c896fe29 2424 break;
e8996ee0 2425 case INDEX_op_movi_i32:
e8996ee0 2426 case INDEX_op_movi_i64:
a1b3c48d 2427 tcg_reg_alloc_movi(s, args, arg_life);
e8996ee0 2428 break;
765b842a 2429 case INDEX_op_insn_start:
fca8a500
RH
2430 if (num_insns >= 0) {
2431 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
2432 }
2433 num_insns++;
bad729e2
RH
2434 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
2435 target_ulong a;
2436#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
2437 a = ((target_ulong)args[i * 2 + 1] << 32) | args[i * 2];
2438#else
2439 a = args[i];
2440#endif
fca8a500 2441 s->gen_insn_data[num_insns][i] = a;
bad729e2 2442 }
c896fe29 2443 break;
5ff9d6a4 2444 case INDEX_op_discard:
f8bf00f1 2445 temp_dead(s, &s->temps[args[0]]);
5ff9d6a4 2446 break;
c896fe29 2447 case INDEX_op_set_label:
e8996ee0 2448 tcg_reg_alloc_bb_end(s, s->reserved_regs);
bec16311 2449 tcg_out_label(s, arg_label(args[0]), s->code_ptr);
c896fe29
FB
2450 break;
2451 case INDEX_op_call:
a1b3c48d 2452 tcg_reg_alloc_call(s, op->callo, op->calli, args, arg_life);
c45cb8bb 2453 break;
c896fe29 2454 default:
25c4d9cc
RH
2455 /* Sanity check that we've not introduced any unhandled opcodes. */
2456 if (def->flags & TCG_OPF_NOT_PRESENT) {
2457 tcg_abort();
2458 }
c896fe29
FB
2459 /* Note: in order to speed up the code, it would be much
2460 faster to have specialized register allocator functions for
2461 some common argument patterns */
a1b3c48d 2462 tcg_reg_alloc_op(s, def, opc, args, arg_life);
c896fe29
FB
2463 break;
2464 }
8d8fdbae 2465#ifdef CONFIG_DEBUG_TCG
c896fe29
FB
2466 check_regs(s);
2467#endif
b125f9dc
RH
2468 /* Test for (pending) buffer overflow. The assumption is that any
2469 one operation beginning below the high water mark cannot overrun
2470 the buffer completely. Thus we can test for overflow after
2471 generating code without having to check during generation. */
644da9b3 2472 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
b125f9dc
RH
2473 return -1;
2474 }
c896fe29 2475 }
fca8a500
RH
2476 tcg_debug_assert(num_insns >= 0);
2477 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
c45cb8bb 2478
b76f0d8c 2479 /* Generate TB finalization at the end of block */
23dceda6
RH
2480 if (!tcg_out_tb_finalize(s)) {
2481 return -1;
2482 }
c896fe29
FB
2483
2484 /* flush instruction cache */
1813e175 2485 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
2aeabc08 2486
1813e175 2487 return tcg_current_code_size(s);
c896fe29
FB
2488}
2489
a23a9ec6 2490#ifdef CONFIG_PROFILER
405cf9ff 2491void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6
FB
2492{
2493 TCGContext *s = &tcg_ctx;
fca8a500
RH
2494 int64_t tb_count = s->tb_count;
2495 int64_t tb_div_count = tb_count ? tb_count : 1;
2496 int64_t tot = s->interm_time + s->code_time;
a23a9ec6 2497
a23a9ec6
FB
2498 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2499 tot, tot / 2.4e9);
2500 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
fca8a500
RH
2501 tb_count, s->tb_count1 - tb_count,
2502 (double)(s->tb_count1 - s->tb_count)
2503 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
a23a9ec6 2504 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
fca8a500 2505 (double)s->op_count / tb_div_count, s->op_count_max);
a23a9ec6 2506 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
fca8a500 2507 (double)s->del_op_count / tb_div_count);
a23a9ec6 2508 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
fca8a500
RH
2509 (double)s->temp_count / tb_div_count, s->temp_count_max);
2510 cpu_fprintf(f, "avg host code/TB %0.1f\n",
2511 (double)s->code_out_len / tb_div_count);
2512 cpu_fprintf(f, "avg search data/TB %0.1f\n",
2513 (double)s->search_out_len / tb_div_count);
a23a9ec6
FB
2514
2515 cpu_fprintf(f, "cycles/op %0.1f\n",
2516 s->op_count ? (double)tot / s->op_count : 0);
2517 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2518 s->code_in_len ? (double)tot / s->code_in_len : 0);
2519 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2520 s->code_out_len ? (double)tot / s->code_out_len : 0);
fca8a500
RH
2521 cpu_fprintf(f, "cycles/search byte %0.1f\n",
2522 s->search_out_len ? (double)tot / s->search_out_len : 0);
2523 if (tot == 0) {
a23a9ec6 2524 tot = 1;
fca8a500 2525 }
a23a9ec6
FB
2526 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2527 (double)s->interm_time / tot * 100.0);
2528 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2529 (double)s->code_time / tot * 100.0);
c5cc28ff
AJ
2530 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2531 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2532 * 100.0);
a23a9ec6
FB
2533 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2534 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2535 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2536 s->restore_count);
2537 cpu_fprintf(f, " avg cycles %0.1f\n",
2538 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
a23a9ec6
FB
2539}
2540#else
405cf9ff 2541void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6 2542{
24bf7b3a 2543 cpu_fprintf(f, "[TCG profiler not compiled]\n");
a23a9ec6
FB
2544}
2545#endif
813da627
RH
2546
2547#ifdef ELF_HOST_MACHINE
5872bbf2
RH
2548/* In order to use this feature, the backend needs to do three things:
2549
2550 (1) Define ELF_HOST_MACHINE to indicate both what value to
2551 put into the ELF image and to indicate support for the feature.
2552
2553 (2) Define tcg_register_jit. This should create a buffer containing
2554 the contents of a .debug_frame section that describes the post-
2555 prologue unwind info for the tcg machine.
2556
2557 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2558*/
813da627
RH
2559
2560/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2561typedef enum {
2562 JIT_NOACTION = 0,
2563 JIT_REGISTER_FN,
2564 JIT_UNREGISTER_FN
2565} jit_actions_t;
2566
2567struct jit_code_entry {
2568 struct jit_code_entry *next_entry;
2569 struct jit_code_entry *prev_entry;
2570 const void *symfile_addr;
2571 uint64_t symfile_size;
2572};
2573
2574struct jit_descriptor {
2575 uint32_t version;
2576 uint32_t action_flag;
2577 struct jit_code_entry *relevant_entry;
2578 struct jit_code_entry *first_entry;
2579};
2580
2581void __jit_debug_register_code(void) __attribute__((noinline));
2582void __jit_debug_register_code(void)
2583{
2584 asm("");
2585}
2586
2587/* Must statically initialize the version, because GDB may check
2588 the version before we can set it. */
2589struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2590
2591/* End GDB interface. */
2592
2593static int find_string(const char *strtab, const char *str)
2594{
2595 const char *p = strtab + 1;
2596
2597 while (1) {
2598 if (strcmp(p, str) == 0) {
2599 return p - strtab;
2600 }
2601 p += strlen(p) + 1;
2602 }
2603}
2604
5872bbf2 2605static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2c90784a
RH
2606 const void *debug_frame,
2607 size_t debug_frame_size)
813da627 2608{
5872bbf2
RH
2609 struct __attribute__((packed)) DebugInfo {
2610 uint32_t len;
2611 uint16_t version;
2612 uint32_t abbrev;
2613 uint8_t ptr_size;
2614 uint8_t cu_die;
2615 uint16_t cu_lang;
2616 uintptr_t cu_low_pc;
2617 uintptr_t cu_high_pc;
2618 uint8_t fn_die;
2619 char fn_name[16];
2620 uintptr_t fn_low_pc;
2621 uintptr_t fn_high_pc;
2622 uint8_t cu_eoc;
2623 };
813da627
RH
2624
2625 struct ElfImage {
2626 ElfW(Ehdr) ehdr;
2627 ElfW(Phdr) phdr;
5872bbf2
RH
2628 ElfW(Shdr) shdr[7];
2629 ElfW(Sym) sym[2];
2630 struct DebugInfo di;
2631 uint8_t da[24];
2632 char str[80];
2633 };
2634
2635 struct ElfImage *img;
2636
2637 static const struct ElfImage img_template = {
2638 .ehdr = {
2639 .e_ident[EI_MAG0] = ELFMAG0,
2640 .e_ident[EI_MAG1] = ELFMAG1,
2641 .e_ident[EI_MAG2] = ELFMAG2,
2642 .e_ident[EI_MAG3] = ELFMAG3,
2643 .e_ident[EI_CLASS] = ELF_CLASS,
2644 .e_ident[EI_DATA] = ELF_DATA,
2645 .e_ident[EI_VERSION] = EV_CURRENT,
2646 .e_type = ET_EXEC,
2647 .e_machine = ELF_HOST_MACHINE,
2648 .e_version = EV_CURRENT,
2649 .e_phoff = offsetof(struct ElfImage, phdr),
2650 .e_shoff = offsetof(struct ElfImage, shdr),
2651 .e_ehsize = sizeof(ElfW(Shdr)),
2652 .e_phentsize = sizeof(ElfW(Phdr)),
2653 .e_phnum = 1,
2654 .e_shentsize = sizeof(ElfW(Shdr)),
2655 .e_shnum = ARRAY_SIZE(img->shdr),
2656 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
abbb3eae
RH
2657#ifdef ELF_HOST_FLAGS
2658 .e_flags = ELF_HOST_FLAGS,
2659#endif
2660#ifdef ELF_OSABI
2661 .e_ident[EI_OSABI] = ELF_OSABI,
2662#endif
5872bbf2
RH
2663 },
2664 .phdr = {
2665 .p_type = PT_LOAD,
2666 .p_flags = PF_X,
2667 },
2668 .shdr = {
2669 [0] = { .sh_type = SHT_NULL },
2670 /* Trick: The contents of code_gen_buffer are not present in
2671 this fake ELF file; that got allocated elsewhere. Therefore
2672 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2673 will not look for contents. We can record any address. */
2674 [1] = { /* .text */
2675 .sh_type = SHT_NOBITS,
2676 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2677 },
2678 [2] = { /* .debug_info */
2679 .sh_type = SHT_PROGBITS,
2680 .sh_offset = offsetof(struct ElfImage, di),
2681 .sh_size = sizeof(struct DebugInfo),
2682 },
2683 [3] = { /* .debug_abbrev */
2684 .sh_type = SHT_PROGBITS,
2685 .sh_offset = offsetof(struct ElfImage, da),
2686 .sh_size = sizeof(img->da),
2687 },
2688 [4] = { /* .debug_frame */
2689 .sh_type = SHT_PROGBITS,
2690 .sh_offset = sizeof(struct ElfImage),
2691 },
2692 [5] = { /* .symtab */
2693 .sh_type = SHT_SYMTAB,
2694 .sh_offset = offsetof(struct ElfImage, sym),
2695 .sh_size = sizeof(img->sym),
2696 .sh_info = 1,
2697 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2698 .sh_entsize = sizeof(ElfW(Sym)),
2699 },
2700 [6] = { /* .strtab */
2701 .sh_type = SHT_STRTAB,
2702 .sh_offset = offsetof(struct ElfImage, str),
2703 .sh_size = sizeof(img->str),
2704 }
2705 },
2706 .sym = {
2707 [1] = { /* code_gen_buffer */
2708 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2709 .st_shndx = 1,
2710 }
2711 },
2712 .di = {
2713 .len = sizeof(struct DebugInfo) - 4,
2714 .version = 2,
2715 .ptr_size = sizeof(void *),
2716 .cu_die = 1,
2717 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2718 .fn_die = 2,
2719 .fn_name = "code_gen_buffer"
2720 },
2721 .da = {
2722 1, /* abbrev number (the cu) */
2723 0x11, 1, /* DW_TAG_compile_unit, has children */
2724 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2725 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2726 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2727 0, 0, /* end of abbrev */
2728 2, /* abbrev number (the fn) */
2729 0x2e, 0, /* DW_TAG_subprogram, no children */
2730 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2731 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2732 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2733 0, 0, /* end of abbrev */
2734 0 /* no more abbrev */
2735 },
2736 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2737 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
813da627
RH
2738 };
2739
2740 /* We only need a single jit entry; statically allocate it. */
2741 static struct jit_code_entry one_entry;
2742
5872bbf2 2743 uintptr_t buf = (uintptr_t)buf_ptr;
813da627 2744 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2c90784a 2745 DebugFrameHeader *dfh;
813da627 2746
5872bbf2
RH
2747 img = g_malloc(img_size);
2748 *img = img_template;
813da627 2749
5872bbf2
RH
2750 img->phdr.p_vaddr = buf;
2751 img->phdr.p_paddr = buf;
2752 img->phdr.p_memsz = buf_size;
813da627 2753
813da627 2754 img->shdr[1].sh_name = find_string(img->str, ".text");
5872bbf2 2755 img->shdr[1].sh_addr = buf;
813da627
RH
2756 img->shdr[1].sh_size = buf_size;
2757
5872bbf2
RH
2758 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2759 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2760
2761 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2762 img->shdr[4].sh_size = debug_frame_size;
2763
2764 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2765 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2766
2767 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2768 img->sym[1].st_value = buf;
2769 img->sym[1].st_size = buf_size;
813da627 2770
5872bbf2 2771 img->di.cu_low_pc = buf;
45aba097 2772 img->di.cu_high_pc = buf + buf_size;
5872bbf2 2773 img->di.fn_low_pc = buf;
45aba097 2774 img->di.fn_high_pc = buf + buf_size;
813da627 2775
2c90784a
RH
2776 dfh = (DebugFrameHeader *)(img + 1);
2777 memcpy(dfh, debug_frame, debug_frame_size);
2778 dfh->fde.func_start = buf;
2779 dfh->fde.func_len = buf_size;
2780
813da627
RH
2781#ifdef DEBUG_JIT
2782 /* Enable this block to be able to debug the ELF image file creation.
2783 One can use readelf, objdump, or other inspection utilities. */
2784 {
2785 FILE *f = fopen("/tmp/qemu.jit", "w+b");
2786 if (f) {
5872bbf2 2787 if (fwrite(img, img_size, 1, f) != img_size) {
813da627
RH
2788 /* Avoid stupid unused return value warning for fwrite. */
2789 }
2790 fclose(f);
2791 }
2792 }
2793#endif
2794
2795 one_entry.symfile_addr = img;
2796 one_entry.symfile_size = img_size;
2797
2798 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2799 __jit_debug_descriptor.relevant_entry = &one_entry;
2800 __jit_debug_descriptor.first_entry = &one_entry;
2801 __jit_debug_register_code();
2802}
2803#else
5872bbf2
RH
2804/* No support for the feature. Provide the entry point expected by exec.c,
2805 and implement the internal function we declared earlier. */
813da627
RH
2806
2807static void tcg_register_jit_int(void *buf, size_t size,
2c90784a
RH
2808 const void *debug_frame,
2809 size_t debug_frame_size)
813da627
RH
2810{
2811}
2812
2813void tcg_register_jit(void *buf, size_t buf_size)
2814{
2815}
2816#endif /* ELF_HOST_MACHINE */