Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 867b3201

History | View | Annotate | Download (89.5 kB)

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

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

    
29
#include "config.h"
30

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

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

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

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

    
50
#include "tcg-op.h"
51

    
52
#if UINTPTR_MAX == UINT32_MAX
53
# define ELF_CLASS  ELFCLASS32
54
#else
55
# define ELF_CLASS  ELFCLASS64
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
                        intptr_t value, intptr_t addend);
70

    
71
/* The CIE and FDE header definitions will be common to all hosts.  */
72
typedef struct {
73
    uint32_t len __attribute__((aligned((sizeof(void *)))));
74
    uint32_t id;
75
    uint8_t version;
76
    char augmentation[1];
77
    uint8_t code_align;
78
    uint8_t data_align;
79
    uint8_t return_column;
80
} DebugFrameCIE;
81

    
82
typedef struct QEMU_PACKED {
83
    uint32_t len __attribute__((aligned((sizeof(void *)))));
84
    uint32_t cie_offset;
85
    uintptr_t func_start;
86
    uintptr_t func_len;
87
} DebugFrameFDEHeader;
88

    
89
static void tcg_register_jit_int(void *buf, size_t size,
90
                                 void *debug_frame, size_t debug_frame_size)
91
    __attribute__((unused));
92

    
93
/* Forward declarations for functions declared and used in tcg-target.c. */
94
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
95
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
96
                       intptr_t arg2);
97
static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
98
static void tcg_out_movi(TCGContext *s, TCGType type,
99
                         TCGReg ret, tcg_target_long arg);
100
static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
101
                       const int *const_args);
102
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
103
                       intptr_t arg2);
104
static int tcg_target_const_match(tcg_target_long val,
105
                                  const TCGArgConstraint *arg_ct);
106
static void tcg_out_tb_init(TCGContext *s);
107
static void tcg_out_tb_finalize(TCGContext *s);
108

    
109

    
110
TCGOpDef tcg_op_defs[] = {
111
#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
112
#include "tcg-opc.h"
113
#undef DEF
114
};
115
const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
116

    
117
static TCGRegSet tcg_target_available_regs[2];
118
static TCGRegSet tcg_target_call_clobber_regs;
119

    
120
static inline void tcg_out8(TCGContext *s, uint8_t v)
121
{
122
    *s->code_ptr++ = v;
123
}
124

    
125
static inline void tcg_out16(TCGContext *s, uint16_t v)
126
{
127
    uint8_t *p = s->code_ptr;
128
    *(uint16_t *)p = v;
129
    s->code_ptr = p + 2;
130
}
131

    
132
static inline void tcg_out32(TCGContext *s, uint32_t v)
133
{
134
    uint8_t *p = s->code_ptr;
135
    *(uint32_t *)p = v;
136
    s->code_ptr = p + 4;
137
}
138

    
139
static inline void tcg_out64(TCGContext *s, uint64_t v)
140
{
141
    uint8_t *p = s->code_ptr;
142
    *(uint64_t *)p = v;
143
    s->code_ptr = p + 8;
144
}
145

    
146
/* label relocation processing */
147

    
148
static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
149
                          int label_index, intptr_t addend)
150
{
151
    TCGLabel *l;
152
    TCGRelocation *r;
153

    
154
    l = &s->labels[label_index];
155
    if (l->has_value) {
156
        /* FIXME: This may break relocations on RISC targets that
157
           modify instruction fields in place.  The caller may not have 
158
           written the initial value.  */
159
        patch_reloc(code_ptr, type, l->u.value, addend);
160
    } else {
161
        /* add a new relocation entry */
162
        r = tcg_malloc(sizeof(TCGRelocation));
163
        r->type = type;
164
        r->ptr = code_ptr;
165
        r->addend = addend;
166
        r->next = l->u.first_reloc;
167
        l->u.first_reloc = r;
168
    }
169
}
170

    
171
static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
172
{
173
    TCGLabel *l;
174
    TCGRelocation *r;
175
    intptr_t value = (intptr_t)ptr;
176

    
177
    l = &s->labels[label_index];
178
    if (l->has_value) {
179
        tcg_abort();
180
    }
181
    r = l->u.first_reloc;
182
    while (r != NULL) {
183
        patch_reloc(r->ptr, r->type, value, r->addend);
184
        r = r->next;
185
    }
186
    l->has_value = 1;
187
    l->u.value = value;
188
}
189

    
190
int gen_new_label(void)
191
{
192
    TCGContext *s = &tcg_ctx;
193
    int idx;
194
    TCGLabel *l;
195

    
196
    if (s->nb_labels >= TCG_MAX_LABELS)
197
        tcg_abort();
198
    idx = s->nb_labels++;
199
    l = &s->labels[idx];
200
    l->has_value = 0;
201
    l->u.first_reloc = NULL;
202
    return idx;
203
}
204

    
205
#include "tcg-target.c"
206

    
207
/* pool based memory allocation */
208
void *tcg_malloc_internal(TCGContext *s, int size)
209
{
210
    TCGPool *p;
211
    int pool_size;
212
    
213
    if (size > TCG_POOL_CHUNK_SIZE) {
214
        /* big malloc: insert a new pool (XXX: could optimize) */
215
        p = g_malloc(sizeof(TCGPool) + size);
216
        p->size = size;
217
        p->next = s->pool_first_large;
218
        s->pool_first_large = p;
219
        return p->data;
220
    } else {
221
        p = s->pool_current;
222
        if (!p) {
223
            p = s->pool_first;
224
            if (!p)
225
                goto new_pool;
226
        } else {
227
            if (!p->next) {
228
            new_pool:
229
                pool_size = TCG_POOL_CHUNK_SIZE;
230
                p = g_malloc(sizeof(TCGPool) + pool_size);
231
                p->size = pool_size;
232
                p->next = NULL;
233
                if (s->pool_current) 
234
                    s->pool_current->next = p;
235
                else
236
                    s->pool_first = p;
237
            } else {
238
                p = p->next;
239
            }
240
        }
241
    }
242
    s->pool_current = p;
243
    s->pool_cur = p->data + size;
244
    s->pool_end = p->data + p->size;
245
    return p->data;
246
}
247

    
248
void tcg_pool_reset(TCGContext *s)
249
{
250
    TCGPool *p, *t;
251
    for (p = s->pool_first_large; p; p = t) {
252
        t = p->next;
253
        g_free(p);
254
    }
255
    s->pool_first_large = NULL;
256
    s->pool_cur = s->pool_end = NULL;
257
    s->pool_current = NULL;
258
}
259

    
260
#include "helper.h"
261

    
262
typedef struct TCGHelperInfo {
263
    void *func;
264
    const char *name;
265
} TCGHelperInfo;
266

    
267
static const TCGHelperInfo all_helpers[] = {
268
#define GEN_HELPER 2
269
#include "helper.h"
270

    
271
    /* Include tcg-runtime.c functions.  */
272
    { tcg_helper_div_i32, "div_i32" },
273
    { tcg_helper_rem_i32, "rem_i32" },
274
    { tcg_helper_divu_i32, "divu_i32" },
275
    { tcg_helper_remu_i32, "remu_i32" },
276

    
277
    { tcg_helper_shl_i64, "shl_i64" },
278
    { tcg_helper_shr_i64, "shr_i64" },
279
    { tcg_helper_sar_i64, "sar_i64" },
280
    { tcg_helper_div_i64, "div_i64" },
281
    { tcg_helper_rem_i64, "rem_i64" },
282
    { tcg_helper_divu_i64, "divu_i64" },
283
    { tcg_helper_remu_i64, "remu_i64" },
284
    { tcg_helper_mulsh_i64, "mulsh_i64" },
285
    { tcg_helper_muluh_i64, "muluh_i64" },
286
};
287

    
288
void tcg_context_init(TCGContext *s)
289
{
290
    int op, total_args, n, i;
291
    TCGOpDef *def;
292
    TCGArgConstraint *args_ct;
293
    int *sorted_args;
294
    GHashTable *helper_table;
295

    
296
    memset(s, 0, sizeof(*s));
297
    s->nb_globals = 0;
298
    
299
    /* Count total number of arguments and allocate the corresponding
300
       space */
301
    total_args = 0;
302
    for(op = 0; op < NB_OPS; op++) {
303
        def = &tcg_op_defs[op];
304
        n = def->nb_iargs + def->nb_oargs;
305
        total_args += n;
306
    }
307

    
308
    args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
309
    sorted_args = g_malloc(sizeof(int) * total_args);
310

    
311
    for(op = 0; op < NB_OPS; op++) {
312
        def = &tcg_op_defs[op];
313
        def->args_ct = args_ct;
314
        def->sorted_args = sorted_args;
315
        n = def->nb_iargs + def->nb_oargs;
316
        sorted_args += n;
317
        args_ct += n;
318
    }
319

    
320
    /* Register helpers.  */
321
    /* Use g_direct_hash/equal for direct pointer comparisons on func.  */
322
    s->helpers = helper_table = g_hash_table_new(NULL, NULL);
323

    
324
    for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
325
        g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
326
                            (gpointer)all_helpers[i].name);
327
    }
328

    
329
    tcg_target_init(s);
330
}
331

    
332
void tcg_prologue_init(TCGContext *s)
333
{
334
    /* init global prologue and epilogue */
335
    s->code_buf = s->code_gen_prologue;
336
    s->code_ptr = s->code_buf;
337
    tcg_target_qemu_prologue(s);
338
    flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
339

    
340
#ifdef DEBUG_DISAS
341
    if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
342
        size_t size = s->code_ptr - s->code_buf;
343
        qemu_log("PROLOGUE: [size=%zu]\n", size);
344
        log_disas(s->code_buf, size);
345
        qemu_log("\n");
346
        qemu_log_flush();
347
    }
348
#endif
349
}
350

    
351
void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
352
{
353
    s->frame_start = start;
354
    s->frame_end = start + size;
355
    s->frame_reg = reg;
356
}
357

    
358
void tcg_func_start(TCGContext *s)
359
{
360
    int i;
361
    tcg_pool_reset(s);
362
    s->nb_temps = s->nb_globals;
363
    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
364
        s->first_free_temp[i] = -1;
365
    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
366
    s->nb_labels = 0;
367
    s->current_frame_offset = s->frame_start;
368

    
369
#ifdef CONFIG_DEBUG_TCG
370
    s->goto_tb_issue_mask = 0;
371
#endif
372

    
373
    s->gen_opc_ptr = s->gen_opc_buf;
374
    s->gen_opparam_ptr = s->gen_opparam_buf;
375

    
376
    s->be = tcg_malloc(sizeof(TCGBackendData));
377
}
378

    
379
static inline void tcg_temp_alloc(TCGContext *s, int n)
380
{
381
    if (n > TCG_MAX_TEMPS)
382
        tcg_abort();
383
}
384

    
385
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
386
                                              const char *name)
387
{
388
    TCGContext *s = &tcg_ctx;
389
    TCGTemp *ts;
390
    int idx;
391

    
392
#if TCG_TARGET_REG_BITS == 32
393
    if (type != TCG_TYPE_I32)
394
        tcg_abort();
395
#endif
396
    if (tcg_regset_test_reg(s->reserved_regs, reg))
397
        tcg_abort();
398
    idx = s->nb_globals;
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 = 1;
404
    ts->reg = reg;
405
    ts->name = name;
406
    s->nb_globals++;
407
    tcg_regset_set_reg(s->reserved_regs, reg);
408
    return idx;
409
}
410

    
411
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
412
{
413
    int idx;
414

    
415
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
416
    return MAKE_TCGV_I32(idx);
417
}
418

    
419
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
420
{
421
    int idx;
422

    
423
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
424
    return MAKE_TCGV_I64(idx);
425
}
426

    
427
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
428
                                              intptr_t offset,
429
                                              const char *name)
