Statistics
| Branch: | Revision:

root / tcg / tcg.c @ ae60fea9

History | View | Annotate | Download (66 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

    
28
#include "config.h"
29

    
30
#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
31
/* define it to suppress various consistency checks (faster) */
32
#define NDEBUG
33
#endif
34

    
35
#include <stdarg.h>
36
#include <stdlib.h>
37
#include <stdio.h>
38
#include <string.h>
39
#include <inttypes.h>
40
#ifdef _WIN32
41
#include <malloc.h>
42
#endif
43
#ifdef _AIX
44
#include <alloca.h>
45
#endif
46

    
47
#include "qemu-common.h"
48
#include "cache-utils.h"
49
#include "host-utils.h"
50
#include "qemu-timer.h"
51

    
52
/* Note: the long term plan is to reduce the dependancies on the QEMU
53
   CPU definitions. Currently they are used for qemu_ld/st
54
   instructions */
55
#define NO_CPU_IO_DEFS
56
#include "cpu.h"
57

    
58
#include "tcg-op.h"
59
#include "elf.h"
60

    
61
#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
62
#error GUEST_BASE not supported on this host.
63
#endif
64

    
65
static void tcg_target_init(TCGContext *s);
66
static void tcg_target_qemu_prologue(TCGContext *s);
67
static void patch_reloc(uint8_t *code_ptr, int type, 
68
                        tcg_target_long value, tcg_target_long addend);
69

    
70
static TCGOpDef tcg_op_defs[] = {
71
#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
72
#include "tcg-opc.h"
73
#undef DEF
74
};
75

    
76
static TCGRegSet tcg_target_available_regs[2];
77
static TCGRegSet tcg_target_call_clobber_regs;
78

    
79
/* XXX: move that inside the context */
80
uint16_t *gen_opc_ptr;
81
TCGArg *gen_opparam_ptr;
82

    
83
static inline void tcg_out8(TCGContext *s, uint8_t v)
84
{
85
    *s->code_ptr++ = v;
86
}
87

    
88
static inline void tcg_out16(TCGContext *s, uint16_t v)
89
{
90
    *(uint16_t *)s->code_ptr = v;
91
    s->code_ptr += 2;
92
}
93

    
94
static inline void tcg_out32(TCGContext *s, uint32_t v)
95
{
96
    *(uint32_t *)s->code_ptr = v;
97
    s->code_ptr += 4;
98
}
99

    
100
/* label relocation processing */
101

    
102
static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
103
                          int label_index, long addend)
104
{
105
    TCGLabel *l;
106
    TCGRelocation *r;
107

    
108
    l = &s->labels[label_index];
109
    if (l->has_value) {
110
        /* FIXME: This may break relocations on RISC targets that
111
           modify instruction fields in place.  The caller may not have 
112
           written the initial value.  */
113
        patch_reloc(code_ptr, type, l->u.value, addend);
114
    } else {
115
        /* add a new relocation entry */
116
        r = tcg_malloc(sizeof(TCGRelocation));
117
        r->type = type;
118
        r->ptr = code_ptr;
119
        r->addend = addend;
120
        r->next = l->u.first_reloc;
121
        l->u.first_reloc = r;
122
    }
123
}
124

    
125
static void tcg_out_label(TCGContext *s, int label_index, 
126
                          tcg_target_long value)
127
{
128
    TCGLabel *l;
129
    TCGRelocation *r;
130

    
131
    l = &s->labels[label_index];
132
    if (l->has_value)
133
        tcg_abort();
134
    r = l->u.first_reloc;
135
    while (r != NULL) {
136
        patch_reloc(r->ptr, r->type, value, r->addend);
137
        r = r->next;
138
    }
139
    l->has_value = 1;
140
    l->u.value = value;
141
}
142

    
143
int gen_new_label(void)
144
{
145
    TCGContext *s = &tcg_ctx;
146
    int idx;
147
    TCGLabel *l;
148

    
149
    if (s->nb_labels >= TCG_MAX_LABELS)
150
        tcg_abort();
151
    idx = s->nb_labels++;
152
    l = &s->labels[idx];
153
    l->has_value = 0;
154
    l->u.first_reloc = NULL;
155
    return idx;
156
}
157

    
158
#include "tcg-target.c"
159

    
160
/* pool based memory allocation */
161
void *tcg_malloc_internal(TCGContext *s, int size)
162
{
163
    TCGPool *p;
164
    int pool_size;
165
    
166
    if (size > TCG_POOL_CHUNK_SIZE) {
167
        /* big malloc: insert a new pool (XXX: could optimize) */
168
        p = qemu_malloc(sizeof(TCGPool) + size);
169
        p->size = size;
170
        if (s->pool_current)
171
            s->pool_current->next = p;
172
        else
173
            s->pool_first = p;
174
        p->next = s->pool_current;
175
    } else {
176
        p = s->pool_current;
177
        if (!p) {
178
            p = s->pool_first;
179
            if (!p)
180
                goto new_pool;
181
        } else {
182
            if (!p->next) {
183
            new_pool:
184
                pool_size = TCG_POOL_CHUNK_SIZE;
185
                p = qemu_malloc(sizeof(TCGPool) + pool_size);
186
                p->size = pool_size;
187
                p->next = NULL;
188
                if (s->pool_current) 
189
                    s->pool_current->next = p;
190
                else
191
                    s->pool_first = p;
192
            } else {
193
                p = p->next;
194
            }
195
        }
196
    }
197
    s->pool_current = p;
198
    s->pool_cur = p->data + size;
199
    s->pool_end = p->data + p->size;
200
    return p->data;
201
}
202

    
203
void tcg_pool_reset(TCGContext *s)
204
{
205
    s->pool_cur = s->pool_end = NULL;
206
    s->pool_current = NULL;
207
}
208

    
209
void tcg_context_init(TCGContext *s)
210
{
211
    int op, total_args, n;
212
    TCGOpDef *def;
213
    TCGArgConstraint *args_ct;
214
    int *sorted_args;
215

    
216
    memset(s, 0, sizeof(*s));
217
    s->temps = s->static_temps;
218
    s->nb_globals = 0;
219
    
220
    /* Count total number of arguments and allocate the corresponding
221
       space */
222
    total_args = 0;
223
    for(op = 0; op < NB_OPS; op++) {
224
        def = &tcg_op_defs[op];
225
        n = def->nb_iargs + def->nb_oargs;
226
        total_args += n;
227
    }
228

    
229
    args_ct = qemu_malloc(sizeof(TCGArgConstraint) * total_args);
230
    sorted_args = qemu_malloc(sizeof(int) * total_args);
231

    
232
    for(op = 0; op < NB_OPS; op++) {
233
        def = &tcg_op_defs[op];
234
        def->args_ct = args_ct;
235
        def->sorted_args = sorted_args;
236
        n = def->nb_iargs + def->nb_oargs;
237
        sorted_args += n;
238
        args_ct += n;
239
    }
240
    
241
    tcg_target_init(s);
242
}
243

    
244
void tcg_prologue_init(TCGContext *s)
245
{
246
    /* init global prologue and epilogue */
247
    s->code_buf = code_gen_prologue;
248
    s->code_ptr = s->code_buf;
249
    tcg_target_qemu_prologue(s);
250
    flush_icache_range((unsigned long)s->code_buf, 
251
                       (unsigned long)s->code_ptr);
252
}
253

    
254
void tcg_set_frame(TCGContext *s, int reg,
255
                   tcg_target_long start, tcg_target_long size)
