1 /* Copyright (C) 1988-2024 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 GCC is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
19 #ifndef GCC_I386_FEATURES_H
20 #define GCC_I386_FEATURES_H
25 XLOGUE_STUB_RESTORE_TAIL
,
27 XLOGUE_STUB_RESTORE_HFP
,
28 XLOGUE_STUB_RESTORE_HFP_TAIL
,
33 enum xlogue_stub_sets
{
35 XLOGUE_SET_ALIGNED_PLUS_8
,
36 XLOGUE_SET_HFP_ALIGNED_OR_REALIGN
,
37 XLOGUE_SET_HFP_ALIGNED_PLUS_8
,
42 /* Register save/restore layout used by out-of-line stubs. */
48 HOST_WIDE_INT offset
; /* Offset used by stub base pointer (rax or
49 rsi) to where each register is stored. */
52 unsigned get_nregs () const {return m_nregs
;}
53 HOST_WIDE_INT
get_stack_align_off_in () const {return m_stack_align_off_in
;}
55 const reginfo
&get_reginfo (unsigned reg
) const
57 gcc_assert (reg
< m_nregs
);
61 static const char *get_stub_name (enum xlogue_stub stub
,
62 unsigned n_extra_args
);
64 /* Returns an rtx for the stub's symbol based upon
65 1.) the specified stub (save, restore or restore_ret) and
66 2.) the value of cfun->machine->call_ms2sysv_extra_regs and
67 3.) rather or not stack alignment is being performed. */
68 static rtx
get_stub_rtx (enum xlogue_stub stub
);
70 /* Returns the amount of stack space (including padding) that the stub
71 needs to store registers based upon data in the machine_function. */
72 HOST_WIDE_INT
get_stack_space_used () const
74 const struct machine_function
*m
= cfun
->machine
;
75 unsigned last_reg
= m
->call_ms2sysv_extra_regs
+ MIN_REGS
- 1;
77 gcc_assert (m
->call_ms2sysv_extra_regs
<= MAX_EXTRA_REGS
);
78 return m_regs
[last_reg
].offset
+ STUB_INDEX_OFFSET
;
81 /* Returns the offset for the base pointer used by the stub. */
82 HOST_WIDE_INT
get_stub_ptr_offset () const
84 return STUB_INDEX_OFFSET
+ m_stack_align_off_in
;
87 static const class xlogue_layout
&get_instance ();
88 static unsigned count_stub_managed_regs ();
89 static bool is_stub_managed_reg (unsigned regno
, unsigned count
);
91 static const HOST_WIDE_INT STUB_INDEX_OFFSET
= 0x70;
92 static const unsigned MIN_REGS
= NUM_X86_64_MS_CLOBBERED_REGS
;
93 static const unsigned MAX_REGS
= 18;
94 static const unsigned MAX_EXTRA_REGS
= MAX_REGS
- MIN_REGS
;
95 static const unsigned VARIANT_COUNT
= MAX_EXTRA_REGS
+ 1;
96 static const unsigned STUB_NAME_MAX_LEN
= 20;
97 static const char * const STUB_BASE_NAMES
[XLOGUE_STUB_COUNT
];
98 static const unsigned REG_ORDER
[MAX_REGS
];
99 static const unsigned REG_ORDER_REALIGN
[MAX_REGS
];
103 xlogue_layout (HOST_WIDE_INT stack_align_off_in
, bool hfp
);
104 xlogue_layout (const xlogue_layout
&);
106 /* True if hard frame pointer is used. */
109 /* Max number of register this layout manages. */
112 /* Incoming offset from 16-byte alignment. */
113 HOST_WIDE_INT m_stack_align_off_in
;
115 /* Register order and offsets. */
116 struct reginfo m_regs
[MAX_REGS
];
118 /* Lazy-inited cache of symbol names for stubs. */
119 static char s_stub_names
[2][XLOGUE_STUB_COUNT
][VARIANT_COUNT
]
122 static const xlogue_layout s_instances
[XLOGUE_SET_COUNT
];
130 scalar_chain (enum machine_mode
, enum machine_mode
);
131 virtual ~scalar_chain ();
133 static unsigned max_id
;
136 enum machine_mode smode
;
138 enum machine_mode vmode
;
141 unsigned int chain_id
;
142 /* A queue of instructions to be included into a chain. */
144 /* Instructions included into a chain. */
146 /* All registers defined by a chain. */
148 /* Registers used in both vector and sclar modes. */
151 /* Limit on chain discovery. */
155 hash_map
<rtx
, rtx
> defs_map
;
156 unsigned n_sse_to_integer
;
157 unsigned n_integer_to_sse
;
158 auto_vec
<rtx_insn
*> control_flow_insns
;
160 bool build (bitmap candidates
, unsigned insn_uid
, bitmap disallowed
);
161 virtual int compute_convert_gain () = 0;
165 void add_to_queue (unsigned insn_uid
);
166 void emit_conversion_insns (rtx insns
, rtx_insn
*pos
);
167 rtx
convert_compare (rtx op1
, rtx op2
, rtx_insn
*insn
);
168 void mark_dual_mode_def (df_ref def
);
169 void convert_reg (rtx_insn
*insn
, rtx dst
, rtx src
);
170 void convert_insn_common (rtx_insn
*insn
);
171 void make_vector_copies (rtx_insn
*, rtx
);
172 void convert_registers ();
173 void convert_op (rtx
*op
, rtx_insn
*insn
);
176 bool add_insn (bitmap candidates
, unsigned insn_uid
, bitmap disallowed
);
177 bool analyze_register_chain (bitmap candidates
, df_ref ref
,
179 virtual void convert_insn (rtx_insn
*insn
) = 0;
182 class general_scalar_chain
: public scalar_chain
185 general_scalar_chain (enum machine_mode smode_
, enum machine_mode vmode_
)
186 : scalar_chain (smode_
, vmode_
) {}
187 int compute_convert_gain () final override
;
190 void convert_insn (rtx_insn
*insn
) final override
;
191 int vector_const_cost (rtx exp
);
192 rtx
convert_rotate (enum rtx_code
, rtx op0
, rtx op1
, rtx_insn
*insn
);
195 class timode_scalar_chain
: public scalar_chain
198 timode_scalar_chain () : scalar_chain (TImode
, V1TImode
) {}
199 int compute_convert_gain () final override
;
202 void fix_debug_reg_uses (rtx reg
);
203 void convert_insn (rtx_insn
*insn
) final override
;
208 bool ix86_save_reg (unsigned int regno
, bool maybe_eh_return
,
209 bool ignore_outlined
);
210 int ix86_compare_version_priority (tree decl1
, tree decl2
);
211 tree
ix86_generate_version_dispatcher_body (void *node_p
);
212 tree
ix86_get_function_versions_dispatcher (void *decl
);
213 tree
ix86_mangle_decl_assembler_name (tree decl
, tree id
);
216 #endif /* GCC_I386_FEATURES_H */