430
{
431
    TCGContext *s = &tcg_ctx;
432
    TCGTemp *ts;
433
    int idx;
434

    
435
    idx = s->nb_globals;
436
#if TCG_TARGET_REG_BITS == 32
437
    if (type == TCG_TYPE_I64) {
438
        char buf[64];
439
        tcg_temp_alloc(s, s->nb_globals + 2);
440
        ts = &s->temps[s->nb_globals];
441
        ts->base_type = type;
442
        ts->type = TCG_TYPE_I32;
443
        ts->fixed_reg = 0;
444
        ts->mem_allocated = 1;
445
        ts->mem_reg = reg;
446
#ifdef TCG_TARGET_WORDS_BIGENDIAN
447
        ts->mem_offset = offset + 4;
448
#else
449
        ts->mem_offset = offset;
450
#endif
451
        pstrcpy(buf, sizeof(buf), name);
452
        pstrcat(buf, sizeof(buf), "_0");
453
        ts->name = strdup(buf);
454
        ts++;
455

    
456
        ts->base_type = type;
457
        ts->type = TCG_TYPE_I32;
458
        ts->fixed_reg = 0;
459
        ts->mem_allocated = 1;
460
        ts->mem_reg = reg;
461
#ifdef TCG_TARGET_WORDS_BIGENDIAN
462
        ts->mem_offset = offset;
463
#else
464
        ts->mem_offset = offset + 4;
465
#endif
466
        pstrcpy(buf, sizeof(buf), name);
467
        pstrcat(buf, sizeof(buf), "_1");
468
        ts->name = strdup(buf);
469

    
470
        s->nb_globals += 2;
471
    } else
472
#endif
473
    {
474
        tcg_temp_alloc(s, s->nb_globals + 1);
475
        ts = &s->temps[s->nb_globals];
476
        ts->base_type = type;
477
        ts->type = type;
478
        ts->fixed_reg = 0;
479
        ts->mem_allocated = 1;
480
        ts->mem_reg = reg;
481
        ts->mem_offset = offset;
482
        ts->name = name;
483
        s->nb_globals++;
484
    }
485
    return idx;
486
}
487

    
488
TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name)
489
{
490
    int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
491
    return MAKE_TCGV_I32(idx);
492
}
493

    
494
TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name)
495
{
496
    int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
497
    return MAKE_TCGV_I64(idx);
498
}
499

    
500
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
501
{
502
    TCGContext *s = &tcg_ctx;
503
    TCGTemp *ts;
504
    int idx, k;
505

    
506
    k = type;
507
    if (temp_local)
508
        k += TCG_TYPE_COUNT;
509
    idx = s->first_free_temp[k];
510
    if (idx != -1) {
511
        /* There is already an available temp with the
512
           right type */
513
        ts = &s->temps[idx];
514
        s->first_free_temp[k] = ts->next_free_temp;
515
        ts->temp_allocated = 1;
516
        assert(ts->temp_local == temp_local);
517
    } else {
518
        idx = s->nb_temps;
519
#if TCG_TARGET_REG_BITS == 32
520
        if (type == TCG_TYPE_I64) {
521
            tcg_temp_alloc(s, s->nb_temps + 2);
522
            ts = &s->temps[s->nb_temps];
523
            ts->base_type = type;
524
            ts->type = TCG_TYPE_I32;
525
            ts->temp_allocated = 1;
526
            ts->temp_local = temp_local;
527
            ts->name = NULL;
528
            ts++;
529
            ts->base_type = TCG_TYPE_I32;
530
            ts->type = TCG_TYPE_I32;
531
            ts->temp_allocated = 1;
532
            ts->temp_local = temp_local;
533
            ts->name = NULL;
534
            s->nb_temps += 2;
535
        } else
536
#endif
537
        {
538
            tcg_temp_alloc(s, s->nb_temps + 1);
539
            ts = &s->temps[s->nb_temps];
540
            ts->base_type = type;
541
            ts->type = type;
542
            ts->temp_allocated = 1;
543
            ts->temp_local = temp_local;
544
            ts->name = NULL;
545
            s->nb_temps++;
546
        }
547
    }
548

    
549
#if defined(CONFIG_DEBUG_TCG)
550
    s->temps_in_use++;
551
#endif
552
    return idx;
553
}
554

    
555
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
556
{
557
    int idx;
558

    
559
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
560
    return MAKE_TCGV_I32(idx);
561
}
562

    
563
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
564
{
565
    int idx;
566

    
567
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
568
    return MAKE_TCGV_I64(idx);
569
}
570

    
571
static inline void tcg_temp_free_internal(int idx)
572
{
573
    TCGContext *s = &tcg_ctx;
574
    TCGTemp *ts;
575
    int k;
576

    
577
#if defined(CONFIG_DEBUG_TCG)
578
    s->temps_in_use--;
579
    if (s->temps_in_use < 0) {
580
        fprintf(stderr, "More temporaries freed than allocated!\n");
581
    }
582
#endif
583

    
584
    assert(idx >= s->nb_globals && idx < s->nb_temps);
585
    ts = &s->temps[idx];
586
    assert(ts->temp_allocated != 0);
587
    ts->temp_allocated = 0;
588
    k = ts->base_type;
589
    if (ts->temp_local)
590
        k += TCG_TYPE_COUNT;
591
    ts->next_free_temp = s->first_free_temp[k];
592
    s->first_free_temp[k] = idx;
593
}
594

    
595
void tcg_temp_free_i32(TCGv_i32 arg)
596
{
597
    tcg_temp_free_internal(GET_TCGV_I32(arg));
598
}
599

    
600
void tcg_temp_free_i64(TCGv_i64 arg)
601
{
602
    tcg_temp_free_internal(GET_TCGV_I64(arg));
603
}
604

    
605
TCGv_i32 tcg_const_i32(int32_t val)
606
{
607
    TCGv_i32 t0;
608
    t0 = tcg_temp_new_i32();
609
    tcg_gen_movi_i32(t0, val);
610
    return t0;
611
}
612

    
613
TCGv_i64 tcg_const_i64(int64_t val)
614
{
615
    TCGv_i64 t0;
616
    t0 = tcg_temp_new_i64();
617
    tcg_gen_movi_i64(t0, val);
618
    return t0;
619
}
620

    
621
TCGv_i32 tcg_const_local_i32(int32_t val)
622
{
623
    TCGv_i32 t0;
624
    t0 = tcg_temp_local_new_i32();
625
    tcg_gen_movi_i32(t0, val);
626
    return t0;
627
}
628

    
629
TCGv_i64 tcg_const_local_i64(int64_t val)
630
{
631
    TCGv_i64 t0;
632
    t0 = tcg_temp_local_new_i64();
633
    tcg_gen_movi_i64(t0, val);
634
    return t0;
635
}
636

    
637
#if defined(CONFIG_DEBUG_TCG)
638
void tcg_clear_temp_count(void)
639
{
640
    TCGContext *s = &tcg_ctx;
641
    s->temps_in_use = 0;
642
}
643

    
644
int tcg_check_temp_count(void)
645
{
646
    TCGContext *s = &tcg_ctx;
647
    if (s->temps_in_use) {
648
        /* Clear the count so that we don't give another
649
         * warning immediately next time around.
650
         */
651
        s->temps_in_use = 0;
652
        return 1;
653
    }
654
    return 0;
655
}
656
#endif
657

    
658
/* Note: we convert the 64 bit args to 32 bit and do some alignment
659
   and endian swap. Maybe it would be better to do the alignment
660
   and endian swap in tcg_reg_alloc_call(). */
661
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
662
                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
663
{
664
    int i;
665
    int real_args;
666
    int nb_rets;
667
    TCGArg *nparam;
668

    
669
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
670
    for (i = 0; i < nargs; ++i) {
671
        int is_64bit = sizemask & (1 << (i+1)*2);
672
        int is_signed = sizemask & (2 << (i+1)*2);
673
        if (!is_64bit) {
674
            TCGv_i64 temp = tcg_temp_new_i64();
675
            TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
676
            if (is_signed) {
677
                tcg_gen_ext32s_i64(temp, orig);
678
            } else {
679
                tcg_gen_ext32u_i64(temp, orig);
680
            }
681
            args[i] = GET_TCGV_I64(temp);
682
        }
683
    }
684
#endif /* TCG_TARGET_EXTEND_ARGS */
685

    
686
    *s->gen_opc_ptr++ = INDEX_op_call;
687
    nparam = s->gen_opparam_ptr++;
688
    if (ret != TCG_CALL_DUMMY_ARG) {
689
#if TCG_TARGET_REG_BITS < 64
690
        if (sizemask & 1) {
691
#ifdef TCG_TARGET_WORDS_BIGENDIAN
692
            *s->gen_opparam_ptr++ = ret + 1;
693
            *s->gen_opparam_ptr++ = ret;
694
#else
695
            *s->gen_opparam_ptr++ = ret;
696
            *s->gen_opparam_ptr++ = ret + 1;
697
#endif
698
            nb_rets = 2;
699
        } else
700
#endif
701
        {
702
            *s->gen_opparam_ptr++ = ret;
703
            nb_rets = 1;
704
        }
705
    } else {
706
        nb_rets = 0;
707
    }
708
    real_args = 0;
709
    for (i = 0; i < nargs; i++) {
710
#if TCG_TARGET_REG_BITS < 64
711
        int is_64bit = sizemask & (1 << (i+1)*2);
712
        if (is_64bit) {
713
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
714
            /* some targets want aligned 64 bit args */
715
            if (real_args & 1) {
716
                *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
717
                real_args++;
718
            }
719
#endif
720
            /* If stack grows up, then we will be placing successive
721
               arguments at lower addresses, which means we need to
722
               reverse the order compared to how we would normally
723
               treat either big or little-endian.  For those arguments
724
               that will wind up in registers, this still works for
725
               HPPA (the only current STACK_GROWSUP target) since the
726
               argument registers are *also* allocated in decreasing
727
               order.  If another such target is added, this logic may
728
               have to get more complicated to differentiate between
729
               stack arguments and register arguments.  */
730
#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
731
            *s->gen_opparam_ptr++ = args[i] + 1;
732
            *s->gen_opparam_ptr++ = args[i];
733
#else
734
            *s->gen_opparam_ptr++ = args[i];
735
            *s->gen_opparam_ptr++ = args[i] + 1;
736
#endif
737
            real_args += 2;
738
            continue;
739
        }
740
#endif /* TCG_TARGET_REG_BITS < 64 */
741

    
742
        *s->gen_opparam_ptr++ = args[i];
743
        real_args++;
744
    }
745
    *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
746

    
747
    *s->gen_opparam_ptr++ = flags;
748

    
749
    *nparam = (nb_rets << 16) | (real_args + 1);
750

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

    
754
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
755
    for (i = 0; i < nargs; ++i) {
756
        int is_64bit = sizemask & (1 << (i+1)*2);
757
        if (!is_64bit) {
758
            TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
759
            tcg_temp_free_i64(temp);
760
        }
761
    }
762
#endif /* TCG_TARGET_EXTEND_ARGS */
763
}
764

    
765
#if TCG_TARGET_REG_BITS == 32
766
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
767
                        int c, int right, int arith)
