1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#ifndef TCG_H
26#define TCG_H
27
28#include "qemu-common.h"
29#include "qemu/bitops.h"
30#include "tcg-target.h"
31
32#define CPU_TEMP_BUF_NLONGS 128
33
34
35#ifndef TCG_TARGET_REG_BITS
36# if UINTPTR_MAX == UINT32_MAX
37# define TCG_TARGET_REG_BITS 32
38# elif UINTPTR_MAX == UINT64_MAX
39# define TCG_TARGET_REG_BITS 64
40# else
41# error Unknown pointer size for tcg target
42# endif
43#endif
44
45#if TCG_TARGET_REG_BITS == 32
46typedef int32_t tcg_target_long;
47typedef uint32_t tcg_target_ulong;
48#define TCG_PRIlx PRIx32
49#define TCG_PRIld PRId32
50#elif TCG_TARGET_REG_BITS == 64
51typedef int64_t tcg_target_long;
52typedef uint64_t tcg_target_ulong;
53#define TCG_PRIlx PRIx64
54#define TCG_PRIld PRId64
55#else
56#error unsupported
57#endif
58
59#if TCG_TARGET_NB_REGS <= 32
60typedef uint32_t TCGRegSet;
61#elif TCG_TARGET_NB_REGS <= 64
62typedef uint64_t TCGRegSet;
63#else
64#error unsupported
65#endif
66
67#if TCG_TARGET_REG_BITS == 32
68
69#define TCG_TARGET_HAS_extrl_i64_i32 0
70#define TCG_TARGET_HAS_extrh_i64_i32 0
71#define TCG_TARGET_HAS_div_i64 0
72#define TCG_TARGET_HAS_rem_i64 0
73#define TCG_TARGET_HAS_div2_i64 0
74#define TCG_TARGET_HAS_rot_i64 0
75#define TCG_TARGET_HAS_ext8s_i64 0
76#define TCG_TARGET_HAS_ext16s_i64 0
77#define TCG_TARGET_HAS_ext32s_i64 0
78#define TCG_TARGET_HAS_ext8u_i64 0
79#define TCG_TARGET_HAS_ext16u_i64 0
80#define TCG_TARGET_HAS_ext32u_i64 0
81#define TCG_TARGET_HAS_bswap16_i64 0
82#define TCG_TARGET_HAS_bswap32_i64 0
83#define TCG_TARGET_HAS_bswap64_i64 0
84#define TCG_TARGET_HAS_neg_i64 0
85#define TCG_TARGET_HAS_not_i64 0
86#define TCG_TARGET_HAS_andc_i64 0
87#define TCG_TARGET_HAS_orc_i64 0
88#define TCG_TARGET_HAS_eqv_i64 0
89#define TCG_TARGET_HAS_nand_i64 0
90#define TCG_TARGET_HAS_nor_i64 0
91#define TCG_TARGET_HAS_deposit_i64 0
92#define TCG_TARGET_HAS_movcond_i64 0
93#define TCG_TARGET_HAS_add2_i64 0
94#define TCG_TARGET_HAS_sub2_i64 0
95#define TCG_TARGET_HAS_mulu2_i64 0
96#define TCG_TARGET_HAS_muls2_i64 0
97#define TCG_TARGET_HAS_muluh_i64 0
98#define TCG_TARGET_HAS_mulsh_i64 0
99
100#define TCG_TARGET_HAS_add2_i32 1
101#define TCG_TARGET_HAS_sub2_i32 1
102#endif
103
104#ifndef TCG_TARGET_deposit_i32_valid
105#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
106#endif
107#ifndef TCG_TARGET_deposit_i64_valid
108#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
109#endif
110
111
112#if defined(TCG_TARGET_HAS_div_i32)
113#define TCG_TARGET_HAS_div2_i32 0
114#elif defined(TCG_TARGET_HAS_div2_i32)
115#define TCG_TARGET_HAS_div_i32 0
116#define TCG_TARGET_HAS_rem_i32 0
117#endif
118#if defined(TCG_TARGET_HAS_div_i64)
119#define TCG_TARGET_HAS_div2_i64 0
120#elif defined(TCG_TARGET_HAS_div2_i64)
121#define TCG_TARGET_HAS_div_i64 0
122#define TCG_TARGET_HAS_rem_i64 0
123#endif
124
125
126#if TCG_TARGET_REG_BITS == 32 \
127 && !(defined(TCG_TARGET_HAS_mulu2_i32) \
128 || defined(TCG_TARGET_HAS_muluh_i32))
129# error "Missing unsigned widening multiply"
130#endif
131
132#ifndef TARGET_INSN_START_EXTRA_WORDS
133# define TARGET_INSN_START_WORDS 1
134#else
135# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
136#endif
137
138typedef enum TCGOpcode {
139#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
140#include "tcg-opc.h"
141#undef DEF
142 NB_OPS,
143} TCGOpcode;
144
145#define tcg_regset_clear(d) (d) = 0
146#define tcg_regset_set(d, s) (d) = (s)
147#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
148#define tcg_regset_set_reg(d, r) (d) |= 1L << (r)
149#define tcg_regset_reset_reg(d, r) (d) &= ~(1L << (r))
150#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
151#define tcg_regset_or(d, a, b) (d) = (a) | (b)
152#define tcg_regset_and(d, a, b) (d) = (a) & (b)
153#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
154#define tcg_regset_not(d, a) (d) = ~(a)
155
156#ifndef TCG_TARGET_INSN_UNIT_SIZE
157# error "Missing TCG_TARGET_INSN_UNIT_SIZE"
158#elif TCG_TARGET_INSN_UNIT_SIZE == 1
159typedef uint8_t tcg_insn_unit;
160#elif TCG_TARGET_INSN_UNIT_SIZE == 2
161typedef uint16_t tcg_insn_unit;
162#elif TCG_TARGET_INSN_UNIT_SIZE == 4
163typedef uint32_t tcg_insn_unit;
164#elif TCG_TARGET_INSN_UNIT_SIZE == 8
165typedef uint64_t tcg_insn_unit;
166#else
167
168#endif
169
170
171typedef struct TCGRelocation {
172 struct TCGRelocation *next;
173 int type;
174 tcg_insn_unit *ptr;
175 intptr_t addend;
176} TCGRelocation;
177
178typedef struct TCGLabel {
179 unsigned has_value : 1;
180 unsigned id : 31;
181 union {
182 uintptr_t value;
183 tcg_insn_unit *value_ptr;
184 TCGRelocation *first_reloc;
185 } u;
186} TCGLabel;
187
188typedef struct TCGPool {
189 struct TCGPool *next;
190 int size;
191 uint8_t data[0] __attribute__ ((aligned));
192} TCGPool;
193
194#define TCG_POOL_CHUNK_SIZE 32768
195
196#define TCG_MAX_TEMPS 512
197#define TCG_MAX_INSNS 512
198
199
200
201#define TCG_STATIC_CALL_ARGS_SIZE 128
202
203typedef enum TCGType {
204 TCG_TYPE_I32,
205 TCG_TYPE_I64,
206 TCG_TYPE_COUNT,
207
208
209#if TCG_TARGET_REG_BITS == 32
210 TCG_TYPE_REG = TCG_TYPE_I32,
211#else
212 TCG_TYPE_REG = TCG_TYPE_I64,
213#endif
214
215
216#if UINTPTR_MAX == UINT32_MAX
217 TCG_TYPE_PTR = TCG_TYPE_I32,
218#else
219 TCG_TYPE_PTR = TCG_TYPE_I64,
220#endif
221
222
223#if TARGET_LONG_BITS == 64
224 TCG_TYPE_TL = TCG_TYPE_I64,
225#else
226 TCG_TYPE_TL = TCG_TYPE_I32,
227#endif
228} TCGType;
229
230
231typedef enum TCGMemOp {
232 MO_8 = 0,
233 MO_16 = 1,
234 MO_32 = 2,
235 MO_64 = 3,
236 MO_SIZE = 3,
237
238 MO_SIGN = 4,
239
240 MO_BSWAP = 8,
241#ifdef HOST_WORDS_BIGENDIAN
242 MO_LE = MO_BSWAP,
243 MO_BE = 0,
244#else
245 MO_LE = 0,
246 MO_BE = MO_BSWAP,
247#endif
248#ifdef TARGET_WORDS_BIGENDIAN
249 MO_TE = MO_BE,
250#else
251 MO_TE = MO_LE,
252#endif
253
254
255
256
257
258 MO_AMASK = 16,
259#ifdef ALIGNED_ONLY
260 MO_ALIGN = 0,
261 MO_UNALN = MO_AMASK,
262#else
263 MO_ALIGN = MO_AMASK,
264 MO_UNALN = 0,
265#endif
266
267
268 MO_UB = MO_8,
269 MO_UW = MO_16,
270 MO_UL = MO_32,
271 MO_SB = MO_SIGN | MO_8,
272 MO_SW = MO_SIGN | MO_16,
273 MO_SL = MO_SIGN | MO_32,
274 MO_Q = MO_64,
275
276 MO_LEUW = MO_LE | MO_UW,
277 MO_LEUL = MO_LE | MO_UL,
278 MO_LESW = MO_LE | MO_SW,
279 MO_LESL = MO_LE | MO_SL,
280 MO_LEQ = MO_LE | MO_Q,
281
282 MO_BEUW = MO_BE | MO_UW,
283 MO_BEUL = MO_BE | MO_UL,
284 MO_BESW = MO_BE | MO_SW,
285 MO_BESL = MO_BE | MO_SL,
286 MO_BEQ = MO_BE | MO_Q,
287
288 MO_TEUW = MO_TE | MO_UW,
289 MO_TEUL = MO_TE | MO_UL,
290 MO_TESW = MO_TE | MO_SW,
291 MO_TESL = MO_TE | MO_SL,
292 MO_TEQ = MO_TE | MO_Q,
293
294 MO_SSIZE = MO_SIZE | MO_SIGN,
295} TCGMemOp;
296
297typedef tcg_target_ulong TCGArg;
298
299
300
301
302
303
304
305
306
307
308typedef struct TCGv_i32_d *TCGv_i32;
309typedef struct TCGv_i64_d *TCGv_i64;
310typedef struct TCGv_ptr_d *TCGv_ptr;
311typedef TCGv_ptr TCGv_env;
312#if TARGET_LONG_BITS == 32
313#define TCGv TCGv_i32
314#elif TARGET_LONG_BITS == 64
315#define TCGv TCGv_i64
316#else
317#error Unhandled TARGET_LONG_BITS value
318#endif
319
320static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(intptr_t i)
321{
322 return (TCGv_i32)i;
323}
324
325static inline TCGv_i64 QEMU_ARTIFICIAL MAKE_TCGV_I64(intptr_t i)
326{
327 return (TCGv_i64)i;
328}
329
330static inline TCGv_ptr QEMU_ARTIFICIAL MAKE_TCGV_PTR(intptr_t i)
331{
332 return (TCGv_ptr)i;
333}
334
335static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_I32(TCGv_i32 t)
336{
337 return (intptr_t)t;
338}
339
340static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_I64(TCGv_i64 t)
341{
342 return (intptr_t)t;
343}
344
345static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t)
346{
347 return (intptr_t)t;
348}
349
350#if TCG_TARGET_REG_BITS == 32
351#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
352#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
353#endif
354
355#define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
356#define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
357#define TCGV_EQUAL_PTR(a, b) (GET_TCGV_PTR(a) == GET_TCGV_PTR(b))
358
359
360#define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
361#define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
362#define TCGV_UNUSED_PTR(x) x = MAKE_TCGV_PTR(-1)
363
364#define TCGV_IS_UNUSED_I32(x) (GET_TCGV_I32(x) == -1)
365#define TCGV_IS_UNUSED_I64(x) (GET_TCGV_I64(x) == -1)
366#define TCGV_IS_UNUSED_PTR(x) (GET_TCGV_PTR(x) == -1)
367
368
369
370
371#define TCG_CALL_NO_READ_GLOBALS 0x0010
372
373#define TCG_CALL_NO_WRITE_GLOBALS 0x0020
374
375#define TCG_CALL_NO_SIDE_EFFECTS 0x0040
376
377
378#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
379#define TCG_CALL_NO_WG TCG_CALL_NO_WRITE_GLOBALS
380#define TCG_CALL_NO_SE TCG_CALL_NO_SIDE_EFFECTS
381#define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE)
382#define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE)
383
384
385#define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
386#define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
387
388
389
390
391
392
393
394typedef enum {
395
396 TCG_COND_NEVER = 0 | 0 | 0 | 0,
397 TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
398 TCG_COND_EQ = 8 | 0 | 0 | 0,
399 TCG_COND_NE = 8 | 0 | 0 | 1,
400
401 TCG_COND_LT = 0 | 0 | 2 | 0,
402 TCG_COND_GE = 0 | 0 | 2 | 1,
403 TCG_COND_LE = 8 | 0 | 2 | 0,
404 TCG_COND_GT = 8 | 0 | 2 | 1,
405
406 TCG_COND_LTU = 0 | 4 | 0 | 0,
407 TCG_COND_GEU = 0 | 4 | 0 | 1,
408 TCG_COND_LEU = 8 | 4 | 0 | 0,
409 TCG_COND_GTU = 8 | 4 | 0 | 1,
410} TCGCond;
411
412
413static inline TCGCond tcg_invert_cond(TCGCond c)
414{
415 return (TCGCond)(c ^ 1);
416}
417
418
419static inline TCGCond tcg_swap_cond(TCGCond c)
420{
421 return c & 6 ? (TCGCond)(c ^ 9) : c;
422}
423
424
425static inline TCGCond tcg_unsigned_cond(TCGCond c)
426{
427 return c & 2 ? (TCGCond)(c ^ 6) : c;
428}
429
430
431static inline bool is_unsigned_cond(TCGCond c)
432{
433 return (c & 4) != 0;
434}
435
436
437
438static inline TCGCond tcg_high_cond(TCGCond c)
439{
440 switch (c) {
441 case TCG_COND_GE:
442 case TCG_COND_LE:
443 case TCG_COND_GEU:
444 case TCG_COND_LEU:
445 return (TCGCond)(c ^ 8);
446 default:
447 return c;
448 }
449}
450
451typedef enum TCGTempVal {
452 TEMP_VAL_DEAD,
453 TEMP_VAL_REG,
454 TEMP_VAL_MEM,
455 TEMP_VAL_CONST,
456} TCGTempVal;
457
458typedef struct TCGTemp {
459 TCGReg reg:8;
460 TCGTempVal val_type:8;
461 TCGType base_type:8;
462 TCGType type:8;
463 unsigned int fixed_reg:1;
464 unsigned int indirect_reg:1;
465 unsigned int indirect_base:1;
466 unsigned int mem_coherent:1;
467 unsigned int mem_allocated:1;
468 unsigned int temp_local:1;
469
470
471 unsigned int temp_allocated:1;
472
473 tcg_target_long val;
474 struct TCGTemp *mem_base;
475 intptr_t mem_offset;
476 const char *name;
477} TCGTemp;
478
479typedef struct TCGContext TCGContext;
480
481typedef struct TCGTempSet {
482 unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
483} TCGTempSet;
484
485typedef struct TCGOp {
486 TCGOpcode opc : 8;
487
488
489 unsigned callo : 2;
490 unsigned calli : 6;
491
492
493 signed args : 16;
494
495
496 signed prev : 16;
497 signed next : 16;
498} TCGOp;
499
500QEMU_BUILD_BUG_ON(NB_OPS > 0xff);
501QEMU_BUILD_BUG_ON(OPC_BUF_SIZE >= 0x7fff);
502QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE >= 0x7fff);
503
504struct TCGContext {
505 uint8_t *pool_cur, *pool_end;
506 TCGPool *pool_first, *pool_current, *pool_first_large;
507 int nb_labels;
508 int nb_globals;
509 int nb_temps;
510
511
512 tcg_insn_unit *code_buf;
513 uintptr_t *tb_next;
514 uint16_t *tb_next_offset;
515 uint16_t *tb_jmp_offset;
516
517
518 uint16_t *op_dead_args;
519
520 uint8_t *op_sync_args;
521
522
523
524 TCGRegSet reserved_regs;
525 intptr_t current_frame_offset;
526 intptr_t frame_start;
527 intptr_t frame_end;
528 TCGTemp *frame_temp;
529
530 tcg_insn_unit *code_ptr;
531
532 GHashTable *helpers;
533
534#ifdef CONFIG_PROFILER
535
536 int64_t tb_count1;
537 int64_t tb_count;
538 int64_t op_count;
539 int op_count_max;
540 int64_t temp_count;
541 int temp_count_max;
542 int64_t del_op_count;
543 int64_t code_in_len;
544 int64_t code_out_len;
545 int64_t search_out_len;
546 int64_t interm_time;
547 int64_t code_time;
548 int64_t la_time;
549 int64_t opt_time;
550 int64_t restore_count;
551 int64_t restore_time;
552#endif
553
554#ifdef CONFIG_DEBUG_TCG
555 int temps_in_use;
556 int goto_tb_issue_mask;
557#endif
558
559 int gen_first_op_idx;
560 int gen_last_op_idx;
561 int gen_next_op_idx;
562 int gen_next_parm_idx;
563
564
565
566
567
568 int code_gen_max_blocks;
569 void *code_gen_prologue;
570 void *code_gen_buffer;
571 size_t code_gen_buffer_size;
572 void *code_gen_ptr;
573
574
575 void *code_gen_highwater;
576
577 TBContext tb_ctx;
578
579
580 struct TCGBackendData *be;
581
582 TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
583 TCGTemp temps[TCG_MAX_TEMPS];
584
585
586
587 TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
588
589 TCGOp gen_op_buf[OPC_BUF_SIZE];
590 TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
591
592 uint16_t gen_insn_end_off[TCG_MAX_INSNS];
593 target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
594};
595
596extern TCGContext tcg_ctx;
597
598
599static inline int tcg_op_buf_count(void)
600{
601 return tcg_ctx.gen_next_op_idx;
602}
603
604
605static inline bool tcg_op_buf_full(void)
606{
607 return tcg_op_buf_count() >= OPC_MAX_SIZE;
608}
609
610
611
612void *tcg_malloc_internal(TCGContext *s, int size);
613void tcg_pool_reset(TCGContext *s);
614void tcg_pool_delete(TCGContext *s);
615
616void tb_lock(void);
617void tb_unlock(void);
618void tb_lock_reset(void);
619
620static inline void *tcg_malloc(int size)
621{
622 TCGContext *s = &tcg_ctx;
623 uint8_t *ptr, *ptr_end;
624 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
625 ptr = s->pool_cur;
626 ptr_end = ptr + size;
627 if (unlikely(ptr_end > s->pool_end)) {
628 return tcg_malloc_internal(&tcg_ctx, size);
629 } else {
630 s->pool_cur = ptr_end;
631 return ptr;
632 }
633}
634
635void tcg_context_init(TCGContext *s);
636void tcg_prologue_init(TCGContext *s);
637void tcg_func_start(TCGContext *s);
638
639int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
640
641void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
642
643int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
644
645TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name);
646TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name);
647
648TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
649TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
650
651void tcg_temp_free_i32(TCGv_i32 arg);
652void tcg_temp_free_i64(TCGv_i64 arg);
653
654static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
655 const char *name)
656{
657 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
658 return MAKE_TCGV_I32(idx);
659}
660
661static inline TCGv_i32 tcg_temp_new_i32(void)
662{
663 return tcg_temp_new_internal_i32(0);
664}
665
666static inline TCGv_i32 tcg_temp_local_new_i32(void)
667{
668 return tcg_temp_new_internal_i32(1);
669}
670
671static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
672 const char *name)
673{
674 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
675 return MAKE_TCGV_I64(idx);
676}
677
678static inline TCGv_i64 tcg_temp_new_i64(void)
679{
680 return tcg_temp_new_internal_i64(0);
681}
682
683static inline TCGv_i64 tcg_temp_local_new_i64(void)
684{
685 return tcg_temp_new_internal_i64(1);
686}
687
688#if defined(CONFIG_DEBUG_TCG)
689
690
691
692
693
694void tcg_clear_temp_count(void);
695int tcg_check_temp_count(void);
696#else
697#define tcg_clear_temp_count() do { } while (0)
698#define tcg_check_temp_count() 0
699#endif
700
701void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
702void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
703
704#define TCG_CT_ALIAS 0x80
705#define TCG_CT_IALIAS 0x40
706#define TCG_CT_REG 0x01
707#define TCG_CT_CONST 0x02
708
709typedef struct TCGArgConstraint {
710 uint16_t ct;
711 uint8_t alias_index;
712 union {
713 TCGRegSet regs;
714 } u;
715} TCGArgConstraint;
716
717#define TCG_MAX_OP_ARGS 16
718
719
720enum {
721
722 TCG_OPF_BB_END = 0x01,
723
724 TCG_OPF_CALL_CLOBBER = 0x02,
725
726
727 TCG_OPF_SIDE_EFFECTS = 0x04,
728
729 TCG_OPF_64BIT = 0x08,
730
731
732 TCG_OPF_NOT_PRESENT = 0x10,
733};
734
735typedef struct TCGOpDef {
736 const char *name;
737 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
738 uint8_t flags;
739 TCGArgConstraint *args_ct;
740 int *sorted_args;
741#if defined(CONFIG_DEBUG_TCG)
742 int used;
743#endif
744} TCGOpDef;
745
746extern TCGOpDef tcg_op_defs[];
747extern const size_t tcg_op_defs_max;
748
749typedef struct TCGTargetOpDef {
750 TCGOpcode op;
751 const char *args_ct_str[TCG_MAX_OP_ARGS];
752} TCGTargetOpDef;
753
754#define tcg_abort() \
755do {\
756 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
757 abort();\
758} while (0)
759
760#ifdef CONFIG_DEBUG_TCG
761# define tcg_debug_assert(X) do { assert(X); } while (0)
762#elif QEMU_GNUC_PREREQ(4, 5)
763# define tcg_debug_assert(X) \
764 do { if (!(X)) { __builtin_unreachable(); } } while (0)
765#else
766# define tcg_debug_assert(X) do { (void)(X); } while (0)
767#endif
768
769void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
770
771#if UINTPTR_MAX == UINT32_MAX
772#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
773#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
774
775#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V)))
776#define tcg_global_reg_new_ptr(R, N) \
777 TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
778#define tcg_global_mem_new_ptr(R, O, N) \
779 TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
780#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
781#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
782#else
783#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
784#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
785
786#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V)))
787#define tcg_global_reg_new_ptr(R, N) \
788 TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
789#define tcg_global_mem_new_ptr(R, O, N) \
790 TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
791#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
792#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
793#endif
794
795void tcg_gen_callN(TCGContext *s, void *func,
796 TCGArg ret, int nargs, TCGArg *args);
797
798void tcg_op_remove(TCGContext *s, TCGOp *op);
799void tcg_optimize(TCGContext *s);
800
801
802void tcg_dump_ops(TCGContext *s);
803
804void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
805TCGv_i32 tcg_const_i32(int32_t val);
806TCGv_i64 tcg_const_i64(int64_t val);
807TCGv_i32 tcg_const_local_i32(int32_t val);
808TCGv_i64 tcg_const_local_i64(int64_t val);
809
810TCGLabel *gen_new_label(void);
811
812
813
814
815
816
817
818
819static inline TCGArg label_arg(TCGLabel *l)
820{
821 return (uintptr_t)l;
822}
823
824
825
826
827
828
829
830
831
832static inline TCGLabel *arg_label(TCGArg i)
833{
834 return (TCGLabel *)(uintptr_t)i;
835}
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
851{
852 return a - b;
853}
854
855
856
857
858
859
860
861
862
863
864static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
865{
866 return tcg_ptr_byte_diff(target, s->code_ptr);
867}
868
869
870
871
872
873
874
875
876
877static inline size_t tcg_current_code_size(TCGContext *s)
878{
879 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
880}
881
882
883typedef uint32_t TCGMemOpIdx;
884
885
886
887
888
889
890
891
892static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx)
893{
894 tcg_debug_assert(idx <= 15);
895 return (op << 4) | idx;
896}
897
898
899
900
901
902
903
904static inline TCGMemOp get_memop(TCGMemOpIdx oi)
905{
906 return oi >> 4;
907}
908
909
910
911
912
913
914
915static inline unsigned get_mmuidx(TCGMemOpIdx oi)
916{
917 return oi & 15;
918}
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964#define TB_EXIT_MASK 3
965#define TB_EXIT_IDX0 0
966#define TB_EXIT_IDX1 1
967#define TB_EXIT_ICOUNT_EXPIRED 2
968#define TB_EXIT_REQUESTED 3
969
970#ifdef HAVE_TCG_QEMU_TB_EXEC
971uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
972#else
973# define tcg_qemu_tb_exec(env, tb_ptr) \
974 ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
975#endif
976
977void tcg_register_jit(void *buf, size_t buf_size);
978
979
980
981
982#ifdef CONFIG_SOFTMMU
983
984tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
985 TCGMemOpIdx oi, uintptr_t retaddr);
986tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
987 TCGMemOpIdx oi, uintptr_t retaddr);
988tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
989 TCGMemOpIdx oi, uintptr_t retaddr);
990uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
991 TCGMemOpIdx oi, uintptr_t retaddr);
992tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
993 TCGMemOpIdx oi, uintptr_t retaddr);
994tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
995 TCGMemOpIdx oi, uintptr_t retaddr);
996uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
997 TCGMemOpIdx oi, uintptr_t retaddr);
998
999
1000tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
1001 TCGMemOpIdx oi, uintptr_t retaddr);
1002tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
1003 TCGMemOpIdx oi, uintptr_t retaddr);
1004tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
1005 TCGMemOpIdx oi, uintptr_t retaddr);
1006tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
1007 TCGMemOpIdx oi, uintptr_t retaddr);
1008tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
1009 TCGMemOpIdx oi, uintptr_t retaddr);
1010
1011void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
1012 TCGMemOpIdx oi, uintptr_t retaddr);
1013void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
1014 TCGMemOpIdx oi, uintptr_t retaddr);
1015void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
1016 TCGMemOpIdx oi, uintptr_t retaddr);
1017void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
1018 TCGMemOpIdx oi, uintptr_t retaddr);
1019void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
1020 TCGMemOpIdx oi, uintptr_t retaddr);
1021void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
1022 TCGMemOpIdx oi, uintptr_t retaddr);
1023void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
1024 TCGMemOpIdx oi, uintptr_t retaddr);
1025
1026uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1027 TCGMemOpIdx oi, uintptr_t retaddr);
1028uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1029 TCGMemOpIdx oi, uintptr_t retaddr);
1030uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1031 TCGMemOpIdx oi, uintptr_t retaddr);
1032uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1033 TCGMemOpIdx oi, uintptr_t retaddr);
1034uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1035 TCGMemOpIdx oi, uintptr_t retaddr);
1036uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1037 TCGMemOpIdx oi, uintptr_t retaddr);
1038uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1039 TCGMemOpIdx oi, uintptr_t retaddr);
1040
1041
1042#ifdef TARGET_WORDS_BIGENDIAN
1043# define helper_ret_ldsw_mmu helper_be_ldsw_mmu
1044# define helper_ret_lduw_mmu helper_be_lduw_mmu
1045# define helper_ret_ldsl_mmu helper_be_ldsl_mmu
1046# define helper_ret_ldul_mmu helper_be_ldul_mmu
1047# define helper_ret_ldl_mmu helper_be_ldul_mmu
1048# define helper_ret_ldq_mmu helper_be_ldq_mmu
1049# define helper_ret_stw_mmu helper_be_stw_mmu
1050# define helper_ret_stl_mmu helper_be_stl_mmu
1051# define helper_ret_stq_mmu helper_be_stq_mmu
1052# define helper_ret_ldw_cmmu helper_be_ldw_cmmu
1053# define helper_ret_ldl_cmmu helper_be_ldl_cmmu
1054# define helper_ret_ldq_cmmu helper_be_ldq_cmmu
1055#else
1056# define helper_ret_ldsw_mmu helper_le_ldsw_mmu
1057# define helper_ret_lduw_mmu helper_le_lduw_mmu
1058# define helper_ret_ldsl_mmu helper_le_ldsl_mmu
1059# define helper_ret_ldul_mmu helper_le_ldul_mmu
1060# define helper_ret_ldl_mmu helper_le_ldul_mmu
1061# define helper_ret_ldq_mmu helper_le_ldq_mmu
1062# define helper_ret_stw_mmu helper_le_stw_mmu
1063# define helper_ret_stl_mmu helper_le_stl_mmu
1064# define helper_ret_stq_mmu helper_le_stq_mmu
1065# define helper_ret_ldw_cmmu helper_le_ldw_cmmu
1066# define helper_ret_ldl_cmmu helper_le_ldl_cmmu
1067# define helper_ret_ldq_cmmu helper_le_ldq_cmmu
1068#endif
1069
1070#endif
1071
1072#endif
1073