Statistics
| Branch: | Revision:

root / tcg / tcg.c @ d73685e3

History | View | Annotate | Download (75.6 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
#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
66
#error GUEST_BASE not supported on this host.
67
#endif
68

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

    
75
static void tcg_register_jit_int(void *buf, size_t size,
76
                                 void *debug_frame, size_t debug_frame_size)
77
    __attribute__((unused));
78

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

    
94
TCGOpDef tcg_op_defs[] = {
95
#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
96
#include "tcg-opc.h"
97
#undef DEF
98
};
99
const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
100

    
101
static TCGRegSet tcg_target_available_regs[2];
102
static TCGRegSet tcg_target_call_clobber_regs;
103

    
104
/* XXX: move that inside the context */
105
uint16_t *gen_opc_ptr;
106
TCGArg *gen_opparam_ptr;
107

    
108
static inline void tcg_out8(TCGContext *s, uint8_t v)
109
{
110
    *s->code_ptr++ = v;
111
}
112

    
113
static inline void tcg_out16(TCGContext *s, uint16_t v)
114
{
115
    *(uint16_t *)s->code_ptr = v;
116
    s->code_ptr += 2;
117
}
118

    
119
static inline void tcg_out32(TCGContext *s, uint32_t v)
120
{
121
    *(uint32_t *)s->code_ptr = v;
122
    s->code_ptr += 4;
123
}
124

    
125
/* label relocation processing */
126

    
127
static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
128
                          int label_index, long addend)
129
{
130
    TCGLabel *l;
131
    TCGRelocation *r;
132

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

    
150
static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
151
{
152
    TCGLabel *l;
153
    TCGRelocation *r;
154
    tcg_target_long value = (tcg_target_long)ptr;
155

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

    
168
int gen_new_label(void)
169
{
170
    TCGContext *s = &tcg_ctx;
171
    int idx;
172
    TCGLabel *l;
173

    
174
    if (s->nb_labels >= TCG_MAX_LABELS)
175
        tcg_abort();
176
    idx = s->nb_labels++;
177
    l = &s->labels[idx];
178
    l->has_value = 0;
179
    l->u.first_reloc = NULL;
180
    return idx;
181
}
182

    
183
#include "tcg-target.c"
184

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

    
226
void tcg_pool_reset(TCGContext *s)
227
{
228
    TCGPool *p, *t;
229
    for (p = s->pool_first_large; p; p = t) {
230
        t = p->next;
231
        g_free(p);
232
    }
233
    s->pool_first_large = NULL;
234
    s->pool_cur = s->pool_end = NULL;
235
    s->pool_current = NULL;
236
}
237

    
238
void tcg_context_init(TCGContext *s)
239
{
240
    int op, total_args, n;
241
    TCGOpDef *def;
242
    TCGArgConstraint *args_ct;
243
    int *sorted_args;
244

    
245
    memset(s, 0, sizeof(*s));
246
    s->temps = s->static_temps;
247
    s->nb_globals = 0;
248
    
249
    /* Count total number of arguments and allocate the corresponding
250
       space */
251
    total_args = 0;
252
    for(op = 0; op < NB_OPS; op++) {
253
        def = &tcg_op_defs[op];
254
        n = def->nb_iargs + def->nb_oargs;
255
        total_args += n;
256
    }
257

    
258
    args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
259
    sorted_args = g_malloc(sizeof(int) * total_args);
260

    
261
    for(op = 0; op < NB_OPS; op++) {
262
        def = &tcg_op_defs[op];
263
        def->args_ct = args_ct;
264
        def->sorted_args = sorted_args;
265
        n = def->nb_iargs + def->nb_oargs;
266
        sorted_args += n;
267
        args_ct += n;
268
    }
269
    
270
    tcg_target_init(s);
271
}
272

    
273
void tcg_prologue_init(TCGContext *s)
274
{
275
    /* init global prologue and epilogue */
276
    s->code_buf = code_gen_prologue;
277
    s->code_ptr = s->code_buf;
278
    tcg_target_qemu_prologue(s);
279
    flush_icache_range((tcg_target_ulong)s->code_buf,
280
                       (tcg_target_ulong)s->code_ptr);
281
}
282

    
283
void tcg_set_frame(TCGContext *s, int reg,
284
                   tcg_target_long start, tcg_target_long size)
285
{
286
    s->frame_start = start;
287
    s->frame_end = start + size;
288
    s->frame_reg = reg;
289
}
290

    
291
void tcg_func_start(TCGContext *s)
292
{
293
    int i;
294
    tcg_pool_reset(s);
295
    s->nb_temps = s->nb_globals;
296
    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
297
        s->first_free_temp[i] = -1;
298
    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
299
    s->nb_labels = 0;
300
    s->current_frame_offset = s->frame_start;
301

    
302
    gen_opc_ptr = gen_opc_buf;
303
    gen_opparam_ptr = gen_opparam_buf;
304
}
305

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

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

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

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

    
342
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
343
    return MAKE_TCGV_I32(idx);
344
}
345

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

    
350
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
351
    return MAKE_TCGV_I64(idx);
352
}
353

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

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

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

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

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

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

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

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

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

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

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

    
488
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
489
{
490
    int idx;
491

    
492
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
493
    return MAKE_TCGV_I32(idx);
494
}
495

    
496
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
497
{
498
    int idx;
499

    
500
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
501
    return MAKE_TCGV_I64(idx);
502
}
503

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

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

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

    
528
void tcg_temp_free_i32(TCGv_i32 arg)
529
{
530
    tcg_temp_free_internal(GET_TCGV_I32(arg));
531
}
532

    
533
void tcg_temp_free_i64(TCGv_i64 arg)
534
{
535
    tcg_temp_free_internal(GET_TCGV_I64(arg));
536
}
537

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

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

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

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

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

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

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

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

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

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

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

    
699
    *gen_opparam_ptr++ = flags;
700

    
701
    *nparam = (nb_rets << 16) | (real_args + 1);
702

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

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

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

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

    
766

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

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

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

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

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

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

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

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

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

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

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

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

    
910
            /* variable number of arguments */
911
            arg = *args++;
912
            nb_oargs = arg >> 16;
913
            nb_iargs = arg & 0xffff;
914
            nb_cargs = def->nb_cargs;
915

    
916
            qemu_log(" %s ", def->name);
