Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 7dfd8c6a

History | View | Annotate | Download (80.3 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_PURE) {
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_CONST)) {
1282
                        /* globals should go back to memory */
1283
                        memset(dead_temps, 1, s->nb_globals);
1284
                        memset(mem_temps, 1, s->nb_globals);
1285
                    }
1286

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

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

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

    
1368
        default:
1369
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1370
            args -= def->nb_args;
1371
            nb_iargs = def->nb_iargs;
1372
            nb_oargs = def->nb_oargs;
1373

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

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

    
1407
                /* if end of basic block, update */
1408
                if (def->flags & TCG_OPF_BB_END) {
1409
                    tcg_la_bb_end(s, dead_temps, mem_temps);
1410
                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1411
                    /* globals should go back to memory */
1412
                    memset(dead_temps, 1, s->nb_globals);
1413
                    memset(mem_temps, 1, s->nb_globals);
1414
                }
1415

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1579
    tcg_regset_andnot(reg_ct, reg1, reg2);
1580

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

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

    
1597
    tcg_abort();
1598
}
1599

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

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

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

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

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

    
1655
/* save globals to their canonical location and assume they can be
1656
   modified be the following code. 'allocated_regs' is used in case a
1657
   temporary registers needs to be allocated to store a constant. */
1658
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1659
{
1660
    int i;
1661

    
1662
    for(i = 0; i < s->nb_globals; i++) {
1663
        temp_save(s, i, allocated_regs);
1664
    }
1665
}
1666

    
1667
/* at the end of a basic block, we assume all temporaries are dead and
1668
   all globals are stored at their canonical location. */
1669
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1670
{
1671
    TCGTemp *ts;
1672
    int i;
1673

    
1674
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1675
        ts = &s->temps[i];
1676
        if (ts->temp_local) {
1677
            temp_save(s, i, allocated_regs);
1678
        } else {
1679
            temp_dead(s, i);
1680
        }
1681
    }
1682

    
1683
    save_globals(s, allocated_regs);
1684
}
1685

    
1686
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1687
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1688

    
1689
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1690
                               uint16_t dead_args, uint8_t sync_args)
1691
{
1692
    TCGTemp *ots;
1693
    tcg_target_ulong val;
1694

    
1695
    ots = &s->temps[args[0]];
1696
    val = args[1];
1697

    
1698
    if (ots->fixed_reg) {
1699
        /* for fixed registers, we do not do any constant
1700
           propagation */
1701
        tcg_out_movi(s, ots->type, ots->reg, val);
1702
    } else {
1703
        /* The movi is not explicitly generated here */
1704
        if (ots->val_type == TEMP_VAL_REG)
1705
            s->reg_to_temp[ots->reg] = -1;
1706
        ots->val_type = TEMP_VAL_CONST;
1707
        ots->val = val;
1708
    }
1709
    if (NEED_SYNC_ARG(0)) {
1710
        temp_sync(s, args[0], s->reserved_regs);
1711
    }
1712
    if (IS_DEAD_ARG(0)) {
1713
        temp_dead(s, args[0]);
1714
    }
1715
}
1716

    
1717
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1718
                              const TCGArg *args, uint16_t dead_args,
1719
                              uint8_t sync_args)
1720
{
1721
    TCGRegSet allocated_regs;
1722
    TCGTemp *ts, *ots;
1723
    const TCGArgConstraint *arg_ct, *oarg_ct;
1724

    
1725
    tcg_regset_set(allocated_regs, s->reserved_regs);
1726
    ots = &s->temps[args[0]];
1727
    ts = &s->temps[args[1]];
1728
    oarg_ct = &def->args_ct[0];
1729
    arg_ct = &def->args_ct[1];
1730

    
1731
    /* If the source value is not in a register, and we're going to be
1732
       forced to have it in a register in order to perform the copy,
1733
       then copy the SOURCE value into its own register first.  That way
1734
       we don't have to reload SOURCE the next time it is used. */
1735
    if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
1736
        || ts->val_type == TEMP_VAL_MEM) {
1737
        ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1738
        if (ts->val_type == TEMP_VAL_MEM) {
1739
            tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
1740
            ts->mem_coherent = 1;
1741
        } else if (ts->val_type == TEMP_VAL_CONST) {
1742
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
1743
        }
1744
        s->reg_to_temp[ts->reg] = args[1];
1745
        ts->val_type = TEMP_VAL_REG;
1746
    }
1747

    
1748
    if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
1749
        /* mov to a non-saved dead register makes no sense (even with
1750
           liveness analysis disabled). */
1751
        assert(NEED_SYNC_ARG(0));
1752
        /* The code above should have moved the temp to a register. */