256
{
257
    s->frame_start = start;
258
    s->frame_end = start + size;
259
    s->frame_reg = reg;
260
}
261

    
262
void tcg_func_start(TCGContext *s)
263
{
264
    int i;
265
    tcg_pool_reset(s);
266
    s->nb_temps = s->nb_globals;
267
    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
268
        s->first_free_temp[i] = -1;
269
    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
270
    s->nb_labels = 0;
271
    s->current_frame_offset = s->frame_start;
272

    
273
    gen_opc_ptr = gen_opc_buf;
274
    gen_opparam_ptr = gen_opparam_buf;
275
}
276

    
277
static inline void tcg_temp_alloc(TCGContext *s, int n)
278
{
279
    if (n > TCG_MAX_TEMPS)
280
        tcg_abort();
281
}
282

    
283
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
284
                                              const char *name)
285
{
286
    TCGContext *s = &tcg_ctx;
287
    TCGTemp *ts;
288
    int idx;
289

    
290
#if TCG_TARGET_REG_BITS == 32
291
    if (type != TCG_TYPE_I32)
292
        tcg_abort();
293
#endif
294
    if (tcg_regset_test_reg(s->reserved_regs, reg))
295
        tcg_abort();
296
    idx = s->nb_globals;
297
    tcg_temp_alloc(s, s->nb_globals + 1);
298
    ts = &s->temps[s->nb_globals];
299
    ts->base_type = type;
300
    ts->type = type;
301
    ts->fixed_reg = 1;
302
    ts->reg = reg;
303
    ts->name = name;
304
    s->nb_globals++;
305
    tcg_regset_set_reg(s->reserved_regs, reg);
306
    return idx;
307
}
308

    
309
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
310
{
311
    int idx;
312

    
313
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
314
    return MAKE_TCGV_I32(idx);
315
}
316

    
317
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
318
{
319
    int idx;
320

    
321
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
322
    return MAKE_TCGV_I64(idx);
323
}
324

    
325
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
326
                                              tcg_target_long offset,
327
                                              const char *name)
328
{
329
    TCGContext *s = &tcg_ctx;
330
    TCGTemp *ts;
331
    int idx;
332

    
333
    idx = s->nb_globals;
334
#if TCG_TARGET_REG_BITS == 32
335
    if (type == TCG_TYPE_I64) {
336
        char buf[64];
337
        tcg_temp_alloc(s, s->nb_globals + 2);
338
        ts = &s->temps[s->nb_globals];
339
        ts->base_type = type;
340
        ts->type = TCG_TYPE_I32;
341
        ts->fixed_reg = 0;
342
        ts->mem_allocated = 1;
343
        ts->mem_reg = reg;
344
#ifdef TCG_TARGET_WORDS_BIGENDIAN
345
        ts->mem_offset = offset + 4;
346
#else
347
        ts->mem_offset = offset;
348
#endif
349
        pstrcpy(buf, sizeof(buf), name);
350
        pstrcat(buf, sizeof(buf), "_0");
351
        ts->name = strdup(buf);
352
        ts++;
353

    
354
        ts->base_type = type;
355
        ts->type = TCG_TYPE_I32;
356
        ts->fixed_reg = 0;
357
        ts->mem_allocated = 1;
358
        ts->mem_reg = reg;
359
#ifdef TCG_TARGET_WORDS_BIGENDIAN
360
        ts->mem_offset = offset;
361
#else
362
        ts->mem_offset = offset + 4;
363
#endif
364
        pstrcpy(buf, sizeof(buf), name);
365
        pstrcat(buf, sizeof(buf), "_1");
366
        ts->name = strdup(buf);
367

    
368
        s->nb_globals += 2;
369
    } else
370
#endif
371
    {
372
        tcg_temp_alloc(s, s->nb_globals + 1);
373
        ts = &s->temps[s->nb_globals];
374
        ts->base_type = type;
375
        ts->type = type;
376
        ts->fixed_reg = 0;
377
        ts->mem_allocated = 1;
378
        ts->mem_reg = reg;
379
        ts->mem_offset = offset;
380
        ts->name = name;
381
        s->nb_globals++;
382
    }
383
    return idx;
384
}
385

    
386
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
387
                                const char *name)
388
{
389
    int idx;
390

    
391
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
392
    return MAKE_TCGV_I32(idx);
393
}
394

    
395
TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
396
                                const char *name)
397
{
398
    int idx;
399

    
400
    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
401
    return MAKE_TCGV_I64(idx);
402
}
403

    
404
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
405
{
406
    TCGContext *s = &tcg_ctx;
407
    TCGTemp *ts;
408
    int idx, k;
409

    
410
    k = type;
411
    if (temp_local)
412
        k += TCG_TYPE_COUNT;
413
    idx = s->first_free_temp[k];
414
    if (idx != -1) {
415
        /* There is already an available temp with the
416
           right type */
417
        ts = &s->temps[idx];
418
        s->first_free_temp[k] = ts->next_free_temp;
419
        ts->temp_allocated = 1;
420
        assert(ts->temp_local == temp_local);
421
    } else {
422
        idx = s->nb_temps;
423
#if TCG_TARGET_REG_BITS == 32
424
        if (type == TCG_TYPE_I64) {
425
            tcg_temp_alloc(s, s->nb_temps + 2);
426
            ts = &s->temps[s->nb_temps];
427
            ts->base_type = type;
428
            ts->type = TCG_TYPE_I32;
429
            ts->temp_allocated = 1;
430
            ts->temp_local = temp_local;
431
            ts->name = NULL;
432
            ts++;
433
            ts->base_type = TCG_TYPE_I32;
434
            ts->type = TCG_TYPE_I32;
435
            ts->temp_allocated = 1;
436
            ts->temp_local = temp_local;
437
            ts->name = NULL;
438
            s->nb_temps += 2;
439
        } else
440
#endif
441
        {
442
            tcg_temp_alloc(s, s->nb_temps + 1);
443
            ts = &s->temps[s->nb_temps];
444
            ts->base_type = type;
445
            ts->type = type;
446
            ts->temp_allocated = 1;
447
            ts->temp_local = temp_local;
448
            ts->name = NULL;
449
            s->nb_temps++;
450
        }
451
    }
452

    
453
#if defined(CONFIG_DEBUG_TCG)
454
    s->temps_in_use++;
455
#endif
456
    return idx;
457
}
458

    
459
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
460
{
461
    int idx;
462

    
463
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
464
    return MAKE_TCGV_I32(idx);
465
}
466

    
467
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
468
{
469
    int idx;
470

    
471
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
472
    return MAKE_TCGV_I64(idx);
473
}
474

    
475
static inline void tcg_temp_free_internal(int idx)
476
{
477
    TCGContext *s = &tcg_ctx;
478
    TCGTemp *ts;
479
    int k;
480

    
481
#if defined(CONFIG_DEBUG_TCG)
482
    s->temps_in_use--;
483
    if (s->temps_in_use < 0) {
484
        fprintf(stderr, "More temporaries freed than allocated!\n");
485
    }
486
#endif
487

    
488
    assert(idx >= s->nb_globals && idx < s->nb_temps);
489
    ts = &s->temps[idx];
490
    assert(ts->temp_allocated != 0);
491
    ts->temp_allocated = 0;
492
    k = ts->base_type;
493
    if (ts->temp_local)
494
        k += TCG_TYPE_COUNT;
495
    ts->next_free_temp = s->first_free_temp[k];
496
    s->first_free_temp[k] = idx;
497
}
498

    
499
void tcg_temp_free_i32(TCGv_i32 arg)
500
{
501
    tcg_temp_free_internal(GET_TCGV_I32(arg));
502
}
503

    
504
void tcg_temp_free_i64(TCGv_i64 arg)
505
{
506
    tcg_temp_free_internal(GET_TCGV_I64(arg));
507
}
508

    
509
TCGv_i32 tcg_const_i32(int32_t val)
510
{
511
    TCGv_i32 t0;
512
    t0 = tcg_temp_new_i32();
513
    tcg_gen_movi_i32(t0, val);
514
    return t0;
515
}
516

    
517
TCGv_i64 tcg_const_i64(int64_t val)
518
{
519
    TCGv_i64 t0;
520
    t0 = tcg_temp_new_i64();
521
    tcg_gen_movi_i64(t0, val);
522
    return t0;
523
}
524

    
525
TCGv_i32 tcg_const_local_i32(int32_t val)
526
{
527
    TCGv_i32 t0;
528
    t0 = tcg_temp_local_new_i32();
529
    tcg_gen_movi_i32(t0, val);
530
    return t0;
531
}
532

    
533
TCGv_i64 tcg_const_local_i64(int64_t val)
534
{
535
    TCGv_i64 t0;
536
    t0 = tcg_temp_local_new_i64();
537
    tcg_gen_movi_i64(t0, val);
538
    return t0;
539
}
540

    
541
#if defined(CONFIG_DEBUG_TCG)
542
void tcg_clear_temp_count(void)
543
{
544
    TCGContext *s = &tcg_ctx;
545
    s->temps_in_use = 0;
546
}
547

    
548
int tcg_check_temp_count(void)
549
{
550
    TCGContext *s = &tcg_ctx;
551
    if (s->temps_in_use) {
552
        /* Clear the count so that we don't give another
553
         * warning immediately next time around.
554
         */
555
        s->temps_in_use = 0;
556
        return 1;
557
    }
558
    return 0;
559
}
560
#endif
561

    
562
void tcg_register_helper(void *func, const char *name)
563
{
564
    TCGContext *s = &tcg_ctx;
565
    int n;
566
    if ((s->nb_helpers + 1) > s->allocated_helpers) {
567
        n = s->allocated_helpers;
568
        if (n == 0) {
569
            n = 4;
570
        } else {
571
            n *= 2;
572
        }
573
        s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
574
        s->allocated_helpers = n;
575
    }
576
    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
577
    s->helpers[s->nb_helpers].name = name;
578
    s->nb_helpers++;
579
}
580

    
581
/* Note: we convert the 64 bit args to 32 bit and do some alignment
582
   and endian swap. Maybe it would be better to do the alignment
583
   and endian swap in tcg_reg_alloc_call(). */