917

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

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

    
1021
/* we give more priority to constraints with less registers */
1022
static int get_constraint_priority(const TCGOpDef *def, int k)
1023
{
1024
    const TCGArgConstraint *arg_ct;
1025

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

    
1043
/* sort from highest priority to lowest */
1044
static void sort_constraints(TCGOpDef *def, int start, int n)
1045
{
1046
    int i, j, p1, p2, tmp;
1047

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

    
1065
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1066
{
1067
    TCGOpcode op;
1068
    TCGOpDef *def;
1069
    const char *ct_str;
1070
    int i, nb_args;
1071

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

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

    
1125
        /* sort the constraints (XXX: this is just an heuristic) */
1126
        sort_constraints(def, 0, def->nb_oargs);
1127
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1128

    
1129
#if 0
1130
        {
1131
            int i;
1132

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

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

    
1168
#ifdef USE_LIVENESS_ANALYSIS
1169

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

    
1183
/* liveness analysis: end of function: globals are live, temps are
1184
   dead. */
1185
/* XXX: at this stage, not used as there would be little gains because
1186
   most TBs end with a conditional jump. */
1187
static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
1188
{
1189
    memset(dead_temps, 0, s->nb_globals);
1190
    memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
1191
}
1192

    
1193
/* liveness analysis: end of basic block: globals are live, temps are
1194
   dead, local temps are live. */
1195
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1196
{
1197
    int i;
1198
    TCGTemp *ts;
1199

    
1200
    memset(dead_temps, 0, s->nb_globals);
1201
    ts = &s->temps[s->nb_globals];
1202
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1203
        if (ts->temp_local)
1204
            dead_temps[i] = 0;
1205
        else
1206
            dead_temps[i] = 1;
1207
        ts++;
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;
1221
    unsigned int dead_args;
1222
    
1223
    gen_opc_ptr++; /* skip end */
1224

    
1225
    nb_ops = gen_opc_ptr - gen_opc_buf;
1226

    
1227
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1228
    
1229
    dead_temps = tcg_malloc(s->nb_temps);
1230
    memset(dead_temps, 1, s->nb_temps);
1231

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

    
1242
                nb_args = args[-1];
1243
                args -= nb_args;
1244
                nb_iargs = args[0] & 0xffff;
1245
                nb_oargs = args[0] >> 16;
1246
                args++;
1247
                call_flags = args[nb_oargs + nb_iargs];
1248

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

    
1262
                    /* output args are dead */
1263
                    dead_args = 0;
1264
                    for(i = 0; i < nb_oargs; i++) {
1265
                        arg = args[i];
1266
                        if (dead_temps[arg]) {
1267
                            dead_args |= (1 << i);
1268
                        }
1269
                        dead_temps[arg] = 1;
1270
                    }
1271
                    
1272
                    if (!(call_flags & TCG_CALL_CONST)) {
1273
                        /* globals are live (they may be used by the call) */
1274
                        memset(dead_temps, 0, s->nb_globals);
1275
                    }
1276

    
1277
                    /* input args are live */
1278
                    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1279
                        arg = args[i];
1280
                        if (arg != TCG_CALL_DUMMY_ARG) {
1281
                            if (dead_temps[arg]) {
1282
                                dead_args |= (1 << i);
1283
                            }
1284
                            dead_temps[arg] = 0;
1285
                        }
1286
                    }
1287
                    s->op_dead_args[op_index] = dead_args;
1288
                }
1289
                args--;
1290
            }
1291
            break;
1292
        case INDEX_op_debug_insn_start:
1293
            args -= def->nb_args;
1294
            break;
1295
        case INDEX_op_nopn:
1296
            nb_args = args[-1];
1297
            args -= nb_args;
1298
            break;
1299
        case INDEX_op_discard:
1300
            args--;
1301
            /* mark the temporary as dead */
1302
            dead_temps[args[0]] = 1;
1303
            break;
1304
        case INDEX_op_end:
1305
            break;
1306
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1307
        default:
1308
            args -= def->nb_args;
1309
            nb_iargs = def->nb_iargs;
1310
            nb_oargs = def->nb_oargs;
1311

    
1312
            /* Test if the operation can be removed because all
1313
               its outputs are dead. We assume that nb_oargs == 0
1314
               implies side effects */
1315
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1316
                for(i = 0; i < nb_oargs; i++) {
1317
                    arg = args[i];
1318
                    if (!dead_temps[arg])
1319
                        goto do_not_remove;
1320
                }
1321
                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1322
#ifdef CONFIG_PROFILER
1323
                s->del_op_count++;
1324
#endif
1325
            } else {
1326
            do_not_remove:
1327

    
1328
                /* output args are dead */
1329
                dead_args = 0;
1330
                for(i = 0; i < nb_oargs; i++) {
1331
                    arg = args[i];
1332
                    if (dead_temps[arg]) {
1333
                        dead_args |= (1 << i);
1334
                    }
1335
                    dead_temps[arg] = 1;
1336
                }
1337

    
1338
                /* if end of basic block, update */
1339
                if (def->flags & TCG_OPF_BB_END) {
1340
                    tcg_la_bb_end(s, dead_temps);
1341
                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1342
                    /* globals are live */
1343
                    memset(dead_temps, 0, s->nb_globals);
1344
                }
1345

    
1346
                /* input args are live */
1347
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1348
                    arg = args[i];
1349
                    if (dead_temps[arg]) {
1350
                        dead_args |= (1 << i);
1351
                    }
1352
                    dead_temps[arg] = 0;
1353
                }
1354
                s->op_dead_args[op_index] = dead_args;
1355
            }
1356
            break;
1357
        }
1358
        op_index--;
1359
    }
1360

    
1361
    if (args != gen_opparam_buf)
1362
        tcg_abort();
1363
}
1364
#else
1365
/* dummy liveness analysis */
1366
static void tcg_liveness_analysis(TCGContext *s)
1367
{
1368
    int nb_ops;
1369
    nb_ops = gen_opc_ptr - gen_opc_buf;
1370

    
1371
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1372
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1373
}
1374
#endif
1375

    
1376
#ifndef NDEBUG
1377
static void dump_regs(TCGContext *s)
1378
{
1379
    TCGTemp *ts;
1380
    int i;
1381
    char buf[64];
1382

    
1383
    for(i = 0; i < s->nb_temps; i++) {
1384
        ts = &s->temps[i];
1385
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1386
        switch(ts->val_type) {
1387
        case TEMP_VAL_REG:
1388
            printf("%s", tcg_target_reg_names[ts->reg]);
1389
            break;
1390
        case TEMP_VAL_MEM:
1391
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1392
            break;
1393
        case TEMP_VAL_CONST:
1394
            printf("$0x%" TCG_PRIlx, ts->val);
1395
            break;
1396
        case TEMP_VAL_DEAD:
1397
            printf("D");
1398
            break;
1399
        default:
1400
            printf("???");
1401
            break;
1402
        }
1403
        printf("\n");
1404
    }
1405

    
1406
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1407
        if (s->reg_to_temp[i] >= 0) {
1408
            printf("%s: %s\n", 
1409
                   tcg_target_reg_names[i], 
1410
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1411
        }
1412
    }
1413
}
1414

    
1415
static void check_regs(TCGContext *s)
1416
{
1417
    int reg, k;
1418
    TCGTemp *ts;
1419
    char buf[64];
1420

    
1421
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1422
        k = s->reg_to_temp[reg];
1423
        if (k >= 0) {
1424
            ts = &s->temps[k];
1425
            if (ts->val_type != TEMP_VAL_REG ||
1426
                ts->reg != reg) {
1427
                printf("Inconsistency for register %s:\n", 
1428
                       tcg_target_reg_names[reg]);
1429
                goto fail;
1430
            }
1431
        }
1432
    }
