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