Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 45aba097

History | View | Annotate | Download (82.6 kB)

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
#define USE_TCG_OPTIMIZATIONS
28

    
29
#include "config.h"
30

    
31
/* Define to jump the ELF file used to communicate with GDB.  */
32
#undef DEBUG_JIT
33

    
34
#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
35
/* define it to suppress various consistency checks (faster) */
36
#define NDEBUG
37
#endif
38

    
39
#include "qemu-common.h"
40
#include "qemu/cache-utils.h"
41
#include "qemu/host-utils.h"
42
#include "qemu/timer.h"
43

    
44
/* Note: the long term plan is to reduce the dependancies on the QEMU
45
   CPU definitions. Currently they are used for qemu_ld/st
46
   instructions */
47
#define NO_CPU_IO_DEFS
48
#include "cpu.h"
49

    
50
#include "tcg-op.h"
51

    
52
#if TCG_TARGET_REG_BITS == 64
53
# define ELF_CLASS  ELFCLASS64
54
#else
55
# define ELF_CLASS  ELFCLASS32
56
#endif
57
#ifdef HOST_WORDS_BIGENDIAN
58
# define ELF_DATA   ELFDATA2MSB
59
#else
60
# define ELF_DATA   ELFDATA2LSB
61
#endif
62

    
63
#include "elf.h"
64

    
65
/* Forward declarations for functions declared in tcg-target.c and used here. */
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 void tcg_register_jit_int(void *buf, size_t size,
72
                                 void *debug_frame, size_t debug_frame_size)
73
    __attribute__((unused));
74

    
75
/* Forward declarations for functions declared and used in tcg-target.c. */
76
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
77
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
78
                       tcg_target_long arg2);
79
static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
80
static void tcg_out_movi(TCGContext *s, TCGType type,
81
                         TCGReg ret, tcg_target_long arg);
82
static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
83
                       const int *const_args);
84
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
85
                       tcg_target_long arg2);
86
static int tcg_target_const_match(tcg_target_long val,
87
                                  const TCGArgConstraint *arg_ct);
88

    
89
TCGOpDef tcg_op_defs[] = {
90
#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
91
#include "tcg-opc.h"
92
#undef DEF
93
};
94
const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
95

    
96
static TCGRegSet tcg_target_available_regs[2];
97
static TCGRegSet tcg_target_call_clobber_regs;
98

    
99
static inline void tcg_out8(TCGContext *s, uint8_t v)
100
{
101
    *s->code_ptr++ = v;
102
}
103

    
104
static inline void tcg_out16(TCGContext *s, uint16_t v)
105
{
106
    *(uint16_t *)s->code_ptr = v;
107
    s->code_ptr += 2;
108
}
109

    
110
static inline void tcg_out32(TCGContext *s, uint32_t v)
111
{
112
    *(uint32_t *)s->code_ptr = v;
113
    s->code_ptr += 4;
114
}
115

    
116
/* label relocation processing */
117

    
118
static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
119
                          int label_index, long addend)
120
{
121
    TCGLabel *l;
122
    TCGRelocation *r;
123

    
124
    l = &s->labels[label_index];
125
    if (l->has_value) {
126
        /* FIXME: This may break relocations on RISC targets that
127
           modify instruction fields in place.  The caller may not have 
128
           written the initial value.  */
129
        patch_reloc(code_ptr, type, l->u.value, addend);
130
    } else {
131
        /* add a new relocation entry */
132
        r = tcg_malloc(sizeof(TCGRelocation));
133
        r->type = type;
134
        r->ptr = code_ptr;
135
        r->addend = addend;
136
        r->next = l->u.first_reloc;
137
        l->u.first_reloc = r;
138
    }
139
}
140

    
141
static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
142
{
143
    TCGLabel *l;
144
    TCGRelocation *r;
145
    tcg_target_long value = (tcg_target_long)ptr;
146

    
147
    l = &s->labels[label_index];
148
    if (l->has_value)
149
        tcg_abort();
150
    r = l->u.first_reloc;
151
    while (r != NULL) {
152
        patch_reloc(r->ptr, r->type, value, r->addend);
153
        r = r->next;
154
    }
155
    l->has_value = 1;
156
    l->u.value = value;
157
}
158

    
159
int gen_new_label(void)
160
{
161
    TCGContext *s = &tcg_ctx;
162
    int idx;
163
    TCGLabel *l;
164

    
165
    if (s->nb_labels >= TCG_MAX_LABELS)
166
        tcg_abort();
167
    idx = s->nb_labels++;
168
    l = &s->labels[idx];
169
    l->has_value = 0;
170
    l->u.first_reloc = NULL;
171
    return idx;
172
}
173

    
174
#include "tcg-target.c"
175

    
176
/* pool based memory allocation */
177
void *tcg_malloc_internal(TCGContext *s, int size)
178
{
179
    TCGPool *p;
180
    int pool_size;
181
    
182
    if (size > TCG_POOL_CHUNK_SIZE) {
183
        /* big malloc: insert a new pool (XXX: could optimize) */
184
        p = g_malloc(sizeof(TCGPool) + size);
185
        p->size = size;
186
        p->next = s->pool_first_large;
187
        s->pool_first_large = p;
188
        return p->data;
189
    } else {
190
        p = s->pool_current;
191
        if (!p) {
192
            p = s->pool_first;
193
            if (!p)
194
                goto new_pool;
195
        } else {
196
            if (!p->next) {
197
            new_pool:
198
                pool_size = TCG_POOL_CHUNK_SIZE;
199
                p = g_malloc(sizeof(TCGPool) + pool_size);
200
                p->size = pool_size;
201
                p->next = NULL;
202
                if (s->pool_current) 
203
                    s->pool_current->next = p;
204
                else
205
                    s->pool_first = p;
206
            } else {
207
                p = p->next;
208
            }
209
        }
210
    }
211
    s->pool_current = p;
212
    s->pool_cur = p->data + size;
213
    s->pool_end = p->data + p->size;
214
    return p->data;
215
}
216

    
217
void tcg_pool_reset(TCGContext *s)
218
{
219
    TCGPool *p, *t;
220
    for (p = s->pool_first_large; p; p = t) {
221
        t = p->next;
222
        g_free(p);
223
    }
224
    s->pool_first_large = NULL;
225
    s->pool_cur = s->pool_end = NULL;
226
    s->pool_current = NULL;
227
}
228

    
229
void tcg_context_init(TCGContext *s)
230
{
231
    int op, total_args, n;
232
    TCGOpDef *def;
233
    TCGArgConstraint *args_ct;
234
    int *sorted_args;
235

    
236
    memset(s, 0, sizeof(*s));
237
    s->nb_globals = 0;
238
    
239
    /* Count total number of arguments and allocate the corresponding
240
       space */
241
    total_args = 0;
242
    for(op = 0; op < NB_OPS; op++) {
243
        def = &tcg_op_defs[op];
244
        n = def->nb_iargs + def->nb_oargs;
245
        total_args += n;
246
    }
247

    
248
    args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
249
    sorted_args = g_malloc(sizeof(int) * total_args);
250

    
251
    for(op = 0; op < NB_OPS; op++) {
252
        def = &tcg_op_defs[op];
253
        def->args_ct = args_ct;
254
        def->sorted_args = sorted_args;
255
        n = def->nb_iargs + def->nb_oargs;
256
        sorted_args += n;
257
        args_ct += n;
258
    }
259
    
260
    tcg_target_init(s);
261
}
262

    
263
void tcg_prologue_init(TCGContext *s)
264
{
265
    /* init global prologue and epilogue */
266
    s->code_buf = s->code_gen_prologue;
267
    s->code_ptr = s->code_buf;
268
    tcg_target_qemu_prologue(s);
269
    flush_icache_range((tcg_target_ulong)s->code_buf,
270
                       (tcg_target_ulong)s->code_ptr);
271

    
272
#ifdef DEBUG_DISAS
273
    if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
274
        size_t size = s->code_ptr - s->code_buf;
275
        qemu_log("PROLOGUE: [size=%zu]\n", size);
276
        log_disas(s->code_buf, size);
277
        qemu_log("\n");
278
        qemu_log_flush();
279
    }
280
#endif
281
}
282

    
283
void tcg_set_frame(TCGContext *s, int reg,
284
                   tcg_target_long start, tcg_target_long size)
285
{
286
    s->frame_start = start;
287
    s->frame_end = start + size;
288
    s->frame_reg = reg;
289
}
290

    
291
void tcg_func_start(TCGContext *s)
292
{
293
    int i;
294
    tcg_pool_reset(s);
295
    s->nb_temps = s->nb_globals;
296
    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
297
        s->first_free_temp[i] = -1;
298
    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
299
    s->nb_labels = 0;
300
    s->current_frame_offset = s->frame_start;
301

    
302
#ifdef CONFIG_DEBUG_TCG
303
    s->goto_tb_issue_mask = 0;
304
#endif
305

    
306
    s->gen_opc_ptr = s->gen_opc_buf;
307
    s->gen_opparam_ptr = s->gen_opparam_buf;
308

    
309
#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
310
    /* Initialize qemu_ld/st labels to assist code generation at the end of TB
311
       for TLB miss cases at the end of TB */
312
    s->qemu_ldst_labels = tcg_malloc(sizeof(TCGLabelQemuLdst) *
313
                                     TCG_MAX_QEMU_LDST);
314
    s->nb_qemu_ldst_labels = 0;
315
#endif
316
}
317

    
318
static inline void tcg_temp_alloc(TCGContext *s, int n)
319
{
320
    if (n > TCG_MAX_TEMPS)
321
        tcg_abort();
322
}
323

    
324
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
325
                                              const char *name)
326
{
327
    TCGContext *s = &tcg_ctx;
328
    TCGTemp *ts;
329
    int idx;
330

    
331
#if TCG_TARGET_REG_BITS == 32
332
    if (type != TCG_TYPE_I32)
333
        tcg_abort();
334
#endif
335
    if (tcg_regset_test_reg(s->reserved_regs, reg))
336
        tcg_abort();
337
    idx = s->nb_globals;
338
    tcg_temp_alloc(s, s->nb_globals + 1);
339
    ts = &s->temps[s->nb_globals];
340
    ts->base_type = type;
341
    ts->type = type;
342
    ts->fixed_reg = 1;
343
    ts->reg = reg;
344
    ts->name = name;
345
    s->nb_globals++;
346
    tcg_regset_set_reg(s->reserved_regs, reg);
347
    return idx;
348
}
349

    
350
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
351
{
352
    int idx;
353

    
354
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
355
    return MAKE_TCGV_I32(idx);
356
}
357

    
358
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
359
{
360
    int idx;
361

    
362
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
363
    return MAKE_TCGV_I64(idx);
364
}
365

    
366
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
367
                                              tcg_target_long offset,
368
                                              const char *name)
