Statistics
| Branch: | Revision:

root / tcg / tcg.c @ b3a1be87

History | View | Annotate | Download (81.5 kB)

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

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

    
29
#include "config.h"
30

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

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

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

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

    
50
#include "tcg-op.h"
51

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

    
63
#include "elf.h"
64

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

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

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

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

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

    
99
/* XXX: move that inside the context */
100
uint16_t *gen_opc_ptr;
101
TCGArg *gen_opparam_ptr;
102

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

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

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

    
120
/* label relocation processing */
121

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

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

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

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

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

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

    
178
#include "tcg-target.c"
179

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

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

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

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

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

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

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

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

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

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

    
300
    gen_opc_ptr = gen_opc_buf;
301
    gen_opparam_ptr = gen_opparam_buf;
302
}
303

    
304
static inline void tcg_temp_alloc(TCGContext *s, int n)
305
{
306
    if (n > TCG_MAX_TEMPS)
307
        tcg_abort();
308
}
309

    
310
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
311
                                              const char *name)
312
{
313
    TCGContext *s = &tcg_ctx;
314
    TCGTemp *ts;
315
    int idx;
316

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

    
336
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
337
{
338
    int idx;
339

    
340
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
341
    return MAKE_TCGV_I32(idx);
342
}
343

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

    
348
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
349
    return MAKE_TCGV_I64(idx);
350
}
351

    
352
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
353
                                              tcg_target_long offset,
354
                                              const char *name)
355
{
356
    TCGContext *s = &tcg_ctx;
357
    TCGTemp *ts;
358
    int idx;
359

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

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

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

    
413
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
414
                                const char *name)
415
{
416
    int idx;
417

    
418
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
419
    return MAKE_TCGV_I32(idx);
420
}
421

    
422
TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
423
                                const char *name)
424
{
425
    int idx;
426

    
427
    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
428
    return MAKE_TCGV_I64(idx);
429
}
430

    
431
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
432
{
433
    TCGContext *s = &tcg_ctx;
434
    TCGTemp *ts;
435
    int idx, k;
436

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

    
480
#if defined(CONFIG_DEBUG_TCG)
481
    s->temps_in_use++;
482
#endif
483
    return idx;
484
}
485

    
486
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
487
{
488
    int idx;
489

    
490
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
491
    return MAKE_TCGV_I32(idx);
492
}
493

    
494
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
495
{
496
    int idx;
497

    
498
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
499
    return MAKE_TCGV_I64(idx);
500
}
501

    
502
static inline void tcg_temp_free_internal(int idx)
503
{
504
    TCGContext *s = &tcg_ctx;
505
    TCGTemp *ts;
506
    int k;
507

    
508
#if defined(CONFIG_DEBUG_TCG)
509
    s->temps_in_use--;
510
    if (s->temps_in_use < 0) {
511
        fprintf(stderr, "More temporaries freed than allocated!\n");
512
    }
513
#endif
514

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

    
526
void tcg_temp_free_i32(TCGv_i32 arg)
527
{
528
    tcg_temp_free_internal(GET_TCGV_I32(arg));
529
}
530

    
531
void tcg_temp_free_i64(TCGv_i64 arg)
532
{
533
    tcg_temp_free_internal(GET_TCGV_I64(arg));
534
}
535

    
536
TCGv_i32 tcg_const_i32(int32_t val)
537
{
538
    TCGv_i32 t0;
539
    t0 = tcg_temp_new_i32();
540
    tcg_gen_movi_i32(t0, val);
541
    return t0;
542
}
543

    
544
TCGv_i64 tcg_const_i64(int64_t val)
545
{
546
    TCGv_i64 t0;
547
    t0 = tcg_temp_new_i64();
548
    tcg_gen_movi_i64(t0, val);
549
    return t0;
550
}
551

    
552
TCGv_i32 tcg_const_local_i32(int32_t val)
553
{
554
    TCGv_i32 t0;
555
    t0 = tcg_temp_local_new_i32();
556
    tcg_gen_movi_i32(t0, val);
557
    return t0;
558
}
559

    
560
TCGv_i64 tcg_const_local_i64(int64_t val)
561
{
562
    TCGv_i64 t0;
563
    t0 = tcg_temp_local_new_i64();
564
    tcg_gen_movi_i64(t0, val);
565
    return t0;
566
}
567

    
568
#if defined(CONFIG_DEBUG_TCG)
569
void tcg_clear_temp_count(void)
570
{
571
    TCGContext *s = &tcg_ctx;
572
    s->temps_in_use = 0;
573
}
574

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

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

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

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

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

    
692
        *gen_opparam_ptr++ = args[i];
693
        real_args++;
694
    }