1433
    for(k = 0; k < s->nb_temps; k++) {
1434
        ts = &s->temps[k];
1435
        if (ts->val_type == TEMP_VAL_REG &&
1436
            !ts->fixed_reg &&
1437
            s->reg_to_temp[ts->reg] != k) {
1438
                printf("Inconsistency for temp %s:\n", 
1439
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1440
        fail:
1441
                printf("reg state:\n");
1442
                dump_regs(s);
1443
                tcg_abort();
1444
        }
1445
    }
1446
}
1447
#endif
1448

    
1449
static void temp_allocate_frame(TCGContext *s, int temp)
1450
{
1451
    TCGTemp *ts;
1452
    ts = &s->temps[temp];
1453
#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
1454
    s->current_frame_offset = (s->current_frame_offset +
1455
                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
1456
        ~(sizeof(tcg_target_long) - 1);
1457
#endif
1458
    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1459
        s->frame_end) {
1460
        tcg_abort();
1461
    }
1462
    ts->mem_offset = s->current_frame_offset;
1463
    ts->mem_reg = s->frame_reg;
1464
    ts->mem_allocated = 1;
1465
    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1466
}
1467

    
1468
/* free register 'reg' by spilling the corresponding temporary if necessary */
1469
static void tcg_reg_free(TCGContext *s, int reg)
1470
{
1471
    TCGTemp *ts;
1472
    int temp;
1473

    
1474
    temp = s->reg_to_temp[reg];
1475
    if (temp != -1) {
1476
        ts = &s->temps[temp];
1477
        assert(ts->val_type == TEMP_VAL_REG);
1478
        if (!ts->mem_coherent) {
1479
            if (!ts->mem_allocated) 
1480
                temp_allocate_frame(s, temp);
1481
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1482
        }
1483
        ts->val_type = TEMP_VAL_MEM;
1484
        s->reg_to_temp[reg] = -1;
1485
    }
1486
}
1487

    
1488
/* Allocate a register belonging to reg1 & ~reg2 */
1489
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1490
{
1491
    int i, reg;
1492
    TCGRegSet reg_ct;
1493

    
1494
    tcg_regset_andnot(reg_ct, reg1, reg2);
1495

    
1496
    /* first try free registers */
1497
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1498
        reg = tcg_target_reg_alloc_order[i];
1499
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1500
            return reg;
1501
    }
1502

    
1503
    /* XXX: do better spill choice */
1504
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1505
        reg = tcg_target_reg_alloc_order[i];
1506
        if (tcg_regset_test_reg(reg_ct, reg)) {
1507
            tcg_reg_free(s, reg);
1508
            return reg;
1509
        }
1510
    }
1511

    
1512
    tcg_abort();
1513
}
1514

    
1515
/* save a temporary to memory. 'allocated_regs' is used in case a
1516
   temporary registers needs to be allocated to store a constant. */
1517
static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1518
{
1519
    TCGTemp *ts;
1520
    int reg;
1521

    
1522
    ts = &s->temps[temp];
1523
    if (!ts->fixed_reg) {
1524
        switch(ts->val_type) {
1525
        case TEMP_VAL_REG:
1526
            tcg_reg_free(s, ts->reg);
1527
            break;
1528
        case TEMP_VAL_DEAD:
1529
            ts->val_type = TEMP_VAL_MEM;
1530
            break;
1531
        case TEMP_VAL_CONST:
1532
            reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1533
                                allocated_regs);
1534
            if (!ts->mem_allocated) 
1535
                temp_allocate_frame(s, temp);
1536
            tcg_out_movi(s, ts->type, reg, ts->val);
1537
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1538
            ts->val_type = TEMP_VAL_MEM;
1539
            break;
1540
        case TEMP_VAL_MEM:
1541
            break;
1542
        default:
1543
            tcg_abort();
1544
        }
1545
    }
1546
}
1547

    
1548
/* save globals to their canonical location and assume they can be
1549
   modified be the following code. 'allocated_regs' is used in case a
1550
   temporary registers needs to be allocated to store a constant. */
1551
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1552
{
1553
    int i;
1554

    
1555
    for(i = 0; i < s->nb_globals; i++) {
1556
        temp_save(s, i, allocated_regs);
1557
    }
1558
}
1559

    
1560
/* at the end of a basic block, we assume all temporaries are dead and
1561
   all globals are stored at their canonical location. */
1562
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1563
{
1564
    TCGTemp *ts;
1565
    int i;
1566

    
1567
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1568
        ts = &s->temps[i];
1569
        if (ts->temp_local) {
1570
            temp_save(s, i, allocated_regs);
1571
        } else {
1572
            if (ts->val_type == TEMP_VAL_REG) {
1573
                s->reg_to_temp[ts->reg] = -1;
1574
            }
1575
            ts->val_type = TEMP_VAL_DEAD;
1576
        }
1577
    }
1578

    
1579
    save_globals(s, allocated_regs);
1580
}
1581

    
1582
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1583

    
1584
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1585
{
1586
    TCGTemp *ots;
1587
    tcg_target_ulong val;
1588

    
1589
    ots = &s->temps[args[0]];
1590
    val = args[1];
1591

    
1592
    if (ots->fixed_reg) {
1593
        /* for fixed registers, we do not do any constant
1594
           propagation */
1595
        tcg_out_movi(s, ots->type, ots->reg, val);
1596
    } else {
1597
        /* The movi is not explicitly generated here */
1598
        if (ots->val_type == TEMP_VAL_REG)
1599
            s->reg_to_temp[ots->reg] = -1;
1600
        ots->val_type = TEMP_VAL_CONST;
1601
        ots->val = val;
1602
    }
1603
}
1604

    
1605
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1606
                              const TCGArg *args,
1607
                              unsigned int dead_args)
