]> Git Repo - qemu.git/blob - tcg/tcg.c
tmp105: Create API for TMP105 temperature sensor.
[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 = 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     assert(ts);
804     if (idx < s->nb_globals) {
805         pstrcpy(buf, buf_size, ts->name);
806     } else {
807         if (ts->temp_local) 
808             snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
809         else
810             snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
811     }
812     return buf;
813 }
814
815 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
816 {
817     return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
818 }
819
820 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
821 {
822     return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
823 }
824
825 static int helper_cmp(const void *p1, const void *p2)
826 {
827     const TCGHelperInfo *th1 = p1;
828     const TCGHelperInfo *th2 = p2;
829     if (th1->func < th2->func)
830         return -1;
831     else if (th1->func == th2->func)
832         return 0;
833     else
834         return 1;
835 }
836
837 /* find helper definition (Note: A hash table would be better) */
838 static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
839 {
840     int m, m_min, m_max;
841     TCGHelperInfo *th;
842     tcg_target_ulong v;
843
844     if (unlikely(!s->helpers_sorted)) {
845         qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
846               helper_cmp);
847         s->helpers_sorted = 1;
848     }
849
850     /* binary search */
851     m_min = 0;
852     m_max = s->nb_helpers - 1;
853     while (m_min <= m_max) {
854         m = (m_min + m_max) >> 1;
855         th = &s->helpers[m];
856         v = th->func;
857         if (v == val)
858             return th;
859         else if (val < v) {
860             m_max = m - 1;
861         } else {
862             m_min = m + 1;
863         }
864     }
865     return NULL;
866 }
867
868 static const char * const cond_name[] =
869 {
870     [TCG_COND_NEVER] = "never",
871     [TCG_COND_ALWAYS] = "always",
872     [TCG_COND_EQ] = "eq",
873     [TCG_COND_NE] = "ne",
874     [TCG_COND_LT] = "lt",
875     [TCG_COND_GE] = "ge",
876     [TCG_COND_LE] = "le",
877     [TCG_COND_GT] = "gt",
878     [TCG_COND_LTU] = "ltu",
879     [TCG_COND_GEU] = "geu",
880     [TCG_COND_LEU] = "leu",
881     [TCG_COND_GTU] = "gtu"
882 };
883
884 void tcg_dump_ops(TCGContext *s)
885 {
886     const uint16_t *opc_ptr;
887     const TCGArg *args;
888     TCGArg arg;
889     TCGOpcode c;
890     int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
891     const TCGOpDef *def;
892     char buf[128];
893
894     first_insn = 1;
895     opc_ptr = s->gen_opc_buf;
896     args = s->gen_opparam_buf;
897     while (opc_ptr < s->gen_opc_ptr) {
898         c = *opc_ptr++;
899         def = &tcg_op_defs[c];
900         if (c == INDEX_op_debug_insn_start) {
901             uint64_t pc;
902 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
903             pc = ((uint64_t)args[1] << 32) | args[0];
904 #else
905             pc = args[0];
906 #endif
907             if (!first_insn) {
908                 qemu_log("\n");
909             }
910             qemu_log(" ---- 0x%" PRIx64, pc);
911             first_insn = 0;
912             nb_oargs = def->nb_oargs;
913             nb_iargs = def->nb_iargs;
914             nb_cargs = def->nb_cargs;
915         } else if (c == INDEX_op_call) {
916             TCGArg arg;
917
918             /* variable number of arguments */
919             arg = *args++;
920             nb_oargs = arg >> 16;
921             nb_iargs = arg & 0xffff;
922             nb_cargs = def->nb_cargs;
923
924             qemu_log(" %s ", def->name);
925
926             /* function name */
927             qemu_log("%s",
928                      tcg_get_arg_str_idx(s, buf, sizeof(buf),
929                                          args[nb_oargs + nb_iargs - 1]));
930             /* flags */
931             qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
932             /* nb out args */
933             qemu_log(",$%d", nb_oargs);
934             for(i = 0; i < nb_oargs; i++) {
935                 qemu_log(",");
936                 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
937                                                    args[i]));
938             }
939             for(i = 0; i < (nb_iargs - 1); i++) {
940                 qemu_log(",");
941                 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
942                     qemu_log("<dummy>");
943                 } else {
944                     qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
945                                                        args[nb_oargs + i]));
946                 }
947             }
948         } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
949             tcg_target_ulong val;
950             TCGHelperInfo *th;
951
952             nb_oargs = def->nb_oargs;
953             nb_iargs = def->nb_iargs;
954             nb_cargs = def->nb_cargs;
955             qemu_log(" %s %s,$", def->name,
956                      tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
957             val = args[1];
958             th = tcg_find_helper(s, val);
959             if (th) {
960                 qemu_log("%s", th->name);
961             } else {
962                 if (c == INDEX_op_movi_i32) {
963                     qemu_log("0x%x", (uint32_t)val);
964                 } else {
965                     qemu_log("0x%" PRIx64 , (uint64_t)val);
966                 }
967             }
968         } else {
969             qemu_log(" %s ", def->name);
970             if (c == INDEX_op_nopn) {
971                 /* variable number of arguments */
972                 nb_cargs = *args;
973                 nb_oargs = 0;
974                 nb_iargs = 0;
975             } else {
976                 nb_oargs = def->nb_oargs;
977                 nb_iargs = def->nb_iargs;
978                 nb_cargs = def->nb_cargs;
979             }
980             
981             k = 0;
982             for(i = 0; i < nb_oargs; i++) {
983                 if (k != 0) {
984                     qemu_log(",");
985                 }
986                 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
987                                                    args[k++]));
988             }
989             for(i = 0; i < nb_iargs; i++) {
990                 if (k != 0) {
991                     qemu_log(",");
992                 }
993                 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
994                                                    args[k++]));
995             }
996             switch (c) {
997             case INDEX_op_brcond_i32:
998             case INDEX_op_setcond_i32:
999             case INDEX_op_movcond_i32:
1000             case INDEX_op_brcond2_i32:
1001             case INDEX_op_setcond2_i32:
1002             case INDEX_op_brcond_i64:
1003             case INDEX_op_setcond_i64:
1004             case INDEX_op_movcond_i64:
1005                 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1006                     qemu_log(",%s", cond_name[args[k++]]);
1007                 } else {
1008                     qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1009                 }
1010                 i = 1;
1011                 break;
1012             default:
1013                 i = 0;
1014                 break;
1015             }
1016             for(; i < nb_cargs; i++) {
1017                 if (k != 0) {
1018                     qemu_log(",");
1019                 }
1020                 arg = args[k++];
1021                 qemu_log("$0x%" TCG_PRIlx, arg);
1022             }
1023         }
1024         qemu_log("\n");
1025         args += nb_iargs + nb_oargs + nb_cargs;
1026     }
1027 }
1028
1029 /* we give more priority to constraints with less registers */
1030 static int get_constraint_priority(const TCGOpDef *def, int k)
1031 {
1032     const TCGArgConstraint *arg_ct;
1033
1034     int i, n;
1035     arg_ct = &def->args_ct[k];
1036     if (arg_ct->ct & TCG_CT_ALIAS) {
1037         /* an alias is equivalent to a single register */
1038         n = 1;
1039     } else {
1040         if (!(arg_ct->ct & TCG_CT_REG))
1041             return 0;
1042         n = 0;
1043         for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1044             if (tcg_regset_test_reg(arg_ct->u.regs, i))
1045                 n++;
1046         }
1047     }
1048     return TCG_TARGET_NB_REGS - n + 1;
1049 }
1050
1051 /* sort from highest priority to lowest */
1052 static void sort_constraints(TCGOpDef *def, int start, int n)
1053 {
1054     int i, j, p1, p2, tmp;
1055
1056     for(i = 0; i < n; i++)
1057         def->sorted_args[start + i] = start + i;
1058     if (n <= 1)
1059         return;
1060     for(i = 0; i < n - 1; i++) {
1061         for(j = i + 1; j < n; j++) {
1062             p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1063             p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1064             if (p1 < p2) {
1065                 tmp = def->sorted_args[start + i];
1066                 def->sorted_args[start + i] = def->sorted_args[start + j];
1067                 def->sorted_args[start + j] = tmp;
1068             }
1069         }
1070     }
1071 }
1072
1073 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1074 {
1075     TCGOpcode op;
1076     TCGOpDef *def;
1077     const char *ct_str;
1078     int i, nb_args;
1079
1080     for(;;) {
1081         if (tdefs->op == (TCGOpcode)-1)
1082             break;
1083         op = tdefs->op;
1084         assert((unsigned)op < NB_OPS);
1085         def = &tcg_op_defs[op];
1086 #if defined(CONFIG_DEBUG_TCG)
1087         /* Duplicate entry in op definitions? */
1088         assert(!def->used);
1089         def->used = 1;
1090 #endif
1091         nb_args = def->nb_iargs + def->nb_oargs;
1092         for(i = 0; i < nb_args; i++) {
1093             ct_str = tdefs->args_ct_str[i];
1094             /* Incomplete TCGTargetOpDef entry? */
1095             assert(ct_str != NULL);
1096             tcg_regset_clear(def->args_ct[i].u.regs);
1097             def->args_ct[i].ct = 0;
1098             if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1099                 int oarg;
1100                 oarg = ct_str[0] - '0';
1101                 assert(oarg < def->nb_oargs);
1102                 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1103                 /* TCG_CT_ALIAS is for the output arguments. The input
1104                    argument is tagged with TCG_CT_IALIAS. */
1105                 def->args_ct[i] = def->args_ct[oarg];
1106                 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1107                 def->args_ct[oarg].alias_index = i;
1108                 def->args_ct[i].ct |= TCG_CT_IALIAS;
1109                 def->args_ct[i].alias_index = oarg;
1110             } else {
1111                 for(;;) {
1112                     if (*ct_str == '\0')
1113                         break;
1114                     switch(*ct_str) {
1115                     case 'i':
1116                         def->args_ct[i].ct |= TCG_CT_CONST;
1117                         ct_str++;
1118                         break;
1119                     default:
1120                         if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1121                             fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1122                                     ct_str, i, def->name);
1123                             exit(1);
1124                         }
1125                     }
1126                 }
1127             }
1128         }
1129
1130         /* TCGTargetOpDef entry with too much information? */
1131         assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1132
1133         /* sort the constraints (XXX: this is just an heuristic) */
1134         sort_constraints(def, 0, def->nb_oargs);
1135         sort_constraints(def, def->nb_oargs, def->nb_iargs);
1136
1137 #if 0
1138         {
1139             int i;
1140
1141             printf("%s: sorted=", def->name);
1142             for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1143                 printf(" %d", def->sorted_args[i]);
1144             printf("\n");
1145         }
1146 #endif
1147         tdefs++;
1148     }
1149
1150 #if defined(CONFIG_DEBUG_TCG)
1151     i = 0;
1152     for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1153         const TCGOpDef *def = &tcg_op_defs[op];
1154         if (op < INDEX_op_call
1155             || op == INDEX_op_debug_insn_start
1156             || (def->flags & TCG_OPF_NOT_PRESENT)) {
1157             /* Wrong entry in op definitions? */
1158             if (def->used) {
1159                 fprintf(stderr, "Invalid op definition for %s\n", def->name);
1160                 i = 1;
1161             }
1162         } else {
1163             /* Missing entry in op definitions? */
1164             if (!def->used) {
1165                 fprintf(stderr, "Missing op definition for %s\n", def->name);
1166                 i = 1;
1167             }
1168         }
1169     }
1170     if (i == 1) {
1171         tcg_abort();
1172     }
1173 #endif
1174 }
1175
1176 #ifdef USE_LIVENESS_ANALYSIS
1177
1178 /* set a nop for an operation using 'nb_args' */
1179 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
1180                                TCGArg *args, int nb_args)
1181 {
1182     if (nb_args == 0) {
1183         *opc_ptr = INDEX_op_nop;
1184     } else {
1185         *opc_ptr = INDEX_op_nopn;
1186         args[0] = nb_args;
1187         args[nb_args - 1] = nb_args;
1188     }
1189 }
1190
1191 /* liveness analysis: end of function: all temps are dead, and globals
1192    should be in memory. */
1193 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1194                                    uint8_t *mem_temps)
1195 {
1196     memset(dead_temps, 1, s->nb_temps);
1197     memset(mem_temps, 1, s->nb_globals);
1198     memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
1199 }
1200
1201 /* liveness analysis: end of basic block: all temps are dead, globals
1202    and local temps should be in memory. */
1203 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1204                                  uint8_t *mem_temps)
1205 {
1206     int i;
1207
1208     memset(dead_temps, 1, s->nb_temps);
1209     memset(mem_temps, 1, s->nb_globals);
1210     for(i = s->nb_globals; i < s->nb_temps; i++) {
1211         mem_temps[i] = s->temps[i].temp_local;
1212     }
1213 }
1214
1215 /* Liveness analysis : update the opc_dead_args array to tell if a
1216    given input arguments is dead. Instructions updating dead
1217    temporaries are removed. */
1218 static void tcg_liveness_analysis(TCGContext *s)
1219 {
1220     int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1221     TCGOpcode op;
1222     TCGArg *args;
1223     const TCGOpDef *def;
1224     uint8_t *dead_temps, *mem_temps;
1225     uint16_t dead_args;
1226     uint8_t sync_args;
1227     
1228     s->gen_opc_ptr++; /* skip end */
1229
1230     nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1231
1232     s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1233     s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1234     
1235     dead_temps = tcg_malloc(s->nb_temps);
1236     mem_temps = tcg_malloc(s->nb_temps);
1237     tcg_la_func_end(s, dead_temps, mem_temps);
1238
1239     args = s->gen_opparam_ptr;
1240     op_index = nb_ops - 1;
1241     while (op_index >= 0) {
1242         op = s->gen_opc_buf[op_index];
1243         def = &tcg_op_defs[op];
1244         switch(op) {
1245         case INDEX_op_call:
1246             {
1247                 int call_flags;
1248
1249                 nb_args = args[-1];
1250                 args -= nb_args;
1251                 nb_iargs = args[0] & 0xffff;
1252                 nb_oargs = args[0] >> 16;
1253                 args++;
1254                 call_flags = args[nb_oargs + nb_iargs];
1255
1256                 /* pure functions can be removed if their result is not
1257                    used */
1258                 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
1259                     for(i = 0; i < nb_oargs; i++) {
1260                         arg = args[i];
1261                         if (!dead_temps[arg] || mem_temps[arg]) {
1262                             goto do_not_remove_call;
1263                         }
1264                     }
1265                     tcg_set_nop(s, s->gen_opc_buf + op_index,
1266                                 args - 1, nb_args);
1267                 } else {
1268                 do_not_remove_call:
1269
1270                     /* output args are dead */
1271                     dead_args = 0;
1272                     sync_args = 0;
1273                     for(i = 0; i < nb_oargs; i++) {
1274                         arg = args[i];
1275                         if (dead_temps[arg]) {
1276                             dead_args |= (1 << i);
1277                         }
1278                         if (mem_temps[arg]) {
1279                             sync_args |= (1 << i);
1280                         }
1281                         dead_temps[arg] = 1;
1282                         mem_temps[arg] = 0;
1283                     }
1284
1285                     if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1286                         /* globals should be synced to memory */
1287                         memset(mem_temps, 1, s->nb_globals);
1288                     }
1289                     if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1290                                         TCG_CALL_NO_READ_GLOBALS))) {
1291                         /* globals should go back to memory */
1292                         memset(dead_temps, 1, s->nb_globals);
1293                     }
1294
1295                     /* input args are live */
1296                     for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1297                         arg = args[i];
1298                         if (arg != TCG_CALL_DUMMY_ARG) {
1299                             if (dead_temps[arg]) {
1300                                 dead_args |= (1 << i);
1301                             }
1302                             dead_temps[arg] = 0;
1303                         }
1304                     }
1305                     s->op_dead_args[op_index] = dead_args;
1306                     s->op_sync_args[op_index] = sync_args;
1307                 }
1308                 args--;
1309             }
1310             break;
1311         case INDEX_op_debug_insn_start:
1312             args -= def->nb_args;
1313             break;
1314         case INDEX_op_nopn:
1315             nb_args = args[-1];
1316             args -= nb_args;
1317             break;
1318         case INDEX_op_discard:
1319             args--;
1320             /* mark the temporary as dead */
1321             dead_temps[args[0]] = 1;
1322             mem_temps[args[0]] = 0;
1323             break;
1324         case INDEX_op_end:
1325             break;
1326
1327         case INDEX_op_add2_i32:
1328         case INDEX_op_sub2_i32:
1329             args -= 6;
1330             nb_iargs = 4;
1331             nb_oargs = 2;
1332             /* Test if the high part of the operation is dead, but not
1333                the low part.  The result can be optimized to a simple
1334                add or sub.  This happens often for x86_64 guest when the
1335                cpu mode is set to 32 bit.  */
1336             if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1337                 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1338                     goto do_remove;
1339                 }
1340                 /* Create the single operation plus nop.  */
1341                 if (op == INDEX_op_add2_i32) {
1342                     op = INDEX_op_add_i32;
1343                 } else {
1344                     op = INDEX_op_sub_i32;
1345                 }
1346                 s->gen_opc_buf[op_index] = op;
1347                 args[1] = args[2];
1348                 args[2] = args[4];
1349                 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1350                 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1351                 /* Fall through and mark the single-word operation live.  */
1352                 nb_iargs = 2;
1353                 nb_oargs = 1;
1354             }
1355             goto do_not_remove;
1356
1357         case INDEX_op_mulu2_i32:
1358             args -= 4;
1359             nb_iargs = 2;
1360             nb_oargs = 2;
1361             /* Likewise, test for the high part of the operation dead.  */
1362             if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1363                 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1364                     goto do_remove;
1365                 }
1366                 s->gen_opc_buf[op_index] = op = INDEX_op_mul_i32;
1367                 args[1] = args[2];
1368                 args[2] = args[3];
1369                 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1370                 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1371                 /* Fall through and mark the single-word operation live.  */
1372                 nb_oargs = 1;
1373             }
1374             goto do_not_remove;
1375
1376         default:
1377             /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1378             args -= def->nb_args;
1379             nb_iargs = def->nb_iargs;
1380             nb_oargs = def->nb_oargs;
1381
1382             /* Test if the operation can be removed because all
1383                its outputs are dead. We assume that nb_oargs == 0
1384                implies side effects */
1385             if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1386                 for(i = 0; i < nb_oargs; i++) {
1387                     arg = args[i];
1388                     if (!dead_temps[arg] || mem_temps[arg]) {
1389                         goto do_not_remove;
1390                     }
1391                 }
1392             do_remove:
1393                 tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
1394 #ifdef CONFIG_PROFILER
1395                 s->del_op_count++;
1396 #endif
1397             } else {
1398             do_not_remove:
1399
1400                 /* output args are dead */
1401                 dead_args = 0;
1402                 sync_args = 0;
1403                 for(i = 0; i < nb_oargs; i++) {
1404                     arg = args[i];
1405                     if (dead_temps[arg]) {
1406                         dead_args |= (1 << i);
1407                     }
1408                     if (mem_temps[arg]) {
1409                         sync_args |= (1 << i);
1410                     }
1411                     dead_temps[arg] = 1;
1412                     mem_temps[arg] = 0;
1413                 }
1414
1415                 /* if end of basic block, update */
1416                 if (def->flags & TCG_OPF_BB_END) {
1417                     tcg_la_bb_end(s, dead_temps, mem_temps);
1418                 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1419                     /* globals should be synced to memory */
1420                     memset(mem_temps, 1, s->nb_globals);
1421                 }
1422
1423                 /* input args are live */
1424                 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1425                     arg = args[i];
1426                     if (dead_temps[arg]) {
1427                         dead_args |= (1 << i);
1428                     }
1429                     dead_temps[arg] = 0;
1430                 }
1431                 s->op_dead_args[op_index] = dead_args;
1432                 s->op_sync_args[op_index] = sync_args;
1433             }
1434             break;
1435         }
1436         op_index--;
1437     }
1438
1439     if (args != s->gen_opparam_buf) {
1440         tcg_abort();
1441     }
1442 }
1443 #else
1444 /* dummy liveness analysis */
1445 static void tcg_liveness_analysis(TCGContext *s)
1446 {
1447     int nb_ops;
1448     nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1449
1450     s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1451     memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1452     s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1453     memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1454 }
1455 #endif
1456
1457 #ifndef NDEBUG
1458 static void dump_regs(TCGContext *s)
1459 {
1460     TCGTemp *ts;
1461     int i;
1462     char buf[64];
1463
1464     for(i = 0; i < s->nb_temps; i++) {
1465         ts = &s->temps[i];
1466         printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1467         switch(ts->val_type) {
1468         case TEMP_VAL_REG:
1469             printf("%s", tcg_target_reg_names[ts->reg]);
1470             break;
1471         case TEMP_VAL_MEM:
1472             printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1473             break;
1474         case TEMP_VAL_CONST:
1475             printf("$0x%" TCG_PRIlx, ts->val);
1476             break;
1477         case TEMP_VAL_DEAD:
1478             printf("D");
1479             break;
1480         default:
1481             printf("???");
1482             break;
1483         }
1484         printf("\n");
1485     }
1486
1487     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1488         if (s->reg_to_temp[i] >= 0) {
1489             printf("%s: %s\n", 
1490                    tcg_target_reg_names[i], 
1491                    tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1492         }
1493     }
1494 }
1495
1496 static void check_regs(TCGContext *s)
1497 {
1498     int reg, k;
1499     TCGTemp *ts;
1500     char buf[64];
1501
1502     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1503         k = s->reg_to_temp[reg];
1504         if (k >= 0) {
1505             ts = &s->temps[k];
1506             if (ts->val_type != TEMP_VAL_REG ||
1507                 ts->reg != reg) {
1508                 printf("Inconsistency for register %s:\n", 
1509                        tcg_target_reg_names[reg]);
1510                 goto fail;
1511             }
1512         }
1513     }
1514     for(k = 0; k < s->nb_temps; k++) {
1515         ts = &s->temps[k];
1516         if (ts->val_type == TEMP_VAL_REG &&
1517             !ts->fixed_reg &&
1518             s->reg_to_temp[ts->reg] != k) {
1519                 printf("Inconsistency for temp %s:\n", 
1520                        tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1521         fail:
1522                 printf("reg state:\n");
1523                 dump_regs(s);
1524                 tcg_abort();
1525         }
1526     }
1527 }
1528 #endif
1529
1530 static void temp_allocate_frame(TCGContext *s, int temp)
1531 {
1532     TCGTemp *ts;
1533     ts = &s->temps[temp];
1534 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1535     /* Sparc64 stack is accessed with offset of 2047 */
1536     s->current_frame_offset = (s->current_frame_offset +
1537                                (tcg_target_long)sizeof(tcg_target_long) - 1) &
1538         ~(sizeof(tcg_target_long) - 1);
1539 #endif
1540     if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1541         s->frame_end) {
1542         tcg_abort();
1543     }
1544     ts->mem_offset = s->current_frame_offset;
1545     ts->mem_reg = s->frame_reg;
1546     ts->mem_allocated = 1;
1547     s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1548 }
1549
1550 /* sync register 'reg' by saving it to the corresponding temporary */
1551 static inline void tcg_reg_sync(TCGContext *s, int reg)
1552 {
1553     TCGTemp *ts;
1554     int temp;
1555
1556     temp = s->reg_to_temp[reg];
1557     ts = &s->temps[temp];
1558     assert(ts->val_type == TEMP_VAL_REG);
1559     if (!ts->mem_coherent && !ts->fixed_reg) {
1560         if (!ts->mem_allocated) {
1561             temp_allocate_frame(s, temp);
1562         }
1563         tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1564     }
1565     ts->mem_coherent = 1;
1566 }
1567
1568 /* free register 'reg' by spilling the corresponding temporary if necessary */
1569 static void tcg_reg_free(TCGContext *s, int reg)
1570 {
1571     int temp;
1572
1573     temp = s->reg_to_temp[reg];
1574     if (temp != -1) {
1575         tcg_reg_sync(s, reg);
1576         s->temps[temp].val_type = TEMP_VAL_MEM;
1577         s->reg_to_temp[reg] = -1;
1578     }
1579 }
1580
1581 /* Allocate a register belonging to reg1 & ~reg2 */
1582 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1583 {
1584     int i, reg;
1585     TCGRegSet reg_ct;
1586
1587     tcg_regset_andnot(reg_ct, reg1, reg2);
1588
1589     /* first try free registers */
1590     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1591         reg = tcg_target_reg_alloc_order[i];
1592         if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1593             return reg;
1594     }
1595
1596     /* XXX: do better spill choice */
1597     for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1598         reg = tcg_target_reg_alloc_order[i];
1599         if (tcg_regset_test_reg(reg_ct, reg)) {
1600             tcg_reg_free(s, reg);
1601             return reg;
1602         }
1603     }
1604
1605     tcg_abort();
1606 }
1607
1608 /* mark a temporary as dead. */
1609 static inline void temp_dead(TCGContext *s, int temp)
1610 {
1611     TCGTemp *ts;
1612
1613     ts = &s->temps[temp];
1614     if (!ts->fixed_reg) {
1615         if (ts->val_type == TEMP_VAL_REG) {
1616             s->reg_to_temp[ts->reg] = -1;
1617         }
1618         if (temp < s->nb_globals || ts->temp_local) {
1619             ts->val_type = TEMP_VAL_MEM;
1620         } else {
1621             ts->val_type = TEMP_VAL_DEAD;
1622         }
1623     }
1624 }
1625
1626 /* sync a temporary to memory. 'allocated_regs' is used in case a
1627    temporary registers needs to be allocated to store a constant. */
1628 static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1629 {
1630     TCGTemp *ts;
1631
1632     ts = &s->temps[temp];
1633     if (!ts->fixed_reg) {
1634         switch(ts->val_type) {
1635         case TEMP_VAL_CONST:
1636             ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1637                                     allocated_regs);
1638             ts->val_type = TEMP_VAL_REG;
1639             s->reg_to_temp[ts->reg] = temp;
1640             ts->mem_coherent = 0;
1641             tcg_out_movi(s, ts->type, ts->reg, ts->val);
1642             /* fallthrough*/
1643         case TEMP_VAL_REG:
1644             tcg_reg_sync(s, ts->reg);
1645             break;
1646         case TEMP_VAL_DEAD:
1647         case TEMP_VAL_MEM:
1648             break;
1649         default:
1650             tcg_abort();
1651         }
1652     }
1653 }
1654
1655 /* save a temporary to memory. 'allocated_regs' is used in case a
1656    temporary registers needs to be allocated to store a constant. */
1657 static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1658 {
1659 #ifdef USE_LIVENESS_ANALYSIS
1660     /* The liveness analysis already ensures that globals are back
1661        in memory. Keep an assert for safety. */
1662     assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1663 #else
1664     temp_sync(s, temp, allocated_regs);
1665     temp_dead(s, temp);
1666 #endif
1667 }
1668
1669 /* save globals to their canonical location and assume they can be
1670    modified be the following code. 'allocated_regs' is used in case a
1671    temporary registers needs to be allocated to store a constant. */
1672 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1673 {
1674     int i;
1675
1676     for(i = 0; i < s->nb_globals; i++) {
1677         temp_save(s, i, allocated_regs);
1678     }
1679 }
1680
1681 /* sync globals to their canonical location and assume they can be
1682    read by the following code. 'allocated_regs' is used in case a
1683    temporary registers needs to be allocated to store a constant. */
1684 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1685 {
1686     int i;
1687
1688     for (i = 0; i < s->nb_globals; i++) {
1689 #ifdef USE_LIVENESS_ANALYSIS
1690         assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1691                s->temps[i].mem_coherent);
1692 #else
1693         temp_sync(s, i, allocated_regs);
1694 #endif
1695     }
1696 }
1697
1698 /* at the end of a basic block, we assume all temporaries are dead and
1699    all globals are stored at their canonical location. */
1700 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1701 {
1702     TCGTemp *ts;
1703     int i;
1704
1705     for(i = s->nb_globals; i < s->nb_temps; i++) {
1706         ts = &s->temps[i];
1707         if (ts->temp_local) {
1708             temp_save(s, i, allocated_regs);
1709         } else {
1710 #ifdef USE_LIVENESS_ANALYSIS
1711             /* The liveness analysis already ensures that temps are dead.
1712                Keep an assert for safety. */
1713             assert(ts->val_type == TEMP_VAL_DEAD);
1714 #else
1715             temp_dead(s, i);
1716 #endif
1717         }
1718     }
1719
1720     save_globals(s, allocated_regs);
1721 }
1722
1723 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1724 #define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1725
1726 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1727                                uint16_t dead_args, uint8_t sync_args)
1728 {
1729     TCGTemp *ots;
1730     tcg_target_ulong val;
1731
1732     ots = &s->temps[args[0]];
1733     val = args[1];
1734
1735     if (ots->fixed_reg) {
1736         /* for fixed registers, we do not do any constant
1737            propagation */
1738         tcg_out_movi(s, ots->type, ots->reg, val);
1739     } else {
1740         /* The movi is not explicitly generated here */
1741         if (ots->val_type == TEMP_VAL_REG)
1742             s->reg_to_temp[ots->reg] = -1;
1743         ots->val_type = TEMP_VAL_CONST;
1744         ots->val = val;
1745     }
1746     if (NEED_SYNC_ARG(0)) {
1747         temp_sync(s, args[0], s->reserved_regs);
1748     }
1749     if (IS_DEAD_ARG(0)) {
1750         temp_dead(s, args[0]);
1751     }
1752 }
1753
1754 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1755                               const TCGArg *args, uint16_t dead_args,
1756                               uint8_t sync_args)
1757 {
1758     TCGRegSet allocated_regs;
1759     TCGTemp *ts, *ots;
1760     const TCGArgConstraint *arg_ct, *oarg_ct;
1761
1762     tcg_regset_set(allocated_regs, s->reserved_regs);
1763     ots = &s->temps[args[0]];
1764     ts = &s->temps[args[1]];
1765     oarg_ct = &def->args_ct[0];
1766     arg_ct = &def->args_ct[1];
1767
1768     /* If the source value is not in a register, and we're going to be
1769        forced to have it in a register in order to perform the copy,
1770        then copy the SOURCE value into its own register first.  That way
1771        we don't have to reload SOURCE the next time it is used. */
1772     if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
1773         || ts->val_type == TEMP_VAL_MEM) {
1774         ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1775         if (ts->val_type == TEMP_VAL_MEM) {
1776             tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
1777             ts->mem_coherent = 1;
1778         } else if (ts->val_type == TEMP_VAL_CONST) {
1779             tcg_out_movi(s, ts->type, ts->reg, ts->val);
1780         }
1781         s->reg_to_temp[ts->reg] = args[1];
1782         ts->val_type = TEMP_VAL_REG;
1783     }
1784
1785     if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
1786         /* mov to a non-saved dead register makes no sense (even with
1787            liveness analysis disabled). */
1788         assert(NEED_SYNC_ARG(0));
1789         /* The code above should have moved the temp to a register. */
1790         assert(ts->val_type == TEMP_VAL_REG);
1791         if (!ots->mem_allocated) {
1792             temp_allocate_frame(s, args[0]);
1793         }
1794         tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
1795         if (IS_DEAD_ARG(1)) {
1796             temp_dead(s, args[1]);
1797         }
1798         temp_dead(s, args[0]);
1799     } else if (ts->val_type == TEMP_VAL_CONST) {
1800         /* propagate constant */
1801         if (ots->val_type == TEMP_VAL_REG) {
1802             s->reg_to_temp[ots->reg] = -1;
1803         }
1804         ots->val_type = TEMP_VAL_CONST;
1805         ots->val = ts->val;
1806     } else {
1807         /* The code in the first if block should have moved the
1808            temp to a register. */
1809         assert(ts->val_type == TEMP_VAL_REG);
1810         if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1811             /* the mov can be suppressed */
1812             if (ots->val_type == TEMP_VAL_REG) {
1813                 s->reg_to_temp[ots->reg] = -1;
1814             }
1815             ots->reg = ts->reg;
1816             temp_dead(s, args[1]);
1817         } else {
1818             if (ots->val_type != TEMP_VAL_REG) {
1819                 /* When allocating a new register, make sure to not spill the
1820                    input one. */
1821                 tcg_regset_set_reg(allocated_regs, ts->reg);
1822                 ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs);
1823             }
1824             tcg_out_mov(s, ots->type, ots->reg, ts->reg);
1825         }
1826         ots->val_type = TEMP_VAL_REG;
1827         ots->mem_coherent = 0;
1828         s->reg_to_temp[ots->reg] = args[0];
1829         if (NEED_SYNC_ARG(0)) {
1830             tcg_reg_sync(s, ots->reg);
1831         }
1832     }
1833 }
1834
1835 static void tcg_reg_alloc_op(TCGContext *s, 
1836                              const TCGOpDef *def, TCGOpcode opc,
1837                              const TCGArg *args, uint16_t dead_args,
1838                              uint8_t sync_args)
1839 {
1840     TCGRegSet allocated_regs;
1841     int i, k, nb_iargs, nb_oargs, reg;
1842     TCGArg arg;
1843     const TCGArgConstraint *arg_ct;
1844     TCGTemp *ts;
1845     TCGArg new_args[TCG_MAX_OP_ARGS];
1846     int const_args[TCG_MAX_OP_ARGS];
1847
1848     nb_oargs = def->nb_oargs;
1849     nb_iargs = def->nb_iargs;
1850
1851     /* copy constants */
1852     memcpy(new_args + nb_oargs + nb_iargs, 
1853            args + nb_oargs + nb_iargs, 
1854            sizeof(TCGArg) * def->nb_cargs);
1855
1856     /* satisfy input constraints */ 
1857     tcg_regset_set(allocated_regs, s->reserved_regs);
1858     for(k = 0; k < nb_iargs; k++) {
1859         i = def->sorted_args[nb_oargs + k];
1860         arg = args[i];
1861         arg_ct = &def->args_ct[i];
1862         ts = &s->temps[arg];
1863         if (ts->val_type == TEMP_VAL_MEM) {
1864             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1865             tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1866             ts->val_type = TEMP_VAL_REG;
1867             ts->reg = reg;
1868             ts->mem_coherent = 1;
1869             s->reg_to_temp[reg] = arg;
1870         } else if (ts->val_type == TEMP_VAL_CONST) {
1871             if (tcg_target_const_match(ts->val, arg_ct)) {
1872                 /* constant is OK for instruction */
1873                 const_args[i] = 1;
1874                 new_args[i] = ts->val;
1875                 goto iarg_end;
1876             } else {
1877                 /* need to move to a register */
1878                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1879                 tcg_out_movi(s, ts->type, reg, ts->val);
1880                 ts->val_type = TEMP_VAL_REG;
1881                 ts->reg = reg;
1882                 ts->mem_coherent = 0;
1883                 s->reg_to_temp[reg] = arg;
1884             }
1885         }
1886         assert(ts->val_type == TEMP_VAL_REG);
1887         if (arg_ct->ct & TCG_CT_IALIAS) {
1888             if (ts->fixed_reg) {
1889                 /* if fixed register, we must allocate a new register
1890                    if the alias is not the same register */
1891                 if (arg != args[arg_ct->alias_index])
1892                     goto allocate_in_reg;
1893             } else {
1894                 /* if the input is aliased to an output and if it is
1895                    not dead after the instruction, we must allocate
1896                    a new register and move it */
1897                 if (!IS_DEAD_ARG(i)) {
1898                     goto allocate_in_reg;
1899                 }
1900             }
1901         }
1902         reg = ts->reg;
1903         if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1904             /* nothing to do : the constraint is satisfied */
1905         } else {
1906         allocate_in_reg:
1907             /* allocate a new register matching the constraint 
1908                and move the temporary register into it */
1909             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1910             tcg_out_mov(s, ts->type, reg, ts->reg);
1911         }
1912         new_args[i] = reg;
1913         const_args[i] = 0;
1914         tcg_regset_set_reg(allocated_regs, reg);
1915     iarg_end: ;
1916     }
1917     
1918     /* mark dead temporaries and free the associated registers */
1919     for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1920         if (IS_DEAD_ARG(i)) {
1921             temp_dead(s, args[i]);
1922         }
1923     }
1924
1925     if (def->flags & TCG_OPF_BB_END) {
1926         tcg_reg_alloc_bb_end(s, allocated_regs);
1927     } else {
1928         if (def->flags & TCG_OPF_CALL_CLOBBER) {
1929             /* XXX: permit generic clobber register list ? */ 
1930             for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1931                 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1932                     tcg_reg_free(s, reg);
1933                 }
1934             }
1935         }
1936         if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1937             /* sync globals if the op has side effects and might trigger
1938                an exception. */
1939             sync_globals(s, allocated_regs);
1940         }
1941         
1942         /* satisfy the output constraints */
1943         tcg_regset_set(allocated_regs, s->reserved_regs);
1944         for(k = 0; k < nb_oargs; k++) {
1945             i = def->sorted_args[k];
1946             arg = args[i];
1947             arg_ct = &def->args_ct[i];
1948             ts = &s->temps[arg];
1949             if (arg_ct->ct & TCG_CT_ALIAS) {
1950                 reg = new_args[arg_ct->alias_index];
1951             } else {
1952                 /* if fixed register, we try to use it */
1953                 reg = ts->reg;
1954                 if (ts->fixed_reg &&
1955                     tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1956                     goto oarg_end;
1957                 }
1958                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1959             }
1960             tcg_regset_set_reg(allocated_regs, reg);
1961             /* if a fixed register is used, then a move will be done afterwards */
1962             if (!ts->fixed_reg) {
1963                 if (ts->val_type == TEMP_VAL_REG) {
1964                     s->reg_to_temp[ts->reg] = -1;
1965                 }
1966                 ts->val_type = TEMP_VAL_REG;
1967                 ts->reg = reg;
1968                 /* temp value is modified, so the value kept in memory is
1969                    potentially not the same */
1970                 ts->mem_coherent = 0;
1971                 s->reg_to_temp[reg] = arg;
1972             }
1973         oarg_end:
1974             new_args[i] = reg;
1975         }
1976     }
1977
1978     /* emit instruction */
1979     tcg_out_op(s, opc, new_args, const_args);
1980     
1981     /* move the outputs in the correct register if needed */
1982     for(i = 0; i < nb_oargs; i++) {
1983         ts = &s->temps[args[i]];
1984         reg = new_args[i];
1985         if (ts->fixed_reg && ts->reg != reg) {
1986             tcg_out_mov(s, ts->type, ts->reg, reg);
1987         }
1988         if (NEED_SYNC_ARG(i)) {
1989             tcg_reg_sync(s, reg);
1990         }
1991         if (IS_DEAD_ARG(i)) {
1992             temp_dead(s, args[i]);
1993         }
1994     }
1995 }
1996
1997 #ifdef TCG_TARGET_STACK_GROWSUP
1998 #define STACK_DIR(x) (-(x))
1999 #else
2000 #define STACK_DIR(x) (x)
2001 #endif
2002
2003 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
2004                               TCGOpcode opc, const TCGArg *args,
2005                               uint16_t dead_args, uint8_t sync_args)
2006 {
2007     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2008     TCGArg arg, func_arg;
2009     TCGTemp *ts;
2010     tcg_target_long stack_offset, call_stack_size, func_addr;
2011     int const_func_arg, allocate_args;
2012     TCGRegSet allocated_regs;
2013     const TCGArgConstraint *arg_ct;
2014
2015     arg = *args++;
2016
2017     nb_oargs = arg >> 16;
2018     nb_iargs = arg & 0xffff;
2019     nb_params = nb_iargs - 1;
2020
2021     flags = args[nb_oargs + nb_iargs];
2022
2023     nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2024     if (nb_regs > nb_params)
2025         nb_regs = nb_params;
2026
2027     /* assign stack slots first */
2028     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2029     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
2030         ~(TCG_TARGET_STACK_ALIGN - 1);
2031     allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2032     if (allocate_args) {
2033         /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2034            preallocate call stack */
2035         tcg_abort();
2036     }
2037
2038     stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2039     for(i = nb_regs; i < nb_params; i++) {
2040         arg = args[nb_oargs + i];
2041 #ifdef TCG_TARGET_STACK_GROWSUP
2042         stack_offset -= sizeof(tcg_target_long);
2043 #endif
2044         if (arg != TCG_CALL_DUMMY_ARG) {
2045             ts = &s->temps[arg];
2046             if (ts->val_type == TEMP_VAL_REG) {
2047                 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2048             } else if (ts->val_type == TEMP_VAL_MEM) {
2049                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2050                                     s->reserved_regs);
2051                 /* XXX: not correct if reading values from the stack */
2052                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2053                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2054             } else if (ts->val_type == TEMP_VAL_CONST) {
2055                 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
2056                                     s->reserved_regs);
2057                 /* XXX: sign extend may be needed on some targets */
2058                 tcg_out_movi(s, ts->type, reg, ts->val);
2059                 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2060             } else {
2061                 tcg_abort();
2062             }
2063         }
2064 #ifndef TCG_TARGET_STACK_GROWSUP
2065         stack_offset += sizeof(tcg_target_long);
2066 #endif
2067     }
2068     
2069     /* assign input registers */
2070     tcg_regset_set(allocated_regs, s->reserved_regs);
2071     for(i = 0; i < nb_regs; i++) {
2072         arg = args[nb_oargs + i];
2073         if (arg != TCG_CALL_DUMMY_ARG) {
2074             ts = &s->temps[arg];
2075             reg = tcg_target_call_iarg_regs[i];
2076             tcg_reg_free(s, reg);
2077             if (ts->val_type == TEMP_VAL_REG) {
2078                 if (ts->reg != reg) {
2079                     tcg_out_mov(s, ts->type, reg, ts->reg);
2080                 }
2081             } else if (ts->val_type == TEMP_VAL_MEM) {
2082                 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2083             } else if (ts->val_type == TEMP_VAL_CONST) {
2084                 /* XXX: sign extend ? */
2085                 tcg_out_movi(s, ts->type, reg, ts->val);
2086             } else {
2087                 tcg_abort();
2088             }
2089             tcg_regset_set_reg(allocated_regs, reg);
2090         }
2091     }
2092     
2093     /* assign function address */
2094     func_arg = args[nb_oargs + nb_iargs - 1];
2095     arg_ct = &def->args_ct[0];
2096     ts = &s->temps[func_arg];
2097     func_addr = ts->val;
2098     const_func_arg = 0;
2099     if (ts->val_type == TEMP_VAL_MEM) {
2100         reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2101         tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2102         func_arg = reg;
2103         tcg_regset_set_reg(allocated_regs, reg);
2104     } else if (ts->val_type == TEMP_VAL_REG) {
2105         reg = ts->reg;
2106         if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2107             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2108             tcg_out_mov(s, ts->type, reg, ts->reg);
2109         }
2110         func_arg = reg;
2111         tcg_regset_set_reg(allocated_regs, reg);
2112     } else if (ts->val_type == TEMP_VAL_CONST) {
2113         if (tcg_target_const_match(func_addr, arg_ct)) {
2114             const_func_arg = 1;
2115             func_arg = func_addr;
2116         } else {
2117             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2118             tcg_out_movi(s, ts->type, reg, func_addr);
2119             func_arg = reg;
2120             tcg_regset_set_reg(allocated_regs, reg);
2121         }
2122     } else {
2123         tcg_abort();
2124     }
2125         
2126     
2127     /* mark dead temporaries and free the associated registers */
2128     for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2129         if (IS_DEAD_ARG(i)) {
2130             temp_dead(s, args[i]);
2131         }
2132     }
2133     
2134     /* clobber call registers */
2135     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2136         if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2137             tcg_reg_free(s, reg);
2138         }
2139     }
2140
2141     /* Save globals if they might be written by the helper, sync them if
2142        they might be read. */
2143     if (flags & TCG_CALL_NO_READ_GLOBALS) {
2144         /* Nothing to do */
2145     } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2146         sync_globals(s, allocated_regs);
2147     } else {
2148         save_globals(s, allocated_regs);
2149     }
2150
2151     tcg_out_op(s, opc, &func_arg, &const_func_arg);
2152
2153     /* assign output registers and emit moves if needed */
2154     for(i = 0; i < nb_oargs; i++) {
2155         arg = args[i];
2156         ts = &s->temps[arg];
2157         reg = tcg_target_call_oarg_regs[i];
2158         assert(s->reg_to_temp[reg] == -1);
2159         if (ts->fixed_reg) {
2160             if (ts->reg != reg) {
2161                 tcg_out_mov(s, ts->type, ts->reg, reg);
2162             }
2163         } else {
2164             if (ts->val_type == TEMP_VAL_REG) {
2165                 s->reg_to_temp[ts->reg] = -1;
2166             }
2167             ts->val_type = TEMP_VAL_REG;
2168             ts->reg = reg;
2169             ts->mem_coherent = 0;
2170             s->reg_to_temp[reg] = arg;
2171             if (NEED_SYNC_ARG(i)) {
2172                 tcg_reg_sync(s, reg);
2173             }
2174             if (IS_DEAD_ARG(i)) {
2175                 temp_dead(s, args[i]);
2176             }
2177         }
2178     }
2179     
2180     return nb_iargs + nb_oargs + def->nb_cargs + 1;
2181 }
2182
2183 #ifdef CONFIG_PROFILER
2184
2185 static int64_t tcg_table_op_count[NB_OPS];
2186
2187 static void dump_op_count(void)
2188 {
2189     int i;
2190     FILE *f;
2191     f = fopen("/tmp/op.log", "w");
2192     for(i = INDEX_op_end; i < NB_OPS; i++) {
2193         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2194     }
2195     fclose(f);
2196 }
2197 #endif
2198
2199
2200 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2201                                       long search_pc)
2202 {
2203     TCGOpcode opc;
2204     int op_index;
2205     const TCGOpDef *def;
2206     const TCGArg *args;
2207
2208 #ifdef DEBUG_DISAS
2209     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2210         qemu_log("OP:\n");
2211         tcg_dump_ops(s);
2212         qemu_log("\n");
2213     }
2214 #endif
2215
2216 #ifdef CONFIG_PROFILER
2217     s->opt_time -= profile_getclock();
2218 #endif
2219
2220 #ifdef USE_TCG_OPTIMIZATIONS
2221     s->gen_opparam_ptr =
2222         tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2223 #endif
2224
2225 #ifdef CONFIG_PROFILER
2226     s->opt_time += profile_getclock();
2227     s->la_time -= profile_getclock();
2228 #endif
2229
2230     tcg_liveness_analysis(s);
2231
2232 #ifdef CONFIG_PROFILER
2233     s->la_time += profile_getclock();
2234 #endif
2235
2236 #ifdef DEBUG_DISAS
2237     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2238         qemu_log("OP after optimization and liveness analysis:\n");
2239         tcg_dump_ops(s);
2240         qemu_log("\n");
2241     }
2242 #endif
2243
2244     tcg_reg_alloc_start(s);
2245
2246     s->code_buf = gen_code_buf;
2247     s->code_ptr = gen_code_buf;
2248
2249     args = s->gen_opparam_buf;
2250     op_index = 0;
2251
2252     for(;;) {
2253         opc = s->gen_opc_buf[op_index];
2254 #ifdef CONFIG_PROFILER
2255         tcg_table_op_count[opc]++;
2256 #endif
2257         def = &tcg_op_defs[opc];
2258 #if 0
2259         printf("%s: %d %d %d\n", def->name,
2260                def->nb_oargs, def->nb_iargs, def->nb_cargs);
2261         //        dump_regs(s);
2262 #endif
2263         switch(opc) {
2264         case INDEX_op_mov_i32:
2265         case INDEX_op_mov_i64:
2266             tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2267                               s->op_sync_args[op_index]);
2268             break;
2269         case INDEX_op_movi_i32:
2270         case INDEX_op_movi_i64:
2271             tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2272                                s->op_sync_args[op_index]);
2273             break;
2274         case INDEX_op_debug_insn_start:
2275             /* debug instruction */
2276             break;
2277         case INDEX_op_nop:
2278         case INDEX_op_nop1:
2279         case INDEX_op_nop2:
2280         case INDEX_op_nop3:
2281             break;
2282         case INDEX_op_nopn:
2283             args += args[0];
2284             goto next;
2285         case INDEX_op_discard:
2286             temp_dead(s, args[0]);
2287             break;
2288         case INDEX_op_set_label:
2289             tcg_reg_alloc_bb_end(s, s->reserved_regs);
2290             tcg_out_label(s, args[0], s->code_ptr);
2291             break;
2292         case INDEX_op_call:
2293             args += tcg_reg_alloc_call(s, def, opc, args,
2294                                        s->op_dead_args[op_index],
2295                                        s->op_sync_args[op_index]);
2296             goto next;
2297         case INDEX_op_end:
2298             goto the_end;
2299         default:
2300             /* Sanity check that we've not introduced any unhandled opcodes. */
2301             if (def->flags & TCG_OPF_NOT_PRESENT) {
2302                 tcg_abort();
2303             }
2304             /* Note: in order to speed up the code, it would be much
2305                faster to have specialized register allocator functions for
2306                some common argument patterns */
2307             tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2308                              s->op_sync_args[op_index]);
2309             break;
2310         }
2311         args += def->nb_args;
2312     next:
2313         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2314             return op_index;
2315         }
2316         op_index++;
2317 #ifndef NDEBUG
2318         check_regs(s);
2319 #endif
2320     }
2321  the_end:
2322 #if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
2323     /* Generate TB finalization at the end of block */
2324     tcg_out_tb_finalize(s);
2325 #endif
2326     return -1;
2327 }
2328
2329 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2330 {
2331 #ifdef CONFIG_PROFILER
2332     {
2333         int n;
2334         n = (s->gen_opc_ptr - s->gen_opc_buf);
2335         s->op_count += n;
2336         if (n > s->op_count_max)
2337             s->op_count_max = n;
2338
2339         s->temp_count += s->nb_temps;
2340         if (s->nb_temps > s->temp_count_max)
2341             s->temp_count_max = s->nb_temps;
2342     }
2343 #endif
2344
2345     tcg_gen_code_common(s, gen_code_buf, -1);
2346
2347     /* flush instruction cache */
2348     flush_icache_range((tcg_target_ulong)gen_code_buf,
2349                        (tcg_target_ulong)s->code_ptr);
2350
2351     return s->code_ptr -  gen_code_buf;
2352 }
2353
2354 /* Return the index of the micro operation such as the pc after is <
2355    offset bytes from the start of the TB.  The contents of gen_code_buf must
2356    not be changed, though writing the same values is ok.
2357    Return -1 if not found. */
2358 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2359 {
2360     return tcg_gen_code_common(s, gen_code_buf, offset);
2361 }
2362
2363 #ifdef CONFIG_PROFILER
2364 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2365 {
2366     TCGContext *s = &tcg_ctx;
2367     int64_t tot;
2368
2369     tot = s->interm_time + s->code_time;
2370     cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2371                 tot, tot / 2.4e9);
2372     cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
2373                 s->tb_count, 
2374                 s->tb_count1 - s->tb_count,
2375                 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2376     cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
2377                 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2378     cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
2379                 s->tb_count ? 
2380                 (double)s->del_op_count / s->tb_count : 0);
2381     cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
2382                 s->tb_count ? 
2383                 (double)s->temp_count / s->tb_count : 0,
2384                 s->temp_count_max);
2385     
2386     cpu_fprintf(f, "cycles/op           %0.1f\n", 
2387                 s->op_count ? (double)tot / s->op_count : 0);
2388     cpu_fprintf(f, "cycles/in byte      %0.1f\n", 
2389                 s->code_in_len ? (double)tot / s->code_in_len : 0);
2390     cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
2391                 s->code_out_len ? (double)tot / s->code_out_len : 0);
2392     if (tot == 0)
2393         tot = 1;
2394     cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
2395                 (double)s->interm_time / tot * 100.0);
2396     cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
2397                 (double)s->code_time / tot * 100.0);
2398     cpu_fprintf(f, "optim./code time    %0.1f%%\n",
2399                 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2400                 * 100.0);
2401     cpu_fprintf(f, "liveness/code time  %0.1f%%\n", 
2402                 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2403     cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
2404                 s->restore_count);
2405     cpu_fprintf(f, "  avg cycles        %0.1f\n",
2406                 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2407
2408     dump_op_count();
2409 }
2410 #else
2411 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2412 {
2413     cpu_fprintf(f, "[TCG profiler not compiled]\n");
2414 }
2415 #endif
2416
2417 #ifdef ELF_HOST_MACHINE
2418 /* In order to use this feature, the backend needs to do three things:
2419
2420    (1) Define ELF_HOST_MACHINE to indicate both what value to
2421        put into the ELF image and to indicate support for the feature.
2422
2423    (2) Define tcg_register_jit.  This should create a buffer containing
2424        the contents of a .debug_frame section that describes the post-
2425        prologue unwind info for the tcg machine.
2426
2427    (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2428 */
2429
2430 /* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
2431 typedef enum {
2432     JIT_NOACTION = 0,
2433     JIT_REGISTER_FN,
2434     JIT_UNREGISTER_FN
2435 } jit_actions_t;
2436
2437 struct jit_code_entry {
2438     struct jit_code_entry *next_entry;
2439     struct jit_code_entry *prev_entry;
2440     const void *symfile_addr;
2441     uint64_t symfile_size;
2442 };
2443
2444 struct jit_descriptor {
2445     uint32_t version;
2446     uint32_t action_flag;
2447     struct jit_code_entry *relevant_entry;
2448     struct jit_code_entry *first_entry;
2449 };
2450
2451 void __jit_debug_register_code(void) __attribute__((noinline));
2452 void __jit_debug_register_code(void)
2453 {
2454     asm("");
2455 }
2456
2457 /* Must statically initialize the version, because GDB may check
2458    the version before we can set it.  */
2459 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2460
2461 /* End GDB interface.  */
2462
2463 static int find_string(const char *strtab, const char *str)
2464 {
2465     const char *p = strtab + 1;
2466
2467     while (1) {
2468         if (strcmp(p, str) == 0) {
2469             return p - strtab;
2470         }
2471         p += strlen(p) + 1;
2472     }
2473 }
2474
2475 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2476                                  void *debug_frame, size_t debug_frame_size)
2477 {
2478     struct __attribute__((packed)) DebugInfo {
2479         uint32_t  len;
2480         uint16_t  version;
2481         uint32_t  abbrev;
2482         uint8_t   ptr_size;
2483         uint8_t   cu_die;
2484         uint16_t  cu_lang;
2485         uintptr_t cu_low_pc;
2486         uintptr_t cu_high_pc;
2487         uint8_t   fn_die;
2488         char      fn_name[16];
2489         uintptr_t fn_low_pc;
2490         uintptr_t fn_high_pc;
2491         uint8_t   cu_eoc;
2492     };
2493
2494     struct ElfImage {
2495         ElfW(Ehdr) ehdr;
2496         ElfW(Phdr) phdr;
2497         ElfW(Shdr) shdr[7];
2498         ElfW(Sym)  sym[2];
2499         struct DebugInfo di;
2500         uint8_t    da[24];
2501         char       str[80];
2502     };
2503
2504     struct ElfImage *img;
2505
2506     static const struct ElfImage img_template = {
2507         .ehdr = {
2508             .e_ident[EI_MAG0] = ELFMAG0,
2509             .e_ident[EI_MAG1] = ELFMAG1,
2510             .e_ident[EI_MAG2] = ELFMAG2,
2511             .e_ident[EI_MAG3] = ELFMAG3,
2512             .e_ident[EI_CLASS] = ELF_CLASS,
2513             .e_ident[EI_DATA] = ELF_DATA,
2514             .e_ident[EI_VERSION] = EV_CURRENT,
2515             .e_type = ET_EXEC,
2516             .e_machine = ELF_HOST_MACHINE,
2517             .e_version = EV_CURRENT,
2518             .e_phoff = offsetof(struct ElfImage, phdr),
2519             .e_shoff = offsetof(struct ElfImage, shdr),
2520             .e_ehsize = sizeof(ElfW(Shdr)),
2521             .e_phentsize = sizeof(ElfW(Phdr)),
2522             .e_phnum = 1,
2523             .e_shentsize = sizeof(ElfW(Shdr)),
2524             .e_shnum = ARRAY_SIZE(img->shdr),
2525             .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2526 #ifdef ELF_HOST_FLAGS
2527             .e_flags = ELF_HOST_FLAGS,
2528 #endif
2529 #ifdef ELF_OSABI
2530             .e_ident[EI_OSABI] = ELF_OSABI,
2531 #endif
2532         },
2533         .phdr = {
2534             .p_type = PT_LOAD,
2535             .p_flags = PF_X,
2536         },
2537         .shdr = {
2538             [0] = { .sh_type = SHT_NULL },
2539             /* Trick: The contents of code_gen_buffer are not present in
2540                this fake ELF file; that got allocated elsewhere.  Therefore
2541                we mark .text as SHT_NOBITS (similar to .bss) so that readers
2542                will not look for contents.  We can record any address.  */
2543             [1] = { /* .text */
2544                 .sh_type = SHT_NOBITS,
2545                 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2546             },
2547             [2] = { /* .debug_info */
2548                 .sh_type = SHT_PROGBITS,
2549                 .sh_offset = offsetof(struct ElfImage, di),
2550                 .sh_size = sizeof(struct DebugInfo),
2551             },
2552             [3] = { /* .debug_abbrev */
2553                 .sh_type = SHT_PROGBITS,
2554                 .sh_offset = offsetof(struct ElfImage, da),
2555                 .sh_size = sizeof(img->da),
2556             },
2557             [4] = { /* .debug_frame */
2558                 .sh_type = SHT_PROGBITS,
2559                 .sh_offset = sizeof(struct ElfImage),
2560             },
2561             [5] = { /* .symtab */
2562                 .sh_type = SHT_SYMTAB,
2563                 .sh_offset = offsetof(struct ElfImage, sym),
2564                 .sh_size = sizeof(img->sym),
2565                 .sh_info = 1,
2566                 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2567                 .sh_entsize = sizeof(ElfW(Sym)),
2568             },
2569             [6] = { /* .strtab */
2570                 .sh_type = SHT_STRTAB,
2571                 .sh_offset = offsetof(struct ElfImage, str),
2572                 .sh_size = sizeof(img->str),
2573             }
2574         },
2575         .sym = {
2576             [1] = { /* code_gen_buffer */
2577                 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2578                 .st_shndx = 1,
2579             }
2580         },
2581         .di = {
2582             .len = sizeof(struct DebugInfo) - 4,
2583             .version = 2,
2584             .ptr_size = sizeof(void *),
2585             .cu_die = 1,
2586             .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
2587             .fn_die = 2,
2588             .fn_name = "code_gen_buffer"
2589         },
2590         .da = {
2591             1,          /* abbrev number (the cu) */
2592             0x11, 1,    /* DW_TAG_compile_unit, has children */
2593             0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
2594             0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2595             0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2596             0, 0,       /* end of abbrev */
2597             2,          /* abbrev number (the fn) */
2598             0x2e, 0,    /* DW_TAG_subprogram, no children */
2599             0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
2600             0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
2601             0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
2602             0, 0,       /* end of abbrev */
2603             0           /* no more abbrev */
2604         },
2605         .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2606                ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2607     };
2608
2609     /* We only need a single jit entry; statically allocate it.  */
2610     static struct jit_code_entry one_entry;
2611
2612     uintptr_t buf = (uintptr_t)buf_ptr;
2613     size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2614
2615     img = g_malloc(img_size);
2616     *img = img_template;
2617     memcpy(img + 1, debug_frame, debug_frame_size);
2618
2619     img->phdr.p_vaddr = buf;
2620     img->phdr.p_paddr = buf;
2621     img->phdr.p_memsz = buf_size;
2622
2623     img->shdr[1].sh_name = find_string(img->str, ".text");
2624     img->shdr[1].sh_addr = buf;
2625     img->shdr[1].sh_size = buf_size;
2626
2627     img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2628     img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2629
2630     img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2631     img->shdr[4].sh_size = debug_frame_size;
2632
2633     img->shdr[5].sh_name = find_string(img->str, ".symtab");
2634     img->shdr[6].sh_name = find_string(img->str, ".strtab");
2635
2636     img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2637     img->sym[1].st_value = buf;
2638     img->sym[1].st_size = buf_size;
2639
2640     img->di.cu_low_pc = buf;
2641     img->di.cu_high_pc = buf_size;
2642     img->di.fn_low_pc = buf;
2643     img->di.fn_high_pc = buf_size;
2644
2645 #ifdef DEBUG_JIT
2646     /* Enable this block to be able to debug the ELF image file creation.
2647        One can use readelf, objdump, or other inspection utilities.  */
2648     {
2649         FILE *f = fopen("/tmp/qemu.jit", "w+b");
2650         if (f) {
2651             if (fwrite(img, img_size, 1, f) != img_size) {
2652                 /* Avoid stupid unused return value warning for fwrite.  */
2653             }
2654             fclose(f);
2655         }
2656     }
2657 #endif
2658
2659     one_entry.symfile_addr = img;
2660     one_entry.symfile_size = img_size;
2661
2662     __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2663     __jit_debug_descriptor.relevant_entry = &one_entry;
2664     __jit_debug_descriptor.first_entry = &one_entry;
2665     __jit_debug_register_code();
2666 }
2667 #else
2668 /* No support for the feature.  Provide the entry point expected by exec.c,
2669    and implement the internal function we declared earlier.  */
2670
2671 static void tcg_register_jit_int(void *buf, size_t size,
2672                                  void *debug_frame, size_t debug_frame_size)
2673 {
2674 }
2675
2676 void tcg_register_jit(void *buf, size_t buf_size)
2677 {
2678 }
2679 #endif /* ELF_HOST_MACHINE */
This page took 0.168573 seconds and 4 git commands to generate.