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