Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 1de7afc9

History | View | Annotate | Download (82.1 kB)

1
/*
2
 * Tiny Code Generator for QEMU
3
 *
4
 * Copyright (c) 2008 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
/* define it to use liveness analysis (better code) */
26
#define USE_LIVENESS_ANALYSIS
27
#define USE_TCG_OPTIMIZATIONS
28

    
29
#include "config.h"
30

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

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

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

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

    
50
#include "tcg-op.h"
51

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

    
63
#include "elf.h"
64

    
65
/* Forward declarations for functions declared in tcg-target.c and used here. */
66
static void tcg_target_init(TCGContext *s);
67
static void tcg_target_qemu_prologue(TCGContext *s);
68
static void patch_reloc(uint8_t *code_ptr, int type, 
69
                        tcg_target_long value, tcg_target_long addend);
70

    
71
static void tcg_register_jit_int(void *buf, size_t size,
72
                                 void *debug_frame, size_t debug_frame_size)
73
    __attribute__((unused));
74

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

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

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

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

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

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

    
116
/* label relocation processing */
117

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

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

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

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

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

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

    
174
#include "tcg-target.c"
175

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

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

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

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

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

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

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

    
273
void tcg_set_frame(TCGContext *s, int reg,
274
                   tcg_target_long start, tcg_target_long size)
275
{
276
    s->frame_start = start;
277
    s->frame_end = start + size;
278
    s->frame_reg = reg;
279
}
280

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

    
292
#ifdef CONFIG_DEBUG_TCG
293
    s->goto_tb_issue_mask = 0;
294
#endif
295

    
296
    s->gen_opc_ptr = s->gen_opc_buf;
297
    s->gen_opparam_ptr = s->gen_opparam_buf;
298

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

    
308
static inline void tcg_temp_alloc(TCGContext *s, int n)
309
{
310
    if (n > TCG_MAX_TEMPS)
311
        tcg_abort();
312
}
313

    
314
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
315
                                              const char *name)
316
{
317
    TCGContext *s = &tcg_ctx;
318
    TCGTemp *ts;
319
    int idx;
320

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

    
340
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
341
{
342
    int idx;
343

    
344
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
345
    return MAKE_TCGV_I32(idx);
346
}
347

    
348
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
349
{
350
    int idx;
351

    
352
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
353
    return MAKE_TCGV_I64(idx);
354
}
355

    
356
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
357
                                              tcg_target_long offset,
358
                                              const char *name)
359
{
360
    TCGContext *s = &tcg_ctx;
361
    TCGTemp *ts;
362
    int idx;
363

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

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

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

    
417
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
418
                                const char *name)
419
{
420
    int idx;
421

    
422
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
423
    return MAKE_TCGV_I32(idx);
424
}
425

    
426
TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
427
                                const char *name)
428
{
429
    int idx;
430

    
431
    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
432
    return MAKE_TCGV_I64(idx);
433
}
434

    
435
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
436
{
437
    TCGContext *s = &tcg_ctx;
438
    TCGTemp *ts;
439
    int idx, k;
440

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

    
484
#if defined(CONFIG_DEBUG_TCG)
485
    s->temps_in_use++;
486
#endif
487
    return idx;
488
}
489

    
490
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
491
{
492
    int idx;
493

    
494
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
495
    return MAKE_TCGV_I32(idx);
496
}
497

    
498
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
499
{
500
    int idx;
501

    
502
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
503
    return MAKE_TCGV_I64(idx);
504
}
505

    
506
static inline void tcg_temp_free_internal(int idx)
507
{
508
    TCGContext *s = &tcg_ctx;
509
    TCGTemp *ts;
510
    int k;
511

    
512
#if defined(CONFIG_DEBUG_TCG)
513
    s->temps_in_use--;
514
    if (s->temps_in_use < 0) {
515
        fprintf(stderr, "More temporaries freed than allocated!\n");
516
    }
517
#endif
518

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

    
530
void tcg_temp_free_i32(TCGv_i32 arg)
531
{
532
    tcg_temp_free_internal(GET_TCGV_I32(arg));
533
}
534

    
535
void tcg_temp_free_i64(TCGv_i64 arg)
536
{
537
    tcg_temp_free_internal(GET_TCGV_I64(arg));
538
}
539

    
540
TCGv_i32 tcg_const_i32(int32_t val)
541
{
542
    TCGv_i32 t0;
543
    t0 = tcg_temp_new_i32();
544
    tcg_gen_movi_i32(t0, val);
545
    return t0;
546
}
547

    
548
TCGv_i64 tcg_const_i64(int64_t val)
549
{
550
    TCGv_i64 t0;
551
    t0 = tcg_temp_new_i64();
552
    tcg_gen_movi_i64(t0, val);
553
    return t0;
554
}
555

    
556
TCGv_i32 tcg_const_local_i32(int32_t val)
557
{
558
    TCGv_i32 t0;
559
    t0 = tcg_temp_local_new_i32();
560
    tcg_gen_movi_i32(t0, val);
561
    return t0;
562
}
563

    
564
TCGv_i64 tcg_const_local_i64(int64_t val)
565
{
566
    TCGv_i64 t0;
567
    t0 = tcg_temp_local_new_i64();
568
    tcg_gen_movi_i64(t0, val);
569
    return t0;
570
}
571

    
572
#if defined(CONFIG_DEBUG_TCG)
573
void tcg_clear_temp_count(void)
574
{
575
    TCGContext *s = &tcg_ctx;
576
    s->temps_in_use = 0;
577
}
578

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

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

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

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

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

    
696
        *s->gen_opparam_ptr++ = args[i];
697
        real_args++;
698
    }