369
{
370
    TCGContext *s = &tcg_ctx;
371
    TCGTemp *ts;
372
    int idx;
373

    
374
    idx = s->nb_globals;
375
#if TCG_TARGET_REG_BITS == 32
376
    if (type == TCG_TYPE_I64) {
377
        char buf[64];
378
        tcg_temp_alloc(s, s->nb_globals + 2);
379
        ts = &s->temps[s->nb_globals];
380
        ts->base_type = type;
381
        ts->type = TCG_TYPE_I32;
382
        ts->fixed_reg = 0;
383
        ts->mem_allocated = 1;
384
        ts->mem_reg = reg;
385
#ifdef TCG_TARGET_WORDS_BIGENDIAN
386
        ts->mem_offset = offset + 4;
387
#else
388
        ts->mem_offset = offset;
389
#endif
390
        pstrcpy(buf, sizeof(buf), name);
391
        pstrcat(buf, sizeof(buf), "_0");
392
        ts->name = strdup(buf);
393
        ts++;
394

    
395
        ts->base_type = type;
396
        ts->type = TCG_TYPE_I32;
397
        ts->fixed_reg = 0;
398
        ts->mem_allocated = 1;
399
        ts->mem_reg = reg;
400
#ifdef TCG_TARGET_WORDS_BIGENDIAN
401
        ts->mem_offset = offset;
402
#else
403
        ts->mem_offset = offset + 4;
404
#endif
405
        pstrcpy(buf, sizeof(buf), name);
406
        pstrcat(buf, sizeof(buf), "_1");
407
        ts->name = strdup(buf);
408

    
409
        s->nb_globals += 2;
410
    } else
411
#endif
412
    {
413
        tcg_temp_alloc(s, s->nb_globals + 1);
414
        ts = &s->temps[s->nb_globals];
415
        ts->base_type = type;
416
        ts->type = type;
417
        ts->fixed_reg = 0;
418
        ts->mem_allocated = 1;
419
        ts->mem_reg = reg;
420
        ts->mem_offset = offset;
421
        ts->name = name;
422
        s->nb_globals++;
423
    }
424
    return idx;
425
}
426

    
427
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
428
                                const char *name)
429
{
430
    int idx;
431

    
432
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
433
    return MAKE_TCGV_I32(idx);
434
}
435

    
436
TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
437
                                const char *name)
438
{
439
    int idx;
440

    
441
    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
442
    return MAKE_TCGV_I64(idx);
443
}
444

    
445
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
446
{
447
    TCGContext *s = &tcg_ctx;
448
    TCGTemp *ts;
449
    int idx, k;
450

    
451
    k = type;
452
    if (temp_local)
453
        k += TCG_TYPE_COUNT;
454
    idx = s->first_free_temp[k];
455
    if (idx != -1) {
456
        /* There is already an available temp with the
457
           right type */
458
        ts = &s->temps[idx];
459
        s->first_free_temp[k] = ts->next_free_temp;
460
        ts->temp_allocated = 1;
461
        assert(ts->temp_local == temp_local);
462
    } else {
463
        idx = s->nb_temps;
464
#if TCG_TARGET_REG_BITS == 32
465
        if (type == TCG_TYPE_I64) {
466
            tcg_temp_alloc(s, s->nb_temps + 2);
467
            ts = &s->temps[s->nb_temps];
468
            ts->base_type = type;
469
            ts->type = TCG_TYPE_I32;
470
            ts->temp_allocated = 1;
471
            ts->temp_local = temp_local;
472
            ts->name = NULL;
473
            ts++;
474
            ts->base_type = TCG_TYPE_I32;
475
            ts->type = TCG_TYPE_I32;
476
            ts->temp_allocated = 1;
477
            ts->temp_local = temp_local;
478
            ts->name = NULL;
479
            s->nb_temps += 2;
480
        } else
481
#endif
482
        {
483
            tcg_temp_alloc(s, s->nb_temps + 1);
484
            ts = &s->temps[s->nb_temps];
485
            ts->base_type = type;
486
            ts->type = type;
487
            ts->temp_allocated = 1;
488
            ts->temp_local = temp_local;
489
            ts->name = NULL;
490
            s->nb_temps++;
491
        }
492
    }
493

    
494
#if defined(CONFIG_DEBUG_TCG)
495
    s->temps_in_use++;
496
#endif
497
    return idx;
498
}
499

    
500
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
501
{
502
    int idx;
503

    
504
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
505
    return MAKE_TCGV_I32(idx);
506
}
507

    
508
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
509
{
510
    int idx;
511

    
512
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
513
    return MAKE_TCGV_I64(idx);
514
}
515

    
516
static inline void tcg_temp_free_internal(int idx)
517
{
518
    TCGContext *s = &tcg_ctx;
519
    TCGTemp *ts;
520
    int k;
521

    
522
#if defined(CONFIG_DEBUG_TCG)
523
    s->temps_in_use--;
524
    if (s->temps_in_use < 0) {
525
        fprintf(stderr, "More temporaries freed than allocated!\n");
526
    }
527
#endif
528

    
529
    assert(idx >= s->nb_globals && idx < s->nb_temps);
530
    ts = &s->temps[idx];
531
    assert(ts->temp_allocated != 0);
532
    ts->temp_allocated = 0;
533
    k = ts->base_type;
534
    if (ts->temp_local)
535
        k += TCG_TYPE_COUNT;
536
    ts->next_free_temp = s->first_free_temp[k];
537
    s->first_free_temp[k] = idx;
538
}
539

    
540
void tcg_temp_free_i32(TCGv_i32 arg)
541
{
542
    tcg_temp_free_internal(GET_TCGV_I32(arg));
543
}
544

    
545
void tcg_temp_free_i64(TCGv_i64 arg)
546
{
547
    tcg_temp_free_internal(GET_TCGV_I64(arg));
548
}
549

    
550
TCGv_i32 tcg_const_i32(int32_t val)
551
{
552
    TCGv_i32 t0;
553
    t0 = tcg_temp_new_i32();
554
    tcg_gen_movi_i32(t0, val);
555
    return t0;
556
}
557

    
558
TCGv_i64 tcg_const_i64(int64_t val)
559
{
560
    TCGv_i64 t0;
561
    t0 = tcg_temp_new_i64();
562
    tcg_gen_movi_i64(t0, val);
563
    return t0;
564
}
565

    
566
TCGv_i32 tcg_const_local_i32(int32_t val)
567
{
568
    TCGv_i32 t0;
569
    t0 = tcg_temp_local_new_i32();
570
    tcg_gen_movi_i32(t0, val);
571
    return t0;
572
}
573

    
574
TCGv_i64 tcg_const_local_i64(int64_t val)
575
{
576
    TCGv_i64 t0;
577
    t0 = tcg_temp_local_new_i64();
578
    tcg_gen_movi_i64(t0, val);
579
    return t0;
580
}
581

    
582
#if defined(CONFIG_DEBUG_TCG)
583
void tcg_clear_temp_count(void)
584
{
585
    TCGContext *s = &tcg_ctx;
586
    s->temps_in_use = 0;
587
}
588

    
589
int tcg_check_temp_count(void)
590
{
591
    TCGContext *s = &tcg_ctx;
592
    if (s->temps_in_use) {
593
        /* Clear the count so that we don't give another
594
         * warning immediately next time around.
595
         */
596
        s->temps_in_use = 0;
597
        return 1;
598
    }
599
    return 0;
600
}
601
#endif
602

    
603
void tcg_register_helper(void *func, const char *name)
604
{
605
    TCGContext *s = &tcg_ctx;
606
    int n;
607
    if ((s->nb_helpers + 1) > s->allocated_helpers) {
608
        n = s->allocated_helpers;
609
        if (n == 0) {
610
            n = 4;
611
        } else {
612
            n *= 2;
613
        }
614
        s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
615
        s->allocated_helpers = n;
616
    }
617
    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
618
    s->helpers[s->nb_helpers].name = name;
619
    s->nb_helpers++;
620
}
621

    
622
/* Note: we convert the 64 bit args to 32 bit and do some alignment
623
   and endian swap. Maybe it would be better to do the alignment
624
   and endian swap in tcg_reg_alloc_call(). */
625
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
626
                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
627
{
628
    int i;
629
    int real_args;
630
    int nb_rets;
631
    TCGArg *nparam;
632

    
633
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
634
    for (i = 0; i < nargs; ++i) {
635
        int is_64bit = sizemask & (1 << (i+1)*2);
636
        int is_signed = sizemask & (2 << (i+1)*2);
637
        if (!is_64bit) {
638
            TCGv_i64 temp = tcg_temp_new_i64();
639
            TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
640
            if (is_signed) {
641
                tcg_gen_ext32s_i64(temp, orig);
642
            } else {
643
                tcg_gen_ext32u_i64(temp, orig);
644
            }
645
            args[i] = GET_TCGV_I64(temp);
646
        }
647
    }
648
#endif /* TCG_TARGET_EXTEND_ARGS */
649

    
650
    *s->gen_opc_ptr++ = INDEX_op_call;
651
    nparam = s->gen_opparam_ptr++;
652
    if (ret != TCG_CALL_DUMMY_ARG) {
653
#if TCG_TARGET_REG_BITS < 64
654
        if (sizemask & 1) {
655
#ifdef TCG_TARGET_WORDS_BIGENDIAN
656
            *s->gen_opparam_ptr++ = ret + 1;
657
            *s->gen_opparam_ptr++ = ret;
658
#else
659
            *s->gen_opparam_ptr++ = ret;
660
            *s->gen_opparam_ptr++ = ret + 1;
661
#endif
662
            nb_rets = 2;
663
        } else
664
#endif
665
        {
666
            *s->gen_opparam_ptr++ = ret;
667
            nb_rets = 1;
668
        }
669
    } else {
670
        nb_rets = 0;
671
    }
672
    real_args = 0;
673
    for (i = 0; i < nargs; i++) {
674
#if TCG_TARGET_REG_BITS < 64
675
        int is_64bit = sizemask & (1 << (i+1)*2);
676
        if (is_64bit) {
677
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
678
            /* some targets want aligned 64 bit args */
679
            if (real_args & 1) {
680
                *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
681
                real_args++;
682
            }
683
#endif
684
            /* If stack grows up, then we will be placing successive
685
               arguments at lower addresses, which means we need to
686
               reverse the order compared to how we would normally
687
               treat either big or little-endian.  For those arguments
688
               that will wind up in registers, this still works for
689
               HPPA (the only current STACK_GROWSUP target) since the
690
               argument registers are *also* allocated in decreasing
691
               order.  If another such target is added, this logic may
692
               have to get more complicated to differentiate between
693
               stack arguments and register arguments.  */
694
#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
695
            *s->gen_opparam_ptr++ = args[i] + 1;
696
            *s->gen_opparam_ptr++ = args[i];
697
#else
698
            *s->gen_opparam_ptr++ = args[i];
699
            *s->gen_opparam_ptr++ = args[i] + 1;
700
#endif
701
            real_args += 2;
702
            continue;
703
        }
704
#endif /* TCG_TARGET_REG_BITS < 64 */
705

    
706
        *s->gen_opparam_ptr++ = args[i];
707
        real_args++;
708
    }
709
    *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
710

    
711
    *s->gen_opparam_ptr++ = flags;
712

    
713
    *nparam = (nb_rets << 16) | (real_args + 1);
714

    
715
    /* total parameters, needed to go backward in the instruction stream */
716
    *s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
717

    
718
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
719
    for (i = 0; i < nargs; ++i) {
720
        int is_64bit = sizemask & (1 << (i+1)*2);
721
        if (!is_64bit) {
722
            TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
723
            tcg_temp_free_i64(temp);
724
        }
725
    }
726
#endif /* TCG_TARGET_EXTEND_ARGS */
727
}
728

    
729
#if TCG_TARGET_REG_BITS == 32
730
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
731
                        int c, int right, int arith)
