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