1608
{
1609
    TCGTemp *ts, *ots;
1610
    int reg;
1611
    const TCGArgConstraint *arg_ct;
1612

    
1613
    ots = &s->temps[args[0]];
1614
    ts = &s->temps[args[1]];
1615
    arg_ct = &def->args_ct[0];
1616

    
1617
    /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1618
    if (ts->val_type == TEMP_VAL_REG) {
1619
        if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1620
            /* the mov can be suppressed */
1621
            if (ots->val_type == TEMP_VAL_REG)
1622
                s->reg_to_temp[ots->reg] = -1;
1623
            reg = ts->reg;
1624
            s->reg_to_temp[reg] = -1;
1625
            ts->val_type = TEMP_VAL_DEAD;
1626
        } else {
1627
            if (ots->val_type == TEMP_VAL_REG) {
1628
                reg = ots->reg;
1629
            } else {
1630
                reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1631
            }
1632
            if (ts->reg != reg) {
1633
                tcg_out_mov(s, ots->type, reg, ts->reg);
1634
            }
1635
        }
1636
    } else if (ts->val_type == TEMP_VAL_MEM) {
1637
        if (ots->val_type == TEMP_VAL_REG) {
1638
            reg = ots->reg;
1639
        } else {
1640
            reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1641
        }
1642
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1643
    } else if (ts->val_type == TEMP_VAL_CONST) {
1644
        if (ots->fixed_reg) {
1645
            reg = ots->reg;
1646
            tcg_out_movi(s, ots->type, reg, ts->val);
1647
        } else {
1648
            /* propagate constant */
1649
            if (ots->val_type == TEMP_VAL_REG)
1650
                s->reg_to_temp[ots->reg] = -1;
1651
            ots->val_type = TEMP_VAL_CONST;
1652
            ots->val = ts->val;
1653
            return;
1654
        }
1655
    } else {
1656
        tcg_abort();
1657
    }
1658
    s->reg_to_temp[reg] = args[0];
1659
    ots->reg = reg;
1660
    ots->val_type = TEMP_VAL_REG;
1661
    ots->mem_coherent = 0;
1662
}
1663

    
1664
static void tcg_reg_alloc_op(TCGContext *s, 
1665
                             const TCGOpDef *def, TCGOpcode opc,
1666
                             const TCGArg *args,
1667
                             unsigned int dead_args)
1668
{
1669
    TCGRegSet allocated_regs;
1670
    int i, k, nb_iargs, nb_oargs, reg;
1671
    TCGArg arg;
1672
    const TCGArgConstraint *arg_ct;
1673
    TCGTemp *ts;
1674
    TCGArg new_args[TCG_MAX_OP_ARGS];
1675
    int const_args[TCG_MAX_OP_ARGS];
1676

    
1677
    nb_oargs = def->nb_oargs;
1678
    nb_iargs = def->nb_iargs;
1679

    
1680
    /* copy constants */
1681
    memcpy(new_args + nb_oargs + nb_iargs, 
1682
           args + nb_oargs + nb_iargs, 
1683
           sizeof(TCGArg) * def->nb_cargs);
1684

    
1685
    /* satisfy input constraints */ 
1686
    tcg_regset_set(allocated_regs, s->reserved_regs);
1687
    for(k = 0; k < nb_iargs; k++) {
1688
        i = def->sorted_args[nb_oargs + k];
1689
        arg = args[i];
1690
        arg_ct = &def->args_ct[i];
1691
        ts = &s->temps[arg];
1692
        if (ts->val_type == TEMP_VAL_MEM) {
1693
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1694
            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1695
            ts->val_type = TEMP_VAL_REG;
1696
            ts->reg = reg;
1697
            ts->mem_coherent = 1;
1698
            s->reg_to_temp[reg] = arg;
1699
        } else if (ts->val_type == TEMP_VAL_CONST) {
1700
            if (tcg_target_const_match(ts->val, arg_ct)) {
1701
                /* constant is OK for instruction */
1702
                const_args[i] = 1;
1703
                new_args[i] = ts->val;
1704
                goto iarg_end;
1705
            } else {
1706
                /* need to move to a register */
1707
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1708
                tcg_out_movi(s, ts->type, reg, ts->val);
1709
                ts->val_type = TEMP_VAL_REG;
1710
                ts->reg = reg;
1711
                ts->mem_coherent = 0;
1712
                s->reg_to_temp[reg] = arg;
1713
            }
1714
        }
1715
        assert(ts->val_type == TEMP_VAL_REG);
1716
        if (arg_ct->ct & TCG_CT_IALIAS) {
1717
            if (ts->fixed_reg) {
1718
                /* if fixed register, we must allocate a new register
1719
                   if the alias is not the same register */
1720
                if (arg != args[arg_ct->alias_index])
1721
                    goto allocate_in_reg;
1722
            } else {
1723
                /* if the input is aliased to an output and if it is
1724
                   not dead after the instruction, we must allocate
1725
                   a new register and move it */
1726
                if (!IS_DEAD_ARG(i)) {
1727
                    goto allocate_in_reg;
1728
                }
1729
            }
1730
        }
1731
        reg = ts->reg;
1732
        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1733
            /* nothing to do : the constraint is satisfied */
1734
        } else {
1735
        allocate_in_reg:
1736
            /* allocate a new register matching the constraint 
1737
               and move the temporary register into it */
1738
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1739
            tcg_out_mov(s, ts->type, reg, ts->reg);
1740
        }
1741
        new_args[i] = reg;
1742
        const_args[i] = 0;
1743
        tcg_regset_set_reg(allocated_regs, reg);
1744
    iarg_end: ;
1745
    }
1746
    
1747
    if (def->flags & TCG_OPF_BB_END) {
1748
        tcg_reg_alloc_bb_end(s, allocated_regs);
1749
    } else {
1750
        /* mark dead temporaries and free the associated registers */
1751
        for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1752
            arg = args[i];
1753
            if (IS_DEAD_ARG(i)) {
1754
                ts = &s->temps[arg];
1755
                if (!ts->fixed_reg) {
1756
                    if (ts->val_type == TEMP_VAL_REG)
1757
                        s->reg_to_temp[ts->reg] = -1;
1758
                    ts->val_type = TEMP_VAL_DEAD;
1759
                }
1760
            }
1761
        }
1762
        
1763
        if (def->flags & TCG_OPF_CALL_CLOBBER) {
1764
            /* XXX: permit generic clobber register list ? */ 
1765
            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1766
                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1767
                    tcg_reg_free(s, reg);
1768
                }
1769
            }
1770
            /* XXX: for load/store we could do that only for the slow path
1771
               (i.e. when a memory callback is called) */
1772
            
