Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 2a24374a

History | View | Annotate | Download (67.4 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
#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
32
/* define it to suppress various consistency checks (faster) */
33
#define NDEBUG
34
#endif
35

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

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

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

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

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

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

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

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

    
94
static TCGRegSet tcg_target_available_regs[2];
95
static TCGRegSet tcg_target_call_clobber_regs;
96

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

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

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

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

    
118
/* label relocation processing */
119

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

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

    
143
static void tcg_out_label(TCGContext *s, int label_index, 
144
                          tcg_target_long value)
145
{
146
    TCGLabel *l;
147
    TCGRelocation *r;
148

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

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

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

    
176
#include "tcg-target.c"
177

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

    
221
void tcg_pool_reset(TCGContext *s)
222
{
223
    s->pool_cur = s->pool_end = NULL;
224
    s->pool_current = NULL;
225
}
226

    
227
void tcg_context_init(TCGContext *s)
228
{
229
    int op, total_args, n;
230
    TCGOpDef *def;
231
    TCGArgConstraint *args_ct;
232
    int *sorted_args;
233

    
234
    memset(s, 0, sizeof(*s));
235
    s->temps = s->static_temps;
236
    s->nb_globals = 0;
237
    
238
    /* Count total number of arguments and allocate the corresponding
239
       space */
240
    total_args = 0;
241
    for(op = 0; op < NB_OPS; op++) {
242
        def = &tcg_op_defs[op];
243
        n = def->nb_iargs + def->nb_oargs;
244
        total_args += n;
245
    }
246

    
247
    args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
248
    sorted_args = g_malloc(sizeof(int) * total_args);
249

    
250
    for(op = 0; op < NB_OPS; op++) {
251
        def = &tcg_op_defs[op];
252
        def->args_ct = args_ct;
253
        def->sorted_args = sorted_args;
254
        n = def->nb_iargs + def->nb_oargs;
255
        sorted_args += n;
256
        args_ct += n;
257
    }
258
    
259
    tcg_target_init(s);
260
}
261

    
262
void tcg_prologue_init(TCGContext *s)
263
{
264
    /* init global prologue and epilogue */
265
    s->code_buf = code_gen_prologue;
266
    s->code_ptr = s->code_buf;
267
    tcg_target_qemu_prologue(s);
268
    flush_icache_range((unsigned long)s->code_buf, 
269
                       (unsigned long)s->code_ptr);
270
}
271

    
272
void tcg_set_frame(TCGContext *s, int reg,
273
                   tcg_target_long start, tcg_target_long size)
274
{
275
    s->frame_start = start;
276
    s->frame_end = start + size;
277
    s->frame_reg = reg;
278
}
279

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

    
291
    gen_opc_ptr = gen_opc_buf;
292
    gen_opparam_ptr = gen_opparam_buf;
293
}
294

    
295
static inline void tcg_temp_alloc(TCGContext *s, int n)
296
{
297
    if (n > TCG_MAX_TEMPS)
298
        tcg_abort();
299
}
300

    
301
static inline int tcg_global_reg_new_internal(TCGType type, int reg,
302
                                              const char *name)
303
{
304
    TCGContext *s = &tcg_ctx;
305
    TCGTemp *ts;
306
    int idx;
307

    
308
#if TCG_TARGET_REG_BITS == 32
309
    if (type != TCG_TYPE_I32)
310
        tcg_abort();
311
#endif
312
    if (tcg_regset_test_reg(s->reserved_regs, reg))
313
        tcg_abort();
314
    idx = s->nb_globals;
315
    tcg_temp_alloc(s, s->nb_globals + 1);
316
    ts = &s->temps[s->nb_globals];
317
    ts->base_type = type;
318
    ts->type = type;
319
    ts->fixed_reg = 1;
320
    ts->reg = reg;
321
    ts->name = name;
322
    s->nb_globals++;
323
    tcg_regset_set_reg(s->reserved_regs, reg);
324
    return idx;
325
}
326

    
327
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
328
{
329
    int idx;
330

    
331
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
332
    return MAKE_TCGV_I32(idx);
333
}
334

    
335
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
336
{
337
    int idx;
338

    
339
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
340
    return MAKE_TCGV_I64(idx);
341
}
342

    
343
static inline int tcg_global_mem_new_internal(TCGType type, int reg,
344
                                              tcg_target_long offset,
345
                                              const char *name)
346
{
347
    TCGContext *s = &tcg_ctx;
348
    TCGTemp *ts;
349
    int idx;
350

    
351
    idx = s->nb_globals;
352
#if TCG_TARGET_REG_BITS == 32
353
    if (type == TCG_TYPE_I64) {
354
        char buf[64];
355
        tcg_temp_alloc(s, s->nb_globals + 2);
356
        ts = &s->temps[s->nb_globals];
357
        ts->base_type = type;
358
        ts->type = TCG_TYPE_I32;
359
        ts->fixed_reg = 0;
360
        ts->mem_allocated = 1;
361
        ts->mem_reg = reg;
362
#ifdef TCG_TARGET_WORDS_BIGENDIAN
363
        ts->mem_offset = offset + 4;
364
#else
365
        ts->mem_offset = offset;
366
#endif
367
        pstrcpy(buf, sizeof(buf), name);
368
        pstrcat(buf, sizeof(buf), "_0");
369
        ts->name = strdup(buf);
370
        ts++;
371

    
372
        ts->base_type = type;
373
        ts->type = TCG_TYPE_I32;
374
        ts->fixed_reg = 0;
375
        ts->mem_allocated = 1;
376
        ts->mem_reg = reg;
377
#ifdef TCG_TARGET_WORDS_BIGENDIAN
378
        ts->mem_offset = offset;
379
#else
380
        ts->mem_offset = offset + 4;
381
#endif
382
        pstrcpy(buf, sizeof(buf), name);
383
        pstrcat(buf, sizeof(buf), "_1");
384
        ts->name = strdup(buf);
385

    
386
        s->nb_globals += 2;
387
    } else
388
#endif
389
    {
390
        tcg_temp_alloc(s, s->nb_globals + 1);
391
        ts = &s->temps[s->nb_globals];
392
        ts->base_type = type;
393
        ts->type = type;
394
        ts->fixed_reg = 0;
395
        ts->mem_allocated = 1;
396
        ts->mem_reg = reg;
397
        ts->mem_offset = offset;
398
        ts->name = name;
399
        s->nb_globals++;
400
    }
401
    return idx;
402
}
403

    
404
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
405
                                const char *name)
