Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 1ff0a2c5

History | View | Annotate | Download (82.2 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 "cache-utils.h"
41
#include "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
/* XXX: move that inside the context */
100
uint16_t *gen_opc_ptr;
101
TCGArg *gen_opparam_ptr;
102

    
103
static inline void tcg_out8(TCGContext *s, uint8_t v)
104
{
105
    *s->code_ptr++ = v;
106
}
107

    
108
static inline void tcg_out16(TCGContext *s, uint16_t v)
109
{
110
    *(uint16_t *)s->code_ptr = v;
111
    s->code_ptr += 2;
112
}
113

    
114
static inline void tcg_out32(TCGContext *s, uint32_t v)
115
{
116
    *(uint32_t *)s->code_ptr = v;
117
    s->code_ptr += 4;
118
}
119

    
120
/* label relocation processing */
121

    
122
static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
123
                          int label_index, long addend)
124
{
125
    TCGLabel *l;
126
    TCGRelocation *r;
127

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

    
145
static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
146
{
147
    TCGLabel *l;
148
    TCGRelocation *r;
149
    tcg_target_long value = (tcg_target_long)ptr;
150

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

    
163
int gen_new_label(void)
164
{
165
    TCGContext *s = &tcg_ctx;
166
    int idx;
167
    TCGLabel *l;
168

    
169
    if (s->nb_labels >= TCG_MAX_LABELS)
170
        tcg_abort();
171
    idx = s->nb_labels++;
172
    l = &s->labels[idx];
173
    l->has_value = 0;
174
    l->u.first_reloc = NULL;
175
    return idx;
176
}
177

    
178
#include "tcg-target.c"
179

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

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

    
233
void tcg_context_init(TCGContext *s)
234
{
235
    int op, total_args, n;
236
    TCGOpDef *def;
237
    TCGArgConstraint *args_ct;
238
    int *sorted_args;
239

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

    
252
    args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
253
    sorted_args = g_malloc(sizeof(int) * total_args);
254

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

    
267
void tcg_prologue_init(TCGContext *s)
268
{
269
    /* init global prologue and epilogue */
270
    s->code_buf = code_gen_prologue;
271
    s->code_ptr = s->code_buf;
272
    tcg_target_qemu_prologue(s);
273
    flush_icache_range((tcg_target_ulong)s->code_buf,
274
                       (tcg_target_ulong)s->code_ptr);
275
}
276

    
277
void tcg_set_frame(TCGContext *s, int reg,
278
                   tcg_target_long start, tcg_target_long size)
279
{
280
    s->frame_start = start;
281
    s->frame_end = start + size;
282
    s->frame_reg = reg;
283
}
284

    
285
void tcg_func_start(TCGContext *s)
286
{
287
    int i;
288
    tcg_pool_reset(s);
289
    s->nb_temps = s->nb_globals;
290
    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
291
        s->first_free_temp[i] = -1;
292
    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
293
    s->nb_labels = 0;
294
    s->current_frame_offset = s->frame_start;
295

    
296
#ifdef CONFIG_DEBUG_TCG
297
    s->goto_tb_issue_mask = 0;
298
#endif
299

    
300
    s->gen_opc_ptr = s->gen_opc_buf;
301
    s->gen_opparam_ptr = s->gen_opparam_buf;
302

    
303
#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
304
    /* Initialize qemu_ld/st labels to assist code generation at the end of TB
305
       for TLB miss cases at the end of TB */
306
    s->qemu_ldst_labels = tcg_malloc(sizeof(TCGLabelQemuLdst) *
307
                                     TCG_MAX_QEMU_LDST);
308
    s->nb_qemu_ldst_labels = 0;
309
#endif
310
}
311

    
312
static inline void tcg_temp_alloc(TCGContext *s, int n)
313
{
314
    if (n > TCG_MAX_TEMPS)
315
        tcg_abort();
316
}
317

    
318
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
319
                                              const char *name)
320
{
321
    TCGContext *s = &tcg_ctx;
322
    TCGTemp *ts;
323
    int idx;
324

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

    
344
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
345
{
346
    int idx;
347

    
348
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
349
    return MAKE_TCGV_I32(idx);
350
}
351

    
352
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
353
{
354
    int idx;
355

    
356
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
357
    return MAKE_TCGV_I64(idx);
358
}
359

    
360
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
361
                                              tcg_target_long offset,
362
                                              const char *name)
363
{
364
    TCGContext *s = &tcg_ctx;
365
    TCGTemp *ts;
366
    int idx;
367

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

    
389
        ts->base_type = type;
390
        ts->type = TCG_TYPE_I32;
391
        ts->fixed_reg = 0;
392
        ts->mem_allocated = 1;
393
        ts->mem_reg = reg;
394
#ifdef TCG_TARGET_WORDS_BIGENDIAN
395
        ts->mem_offset = offset;
396
#else
397
        ts->mem_offset = offset + 4;
398
#endif
399
        pstrcpy(buf, sizeof(buf), name);
400
        pstrcat(buf, sizeof(buf), "_1");
401
        ts->name = strdup(buf);
402

    
403
        s->nb_globals += 2;
404
    } else
405
#endif
406
    {
407
        tcg_temp_alloc(s, s->nb_globals + 1);
408
        ts = &s->temps[s->nb_globals];
409
        ts->base_type = type;
410
        ts->type = type;
411
        ts->fixed_reg = 0;
412
        ts->mem_allocated = 1;
413
        ts->mem_reg = reg;
414
        ts->mem_offset = offset;
415
        ts->name = name;
416
        s->nb_globals++;
417
    }
418
    return idx;
419
}
420

    
421
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
422
                                const char *name)