732
{
733
    if (c == 0) {
734
        tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
735
        tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
736
    } else if (c >= 32) {
737
        c -= 32;
738
        if (right) {
739
            if (arith) {
740
                tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
741
                tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
742
            } else {
743
                tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
744
                tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
745
            }
746
        } else {
747
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
748
            tcg_gen_movi_i32(TCGV_LOW(ret), 0);
749
        }
750
    } else {
751
        TCGv_i32 t0, t1;
752

    
753
        t0 = tcg_temp_new_i32();
754
        t1 = tcg_temp_new_i32();
755
        if (right) {
756
            tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
757
            if (arith)
758
                tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
759
            else
760
                tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
761
            tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
762
            tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
763
            tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
764
        } else {
765
            tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
766
            /* Note: ret can be the same as arg1, so we use t1 */
767
            tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
768
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
769
            tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
770
            tcg_gen_mov_i32(TCGV_LOW(ret), t1);
771
        }
772
        tcg_temp_free_i32(t0);
773
        tcg_temp_free_i32(t1);
774
    }
775
}
776
#endif
777

    
778

    
779
static void tcg_reg_alloc_start(TCGContext *s)
780
{
781
    int i;
782
    TCGTemp *ts;
783
    for(i = 0; i < s->nb_globals; i++) {
784
        ts = &s->temps[i];
785
        if (ts->fixed_reg) {
786
            ts->val_type = TEMP_VAL_REG;
787
        } else {
788
            ts->val_type = TEMP_VAL_MEM;
789
        }
790
    }
791
    for(i = s->nb_globals; i < s->nb_temps; i++) {
792
        ts = &s->temps[i];
793
        if (ts->temp_local) {
794
            ts->val_type = TEMP_VAL_MEM;
795
        } else {
796
            ts->val_type = TEMP_VAL_DEAD;
797
        }
798
        ts->mem_allocated = 0;
799
        ts->fixed_reg = 0;
800
    }
801
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
802
        s->reg_to_temp[i] = -1;
803
    }
804
}
805

    
806
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
807
                                 int idx)
808
{
809
    TCGTemp *ts;
810

    
811
    assert(idx >= 0 && idx < s->nb_temps);
812
    ts = &s->temps[idx];
813
    if (idx < s->nb_globals) {
814
        pstrcpy(buf, buf_size, ts->name);
815
    } else {
816
        if (ts->temp_local) 
817
            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
818
        else
819
            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
820
    }
821
    return buf;
822
}
823

    
824
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
825
{
826
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
827
}
828

    
829
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
830
{
831
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
832
}
833

    
834
static int helper_cmp(const void *p1, const void *p2)
835
{
836
    const TCGHelperInfo *th1 = p1;
837
    const TCGHelperInfo *th2 = p2;
838
    if (th1->func < th2->func)
839
        return -1;
840
    else if (th1->func == th2->func)
841
        return 0;
842
    else
843
        return 1;
844
}
845

    
846
/* find helper definition (Note: A hash table would be better) */
847
static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
848
{
849
    int m, m_min, m_max;
850
    TCGHelperInfo *th;
851
    tcg_target_ulong v;
852

    
853
    if (unlikely(!s->helpers_sorted)) {
854
        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
855
              helper_cmp);
856
        s->helpers_sorted = 1;
857
    }
858

    
859
    /* binary search */
860
    m_min = 0;
861
    m_max = s->nb_helpers - 1;
862
    while (m_min <= m_max) {
863
        m = (m_min + m_max) >> 1;
864
        th = &s->helpers[m];
865
        v = th->func;
866
        if (v == val)
867
            return th;
868
        else if (val < v) {
869
            m_max = m - 1;
870
        } else {
871
            m_min = m + 1;
872
        }
873
    }
874
    return NULL;
875
}
876

    
877
static const char * const cond_name[] =
878
{
879
    [TCG_COND_NEVER] = "never",
880
    [TCG_COND_ALWAYS] = "always",
881
    [TCG_COND_EQ] = "eq",
882
    [TCG_COND_NE] = "ne",
883
    [TCG_COND_LT] = "lt",
884
    [TCG_COND_GE] = "ge",
885
    [TCG_COND_LE] = "le",
886
    [TCG_COND_GT] = "gt",
887
    [TCG_COND_LTU] = "ltu",
888
    [TCG_COND_GEU] = "geu",
889
    [TCG_COND_LEU] = "leu",
890
    [TCG_COND_GTU] = "gtu"
891
};
892

    
893
void tcg_dump_ops(TCGContext *s)
894
{
895
    const uint16_t *opc_ptr;
896
    const TCGArg *args;
897
    TCGArg arg;
898
    TCGOpcode c;
899
    int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
900
    const TCGOpDef *def;
901
    char buf[128];
902

    
903
    first_insn = 1;
904
    opc_ptr = s->gen_opc_buf;
905
    args = s->gen_opparam_buf;
906
    while (opc_ptr < s->gen_opc_ptr) {
907
        c = *opc_ptr++;
908
        def = &tcg_op_defs[c];
909
        if (c == INDEX_op_debug_insn_start) {
910
            uint64_t pc;
911
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
912
            pc = ((uint64_t)args[1] << 32) | args[0];
913
#else
914
            pc = args[0];
915
#endif
916
            if (!first_insn) {
917
                qemu_log("\n");
918
            }
919
            qemu_log(" ---- 0x%" PRIx64, pc);
920
            first_insn = 0;
921
            nb_oargs = def->nb_oargs;
922
            nb_iargs = def->nb_iargs;
923
            nb_cargs = def->nb_cargs;
924
        } else if (c == INDEX_op_call) {
925
            TCGArg arg;
926

    
927
            /* variable number of arguments */
928
            arg = *args++;
929
            nb_oargs = arg >> 16;
930
            nb_iargs = arg & 0xffff;
931
            nb_cargs = def->nb_cargs;
932

    
933
            qemu_log(" %s ", def->name);
934

    
935
            /* function name */
936
            qemu_log("%s",
937
                     tcg_get_arg_str_idx(s, buf, sizeof(buf),
938
                                         args[nb_oargs + nb_iargs - 1]));
939
            /* flags */
940
            qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
941
            /* nb out args */
942
            qemu_log(",$%d", nb_oargs);
943
            for(i = 0; i < nb_oargs; i++) {
944
                qemu_log(",");
945
                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
946
                                                   args[i]));
947
            }
948
            for(i = 0; i < (nb_iargs - 1); i++) {
949
                qemu_log(",");
950
                if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
951
                    qemu_log("<dummy>");
952
                } else {
953
                    qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
954
                                                       args[nb_oargs + i]));
955
                }
956
            }
957
        } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
958
            tcg_target_ulong val;
959
            TCGHelperInfo *th;
960

    
961
            nb_oargs = def->nb_oargs;
962
            nb_iargs = def->nb_iargs;
963
            nb_cargs = def->nb_cargs;
964
            qemu_log(" %s %s,$", def->name,
965
                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
966
            val = args[1];
967
            th = tcg_find_helper(s, val);
968
            if (th) {
969
                qemu_log("%s", th->name);
970
            } else {
971
                if (c == INDEX_op_movi_i32) {
972
                    qemu_log("0x%x", (uint32_t)val);
973
                } else {
974
                    qemu_log("0x%" PRIx64 , (uint64_t)val);
975
                }
976
            }
977
        } else {
978
            qemu_log(" %s ", def->name);
979
            if (c == INDEX_op_nopn) {
980
                /* variable number of arguments */
981
                nb_cargs = *args;
982
                nb_oargs = 0;
983
                nb_iargs = 0;
984
            } else {
985
                nb_oargs = def->nb_oargs;
986
                nb_iargs = def->nb_iargs;
987
                nb_cargs = def->nb_cargs;
988
            }
989
            
990
            k = 0;
991
            for(i = 0; i < nb_oargs; i++) {
992
                if (k != 0) {
993
                    qemu_log(",");
994
                }
995
                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
996
                                                   args[k++]));
997
            }
998
            for(i = 0; i < nb_iargs; i++) {
999
                if (k != 0) {
1000
                    qemu_log(",");
1001
                }
1002
                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1003
                                                   args[k++]));
1004
            }
1005
            switch (c) {
1006
            case INDEX_op_brcond_i32:
1007
            case INDEX_op_setcond_i32:
1008
            case INDEX_op_movcond_i32:
1009
            case INDEX_op_brcond2_i32:
1010
            case INDEX_op_setcond2_i32:
1011
            case INDEX_op_brcond_i64:
1012
            case INDEX_op_setcond_i64:
1013
            case INDEX_op_movcond_i64:
1014
                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1015
                    qemu_log(",%s", cond_name[args[k++]]);
1016
                } else {
1017
                    qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1018
                }
1019
                i = 1;
1020
                break;
1021
            default:
1022
                i = 0;
1023
                break;
1024
            }
1025
            for(; i < nb_cargs; i++) {
1026
                if (k != 0) {
1027
                    qemu_log(",");
1028
                }
1029
                arg = args[k++];
1030
                qemu_log("$0x%" TCG_PRIlx, arg);
1031
            }
1032
        }
1033
        qemu_log("\n");
1034
        args += nb_iargs + nb_oargs + nb_cargs;
1035
    }
1036
}
1037

    
1038
/* we give more priority to constraints with less registers */
1039
static int get_constraint_priority(const TCGOpDef *def, int k)
1040
{
1041
    const TCGArgConstraint *arg_ct;
1042

    
1043
    int i, n;
1044
    arg_ct = &def->args_ct[k];
1045
    if (arg_ct->ct & TCG_CT_ALIAS) {
1046
        /* an alias is equivalent to a single register */
1047
        n = 1;
1048
    } else {
1049
        if (!(arg_ct->ct & TCG_CT_REG))
1050
            return 0;
1051
        n = 0;
1052
        for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1053
            if (tcg_regset_test_reg(arg_ct->u.regs, i))
1054
                n++;
1055
        }
1056
    }
1057
    return TCG_TARGET_NB_REGS - n + 1;
