]> Git Repo - qemu.git/blame - tcg/tcg.c
tcg: Push tcg-runtime routines into exec/helper-*
[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
RH
358 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
359 (gpointer)all_helpers[i].name);
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) {
1152 ret = g_hash_table_lookup(s->helpers, (gpointer)val);
4dc81f28 1153 }
6e085f72 1154 return ret;
4dc81f28
FB
1155}
1156
f48f3ede
BS
1157static const char * const cond_name[] =
1158{
0aed257f
RH
1159 [TCG_COND_NEVER] = "never",
1160 [TCG_COND_ALWAYS] = "always",
f48f3ede
BS
1161 [TCG_COND_EQ] = "eq",
1162 [TCG_COND_NE] = "ne",
1163 [TCG_COND_LT] = "lt",
1164 [TCG_COND_GE] = "ge",
1165 [TCG_COND_LE] = "le",
1166 [TCG_COND_GT] = "gt",
1167 [TCG_COND_LTU] = "ltu",
1168 [TCG_COND_GEU] = "geu",
1169 [TCG_COND_LEU] = "leu",
1170 [TCG_COND_GTU] = "gtu"
1171};
1172
f713d6ad
RH
1173static const char * const ldst_name[] =
1174{
1175 [MO_UB] = "ub",
1176 [MO_SB] = "sb",
1177 [MO_LEUW] = "leuw",
1178 [MO_LESW] = "lesw",
1179 [MO_LEUL] = "leul",
1180 [MO_LESL] = "lesl",
1181 [MO_LEQ] = "leq",
1182 [MO_BEUW] = "beuw",
1183 [MO_BESW] = "besw",
1184 [MO_BEUL] = "beul",
1185 [MO_BESL] = "besl",
1186 [MO_BEQ] = "beq",
1187};
1188
eeacee4d 1189void tcg_dump_ops(TCGContext *s)
c896fe29
FB
1190{
1191 const uint16_t *opc_ptr;
1192 const TCGArg *args;
1193 TCGArg arg;
a9751609
RH
1194 TCGOpcode c;
1195 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
c896fe29
FB
1196 const TCGOpDef *def;
1197 char buf[128];
1198
7e4597d7 1199 first_insn = 1;
92414b31 1200 opc_ptr = s->gen_opc_buf;
1ff0a2c5 1201 args = s->gen_opparam_buf;
efd7f486 1202 while (opc_ptr < s->gen_opc_ptr) {
c896fe29
FB
1203 c = *opc_ptr++;
1204 def = &tcg_op_defs[c];
7e4597d7
FB
1205 if (c == INDEX_op_debug_insn_start) {
1206 uint64_t pc;
1207#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
1208 pc = ((uint64_t)args[1] << 32) | args[0];
1209#else
1210 pc = args[0];
1211#endif
eeacee4d
BS
1212 if (!first_insn) {
1213 qemu_log("\n");
1214 }
1215 qemu_log(" ---- 0x%" PRIx64, pc);
7e4597d7
FB
1216 first_insn = 0;
1217 nb_oargs = def->nb_oargs;
1218 nb_iargs = def->nb_iargs;
1219 nb_cargs = def->nb_cargs;
1220 } else if (c == INDEX_op_call) {
c896fe29 1221 TCGArg arg;
4dc81f28 1222
c896fe29
FB
1223 /* variable number of arguments */
1224 arg = *args++;
1225 nb_oargs = arg >> 16;
1226 nb_iargs = arg & 0xffff;
1227 nb_cargs = def->nb_cargs;
c896fe29 1228
cf066674
RH
1229 /* function name, flags, out args */
1230 qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
1231 tcg_find_helper(s, args[nb_oargs + nb_iargs]),
1232 args[nb_oargs + nb_iargs + 1], nb_oargs);
1233 for (i = 0; i < nb_oargs; i++) {
1234 qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
eeacee4d 1235 args[i]));
b03cce8e 1236 }
cf066674
RH
1237 for (i = 0; i < nb_iargs; i++) {
1238 TCGArg arg = args[nb_oargs + i];
1239 const char *t = "<dummy>";
1240 if (arg != TCG_CALL_DUMMY_ARG) {
1241 t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);
eeacee4d 1242 }
cf066674 1243 qemu_log(",%s", t);
e8996ee0 1244 }
b03cce8e 1245 } else {
eeacee4d 1246 qemu_log(" %s ", def->name);
b03cce8e
FB
1247 if (c == INDEX_op_nopn) {
1248 /* variable number of arguments */
1249 nb_cargs = *args;
1250 nb_oargs = 0;
1251 nb_iargs = 0;
1252 } else {
1253 nb_oargs = def->nb_oargs;
1254 nb_iargs = def->nb_iargs;
1255 nb_cargs = def->nb_cargs;
1256 }
1257
1258 k = 0;
1259 for(i = 0; i < nb_oargs; i++) {
eeacee4d
BS
1260 if (k != 0) {
1261 qemu_log(",");
1262 }
1263 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1264 args[k++]));
b03cce8e
FB
1265 }
1266 for(i = 0; i < nb_iargs; i++) {
eeacee4d
BS
1267 if (k != 0) {
1268 qemu_log(",");
1269 }
1270 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1271 args[k++]));
b03cce8e 1272 }
be210acb
RH
1273 switch (c) {
1274 case INDEX_op_brcond_i32:
be210acb 1275 case INDEX_op_setcond_i32:
ffc5ea09 1276 case INDEX_op_movcond_i32:
ffc5ea09 1277 case INDEX_op_brcond2_i32:
be210acb 1278 case INDEX_op_setcond2_i32:
ffc5ea09 1279 case INDEX_op_brcond_i64:
be210acb 1280 case INDEX_op_setcond_i64:
ffc5ea09 1281 case INDEX_op_movcond_i64:
eeacee4d
BS
1282 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1283 qemu_log(",%s", cond_name[args[k++]]);
1284 } else {
1285 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1286 }
f48f3ede 1287 i = 1;
be210acb 1288 break;
f713d6ad
RH
1289 case INDEX_op_qemu_ld_i32:
1290 case INDEX_op_qemu_st_i32:
1291 case INDEX_op_qemu_ld_i64:
1292 case INDEX_op_qemu_st_i64:
1293 if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) {
1294 qemu_log(",%s", ldst_name[args[k++]]);
1295 } else {
1296 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1297 }
1298 i = 1;
1299 break;
be210acb 1300 default:
f48f3ede 1301 i = 0;
be210acb
RH
1302 break;
1303 }
f48f3ede 1304 for(; i < nb_cargs; i++) {
eeacee4d
BS
1305 if (k != 0) {
1306 qemu_log(",");
1307 }
b03cce8e 1308 arg = args[k++];
eeacee4d 1309 qemu_log("$0x%" TCG_PRIlx, arg);
b03cce8e 1310 }
c896fe29 1311 }
eeacee4d 1312 qemu_log("\n");
c896fe29
FB
1313 args += nb_iargs + nb_oargs + nb_cargs;
1314 }
1315}
1316
1317/* we give more priority to constraints with less registers */
1318static int get_constraint_priority(const TCGOpDef *def, int k)
1319{
1320 const TCGArgConstraint *arg_ct;
1321
1322 int i, n;
1323 arg_ct = &def->args_ct[k];
1324 if (arg_ct->ct & TCG_CT_ALIAS) {
1325 /* an alias is equivalent to a single register */
1326 n = 1;
1327 } else {
1328 if (!(arg_ct->ct & TCG_CT_REG))
1329 return 0;
1330 n = 0;
1331 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1332 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1333 n++;
1334 }
1335 }
1336 return TCG_TARGET_NB_REGS - n + 1;
1337}
1338
1339/* sort from highest priority to lowest */
1340static void sort_constraints(TCGOpDef *def, int start, int n)
1341{
1342 int i, j, p1, p2, tmp;
1343
1344 for(i = 0; i < n; i++)
1345 def->sorted_args[start + i] = start + i;
1346 if (n <= 1)
1347 return;
1348 for(i = 0; i < n - 1; i++) {
1349 for(j = i + 1; j < n; j++) {
1350 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1351 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1352 if (p1 < p2) {
1353 tmp = def->sorted_args[start + i];
1354 def->sorted_args[start + i] = def->sorted_args[start + j];
1355 def->sorted_args[start + j] = tmp;
1356 }
1357 }
1358 }
1359}
1360
1361void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1362{
a9751609 1363 TCGOpcode op;
c896fe29
FB
1364 TCGOpDef *def;
1365 const char *ct_str;
1366 int i, nb_args;
1367
1368 for(;;) {
a9751609 1369 if (tdefs->op == (TCGOpcode)-1)
c896fe29
FB
1370 break;
1371 op = tdefs->op;
c3b08d0e 1372 assert((unsigned)op < NB_OPS);
c896fe29 1373 def = &tcg_op_defs[op];
c68aaa18
SW
1374#if defined(CONFIG_DEBUG_TCG)
1375 /* Duplicate entry in op definitions? */
1376 assert(!def->used);
1377 def->used = 1;
1378#endif
c896fe29
FB
1379 nb_args = def->nb_iargs + def->nb_oargs;
1380 for(i = 0; i < nb_args; i++) {
1381 ct_str = tdefs->args_ct_str[i];
c68aaa18
SW
1382 /* Incomplete TCGTargetOpDef entry? */
1383 assert(ct_str != NULL);
c896fe29
FB
1384 tcg_regset_clear(def->args_ct[i].u.regs);
1385 def->args_ct[i].ct = 0;
1386 if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1387 int oarg;
1388 oarg = ct_str[0] - '0';
1389 assert(oarg < def->nb_oargs);
1390 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1391 /* TCG_CT_ALIAS is for the output arguments. The input
5ff9d6a4 1392 argument is tagged with TCG_CT_IALIAS. */
c896fe29 1393 def->args_ct[i] = def->args_ct[oarg];
5ff9d6a4
FB
1394 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1395 def->args_ct[oarg].alias_index = i;
c896fe29 1396 def->args_ct[i].ct |= TCG_CT_IALIAS;
5ff9d6a4 1397 def->args_ct[i].alias_index = oarg;
c896fe29
FB
1398 } else {
1399 for(;;) {
1400 if (*ct_str == '\0')
1401 break;
1402 switch(*ct_str) {
1403 case 'i':
1404 def->args_ct[i].ct |= TCG_CT_CONST;
1405 ct_str++;
1406 break;
1407 default:
1408 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1409 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1410 ct_str, i, def->name);
1411 exit(1);
1412 }
1413 }
1414 }
1415 }
1416 }
1417
c68aaa18
SW
1418 /* TCGTargetOpDef entry with too much information? */
1419 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1420
c896fe29
FB
1421 /* sort the constraints (XXX: this is just an heuristic) */
1422 sort_constraints(def, 0, def->nb_oargs);
1423 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1424
1425#if 0
1426 {
1427 int i;
1428
1429 printf("%s: sorted=", def->name);
1430 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1431 printf(" %d", def->sorted_args[i]);
1432 printf("\n");
1433 }
1434#endif
1435 tdefs++;
1436 }
1437
c68aaa18 1438#if defined(CONFIG_DEBUG_TCG)
a9751609 1439 i = 0;
c68aaa18 1440 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
f412c762 1441 const TCGOpDef *def = &tcg_op_defs[op];
c1a61f6c 1442 if (def->flags & TCG_OPF_NOT_PRESENT) {
c68aaa18 1443 /* Wrong entry in op definitions? */
f412c762
RH
1444 if (def->used) {
1445 fprintf(stderr, "Invalid op definition for %s\n", def->name);
a9751609
RH
1446 i = 1;
1447 }
c68aaa18
SW
1448 } else {
1449 /* Missing entry in op definitions? */
f412c762
RH
1450 if (!def->used) {
1451 fprintf(stderr, "Missing op definition for %s\n", def->name);
a9751609
RH
1452 i = 1;
1453 }
c68aaa18
SW
1454 }
1455 }
a9751609
RH
1456 if (i == 1) {
1457 tcg_abort();
1458 }
c68aaa18 1459#endif
c896fe29
FB
1460}
1461
1462#ifdef USE_LIVENESS_ANALYSIS
1463
1464/* set a nop for an operation using 'nb_args' */
1465static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
1466 TCGArg *args, int nb_args)
1467{
1468 if (nb_args == 0) {
1469 *opc_ptr = INDEX_op_nop;
1470 } else {
1471 *opc_ptr = INDEX_op_nopn;
1472 args[0] = nb_args;
1473 args[nb_args - 1] = nb_args;
1474 }
1475}
1476
9c43b68d
AJ
1477/* liveness analysis: end of function: all temps are dead, and globals
1478 should be in memory. */
1479static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1480 uint8_t *mem_temps)
c896fe29 1481{
9c43b68d
AJ
1482 memset(dead_temps, 1, s->nb_temps);
1483 memset(mem_temps, 1, s->nb_globals);
1484 memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
c896fe29
FB
1485}
1486
9c43b68d
AJ
1487/* liveness analysis: end of basic block: all temps are dead, globals
1488 and local temps should be in memory. */
1489static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1490 uint8_t *mem_temps)
641d5fbe
FB
1491{
1492 int i;
641d5fbe 1493
9c43b68d
AJ
1494 memset(dead_temps, 1, s->nb_temps);
1495 memset(mem_temps, 1, s->nb_globals);
641d5fbe 1496 for(i = s->nb_globals; i < s->nb_temps; i++) {
9c43b68d 1497 mem_temps[i] = s->temps[i].temp_local;
641d5fbe
FB
1498 }
1499}
1500
866cb6cb 1501/* Liveness analysis : update the opc_dead_args array to tell if a
c896fe29
FB
1502 given input arguments is dead. Instructions updating dead
1503 temporaries are removed. */
8fcd3692 1504static void tcg_liveness_analysis(TCGContext *s)
c896fe29 1505{
cf066674 1506 int i, op_index, nb_args, nb_iargs, nb_oargs, nb_ops;
03271524 1507 TCGOpcode op, op_new, op_new2;
cf066674 1508 TCGArg *args, arg;
c896fe29 1509 const TCGOpDef *def;
9c43b68d 1510 uint8_t *dead_temps, *mem_temps;
ec7a869d
AJ
1511 uint16_t dead_args;
1512 uint8_t sync_args;
03271524 1513 bool have_op_new2;
c896fe29 1514
efd7f486 1515 s->gen_opc_ptr++; /* skip end */
c896fe29 1516
92414b31 1517 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
c896fe29 1518
866cb6cb 1519 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
ec7a869d 1520 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
c896fe29
FB
1521
1522 dead_temps = tcg_malloc(s->nb_temps);
9c43b68d
AJ
1523 mem_temps = tcg_malloc(s->nb_temps);
1524 tcg_la_func_end(s, dead_temps, mem_temps);
c896fe29 1525
c4afe5c4 1526 args = s->gen_opparam_ptr;
c896fe29
FB
1527 op_index = nb_ops - 1;
1528 while (op_index >= 0) {
92414b31 1529 op = s->gen_opc_buf[op_index];
c896fe29
FB
1530 def = &tcg_op_defs[op];
1531 switch(op) {
1532 case INDEX_op_call:
c6e113f5
FB
1533 {
1534 int call_flags;
c896fe29 1535
c6e113f5
FB
1536 nb_args = args[-1];
1537 args -= nb_args;
cf066674
RH
1538 arg = *args++;
1539 nb_iargs = arg & 0xffff;
1540 nb_oargs = arg >> 16;
1541 call_flags = args[nb_oargs + nb_iargs + 1];
c6e113f5
FB
1542
1543 /* pure functions can be removed if their result is not
1544 used */
78505279 1545 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
cf066674 1546 for (i = 0; i < nb_oargs; i++) {
c6e113f5 1547 arg = args[i];
9c43b68d 1548 if (!dead_temps[arg] || mem_temps[arg]) {
c6e113f5 1549 goto do_not_remove_call;
9c43b68d 1550 }
c6e113f5 1551 }
92414b31 1552 tcg_set_nop(s, s->gen_opc_buf + op_index,
c6e113f5
FB
1553 args - 1, nb_args);
1554 } else {
1555 do_not_remove_call:
c896fe29 1556
c6e113f5 1557 /* output args are dead */
6b64b624 1558 dead_args = 0;
ec7a869d 1559 sync_args = 0;
cf066674 1560 for (i = 0; i < nb_oargs; i++) {
c6e113f5 1561 arg = args[i];
6b64b624
AJ
1562 if (dead_temps[arg]) {
1563 dead_args |= (1 << i);
1564 }
9c43b68d
AJ
1565 if (mem_temps[arg]) {
1566 sync_args |= (1 << i);
1567 }
c6e113f5 1568 dead_temps[arg] = 1;
9c43b68d 1569 mem_temps[arg] = 0;
c6e113f5 1570 }
78505279
AJ
1571
1572 if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1573 /* globals should be synced to memory */
1574 memset(mem_temps, 1, s->nb_globals);
1575 }
1576 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1577 TCG_CALL_NO_READ_GLOBALS))) {
9c43b68d
AJ
1578 /* globals should go back to memory */
1579 memset(dead_temps, 1, s->nb_globals);
b9c18f56
AJ
1580 }
1581
c6e113f5 1582 /* input args are live */
cf066674 1583 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 1584 arg = args[i];
39cf05d3
FB
1585 if (arg != TCG_CALL_DUMMY_ARG) {
1586 if (dead_temps[arg]) {
866cb6cb 1587 dead_args |= (1 << i);
39cf05d3
FB
1588 }
1589 dead_temps[arg] = 0;
c6e113f5 1590 }
c6e113f5 1591 }
866cb6cb 1592 s->op_dead_args[op_index] = dead_args;
ec7a869d 1593 s->op_sync_args[op_index] = sync_args;
c896fe29 1594 }
c6e113f5 1595 args--;
c896fe29 1596 }
c896fe29 1597 break;
7e4597d7
FB
1598 case INDEX_op_debug_insn_start:
1599 args -= def->nb_args;
1600 break;
c896fe29
FB
1601 case INDEX_op_nopn:
1602 nb_args = args[-1];
1603 args -= nb_args;
1604 break;
5ff9d6a4
FB
1605 case INDEX_op_discard:
1606 args--;
1607 /* mark the temporary as dead */
1608 dead_temps[args[0]] = 1;
9c43b68d 1609 mem_temps[args[0]] = 0;
5ff9d6a4 1610 break;
c896fe29
FB
1611 case INDEX_op_end:
1612 break;
1305c451
RH
1613
1614 case INDEX_op_add2_i32:
f1fae40c
RH
1615 op_new = INDEX_op_add_i32;
1616 goto do_addsub2;
1305c451 1617 case INDEX_op_sub2_i32:
f1fae40c
RH
1618 op_new = INDEX_op_sub_i32;
1619 goto do_addsub2;
1620 case INDEX_op_add2_i64:
1621 op_new = INDEX_op_add_i64;
1622 goto do_addsub2;
1623 case INDEX_op_sub2_i64:
1624 op_new = INDEX_op_sub_i64;
1625 do_addsub2:
1305c451
RH
1626 args -= 6;
1627 nb_iargs = 4;
1628 nb_oargs = 2;
1629 /* Test if the high part of the operation is dead, but not
1630 the low part. The result can be optimized to a simple
1631 add or sub. This happens often for x86_64 guest when the
1632 cpu mode is set to 32 bit. */
3c5645fa
KB
1633 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1634 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1305c451
RH
1635 goto do_remove;
1636 }
1637 /* Create the single operation plus nop. */
f1fae40c 1638 s->gen_opc_buf[op_index] = op = op_new;
1305c451
RH
1639 args[1] = args[2];
1640 args[2] = args[4];
92414b31
EV
1641 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1642 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1305c451
RH
1643 /* Fall through and mark the single-word operation live. */
1644 nb_iargs = 2;
1645 nb_oargs = 1;
1646 }
1647 goto do_not_remove;
1648
1414968a 1649 case INDEX_op_mulu2_i32:
03271524
RH
1650 op_new = INDEX_op_mul_i32;
1651 op_new2 = INDEX_op_muluh_i32;
1652 have_op_new2 = TCG_TARGET_HAS_muluh_i32;
1653 goto do_mul2;
f1fae40c
RH
1654 case INDEX_op_muls2_i32:
1655 op_new = INDEX_op_mul_i32;
03271524
RH
1656 op_new2 = INDEX_op_mulsh_i32;
1657 have_op_new2 = TCG_TARGET_HAS_mulsh_i32;
f1fae40c
RH
1658 goto do_mul2;
1659 case INDEX_op_mulu2_i64:
03271524
RH
1660 op_new = INDEX_op_mul_i64;
1661 op_new2 = INDEX_op_muluh_i64;
1662 have_op_new2 = TCG_TARGET_HAS_muluh_i64;
1663 goto do_mul2;
f1fae40c
RH
1664 case INDEX_op_muls2_i64:
1665 op_new = INDEX_op_mul_i64;
03271524
RH
1666 op_new2 = INDEX_op_mulsh_i64;
1667 have_op_new2 = TCG_TARGET_HAS_mulsh_i64;
1668 goto do_mul2;
f1fae40c 1669 do_mul2:
1414968a
RH
1670 args -= 4;
1671 nb_iargs = 2;
1672 nb_oargs = 2;
3c5645fa
KB
1673 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1674 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
03271524 1675 /* Both parts of the operation are dead. */
1414968a
RH
1676 goto do_remove;
1677 }
03271524 1678 /* The high part of the operation is dead; generate the low. */
f1fae40c 1679 s->gen_opc_buf[op_index] = op = op_new;
1414968a
RH
1680 args[1] = args[2];
1681 args[2] = args[3];
03271524
RH
1682 } else if (have_op_new2 && dead_temps[args[0]]
1683 && !mem_temps[args[0]]) {
1684 /* The low part of the operation is dead; generate the high. */
1685 s->gen_opc_buf[op_index] = op = op_new2;
1686 args[0] = args[1];
1687 args[1] = args[2];
1688 args[2] = args[3];
1689 } else {
1690 goto do_not_remove;
1414968a 1691 }
03271524
RH
1692 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1693 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1694 /* Mark the single-word operation live. */
1695 nb_oargs = 1;
1414968a
RH
1696 goto do_not_remove;
1697
c896fe29 1698 default:
1305c451 1699 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
49516bc0
AJ
1700 args -= def->nb_args;
1701 nb_iargs = def->nb_iargs;
1702 nb_oargs = def->nb_oargs;
c896fe29 1703
49516bc0
AJ
1704 /* Test if the operation can be removed because all
1705 its outputs are dead. We assume that nb_oargs == 0
1706 implies side effects */
1707 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1708 for(i = 0; i < nb_oargs; i++) {
1709 arg = args[i];
9c43b68d 1710 if (!dead_temps[arg] || mem_temps[arg]) {
49516bc0 1711 goto do_not_remove;
9c43b68d 1712 }
49516bc0 1713 }
1305c451 1714 do_remove:
92414b31 1715 tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
c896fe29 1716#ifdef CONFIG_PROFILER
49516bc0 1717 s->del_op_count++;
c896fe29 1718#endif
49516bc0
AJ
1719 } else {
1720 do_not_remove:
c896fe29 1721
49516bc0 1722 /* output args are dead */
6b64b624 1723 dead_args = 0;
ec7a869d 1724 sync_args = 0;
49516bc0
AJ
1725 for(i = 0; i < nb_oargs; i++) {
1726 arg = args[i];
6b64b624
AJ
1727 if (dead_temps[arg]) {
1728 dead_args |= (1 << i);
1729 }
9c43b68d
AJ
1730 if (mem_temps[arg]) {
1731 sync_args |= (1 << i);
1732 }
49516bc0 1733 dead_temps[arg] = 1;
9c43b68d 1734 mem_temps[arg] = 0;
49516bc0
AJ
1735 }
1736
1737 /* if end of basic block, update */
1738 if (def->flags & TCG_OPF_BB_END) {
9c43b68d 1739 tcg_la_bb_end(s, dead_temps, mem_temps);
3d5c5f87
AJ
1740 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1741 /* globals should be synced to memory */
9c43b68d 1742 memset(mem_temps, 1, s->nb_globals);
49516bc0
AJ
1743 }
1744
1745 /* input args are live */
866cb6cb
AJ
1746 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1747 arg = args[i];
49516bc0 1748 if (dead_temps[arg]) {
866cb6cb 1749 dead_args |= (1 << i);
c896fe29 1750 }
49516bc0 1751 dead_temps[arg] = 0;
c896fe29 1752 }
866cb6cb 1753 s->op_dead_args[op_index] = dead_args;
ec7a869d 1754 s->op_sync_args[op_index] = sync_args;
c896fe29
FB
1755 }
1756 break;
1757 }
1758 op_index--;
1759 }
1760
1ff0a2c5 1761 if (args != s->gen_opparam_buf) {
c896fe29 1762 tcg_abort();
1ff0a2c5 1763 }
c896fe29
FB
1764}
1765#else
1766/* dummy liveness analysis */
655feed5 1767static void tcg_liveness_analysis(TCGContext *s)
c896fe29
FB
1768{
1769 int nb_ops;
92414b31 1770 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
c896fe29 1771
866cb6cb
AJ
1772 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1773 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
ec7a869d
AJ
1774 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1775 memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
c896fe29
FB
1776}
1777#endif
1778
1779#ifndef NDEBUG
1780static void dump_regs(TCGContext *s)
1781{
1782 TCGTemp *ts;
1783 int i;
1784 char buf[64];
1785
1786 for(i = 0; i < s->nb_temps; i++) {
1787 ts = &s->temps[i];
ac56dd48 1788 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
c896fe29
FB
1789 switch(ts->val_type) {
1790 case TEMP_VAL_REG:
1791 printf("%s", tcg_target_reg_names[ts->reg]);
1792 break;
1793 case TEMP_VAL_MEM:
1794 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1795 break;
1796 case TEMP_VAL_CONST:
1797 printf("$0x%" TCG_PRIlx, ts->val);
1798 break;
1799 case TEMP_VAL_DEAD:
1800 printf("D");
1801 break;
1802 default:
1803 printf("???");
1804 break;
1805 }
1806 printf("\n");
1807 }
1808
1809 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1810 if (s->reg_to_temp[i] >= 0) {
1811 printf("%s: %s\n",
1812 tcg_target_reg_names[i],
ac56dd48 1813 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
c896fe29
FB
1814 }
1815 }
1816}
1817
1818static void check_regs(TCGContext *s)
1819{
1820 int reg, k;
1821 TCGTemp *ts;
1822 char buf[64];
1823
1824 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1825 k = s->reg_to_temp[reg];
1826 if (k >= 0) {
1827 ts = &s->temps[k];
1828 if (ts->val_type != TEMP_VAL_REG ||
1829 ts->reg != reg) {
1830 printf("Inconsistency for register %s:\n",
1831 tcg_target_reg_names[reg]);
b03cce8e 1832 goto fail;
c896fe29
FB
1833 }
1834 }
1835 }
1836 for(k = 0; k < s->nb_temps; k++) {
1837 ts = &s->temps[k];
1838 if (ts->val_type == TEMP_VAL_REG &&
1839 !ts->fixed_reg &&
1840 s->reg_to_temp[ts->reg] != k) {
1841 printf("Inconsistency for temp %s:\n",
ac56dd48 1842 tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
b03cce8e 1843 fail:
c896fe29
FB
1844 printf("reg state:\n");
1845 dump_regs(s);
1846 tcg_abort();
1847 }
1848 }
1849}
1850#endif
1851
1852static void temp_allocate_frame(TCGContext *s, int temp)
1853{
1854 TCGTemp *ts;
1855 ts = &s->temps[temp];
9b9c37c3
RH
1856#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1857 /* Sparc64 stack is accessed with offset of 2047 */
b591dc59
BS
1858 s->current_frame_offset = (s->current_frame_offset +
1859 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1860 ~(sizeof(tcg_target_long) - 1);
f44c9960 1861#endif
b591dc59
BS
1862 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1863 s->frame_end) {
5ff9d6a4 1864 tcg_abort();
b591dc59 1865 }
c896fe29
FB
1866 ts->mem_offset = s->current_frame_offset;
1867 ts->mem_reg = s->frame_reg;
1868 ts->mem_allocated = 1;
e2c6d1b4 1869 s->current_frame_offset += sizeof(tcg_target_long);
c896fe29
FB
1870}
1871
7f6ceedf
AJ
1872/* sync register 'reg' by saving it to the corresponding temporary */
1873static inline void tcg_reg_sync(TCGContext *s, int reg)
1874{
1875 TCGTemp *ts;
1876 int temp;
1877
1878 temp = s->reg_to_temp[reg];
1879 ts = &s->temps[temp];
1880 assert(ts->val_type == TEMP_VAL_REG);
1881 if (!ts->mem_coherent && !ts->fixed_reg) {
1882 if (!ts->mem_allocated) {
1883 temp_allocate_frame(s, temp);
1884 }
1885 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1886 }
1887 ts->mem_coherent = 1;
1888}
1889
c896fe29
FB
1890/* free register 'reg' by spilling the corresponding temporary if necessary */
1891static void tcg_reg_free(TCGContext *s, int reg)
1892{
c896fe29
FB
1893 int temp;
1894
1895 temp = s->reg_to_temp[reg];
1896 if (temp != -1) {
7f6ceedf
AJ
1897 tcg_reg_sync(s, reg);
1898 s->temps[temp].val_type = TEMP_VAL_MEM;
c896fe29
FB
1899 s->reg_to_temp[reg] = -1;
1900 }
1901}
1902
1903/* Allocate a register belonging to reg1 & ~reg2 */
1904static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1905{
1906 int i, reg;
1907 TCGRegSet reg_ct;
1908
1909 tcg_regset_andnot(reg_ct, reg1, reg2);
1910
1911 /* first try free registers */
0954d0d9 1912 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
c896fe29
FB
1913 reg = tcg_target_reg_alloc_order[i];
1914 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1915 return reg;
1916 }
1917
1918 /* XXX: do better spill choice */
0954d0d9 1919 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
c896fe29
FB
1920 reg = tcg_target_reg_alloc_order[i];
1921 if (tcg_regset_test_reg(reg_ct, reg)) {
1922 tcg_reg_free(s, reg);
1923 return reg;
1924 }
1925 }
1926
1927 tcg_abort();
1928}
1929
639368dd
AJ
1930/* mark a temporary as dead. */
1931static inline void temp_dead(TCGContext *s, int temp)
1932{
1933 TCGTemp *ts;
1934
1935 ts = &s->temps[temp];
1936 if (!ts->fixed_reg) {
1937 if (ts->val_type == TEMP_VAL_REG) {
1938 s->reg_to_temp[ts->reg] = -1;
1939 }
e5138db5 1940 if (temp < s->nb_globals || ts->temp_local) {
639368dd
AJ
1941 ts->val_type = TEMP_VAL_MEM;
1942 } else {
1943 ts->val_type = TEMP_VAL_DEAD;
1944 }
1945 }
1946}
1947
1ad80729 1948/* sync a temporary to memory. 'allocated_regs' is used in case a
641d5fbe 1949 temporary registers needs to be allocated to store a constant. */
1ad80729 1950static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
641d5fbe
FB
1951{
1952 TCGTemp *ts;
641d5fbe
FB
1953
1954 ts = &s->temps[temp];
1955 if (!ts->fixed_reg) {
1956 switch(ts->val_type) {
1ad80729
AJ
1957 case TEMP_VAL_CONST:
1958 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1959 allocated_regs);
1960 ts->val_type = TEMP_VAL_REG;
1961 s->reg_to_temp[ts->reg] = temp;
1962 ts->mem_coherent = 0;
1963 tcg_out_movi(s, ts->type, ts->reg, ts->val);
1964 /* fallthrough*/
641d5fbe 1965 case TEMP_VAL_REG:
1ad80729 1966 tcg_reg_sync(s, ts->reg);
641d5fbe
FB
1967 break;
1968 case TEMP_VAL_DEAD:
641d5fbe
FB
1969 case TEMP_VAL_MEM:
1970 break;
1971 default:
1972 tcg_abort();
1973 }
1974 }
1975}
1976
1ad80729
AJ
1977/* save a temporary to memory. 'allocated_regs' is used in case a
1978 temporary registers needs to be allocated to store a constant. */
1979static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1980{
2c0366f0
AJ
1981#ifdef USE_LIVENESS_ANALYSIS
1982 /* The liveness analysis already ensures that globals are back
1983 in memory. Keep an assert for safety. */
1984 assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1985#else
1ad80729
AJ
1986 temp_sync(s, temp, allocated_regs);
1987 temp_dead(s, temp);
2c0366f0 1988#endif
1ad80729
AJ
1989}
1990
9814dd27 1991/* save globals to their canonical location and assume they can be
e8996ee0
FB
1992 modified be the following code. 'allocated_regs' is used in case a
1993 temporary registers needs to be allocated to store a constant. */
1994static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
c896fe29 1995{
641d5fbe 1996 int i;
c896fe29
FB
1997
1998 for(i = 0; i < s->nb_globals; i++) {
641d5fbe 1999 temp_save(s, i, allocated_regs);
c896fe29 2000 }
e5097dc8
FB
2001}
2002
3d5c5f87
AJ
2003/* sync globals to their canonical location and assume they can be
2004 read by the following code. 'allocated_regs' is used in case a
2005 temporary registers needs to be allocated to store a constant. */
2006static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
2007{
2008 int i;
2009
2010 for (i = 0; i < s->nb_globals; i++) {
2011#ifdef USE_LIVENESS_ANALYSIS
2012 assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
2013 s->temps[i].mem_coherent);
2014#else
2015 temp_sync(s, i, allocated_regs);
2016#endif
2017 }
2018}
2019
e5097dc8 2020/* at the end of a basic block, we assume all temporaries are dead and
e8996ee0
FB
2021 all globals are stored at their canonical location. */
2022static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
e5097dc8
FB
2023{
2024 TCGTemp *ts;
2025 int i;
2026
c896fe29
FB
2027 for(i = s->nb_globals; i < s->nb_temps; i++) {
2028 ts = &s->temps[i];
641d5fbe
FB
2029 if (ts->temp_local) {
2030 temp_save(s, i, allocated_regs);
2031 } else {
2c0366f0
AJ
2032#ifdef USE_LIVENESS_ANALYSIS
2033 /* The liveness analysis already ensures that temps are dead.
2034 Keep an assert for safety. */
2035 assert(ts->val_type == TEMP_VAL_DEAD);
2036#else
639368dd 2037 temp_dead(s, i);
2c0366f0 2038#endif
c896fe29
FB
2039 }
2040 }
e8996ee0
FB
2041
2042 save_globals(s, allocated_regs);
c896fe29
FB
2043}
2044
866cb6cb 2045#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
ec7a869d 2046#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
c896fe29 2047
ec7a869d
AJ
2048static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
2049 uint16_t dead_args, uint8_t sync_args)
e8996ee0
FB
2050{
2051 TCGTemp *ots;
2052 tcg_target_ulong val;
2053
2054 ots = &s->temps[args[0]];
2055 val = args[1];
2056
2057 if (ots->fixed_reg) {
2058 /* for fixed registers, we do not do any constant
2059 propagation */
2060 tcg_out_movi(s, ots->type, ots->reg, val);
2061 } else {
1235fc06 2062 /* The movi is not explicitly generated here */
e8996ee0
FB
2063 if (ots->val_type == TEMP_VAL_REG)
2064 s->reg_to_temp[ots->reg] = -1;
2065 ots->val_type = TEMP_VAL_CONST;
2066 ots->val = val;
2067 }
ec7a869d
AJ
2068 if (NEED_SYNC_ARG(0)) {
2069 temp_sync(s, args[0], s->reserved_regs);
2070 }
4c4e1ab2
AJ
2071 if (IS_DEAD_ARG(0)) {
2072 temp_dead(s, args[0]);
2073 }
e8996ee0
FB
2074}
2075
c896fe29 2076static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
ec7a869d
AJ
2077 const TCGArg *args, uint16_t dead_args,
2078 uint8_t sync_args)
c896fe29 2079{
c29c1d7e 2080 TCGRegSet allocated_regs;
c896fe29 2081 TCGTemp *ts, *ots;
450445d5 2082 TCGType otype, itype;
c896fe29 2083
c29c1d7e 2084 tcg_regset_set(allocated_regs, s->reserved_regs);
c896fe29
FB
2085 ots = &s->temps[args[0]];
2086 ts = &s->temps[args[1]];
450445d5
RH
2087
2088 /* Note that otype != itype for no-op truncation. */
2089 otype = ots->type;
2090 itype = ts->type;
c29c1d7e
AJ
2091
2092 /* If the source value is not in a register, and we're going to be
2093 forced to have it in a register in order to perform the copy,
2094 then copy the SOURCE value into its own register first. That way
2095 we don't have to reload SOURCE the next time it is used. */
2096 if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
2097 || ts->val_type == TEMP_VAL_MEM) {
450445d5 2098 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[itype],
af3cbfbe 2099 allocated_regs);
c29c1d7e 2100 if (ts->val_type == TEMP_VAL_MEM) {
450445d5 2101 tcg_out_ld(s, itype, ts->reg, ts->mem_reg, ts->mem_offset);
c29c1d7e
AJ
2102 ts->mem_coherent = 1;
2103 } else if (ts->val_type == TEMP_VAL_CONST) {
450445d5 2104 tcg_out_movi(s, itype, ts->reg, ts->val);
c29c1d7e
AJ
2105 }
2106 s->reg_to_temp[ts->reg] = args[1];
2107 ts->val_type = TEMP_VAL_REG;
2108 }
c896fe29 2109
c29c1d7e
AJ
2110 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
2111 /* mov to a non-saved dead register makes no sense (even with
2112 liveness analysis disabled). */
2113 assert(NEED_SYNC_ARG(0));
2114 /* The code above should have moved the temp to a register. */
2115 assert(ts->val_type == TEMP_VAL_REG);
2116 if (!ots->mem_allocated) {
2117 temp_allocate_frame(s, args[0]);
2118 }
450445d5 2119 tcg_out_st(s, otype, ts->reg, ots->mem_reg, ots->mem_offset);
c29c1d7e
AJ
2120 if (IS_DEAD_ARG(1)) {
2121 temp_dead(s, args[1]);
2122 }
2123 temp_dead(s, args[0]);
2124 } else if (ts->val_type == TEMP_VAL_CONST) {
2125 /* propagate constant */
2126 if (ots->val_type == TEMP_VAL_REG) {
2127 s->reg_to_temp[ots->reg] = -1;
2128 }
2129 ots->val_type = TEMP_VAL_CONST;
2130 ots->val = ts->val;
2131 } else {
2132 /* The code in the first if block should have moved the
2133 temp to a register. */
2134 assert(ts->val_type == TEMP_VAL_REG);
866cb6cb 2135 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
c896fe29 2136 /* the mov can be suppressed */
c29c1d7e 2137 if (ots->val_type == TEMP_VAL_REG) {
c896fe29 2138 s->reg_to_temp[ots->reg] = -1;
c29c1d7e
AJ
2139 }
2140 ots->reg = ts->reg;
639368dd 2141 temp_dead(s, args[1]);
c896fe29 2142 } else {
c29c1d7e
AJ
2143 if (ots->val_type != TEMP_VAL_REG) {
2144 /* When allocating a new register, make sure to not spill the
2145 input one. */
2146 tcg_regset_set_reg(allocated_regs, ts->reg);
450445d5 2147 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
af3cbfbe 2148 allocated_regs);
c896fe29 2149 }
450445d5 2150 tcg_out_mov(s, otype, ots->reg, ts->reg);
c896fe29 2151 }
c29c1d7e
AJ
2152 ots->val_type = TEMP_VAL_REG;
2153 ots->mem_coherent = 0;
2154 s->reg_to_temp[ots->reg] = args[0];
2155 if (NEED_SYNC_ARG(0)) {
2156 tcg_reg_sync(s, ots->reg);
c896fe29 2157 }
ec7a869d 2158 }
c896fe29
FB
2159}
2160
2161static void tcg_reg_alloc_op(TCGContext *s,
a9751609 2162 const TCGOpDef *def, TCGOpcode opc,
ec7a869d
AJ
2163 const TCGArg *args, uint16_t dead_args,
2164 uint8_t sync_args)
c896fe29
FB
2165{
2166 TCGRegSet allocated_regs;
2167 int i, k, nb_iargs, nb_oargs, reg;
2168 TCGArg arg;
2169 const TCGArgConstraint *arg_ct;
2170 TCGTemp *ts;
2171 TCGArg new_args[TCG_MAX_OP_ARGS];
2172 int const_args[TCG_MAX_OP_ARGS];
2173
2174 nb_oargs = def->nb_oargs;
2175 nb_iargs = def->nb_iargs;
2176
2177 /* copy constants */
2178 memcpy(new_args + nb_oargs + nb_iargs,
2179 args + nb_oargs + nb_iargs,
2180 sizeof(TCGArg) * def->nb_cargs);
2181
2182 /* satisfy input constraints */
2183 tcg_regset_set(allocated_regs, s->reserved_regs);
2184 for(k = 0; k < nb_iargs; k++) {
2185 i = def->sorted_args[nb_oargs + k];
2186 arg = args[i];
2187 arg_ct = &def->args_ct[i];
2188 ts = &s->temps[arg];
2189 if (ts->val_type == TEMP_VAL_MEM) {
2190 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
e4d5434c 2191 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
c896fe29
FB
2192 ts->val_type = TEMP_VAL_REG;
2193 ts->reg = reg;
2194 ts->mem_coherent = 1;
2195 s->reg_to_temp[reg] = arg;
2196 } else if (ts->val_type == TEMP_VAL_CONST) {
f6c6afc1 2197 if (tcg_target_const_match(ts->val, ts->type, arg_ct)) {
c896fe29
FB
2198 /* constant is OK for instruction */
2199 const_args[i] = 1;
2200 new_args[i] = ts->val;
2201 goto iarg_end;
2202 } else {
e8996ee0 2203 /* need to move to a register */
c896fe29
FB
2204 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2205 tcg_out_movi(s, ts->type, reg, ts->val);
e8996ee0
FB
2206 ts->val_type = TEMP_VAL_REG;
2207 ts->reg = reg;
2208 ts->mem_coherent = 0;
2209 s->reg_to_temp[reg] = arg;
c896fe29
FB
2210 }
2211 }
2212 assert(ts->val_type == TEMP_VAL_REG);
5ff9d6a4
FB
2213 if (arg_ct->ct & TCG_CT_IALIAS) {
2214 if (ts->fixed_reg) {
2215 /* if fixed register, we must allocate a new register
2216 if the alias is not the same register */
2217 if (arg != args[arg_ct->alias_index])
2218 goto allocate_in_reg;
2219 } else {
2220 /* if the input is aliased to an output and if it is
2221 not dead after the instruction, we must allocate
2222 a new register and move it */
866cb6cb 2223 if (!IS_DEAD_ARG(i)) {
5ff9d6a4 2224 goto allocate_in_reg;
866cb6cb 2225 }
5ff9d6a4 2226 }
c896fe29
FB
2227 }
2228 reg = ts->reg;
2229 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2230 /* nothing to do : the constraint is satisfied */
2231 } else {
2232 allocate_in_reg:
2233 /* allocate a new register matching the constraint
2234 and move the temporary register into it */
2235 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
3b6dac34 2236 tcg_out_mov(s, ts->type, reg, ts->reg);
c896fe29 2237 }
c896fe29
FB
2238 new_args[i] = reg;
2239 const_args[i] = 0;
2240 tcg_regset_set_reg(allocated_regs, reg);
2241 iarg_end: ;
2242 }
2243
a52ad07e
AJ
2244 /* mark dead temporaries and free the associated registers */
2245 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2246 if (IS_DEAD_ARG(i)) {
2247 temp_dead(s, args[i]);
2248 }
2249 }
2250
e8996ee0
FB
2251 if (def->flags & TCG_OPF_BB_END) {
2252 tcg_reg_alloc_bb_end(s, allocated_regs);
2253 } else {
e8996ee0
FB
2254 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2255 /* XXX: permit generic clobber register list ? */
2256 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2257 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2258 tcg_reg_free(s, reg);
2259 }
c896fe29 2260 }
3d5c5f87
AJ
2261 }
2262 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2263 /* sync globals if the op has side effects and might trigger
2264 an exception. */
2265 sync_globals(s, allocated_regs);
c896fe29 2266 }
e8996ee0
FB
2267
2268 /* satisfy the output constraints */
2269 tcg_regset_set(allocated_regs, s->reserved_regs);
2270 for(k = 0; k < nb_oargs; k++) {
2271 i = def->sorted_args[k];
2272 arg = args[i];
2273 arg_ct = &def->args_ct[i];
2274 ts = &s->temps[arg];
2275 if (arg_ct->ct & TCG_CT_ALIAS) {
2276 reg = new_args[arg_ct->alias_index];
2277 } else {
2278 /* if fixed register, we try to use it */
2279 reg = ts->reg;
2280 if (ts->fixed_reg &&
2281 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2282 goto oarg_end;
2283 }
2284 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
c896fe29 2285 }
e8996ee0
FB
2286 tcg_regset_set_reg(allocated_regs, reg);
2287 /* if a fixed register is used, then a move will be done afterwards */
2288 if (!ts->fixed_reg) {
ec7a869d
AJ
2289 if (ts->val_type == TEMP_VAL_REG) {
2290 s->reg_to_temp[ts->reg] = -1;
2291 }
2292 ts->val_type = TEMP_VAL_REG;
2293 ts->reg = reg;
2294 /* temp value is modified, so the value kept in memory is
2295 potentially not the same */
2296 ts->mem_coherent = 0;
2297 s->reg_to_temp[reg] = arg;
e8996ee0
FB
2298 }
2299 oarg_end:
2300 new_args[i] = reg;
c896fe29 2301 }
c896fe29
FB
2302 }
2303
c896fe29
FB
2304 /* emit instruction */
2305 tcg_out_op(s, opc, new_args, const_args);
2306
2307 /* move the outputs in the correct register if needed */
2308 for(i = 0; i < nb_oargs; i++) {
2309 ts = &s->temps[args[i]];
2310 reg = new_args[i];
2311 if (ts->fixed_reg && ts->reg != reg) {
3b6dac34 2312 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29 2313 }
ec7a869d
AJ
2314 if (NEED_SYNC_ARG(i)) {
2315 tcg_reg_sync(s, reg);
2316 }
2317 if (IS_DEAD_ARG(i)) {
2318 temp_dead(s, args[i]);
2319 }
c896fe29
FB
2320 }
2321}
2322
b03cce8e
FB
2323#ifdef TCG_TARGET_STACK_GROWSUP
2324#define STACK_DIR(x) (-(x))
2325#else
2326#define STACK_DIR(x) (x)
2327#endif
2328
c896fe29 2329static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
a9751609 2330 TCGOpcode opc, const TCGArg *args,
ec7a869d 2331 uint16_t dead_args, uint8_t sync_args)
c896fe29
FB
2332{
2333 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
cf066674 2334 TCGArg arg;
c896fe29 2335 TCGTemp *ts;
d3452f1f
RH
2336 intptr_t stack_offset;
2337 size_t call_stack_size;
cf066674
RH
2338 tcg_insn_unit *func_addr;
2339 int allocate_args;
c896fe29 2340 TCGRegSet allocated_regs;
c896fe29
FB
2341
2342 arg = *args++;
2343
2344 nb_oargs = arg >> 16;
2345 nb_iargs = arg & 0xffff;
cf066674 2346 nb_params = nb_iargs;
c896fe29 2347
cf066674
RH
2348 func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs];
2349 flags = args[nb_oargs + nb_iargs + 1];
c896fe29 2350
6e17d0c5 2351 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
cf066674 2352 if (nb_regs > nb_params) {
c896fe29 2353 nb_regs = nb_params;
cf066674 2354 }
c896fe29
FB
2355
2356 /* assign stack slots first */
c896fe29
FB
2357 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2358 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2359 ~(TCG_TARGET_STACK_ALIGN - 1);
b03cce8e
FB
2360 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2361 if (allocate_args) {
345649c0
BS
2362 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2363 preallocate call stack */
2364 tcg_abort();
b03cce8e 2365 }
39cf05d3
FB
2366
2367 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
c896fe29
FB
2368 for(i = nb_regs; i < nb_params; i++) {
2369 arg = args[nb_oargs + i];
39cf05d3
FB
2370#ifdef TCG_TARGET_STACK_GROWSUP
2371 stack_offset -= sizeof(tcg_target_long);
2372#endif
2373 if (arg != TCG_CALL_DUMMY_ARG) {
2374 ts = &s->temps[arg];
2375 if (ts->val_type == TEMP_VAL_REG) {
2376 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2377 } else if (ts->val_type == TEMP_VAL_MEM) {
2378 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2379 s->reserved_regs);
2380 /* XXX: not correct if reading values from the stack */
2381 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2382 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2383 } else if (ts->val_type == TEMP_VAL_CONST) {
2384 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2385 s->reserved_regs);
2386 /* XXX: sign extend may be needed on some targets */
2387 tcg_out_movi(s, ts->type, reg, ts->val);
2388 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2389 } else {
2390 tcg_abort();
2391 }
c896fe29 2392 }
39cf05d3
FB
2393#ifndef TCG_TARGET_STACK_GROWSUP
2394 stack_offset += sizeof(tcg_target_long);
2395#endif
c896fe29
FB
2396 }
2397
2398 /* assign input registers */
2399 tcg_regset_set(allocated_regs, s->reserved_regs);
2400 for(i = 0; i < nb_regs; i++) {
2401 arg = args[nb_oargs + i];
39cf05d3
FB
2402 if (arg != TCG_CALL_DUMMY_ARG) {
2403 ts = &s->temps[arg];
2404 reg = tcg_target_call_iarg_regs[i];
2405 tcg_reg_free(s, reg);
2406 if (ts->val_type == TEMP_VAL_REG) {
2407 if (ts->reg != reg) {
3b6dac34 2408 tcg_out_mov(s, ts->type, reg, ts->reg);
39cf05d3
FB
2409 }
2410 } else if (ts->val_type == TEMP_VAL_MEM) {
2411 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2412 } else if (ts->val_type == TEMP_VAL_CONST) {
2413 /* XXX: sign extend ? */
2414 tcg_out_movi(s, ts->type, reg, ts->val);
2415 } else {
2416 tcg_abort();
c896fe29 2417 }
39cf05d3 2418 tcg_regset_set_reg(allocated_regs, reg);
c896fe29 2419 }
c896fe29
FB
2420 }
2421
c896fe29 2422 /* mark dead temporaries and free the associated registers */
866cb6cb 2423 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 2424 if (IS_DEAD_ARG(i)) {
639368dd 2425 temp_dead(s, args[i]);
c896fe29
FB
2426 }
2427 }
2428
2429 /* clobber call registers */
2430 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2431 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2432 tcg_reg_free(s, reg);
2433 }
2434 }
78505279
AJ
2435
2436 /* Save globals if they might be written by the helper, sync them if
2437 they might be read. */
2438 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2439 /* Nothing to do */
2440 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2441 sync_globals(s, allocated_regs);
2442 } else {
b9c18f56
AJ
2443 save_globals(s, allocated_regs);
2444 }
c896fe29 2445
cf066674 2446 tcg_out_call(s, func_addr);
c896fe29
FB
2447
2448 /* assign output registers and emit moves if needed */
2449 for(i = 0; i < nb_oargs; i++) {
2450 arg = args[i];
2451 ts = &s->temps[arg];
2452 reg = tcg_target_call_oarg_regs[i];
e8996ee0 2453 assert(s->reg_to_temp[reg] == -1);
34b1a49c 2454
c896fe29
FB
2455 if (ts->fixed_reg) {
2456 if (ts->reg != reg) {
3b6dac34 2457 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29
FB
2458 }
2459 } else {
ec7a869d
AJ
2460 if (ts->val_type == TEMP_VAL_REG) {
2461 s->reg_to_temp[ts->reg] = -1;
2462 }
2463 ts->val_type = TEMP_VAL_REG;
2464 ts->reg = reg;
2465 ts->mem_coherent = 0;
2466 s->reg_to_temp[reg] = arg;
2467 if (NEED_SYNC_ARG(i)) {
2468 tcg_reg_sync(s, reg);
2469 }
8c11ad25 2470 if (IS_DEAD_ARG(i)) {
639368dd 2471 temp_dead(s, args[i]);
8c11ad25 2472 }
c896fe29
FB
2473 }
2474 }
2475
2476 return nb_iargs + nb_oargs + def->nb_cargs + 1;
2477}
2478
2479#ifdef CONFIG_PROFILER
2480
54604f74 2481static int64_t tcg_table_op_count[NB_OPS];
c896fe29 2482
871e6c35 2483static void dump_op_count(void)
c896fe29
FB
2484{
2485 int i;
2486 FILE *f;
54604f74 2487 f = fopen("/tmp/op.log", "w");
c896fe29 2488 for(i = INDEX_op_end; i < NB_OPS; i++) {
54604f74 2489 fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
c896fe29
FB
2490 }
2491 fclose(f);
2492}
2493#endif
2494
2495
1813e175
RH
2496static inline int tcg_gen_code_common(TCGContext *s,
2497 tcg_insn_unit *gen_code_buf,
2ba1eeb6 2498 long search_pc)
c896fe29 2499{
a9751609
RH
2500 TCGOpcode opc;
2501 int op_index;
c896fe29 2502 const TCGOpDef *def;
c896fe29
FB
2503 const TCGArg *args;
2504
2505#ifdef DEBUG_DISAS
8fec2b8c 2506 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
93fcfe39 2507 qemu_log("OP:\n");
eeacee4d 2508 tcg_dump_ops(s);
93fcfe39 2509 qemu_log("\n");
c896fe29
FB
2510 }
2511#endif
2512
c5cc28ff
AJ
2513#ifdef CONFIG_PROFILER
2514 s->opt_time -= profile_getclock();
2515#endif
2516
8f2e8c07 2517#ifdef USE_TCG_OPTIMIZATIONS
c4afe5c4 2518 s->gen_opparam_ptr =
1ff0a2c5 2519 tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
8f2e8c07
KB
2520#endif
2521
a23a9ec6 2522#ifdef CONFIG_PROFILER
c5cc28ff 2523 s->opt_time += profile_getclock();
a23a9ec6
FB
2524 s->la_time -= profile_getclock();
2525#endif
c5cc28ff 2526
c896fe29 2527 tcg_liveness_analysis(s);
c5cc28ff 2528
a23a9ec6
FB
2529#ifdef CONFIG_PROFILER
2530 s->la_time += profile_getclock();
2531#endif
c896fe29
FB
2532
2533#ifdef DEBUG_DISAS
8fec2b8c 2534 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
c5cc28ff 2535 qemu_log("OP after optimization and liveness analysis:\n");
eeacee4d 2536 tcg_dump_ops(s);
93fcfe39 2537 qemu_log("\n");
c896fe29
FB
2538 }
2539#endif
2540
2541 tcg_reg_alloc_start(s);
2542
2543 s->code_buf = gen_code_buf;
2544 s->code_ptr = gen_code_buf;
2545
9ecefc84
RH
2546 tcg_out_tb_init(s);
2547
1ff0a2c5 2548 args = s->gen_opparam_buf;
c896fe29 2549 op_index = 0;
b3db8758 2550
c896fe29 2551 for(;;) {
92414b31 2552 opc = s->gen_opc_buf[op_index];
c896fe29 2553#ifdef CONFIG_PROFILER
54604f74 2554 tcg_table_op_count[opc]++;
c896fe29
FB
2555#endif
2556 def = &tcg_op_defs[opc];
2557#if 0
2558 printf("%s: %d %d %d\n", def->name,
2559 def->nb_oargs, def->nb_iargs, def->nb_cargs);
2560 // dump_regs(s);
2561#endif
2562 switch(opc) {
2563 case INDEX_op_mov_i32:
c896fe29 2564 case INDEX_op_mov_i64:
ec7a869d
AJ
2565 tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2566 s->op_sync_args[op_index]);
c896fe29 2567 break;
e8996ee0 2568 case INDEX_op_movi_i32:
e8996ee0 2569 case INDEX_op_movi_i64:
ec7a869d
AJ
2570 tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2571 s->op_sync_args[op_index]);
e8996ee0 2572 break;
7e4597d7
FB
2573 case INDEX_op_debug_insn_start:
2574 /* debug instruction */
2575 break;
c896fe29
FB
2576 case INDEX_op_nop:
2577 case INDEX_op_nop1:
2578 case INDEX_op_nop2:
2579 case INDEX_op_nop3:
2580 break;
2581 case INDEX_op_nopn:
2582 args += args[0];
2583 goto next;
5ff9d6a4 2584 case INDEX_op_discard:
639368dd 2585 temp_dead(s, args[0]);
5ff9d6a4 2586 break;
c896fe29 2587 case INDEX_op_set_label:
e8996ee0 2588 tcg_reg_alloc_bb_end(s, s->reserved_regs);
9d6fca70 2589 tcg_out_label(s, args[0], s->code_ptr);
c896fe29
FB
2590 break;
2591 case INDEX_op_call:
ec7a869d
AJ
2592 args += tcg_reg_alloc_call(s, def, opc, args,
2593 s->op_dead_args[op_index],
2594 s->op_sync_args[op_index]);
c896fe29
FB
2595 goto next;
2596 case INDEX_op_end:
2597 goto the_end;
c896fe29 2598 default:
25c4d9cc
RH
2599 /* Sanity check that we've not introduced any unhandled opcodes. */
2600 if (def->flags & TCG_OPF_NOT_PRESENT) {
2601 tcg_abort();
2602 }
c896fe29
FB
2603 /* Note: in order to speed up the code, it would be much
2604 faster to have specialized register allocator functions for
2605 some common argument patterns */
ec7a869d
AJ
2606 tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2607 s->op_sync_args[op_index]);
c896fe29
FB
2608 break;
2609 }
2610 args += def->nb_args;
8df1ca4b 2611 next:
1813e175 2612 if (search_pc >= 0 && search_pc < tcg_current_code_size(s)) {
b314f270 2613 return op_index;
c896fe29
FB
2614 }
2615 op_index++;
2616#ifndef NDEBUG
2617 check_regs(s);
2618#endif
2619 }
2620 the_end:
b76f0d8c
YL
2621 /* Generate TB finalization at the end of block */
2622 tcg_out_tb_finalize(s);
c896fe29
FB
2623 return -1;
2624}
2625
1813e175 2626int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf)
c896fe29
FB
2627{
2628#ifdef CONFIG_PROFILER
2629 {
c896fe29 2630 int n;
92414b31 2631 n = (s->gen_opc_ptr - s->gen_opc_buf);
a23a9ec6
FB
2632 s->op_count += n;
2633 if (n > s->op_count_max)
2634 s->op_count_max = n;
2635
2636 s->temp_count += s->nb_temps;
2637 if (s->nb_temps > s->temp_count_max)
2638 s->temp_count_max = s->nb_temps;
c896fe29
FB
2639 }
2640#endif
2641
2ba1eeb6 2642 tcg_gen_code_common(s, gen_code_buf, -1);
c896fe29
FB
2643
2644 /* flush instruction cache */
1813e175 2645 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
2aeabc08 2646
1813e175 2647 return tcg_current_code_size(s);
c896fe29
FB
2648}
2649
2ba1eeb6 2650/* Return the index of the micro operation such as the pc after is <
623e265c
PB
2651 offset bytes from the start of the TB. The contents of gen_code_buf must
2652 not be changed, though writing the same values is ok.
2653 Return -1 if not found. */
1813e175
RH
2654int tcg_gen_code_search_pc(TCGContext *s, tcg_insn_unit *gen_code_buf,
2655 long offset)
c896fe29 2656{
623e265c 2657 return tcg_gen_code_common(s, gen_code_buf, offset);
c896fe29 2658}
a23a9ec6
FB
2659
2660#ifdef CONFIG_PROFILER
405cf9ff 2661void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6
FB
2662{
2663 TCGContext *s = &tcg_ctx;
2664 int64_t tot;
2665
2666 tot = s->interm_time + s->code_time;
2667 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2668 tot, tot / 2.4e9);
2669 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2670 s->tb_count,
2671 s->tb_count1 - s->tb_count,
2672 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2673 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2674 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
a23a9ec6
FB
2675 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2676 s->tb_count ?
2677 (double)s->del_op_count / s->tb_count : 0);
2678 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2679 s->tb_count ?
2680 (double)s->temp_count / s->tb_count : 0,
2681 s->temp_count_max);
2682
2683 cpu_fprintf(f, "cycles/op %0.1f\n",
2684 s->op_count ? (double)tot / s->op_count : 0);
2685 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2686 s->code_in_len ? (double)tot / s->code_in_len : 0);
2687 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2688 s->code_out_len ? (double)tot / s->code_out_len : 0);
2689 if (tot == 0)
2690 tot = 1;
2691 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2692 (double)s->interm_time / tot * 100.0);
2693 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2694 (double)s->code_time / tot * 100.0);
c5cc28ff
AJ
2695 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2696 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2697 * 100.0);
a23a9ec6
FB
2698 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2699 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2700 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2701 s->restore_count);
2702 cpu_fprintf(f, " avg cycles %0.1f\n",
2703 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
871e6c35
BS
2704
2705 dump_op_count();
a23a9ec6
FB
2706}
2707#else
405cf9ff 2708void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6 2709{
24bf7b3a 2710 cpu_fprintf(f, "[TCG profiler not compiled]\n");
a23a9ec6
FB
2711}
2712#endif
813da627
RH
2713
2714#ifdef ELF_HOST_MACHINE
5872bbf2
RH
2715/* In order to use this feature, the backend needs to do three things:
2716
2717 (1) Define ELF_HOST_MACHINE to indicate both what value to
2718 put into the ELF image and to indicate support for the feature.
2719
2720 (2) Define tcg_register_jit. This should create a buffer containing
2721 the contents of a .debug_frame section that describes the post-
2722 prologue unwind info for the tcg machine.
2723
2724 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2725*/
813da627
RH
2726
2727/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2728typedef enum {
2729 JIT_NOACTION = 0,
2730 JIT_REGISTER_FN,
2731 JIT_UNREGISTER_FN
2732} jit_actions_t;
2733
2734struct jit_code_entry {
2735 struct jit_code_entry *next_entry;
2736 struct jit_code_entry *prev_entry;
2737 const void *symfile_addr;
2738 uint64_t symfile_size;
2739};
2740
2741struct jit_descriptor {
2742 uint32_t version;
2743 uint32_t action_flag;
2744 struct jit_code_entry *relevant_entry;
2745 struct jit_code_entry *first_entry;
2746};
2747
2748void __jit_debug_register_code(void) __attribute__((noinline));
2749void __jit_debug_register_code(void)
2750{
2751 asm("");
2752}
2753
2754/* Must statically initialize the version, because GDB may check
2755 the version before we can set it. */
2756struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2757
2758/* End GDB interface. */
2759
2760static int find_string(const char *strtab, const char *str)
2761{
2762 const char *p = strtab + 1;
2763
2764 while (1) {
2765 if (strcmp(p, str) == 0) {
2766 return p - strtab;
2767 }
2768 p += strlen(p) + 1;
2769 }
2770}
2771
5872bbf2 2772static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
813da627
RH
2773 void *debug_frame, size_t debug_frame_size)
2774{
5872bbf2
RH
2775 struct __attribute__((packed)) DebugInfo {
2776 uint32_t len;
2777 uint16_t version;
2778 uint32_t abbrev;
2779 uint8_t ptr_size;
2780 uint8_t cu_die;
2781 uint16_t cu_lang;
2782 uintptr_t cu_low_pc;
2783 uintptr_t cu_high_pc;
2784 uint8_t fn_die;
2785 char fn_name[16];
2786 uintptr_t fn_low_pc;
2787 uintptr_t fn_high_pc;
2788 uint8_t cu_eoc;
2789 };
813da627
RH
2790
2791 struct ElfImage {
2792 ElfW(Ehdr) ehdr;
2793 ElfW(Phdr) phdr;
5872bbf2
RH
2794 ElfW(Shdr) shdr[7];
2795 ElfW(Sym) sym[2];
2796 struct DebugInfo di;
2797 uint8_t da[24];
2798 char str[80];
2799 };
2800
2801 struct ElfImage *img;
2802
2803 static const struct ElfImage img_template = {
2804 .ehdr = {
2805 .e_ident[EI_MAG0] = ELFMAG0,
2806 .e_ident[EI_MAG1] = ELFMAG1,
2807 .e_ident[EI_MAG2] = ELFMAG2,
2808 .e_ident[EI_MAG3] = ELFMAG3,
2809 .e_ident[EI_CLASS] = ELF_CLASS,
2810 .e_ident[EI_DATA] = ELF_DATA,
2811 .e_ident[EI_VERSION] = EV_CURRENT,
2812 .e_type = ET_EXEC,
2813 .e_machine = ELF_HOST_MACHINE,
2814 .e_version = EV_CURRENT,
2815 .e_phoff = offsetof(struct ElfImage, phdr),
2816 .e_shoff = offsetof(struct ElfImage, shdr),
2817 .e_ehsize = sizeof(ElfW(Shdr)),
2818 .e_phentsize = sizeof(ElfW(Phdr)),
2819 .e_phnum = 1,
2820 .e_shentsize = sizeof(ElfW(Shdr)),
2821 .e_shnum = ARRAY_SIZE(img->shdr),
2822 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
abbb3eae
RH
2823#ifdef ELF_HOST_FLAGS
2824 .e_flags = ELF_HOST_FLAGS,
2825#endif
2826#ifdef ELF_OSABI
2827 .e_ident[EI_OSABI] = ELF_OSABI,
2828#endif
5872bbf2
RH
2829 },
2830 .phdr = {
2831 .p_type = PT_LOAD,
2832 .p_flags = PF_X,
2833 },
2834 .shdr = {
2835 [0] = { .sh_type = SHT_NULL },
2836 /* Trick: The contents of code_gen_buffer are not present in
2837 this fake ELF file; that got allocated elsewhere. Therefore
2838 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2839 will not look for contents. We can record any address. */
2840 [1] = { /* .text */
2841 .sh_type = SHT_NOBITS,
2842 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2843 },
2844 [2] = { /* .debug_info */
2845 .sh_type = SHT_PROGBITS,
2846 .sh_offset = offsetof(struct ElfImage, di),
2847 .sh_size = sizeof(struct DebugInfo),
2848 },
2849 [3] = { /* .debug_abbrev */
2850 .sh_type = SHT_PROGBITS,
2851 .sh_offset = offsetof(struct ElfImage, da),
2852 .sh_size = sizeof(img->da),
2853 },
2854 [4] = { /* .debug_frame */
2855 .sh_type = SHT_PROGBITS,
2856 .sh_offset = sizeof(struct ElfImage),
2857 },
2858 [5] = { /* .symtab */
2859 .sh_type = SHT_SYMTAB,
2860 .sh_offset = offsetof(struct ElfImage, sym),
2861 .sh_size = sizeof(img->sym),
2862 .sh_info = 1,
2863 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2864 .sh_entsize = sizeof(ElfW(Sym)),
2865 },
2866 [6] = { /* .strtab */
2867 .sh_type = SHT_STRTAB,
2868 .sh_offset = offsetof(struct ElfImage, str),
2869 .sh_size = sizeof(img->str),
2870 }
2871 },
2872 .sym = {
2873 [1] = { /* code_gen_buffer */
2874 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2875 .st_shndx = 1,
2876 }
2877 },
2878 .di = {
2879 .len = sizeof(struct DebugInfo) - 4,
2880 .version = 2,
2881 .ptr_size = sizeof(void *),
2882 .cu_die = 1,
2883 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2884 .fn_die = 2,
2885 .fn_name = "code_gen_buffer"
2886 },
2887 .da = {
2888 1, /* abbrev number (the cu) */
2889 0x11, 1, /* DW_TAG_compile_unit, has children */
2890 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2891 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2892 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2893 0, 0, /* end of abbrev */
2894 2, /* abbrev number (the fn) */
2895 0x2e, 0, /* DW_TAG_subprogram, no children */
2896 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2897 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2898 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2899 0, 0, /* end of abbrev */
2900 0 /* no more abbrev */
2901 },
2902 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2903 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
813da627
RH
2904 };
2905
2906 /* We only need a single jit entry; statically allocate it. */
2907 static struct jit_code_entry one_entry;
2908
5872bbf2 2909 uintptr_t buf = (uintptr_t)buf_ptr;
813da627 2910 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
813da627 2911
5872bbf2
RH
2912 img = g_malloc(img_size);
2913 *img = img_template;
2914 memcpy(img + 1, debug_frame, debug_frame_size);
813da627 2915
5872bbf2
RH
2916 img->phdr.p_vaddr = buf;
2917 img->phdr.p_paddr = buf;
2918 img->phdr.p_memsz = buf_size;
813da627 2919
813da627 2920 img->shdr[1].sh_name = find_string(img->str, ".text");
5872bbf2 2921 img->shdr[1].sh_addr = buf;
813da627
RH
2922 img->shdr[1].sh_size = buf_size;
2923
5872bbf2
RH
2924 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2925 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2926
2927 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2928 img->shdr[4].sh_size = debug_frame_size;
2929
2930 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2931 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2932
2933 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2934 img->sym[1].st_value = buf;
2935 img->sym[1].st_size = buf_size;
813da627 2936
5872bbf2 2937 img->di.cu_low_pc = buf;
45aba097 2938 img->di.cu_high_pc = buf + buf_size;
5872bbf2 2939 img->di.fn_low_pc = buf;
45aba097 2940 img->di.fn_high_pc = buf + buf_size;
813da627
RH
2941
2942#ifdef DEBUG_JIT
2943 /* Enable this block to be able to debug the ELF image file creation.
2944 One can use readelf, objdump, or other inspection utilities. */
2945 {
2946 FILE *f = fopen("/tmp/qemu.jit", "w+b");
2947 if (f) {
5872bbf2 2948 if (fwrite(img, img_size, 1, f) != img_size) {
813da627
RH
2949 /* Avoid stupid unused return value warning for fwrite. */
2950 }
2951 fclose(f);
2952 }
2953 }
2954#endif
2955
2956 one_entry.symfile_addr = img;
2957 one_entry.symfile_size = img_size;
2958
2959 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2960 __jit_debug_descriptor.relevant_entry = &one_entry;
2961 __jit_debug_descriptor.first_entry = &one_entry;
2962 __jit_debug_register_code();
2963}
2964#else
5872bbf2
RH
2965/* No support for the feature. Provide the entry point expected by exec.c,
2966 and implement the internal function we declared earlier. */
813da627
RH
2967
2968static void tcg_register_jit_int(void *buf, size_t size,
2969 void *debug_frame, size_t debug_frame_size)
2970{
2971}
2972
2973void tcg_register_jit(void *buf, size_t buf_size)
2974{
2975}
2976#endif /* ELF_HOST_MACHINE */
This page took 1.152183 seconds and 4 git commands to generate.