423
{
424
    int idx;
425

    
426
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
427
    return MAKE_TCGV_I32(idx);
428
}
429

    
430
TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
431
                                const char *name)
432
{
433
    int idx;
434

    
435
    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
436
    return MAKE_TCGV_I64(idx);
437
}
438

    
439
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
440
{
441
    TCGContext *s = &tcg_ctx;
442
    TCGTemp *ts;
443
    int idx, k;
444

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

    
488
#if defined(CONFIG_DEBUG_TCG)
489
    s->temps_in_use++;
490
#endif
491
    return idx;
492
}
493

    
494
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
495
{
496
    int idx;
497

    
498
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
499
    return MAKE_TCGV_I32(idx);
500
}
501

    
502
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
503
{
504
    int idx;
505

    
506
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
507
    return MAKE_TCGV_I64(idx);
508
}
509

    
510
static inline void tcg_temp_free_internal(int idx)
511
{
512
    TCGContext *s = &tcg_ctx;
513
    TCGTemp *ts;
514
    int k;
515

    
516
#if defined(CONFIG_DEBUG_TCG)
517
    s->temps_in_use--;
518
    if (s->temps_in_use < 0) {
519
        fprintf(stderr, "More temporaries freed than allocated!\n");
520
    }
521
#endif
522

    
523
    assert(idx >= s->nb_globals && idx < s->nb_temps);
524
    ts = &s->temps[idx];
525
    assert(ts->temp_allocated != 0);
526
    ts->temp_allocated = 0;
527
    k = ts->base_type;
528
    if (ts->temp_local)
529
        k += TCG_TYPE_COUNT;
530
    ts->next_free_temp = s->first_free_temp[k];
531
    s->first_free_temp[k] = idx;
532
}
533

    
534
void tcg_temp_free_i32(TCGv_i32 arg)
535
{
536
    tcg_temp_free_internal(GET_TCGV_I32(arg));
537
}
538

    
539
void tcg_temp_free_i64(TCGv_i64 arg)
540
{
541
    tcg_temp_free_internal(GET_TCGV_I64(arg));
542
}
543

    
544
TCGv_i32 tcg_const_i32(int32_t val)
545
{
546
    TCGv_i32 t0;
547
    t0 = tcg_temp_new_i32();
548
    tcg_gen_movi_i32(t0, val);
549
    return t0;
550
}
551

    
552
TCGv_i64 tcg_const_i64(int64_t val)
553
{
554
    TCGv_i64 t0;
555
    t0 = tcg_temp_new_i64();
556
    tcg_gen_movi_i64(t0, val);
557
    return t0;
558
}
559

    
560
TCGv_i32 tcg_const_local_i32(int32_t val)
561
{
562
    TCGv_i32 t0;
563
    t0 = tcg_temp_local_new_i32();
564
    tcg_gen_movi_i32(t0, val);
565
    return t0;
566
}
567

    
568
TCGv_i64 tcg_const_local_i64(int64_t val)
569
{
570
    TCGv_i64 t0;
571
    t0 = tcg_temp_local_new_i64();
572
    tcg_gen_movi_i64(t0, val);
573
    return t0;
574
}
575

    
576
#if defined(CONFIG_DEBUG_TCG)
577
void tcg_clear_temp_count(void)
578
{
579
    TCGContext *s = &tcg_ctx;
580
    s->temps_in_use = 0;
581
}
582

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

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

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

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

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

    
700
        *s->gen_opparam_ptr++ = args[i];
701
        real_args++;
702
    }
703
    *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
704

    
705
    *s->gen_opparam_ptr++ = flags;
706

    
707
    *nparam = (nb_rets << 16) | (real_args + 1);
708

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

    
712
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
713
    for (i = 0; i < nargs; ++i) {
714
        int is_64bit = sizemask & (1 << (i+1)*2);
715
        if (!is_64bit) {
716
            TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
717
            tcg_temp_free_i64(temp);
718
        }
719
    }
720
#endif /* TCG_TARGET_EXTEND_ARGS */
721
}
722

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

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

    
772

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

    
800
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
801
                                 int idx)
802
{
803
    TCGTemp *ts;
804

    
805
    assert(idx >= 0 && idx < s->nb_temps);
806
    ts = &s->temps[idx];
807
    assert(ts);
808
    if (idx < s->nb_globals) {
809
        pstrcpy(buf, buf_size, ts->name);
810
    } else {
811
        if (ts->temp_local) 
812
            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
813
        else
814
            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
815
    }
816
    return buf;
817
}
818

    
819
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
820
{
821
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
822
}
823

    
824
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
825
{
826
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
827
}
828

    
829
static int helper_cmp(const void *p1, const void *p2)
830
{
831
    const TCGHelperInfo *th1 = p1;
832
    const TCGHelperInfo *th2 = p2;
833
    if (th1->func < th2->func)
834
        return -1;
835
    else if (th1->func == th2->func)
836
        return 0;
837
    else
838
        return 1;
839
}
840

    
841
/* find helper definition (Note: A hash table would be better) */
842
static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
843
{
844
    int m, m_min, m_max;
845
    TCGHelperInfo *th;
846
    tcg_target_ulong v;
847

    
848
    if (unlikely(!s->helpers_sorted)) {
849
        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
850
              helper_cmp);
851
        s->helpers_sorted = 1;
852
    }