1773
            /* store globals and free associated registers (we assume the insn
1774
               can modify any global. */
1775
            save_globals(s, allocated_regs);
1776
        }
1777
        
1778
        /* satisfy the output constraints */
1779
        tcg_regset_set(allocated_regs, s->reserved_regs);
1780
        for(k = 0; k < nb_oargs; k++) {
1781
            i = def->sorted_args[k];
1782
            arg = args[i];
1783
            arg_ct = &def->args_ct[i];
1784
            ts = &s->temps[arg];
1785
            if (arg_ct->ct & TCG_CT_ALIAS) {
1786
                reg = new_args[arg_ct->alias_index];
1787
            } else {
1788
                /* if fixed register, we try to use it */
1789
                reg = ts->reg;
1790
                if (ts->fixed_reg &&
1791
                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1792
                    goto oarg_end;
1793
                }
1794
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1795
            }
1796
            tcg_regset_set_reg(allocated_regs, reg);
1797
            /* if a fixed register is used, then a move will be done afterwards */
1798
            if (!ts->fixed_reg) {
1799
                if (ts->val_type == TEMP_VAL_REG)
1800
                    s->reg_to_temp[ts->reg] = -1;
1801
                if (IS_DEAD_ARG(i)) {
1802
                    ts->val_type = TEMP_VAL_DEAD;
1803
                } else {
1804
                    ts->val_type = TEMP_VAL_REG;
1805
                    ts->reg = reg;
1806
                    /* temp value is modified, so the value kept in memory is
1807
                       potentially not the same */
1808
                    ts->mem_coherent = 0;
1809
                    s->reg_to_temp[reg] = arg;
1810
               }
1811
            }
1812
        oarg_end:
1813
            new_args[i] = reg;
1814
        }
1815
    }
1816

    
1817
    /* emit instruction */
1818
    tcg_out_op(s, opc, new_args, const_args);
1819
    
1820
    /* move the outputs in the correct register if needed */
1821
    for(i = 0; i < nb_oargs; i++) {
1822
        ts = &s->temps[args[i]];
1823
        reg = new_args[i];
1824
        if (ts->fixed_reg && ts->reg != reg) {
1825
            tcg_out_mov(s, ts->type, ts->reg, reg);
1826
        }
1827
    }
1828
}
1829

    
1830
#ifdef TCG_TARGET_STACK_GROWSUP
1831
#define STACK_DIR(x) (-(x))
1832
#else
1833
#define STACK_DIR(x) (x)
1834
#endif
1835

    
1836
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1837
                              TCGOpcode opc, const TCGArg *args,
1838
                              unsigned int dead_args)
1839
{
1840
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1841
    TCGArg arg, func_arg;
1842
    TCGTemp *ts;
1843
    tcg_target_long stack_offset, call_stack_size, func_addr;
1844
    int const_func_arg, allocate_args;
1845
    TCGRegSet allocated_regs;
1846
    const TCGArgConstraint *arg_ct;
1847

    
1848
    arg = *args++;
1849

    
1850
    nb_oargs = arg >> 16;
1851
    nb_iargs = arg & 0xffff;
1852
    nb_params = nb_iargs - 1;
1853

    
1854
    flags = args[nb_oargs + nb_iargs];
1855

    
1856
    nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1857
    if (nb_regs > nb_params)
1858
        nb_regs = nb_params;
1859

    
1860
    /* assign stack slots first */
1861
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1862
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1863
        ~(TCG_TARGET_STACK_ALIGN - 1);
1864
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1865
    if (allocate_args) {
1866
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1867
           preallocate call stack */
1868
        tcg_abort();
1869
    }
1870

    
1871
    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1872
    for(i = nb_regs; i < nb_params; i++) {
1873
        arg = args[nb_oargs + i];
1874
#ifdef TCG_TARGET_STACK_GROWSUP
1875
        stack_offset -= sizeof(tcg_target_long);
1876
#endif
1877
        if (arg != TCG_CALL_DUMMY_ARG) {
1878
            ts = &s->temps[arg];
1879
            if (ts->val_type == TEMP_VAL_REG) {
1880
                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1881
            } else if (ts->val_type == TEMP_VAL_MEM) {
1882
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1883
                                    s->reserved_regs);
1884
                /* XXX: not correct if reading values from the stack */
1885
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1886
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1887
            } else if (ts->val_type == TEMP_VAL_CONST) {
1888
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1889
                                    s->reserved_regs);
1890
                /* XXX: sign extend may be needed on some targets */
1891
                tcg_out_movi(s, ts->type, reg, ts->val);
1892
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1893
            } else {
1894
                tcg_abort();
1895
            }
1896
        }
1897
#ifndef TCG_TARGET_STACK_GROWSUP
1898
        stack_offset += sizeof(tcg_target_long);
1899
#endif
1900
    }
1901
    
1902
    /* assign input registers */
1903
    tcg_regset_set(allocated_regs, s->reserved_regs);
1904
    for(i = 0; i < nb_regs; i++) {
1905
        arg = args[nb_oargs + i];
1906
        if (arg != TCG_CALL_DUMMY_ARG) {
1907
            ts = &s->temps[arg];
1908
            reg = tcg_target_call_iarg_regs[i];
1909
            tcg_reg_free(s, reg);
1910
            if (ts->val_type == TEMP_VAL_REG) {
1911
                if (ts->reg != reg) {
1912
                    tcg_out_mov(s, ts->type, reg, ts->reg);
1913
                }
1914
            } else if (ts->val_type == TEMP_VAL_MEM) {
1915
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1916
            } else if (ts->val_type == TEMP_VAL_CONST) {
1917
                /* XXX: sign extend ? */
1918
                tcg_out_movi(s, ts->type, reg, ts->val);
1919
            } else {
1920
                tcg_abort();
1921
            }
1922
            tcg_regset_set_reg(allocated_regs, reg);
1923
        }
1924
    }
1925
    
1926
    /* assign function address */
1927
    func_arg = args[nb_oargs + nb_iargs - 1];
1928
    arg_ct = &def->args_ct[0];
1929
    ts = &s->temps[func_arg];
1930
    func_addr = ts->val;
1931
    const_func_arg = 0;
1932
    if (ts->val_type == TEMP_VAL_MEM) {
1933
        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1934
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1935
        func_arg = reg;
1936
        tcg_regset_set_reg(allocated_regs, reg);
1937
    } else if (ts->val_type == TEMP_VAL_REG) {
1938
        reg = ts->reg;
1939
        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1940
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1941
            tcg_out_mov(s, ts->type, reg, ts->reg);
1942
        }
1943
        func_arg = reg;
1944
        tcg_regset_set_reg(allocated_regs, reg);
