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