853

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

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

    
888
void tcg_dump_ops(TCGContext *s)
889
{
890
    const uint16_t *opc_ptr;
891
    const TCGArg *args;
892
    TCGArg arg;
893
    TCGOpcode c;
894
    int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
895
    const TCGOpDef *def;
896
    char buf[128];
897

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

    
922
            /* variable number of arguments */
923
            arg = *args++;
924
            nb_oargs = arg >> 16;
925
            nb_iargs = arg & 0xffff;
926
            nb_cargs = def->nb_cargs;
927

    
928
            qemu_log(" %s ", def->name);
929

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

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

    
1033
/* we give more priority to constraints with less registers */
1034
static int get_constraint_priority(const TCGOpDef *def, int k)
1035
{
1036
    const TCGArgConstraint *arg_ct;
1037

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

    
1055
/* sort from highest priority to lowest */
1056
static void sort_constraints(TCGOpDef *def, int start, int n)
1057
{
1058
    int i, j, p1, p2, tmp;
1059

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

    
1077
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1078
{
1079
    TCGOpcode op;
1080
    TCGOpDef *def;
1081
    const char *ct_str;
1082
    int i, nb_args;
1083

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

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

    
1137
        /* sort the constraints (XXX: this is just an heuristic) */
1138
        sort_constraints(def, 0, def->nb_oargs);
1139
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1140

    
1141
#if 0
1142
        {
1143
            int i;
1144

1145
            printf("%s: sorted=", def->name);
1146
            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1147
                printf(" %d", def->sorted_args[i]);
1148
            printf("\n");
1149
        }
1150
#endif
1151
        tdefs++;
1152
    }
1153

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

    
1180
#ifdef USE_LIVENESS_ANALYSIS
1181

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

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

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

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

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

    
1234
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1235

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

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

    
1253
                nb_args = args[-1];
1254
                args -= nb_args;
1255
                nb_iargs = args[0] & 0xffff;
1256
                nb_oargs = args[0] >> 16;
1257
                args++;
1258
                call_flags = args[nb_oargs + nb_iargs];
1259

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

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

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

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

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

    
1361
        case INDEX_op_mulu2_i32:
1362
            args -= 4;
1363
            nb_iargs = 2;
1364
            nb_oargs = 2;
1365
            /* Likewise, test for the high part of the operation dead.  */
1366
            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1367
                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1368
                    goto do_remove;
1369
                }
1370
                s->gen_opc_buf[op_index] = op = INDEX_op_mul_i32;
1371
                args[1] = args[2];
1372
                args[2] = args[3];
1373
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1374
                tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1375
                /* Fall through and mark the single-word operation live.  */
1376
                nb_oargs = 1;
1377
            }
1378
            goto do_not_remove;
1379

    
1380
        default:
1381
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1382
            args -= def->nb_args;
1383
            nb_iargs = def->nb_iargs;
1384
            nb_oargs = def->nb_oargs;
1385

    
1386
            /* Test if the operation can be removed because all
1387
               its outputs are dead. We assume that nb_oargs == 0
1388
               implies side effects */
1389
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1390
                for(i = 0; i < nb_oargs; i++) {
1391
                    arg = args[i];
1392
                    if (!dead_temps[arg] || mem_temps[arg]) {
1393
                        goto do_not_remove;
1394
                    }
1395
                }
1396
            do_remove:
1397
                tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
1398
#ifdef CONFIG_PROFILER
1399
                s->del_op_count++;
1400
#endif
1401
            } else {
1402
            do_not_remove:
1403

    
1404
                /* output args are dead */
1405
                dead_args = 0;
1406
                sync_args = 0;
1407
                for(i = 0; i < nb_oargs; i++) {
1408
                    arg = args[i];
1409
                    if (dead_temps[arg]) {
1410
                        dead_args |= (1 << i);
1411
                    }
1412
                    if (mem_temps[arg]) {
1413
                        sync_args |= (1 << i);
1414
                    }
1415
                    dead_temps[arg] = 1;
1416
                    mem_temps[arg] = 0;
1417
                }
1418

    
1419
                /* if end of basic block, update */
1420
                if (def->flags & TCG_OPF_BB_END) {
1421
                    tcg_la_bb_end(s, dead_temps, mem_temps);
1422
                } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1423
                    /* globals should be synced to memory */
1424
                    memset(mem_temps, 1, s->nb_globals);
1425
                }
1426

    
1427
                /* input args are live */
1428
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1429
                    arg = args[i];
1430
                    if (dead_temps[arg]) {
1431
                        dead_args |= (1 << i);
1432
                    }
1433
                    dead_temps[arg] = 0;
1434
                }
1435
                s->op_dead_args[op_index] = dead_args;
1436
                s->op_sync_args[op_index] = sync_args;
1437
            }
1438
            break;
1439
        }
1440
        op_index--;
1441
    }