1945
    } else if (ts->val_type == TEMP_VAL_CONST) {
1946
        if (tcg_target_const_match(func_addr, arg_ct)) {
1947
            const_func_arg = 1;
1948
            func_arg = func_addr;
1949
        } else {
1950
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1951
            tcg_out_movi(s, ts->type, reg, func_addr);
1952
            func_arg = reg;
1953
            tcg_regset_set_reg(allocated_regs, reg);
1954
        }
1955
    } else {
1956
        tcg_abort();
1957
    }
1958
        
1959
    
1960
    /* mark dead temporaries and free the associated registers */
1961
    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1962
        arg = args[i];
1963
        if (IS_DEAD_ARG(i)) {
1964
            ts = &s->temps[arg];
1965
            if (!ts->fixed_reg) {
1966
                if (ts->val_type == TEMP_VAL_REG)
1967
                    s->reg_to_temp[ts->reg] = -1;
1968
                ts->val_type = TEMP_VAL_DEAD;
1969
            }
1970
        }
1971
    }
1972
    
1973
    /* clobber call registers */
1974
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1975
        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1976
            tcg_reg_free(s, reg);
1977
        }
1978
    }
1979
    
1980
    /* store globals and free associated registers (we assume the call
1981
       can modify any global. */
1982
    if (!(flags & TCG_CALL_CONST)) {
1983
        save_globals(s, allocated_regs);
1984
    }
1985

    
1986
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
1987

    
1988
    /* assign output registers and emit moves if needed */
1989
    for(i = 0; i < nb_oargs; i++) {
1990
        arg = args[i];
1991
        ts = &s->temps[arg];
1992
        reg = tcg_target_call_oarg_regs[i];
1993
        assert(s->reg_to_temp[reg] == -1);
1994
        if (ts->fixed_reg) {
1995
            if (ts->reg != reg) {
1996
                tcg_out_mov(s, ts->type, ts->reg, reg);
1997
            }
1998
        } else {
1999
            if (ts->val_type == TEMP_VAL_REG)
2000
                s->reg_to_temp[ts->reg] = -1;
2001
            if (IS_DEAD_ARG(i)) {
2002
                ts->val_type = TEMP_VAL_DEAD;
2003
            } else {
2004
                ts->val_type = TEMP_VAL_REG;
2005
                ts->reg = reg;
2006
                ts->mem_coherent = 0;
2007
                s->reg_to_temp[reg] = arg;
2008
            }
2009
        }
2010
    }
2011
    
2012
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2013
}
2014

    
2015
#ifdef CONFIG_PROFILER
2016

    
2017
static int64_t tcg_table_op_count[NB_OPS];
2018

    
2019
static void dump_op_count(void)
2020
{
2021
    int i;
2022
    FILE *f;
2023
    f = fopen("/tmp/op.log", "w");
2024
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2025
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2026
    }
2027
    fclose(f);
2028
}
2029
#endif
2030

    
2031

    
2032
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2033
                                      long search_pc)
2034
{
2035
    TCGOpcode opc;
2036
    int op_index;
2037
    const TCGOpDef *def;
2038
    unsigned int dead_args;
2039
    const TCGArg *args;
2040

    
2041
#ifdef DEBUG_DISAS
2042
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2043
        qemu_log("OP:\n");
2044
        tcg_dump_ops(s);
2045
        qemu_log("\n");
2046
    }
2047
#endif
2048

    
2049
#ifdef CONFIG_PROFILER
2050
    s->opt_time -= profile_getclock();
2051
#endif
2052

    
2053
#ifdef USE_TCG_OPTIMIZATIONS
2054
    gen_opparam_ptr =
2055
        tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2056
#endif
2057

    
2058
#ifdef CONFIG_PROFILER
2059
    s->opt_time += profile_getclock();
2060
    s->la_time -= profile_getclock();
2061
#endif
2062

    
2063
    tcg_liveness_analysis(s);
2064

    
2065
#ifdef CONFIG_PROFILER
2066
    s->la_time += profile_getclock();
2067
#endif
2068

    
2069
#ifdef DEBUG_DISAS
2070
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2071
        qemu_log("OP after optimization and liveness analysis:\n");
2072
        tcg_dump_ops(s);
2073
        qemu_log("\n");
2074
    }
2075
#endif
2076

    
2077
    tcg_reg_alloc_start(s);
2078

    
2079
    s->code_buf = gen_code_buf;
2080
    s->code_ptr = gen_code_buf;
2081

    
2082
    args = gen_opparam_buf;
2083
    op_index = 0;
2084

    
2085
    for(;;) {
2086
        opc = gen_opc_buf[op_index];
2087
#ifdef CONFIG_PROFILER
2088
        tcg_table_op_count[opc]++;
2089
#endif
2090
        def = &tcg_op_defs[opc];
2091
#if 0
2092
        printf("%s: %d %d %d\n", def->name,
2093
               def->nb_oargs, def->nb_iargs, def->nb_cargs);
2094
        //        dump_regs(s);
2095
#endif
2096
        switch(opc) {
2097
        case INDEX_op_mov_i32:
2098
        case INDEX_op_mov_i64:
2099
            dead_args = s->op_dead_args[op_index];
2100
            tcg_reg_alloc_mov(s, def, args, dead_args);
2101
            break;
2102
        case INDEX_op_movi_i32:
2103
        case INDEX_op_movi_i64:
2104
            tcg_reg_alloc_movi(s, args);
2105
            break;
2106
        case INDEX_op_debug_insn_start:
2107
            /* debug instruction */
2108
            break;
2109
        case INDEX_op_nop:
2110
        case INDEX_op_nop1:
2111
        case INDEX_op_nop2:
2112
        case INDEX_op_nop3:
2113
            break;
2114
        case INDEX_op_nopn:
2115
            args += args[0];
2116
            goto next;
2117
        case INDEX_op_discard:
2118
            {
2119
                TCGTemp *ts;
2120
                ts = &s->temps[args[0]];
2121
                /* mark the temporary as dead */
2122
                if (!ts->fixed_reg) {
2123
                    if (ts->val_type == TEMP_VAL_REG)
2124
                        s->reg_to_temp[ts->reg] = -1;
2125
                    ts->val_type = TEMP_VAL_DEAD;
2126
                }
2127
            }
2128
            break;
2129
        case INDEX_op_set_label:
2130
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
2131
            tcg_out_label(s, args[0], s->code_ptr);
2132
            break;
2133
        case INDEX_op_call:
2134
            dead_args = s->op_dead_args[op_index];
2135
            args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2136
            goto next;
2137
        case INDEX_op_end:
2138
            goto the_end;
2139
        default:
2140
            /* Sanity check that we've not introduced any unhandled opcodes. */
2141
            if (def->flags & TCG_OPF_NOT_PRESENT) {
2142
                tcg_abort();
2143
            }
2144
            /* Note: in order to speed up the code, it would be much
2145
               faster to have specialized register allocator functions for
2146
               some common argument patterns */
2147
            dead_args = s->op_dead_args[op_index];
2148
            tcg_reg_alloc_op(s, def, opc, args, dead_args);
2149
            break;
2150
        }
2151
        args += def->nb_args;
2152
    next:
2153
        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2154
            return op_index;
2155
        }
