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