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