1753
        assert(ts->val_type == TEMP_VAL_REG);
1754
        if (!ots->mem_allocated) {
1755
            temp_allocate_frame(s, args[0]);
1756
        }
1757
        tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
1758
        if (IS_DEAD_ARG(1)) {
1759
            temp_dead(s, args[1]);
1760
        }
1761
        temp_dead(s, args[0]);
1762
    } else if (ts->val_type == TEMP_VAL_CONST) {
1763
        /* propagate constant */
1764
        if (ots->val_type == TEMP_VAL_REG) {
1765
            s->reg_to_temp[ots->reg] = -1;
1766
        }
1767
        ots->val_type = TEMP_VAL_CONST;
1768
        ots->val = ts->val;
1769
    } else {
1770
        /* The code in the first if block should have moved the
1771
           temp to a register. */
1772
        assert(ts->val_type == TEMP_VAL_REG);
1773
        if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1774
            /* the mov can be suppressed */
1775
            if (ots->val_type == TEMP_VAL_REG) {
1776
                s->reg_to_temp[ots->reg] = -1;
1777
            }
1778
            ots->reg = ts->reg;
1779
            temp_dead(s, args[1]);
1780
        } else {
1781
            if (ots->val_type != TEMP_VAL_REG) {
1782
                /* When allocating a new register, make sure to not spill the
1783
                   input one. */
1784
                tcg_regset_set_reg(allocated_regs, ts->reg);
1785
                ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs);
1786
            }
1787
            tcg_out_mov(s, ots->type, ots->reg, ts->reg);
1788
        }
1789
        ots->val_type = TEMP_VAL_REG;
1790
        ots->mem_coherent = 0;
1791
        s->reg_to_temp[ots->reg] = args[0];
1792
        if (NEED_SYNC_ARG(0)) {
1793
            tcg_reg_sync(s, ots->reg);
1794
        }
1795
    }
1796
}
1797

    
1798
static void tcg_reg_alloc_op(TCGContext *s, 
1799
                             const TCGOpDef *def, TCGOpcode opc,
1800
                             const TCGArg *args, uint16_t dead_args,
1801
                             uint8_t sync_args)
1802
{
1803
    TCGRegSet allocated_regs;
1804
    int i, k, nb_iargs, nb_oargs, reg;
1805
    TCGArg arg;
1806
    const TCGArgConstraint *arg_ct;
1807
    TCGTemp *ts;
1808
    TCGArg new_args[TCG_MAX_OP_ARGS];
1809
    int const_args[TCG_MAX_OP_ARGS];
1810

    
1811
    nb_oargs = def->nb_oargs;
1812
    nb_iargs = def->nb_iargs;
1813

    
1814
    /* copy constants */
1815
    memcpy(new_args + nb_oargs + nb_iargs, 
1816
           args + nb_oargs + nb_iargs, 
1817
           sizeof(TCGArg) * def->nb_cargs);
1818

    
1819
    /* satisfy input constraints */ 
1820
    tcg_regset_set(allocated_regs, s->reserved_regs);
1821
    for(k = 0; k < nb_iargs; k++) {
1822
        i = def->sorted_args[nb_oargs + k];
1823
        arg = args[i];
1824
        arg_ct = &def->args_ct[i];
1825
        ts = &s->temps[arg];
1826
        if (ts->val_type == TEMP_VAL_MEM) {
1827
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1828
            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1829
            ts->val_type = TEMP_VAL_REG;
1830
            ts->reg = reg;
1831
            ts->mem_coherent = 1;
1832
            s->reg_to_temp[reg] = arg;
1833
        } else if (ts->val_type == TEMP_VAL_CONST) {
1834
            if (tcg_target_const_match(ts->val, arg_ct)) {
1835
                /* constant is OK for instruction */
1836
                const_args[i] = 1;
1837
                new_args[i] = ts->val;
1838
                goto iarg_end;
1839
            } else {
1840
                /* need to move to a register */
1841
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1842
                tcg_out_movi(s, ts->type, reg, ts->val);
1843
                ts->val_type = TEMP_VAL_REG;
1844
                ts->reg = reg;
1845
                ts->mem_coherent = 0;
1846
                s->reg_to_temp[reg] = arg;
1847
            }
1848
        }
1849
        assert(ts->val_type == TEMP_VAL_REG);
1850
        if (arg_ct->ct & TCG_CT_IALIAS) {
1851
            if (ts->fixed_reg) {
1852
                /* if fixed register, we must allocate a new register
1853
                   if the alias is not the same register */
1854
                if (arg != args[arg_ct->alias_index])
1855
                    goto allocate_in_reg;
1856
            } else {
1857
                /* if the input is aliased to an output and if it is
1858
                   not dead after the instruction, we must allocate
1859
                   a new register and move it */
1860
                if (!IS_DEAD_ARG(i)) {
1861
                    goto allocate_in_reg;
1862
                }
1863
            }
1864
        }
1865
        reg = ts->reg;
1866
        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1867
            /* nothing to do : the constraint is satisfied */
1868
        } else {
1869
        allocate_in_reg:
1870
            /* allocate a new register matching the constraint 
1871
               and move the temporary register into it */
1872
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1873
            tcg_out_mov(s, ts->type, reg, ts->reg);
1874
        }
1875
        new_args[i] = reg;
1876
        const_args[i] = 0;
1877
        tcg_regset_set_reg(allocated_regs, reg);
1878
    iarg_end: ;
1879
    }
