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