xref: /openbmc/qemu/tcg/tcg.c (revision 41bd3603)
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 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
32 /* define it to suppress various consistency checks (faster) */
33 #define NDEBUG
34 #endif
35 
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <inttypes.h>
41 #ifdef _WIN32
42 #include <malloc.h>
43 #endif
44 #ifdef _AIX
45 #include <alloca.h>
46 #endif
47 
48 #include "qemu-common.h"
49 #include "cache-utils.h"
50 #include "host-utils.h"
51 #include "qemu-timer.h"
52 
53 /* Note: the long term plan is to reduce the dependancies on the QEMU
54    CPU definitions. Currently they are used for qemu_ld/st
55    instructions */
56 #define NO_CPU_IO_DEFS
57 #include "cpu.h"
58 
59 #include "tcg-op.h"
60 #include "elf.h"
61 
62 #if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
63 #error GUEST_BASE not supported on this host.
64 #endif
65 
66 /* Forward declarations for functions declared in tcg-target.c and used here. */
67 static void tcg_target_init(TCGContext *s);
68 static void tcg_target_qemu_prologue(TCGContext *s);
69 static void patch_reloc(uint8_t *code_ptr, int type,
70                         tcg_target_long value, tcg_target_long addend);
71 
72 /* Forward declarations for functions declared and used in tcg-target.c. */
73 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
74 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
75                        tcg_target_long arg2);
76 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
77 static void tcg_out_movi(TCGContext *s, TCGType type,
78                          TCGReg ret, tcg_target_long arg);
79 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
80                        const int *const_args);
81 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
82                        tcg_target_long arg2);
83 static int tcg_target_const_match(tcg_target_long val,
84                                   const TCGArgConstraint *arg_ct);
85 static int tcg_target_get_call_iarg_regs_count(int flags);
86 
87 TCGOpDef tcg_op_defs[] = {
88 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
89 #include "tcg-opc.h"
90 #undef DEF
91 };
92 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
93 
94 static TCGRegSet tcg_target_available_regs[2];
95 static TCGRegSet tcg_target_call_clobber_regs;
96 
97 /* XXX: move that inside the context */
98 uint16_t *gen_opc_ptr;
99 TCGArg *gen_opparam_ptr;
100 
101 static inline void tcg_out8(TCGContext *s, uint8_t v)
102 {
103     *s->code_ptr++ = v;
104 }
105 
106 static inline void tcg_out16(TCGContext *s, uint16_t v)
107 {
108     *(uint16_t *)s->code_ptr = v;
109     s->code_ptr += 2;
110 }
111 
112 static inline void tcg_out32(TCGContext *s, uint32_t v)
113 {
114     *(uint32_t *)s->code_ptr = v;
115     s->code_ptr += 4;
116 }
117 
118 /* label relocation processing */
119 
120 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
121                           int label_index, long addend)
122 {
123     TCGLabel *l;
124     TCGRelocation *r;
125 
126     l = &s->labels[label_index];
127     if (l->has_value) {
128         /* FIXME: This may break relocations on RISC targets that
129            modify instruction fields in place.  The caller may not have
130            written the initial value.  */
131         patch_reloc(code_ptr, type, l->u.value, addend);
132     } else {
133         /* add a new relocation entry */
134         r = tcg_malloc(sizeof(TCGRelocation));
135         r->type = type;
136         r->ptr = code_ptr;
137         r->addend = addend;
138         r->next = l->u.first_reloc;
139         l->u.first_reloc = r;
140     }
141 }
142 
143 static void tcg_out_label(TCGContext *s, int label_index,
144                           tcg_target_long value)
145 {
146     TCGLabel *l;
147     TCGRelocation *r;
148 
149     l = &s->labels[label_index];
150     if (l->has_value)
151         tcg_abort();
152     r = l->u.first_reloc;
153     while (r != NULL) {
154         patch_reloc(r->ptr, r->type, value, r->addend);
155         r = r->next;
156     }
157     l->has_value = 1;
158     l->u.value = value;
159 }
160 
161 int gen_new_label(void)
162 {
163     TCGContext *s = &tcg_ctx;
164     int idx;
165     TCGLabel *l;
166 
167     if (s->nb_labels >= TCG_MAX_LABELS)
168         tcg_abort();
169     idx = s->nb_labels++;
170     l = &s->labels[idx];
171     l->has_value = 0;
172     l->u.first_reloc = NULL;
173     return idx;
174 }
175 
176 #include "tcg-target.c"
177 
178 /* pool based memory allocation */
179 void *tcg_malloc_internal(TCGContext *s, int size)
180 {
181     TCGPool *p;
182     int pool_size;
183 
184     if (size > TCG_POOL_CHUNK_SIZE) {
185         /* big malloc: insert a new pool (XXX: could optimize) */
186         p = g_malloc(sizeof(TCGPool) + size);
187         p->size = size;
188         if (s->pool_current)
189             s->pool_current->next = p;
190         else
191             s->pool_first = p;
192         p->next = s->pool_current;
193     } else {
194         p = s->pool_current;
195         if (!p) {
196             p = s->pool_first;
197             if (!p)
198                 goto new_pool;
199         } else {
200             if (!p->next) {
201             new_pool:
202                 pool_size = TCG_POOL_CHUNK_SIZE;
203                 p = g_malloc(sizeof(TCGPool) + pool_size);
204                 p->size = pool_size;
205                 p->next = NULL;
206                 if (s->pool_current)
207                     s->pool_current->next = p;
208                 else
209                     s->pool_first = p;
210             } else {
211                 p = p->next;
212             }
213         }
214     }
215     s->pool_current = p;
216     s->pool_cur = p->data + size;
217     s->pool_end = p->data + p->size;
218     return p->data;
219 }
220 
221 void tcg_pool_reset(TCGContext *s)
222 {
223     s->pool_cur = s->pool_end = NULL;
224     s->pool_current = NULL;
225 }
226 
227 void tcg_context_init(TCGContext *s)
228 {
229     int op, total_args, n;
230     TCGOpDef *def;
231     TCGArgConstraint *args_ct;
232     int *sorted_args;
233 
234     memset(s, 0, sizeof(*s));
235     s->temps = s->static_temps;
236     s->nb_globals = 0;
237 
238     /* Count total number of arguments and allocate the corresponding
239        space */
240     total_args = 0;
241     for(op = 0; op < NB_OPS; op++) {
242         def = &tcg_op_defs[op];
243         n = def->nb_iargs + def->nb_oargs;
244         total_args += n;
245     }
246 
247     args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
248     sorted_args = g_malloc(sizeof(int) * total_args);
249 
250     for(op = 0; op < NB_OPS; op++) {
251         def = &tcg_op_defs[op];
252         def->args_ct = args_ct;
253         def->sorted_args = sorted_args;
254         n = def->nb_iargs + def->nb_oargs;
255         sorted_args += n;
256         args_ct += n;
257     }
258 
259     tcg_target_init(s);
260 }
261 
262 void tcg_prologue_init(TCGContext *s)
263 {
264     /* init global prologue and epilogue */
265     s->code_buf = code_gen_prologue;
266     s->code_ptr = s->code_buf;
267     tcg_target_qemu_prologue(s);
268     flush_icache_range((unsigned long)s->code_buf,
269                        (unsigned long)s->code_ptr);
270 }
271 
272 void tcg_set_frame(TCGContext *s, int reg,
273                    tcg_target_long start, tcg_target_long size)
274 {
275     s->frame_start = start;
276     s->frame_end = start + size;
277     s->frame_reg = reg;
278 }
279 
280 void tcg_func_start(TCGContext *s)
281 {
282     int i;
283     tcg_pool_reset(s);
284     s->nb_temps = s->nb_globals;
285     for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
286         s->first_free_temp[i] = -1;
287     s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
288     s->nb_labels = 0;
289     s->current_frame_offset = s->frame_start;
290 
291     gen_opc_ptr = gen_opc_buf;
292     gen_opparam_ptr = gen_opparam_buf;
293 }
294 
295 static inline void tcg_temp_alloc(TCGContext *s, int n)
296 {
297     if (n > TCG_MAX_TEMPS)
298         tcg_abort();
299 }
300 
301 static inline int tcg_global_reg_new_internal(TCGType type, int reg,
302                                               const char *name)
303 {
304     TCGContext *s = &tcg_ctx;
305     TCGTemp *ts;
306     int idx;
307 
308 #if TCG_TARGET_REG_BITS == 32
309     if (type != TCG_TYPE_I32)
310         tcg_abort();
311 #endif
312     if (tcg_regset_test_reg(s->reserved_regs, reg))
313         tcg_abort();
314     idx = s->nb_globals;
315     tcg_temp_alloc(s, s->nb_globals + 1);
316     ts = &s->temps[s->nb_globals];
317     ts->base_type = type;
318     ts->type = type;
319     ts->fixed_reg = 1;
320     ts->reg = reg;
321     ts->name = name;
322     s->nb_globals++;
323     tcg_regset_set_reg(s->reserved_regs, reg);
324     return idx;
325 }
326 
327 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
328 {
329     int idx;
330 
331     idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
332     return MAKE_TCGV_I32(idx);
333 }
334 
335 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
336 {
337     int idx;
338 
339     idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
340     return MAKE_TCGV_I64(idx);
341 }
342 
343 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
344                                               tcg_target_long offset,
345                                               const char *name)
346 {
347     TCGContext *s = &tcg_ctx;
348     TCGTemp *ts;
349     int idx;
350 
351     idx = s->nb_globals;
352 #if TCG_TARGET_REG_BITS == 32
353     if (type == TCG_TYPE_I64) {
354         char buf[64];
355         tcg_temp_alloc(s, s->nb_globals + 2);
356         ts = &s->temps[s->nb_globals];
357         ts->base_type = type;
358         ts->type = TCG_TYPE_I32;
359         ts->fixed_reg = 0;
360         ts->mem_allocated = 1;
361         ts->mem_reg = reg;
362 #ifdef TCG_TARGET_WORDS_BIGENDIAN
363         ts->mem_offset = offset + 4;
364 #else
365         ts->mem_offset = offset;
366 #endif
367         pstrcpy(buf, sizeof(buf), name);
368         pstrcat(buf, sizeof(buf), "_0");
369         ts->name = strdup(buf);
370         ts++;
371 
372         ts->base_type = type;
373         ts->type = TCG_TYPE_I32;
374         ts->fixed_reg = 0;
375         ts->mem_allocated = 1;
376         ts->mem_reg = reg;
377 #ifdef TCG_TARGET_WORDS_BIGENDIAN
378         ts->mem_offset = offset;
379 #else
380         ts->mem_offset = offset + 4;
381 #endif
382         pstrcpy(buf, sizeof(buf), name);
383         pstrcat(buf, sizeof(buf), "_1");
384         ts->name = strdup(buf);
385 
386         s->nb_globals += 2;
387     } else
388 #endif
389     {
390         tcg_temp_alloc(s, s->nb_globals + 1);
391         ts = &s->temps[s->nb_globals];
392         ts->base_type = type;
393         ts->type = type;
394         ts->fixed_reg = 0;
395         ts->mem_allocated = 1;
396         ts->mem_reg = reg;
397         ts->mem_offset = offset;
398         ts->name = name;
399         s->nb_globals++;
400     }
401     return idx;
402 }
403 
404 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
405                                 const char *name)
406 {
407     int idx;
408 
409     idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
410     return MAKE_TCGV_I32(idx);
411 }
412 
413 TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
414                                 const char *name)
415 {
416     int idx;
417 
418     idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
419     return MAKE_TCGV_I64(idx);
420 }
421 
422 static inline int tcg_temp_new_internal(TCGType type, int temp_local)
423 {
424     TCGContext *s = &tcg_ctx;
425     TCGTemp *ts;
426     int idx, k;
427 
428     k = type;
429     if (temp_local)
430         k += TCG_TYPE_COUNT;
431     idx = s->first_free_temp[k];
432     if (idx != -1) {
433         /* There is already an available temp with the
434            right type */
435         ts = &s->temps[idx];
436         s->first_free_temp[k] = ts->next_free_temp;
437         ts->temp_allocated = 1;
438         assert(ts->temp_local == temp_local);
439     } else {
440         idx = s->nb_temps;
441 #if TCG_TARGET_REG_BITS == 32
442         if (type == TCG_TYPE_I64) {
443             tcg_temp_alloc(s, s->nb_temps + 2);
444             ts = &s->temps[s->nb_temps];
445             ts->base_type = type;
446             ts->type = TCG_TYPE_I32;
447             ts->temp_allocated = 1;
448             ts->temp_local = temp_local;
449             ts->name = NULL;
450             ts++;
451             ts->base_type = TCG_TYPE_I32;
452             ts->type = TCG_TYPE_I32;
453             ts->temp_allocated = 1;
454             ts->temp_local = temp_local;
455             ts->name = NULL;
456             s->nb_temps += 2;
457         } else
458 #endif
459         {
460             tcg_temp_alloc(s, s->nb_temps + 1);
461             ts = &s->temps[s->nb_temps];
462             ts->base_type = type;
463             ts->type = type;
464             ts->temp_allocated = 1;
465             ts->temp_local = temp_local;
466             ts->name = NULL;
467             s->nb_temps++;
468         }
469     }
470 
471 #if defined(CONFIG_DEBUG_TCG)
472     s->temps_in_use++;
473 #endif
474     return idx;
475 }
476 
477 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
478 {
479     int idx;
480 
481     idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
482     return MAKE_TCGV_I32(idx);
483 }
484 
485 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
486 {
487     int idx;
488 
489     idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
490     return MAKE_TCGV_I64(idx);
491 }
492 
493 static inline void tcg_temp_free_internal(int idx)
494 {
495     TCGContext *s = &tcg_ctx;
496     TCGTemp *ts;
497     int k;
498 
499 #if defined(CONFIG_DEBUG_TCG)
500     s->temps_in_use--;
501     if (s->temps_in_use < 0) {
502         fprintf(stderr, "More temporaries freed than allocated!\n");
503     }
504 #endif
505 
506     assert(idx >= s->nb_globals && idx < s->nb_temps);
507     ts = &s->temps[idx];
508     assert(ts->temp_allocated != 0);
509     ts->temp_allocated = 0;
510     k = ts->base_type;
511     if (ts->temp_local)
512         k += TCG_TYPE_COUNT;
513     ts->next_free_temp = s->first_free_temp[k];
514     s->first_free_temp[k] = idx;
515 }
516 
517 void tcg_temp_free_i32(TCGv_i32 arg)
518 {
519     tcg_temp_free_internal(GET_TCGV_I32(arg));
520 }
521 
522 void tcg_temp_free_i64(TCGv_i64 arg)
523 {
524     tcg_temp_free_internal(GET_TCGV_I64(arg));
525 }
526 
527 TCGv_i32 tcg_const_i32(int32_t val)
528 {
529     TCGv_i32 t0;
530     t0 = tcg_temp_new_i32();
531     tcg_gen_movi_i32(t0, val);
532     return t0;
533 }
534 
535 TCGv_i64 tcg_const_i64(int64_t val)
536 {
537     TCGv_i64 t0;
538     t0 = tcg_temp_new_i64();
539     tcg_gen_movi_i64(t0, val);
540     return t0;
541 }
542 
543 TCGv_i32 tcg_const_local_i32(int32_t val)
544 {
545     TCGv_i32 t0;
546     t0 = tcg_temp_local_new_i32();
547     tcg_gen_movi_i32(t0, val);
548     return t0;
549 }
550 
551 TCGv_i64 tcg_const_local_i64(int64_t val)
552 {
553     TCGv_i64 t0;
554     t0 = tcg_temp_local_new_i64();
555     tcg_gen_movi_i64(t0, val);
556     return t0;
557 }
558 
559 #if defined(CONFIG_DEBUG_TCG)
560 void tcg_clear_temp_count(void)
561 {
562     TCGContext *s = &tcg_ctx;
563     s->temps_in_use = 0;
564 }
565 
566 int tcg_check_temp_count(void)
567 {
568     TCGContext *s = &tcg_ctx;
569     if (s->temps_in_use) {
570         /* Clear the count so that we don't give another
571          * warning immediately next time around.
572          */
573         s->temps_in_use = 0;
574         return 1;
575     }
576     return 0;
577 }
578 #endif
579 
580 void tcg_register_helper(void *func, const char *name)
581 {
582     TCGContext *s = &tcg_ctx;
583     int n;
584     if ((s->nb_helpers + 1) > s->allocated_helpers) {
585         n = s->allocated_helpers;
586         if (n == 0) {
587             n = 4;
588         } else {
589             n *= 2;
590         }
591         s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
592         s->allocated_helpers = n;
593     }
594     s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
595     s->helpers[s->nb_helpers].name = name;
596     s->nb_helpers++;
597 }
598 
599 /* Note: we convert the 64 bit args to 32 bit and do some alignment
600    and endian swap. Maybe it would be better to do the alignment
601    and endian swap in tcg_reg_alloc_call(). */
602 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
603                    int sizemask, TCGArg ret, int nargs, TCGArg *args)
604 {
605 #if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
606     int call_type;
607 #endif
608     int i;
609     int real_args;
610     int nb_rets;
611     TCGArg *nparam;
612 
613 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
614     for (i = 0; i < nargs; ++i) {
615         int is_64bit = sizemask & (1 << (i+1)*2);
616         int is_signed = sizemask & (2 << (i+1)*2);
617         if (!is_64bit) {
618             TCGv_i64 temp = tcg_temp_new_i64();
619             TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
620             if (is_signed) {
621                 tcg_gen_ext32s_i64(temp, orig);
622             } else {
623                 tcg_gen_ext32u_i64(temp, orig);
624             }
625             args[i] = GET_TCGV_I64(temp);
626         }
627     }
628 #endif /* TCG_TARGET_EXTEND_ARGS */
629 
630     *gen_opc_ptr++ = INDEX_op_call;
631     nparam = gen_opparam_ptr++;
632 #if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
633     call_type = (flags & TCG_CALL_TYPE_MASK);
634 #endif
635     if (ret != TCG_CALL_DUMMY_ARG) {
636 #if TCG_TARGET_REG_BITS < 64
637         if (sizemask & 1) {
638 #ifdef TCG_TARGET_WORDS_BIGENDIAN
639             *gen_opparam_ptr++ = ret + 1;
640             *gen_opparam_ptr++ = ret;
641 #else
642             *gen_opparam_ptr++ = ret;
643             *gen_opparam_ptr++ = ret + 1;
644 #endif
645             nb_rets = 2;
646         } else
647 #endif
648         {
649             *gen_opparam_ptr++ = ret;
650             nb_rets = 1;
651         }
652     } else {
653         nb_rets = 0;
654     }
655     real_args = 0;
656     for (i = 0; i < nargs; i++) {
657 #if TCG_TARGET_REG_BITS < 64
658         int is_64bit = sizemask & (1 << (i+1)*2);
659         if (is_64bit) {
660 #ifdef TCG_TARGET_I386
661             /* REGPARM case: if the third parameter is 64 bit, it is
662                allocated on the stack */
663             if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
664                 call_type = TCG_CALL_TYPE_REGPARM_2;
665                 flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
666             }
667 #endif
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_EQ] = "eq",
868     [TCG_COND_NE] = "ne",
869     [TCG_COND_LT] = "lt",
870     [TCG_COND_GE] = "ge",
871     [TCG_COND_LE] = "le",
872     [TCG_COND_GT] = "gt",
873     [TCG_COND_LTU] = "ltu",
874     [TCG_COND_GEU] = "geu",
875     [TCG_COND_LEU] = "leu",
876     [TCG_COND_GTU] = "gtu"
877 };
878 
879 void tcg_dump_ops(TCGContext *s, FILE *outfile)
880 {
881     const uint16_t *opc_ptr;
882     const TCGArg *args;
883     TCGArg arg;
884     TCGOpcode c;
885     int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
886     const TCGOpDef *def;
887     char buf[128];
888 
889     first_insn = 1;
890     opc_ptr = gen_opc_buf;
891     args = gen_opparam_buf;
892     while (opc_ptr < gen_opc_ptr) {
893         c = *opc_ptr++;
894         def = &tcg_op_defs[c];
895         if (c == INDEX_op_debug_insn_start) {
896             uint64_t pc;
897 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
898             pc = ((uint64_t)args[1] << 32) | args[0];
899 #else
900             pc = args[0];
901 #endif
902             if (!first_insn)
903                 fprintf(outfile, "\n");
904             fprintf(outfile, " ---- 0x%" PRIx64, pc);
905             first_insn = 0;
906             nb_oargs = def->nb_oargs;
907             nb_iargs = def->nb_iargs;
908             nb_cargs = def->nb_cargs;
909         } else if (c == INDEX_op_call) {
910             TCGArg arg;
911 
912             /* variable number of arguments */
913             arg = *args++;
914             nb_oargs = arg >> 16;
915             nb_iargs = arg & 0xffff;
916             nb_cargs = def->nb_cargs;
917 
918             fprintf(outfile, " %s ", def->name);
919 
920             /* function name */
921             fprintf(outfile, "%s",
922                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
923             /* flags */
924             fprintf(outfile, ",$0x%" TCG_PRIlx,
925                     args[nb_oargs + nb_iargs]);
926             /* nb out args */
927             fprintf(outfile, ",$%d", nb_oargs);
928             for(i = 0; i < nb_oargs; i++) {
929                 fprintf(outfile, ",");
930                 fprintf(outfile, "%s",
931                         tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
932             }
933             for(i = 0; i < (nb_iargs - 1); i++) {
934                 fprintf(outfile, ",");
935                 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
936                     fprintf(outfile, "<dummy>");
937                 } else {
938                     fprintf(outfile, "%s",
939                             tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
940                 }
941             }
942         } else if (c == INDEX_op_movi_i32
943 #if TCG_TARGET_REG_BITS == 64
944                    || c == INDEX_op_movi_i64
945 #endif
946                    ) {
947             tcg_target_ulong val;
948             TCGHelperInfo *th;
949 
950             nb_oargs = def->nb_oargs;
951             nb_iargs = def->nb_iargs;
952             nb_cargs = def->nb_cargs;
953             fprintf(outfile, " %s %s,$", def->name,
954                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
955             val = args[1];
956             th = tcg_find_helper(s, val);
957             if (th) {
958                 fprintf(outfile, "%s", th->name);
959             } else {
960                 if (c == INDEX_op_movi_i32)
961                     fprintf(outfile, "0x%x", (uint32_t)val);
962                 else
963                     fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
964             }
965         } else {
966             fprintf(outfile, " %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                     fprintf(outfile, ",");
982                 fprintf(outfile, "%s",
983                         tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
984             }
985             for(i = 0; i < nb_iargs; i++) {
986                 if (k != 0)
987                     fprintf(outfile, ",");
988                 fprintf(outfile, "%s",
989                         tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
990             }
991             switch (c) {
992             case INDEX_op_brcond_i32:
993 #if TCG_TARGET_REG_BITS == 32
994             case INDEX_op_brcond2_i32:
995 #elif TCG_TARGET_REG_BITS == 64
996             case INDEX_op_brcond_i64:
997 #endif
998             case INDEX_op_setcond_i32:
999 #if TCG_TARGET_REG_BITS == 32
1000             case INDEX_op_setcond2_i32:
1001 #elif TCG_TARGET_REG_BITS == 64
1002             case INDEX_op_setcond_i64:
1003 #endif
1004                 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
1005                     fprintf(outfile, ",%s", cond_name[args[k++]]);
1006                 else
1007                     fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
1008                 i = 1;
1009                 break;
1010             default:
1011                 i = 0;
1012                 break;
1013             }
1014             for(; i < nb_cargs; i++) {
1015                 if (k != 0)
1016                     fprintf(outfile, ",");
1017                 arg = args[k++];
1018                 fprintf(outfile, "$0x%" TCG_PRIlx, arg);
1019             }
1020         }
1021         fprintf(outfile, "\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_set_label:
1298             args--;
1299             /* mark end of basic block */
1300             tcg_la_bb_end(s, dead_temps);
1301             break;
1302         case INDEX_op_debug_insn_start:
1303             args -= def->nb_args;
1304             break;
1305         case INDEX_op_nopn:
1306             nb_args = args[-1];
1307             args -= nb_args;
1308             break;
1309         case INDEX_op_discard:
1310             args--;
1311             /* mark the temporary as dead */
1312             dead_temps[args[0]] = 1;
1313             break;
1314         case INDEX_op_end:
1315             break;
1316             /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1317         default:
1318             args -= def->nb_args;
1319             nb_iargs = def->nb_iargs;
1320             nb_oargs = def->nb_oargs;
1321 
1322             /* Test if the operation can be removed because all
1323                its outputs are dead. We assume that nb_oargs == 0
1324                implies side effects */
1325             if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1326                 for(i = 0; i < nb_oargs; i++) {
1327                     arg = args[i];
1328                     if (!dead_temps[arg])
1329                         goto do_not_remove;
1330                 }
1331                 tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1332 #ifdef CONFIG_PROFILER
1333                 s->del_op_count++;
1334 #endif
1335             } else {
1336             do_not_remove:
1337 
1338                 /* output args are dead */
1339                 dead_args = 0;
1340                 for(i = 0; i < nb_oargs; i++) {
1341                     arg = args[i];
1342                     if (dead_temps[arg]) {
1343                         dead_args |= (1 << i);
1344                     }
1345                     dead_temps[arg] = 1;
1346                 }
1347 
1348                 /* if end of basic block, update */
1349                 if (def->flags & TCG_OPF_BB_END) {
1350                     tcg_la_bb_end(s, dead_temps);
1351                 } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1352                     /* globals are live */
1353                     memset(dead_temps, 0, s->nb_globals);
1354                 }
1355 
1356                 /* input args are live */
1357                 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1358                     arg = args[i];
1359                     if (dead_temps[arg]) {
1360                         dead_args |= (1 << i);
1361                     }
1362                     dead_temps[arg] = 0;
1363                 }
1364                 s->op_dead_args[op_index] = dead_args;
1365             }
1366             break;
1367         }
1368         op_index--;
1369     }
1370 
1371     if (args != gen_opparam_buf)
1372         tcg_abort();
1373 }
1374 #else
1375 /* dummy liveness analysis */
1376 static void tcg_liveness_analysis(TCGContext *s)
1377 {
1378     int nb_ops;
1379     nb_ops = gen_opc_ptr - gen_opc_buf;
1380 
1381     s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1382     memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1383 }
1384 #endif
1385 
1386 #ifndef NDEBUG
1387 static void dump_regs(TCGContext *s)
1388 {
1389     TCGTemp *ts;
1390     int i;
1391     char buf[64];
1392 
1393     for(i = 0; i < s->nb_temps; i++) {
1394         ts = &s->temps[i];
1395         printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1396         switch(ts->val_type) {
1397         case TEMP_VAL_REG:
1398             printf("%s", tcg_target_reg_names[ts->reg]);
1399             break;
1400         case TEMP_VAL_MEM:
1401             printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1402             break;
1403         case TEMP_VAL_CONST:
1404             printf("$0x%" TCG_PRIlx, ts->val);
1405             break;
1406         case TEMP_VAL_DEAD:
1407             printf("D");
1408             break;
1409         default:
1410             printf("???");
1411             break;
1412         }
1413         printf("\n");
1414     }
1415 
1416     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1417         if (s->reg_to_temp[i] >= 0) {
1418             printf("%s: %s\n",
1419                    tcg_target_reg_names[i],
1420                    tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1421         }
1422     }
1423 }
1424 
1425 static void check_regs(TCGContext *s)
1426 {
1427     int reg, k;
1428     TCGTemp *ts;
1429     char buf[64];
1430 
1431     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1432         k = s->reg_to_temp[reg];
1433         if (k >= 0) {
1434             ts = &s->temps[k];
1435             if (ts->val_type != TEMP_VAL_REG ||
1436                 ts->reg != reg) {
1437                 printf("Inconsistency for register %s:\n",
1438                        tcg_target_reg_names[reg]);
1439                 goto fail;
1440             }
1441         }
1442     }
1443     for(k = 0; k < s->nb_temps; k++) {
1444         ts = &s->temps[k];
1445         if (ts->val_type == TEMP_VAL_REG &&
1446             !ts->fixed_reg &&
1447             s->reg_to_temp[ts->reg] != k) {
1448                 printf("Inconsistency for temp %s:\n",
1449                        tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1450         fail:
1451                 printf("reg state:\n");
1452                 dump_regs(s);
1453                 tcg_abort();
1454         }
1455     }
1456 }
1457 #endif
1458 
1459 static void temp_allocate_frame(TCGContext *s, int temp)
1460 {
1461     TCGTemp *ts;
1462     ts = &s->temps[temp];
1463 #ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
1464     s->current_frame_offset = (s->current_frame_offset +
1465                                (tcg_target_long)sizeof(tcg_target_long) - 1) &
1466         ~(sizeof(tcg_target_long) - 1);
1467 #endif
1468     if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1469         s->frame_end) {
1470         tcg_abort();
1471     }
1472     ts->mem_offset = s->current_frame_offset;
1473     ts->mem_reg = s->frame_reg;
1474     ts->mem_allocated = 1;
1475     s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1476 }
1477 
1478 /* free register 'reg' by spilling the corresponding temporary if necessary */
1479 static void tcg_reg_free(TCGContext *s, int reg)
1480 {
1481     TCGTemp *ts;
1482     int temp;
1483 
1484     temp = s->reg_to_temp[reg];
1485     if (temp != -1) {
1486         ts = &s->temps[temp];
1487         assert(ts->val_type == TEMP_VAL_REG);
1488         if (!ts->mem_coherent) {
1489             if (!ts->mem_allocated)
1490                 temp_allocate_frame(s, temp);
1491             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1492         }
1493         ts->val_type = TEMP_VAL_MEM;
1494         s->reg_to_temp[reg] = -1;
1495     }
1496 }
1497 
1498 /* Allocate a register belonging to reg1 & ~reg2 */
1499 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1500 {
1501     int i, reg;
1502     TCGRegSet reg_ct;
1503 
1504     tcg_regset_andnot(reg_ct, reg1, reg2);
1505 
1506     /* first try free registers */
1507     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1508         reg = tcg_target_reg_alloc_order[i];
1509         if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1510             return reg;
1511     }
1512 
1513     /* XXX: do better spill choice */
1514     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1515         reg = tcg_target_reg_alloc_order[i];
1516         if (tcg_regset_test_reg(reg_ct, reg)) {
1517             tcg_reg_free(s, reg);
1518             return reg;
1519         }
1520     }
1521 
1522     tcg_abort();
1523 }
1524 
1525 /* save a temporary to memory. 'allocated_regs' is used in case a
1526    temporary registers needs to be allocated to store a constant. */
1527 static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1528 {
1529     TCGTemp *ts;
1530     int reg;
1531 
1532     ts = &s->temps[temp];
1533     if (!ts->fixed_reg) {
1534         switch(ts->val_type) {
1535         case TEMP_VAL_REG:
1536             tcg_reg_free(s, ts->reg);
1537             break;
1538         case TEMP_VAL_DEAD:
1539             ts->val_type = TEMP_VAL_MEM;
1540             break;
1541         case TEMP_VAL_CONST:
1542             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1543                                 allocated_regs);
1544             if (!ts->mem_allocated)
1545                 temp_allocate_frame(s, temp);
1546             tcg_out_movi(s, ts->type, reg, ts->val);
1547             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1548             ts->val_type = TEMP_VAL_MEM;
1549             break;
1550         case TEMP_VAL_MEM:
1551             break;
1552         default:
1553             tcg_abort();
1554         }
1555     }
1556 }
1557 
1558 /* save globals to their canonical location and assume they can be
1559    modified be the following code. 'allocated_regs' is used in case a
1560    temporary registers needs to be allocated to store a constant. */
1561 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1562 {
1563     int i;
1564 
1565     for(i = 0; i < s->nb_globals; i++) {
1566         temp_save(s, i, allocated_regs);
1567     }
1568 }
1569 
1570 /* at the end of a basic block, we assume all temporaries are dead and
1571    all globals are stored at their canonical location. */
1572 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1573 {
1574     TCGTemp *ts;
1575     int i;
1576 
1577     for(i = s->nb_globals; i < s->nb_temps; i++) {
1578         ts = &s->temps[i];
1579         if (ts->temp_local) {
1580             temp_save(s, i, allocated_regs);
1581         } else {
1582             if (ts->val_type == TEMP_VAL_REG) {
1583                 s->reg_to_temp[ts->reg] = -1;
1584             }
1585             ts->val_type = TEMP_VAL_DEAD;
1586         }
1587     }
1588 
1589     save_globals(s, allocated_regs);
1590 }
1591 
1592 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1593 
1594 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1595 {
1596     TCGTemp *ots;
1597     tcg_target_ulong val;
1598 
1599     ots = &s->temps[args[0]];
1600     val = args[1];
1601 
1602     if (ots->fixed_reg) {
1603         /* for fixed registers, we do not do any constant
1604            propagation */
1605         tcg_out_movi(s, ots->type, ots->reg, val);
1606     } else {
1607         /* The movi is not explicitly generated here */
1608         if (ots->val_type == TEMP_VAL_REG)
1609             s->reg_to_temp[ots->reg] = -1;
1610         ots->val_type = TEMP_VAL_CONST;
1611         ots->val = val;
1612     }
1613 }
1614 
1615 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1616                               const TCGArg *args,
1617                               unsigned int dead_args)
1618 {
1619     TCGTemp *ts, *ots;
1620     int reg;
1621     const TCGArgConstraint *arg_ct;
1622 
1623     ots = &s->temps[args[0]];
1624     ts = &s->temps[args[1]];
1625     arg_ct = &def->args_ct[0];
1626 
1627     /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1628     if (ts->val_type == TEMP_VAL_REG) {
1629         if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1630             /* the mov can be suppressed */
1631             if (ots->val_type == TEMP_VAL_REG)
1632                 s->reg_to_temp[ots->reg] = -1;
1633             reg = ts->reg;
1634             s->reg_to_temp[reg] = -1;
1635             ts->val_type = TEMP_VAL_DEAD;
1636         } else {
1637             if (ots->val_type == TEMP_VAL_REG) {
1638                 reg = ots->reg;
1639             } else {
1640                 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1641             }
1642             if (ts->reg != reg) {
1643                 tcg_out_mov(s, ots->type, reg, ts->reg);
1644             }
1645         }
1646     } else if (ts->val_type == TEMP_VAL_MEM) {
1647         if (ots->val_type == TEMP_VAL_REG) {
1648             reg = ots->reg;
1649         } else {
1650             reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1651         }
1652         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1653     } else if (ts->val_type == TEMP_VAL_CONST) {
1654         if (ots->fixed_reg) {
1655             reg = ots->reg;
1656             tcg_out_movi(s, ots->type, reg, ts->val);
1657         } else {
1658             /* propagate constant */
1659             if (ots->val_type == TEMP_VAL_REG)
1660                 s->reg_to_temp[ots->reg] = -1;
1661             ots->val_type = TEMP_VAL_CONST;
1662             ots->val = ts->val;
1663             return;
1664         }
1665     } else {
1666         tcg_abort();
1667     }
1668     s->reg_to_temp[reg] = args[0];
1669     ots->reg = reg;
1670     ots->val_type = TEMP_VAL_REG;
1671     ots->mem_coherent = 0;
1672 }
1673 
1674 static void tcg_reg_alloc_op(TCGContext *s,
1675                              const TCGOpDef *def, TCGOpcode opc,
1676                              const TCGArg *args,
1677                              unsigned int dead_args)
1678 {
1679     TCGRegSet allocated_regs;
1680     int i, k, nb_iargs, nb_oargs, reg;
1681     TCGArg arg;
1682     const TCGArgConstraint *arg_ct;
1683     TCGTemp *ts;
1684     TCGArg new_args[TCG_MAX_OP_ARGS];
1685     int const_args[TCG_MAX_OP_ARGS];
1686 
1687     nb_oargs = def->nb_oargs;
1688     nb_iargs = def->nb_iargs;
1689 
1690     /* copy constants */
1691     memcpy(new_args + nb_oargs + nb_iargs,
1692            args + nb_oargs + nb_iargs,
1693            sizeof(TCGArg) * def->nb_cargs);
1694 
1695     /* satisfy input constraints */
1696     tcg_regset_set(allocated_regs, s->reserved_regs);
1697     for(k = 0; k < nb_iargs; k++) {
1698         i = def->sorted_args[nb_oargs + k];
1699         arg = args[i];
1700         arg_ct = &def->args_ct[i];
1701         ts = &s->temps[arg];
1702         if (ts->val_type == TEMP_VAL_MEM) {
1703             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1704             tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1705             ts->val_type = TEMP_VAL_REG;
1706             ts->reg = reg;
1707             ts->mem_coherent = 1;
1708             s->reg_to_temp[reg] = arg;
1709         } else if (ts->val_type == TEMP_VAL_CONST) {
1710             if (tcg_target_const_match(ts->val, arg_ct)) {
1711                 /* constant is OK for instruction */
1712                 const_args[i] = 1;
1713                 new_args[i] = ts->val;
1714                 goto iarg_end;
1715             } else {
1716                 /* need to move to a register */
1717                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1718                 tcg_out_movi(s, ts->type, reg, ts->val);
1719                 ts->val_type = TEMP_VAL_REG;
1720                 ts->reg = reg;
1721                 ts->mem_coherent = 0;
1722                 s->reg_to_temp[reg] = arg;
1723             }
1724         }
1725         assert(ts->val_type == TEMP_VAL_REG);
1726         if (arg_ct->ct & TCG_CT_IALIAS) {
1727             if (ts->fixed_reg) {
1728                 /* if fixed register, we must allocate a new register
1729                    if the alias is not the same register */
1730                 if (arg != args[arg_ct->alias_index])
1731                     goto allocate_in_reg;
1732             } else {
1733                 /* if the input is aliased to an output and if it is
1734                    not dead after the instruction, we must allocate
1735                    a new register and move it */
1736                 if (!IS_DEAD_ARG(i)) {
1737                     goto allocate_in_reg;
1738                 }
1739             }
1740         }
1741         reg = ts->reg;
1742         if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1743             /* nothing to do : the constraint is satisfied */
1744         } else {
1745         allocate_in_reg:
1746             /* allocate a new register matching the constraint
1747                and move the temporary register into it */
1748             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1749             tcg_out_mov(s, ts->type, reg, ts->reg);
1750         }
1751         new_args[i] = reg;
1752         const_args[i] = 0;
1753         tcg_regset_set_reg(allocated_regs, reg);
1754     iarg_end: ;
1755     }
1756 
1757     if (def->flags & TCG_OPF_BB_END) {
1758         tcg_reg_alloc_bb_end(s, allocated_regs);
1759     } else {
1760         /* mark dead temporaries and free the associated registers */
1761         for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1762             arg = args[i];
1763             if (IS_DEAD_ARG(i)) {
1764                 ts = &s->temps[arg];
1765                 if (!ts->fixed_reg) {
1766                     if (ts->val_type == TEMP_VAL_REG)
1767                         s->reg_to_temp[ts->reg] = -1;
1768                     ts->val_type = TEMP_VAL_DEAD;
1769                 }
1770             }
1771         }
1772 
1773         if (def->flags & TCG_OPF_CALL_CLOBBER) {
1774             /* XXX: permit generic clobber register list ? */
1775             for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1776                 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1777                     tcg_reg_free(s, reg);
1778                 }
1779             }
1780             /* XXX: for load/store we could do that only for the slow path
1781                (i.e. when a memory callback is called) */
1782 
1783             /* store globals and free associated registers (we assume the insn
1784                can modify any global. */
1785             save_globals(s, allocated_regs);
1786         }
1787 
1788         /* satisfy the output constraints */
1789         tcg_regset_set(allocated_regs, s->reserved_regs);
1790         for(k = 0; k < nb_oargs; k++) {
1791             i = def->sorted_args[k];
1792             arg = args[i];
1793             arg_ct = &def->args_ct[i];
1794             ts = &s->temps[arg];
1795             if (arg_ct->ct & TCG_CT_ALIAS) {
1796                 reg = new_args[arg_ct->alias_index];
1797             } else {
1798                 /* if fixed register, we try to use it */
1799                 reg = ts->reg;
1800                 if (ts->fixed_reg &&
1801                     tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1802                     goto oarg_end;
1803                 }
1804                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1805             }
1806             tcg_regset_set_reg(allocated_regs, reg);
1807             /* if a fixed register is used, then a move will be done afterwards */
1808             if (!ts->fixed_reg) {
1809                 if (ts->val_type == TEMP_VAL_REG)
1810                     s->reg_to_temp[ts->reg] = -1;
1811                 if (IS_DEAD_ARG(i)) {
1812                     ts->val_type = TEMP_VAL_DEAD;
1813                 } else {
1814                     ts->val_type = TEMP_VAL_REG;
1815                     ts->reg = reg;
1816                     /* temp value is modified, so the value kept in memory is
1817                        potentially not the same */
1818                     ts->mem_coherent = 0;
1819                     s->reg_to_temp[reg] = arg;
1820                }
1821             }
1822         oarg_end:
1823             new_args[i] = reg;
1824         }
1825     }
1826 
1827     /* emit instruction */
1828     tcg_out_op(s, opc, new_args, const_args);
1829 
1830     /* move the outputs in the correct register if needed */
1831     for(i = 0; i < nb_oargs; i++) {
1832         ts = &s->temps[args[i]];
1833         reg = new_args[i];
1834         if (ts->fixed_reg && ts->reg != reg) {
1835             tcg_out_mov(s, ts->type, ts->reg, reg);
1836         }
1837     }
1838 }
1839 
1840 #ifdef TCG_TARGET_STACK_GROWSUP
1841 #define STACK_DIR(x) (-(x))
1842 #else
1843 #define STACK_DIR(x) (x)
1844 #endif
1845 
1846 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1847                               TCGOpcode opc, const TCGArg *args,
1848                               unsigned int dead_args)
1849 {
1850     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1851     TCGArg arg, func_arg;
1852     TCGTemp *ts;
1853     tcg_target_long stack_offset, call_stack_size, func_addr;
1854     int const_func_arg, allocate_args;
1855     TCGRegSet allocated_regs;
1856     const TCGArgConstraint *arg_ct;
1857 
1858     arg = *args++;
1859 
1860     nb_oargs = arg >> 16;
1861     nb_iargs = arg & 0xffff;
1862     nb_params = nb_iargs - 1;
1863 
1864     flags = args[nb_oargs + nb_iargs];
1865 
1866     nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1867     if (nb_regs > nb_params)
1868         nb_regs = nb_params;
1869 
1870     /* assign stack slots first */
1871     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1872     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
1873         ~(TCG_TARGET_STACK_ALIGN - 1);
1874     allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1875     if (allocate_args) {
1876         /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1877            preallocate call stack */
1878         tcg_abort();
1879     }
1880 
1881     stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1882     for(i = nb_regs; i < nb_params; i++) {
1883         arg = args[nb_oargs + i];
1884 #ifdef TCG_TARGET_STACK_GROWSUP
1885         stack_offset -= sizeof(tcg_target_long);
1886 #endif
1887         if (arg != TCG_CALL_DUMMY_ARG) {
1888             ts = &s->temps[arg];
1889             if (ts->val_type == TEMP_VAL_REG) {
1890                 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1891             } else if (ts->val_type == TEMP_VAL_MEM) {
1892                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1893                                     s->reserved_regs);
1894                 /* XXX: not correct if reading values from the stack */
1895                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1896                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1897             } else if (ts->val_type == TEMP_VAL_CONST) {
1898                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1899                                     s->reserved_regs);
1900                 /* XXX: sign extend may be needed on some targets */
1901                 tcg_out_movi(s, ts->type, reg, ts->val);
1902                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1903             } else {
1904                 tcg_abort();
1905             }
1906         }
1907 #ifndef TCG_TARGET_STACK_GROWSUP
1908         stack_offset += sizeof(tcg_target_long);
1909 #endif
1910     }
1911 
1912     /* assign input registers */
1913     tcg_regset_set(allocated_regs, s->reserved_regs);
1914     for(i = 0; i < nb_regs; i++) {
1915         arg = args[nb_oargs + i];
1916         if (arg != TCG_CALL_DUMMY_ARG) {
1917             ts = &s->temps[arg];
1918             reg = tcg_target_call_iarg_regs[i];
1919             tcg_reg_free(s, reg);
1920             if (ts->val_type == TEMP_VAL_REG) {
1921                 if (ts->reg != reg) {
1922                     tcg_out_mov(s, ts->type, reg, ts->reg);
1923                 }
1924             } else if (ts->val_type == TEMP_VAL_MEM) {
1925                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1926             } else if (ts->val_type == TEMP_VAL_CONST) {
1927                 /* XXX: sign extend ? */
1928                 tcg_out_movi(s, ts->type, reg, ts->val);
1929             } else {
1930                 tcg_abort();
1931             }
1932             tcg_regset_set_reg(allocated_regs, reg);
1933         }
1934     }
1935 
1936     /* assign function address */
1937     func_arg = args[nb_oargs + nb_iargs - 1];
1938     arg_ct = &def->args_ct[0];
1939     ts = &s->temps[func_arg];
1940     func_addr = ts->val;
1941     const_func_arg = 0;
1942     if (ts->val_type == TEMP_VAL_MEM) {
1943         reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1944         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1945         func_arg = reg;
1946         tcg_regset_set_reg(allocated_regs, reg);
1947     } else if (ts->val_type == TEMP_VAL_REG) {
1948         reg = ts->reg;
1949         if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1950             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1951             tcg_out_mov(s, ts->type, reg, ts->reg);
1952         }
1953         func_arg = reg;
1954         tcg_regset_set_reg(allocated_regs, reg);
1955     } else if (ts->val_type == TEMP_VAL_CONST) {
1956         if (tcg_target_const_match(func_addr, arg_ct)) {
1957             const_func_arg = 1;
1958             func_arg = func_addr;
1959         } else {
1960             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1961             tcg_out_movi(s, ts->type, reg, func_addr);
1962             func_arg = reg;
1963             tcg_regset_set_reg(allocated_regs, reg);
1964         }
1965     } else {
1966         tcg_abort();
1967     }
1968 
1969 
1970     /* mark dead temporaries and free the associated registers */
1971     for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1972         arg = args[i];
1973         if (IS_DEAD_ARG(i)) {
1974             ts = &s->temps[arg];
1975             if (!ts->fixed_reg) {
1976                 if (ts->val_type == TEMP_VAL_REG)
1977                     s->reg_to_temp[ts->reg] = -1;
1978                 ts->val_type = TEMP_VAL_DEAD;
1979             }
1980         }
1981     }
1982 
1983     /* clobber call registers */
1984     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1985         if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1986             tcg_reg_free(s, reg);
1987         }
1988     }
1989 
1990     /* store globals and free associated registers (we assume the call
1991        can modify any global. */
1992     if (!(flags & TCG_CALL_CONST)) {
1993         save_globals(s, allocated_regs);
1994     }
1995 
1996     tcg_out_op(s, opc, &func_arg, &const_func_arg);
1997 
1998     /* assign output registers and emit moves if needed */
1999     for(i = 0; i < nb_oargs; i++) {
2000         arg = args[i];
2001         ts = &s->temps[arg];
2002         reg = tcg_target_call_oarg_regs[i];
2003         assert(s->reg_to_temp[reg] == -1);
2004         if (ts->fixed_reg) {
2005             if (ts->reg != reg) {
2006                 tcg_out_mov(s, ts->type, ts->reg, reg);
2007             }
2008         } else {
2009             if (ts->val_type == TEMP_VAL_REG)
2010                 s->reg_to_temp[ts->reg] = -1;
2011             if (IS_DEAD_ARG(i)) {
2012                 ts->val_type = TEMP_VAL_DEAD;
2013             } else {
2014                 ts->val_type = TEMP_VAL_REG;
2015                 ts->reg = reg;
2016                 ts->mem_coherent = 0;
2017                 s->reg_to_temp[reg] = arg;
2018             }
2019         }
2020     }
2021 
2022     return nb_iargs + nb_oargs + def->nb_cargs + 1;
2023 }
2024 
2025 #ifdef CONFIG_PROFILER
2026 
2027 static int64_t tcg_table_op_count[NB_OPS];
2028 
2029 static void dump_op_count(void)
2030 {
2031     int i;
2032     FILE *f;
2033     f = fopen("/tmp/op.log", "w");
2034     for(i = INDEX_op_end; i < NB_OPS; i++) {
2035         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2036     }
2037     fclose(f);
2038 }
2039 #endif
2040 
2041 
2042 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2043                                       long search_pc)
2044 {
2045     TCGOpcode opc;
2046     int op_index;
2047     const TCGOpDef *def;
2048     unsigned int dead_args;
2049     const TCGArg *args;
2050 
2051 #ifdef DEBUG_DISAS
2052     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2053         qemu_log("OP:\n");
2054         tcg_dump_ops(s, logfile);
2055         qemu_log("\n");
2056     }
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->la_time -= profile_getclock();
2066 #endif
2067     tcg_liveness_analysis(s);
2068 #ifdef CONFIG_PROFILER
2069     s->la_time += profile_getclock();
2070 #endif
2071 
2072 #ifdef DEBUG_DISAS
2073     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2074         qemu_log("OP after liveness analysis:\n");
2075         tcg_dump_ops(s, logfile);
2076         qemu_log("\n");
2077     }
2078 #endif
2079 
2080     tcg_reg_alloc_start(s);
2081 
2082     s->code_buf = gen_code_buf;
2083     s->code_ptr = gen_code_buf;
2084 
2085     args = gen_opparam_buf;
2086     op_index = 0;
2087 
2088     for(;;) {
2089         opc = gen_opc_buf[op_index];
2090 #ifdef CONFIG_PROFILER
2091         tcg_table_op_count[opc]++;
2092 #endif
2093         def = &tcg_op_defs[opc];
2094 #if 0
2095         printf("%s: %d %d %d\n", def->name,
2096                def->nb_oargs, def->nb_iargs, def->nb_cargs);
2097         //        dump_regs(s);
2098 #endif
2099         switch(opc) {
2100         case INDEX_op_mov_i32:
2101 #if TCG_TARGET_REG_BITS == 64
2102         case INDEX_op_mov_i64:
2103 #endif
2104             dead_args = s->op_dead_args[op_index];
2105             tcg_reg_alloc_mov(s, def, args, dead_args);
2106             break;
2107         case INDEX_op_movi_i32:
2108 #if TCG_TARGET_REG_BITS == 64
2109         case INDEX_op_movi_i64:
2110 #endif
2111             tcg_reg_alloc_movi(s, args);
2112             break;
2113         case INDEX_op_debug_insn_start:
2114             /* debug instruction */
2115             break;
2116         case INDEX_op_nop:
2117         case INDEX_op_nop1:
2118         case INDEX_op_nop2:
2119         case INDEX_op_nop3:
2120             break;
2121         case INDEX_op_nopn:
2122             args += args[0];
2123             goto next;
2124         case INDEX_op_discard:
2125             {
2126                 TCGTemp *ts;
2127                 ts = &s->temps[args[0]];
2128                 /* mark the temporary as dead */
2129                 if (!ts->fixed_reg) {
2130                     if (ts->val_type == TEMP_VAL_REG)
2131                         s->reg_to_temp[ts->reg] = -1;
2132                     ts->val_type = TEMP_VAL_DEAD;
2133                 }
2134             }
2135             break;
2136         case INDEX_op_set_label:
2137             tcg_reg_alloc_bb_end(s, s->reserved_regs);
2138             tcg_out_label(s, args[0], (long)s->code_ptr);
2139             break;
2140         case INDEX_op_call:
2141             dead_args = s->op_dead_args[op_index];
2142             args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2143             goto next;
2144         case INDEX_op_end:
2145             goto the_end;
2146         default:
2147             /* Sanity check that we've not introduced any unhandled opcodes. */
2148             if (def->flags & TCG_OPF_NOT_PRESENT) {
2149                 tcg_abort();
2150             }
2151             /* Note: in order to speed up the code, it would be much
2152                faster to have specialized register allocator functions for
2153                some common argument patterns */
2154             dead_args = s->op_dead_args[op_index];
2155             tcg_reg_alloc_op(s, def, opc, args, dead_args);
2156             break;
2157         }
2158         args += def->nb_args;
2159     next:
2160         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2161             return op_index;
2162         }
2163         op_index++;
2164 #ifndef NDEBUG
2165         check_regs(s);
2166 #endif
2167     }
2168  the_end:
2169     return -1;
2170 }
2171 
2172 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2173 {
2174 #ifdef CONFIG_PROFILER
2175     {
2176         int n;
2177         n = (gen_opc_ptr - gen_opc_buf);
2178         s->op_count += n;
2179         if (n > s->op_count_max)
2180             s->op_count_max = n;
2181 
2182         s->temp_count += s->nb_temps;
2183         if (s->nb_temps > s->temp_count_max)
2184             s->temp_count_max = s->nb_temps;
2185     }
2186 #endif
2187 
2188     tcg_gen_code_common(s, gen_code_buf, -1);
2189 
2190     /* flush instruction cache */
2191     flush_icache_range((unsigned long)gen_code_buf,
2192                        (unsigned long)s->code_ptr);
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, "liveness/code time  %0.1f%%\n",
2241                 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2242     cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2243                 s->restore_count);
2244     cpu_fprintf(f, "  avg cycles        %0.1f\n",
2245                 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2246 
2247     dump_op_count();
2248 }
2249 #else
2250 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2251 {
2252     cpu_fprintf(f, "[TCG profiler not compiled]\n");
2253 }
2254 #endif
2255