]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/i386-features.h
Update copyright years.
[thirdparty/gcc.git] / gcc / config / i386 / i386-features.h
CommitLineData
99dee823 1/* Copyright (C) 1988-2021 Free Software Foundation, Inc.
2bf6d935
ML
2
3This file is part of GCC.
4
5GCC is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 3, or (at your option)
8any later version.
9
10GCC is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along 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
22enum 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
33enum 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. */
43class xlogue_layout {
44public:
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 const reginfo &get_reginfo (unsigned reg) const
56 {
57 gcc_assert (reg < m_nregs);
58 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 HOST_WIDE_INT get_stack_space_used () const
73 {
74 const struct machine_function *m = cfun->machine;
75 unsigned last_reg = m->call_ms2sysv_extra_regs + MIN_REGS - 1;
76
77 gcc_assert (m->call_ms2sysv_extra_regs <= MAX_EXTRA_REGS);
78 return m_regs[last_reg].offset + STUB_INDEX_OFFSET;
79 }
80
81 /* Returns the offset for the base pointer used by the stub. */
82 HOST_WIDE_INT get_stub_ptr_offset () const
83 {
84 return STUB_INDEX_OFFSET + m_stack_align_off_in;
85 }
86
99b1c316 87 static const class xlogue_layout &get_instance ();
2bf6d935
ML
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
101private:
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
125namespace {
126
127class scalar_chain
128{
129 public:
93cf5515 130 scalar_chain (enum machine_mode, enum machine_mode);
2bf6d935
ML
131 virtual ~scalar_chain ();
132
133 static unsigned max_id;
134
93cf5515
RB
135 /* Scalar mode. */
136 enum machine_mode smode;
137 /* Vector mode. */
138 enum machine_mode vmode;
139
2bf6d935
ML
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 void build (bitmap candidates, unsigned insn_uid);
152 virtual int compute_convert_gain () = 0;
153 int convert ();
154
155 protected:
156 void add_to_queue (unsigned insn_uid);
157 void emit_conversion_insns (rtx insns, rtx_insn *pos);
158
159 private:
160 void add_insn (bitmap candidates, unsigned insn_uid);
161 void analyze_register_chain (bitmap candidates, df_ref ref);
162 virtual void mark_dual_mode_def (df_ref def) = 0;
163 virtual void convert_insn (rtx_insn *insn) = 0;
164 virtual void convert_registers () = 0;
165};
166
93cf5515 167class general_scalar_chain : public scalar_chain
2bf6d935
ML
168{
169 public:
b5a6addb
RB
170 general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_);
171 ~general_scalar_chain ();
2bf6d935
ML
172 int compute_convert_gain ();
173 private:
48a31a09 174 hash_map<rtx, rtx> defs_map;
b5a6addb
RB
175 bitmap insns_conv;
176 unsigned n_sse_to_integer;
177 unsigned n_integer_to_sse;
2bf6d935 178 void mark_dual_mode_def (df_ref def);
2bf6d935
ML
179 void convert_insn (rtx_insn *insn);
180 void convert_op (rtx *op, rtx_insn *insn);
48a31a09 181 void convert_reg (rtx_insn *insn, rtx dst, rtx src);
b5a6addb 182 void make_vector_copies (rtx_insn *, rtx);
2bf6d935
ML
183 void convert_registers ();
184 int vector_const_cost (rtx exp);
185};
186
187class timode_scalar_chain : public scalar_chain
188{
189 public:
93cf5515
RB
190 timode_scalar_chain () : scalar_chain (TImode, V1TImode) {}
191
2bf6d935
ML
192 /* Convert from TImode to V1TImode is always faster. */
193 int compute_convert_gain () { return 1; }
194
195 private:
196 void mark_dual_mode_def (df_ref def);
197 void fix_debug_reg_uses (rtx reg);
198 void convert_insn (rtx_insn *insn);
199 /* We don't convert registers to difference size. */
200 void convert_registers () {}
201};
202
203} // anon namespace
204
205bool ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined);
206int ix86_compare_version_priority (tree decl1, tree decl2);
207tree ix86_generate_version_dispatcher_body (void *node_p);
208tree ix86_get_function_versions_dispatcher (void *decl);
209tree ix86_mangle_decl_assembler_name (tree decl, tree id);
210
211
212#endif /* GCC_I386_FEATURES_H */