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