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