25
#include "qemu/osdep.h"
30
#include "qemu/error-report.h"
31
#include "qemu/cutils.h"
32
#include "qemu/host-utils.h"
33
#include "qemu/qemu-print.h"
34
#include "qemu/cacheflush.h"
35
#include "qemu/cacheinfo.h"
36
#include "qemu/timer.h"
37
#include "exec/translation-block.h"
38
#include "exec/tlb-common.h"
39
#include "tcg/startup.h"
40
#include "tcg/tcg-op-common.h"
42
#if UINTPTR_MAX == UINT32_MAX
43
# define ELF_CLASS ELFCLASS32
45
# define ELF_CLASS ELFCLASS64
48
# define ELF_DATA ELFDATA2MSB
50
# define ELF_DATA ELFDATA2LSB
55
#include "tcg/tcg-ldst.h"
56
#include "tcg/tcg-temp-internal.h"
57
#include "tcg-internal.h"
59
#ifdef CONFIG_USER_ONLY
60
#include "user/guest-base.h"
65
static void tcg_target_init(TCGContext *s);
66
static void tcg_target_qemu_prologue(TCGContext *s);
67
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
68
intptr_t value, intptr_t addend);
72
uint32_t len __attribute__((aligned((sizeof(void *)))));
78
uint8_t return_column;
81
typedef struct QEMU_PACKED {
82
uint32_t len __attribute__((aligned((sizeof(void *)))));
88
typedef struct QEMU_PACKED {
90
DebugFrameFDEHeader fde;
93
typedef struct TCGLabelQemuLdst {
101
const tcg_insn_unit *raddr;
102
tcg_insn_unit *label_ptr[2];
103
QSIMPLEQ_ENTRY(TCGLabelQemuLdst) next;
106
static void tcg_register_jit_int(const void *buf, size_t size,
107
const void *debug_frame,
108
size_t debug_frame_size)
109
__attribute__((unused));
112
static void tcg_out_tb_start(TCGContext *s);
113
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
115
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
116
static void tcg_out_movi(TCGContext *s, TCGType type,
117
TCGReg ret, tcg_target_long arg);
118
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
119
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
120
static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
121
static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
122
static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
123
static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg);
124
static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
125
static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
126
static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg);
127
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
128
static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2);
129
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
130
static void tcg_out_goto_tb(TCGContext *s, int which);
131
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
132
const TCGArg args[TCG_MAX_OP_ARGS],
133
const int const_args[TCG_MAX_OP_ARGS]);
134
#if TCG_TARGET_MAYBE_vec
135
static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
136
TCGReg dst, TCGReg src);
137
static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
138
TCGReg dst, TCGReg base, intptr_t offset);
139
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
140
TCGReg dst, int64_t arg);
141
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
142
unsigned vecl, unsigned vece,
143
const TCGArg args[TCG_MAX_OP_ARGS],
144
const int const_args[TCG_MAX_OP_ARGS]);
146
static inline bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
147
TCGReg dst, TCGReg src)
149
g_assert_not_reached();
151
static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
152
TCGReg dst, TCGReg base, intptr_t offset)
154
g_assert_not_reached();
156
static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
157
TCGReg dst, int64_t arg)
159
g_assert_not_reached();
161
static inline void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
162
unsigned vecl, unsigned vece,
163
const TCGArg args[TCG_MAX_OP_ARGS],
164
const int const_args[TCG_MAX_OP_ARGS])
166
g_assert_not_reached();
169
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
171
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
172
TCGReg base, intptr_t ofs);
173
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
174
const TCGHelperInfo *info);
175
static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot);
176
static bool tcg_target_const_match(int64_t val, int ct,
177
TCGType type, TCGCond cond, int vece);
178
#ifdef TCG_TARGET_NEED_LDST_LABELS
179
static int tcg_out_ldst_finalize(TCGContext *s);
182
#ifndef CONFIG_USER_ONLY
183
#define guest_base ({ qemu_build_not_reached(); (uintptr_t)0; })
186
typedef struct TCGLdstHelperParam {
187
TCGReg (*ra_gen)(TCGContext *s, const TCGLabelQemuLdst *l, int arg_reg);
192
static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *l,
193
const TCGLdstHelperParam *p)
194
__attribute__((unused));
195
static void tcg_out_ld_helper_ret(TCGContext *s, const TCGLabelQemuLdst *l,
196
bool load_sign, const TCGLdstHelperParam *p)
197
__attribute__((unused));
198
static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *l,
199
const TCGLdstHelperParam *p)
200
__attribute__((unused));
202
static void * const qemu_ld_helpers[MO_SSIZE + 1] __attribute__((unused)) = {
203
[MO_UB] = helper_ldub_mmu,
204
[MO_SB] = helper_ldsb_mmu,
205
[MO_UW] = helper_lduw_mmu,
206
[MO_SW] = helper_ldsw_mmu,
207
[MO_UL] = helper_ldul_mmu,
208
[MO_UQ] = helper_ldq_mmu,
209
#if TCG_TARGET_REG_BITS == 64
210
[MO_SL] = helper_ldsl_mmu,
211
[MO_128] = helper_ld16_mmu,
215
static void * const qemu_st_helpers[MO_SIZE + 1] __attribute__((unused)) = {
216
[MO_8] = helper_stb_mmu,
217
[MO_16] = helper_stw_mmu,
218
[MO_32] = helper_stl_mmu,
219
[MO_64] = helper_stq_mmu,
220
#if TCG_TARGET_REG_BITS == 64
221
[MO_128] = helper_st16_mmu,
230
static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc,
231
MemOp host_atom, bool allow_two_ops)
232
__attribute__((unused));
234
#ifdef CONFIG_USER_ONLY
238
TCGContext tcg_init_ctx;
239
__thread TCGContext *tcg_ctx;
241
TCGContext **tcg_ctxs;
242
unsigned int tcg_cur_ctxs;
243
unsigned int tcg_max_ctxs;
245
const void *tcg_code_gen_epilogue;
246
uintptr_t tcg_splitwx_diff;
248
#ifndef CONFIG_TCG_INTERPRETER
249
tcg_prologue_fn *tcg_qemu_tb_exec;
252
static TCGRegSet tcg_target_available_regs[TCG_TYPE_COUNT];
253
static TCGRegSet tcg_target_call_clobber_regs;
255
#if TCG_TARGET_INSN_UNIT_SIZE == 1
256
static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
261
static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
268
#if TCG_TARGET_INSN_UNIT_SIZE <= 2
269
static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
271
if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
274
tcg_insn_unit *p = s->code_ptr;
275
memcpy(p, &v, sizeof(v));
276
s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
280
static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
283
if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
286
memcpy(p, &v, sizeof(v));
291
#if TCG_TARGET_INSN_UNIT_SIZE <= 4
292
static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
294
if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
297
tcg_insn_unit *p = s->code_ptr;
298
memcpy(p, &v, sizeof(v));
299
s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
303
static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
306
if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
309
memcpy(p, &v, sizeof(v));
314
#if TCG_TARGET_INSN_UNIT_SIZE <= 8
315
static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
317
if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
320
tcg_insn_unit *p = s->code_ptr;
321
memcpy(p, &v, sizeof(v));
322
s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
326
static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
329
if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
332
memcpy(p, &v, sizeof(v));
339
static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
340
TCGLabel *l, intptr_t addend)
342
TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation));
347
QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
350
static void tcg_out_label(TCGContext *s, TCGLabel *l)
352
tcg_debug_assert(!l->has_value);
354
l->u.value_ptr = tcg_splitwx_to_rx(s->code_ptr);
357
TCGLabel *gen_new_label(void)
359
TCGContext *s = tcg_ctx;
360
TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
362
memset(l, 0, sizeof(TCGLabel));
363
l->id = s->nb_labels++;
364
QSIMPLEQ_INIT(&l->branches);
365
QSIMPLEQ_INIT(&l->relocs);
367
QSIMPLEQ_INSERT_TAIL(&s->labels, l, next);
372
static bool tcg_resolve_relocs(TCGContext *s)
376
QSIMPLEQ_FOREACH(l, &s->labels, next) {
378
uintptr_t value = l->u.value;
380
QSIMPLEQ_FOREACH(r, &l->relocs, next) {
381
if (!patch_reloc(r->ptr, r->type, value, r->addend)) {
389
static void set_jmp_reset_offset(TCGContext *s, int which)
395
s->gen_tb->jmp_reset_offset[which] = tcg_current_code_size(s);
398
static void G_GNUC_UNUSED set_jmp_insn_offset(TCGContext *s, int which)
404
s->gen_tb->jmp_insn_offset[which] = tcg_current_code_size(s);
407
static uintptr_t G_GNUC_UNUSED get_jmp_target_addr(TCGContext *s, int which)
413
return (uintptr_t)tcg_splitwx_to_rx(&s->gen_tb->jmp_target_addr[which]);
416
static int __attribute__((unused))
417
tlb_mask_table_ofs(TCGContext *s, int which)
419
return (offsetof(CPUNegativeOffsetState, tlb.f[which]) -
420
sizeof(CPUNegativeOffsetState));
425
void tcg_raise_tb_overflow(TCGContext *s)
427
siglongjmp(s->jmp_trans, -2);
439
typedef struct TCGMovExtend {
458
static void tcg_out_movext(TCGContext *s, TCGType dst_type, TCGReg dst,
459
TCGType src_type, MemOp src_ext, TCGReg src)
463
tcg_out_ext8u(s, dst, src);
466
tcg_out_ext8s(s, dst_type, dst, src);
469
tcg_out_ext16u(s, dst, src);
472
tcg_out_ext16s(s, dst_type, dst, src);
476
if (dst_type == TCG_TYPE_I32) {
477
if (src_type == TCG_TYPE_I32) {
478
tcg_out_mov(s, TCG_TYPE_I32, dst, src);
480
tcg_out_extrl_i64_i32(s, dst, src);
482
} else if (src_type == TCG_TYPE_I32) {
483
if (src_ext & MO_SIGN) {
484
tcg_out_exts_i32_i64(s, dst, src);
486
tcg_out_extu_i32_i64(s, dst, src);
489
if (src_ext & MO_SIGN) {
490
tcg_out_ext32s(s, dst, src);
492
tcg_out_ext32u(s, dst, src);
497
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
498
if (dst_type == TCG_TYPE_I32) {
499
tcg_out_extrl_i64_i32(s, dst, src);
501
tcg_out_mov(s, TCG_TYPE_I64, dst, src);
505
g_assert_not_reached();
510
static void tcg_out_movext1_new_src(TCGContext *s, const TCGMovExtend *i,
513
tcg_out_movext(s, i->dst_type, i->dst, i->src_type, i->src_ext, src);
516
static void tcg_out_movext1(TCGContext *s, const TCGMovExtend *i)
518
tcg_out_movext1_new_src(s, i, i->src);
532
static void tcg_out_movext2(TCGContext *s, const TCGMovExtend *i1,
533
const TCGMovExtend *i2, int scratch)
535
TCGReg src1 = i1->src;
536
TCGReg src2 = i2->src;
538
if (i1->dst != src2) {
539
tcg_out_movext1(s, i1);
540
tcg_out_movext1(s, i2);
543
if (i2->dst == src1) {
544
TCGType src1_type = i1->src_type;
545
TCGType src2_type = i2->src_type;
547
if (tcg_out_xchg(s, MAX(src1_type, src2_type), src1, src2)) {
552
tcg_debug_assert(scratch >= 0);
553
tcg_out_mov(s, src1_type, scratch, src1);
557
tcg_out_movext1_new_src(s, i2, src2);
558
tcg_out_movext1_new_src(s, i1, src1);
573
static void tcg_out_movext3(TCGContext *s, const TCGMovExtend *i1,
574
const TCGMovExtend *i2, const TCGMovExtend *i3,
577
TCGReg src1 = i1->src;
578
TCGReg src2 = i2->src;
579
TCGReg src3 = i3->src;
581
if (i1->dst != src2 && i1->dst != src3) {
582
tcg_out_movext1(s, i1);
583
tcg_out_movext2(s, i2, i3, scratch);
586
if (i2->dst != src1 && i2->dst != src3) {
587
tcg_out_movext1(s, i2);
588
tcg_out_movext2(s, i1, i3, scratch);
591
if (i3->dst != src1 && i3->dst != src2) {
592
tcg_out_movext1(s, i3);
593
tcg_out_movext2(s, i1, i2, scratch);
602
if (i1->dst == src2 && i2->dst == src3 && i3->dst == src1) {
604
if (tcg_out_xchg(s, MAX(i1->src_type, i2->src_type), src1, src2)) {
605
tcg_out_xchg(s, MAX(i2->src_type, i3->src_type), src2, src3);
607
tcg_out_movext1_new_src(s, i1, i1->dst);
608
tcg_out_movext1_new_src(s, i2, i2->dst);
609
tcg_out_movext1_new_src(s, i3, i3->dst);
611
tcg_debug_assert(scratch >= 0);
612
tcg_out_mov(s, i1->src_type, scratch, src1);
613
tcg_out_movext1(s, i3);
614
tcg_out_movext1(s, i2);
615
tcg_out_movext1_new_src(s, i1, scratch);
617
} else if (i1->dst == src3 && i2->dst == src1 && i3->dst == src2) {
619
if (tcg_out_xchg(s, MAX(i2->src_type, i3->src_type), src2, src3)) {
620
tcg_out_xchg(s, MAX(i1->src_type, i2->src_type), src1, src2);
622
tcg_out_movext1_new_src(s, i1, i1->dst);
623
tcg_out_movext1_new_src(s, i2, i2->dst);
624
tcg_out_movext1_new_src(s, i3, i3->dst);
626
tcg_debug_assert(scratch >= 0);
627
tcg_out_mov(s, i1->src_type, scratch, src1);
628
tcg_out_movext1(s, i2);
629
tcg_out_movext1(s, i3);
630
tcg_out_movext1_new_src(s, i1, scratch);
633
g_assert_not_reached();
637
#define C_PFX1(P, A) P##A
638
#define C_PFX2(P, A, B) P##A##_##B
639
#define C_PFX3(P, A, B, C) P##A##_##B##_##C
640
#define C_PFX4(P, A, B, C, D) P##A##_##B##_##C##_##D
641
#define C_PFX5(P, A, B, C, D, E) P##A##_##B##_##C##_##D##_##E
642
#define C_PFX6(P, A, B, C, D, E, F) P##A##_##B##_##C##_##D##_##E##_##F
646
#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1),
647
#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2),
648
#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3),
649
#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4),
651
#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1),
652
#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2),
653
#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3),
654
#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4),
656
#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2),
657
#define C_N1O1_I1(O1, O2, I1) C_PFX3(c_n1o1_i1_, O1, O2, I1),
658
#define C_N2_I1(O1, O2, I1) C_PFX3(c_n2_i1_, O1, O2, I1),
660
#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1),
661
#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
662
#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
663
#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4),
664
#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, I3, I4),
667
#include "tcg-target-con-set.h"
668
} TCGConstraintSetIndex;
670
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
691
#define C_O0_I1(I1) { .args_ct_str = { #I1 } },
692
#define C_O0_I2(I1, I2) { .args_ct_str = { #I1, #I2 } },
693
#define C_O0_I3(I1, I2, I3) { .args_ct_str = { #I1, #I2, #I3 } },
694
#define C_O0_I4(I1, I2, I3, I4) { .args_ct_str = { #I1, #I2, #I3, #I4 } },
696
#define C_O1_I1(O1, I1) { .args_ct_str = { #O1, #I1 } },
697
#define C_O1_I2(O1, I1, I2) { .args_ct_str = { #O1, #I1, #I2 } },
698
#define C_O1_I3(O1, I1, I2, I3) { .args_ct_str = { #O1, #I1, #I2, #I3 } },
699
#define C_O1_I4(O1, I1, I2, I3, I4) { .args_ct_str = { #O1, #I1, #I2, #I3, #I4 } },
701
#define C_N1_I2(O1, I1, I2) { .args_ct_str = { "&" #O1, #I1, #I2 } },
702
#define C_N1O1_I1(O1, O2, I1) { .args_ct_str = { "&" #O1, #O2, #I1 } },
703
#define C_N2_I1(O1, O2, I1) { .args_ct_str = { "&" #O1, "&" #O2, #I1 } },
705
#define C_O2_I1(O1, O2, I1) { .args_ct_str = { #O1, #O2, #I1 } },
706
#define C_O2_I2(O1, O2, I1, I2) { .args_ct_str = { #O1, #O2, #I1, #I2 } },
707
#define C_O2_I3(O1, O2, I1, I2, I3) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3 } },
708
#define C_O2_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3, #I4 } },
709
#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { "&" #O1, #O2, #I1, #I2, #I3, #I4 } },
711
static const TCGTargetOpDef constraint_sets[] = {
712
#include "tcg-target-con-set.h"
735
#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1)
736
#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2)
737
#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3)
738
#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4)
740
#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1)
741
#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2)
742
#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3)
743
#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4)
745
#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2)
746
#define C_N1O1_I1(O1, O2, I1) C_PFX3(c_n1o1_i1_, O1, O2, I1)
747
#define C_N2_I1(O1, O2, I1) C_PFX3(c_n2_i1_, O1, O2, I1)
749
#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1)
750
#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2)
751
#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
752
#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
753
#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, I3, I4)
755
#include "tcg-target.c.inc"
757
#ifndef CONFIG_TCG_INTERPRETER
759
QEMU_BUILD_BUG_ON((int)(offsetof(CPUNegativeOffsetState, tlb.f[0]) -
760
sizeof(CPUNegativeOffsetState))
761
< MIN_TLB_MASK_TABLE_OFS);
780
#ifdef CONFIG_USER_ONLY
781
void tcg_register_thread(void)
783
tcg_ctx = &tcg_init_ctx;
786
void tcg_register_thread(void)
788
TCGContext *s = g_malloc(sizeof(*s));
794
for (i = 0, n = tcg_init_ctx.nb_globals; i < n; ++i) {
795
if (tcg_init_ctx.temps[i].mem_base) {
796
ptrdiff_t b = tcg_init_ctx.temps[i].mem_base - tcg_init_ctx.temps;
797
tcg_debug_assert(b >= 0 && b < n);
798
s->temps[i].mem_base = &s->temps[b];
803
n = qatomic_fetch_inc(&tcg_cur_ctxs);
804
g_assert(n < tcg_max_ctxs);
805
qatomic_set(&tcg_ctxs[n], s);
808
tcg_region_initial_alloc(s);
816
void *tcg_malloc_internal(TCGContext *s, int size)
821
if (size > TCG_POOL_CHUNK_SIZE) {
823
p = g_malloc(sizeof(TCGPool) + size);
825
p->next = s->pool_first_large;
826
s->pool_first_large = p;
837
pool_size = TCG_POOL_CHUNK_SIZE;
838
p = g_malloc(sizeof(TCGPool) + pool_size);
841
if (s->pool_current) {
842
s->pool_current->next = p;
852
s->pool_cur = p->data + size;
853
s->pool_end = p->data + p->size;
857
void tcg_pool_reset(TCGContext *s)
860
for (p = s->pool_first_large; p; p = t) {
864
s->pool_first_large = NULL;
865
s->pool_cur = s->pool_end = NULL;
866
s->pool_current = NULL;
877
#if TCG_TARGET_REG_BITS == 32
878
# define dh_typecode_ttl dh_typecode_i32
880
# define dh_typecode_ttl dh_typecode_i64
883
static TCGHelperInfo info_helper_ld32_mmu = {
884
.flags = TCG_CALL_NO_WG,
885
.typemask = dh_typemask(ttl, 0)
886
| dh_typemask(env, 1)
887
| dh_typemask(i64, 2)
888
| dh_typemask(i32, 3)
889
| dh_typemask(ptr, 4)
892
static TCGHelperInfo info_helper_ld64_mmu = {
893
.flags = TCG_CALL_NO_WG,
894
.typemask = dh_typemask(i64, 0)
895
| dh_typemask(env, 1)
896
| dh_typemask(i64, 2)
897
| dh_typemask(i32, 3)
898
| dh_typemask(ptr, 4)
901
static TCGHelperInfo info_helper_ld128_mmu = {
902
.flags = TCG_CALL_NO_WG,
903
.typemask = dh_typemask(i128, 0)
904
| dh_typemask(env, 1)
905
| dh_typemask(i64, 2)
906
| dh_typemask(i32, 3)
907
| dh_typemask(ptr, 4)
910
static TCGHelperInfo info_helper_st32_mmu = {
911
.flags = TCG_CALL_NO_WG,
912
.typemask = dh_typemask(void, 0)
913
| dh_typemask(env, 1)
914
| dh_typemask(i64, 2)
915
| dh_typemask(i32, 3)
916
| dh_typemask(i32, 4)
917
| dh_typemask(ptr, 5)
920
static TCGHelperInfo info_helper_st64_mmu = {
921
.flags = TCG_CALL_NO_WG,
922
.typemask = dh_typemask(void, 0)
923
| dh_typemask(env, 1)
924
| dh_typemask(i64, 2)
925
| dh_typemask(i64, 3)
926
| dh_typemask(i32, 4)
927
| dh_typemask(ptr, 5)
930
static TCGHelperInfo info_helper_st128_mmu = {
931
.flags = TCG_CALL_NO_WG,
932
.typemask = dh_typemask(void, 0)
933
| dh_typemask(env, 1)
934
| dh_typemask(i64, 2)
935
| dh_typemask(i128, 3)
936
| dh_typemask(i32, 4)
937
| dh_typemask(ptr, 5)
940
#ifdef CONFIG_TCG_INTERPRETER
941
static ffi_type *typecode_to_ffi(int argmask)
947
static ffi_type *ffi_type_i128_elements[3] = {
952
static ffi_type ffi_type_i128 = {
954
.alignment = __alignof__(Int128),
955
.type = FFI_TYPE_STRUCT,
956
.elements = ffi_type_i128_elements,
960
case dh_typecode_void:
961
return &ffi_type_void;
962
case dh_typecode_i32:
963
return &ffi_type_uint32;
964
case dh_typecode_s32:
965
return &ffi_type_sint32;
966
case dh_typecode_i64:
967
return &ffi_type_uint64;
968
case dh_typecode_s64:
969
return &ffi_type_sint64;
970
case dh_typecode_ptr:
971
return &ffi_type_pointer;
972
case dh_typecode_i128:
973
return &ffi_type_i128;
975
g_assert_not_reached();
978
static ffi_cif *init_ffi_layout(TCGHelperInfo *info)
980
unsigned typemask = info->typemask;
989
nargs = 32 - clz32(typemask >> 3);
990
nargs = DIV_ROUND_UP(nargs, 3);
991
assert(nargs <= MAX_CALL_IARGS);
993
ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
994
ca->cif.rtype = typecode_to_ffi(typemask & 7);
995
ca->cif.nargs = nargs;
998
ca->cif.arg_types = ca->args;
999
for (int j = 0; j < nargs; ++j) {
1000
int typecode = extract32(typemask, (j + 1) * 3, 3);
1001
ca->args[j] = typecode_to_ffi(typecode);
1005
status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
1006
ca->cif.rtype, ca->cif.arg_types);
1007
assert(status == FFI_OK);
1012
#define HELPER_INFO_INIT(I) (&(I)->cif)
1013
#define HELPER_INFO_INIT_VAL(I) init_ffi_layout(I)
1015
#define HELPER_INFO_INIT(I) (&(I)->init)
1016
#define HELPER_INFO_INIT_VAL(I) 1
1019
static inline bool arg_slot_reg_p(unsigned arg_slot)
1025
unsigned nreg = ARRAY_SIZE(tcg_target_call_iarg_regs);
1026
return arg_slot < nreg;
1029
static inline int arg_slot_stk_ofs(unsigned arg_slot)
1031
unsigned max = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long);
1032
unsigned stk_slot = arg_slot - ARRAY_SIZE(tcg_target_call_iarg_regs);
1034
tcg_debug_assert(stk_slot < max);
1035
return TCG_TARGET_CALL_STACK_OFFSET + stk_slot * sizeof(tcg_target_long);
1038
typedef struct TCGCumulativeArgs {
1045
static void layout_arg_even(TCGCumulativeArgs *cum)
1047
cum->arg_slot += cum->arg_slot & 1;
1050
static void layout_arg_1(TCGCumulativeArgs *cum, TCGHelperInfo *info,
1051
TCGCallArgumentKind kind)
1053
TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
1055
*loc = (TCGCallArgumentLoc){
1057
.arg_idx = cum->arg_idx,
1058
.arg_slot = cum->arg_slot,
1064
static void layout_arg_normal_n(TCGCumulativeArgs *cum,
1065
TCGHelperInfo *info, int n)
1067
TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
1069
for (int i = 0; i < n; ++i) {
1071
loc[i] = (TCGCallArgumentLoc){
1072
.kind = TCG_CALL_ARG_NORMAL,
1073
.arg_idx = cum->arg_idx,
1075
.arg_slot = cum->arg_slot + i,
1078
cum->info_in_idx += n;
1082
static void layout_arg_by_ref(TCGCumulativeArgs *cum, TCGHelperInfo *info)
1084
TCGCallArgumentLoc *loc = &info->in[cum->info_in_idx];
1085
int n = 128 / TCG_TARGET_REG_BITS;
1088
layout_arg_1(cum, info, TCG_CALL_ARG_BY_REF);
1096
loc[0].ref_slot = cum->ref_slot;
1102
for (int i = 1; i < n; ++i) {
1103
loc[i] = (TCGCallArgumentLoc){
1104
.kind = TCG_CALL_ARG_BY_REF_N,
1105
.arg_idx = cum->arg_idx,
1107
.ref_slot = cum->ref_slot + i,
1110
cum->info_in_idx += n - 1;
1114
static void init_call_layout(TCGHelperInfo *info)
1116
int max_reg_slots = ARRAY_SIZE(tcg_target_call_iarg_regs);
1117
int max_stk_slots = TCG_STATIC_CALL_ARGS_SIZE / sizeof(tcg_target_long);
1118
unsigned typemask = info->typemask;
1120
TCGCumulativeArgs cum = { };
1125
typecode = typemask & 7;
1127
case dh_typecode_void:
1130
case dh_typecode_i32:
1131
case dh_typecode_s32:
1132
case dh_typecode_ptr:
1134
info->out_kind = TCG_CALL_RET_NORMAL;
1136
case dh_typecode_i64:
1137
case dh_typecode_s64:
1138
info->nr_out = 64 / TCG_TARGET_REG_BITS;
1139
info->out_kind = TCG_CALL_RET_NORMAL;
1141
tcg_target_call_oarg_reg(info->out_kind, info->nr_out - 1);
1143
case dh_typecode_i128:
1144
info->nr_out = 128 / TCG_TARGET_REG_BITS;
1145
info->out_kind = TCG_TARGET_CALL_RET_I128;
1146
switch (TCG_TARGET_CALL_RET_I128) {
1147
case TCG_CALL_RET_NORMAL:
1149
tcg_target_call_oarg_reg(info->out_kind, info->nr_out - 1);
1151
case TCG_CALL_RET_BY_VEC:
1153
tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0);
1155
case TCG_CALL_RET_BY_REF:
1164
qemu_build_not_reached();
1168
g_assert_not_reached();
1174
for (typemask >>= 3; typemask; typemask >>= 3, cum.arg_idx++) {
1175
TCGCallArgumentKind kind;
1178
typecode = typemask & 7;
1180
case dh_typecode_i32:
1181
case dh_typecode_s32:
1182
type = TCG_TYPE_I32;
1184
case dh_typecode_i64:
1185
case dh_typecode_s64:
1186
type = TCG_TYPE_I64;
1188
case dh_typecode_ptr:
1189
type = TCG_TYPE_PTR;
1191
case dh_typecode_i128:
1192
type = TCG_TYPE_I128;
1195
g_assert_not_reached();
1200
switch (TCG_TARGET_CALL_ARG_I32) {
1201
case TCG_CALL_ARG_EVEN:
1202
layout_arg_even(&cum);
1204
case TCG_CALL_ARG_NORMAL:
1205
layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL);
1207
case TCG_CALL_ARG_EXTEND:
1208
kind = TCG_CALL_ARG_EXTEND_U + (typecode & 1);
1209
layout_arg_1(&cum, info, kind);
1212
qemu_build_not_reached();
1217
switch (TCG_TARGET_CALL_ARG_I64) {
1218
case TCG_CALL_ARG_EVEN:
1219
layout_arg_even(&cum);
1221
case TCG_CALL_ARG_NORMAL:
1222
if (TCG_TARGET_REG_BITS == 32) {
1223
layout_arg_normal_n(&cum, info, 2);
1225
layout_arg_1(&cum, info, TCG_CALL_ARG_NORMAL);
1229
qemu_build_not_reached();
1234
switch (TCG_TARGET_CALL_ARG_I128) {
1235
case TCG_CALL_ARG_EVEN:
1236
layout_arg_even(&cum);
1238
case TCG_CALL_ARG_NORMAL:
1239
layout_arg_normal_n(&cum, info, 128 / TCG_TARGET_REG_BITS);
1241
case TCG_CALL_ARG_BY_REF:
1242
layout_arg_by_ref(&cum, info);
1245
qemu_build_not_reached();
1250
g_assert_not_reached();
1253
info->nr_in = cum.info_in_idx;
1256
assert(cum.info_in_idx <= ARRAY_SIZE(info->in));
1258
assert(cum.arg_slot <= max_reg_slots + max_stk_slots);
1265
if (cum.ref_slot != 0) {
1268
if (cum.arg_slot > max_reg_slots) {
1269
int align = __alignof(Int128) / sizeof(tcg_target_long);
1271
ref_base = cum.arg_slot - max_reg_slots;
1273
ref_base = ROUND_UP(ref_base, align);
1276
assert(ref_base + cum.ref_slot <= max_stk_slots);
1277
ref_base += max_reg_slots;
1279
if (ref_base != 0) {
1280
for (int i = cum.info_in_idx - 1; i >= 0; --i) {
1281
TCGCallArgumentLoc *loc = &info->in[i];
1282
switch (loc->kind) {
1283
case TCG_CALL_ARG_BY_REF:
1284
case TCG_CALL_ARG_BY_REF_N:
1285
loc->ref_slot += ref_base;
1295
static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
1296
static void process_op_defs(TCGContext *s);
1297
static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
1298
TCGReg reg, const char *name);
1300
static void tcg_context_init(unsigned max_cpus)
1302
TCGContext *s = &tcg_init_ctx;
1303
int op, total_args, n, i;
1305
TCGArgConstraint *args_ct;
1308
memset(s, 0, sizeof(*s));
1314
for(op = 0; op < NB_OPS; op++) {
1315
def = &tcg_op_defs[op];
1316
n = def->nb_iargs + def->nb_oargs;
1320
args_ct = g_new0(TCGArgConstraint, total_args);
1322
for(op = 0; op < NB_OPS; op++) {
1323
def = &tcg_op_defs[op];
1324
def->args_ct = args_ct;
1325
n = def->nb_iargs + def->nb_oargs;
1329
init_call_layout(&info_helper_ld32_mmu);
1330
init_call_layout(&info_helper_ld64_mmu);
1331
init_call_layout(&info_helper_ld128_mmu);
1332
init_call_layout(&info_helper_st32_mmu);
1333
init_call_layout(&info_helper_st64_mmu);
1334
init_call_layout(&info_helper_st128_mmu);
1341
for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
1342
int r = tcg_target_reg_alloc_order[n];
1343
if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) {
1347
for (i = 0; i < n; ++i) {
1348
indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
1350
for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
1351
indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
1361
#ifdef CONFIG_USER_ONLY
1362
tcg_ctxs = &tcg_ctx;
1366
tcg_max_ctxs = max_cpus;
1367
tcg_ctxs = g_new0(TCGContext *, max_cpus);
1370
tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0));
1371
ts = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, TCG_AREG0, "env");
1372
tcg_env = temp_tcgv_ptr(ts);
1375
void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus)
1377
tcg_context_init(max_cpus);
1378
tcg_region_init(tb_size, splitwx, max_cpus);
1385
TranslationBlock *tcg_tb_alloc(TCGContext *s)
1387
uintptr_t align = qemu_icache_linesize;
1388
TranslationBlock *tb;
1392
tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
1393
next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
1395
if (unlikely(next > s->code_gen_highwater)) {
1396
if (tcg_region_alloc(s)) {
1401
qatomic_set(&s->code_gen_ptr, next);
1402
s->data_gen_ptr = NULL;
1406
void tcg_prologue_init(void)
1408
TCGContext *s = tcg_ctx;
1409
size_t prologue_size;
1411
s->code_ptr = s->code_gen_ptr;
1412
s->code_buf = s->code_gen_ptr;
1413
s->data_gen_ptr = NULL;
1415
#ifndef CONFIG_TCG_INTERPRETER
1416
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
1419
#ifdef TCG_TARGET_NEED_POOL_LABELS
1420
s->pool_labels = NULL;
1423
qemu_thread_jit_write();
1425
tcg_target_qemu_prologue(s);
1427
#ifdef TCG_TARGET_NEED_POOL_LABELS
1430
int result = tcg_out_pool_finalize(s);
1431
tcg_debug_assert(result == 0);
1435
prologue_size = tcg_current_code_size(s);
1436
perf_report_prologue(s->code_gen_ptr, prologue_size);
1438
#ifndef CONFIG_TCG_INTERPRETER
1439
flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
1440
(uintptr_t)s->code_buf, prologue_size);
1443
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
1444
FILE *logfile = qemu_log_trylock();
1446
fprintf(logfile, "PROLOGUE: [size=%zu]\n", prologue_size);
1447
if (s->data_gen_ptr) {
1448
size_t code_size = s->data_gen_ptr - s->code_gen_ptr;
1449
size_t data_size = prologue_size - code_size;
1452
disas(logfile, s->code_gen_ptr, code_size);
1454
for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
1455
if (sizeof(tcg_target_ulong) == 8) {
1457
"0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
1458
(uintptr_t)s->data_gen_ptr + i,
1459
*(uint64_t *)(s->data_gen_ptr + i));
1462
"0x%08" PRIxPTR ": .long 0x%08x\n",
1463
(uintptr_t)s->data_gen_ptr + i,
1464
*(uint32_t *)(s->data_gen_ptr + i));
1468
disas(logfile, s->code_gen_ptr, prologue_size);
1470
fprintf(logfile, "\n");
1471
qemu_log_unlock(logfile);
1475
#ifndef CONFIG_TCG_INTERPRETER
1481
tcg_debug_assert(tcg_code_gen_epilogue != NULL);
1484
tcg_region_prologue_set(s);
1487
void tcg_func_start(TCGContext *s)
1490
s->nb_temps = s->nb_globals;
1493
memset(s->free_temps, 0, sizeof(s->free_temps));
1496
for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
1497
if (s->const_table[i]) {
1498
g_hash_table_remove_all(s->const_table[i]);
1504
s->current_frame_offset = s->frame_start;
1506
#ifdef CONFIG_DEBUG_TCG
1507
s->goto_tb_issue_mask = 0;
1510
QTAILQ_INIT(&s->ops);
1511
QTAILQ_INIT(&s->free_ops);
1512
s->emit_before_op = NULL;
1513
QSIMPLEQ_INIT(&s->labels);
1515
tcg_debug_assert(s->addr_type == TCG_TYPE_I32 ||
1516
s->addr_type == TCG_TYPE_I64);
1518
tcg_debug_assert(s->insn_start_words > 0);
1521
static TCGTemp *tcg_temp_alloc(TCGContext *s)
1523
int n = s->nb_temps++;
1525
if (n >= TCG_MAX_TEMPS) {
1526
tcg_raise_tb_overflow(s);
1528
return memset(&s->temps[n], 0, sizeof(TCGTemp));
1531
static TCGTemp *tcg_global_alloc(TCGContext *s)
1535
tcg_debug_assert(s->nb_globals == s->nb_temps);
1536
tcg_debug_assert(s->nb_globals < TCG_MAX_TEMPS);
1538
ts = tcg_temp_alloc(s);
1539
ts->kind = TEMP_GLOBAL;
1544
static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
1545
TCGReg reg, const char *name)
1549
tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
1551
ts = tcg_global_alloc(s);
1552
ts->base_type = type;
1554
ts->kind = TEMP_FIXED;
1557
tcg_regset_set_reg(s->reserved_regs, reg);
1562
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
1564
s->frame_start = start;
1565
s->frame_end = start + size;
1567
= tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
1570
static TCGTemp *tcg_global_mem_new_internal(TCGv_ptr base, intptr_t offset,
1571
const char *name, TCGType type)
1573
TCGContext *s = tcg_ctx;
1574
TCGTemp *base_ts = tcgv_ptr_temp(base);
1575
TCGTemp *ts = tcg_global_alloc(s);
1576
int indirect_reg = 0;
1578
switch (base_ts->kind) {
1583
tcg_debug_assert(!base_ts->indirect_reg);
1584
base_ts->indirect_base = 1;
1585
s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
1590
g_assert_not_reached();
1593
if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1594
TCGTemp *ts2 = tcg_global_alloc(s);
1597
ts->base_type = TCG_TYPE_I64;
1598
ts->type = TCG_TYPE_I32;
1599
ts->indirect_reg = indirect_reg;
1600
ts->mem_allocated = 1;
1601
ts->mem_base = base_ts;
1602
ts->mem_offset = offset;
1603
pstrcpy(buf, sizeof(buf), name);
1604
pstrcat(buf, sizeof(buf), "_0");
1605
ts->name = strdup(buf);
1607
tcg_debug_assert(ts2 == ts + 1);
1608
ts2->base_type = TCG_TYPE_I64;
1609
ts2->type = TCG_TYPE_I32;
1610
ts2->indirect_reg = indirect_reg;
1611
ts2->mem_allocated = 1;
1612
ts2->mem_base = base_ts;
1613
ts2->mem_offset = offset + 4;
1614
ts2->temp_subindex = 1;
1615
pstrcpy(buf, sizeof(buf), name);
1616
pstrcat(buf, sizeof(buf), "_1");
1617
ts2->name = strdup(buf);
1619
ts->base_type = type;
1621
ts->indirect_reg = indirect_reg;
1622
ts->mem_allocated = 1;
1623
ts->mem_base = base_ts;
1624
ts->mem_offset = offset;
1630
TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t off, const char *name)
1632
TCGTemp *ts = tcg_global_mem_new_internal(reg, off, name, TCG_TYPE_I32);
1633
return temp_tcgv_i32(ts);
1636
TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t off, const char *name)
1638
TCGTemp *ts = tcg_global_mem_new_internal(reg, off, name, TCG_TYPE_I64);
1639
return temp_tcgv_i64(ts);
1642
TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t off, const char *name)
1644
TCGTemp *ts = tcg_global_mem_new_internal(reg, off, name, TCG_TYPE_PTR);
1645
return temp_tcgv_ptr(ts);
1648
TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
1650
TCGContext *s = tcg_ctx;
1654
if (kind == TEMP_EBB) {
1655
int idx = find_first_bit(s->free_temps[type].l, TCG_MAX_TEMPS);
1657
if (idx < TCG_MAX_TEMPS) {
1659
clear_bit(idx, s->free_temps[type].l);
1661
ts = &s->temps[idx];
1662
ts->temp_allocated = 1;
1663
tcg_debug_assert(ts->base_type == type);
1664
tcg_debug_assert(ts->kind == kind);
1668
tcg_debug_assert(kind == TEMP_TB);
1679
n = 64 / TCG_TARGET_REG_BITS;
1682
n = 128 / TCG_TARGET_REG_BITS;
1685
g_assert_not_reached();
1688
ts = tcg_temp_alloc(s);
1689
ts->base_type = type;
1690
ts->temp_allocated = 1;
1696
ts->type = TCG_TYPE_REG;
1698
for (int i = 1; i < n; ++i) {
1699
TCGTemp *ts2 = tcg_temp_alloc(s);
1701
tcg_debug_assert(ts2 == ts + i);
1702
ts2->base_type = type;
1703
ts2->type = TCG_TYPE_REG;
1704
ts2->temp_allocated = 1;
1705
ts2->temp_subindex = i;
1712
TCGv_i32 tcg_temp_new_i32(void)
1714
return temp_tcgv_i32(tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB));
1717
TCGv_i32 tcg_temp_ebb_new_i32(void)
1719
return temp_tcgv_i32(tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB));
1722
TCGv_i64 tcg_temp_new_i64(void)
1724
return temp_tcgv_i64(tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB));
1727
TCGv_i64 tcg_temp_ebb_new_i64(void)
1729
return temp_tcgv_i64(tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB));
1732
TCGv_ptr tcg_temp_new_ptr(void)
1734
return temp_tcgv_ptr(tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB));
1737
TCGv_ptr tcg_temp_ebb_new_ptr(void)
1739
return temp_tcgv_ptr(tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB));
1742
TCGv_i128 tcg_temp_new_i128(void)
1744
return temp_tcgv_i128(tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB));
1747
TCGv_i128 tcg_temp_ebb_new_i128(void)
1749
return temp_tcgv_i128(tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB));
1752
TCGv_vec tcg_temp_new_vec(TCGType type)
1756
#ifdef CONFIG_DEBUG_TCG
1759
assert(TCG_TARGET_HAS_v64);
1762
assert(TCG_TARGET_HAS_v128);
1765
assert(TCG_TARGET_HAS_v256);
1768
g_assert_not_reached();
1772
t = tcg_temp_new_internal(type, TEMP_EBB);
1773
return temp_tcgv_vec(t);
1777
TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
1779
TCGTemp *t = tcgv_vec_temp(match);
1781
tcg_debug_assert(t->temp_allocated != 0);
1783
t = tcg_temp_new_internal(t->base_type, TEMP_EBB);
1784
return temp_tcgv_vec(t);
1787
void tcg_temp_free_internal(TCGTemp *ts)
1789
TCGContext *s = tcg_ctx;
1797
tcg_debug_assert(ts->temp_allocated != 0);
1798
ts->temp_allocated = 0;
1799
set_bit(temp_idx(ts), s->free_temps[ts->base_type].l);
1803
g_assert_not_reached();
1807
void tcg_temp_free_i32(TCGv_i32 arg)
1809
tcg_temp_free_internal(tcgv_i32_temp(arg));
1812
void tcg_temp_free_i64(TCGv_i64 arg)
1814
tcg_temp_free_internal(tcgv_i64_temp(arg));
1817
void tcg_temp_free_i128(TCGv_i128 arg)
1819
tcg_temp_free_internal(tcgv_i128_temp(arg));
1822
void tcg_temp_free_ptr(TCGv_ptr arg)
1824
tcg_temp_free_internal(tcgv_ptr_temp(arg));
1827
void tcg_temp_free_vec(TCGv_vec arg)
1829
tcg_temp_free_internal(tcgv_vec_temp(arg));
1832
TCGTemp *tcg_constant_internal(TCGType type, int64_t val)
1834
TCGContext *s = tcg_ctx;
1835
GHashTable *h = s->const_table[type];
1839
h = g_hash_table_new(g_int64_hash, g_int64_equal);
1840
s->const_table[type] = h;
1843
ts = g_hash_table_lookup(h, &val);
1847
ts = tcg_temp_alloc(s);
1849
if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1850
TCGTemp *ts2 = tcg_temp_alloc(s);
1852
tcg_debug_assert(ts2 == ts + 1);
1854
ts->base_type = TCG_TYPE_I64;
1855
ts->type = TCG_TYPE_I32;
1856
ts->kind = TEMP_CONST;
1857
ts->temp_allocated = 1;
1859
ts2->base_type = TCG_TYPE_I64;
1860
ts2->type = TCG_TYPE_I32;
1861
ts2->kind = TEMP_CONST;
1862
ts2->temp_allocated = 1;
1863
ts2->temp_subindex = 1;
1870
ts[HOST_BIG_ENDIAN].val = val;
1871
ts[!HOST_BIG_ENDIAN].val = val >> 32;
1872
val_ptr = &ts[HOST_BIG_ENDIAN].val;
1874
ts->base_type = type;
1876
ts->kind = TEMP_CONST;
1877
ts->temp_allocated = 1;
1881
g_hash_table_insert(h, val_ptr, ts);
1887
TCGv_i32 tcg_constant_i32(int32_t val)
1889
return temp_tcgv_i32(tcg_constant_internal(TCG_TYPE_I32, val));
1892
TCGv_i64 tcg_constant_i64(int64_t val)
1894
return temp_tcgv_i64(tcg_constant_internal(TCG_TYPE_I64, val));
1897
TCGv_ptr tcg_constant_ptr_int(intptr_t val)
1899
return temp_tcgv_ptr(tcg_constant_internal(TCG_TYPE_PTR, val));
1902
TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val)
1904
val = dup_const(vece, val);
1905
return temp_tcgv_vec(tcg_constant_internal(type, val));
1908
TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val)
1910
TCGTemp *t = tcgv_vec_temp(match);
1912
tcg_debug_assert(t->temp_allocated != 0);
1913
return tcg_constant_vec(t->base_type, vece, val);
1916
#ifdef CONFIG_DEBUG_TCG
1917
size_t temp_idx(TCGTemp *ts)
1919
ptrdiff_t n = ts - tcg_ctx->temps;
1920
assert(n >= 0 && n < tcg_ctx->nb_temps);
1924
TCGTemp *tcgv_i32_temp(TCGv_i32 v)
1926
uintptr_t o = (uintptr_t)v - offsetof(TCGContext, temps);
1928
assert(o < sizeof(TCGTemp) * tcg_ctx->nb_temps);
1929
assert(o % sizeof(TCGTemp) == 0);
1931
return (void *)tcg_ctx + (uintptr_t)v;
1937
bool tcg_op_supported(TCGOpcode op)
1940
= TCG_TARGET_HAS_v64 | TCG_TARGET_HAS_v128 | TCG_TARGET_HAS_v256;
1943
case INDEX_op_discard:
1944
case INDEX_op_set_label:
1948
case INDEX_op_insn_start:
1949
case INDEX_op_exit_tb:
1950
case INDEX_op_goto_tb:
1951
case INDEX_op_goto_ptr:
1952
case INDEX_op_qemu_ld_a32_i32:
1953
case INDEX_op_qemu_ld_a64_i32:
1954
case INDEX_op_qemu_st_a32_i32:
1955
case INDEX_op_qemu_st_a64_i32:
1956
case INDEX_op_qemu_ld_a32_i64:
1957
case INDEX_op_qemu_ld_a64_i64:
1958
case INDEX_op_qemu_st_a32_i64:
1959
case INDEX_op_qemu_st_a64_i64:
1962
case INDEX_op_qemu_st8_a32_i32:
1963
case INDEX_op_qemu_st8_a64_i32:
1964
return TCG_TARGET_HAS_qemu_st8_i32;
1966
case INDEX_op_qemu_ld_a32_i128:
1967
case INDEX_op_qemu_ld_a64_i128:
1968
case INDEX_op_qemu_st_a32_i128:
1969
case INDEX_op_qemu_st_a64_i128:
1970
return TCG_TARGET_HAS_qemu_ldst_i128;
1972
case INDEX_op_mov_i32:
1973
case INDEX_op_setcond_i32:
1974
case INDEX_op_brcond_i32:
1975
case INDEX_op_movcond_i32:
1976
case INDEX_op_ld8u_i32:
1977
case INDEX_op_ld8s_i32:
1978
case INDEX_op_ld16u_i32:
1979
case INDEX_op_ld16s_i32:
1980
case INDEX_op_ld_i32:
1981
case INDEX_op_st8_i32:
1982
case INDEX_op_st16_i32:
1983
case INDEX_op_st_i32:
1984
case INDEX_op_add_i32:
1985
case INDEX_op_sub_i32:
1986
case INDEX_op_neg_i32:
1987
case INDEX_op_mul_i32:
1988
case INDEX_op_and_i32:
1989
case INDEX_op_or_i32:
1990
case INDEX_op_xor_i32:
1991
case INDEX_op_shl_i32:
1992
case INDEX_op_shr_i32:
1993
case INDEX_op_sar_i32:
1996
case INDEX_op_negsetcond_i32:
1997
return TCG_TARGET_HAS_negsetcond_i32;
1998
case INDEX_op_div_i32:
1999
case INDEX_op_divu_i32:
2000
return TCG_TARGET_HAS_div_i32;
2001
case INDEX_op_rem_i32:
2002
case INDEX_op_remu_i32:
2003
return TCG_TARGET_HAS_rem_i32;
2004
case INDEX_op_div2_i32:
2005
case INDEX_op_divu2_i32:
2006
return TCG_TARGET_HAS_div2_i32;
2007
case INDEX_op_rotl_i32:
2008
case INDEX_op_rotr_i32:
2009
return TCG_TARGET_HAS_rot_i32;
2010
case INDEX_op_deposit_i32:
2011
return TCG_TARGET_HAS_deposit_i32;
2012
case INDEX_op_extract_i32:
2013
return TCG_TARGET_HAS_extract_i32;
2014
case INDEX_op_sextract_i32:
2015
return TCG_TARGET_HAS_sextract_i32;
2016
case INDEX_op_extract2_i32:
2017
return TCG_TARGET_HAS_extract2_i32;
2018
case INDEX_op_add2_i32:
2019
return TCG_TARGET_HAS_add2_i32;
2020
case INDEX_op_sub2_i32:
2021
return TCG_TARGET_HAS_sub2_i32;
2022
case INDEX_op_mulu2_i32:
2023
return TCG_TARGET_HAS_mulu2_i32;
2024
case INDEX_op_muls2_i32:
2025
return TCG_TARGET_HAS_muls2_i32;
2026
case INDEX_op_muluh_i32:
2027
return TCG_TARGET_HAS_muluh_i32;
2028
case INDEX_op_mulsh_i32:
2029
return TCG_TARGET_HAS_mulsh_i32;
2030
case INDEX_op_ext8s_i32:
2031
return TCG_TARGET_HAS_ext8s_i32;
2032
case INDEX_op_ext16s_i32:
2033
return TCG_TARGET_HAS_ext16s_i32;
2034
case INDEX_op_ext8u_i32:
2035
return TCG_TARGET_HAS_ext8u_i32;
2036
case INDEX_op_ext16u_i32:
2037
return TCG_TARGET_HAS_ext16u_i32;
2038
case INDEX_op_bswap16_i32:
2039
return TCG_TARGET_HAS_bswap16_i32;
2040
case INDEX_op_bswap32_i32:
2041
return TCG_TARGET_HAS_bswap32_i32;
2042
case INDEX_op_not_i32:
2043
return TCG_TARGET_HAS_not_i32;
2044
case INDEX_op_andc_i32:
2045
return TCG_TARGET_HAS_andc_i32;
2046
case INDEX_op_orc_i32:
2047
return TCG_TARGET_HAS_orc_i32;
2048
case INDEX_op_eqv_i32:
2049
return TCG_TARGET_HAS_eqv_i32;
2050
case INDEX_op_nand_i32:
2051
return TCG_TARGET_HAS_nand_i32;
2052
case INDEX_op_nor_i32:
2053
return TCG_TARGET_HAS_nor_i32;
2054
case INDEX_op_clz_i32:
2055
return TCG_TARGET_HAS_clz_i32;
2056
case INDEX_op_ctz_i32:
2057
return TCG_TARGET_HAS_ctz_i32;
2058
case INDEX_op_ctpop_i32:
2059
return TCG_TARGET_HAS_ctpop_i32;
2061
case INDEX_op_brcond2_i32:
2062
case INDEX_op_setcond2_i32:
2063
return TCG_TARGET_REG_BITS == 32;
2065
case INDEX_op_mov_i64:
2066
case INDEX_op_setcond_i64:
2067
case INDEX_op_brcond_i64:
2068
case INDEX_op_movcond_i64:
2069
case INDEX_op_ld8u_i64:
2070
case INDEX_op_ld8s_i64:
2071
case INDEX_op_ld16u_i64:
2072
case INDEX_op_ld16s_i64:
2073
case INDEX_op_ld32u_i64:
2074
case INDEX_op_ld32s_i64:
2075
case INDEX_op_ld_i64:
2076
case INDEX_op_st8_i64:
2077
case INDEX_op_st16_i64:
2078
case INDEX_op_st32_i64:
2079
case INDEX_op_st_i64:
2080
case INDEX_op_add_i64:
2081
case INDEX_op_sub_i64:
2082
case INDEX_op_neg_i64:
2083
case INDEX_op_mul_i64:
2084
case INDEX_op_and_i64:
2085
case INDEX_op_or_i64:
2086
case INDEX_op_xor_i64:
2087
case INDEX_op_shl_i64:
2088
case INDEX_op_shr_i64:
2089
case INDEX_op_sar_i64:
2090
case INDEX_op_ext_i32_i64:
2091
case INDEX_op_extu_i32_i64:
2092
return TCG_TARGET_REG_BITS == 64;
2094
case INDEX_op_negsetcond_i64:
2095
return TCG_TARGET_HAS_negsetcond_i64;
2096
case INDEX_op_div_i64:
2097
case INDEX_op_divu_i64:
2098
return TCG_TARGET_HAS_div_i64;
2099
case INDEX_op_rem_i64:
2100
case INDEX_op_remu_i64:
2101
return TCG_TARGET_HAS_rem_i64;
2102
case INDEX_op_div2_i64:
2103
case INDEX_op_divu2_i64:
2104
return TCG_TARGET_HAS_div2_i64;
2105
case INDEX_op_rotl_i64:
2106
case INDEX_op_rotr_i64:
2107
return TCG_TARGET_HAS_rot_i64;
2108
case INDEX_op_deposit_i64:
2109
return TCG_TARGET_HAS_deposit_i64;
2110
case INDEX_op_extract_i64:
2111
return TCG_TARGET_HAS_extract_i64;
2112
case INDEX_op_sextract_i64:
2113
return TCG_TARGET_HAS_sextract_i64;
2114
case INDEX_op_extract2_i64:
2115
return TCG_TARGET_HAS_extract2_i64;
2116
case INDEX_op_extrl_i64_i32:
2117
case INDEX_op_extrh_i64_i32:
2118
return TCG_TARGET_HAS_extr_i64_i32;
2119
case INDEX_op_ext8s_i64:
2120
return TCG_TARGET_HAS_ext8s_i64;
2121
case INDEX_op_ext16s_i64:
2122
return TCG_TARGET_HAS_ext16s_i64;
2123
case INDEX_op_ext32s_i64:
2124
return TCG_TARGET_HAS_ext32s_i64;
2125
case INDEX_op_ext8u_i64:
2126
return TCG_TARGET_HAS_ext8u_i64;
2127
case INDEX_op_ext16u_i64:
2128
return TCG_TARGET_HAS_ext16u_i64;
2129
case INDEX_op_ext32u_i64:
2130
return TCG_TARGET_HAS_ext32u_i64;
2131
case INDEX_op_bswap16_i64:
2132
return TCG_TARGET_HAS_bswap16_i64;
2133
case INDEX_op_bswap32_i64:
2134
return TCG_TARGET_HAS_bswap32_i64;
2135
case INDEX_op_bswap64_i64:
2136
return TCG_TARGET_HAS_bswap64_i64;
2137
case INDEX_op_not_i64:
2138
return TCG_TARGET_HAS_not_i64;
2139
case INDEX_op_andc_i64:
2140
return TCG_TARGET_HAS_andc_i64;
2141
case INDEX_op_orc_i64:
2142
return TCG_TARGET_HAS_orc_i64;
2143
case INDEX_op_eqv_i64:
2144
return TCG_TARGET_HAS_eqv_i64;
2145
case INDEX_op_nand_i64:
2146
return TCG_TARGET_HAS_nand_i64;
2147
case INDEX_op_nor_i64:
2148
return TCG_TARGET_HAS_nor_i64;
2149
case INDEX_op_clz_i64:
2150
return TCG_TARGET_HAS_clz_i64;
2151
case INDEX_op_ctz_i64:
2152
return TCG_TARGET_HAS_ctz_i64;
2153
case INDEX_op_ctpop_i64:
2154
return TCG_TARGET_HAS_ctpop_i64;
2155
case INDEX_op_add2_i64:
2156
return TCG_TARGET_HAS_add2_i64;
2157
case INDEX_op_sub2_i64:
2158
return TCG_TARGET_HAS_sub2_i64;
2159
case INDEX_op_mulu2_i64:
2160
return TCG_TARGET_HAS_mulu2_i64;
2161
case INDEX_op_muls2_i64:
2162
return TCG_TARGET_HAS_muls2_i64;
2163
case INDEX_op_muluh_i64:
2164
return TCG_TARGET_HAS_muluh_i64;
2165
case INDEX_op_mulsh_i64:
2166
return TCG_TARGET_HAS_mulsh_i64;
2168
case INDEX_op_mov_vec:
2169
case INDEX_op_dup_vec:
2170
case INDEX_op_dupm_vec:
2171
case INDEX_op_ld_vec:
2172
case INDEX_op_st_vec:
2173
case INDEX_op_add_vec:
2174
case INDEX_op_sub_vec:
2175
case INDEX_op_and_vec:
2176
case INDEX_op_or_vec:
2177
case INDEX_op_xor_vec:
2178
case INDEX_op_cmp_vec:
2180
case INDEX_op_dup2_vec:
2181
return have_vec && TCG_TARGET_REG_BITS == 32;
2182
case INDEX_op_not_vec:
2183
return have_vec && TCG_TARGET_HAS_not_vec;
2184
case INDEX_op_neg_vec:
2185
return have_vec && TCG_TARGET_HAS_neg_vec;
2186
case INDEX_op_abs_vec:
2187
return have_vec && TCG_TARGET_HAS_abs_vec;
2188
case INDEX_op_andc_vec:
2189
return have_vec && TCG_TARGET_HAS_andc_vec;
2190
case INDEX_op_orc_vec:
2191
return have_vec && TCG_TARGET_HAS_orc_vec;
2192
case INDEX_op_nand_vec:
2193
return have_vec && TCG_TARGET_HAS_nand_vec;
2194
case INDEX_op_nor_vec:
2195
return have_vec && TCG_TARGET_HAS_nor_vec;
2196
case INDEX_op_eqv_vec:
2197
return have_vec && TCG_TARGET_HAS_eqv_vec;
2198
case INDEX_op_mul_vec:
2199
return have_vec && TCG_TARGET_HAS_mul_vec;
2200
case INDEX_op_shli_vec:
2201
case INDEX_op_shri_vec:
2202
case INDEX_op_sari_vec:
2203
return have_vec && TCG_TARGET_HAS_shi_vec;
2204
case INDEX_op_shls_vec:
2205
case INDEX_op_shrs_vec:
2206
case INDEX_op_sars_vec:
2207
return have_vec && TCG_TARGET_HAS_shs_vec;
2208
case INDEX_op_shlv_vec:
2209
case INDEX_op_shrv_vec:
2210
case INDEX_op_sarv_vec:
2211
return have_vec && TCG_TARGET_HAS_shv_vec;
2212
case INDEX_op_rotli_vec:
2213
return have_vec && TCG_TARGET_HAS_roti_vec;
2214
case INDEX_op_rotls_vec:
2215
return have_vec && TCG_TARGET_HAS_rots_vec;
2216
case INDEX_op_rotlv_vec:
2217
case INDEX_op_rotrv_vec:
2218
return have_vec && TCG_TARGET_HAS_rotv_vec;
2219
case INDEX_op_ssadd_vec:
2220
case INDEX_op_usadd_vec:
2221
case INDEX_op_sssub_vec:
2222
case INDEX_op_ussub_vec:
2223
return have_vec && TCG_TARGET_HAS_sat_vec;
2224
case INDEX_op_smin_vec:
2225
case INDEX_op_umin_vec:
2226
case INDEX_op_smax_vec:
2227
case INDEX_op_umax_vec:
2228
return have_vec && TCG_TARGET_HAS_minmax_vec;
2229
case INDEX_op_bitsel_vec:
2230
return have_vec && TCG_TARGET_HAS_bitsel_vec;
2231
case INDEX_op_cmpsel_vec:
2232
return have_vec && TCG_TARGET_HAS_cmpsel_vec;
2235
tcg_debug_assert(op > INDEX_op_last_generic && op < NB_OPS);
2240
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs);
2242
static void tcg_gen_callN(void *func, TCGHelperInfo *info,
2243
TCGTemp *ret, TCGTemp **args)
2245
TCGv_i64 extend_free[MAX_CALL_IARGS];
2248
int i, n, pi = 0, total_args;
2250
if (unlikely(g_once_init_enter(HELPER_INFO_INIT(info)))) {
2251
init_call_layout(info);
2252
g_once_init_leave(HELPER_INFO_INIT(info), HELPER_INFO_INIT_VAL(info));
2255
total_args = info->nr_out + info->nr_in + 2;
2256
op = tcg_op_alloc(INDEX_op_call, total_args);
2260
if (tcg_ctx->plugin_insn && !(info->flags & TCG_CALL_NO_SIDE_EFFECTS)) {
2261
tcg_ctx->plugin_insn->calls_helpers = true;
2265
TCGOP_CALLO(op) = n = info->nr_out;
2268
tcg_debug_assert(ret == NULL);
2271
tcg_debug_assert(ret != NULL);
2272
op->args[pi++] = temp_arg(ret);
2276
tcg_debug_assert(ret != NULL);
2277
tcg_debug_assert(ret->base_type == ret->type + ctz32(n));
2278
tcg_debug_assert(ret->temp_subindex == 0);
2279
for (i = 0; i < n; ++i) {
2280
op->args[pi++] = temp_arg(ret + i);
2284
g_assert_not_reached();
2287
TCGOP_CALLI(op) = n = info->nr_in;
2288
for (i = 0; i < n; i++) {
2289
const TCGCallArgumentLoc *loc = &info->in[i];
2290
TCGTemp *ts = args[loc->arg_idx] + loc->tmp_subindex;
2292
switch (loc->kind) {
2293
case TCG_CALL_ARG_NORMAL:
2294
case TCG_CALL_ARG_BY_REF:
2295
case TCG_CALL_ARG_BY_REF_N:
2296
op->args[pi++] = temp_arg(ts);
2299
case TCG_CALL_ARG_EXTEND_U:
2300
case TCG_CALL_ARG_EXTEND_S:
2302
TCGv_i64 temp = tcg_temp_ebb_new_i64();
2303
TCGv_i32 orig = temp_tcgv_i32(ts);
2305
if (loc->kind == TCG_CALL_ARG_EXTEND_S) {
2306
tcg_gen_ext_i32_i64(temp, orig);
2308
tcg_gen_extu_i32_i64(temp, orig);
2310
op->args[pi++] = tcgv_i64_arg(temp);
2311
extend_free[n_extend++] = temp;
2316
g_assert_not_reached();
2319
op->args[pi++] = (uintptr_t)func;
2320
op->args[pi++] = (uintptr_t)info;
2321
tcg_debug_assert(pi == total_args);
2323
if (tcg_ctx->emit_before_op) {
2324
QTAILQ_INSERT_BEFORE(tcg_ctx->emit_before_op, op, link);
2326
QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
2329
tcg_debug_assert(n_extend < ARRAY_SIZE(extend_free));
2330
for (i = 0; i < n_extend; ++i) {
2331
tcg_temp_free_i64(extend_free[i]);
2335
void tcg_gen_call0(void *func, TCGHelperInfo *info, TCGTemp *ret)
2337
tcg_gen_callN(func, info, ret, NULL);
2340
void tcg_gen_call1(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1)
2342
tcg_gen_callN(func, info, ret, &t1);
2345
void tcg_gen_call2(void *func, TCGHelperInfo *info, TCGTemp *ret,
2346
TCGTemp *t1, TCGTemp *t2)
2348
TCGTemp *args[2] = { t1, t2 };
2349
tcg_gen_callN(func, info, ret, args);
2352
void tcg_gen_call3(void *func, TCGHelperInfo *info, TCGTemp *ret,
2353
TCGTemp *t1, TCGTemp *t2, TCGTemp *t3)
2355
TCGTemp *args[3] = { t1, t2, t3 };
2356
tcg_gen_callN(func, info, ret, args);
2359
void tcg_gen_call4(void *func, TCGHelperInfo *info, TCGTemp *ret,
2360
TCGTemp *t1, TCGTemp *t2, TCGTemp *t3, TCGTemp *t4)
2362
TCGTemp *args[4] = { t1, t2, t3, t4 };
2363
tcg_gen_callN(func, info, ret, args);
2366
void tcg_gen_call5(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
2367
TCGTemp *t2, TCGTemp *t3, TCGTemp *t4, TCGTemp *t5)
2369
TCGTemp *args[5] = { t1, t2, t3, t4, t5 };
2370
tcg_gen_callN(func, info, ret, args);
2373
void tcg_gen_call6(void *func, TCGHelperInfo *info, TCGTemp *ret,
2374
TCGTemp *t1, TCGTemp *t2, TCGTemp *t3,
2375
TCGTemp *t4, TCGTemp *t5, TCGTemp *t6)
2377
TCGTemp *args[6] = { t1, t2, t3, t4, t5, t6 };
2378
tcg_gen_callN(func, info, ret, args);
2381
void tcg_gen_call7(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
2382
TCGTemp *t2, TCGTemp *t3, TCGTemp *t4,
2383
TCGTemp *t5, TCGTemp *t6, TCGTemp *t7)
2385
TCGTemp *args[7] = { t1, t2, t3, t4, t5, t6, t7 };
2386
tcg_gen_callN(func, info, ret, args);
2389
static void tcg_reg_alloc_start(TCGContext *s)
2393
for (i = 0, n = s->nb_temps; i < n; i++) {
2394
TCGTemp *ts = &s->temps[i];
2395
TCGTempVal val = TEMP_VAL_MEM;
2399
val = TEMP_VAL_CONST;
2407
val = TEMP_VAL_DEAD;
2410
ts->mem_allocated = 0;
2413
g_assert_not_reached();
2418
memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
2421
static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
2424
int idx = temp_idx(ts);
2429
pstrcpy(buf, buf_size, ts->name);
2432
snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
2435
snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
2440
snprintf(buf, buf_size, "$0x%x", (int32_t)ts->val);
2442
#if TCG_TARGET_REG_BITS > 32
2444
snprintf(buf, buf_size, "$0x%" PRIx64, ts->val);
2450
snprintf(buf, buf_size, "v%d$0x%" PRIx64,
2451
64 << (ts->type - TCG_TYPE_V64), ts->val);
2454
g_assert_not_reached();
2461
static char *tcg_get_arg_str(TCGContext *s, char *buf,
2462
int buf_size, TCGArg arg)
2464
return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
2467
static const char * const cond_name[] =
2469
[TCG_COND_NEVER] = "never",
2470
[TCG_COND_ALWAYS] = "always",
2471
[TCG_COND_EQ] = "eq",
2472
[TCG_COND_NE] = "ne",
2473
[TCG_COND_LT] = "lt",
2474
[TCG_COND_GE] = "ge",
2475
[TCG_COND_LE] = "le",
2476
[TCG_COND_GT] = "gt",
2477
[TCG_COND_LTU] = "ltu",
2478
[TCG_COND_GEU] = "geu",
2479
[TCG_COND_LEU] = "leu",
2480
[TCG_COND_GTU] = "gtu",
2481
[TCG_COND_TSTEQ] = "tsteq",
2482
[TCG_COND_TSTNE] = "tstne",
2485
static const char * const ldst_name[(MO_BSWAP | MO_SSIZE) + 1] =
2499
[MO_128 + MO_BE] = "beo",
2500
[MO_128 + MO_LE] = "leo",
2503
static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
2504
[MO_UNALN >> MO_ASHIFT] = "un+",
2505
[MO_ALIGN >> MO_ASHIFT] = "al+",
2506
[MO_ALIGN_2 >> MO_ASHIFT] = "al2+",
2507
[MO_ALIGN_4 >> MO_ASHIFT] = "al4+",
2508
[MO_ALIGN_8 >> MO_ASHIFT] = "al8+",
2509
[MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
2510
[MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
2511
[MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
2514
static const char * const atom_name[(MO_ATOM_MASK >> MO_ATOM_SHIFT) + 1] = {
2515
[MO_ATOM_IFALIGN >> MO_ATOM_SHIFT] = "",
2516
[MO_ATOM_IFALIGN_PAIR >> MO_ATOM_SHIFT] = "pair+",
2517
[MO_ATOM_WITHIN16 >> MO_ATOM_SHIFT] = "w16+",
2518
[MO_ATOM_WITHIN16_PAIR >> MO_ATOM_SHIFT] = "w16p+",
2519
[MO_ATOM_SUBALIGN >> MO_ATOM_SHIFT] = "sub+",
2520
[MO_ATOM_NONE >> MO_ATOM_SHIFT] = "noat+",
2523
static const char bswap_flag_name[][6] = {
2524
[TCG_BSWAP_IZ] = "iz",
2525
[TCG_BSWAP_OZ] = "oz",
2526
[TCG_BSWAP_OS] = "os",
2527
[TCG_BSWAP_IZ | TCG_BSWAP_OZ] = "iz,oz",
2528
[TCG_BSWAP_IZ | TCG_BSWAP_OS] = "iz,os",
2532
static const char * const plugin_from_name[] = {
2540
static inline bool tcg_regset_single(TCGRegSet d)
2542
return (d & (d - 1)) == 0;
2545
static inline TCGReg tcg_regset_first(TCGRegSet d)
2547
if (TCG_TARGET_NB_REGS <= 32) {
2555
#define ne_fprintf(...) \
2556
({ int ret_ = fprintf(__VA_ARGS__); ret_ >= 0 ? ret_ : 0; })
2558
void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
2563
QTAILQ_FOREACH(op, &s->ops, link) {
2564
int i, k, nb_oargs, nb_iargs, nb_cargs;
2565
const TCGOpDef *def;
2570
def = &tcg_op_defs[c];
2572
if (c == INDEX_op_insn_start) {
2574
col += ne_fprintf(f, "\n ----");
2576
for (i = 0, k = s->insn_start_words; i < k; ++i) {
2577
col += ne_fprintf(f, " %016" PRIx64,
2578
tcg_get_insn_start_param(op, i));
2580
} else if (c == INDEX_op_call) {
2581
const TCGHelperInfo *info = tcg_call_info(op);
2582
void *func = tcg_call_func(op);
2585
nb_oargs = TCGOP_CALLO(op);
2586
nb_iargs = TCGOP_CALLI(op);
2587
nb_cargs = def->nb_cargs;
2589
col += ne_fprintf(f, " %s ", def->name);
2596
if (func == info->func) {
2597
col += ne_fprintf(f, "%s", info->name);
2599
col += ne_fprintf(f, "plugin(%p)", func);
2602
col += ne_fprintf(f, ",$0x%x,$%d", info->flags, nb_oargs);
2603
for (i = 0; i < nb_oargs; i++) {
2604
col += ne_fprintf(f, ",%s", tcg_get_arg_str(s, buf, sizeof(buf),
2607
for (i = 0; i < nb_iargs; i++) {
2608
TCGArg arg = op->args[nb_oargs + i];
2609
const char *t = tcg_get_arg_str(s, buf, sizeof(buf), arg);
2610
col += ne_fprintf(f, ",%s", t);
2613
col += ne_fprintf(f, " %s ", def->name);
2615
nb_oargs = def->nb_oargs;
2616
nb_iargs = def->nb_iargs;
2617
nb_cargs = def->nb_cargs;
2619
if (def->flags & TCG_OPF_VECTOR) {
2620
col += ne_fprintf(f, "v%d,e%d,", 64 << TCGOP_VECL(op),
2621
8 << TCGOP_VECE(op));
2625
for (i = 0; i < nb_oargs; i++) {
2626
const char *sep = k ? "," : "";
2627
col += ne_fprintf(f, "%s%s", sep,
2628
tcg_get_arg_str(s, buf, sizeof(buf),
2631
for (i = 0; i < nb_iargs; i++) {
2632
const char *sep = k ? "," : "";
2633
col += ne_fprintf(f, "%s%s", sep,
2634
tcg_get_arg_str(s, buf, sizeof(buf),
2638
case INDEX_op_brcond_i32:
2639
case INDEX_op_setcond_i32:
2640
case INDEX_op_negsetcond_i32:
2641
case INDEX_op_movcond_i32:
2642
case INDEX_op_brcond2_i32:
2643
case INDEX_op_setcond2_i32:
2644
case INDEX_op_brcond_i64:
2645
case INDEX_op_setcond_i64:
2646
case INDEX_op_negsetcond_i64:
2647
case INDEX_op_movcond_i64:
2648
case INDEX_op_cmp_vec:
2649
case INDEX_op_cmpsel_vec:
2650
if (op->args[k] < ARRAY_SIZE(cond_name)
2651
&& cond_name[op->args[k]]) {
2652
col += ne_fprintf(f, ",%s", cond_name[op->args[k++]]);
2654
col += ne_fprintf(f, ",$0x%" TCG_PRIlx, op->args[k++]);
2658
case INDEX_op_qemu_ld_a32_i32:
2659
case INDEX_op_qemu_ld_a64_i32:
2660
case INDEX_op_qemu_st_a32_i32:
2661
case INDEX_op_qemu_st_a64_i32:
2662
case INDEX_op_qemu_st8_a32_i32:
2663
case INDEX_op_qemu_st8_a64_i32:
2664
case INDEX_op_qemu_ld_a32_i64:
2665
case INDEX_op_qemu_ld_a64_i64:
2666
case INDEX_op_qemu_st_a32_i64:
2667
case INDEX_op_qemu_st_a64_i64:
2668
case INDEX_op_qemu_ld_a32_i128:
2669
case INDEX_op_qemu_ld_a64_i128:
2670
case INDEX_op_qemu_st_a32_i128:
2671
case INDEX_op_qemu_st_a64_i128:
2673
const char *s_al, *s_op, *s_at;
2674
MemOpIdx oi = op->args[k++];
2675
MemOp mop = get_memop(oi);
2676
unsigned ix = get_mmuidx(oi);
2678
s_al = alignment_name[(mop & MO_AMASK) >> MO_ASHIFT];
2679
s_op = ldst_name[mop & (MO_BSWAP | MO_SSIZE)];
2680
s_at = atom_name[(mop & MO_ATOM_MASK) >> MO_ATOM_SHIFT];
2681
mop &= ~(MO_AMASK | MO_BSWAP | MO_SSIZE | MO_ATOM_MASK);
2684
if (!mop && s_al && s_op && s_at) {
2685
col += ne_fprintf(f, ",%s%s%s,%u",
2686
s_at, s_al, s_op, ix);
2688
mop = get_memop(oi);
2689
col += ne_fprintf(f, ",$0x%x,%u", mop, ix);
2694
case INDEX_op_bswap16_i32:
2695
case INDEX_op_bswap16_i64:
2696
case INDEX_op_bswap32_i32:
2697
case INDEX_op_bswap32_i64:
2698
case INDEX_op_bswap64_i64:
2700
TCGArg flags = op->args[k];
2701
const char *name = NULL;
2703
if (flags < ARRAY_SIZE(bswap_flag_name)) {
2704
name = bswap_flag_name[flags];
2707
col += ne_fprintf(f, ",%s", name);
2709
col += ne_fprintf(f, ",$0x%" TCG_PRIlx, flags);
2715
case INDEX_op_plugin_cb:
2717
TCGArg from = op->args[k++];
2718
const char *name = NULL;
2720
if (from < ARRAY_SIZE(plugin_from_name)) {
2721
name = plugin_from_name[from];
2724
col += ne_fprintf(f, "%s", name);
2726
col += ne_fprintf(f, "$0x%" TCG_PRIlx, from);
2737
case INDEX_op_set_label:
2739
case INDEX_op_brcond_i32:
2740
case INDEX_op_brcond_i64:
2741
case INDEX_op_brcond2_i32:
2742
col += ne_fprintf(f, "%s$L%d", k ? "," : "",
2743
arg_label(op->args[k])->id);
2748
TCGBar membar = op->args[k];
2749
const char *b_op, *m_op;
2751
switch (membar & TCG_BAR_SC) {
2765
g_assert_not_reached();
2768
switch (membar & TCG_MO_ALL) {
2784
case TCG_MO_LD_LD | TCG_MO_LD_ST:
2787
case TCG_MO_LD_LD | TCG_MO_ST_LD:
2790
case TCG_MO_LD_LD | TCG_MO_ST_ST:
2793
case TCG_MO_LD_ST | TCG_MO_ST_LD:
2796
case TCG_MO_LD_ST | TCG_MO_ST_ST:
2799
case TCG_MO_ST_LD | TCG_MO_ST_ST:
2802
case TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_LD:
2805
case TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST:
2808
case TCG_MO_LD_LD | TCG_MO_ST_LD | TCG_MO_ST_ST:
2811
case TCG_MO_LD_ST | TCG_MO_ST_LD | TCG_MO_ST_ST:
2818
g_assert_not_reached();
2821
col += ne_fprintf(f, "%s%s:%s", (k ? "," : ""), b_op, m_op);
2828
for (; i < nb_cargs; i++, k++) {
2829
col += ne_fprintf(f, "%s$0x%" TCG_PRIlx, k ? "," : "",
2834
if (have_prefs || op->life) {
2835
for (; col < 40; ++col) {
2841
unsigned life = op->life;
2843
if (life & (SYNC_ARG * 3)) {
2844
ne_fprintf(f, " sync:");
2845
for (i = 0; i < 2; ++i) {
2846
if (life & (SYNC_ARG << i)) {
2847
ne_fprintf(f, " %d", i);
2853
ne_fprintf(f, " dead:");
2854
for (i = 0; life; ++i, life >>= 1) {
2856
ne_fprintf(f, " %d", i);
2863
for (i = 0; i < nb_oargs; ++i) {
2864
TCGRegSet set = output_pref(op, i);
2867
ne_fprintf(f, " pref=");
2872
ne_fprintf(f, "none");
2873
} else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) {
2874
ne_fprintf(f, "all");
2875
#ifdef CONFIG_DEBUG_TCG
2876
} else if (tcg_regset_single(set)) {
2877
TCGReg reg = tcg_regset_first(set);
2878
ne_fprintf(f, "%s", tcg_target_reg_names[reg]);
2880
} else if (TCG_TARGET_NB_REGS <= 32) {
2881
ne_fprintf(f, "0x%x", (uint32_t)set);
2883
ne_fprintf(f, "0x%" PRIx64, (uint64_t)set);
2893
static int get_constraint_priority(const TCGOpDef *def, int k)
2895
const TCGArgConstraint *arg_ct = &def->args_ct[k];
2896
int n = ctpop64(arg_ct->regs);
2902
if (n == 1 || arg_ct->oalias) {
2911
switch (arg_ct->pair) {
2916
return (arg_ct->pair_index + 1) * 2 - 1;
2925
static void sort_constraints(TCGOpDef *def, int start, int n)
2928
TCGArgConstraint *a = def->args_ct;
2930
for (i = 0; i < n; i++) {
2931
a[start + i].sort_index = start + i;
2936
for (i = 0; i < n - 1; i++) {
2937
for (j = i + 1; j < n; j++) {
2938
int p1 = get_constraint_priority(def, a[start + i].sort_index);
2939
int p2 = get_constraint_priority(def, a[start + j].sort_index);
2941
int tmp = a[start + i].sort_index;
2942
a[start + i].sort_index = a[start + j].sort_index;
2943
a[start + j].sort_index = tmp;
2949
static void process_op_defs(TCGContext *s)
2953
for (op = 0; op < NB_OPS; op++) {
2954
TCGOpDef *def = &tcg_op_defs[op];
2955
const TCGTargetOpDef *tdefs;
2956
bool saw_alias_pair = false;
2957
int i, o, i2, o2, nb_args;
2959
if (def->flags & TCG_OPF_NOT_PRESENT) {
2963
nb_args = def->nb_iargs + def->nb_oargs;
2973
unsigned con_set = tcg_target_op_def(op);
2974
tcg_debug_assert(con_set < ARRAY_SIZE(constraint_sets));
2975
tdefs = &constraint_sets[con_set];
2977
for (i = 0; i < nb_args; i++) {
2978
const char *ct_str = tdefs->args_ct_str[i];
2979
bool input_p = i >= def->nb_oargs;
2982
tcg_debug_assert(ct_str != NULL);
2987
tcg_debug_assert(input_p);
2988
tcg_debug_assert(o < def->nb_oargs);
2989
tcg_debug_assert(def->args_ct[o].regs != 0);
2990
tcg_debug_assert(!def->args_ct[o].oalias);
2991
def->args_ct[i] = def->args_ct[o];
2993
def->args_ct[o].oalias = 1;
2994
def->args_ct[o].alias_index = i;
2996
def->args_ct[i].ialias = 1;
2997
def->args_ct[i].alias_index = o;
2998
if (def->args_ct[i].pair) {
2999
saw_alias_pair = true;
3001
tcg_debug_assert(ct_str[1] == '\0');
3005
tcg_debug_assert(!input_p);
3006
def->args_ct[i].newreg = true;
3012
tcg_debug_assert(i > (input_p ? def->nb_oargs : 0));
3014
tcg_debug_assert(!def->args_ct[o].pair);
3015
tcg_debug_assert(!def->args_ct[o].ct);
3016
def->args_ct[i] = (TCGArgConstraint){
3019
.regs = def->args_ct[o].regs << 1,
3020
.newreg = def->args_ct[o].newreg,
3022
def->args_ct[o].pair = 1;
3023
def->args_ct[o].pair_index = i;
3024
tcg_debug_assert(ct_str[1] == '\0');
3029
tcg_debug_assert(i > (input_p ? def->nb_oargs : 0));
3031
tcg_debug_assert(!def->args_ct[o].pair);
3032
tcg_debug_assert(!def->args_ct[o].ct);
3033
def->args_ct[i] = (TCGArgConstraint){
3036
.regs = def->args_ct[o].regs >> 1,
3037
.newreg = def->args_ct[o].newreg,
3039
def->args_ct[o].pair = 2;
3040
def->args_ct[o].pair_index = i;
3041
tcg_debug_assert(ct_str[1] == '\0');
3048
def->args_ct[i].ct |= TCG_CT_CONST;
3054
#define CONST(CASE, MASK) \
3055
case CASE: def->args_ct[i].ct |= MASK; break;
3056
#define REGS(CASE, MASK) \
3057
case CASE: def->args_ct[i].regs |= MASK; break;
3059
#include "tcg-target-con-str.h"
3069
g_assert_not_reached();
3071
} while (*++ct_str != '\0');
3075
tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
3096
if (saw_alias_pair) {
3097
for (i = def->nb_oargs; i < nb_args; i++) {
3103
if (!def->args_ct[i].ialias) {
3106
switch (def->args_ct[i].pair) {
3110
o = def->args_ct[i].alias_index;
3111
o2 = def->args_ct[o].pair_index;
3112
tcg_debug_assert(def->args_ct[o].pair == 1);
3113
tcg_debug_assert(def->args_ct[o2].pair == 2);
3114
if (def->args_ct[o2].oalias) {
3116
i2 = def->args_ct[o2].alias_index;
3117
tcg_debug_assert(def->args_ct[i2].pair == 2);
3118
def->args_ct[i2].pair_index = i;
3119
def->args_ct[i].pair_index = i2;
3122
def->args_ct[i].pair_index = i;
3126
o = def->args_ct[i].alias_index;
3127
o2 = def->args_ct[o].pair_index;
3128
tcg_debug_assert(def->args_ct[o].pair == 2);
3129
tcg_debug_assert(def->args_ct[o2].pair == 1);
3130
if (def->args_ct[o2].oalias) {
3132
i2 = def->args_ct[o2].alias_index;
3133
tcg_debug_assert(def->args_ct[i2].pair == 1);
3134
def->args_ct[i2].pair_index = i;
3135
def->args_ct[i].pair_index = i2;
3138
def->args_ct[i].pair = 3;
3139
def->args_ct[o2].pair = 3;
3140
def->args_ct[i].pair_index = o2;
3141
def->args_ct[o2].pair_index = i;
3145
g_assert_not_reached();
3151
sort_constraints(def, 0, def->nb_oargs);
3152
sort_constraints(def, def->nb_oargs, def->nb_iargs);
3156
static void remove_label_use(TCGOp *op, int idx)
3158
TCGLabel *label = arg_label(op->args[idx]);
3161
QSIMPLEQ_FOREACH(use, &label->branches, next) {
3162
if (use->op == op) {
3163
QSIMPLEQ_REMOVE(&label->branches, use, TCGLabelUse, next);
3167
g_assert_not_reached();
3170
void tcg_op_remove(TCGContext *s, TCGOp *op)
3174
remove_label_use(op, 0);
3176
case INDEX_op_brcond_i32:
3177
case INDEX_op_brcond_i64:
3178
remove_label_use(op, 3);
3180
case INDEX_op_brcond2_i32:
3181
remove_label_use(op, 5);
3187
QTAILQ_REMOVE(&s->ops, op, link);
3188
QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
3192
void tcg_remove_ops_after(TCGOp *op)
3194
TCGContext *s = tcg_ctx;
3197
TCGOp *last = tcg_last_op();
3201
tcg_op_remove(s, last);
3205
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
3207
TCGContext *s = tcg_ctx;
3210
if (unlikely(!QTAILQ_EMPTY(&s->free_ops))) {
3211
QTAILQ_FOREACH(op, &s->free_ops, link) {
3212
if (nargs <= op->nargs) {
3213
QTAILQ_REMOVE(&s->free_ops, op, link);
3221
nargs = MAX(4, nargs);
3222
op = tcg_malloc(sizeof(TCGOp) + sizeof(TCGArg) * nargs);
3225
memset(op, 0, offsetof(TCGOp, link));
3230
tcg_debug_assert(op->nargs == nargs);
3236
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs)
3238
TCGOp *op = tcg_op_alloc(opc, nargs);
3240
if (tcg_ctx->emit_before_op) {
3241
QTAILQ_INSERT_BEFORE(tcg_ctx->emit_before_op, op, link);
3243
QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
3248
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
3249
TCGOpcode opc, unsigned nargs)
3251
TCGOp *new_op = tcg_op_alloc(opc, nargs);
3252
QTAILQ_INSERT_BEFORE(old_op, new_op, link);
3256
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
3257
TCGOpcode opc, unsigned nargs)
3259
TCGOp *new_op = tcg_op_alloc(opc, nargs);
3260
QTAILQ_INSERT_AFTER(&s->ops, old_op, new_op, link);
3264
static void move_label_uses(TCGLabel *to, TCGLabel *from)
3268
QSIMPLEQ_FOREACH(u, &from->branches, next) {
3272
op->args[0] = label_arg(to);
3274
case INDEX_op_brcond_i32:
3275
case INDEX_op_brcond_i64:
3276
op->args[3] = label_arg(to);
3278
case INDEX_op_brcond2_i32:
3279
op->args[5] = label_arg(to);
3282
g_assert_not_reached();
3286
QSIMPLEQ_CONCAT(&to->branches, &from->branches);
3290
static void __attribute__((noinline))
3291
reachable_code_pass(TCGContext *s)
3293
TCGOp *op, *op_next, *op_prev;
3296
QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
3301
case INDEX_op_set_label:
3302
label = arg_label(op->args[0]);
3308
op_prev = QTAILQ_PREV(op, link);
3316
if (op_prev->opc == INDEX_op_set_label) {
3317
move_label_uses(label, arg_label(op_prev->args[0]));
3318
tcg_op_remove(s, op_prev);
3319
op_prev = QTAILQ_PREV(op, link);
3329
if (op_prev->opc == INDEX_op_br &&
3330
label == arg_label(op_prev->args[0])) {
3331
tcg_op_remove(s, op_prev);
3336
if (QSIMPLEQ_EMPTY(&label->branches)) {
3353
case INDEX_op_exit_tb:
3354
case INDEX_op_goto_ptr:
3361
if (tcg_call_flags(op) & TCG_CALL_NO_RETURN) {
3366
case INDEX_op_insn_start:
3376
tcg_op_remove(s, op);
3384
#define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
3385
#define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
3388
static inline TCGRegSet *la_temp_pref(TCGTemp *ts)
3390
return ts->state_ptr;
3396
static inline void la_reset_pref(TCGTemp *ts)
3399
= (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]);
3404
static void la_func_end(TCGContext *s, int ng, int nt)
3408
for (i = 0; i < ng; ++i) {
3409
s->temps[i].state = TS_DEAD | TS_MEM;
3410
la_reset_pref(&s->temps[i]);
3412
for (i = ng; i < nt; ++i) {
3413
s->temps[i].state = TS_DEAD;
3414
la_reset_pref(&s->temps[i]);
3420
static void la_bb_end(TCGContext *s, int ng, int nt)
3424
for (i = 0; i < nt; ++i) {
3425
TCGTemp *ts = &s->temps[i];
3432
state = TS_DEAD | TS_MEM;
3439
g_assert_not_reached();
3447
static void la_global_sync(TCGContext *s, int ng)
3451
for (i = 0; i < ng; ++i) {
3452
int state = s->temps[i].state;
3453
s->temps[i].state = state | TS_MEM;
3454
if (state == TS_DEAD) {
3456
la_reset_pref(&s->temps[i]);
3466
static void la_bb_sync(TCGContext *s, int ng, int nt)
3468
la_global_sync(s, ng);
3470
for (int i = ng; i < nt; ++i) {
3471
TCGTemp *ts = &s->temps[i];
3477
ts->state = state | TS_MEM;
3478
if (state != TS_DEAD) {
3486
g_assert_not_reached();
3488
la_reset_pref(&s->temps[i]);
3493
static void la_global_kill(TCGContext *s, int ng)
3497
for (i = 0; i < ng; i++) {
3498
s->temps[i].state = TS_DEAD | TS_MEM;
3499
la_reset_pref(&s->temps[i]);
3504
static void la_cross_call(TCGContext *s, int nt)
3506
TCGRegSet mask = ~tcg_target_call_clobber_regs;
3509
for (i = 0; i < nt; i++) {
3510
TCGTemp *ts = &s->temps[i];
3511
if (!(ts->state & TS_DEAD)) {
3512
TCGRegSet *pset = la_temp_pref(ts);
3513
TCGRegSet set = *pset;
3518
set = tcg_target_available_regs[ts->type] & mask;
3529
static void __attribute__((noinline))
3530
liveness_pass_0(TCGContext *s)
3532
void * const multiple_ebb = (void *)(uintptr_t)-1;
3533
int nb_temps = s->nb_temps;
3536
for (int i = s->nb_globals; i < nb_temps; ++i) {
3537
s->temps[i].state_ptr = NULL;
3546
ebb = QTAILQ_FIRST(&s->ops);
3547
QTAILQ_FOREACH(op, &s->ops, link) {
3548
const TCGOpDef *def;
3549
int nb_oargs, nb_iargs;
3552
case INDEX_op_set_label:
3555
case INDEX_op_discard:
3558
nb_oargs = TCGOP_CALLO(op);
3559
nb_iargs = TCGOP_CALLI(op);
3562
def = &tcg_op_defs[op->opc];
3563
nb_oargs = def->nb_oargs;
3564
nb_iargs = def->nb_iargs;
3568
for (int i = 0; i < nb_oargs + nb_iargs; ++i) {
3569
TCGTemp *ts = arg_temp(op->args[i]);
3571
if (ts->kind != TEMP_TB) {
3574
if (ts->state_ptr == NULL) {
3575
ts->state_ptr = ebb;
3576
} else if (ts->state_ptr != ebb) {
3577
ts->state_ptr = multiple_ebb;
3586
for (int i = s->nb_globals; i < nb_temps; ++i) {
3587
TCGTemp *ts = &s->temps[i];
3588
if (ts->kind == TEMP_TB && ts->state_ptr != multiple_ebb) {
3589
ts->kind = TEMP_EBB;
3597
static void __attribute__((noinline))
3598
liveness_pass_1(TCGContext *s)
3600
int nb_globals = s->nb_globals;
3601
int nb_temps = s->nb_temps;
3602
TCGOp *op, *op_prev;
3606
prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps);
3607
for (i = 0; i < nb_temps; ++i) {
3608
s->temps[i].state_ptr = prefs + i;
3612
la_func_end(s, nb_globals, nb_temps);
3614
QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, link, op_prev) {
3615
int nb_iargs, nb_oargs;
3616
TCGOpcode opc_new, opc_new2;
3618
TCGLifeData arg_life = 0;
3620
TCGOpcode opc = op->opc;
3621
const TCGOpDef *def = &tcg_op_defs[opc];
3626
const TCGHelperInfo *info = tcg_call_info(op);
3627
int call_flags = tcg_call_flags(op);
3629
nb_oargs = TCGOP_CALLO(op);
3630
nb_iargs = TCGOP_CALLI(op);
3633
if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
3634
for (i = 0; i < nb_oargs; i++) {
3635
ts = arg_temp(op->args[i]);
3636
if (ts->state != TS_DEAD) {
3637
goto do_not_remove_call;
3645
for (i = 0; i < nb_oargs; i++) {
3646
ts = arg_temp(op->args[i]);
3647
if (ts->state & TS_DEAD) {
3648
arg_life |= DEAD_ARG << i;
3650
if (ts->state & TS_MEM) {
3651
arg_life |= SYNC_ARG << i;
3653
ts->state = TS_DEAD;
3658
memset(op->output_pref, 0, sizeof(op->output_pref));
3660
if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
3661
TCG_CALL_NO_READ_GLOBALS))) {
3662
la_global_kill(s, nb_globals);
3663
} else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
3664
la_global_sync(s, nb_globals);
3668
for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
3669
ts = arg_temp(op->args[i]);
3670
if (ts->state & TS_DEAD) {
3671
arg_life |= DEAD_ARG << i;
3676
la_cross_call(s, nb_temps);
3688
for (i = nb_iargs - 1; i >= 0; i--) {
3689
const TCGCallArgumentLoc *loc = &info->in[i];
3690
ts = arg_temp(op->args[nb_oargs + i]);
3692
if (ts->state & TS_DEAD) {
3693
switch (loc->kind) {
3694
case TCG_CALL_ARG_NORMAL:
3695
case TCG_CALL_ARG_EXTEND_U:
3696
case TCG_CALL_ARG_EXTEND_S:
3697
if (arg_slot_reg_p(loc->arg_slot)) {
3698
*la_temp_pref(ts) = 0;
3704
tcg_target_available_regs[ts->type];
3707
ts->state &= ~TS_DEAD;
3716
for (i = 0; i < nb_iargs; i++) {
3717
const TCGCallArgumentLoc *loc = &info->in[i];
3718
ts = arg_temp(op->args[nb_oargs + i]);
3720
switch (loc->kind) {
3721
case TCG_CALL_ARG_NORMAL:
3722
case TCG_CALL_ARG_EXTEND_U:
3723
case TCG_CALL_ARG_EXTEND_S:
3724
if (arg_slot_reg_p(loc->arg_slot)) {
3725
tcg_regset_set_reg(*la_temp_pref(ts),
3726
tcg_target_call_iarg_regs[loc->arg_slot]);
3735
case INDEX_op_insn_start:
3737
case INDEX_op_discard:
3739
ts = arg_temp(op->args[0]);
3740
ts->state = TS_DEAD;
3744
case INDEX_op_add2_i32:
3745
opc_new = INDEX_op_add_i32;
3747
case INDEX_op_sub2_i32:
3748
opc_new = INDEX_op_sub_i32;
3750
case INDEX_op_add2_i64:
3751
opc_new = INDEX_op_add_i64;
3753
case INDEX_op_sub2_i64:
3754
opc_new = INDEX_op_sub_i64;
3762
if (arg_temp(op->args[1])->state == TS_DEAD) {
3763
if (arg_temp(op->args[0])->state == TS_DEAD) {
3768
op->opc = opc = opc_new;
3769
op->args[1] = op->args[2];
3770
op->args[2] = op->args[4];
3777
case INDEX_op_mulu2_i32:
3778
opc_new = INDEX_op_mul_i32;
3779
opc_new2 = INDEX_op_muluh_i32;
3780
have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
3782
case INDEX_op_muls2_i32:
3783
opc_new = INDEX_op_mul_i32;
3784
opc_new2 = INDEX_op_mulsh_i32;
3785
have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
3787
case INDEX_op_mulu2_i64:
3788
opc_new = INDEX_op_mul_i64;
3789
opc_new2 = INDEX_op_muluh_i64;
3790
have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
3792
case INDEX_op_muls2_i64:
3793
opc_new = INDEX_op_mul_i64;
3794
opc_new2 = INDEX_op_mulsh_i64;
3795
have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
3800
if (arg_temp(op->args[1])->state == TS_DEAD) {
3801
if (arg_temp(op->args[0])->state == TS_DEAD) {
3806
op->opc = opc = opc_new;
3807
op->args[1] = op->args[2];
3808
op->args[2] = op->args[3];
3809
} else if (arg_temp(op->args[0])->state == TS_DEAD && have_opc_new2) {
3811
op->opc = opc = opc_new2;
3812
op->args[0] = op->args[1];
3813
op->args[1] = op->args[2];
3814
op->args[2] = op->args[3];
3824
nb_iargs = def->nb_iargs;
3825
nb_oargs = def->nb_oargs;
3830
if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
3831
for (i = 0; i < nb_oargs; i++) {
3832
if (arg_temp(op->args[i])->state != TS_DEAD) {
3841
tcg_op_remove(s, op);
3845
for (i = 0; i < nb_oargs; i++) {
3846
ts = arg_temp(op->args[i]);
3849
if (i < ARRAY_SIZE(op->output_pref)) {
3850
op->output_pref[i] = *la_temp_pref(ts);
3854
if (ts->state & TS_DEAD) {
3855
arg_life |= DEAD_ARG << i;
3857
if (ts->state & TS_MEM) {
3858
arg_life |= SYNC_ARG << i;
3860
ts->state = TS_DEAD;
3865
if (def->flags & TCG_OPF_BB_EXIT) {
3866
la_func_end(s, nb_globals, nb_temps);
3867
} else if (def->flags & TCG_OPF_COND_BRANCH) {
3868
la_bb_sync(s, nb_globals, nb_temps);
3869
} else if (def->flags & TCG_OPF_BB_END) {
3870
la_bb_end(s, nb_globals, nb_temps);
3871
} else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
3872
la_global_sync(s, nb_globals);
3873
if (def->flags & TCG_OPF_CALL_CLOBBER) {
3874
la_cross_call(s, nb_temps);
3879
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
3880
ts = arg_temp(op->args[i]);
3881
if (ts->state & TS_DEAD) {
3882
arg_life |= DEAD_ARG << i;
3887
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
3888
ts = arg_temp(op->args[i]);
3889
if (ts->state & TS_DEAD) {
3892
*la_temp_pref(ts) = tcg_target_available_regs[ts->type];
3893
ts->state &= ~TS_DEAD;
3899
case INDEX_op_mov_i32:
3900
case INDEX_op_mov_i64:
3904
if (IS_DEAD_ARG(1)) {
3905
*la_temp_pref(arg_temp(op->args[0]))
3906
= *la_temp_pref(arg_temp(op->args[1]));
3911
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
3912
const TCGArgConstraint *ct = &def->args_ct[i];
3913
TCGRegSet set, *pset;
3915
ts = arg_temp(op->args[i]);
3916
pset = la_temp_pref(ts);
3921
set &= output_pref(op, ct->alias_index);
3933
op->life = arg_life;
3938
static bool __attribute__((noinline))
3939
liveness_pass_2(TCGContext *s)
3941
int nb_globals = s->nb_globals;
3943
bool changes = false;
3944
TCGOp *op, *op_next;
3947
for (i = 0; i < nb_globals; ++i) {
3948
TCGTemp *its = &s->temps[i];
3949
if (its->indirect_reg) {
3950
TCGTemp *dts = tcg_temp_alloc(s);
3951
dts->type = its->type;
3952
dts->base_type = its->base_type;
3953
dts->temp_subindex = its->temp_subindex;
3954
dts->kind = TEMP_EBB;
3955
its->state_ptr = dts;
3957
its->state_ptr = NULL;
3960
its->state = TS_DEAD;
3962
for (nb_temps = s->nb_temps; i < nb_temps; ++i) {
3963
TCGTemp *its = &s->temps[i];
3964
its->state_ptr = NULL;
3965
its->state = TS_DEAD;
3968
QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
3969
TCGOpcode opc = op->opc;
3970
const TCGOpDef *def = &tcg_op_defs[opc];
3971
TCGLifeData arg_life = op->life;
3972
int nb_iargs, nb_oargs, call_flags;
3973
TCGTemp *arg_ts, *dir_ts;
3975
if (opc == INDEX_op_call) {
3976
nb_oargs = TCGOP_CALLO(op);
3977
nb_iargs = TCGOP_CALLI(op);
3978
call_flags = tcg_call_flags(op);
3980
nb_iargs = def->nb_iargs;
3981
nb_oargs = def->nb_oargs;
3984
if (def->flags & TCG_OPF_COND_BRANCH) {
3986
call_flags = TCG_CALL_NO_WRITE_GLOBALS;
3987
} else if (def->flags & TCG_OPF_BB_END) {
3990
} else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
3992
call_flags = TCG_CALL_NO_WRITE_GLOBALS;
3995
call_flags = (TCG_CALL_NO_READ_GLOBALS |
3996
TCG_CALL_NO_WRITE_GLOBALS);
4001
for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
4002
arg_ts = arg_temp(op->args[i]);
4003
dir_ts = arg_ts->state_ptr;
4004
if (dir_ts && arg_ts->state == TS_DEAD) {
4005
TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32
4008
TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
4010
lop->args[0] = temp_arg(dir_ts);
4011
lop->args[1] = temp_arg(arg_ts->mem_base);
4012
lop->args[2] = arg_ts->mem_offset;
4015
arg_ts->state = TS_MEM;
4022
for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
4023
arg_ts = arg_temp(op->args[i]);
4024
dir_ts = arg_ts->state_ptr;
4026
op->args[i] = temp_arg(dir_ts);
4028
if (IS_DEAD_ARG(i)) {
4029
arg_ts->state = TS_DEAD;
4036
if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
4038
} else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
4039
for (i = 0; i < nb_globals; ++i) {
4042
arg_ts = &s->temps[i];
4043
tcg_debug_assert(arg_ts->state_ptr == 0
4044
|| arg_ts->state != 0);
4047
for (i = 0; i < nb_globals; ++i) {
4050
arg_ts = &s->temps[i];
4051
tcg_debug_assert(arg_ts->state_ptr == 0
4052
|| arg_ts->state == TS_DEAD);
4057
if (opc == INDEX_op_mov_i32 || opc == INDEX_op_mov_i64) {
4058
arg_ts = arg_temp(op->args[0]);
4059
dir_ts = arg_ts->state_ptr;
4061
op->args[0] = temp_arg(dir_ts);
4067
if (NEED_SYNC_ARG(0)) {
4068
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
4071
TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
4072
TCGTemp *out_ts = dir_ts;
4074
if (IS_DEAD_ARG(0)) {
4075
out_ts = arg_temp(op->args[1]);
4076
arg_ts->state = TS_DEAD;
4077
tcg_op_remove(s, op);
4079
arg_ts->state = TS_MEM;
4082
sop->args[0] = temp_arg(out_ts);
4083
sop->args[1] = temp_arg(arg_ts->mem_base);
4084
sop->args[2] = arg_ts->mem_offset;
4086
tcg_debug_assert(!IS_DEAD_ARG(0));
4090
for (i = 0; i < nb_oargs; i++) {
4091
arg_ts = arg_temp(op->args[i]);
4092
dir_ts = arg_ts->state_ptr;
4096
op->args[i] = temp_arg(dir_ts);
4103
if (NEED_SYNC_ARG(i)) {
4104
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
4107
TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
4109
sop->args[0] = temp_arg(dir_ts);
4110
sop->args[1] = temp_arg(arg_ts->mem_base);
4111
sop->args[2] = arg_ts->mem_offset;
4113
arg_ts->state = TS_MEM;
4116
if (IS_DEAD_ARG(i)) {
4117
arg_ts->state = TS_DEAD;
4126
static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
4132
size = tcg_type_size(ts->base_type);
4133
switch (ts->base_type) {
4152
g_assert_not_reached();
4161
align = MIN(TCG_TARGET_STACK_ALIGN, align);
4162
off = ROUND_UP(s->current_frame_offset, align);
4165
if (off + size > s->frame_end) {
4166
tcg_raise_tb_overflow(s);
4168
s->current_frame_offset = off + size;
4169
#if defined(__sparc__)
4170
off += TCG_TARGET_STACK_BIAS;
4174
if (ts->base_type != ts->type) {
4175
int part_size = tcg_type_size(ts->type);
4176
int part_count = size / part_size;
4182
ts -= ts->temp_subindex;
4183
for (int i = 0; i < part_count; ++i) {
4184
ts[i].mem_offset = off + i * part_size;
4185
ts[i].mem_base = s->frame_temp;
4186
ts[i].mem_allocated = 1;
4189
ts->mem_offset = off;
4190
ts->mem_base = s->frame_temp;
4191
ts->mem_allocated = 1;
4196
static void set_temp_val_reg(TCGContext *s, TCGTemp *ts, TCGReg reg)
4198
if (ts->val_type == TEMP_VAL_REG) {
4199
TCGReg old = ts->reg;
4200
tcg_debug_assert(s->reg_to_temp[old] == ts);
4204
s->reg_to_temp[old] = NULL;
4206
tcg_debug_assert(s->reg_to_temp[reg] == NULL);
4207
s->reg_to_temp[reg] = ts;
4208
ts->val_type = TEMP_VAL_REG;
4213
static void set_temp_val_nonreg(TCGContext *s, TCGTemp *ts, TCGTempVal type)
4215
tcg_debug_assert(type != TEMP_VAL_REG);
4216
if (ts->val_type == TEMP_VAL_REG) {
4217
TCGReg reg = ts->reg;
4218
tcg_debug_assert(s->reg_to_temp[reg] == ts);
4219
s->reg_to_temp[reg] = NULL;
4221
ts->val_type = type;
4224
static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);
4228
static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
4230
TCGTempVal new_type;
4237
new_type = TEMP_VAL_MEM;
4240
new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD;
4243
new_type = TEMP_VAL_CONST;
4246
g_assert_not_reached();
4248
set_temp_val_nonreg(s, ts, new_type);
4252
static inline void temp_dead(TCGContext *s, TCGTemp *ts)
4254
temp_free_or_dead(s, ts, 1);
4261
static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
4262
TCGRegSet preferred_regs, int free_or_dead)
4264
if (!temp_readonly(ts) && !ts->mem_coherent) {
4265
if (!ts->mem_allocated) {
4266
temp_allocate_frame(s, ts);
4268
switch (ts->val_type) {
4269
case TEMP_VAL_CONST:
4274
&& tcg_out_sti(s, ts->type, ts->val,
4275
ts->mem_base->reg, ts->mem_offset)) {
4278
temp_load(s, ts, tcg_target_available_regs[ts->type],
4279
allocated_regs, preferred_regs);
4283
tcg_out_st(s, ts->type, ts->reg,
4284
ts->mem_base->reg, ts->mem_offset);
4292
g_assert_not_reached();
4294
ts->mem_coherent = 1;
4297
temp_free_or_dead(s, ts, free_or_dead);
4302
static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
4304
TCGTemp *ts = s->reg_to_temp[reg];
4306
temp_sync(s, ts, allocated_regs, 0, -1);
4320
static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
4321
TCGRegSet allocated_regs,
4322
TCGRegSet preferred_regs, bool rev)
4324
int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
4325
TCGRegSet reg_ct[2];
4328
reg_ct[1] = required_regs & ~allocated_regs;
4329
tcg_debug_assert(reg_ct[1] != 0);
4330
reg_ct[0] = reg_ct[1] & preferred_regs;
4334
f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
4336
order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
4339
for (j = f; j < 2; j++) {
4340
TCGRegSet set = reg_ct[j];
4342
if (tcg_regset_single(set)) {
4344
TCGReg reg = tcg_regset_first(set);
4345
if (s->reg_to_temp[reg] == NULL) {
4349
for (i = 0; i < n; i++) {
4350
TCGReg reg = order[i];
4351
if (s->reg_to_temp[reg] == NULL &&
4352
tcg_regset_test_reg(set, reg)) {
4360
for (j = f; j < 2; j++) {
4361
TCGRegSet set = reg_ct[j];
4363
if (tcg_regset_single(set)) {
4365
TCGReg reg = tcg_regset_first(set);
4366
tcg_reg_free(s, reg, allocated_regs);
4369
for (i = 0; i < n; i++) {
4370
TCGReg reg = order[i];
4371
if (tcg_regset_test_reg(set, reg)) {
4372
tcg_reg_free(s, reg, allocated_regs);
4379
g_assert_not_reached();
4382
static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs,
4383
TCGRegSet allocated_regs,
4384
TCGRegSet preferred_regs, bool rev)
4386
int i, j, k, fmin, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
4387
TCGRegSet reg_ct[2];
4391
reg_ct[1] = required_regs & ~(allocated_regs | (allocated_regs >> 1));
4392
tcg_debug_assert(reg_ct[1] != 0);
4393
reg_ct[0] = reg_ct[1] & preferred_regs;
4395
order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
4401
k = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
4407
for (fmin = 2; fmin >= 0; fmin--) {
4408
for (j = k; j < 2; j++) {
4409
TCGRegSet set = reg_ct[j];
4411
for (i = 0; i < n; i++) {
4412
TCGReg reg = order[i];
4414
if (tcg_regset_test_reg(set, reg)) {
4415
int f = !s->reg_to_temp[reg] + !s->reg_to_temp[reg + 1];
4417
tcg_reg_free(s, reg, allocated_regs);
4418
tcg_reg_free(s, reg + 1, allocated_regs);
4425
g_assert_not_reached();
4430
static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
4431
TCGRegSet allocated_regs, TCGRegSet preferred_regs)
4435
switch (ts->val_type) {
4438
case TEMP_VAL_CONST:
4439
reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
4440
preferred_regs, ts->indirect_base);
4441
if (ts->type <= TCG_TYPE_I64) {
4442
tcg_out_movi(s, ts->type, reg, ts->val);
4444
uint64_t val = ts->val;
4452
if (val == dup_const(MO_8, val)) {
4454
} else if (val == dup_const(MO_16, val)) {
4456
} else if (val == dup_const(MO_32, val)) {
4460
tcg_out_dupi_vec(s, ts->type, vece, reg, ts->val);
4462
ts->mem_coherent = 0;
4465
reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
4466
preferred_regs, ts->indirect_base);
4467
tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
4468
ts->mem_coherent = 1;
4472
g_assert_not_reached();
4474
set_temp_val_reg(s, ts, reg);
4479
static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
4483
tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || temp_readonly(ts));
4489
static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
4493
for (i = 0, n = s->nb_globals; i < n; i++) {
4494
temp_save(s, &s->temps[i], allocated_regs);
4501
static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
4505
for (i = 0, n = s->nb_globals; i < n; i++) {
4506
TCGTemp *ts = &s->temps[i];
4507
tcg_debug_assert(ts->val_type != TEMP_VAL_REG
4508
|| ts->kind == TEMP_FIXED
4509
|| ts->mem_coherent);
4515
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
4519
for (i = s->nb_globals; i < s->nb_temps; i++) {
4520
TCGTemp *ts = &s->temps[i];
4524
temp_save(s, ts, allocated_regs);
4529
tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
4533
tcg_debug_assert(ts->val_type == TEMP_VAL_CONST);
4536
g_assert_not_reached();
4540
save_globals(s, allocated_regs);
4548
static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
4550
sync_globals(s, allocated_regs);
4552
for (int i = s->nb_globals; i < s->nb_temps; i++) {
4553
TCGTemp *ts = &s->temps[i];
4560
tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
4566
g_assert_not_reached();
4574
static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
4575
tcg_target_ulong val, TCGLifeData arg_life,
4576
TCGRegSet preferred_regs)
4579
tcg_debug_assert(!temp_readonly(ots));
4582
set_temp_val_nonreg(s, ots, TEMP_VAL_CONST);
4584
ots->mem_coherent = 0;
4585
if (NEED_SYNC_ARG(0)) {
4586
temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0));
4587
} else if (IS_DEAD_ARG(0)) {
4595
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
4597
const TCGLifeData arg_life = op->life;
4598
TCGRegSet allocated_regs, preferred_regs;
4600
TCGType otype, itype;
4603
allocated_regs = s->reserved_regs;
4604
preferred_regs = output_pref(op, 0);
4605
ots = arg_temp(op->args[0]);
4606
ts = arg_temp(op->args[1]);
4609
tcg_debug_assert(!temp_readonly(ots));
4615
if (ts->val_type == TEMP_VAL_CONST) {
4617
tcg_target_ulong val = ts->val;
4618
if (IS_DEAD_ARG(1)) {
4621
tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
4629
if (ts->val_type == TEMP_VAL_MEM) {
4630
temp_load(s, ts, tcg_target_available_regs[itype],
4631
allocated_regs, preferred_regs);
4633
tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
4636
if (IS_DEAD_ARG(0)) {
4639
tcg_debug_assert(NEED_SYNC_ARG(0));
4640
if (!ots->mem_allocated) {
4641
temp_allocate_frame(s, ots);
4643
tcg_out_st(s, otype, ireg, ots->mem_base->reg, ots->mem_offset);
4644
if (IS_DEAD_ARG(1)) {
4651
if (IS_DEAD_ARG(1) && ts->kind != TEMP_FIXED) {
4660
if (ots->val_type == TEMP_VAL_REG) {
4664
oreg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
4665
allocated_regs | ((TCGRegSet)1 << ireg),
4666
preferred_regs, ots->indirect_base);
4668
if (!tcg_out_mov(s, otype, oreg, ireg)) {
4674
assert(!temp_readonly(ots));
4675
if (!ts->mem_allocated) {
4676
temp_allocate_frame(s, ots);
4678
tcg_out_st(s, ts->type, ireg, ots->mem_base->reg, ots->mem_offset);
4679
set_temp_val_nonreg(s, ts, TEMP_VAL_MEM);
4680
ots->mem_coherent = 1;
4684
set_temp_val_reg(s, ots, oreg);
4685
ots->mem_coherent = 0;
4687
if (NEED_SYNC_ARG(0)) {
4688
temp_sync(s, ots, allocated_regs, 0, 0);
4695
static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
4697
const TCGLifeData arg_life = op->life;
4698
TCGRegSet dup_out_regs, dup_in_regs;
4700
TCGType itype, vtype;
4705
ots = arg_temp(op->args[0]);
4706
its = arg_temp(op->args[1]);
4709
tcg_debug_assert(!temp_readonly(ots));
4712
vece = TCGOP_VECE(op);
4713
vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
4715
if (its->val_type == TEMP_VAL_CONST) {
4717
tcg_target_ulong val = its->val;
4718
if (IS_DEAD_ARG(1)) {
4721
tcg_reg_alloc_do_movi(s, ots, val, arg_life, output_pref(op, 0));
4725
dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
4726
dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs;
4729
if (ots->val_type != TEMP_VAL_REG) {
4730
TCGRegSet allocated_regs = s->reserved_regs;
4733
if (!IS_DEAD_ARG(1) && its->val_type == TEMP_VAL_REG) {
4735
tcg_regset_set_reg(allocated_regs, its->reg);
4737
oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
4738
output_pref(op, 0), ots->indirect_base);
4739
set_temp_val_reg(s, ots, oreg);
4742
switch (its->val_type) {
4749
if (tcg_regset_test_reg(dup_in_regs, its->reg)) {
4750
if (tcg_out_dup_vec(s, vtype, vece, ots->reg, its->reg)) {
4755
if (!its->mem_coherent) {
4761
if (tcg_out_mov(s, itype, ots->reg, its->reg)) {
4765
temp_sync(s, its, s->reserved_regs, 0, 0);
4771
if (HOST_BIG_ENDIAN) {
4772
lowpart_ofs = tcg_type_size(itype) - (1 << vece);
4774
if (tcg_out_dupm_vec(s, vtype, vece, ots->reg, its->mem_base->reg,
4775
its->mem_offset + lowpart_ofs)) {
4779
tcg_out_ld(s, itype, ots->reg, its->mem_base->reg, its->mem_offset);
4783
g_assert_not_reached();
4787
ok = tcg_out_dup_vec(s, vtype, vece, ots->reg, ots->reg);
4788
tcg_debug_assert(ok);
4791
ots->mem_coherent = 0;
4792
if (IS_DEAD_ARG(1)) {
4795
if (NEED_SYNC_ARG(0)) {
4796
temp_sync(s, ots, s->reserved_regs, 0, 0);
4798
if (IS_DEAD_ARG(0)) {
4803
static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
4805
const TCGLifeData arg_life = op->life;
4806
const TCGOpDef * const def = &tcg_op_defs[op->opc];
4807
TCGRegSet i_allocated_regs;
4808
TCGRegSet o_allocated_regs;
4809
int i, k, nb_iargs, nb_oargs;
4812
const TCGArgConstraint *arg_ct;
4814
TCGArg new_args[TCG_MAX_OP_ARGS];
4815
int const_args[TCG_MAX_OP_ARGS];
4818
nb_oargs = def->nb_oargs;
4819
nb_iargs = def->nb_iargs;
4822
memcpy(new_args + nb_oargs + nb_iargs,
4823
op->args + nb_oargs + nb_iargs,
4824
sizeof(TCGArg) * def->nb_cargs);
4826
i_allocated_regs = s->reserved_regs;
4827
o_allocated_regs = s->reserved_regs;
4830
case INDEX_op_brcond_i32:
4831
case INDEX_op_brcond_i64:
4832
op_cond = op->args[2];
4834
case INDEX_op_setcond_i32:
4835
case INDEX_op_setcond_i64:
4836
case INDEX_op_negsetcond_i32:
4837
case INDEX_op_negsetcond_i64:
4838
case INDEX_op_cmp_vec:
4839
op_cond = op->args[3];
4841
case INDEX_op_brcond2_i32:
4842
op_cond = op->args[4];
4844
case INDEX_op_movcond_i32:
4845
case INDEX_op_movcond_i64:
4846
case INDEX_op_setcond2_i32:
4847
case INDEX_op_cmpsel_vec:
4848
op_cond = op->args[5];
4852
op_cond = TCG_COND_ALWAYS;
4857
for (k = 0; k < nb_iargs; k++) {
4858
TCGRegSet i_preferred_regs, i_required_regs;
4859
bool allocate_new_reg, copyto_new_reg;
4863
i = def->args_ct[nb_oargs + k].sort_index;
4865
arg_ct = &def->args_ct[i];
4868
if (ts->val_type == TEMP_VAL_CONST
4869
&& tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
4870
op_cond, TCGOP_VECE(op))) {
4873
new_args[i] = ts->val;
4878
i_preferred_regs = 0;
4879
i_required_regs = arg_ct->regs;
4880
allocate_new_reg = false;
4881
copyto_new_reg = false;
4883
switch (arg_ct->pair) {
4885
if (arg_ct->ialias) {
4886
i_preferred_regs = output_pref(op, arg_ct->alias_index);
4894
if (temp_readonly(ts) || !IS_DEAD_ARG(i)
4895
|| def->args_ct[arg_ct->alias_index].newreg) {
4896
allocate_new_reg = true;
4897
} else if (ts->val_type == TEMP_VAL_REG) {
4903
tcg_regset_test_reg(i_allocated_regs, reg);
4906
if (!allocate_new_reg) {
4907
temp_load(s, ts, i_required_regs, i_allocated_regs,
4910
allocate_new_reg = !tcg_regset_test_reg(i_required_regs, reg);
4912
if (allocate_new_reg) {
4917
temp_load(s, ts, tcg_target_available_regs[ts->type],
4918
i_allocated_regs, 0);
4919
reg = tcg_reg_alloc(s, i_required_regs, i_allocated_regs,
4920
i_preferred_regs, ts->indirect_base);
4921
copyto_new_reg = true;
4928
i2 = arg_ct->pair_index;
4929
ts2 = i1 != i2 ? arg_temp(op->args[i2]) : NULL;
4935
if (arg_ct->ialias) {
4936
i_preferred_regs = output_pref(op, arg_ct->alias_index);
4937
if (IS_DEAD_ARG(i1) &&
4939
!temp_readonly(ts) &&
4940
ts->val_type == TEMP_VAL_REG &&
4941
ts->reg < TCG_TARGET_NB_REGS - 1 &&
4942
tcg_regset_test_reg(i_required_regs, reg) &&
4943
!tcg_regset_test_reg(i_allocated_regs, reg) &&
4944
!tcg_regset_test_reg(i_allocated_regs, reg + 1) &&
4946
? ts2->val_type == TEMP_VAL_REG &&
4947
ts2->reg == reg + 1 &&
4949
: s->reg_to_temp[reg + 1] == NULL)) {
4954
tcg_debug_assert(ts2);
4955
if (ts->val_type == TEMP_VAL_REG &&
4956
ts2->val_type == TEMP_VAL_REG &&
4957
ts2->reg == reg + 1 &&
4958
tcg_regset_test_reg(i_required_regs, reg)) {
4962
reg = tcg_reg_alloc_pair(s, i_required_regs, i_allocated_regs,
4963
0, ts->indirect_base);
4967
reg = new_args[arg_ct->pair_index] + 1;
4971
tcg_debug_assert(arg_ct->ialias);
4972
i_preferred_regs = output_pref(op, arg_ct->alias_index);
4974
if (IS_DEAD_ARG(i) &&
4975
!temp_readonly(ts) &&
4976
ts->val_type == TEMP_VAL_REG &&
4978
s->reg_to_temp[reg - 1] == NULL &&
4979
tcg_regset_test_reg(i_required_regs, reg) &&
4980
!tcg_regset_test_reg(i_allocated_regs, reg) &&
4981
!tcg_regset_test_reg(i_allocated_regs, reg - 1)) {
4982
tcg_regset_set_reg(i_allocated_regs, reg - 1);
4985
reg = tcg_reg_alloc_pair(s, i_required_regs >> 1,
4986
i_allocated_regs, 0,
4988
tcg_regset_set_reg(i_allocated_regs, reg);
4997
if (arg_ct->ialias && (!IS_DEAD_ARG(i) || temp_readonly(ts))) {
4998
TCGRegSet t_allocated_regs = i_allocated_regs;
5005
tcg_regset_set_reg(t_allocated_regs, reg);
5006
tcg_regset_set_reg(t_allocated_regs, reg + 1);
5007
if (ts->val_type == TEMP_VAL_REG && ts->reg == reg) {
5012
tcg_debug_assert(ts->kind != TEMP_FIXED);
5013
nr = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
5014
t_allocated_regs, 0, ts->indirect_base);
5015
ok = tcg_out_mov(s, ts->type, nr, reg);
5016
tcg_debug_assert(ok);
5018
set_temp_val_reg(s, ts, nr);
5020
temp_load(s, ts, tcg_target_available_regs[ts->type],
5021
t_allocated_regs, 0);
5022
copyto_new_reg = true;
5026
i_required_regs = (TCGRegSet)1 << reg;
5027
temp_load(s, ts, i_required_regs, i_allocated_regs,
5029
copyto_new_reg = ts->reg != reg;
5034
g_assert_not_reached();
5037
if (copyto_new_reg) {
5038
if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
5043
temp_sync(s, ts, i_allocated_regs, 0, 0);
5044
tcg_out_ld(s, ts->type, reg,
5045
ts->mem_base->reg, ts->mem_offset);
5050
tcg_regset_set_reg(i_allocated_regs, reg);
5054
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
5055
if (IS_DEAD_ARG(i)) {
5056
temp_dead(s, arg_temp(op->args[i]));
5060
if (def->flags & TCG_OPF_COND_BRANCH) {
5061
tcg_reg_alloc_cbranch(s, i_allocated_regs);
5062
} else if (def->flags & TCG_OPF_BB_END) {
5063
tcg_reg_alloc_bb_end(s, i_allocated_regs);
5065
if (def->flags & TCG_OPF_CALL_CLOBBER) {
5067
for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
5068
if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
5069
tcg_reg_free(s, i, i_allocated_regs);
5073
if (def->flags & TCG_OPF_SIDE_EFFECTS) {
5076
sync_globals(s, i_allocated_regs);
5080
for(k = 0; k < nb_oargs; k++) {
5081
i = def->args_ct[k].sort_index;
5083
arg_ct = &def->args_ct[i];
5087
tcg_debug_assert(!temp_readonly(ts));
5089
switch (arg_ct->pair) {
5091
if (arg_ct->oalias && !const_args[arg_ct->alias_index]) {
5092
reg = new_args[arg_ct->alias_index];
5093
} else if (arg_ct->newreg) {
5094
reg = tcg_reg_alloc(s, arg_ct->regs,
5095
i_allocated_regs | o_allocated_regs,
5096
output_pref(op, k), ts->indirect_base);
5098
reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs,
5099
output_pref(op, k), ts->indirect_base);
5104
if (arg_ct->oalias) {
5105
reg = new_args[arg_ct->alias_index];
5106
} else if (arg_ct->newreg) {
5107
reg = tcg_reg_alloc_pair(s, arg_ct->regs,
5108
i_allocated_regs | o_allocated_regs,
5112
reg = tcg_reg_alloc_pair(s, arg_ct->regs, o_allocated_regs,
5119
if (arg_ct->oalias) {
5120
reg = new_args[arg_ct->alias_index];
5122
reg = new_args[arg_ct->pair_index] + 1;
5127
tcg_debug_assert(!arg_ct->newreg);
5128
reg = new_args[arg_ct->pair_index] - 1;
5132
g_assert_not_reached();
5134
tcg_regset_set_reg(o_allocated_regs, reg);
5135
set_temp_val_reg(s, ts, reg);
5136
ts->mem_coherent = 0;
5143
case INDEX_op_ext8s_i32:
5144
tcg_out_ext8s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
5146
case INDEX_op_ext8s_i64:
5147
tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
5149
case INDEX_op_ext8u_i32:
5150
case INDEX_op_ext8u_i64:
5151
tcg_out_ext8u(s, new_args[0], new_args[1]);
5153
case INDEX_op_ext16s_i32:
5154
tcg_out_ext16s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
5156
case INDEX_op_ext16s_i64:
5157
tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
5159
case INDEX_op_ext16u_i32:
5160
case INDEX_op_ext16u_i64:
5161
tcg_out_ext16u(s, new_args[0], new_args[1]);
5163
case INDEX_op_ext32s_i64:
5164
tcg_out_ext32s(s, new_args[0], new_args[1]);
5166
case INDEX_op_ext32u_i64:
5167
tcg_out_ext32u(s, new_args[0], new_args[1]);
5169
case INDEX_op_ext_i32_i64:
5170
tcg_out_exts_i32_i64(s, new_args[0], new_args[1]);
5172
case INDEX_op_extu_i32_i64:
5173
tcg_out_extu_i32_i64(s, new_args[0], new_args[1]);
5175
case INDEX_op_extrl_i64_i32:
5176
tcg_out_extrl_i64_i32(s, new_args[0], new_args[1]);
5179
if (def->flags & TCG_OPF_VECTOR) {
5180
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
5181
new_args, const_args);
5183
tcg_out_op(s, op->opc, new_args, const_args);
5189
for(i = 0; i < nb_oargs; i++) {
5190
ts = arg_temp(op->args[i]);
5193
tcg_debug_assert(!temp_readonly(ts));
5195
if (NEED_SYNC_ARG(i)) {
5196
temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
5197
} else if (IS_DEAD_ARG(i)) {
5203
static bool tcg_reg_alloc_dup2(TCGContext *s, const TCGOp *op)
5205
const TCGLifeData arg_life = op->life;
5206
TCGTemp *ots, *itsl, *itsh;
5207
TCGType vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
5210
tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
5211
tcg_debug_assert(TCGOP_VECE(op) == MO_64);
5213
ots = arg_temp(op->args[0]);
5214
itsl = arg_temp(op->args[1]);
5215
itsh = arg_temp(op->args[2]);
5218
tcg_debug_assert(!temp_readonly(ots));
5221
if (ots->val_type != TEMP_VAL_REG) {
5222
TCGRegSet allocated_regs = s->reserved_regs;
5223
TCGRegSet dup_out_regs =
5224
tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
5228
if (!IS_DEAD_ARG(1) && itsl->val_type == TEMP_VAL_REG) {
5229
tcg_regset_set_reg(allocated_regs, itsl->reg);
5231
if (!IS_DEAD_ARG(2) && itsh->val_type == TEMP_VAL_REG) {
5232
tcg_regset_set_reg(allocated_regs, itsh->reg);
5235
oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
5236
output_pref(op, 0), ots->indirect_base);
5237
set_temp_val_reg(s, ots, oreg);
5241
if (itsl->val_type == TEMP_VAL_CONST && itsh->val_type == TEMP_VAL_CONST) {
5242
uint64_t val = deposit64(itsl->val, 32, 32, itsh->val);
5245
if (val == dup_const(MO_8, val)) {
5247
} else if (val == dup_const(MO_16, val)) {
5249
} else if (val == dup_const(MO_32, val)) {
5253
tcg_out_dupi_vec(s, vtype, vece, ots->reg, val);
5258
if (itsl->temp_subindex == HOST_BIG_ENDIAN &&
5259
itsh->temp_subindex == !HOST_BIG_ENDIAN &&
5260
itsl == itsh + (HOST_BIG_ENDIAN ? 1 : -1)) {
5261
TCGTemp *its = itsl - HOST_BIG_ENDIAN;
5263
temp_sync(s, its + 0, s->reserved_regs, 0, 0);
5264
temp_sync(s, its + 1, s->reserved_regs, 0, 0);
5266
if (tcg_out_dupm_vec(s, vtype, MO_64, ots->reg,
5267
its->mem_base->reg, its->mem_offset)) {
5276
ots->mem_coherent = 0;
5277
if (IS_DEAD_ARG(1)) {
5280
if (IS_DEAD_ARG(2)) {
5283
if (NEED_SYNC_ARG(0)) {
5284
temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
5285
} else if (IS_DEAD_ARG(0)) {
5291
static void load_arg_reg(TCGContext *s, TCGReg reg, TCGTemp *ts,
5292
TCGRegSet allocated_regs)
5294
if (ts->val_type == TEMP_VAL_REG) {
5295
if (ts->reg != reg) {
5296
tcg_reg_free(s, reg, allocated_regs);
5297
if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
5302
temp_sync(s, ts, allocated_regs, 0, 0);
5303
tcg_out_ld(s, ts->type, reg,
5304
ts->mem_base->reg, ts->mem_offset);
5308
TCGRegSet arg_set = 0;
5310
tcg_reg_free(s, reg, allocated_regs);
5311
tcg_regset_set_reg(arg_set, reg);
5312
temp_load(s, ts, arg_set, allocated_regs, 0);
5316
static void load_arg_stk(TCGContext *s, unsigned arg_slot, TCGTemp *ts,
5317
TCGRegSet allocated_regs)
5324
temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs, 0);
5325
tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK,
5326
arg_slot_stk_ofs(arg_slot));
5329
static void load_arg_normal(TCGContext *s, const TCGCallArgumentLoc *l,
5330
TCGTemp *ts, TCGRegSet *allocated_regs)
5332
if (arg_slot_reg_p(l->arg_slot)) {
5333
TCGReg reg = tcg_target_call_iarg_regs[l->arg_slot];
5334
load_arg_reg(s, reg, ts, *allocated_regs);
5335
tcg_regset_set_reg(*allocated_regs, reg);
5337
load_arg_stk(s, l->arg_slot, ts, *allocated_regs);
5341
static void load_arg_ref(TCGContext *s, unsigned arg_slot, TCGReg ref_base,
5342
intptr_t ref_off, TCGRegSet *allocated_regs)
5346
if (arg_slot_reg_p(arg_slot)) {
5347
reg = tcg_target_call_iarg_regs[arg_slot];
5348
tcg_reg_free(s, reg, *allocated_regs);
5349
tcg_out_addi_ptr(s, reg, ref_base, ref_off);
5350
tcg_regset_set_reg(*allocated_regs, reg);
5352
reg = tcg_reg_alloc(s, tcg_target_available_regs[TCG_TYPE_PTR],
5353
*allocated_regs, 0, false);
5354
tcg_out_addi_ptr(s, reg, ref_base, ref_off);
5355
tcg_out_st(s, TCG_TYPE_PTR, reg, TCG_REG_CALL_STACK,
5356
arg_slot_stk_ofs(arg_slot));
5360
static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
5362
const int nb_oargs = TCGOP_CALLO(op);
5363
const int nb_iargs = TCGOP_CALLI(op);
5364
const TCGLifeData arg_life = op->life;
5365
const TCGHelperInfo *info = tcg_call_info(op);
5366
TCGRegSet allocated_regs = s->reserved_regs;
5373
for (i = nb_iargs - 1; i >= 0; --i) {
5374
const TCGCallArgumentLoc *loc = &info->in[i];
5375
TCGTemp *ts = arg_temp(op->args[nb_oargs + i]);
5377
switch (loc->kind) {
5378
case TCG_CALL_ARG_NORMAL:
5379
case TCG_CALL_ARG_EXTEND_U:
5380
case TCG_CALL_ARG_EXTEND_S:
5381
load_arg_normal(s, loc, ts, &allocated_regs);
5383
case TCG_CALL_ARG_BY_REF:
5384
load_arg_stk(s, loc->ref_slot, ts, allocated_regs);
5385
load_arg_ref(s, loc->arg_slot, TCG_REG_CALL_STACK,
5386
arg_slot_stk_ofs(loc->ref_slot),
5389
case TCG_CALL_ARG_BY_REF_N:
5390
load_arg_stk(s, loc->ref_slot, ts, allocated_regs);
5393
g_assert_not_reached();
5398
for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
5399
if (IS_DEAD_ARG(i)) {
5400
temp_dead(s, arg_temp(op->args[i]));
5405
for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
5406
if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
5407
tcg_reg_free(s, i, allocated_regs);
5415
if (info->flags & TCG_CALL_NO_READ_GLOBALS) {
5417
} else if (info->flags & TCG_CALL_NO_WRITE_GLOBALS) {
5418
sync_globals(s, allocated_regs);
5420
save_globals(s, allocated_regs);
5427
if (info->out_kind == TCG_CALL_RET_BY_REF) {
5428
TCGTemp *ts = arg_temp(op->args[0]);
5430
if (!ts->mem_allocated) {
5431
temp_allocate_frame(s, ts);
5433
load_arg_ref(s, 0, ts->mem_base->reg, ts->mem_offset, &allocated_regs);
5436
tcg_out_call(s, tcg_call_func(op), info);
5439
switch (info->out_kind) {
5440
case TCG_CALL_RET_NORMAL:
5441
for (i = 0; i < nb_oargs; i++) {
5442
TCGTemp *ts = arg_temp(op->args[i]);
5443
TCGReg reg = tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, i);
5446
tcg_debug_assert(!temp_readonly(ts));
5448
set_temp_val_reg(s, ts, reg);
5449
ts->mem_coherent = 0;
5453
case TCG_CALL_RET_BY_VEC:
5455
TCGTemp *ts = arg_temp(op->args[0]);
5457
tcg_debug_assert(ts->base_type == TCG_TYPE_I128);
5458
tcg_debug_assert(ts->temp_subindex == 0);
5459
if (!ts->mem_allocated) {
5460
temp_allocate_frame(s, ts);
5462
tcg_out_st(s, TCG_TYPE_V128,
5463
tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0),
5464
ts->mem_base->reg, ts->mem_offset);
5468
case TCG_CALL_RET_BY_REF:
5470
for (i = 0; i < nb_oargs; i++) {
5471
TCGTemp *ts = arg_temp(op->args[i]);
5472
ts->val_type = TEMP_VAL_MEM;
5477
g_assert_not_reached();
5481
for (i = 0; i < nb_oargs; i++) {
5482
TCGTemp *ts = arg_temp(op->args[i]);
5483
if (NEED_SYNC_ARG(i)) {
5484
temp_sync(s, ts, s->reserved_regs, 0, IS_DEAD_ARG(i));
5485
} else if (IS_DEAD_ARG(i)) {
5506
static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc,
5507
MemOp host_atom, bool allow_two_ops)
5509
MemOp align = get_alignment_bits(opc);
5510
MemOp size = opc & MO_SIZE;
5511
MemOp half = size ? size - 1 : 0;
5512
MemOp atom = opc & MO_ATOM_MASK;
5521
case MO_ATOM_IFALIGN:
5525
case MO_ATOM_IFALIGN_PAIR:
5529
case MO_ATOM_WITHIN16:
5531
if (size == MO_128) {
5533
} else if (host_atom != MO_ATOM_WITHIN16) {
5535
align = MAX(align, size);
5539
case MO_ATOM_WITHIN16_PAIR:
5546
if (host_atom != MO_ATOM_WITHIN16 && allow_two_ops) {
5547
align = MAX(align, half);
5551
case MO_ATOM_SUBALIGN:
5553
if (host_atom != MO_ATOM_SUBALIGN) {
5555
if (allow_two_ops) {
5556
align = MAX(align, half);
5558
align = MAX(align, size);
5564
g_assert_not_reached();
5567
return (TCGAtomAlign){ .atom = atmax, .align = align };
5576
static int tcg_out_helper_stk_ofs(TCGType type, unsigned slot)
5578
int ofs = arg_slot_stk_ofs(slot);
5584
if (HOST_BIG_ENDIAN &&
5585
TCG_TARGET_REG_BITS == 64 &&
5586
type == TCG_TYPE_I32) {
5592
static void tcg_out_helper_load_slots(TCGContext *s,
5593
unsigned nmov, TCGMovExtend *mov,
5594
const TCGLdstHelperParam *parm)
5603
for (i = nmov; i-- > 0; ) {
5604
unsigned slot = mov[i].dst;
5606
if (arg_slot_reg_p(slot)) {
5610
TCGReg src = mov[i].src;
5611
TCGType dst_type = mov[i].dst_type;
5612
MemOp dst_mo = dst_type == TCG_TYPE_I32 ? MO_32 : MO_64;
5615
if ((mov[i].src_ext & MO_SIZE) != dst_mo) {
5616
tcg_debug_assert(parm->ntmp != 0);
5617
mov[i].dst = src = parm->tmp[0];
5618
tcg_out_movext1(s, &mov[i]);
5621
tcg_out_st(s, dst_type, src, TCG_REG_CALL_STACK,
5622
tcg_out_helper_stk_ofs(dst_type, slot));
5632
for (i = 0; i < nmov; ++i) {
5633
mov[i].dst = tcg_target_call_iarg_regs[mov[i].dst];
5639
tcg_debug_assert(parm->ntmp >= 2);
5642
for (unsigned j = 0; j < 3; ++j) {
5643
if (dst3 == mov[j].src) {
5649
TCGReg scratch = parm->tmp[1];
5651
tcg_out_mov(s, mov[3].src_type, scratch, mov[3].src);
5652
tcg_out_movext3(s, mov, mov + 1, mov + 2, parm->tmp[0]);
5653
tcg_out_movext1_new_src(s, &mov[3], scratch);
5659
tcg_out_movext1(s, &mov[3]);
5663
tcg_out_movext3(s, mov, mov + 1, mov + 2,
5664
parm->ntmp ? parm->tmp[0] : -1);
5667
tcg_out_movext2(s, mov, mov + 1,
5668
parm->ntmp ? parm->tmp[0] : -1);
5671
tcg_out_movext1(s, mov);
5674
g_assert_not_reached();
5678
static void tcg_out_helper_load_imm(TCGContext *s, unsigned slot,
5679
TCGType type, tcg_target_long imm,
5680
const TCGLdstHelperParam *parm)
5682
if (arg_slot_reg_p(slot)) {
5683
tcg_out_movi(s, type, tcg_target_call_iarg_regs[slot], imm);
5685
int ofs = tcg_out_helper_stk_ofs(type, slot);
5686
if (!tcg_out_sti(s, type, imm, TCG_REG_CALL_STACK, ofs)) {
5687
tcg_debug_assert(parm->ntmp != 0);
5688
tcg_out_movi(s, type, parm->tmp[0], imm);
5689
tcg_out_st(s, type, parm->tmp[0], TCG_REG_CALL_STACK, ofs);
5694
static void tcg_out_helper_load_common_args(TCGContext *s,
5695
const TCGLabelQemuLdst *ldst,
5696
const TCGLdstHelperParam *parm,
5697
const TCGHelperInfo *info,
5700
TCGMovExtend ptr_mov = {
5701
.dst_type = TCG_TYPE_PTR,
5702
.src_type = TCG_TYPE_PTR,
5703
.src_ext = sizeof(void *) == 4 ? MO_32 : MO_64
5705
const TCGCallArgumentLoc *loc = &info->in[0];
5708
tcg_target_ulong imm;
5713
ptr_mov.dst = loc->arg_slot;
5714
ptr_mov.src = TCG_AREG0;
5715
tcg_out_helper_load_slots(s, 1, &ptr_mov, parm);
5721
loc = &info->in[next_arg];
5722
type = TCG_TYPE_I32;
5723
switch (loc->kind) {
5724
case TCG_CALL_ARG_NORMAL:
5726
case TCG_CALL_ARG_EXTEND_U:
5727
case TCG_CALL_ARG_EXTEND_S:
5729
tcg_debug_assert(imm <= INT32_MAX);
5730
type = TCG_TYPE_REG;
5733
g_assert_not_reached();
5735
tcg_out_helper_load_imm(s, loc->arg_slot, type, imm, parm);
5741
loc = &info->in[next_arg];
5742
slot = loc->arg_slot;
5747
if (arg_slot_reg_p(slot)) {
5748
arg_reg = tcg_target_call_iarg_regs[slot];
5750
ra_reg = parm->ra_gen(s, ldst, arg_reg);
5753
ptr_mov.src = ra_reg;
5754
tcg_out_helper_load_slots(s, 1, &ptr_mov, parm);
5756
imm = (uintptr_t)ldst->raddr;
5757
tcg_out_helper_load_imm(s, slot, TCG_TYPE_PTR, imm, parm);
5761
static unsigned tcg_out_helper_add_mov(TCGMovExtend *mov,
5762
const TCGCallArgumentLoc *loc,
5763
TCGType dst_type, TCGType src_type,
5764
TCGReg lo, TCGReg hi)
5768
if (dst_type <= TCG_TYPE_REG) {
5771
switch (loc->kind) {
5772
case TCG_CALL_ARG_NORMAL:
5773
src_ext = src_type == TCG_TYPE_I32 ? MO_32 : MO_64;
5775
case TCG_CALL_ARG_EXTEND_U:
5776
dst_type = TCG_TYPE_REG;
5779
case TCG_CALL_ARG_EXTEND_S:
5780
dst_type = TCG_TYPE_REG;
5784
g_assert_not_reached();
5787
mov[0].dst = loc->arg_slot;
5788
mov[0].dst_type = dst_type;
5790
mov[0].src_type = src_type;
5791
mov[0].src_ext = src_ext;
5795
if (TCG_TARGET_REG_BITS == 32) {
5796
assert(dst_type == TCG_TYPE_I64);
5799
assert(dst_type == TCG_TYPE_I128);
5803
mov[0].dst = loc[HOST_BIG_ENDIAN].arg_slot;
5805
mov[0].dst_type = TCG_TYPE_REG;
5806
mov[0].src_type = TCG_TYPE_REG;
5807
mov[0].src_ext = reg_mo;
5809
mov[1].dst = loc[!HOST_BIG_ENDIAN].arg_slot;
5811
mov[1].dst_type = TCG_TYPE_REG;
5812
mov[1].src_type = TCG_TYPE_REG;
5813
mov[1].src_ext = reg_mo;
5818
static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
5819
const TCGLdstHelperParam *parm)
5821
const TCGHelperInfo *info;
5822
const TCGCallArgumentLoc *loc;
5823
TCGMovExtend mov[2];
5824
unsigned next_arg, nmov;
5825
MemOp mop = get_memop(ldst->oi);
5827
switch (mop & MO_SIZE) {
5831
info = &info_helper_ld32_mmu;
5834
info = &info_helper_ld64_mmu;
5837
info = &info_helper_ld128_mmu;
5840
g_assert_not_reached();
5846
loc = &info->in[next_arg];
5847
if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
5853
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
5854
TCG_TYPE_I32, TCG_TYPE_I32,
5855
ldst->addrlo_reg, -1);
5856
tcg_out_helper_load_slots(s, 1, mov, parm);
5858
tcg_out_helper_load_imm(s, loc[!HOST_BIG_ENDIAN].arg_slot,
5859
TCG_TYPE_I32, 0, parm);
5862
nmov = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
5863
ldst->addrlo_reg, ldst->addrhi_reg);
5864
tcg_out_helper_load_slots(s, nmov, mov, parm);
5868
switch (info->out_kind) {
5869
case TCG_CALL_RET_NORMAL:
5870
case TCG_CALL_RET_BY_VEC:
5872
case TCG_CALL_RET_BY_REF:
5878
int ofs_slot0 = TCG_TARGET_CALL_STACK_OFFSET;
5880
if (arg_slot_reg_p(0)) {
5881
tcg_out_addi_ptr(s, tcg_target_call_iarg_regs[0],
5882
TCG_REG_CALL_STACK, ofs_slot0);
5884
tcg_debug_assert(parm->ntmp != 0);
5885
tcg_out_addi_ptr(s, parm->tmp[0],
5886
TCG_REG_CALL_STACK, ofs_slot0);
5887
tcg_out_st(s, TCG_TYPE_PTR, parm->tmp[0],
5888
TCG_REG_CALL_STACK, ofs_slot0);
5893
g_assert_not_reached();
5896
tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg);
5899
static void tcg_out_ld_helper_ret(TCGContext *s, const TCGLabelQemuLdst *ldst,
5901
const TCGLdstHelperParam *parm)
5903
MemOp mop = get_memop(ldst->oi);
5904
TCGMovExtend mov[2];
5907
switch (ldst->type) {
5909
if (TCG_TARGET_REG_BITS == 32) {
5915
mov[0].dst = ldst->datalo_reg;
5916
mov[0].src = tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, 0);
5917
mov[0].dst_type = ldst->type;
5918
mov[0].src_type = TCG_TYPE_REG;
5930
if (load_sign || !(mop & MO_SIGN)) {
5931
if (TCG_TARGET_REG_BITS == 32 || ldst->type == TCG_TYPE_I32) {
5932
mov[0].src_ext = MO_32;
5934
mov[0].src_ext = MO_64;
5937
mov[0].src_ext = mop & MO_SSIZE;
5939
tcg_out_movext1(s, mov);
5943
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
5944
ofs_slot0 = TCG_TARGET_CALL_STACK_OFFSET;
5945
switch (TCG_TARGET_CALL_RET_I128) {
5946
case TCG_CALL_RET_NORMAL:
5948
case TCG_CALL_RET_BY_VEC:
5949
tcg_out_st(s, TCG_TYPE_V128,
5950
tcg_target_call_oarg_reg(TCG_CALL_RET_BY_VEC, 0),
5951
TCG_REG_CALL_STACK, ofs_slot0);
5953
case TCG_CALL_RET_BY_REF:
5954
tcg_out_ld(s, TCG_TYPE_I64, ldst->datalo_reg,
5955
TCG_REG_CALL_STACK, ofs_slot0 + 8 * HOST_BIG_ENDIAN);
5956
tcg_out_ld(s, TCG_TYPE_I64, ldst->datahi_reg,
5957
TCG_REG_CALL_STACK, ofs_slot0 + 8 * !HOST_BIG_ENDIAN);
5960
g_assert_not_reached();
5965
g_assert_not_reached();
5968
mov[0].dst = ldst->datalo_reg;
5970
tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, HOST_BIG_ENDIAN);
5971
mov[0].dst_type = TCG_TYPE_REG;
5972
mov[0].src_type = TCG_TYPE_REG;
5973
mov[0].src_ext = TCG_TARGET_REG_BITS == 32 ? MO_32 : MO_64;
5975
mov[1].dst = ldst->datahi_reg;
5977
tcg_target_call_oarg_reg(TCG_CALL_RET_NORMAL, !HOST_BIG_ENDIAN);
5978
mov[1].dst_type = TCG_TYPE_REG;
5979
mov[1].src_type = TCG_TYPE_REG;
5980
mov[1].src_ext = TCG_TARGET_REG_BITS == 32 ? MO_32 : MO_64;
5982
tcg_out_movext2(s, mov, mov + 1, parm->ntmp ? parm->tmp[0] : -1);
5985
static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
5986
const TCGLdstHelperParam *parm)
5988
const TCGHelperInfo *info;
5989
const TCGCallArgumentLoc *loc;
5990
TCGMovExtend mov[4];
5992
unsigned next_arg, nmov, n;
5993
MemOp mop = get_memop(ldst->oi);
5995
switch (mop & MO_SIZE) {
5999
info = &info_helper_st32_mmu;
6000
data_type = TCG_TYPE_I32;
6003
info = &info_helper_st64_mmu;
6004
data_type = TCG_TYPE_I64;
6007
info = &info_helper_st128_mmu;
6008
data_type = TCG_TYPE_I128;
6011
g_assert_not_reached();
6019
loc = &info->in[next_arg];
6020
if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
6027
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
6028
TCG_TYPE_I32, TCG_TYPE_I32,
6029
ldst->addrlo_reg, -1);
6033
n = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
6034
ldst->addrlo_reg, ldst->addrhi_reg);
6040
loc = &info->in[next_arg];
6041
switch (loc->kind) {
6042
case TCG_CALL_ARG_NORMAL:
6043
case TCG_CALL_ARG_EXTEND_U:
6044
case TCG_CALL_ARG_EXTEND_S:
6045
n = tcg_out_helper_add_mov(mov + nmov, loc, data_type, ldst->type,
6046
ldst->datalo_reg, ldst->datahi_reg);
6049
tcg_out_helper_load_slots(s, nmov, mov, parm);
6052
case TCG_CALL_ARG_BY_REF:
6053
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
6054
tcg_debug_assert(data_type == TCG_TYPE_I128);
6055
tcg_out_st(s, TCG_TYPE_I64,
6056
HOST_BIG_ENDIAN ? ldst->datahi_reg : ldst->datalo_reg,
6057
TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc[0].ref_slot));
6058
tcg_out_st(s, TCG_TYPE_I64,
6059
HOST_BIG_ENDIAN ? ldst->datalo_reg : ldst->datahi_reg,
6060
TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc[1].ref_slot));
6062
tcg_out_helper_load_slots(s, nmov, mov, parm);
6064
if (arg_slot_reg_p(loc->arg_slot)) {
6065
tcg_out_addi_ptr(s, tcg_target_call_iarg_regs[loc->arg_slot],
6067
arg_slot_stk_ofs(loc->ref_slot));
6069
tcg_debug_assert(parm->ntmp != 0);
6070
tcg_out_addi_ptr(s, parm->tmp[0], TCG_REG_CALL_STACK,
6071
arg_slot_stk_ofs(loc->ref_slot));
6072
tcg_out_st(s, TCG_TYPE_PTR, parm->tmp[0],
6073
TCG_REG_CALL_STACK, arg_slot_stk_ofs(loc->arg_slot));
6079
g_assert_not_reached();
6082
if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
6084
loc = &info->in[1 + !HOST_BIG_ENDIAN];
6085
tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm);
6088
tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg);
6091
int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
6093
int i, start_words, num_insns;
6096
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
6097
&& qemu_log_in_addr_range(pc_start))) {
6098
FILE *logfile = qemu_log_trylock();
6100
fprintf(logfile, "OP:\n");
6101
tcg_dump_ops(s, logfile, false);
6102
fprintf(logfile, "\n");
6103
qemu_log_unlock(logfile);
6107
#ifdef CONFIG_DEBUG_TCG
6113
QSIMPLEQ_FOREACH(l, &s->labels, next) {
6114
if (unlikely(!l->present) && !QSIMPLEQ_EMPTY(&l->branches)) {
6115
qemu_log_mask(CPU_LOG_TB_OP,
6116
"$L%d referenced but not present.\n", l->id);
6126
reachable_code_pass(s);
6130
if (s->nb_indirects > 0) {
6131
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
6132
&& qemu_log_in_addr_range(pc_start))) {
6133
FILE *logfile = qemu_log_trylock();
6135
fprintf(logfile, "OP before indirect lowering:\n");
6136
tcg_dump_ops(s, logfile, false);
6137
fprintf(logfile, "\n");
6138
qemu_log_unlock(logfile);
6143
if (liveness_pass_2(s)) {
6149
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
6150
&& qemu_log_in_addr_range(pc_start))) {
6151
FILE *logfile = qemu_log_trylock();
6153
fprintf(logfile, "OP after optimization and liveness analysis:\n");
6154
tcg_dump_ops(s, logfile, true);
6155
fprintf(logfile, "\n");
6156
qemu_log_unlock(logfile);
6161
tb->jmp_reset_offset[0] = TB_JMP_OFFSET_INVALID;
6162
tb->jmp_reset_offset[1] = TB_JMP_OFFSET_INVALID;
6163
tb->jmp_insn_offset[0] = TB_JMP_OFFSET_INVALID;
6164
tb->jmp_insn_offset[1] = TB_JMP_OFFSET_INVALID;
6166
tcg_reg_alloc_start(s);
6173
s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
6174
s->code_ptr = s->code_buf;
6176
#ifdef TCG_TARGET_NEED_LDST_LABELS
6177
QSIMPLEQ_INIT(&s->ldst_labels);
6179
#ifdef TCG_TARGET_NEED_POOL_LABELS
6180
s->pool_labels = NULL;
6183
start_words = s->insn_start_words;
6185
tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * start_words);
6187
tcg_out_tb_start(s);
6190
QTAILQ_FOREACH(op, &s->ops, link) {
6191
TCGOpcode opc = op->opc;
6194
case INDEX_op_mov_i32:
6195
case INDEX_op_mov_i64:
6196
case INDEX_op_mov_vec:
6197
tcg_reg_alloc_mov(s, op);
6199
case INDEX_op_dup_vec:
6200
tcg_reg_alloc_dup(s, op);
6202
case INDEX_op_insn_start:
6203
if (num_insns >= 0) {
6204
size_t off = tcg_current_code_size(s);
6205
s->gen_insn_end_off[num_insns] = off;
6207
assert(s->gen_insn_end_off[num_insns] == off);
6210
for (i = 0; i < start_words; ++i) {
6211
s->gen_insn_data[num_insns * start_words + i] =
6212
tcg_get_insn_start_param(op, i);
6215
case INDEX_op_discard:
6216
temp_dead(s, arg_temp(op->args[0]));
6218
case INDEX_op_set_label:
6219
tcg_reg_alloc_bb_end(s, s->reserved_regs);
6220
tcg_out_label(s, arg_label(op->args[0]));
6223
tcg_reg_alloc_call(s, op);
6225
case INDEX_op_exit_tb:
6226
tcg_out_exit_tb(s, op->args[0]);
6228
case INDEX_op_goto_tb:
6229
tcg_out_goto_tb(s, op->args[0]);
6231
case INDEX_op_dup2_vec:
6232
if (tcg_reg_alloc_dup2(s, op)) {
6238
tcg_debug_assert(tcg_op_supported(opc));
6242
tcg_reg_alloc_op(s, op);
6249
if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
6253
if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) {
6257
tcg_debug_assert(num_insns + 1 == s->gen_tb->icount);
6258
s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
6261
#ifdef TCG_TARGET_NEED_LDST_LABELS
6262
i = tcg_out_ldst_finalize(s);
6267
#ifdef TCG_TARGET_NEED_POOL_LABELS
6268
i = tcg_out_pool_finalize(s);
6273
if (!tcg_resolve_relocs(s)) {
6277
#ifndef CONFIG_TCG_INTERPRETER
6279
flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
6280
(uintptr_t)s->code_buf,
6281
tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
6284
return tcg_current_code_size(s);
6287
#ifdef ELF_HOST_MACHINE
6307
struct jit_code_entry {
6308
struct jit_code_entry *next_entry;
6309
struct jit_code_entry *prev_entry;
6310
const void *symfile_addr;
6311
uint64_t symfile_size;
6314
struct jit_descriptor {
6316
uint32_t action_flag;
6317
struct jit_code_entry *relevant_entry;
6318
struct jit_code_entry *first_entry;
6321
void __jit_debug_register_code(void) __attribute__((noinline));
6322
void __jit_debug_register_code(void)
6329
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
6333
static int find_string(const char *strtab, const char *str)
6335
const char *p = strtab + 1;
6338
if (strcmp(p, str) == 0) {
6345
static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size,
6346
const void *debug_frame,
6347
size_t debug_frame_size)
6349
struct __attribute__((packed)) DebugInfo {
6356
uintptr_t cu_low_pc;
6357
uintptr_t cu_high_pc;
6360
uintptr_t fn_low_pc;
6361
uintptr_t fn_high_pc;
6370
struct DebugInfo di;
6375
struct ElfImage *img;
6377
static const struct ElfImage img_template = {
6379
.e_ident[EI_MAG0] = ELFMAG0,
6380
.e_ident[EI_MAG1] = ELFMAG1,
6381
.e_ident[EI_MAG2] = ELFMAG2,
6382
.e_ident[EI_MAG3] = ELFMAG3,
6383
.e_ident[EI_CLASS] = ELF_CLASS,
6384
.e_ident[EI_DATA] = ELF_DATA,
6385
.e_ident[EI_VERSION] = EV_CURRENT,
6387
.e_machine = ELF_HOST_MACHINE,
6388
.e_version = EV_CURRENT,
6389
.e_phoff = offsetof(struct ElfImage, phdr),
6390
.e_shoff = offsetof(struct ElfImage, shdr),
6391
.e_ehsize = sizeof(ElfW(Shdr)),
6392
.e_phentsize = sizeof(ElfW(Phdr)),
6394
.e_shentsize = sizeof(ElfW(Shdr)),
6395
.e_shnum = ARRAY_SIZE(img->shdr),
6396
.e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
6397
#ifdef ELF_HOST_FLAGS
6398
.e_flags = ELF_HOST_FLAGS,
6401
.e_ident[EI_OSABI] = ELF_OSABI,
6409
[0] = { .sh_type = SHT_NULL },
6415
.sh_type = SHT_NOBITS,
6416
.sh_flags = SHF_EXECINSTR | SHF_ALLOC,
6419
.sh_type = SHT_PROGBITS,
6420
.sh_offset = offsetof(struct ElfImage, di),
6421
.sh_size = sizeof(struct DebugInfo),
6424
.sh_type = SHT_PROGBITS,
6425
.sh_offset = offsetof(struct ElfImage, da),
6426
.sh_size = sizeof(img->da),
6429
.sh_type = SHT_PROGBITS,
6430
.sh_offset = sizeof(struct ElfImage),
6433
.sh_type = SHT_SYMTAB,
6434
.sh_offset = offsetof(struct ElfImage, sym),
6435
.sh_size = sizeof(img->sym),
6437
.sh_link = ARRAY_SIZE(img->shdr) - 1,
6438
.sh_entsize = sizeof(ElfW(Sym)),
6441
.sh_type = SHT_STRTAB,
6442
.sh_offset = offsetof(struct ElfImage, str),
6443
.sh_size = sizeof(img->str),
6448
.st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
6453
.len = sizeof(struct DebugInfo) - 4,
6455
.ptr_size = sizeof(void *),
6459
.fn_name = "code_gen_buffer"
6476
.str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
6477
".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
6481
static struct jit_code_entry one_entry;
6483
uintptr_t buf = (uintptr_t)buf_ptr;
6484
size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
6485
DebugFrameHeader *dfh;
6487
img = g_malloc(img_size);
6488
*img = img_template;
6490
img->phdr.p_vaddr = buf;
6491
img->phdr.p_paddr = buf;
6492
img->phdr.p_memsz = buf_size;
6494
img->shdr[1].sh_name = find_string(img->str, ".text");
6495
img->shdr[1].sh_addr = buf;
6496
img->shdr[1].sh_size = buf_size;
6498
img->shdr[2].sh_name = find_string(img->str, ".debug_info");
6499
img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
6501
img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
6502
img->shdr[4].sh_size = debug_frame_size;
6504
img->shdr[5].sh_name = find_string(img->str, ".symtab");
6505
img->shdr[6].sh_name = find_string(img->str, ".strtab");
6507
img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
6508
img->sym[1].st_value = buf;
6509
img->sym[1].st_size = buf_size;
6511
img->di.cu_low_pc = buf;
6512
img->di.cu_high_pc = buf + buf_size;
6513
img->di.fn_low_pc = buf;
6514
img->di.fn_high_pc = buf + buf_size;
6516
dfh = (DebugFrameHeader *)(img + 1);
6517
memcpy(dfh, debug_frame, debug_frame_size);
6518
dfh->fde.func_start = buf;
6519
dfh->fde.func_len = buf_size;
6525
g_autofree char *jit = g_strdup_printf("%s/qemu.jit", g_get_tmp_dir());
6526
FILE *f = fopen(jit, "w+b");
6528
if (fwrite(img, img_size, 1, f) != img_size) {
6536
one_entry.symfile_addr = img;
6537
one_entry.symfile_size = img_size;
6539
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
6540
__jit_debug_descriptor.relevant_entry = &one_entry;
6541
__jit_debug_descriptor.first_entry = &one_entry;
6542
__jit_debug_register_code();
6548
static void tcg_register_jit_int(const void *buf, size_t size,
6549
const void *debug_frame,
6550
size_t debug_frame_size)
6554
void tcg_register_jit(const void *buf, size_t buf_size)
6559
#if !TCG_TARGET_MAYBE_vec
6560
void tcg_expand_vec_op(TCGOpcode o, TCGType t, unsigned e, TCGArg a0, ...)
6562
g_assert_not_reached();