584
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
585
                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
586
{
587
#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
588
    int call_type;
589
#endif
590
    int i;
591
    int real_args;
592
    int nb_rets;
593
    TCGArg *nparam;
594

    
595
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
596
    for (i = 0; i < nargs; ++i) {
597
        int is_64bit = sizemask & (1 << (i+1)*2);
598
        int is_signed = sizemask & (2 << (i+1)*2);
599
        if (!is_64bit) {
600
            TCGv_i64 temp = tcg_temp_new_i64();
601
            TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
602
            if (is_signed) {
603
                tcg_gen_ext32s_i64(temp, orig);
604
            } else {
605
                tcg_gen_ext32u_i64(temp, orig);
606
            }
607
            args[i] = GET_TCGV_I64(temp);
608
        }
609
    }
610
#endif /* TCG_TARGET_EXTEND_ARGS */
611

    
612
    *gen_opc_ptr++ = INDEX_op_call;
613
    nparam = gen_opparam_ptr++;
614
#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
615
    call_type = (flags & TCG_CALL_TYPE_MASK);
616
#endif
617
    if (ret != TCG_CALL_DUMMY_ARG) {
618
#if TCG_TARGET_REG_BITS < 64
619
        if (sizemask & 1) {
620
#ifdef TCG_TARGET_WORDS_BIGENDIAN
621
            *gen_opparam_ptr++ = ret + 1;
622
            *gen_opparam_ptr++ = ret;
623
#else
624
            *gen_opparam_ptr++ = ret;
625
            *gen_opparam_ptr++ = ret + 1;
626
#endif
627
            nb_rets = 2;
628
        } else
629
#endif
630
        {
631
            *gen_opparam_ptr++ = ret;
632
            nb_rets = 1;
633
        }
634
    } else {
635
        nb_rets = 0;
636
    }
637
    real_args = 0;
638
    for (i = 0; i < nargs; i++) {
639
#if TCG_TARGET_REG_BITS < 64
640
        int is_64bit = sizemask & (1 << (i+1)*2);
641
        if (is_64bit) {
642
#ifdef TCG_TARGET_I386
643
            /* REGPARM case: if the third parameter is 64 bit, it is
644
               allocated on the stack */
645
            if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
646
                call_type = TCG_CALL_TYPE_REGPARM_2;
647
                flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
648
            }
649
#endif
650
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
651
            /* some targets want aligned 64 bit args */
652
            if (real_args & 1) {
653
                *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
654
                real_args++;
655
            }
656
#endif
657
            /* If stack grows up, then we will be placing successive
658
               arguments at lower addresses, which means we need to
659
               reverse the order compared to how we would normally
660
               treat either big or little-endian.  For those arguments
661
               that will wind up in registers, this still works for
662
               HPPA (the only current STACK_GROWSUP target) since the
663
               argument registers are *also* allocated in decreasing
664
               order.  If another such target is added, this logic may
665
               have to get more complicated to differentiate between
666
               stack arguments and register arguments.  */
667
#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
668
            *gen_opparam_ptr++ = args[i] + 1;
669
            *gen_opparam_ptr++ = args[i];
670
#else
671
            *gen_opparam_ptr++ = args[i];
672
            *gen_opparam_ptr++ = args[i] + 1;
673
#endif
674
            real_args += 2;
675
            continue;
676
        }
677
#endif /* TCG_TARGET_REG_BITS < 64 */
678

    
679
        *gen_opparam_ptr++ = args[i];
680
        real_args++;
681
    }
682
    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
683

    
684
    *gen_opparam_ptr++ = flags;
685

    
686
    *nparam = (nb_rets << 16) | (real_args + 1);
687

    
688
    /* total parameters, needed to go backward in the instruction stream */
689
    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
690

    
691
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
692
    for (i = 0; i < nargs; ++i) {
693
        int is_64bit = sizemask & (1 << (i+1)*2);
694
        if (!is_64bit) {
695
            TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
696
            tcg_temp_free_i64(temp);
697
        }
698
    }
699
#endif /* TCG_TARGET_EXTEND_ARGS */
700
}
701

    
702
#if TCG_TARGET_REG_BITS == 32
703
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
704
                        int c, int right, int arith)