768
{
769
    if (c == 0) {
770
        tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
771
        tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
772
    } else if (c >= 32) {
773
        c -= 32;
774
        if (right) {
775
            if (arith) {
776
                tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
777
                tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
778
            } else {
779
                tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
780
                tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
781
            }
782
        } else {
783
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
784
            tcg_gen_movi_i32(TCGV_LOW(ret), 0);
785
        }
786
    } else {
787
        TCGv_i32 t0, t1;
788

    
789
        t0 = tcg_temp_new_i32();
790
        t1 = tcg_temp_new_i32();
791
        if (right) {
792
            tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
793
            if (arith)
794
                tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
795
            else
796
                tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
797
            tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
798
            tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
799
            tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
800
        } else {
801
            tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
802
            /* Note: ret can be the same as arg1, so we use t1 */
803
            tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
804
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
805
            tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
806
            tcg_gen_mov_i32(TCGV_LOW(ret), t1);
807
        }
808
        tcg_temp_free_i32(t0);
809
        tcg_temp_free_i32(t1);
810
    }
811
}
812
#endif
813

    
814
static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
815
{
816
    switch (op & MO_SIZE) {
817
    case MO_8:
818
        op &= ~MO_BSWAP;
819
        break;
820
    case MO_16:
821
        break;
822
    case MO_32:
823
        if (!is64) {
824
            op &= ~MO_SIGN;
825
        }
826
        break;
827
    case MO_64:
828
        if (!is64) {
829
            tcg_abort();
830
        }
831
        break;
832
    }
833
    if (st) {
834
        op &= ~MO_SIGN;
835
    }
836
    return op;
837
}
838

    
839
static const TCGOpcode old_ld_opc[8] = {
840
    [MO_UB] = INDEX_op_qemu_ld8u,
841
    [MO_SB] = INDEX_op_qemu_ld8s,
842
    [MO_UW] = INDEX_op_qemu_ld16u,
843
    [MO_SW] = INDEX_op_qemu_ld16s,
844
#if TCG_TARGET_REG_BITS == 32
845
    [MO_UL] = INDEX_op_qemu_ld32,
846
    [MO_SL] = INDEX_op_qemu_ld32,
847
#else
848
    [MO_UL] = INDEX_op_qemu_ld32u,
849
    [MO_SL] = INDEX_op_qemu_ld32s,
850
#endif
851
    [MO_Q]  = INDEX_op_qemu_ld64,
852
};
853

    
854
static const TCGOpcode old_st_opc[4] = {
855
    [MO_UB] = INDEX_op_qemu_st8,
856
    [MO_UW] = INDEX_op_qemu_st16,
857
    [MO_UL] = INDEX_op_qemu_st32,
858
    [MO_Q]  = INDEX_op_qemu_st64,
859
};
860

    
861
void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
862
{
863
    memop = tcg_canonicalize_memop(memop, 0, 0);
864

    
865
    if (TCG_TARGET_HAS_new_ldst) {
866
        *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i32;
867
        tcg_add_param_i32(val);
868
        tcg_add_param_tl(addr);
869
        *tcg_ctx.gen_opparam_ptr++ = memop;
870
        *tcg_ctx.gen_opparam_ptr++ = idx;
871
        return;
872
    }
873

    
874
    /* The old opcodes only support target-endian memory operations.  */
875
    assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
876
    assert(old_ld_opc[memop & MO_SSIZE] != 0);
877

    
878
    if (TCG_TARGET_REG_BITS == 32) {
879
        *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE];
880
        tcg_add_param_i32(val);
881
        tcg_add_param_tl(addr);
882
        *tcg_ctx.gen_opparam_ptr++ = idx;
883
    } else {
884
        TCGv_i64 val64 = tcg_temp_new_i64();
885

    
886
        *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE];
887
        tcg_add_param_i64(val64);
888
        tcg_add_param_tl(addr);
889
        *tcg_ctx.gen_opparam_ptr++ = idx;
890

    
891
        tcg_gen_trunc_i64_i32(val, val64);
892
        tcg_temp_free_i64(val64);
893
    }
894
}
895

    
896
void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
897
{
898
    memop = tcg_canonicalize_memop(memop, 0, 1);
899

    
900
    if (TCG_TARGET_HAS_new_ldst) {
901
        *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i32;
902
        tcg_add_param_i32(val);
903
        tcg_add_param_tl(addr);
904
        *tcg_ctx.gen_opparam_ptr++ = memop;
905
        *tcg_ctx.gen_opparam_ptr++ = idx;
906
        return;
907
    }
908

    
909
    /* The old opcodes only support target-endian memory operations.  */
910
    assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
911
    assert(old_st_opc[memop & MO_SIZE] != 0);
912

    
913
    if (TCG_TARGET_REG_BITS == 32) {
914
        *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE];
915
        tcg_add_param_i32(val);
916
        tcg_add_param_tl(addr);
917
        *tcg_ctx.gen_opparam_ptr++ = idx;
918
    } else {
919
        TCGv_i64 val64 = tcg_temp_new_i64();
920

    
921
        tcg_gen_extu_i32_i64(val64, val);
922

    
923
        *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE];
924
        tcg_add_param_i64(val64);
925
        tcg_add_param_tl(addr);
926
        *tcg_ctx.gen_opparam_ptr++ = idx;
927

    
928
        tcg_temp_free_i64(val64);
929
    }
930
}
931

    
932
void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
933
{
934
    memop = tcg_canonicalize_memop(memop, 1, 0);
935

    
936
#if TCG_TARGET_REG_BITS == 32
937
    if ((memop & MO_SIZE) < MO_64) {
938
        tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
939
        if (memop & MO_SIGN) {
940
            tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
941
        } else {
942
            tcg_gen_movi_i32(TCGV_HIGH(val), 0);
943
        }
944
        return;
945
    }
946
#endif
947

    
948
    if (TCG_TARGET_HAS_new_ldst) {
949
        *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i64;
950
        tcg_add_param_i64(val);
951
        tcg_add_param_tl(addr);
952
        *tcg_ctx.gen_opparam_ptr++ = memop;
953
        *tcg_ctx.gen_opparam_ptr++ = idx;
954
        return;
955
    }
956

    
957
    /* The old opcodes only support target-endian memory operations.  */
958
    assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
959
    assert(old_ld_opc[memop & MO_SSIZE] != 0);
960

    
961
    *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE];
962
    tcg_add_param_i64(val);
963
    tcg_add_param_tl(addr);
964
    *tcg_ctx.gen_opparam_ptr++ = idx;
965
}
966

    
967
void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
968
{
969
    memop = tcg_canonicalize_memop(memop, 1, 1);
970

    
971
#if TCG_TARGET_REG_BITS == 32
972
    if ((memop & MO_SIZE) < MO_64) {
973
        tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
974
        return;
975
    }
976
#endif
977

    
978
    if (TCG_TARGET_HAS_new_ldst) {
979
        *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i64;
980
        tcg_add_param_i64(val);
981
        tcg_add_param_tl(addr);
982
        *tcg_ctx.gen_opparam_ptr++ = memop;
983
        *tcg_ctx.gen_opparam_ptr++ = idx;
984
        return;
985
    }
986

    
987
    /* The old opcodes only support target-endian memory operations.  */
988
    assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
989
    assert(old_st_opc[memop & MO_SIZE] != 0);
990

    
991
    *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE];
992
    tcg_add_param_i64(val);
993
    tcg_add_param_tl(addr);
994
    *tcg_ctx.gen_opparam_ptr++ = idx;
995
}
996

    
997
static void tcg_reg_alloc_start(TCGContext *s)
998
{
999
    int i;
1000
    TCGTemp *ts;
1001
    for(i = 0; i < s->nb_globals; i++) {
1002
        ts = &s->temps[i];
1003
        if (ts->fixed_reg) {
1004
            ts->val_type = TEMP_VAL_REG;
1005
        } else {
1006
            ts->val_type = TEMP_VAL_MEM;
1007
        }
1008
    }
1009
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1010
        ts = &s->temps[i];
1011
        if (ts->temp_local) {
1012
            ts->val_type = TEMP_VAL_MEM;
1013
        } else {
1014
            ts->val_type = TEMP_VAL_DEAD;
1015
        }
1016
        ts->mem_allocated = 0;
1017
        ts->fixed_reg = 0;
1018
    }
1019
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1020
        s->reg_to_temp[i] = -1;
1021
    }
1022
}
1023

    
1024
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
1025
                                 int idx)
1026
{
1027
    TCGTemp *ts;
1028

    
1029
    assert(idx >= 0 && idx < s->nb_temps);
1030
    ts = &s->temps[idx];
1031
    if (idx < s->nb_globals) {
1032
        pstrcpy(buf, buf_size, ts->name);
1033
    } else {
1034
        if (ts->temp_local) 
1035
            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
1036
        else
1037
            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
1038
    }
1039
    return buf;
1040
}
1041

    
1042
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
1043
{
1044
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
1045
}
1046

    
1047
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
1048
{
1049
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
1050
}
1051

    
1052
/* Find helper name.  */
1053
static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
1054
{
1055
    const char *ret = NULL;
1056
    if (s->helpers) {
1057
        ret = g_hash_table_lookup(s->helpers, (gpointer)val);
1058
    }
1059
    return ret;
1060
}
1061

    
1062
static const char * const cond_name[] =
1063
{
1064
    [TCG_COND_NEVER] = "never",
1065
    [TCG_COND_ALWAYS] = "always",
1066
    [TCG_COND_EQ] = "eq",
1067
    [TCG_COND_NE] = "ne",
1068
    [TCG_COND_LT] = "lt",
1069
    [TCG_COND_GE] = "ge",
1070
    [TCG_COND_LE] = "le",
1071
    [TCG_COND_GT] = "gt",
1072
    [TCG_COND_LTU] = "ltu",
1073
    [TCG_COND_GEU] = "geu",
1074
    [TCG_COND_LEU] = "leu",
1075
    [TCG_COND_GTU] = "gtu"
1076
};
1077

    
1078
static const char * const ldst_name[] =
1079
{
1080
    [MO_UB]   = "ub",
1081
    [MO_SB]   = "sb",
1082
    [MO_LEUW] = "leuw",
1083
    [MO_LESW] = "lesw",
1084
    [MO_LEUL] = "leul",
1085
    [MO_LESL] = "lesl",
1086
    [MO_LEQ]  = "leq",
1087
    [MO_BEUW] = "beuw",
1088
    [MO_BESW] = "besw",
1089
    [MO_BEUL] = "beul",
1090
    [MO_BESL] = "besl",
1091
    [MO_BEQ]  = "beq",
1092
};
1093

    
1094
void tcg_dump_ops(TCGContext *s)
1095
{
1096
    const uint16_t *opc_ptr;
1097
    const TCGArg *args;
1098
    TCGArg arg;
1099
    TCGOpcode c;
1100
    int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
1101
    const TCGOpDef *def;
1102
    char buf[128];
1103

    
1104
    first_insn = 1;
1105
    opc_ptr = s->gen_opc_buf;
1106
    args = s->gen_opparam_buf;
1107
    while (opc_ptr < s->gen_opc_ptr) {
1108
        c = *opc_ptr++;
1109
        def = &tcg_op_defs[c];
1110
        if (c == INDEX_op_debug_insn_start) {
1111
            uint64_t pc;
1112
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
1113
            pc = ((uint64_t)args[1] << 32) | args[0];
1114
#else
1115
            pc = args[0];
1116
#endif
1117
            if (!first_insn) {
1118
                qemu_log("\n");
1119
            }
1120
            qemu_log(" ---- 0x%" PRIx64, pc);
1121
            first_insn = 0;
1122
            nb_oargs = def->nb_oargs;
1123
            nb_iargs = def->nb_iargs;
1124
            nb_cargs = def->nb_cargs;
1125
        } else if (c == INDEX_op_call) {
1126
            TCGArg arg;
1127

    
1128
            /* variable number of arguments */
1129
            arg = *args++;
1130
            nb_oargs = arg >> 16;
1131
            nb_iargs = arg & 0xffff;
1132
            nb_cargs = def->nb_cargs;
1133

    
1134
            qemu_log(" %s ", def->name);
1135

    
1136
            /* function name */
1137
            qemu_log("%s",
1138
                     tcg_get_arg_str_idx(s, buf, sizeof(buf),
1139
                                         args[nb_oargs + nb_iargs - 1]));
1140
            /* flags */
1141
            qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
1142
            /* nb out args */
1143
            qemu_log(",$%d", nb_oargs);
1144
            for(i = 0; i < nb_oargs; i++) {
1145
                qemu_log(",");
1146
                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1147
                                                   args[i]));
1148
            }
1149
            for(i = 0; i < (nb_iargs - 1); i++) {
1150
                qemu_log(",");
1151
                if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
1152
                    qemu_log("<dummy>");
1153
                } else {
1154
                    qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1155
                                                       args[nb_oargs + i]));
1156
                }
1157
            }
1158
        } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
1159
            tcg_target_ulong val;
1160
            const char *name;
1161

    
1162
            nb_oargs = def->nb_oargs;
1163
            nb_iargs = def->nb_iargs;
1164
            nb_cargs = def->nb_cargs;
1165
            qemu_log(" %s %s,$", def->name,
1166
                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
1167
            val = args[1];
1168
            name = tcg_find_helper(s, val);
1169
            if (name) {
1170
                qemu_log("%s", name);
1171
            } else {
1172
                if (c == INDEX_op_movi_i32) {
1173
                    qemu_log("0x%x", (uint32_t)val);
1174
                } else {
1175
                    qemu_log("0x%" PRIx64 , (uint64_t)val);
1176
                }
1177
            }
1178
        } else {
1179
            qemu_log(" %s ", def->name);
1180
            if (c == INDEX_op_nopn) {
1181
                /* variable number of arguments */
1182
                nb_cargs = *args;
1183
                nb_oargs = 0;
1184
                nb_iargs = 0;
1185
            } else {
1186
                nb_oargs = def->nb_oargs;
1187
                nb_iargs = def->nb_iargs;
1188
                nb_cargs = def->nb_cargs;
1189
            }
1190
            
1191
            k = 0;
1192
            for(i = 0; i < nb_oargs; i++) {
1193
                if (k != 0) {
1194
                    qemu_log(",");
1195
                }
1196
                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1197
                                                   args[k++]));
