xref: /openbmc/qemu/tcg/tcg.c (revision 51b24e34)
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 
28 #include "config.h"
29 
30 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
31 /* define it to suppress various consistency checks (faster) */
32 #define NDEBUG
33 #endif
34 
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <inttypes.h>
40 #ifdef _WIN32
41 #include <malloc.h>
42 #endif
43 #ifdef _AIX
44 #include <alloca.h>
45 #endif
46 
47 #include "qemu-common.h"
48 #include "cache-utils.h"
49 #include "host-utils.h"
50 #include "qemu-timer.h"
51 
52 /* Note: the long term plan is to reduce the dependancies on the QEMU
53    CPU definitions. Currently they are used for qemu_ld/st
54    instructions */
55 #define NO_CPU_IO_DEFS
56 #include "cpu.h"
57 #include "exec-all.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 = qemu_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 = qemu_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 = qemu_malloc(sizeof(TCGArgConstraint) * total_args);
231     sorted_args = qemu_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     s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
1444     if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
1445         tcg_abort();
1446     ts->mem_offset = s->current_frame_offset;
1447     ts->mem_reg = s->frame_reg;
1448     ts->mem_allocated = 1;
1449     s->current_frame_offset += sizeof(tcg_target_long);
1450 }
1451 
1452 /* free register 'reg' by spilling the corresponding temporary if necessary */
1453 static void tcg_reg_free(TCGContext *s, int reg)
1454 {
1455     TCGTemp *ts;
1456     int temp;
1457 
1458     temp = s->reg_to_temp[reg];
1459     if (temp != -1) {
1460         ts = &s->temps[temp];
1461         assert(ts->val_type == TEMP_VAL_REG);
1462         if (!ts->mem_coherent) {
1463             if (!ts->mem_allocated)
1464                 temp_allocate_frame(s, temp);
1465             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1466         }
1467         ts->val_type = TEMP_VAL_MEM;
1468         s->reg_to_temp[reg] = -1;
1469     }
1470 }
1471 
1472 /* Allocate a register belonging to reg1 & ~reg2 */
1473 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1474 {
1475     int i, reg;
1476     TCGRegSet reg_ct;
1477 
1478     tcg_regset_andnot(reg_ct, reg1, reg2);
1479 
1480     /* first try free registers */
1481     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1482         reg = tcg_target_reg_alloc_order[i];
1483         if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1484             return reg;
1485     }
1486 
1487     /* XXX: do better spill choice */
1488     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1489         reg = tcg_target_reg_alloc_order[i];
1490         if (tcg_regset_test_reg(reg_ct, reg)) {
1491             tcg_reg_free(s, reg);
1492             return reg;
1493         }
1494     }
1495 
1496     tcg_abort();
1497 }
1498 
1499 /* save a temporary to memory. 'allocated_regs' is used in case a
1500    temporary registers needs to be allocated to store a constant. */
1501 static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1502 {
1503     TCGTemp *ts;
1504     int reg;
1505 
1506     ts = &s->temps[temp];
1507     if (!ts->fixed_reg) {
1508         switch(ts->val_type) {
1509         case TEMP_VAL_REG:
1510             tcg_reg_free(s, ts->reg);
1511             break;
1512         case TEMP_VAL_DEAD:
1513             ts->val_type = TEMP_VAL_MEM;
1514             break;
1515         case TEMP_VAL_CONST:
1516             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1517                                 allocated_regs);
1518             if (!ts->mem_allocated)
1519                 temp_allocate_frame(s, temp);
1520             tcg_out_movi(s, ts->type, reg, ts->val);
1521             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1522             ts->val_type = TEMP_VAL_MEM;
1523             break;
1524         case TEMP_VAL_MEM:
1525             break;
1526         default:
1527             tcg_abort();
1528         }
1529     }
1530 }
1531 
1532 /* save globals to their cannonical location and assume they can be
1533    modified be the following code. 'allocated_regs' is used in case a
1534    temporary registers needs to be allocated to store a constant. */
1535 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1536 {
1537     int i;
1538 
1539     for(i = 0; i < s->nb_globals; i++) {
1540         temp_save(s, i, allocated_regs);
1541     }
1542 }
1543 
1544 /* at the end of a basic block, we assume all temporaries are dead and
1545    all globals are stored at their canonical location. */
1546 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1547 {
1548     TCGTemp *ts;
1549     int i;
1550 
1551     for(i = s->nb_globals; i < s->nb_temps; i++) {
1552         ts = &s->temps[i];
1553         if (ts->temp_local) {
1554             temp_save(s, i, allocated_regs);
1555         } else {
1556             if (ts->val_type == TEMP_VAL_REG) {
1557                 s->reg_to_temp[ts->reg] = -1;
1558             }
1559             ts->val_type = TEMP_VAL_DEAD;
1560         }
1561     }
1562 
1563     save_globals(s, allocated_regs);
1564 }
1565 
1566 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1567 
1568 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1569 {
1570     TCGTemp *ots;
1571     tcg_target_ulong val;
1572 
1573     ots = &s->temps[args[0]];
1574     val = args[1];
1575 
1576     if (ots->fixed_reg) {
1577         /* for fixed registers, we do not do any constant
1578            propagation */
1579         tcg_out_movi(s, ots->type, ots->reg, val);
1580     } else {
1581         /* The movi is not explicitly generated here */
1582         if (ots->val_type == TEMP_VAL_REG)
1583             s->reg_to_temp[ots->reg] = -1;
1584         ots->val_type = TEMP_VAL_CONST;
1585         ots->val = val;
1586     }
1587 }
1588 
1589 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1590                               const TCGArg *args,
1591                               unsigned int dead_args)
1592 {
1593     TCGTemp *ts, *ots;
1594     int reg;
1595     const TCGArgConstraint *arg_ct;
1596 
1597     ots = &s->temps[args[0]];
1598     ts = &s->temps[args[1]];
1599     arg_ct = &def->args_ct[0];
1600 
1601     /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1602     if (ts->val_type == TEMP_VAL_REG) {
1603         if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1604             /* the mov can be suppressed */
1605             if (ots->val_type == TEMP_VAL_REG)
1606                 s->reg_to_temp[ots->reg] = -1;
1607             reg = ts->reg;
1608             s->reg_to_temp[reg] = -1;
1609             ts->val_type = TEMP_VAL_DEAD;
1610         } else {
1611             if (ots->val_type == TEMP_VAL_REG) {
1612                 reg = ots->reg;
1613             } else {
1614                 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1615             }
1616             if (ts->reg != reg) {
1617                 tcg_out_mov(s, ots->type, reg, ts->reg);
1618             }
1619         }
1620     } else if (ts->val_type == TEMP_VAL_MEM) {
1621         if (ots->val_type == TEMP_VAL_REG) {
1622             reg = ots->reg;
1623         } else {
1624             reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1625         }
1626         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1627     } else if (ts->val_type == TEMP_VAL_CONST) {
1628         if (ots->fixed_reg) {
1629             reg = ots->reg;
1630             tcg_out_movi(s, ots->type, reg, ts->val);
1631         } else {
1632             /* propagate constant */
1633             if (ots->val_type == TEMP_VAL_REG)
1634                 s->reg_to_temp[ots->reg] = -1;
1635             ots->val_type = TEMP_VAL_CONST;
1636             ots->val = ts->val;
1637             return;
1638         }
1639     } else {
1640         tcg_abort();
1641     }
1642     s->reg_to_temp[reg] = args[0];
1643     ots->reg = reg;
1644     ots->val_type = TEMP_VAL_REG;
1645     ots->mem_coherent = 0;
1646 }
1647 
1648 static void tcg_reg_alloc_op(TCGContext *s,
1649                              const TCGOpDef *def, TCGOpcode opc,
1650                              const TCGArg *args,
1651                              unsigned int dead_args)
1652 {
1653     TCGRegSet allocated_regs;
1654     int i, k, nb_iargs, nb_oargs, reg;
1655     TCGArg arg;
1656     const TCGArgConstraint *arg_ct;
1657     TCGTemp *ts;
1658     TCGArg new_args[TCG_MAX_OP_ARGS];
1659     int const_args[TCG_MAX_OP_ARGS];
1660 
1661     nb_oargs = def->nb_oargs;
1662     nb_iargs = def->nb_iargs;
1663 
1664     /* copy constants */
1665     memcpy(new_args + nb_oargs + nb_iargs,
1666            args + nb_oargs + nb_iargs,
1667            sizeof(TCGArg) * def->nb_cargs);
1668 
1669     /* satisfy input constraints */
1670     tcg_regset_set(allocated_regs, s->reserved_regs);
1671     for(k = 0; k < nb_iargs; k++) {
1672         i = def->sorted_args[nb_oargs + k];
1673         arg = args[i];
1674         arg_ct = &def->args_ct[i];
1675         ts = &s->temps[arg];
1676         if (ts->val_type == TEMP_VAL_MEM) {
1677             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1678             tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1679             ts->val_type = TEMP_VAL_REG;
1680             ts->reg = reg;
1681             ts->mem_coherent = 1;
1682             s->reg_to_temp[reg] = arg;
1683         } else if (ts->val_type == TEMP_VAL_CONST) {
1684             if (tcg_target_const_match(ts->val, arg_ct)) {
1685                 /* constant is OK for instruction */
1686                 const_args[i] = 1;
1687                 new_args[i] = ts->val;
1688                 goto iarg_end;
1689             } else {
1690                 /* need to move to a register */
1691                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1692                 tcg_out_movi(s, ts->type, reg, ts->val);
1693                 ts->val_type = TEMP_VAL_REG;
1694                 ts->reg = reg;
1695                 ts->mem_coherent = 0;
1696                 s->reg_to_temp[reg] = arg;
1697             }
1698         }
1699         assert(ts->val_type == TEMP_VAL_REG);
1700         if (arg_ct->ct & TCG_CT_IALIAS) {
1701             if (ts->fixed_reg) {
1702                 /* if fixed register, we must allocate a new register
1703                    if the alias is not the same register */
1704                 if (arg != args[arg_ct->alias_index])
1705                     goto allocate_in_reg;
1706             } else {
1707                 /* if the input is aliased to an output and if it is
1708                    not dead after the instruction, we must allocate
1709                    a new register and move it */
1710                 if (!IS_DEAD_ARG(i)) {
1711                     goto allocate_in_reg;
1712                 }
1713             }
1714         }
1715         reg = ts->reg;
1716         if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1717             /* nothing to do : the constraint is satisfied */
1718         } else {
1719         allocate_in_reg:
1720             /* allocate a new register matching the constraint
1721                and move the temporary register into it */
1722             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1723             tcg_out_mov(s, ts->type, reg, ts->reg);
1724         }
1725         new_args[i] = reg;
1726         const_args[i] = 0;
1727         tcg_regset_set_reg(allocated_regs, reg);
1728     iarg_end: ;
1729     }
1730 
1731     if (def->flags & TCG_OPF_BB_END) {
1732         tcg_reg_alloc_bb_end(s, allocated_regs);
1733     } else {
1734         /* mark dead temporaries and free the associated registers */
1735         for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1736             arg = args[i];
1737             if (IS_DEAD_ARG(i)) {
1738                 ts = &s->temps[arg];
1739                 if (!ts->fixed_reg) {
1740                     if (ts->val_type == TEMP_VAL_REG)
1741                         s->reg_to_temp[ts->reg] = -1;
1742                     ts->val_type = TEMP_VAL_DEAD;
1743                 }
1744             }
1745         }
1746 
1747         if (def->flags & TCG_OPF_CALL_CLOBBER) {
1748             /* XXX: permit generic clobber register list ? */
1749             for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1750                 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1751                     tcg_reg_free(s, reg);
1752                 }
1753             }
1754             /* XXX: for load/store we could do that only for the slow path
1755                (i.e. when a memory callback is called) */
1756 
1757             /* store globals and free associated registers (we assume the insn
1758                can modify any global. */
1759             save_globals(s, allocated_regs);
1760         }
1761 
1762         /* satisfy the output constraints */
1763         tcg_regset_set(allocated_regs, s->reserved_regs);
1764         for(k = 0; k < nb_oargs; k++) {
1765             i = def->sorted_args[k];
1766             arg = args[i];
1767             arg_ct = &def->args_ct[i];
1768             ts = &s->temps[arg];
1769             if (arg_ct->ct & TCG_CT_ALIAS) {
1770                 reg = new_args[arg_ct->alias_index];
1771             } else {
1772                 /* if fixed register, we try to use it */
1773                 reg = ts->reg;
1774                 if (ts->fixed_reg &&
1775                     tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1776                     goto oarg_end;
1777                 }
1778                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1779             }
1780             tcg_regset_set_reg(allocated_regs, reg);
1781             /* if a fixed register is used, then a move will be done afterwards */
1782             if (!ts->fixed_reg) {
1783                 if (ts->val_type == TEMP_VAL_REG)
1784                     s->reg_to_temp[ts->reg] = -1;
1785                 if (IS_DEAD_ARG(i)) {
1786                     ts->val_type = TEMP_VAL_DEAD;
1787                 } else {
1788                     ts->val_type = TEMP_VAL_REG;
1789                     ts->reg = reg;
1790                     /* temp value is modified, so the value kept in memory is
1791                        potentially not the same */
1792                     ts->mem_coherent = 0;
1793                     s->reg_to_temp[reg] = arg;
1794                }
1795             }
1796         oarg_end:
1797             new_args[i] = reg;
1798         }
1799     }
1800 
1801     /* emit instruction */
1802     tcg_out_op(s, opc, new_args, const_args);
1803 
1804     /* move the outputs in the correct register if needed */
1805     for(i = 0; i < nb_oargs; i++) {
1806         ts = &s->temps[args[i]];
1807         reg = new_args[i];
1808         if (ts->fixed_reg && ts->reg != reg) {
1809             tcg_out_mov(s, ts->type, ts->reg, reg);
1810         }
1811     }
1812 }
1813 
1814 #ifdef TCG_TARGET_STACK_GROWSUP
1815 #define STACK_DIR(x) (-(x))
1816 #else
1817 #define STACK_DIR(x) (x)
1818 #endif
1819 
1820 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1821                               TCGOpcode opc, const TCGArg *args,
1822                               unsigned int dead_args)
1823 {
1824     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1825     TCGArg arg, func_arg;
1826     TCGTemp *ts;
1827     tcg_target_long stack_offset, call_stack_size, func_addr;
1828     int const_func_arg, allocate_args;
1829     TCGRegSet allocated_regs;
1830     const TCGArgConstraint *arg_ct;
1831 
1832     arg = *args++;
1833 
1834     nb_oargs = arg >> 16;
1835     nb_iargs = arg & 0xffff;
1836     nb_params = nb_iargs - 1;
1837 
1838     flags = args[nb_oargs + nb_iargs];
1839 
1840     nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1841     if (nb_regs > nb_params)
1842         nb_regs = nb_params;
1843 
1844     /* assign stack slots first */
1845     /* XXX: preallocate call stack */
1846     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1847     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
1848         ~(TCG_TARGET_STACK_ALIGN - 1);
1849     allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1850     if (allocate_args) {
1851         tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
1852     }
1853 
1854     stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1855     for(i = nb_regs; i < nb_params; i++) {
1856         arg = args[nb_oargs + i];
1857 #ifdef TCG_TARGET_STACK_GROWSUP
1858         stack_offset -= sizeof(tcg_target_long);
1859 #endif
1860         if (arg != TCG_CALL_DUMMY_ARG) {
1861             ts = &s->temps[arg];
1862             if (ts->val_type == TEMP_VAL_REG) {
1863                 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1864             } else if (ts->val_type == TEMP_VAL_MEM) {
1865                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1866                                     s->reserved_regs);
1867                 /* XXX: not correct if reading values from the stack */
1868                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1869                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1870             } else if (ts->val_type == TEMP_VAL_CONST) {
1871                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1872                                     s->reserved_regs);
1873                 /* XXX: sign extend may be needed on some targets */
1874                 tcg_out_movi(s, ts->type, reg, ts->val);
1875                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1876             } else {
1877                 tcg_abort();
1878             }
1879         }
1880 #ifndef TCG_TARGET_STACK_GROWSUP
1881         stack_offset += sizeof(tcg_target_long);
1882 #endif
1883     }
1884 
1885     /* assign input registers */
1886     tcg_regset_set(allocated_regs, s->reserved_regs);
1887     for(i = 0; i < nb_regs; i++) {
1888         arg = args[nb_oargs + i];
1889         if (arg != TCG_CALL_DUMMY_ARG) {
1890             ts = &s->temps[arg];
1891             reg = tcg_target_call_iarg_regs[i];
1892             tcg_reg_free(s, reg);
1893             if (ts->val_type == TEMP_VAL_REG) {
1894                 if (ts->reg != reg) {
1895                     tcg_out_mov(s, ts->type, reg, ts->reg);
1896                 }
1897             } else if (ts->val_type == TEMP_VAL_MEM) {
1898                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1899             } else if (ts->val_type == TEMP_VAL_CONST) {
1900                 /* XXX: sign extend ? */
1901                 tcg_out_movi(s, ts->type, reg, ts->val);
1902             } else {
1903                 tcg_abort();
1904             }
1905             tcg_regset_set_reg(allocated_regs, reg);
1906         }
1907     }
1908 
1909     /* assign function address */
1910     func_arg = args[nb_oargs + nb_iargs - 1];
1911     arg_ct = &def->args_ct[0];
1912     ts = &s->temps[func_arg];
1913     func_addr = ts->val;
1914     const_func_arg = 0;
1915     if (ts->val_type == TEMP_VAL_MEM) {
1916         reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1917         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1918         func_arg = reg;
1919         tcg_regset_set_reg(allocated_regs, reg);
1920     } else if (ts->val_type == TEMP_VAL_REG) {
1921         reg = ts->reg;
1922         if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1923             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1924             tcg_out_mov(s, ts->type, reg, ts->reg);
1925         }
1926         func_arg = reg;
1927         tcg_regset_set_reg(allocated_regs, reg);
1928     } else if (ts->val_type == TEMP_VAL_CONST) {
1929         if (tcg_target_const_match(func_addr, arg_ct)) {
1930             const_func_arg = 1;
1931             func_arg = func_addr;
1932         } else {
1933             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1934             tcg_out_movi(s, ts->type, reg, func_addr);
1935             func_arg = reg;
1936             tcg_regset_set_reg(allocated_regs, reg);
1937         }
1938     } else {
1939         tcg_abort();
1940     }
1941 
1942 
1943     /* mark dead temporaries and free the associated registers */
1944     for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1945         arg = args[i];
1946         if (IS_DEAD_ARG(i)) {
1947             ts = &s->temps[arg];
1948             if (!ts->fixed_reg) {
1949                 if (ts->val_type == TEMP_VAL_REG)
1950                     s->reg_to_temp[ts->reg] = -1;
1951                 ts->val_type = TEMP_VAL_DEAD;
1952             }
1953         }
1954     }
1955 
1956     /* clobber call registers */
1957     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1958         if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1959             tcg_reg_free(s, reg);
1960         }
1961     }
1962 
1963     /* store globals and free associated registers (we assume the call
1964        can modify any global. */
1965     if (!(flags & TCG_CALL_CONST)) {
1966         save_globals(s, allocated_regs);
1967     }
1968 
1969     tcg_out_op(s, opc, &func_arg, &const_func_arg);
1970 
1971     if (allocate_args) {
1972         tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
1973     }
1974 
1975     /* assign output registers and emit moves if needed */
1976     for(i = 0; i < nb_oargs; i++) {
1977         arg = args[i];
1978         ts = &s->temps[arg];
1979         reg = tcg_target_call_oarg_regs[i];
1980         assert(s->reg_to_temp[reg] == -1);
1981         if (ts->fixed_reg) {
1982             if (ts->reg != reg) {
1983                 tcg_out_mov(s, ts->type, ts->reg, reg);
1984             }
1985         } else {
1986             if (ts->val_type == TEMP_VAL_REG)
1987                 s->reg_to_temp[ts->reg] = -1;
1988             if (IS_DEAD_ARG(i)) {
1989                 ts->val_type = TEMP_VAL_DEAD;
1990             } else {
1991                 ts->val_type = TEMP_VAL_REG;
1992                 ts->reg = reg;
1993                 ts->mem_coherent = 0;
1994                 s->reg_to_temp[reg] = arg;
1995             }
1996         }
1997     }
1998 
1999     return nb_iargs + nb_oargs + def->nb_cargs + 1;
2000 }
2001 
2002 #ifdef CONFIG_PROFILER
2003 
2004 static int64_t tcg_table_op_count[NB_OPS];
2005 
2006 static void dump_op_count(void)
2007 {
2008     int i;
2009     FILE *f;
2010     f = fopen("/tmp/op.log", "w");
2011     for(i = INDEX_op_end; i < NB_OPS; i++) {
2012         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2013     }
2014     fclose(f);
2015 }
2016 #endif
2017 
2018 
2019 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2020                                       long search_pc)
2021 {
2022     TCGOpcode opc;
2023     int op_index;
2024     const TCGOpDef *def;
2025     unsigned int dead_args;
2026     const TCGArg *args;
2027 
2028 #ifdef DEBUG_DISAS
2029     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2030         qemu_log("OP:\n");
2031         tcg_dump_ops(s, logfile);
2032         qemu_log("\n");
2033     }
2034 #endif
2035 
2036 #ifdef CONFIG_PROFILER
2037     s->la_time -= profile_getclock();
2038 #endif
2039     tcg_liveness_analysis(s);
2040 #ifdef CONFIG_PROFILER
2041     s->la_time += profile_getclock();
2042 #endif
2043 
2044 #ifdef DEBUG_DISAS
2045     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2046         qemu_log("OP after liveness analysis:\n");
2047         tcg_dump_ops(s, logfile);
2048         qemu_log("\n");
2049     }
2050 #endif
2051 
2052     tcg_reg_alloc_start(s);
2053 
2054     s->code_buf = gen_code_buf;
2055     s->code_ptr = gen_code_buf;
2056 
2057     args = gen_opparam_buf;
2058     op_index = 0;
2059 
2060     for(;;) {
2061         opc = gen_opc_buf[op_index];
2062 #ifdef CONFIG_PROFILER
2063         tcg_table_op_count[opc]++;
2064 #endif
2065         def = &tcg_op_defs[opc];
2066 #if 0
2067         printf("%s: %d %d %d\n", def->name,
2068                def->nb_oargs, def->nb_iargs, def->nb_cargs);
2069         //        dump_regs(s);
2070 #endif
2071         switch(opc) {
2072         case INDEX_op_mov_i32:
2073 #if TCG_TARGET_REG_BITS == 64
2074         case INDEX_op_mov_i64:
2075 #endif
2076             dead_args = s->op_dead_args[op_index];
2077             tcg_reg_alloc_mov(s, def, args, dead_args);
2078             break;
2079         case INDEX_op_movi_i32:
2080 #if TCG_TARGET_REG_BITS == 64
2081         case INDEX_op_movi_i64:
2082 #endif
2083             tcg_reg_alloc_movi(s, args);
2084             break;
2085         case INDEX_op_debug_insn_start:
2086             /* debug instruction */
2087             break;
2088         case INDEX_op_nop:
2089         case INDEX_op_nop1:
2090         case INDEX_op_nop2:
2091         case INDEX_op_nop3:
2092             break;
2093         case INDEX_op_nopn:
2094             args += args[0];
2095             goto next;
2096         case INDEX_op_discard:
2097             {
2098                 TCGTemp *ts;
2099                 ts = &s->temps[args[0]];
2100                 /* mark the temporary as dead */
2101                 if (!ts->fixed_reg) {
2102                     if (ts->val_type == TEMP_VAL_REG)
2103                         s->reg_to_temp[ts->reg] = -1;
2104                     ts->val_type = TEMP_VAL_DEAD;
2105                 }
2106             }
2107             break;
2108         case INDEX_op_set_label:
2109             tcg_reg_alloc_bb_end(s, s->reserved_regs);
2110             tcg_out_label(s, args[0], (long)s->code_ptr);
2111             break;
2112         case INDEX_op_call:
2113             dead_args = s->op_dead_args[op_index];
2114             args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2115             goto next;
2116         case INDEX_op_end:
2117             goto the_end;
2118         default:
2119             /* Note: in order to speed up the code, it would be much
2120                faster to have specialized register allocator functions for
2121                some common argument patterns */
2122             dead_args = s->op_dead_args[op_index];
2123             tcg_reg_alloc_op(s, def, opc, args, dead_args);
2124             break;
2125         }
2126         args += def->nb_args;
2127     next:
2128         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2129             return op_index;
2130         }
2131         op_index++;
2132 #ifndef NDEBUG
2133         check_regs(s);
2134 #endif
2135     }
2136  the_end:
2137     return -1;
2138 }
2139 
2140 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2141 {
2142 #ifdef CONFIG_PROFILER
2143     {
2144         int n;
2145         n = (gen_opc_ptr - gen_opc_buf);
2146         s->op_count += n;
2147         if (n > s->op_count_max)
2148             s->op_count_max = n;
2149 
2150         s->temp_count += s->nb_temps;
2151         if (s->nb_temps > s->temp_count_max)
2152             s->temp_count_max = s->nb_temps;
2153     }
2154 #endif
2155 
2156     tcg_gen_code_common(s, gen_code_buf, -1);
2157 
2158     /* flush instruction cache */
2159     flush_icache_range((unsigned long)gen_code_buf,
2160                        (unsigned long)s->code_ptr);
2161     return s->code_ptr -  gen_code_buf;
2162 }
2163 
2164 /* Return the index of the micro operation such as the pc after is <
2165    offset bytes from the start of the TB.  The contents of gen_code_buf must
2166    not be changed, though writing the same values is ok.
2167    Return -1 if not found. */
2168 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2169 {
2170     return tcg_gen_code_common(s, gen_code_buf, offset);
2171 }
2172 
2173 #ifdef CONFIG_PROFILER
2174 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2175 {
2176     TCGContext *s = &tcg_ctx;
2177     int64_t tot;
2178 
2179     tot = s->interm_time + s->code_time;
2180     cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2181                 tot, tot / 2.4e9);
2182     cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2183                 s->tb_count,
2184                 s->tb_count1 - s->tb_count,
2185                 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2186     cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n",
2187                 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2188     cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2189                 s->tb_count ?
2190                 (double)s->del_op_count / s->tb_count : 0);
2191     cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2192                 s->tb_count ?
2193                 (double)s->temp_count / s->tb_count : 0,
2194                 s->temp_count_max);
2195 
2196     cpu_fprintf(f, "cycles/op           %0.1f\n",
2197                 s->op_count ? (double)tot / s->op_count : 0);
2198     cpu_fprintf(f, "cycles/in byte      %0.1f\n",
2199                 s->code_in_len ? (double)tot / s->code_in_len : 0);
2200     cpu_fprintf(f, "cycles/out byte     %0.1f\n",
2201                 s->code_out_len ? (double)tot / s->code_out_len : 0);
2202     if (tot == 0)
2203         tot = 1;
2204     cpu_fprintf(f, "  gen_interm time   %0.1f%%\n",
2205                 (double)s->interm_time / tot * 100.0);
2206     cpu_fprintf(f, "  gen_code time     %0.1f%%\n",
2207                 (double)s->code_time / tot * 100.0);
2208     cpu_fprintf(f, "liveness/code time  %0.1f%%\n",
2209                 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2210     cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2211                 s->restore_count);
2212     cpu_fprintf(f, "  avg cycles        %0.1f\n",
2213                 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2214 
2215     dump_op_count();
2216 }
2217 #else
2218 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2219 {
2220     cpu_fprintf(f, "[TCG profiler not compiled]\n");
2221 }
2222 #endif
2223