695
    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
696

    
697
    *gen_opparam_ptr++ = flags;
698

    
699
    *nparam = (nb_rets << 16) | (real_args + 1);
700

    
701
    /* total parameters, needed to go backward in the instruction stream */
702
    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
703

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

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

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

    
764

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

    
792
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
793
                                 int idx)
794
{
795
    TCGTemp *ts;
796

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

    
811
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
812
{
813
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
814
}
815

    
816
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
817
{
818
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
819
}
820

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

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

    
840
    if (unlikely(!s->helpers_sorted)) {
841
        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
842
              helper_cmp);
843
        s->helpers_sorted = 1;
844
    }
845

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

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

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

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

    
914
            /* variable number of arguments */
915
            arg = *args++;
916
            nb_oargs = arg >> 16;
917
            nb_iargs = arg & 0xffff;
918
            nb_cargs = def->nb_cargs;
919

    
920
            qemu_log(" %s ", def->name);
921

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

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

    
1025
/* we give more priority to constraints with less registers */
1026
static int get_constraint_priority(const TCGOpDef *def, int k)
1027
{
1028
    const TCGArgConstraint *arg_ct;
1029

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

    
1047
/* sort from highest priority to lowest */
1048
static void sort_constraints(TCGOpDef *def, int start, int n)
1049
{
1050
    int i, j, p1, p2, tmp;
1051

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

    
1069
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1070
{
1071
    TCGOpcode op;
1072
    TCGOpDef *def;
1073
    const char *ct_str;
1074
    int i, nb_args;
1075

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

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

    
1129
        /* sort the constraints (XXX: this is just an heuristic) */
1130
        sort_constraints(def, 0, def->nb_oargs);
1131
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1132

    
1133
#if 0
1134
        {
1135
            int i;
1136

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

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

    
1172
#ifdef USE_LIVENESS_ANALYSIS
1173

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

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

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

    
1204
    memset(dead_temps, 1, s->nb_temps);
1205
    memset(mem_temps, 1, s->nb_globals);
1206
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1207
        mem_temps[i] = s->temps[i].temp_local;
1208
    }
1209
}
1210

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

    
1226
    nb_ops = gen_opc_ptr - gen_opc_buf;
1227

    
1228
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1229
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1230
    
1231
    dead_temps = tcg_malloc(s->nb_temps);
1232
    mem_temps = tcg_malloc(s->nb_temps);
1233
    tcg_la_func_end(s, dead_temps, mem_temps);
1234

    
1235
    args = gen_opparam_ptr;
1236
    op_index = nb_ops - 1;
1237
    while (op_index >= 0) {
1238
        op = gen_opc_buf[op_index];
1239
        def = &tcg_op_defs[op];
1240
        switch(op) {
1241
        case INDEX_op_call:
1242
            {
1243
                int call_flags;
1244

    
1245
                nb_args = args[-1];
1246
                args -= nb_args;
1247
                nb_iargs = args[0] & 0xffff;
1248
                nb_oargs = args[0] >> 16;
1249
                args++;
1250
                call_flags = args[nb_oargs + nb_iargs];
1251

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

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

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

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

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

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

    
1372
        default:
1373
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1374
            args -= def->nb_args;
1375
            nb_iargs = def->nb_iargs;
1376
            nb_oargs = def->nb_oargs;
1377

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

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

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

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

    
1435
    if (args != gen_opparam_buf)
1436
        tcg_abort();
1437
}
1438
#else
1439
/* dummy liveness analysis */
1440
static void tcg_liveness_analysis(TCGContext *s)
1441
{
1442
    int nb_ops;
1443
    nb_ops = gen_opc_ptr - gen_opc_buf;
1444

    
1445
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1446
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1447
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1448
    memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1449
}
1450
#endif
1451

    
1452
#ifndef NDEBUG
1453
static void dump_regs(TCGContext *s)
1454
{
1455
    TCGTemp *ts;
1456
    int i;
1457
    char buf[64];
1458

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

    
1482
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1483
        if (s->reg_to_temp[i] >= 0) {
1484
            printf("%s: %s\n", 
1485
                   tcg_target_reg_names[i], 
1486
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1487
        }
1488
    }
1489
}
1490

    
1491
static void check_regs(TCGContext *s)
1492
{
1493
    int reg, k;
1494
    TCGTemp *ts;
1495
    char buf[64];
1496

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

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

    
1545
/* sync register 'reg' by saving it to the corresponding temporary */
1546
static inline void tcg_reg_sync(TCGContext *s, int reg)
1547
{
1548
    TCGTemp *ts;
1549
    int temp;
1550

    
1551
    temp = s->reg_to_temp[reg];
1552
    ts = &s->temps[temp];
1553
    assert(ts->val_type == TEMP_VAL_REG);
1554
    if (!ts->mem_coherent && !ts->fixed_reg) {
1555
        if (!ts->mem_allocated) {
1556
            temp_allocate_frame(s, temp);
1557
        }
1558
        tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1559
    }
1560
    ts->mem_coherent = 1;
1561
}
1562

    
1563
/* free register 'reg' by spilling the corresponding temporary if necessary */
1564
static void tcg_reg_free(TCGContext *s, int reg)
1565
{
1566
    int temp;
1567

    
1568
    temp = s->reg_to_temp[reg];
1569
    if (temp != -1) {
1570
        tcg_reg_sync(s, reg);
1571
        s->temps[temp].val_type = TEMP_VAL_MEM;
1572
        s->reg_to_temp[reg] = -1;
1573
    }
1574
}
1575

    
1576
/* Allocate a register belonging to reg1 & ~reg2 */
1577
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1578
{
1579
    int i, reg;
1580
    TCGRegSet reg_ct;
1581

    
1582
    tcg_regset_andnot(reg_ct, reg1, reg2);
1583

    
1584
    /* first try free registers */
1585
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1586
        reg = tcg_target_reg_alloc_order[i];
1587
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1588
            return reg;
1589
    }
1590

    
1591
    /* XXX: do better spill choice */
1592
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1593
        reg = tcg_target_reg_alloc_order[i];
1594
        if (tcg_regset_test_reg(reg_ct, reg)) {
1595
            tcg_reg_free(s, reg);
1596
            return reg;
1597
        }
1598
    }
1599

    
1600
    tcg_abort();
1601
}
1602

    
1603
/* mark a temporary as dead. */
1604
static inline void temp_dead(TCGContext *s, int temp)
1605
{
1606
    TCGTemp *ts;
1607

    
1608
    ts = &s->temps[temp];
1609
    if (!ts->fixed_reg) {
1610
        if (ts->val_type == TEMP_VAL_REG) {
1611
            s->reg_to_temp[ts->reg] = -1;
1612
        }
1613
        if (temp < s->nb_globals || (ts->temp_local && ts->mem_allocated)) {
1614
            ts->val_type = TEMP_VAL_MEM;
1615
        } else {
1616
            ts->val_type = TEMP_VAL_DEAD;
1617
        }
1618
    }
1619
}
1620

    
1621
/* sync a temporary to memory. 'allocated_regs' is used in case a
1622
   temporary registers needs to be allocated to store a constant. */
1623
static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1624
{
1625
    TCGTemp *ts;
1626

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

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

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

    
1671
    for(i = 0; i < s->nb_globals; i++) {
1672
        temp_save(s, i, allocated_regs);
1673
    }
1674
}
1675

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

    
1683
    for (i = 0; i < s->nb_globals; i++) {
1684
#ifdef USE_LIVENESS_ANALYSIS
1685
        assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1686
               s->temps[i].mem_coherent);
1687
#else
1688
        temp_sync(s, i, allocated_regs);
1689
#endif
1690
    }
1691
}
1692

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

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

    
1715
    save_globals(s, allocated_regs);
1716
}
1717

    
1718
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1719
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1720

    
1721
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1722
                               uint16_t dead_args, uint8_t sync_args)
