Daily bump.
[official-gcc.git] / gcc / d / d-target.cc
blob1488bcebb2c65c7b7de6bdd6e55eea97ba80b264
1 /* d-target.cc -- Target interface for the D front end.
2 Copyright (C) 2013-2021 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 "diagnostic.h"
34 #include "stor-layout.h"
35 #include "tm.h"
36 #include "tm_p.h"
37 #include "target.h"
39 #include "d-tree.h"
40 #include "d-target.h"
42 /* Implements the Target interface defined by the front end.
43 Used for retrieving target-specific information. */
45 Target target;
47 /* Internal key handlers for `__traits(getTargetInfo)'. */
48 static tree d_handle_target_cpp_std (void);
49 static tree d_handle_target_cpp_runtime_library (void);
50 static tree d_handle_target_object_format (void);
52 /* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
53 which are always available. */
54 static const struct d_target_info_spec d_language_target_info[] =
56 /* { name, handler } */
57 { "cppStd", d_handle_target_cpp_std },
58 { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
59 { "floatAbi", NULL },
60 { "objectFormat", d_handle_target_object_format },
61 { NULL, NULL },
64 /* Table `__traits(getTargetInfo)' keys. */
65 static vec<d_target_info_spec> d_target_info_table;
68 /* Initialize the floating-point constants for TYPE. */
70 template <typename T>
71 static void
72 define_float_constants (T &f, tree type)
74 const double log10_2 = 0.30102999566398119521;
75 char buf[128];
77 /* Get back-end real mode format. */
78 const machine_mode mode = TYPE_MODE (type);
79 const real_format *fmt = REAL_MODE_FORMAT (mode);
81 /* The largest representable value that's not infinity. */
82 get_max_float (fmt, buf, sizeof (buf), false);
83 real_from_string (&f.max.rv (), buf);
85 /* The smallest representable normalized value that's not 0. */
86 snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - 1);
87 real_from_string (&f.min_normal.rv (), buf);
89 /* Floating-point NaN. */
90 real_nan (&f.nan.rv (), "", 1, mode);
92 /* Signalling floating-point NaN. */
93 real_nan (&f.snan.rv (), "", 0, mode);
95 /* Floating-point +Infinity if the target supports infinities. */
96 real_inf (&f.infinity.rv ());
98 /* The smallest increment to the value 1. */
99 if (fmt->pnan < fmt->p)
100 snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - fmt->p);
101 else
102 snprintf (buf, sizeof (buf), "0x1p%d", 1 - fmt->p);
103 real_from_string (&f.epsilon.rv (), buf);
105 /* The number of decimal digits of precision. */
106 f.dig = (fmt->p - 1) * log10_2;
108 /* The number of bits in mantissa. */
109 f.mant_dig = fmt->p;
111 /* The maximum int value such that 2** (value-1) is representable. */
112 f.max_exp = fmt->emax;
114 /* The minimum int value such that 2** (value-1) is representable as a
115 normalized value. */
116 f.min_exp = fmt->emin;
118 /* The maximum int value such that 10**value is representable. */
119 f.max_10_exp = fmt->emax * log10_2;
121 /* The minimum int value such that 10**value is representable as a
122 normalized value. */
123 f.min_10_exp = (fmt->emin - 1) * log10_2;
126 /* Initialize all variables of the Target structure. */
128 void
129 Target::_init (const Param &)
131 /* Map D frontend type and sizes to GCC back-end types. */
132 this->ptrsize = (POINTER_SIZE / BITS_PER_UNIT);
133 this->realsize = int_size_in_bytes (long_double_type_node);
134 this->realpad = (this->realsize -
135 (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));
136 this->realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);
138 /* Much of the dmd front-end uses ints for sizes and offsets, and cannot
139 handle any larger data type without some pervasive rework. */
140 this->maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (integer_type_node));
142 /* Define what type to use for size_t, ptrdiff_t. */
143 if (this->ptrsize == 8)
145 global.params.isLP64 = true;
146 Type::tsize_t = Type::basic[Tuns64];
147 Type::tptrdiff_t = Type::basic[Tint64];
149 else if (this->ptrsize == 4)
151 Type::tsize_t = Type::basic[Tuns32];
152 Type::tptrdiff_t = Type::basic[Tint32];
154 else if (this->ptrsize == 2)
156 Type::tsize_t = Type::basic[Tuns16];
157 Type::tptrdiff_t = Type::basic[Tint16];
159 else
160 sorry ("D does not support pointers on this target.");
162 Type::thash_t = Type::tsize_t;
164 /* Set-up target C ABI. */
165 this->c.longsize = int_size_in_bytes (long_integer_type_node);
166 this->c.long_doublesize = int_size_in_bytes (long_double_type_node);
168 /* Define what type to use for wchar_t. We don't want to support wide
169 characters less than "short" in D. */
170 if (WCHAR_TYPE_SIZE == 32)
171 this->c.twchar_t = Type::basic[Tdchar];
172 else if (WCHAR_TYPE_SIZE == 16)
173 this->c.twchar_t = Type::basic[Twchar];
174 else
175 sorry ("D does not support wide characters on this target.");
177 /* Set-up target C++ ABI. */
178 this->cpp.reverseOverloads = false;
179 this->cpp.exceptions = true;
180 this->cpp.twoDtorInVtable = true;
182 /* Set-up target Objective-C ABI. */
183 this->objc.supported = false;
185 /* Initialize all compile-time properties for floating-point types.
186 Should ensure that our real_t type is able to represent real_value. */
187 gcc_assert (sizeof (real_t) >= sizeof (real_value));
189 define_float_constants (this->FloatProperties, float_type_node);
190 define_float_constants (this->DoubleProperties, double_type_node);
191 define_float_constants (this->RealProperties, long_double_type_node);
193 /* Commonly used floating-point constants. */
194 const machine_mode mode = TYPE_MODE (long_double_type_node);
195 real_convert (&CTFloat::zero.rv (), mode, &dconst0);
196 real_convert (&CTFloat::one.rv (), mode, &dconst1);
197 real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
198 real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
200 /* Initialize target info tables, the keys required by the language are added
201 last, so that the OS and CPU handlers can override. */
202 targetdm.d_register_cpu_target_info ();
203 targetdm.d_register_os_target_info ();
204 d_add_target_info_handlers (d_language_target_info);
207 /* Return GCC memory alignment size for type TYPE. */
209 unsigned
210 Target::alignsize (Type *type)
212 gcc_assert (type->isTypeBasic ());
213 return min_align_of_type (build_ctype (type));
216 /* Return GCC field alignment size for type TYPE. */
218 unsigned
219 Target::fieldalign (Type *type)
221 /* Work out the correct alignment for the field decl. */
222 unsigned int align = type->alignsize () * BITS_PER_UNIT;
224 #ifdef BIGGEST_FIELD_ALIGNMENT
225 align = MIN (align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
226 #endif
228 #ifdef ADJUST_FIELD_ALIGN
229 if (type->isTypeBasic ())
230 align = ADJUST_FIELD_ALIGN (NULL_TREE, build_ctype (type), align);
231 #endif
233 /* Also controlled by -fpack-struct= */
234 if (maximum_field_alignment)
235 align = MIN (align, maximum_field_alignment);
237 return align / BITS_PER_UNIT;
240 /* Returns a Type for the va_list type of the target. */
242 Type *
243 Target::va_listType (const Loc &, Scope *)
245 if (this->tvalist)
246 return this->tvalist;
248 /* Build the "standard" abi va_list. */
249 this->tvalist = build_frontend_type (va_list_type_node);
250 if (!this->tvalist)
251 sorry ("cannot represent built-in %<va_list%> type in D");
253 /* Map the va_list type to the D frontend Type. This is to prevent both
254 errors in gimplification or an ICE in targetm.canonical_va_list_type. */
255 this->tvalist->ctype = va_list_type_node;
256 TYPE_LANG_SPECIFIC (va_list_type_node) = build_lang_type (this->tvalist);
258 return this->tvalist;
261 /* Checks whether the target supports a vector type with total size SZ
262 (in bytes) and element type TYPE. */
265 Target::isVectorTypeSupported (int sz, Type *type)
267 /* Size must be greater than zero, and a power of two. */
268 if (sz <= 0 || sz & (sz - 1))
269 return 3;
271 /* __vector(void[]) is treated same as __vector(ubyte[]) */
272 if (type == Type::tvoid)
273 type = Type::tuns8;
275 /* No support for non-trivial types, complex types, or booleans. */
276 if (!type->isTypeBasic () || type->iscomplex () || type->ty == Tbool)
277 return 2;
279 /* In [simd/vector extensions], which vector types are supported depends on
280 the target. The implementation is expected to only support the vector
281 types that are implemented in the target's hardware. */
282 unsigned HOST_WIDE_INT nunits = sz / type->size ();
283 tree ctype = build_vector_type (build_ctype (type), nunits);
285 if (!targetm.vector_mode_supported_p (TYPE_MODE (ctype)))
286 return 2;
288 return 0;
291 /* Checks whether the target supports operation OP for vectors of type TYPE.
292 For binary ops T2 is the type of the right-hand operand.
293 Returns true if the operation is supported or type is not a vector. */
295 bool
296 Target::isVectorOpSupported (Type *type, TOK op, Type *)
298 if (type->ty != Tvector)
299 return true;
301 /* Don't support if type is non-scalar, such as __vector(void[]). */
302 if (!type->isscalar ())
303 return false;
305 /* Don't support if expression cannot be represented. */
306 switch (op)
308 case TOKpow:
309 case TOKpowass:
310 /* pow() is lowered as a function call. */
311 return false;
313 case TOKmod:
314 case TOKmodass:
315 /* fmod() is lowered as a function call. */
316 if (type->isfloating ())
317 return false;
318 break;
320 case TOKandand:
321 case TOKoror:
322 /* Logical operators must have a result type of bool. */
323 return false;
325 case TOKue:
326 case TOKlg:
327 case TOKule:
328 case TOKul:
329 case TOKuge:
330 case TOKug:
331 case TOKle:
332 case TOKlt:
333 case TOKge:
334 case TOKgt:
335 case TOKleg:
336 case TOKunord:
337 case TOKequal:
338 case TOKnotequal:
339 case TOKidentity:
340 case TOKnotidentity:
341 /* Comparison operators must have a result type of bool. */
342 return false;
344 default:
345 break;
348 return true;
351 /* Return the symbol mangling of S for C++ linkage. */
353 const char *
354 TargetCPP::toMangle (Dsymbol *s)
356 return toCppMangleItanium (s);
359 /* Return the symbol mangling of CD for C++ linkage. */
361 const char *
362 TargetCPP::typeInfoMangle (ClassDeclaration *cd)
364 return cppTypeInfoMangleItanium (cd);
367 /* Get mangle name of a this-adjusting thunk to the function declaration FD
368 at call offset OFFSET for C++ linkage. */
370 const char *
371 TargetCPP::thunkMangle (FuncDeclaration *fd, int offset)
373 return cppThunkMangleItanium (fd, offset);
376 /* For a vendor-specific type, return a string containing the C++ mangling.
377 In all other cases, return NULL. */
379 const char *
380 TargetCPP::typeMangle (Type *type)
382 if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct)
384 tree ctype = build_ctype (type);
385 return targetm.mangle_type (ctype);
388 return NULL;
391 /* Return the type that will really be used for passing the given parameter
392 ARG to an extern(C++) function. */
394 Type *
395 TargetCPP::parameterType (Parameter *arg)
397 Type *t = arg->type->merge2 ();
398 if (arg->storageClass & (STCout | STCref))
399 t = t->referenceTo ();
400 else if (arg->storageClass & STClazy)
402 /* Mangle as delegate. */
403 Type *td = TypeFunction::create (NULL, t, VARARGnone, LINKd);
404 td = TypeDelegate::create (td);
405 t = t->merge2 ();
408 /* Could be a va_list, which we mangle as a pointer. */
409 Type *tvalist = target.va_listType (Loc (), NULL);
410 if (t->ty == Tsarray && tvalist->ty == Tsarray)
412 Type *tb = t->toBasetype ()->mutableOf ();
413 if (tb == tvalist)
415 tb = t->nextOf ()->pointerTo ();
416 t = tb->castMod (t->mod);
420 return t;
423 /* Checks whether TYPE is a vendor-specific fundamental type. Stores the result
424 in IS_FUNDAMENTAL and returns true if the parameter was set. */
426 bool
427 TargetCPP::fundamentalType (const Type *, bool &)
429 return false;
432 /* Get the starting offset position for fields of an `extern(C++)` class
433 that is derived from the given BASE_CLASS. */
435 unsigned
436 TargetCPP::derivedClassOffset(ClassDeclaration *base_class)
438 return base_class->structsize;
441 /* Return the default `extern (System)' linkage for the target. */
443 LINK
444 Target::systemLinkage (void)
446 unsigned link_system, link_windows;
448 if (targetdm.d_has_stdcall_convention (&link_system, &link_windows))
450 /* In [attribute/linkage], `System' is the same as `Windows' on Windows
451 platforms, and `C' on other platforms. */
452 if (link_system)
453 return LINKwindows;
456 return LINKc;
459 /* Generate a TypeTuple of the equivalent types used to determine if a
460 function argument of the given type can be passed in registers.
461 The results of this are highly platform dependent, and intended
462 primarly for use in implementing va_arg() with RTTI. */
464 TypeTuple *
465 Target::toArgTypes (Type *)
467 /* Not implemented, however this is not currently used anywhere. */
468 return NULL;
471 /* Determine return style of function, whether in registers or through a
472 hidden pointer to the caller's stack. */
474 bool
475 Target::isReturnOnStack (TypeFunction *tf, bool)
477 /* Need the back-end type to determine this, but this is called from the
478 frontend before semantic processing is finished. An accurate value
479 is not currently needed anyway. */
480 if (tf->isref)
481 return false;
483 Type *tn = tf->next->toBasetype ();
485 return (tn->ty == Tstruct || tn->ty == Tsarray);
488 /* Add all target info in HANDLERS to D_TARGET_INFO_TABLE for use by
489 Target::getTargetInfo(). */
491 void
492 d_add_target_info_handlers (const d_target_info_spec *handlers)
494 gcc_assert (handlers != NULL);
496 if (d_target_info_table.is_empty ())
497 d_target_info_table.create (8);
499 for (size_t i = 0; handlers[i].name != NULL; i++)
500 d_target_info_table.safe_push (handlers[i]);
503 /* Handle a call to `__traits(getTargetInfo, "cppStd")'. */
505 tree
506 d_handle_target_cpp_std (void)
508 return build_integer_cst (global.params.cplusplus);
511 /* Handle a call to `__traits(getTargetInfo, "cppRuntimeLibrary")'. */
513 tree
514 d_handle_target_cpp_runtime_library (void)
516 /* The driver only ever optionally links to libstdc++. */
517 const char *libstdcxx = "libstdc++";
518 return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
521 /* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
523 tree
524 d_handle_target_object_format (void)
526 const char *objfmt;
528 #ifdef OBJECT_FORMAT_ELF
529 objfmt = "elf";
530 #else
531 if (TARGET_COFF || TARGET_PECOFF)
532 objfmt = "coff";
533 else
534 objfmt = "";
535 #endif
537 return build_string_literal (strlen (objfmt) + 1, objfmt);
540 /* Look up the target info KEY in the available getTargetInfo tables, and return
541 the result as an Expression, or NULL if KEY is not found. When the key must
542 always exist, but is not supported, an empty string expression is returned.
543 LOC is the location to use for the returned expression. */
545 Expression *
546 Target::getTargetInfo (const char *key, const Loc &loc)
548 unsigned ix;
549 d_target_info_spec *spec;
551 FOR_EACH_VEC_ELT (d_target_info_table, ix, spec)
553 tree result;
555 if (strcmp (key, spec->name) != 0)
556 continue;
558 /* Get the requested information, or empty string if unhandled. */
559 if (spec->handler)
561 result = (spec->handler) ();
562 /* Handler didn't return a result, meaning it really does not support
563 the key in the current target configuration. Check whether there
564 are any other handlers which may recognize the key. */
565 if (result == NULL_TREE)
566 continue;
568 else
569 result = build_string_literal (1, "");
571 gcc_assert (result);
572 return d_eval_constant_expression (loc, result);
575 return NULL;
579 * Returns true if the implementation for object monitors is always defined
580 * in the D runtime library (rt/monitor_.d). */
582 bool
583 Target::libraryObjectMonitors (FuncDeclaration *, Statement *)
585 return true;