1058
}
1059

    
1060
/* sort from highest priority to lowest */
1061
static void sort_constraints(TCGOpDef *def, int start, int n)
1062
{
1063
    int i, j, p1, p2, tmp;
1064

    
1065
    for(i = 0; i < n; i++)
1066
        def->sorted_args[start + i] = start + i;
1067
    if (n <= 1)
1068
        return;
1069
    for(i = 0; i < n - 1; i++) {
1070
        for(j = i + 1; j < n; j++) {
1071
            p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1072
            p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1073
            if (p1 < p2) {
1074
                tmp = def->sorted_args[start + i];
1075
                def->sorted_args[start + i] = def->sorted_args[start + j];
1076
                def->sorted_args[start + j] = tmp;
1077
            }
1078
        }
1079
    }
1080
}
1081

    
1082
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1083
{
1084
    TCGOpcode op;
1085
    TCGOpDef *def;
1086
    const char *ct_str;
1087
    int i, nb_args;
1088

    
1089
    for(;;) {
1090
        if (tdefs->op == (TCGOpcode)-1)
1091
            break;
1092
        op = tdefs->op;
1093
        assert((unsigned)op < NB_OPS);
1094
        def = &tcg_op_defs[op];
1095
#if defined(CONFIG_DEBUG_TCG)
1096
        /* Duplicate entry in op definitions? */
1097
        assert(!def->used);
1098
        def->used = 1;
1099
#endif
1100
        nb_args = def->nb_iargs + def->nb_oargs;
1101
        for(i = 0; i < nb_args; i++) {
1102
            ct_str = tdefs->args_ct_str[i];
1103
            /* Incomplete TCGTargetOpDef entry? */
1104
            assert(ct_str != NULL);
1105
            tcg_regset_clear(def->args_ct[i].u.regs);
1106
            def->args_ct[i].ct = 0;
1107
            if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1108
                int oarg;
1109
                oarg = ct_str[0] - '0';
1110
                assert(oarg < def->nb_oargs);
1111
                assert(def->args_ct[oarg].ct & TCG_CT_REG);
1112
                /* TCG_CT_ALIAS is for the output arguments. The input
1113
                   argument is tagged with TCG_CT_IALIAS. */
1114
                def->args_ct[i] = def->args_ct[oarg];
1115
                def->args_ct[oarg].ct = TCG_CT_ALIAS;
1116
                def->args_ct[oarg].alias_index = i;
1117
                def->args_ct[i].ct |= TCG_CT_IALIAS;
1118
                def->args_ct[i].alias_index = oarg;
1119
            } else {
1120
                for(;;) {
1121
                    if (*ct_str == '\0')
1122
                        break;
1123
                    switch(*ct_str) {
1124
                    case 'i':
1125
                        def->args_ct[i].ct |= TCG_CT_CONST;
1126
                        ct_str++;
1127
                        break;
1128
                    default:
1129
                        if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1130
                            fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1131
                                    ct_str, i, def->name);
1132
                            exit(1);
1133
                        }
1134
                    }
1135
                }
1136
            }
1137
        }
1138

    
1139
        /* TCGTargetOpDef entry with too much information? */
1140
        assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1141

    
1142
        /* sort the constraints (XXX: this is just an heuristic) */
1143
        sort_constraints(def, 0, def->nb_oargs);
1144
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1145

    
1146
#if 0
1147
        {
1148
            int i;
1149

1150
            printf("%s: sorted=", def->name);
1151
            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1152
                printf(" %d", def->sorted_args[i]);
1153
            printf("\n");
1154
        }
1155
#endif
1156
        tdefs++;
1157
    }
1158

    
1159
#if defined(CONFIG_DEBUG_TCG)
1160
    i = 0;
1161
    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1162
        const TCGOpDef *def = &tcg_op_defs[op];
1163
        if (def->flags & TCG_OPF_NOT_PRESENT) {
1164
            /* Wrong entry in op definitions? */
1165
            if (def->used) {
1166
                fprintf(stderr, "Invalid op definition for %s\n", def->name);
1167
                i = 1;
1168
            }
1169
        } else {
1170
            /* Missing entry in op definitions? */
1171
            if (!def->used) {
1172
                fprintf(stderr, "Missing op definition for %s\n", def->name);
1173
                i = 1;
1174
            }
1175
        }
1176
    }
1177
    if (i == 1) {
1178
        tcg_abort();
1179
    }
1180
#endif
1181
}
1182

    
1183
#ifdef USE_LIVENESS_ANALYSIS
1184

    
1185
/* set a nop for an operation using 'nb_args' */
1186
static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
1187
                               TCGArg *args, int nb_args)
1188
{
1189
    if (nb_args == 0) {
1190
        *opc_ptr = INDEX_op_nop;
1191
    } else {
1192
        *opc_ptr = INDEX_op_nopn;
1193
        args[0] = nb_args;
1194
        args[nb_args - 1] = nb_args;
1195
    }
1196
}
1197

    
1198
/* liveness analysis: end of function: all temps are dead, and globals
1199
   should be in memory. */
1200
static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1201
                                   uint8_t *mem_temps)
1202
{
1203
    memset(dead_temps, 1, s->nb_temps);
1204
    memset(mem_temps, 1, s->nb_globals);
1205
    memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
1206
}
1207

    
1208
/* liveness analysis: end of basic block: all temps are dead, globals
1209
   and local temps should be in memory. */
1210
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1211
                                 uint8_t *mem_temps)
1212
{
1213
    int i;
1214

    
1215
    memset(dead_temps, 1, s->nb_temps);
1216
    memset(mem_temps, 1, s->nb_globals);
1217
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1218
        mem_temps[i] = s->temps[i].temp_local;
1219
    }
1220
}
1221

    
1222
/* Liveness analysis : update the opc_dead_args array to tell if a
1223
   given input arguments is dead. Instructions updating dead
1224
   temporaries are removed. */
1225
static void tcg_liveness_analysis(TCGContext *s)
1226
{
1227
    int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1228
    TCGOpcode op, op_new;
1229
    TCGArg *args;
1230
    const TCGOpDef *def;
1231
    uint8_t *dead_temps, *mem_temps;
1232
    uint16_t dead_args;
1233
    uint8_t sync_args;
1234
    
1235
    s->gen_opc_ptr++; /* skip end */
1236

    
1237
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1238

    
1239
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1240
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1241
    
1242
    dead_temps = tcg_malloc(s->nb_temps);
1243
    mem_temps = tcg_malloc(s->nb_temps);
1244
    tcg_la_func_end(s, dead_temps, mem_temps);
1245

    
1246
    args = s->gen_opparam_ptr;
1247
    op_index = nb_ops - 1;
1248
    while (op_index >= 0) {
1249
        op = s->gen_opc_buf[op_index];
1250
        def = &tcg_op_defs[op];
1251
        switch(op) {
1252
        case INDEX_op_call:
1253
            {
1254
                int call_flags;
1255

    
1256
                nb_args = args[-1];
1257
                args -= nb_args;
1258
                nb_iargs = args[0] & 0xffff;
1259
                nb_oargs = args[0] >> 16;
1260
                args++;
1261
                call_flags = args[nb_oargs + nb_iargs];
1262

    
1263
                /* pure functions can be removed if their result is not
1264
                   used */
1265
                if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
1266
                    for(i = 0; i < nb_oargs; i++) {
1267
                        arg = args[i];
1268
                        if (!dead_temps[arg] || mem_temps[arg]) {
1269
                            goto do_not_remove_call;
1270
                        }
1271
                    }
1272
                    tcg_set_nop(s, s->gen_opc_buf + op_index,
1273
                                args - 1, nb_args);
1274
                } else {
1275
                do_not_remove_call:
1276

    
1277
                    /* output args are dead */
1278
                    dead_args = 0;
1279
                    sync_args = 0;
1280
                    for(i = 0; i < nb_oargs; i++) {
1281
                        arg = args[i];
1282
                        if (dead_temps[arg]) {
1283
                            dead_args |= (1 << i);
1284
                        }
1285
                        if (mem_temps[arg]) {
1286
                            sync_args |= (1 << i);
1287
                        }
1288
                        dead_temps[arg] = 1;
1289
                        mem_temps[arg] = 0;
1290
                    }
1291

    
1292
                    if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1293
                        /* globals should be synced to memory */
1294
                        memset(mem_temps, 1, s->nb_globals);
1295
                    }
1296
                    if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1297
                                        TCG_CALL_NO_READ_GLOBALS))) {
1298
                        /* globals should go back to memory */
1299
                        memset(dead_temps, 1, s->nb_globals);
1300
                    }
1301

    
1302
                    /* input args are live */
1303
                    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1304
                        arg = args[i];
1305
                        if (arg != TCG_CALL_DUMMY_ARG) {
1306
                            if (dead_temps[arg]) {
1307
                                dead_args |= (1 << i);
1308
                            }
1309
                            dead_temps[arg] = 0;
1310
                        }
1311
                    }
1312
                    s->op_dead_args[op_index] = dead_args;
1313
                    s->op_sync_args[op_index] = sync_args;
1314
                }
1315
                args--;
1316
            }
1317
            break;
1318
        case INDEX_op_debug_insn_start:
1319
            args -= def->nb_args;
1320
            break;
1321
        case INDEX_op_nopn:
1322
            nb_args = args[-1];
1323
            args -= nb_args;
1324
            break;
1325
        case INDEX_op_discard:
1326
            args--;
1327
            /* mark the temporary as dead */
1328
            dead_temps[args[0]] = 1;
1329
            mem_temps[args[0]] = 0;
1330
            break;
1331
        case INDEX_op_end:
1332
            break;
1333

    
1334
        case INDEX_op_add2_i32:
1335
            op_new = INDEX_op_add_i32;
1336
            goto do_addsub2;
1337
        case INDEX_op_sub2_i32:
1338
            op_new = INDEX_op_sub_i32;
1339
            goto do_addsub2;
1340
        case INDEX_op_add2_i64:
1341
            op_new = INDEX_op_add_i64;
1342
            goto do_addsub2;
1343
        case INDEX_op_sub2_i64:
1344
            op_new = INDEX_op_sub_i64;
1345
        do_addsub2:
1346
            args -= 6;
1347
            nb_iargs = 4;
1348
            nb_oargs = 2;
1349
            /* Test if the high part of the operation is dead, but not
1350
               the low part.  The result can be optimized to a simple
1351
               add or sub.  This happens often for x86_64 guest when the
1352
               cpu mode is set to 32 bit.  */
1353
            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1354
                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1355
                    goto do_remove;
1356
                }
1357
                /* Create the single operation plus nop.  */
1358
                s->gen_opc_buf[op_index] = op = op_new;
1359
                args[1] = args[2];
1360
                args[2] = args[4];
1361
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1362
                tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1363
                /* Fall through and mark the single-word operation live.  */
1364
                nb_iargs = 2;
1365
                nb_oargs = 1;
1366
            }
1367
            goto do_not_remove;
1368

    
1369
        case INDEX_op_mulu2_i32:
1370
        case INDEX_op_muls2_i32:
1371
            op_new = INDEX_op_mul_i32;
1372
            goto do_mul2;
1373
        case INDEX_op_mulu2_i64:
1374
        case INDEX_op_muls2_i64:
1375
            op_new = INDEX_op_mul_i64;
1376
        do_mul2:
1377
            args -= 4;
1378
            nb_iargs = 2;
1379
            nb_oargs = 2;
1380
            /* Likewise, test for the high part of the operation dead.  */
1381
            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1382
                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1383
                    goto do_remove;
1384
                }
1385
                s->gen_opc_buf[op_index] = op = op_new;
1386
                args[1] = args[2];
1387
                args[2] = args[3];
1388
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1389
                tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1390
                /* Fall through and mark the single-word operation live.  */
1391
                nb_oargs = 1;
1392
            }
1393
            goto do_not_remove;
1394

    
1395
        default:
1396
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1397
            args -= def->nb_args;
1398
            nb_iargs = def->nb_iargs;
1399
            nb_oargs = def->nb_oargs;
1400

    
1401
            /* Test if the operation can be removed because all
1402
               its outputs are dead. We assume that nb_oargs == 0
1403
               implies side effects */
1404
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1405
                for(i = 0; i < nb_oargs; i++) {
1406
                    arg = args[i];
1407
                    if (!dead_temps[arg] || mem_temps[arg]) {
1408
                        goto do_not_remove;
1409
                    }
1410
                }
1411
            do_remove:
1412
                tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
1413
#ifdef CONFIG_PROFILER
1414
                s->del_op_count++;