705
{
706
    if (c == 0) {
707
        tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
708
        tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
709
    } else if (c >= 32) {
710
        c -= 32;
711
        if (right) {
712
            if (arith) {
713
                tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
714
                tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
715
            } else {
716
                tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
717
                tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
718
            }
719
        } else {
720
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
721
            tcg_gen_movi_i32(TCGV_LOW(ret), 0);
722
        }
723
    } else {
724
        TCGv_i32 t0, t1;
725

    
726
        t0 = tcg_temp_new_i32();
727
        t1 = tcg_temp_new_i32();
728
        if (right) {
729
            tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
730
            if (arith)
731
                tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
732
            else
733
                tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
734
            tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
735
            tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
736
            tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
737
        } else {
738
            tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
739
            /* Note: ret can be the same as arg1, so we use t1 */
740
            tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
741
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
742
            tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
743
            tcg_gen_mov_i32(TCGV_LOW(ret), t1);
744
        }
745
        tcg_temp_free_i32(t0);
746
        tcg_temp_free_i32(t1);
747
    }
748
}
749
#endif
750

    
751

    
752
static void tcg_reg_alloc_start(TCGContext *s)
753
{
754
    int i;
755
    TCGTemp *ts;
756
    for(i = 0; i < s->nb_globals; i++) {
757
        ts = &s->temps[i];
758
        if (ts->fixed_reg) {
759
            ts->val_type = TEMP_VAL_REG;
760
        } else {
761
            ts->val_type = TEMP_VAL_MEM;
762
        }
763
    }
764
    for(i = s->nb_globals; i < s->nb_temps; i++) {
765
        ts = &s->temps[i];
766
        ts->val_type = TEMP_VAL_DEAD;
767
        ts->mem_allocated = 0;
768
        ts->fixed_reg = 0;
769
    }
770
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
771
        s->reg_to_temp[i] = -1;
772
    }
773
}
774

    
775
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
776
                                 int idx)
777
{
778
    TCGTemp *ts;
779

    
780
    ts = &s->temps[idx];
781
    if (idx < s->nb_globals) {
782
        pstrcpy(buf, buf_size, ts->name);
783
    } else {
784
        if (ts->temp_local) 
785
            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
786
        else
787
            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
788
    }
789
    return buf;
790
}
791

    
792
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
793
{
794
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
795
}
796

    
797
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
798
{
799
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
800
}
801

    
802
static int helper_cmp(const void *p1, const void *p2)
803
{
804
    const TCGHelperInfo *th1 = p1;
805
    const TCGHelperInfo *th2 = p2;
806
    if (th1->func < th2->func)
807
        return -1;
808
    else if (th1->func == th2->func)
809
        return 0;
810
    else
811
        return 1;
812
}
813

    
814
/* find helper definition (Note: A hash table would be better) */
815
static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
816
{
817
    int m, m_min, m_max;
818
    TCGHelperInfo *th;
819
    tcg_target_ulong v;
820

    
821
    if (unlikely(!s->helpers_sorted)) {
822
        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
823
              helper_cmp);
824
        s->helpers_sorted = 1;
825
    }
826

    
827
    /* binary search */
828
    m_min = 0;
829
    m_max = s->nb_helpers - 1;
830
    while (m_min <= m_max) {
831
        m = (m_min + m_max) >> 1;
832
        th = &s->helpers[m];
833
        v = th->func;
834
        if (v == val)
835
            return th;
836
        else if (val < v) {
837
            m_max = m - 1;
838
        } else {
839
            m_min = m + 1;
840
        }
841
    }
842
    return NULL;
843
}
844

    
845
static const char * const cond_name[] =
846
{
847
    [TCG_COND_EQ] = "eq",
848
    [TCG_COND_NE] = "ne",
849
    [TCG_COND_LT] = "lt",
850
    [TCG_COND_GE] = "ge",
851
    [TCG_COND_LE] = "le",
852
    [TCG_COND_GT] = "gt",
853
    [TCG_COND_LTU] = "ltu",
854
    [TCG_COND_GEU] = "geu",
855
    [TCG_COND_LEU] = "leu",
856
    [TCG_COND_GTU] = "gtu"
857
};
858

    
859
void tcg_dump_ops(TCGContext *s, FILE *outfile)
860
{
861
    const uint16_t *opc_ptr;
862
    const TCGArg *args;
863
    TCGArg arg;
864
    TCGOpcode c;
865
    int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
866
    const TCGOpDef *def;
867
    char buf[128];
868

    
869
    first_insn = 1;
870
    opc_ptr = gen_opc_buf;
871
    args = gen_opparam_buf;
872
    while (opc_ptr < gen_opc_ptr) {
873
        c = *opc_ptr++;
874
        def = &tcg_op_defs[c];
875
        if (c == INDEX_op_debug_insn_start) {
876
            uint64_t pc;
877
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
878
            pc = ((uint64_t)args[1] << 32) | args[0];
879
#else
880
            pc = args[0];
881
#endif
882
            if (!first_insn) 
883
                fprintf(outfile, "\n");
884
            fprintf(outfile, " ---- 0x%" PRIx64, pc);
885
            first_insn = 0;
886
            nb_oargs = def->nb_oargs;
887
            nb_iargs = def->nb_iargs;
888
            nb_cargs = def->nb_cargs;
889
        } else if (c == INDEX_op_call) {
890
            TCGArg arg;
891

    
892
            /* variable number of arguments */
893
            arg = *args++;
894
            nb_oargs = arg >> 16;
895
            nb_iargs = arg & 0xffff;
896
            nb_cargs = def->nb_cargs;
897

    
898
            fprintf(outfile, " %s ", def->name);
899

    
900
            /* function name */
901
            fprintf(outfile, "%s",
902
                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
903
            /* flags */
904
            fprintf(outfile, ",$0x%" TCG_PRIlx,
905
                    args[nb_oargs + nb_iargs]);
906
            /* nb out args */
907
            fprintf(outfile, ",$%d", nb_oargs);
908
            for(i = 0; i < nb_oargs; i++) {
909
                fprintf(outfile, ",");
910
                fprintf(outfile, "%s",
911
                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
912
            }
913
            for(i = 0; i < (nb_iargs - 1); i++) {
914
                fprintf(outfile, ",");
915
                if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
916
                    fprintf(outfile, "<dummy>");
917
                } else {
918
                    fprintf(outfile, "%s",
919
                            tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
920
                }
921
            }
922
        } else if (c == INDEX_op_movi_i32 
923
#if TCG_TARGET_REG_BITS == 64
924
                   || c == INDEX_op_movi_i64
925
#endif
926
                   ) {
927
            tcg_target_ulong val;
928
            TCGHelperInfo *th;
929

    
930
            nb_oargs = def->nb_oargs;
931
            nb_iargs = def->nb_iargs;
932
            nb_cargs = def->nb_cargs;
933
            fprintf(outfile, " %s %s,$", def->name, 
934
                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
935
            val = args[1];
936
            th = tcg_find_helper(s, val);
937
            if (th) {
938
                fprintf(outfile, "%s", th->name);
939
            } else {
940
                if (c == INDEX_op_movi_i32)
941
                    fprintf(outfile, "0x%x", (uint32_t)val);
942
                else
943
                    fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
944
            }
945
        } else {
946
            fprintf(outfile, " %s ", def->name);
947
            if (c == INDEX_op_nopn) {
948
                /* variable number of arguments */
949
                nb_cargs = *args;
950
                nb_oargs = 0;
951
                nb_iargs = 0;
952
            } else {
953
                nb_oargs = def->nb_oargs;
954
                nb_iargs = def->nb_iargs;
955
                nb_cargs = def->nb_cargs;
956
            }
957
            
958
            k = 0;
959
            for(i = 0; i < nb_oargs; i++) {
960
                if (k != 0)
961
                    fprintf(outfile, ",");
962
                fprintf(outfile, "%s",
963
                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
964
            }
965
            for(i = 0; i < nb_iargs; i++) {
966
                if (k != 0)
967
                    fprintf(outfile, ",");
968
                fprintf(outfile, "%s",
969
                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
970
            }
971
            switch (c) {
972
            case INDEX_op_brcond_i32:
973
#if TCG_TARGET_REG_BITS == 32
974
            case INDEX_op_brcond2_i32:
975
#elif TCG_TARGET_REG_BITS == 64
976
            case INDEX_op_brcond_i64:
977
#endif
978
            case INDEX_op_setcond_i32:
979
#if TCG_TARGET_REG_BITS == 32
980
            case INDEX_op_setcond2_i32:
981
#elif TCG_TARGET_REG_BITS == 64
982
            case INDEX_op_setcond_i64:
983
#endif
984
                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
985
                    fprintf(outfile, ",%s", cond_name[args[k++]]);
986
                else
987
                    fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
988
                i = 1;
989
                break;
990
            default:
991
                i = 0;
992
                break;
993
            }
994
            for(; i < nb_cargs; i++) {
995
                if (k != 0)
996
                    fprintf(outfile, ",");
997
                arg = args[k++];
998
                fprintf(outfile, "$0x%" TCG_PRIlx, arg);
999
            }
1000
        }
1001
        fprintf(outfile, "\n");
1002
        args += nb_iargs + nb_oargs + nb_cargs;
1003
    }
1004
}
1005

    
1006
/* we give more priority to constraints with less registers */
1007
static int get_constraint_priority(const TCGOpDef *def, int k)
1008
{
1009
    const TCGArgConstraint *arg_ct;
1010

    
1011
    int i, n;
1012
    arg_ct = &def->args_ct[k];
1013
    if (arg_ct->ct & TCG_CT_ALIAS) {
1014
        /* an alias is equivalent to a single register */
1015
        n = 1;
1016
    } else {
1017
        if (!(arg_ct->ct & TCG_CT_REG))
1018
            return 0;
1019
        n = 0;
1020
        for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1021
            if (tcg_regset_test_reg(arg_ct->u.regs, i))
1022
                n++;
1023
        }
1024
    }
1025
    return TCG_TARGET_NB_REGS - n + 1;
1026
}
1027

    
1028
/* sort from highest priority to lowest */
1029
static void sort_constraints(TCGOpDef *def, int start, int n)
1030
{
1031
    int i, j, p1, p2, tmp;
1032

    
1033
    for(i = 0; i < n; i++)
1034
        def->sorted_args[start + i] = start + i;
1035
    if (n <= 1)
1036
        return;
1037
    for(i = 0; i < n - 1; i++) {
1038
        for(j = i + 1; j < n; j++) {
1039
            p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1040
            p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1041
            if (p1 < p2) {
1042
                tmp = def->sorted_args[start + i];
1043
                def->sorted_args[start + i] = def->sorted_args[start + j];
1044
                def->sorted_args[start + j] = tmp;
1045
            }
1046
        }
1047
    }
1048
}
1049

    
1050
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1051
{
1052
    TCGOpcode op;
1053
    TCGOpDef *def;
1054
    const char *ct_str;
1055
    int i, nb_args;
1056

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

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

    
1110
        /* sort the constraints (XXX: this is just an heuristic) */
1111
        sort_constraints(def, 0, def->nb_oargs);
1112
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1113

    
1114
#if 0
1115
        {
1116
            int i;
1117

1118
            printf("%s: sorted=", def->name);
1119
            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1120
                printf(" %d", def->sorted_args[i]);
1121
            printf("\n");
1122
        }
1123
#endif
1124
        tdefs++;
1125
    }
1126

    
1127
#if defined(CONFIG_DEBUG_TCG)
1128
    i = 0;
1129
    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1130
        if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
1131
            /* Wrong entry in op definitions? */
1132
            if (tcg_op_defs[op].used) {
1133
                fprintf(stderr, "Invalid op definition for %s\n",
1134
                        tcg_op_defs[op].name);
1135
                i = 1;
1136
            }
1137
        } else {
1138
            /* Missing entry in op definitions? */
1139
            if (!tcg_op_defs[op].used) {
1140
                fprintf(stderr, "Missing op definition for %s\n",
1141
                        tcg_op_defs[op].name);
1142
                i = 1;
1143
            }
1144
        }
1145
    }
1146
    if (i == 1) {
1147
        tcg_abort();
1148
    }
1149
#endif
1150
}
1151

    
1152
#ifdef USE_LIVENESS_ANALYSIS
1153

    
1154
/* set a nop for an operation using 'nb_args' */
1155
static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
1156
                               TCGArg *args, int nb_args)
