Branch data Line data Source code
1 : : /* Copyright (C) 1988-2024 Free Software Foundation, Inc.
2 : :
3 : : This file is part of GCC.
4 : :
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)
8 : : any later version.
9 : :
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.
14 : :
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/>. */
18 : :
19 : : #ifndef GCC_I386_FEATURES_H
20 : : #define GCC_I386_FEATURES_H
21 : :
22 : : enum xlogue_stub {
23 : : XLOGUE_STUB_SAVE,
24 : : XLOGUE_STUB_RESTORE,
25 : : XLOGUE_STUB_RESTORE_TAIL,
26 : : XLOGUE_STUB_SAVE_HFP,
27 : : XLOGUE_STUB_RESTORE_HFP,
28 : : XLOGUE_STUB_RESTORE_HFP_TAIL,
29 : :
30 : : XLOGUE_STUB_COUNT
31 : : };
32 : :
33 : : enum xlogue_stub_sets {
34 : : XLOGUE_SET_ALIGNED,
35 : : XLOGUE_SET_ALIGNED_PLUS_8,
36 : : XLOGUE_SET_HFP_ALIGNED_OR_REALIGN,
37 : : XLOGUE_SET_HFP_ALIGNED_PLUS_8,
38 : :
39 : : XLOGUE_SET_COUNT
40 : : };
41 : :
42 : : /* Register save/restore layout used by out-of-line stubs. */
43 : : class xlogue_layout {
44 : : public:
45 : : struct reginfo
46 : : {
47 : : unsigned regno;
48 : : HOST_WIDE_INT offset; /* Offset used by stub base pointer (rax or
49 : : rsi) to where each register is stored. */
50 : : };
51 : :
52 : : unsigned get_nregs () const {return m_nregs;}
53 : : HOST_WIDE_INT get_stack_align_off_in () const {return m_stack_align_off_in;}
54 : :
55 : 194816 : const reginfo &get_reginfo (unsigned reg) const
56 : : {
57 : 194816 : gcc_assert (reg < m_nregs);
58 : 194816 : return m_regs[reg];
59 : : }
60 : :
61 : : static const char *get_stub_name (enum xlogue_stub stub,
62 : : unsigned n_extra_args);
63 : :
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);
69 : :
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 : 38105 : HOST_WIDE_INT get_stack_space_used () const
73 : : {
74 : 38105 : const struct machine_function *m = cfun->machine;
75 : 38105 : unsigned last_reg = m->call_ms2sysv_extra_regs + MIN_REGS - 1;
76 : :
77 : 38105 : gcc_assert (m->call_ms2sysv_extra_regs <= MAX_EXTRA_REGS);
78 : 38105 : return m_regs[last_reg].offset + STUB_INDEX_OFFSET;
79 : : }
80 : :
81 : : /* Returns the offset for the base pointer used by the stub. */
82 : 14666 : HOST_WIDE_INT get_stub_ptr_offset () const
83 : : {
84 : 14666 : return STUB_INDEX_OFFSET + m_stack_align_off_in;
85 : : }
86 : :
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);
90 : :
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];
100 : :
101 : : private:
102 : : xlogue_layout ();
103 : : xlogue_layout (HOST_WIDE_INT stack_align_off_in, bool hfp);
104 : : xlogue_layout (const xlogue_layout &);
105 : :
106 : : /* True if hard frame pointer is used. */
107 : : bool m_hfp;
108 : :
109 : : /* Max number of register this layout manages. */
110 : : unsigned m_nregs;
111 : :
112 : : /* Incoming offset from 16-byte alignment. */
113 : : HOST_WIDE_INT m_stack_align_off_in;
114 : :
115 : : /* Register order and offsets. */
116 : : struct reginfo m_regs[MAX_REGS];
117 : :
118 : : /* Lazy-inited cache of symbol names for stubs. */
119 : : static char s_stub_names[2][XLOGUE_STUB_COUNT][VARIANT_COUNT]
120 : : [STUB_NAME_MAX_LEN];
121 : :
122 : : static const xlogue_layout s_instances[XLOGUE_SET_COUNT];
123 : : };
124 : :
125 : : namespace {
126 : :
127 : : class scalar_chain
128 : : {
129 : : public:
130 : : scalar_chain (enum machine_mode, enum machine_mode);
131 : : virtual ~scalar_chain ();
132 : :
133 : : static unsigned max_id;
134 : :
135 : : /* Scalar mode. */
136 : : enum machine_mode smode;
137 : : /* Vector mode. */
138 : : enum machine_mode vmode;
139 : :
140 : : /* ID of a chain. */
141 : : unsigned int chain_id;
142 : : /* A queue of instructions to be included into a chain. */
143 : : bitmap queue;
144 : : /* Instructions included into a chain. */
145 : : bitmap insns;
146 : : /* All registers defined by a chain. */
147 : : bitmap defs;
148 : : /* Registers used in both vector and sclar modes. */
149 : : bitmap defs_conv;
150 : :
151 : : /* Limit on chain discovery. */
152 : : unsigned max_visits;
153 : :
154 : : bitmap insns_conv;
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;
159 : :
160 : : bool build (bitmap candidates, unsigned insn_uid, bitmap disallowed);
161 : : virtual int compute_convert_gain () = 0;
162 : : int convert ();
163 : :
164 : : protected:
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);
174 : :
175 : : private:
176 : : bool add_insn (bitmap candidates, unsigned insn_uid, bitmap disallowed);
177 : : bool analyze_register_chain (bitmap candidates, df_ref ref,
178 : : bitmap disallowed);
179 : : virtual void convert_insn (rtx_insn *insn) = 0;
180 : : };
181 : :
182 : : class general_scalar_chain : public scalar_chain
183 : : {
184 : : public:
185 : 5640702 : general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_)
186 : 5640702 : : scalar_chain (smode_, vmode_) {}
187 : : int compute_convert_gain () final override;
188 : :
189 : : private:
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);
193 : : };
194 : :
195 : : class timode_scalar_chain : public scalar_chain
196 : : {
197 : : public:
198 : 431489 : timode_scalar_chain () : scalar_chain (TImode, V1TImode) {}
199 : : int compute_convert_gain () final override;
200 : :
201 : : private:
202 : : void fix_debug_reg_uses (rtx reg);
203 : : void convert_insn (rtx_insn *insn) final override;
204 : : };
205 : :
206 : : } // anon namespace
207 : :
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);
214 : :
215 : :
216 : : #endif /* GCC_I386_FEATURES_H */
|