406
{
407
    int idx;
408

    
409
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
410
    return MAKE_TCGV_I32(idx);
411
}
412

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

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

    
422
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
423
{
424
    TCGContext *s = &tcg_ctx;
425
    TCGTemp *ts;
426
    int idx, k;
427

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

    
471
#if defined(CONFIG_DEBUG_TCG)
472
    s->temps_in_use++;
473
#endif
474
    return idx;
475
}
476

    
477
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
478
{
479
    int idx;
480

    
481
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
482
    return MAKE_TCGV_I32(idx);
483
}
484

    
485
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
486
{
487
    int idx;
488

    
489
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
490
    return MAKE_TCGV_I64(idx);
491
}
492

    
493
static inline void tcg_temp_free_internal(int idx)
494
{
495
    TCGContext *s = &tcg_ctx;
496
    TCGTemp *ts;
497
    int k;
498

    
499
#if defined(CONFIG_DEBUG_TCG)
500
    s->temps_in_use--;
501
    if (s->temps_in_use < 0) {
502
        fprintf(stderr, "More temporaries freed than allocated!\n");
503
    }
504
#endif
505

    
506
    assert(idx >= s->nb_globals && idx < s->nb_temps);
507
    ts = &s->temps[idx];
508
    assert(ts->temp_allocated != 0);
509
    ts->temp_allocated = 0;
510
    k = ts->base_type;
511
    if (ts->temp_local)
512
        k += TCG_TYPE_COUNT;
513
    ts->next_free_temp = s->first_free_temp[k];
514
    s->first_free_temp[k] = idx;
515
}
516

    
517
void tcg_temp_free_i32(TCGv_i32 arg)
518
{
519
    tcg_temp_free_internal(GET_TCGV_I32(arg));
520
}
521

    
522
void tcg_temp_free_i64(TCGv_i64 arg)
523
{
524
    tcg_temp_free_internal(GET_TCGV_I64(arg));
525
}
526

    
527
TCGv_i32 tcg_const_i32(int32_t val)
528
{
529
    TCGv_i32 t0;
530
    t0 = tcg_temp_new_i32();
531
    tcg_gen_movi_i32(t0, val);
532
    return t0;
533
}
534

    
535
TCGv_i64 tcg_const_i64(int64_t val)
536
{
537
    TCGv_i64 t0;
538
    t0 = tcg_temp_new_i64();
539
    tcg_gen_movi_i64(t0, val);
540
    return t0;
541
}
542

    
543
TCGv_i32 tcg_const_local_i32(int32_t val)
544
{
545
    TCGv_i32 t0;
546
    t0 = tcg_temp_local_new_i32();
547
    tcg_gen_movi_i32(t0, val);
548
    return t0;
549
}
550

    
551
TCGv_i64 tcg_const_local_i64(int64_t val)
552
{
553
    TCGv_i64 t0;
554
    t0 = tcg_temp_local_new_i64();
555
    tcg_gen_movi_i64(t0, val);
556
    return t0;
557
}
558

    
559
#if defined(CONFIG_DEBUG_TCG)
560
void tcg_clear_temp_count(void)
561
{
562
    TCGContext *s = &tcg_ctx;
563
    s->temps_in_use = 0;
564
}
565

    
566
int tcg_check_temp_count(void)
567
{
568
    TCGContext *s = &tcg_ctx;
569
    if (s->temps_in_use) {
570
        /* Clear the count so that we don't give another
571
         * warning immediately next time around.
572
         */
573
        s->temps_in_use = 0;
574
        return 1;
575
    }
576
    return 0;
577
}
578
#endif
579

    
580
void tcg_register_helper(void *func, const char *name)
581
{
582
    TCGContext *s = &tcg_ctx;
583
    int n;
584
    if ((s->nb_helpers + 1) > s->allocated_helpers) {
585
        n = s->allocated_helpers;
586
        if (n == 0) {
587
            n = 4;
588
        } else {
589
            n *= 2;
590
        }
591
        s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
592
        s->allocated_helpers = n;
593
    }
594
    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
595
    s->helpers[s->nb_helpers].name = name;
596
    s->nb_helpers++;
597
}
598

    
599
/* Note: we convert the 64 bit args to 32 bit and do some alignment
600
   and endian swap. Maybe it would be better to do the alignment
601
   and endian swap in tcg_reg_alloc_call(). */
