Statistics
| Branch: | Revision:

root / tcg / tcg.c @ 3f90f252

History | View | Annotate | Download (63.3 kB)

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

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

    
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

    
51
/* Note: the long term plan is to reduce the dependancies on the QEMU
52
   CPU definitions. Currently they are used for qemu_ld/st
53
   instructions */
54
#define NO_CPU_IO_DEFS
55
#include "cpu.h"
56
#include "exec-all.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 patch_reloc(uint8_t *code_ptr, int type, 
66
                        tcg_target_long value, tcg_target_long addend);
67

    
68
static TCGOpDef tcg_op_defs[] = {
69
#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
70
#define DEF2(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags, 0 },
71
#include "tcg-opc.h"
72
#undef DEF
73
#undef DEF2
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
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
    /* init global prologue and epilogue */
244
    s->code_buf = code_gen_prologue;
245
    s->code_ptr = s->code_buf;
246
    tcg_target_qemu_prologue(s);
247
    flush_icache_range((unsigned long)s->code_buf, 
248
                       (unsigned long)s->code_ptr);
249
}
250

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

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

    
270
    gen_opc_ptr = gen_opc_buf;
271
    gen_opparam_ptr = gen_opparam_buf;
272
}
273

    
274
static inline void tcg_temp_alloc(TCGContext *s, int n)
275
{
276
    if (n > TCG_MAX_TEMPS)
277
        tcg_abort();
278
}
279

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

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

    
306
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
307
{
308
    int idx;
309

    
310
    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
311
    return MAKE_TCGV_I32(idx);
312
}
313

    
314
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
315
{
316
    int idx;
317

    
318
    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
319
    return MAKE_TCGV_I64(idx);
320
}
321

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

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

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

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

    
383
TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
384
                                const char *name)
385
{
386
    int idx;
387

    
388
    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
389
    return MAKE_TCGV_I32(idx);
390
}
391

    
392
TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
393
                                const char *name)
394
{
395
    int idx;
396

    
397
    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
398
    return MAKE_TCGV_I64(idx);
399
}
400

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

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

    
452
TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
453
{
454
    int idx;
455

    
456
    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
457
    return MAKE_TCGV_I32(idx);
458
}
459

    
460
TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
461
{
462
    int idx;
463

    
464
    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
465
    return MAKE_TCGV_I64(idx);
466
}
467

    
468
static inline void tcg_temp_free_internal(int idx)
469
{
470
    TCGContext *s = &tcg_ctx;
471
    TCGTemp *ts;
472
    int k;
473

    
474
    assert(idx >= s->nb_globals && idx < s->nb_temps);
475
    ts = &s->temps[idx];
476
    assert(ts->temp_allocated != 0);
477
    ts->temp_allocated = 0;
478
    k = ts->base_type;
479
    if (ts->temp_local)
480
        k += TCG_TYPE_COUNT;
481
    ts->next_free_temp = s->first_free_temp[k];
482
    s->first_free_temp[k] = idx;
483
}
484

    
485
void tcg_temp_free_i32(TCGv_i32 arg)
486
{
487
    tcg_temp_free_internal(GET_TCGV_I32(arg));
488
}
489

    
490
void tcg_temp_free_i64(TCGv_i64 arg)
491
{
492
    tcg_temp_free_internal(GET_TCGV_I64(arg));
493
}
494

    
495
TCGv_i32 tcg_const_i32(int32_t val)
496
{
497
    TCGv_i32 t0;
498
    t0 = tcg_temp_new_i32();
499
    tcg_gen_movi_i32(t0, val);
500
    return t0;
501
}
502

    
503
TCGv_i64 tcg_const_i64(int64_t val)
504
{
505
    TCGv_i64 t0;
506
    t0 = tcg_temp_new_i64();
507
    tcg_gen_movi_i64(t0, val);
508
    return t0;
509
}
510

    
511
TCGv_i32 tcg_const_local_i32(int32_t val)
512
{
513
    TCGv_i32 t0;
514
    t0 = tcg_temp_local_new_i32();
515
    tcg_gen_movi_i32(t0, val);
516
    return t0;
517
}
518

    
519
TCGv_i64 tcg_const_local_i64(int64_t val)
520
{
521
    TCGv_i64 t0;
522
    t0 = tcg_temp_local_new_i64();
523
    tcg_gen_movi_i64(t0, val);
524
    return t0;
525
}
526

    
527
void tcg_register_helper(void *func, const char *name)
528
{
529
    TCGContext *s = &tcg_ctx;
530
    int n;
531
    if ((s->nb_helpers + 1) > s->allocated_helpers) {
532
        n = s->allocated_helpers;
533
        if (n == 0) {
534
            n = 4;
535
        } else {
536
            n *= 2;
537
        }
538
        s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
539
        s->allocated_helpers = n;
540
    }
541
    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
542
    s->helpers[s->nb_helpers].name = name;
543
    s->nb_helpers++;
544
}
545

    
546
/* Note: we convert the 64 bit args to 32 bit and do some alignment
547
   and endian swap. Maybe it would be better to do the alignment
548
   and endian swap in tcg_reg_alloc_call(). */
549
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
550
                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
551
{
552
    int call_type;
553
    int i;
554
    int real_args;
555
    int nb_rets;
556
    TCGArg *nparam;
557
    *gen_opc_ptr++ = INDEX_op_call;
558
    nparam = gen_opparam_ptr++;
559
    call_type = (flags & TCG_CALL_TYPE_MASK);
560
    if (ret != TCG_CALL_DUMMY_ARG) {
561
#if TCG_TARGET_REG_BITS < 64
562
        if (sizemask & 1) {
563
#ifdef TCG_TARGET_WORDS_BIGENDIAN
564
            *gen_opparam_ptr++ = ret + 1;
565
            *gen_opparam_ptr++ = ret;
566
#else
567
            *gen_opparam_ptr++ = ret;
568
            *gen_opparam_ptr++ = ret + 1;
569
#endif
570
            nb_rets = 2;
571
        } else
572
#endif
573
        {
574
            *gen_opparam_ptr++ = ret;
575
            nb_rets = 1;
576
        }
577
    } else {
578
        nb_rets = 0;
579
    }
580
    real_args = 0;
581
    for (i = 0; i < nargs; i++) {
582
#if TCG_TARGET_REG_BITS < 64
583
        if (sizemask & (2 << i)) {
584
#ifdef TCG_TARGET_I386
585
            /* REGPARM case: if the third parameter is 64 bit, it is
586
               allocated on the stack */
587
            if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
588
                call_type = TCG_CALL_TYPE_REGPARM_2;
589
                flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
590
            }
591
#endif
592
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
593
            /* some targets want aligned 64 bit args */
594
            if (real_args & 1) {
595
                *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
596
                real_args++;
597
            }
598
#endif
599
            /* If stack grows up, then we will be placing successive
600
               arguments at lower addresses, which means we need to
601
               reverse the order compared to how we would normally
602
               treat either big or little-endian.  For those arguments
603
               that will wind up in registers, this still works for
604
               HPPA (the only current STACK_GROWSUP target) since the
605
               argument registers are *also* allocated in decreasing
606
               order.  If another such target is added, this logic may
607
               have to get more complicated to differentiate between
608
               stack arguments and register arguments.  */
609
#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
610
            *gen_opparam_ptr++ = args[i] + 1;
611
            *gen_opparam_ptr++ = args[i];
612
#else
613
            *gen_opparam_ptr++ = args[i];
614
            *gen_opparam_ptr++ = args[i] + 1;
615
#endif
616
            real_args += 2;
617
        } else
618
#endif
619
        {
620
            *gen_opparam_ptr++ = args[i];
621
            real_args++;
622
        }
623
    }
