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