1442

    
1443
    if (args != s->gen_opparam_buf) {
1444
        tcg_abort();
1445
    }
1446
}
1447
#else
1448
/* dummy liveness analysis */
1449
static void tcg_liveness_analysis(TCGContext *s)
1450
{
1451
    int nb_ops;
1452
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1453

    
1454
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1455
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1456
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1457
    memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1458
}
1459
#endif
1460

    
1461
#ifndef NDEBUG
1462
static void dump_regs(TCGContext *s)
1463
{
1464
    TCGTemp *ts;
1465
    int i;
1466
    char buf[64];
1467

    
1468
    for(i = 0; i < s->nb_temps; i++) {
1469
        ts = &s->temps[i];
1470
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1471
        switch(ts->val_type) {
1472
        case TEMP_VAL_REG:
1473
            printf("%s", tcg_target_reg_names[ts->reg]);
1474
            break;
1475
        case TEMP_VAL_MEM:
1476
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1477
            break;
1478
        case TEMP_VAL_CONST:
1479
            printf("$0x%" TCG_PRIlx, ts->val);
1480
            break;
1481
        case TEMP_VAL_DEAD:
1482
            printf("D");
1483
            break;
1484
        default:
1485
            printf("???");
1486
            break;
1487
        }
1488
        printf("\n");
1489
    }
1490

    
1491
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1492
        if (s->reg_to_temp[i] >= 0) {
1493
            printf("%s: %s\n", 
1494
                   tcg_target_reg_names[i], 
1495
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1496
        }
1497
    }
1498
}
1499

    
1500
static void check_regs(TCGContext *s)
1501
{
1502
    int reg, k;
1503
    TCGTemp *ts;
1504
    char buf[64];
1505

    
1506
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1507
        k = s->reg_to_temp[reg];
1508
        if (k >= 0) {
1509
            ts = &s->temps[k];
1510
            if (ts->val_type != TEMP_VAL_REG ||
1511
                ts->reg != reg) {
1512
                printf("Inconsistency for register %s:\n", 
1513
                       tcg_target_reg_names[reg]);
1514
                goto fail;
1515
            }
1516
        }
1517
    }
1518
    for(k = 0; k < s->nb_temps; k++) {
1519
        ts = &s->temps[k];
1520
        if (ts->val_type == TEMP_VAL_REG &&
1521
            !ts->fixed_reg &&
1522
            s->reg_to_temp[ts->reg] != k) {
1523
                printf("Inconsistency for temp %s:\n", 
1524
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1525
        fail:
1526
                printf("reg state:\n");
1527
                dump_regs(s);
1528
                tcg_abort();
1529
        }
1530
    }
1531
}
1532
#endif
1533

    
1534
static void temp_allocate_frame(TCGContext *s, int temp)
1535
{
1536
    TCGTemp *ts;
1537
    ts = &s->temps[temp];
1538
#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1539
    /* Sparc64 stack is accessed with offset of 2047 */
1540
    s->current_frame_offset = (s->current_frame_offset +
1541
                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
1542
        ~(sizeof(tcg_target_long) - 1);
1543
#endif
1544
    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1545
        s->frame_end) {
1546
        tcg_abort();
1547
    }
1548
    ts->mem_offset = s->current_frame_offset;
1549
    ts->mem_reg = s->frame_reg;
1550
    ts->mem_allocated = 1;
1551
    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1552
}
1553

    
1554
/* sync register 'reg' by saving it to the corresponding temporary */
1555
static inline void tcg_reg_sync(TCGContext *s, int reg)
1556
{
1557
    TCGTemp *ts;
1558
    int temp;
1559

    
1560
    temp = s->reg_to_temp[reg];
1561
    ts = &s->temps[temp];
1562
    assert(ts->val_type == TEMP_VAL_REG);
1563
    if (!ts->mem_coherent && !ts->fixed_reg) {
1564
        if (!ts->mem_allocated) {
1565
            temp_allocate_frame(s, temp);
1566
        }
1567
        tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1568
    }
1569
    ts->mem_coherent = 1;
1570
}
1571

    
1572
/* free register 'reg' by spilling the corresponding temporary if necessary */
1573
static void tcg_reg_free(TCGContext *s, int reg)
1574
{
1575
    int temp;
1576

    
1577
    temp = s->reg_to_temp[reg];
1578
    if (temp != -1) {
1579
        tcg_reg_sync(s, reg);
1580
        s->temps[temp].val_type = TEMP_VAL_MEM;
1581
        s->reg_to_temp[reg] = -1;
1582
    }
1583
}
1584

    
1585
/* Allocate a register belonging to reg1 & ~reg2 */
1586
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1587
{
1588
    int i, reg;
1589
    TCGRegSet reg_ct;
1590

    
1591
    tcg_regset_andnot(reg_ct, reg1, reg2);
1592

    
1593
    /* first try free registers */
1594
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1595
        reg = tcg_target_reg_alloc_order[i];
1596
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1597
            return reg;
1598
    }
1599

    
1600
    /* XXX: do better spill choice */
1601
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1602
        reg = tcg_target_reg_alloc_order[i];
1603
        if (tcg_regset_test_reg(reg_ct, reg)) {
1604
            tcg_reg_free(s, reg);
1605
            return reg;
1606
        }
1607
    }
1608

    
1609
    tcg_abort();