1157
{
1158
    if (nb_args == 0) {
1159
        *opc_ptr = INDEX_op_nop;
1160
    } else {
1161
        *opc_ptr = INDEX_op_nopn;
1162
        args[0] = nb_args;
1163
        args[nb_args - 1] = nb_args;
1164
    }
1165
}
1166

    
1167
/* liveness analysis: end of function: globals are live, temps are
1168
   dead. */
1169
/* XXX: at this stage, not used as there would be little gains because
1170
   most TBs end with a conditional jump. */
1171
static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
1172
{
1173
    memset(dead_temps, 0, s->nb_globals);
1174
    memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
1175
}
1176

    
1177
/* liveness analysis: end of basic block: globals are live, temps are
1178
   dead, local temps are live. */
1179
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1180
{
1181
    int i;
1182
    TCGTemp *ts;
1183

    
1184
    memset(dead_temps, 0, s->nb_globals);
1185
    ts = &s->temps[s->nb_globals];
1186
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1187
        if (ts->temp_local)
1188
            dead_temps[i] = 0;
1189
        else
1190
            dead_temps[i] = 1;
1191
        ts++;
1192
    }
1193
}
1194

    
1195
/* Liveness analysis : update the opc_dead_args array to tell if a
1196
   given input arguments is dead. Instructions updating dead
1197
   temporaries are removed. */