1880
    
1881
    /* mark dead temporaries and free the associated registers */
1882
    for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1883
        if (IS_DEAD_ARG(i)) {
1884
            temp_dead(s, args[i]);
1885
        }
1886
    }
1887

    
1888
    if (def->flags & TCG_OPF_BB_END) {
1889
        tcg_reg_alloc_bb_end(s, allocated_regs);
1890
    } else {
1891
        if (def->flags & TCG_OPF_CALL_CLOBBER) {
1892
            /* XXX: permit generic clobber register list ? */ 
1893
            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1894
                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1895
                    tcg_reg_free(s, reg);
1896
                }
1897
            }
1898
            /* XXX: for load/store we could do that only for the slow path
1899
               (i.e. when a memory callback is called) */
1900
            
1901
            /* store globals and free associated registers (we assume the insn
1902
               can modify any global. */
1903
            save_globals(s, allocated_regs);
1904
        }
1905
        
1906
        /* satisfy the output constraints */
1907
        tcg_regset_set(allocated_regs, s->reserved_regs);
1908
        for(k = 0; k < nb_oargs; k++) {
1909
            i = def->sorted_args[k];
1910
            arg = args[i];
1911
            arg_ct = &def->args_ct[i];
1912
            ts = &s->temps[arg];
1913
            if (arg_ct->ct & TCG_CT_ALIAS) {
1914
                reg = new_args[arg_ct->alias_index];
1915
            } else {
1916
                /* if fixed register, we try to use it */
1917
                reg = ts->reg;
1918
                if (ts->fixed_reg &&
1919
                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1920
                    goto oarg_end;
1921
                }
1922
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1923
            }
1924
            tcg_regset_set_reg(allocated_regs, reg);
1925
            /* if a fixed register is used, then a move will be done afterwards */
1926
            if (!ts->fixed_reg) {
1927
                if (ts->val_type == TEMP_VAL_REG) {
1928
                    s->reg_to_temp[ts->reg] = -1;
1929
                }
1930
                ts->val_type = TEMP_VAL_REG;
1931
                ts->reg = reg;
1932
                /* temp value is modified, so the value kept in memory is
1933
                   potentially not the same */
1934
                ts->mem_coherent = 0;
1935
                s->reg_to_temp[reg] = arg;
1936
            }
1937
        oarg_end:
1938
            new_args[i] = reg;
1939
        }
1940
    }
1941

    
1942
    /* emit instruction */
1943
    tcg_out_op(s, opc, new_args, const_args);
1944
    
1945
    /* move the outputs in the correct register if needed */
1946
    for(i = 0; i < nb_oargs; i++) {
1947
        ts = &s->temps[args[i]];
1948
        reg = new_args[i];
1949
        if (ts->fixed_reg && ts->reg != reg) {
1950
            tcg_out_mov(s, ts->type, ts->reg, reg);
1951
        }
1952
        if (NEED_SYNC_ARG(i)) {
1953
            tcg_reg_sync(s, reg);
1954
        }
1955
        if (IS_DEAD_ARG(i)) {
1956
            temp_dead(s, args[i]);
1957
        }
1958
    }
1959
}
1960

    
1961
#ifdef TCG_TARGET_STACK_GROWSUP
1962
#define STACK_DIR(x) (-(x))
1963
#else
1964
#define STACK_DIR(x) (x)
1965
#endif
1966

    
1967
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1968
                              TCGOpcode opc, const TCGArg *args,
1969
                              uint16_t dead_args, uint8_t sync_args)
