PR rtl-optimization/88470
[official-gcc.git] / gcc / d / d-target.cc
blob86b042938af682ae24d20c3304f8191c1b9716e4
1 /* d-target.cc -- Target interface for the D front end.
2 Copyright (C) 2013-2018 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/declaration.h"
24 #include "dmd/expression.h"
25 #include "dmd/mangle.h"
26 #include "dmd/mtype.h"
27 #include "dmd/tokens.h"
28 #include "dmd/target.h"
30 #include "tree.h"
31 #include "memmodel.h"
32 #include "fold-const.h"
33 #include "stor-layout.h"
34 #include "tm.h"
35 #include "tm_p.h"
36 #include "target.h"
38 #include "d-tree.h"
39 #include "d-target.h"
41 /* Implements the Target interface defined by the front end.
42 Used for retrieving target-specific information. */
44 /* Type size information used by frontend. */
45 int Target::ptrsize;
46 int Target::c_longsize;
47 int Target::realsize;
48 int Target::realpad;
49 int Target::realalignsize;
50 bool Target::reverseCppOverloads;
51 bool Target::cppExceptions;
52 int Target::classinfosize;
53 unsigned long long Target::maxStaticDataSize;
55 /* Floating-point constants for for .max, .min, and other properties. */
56 template <typename T> real_t Target::FPTypeProperties<T>::max;
57 template <typename T> real_t Target::FPTypeProperties<T>::min_normal;
58 template <typename T> real_t Target::FPTypeProperties<T>::nan;
59 template <typename T> real_t Target::FPTypeProperties<T>::snan;
60 template <typename T> real_t Target::FPTypeProperties<T>::infinity;
61 template <typename T> real_t Target::FPTypeProperties<T>::epsilon;
62 template <typename T> d_int64 Target::FPTypeProperties<T>::dig;
63 template <typename T> d_int64 Target::FPTypeProperties<T>::mant_dig;
64 template <typename T> d_int64 Target::FPTypeProperties<T>::max_exp;
65 template <typename T> d_int64 Target::FPTypeProperties<T>::min_exp;
66 template <typename T> d_int64 Target::FPTypeProperties<T>::max_10_exp;
67 template <typename T> d_int64 Target::FPTypeProperties<T>::min_10_exp;
70 /* Initialize the floating-point constants for TYPE. */
72 template <typename T>
73 static void
74 define_float_constants (tree type)
76 const double log10_2 = 0.30102999566398119521;
77 char buf[128];
79 /* Get back-end real mode format. */
80 const machine_mode mode = TYPE_MODE (type);
81 const real_format *fmt = REAL_MODE_FORMAT (mode);
83 /* The largest representable value that's not infinity. */
84 get_max_float (fmt, buf, sizeof (buf));
85 real_from_string (&T::max.rv (), buf);
87 /* The smallest representable normalized value that's not 0. */
88 snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - 1);
89 real_from_string (&T::min_normal.rv (), buf);
91 /* Floating-point NaN. */
92 real_nan (&T::nan.rv (), "", 1, mode);
94 /* Signalling floating-point NaN. */
95 real_nan (&T::snan.rv (), "", 0, mode);
97 /* Floating-point +Infinity if the target supports infinities. */
98 real_inf (&T::infinity.rv ());
100 /* The smallest increment to the value 1. */
101 if (fmt->pnan < fmt->p)
102 snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - fmt->p);
103 else
104 snprintf (buf, sizeof (buf), "0x1p%d", 1 - fmt->p);
105 real_from_string (&T::epsilon.rv (), buf);
107 /* The number of decimal digits of precision. */
108 T::dig = (fmt->p - 1) * log10_2;
110 /* The number of bits in mantissa. */
111 T::mant_dig = fmt->p;
113 /* The maximum int value such that 2** (value-1) is representable. */
114 T::max_exp = fmt->emax;
116 /* The minimum int value such that 2** (value-1) is representable as a
117 normalized value. */
118 T::min_exp = fmt->emin;
120 /* The maximum int value such that 10**value is representable. */
121 T::max_10_exp = fmt->emax * log10_2;
123 /* The minimum int value such that 10**value is representable as a
124 normalized value. */
125 T::min_10_exp = (fmt->emin - 1) * log10_2;
128 /* Initialize all variables of the Target structure. */
130 void
131 Target::_init (void)
133 /* Map D frontend type and sizes to GCC back-end types. */
134 Target::ptrsize = (POINTER_SIZE / BITS_PER_UNIT);
135 Target::realsize = int_size_in_bytes (long_double_type_node);
136 Target::realpad = (Target::realsize -
137 (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));
138 Target::realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);
140 /* Size of run-time TypeInfo object. */
141 Target::classinfosize = 19 * Target::ptrsize;
143 /* Allow data sizes up to half of the address space. */
144 Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
146 /* Define what type to use for size_t, ptrdiff_t. */
147 if (POINTER_SIZE == 64)
149 global.params.isLP64 = true;
150 Tsize_t = Tuns64;
151 Tptrdiff_t = Tint64;
153 else
155 Tsize_t = Tuns32;
156 Tptrdiff_t = Tint32;
159 Type::tsize_t = Type::basic[Tsize_t];
160 Type::tptrdiff_t = Type::basic[Tptrdiff_t];
161 Type::thash_t = Type::tsize_t;
163 /* Set-up target C ABI. */
164 Target::c_longsize = int_size_in_bytes (long_integer_type_node);
166 /* Set-up target C++ ABI. */
167 Target::reverseCppOverloads = false;
168 Target::cppExceptions = true;
170 /* Initialize all compile-time properties for floating-point types.
171 Should ensure that our real_t type is able to represent real_value. */
172 gcc_assert (sizeof (real_t) >= sizeof (real_value));
174 define_float_constants <Target::FloatProperties> (float_type_node);
175 define_float_constants <Target::DoubleProperties> (double_type_node);
176 define_float_constants <Target::RealProperties> (long_double_type_node);
178 /* Commonly used floating-point constants. */
179 const machine_mode mode = TYPE_MODE (long_double_type_node);
180 real_convert (&CTFloat::zero.rv (), mode, &dconst0);
181 real_convert (&CTFloat::one.rv (), mode, &dconst1);
182 real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
183 real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
186 /* Return GCC memory alignment size for type TYPE. */
188 unsigned
189 Target::alignsize (Type *type)
191 gcc_assert (type->isTypeBasic ());
192 return min_align_of_type (build_ctype (type));
195 /* Return GCC field alignment size for type TYPE. */
197 unsigned
198 Target::fieldalign (Type *type)
200 /* Work out the correct alignment for the field decl. */
201 unsigned int align = type->alignsize () * BITS_PER_UNIT;
203 #ifdef BIGGEST_FIELD_ALIGNMENT
204 align = MIN (align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
205 #endif
207 #ifdef ADJUST_FIELD_ALIGN
208 if (type->isTypeBasic ())
209 align = ADJUST_FIELD_ALIGN (NULL_TREE, build_ctype (type), align);
210 #endif
212 /* Also controlled by -fpack-struct= */
213 if (maximum_field_alignment)
214 align = MIN (align, maximum_field_alignment);
216 return align / BITS_PER_UNIT;
219 /* Return size of OS critical section.
220 Can't use the sizeof () calls directly since cross compiling is supported
221 and would end up using the host sizes rather than the target sizes. */
223 unsigned
224 Target::critsecsize (void)
226 return targetdm.d_critsec_size ();
229 /* Returns a Type for the va_list type of the target. */
231 Type *
232 Target::va_listType (void)
234 return Type::tvalist;
237 /* Checks whether the target supports a vector type with total size SZ
238 (in bytes) and element type TYPE. */
241 Target::isVectorTypeSupported (int sz, Type *type)
243 /* Size must be greater than zero, and a power of two. */
244 if (sz <= 0 || sz & (sz - 1))
245 return 2;
247 /* __vector(void[]) is treated same as __vector(ubyte[]) */
248 if (type == Type::tvoid)
249 type = Type::tuns8;
251 /* No support for non-trivial types. */
252 if (!type->isTypeBasic ())
253 return 3;
255 /* If there is no hardware support, check if we can safely emulate it. */
256 tree ctype = build_ctype (type);
257 machine_mode mode = TYPE_MODE (ctype);
259 if (!targetm.vector_mode_supported_p (mode)
260 && !targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode)))
261 return 3;
263 return 0;
266 /* Checks whether the target supports operation OP for vectors of type TYPE.
267 For binary ops T2 is the type of the right-hand operand.
268 Returns true if the operation is supported or type is not a vector. */
270 bool
271 Target::isVectorOpSupported (Type *type, TOK op, Type *)
273 if (type->ty != Tvector)
274 return true;
276 /* Don't support if type is non-scalar, such as __vector(void[]). */
277 if (!type->isscalar ())
278 return false;
280 /* Don't support if expression cannot be represented. */
281 switch (op)
283 case TOKpow:
284 case TOKpowass:
285 /* pow() is lowered as a function call. */
286 return false;
288 case TOKmod:
289 case TOKmodass:
290 /* fmod() is lowered as a function call. */
291 if (type->isfloating ())
292 return false;
293 break;
295 case TOKandand:
296 case TOKoror:
297 /* Logical operators must have a result type of bool. */
298 return false;
300 case TOKue:
301 case TOKlg:
302 case TOKule:
303 case TOKul:
304 case TOKuge:
305 case TOKug:
306 case TOKle:
307 case TOKlt:
308 case TOKge:
309 case TOKgt:
310 case TOKleg:
311 case TOKunord:
312 case TOKequal:
313 case TOKnotequal:
314 case TOKidentity:
315 case TOKnotidentity:
316 /* Comparison operators must have a result type of bool. */
317 return false;
319 default:
320 break;
323 return true;
326 /* Return the symbol mangling of S for C++ linkage. */
328 const char *
329 Target::toCppMangle (Dsymbol *s)
331 return toCppMangleItanium (s);
334 /* Return the symbol mangling of CD for C++ linkage. */
336 const char *
337 Target::cppTypeInfoMangle (ClassDeclaration *cd)
339 return cppTypeInfoMangleItanium (cd);
342 /* For a vendor-specific type, return a string containing the C++ mangling.
343 In all other cases, return NULL. */
345 const char *
346 Target::cppTypeMangle (Type *type)
348 if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct)
350 tree ctype = build_ctype (type);
351 return targetm.mangle_type (ctype);
354 return NULL;
357 /* Return the type that will really be used for passing the given parameter
358 ARG to an extern(C++) function. */
360 Type *
361 Target::cppParameterType (Parameter *arg)
363 Type *t = arg->type->merge2 ();
364 if (arg->storageClass & (STCout | STCref))
365 t = t->referenceTo ();
366 else if (arg->storageClass & STClazy)
368 /* Mangle as delegate. */
369 Type *td = TypeFunction::create (NULL, t, 0, LINKd);
370 td = TypeDelegate::create (td);
371 t = t->merge2 ();
374 /* Could be a va_list, which we mangle as a pointer. */
375 if (t->ty == Tsarray && Type::tvalist->ty == Tsarray)
377 Type *tb = t->toBasetype ()->mutableOf ();
378 if (tb == Type::tvalist)
380 tb = t->nextOf ()->pointerTo ();
381 t = tb->castMod (t->mod);
385 return t;
388 /* Return the default system linkage for the target. */
390 LINK
391 Target::systemLinkage (void)
393 return LINKc;