624
    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
625

    
626
    *gen_opparam_ptr++ = flags;
627

    
628
    *nparam = (nb_rets << 16) | (real_args + 1);
629

    
630
    /* total parameters, needed to go backward in the instruction stream */
631
    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
632
}
633

    
634
#if TCG_TARGET_REG_BITS == 32
635
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
636
                        int c, int right, int arith)
637
{
638
    if (c == 0) {
639
        tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
640
        tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
641
    } else if (c >= 32) {
642
        c -= 32;
643
        if (right) {
644
            if (arith) {
645
                tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
646
                tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
647
            } else {
648
                tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
649
                tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
650
            }
651
        } else {
652
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
653
            tcg_gen_movi_i32(TCGV_LOW(ret), 0);
654
        }
655
    } else {
656
        TCGv_i32 t0, t1;
657

    
658
        t0 = tcg_temp_new_i32();
659
        t1 = tcg_temp_new_i32();
660
        if (right) {
661
            tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
662
            if (arith)
663
                tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
664
            else
665
                tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
666
            tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
667
            tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
668
            tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
669
        } else {
670
            tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
671
            /* Note: ret can be the same as arg1, so we use t1 */
672
            tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
673
            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
674
            tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
675
            tcg_gen_mov_i32(TCGV_LOW(ret), t1);
676
        }
677
        tcg_temp_free_i32(t0);
678
        tcg_temp_free_i32(t1);
679
    }
680
}
681
#endif
682

    
683

    
684
static void tcg_reg_alloc_start(TCGContext *s)
685
{
686
    int i;
687
    TCGTemp *ts;
688
    for(i = 0; i < s->nb_globals; i++) {
689
        ts = &s->temps[i];
690
        if (ts->fixed_reg) {
691
            ts->val_type = TEMP_VAL_REG;
692
        } else {
693
            ts->val_type = TEMP_VAL_MEM;
694
        }
695
    }
696
    for(i = s->nb_globals; i < s->nb_temps; i++) {
697
        ts = &s->temps[i];
698
        ts->val_type = TEMP_VAL_DEAD;
699
        ts->mem_allocated = 0;
700
        ts->fixed_reg = 0;
701
    }
702
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
703
        s->reg_to_temp[i] = -1;
704
    }
705
}
706

    
707
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
708
                                 int idx)
709
{
710
    TCGTemp *ts;
711

    
712
    ts = &s->temps[idx];
713
    if (idx < s->nb_globals) {
714
        pstrcpy(buf, buf_size, ts->name);
715
    } else {
716
        if (ts->temp_local) 
717
            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
718
        else
719
            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
720
    }
721
    return buf;
722
}
723

    
724
char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
725
{
726
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
727
}
728

    
729
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
730
{
731
    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
732
}
733

    
734
static int helper_cmp(const void *p1, const void *p2)
735
{
736
    const TCGHelperInfo *th1 = p1;
737
    const TCGHelperInfo *th2 = p2;
738
    if (th1->func < th2->func)
739
        return -1;
740
    else if (th1->func == th2->func)
741
        return 0;
742
    else
743
        return 1;
744
}
745

    
746
/* find helper definition (Note: A hash table would be better) */
747
static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
748
{
749
    int m, m_min, m_max;
750
    TCGHelperInfo *th;
751
    tcg_target_ulong v;
752

    
753
    if (unlikely(!s->helpers_sorted)) {
754
        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
755
              helper_cmp);
756
        s->helpers_sorted = 1;
757
    }
758

    
759
    /* binary search */
760
    m_min = 0;
761
    m_max = s->nb_helpers - 1;
762
    while (m_min <= m_max) {
763
        m = (m_min + m_max) >> 1;
764
        th = &s->helpers[m];
765
        v = th->func;
766
        if (v == val)
767
            return th;
768
        else if (val < v) {
769
            m_max = m - 1;
770
        } else {
771
            m_min = m + 1;
772
        }
773
    }
774
    return NULL;