1610
}
1611

    
1612
/* mark a temporary as dead. */
1613
static inline void temp_dead(TCGContext *s, int temp)
1614
{
1615
    TCGTemp *ts;
1616

    
1617
    ts = &s->temps[temp];
1618
    if (!ts->fixed_reg) {
1619
        if (ts->val_type == TEMP_VAL_REG) {
1620
            s->reg_to_temp[ts->reg] = -1;
1621
        }
1622
        if (temp < s->nb_globals || (ts->temp_local && ts->mem_allocated)) {
1623
            ts->val_type = TEMP_VAL_MEM;
1624
        } else {
1625
            ts->val_type = TEMP_VAL_DEAD;
1626
        }
1627
    }
1628
}
1629

    
1630
/* sync a temporary to memory. 'allocated_regs' is used in case a
1631
   temporary registers needs to be allocated to store a constant. */
1632
static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1633
{
1634
    TCGTemp *ts;
1635

    
1636
    ts = &s->temps[temp];
1637
    if (!ts->fixed_reg) {
1638
        switch(ts->val_type) {
1639
        case TEMP_VAL_CONST:
1640
            ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1641
                                    allocated_regs);
1642
            ts->val_type = TEMP_VAL_REG;
1643
            s->reg_to_temp[ts->reg] = temp;
1644
            ts->mem_coherent = 0;
1645
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
1646
            /* fallthrough*/
1647
        case TEMP_VAL_REG:
1648
            tcg_reg_sync(s, ts->reg);
1649
            break;
1650
        case TEMP_VAL_DEAD:
1651
        case TEMP_VAL_MEM:
1652
            break;
1653
        default:
1654
            tcg_abort();
1655
        }
1656
    }
1657
}
1658

    
1659
/* save a temporary to memory. 'allocated_regs' is used in case a
1660
   temporary registers needs to be allocated to store a constant. */
1661
static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1662
{
1663
#ifdef USE_LIVENESS_ANALYSIS
1664
    /* The liveness analysis already ensures that globals are back
1665
       in memory. Keep an assert for safety. */
1666
    assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1667
#else
1668
    temp_sync(s, temp, allocated_regs);
1669
    temp_dead(s, temp);
1670
#endif
1671
}
1672

    
1673
/* save globals to their canonical location and assume they can be
1674
   modified be the following code. 'allocated_regs' is used in case a
1675
   temporary registers needs to be allocated to store a constant. */
1676
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1677
{
1678
    int i;
1679

    
1680
    for(i = 0; i < s->nb_globals; i++) {
1681
        temp_save(s, i, allocated_regs);
1682
    }
1683
}
1684

    
1685
/* sync globals to their canonical location and assume they can be
1686
   read by the following code. 'allocated_regs' is used in case a
1687
   temporary registers needs to be allocated to store a constant. */
1688
static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1689
{
1690
    int i;
1691

    
1692
    for (i = 0; i < s->nb_globals; i++) {
1693
#ifdef USE_LIVENESS_ANALYSIS
1694
        assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1695
               s->temps[i].mem_coherent);
1696
#else
1697
        temp_sync(s, i, allocated_regs);
1698
#endif
1699
    }
1700
}
1701

    
1702
/* at the end of a basic block, we assume all temporaries are dead and
1703
   all globals are stored at their canonical location. */
1704
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1705
{
1706
    TCGTemp *ts;
1707
    int i;
1708

    
1709
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1710
        ts = &s->temps[i];
1711
        if (ts->temp_local) {
1712
            temp_save(s, i, allocated_regs);
1713
        } else {
1714
#ifdef USE_LIVENESS_ANALYSIS
1715
            /* The liveness analysis already ensures that temps are dead.
1716
               Keep an assert for safety. */
1717
            assert(ts->val_type == TEMP_VAL_DEAD);
1718
#else
1719
            temp_dead(s, i);
1720
#endif
1721
        }
1722
    }
1723

    
1724
    save_globals(s, allocated_regs);
1725
}
1726

    
1727
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1728
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1729

    
1730
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1731
                               uint16_t dead_args, uint8_t sync_args)
1732
{
1733
    TCGTemp *ots;
1734
    tcg_target_ulong val;
1735

    
1736
    ots = &s->temps[args[0]];
1737
    val = args[1];
1738

    
1739
    if (ots->fixed_reg) {
1740
        /* for fixed registers, we do not do any constant
1741
           propagation */
1742
        tcg_out_movi(s, ots->type, ots->reg, val);
1743
    } else {
1744
        /* The movi is not explicitly generated here */
1745
        if (ots->val_type == TEMP_VAL_REG)
1746
            s->reg_to_temp[ots->reg] = -1;
1747
        ots->val_type = TEMP_VAL_CONST;
1748
        ots->val = val;
1749
    }
1750
    if (NEED_SYNC_ARG(0)) {
1751
        temp_sync(s, args[0], s->reserved_regs);
1752
    }
1753
    if (IS_DEAD_ARG(0)) {
1754
        temp_dead(s, args[0]);
1755
    }
1756
}
1757

    
1758
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1759
                              const TCGArg *args, uint16_t dead_args,
1760
                              uint8_t sync_args)