1415
#endif
1416
            } else {
1417
            do_not_remove:
1418

    
1419
                /* output args are dead */
1420
                dead_args = 0;
1421
                sync_args = 0;
1422
                for(i = 0; i < nb_oargs; i++) {
1423
                    arg = args[i];
1424
                    if (dead_temps[arg]) {
1425
                        dead_args |= (1 << i);
1426
                    }
1427
                    if (mem_temps[arg]) {
1428
                        sync_args |= (1 << i);
1429
                    }
1430
                    dead_temps[arg] = 1;
1431
                    mem_temps[arg] = 0;
1432
                }
1433

    
1434
                /* if end of basic block, update */
1435
                if (def->flags & TCG_OPF_BB_END) {
1436
                    tcg_la_bb_end(s, dead_temps, mem_temps);
1437
                } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1438
                    /* globals should be synced to memory */
1439
                    memset(mem_temps, 1, s->nb_globals);
1440
                }
1441

    
1442
                /* input args are live */
1443
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1444
                    arg = args[i];
1445
                    if (dead_temps[arg]) {
1446
                        dead_args |= (1 << i);
1447
                    }
1448
                    dead_temps[arg] = 0;
1449
                }
1450
                s->op_dead_args[op_index] = dead_args;
1451
                s->op_sync_args[op_index] = sync_args;
1452
            }
1453
            break;
1454
        }
1455
        op_index--;
1456
    }
1457

    
1458
    if (args != s->gen_opparam_buf) {
1459
        tcg_abort();
1460
    }
1461
}
1462
#else
1463
/* dummy liveness analysis */
1464
static void tcg_liveness_analysis(TCGContext *s)
1465
{
1466
    int nb_ops;
1467
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1468

    
1469
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1470
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1471
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1472
    memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1473
}
1474
#endif
1475

    
1476
#ifndef NDEBUG
1477
static void dump_regs(TCGContext *s)
1478
{
1479
    TCGTemp *ts;
1480
    int i;
1481
    char buf[64];
1482

    
1483
    for(i = 0; i < s->nb_temps; i++) {
1484
        ts = &s->temps[i];
1485
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1486
        switch(ts->val_type) {
1487
        case TEMP_VAL_REG:
1488
            printf("%s", tcg_target_reg_names[ts->reg]);
1489
            break;
1490
        case TEMP_VAL_MEM:
1491
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1492
            break;
1493
        case TEMP_VAL_CONST:
1494
            printf("$0x%" TCG_PRIlx, ts->val);
1495
            break;
1496
        case TEMP_VAL_DEAD:
1497
            printf("D");
1498
            break;
1499
        default:
1500
            printf("???");
1501
            break;
1502
        }
1503
        printf("\n");
1504
    }
1505

    
1506
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1507
        if (s->reg_to_temp[i] >= 0) {
1508
            printf("%s: %s\n", 
1509
                   tcg_target_reg_names[i], 
1510
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1511
        }
1512
    }
1513
}
1514

    
1515
static void check_regs(TCGContext *s)
1516
{
1517
    int reg, k;
1518
    TCGTemp *ts;
1519
    char buf[64];
1520

    
1521
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1522
        k = s->reg_to_temp[reg];
1523
        if (k >= 0) {
1524
            ts = &s->temps[k];
1525
            if (ts->val_type != TEMP_VAL_REG ||
1526
                ts->reg != reg) {
1527
                printf("Inconsistency for register %s:\n", 
1528
                       tcg_target_reg_names[reg]);
1529
                goto fail;
1530
            }
1531
        }
1532
    }
1533
    for(k = 0; k < s->nb_temps; k++) {
1534
        ts = &s->temps[k];
1535
        if (ts->val_type == TEMP_VAL_REG &&
1536
            !ts->fixed_reg &&
1537
            s->reg_to_temp[ts->reg] != k) {
1538
                printf("Inconsistency for temp %s:\n", 
1539
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1540
        fail:
1541
                printf("reg state:\n");
1542
                dump_regs(s);
1543
                tcg_abort();
1544
        }
1545
    }
1546
}
1547
#endif
1548

    
1549
static void temp_allocate_frame(TCGContext *s, int temp)
1550
{
1551
    TCGTemp *ts;
1552
    ts = &s->temps[temp];
1553
#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1554
    /* Sparc64 stack is accessed with offset of 2047 */
1555
    s->current_frame_offset = (s->current_frame_offset +
1556
                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
1557
        ~(sizeof(tcg_target_long) - 1);
1558
#endif
1559
    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1560
        s->frame_end) {
1561
        tcg_abort();
1562
    }
1563
    ts->mem_offset = s->current_frame_offset;
1564
    ts->mem_reg = s->frame_reg;
1565
    ts->mem_allocated = 1;
1566
    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1567
}
1568

    
1569
/* sync register 'reg' by saving it to the corresponding temporary */
1570
static inline void tcg_reg_sync(TCGContext *s, int reg)
1571
{
1572
    TCGTemp *ts;
1573
    int temp;
1574

    
1575
    temp = s->reg_to_temp[reg];
1576
    ts = &s->temps[temp];
1577
    assert(ts->val_type == TEMP_VAL_REG);
1578
    if (!ts->mem_coherent && !ts->fixed_reg) {
1579
        if (!ts->mem_allocated) {
1580
            temp_allocate_frame(s, temp);
1581
        }
1582
        tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1583
    }
1584
    ts->mem_coherent = 1;
1585
}
1586

    
1587
/* free register 'reg' by spilling the corresponding temporary if necessary */
1588
static void tcg_reg_free(TCGContext *s, int reg)
1589
{
1590
    int temp;
1591

    
1592
    temp = s->reg_to_temp[reg];
1593
    if (temp != -1) {
1594
        tcg_reg_sync(s, reg);
1595
        s->temps[temp].val_type = TEMP_VAL_MEM;
1596
        s->reg_to_temp[reg] = -1;
1597
    }
1598
}
1599

    
1600
/* Allocate a register belonging to reg1 & ~reg2 */
1601
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1602
{
1603
    int i, reg;
1604
    TCGRegSet reg_ct;
1605

    
1606
    tcg_regset_andnot(reg_ct, reg1, reg2);
1607

    
1608
    /* first try free registers */
1609
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1610
        reg = tcg_target_reg_alloc_order[i];
1611
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1612
            return reg;
1613
    }
1614

    
1615
    /* XXX: do better spill choice */
1616
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1617
        reg = tcg_target_reg_alloc_order[i];
1618
        if (tcg_regset_test_reg(reg_ct, reg)) {
1619
            tcg_reg_free(s, reg);
1620
            return reg;
1621
        }
1622
    }
1623

    
1624
    tcg_abort();
1625
}
1626

    
1627
/* mark a temporary as dead. */
1628
static inline void temp_dead(TCGContext *s, int temp)
1629
{
1630
    TCGTemp *ts;
1631

    
1632
    ts = &s->temps[temp];
1633
    if (!ts->fixed_reg) {
1634
        if (ts->val_type == TEMP_VAL_REG) {
1635
            s->reg_to_temp[ts->reg] = -1;
1636
        }
1637
        if (temp < s->nb_globals || ts->temp_local) {
1638
            ts->val_type = TEMP_VAL_MEM;
1639
        } else {
1640
            ts->val_type = TEMP_VAL_DEAD;
1641
        }
1642
    }
1643
}
1644

    
1645
/* sync a temporary to memory. 'allocated_regs' is used in case a
1646
   temporary registers needs to be allocated to store a constant. */
1647
static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1648
{
1649
    TCGTemp *ts;
1650

    
1651
    ts = &s->temps[temp];
1652
    if (!ts->fixed_reg) {
1653
        switch(ts->val_type) {
1654
        case TEMP_VAL_CONST:
1655
            ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1656
                                    allocated_regs);
1657
            ts->val_type = TEMP_VAL_REG;
1658
            s->reg_to_temp[ts->reg] = temp;
1659
            ts->mem_coherent = 0;
1660
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
1661
            /* fallthrough*/
1662
        case TEMP_VAL_REG:
1663
            tcg_reg_sync(s, ts->reg);
1664
            break;
1665
        case TEMP_VAL_DEAD:
1666
        case TEMP_VAL_MEM:
1667
            break;
1668
        default:
1669
            tcg_abort();
1670
        }
1671
    }
1672
}
1673

    
1674
/* save a temporary to memory. 'allocated_regs' is used in case a
1675
   temporary registers needs to be allocated to store a constant. */
1676
static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1677
{
1678
#ifdef USE_LIVENESS_ANALYSIS
1679
    /* The liveness analysis already ensures that globals are back
1680
       in memory. Keep an assert for safety. */
1681
    assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1682
#else
1683
    temp_sync(s, temp, allocated_regs);
1684
    temp_dead(s, temp);
1685
#endif
1686
}
1687

    
1688
/* save globals to their canonical location and assume they can be
1689
   modified be the following code. 'allocated_regs' is used in case a
1690
   temporary registers needs to be allocated to store a constant. */
1691
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1692
{
1693
    int i;
1694

    
1695
    for(i = 0; i < s->nb_globals; i++) {
1696
        temp_save(s, i, allocated_regs);
1697
    }
1698
}
1699

    
1700
/* sync globals to their canonical location and assume they can be
1701
   read by the following code. 'allocated_regs' is used in case a
1702
   temporary registers needs to be allocated to store a constant. */
1703
static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1704
{
1705
    int i;
1706

    
1707
    for (i = 0; i < s->nb_globals; i++) {
1708
#ifdef USE_LIVENESS_ANALYSIS
1709
        assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1710
               s->temps[i].mem_coherent);
1711
#else
1712
        temp_sync(s, i, allocated_regs);
1713
#endif
1714
    }
1715
}
1716

    
1717
/* at the end of a basic block, we assume all temporaries are dead and
1718
   all globals are stored at their canonical location. */
1719
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1720
{
1721
    TCGTemp *ts;
1722
    int i;
1723

    
1724
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1725
        ts = &s->temps[i];
1726
        if (ts->temp_local) {
1727
            temp_save(s, i, allocated_regs);
1728
        } else {
1729
#ifdef USE_LIVENESS_ANALYSIS
1730
            /* The liveness analysis already ensures that temps are dead.
1731
               Keep an assert for safety. */
1732
            assert(ts->val_type == TEMP_VAL_DEAD);
1733
#else
1734
            temp_dead(s, i);
1735
#endif
1736
        }
1737
    }
1738

    
1739
    save_globals(s, allocated_regs);
1740
}
1741

    
1742
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1743
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1744

    
1745
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1746
                               uint16_t dead_args, uint8_t sync_args)
1747
{
1748
    TCGTemp *ots;
1749
    tcg_target_ulong val;
1750

    
1751
    ots = &s->temps[args[0]];
1752
    val = args[1];
1753

    
1754
    if (ots->fixed_reg) {
1755
        /* for fixed registers, we do not do any constant
1756
           propagation */
1757
        tcg_out_movi(s, ots->type, ots->reg, val);
1758
    } else {
1759
        /* The movi is not explicitly generated here */
1760
        if (ots->val_type == TEMP_VAL_REG)
1761
            s->reg_to_temp[ots->reg] = -1;
1762
        ots->val_type = TEMP_VAL_CONST;
1763
        ots->val = val;
1764
    }
1765
    if (NEED_SYNC_ARG(0)) {
1766
        temp_sync(s, args[0], s->reserved_regs);
1767
    }
1768
    if (IS_DEAD_ARG(0)) {
1769
        temp_dead(s, args[0]);
1770
    }
1771
}
1772

    
1773
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1774
                              const TCGArg *args, uint16_t dead_args,
