annotate gcc/config/aarch64/aarch64-builtins.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Builtins' description for AArch64 SIMD architecture.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2011-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by ARM Ltd.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but
kono
parents:
diff changeset
13 WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
kono
parents:
diff changeset
15 General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
21 #define IN_TARGET_CODE 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
22
111
kono
parents:
diff changeset
23 #include "config.h"
kono
parents:
diff changeset
24 #include "system.h"
kono
parents:
diff changeset
25 #include "coretypes.h"
kono
parents:
diff changeset
26 #include "tm.h"
kono
parents:
diff changeset
27 #include "function.h"
kono
parents:
diff changeset
28 #include "basic-block.h"
kono
parents:
diff changeset
29 #include "rtl.h"
kono
parents:
diff changeset
30 #include "tree.h"
kono
parents:
diff changeset
31 #include "gimple.h"
kono
parents:
diff changeset
32 #include "memmodel.h"
kono
parents:
diff changeset
33 #include "tm_p.h"
kono
parents:
diff changeset
34 #include "expmed.h"
kono
parents:
diff changeset
35 #include "optabs.h"
kono
parents:
diff changeset
36 #include "recog.h"
kono
parents:
diff changeset
37 #include "diagnostic-core.h"
kono
parents:
diff changeset
38 #include "fold-const.h"
kono
parents:
diff changeset
39 #include "stor-layout.h"
kono
parents:
diff changeset
40 #include "explow.h"
kono
parents:
diff changeset
41 #include "expr.h"
kono
parents:
diff changeset
42 #include "langhooks.h"
kono
parents:
diff changeset
43 #include "gimple-iterator.h"
kono
parents:
diff changeset
44 #include "case-cfn-macros.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
45 #include "emit-rtl.h"
111
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 #define v8qi_UP E_V8QImode
kono
parents:
diff changeset
48 #define v4hi_UP E_V4HImode
kono
parents:
diff changeset
49 #define v4hf_UP E_V4HFmode
kono
parents:
diff changeset
50 #define v2si_UP E_V2SImode
kono
parents:
diff changeset
51 #define v2sf_UP E_V2SFmode
kono
parents:
diff changeset
52 #define v1df_UP E_V1DFmode
kono
parents:
diff changeset
53 #define di_UP E_DImode
kono
parents:
diff changeset
54 #define df_UP E_DFmode
kono
parents:
diff changeset
55 #define v16qi_UP E_V16QImode
kono
parents:
diff changeset
56 #define v8hi_UP E_V8HImode
kono
parents:
diff changeset
57 #define v8hf_UP E_V8HFmode
kono
parents:
diff changeset
58 #define v4si_UP E_V4SImode
kono
parents:
diff changeset
59 #define v4sf_UP E_V4SFmode
kono
parents:
diff changeset
60 #define v2di_UP E_V2DImode
kono
parents:
diff changeset
61 #define v2df_UP E_V2DFmode
kono
parents:
diff changeset
62 #define ti_UP E_TImode
kono
parents:
diff changeset
63 #define oi_UP E_OImode
kono
parents:
diff changeset
64 #define ci_UP E_CImode
kono
parents:
diff changeset
65 #define xi_UP E_XImode
kono
parents:
diff changeset
66 #define si_UP E_SImode
kono
parents:
diff changeset
67 #define sf_UP E_SFmode
kono
parents:
diff changeset
68 #define hi_UP E_HImode
kono
parents:
diff changeset
69 #define hf_UP E_HFmode
kono
parents:
diff changeset
70 #define qi_UP E_QImode
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
71 #define bf_UP E_BFmode
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
72 #define v4bf_UP E_V4BFmode
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
73 #define v8bf_UP E_V8BFmode
111
kono
parents:
diff changeset
74 #define UP(X) X##_UP
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 #define SIMD_MAX_BUILTIN_ARGS 5
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 enum aarch64_type_qualifiers
kono
parents:
diff changeset
79 {
kono
parents:
diff changeset
80 /* T foo. */
kono
parents:
diff changeset
81 qualifier_none = 0x0,
kono
parents:
diff changeset
82 /* unsigned T foo. */
kono
parents:
diff changeset
83 qualifier_unsigned = 0x1, /* 1 << 0 */
kono
parents:
diff changeset
84 /* const T foo. */
kono
parents:
diff changeset
85 qualifier_const = 0x2, /* 1 << 1 */
kono
parents:
diff changeset
86 /* T *foo. */
kono
parents:
diff changeset
87 qualifier_pointer = 0x4, /* 1 << 2 */
kono
parents:
diff changeset
88 /* Used when expanding arguments if an operand could
kono
parents:
diff changeset
89 be an immediate. */
kono
parents:
diff changeset
90 qualifier_immediate = 0x8, /* 1 << 3 */
kono
parents:
diff changeset
91 qualifier_maybe_immediate = 0x10, /* 1 << 4 */
kono
parents:
diff changeset
92 /* void foo (...). */
kono
parents:
diff changeset
93 qualifier_void = 0x20, /* 1 << 5 */
kono
parents:
diff changeset
94 /* Some patterns may have internal operands, this qualifier is an
kono
parents:
diff changeset
95 instruction to the initialisation code to skip this operand. */
kono
parents:
diff changeset
96 qualifier_internal = 0x40, /* 1 << 6 */
kono
parents:
diff changeset
97 /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
kono
parents:
diff changeset
98 rather than using the type of the operand. */
kono
parents:
diff changeset
99 qualifier_map_mode = 0x80, /* 1 << 7 */
kono
parents:
diff changeset
100 /* qualifier_pointer | qualifier_map_mode */
kono
parents:
diff changeset
101 qualifier_pointer_map_mode = 0x84,
kono
parents:
diff changeset
102 /* qualifier_const | qualifier_pointer | qualifier_map_mode */
kono
parents:
diff changeset
103 qualifier_const_pointer_map_mode = 0x86,
kono
parents:
diff changeset
104 /* Polynomial types. */
kono
parents:
diff changeset
105 qualifier_poly = 0x100,
kono
parents:
diff changeset
106 /* Lane indices - must be in range, and flipped for bigendian. */
kono
parents:
diff changeset
107 qualifier_lane_index = 0x200,
kono
parents:
diff changeset
108 /* Lane indices for single lane structure loads and stores. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
109 qualifier_struct_load_store_lane_index = 0x400,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
110 /* Lane indices selected in pairs. - must be in range, and flipped for
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
111 bigendian. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
112 qualifier_lane_pair_index = 0x800,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
113 /* Lane indices selected in quadtuplets. - must be in range, and flipped for
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
114 bigendian. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
115 qualifier_lane_quadtup_index = 0x1000,
111
kono
parents:
diff changeset
116 };
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 typedef struct
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 const char *name;
kono
parents:
diff changeset
121 machine_mode mode;
kono
parents:
diff changeset
122 const enum insn_code code;
kono
parents:
diff changeset
123 unsigned int fcode;
kono
parents:
diff changeset
124 enum aarch64_type_qualifiers *qualifiers;
kono
parents:
diff changeset
125 } aarch64_simd_builtin_datum;
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
128 aarch64_types_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
129 = { qualifier_none, qualifier_none };
kono
parents:
diff changeset
130 #define TYPES_UNOP (aarch64_types_unop_qualifiers)
kono
parents:
diff changeset
131 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
132 aarch64_types_unopu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
133 = { qualifier_unsigned, qualifier_unsigned };
kono
parents:
diff changeset
134 #define TYPES_UNOPU (aarch64_types_unopu_qualifiers)
kono
parents:
diff changeset
135 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
136 aarch64_types_unopus_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
137 = { qualifier_unsigned, qualifier_none };
kono
parents:
diff changeset
138 #define TYPES_UNOPUS (aarch64_types_unopus_qualifiers)
kono
parents:
diff changeset
139 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
140 aarch64_types_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
141 = { qualifier_none, qualifier_none, qualifier_maybe_immediate };
kono
parents:
diff changeset
142 #define TYPES_BINOP (aarch64_types_binop_qualifiers)
kono
parents:
diff changeset
143 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
144 aarch64_types_binopu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
145 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned };
kono
parents:
diff changeset
146 #define TYPES_BINOPU (aarch64_types_binopu_qualifiers)
kono
parents:
diff changeset
147 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
148 aarch64_types_binop_uus_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
149 = { qualifier_unsigned, qualifier_unsigned, qualifier_none };
kono
parents:
diff changeset
150 #define TYPES_BINOP_UUS (aarch64_types_binop_uus_qualifiers)
kono
parents:
diff changeset
151 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
152 aarch64_types_binop_ssu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
153 = { qualifier_none, qualifier_none, qualifier_unsigned };
kono
parents:
diff changeset
154 #define TYPES_BINOP_SSU (aarch64_types_binop_ssu_qualifiers)
kono
parents:
diff changeset
155 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
156 aarch64_types_binop_uss_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
157 = { qualifier_unsigned, qualifier_none, qualifier_none };
kono
parents:
diff changeset
158 #define TYPES_BINOP_USS (aarch64_types_binop_uss_qualifiers)
kono
parents:
diff changeset
159 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
160 aarch64_types_binopp_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
161 = { qualifier_poly, qualifier_poly, qualifier_poly };
kono
parents:
diff changeset
162 #define TYPES_BINOPP (aarch64_types_binopp_qualifiers)
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
165 aarch64_types_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
166 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
kono
parents:
diff changeset
167 #define TYPES_TERNOP (aarch64_types_ternop_qualifiers)
kono
parents:
diff changeset
168 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
169 aarch64_types_ternop_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
170 = { qualifier_none, qualifier_none, qualifier_none, qualifier_lane_index };
kono
parents:
diff changeset
171 #define TYPES_TERNOP_LANE (aarch64_types_ternop_lane_qualifiers)
kono
parents:
diff changeset
172 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
173 aarch64_types_ternopu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
174 = { qualifier_unsigned, qualifier_unsigned,
kono
parents:
diff changeset
175 qualifier_unsigned, qualifier_unsigned };
kono
parents:
diff changeset
176 #define TYPES_TERNOPU (aarch64_types_ternopu_qualifiers)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177 static enum aarch64_type_qualifiers
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 aarch64_types_ternopu_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 = { qualifier_unsigned, qualifier_unsigned,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180 qualifier_unsigned, qualifier_immediate };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 #define TYPES_TERNOPUI (aarch64_types_ternopu_imm_qualifiers)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
182 static enum aarch64_type_qualifiers
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
183 aarch64_types_ternop_ssus_qualifiers[SIMD_MAX_BUILTIN_ARGS]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
184 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_none };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
185 #define TYPES_TERNOP_SSUS (aarch64_types_ternop_ssus_qualifiers)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186
111
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 static enum aarch64_type_qualifiers
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
189 aarch64_types_quadop_lane_pair_qualifiers[SIMD_MAX_BUILTIN_ARGS]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
190 = { qualifier_none, qualifier_none, qualifier_none,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
191 qualifier_none, qualifier_lane_pair_index };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
192 #define TYPES_QUADOP_LANE_PAIR (aarch64_types_quadop_lane_pair_qualifiers)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
193 static enum aarch64_type_qualifiers
111
kono
parents:
diff changeset
194 aarch64_types_quadop_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
195 = { qualifier_none, qualifier_none, qualifier_none,
kono
parents:
diff changeset
196 qualifier_none, qualifier_lane_index };
kono
parents:
diff changeset
197 #define TYPES_QUADOP_LANE (aarch64_types_quadop_lane_qualifiers)
kono
parents:
diff changeset
198 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
199 aarch64_types_quadopu_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
200 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
kono
parents:
diff changeset
201 qualifier_unsigned, qualifier_lane_index };
kono
parents:
diff changeset
202 #define TYPES_QUADOPU_LANE (aarch64_types_quadopu_lane_qualifiers)
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 static enum aarch64_type_qualifiers
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
205 aarch64_types_quadopssus_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
206 = { qualifier_none, qualifier_none, qualifier_unsigned,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
207 qualifier_none, qualifier_lane_quadtup_index };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
208 #define TYPES_QUADOPSSUS_LANE_QUADTUP \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
209 (aarch64_types_quadopssus_lane_quadtup_qualifiers)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
210 static enum aarch64_type_qualifiers
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
211 aarch64_types_quadopsssu_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
212 = { qualifier_none, qualifier_none, qualifier_none,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
213 qualifier_unsigned, qualifier_lane_quadtup_index };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
214 #define TYPES_QUADOPSSSU_LANE_QUADTUP \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
215 (aarch64_types_quadopsssu_lane_quadtup_qualifiers)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
216
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
217 static enum aarch64_type_qualifiers
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218 aarch64_types_quadopu_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 qualifier_unsigned, qualifier_immediate };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 #define TYPES_QUADOPUI (aarch64_types_quadopu_imm_qualifiers)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 static enum aarch64_type_qualifiers
111
kono
parents:
diff changeset
224 aarch64_types_binop_imm_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
225 = { qualifier_poly, qualifier_none, qualifier_immediate };
kono
parents:
diff changeset
226 #define TYPES_GETREGP (aarch64_types_binop_imm_p_qualifiers)
kono
parents:
diff changeset
227 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
228 aarch64_types_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
229 = { qualifier_none, qualifier_none, qualifier_immediate };
kono
parents:
diff changeset
230 #define TYPES_GETREG (aarch64_types_binop_imm_qualifiers)
kono
parents:
diff changeset
231 #define TYPES_SHIFTIMM (aarch64_types_binop_imm_qualifiers)
kono
parents:
diff changeset
232 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
233 aarch64_types_shift_to_unsigned_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
234 = { qualifier_unsigned, qualifier_none, qualifier_immediate };
kono
parents:
diff changeset
235 #define TYPES_SHIFTIMM_USS (aarch64_types_shift_to_unsigned_qualifiers)
kono
parents:
diff changeset
236 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
237 aarch64_types_fcvt_from_unsigned_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
238 = { qualifier_none, qualifier_unsigned, qualifier_immediate };
kono
parents:
diff changeset
239 #define TYPES_FCVTIMM_SUS (aarch64_types_fcvt_from_unsigned_qualifiers)
kono
parents:
diff changeset
240 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
241 aarch64_types_unsigned_shift_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
242 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate };
kono
parents:
diff changeset
243 #define TYPES_USHIFTIMM (aarch64_types_unsigned_shift_qualifiers)
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
246 aarch64_types_ternop_s_imm_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
247 = { qualifier_none, qualifier_none, qualifier_poly, qualifier_immediate};
kono
parents:
diff changeset
248 #define TYPES_SETREGP (aarch64_types_ternop_s_imm_p_qualifiers)
kono
parents:
diff changeset
249 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
250 aarch64_types_ternop_s_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
251 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate};
kono
parents:
diff changeset
252 #define TYPES_SETREG (aarch64_types_ternop_s_imm_qualifiers)
kono
parents:
diff changeset
253 #define TYPES_SHIFTINSERT (aarch64_types_ternop_s_imm_qualifiers)
kono
parents:
diff changeset
254 #define TYPES_SHIFTACC (aarch64_types_ternop_s_imm_qualifiers)
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
257 aarch64_types_ternop_p_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
258 = { qualifier_poly, qualifier_poly, qualifier_poly, qualifier_immediate};
kono
parents:
diff changeset
259 #define TYPES_SHIFTINSERTP (aarch64_types_ternop_p_imm_qualifiers)
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
262 aarch64_types_unsigned_shiftacc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
263 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
kono
parents:
diff changeset
264 qualifier_immediate };
kono
parents:
diff changeset
265 #define TYPES_USHIFTACC (aarch64_types_unsigned_shiftacc_qualifiers)
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
269 aarch64_types_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
270 = { qualifier_none, qualifier_none, qualifier_none };
kono
parents:
diff changeset
271 #define TYPES_COMBINE (aarch64_types_combine_qualifiers)
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
274 aarch64_types_combine_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
275 = { qualifier_poly, qualifier_poly, qualifier_poly };
kono
parents:
diff changeset
276 #define TYPES_COMBINEP (aarch64_types_combine_p_qualifiers)
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
279 aarch64_types_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
280 = { qualifier_none, qualifier_const_pointer_map_mode };
kono
parents:
diff changeset
281 #define TYPES_LOAD1 (aarch64_types_load1_qualifiers)
kono
parents:
diff changeset
282 #define TYPES_LOADSTRUCT (aarch64_types_load1_qualifiers)
kono
parents:
diff changeset
283 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
284 aarch64_types_loadstruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
285 = { qualifier_none, qualifier_const_pointer_map_mode,
kono
parents:
diff changeset
286 qualifier_none, qualifier_struct_load_store_lane_index };
kono
parents:
diff changeset
287 #define TYPES_LOADSTRUCT_LANE (aarch64_types_loadstruct_lane_qualifiers)
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
290 aarch64_types_bsl_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
291 = { qualifier_poly, qualifier_unsigned,
kono
parents:
diff changeset
292 qualifier_poly, qualifier_poly };
kono
parents:
diff changeset
293 #define TYPES_BSL_P (aarch64_types_bsl_p_qualifiers)
kono
parents:
diff changeset
294 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
295 aarch64_types_bsl_s_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
296 = { qualifier_none, qualifier_unsigned,
kono
parents:
diff changeset
297 qualifier_none, qualifier_none };
kono
parents:
diff changeset
298 #define TYPES_BSL_S (aarch64_types_bsl_s_qualifiers)
kono
parents:
diff changeset
299 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
300 aarch64_types_bsl_u_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
301 = { qualifier_unsigned, qualifier_unsigned,
kono
parents:
diff changeset
302 qualifier_unsigned, qualifier_unsigned };
kono
parents:
diff changeset
303 #define TYPES_BSL_U (aarch64_types_bsl_u_qualifiers)
kono
parents:
diff changeset
304
kono
parents:
diff changeset
305 /* The first argument (return type) of a store should be void type,
kono
parents:
diff changeset
306 which we represent with qualifier_void. Their first operand will be
kono
parents:
diff changeset
307 a DImode pointer to the location to store to, so we must use
kono
parents:
diff changeset
308 qualifier_map_mode | qualifier_pointer to build a pointer to the
kono
parents:
diff changeset
309 element type of the vector. */
kono
parents:
diff changeset
310 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
311 aarch64_types_store1_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
312 = { qualifier_void, qualifier_pointer_map_mode, qualifier_poly };
kono
parents:
diff changeset
313 #define TYPES_STORE1P (aarch64_types_store1_p_qualifiers)
kono
parents:
diff changeset
314 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
315 aarch64_types_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
316 = { qualifier_void, qualifier_pointer_map_mode, qualifier_none };
kono
parents:
diff changeset
317 #define TYPES_STORE1 (aarch64_types_store1_qualifiers)
kono
parents:
diff changeset
318 #define TYPES_STORESTRUCT (aarch64_types_store1_qualifiers)
kono
parents:
diff changeset
319 static enum aarch64_type_qualifiers
kono
parents:
diff changeset
320 aarch64_types_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
kono
parents:
diff changeset
321 = { qualifier_void, qualifier_pointer_map_mode,
kono
parents:
diff changeset
322 qualifier_none, qualifier_struct_load_store_lane_index };
kono
parents:
diff changeset
323 #define TYPES_STORESTRUCT_LANE (aarch64_types_storestruct_lane_qualifiers)
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 #define CF0(N, X) CODE_FOR_aarch64_##N##X
kono
parents:
diff changeset
326 #define CF1(N, X) CODE_FOR_##N##X##1
kono
parents:
diff changeset
327 #define CF2(N, X) CODE_FOR_##N##X##2
kono
parents:
diff changeset
328 #define CF3(N, X) CODE_FOR_##N##X##3
kono
parents:
diff changeset
329 #define CF4(N, X) CODE_FOR_##N##X##4
kono
parents:
diff changeset
330 #define CF10(N, X) CODE_FOR_##N##X
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 #define VAR1(T, N, MAP, A) \
kono
parents:
diff changeset
333 {#N #A, UP (A), CF##MAP (N, A), 0, TYPES_##T},
kono
parents:
diff changeset
334 #define VAR2(T, N, MAP, A, B) \
kono
parents:
diff changeset
335 VAR1 (T, N, MAP, A) \
kono
parents:
diff changeset
336 VAR1 (T, N, MAP, B)
kono
parents:
diff changeset
337 #define VAR3(T, N, MAP, A, B, C) \
kono
parents:
diff changeset
338 VAR2 (T, N, MAP, A, B) \
kono
parents:
diff changeset
339 VAR1 (T, N, MAP, C)
kono
parents:
diff changeset
340 #define VAR4(T, N, MAP, A, B, C, D) \
kono
parents:
diff changeset
341 VAR3 (T, N, MAP, A, B, C) \
kono
parents:
diff changeset
342 VAR1 (T, N, MAP, D)
kono
parents:
diff changeset
343 #define VAR5(T, N, MAP, A, B, C, D, E) \
kono
parents:
diff changeset
344 VAR4 (T, N, MAP, A, B, C, D) \
kono
parents:
diff changeset
345 VAR1 (T, N, MAP, E)
kono
parents:
diff changeset
346 #define VAR6(T, N, MAP, A, B, C, D, E, F) \
kono
parents:
diff changeset
347 VAR5 (T, N, MAP, A, B, C, D, E) \
kono
parents:
diff changeset
348 VAR1 (T, N, MAP, F)
kono
parents:
diff changeset
349 #define VAR7(T, N, MAP, A, B, C, D, E, F, G) \
kono
parents:
diff changeset
350 VAR6 (T, N, MAP, A, B, C, D, E, F) \
kono
parents:
diff changeset
351 VAR1 (T, N, MAP, G)
kono
parents:
diff changeset
352 #define VAR8(T, N, MAP, A, B, C, D, E, F, G, H) \
kono
parents:
diff changeset
353 VAR7 (T, N, MAP, A, B, C, D, E, F, G) \
kono
parents:
diff changeset
354 VAR1 (T, N, MAP, H)
kono
parents:
diff changeset
355 #define VAR9(T, N, MAP, A, B, C, D, E, F, G, H, I) \
kono
parents:
diff changeset
356 VAR8 (T, N, MAP, A, B, C, D, E, F, G, H) \
kono
parents:
diff changeset
357 VAR1 (T, N, MAP, I)
kono
parents:
diff changeset
358 #define VAR10(T, N, MAP, A, B, C, D, E, F, G, H, I, J) \
kono
parents:
diff changeset
359 VAR9 (T, N, MAP, A, B, C, D, E, F, G, H, I) \
kono
parents:
diff changeset
360 VAR1 (T, N, MAP, J)
kono
parents:
diff changeset
361 #define VAR11(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K) \
kono
parents:
diff changeset
362 VAR10 (T, N, MAP, A, B, C, D, E, F, G, H, I, J) \
kono
parents:
diff changeset
363 VAR1 (T, N, MAP, K)
kono
parents:
diff changeset
364 #define VAR12(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K, L) \
kono
parents:
diff changeset
365 VAR11 (T, N, MAP, A, B, C, D, E, F, G, H, I, J, K) \
kono
parents:
diff changeset
366 VAR1 (T, N, MAP, L)
kono
parents:
diff changeset
367 #define VAR13(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K, L, M) \
kono
parents:
diff changeset
368 VAR12 (T, N, MAP, A, B, C, D, E, F, G, H, I, J, K, L) \
kono
parents:
diff changeset
369 VAR1 (T, N, MAP, M)
kono
parents:
diff changeset
370 #define VAR14(T, X, MAP, A, B, C, D, E, F, G, H, I, J, K, L, M, N) \
kono
parents:
diff changeset
371 VAR13 (T, X, MAP, A, B, C, D, E, F, G, H, I, J, K, L, M) \
kono
parents:
diff changeset
372 VAR1 (T, X, MAP, N)
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 #include "aarch64-builtin-iterators.h"
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = {
kono
parents:
diff changeset
377 #include "aarch64-simd-builtins.def"
kono
parents:
diff changeset
378 };
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 /* There's only 8 CRC32 builtins. Probably not worth their own .def file. */
kono
parents:
diff changeset
381 #define AARCH64_CRC32_BUILTINS \
kono
parents:
diff changeset
382 CRC32_BUILTIN (crc32b, QI) \
kono
parents:
diff changeset
383 CRC32_BUILTIN (crc32h, HI) \
kono
parents:
diff changeset
384 CRC32_BUILTIN (crc32w, SI) \
kono
parents:
diff changeset
385 CRC32_BUILTIN (crc32x, DI) \
kono
parents:
diff changeset
386 CRC32_BUILTIN (crc32cb, QI) \
kono
parents:
diff changeset
387 CRC32_BUILTIN (crc32ch, HI) \
kono
parents:
diff changeset
388 CRC32_BUILTIN (crc32cw, SI) \
kono
parents:
diff changeset
389 CRC32_BUILTIN (crc32cx, DI)
kono
parents:
diff changeset
390
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
391 /* The next 8 FCMLA instrinsics require some special handling compared the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
392 normal simd intrinsics. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
393 #define AARCH64_SIMD_FCMLA_LANEQ_BUILTINS \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
394 FCMLA_LANEQ_BUILTIN (0, v2sf, fcmla, V2SF, false) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
395 FCMLA_LANEQ_BUILTIN (90, v2sf, fcmla, V2SF, false) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
396 FCMLA_LANEQ_BUILTIN (180, v2sf, fcmla, V2SF, false) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
397 FCMLA_LANEQ_BUILTIN (270, v2sf, fcmla, V2SF, false) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
398 FCMLA_LANEQ_BUILTIN (0, v4hf, fcmla_laneq, V4HF, true) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
399 FCMLA_LANEQ_BUILTIN (90, v4hf, fcmla_laneq, V4HF, true) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
400 FCMLA_LANEQ_BUILTIN (180, v4hf, fcmla_laneq, V4HF, true) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
401 FCMLA_LANEQ_BUILTIN (270, v4hf, fcmla_laneq, V4HF, true) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
402
111
kono
parents:
diff changeset
403 typedef struct
kono
parents:
diff changeset
404 {
kono
parents:
diff changeset
405 const char *name;
kono
parents:
diff changeset
406 machine_mode mode;
kono
parents:
diff changeset
407 const enum insn_code icode;
kono
parents:
diff changeset
408 unsigned int fcode;
kono
parents:
diff changeset
409 } aarch64_crc_builtin_datum;
kono
parents:
diff changeset
410
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
411 /* Hold information about how to expand the FCMLA_LANEQ builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
412 typedef struct
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
413 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
414 const char *name;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
415 machine_mode mode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
416 const enum insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
417 unsigned int fcode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
418 bool lane;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
419 } aarch64_fcmla_laneq_builtin_datum;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
420
111
kono
parents:
diff changeset
421 #define CRC32_BUILTIN(N, M) \
kono
parents:
diff changeset
422 AARCH64_BUILTIN_##N,
kono
parents:
diff changeset
423
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
424 #define FCMLA_LANEQ_BUILTIN(I, N, X, M, T) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
425 AARCH64_SIMD_BUILTIN_FCMLA_LANEQ##I##_##M,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
426
111
kono
parents:
diff changeset
427 #undef VAR1
kono
parents:
diff changeset
428 #define VAR1(T, N, MAP, A) \
kono
parents:
diff changeset
429 AARCH64_SIMD_BUILTIN_##T##_##N##A,
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 enum aarch64_builtins
kono
parents:
diff changeset
432 {
kono
parents:
diff changeset
433 AARCH64_BUILTIN_MIN,
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 AARCH64_BUILTIN_GET_FPCR,
kono
parents:
diff changeset
436 AARCH64_BUILTIN_SET_FPCR,
kono
parents:
diff changeset
437 AARCH64_BUILTIN_GET_FPSR,
kono
parents:
diff changeset
438 AARCH64_BUILTIN_SET_FPSR,
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 AARCH64_BUILTIN_RSQRT_DF,
kono
parents:
diff changeset
441 AARCH64_BUILTIN_RSQRT_SF,
kono
parents:
diff changeset
442 AARCH64_BUILTIN_RSQRT_V2DF,
kono
parents:
diff changeset
443 AARCH64_BUILTIN_RSQRT_V2SF,
kono
parents:
diff changeset
444 AARCH64_BUILTIN_RSQRT_V4SF,
kono
parents:
diff changeset
445 AARCH64_SIMD_BUILTIN_BASE,
kono
parents:
diff changeset
446 AARCH64_SIMD_BUILTIN_LANE_CHECK,
kono
parents:
diff changeset
447 #include "aarch64-simd-builtins.def"
kono
parents:
diff changeset
448 /* The first enum element which is based on an insn_data pattern. */
kono
parents:
diff changeset
449 AARCH64_SIMD_PATTERN_START = AARCH64_SIMD_BUILTIN_LANE_CHECK + 1,
kono
parents:
diff changeset
450 AARCH64_SIMD_BUILTIN_MAX = AARCH64_SIMD_PATTERN_START
kono
parents:
diff changeset
451 + ARRAY_SIZE (aarch64_simd_builtin_data) - 1,
kono
parents:
diff changeset
452 AARCH64_CRC32_BUILTIN_BASE,
kono
parents:
diff changeset
453 AARCH64_CRC32_BUILTINS
kono
parents:
diff changeset
454 AARCH64_CRC32_BUILTIN_MAX,
kono
parents:
diff changeset
455 /* ARMv8.3-A Pointer Authentication Builtins. */
kono
parents:
diff changeset
456 AARCH64_PAUTH_BUILTIN_AUTIA1716,
kono
parents:
diff changeset
457 AARCH64_PAUTH_BUILTIN_PACIA1716,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 AARCH64_PAUTH_BUILTIN_AUTIB1716,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
459 AARCH64_PAUTH_BUILTIN_PACIB1716,
111
kono
parents:
diff changeset
460 AARCH64_PAUTH_BUILTIN_XPACLRI,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
461 /* Special cased Armv8.3-A Complex FMA by Lane quad Builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
462 AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
463 AARCH64_SIMD_FCMLA_LANEQ_BUILTINS
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
464 /* Builtin for Arm8.3-a Javascript conversion instruction. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
465 AARCH64_JSCVT,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
466 /* TME builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
467 AARCH64_TME_BUILTIN_TSTART,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
468 AARCH64_TME_BUILTIN_TCOMMIT,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
469 AARCH64_TME_BUILTIN_TTEST,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
470 AARCH64_TME_BUILTIN_TCANCEL,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
471 /* Armv8.5-a RNG instruction builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
472 AARCH64_BUILTIN_RNG_RNDR,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
473 AARCH64_BUILTIN_RNG_RNDRRS,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
474 /* MEMTAG builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
475 AARCH64_MEMTAG_BUILTIN_START,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
476 AARCH64_MEMTAG_BUILTIN_IRG,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
477 AARCH64_MEMTAG_BUILTIN_GMI,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
478 AARCH64_MEMTAG_BUILTIN_SUBP,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
479 AARCH64_MEMTAG_BUILTIN_INC_TAG,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
480 AARCH64_MEMTAG_BUILTIN_SET_TAG,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
481 AARCH64_MEMTAG_BUILTIN_GET_TAG,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
482 AARCH64_MEMTAG_BUILTIN_END,
111
kono
parents:
diff changeset
483 AARCH64_BUILTIN_MAX
kono
parents:
diff changeset
484 };
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 #undef CRC32_BUILTIN
kono
parents:
diff changeset
487 #define CRC32_BUILTIN(N, M) \
kono
parents:
diff changeset
488 {"__builtin_aarch64_"#N, E_##M##mode, CODE_FOR_aarch64_##N, AARCH64_BUILTIN_##N},
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 static aarch64_crc_builtin_datum aarch64_crc_builtin_data[] = {
kono
parents:
diff changeset
491 AARCH64_CRC32_BUILTINS
kono
parents:
diff changeset
492 };
kono
parents:
diff changeset
493
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
494
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
495 #undef FCMLA_LANEQ_BUILTIN
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
496 #define FCMLA_LANEQ_BUILTIN(I, N, X, M, T) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
497 {"__builtin_aarch64_fcmla_laneq"#I#N, E_##M##mode, CODE_FOR_aarch64_##X##I##N, \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
498 AARCH64_SIMD_BUILTIN_FCMLA_LANEQ##I##_##M, T},
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
499
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
500 /* This structure contains how to manage the mapping form the builtin to the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
501 instruction to generate in the backend and how to invoke the instruction. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
502 static aarch64_fcmla_laneq_builtin_datum aarch64_fcmla_lane_builtin_data[] = {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
503 AARCH64_SIMD_FCMLA_LANEQ_BUILTINS
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
504 };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
505
111
kono
parents:
diff changeset
506 #undef CRC32_BUILTIN
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 static GTY(()) tree aarch64_builtin_decls[AARCH64_BUILTIN_MAX];
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 #define NUM_DREG_TYPES 6
kono
parents:
diff changeset
511 #define NUM_QREG_TYPES 6
kono
parents:
diff changeset
512
kono
parents:
diff changeset
513 /* Internal scalar builtin types. These types are used to support
kono
parents:
diff changeset
514 neon intrinsic builtins. They are _not_ user-visible types. Therefore
kono
parents:
diff changeset
515 the mangling for these types are implementation defined. */
kono
parents:
diff changeset
516 const char *aarch64_scalar_builtin_types[] = {
kono
parents:
diff changeset
517 "__builtin_aarch64_simd_qi",
kono
parents:
diff changeset
518 "__builtin_aarch64_simd_hi",
kono
parents:
diff changeset
519 "__builtin_aarch64_simd_si",
kono
parents:
diff changeset
520 "__builtin_aarch64_simd_hf",
kono
parents:
diff changeset
521 "__builtin_aarch64_simd_sf",
kono
parents:
diff changeset
522 "__builtin_aarch64_simd_di",
kono
parents:
diff changeset
523 "__builtin_aarch64_simd_df",
kono
parents:
diff changeset
524 "__builtin_aarch64_simd_poly8",
kono
parents:
diff changeset
525 "__builtin_aarch64_simd_poly16",
kono
parents:
diff changeset
526 "__builtin_aarch64_simd_poly64",
kono
parents:
diff changeset
527 "__builtin_aarch64_simd_poly128",
kono
parents:
diff changeset
528 "__builtin_aarch64_simd_ti",
kono
parents:
diff changeset
529 "__builtin_aarch64_simd_uqi",
kono
parents:
diff changeset
530 "__builtin_aarch64_simd_uhi",
kono
parents:
diff changeset
531 "__builtin_aarch64_simd_usi",
kono
parents:
diff changeset
532 "__builtin_aarch64_simd_udi",
kono
parents:
diff changeset
533 "__builtin_aarch64_simd_ei",
kono
parents:
diff changeset
534 "__builtin_aarch64_simd_oi",
kono
parents:
diff changeset
535 "__builtin_aarch64_simd_ci",
kono
parents:
diff changeset
536 "__builtin_aarch64_simd_xi",
kono
parents:
diff changeset
537 NULL
kono
parents:
diff changeset
538 };
kono
parents:
diff changeset
539
kono
parents:
diff changeset
540 #define ENTRY(E, M, Q, G) E,
kono
parents:
diff changeset
541 enum aarch64_simd_type
kono
parents:
diff changeset
542 {
kono
parents:
diff changeset
543 #include "aarch64-simd-builtin-types.def"
kono
parents:
diff changeset
544 ARM_NEON_H_TYPES_LAST
kono
parents:
diff changeset
545 };
kono
parents:
diff changeset
546 #undef ENTRY
kono
parents:
diff changeset
547
kono
parents:
diff changeset
548 struct aarch64_simd_type_info
kono
parents:
diff changeset
549 {
kono
parents:
diff changeset
550 enum aarch64_simd_type type;
kono
parents:
diff changeset
551
kono
parents:
diff changeset
552 /* Internal type name. */
kono
parents:
diff changeset
553 const char *name;
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 /* Internal type name(mangled). The mangled names conform to the
kono
parents:
diff changeset
556 AAPCS64 (see "Procedure Call Standard for the ARM 64-bit Architecture",
kono
parents:
diff changeset
557 Appendix A). To qualify for emission with the mangled names defined in
kono
parents:
diff changeset
558 that document, a vector type must not only be of the correct mode but also
kono
parents:
diff changeset
559 be of the correct internal AdvSIMD vector type (e.g. __Int8x8_t); these
kono
parents:
diff changeset
560 types are registered by aarch64_init_simd_builtin_types (). In other
kono
parents:
diff changeset
561 words, vector types defined in other ways e.g. via vector_size attribute
kono
parents:
diff changeset
562 will get default mangled names. */
kono
parents:
diff changeset
563 const char *mangle;
kono
parents:
diff changeset
564
kono
parents:
diff changeset
565 /* Internal type. */
kono
parents:
diff changeset
566 tree itype;
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 /* Element type. */
kono
parents:
diff changeset
569 tree eltype;
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 /* Machine mode the internal type maps to. */
kono
parents:
diff changeset
572 enum machine_mode mode;
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 /* Qualifiers. */
kono
parents:
diff changeset
575 enum aarch64_type_qualifiers q;
kono
parents:
diff changeset
576 };
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 #define ENTRY(E, M, Q, G) \
kono
parents:
diff changeset
579 {E, "__" #E, #G "__" #E, NULL_TREE, NULL_TREE, E_##M##mode, qualifier_##Q},
kono
parents:
diff changeset
580 static struct aarch64_simd_type_info aarch64_simd_types [] = {
kono
parents:
diff changeset
581 #include "aarch64-simd-builtin-types.def"
kono
parents:
diff changeset
582 };
kono
parents:
diff changeset
583 #undef ENTRY
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 static tree aarch64_simd_intOI_type_node = NULL_TREE;
kono
parents:
diff changeset
586 static tree aarch64_simd_intCI_type_node = NULL_TREE;
kono
parents:
diff changeset
587 static tree aarch64_simd_intXI_type_node = NULL_TREE;
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 /* The user-visible __fp16 type, and a pointer to that type. Used
kono
parents:
diff changeset
590 across the back-end. */
kono
parents:
diff changeset
591 tree aarch64_fp16_type_node = NULL_TREE;
kono
parents:
diff changeset
592 tree aarch64_fp16_ptr_type_node = NULL_TREE;
kono
parents:
diff changeset
593
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
594 /* Back-end node type for brain float (bfloat) types. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
595 tree aarch64_bf16_type_node = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
596 tree aarch64_bf16_ptr_type_node = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
597
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
598 /* Wrapper around add_builtin_function. NAME is the name of the built-in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
599 function, TYPE is the function type, and CODE is the function subcode
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
600 (relative to AARCH64_BUILTIN_GENERAL). */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
601 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
602 aarch64_general_add_builtin (const char *name, tree type, unsigned int code)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
603 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
604 code = (code << AARCH64_BUILTIN_SHIFT) | AARCH64_BUILTIN_GENERAL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
605 return add_builtin_function (name, type, code, BUILT_IN_MD,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
606 NULL, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
607 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
608
111
kono
parents:
diff changeset
609 static const char *
kono
parents:
diff changeset
610 aarch64_mangle_builtin_scalar_type (const_tree type)
kono
parents:
diff changeset
611 {
kono
parents:
diff changeset
612 int i = 0;
kono
parents:
diff changeset
613
kono
parents:
diff changeset
614 while (aarch64_scalar_builtin_types[i] != NULL)
kono
parents:
diff changeset
615 {
kono
parents:
diff changeset
616 const char *name = aarch64_scalar_builtin_types[i];
kono
parents:
diff changeset
617
kono
parents:
diff changeset
618 if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
kono
parents:
diff changeset
619 && DECL_NAME (TYPE_NAME (type))
kono
parents:
diff changeset
620 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), name))
kono
parents:
diff changeset
621 return aarch64_scalar_builtin_types[i];
kono
parents:
diff changeset
622 i++;
kono
parents:
diff changeset
623 }
kono
parents:
diff changeset
624 return NULL;
kono
parents:
diff changeset
625 }
kono
parents:
diff changeset
626
kono
parents:
diff changeset
627 static const char *
kono
parents:
diff changeset
628 aarch64_mangle_builtin_vector_type (const_tree type)
kono
parents:
diff changeset
629 {
kono
parents:
diff changeset
630 int i;
kono
parents:
diff changeset
631 int nelts = sizeof (aarch64_simd_types) / sizeof (aarch64_simd_types[0]);
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633 for (i = 0; i < nelts; i++)
kono
parents:
diff changeset
634 if (aarch64_simd_types[i].mode == TYPE_MODE (type)
kono
parents:
diff changeset
635 && TYPE_NAME (type)
kono
parents:
diff changeset
636 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
kono
parents:
diff changeset
637 && DECL_NAME (TYPE_NAME (type))
kono
parents:
diff changeset
638 && !strcmp
kono
parents:
diff changeset
639 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
kono
parents:
diff changeset
640 aarch64_simd_types[i].name))
kono
parents:
diff changeset
641 return aarch64_simd_types[i].mangle;
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 return NULL;
kono
parents:
diff changeset
644 }
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 const char *
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
647 aarch64_general_mangle_builtin_type (const_tree type)
111
kono
parents:
diff changeset
648 {
kono
parents:
diff changeset
649 const char *mangle;
kono
parents:
diff changeset
650 /* Walk through all the AArch64 builtins types tables to filter out the
kono
parents:
diff changeset
651 incoming type. */
kono
parents:
diff changeset
652 if ((mangle = aarch64_mangle_builtin_vector_type (type))
kono
parents:
diff changeset
653 || (mangle = aarch64_mangle_builtin_scalar_type (type)))
kono
parents:
diff changeset
654 return mangle;
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 return NULL;
kono
parents:
diff changeset
657 }
kono
parents:
diff changeset
658
kono
parents:
diff changeset
659 static tree
kono
parents:
diff changeset
660 aarch64_simd_builtin_std_type (machine_mode mode,
kono
parents:
diff changeset
661 enum aarch64_type_qualifiers q)
kono
parents:
diff changeset
662 {
kono
parents:
diff changeset
663 #define QUAL_TYPE(M) \
kono
parents:
diff changeset
664 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
kono
parents:
diff changeset
665 switch (mode)
kono
parents:
diff changeset
666 {
kono
parents:
diff changeset
667 case E_QImode:
kono
parents:
diff changeset
668 return QUAL_TYPE (QI);
kono
parents:
diff changeset
669 case E_HImode:
kono
parents:
diff changeset
670 return QUAL_TYPE (HI);
kono
parents:
diff changeset
671 case E_SImode:
kono
parents:
diff changeset
672 return QUAL_TYPE (SI);
kono
parents:
diff changeset
673 case E_DImode:
kono
parents:
diff changeset
674 return QUAL_TYPE (DI);
kono
parents:
diff changeset
675 case E_TImode:
kono
parents:
diff changeset
676 return QUAL_TYPE (TI);
kono
parents:
diff changeset
677 case E_OImode:
kono
parents:
diff changeset
678 return aarch64_simd_intOI_type_node;
kono
parents:
diff changeset
679 case E_CImode:
kono
parents:
diff changeset
680 return aarch64_simd_intCI_type_node;
kono
parents:
diff changeset
681 case E_XImode:
kono
parents:
diff changeset
682 return aarch64_simd_intXI_type_node;
kono
parents:
diff changeset
683 case E_HFmode:
kono
parents:
diff changeset
684 return aarch64_fp16_type_node;
kono
parents:
diff changeset
685 case E_SFmode:
kono
parents:
diff changeset
686 return float_type_node;
kono
parents:
diff changeset
687 case E_DFmode:
kono
parents:
diff changeset
688 return double_type_node;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
689 case E_BFmode:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
690 return aarch64_bf16_type_node;
111
kono
parents:
diff changeset
691 default:
kono
parents:
diff changeset
692 gcc_unreachable ();
kono
parents:
diff changeset
693 }
kono
parents:
diff changeset
694 #undef QUAL_TYPE
kono
parents:
diff changeset
695 }
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 static tree
kono
parents:
diff changeset
698 aarch64_lookup_simd_builtin_type (machine_mode mode,
kono
parents:
diff changeset
699 enum aarch64_type_qualifiers q)
kono
parents:
diff changeset
700 {
kono
parents:
diff changeset
701 int i;
kono
parents:
diff changeset
702 int nelts = sizeof (aarch64_simd_types) / sizeof (aarch64_simd_types[0]);
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 /* Non-poly scalar modes map to standard types not in the table. */
kono
parents:
diff changeset
705 if (q != qualifier_poly && !VECTOR_MODE_P (mode))
kono
parents:
diff changeset
706 return aarch64_simd_builtin_std_type (mode, q);
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 for (i = 0; i < nelts; i++)
kono
parents:
diff changeset
709 if (aarch64_simd_types[i].mode == mode
kono
parents:
diff changeset
710 && aarch64_simd_types[i].q == q)
kono
parents:
diff changeset
711 return aarch64_simd_types[i].itype;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 return NULL_TREE;
kono
parents:
diff changeset
714 }
kono
parents:
diff changeset
715
kono
parents:
diff changeset
716 static tree
kono
parents:
diff changeset
717 aarch64_simd_builtin_type (machine_mode mode,
kono
parents:
diff changeset
718 bool unsigned_p, bool poly_p)
kono
parents:
diff changeset
719 {
kono
parents:
diff changeset
720 if (poly_p)
kono
parents:
diff changeset
721 return aarch64_lookup_simd_builtin_type (mode, qualifier_poly);
kono
parents:
diff changeset
722 else if (unsigned_p)
kono
parents:
diff changeset
723 return aarch64_lookup_simd_builtin_type (mode, qualifier_unsigned);
kono
parents:
diff changeset
724 else
kono
parents:
diff changeset
725 return aarch64_lookup_simd_builtin_type (mode, qualifier_none);
kono
parents:
diff changeset
726 }
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 static void
kono
parents:
diff changeset
729 aarch64_init_simd_builtin_types (void)
kono
parents:
diff changeset
730 {
kono
parents:
diff changeset
731 int i;
kono
parents:
diff changeset
732 int nelts = sizeof (aarch64_simd_types) / sizeof (aarch64_simd_types[0]);
kono
parents:
diff changeset
733 tree tdecl;
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 /* Init all the element types built by the front-end. */
kono
parents:
diff changeset
736 aarch64_simd_types[Int8x8_t].eltype = intQI_type_node;
kono
parents:
diff changeset
737 aarch64_simd_types[Int8x16_t].eltype = intQI_type_node;
kono
parents:
diff changeset
738 aarch64_simd_types[Int16x4_t].eltype = intHI_type_node;
kono
parents:
diff changeset
739 aarch64_simd_types[Int16x8_t].eltype = intHI_type_node;
kono
parents:
diff changeset
740 aarch64_simd_types[Int32x2_t].eltype = intSI_type_node;
kono
parents:
diff changeset
741 aarch64_simd_types[Int32x4_t].eltype = intSI_type_node;
kono
parents:
diff changeset
742 aarch64_simd_types[Int64x1_t].eltype = intDI_type_node;
kono
parents:
diff changeset
743 aarch64_simd_types[Int64x2_t].eltype = intDI_type_node;
kono
parents:
diff changeset
744 aarch64_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node;
kono
parents:
diff changeset
745 aarch64_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node;
kono
parents:
diff changeset
746 aarch64_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node;
kono
parents:
diff changeset
747 aarch64_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node;
kono
parents:
diff changeset
748 aarch64_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node;
kono
parents:
diff changeset
749 aarch64_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node;
kono
parents:
diff changeset
750 aarch64_simd_types[Uint64x1_t].eltype = unsigned_intDI_type_node;
kono
parents:
diff changeset
751 aarch64_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node;
kono
parents:
diff changeset
752
kono
parents:
diff changeset
753 /* Poly types are a world of their own. */
kono
parents:
diff changeset
754 aarch64_simd_types[Poly8_t].eltype = aarch64_simd_types[Poly8_t].itype =
kono
parents:
diff changeset
755 build_distinct_type_copy (unsigned_intQI_type_node);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
756 /* Prevent front-ends from transforming Poly8_t arrays into string
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
757 literals. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
758 TYPE_STRING_FLAG (aarch64_simd_types[Poly8_t].eltype) = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
759
111
kono
parents:
diff changeset
760 aarch64_simd_types[Poly16_t].eltype = aarch64_simd_types[Poly16_t].itype =
kono
parents:
diff changeset
761 build_distinct_type_copy (unsigned_intHI_type_node);
kono
parents:
diff changeset
762 aarch64_simd_types[Poly64_t].eltype = aarch64_simd_types[Poly64_t].itype =
kono
parents:
diff changeset
763 build_distinct_type_copy (unsigned_intDI_type_node);
kono
parents:
diff changeset
764 aarch64_simd_types[Poly128_t].eltype = aarch64_simd_types[Poly128_t].itype =
kono
parents:
diff changeset
765 build_distinct_type_copy (unsigned_intTI_type_node);
kono
parents:
diff changeset
766 /* Init poly vector element types with scalar poly types. */
kono
parents:
diff changeset
767 aarch64_simd_types[Poly8x8_t].eltype = aarch64_simd_types[Poly8_t].itype;
kono
parents:
diff changeset
768 aarch64_simd_types[Poly8x16_t].eltype = aarch64_simd_types[Poly8_t].itype;
kono
parents:
diff changeset
769 aarch64_simd_types[Poly16x4_t].eltype = aarch64_simd_types[Poly16_t].itype;
kono
parents:
diff changeset
770 aarch64_simd_types[Poly16x8_t].eltype = aarch64_simd_types[Poly16_t].itype;
kono
parents:
diff changeset
771 aarch64_simd_types[Poly64x1_t].eltype = aarch64_simd_types[Poly64_t].itype;
kono
parents:
diff changeset
772 aarch64_simd_types[Poly64x2_t].eltype = aarch64_simd_types[Poly64_t].itype;
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774 /* Continue with standard types. */
kono
parents:
diff changeset
775 aarch64_simd_types[Float16x4_t].eltype = aarch64_fp16_type_node;
kono
parents:
diff changeset
776 aarch64_simd_types[Float16x8_t].eltype = aarch64_fp16_type_node;
kono
parents:
diff changeset
777 aarch64_simd_types[Float32x2_t].eltype = float_type_node;
kono
parents:
diff changeset
778 aarch64_simd_types[Float32x4_t].eltype = float_type_node;
kono
parents:
diff changeset
779 aarch64_simd_types[Float64x1_t].eltype = double_type_node;
kono
parents:
diff changeset
780 aarch64_simd_types[Float64x2_t].eltype = double_type_node;
kono
parents:
diff changeset
781
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
782 /* Init Bfloat vector types with underlying __bf16 type. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
783 aarch64_simd_types[Bfloat16x4_t].eltype = aarch64_bf16_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
784 aarch64_simd_types[Bfloat16x8_t].eltype = aarch64_bf16_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
785
111
kono
parents:
diff changeset
786 for (i = 0; i < nelts; i++)
kono
parents:
diff changeset
787 {
kono
parents:
diff changeset
788 tree eltype = aarch64_simd_types[i].eltype;
kono
parents:
diff changeset
789 machine_mode mode = aarch64_simd_types[i].mode;
kono
parents:
diff changeset
790
kono
parents:
diff changeset
791 if (aarch64_simd_types[i].itype == NULL)
kono
parents:
diff changeset
792 {
kono
parents:
diff changeset
793 aarch64_simd_types[i].itype
kono
parents:
diff changeset
794 = build_distinct_type_copy
kono
parents:
diff changeset
795 (build_vector_type (eltype, GET_MODE_NUNITS (mode)));
kono
parents:
diff changeset
796 SET_TYPE_STRUCTURAL_EQUALITY (aarch64_simd_types[i].itype);
kono
parents:
diff changeset
797 }
kono
parents:
diff changeset
798
kono
parents:
diff changeset
799 tdecl = add_builtin_type (aarch64_simd_types[i].name,
kono
parents:
diff changeset
800 aarch64_simd_types[i].itype);
kono
parents:
diff changeset
801 TYPE_NAME (aarch64_simd_types[i].itype) = tdecl;
kono
parents:
diff changeset
802 }
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 #define AARCH64_BUILD_SIGNED_TYPE(mode) \
kono
parents:
diff changeset
805 make_signed_type (GET_MODE_PRECISION (mode));
kono
parents:
diff changeset
806 aarch64_simd_intOI_type_node = AARCH64_BUILD_SIGNED_TYPE (OImode);
kono
parents:
diff changeset
807 aarch64_simd_intCI_type_node = AARCH64_BUILD_SIGNED_TYPE (CImode);
kono
parents:
diff changeset
808 aarch64_simd_intXI_type_node = AARCH64_BUILD_SIGNED_TYPE (XImode);
kono
parents:
diff changeset
809 #undef AARCH64_BUILD_SIGNED_TYPE
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 tdecl = add_builtin_type
kono
parents:
diff changeset
812 ("__builtin_aarch64_simd_oi" , aarch64_simd_intOI_type_node);
kono
parents:
diff changeset
813 TYPE_NAME (aarch64_simd_intOI_type_node) = tdecl;
kono
parents:
diff changeset
814 tdecl = add_builtin_type
kono
parents:
diff changeset
815 ("__builtin_aarch64_simd_ci" , aarch64_simd_intCI_type_node);
kono
parents:
diff changeset
816 TYPE_NAME (aarch64_simd_intCI_type_node) = tdecl;
kono
parents:
diff changeset
817 tdecl = add_builtin_type
kono
parents:
diff changeset
818 ("__builtin_aarch64_simd_xi" , aarch64_simd_intXI_type_node);
kono
parents:
diff changeset
819 TYPE_NAME (aarch64_simd_intXI_type_node) = tdecl;
kono
parents:
diff changeset
820 }
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 static void
kono
parents:
diff changeset
823 aarch64_init_simd_builtin_scalar_types (void)
kono
parents:
diff changeset
824 {
kono
parents:
diff changeset
825 /* Define typedefs for all the standard scalar types. */
kono
parents:
diff changeset
826 (*lang_hooks.types.register_builtin_type) (intQI_type_node,
kono
parents:
diff changeset
827 "__builtin_aarch64_simd_qi");
kono
parents:
diff changeset
828 (*lang_hooks.types.register_builtin_type) (intHI_type_node,
kono
parents:
diff changeset
829 "__builtin_aarch64_simd_hi");
kono
parents:
diff changeset
830 (*lang_hooks.types.register_builtin_type) (aarch64_fp16_type_node,
kono
parents:
diff changeset
831 "__builtin_aarch64_simd_hf");
kono
parents:
diff changeset
832 (*lang_hooks.types.register_builtin_type) (intSI_type_node,
kono
parents:
diff changeset
833 "__builtin_aarch64_simd_si");
kono
parents:
diff changeset
834 (*lang_hooks.types.register_builtin_type) (float_type_node,
kono
parents:
diff changeset
835 "__builtin_aarch64_simd_sf");
kono
parents:
diff changeset
836 (*lang_hooks.types.register_builtin_type) (intDI_type_node,
kono
parents:
diff changeset
837 "__builtin_aarch64_simd_di");
kono
parents:
diff changeset
838 (*lang_hooks.types.register_builtin_type) (double_type_node,
kono
parents:
diff changeset
839 "__builtin_aarch64_simd_df");
kono
parents:
diff changeset
840 (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node,
kono
parents:
diff changeset
841 "__builtin_aarch64_simd_poly8");
kono
parents:
diff changeset
842 (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node,
kono
parents:
diff changeset
843 "__builtin_aarch64_simd_poly16");
kono
parents:
diff changeset
844 (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node,
kono
parents:
diff changeset
845 "__builtin_aarch64_simd_poly64");
kono
parents:
diff changeset
846 (*lang_hooks.types.register_builtin_type) (unsigned_intTI_type_node,
kono
parents:
diff changeset
847 "__builtin_aarch64_simd_poly128");
kono
parents:
diff changeset
848 (*lang_hooks.types.register_builtin_type) (intTI_type_node,
kono
parents:
diff changeset
849 "__builtin_aarch64_simd_ti");
kono
parents:
diff changeset
850 /* Unsigned integer types for various mode sizes. */
kono
parents:
diff changeset
851 (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node,
kono
parents:
diff changeset
852 "__builtin_aarch64_simd_uqi");
kono
parents:
diff changeset
853 (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node,
kono
parents:
diff changeset
854 "__builtin_aarch64_simd_uhi");
kono
parents:
diff changeset
855 (*lang_hooks.types.register_builtin_type) (unsigned_intSI_type_node,
kono
parents:
diff changeset
856 "__builtin_aarch64_simd_usi");
kono
parents:
diff changeset
857 (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node,
kono
parents:
diff changeset
858 "__builtin_aarch64_simd_udi");
kono
parents:
diff changeset
859 }
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 static bool aarch64_simd_builtins_initialized_p = false;
kono
parents:
diff changeset
862
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
863 /* Due to the architecture not providing lane variant of the lane instructions
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
864 for fcmla we can't use the standard simd builtin expansion code, but we
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
865 still want the majority of the validation that would normally be done. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
866
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
867 void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
868 aarch64_init_fcmla_laneq_builtins (void)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
869 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
870 unsigned int i = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
871
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
872 for (i = 0; i < ARRAY_SIZE (aarch64_fcmla_lane_builtin_data); ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
873 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
874 aarch64_fcmla_laneq_builtin_datum* d
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
875 = &aarch64_fcmla_lane_builtin_data[i];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
876 tree argtype = aarch64_lookup_simd_builtin_type (d->mode, qualifier_none);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
877 machine_mode quadmode = GET_MODE_2XWIDER_MODE (d->mode).require ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
878 tree quadtype
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
879 = aarch64_lookup_simd_builtin_type (quadmode, qualifier_none);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
880 tree lanetype
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
881 = aarch64_simd_builtin_std_type (SImode, qualifier_lane_pair_index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
882 tree ftype = build_function_type_list (argtype, argtype, argtype,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
883 quadtype, lanetype, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
884 tree fndecl = aarch64_general_add_builtin (d->name, ftype, d->fcode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
885
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
886 aarch64_builtin_decls[d->fcode] = fndecl;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
887 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
888 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
889
111
kono
parents:
diff changeset
890 void
kono
parents:
diff changeset
891 aarch64_init_simd_builtins (void)
kono
parents:
diff changeset
892 {
kono
parents:
diff changeset
893 unsigned int i, fcode = AARCH64_SIMD_PATTERN_START;
kono
parents:
diff changeset
894
kono
parents:
diff changeset
895 if (aarch64_simd_builtins_initialized_p)
kono
parents:
diff changeset
896 return;
kono
parents:
diff changeset
897
kono
parents:
diff changeset
898 aarch64_simd_builtins_initialized_p = true;
kono
parents:
diff changeset
899
kono
parents:
diff changeset
900 aarch64_init_simd_builtin_types ();
kono
parents:
diff changeset
901
kono
parents:
diff changeset
902 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
kono
parents:
diff changeset
903 Therefore we need to preserve the old __builtin scalar types. It can be
kono
parents:
diff changeset
904 removed once all the intrinsics become strongly typed using the qualifier
kono
parents:
diff changeset
905 system. */
kono
parents:
diff changeset
906 aarch64_init_simd_builtin_scalar_types ();
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 tree lane_check_fpr = build_function_type_list (void_type_node,
kono
parents:
diff changeset
909 size_type_node,
kono
parents:
diff changeset
910 size_type_node,
kono
parents:
diff changeset
911 intSI_type_node,
kono
parents:
diff changeset
912 NULL);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
913 aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_LANE_CHECK]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
914 = aarch64_general_add_builtin ("__builtin_aarch64_im_lane_boundsi",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
915 lane_check_fpr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
916 AARCH64_SIMD_BUILTIN_LANE_CHECK);
111
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 for (i = 0; i < ARRAY_SIZE (aarch64_simd_builtin_data); i++, fcode++)
kono
parents:
diff changeset
919 {
kono
parents:
diff changeset
920 bool print_type_signature_p = false;
kono
parents:
diff changeset
921 char type_signature[SIMD_MAX_BUILTIN_ARGS + 1] = { 0 };
kono
parents:
diff changeset
922 aarch64_simd_builtin_datum *d = &aarch64_simd_builtin_data[i];
kono
parents:
diff changeset
923 char namebuf[60];
kono
parents:
diff changeset
924 tree ftype = NULL;
kono
parents:
diff changeset
925 tree fndecl = NULL;
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 d->fcode = fcode;
kono
parents:
diff changeset
928
kono
parents:
diff changeset
929 /* We must track two variables here. op_num is
kono
parents:
diff changeset
930 the operand number as in the RTL pattern. This is
kono
parents:
diff changeset
931 required to access the mode (e.g. V4SF mode) of the
kono
parents:
diff changeset
932 argument, from which the base type can be derived.
kono
parents:
diff changeset
933 arg_num is an index in to the qualifiers data, which
kono
parents:
diff changeset
934 gives qualifiers to the type (e.g. const unsigned).
kono
parents:
diff changeset
935 The reason these two variables may differ by one is the
kono
parents:
diff changeset
936 void return type. While all return types take the 0th entry
kono
parents:
diff changeset
937 in the qualifiers array, there is no operand for them in the
kono
parents:
diff changeset
938 RTL pattern. */
kono
parents:
diff changeset
939 int op_num = insn_data[d->code].n_operands - 1;
kono
parents:
diff changeset
940 int arg_num = d->qualifiers[0] & qualifier_void
kono
parents:
diff changeset
941 ? op_num + 1
kono
parents:
diff changeset
942 : op_num;
kono
parents:
diff changeset
943 tree return_type = void_type_node, args = void_list_node;
kono
parents:
diff changeset
944 tree eltype;
kono
parents:
diff changeset
945
kono
parents:
diff changeset
946 /* Build a function type directly from the insn_data for this
kono
parents:
diff changeset
947 builtin. The build_function_type () function takes care of
kono
parents:
diff changeset
948 removing duplicates for us. */
kono
parents:
diff changeset
949 for (; op_num >= 0; arg_num--, op_num--)
kono
parents:
diff changeset
950 {
kono
parents:
diff changeset
951 machine_mode op_mode = insn_data[d->code].operand[op_num].mode;
kono
parents:
diff changeset
952 enum aarch64_type_qualifiers qualifiers = d->qualifiers[arg_num];
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 if (qualifiers & qualifier_unsigned)
kono
parents:
diff changeset
955 {
kono
parents:
diff changeset
956 type_signature[op_num] = 'u';
kono
parents:
diff changeset
957 print_type_signature_p = true;
kono
parents:
diff changeset
958 }
kono
parents:
diff changeset
959 else if (qualifiers & qualifier_poly)
kono
parents:
diff changeset
960 {
kono
parents:
diff changeset
961 type_signature[op_num] = 'p';
kono
parents:
diff changeset
962 print_type_signature_p = true;
kono
parents:
diff changeset
963 }
kono
parents:
diff changeset
964 else
kono
parents:
diff changeset
965 type_signature[op_num] = 's';
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 /* Skip an internal operand for vget_{low, high}. */
kono
parents:
diff changeset
968 if (qualifiers & qualifier_internal)
kono
parents:
diff changeset
969 continue;
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 /* Some builtins have different user-facing types
kono
parents:
diff changeset
972 for certain arguments, encoded in d->mode. */
kono
parents:
diff changeset
973 if (qualifiers & qualifier_map_mode)
kono
parents:
diff changeset
974 op_mode = d->mode;
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 /* For pointers, we want a pointer to the basic type
kono
parents:
diff changeset
977 of the vector. */
kono
parents:
diff changeset
978 if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode))
kono
parents:
diff changeset
979 op_mode = GET_MODE_INNER (op_mode);
kono
parents:
diff changeset
980
kono
parents:
diff changeset
981 eltype = aarch64_simd_builtin_type
kono
parents:
diff changeset
982 (op_mode,
kono
parents:
diff changeset
983 (qualifiers & qualifier_unsigned) != 0,
kono
parents:
diff changeset
984 (qualifiers & qualifier_poly) != 0);
kono
parents:
diff changeset
985 gcc_assert (eltype != NULL);
kono
parents:
diff changeset
986
kono
parents:
diff changeset
987 /* Add qualifiers. */
kono
parents:
diff changeset
988 if (qualifiers & qualifier_const)
kono
parents:
diff changeset
989 eltype = build_qualified_type (eltype, TYPE_QUAL_CONST);
kono
parents:
diff changeset
990
kono
parents:
diff changeset
991 if (qualifiers & qualifier_pointer)
kono
parents:
diff changeset
992 eltype = build_pointer_type (eltype);
kono
parents:
diff changeset
993
kono
parents:
diff changeset
994 /* If we have reached arg_num == 0, we are at a non-void
kono
parents:
diff changeset
995 return type. Otherwise, we are still processing
kono
parents:
diff changeset
996 arguments. */
kono
parents:
diff changeset
997 if (arg_num == 0)
kono
parents:
diff changeset
998 return_type = eltype;
kono
parents:
diff changeset
999 else
kono
parents:
diff changeset
1000 args = tree_cons (NULL_TREE, eltype, args);
kono
parents:
diff changeset
1001 }
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 ftype = build_function_type (return_type, args);
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 gcc_assert (ftype != NULL);
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 if (print_type_signature_p)
kono
parents:
diff changeset
1008 snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s_%s",
kono
parents:
diff changeset
1009 d->name, type_signature);
kono
parents:
diff changeset
1010 else
kono
parents:
diff changeset
1011 snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s",
kono
parents:
diff changeset
1012 d->name);
kono
parents:
diff changeset
1013
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1014 fndecl = aarch64_general_add_builtin (namebuf, ftype, fcode);
111
kono
parents:
diff changeset
1015 aarch64_builtin_decls[fcode] = fndecl;
kono
parents:
diff changeset
1016 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1017
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1018 /* Initialize the remaining fcmla_laneq intrinsics. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1019 aarch64_init_fcmla_laneq_builtins ();
111
kono
parents:
diff changeset
1020 }
kono
parents:
diff changeset
1021
kono
parents:
diff changeset
1022 static void
kono
parents:
diff changeset
1023 aarch64_init_crc32_builtins ()
kono
parents:
diff changeset
1024 {
kono
parents:
diff changeset
1025 tree usi_type = aarch64_simd_builtin_std_type (SImode, qualifier_unsigned);
kono
parents:
diff changeset
1026 unsigned int i = 0;
kono
parents:
diff changeset
1027
kono
parents:
diff changeset
1028 for (i = 0; i < ARRAY_SIZE (aarch64_crc_builtin_data); ++i)
kono
parents:
diff changeset
1029 {
kono
parents:
diff changeset
1030 aarch64_crc_builtin_datum* d = &aarch64_crc_builtin_data[i];
kono
parents:
diff changeset
1031 tree argtype = aarch64_simd_builtin_std_type (d->mode,
kono
parents:
diff changeset
1032 qualifier_unsigned);
kono
parents:
diff changeset
1033 tree ftype = build_function_type_list (usi_type, usi_type, argtype, NULL_TREE);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1034 tree fndecl = aarch64_general_add_builtin (d->name, ftype, d->fcode);
111
kono
parents:
diff changeset
1035
kono
parents:
diff changeset
1036 aarch64_builtin_decls[d->fcode] = fndecl;
kono
parents:
diff changeset
1037 }
kono
parents:
diff changeset
1038 }
kono
parents:
diff changeset
1039
kono
parents:
diff changeset
1040 /* Add builtins for reciprocal square root. */
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 void
kono
parents:
diff changeset
1043 aarch64_init_builtin_rsqrt (void)
kono
parents:
diff changeset
1044 {
kono
parents:
diff changeset
1045 tree fndecl = NULL;
kono
parents:
diff changeset
1046 tree ftype = NULL;
kono
parents:
diff changeset
1047
kono
parents:
diff changeset
1048 tree V2SF_type_node = build_vector_type (float_type_node, 2);
kono
parents:
diff changeset
1049 tree V2DF_type_node = build_vector_type (double_type_node, 2);
kono
parents:
diff changeset
1050 tree V4SF_type_node = build_vector_type (float_type_node, 4);
kono
parents:
diff changeset
1051
kono
parents:
diff changeset
1052 struct builtin_decls_data
kono
parents:
diff changeset
1053 {
kono
parents:
diff changeset
1054 tree type_node;
kono
parents:
diff changeset
1055 const char *builtin_name;
kono
parents:
diff changeset
1056 int function_code;
kono
parents:
diff changeset
1057 };
kono
parents:
diff changeset
1058
kono
parents:
diff changeset
1059 builtin_decls_data bdda[] =
kono
parents:
diff changeset
1060 {
kono
parents:
diff changeset
1061 { double_type_node, "__builtin_aarch64_rsqrt_df", AARCH64_BUILTIN_RSQRT_DF },
kono
parents:
diff changeset
1062 { float_type_node, "__builtin_aarch64_rsqrt_sf", AARCH64_BUILTIN_RSQRT_SF },
kono
parents:
diff changeset
1063 { V2DF_type_node, "__builtin_aarch64_rsqrt_v2df", AARCH64_BUILTIN_RSQRT_V2DF },
kono
parents:
diff changeset
1064 { V2SF_type_node, "__builtin_aarch64_rsqrt_v2sf", AARCH64_BUILTIN_RSQRT_V2SF },
kono
parents:
diff changeset
1065 { V4SF_type_node, "__builtin_aarch64_rsqrt_v4sf", AARCH64_BUILTIN_RSQRT_V4SF }
kono
parents:
diff changeset
1066 };
kono
parents:
diff changeset
1067
kono
parents:
diff changeset
1068 builtin_decls_data *bdd = bdda;
kono
parents:
diff changeset
1069 builtin_decls_data *bdd_end = bdd + (sizeof (bdda) / sizeof (builtin_decls_data));
kono
parents:
diff changeset
1070
kono
parents:
diff changeset
1071 for (; bdd < bdd_end; bdd++)
kono
parents:
diff changeset
1072 {
kono
parents:
diff changeset
1073 ftype = build_function_type_list (bdd->type_node, bdd->type_node, NULL_TREE);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1074 fndecl = aarch64_general_add_builtin (bdd->builtin_name,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1075 ftype, bdd->function_code);
111
kono
parents:
diff changeset
1076 aarch64_builtin_decls[bdd->function_code] = fndecl;
kono
parents:
diff changeset
1077 }
kono
parents:
diff changeset
1078 }
kono
parents:
diff changeset
1079
kono
parents:
diff changeset
1080 /* Initialize the backend types that support the user-visible __fp16
kono
parents:
diff changeset
1081 type, also initialize a pointer to that type, to be used when
kono
parents:
diff changeset
1082 forming HFAs. */
kono
parents:
diff changeset
1083
kono
parents:
diff changeset
1084 static void
kono
parents:
diff changeset
1085 aarch64_init_fp16_types (void)
kono
parents:
diff changeset
1086 {
kono
parents:
diff changeset
1087 aarch64_fp16_type_node = make_node (REAL_TYPE);
kono
parents:
diff changeset
1088 TYPE_PRECISION (aarch64_fp16_type_node) = 16;
kono
parents:
diff changeset
1089 layout_type (aarch64_fp16_type_node);
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 (*lang_hooks.types.register_builtin_type) (aarch64_fp16_type_node, "__fp16");
kono
parents:
diff changeset
1092 aarch64_fp16_ptr_type_node = build_pointer_type (aarch64_fp16_type_node);
kono
parents:
diff changeset
1093 }
kono
parents:
diff changeset
1094
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1095 /* Initialize the backend REAL_TYPE type supporting bfloat types. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1096 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1097 aarch64_init_bf16_types (void)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1098 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1099 aarch64_bf16_type_node = make_node (REAL_TYPE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1100 TYPE_PRECISION (aarch64_bf16_type_node) = 16;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1101 SET_TYPE_MODE (aarch64_bf16_type_node, BFmode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1102 layout_type (aarch64_bf16_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1103
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1104 lang_hooks.types.register_builtin_type (aarch64_bf16_type_node, "__bf16");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1105 aarch64_bf16_ptr_type_node = build_pointer_type (aarch64_bf16_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1106 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1107
111
kono
parents:
diff changeset
1108 /* Pointer authentication builtins that will become NOP on legacy platform.
kono
parents:
diff changeset
1109 Currently, these builtins are for internal use only (libgcc EH unwinder). */
kono
parents:
diff changeset
1110
kono
parents:
diff changeset
1111 void
kono
parents:
diff changeset
1112 aarch64_init_pauth_hint_builtins (void)
kono
parents:
diff changeset
1113 {
kono
parents:
diff changeset
1114 /* Pointer Authentication builtins. */
kono
parents:
diff changeset
1115 tree ftype_pointer_auth
kono
parents:
diff changeset
1116 = build_function_type_list (ptr_type_node, ptr_type_node,
kono
parents:
diff changeset
1117 unsigned_intDI_type_node, NULL_TREE);
kono
parents:
diff changeset
1118 tree ftype_pointer_strip
kono
parents:
diff changeset
1119 = build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE);
kono
parents:
diff changeset
1120
kono
parents:
diff changeset
1121 aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_AUTIA1716]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1122 = aarch64_general_add_builtin ("__builtin_aarch64_autia1716",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1123 ftype_pointer_auth,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1124 AARCH64_PAUTH_BUILTIN_AUTIA1716);
111
kono
parents:
diff changeset
1125 aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_PACIA1716]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1126 = aarch64_general_add_builtin ("__builtin_aarch64_pacia1716",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1127 ftype_pointer_auth,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1128 AARCH64_PAUTH_BUILTIN_PACIA1716);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1129 aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_AUTIB1716]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1130 = aarch64_general_add_builtin ("__builtin_aarch64_autib1716",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1131 ftype_pointer_auth,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1132 AARCH64_PAUTH_BUILTIN_AUTIB1716);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1133 aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_PACIB1716]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1134 = aarch64_general_add_builtin ("__builtin_aarch64_pacib1716",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1135 ftype_pointer_auth,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1136 AARCH64_PAUTH_BUILTIN_PACIB1716);
111
kono
parents:
diff changeset
1137 aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_XPACLRI]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1138 = aarch64_general_add_builtin ("__builtin_aarch64_xpaclri",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1139 ftype_pointer_strip,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1140 AARCH64_PAUTH_BUILTIN_XPACLRI);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1141 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1142
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1143 /* Initialize the transactional memory extension (TME) builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1144 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1145 aarch64_init_tme_builtins (void)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1146 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1147 tree ftype_uint64_void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1148 = build_function_type_list (uint64_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1149 tree ftype_void_void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1150 = build_function_type_list (void_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1151 tree ftype_void_uint64
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1152 = build_function_type_list (void_type_node, uint64_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1153
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1154 aarch64_builtin_decls[AARCH64_TME_BUILTIN_TSTART]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1155 = aarch64_general_add_builtin ("__builtin_aarch64_tstart",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1156 ftype_uint64_void,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1157 AARCH64_TME_BUILTIN_TSTART);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1158 aarch64_builtin_decls[AARCH64_TME_BUILTIN_TTEST]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1159 = aarch64_general_add_builtin ("__builtin_aarch64_ttest",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1160 ftype_uint64_void,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1161 AARCH64_TME_BUILTIN_TTEST);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1162 aarch64_builtin_decls[AARCH64_TME_BUILTIN_TCOMMIT]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1163 = aarch64_general_add_builtin ("__builtin_aarch64_tcommit",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1164 ftype_void_void,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1165 AARCH64_TME_BUILTIN_TCOMMIT);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1166 aarch64_builtin_decls[AARCH64_TME_BUILTIN_TCANCEL]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1167 = aarch64_general_add_builtin ("__builtin_aarch64_tcancel",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1168 ftype_void_uint64,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1169 AARCH64_TME_BUILTIN_TCANCEL);
111
kono
parents:
diff changeset
1170 }
kono
parents:
diff changeset
1171
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1172 /* Add builtins for Random Number instructions. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1173
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1174 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1175 aarch64_init_rng_builtins (void)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1176 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177 tree unsigned_ptr_type = build_pointer_type (unsigned_intDI_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1178 tree ftype
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 = build_function_type_list (integer_type_node, unsigned_ptr_type, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 aarch64_builtin_decls[AARCH64_BUILTIN_RNG_RNDR]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 = aarch64_general_add_builtin ("__builtin_aarch64_rndr", ftype,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1182 AARCH64_BUILTIN_RNG_RNDR);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1183 aarch64_builtin_decls[AARCH64_BUILTIN_RNG_RNDRRS]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 = aarch64_general_add_builtin ("__builtin_aarch64_rndrrs", ftype,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1185 AARCH64_BUILTIN_RNG_RNDRRS);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1186 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1187
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188 /* Initialize the memory tagging extension (MTE) builtins. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 struct
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1190 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1191 tree ftype;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 enum insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 } aarch64_memtag_builtin_data[AARCH64_MEMTAG_BUILTIN_END -
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1194 AARCH64_MEMTAG_BUILTIN_START - 1];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1195
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1196 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1197 aarch64_init_memtag_builtins (void)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1198 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1199 tree fntype = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1200
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1201 #define AARCH64_INIT_MEMTAG_BUILTINS_DECL(F, N, I, T) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1202 aarch64_builtin_decls[AARCH64_MEMTAG_BUILTIN_##F] \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1203 = aarch64_general_add_builtin ("__builtin_aarch64_memtag_"#N, \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1204 T, AARCH64_MEMTAG_BUILTIN_##F); \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1205 aarch64_memtag_builtin_data[AARCH64_MEMTAG_BUILTIN_##F - \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1206 AARCH64_MEMTAG_BUILTIN_START - 1] = \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1207 {T, CODE_FOR_##I};
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1208
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1209 fntype = build_function_type_list (ptr_type_node, ptr_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1210 uint64_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1211 AARCH64_INIT_MEMTAG_BUILTINS_DECL (IRG, irg, irg, fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1212
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1213 fntype = build_function_type_list (uint64_type_node, ptr_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1214 uint64_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1215 AARCH64_INIT_MEMTAG_BUILTINS_DECL (GMI, gmi, gmi, fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1216
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1217 fntype = build_function_type_list (ptrdiff_type_node, ptr_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1218 ptr_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1219 AARCH64_INIT_MEMTAG_BUILTINS_DECL (SUBP, subp, subp, fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1220
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1221 fntype = build_function_type_list (ptr_type_node, ptr_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1222 unsigned_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1223 AARCH64_INIT_MEMTAG_BUILTINS_DECL (INC_TAG, inc_tag, addg, fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1224
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1225 fntype = build_function_type_list (void_type_node, ptr_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1226 AARCH64_INIT_MEMTAG_BUILTINS_DECL (SET_TAG, set_tag, stg, fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1227
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1228 fntype = build_function_type_list (ptr_type_node, ptr_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1229 AARCH64_INIT_MEMTAG_BUILTINS_DECL (GET_TAG, get_tag, ldg, fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1230
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1231 #undef AARCH64_INIT_MEMTAG_BUILTINS_DECL
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1232 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1233
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1234 /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1235
111
kono
parents:
diff changeset
1236 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1237 aarch64_general_init_builtins (void)
111
kono
parents:
diff changeset
1238 {
kono
parents:
diff changeset
1239 tree ftype_set_fpr
kono
parents:
diff changeset
1240 = build_function_type_list (void_type_node, unsigned_type_node, NULL);
kono
parents:
diff changeset
1241 tree ftype_get_fpr
kono
parents:
diff changeset
1242 = build_function_type_list (unsigned_type_node, NULL);
kono
parents:
diff changeset
1243
kono
parents:
diff changeset
1244 aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1245 = aarch64_general_add_builtin ("__builtin_aarch64_get_fpcr",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1246 ftype_get_fpr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1247 AARCH64_BUILTIN_GET_FPCR);
111
kono
parents:
diff changeset
1248 aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1249 = aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1250 ftype_set_fpr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1251 AARCH64_BUILTIN_SET_FPCR);
111
kono
parents:
diff changeset
1252 aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1253 = aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1254 ftype_get_fpr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1255 AARCH64_BUILTIN_GET_FPSR);
111
kono
parents:
diff changeset
1256 aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR]
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1257 = aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1258 ftype_set_fpr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1259 AARCH64_BUILTIN_SET_FPSR);
111
kono
parents:
diff changeset
1260
kono
parents:
diff changeset
1261 aarch64_init_fp16_types ();
kono
parents:
diff changeset
1262
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1263 aarch64_init_bf16_types ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1264
111
kono
parents:
diff changeset
1265 if (TARGET_SIMD)
kono
parents:
diff changeset
1266 aarch64_init_simd_builtins ();
kono
parents:
diff changeset
1267
kono
parents:
diff changeset
1268 aarch64_init_crc32_builtins ();
kono
parents:
diff changeset
1269 aarch64_init_builtin_rsqrt ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1270 aarch64_init_rng_builtins ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1271
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1272 tree ftype_jcvt
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1273 = build_function_type_list (intSI_type_node, double_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1274 aarch64_builtin_decls[AARCH64_JSCVT]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1275 = aarch64_general_add_builtin ("__builtin_aarch64_jcvtzs", ftype_jcvt,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1276 AARCH64_JSCVT);
111
kono
parents:
diff changeset
1277
kono
parents:
diff changeset
1278 /* Initialize pointer authentication builtins which are backed by instructions
kono
parents:
diff changeset
1279 in NOP encoding space.
kono
parents:
diff changeset
1280
kono
parents:
diff changeset
1281 NOTE: these builtins are supposed to be used by libgcc unwinder only, as
kono
parents:
diff changeset
1282 there is no support on return address signing under ILP32, we don't
kono
parents:
diff changeset
1283 register them. */
kono
parents:
diff changeset
1284 if (!TARGET_ILP32)
kono
parents:
diff changeset
1285 aarch64_init_pauth_hint_builtins ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1286
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1287 if (TARGET_TME)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1288 aarch64_init_tme_builtins ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1289
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1290 if (TARGET_MEMTAG)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1291 aarch64_init_memtag_builtins ();
111
kono
parents:
diff changeset
1292 }
kono
parents:
diff changeset
1293
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1294 /* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group. */
111
kono
parents:
diff changeset
1295 tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1296 aarch64_general_builtin_decl (unsigned code, bool)
111
kono
parents:
diff changeset
1297 {
kono
parents:
diff changeset
1298 if (code >= AARCH64_BUILTIN_MAX)
kono
parents:
diff changeset
1299 return error_mark_node;
kono
parents:
diff changeset
1300
kono
parents:
diff changeset
1301 return aarch64_builtin_decls[code];
kono
parents:
diff changeset
1302 }
kono
parents:
diff changeset
1303
kono
parents:
diff changeset
1304 typedef enum
kono
parents:
diff changeset
1305 {
kono
parents:
diff changeset
1306 SIMD_ARG_COPY_TO_REG,
kono
parents:
diff changeset
1307 SIMD_ARG_CONSTANT,
kono
parents:
diff changeset
1308 SIMD_ARG_LANE_INDEX,
kono
parents:
diff changeset
1309 SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1310 SIMD_ARG_LANE_PAIR_INDEX,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1311 SIMD_ARG_LANE_QUADTUP_INDEX,
111
kono
parents:
diff changeset
1312 SIMD_ARG_STOP
kono
parents:
diff changeset
1313 } builtin_simd_arg;
kono
parents:
diff changeset
1314
kono
parents:
diff changeset
1315
kono
parents:
diff changeset
1316 static rtx
kono
parents:
diff changeset
1317 aarch64_simd_expand_args (rtx target, int icode, int have_retval,
kono
parents:
diff changeset
1318 tree exp, builtin_simd_arg *args,
kono
parents:
diff changeset
1319 machine_mode builtin_mode)
kono
parents:
diff changeset
1320 {
kono
parents:
diff changeset
1321 rtx pat;
kono
parents:
diff changeset
1322 rtx op[SIMD_MAX_BUILTIN_ARGS + 1]; /* First element for result operand. */
kono
parents:
diff changeset
1323 int opc = 0;
kono
parents:
diff changeset
1324
kono
parents:
diff changeset
1325 if (have_retval)
kono
parents:
diff changeset
1326 {
kono
parents:
diff changeset
1327 machine_mode tmode = insn_data[icode].operand[0].mode;
kono
parents:
diff changeset
1328 if (!target
kono
parents:
diff changeset
1329 || GET_MODE (target) != tmode
kono
parents:
diff changeset
1330 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
kono
parents:
diff changeset
1331 target = gen_reg_rtx (tmode);
kono
parents:
diff changeset
1332 op[opc++] = target;
kono
parents:
diff changeset
1333 }
kono
parents:
diff changeset
1334
kono
parents:
diff changeset
1335 for (;;)
kono
parents:
diff changeset
1336 {
kono
parents:
diff changeset
1337 builtin_simd_arg thisarg = args[opc - have_retval];
kono
parents:
diff changeset
1338
kono
parents:
diff changeset
1339 if (thisarg == SIMD_ARG_STOP)
kono
parents:
diff changeset
1340 break;
kono
parents:
diff changeset
1341 else
kono
parents:
diff changeset
1342 {
kono
parents:
diff changeset
1343 tree arg = CALL_EXPR_ARG (exp, opc - have_retval);
kono
parents:
diff changeset
1344 machine_mode mode = insn_data[icode].operand[opc].mode;
kono
parents:
diff changeset
1345 op[opc] = expand_normal (arg);
kono
parents:
diff changeset
1346
kono
parents:
diff changeset
1347 switch (thisarg)
kono
parents:
diff changeset
1348 {
kono
parents:
diff changeset
1349 case SIMD_ARG_COPY_TO_REG:
kono
parents:
diff changeset
1350 if (POINTER_TYPE_P (TREE_TYPE (arg)))
kono
parents:
diff changeset
1351 op[opc] = convert_memory_address (Pmode, op[opc]);
kono
parents:
diff changeset
1352 /*gcc_assert (GET_MODE (op[opc]) == mode); */
kono
parents:
diff changeset
1353 if (!(*insn_data[icode].operand[opc].predicate)
kono
parents:
diff changeset
1354 (op[opc], mode))
kono
parents:
diff changeset
1355 op[opc] = copy_to_mode_reg (mode, op[opc]);
kono
parents:
diff changeset
1356 break;
kono
parents:
diff changeset
1357
kono
parents:
diff changeset
1358 case SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
kono
parents:
diff changeset
1359 gcc_assert (opc > 1);
kono
parents:
diff changeset
1360 if (CONST_INT_P (op[opc]))
kono
parents:
diff changeset
1361 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1362 unsigned int nunits
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1363 = GET_MODE_NUNITS (builtin_mode).to_constant ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1364 aarch64_simd_lane_bounds (op[opc], 0, nunits, exp);
111
kono
parents:
diff changeset
1365 /* Keep to GCC-vector-extension lane indices in the RTL. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1366 op[opc] = aarch64_endian_lane_rtx (builtin_mode,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1367 INTVAL (op[opc]));
111
kono
parents:
diff changeset
1368 }
kono
parents:
diff changeset
1369 goto constant_arg;
kono
parents:
diff changeset
1370
kono
parents:
diff changeset
1371 case SIMD_ARG_LANE_INDEX:
kono
parents:
diff changeset
1372 /* Must be a previous operand into which this is an index. */
kono
parents:
diff changeset
1373 gcc_assert (opc > 0);
kono
parents:
diff changeset
1374 if (CONST_INT_P (op[opc]))
kono
parents:
diff changeset
1375 {
kono
parents:
diff changeset
1376 machine_mode vmode = insn_data[icode].operand[opc - 1].mode;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1377 unsigned int nunits
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1378 = GET_MODE_NUNITS (vmode).to_constant ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1379 aarch64_simd_lane_bounds (op[opc], 0, nunits, exp);
111
kono
parents:
diff changeset
1380 /* Keep to GCC-vector-extension lane indices in the RTL. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1381 op[opc] = aarch64_endian_lane_rtx (vmode, INTVAL (op[opc]));
111
kono
parents:
diff changeset
1382 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1383 /* If the lane index isn't a constant then error out. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1384 goto constant_arg;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1385
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1386 case SIMD_ARG_LANE_PAIR_INDEX:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1387 /* Must be a previous operand into which this is an index and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1388 index is restricted to nunits / 2. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1389 gcc_assert (opc > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1390 if (CONST_INT_P (op[opc]))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1391 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1392 machine_mode vmode = insn_data[icode].operand[opc - 1].mode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1393 unsigned int nunits
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1394 = GET_MODE_NUNITS (vmode).to_constant ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1395 aarch64_simd_lane_bounds (op[opc], 0, nunits / 2, exp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1396 /* Keep to GCC-vector-extension lane indices in the RTL. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1397 int lane = INTVAL (op[opc]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1398 op[opc] = gen_int_mode (ENDIAN_LANE_N (nunits / 2, lane),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1399 SImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1400 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1401 /* If the lane index isn't a constant then error out. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1402 goto constant_arg;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1403 case SIMD_ARG_LANE_QUADTUP_INDEX:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1404 /* Must be a previous operand into which this is an index and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1405 index is restricted to nunits / 4. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1406 gcc_assert (opc > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1407 if (CONST_INT_P (op[opc]))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1408 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1409 machine_mode vmode = insn_data[icode].operand[opc - 1].mode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1410 unsigned int nunits
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1411 = GET_MODE_NUNITS (vmode).to_constant ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1412 aarch64_simd_lane_bounds (op[opc], 0, nunits / 4, exp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1413 /* Keep to GCC-vector-extension lane indices in the RTL. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1414 int lane = INTVAL (op[opc]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1415 op[opc] = gen_int_mode (ENDIAN_LANE_N (nunits / 4, lane),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1416 SImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1417 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1418 /* If the lane index isn't a constant then error out. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1419 goto constant_arg;
111
kono
parents:
diff changeset
1420 case SIMD_ARG_CONSTANT:
kono
parents:
diff changeset
1421 constant_arg:
kono
parents:
diff changeset
1422 if (!(*insn_data[icode].operand[opc].predicate)
kono
parents:
diff changeset
1423 (op[opc], mode))
kono
parents:
diff changeset
1424 {
kono
parents:
diff changeset
1425 error ("%Kargument %d must be a constant immediate",
kono
parents:
diff changeset
1426 exp, opc + 1 - have_retval);
kono
parents:
diff changeset
1427 return const0_rtx;
kono
parents:
diff changeset
1428 }
kono
parents:
diff changeset
1429 break;
kono
parents:
diff changeset
1430
kono
parents:
diff changeset
1431 case SIMD_ARG_STOP:
kono
parents:
diff changeset
1432 gcc_unreachable ();
kono
parents:
diff changeset
1433 }
kono
parents:
diff changeset
1434
kono
parents:
diff changeset
1435 opc++;
kono
parents:
diff changeset
1436 }
kono
parents:
diff changeset
1437 }
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 switch (opc)
kono
parents:
diff changeset
1440 {
kono
parents:
diff changeset
1441 case 1:
kono
parents:
diff changeset
1442 pat = GEN_FCN (icode) (op[0]);
kono
parents:
diff changeset
1443 break;
kono
parents:
diff changeset
1444
kono
parents:
diff changeset
1445 case 2:
kono
parents:
diff changeset
1446 pat = GEN_FCN (icode) (op[0], op[1]);
kono
parents:
diff changeset
1447 break;
kono
parents:
diff changeset
1448
kono
parents:
diff changeset
1449 case 3:
kono
parents:
diff changeset
1450 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
kono
parents:
diff changeset
1451 break;
kono
parents:
diff changeset
1452
kono
parents:
diff changeset
1453 case 4:
kono
parents:
diff changeset
1454 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
kono
parents:
diff changeset
1455 break;
kono
parents:
diff changeset
1456
kono
parents:
diff changeset
1457 case 5:
kono
parents:
diff changeset
1458 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
kono
parents:
diff changeset
1459 break;
kono
parents:
diff changeset
1460
kono
parents:
diff changeset
1461 case 6:
kono
parents:
diff changeset
1462 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
kono
parents:
diff changeset
1463 break;
kono
parents:
diff changeset
1464
kono
parents:
diff changeset
1465 default:
kono
parents:
diff changeset
1466 gcc_unreachable ();
kono
parents:
diff changeset
1467 }
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 if (!pat)
kono
parents:
diff changeset
1470 return NULL_RTX;
kono
parents:
diff changeset
1471
kono
parents:
diff changeset
1472 emit_insn (pat);
kono
parents:
diff changeset
1473
kono
parents:
diff changeset
1474 return target;
kono
parents:
diff changeset
1475 }
kono
parents:
diff changeset
1476
kono
parents:
diff changeset
1477 /* Expand an AArch64 AdvSIMD builtin(intrinsic). */
kono
parents:
diff changeset
1478 rtx
kono
parents:
diff changeset
1479 aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
kono
parents:
diff changeset
1480 {
kono
parents:
diff changeset
1481 if (fcode == AARCH64_SIMD_BUILTIN_LANE_CHECK)
kono
parents:
diff changeset
1482 {
kono
parents:
diff changeset
1483 rtx totalsize = expand_normal (CALL_EXPR_ARG (exp, 0));
kono
parents:
diff changeset
1484 rtx elementsize = expand_normal (CALL_EXPR_ARG (exp, 1));
kono
parents:
diff changeset
1485 if (CONST_INT_P (totalsize) && CONST_INT_P (elementsize)
kono
parents:
diff changeset
1486 && UINTVAL (elementsize) != 0
kono
parents:
diff changeset
1487 && UINTVAL (totalsize) != 0)
kono
parents:
diff changeset
1488 {
kono
parents:
diff changeset
1489 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 2));
kono
parents:
diff changeset
1490 if (CONST_INT_P (lane_idx))
kono
parents:
diff changeset
1491 aarch64_simd_lane_bounds (lane_idx, 0,
kono
parents:
diff changeset
1492 UINTVAL (totalsize)
kono
parents:
diff changeset
1493 / UINTVAL (elementsize),
kono
parents:
diff changeset
1494 exp);
kono
parents:
diff changeset
1495 else
kono
parents:
diff changeset
1496 error ("%Klane index must be a constant immediate", exp);
kono
parents:
diff changeset
1497 }
kono
parents:
diff changeset
1498 else
kono
parents:
diff changeset
1499 error ("%Ktotal size and element size must be a non-zero constant immediate", exp);
kono
parents:
diff changeset
1500 /* Don't generate any RTL. */
kono
parents:
diff changeset
1501 return const0_rtx;
kono
parents:
diff changeset
1502 }
kono
parents:
diff changeset
1503 aarch64_simd_builtin_datum *d =
kono
parents:
diff changeset
1504 &aarch64_simd_builtin_data[fcode - AARCH64_SIMD_PATTERN_START];
kono
parents:
diff changeset
1505 enum insn_code icode = d->code;
kono
parents:
diff changeset
1506 builtin_simd_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
kono
parents:
diff changeset
1507 int num_args = insn_data[d->code].n_operands;
kono
parents:
diff changeset
1508 int is_void = 0;
kono
parents:
diff changeset
1509 int k;
kono
parents:
diff changeset
1510
kono
parents:
diff changeset
1511 is_void = !!(d->qualifiers[0] & qualifier_void);
kono
parents:
diff changeset
1512
kono
parents:
diff changeset
1513 num_args += is_void;
kono
parents:
diff changeset
1514
kono
parents:
diff changeset
1515 for (k = 1; k < num_args; k++)
kono
parents:
diff changeset
1516 {
kono
parents:
diff changeset
1517 /* We have four arrays of data, each indexed in a different fashion.
kono
parents:
diff changeset
1518 qualifiers - element 0 always describes the function return type.
kono
parents:
diff changeset
1519 operands - element 0 is either the operand for return value (if
kono
parents:
diff changeset
1520 the function has a non-void return type) or the operand for the
kono
parents:
diff changeset
1521 first argument.
kono
parents:
diff changeset
1522 expr_args - element 0 always holds the first argument.
kono
parents:
diff changeset
1523 args - element 0 is always used for the return type. */
kono
parents:
diff changeset
1524 int qualifiers_k = k;
kono
parents:
diff changeset
1525 int operands_k = k - is_void;
kono
parents:
diff changeset
1526 int expr_args_k = k - 1;
kono
parents:
diff changeset
1527
kono
parents:
diff changeset
1528 if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
kono
parents:
diff changeset
1529 args[k] = SIMD_ARG_LANE_INDEX;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1530 else if (d->qualifiers[qualifiers_k] & qualifier_lane_pair_index)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1531 args[k] = SIMD_ARG_LANE_PAIR_INDEX;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1532 else if (d->qualifiers[qualifiers_k] & qualifier_lane_quadtup_index)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1533 args[k] = SIMD_ARG_LANE_QUADTUP_INDEX;
111
kono
parents:
diff changeset
1534 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
kono
parents:
diff changeset
1535 args[k] = SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
kono
parents:
diff changeset
1536 else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
kono
parents:
diff changeset
1537 args[k] = SIMD_ARG_CONSTANT;
kono
parents:
diff changeset
1538 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
kono
parents:
diff changeset
1539 {
kono
parents:
diff changeset
1540 rtx arg
kono
parents:
diff changeset
1541 = expand_normal (CALL_EXPR_ARG (exp,
kono
parents:
diff changeset
1542 (expr_args_k)));
kono
parents:
diff changeset
1543 /* Handle constants only if the predicate allows it. */
kono
parents:
diff changeset
1544 bool op_const_int_p =
kono
parents:
diff changeset
1545 (CONST_INT_P (arg)
kono
parents:
diff changeset
1546 && (*insn_data[icode].operand[operands_k].predicate)
kono
parents:
diff changeset
1547 (arg, insn_data[icode].operand[operands_k].mode));
kono
parents:
diff changeset
1548 args[k] = op_const_int_p ? SIMD_ARG_CONSTANT : SIMD_ARG_COPY_TO_REG;
kono
parents:
diff changeset
1549 }
kono
parents:
diff changeset
1550 else
kono
parents:
diff changeset
1551 args[k] = SIMD_ARG_COPY_TO_REG;
kono
parents:
diff changeset
1552
kono
parents:
diff changeset
1553 }
kono
parents:
diff changeset
1554 args[k] = SIMD_ARG_STOP;
kono
parents:
diff changeset
1555
kono
parents:
diff changeset
1556 /* The interface to aarch64_simd_expand_args expects a 0 if
kono
parents:
diff changeset
1557 the function is void, and a 1 if it is not. */
kono
parents:
diff changeset
1558 return aarch64_simd_expand_args
kono
parents:
diff changeset
1559 (target, icode, !is_void, exp, &args[1], d->mode);
kono
parents:
diff changeset
1560 }
kono
parents:
diff changeset
1561
kono
parents:
diff changeset
1562 rtx
kono
parents:
diff changeset
1563 aarch64_crc32_expand_builtin (int fcode, tree exp, rtx target)
kono
parents:
diff changeset
1564 {
kono
parents:
diff changeset
1565 rtx pat;
kono
parents:
diff changeset
1566 aarch64_crc_builtin_datum *d
kono
parents:
diff changeset
1567 = &aarch64_crc_builtin_data[fcode - (AARCH64_CRC32_BUILTIN_BASE + 1)];
kono
parents:
diff changeset
1568 enum insn_code icode = d->icode;
kono
parents:
diff changeset
1569 tree arg0 = CALL_EXPR_ARG (exp, 0);
kono
parents:
diff changeset
1570 tree arg1 = CALL_EXPR_ARG (exp, 1);
kono
parents:
diff changeset
1571 rtx op0 = expand_normal (arg0);
kono
parents:
diff changeset
1572 rtx op1 = expand_normal (arg1);
kono
parents:
diff changeset
1573 machine_mode tmode = insn_data[icode].operand[0].mode;
kono
parents:
diff changeset
1574 machine_mode mode0 = insn_data[icode].operand[1].mode;
kono
parents:
diff changeset
1575 machine_mode mode1 = insn_data[icode].operand[2].mode;
kono
parents:
diff changeset
1576
kono
parents:
diff changeset
1577 if (! target
kono
parents:
diff changeset
1578 || GET_MODE (target) != tmode
kono
parents:
diff changeset
1579 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
kono
parents:
diff changeset
1580 target = gen_reg_rtx (tmode);
kono
parents:
diff changeset
1581
kono
parents:
diff changeset
1582 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
kono
parents:
diff changeset
1583 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
kono
parents:
diff changeset
1584
kono
parents:
diff changeset
1585 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
kono
parents:
diff changeset
1586 op0 = copy_to_mode_reg (mode0, op0);
kono
parents:
diff changeset
1587 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
kono
parents:
diff changeset
1588 op1 = copy_to_mode_reg (mode1, op1);
kono
parents:
diff changeset
1589
kono
parents:
diff changeset
1590 pat = GEN_FCN (icode) (target, op0, op1);
kono
parents:
diff changeset
1591 if (!pat)
kono
parents:
diff changeset
1592 return NULL_RTX;
kono
parents:
diff changeset
1593
kono
parents:
diff changeset
1594 emit_insn (pat);
kono
parents:
diff changeset
1595 return target;
kono
parents:
diff changeset
1596 }
kono
parents:
diff changeset
1597
kono
parents:
diff changeset
1598 /* Function to expand reciprocal square root builtins. */
kono
parents:
diff changeset
1599
kono
parents:
diff changeset
1600 static rtx
kono
parents:
diff changeset
1601 aarch64_expand_builtin_rsqrt (int fcode, tree exp, rtx target)
kono
parents:
diff changeset
1602 {
kono
parents:
diff changeset
1603 tree arg0 = CALL_EXPR_ARG (exp, 0);
kono
parents:
diff changeset
1604 rtx op0 = expand_normal (arg0);
kono
parents:
diff changeset
1605
kono
parents:
diff changeset
1606 rtx (*gen) (rtx, rtx);
kono
parents:
diff changeset
1607
kono
parents:
diff changeset
1608 switch (fcode)
kono
parents:
diff changeset
1609 {
kono
parents:
diff changeset
1610 case AARCH64_BUILTIN_RSQRT_DF:
kono
parents:
diff changeset
1611 gen = gen_rsqrtdf2;
kono
parents:
diff changeset
1612 break;
kono
parents:
diff changeset
1613 case AARCH64_BUILTIN_RSQRT_SF:
kono
parents:
diff changeset
1614 gen = gen_rsqrtsf2;
kono
parents:
diff changeset
1615 break;
kono
parents:
diff changeset
1616 case AARCH64_BUILTIN_RSQRT_V2DF:
kono
parents:
diff changeset
1617 gen = gen_rsqrtv2df2;
kono
parents:
diff changeset
1618 break;
kono
parents:
diff changeset
1619 case AARCH64_BUILTIN_RSQRT_V2SF:
kono
parents:
diff changeset
1620 gen = gen_rsqrtv2sf2;
kono
parents:
diff changeset
1621 break;
kono
parents:
diff changeset
1622 case AARCH64_BUILTIN_RSQRT_V4SF:
kono
parents:
diff changeset
1623 gen = gen_rsqrtv4sf2;
kono
parents:
diff changeset
1624 break;
kono
parents:
diff changeset
1625 default: gcc_unreachable ();
kono
parents:
diff changeset
1626 }
kono
parents:
diff changeset
1627
kono
parents:
diff changeset
1628 if (!target)
kono
parents:
diff changeset
1629 target = gen_reg_rtx (GET_MODE (op0));
kono
parents:
diff changeset
1630
kono
parents:
diff changeset
1631 emit_insn (gen (target, op0));
kono
parents:
diff changeset
1632
kono
parents:
diff changeset
1633 return target;
kono
parents:
diff changeset
1634 }
kono
parents:
diff changeset
1635
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1636 /* Expand a FCMLA lane expression EXP with code FCODE and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1637 result going to TARGET if that is convenient. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1638
111
kono
parents:
diff changeset
1639 rtx
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1640 aarch64_expand_fcmla_builtin (tree exp, rtx target, int fcode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1641 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1642 int bcode = fcode - AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1643 aarch64_fcmla_laneq_builtin_datum* d
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1644 = &aarch64_fcmla_lane_builtin_data[bcode];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1645 machine_mode quadmode = GET_MODE_2XWIDER_MODE (d->mode).require ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1646 rtx op0 = force_reg (d->mode, expand_normal (CALL_EXPR_ARG (exp, 0)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1647 rtx op1 = force_reg (d->mode, expand_normal (CALL_EXPR_ARG (exp, 1)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1648 rtx op2 = force_reg (quadmode, expand_normal (CALL_EXPR_ARG (exp, 2)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1649 tree tmp = CALL_EXPR_ARG (exp, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1650 rtx lane_idx = expand_expr (tmp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1651
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1652 /* Validate that the lane index is a constant. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1653 if (!CONST_INT_P (lane_idx))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1654 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1655 error ("%Kargument %d must be a constant immediate", exp, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1656 return const0_rtx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1657 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1658
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1659 /* Validate that the index is within the expected range. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1660 int nunits = GET_MODE_NUNITS (quadmode).to_constant ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1661 aarch64_simd_lane_bounds (lane_idx, 0, nunits / 2, exp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1662
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1663 /* Generate the correct register and mode. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1664 int lane = INTVAL (lane_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1665
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1666 if (lane < nunits / 4)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1667 op2 = simplify_gen_subreg (d->mode, op2, quadmode,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1668 subreg_lowpart_offset (d->mode, quadmode));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1669 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1670 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1671 /* Select the upper 64 bits, either a V2SF or V4HF, this however
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1672 is quite messy, as the operation required even though simple
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1673 doesn't have a simple RTL pattern, and seems it's quite hard to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1674 define using a single RTL pattern. The target generic version
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1675 gen_highpart_mode generates code that isn't optimal. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1676 rtx temp1 = gen_reg_rtx (d->mode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1677 rtx temp2 = gen_reg_rtx (DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1678 temp1 = simplify_gen_subreg (d->mode, op2, quadmode,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1679 subreg_lowpart_offset (d->mode, quadmode));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1680 temp1 = simplify_gen_subreg (V2DImode, temp1, d->mode, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1681 if (BYTES_BIG_ENDIAN)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1682 emit_insn (gen_aarch64_get_lanev2di (temp2, temp1, const0_rtx));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1683 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1684 emit_insn (gen_aarch64_get_lanev2di (temp2, temp1, const1_rtx));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1685 op2 = simplify_gen_subreg (d->mode, temp2, GET_MODE (temp2), 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1686
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1687 /* And recalculate the index. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1688 lane -= nunits / 4;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1689 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1690
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1691 /* Keep to GCC-vector-extension lane indices in the RTL, only nunits / 4
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1692 (max nunits in range check) are valid. Which means only 0-1, so we
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1693 only need to know the order in a V2mode. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1694 lane_idx = aarch64_endian_lane_rtx (V2DImode, lane);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1695
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1696 if (!target)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1697 target = gen_reg_rtx (d->mode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1698 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1699 target = force_reg (d->mode, target);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1700
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1701 rtx pat = NULL_RTX;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1702
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1703 if (d->lane)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1704 pat = GEN_FCN (d->icode) (target, op0, op1, op2, lane_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1705 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1706 pat = GEN_FCN (d->icode) (target, op0, op1, op2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1707
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1708 if (!pat)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1709 return NULL_RTX;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1710
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1711 emit_insn (pat);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1712 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1713 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1714
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1715 /* Function to expand an expression EXP which calls one of the Transactional
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1716 Memory Extension (TME) builtins FCODE with the result going to TARGET. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1717 static rtx
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1718 aarch64_expand_builtin_tme (int fcode, tree exp, rtx target)
111
kono
parents:
diff changeset
1719 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1720 switch (fcode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1721 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1722 case AARCH64_TME_BUILTIN_TSTART:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1723 target = gen_reg_rtx (DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1724 emit_insn (GEN_FCN (CODE_FOR_tstart) (target));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1725 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1726
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1727 case AARCH64_TME_BUILTIN_TTEST:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1728 target = gen_reg_rtx (DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1729 emit_insn (GEN_FCN (CODE_FOR_ttest) (target));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1730 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1731
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1732 case AARCH64_TME_BUILTIN_TCOMMIT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1733 emit_insn (GEN_FCN (CODE_FOR_tcommit) ());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1734 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1735
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1736 case AARCH64_TME_BUILTIN_TCANCEL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1737 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1738 tree arg0 = CALL_EXPR_ARG (exp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1739 rtx op0 = expand_normal (arg0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1740 if (CONST_INT_P (op0) && UINTVAL (op0) <= 65536)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1741 emit_insn (GEN_FCN (CODE_FOR_tcancel) (op0));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1742 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1743 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1744 error ("%Kargument must be a 16-bit constant immediate", exp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1745 return const0_rtx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1746 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1747 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1748 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1749
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1750 default :
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1751 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1752 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1753 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1754 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1755
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1756 /* Expand a random number builtin EXP with code FCODE, putting the result
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1757 int TARGET. If IGNORE is true the return value is ignored. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1758
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1759 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1760 aarch64_expand_rng_builtin (tree exp, rtx target, int fcode, int ignore)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1761 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1762 rtx pat;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1763 enum insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1764 if (fcode == AARCH64_BUILTIN_RNG_RNDR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1765 icode = CODE_FOR_aarch64_rndr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1766 else if (fcode == AARCH64_BUILTIN_RNG_RNDRRS)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1767 icode = CODE_FOR_aarch64_rndrrs;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1768 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1769 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1770
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1771 rtx rand = gen_reg_rtx (DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1772 pat = GEN_FCN (icode) (rand);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1773 if (!pat)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1774 return NULL_RTX;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1775
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1776 tree arg0 = CALL_EXPR_ARG (exp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1777 rtx res_addr = expand_normal (arg0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1778 res_addr = convert_memory_address (Pmode, res_addr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1779 rtx res_mem = gen_rtx_MEM (DImode, res_addr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1780 emit_insn (pat);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1781 emit_move_insn (res_mem, rand);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1782 /* If the status result is unused don't generate the CSET code. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1783 if (ignore)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1784 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1785
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1786 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1787 rtx cmp_rtx = gen_rtx_fmt_ee (NE, SImode, cc_reg, const0_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1788 emit_insn (gen_aarch64_cstoresi (target, cmp_rtx, cc_reg));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1789 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1790 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1791
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1792 /* Expand an expression EXP that calls a MEMTAG built-in FCODE
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1793 with result going to TARGET. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1794 static rtx
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1795 aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1796 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1797 if (TARGET_ILP32)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1798 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1799 error ("Memory Tagging Extension does not support %<-mabi=ilp32%>");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1800 return const0_rtx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1801 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1802
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1803 rtx pat = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1804 enum insn_code icode = aarch64_memtag_builtin_data[fcode -
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1805 AARCH64_MEMTAG_BUILTIN_START - 1].icode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1806
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1807 rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1808 machine_mode mode0 = GET_MODE (op0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1809 op0 = force_reg (mode0 == VOIDmode ? DImode : mode0, op0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1810 op0 = convert_to_mode (DImode, op0, true);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1811
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1812 switch (fcode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1813 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1814 case AARCH64_MEMTAG_BUILTIN_IRG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1815 case AARCH64_MEMTAG_BUILTIN_GMI:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1816 case AARCH64_MEMTAG_BUILTIN_SUBP:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1817 case AARCH64_MEMTAG_BUILTIN_INC_TAG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1818 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1819 if (! target
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1820 || GET_MODE (target) != DImode
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1821 || ! (*insn_data[icode].operand[0].predicate) (target, DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1822 target = gen_reg_rtx (DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1823
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1824 if (fcode == AARCH64_MEMTAG_BUILTIN_INC_TAG)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1825 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1826 rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1827
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1828 if ((*insn_data[icode].operand[3].predicate) (op1, QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1829 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1830 pat = GEN_FCN (icode) (target, op0, const0_rtx, op1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1831 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1832 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1833 error ("%Kargument %d must be a constant immediate "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1834 "in range [0,15]", exp, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1835 return const0_rtx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1836 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1837 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1838 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1839 rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1840 machine_mode mode1 = GET_MODE (op1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1841 op1 = force_reg (mode1 == VOIDmode ? DImode : mode1, op1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1842 op1 = convert_to_mode (DImode, op1, true);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1843 pat = GEN_FCN (icode) (target, op0, op1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1844 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1845 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1846 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1847 case AARCH64_MEMTAG_BUILTIN_GET_TAG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1848 target = op0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1849 pat = GEN_FCN (icode) (target, op0, const0_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1850 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1851 case AARCH64_MEMTAG_BUILTIN_SET_TAG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1852 pat = GEN_FCN (icode) (op0, op0, const0_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1853 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1854 default:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1855 gcc_unreachable();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1856 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1857
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1858 if (!pat)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1859 return NULL_RTX;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1860
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1861 emit_insn (pat);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1862 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1863 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1864
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1865 /* Expand an expression EXP that calls built-in function FCODE,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1866 with result going to TARGET if that's convenient. IGNORE is true
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1867 if the result of the builtin is ignored. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1868 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1869 aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1870 int ignore)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1871 {
111
kono
parents:
diff changeset
1872 int icode;
kono
parents:
diff changeset
1873 rtx pat, op0;
kono
parents:
diff changeset
1874 tree arg0;
kono
parents:
diff changeset
1875
kono
parents:
diff changeset
1876 switch (fcode)
kono
parents:
diff changeset
1877 {
kono
parents:
diff changeset
1878 case AARCH64_BUILTIN_GET_FPCR:
kono
parents:
diff changeset
1879 case AARCH64_BUILTIN_SET_FPCR:
kono
parents:
diff changeset
1880 case AARCH64_BUILTIN_GET_FPSR:
kono
parents:
diff changeset
1881 case AARCH64_BUILTIN_SET_FPSR:
kono
parents:
diff changeset
1882 if ((fcode == AARCH64_BUILTIN_GET_FPCR)
kono
parents:
diff changeset
1883 || (fcode == AARCH64_BUILTIN_GET_FPSR))
kono
parents:
diff changeset
1884 {
kono
parents:
diff changeset
1885 icode = (fcode == AARCH64_BUILTIN_GET_FPSR) ?
kono
parents:
diff changeset
1886 CODE_FOR_get_fpsr : CODE_FOR_get_fpcr;
kono
parents:
diff changeset
1887 target = gen_reg_rtx (SImode);
kono
parents:
diff changeset
1888 pat = GEN_FCN (icode) (target);
kono
parents:
diff changeset
1889 }
kono
parents:
diff changeset
1890 else
kono
parents:
diff changeset
1891 {
kono
parents:
diff changeset
1892 target = NULL_RTX;
kono
parents:
diff changeset
1893 icode = (fcode == AARCH64_BUILTIN_SET_FPSR) ?
kono
parents:
diff changeset
1894 CODE_FOR_set_fpsr : CODE_FOR_set_fpcr;
kono
parents:
diff changeset
1895 arg0 = CALL_EXPR_ARG (exp, 0);
kono
parents:
diff changeset
1896 op0 = force_reg (SImode, expand_normal (arg0));
kono
parents:
diff changeset
1897 pat = GEN_FCN (icode) (op0);
kono
parents:
diff changeset
1898 }
kono
parents:
diff changeset
1899 emit_insn (pat);
kono
parents:
diff changeset
1900 return target;
kono
parents:
diff changeset
1901
kono
parents:
diff changeset
1902 case AARCH64_PAUTH_BUILTIN_AUTIA1716:
kono
parents:
diff changeset
1903 case AARCH64_PAUTH_BUILTIN_PACIA1716:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1904 case AARCH64_PAUTH_BUILTIN_AUTIB1716:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1905 case AARCH64_PAUTH_BUILTIN_PACIB1716:
111
kono
parents:
diff changeset
1906 case AARCH64_PAUTH_BUILTIN_XPACLRI:
kono
parents:
diff changeset
1907 arg0 = CALL_EXPR_ARG (exp, 0);
kono
parents:
diff changeset
1908 op0 = force_reg (Pmode, expand_normal (arg0));
kono
parents:
diff changeset
1909
kono
parents:
diff changeset
1910 if (!target)
kono
parents:
diff changeset
1911 target = gen_reg_rtx (Pmode);
kono
parents:
diff changeset
1912 else
kono
parents:
diff changeset
1913 target = force_reg (Pmode, target);
kono
parents:
diff changeset
1914
kono
parents:
diff changeset
1915 emit_move_insn (target, op0);
kono
parents:
diff changeset
1916
kono
parents:
diff changeset
1917 if (fcode == AARCH64_PAUTH_BUILTIN_XPACLRI)
kono
parents:
diff changeset
1918 {
kono
parents:
diff changeset
1919 rtx lr = gen_rtx_REG (Pmode, R30_REGNUM);
kono
parents:
diff changeset
1920 icode = CODE_FOR_xpaclri;
kono
parents:
diff changeset
1921 emit_move_insn (lr, op0);
kono
parents:
diff changeset
1922 emit_insn (GEN_FCN (icode) ());
kono
parents:
diff changeset
1923 emit_move_insn (target, lr);
kono
parents:
diff changeset
1924 }
kono
parents:
diff changeset
1925 else
kono
parents:
diff changeset
1926 {
kono
parents:
diff changeset
1927 tree arg1 = CALL_EXPR_ARG (exp, 1);
kono
parents:
diff changeset
1928 rtx op1 = force_reg (Pmode, expand_normal (arg1));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1929 switch (fcode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1930 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1931 case AARCH64_PAUTH_BUILTIN_AUTIA1716:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1932 icode = CODE_FOR_autia1716;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1933 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1934 case AARCH64_PAUTH_BUILTIN_AUTIB1716:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1935 icode = CODE_FOR_autib1716;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1936 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1937 case AARCH64_PAUTH_BUILTIN_PACIA1716:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1938 icode = CODE_FOR_pacia1716;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1939 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1940 case AARCH64_PAUTH_BUILTIN_PACIB1716:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1941 icode = CODE_FOR_pacib1716;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1942 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1943 default:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1944 icode = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1945 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1946 }
111
kono
parents:
diff changeset
1947
kono
parents:
diff changeset
1948 rtx x16_reg = gen_rtx_REG (Pmode, R16_REGNUM);
kono
parents:
diff changeset
1949 rtx x17_reg = gen_rtx_REG (Pmode, R17_REGNUM);
kono
parents:
diff changeset
1950 emit_move_insn (x17_reg, op0);
kono
parents:
diff changeset
1951 emit_move_insn (x16_reg, op1);
kono
parents:
diff changeset
1952 emit_insn (GEN_FCN (icode) ());
kono
parents:
diff changeset
1953 emit_move_insn (target, x17_reg);
kono
parents:
diff changeset
1954 }
kono
parents:
diff changeset
1955
kono
parents:
diff changeset
1956 return target;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1957
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1958 case AARCH64_JSCVT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1959 arg0 = CALL_EXPR_ARG (exp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1960 op0 = force_reg (DFmode, expand_normal (arg0));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1961 if (!target)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1962 target = gen_reg_rtx (SImode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1963 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1964 target = force_reg (SImode, target);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1965 emit_insn (GEN_FCN (CODE_FOR_aarch64_fjcvtzs) (target, op0));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1966 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1967
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1968 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ0_V2SF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1969 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ90_V2SF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1970 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ180_V2SF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1971 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ270_V2SF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1972 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ0_V4HF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1973 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ90_V4HF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1974 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ180_V4HF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1975 case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ270_V4HF:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1976 return aarch64_expand_fcmla_builtin (exp, target, fcode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1977 case AARCH64_BUILTIN_RNG_RNDR:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1978 case AARCH64_BUILTIN_RNG_RNDRRS:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1979 return aarch64_expand_rng_builtin (exp, target, fcode, ignore);
111
kono
parents:
diff changeset
1980 }
kono
parents:
diff changeset
1981
kono
parents:
diff changeset
1982 if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX)
kono
parents:
diff changeset
1983 return aarch64_simd_expand_builtin (fcode, exp, target);
kono
parents:
diff changeset
1984 else if (fcode >= AARCH64_CRC32_BUILTIN_BASE && fcode <= AARCH64_CRC32_BUILTIN_MAX)
kono
parents:
diff changeset
1985 return aarch64_crc32_expand_builtin (fcode, exp, target);
kono
parents:
diff changeset
1986
kono
parents:
diff changeset
1987 if (fcode == AARCH64_BUILTIN_RSQRT_DF
kono
parents:
diff changeset
1988 || fcode == AARCH64_BUILTIN_RSQRT_SF
kono
parents:
diff changeset
1989 || fcode == AARCH64_BUILTIN_RSQRT_V2DF
kono
parents:
diff changeset
1990 || fcode == AARCH64_BUILTIN_RSQRT_V2SF
kono
parents:
diff changeset
1991 || fcode == AARCH64_BUILTIN_RSQRT_V4SF)
kono
parents:
diff changeset
1992 return aarch64_expand_builtin_rsqrt (fcode, exp, target);
kono
parents:
diff changeset
1993
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1994 if (fcode == AARCH64_TME_BUILTIN_TSTART
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1995 || fcode == AARCH64_TME_BUILTIN_TCOMMIT
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1996 || fcode == AARCH64_TME_BUILTIN_TTEST
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1997 || fcode == AARCH64_TME_BUILTIN_TCANCEL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1998 return aarch64_expand_builtin_tme (fcode, exp, target);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1999
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2000 if (fcode >= AARCH64_MEMTAG_BUILTIN_START
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2001 && fcode <= AARCH64_MEMTAG_BUILTIN_END)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2002 return aarch64_expand_builtin_memtag (fcode, exp, target);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2003
111
kono
parents:
diff changeset
2004 gcc_unreachable ();
kono
parents:
diff changeset
2005 }
kono
parents:
diff changeset
2006
kono
parents:
diff changeset
2007 tree
kono
parents:
diff changeset
2008 aarch64_builtin_vectorized_function (unsigned int fn, tree type_out,
kono
parents:
diff changeset
2009 tree type_in)
kono
parents:
diff changeset
2010 {
kono
parents:
diff changeset
2011 machine_mode in_mode, out_mode;
kono
parents:
diff changeset
2012
kono
parents:
diff changeset
2013 if (TREE_CODE (type_out) != VECTOR_TYPE
kono
parents:
diff changeset
2014 || TREE_CODE (type_in) != VECTOR_TYPE)
kono
parents:
diff changeset
2015 return NULL_TREE;
kono
parents:
diff changeset
2016
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2017 out_mode = TYPE_MODE (type_out);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2018 in_mode = TYPE_MODE (type_in);
111
kono
parents:
diff changeset
2019
kono
parents:
diff changeset
2020 #undef AARCH64_CHECK_BUILTIN_MODE
kono
parents:
diff changeset
2021 #define AARCH64_CHECK_BUILTIN_MODE(C, N) 1
kono
parents:
diff changeset
2022 #define AARCH64_FIND_FRINT_VARIANT(N) \
kono
parents:
diff changeset
2023 (AARCH64_CHECK_BUILTIN_MODE (2, D) \
kono
parents:
diff changeset
2024 ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2df] \
kono
parents:
diff changeset
2025 : (AARCH64_CHECK_BUILTIN_MODE (4, S) \
kono
parents:
diff changeset
2026 ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v4sf] \
kono
parents:
diff changeset
2027 : (AARCH64_CHECK_BUILTIN_MODE (2, S) \
kono
parents:
diff changeset
2028 ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2sf] \
kono
parents:
diff changeset
2029 : NULL_TREE)))
kono
parents:
diff changeset
2030 switch (fn)
kono
parents:
diff changeset
2031 {
kono
parents:
diff changeset
2032 #undef AARCH64_CHECK_BUILTIN_MODE
kono
parents:
diff changeset
2033 #define AARCH64_CHECK_BUILTIN_MODE(C, N) \
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2034 (out_mode == V##C##N##Fmode && in_mode == V##C##N##Fmode)
111
kono
parents:
diff changeset
2035 CASE_CFN_FLOOR:
kono
parents:
diff changeset
2036 return AARCH64_FIND_FRINT_VARIANT (floor);
kono
parents:
diff changeset
2037 CASE_CFN_CEIL:
kono
parents:
diff changeset
2038 return AARCH64_FIND_FRINT_VARIANT (ceil);
kono
parents:
diff changeset
2039 CASE_CFN_TRUNC:
kono
parents:
diff changeset
2040 return AARCH64_FIND_FRINT_VARIANT (btrunc);
kono
parents:
diff changeset
2041 CASE_CFN_ROUND:
kono
parents:
diff changeset
2042 return AARCH64_FIND_FRINT_VARIANT (round);
kono
parents:
diff changeset
2043 CASE_CFN_NEARBYINT:
kono
parents:
diff changeset
2044 return AARCH64_FIND_FRINT_VARIANT (nearbyint);
kono
parents:
diff changeset
2045 CASE_CFN_SQRT:
kono
parents:
diff changeset
2046 return AARCH64_FIND_FRINT_VARIANT (sqrt);
kono
parents:
diff changeset
2047 #undef AARCH64_CHECK_BUILTIN_MODE
kono
parents:
diff changeset
2048 #define AARCH64_CHECK_BUILTIN_MODE(C, N) \
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2049 (out_mode == V##C##SImode && in_mode == V##C##N##Imode)
111
kono
parents:
diff changeset
2050 CASE_CFN_CLZ:
kono
parents:
diff changeset
2051 {
kono
parents:
diff changeset
2052 if (AARCH64_CHECK_BUILTIN_MODE (4, S))
kono
parents:
diff changeset
2053 return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si];
kono
parents:
diff changeset
2054 return NULL_TREE;
kono
parents:
diff changeset
2055 }
kono
parents:
diff changeset
2056 CASE_CFN_CTZ:
kono
parents:
diff changeset
2057 {
kono
parents:
diff changeset
2058 if (AARCH64_CHECK_BUILTIN_MODE (2, S))
kono
parents:
diff changeset
2059 return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv2si];
kono
parents:
diff changeset
2060 else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
kono
parents:
diff changeset
2061 return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv4si];
kono
parents:
diff changeset
2062 return NULL_TREE;
kono
parents:
diff changeset
2063 }
kono
parents:
diff changeset
2064 #undef AARCH64_CHECK_BUILTIN_MODE
kono
parents:
diff changeset
2065 #define AARCH64_CHECK_BUILTIN_MODE(C, N) \
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2066 (out_mode == V##C##N##Imode && in_mode == V##C##N##Fmode)
111
kono
parents:
diff changeset
2067 CASE_CFN_IFLOOR:
kono
parents:
diff changeset
2068 CASE_CFN_LFLOOR:
kono
parents:
diff changeset
2069 CASE_CFN_LLFLOOR:
kono
parents:
diff changeset
2070 {
kono
parents:
diff changeset
2071 enum aarch64_builtins builtin;
kono
parents:
diff changeset
2072 if (AARCH64_CHECK_BUILTIN_MODE (2, D))
kono
parents:
diff changeset
2073 builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di;
kono
parents:
diff changeset
2074 else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
kono
parents:
diff changeset
2075 builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si;
kono
parents:
diff changeset
2076 else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
kono
parents:
diff changeset
2077 builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si;
kono
parents:
diff changeset
2078 else
kono
parents:
diff changeset
2079 return NULL_TREE;
kono
parents:
diff changeset
2080
kono
parents:
diff changeset
2081 return aarch64_builtin_decls[builtin];
kono
parents:
diff changeset
2082 }
kono
parents:
diff changeset
2083 CASE_CFN_ICEIL:
kono
parents:
diff changeset
2084 CASE_CFN_LCEIL:
kono
parents:
diff changeset
2085 CASE_CFN_LLCEIL:
kono
parents:
diff changeset
2086 {
kono
parents:
diff changeset
2087 enum aarch64_builtins builtin;
kono
parents:
diff changeset
2088 if (AARCH64_CHECK_BUILTIN_MODE (2, D))
kono
parents:
diff changeset
2089 builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di;
kono
parents:
diff changeset
2090 else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
kono
parents:
diff changeset
2091 builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si;
kono
parents:
diff changeset
2092 else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
kono
parents:
diff changeset
2093 builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si;
kono
parents:
diff changeset
2094 else
kono
parents:
diff changeset
2095 return NULL_TREE;
kono
parents:
diff changeset
2096
kono
parents:
diff changeset
2097 return aarch64_builtin_decls[builtin];
kono
parents:
diff changeset
2098 }
kono
parents:
diff changeset
2099 CASE_CFN_IROUND:
kono
parents:
diff changeset
2100 CASE_CFN_LROUND:
kono
parents:
diff changeset
2101 CASE_CFN_LLROUND:
kono
parents:
diff changeset
2102 {
kono
parents:
diff changeset
2103 enum aarch64_builtins builtin;
kono
parents:
diff changeset
2104 if (AARCH64_CHECK_BUILTIN_MODE (2, D))
kono
parents:
diff changeset
2105 builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di;
kono
parents:
diff changeset
2106 else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
kono
parents:
diff changeset
2107 builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si;
kono
parents:
diff changeset
2108 else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
kono
parents:
diff changeset
2109 builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si;
kono
parents:
diff changeset
2110 else
kono
parents:
diff changeset
2111 return NULL_TREE;
kono
parents:
diff changeset
2112
kono
parents:
diff changeset
2113 return aarch64_builtin_decls[builtin];
kono
parents:
diff changeset
2114 }
kono
parents:
diff changeset
2115 default:
kono
parents:
diff changeset
2116 return NULL_TREE;
kono
parents:
diff changeset
2117 }
kono
parents:
diff changeset
2118
kono
parents:
diff changeset
2119 return NULL_TREE;
kono
parents:
diff changeset
2120 }
kono
parents:
diff changeset
2121
kono
parents:
diff changeset
2122 /* Return builtin for reciprocal square root. */
kono
parents:
diff changeset
2123
kono
parents:
diff changeset
2124 tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2125 aarch64_general_builtin_rsqrt (unsigned int fn)
111
kono
parents:
diff changeset
2126 {
kono
parents:
diff changeset
2127 if (fn == AARCH64_SIMD_BUILTIN_UNOP_sqrtv2df)
kono
parents:
diff changeset
2128 return aarch64_builtin_decls[AARCH64_BUILTIN_RSQRT_V2DF];
kono
parents:
diff changeset
2129 if (fn == AARCH64_SIMD_BUILTIN_UNOP_sqrtv2sf)
kono
parents:
diff changeset
2130 return aarch64_builtin_decls[AARCH64_BUILTIN_RSQRT_V2SF];
kono
parents:
diff changeset
2131 if (fn == AARCH64_SIMD_BUILTIN_UNOP_sqrtv4sf)
kono
parents:
diff changeset
2132 return aarch64_builtin_decls[AARCH64_BUILTIN_RSQRT_V4SF];
kono
parents:
diff changeset
2133 return NULL_TREE;
kono
parents:
diff changeset
2134 }
kono
parents:
diff changeset
2135
kono
parents:
diff changeset
2136 #undef VAR1
kono
parents:
diff changeset
2137 #define VAR1(T, N, MAP, A) \
kono
parents:
diff changeset
2138 case AARCH64_SIMD_BUILTIN_##T##_##N##A:
kono
parents:
diff changeset
2139
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2140 /* Try to fold a call to the built-in function with subcode FCODE. The
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2141 function is passed the N_ARGS arguments in ARGS and it returns a value
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2142 of type TYPE. Return the new expression on success and NULL_TREE on
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2143 failure. */
111
kono
parents:
diff changeset
2144 tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2145 aarch64_general_fold_builtin (unsigned int fcode, tree type,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2146 unsigned int n_args ATTRIBUTE_UNUSED, tree *args)
111
kono
parents:
diff changeset
2147 {
kono
parents:
diff changeset
2148 switch (fcode)
kono
parents:
diff changeset
2149 {
kono
parents:
diff changeset
2150 BUILTIN_VDQF (UNOP, abs, 2)
kono
parents:
diff changeset
2151 return fold_build1 (ABS_EXPR, type, args[0]);
kono
parents:
diff changeset
2152 VAR1 (UNOP, floatv2si, 2, v2sf)
kono
parents:
diff changeset
2153 VAR1 (UNOP, floatv4si, 2, v4sf)
kono
parents:
diff changeset
2154 VAR1 (UNOP, floatv2di, 2, v2df)
kono
parents:
diff changeset
2155 return fold_build1 (FLOAT_EXPR, type, args[0]);
kono
parents:
diff changeset
2156 default:
kono
parents:
diff changeset
2157 break;
kono
parents:
diff changeset
2158 }
kono
parents:
diff changeset
2159
kono
parents:
diff changeset
2160 return NULL_TREE;
kono
parents:
diff changeset
2161 }
kono
parents:
diff changeset
2162
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2163 /* Try to fold STMT, given that it's a call to the built-in function with
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2164 subcode FCODE. Return the new statement on success and null on
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2165 failure. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2166 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2167 aarch64_general_gimple_fold_builtin (unsigned int fcode, gcall *stmt)
111
kono
parents:
diff changeset
2168 {
kono
parents:
diff changeset
2169 gimple *new_stmt = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2170 unsigned nargs = gimple_call_num_args (stmt);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2171 tree *args = (nargs > 0
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2172 ? gimple_call_arg_ptr (stmt, 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2173 : &error_mark_node);
111
kono
parents:
diff changeset
2174
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2175 /* We use gimple's IFN_REDUC_(PLUS|MIN|MAX)s for float, signed int
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2176 and unsigned int; it will distinguish according to the types of
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2177 the arguments to the __builtin. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2178 switch (fcode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2179 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2180 BUILTIN_VALL (UNOP, reduc_plus_scal_, 10)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2181 new_stmt = gimple_build_call_internal (IFN_REDUC_PLUS,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2182 1, args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2183 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2184 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2185 BUILTIN_VDQIF (UNOP, reduc_smax_scal_, 10)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2186 BUILTIN_VDQ_BHSI (UNOPU, reduc_umax_scal_, 10)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2187 new_stmt = gimple_build_call_internal (IFN_REDUC_MAX,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2188 1, args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2189 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2190 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2191 BUILTIN_VDQIF (UNOP, reduc_smin_scal_, 10)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2192 BUILTIN_VDQ_BHSI (UNOPU, reduc_umin_scal_, 10)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2193 new_stmt = gimple_build_call_internal (IFN_REDUC_MIN,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2194 1, args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2195 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2196 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2197 BUILTIN_GPF (BINOP, fmulx, 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2198 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2199 gcc_assert (nargs == 2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2200 bool a0_cst_p = TREE_CODE (args[0]) == REAL_CST;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2201 bool a1_cst_p = TREE_CODE (args[1]) == REAL_CST;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2202 if (a0_cst_p || a1_cst_p)
111
kono
parents:
diff changeset
2203 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2204 if (a0_cst_p && a1_cst_p)
111
kono
parents:
diff changeset
2205 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2206 tree t0 = TREE_TYPE (args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2207 real_value a0 = (TREE_REAL_CST (args[0]));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2208 real_value a1 = (TREE_REAL_CST (args[1]));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2209 if (real_equal (&a1, &dconst0))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2210 std::swap (a0, a1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2211 /* According to real_equal (), +0 equals -0. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2212 if (real_equal (&a0, &dconst0) && real_isinf (&a1))
111
kono
parents:
diff changeset
2213 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2214 real_value res = dconst2;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2215 res.sign = a0.sign ^ a1.sign;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2216 new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2217 REAL_CST,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2218 build_real (t0, res));
111
kono
parents:
diff changeset
2219 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2220 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2221 new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2222 MULT_EXPR,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2223 args[0], args[1]);
111
kono
parents:
diff changeset
2224 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2225 else /* a0_cst_p ^ a1_cst_p. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2226 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2227 real_value const_part = a0_cst_p
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2228 ? TREE_REAL_CST (args[0]) : TREE_REAL_CST (args[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2229 if (!real_equal (&const_part, &dconst0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2230 && !real_isinf (&const_part))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2231 new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2232 MULT_EXPR, args[0],
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2233 args[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2234 }
111
kono
parents:
diff changeset
2235 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2236 if (new_stmt)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2237 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2238 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2239 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2240 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2241 break;
111
kono
parents:
diff changeset
2242 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2243 default:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2244 break;
111
kono
parents:
diff changeset
2245 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2246 return new_stmt;
111
kono
parents:
diff changeset
2247 }
kono
parents:
diff changeset
2248
kono
parents:
diff changeset
2249 void
kono
parents:
diff changeset
2250 aarch64_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
kono
parents:
diff changeset
2251 {
kono
parents:
diff changeset
2252 const unsigned AARCH64_FE_INVALID = 1;
kono
parents:
diff changeset
2253 const unsigned AARCH64_FE_DIVBYZERO = 2;
kono
parents:
diff changeset
2254 const unsigned AARCH64_FE_OVERFLOW = 4;
kono
parents:
diff changeset
2255 const unsigned AARCH64_FE_UNDERFLOW = 8;
kono
parents:
diff changeset
2256 const unsigned AARCH64_FE_INEXACT = 16;
kono
parents:
diff changeset
2257 const unsigned HOST_WIDE_INT AARCH64_FE_ALL_EXCEPT = (AARCH64_FE_INVALID
kono
parents:
diff changeset
2258 | AARCH64_FE_DIVBYZERO
kono
parents:
diff changeset
2259 | AARCH64_FE_OVERFLOW
kono
parents:
diff changeset
2260 | AARCH64_FE_UNDERFLOW
kono
parents:
diff changeset
2261 | AARCH64_FE_INEXACT);
kono
parents:
diff changeset
2262 const unsigned HOST_WIDE_INT AARCH64_FE_EXCEPT_SHIFT = 8;
kono
parents:
diff changeset
2263 tree fenv_cr, fenv_sr, get_fpcr, set_fpcr, mask_cr, mask_sr;
kono
parents:
diff changeset
2264 tree ld_fenv_cr, ld_fenv_sr, masked_fenv_cr, masked_fenv_sr, hold_fnclex_cr;
kono
parents:
diff changeset
2265 tree hold_fnclex_sr, new_fenv_var, reload_fenv, restore_fnenv, get_fpsr, set_fpsr;
kono
parents:
diff changeset
2266 tree update_call, atomic_feraiseexcept, hold_fnclex, masked_fenv, ld_fenv;
kono
parents:
diff changeset
2267
kono
parents:
diff changeset
2268 /* Generate the equivalence of :
kono
parents:
diff changeset
2269 unsigned int fenv_cr;
kono
parents:
diff changeset
2270 fenv_cr = __builtin_aarch64_get_fpcr ();
kono
parents:
diff changeset
2271
kono
parents:
diff changeset
2272 unsigned int fenv_sr;
kono
parents:
diff changeset
2273 fenv_sr = __builtin_aarch64_get_fpsr ();
kono
parents:
diff changeset
2274
kono
parents:
diff changeset
2275 Now set all exceptions to non-stop
kono
parents:
diff changeset
2276 unsigned int mask_cr
kono
parents:
diff changeset
2277 = ~(AARCH64_FE_ALL_EXCEPT << AARCH64_FE_EXCEPT_SHIFT);
kono
parents:
diff changeset
2278 unsigned int masked_cr;
kono
parents:
diff changeset
2279 masked_cr = fenv_cr & mask_cr;
kono
parents:
diff changeset
2280
kono
parents:
diff changeset
2281 And clear all exception flags
kono
parents:
diff changeset
2282 unsigned int maske_sr = ~AARCH64_FE_ALL_EXCEPT;
kono
parents:
diff changeset
2283 unsigned int masked_cr;
kono
parents:
diff changeset
2284 masked_sr = fenv_sr & mask_sr;
kono
parents:
diff changeset
2285
kono
parents:
diff changeset
2286 __builtin_aarch64_set_cr (masked_cr);
kono
parents:
diff changeset
2287 __builtin_aarch64_set_sr (masked_sr); */
kono
parents:
diff changeset
2288
kono
parents:
diff changeset
2289 fenv_cr = create_tmp_var_raw (unsigned_type_node);
kono
parents:
diff changeset
2290 fenv_sr = create_tmp_var_raw (unsigned_type_node);
kono
parents:
diff changeset
2291
kono
parents:
diff changeset
2292 get_fpcr = aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR];
kono
parents:
diff changeset
2293 set_fpcr = aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR];
kono
parents:
diff changeset
2294 get_fpsr = aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR];
kono
parents:
diff changeset
2295 set_fpsr = aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR];
kono
parents:
diff changeset
2296
kono
parents:
diff changeset
2297 mask_cr = build_int_cst (unsigned_type_node,
kono
parents:
diff changeset
2298 ~(AARCH64_FE_ALL_EXCEPT << AARCH64_FE_EXCEPT_SHIFT));
kono
parents:
diff changeset
2299 mask_sr = build_int_cst (unsigned_type_node,
kono
parents:
diff changeset
2300 ~(AARCH64_FE_ALL_EXCEPT));
kono
parents:
diff changeset
2301
kono
parents:
diff changeset
2302 ld_fenv_cr = build2 (MODIFY_EXPR, unsigned_type_node,
kono
parents:
diff changeset
2303 fenv_cr, build_call_expr (get_fpcr, 0));
kono
parents:
diff changeset
2304 ld_fenv_sr = build2 (MODIFY_EXPR, unsigned_type_node,
kono
parents:
diff changeset
2305 fenv_sr, build_call_expr (get_fpsr, 0));
kono
parents:
diff changeset
2306
kono
parents:
diff changeset
2307 masked_fenv_cr = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_cr, mask_cr);
kono
parents:
diff changeset
2308 masked_fenv_sr = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_sr, mask_sr);
kono
parents:
diff changeset
2309
kono
parents:
diff changeset
2310 hold_fnclex_cr = build_call_expr (set_fpcr, 1, masked_fenv_cr);
kono
parents:
diff changeset
2311 hold_fnclex_sr = build_call_expr (set_fpsr, 1, masked_fenv_sr);
kono
parents:
diff changeset
2312
kono
parents:
diff changeset
2313 hold_fnclex = build2 (COMPOUND_EXPR, void_type_node, hold_fnclex_cr,
kono
parents:
diff changeset
2314 hold_fnclex_sr);
kono
parents:
diff changeset
2315 masked_fenv = build2 (COMPOUND_EXPR, void_type_node, masked_fenv_cr,
kono
parents:
diff changeset
2316 masked_fenv_sr);
kono
parents:
diff changeset
2317 ld_fenv = build2 (COMPOUND_EXPR, void_type_node, ld_fenv_cr, ld_fenv_sr);
kono
parents:
diff changeset
2318
kono
parents:
diff changeset
2319 *hold = build2 (COMPOUND_EXPR, void_type_node,
kono
parents:
diff changeset
2320 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
kono
parents:
diff changeset
2321 hold_fnclex);
kono
parents:
diff changeset
2322
kono
parents:
diff changeset
2323 /* Store the value of masked_fenv to clear the exceptions:
kono
parents:
diff changeset
2324 __builtin_aarch64_set_fpsr (masked_fenv_sr); */
kono
parents:
diff changeset
2325
kono
parents:
diff changeset
2326 *clear = build_call_expr (set_fpsr, 1, masked_fenv_sr);
kono
parents:
diff changeset
2327
kono
parents:
diff changeset
2328 /* Generate the equivalent of :
kono
parents:
diff changeset
2329 unsigned int new_fenv_var;
kono
parents:
diff changeset
2330 new_fenv_var = __builtin_aarch64_get_fpsr ();
kono
parents:
diff changeset
2331
kono
parents:
diff changeset
2332 __builtin_aarch64_set_fpsr (fenv_sr);
kono
parents:
diff changeset
2333
kono
parents:
diff changeset
2334 __atomic_feraiseexcept (new_fenv_var); */
kono
parents:
diff changeset
2335
kono
parents:
diff changeset
2336 new_fenv_var = create_tmp_var_raw (unsigned_type_node);
kono
parents:
diff changeset
2337 reload_fenv = build2 (MODIFY_EXPR, unsigned_type_node,
kono
parents:
diff changeset
2338 new_fenv_var, build_call_expr (get_fpsr, 0));
kono
parents:
diff changeset
2339 restore_fnenv = build_call_expr (set_fpsr, 1, fenv_sr);
kono
parents:
diff changeset
2340 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
kono
parents:
diff changeset
2341 update_call = build_call_expr (atomic_feraiseexcept, 1,
kono
parents:
diff changeset
2342 fold_convert (integer_type_node, new_fenv_var));
kono
parents:
diff changeset
2343 *update = build2 (COMPOUND_EXPR, void_type_node,
kono
parents:
diff changeset
2344 build2 (COMPOUND_EXPR, void_type_node,
kono
parents:
diff changeset
2345 reload_fenv, restore_fnenv), update_call);
kono
parents:
diff changeset
2346 }
kono
parents:
diff changeset
2347
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2348 /* Resolve overloaded MEMTAG build-in functions. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2349 #define AARCH64_BUILTIN_SUBCODE(F) \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2350 (DECL_MD_FUNCTION_CODE (F) >> AARCH64_BUILTIN_SHIFT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2351
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2352 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2353 aarch64_resolve_overloaded_memtag (location_t loc,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2354 tree fndecl, void *pass_params)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2355 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2356 vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (pass_params);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2357 unsigned param_num = params ? params->length() : 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2358 unsigned int fcode = AARCH64_BUILTIN_SUBCODE (fndecl);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2359 tree inittype = aarch64_memtag_builtin_data[
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2360 fcode - AARCH64_MEMTAG_BUILTIN_START - 1].ftype;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2361 unsigned arg_num = list_length (TYPE_ARG_TYPES (inittype)) - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2362
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2363 if (param_num != arg_num)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2364 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2365 TREE_TYPE (fndecl) = inittype;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2366 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2367 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2368 tree retype = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2369
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2370 if (fcode == AARCH64_MEMTAG_BUILTIN_SUBP)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2371 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2372 tree t0 = TREE_TYPE ((*params)[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2373 tree t1 = TREE_TYPE ((*params)[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2374
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2375 if (t0 == error_mark_node || TREE_CODE (t0) != POINTER_TYPE)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2376 t0 = ptr_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2377 if (t1 == error_mark_node || TREE_CODE (t1) != POINTER_TYPE)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2378 t1 = ptr_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2379
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2380 if (TYPE_MODE (t0) != DImode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2381 warning_at (loc, 1, "expected 64-bit address but argument 1 is %d-bit",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2382 (int)tree_to_shwi (DECL_SIZE ((*params)[0])));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2383
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2384 if (TYPE_MODE (t1) != DImode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2385 warning_at (loc, 1, "expected 64-bit address but argument 2 is %d-bit",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2386 (int)tree_to_shwi (DECL_SIZE ((*params)[1])));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2387
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2388 retype = build_function_type_list (ptrdiff_type_node, t0, t1, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2389 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2390 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2391 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2392 tree t0 = TREE_TYPE ((*params)[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2393
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2394 if (t0 == error_mark_node || TREE_CODE (t0) != POINTER_TYPE)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2395 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2396 TREE_TYPE (fndecl) = inittype;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2397 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2398 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2399
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2400 if (TYPE_MODE (t0) != DImode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2401 warning_at (loc, 1, "expected 64-bit address but argument 1 is %d-bit",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2402 (int)tree_to_shwi (DECL_SIZE ((*params)[0])));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2403
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2404 switch (fcode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2405 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2406 case AARCH64_MEMTAG_BUILTIN_IRG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2407 retype = build_function_type_list (t0, t0, uint64_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2408 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2409 case AARCH64_MEMTAG_BUILTIN_GMI:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2410 retype = build_function_type_list (uint64_type_node, t0,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2411 uint64_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2412 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2413 case AARCH64_MEMTAG_BUILTIN_INC_TAG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2414 retype = build_function_type_list (t0, t0, unsigned_type_node, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2415 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2416 case AARCH64_MEMTAG_BUILTIN_SET_TAG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2417 retype = build_function_type_list (void_type_node, t0, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2418 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2419 case AARCH64_MEMTAG_BUILTIN_GET_TAG:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2420 retype = build_function_type_list (t0, t0, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2421 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2422 default:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2423 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2424 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2425 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2426
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2427 if (!retype || retype == error_mark_node)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2428 TREE_TYPE (fndecl) = inittype;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2429 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2430 TREE_TYPE (fndecl) = retype;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2431
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2432 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2433 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2434
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2435 /* Called at aarch64_resolve_overloaded_builtin in aarch64-c.c. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2436 tree
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2437 aarch64_resolve_overloaded_builtin_general (location_t loc, tree function,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2438 void *pass_params)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2439 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2440 unsigned int fcode = AARCH64_BUILTIN_SUBCODE (function);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2441
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2442 if (fcode >= AARCH64_MEMTAG_BUILTIN_START
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2443 && fcode <= AARCH64_MEMTAG_BUILTIN_END)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2444 return aarch64_resolve_overloaded_memtag(loc, function, pass_params);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2445
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2446 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2447 }
111
kono
parents:
diff changeset
2448
kono
parents:
diff changeset
2449 #undef AARCH64_CHECK_BUILTIN_MODE
kono
parents:
diff changeset
2450 #undef AARCH64_FIND_FRINT_VARIANT
kono
parents:
diff changeset
2451 #undef CF0
kono
parents:
diff changeset
2452 #undef CF1
kono
parents:
diff changeset
2453 #undef CF2
kono
parents:
diff changeset
2454 #undef CF3
kono
parents:
diff changeset
2455 #undef CF4
kono
parents:
diff changeset
2456 #undef CF10
kono
parents:
diff changeset
2457 #undef VAR1
kono
parents:
diff changeset
2458 #undef VAR2
kono
parents:
diff changeset
2459 #undef VAR3
kono
parents:
diff changeset
2460 #undef VAR4
kono
parents:
diff changeset
2461 #undef VAR5
kono
parents:
diff changeset
2462 #undef VAR6
kono
parents:
diff changeset
2463 #undef VAR7
kono
parents:
diff changeset
2464 #undef VAR8
kono
parents:
diff changeset
2465 #undef VAR9
kono
parents:
diff changeset
2466 #undef VAR10
kono
parents:
diff changeset
2467 #undef VAR11
kono
parents:
diff changeset
2468
kono
parents:
diff changeset
2469 #include "gt-aarch64-builtins.h"