699
    *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
700

    
701
    *s->gen_opparam_ptr++ = flags;
702

    
703
    *nparam = (nb_rets << 16) | (real_args + 1);
704

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

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

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

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

    
768

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

    
796
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
797
                                 int idx)
798
{
799
    TCGTemp *ts;
800

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

    
815
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
816
{
817
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
818
}
819

    
820
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
821
{
822
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
823
}
824

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

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

    
844
    if (unlikely(!s->helpers_sorted)) {
845
        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
846
              helper_cmp);
847
        s->helpers_sorted = 1;
848
    }
849

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

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

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

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

    
918
            /* variable number of arguments */
919
            arg = *args++;
920
            nb_oargs = arg >> 16;
921
            nb_iargs = arg & 0xffff;
922
            nb_cargs = def->nb_cargs;
923

    
924
            qemu_log(" %s ", def->name);
925

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

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

    
1029
/* we give more priority to constraints with less registers */
1030
static int get_constraint_priority(const TCGOpDef *def, int k)
1031
{
1032
    const TCGArgConstraint *arg_ct;
1033

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

    
1051
/* sort from highest priority to lowest */
1052
static void sort_constraints(TCGOpDef *def, int start, int n)
1053
{
1054
    int i, j, p1, p2, tmp;
1055

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

    
1073
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1074
{
1075
    TCGOpcode op;
1076
    TCGOpDef *def;
1077
    const char *ct_str;
1078
    int i, nb_args;
1079

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

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

    
1133
        /* sort the constraints (XXX: this is just an heuristic) */
1134
        sort_constraints(def, 0, def->nb_oargs);
1135
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1136

    
1137
#if 0
1138
        {
1139
            int i;
1140

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

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

    
1176
#ifdef USE_LIVENESS_ANALYSIS
1177

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

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

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

    
1208
    memset(dead_temps, 1, s->nb_temps);
1209
    memset(mem_temps, 1, s->nb_globals);
1210
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1211
        mem_temps[i] = s->temps[i].temp_local;
1212
    }
1213
}
1214

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

    
1230
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1231

    
1232
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1233
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1234
    
1235
    dead_temps = tcg_malloc(s->nb_temps);
1236
    mem_temps = tcg_malloc(s->nb_temps);
1237
    tcg_la_func_end(s, dead_temps, mem_temps);
1238

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

    
1249
                nb_args = args[-1];
1250
                args -= nb_args;
1251
                nb_iargs = args[0] & 0xffff;
1252
                nb_oargs = args[0] >> 16;
1253
                args++;
1254
                call_flags = args[nb_oargs + nb_iargs];
1255

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

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

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

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

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

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

    
1376
        default:
1377
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1378
            args -= def->nb_args;
1379
            nb_iargs = def->nb_iargs;
1380
            nb_oargs = def->nb_oargs;
1381

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

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

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

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

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

    
1450
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1451
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1452
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1453
    memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1454
}
1455
#endif
1456

    
1457
#ifndef NDEBUG
1458
static void dump_regs(TCGContext *s)
1459
{
1460
    TCGTemp *ts;
1461
    int i;
1462
    char buf[64];
1463

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

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

    
1496
static void check_regs(TCGContext *s)
1497
{
1498
    int reg, k;
1499
    TCGTemp *ts;
1500
    char buf[64];
1501

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

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

    
1550
/* sync register 'reg' by saving it to the corresponding temporary */
1551
static inline void tcg_reg_sync(TCGContext *s, int reg)
1552
{
1553
    TCGTemp *ts;
1554
    int temp;
1555

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

    
1568
/* free register 'reg' by spilling the corresponding temporary if necessary */
1569
static void tcg_reg_free(TCGContext *s, int reg)
1570
{
1571
    int temp;
1572

    
1573
    temp = s->reg_to_temp[reg];
1574
    if (temp != -1) {
1575
        tcg_reg_sync(s, reg);
1576
        s->temps[temp].val_type = TEMP_VAL_MEM;
1577
        s->reg_to_temp[reg] = -1;
1578
    }
1579
}
1580

    
1581
/* Allocate a register belonging to reg1 & ~reg2 */
1582
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1583
{
1584
    int i, reg;
1585
    TCGRegSet reg_ct;
1586

    
1587
    tcg_regset_andnot(reg_ct, reg1, reg2);
1588

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

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

    
1605
    tcg_abort();
1606
}
1607

    
1608
/* mark a temporary as dead. */
1609
static inline void temp_dead(TCGContext *s, int temp)
1610
{
1611
    TCGTemp *ts;
1612

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

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

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

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

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

    
1676
    for(i = 0; i < s->nb_globals; i++) {
1677
        temp_save(s, i, allocated_regs);
1678
    }
1679
}
1680

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

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

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

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

    
1720
    save_globals(s, allocated_regs);
1721
}
1722

    
1723
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1724
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1725

    
1726
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1727
                               uint16_t dead_args, uint8_t sync_args)
1728
{
1729
    TCGTemp *ots;
1730
    tcg_target_ulong val;
1731

    
1732
    ots = &s->temps[args[0]];
1733
    val = args[1];
1734

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

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

    
1762
    tcg_regset_set(allocated_regs, s->reserved_regs);
1763
    ots = &s->temps[args[0]];
1764
    ts = &s->temps[args[1]];
1765
    oarg_ct = &def->args_ct[0];
1766
    arg_ct = &def->args_ct[1];
1767

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

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

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

    
1848
    nb_oargs = def->nb_oargs;
1849
    nb_iargs = def->nb_iargs;
1850

    
1851
    /* copy constants */
1852
    memcpy(new_args + nb_oargs + nb_iargs, 
1853
           args + nb_oargs + nb_iargs, 
1854
           sizeof(TCGArg) * def->nb_cargs);
1855

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

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

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

    
1997
#ifdef TCG_TARGET_STACK_GROWSUP
1998
#define STACK_DIR(x) (-(x))
1999
#else
2000
#define STACK_DIR(x) (x)
2001
#endif
2002

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

    
2015
    arg = *args++;
2016

    
2017
    nb_oargs = arg >> 16;
2018
    nb_iargs = arg & 0xffff;
2019
    nb_params = nb_iargs - 1;
2020

    
2021
    flags = args[nb_oargs + nb_iargs];
2022

    
2023
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2024
    if (nb_regs > nb_params)
2025
        nb_regs = nb_params;
2026

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

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

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

    
2151
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2152

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

    
2183
#ifdef CONFIG_PROFILER
2184

    
2185
static int64_t tcg_table_op_count[NB_OPS];
2186

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

    
2199

    
2200
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2201
                                      long search_pc)
2202
{
2203
    TCGOpcode opc;
2204
    int op_index;
2205
    const TCGOpDef *def;
2206
    const TCGArg *args;
2207

    
2208
#ifdef DEBUG_DISAS
2209
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2210
        qemu_log("OP:\n");
2211
        tcg_dump_ops(s);
2212
        qemu_log("\n");
2213
    }
2214
#endif
2215

    
2216
#ifdef CONFIG_PROFILER
2217
    s->opt_time -= profile_getclock();
2218
#endif
2219

    
2220
#ifdef USE_TCG_OPTIMIZATIONS
2221
    s->gen_opparam_ptr =
2222
        tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2223
#endif
2224

    
2225
#ifdef CONFIG_PROFILER
2226
    s->opt_time += profile_getclock();
2227
    s->la_time -= profile_getclock();
2228
#endif
2229

    
2230
    tcg_liveness_analysis(s);
2231

    
2232
#ifdef CONFIG_PROFILER
2233
    s->la_time += profile_getclock();
2234
#endif
2235

    
2236
#ifdef DEBUG_DISAS
2237
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2238
        qemu_log("OP after optimization and liveness analysis:\n");
2239
        tcg_dump_ops(s);
2240
        qemu_log("\n");
2241
    }
2242
#endif
2243

    
2244
    tcg_reg_alloc_start(s);
2245

    
2246
    s->code_buf = gen_code_buf;
2247
    s->code_ptr = gen_code_buf;
2248

    
2249
    args = s->gen_opparam_buf;
2250
    op_index = 0;
2251

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

    
2329
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2330
{
2331
#ifdef CONFIG_PROFILER
2332
    {
2333
        int n;
2334
        n = (s->gen_opc_ptr - s->gen_opc_buf);
2335
        s->op_count += n;
2336
        if (n > s->op_count_max)
2337
            s->op_count_max = n;
2338

    
2339
        s->temp_count += s->nb_temps;
2340
        if (s->nb_temps > s->temp_count_max)
2341
            s->temp_count_max = s->nb_temps;
2342
    }
2343
#endif
2344

    
2345
    tcg_gen_code_common(s, gen_code_buf, -1);
2346

    
2347
    /* flush instruction cache */
2348
    flush_icache_range((tcg_target_ulong)gen_code_buf,
2349
                       (tcg_target_ulong)s->code_ptr);
2350

    
2351
    return s->code_ptr -  gen_code_buf;
2352
}
2353

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

    
2363
#ifdef CONFIG_PROFILER
2364
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2365
{
2366
    TCGContext *s = &tcg_ctx;
2367
    int64_t tot;
2368

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

    
2408
    dump_op_count();
2409
}
2410
#else
2411
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2412
{
2413
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2414
}
2415
#endif
2416

    
2417
#ifdef ELF_HOST_MACHINE
2418
/* In order to use this feature, the backend needs to do three things:
2419

2420
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2421
       put into the ELF image and to indicate support for the feature.
2422

2423
   (2) Define tcg_register_jit.  This should create a buffer containing
2424
       the contents of a .debug_frame section that describes the post-
2425
       prologue unwind info for the tcg machine.
2426

2427
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2428
*/
2429

    
2430
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2431
typedef enum {
2432
    JIT_NOACTION = 0,
2433
    JIT_REGISTER_FN,
2434
    JIT_UNREGISTER_FN
2435
} jit_actions_t;
2436

    
2437
struct jit_code_entry {
2438
    struct jit_code_entry *next_entry;
2439
    struct jit_code_entry *prev_entry;
2440
    const void *symfile_addr;
2441
    uint64_t symfile_size;
2442
};
2443

    
2444
struct jit_descriptor {
2445
    uint32_t version;
2446
    uint32_t action_flag;
2447
    struct jit_code_entry *relevant_entry;
2448
    struct jit_code_entry *first_entry;
2449
};
2450

    
2451
void __jit_debug_register_code(void) __attribute__((noinline));
2452
void __jit_debug_register_code(void)
2453
{
2454
    asm("");
2455
}
2456

    
2457
/* Must statically initialize the version, because GDB may check
2458
   the version before we can set it.  */
2459
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2460

    
2461
/* End GDB interface.  */
2462

    
2463
static int find_string(const char *strtab, const char *str)
2464
{
2465
    const char *p = strtab + 1;
2466

    
2467
    while (1) {
2468
        if (strcmp(p, str) == 0) {
2469
            return p - strtab;
2470
        }
2471
        p += strlen(p) + 1;
2472
    }
2473
}
2474

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

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

    
2504
    struct ElfImage *img;
2505

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

    
2609
    /* We only need a single jit entry; statically allocate it.  */
2610
    static struct jit_code_entry one_entry;
2611

    
2612
    uintptr_t buf = (uintptr_t)buf_ptr;
2613
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2614

    
2615
    img = g_malloc(img_size);
2616
    *img = img_template;
2617
    memcpy(img + 1, debug_frame, debug_frame_size);
2618

    
2619
    img->phdr.p_vaddr = buf;
2620
    img->phdr.p_paddr = buf;
2621
    img->phdr.p_memsz = buf_size;
2622

    
2623
    img->shdr[1].sh_name = find_string(img->str, ".text");
2624
    img->shdr[1].sh_addr = buf;
2625
    img->shdr[1].sh_size = buf_size;
2626

    
2627
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2628
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2629

    
2630
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2631
    img->shdr[4].sh_size = debug_frame_size;
2632

    
2633
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2634
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2635

    
2636
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2637
    img->sym[1].st_value = buf;
2638
    img->sym[1].st_size = buf_size;
2639

    
2640
    img->di.cu_low_pc = buf;
2641
    img->di.cu_high_pc = buf_size;
2642
    img->di.fn_low_pc = buf;
2643
    img->di.fn_high_pc = buf_size;
2644

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

    
2659
    one_entry.symfile_addr = img;
2660
    one_entry.symfile_size = img_size;
2661

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

    
2671
static void tcg_register_jit_int(void *buf, size_t size,
2672
                                 void *debug_frame, size_t debug_frame_size)
2673
{
2674
}
2675

    
2676
void tcg_register_jit(void *buf, size_t buf_size)
2677
{
2678
}
2679
#endif /* ELF_HOST_MACHINE */