Fix TCG relocation bug (exposed by fault after brcond op). Add FIXME for
[qemu] / 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 suppress various consistency checks (faster) */
26 #define NDEBUG
27
28 /* define it to use liveness analysis (better code) */
29 #define USE_LIVENESS_ANALYSIS
30
31 #include <assert.h>
32 #include <stdarg.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <inttypes.h>
37 #ifdef _WIN32
38 #include <malloc.h>
39 #endif
40
41 #include "config.h"
42 #include "osdep.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 #include "exec-all.h"
50
51 #include "tcg-op.h"
52 #include "elf.h"
53
54
55 static void patch_reloc(uint8_t *code_ptr, int type, 
56                         tcg_target_long value);
57
58 TCGOpDef tcg_op_defs[] = {
59 #define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
60 #define DEF2(s, iargs, oargs, cargs, flags) { #s, iargs, oargs, cargs, iargs + oargs + cargs, flags, 0 },
61 #include "tcg-opc.h"
62 #undef DEF
63 #undef DEF2
64 };
65
66 TCGRegSet tcg_target_available_regs[2];
67 TCGRegSet tcg_target_call_clobber_regs;
68
69 /* XXX: move that inside the context */
70 uint16_t *gen_opc_ptr;
71 TCGArg *gen_opparam_ptr;
72
73 static inline void tcg_out8(TCGContext *s, uint8_t v)
74 {
75     *s->code_ptr++ = v;
76 }
77
78 static inline void tcg_out16(TCGContext *s, uint16_t v)
79 {
80     *(uint16_t *)s->code_ptr = v;
81     s->code_ptr += 2;
82 }
83
84 static inline void tcg_out32(TCGContext *s, uint32_t v)
85 {
86     *(uint32_t *)s->code_ptr = v;
87     s->code_ptr += 4;
88 }
89
90 /* label relocation processing */
91
92 void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, 
93                    int label_index, long addend)
94 {
95     TCGLabel *l;
96     TCGRelocation *r;
97
98     l = &s->labels[label_index];
99     if (l->has_value) {
100         /* FIXME: This is wrong.  We can not resolve the relocation
101            immediately because the caller has not yet written the
102            initial value.  */
103         patch_reloc(code_ptr, type, l->u.value + addend);
104     } else {
105         /* add a new relocation entry */
106         r = tcg_malloc(sizeof(TCGRelocation));
107         r->type = type;
108         r->ptr = code_ptr;
109         r->addend = addend;
110         r->next = l->u.first_reloc;
111         l->u.first_reloc = r;
112     }
113 }
114
115 static void tcg_out_label(TCGContext *s, int label_index, 
116                           tcg_target_long value)
117 {
118     TCGLabel *l;
119     TCGRelocation *r;
120
121     l = &s->labels[label_index];
122     if (l->has_value)
123         tcg_abort();
124     r = l->u.first_reloc;
125     while (r != NULL) {
126         patch_reloc(r->ptr, r->type, value + r->addend);
127         r = r->next;
128     }
129     l->has_value = 1;
130     l->u.value = value;
131 }
132
133 int gen_new_label(void)
134 {
135     TCGContext *s = &tcg_ctx;
136     int idx;
137     TCGLabel *l;
138
139     if (s->nb_labels >= TCG_MAX_LABELS)
140         tcg_abort();
141     idx = s->nb_labels++;
142     l = &s->labels[idx];
143     l->has_value = 0;
144     l->u.first_reloc = NULL;
145     return idx;
146 }
147
148 #include "tcg-target.c"
149
150 /* XXX: factorize */
151 static void pstrcpy(char *buf, int buf_size, const char *str)
152 {
153     int c;
154     char *q = buf;
155
156     if (buf_size <= 0)
157         return;
158
159     for(;;) {
160         c = *str++;
161         if (c == 0 || q >= buf + buf_size - 1)
162             break;
163         *q++ = c;
164     }
165     *q = '\0';
166 }
167
168 #if TCG_TARGET_REG_BITS == 32
169 /* strcat and truncate. */
170 static char *pstrcat(char *buf, int buf_size, const char *s)
171 {
172     int len;
173     len = strlen(buf);
174     if (len < buf_size)
175         pstrcpy(buf + len, buf_size - len, s);
176     return buf;
177 }
178 #endif
179
180 /* pool based memory allocation */
181 void *tcg_malloc_internal(TCGContext *s, int size)
182 {
183     TCGPool *p;
184     int pool_size;
185     
186     if (size > TCG_POOL_CHUNK_SIZE) {
187         /* big malloc: insert a new pool (XXX: could optimize) */
188         p = qemu_malloc(sizeof(TCGPool) + size);
189         p->size = size;
190         if (s->pool_current)
191             s->pool_current->next = p;
192         else
193             s->pool_first = p;
194         p->next = s->pool_current;
195     } else {
196         p = s->pool_current;
197         if (!p) {
198             p = s->pool_first;
199             if (!p)
200                 goto new_pool;
201         } else {
202             if (!p->next) {
203             new_pool:
204                 pool_size = TCG_POOL_CHUNK_SIZE;
205                 p = qemu_malloc(sizeof(TCGPool) + pool_size);
206                 p->size = pool_size;
207                 p->next = NULL;
208                 if (s->pool_current) 
209                     s->pool_current->next = p;
210                 else
211                     s->pool_first = p;
212             } else {
213                 p = p->next;
214             }
215         }
216     }
217     s->pool_current = p;
218     s->pool_cur = p->data + size;
219     s->pool_end = p->data + p->size;
220     return p->data;
221 }
222
223 void tcg_pool_reset(TCGContext *s)
224 {
225     s->pool_cur = s->pool_end = NULL;
226     s->pool_current = NULL;
227 }
228
229 /* free all the pool */
230 void tcg_pool_free(TCGContext *s)
231 {
232     TCGPool *p, *p1;
233
234     for(p = s->pool_first; p != NULL; p = p1) {
235         p1 = p->next;
236         qemu_free(p);
237     }
238     s->pool_first = NULL;
239     s->pool_cur = s->pool_end = NULL;
240 }
241
242 void tcg_context_init(TCGContext *s)
243 {
244     int op, total_args, n;
245     TCGOpDef *def;
246     TCGArgConstraint *args_ct;
247     int *sorted_args;
248
249     memset(s, 0, sizeof(*s));
250     s->temps = s->static_temps;
251     s->nb_globals = 0;
252     
253     /* Count total number of arguments and allocate the corresponding
254        space */
255     total_args = 0;
256     for(op = 0; op < NB_OPS; op++) {
257         def = &tcg_op_defs[op];
258         n = def->nb_iargs + def->nb_oargs;
259         total_args += n;
260     }
261
262     args_ct = qemu_malloc(sizeof(TCGArgConstraint) * total_args);
263     sorted_args = qemu_malloc(sizeof(int) * total_args);
264
265     for(op = 0; op < NB_OPS; op++) {
266         def = &tcg_op_defs[op];
267         def->args_ct = args_ct;
268         def->sorted_args = sorted_args;
269         n = def->nb_iargs + def->nb_oargs;
270         sorted_args += n;
271         args_ct += n;
272     }
273     
274     tcg_target_init(s);
275 }
276
277 void tcg_set_frame(TCGContext *s, int reg,
278                    tcg_target_long start, tcg_target_long size)
279 {
280     s->frame_start = start;
281     s->frame_end = start + size;
282     s->frame_reg = reg;
283 }
284
285 void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func)
286 {
287     s->macro_func = func;
288 }
289
290 void tcg_func_start(TCGContext *s)
291 {
292     tcg_pool_reset(s);
293     s->nb_temps = s->nb_globals;
294     s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
295     s->nb_labels = 0;
296     s->current_frame_offset = s->frame_start;
297
298     gen_opc_ptr = gen_opc_buf;
299     gen_opparam_ptr = gen_opparam_buf;
300 }
301
302 static inline void tcg_temp_alloc(TCGContext *s, int n)
303 {
304     if (n > TCG_MAX_TEMPS)
305         tcg_abort();
306 }
307
308 TCGv tcg_global_reg_new(TCGType type, int reg, const char *name)
309 {
310     TCGContext *s = &tcg_ctx;
311     TCGTemp *ts;
312     int idx;
313
314 #if TCG_TARGET_REG_BITS == 32
315     if (type != TCG_TYPE_I32)
316         tcg_abort();
317 #endif
318     if (tcg_regset_test_reg(s->reserved_regs, reg))
319         tcg_abort();
320     idx = s->nb_globals;
321     tcg_temp_alloc(s, s->nb_globals + 1);
322     ts = &s->temps[s->nb_globals];
323     ts->base_type = type;
324     ts->type = type;
325     ts->fixed_reg = 1;
326     ts->reg = reg;
327     ts->val_type = TEMP_VAL_REG;
328     ts->name = name;
329     s->nb_globals++;
330     tcg_regset_set_reg(s->reserved_regs, reg);
331     return MAKE_TCGV(idx);
332 }
333
334 TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
335                         const char *name)
336 {
337     TCGContext *s = &tcg_ctx;
338     TCGTemp *ts;
339     int idx;
340
341     idx = s->nb_globals;
342 #if TCG_TARGET_REG_BITS == 32
343     if (type == TCG_TYPE_I64) {
344         char buf[64];
345         tcg_temp_alloc(s, s->nb_globals + 1);
346         ts = &s->temps[s->nb_globals];
347         ts->base_type = type;
348         ts->type = TCG_TYPE_I32;
349         ts->fixed_reg = 0;
350         ts->mem_allocated = 1;
351         ts->mem_reg = reg;
352 #ifdef TCG_TARGET_WORDS_BIGENDIAN
353         ts->mem_offset = offset + 4;
354 #else
355         ts->mem_offset = offset;
356 #endif
357         ts->val_type = TEMP_VAL_MEM;
358         pstrcpy(buf, sizeof(buf), name);
359         pstrcat(buf, sizeof(buf), "_0");
360         ts->name = strdup(buf);
361         ts++;
362
363         ts->base_type = type;
364         ts->type = TCG_TYPE_I32;
365         ts->fixed_reg = 0;
366         ts->mem_allocated = 1;
367         ts->mem_reg = reg;
368 #ifdef TCG_TARGET_WORDS_BIGENDIAN
369         ts->mem_offset = offset;
370 #else
371         ts->mem_offset = offset + 4;
372 #endif
373         ts->val_type = TEMP_VAL_MEM;
374         pstrcpy(buf, sizeof(buf), name);
375         pstrcat(buf, sizeof(buf), "_1");
376         ts->name = strdup(buf);
377
378         s->nb_globals += 2;
379     } else
380 #endif
381     {
382         tcg_temp_alloc(s, s->nb_globals + 1);
383         ts = &s->temps[s->nb_globals];
384         ts->base_type = type;
385         ts->type = type;
386         ts->fixed_reg = 0;
387         ts->mem_allocated = 1;
388         ts->mem_reg = reg;
389         ts->mem_offset = offset;
390         ts->val_type = TEMP_VAL_MEM;
391         ts->name = name;
392         s->nb_globals++;
393     }
394     return MAKE_TCGV(idx);
395 }
396
397 TCGv tcg_temp_new(TCGType type)
398 {
399     TCGContext *s = &tcg_ctx;
400     TCGTemp *ts;
401     int idx;
402
403     idx = s->nb_temps;
404 #if TCG_TARGET_REG_BITS == 32
405     if (type == TCG_TYPE_I64) {
406         tcg_temp_alloc(s, s->nb_temps + 1);
407         ts = &s->temps[s->nb_temps];
408         ts->base_type = type;
409         ts->type = TCG_TYPE_I32;
410         ts->fixed_reg = 0;
411         ts->val_type = TEMP_VAL_DEAD;
412         ts->mem_allocated = 0;
413         ts->name = NULL;
414         ts++;
415         ts->base_type = TCG_TYPE_I32;
416         ts->type = TCG_TYPE_I32;
417         ts->val_type = TEMP_VAL_DEAD;
418         ts->fixed_reg = 0;
419         ts->mem_allocated = 0;
420         ts->name = NULL;
421         s->nb_temps += 2;
422     } else
423 #endif
424     {
425         tcg_temp_alloc(s, s->nb_temps + 1);
426         ts = &s->temps[s->nb_temps];
427         ts->base_type = type;
428         ts->type = type;
429         ts->fixed_reg = 0;
430         ts->val_type = TEMP_VAL_DEAD;
431         ts->mem_allocated = 0;
432         ts->name = NULL;
433         s->nb_temps++;
434     }
435     return MAKE_TCGV(idx);
436 }
437
438 TCGv tcg_const_i32(int32_t val)
439 {
440     TCGContext *s = &tcg_ctx;
441     TCGTemp *ts;
442     int idx;
443
444     idx = s->nb_temps;
445     tcg_temp_alloc(s, idx + 1);
446     ts = &s->temps[idx];
447     ts->base_type = ts->type = TCG_TYPE_I32;
448     ts->val_type = TEMP_VAL_CONST;
449     ts->name = NULL;
450     ts->val = val;
451     s->nb_temps++;
452     return MAKE_TCGV(idx);
453 }
454
455 TCGv tcg_const_i64(int64_t val)
456 {
457     TCGContext *s = &tcg_ctx;
458     TCGTemp *ts;
459     int idx;
460
461     idx = s->nb_temps;
462 #if TCG_TARGET_REG_BITS == 32
463     tcg_temp_alloc(s, idx + 2);
464     ts = &s->temps[idx];
465     ts->base_type = TCG_TYPE_I64;
466     ts->type = TCG_TYPE_I32;
467     ts->val_type = TEMP_VAL_CONST;
468     ts->name = NULL;
469     ts->val = val;
470     ts++;
471     ts->base_type = TCG_TYPE_I32;
472     ts->type = TCG_TYPE_I32;
473     ts->val_type = TEMP_VAL_CONST;
474     ts->name = NULL;
475     ts->val = val >> 32;
476     s->nb_temps += 2;
477 #else
478     tcg_temp_alloc(s, idx + 1);
479     ts = &s->temps[idx];
480     ts->base_type = ts->type = TCG_TYPE_I64;
481     ts->val_type = TEMP_VAL_CONST;
482     ts->name = NULL;
483     ts->val = val;
484     s->nb_temps++;
485 #endif    
486     return MAKE_TCGV(idx);
487 }
488
489 void tcg_register_helper(void *func, const char *name)
490 {
491     TCGContext *s = &tcg_ctx;
492     int n;
493     if ((s->nb_helpers + 1) > s->allocated_helpers) {
494         n = s->allocated_helpers;
495         if (n == 0) {
496             n = 4;
497         } else {
498             n *= 2;
499         }
500         s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
501         s->allocated_helpers = n;
502     }
503     s->helpers[s->nb_helpers].func = func;
504     s->helpers[s->nb_helpers].name = name;
505     s->nb_helpers++;
506 }
507
508 const char *tcg_helper_get_name(TCGContext *s, void *func)
509 {
510     int i;
511
512     for(i = 0; i < s->nb_helpers; i++) {
513         if (s->helpers[i].func == func)
514             return s->helpers[i].name;
515     }
516     return NULL;
517 }
518
519 static inline TCGType tcg_get_base_type(TCGContext *s, TCGv arg)
520 {
521     return s->temps[GET_TCGV(arg)].base_type;
522 }
523
524 static void tcg_gen_call_internal(TCGContext *s, TCGv func, 
525                                   unsigned int flags,
526                                   unsigned int nb_rets, const TCGv *rets,
527                                   unsigned int nb_params, const TCGv *params)
528 {
529     int i;
530     *gen_opc_ptr++ = INDEX_op_call;
531     *gen_opparam_ptr++ = (nb_rets << 16) | (nb_params + 1);
532     for(i = 0; i < nb_rets; i++) {
533         *gen_opparam_ptr++ = GET_TCGV(rets[i]);
534     }
535     for(i = 0; i < nb_params; i++) {
536         *gen_opparam_ptr++ = GET_TCGV(params[i]);
537     }
538     *gen_opparam_ptr++ = GET_TCGV(func);
539
540     *gen_opparam_ptr++ = flags;
541     /* total parameters, needed to go backward in the instruction stream */
542     *gen_opparam_ptr++ = 1 + nb_rets + nb_params + 3;
543 }
544
545
546 #if TCG_TARGET_REG_BITS < 64
547 /* Note: we convert the 64 bit args to 32 bit */
548 void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
549                   unsigned int nb_rets, const TCGv *rets,
550                   unsigned int nb_params, const TCGv *args1)
551 {
552     TCGv ret, *args2, rets_2[2], arg;
553     int j, i, call_type;
554
555     if (nb_rets == 1) {
556         ret = rets[0];
557         if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) {
558             nb_rets = 2;
559             rets_2[0] = ret;
560             rets_2[1] = TCGV_HIGH(ret);
561             rets = rets_2;
562         }
563     }
564     args2 = alloca((nb_params * 2) * sizeof(TCGv));
565     j = 0;
566     call_type = (flags & TCG_CALL_TYPE_MASK);
567     for(i = 0; i < nb_params; i++) {
568         arg = args1[i];
569         if (tcg_get_base_type(s, arg) == TCG_TYPE_I64) {
570 #ifdef TCG_TARGET_I386
571             /* REGPARM case: if the third parameter is 64 bit, it is
572                allocated on the stack */
573             if (j == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
574                 call_type = TCG_CALL_TYPE_REGPARM_2;
575                 flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
576             }
577             args2[j++] = arg;
578             args2[j++] = TCGV_HIGH(arg);
579 #else
580 #ifdef TCG_TARGET_WORDS_BIGENDIAN
581             args2[j++] = TCGV_HOGH(arg);
582             args2[j++] = arg;
583 #else
584             args2[j++] = arg;
585             args2[j++] = TCGV_HIGH(arg);
586 #endif
587 #endif
588         } else {
589             args2[j++] = arg;
590         }
591     }
592     tcg_gen_call_internal(s, func, flags, 
593                           nb_rets, rets, j, args2);
594 }
595 #else
596 void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
597                   unsigned int nb_rets, const TCGv *rets,
598                   unsigned int nb_params, const TCGv *args1)
599 {
600     tcg_gen_call_internal(s, func, flags, 
601                           nb_rets, rets, nb_params, args1);
602 }
603 #endif
604
605 #if TCG_TARGET_REG_BITS == 32
606 void tcg_gen_shifti_i64(TCGv ret, TCGv arg1, 
607                         int c, int right, int arith)
608 {
609     if (c == 0)
610         return;
611     if (c >= 32) {
612         c -= 32;
613         if (right) {
614             if (arith) {
615                 tcg_gen_sari_i32(ret, TCGV_HIGH(arg1), c);
616                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
617             } else {
618                 tcg_gen_shri_i32(ret, TCGV_HIGH(arg1), c);
619                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
620             }
621         } else {
622             tcg_gen_shli_i32(TCGV_HIGH(ret), arg1, c);
623             tcg_gen_movi_i32(ret, 0);
624         }
625     } else {
626         TCGv t0, t1;
627
628         t0 = tcg_temp_new(TCG_TYPE_I32);
629         t1 = tcg_temp_new(TCG_TYPE_I32);
630         if (right) {
631             tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
632             if (arith)
633                 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
634             else 
635                 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
636             tcg_gen_shri_i32(ret, arg1, c); 
637             tcg_gen_or_i32(ret, ret, t0);
638             tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
639         } else {
640             tcg_gen_shri_i32(t0, arg1, 32 - c);
641             /* Note: ret can be the same as arg1, so we use t1 */
642             tcg_gen_shli_i32(t1, arg1, c); 
643             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
644             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
645             tcg_gen_mov_i32(ret, t1);
646         }
647     }
648 }
649 #endif
650
651 void tcg_reg_alloc_start(TCGContext *s)
652 {
653     int i;
654     TCGTemp *ts;
655     for(i = 0; i < s->nb_globals; i++) {
656         ts = &s->temps[i];
657         if (ts->fixed_reg) {
658             ts->val_type = TEMP_VAL_REG;
659         } else {
660             ts->val_type = TEMP_VAL_MEM;
661         }
662     }
663     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
664         s->reg_to_temp[i] = -1;
665     }
666 }
667
668 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
669                                  int idx)
670 {
671     TCGTemp *ts;
672
673     ts = &s->temps[idx];
674     if (idx < s->nb_globals) {
675         pstrcpy(buf, buf_size, ts->name);
676     } else {
677         if (ts->val_type == TEMP_VAL_CONST) {
678             snprintf(buf, buf_size, "$0x%" TCG_PRIlx , ts->val);
679         } else {
680             snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
681         }
682     }
683     return buf;
684 }
685
686 char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg)
687 {
688     return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV(arg));
689 }
690
691 void tcg_dump_ops(TCGContext *s, FILE *outfile)
692 {
693     const uint16_t *opc_ptr;
694     const TCGArg *args;
695     TCGArg arg;
696     int c, i, k, nb_oargs, nb_iargs, nb_cargs;
697     const TCGOpDef *def;
698     char buf[128];
699
700     opc_ptr = gen_opc_buf;
701     args = gen_opparam_buf;
702     while (opc_ptr < gen_opc_ptr) {
703         c = *opc_ptr++;
704         def = &tcg_op_defs[c];
705         fprintf(outfile, " %s ", def->name);
706         if (c == INDEX_op_call) {
707             TCGArg arg;
708             /* variable number of arguments */
709             arg = *args++;
710             nb_oargs = arg >> 16;
711             nb_iargs = arg & 0xffff;
712             nb_cargs = def->nb_cargs;
713         } else if (c == INDEX_op_nopn) {
714             /* variable number of arguments */
715             nb_cargs = *args;
716             nb_oargs = 0;
717             nb_iargs = 0;
718         } else {
719             nb_oargs = def->nb_oargs;
720             nb_iargs = def->nb_iargs;
721             nb_cargs = def->nb_cargs;
722         }
723
724         k = 0;
725         for(i = 0; i < nb_oargs; i++) {
726             if (k != 0)
727                 fprintf(outfile, ",");
728             fprintf(outfile, "%s",
729                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
730         }
731         for(i = 0; i < nb_iargs; i++) {
732             if (k != 0)
733                 fprintf(outfile, ",");
734             /* XXX: dump helper name for call */
735             fprintf(outfile, "%s",
736                     tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
737         }
738         for(i = 0; i < nb_cargs; i++) {
739             if (k != 0)
740                 fprintf(outfile, ",");
741             arg = args[k++];
742             fprintf(outfile, "$0x%" TCG_PRIlx, arg);
743         }
744         fprintf(outfile, "\n");
745         args += nb_iargs + nb_oargs + nb_cargs;
746     }
747 }
748
749 /* we give more priority to constraints with less registers */
750 static int get_constraint_priority(const TCGOpDef *def, int k)
751 {
752     const TCGArgConstraint *arg_ct;
753
754     int i, n;
755     arg_ct = &def->args_ct[k];
756     if (arg_ct->ct & TCG_CT_ALIAS) {
757         /* an alias is equivalent to a single register */
758         n = 1;
759     } else {
760         if (!(arg_ct->ct & TCG_CT_REG))
761             return 0;
762         n = 0;
763         for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
764             if (tcg_regset_test_reg(arg_ct->u.regs, i))
765                 n++;
766         }
767     }
768     return TCG_TARGET_NB_REGS - n + 1;
769 }
770
771 /* sort from highest priority to lowest */
772 static void sort_constraints(TCGOpDef *def, int start, int n)
773 {
774     int i, j, p1, p2, tmp;
775
776     for(i = 0; i < n; i++)
777         def->sorted_args[start + i] = start + i;
778     if (n <= 1)
779         return;
780     for(i = 0; i < n - 1; i++) {
781         for(j = i + 1; j < n; j++) {
782             p1 = get_constraint_priority(def, def->sorted_args[start + i]);
783             p2 = get_constraint_priority(def, def->sorted_args[start + j]);
784             if (p1 < p2) {
785                 tmp = def->sorted_args[start + i];
786                 def->sorted_args[start + i] = def->sorted_args[start + j];
787                 def->sorted_args[start + j] = tmp;
788             }
789         }
790     }
791 }
792
793 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
794 {
795     int op;
796     TCGOpDef *def;
797     const char *ct_str;
798     int i, nb_args;
799
800     for(;;) {
801         if (tdefs->op < 0)
802             break;
803         op = tdefs->op;
804         assert(op >= 0 && op < NB_OPS);
805         def = &tcg_op_defs[op];
806         nb_args = def->nb_iargs + def->nb_oargs;
807         for(i = 0; i < nb_args; i++) {
808             ct_str = tdefs->args_ct_str[i];
809             tcg_regset_clear(def->args_ct[i].u.regs);
810             def->args_ct[i].ct = 0;
811             if (ct_str[0] >= '0' && ct_str[0] <= '9') {
812                 int oarg;
813                 oarg = ct_str[0] - '0';
814                 assert(oarg < def->nb_oargs);
815                 assert(def->args_ct[oarg].ct & TCG_CT_REG);
816                 /* TCG_CT_ALIAS is for the output arguments. The input
817                    argument is tagged with TCG_CT_IALIAS. */
818                 def->args_ct[i] = def->args_ct[oarg];
819                 def->args_ct[oarg].ct = TCG_CT_ALIAS;
820                 def->args_ct[oarg].alias_index = i;
821                 def->args_ct[i].ct |= TCG_CT_IALIAS;
822                 def->args_ct[i].alias_index = oarg;
823             } else {
824                 for(;;) {
825                     if (*ct_str == '\0')
826                         break;
827                     switch(*ct_str) {
828                     case 'i':
829                         def->args_ct[i].ct |= TCG_CT_CONST;
830                         ct_str++;
831                         break;
832                     default:
833                         if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
834                             fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
835                                     ct_str, i, def->name);
836                             exit(1);
837                         }
838                     }
839                 }
840             }
841         }
842
843         /* sort the constraints (XXX: this is just an heuristic) */
844         sort_constraints(def, 0, def->nb_oargs);
845         sort_constraints(def, def->nb_oargs, def->nb_iargs);
846
847 #if 0
848         {
849             int i;
850
851             printf("%s: sorted=", def->name);
852             for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
853                 printf(" %d", def->sorted_args[i]);
854             printf("\n");
855         }
856 #endif
857         tdefs++;
858     }
859
860 }
861
862 #ifdef USE_LIVENESS_ANALYSIS
863
864 /* set a nop for an operation using 'nb_args' */
865 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 
866                                TCGArg *args, int nb_args)
867 {
868     if (nb_args == 0) {
869         *opc_ptr = INDEX_op_nop;
870     } else {
871         *opc_ptr = INDEX_op_nopn;
872         args[0] = nb_args;
873         args[nb_args - 1] = nb_args;
874     }
875 }
876
877 /* liveness analysis: end of basic block: globals are live, temps are dead */
878 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
879 {
880     memset(dead_temps, 0, s->nb_globals);
881     memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
882 }
883
884 /* Liveness analysis : update the opc_dead_iargs array to tell if a
885    given input arguments is dead. Instructions updating dead
886    temporaries are removed. */
887 void tcg_liveness_analysis(TCGContext *s)
888 {
889     int i, op_index, op, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
890     TCGArg *args;
891     const TCGOpDef *def;
892     uint8_t *dead_temps;
893     unsigned int dead_iargs;
894     
895     gen_opc_ptr++; /* skip end */
896
897     nb_ops = gen_opc_ptr - gen_opc_buf;
898
899     /* XXX: make it really dynamic */
900     s->op_dead_iargs = tcg_malloc(OPC_BUF_SIZE * sizeof(uint16_t));
901     
902     dead_temps = tcg_malloc(s->nb_temps);
903     memset(dead_temps, 1, s->nb_temps);
904
905     args = gen_opparam_ptr;
906     op_index = nb_ops - 1;
907     while (op_index >= 0) {
908         op = gen_opc_buf[op_index];
909         def = &tcg_op_defs[op];
910         switch(op) {
911         case INDEX_op_call:
912             nb_args = args[-1];
913             args -= nb_args;
914             nb_iargs = args[0] & 0xffff;
915             nb_oargs = args[0] >> 16;
916             args++;
917
918             /* output args are dead */
919             for(i = 0; i < nb_oargs; i++) {
920                 arg = args[i];
921                 dead_temps[arg] = 1;
922             }
923             
924             /* globals are live (they may be used by the call) */
925             memset(dead_temps, 0, s->nb_globals);
926
927             /* input args are live */
928             dead_iargs = 0;
929             for(i = 0; i < nb_iargs; i++) {
930                 arg = args[i + nb_oargs];
931                 if (dead_temps[arg]) {
932                     dead_iargs |= (1 << i);
933                 }
934                 dead_temps[arg] = 0;
935             }
936             s->op_dead_iargs[op_index] = dead_iargs;
937             args--;
938             break;
939         case INDEX_op_set_label:
940             args--;
941             /* mark end of basic block */
942             tcg_la_bb_end(s, dead_temps);
943             break;
944         case INDEX_op_nopn:
945             nb_args = args[-1];
946             args -= nb_args;
947             break;
948         case INDEX_op_discard:
949             args--;
950             /* mark the temporary as dead */
951             dead_temps[args[0]] = 1;
952             break;
953         case INDEX_op_macro_2:
954             {
955                 int dead_args[2], macro_id;
956                 int saved_op_index, saved_arg_index;
957                 int macro_op_index, macro_arg_index;
958                 int macro_end_op_index, macro_end_arg_index;
959                 int last_nb_temps;
960                 
961                 nb_args = 3;
962                 args -= nb_args;
963                 dead_args[0] = dead_temps[args[0]];
964                 dead_args[1] = dead_temps[args[1]];
965                 macro_id = args[2];
966
967                 /* call the macro function which generate code
968                    depending on the live outputs */
969                 saved_op_index = op_index;
970                 saved_arg_index = args - gen_opparam_buf;
971
972                 /* add a macro start instruction */
973                 *gen_opc_ptr++ = INDEX_op_macro_start;
974                 *gen_opparam_ptr++ = saved_op_index;
975                 *gen_opparam_ptr++ = saved_arg_index;
976
977                 macro_op_index = gen_opc_ptr - gen_opc_buf;
978                 macro_arg_index = gen_opparam_ptr -  gen_opparam_buf;
979
980                 last_nb_temps = s->nb_temps;
981
982                 s->macro_func(s, macro_id, dead_args);
983
984                 /* realloc temp info (XXX: make it faster) */
985                 if (s->nb_temps > last_nb_temps) {
986                     uint8_t *new_dead_temps;
987
988                     new_dead_temps = tcg_malloc(s->nb_temps);
989                     memcpy(new_dead_temps, dead_temps, last_nb_temps);
990                     memset(new_dead_temps + last_nb_temps, 1, 
991                            s->nb_temps - last_nb_temps);
992                     dead_temps = new_dead_temps;
993                 }
994
995                 macro_end_op_index = gen_opc_ptr - gen_opc_buf;
996                 macro_end_arg_index = gen_opparam_ptr - gen_opparam_buf;
997
998                 /* end of macro: add a goto to the next instruction */
999                 *gen_opc_ptr++ = INDEX_op_macro_end;
1000                 *gen_opparam_ptr++ = op_index + 1;
1001                 *gen_opparam_ptr++ = saved_arg_index + nb_args;
1002
1003                 /* modify the macro operation to be a macro_goto */
1004                 gen_opc_buf[op_index] = INDEX_op_macro_goto;
1005                 args[0] = macro_op_index;
1006                 args[1] = macro_arg_index;
1007                 args[2] = 0; /* dummy third arg to match the 
1008                                 macro parameters */
1009
1010                 /* set the next instruction to the end of the macro */
1011                 op_index = macro_end_op_index;
1012                 args = macro_end_arg_index + gen_opparam_buf;
1013             }
1014             break;
1015         case INDEX_op_macro_start:
1016             args -= 2;
1017             op_index = args[0];
1018             args = gen_opparam_buf + args[1];
1019             break;
1020         case INDEX_op_macro_goto:
1021         case INDEX_op_macro_end:
1022             tcg_abort(); /* should never happen in liveness analysis */
1023         case INDEX_op_end:
1024             break;
1025             /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1026         default:
1027             if (op > INDEX_op_end) {
1028                 args -= def->nb_args;
1029                 nb_iargs = def->nb_iargs;
1030                 nb_oargs = def->nb_oargs;
1031
1032                 /* Test if the operation can be removed because all
1033                    its outputs are dead. We assume that nb_oargs == 0
1034                    implies side effects */
1035                 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1036                     for(i = 0; i < nb_oargs; i++) {
1037                         arg = args[i];
1038                         if (!dead_temps[arg])
1039                             goto do_not_remove;
1040                     }
1041                     tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1042 #ifdef CONFIG_PROFILER
1043                     {
1044                         extern int64_t dyngen_tcg_del_op_count;
1045                         dyngen_tcg_del_op_count++;
1046                     }
1047 #endif
1048                 } else {
1049                 do_not_remove:
1050
1051                     /* output args are dead */
1052                     for(i = 0; i < nb_oargs; i++) {
1053                         arg = args[i];
1054                         dead_temps[arg] = 1;
1055                     }
1056                     
1057                     /* if end of basic block, update */
1058                     if (def->flags & TCG_OPF_BB_END) {
1059                         tcg_la_bb_end(s, dead_temps);
1060                     }
1061                     
1062                     /* input args are live */
1063                     dead_iargs = 0;
1064                     for(i = 0; i < nb_iargs; i++) {
1065                         arg = args[i + nb_oargs];
1066                         if (dead_temps[arg]) {
1067                             dead_iargs |= (1 << i);
1068                         }
1069                         dead_temps[arg] = 0;
1070                     }
1071                     s->op_dead_iargs[op_index] = dead_iargs;
1072                 }
1073             } else {
1074                 /* legacy dyngen operations */
1075                 args -= def->nb_args;
1076                 /* mark end of basic block */
1077                 tcg_la_bb_end(s, dead_temps);
1078             }
1079             break;
1080         }
1081         op_index--;
1082     }
1083
1084     if (args != gen_opparam_buf)
1085         tcg_abort();
1086 }
1087 #else
1088 /* dummy liveness analysis */
1089 void tcg_liveness_analysis(TCGContext *s)
1090 {
1091     int nb_ops;
1092     nb_ops = gen_opc_ptr - gen_opc_buf;
1093
1094     s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1095     memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
1096 }
1097 #endif
1098
1099 #ifndef NDEBUG
1100 static void dump_regs(TCGContext *s)
1101 {
1102     TCGTemp *ts;
1103     int i;
1104     char buf[64];
1105
1106     for(i = 0; i < s->nb_temps; i++) {
1107         ts = &s->temps[i];
1108         printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1109         switch(ts->val_type) {
1110         case TEMP_VAL_REG:
1111             printf("%s", tcg_target_reg_names[ts->reg]);
1112             break;
1113         case TEMP_VAL_MEM:
1114             printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1115             break;
1116         case TEMP_VAL_CONST:
1117             printf("$0x%" TCG_PRIlx, ts->val);
1118             break;
1119         case TEMP_VAL_DEAD:
1120             printf("D");
1121             break;
1122         default:
1123             printf("???");
1124             break;
1125         }
1126         printf("\n");
1127     }
1128
1129     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1130         if (s->reg_to_temp[i] >= 0) {
1131             printf("%s: %s\n", 
1132                    tcg_target_reg_names[i], 
1133                    tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1134         }
1135     }
1136 }
1137
1138 static void check_regs(TCGContext *s)
1139 {
1140     int reg, k;
1141     TCGTemp *ts;
1142     char buf[64];
1143
1144     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1145         k = s->reg_to_temp[reg];
1146         if (k >= 0) {
1147             ts = &s->temps[k];
1148             if (ts->val_type != TEMP_VAL_REG ||
1149                 ts->reg != reg) {
1150                 printf("Inconsistency for register %s:\n", 
1151                        tcg_target_reg_names[reg]);
1152                 printf("reg state:\n");
1153                 dump_regs(s);
1154                 tcg_abort();
1155             }
1156         }
1157     }
1158     for(k = 0; k < s->nb_temps; k++) {
1159         ts = &s->temps[k];
1160         if (ts->val_type == TEMP_VAL_REG &&
1161             !ts->fixed_reg &&
1162             s->reg_to_temp[ts->reg] != k) {
1163                 printf("Inconsistency for temp %s:\n", 
1164                        tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1165                 printf("reg state:\n");
1166                 dump_regs(s);
1167                 tcg_abort();
1168         }
1169     }
1170 }
1171 #endif
1172
1173 static void temp_allocate_frame(TCGContext *s, int temp)
1174 {
1175     TCGTemp *ts;
1176     ts = &s->temps[temp];
1177     s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
1178     if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
1179         tcg_abort();
1180     ts->mem_offset = s->current_frame_offset;
1181     ts->mem_reg = s->frame_reg;
1182     ts->mem_allocated = 1;
1183     s->current_frame_offset += sizeof(tcg_target_long);
1184 }
1185
1186 /* free register 'reg' by spilling the corresponding temporary if necessary */
1187 static void tcg_reg_free(TCGContext *s, int reg)
1188 {
1189     TCGTemp *ts;
1190     int temp;
1191
1192     temp = s->reg_to_temp[reg];
1193     if (temp != -1) {
1194         ts = &s->temps[temp];
1195         assert(ts->val_type == TEMP_VAL_REG);
1196         if (!ts->mem_coherent) {
1197             if (!ts->mem_allocated) 
1198                 temp_allocate_frame(s, temp);
1199             tcg_out_st(s, reg, ts->mem_reg, ts->mem_offset);
1200         }
1201         ts->val_type = TEMP_VAL_MEM;
1202         s->reg_to_temp[reg] = -1;
1203     }
1204 }
1205
1206 /* Allocate a register belonging to reg1 & ~reg2 */
1207 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1208 {
1209     int i, reg;
1210     TCGRegSet reg_ct;
1211
1212     tcg_regset_andnot(reg_ct, reg1, reg2);
1213
1214     /* first try free registers */
1215     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1216         reg = tcg_target_reg_alloc_order[i];
1217         if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1218             return reg;
1219     }
1220
1221     /* XXX: do better spill choice */
1222     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1223         reg = tcg_target_reg_alloc_order[i];
1224         if (tcg_regset_test_reg(reg_ct, reg)) {
1225             tcg_reg_free(s, reg);
1226             return reg;
1227         }
1228     }
1229
1230     tcg_abort();
1231 }
1232
1233 /* at the end of a basic block, we assume all temporaries are dead and
1234    all globals are stored at their canonical location */
1235 /* XXX: optimize by handling constants in another array ? */
1236 void tcg_reg_alloc_bb_end(TCGContext *s)
1237 {
1238     TCGTemp *ts;
1239     int i;
1240
1241     for(i = 0; i < s->nb_globals; i++) {
1242         ts = &s->temps[i];
1243         if (!ts->fixed_reg) {
1244             if (ts->val_type == TEMP_VAL_REG) {
1245                 tcg_reg_free(s, ts->reg);
1246             }
1247         }
1248     }
1249
1250     for(i = s->nb_globals; i < s->nb_temps; i++) {
1251         ts = &s->temps[i];
1252         if (ts->val_type != TEMP_VAL_CONST) {
1253             if (ts->val_type == TEMP_VAL_REG) {
1254                 s->reg_to_temp[ts->reg] = -1;
1255             }
1256             ts->val_type = TEMP_VAL_DEAD;
1257         }
1258     }
1259 }
1260
1261 #define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
1262
1263 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1264                               const TCGArg *args,
1265                               unsigned int dead_iargs)
1266 {
1267     TCGTemp *ts, *ots;
1268     int reg;
1269     const TCGArgConstraint *arg_ct;
1270
1271     ots = &s->temps[args[0]];
1272     ts = &s->temps[args[1]];
1273     arg_ct = &def->args_ct[0];
1274
1275     if (ts->val_type == TEMP_VAL_REG) {
1276         if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
1277             /* the mov can be suppressed */
1278             if (ots->val_type == TEMP_VAL_REG)
1279                 s->reg_to_temp[ots->reg] = -1;
1280             reg = ts->reg;
1281             s->reg_to_temp[reg] = -1;
1282             ts->val_type = TEMP_VAL_DEAD;
1283         } else {
1284             if (ots->val_type == TEMP_VAL_REG) {
1285                 reg = ots->reg;
1286             } else {
1287                 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1288             }
1289             if (ts->reg != reg) {
1290                 tcg_out_mov(s, reg, ts->reg);
1291             }
1292         }
1293     } else if (ts->val_type == TEMP_VAL_MEM) {
1294         if (ots->val_type == TEMP_VAL_REG) {
1295             reg = ots->reg;
1296         } else {
1297             reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1298         }
1299         tcg_out_ld(s, reg, ts->mem_reg, ts->mem_offset);
1300     } else if (ts->val_type == TEMP_VAL_CONST) {
1301         if (ots->val_type == TEMP_VAL_REG) {
1302             reg = ots->reg;
1303         } else {
1304             reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1305         }
1306         tcg_out_movi(s, ots->type, reg, ts->val);
1307     } else {
1308         tcg_abort();
1309     }
1310     s->reg_to_temp[reg] = args[0];
1311     ots->reg = reg;
1312     ots->val_type = TEMP_VAL_REG;
1313     ots->mem_coherent = 0;
1314 }
1315
1316 static void tcg_reg_alloc_op(TCGContext *s, 
1317                              const TCGOpDef *def, int opc,
1318                              const TCGArg *args,
1319                              unsigned int dead_iargs)
1320 {
1321     TCGRegSet allocated_regs;
1322     int i, k, nb_iargs, nb_oargs, reg;
1323     TCGArg arg;
1324     const TCGArgConstraint *arg_ct;
1325     TCGTemp *ts;
1326     TCGArg new_args[TCG_MAX_OP_ARGS];
1327     int const_args[TCG_MAX_OP_ARGS];
1328
1329     nb_oargs = def->nb_oargs;
1330     nb_iargs = def->nb_iargs;
1331
1332     /* copy constants */
1333     memcpy(new_args + nb_oargs + nb_iargs, 
1334            args + nb_oargs + nb_iargs, 
1335            sizeof(TCGArg) * def->nb_cargs);
1336
1337     /* satisfy input constraints */ 
1338     tcg_regset_set(allocated_regs, s->reserved_regs);
1339     for(k = 0; k < nb_iargs; k++) {
1340         i = def->sorted_args[nb_oargs + k];
1341         arg = args[i];
1342         arg_ct = &def->args_ct[i];
1343         ts = &s->temps[arg];
1344         if (ts->val_type == TEMP_VAL_MEM) {
1345             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1346             tcg_out_ld(s, reg, ts->mem_reg, ts->mem_offset);
1347             ts->val_type = TEMP_VAL_REG;
1348             ts->reg = reg;
1349             ts->mem_coherent = 1;
1350             s->reg_to_temp[reg] = arg;
1351         } else if (ts->val_type == TEMP_VAL_CONST) {
1352             if (tcg_target_const_match(ts->val, arg_ct)) {
1353                 /* constant is OK for instruction */
1354                 const_args[i] = 1;
1355                 new_args[i] = ts->val;
1356                 goto iarg_end;
1357             } else {
1358                 /* need to move to a register*/
1359                 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1360                 tcg_out_movi(s, ts->type, reg, ts->val);
1361                 goto iarg_end1;
1362             }
1363         }
1364         assert(ts->val_type == TEMP_VAL_REG);
1365         if (arg_ct->ct & TCG_CT_IALIAS) {
1366             if (ts->fixed_reg) {
1367                 /* if fixed register, we must allocate a new register
1368                    if the alias is not the same register */
1369                 if (arg != args[arg_ct->alias_index])
1370                     goto allocate_in_reg;
1371             } else {
1372                 /* if the input is aliased to an output and if it is
1373                    not dead after the instruction, we must allocate
1374                    a new register and move it */
1375                 if (!IS_DEAD_IARG(i - nb_oargs)) 
1376                     goto allocate_in_reg;
1377             }
1378         }
1379         reg = ts->reg;
1380         if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1381             /* nothing to do : the constraint is satisfied */
1382         } else {
1383         allocate_in_reg:
1384             /* allocate a new register matching the constraint 
1385                and move the temporary register into it */
1386             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1387             tcg_out_mov(s, reg, ts->reg);
1388         }
1389     iarg_end1:
1390         new_args[i] = reg;
1391         const_args[i] = 0;
1392         tcg_regset_set_reg(allocated_regs, reg);
1393     iarg_end: ;
1394     }
1395     
1396     /* mark dead temporaries and free the associated registers */
1397     for(i = 0; i < nb_iargs; i++) {
1398         arg = args[nb_oargs + i];
1399         if (IS_DEAD_IARG(i)) {
1400             ts = &s->temps[arg];
1401             if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
1402                 if (ts->val_type == TEMP_VAL_REG)
1403                     s->reg_to_temp[ts->reg] = -1;
1404                 ts->val_type = TEMP_VAL_DEAD;
1405             }
1406         }
1407     }
1408
1409     /* XXX: permit generic clobber register list ? */ 
1410     if (def->flags & TCG_OPF_CALL_CLOBBER) {
1411         for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1412             if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1413                 tcg_reg_free(s, reg);
1414             }
1415         }
1416     }
1417
1418     /* satisfy the output constraints */
1419     tcg_regset_set(allocated_regs, s->reserved_regs);
1420     for(k = 0; k < nb_oargs; k++) {
1421         i = def->sorted_args[k];
1422         arg = args[i];
1423         arg_ct = &def->args_ct[i];
1424         ts = &s->temps[arg];
1425         if (arg_ct->ct & TCG_CT_ALIAS) {
1426             reg = new_args[arg_ct->alias_index];
1427         } else {
1428             /* if fixed register, we try to use it */
1429             reg = ts->reg;
1430             if (ts->fixed_reg &&
1431                 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1432                 goto oarg_end;
1433             }
1434             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1435         }
1436         tcg_regset_set_reg(allocated_regs, reg);
1437         /* if a fixed register is used, then a move will be done afterwards */
1438         if (!ts->fixed_reg) {
1439             if (ts->val_type == TEMP_VAL_REG)
1440                 s->reg_to_temp[ts->reg] = -1;
1441             ts->val_type = TEMP_VAL_REG;
1442             ts->reg = reg;
1443             /* temp value is modified, so the value kept in memory is
1444                potentially not the same */
1445             ts->mem_coherent = 0; 
1446             s->reg_to_temp[reg] = arg;
1447         }
1448     oarg_end:
1449         new_args[i] = reg;
1450     }
1451
1452     if (def->flags & TCG_OPF_BB_END)
1453         tcg_reg_alloc_bb_end(s);
1454
1455     /* emit instruction */
1456     tcg_out_op(s, opc, new_args, const_args);
1457     
1458     /* move the outputs in the correct register if needed */
1459     for(i = 0; i < nb_oargs; i++) {
1460         ts = &s->temps[args[i]];
1461         reg = new_args[i];
1462         if (ts->fixed_reg && ts->reg != reg) {
1463             tcg_out_mov(s, ts->reg, reg);
1464         }
1465     }
1466 }
1467
1468 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1469                               int opc, const TCGArg *args,
1470                               unsigned int dead_iargs)
1471 {
1472     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1473     TCGArg arg, func_arg;
1474     TCGTemp *ts;
1475     tcg_target_long stack_offset, call_stack_size;
1476     int const_func_arg;
1477     TCGRegSet allocated_regs;
1478     const TCGArgConstraint *arg_ct;
1479
1480     arg = *args++;
1481
1482     nb_oargs = arg >> 16;
1483     nb_iargs = arg & 0xffff;
1484     nb_params = nb_iargs - 1;
1485
1486     flags = args[nb_oargs + nb_iargs];
1487
1488     nb_regs = tcg_target_get_call_iarg_regs_count(flags);
1489     if (nb_regs > nb_params)
1490         nb_regs = nb_params;
1491
1492     /* assign stack slots first */
1493     /* XXX: preallocate call stack */
1494     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1495     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
1496         ~(TCG_TARGET_STACK_ALIGN - 1);
1497     tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size);
1498
1499     stack_offset = 0;
1500     for(i = nb_regs; i < nb_params; i++) {
1501         arg = args[nb_oargs + i];
1502         ts = &s->temps[arg];
1503         if (ts->val_type == TEMP_VAL_REG) {
1504             tcg_out_st(s, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1505         } else if (ts->val_type == TEMP_VAL_MEM) {
1506             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1507                                 s->reserved_regs);
1508             /* XXX: not correct if reading values from the stack */
1509             tcg_out_ld(s, reg, ts->mem_reg, ts->mem_offset);
1510             tcg_out_st(s, reg, TCG_REG_CALL_STACK, stack_offset);
1511         } else if (ts->val_type == TEMP_VAL_CONST) {
1512             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
1513                                 s->reserved_regs);
1514             /* XXX: sign extend may be needed on some targets */
1515             tcg_out_movi(s, ts->type, reg, ts->val);
1516             tcg_out_st(s, reg, TCG_REG_CALL_STACK, stack_offset);
1517         } else {
1518             tcg_abort();
1519         }
1520         stack_offset += sizeof(tcg_target_long);
1521     }
1522     
1523     /* assign input registers */
1524     tcg_regset_set(allocated_regs, s->reserved_regs);
1525     for(i = 0; i < nb_regs; i++) {
1526         arg = args[nb_oargs + i];
1527         ts = &s->temps[arg];
1528         reg = tcg_target_call_iarg_regs[i];
1529         tcg_reg_free(s, reg);
1530         if (ts->val_type == TEMP_VAL_REG) {
1531             if (ts->reg != reg) {
1532                 tcg_out_mov(s, reg, ts->reg);
1533             }
1534         } else if (ts->val_type == TEMP_VAL_MEM) {
1535             tcg_out_ld(s, reg, ts->mem_reg, ts->mem_offset);
1536         } else if (ts->val_type == TEMP_VAL_CONST) {
1537             /* XXX: sign extend ? */
1538             tcg_out_movi(s, ts->type, reg, ts->val);
1539         } else {
1540             tcg_abort();
1541         }
1542         tcg_regset_set_reg(allocated_regs, reg);
1543     }
1544     
1545     /* assign function address */
1546     func_arg = args[nb_oargs + nb_iargs - 1];
1547     arg_ct = &def->args_ct[0];
1548     ts = &s->temps[func_arg];
1549     const_func_arg = 0;
1550     if (ts->val_type == TEMP_VAL_MEM) {
1551         reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1552         tcg_out_ld(s, reg, ts->mem_reg, ts->mem_offset);
1553         func_arg = reg;
1554     } else if (ts->val_type == TEMP_VAL_REG) {
1555         reg = ts->reg;
1556         if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1557             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1558             tcg_out_mov(s, reg, ts->reg);
1559         }
1560         func_arg = reg;
1561     } else if (ts->val_type == TEMP_VAL_CONST) {
1562         if (tcg_target_const_match(ts->val, arg_ct)) {
1563             const_func_arg = 1;
1564             func_arg = ts->val;
1565         } else {
1566             reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1567             tcg_out_movi(s, ts->type, reg, ts->val);
1568             func_arg = reg;
1569         }
1570     } else {
1571         tcg_abort();
1572     }
1573     
1574     /* mark dead temporaries and free the associated registers */
1575     for(i = 0; i < nb_params; i++) {
1576         arg = args[nb_oargs + i];
1577         if (IS_DEAD_IARG(i)) {
1578             ts = &s->temps[arg];
1579             if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
1580                 if (ts->val_type == TEMP_VAL_REG)
1581                     s->reg_to_temp[ts->reg] = -1;
1582                 ts->val_type = TEMP_VAL_DEAD;
1583             }
1584         }
1585     }
1586     
1587     /* clobber call registers */
1588     for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1589         if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1590             tcg_reg_free(s, reg);
1591         }
1592     }
1593     
1594     /* store globals and free associated registers (we assume the call
1595        can modify any global. */
1596     for(i = 0; i < s->nb_globals; i++) {
1597         ts = &s->temps[i];
1598         if (!ts->fixed_reg) {
1599             if (ts->val_type == TEMP_VAL_REG) {
1600                 tcg_reg_free(s, ts->reg);
1601             }
1602         }
1603     }
1604
1605     tcg_out_op(s, opc, &func_arg, &const_func_arg);
1606     
1607     tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size);
1608
1609     /* assign output registers and emit moves if needed */
1610     for(i = 0; i < nb_oargs; i++) {
1611         arg = args[i];
1612         ts = &s->temps[arg];
1613         reg = tcg_target_call_oarg_regs[i];
1614         tcg_reg_free(s, reg);
1615         if (ts->fixed_reg) {
1616             if (ts->reg != reg) {
1617                 tcg_out_mov(s, ts->reg, reg);
1618             }
1619         } else {
1620             if (ts->val_type == TEMP_VAL_REG)
1621                 s->reg_to_temp[ts->reg] = -1;
1622             ts->val_type = TEMP_VAL_REG;
1623             ts->reg = reg;
1624             ts->mem_coherent = 0; 
1625             s->reg_to_temp[reg] = arg;
1626         }
1627     }
1628     
1629     return nb_iargs + nb_oargs + def->nb_cargs + 1;
1630 }
1631
1632 #ifdef CONFIG_PROFILER
1633
1634 static int64_t dyngen_table_op_count[NB_OPS];
1635
1636 void dump_op_count(void)
1637 {
1638     int i;
1639     FILE *f;
1640     f = fopen("/tmp/op1.log", "w");
1641     for(i = 0; i < INDEX_op_end; i++) {
1642         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
1643     }
1644     fclose(f);
1645     f = fopen("/tmp/op2.log", "w");
1646     for(i = INDEX_op_end; i < NB_OPS; i++) {
1647         fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
1648     }
1649     fclose(f);
1650 }
1651 #endif
1652
1653
1654 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1655                                       long search_pc)
1656 {
1657     int opc, op_index, macro_op_index;
1658     const TCGOpDef *def;
1659     unsigned int dead_iargs;
1660     const TCGArg *args;
1661
1662 #ifdef DEBUG_DISAS
1663     if (unlikely(loglevel & CPU_LOG_TB_OP)) {
1664         fprintf(logfile, "OP:\n");
1665         tcg_dump_ops(s, logfile);
1666         fprintf(logfile, "\n");
1667     }
1668 #endif
1669
1670     tcg_liveness_analysis(s);
1671
1672 #ifdef DEBUG_DISAS
1673     if (unlikely(loglevel & CPU_LOG_TB_OP_OPT)) {
1674         fprintf(logfile, "OP after la:\n");
1675         tcg_dump_ops(s, logfile);
1676         fprintf(logfile, "\n");
1677     }
1678 #endif
1679
1680     tcg_reg_alloc_start(s);
1681
1682     s->code_buf = gen_code_buf;
1683     s->code_ptr = gen_code_buf;
1684
1685     macro_op_index = -1;
1686     args = gen_opparam_buf;
1687     op_index = 0;
1688     for(;;) {
1689         opc = gen_opc_buf[op_index];
1690 #ifdef CONFIG_PROFILER
1691         dyngen_table_op_count[opc]++;
1692 #endif
1693         def = &tcg_op_defs[opc];
1694 #if 0
1695         printf("%s: %d %d %d\n", def->name,
1696                def->nb_oargs, def->nb_iargs, def->nb_cargs);
1697         //        dump_regs(s);
1698 #endif
1699         switch(opc) {
1700         case INDEX_op_mov_i32:
1701 #if TCG_TARGET_REG_BITS == 64
1702         case INDEX_op_mov_i64:
1703 #endif
1704             dead_iargs = s->op_dead_iargs[op_index];
1705             tcg_reg_alloc_mov(s, def, args, dead_iargs);
1706             break;
1707         case INDEX_op_nop:
1708         case INDEX_op_nop1:
1709         case INDEX_op_nop2:
1710         case INDEX_op_nop3:
1711             break;
1712         case INDEX_op_nopn:
1713             args += args[0];
1714             goto next;
1715         case INDEX_op_discard:
1716             {
1717                 TCGTemp *ts;
1718                 ts = &s->temps[args[0]];
1719                 /* mark the temporary as dead */
1720                 if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
1721                     if (ts->val_type == TEMP_VAL_REG)
1722                         s->reg_to_temp[ts->reg] = -1;
1723                     ts->val_type = TEMP_VAL_DEAD;
1724                 }
1725             }
1726             break;
1727         case INDEX_op_macro_goto:
1728             macro_op_index = op_index; /* only used for exceptions */
1729             op_index = args[0] - 1;
1730             args = gen_opparam_buf + args[1];
1731             goto next;
1732         case INDEX_op_macro_end:
1733             macro_op_index = -1; /* only used for exceptions */
1734             op_index = args[0] - 1;
1735             args = gen_opparam_buf + args[1];
1736             goto next;
1737         case INDEX_op_macro_start:
1738             /* must never happen here */
1739             tcg_abort();
1740         case INDEX_op_set_label:
1741             tcg_reg_alloc_bb_end(s);
1742             tcg_out_label(s, args[0], (long)s->code_ptr);
1743             break;
1744         case INDEX_op_call:
1745             dead_iargs = s->op_dead_iargs[op_index];
1746             args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
1747             goto next;
1748         case INDEX_op_end:
1749             goto the_end;
1750         case 0 ... INDEX_op_end - 1:
1751             /* legacy dyngen ops */
1752 #ifdef CONFIG_PROFILER
1753             {
1754                 extern int64_t dyngen_old_op_count;
1755                 dyngen_old_op_count++;
1756             }
1757 #endif
1758             tcg_reg_alloc_bb_end(s);
1759             if (search_pc >= 0) {
1760                 s->code_ptr += def->copy_size;
1761                 args += def->nb_args;
1762             } else {
1763                 args = dyngen_op(s, opc, args);
1764             }
1765             goto next;
1766         default:
1767             /* Note: in order to speed up the code, it would be much
1768                faster to have specialized register allocator functions for
1769                some common argument patterns */
1770             dead_iargs = s->op_dead_iargs[op_index];
1771             tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
1772             break;
1773         }
1774         args += def->nb_args;
1775     next: ;
1776         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
1777             if (macro_op_index >= 0)
1778                 return macro_op_index;
1779             else
1780                 return op_index;
1781         }
1782         op_index++;
1783 #ifndef NDEBUG
1784         check_regs(s);
1785 #endif
1786     }
1787  the_end:
1788     return -1;
1789 }
1790
1791 int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
1792 {
1793 #ifdef CONFIG_PROFILER
1794     {
1795         extern int64_t dyngen_op_count;
1796         extern int dyngen_op_count_max;
1797         int n;
1798         n = (gen_opc_ptr - gen_opc_buf);
1799         dyngen_op_count += n;
1800         if (n > dyngen_op_count_max)
1801             dyngen_op_count_max = n;
1802     }
1803 #endif
1804
1805     tcg_gen_code_common(s, gen_code_buf, -1);
1806
1807     /* flush instruction cache */
1808     flush_icache_range((unsigned long)gen_code_buf, 
1809                        (unsigned long)s->code_ptr);
1810     return s->code_ptr -  gen_code_buf;
1811 }
1812
1813 static uint8_t *dummy_code_buf;
1814
1815 /* Return the index of the micro operation such as the pc after is <
1816    offset bytes from the start of the TB.
1817    We have to use a dummy code buffer here to avoid clobbering the
1818    oringinal code.  Because we terminate code generation part way through
1819    we can end up with unresolved relocations.  Return -1 if not found. */
1820 int dyngen_code_search_pc(TCGContext *s, long offset)
1821 {
1822     if (!dummy_code_buf)
1823         dummy_code_buf = qemu_malloc(code_gen_max_block_size());
1824     return tcg_gen_code_common(s, dummy_code_buf, offset);
1825 }