1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu-common.h"
25
26
27#if UINTPTR_MAX == UINT32_MAX
28# define TCG_TARGET_REG_BITS 32
29#elif UINTPTR_MAX == UINT64_MAX
30# define TCG_TARGET_REG_BITS 64
31#else
32# error Unknown pointer size for tcg target
33#endif
34
35#if TCG_TARGET_REG_BITS == 32
36typedef int32_t tcg_target_long;
37typedef uint32_t tcg_target_ulong;
38#define TCG_PRIlx PRIx32
39#define TCG_PRIld PRId32
40#elif TCG_TARGET_REG_BITS == 64
41typedef int64_t tcg_target_long;
42typedef uint64_t tcg_target_ulong;
43#define TCG_PRIlx PRIx64
44#define TCG_PRIld PRId64
45#else
46#error unsupported
47#endif
48
49#include "tcg-target.h"
50#include "tcg-runtime.h"
51
52#if TCG_TARGET_NB_REGS <= 32
53typedef uint32_t TCGRegSet;
54#elif TCG_TARGET_NB_REGS <= 64
55typedef uint64_t TCGRegSet;
56#else
57#error unsupported
58#endif
59
60
61#if TCG_TARGET_REG_BITS == 32
62#define TCG_TARGET_HAS_div_i64 0
63#define TCG_TARGET_HAS_div2_i64 0
64#define TCG_TARGET_HAS_rot_i64 0
65#define TCG_TARGET_HAS_ext8s_i64 0
66#define TCG_TARGET_HAS_ext16s_i64 0
67#define TCG_TARGET_HAS_ext32s_i64 0
68#define TCG_TARGET_HAS_ext8u_i64 0
69#define TCG_TARGET_HAS_ext16u_i64 0
70#define TCG_TARGET_HAS_ext32u_i64 0
71#define TCG_TARGET_HAS_bswap16_i64 0
72#define TCG_TARGET_HAS_bswap32_i64 0
73#define TCG_TARGET_HAS_bswap64_i64 0
74#define TCG_TARGET_HAS_neg_i64 0
75#define TCG_TARGET_HAS_not_i64 0
76#define TCG_TARGET_HAS_andc_i64 0
77#define TCG_TARGET_HAS_orc_i64 0
78#define TCG_TARGET_HAS_eqv_i64 0
79#define TCG_TARGET_HAS_nand_i64 0
80#define TCG_TARGET_HAS_nor_i64 0
81#define TCG_TARGET_HAS_deposit_i64 0
82#define TCG_TARGET_HAS_movcond_i64 0
83#endif
84
85#ifndef TCG_TARGET_deposit_i32_valid
86#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
87#endif
88#ifndef TCG_TARGET_deposit_i64_valid
89#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
90#endif
91
92
93#if defined(TCG_TARGET_HAS_div_i32)
94#define TCG_TARGET_HAS_div2_i32 0
95#elif defined(TCG_TARGET_HAS_div2_i32)
96#define TCG_TARGET_HAS_div_i32 0
97#endif
98#if defined(TCG_TARGET_HAS_div_i64)
99#define TCG_TARGET_HAS_div2_i64 0
100#elif defined(TCG_TARGET_HAS_div2_i64)
101#define TCG_TARGET_HAS_div_i64 0
102#endif
103
104typedef enum TCGOpcode {
105#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
106#include "tcg-opc.h"
107#undef DEF
108 NB_OPS,
109} TCGOpcode;
110
111#define tcg_regset_clear(d) (d) = 0
112#define tcg_regset_set(d, s) (d) = (s)
113#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
114#define tcg_regset_set_reg(d, r) (d) |= 1L << (r)
115#define tcg_regset_reset_reg(d, r) (d) &= ~(1L << (r))
116#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
117#define tcg_regset_or(d, a, b) (d) = (a) | (b)
118#define tcg_regset_and(d, a, b) (d) = (a) & (b)
119#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
120#define tcg_regset_not(d, a) (d) = ~(a)
121
122typedef struct TCGRelocation {
123 struct TCGRelocation *next;
124 int type;
125 uint8_t *ptr;
126 tcg_target_long addend;
127} TCGRelocation;
128
129typedef struct TCGLabel {
130 int has_value;
131 union {
132 tcg_target_ulong value;
133 TCGRelocation *first_reloc;
134 } u;
135} TCGLabel;
136
137typedef struct TCGPool {
138 struct TCGPool *next;
139 int size;
140 uint8_t data[0] __attribute__ ((aligned));
141} TCGPool;
142
143#define TCG_POOL_CHUNK_SIZE 32768
144
145#define TCG_MAX_LABELS 512
146
147#define TCG_MAX_TEMPS 512
148
149
150
151#define TCG_STATIC_CALL_ARGS_SIZE 128
152
153typedef enum TCGType {
154 TCG_TYPE_I32,
155 TCG_TYPE_I64,
156 TCG_TYPE_COUNT,
157
158
159#if TCG_TARGET_REG_BITS == 32
160 TCG_TYPE_REG = TCG_TYPE_I32,
161#else
162 TCG_TYPE_REG = TCG_TYPE_I64,
163#endif
164
165
166
167 TCG_TYPE_PTR = TCG_TYPE_REG,
168
169
170#if TARGET_LONG_BITS == 64
171 TCG_TYPE_TL = TCG_TYPE_I64,
172#else
173 TCG_TYPE_TL = TCG_TYPE_I32,
174#endif
175} TCGType;
176
177typedef tcg_target_ulong TCGArg;
178
179
180
181
182
183
184
185
186
187
188
189
190
191#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
192
193
194#define TCG_MAX_QEMU_LDST 640
195
196typedef struct TCGLabelQemuLdst {
197 int is_ld:1;
198 int opc:4;
199 int addrlo_reg;
200 int addrhi_reg;
201 int datalo_reg;
202 int datahi_reg;
203 int mem_index;
204 uint8_t *raddr;
205 uint8_t *label_ptr[2];
206} TCGLabelQemuLdst;
207#endif
208
209#ifdef CONFIG_DEBUG_TCG
210#define DEBUG_TCGV 1
211#endif
212
213#ifdef DEBUG_TCGV
214
215typedef struct
216{
217 int i32;
218} TCGv_i32;
219
220typedef struct
221{
222 int i64;
223} TCGv_i64;
224
225typedef struct {
226 int iptr;
227} TCGv_ptr;
228
229#define MAKE_TCGV_I32(i) __extension__ \
230 ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
231#define MAKE_TCGV_I64(i) __extension__ \
232 ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
233#define MAKE_TCGV_PTR(i) __extension__ \
234 ({ TCGv_ptr make_tcgv_tmp = {i}; make_tcgv_tmp; })
235#define GET_TCGV_I32(t) ((t).i32)
236#define GET_TCGV_I64(t) ((t).i64)
237#define GET_TCGV_PTR(t) ((t).iptr)
238#if TCG_TARGET_REG_BITS == 32
239#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
240#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
241#endif
242
243#else
244
245typedef int TCGv_i32;
246typedef int TCGv_i64;
247#if TCG_TARGET_REG_BITS == 32
248#define TCGv_ptr TCGv_i32
249#else
250#define TCGv_ptr TCGv_i64
251#endif
252#define MAKE_TCGV_I32(x) (x)
253#define MAKE_TCGV_I64(x) (x)
254#define MAKE_TCGV_PTR(x) (x)
255#define GET_TCGV_I32(t) (t)
256#define GET_TCGV_I64(t) (t)
257#define GET_TCGV_PTR(t) (t)
258
259#if TCG_TARGET_REG_BITS == 32
260#define TCGV_LOW(t) (t)
261#define TCGV_HIGH(t) ((t) + 1)
262#endif
263
264#endif
265
266#define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
267#define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
268
269
270#define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
271#define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
272
273#define TCGV_IS_UNUSED_I32(x) (GET_TCGV_I32(x) == -1)
274#define TCGV_IS_UNUSED_I64(x) (GET_TCGV_I64(x) == -1)
275
276
277
278
279#define TCG_CALL_NO_READ_GLOBALS 0x0010
280
281#define TCG_CALL_NO_WRITE_GLOBALS 0x0020
282
283#define TCG_CALL_NO_SIDE_EFFECTS 0x0040
284
285
286#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
287#define TCG_CALL_NO_WG TCG_CALL_NO_WRITE_GLOBALS
288#define TCG_CALL_NO_SE TCG_CALL_NO_SIDE_EFFECTS
289#define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE)
290#define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE)
291
292
293#define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
294#define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
295
296
297
298
299
300
301
302typedef enum {
303
304 TCG_COND_NEVER = 0 | 0 | 0 | 0,
305 TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
306 TCG_COND_EQ = 8 | 0 | 0 | 0,
307 TCG_COND_NE = 8 | 0 | 0 | 1,
308
309 TCG_COND_LT = 0 | 0 | 2 | 0,
310 TCG_COND_GE = 0 | 0 | 2 | 1,
311 TCG_COND_LE = 8 | 0 | 2 | 0,
312 TCG_COND_GT = 8 | 0 | 2 | 1,
313
314 TCG_COND_LTU = 0 | 4 | 0 | 0,
315 TCG_COND_GEU = 0 | 4 | 0 | 1,
316 TCG_COND_LEU = 8 | 4 | 0 | 0,
317 TCG_COND_GTU = 8 | 4 | 0 | 1,
318} TCGCond;
319
320
321static inline TCGCond tcg_invert_cond(TCGCond c)
322{
323 return (TCGCond)(c ^ 1);
324}
325
326
327static inline TCGCond tcg_swap_cond(TCGCond c)
328{
329 return c & 6 ? (TCGCond)(c ^ 9) : c;
330}
331
332
333static inline TCGCond tcg_unsigned_cond(TCGCond c)
334{
335 return c & 2 ? (TCGCond)(c ^ 6) : c;
336}
337
338
339static inline bool is_unsigned_cond(TCGCond c)
340{
341 return (c & 4) != 0;
342}
343
344
345
346static inline TCGCond tcg_high_cond(TCGCond c)
347{
348 switch (c) {
349 case TCG_COND_GE:
350 case TCG_COND_LE:
351 case TCG_COND_GEU:
352 case TCG_COND_LEU:
353 return (TCGCond)(c ^ 8);
354 default:
355 return c;
356 }
357}
358
359#define TEMP_VAL_DEAD 0
360#define TEMP_VAL_REG 1
361#define TEMP_VAL_MEM 2
362#define TEMP_VAL_CONST 3
363
364
365typedef struct TCGTemp {
366 TCGType base_type;
367 TCGType type;
368 int val_type;
369 int reg;
370 tcg_target_long val;
371 int mem_reg;
372 tcg_target_long mem_offset;
373 unsigned int fixed_reg:1;
374 unsigned int mem_coherent:1;
375 unsigned int mem_allocated:1;
376 unsigned int temp_local:1;
377
378
379 unsigned int temp_allocated:1;
380
381 int next_free_temp;
382 const char *name;
383} TCGTemp;
384
385typedef struct TCGHelperInfo {
386 tcg_target_ulong func;
387 const char *name;
388} TCGHelperInfo;
389
390typedef struct TCGContext TCGContext;
391
392struct TCGContext {
393 uint8_t *pool_cur, *pool_end;
394 TCGPool *pool_first, *pool_current, *pool_first_large;
395 TCGLabel *labels;
396 int nb_labels;
397 int nb_globals;
398 int nb_temps;
399
400 int first_free_temp[TCG_TYPE_COUNT * 2];
401
402
403 uint8_t *code_buf;
404 uintptr_t *tb_next;
405 uint16_t *tb_next_offset;
406 uint16_t *tb_jmp_offset;
407
408
409 uint16_t *op_dead_args;
410
411 uint8_t *op_sync_args;
412
413
414
415
416
417 int reg_to_temp[TCG_TARGET_NB_REGS];
418 TCGRegSet reserved_regs;
419 tcg_target_long current_frame_offset;
420 tcg_target_long frame_start;
421 tcg_target_long frame_end;
422 int frame_reg;
423
424 uint8_t *code_ptr;
425 TCGTemp temps[TCG_MAX_TEMPS];
426
427 TCGHelperInfo *helpers;
428 int nb_helpers;
429 int allocated_helpers;
430 int helpers_sorted;
431
432#ifdef CONFIG_PROFILER
433
434 int64_t tb_count1;
435 int64_t tb_count;
436 int64_t op_count;
437 int op_count_max;
438 int64_t temp_count;
439 int temp_count_max;
440 int64_t del_op_count;
441 int64_t code_in_len;
442 int64_t code_out_len;
443 int64_t interm_time;
444 int64_t code_time;
445 int64_t la_time;
446 int64_t opt_time;
447 int64_t restore_count;
448 int64_t restore_time;
449#endif
450
451#ifdef CONFIG_DEBUG_TCG
452 int temps_in_use;
453 int goto_tb_issue_mask;
454#endif
455
456 uint16_t gen_opc_buf[OPC_BUF_SIZE];
457 TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
458
459 uint16_t *gen_opc_ptr;
460 TCGArg *gen_opparam_ptr;
461 target_ulong gen_opc_pc[OPC_BUF_SIZE];
462 uint16_t gen_opc_icount[OPC_BUF_SIZE];
463 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
464
465#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
466
467
468 TCGLabelQemuLdst *qemu_ldst_labels;
469 int nb_qemu_ldst_labels;
470#endif
471};
472
473extern TCGContext tcg_ctx;
474
475
476
477void *tcg_malloc_internal(TCGContext *s, int size);
478void tcg_pool_reset(TCGContext *s);
479void tcg_pool_delete(TCGContext *s);
480
481static inline void *tcg_malloc(int size)
482{
483 TCGContext *s = &tcg_ctx;
484 uint8_t *ptr, *ptr_end;
485 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
486 ptr = s->pool_cur;
487 ptr_end = ptr + size;
488 if (unlikely(ptr_end > s->pool_end)) {
489 return tcg_malloc_internal(&tcg_ctx, size);
490 } else {
491 s->pool_cur = ptr_end;
492 return ptr;
493 }
494}
495
496void tcg_context_init(TCGContext *s);
497void tcg_prologue_init(TCGContext *s);
498void tcg_func_start(TCGContext *s);
499
500int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
501int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
502
503void tcg_set_frame(TCGContext *s, int reg,
504 tcg_target_long start, tcg_target_long size);
505
506TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
507TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
508 const char *name);
509TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
510static inline TCGv_i32 tcg_temp_new_i32(void)
511{
512 return tcg_temp_new_internal_i32(0);
513}
514static inline TCGv_i32 tcg_temp_local_new_i32(void)
515{
516 return tcg_temp_new_internal_i32(1);
517}
518void tcg_temp_free_i32(TCGv_i32 arg);
519char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
520
521TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
522TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
523 const char *name);
524TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
525static inline TCGv_i64 tcg_temp_new_i64(void)
526{
527 return tcg_temp_new_internal_i64(0);
528}
529static inline TCGv_i64 tcg_temp_local_new_i64(void)
530{
531 return tcg_temp_new_internal_i64(1);
532}
533void tcg_temp_free_i64(TCGv_i64 arg);
534char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
535
536#if defined(CONFIG_DEBUG_TCG)
537
538
539
540
541
542void tcg_clear_temp_count(void);
543int tcg_check_temp_count(void);
544#else
545#define tcg_clear_temp_count() do { } while (0)
546#define tcg_check_temp_count() 0
547#endif
548
549void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
550
551#define TCG_CT_ALIAS 0x80
552#define TCG_CT_IALIAS 0x40
553#define TCG_CT_REG 0x01
554#define TCG_CT_CONST 0x02
555
556typedef struct TCGArgConstraint {
557 uint16_t ct;
558 uint8_t alias_index;
559 union {
560 TCGRegSet regs;
561 } u;
562} TCGArgConstraint;
563
564#define TCG_MAX_OP_ARGS 16
565
566
567enum {
568
569 TCG_OPF_BB_END = 0x01,
570
571 TCG_OPF_CALL_CLOBBER = 0x02,
572
573
574 TCG_OPF_SIDE_EFFECTS = 0x04,
575
576 TCG_OPF_64BIT = 0x08,
577
578 TCG_OPF_NOT_PRESENT = 0x10,
579};
580
581typedef struct TCGOpDef {
582 const char *name;
583 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
584 uint8_t flags;
585 TCGArgConstraint *args_ct;
586 int *sorted_args;
587#if defined(CONFIG_DEBUG_TCG)
588 int used;
589#endif
590} TCGOpDef;
591
592extern TCGOpDef tcg_op_defs[];
593extern const size_t tcg_op_defs_max;
594
595typedef struct TCGTargetOpDef {
596 TCGOpcode op;
597 const char *args_ct_str[TCG_MAX_OP_ARGS];
598} TCGTargetOpDef;
599
600#define tcg_abort() \
601do {\
602 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
603 abort();\
604} while (0)
605
606#ifdef CONFIG_DEBUG_TCG
607# define tcg_debug_assert(X) do { assert(X); } while (0)
608#elif QEMU_GNUC_PREREQ(4, 5)
609# define tcg_debug_assert(X) \
610 do { if (!(X)) { __builtin_unreachable(); } } while (0)
611#else
612# define tcg_debug_assert(X) do { (void)(X); } while (0)
613#endif
614
615void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
616
617#if TCG_TARGET_REG_BITS == 32
618#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
619#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
620
621#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((tcg_target_long)(V)))
622#define tcg_global_reg_new_ptr(R, N) \
623 TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
624#define tcg_global_mem_new_ptr(R, O, N) \
625 TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
626#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
627#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
628#else
629#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
630#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
631
632#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((tcg_target_long)(V)))
633#define tcg_global_reg_new_ptr(R, N) \
634 TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
635#define tcg_global_mem_new_ptr(R, O, N) \
636 TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
637#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
638#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
639#endif
640
641void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
642 int sizemask, TCGArg ret, int nargs, TCGArg *args);
643
644void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
645 int c, int right, int arith);
646
647TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args,
648 TCGOpDef *tcg_op_def);
649
650
651void tcg_register_helper(void *func, const char *name);
652const char *tcg_helper_get_name(TCGContext *s, void *func);
653void tcg_dump_ops(TCGContext *s);
654
655void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
656TCGv_i32 tcg_const_i32(int32_t val);
657TCGv_i64 tcg_const_i64(int64_t val);
658TCGv_i32 tcg_const_local_i32(int32_t val);
659TCGv_i64 tcg_const_local_i64(int64_t val);
660
661extern uint8_t *code_gen_prologue;
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705#define TB_EXIT_MASK 3
706#define TB_EXIT_IDX0 0
707#define TB_EXIT_IDX1 1
708#define TB_EXIT_ICOUNT_EXPIRED 2
709#define TB_EXIT_REQUESTED 3
710
711#if !defined(tcg_qemu_tb_exec)
712# define tcg_qemu_tb_exec(env, tb_ptr) \
713 ((tcg_target_ulong (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
714#endif
715
716void tcg_register_jit(void *buf, size_t buf_size);
717
718#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
719
720void tcg_out_tb_finalize(TCGContext *s);
721#endif
722