1761
{
1762
    TCGRegSet allocated_regs;
1763
    TCGTemp *ts, *ots;
1764
    const TCGArgConstraint *arg_ct, *oarg_ct;
1765

    
1766
    tcg_regset_set(allocated_regs, s->reserved_regs);
1767
    ots = &s->temps[args[0]];
1768
    ts = &s->temps[args[1]];
1769
    oarg_ct = &def->args_ct[0];
1770
    arg_ct = &def->args_ct[1];
1771

    
1772
    /* If the source value is not in a register, and we're going to be
1773
       forced to have it in a register in order to perform the copy,
1774
       then copy the SOURCE value into its own register first.  That way
1775
       we don't have to reload SOURCE the next time it is used. */
1776
    if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
1777
        || ts->val_type == TEMP_VAL_MEM) {
1778
        ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1779
        if (ts->val_type == TEMP_VAL_MEM) {
1780
            tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
1781
            ts->mem_coherent = 1;
1782
        } else if (ts->val_type == TEMP_VAL_CONST) {
1783
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
1784
        }
1785
        s->reg_to_temp[ts->reg] = args[1];
1786
        ts->val_type = TEMP_VAL_REG;
1787
    }
1788

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

    
1839
static void tcg_reg_alloc_op(TCGContext *s, 
1840
                             const TCGOpDef *def, TCGOpcode opc,
1841
                             const TCGArg *args, uint16_t dead_args,
1842
                             uint8_t sync_args)
1843
{
1844
    TCGRegSet allocated_regs;
1845
    int i, k, nb_iargs, nb_oargs, reg;
1846
    TCGArg arg;
1847
    const TCGArgConstraint *arg_ct;
1848
    TCGTemp *ts;
1849
    TCGArg new_args[TCG_MAX_OP_ARGS];
1850
    int const_args[TCG_MAX_OP_ARGS];
1851

    
1852
    nb_oargs = def->nb_oargs;
1853
    nb_iargs = def->nb_iargs;
1854

    
1855
    /* copy constants */
1856
    memcpy(new_args + nb_oargs + nb_iargs, 
1857
           args + nb_oargs + nb_iargs, 
1858
           sizeof(TCGArg) * def->nb_cargs);
1859

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

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

    
1982
    /* emit instruction */
1983
    tcg_out_op(s, opc, new_args, const_args);
1984
    
1985
    /* move the outputs in the correct register if needed */
1986
    for(i = 0; i < nb_oargs; i++) {
1987
        ts = &s->temps[args[i]];
1988
        reg = new_args[i];
1989
        if (ts->fixed_reg && ts->reg != reg) {
1990
            tcg_out_mov(s, ts->type, ts->reg, reg);
1991
        }
1992
        if (NEED_SYNC_ARG(i)) {
1993
            tcg_reg_sync(s, reg);
1994
        }
1995
        if (IS_DEAD_ARG(i)) {
1996
            temp_dead(s, args[i]);
1997
        }
1998
    }
1999
}
2000

    
2001
#ifdef TCG_TARGET_STACK_GROWSUP
2002
#define STACK_DIR(x) (-(x))
2003
#else
2004
#define STACK_DIR(x) (x)
2005
#endif
2006

    
2007
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
2008
                              TCGOpcode opc, const TCGArg *args,
2009
                              uint16_t dead_args, uint8_t sync_args)
2010
{
2011
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2012
    TCGArg arg, func_arg;
2013
    TCGTemp *ts;
2014
    tcg_target_long stack_offset, call_stack_size, func_addr;
2015
    int const_func_arg, allocate_args;
2016
    TCGRegSet allocated_regs;
2017
    const TCGArgConstraint *arg_ct;
2018

    
2019
    arg = *args++;
2020

    
2021
    nb_oargs = arg >> 16;
2022
    nb_iargs = arg & 0xffff;
2023
    nb_params = nb_iargs - 1;
2024

    
2025
    flags = args[nb_oargs + nb_iargs];
2026

    
2027
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2028
    if (nb_regs > nb_params)
2029
        nb_regs = nb_params;
2030

    
2031
    /* assign stack slots first */
2032
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2033
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
2034
        ~(TCG_TARGET_STACK_ALIGN - 1);
2035
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2036
    if (allocate_args) {
2037
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2038
           preallocate call stack */
2039
        tcg_abort();
2040
    }
2041

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

    
2145
    /* Save globals if they might be written by the helper, sync them if
2146
       they might be read. */
2147
    if (flags & TCG_CALL_NO_READ_GLOBALS) {
2148
        /* Nothing to do */
2149
    } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2150
        sync_globals(s, allocated_regs);
2151
    } else {
2152
        save_globals(s, allocated_regs);
2153
    }
2154

    
2155
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2156

    
2157
    /* assign output registers and emit moves if needed */
2158
    for(i = 0; i < nb_oargs; i++) {
2159
        arg = args[i];
2160
        ts = &s->temps[arg];
2161
        reg = tcg_target_call_oarg_regs[i];
2162
        assert(s->reg_to_temp[reg] == -1);
2163
        if (ts->fixed_reg) {
2164
            if (ts->reg != reg) {
2165
                tcg_out_mov(s, ts->type, ts->reg, reg);
2166
            }
2167
        } else {
2168
            if (ts->val_type == TEMP_VAL_REG) {
2169
                s->reg_to_temp[ts->reg] = -1;
2170
            }
2171
            ts->val_type = TEMP_VAL_REG;
2172
            ts->reg = reg;
2173
            ts->mem_coherent = 0;
2174
            s->reg_to_temp[reg] = arg;
2175
            if (NEED_SYNC_ARG(i)) {
2176
                tcg_reg_sync(s, reg);
2177
            }
2178
            if (IS_DEAD_ARG(i)) {
2179
                temp_dead(s, args[i]);
2180
            }
2181
        }
2182
    }