1775
                              uint8_t sync_args)
1776
{
1777
    TCGRegSet allocated_regs;
1778
    TCGTemp *ts, *ots;
1779
    const TCGArgConstraint *arg_ct, *oarg_ct;
1780

    
1781
    tcg_regset_set(allocated_regs, s->reserved_regs);
1782
    ots = &s->temps[args[0]];
1783
    ts = &s->temps[args[1]];
1784
    oarg_ct = &def->args_ct[0];
1785
    arg_ct = &def->args_ct[1];
1786

    
1787
    /* If the source value is not in a register, and we're going to be
1788
       forced to have it in a register in order to perform the copy,
1789
       then copy the SOURCE value into its own register first.  That way
1790
       we don't have to reload SOURCE the next time it is used. */
1791
    if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
1792
        || ts->val_type == TEMP_VAL_MEM) {
1793
        ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1794
        if (ts->val_type == TEMP_VAL_MEM) {
1795
            tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
1796
            ts->mem_coherent = 1;
1797
        } else if (ts->val_type == TEMP_VAL_CONST) {
1798
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
1799
        }
1800
        s->reg_to_temp[ts->reg] = args[1];
1801
        ts->val_type = TEMP_VAL_REG;
1802
    }
1803

    
1804
    if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
1805
        /* mov to a non-saved dead register makes no sense (even with
1806
           liveness analysis disabled). */
1807
        assert(NEED_SYNC_ARG(0));
1808
        /* The code above should have moved the temp to a register. */
1809
        assert(ts->val_type == TEMP_VAL_REG);
1810
        if (!ots->mem_allocated) {
1811
            temp_allocate_frame(s, args[0]);
1812
        }
1813
        tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
1814
        if (IS_DEAD_ARG(1)) {
1815
            temp_dead(s, args[1]);
1816
        }
1817
        temp_dead(s, args[0]);
1818
    } else if (ts->val_type == TEMP_VAL_CONST) {
1819
        /* propagate constant */
1820
        if (ots->val_type == TEMP_VAL_REG) {
1821
            s->reg_to_temp[ots->reg] = -1;
1822
        }
1823
        ots->val_type = TEMP_VAL_CONST;
1824
        ots->val = ts->val;
1825
    } else {
1826
        /* The code in the first if block should have moved the
1827
           temp to a register. */
1828
        assert(ts->val_type == TEMP_VAL_REG);
1829
        if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1830
            /* the mov can be suppressed */
1831
            if (ots->val_type == TEMP_VAL_REG) {
1832
                s->reg_to_temp[ots->reg] = -1;
1833
            }
1834
            ots->reg = ts->reg;
1835
            temp_dead(s, args[1]);
1836
        } else {
1837
            if (ots->val_type != TEMP_VAL_REG) {
1838
                /* When allocating a new register, make sure to not spill the
1839
                   input one. */
1840
                tcg_regset_set_reg(allocated_regs, ts->reg);
1841
                ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs);
1842
            }
1843
            tcg_out_mov(s, ots->type, ots->reg, ts->reg);
1844
        }
1845
        ots->val_type = TEMP_VAL_REG;
1846
        ots->mem_coherent = 0;
1847
        s->reg_to_temp[ots->reg] = args[0];
1848
        if (NEED_SYNC_ARG(0)) {
1849
            tcg_reg_sync(s, ots->reg);
1850
        }
1851
    }
1852
}
1853

    
1854
static void tcg_reg_alloc_op(TCGContext *s, 
1855
                             const TCGOpDef *def, TCGOpcode opc,
1856
                             const TCGArg *args, uint16_t dead_args,
1857
                             uint8_t sync_args)
1858
{
1859
    TCGRegSet allocated_regs;
1860
    int i, k, nb_iargs, nb_oargs, reg;
1861
    TCGArg arg;
1862
    const TCGArgConstraint *arg_ct;
1863
    TCGTemp *ts;
1864
    TCGArg new_args[TCG_MAX_OP_ARGS];
1865
    int const_args[TCG_MAX_OP_ARGS];
1866

    
1867
    nb_oargs = def->nb_oargs;
1868
    nb_iargs = def->nb_iargs;
1869

    
1870
    /* copy constants */
1871
    memcpy(new_args + nb_oargs + nb_iargs, 
1872
           args + nb_oargs + nb_iargs, 
1873
           sizeof(TCGArg) * def->nb_cargs);
1874

    
1875
    /* satisfy input constraints */ 
1876
    tcg_regset_set(allocated_regs, s->reserved_regs);
1877
    for(k = 0; k < nb_iargs; k++) {
1878
        i = def->sorted_args[nb_oargs + k];
1879
        arg = args[i];
1880
        arg_ct = &def->args_ct[i];
1881
        ts = &s->temps[arg];
1882
        if (ts->val_type == TEMP_VAL_MEM) {
1883
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1884
            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1885
            ts->val_type = TEMP_VAL_REG;
1886
            ts->reg = reg;
1887
            ts->mem_coherent = 1;
1888
            s->reg_to_temp[reg] = arg;
1889
        } else if (ts->val_type == TEMP_VAL_CONST) {
1890
            if (tcg_target_const_match(ts->val, arg_ct)) {
1891
                /* constant is OK for instruction */
1892
                const_args[i] = 1;
1893
                new_args[i] = ts->val;
1894
                goto iarg_end;
1895
            } else {
1896
                /* need to move to a register */
1897
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1898
                tcg_out_movi(s, ts->type, reg, ts->val);
1899
                ts->val_type = TEMP_VAL_REG;
1900
                ts->reg = reg;
1901
                ts->mem_coherent = 0;
1902
                s->reg_to_temp[reg] = arg;
1903
            }
1904
        }
1905
        assert(ts->val_type == TEMP_VAL_REG);
1906
        if (arg_ct->ct & TCG_CT_IALIAS) {
1907
            if (ts->fixed_reg) {
1908
                /* if fixed register, we must allocate a new register
1909
                   if the alias is not the same register */
1910
                if (arg != args[arg_ct->alias_index])
1911
                    goto allocate_in_reg;
1912
            } else {
1913
                /* if the input is aliased to an output and if it is
1914
                   not dead after the instruction, we must allocate
1915
                   a new register and move it */
1916
                if (!IS_DEAD_ARG(i)) {
1917
                    goto allocate_in_reg;
1918
                }
1919
            }
1920
        }
1921
        reg = ts->reg;
1922
        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1923
            /* nothing to do : the constraint is satisfied */
1924
        } else {
1925
        allocate_in_reg:
1926
            /* allocate a new register matching the constraint 
1927
               and move the temporary register into it */
1928
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1929
            tcg_out_mov(s, ts->type, reg, ts->reg);
1930
        }
1931
        new_args[i] = reg;
1932
        const_args[i] = 0;
1933
        tcg_regset_set_reg(allocated_regs, reg);
1934
    iarg_end: ;
1935
    }
1936
    
1937
    /* mark dead temporaries and free the associated registers */
1938
    for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1939
        if (IS_DEAD_ARG(i)) {
1940
            temp_dead(s, args[i]);
1941
        }
1942
    }
1943

    
1944
    if (def->flags & TCG_OPF_BB_END) {
1945
        tcg_reg_alloc_bb_end(s, allocated_regs);
1946
    } else {
1947
        if (def->flags & TCG_OPF_CALL_CLOBBER) {
1948
            /* XXX: permit generic clobber register list ? */ 
1949
            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1950
                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1951
                    tcg_reg_free(s, reg);
1952
                }
1953
            }
1954
        }
1955
        if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1956
            /* sync globals if the op has side effects and might trigger
1957
               an exception. */
1958
            sync_globals(s, allocated_regs);
1959
        }
1960
        
1961
        /* satisfy the output constraints */
1962
        tcg_regset_set(allocated_regs, s->reserved_regs);
1963
        for(k = 0; k < nb_oargs; k++) {
1964
            i = def->sorted_args[k];
1965
            arg = args[i];
1966
            arg_ct = &def->args_ct[i];
1967
            ts = &s->temps[arg];
1968
            if (arg_ct->ct & TCG_CT_ALIAS) {
1969
                reg = new_args[arg_ct->alias_index];
1970
            } else {
1971
                /* if fixed register, we try to use it */
1972
                reg = ts->reg;
1973
                if (ts->fixed_reg &&
1974
                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1975
                    goto oarg_end;
1976
                }
1977
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1978
            }
1979
            tcg_regset_set_reg(allocated_regs, reg);
1980
            /* if a fixed register is used, then a move will be done afterwards */
1981
            if (!ts->fixed_reg) {
1982
                if (ts->val_type == TEMP_VAL_REG) {
1983
                    s->reg_to_temp[ts->reg] = -1;
1984
                }
1985
                ts->val_type = TEMP_VAL_REG;
1986
                ts->reg = reg;
1987
                /* temp value is modified, so the value kept in memory is
1988
                   potentially not the same */
1989
                ts->mem_coherent = 0;
1990
                s->reg_to_temp[reg] = arg;
1991
            }
1992
        oarg_end:
1993
            new_args[i] = reg;
1994
        }
1995
    }
1996

    
1997
    /* emit instruction */
1998
    tcg_out_op(s, opc, new_args, const_args);
1999
    
2000
    /* move the outputs in the correct register if needed */
2001
    for(i = 0; i < nb_oargs; i++) {
2002
        ts = &s->temps[args[i]];
2003
        reg = new_args[i];
2004
        if (ts->fixed_reg && ts->reg != reg) {
2005
            tcg_out_mov(s, ts->type, ts->reg, reg);
2006
        }
2007
        if (NEED_SYNC_ARG(i)) {
2008
            tcg_reg_sync(s, reg);
2009
        }
2010
        if (IS_DEAD_ARG(i)) {
2011
            temp_dead(s, args[i]);
2012
        }
2013
    }
2014
}
2015

    
2016
#ifdef TCG_TARGET_STACK_GROWSUP
2017
#define STACK_DIR(x) (-(x))
2018
#else
2019
#define STACK_DIR(x) (x)
2020
#endif
2021

    
2022
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
2023
                              TCGOpcode opc, const TCGArg *args,
2024
                              uint16_t dead_args, uint8_t sync_args)