1970
{
1971
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1972
    TCGArg arg, func_arg;
1973
    TCGTemp *ts;
1974
    tcg_target_long stack_offset, call_stack_size, func_addr;
1975
    int const_func_arg, allocate_args;
1976
    TCGRegSet allocated_regs;
1977
    const TCGArgConstraint *arg_ct;
1978

    
1979
    arg = *args++;
1980

    
1981
    nb_oargs = arg >> 16;
1982
    nb_iargs = arg & 0xffff;
1983
    nb_params = nb_iargs - 1;
1984

    
1985
    flags = args[nb_oargs + nb_iargs];
1986

    
1987
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
1988
    if (nb_regs > nb_params)
1989
        nb_regs = nb_params;
1990

    
1991
    /* assign stack slots first */
1992
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1993
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1994
        ~(TCG_TARGET_STACK_ALIGN - 1);
1995
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1996
    if (allocate_args) {
1997
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1998
           preallocate call stack */
1999
        tcg_abort();
2000
    }
2001

    
2002
    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2003
    for(i = nb_regs; i < nb_params; i++) {
2004
        arg = args[nb_oargs + i];
2005
#ifdef TCG_TARGET_STACK_GROWSUP
2006
        stack_offset -= sizeof(tcg_target_long);
2007
#endif
2008
        if (arg != TCG_CALL_DUMMY_ARG) {
2009
            ts = &s->temps[arg];
2010
            if (ts->val_type == TEMP_VAL_REG) {
2011
                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2012
            } else if (ts->val_type == TEMP_VAL_MEM) {
2013
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2014
                                    s->reserved_regs);
2015
                /* XXX: not correct if reading values from the stack */
2016
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2017
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2018
            } else if (ts->val_type == TEMP_VAL_CONST) {
2019
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2020
                                    s->reserved_regs);
2021
                /* XXX: sign extend may be needed on some targets */
2022
                tcg_out_movi(s, ts->type, reg, ts->val);
2023
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2024
            } else {
2025
                tcg_abort();
2026
            }
2027
        }
2028
#ifndef TCG_TARGET_STACK_GROWSUP
2029
        stack_offset += sizeof(tcg_target_long);
2030
#endif
2031
    }
2032
    
2033
    /* assign input registers */
2034
    tcg_regset_set(allocated_regs, s->reserved_regs);
2035
    for(i = 0; i < nb_regs; i++) {
2036
        arg = args[nb_oargs + i];
2037
        if (arg != TCG_CALL_DUMMY_ARG) {
2038
            ts = &s->temps[arg];
2039
            reg = tcg_target_call_iarg_regs[i];
2040
            tcg_reg_free(s, reg);
2041
            if (ts->val_type == TEMP_VAL_REG) {
2042
                if (ts->reg != reg) {
2043
                    tcg_out_mov(s, ts->type, reg, ts->reg);
2044
                }
2045
            } else if (ts->val_type == TEMP_VAL_MEM) {
2046
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2047
            } else if (ts->val_type == TEMP_VAL_CONST) {
2048
                /* XXX: sign extend ? */
2049
                tcg_out_movi(s, ts->type, reg, ts->val);
2050
            } else {
2051
                tcg_abort();
2052
            }
2053
            tcg_regset_set_reg(allocated_regs, reg);
2054
        }
2055
    }
2056
    
2057
    /* assign function address */
2058
    func_arg = args[nb_oargs + nb_iargs - 1];
2059
    arg_ct = &def->args_ct[0];
2060
    ts = &s->temps[func_arg];
2061
    func_addr = ts->val;
2062
    const_func_arg = 0;
2063
    if (ts->val_type == TEMP_VAL_MEM) {
2064
        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2065
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2066
        func_arg = reg;
2067
        tcg_regset_set_reg(allocated_regs, reg);
2068
    } else if (ts->val_type == TEMP_VAL_REG) {
2069
        reg = ts->reg;
2070
        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2071
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2072
            tcg_out_mov(s, ts->type, reg, ts->reg);
2073
        }
2074
        func_arg = reg;
2075
        tcg_regset_set_reg(allocated_regs, reg);
2076
    } else if (ts->val_type == TEMP_VAL_CONST) {
2077
        if (tcg_target_const_match(func_addr, arg_ct)) {
2078
            const_func_arg = 1;
2079
            func_arg = func_addr;
2080
        } else {
2081
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2082
            tcg_out_movi(s, ts->type, reg, func_addr);
2083
            func_arg = reg;
2084
            tcg_regset_set_reg(allocated_regs, reg);
2085
        }
2086
    } else {
2087
        tcg_abort();
2088
    }
2089
        
2090
    
2091
    /* mark dead temporaries and free the associated registers */
2092
    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2093
        if (IS_DEAD_ARG(i)) {
2094
            temp_dead(s, args[i]);
2095
        }
2096
    }
2097
    
2098
    /* clobber call registers */
2099
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2100
        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2101
            tcg_reg_free(s, reg);
