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 "cpu.h"
29#include "exec/memop.h"
30#include "exec/memopidx.h"
31#include "qemu/bitops.h"
32#include "qemu/plugin.h"
33#include "qemu/queue.h"
34#include "tcg/tcg-mo.h"
35#include "tcg-target.h"
36#include "tcg/tcg-cond.h"
37
38
39#define MAX_OP_PER_INSTR 266
40
41#define MAX_CALL_IARGS 7
42
43#define CPU_TEMP_BUF_NLONGS 128
44#define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long))
45
46
47#ifndef TCG_TARGET_REG_BITS
48# if UINTPTR_MAX == UINT32_MAX
49# define TCG_TARGET_REG_BITS 32
50# elif UINTPTR_MAX == UINT64_MAX
51# define TCG_TARGET_REG_BITS 64
52# else
53# error Unknown pointer size for tcg target
54# endif
55#endif
56
57#if TCG_TARGET_REG_BITS == 32
58typedef int32_t tcg_target_long;
59typedef uint32_t tcg_target_ulong;
60#define TCG_PRIlx PRIx32
61#define TCG_PRIld PRId32
62#elif TCG_TARGET_REG_BITS == 64
63typedef int64_t tcg_target_long;
64typedef uint64_t tcg_target_ulong;
65#define TCG_PRIlx PRIx64
66#define TCG_PRIld PRId64
67#else
68#error unsupported
69#endif
70
71
72
73
74#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
75#define TCG_OVERSIZED_GUEST 1
76#else
77#define TCG_OVERSIZED_GUEST 0
78#endif
79
80#if TCG_TARGET_NB_REGS <= 32
81typedef uint32_t TCGRegSet;
82#elif TCG_TARGET_NB_REGS <= 64
83typedef uint64_t TCGRegSet;
84#else
85#error unsupported
86#endif
87
88#if TCG_TARGET_REG_BITS == 32
89
90#define TCG_TARGET_HAS_extrl_i64_i32 0
91#define TCG_TARGET_HAS_extrh_i64_i32 0
92#define TCG_TARGET_HAS_div_i64 0
93#define TCG_TARGET_HAS_rem_i64 0
94#define TCG_TARGET_HAS_div2_i64 0
95#define TCG_TARGET_HAS_rot_i64 0
96#define TCG_TARGET_HAS_ext8s_i64 0
97#define TCG_TARGET_HAS_ext16s_i64 0
98#define TCG_TARGET_HAS_ext32s_i64 0
99#define TCG_TARGET_HAS_ext8u_i64 0
100#define TCG_TARGET_HAS_ext16u_i64 0
101#define TCG_TARGET_HAS_ext32u_i64 0
102#define TCG_TARGET_HAS_bswap16_i64 0
103#define TCG_TARGET_HAS_bswap32_i64 0
104#define TCG_TARGET_HAS_bswap64_i64 0
105#define TCG_TARGET_HAS_neg_i64 0
106#define TCG_TARGET_HAS_not_i64 0
107#define TCG_TARGET_HAS_andc_i64 0
108#define TCG_TARGET_HAS_orc_i64 0
109#define TCG_TARGET_HAS_eqv_i64 0
110#define TCG_TARGET_HAS_nand_i64 0
111#define TCG_TARGET_HAS_nor_i64 0
112#define TCG_TARGET_HAS_clz_i64 0
113#define TCG_TARGET_HAS_ctz_i64 0
114#define TCG_TARGET_HAS_ctpop_i64 0
115#define TCG_TARGET_HAS_deposit_i64 0
116#define TCG_TARGET_HAS_extract_i64 0
117#define TCG_TARGET_HAS_sextract_i64 0
118#define TCG_TARGET_HAS_extract2_i64 0
119#define TCG_TARGET_HAS_movcond_i64 0
120#define TCG_TARGET_HAS_add2_i64 0
121#define TCG_TARGET_HAS_sub2_i64 0
122#define TCG_TARGET_HAS_mulu2_i64 0
123#define TCG_TARGET_HAS_muls2_i64 0
124#define TCG_TARGET_HAS_muluh_i64 0
125#define TCG_TARGET_HAS_mulsh_i64 0
126
127#define TCG_TARGET_HAS_add2_i32 1
128#define TCG_TARGET_HAS_sub2_i32 1
129#endif
130
131#ifndef TCG_TARGET_deposit_i32_valid
132#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
133#endif
134#ifndef TCG_TARGET_deposit_i64_valid
135#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
136#endif
137#ifndef TCG_TARGET_extract_i32_valid
138#define TCG_TARGET_extract_i32_valid(ofs, len) 1
139#endif
140#ifndef TCG_TARGET_extract_i64_valid
141#define TCG_TARGET_extract_i64_valid(ofs, len) 1
142#endif
143
144
145#if defined(TCG_TARGET_HAS_div_i32)
146#define TCG_TARGET_HAS_div2_i32 0
147#elif defined(TCG_TARGET_HAS_div2_i32)
148#define TCG_TARGET_HAS_div_i32 0
149#define TCG_TARGET_HAS_rem_i32 0
150#endif
151#if defined(TCG_TARGET_HAS_div_i64)
152#define TCG_TARGET_HAS_div2_i64 0
153#elif defined(TCG_TARGET_HAS_div2_i64)
154#define TCG_TARGET_HAS_div_i64 0
155#define TCG_TARGET_HAS_rem_i64 0
156#endif
157
158#if !defined(TCG_TARGET_HAS_v64) \
159 && !defined(TCG_TARGET_HAS_v128) \
160 && !defined(TCG_TARGET_HAS_v256)
161#define TCG_TARGET_MAYBE_vec 0
162#define TCG_TARGET_HAS_abs_vec 0
163#define TCG_TARGET_HAS_neg_vec 0
164#define TCG_TARGET_HAS_not_vec 0
165#define TCG_TARGET_HAS_andc_vec 0
166#define TCG_TARGET_HAS_orc_vec 0
167#define TCG_TARGET_HAS_nand_vec 0
168#define TCG_TARGET_HAS_nor_vec 0
169#define TCG_TARGET_HAS_eqv_vec 0
170#define TCG_TARGET_HAS_roti_vec 0
171#define TCG_TARGET_HAS_rots_vec 0
172#define TCG_TARGET_HAS_rotv_vec 0
173#define TCG_TARGET_HAS_shi_vec 0
174#define TCG_TARGET_HAS_shs_vec 0
175#define TCG_TARGET_HAS_shv_vec 0
176#define TCG_TARGET_HAS_mul_vec 0
177#define TCG_TARGET_HAS_sat_vec 0
178#define TCG_TARGET_HAS_minmax_vec 0
179#define TCG_TARGET_HAS_bitsel_vec 0
180#define TCG_TARGET_HAS_cmpsel_vec 0
181#else
182#define TCG_TARGET_MAYBE_vec 1
183#endif
184#ifndef TCG_TARGET_HAS_v64
185#define TCG_TARGET_HAS_v64 0
186#endif
187#ifndef TCG_TARGET_HAS_v128
188#define TCG_TARGET_HAS_v128 0
189#endif
190#ifndef TCG_TARGET_HAS_v256
191#define TCG_TARGET_HAS_v256 0
192#endif
193
194#ifndef TARGET_INSN_START_EXTRA_WORDS
195# define TARGET_INSN_START_WORDS 1
196#else
197# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
198#endif
199
200typedef enum TCGOpcode {
201#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
202#include "tcg/tcg-opc.h"
203#undef DEF
204 NB_OPS,
205} TCGOpcode;
206
207#define tcg_regset_set_reg(d, r) ((d) |= (TCGRegSet)1 << (r))
208#define tcg_regset_reset_reg(d, r) ((d) &= ~((TCGRegSet)1 << (r)))
209#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
210
211#ifndef TCG_TARGET_INSN_UNIT_SIZE
212# error "Missing TCG_TARGET_INSN_UNIT_SIZE"
213#elif TCG_TARGET_INSN_UNIT_SIZE == 1
214typedef uint8_t tcg_insn_unit;
215#elif TCG_TARGET_INSN_UNIT_SIZE == 2
216typedef uint16_t tcg_insn_unit;
217#elif TCG_TARGET_INSN_UNIT_SIZE == 4
218typedef uint32_t tcg_insn_unit;
219#elif TCG_TARGET_INSN_UNIT_SIZE == 8
220typedef uint64_t tcg_insn_unit;
221#else
222
223#endif
224
225
226#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
227# define tcg_debug_assert(X) do { assert(X); } while (0)
228#else
229# define tcg_debug_assert(X) \
230 do { if (!(X)) { __builtin_unreachable(); } } while (0)
231#endif
232
233typedef struct TCGRelocation TCGRelocation;
234struct TCGRelocation {
235 QSIMPLEQ_ENTRY(TCGRelocation) next;
236 tcg_insn_unit *ptr;
237 intptr_t addend;
238 int type;
239};
240
241typedef struct TCGOp TCGOp;
242typedef struct TCGLabelUse TCGLabelUse;
243struct TCGLabelUse {
244 QSIMPLEQ_ENTRY(TCGLabelUse) next;
245 TCGOp *op;
246};
247
248typedef struct TCGLabel TCGLabel;
249struct TCGLabel {
250 bool present;
251 bool has_value;
252 uint16_t id;
253 union {
254 uintptr_t value;
255 const tcg_insn_unit *value_ptr;
256 } u;
257 QSIMPLEQ_HEAD(, TCGLabelUse) branches;
258 QSIMPLEQ_HEAD(, TCGRelocation) relocs;
259 QSIMPLEQ_ENTRY(TCGLabel) next;
260};
261
262typedef struct TCGPool {
263 struct TCGPool *next;
264 int size;
265 uint8_t data[] __attribute__ ((aligned));
266} TCGPool;
267
268#define TCG_POOL_CHUNK_SIZE 32768
269
270#define TCG_MAX_TEMPS 512
271#define TCG_MAX_INSNS 512
272
273
274
275#define TCG_STATIC_CALL_ARGS_SIZE 128
276
277typedef enum TCGType {
278 TCG_TYPE_I32,
279 TCG_TYPE_I64,
280 TCG_TYPE_I128,
281
282 TCG_TYPE_V64,
283 TCG_TYPE_V128,
284 TCG_TYPE_V256,
285
286
287#define TCG_TYPE_COUNT (TCG_TYPE_V256 + 1)
288
289
290#if TCG_TARGET_REG_BITS == 32
291 TCG_TYPE_REG = TCG_TYPE_I32,
292#else
293 TCG_TYPE_REG = TCG_TYPE_I64,
294#endif
295
296
297#if UINTPTR_MAX == UINT32_MAX
298 TCG_TYPE_PTR = TCG_TYPE_I32,
299#else
300 TCG_TYPE_PTR = TCG_TYPE_I64,
301#endif
302
303
304#if TARGET_LONG_BITS == 64
305 TCG_TYPE_TL = TCG_TYPE_I64,
306#else
307 TCG_TYPE_TL = TCG_TYPE_I32,
308#endif
309} TCGType;
310
311
312
313
314
315
316
317static inline int tcg_type_size(TCGType t)
318{
319 unsigned i = t;
320 if (i >= TCG_TYPE_V64) {
321 tcg_debug_assert(i < TCG_TYPE_COUNT);
322 i -= TCG_TYPE_V64 - 1;
323 }
324 return 4 << i;
325}
326
327
328
329
330
331
332
333static inline unsigned get_alignment_bits(MemOp memop)
334{
335 unsigned a = memop & MO_AMASK;
336
337 if (a == MO_UNALN) {
338
339 a = 0;
340 } else if (a == MO_ALIGN) {
341
342 a = memop & MO_SIZE;
343 } else {
344
345 a = a >> MO_ASHIFT;
346 }
347#if defined(CONFIG_SOFTMMU)
348
349 tcg_debug_assert((TLB_FLAGS_MASK & ((1 << a) - 1)) == 0);
350#endif
351 return a;
352}
353
354typedef tcg_target_ulong TCGArg;
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387typedef struct TCGv_i32_d *TCGv_i32;
388typedef struct TCGv_i64_d *TCGv_i64;
389typedef struct TCGv_i128_d *TCGv_i128;
390typedef struct TCGv_ptr_d *TCGv_ptr;
391typedef struct TCGv_vec_d *TCGv_vec;
392typedef TCGv_ptr TCGv_env;
393#if TARGET_LONG_BITS == 32
394#define TCGv TCGv_i32
395#elif TARGET_LONG_BITS == 64
396#define TCGv TCGv_i64
397#else
398#error Unhandled TARGET_LONG_BITS value
399#endif
400
401
402
403
404#define TCG_CALL_NO_READ_GLOBALS 0x0001
405
406#define TCG_CALL_NO_WRITE_GLOBALS 0x0002
407
408#define TCG_CALL_NO_SIDE_EFFECTS 0x0004
409
410#define TCG_CALL_NO_RETURN 0x0008
411
412#define TCG_CALL_PLUGIN 0x0010
413
414
415#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
416#define TCG_CALL_NO_WG TCG_CALL_NO_WRITE_GLOBALS
417#define TCG_CALL_NO_SE TCG_CALL_NO_SIDE_EFFECTS
418#define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE)
419#define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE)
420
421
422
423
424
425
426
427enum {
428 TCG_BSWAP_IZ = 1,
429 TCG_BSWAP_OZ = 2,
430 TCG_BSWAP_OS = 4,
431};
432
433typedef enum TCGTempVal {
434 TEMP_VAL_DEAD,
435 TEMP_VAL_REG,
436 TEMP_VAL_MEM,
437 TEMP_VAL_CONST,
438} TCGTempVal;
439
440typedef enum TCGTempKind {
441
442
443
444
445
446 TEMP_EBB,
447
448 TEMP_TB,
449
450 TEMP_GLOBAL,
451
452 TEMP_FIXED,
453
454 TEMP_CONST,
455} TCGTempKind;
456
457typedef struct TCGTemp {
458 TCGReg reg:8;
459 TCGTempVal val_type:8;
460 TCGType base_type:8;
461 TCGType type:8;
462 TCGTempKind kind:3;
463 unsigned int indirect_reg:1;
464 unsigned int indirect_base:1;
465 unsigned int mem_coherent:1;
466 unsigned int mem_allocated:1;
467 unsigned int temp_allocated:1;
468 unsigned int temp_subindex:1;
469
470 int64_t val;
471 struct TCGTemp *mem_base;
472 intptr_t mem_offset;
473 const char *name;
474
475
476
477
478 uintptr_t state;
479 void *state_ptr;
480} TCGTemp;
481
482typedef struct TCGContext TCGContext;
483
484typedef struct TCGTempSet {
485 unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
486} TCGTempSet;
487
488
489
490
491
492
493#define DEAD_ARG (1 << 4)
494#define SYNC_ARG (1 << 0)
495typedef uint32_t TCGLifeData;
496
497struct TCGOp {
498 TCGOpcode opc : 8;
499 unsigned nargs : 8;
500
501
502 unsigned param1 : 8;
503 unsigned param2 : 8;
504
505
506 TCGLifeData life;
507
508
509 QTAILQ_ENTRY(TCGOp) link;
510
511
512 TCGRegSet output_pref[2];
513
514
515 TCGArg args[];
516};
517
518#define TCGOP_CALLI(X) (X)->param1
519#define TCGOP_CALLO(X) (X)->param2
520
521#define TCGOP_VECL(X) (X)->param1
522#define TCGOP_VECE(X) (X)->param2
523
524
525QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
526
527static inline TCGRegSet output_pref(const TCGOp *op, unsigned i)
528{
529 return i < ARRAY_SIZE(op->output_pref) ? op->output_pref[i] : 0;
530}
531
532typedef struct TCGProfile {
533 int64_t cpu_exec_time;
534 int64_t tb_count1;
535 int64_t tb_count;
536 int64_t op_count;
537 int op_count_max;
538 int temp_count_max;
539 int64_t temp_count;
540 int64_t del_op_count;
541 int64_t code_in_len;
542 int64_t code_out_len;
543 int64_t search_out_len;
544 int64_t interm_time;
545 int64_t code_time;
546 int64_t la_time;
547 int64_t opt_time;
548 int64_t restore_count;
549 int64_t restore_time;
550 int64_t table_op_count[NB_OPS];
551} TCGProfile;
552
553struct TCGContext {
554 uint8_t *pool_cur, *pool_end;
555 TCGPool *pool_first, *pool_current, *pool_first_large;
556 int nb_labels;
557 int nb_globals;
558 int nb_temps;
559 int nb_indirects;
560 int nb_ops;
561
562 TCGRegSet reserved_regs;
563 intptr_t current_frame_offset;
564 intptr_t frame_start;
565 intptr_t frame_end;
566 TCGTemp *frame_temp;
567
568 TranslationBlock *gen_tb;
569 tcg_insn_unit *code_buf;
570 tcg_insn_unit *code_ptr;
571
572#ifdef CONFIG_PROFILER
573 TCGProfile prof;
574#endif
575
576#ifdef CONFIG_DEBUG_TCG
577 int goto_tb_issue_mask;
578 const TCGOpcode *vecop_list;
579#endif
580
581
582
583
584
585 void *code_gen_buffer;
586 size_t code_gen_buffer_size;
587 void *code_gen_ptr;
588 void *data_gen_ptr;
589
590
591 void *code_gen_highwater;
592
593
594 CPUState *cpu;
595
596
597#ifdef TCG_TARGET_NEED_LDST_LABELS
598 QSIMPLEQ_HEAD(, TCGLabelQemuLdst) ldst_labels;
599#endif
600#ifdef TCG_TARGET_NEED_POOL_LABELS
601 struct TCGLabelPoolData *pool_labels;
602#endif
603
604 TCGLabel *exitreq_label;
605
606#ifdef CONFIG_PLUGIN
607
608
609
610
611
612
613
614 struct qemu_plugin_tb *plugin_tb;
615
616
617 struct qemu_plugin_insn *plugin_insn;
618#endif
619
620 GHashTable *const_table[TCG_TYPE_COUNT];
621 TCGTempSet free_temps[TCG_TYPE_COUNT];
622 TCGTemp temps[TCG_MAX_TEMPS];
623
624 QTAILQ_HEAD(, TCGOp) ops, free_ops;
625 QSIMPLEQ_HEAD(, TCGLabel) labels;
626
627
628
629 TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
630
631 uint16_t gen_insn_end_off[TCG_MAX_INSNS];
632 target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
633
634
635 sigjmp_buf jmp_trans;
636};
637
638static inline bool temp_readonly(TCGTemp *ts)
639{
640 return ts->kind >= TEMP_FIXED;
641}
642
643extern __thread TCGContext *tcg_ctx;
644extern const void *tcg_code_gen_epilogue;
645extern uintptr_t tcg_splitwx_diff;
646extern TCGv_env cpu_env;
647
648bool in_code_gen_buffer(const void *p);
649
650#ifdef CONFIG_DEBUG_TCG
651const void *tcg_splitwx_to_rx(void *rw);
652void *tcg_splitwx_to_rw(const void *rx);
653#else
654static inline const void *tcg_splitwx_to_rx(void *rw)
655{
656 return rw ? rw + tcg_splitwx_diff : NULL;
657}
658
659static inline void *tcg_splitwx_to_rw(const void *rx)
660{
661 return rx ? (void *)rx - tcg_splitwx_diff : NULL;
662}
663#endif
664
665static inline size_t temp_idx(TCGTemp *ts)
666{
667 ptrdiff_t n = ts - tcg_ctx->temps;
668 tcg_debug_assert(n >= 0 && n < tcg_ctx->nb_temps);
669 return n;
670}
671
672static inline TCGArg temp_arg(TCGTemp *ts)
673{
674 return (uintptr_t)ts;
675}
676
677static inline TCGTemp *arg_temp(TCGArg a)
678{
679 return (TCGTemp *)(uintptr_t)a;
680}
681
682
683
684
685static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
686{
687 uintptr_t o = (uintptr_t)v;
688 TCGTemp *t = (void *)tcg_ctx + o;
689 tcg_debug_assert(offsetof(TCGContext, temps[temp_idx(t)]) == o);
690 return t;
691}
692
693static inline TCGTemp *tcgv_i64_temp(TCGv_i64 v)
694{
695 return tcgv_i32_temp((TCGv_i32)v);
696}
697
698static inline TCGTemp *tcgv_i128_temp(TCGv_i128 v)
699{
700 return tcgv_i32_temp((TCGv_i32)v);
701}
702
703static inline TCGTemp *tcgv_ptr_temp(TCGv_ptr v)
704{
705 return tcgv_i32_temp((TCGv_i32)v);
706}
707
708static inline TCGTemp *tcgv_vec_temp(TCGv_vec v)
709{
710 return tcgv_i32_temp((TCGv_i32)v);
711}
712
713static inline TCGArg tcgv_i32_arg(TCGv_i32 v)
714{
715 return temp_arg(tcgv_i32_temp(v));
716}
717
718static inline TCGArg tcgv_i64_arg(TCGv_i64 v)
719{
720 return temp_arg(tcgv_i64_temp(v));
721}
722
723static inline TCGArg tcgv_i128_arg(TCGv_i128 v)
724{
725 return temp_arg(tcgv_i128_temp(v));
726}
727
728static inline TCGArg tcgv_ptr_arg(TCGv_ptr v)
729{
730 return temp_arg(tcgv_ptr_temp(v));
731}
732
733static inline TCGArg tcgv_vec_arg(TCGv_vec v)
734{
735 return temp_arg(tcgv_vec_temp(v));
736}
737
738static inline TCGv_i32 temp_tcgv_i32(TCGTemp *t)
739{
740 (void)temp_idx(t);
741 return (TCGv_i32)((void *)t - (void *)tcg_ctx);
742}
743
744static inline TCGv_i64 temp_tcgv_i64(TCGTemp *t)
745{
746 return (TCGv_i64)temp_tcgv_i32(t);
747}
748
749static inline TCGv_i128 temp_tcgv_i128(TCGTemp *t)
750{
751 return (TCGv_i128)temp_tcgv_i32(t);
752}
753
754static inline TCGv_ptr temp_tcgv_ptr(TCGTemp *t)
755{
756 return (TCGv_ptr)temp_tcgv_i32(t);
757}
758
759static inline TCGv_vec temp_tcgv_vec(TCGTemp *t)
760{
761 return (TCGv_vec)temp_tcgv_i32(t);
762}
763
764static inline TCGArg tcg_get_insn_param(TCGOp *op, int arg)
765{
766 return op->args[arg];
767}
768
769static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v)
770{
771 op->args[arg] = v;
772}
773
774static inline target_ulong tcg_get_insn_start_param(TCGOp *op, int arg)
775{
776#if TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
777 return tcg_get_insn_param(op, arg);
778#else
779 return tcg_get_insn_param(op, arg * 2) |
780 ((uint64_t)tcg_get_insn_param(op, arg * 2 + 1) << 32);
781#endif
782}
783
784static inline void tcg_set_insn_start_param(TCGOp *op, int arg, target_ulong v)
785{
786#if TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
787 tcg_set_insn_param(op, arg, v);
788#else
789 tcg_set_insn_param(op, arg * 2, v);
790 tcg_set_insn_param(op, arg * 2 + 1, v >> 32);
791#endif
792}
793
794
795static inline TCGOp *tcg_last_op(void)
796{
797 return QTAILQ_LAST(&tcg_ctx->ops);
798}
799
800
801static inline bool tcg_op_buf_full(void)
802{
803
804
805
806
807
808
809
810 return tcg_ctx->nb_ops >= 4000;
811}
812
813
814
815
816void *tcg_malloc_internal(TCGContext *s, int size);
817void tcg_pool_reset(TCGContext *s);
818TranslationBlock *tcg_tb_alloc(TCGContext *s);
819
820void tcg_region_reset_all(void);
821
822size_t tcg_code_size(void);
823size_t tcg_code_capacity(void);
824
825void tcg_tb_insert(TranslationBlock *tb);
826void tcg_tb_remove(TranslationBlock *tb);
827TranslationBlock *tcg_tb_lookup(uintptr_t tc_ptr);
828void tcg_tb_foreach(GTraverseFunc func, gpointer user_data);
829size_t tcg_nb_tbs(void);
830
831
832static inline void *tcg_malloc(int size)
833{
834 TCGContext *s = tcg_ctx;
835 uint8_t *ptr, *ptr_end;
836
837
838 size = QEMU_ALIGN_UP(size, 8);
839
840 ptr = s->pool_cur;
841 ptr_end = ptr + size;
842 if (unlikely(ptr_end > s->pool_end)) {
843 return tcg_malloc_internal(tcg_ctx, size);
844 } else {
845 s->pool_cur = ptr_end;
846 return ptr;
847 }
848}
849
850void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus);
851void tcg_register_thread(void);
852void tcg_prologue_init(TCGContext *s);
853void tcg_func_start(TCGContext *s);
854
855int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start);
856
857void tb_target_set_jmp_target(const TranslationBlock *, int,
858 uintptr_t, uintptr_t);
859
860void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
861
862TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr,
863 intptr_t, const char *);
864TCGTemp *tcg_temp_new_internal(TCGType, TCGTempKind);
865TCGv_vec tcg_temp_new_vec(TCGType type);
866TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match);
867
868static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
869 const char *name)
870{
871 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
872 return temp_tcgv_i32(t);
873}
874
875static inline TCGv_i32 tcg_temp_new_i32(void)
876{
877 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB);
878 return temp_tcgv_i32(t);
879}
880
881static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
882 const char *name)
883{
884 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
885 return temp_tcgv_i64(t);
886}
887
888static inline TCGv_i64 tcg_temp_new_i64(void)
889{
890 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB);
891 return temp_tcgv_i64(t);
892}
893
894static inline TCGv_i128 tcg_temp_new_i128(void)
895{
896 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB);
897 return temp_tcgv_i128(t);
898}
899
900static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset,
901 const char *name)
902{
903 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_PTR, reg, offset, name);
904 return temp_tcgv_ptr(t);
905}
906
907static inline TCGv_ptr tcg_temp_new_ptr(void)
908{
909 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB);
910 return temp_tcgv_ptr(t);
911}
912
913int64_t tcg_cpu_exec_time(void);
914void tcg_dump_info(GString *buf);
915void tcg_dump_op_count(GString *buf);
916
917#define TCG_CT_CONST 1
918
919typedef struct TCGArgConstraint {
920 unsigned ct : 16;
921 unsigned alias_index : 4;
922 unsigned sort_index : 4;
923 unsigned pair_index : 4;
924 unsigned pair : 2;
925 bool oalias : 1;
926 bool ialias : 1;
927 bool newreg : 1;
928 TCGRegSet regs;
929} TCGArgConstraint;
930
931#define TCG_MAX_OP_ARGS 16
932
933
934enum {
935
936 TCG_OPF_BB_EXIT = 0x01,
937
938 TCG_OPF_BB_END = 0x02,
939
940 TCG_OPF_CALL_CLOBBER = 0x04,
941
942
943 TCG_OPF_SIDE_EFFECTS = 0x08,
944
945 TCG_OPF_64BIT = 0x10,
946
947
948 TCG_OPF_NOT_PRESENT = 0x20,
949
950 TCG_OPF_VECTOR = 0x40,
951
952 TCG_OPF_COND_BRANCH = 0x80
953};
954
955typedef struct TCGOpDef {
956 const char *name;
957 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
958 uint8_t flags;
959 TCGArgConstraint *args_ct;
960} TCGOpDef;
961
962extern TCGOpDef tcg_op_defs[];
963extern const size_t tcg_op_defs_max;
964
965typedef struct TCGTargetOpDef {
966 TCGOpcode op;
967 const char *args_ct_str[TCG_MAX_OP_ARGS];
968} TCGTargetOpDef;
969
970#define tcg_abort() \
971do {\
972 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
973 abort();\
974} while (0)
975
976bool tcg_op_supported(TCGOpcode op);
977
978void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
979
980TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
981void tcg_op_remove(TCGContext *s, TCGOp *op);
982TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op,
983 TCGOpcode opc, unsigned nargs);
984TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op,
985 TCGOpcode opc, unsigned nargs);
986
987
988
989
990
991
992
993
994
995void tcg_remove_ops_after(TCGOp *op);
996
997void tcg_optimize(TCGContext *s);
998
999
1000
1001
1002
1003
1004TCGTemp *tcg_constant_internal(TCGType type, int64_t val);
1005
1006static inline TCGv_i32 tcg_constant_i32(int32_t val)
1007{
1008 return temp_tcgv_i32(tcg_constant_internal(TCG_TYPE_I32, val));
1009}
1010
1011static inline TCGv_i64 tcg_constant_i64(int64_t val)
1012{
1013 return temp_tcgv_i64(tcg_constant_internal(TCG_TYPE_I64, val));
1014}
1015
1016TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val);
1017TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val);
1018
1019#if UINTPTR_MAX == UINT32_MAX
1020# define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i32((intptr_t)(x)))
1021#else
1022# define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i64((intptr_t)(x)))
1023#endif
1024
1025TCGLabel *gen_new_label(void);
1026
1027
1028
1029
1030
1031
1032
1033
1034static inline TCGArg label_arg(TCGLabel *l)
1035{
1036 return (uintptr_t)l;
1037}
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047static inline TCGLabel *arg_label(TCGArg i)
1048{
1049 return (TCGLabel *)(uintptr_t)i;
1050}
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065static inline ptrdiff_t tcg_ptr_byte_diff(const void *a, const void *b)
1066{
1067 return a - b;
1068}
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, const void *target)
1080{
1081 return tcg_ptr_byte_diff(target, tcg_splitwx_to_rx(s->code_ptr));
1082}
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092static inline ptrdiff_t tcg_tbrel_diff(TCGContext *s, const void *target)
1093{
1094 return tcg_ptr_byte_diff(target, tcg_splitwx_to_rx(s->code_buf));
1095}
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105static inline size_t tcg_current_code_size(TCGContext *s)
1106{
1107 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
1108}
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155#define TB_EXIT_MASK 3
1156#define TB_EXIT_IDX0 0
1157#define TB_EXIT_IDX1 1
1158#define TB_EXIT_IDXMAX 1
1159#define TB_EXIT_REQUESTED 3
1160
1161#ifdef CONFIG_TCG_INTERPRETER
1162uintptr_t tcg_qemu_tb_exec(CPUArchState *env, const void *tb_ptr);
1163#else
1164typedef uintptr_t tcg_prologue_fn(CPUArchState *env, const void *tb_ptr);
1165extern tcg_prologue_fn *tcg_qemu_tb_exec;
1166#endif
1167
1168void tcg_register_jit(const void *buf, size_t buf_size);
1169
1170#if TCG_TARGET_MAYBE_vec
1171
1172
1173
1174int tcg_can_emit_vec_op(TCGOpcode, TCGType, unsigned);
1175#else
1176static inline int tcg_can_emit_vec_op(TCGOpcode o, TCGType t, unsigned ve)
1177{
1178 return 0;
1179}
1180#endif
1181
1182
1183void tcg_expand_vec_op(TCGOpcode, TCGType, unsigned, TCGArg, ...);
1184
1185
1186uint64_t dup_const(unsigned vece, uint64_t c);
1187
1188#define dup_const(VECE, C) \
1189 (__builtin_constant_p(VECE) \
1190 ? ( (VECE) == MO_8 ? 0x0101010101010101ull * (uint8_t)(C) \
1191 : (VECE) == MO_16 ? 0x0001000100010001ull * (uint16_t)(C) \
1192 : (VECE) == MO_32 ? 0x0000000100000001ull * (uint32_t)(C) \
1193 : (VECE) == MO_64 ? (uint64_t)(C) \
1194 : (qemu_build_not_reached_always(), 0)) \
1195 : dup_const(VECE, C))
1196
1197#if TARGET_LONG_BITS == 64
1198# define dup_const_tl dup_const
1199#else
1200# define dup_const_tl(VECE, C) \
1201 (__builtin_constant_p(VECE) \
1202 ? ( (VECE) == MO_8 ? 0x01010101ul * (uint8_t)(C) \
1203 : (VECE) == MO_16 ? 0x00010001ul * (uint16_t)(C) \
1204 : (VECE) == MO_32 ? 0x00000001ul * (uint32_t)(C) \
1205 : (qemu_build_not_reached_always(), 0)) \
1206 : (target_long)dup_const(VECE, C))
1207#endif
1208
1209#ifdef CONFIG_DEBUG_TCG
1210void tcg_assert_listed_vecop(TCGOpcode);
1211#else
1212static inline void tcg_assert_listed_vecop(TCGOpcode op) { }
1213#endif
1214
1215static inline const TCGOpcode *tcg_swap_vecop_list(const TCGOpcode *n)
1216{
1217#ifdef CONFIG_DEBUG_TCG
1218 const TCGOpcode *o = tcg_ctx->vecop_list;
1219 tcg_ctx->vecop_list = n;
1220 return o;
1221#else
1222 return NULL;
1223#endif
1224}
1225
1226bool tcg_can_emit_vecop_list(const TCGOpcode *, TCGType, unsigned);
1227
1228#endif
1229