2025
{
2026
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2027
    TCGArg arg, func_arg;
2028
    TCGTemp *ts;
2029
    tcg_target_long stack_offset, call_stack_size, func_addr;
2030
    int const_func_arg, allocate_args;
2031
    TCGRegSet allocated_regs;
2032
    const TCGArgConstraint *arg_ct;
2033

    
2034
    arg = *args++;
2035

    
2036
    nb_oargs = arg >> 16;
2037
    nb_iargs = arg & 0xffff;
2038
    nb_params = nb_iargs - 1;
2039

    
2040
    flags = args[nb_oargs + nb_iargs];
2041

    
2042
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2043
    if (nb_regs > nb_params)
2044
        nb_regs = nb_params;
2045

    
2046
    /* assign stack slots first */
2047
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2048
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
2049
        ~(TCG_TARGET_STACK_ALIGN - 1);
2050
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2051
    if (allocate_args) {
2052
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2053
           preallocate call stack */
2054
        tcg_abort();
2055
    }
2056

    
2057
    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2058
    for(i = nb_regs; i < nb_params; i++) {
2059
        arg = args[nb_oargs + i];
2060
#ifdef TCG_TARGET_STACK_GROWSUP
2061
        stack_offset -= sizeof(tcg_target_long);
2062
#endif
2063
        if (arg != TCG_CALL_DUMMY_ARG) {
2064
            ts = &s->temps[arg];
2065
            if (ts->val_type == TEMP_VAL_REG) {
2066
                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2067
            } else if (ts->val_type == TEMP_VAL_MEM) {
2068
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2069
                                    s->reserved_regs);
2070
                /* XXX: not correct if reading values from the stack */
2071
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2072
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2073
            } else if (ts->val_type == TEMP_VAL_CONST) {
2074
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2075
                                    s->reserved_regs);
2076
                /* XXX: sign extend may be needed on some targets */
2077
                tcg_out_movi(s, ts->type, reg, ts->val);
2078
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2079
            } else {
2080
                tcg_abort();
2081
            }
2082
        }
2083
#ifndef TCG_TARGET_STACK_GROWSUP
2084
        stack_offset += sizeof(tcg_target_long);
2085
#endif
2086
    }
2087
    
2088
    /* assign input registers */
2089
    tcg_regset_set(allocated_regs, s->reserved_regs);
2090
    for(i = 0; i < nb_regs; i++) {
2091
        arg = args[nb_oargs + i];
2092
        if (arg != TCG_CALL_DUMMY_ARG) {
2093
            ts = &s->temps[arg];
2094
            reg = tcg_target_call_iarg_regs[i];
2095
            tcg_reg_free(s, reg);
2096
            if (ts->val_type == TEMP_VAL_REG) {
2097
                if (ts->reg != reg) {
2098
                    tcg_out_mov(s, ts->type, reg, ts->reg);
2099
                }
2100
            } else if (ts->val_type == TEMP_VAL_MEM) {
2101
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2102
            } else if (ts->val_type == TEMP_VAL_CONST) {
2103
                /* XXX: sign extend ? */
2104
                tcg_out_movi(s, ts->type, reg, ts->val);
2105
            } else {
2106
                tcg_abort();
2107
            }
2108
            tcg_regset_set_reg(allocated_regs, reg);
2109
        }
2110
    }
2111
    
2112
    /* assign function address */
2113
    func_arg = args[nb_oargs + nb_iargs - 1];
2114
    arg_ct = &def->args_ct[0];
2115
    ts = &s->temps[func_arg];
2116
    func_addr = ts->val;
2117
    const_func_arg = 0;
2118
    if (ts->val_type == TEMP_VAL_MEM) {
2119
        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2120
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2121
        func_arg = reg;
2122
        tcg_regset_set_reg(allocated_regs, reg);
2123
    } else if (ts->val_type == TEMP_VAL_REG) {
2124
        reg = ts->reg;
2125
        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2126
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2127
            tcg_out_mov(s, ts->type, reg, ts->reg);
2128
        }
2129
        func_arg = reg;
2130
        tcg_regset_set_reg(allocated_regs, reg);
2131
    } else if (ts->val_type == TEMP_VAL_CONST) {
2132
        if (tcg_target_const_match(func_addr, arg_ct)) {
2133
            const_func_arg = 1;
2134
            func_arg = func_addr;
2135
        } else {
2136
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2137
            tcg_out_movi(s, ts->type, reg, func_addr);
2138
            func_arg = reg;
2139
            tcg_regset_set_reg(allocated_regs, reg);
2140
        }
2141
    } else {
2142
        tcg_abort();
2143
    }
2144
        
2145
    
2146
    /* mark dead temporaries and free the associated registers */
2147
    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2148
        if (IS_DEAD_ARG(i)) {
2149
            temp_dead(s, args[i]);
2150
        }
2151
    }
2152
    
2153
    /* clobber call registers */
2154
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2155
        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2156
            tcg_reg_free(s, reg);
2157
        }
2158
    }
2159

    
2160
    /* Save globals if they might be written by the helper, sync them if
2161
       they might be read. */
2162
    if (flags & TCG_CALL_NO_READ_GLOBALS) {
2163
        /* Nothing to do */
2164
    } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2165
        sync_globals(s, allocated_regs);
2166
    } else {
2167
        save_globals(s, allocated_regs);
2168
    }
2169

    
2170
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2171

    
2172
    /* assign output registers and emit moves if needed */
2173
    for(i = 0; i < nb_oargs; i++) {
2174
        arg = args[i];
2175
        ts = &s->temps[arg];
2176
        reg = tcg_target_call_oarg_regs[i];
2177
        assert(s->reg_to_temp[reg] == -1);
2178
        if (ts->fixed_reg) {
2179
            if (ts->reg != reg) {
2180
                tcg_out_mov(s, ts->type, ts->reg, reg);
2181
            }
2182
        } else {
2183
            if (ts->val_type == TEMP_VAL_REG) {
2184
                s->reg_to_temp[ts->reg] = -1;
2185
            }
2186
            ts->val_type = TEMP_VAL_REG;
2187
            ts->reg = reg;
2188
            ts->mem_coherent = 0;
2189
            s->reg_to_temp[reg] = arg;
2190
            if (NEED_SYNC_ARG(i)) {
2191
                tcg_reg_sync(s, reg);
2192
            }
2193
            if (IS_DEAD_ARG(i)) {
2194
                temp_dead(s, args[i]);
2195
            }
2196
        }
2197
    }
2198
    
2199
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2200
}
2201

    
2202
#ifdef CONFIG_PROFILER
2203

    
2204
static int64_t tcg_table_op_count[NB_OPS];
2205

    
2206
static void dump_op_count(void)
2207
{
2208
    int i;
2209
    FILE *f;
2210
    f = fopen("/tmp/op.log", "w");
2211
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2212
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2213
    }
2214
    fclose(f);
2215
}
2216
#endif
2217

    
2218

    
2219
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2220
                                      long search_pc)
2221
{
2222
    TCGOpcode opc;
2223
    int op_index;
2224
    const TCGOpDef *def;
2225
    const TCGArg *args;
2226

    
2227
#ifdef DEBUG_DISAS
2228
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2229
        qemu_log("OP:\n");
2230
        tcg_dump_ops(s);
2231
        qemu_log("\n");
2232
    }
2233
#endif
2234

    
2235
#ifdef CONFIG_PROFILER
2236
    s->opt_time -= profile_getclock();
2237
#endif
2238

    
2239
#ifdef USE_TCG_OPTIMIZATIONS
2240
    s->gen_opparam_ptr =
2241
        tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2242
#endif
2243

    
2244
#ifdef CONFIG_PROFILER
2245
    s->opt_time += profile_getclock();
2246
    s->la_time -= profile_getclock();
2247
#endif
2248

    
2249
    tcg_liveness_analysis(s);
2250

    
2251
#ifdef CONFIG_PROFILER
2252
    s->la_time += profile_getclock();
2253
#endif
2254

    
2255
#ifdef DEBUG_DISAS
2256
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2257
        qemu_log("OP after optimization and liveness analysis:\n");
2258
        tcg_dump_ops(s);
2259
        qemu_log("\n");
2260
    }
2261
#endif
2262

    
2263
    tcg_reg_alloc_start(s);
2264

    
2265
    s->code_buf = gen_code_buf;
2266
    s->code_ptr = gen_code_buf;
2267

    
2268
    args = s->gen_opparam_buf;
2269
    op_index = 0;
2270

    
2271
    for(;;) {
2272
        opc = s->gen_opc_buf[op_index];
2273
#ifdef CONFIG_PROFILER
2274
        tcg_table_op_count[opc]++;
2275
#endif
2276
        def = &tcg_op_defs[opc];
2277
#if 0
2278
        printf("%s: %d %d %d\n", def->name,
2279
               def->nb_oargs, def->nb_iargs, def->nb_cargs);
2280
        //        dump_regs(s);
2281
#endif
2282
        switch(opc) {
2283
        case INDEX_op_mov_i32:
2284
        case INDEX_op_mov_i64:
2285
            tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2286
                              s->op_sync_args[op_index]);
2287
            break;
2288
        case INDEX_op_movi_i32:
2289
        case INDEX_op_movi_i64:
2290
            tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2291
                               s->op_sync_args[op_index]);
2292
            break;
2293
        case INDEX_op_debug_insn_start:
2294
            /* debug instruction */
2295
            break;
2296
        case INDEX_op_nop:
2297
        case INDEX_op_nop1:
2298
        case INDEX_op_nop2:
2299
        case INDEX_op_nop3:
2300
            break;
2301
        case INDEX_op_nopn:
2302
            args += args[0];
2303
            goto next;
2304
        case INDEX_op_discard:
2305
            temp_dead(s, args[0]);
2306
            break;
2307
        case INDEX_op_set_label:
2308
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
2309
            tcg_out_label(s, args[0], s->code_ptr);
2310
            break;
2311
        case INDEX_op_call:
2312
            args += tcg_reg_alloc_call(s, def, opc, args,
2313
                                       s->op_dead_args[op_index],
2314
                                       s->op_sync_args[op_index]);
2315
            goto next;
2316
        case INDEX_op_end:
2317
            goto the_end;
2318
        default:
2319
            /* Sanity check that we've not introduced any unhandled opcodes. */
2320
            if (def->flags & TCG_OPF_NOT_PRESENT) {
2321
                tcg_abort();
2322
            }
2323
            /* Note: in order to speed up the code, it would be much
2324
               faster to have specialized register allocator functions for
2325
               some common argument patterns */
2326
            tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2327
                             s->op_sync_args[op_index]);
2328
            break;
2329
        }
2330
        args += def->nb_args;
2331
    next:
2332
        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2333
            return op_index;
2334
        }
2335
        op_index++;
2336
#ifndef NDEBUG
2337
        check_regs(s);
2338
#endif
2339
    }
2340
 the_end:
2341
#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
2342
    /* Generate TB finalization at the end of block */
2343
    tcg_out_tb_finalize(s);
2344
#endif
2345
    return -1;
2346
}
2347

    
2348
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2349
{
2350
#ifdef CONFIG_PROFILER
2351
    {
2352
        int n;
2353
        n = (s->gen_opc_ptr - s->gen_opc_buf);
2354
        s->op_count += n;
2355
        if (n > s->op_count_max)
2356
            s->op_count_max = n;
2357

    
2358
        s->temp_count += s->nb_temps;
2359
        if (s->nb_temps > s->temp_count_max)
2360
            s->temp_count_max = s->nb_temps;
2361
    }
2362
#endif
2363

    
2364
    tcg_gen_code_common(s, gen_code_buf, -1);
2365

    
2366
    /* flush instruction cache */
2367
    flush_icache_range((tcg_target_ulong)gen_code_buf,
2368
                       (tcg_target_ulong)s->code_ptr);
2369

    
2370
    return s->code_ptr -  gen_code_buf;
2371
}
2372

    
2373
/* Return the index of the micro operation such as the pc after is <
2374
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2375
   not be changed, though writing the same values is ok.
2376
   Return -1 if not found. */