2102
        }
2103
    }
2104
    
2105
    /* store globals and free associated registers (we assume the call
2106
       can modify any global. */
2107
    if (!(flags & TCG_CALL_CONST)) {
2108
        save_globals(s, allocated_regs);
2109
    }
2110

    
2111
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2112

    
2113
    /* assign output registers and emit moves if needed */
2114
    for(i = 0; i < nb_oargs; i++) {
2115
        arg = args[i];
2116
        ts = &s->temps[arg];
2117
        reg = tcg_target_call_oarg_regs[i];
2118
        assert(s->reg_to_temp[reg] == -1);
2119
        if (ts->fixed_reg) {
2120
            if (ts->reg != reg) {
2121
                tcg_out_mov(s, ts->type, ts->reg, reg);
2122
            }
2123
        } else {
2124
            if (ts->val_type == TEMP_VAL_REG) {
2125
                s->reg_to_temp[ts->reg] = -1;
2126
            }
2127
            ts->val_type = TEMP_VAL_REG;
2128
            ts->reg = reg;
2129
            ts->mem_coherent = 0;
2130
            s->reg_to_temp[reg] = arg;
2131
            if (NEED_SYNC_ARG(i)) {
2132
                tcg_reg_sync(s, reg);
2133
            }
2134
            if (IS_DEAD_ARG(i)) {
2135
                temp_dead(s, args[i]);
2136
            }
2137
        }
2138
    }
2139
    
2140
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2141
}
2142

    
2143
#ifdef CONFIG_PROFILER
2144

    
2145
static int64_t tcg_table_op_count[NB_OPS];
2146

    
2147
static void dump_op_count(void)
2148
{
2149
    int i;
2150
    FILE *f;
2151
    f = fopen("/tmp/op.log", "w");
2152
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2153
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2154
    }
2155
    fclose(f);
2156
}
2157
#endif
2158

    
2159

    
2160
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2161
                                      long search_pc)
2162
{
2163
    TCGOpcode opc;
2164
    int op_index;
2165
    const TCGOpDef *def;
2166
    const TCGArg *args;
2167

    
2168
#ifdef DEBUG_DISAS
2169
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2170
        qemu_log("OP:\n");
2171
        tcg_dump_ops(s);
2172
        qemu_log("\n");
2173
    }
2174
#endif
2175

    
2176
#ifdef CONFIG_PROFILER
2177
    s->opt_time -= profile_getclock();
2178
#endif
2179

    
2180
#ifdef USE_TCG_OPTIMIZATIONS
2181
    gen_opparam_ptr =
2182
        tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2183
#endif
2184

    
2185
#ifdef CONFIG_PROFILER
2186
    s->opt_time += profile_getclock();
2187
    s->la_time -= profile_getclock();
2188
#endif
2189

    
2190
    tcg_liveness_analysis(s);
2191

    
2192
#ifdef CONFIG_PROFILER
2193
    s->la_time += profile_getclock();
2194
#endif
2195

    
2196
#ifdef DEBUG_DISAS
2197
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2198
        qemu_log("OP after optimization and liveness analysis:\n");
2199
        tcg_dump_ops(s);
2200
        qemu_log("\n");
2201
    }
2202
#endif
2203

    
2204
    tcg_reg_alloc_start(s);
2205

    
2206
    s->code_buf = gen_code_buf;
2207
    s->code_ptr = gen_code_buf;
2208

    
2209
    args = gen_opparam_buf;
2210
    op_index = 0;
2211

    
2212
    for(;;) {
2213
        opc = gen_opc_buf[op_index];
2214
#ifdef CONFIG_PROFILER
2215
        tcg_table_op_count[opc]++;
2216
#endif
2217
        def = &tcg_op_defs[opc];
2218
#if 0
2219
        printf("%s: %d %d %d\n", def->name,
2220
               def->nb_oargs, def->nb_iargs, def->nb_cargs);
2221
        //        dump_regs(s);
2222
#endif
2223
        switch(opc) {
2224
        case INDEX_op_mov_i32:
2225
        case INDEX_op_mov_i64:
2226
            tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2227
                              s->op_sync_args[op_index]);
2228
            break;
2229
        case INDEX_op_movi_i32:
2230
        case INDEX_op_movi_i64:
2231
            tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2232
                               s->op_sync_args[op_index]);
2233
            break;
2234
        case INDEX_op_debug_insn_start:
2235
            /* debug instruction */
2236
            break;
2237
        case INDEX_op_nop:
2238
        case INDEX_op_nop1:
2239
        case INDEX_op_nop2:
2240
        case INDEX_op_nop3:
2241
            break;
2242
        case INDEX_op_nopn:
