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