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