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