2156
        op_index++;
2157
#ifndef NDEBUG
2158
        check_regs(s);
2159
#endif
2160
    }
2161
 the_end:
2162
    return -1;
2163
}
2164

    
2165
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2166
{
2167
#ifdef CONFIG_PROFILER
2168
    {
2169
        int n;
2170
        n = (gen_opc_ptr - gen_opc_buf);
2171
        s->op_count += n;
2172
        if (n > s->op_count_max)
2173
            s->op_count_max = n;
2174

    
2175
        s->temp_count += s->nb_temps;
2176
        if (s->nb_temps > s->temp_count_max)
2177
            s->temp_count_max = s->nb_temps;
2178
    }
2179
#endif
2180

    
2181
    tcg_gen_code_common(s, gen_code_buf, -1);
2182

    
2183
    /* flush instruction cache */
2184
    flush_icache_range((tcg_target_ulong)gen_code_buf,
2185
                       (tcg_target_ulong)s->code_ptr);
2186

    
2187
    return s->code_ptr -  gen_code_buf;
2188
}
2189

    
2190
/* Return the index of the micro operation such as the pc after is <
2191
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2192
   not be changed, though writing the same values is ok.
2193
   Return -1 if not found. */
2194
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2195
{
2196
    return tcg_gen_code_common(s, gen_code_buf, offset);
2197
}
2198

    
2199
#ifdef CONFIG_PROFILER
2200
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2201
{
2202
    TCGContext *s = &tcg_ctx;
2203
    int64_t tot;
2204

    
2205
    tot = s->interm_time + s->code_time;
2206
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2207
                tot, tot / 2.4e9);
2208
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2209
                s->tb_count, 
2210
                s->tb_count1 - s->tb_count,
2211
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2212
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2213
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2214
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2215
                s->tb_count ? 
2216
                (double)s->del_op_count / s->tb_count : 0);
2217
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2218
                s->tb_count ? 
2219
                (double)s->temp_count / s->tb_count : 0,
2220
                s->temp_count_max);
2221
    
2222
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2223
                s->op_count ? (double)tot / s->op_count : 0);
2224
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2225
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2226
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2227
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2228
    if (tot == 0)
2229
        tot = 1;
2230
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2231
                (double)s->interm_time / tot * 100.0);
2232
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2233
                (double)s->code_time / tot * 100.0);
2234
    cpu_fprintf(f, "optim./code time    %0.1f%%\n",
2235
                (double)s->opt_time / (s->code_time ? s->code_time : 1)
2236
                * 100.0);
2237
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2238
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2239
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2240
                s->restore_count);
2241
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2242
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2243

    
2244
    dump_op_count();
2245
}
2246
#else
2247
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2248
{
2249
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2250
}
2251
#endif
2252

    
2253
#ifdef ELF_HOST_MACHINE
2254
/* In order to use this feature, the backend needs to do three things:
2255

2256
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2257
       put into the ELF image and to indicate support for the feature.
2258

2259
   (2) Define tcg_register_jit.  This should create a buffer containing
2260
       the contents of a .debug_frame section that describes the post-
2261
       prologue unwind info for the tcg machine.
2262

2263
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2264
*/
2265

    
2266
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2267
typedef enum {
2268
    JIT_NOACTION = 0,
2269
    JIT_REGISTER_FN,
2270
    JIT_UNREGISTER_FN
2271
} jit_actions_t;
2272

    
2273
struct jit_code_entry {
2274
    struct jit_code_entry *next_entry;
2275
    struct jit_code_entry *prev_entry;
2276
    const void *symfile_addr;
2277
    uint64_t symfile_size;
2278
};
2279

    
2280
struct jit_descriptor {
2281
    uint32_t version;
2282
    uint32_t action_flag;
2283
    struct jit_code_entry *relevant_entry;
2284
    struct jit_code_entry *first_entry;
2285
};
2286

    
2287
void __jit_debug_register_code(void) __attribute__((noinline));
2288
void __jit_debug_register_code(void)
2289
{
2290
    asm("");
2291
}
2292

    
2293
/* Must statically initialize the version, because GDB may check
2294
   the version before we can set it.  */
2295
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2296

    
2297
/* End GDB interface.  */
2298

    
2299
static int find_string(const char *strtab, const char *str)
2300
{
2301
    const char *p = strtab + 1;
2302

    
2303
    while (1) {
2304
        if (strcmp(p, str) == 0) {
2305
            return p - strtab;
2306
        }
2307
        p += strlen(p) + 1;
2308
    }
2309
}
2310

    
2311
static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2312
                                 void *debug_frame, size_t debug_frame_size)