1198
static void tcg_liveness_analysis(TCGContext *s)
1199
{
1200
    int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1201
    TCGOpcode op;
1202
    TCGArg *args;
1203
    const TCGOpDef *def;
1204
    uint8_t *dead_temps;
1205
    unsigned int dead_args;
1206
    
1207
    gen_opc_ptr++; /* skip end */
1208

    
1209
    nb_ops = gen_opc_ptr - gen_opc_buf;
1210

    
1211
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1212
    
1213
    dead_temps = tcg_malloc(s->nb_temps);
1214
    memset(dead_temps, 1, s->nb_temps);
1215

    
1216
    args = gen_opparam_ptr;
1217
    op_index = nb_ops - 1;
1218
    while (op_index >= 0) {
1219
        op = gen_opc_buf[op_index];
1220
        def = &tcg_op_defs[op];
1221
        switch(op) {
1222
        case INDEX_op_call:
1223
            {
1224
                int call_flags;
1225

    
1226
                nb_args = args[-1];
1227
                args -= nb_args;
1228
                nb_iargs = args[0] & 0xffff;
1229
                nb_oargs = args[0] >> 16;
1230
                args++;
1231
                call_flags = args[nb_oargs + nb_iargs];
1232

    
1233
                /* pure functions can be removed if their result is not
1234
                   used */
1235
                if (call_flags & TCG_CALL_PURE) {
1236
                    for(i = 0; i < nb_oargs; i++) {
1237
                        arg = args[i];
1238
                        if (!dead_temps[arg])
1239
                            goto do_not_remove_call;
1240
                    }
1241
                    tcg_set_nop(s, gen_opc_buf + op_index, 
1242
                                args - 1, nb_args);
1243
                } else {
1244
                do_not_remove_call:
1245

    
1246
                    /* output args are dead */
1247
                    dead_args = 0;
1248
                    for(i = 0; i < nb_oargs; i++) {
1249
                        arg = args[i];
1250
                        if (dead_temps[arg]) {
1251
                            dead_args |= (1 << i);
1252
                        }
1253
                        dead_temps[arg] = 1;
1254
                    }
1255
                    
1256
                    if (!(call_flags & TCG_CALL_CONST)) {
1257
                        /* globals are live (they may be used by the call) */
1258
                        memset(dead_temps, 0, s->nb_globals);
1259
                    }
1260

    
1261
                    /* input args are live */
1262
                    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1263
                        arg = args[i];
1264
                        if (arg != TCG_CALL_DUMMY_ARG) {
1265
                            if (dead_temps[arg]) {
1266
                                dead_args |= (1 << i);
1267
                            }
1268
                            dead_temps[arg] = 0;
1269
                        }
1270
                    }
1271
                    s->op_dead_args[op_index] = dead_args;
1272
                }
1273
                args--;
1274
            }
1275
            break;
1276
        case INDEX_op_set_label:
1277
            args--;
1278
            /* mark end of basic block */
1279
            tcg_la_bb_end(s, dead_temps);
1280
            break;
1281
        case INDEX_op_debug_insn_start:
1282
            args -= def->nb_args;
1283
            break;
1284
        case INDEX_op_nopn:
1285
            nb_args = args[-1];
1286
            args -= nb_args;
1287
            break;
1288
        case INDEX_op_discard:
1289
            args--;
1290
            /* mark the temporary as dead */
1291
            dead_temps[args[0]] = 1;
1292
            break;
1293
        case INDEX_op_end:
1294
            break;
1295
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1296
        default:
1297
            args -= def->nb_args;
1298
            nb_iargs = def->nb_iargs;
1299
            nb_oargs = def->nb_oargs;
1300

    
1301
            /* Test if the operation can be removed because all
1302
               its outputs are dead. We assume that nb_oargs == 0
1303
               implies side effects */
1304
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1305
                for(i = 0; i < nb_oargs; i++) {
1306
                    arg = args[i];
1307
                    if (!dead_temps[arg])
1308
                        goto do_not_remove;
1309
                }
1310
                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1311
#ifdef CONFIG_PROFILER
1312
                s->del_op_count++;
1313
#endif
1314
            } else {
1315
            do_not_remove:
1316

    
1317
                /* output args are dead */
1318
                dead_args = 0;
1319
                for(i = 0; i < nb_oargs; i++) {
1320
                    arg = args[i];
1321
                    if (dead_temps[arg]) {
1322
                        dead_args |= (1 << i);
1323
                    }
1324
                    dead_temps[arg] = 1;
1325
                }
1326

    
1327
                /* if end of basic block, update */
1328
                if (def->flags & TCG_OPF_BB_END) {
1329
                    tcg_la_bb_end(s, dead_temps);
1330
                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1331
                    /* globals are live */
1332
                    memset(dead_temps, 0, s->nb_globals);
1333
                }
1334

    
1335
                /* input args are live */
1336
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1337
                    arg = args[i];
1338
                    if (dead_temps[arg]) {
1339
                        dead_args |= (1 << i);
1340
                    }
1341
                    dead_temps[arg] = 0;
1342
                }
1343
                s->op_dead_args[op_index] = dead_args;
1344
            }
1345
            break;
1346
        }
1347
        op_index--;
1348
    }
1349

    
1350
    if (args != gen_opparam_buf)
1351
        tcg_abort();
1352
}
1353
#else
1354
/* dummy liveness analysis */
1355
static void tcg_liveness_analysis(TCGContext *s)
1356
{
1357
    int nb_ops;
1358
    nb_ops = gen_opc_ptr - gen_opc_buf;
1359

    
1360
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1361
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1362
}
1363
#endif
1364

    
1365
#ifndef NDEBUG
1366
static void dump_regs(TCGContext *s)
1367
{
1368
    TCGTemp *ts;
1369
    int i;
1370
    char buf[64];
1371

    
1372
    for(i = 0; i < s->nb_temps; i++) {
1373
        ts = &s->temps[i];
1374
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1375
        switch(ts->val_type) {
1376
        case TEMP_VAL_REG:
1377
            printf("%s", tcg_target_reg_names[ts->reg]);
1378
            break;
1379
        case TEMP_VAL_MEM:
1380
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1381
            break;
1382
        case TEMP_VAL_CONST:
1383
            printf("$0x%" TCG_PRIlx, ts->val);
1384
            break;
1385
        case TEMP_VAL_DEAD:
1386
            printf("D");
1387
            break;
1388
        default:
1389
            printf("???");
1390
            break;
1391
        }
1392
        printf("\n");
1393
    }
1394

    
1395
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1396
        if (s->reg_to_temp[i] >= 0) {
1397
            printf("%s: %s\n", 
1398
                   tcg_target_reg_names[i], 
1399
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1400
        }
1401
    }
1402
}
1403

    
1404
static void check_regs(TCGContext *s)
1405
{
1406
    int reg, k;
1407
    TCGTemp *ts;
1408
    char buf[64];
1409

    
1410
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1411
        k = s->reg_to_temp[reg];
1412
        if (k >= 0) {
1413
            ts = &s->temps[k];
1414
            if (ts->val_type != TEMP_VAL_REG ||
1415
                ts->reg != reg) {
1416
                printf("Inconsistency for register %s:\n", 
1417
                       tcg_target_reg_names[reg]);
1418
                goto fail;
1419
            }
1420
        }
1421
    }
1422
    for(k = 0; k < s->nb_temps; k++) {
1423
        ts = &s->temps[k];
1424
        if (ts->val_type == TEMP_VAL_REG &&
1425
            !ts->fixed_reg &&
1426
            s->reg_to_temp[ts->reg] != k) {
1427
                printf("Inconsistency for temp %s:\n", 
1428
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1429
        fail:
1430
                printf("reg state:\n");
1431
                dump_regs(s);
1432
                tcg_abort();
1433
        }
1434
    }
1435
}
1436
#endif
1437

    
1438
static void temp_allocate_frame(TCGContext *s, int temp)
1439
{
1440
    TCGTemp *ts;
1441
    ts = &s->temps[temp];
1442
#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
1443
    s->current_frame_offset = (s->current_frame_offset +
1444
                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
1445
        ~(sizeof(tcg_target_long) - 1);
1446
#endif
1447
    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1448
        s->frame_end) {
1449
        tcg_abort();
1450
    }
1451
    ts->mem_offset = s->current_frame_offset;
1452
    ts->mem_reg = s->frame_reg;
1453
    ts->mem_allocated = 1;
1454
    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1455
}
1456

    
1457
/* free register 'reg' by spilling the corresponding temporary if necessary */
1458
static void tcg_reg_free(TCGContext *s, int reg)
1459
{
1460
    TCGTemp *ts;
1461
    int temp;
1462

    
1463
    temp = s->reg_to_temp[reg];
1464
    if (temp != -1) {
1465
        ts = &s->temps[temp];
1466
        assert(ts->val_type == TEMP_VAL_REG);
1467
        if (!ts->mem_coherent) {
1468
            if (!ts->mem_allocated) 
1469
                temp_allocate_frame(s, temp);
1470
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1471
        }
1472
        ts->val_type = TEMP_VAL_MEM;
1473
        s->reg_to_temp[reg] = -1;
1474
    }
1475
}
1476

    
1477
/* Allocate a register belonging to reg1 & ~reg2 */
1478
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1479
{
1480
    int i, reg;
1481
    TCGRegSet reg_ct;
1482

    
1483
    tcg_regset_andnot(reg_ct, reg1, reg2);
1484

    
1485
    /* first try free registers */
1486
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1487
        reg = tcg_target_reg_alloc_order[i];
1488
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1489
            return reg;
1490
    }
