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