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