Statistics
| Branch: | Revision:

root / tcg / tcg.c @ d1bdd3af

History | View | Annotate | Download (82.7 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 (op < INDEX_op_call
1164
            || op == INDEX_op_debug_insn_start
1165
            || (def->flags & TCG_OPF_NOT_PRESENT)) {
1166
            /* Wrong entry in op definitions? */
1167
            if (def->used) {
1168
                fprintf(stderr, "Invalid op definition for %s\n", def->name);
1169
                i = 1;
1170
            }
1171
        } else {
1172
            /* Missing entry in op definitions? */
1173
            if (!def->used) {
1174
                fprintf(stderr, "Missing op definition for %s\n", def->name);
1175
                i = 1;
1176
            }
1177
        }
1178
    }
1179
    if (i == 1) {
1180
        tcg_abort();
1181
    }
1182
#endif
1183
}
1184

    
1185
#ifdef USE_LIVENESS_ANALYSIS
1186

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

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

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

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

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

    
1239
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1240

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1608
    tcg_regset_andnot(reg_ct, reg1, reg2);
1609

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

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

    
1626
    tcg_abort();
1627
}
1628

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

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

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

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

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

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

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

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

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

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

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

    
1741
    save_globals(s, allocated_regs);
1742
}
1743

    
1744
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1745
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1746

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

    
1753
    ots = &s->temps[args[0]];
1754
    val = args[1];
1755

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

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

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

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

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

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

    
1869
    nb_oargs = def->nb_oargs;
1870
    nb_iargs = def->nb_iargs;
1871

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

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

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

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

    
2018
#ifdef TCG_TARGET_STACK_GROWSUP
2019
#define STACK_DIR(x) (-(x))
2020
#else
2021
#define STACK_DIR(x) (x)
2022
#endif
2023

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

    
2036
    arg = *args++;
2037

    
2038
    nb_oargs = arg >> 16;
2039
    nb_iargs = arg & 0xffff;
2040
    nb_params = nb_iargs - 1;
2041

    
2042
    flags = args[nb_oargs + nb_iargs];
2043

    
2044
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2045
    if (nb_regs > nb_params)
2046
        nb_regs = nb_params;
2047

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

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

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

    
2172
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2173

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

    
2204
#ifdef CONFIG_PROFILER
2205

    
2206
static int64_t tcg_table_op_count[NB_OPS];
2207

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

    
2220

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

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

    
2237
#ifdef CONFIG_PROFILER
2238
    s->opt_time -= profile_getclock();
2239
#endif
2240

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

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

    
2251
    tcg_liveness_analysis(s);
2252

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

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

    
2265
    tcg_reg_alloc_start(s);
2266

    
2267
    s->code_buf = gen_code_buf;
2268
    s->code_ptr = gen_code_buf;
2269

    
2270
    args = s->gen_opparam_buf;
2271
    op_index = 0;
2272

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

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

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

    
2366
    tcg_gen_code_common(s, gen_code_buf, -1);
2367

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

    
2372
    return s->code_ptr -  gen_code_buf;
2373
}
2374

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

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

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

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

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

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

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

2448
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2449
*/
2450

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

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

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

    
2472
void __jit_debug_register_code(void) __attribute__((noinline));
2473
void __jit_debug_register_code(void)
2474
{
2475
    asm("");
2476
}
2477

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

    
2482
/* End GDB interface.  */
2483

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

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

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

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

    
2525
    struct ElfImage *img;
2526

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

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

    
2633
    uintptr_t buf = (uintptr_t)buf_ptr;
2634
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2635

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

    
2640
    img->phdr.p_vaddr = buf;
2641
    img->phdr.p_paddr = buf;
2642
    img->phdr.p_memsz = buf_size;
2643

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

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

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

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

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

    
2661
    img->di.cu_low_pc = buf;
2662
    img->di.cu_high_pc = buf_size;
2663
    img->di.fn_low_pc = buf;
2664
    img->di.fn_high_pc = buf_size;
2665

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

    
2680
    one_entry.symfile_addr = img;
2681
    one_entry.symfile_size = img_size;
2682

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

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

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