602
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
603
                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
604
{
605
#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
606
    int call_type;
607
#endif
608
    int i;
609
    int real_args;
610
    int nb_rets;
611
    TCGArg *nparam;
612

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

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

    
697
        *gen_opparam_ptr++ = args[i];
698
        real_args++;
699
    }
700
    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
701

    
702
    *gen_opparam_ptr++ = flags;
703

    
704
    *nparam = (nb_rets << 16) | (real_args + 1);
705

    
706
    /* total parameters, needed to go backward in the instruction stream */
707
    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
708

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

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

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

    
769

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

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

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

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

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

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

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

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

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

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

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

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

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

    
918
            fprintf(outfile, " %s ", def->name);
919

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

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

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

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

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

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

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

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

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

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

    
1134
#if 0
1135
        {
1136
            int i;
1137

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

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

    
1173
#ifdef USE_LIVENESS_ANALYSIS
1174

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

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

    
1198
/* liveness analysis: end of basic block: globals are live, temps are
1199
   dead, local temps are live. */
1200
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1201
{
1202
    int i;
1203
    TCGTemp *ts;
1204

    
1205
    memset(dead_temps, 0, s->nb_globals);
1206
    ts = &s->temps[s->nb_globals];
1207
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1208
        if (ts->temp_local)
1209
            dead_temps[i] = 0;
1210
        else
1211
            dead_temps[i] = 1;
1212
        ts++;
1213
    }
1214
}
1215

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

    
1230
    nb_ops = gen_opc_ptr - gen_opc_buf;
1231

    
1232
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1233
    
1234
    dead_temps = tcg_malloc(s->nb_temps);
1235
    memset(dead_temps, 1, s->nb_temps);