775
}
776

    
777
static const char * const cond_name[] =
778
{
779
    [TCG_COND_EQ] = "eq",
780
    [TCG_COND_NE] = "ne",
781
    [TCG_COND_LT] = "lt",
782
    [TCG_COND_GE] = "ge",
783
    [TCG_COND_LE] = "le",
784
    [TCG_COND_GT] = "gt",
785
    [TCG_COND_LTU] = "ltu",
786
    [TCG_COND_GEU] = "geu",
787
    [TCG_COND_LEU] = "leu",
788
    [TCG_COND_GTU] = "gtu"
789
};
790

    
791
void tcg_dump_ops(TCGContext *s, FILE *outfile)
792
{
793
    const uint16_t *opc_ptr;
794
    const TCGArg *args;
795
    TCGArg arg;
796
    int c, i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
797
    const TCGOpDef *def;
798
    char buf[128];
799

    
800
    first_insn = 1;
801
    opc_ptr = gen_opc_buf;
802
    args = gen_opparam_buf;
803
    while (opc_ptr < gen_opc_ptr) {
804
        c = *opc_ptr++;
805
        def = &tcg_op_defs[c];
806
        if (c == INDEX_op_debug_insn_start) {
807
            uint64_t pc;
808
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
809
            pc = ((uint64_t)args[1] << 32) | args[0];
810
#else
811
            pc = args[0];
812
#endif
813
            if (!first_insn) 
814
                fprintf(outfile, "\n");
815
            fprintf(outfile, " ---- 0x%" PRIx64, pc);
816
            first_insn = 0;
817
            nb_oargs = def->nb_oargs;
818
            nb_iargs = def->nb_iargs;
819
            nb_cargs = def->nb_cargs;
820
        } else if (c == INDEX_op_call) {
821
            TCGArg arg;
822

    
823
            /* variable number of arguments */
824
            arg = *args++;
825
            nb_oargs = arg >> 16;
826
            nb_iargs = arg & 0xffff;
827
            nb_cargs = def->nb_cargs;
828

    
829
            fprintf(outfile, " %s ", def->name);
830

    
831
            /* function name */
832
            fprintf(outfile, "%s",
833
                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
834
            /* flags */
835
            fprintf(outfile, ",$0x%" TCG_PRIlx,
836
                    args[nb_oargs + nb_iargs]);
837
            /* nb out args */
838
            fprintf(outfile, ",$%d", nb_oargs);
839
            for(i = 0; i < nb_oargs; i++) {
840
                fprintf(outfile, ",");
841
                fprintf(outfile, "%s",
842
                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
843
            }
844
            for(i = 0; i < (nb_iargs - 1); i++) {
845
                fprintf(outfile, ",");
846
                if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
847
                    fprintf(outfile, "<dummy>");
848
                } else {
849
                    fprintf(outfile, "%s",
850
                            tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
851
                }
852
            }
853
        } else if (c == INDEX_op_movi_i32 
854
#if TCG_TARGET_REG_BITS == 64
855
                   || c == INDEX_op_movi_i64
856
#endif
857
                   ) {
858
            tcg_target_ulong val;
859
            TCGHelperInfo *th;
860

    
861
            nb_oargs = def->nb_oargs;
862
            nb_iargs = def->nb_iargs;
863
            nb_cargs = def->nb_cargs;
864
            fprintf(outfile, " %s %s,$", def->name, 
865
                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
866
            val = args[1];
867
            th = tcg_find_helper(s, val);
868
            if (th) {
869
                fprintf(outfile, "%s", th->name);
870
            } else {
871
                if (c == INDEX_op_movi_i32)
872
                    fprintf(outfile, "0x%x", (uint32_t)val);
873
                else
874
                    fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
875
            }
876
        } else {
877
            fprintf(outfile, " %s ", def->name);
878
            if (c == INDEX_op_nopn) {
879
                /* variable number of arguments */
880
                nb_cargs = *args;
881
                nb_oargs = 0;
882
                nb_iargs = 0;
883
            } else {
884
                nb_oargs = def->nb_oargs;
885
                nb_iargs = def->nb_iargs;
886
                nb_cargs = def->nb_cargs;
887
            }
888
            
889
            k = 0;
890
            for(i = 0; i < nb_oargs; i++) {
891
                if (k != 0)
892
                    fprintf(outfile, ",");
893
                fprintf(outfile, "%s",
894
                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
895
            }
896
            for(i = 0; i < nb_iargs; i++) {
897
                if (k != 0)
898
                    fprintf(outfile, ",");
899
                fprintf(outfile, "%s",
900
                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
901
            }
902
            switch (c) {
903
            case INDEX_op_brcond_i32:
904
#if TCG_TARGET_REG_BITS == 32
905
            case INDEX_op_brcond2_i32:
906
#elif TCG_TARGET_REG_BITS == 64
907
            case INDEX_op_brcond_i64:
908
#endif
909
            case INDEX_op_setcond_i32:
910
#if TCG_TARGET_REG_BITS == 32
911
            case INDEX_op_setcond2_i32:
912
#elif TCG_TARGET_REG_BITS == 64
913
            case INDEX_op_setcond_i64:
914
#endif
915
                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
916
                    fprintf(outfile, ",%s", cond_name[args[k++]]);
917
                else
918
                    fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
919
                i = 1;
920
                break;
921
            default:
922
                i = 0;
923
                break;
924
            }
925
            for(; i < nb_cargs; i++) {
926
                if (k != 0)
927
                    fprintf(outfile, ",");
928
                arg = args[k++];
929
                fprintf(outfile, "$0x%" TCG_PRIlx, arg);
930
            }
931
        }
932
        fprintf(outfile, "\n");
933
        args += nb_iargs + nb_oargs + nb_cargs;
934
    }
935
}
936

    
937
/* we give more priority to constraints with less registers */
938
static int get_constraint_priority(const TCGOpDef *def, int k)
939
{
940
    const TCGArgConstraint *arg_ct;
941

    
942
    int i, n;
943
    arg_ct = &def->args_ct[k];
944
    if (arg_ct->ct & TCG_CT_ALIAS) {
945
        /* an alias is equivalent to a single register */
946
        n = 1;
947
    } else {
948
        if (!(arg_ct->ct & TCG_CT_REG))
949
            return 0;
950
        n = 0;
951
        for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
952
            if (tcg_regset_test_reg(arg_ct->u.regs, i))
953
                n++;
954
        }
955
    }
956
    return TCG_TARGET_NB_REGS - n + 1;
957
}
958

    
959
/* sort from highest priority to lowest */
960
static void sort_constraints(TCGOpDef *def, int start, int n)
961
{
962
    int i, j, p1, p2, tmp;
963

    
964
    for(i = 0; i < n; i++)
965
        def->sorted_args[start + i] = start + i;
966
    if (n <= 1)
967
        return;
968
    for(i = 0; i < n - 1; i++) {
969
        for(j = i + 1; j < n; j++) {
970
            p1 = get_constraint_priority(def, def->sorted_args[start + i]);
971
            p2 = get_constraint_priority(def, def->sorted_args[start + j]);
972
            if (p1 < p2) {
973
                tmp = def->sorted_args[start + i];
974
                def->sorted_args[start + i] = def->sorted_args[start + j];
975
                def->sorted_args[start + j] = tmp;
976
            }
977
        }
978
    }
979
}
980

    
981
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
982
{
983
    int op;
984
    TCGOpDef *def;
985
    const char *ct_str;
986
    int i, nb_args;
987

    
988
    for(;;) {
989
        if (tdefs->op < 0)
990
            break;
991
        op = tdefs->op;
992
        assert(op >= 0 && op < NB_OPS);
993
        def = &tcg_op_defs[op];
994
#if defined(CONFIG_DEBUG_TCG)
995
        /* Duplicate entry in op definitions? */
996
        assert(!def->used);
997
        def->used = 1;
998
#endif
999
        nb_args = def->nb_iargs + def->nb_oargs;
1000
        for(i = 0; i < nb_args; i++) {
1001
            ct_str = tdefs->args_ct_str[i];
1002
            /* Incomplete TCGTargetOpDef entry? */
1003
            assert(ct_str != NULL);
1004
            tcg_regset_clear(def->args_ct[i].u.regs);
1005
            def->args_ct[i].ct = 0;
1006
            if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1007
                int oarg;
1008
                oarg = ct_str[0] - '0';
1009
                assert(oarg < def->nb_oargs);
1010
                assert(def->args_ct[oarg].ct & TCG_CT_REG);
1011
                /* TCG_CT_ALIAS is for the output arguments. The input
1012
                   argument is tagged with TCG_CT_IALIAS. */
1013
                def->args_ct[i] = def->args_ct[oarg];
1014
                def->args_ct[oarg].ct = TCG_CT_ALIAS;
1015
                def->args_ct[oarg].alias_index = i;
1016
                def->args_ct[i].ct |= TCG_CT_IALIAS;
1017
                def->args_ct[i].alias_index = oarg;
1018
            } else {
1019
                for(;;) {
1020
                    if (*ct_str == '\0')
1021
                        break;
1022
                    switch(*ct_str) {
1023
                    case 'i':
1024
                        def->args_ct[i].ct |= TCG_CT_CONST;
1025
                        ct_str++;
1026
                        break;
1027
                    default:
1028
                        if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1029
                            fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1030
                                    ct_str, i, def->name);
1031
                            exit(1);
1032
                        }
1033
                    }
1034
                }
1035
            }
1036
        }
1037

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

    
1041
        /* sort the constraints (XXX: this is just an heuristic) */
1042
        sort_constraints(def, 0, def->nb_oargs);
1043
        sort_constraints(def, def->nb_oargs, def->nb_iargs);
1044

    
1045
#if 0
1046
        {
1047
            int i;
1048

1049
            printf("%s: sorted=", def->name);
1050
            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1051
                printf(" %d", def->sorted_args[i]);
1052
            printf("\n");
1053
        }
1054
#endif
1055
        tdefs++;
1056
    }
1057

    
1058
#if defined(CONFIG_DEBUG_TCG)
1059
    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1060
        if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
1061
            /* Wrong entry in op definitions? */
1062
            assert(!tcg_op_defs[op].used);
1063
        } else {
1064
            /* Missing entry in op definitions? */
1065
            assert(tcg_op_defs[op].used);
1066
        }
1067
    }
1068
#endif
1069
}
1070

    
1071
#ifdef USE_LIVENESS_ANALYSIS
1072

    
1073
/* set a nop for an operation using 'nb_args' */
1074
static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
1075
                               TCGArg *args, int nb_args)