1723
{
1724
    TCGTemp *ots;
1725
    tcg_target_ulong val;
1726

    
1727
    ots = &s->temps[args[0]];
1728
    val = args[1];
1729

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

    
1749
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1750
                              const TCGArg *args, uint16_t dead_args,
1751
                              uint8_t sync_args)
1752
{
1753
    TCGRegSet allocated_regs;
1754
    TCGTemp *ts, *ots;
1755
    const TCGArgConstraint *arg_ct, *oarg_ct;
1756

    
1757
    tcg_regset_set(allocated_regs, s->reserved_regs);
1758
    ots = &s->temps[args[0]];
1759
    ts = &s->temps[args[1]];
1760
    oarg_ct = &def->args_ct[0];
1761
    arg_ct = &def->args_ct[1];
1762

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

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

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

    
1843
    nb_oargs = def->nb_oargs;
1844
    nb_iargs = def->nb_iargs;
1845

    
1846
    /* copy constants */
1847
    memcpy(new_args + nb_oargs + nb_iargs, 
1848
           args + nb_oargs + nb_iargs, 
1849
           sizeof(TCGArg) * def->nb_cargs);
1850

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

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

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

    
1992
#ifdef TCG_TARGET_STACK_GROWSUP
1993
#define STACK_DIR(x) (-(x))
1994
#else
1995
#define STACK_DIR(x) (x)
1996
#endif
1997

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

    
2010
    arg = *args++;
2011

    
2012
    nb_oargs = arg >> 16;
2013
    nb_iargs = arg & 0xffff;
2014
    nb_params = nb_iargs - 1;
2015

    
2016
    flags = args[nb_oargs + nb_iargs];
2017

    
2018
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2019
    if (nb_regs > nb_params)
2020
        nb_regs = nb_params;
2021

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

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

    
2136
    /* Save globals if they might be written by the helper, sync them if
2137
       they might be read. */
2138
    if (flags & TCG_CALL_NO_READ_GLOBALS) {
2139
        /* Nothing to do */
2140
    } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2141
        sync_globals(s, allocated_regs);
2142
    } else {
2143
        save_globals(s, allocated_regs);
2144
    }