1491

    
1492
    /* XXX: do better spill choice */
1493
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1494
        reg = tcg_target_reg_alloc_order[i];
1495
        if (tcg_regset_test_reg(reg_ct, reg)) {
1496
            tcg_reg_free(s, reg);
1497
            return reg;
1498
        }
1499
    }
1500

    
1501
    tcg_abort();
1502
}
1503

    
1504
/* save a temporary to memory. 'allocated_regs' is used in case a
1505
   temporary registers needs to be allocated to store a constant. */
1506
static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1507
{
1508
    TCGTemp *ts;
1509
    int reg;
1510

    
1511
    ts = &s->temps[temp];
1512
    if (!ts->fixed_reg) {
1513
        switch(ts->val_type) {
1514
        case TEMP_VAL_REG:
1515
            tcg_reg_free(s, ts->reg);
1516
            break;
1517
        case TEMP_VAL_DEAD:
1518
            ts->val_type = TEMP_VAL_MEM;
1519
            break;
1520
        case TEMP_VAL_CONST:
1521
            reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1522
                                allocated_regs);
1523
            if (!ts->mem_allocated) 
1524
                temp_allocate_frame(s, temp);
1525
            tcg_out_movi(s, ts->type, reg, ts->val);
1526
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1527
            ts->val_type = TEMP_VAL_MEM;
1528
            break;
1529
        case TEMP_VAL_MEM:
1530
            break;
1531
        default:
1532
            tcg_abort();
1533
        }
1534
    }
1535
}
1536

    
1537
/* save globals to their cannonical location and assume they can be
1538
   modified be the following code. 'allocated_regs' is used in case a
1539
   temporary registers needs to be allocated to store a constant. */
1540
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1541
{
1542
    int i;
1543

    
1544
    for(i = 0; i < s->nb_globals; i++) {
1545
        temp_save(s, i, allocated_regs);
1546
    }
1547
}
1548

    
1549
/* at the end of a basic block, we assume all temporaries are dead and
1550
   all globals are stored at their canonical location. */
1551
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1552
{
1553
    TCGTemp *ts;
1554
    int i;
1555

    
1556
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1557
        ts = &s->temps[i];
1558
        if (ts->temp_local) {
1559
            temp_save(s, i, allocated_regs);
1560
        } else {
1561
            if (ts->val_type == TEMP_VAL_REG) {
1562
                s->reg_to_temp[ts->reg] = -1;
1563
            }
1564
            ts->val_type = TEMP_VAL_DEAD;
1565
        }
1566
    }
1567

    
1568
    save_globals(s, allocated_regs);
1569
}
1570

    
1571
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1572

    
1573
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1574
{
1575
    TCGTemp *ots;
1576
    tcg_target_ulong val;
1577

    
1578
    ots = &s->temps[args[0]];
1579
    val = args[1];
1580

    
1581
    if (ots->fixed_reg) {
1582
        /* for fixed registers, we do not do any constant
1583
           propagation */
1584
        tcg_out_movi(s, ots->type, ots->reg, val);
1585
    } else {
1586
        /* The movi is not explicitly generated here */
1587
        if (ots->val_type == TEMP_VAL_REG)
1588
            s->reg_to_temp[ots->reg] = -1;
1589
        ots->val_type = TEMP_VAL_CONST;
1590
        ots->val = val;
1591
    }
1592
}
1593

    
1594
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1595
                              const TCGArg *args,
1596
                              unsigned int dead_args)
1597
{
1598
    TCGTemp *ts, *ots;
1599
    int reg;
1600
    const TCGArgConstraint *arg_ct;
1601

    
1602
    ots = &s->temps[args[0]];
1603
    ts = &s->temps[args[1]];
1604
    arg_ct = &def->args_ct[0];
1605

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

    
1653
static void tcg_reg_alloc_op(TCGContext *s, 
1654
                             const TCGOpDef *def, TCGOpcode opc,
1655
                             const TCGArg *args,
1656
                             unsigned int dead_args)
1657
{
1658
    TCGRegSet allocated_regs;
1659
    int i, k, nb_iargs, nb_oargs, reg;
1660
    TCGArg arg;
1661
    const TCGArgConstraint *arg_ct;
1662
    TCGTemp *ts;
1663
    TCGArg new_args[TCG_MAX_OP_ARGS];
1664
    int const_args[TCG_MAX_OP_ARGS];
1665

    
1666
    nb_oargs = def->nb_oargs;
1667
    nb_iargs = def->nb_iargs;
1668

    
1669
    /* copy constants */
1670
    memcpy(new_args + nb_oargs + nb_iargs, 
1671
           args + nb_oargs + nb_iargs, 
1672
           sizeof(TCGArg) * def->nb_cargs);
1673

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

    
1806
    /* emit instruction */
1807
    tcg_out_op(s, opc, new_args, const_args);
1808
    
1809
    /* move the outputs in the correct register if needed */
1810
    for(i = 0; i < nb_oargs; i++) {
1811
        ts = &s->temps[args[i]];
1812
        reg = new_args[i];
1813
        if (ts->fixed_reg && ts->reg != reg) {
1814
            tcg_out_mov(s, ts->type, ts->reg, reg);
1815
        }
1816
    }
1817
}
1818

    
1819
#ifdef TCG_TARGET_STACK_GROWSUP
1820
#define STACK_DIR(x) (-(x))
1821
#else
1822
#define STACK_DIR(x) (x)
1823
#endif
1824

    
1825
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1826
                              TCGOpcode opc, const TCGArg *args,
1827
                              unsigned int dead_args)
1828
{
1829
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1830
    TCGArg arg, func_arg;
1831
    TCGTemp *ts;
1832
    tcg_target_long stack_offset, call_stack_size, func_addr;
1833
    int const_func_arg, allocate_args;
1834
    TCGRegSet allocated_regs;
1835
    const TCGArgConstraint *arg_ct;
1836

    
1837
    arg = *args++;
1838

    
1839
    nb_oargs = arg >> 16;
1840
    nb_iargs = arg & 0xffff;
1841
    nb_params = nb_iargs - 1;
1842

    
1843
    flags = args[nb_oargs + nb_iargs];
1844

    
1845
    nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1846
    if (nb_regs > nb_params)
1847
        nb_regs = nb_params;
1848

    
1849
    /* assign stack slots first */
1850
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1851
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1852
        ~(TCG_TARGET_STACK_ALIGN - 1);
1853
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1854
    if (allocate_args) {
1855
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1856
           preallocate call stack */
1857
        tcg_abort();
1858
    }
1859

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

    
1975
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
1976

    
1977
    /* assign output registers and emit moves if needed */
1978
    for(i = 0; i < nb_oargs; i++) {
1979
        arg = args[i];
1980
        ts = &s->temps[arg];
1981
        reg = tcg_target_call_oarg_regs[i];
1982
        assert(s->reg_to_temp[reg] == -1);
1983
        if (ts->fixed_reg) {
1984
            if (ts->reg != reg) {
1985
                tcg_out_mov(s, ts->type, ts->reg, reg);
1986
            }
1987
        } else {
1988
            if (ts->val_type == TEMP_VAL_REG)
1989
                s->reg_to_temp[ts->reg] = -1;
1990
            if (IS_DEAD_ARG(i)) {
1991
                ts->val_type = TEMP_VAL_DEAD;
1992
            } else {
1993
                ts->val_type = TEMP_VAL_REG;
1994
                ts->reg = reg;
1995
                ts->mem_coherent = 0;
1996
                s->reg_to_temp[reg] = arg;
1997
            }
1998
        }
1999
    }
2000
    
2001
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2002
}
2003

    
2004
#ifdef CONFIG_PROFILER
2005

    
2006
static int64_t tcg_table_op_count[NB_OPS];
2007

    
2008
static void dump_op_count(void)
2009
{
2010
    int i;
2011
    FILE *f;
2012
    f = fopen("/tmp/op.log", "w");
2013
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2014
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2015
    }