1076
{
1077
    if (nb_args == 0) {
1078
        *opc_ptr = INDEX_op_nop;
1079
    } else {
1080
        *opc_ptr = INDEX_op_nopn;
1081
        args[0] = nb_args;
1082
        args[nb_args - 1] = nb_args;
1083
    }
1084
}
1085

    
1086
/* liveness analysis: end of function: globals are live, temps are
1087
   dead. */
1088
/* XXX: at this stage, not used as there would be little gains because
1089
   most TBs end with a conditional jump. */
1090
static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
1091
{
1092
    memset(dead_temps, 0, s->nb_globals);
1093
    memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
1094
}
1095

    
1096
/* liveness analysis: end of basic block: globals are live, temps are
1097
   dead, local temps are live. */
1098
static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1099
{
1100
    int i;
1101
    TCGTemp *ts;
1102

    
1103
    memset(dead_temps, 0, s->nb_globals);
1104
    ts = &s->temps[s->nb_globals];
1105
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1106
        if (ts->temp_local)
1107
            dead_temps[i] = 0;
1108
        else
1109
            dead_temps[i] = 1;
1110
        ts++;
1111
    }
1112
}
1113

    
1114
/* Liveness analysis : update the opc_dead_iargs array to tell if a
1115
   given input arguments is dead. Instructions updating dead
1116
   temporaries are removed. */
1117
static void tcg_liveness_analysis(TCGContext *s)
1118
{
1119
    int i, op_index, op, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1120
    TCGArg *args;
1121
    const TCGOpDef *def;
1122
    uint8_t *dead_temps;
1123
    unsigned int dead_iargs;
1124
    
1125
    gen_opc_ptr++; /* skip end */
1126

    
1127
    nb_ops = gen_opc_ptr - gen_opc_buf;
1128

    
1129
    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1130
    
1131
    dead_temps = tcg_malloc(s->nb_temps);
1132
    memset(dead_temps, 1, s->nb_temps);
1133

    
1134
    args = gen_opparam_ptr;
1135
    op_index = nb_ops - 1;
1136
    while (op_index >= 0) {
1137
        op = gen_opc_buf[op_index];
1138
        def = &tcg_op_defs[op];
1139
        switch(op) {
1140
        case INDEX_op_call:
1141
            {
1142
                int call_flags;
1143

    
1144
                nb_args = args[-1];
1145
                args -= nb_args;
1146
                nb_iargs = args[0] & 0xffff;
1147
                nb_oargs = args[0] >> 16;
1148
                args++;
1149
                call_flags = args[nb_oargs + nb_iargs];
1150

    
1151
                /* pure functions can be removed if their result is not
1152
                   used */
1153
                if (call_flags & TCG_CALL_PURE) {
1154
                    for(i = 0; i < nb_oargs; i++) {
1155
                        arg = args[i];
1156
                        if (!dead_temps[arg])
1157
                            goto do_not_remove_call;
1158
                    }
1159
                    tcg_set_nop(s, gen_opc_buf + op_index, 
1160
                                args - 1, nb_args);
1161
                } else {
1162
                do_not_remove_call:
1163

    
1164
                    /* output args are dead */
1165
                    for(i = 0; i < nb_oargs; i++) {
1166
                        arg = args[i];
1167
                        dead_temps[arg] = 1;
1168
                    }
1169
                    
1170
                    if (!(call_flags & TCG_CALL_CONST)) {
1171
                        /* globals are live (they may be used by the call) */
1172
                        memset(dead_temps, 0, s->nb_globals);
1173
                    }
1174

    
1175
                    /* input args are live */
1176
                    dead_iargs = 0;
1177
                    for(i = 0; i < nb_iargs; i++) {
1178
                        arg = args[i + nb_oargs];
1179
                        if (arg != TCG_CALL_DUMMY_ARG) {
1180
                            if (dead_temps[arg]) {
1181
                                dead_iargs |= (1 << i);
1182
                            }
1183
                            dead_temps[arg] = 0;
1184
                        }
1185
                    }
1186
                    s->op_dead_iargs[op_index] = dead_iargs;
1187
                }
1188
                args--;
1189
            }
1190
            break;
1191
        case INDEX_op_set_label:
1192
            args--;
1193
            /* mark end of basic block */
1194
            tcg_la_bb_end(s, dead_temps);
1195
            break;
1196
        case INDEX_op_debug_insn_start:
1197
            args -= def->nb_args;
1198
            break;
1199
        case INDEX_op_nopn:
1200
            nb_args = args[-1];
1201
            args -= nb_args;
1202
            break;
1203
        case INDEX_op_discard:
1204
            args--;
1205
            /* mark the temporary as dead */
1206
            dead_temps[args[0]] = 1;
1207
            break;
1208
        case INDEX_op_end:
1209
            break;
1210
            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1211
        default:
1212
            args -= def->nb_args;
1213
            nb_iargs = def->nb_iargs;
1214
            nb_oargs = def->nb_oargs;
1215

    
1216
            /* Test if the operation can be removed because all
1217
               its outputs are dead. We assume that nb_oargs == 0
1218
               implies side effects */
1219
            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1220
                for(i = 0; i < nb_oargs; i++) {
1221
                    arg = args[i];
1222
                    if (!dead_temps[arg])
1223
                        goto do_not_remove;
1224
                }
1225
                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1226
#ifdef CONFIG_PROFILER
1227
                s->del_op_count++;
1228
#endif
1229
            } else {
1230
            do_not_remove:
1231

    
1232
                /* output args are dead */
1233
                for(i = 0; i < nb_oargs; i++) {
1234
                    arg = args[i];
1235
                    dead_temps[arg] = 1;
1236
                }
1237

    
1238
                /* if end of basic block, update */
1239
                if (def->flags & TCG_OPF_BB_END) {
1240
                    tcg_la_bb_end(s, dead_temps);
1241
                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1242
                    /* globals are live */
1243
                    memset(dead_temps, 0, s->nb_globals);
1244
                }
1245

    
1246
                /* input args are live */
1247
                dead_iargs = 0;
1248
                for(i = 0; i < nb_iargs; i++) {
1249
                    arg = args[i + nb_oargs];
1250
                    if (dead_temps[arg]) {
1251
                        dead_iargs |= (1 << i);
1252
                    }
1253
                    dead_temps[arg] = 0;
1254
                }
1255
                s->op_dead_iargs[op_index] = dead_iargs;
1256
            }
1257
            break;
1258
        }
1259
        op_index--;
1260
    }
1261

    
1262
    if (args != gen_opparam_buf)
1263
        tcg_abort();