2145

    
2146
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2147

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

    
2178
#ifdef CONFIG_PROFILER
2179

    
2180
static int64_t tcg_table_op_count[NB_OPS];
2181

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

    
2194

    
2195
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2196
                                      long search_pc)
2197
{
2198
    TCGOpcode opc;
2199
    int op_index;
2200
    const TCGOpDef *def;
2201
    const TCGArg *args;
2202

    
2203
#ifdef DEBUG_DISAS
2204
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2205
        qemu_log("OP:\n");
2206
        tcg_dump_ops(s);
2207
        qemu_log("\n");
2208
    }
2209
#endif
2210

    
2211
#ifdef CONFIG_PROFILER
2212
    s->opt_time -= profile_getclock();
2213
#endif
2214

    
2215
#ifdef USE_TCG_OPTIMIZATIONS
2216
    gen_opparam_ptr =
2217
        tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2218
#endif
2219

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

    
2225
    tcg_liveness_analysis(s);
2226

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

    
2231
#ifdef DEBUG_DISAS
2232
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2233
        qemu_log("OP after optimization and liveness analysis:\n");
2234
        tcg_dump_ops(s);
2235
        qemu_log("\n");
2236
    }
2237
#endif
2238

    
2239
    tcg_reg_alloc_start(s);
2240

    
2241
    s->code_buf = gen_code_buf;
