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