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