2242
    s->code_ptr = gen_code_buf;
2243

    
2244
    args = gen_opparam_buf;
2245
    op_index = 0;
2246

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

    
2320
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2321
{
2322
#ifdef CONFIG_PROFILER
2323
    {
2324
        int n;
2325
        n = (gen_opc_ptr - gen_opc_buf);
2326
        s->op_count += n;
2327
        if (n > s->op_count_max)
2328
            s->op_count_max = n;
2329

    
2330
        s->temp_count += s->nb_temps;
2331
        if (s->nb_temps > s->temp_count_max)
2332
            s->temp_count_max = s->nb_temps;
2333
    }
2334
#endif
2335

    
2336
    tcg_gen_code_common(s, gen_code_buf, -1);
2337

    
2338
    /* flush instruction cache */
2339
    flush_icache_range((tcg_target_ulong)gen_code_buf,
2340
                       (tcg_target_ulong)s->code_ptr);
2341

    
2342
    return s->code_ptr -  gen_code_buf;
2343
}
2344

    
2345
/* Return the index of the micro operation such as the pc after is <
2346
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2347
   not be changed, though writing the same values is ok.
2348
   Return -1 if not found. */
2349
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2350
{
2351
    return tcg_gen_code_common(s, gen_code_buf, offset);
2352
}
2353

    
2354
#ifdef CONFIG_PROFILER
2355
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2356
{
2357
    TCGContext *s = &tcg_ctx;
2358
    int64_t tot;
2359

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

    
2399
    dump_op_count();
2400
}
2401
#else
2402
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2403
{
2404
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2405
}
2406
#endif
2407

    
2408
#ifdef ELF_HOST_MACHINE
2409
/* In order to use this feature, the backend needs to do three things:
2410

2411
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2412
       put into the ELF image and to indicate support for the feature.
2413

2414
   (2) Define tcg_register_jit.  This should create a buffer containing
2415
       the contents of a .debug_frame section that describes the post-
2416
       prologue unwind info for the tcg machine.
2417

2418
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2419
*/
2420

    
2421
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2422
typedef enum {
2423
    JIT_NOACTION = 0,
2424
    JIT_REGISTER_FN,
2425
    JIT_UNREGISTER_FN
2426
} jit_actions_t;
2427

    
2428
struct jit_code_entry {
2429
    struct jit_code_entry *next_entry;
2430
    struct jit_code_entry *prev_entry;
2431
    const void *symfile_addr;
2432
    uint64_t symfile_size;
2433
};
2434

    
2435
struct jit_descriptor {
2436
    uint32_t version;
2437
    uint32_t action_flag;
2438
    struct jit_code_entry *relevant_entry;
2439
    struct jit_code_entry *first_entry;
2440
};
2441

    
2442
void __jit_debug_register_code(void) __attribute__((noinline));
2443
void __jit_debug_register_code(void)
2444
{
2445
    asm("");
2446
}
2447

    
2448
/* Must statically initialize the version, because GDB may check
2449
   the version before we can set it.  */
2450
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2451

    
2452
/* End GDB interface.  */
2453

    
2454
static int find_string(const char *strtab, const char *str)
2455
{
2456
    const char *p = strtab + 1;
2457

    
2458
    while (1) {
2459
        if (strcmp(p, str) == 0) {
2460
            return p - strtab;
2461
        }
2462
        p += strlen(p) + 1;
2463
    }
2464
}
2465

    
2466
static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2467
                                 void *debug_frame, size_t debug_frame_size)