2016
    fclose(f);
2017
}
2018
#endif
2019

    
2020

    
2021
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2022
                                      long search_pc)
2023
{
2024
    TCGOpcode opc;
2025
    int op_index;
2026
    const TCGOpDef *def;
2027
    unsigned int dead_args;
2028
    const TCGArg *args;
2029

    
2030
#ifdef DEBUG_DISAS
2031
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2032
        qemu_log("OP:\n");
2033
        tcg_dump_ops(s, logfile);
2034
        qemu_log("\n");
2035
    }
2036
#endif
2037

    
2038
#ifdef CONFIG_PROFILER
2039
    s->la_time -= profile_getclock();
2040
#endif
2041
    tcg_liveness_analysis(s);
2042
#ifdef CONFIG_PROFILER
2043
    s->la_time += profile_getclock();
2044
#endif
2045

    
2046
#ifdef DEBUG_DISAS
2047
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2048
        qemu_log("OP after liveness analysis:\n");
2049
        tcg_dump_ops(s, logfile);
2050
        qemu_log("\n");
2051
    }
2052
#endif
2053

    
2054
    tcg_reg_alloc_start(s);
2055

    
2056
    s->code_buf = gen_code_buf;
2057
    s->code_ptr = gen_code_buf;
2058

    
2059
    args = gen_opparam_buf;
2060
    op_index = 0;
2061

    
2062
    for(;;) {
2063
        opc = gen_opc_buf[op_index];
2064
#ifdef CONFIG_PROFILER
2065
        tcg_table_op_count[opc]++;
2066
#endif
2067
        def = &tcg_op_defs[opc];
2068
#if 0
2069
        printf("%s: %d %d %d\n", def->name,
2070
               def->nb_oargs, def->nb_iargs, def->nb_cargs);
2071
        //        dump_regs(s);
2072
#endif
2073
        switch(opc) {
2074
        case INDEX_op_mov_i32:
2075
#if TCG_TARGET_REG_BITS == 64
2076
        case INDEX_op_mov_i64:
2077
#endif
2078
            dead_args = s->op_dead_args[op_index];
2079
            tcg_reg_alloc_mov(s, def, args, dead_args);
2080
            break;
2081
        case INDEX_op_movi_i32:
2082
#if TCG_TARGET_REG_BITS == 64
2083
        case INDEX_op_movi_i64:
2084
#endif
2085
            tcg_reg_alloc_movi(s, args);
2086
            break;
2087
        case INDEX_op_debug_insn_start:
2088
            /* debug instruction */
2089
            break;
2090
        case INDEX_op_nop:
2091
        case INDEX_op_nop1:
2092
        case INDEX_op_nop2:
2093
        case INDEX_op_nop3:
2094
            break;
2095
        case INDEX_op_nopn:
2096
            args += args[0];
2097
            goto next;
2098
        case INDEX_op_discard:
2099
            {
2100
                TCGTemp *ts;
2101
                ts = &s->temps[args[0]];
2102
                /* mark the temporary as dead */
2103
                if (!ts->fixed_reg) {
2104
                    if (ts->val_type == TEMP_VAL_REG)
2105
                        s->reg_to_temp[ts->reg] = -1;
2106
                    ts->val_type = TEMP_VAL_DEAD;
2107
                }
2108
            }
2109
            break;
2110
        case INDEX_op_set_label:
2111
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
2112
            tcg_out_label(s, args[0], (long)s->code_ptr);
2113
            break;
2114
        case INDEX_op_call:
2115
            dead_args = s->op_dead_args[op_index];
2116
            args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2117
            goto next;
2118
        case INDEX_op_end:
2119
            goto the_end;
2120
        default:
2121
            /* Note: in order to speed up the code, it would be much
2122
               faster to have specialized register allocator functions for
2123
               some common argument patterns */
2124
            dead_args = s->op_dead_args[op_index];
2125
            tcg_reg_alloc_op(s, def, opc, args, dead_args);
2126
            break;
2127
        }
2128
        args += def->nb_args;
2129
    next:
2130
        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2131
            return op_index;
2132
        }
2133
        op_index++;
2134
#ifndef NDEBUG
2135
        check_regs(s);
2136
#endif
2137
    }
2138
 the_end:
2139
    return -1;
2140
}
2141

    
2142
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2143
{
2144
#ifdef CONFIG_PROFILER
2145
    {
2146
        int n;
2147
        n = (gen_opc_ptr - gen_opc_buf);
2148
        s->op_count += n;
2149
        if (n > s->op_count_max)
2150
            s->op_count_max = n;
2151

    
2152
        s->temp_count += s->nb_temps;
2153
        if (s->nb_temps > s->temp_count_max)
2154
            s->temp_count_max = s->nb_temps;
2155
    }
2156
#endif
2157

    
2158
    tcg_gen_code_common(s, gen_code_buf, -1);
2159

    
2160
    /* flush instruction cache */
2161
    flush_icache_range((unsigned long)gen_code_buf, 
2162
                       (unsigned long)s->code_ptr);
2163
    return s->code_ptr -  gen_code_buf;
2164
}
2165

    
2166
/* Return the index of the micro operation such as the pc after is <
2167
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2168
   not be changed, though writing the same values is ok.
2169
   Return -1 if not found. */
2170
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2171
{
2172
    return tcg_gen_code_common(s, gen_code_buf, offset);
2173
}
2174

    
2175
#ifdef CONFIG_PROFILER
2176
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2177
{
2178
    TCGContext *s = &tcg_ctx;
2179
    int64_t tot;
2180

    
2181
    tot = s->interm_time + s->code_time;
2182
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2183
                tot, tot / 2.4e9);
2184
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2185
                s->tb_count, 
2186
                s->tb_count1 - s->tb_count,
2187
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2188
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2189
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2190
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2191
                s->tb_count ? 
2192
                (double)s->del_op_count / s->tb_count : 0);
2193
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2194
                s->tb_count ? 
2195
                (double)s->temp_count / s->tb_count : 0,
2196
                s->temp_count_max);
2197
    
2198
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2199
                s->op_count ? (double)tot / s->op_count : 0);
2200
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2201
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2202
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2203
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2204
    if (tot == 0)
2205
        tot = 1;
2206
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2207
                (double)s->interm_time / tot * 100.0);
2208
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2209
                (double)s->code_time / tot * 100.0);
2210
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2211
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2212
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2213
                s->restore_count);
2214
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2215
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2216

    
2217
    dump_op_count();
2218
}
2219
#else
2220
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2221
{
2222
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2223
}
2224
#endif