xref: /openbmc/qemu/tcg/tcg.c (revision 03feae73056ba3223151c31871860e30630645ac)
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 #ifdef TCG_TARGET_I386
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 #ifdef TCG_TARGET_I386
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_iargs 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_iargs;
1207 
1208     gen_opc_ptr++; /* skip end */
1209 
1210     nb_ops = gen_opc_ptr - gen_opc_buf;
1211 
1212     s->op_dead_iargs = 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                     for(i = 0; i < nb_oargs; i++) {
1249                         arg = args[i];
1250                         dead_temps[arg] = 1;
1251                     }
1252 
1253                     if (!(call_flags & TCG_CALL_CONST)) {
1254                         /* globals are live (they may be used by the call) */
1255                         memset(dead_temps, 0, s->nb_globals);
1256                     }
1257 
1258                     /* input args are live */
1259                     dead_iargs = 0;
1260                     for(i = 0; i < nb_iargs; i++) {
1261                         arg = args[i + nb_oargs];
1262                         if (arg != TCG_CALL_DUMMY_ARG) {
1263                             if (dead_temps[arg]) {
1264                                 dead_iargs |= (1 << i);
1265                             }
1266                             dead_temps[arg] = 0;
1267                         }
1268                     }
1269                     s->op_dead_iargs[op_index] = dead_iargs;
1270                 }
1271                 args--;
1272             }
1273             break;
1274         case INDEX_op_set_label:
1275             args--;
1276             /* mark end of basic block */
1277             tcg_la_bb_end(s, dead_temps);
1278             break;
1279         case INDEX_op_debug_insn_start:
1280             args -= def->nb_args;
1281             break;
1282         case INDEX_op_nopn:
1283             nb_args = args[-1];
1284             args -= nb_args;
1285             break;
1286         case INDEX_op_discard:
1287             args--;
1288             /* mark the temporary as dead */
1289             dead_temps[args[0]] = 1;
1290             break;
1291         case INDEX_op_end:
1292             break;
1293             /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1294         default:
1295             args -= def->nb_args;
1296             nb_iargs = def->nb_iargs;
1297             nb_oargs = def->nb_oargs;
1298 
1299             /* Test if the operation can be removed because all
1300                its outputs are dead. We assume that nb_oargs == 0
1301                implies side effects */
1302             if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1303                 for(i = 0; i < nb_oargs; i++) {
1304                     arg = args[i];
1305                     if (!dead_temps[arg])
1306                         goto do_not_remove;
1307                 }
1308                 tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1309 #ifdef CONFIG_PROFILER
1310                 s->del_op_count++;
1311 #endif
1312             } else {
1313             do_not_remove:
1314 
1315                 /* output args are dead */
1316                 for(i = 0; i < nb_oargs; i++) {
1317                     arg = args[i];
1318                     dead_temps[arg] = 1;
1319                 }
1320 
1321                 /* if end of basic block, update */
1322                 if (def->flags & TCG_OPF_BB_END) {
1323                     tcg_la_bb_end(s, dead_temps);
1324                 } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1325                     /* globals are live */
1326                     memset(dead_temps, 0, s->nb_globals);
1327                 }
1328 
1329                 /* input args are live */
1330                 dead_iargs = 0;
1331                 for(i = 0; i < nb_iargs; i++) {
1332                     arg = args[i + nb_oargs];
1333                     if (dead_temps[arg]) {
1334                         dead_iargs |= (1 << i);
1335                     }
1336                     dead_temps[arg] = 0;
1337                 }
1338                 s->op_dead_iargs[op_index] = dead_iargs;
1339             }
1340             break;
1341         }
1342         op_index--;
1343     }
1344 
1345     if (args != gen_opparam_buf)
1346         tcg_abort();
1347 }
1348 #else
1349 /* dummy liveness analysis */
1350 static void tcg_liveness_analysis(TCGContext *s)
1351 {
1352     int nb_ops;
1353     nb_ops = gen_opc_ptr - gen_opc_buf;
1354 
1355     s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1356     memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
1357 }
1358 #endif
1359 
1360 #ifndef NDEBUG
1361 static void dump_regs(TCGContext *s)
1362 {
1363     TCGTemp *ts;
1364     int i;
1365     char buf[64];
1366 
1367     for(i = 0; i < s->nb_temps; i++) {
1368         ts = &s->temps[i];
1369         printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1370         switch(ts->val_type) {
1371         case TEMP_VAL_REG:
1372             printf("%s", tcg_target_reg_names[ts->reg]);
1373             break;
1374         case TEMP_VAL_MEM:
1375             printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1376             break;
1377         case TEMP_VAL_CONST:
1378             printf("$0x%" TCG_PRIlx, ts->val);
1379             break;
1380         case TEMP_VAL_DEAD:
1381             printf("D");
1382             break;
1383         default:
1384             printf("???");
1385             break;
1386         }
1387         printf("\n");
1388     }
1389 
1390     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1391         if (s->reg_to_temp[i] >= 0) {
1392             printf("%s: %s\n",
1393                    tcg_target_reg_names[i],
1394                    tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1395         }
1396     }
1397 }
1398 
1399 static void check_regs(TCGContext *s)
1400 {
1401     int reg, k;
1402     TCGTemp *ts;
1403     char buf[64];
1404 
1405     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1406         k = s->reg_to_temp[reg];
1407         if (k >= 0) {
1408             ts = &s->temps[k];
1409             if (ts->val_type != TEMP_VAL_REG ||
1410                 ts->reg != reg) {
1411                 printf("Inconsistency for register %s:\n",
1412                        tcg_target_reg_names[reg]);
1413                 goto fail;
1414             }
1415         }
1416     }
1417     for(k = 0; k < s->nb_temps; k++) {
1418         ts = &s->temps[k];
1419         if (ts->val_type == TEMP_VAL_REG &&
1420             !ts->fixed_reg &&
1421             s->reg_to_temp[ts->reg] != k) {
1422                 printf("Inconsistency for temp %s:\n",
1423                        tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1424         fail:
1425                 printf("reg state:\n");
1426                 dump_regs(s);
1427                 tcg_abort();
1428         }
1429     }
1430 }
1431 #endif
1432 
1433 static void temp_allocate_frame(TCGContext *s, int temp)
1434 {
1435     TCGTemp *ts;
1436     ts = &s->temps[temp];
1437     s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
1438     if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
1439         tcg_abort();
1440     ts->mem_offset = s->current_frame_offset;
1441     ts->mem_reg = s->frame_reg;
1442     ts->mem_allocated = 1;
1443     s->current_frame_offset += sizeof(tcg_target_long);
1444 }
1445 
1446 /* free register 'reg' by spilling the corresponding temporary if necessary */
1447 static void tcg_reg_free(TCGContext *s, int reg)
1448 {
1449     TCGTemp *ts;
1450     int temp;
1451 
1452     temp = s->reg_to_temp[reg];
1453     if (temp != -1) {
1454         ts = &s->temps[temp];
1455         assert(ts->val_type == TEMP_VAL_REG);
1456         if (!ts->mem_coherent) {
1457             if (!ts->mem_allocated)
1458                 temp_allocate_frame(s, temp);
1459             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1460         }
1461         ts->val_type = TEMP_VAL_MEM;
1462         s->reg_to_temp[reg] = -1;
1463     }
1464 }
1465 
1466 /* Allocate a register belonging to reg1 & ~reg2 */
1467 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1468 {
1469     int i, reg;
1470     TCGRegSet reg_ct;
1471 
1472     tcg_regset_andnot(reg_ct, reg1, reg2);
1473 
1474     /* first try free registers */
1475     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1476         reg = tcg_target_reg_alloc_order[i];
1477         if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1478             return reg;
1479     }
1480 
1481     /* XXX: do better spill choice */
1482     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1483         reg = tcg_target_reg_alloc_order[i];
1484         if (tcg_regset_test_reg(reg_ct, reg)) {
1485             tcg_reg_free(s, reg);
1486             return reg;
1487         }
1488     }
1489 
1490     tcg_abort();
1491 }
1492 
1493 /* save a temporary to memory. 'allocated_regs' is used in case a
1494    temporary registers needs to be allocated to store a constant. */
1495 static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1496 {
1497     TCGTemp *ts;
1498     int reg;
1499 
1500     ts = &s->temps[temp];
1501     if (!ts->fixed_reg) {
1502         switch(ts->val_type) {
1503         case TEMP_VAL_REG:
1504             tcg_reg_free(s, ts->reg);
1505             break;
1506         case TEMP_VAL_DEAD:
1507             ts->val_type = TEMP_VAL_MEM;
1508             break;
1509         case TEMP_VAL_CONST:
1510             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1511                                 allocated_regs);
1512             if (!ts->mem_allocated)
1513                 temp_allocate_frame(s, temp);
1514             tcg_out_movi(s, ts->type, reg, ts->val);
1515             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1516             ts->val_type = TEMP_VAL_MEM;
1517             break;
1518         case TEMP_VAL_MEM:
1519             break;
1520         default:
1521             tcg_abort();
1522         }
1523     }
1524 }
1525 
1526 /* save globals to their cannonical location and assume they can be
1527    modified be the following code. 'allocated_regs' is used in case a
1528    temporary registers needs to be allocated to store a constant. */
1529 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1530 {
1531     int i;
1532 
1533     for(i = 0; i < s->nb_globals; i++) {
1534         temp_save(s, i, allocated_regs);
1535     }
1536 }
1537 
1538 /* at the end of a basic block, we assume all temporaries are dead and
1539    all globals are stored at their canonical location. */
1540 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1541 {
1542     TCGTemp *ts;
1543     int i;
1544 
1545     for(i = s->nb_globals; i < s->nb_temps; i++) {
1546         ts = &s->temps[i];
1547         if (ts->temp_local) {
1548             temp_save(s, i, allocated_regs);
1549         } else {
1550             if (ts->val_type == TEMP_VAL_REG) {
1551                 s->reg_to_temp[ts->reg] = -1;
1552             }
1553             ts->val_type = TEMP_VAL_DEAD;
1554         }
1555     }
1556 
1557     save_globals(s, allocated_regs);
1558 }
1559 
1560 #define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
1561 
1562 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1563 {
1564     TCGTemp *ots;
1565     tcg_target_ulong val;
1566 
1567     ots = &s->temps[args[0]];
1568     val = args[1];
1569 
1570     if (ots->fixed_reg) {
1571         /* for fixed registers, we do not do any constant
1572            propagation */
1573         tcg_out_movi(s, ots->type, ots->reg, val);
1574     } else {
1575         /* The movi is not explicitly generated here */
1576         if (ots->val_type == TEMP_VAL_REG)
1577             s->reg_to_temp[ots->reg] = -1;
1578         ots->val_type = TEMP_VAL_CONST;
1579         ots->val = val;
1580     }
1581 }
1582 
1583 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1584                               const TCGArg *args,
1585                               unsigned int dead_iargs)
1586 {
1587     TCGTemp *ts, *ots;
1588     int reg;
1589     const TCGArgConstraint *arg_ct;
1590 
1591     ots = &s->temps[args[0]];
1592     ts = &s->temps[args[1]];
1593     arg_ct = &def->args_ct[0];
1594 
1595     /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
1596     if (ts->val_type == TEMP_VAL_REG) {
1597         if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
1598             /* the mov can be suppressed */
1599             if (ots->val_type == TEMP_VAL_REG)
1600                 s->reg_to_temp[ots->reg] = -1;
1601             reg = ts->reg;
1602             s->reg_to_temp[reg] = -1;
1603             ts->val_type = TEMP_VAL_DEAD;
1604         } else {
1605             if (ots->val_type == TEMP_VAL_REG) {
1606                 reg = ots->reg;
1607             } else {
1608                 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1609             }
1610             if (ts->reg != reg) {
1611                 tcg_out_mov(s, ots->type, reg, ts->reg);
1612             }
1613         }
1614     } else if (ts->val_type == TEMP_VAL_MEM) {
1615         if (ots->val_type == TEMP_VAL_REG) {
1616             reg = ots->reg;
1617         } else {
1618             reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1619         }
1620         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1621     } else if (ts->val_type == TEMP_VAL_CONST) {
1622         if (ots->fixed_reg) {
1623             reg = ots->reg;
1624             tcg_out_movi(s, ots->type, reg, ts->val);
1625         } else {
1626             /* propagate constant */
1627             if (ots->val_type == TEMP_VAL_REG)
1628                 s->reg_to_temp[ots->reg] = -1;
1629             ots->val_type = TEMP_VAL_CONST;
1630             ots->val = ts->val;
1631             return;
1632         }
1633     } else {
1634         tcg_abort();
1635     }
1636     s->reg_to_temp[reg] = args[0];
1637     ots->reg = reg;
1638     ots->val_type = TEMP_VAL_REG;
1639     ots->mem_coherent = 0;
1640 }
1641 
1642 static void tcg_reg_alloc_op(TCGContext *s,
1643                              const TCGOpDef *def, TCGOpcode opc,
1644                              const TCGArg *args,
1645                              unsigned int dead_iargs)
1646 {
1647     TCGRegSet allocated_regs;
1648     int i, k, nb_iargs, nb_oargs, reg;
1649     TCGArg arg;
1650     const TCGArgConstraint *arg_ct;
1651     TCGTemp *ts;
1652     TCGArg new_args[TCG_MAX_OP_ARGS];
1653     int const_args[TCG_MAX_OP_ARGS];
1654 
1655     nb_oargs = def->nb_oargs;
1656     nb_iargs = def->nb_iargs;
1657 
1658     /* copy constants */
1659     memcpy(new_args + nb_oargs + nb_iargs,
1660            args + nb_oargs + nb_iargs,
1661            sizeof(TCGArg) * def->nb_cargs);
1662 
1663     /* satisfy input constraints */
1664     tcg_regset_set(allocated_regs, s->reserved_regs);
1665     for(k = 0; k < nb_iargs; k++) {
1666         i = def->sorted_args[nb_oargs + k];
1667         arg = args[i];
1668         arg_ct = &def->args_ct[i];
1669         ts = &s->temps[arg];
1670         if (ts->val_type == TEMP_VAL_MEM) {
1671             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1672             tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1673             ts->val_type = TEMP_VAL_REG;
1674             ts->reg = reg;
1675             ts->mem_coherent = 1;
1676             s->reg_to_temp[reg] = arg;
1677         } else if (ts->val_type == TEMP_VAL_CONST) {
1678             if (tcg_target_const_match(ts->val, arg_ct)) {
1679                 /* constant is OK for instruction */
1680                 const_args[i] = 1;
1681                 new_args[i] = ts->val;
1682                 goto iarg_end;
1683             } else {
1684                 /* need to move to a register */
1685                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1686                 tcg_out_movi(s, ts->type, reg, ts->val);
1687                 ts->val_type = TEMP_VAL_REG;
1688                 ts->reg = reg;
1689                 ts->mem_coherent = 0;
1690                 s->reg_to_temp[reg] = arg;
1691             }
1692         }
1693         assert(ts->val_type == TEMP_VAL_REG);
1694         if (arg_ct->ct & TCG_CT_IALIAS) {
1695             if (ts->fixed_reg) {
1696                 /* if fixed register, we must allocate a new register
1697                    if the alias is not the same register */
1698                 if (arg != args[arg_ct->alias_index])
1699                     goto allocate_in_reg;
1700             } else {
1701                 /* if the input is aliased to an output and if it is
1702                    not dead after the instruction, we must allocate
1703                    a new register and move it */
1704                 if (!IS_DEAD_IARG(i - nb_oargs))
1705                     goto allocate_in_reg;
1706             }
1707         }
1708         reg = ts->reg;
1709         if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1710             /* nothing to do : the constraint is satisfied */
1711         } else {
1712         allocate_in_reg:
1713             /* allocate a new register matching the constraint
1714                and move the temporary register into it */
1715             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1716             tcg_out_mov(s, ts->type, reg, ts->reg);
1717         }
1718         new_args[i] = reg;
1719         const_args[i] = 0;
1720         tcg_regset_set_reg(allocated_regs, reg);
1721     iarg_end: ;
1722     }
1723 
1724     if (def->flags & TCG_OPF_BB_END) {
1725         tcg_reg_alloc_bb_end(s, allocated_regs);
1726     } else {
1727         /* mark dead temporaries and free the associated registers */
1728         for(i = 0; i < nb_iargs; i++) {
1729             arg = args[nb_oargs + i];
1730             if (IS_DEAD_IARG(i)) {
1731                 ts = &s->temps[arg];
1732                 if (!ts->fixed_reg) {
1733                     if (ts->val_type == TEMP_VAL_REG)
1734                         s->reg_to_temp[ts->reg] = -1;
1735                     ts->val_type = TEMP_VAL_DEAD;
1736                 }
1737             }
1738         }
1739 
1740         if (def->flags & TCG_OPF_CALL_CLOBBER) {
1741             /* XXX: permit generic clobber register list ? */
1742             for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1743                 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1744                     tcg_reg_free(s, reg);
1745                 }
1746             }
1747             /* XXX: for load/store we could do that only for the slow path
1748                (i.e. when a memory callback is called) */
1749 
1750             /* store globals and free associated registers (we assume the insn
1751                can modify any global. */
1752             save_globals(s, allocated_regs);
1753         }
1754 
1755         /* satisfy the output constraints */
1756         tcg_regset_set(allocated_regs, s->reserved_regs);
1757         for(k = 0; k < nb_oargs; k++) {
1758             i = def->sorted_args[k];
1759             arg = args[i];
1760             arg_ct = &def->args_ct[i];
1761             ts = &s->temps[arg];
1762             if (arg_ct->ct & TCG_CT_ALIAS) {
1763                 reg = new_args[arg_ct->alias_index];
1764             } else {
1765                 /* if fixed register, we try to use it */
1766                 reg = ts->reg;
1767                 if (ts->fixed_reg &&
1768                     tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1769                     goto oarg_end;
1770                 }
1771                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1772             }
1773             tcg_regset_set_reg(allocated_regs, reg);
1774             /* if a fixed register is used, then a move will be done afterwards */
1775             if (!ts->fixed_reg) {
1776                 if (ts->val_type == TEMP_VAL_REG)
1777                     s->reg_to_temp[ts->reg] = -1;
1778                 ts->val_type = TEMP_VAL_REG;
1779                 ts->reg = reg;
1780                 /* temp value is modified, so the value kept in memory is
1781                    potentially not the same */
1782                 ts->mem_coherent = 0;
1783                 s->reg_to_temp[reg] = arg;
1784             }
1785         oarg_end:
1786             new_args[i] = reg;
1787         }
1788     }
1789 
1790     /* emit instruction */
1791     tcg_out_op(s, opc, new_args, const_args);
1792 
1793     /* move the outputs in the correct register if needed */
1794     for(i = 0; i < nb_oargs; i++) {
1795         ts = &s->temps[args[i]];
1796         reg = new_args[i];
1797         if (ts->fixed_reg && ts->reg != reg) {
1798             tcg_out_mov(s, ts->type, ts->reg, reg);
1799         }
1800     }
1801 }
1802 
1803 #ifdef TCG_TARGET_STACK_GROWSUP
1804 #define STACK_DIR(x) (-(x))
1805 #else
1806 #define STACK_DIR(x) (x)
1807 #endif
1808 
1809 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1810                               TCGOpcode opc, const TCGArg *args,
1811                               unsigned int dead_iargs)
1812 {
1813     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1814     TCGArg arg, func_arg;
1815     TCGTemp *ts;
1816     tcg_target_long stack_offset, call_stack_size, func_addr;
1817     int const_func_arg, allocate_args;
1818     TCGRegSet allocated_regs;
1819     const TCGArgConstraint *arg_ct;
1820 
1821     arg = *args++;
1822 
1823     nb_oargs = arg >> 16;
1824     nb_iargs = arg & 0xffff;
1825     nb_params = nb_iargs - 1;
1826 
1827     flags = args[nb_oargs + nb_iargs];
1828 
1829     nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1830     if (nb_regs > nb_params)
1831         nb_regs = nb_params;
1832 
1833     /* assign stack slots first */
1834     /* XXX: preallocate call stack */
1835     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1836     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
1837         ~(TCG_TARGET_STACK_ALIGN - 1);
1838     allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1839     if (allocate_args) {
1840         tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
1841     }
1842 
1843     stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1844     for(i = nb_regs; i < nb_params; i++) {
1845         arg = args[nb_oargs + i];
1846 #ifdef TCG_TARGET_STACK_GROWSUP
1847         stack_offset -= sizeof(tcg_target_long);
1848 #endif
1849         if (arg != TCG_CALL_DUMMY_ARG) {
1850             ts = &s->temps[arg];
1851             if (ts->val_type == TEMP_VAL_REG) {
1852                 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1853             } else if (ts->val_type == TEMP_VAL_MEM) {
1854                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1855                                     s->reserved_regs);
1856                 /* XXX: not correct if reading values from the stack */
1857                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1858                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1859             } else if (ts->val_type == TEMP_VAL_CONST) {
1860                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1861                                     s->reserved_regs);
1862                 /* XXX: sign extend may be needed on some targets */
1863                 tcg_out_movi(s, ts->type, reg, ts->val);
1864                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1865             } else {
1866                 tcg_abort();
1867             }
1868         }
1869 #ifndef TCG_TARGET_STACK_GROWSUP
1870         stack_offset += sizeof(tcg_target_long);
1871 #endif
1872     }
1873 
1874     /* assign input registers */
1875     tcg_regset_set(allocated_regs, s->reserved_regs);
1876     for(i = 0; i < nb_regs; i++) {
1877         arg = args[nb_oargs + i];
1878         if (arg != TCG_CALL_DUMMY_ARG) {
1879             ts = &s->temps[arg];
1880             reg = tcg_target_call_iarg_regs[i];
1881             tcg_reg_free(s, reg);
1882             if (ts->val_type == TEMP_VAL_REG) {
1883                 if (ts->reg != reg) {
1884                     tcg_out_mov(s, ts->type, reg, ts->reg);
1885                 }
1886             } else if (ts->val_type == TEMP_VAL_MEM) {
1887                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1888             } else if (ts->val_type == TEMP_VAL_CONST) {
1889                 /* XXX: sign extend ? */
1890                 tcg_out_movi(s, ts->type, reg, ts->val);
1891             } else {
1892                 tcg_abort();
1893             }
1894             tcg_regset_set_reg(allocated_regs, reg);
1895         }
1896     }
1897 
1898     /* assign function address */
1899     func_arg = args[nb_oargs + nb_iargs - 1];
1900     arg_ct = &def->args_ct[0];
1901     ts = &s->temps[func_arg];
1902     func_addr = ts->val;
1903     const_func_arg = 0;
1904     if (ts->val_type == TEMP_VAL_MEM) {
1905         reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1906         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1907         func_arg = reg;
1908         tcg_regset_set_reg(allocated_regs, reg);
1909     } else if (ts->val_type == TEMP_VAL_REG) {
1910         reg = ts->reg;
1911         if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1912             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1913             tcg_out_mov(s, ts->type, reg, ts->reg);
1914         }
1915         func_arg = reg;
1916         tcg_regset_set_reg(allocated_regs, reg);
1917     } else if (ts->val_type == TEMP_VAL_CONST) {
1918         if (tcg_target_const_match(func_addr, arg_ct)) {
1919             const_func_arg = 1;
1920             func_arg = func_addr;
1921         } else {
1922             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1923             tcg_out_movi(s, ts->type, reg, func_addr);
1924             func_arg = reg;
1925             tcg_regset_set_reg(allocated_regs, reg);
1926         }
1927     } else {
1928         tcg_abort();
1929     }
1930 
1931 
1932     /* mark dead temporaries and free the associated registers */
1933     for(i = 0; i < nb_iargs; i++) {
1934         arg = args[nb_oargs + i];
1935         if (IS_DEAD_IARG(i)) {
1936             ts = &s->temps[arg];
1937             if (!ts->fixed_reg) {
1938                 if (ts->val_type == TEMP_VAL_REG)
1939                     s->reg_to_temp[ts->reg] = -1;
1940                 ts->val_type = TEMP_VAL_DEAD;
1941             }
1942         }
1943     }
1944 
1945     /* clobber call registers */
1946     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1947         if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1948             tcg_reg_free(s, reg);
1949         }
1950     }
1951 
1952     /* store globals and free associated registers (we assume the call
1953        can modify any global. */
1954     if (!(flags & TCG_CALL_CONST)) {
1955         save_globals(s, allocated_regs);
1956     }
1957 
1958     tcg_out_op(s, opc, &func_arg, &const_func_arg);
1959 
1960     if (allocate_args) {
1961         tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
1962     }
1963 
1964     /* assign output registers and emit moves if needed */
1965     for(i = 0; i < nb_oargs; i++) {
1966         arg = args[i];
1967         ts = &s->temps[arg];
1968         reg = tcg_target_call_oarg_regs[i];
1969         assert(s->reg_to_temp[reg] == -1);
1970         if (ts->fixed_reg) {
1971             if (ts->reg != reg) {
1972                 tcg_out_mov(s, ts->type, ts->reg, reg);
1973             }
1974         } else {
1975             if (ts->val_type == TEMP_VAL_REG)
1976                 s->reg_to_temp[ts->reg] = -1;
1977             ts->val_type = TEMP_VAL_REG;
1978             ts->reg = reg;
1979             ts->mem_coherent = 0;
1980             s->reg_to_temp[reg] = arg;
1981         }
1982     }
1983 
1984     return nb_iargs + nb_oargs + def->nb_cargs + 1;
1985 }
1986 
1987 #ifdef CONFIG_PROFILER
1988 
1989 static int64_t tcg_table_op_count[NB_OPS];
1990 
1991 static void dump_op_count(void)
1992 {
1993     int i;
1994     FILE *f;
1995     f = fopen("/tmp/op.log", "w");
1996     for(i = INDEX_op_end; i < NB_OPS; i++) {
1997         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
1998     }
1999     fclose(f);
2000 }
2001 #endif
2002 
2003 
2004 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2005                                       long search_pc)
2006 {
2007     TCGOpcode opc;
2008     int op_index;
2009     const TCGOpDef *def;
2010     unsigned int dead_iargs;
2011     const TCGArg *args;
2012 
2013 #ifdef DEBUG_DISAS
2014     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2015         qemu_log("OP:\n");
2016         tcg_dump_ops(s, logfile);
2017         qemu_log("\n");
2018     }
2019 #endif
2020 
2021 #ifdef CONFIG_PROFILER
2022     s->la_time -= profile_getclock();
2023 #endif
2024     tcg_liveness_analysis(s);
2025 #ifdef CONFIG_PROFILER
2026     s->la_time += profile_getclock();
2027 #endif
2028 
2029 #ifdef DEBUG_DISAS
2030     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2031         qemu_log("OP after liveness analysis:\n");
2032         tcg_dump_ops(s, logfile);
2033         qemu_log("\n");
2034     }
2035 #endif
2036 
2037     tcg_reg_alloc_start(s);
2038 
2039     s->code_buf = gen_code_buf;
2040     s->code_ptr = gen_code_buf;
2041 
2042     args = gen_opparam_buf;
2043     op_index = 0;
2044 
2045     for(;;) {
2046         opc = gen_opc_buf[op_index];
2047 #ifdef CONFIG_PROFILER
2048         tcg_table_op_count[opc]++;
2049 #endif
2050         def = &tcg_op_defs[opc];
2051 #if 0
2052         printf("%s: %d %d %d\n", def->name,
2053                def->nb_oargs, def->nb_iargs, def->nb_cargs);
2054         //        dump_regs(s);
2055 #endif
2056         switch(opc) {
2057         case INDEX_op_mov_i32:
2058 #if TCG_TARGET_REG_BITS == 64
2059         case INDEX_op_mov_i64:
2060 #endif
2061             dead_iargs = s->op_dead_iargs[op_index];
2062             tcg_reg_alloc_mov(s, def, args, dead_iargs);
2063             break;
2064         case INDEX_op_movi_i32:
2065 #if TCG_TARGET_REG_BITS == 64
2066         case INDEX_op_movi_i64:
2067 #endif
2068             tcg_reg_alloc_movi(s, args);
2069             break;
2070         case INDEX_op_debug_insn_start:
2071             /* debug instruction */
2072             break;
2073         case INDEX_op_nop:
2074         case INDEX_op_nop1:
2075         case INDEX_op_nop2:
2076         case INDEX_op_nop3:
2077             break;
2078         case INDEX_op_nopn:
2079             args += args[0];
2080             goto next;
2081         case INDEX_op_discard:
2082             {
2083                 TCGTemp *ts;
2084                 ts = &s->temps[args[0]];
2085                 /* mark the temporary as dead */
2086                 if (!ts->fixed_reg) {
2087                     if (ts->val_type == TEMP_VAL_REG)
2088                         s->reg_to_temp[ts->reg] = -1;
2089                     ts->val_type = TEMP_VAL_DEAD;
2090                 }
2091             }
2092             break;
2093         case INDEX_op_set_label:
2094             tcg_reg_alloc_bb_end(s, s->reserved_regs);
2095             tcg_out_label(s, args[0], (long)s->code_ptr);
2096             break;
2097         case INDEX_op_call:
2098             dead_iargs = s->op_dead_iargs[op_index];
2099             args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
2100             goto next;
2101         case INDEX_op_end:
2102             goto the_end;
2103         default:
2104             /* Note: in order to speed up the code, it would be much
2105                faster to have specialized register allocator functions for
2106                some common argument patterns */
2107             dead_iargs = s->op_dead_iargs[op_index];
2108             tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
2109             break;
2110         }
2111         args += def->nb_args;
2112     next:
2113         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2114             return op_index;
2115         }
2116         op_index++;
2117 #ifndef NDEBUG
2118         check_regs(s);
2119 #endif
2120     }
2121  the_end:
2122     return -1;
2123 }
2124 
2125 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2126 {
2127 #ifdef CONFIG_PROFILER
2128     {
2129         int n;
2130         n = (gen_opc_ptr - gen_opc_buf);
2131         s->op_count += n;
2132         if (n > s->op_count_max)
2133             s->op_count_max = n;
2134 
2135         s->temp_count += s->nb_temps;
2136         if (s->nb_temps > s->temp_count_max)
2137             s->temp_count_max = s->nb_temps;
2138     }
2139 #endif
2140 
2141     tcg_gen_code_common(s, gen_code_buf, -1);
2142 
2143     /* flush instruction cache */
2144     flush_icache_range((unsigned long)gen_code_buf,
2145                        (unsigned long)s->code_ptr);
2146     return s->code_ptr -  gen_code_buf;
2147 }
2148 
2149 /* Return the index of the micro operation such as the pc after is <
2150    offset bytes from the start of the TB.  The contents of gen_code_buf must
2151    not be changed, though writing the same values is ok.
2152    Return -1 if not found. */
2153 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2154 {
2155     return tcg_gen_code_common(s, gen_code_buf, offset);
2156 }
2157 
2158 #ifdef CONFIG_PROFILER
2159 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2160 {
2161     TCGContext *s = &tcg_ctx;
2162     int64_t tot;
2163 
2164     tot = s->interm_time + s->code_time;
2165     cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2166                 tot, tot / 2.4e9);
2167     cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2168                 s->tb_count,
2169                 s->tb_count1 - s->tb_count,
2170                 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2171     cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n",
2172                 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2173     cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2174                 s->tb_count ?
2175                 (double)s->del_op_count / s->tb_count : 0);
2176     cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2177                 s->tb_count ?
2178                 (double)s->temp_count / s->tb_count : 0,
2179                 s->temp_count_max);
2180 
2181     cpu_fprintf(f, "cycles/op           %0.1f\n",
2182                 s->op_count ? (double)tot / s->op_count : 0);
2183     cpu_fprintf(f, "cycles/in byte      %0.1f\n",
2184                 s->code_in_len ? (double)tot / s->code_in_len : 0);
2185     cpu_fprintf(f, "cycles/out byte     %0.1f\n",
2186                 s->code_out_len ? (double)tot / s->code_out_len : 0);
2187     if (tot == 0)
2188         tot = 1;
2189     cpu_fprintf(f, "  gen_interm time   %0.1f%%\n",
2190                 (double)s->interm_time / tot * 100.0);
2191     cpu_fprintf(f, "  gen_code time     %0.1f%%\n",
2192                 (double)s->code_time / tot * 100.0);
2193     cpu_fprintf(f, "liveness/code time  %0.1f%%\n",
2194                 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2195     cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2196                 s->restore_count);
2197     cpu_fprintf(f, "  avg cycles        %0.1f\n",
2198                 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2199 
2200     dump_op_count();
2201 }
2202 #else
2203 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2204 {
2205     cpu_fprintf(f, "[TCG profiler not compiled]\n");
2206 }
2207 #endif
2208