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