]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-target.cc
d/dmd: Merge upstream dmd f8e38c001
[thirdparty/gcc.git] / gcc / d / d-target.cc
CommitLineData
b4c522fa 1/* d-target.cc -- Target interface for the D front end.
a5544970 2 Copyright (C) 2013-2019 Free Software Foundation, Inc.
b4c522fa
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with GCC; see the file COPYING3. If not see
16<http://www.gnu.org/licenses/>. */
17
18#include "config.h"
19#include "system.h"
20#include "coretypes.h"
21
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"
29
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"
37
38#include "d-tree.h"
39#include "d-target.h"
40
41/* Implements the Target interface defined by the front end.
42 Used for retrieving target-specific information. */
43
44/* Type size information used by frontend. */
45int Target::ptrsize;
46int Target::c_longsize;
47int Target::realsize;
48int Target::realpad;
49int Target::realalignsize;
50bool Target::reverseCppOverloads;
51bool Target::cppExceptions;
52int Target::classinfosize;
53unsigned long long Target::maxStaticDataSize;
54
55/* Floating-point constants for for .max, .min, and other properties. */
56template <typename T> real_t Target::FPTypeProperties<T>::max;
57template <typename T> real_t Target::FPTypeProperties<T>::min_normal;
58template <typename T> real_t Target::FPTypeProperties<T>::nan;
59template <typename T> real_t Target::FPTypeProperties<T>::snan;
60template <typename T> real_t Target::FPTypeProperties<T>::infinity;
61template <typename T> real_t Target::FPTypeProperties<T>::epsilon;
62template <typename T> d_int64 Target::FPTypeProperties<T>::dig;
63template <typename T> d_int64 Target::FPTypeProperties<T>::mant_dig;
64template <typename T> d_int64 Target::FPTypeProperties<T>::max_exp;
65template <typename T> d_int64 Target::FPTypeProperties<T>::min_exp;
66template <typename T> d_int64 Target::FPTypeProperties<T>::max_10_exp;
67template <typename T> d_int64 Target::FPTypeProperties<T>::min_10_exp;
68
69
70/* Initialize the floating-point constants for TYPE. */
71
72template <typename T>
73static void
74define_float_constants (tree type)
75{
76 const double log10_2 = 0.30102999566398119521;
77 char buf[128];
78
79 /* Get back-end real mode format. */
80 const machine_mode mode = TYPE_MODE (type);
81 const real_format *fmt = REAL_MODE_FORMAT (mode);
82
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);
86
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);
90
91 /* Floating-point NaN. */
92 real_nan (&T::nan.rv (), "", 1, mode);
93
94 /* Signalling floating-point NaN. */
95 real_nan (&T::snan.rv (), "", 0, mode);
96
97 /* Floating-point +Infinity if the target supports infinities. */
98 real_inf (&T::infinity.rv ());
99
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);
106
107 /* The number of decimal digits of precision. */
108 T::dig = (fmt->p - 1) * log10_2;
109
110 /* The number of bits in mantissa. */
111 T::mant_dig = fmt->p;
112
113 /* The maximum int value such that 2** (value-1) is representable. */
114 T::max_exp = fmt->emax;
115
116 /* The minimum int value such that 2** (value-1) is representable as a
117 normalized value. */
118 T::min_exp = fmt->emin;
119
120 /* The maximum int value such that 10**value is representable. */
121 T::max_10_exp = fmt->emax * log10_2;
122
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;
126}
127
128/* Initialize all variables of the Target structure. */
129
130void
131Target::_init (void)
132{
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);
139
140 /* Size of run-time TypeInfo object. */
141 Target::classinfosize = 19 * Target::ptrsize;
142
143 /* Allow data sizes up to half of the address space. */
144 Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
145
146 /* Define what type to use for size_t, ptrdiff_t. */
147 if (POINTER_SIZE == 64)
148 {
149 global.params.isLP64 = true;
150 Tsize_t = Tuns64;
151 Tptrdiff_t = Tint64;
152 }
153 else
154 {
155 Tsize_t = Tuns32;
156 Tptrdiff_t = Tint32;
157 }
158
159 Type::tsize_t = Type::basic[Tsize_t];
160 Type::tptrdiff_t = Type::basic[Tptrdiff_t];
161 Type::thash_t = Type::tsize_t;
162
163 /* Set-up target C ABI. */
164 Target::c_longsize = int_size_in_bytes (long_integer_type_node);
165
166 /* Set-up target C++ ABI. */
167 Target::reverseCppOverloads = false;
168 Target::cppExceptions = true;
169
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));
173
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);
177
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);
184}
185
186/* Return GCC memory alignment size for type TYPE. */
187
188unsigned
189Target::alignsize (Type *type)
190{
191 gcc_assert (type->isTypeBasic ());
d7815fc4 192 return min_align_of_type (build_ctype (type));
b4c522fa
IB
193}
194
195/* Return GCC field alignment size for type TYPE. */
196
197unsigned
198Target::fieldalign (Type *type)
199{
200 /* Work out the correct alignment for the field decl. */
201 unsigned int align = type->alignsize () * BITS_PER_UNIT;
202
203#ifdef BIGGEST_FIELD_ALIGNMENT
204 align = MIN (align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
205#endif
206
207#ifdef ADJUST_FIELD_ALIGN
208 if (type->isTypeBasic ())
209 align = ADJUST_FIELD_ALIGN (NULL_TREE, build_ctype (type), align);
210#endif
211
212 /* Also controlled by -fpack-struct= */
213 if (maximum_field_alignment)
214 align = MIN (align, maximum_field_alignment);
215
216 return align / BITS_PER_UNIT;
217}
218
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. */
222
223unsigned
224Target::critsecsize (void)
225{
226 return targetdm.d_critsec_size ();
227}
228
229/* Returns a Type for the va_list type of the target. */
230
231Type *
232Target::va_listType (void)
233{
234 return Type::tvalist;
235}
236
237/* Checks whether the target supports a vector type with total size SZ
238 (in bytes) and element type TYPE. */
239
240int
241Target::isVectorTypeSupported (int sz, Type *type)
242{
243 /* Size must be greater than zero, and a power of two. */
244 if (sz <= 0 || sz & (sz - 1))
245 return 2;
246
247 /* __vector(void[]) is treated same as __vector(ubyte[]) */
248 if (type == Type::tvoid)
249 type = Type::tuns8;
250
251 /* No support for non-trivial types. */
252 if (!type->isTypeBasic ())
253 return 3;
254
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);
258
259 if (!targetm.vector_mode_supported_p (mode)
260 && !targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode)))
261 return 3;
262
263 return 0;
264}
265
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. */
269
270bool
271Target::isVectorOpSupported (Type *type, TOK op, Type *)
272{
273 if (type->ty != Tvector)
274 return true;
275
276 /* Don't support if type is non-scalar, such as __vector(void[]). */
277 if (!type->isscalar ())
278 return false;
279
280 /* Don't support if expression cannot be represented. */
281 switch (op)
282 {
283 case TOKpow:
284 case TOKpowass:
285 /* pow() is lowered as a function call. */
286 return false;
287
288 case TOKmod:
289 case TOKmodass:
290 /* fmod() is lowered as a function call. */
291 if (type->isfloating ())
292 return false;
293 break;
294
295 case TOKandand:
296 case TOKoror:
297 /* Logical operators must have a result type of bool. */
298 return false;
299
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;
318
319 default:
320 break;
321 }
322
323 return true;
324}
325
326/* Return the symbol mangling of S for C++ linkage. */
327
328const char *
329Target::toCppMangle (Dsymbol *s)
330{
331 return toCppMangleItanium (s);
332}
333
334/* Return the symbol mangling of CD for C++ linkage. */
335
336const char *
337Target::cppTypeInfoMangle (ClassDeclaration *cd)
338{
339 return cppTypeInfoMangleItanium (cd);
340}
341
342/* For a vendor-specific type, return a string containing the C++ mangling.
343 In all other cases, return NULL. */
344
345const char *
346Target::cppTypeMangle (Type *type)
347{
348 if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct)
349 {
350 tree ctype = build_ctype (type);
351 return targetm.mangle_type (ctype);
352 }
353
354 return NULL;
355}
356
357/* Return the type that will really be used for passing the given parameter
358 ARG to an extern(C++) function. */
359
360Type *
361Target::cppParameterType (Parameter *arg)
362{
363 Type *t = arg->type->merge2 ();
364 if (arg->storageClass & (STCout | STCref))
365 t = t->referenceTo ();
366 else if (arg->storageClass & STClazy)
367 {
368 /* Mangle as delegate. */
369 Type *td = TypeFunction::create (NULL, t, 0, LINKd);
370 td = TypeDelegate::create (td);
371 t = t->merge2 ();
372 }
373
374 /* Could be a va_list, which we mangle as a pointer. */
375 if (t->ty == Tsarray && Type::tvalist->ty == Tsarray)
376 {
377 Type *tb = t->toBasetype ()->mutableOf ();
378 if (tb == Type::tvalist)
379 {
380 tb = t->nextOf ()->pointerTo ();
381 t = tb->castMod (t->mod);
382 }
383 }
384
385 return t;
386}
387
c9634470
IB
388/* Checks whether TYPE is a vendor-specific fundamental type. Stores the result
389 in IS_FUNDAMENTAL and returns true if the parameter was set. */
390
391bool
392Target::cppFundamentalType (const Type *, bool &)
393{
394 return false;
395}
396
b4c522fa
IB
397/* Return the default system linkage for the target. */
398
399LINK
400Target::systemLinkage (void)
401{
402 return LINKc;
403}