1198
            }
1199
            for(i = 0; i < nb_iargs; i++) {
1200
                if (k != 0) {
1201
                    qemu_log(",");
1202
                }
1203
                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1204
                                                   args[k++]));
1205
            }
1206
            switch (c) {
1207
            case INDEX_op_brcond_i32:
1208
            case INDEX_op_setcond_i32:
1209
            case INDEX_op_movcond_i32:
1210
            case INDEX_op_brcond2_i32:
1211
            case INDEX_op_setcond2_i32:
1212
            case INDEX_op_brcond_i64:
1213
            case INDEX_op_setcond_i64:
1214
            case INDEX_op_movcond_i64:
1215
                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1216
                    qemu_log(",%s", cond_name[args[k++]]);
1217
                } else {
1218
                    qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1219
                }
1220
                i = 1;
1221
                break;
1222
            case INDEX_op_qemu_ld_i32:
1223
            case INDEX_op_qemu_st_i32:
1224
            case INDEX_op_qemu_ld_i64:
1225
            case INDEX_op_qemu_st_i64:
1226
                if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) {
1227
                    qemu_log(",%s", ldst_name[args[k++]]);
1228
                } else {
1229
                    qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1230
                }
1231
                i = 1;
1232
                break;
1233
            default:
1234
                i = 0;
1235
                break;
1236
            }
1237
            for(; i < nb_cargs; i++) {
1238
                if (k != 0) {
1239
                    qemu_log(",");
1240
                }
1241
                arg = args[k++];
1242
                qemu_log("$0x%" TCG_PRIlx, arg);
1243
            }
1244
        }
1245
        qemu_log("\n");
1246
        args += nb_iargs + nb_oargs + nb_cargs;
1247
    }
1248
}
1249

    
1250
/* we give more priority to constraints with less registers */
1251
static int get_constraint_priority(const TCGOpDef *def, int k)
1252
{
1253
    const TCGArgConstraint *arg_ct;
1254

    
1255
    int i, n;
1256
    arg_ct = &def->args_ct[k];
1257
    if (arg_ct->ct & TCG_CT_ALIAS) {
1258
        /* an alias is equivalent to a single register */
1259
        n = 1;
1260
    } else {
1261
        if (!(arg_ct->ct & TCG_CT_REG))
1262
            return 0;
1263
        n = 0;
1264
        for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1265
            if (tcg_regset_test_reg(arg_ct->u.regs, i))
1266
                n++;
1267
        }
1268
    }
1269
    return TCG_TARGET_NB_REGS - n + 1;
1270
}
1271

    
1272
/* sort from highest priority to lowest */
1273
static void sort_constraints(TCGOpDef *def, int start, int n)
1274
{
1275
    int i, j, p1, p2, tmp;
1276

    
1277
    for(i = 0; i < n; i++)
1278
        def->sorted_args[start + i] = start + i;
1279
    if (n <= 1)
1280
        return;
1281
    for(i = 0; i < n - 1; i++) {
1282
        for(j = i + 1; j < n; j++) {
1283
            p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1284
            p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1285
            if (p1 < p2) {
1286
                tmp = def->sorted_args[start + i];
1287
                def->sorted_args[start + i] = def->sorted_args[start + j];
1288
                def->sorted_args[start + j] = tmp;
1289
            }
1290
        }
1291
    }
1292
}
1293

    
1294
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1295
{
1296
    TCGOpcode op;
1297
    TCGOpDef *def;
1298
    const char *ct_str;
1299
    int i, nb_args;
1300

    
1301
    for(;;) {
1302
        if (tdefs->op == (TCGOpcode)-1)
1303
            break;
1304
        op = tdefs->op;
1305
        assert((unsigned)op < NB_OPS);
1306
        def = &tcg_op_defs[op];
1307
#if defined(CONFIG_DEBUG_TCG)
1308
        /* Duplicate entry in op definitions? */
1309
        assert(!def->used);
1310
        def->used = 1;
1311
#endif
1312
        nb_args = def->nb_iargs + def->nb_oargs;
1313
        for(i = 0; i < nb_args; i++) {
1314
            ct_str = tdefs->args_ct_str[i];
1315
            /* Incomplete TCGTargetOpDef entry? */
1316
            assert(ct_str != NULL);
1317
            tcg_regset_clear(def->args_ct[i].u.regs);
1318
            def->args_ct[i].ct = 0;
1319
            if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1320
                int oarg;
1321
                oarg = ct_str[0] - '0';
1322
                assert(oarg < def->nb_oargs);
1323
                assert(def->args_ct[oarg].ct & TCG_CT_REG);
1324
                /* TCG_CT_ALIAS is for the output arguments. The input
1325
                   argument is tagged with TCG_CT_IALIAS. */
1326
                def->args_ct[i] = def->args_ct[oarg];
1327
                def->args_ct[oarg].ct = TCG_CT_ALIAS;
1328
                def->args_ct[oarg].alias_index = i;
1329
                def->args_ct[i].ct |= TCG_CT_IALIAS;
1330
                def->args_ct[i].alias_index = oarg;
1331
            } else {
1332
                for(;;) {
1333
                    if (*ct_str == '\0')
1334
                        break;
1335
                    switch(*ct_str) {
1336
                    case 'i':
1337
                        def->args_ct[i].ct |= TCG_CT_CONST;
1338
                        ct_str++;
1339
                        break;
1340
                    default:
1341
                        if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1342
                            fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1343
                                    ct_str, i, def->name);
1344
                            exit(1);
1345
                        }
1346
                    }
1347
                }
1348
            }
1349
        }
1350

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

    
1354
        /* sort the constraints (XXX: this is just an heuristic) */
1355
        sort_constraints(def, 0, def->nb_oargs);
1356
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1357

    
1358
#if 0
1359
        {
1360
            int i;
1361

1362
            printf("%s: sorted=", def->name);
1363
            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1364
                printf(" %d", def->sorted_args[i]);
1365
            printf("\n");
1366
        }
1367
#endif
1368
        tdefs++;
1369
    }
1370

    
1371
#if defined(CONFIG_DEBUG_TCG)
1372
    i = 0;
1373
    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1374
        const TCGOpDef *def = &tcg_op_defs[op];
1375
        if (def->flags & TCG_OPF_NOT_PRESENT) {
1376
            /* Wrong entry in op definitions? */
1377
            if (def->used) {
1378
                fprintf(stderr, "Invalid op definition for %s\n", def->name);
1379
                i = 1;
1380
            }
1381
        } else {
1382
            /* Missing entry in op definitions? */
1383
            if (!def->used) {
1384
                fprintf(stderr, "Missing op definition for %s\n", def->name);
1385
                i = 1;
1386
            }
1387
        }
1388
    }
1389
    if (i == 1) {
1390
        tcg_abort();
1391
    }
1392
#endif
1393
}
1394

    
1395
#ifdef USE_LIVENESS_ANALYSIS
1396

    
1397
/* set a nop for an operation using 'nb_args' */
1398
static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
1399
                               TCGArg *args, int nb_args)
1400
{
1401
    if (nb_args == 0) {
1402
        *opc_ptr = INDEX_op_nop;
1403
    } else {
1404
        *opc_ptr = INDEX_op_nopn;
1405
        args[0] = nb_args;
1406
        args[nb_args - 1] = nb_args;
1407
    }
1408
}
1409

    
1410
/* liveness analysis: end of function: all temps are dead, and globals
1411
   should be in memory. */
1412
static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1413
                                   uint8_t *mem_temps)
1414
{
1415
    memset(dead_temps, 1, s->nb_temps);
1416
    memset(mem_temps, 1, s->nb_globals);
1417
    memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
1418
}
1419

    
1420
/* liveness analysis: end of basic block: all temps are dead, globals
1421
   and local temps should be in memory. */
1422
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1423
                                 uint8_t *mem_temps)
1424
{
1425
    int i;
1426

    
1427
    memset(dead_temps, 1, s->nb_temps);
1428
    memset(mem_temps, 1, s->nb_globals);
1429
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1430
        mem_temps[i] = s->temps[i].temp_local;
1431
    }
1432
}
1433

    
1434
/* Liveness analysis : update the opc_dead_args array to tell if a
1435
   given input arguments is dead. Instructions updating dead
1436
   temporaries are removed. */
1437
static void tcg_liveness_analysis(TCGContext *s)
1438
{
1439
    int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1440
    TCGOpcode op, op_new, op_new2;
1441
    TCGArg *args;
1442
    const TCGOpDef *def;
1443
    uint8_t *dead_temps, *mem_temps;
1444
    uint16_t dead_args;
1445
    uint8_t sync_args;
1446
    bool have_op_new2;
1447
    
1448
    s->gen_opc_ptr++; /* skip end */
1449

    
1450
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1451

    
1452
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1453
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1454
    
1455
    dead_temps = tcg_malloc(s->nb_temps);
1456
    mem_temps = tcg_malloc(s->nb_temps);
1457
    tcg_la_func_end(s, dead_temps, mem_temps);
1458

    
1459
    args = s->gen_opparam_ptr;
1460
    op_index = nb_ops - 1;
1461
    while (op_index >= 0) {
1462
        op = s->gen_opc_buf[op_index];
1463
        def = &tcg_op_defs[op];
1464
        switch(op) {
1465
        case INDEX_op_call:
1466
            {
1467
                int call_flags;
1468

    
1469
                nb_args = args[-1];
1470
                args -= nb_args;
1471
                nb_iargs = args[0] & 0xffff;
1472
                nb_oargs = args[0] >> 16;
1473
                args++;
1474
                call_flags = args[nb_oargs + nb_iargs];
1475

    
1476
                /* pure functions can be removed if their result is not
1477
                   used */
1478
                if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
1479
                    for(i = 0; i < nb_oargs; i++) {
1480
                        arg = args[i];
1481
                        if (!dead_temps[arg] || mem_temps[arg]) {
1482
                            goto do_not_remove_call;
1483
                        }
1484
                    }
1485
                    tcg_set_nop(s, s->gen_opc_buf + op_index,
1486
                                args - 1, nb_args);
1487
                } else {
1488
                do_not_remove_call:
1489

    
1490
                    /* output args are dead */
1491
                    dead_args = 0;
1492
                    sync_args = 0;
1493
                    for(i = 0; i < nb_oargs; i++) {
1494
                        arg = args[i];
1495
                        if (dead_temps[arg]) {
1496
                            dead_args |= (1 << i);
1497
                        }
1498
                        if (mem_temps[arg]) {
1499
                            sync_args |= (1 << i);
1500
                        }
1501
                        dead_temps[arg] = 1;
1502
                        mem_temps[arg] = 0;
1503
                    }
1504

    
1505
                    if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1506
                        /* globals should be synced to memory */
1507
                        memset(mem_temps, 1, s->nb_globals);
1508
                    }
1509
                    if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1510
                                        TCG_CALL_NO_READ_GLOBALS))) {
1511
                        /* globals should go back to memory */
1512
                        memset(dead_temps, 1, s->nb_globals);
1513
                    }
1514

    
1515
                    /* input args are live */
1516
                    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1517
                        arg = args[i];
1518
                        if (arg != TCG_CALL_DUMMY_ARG) {
1519
                            if (dead_temps[arg]) {
1520
                                dead_args |= (1 << i);
1521
                            }
1522
                            dead_temps[arg] = 0;
1523
                        }
1524
                    }
1525
                    s->op_dead_args[op_index] = dead_args;
1526
                    s->op_sync_args[op_index] = sync_args;
1527
                }
1528
                args--;
1529
            }
1530
            break;
1531
        case INDEX_op_debug_insn_start:
1532
            args -= def->nb_args;
1533
            break;
1534
        case INDEX_op_nopn:
1535
            nb_args = args[-1];
1536
            args -= nb_args;
1537
            break;
1538
        case INDEX_op_discard:
1539
            args--;
1540
            /* mark the temporary as dead */
1541
            dead_temps[args[0]] = 1;
1542
            mem_temps[args[0]] = 0;
1543
            break;
1544
        case INDEX_op_end:
1545
            break;
1546

    
1547
        case INDEX_op_add2_i32:
1548
            op_new = INDEX_op_add_i32;
1549
            goto do_addsub2;
1550
        case INDEX_op_sub2_i32:
1551
            op_new = INDEX_op_sub_i32;
1552
            goto do_addsub2;
1553
        case INDEX_op_add2_i64:
1554
            op_new = INDEX_op_add_i64;
1555
            goto do_addsub2;
1556
        case INDEX_op_sub2_i64:
1557
            op_new = INDEX_op_sub_i64;
1558
        do_addsub2:
1559
            args -= 6;
1560
            nb_iargs = 4;
1561
            nb_oargs = 2;
1562
            /* Test if the high part of the operation is dead, but not
1563
               the low part.  The result can be optimized to a simple
1564
               add or sub.  This happens often for x86_64 guest when the
1565
               cpu mode is set to 32 bit.  */
1566
            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1567
                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1568
                    goto do_remove;
1569
                }
1570
                /* Create the single operation plus nop.  */
1571
                s->gen_opc_buf[op_index] = op = op_new;
1572
                args[1] = args[2];
1573
                args[2] = args[4];
1574
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1575
                tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1576
                /* Fall through and mark the single-word operation live.  */
1577
                nb_iargs = 2;
1578
                nb_oargs = 1;
1579
            }
1580
            goto do_not_remove;
1581

    
1582
        case INDEX_op_mulu2_i32:
1583
            op_new = INDEX_op_mul_i32;
1584
            op_new2 = INDEX_op_muluh_i32;
1585
            have_op_new2 = TCG_TARGET_HAS_muluh_i32;
1586
            goto do_mul2;
1587
        case INDEX_op_muls2_i32:
1588
            op_new = INDEX_op_mul_i32;
1589
            op_new2 = INDEX_op_mulsh_i32;
1590
            have_op_new2 = TCG_TARGET_HAS_mulsh_i32;
1591
            goto do_mul2;
1592
        case INDEX_op_mulu2_i64:
1593
            op_new = INDEX_op_mul_i64;
1594
            op_new2 = INDEX_op_muluh_i64;
1595
            have_op_new2 = TCG_TARGET_HAS_muluh_i64;
1596
            goto do_mul2;
1597
        case INDEX_op_muls2_i64:
1598
            op_new = INDEX_op_mul_i64;
1599
            op_new2 = INDEX_op_mulsh_i64;
1600
            have_op_new2 = TCG_TARGET_HAS_mulsh_i64;
1601
            goto do_mul2;
1602
        do_mul2:
1603
            args -= 4;
1604
            nb_iargs = 2;
1605
            nb_oargs = 2;
1606
            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1607
                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1608
                    /* Both parts of the operation are dead.  */
1609
                    goto do_remove;
1610
                }
1611
                /* The high part of the operation is dead; generate the low. */
1612
                s->gen_opc_buf[op_index] = op = op_new;
1613
                args[1] = args[2];
1614
                args[2] = args[3];
1615
            } else if (have_op_new2 && dead_temps[args[0]]
1616
                       && !mem_temps[args[0]]) {
1617
                /* The low part of the operation is dead; generate the high.  */
1618
                s->gen_opc_buf[op_index] = op = op_new2;
1619
                args[0] = args[1];
1620
                args[1] = args[2];
1621
                args[2] = args[3];
1622
            } else {
1623
                goto do_not_remove;
1624
            }
1625
            assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1626
            tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1627
            /* Mark the single-word operation live.  */
1628
            nb_oargs = 1;
1629
            goto do_not_remove;
1630

    
1631
        default:
1632
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1633
            args -= def->nb_args;
1634
            nb_iargs = def->nb_iargs;
1635
            nb_oargs = def->nb_oargs;
1636

    
1637
            /* Test if the operation can be removed because all
1638
               its outputs are dead. We assume that nb_oargs == 0
1639
               implies side effects */
1640
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1641
                for(i = 0; i < nb_oargs; i++) {
1642
                    arg = args[i];
1643
                    if (!dead_temps[arg] || mem_temps[arg]) {
1644
                        goto do_not_remove;
1645
                    }
1646
                }
1647
            do_remove:
1648
                tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
1649
#ifdef CONFIG_PROFILER
1650
                s->del_op_count++;
1651
#endif
1652
            } else {
1653
            do_not_remove:
1654

    
1655
                /* output args are dead */
1656
                dead_args = 0;
1657
                sync_args = 0;
1658
                for(i = 0; i < nb_oargs; i++) {
1659
                    arg = args[i];
1660
                    if (dead_temps[arg]) {
1661
                        dead_args |= (1 << i);
1662
                    }
1663
                    if (mem_temps[arg]) {
1664
                        sync_args |= (1 << i);
1665
                    }
1666
                    dead_temps[arg] = 1;
1667
                    mem_temps[arg] = 0;
1668
                }
1669

    
1670
                /* if end of basic block, update */
1671
                if (def->flags & TCG_OPF_BB_END) {
1672
                    tcg_la_bb_end(s, dead_temps, mem_temps);
1673
                } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1674
                    /* globals should be synced to memory */
1675
                    memset(mem_temps, 1, s->nb_globals);
1676
                }
1677

    
1678
                /* input args are live */
1679
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1680
                    arg = args[i];
1681
                    if (dead_temps[arg]) {
1682
                        dead_args |= (1 << i);
1683
                    }
1684
                    dead_temps[arg] = 0;
1685
                }
1686
                s->op_dead_args[op_index] = dead_args;
1687
                s->op_sync_args[op_index] = sync_args;
1688
            }
1689
            break;
1690
        }
1691
        op_index--;
1692
    }
1693

    
1694
    if (args != s->gen_opparam_buf) {
1695
        tcg_abort();
1696
    }
1697
}
1698
#else
1699
/* dummy liveness analysis */
1700
static void tcg_liveness_analysis(TCGContext *s)
1701
{
1702
    int nb_ops;
1703
    nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1704

    
1705
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1706
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1707
    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1708
    memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1709
}
1710
#endif
1711

    
1712
#ifndef NDEBUG
1713
static void dump_regs(TCGContext *s)
1714
{
1715
    TCGTemp *ts;
1716
    int i;
1717
    char buf[64];
1718

    
1719
    for(i = 0; i < s->nb_temps; i++) {
1720
        ts = &s->temps[i];
1721
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1722
        switch(ts->val_type) {
1723
        case TEMP_VAL_REG:
1724
            printf("%s", tcg_target_reg_names[ts->reg]);
1725
            break;
1726
        case TEMP_VAL_MEM:
1727
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1728
            break;
1729
        case TEMP_VAL_CONST:
1730
            printf("$0x%" TCG_PRIlx, ts->val);
1731
            break;
1732
        case TEMP_VAL_DEAD:
1733
            printf("D");
1734
            break;
1735
        default:
1736
            printf("???");
1737
            break;
1738
        }
1739
        printf("\n");
1740
    }
1741

    
1742
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1743
        if (s->reg_to_temp[i] >= 0) {
1744
            printf("%s: %s\n", 
1745
                   tcg_target_reg_names[i], 
1746
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1747
        }
1748
    }
1749
}
1750

    
1751
static void check_regs(TCGContext *s)
1752
{
1753
    int reg, k;
1754
    TCGTemp *ts;
1755
    char buf[64];
1756

    
1757
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1758
        k = s->reg_to_temp[reg];
1759
        if (k >= 0) {
1760
            ts = &s->temps[k];
1761
            if (ts->val_type != TEMP_VAL_REG ||
1762
                ts->reg != reg) {
1763
                printf("Inconsistency for register %s:\n", 
1764
                       tcg_target_reg_names[reg]);
1765
                goto fail;
1766
            }
1767
        }
1768
    }
1769
    for(k = 0; k < s->nb_temps; k++) {
1770
        ts = &s->temps[k];
1771
        if (ts->val_type == TEMP_VAL_REG &&
1772
            !ts->fixed_reg &&
1773
            s->reg_to_temp[ts->reg] != k) {
1774
                printf("Inconsistency for temp %s:\n", 
1775
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1776
        fail:
1777
                printf("reg state:\n");
1778
                dump_regs(s);
1779
                tcg_abort();
1780
        }
1781
    }
1782
}
1783
#endif
1784

    
1785
static void temp_allocate_frame(TCGContext *s, int temp)
1786
{
1787
    TCGTemp *ts;
1788
    ts = &s->temps[temp];
1789
#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1790
    /* Sparc64 stack is accessed with offset of 2047 */
1791
    s->current_frame_offset = (s->current_frame_offset +
1792
                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
1793
        ~(sizeof(tcg_target_long) - 1);
1794
#endif
1795
    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1796
        s->frame_end) {
1797
        tcg_abort();
1798
    }
1799
    ts->mem_offset = s->current_frame_offset;
1800
    ts->mem_reg = s->frame_reg;
1801
    ts->mem_allocated = 1;
1802
    s->current_frame_offset += sizeof(tcg_target_long);
1803
}
1804

    
1805
/* sync register 'reg' by saving it to the corresponding temporary */
1806
static inline void tcg_reg_sync(TCGContext *s, int reg)
1807
{
1808
    TCGTemp *ts;
1809
    int temp;
1810

    
1811
    temp = s->reg_to_temp[reg];
1812
    ts = &s->temps[temp];
1813
    assert(ts->val_type == TEMP_VAL_REG);
1814
    if (!ts->mem_coherent && !ts->fixed_reg) {
1815
        if (!ts->mem_allocated) {
1816
            temp_allocate_frame(s, temp);
1817
        }
1818
        tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1819
    }
1820
    ts->mem_coherent = 1;
1821
}
1822

    
1823
/* free register 'reg' by spilling the corresponding temporary if necessary */
1824
static void tcg_reg_free(TCGContext *s, int reg)
1825
{
1826
    int temp;
1827

    
1828
    temp = s->reg_to_temp[reg];
1829
    if (temp != -1) {
1830
        tcg_reg_sync(s, reg);
1831
        s->temps[temp].val_type = TEMP_VAL_MEM;
1832
        s->reg_to_temp[reg] = -1;
1833
    }
1834
}
1835

    
1836
/* Allocate a register belonging to reg1 & ~reg2 */
1837
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1838
{
1839
    int i, reg;
1840
    TCGRegSet reg_ct;
1841

    
1842
    tcg_regset_andnot(reg_ct, reg1, reg2);
1843

    
1844
    /* first try free registers */
1845
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1846
        reg = tcg_target_reg_alloc_order[i];
1847
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1848
            return reg;
1849
    }
1850

    
1851
    /* XXX: do better spill choice */
1852
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1853
        reg = tcg_target_reg_alloc_order[i];
1854
        if (tcg_regset_test_reg(reg_ct, reg)) {
1855
            tcg_reg_free(s, reg);
1856
            return reg;
1857
        }
1858
    }
1859

    
1860
    tcg_abort();
1861
}
1862

    
1863
/* mark a temporary as dead. */
1864
static inline void temp_dead(TCGContext *s, int temp)
1865
{
1866
    TCGTemp *ts;
1867

    
1868
    ts = &s->temps[temp];
1869
    if (!ts->fixed_reg) {
1870
        if (ts->val_type == TEMP_VAL_REG) {
1871
            s->reg_to_temp[ts->reg] = -1;
1872
        }
1873
        if (temp < s->nb_globals || ts->temp_local) {
1874
            ts->val_type = TEMP_VAL_MEM;
1875
        } else {
1876
            ts->val_type = TEMP_VAL_DEAD;
1877
        }
1878
    }
1879
}
1880

    
1881
/* sync a temporary to memory. 'allocated_regs' is used in case a
1882
   temporary registers needs to be allocated to store a constant. */
1883
static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1884
{
1885
    TCGTemp *ts;
1886

    
1887
    ts = &s->temps[temp];
1888
    if (!ts->fixed_reg) {
1889
        switch(ts->val_type) {
1890
        case TEMP_VAL_CONST:
1891
            ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1892
                                    allocated_regs);
1893
            ts->val_type = TEMP_VAL_REG;
1894
            s->reg_to_temp[ts->reg] = temp;
1895
            ts->mem_coherent = 0;
1896
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
1897
            /* fallthrough*/
1898
        case TEMP_VAL_REG:
1899
            tcg_reg_sync(s, ts->reg);
1900
            break;
1901
        case TEMP_VAL_DEAD:
1902
        case TEMP_VAL_MEM:
1903
            break;
1904
        default:
1905
            tcg_abort();
1906
        }
1907
    }