1236

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

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

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

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

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

    
1322
            /* Test if the operation can be removed because all
1323
               its outputs are dead. We assume that nb_oargs == 0
1324
               implies side effects */
1325
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1326
                for(i = 0; i < nb_oargs; i++) {
1327
                    arg = args[i];
1328
                    if (!dead_temps[arg])
1329
                        goto do_not_remove;
1330
                }
1331
                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1332
#ifdef CONFIG_PROFILER
1333
                s->del_op_count++;
1334
#endif
1335
            } else {
1336
            do_not_remove:
1337

    
1338
                /* output args are dead */
1339
                dead_args = 0;
1340
                for(i = 0; i < nb_oargs; i++) {
1341
                    arg = args[i];
1342
                    if (dead_temps[arg]) {
1343
                        dead_args |= (1 << i);
1344
                    }
1345
                    dead_temps[arg] = 1;
1346
                }
1347

    
1348
                /* if end of basic block, update */
1349
                if (def->flags & TCG_OPF_BB_END) {
1350
                    tcg_la_bb_end(s, dead_temps);
1351
                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1352
                    /* globals are live */
1353
                    memset(dead_temps, 0, s->nb_globals);
1354
                }
1355

    
1356
                /* input args are live */
1357
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1358
                    arg = args[i];
1359
                    if (dead_temps[arg]) {
1360
                        dead_args |= (1 << i);
1361
                    }
1362
                    dead_temps[arg] = 0;
1363
                }
1364
                s->op_dead_args[op_index] = dead_args;
1365
            }
1366
            break;
1367
        }
1368
        op_index--;
1369
    }
1370

    
1371
    if (args != gen_opparam_buf)
1372
        tcg_abort();
1373
}
1374
#else
1375
/* dummy liveness analysis */
1376
static void tcg_liveness_analysis(TCGContext *s)
1377
{
1378
    int nb_ops;
1379
    nb_ops = gen_opc_ptr - gen_opc_buf;
1380

    
1381
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1382
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1383
}
1384
#endif
1385

    
1386
#ifndef NDEBUG
1387
static void dump_regs(TCGContext *s)
1388
{
1389
    TCGTemp *ts;
1390
    int i;
1391
    char buf[64];
1392

    
1393
    for(i = 0; i < s->nb_temps; i++) {
1394
        ts = &s->temps[i];
1395
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1396
        switch(ts->val_type) {
1397
        case TEMP_VAL_REG:
1398
            printf("%s", tcg_target_reg_names[ts->reg]);
1399
            break;
1400
        case TEMP_VAL_MEM:
1401
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1402
            break;
1403
        case TEMP_VAL_CONST:
1404
            printf("$0x%" TCG_PRIlx, ts->val);
1405
            break;
1406
        case TEMP_VAL_DEAD:
1407
            printf("D");
1408
            break;
1409
        default:
1410
            printf("???");
1411
            break;
1412
        }
1413
        printf("\n");
1414
    }
1415

    
1416
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1417
        if (s->reg_to_temp[i] >= 0) {
1418
            printf("%s: %s\n", 
1419
                   tcg_target_reg_names[i], 
1420
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1421
        }
1422
    }
1423
}
1424

    
1425
static void check_regs(TCGContext *s)
1426
{
1427
    int reg, k;
1428
    TCGTemp *ts;
1429
    char buf[64];
1430

    
1431
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1432
        k = s->reg_to_temp[reg];
1433
        if (k >= 0) {
1434
            ts = &s->temps[k];
1435
            if (ts->val_type != TEMP_VAL_REG ||
1436
                ts->reg != reg) {
1437
                printf("Inconsistency for register %s:\n", 
1438
                       tcg_target_reg_names[reg]);
1439
                goto fail;
1440
            }
1441
        }
1442
    }
