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