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