1908
}
1909

    
1910
/* save a temporary to memory. 'allocated_regs' is used in case a
1911
   temporary registers needs to be allocated to store a constant. */
1912
static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1913
{
1914
#ifdef USE_LIVENESS_ANALYSIS
1915
    /* The liveness analysis already ensures that globals are back
1916
       in memory. Keep an assert for safety. */
1917
    assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1918
#else
1919
    temp_sync(s, temp, allocated_regs);
1920
    temp_dead(s, temp);
1921
#endif
1922
}
1923

    
1924
/* save globals to their canonical location and assume they can be
1925
   modified be the following code. 'allocated_regs' is used in case a
1926
   temporary registers needs to be allocated to store a constant. */
1927
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1928
{
1929
    int i;
1930

    
1931
    for(i = 0; i < s->nb_globals; i++) {
1932
        temp_save(s, i, allocated_regs);
1933
    }
1934
}
1935

    
1936
/* sync globals to their canonical location and assume they can be
1937
   read by the following code. 'allocated_regs' is used in case a
1938
   temporary registers needs to be allocated to store a constant. */
1939
static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1940
{
1941
    int i;
1942

    
1943
    for (i = 0; i < s->nb_globals; i++) {
1944
#ifdef USE_LIVENESS_ANALYSIS
1945
        assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1946
               s->temps[i].mem_coherent);
1947
#else
1948
        temp_sync(s, i, allocated_regs);
1949
#endif
1950
    }
1951
}
1952

    
1953
/* at the end of a basic block, we assume all temporaries are dead and
1954
   all globals are stored at their canonical location. */
1955
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1956
{
1957
    TCGTemp *ts;
1958
    int i;
1959

    
1960
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1961
        ts = &s->temps[i];
1962
        if (ts->temp_local) {
1963
            temp_save(s, i, allocated_regs);
1964
        } else {
1965
#ifdef USE_LIVENESS_ANALYSIS
1966
            /* The liveness analysis already ensures that temps are dead.
1967
               Keep an assert for safety. */
1968
            assert(ts->val_type == TEMP_VAL_DEAD);
1969
#else
1970
            temp_dead(s, i);
1971
#endif
1972
        }
1973
    }
1974

    
1975
    save_globals(s, allocated_regs);
1976
}
1977

    
1978
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1979
#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1980

    
1981
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1982
                               uint16_t dead_args, uint8_t sync_args)
1983
{
1984
    TCGTemp *ots;
1985
    tcg_target_ulong val;
1986

    
1987
    ots = &s->temps[args[0]];
1988
    val = args[1];
1989

    
1990
    if (ots->fixed_reg) {
1991
        /* for fixed registers, we do not do any constant
1992
           propagation */
1993
        tcg_out_movi(s, ots->type, ots->reg, val);
1994
    } else {
1995
        /* The movi is not explicitly generated here */
1996
        if (ots->val_type == TEMP_VAL_REG)
1997
            s->reg_to_temp[ots->reg] = -1;
1998
        ots->val_type = TEMP_VAL_CONST;
1999
        ots->val = val;
2000
    }
2001
    if (NEED_SYNC_ARG(0)) {
2002
        temp_sync(s, args[0], s->reserved_regs);
2003
    }
2004
    if (IS_DEAD_ARG(0)) {
2005
        temp_dead(s, args[0]);
2006
    }
2007
}
2008

    
2009
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
2010
                              const TCGArg *args, uint16_t dead_args,
2011
                              uint8_t sync_args)
2012
{
2013
    TCGRegSet allocated_regs;
2014
    TCGTemp *ts, *ots;
2015
    const TCGArgConstraint *arg_ct, *oarg_ct;
2016

    
2017
    tcg_regset_set(allocated_regs, s->reserved_regs);
2018
    ots = &s->temps[args[0]];
2019
    ts = &s->temps[args[1]];
2020
    oarg_ct = &def->args_ct[0];
2021
    arg_ct = &def->args_ct[1];
2022

    
2023
    /* If the source value is not in a register, and we're going to be
2024
       forced to have it in a register in order to perform the copy,
2025
       then copy the SOURCE value into its own register first.  That way
2026
       we don't have to reload SOURCE the next time it is used. */
2027
    if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
2028
        || ts->val_type == TEMP_VAL_MEM) {
2029
        ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2030
        if (ts->val_type == TEMP_VAL_MEM) {
2031
            tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
2032
            ts->mem_coherent = 1;
2033
        } else if (ts->val_type == TEMP_VAL_CONST) {
2034
            tcg_out_movi(s, ts->type, ts->reg, ts->val);
2035
        }
2036
        s->reg_to_temp[ts->reg] = args[1];
2037
        ts->val_type = TEMP_VAL_REG;
2038
    }
2039

    
2040
    if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
2041
        /* mov to a non-saved dead register makes no sense (even with
2042
           liveness analysis disabled). */
2043
        assert(NEED_SYNC_ARG(0));
2044
        /* The code above should have moved the temp to a register. */
2045
        assert(ts->val_type == TEMP_VAL_REG);
2046
        if (!ots->mem_allocated) {
2047
            temp_allocate_frame(s, args[0]);
2048
        }
2049
        tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
2050
        if (IS_DEAD_ARG(1)) {
2051
            temp_dead(s, args[1]);
2052
        }
2053
        temp_dead(s, args[0]);
2054
    } else if (ts->val_type == TEMP_VAL_CONST) {
2055
        /* propagate constant */
2056
        if (ots->val_type == TEMP_VAL_REG) {
2057
            s->reg_to_temp[ots->reg] = -1;
2058
        }
2059
        ots->val_type = TEMP_VAL_CONST;
2060
        ots->val = ts->val;
2061
    } else {
2062
        /* The code in the first if block should have moved the
2063
           temp to a register. */
2064
        assert(ts->val_type == TEMP_VAL_REG);
2065
        if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
2066
            /* the mov can be suppressed */
2067
            if (ots->val_type == TEMP_VAL_REG) {
2068
                s->reg_to_temp[ots->reg] = -1;
2069
            }
2070
            ots->reg = ts->reg;
2071
            temp_dead(s, args[1]);
2072
        } else {
2073
            if (ots->val_type != TEMP_VAL_REG) {
2074
                /* When allocating a new register, make sure to not spill the
2075
                   input one. */
2076
                tcg_regset_set_reg(allocated_regs, ts->reg);
2077
                ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs);
2078
            }
2079
            tcg_out_mov(s, ots->type, ots->reg, ts->reg);
2080
        }
2081
        ots->val_type = TEMP_VAL_REG;
2082
        ots->mem_coherent = 0;
2083
        s->reg_to_temp[ots->reg] = args[0];
2084
        if (NEED_SYNC_ARG(0)) {
2085
            tcg_reg_sync(s, ots->reg);
2086
        }
2087
    }
2088
}
2089

    
2090
static void tcg_reg_alloc_op(TCGContext *s, 
2091
                             const TCGOpDef *def, TCGOpcode opc,
2092
                             const TCGArg *args, uint16_t dead_args,
2093
                             uint8_t sync_args)
2094
{
2095
    TCGRegSet allocated_regs;
2096
    int i, k, nb_iargs, nb_oargs, reg;
2097
    TCGArg arg;
2098
    const TCGArgConstraint *arg_ct;
2099
    TCGTemp *ts;
2100
    TCGArg new_args[TCG_MAX_OP_ARGS];
2101
    int const_args[TCG_MAX_OP_ARGS];
2102

    
2103
    nb_oargs = def->nb_oargs;
2104
    nb_iargs = def->nb_iargs;
2105

    
2106
    /* copy constants */
2107
    memcpy(new_args + nb_oargs + nb_iargs, 
2108
           args + nb_oargs + nb_iargs, 
2109
           sizeof(TCGArg) * def->nb_cargs);
2110

    
2111
    /* satisfy input constraints */ 
2112
    tcg_regset_set(allocated_regs, s->reserved_regs);
2113
    for(k = 0; k < nb_iargs; k++) {
2114
        i = def->sorted_args[nb_oargs + k];
2115
        arg = args[i];
2116
        arg_ct = &def->args_ct[i];
2117
        ts = &s->temps[arg];
2118
        if (ts->val_type == TEMP_VAL_MEM) {
2119
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2120
            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2121
            ts->val_type = TEMP_VAL_REG;
2122
            ts->reg = reg;
2123
            ts->mem_coherent = 1;
2124
            s->reg_to_temp[reg] = arg;
2125
        } else if (ts->val_type == TEMP_VAL_CONST) {
2126
            if (tcg_target_const_match(ts->val, arg_ct)) {
2127
                /* constant is OK for instruction */
2128
                const_args[i] = 1;
2129
                new_args[i] = ts->val;
2130
                goto iarg_end;
2131
            } else {
2132
                /* need to move to a register */
2133
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2134
                tcg_out_movi(s, ts->type, reg, ts->val);
2135
                ts->val_type = TEMP_VAL_REG;
2136
                ts->reg = reg;
2137
                ts->mem_coherent = 0;
2138
                s->reg_to_temp[reg] = arg;
2139
            }
2140
        }
2141
        assert(ts->val_type == TEMP_VAL_REG);
2142
        if (arg_ct->ct & TCG_CT_IALIAS) {
2143
            if (ts->fixed_reg) {
2144
                /* if fixed register, we must allocate a new register
2145
                   if the alias is not the same register */
2146
                if (arg != args[arg_ct->alias_index])
2147
                    goto allocate_in_reg;
2148
            } else {
2149
                /* if the input is aliased to an output and if it is
2150
                   not dead after the instruction, we must allocate
2151
                   a new register and move it */
2152
                if (!IS_DEAD_ARG(i)) {
2153
                    goto allocate_in_reg;
2154
                }
2155
            }
2156
        }
2157
        reg = ts->reg;
2158
        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2159
            /* nothing to do : the constraint is satisfied */
2160
        } else {
2161
        allocate_in_reg:
2162
            /* allocate a new register matching the constraint 
2163
               and move the temporary register into it */
2164
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2165
            tcg_out_mov(s, ts->type, reg, ts->reg);
2166
        }
2167
        new_args[i] = reg;
2168
        const_args[i] = 0;
2169
        tcg_regset_set_reg(allocated_regs, reg);
2170
    iarg_end: ;
2171
    }
2172
    
2173
    /* mark dead temporaries and free the associated registers */
2174
    for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2175
        if (IS_DEAD_ARG(i)) {
2176
            temp_dead(s, args[i]);
2177
        }
2178
    }
2179

    
2180
    if (def->flags & TCG_OPF_BB_END) {
2181
        tcg_reg_alloc_bb_end(s, allocated_regs);
2182
    } else {
2183
        if (def->flags & TCG_OPF_CALL_CLOBBER) {
2184
            /* XXX: permit generic clobber register list ? */ 
2185
            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2186
                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2187
                    tcg_reg_free(s, reg);
2188
                }
2189
            }
2190
        }
2191
        if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2192
            /* sync globals if the op has side effects and might trigger
2193
               an exception. */
2194
            sync_globals(s, allocated_regs);
2195
        }
2196
        
2197
        /* satisfy the output constraints */
2198
        tcg_regset_set(allocated_regs, s->reserved_regs);
2199
        for(k = 0; k < nb_oargs; k++) {
2200
            i = def->sorted_args[k];
2201
            arg = args[i];
2202
            arg_ct = &def->args_ct[i];
2203
            ts = &s->temps[arg];
2204
            if (arg_ct->ct & TCG_CT_ALIAS) {
2205
                reg = new_args[arg_ct->alias_index];
2206
            } else {
2207
                /* if fixed register, we try to use it */
2208
                reg = ts->reg;
2209
                if (ts->fixed_reg &&
2210
                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2211
                    goto oarg_end;
2212
                }
2213
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2214
            }
2215
            tcg_regset_set_reg(allocated_regs, reg);
2216
            /* if a fixed register is used, then a move will be done afterwards */
2217
            if (!ts->fixed_reg) {
2218
                if (ts->val_type == TEMP_VAL_REG) {
2219
                    s->reg_to_temp[ts->reg] = -1;
2220
                }
2221
                ts->val_type = TEMP_VAL_REG;
2222
                ts->reg = reg;
2223
                /* temp value is modified, so the value kept in memory is
2224
                   potentially not the same */
2225
                ts->mem_coherent = 0;
2226
                s->reg_to_temp[reg] = arg;
2227
            }
2228
        oarg_end:
2229
            new_args[i] = reg;
2230
        }