2377
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2378
{
2379
    return tcg_gen_code_common(s, gen_code_buf, offset);
2380
}
2381

    
2382
#ifdef CONFIG_PROFILER
2383
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2384
{
2385
    TCGContext *s = &tcg_ctx;
2386
    int64_t tot;
2387

    
2388
    tot = s->interm_time + s->code_time;
2389
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2390
                tot, tot / 2.4e9);
2391
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2392
                s->tb_count, 
2393
                s->tb_count1 - s->tb_count,
2394
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2395
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2396
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2397
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2398
                s->tb_count ? 
2399
                (double)s->del_op_count / s->tb_count : 0);
2400
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2401
                s->tb_count ? 
2402
                (double)s->temp_count / s->tb_count : 0,
2403
                s->temp_count_max);
2404
    
2405
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2406
                s->op_count ? (double)tot / s->op_count : 0);
2407
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2408
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2409
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2410
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2411
    if (tot == 0)
2412
        tot = 1;
2413
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2414
                (double)s->interm_time / tot * 100.0);
2415
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2416
                (double)s->code_time / tot * 100.0);
2417
    cpu_fprintf(f, "optim./code time    %0.1f%%\n",
2418
                (double)s->opt_time / (s->code_time ? s->code_time : 1)
2419
                * 100.0);
2420
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2421
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2422
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2423
                s->restore_count);
2424
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2425
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2426

    
2427
    dump_op_count();
2428
}
2429
#else
2430
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2431
{
2432
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2433
}
2434
#endif
2435

    
2436
#ifdef ELF_HOST_MACHINE
2437
/* In order to use this feature, the backend needs to do three things:
2438

2439
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2440
       put into the ELF image and to indicate support for the feature.
2441

2442
   (2) Define tcg_register_jit.  This should create a buffer containing
2443
       the contents of a .debug_frame section that describes the post-
2444
       prologue unwind info for the tcg machine.
2445

2446
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2447
*/
2448

    
2449
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2450
typedef enum {
2451
    JIT_NOACTION = 0,
2452
    JIT_REGISTER_FN,
2453
    JIT_UNREGISTER_FN
2454
} jit_actions_t;
2455

    
2456
struct jit_code_entry {
2457
    struct jit_code_entry *next_entry;
2458
    struct jit_code_entry *prev_entry;
2459
    const void *symfile_addr;
2460
    uint64_t symfile_size;
2461
};
2462

    
2463
struct jit_descriptor {
2464
    uint32_t version;
2465
    uint32_t action_flag;
2466
    struct jit_code_entry *relevant_entry;
2467
    struct jit_code_entry *first_entry;
2468
};
2469

    
2470
void __jit_debug_register_code(void) __attribute__((noinline));
2471
void __jit_debug_register_code(void)
2472
{
2473
    asm("");
2474
}
2475

    
2476
/* Must statically initialize the version, because GDB may check
2477
   the version before we can set it.  */
2478
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2479

    
2480
/* End GDB interface.  */
2481

    
2482
static int find_string(const char *strtab, const char *str)
2483
{
2484
    const char *p = strtab + 1;
2485

    
2486
    while (1) {
2487
        if (strcmp(p, str) == 0) {
2488
            return p - strtab;
2489
        }
2490
        p += strlen(p) + 1;
2491
    }
2492
}
2493

    
2494
static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2495
                                 void *debug_frame, size_t debug_frame_size)
2496
{
2497
    struct __attribute__((packed)) DebugInfo {
2498
        uint32_t  len;
2499
        uint16_t  version;
2500
        uint32_t  abbrev;
2501
        uint8_t   ptr_size;
2502
        uint8_t   cu_die;
2503
        uint16_t  cu_lang;
2504
        uintptr_t cu_low_pc;
2505
        uintptr_t cu_high_pc;
2506
        uint8_t   fn_die;
2507
        char      fn_name[16];
2508
        uintptr_t fn_low_pc;
2509
        uintptr_t fn_high_pc;
2510
        uint8_t   cu_eoc;
2511
    };
2512

    
2513
    struct ElfImage {
2514
        ElfW(Ehdr) ehdr;
2515
        ElfW(Phdr) phdr;
2516
        ElfW(Shdr) shdr[7];
2517
        ElfW(Sym)  sym[2];
2518
        struct DebugInfo di;
2519
        uint8_t    da[24];
2520
        char       str[80];
2521
    };
2522

    
2523
    struct ElfImage *img;
2524

    
2525
    static const struct ElfImage img_template = {
2526
        .ehdr = {
2527
            .e_ident[EI_MAG0] = ELFMAG0,
2528
            .e_ident[EI_MAG1] = ELFMAG1,
2529
            .e_ident[EI_MAG2] = ELFMAG2,
2530
            .e_ident[EI_MAG3] = ELFMAG3,
2531
            .e_ident[EI_CLASS] = ELF_CLASS,
2532
            .e_ident[EI_DATA] = ELF_DATA,
2533
            .e_ident[EI_VERSION] = EV_CURRENT,
2534
            .e_type = ET_EXEC,
2535
            .e_machine = ELF_HOST_MACHINE,
2536
            .e_version = EV_CURRENT,
2537
            .e_phoff = offsetof(struct ElfImage, phdr),
2538
            .e_shoff = offsetof(struct ElfImage, shdr),
2539
            .e_ehsize = sizeof(ElfW(Shdr)),
2540
            .e_phentsize = sizeof(ElfW(Phdr)),
2541
            .e_phnum = 1,
2542
            .e_shentsize = sizeof(ElfW(Shdr)),
2543
            .e_shnum = ARRAY_SIZE(img->shdr),
2544
            .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2545
#ifdef ELF_HOST_FLAGS
2546
            .e_flags = ELF_HOST_FLAGS,
2547
#endif
2548
#ifdef ELF_OSABI
2549
            .e_ident[EI_OSABI] = ELF_OSABI,
2550
#endif
2551
        },
2552
        .phdr = {
2553
            .p_type = PT_LOAD,
2554
            .p_flags = PF_X,
2555
        },
2556
        .shdr = {
2557
            [0] = { .sh_type = SHT_NULL },
2558
            /* Trick: The contents of code_gen_buffer are not present in
2559
               this fake ELF file; that got allocated elsewhere.  Therefore
2560
               we mark .text as SHT_NOBITS (similar to .bss) so that readers
2561
               will not look for contents.  We can record any address.  */
2562
            [1] = { /* .text */
2563
                .sh_type = SHT_NOBITS,
2564
                .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2565
            },
2566
            [2] = { /* .debug_info */
2567
                .sh_type = SHT_PROGBITS,
2568
                .sh_offset = offsetof(struct ElfImage, di),
2569
                .sh_size = sizeof(struct DebugInfo),
2570
            },
2571
            [3] = { /* .debug_abbrev */
2572
                .sh_type = SHT_PROGBITS,
2573
                .sh_offset = offsetof(struct ElfImage, da),
2574
                .sh_size = sizeof(img->da),
2575
            },
2576
            [4] = { /* .debug_frame */
2577
                .sh_type = SHT_PROGBITS,
2578
                .sh_offset = sizeof(struct ElfImage),
2579
            },
2580
            [5] = { /* .symtab */
2581
                .sh_type = SHT_SYMTAB,
2582
                .sh_offset = offsetof(struct ElfImage, sym),
2583
                .sh_size = sizeof(img->sym),
2584
                .sh_info = 1,
2585
                .sh_link = ARRAY_SIZE(img->shdr) - 1,
2586
                .sh_entsize = sizeof(ElfW(Sym)),
2587
            },
2588
            [6] = { /* .strtab */
2589
                .sh_type = SHT_STRTAB,
2590
                .sh_offset = offsetof(struct ElfImage, str),
2591
                .sh_size = sizeof(img->str),
2592
            }
2593
        },
2594
        .sym = {
2595
            [1] = { /* code_gen_buffer */
2596
                .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2597
                .st_shndx = 1,
2598
            }
2599
        },
2600
        .di = {
2601
            .len = sizeof(struct DebugInfo) - 4,
2602
            .version = 2,
2603
            .ptr_size = sizeof(void *),
2604
            .cu_die = 1,
2605
            .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
2606
            .fn_die = 2,
2607
            .fn_name = "code_gen_buffer"
2608
        },
2609
        .da = {
2610
            1,          /* abbrev number (the cu) */
2611
            0x11, 1,    /* DW_TAG_compile_unit, has children */
2612
            0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
2613
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2614
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2615
            0, 0,       /* end of abbrev */
2616
            2,          /* abbrev number (the fn) */
2617
            0x2e, 0,    /* DW_TAG_subprogram, no children */
2618
            0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
2619
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2620
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2621
            0, 0,       /* end of abbrev */
2622
            0           /* no more abbrev */
2623
        },
2624
        .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2625
               ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2626
    };
2627

    
2628
    /* We only need a single jit entry; statically allocate it.  */
2629
    static struct jit_code_entry one_entry;
2630

    
2631
    uintptr_t buf = (uintptr_t)buf_ptr;
2632
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2633

    
2634
    img = g_malloc(img_size);
2635
    *img = img_template;
2636
    memcpy(img + 1, debug_frame, debug_frame_size);
2637

    
2638
    img->phdr.p_vaddr = buf;
2639
    img->phdr.p_paddr = buf;
2640
    img->phdr.p_memsz = buf_size;
2641

    
2642
    img->shdr[1].sh_name = find_string(img->str, ".text");
2643
    img->shdr[1].sh_addr = buf;
2644
    img->shdr[1].sh_size = buf_size;
2645

    
2646
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2647
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2648

    
2649
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2650
    img->shdr[4].sh_size = debug_frame_size;
2651

    
2652
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2653
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2654

    
2655
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2656
    img->sym[1].st_value = buf;
2657
    img->sym[1].st_size = buf_size;
2658

    
2659
    img->di.cu_low_pc = buf;
2660
    img->di.cu_high_pc = buf + buf_size;
2661
    img->di.fn_low_pc = buf;
2662
    img->di.fn_high_pc = buf + buf_size;
2663

    
2664
#ifdef DEBUG_JIT
2665
    /* Enable this block to be able to debug the ELF image file creation.
2666
       One can use readelf, objdump, or other inspection utilities.  */
2667
    {
2668
        FILE *f = fopen("/tmp/qemu.jit", "w+b");
2669
        if (f) {
2670
            if (fwrite(img, img_size, 1, f) != img_size) {
2671
                /* Avoid stupid unused return value warning for fwrite.  */
2672
            }
2673
            fclose(f);
2674
        }
2675
    }
2676
#endif
2677

    
2678
    one_entry.symfile_addr = img;
2679
    one_entry.symfile_size = img_size;
2680

    
2681
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2682
    __jit_debug_descriptor.relevant_entry = &one_entry;
2683
    __jit_debug_descriptor.first_entry = &one_entry;
2684
    __jit_debug_register_code();
2685
}
2686
#else
2687
/* No support for the feature.  Provide the entry point expected by exec.c,
2688
   and implement the internal function we declared earlier.  */
2689

    
2690
static void tcg_register_jit_int(void *buf, size_t size,
2691
                                 void *debug_frame, size_t debug_frame_size)
2692
{
2693
}
2694

    
2695
void tcg_register_jit(void *buf, size_t buf_size)
2696
{
2697
}
2698
#endif /* ELF_HOST_MACHINE */