1264
}
1265
#else
1266
/* dummy liveness analysis */
1267
void tcg_liveness_analysis(TCGContext *s)
1268
{
1269
    int nb_ops;
1270
    nb_ops = gen_opc_ptr - gen_opc_buf;
1271

    
1272
    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1273
    memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
1274
}
1275
#endif
1276

    
1277
#ifndef NDEBUG
1278
static void dump_regs(TCGContext *s)
1279
{
1280
    TCGTemp *ts;
1281
    int i;
1282
    char buf[64];
1283

    
1284
    for(i = 0; i < s->nb_temps; i++) {
1285
        ts = &s->temps[i];
1286
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1287
        switch(ts->val_type) {
1288
        case TEMP_VAL_REG:
1289
            printf("%s", tcg_target_reg_names[ts->reg]);
1290
            break;
1291
        case TEMP_VAL_MEM:
1292
            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1293
            break;
1294
        case TEMP_VAL_CONST:
1295
            printf("$0x%" TCG_PRIlx, ts->val);
1296
            break;
1297
        case TEMP_VAL_DEAD:
1298
            printf("D");
1299
            break;
1300
        default:
1301
            printf("???");
1302
            break;
1303
        }
1304
        printf("\n");
1305
    }
1306

    
1307
    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1308
        if (s->reg_to_temp[i] >= 0) {
1309
            printf("%s: %s\n", 
1310
                   tcg_target_reg_names[i], 
1311
                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1312
        }
1313
    }
1314
}
1315

    
1316
static void check_regs(TCGContext *s)
1317
{
1318
    int reg, k;
1319
    TCGTemp *ts;
1320
    char buf[64];
1321

    
1322
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1323
        k = s->reg_to_temp[reg];
1324
        if (k >= 0) {
1325
            ts = &s->temps[k];
1326
            if (ts->val_type != TEMP_VAL_REG ||
1327
                ts->reg != reg) {
1328
                printf("Inconsistency for register %s:\n", 
1329
                       tcg_target_reg_names[reg]);
1330
                goto fail;
1331
            }
1332
        }
1333
    }
1334
    for(k = 0; k < s->nb_temps; k++) {
1335
        ts = &s->temps[k];
1336
        if (ts->val_type == TEMP_VAL_REG &&
1337
            !ts->fixed_reg &&
1338
            s->reg_to_temp[ts->reg] != k) {
1339
                printf("Inconsistency for temp %s:\n", 
1340
                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1341
        fail:
1342
                printf("reg state:\n");
1343
                dump_regs(s);
1344
                tcg_abort();
1345
        }
1346
    }
1347
}
1348
#endif
1349

    
1350
static void temp_allocate_frame(TCGContext *s, int temp)
1351
{
1352
    TCGTemp *ts;
1353
    ts = &s->temps[temp];
1354
    s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
1355
    if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
1356
        tcg_abort();
1357
    ts->mem_offset = s->current_frame_offset;
1358
    ts->mem_reg = s->frame_reg;
1359
    ts->mem_allocated = 1;
1360
    s->current_frame_offset += sizeof(tcg_target_long);
1361
}
1362

    
1363
/* free register 'reg' by spilling the corresponding temporary if necessary */
1364
static void tcg_reg_free(TCGContext *s, int reg)
1365
{
1366
    TCGTemp *ts;
1367
    int temp;
1368

    
1369
    temp = s->reg_to_temp[reg];
1370
    if (temp != -1) {
1371
        ts = &s->temps[temp];
1372
        assert(ts->val_type == TEMP_VAL_REG);
1373
        if (!ts->mem_coherent) {
1374
            if (!ts->mem_allocated) 
1375
                temp_allocate_frame(s, temp);
1376
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1377
        }
1378
        ts->val_type = TEMP_VAL_MEM;
1379
        s->reg_to_temp[reg] = -1;
1380
    }
1381
}
1382

    
1383
/* Allocate a register belonging to reg1 & ~reg2 */
1384
static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1385
{
1386
    int i, reg;
1387
    TCGRegSet reg_ct;
1388

    
1389
    tcg_regset_andnot(reg_ct, reg1, reg2);
1390

    
1391
    /* first try free registers */
1392
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1393
        reg = tcg_target_reg_alloc_order[i];
1394
        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1395
            return reg;
1396
    }
1397

    
1398
    /* XXX: do better spill choice */
1399
    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1400
        reg = tcg_target_reg_alloc_order[i];
1401
        if (tcg_regset_test_reg(reg_ct, reg)) {
1402
            tcg_reg_free(s, reg);
1403
            return reg;
1404
        }
1405
    }
1406

    
1407
    tcg_abort();
1408
}
1409

    
1410
/* save a temporary to memory. 'allocated_regs' is used in case a
1411
   temporary registers needs to be allocated to store a constant. */
1412
static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1413
{
1414
    TCGTemp *ts;
1415
    int reg;
1416

    
1417
    ts = &s->temps[temp];
1418
    if (!ts->fixed_reg) {
1419
        switch(ts->val_type) {
1420
        case TEMP_VAL_REG:
1421
            tcg_reg_free(s, ts->reg);
1422
            break;
1423
        case TEMP_VAL_DEAD:
1424
            ts->val_type = TEMP_VAL_MEM;
1425
            break;
1426
        case TEMP_VAL_CONST:
1427
            reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1428
                                allocated_regs);
1429
            if (!ts->mem_allocated) 
1430
                temp_allocate_frame(s, temp);
1431
            tcg_out_movi(s, ts->type, reg, ts->val);
1432
            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1433
            ts->val_type = TEMP_VAL_MEM;
1434
            break;
1435
        case TEMP_VAL_MEM:
1436
            break;
1437
        default:
1438
            tcg_abort();
1439
        }
1440
    }
1441
}
1442

    
1443
/* save globals to their cannonical location and assume they can be
1444
   modified be the following code. 'allocated_regs' is used in case a
1445
   temporary registers needs to be allocated to store a constant. */
1446
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1447
{
1448
    int i;
1449

    
1450
    for(i = 0; i < s->nb_globals; i++) {
1451
        temp_save(s, i, allocated_regs);
1452
    }
1453
}
1454

    
1455
/* at the end of a basic block, we assume all temporaries are dead and
1456
   all globals are stored at their canonical location. */
1457
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1458
{
1459
    TCGTemp *ts;
1460
    int i;
1461

    
1462
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1463
        ts = &s->temps[i];
1464
        if (ts->temp_local) {
1465
            temp_save(s, i, allocated_regs);
1466
        } else {
1467
            if (ts->val_type == TEMP_VAL_REG) {
1468
                s->reg_to_temp[ts->reg] = -1;
1469
            }
1470
            ts->val_type = TEMP_VAL_DEAD;
1471
        }
1472
    }
1473

    
1474
    save_globals(s, allocated_regs);
1475
}
1476

    
1477
#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
1478

    
1479
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1480
{
1481
    TCGTemp *ots;
1482
    tcg_target_ulong val;
1483

    
1484
    ots = &s->temps[args[0]];
1485
    val = args[1];
1486

    
1487
    if (ots->fixed_reg) {
1488
        /* for fixed registers, we do not do any constant
1489
           propagation */
1490
        tcg_out_movi(s, ots->type, ots->reg, val);
1491
    } else {
1492
        /* The movi is not explicitly generated here */
1493
        if (ots->val_type == TEMP_VAL_REG)
1494
            s->reg_to_temp[ots->reg] = -1;
1495
        ots->val_type = TEMP_VAL_CONST;
1496
        ots->val = val;
1497
    }
1498
}
1499

    
1500
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1501
                              const TCGArg *args,
1502
                              unsigned int dead_iargs)