2313
{
2314
    struct __attribute__((packed)) DebugInfo {
2315
        uint32_t  len;
2316
        uint16_t  version;
2317
        uint32_t  abbrev;
2318
        uint8_t   ptr_size;
2319
        uint8_t   cu_die;
2320
        uint16_t  cu_lang;
2321
        uintptr_t cu_low_pc;
2322
        uintptr_t cu_high_pc;
2323
        uint8_t   fn_die;
2324
        char      fn_name[16];
2325
        uintptr_t fn_low_pc;
2326
        uintptr_t fn_high_pc;
2327
        uint8_t   cu_eoc;
2328
    };
2329

    
2330
    struct ElfImage {
2331
        ElfW(Ehdr) ehdr;
2332
        ElfW(Phdr) phdr;
2333
        ElfW(Shdr) shdr[7];
2334
        ElfW(Sym)  sym[2];
2335
        struct DebugInfo di;
2336
        uint8_t    da[24];
2337
        char       str[80];
2338
    };
2339

    
2340
    struct ElfImage *img;
2341

    
2342
    static const struct ElfImage img_template = {
2343
        .ehdr = {
2344
            .e_ident[EI_MAG0] = ELFMAG0,
2345
            .e_ident[EI_MAG1] = ELFMAG1,
2346
            .e_ident[EI_MAG2] = ELFMAG2,
2347
            .e_ident[EI_MAG3] = ELFMAG3,
2348
            .e_ident[EI_CLASS] = ELF_CLASS,
2349
            .e_ident[EI_DATA] = ELF_DATA,
2350
            .e_ident[EI_VERSION] = EV_CURRENT,
2351
            .e_type = ET_EXEC,
2352
            .e_machine = ELF_HOST_MACHINE,
2353
            .e_version = EV_CURRENT,
2354
            .e_phoff = offsetof(struct ElfImage, phdr),
2355
            .e_shoff = offsetof(struct ElfImage, shdr),
2356
            .e_ehsize = sizeof(ElfW(Shdr)),
2357
            .e_phentsize = sizeof(ElfW(Phdr)),
2358
            .e_phnum = 1,
2359
            .e_shentsize = sizeof(ElfW(Shdr)),
2360
            .e_shnum = ARRAY_SIZE(img->shdr),
2361
            .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2362
#ifdef ELF_HOST_FLAGS
2363
            .e_flags = ELF_HOST_FLAGS,
2364
#endif
2365
#ifdef ELF_OSABI
2366
            .e_ident[EI_OSABI] = ELF_OSABI,
2367
#endif
2368
        },
2369
        .phdr = {
2370
            .p_type = PT_LOAD,
2371
            .p_flags = PF_X,
2372
        },
2373
        .shdr = {
2374
            [0] = { .sh_type = SHT_NULL },
2375
            /* Trick: The contents of code_gen_buffer are not present in
2376
               this fake ELF file; that got allocated elsewhere.  Therefore
2377
               we mark .text as SHT_NOBITS (similar to .bss) so that readers
2378
               will not look for contents.  We can record any address.  */
2379
            [1] = { /* .text */
2380
                .sh_type = SHT_NOBITS,
2381
                .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2382
            },
2383
            [2] = { /* .debug_info */
2384
                .sh_type = SHT_PROGBITS,
2385
                .sh_offset = offsetof(struct ElfImage, di),
2386
                .sh_size = sizeof(struct DebugInfo),
2387
            },
2388
            [3] = { /* .debug_abbrev */
2389
                .sh_type = SHT_PROGBITS,
2390
                .sh_offset = offsetof(struct ElfImage, da),
2391
                .sh_size = sizeof(img->da),
2392
            },
2393
            [4] = { /* .debug_frame */
2394
                .sh_type = SHT_PROGBITS,
2395
                .sh_offset = sizeof(struct ElfImage),
2396
            },
2397
            [5] = { /* .symtab */
2398
                .sh_type = SHT_SYMTAB,
2399
                .sh_offset = offsetof(struct ElfImage, sym),
2400
                .sh_size = sizeof(img->sym),
2401
                .sh_info = 1,
2402
                .sh_link = ARRAY_SIZE(img->shdr) - 1,
2403
                .sh_entsize = sizeof(ElfW(Sym)),
2404
            },
2405
            [6] = { /* .strtab */
2406
                .sh_type = SHT_STRTAB,
2407
                .sh_offset = offsetof(struct ElfImage, str),
2408
                .sh_size = sizeof(img->str),
2409
            }
2410
        },
2411
        .sym = {
2412
            [1] = { /* code_gen_buffer */
2413
                .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2414
                .st_shndx = 1,
2415
            }
2416
        },
2417
        .di = {
2418
            .len = sizeof(struct DebugInfo) - 4,
2419
            .version = 2,
2420
            .ptr_size = sizeof(void *),
2421
            .cu_die = 1,
2422
            .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
2423
            .fn_die = 2,
2424
            .fn_name = "code_gen_buffer"
2425
        },
2426
        .da = {
2427
            1,          /* abbrev number (the cu) */
2428
            0x11, 1,    /* DW_TAG_compile_unit, has children */
2429
            0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
2430
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2431
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2432
            0, 0,       /* end of abbrev */
2433
            2,          /* abbrev number (the fn) */
2434
            0x2e, 0,    /* DW_TAG_subprogram, no children */
2435
            0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
2436
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2437
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2438
            0, 0,       /* end of abbrev */
2439
            0           /* no more abbrev */
2440
        },
2441
        .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2442
               ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2443
    };
2444

    
2445
    /* We only need a single jit entry; statically allocate it.  */
2446
    static struct jit_code_entry one_entry;
2447

    
2448
    uintptr_t buf = (uintptr_t)buf_ptr;
2449
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2450

    
2451
    img = g_malloc(img_size);
2452
    *img = img_template;
2453
    memcpy(img + 1, debug_frame, debug_frame_size);
2454

    
2455
    img->phdr.p_vaddr = buf;
2456
    img->phdr.p_paddr = buf;
2457
    img->phdr.p_memsz = buf_size;
2458

    
2459
    img->shdr[1].sh_name = find_string(img->str, ".text");
2460
    img->shdr[1].sh_addr = buf;
2461
    img->shdr[1].sh_size = buf_size;
2462

    
2463
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2464
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2465

    
2466
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2467
    img->shdr[4].sh_size = debug_frame_size;
2468

    
2469
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2470
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2471

    
2472
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2473
    img->sym[1].st_value = buf;
2474
    img->sym[1].st_size = buf_size;
2475

    
2476
    img->di.cu_low_pc = buf;
2477
    img->di.cu_high_pc = buf_size;
2478
    img->di.fn_low_pc = buf;
2479
    img->di.fn_high_pc = buf_size;
2480

    
2481
#ifdef DEBUG_JIT
2482
    /* Enable this block to be able to debug the ELF image file creation.
2483
       One can use readelf, objdump, or other inspection utilities.  */
2484
    {
2485
        FILE *f = fopen("/tmp/qemu.jit", "w+b");
2486
        if (f) {
2487
            if (fwrite(img, img_size, 1, f) != img_size) {
2488
                /* Avoid stupid unused return value warning for fwrite.  */
2489
            }
2490
            fclose(f);
2491
        }
2492
    }
2493
#endif
2494

    
2495
    one_entry.symfile_addr = img;
2496
    one_entry.symfile_size = img_size;
2497

    
2498
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2499
    __jit_debug_descriptor.relevant_entry = &one_entry;
2500
    __jit_debug_descriptor.first_entry = &one_entry;
2501
    __jit_debug_register_code();
2502
}
2503
#else
2504
/* No support for the feature.  Provide the entry point expected by exec.c,
2505
   and implement the internal function we declared earlier.  */
2506

    
2507
static void tcg_register_jit_int(void *buf, size_t size,
2508
                                 void *debug_frame, size_t debug_frame_size)
2509
{
2510
}
2511

    
2512
void tcg_register_jit(void *buf, size_t buf_size)
2513
{
2514
}
2515
#endif /* ELF_HOST_MACHINE */