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