1503
{
1504
    TCGTemp *ts, *ots;
1505
    int reg;
1506
    const TCGArgConstraint *arg_ct;
1507

    
1508
    ots = &s->temps[args[0]];
1509
    ts = &s->temps[args[1]];
1510
    arg_ct = &def->args_ct[0];
1511

    
1512
    /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
1513
    if (ts->val_type == TEMP_VAL_REG) {
1514
        if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
1515
            /* the mov can be suppressed */
1516
            if (ots->val_type == TEMP_VAL_REG)
1517
                s->reg_to_temp[ots->reg] = -1;
1518
            reg = ts->reg;
1519
            s->reg_to_temp[reg] = -1;
1520
            ts->val_type = TEMP_VAL_DEAD;
1521
        } else {
1522
            if (ots->val_type == TEMP_VAL_REG) {
1523
                reg = ots->reg;
1524
            } else {
1525
                reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1526
            }
1527
            if (ts->reg != reg) {
1528
                tcg_out_mov(s, reg, ts->reg);
1529
            }
1530
        }
1531
    } else if (ts->val_type == TEMP_VAL_MEM) {
1532
        if (ots->val_type == TEMP_VAL_REG) {
1533
            reg = ots->reg;
1534
        } else {
1535
            reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1536
        }
1537
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1538
    } else if (ts->val_type == TEMP_VAL_CONST) {
1539
        if (ots->fixed_reg) {
1540
            reg = ots->reg;
1541
            tcg_out_movi(s, ots->type, reg, ts->val);
1542
        } else {
1543
            /* propagate constant */
1544
            if (ots->val_type == TEMP_VAL_REG)
1545
                s->reg_to_temp[ots->reg] = -1;
1546
            ots->val_type = TEMP_VAL_CONST;
1547
            ots->val = ts->val;
1548
            return;
1549
        }
1550
    } else {
1551
        tcg_abort();
1552
    }
1553
    s->reg_to_temp[reg] = args[0];
1554
    ots->reg = reg;
1555
    ots->val_type = TEMP_VAL_REG;
1556
    ots->mem_coherent = 0;
1557
}
1558

    
1559
static void tcg_reg_alloc_op(TCGContext *s, 
1560
                             const TCGOpDef *def, int opc,
1561
                             const TCGArg *args,
1562
                             unsigned int dead_iargs)
1563
{
1564
    TCGRegSet allocated_regs;
1565
    int i, k, nb_iargs, nb_oargs, reg;
1566
    TCGArg arg;
1567
    const TCGArgConstraint *arg_ct;
1568
    TCGTemp *ts;
1569
    TCGArg new_args[TCG_MAX_OP_ARGS];
1570
    int const_args[TCG_MAX_OP_ARGS];
1571

    
1572
    nb_oargs = def->nb_oargs;
1573
    nb_iargs = def->nb_iargs;
1574

    
1575
    /* copy constants */
1576
    memcpy(new_args + nb_oargs + nb_iargs, 
1577
           args + nb_oargs + nb_iargs, 
1578
           sizeof(TCGArg) * def->nb_cargs);
1579

    
1580
    /* satisfy input constraints */ 
1581
    tcg_regset_set(allocated_regs, s->reserved_regs);
1582
    for(k = 0; k < nb_iargs; k++) {
1583
        i = def->sorted_args[nb_oargs + k];
1584
        arg = args[i];
1585
        arg_ct = &def->args_ct[i];
1586
        ts = &s->temps[arg];
1587
        if (ts->val_type == TEMP_VAL_MEM) {
1588
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1589
            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1590
            ts->val_type = TEMP_VAL_REG;
1591
            ts->reg = reg;
1592
            ts->mem_coherent = 1;
1593
            s->reg_to_temp[reg] = arg;
1594
        } else if (ts->val_type == TEMP_VAL_CONST) {
1595
            if (tcg_target_const_match(ts->val, arg_ct)) {
1596
                /* constant is OK for instruction */
1597
                const_args[i] = 1;
1598
                new_args[i] = ts->val;
1599
                goto iarg_end;
1600
            } else {
1601
                /* need to move to a register */
1602
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1603
                tcg_out_movi(s, ts->type, reg, ts->val);
1604
                ts->val_type = TEMP_VAL_REG;
1605
                ts->reg = reg;
1606
                ts->mem_coherent = 0;
1607
                s->reg_to_temp[reg] = arg;
1608
            }
1609
        }
1610
        assert(ts->val_type == TEMP_VAL_REG);
1611
        if (arg_ct->ct & TCG_CT_IALIAS) {
1612
            if (ts->fixed_reg) {
1613
                /* if fixed register, we must allocate a new register
1614
                   if the alias is not the same register */
1615
                if (arg != args[arg_ct->alias_index])
1616
                    goto allocate_in_reg;
1617
            } else {
1618
                /* if the input is aliased to an output and if it is
1619
                   not dead after the instruction, we must allocate
1620
                   a new register and move it */
1621
                if (!IS_DEAD_IARG(i - nb_oargs)) 
1622
                    goto allocate_in_reg;
1623
            }
1624
        }
1625
        reg = ts->reg;
1626
        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1627
            /* nothing to do : the constraint is satisfied */
1628
        } else {
1629
        allocate_in_reg:
1630
            /* allocate a new register matching the constraint 
1631
               and move the temporary register into it */
1632
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1633
            tcg_out_mov(s, reg, ts->reg);
1634
        }
1635
        new_args[i] = reg;
1636
        const_args[i] = 0;
1637
        tcg_regset_set_reg(allocated_regs, reg);
1638
    iarg_end: ;
1639
    }
1640
    
1641
    if (def->flags & TCG_OPF_BB_END) {
1642
        tcg_reg_alloc_bb_end(s, allocated_regs);
1643
    } else {
1644
        /* mark dead temporaries and free the associated registers */
1645
        for(i = 0; i < nb_iargs; i++) {
1646
            arg = args[nb_oargs + i];
1647
            if (IS_DEAD_IARG(i)) {
1648
                ts = &s->temps[arg];
1649
                if (!ts->fixed_reg) {
1650
                    if (ts->val_type == TEMP_VAL_REG)
1651
                        s->reg_to_temp[ts->reg] = -1;
1652
                    ts->val_type = TEMP_VAL_DEAD;
1653
                }
1654
            }
1655
        }
1656
        
1657
        if (def->flags & TCG_OPF_CALL_CLOBBER) {
1658
            /* XXX: permit generic clobber register list ? */ 
1659
            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1660
                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1661
                    tcg_reg_free(s, reg);
1662
                }
1663
            }
1664
            /* XXX: for load/store we could do that only for the slow path
1665
               (i.e. when a memory callback is called) */
1666
            
1667
            /* store globals and free associated registers (we assume the insn
1668
               can modify any global. */
1669
            save_globals(s, allocated_regs);
1670
        }
1671
        
1672
        /* satisfy the output constraints */
1673
        tcg_regset_set(allocated_regs, s->reserved_regs);
1674
        for(k = 0; k < nb_oargs; k++) {
1675
            i = def->sorted_args[k];
1676
            arg = args[i];
1677
            arg_ct = &def->args_ct[i];
1678
            ts = &s->temps[arg];
1679
            if (arg_ct->ct & TCG_CT_ALIAS) {
1680
                reg = new_args[arg_ct->alias_index];
1681
            } else {
1682
                /* if fixed register, we try to use it */
1683
                reg = ts->reg;
1684
                if (ts->fixed_reg &&
1685
                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1686
                    goto oarg_end;
1687
                }
1688
                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1689
            }
1690
            tcg_regset_set_reg(allocated_regs, reg);
1691
            /* if a fixed register is used, then a move will be done afterwards */
1692
            if (!ts->fixed_reg) {
1693
                if (ts->val_type == TEMP_VAL_REG)
1694
                    s->reg_to_temp[ts->reg] = -1;
1695
                ts->val_type = TEMP_VAL_REG;
1696
                ts->reg = reg;
1697
                /* temp value is modified, so the value kept in memory is
1698
                   potentially not the same */
1699
                ts->mem_coherent = 0; 
1700
                s->reg_to_temp[reg] = arg;
1701
            }
1702
        oarg_end:
1703
            new_args[i] = reg;
1704
        }
1705
    }
