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