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