]> Git Repo - qemu.git/blob - tcg/tcg.c
pci: Unregister BARs before device exit
[qemu.git] / tcg / tcg.c
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 /* define it to use liveness analysis (better code) */
26 #define USE_LIVENESS_ANALYSIS
27 #define USE_TCG_OPTIMIZATIONS
28
29 #include "config.h"
30
31 /* Define to jump the ELF file used to communicate with GDB.  */
32 #undef DEBUG_JIT
33
34 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
35 /* define it to suppress various consistency checks (faster) */
36 #define NDEBUG
37 #endif
38
39 #include "qemu-common.h"
40 #include "cache-utils.h"
41 #include "host-utils.h"
42 #include "qemu-timer.h"
43
44 /* Note: the long term plan is to reduce the dependancies on the QEMU
45    CPU definitions. Currently they are used for qemu_ld/st
46    instructions */
47 #define NO_CPU_IO_DEFS
48 #include "cpu.h"
49
50 #include "tcg-op.h"
51
52 #if TCG_TARGET_REG_BITS == 64
53 # define ELF_CLASS  ELFCLASS64
54 #else
55 # define ELF_CLASS  ELFCLASS32
56 #endif
57 #ifdef HOST_WORDS_BIGENDIAN
58 # define ELF_DATA   ELFDATA2MSB
59 #else
60 # define ELF_DATA   ELFDATA2LSB
61 #endif
62
63 #include "elf.h"
64
65 #if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
66 #error GUEST_BASE not supported on this host.
67 #endif
68
69 /* Forward declarations for functions declared in tcg-target.c and used here. */
70 static void tcg_target_init(TCGContext *s);
71 static void tcg_target_qemu_prologue(TCGContext *s);
72 static void patch_reloc(uint8_t *code_ptr, int type, 
73                         tcg_target_long value, tcg_target_long addend);
74
75 static void tcg_register_jit_int(void *buf, size_t size,
76                                  void *debug_frame, size_t debug_frame_size)
77     __attribute__((unused));
78
79 /* Forward declarations for functions declared and used in tcg-target.c. */
80 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
81 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
82                        tcg_target_long arg2);
83 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
84 static void tcg_out_movi(TCGContext *s, TCGType type,
85                          TCGReg ret, tcg_target_long arg);
86 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
87                        const int *const_args);
88 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
89                        tcg_target_long arg2);
90 static int tcg_target_const_match(tcg_target_long val,
91                                   const TCGArgConstraint *arg_ct);
92 static int tcg_target_get_call_iarg_regs_count(int flags);
93
94 TCGOpDef tcg_op_defs[] = {
95 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
96 #include "tcg-opc.h"
97 #undef DEF
98 };
99 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
100
101 static TCGRegSet tcg_target_available_regs[2];
102 static TCGRegSet tcg_target_call_clobber_regs;
103
104 /* XXX: move that inside the context */
105 uint16_t *gen_opc_ptr;
106 TCGArg *gen_opparam_ptr;
107
108 static inline void tcg_out8(TCGContext *s, uint8_t v)
109 {
110     *s->code_ptr++ = v;
111 }
112
113 static inline void tcg_out16(TCGContext *s, uint16_t v)
114 {
115     *(uint16_t *)s->code_ptr = v;
116     s->code_ptr += 2;
117 }
118
119 static inline void tcg_out32(TCGContext *s, uint32_t v)
120 {
121     *(uint32_t *)s->code_ptr = v;
122     s->code_ptr += 4;
123 }
124
125 /* label relocation processing */
126
127 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
128                           int label_index, long addend)
129 {
130     TCGLabel *l;
131     TCGRelocation *r;
132
133     l = &s->labels[label_index];
134     if (l->has_value) {
135         /* FIXME: This may break relocations on RISC targets that
136            modify instruction fields in place.  The caller may not have 
137            written the initial value.  */
138         patch_reloc(code_ptr, type, l->u.value, addend);
139     } else {
140         /* add a new relocation entry */
141         r = tcg_malloc(sizeof(TCGRelocation));
142         r->type = type;
143         r->ptr = code_ptr;
144         r->addend = addend;
145         r->next = l->u.first_reloc;
146         l->u.first_reloc = r;
147     }
148 }
149
150 static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
151 {
152     TCGLabel *l;
153     TCGRelocation *r;
154     tcg_target_long value = (tcg_target_long)ptr;
155
156     l = &s->labels[label_index];
157     if (l->has_value)
158         tcg_abort();
159     r = l->u.first_reloc;
160     while (r != NULL) {
161         patch_reloc(r->ptr, r->type, value, r->addend);
162         r = r->next;
163     }
164     l->has_value = 1;
165     l->u.value = value;
166 }
167
168 int gen_new_label(void)
169 {
170     TCGContext *s = &tcg_ctx;
171     int idx;
172     TCGLabel *l;
173
174     if (s->nb_labels >= TCG_MAX_LABELS)
175         tcg_abort();
176     idx = s->nb_labels++;
177     l = &s->labels[idx];
178     l->has_value = 0;
179     l->u.first_reloc = NULL;
180     return idx;
181 }
182
183 #include "tcg-target.c"
184
185 /* pool based memory allocation */
186 void *tcg_malloc_internal(TCGContext *s, int size)
187 {
188     TCGPool *p;
189     int pool_size;
190     
191     if (size > TCG_POOL_CHUNK_SIZE) {
192         /* big malloc: insert a new pool (XXX: could optimize) */
193         p = g_malloc(sizeof(TCGPool) + size);
194         p->size = size;
195         p->next = s->pool_first_large;
196         s->pool_first_large = p;
197         return p->data;
198     } else {
199         p = s->pool_current;
200         if (!p) {
201             p = s->pool_first;
202             if (!p)
203                 goto new_pool;
204         } else {
205             if (!p->next) {
206             new_pool:
207                 pool_size = TCG_POOL_CHUNK_SIZE;
208                 p = g_malloc(sizeof(TCGPool) + pool_size);
209                 p->size = pool_size;
210                 p->next = NULL;
211                 if (s->pool_current) 
212                     s->pool_current->next = p;
213                 else
214                     s->pool_first = p;
215             } else {
216                 p = p->next;
217             }
218         }
219     }
220     s->pool_current = p;
221     s->pool_cur = p->data + size;
222     s->pool_end = p->data + p->size;
223     return p->data;
224 }
225
226 void tcg_pool_reset(TCGContext *s)
227 {
228     TCGPool *p, *t;
229     for (p = s->pool_first_large; p; p = t) {
230         t = p->next;
231         g_free(p);
232     }
233     s->pool_first_large = NULL;
234     s->pool_cur = s->pool_end = NULL;
235     s->pool_current = NULL;
236 }
237
238 void tcg_context_init(TCGContext *s)
239 {
240     int op, total_args, n;
241     TCGOpDef *def;
242     TCGArgConstraint *args_ct;
243     int *sorted_args;
244
245     memset(s, 0, sizeof(*s));
246     s->temps = s->static_temps;
247     s->nb_globals = 0;
248     
249     /* Count total number of arguments and allocate the corresponding
250        space */
251     total_args = 0;
252     for(op = 0; op < NB_OPS; op++) {
253         def = &tcg_op_defs[op];
254         n = def->nb_iargs + def->nb_oargs;
255         total_args += n;
256     }
257
258     args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
259     sorted_args = g_malloc(sizeof(int) * total_args);
260
261     for(op = 0; op < NB_OPS; op++) {
262         def = &tcg_op_defs[op];
263         def->args_ct = args_ct;
264         def->sorted_args = sorted_args;
265         n = def->nb_iargs + def->nb_oargs;
266         sorted_args += n;
267         args_ct += n;
268     }
269     
270     tcg_target_init(s);
271 }
272
273 void tcg_prologue_init(TCGContext *s)
274 {
275     /* init global prologue and epilogue */
276     s->code_buf = code_gen_prologue;
277     s->code_ptr = s->code_buf;
278     tcg_target_qemu_prologue(s);
279     flush_icache_range((tcg_target_ulong)s->code_buf,
280                        (tcg_target_ulong)s->code_ptr);
281 }
282
283 void tcg_set_frame(TCGContext *s, int reg,
284                    tcg_target_long start, tcg_target_long size)
285 {
286     s->frame_start = start;
287     s->frame_end = start + size;
288     s->frame_reg = reg;
289 }
290
291 void tcg_func_start(TCGContext *s)
292 {
293     int i;
294     tcg_pool_reset(s);
295     s->nb_temps = s->nb_globals;
296     for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
297         s->first_free_temp[i] = -1;
298     s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
299     s->nb_labels = 0;
300     s->current_frame_offset = s->frame_start;
301
302     gen_opc_ptr = gen_opc_buf;
303     gen_opparam_ptr = gen_opparam_buf;
304 }
305
306 static inline void tcg_temp_alloc(TCGContext *s, int n)
307 {
308     if (n > TCG_MAX_TEMPS)
309         tcg_abort();
310 }
311
312 static inline int tcg_global_reg_new_internal(TCGType type, int reg,
313                                               const char *name)
314 {
315     TCGContext *s = &tcg_ctx;
316     TCGTemp *ts;
317     int idx;
318
319 #if TCG_TARGET_REG_BITS == 32
320     if (type != TCG_TYPE_I32)
321         tcg_abort();
322 #endif
323     if (tcg_regset_test_reg(s->reserved_regs, reg))
324         tcg_abort();
325     idx = s->nb_globals;
326     tcg_temp_alloc(s, s->nb_globals + 1);
327     ts = &s->temps[s->nb_globals];
328     ts->base_type = type;
329     ts->type = type;
330     ts->fixed_reg = 1;
331     ts->reg = reg;
332     ts->name = name;
333     s->nb_globals++;
334     tcg_regset_set_reg(s->reserved_regs, reg);
335     return idx;
336 }
337
338 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
339 {
340     int idx;
341
342     idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
343     return MAKE_TCGV_I32(idx);
344 }
345
346 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
347 {
348     int idx;
349
350     idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
351     return MAKE_TCGV_I64(idx);
352 }
353
354 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
355                                               tcg_target_long offset,
356                                               const char *name)
357 {
358     TCGContext *s = &tcg_ctx;
359     TCGTemp *ts;
360     int idx;
361
362     idx = s->nb_globals;
363 #if TCG_TARGET_REG_BITS == 32
364     if (type == TCG_TYPE_I64) {
365         char buf[64];
366         tcg_temp_alloc(s, s->nb_globals + 2);
367         ts = &s->temps[s->nb_globals];
368         ts->base_type = type;
369         ts->type = TCG_TYPE_I32;
370         ts->fixed_reg = 0;
371         ts->mem_allocated = 1;
372         ts->mem_reg = reg;
373 #ifdef TCG_TARGET_WORDS_BIGENDIAN
374         ts->mem_offset = offset + 4;
375 #else
376         ts->mem_offset = offset;
377 #endif
378         pstrcpy(buf, sizeof(buf), name);
379         pstrcat(buf, sizeof(buf), "_0");
380         ts->name = strdup(buf);
381         ts++;
382
383         ts->base_type = type;
384         ts->type = TCG_TYPE_I32;
385         ts->fixed_reg = 0;
386         ts->mem_allocated = 1;
387         ts->mem_reg = reg;
388 #ifdef TCG_TARGET_WORDS_BIGENDIAN
389         ts->mem_offset = offset;
390 #else
391         ts->mem_offset = offset + 4;
392 #endif
393         pstrcpy(buf, sizeof(buf), name);
394         pstrcat(buf, sizeof(buf), "_1");
395         ts->name = strdup(buf);
396
397         s->nb_globals += 2;
398     } else
399 #endif
400     {
401         tcg_temp_alloc(s, s->nb_globals + 1);
402         ts = &s->temps[s->nb_globals];
403         ts->base_type = type;
404         ts->type = type;
405         ts->fixed_reg = 0;
406         ts->mem_allocated = 1;
407         ts->mem_reg = reg;
408         ts->mem_offset = offset;
409         ts->name = name;
410         s->nb_globals++;
411     }
412     return idx;
413 }
414
415 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
416                                 const char *name)
417 {
418     int idx;
419
420     idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
421     return MAKE_TCGV_I32(idx);
422 }
423
424 TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
425                                 const char *name)
426 {
427     int idx;
428
429     idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
430     return MAKE_TCGV_I64(idx);
431 }
432
433 static inline int tcg_temp_new_internal(TCGType type, int temp_local)
434 {
435     TCGContext *s = &tcg_ctx;
436     TCGTemp *ts;
437     int idx, k;
438
439     k = type;
440     if (temp_local)
441         k += TCG_TYPE_COUNT;
442     idx = s->first_free_temp[k];
443     if (idx != -1) {
444         /* There is already an available temp with the
445            right type */
446         ts = &s->temps[idx];
447         s->first_free_temp[k] = ts->next_free_temp;
448         ts->temp_allocated = 1;
449         assert(ts->temp_local == temp_local);
450     } else {
451         idx = s->nb_temps;
452 #if TCG_TARGET_REG_BITS == 32
453         if (type == TCG_TYPE_I64) {
454             tcg_temp_alloc(s, s->nb_temps + 2);
455             ts = &s->temps[s->nb_temps];
456             ts->base_type = type;
457             ts->type = TCG_TYPE_I32;
458             ts->temp_allocated = 1;
459             ts->temp_local = temp_local;
460             ts->name = NULL;
461             ts++;
462             ts->base_type = TCG_TYPE_I32;
463             ts->type = TCG_TYPE_I32;
464             ts->temp_allocated = 1;
465             ts->temp_local = temp_local;
466             ts->name = NULL;
467             s->nb_temps += 2;
468         } else
469 #endif
470         {
471             tcg_temp_alloc(s, s->nb_temps + 1);
472             ts = &s->temps[s->nb_temps];
473             ts->base_type = type;
474             ts->type = type;
475             ts->temp_allocated = 1;
476             ts->temp_local = temp_local;
477             ts->name = NULL;
478             s->nb_temps++;
479         }
480     }
481
482 #if defined(CONFIG_DEBUG_TCG)
483     s->temps_in_use++;
484 #endif
485     return idx;
486 }
487
488 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
489 {
490     int idx;
491
492     idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
493     return MAKE_TCGV_I32(idx);
494 }
495
496 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
497 {
498     int idx;
499
500     idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
501     return MAKE_TCGV_I64(idx);
502 }
503
504 static inline void tcg_temp_free_internal(int idx)
505 {
506     TCGContext *s = &tcg_ctx;
507     TCGTemp *ts;
508     int k;
509
510 #if defined(CONFIG_DEBUG_TCG)
511     s->temps_in_use--;
512     if (s->temps_in_use < 0) {
513         fprintf(stderr, "More temporaries freed than allocated!\n");
514     }
515 #endif
516
517     assert(idx >= s->nb_globals && idx < s->nb_temps);
518     ts = &s->temps[idx];
519     assert(ts->temp_allocated != 0);
520     ts->temp_allocated = 0;
521     k = ts->base_type;
522     if (ts->temp_local)
523         k += TCG_TYPE_COUNT;
524     ts->next_free_temp = s->first_free_temp[k];
525     s->first_free_temp[k] = idx;
526 }
527
528 void tcg_temp_free_i32(TCGv_i32 arg)
529 {
530     tcg_temp_free_internal(GET_TCGV_I32(arg));
531 }
532
533 void tcg_temp_free_i64(TCGv_i64 arg)
534 {
535     tcg_temp_free_internal(GET_TCGV_I64(arg));
536 }
537
538 TCGv_i32 tcg_const_i32(int32_t val)
539 {
540     TCGv_i32 t0;
541     t0 = tcg_temp_new_i32();
542     tcg_gen_movi_i32(t0, val);
543     return t0;
544 }
545
546 TCGv_i64 tcg_const_i64(int64_t val)
547 {
548     TCGv_i64 t0;
549     t0 = tcg_temp_new_i64();
550     tcg_gen_movi_i64(t0, val);
551     return t0;
552 }
553
554 TCGv_i32 tcg_const_local_i32(int32_t val)
555 {
556     TCGv_i32 t0;
557     t0 = tcg_temp_local_new_i32();
558     tcg_gen_movi_i32(t0, val);
559     return t0;
560 }
561
562 TCGv_i64 tcg_const_local_i64(int64_t val)
563 {
564     TCGv_i64 t0;
565     t0 = tcg_temp_local_new_i64();
566     tcg_gen_movi_i64(t0, val);
567     return t0;
568 }
569
570 #if defined(CONFIG_DEBUG_TCG)
571 void tcg_clear_temp_count(void)
572 {
573     TCGContext *s = &tcg_ctx;
574     s->temps_in_use = 0;
575 }
576
577 int tcg_check_temp_count(void)
578 {
579     TCGContext *s = &tcg_ctx;
580     if (s->temps_in_use) {
581         /* Clear the count so that we don't give another
582          * warning immediately next time around.
583          */
584         s->temps_in_use = 0;
585         return 1;
586     }
587     return 0;
588 }
589 #endif
590
591 void tcg_register_helper(void *func, const char *name)
592 {
593     TCGContext *s = &tcg_ctx;
594     int n;
595     if ((s->nb_helpers + 1) > s->allocated_helpers) {
596         n = s->allocated_helpers;
597         if (n == 0) {
598             n = 4;
599         } else {
600             n *= 2;
601         }
602         s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
603         s->allocated_helpers = n;
604     }
605     s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
606     s->helpers[s->nb_helpers].name = name;
607     s->nb_helpers++;
608 }
609
610 /* Note: we convert the 64 bit args to 32 bit and do some alignment
611    and endian swap. Maybe it would be better to do the alignment
612    and endian swap in tcg_reg_alloc_call(). */
613 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
614                    int sizemask, TCGArg ret, int nargs, TCGArg *args)
615 {
616     int i;
617     int real_args;
618     int nb_rets;
619     TCGArg *nparam;
620
621 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
622     for (i = 0; i < nargs; ++i) {
623         int is_64bit = sizemask & (1 << (i+1)*2);
624         int is_signed = sizemask & (2 << (i+1)*2);
625         if (!is_64bit) {
626             TCGv_i64 temp = tcg_temp_new_i64();
627             TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
628             if (is_signed) {
629                 tcg_gen_ext32s_i64(temp, orig);
630             } else {
631                 tcg_gen_ext32u_i64(temp, orig);
632             }
633             args[i] = GET_TCGV_I64(temp);
634         }
635     }
636 #endif /* TCG_TARGET_EXTEND_ARGS */
637
638     *gen_opc_ptr++ = INDEX_op_call;
639     nparam = gen_opparam_ptr++;
640     if (ret != TCG_CALL_DUMMY_ARG) {
641 #if TCG_TARGET_REG_BITS < 64
642         if (sizemask & 1) {
643 #ifdef TCG_TARGET_WORDS_BIGENDIAN
644             *gen_opparam_ptr++ = ret + 1;
645             *gen_opparam_ptr++ = ret;
646 #else
647             *gen_opparam_ptr++ = ret;
648             *gen_opparam_ptr++ = ret + 1;
649 #endif
650             nb_rets = 2;
651         } else
652 #endif
653         {
654             *gen_opparam_ptr++ = ret;
655             nb_rets = 1;
656         }
657     } else {
658         nb_rets = 0;
659     }
660     real_args = 0;
661     for (i = 0; i < nargs; i++) {
662 #if TCG_TARGET_REG_BITS < 64
663         int is_64bit = sizemask & (1 << (i+1)*2);
664         if (is_64bit) {
665 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
666             /* some targets want aligned 64 bit args */
667             if (real_args & 1) {
668                 *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
669                 real_args++;
670             }
671 #endif
672             /* If stack grows up, then we will be placing successive
673                arguments at lower addresses, which means we need to
674                reverse the order compared to how we would normally
675                treat either big or little-endian.  For those arguments
676                that will wind up in registers, this still works for
677                HPPA (the only current STACK_GROWSUP target) since the
678                argument registers are *also* allocated in decreasing
679                order.  If another such target is added, this logic may
680                have to get more complicated to differentiate between
681                stack arguments and register arguments.  */
682 #if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
683             *gen_opparam_ptr++ = args[i] + 1;
684             *gen_opparam_ptr++ = args[i];
685 #else
686             *gen_opparam_ptr++ = args[i];
687             *gen_opparam_ptr++ = args[i] + 1;
688 #endif
689             real_args += 2;
690             continue;
691         }
692 #endif /* TCG_TARGET_REG_BITS < 64 */
693
694         *gen_opparam_ptr++ = args[i];
695         real_args++;
696     }
697     *gen_opparam_ptr++ = GET_TCGV_PTR(func);
698
699     *gen_opparam_ptr++ = flags;
700
701     *nparam = (nb_rets << 16) | (real_args + 1);
702
703     /* total parameters, needed to go backward in the instruction stream */
704     *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
705
706 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
707     for (i = 0; i < nargs; ++i) {
708         int is_64bit = sizemask & (1 << (i+1)*2);
709         if (!is_64bit) {
710             TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
711             tcg_temp_free_i64(temp);
712         }
713     }
714 #endif /* TCG_TARGET_EXTEND_ARGS */
715 }
716
717 #if TCG_TARGET_REG_BITS == 32
718 void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
719                         int c, int right, int arith)
720 {
721     if (c == 0) {
722         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
723         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
724     } else if (c >= 32) {
725         c -= 32;
726         if (right) {
727             if (arith) {
728                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
729                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
730             } else {
731                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
732                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
733             }
734         } else {
735             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
736             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
737         }
738     } else {
739         TCGv_i32 t0, t1;
740
741         t0 = tcg_temp_new_i32();
742         t1 = tcg_temp_new_i32();
743         if (right) {
744             tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
745             if (arith)
746                 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
747             else
748                 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
749             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
750             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
751             tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
752         } else {
753             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
754             /* Note: ret can be the same as arg1, so we use t1 */
755             tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
756             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
757             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
758             tcg_gen_mov_i32(TCGV_LOW(ret), t1);
759         }
760         tcg_temp_free_i32(t0);
761         tcg_temp_free_i32(t1);
762     }
763 }
764 #endif
765
766
767 static void tcg_reg_alloc_start(TCGContext *s)
768 {
769     int i;
770     TCGTemp *ts;
771     for(i = 0; i < s->nb_globals; i++) {
772         ts = &s->temps[i];
773         if (ts->fixed_reg) {
774             ts->val_type = TEMP_VAL_REG;
775         } else {
776             ts->val_type = TEMP_VAL_MEM;
777         }
778     }
779     for(i = s->nb_globals; i < s->nb_temps; i++) {
780         ts = &s->temps[i];
781         ts->val_type = TEMP_VAL_DEAD;
782         ts->mem_allocated = 0;
783         ts->fixed_reg = 0;
784     }
785     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
786         s->reg_to_temp[i] = -1;
787     }
788 }
789
790 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
791                                  int idx)
792 {
793     TCGTemp *ts;
794
795     assert(idx >= 0 && idx < s->nb_temps);
796     ts = &s->temps[idx];
797     assert(ts);
798     if (idx < s->nb_globals) {
799         pstrcpy(buf, buf_size, ts->name);
800     } else {
801         if (ts->temp_local) 
802             snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
803         else
804             snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
805     }
806     return buf;
807 }
808
809 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
810 {
811     return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
812 }
813
814 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
815 {
816     return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
817 }
818
819 static int helper_cmp(const void *p1, const void *p2)
820 {
821     const TCGHelperInfo *th1 = p1;
822     const TCGHelperInfo *th2 = p2;
823     if (th1->func < th2->func)
824         return -1;
825     else if (th1->func == th2->func)
826         return 0;
827     else
828         return 1;
829 }
830
831 /* find helper definition (Note: A hash table would be better) */
832 static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
833 {
834     int m, m_min, m_max;
835     TCGHelperInfo *th;
836     tcg_target_ulong v;
837
838     if (unlikely(!s->helpers_sorted)) {
839         qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
840               helper_cmp);
841         s->helpers_sorted = 1;
842     }
843
844     /* binary search */
845     m_min = 0;
846     m_max = s->nb_helpers - 1;
847     while (m_min <= m_max) {
848         m = (m_min + m_max) >> 1;
849         th = &s->helpers[m];
850         v = th->func;
851         if (v == val)
852             return th;
853         else if (val < v) {
854             m_max = m - 1;
855         } else {
856             m_min = m + 1;
857         }
858     }
859     return NULL;
860 }
861
862 static const char * const cond_name[] =
863 {
864     [TCG_COND_EQ] = "eq",
865     [TCG_COND_NE] = "ne",
866     [TCG_COND_LT] = "lt",
867     [TCG_COND_GE] = "ge",
868     [TCG_COND_LE] = "le",
869     [TCG_COND_GT] = "gt",
870     [TCG_COND_LTU] = "ltu",
871     [TCG_COND_GEU] = "geu",
872     [TCG_COND_LEU] = "leu",
873     [TCG_COND_GTU] = "gtu"
874 };
875
876 void tcg_dump_ops(TCGContext *s, FILE *outfile)
877 {
878     const uint16_t *opc_ptr;
879     const TCGArg *args;
880     TCGArg arg;
881     TCGOpcode c;
882     int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
883     const TCGOpDef *def;
884     char buf[128];
885
886     first_insn = 1;
887     opc_ptr = gen_opc_buf;
888     args = gen_opparam_buf;
889     while (opc_ptr < gen_opc_ptr) {
890         c = *opc_ptr++;
891         def = &tcg_op_defs[c];
892         if (c == INDEX_op_debug_insn_start) {
893             uint64_t pc;
894 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
895             pc = ((uint64_t)args[1] << 32) | args[0];
896 #else
897             pc = args[0];
898 #endif
899             if (!first_insn) 
900                 fprintf(outfile, "\n");
901             fprintf(outfile, " ---- 0x%" PRIx64, pc);
902             first_insn = 0;
903             nb_oargs = def->nb_oargs;
904             nb_iargs = def->nb_iargs;
905             nb_cargs = def->nb_cargs;
906         } else if (c == INDEX_op_call) {
907             TCGArg arg;
908
909             /* variable number of arguments */
910             arg = *args++;
911             nb_oargs = arg >> 16;
912             nb_iargs = arg & 0xffff;
913             nb_cargs = def->nb_cargs;
914
915             fprintf(outfile, " %s ", def->name);
916
917             /* function name */
918             fprintf(outfile, "%s",
919                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
920             /* flags */
921             fprintf(outfile, ",$0x%" TCG_PRIlx,
922                     args[nb_oargs + nb_iargs]);
923             /* nb out args */
924             fprintf(outfile, ",$%d", nb_oargs);
925             for(i = 0; i < nb_oargs; i++) {
926                 fprintf(outfile, ",");
927                 fprintf(outfile, "%s",
928                         tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
929             }
930             for(i = 0; i < (nb_iargs - 1); i++) {
931                 fprintf(outfile, ",");
932                 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
933                     fprintf(outfile, "<dummy>");
934                 } else {
935                     fprintf(outfile, "%s",
936                             tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
937                 }
938             }
939         } else if (c == INDEX_op_movi_i32 
940 #if TCG_TARGET_REG_BITS == 64
941                    || c == INDEX_op_movi_i64
942 #endif
943                    ) {
944             tcg_target_ulong val;
945             TCGHelperInfo *th;
946
947             nb_oargs = def->nb_oargs;
948             nb_iargs = def->nb_iargs;
949             nb_cargs = def->nb_cargs;
950             fprintf(outfile, " %s %s,$", def->name, 
951                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
952             val = args[1];
953             th = tcg_find_helper(s, val);
954             if (th) {
955                 fprintf(outfile, "%s", th->name);
956             } else {
957                 if (c == INDEX_op_movi_i32)
958                     fprintf(outfile, "0x%x", (uint32_t)val);
959                 else
960                     fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
961             }
962         } else {
963             fprintf(outfile, " %s ", def->name);
964             if (c == INDEX_op_nopn) {
965                 /* variable number of arguments */
966                 nb_cargs = *args;
967                 nb_oargs = 0;
968                 nb_iargs = 0;
969             } else {
970                 nb_oargs = def->nb_oargs;
971                 nb_iargs = def->nb_iargs;
972                 nb_cargs = def->nb_cargs;
973             }
974             
975             k = 0;
976             for(i = 0; i < nb_oargs; i++) {
977                 if (k != 0)
978                     fprintf(outfile, ",");
979                 fprintf(outfile, "%s",
980                         tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
981             }
982             for(i = 0; i < nb_iargs; i++) {
983                 if (k != 0)
984                     fprintf(outfile, ",");
985                 fprintf(outfile, "%s",
986                         tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
987             }
988             switch (c) {
989             case INDEX_op_brcond_i32:
990 #if TCG_TARGET_REG_BITS == 32
991             case INDEX_op_brcond2_i32:
992 #elif TCG_TARGET_REG_BITS == 64
993             case INDEX_op_brcond_i64:
994 #endif
995             case INDEX_op_setcond_i32:
996 #if TCG_TARGET_REG_BITS == 32
997             case INDEX_op_setcond2_i32:
998 #elif TCG_TARGET_REG_BITS == 64
999             case INDEX_op_setcond_i64:
1000 #endif
1001                 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
1002                     fprintf(outfile, ",%s", cond_name[args[k++]]);
1003                 else
1004                     fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
1005                 i = 1;
1006                 break;
1007             default:
1008                 i = 0;
1009                 break;
1010             }
1011             for(; i < nb_cargs; i++) {
1012                 if (k != 0)
1013                     fprintf(outfile, ",");
1014                 arg = args[k++];
1015                 fprintf(outfile, "$0x%" TCG_PRIlx, arg);
1016             }
1017         }
1018         fprintf(outfile, "\n");
1019         args += nb_iargs + nb_oargs + nb_cargs;
1020     }
1021 }
1022
1023 /* we give more priority to constraints with less registers */
1024 static int get_constraint_priority(const TCGOpDef *def, int k)
1025 {
1026     const TCGArgConstraint *arg_ct;
1027
1028     int i, n;
1029     arg_ct = &def->args_ct[k];
1030     if (arg_ct->ct & TCG_CT_ALIAS) {
1031         /* an alias is equivalent to a single register */
1032         n = 1;
1033     } else {
1034         if (!(arg_ct->ct & TCG_CT_REG))
1035             return 0;
1036         n = 0;
1037         for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1038             if (tcg_regset_test_reg(arg_ct->u.regs, i))
1039                 n++;
1040         }
1041     }
1042     return TCG_TARGET_NB_REGS - n + 1;
1043 }
1044
1045 /* sort from highest priority to lowest */
1046 static void sort_constraints(TCGOpDef *def, int start, int n)
1047 {
1048     int i, j, p1, p2, tmp;
1049
1050     for(i = 0; i < n; i++)
1051         def->sorted_args[start + i] = start + i;
1052     if (n <= 1)
1053         return;
1054     for(i = 0; i < n - 1; i++) {
1055         for(j = i + 1; j < n; j++) {
1056             p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1057             p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1058             if (p1 < p2) {
1059                 tmp = def->sorted_args[start + i];
1060                 def->sorted_args[start + i] = def->sorted_args[start + j];
1061                 def->sorted_args[start + j] = tmp;
1062             }
1063         }
1064     }
1065 }
1066
1067 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1068 {
1069     TCGOpcode op;
1070     TCGOpDef *def;
1071     const char *ct_str;
1072     int i, nb_args;
1073
1074     for(;;) {
1075         if (tdefs->op == (TCGOpcode)-1)
1076             break;
1077         op = tdefs->op;
1078         assert((unsigned)op < NB_OPS);
1079         def = &tcg_op_defs[op];
1080 #if defined(CONFIG_DEBUG_TCG)
1081         /* Duplicate entry in op definitions? */
1082         assert(!def->used);
1083         def->used = 1;
1084 #endif
1085         nb_args = def->nb_iargs + def->nb_oargs;
1086         for(i = 0; i < nb_args; i++) {
1087             ct_str = tdefs->args_ct_str[i];
1088             /* Incomplete TCGTargetOpDef entry? */
1089             assert(ct_str != NULL);
1090             tcg_regset_clear(def->args_ct[i].u.regs);
1091             def->args_ct[i].ct = 0;
1092             if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1093                 int oarg;
1094                 oarg = ct_str[0] - '0';
1095                 assert(oarg < def->nb_oargs);
1096                 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1097                 /* TCG_CT_ALIAS is for the output arguments. The input
1098                    argument is tagged with TCG_CT_IALIAS. */
1099                 def->args_ct[i] = def->args_ct[oarg];
1100                 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1101                 def->args_ct[oarg].alias_index = i;
1102                 def->args_ct[i].ct |= TCG_CT_IALIAS;
1103                 def->args_ct[i].alias_index = oarg;
1104             } else {
1105                 for(;;) {
1106                     if (*ct_str == '\0')
1107                         break;
1108                     switch(*ct_str) {
1109                     case 'i':
1110                         def->args_ct[i].ct |= TCG_CT_CONST;
1111                         ct_str++;
1112                         break;
1113                     default:
1114                         if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1115                             fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1116                                     ct_str, i, def->name);
1117                             exit(1);
1118                         }
1119                     }
1120                 }
1121             }
1122         }
1123
1124         /* TCGTargetOpDef entry with too much information? */
1125         assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1126
1127         /* sort the constraints (XXX: this is just an heuristic) */
1128         sort_constraints(def, 0, def->nb_oargs);
1129         sort_constraints(def, def->nb_oargs, def->nb_iargs);
1130
1131 #if 0
1132         {
1133             int i;
1134
1135             printf("%s: sorted=", def->name);
1136             for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1137                 printf(" %d", def->sorted_args[i]);
1138             printf("\n");
1139         }
1140 #endif
1141         tdefs++;
1142     }
1143
1144 #if defined(CONFIG_DEBUG_TCG)
1145     i = 0;
1146     for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1147         const TCGOpDef *def = &tcg_op_defs[op];
1148         if (op < INDEX_op_call
1149             || op == INDEX_op_debug_insn_start
1150             || (def->flags & TCG_OPF_NOT_PRESENT)) {
1151             /* Wrong entry in op definitions? */
1152             if (def->used) {
1153                 fprintf(stderr, "Invalid op definition for %s\n", def->name);
1154                 i = 1;
1155             }
1156         } else {
1157             /* Missing entry in op definitions? */
1158             if (!def->used) {
1159                 fprintf(stderr, "Missing op definition for %s\n", def->name);
1160                 i = 1;
1161             }
1162         }
1163     }
1164     if (i == 1) {
1165         tcg_abort();
1166     }
1167 #endif
1168 }
1169
1170 #ifdef USE_LIVENESS_ANALYSIS
1171
1172 /* set a nop for an operation using 'nb_args' */
1173 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
1174                                TCGArg *args, int nb_args)
1175 {
1176     if (nb_args == 0) {
1177         *opc_ptr = INDEX_op_nop;
1178     } else {
1179         *opc_ptr = INDEX_op_nopn;
1180         args[0] = nb_args;
1181         args[nb_args - 1] = nb_args;
1182     }
1183 }
1184
1185 /* liveness analysis: end of function: globals are live, temps are
1186    dead. */
1187 /* XXX: at this stage, not used as there would be little gains because
1188    most TBs end with a conditional jump. */
1189 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
1190 {
1191     memset(dead_temps, 0, s->nb_globals);
1192     memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
1193 }
1194
1195 /* liveness analysis: end of basic block: globals are live, temps are
1196    dead, local temps are live. */
1197 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1198 {
1199     int i;
1200     TCGTemp *ts;
1201
1202     memset(dead_temps, 0, s->nb_globals);
1203     ts = &s->temps[s->nb_globals];
1204     for(i = s->nb_globals; i < s->nb_temps; i++) {
1205         if (ts->temp_local)
1206             dead_temps[i] = 0;
1207         else
1208             dead_temps[i] = 1;
1209         ts++;
1210     }
1211 }
1212
1213 /* Liveness analysis : update the opc_dead_args array to tell if a
1214    given input arguments is dead. Instructions updating dead
1215    temporaries are removed. */
1216 static void tcg_liveness_analysis(TCGContext *s)
1217 {
1218     int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1219     TCGOpcode op;
1220     TCGArg *args;
1221     const TCGOpDef *def;
1222     uint8_t *dead_temps;
1223     unsigned int dead_args;
1224     
1225     gen_opc_ptr++; /* skip end */
1226
1227     nb_ops = gen_opc_ptr - gen_opc_buf;
1228
1229     s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1230     
1231     dead_temps = tcg_malloc(s->nb_temps);
1232     memset(dead_temps, 1, s->nb_temps);
1233
1234     args = gen_opparam_ptr;
1235     op_index = nb_ops - 1;
1236     while (op_index >= 0) {
1237         op = gen_opc_buf[op_index];
1238         def = &tcg_op_defs[op];
1239         switch(op) {
1240         case INDEX_op_call:
1241             {
1242                 int call_flags;
1243
1244                 nb_args = args[-1];
1245                 args -= nb_args;
1246                 nb_iargs = args[0] & 0xffff;
1247                 nb_oargs = args[0] >> 16;
1248                 args++;
1249                 call_flags = args[nb_oargs + nb_iargs];
1250
1251                 /* pure functions can be removed if their result is not
1252                    used */
1253                 if (call_flags & TCG_CALL_PURE) {
1254                     for(i = 0; i < nb_oargs; i++) {
1255                         arg = args[i];
1256                         if (!dead_temps[arg])
1257                             goto do_not_remove_call;
1258                     }
1259                     tcg_set_nop(s, gen_opc_buf + op_index, 
1260                                 args - 1, nb_args);
1261                 } else {
1262                 do_not_remove_call:
1263
1264                     /* output args are dead */
1265                     dead_args = 0;
1266                     for(i = 0; i < nb_oargs; i++) {
1267                         arg = args[i];
1268                         if (dead_temps[arg]) {
1269                             dead_args |= (1 << i);
1270                         }
1271                         dead_temps[arg] = 1;
1272                     }
1273                     
1274                     if (!(call_flags & TCG_CALL_CONST)) {
1275                         /* globals are live (they may be used by the call) */
1276                         memset(dead_temps, 0, s->nb_globals);
1277                     }
1278
1279                     /* input args are live */
1280                     for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1281                         arg = args[i];
1282                         if (arg != TCG_CALL_DUMMY_ARG) {
1283                             if (dead_temps[arg]) {
1284                                 dead_args |= (1 << i);
1285                             }
1286                             dead_temps[arg] = 0;
1287                         }
1288                     }
1289                     s->op_dead_args[op_index] = dead_args;
1290                 }
1291                 args--;
1292             }
1293             break;
1294         case INDEX_op_set_label:
1295             args--;
1296             /* mark end of basic block */
1297             tcg_la_bb_end(s, dead_temps);
1298             break;
1299         case INDEX_op_debug_insn_start:
1300             args -= def->nb_args;
1301             break;
1302         case INDEX_op_nopn:
1303             nb_args = args[-1];
1304             args -= nb_args;
1305             break;
1306         case INDEX_op_discard:
1307             args--;
1308             /* mark the temporary as dead */
1309             dead_temps[args[0]] = 1;
1310             break;
1311         case INDEX_op_end:
1312             break;
1313             /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1314         default:
1315             args -= def->nb_args;
1316             nb_iargs = def->nb_iargs;
1317             nb_oargs = def->nb_oargs;
1318
1319             /* Test if the operation can be removed because all
1320                its outputs are dead. We assume that nb_oargs == 0
1321                implies side effects */
1322             if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1323                 for(i = 0; i < nb_oargs; i++) {
1324                     arg = args[i];
1325                     if (!dead_temps[arg])
1326                         goto do_not_remove;
1327                 }
1328                 tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1329 #ifdef CONFIG_PROFILER
1330                 s->del_op_count++;
1331 #endif
1332             } else {
1333             do_not_remove:
1334
1335                 /* output args are dead */
1336                 dead_args = 0;
1337                 for(i = 0; i < nb_oargs; i++) {
1338                     arg = args[i];
1339                     if (dead_temps[arg]) {
1340                         dead_args |= (1 << i);
1341                     }
1342                     dead_temps[arg] = 1;
1343                 }
1344
1345                 /* if end of basic block, update */
1346                 if (def->flags & TCG_OPF_BB_END) {
1347                     tcg_la_bb_end(s, dead_temps);
1348                 } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1349                     /* globals are live */
1350                     memset(dead_temps, 0, s->nb_globals);
1351                 }
1352
1353                 /* input args are live */
1354                 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1355                     arg = args[i];
1356                     if (dead_temps[arg]) {
1357                         dead_args |= (1 << i);
1358                     }
1359                     dead_temps[arg] = 0;
1360                 }
1361                 s->op_dead_args[op_index] = dead_args;
1362             }
1363             break;
1364         }
1365         op_index--;
1366     }
1367
1368     if (args != gen_opparam_buf)
1369         tcg_abort();
1370 }
1371 #else
1372 /* dummy liveness analysis */
1373 static void tcg_liveness_analysis(TCGContext *s)
1374 {
1375     int nb_ops;
1376     nb_ops = gen_opc_ptr - gen_opc_buf;
1377
1378     s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1379     memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1380 }
1381 #endif
1382
1383 #ifndef NDEBUG
1384 static void dump_regs(TCGContext *s)
1385 {
1386     TCGTemp *ts;
1387     int i;
1388     char buf[64];
1389
1390     for(i = 0; i < s->nb_temps; i++) {
1391         ts = &s->temps[i];
1392         printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1393         switch(ts->val_type) {
1394         case TEMP_VAL_REG:
1395             printf("%s", tcg_target_reg_names[ts->reg]);
1396             break;
1397         case TEMP_VAL_MEM:
1398             printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1399             break;
1400         case TEMP_VAL_CONST:
1401             printf("$0x%" TCG_PRIlx, ts->val);
1402             break;
1403         case TEMP_VAL_DEAD:
1404             printf("D");
1405             break;
1406         default:
1407             printf("???");
1408             break;
1409         }
1410         printf("\n");
1411     }
1412
1413     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1414         if (s->reg_to_temp[i] >= 0) {
1415             printf("%s: %s\n", 
1416                    tcg_target_reg_names[i], 
1417                    tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1418         }
1419     }
1420 }
1421
1422 static void check_regs(TCGContext *s)
1423 {
1424     int reg, k;
1425     TCGTemp *ts;
1426     char buf[64];
1427
1428     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1429         k = s->reg_to_temp[reg];
1430         if (k >= 0) {
1431             ts = &s->temps[k];
1432             if (ts->val_type != TEMP_VAL_REG ||
1433                 ts->reg != reg) {
1434                 printf("Inconsistency for register %s:\n", 
1435                        tcg_target_reg_names[reg]);
1436                 goto fail;
1437             }
1438         }
1439     }
1440     for(k = 0; k < s->nb_temps; k++) {
1441         ts = &s->temps[k];
1442         if (ts->val_type == TEMP_VAL_REG &&
1443             !ts->fixed_reg &&
1444             s->reg_to_temp[ts->reg] != k) {
1445                 printf("Inconsistency for temp %s:\n", 
1446                        tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1447         fail:
1448                 printf("reg state:\n");
1449                 dump_regs(s);
1450                 tcg_abort();
1451         }
1452     }
1453 }
1454 #endif
1455
1456 static void temp_allocate_frame(TCGContext *s, int temp)
1457 {
1458     TCGTemp *ts;
1459     ts = &s->temps[temp];
1460 #ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
1461     s->current_frame_offset = (s->current_frame_offset +
1462                                (tcg_target_long)sizeof(tcg_target_long) - 1) &
1463         ~(sizeof(tcg_target_long) - 1);
1464 #endif
1465     if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1466         s->frame_end) {
1467         tcg_abort();
1468     }
1469     ts->mem_offset = s->current_frame_offset;
1470     ts->mem_reg = s->frame_reg;
1471     ts->mem_allocated = 1;
1472     s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1473 }
1474
1475 /* free register 'reg' by spilling the corresponding temporary if necessary */
1476 static void tcg_reg_free(TCGContext *s, int reg)
1477 {
1478     TCGTemp *ts;
1479     int temp;
1480
1481     temp = s->reg_to_temp[reg];
1482     if (temp != -1) {
1483         ts = &s->temps[temp];
1484         assert(ts->val_type == TEMP_VAL_REG);
1485         if (!ts->mem_coherent) {
1486             if (!ts->mem_allocated) 
1487                 temp_allocate_frame(s, temp);
1488             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1489         }
1490         ts->val_type = TEMP_VAL_MEM;
1491         s->reg_to_temp[reg] = -1;
1492     }
1493 }
1494
1495 /* Allocate a register belonging to reg1 & ~reg2 */
1496 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1497 {
1498     int i, reg;
1499     TCGRegSet reg_ct;
1500
1501     tcg_regset_andnot(reg_ct, reg1, reg2);
1502
1503     /* first try free registers */
1504     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1505         reg = tcg_target_reg_alloc_order[i];
1506         if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1507             return reg;
1508     }
1509
1510     /* XXX: do better spill choice */
1511     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1512         reg = tcg_target_reg_alloc_order[i];
1513         if (tcg_regset_test_reg(reg_ct, reg)) {
1514             tcg_reg_free(s, reg);
1515             return reg;
1516         }
1517     }
1518
1519     tcg_abort();
1520 }
1521
1522 /* save a temporary to memory. 'allocated_regs' is used in case a
1523    temporary registers needs to be allocated to store a constant. */
1524 static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1525 {
1526     TCGTemp *ts;
1527     int reg;
1528
1529     ts = &s->temps[temp];
1530     if (!ts->fixed_reg) {
1531         switch(ts->val_type) {
1532         case TEMP_VAL_REG:
1533             tcg_reg_free(s, ts->reg);
1534             break;
1535         case TEMP_VAL_DEAD:
1536             ts->val_type = TEMP_VAL_MEM;
1537             break;
1538         case TEMP_VAL_CONST:
1539             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1540                                 allocated_regs);
1541             if (!ts->mem_allocated) 
1542                 temp_allocate_frame(s, temp);
1543             tcg_out_movi(s, ts->type, reg, ts->val);
1544             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1545             ts->val_type = TEMP_VAL_MEM;
1546             break;
1547         case TEMP_VAL_MEM:
1548             break;
1549         default:
1550             tcg_abort();
1551         }
1552     }
1553 }
1554
1555 /* save globals to their canonical location and assume they can be
1556    modified be the following code. 'allocated_regs' is used in case a
1557    temporary registers needs to be allocated to store a constant. */
1558 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1559 {
1560     int i;
1561
1562     for(i = 0; i < s->nb_globals; i++) {
1563         temp_save(s, i, allocated_regs);
1564     }
1565 }
1566
1567 /* at the end of a basic block, we assume all temporaries are dead and
1568    all globals are stored at their canonical location. */
1569 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1570 {
1571     TCGTemp *ts;
1572     int i;
1573
1574     for(i = s->nb_globals; i < s->nb_temps; i++) {
1575         ts = &s->temps[i];
1576         if (ts->temp_local) {
1577             temp_save(s, i, allocated_regs);
1578         } else {
1579             if (ts->val_type == TEMP_VAL_REG) {
1580                 s->reg_to_temp[ts->reg] = -1;
1581             }
1582             ts->val_type = TEMP_VAL_DEAD;
1583         }
1584     }
1585
1586     save_globals(s, allocated_regs);
1587 }
1588
1589 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1590
1591 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1592 {
1593     TCGTemp *ots;
1594     tcg_target_ulong val;
1595
1596     ots = &s->temps[args[0]];
1597     val = args[1];
1598
1599     if (ots->fixed_reg) {
1600         /* for fixed registers, we do not do any constant
1601            propagation */
1602         tcg_out_movi(s, ots->type, ots->reg, val);
1603     } else {
1604         /* The movi is not explicitly generated here */
1605         if (ots->val_type == TEMP_VAL_REG)
1606             s->reg_to_temp[ots->reg] = -1;
1607         ots->val_type = TEMP_VAL_CONST;
1608         ots->val = val;
1609     }
1610 }
1611
1612 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1613                               const TCGArg *args,
1614                               unsigned int dead_args)
1615 {
1616     TCGTemp *ts, *ots;
1617     int reg;
1618     const TCGArgConstraint *arg_ct;
1619
1620     ots = &s->temps[args[0]];
1621     ts = &s->temps[args[1]];
1622     arg_ct = &def->args_ct[0];
1623
1624     /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1625     if (ts->val_type == TEMP_VAL_REG) {
1626         if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1627             /* the mov can be suppressed */
1628             if (ots->val_type == TEMP_VAL_REG)
1629                 s->reg_to_temp[ots->reg] = -1;
1630             reg = ts->reg;
1631             s->reg_to_temp[reg] = -1;
1632             ts->val_type = TEMP_VAL_DEAD;
1633         } else {
1634             if (ots->val_type == TEMP_VAL_REG) {
1635                 reg = ots->reg;
1636             } else {
1637                 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1638             }
1639             if (ts->reg != reg) {
1640                 tcg_out_mov(s, ots->type, reg, ts->reg);
1641             }
1642         }
1643     } else if (ts->val_type == TEMP_VAL_MEM) {
1644         if (ots->val_type == TEMP_VAL_REG) {
1645             reg = ots->reg;
1646         } else {
1647             reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1648         }
1649         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1650     } else if (ts->val_type == TEMP_VAL_CONST) {
1651         if (ots->fixed_reg) {
1652             reg = ots->reg;
1653             tcg_out_movi(s, ots->type, reg, ts->val);
1654         } else {
1655             /* propagate constant */
1656             if (ots->val_type == TEMP_VAL_REG)
1657                 s->reg_to_temp[ots->reg] = -1;
1658             ots->val_type = TEMP_VAL_CONST;
1659             ots->val = ts->val;
1660             return;
1661         }
1662     } else {
1663         tcg_abort();
1664     }
1665     s->reg_to_temp[reg] = args[0];
1666     ots->reg = reg;
1667     ots->val_type = TEMP_VAL_REG;
1668     ots->mem_coherent = 0;
1669 }
1670
1671 static void tcg_reg_alloc_op(TCGContext *s, 
1672                              const TCGOpDef *def, TCGOpcode opc,
1673                              const TCGArg *args,
1674                              unsigned int dead_args)
1675 {
1676     TCGRegSet allocated_regs;
1677     int i, k, nb_iargs, nb_oargs, reg;
1678     TCGArg arg;
1679     const TCGArgConstraint *arg_ct;
1680     TCGTemp *ts;
1681     TCGArg new_args[TCG_MAX_OP_ARGS];
1682     int const_args[TCG_MAX_OP_ARGS];
1683
1684     nb_oargs = def->nb_oargs;
1685     nb_iargs = def->nb_iargs;
1686
1687     /* copy constants */
1688     memcpy(new_args + nb_oargs + nb_iargs, 
1689            args + nb_oargs + nb_iargs, 
1690            sizeof(TCGArg) * def->nb_cargs);
1691
1692     /* satisfy input constraints */ 
1693     tcg_regset_set(allocated_regs, s->reserved_regs);
1694     for(k = 0; k < nb_iargs; k++) {
1695         i = def->sorted_args[nb_oargs + k];
1696         arg = args[i];
1697         arg_ct = &def->args_ct[i];
1698         ts = &s->temps[arg];
1699         if (ts->val_type == TEMP_VAL_MEM) {
1700             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1701             tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1702             ts->val_type = TEMP_VAL_REG;
1703             ts->reg = reg;
1704             ts->mem_coherent = 1;
1705             s->reg_to_temp[reg] = arg;
1706         } else if (ts->val_type == TEMP_VAL_CONST) {
1707             if (tcg_target_const_match(ts->val, arg_ct)) {
1708                 /* constant is OK for instruction */
1709                 const_args[i] = 1;
1710                 new_args[i] = ts->val;
1711                 goto iarg_end;
1712             } else {
1713                 /* need to move to a register */
1714                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1715                 tcg_out_movi(s, ts->type, reg, ts->val);
1716                 ts->val_type = TEMP_VAL_REG;
1717                 ts->reg = reg;
1718                 ts->mem_coherent = 0;
1719                 s->reg_to_temp[reg] = arg;
1720             }
1721         }
1722         assert(ts->val_type == TEMP_VAL_REG);
1723         if (arg_ct->ct & TCG_CT_IALIAS) {
1724             if (ts->fixed_reg) {
1725                 /* if fixed register, we must allocate a new register
1726                    if the alias is not the same register */
1727                 if (arg != args[arg_ct->alias_index])
1728                     goto allocate_in_reg;
1729             } else {
1730                 /* if the input is aliased to an output and if it is
1731                    not dead after the instruction, we must allocate
1732                    a new register and move it */
1733                 if (!IS_DEAD_ARG(i)) {
1734                     goto allocate_in_reg;
1735                 }
1736             }
1737         }
1738         reg = ts->reg;
1739         if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1740             /* nothing to do : the constraint is satisfied */
1741         } else {
1742         allocate_in_reg:
1743             /* allocate a new register matching the constraint 
1744                and move the temporary register into it */
1745             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1746             tcg_out_mov(s, ts->type, reg, ts->reg);
1747         }
1748         new_args[i] = reg;
1749         const_args[i] = 0;
1750         tcg_regset_set_reg(allocated_regs, reg);
1751     iarg_end: ;
1752     }
1753     
1754     if (def->flags & TCG_OPF_BB_END) {
1755         tcg_reg_alloc_bb_end(s, allocated_regs);
1756     } else {
1757         /* mark dead temporaries and free the associated registers */
1758         for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1759             arg = args[i];
1760             if (IS_DEAD_ARG(i)) {
1761                 ts = &s->temps[arg];
1762                 if (!ts->fixed_reg) {
1763                     if (ts->val_type == TEMP_VAL_REG)
1764                         s->reg_to_temp[ts->reg] = -1;
1765                     ts->val_type = TEMP_VAL_DEAD;
1766                 }
1767             }
1768         }
1769         
1770         if (def->flags & TCG_OPF_CALL_CLOBBER) {
1771             /* XXX: permit generic clobber register list ? */ 
1772             for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1773                 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1774                     tcg_reg_free(s, reg);
1775                 }
1776             }
1777             /* XXX: for load/store we could do that only for the slow path
1778                (i.e. when a memory callback is called) */
1779             
1780             /* store globals and free associated registers (we assume the insn
1781                can modify any global. */
1782             save_globals(s, allocated_regs);
1783         }
1784         
1785         /* satisfy the output constraints */
1786         tcg_regset_set(allocated_regs, s->reserved_regs);
1787         for(k = 0; k < nb_oargs; k++) {
1788             i = def->sorted_args[k];
1789             arg = args[i];
1790             arg_ct = &def->args_ct[i];
1791             ts = &s->temps[arg];
1792             if (arg_ct->ct & TCG_CT_ALIAS) {
1793                 reg = new_args[arg_ct->alias_index];
1794             } else {
1795                 /* if fixed register, we try to use it */
1796                 reg = ts->reg;
1797                 if (ts->fixed_reg &&
1798                     tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1799                     goto oarg_end;
1800                 }
1801                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1802             }
1803             tcg_regset_set_reg(allocated_regs, reg);
1804             /* if a fixed register is used, then a move will be done afterwards */
1805             if (!ts->fixed_reg) {
1806                 if (ts->val_type == TEMP_VAL_REG)
1807                     s->reg_to_temp[ts->reg] = -1;
1808                 if (IS_DEAD_ARG(i)) {
1809                     ts->val_type = TEMP_VAL_DEAD;
1810                 } else {
1811                     ts->val_type = TEMP_VAL_REG;
1812                     ts->reg = reg;
1813                     /* temp value is modified, so the value kept in memory is
1814                        potentially not the same */
1815                     ts->mem_coherent = 0;
1816                     s->reg_to_temp[reg] = arg;
1817                }
1818             }
1819         oarg_end:
1820             new_args[i] = reg;
1821         }
1822     }
1823
1824     /* emit instruction */
1825     tcg_out_op(s, opc, new_args, const_args);
1826     
1827     /* move the outputs in the correct register if needed */
1828     for(i = 0; i < nb_oargs; i++) {
1829         ts = &s->temps[args[i]];
1830         reg = new_args[i];
1831         if (ts->fixed_reg && ts->reg != reg) {
1832             tcg_out_mov(s, ts->type, ts->reg, reg);
1833         }
1834     }
1835 }
1836
1837 #ifdef TCG_TARGET_STACK_GROWSUP
1838 #define STACK_DIR(x) (-(x))
1839 #else
1840 #define STACK_DIR(x) (x)
1841 #endif
1842
1843 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1844                               TCGOpcode opc, const TCGArg *args,
1845                               unsigned int dead_args)
1846 {
1847     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1848     TCGArg arg, func_arg;
1849     TCGTemp *ts;
1850     tcg_target_long stack_offset, call_stack_size, func_addr;
1851     int const_func_arg, allocate_args;
1852     TCGRegSet allocated_regs;
1853     const TCGArgConstraint *arg_ct;
1854
1855     arg = *args++;
1856
1857     nb_oargs = arg >> 16;
1858     nb_iargs = arg & 0xffff;
1859     nb_params = nb_iargs - 1;
1860
1861     flags = args[nb_oargs + nb_iargs];
1862
1863     nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1864     if (nb_regs > nb_params)
1865         nb_regs = nb_params;
1866
1867     /* assign stack slots first */
1868     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1869     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1870         ~(TCG_TARGET_STACK_ALIGN - 1);
1871     allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1872     if (allocate_args) {
1873         /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1874            preallocate call stack */
1875         tcg_abort();
1876     }
1877
1878     stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1879     for(i = nb_regs; i < nb_params; i++) {
1880         arg = args[nb_oargs + i];
1881 #ifdef TCG_TARGET_STACK_GROWSUP
1882         stack_offset -= sizeof(tcg_target_long);
1883 #endif
1884         if (arg != TCG_CALL_DUMMY_ARG) {
1885             ts = &s->temps[arg];
1886             if (ts->val_type == TEMP_VAL_REG) {
1887                 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1888             } else if (ts->val_type == TEMP_VAL_MEM) {
1889                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1890                                     s->reserved_regs);
1891                 /* XXX: not correct if reading values from the stack */
1892                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1893                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1894             } else if (ts->val_type == TEMP_VAL_CONST) {
1895                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1896                                     s->reserved_regs);
1897                 /* XXX: sign extend may be needed on some targets */
1898                 tcg_out_movi(s, ts->type, reg, ts->val);
1899                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1900             } else {
1901                 tcg_abort();
1902             }
1903         }
1904 #ifndef TCG_TARGET_STACK_GROWSUP
1905         stack_offset += sizeof(tcg_target_long);
1906 #endif
1907     }
1908     
1909     /* assign input registers */
1910     tcg_regset_set(allocated_regs, s->reserved_regs);
1911     for(i = 0; i < nb_regs; i++) {
1912         arg = args[nb_oargs + i];
1913         if (arg != TCG_CALL_DUMMY_ARG) {
1914             ts = &s->temps[arg];
1915             reg = tcg_target_call_iarg_regs[i];
1916             tcg_reg_free(s, reg);
1917             if (ts->val_type == TEMP_VAL_REG) {
1918                 if (ts->reg != reg) {
1919                     tcg_out_mov(s, ts->type, reg, ts->reg);
1920                 }
1921             } else if (ts->val_type == TEMP_VAL_MEM) {
1922                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1923             } else if (ts->val_type == TEMP_VAL_CONST) {
1924                 /* XXX: sign extend ? */
1925                 tcg_out_movi(s, ts->type, reg, ts->val);
1926             } else {
1927                 tcg_abort();
1928             }
1929             tcg_regset_set_reg(allocated_regs, reg);
1930         }
1931     }
1932     
1933     /* assign function address */
1934     func_arg = args[nb_oargs + nb_iargs - 1];
1935     arg_ct = &def->args_ct[0];
1936     ts = &s->temps[func_arg];
1937     func_addr = ts->val;
1938     const_func_arg = 0;
1939     if (ts->val_type == TEMP_VAL_MEM) {
1940         reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1941         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1942         func_arg = reg;
1943         tcg_regset_set_reg(allocated_regs, reg);
1944     } else if (ts->val_type == TEMP_VAL_REG) {
1945         reg = ts->reg;
1946         if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1947             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1948             tcg_out_mov(s, ts->type, reg, ts->reg);
1949         }
1950         func_arg = reg;
1951         tcg_regset_set_reg(allocated_regs, reg);
1952     } else if (ts->val_type == TEMP_VAL_CONST) {
1953         if (tcg_target_const_match(func_addr, arg_ct)) {
1954             const_func_arg = 1;
1955             func_arg = func_addr;
1956         } else {
1957             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1958             tcg_out_movi(s, ts->type, reg, func_addr);
1959             func_arg = reg;
1960             tcg_regset_set_reg(allocated_regs, reg);
1961         }
1962     } else {
1963         tcg_abort();
1964     }
1965         
1966     
1967     /* mark dead temporaries and free the associated registers */
1968     for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1969         arg = args[i];
1970         if (IS_DEAD_ARG(i)) {
1971             ts = &s->temps[arg];
1972             if (!ts->fixed_reg) {
1973                 if (ts->val_type == TEMP_VAL_REG)
1974                     s->reg_to_temp[ts->reg] = -1;
1975                 ts->val_type = TEMP_VAL_DEAD;
1976             }
1977         }
1978     }
1979     
1980     /* clobber call registers */
1981     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1982         if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1983             tcg_reg_free(s, reg);
1984         }
1985     }
1986     
1987     /* store globals and free associated registers (we assume the call
1988        can modify any global. */
1989     if (!(flags & TCG_CALL_CONST)) {
1990         save_globals(s, allocated_regs);
1991     }
1992
1993     tcg_out_op(s, opc, &func_arg, &const_func_arg);
1994
1995     /* assign output registers and emit moves if needed */
1996     for(i = 0; i < nb_oargs; i++) {
1997         arg = args[i];
1998         ts = &s->temps[arg];
1999         reg = tcg_target_call_oarg_regs[i];
2000         assert(s->reg_to_temp[reg] == -1);
2001         if (ts->fixed_reg) {
2002             if (ts->reg != reg) {
2003                 tcg_out_mov(s, ts->type, ts->reg, reg);
2004             }
2005         } else {
2006             if (ts->val_type == TEMP_VAL_REG)
2007                 s->reg_to_temp[ts->reg] = -1;
2008             if (IS_DEAD_ARG(i)) {
2009                 ts->val_type = TEMP_VAL_DEAD;
2010             } else {
2011                 ts->val_type = TEMP_VAL_REG;
2012                 ts->reg = reg;
2013                 ts->mem_coherent = 0;
2014                 s->reg_to_temp[reg] = arg;
2015             }
2016         }
2017     }
2018     
2019     return nb_iargs + nb_oargs + def->nb_cargs + 1;
2020 }
2021
2022 #ifdef CONFIG_PROFILER
2023
2024 static int64_t tcg_table_op_count[NB_OPS];
2025
2026 static void dump_op_count(void)
2027 {
2028     int i;
2029     FILE *f;
2030     f = fopen("/tmp/op.log", "w");
2031     for(i = INDEX_op_end; i < NB_OPS; i++) {
2032         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2033     }
2034     fclose(f);
2035 }
2036 #endif
2037
2038
2039 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2040                                       long search_pc)
2041 {
2042     TCGOpcode opc;
2043     int op_index;
2044     const TCGOpDef *def;
2045     unsigned int dead_args;
2046     const TCGArg *args;
2047
2048 #ifdef DEBUG_DISAS
2049     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2050         qemu_log("OP:\n");
2051         tcg_dump_ops(s, logfile);
2052         qemu_log("\n");
2053     }
2054 #endif
2055
2056 #ifdef USE_TCG_OPTIMIZATIONS
2057     gen_opparam_ptr =
2058         tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2059 #endif
2060
2061 #ifdef CONFIG_PROFILER
2062     s->la_time -= profile_getclock();
2063 #endif
2064     tcg_liveness_analysis(s);
2065 #ifdef CONFIG_PROFILER
2066     s->la_time += profile_getclock();
2067 #endif
2068
2069 #ifdef DEBUG_DISAS
2070     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2071         qemu_log("OP after liveness analysis:\n");
2072         tcg_dump_ops(s, logfile);
2073         qemu_log("\n");
2074     }
2075 #endif
2076
2077     tcg_reg_alloc_start(s);
2078
2079     s->code_buf = gen_code_buf;
2080     s->code_ptr = gen_code_buf;
2081
2082     args = gen_opparam_buf;
2083     op_index = 0;
2084
2085     for(;;) {
2086         opc = gen_opc_buf[op_index];
2087 #ifdef CONFIG_PROFILER
2088         tcg_table_op_count[opc]++;
2089 #endif
2090         def = &tcg_op_defs[opc];
2091 #if 0
2092         printf("%s: %d %d %d\n", def->name,
2093                def->nb_oargs, def->nb_iargs, def->nb_cargs);
2094         //        dump_regs(s);
2095 #endif
2096         switch(opc) {
2097         case INDEX_op_mov_i32:
2098 #if TCG_TARGET_REG_BITS == 64
2099         case INDEX_op_mov_i64:
2100 #endif
2101             dead_args = s->op_dead_args[op_index];
2102             tcg_reg_alloc_mov(s, def, args, dead_args);
2103             break;
2104         case INDEX_op_movi_i32:
2105 #if TCG_TARGET_REG_BITS == 64
2106         case INDEX_op_movi_i64:
2107 #endif
2108             tcg_reg_alloc_movi(s, args);
2109             break;
2110         case INDEX_op_debug_insn_start:
2111             /* debug instruction */
2112             break;
2113         case INDEX_op_nop:
2114         case INDEX_op_nop1:
2115         case INDEX_op_nop2:
2116         case INDEX_op_nop3:
2117             break;
2118         case INDEX_op_nopn:
2119             args += args[0];
2120             goto next;
2121         case INDEX_op_discard:
2122             {
2123                 TCGTemp *ts;
2124                 ts = &s->temps[args[0]];
2125                 /* mark the temporary as dead */
2126                 if (!ts->fixed_reg) {
2127                     if (ts->val_type == TEMP_VAL_REG)
2128                         s->reg_to_temp[ts->reg] = -1;
2129                     ts->val_type = TEMP_VAL_DEAD;
2130                 }
2131             }
2132             break;
2133         case INDEX_op_set_label:
2134             tcg_reg_alloc_bb_end(s, s->reserved_regs);
2135             tcg_out_label(s, args[0], s->code_ptr);
2136             break;
2137         case INDEX_op_call:
2138             dead_args = s->op_dead_args[op_index];
2139             args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2140             goto next;
2141         case INDEX_op_end:
2142             goto the_end;
2143         default:
2144             /* Sanity check that we've not introduced any unhandled opcodes. */
2145             if (def->flags & TCG_OPF_NOT_PRESENT) {
2146                 tcg_abort();
2147             }
2148             /* Note: in order to speed up the code, it would be much
2149                faster to have specialized register allocator functions for
2150                some common argument patterns */
2151             dead_args = s->op_dead_args[op_index];
2152             tcg_reg_alloc_op(s, def, opc, args, dead_args);
2153             break;
2154         }
2155         args += def->nb_args;
2156     next:
2157         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2158             return op_index;
2159         }
2160         op_index++;
2161 #ifndef NDEBUG
2162         check_regs(s);
2163 #endif
2164     }
2165  the_end:
2166     return -1;
2167 }
2168
2169 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2170 {
2171 #ifdef CONFIG_PROFILER
2172     {
2173         int n;
2174         n = (gen_opc_ptr - gen_opc_buf);
2175         s->op_count += n;
2176         if (n > s->op_count_max)
2177             s->op_count_max = n;
2178
2179         s->temp_count += s->nb_temps;
2180         if (s->nb_temps > s->temp_count_max)
2181             s->temp_count_max = s->nb_temps;
2182     }
2183 #endif
2184
2185     tcg_gen_code_common(s, gen_code_buf, -1);
2186
2187     /* flush instruction cache */
2188     flush_icache_range((tcg_target_ulong)gen_code_buf,
2189                        (tcg_target_ulong)s->code_ptr);
2190
2191     return s->code_ptr -  gen_code_buf;
2192 }
2193
2194 /* Return the index of the micro operation such as the pc after is <
2195    offset bytes from the start of the TB.  The contents of gen_code_buf must
2196    not be changed, though writing the same values is ok.
2197    Return -1 if not found. */
2198 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2199 {
2200     return tcg_gen_code_common(s, gen_code_buf, offset);
2201 }
2202
2203 #ifdef CONFIG_PROFILER
2204 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2205 {
2206     TCGContext *s = &tcg_ctx;
2207     int64_t tot;
2208
2209     tot = s->interm_time + s->code_time;
2210     cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2211                 tot, tot / 2.4e9);
2212     cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2213                 s->tb_count, 
2214                 s->tb_count1 - s->tb_count,
2215                 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2216     cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2217                 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2218     cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2219                 s->tb_count ? 
2220                 (double)s->del_op_count / s->tb_count : 0);
2221     cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2222                 s->tb_count ? 
2223                 (double)s->temp_count / s->tb_count : 0,
2224                 s->temp_count_max);
2225     
2226     cpu_fprintf(f, "cycles/op           %0.1f\n", 
2227                 s->op_count ? (double)tot / s->op_count : 0);
2228     cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2229                 s->code_in_len ? (double)tot / s->code_in_len : 0);
2230     cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2231                 s->code_out_len ? (double)tot / s->code_out_len : 0);
2232     if (tot == 0)
2233         tot = 1;
2234     cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2235                 (double)s->interm_time / tot * 100.0);
2236     cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2237                 (double)s->code_time / tot * 100.0);
2238     cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2239                 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2240     cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2241                 s->restore_count);
2242     cpu_fprintf(f, "  avg cycles        %0.1f\n",
2243                 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2244
2245     dump_op_count();
2246 }
2247 #else
2248 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2249 {
2250     cpu_fprintf(f, "[TCG profiler not compiled]\n");
2251 }
2252 #endif
2253
2254 #ifdef ELF_HOST_MACHINE
2255 /* In order to use this feature, the backend needs to do three things:
2256
2257    (1) Define ELF_HOST_MACHINE to indicate both what value to
2258        put into the ELF image and to indicate support for the feature.
2259
2260    (2) Define tcg_register_jit.  This should create a buffer containing
2261        the contents of a .debug_frame section that describes the post-
2262        prologue unwind info for the tcg machine.
2263
2264    (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2265 */
2266
2267 /* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2268 typedef enum {
2269     JIT_NOACTION = 0,
2270     JIT_REGISTER_FN,
2271     JIT_UNREGISTER_FN
2272 } jit_actions_t;
2273
2274 struct jit_code_entry {
2275     struct jit_code_entry *next_entry;
2276     struct jit_code_entry *prev_entry;
2277     const void *symfile_addr;
2278     uint64_t symfile_size;
2279 };
2280
2281 struct jit_descriptor {
2282     uint32_t version;
2283     uint32_t action_flag;
2284     struct jit_code_entry *relevant_entry;
2285     struct jit_code_entry *first_entry;
2286 };
2287
2288 void __jit_debug_register_code(void) __attribute__((noinline));
2289 void __jit_debug_register_code(void)
2290 {
2291     asm("");
2292 }
2293
2294 /* Must statically initialize the version, because GDB may check
2295    the version before we can set it.  */
2296 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2297
2298 /* End GDB interface.  */
2299
2300 static int find_string(const char *strtab, const char *str)
2301 {
2302     const char *p = strtab + 1;
2303
2304     while (1) {
2305         if (strcmp(p, str) == 0) {
2306             return p - strtab;
2307         }
2308         p += strlen(p) + 1;
2309     }
2310 }
2311
2312 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2313                                  void *debug_frame, size_t debug_frame_size)
2314 {
2315     struct __attribute__((packed)) DebugInfo {
2316         uint32_t  len;
2317         uint16_t  version;
2318         uint32_t  abbrev;
2319         uint8_t   ptr_size;
2320         uint8_t   cu_die;
2321         uint16_t  cu_lang;
2322         uintptr_t cu_low_pc;
2323         uintptr_t cu_high_pc;
2324         uint8_t   fn_die;
2325         char      fn_name[16];
2326         uintptr_t fn_low_pc;
2327         uintptr_t fn_high_pc;
2328         uint8_t   cu_eoc;
2329     };
2330
2331     struct ElfImage {
2332         ElfW(Ehdr) ehdr;
2333         ElfW(Phdr) phdr;
2334         ElfW(Shdr) shdr[7];
2335         ElfW(Sym)  sym[2];
2336         struct DebugInfo di;
2337         uint8_t    da[24];
2338         char       str[80];
2339     };
2340
2341     struct ElfImage *img;
2342
2343     static const struct ElfImage img_template = {
2344         .ehdr = {
2345             .e_ident[EI_MAG0] = ELFMAG0,
2346             .e_ident[EI_MAG1] = ELFMAG1,
2347             .e_ident[EI_MAG2] = ELFMAG2,
2348             .e_ident[EI_MAG3] = ELFMAG3,
2349             .e_ident[EI_CLASS] = ELF_CLASS,
2350             .e_ident[EI_DATA] = ELF_DATA,
2351             .e_ident[EI_VERSION] = EV_CURRENT,
2352             .e_type = ET_EXEC,
2353             .e_machine = ELF_HOST_MACHINE,
2354             .e_version = EV_CURRENT,
2355             .e_phoff = offsetof(struct ElfImage, phdr),
2356             .e_shoff = offsetof(struct ElfImage, shdr),
2357             .e_ehsize = sizeof(ElfW(Shdr)),
2358             .e_phentsize = sizeof(ElfW(Phdr)),
2359             .e_phnum = 1,
2360             .e_shentsize = sizeof(ElfW(Shdr)),
2361             .e_shnum = ARRAY_SIZE(img->shdr),
2362             .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2363 #ifdef ELF_HOST_FLAGS
2364             .e_flags = ELF_HOST_FLAGS,
2365 #endif
2366 #ifdef ELF_OSABI
2367             .e_ident[EI_OSABI] = ELF_OSABI,
2368 #endif
2369         },
2370         .phdr = {
2371             .p_type = PT_LOAD,
2372             .p_flags = PF_X,
2373         },
2374         .shdr = {
2375             [0] = { .sh_type = SHT_NULL },
2376             /* Trick: The contents of code_gen_buffer are not present in
2377                this fake ELF file; that got allocated elsewhere.  Therefore
2378                we mark .text as SHT_NOBITS (similar to .bss) so that readers
2379                will not look for contents.  We can record any address.  */
2380             [1] = { /* .text */
2381                 .sh_type = SHT_NOBITS,
2382                 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2383             },
2384             [2] = { /* .debug_info */
2385                 .sh_type = SHT_PROGBITS,
2386                 .sh_offset = offsetof(struct ElfImage, di),
2387                 .sh_size = sizeof(struct DebugInfo),
2388             },
2389             [3] = { /* .debug_abbrev */
2390                 .sh_type = SHT_PROGBITS,
2391                 .sh_offset = offsetof(struct ElfImage, da),
2392                 .sh_size = sizeof(img->da),
2393             },
2394             [4] = { /* .debug_frame */
2395                 .sh_type = SHT_PROGBITS,
2396                 .sh_offset = sizeof(struct ElfImage),
2397             },
2398             [5] = { /* .symtab */
2399                 .sh_type = SHT_SYMTAB,
2400                 .sh_offset = offsetof(struct ElfImage, sym),
2401                 .sh_size = sizeof(img->sym),
2402                 .sh_info = 1,
2403                 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2404                 .sh_entsize = sizeof(ElfW(Sym)),
2405             },
2406             [6] = { /* .strtab */
2407                 .sh_type = SHT_STRTAB,
2408                 .sh_offset = offsetof(struct ElfImage, str),
2409                 .sh_size = sizeof(img->str),
2410             }
2411         },
2412         .sym = {
2413             [1] = { /* code_gen_buffer */
2414                 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2415                 .st_shndx = 1,
2416             }
2417         },
2418         .di = {
2419             .len = sizeof(struct DebugInfo) - 4,
2420             .version = 2,
2421             .ptr_size = sizeof(void *),
2422             .cu_die = 1,
2423             .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
2424             .fn_die = 2,
2425             .fn_name = "code_gen_buffer"
2426         },
2427         .da = {
2428             1,          /* abbrev number (the cu) */
2429             0x11, 1,    /* DW_TAG_compile_unit, has children */
2430             0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
2431             0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2432             0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2433             0, 0,       /* end of abbrev */
2434             2,          /* abbrev number (the fn) */
2435             0x2e, 0,    /* DW_TAG_subprogram, no children */
2436             0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
2437             0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2438             0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2439             0, 0,       /* end of abbrev */
2440             0           /* no more abbrev */
2441         },
2442         .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2443                ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2444     };
2445
2446     /* We only need a single jit entry; statically allocate it.  */
2447     static struct jit_code_entry one_entry;
2448
2449     uintptr_t buf = (uintptr_t)buf_ptr;
2450     size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2451
2452     img = g_malloc(img_size);
2453     *img = img_template;
2454     memcpy(img + 1, debug_frame, debug_frame_size);
2455
2456     img->phdr.p_vaddr = buf;
2457     img->phdr.p_paddr = buf;
2458     img->phdr.p_memsz = buf_size;
2459
2460     img->shdr[1].sh_name = find_string(img->str, ".text");
2461     img->shdr[1].sh_addr = buf;
2462     img->shdr[1].sh_size = buf_size;
2463
2464     img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2465     img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2466
2467     img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2468     img->shdr[4].sh_size = debug_frame_size;
2469
2470     img->shdr[5].sh_name = find_string(img->str, ".symtab");
2471     img->shdr[6].sh_name = find_string(img->str, ".strtab");
2472
2473     img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2474     img->sym[1].st_value = buf;
2475     img->sym[1].st_size = buf_size;
2476
2477     img->di.cu_low_pc = buf;
2478     img->di.cu_high_pc = buf_size;
2479     img->di.fn_low_pc = buf;
2480     img->di.fn_high_pc = buf_size;
2481
2482 #ifdef DEBUG_JIT
2483     /* Enable this block to be able to debug the ELF image file creation.
2484        One can use readelf, objdump, or other inspection utilities.  */
2485     {
2486         FILE *f = fopen("/tmp/qemu.jit", "w+b");
2487         if (f) {
2488             if (fwrite(img, img_size, 1, f) != img_size) {
2489                 /* Avoid stupid unused return value warning for fwrite.  */
2490             }
2491             fclose(f);
2492         }
2493     }
2494 #endif
2495
2496     one_entry.symfile_addr = img;
2497     one_entry.symfile_size = img_size;
2498
2499     __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2500     __jit_debug_descriptor.relevant_entry = &one_entry;
2501     __jit_debug_descriptor.first_entry = &one_entry;
2502     __jit_debug_register_code();
2503 }
2504 #else
2505 /* No support for the feature.  Provide the entry point expected by exec.c,
2506    and implement the internal function we declared earlier.  */
2507
2508 static void tcg_register_jit_int(void *buf, size_t size,
2509                                  void *debug_frame, size_t debug_frame_size)
2510 {
2511 }
2512
2513 void tcg_register_jit(void *buf, size_t buf_size)
2514 {
2515 }
2516 #endif /* ELF_HOST_MACHINE */
This page took 0.162627 seconds and 4 git commands to generate.