2243
            args += args[0];
2244
            goto next;
2245
        case INDEX_op_discard:
2246
            temp_dead(s, args[0]);
2247
            break;
2248
        case INDEX_op_set_label:
2249
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
2250
            tcg_out_label(s, args[0], s->code_ptr);
2251
            break;
2252
        case INDEX_op_call:
2253
            args += tcg_reg_alloc_call(s, def, opc, args,
2254
                                       s->op_dead_args[op_index],
2255
                                       s->op_sync_args[op_index]);
2256
            goto next;
2257
        case INDEX_op_end:
2258
            goto the_end;
2259
        default:
2260
            /* Sanity check that we've not introduced any unhandled opcodes. */
2261
            if (def->flags & TCG_OPF_NOT_PRESENT) {
2262
                tcg_abort();
2263
            }
2264
            /* Note: in order to speed up the code, it would be much
2265
               faster to have specialized register allocator functions for
2266
               some common argument patterns */
2267
            tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2268
                             s->op_sync_args[op_index]);
2269
            break;
2270
        }
2271
        args += def->nb_args;
2272
    next:
2273
        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2274
            return op_index;
2275
        }
2276
        op_index++;
2277
#ifndef NDEBUG
2278
        check_regs(s);
2279
#endif
2280
    }
2281
 the_end:
2282
    return -1;
2283
}
2284

    
2285
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2286
{
2287
#ifdef CONFIG_PROFILER
2288
    {
2289
        int n;
2290
        n = (gen_opc_ptr - gen_opc_buf);
2291
        s->op_count += n;
2292
        if (n > s->op_count_max)
2293
            s->op_count_max = n;
2294

    
2295
        s->temp_count += s->nb_temps;
2296
        if (s->nb_temps > s->temp_count_max)
2297
            s->temp_count_max = s->nb_temps;
2298
    }
2299
#endif
2300

    
2301
    tcg_gen_code_common(s, gen_code_buf, -1);
2302

    
2303
    /* flush instruction cache */
2304
    flush_icache_range((tcg_target_ulong)gen_code_buf,
2305
                       (tcg_target_ulong)s->code_ptr);
2306

    
2307
    return s->code_ptr -  gen_code_buf;
2308
}
2309

    
2310
/* Return the index of the micro operation such as the pc after is <
2311
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2312
   not be changed, though writing the same values is ok.
2313
   Return -1 if not found. */
2314
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2315
{
2316
    return tcg_gen_code_common(s, gen_code_buf, offset);
2317
}
2318

    
2319
#ifdef CONFIG_PROFILER
2320
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2321
{
2322
    TCGContext *s = &tcg_ctx;
2323
    int64_t tot;
2324

    
2325
    tot = s->interm_time + s->code_time;
2326
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2327
                tot, tot / 2.4e9);
2328
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2329
                s->tb_count, 
2330
                s->tb_count1 - s->tb_count,
2331
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2332
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2333
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2334
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2335
                s->tb_count ? 
2336
                (double)s->del_op_count / s->tb_count : 0);
2337
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2338
                s->tb_count ? 
2339
                (double)s->temp_count / s->tb_count : 0,
2340
                s->temp_count_max);
2341
    
2342
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2343
                s->op_count ? (double)tot / s->op_count : 0);
2344
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2345
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2346
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2347
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2348
    if (tot == 0)
2349
        tot = 1;
2350
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2351
                (double)s->interm_time / tot * 100.0);
2352
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2353
                (double)s->code_time / tot * 100.0);
2354
    cpu_fprintf(f, "optim./code time    %0.1f%%\n",
2355
                (double)s->opt_time / (s->code_time ? s->code_time : 1)
2356
                * 100.0);
2357
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2358
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2359
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2360
                s->restore_count);
2361
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2362
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2363

    
2364
    dump_op_count();
2365
}
2366
#else
2367
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2368
{
2369
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2370
}
2371
#endif
2372

    
2373
#ifdef ELF_HOST_MACHINE
2374
/* In order to use this feature, the backend needs to do three things:
2375

2376
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2377
       put into the ELF image and to indicate support for the feature.
2378

2379
   (2) Define tcg_register_jit.  This should create a buffer containing
2380
       the contents of a .debug_frame section that describes the post-
2381
       prologue unwind info for the tcg machine.
2382

2383
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2384
*/
2385

    
2386
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2387
typedef enum {
2388
    JIT_NOACTION = 0,
2389
    JIT_REGISTER_FN,
2390
    JIT_UNREGISTER_FN
2391
} jit_actions_t;
2392

    
2393
struct jit_code_entry {
2394
    struct jit_code_entry *next_entry;
2395
    struct jit_code_entry *prev_entry;
2396
    const void *symfile_addr;
2397
    uint64_t symfile_size;
2398
};
2399

    
2400
struct jit_descriptor {
2401
    uint32_t version;
2402
    uint32_t action_flag;
2403
    struct jit_code_entry *relevant_entry;
2404
    struct jit_code_entry *first_entry;
2405
};
2406

    
2407
void __jit_debug_register_code(void) __attribute__((noinline));
2408
void __jit_debug_register_code(void)
2409
{
2410
    asm("");
2411
}
2412

    
2413
/* Must statically initialize the version, because GDB may check
2414
   the version before we can set it.  */