2183
    
2184
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2185
}
2186

    
2187
#ifdef CONFIG_PROFILER
2188

    
2189
static int64_t tcg_table_op_count[NB_OPS];
2190

    
2191
static void dump_op_count(void)
2192
{
2193
    int i;
2194
    FILE *f;
2195
    f = fopen("/tmp/op.log", "w");
2196
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2197
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2198
    }
2199
    fclose(f);
2200
}
2201
#endif
2202

    
2203

    
2204
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2205
                                      long search_pc)
2206
{
2207
    TCGOpcode opc;
2208
    int op_index;
2209
    const TCGOpDef *def;
2210
    const TCGArg *args;
2211

    
2212
#ifdef DEBUG_DISAS
2213
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2214
        qemu_log("OP:\n");
2215
        tcg_dump_ops(s);
2216
        qemu_log("\n");
2217
    }
2218
#endif
2219

    
2220
#ifdef CONFIG_PROFILER
2221
    s->opt_time -= profile_getclock();
2222
#endif
2223

    
2224
#ifdef USE_TCG_OPTIMIZATIONS
2225
    s->gen_opparam_ptr =
2226
        tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2227
#endif
2228

    
2229
#ifdef CONFIG_PROFILER
2230
    s->opt_time += profile_getclock();
2231
    s->la_time -= profile_getclock();
2232
#endif
2233

    
2234
    tcg_liveness_analysis(s);
2235

    
2236
#ifdef CONFIG_PROFILER
2237
    s->la_time += profile_getclock();
2238
#endif
2239

    
2240
#ifdef DEBUG_DISAS
2241
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2242
        qemu_log("OP after optimization and liveness analysis:\n");
2243
        tcg_dump_ops(s);
2244
        qemu_log("\n");
2245
    }
2246
#endif
2247

    
2248
    tcg_reg_alloc_start(s);
2249

    
2250
    s->code_buf = gen_code_buf;
2251
    s->code_ptr = gen_code_buf;
2252

    
2253
    args = s->gen_opparam_buf;
2254
    op_index = 0;
2255

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

    
2333
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2334
{
2335
#ifdef CONFIG_PROFILER
2336
    {
2337
        int n;
2338
        n = (s->gen_opc_ptr - s->gen_opc_buf);
2339
        s->op_count += n;
2340
        if (n > s->op_count_max)
2341
            s->op_count_max = n;
2342

    
2343
        s->temp_count += s->nb_temps;
2344
        if (s->nb_temps > s->temp_count_max)
2345
            s->temp_count_max = s->nb_temps;
2346
    }
2347
#endif
2348

    
2349
    tcg_gen_code_common(s, gen_code_buf, -1);
2350

    
2351
    /* flush instruction cache */
2352
    flush_icache_range((tcg_target_ulong)gen_code_buf,
2353
                       (tcg_target_ulong)s->code_ptr);
2354

    
2355
    return s->code_ptr -  gen_code_buf;
2356
}
2357

    
2358
/* Return the index of the micro operation such as the pc after is <
2359
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2360
   not be changed, though writing the same values is ok.
2361
   Return -1 if not found. */
2362
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2363
{
2364
    return tcg_gen_code_common(s, gen_code_buf, offset);
2365
}
2366

    
2367
#ifdef CONFIG_PROFILER
2368
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2369
{
2370
    TCGContext *s = &tcg_ctx;
2371
    int64_t tot;
2372

    
2373
    tot = s->interm_time + s->code_time;
2374
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2375
                tot, tot / 2.4e9);
2376
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2377
                s->tb_count, 
2378
                s->tb_count1 - s->tb_count,
2379
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2380
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2381
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2382
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2383
                s->tb_count ? 
2384
                (double)s->del_op_count / s->tb_count : 0);
2385
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2386
                s->tb_count ? 
2387
                (double)s->temp_count / s->tb_count : 0,
2388
                s->temp_count_max);
2389
    
2390
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2391
                s->op_count ? (double)tot / s->op_count : 0);
2392
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2393
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2394
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2395
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2396
    if (tot == 0)
2397
        tot = 1;
2398
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2399
                (double)s->interm_time / tot * 100.0);
2400
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2401
                (double)s->code_time / tot * 100.0);
2402
    cpu_fprintf(f, "optim./code time    %0.1f%%\n",
2403
                (double)s->opt_time / (s->code_time ? s->code_time : 1)
2404
                * 100.0);
2405
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2406
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2407
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2408
                s->restore_count);
2409
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2410
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2411

    
2412
    dump_op_count();