1706

    
1707
    /* emit instruction */
1708
    tcg_out_op(s, opc, new_args, const_args);
1709
    
1710
    /* move the outputs in the correct register if needed */
1711
    for(i = 0; i < nb_oargs; i++) {
1712
        ts = &s->temps[args[i]];
1713
        reg = new_args[i];
1714
        if (ts->fixed_reg && ts->reg != reg) {
1715
            tcg_out_mov(s, ts->reg, reg);
1716
        }
1717
    }
1718
}
1719

    
1720
#ifdef TCG_TARGET_STACK_GROWSUP
1721
#define STACK_DIR(x) (-(x))
1722
#else
1723
#define STACK_DIR(x) (x)
1724
#endif
1725

    
1726
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1727
                              int opc, const TCGArg *args,
1728
                              unsigned int dead_iargs)
1729
{
1730
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1731
    TCGArg arg, func_arg;
1732
    TCGTemp *ts;
1733
    tcg_target_long stack_offset, call_stack_size, func_addr;
1734
    int const_func_arg, allocate_args;
1735
    TCGRegSet allocated_regs;
1736
    const TCGArgConstraint *arg_ct;
1737

    
1738
    arg = *args++;
1739

    
1740
    nb_oargs = arg >> 16;
1741
    nb_iargs = arg & 0xffff;
1742
    nb_params = nb_iargs - 1;
1743

    
1744
    flags = args[nb_oargs + nb_iargs];
1745

    
1746
    nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1747
    if (nb_regs > nb_params)
1748
        nb_regs = nb_params;
1749

    
1750
    /* assign stack slots first */
1751
    /* XXX: preallocate call stack */
1752
    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1753
    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1754
        ~(TCG_TARGET_STACK_ALIGN - 1);
1755
    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1756
    if (allocate_args) {
1757
        tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
1758
    }
1759

    
1760
    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1761
    for(i = nb_regs; i < nb_params; i++) {
1762
        arg = args[nb_oargs + i];
1763
#ifdef TCG_TARGET_STACK_GROWSUP
1764
        stack_offset -= sizeof(tcg_target_long);
1765
#endif
1766
        if (arg != TCG_CALL_DUMMY_ARG) {
1767
            ts = &s->temps[arg];
1768
            if (ts->val_type == TEMP_VAL_REG) {
1769
                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1770
            } else if (ts->val_type == TEMP_VAL_MEM) {
1771
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1772
                                    s->reserved_regs);
1773
                /* XXX: not correct if reading values from the stack */
1774
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1775
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1776
            } else if (ts->val_type == TEMP_VAL_CONST) {
1777
                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1778
                                    s->reserved_regs);
1779
                /* XXX: sign extend may be needed on some targets */
1780
                tcg_out_movi(s, ts->type, reg, ts->val);
1781
                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1782
            } else {
1783
                tcg_abort();
1784
            }
1785
        }
1786
#ifndef TCG_TARGET_STACK_GROWSUP
1787
        stack_offset += sizeof(tcg_target_long);
1788
#endif
1789
    }
1790
    
1791
    /* assign input registers */
1792
    tcg_regset_set(allocated_regs, s->reserved_regs);
1793
    for(i = 0; i < nb_regs; i++) {
1794
        arg = args[nb_oargs + i];
1795
        if (arg != TCG_CALL_DUMMY_ARG) {
1796
            ts = &s->temps[arg];
1797
            reg = tcg_target_call_iarg_regs[i];
1798
            tcg_reg_free(s, reg);
1799
            if (ts->val_type == TEMP_VAL_REG) {
1800
                if (ts->reg != reg) {
1801
                    tcg_out_mov(s, reg, ts->reg);
1802
                }
1803
            } else if (ts->val_type == TEMP_VAL_MEM) {
1804
                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1805
            } else if (ts->val_type == TEMP_VAL_CONST) {
1806
                /* XXX: sign extend ? */
1807
                tcg_out_movi(s, ts->type, reg, ts->val);
1808
            } else {
1809
                tcg_abort();
1810
            }
1811
            tcg_regset_set_reg(allocated_regs, reg);
1812
        }
1813
    }
1814
    
1815
    /* assign function address */
1816
    func_arg = args[nb_oargs + nb_iargs - 1];
1817
    arg_ct = &def->args_ct[0];
1818
    ts = &s->temps[func_arg];
1819
    func_addr = ts->val;
1820
    const_func_arg = 0;
1821
    if (ts->val_type == TEMP_VAL_MEM) {
1822
        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1823
        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1824
        func_arg = reg;
1825
        tcg_regset_set_reg(allocated_regs, reg);
1826
    } else if (ts->val_type == TEMP_VAL_REG) {
1827
        reg = ts->reg;
1828
        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1829
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1830
            tcg_out_mov(s, reg, ts->reg);
1831
        }
1832
        func_arg = reg;
1833
        tcg_regset_set_reg(allocated_regs, reg);
1834
    } else if (ts->val_type == TEMP_VAL_CONST) {
1835
        if (tcg_target_const_match(func_addr, arg_ct)) {
1836
            const_func_arg = 1;
1837
            func_arg = func_addr;
1838
        } else {
1839
            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1840
            tcg_out_movi(s, ts->type, reg, func_addr);
1841
            func_arg = reg;
1842
            tcg_regset_set_reg(allocated_regs, reg);
1843
        }
1844
    } else {
1845
        tcg_abort();
1846
    }
1847
        
1848
    
1849
    /* mark dead temporaries and free the associated registers */
1850
    for(i = 0; i < nb_iargs; i++) {
1851
        arg = args[nb_oargs + i];
1852
        if (IS_DEAD_IARG(i)) {
1853
            ts = &s->temps[arg];
1854
            if (!ts->fixed_reg) {
1855
                if (ts->val_type == TEMP_VAL_REG)
1856
                    s->reg_to_temp[ts->reg] = -1;
1857
                ts->val_type = TEMP_VAL_DEAD;
1858
            }
1859
        }
1860
    }
1861
    
1862
    /* clobber call registers */
1863
    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1864
        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1865
            tcg_reg_free(s, reg);
1866
        }
1867
    }
1868
    
1869
    /* store globals and free associated registers (we assume the call
1870
       can modify any global. */
1871
    if (!(flags & TCG_CALL_CONST)) {
1872
        save_globals(s, allocated_regs);
1873
    }
1874

    
1875
    tcg_out_op(s, opc, &func_arg, &const_func_arg);
1876
    
1877
    if (allocate_args) {
1878
        tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
1879
    }
1880

    
1881
    /* assign output registers and emit moves if needed */
1882
    for(i = 0; i < nb_oargs; i++) {
1883
        arg = args[i];
1884
        ts = &s->temps[arg];
1885
        reg = tcg_target_call_oarg_regs[i];
1886
        assert(s->reg_to_temp[reg] == -1);
1887
        if (ts->fixed_reg) {
1888
            if (ts->reg != reg) {
1889
                tcg_out_mov(s, ts->reg, reg);
1890
            }
1891
        } else {
1892
            if (ts->val_type == TEMP_VAL_REG)
1893
                s->reg_to_temp[ts->reg] = -1;
1894
            ts->val_type = TEMP_VAL_REG;
1895
            ts->reg = reg;
1896
            ts->mem_coherent = 0; 
1897
            s->reg_to_temp[reg] = arg;
1898
        }
1899
    }
1900
    
1901
    return nb_iargs + nb_oargs + def->nb_cargs + 1;