1443
    for(k = 0; k < s->nb_temps; k++) {
1444
        ts = &s->temps[k];
1445
        if (ts->val_type == TEMP_VAL_REG &&
1446
            !ts->fixed_reg &&
1447
            s->reg_to_temp[ts->reg] != k) {
1448
                printf("Inconsistency for temp %s:\n", 
1449
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1450
        fail:
1451
                printf("reg state:\n");
1452
                dump_regs(s);
1453
                tcg_abort();
1454
        }
1455
    }
1456
}
1457
#endif
1458

    
1459
static void temp_allocate_frame(TCGContext *s, int temp)
1460
{
1461
    TCGTemp *ts;
1462
    ts = &s->temps[temp];
1463
#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
1464
    s->current_frame_offset = (s->current_frame_offset +
1465
                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
1466
        ~(sizeof(tcg_target_long) - 1);
1467
#endif
1468
    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1469
        s->frame_end) {
1470
        tcg_abort();
1471
    }
1472
    ts->mem_offset = s->current_frame_offset;
1473
    ts->mem_reg = s->frame_reg;
1474
    ts->mem_allocated = 1;
1475
    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1476
}
1477

    
1478
/* free register 'reg' by spilling the corresponding temporary if necessary */
1479
static void tcg_reg_free(TCGContext *s, int reg)
1480
{
1481
    TCGTemp *ts;
1482
    int temp;
1483

    
1484
    temp = s->reg_to_temp[reg];
1485
    if (temp != -1) {
1486
        ts = &s->temps[temp];
1487
        assert(ts->val_type == TEMP_VAL_REG);
1488
        if (!ts->mem_coherent) {
1489
            if (!ts->mem_allocated) 
1490
                temp_allocate_frame(s, temp);
1491
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1492
        }
1493
        ts->val_type = TEMP_VAL_MEM;
1494
        s->reg_to_temp[reg] = -1;
1495
    }
1496
}
1497

    
1498
/* Allocate a register belonging to reg1 & ~reg2 */
1499
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1500
{
1501
    int i, reg;
1502
    TCGRegSet reg_ct;
1503

    
1504
    tcg_regset_andnot(reg_ct, reg1, reg2);
1505

    
1506
    /* first try free registers */
1507
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1508
        reg = tcg_target_reg_alloc_order[i];
1509
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1510
            return reg;
1511
    }
1512

    
1513
    /* XXX: do better spill choice */
1514
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1515
        reg = tcg_target_reg_alloc_order[i];
1516
        if (tcg_regset_test_reg(reg_ct, reg)) {
1517
            tcg_reg_free(s, reg);
1518
            return reg;
1519
        }
1520
    }
1521

    
1522
    tcg_abort();
1523
}
1524

    
1525
/* save a temporary to memory. 'allocated_regs' is used in case a
1526
   temporary registers needs to be allocated to store a constant. */
1527
static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1528
{
1529
    TCGTemp *ts;
1530
    int reg;
1531

    
1532
    ts = &s->temps[temp];
1533
    if (!ts->fixed_reg) {
1534
        switch(ts->val_type) {
1535
        case TEMP_VAL_REG:
1536
            tcg_reg_free(s, ts->reg);
1537
            break;
1538
        case TEMP_VAL_DEAD:
1539
            ts->val_type = TEMP_VAL_MEM;
1540
            break;
1541
        case TEMP_VAL_CONST:
1542
            reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1543
                                allocated_regs);
1544
            if (!ts->mem_allocated) 
1545
                temp_allocate_frame(s, temp);
1546
            tcg_out_movi(s, ts->type, reg, ts->val);
1547
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1548
            ts->val_type = TEMP_VAL_MEM;
1549
            break;
1550
        case TEMP_VAL_MEM:
1551
            break;
1552
        default:
1553
            tcg_abort();
1554
        }
1555
    }
1556
}
1557

    
1558
/* save globals to their cannonical location and assume they can be
1559
   modified be the following code. 'allocated_regs' is used in case a
1560
   temporary registers needs to be allocated to store a constant. */
1561
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1562
{
1563
    int i;
1564

    
1565
    for(i = 0; i < s->nb_globals; i++) {
1566
        temp_save(s, i, allocated_regs);
1567
    }
1568
}
1569

    
1570
/* at the end of a basic block, we assume all temporaries are dead and
1571
   all globals are stored at their canonical location. */