2231
    }
2232

    
2233
    /* emit instruction */
2234
    tcg_out_op(s, opc, new_args, const_args);
2235
    
2236
    /* move the outputs in the correct register if needed */
2237
    for(i = 0; i < nb_oargs; i++) {
2238
        ts = &s->temps[args[i]];
2239
        reg = new_args[i];
2240
        if (ts->fixed_reg && ts->reg != reg) {
2241
            tcg_out_mov(s, ts->type, ts->reg, reg);
2242
        }
2243
        if (NEED_SYNC_ARG(i)) {
2244
            tcg_reg_sync(s, reg);
2245
        }
2246
        if (IS_DEAD_ARG(i)) {
2247
            temp_dead(s, args[i]);
2248
        }
2249
    }
2250
}
2251

    
2252
#ifdef TCG_TARGET_STACK_GROWSUP
2253
#define STACK_DIR(x) (-(x))
2254
#else
2255
#define STACK_DIR(x) (x)
2256
#endif
2257

    
2258
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
2259
                              TCGOpcode opc, const TCGArg *args,
2260
                              uint16_t dead_args, uint8_t sync_args)
2261
{
2262
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2263
    TCGArg arg, func_arg;
2264
    TCGTemp *ts;
2265
    intptr_t stack_offset;
2266
    size_t call_stack_size;
2267
    uintptr_t func_addr;
2268
    int const_func_arg, allocate_args;
2269
    TCGRegSet allocated_regs;
2270
    const TCGArgConstraint *arg_ct;
2271

    
2272
    arg = *args++;
2273

    
2274
    nb_oargs = arg >> 16;
2275
    nb_iargs = arg & 0xffff;
2276
    nb_params = nb_iargs - 1;
2277

    
2278
    flags = args[nb_oargs + nb_iargs];
2279

    
2280
    nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2281
    if (nb_regs > nb_params)
2282
        nb_regs = nb_params;
2283

    
2284
    /* assign stack slots first */
2285
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2286
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
2287
        ~(TCG_TARGET_STACK_ALIGN - 1);
2288
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2289
    if (allocate_args) {
2290
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2291
           preallocate call stack */
2292
        tcg_abort();
2293
    }
2294

    
2295
    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2296
    for(i = nb_regs; i < nb_params; i++) {
2297
        arg = args[nb_oargs + i];
2298
#ifdef TCG_TARGET_STACK_GROWSUP
2299
        stack_offset -= sizeof(tcg_target_long);
2300
#endif
2301
        if (arg != TCG_CALL_DUMMY_ARG) {
2302
            ts = &s->temps[arg];
2303
            if (ts->val_type == TEMP_VAL_REG) {
2304
                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2305
            } else if (ts->val_type == TEMP_VAL_MEM) {
2306
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2307
                                    s->reserved_regs);
2308
                /* XXX: not correct if reading values from the stack */
2309
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2310
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2311
            } else if (ts->val_type == TEMP_VAL_CONST) {
2312
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2313
                                    s->reserved_regs);
2314
                /* XXX: sign extend may be needed on some targets */
2315
                tcg_out_movi(s, ts->type, reg, ts->val);
2316
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2317
            } else {
2318
                tcg_abort();
2319
            }
2320
        }
2321
#ifndef TCG_TARGET_STACK_GROWSUP
2322
        stack_offset += sizeof(tcg_target_long);
2323
#endif
2324
    }
2325
    
2326
    /* assign input registers */
2327
    tcg_regset_set(allocated_regs, s->reserved_regs);
2328
    for(i = 0; i < nb_regs; i++) {
2329
        arg = args[nb_oargs + i];
2330
        if (arg != TCG_CALL_DUMMY_ARG) {
2331
            ts = &s->temps[arg];
2332
            reg = tcg_target_call_iarg_regs[i];
2333
            tcg_reg_free(s, reg);
2334
            if (ts->val_type == TEMP_VAL_REG) {
2335
                if (ts->reg != reg) {
2336
                    tcg_out_mov(s, ts->type, reg, ts->reg);
2337
                }
2338
            } else if (ts->val_type == TEMP_VAL_MEM) {
2339
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2340
            } else if (ts->val_type == TEMP_VAL_CONST) {
2341
                /* XXX: sign extend ? */
2342
                tcg_out_movi(s, ts->type, reg, ts->val);
2343
            } else {
2344
                tcg_abort();
2345
            }
2346
            tcg_regset_set_reg(allocated_regs, reg);
2347
        }
2348
    }
2349
    
2350
    /* assign function address */
2351
    func_arg = args[nb_oargs + nb_iargs - 1];
2352
    arg_ct = &def->args_ct[0];
2353
    ts = &s->temps[func_arg];
2354
    func_addr = ts->val;
2355
    const_func_arg = 0;
2356
    if (ts->val_type == TEMP_VAL_MEM) {
2357
        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2358
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2359
        func_arg = reg;
2360
        tcg_regset_set_reg(allocated_regs, reg);
2361
    } else if (ts->val_type == TEMP_VAL_REG) {
2362
        reg = ts->reg;
2363
        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2364
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2365
            tcg_out_mov(s, ts->type, reg, ts->reg);
2366
        }
2367
        func_arg = reg;
2368
        tcg_regset_set_reg(allocated_regs, reg);
2369
    } else if (ts->val_type == TEMP_VAL_CONST) {
2370
        if (tcg_target_const_match(func_addr, arg_ct)) {
2371
            const_func_arg = 1;
2372
            func_arg = func_addr;
2373
        } else {
2374
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2375
            tcg_out_movi(s, ts->type, reg, func_addr);
2376
            func_arg = reg;
2377
            tcg_regset_set_reg(allocated_regs, reg);
2378
        }
2379
    } else {
2380
        tcg_abort();
2381
    }
2382
        
2383
    
2384
    /* mark dead temporaries and free the associated registers */
2385
    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2386
        if (IS_DEAD_ARG(i)) {
2387
            temp_dead(s, args[i]);
2388
        }
2389
    }
2390
    
2391
    /* clobber call registers */
2392
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2393
        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2394
            tcg_reg_free(s, reg);
2395
        }
2396
    }
2397

    
2398
    /* Save globals if they might be written by the helper, sync them if
2399
       they might be read. */
2400
    if (flags & TCG_CALL_NO_READ_GLOBALS) {
2401
        /* Nothing to do */
2402
    } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2403
        sync_globals(s, allocated_regs);
2404
    } else {
2405
        save_globals(s, allocated_regs);
2406
    }
2407

    
2408
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
2409

    
2410
    /* assign output registers and emit moves if needed */
2411
    for(i = 0; i < nb_oargs; i++) {
2412
        arg = args[i];
2413
        ts = &s->temps[arg];
2414
        reg = tcg_target_call_oarg_regs[i];
2415
        assert(s->reg_to_temp[reg] == -1);
2416
        if (ts->fixed_reg) {
2417
            if (ts->reg != reg) {
2418
                tcg_out_mov(s, ts->type, ts->reg, reg);
2419
            }
2420
        } else {
2421
            if (ts->val_type == TEMP_VAL_REG) {
2422
                s->reg_to_temp[ts->reg] = -1;
2423
            }
2424
            ts->val_type = TEMP_VAL_REG;
2425
            ts->reg = reg;
2426
            ts->mem_coherent = 0;
2427
            s->reg_to_temp[reg] = arg;
2428
            if (NEED_SYNC_ARG(i)) {
2429
                tcg_reg_sync(s, reg);
2430
            }
2431
            if (IS_DEAD_ARG(i)) {
2432
                temp_dead(s, args[i]);
2433
            }
2434
        }
2435
    }
2436
    
2437
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2438
}
2439

    
2440
#ifdef CONFIG_PROFILER
2441

    
2442
static int64_t tcg_table_op_count[NB_OPS];
2443

    
2444
static void dump_op_count(void)
2445
{
2446
    int i;
2447
    FILE *f;
2448
    f = fopen("/tmp/op.log", "w");
2449
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2450
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2451
    }
2452
    fclose(f);
2453
}
2454
#endif
2455

    
2456

    
2457
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2458
                                      long search_pc)
2459
{
2460
    TCGOpcode opc;
2461
    int op_index;
2462
    const TCGOpDef *def;
2463
    const TCGArg *args;
2464

    
2465
#ifdef DEBUG_DISAS
2466
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2467
        qemu_log("OP:\n");
2468
        tcg_dump_ops(s);
2469
        qemu_log("\n");
2470
    }
2471
#endif
2472

    
2473
#ifdef CONFIG_PROFILER
2474
    s->opt_time -= profile_getclock();
2475
#endif
2476

    
2477
#ifdef USE_TCG_OPTIMIZATIONS
2478
    s->gen_opparam_ptr =
2479
        tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2480
#endif
2481

    
2482
#ifdef CONFIG_PROFILER
2483
    s->opt_time += profile_getclock();
2484
    s->la_time -= profile_getclock();
2485
#endif
2486

    
2487
    tcg_liveness_analysis(s);
2488

    
2489
#ifdef CONFIG_PROFILER
2490
    s->la_time += profile_getclock();
2491
#endif
2492

    
2493
#ifdef DEBUG_DISAS
2494
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2495
        qemu_log("OP after optimization and liveness analysis:\n");
2496
        tcg_dump_ops(s);
2497
        qemu_log("\n");
2498
    }
2499
#endif
2500

    
2501
    tcg_reg_alloc_start(s);
2502

    
2503
    s->code_buf = gen_code_buf;
2504
    s->code_ptr = gen_code_buf;
2505

    
2506
    tcg_out_tb_init(s);
2507

    
2508
    args = s->gen_opparam_buf;
2509
    op_index = 0;
2510

    
2511
    for(;;) {
2512
        opc = s->gen_opc_buf[op_index];
2513
#ifdef CONFIG_PROFILER
2514
        tcg_table_op_count[opc]++;
2515
#endif
2516
        def = &tcg_op_defs[opc];
2517
#if 0
2518
        printf("%s: %d %d %d\n", def->name,
2519
               def->nb_oargs, def->nb_iargs, def->nb_cargs);
2520
        //        dump_regs(s);
2521
#endif
2522
        switch(opc) {
2523
        case INDEX_op_mov_i32:
2524
        case INDEX_op_mov_i64:
2525
            tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2526
                              s->op_sync_args[op_index]);
2527
            break;
2528
        case INDEX_op_movi_i32:
2529
        case INDEX_op_movi_i64:
2530
            tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2531
                               s->op_sync_args[op_index]);
2532
            break;
2533
        case INDEX_op_debug_insn_start:
2534
            /* debug instruction */
2535
            break;
2536
        case INDEX_op_nop:
2537
        case INDEX_op_nop1:
2538
        case INDEX_op_nop2:
2539
        case INDEX_op_nop3:
2540
            break;
2541
        case INDEX_op_nopn:
2542
            args += args[0];
2543
            goto next;
2544
        case INDEX_op_discard:
2545
            temp_dead(s, args[0]);
2546
            break;
2547
        case INDEX_op_set_label:
2548
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
2549
            tcg_out_label(s, args[0], s->code_ptr);
2550
            break;
2551
        case INDEX_op_call:
2552
            args += tcg_reg_alloc_call(s, def, opc, args,
2553
                                       s->op_dead_args[op_index],
2554
                                       s->op_sync_args[op_index]);
2555
            goto next;
2556
        case INDEX_op_end:
2557
            goto the_end;
2558
        default:
2559
            /* Sanity check that we've not introduced any unhandled opcodes. */
2560
            if (def->flags & TCG_OPF_NOT_PRESENT) {
2561
                tcg_abort();
2562
            }
2563
            /* Note: in order to speed up the code, it would be much
2564
               faster to have specialized register allocator functions for
2565
               some common argument patterns */
2566
            tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2567
                             s->op_sync_args[op_index]);
2568
            break;
2569
        }
2570
        args += def->nb_args;
2571
    next:
2572
        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2573
            return op_index;
2574
        }
2575
        op_index++;
2576
#ifndef NDEBUG
2577
        check_regs(s);
2578
#endif
2579
    }
2580
 the_end:
2581
    /* Generate TB finalization at the end of block */
2582
    tcg_out_tb_finalize(s);
2583
    return -1;