1902
}
1903

    
1904
#ifdef CONFIG_PROFILER
1905

    
1906
static int64_t tcg_table_op_count[NB_OPS];
1907

    
1908
static void dump_op_count(void)
1909
{
1910
    int i;
1911
    FILE *f;
1912
    f = fopen("/tmp/op.log", "w");
1913
    for(i = INDEX_op_end; i < NB_OPS; i++) {
1914
        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
1915
    }
1916
    fclose(f);
1917
}
1918
#endif
1919

    
1920

    
1921
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1922
                                      long search_pc)
1923
{
1924
    int opc, op_index;
1925
    const TCGOpDef *def;
1926
    unsigned int dead_iargs;
1927
    const TCGArg *args;
1928

    
1929
#ifdef DEBUG_DISAS
1930
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
1931
        qemu_log("OP:\n");
1932
        tcg_dump_ops(s, logfile);
1933
        qemu_log("\n");
1934
    }
1935
#endif
1936

    
1937
#ifdef CONFIG_PROFILER
1938
    s->la_time -= profile_getclock();
1939
#endif
1940
    tcg_liveness_analysis(s);
1941
#ifdef CONFIG_PROFILER
1942
    s->la_time += profile_getclock();
1943
#endif
1944

    
1945
#ifdef DEBUG_DISAS
1946
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
1947
        qemu_log("OP after liveness analysis:\n");
1948
        tcg_dump_ops(s, logfile);
1949
        qemu_log("\n");
1950
    }
1951
#endif
1952

    
1953
    tcg_reg_alloc_start(s);
1954

    
1955
    s->code_buf = gen_code_buf;
1956
    s->code_ptr = gen_code_buf;
1957

    
1958
    args = gen_opparam_buf;
1959
    op_index = 0;
1960

    
1961
    for(;;) {
1962
        opc = gen_opc_buf[op_index];
1963
#ifdef CONFIG_PROFILER
1964
        tcg_table_op_count[opc]++;
1965
#endif
1966
        def = &tcg_op_defs[opc];
1967
#if 0
1968
        printf("%s: %d %d %d\n", def->name,
1969
               def->nb_oargs, def->nb_iargs, def->nb_cargs);
1970
        //        dump_regs(s);
1971
#endif
1972
        switch(opc) {
1973
        case INDEX_op_mov_i32:
1974
#if TCG_TARGET_REG_BITS == 64
1975
        case INDEX_op_mov_i64:
1976
#endif
1977
            dead_iargs = s->op_dead_iargs[op_index];
1978
            tcg_reg_alloc_mov(s, def, args, dead_iargs);
1979
            break;
1980
        case INDEX_op_movi_i32:
1981
#if TCG_TARGET_REG_BITS == 64
1982
        case INDEX_op_movi_i64:
1983
#endif
1984
            tcg_reg_alloc_movi(s, args);
1985
            break;
1986
        case INDEX_op_debug_insn_start:
1987
            /* debug instruction */
1988
            break;
1989
        case INDEX_op_nop:
1990
        case INDEX_op_nop1:
1991
        case INDEX_op_nop2:
1992
        case INDEX_op_nop3:
1993
            break;
1994
        case INDEX_op_nopn:
1995
            args += args[0];
1996
            goto next;
1997
        case INDEX_op_discard:
1998
            {
1999
                TCGTemp *ts;
2000
                ts = &s->temps[args[0]];
2001
                /* mark the temporary as dead */
2002
                if (!ts->fixed_reg) {
2003
                    if (ts->val_type == TEMP_VAL_REG)
2004
                        s->reg_to_temp[ts->reg] = -1;
2005
                    ts->val_type = TEMP_VAL_DEAD;
2006
                }
2007
            }
2008
            break;
2009
        case INDEX_op_set_label:
2010
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
2011
            tcg_out_label(s, args[0], (long)s->code_ptr);
2012
            break;
2013
        case INDEX_op_call:
2014
            dead_iargs = s->op_dead_iargs[op_index];
2015
            args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
2016
            goto next;
2017
        case INDEX_op_end:
2018
            goto the_end;
2019
        default:
2020
            /* Note: in order to speed up the code, it would be much
2021
               faster to have specialized register allocator functions for
2022
               some common argument patterns */
2023
            dead_iargs = s->op_dead_iargs[op_index];
2024
            tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
2025
            break;
2026
        }
2027
        args += def->nb_args;
2028
    next:
2029
        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2030
            return op_index;
2031
        }
2032
        op_index++;
2033
#ifndef NDEBUG
2034
        check_regs(s);
2035
#endif
2036
    }
2037
 the_end:
2038
    return -1;
2039
}
2040

    
2041
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2042
{
2043
#ifdef CONFIG_PROFILER
2044
    {
2045
        int n;
2046
        n = (gen_opc_ptr - gen_opc_buf);
2047
        s->op_count += n;
2048
        if (n > s->op_count_max)
2049
            s->op_count_max = n;
2050

    
2051
        s->temp_count += s->nb_temps;
2052
        if (s->nb_temps > s->temp_count_max)
2053
            s->temp_count_max = s->nb_temps;
2054
    }
2055
#endif
2056

    
2057
    tcg_gen_code_common(s, gen_code_buf, -1);
2058

    
2059
    /* flush instruction cache */
2060
    flush_icache_range((unsigned long)gen_code_buf, 
2061
                       (unsigned long)s->code_ptr);
2062
    return s->code_ptr -  gen_code_buf;
2063
}
2064

    
2065
/* Return the index of the micro operation such as the pc after is <
2066
   offset bytes from the start of the TB.  The contents of gen_code_buf must
2067
   not be changed, though writing the same values is ok.
2068
   Return -1 if not found. */
2069
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2070
{
2071
    return tcg_gen_code_common(s, gen_code_buf, offset);
2072
}
2073

    
2074
#ifdef CONFIG_PROFILER
2075
void tcg_dump_info(FILE *f,
2076
                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2077
{
2078
    TCGContext *s = &tcg_ctx;
2079
    int64_t tot;
2080

    
2081
    tot = s->interm_time + s->code_time;
2082
    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2083
                tot, tot / 2.4e9);
2084
    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2085
                s->tb_count, 
2086
                s->tb_count1 - s->tb_count,
2087
                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2088
    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2089
                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2090
    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2091
                s->tb_count ? 
2092
                (double)s->del_op_count / s->tb_count : 0);
2093
    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2094
                s->tb_count ? 
2095
                (double)s->temp_count / s->tb_count : 0,
2096
                s->temp_count_max);
2097
    
2098
    cpu_fprintf(f, "cycles/op           %0.1f\n", 
2099
                s->op_count ? (double)tot / s->op_count : 0);
2100
    cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2101
                s->code_in_len ? (double)tot / s->code_in_len : 0);
2102
    cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2103
                s->code_out_len ? (double)tot / s->code_out_len : 0);
2104
    if (tot == 0)
2105
        tot = 1;
2106
    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2107
                (double)s->interm_time / tot * 100.0);
2108
    cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2109
                (double)s->code_time / tot * 100.0);
2110
    cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2111
                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2112
    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2113
                s->restore_count);
2114
    cpu_fprintf(f, "  avg cycles        %0.1f\n",
2115
                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2116

    
2117
    dump_op_count();
2118
}
2119
#else
2120
void tcg_dump_info(FILE *f,
2121
                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2122
{
2123
    cpu_fprintf(f, "[TCG profiler not compiled]\n");
2124
}
2125
#endif