1 /* d-target.cc -- Target interface for the D front end.
2 Copyright (C) 2013-2020 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 "diagnostic.h"
34 #include "stor-layout.h"
42 /* Implements the Target interface defined by the front end.
43 Used for retrieving target-specific information. */
48 /* Initialize the floating-point constants for TYPE. */
52 define_float_constants (T
&f
, tree type
)
54 const double log10_2
= 0.30102999566398119521;
57 /* Get back-end real mode format. */
58 const machine_mode mode
= TYPE_MODE (type
);
59 const real_format
*fmt
= REAL_MODE_FORMAT (mode
);
61 /* The largest representable value that's not infinity. */
62 get_max_float (fmt
, buf
, sizeof (buf
), false);
63 real_from_string (&f
.max
.rv (), buf
);
65 /* The smallest representable normalized value that's not 0. */
66 snprintf (buf
, sizeof (buf
), "0x1p%d", fmt
->emin
- 1);
67 real_from_string (&f
.min_normal
.rv (), buf
);
69 /* Floating-point NaN. */
70 real_nan (&f
.nan
.rv (), "", 1, mode
);
72 /* Signalling floating-point NaN. */
73 real_nan (&f
.snan
.rv (), "", 0, mode
);
75 /* Floating-point +Infinity if the target supports infinities. */
76 real_inf (&f
.infinity
.rv ());
78 /* The smallest increment to the value 1. */
79 if (fmt
->pnan
< fmt
->p
)
80 snprintf (buf
, sizeof (buf
), "0x1p%d", fmt
->emin
- fmt
->p
);
82 snprintf (buf
, sizeof (buf
), "0x1p%d", 1 - fmt
->p
);
83 real_from_string (&f
.epsilon
.rv (), buf
);
85 /* The number of decimal digits of precision. */
86 f
.dig
= (fmt
->p
- 1) * log10_2
;
88 /* The number of bits in mantissa. */
91 /* The maximum int value such that 2** (value-1) is representable. */
92 f
.max_exp
= fmt
->emax
;
94 /* The minimum int value such that 2** (value-1) is representable as a
96 f
.min_exp
= fmt
->emin
;
98 /* The maximum int value such that 10**value is representable. */
99 f
.max_10_exp
= fmt
->emax
* log10_2
;
101 /* The minimum int value such that 10**value is representable as a
103 f
.min_10_exp
= (fmt
->emin
- 1) * log10_2
;
106 /* Initialize all variables of the Target structure. */
109 Target::_init (const Param
&)
111 /* Map D frontend type and sizes to GCC back-end types. */
112 this->ptrsize
= (POINTER_SIZE
/ BITS_PER_UNIT
);
113 this->realsize
= int_size_in_bytes (long_double_type_node
);
114 this->realpad
= (this->realsize
-
115 (TYPE_PRECISION (long_double_type_node
) / BITS_PER_UNIT
));
116 this->realalignsize
= TYPE_ALIGN_UNIT (long_double_type_node
);
118 /* Much of the dmd front-end uses ints for sizes and offsets, and cannot
119 handle any larger data type without some pervasive rework. */
120 this->maxStaticDataSize
= tree_to_shwi (TYPE_MAX_VALUE (integer_type_node
));
122 /* Define what type to use for size_t, ptrdiff_t. */
123 if (this->ptrsize
== 8)
125 global
.params
.isLP64
= true;
126 Type::tsize_t
= Type::basic
[Tuns64
];
127 Type::tptrdiff_t
= Type::basic
[Tint64
];
129 else if (this->ptrsize
== 4)
131 Type::tsize_t
= Type::basic
[Tuns32
];
132 Type::tptrdiff_t
= Type::basic
[Tint32
];
134 else if (this->ptrsize
== 2)
136 Type::tsize_t
= Type::basic
[Tuns16
];
137 Type::tptrdiff_t
= Type::basic
[Tint16
];
140 sorry ("D does not support pointers on this target.");
142 Type::thash_t
= Type::tsize_t
;
144 /* Set-up target C ABI. */
145 this->c
.longsize
= int_size_in_bytes (long_integer_type_node
);
146 this->c
.long_doublesize
= int_size_in_bytes (long_double_type_node
);
148 /* Set-up target C++ ABI. */
149 this->cpp
.reverseOverloads
= false;
150 this->cpp
.exceptions
= true;
151 this->cpp
.twoDtorInVtable
= true;
153 /* Set-up target Objective-C ABI. */
154 this->objc
.supported
= false;
156 /* Initialize all compile-time properties for floating-point types.
157 Should ensure that our real_t type is able to represent real_value. */
158 gcc_assert (sizeof (real_t
) >= sizeof (real_value
));
160 define_float_constants (this->FloatProperties
, float_type_node
);
161 define_float_constants (this->DoubleProperties
, double_type_node
);
162 define_float_constants (this->RealProperties
, long_double_type_node
);
164 /* Commonly used floating-point constants. */
165 const machine_mode mode
= TYPE_MODE (long_double_type_node
);
166 real_convert (&CTFloat::zero
.rv (), mode
, &dconst0
);
167 real_convert (&CTFloat::one
.rv (), mode
, &dconst1
);
168 real_convert (&CTFloat::minusone
.rv (), mode
, &dconstm1
);
169 real_convert (&CTFloat::half
.rv (), mode
, &dconsthalf
);
172 /* Return GCC memory alignment size for type TYPE. */
175 Target::alignsize (Type
*type
)
177 gcc_assert (type
->isTypeBasic ());
178 return min_align_of_type (build_ctype (type
));
181 /* Return GCC field alignment size for type TYPE. */
184 Target::fieldalign (Type
*type
)
186 /* Work out the correct alignment for the field decl. */
187 unsigned int align
= type
->alignsize () * BITS_PER_UNIT
;
189 #ifdef BIGGEST_FIELD_ALIGNMENT
190 align
= MIN (align
, (unsigned) BIGGEST_FIELD_ALIGNMENT
);
193 #ifdef ADJUST_FIELD_ALIGN
194 if (type
->isTypeBasic ())
195 align
= ADJUST_FIELD_ALIGN (NULL_TREE
, build_ctype (type
), align
);
198 /* Also controlled by -fpack-struct= */
199 if (maximum_field_alignment
)
200 align
= MIN (align
, maximum_field_alignment
);
202 return align
/ BITS_PER_UNIT
;
205 /* Returns a Type for the va_list type of the target. */
208 Target::va_listType (const Loc
&, Scope
*)
211 return this->tvalist
;
213 /* Build the "standard" abi va_list. */
214 this->tvalist
= build_frontend_type (va_list_type_node
);
216 sorry ("cannot represent built-in %<va_list%> type in D");
218 /* Map the va_list type to the D frontend Type. This is to prevent both
219 errors in gimplification or an ICE in targetm.canonical_va_list_type. */
220 this->tvalist
->ctype
= va_list_type_node
;
221 TYPE_LANG_SPECIFIC (va_list_type_node
) = build_lang_type (this->tvalist
);
223 return this->tvalist
;
226 /* Checks whether the target supports a vector type with total size SZ
227 (in bytes) and element type TYPE. */
230 Target::isVectorTypeSupported (int sz
, Type
*type
)
232 /* Size must be greater than zero, and a power of two. */
233 if (sz
<= 0 || sz
& (sz
- 1))
236 /* __vector(void[]) is treated same as __vector(ubyte[]) */
237 if (type
== Type::tvoid
)
240 /* No support for non-trivial types, complex types, or booleans. */
241 if (!type
->isTypeBasic () || type
->iscomplex () || type
->ty
== Tbool
)
244 /* In [simd/vector extensions], which vector types are supported depends on
245 the target. The implementation is expected to only support the vector
246 types that are implemented in the target's hardware. */
247 unsigned HOST_WIDE_INT nunits
= sz
/ type
->size ();
248 tree ctype
= build_vector_type (build_ctype (type
), nunits
);
250 if (!targetm
.vector_mode_supported_p (TYPE_MODE (ctype
)))
256 /* Checks whether the target supports operation OP for vectors of type TYPE.
257 For binary ops T2 is the type of the right-hand operand.
258 Returns true if the operation is supported or type is not a vector. */
261 Target::isVectorOpSupported (Type
*type
, TOK op
, Type
*)
263 if (type
->ty
!= Tvector
)
266 /* Don't support if type is non-scalar, such as __vector(void[]). */
267 if (!type
->isscalar ())
270 /* Don't support if expression cannot be represented. */
275 /* pow() is lowered as a function call. */
280 /* fmod() is lowered as a function call. */
281 if (type
->isfloating ())
287 /* Logical operators must have a result type of bool. */
306 /* Comparison operators must have a result type of bool. */
316 /* Return the symbol mangling of S for C++ linkage. */
319 TargetCPP::toMangle (Dsymbol
*s
)
321 return toCppMangleItanium (s
);
324 /* Return the symbol mangling of CD for C++ linkage. */
327 TargetCPP::typeInfoMangle (ClassDeclaration
*cd
)
329 return cppTypeInfoMangleItanium (cd
);
332 /* For a vendor-specific type, return a string containing the C++ mangling.
333 In all other cases, return NULL. */
336 TargetCPP::typeMangle (Type
*type
)
338 if (type
->isTypeBasic () || type
->ty
== Tvector
|| type
->ty
== Tstruct
)
340 tree ctype
= build_ctype (type
);
341 return targetm
.mangle_type (ctype
);
347 /* Return the type that will really be used for passing the given parameter
348 ARG to an extern(C++) function. */
351 TargetCPP::parameterType (Parameter
*arg
)
353 Type
*t
= arg
->type
->merge2 ();
354 if (arg
->storageClass
& (STCout
| STCref
))
355 t
= t
->referenceTo ();
356 else if (arg
->storageClass
& STClazy
)
358 /* Mangle as delegate. */
359 Type
*td
= TypeFunction::create (NULL
, t
, VARARGnone
, LINKd
);
360 td
= TypeDelegate::create (td
);
364 /* Could be a va_list, which we mangle as a pointer. */
365 Type
*tvalist
= target
.va_listType (Loc (), NULL
);
366 if (t
->ty
== Tsarray
&& tvalist
->ty
== Tsarray
)
368 Type
*tb
= t
->toBasetype ()->mutableOf ();
371 tb
= t
->nextOf ()->pointerTo ();
372 t
= tb
->castMod (t
->mod
);
379 /* Checks whether TYPE is a vendor-specific fundamental type. Stores the result
380 in IS_FUNDAMENTAL and returns true if the parameter was set. */
383 TargetCPP::fundamentalType (const Type
*, bool &)
388 /* Return the default system linkage for the target. */
391 Target::systemLinkage (void)
396 /* Generate a TypeTuple of the equivalent types used to determine if a
397 function argument of the given type can be passed in registers.
398 The results of this are highly platform dependent, and intended
399 primarly for use in implementing va_arg() with RTTI. */
402 Target::toArgTypes (Type
*)
404 /* Not implemented, however this is not currently used anywhere. */