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
598static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
599{
600 int op_argi = tcg_ctx.gen_op_buf[op_idx].args;
601 tcg_ctx.gen_opparam_buf[op_argi + arg] = v;
602}
603
604
605static inline int tcg_op_buf_count(void)
606{
607 return tcg_ctx.gen_next_op_idx;
608}
609
610
611static inline bool tcg_op_buf_full(void)
612{
613 return tcg_op_buf_count() >= OPC_MAX_SIZE;
614}
615
616
617
618void *tcg_malloc_internal(TCGContext *s, int size);
619void tcg_pool_reset(TCGContext *s);
620void tcg_pool_delete(TCGContext *s);
621
622void tb_lock(void);
623void tb_unlock(void);
624void tb_lock_reset(void);
625
626static inline void *tcg_malloc(int size)
627{
628 TCGContext *s = &tcg_ctx;
629 uint8_t *ptr, *ptr_end;
630 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
631 ptr = s->pool_cur;
632 ptr_end = ptr + size;
633 if (unlikely(ptr_end > s->pool_end)) {
634 return tcg_malloc_internal(&tcg_ctx, size);
635 } else {
636 s->pool_cur = ptr_end;
637 return ptr;
638 }
639}
640
641void tcg_context_init(TCGContext *s);
642void tcg_prologue_init(TCGContext *s);
643void tcg_func_start(TCGContext *s);
644
645int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
646
647void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
648
649int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
650
651TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name);
652TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name);
653
654TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
655TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
656
657void tcg_temp_free_i32(TCGv_i32 arg);
658void tcg_temp_free_i64(TCGv_i64 arg);
659
660static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
661 const char *name)
662{
663 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
664 return MAKE_TCGV_I32(idx);
665}
666
667static inline TCGv_i32 tcg_temp_new_i32(void)
668{
669 return tcg_temp_new_internal_i32(0);
670}
671
672static inline TCGv_i32 tcg_temp_local_new_i32(void)
673{
674 return tcg_temp_new_internal_i32(1);
675}
676
677static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
678 const char *name)
679{
680 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
681 return MAKE_TCGV_I64(idx);
682}
683
684static inline TCGv_i64 tcg_temp_new_i64(void)
685{
686 return tcg_temp_new_internal_i64(0);
687}
688
689static inline TCGv_i64 tcg_temp_local_new_i64(void)
690{
691 return tcg_temp_new_internal_i64(1);
692}
693
694#if defined(CONFIG_DEBUG_TCG)
695
696
697
698
699
700void tcg_clear_temp_count(void);
701int tcg_check_temp_count(void);
702#else
703#define tcg_clear_temp_count() do { } while (0)
704#define tcg_check_temp_count() 0
705#endif
706
707void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
708void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
709
710#define TCG_CT_ALIAS 0x80
711#define TCG_CT_IALIAS 0x40
712#define TCG_CT_REG 0x01
713#define TCG_CT_CONST 0x02
714
715typedef struct TCGArgConstraint {
716 uint16_t ct;
717 uint8_t alias_index;
718 union {
719 TCGRegSet regs;
720 } u;
721} TCGArgConstraint;
722
723#define TCG_MAX_OP_ARGS 16
724
725
726enum {
727
728 TCG_OPF_BB_END = 0x01,
729
730 TCG_OPF_CALL_CLOBBER = 0x02,
731
732
733 TCG_OPF_SIDE_EFFECTS = 0x04,
734
735 TCG_OPF_64BIT = 0x08,
736
737
738 TCG_OPF_NOT_PRESENT = 0x10,
739};
740
741typedef struct TCGOpDef {
742 const char *name;
743 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
744 uint8_t flags;
745 TCGArgConstraint *args_ct;
746 int *sorted_args;
747#if defined(CONFIG_DEBUG_TCG)
748 int used;
749#endif
750} TCGOpDef;
751
752extern TCGOpDef tcg_op_defs[];
753extern const size_t tcg_op_defs_max;
754
755typedef struct TCGTargetOpDef {
756 TCGOpcode op;
757 const char *args_ct_str[TCG_MAX_OP_ARGS];
758} TCGTargetOpDef;
759
760#define tcg_abort() \
761do {\
762 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
763 abort();\
764} while (0)
765
766#ifdef CONFIG_DEBUG_TCG
767# define tcg_debug_assert(X) do { assert(X); } while (0)
768#elif QEMU_GNUC_PREREQ(4, 5)
769# define tcg_debug_assert(X) \
770 do { if (!(X)) { __builtin_unreachable(); } } while (0)
771#else
772# define tcg_debug_assert(X) do { (void)(X); } while (0)
773#endif
774
775void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
776
777#if UINTPTR_MAX == UINT32_MAX
778#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
779#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
780
781#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V)))
782#define tcg_global_reg_new_ptr(R, N) \
783 TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
784#define tcg_global_mem_new_ptr(R, O, N) \
785 TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
786#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
787#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
788#else
789#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
790#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
791
792#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V)))
793#define tcg_global_reg_new_ptr(R, N) \
794 TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
795#define tcg_global_mem_new_ptr(R, O, N) \
796 TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
797#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
798#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
799#endif
800
801void tcg_gen_callN(TCGContext *s, void *func,
802 TCGArg ret, int nargs, TCGArg *args);
803
804void tcg_op_remove(TCGContext *s, TCGOp *op);
805void tcg_optimize(TCGContext *s);
806
807
808void tcg_dump_ops(TCGContext *s);
809
810void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
811TCGv_i32 tcg_const_i32(int32_t val);
812TCGv_i64 tcg_const_i64(int64_t val);
813TCGv_i32 tcg_const_local_i32(int32_t val);
814TCGv_i64 tcg_const_local_i64(int64_t val);
815
816TCGLabel *gen_new_label(void);
817
818
819
820
821
822
823
824
825static inline TCGArg label_arg(TCGLabel *l)
826{
827 return (uintptr_t)l;
828}
829
830
831
832
833
834
835
836
837
838static inline TCGLabel *arg_label(TCGArg i)
839{
840 return (TCGLabel *)(uintptr_t)i;
841}
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
857{
858 return a - b;
859}
860
861
862
863
864
865
866
867
868
869
870static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
871{
872 return tcg_ptr_byte_diff(target, s->code_ptr);
873}
874
875
876
877
878
879
880
881
882
883static inline size_t tcg_current_code_size(TCGContext *s)
884{
885 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
886}
887
888
889typedef uint32_t TCGMemOpIdx;
890
891
892
893
894
895
896
897
898static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx)
899{
900 tcg_debug_assert(idx <= 15);
901 return (op << 4) | idx;
902}
903
904
905
906
907
908
909
910static inline TCGMemOp get_memop(TCGMemOpIdx oi)
911{
912 return oi >> 4;
913}
914
915
916
917
918
919
920
921static inline unsigned get_mmuidx(TCGMemOpIdx oi)
922{
923 return oi & 15;
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
965
966
967
968
969
970#define TB_EXIT_MASK 3
971#define TB_EXIT_IDX0 0
972#define TB_EXIT_IDX1 1
973#define TB_EXIT_ICOUNT_EXPIRED 2
974#define TB_EXIT_REQUESTED 3
975
976#ifdef HAVE_TCG_QEMU_TB_EXEC
977uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
978#else
979# define tcg_qemu_tb_exec(env, tb_ptr) \
980 ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
981#endif
982
983void tcg_register_jit(void *buf, size_t buf_size);
984
985
986
987
988#ifdef CONFIG_SOFTMMU
989
990tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
991 TCGMemOpIdx oi, uintptr_t retaddr);
992tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
993 TCGMemOpIdx oi, uintptr_t retaddr);
994tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
995 TCGMemOpIdx oi, uintptr_t retaddr);
996uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
997 TCGMemOpIdx oi, uintptr_t retaddr);
998tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
999 TCGMemOpIdx oi, uintptr_t retaddr);
1000tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
1001 TCGMemOpIdx oi, uintptr_t retaddr);
1002uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
1003 TCGMemOpIdx oi, uintptr_t retaddr);
1004
1005
1006tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
1007 TCGMemOpIdx oi, uintptr_t retaddr);
1008tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
1009 TCGMemOpIdx oi, uintptr_t retaddr);
1010tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
1011 TCGMemOpIdx oi, uintptr_t retaddr);
1012tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
1013 TCGMemOpIdx oi, uintptr_t retaddr);
1014tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
1015 TCGMemOpIdx oi, uintptr_t retaddr);
1016
1017void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
1018 TCGMemOpIdx oi, uintptr_t retaddr);
1019void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
1020 TCGMemOpIdx oi, uintptr_t retaddr);
1021void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
1022 TCGMemOpIdx oi, uintptr_t retaddr);
1023void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
1024 TCGMemOpIdx oi, uintptr_t retaddr);
1025void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
1026 TCGMemOpIdx oi, uintptr_t retaddr);
1027void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
1028 TCGMemOpIdx oi, uintptr_t retaddr);
1029void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
1030 TCGMemOpIdx oi, uintptr_t retaddr);
1031
1032uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1033 TCGMemOpIdx oi, uintptr_t retaddr);
1034uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1035 TCGMemOpIdx oi, uintptr_t retaddr);
1036uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1037 TCGMemOpIdx oi, uintptr_t retaddr);
1038uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1039 TCGMemOpIdx oi, uintptr_t retaddr);
1040uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1041 TCGMemOpIdx oi, uintptr_t retaddr);
1042uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1043 TCGMemOpIdx oi, uintptr_t retaddr);
1044uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1045 TCGMemOpIdx oi, uintptr_t retaddr);
1046
1047
1048#ifdef TARGET_WORDS_BIGENDIAN
1049# define helper_ret_ldsw_mmu helper_be_ldsw_mmu
1050# define helper_ret_lduw_mmu helper_be_lduw_mmu
1051# define helper_ret_ldsl_mmu helper_be_ldsl_mmu
1052# define helper_ret_ldul_mmu helper_be_ldul_mmu
1053# define helper_ret_ldl_mmu helper_be_ldul_mmu
1054# define helper_ret_ldq_mmu helper_be_ldq_mmu
1055# define helper_ret_stw_mmu helper_be_stw_mmu
1056# define helper_ret_stl_mmu helper_be_stl_mmu
1057# define helper_ret_stq_mmu helper_be_stq_mmu
1058# define helper_ret_ldw_cmmu helper_be_ldw_cmmu
1059# define helper_ret_ldl_cmmu helper_be_ldl_cmmu
1060# define helper_ret_ldq_cmmu helper_be_ldq_cmmu
1061#else
1062# define helper_ret_ldsw_mmu helper_le_ldsw_mmu
1063# define helper_ret_lduw_mmu helper_le_lduw_mmu
1064# define helper_ret_ldsl_mmu helper_le_ldsl_mmu
1065# define helper_ret_ldul_mmu helper_le_ldul_mmu
1066# define helper_ret_ldl_mmu helper_le_ldul_mmu
1067# define helper_ret_ldq_mmu helper_le_ldq_mmu
1068# define helper_ret_stw_mmu helper_le_stw_mmu
1069# define helper_ret_stl_mmu helper_le_stl_mmu
1070# define helper_ret_stq_mmu helper_le_stq_mmu
1071# define helper_ret_ldw_cmmu helper_le_ldw_cmmu
1072# define helper_ret_ldl_cmmu helper_le_ldl_cmmu
1073# define helper_ret_ldq_cmmu helper_le_ldq_cmmu
1074#endif
1075
1076#endif
1077
1078#endif
1079