2584
}
2585

    
2586
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2587
{
2588
#ifdef CONFIG_PROFILER
2589
    {
2590
        int n;
2591
        n = (s->gen_opc_ptr - s->gen_opc_buf);
2592
        s->op_count += n;
2593
        if (n > s->op_count_max)
2594
            s->op_count_max = n;
2595

    
2596
        s->temp_count += s->nb_temps;
2597
        if (s->nb_temps > s->temp_count_max)
2598
            s->temp_count_max = s->nb_temps;
2599
    }
2600
#endif
2601

    
2602
    tcg_gen_code_common(s, gen_code_buf, -1);
2603

    
2604
    /* flush instruction cache */
2605
    flush_icache_range((uintptr_t)gen_code_buf, (uintptr_t)s->code_ptr);
2606

    
2607
    return s->code_ptr -  gen_code_buf;
2608
}
2609

    
2610
/* Return the index of the micro operation such as the pc after is <
2611
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2612
   not be changed, though writing the same values is ok.
2613
   Return -1 if not found. */
2614
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2615
{
2616
    return tcg_gen_code_common(s, gen_code_buf, offset);
2617
}
2618

    
2619
#ifdef CONFIG_PROFILER
2620
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2621
{
2622
    TCGContext *s = &tcg_ctx;
2623
    int64_t tot;
2624

    
2625
    tot = s->interm_time + s->code_time;
2626
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2627
                tot, tot / 2.4e9);
2628
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2629
                s->tb_count, 
2630
                s->tb_count1 - s->tb_count,
2631
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2632
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2633
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2634
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2635
                s->tb_count ? 
2636
                (double)s->del_op_count / s->tb_count : 0);
2637
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2638
                s->tb_count ? 
2639
                (double)s->temp_count / s->tb_count : 0,
2640
                s->temp_count_max);
2641
    
2642
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2643
                s->op_count ? (double)tot / s->op_count : 0);
2644
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2645
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2646
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2647
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2648
    if (tot == 0)
2649
        tot = 1;
2650
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2651
                (double)s->interm_time / tot * 100.0);
2652
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2653
                (double)s->code_time / tot * 100.0);
2654
    cpu_fprintf(f, "optim./code time    %0.1f%%\n",
2655
                (double)s->opt_time / (s->code_time ? s->code_time : 1)
2656
                * 100.0);
2657
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2658
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2659
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2660
                s->restore_count);
2661
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2662
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2663

    
2664
    dump_op_count();
2665
}
2666
#else
2667
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2668
{
2669
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2670
}
2671
#endif
2672

    
2673
#ifdef ELF_HOST_MACHINE
2674
/* In order to use this feature, the backend needs to do three things:
2675

2676
   (1) Define ELF_HOST_MACHINE to indicate both what value to
2677
       put into the ELF image and to indicate support for the feature.
2678

2679
   (2) Define tcg_register_jit.  This should create a buffer containing
2680
       the contents of a .debug_frame section that describes the post-
2681
       prologue unwind info for the tcg machine.
2682

2683
   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2684
*/
2685

    
2686
/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2687
typedef enum {
2688
    JIT_NOACTION = 0,
2689
    JIT_REGISTER_FN,
2690
    JIT_UNREGISTER_FN
2691
} jit_actions_t;
2692

    
2693
struct jit_code_entry {
2694
    struct jit_code_entry *next_entry;
2695
    struct jit_code_entry *prev_entry;
2696
    const void *symfile_addr;
2697
    uint64_t symfile_size;
2698
};
2699

    
2700
struct jit_descriptor {
2701
    uint32_t version;
2702
    uint32_t action_flag;
2703
    struct jit_code_entry *relevant_entry;
2704
    struct jit_code_entry *first_entry;
2705
};
2706

    
2707
void __jit_debug_register_code(void) __attribute__((noinline));
2708
void __jit_debug_register_code(void)
2709
{
2710
    asm("");
2711
}
2712

    
2713
/* Must statically initialize the version, because GDB may check
2714
   the version before we can set it.  */
2715
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2716

    
2717
/* End GDB interface.  */
2718

    
2719
static int find_string(const char *strtab, const char *str)
2720
{
2721
    const char *p = strtab + 1;
2722

    
2723
    while (1) {
2724
        if (strcmp(p, str) == 0) {
2725
            return p - strtab;
2726
        }
2727
        p += strlen(p) + 1;
2728
    }
2729
}
2730

    
2731
static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2732
                                 void *debug_frame, size_t debug_frame_size)
2733
{
2734
    struct __attribute__((packed)) DebugInfo {
2735
        uint32_t  len;
2736
        uint16_t  version;
2737
        uint32_t  abbrev;
2738
        uint8_t   ptr_size;
2739
        uint8_t   cu_die;
2740
        uint16_t  cu_lang;
2741
        uintptr_t cu_low_pc;
2742
        uintptr_t cu_high_pc;
2743
        uint8_t   fn_die;
2744
        char      fn_name[16];
2745
        uintptr_t fn_low_pc;
2746
        uintptr_t fn_high_pc;
2747
        uint8_t   cu_eoc;
2748
    };
2749

    
2750
    struct ElfImage {
2751
        ElfW(Ehdr) ehdr;
2752
        ElfW(Phdr) phdr;
2753
        ElfW(Shdr) shdr[7];
2754
        ElfW(Sym)  sym[2];
2755
        struct DebugInfo di;
2756
        uint8_t    da[24];
2757
        char       str[80];
2758
    };
2759

    
2760
    struct ElfImage *img;
2761

    
2762
    static const struct ElfImage img_template = {
2763
        .ehdr = {
2764
            .e_ident[EI_MAG0] = ELFMAG0,
2765
            .e_ident[EI_MAG1] = ELFMAG1,
2766
            .e_ident[EI_MAG2] = ELFMAG2,
2767
            .e_ident[EI_MAG3] = ELFMAG3,
2768
            .e_ident[EI_CLASS] = ELF_CLASS,
2769
            .e_ident[EI_DATA] = ELF_DATA,
2770
            .e_ident[EI_VERSION] = EV_CURRENT,
2771
            .e_type = ET_EXEC,
2772
            .e_machine = ELF_HOST_MACHINE,
2773
            .e_version = EV_CURRENT,
2774
            .e_phoff = offsetof(struct ElfImage, phdr),
2775
            .e_shoff = offsetof(struct ElfImage, shdr),
2776
            .e_ehsize = sizeof(ElfW(Shdr)),
2777
            .e_phentsize = sizeof(ElfW(Phdr)),
2778
            .e_phnum = 1,
2779
            .e_shentsize = sizeof(ElfW(Shdr)),
2780
            .e_shnum = ARRAY_SIZE(img->shdr),
2781
            .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2782
#ifdef ELF_HOST_FLAGS
2783
            .e_flags = ELF_HOST_FLAGS,
2784
#endif
2785
#ifdef ELF_OSABI
2786
            .e_ident[EI_OSABI] = ELF_OSABI,
2787
#endif
2788
        },
2789
        .phdr = {
2790
            .p_type = PT_LOAD,
2791
            .p_flags = PF_X,
2792
        },
2793
        .shdr = {
2794
            [0] = { .sh_type = SHT_NULL },
2795
            /* Trick: The contents of code_gen_buffer are not present in
2796
               this fake ELF file; that got allocated elsewhere.  Therefore
2797
               we mark .text as SHT_NOBITS (similar to .bss) so that readers
2798
               will not look for contents.  We can record any address.  */
2799
            [1] = { /* .text */
2800
                .sh_type = SHT_NOBITS,
2801
                .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2802
            },
2803
            [2] = { /* .debug_info */
2804
                .sh_type = SHT_PROGBITS,
2805
                .sh_offset = offsetof(struct ElfImage, di),
2806
                .sh_size = sizeof(struct DebugInfo),
2807
            },
2808
            [3] = { /* .debug_abbrev */
2809
                .sh_type = SHT_PROGBITS,
2810
                .sh_offset = offsetof(struct ElfImage, da),
2811
                .sh_size = sizeof(img->da),
2812
            },
2813
            [4] = { /* .debug_frame */
2814
                .sh_type = SHT_PROGBITS,
2815
                .sh_offset = sizeof(struct ElfImage),
2816
            },
2817
            [5] = { /* .symtab */
2818
                .sh_type = SHT_SYMTAB,
2819
                .sh_offset = offsetof(struct ElfImage, sym),
2820
                .sh_size = sizeof(img->sym),
2821
                .sh_info = 1,
2822
                .sh_link = ARRAY_SIZE(img->shdr) - 1,
2823
                .sh_entsize = sizeof(ElfW(Sym)),
2824
            },
2825
            [6] = { /* .strtab */
2826
                .sh_type = SHT_STRTAB,
2827
                .sh_offset = offsetof(struct ElfImage, str),
2828
                .sh_size = sizeof(img->str),
2829
            }
2830
        },
2831
        .sym = {
2832
            [1] = { /* code_gen_buffer */
2833
                .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2834
                .st_shndx = 1,
2835
            }
2836
        },
2837
        .di = {
2838
            .len = sizeof(struct DebugInfo) - 4,
2839
            .version = 2,
2840
            .ptr_size = sizeof(void *),
2841
            .cu_die = 1,
2842
            .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
2843
            .fn_die = 2,
2844
            .fn_name = "code_gen_buffer"
2845
        },
2846
        .da = {
2847
            1,          /* abbrev number (the cu) */
2848
            0x11, 1,    /* DW_TAG_compile_unit, has children */
2849
            0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
2850
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2851
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2852
            0, 0,       /* end of abbrev */
2853
            2,          /* abbrev number (the fn) */
2854
            0x2e, 0,    /* DW_TAG_subprogram, no children */
2855
            0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
2856
            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2857
            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2858
            0, 0,       /* end of abbrev */
2859
            0           /* no more abbrev */
2860
        },
2861
        .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2862
               ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2863
    };
2864

    
2865
    /* We only need a single jit entry; statically allocate it.  */
2866
    static struct jit_code_entry one_entry;
2867

    
2868
    uintptr_t buf = (uintptr_t)buf_ptr;
2869
    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2870

    
2871
    img = g_malloc(img_size);
2872
    *img = img_template;
2873
    memcpy(img + 1, debug_frame, debug_frame_size);
2874

    
2875
    img->phdr.p_vaddr = buf;
2876
    img->phdr.p_paddr = buf;
2877
    img->phdr.p_memsz = buf_size;
2878

    
2879
    img->shdr[1].sh_name = find_string(img->str, ".text");
2880
    img->shdr[1].sh_addr = buf;
2881
    img->shdr[1].sh_size = buf_size;
2882

    
2883
    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2884
    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2885

    
2886
    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2887
    img->shdr[4].sh_size = debug_frame_size;
2888

    
2889
    img->shdr[5].sh_name = find_string(img->str, ".symtab");
2890
    img->shdr[6].sh_name = find_string(img->str, ".strtab");
2891

    
2892
    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2893
    img->sym[1].st_value = buf;
2894
    img->sym[1].st_size = buf_size;
2895

    
2896
    img->di.cu_low_pc = buf;
2897
    img->di.cu_high_pc = buf + buf_size;
2898
    img->di.fn_low_pc = buf;
2899
    img->di.fn_high_pc = buf + buf_size;
2900

    
2901
#ifdef DEBUG_JIT
2902
    /* Enable this block to be able to debug the ELF image file creation.
2903
       One can use readelf, objdump, or other inspection utilities.  */
2904
    {
2905
        FILE *f = fopen("/tmp/qemu.jit", "w+b");
2906
        if (f) {
2907
            if (fwrite(img, img_size, 1, f) != img_size) {
2908
                /* Avoid stupid unused return value warning for fwrite.  */
2909
            }
2910
            fclose(f);
2911
        }
2912
    }
2913
#endif
2914

    
2915
    one_entry.symfile_addr = img;
2916
    one_entry.symfile_size = img_size;
2917

    
2918
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2919
    __jit_debug_descriptor.relevant_entry = &one_entry;
2920
    __jit_debug_descriptor.first_entry = &one_entry;
2921
    __jit_debug_register_code();
2922
}
2923
#else
2924
/* No support for the feature.  Provide the entry point expected by exec.c,
2925
   and implement the internal function we declared earlier.  */
2926

    
2927
static void tcg_register_jit_int(void *buf, size_t size,
2928
                                 void *debug_frame, size_t debug_frame_size)
2929
{
2930
}
2931

    
2932
void tcg_register_jit(void *buf, size_t buf_size)
2933
{
2934
}
2935
#endif /* ELF_HOST_MACHINE */