2468
{
2469
    struct __attribute__((packed)) DebugInfo {
2470
        uint32_t  len;
2471
        uint16_t  version;
2472
        uint32_t  abbrev;
2473
        uint8_t   ptr_size;
2474
        uint8_t   cu_die;
2475
        uint16_t  cu_lang;
2476
        uintptr_t cu_low_pc;
2477
        uintptr_t cu_high_pc;
2478
        uint8_t   fn_die;
2479
        char      fn_name[16];
2480
        uintptr_t fn_low_pc;
2481
        uintptr_t fn_high_pc;
2482
        uint8_t   cu_eoc;
2483
    };
2484

    
2485
    struct ElfImage {
2486
        ElfW(Ehdr) ehdr;
2487
        ElfW(Phdr) phdr;
2488
        ElfW(Shdr) shdr[7];
2489
        ElfW(Sym)  sym[2];
2490
        struct DebugInfo di;
2491
        uint8_t    da[24];
2492
        char       str[80];
2493
    };
2494

    
2495
    struct ElfImage *img;
2496

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

    
2600
    /* We only need a single jit entry; statically allocate it.  */
2601
    static struct jit_code_entry one_entry;
2602

    
2603
    uintptr_t buf = (uintptr_t)buf_ptr;
2604
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2605

    
2606
    img = g_malloc(img_size);
2607
    *img = img_template;
2608
    memcpy(img + 1, debug_frame, debug_frame_size);
2609

    
2610
    img->phdr.p_vaddr = buf;
2611
    img->phdr.p_paddr = buf;
2612
    img->phdr.p_memsz = buf_size;
2613

    
2614
    img->shdr[1].sh_name = find_string(img->str, ".text");
2615
    img->shdr[1].sh_addr = buf;
2616
    img->shdr[1].sh_size = buf_size;
2617

    
2618
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2619
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2620

    
2621
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2622
    img->shdr[4].sh_size = debug_frame_size;
2623

    
2624
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2625
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2626

    
2627
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2628
    img->sym[1].st_value = buf;
2629
    img->sym[1].st_size = buf_size;
2630

    
2631
    img->di.cu_low_pc = buf;
2632
    img->di.cu_high_pc = buf_size;
2633
    img->di.fn_low_pc = buf;
2634
    img->di.fn_high_pc = buf_size;
2635

    
2636
#ifdef DEBUG_JIT
2637
    /* Enable this block to be able to debug the ELF image file creation.
2638
       One can use readelf, objdump, or other inspection utilities.  */
2639
    {
2640
        FILE *f = fopen("/tmp/qemu.jit", "w+b");
2641
        if (f) {
2642
            if (fwrite(img, img_size, 1, f) != img_size) {
2643
                /* Avoid stupid unused return value warning for fwrite.  */
2644
            }
2645
            fclose(f);
2646
        }
2647
    }
2648
#endif
2649

    
2650
    one_entry.symfile_addr = img;
2651
    one_entry.symfile_size = img_size;
2652

    
2653
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2654
    __jit_debug_descriptor.relevant_entry = &one_entry;
2655
    __jit_debug_descriptor.first_entry = &one_entry;
2656
    __jit_debug_register_code();
2657
}
2658
#else
2659
/* No support for the feature.  Provide the entry point expected by exec.c,
2660
   and implement the internal function we declared earlier.  */
2661

    
2662
static void tcg_register_jit_int(void *buf, size_t size,
2663
                                 void *debug_frame, size_t debug_frame_size)
2664
{
2665
}
2666

    
2667
void tcg_register_jit(void *buf, size_t buf_size)
2668
{
2669
}
2670
#endif /* ELF_HOST_MACHINE */