1572
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1573
{
1574
    TCGTemp *ts;
1575
    int i;
1576

    
1577
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1578
        ts = &s->temps[i];
1579
        if (ts->temp_local) {
1580
            temp_save(s, i, allocated_regs);
1581
        } else {
1582
            if (ts->val_type == TEMP_VAL_REG) {
1583
                s->reg_to_temp[ts->reg] = -1;
1584
            }
1585
            ts->val_type = TEMP_VAL_DEAD;
1586
        }
1587
    }
1588

    
1589
    save_globals(s, allocated_regs);
1590
}
1591

    
1592
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1593

    
1594
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1595
{
1596
    TCGTemp *ots;
1597
    tcg_target_ulong val;
1598

    
1599
    ots = &s->temps[args[0]];
1600
    val = args[1];
1601

    
1602
    if (ots->fixed_reg) {
1603
        /* for fixed registers, we do not do any constant
1604
           propagation */
1605
        tcg_out_movi(s, ots->type, ots->reg, val);
1606
    } else {
1607
        /* The movi is not explicitly generated here */
1608
        if (ots->val_type == TEMP_VAL_REG)
1609
            s->reg_to_temp[ots->reg] = -1;
1610
        ots->val_type = TEMP_VAL_CONST;
1611
        ots->val = val;
1612
    }
1613
}
1614

    
1615
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1616
                              const TCGArg *args,
1617
                              unsigned int dead_args)
1618
{
1619
    TCGTemp *ts, *ots;
1620
    int reg;
1621
    const TCGArgConstraint *arg_ct;
1622

    
1623
    ots = &s->temps[args[0]];
1624
    ts = &s->temps[args[1]];
1625
    arg_ct = &def->args_ct[0];
1626

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

    
1674
static void tcg_reg_alloc_op(TCGContext *s, 
1675
                             const TCGOpDef *def, TCGOpcode opc,
1676
                             const TCGArg *args,
1677
                             unsigned int dead_args)
1678
{
1679
    TCGRegSet allocated_regs;
1680
    int i, k, nb_iargs, nb_oargs, reg;
1681
    TCGArg arg;
1682
    const TCGArgConstraint *arg_ct;
1683
    TCGTemp *ts;
1684
    TCGArg new_args[TCG_MAX_OP_ARGS];
1685
    int const_args[TCG_MAX_OP_ARGS];
1686

    
1687
    nb_oargs = def->nb_oargs;
1688
    nb_iargs = def->nb_iargs;
1689

    
1690
    /* copy constants */
1691
    memcpy(new_args + nb_oargs + nb_iargs, 
1692
           args + nb_oargs + nb_iargs, 
1693
           sizeof(TCGArg) * def->nb_cargs);
1694

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

    
1827
    /* emit instruction */
1828
    tcg_out_op(s, opc, new_args, const_args);
1829
    
1830
    /* move the outputs in the correct register if needed */
1831
    for(i = 0; i < nb_oargs; i++) {
1832
        ts = &s->temps[args[i]];
1833
        reg = new_args[i];
1834
        if (ts->fixed_reg && ts->reg != reg) {
1835
            tcg_out_mov(s, ts->type, ts->reg, reg);
1836
        }
1837
    }
1838
}
1839

    
1840
#ifdef TCG_TARGET_STACK_GROWSUP
1841
#define STACK_DIR(x) (-(x))
1842
#else
1843
#define STACK_DIR(x) (x)
1844
#endif
1845

    
1846
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1847
                              TCGOpcode opc, const TCGArg *args,
1848
                              unsigned int dead_args)
