annotate gcc/d/intrinsics.cc @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* intrinsics.cc -- D language compiler intrinsics.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 GCC is free software; you can redistribute it and/or modify
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 GCC is distributed in the hope that it will be useful,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 GNU General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "config.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "system.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "coretypes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "dmd/declaration.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "dmd/identifier.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "dmd/mangle.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "dmd/mangle.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "dmd/module.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "dmd/template.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "tm.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 #include "function.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 #include "tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 #include "fold-const.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 #include "stringpool.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 #include "builtins.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 #include "d-tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 /* An internal struct used to hold information on D intrinsics. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 struct intrinsic_decl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 /* The DECL_FUNCTION_CODE of this decl. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 intrinsic_code code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 /* The name of the intrinsic. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 const char *name;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 /* The module where the intrinsic is located. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 const char *module;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 /* The mangled signature decoration of the intrinsic. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 const char *deco;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 /* True if the intrinsic is only handled in CTFE. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 bool ctfeonly;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 static const intrinsic_decl intrinsic_decls[] =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 #define DEF_D_INTRINSIC(CODE, ALIAS, NAME, MODULE, DECO, CTFE) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 { INTRINSIC_ ## ALIAS, NAME, MODULE, DECO, CTFE },
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 #include "intrinsics.def"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 #undef DEF_D_INTRINSIC
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 /* Checks if DECL is an intrinsic or run time library function that requires
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 special processing. Sets DECL_INTRINSIC_CODE so it can be identified
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 later in maybe_expand_intrinsic. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 maybe_set_intrinsic (FuncDeclaration *decl)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 if (!decl->ident || decl->builtin != BUILTINunknown)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 /* The builtin flag is updated only if we can evaluate the intrinsic
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 at compile-time. Such as the math or bitop intrinsics. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 decl->builtin = BUILTINno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 /* Check if it's a compiler intrinsic. We only require that any
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 internally recognised intrinsics are declared in a module with
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 an explicit module declaration. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 Module *m = decl->getModule ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 if (!m || !m->md)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 TemplateInstance *ti = decl->isInstantiated ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 TemplateDeclaration *td = ti ? ti->tempdecl->isTemplateDeclaration () : NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 const char *tname = decl->ident->toChars ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 const char *tmodule = m->md->toChars ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 const char *tdeco = (td == NULL) ? decl->type->deco : NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 /* Look through all D intrinsics. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 for (size_t i = 0; i < (int) INTRINSIC_LAST; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 if (!intrinsic_decls[i].name)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 if (strcmp (intrinsic_decls[i].name, tname) != 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 || strcmp (intrinsic_decls[i].module, tmodule) != 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 /* Instantiated functions would have the wrong type deco, get it from the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 template member instead. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 if (tdeco == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 if (!td || !td->onemember)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 FuncDeclaration *fd = td->onemember->isFuncDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 if (fd == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 OutBuffer buf;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 mangleToBuffer (fd->type, &buf);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 tdeco = buf.extractString ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 /* Matching the type deco may be a bit too strict, as it means that all
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 function attributes that end up in the signature must be kept aligned
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 between the compiler and library declaration. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 if (strcmp (intrinsic_decls[i].deco, tdeco) == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 intrinsic_code code = intrinsic_decls[i].code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 if (decl->csym == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 get_symbol_decl (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 /* If there is no function body, then the implementation is always
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 provided by the compiler. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 if (!decl->fbody)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 set_decl_built_in_function (decl->csym, BUILT_IN_FRONTEND, code);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 /* Infer whether the intrinsic can be used for CTFE, let the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 front-end know that it can be evaluated at compile-time. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 switch (code)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 case INTRINSIC_VA_ARG:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 case INTRINSIC_C_VA_ARG:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 case INTRINSIC_VASTART:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 case INTRINSIC_ADDS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 case INTRINSIC_SUBS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 case INTRINSIC_MULS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 case INTRINSIC_NEGS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 case INTRINSIC_VLOAD:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 case INTRINSIC_VSTORE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 case INTRINSIC_POW:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 /* Check that this overload of pow() is has an equivalent
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 built-in function. It could be `int pow(int, int)'. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 tree rettype = TREE_TYPE (TREE_TYPE (decl->csym));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 if (mathfn_built_in (rettype, BUILT_IN_POW) != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 decl->builtin = BUILTINyes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 decl->builtin = BUILTINyes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 /* The intrinsic was marked as CTFE-only. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 if (intrinsic_decls[i].ctfeonly)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 DECL_BUILT_IN_CTFE (decl->csym) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 DECL_INTRINSIC_CODE (decl->csym) = code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 /* Construct a function call to the built-in function CODE, N is the number of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 arguments, and the `...' parameters are the argument expressions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 call_builtin_fn (tree callexp, built_in_function code, int n, ...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 tree *argarray = XALLOCAVEC (tree, n);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 va_list ap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 va_start (ap, n);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 for (int i = 0; i < n; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 argarray[i] = va_arg (ap, tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 va_end (ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 tree exp = build_call_expr_loc_array (EXPR_LOCATION (callexp),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 builtin_decl_explicit (code),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 n, argarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 return convert (TREE_TYPE (callexp), fold (exp));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 /* Expand a front-end instrinsic call to bsf(). This takes one argument,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 int bsf (uint arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 int bsf (ulong arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 This scans all bits in the given argument starting with the first,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 returning the bit number of the first bit set. The original call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 expand_intrinsic_bsf (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 /* The bsr() intrinsic gets turned into __builtin_ctz(arg).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 The return value is supposed to be undefined if arg is zero. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 tree arg = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 int argsize = TYPE_PRECISION (TREE_TYPE (arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 /* Which variant of __builtin_ctz* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CTZ
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_CTZL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_CTZLL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 : END_BUILTINS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 gcc_assert (code != END_BUILTINS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 return call_builtin_fn (callexp, code, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 /* Expand a front-end instrinsic call to bsr(). This takes one argument,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 int bsr (uint arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 int bsr (ulong arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 This scans all bits in the given argument from the most significant bit
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 to the least significant, returning the bit number of the first bit set.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 expand_intrinsic_bsr (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 /* The bsr() intrinsic gets turned into (size - 1) - __builtin_clz(arg).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 The return value is supposed to be undefined if arg is zero. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 tree arg = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 tree type = TREE_TYPE (arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 int argsize = TYPE_PRECISION (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 /* Which variant of __builtin_clz* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CLZ
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_CLZL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_CLZLL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 : END_BUILTINS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 gcc_assert (code != END_BUILTINS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 tree result = call_builtin_fn (callexp, code, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 /* Handle int -> long conversions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 if (TREE_TYPE (result) != type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 result = fold_convert (type, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 result = fold_build2 (MINUS_EXPR, type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 build_integer_cst (argsize - 1, type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 return fold_convert (TREE_TYPE (callexp), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 /* Expand a front-end intrinsic call to INTRINSIC, which is either a call to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 bt(), btc(), btr(), or bts(). These intrinsics expect to take two arguments,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 the signature to which is:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 int bt (size_t* ptr, size_t bitnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 All intrinsics test if a bit is set and return the result of that condition.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 Variants of `bt' will then update that bit. `btc' compliments the bit, `bts'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 sets the bit, and `btr' resets the bit. The original call expression is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 expand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 tree ptr = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 tree bitnum = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 tree type = TREE_TYPE (TREE_TYPE (ptr));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 /* size_t bitsize = sizeof(*ptr) * BITS_PER_UNIT; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 tree bitsize = fold_convert (type, TYPE_SIZE (type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 /* ptr[bitnum / bitsize] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 ptr = build_array_index (ptr, fold_build2 (TRUNC_DIV_EXPR, type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 bitnum, bitsize));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 ptr = indirect_ref (type, ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 /* mask = 1 << (bitnum % bitsize); */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 bitnum = fold_build2 (TRUNC_MOD_EXPR, type, bitnum, bitsize);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 bitnum = fold_build2 (LSHIFT_EXPR, type, size_one_node, bitnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 /* cond = ptr[bitnum / size] & mask; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 tree cond = fold_build2 (BIT_AND_EXPR, type, ptr, bitnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 /* cond ? -1 : 0; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 cond = build_condition (TREE_TYPE (callexp), d_truthvalue_conversion (cond),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 integer_minus_one_node, integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 /* Update the bit as needed, only testing the bit for bt(). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 if (intrinsic == INTRINSIC_BT)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 return cond;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 tree_code code = (intrinsic == INTRINSIC_BTC) ? BIT_XOR_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 : (intrinsic == INTRINSIC_BTR) ? BIT_AND_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 : (intrinsic == INTRINSIC_BTS) ? BIT_IOR_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 : ERROR_MARK;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 gcc_assert (code != ERROR_MARK);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 /* ptr[bitnum / size] op= mask; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 if (intrinsic == INTRINSIC_BTR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 bitnum = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (bitnum), bitnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 ptr = modify_expr (ptr, fold_build2 (code, TREE_TYPE (ptr), ptr, bitnum));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 /* Store the condition result in a temporary, and return expressions in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 correct order of evaluation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 tree tmp = build_local_temp (TREE_TYPE (callexp));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 cond = modify_expr (tmp, cond);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 return compound_expr (cond, compound_expr (ptr, tmp));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 /* Expand a front-end intrinsic call to bswap(). This takes one argument, the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 int bswap (uint arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 int bswap (ulong arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 This swaps all bytes in an N byte type end-to-end. The original call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 expand_intrinsic_bswap (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 tree arg = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 int argsize = TYPE_PRECISION (TREE_TYPE (arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 /* Which variant of __builtin_bswap* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 built_in_function code = (argsize == 32) ? BUILT_IN_BSWAP32
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 : (argsize == 64) ? BUILT_IN_BSWAP64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 : END_BUILTINS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 gcc_assert (code != END_BUILTINS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 return call_builtin_fn (callexp, code, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 /* Expand a front-end intrinsic call to popcnt(). This takes one argument, the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 int popcnt (uint arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 int popcnt (ulong arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 Calculates the number of set bits in an integer. The original call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 expand_intrinsic_popcnt (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 tree arg = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 int argsize = TYPE_PRECISION (TREE_TYPE (arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 /* Which variant of __builtin_popcount* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_POPCOUNT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_POPCOUNTL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_POPCOUNTLL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 : END_BUILTINS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 gcc_assert (code != END_BUILTINS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 return call_builtin_fn (callexp, code, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 /* Expand a front-end intrinsic call to INTRINSIC, which is either a call to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 sqrt(), sqrtf(), sqrtl(). These intrinsics expect to take one argument,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 float sqrt (float arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 double sqrt (double arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 real sqrt (real arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 This computes the square root of the given argument. The original call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 expand_intrinsic_sqrt (intrinsic_code intrinsic, tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 tree arg = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 /* Which variant of __builtin_sqrt* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 built_in_function code = (intrinsic == INTRINSIC_SQRT) ? BUILT_IN_SQRT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 : (intrinsic == INTRINSIC_SQRTF) ? BUILT_IN_SQRTF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 : (intrinsic == INTRINSIC_SQRTL) ? BUILT_IN_SQRTL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 : END_BUILTINS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 gcc_assert (code != END_BUILTINS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 return call_builtin_fn (callexp, code, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 /* Expand a front-end intrinsic call to copysign(). This takes two arguments,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 float copysign (T to, float from);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 double copysign (T to, double from);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 real copysign (T to, real from);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 This computes a value composed of TO with the sign bit of FROM. The original
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 expand_intrinsic_copysign (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 tree to = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 tree from = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 tree type = TREE_TYPE (to);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 /* Convert parameters to the same type. Prefer the first parameter unless it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 is an integral type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 if (INTEGRAL_TYPE_P (type))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 to = fold_convert (TREE_TYPE (from), to);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 type = TREE_TYPE (to);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 from = fold_convert (type, from);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 /* Which variant of __builtin_copysign* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 tree builtin = mathfn_built_in (type, BUILT_IN_COPYSIGN);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 gcc_assert (builtin != NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 return call_builtin_fn (callexp, DECL_FUNCTION_CODE (builtin), 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 to, from);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 /* Expand a front-end intrinsic call to pow(). This takes two arguments, the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 float pow (float base, T exponent);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 double pow (double base, T exponent);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 real pow (real base, T exponent);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 This computes the value of BASE raised to the power of EXPONENT.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 expand_intrinsic_pow (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 tree base = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 tree exponent = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 tree exptype = TREE_TYPE (exponent);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 /* Which variant of __builtin_pow* should we call? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 built_in_function code = SCALAR_FLOAT_TYPE_P (exptype) ? BUILT_IN_POW
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 : INTEGRAL_TYPE_P (exptype) ? BUILT_IN_POWI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 : END_BUILTINS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 gcc_assert (code != END_BUILTINS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 tree builtin = mathfn_built_in (TREE_TYPE (base), code);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 gcc_assert (builtin != NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 return call_builtin_fn (callexp, DECL_FUNCTION_CODE (builtin), 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 base, exponent);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 /* Expand a front-end intrinsic call to va_arg(). This takes either one or two
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 arguments, the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 T va_arg(T) (ref va_list ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 void va_arg(T) (va_list ap, ref T parmn);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 This retrieves the next variadic parameter that is type T from the given
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 va_list. If also given, store the value into parmn, otherwise return it.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 expand_intrinsic_vaarg (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 tree ap = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 tree parmn = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 tree type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 STRIP_NOPS (ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 if (call_expr_nargs (callexp) == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 type = TREE_TYPE (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 parmn = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 STRIP_NOPS (parmn);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 gcc_assert (TREE_CODE (parmn) == ADDR_EXPR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 parmn = TREE_OPERAND (parmn, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 type = TREE_TYPE (parmn);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 /* (T) VA_ARG_EXP<ap>; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 tree exp = build1 (VA_ARG_EXPR, type, ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 /* parmn = (T) VA_ARG_EXP<ap>; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 if (parmn != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 exp = modify_expr (parmn, exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 return exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 /* Expand a front-end intrinsic call to va_start(), which takes two arguments,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 the signature to which is:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 void va_start(T) (out va_list ap, ref T parmn);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 This initializes the va_list type, where parmn should be the last named
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 parameter. The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 expand_intrinsic_vastart (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 tree ap = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 tree parmn = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 STRIP_NOPS (ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 STRIP_NOPS (parmn);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 /* The va_list argument should already have its address taken. The second
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 argument, however, is inout and that needs to be fixed to prevent a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 warning. Could be casting, so need to check type too? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 gcc_assert (TREE_CODE (ap) == ADDR_EXPR && TREE_CODE (parmn) == ADDR_EXPR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 /* Assuming nobody tries to change the return type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 parmn = TREE_OPERAND (parmn, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 return call_builtin_fn (callexp, BUILT_IN_VA_START, 2, ap, parmn);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 /* Expand a front-end instrinsic call to INTRINSIC, which is either a call to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 adds(), addu(), subs(), subu(), negs(), muls(), or mulu(). These intrinsics
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 expect to take two or three arguments, the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 int adds (int x, int y, ref bool overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 long adds (long x, long y, ref bool overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 int negs (int x, ref bool overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 long negs (long x, ref bool overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 This performs an operation on two signed or unsigned integers, checking for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 overflow. The overflow is sticky, meaning that a sequence of operations
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 can be done and overflow need only be checked at the end. The original call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 expand_intrinsic_checkedint (intrinsic_code intrinsic, tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 tree type = TREE_TYPE (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 tree x;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 tree y;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 tree overflow;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 /* The negs() intrinsic gets turned into SUB_OVERFLOW (0, y). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 if (intrinsic == INTRINSIC_NEGS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 x = fold_convert (type, integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 y = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 overflow = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 x = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 y = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 overflow = CALL_EXPR_ARG (callexp, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 /* Which variant of *_OVERFLOW should we generate? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 internal_fn icode = (intrinsic == INTRINSIC_ADDS) ? IFN_ADD_OVERFLOW
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 : (intrinsic == INTRINSIC_SUBS) ? IFN_SUB_OVERFLOW
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 : (intrinsic == INTRINSIC_MULS) ? IFN_MUL_OVERFLOW
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 : (intrinsic == INTRINSIC_NEGS) ? IFN_SUB_OVERFLOW
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 : IFN_LAST;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 gcc_assert (icode != IFN_LAST);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 tree result
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 = build_call_expr_internal_loc (EXPR_LOCATION (callexp), icode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 build_complex_type (type), 2, x, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 STRIP_NOPS (overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 overflow = build_deref (overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 /* Assign returned result to overflow parameter, however if overflow is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 already true, maintain its value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 type = TREE_TYPE (overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 result = save_expr (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 tree exp = fold_build2 (BIT_IOR_EXPR, type, overflow,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 fold_convert (type, imaginary_part (result)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 exp = modify_expr (overflow, exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 /* Return the value of result. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 return compound_expr (exp, real_part (result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 /* Expand a front-end instrinsic call to volatileLoad(). This takes one
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 argument, the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 ubyte volatileLoad (ubyte* ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 ushort volatileLoad (ushort* ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 uint volatileLoad (uint* ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 ulong volatileLoad (ulong* ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 This reads a value from the memory location indicated by ptr. Calls to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 them are be guaranteed to not be removed (such as during DCE) or reordered
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 in the same thread. The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 expand_volatile_load (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 tree ptr = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 tree ptrtype = TREE_TYPE (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 gcc_assert (POINTER_TYPE_P (ptrtype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 /* (T) *(volatile T *) ptr; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 tree result = indirect_ref (type, ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 TREE_THIS_VOLATILE (result) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 /* Expand a front-end instrinsic call to volatileStore(). This takes two
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 arguments, the signature to which can be either:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 void volatileStore (ubyte* ptr, ubyte value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 void volatileStore (ushort* ptr, ushort value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 void volatileStore (uint* ptr, uint value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 void volatileStore (ulong* ptr, ulong value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 This writes a value to the memory location indicated by ptr. Calls to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 them are be guaranteed to not be removed (such as during DCE) or reordered
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 in the same thread. The original call expression is held in CALLEXP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 expand_volatile_store (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 tree ptr = CALL_EXPR_ARG (callexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 tree ptrtype = TREE_TYPE (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 gcc_assert (POINTER_TYPE_P (ptrtype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 /* (T) *(volatile T *) ptr; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 tree result = indirect_ref (type, ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 TREE_THIS_VOLATILE (result) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 /* (*(volatile T *) ptr) = value; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 tree value = CALL_EXPR_ARG (callexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 return modify_expr (result, value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 /* If CALLEXP is for an intrinsic , expand and return inlined compiler
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 generated instructions. Most map directly to GCC builtins, others
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 require a little extra work around them. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 maybe_expand_intrinsic (tree callexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 tree callee = CALL_EXPR_FN (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 if (TREE_CODE (callee) == ADDR_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 callee = TREE_OPERAND (callee, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 if (TREE_CODE (callee) != FUNCTION_DECL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 return callexp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 /* Don't expand CTFE-only intrinsics outside of semantic processing. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 if (DECL_BUILT_IN_CTFE (callee) && !doing_semantic_analysis_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 return callexp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 intrinsic_code intrinsic = DECL_INTRINSIC_CODE (callee);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 built_in_function code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 switch (intrinsic)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 case INTRINSIC_NONE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 return callexp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 case INTRINSIC_BSF:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 return expand_intrinsic_bsf (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 case INTRINSIC_BSR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 return expand_intrinsic_bsr (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 case INTRINSIC_BT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 case INTRINSIC_BTC:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 case INTRINSIC_BTR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 case INTRINSIC_BTS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 return expand_intrinsic_bt (intrinsic, callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 case INTRINSIC_BSWAP:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 return expand_intrinsic_bswap (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 case INTRINSIC_POPCNT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 return expand_intrinsic_popcnt (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 case INTRINSIC_COS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 return call_builtin_fn (callexp, BUILT_IN_COSL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 case INTRINSIC_SIN:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 return call_builtin_fn (callexp, BUILT_IN_SINL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 case INTRINSIC_RNDTOL:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 /* Not sure if llroundl stands as a good replacement for the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 expected behavior of rndtol. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 return call_builtin_fn (callexp, BUILT_IN_LLROUNDL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 case INTRINSIC_SQRT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 case INTRINSIC_SQRTF:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 case INTRINSIC_SQRTL:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 return expand_intrinsic_sqrt (intrinsic, callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 case INTRINSIC_LDEXP:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 return call_builtin_fn (callexp, BUILT_IN_LDEXPL, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 CALL_EXPR_ARG (callexp, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 CALL_EXPR_ARG (callexp, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 case INTRINSIC_FABS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 return call_builtin_fn (callexp, BUILT_IN_FABSL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 case INTRINSIC_RINT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 return call_builtin_fn (callexp, BUILT_IN_RINTL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 case INTRINSIC_TAN:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 return call_builtin_fn (callexp, BUILT_IN_TANL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 case INTRINSIC_ISNAN:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 return call_builtin_fn (callexp, BUILT_IN_ISNAN, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 case INTRINSIC_ISINFINITY:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 return call_builtin_fn (callexp, BUILT_IN_ISINF, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 case INTRINSIC_ISFINITE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 return call_builtin_fn (callexp, BUILT_IN_ISFINITE, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 case INTRINSIC_EXP:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 return call_builtin_fn (callexp, BUILT_IN_EXPL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 case INTRINSIC_EXPM1:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 return call_builtin_fn (callexp, BUILT_IN_EXPM1L, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 case INTRINSIC_EXP2:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 return call_builtin_fn (callexp, BUILT_IN_EXP2L, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 case INTRINSIC_LOG:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 return call_builtin_fn (callexp, BUILT_IN_LOGL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 case INTRINSIC_LOG2:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 return call_builtin_fn (callexp, BUILT_IN_LOG2L, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 case INTRINSIC_LOG10:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 return call_builtin_fn (callexp, BUILT_IN_LOG10L, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 case INTRINSIC_ROUND:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 return call_builtin_fn (callexp, BUILT_IN_ROUNDL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 case INTRINSIC_FLOORF:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 case INTRINSIC_FLOOR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 case INTRINSIC_FLOORL:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 code = (intrinsic == INTRINSIC_FLOOR) ? BUILT_IN_FLOOR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 : (intrinsic == INTRINSIC_FLOORF) ? BUILT_IN_FLOORF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 : BUILT_IN_FLOORL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 return call_builtin_fn (callexp, code, 1, CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 case INTRINSIC_CEILF:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 case INTRINSIC_CEIL:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 case INTRINSIC_CEILL:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 code = (intrinsic == INTRINSIC_CEIL) ? BUILT_IN_CEIL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 : (intrinsic == INTRINSIC_CEILF) ? BUILT_IN_CEILF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 : BUILT_IN_CEILL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 return call_builtin_fn (callexp, code, 1, CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 case INTRINSIC_TRUNC:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 return call_builtin_fn (callexp, BUILT_IN_TRUNCL, 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 CALL_EXPR_ARG (callexp, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 case INTRINSIC_FMIN:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 return call_builtin_fn (callexp, BUILT_IN_FMINL, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 CALL_EXPR_ARG (callexp, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 CALL_EXPR_ARG (callexp, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 case INTRINSIC_FMAX:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 return call_builtin_fn (callexp, BUILT_IN_FMAXL, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 CALL_EXPR_ARG (callexp, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 CALL_EXPR_ARG (callexp, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 case INTRINSIC_COPYSIGN:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 return expand_intrinsic_copysign (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 case INTRINSIC_POW:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 return expand_intrinsic_pow (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 case INTRINSIC_FMA:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 return call_builtin_fn (callexp, BUILT_IN_FMAL, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 CALL_EXPR_ARG (callexp, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 CALL_EXPR_ARG (callexp, 1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 CALL_EXPR_ARG (callexp, 2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 case INTRINSIC_VA_ARG:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 case INTRINSIC_C_VA_ARG:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 return expand_intrinsic_vaarg (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 case INTRINSIC_VASTART:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 return expand_intrinsic_vastart (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 case INTRINSIC_ADDS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 case INTRINSIC_SUBS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 case INTRINSIC_MULS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 case INTRINSIC_NEGS:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 return expand_intrinsic_checkedint (intrinsic, callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 case INTRINSIC_VLOAD:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 return expand_volatile_load (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 case INTRINSIC_VSTORE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 return expand_volatile_store (callexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 }