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