1849
{
1850
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1851
    TCGArg arg, func_arg;
1852
    TCGTemp *ts;
1853
    tcg_target_long stack_offset, call_stack_size, func_addr;
1854
    int const_func_arg, allocate_args;
1855
    TCGRegSet allocated_regs;
1856
    const TCGArgConstraint *arg_ct;
1857

    
1858
    arg = *args++;
1859

    
1860
    nb_oargs = arg >> 16;
1861
    nb_iargs = arg & 0xffff;
1862
    nb_params = nb_iargs - 1;
1863

    
1864
    flags = args[nb_oargs + nb_iargs];
1865

    
1866
    nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1867
    if (nb_regs > nb_params)
1868
        nb_regs = nb_params;
1869

    
1870
    /* assign stack slots first */
1871
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1872
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1873
        ~(TCG_TARGET_STACK_ALIGN - 1);
1874
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1875
    if (allocate_args) {
1876
        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1877
           preallocate call stack */
1878
        tcg_abort();
1879
    }
1880

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

    
1996
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
1997

    
1998
    /* assign output registers and emit moves if needed */
1999
    for(i = 0; i < nb_oargs; i++) {
2000
        arg = args[i];
2001
        ts = &s->temps[arg];
2002
        reg = tcg_target_call_oarg_regs[i];
2003
        assert(s->reg_to_temp[reg] == -1);
2004
        if (ts->fixed_reg) {
2005
            if (ts->reg != reg) {
2006
                tcg_out_mov(s, ts->type, ts->reg, reg);
2007
            }
2008
        } else {
2009
            if (ts->val_type == TEMP_VAL_REG)
2010
                s->reg_to_temp[ts->reg] = -1;
2011
            if (IS_DEAD_ARG(i)) {
2012
                ts->val_type = TEMP_VAL_DEAD;
2013
            } else {
2014
                ts->val_type = TEMP_VAL_REG;
2015
                ts->reg = reg;
2016
                ts->mem_coherent = 0;
2017
                s->reg_to_temp[reg] = arg;
2018
            }
2019
        }
2020
    }
2021
    
2022
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
2023
}
2024

    
2025
#ifdef CONFIG_PROFILER
2026

    
2027
static int64_t tcg_table_op_count[NB_OPS];
2028

    
2029
static void dump_op_count(void)
2030
{
2031
    int i;
2032
    FILE *f;
2033
    f = fopen("/tmp/op.log", "w");
2034
    for(i = INDEX_op_end; i < NB_OPS; i++) {
2035
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2036
    }
2037
    fclose(f);
2038
}
2039
#endif
2040

    
2041

    
2042
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2043
                                      long search_pc)
2044
{
2045
    TCGOpcode opc;
2046
    int op_index;
2047
    const TCGOpDef *def;
2048
    unsigned int dead_args;
2049
    const TCGArg *args;
2050

    
2051
#ifdef DEBUG_DISAS
2052
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2053
        qemu_log("OP:\n");
2054
        tcg_dump_ops(s, logfile);
2055
        qemu_log("\n");
2056
    }
2057
#endif
2058

    
2059
#ifdef USE_TCG_OPTIMIZATIONS
2060
    gen_opparam_ptr =
2061
        tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2062
#endif
2063

    
2064
#ifdef CONFIG_PROFILER
2065
    s->la_time -= profile_getclock();
2066
#endif
2067
    tcg_liveness_analysis(s);
2068
#ifdef CONFIG_PROFILER
2069
    s->la_time += profile_getclock();
2070
#endif
2071

    
2072
#ifdef DEBUG_DISAS
2073
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2074
        qemu_log("OP after liveness analysis:\n");
2075
        tcg_dump_ops(s, logfile);
2076
        qemu_log("\n");
2077
    }
2078
#endif
2079

    
2080
    tcg_reg_alloc_start(s);
2081

    
2082
    s->code_buf = gen_code_buf;
2083
    s->code_ptr = gen_code_buf;
2084

    
2085
    args = gen_opparam_buf;
2086
    op_index = 0;
2087

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

    
2172
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2173
{
2174
#ifdef CONFIG_PROFILER
2175
    {
2176
        int n;
2177
        n = (gen_opc_ptr - gen_opc_buf);
2178
        s->op_count += n;
2179
        if (n > s->op_count_max)
2180
            s->op_count_max = n;
2181

    
2182
        s->temp_count += s->nb_temps;
2183
        if (s->nb_temps > s->temp_count_max)
2184
            s->temp_count_max = s->nb_temps;
2185
    }
2186
#endif
2187

    
2188
    tcg_gen_code_common(s, gen_code_buf, -1);
2189

    
2190
    /* flush instruction cache */
2191
    flush_icache_range((unsigned long)gen_code_buf, 
2192
                       (unsigned long)s->code_ptr);
2193
    return s->code_ptr -  gen_code_buf;
2194
}
2195

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

    
2205
#ifdef CONFIG_PROFILER
2206
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2207
{
2208
    TCGContext *s = &tcg_ctx;
2209
    int64_t tot;
2210

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

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