2413
}
2414
#else
2415
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2416
{
2417
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2418
}
2419
#endif
2420

    
2421
#ifdef ELF_HOST_MACHINE
2422
/* In order to use this feature, the backend needs to do three things:
2423

2424
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2425
       put into the ELF image and to indicate support for the feature.
2426

2427
   (2) Define tcg_register_jit.  This should create a buffer containing
2428
       the contents of a .debug_frame section that describes the post-
2429
       prologue unwind info for the tcg machine.
2430

2431
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2432
*/
2433

    
2434
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2435
typedef enum {
2436
    JIT_NOACTION = 0,
2437
    JIT_REGISTER_FN,
2438
    JIT_UNREGISTER_FN
2439
} jit_actions_t;
2440

    
2441
struct jit_code_entry {
2442
    struct jit_code_entry *next_entry;
2443
    struct jit_code_entry *prev_entry;
2444
    const void *symfile_addr;
2445
    uint64_t symfile_size;
2446
};
2447

    
2448
struct jit_descriptor {
2449
    uint32_t version;
2450
    uint32_t action_flag;
2451
    struct jit_code_entry *relevant_entry;
2452
    struct jit_code_entry *first_entry;
2453
};
2454

    
2455
void __jit_debug_register_code(void) __attribute__((noinline));
2456
void __jit_debug_register_code(void)
2457
{
2458
    asm("");
2459
}
2460

    
2461
/* Must statically initialize the version, because GDB may check
2462
   the version before we can set it.  */
2463
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2464

    
2465
/* End GDB interface.  */
2466

    
2467
static int find_string(const char *strtab, const char *str)
2468
{
2469
    const char *p = strtab + 1;
2470

    
2471
    while (1) {
2472
        if (strcmp(p, str) == 0) {
2473
            return p - strtab;
2474
        }
2475
        p += strlen(p) + 1;
2476
    }
2477
}
2478

    
2479
static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2480
                                 void *debug_frame, size_t debug_frame_size)
2481
{
2482
    struct __attribute__((packed)) DebugInfo {
2483
        uint32_t  len;
2484
        uint16_t  version;
2485
        uint32_t  abbrev;
2486
        uint8_t   ptr_size;
2487
        uint8_t   cu_die;
2488
        uint16_t  cu_lang;
2489
        uintptr_t cu_low_pc;
2490
        uintptr_t cu_high_pc;
2491
        uint8_t   fn_die;
2492
        char      fn_name[16];
2493
        uintptr_t fn_low_pc;
2494
        uintptr_t fn_high_pc;
2495
        uint8_t   cu_eoc;
2496
    };
2497

    
2498
    struct ElfImage {
2499
        ElfW(Ehdr) ehdr;
2500
        ElfW(Phdr) phdr;
2501
        ElfW(Shdr) shdr[7];
2502
        ElfW(Sym)  sym[2];
2503
        struct DebugInfo di;
2504
        uint8_t    da[24];
2505
        char       str[80];
2506
    };
2507

    
2508
    struct ElfImage *img;
2509

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

    
2613
    /* We only need a single jit entry; statically allocate it.  */
2614
    static struct jit_code_entry one_entry;
2615

    
2616
    uintptr_t buf = (uintptr_t)buf_ptr;
2617
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2618

    
2619
    img = g_malloc(img_size);
2620
    *img = img_template;
2621
    memcpy(img + 1, debug_frame, debug_frame_size);
2622

    
2623
    img->phdr.p_vaddr = buf;
2624
    img->phdr.p_paddr = buf;
2625
    img->phdr.p_memsz = buf_size;
2626

    
2627
    img->shdr[1].sh_name = find_string(img->str, ".text");
2628
    img->shdr[1].sh_addr = buf;
2629
    img->shdr[1].sh_size = buf_size;
2630

    
2631
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2632
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2633

    
2634
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2635
    img->shdr[4].sh_size = debug_frame_size;
2636

    
2637
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2638
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2639

    
2640
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2641
    img->sym[1].st_value = buf;
2642
    img->sym[1].st_size = buf_size;
2643

    
2644
    img->di.cu_low_pc = buf;
2645
    img->di.cu_high_pc = buf_size;
2646
    img->di.fn_low_pc = buf;
2647
    img->di.fn_high_pc = buf_size;
2648

    
2649
#ifdef DEBUG_JIT
2650
    /* Enable this block to be able to debug the ELF image file creation.
2651
       One can use readelf, objdump, or other inspection utilities.  */
2652
    {
2653
        FILE *f = fopen("/tmp/qemu.jit", "w+b");
2654
        if (f) {
2655
            if (fwrite(img, img_size, 1, f) != img_size) {
2656
                /* Avoid stupid unused return value warning for fwrite.  */
2657
            }
2658
            fclose(f);
2659
        }
2660
    }
2661
#endif
2662

    
2663
    one_entry.symfile_addr = img;
2664
    one_entry.symfile_size = img_size;
2665

    
2666
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2667
    __jit_debug_descriptor.relevant_entry = &one_entry;
2668
    __jit_debug_descriptor.first_entry = &one_entry;
2669
    __jit_debug_register_code();
2670
}
2671
#else
2672
/* No support for the feature.  Provide the entry point expected by exec.c,
2673
   and implement the internal function we declared earlier.  */
2674

    
2675
static void tcg_register_jit_int(void *buf, size_t size,
2676
                                 void *debug_frame, size_t debug_frame_size)
2677
{
2678
}
2679

    
2680
void tcg_register_jit(void *buf, size_t buf_size)
2681
{
2682
}
2683
#endif /* ELF_HOST_MACHINE */