2415
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2416

    
2417
/* End GDB interface.  */
2418

    
2419
static int find_string(const char *strtab, const char *str)
2420
{
2421
    const char *p = strtab + 1;
2422

    
2423
    while (1) {
2424
        if (strcmp(p, str) == 0) {
2425
            return p - strtab;
2426
        }
2427
        p += strlen(p) + 1;
2428
    }
2429
}
2430

    
2431
static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2432
                                 void *debug_frame, size_t debug_frame_size)
2433
{
2434
    struct __attribute__((packed)) DebugInfo {
2435
        uint32_t  len;
2436
        uint16_t  version;
2437
        uint32_t  abbrev;
2438
        uint8_t   ptr_size;
2439
        uint8_t   cu_die;
2440
        uint16_t  cu_lang;
2441
        uintptr_t cu_low_pc;
2442
        uintptr_t cu_high_pc;
2443
        uint8_t   fn_die;
2444
        char      fn_name[16];
2445
        uintptr_t fn_low_pc;
2446
        uintptr_t fn_high_pc;
2447
        uint8_t   cu_eoc;
2448
    };
2449

    
2450
    struct ElfImage {
2451
        ElfW(Ehdr) ehdr;
2452
        ElfW(Phdr) phdr;
2453
        ElfW(Shdr) shdr[7];
2454
        ElfW(Sym)  sym[2];
2455
        struct DebugInfo di;
2456
        uint8_t    da[24];
2457
        char       str[80];
2458
    };
2459

    
2460
    struct ElfImage *img;
2461

    
2462
    static const struct ElfImage img_template = {
2463
        .ehdr = {
2464
            .e_ident[EI_MAG0] = ELFMAG0,
2465
            .e_ident[EI_MAG1] = ELFMAG1,
2466
            .e_ident[EI_MAG2] = ELFMAG2,
2467
            .e_ident[EI_MAG3] = ELFMAG3,
2468
            .e_ident[EI_CLASS] = ELF_CLASS,
2469
            .e_ident[EI_DATA] = ELF_DATA,
2470
            .e_ident[EI_VERSION] = EV_CURRENT,
2471
            .e_type = ET_EXEC,
2472
            .e_machine = ELF_HOST_MACHINE,
2473
            .e_version = EV_CURRENT,
2474
            .e_phoff = offsetof(struct ElfImage, phdr),
2475
            .e_shoff = offsetof(struct ElfImage, shdr),
2476
            .e_ehsize = sizeof(ElfW(Shdr)),
2477
            .e_phentsize = sizeof(ElfW(Phdr)),
2478
            .e_phnum = 1,
2479
            .e_shentsize = sizeof(ElfW(Shdr)),
2480
            .e_shnum = ARRAY_SIZE(img->shdr),
2481
            .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2482
#ifdef ELF_HOST_FLAGS
2483
            .e_flags = ELF_HOST_FLAGS,
2484
#endif
2485
#ifdef ELF_OSABI
2486
            .e_ident[EI_OSABI] = ELF_OSABI,
2487
#endif
2488
        },
2489
        .phdr = {
2490
            .p_type = PT_LOAD,
2491
            .p_flags = PF_X,
2492
        },
2493
        .shdr = {
2494
            [0] = { .sh_type = SHT_NULL },
2495
            /* Trick: The contents of code_gen_buffer are not present in
2496
               this fake ELF file; that got allocated elsewhere.  Therefore
2497
               we mark .text as SHT_NOBITS (similar to .bss) so that readers
2498
               will not look for contents.  We can record any address.  */
2499
            [1] = { /* .text */
2500
                .sh_type = SHT_NOBITS,
2501
                .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2502
            },
2503
            [2] = { /* .debug_info */
2504
                .sh_type = SHT_PROGBITS,
2505
                .sh_offset = offsetof(struct ElfImage, di),
2506
                .sh_size = sizeof(struct DebugInfo),
2507
            },
2508
            [3] = { /* .debug_abbrev */
2509
                .sh_type = SHT_PROGBITS,
2510
                .sh_offset = offsetof(struct ElfImage, da),
2511
                .sh_size = sizeof(img->da),
2512
            },
2513
            [4] = { /* .debug_frame */
2514
                .sh_type = SHT_PROGBITS,
2515
                .sh_offset = sizeof(struct ElfImage),
2516
            },
2517
            [5] = { /* .symtab */
2518
                .sh_type = SHT_SYMTAB,
2519
                .sh_offset = offsetof(struct ElfImage, sym),
2520
                .sh_size = sizeof(img->sym),
2521
                .sh_info = 1,
2522
                .sh_link = ARRAY_SIZE(img->shdr) - 1,
2523
                .sh_entsize = sizeof(ElfW(Sym)),
2524
            },
2525
            [6] = { /* .strtab */
2526
                .sh_type = SHT_STRTAB,
2527
                .sh_offset = offsetof(struct ElfImage, str),
2528
                .sh_size = sizeof(img->str),
2529
            }
2530
        },
2531
        .sym = {
2532
            [1] = { /* code_gen_buffer */
2533
                .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2534
                .st_shndx = 1,
2535
            }
2536
        },
2537
        .di = {
2538
            .len = sizeof(struct DebugInfo) - 4,
2539
            .version = 2,
2540
            .ptr_size = sizeof(void *),
2541
            .cu_die = 1,
2542
            .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
2543
            .fn_die = 2,
2544
            .fn_name = "code_gen_buffer"
2545
        },
2546
        .da = {
2547
            1,          /* abbrev number (the cu) */
2548
            0x11, 1,    /* DW_TAG_compile_unit, has children */
2549
            0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
2550
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2551
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2552
            0, 0,       /* end of abbrev */
2553
            2,          /* abbrev number (the fn) */
2554
            0x2e, 0,    /* DW_TAG_subprogram, no children */
2555
            0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
2556
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2557
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2558
            0, 0,       /* end of abbrev */
2559
            0           /* no more abbrev */
2560
        },
2561
        .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2562
               ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2563
    };
2564

    
2565
    /* We only need a single jit entry; statically allocate it.  */
2566
    static struct jit_code_entry one_entry;
2567

    
2568
    uintptr_t buf = (uintptr_t)buf_ptr;
2569
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2570

    
2571
    img = g_malloc(img_size);
2572
    *img = img_template;
2573
    memcpy(img + 1, debug_frame, debug_frame_size);
2574

    
2575
    img->phdr.p_vaddr = buf;
2576
    img->phdr.p_paddr = buf;
2577
    img->phdr.p_memsz = buf_size;
2578

    
2579
    img->shdr[1].sh_name = find_string(img->str, ".text");
2580
    img->shdr[1].sh_addr = buf;
2581
    img->shdr[1].sh_size = buf_size;
2582

    
2583
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2584
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2585

    
2586
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2587
    img->shdr[4].sh_size = debug_frame_size;
2588

    
2589
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2590
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2591

    
2592
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2593
    img->sym[1].st_value = buf;
2594
    img->sym[1].st_size = buf_size;
2595

    
2596
    img->di.cu_low_pc = buf;
2597
    img->di.cu_high_pc = buf_size;
2598
    img->di.fn_low_pc = buf;
2599
    img->di.fn_high_pc = buf_size;
2600

    
2601
#ifdef DEBUG_JIT
2602
    /* Enable this block to be able to debug the ELF image file creation.
2603
       One can use readelf, objdump, or other inspection utilities.  */
2604
    {
2605
        FILE *f = fopen("/tmp/qemu.jit", "w+b");
2606
        if (f) {
2607
            if (fwrite(img, img_size, 1, f) != img_size) {
2608
                /* Avoid stupid unused return value warning for fwrite.  */
2609
            }
2610
            fclose(f);
2611
        }
2612
    }
2613
#endif
2614

    
2615
    one_entry.symfile_addr = img;
2616
    one_entry.symfile_size = img_size;
2617

    
2618
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2619
    __jit_debug_descriptor.relevant_entry = &one_entry;
2620
    __jit_debug_descriptor.first_entry = &one_entry;
2621
    __jit_debug_register_code();
2622
}
2623
#else
2624
/* No support for the feature.  Provide the entry point expected by exec.c,
2625
   and implement the internal function we declared earlier.  */
2626

    
2627
static void tcg_register_jit_int(void *buf, size_t size,
2628
                                 void *debug_frame, size_t debug_frame_size)
2629
{
2630
}
2631

    
2632
void tcg_register_jit(void *buf, size_t buf_size)
2633
{
2634
}
2635
#endif /* ELF_HOST_MACHINE */