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)
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/>. */
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"
32 #include "fold-const.h"
33 #include "stor-layout.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. */
46 int Target::c_longsize
;
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. */
74 define_float_constants (tree type
)
76 const double log10_2
= 0.30102999566398119521;
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
);
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
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
125 T::min_10_exp
= (fmt
->emin
- 1) * log10_2
;
128 /* Initialize all variables of the Target structure. */
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;
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. */
189 Target::alignsize (Type
*type
)
191 gcc_assert (type
->isTypeBasic ());
192 return TYPE_ALIGN_UNIT (build_ctype (type
));
195 /* Return GCC field alignment size for type TYPE. */
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
);
207 #ifdef ADJUST_FIELD_ALIGN
208 if (type
->isTypeBasic ())
209 align
= ADJUST_FIELD_ALIGN (NULL_TREE
, build_ctype (type
), align
);
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. */
224 Target::critsecsize (void)
226 return targetdm
.d_critsec_size ();
229 /* Returns a Type for the va_list type of the target. */
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))
247 /* __vector(void[]) is treated same as __vector(ubyte[]) */
248 if (type
== Type::tvoid
)
251 /* No support for non-trivial types. */
252 if (!type
->isTypeBasic ())
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
)))
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. */
271 Target::isVectorOpSupported (Type
*type
, TOK op
, Type
*)
273 if (type
->ty
!= Tvector
)
276 /* Don't support if type is non-scalar, such as __vector(void[]). */
277 if (!type
->isscalar ())
280 /* Don't support if expression cannot be represented. */
285 /* pow() is lowered as a function call. */
290 /* fmod() is lowered as a function call. */
291 if (type
->isfloating ())
297 /* Logical operators must have a result type of bool. */
316 /* Comparison operators must have a result type of bool. */
326 /* Return the symbol mangling of S for C++ linkage. */
329 Target::toCppMangle (Dsymbol
*s
)
331 return toCppMangleItanium (s
);
334 /* Return the symbol mangling of CD for C++ linkage. */
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. */
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
);
357 /* Return the type that will really be used for passing the given parameter
358 ARG to an extern(C++) function. */
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
);
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
);
388 /* Return the default system linkage for the target. */
391 Target::systemLinkage (void)