diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index 144d5b88483b16f1477569f7d049b464bccf8704..b5264613db0cf08c37cde13e4a145ff43840b12d 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -239,6 +239,7 @@ d21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(d.prev) D_TEXI_FILES = \ d/gdc.texi \ + d/implement-d.texi \ $(gcc_docdir)/include/fdl.texi \ $(gcc_docdir)/include/gpl_v3.texi \ $(gcc_docdir)/include/gcc-common.texi \ diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi index 45dc544e83fb4eece9220be024e7375d351d22a6..c99c36558a9f7ca640cd9fdb1c65db3e8f87d1ea 100644 --- a/gcc/d/gdc.texi +++ b/gcc/d/gdc.texi @@ -65,13 +65,15 @@ Boston, MA 02110-1301, USA@* @top Introduction This manual describes how to use @command{gdc}, the GNU compiler for -the D programming language. This manual is specifically about -@command{gdc}. For more information about the D programming -language in general, including language specifications and standard -package documentation, see @uref{https://dlang.org/}. +the D programming language. This manual is specifically about how to +invoke @command{gdc}, as well as its features and incompatibilities. +For more information about the D programming language in general, +including language specifications and standard package documentation, +see @uref{https://dlang.org/}. @menu * Invoking gdc:: How to run gdc. +* D Implementation:: User-visible implementation details. * Copying:: The GNU General Public License. * GNU Free Documentation License:: How you can share and copy this manual. @@ -838,6 +840,8 @@ and all @code{function} bodies that are being compiled. @c man end +@include implement-d.texi + @include gpl_v3.texi @include fdl.texi diff --git a/gcc/d/implement-d.texi b/gcc/d/implement-d.texi new file mode 100644 index 0000000000000000000000000000000000000000..8f3f825e7973af7f614ecd6a45de33ccf962f45a --- /dev/null +++ b/gcc/d/implement-d.texi @@ -0,0 +1,2514 @@ +@ignore +Copyright (C) 2022 Free Software Foundation, Inc. +This is part of the GNU D manual. +For copying conditions, see the file gdc.texi. +@end ignore + +@node D Implementation +@chapter Language Reference +@cindex language reference, D language + +The implementation of the D programming language used by the GNU D compiler is +shared with parts of the front-end for the Digital Mars D compiler, hosted at +@uref{https://github.com/dlang/dmd/}. This common front-end covers lexical +analysis, parsing, and semantic analysis of the D programming language defined +in the documents at @uref{https://dlang.org/}. + +The implementation details described in this manual are GNU D extensions to the +D programming language. If you want to write code that checks whether these +features are available, you can test for the predefined version @code{GNU}, or +you can check whether a specific feature is compilable using +@code{__traits(compiles)}. + +@smallexample +version (GNU) +@{ + import gcc.builtins; + return __builtin_atan2(x, y); +@} + +static if (__traits(compiles, @{ asm @{"";@} @})) +@{ + asm @{ "magic instruction"; @} +@} +@end smallexample + +@menu +* Attributes:: Implementation-defined attributes. +* Builtin Functions:: GCC built-ins module. +* ImportC:: Importing C sources into D. +* Inline Assembly:: Interfacing D with assembler. +* Intrinsics:: Intrinsic functions supported by GDC. +* Predefined Pragmas:: Pragmas accepted by GDC. +* Predefined Versions:: List of versions for conditional compilation. +* Special Enums:: Intrinsic type interoperability with C and C++. +* Traits:: Compile-time reflection extensions. +* Vector Extensions:: Using vector types and supported operations. +* Vector Intrinsics:: Vector instructions through intrinsics. +* Missing Features:: Deviations from the D2 specification in GDC. +@end menu + + +@c -------------------------------------------------------- + +@node Attributes +@section Attributes +@cindex attributes + +User-Defined Attributes (UDA) are compile-time expressions introduced by the +@code{@@} token that can be attached to a declaration. These attributes can +then be queried, extracted, and manipulated at compile time. + +GNU D provides a number of extra special attributes to control specific +compiler behavior that may help the compiler optimize or check code more +carefully for correctness. The attributes are defined in the +@code{gcc.attributes} module. + +There is some overlap between the purposes of attributes and pragmas. It has +been found more convenient to use @code{@@attribute} to achieve a natural +attachment of attributes to their corresponding declarations, whereas +@code{pragma} is of use for compatibility with other compilers or constructs +that do not naturally form part of the grammar. + +@menu +* Attribute Syntax:: +* Common Attributes:: +* Other Attributes:: +* Target Attributes:: +@end menu + +@c -------------------------------------------------------- + +@node Attribute Syntax +@subsection Attribute Syntax + +@code{@@(gcc.attributes.attribute)} is the generic entrypoint for applying GCC +attributes to a function, variable, or type. There is no type checking done, +as well as no deprecation path for attributes removed from the compiler. So +the recommendation is to use any of the other UDAs available as described in +@ref{Common Attributes} unless it is a target-specific attribute +(@xref{Target Attributes}). + +Function attributes introduced by the @code{@@attribute} UDA are used in the +declaration of a function, followed by an attribute name string and any +arguments separated by commas enclosed in parentheses. + +@smallexample +import gcc.attributes; +@@attribute("regparm", 1) int func(int size); +@end smallexample + +@noindent +Multiple attributes can be applied to a single declaration either with multiple +@code{@@attribute} attributes, or passing all attributes as a comma-separated +list enclosed by parentheses. + +@smallexample +// Both func1 and func2 have the same attributes applied. +@@attribute("noinline") @@attribute("noclone") void func1(); +@@(attribute("noinline"), attribute("noclone")) void func2(); +@end smallexample + +@noindent +There are some problems with the semantics of such attributes in D. For +example, there are no manglings for attributes, although they may affect code +generation, so problems may arise when attributed types are used in conjunction +with templates or overloading. Similarly, @code{typeid} does not distinguish +between types with different attributes. Support for attributes in D are +restricted to declarations only. + +@c -------------------------------------------------------- + +@node Common Attributes +@subsection Common Attributes + +The following attributes are supported on most targets. + +@table @code + +@item @@(gcc.attributes.alloc_size (@var{sizeArgIdx})) +@itemx @@(gcc.attributes.alloc_size (@var{sizeArgIdx}, @var{numArgIdx})) +@itemx @@(gcc.attributes.alloc_size (@var{sizeArgIdx}, @var{numArgIdx}, @var{zeroBasedNumbering})) +@cindex @code{alloc_size} function attribute +@cindex @code{alloc_size} variable attribute + +The @code{@@alloc_size} attribute may be applied to a function - or a function +pointer variable - that returns a pointer and takes at least one argument of +an integer or enumerated type. It indicates that the returned pointer points +to memory whose size is given by the function argument at @code{sizeArgIdx}, or +by the product of the arguments at @code{sizeArgIdx} and @code{numArgIdx}. +Meaningful sizes are positive values less than @code{ptrdiff_t.max}. Unless +@code{zeroBasedNumbering} is true, argument numbering starts at one for +ordinary functions, and at two for non-static member functions. + +If @code{numArgIdx} is less than @code{0}, it is taken to mean there is no +argument specifying the element count. + +@smallexample +@@alloc_size(1) void* malloc(size_t); +@@alloc_size(3,2) void* reallocarray(void *, size_t, size_t); +@@alloc_size(1,2) void* my_calloc(size_t, size_t, bool); +void malloc_cb(@@alloc_size(1) void* function(size_t) ptr) @{ @} +@end smallexample + +@item @@(gcc.attributes.always_inline) +@cindex @code{always_inline} function attribute + +The @code{@@always_inline} attribute inlines the function independent of any +restrictions that otherwise apply to inlining. Failure to inline such a +function is diagnosed as an error. + +@smallexample +@@always_inline int func(); +@end smallexample + +@item @@(gcc.attributes.cold) +@cindex @code{cold} function attribute + +The @code{@@cold} attribute on functions is used to inform the compiler that the +function is unlikely to be executed. The function is optimized for size +rather than speed and on many targets it is placed into a special subsection +of the text section so all cold functions appear close together, improving +code locality of non-cold parts of program. The paths leading to calls of +cold functions within code are considered to be cold too. + +@smallexample +@@cold int func(); +@end smallexample + +@item @@(gcc.attributes.flatten) +@cindex @code{flatten} function attribute + +The @code{@@flatten} attribute is used to inform the compiler that every call +inside this function should be inlined, if possible. Functions declared with +attribute @code{@@noinline} and similar are not inlined. + +@smallexample +@@flatten int func(); +@end smallexample + +@item @@(gcc.attributes.no_icf) +@cindex @code{no_icf} function attribute + +The @code{@@no_icf} attribute prevents a function from being merged with +another semantically equivalent function. + +@smallexample +@@no_icf int func(); +@end smallexample + +@item @@(gcc.attributes.no_sanitize ("@var{sanitize_option}")) +@cindex @code{no_sanitize} function attribute + +The @code{@@no_sanitize} attribute on functions is used to inform the compiler +that it should not do sanitization of any option mentioned in +@var{sanitize_option}. A list of values acceptable by the @option{-fsanitize} +option can be provided. + +@smallexample +@@no_sanitize("alignment", "object-size") void func1() @{ @} +@@no_sanitize("alignment,object-size") void func2() @{ @} +@end smallexample + +@item @@(gcc.attributes.noclone) +@cindex @code{noclone} function attribute + +The @code{@@noclone} attribute prevents a function from being considered for +cloning - a mechanism that produces specialized copies of functions and which +is (currently) performed by interprocedural constant propagation. + +@smallexample +@@noclone int func(); +@end smallexample + +@item @@(gcc.attributes.noinline) +@cindex @code{noinline} function attribute + +The @code{@@noinline} attribute prevents a function from being considered for +inlining. If the function does not have side effects, there are optimizations +other than inlining that cause function calls to be optimized away, although +the function call is live. To keep such calls from being optimized away, put +@code{asm @{ ""; @}} in the called function, to serve as a special side effect. + +@smallexample +@@noinline int func(); +@end smallexample + +@item @@(gcc.attributes.noipa) +@cindex @code{noipa} function attribute + +The @code{@@noipa} attribute disables interprocedural optimizations between the +function with this attribute and its callers, as if the body of the function is +not available when optimizing callers and the callers are unavailable when +optimizing the body. This attribute implies @code{@@noinline}, +@code{@@noclone}, and @code{@@no_icf} attributes. However, this attribute is +not equivalent to a combination of other attributes, because its purpose is to +suppress existing and future optimizations employing interprocedural analysis, +including those that do not have an attribute suitable for disabling them +individually. + +This attribute is supported mainly for the purpose of testing the compiler. + +@smallexample +@@noipa int func(); +@end smallexample + +@item @@(gcc.attributes.noplt) +@cindex @code{noplt} function attribute + +The @code{@@noplt} attribute is the counterpart to option @option{-fno-plt}. +Calls to functions marked with this attribute in position-independent code do +not use the PLT in position-independent code. + +In position-dependant code, a few targets also convert call to functions that +are marked to not use the PLT to use the GOT instead. + +@smallexample +@@noplt int func(); +@end smallexample + +@item @@(gcc.attributes.optimize (@var{arguments})) +@cindex @code{optimize} function attribute + +The @code{@@optimize} attribute is used to specify that a function is to be +compiled with different optimization options than specified on the command +line. Valid @var{arguments} are constant non-negative integers and strings. +Multiple arguments can be provided, separated by commas to specify multiple +options. Each numeric argument specifies an optimization level. Each string +argument that begins with the letter @code{O} refers to an optimization option +such as @option{-O0} or @option{-Os}. Other options are taken as suffixes to +the @code{-f} prefix jointly forming the name of an optimization option. + +Not every optimization option that starts with the @code{-f} prefix +specified by the attribute necessarily has an effect on the function. +The @code{@@optimize} attribute should be used for debugging purposes only. +It is not suitable in production code. + +@smallexample +@@optimize(2) double fn0(double x); +@@optimize("2") double fn1(double x); +@@optimize("s") double fn2(double x); +@@optimize("Ofast") double fn3(double x); +@@optimize("-O2") double fn4(double x); +@@optimize("tree-vectorize") double fn5(double x); +@@optimize("-ftree-vectorize") double fn6(double x); +@@optimize("no-finite-math-only", 3) double fn7(double x); +@end smallexample + +@item @@(gcc.attributes.register ("@var{registerName}")) +@cindex @code{register} variable attribute + +The @code{@@register} attribute specifies that a local or @code{__gshared} +variable is to be given a register storage-class in the C99 sense of the term, +and will be placed into a register named @var{registerName}. + +The variable needs to boiled down to a data type that fits the target register. +It also cannot have either thread-local or @code{extern} storage. It is an +error to take the address of a register variable. + +@smallexample +@@register("ebx") __gshared int ebx = void; +void func() @{ @@register("r10") long r10 = 0x2a; @} +@end smallexample + +@item @@(gcc.attributes.restrict) +@cindex @code{restrict} parameter attribute + +The @code{@@restrict} attribute specifies that a function parameter is to be +restrict-qualified in the C99 sense of the term. The parameter needs to boil +down to either a pointer or reference type, such as a D pointer, class +reference, or a @code{ref} parameter. + +@smallexample +void func(@@restrict ref const float[16] array); +@end smallexample + +@item @@(gcc.attributes.section ("@var{sectionName}")) +@cindex @code{section} function attribute +@cindex @code{section} variable attribute + +The @code{@@section} attribute specifies that a function or variable lives in a +particular section. For when you need certain particular functions to appear +in special sections. + +Some file formats do not support arbitrary sections so the section attribute is +not available on all platforms. If you need to map the entire contents of a +module to a particular section, consider using the facilities of the linker +instead. + +@smallexample +@@section("bar") extern void func(); +@@section("stack") ubyte[10000] stack; +@end smallexample + +@item @@(gcc.attributes.simd) +@cindex @code{simd} function attribute + +The @code{@@simd} attribute enables creation of one or more function versions +that can process multiple arguments using SIMD instructions from a single +invocation. Specifying this attribute allows compiler to assume that such +versions are available at link time (provided in the same or another module). +Generated versions are target-dependent and described in the corresponding +Vector ABI document. + +@smallexample +@@simd double sqrt(double x); +@end smallexample + +@item @@(gcc.attributes.simd_clones ("@var{mask}")) +@cindex @code{simd_clones} function attribute + +The @code{@@simd_clones} attribute is the same as @code{@@simd}, but also +includes a @var{mask} argument. Valid masks values are @code{notinbranch} or +@code{inbranch}, and instructs the compiler to generate non-masked or masked +clones correspondingly. + +@smallexample +@@simd_clones("notinbranch") double atan2(double y, double x); +@end smallexample + +@item @@(gcc.attributes.symver ("@var{arguments}")) +@cindex @code{symver} function attribute + +The @code{@@symver} attribute creates a symbol version on ELF targets. +The syntax of the string parameter is @code{"@var{name}@@@var{nodename}"}. +The @var{name} part of the parameter is the actual name of the symbol by which +it will be externally referenced. The @var{nodename} portion should be the +name of a node specified in the version script supplied to the linker when +building a shared library. Versioned symbol must be defined and must be +exported with default visibility. + +Finally if the parameter is @code{"@var{name}@@@@@var{nodename}"} then in +addition to creating a symbol version (as if +@code{"@var{name}@@@var{nodename}"} was used) the version will be also used to +resolve @var{name} by the linker. + +@smallexample +@@symver("foo@@VERS_1") int foo_v1(); +@end smallexample + +@item @@(gcc.attributes.target ("@var{options}")) +@cindex @code{target} function attribute + +The @code{@@target} attribute is used to specify that a function is to be +compiled with different target options than specified on the command line. One +or more strings can be provided as arguments, separated by commas to specify +multiple options. Each string consists of one or more comma-separated suffixes +to the @option{-m} prefix jointly forming the name of a machine-dependent +option. + +The target attribute can be used for instance to have a function compiled with +a different ISA (instruction set architecture) than the default. + +The options supported are specific to each target. + +@smallexample +@@target("arch=core2") void core2_func(); +@@target("sse3") void sse3_func(); +@end smallexample + +@item @@(gcc.attributes.target_clones ("@var{options}")) +@cindex @code{target_clones} function attribute + +The @code{@@target_clones} attribute is used to specify that a function be +cloned into multiple versions compiled with different target @var{options} than +specified on the command line. The supported options and restrictions are the +same as for @code{@@target} attribute. + +It also creates a resolver function that dynamically selects a clone suitable +for current architecture. The resolver is created only if there is a usage of +a function with @code{@@target_clones} attribute. + +@smallexample +@@target_clones("sse4.1,avx,default") double func(double x); +@end smallexample + +@item @@(gcc.attributes.used) +@cindex @code{used} function attribute +@cindex @code{used} variable attribute + +The @code{@@used} attribute, annotated to a function or variable, means that +code must be emitted for the function even if it appears that the function is +not referenced. This is useful, for example, when the function is referenced +only in inline assembly. + +@smallexample +@@used __gshared int var = 0x1000; +@end smallexample + +@item @@(gcc.attributes.visibility ("@var{visibilityName}")) +@cindex @code{visibility} function attribute +@cindex @code{visibility} variable attribute + +The @code{@@visibility} attribute affects the linkage of the declaration to +which it is attached. It can be applied to variables, types, and functions. + +There are four supported visibility_type values: @code{default}, @code{hidden}, +@code{protected}, or @code{internal} visibility. + +@smallexample +@@visibility("protected") void func() @{ @} +@end smallexample + +@item @@(gcc.attributes.weak) +@cindex @code{weak} function attribute +@cindex @code{weak} variable attribute + +The @code{@@weak} attribute causes a declaration of an external symbol to be +emitted as a weak symbol rather than a global. This is primarily useful in +defining library functions that can be overridden in user code, though it can +also be used with non-function declarations. The overriding symbol must have +the same type as the weak symbol. In addition, if it designates a variable it +must also have the same size and alignment as the weak symbol. + +Weak symbols are supported for ELF targets, and also for a.out targets when +using the GNU assembler and linker. + +@smallexample +@@weak int func() @{ return 1; @} +@end smallexample + +@end table + +@c -------------------------------------------------------- + +@node Other Attributes +@subsection Other Attributes + +The following attributes are defined for compatibility with other compilers. + +@table @code + +@item @@(gcc.attributes.allocSize (@var{sizeArgIdx})) +@itemx @@(gcc.attributes.allocSize (@var{sizeArgIdx}, @var{numArgIdx})) +@item @@(gcc.attributes.allocSize (@var{sizeArgIdx})) +@cindex @code{allocSize} function attribute + +These attributes are a synonym for +@code{@@alloc_size(@var{sizeArgIdx}, @var{numArgIdx}, true)}. +Unlike @code{@@alloc_size}, it uses 0-based index of the function arguments. + +@item @@(gcc.attributes.assumeUsed) +@cindex @code{assumeUsed} function attribute +@cindex @code{assumeUsed} variable attribute + +This attribute is a synonym for @code{@@used}. + +@item @@(gcc.attributes.dynamicCompile) +@itemx @@(gcc.attributes.dynamicCompileConst) +@itemx @@(gcc.attributes.dynamicCompileEmit) +@cindex @code{dynamicCompile} function attribute + +These attributes are accepted, but have no effect. + +@item @@(gcc.attributes.fastmath) +@cindex @code{fastmath} function attribute + +This attribute is a synonym for @code{@@optimize("Ofast")}. Explicitly sets +"fast-math" for a function, enabling aggressive math optimizations. + +@item @@(gcc.attributes.hidden) +@cindex @code{hidden} function attribute +@cindex @code{hidden} variable attribute + +This attribute is a synonym for @code{@@visibility("hidden")}. Sets the +visibility of a function or global variable to "hidden". + +@item @@(gcc.attributes.naked) +@cindex @code{naked} function attribute + +This attribute is a synonym for @code{@@attribute("naked")}. Adds GCC's +"naked" attribute to a function, disabling function prologue / epilogue +emission. Intended to be used in combination with basic @code{asm} statements. +While using extended @code{asm} or a mixture of basic @code{asm} and D code may +appear to work, they cannot be depended upon to work reliably and are not +supported. + +@item @@(gcc.attributes.noSanitize ("@var{sanitize_option}")) +@cindex @code{noSanitize} function attribute + +This attribute is a synonym for @code{@@no_sanitize("sanitize_option")}. + + +@item @@(gcc.attributes.optStrategy ("@var{strategy}")) +@cindex @code{optStrategy} function attribute + +This attribute is a synonym for @code{@@optimize("O0")} and +@code{@@optimize("Os")}. Sets the optimization strategy for a function. Valid +strategies are "none", "optsize", "minsize". The strategies are mutually +exclusive. + +@item @@(gcc.attributes.polly) + +This attribute is a synonym for +@code{@@optimize("loop-parallelize-all", "loop-nest-optimize")}. +Only effective when GDC was built with ISL included. + +@end table + +@c -------------------------------------------------------- + +@node Target Attributes +@subsection Target-specific Attributes + +Many targets have their own target-specific attributes. These are also exposed +via the @code{gcc.attributes} module with use of the generic +@code{@@(gcc.attributes.attribute)} UDA function. + +@xref{Attribute Syntax}, for details of the exact syntax for using attributes. + +See the function and variable attribute documentation in the GCC manual for +more information about what attributes are available on each target. + +Examples of using x86-specific target attributes are shown as follows: + +@smallexample +import gcc.attributes; + +@@attribute("cdecl") +@@attribute("fastcall") +@@attribute("ms_abi") +@@attribute("sysv_abi") +@@attribute("callee_pop_aggregate_return", 1) +@@attribute("ms_hook_prologue") +@@attribute("naked") +@@attribute("regparm", 2) +@@attribute("sseregparm") +@@attribute("force_align_arg_pointer") +@@attribute("stdcall") +@@attribute("no_caller_saved_registers") +@@attribute("interrupt") +@@attribute("indirect_branch", "thunk") +@@attribute("function_return", "keep")) +@@attribute("nocf_check") +@@attribute("cf_check") +@@attribute("indirect_return") +@@attribute("fentry_name", "nop") +@@attribute("fentry_section", "__entry_loc") +@@attribute("nodirect_extern_access") + +@end smallexample + + +@c -------------------------------------------------------- + +@node Builtin Functions +@section Built-in Functions +@cindex built-in functions + +GCC provides a large number of built-in functions that are made available in +GNU D by importing the @code{gcc.builtins} module. Declarations in this module +are automatically created by the compiler. All declarations start with +@code{__builtin_}. Refer to the built-in function documentation in the GCC +manual for a full list of functions that are available. + +@menu +* Builtin Types:: +* Query Builtins:: +* Other Builtins:: +@end menu + +@c -------------------------------------------------------- + +@node Builtin Types +@subsection Built-in Types +@cindex built-in types + +In addition to built-in functions, the following types are defined in the +@code{gcc.builtins} module. + +@table @code +@item ___builtin_clong +The D equivalent of the target's C @code{long} type. + +@item ___builtin_clonglong +The D equivalent of the target's C @code{long long} type. + +@item ___builtin_culong +The D equivalent of the target's C @code{unsigned long} type. + +@item ___builtin_culonglong +The D equivalent of the target's C @code{unsigned long long} type. + +@item ___builtin_machine_byte +Signed unit-sized integer type. + +@item ___builtin_machine_int +Signed word-sized integer type. + +@item ___builtin_machine_ubyte +Unsigned unit-sized integer type. + +@item ___builtin_machine_uint +Unsigned word-sized integer type. + +@item ___builtin_pointer_int +Signed pointer-sized integer type. + +@item ___builtin_pointer_uint +Unsigned pointer-sized integer type. + +@item ___builtin_unwind_int +The D equivalent of the target's C @code{_Unwind_Sword} type. + +@item ___builtin_unwind_uint +The D equivalent of the target's C @code{_Unwind_Word} type. + +@item ___builtin_va_list +The target's @code{va_list} type. +@end table + +@c -------------------------------------------------------- + +@node Query Builtins +@subsection Querying Available Built-ins +@cindex built-in functions + +Not all of the functions are supported, and some target-specific functions may +only be available when compiling for a particular ISA. One way of finding out +what is exposed by the built-ins module is by generating a D interface file. +Assuming you have no file @file{builtins.d}, the command +@smallexample + echo "module gcc.builtins;" > builtins.d; gdc -H -fsyntax-only builtins.d +@end smallexample +@noindent +will save all built-in declarations to the file @file{builtins.di}. + +Another way to determine whether a specific built-in is available is by using +compile-time reflection. +@smallexample +enum X86_HAVE_SSE3 = __traits(compiles, __builtin_ia32_haddps); +enum X86_HAVE_SSSE3 = __traits(compiles, __builtin_ia32_pmulhrsw128); +enum X86_HAVE_SSE41 = __traits(compiles, __builtin_ia32_dpps); +enum X86_HAVE_SSE42 = __traits(compiles, __builtin_ia32_pcmpgtq); +enum X86_HAVE_AVX = __traits(compiles, __builtin_ia32_vbroadcastf128_pd256); +enum X86_HAVE_AVX2 = __traits(compiles, __builtin_ia32_gathersiv2df); +enum X86_HAVE_BMI2 = __traits(compiles, __builtin_ia32_pext_si); +@end smallexample + +@c -------------------------------------------------------- + +@node Other Builtins +@subsection Other Built-in Functions +@cindex built-in functions +@opindex fno-builtin + +As well as built-ins being available from the @code{gcc.builtins} module, GNU D +will also recognize when an @code{extern(C)} library function is a GCC +built-in. Many of these functions are only optimized in certain cases; if they +are not optimized in a particular case, a call to the library function is +emitted. This optimization can be disabled with the @option{-fno-builtin} +option (@pxref{Runtime Options}). + +In the @code{core.stdc.complex} module, the functions +@code{cabs}, @code{cabsf}, @code{cabsl}, @code{cacos}, @code{cacosf}, +@code{cacosh}, @code{cacoshf}, @code{cacoshl}, @code{cacosl}, @code{carg}, +@code{cargf}, @code{cargl}, @code{casin}, @code{casinf}, @code{casinh}, +@code{casinhf}, @code{casinhl}, @code{casinl}, @code{catan}, @code{catanf}, +@code{catanh}, @code{catanhf}, @code{catanhl}, @code{catanl}, @code{ccos}, +@code{ccosf}, @code{ccosh}, @code{ccoshf}, @code{ccoshl}, @code{ccosl}, +@code{cexp}, @code{cexpf}, @code{cexpl}, @code{clog}, @code{clogf}, +@code{clogl}, @code{conj}, @code{conjf}, @code{conjl}, @code{cpow}, +@code{cpowf}, @code{cpowl}, @code{cproj}, @code{cprojf}, @code{cprojl}, +@code{csin}, @code{csinf}, @code{csinh}, @code{csinhf}, @code{csinhl}, +@code{csinl}, @code{csqrt}, @code{csqrtf}, @code{csqrtl}, @code{ctan}, +@code{ctanf}, @code{ctanh}, @code{ctanhf}, @code{ctanhl}, @code{ctanl} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.ctype} module, the functions +@code{isalnum}, @code{isalpha}, @code{isblank}, @code{iscntrl}, @code{isdigit}, +@code{isgraph}, @code{islower}, @code{isprint}, @code{ispunct}, @code{isspace}, +@code{isupper}, @code{isxdigit}, @code{tolower}, @code{toupper} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.fenv} module, the functions +@code{feclearexcept}, @code{fegetenv}, @code{fegetexceptflag}, +@code{fegetround}, @code{feholdexcept}, @code{feraiseexcept}, @code{fesetenv}, +@code{fesetexceptflag}, @code{fesetround}, @code{fetestexcept}, +@code{feupdateenv} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.inttypes} module, the function @code{imaxabs} may be +handled as a built-in function. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.math} module, the functions +@code{acos}, @code{acosf}, @code{acosh}, @code{acoshf}, @code{acoshl}, +@code{acosl}, @code{asin}, @code{asinf}, @code{asinh}, @code{asinhf}, +@code{asinhl}, @code{asinl}, @code{atan}, @code{atan2}, @code{atan2f}, +@code{atan2l}, @code{atanf}, @code{atanh}, @code{atanhf}, @code{atanhl}, +@code{atanl}, @code{cbrt}, @code{cbrtf}, @code{cbrtl}, @code{ceil}, +@code{ceilf}, @code{ceill}, @code{copysign}, @code{copysignf}, +@code{copysignl}, @code{cos}, @code{cosf}, @code{cosh}, @code{coshf}, +@code{coshl}, @code{cosl}, @code{erf}, @code{erfc}, @code{erfcf}, @code{erfcl}, +@code{erff}, @code{erfl}, @code{exp}, @code{exp2}, @code{exp2f}, @code{exp2l}, +@code{expf}, @code{expl}, @code{expm1}, @code{expm1f}, @code{expm1l}, +@code{fabs}, @code{fabsf}, @code{fabsl}, @code{fdim}, @code{fdimf}, +@code{fdiml}, @code{floor}, @code{floorf}, @code{floorl}, @code{fma}, +@code{fmaf}, @code{fmal}, @code{fmax}, @code{fmaxf}, @code{fmaxl}, @code{fmin}, +@code{fminf}, @code{fminl}, @code{fmod}, @code{fmodf}, @code{fmodl}, +@code{frexp}, @code{frexpf}, @code{frexpl}, @code{hypot}, @code{hypotf}, +@code{hypotl}, @code{ilogb}, @code{ilogbf}, @code{ilogbl}, @code{isinf}, +@code{isnan}, @code{ldexp}, @code{ldexpf}, @code{ldexpl}, @code{lgamma}, +@code{lgammaf}, @code{lgammal}, @code{llrint}, @code{llrintf}, @code{llrintl}, +@code{llround}, @code{llroundf}, @code{llroundl}, @code{log}, @code{log10}, +@code{log10f}, @code{log10l}, @code{log1p}, @code{log1pf}, @code{log1pl}, +@code{log2}, @code{log2f}, @code{log2l}, @code{logb}, @code{logbf}, +@code{logbl}, @code{logf}, @code{logl}, @code{lrint}, @code{lrintf}, +@code{lrintl}, @code{lround}, @code{lroundf}, @code{lroundl}, @code{modf}, +@code{modff}, @code{modfl}, @code{nan}, @code{nanf}, @code{nanl}, +@code{nearbyint}, @code{nearbyintf}, @code{nearbyintl}, @code{nextafter}, +@code{nextafterf}, @code{nextafterl}, @code{nexttoward}, @code{nexttowardf}, +@code{nexttowardl}, @code{pow}, @code{powf}, @code{powl}, @code{remainder}, +@code{remainderf}, @code{remainderl}, @code{remquo}, @code{remquof}, +@code{remquol}, @code{rint}, @code{rintf}, @code{rintl}, @code{round}, +@code{roundf}, @code{roundl}, @code{scalbln}, @code{scalblnf}, @code{scalblnl}, +@code{scalbn}, @code{scalbnf}, @code{scalbnl}, @code{signbit}, @code{sin}, +@code{sinf}, @code{sinh}, @code{sinhf}, @code{sinhl}, @code{sinl}, @code{sqrt}, +@code{sqrtf}, @code{sqrtl}, @code{tan}, @code{tanf}, @code{tanh}, @code{tanhf}, +@code{tanhl}, @code{tanl}, @code{tgamma}, @code{tgammaf}, @code{tgammal}, +@code{trunc}, @code{truncf}, @code{truncl} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.stdio} module, the functions +@code{fprintf}, @code{fputc}, @code{fputc_unlocked}, @code{fputs}, +@code{fwrite}, @code{printf}, @code{puts}, @code{snprintf}, @code{sprintf}, +@code{vfprintf}, @code{vprintf}, @code{vsnprintf}, @code{vsprintf} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.stdlib} module, the functions +@code{abort}, @code{abs}, @code{aligned_alloc}, @code{alloca}, @code{calloc}, +@code{exit}, @code{_Exit}, @code{free}, @code{labs}, @code{llabs}, +@code{malloc}, @code{realloc} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.string} module, the functions +@code{memchr}, @code{memcmp}, @code{memcpy}, @code{memmove}, @code{memset}, +@code{strcat}, @code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn}, +@code{strdup}, @code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy}, +@code{strpbrk}, @code{strrchr}, @code{strspn}, @code{strstr} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.time} module, the function @code{strftime} may be +handled as a built-in function. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +In the @code{core.stdc.wctype} module, the functions +@code{iswalnum}, @code{iswalpha}, @code{iswblank}, @code{iswcntrl}, +@code{iswdigit}, @code{iswgraph}, @code{iswlower}, @code{iswprint}, +@code{iswpunct}, @code{iswspace}, @code{iswupper}, @code{iswxdigit}, +@code{towlower}, @code{towupper} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + +Within the @code{core.sys} package for POSIX and platform definitions, the +functions +@code{putchar_unlocked}, @code{putc_unlocked}, @code{posix_memalign}, +@code{ffs}, @code{strcasecmp}, @code{strncasecmp}, @code{stpcpy}, +@code{stpncpy}, @code{strndup}, @code{strnlen}, @code{execl}, @code{execle}, +@code{execlp}, @code{execv}, @code{execve}, @code{execvp}, @code{_exit}, +@code{fork} +may be handled as built-in functions. All these functions have corresponding +versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module. + + +@c -------------------------------------------------------- + +@node ImportC +@section Importing C Sources into D +@cindex importC + +ImportC is a C preprocessor and parser embedded into the GNU D implementation. +It enables direct importation of C files, without needing to manually prepare a +D file corresponding to the declarations in the C file. + +ImportC is an implementation of ISO/IEC 9899:2011, which will be referred to as +C11. Prior versions, such as C99, C89, and K+R C, are not supported. + +Assuming you have no file @file{cstdio.c} or @file{main.d}, the commands +@smallexample + cat > cstdio.c << @@EOC + int printf(const char*, ...); + @@EOC + cat > main.d << @@EOD + import cstdio; + void main() @{ printf("Hello ImportC\n"); @} + @@EOD + gdc main.d -o main; ./main +@end smallexample +will generate a program which will print @samp{Hello ImportC}. + +ImportC does not have a preprocessor. It is designed to compile C files after +they have been first run through the C preprocessor. If the C file has a +@samp{.i} extension, the file is presumed to be already preprocessed. +Preprocessing can be run manually: +@smallexample + gcc -E file.c > file.i +@end smallexample + +@noindent +ImportC collects all the @code{#define} macros from the preprocessor run when +it is run automatically. The macros that look like manifest constants, such as: +@smallexample +#define COLOR 0x123456 +@end smallexample +are interpreted as D manifest constant declarations of the form: +@smallexample +enum COLOR = 0x123456; +@end smallexample + +@noindent +The variety of macros that can be interpreted as D declarations may be +expanded, but will never encompass all the metaprogramming uses of C macros. + +GNU D does not directly compile C files into modules that can be linked in with +D code to form an executable. When given a source file with the suffix +@samp{.c}, the compiler driver program @command{gdc} instead runs the +subprogram @command{cc1}. + +@smallexample +gdc file1.d file2.c // d21 file1.d -o file1.s + // cc1 file2.c -o file2.s + // as file1.s -o file1.o + // as file2.s -o file2.o + // ld file1.o file2.o +@end smallexample + + +@c -------------------------------------------------------- + +@node Inline Assembly +@section Inline Assembly +@cindex assembly language in D + +The @code{asm} keyword allows you to embed assembler instructions within D +code. GNU D provides two forms of inline @code{asm} statements. A @dfn{basic +@code{asm}} statement is one with no operands, while an @dfn{extended +@code{asm}} statement includes one or more operands. + +@example +asm @var{FunctionAttributes} @{ + @var{AssemblerInstruction} ; +@} + +asm @var{FunctionAttributes} @{ + @var{AssemblerTemplate} + : @var{OutputOperands} + @r{[} : @var{InputOperands} + @r{[} : @var{Clobbers} + @r{[} : @var{GotoLabels} @r{]} @r{]} @r{]} ; +@} +@end example + +@noindent +The extended form is preferred for mixing D and assembly language within a +function, but to include assembly language in a function declared with the +@code{naked} attribute you must use basic @code{asm}. + +@smallexample +uint incr (uint value) +@{ + uint result; + asm @{ "incl %0" + : "=a" (result) + : "a" (value); + @} + return result; +@} +@end smallexample + +@noindent +Multiple assembler instructions can appear within an @code{asm} block, or the +instruction template can be a multi-line or concatenated string. In both +cases, GCC's optimizers won't discard or move any instruction within the +statement block. +@smallexample +bool hasCPUID() +@{ + uint flags = void; + asm nothrow @@nogc @{ + "pushfl"; + "pushfl"; + "xorl %0, (%%esp)" :: "i" (0x00200000); + "popfl"; + "pushfl"; + "popl %0" : "=a" (flags); + "xorl (%%esp), %0" : "=a" (flags); + "popfl"; + @} + return (flags & 0x0020_0000) != 0; +@} +@end smallexample + +@noindent +The instruction templates for both basic and extended @code{asm} can be any +expression that can be evaluated at compile-time to a string, not just string +literals. + +@smallexample +uint invert(uint v) +@{ + uint result; + asm @@safe @@nogc nothrow pure @{ + genAsmInsn(`invert`) + : [res] `=r` (result) + : [arg1] `r` (v); + @} + return result; + +@} +@end smallexample + +@noindent +The total number of input + output + goto operands is limited to 30. + + +@c -------------------------------------------------------- + +@node Intrinsics +@section Intrinsics +@cindex intrinsics + +The D language specification itself does not define any intrinsics that a +compatible compiler must implement. Rather, within the D core library there +are a number of modules that define primitives with generic implementations. +While the generic versions of these functions are computationally expensive +relative to the cost of the operation itself, compiler implementations are free +to recognize them and generate equivalent and faster code. + +The following are the kinds of intrinsics recognized by GNU D. + +@menu +* Bit Operation Intrinsics:: +* Integer Overflow Intrinsics:: +* Math Intrinsics:: +* Variadic Intrinsics:: +* Volatile Intrinsics:: +* CTFE Intrinsics:: +@end menu + +@c -------------------------------------------------------- + +@node Bit Operation Intrinsics +@subsection Bit Operation Intrinsics +@cindex intrinsics, bitop + +The following functions are a collection of intrinsics that do bit-level +operations, available by importing the @code{core.bitop} module. + +Although most are named after x86 hardware instructions, it is not guaranteed +that they will result in generating equivalent assembly on x86. If the +compiler determines there is a better way to get the same result in hardware, +then that will be used instead. + +@deftypefn {Function} {int} core.bitop.bsf (uint @var{v}) +@deftypefnx {Function} {int} core.bitop.bsf (ulong @var{v}) + +Scans the bits in @var{v} starting with bit @code{0}, looking for the first set +bit. Returns the bit number of the first bit set. The return value is +undefined if @var{v} is zero. + +This intrinsic is the same as the GCC built-in function @code{__builtin_ctz}. +@end deftypefn + +@deftypefn {Function} {int} core.bitop.bsr (uint @var{v}) +@deftypefnx {Function} {int} core.bitop.bsr (ulong @var{v}) + +Scans the bits in @var{v} from the most significant bit to the least +significant bit, looking for the first set bit. Returns the bit number of the +first bit set. The return value is undefined if @var{v} is zero. + +This intrinsic is equivalent to writing the following: +@smallexample +result = __builtin_clz(v) ^ (v.sizeof * 8 - 1) +@end smallexample +@end deftypefn + +@deftypefn {Function} {int} core.bitop.bt (scope const(uint*) @var{p}, uint @var{bitnum}) +@deftypefnx {Function} {int} core.bitop.bt (scope const(uint*) @var{p}, uint @var{bitnum}) + +Tests the bit @var{bitnum} in the input parameter @var{p}. Returns a non-zero +value if the bit was set, and a zero if it was clear. + +This intrinsic is equivalent to writing the following: +@smallexample +immutable bits_per_unit = (*p).sizeof * 8; +immutable bit_mask = size_t(1) << (bitnum % bits_per_unit); + +result = (p[bitnum / bits_per_unit] & bit_mask) != 0; +@end smallexample +@end deftypefn + +@deftypefn {Function} {int} core.bitop.btc (uint* @var{p}, uint @var{bitnum}) +@deftypefnx {Function} {int} core.bitop.btc (ulong* @var{p}, ulong @var{bitnum}) + +Tests and complements the bit @var{bitnum} in the input parameter @var{p}. +Returns a non-zero value if the bit was set, and a zero if it was clear. + +This intrinsic is equivalent to writing the following: +@smallexample +immutable bits_per_unit = (*p).sizeof * 8; +immutable bit_mask = size_t(1) << (bitnum % bits_per_unit); + +result = (p[bitnum / bits_per_unit] & bit_mask) != 0; + +p[bitnum / bits_per_unit] ^= bit_mask; +@end smallexample +@end deftypefn + +@deftypefn {Function} {int} core.bitop.btr (uint* @var{p}, uint @var{bitnum}) +@deftypefnx {Function} {int} core.bitop.btr (ulong* @var{p}, ulong @var{bitnum}) + +Tests and resets (sets to 0) the bit @var{bitnum} in the input parameter +@var{p}. Returns a non-zero value if the bit was set, and a zero if it was +clear. + +This intrinsic is equivalent to writing the following: +@smallexample +immutable bits_per_unit = (*p).sizeof * 8; +immutable bit_mask = size_t(1) << (bitnum % bits_per_unit); + +result = (p[bitnum / bits_per_unit] & bit_mask) != 0; + +p[bitnum / bits_per_unit] &= ~bit_mask; +@end smallexample +@end deftypefn + +@deftypefn {Function} {int} core.bitop.bts (uint* @var{p}, uint @var{bitnum}) +@deftypefnx {Function} {int} core.bitop.bts (ulong* @var{p}, ulong @var{bitnum}) + +Tests and sets the bit @var{bitnum} in the input parameter @var{p}. Returns a +non-zero value if the bit was set, and a zero if it was clear. + +This intrinsic is equivalent to writing the following: +@smallexample +immutable bits_per_unit = (*p).sizeof * 8; +immutable bit_mask = size_t(1) << (bitnum % bits_per_unit); + +result = (p[bitnum / bits_per_unit] & bit_mask) != 0; + +p[bitnum / bits_per_unit] |= bit_mask; +@end smallexample +@end deftypefn + + +@deftypefn {Function} {ushort} core.bitop.byteswap (ushort @var{x}) +@deftypefnx {Function} {uint} core.bitop.bswap (uint @var{x}) +@deftypefnx {Function} {ulong} core.bitop.bswap (ulong @var{x}) + +Swaps the bytes in @var{x} end-to-end; for example, in a 4-byte @code{uint}, +byte @code{0} becomes byte @code{3}, byte @code{1} becomes byte @code{2}, etc. + +This intrinsic is the same as the GCC built-in function @code{__builtin_bswap}. +@end deftypefn + +@deftypefn {Function} {int} core.bitop.popcnt (uint @var{x}) +@deftypefnx {Function} {int} core.bitop.popcnt (ulong @var{x}) + +Calculates the number of set bits in @var{x}. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_popcount}. +@end deftypefn + +@deftypefn {Template} {T} core.bitop.rol (T)(const T @var{value}, const uint @var{count}) +@deftypefnx {Template} {T} core.bitop.rol (uint @var{count}, T)(const T @var{value}) + +Bitwise rotate @var{value} left by @var{count} bit positions. + +This intrinsic is equivalent to writing the following: +@smallexample +result = cast(T) ((value << count) | (value >> (T.sizeof * 8 - count))); +@end smallexample +@end deftypefn + +@deftypefn {Template} {T} core.bitop.ror (T)(const T @var{value}, const uint @var{count}) +@deftypefnx {Template} {T} core.bitop.ror (uint @var{count}, T)(const T @var{value}) + +Bitwise rotate @var{value} right by @var{count} bit positions. + +This intrinsic is equivalent to writing the following: +@smallexample +result = cast(T) ((value >> count) | (value << (T.sizeof * 8 - count))); +@end smallexample +@end deftypefn + +@c -------------------------------------------------------- + +@node Integer Overflow Intrinsics +@subsection Integer Overflow Intrinsics +@cindex intrinsics, checkedint + +The following functions are a collection of intrinsics that implement integral +arithmetic primitives that check for out-of-range results, available by +importing the @code{core.checkedint} module. + +In all intrinsics, the overflow is sticky, meaning a sequence of operations can +be done and overflow need only be checked at the end. + +@deftypefn {Function} {int} core.checkedint.adds (int @var{x}, int @var{y}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.adds (long @var{x}, long @var{y}, @ + ref bool @var{overflow}) + +Add two signed integers, checking for overflow. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_sadd_overflow}. +@end deftypefn + +@deftypefn {Function} {int} core.checkedint.addu (int @var{x}, int @var{y}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.addu (long @var{x}, long @var{y}, @ + ref bool @var{overflow}) + +Add two unsigned integers, checking for overflow. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_uadd_overflow}. +@end deftypefn + +@deftypefn {Function} {int} core.checkedint.muls (int @var{x}, int @var{y}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.muls (long @var{x}, long @var{y}, @ + ref bool @var{overflow}) + +Multiply two signed integers, checking for overflow. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_smul_overflow}. +@end deftypefn + +@deftypefn {Function} {int} core.checkedint.mulu (int @var{x}, int @var{y}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.mulu (long @var{x}, long @var{y}, @ + ref bool @var{overflow}) + +Multiply two unsigned integers, checking for overflow. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_umul_overflow}. +@end deftypefn + +@deftypefn {Function} {int} core.checkedint.negs (int @var{x}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.negs (long @var{x}, @ + ref bool @var{overflow}) + +Negates an integer. + +This intrinsic is equivalent to writing the following: +@smallexample +result = __builtin_ssub (0, x, overflow); +@end smallexample +@end deftypefn + +@deftypefn {Function} {int} core.checkedint.subs (int @var{x}, int @var{y}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.subs (long @var{x}, long @var{y}, @ + ref bool @var{overflow}) + +Substract two signed integers, checking for overflow. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_ssub_overflow}. +@end deftypefn + +@deftypefn {Function} {int} core.checkedint.subu (int @var{x}, int @var{y}, @ + ref bool @var{overflow}) +@deftypefnx {Function} {long} core.checkedint.subu (long @var{x}, long @var{y}, @ + ref bool @var{overflow}) + +Substract two unsigned integers, checking for overflow. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_usub_overflow}. +@end deftypefn + +@c -------------------------------------------------------- + +@node Math Intrinsics +@subsection Math Intrinsics +@cindex intrinsics, math + +The following functions are a collection of mathematical intrinsics, available +by importing the @code{core.math} module. + +@deftypefn {Function} {float} core.math.cos (float x) +@deftypefnx {Function} {double} core.math.cos (double x) +@deftypefnx {Function} {real} core.math.cos (real x) + +Returns cosine of @var{x}, where @var{x} is in radians. The return value is +undefined if @var{x} is greater than @math{2^{64}}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_cos}. +@end deftypefn + +@deftypefn {Function} {float} core.math.fabs (float x) +@deftypefnx {Function} {double} core.math.fabs (double x) +@deftypefnx {Function} {real} core.math.fabs (real x) + +Compute the absolute value of @var{x}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_fabs}. +@end deftypefn + +@deftypefn {Function} {float} core.math.ldexp (float n, int exp) +@deftypefnx {Function} {double} core.math.ldexp (double n, int exp) +@deftypefnx {Function} {real} core.math.ldexp (real n, int exp) + +Compute @math{n * 2^{exp}}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_ldexp}. +@end deftypefn + +@deftypefn {Function} {float} core.math.rint (float x) +@deftypefnx {Function} {double} core.math.rint (double x) +@deftypefnx {Function} {real} core.math.rint (real x) + +Rounds @var{x} to the nearest integer value, using the current rounding mode. +If the return value is not equal to @var{x}, the @code{FE_INEXACT} exception is +raised. @code{nearbyint} performs the same operation, but does not set the +@code{FE_INEXACT} exception. + +This intrinsic is the same as the GCC built-in function @code{__builtin_rint}. +@end deftypefn + +@deftypefn {Function} {float} core.math.rndtol (float x) +@deftypefnx {Function} {double} core.math.rndtol (double x) +@deftypefnx {Function} {real} core.math.rndtol (real x) + +Returns @var{x} rounded to a long value using the current rounding mode. +If the integer value of @var{x} is greater than @code{long.max}, the result +is indeterminate. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_llround}. +@end deftypefn + +@deftypefn {Function} {float} core.math.sin (float x) +@deftypefnx {Function} {double} core.math.sin (double x) +@deftypefnx {Function} {real} core.math.sin (real x) + +Returns sine of @var{x}, where @var{x} is in radians. The return value is +undefined if @var{x} is greater than @math{2^{64}}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_sin}. +@end deftypefn + +@deftypefn {Function} {float} core.math.sqrt (float x) +@deftypefnx {Function} {double} core.math.sqrt (double x) +@deftypefnx {Function} {real} core.math.sqrt (real x) + +Compute the sqrt of @var{x}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_sqrt}. +@end deftypefn + +@deftypefn {Template} {T} core.math.toPrec (T)(float f) +@deftypefnx {Template} {T} core.math.toPrec (T)(double f) +@deftypefnx {Template} {T} core.math.toPrec (T)(real f) + +Round @var{f} to a specific precision. + +In floating-point operations, D language types specify only a minimum +precision, not a maximum. The @code{toPrec} function forces rounding of the +argument @var{f} to the precision of the specified floating point type +@code{T}. The rounding mode used is inevitably target-dependent, but will be +done in a way to maximize accuracy. In most cases, the default is +round-to-nearest. +@end deftypefn + +@c -------------------------------------------------------- + +@node Variadic Intrinsics +@subsection Variadic Intrinsics +@cindex intrinsics, stdarg + +The following functions are a collection of variadic intrinsics, available by +importing the @code{core.stdc.stdarg} module. + +@deftypefn {Template} {void} core.stdc.stdarg.va_arg (T)(ref va_list ap, ref T parmn) + +Retrieve and store in @var{parmn} the next value from the @code{va_list} +@var{ap} that is of type @code{T}. + +This intrinsic is equivalent to writing the following: +@smallexample +parmn = __builtin_va_arg (ap, T); +@end smallexample +@end deftypefn + +@deftypefn {Template} {T} core.stdc.stdarg.va_arg (T)(ref va_list ap) + +Retrieve and return the next value from the @code{va_list} @var{ap} that is of +type @code{T}. + +This intrinsic is equivalent to writing the following: +@smallexample +result = __builtin_va_arg (ap, T); +@end smallexample +@end deftypefn + +@deftypefn {Function} {void} core.stdc.stdarg.va_copy (out va_list dest, va_list src) + +Make a copy of @var{src} in its current state and store to @var{dest}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_va_copy}. +@end deftypefn + +@deftypefn {Function} {void} core.stdc.stdarg.va_end (va_list ap) + +Destroy @var{ap} so that it is no longer useable. + +This intrinsic is the same as the GCC built-in function @code{__builtin_va_end}. +@end deftypefn + +@deftypefn {Template} {void} core.stdc.stdarg.va_start (T)(out va_list ap, ref T parmn) + +Initialize @var{ap} so that it can be used to access the variable arguments +that follow the named argument @var{parmn}. + +This intrinsic is the same as the GCC built-in function @code{__builtin_va_start}. +@end deftypefn + +@c -------------------------------------------------------- + +@node Volatile Intrinsics +@subsection Volatile Intrinsics +@cindex intrinsics, volatile + +The following functions are a collection of intrinsics for volatile operations, +available by importing the @code{core.volatile} module. + +Calls to them are guaranteed to not be removed (as dead assignment elimination +or presumed to have no effect) or reordered in the same thread. + +These reordering guarantees are only made with regards to other operations done +through these functions; the compiler is free to reorder regular loads/stores +with regards to loads/stores done through these functions. + +This is useful when dealing with memory-mapped I/O (MMIO) where a store can +have an effect other than just writing a value, or where sequential loads with +no intervening stores can retrieve different values from the same location due +to external stores to the location. + +These functions will, when possible, do the load/store as a single operation. +In general, this is possible when the size of the operation is less than or +equal to @code{(void*).sizeof}, although some targets may support larger +operations. If the load/store cannot be done as a single operation, multiple +smaller operations will be used. + +These are not to be conflated with atomic operations. They do not guarantee +any atomicity. This may be provided by coincidence as a result of the +instructions used on the target, but this should not be relied on for portable +programs. Further, no memory fences are implied by these functions. They +should not be used for communication between threads. They may be used to +guarantee a write or read cycle occurs at a specified address. + +@deftypefn {Function} {ubyte} core.volatile.volatileLoad (ubyte* ptr) +@deftypefnx {Function} {ushort} core.volatile.volatileLoad (ushort* ptr) +@deftypefnx {Function} {uint} core.volatile.volatileLoad (uint* ptr) +@deftypefnx {Function} {ulong} core.volatile.volatileLoad (ulong* ptr) + +Read value from the memory location indicated by @var{ptr}. +@end deftypefn + +@deftypefn {Function} {ubyte} core.volatile.volatileStore (ubyte* ptr, ubyte value) +@deftypefnx {Function} {ushort} core.volatile.volatileStore (ushort* ptr, ushort value) +@deftypefnx {Function} {uint} core.volatile.volatileStore (uint* ptr, uint value) +@deftypefnx {Function} {ulong} core.volatile.volatileStore (ulong* ptr, ulong value) + +Write @var{value} to the memory location indicated by @var{ptr}. +@end deftypefn + +@c -------------------------------------------------------- + +@node CTFE Intrinsics +@subsection CTFE Intrinsics +@cindex intrinsics, ctfe + +The following functions are only treated as intrinsics during compile-time +function execution (CTFE) phase of compilation to allow more functions to be +computable at compile-time, either because their generic implementations are +too complex, or do some low-level bit manipulation of floating point types. + +Calls to these functions that exist after CTFE has finished will get standard +code-generation without any special compiler intrinsic suppport. + +@deftypefn {Function} {float} std.math.exponential.exp (float x) +@deftypefnx {Function} {double} std.math.exponential.exp (double x) +@deftypefnx {Function} {real} std.math.exponential.exp (real x) + +Calculates @math{e^x}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_exp}. +@end deftypefn + +@deftypefn {Function} {float} std.math.exponential.expm1 (float x) +@deftypefnx {Function} {double} std.math.exponential.expm1 (double x) +@deftypefnx {Function} {real} std.math.exponential.expm1 (real x) + +Calculates @math{e^x-1.0}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_expm1}. +@end deftypefn + +@deftypefn {Function} {float} std.math.exponential.exp2 (float x) +@deftypefnx {Function} {double} std.math.exponential.exp2 (double x) +@deftypefnx {Function} {real} std.math.exponential.exp2 (real x) + +Calculates @math{2^x}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_exp2}. +@end deftypefn + +@deftypefn {Function} {float} std.math.exponential.log (float x) +@deftypefnx {Function} {double} std.math.exponential.log (double x) +@deftypefnx {Function} {real} std.math.exponential.log (real x) + +Calculate the natural logarithm of @var{x}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_log}. +@end deftypefn + +@deftypefn {Function} {float} std.math.exponential.log10 (float x) +@deftypefnx {Function} {double} std.math.exponential.log10 (double x) +@deftypefnx {Function} {real} std.math.exponential.log10 (real x) + +Calculates the base-10 logarithm of @var{x}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_log10}. +@end deftypefn + +@deftypefn {Function} {float} std.math.exponential.log2 (float x) +@deftypefnx {Function} {double} std.math.exponential.log2 (double x) +@deftypefnx {Function} {real} std.math.exponential.log2 (real x) + +Calculates the base-2 logarithm of @var{x}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_log2}. +@end deftypefn + +@deftypefn {Template} {Largest!(F, G)} std.math.exponential.pow (F, G) (F x, G y) +@deftypefnx {Template} {real} std.math.exponential.pow (I, F)(I x, F y) + +Calculates @math{x^y}, where @var{y} is a float. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_pow}. +@end deftypefn + +@deftypefn {Template} {F} std.math.exponential.pow (F, G) (F x, G n) + +Calculates @math{x^n}, where @var{n} is an integer. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_powi}. +@end deftypefn + +@deftypefn {Function} {real} std.math.operations.fma (real x, real y, real z) + +Returns @code{(x * y) + z}, rounding only once according to the current +rounding mode. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_fma}. +@end deftypefn + +@deftypefn {Template} {F} std.math.operations.fmax (F)(const F x, const F y) + +Returns the larger of @var{x} and @var{y}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_fmax}. +@end deftypefn + +@deftypefn {Template} {F} std.math.operations.fmin (F)(const F x, const F y) + +Returns the smaller of @var{x} and @var{y}. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_fmin}. +@end deftypefn + +@deftypefn {Function} {float} std.math.rounding.ceil (float x) +@deftypefnx {Function} {double} std.math.rounding.ceil (double x) +@deftypefnx {Function} {real} std.math.rounding.ceil (real x) + +Returns the value of @var{x} rounded upward to the next integer (toward +positive infinity). + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_ceil}. +@end deftypefn + +@deftypefn {Function} {float} std.math.rounding.floor (float x) +@deftypefnx {Function} {double} std.math.rounding.floor (double x) +@deftypefnx {Function} {real} std.math.rounding.floor (real x) + +Returns the value of @var{x} rounded downward to the next integer (toward +negative infinity). + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_floor}. +@end deftypefn + +@deftypefn {Function} {real} std.math.rounding.round (real x) + +Return the value of @var{x} rounded to the nearest integer. If the fractional +part of @var{x} is exactly 0.5, the return value is rounded away from zero. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_round}. +@end deftypefn + +@deftypefn {Function} {real} std.math.rounding.trunc (real x) + +Returns the integer portion of @var{x}, dropping the fractional portion. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_trunc}. +@end deftypefn + +@deftypefn {Template} {R} std.math.traits.copysign (R, X)(R to, X from) + +Returns a value composed of @var{to} with @var{from}'s sign bit. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_copysign}. +@end deftypefn + +@deftypefn {Template} {bool} std.math.traits.isFinite (X)(X x) + +Returns true if @var{x} is finite. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_isfinite}. +@end deftypefn + +@deftypefn {Template} {bool} std.math.traits.isInfinity (X)(X x) + +Returns true if @var{x} is infinite. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_isinf}. +@end deftypefn + +@deftypefn {Template} {bool} std.math.traits.isNaN (X)(X x) + +Returns true if @var{x} is NaN. + +This function is evaluated during CTFE as the GCC built-in function +@code{__builtin_isnan}. +@end deftypefn + +@deftypefn {Function} {float} std.math.trigoometry.tan (float x) +@deftypefnx {Function} {double} std.math.trigoometry.tan (double x) +@deftypefnx {Function} {real} std.math.trigonometry.tan (real x) + +Returns tangent of @var{x}, where @var{x} is in radians. + +This intrinsic is the same as the GCC built-in function @code{__builtin_tan}. +@end deftypefn + + +@c -------------------------------------------------------- + +@node Predefined Pragmas +@section Predefined Pragmas +@cindex predefined pragmas +@cindex @code{pragma} + +The @code{@w{pragma}} operator is used as a way to pass special information to the +implementation and allow the addition of vendor specific extensions. The +standard predefined pragmas are documented by the D language specification +hosted at @uref{https://dlang.org/spec/pragma.html#predefined-pragmas}. A D +compiler must recognize, but is free to ignore any pragma in this list. + +Where a pragma is ignored, the GNU D compiler will emit a warning when the +@option{-Wunknown-pragmas} option is seen on the command-line. + +@table @code +@item pragma(crt_constructor) +@code{pragma(crt_constructor)} annotates a function so it is run after the C +runtime library is initialized and before the D runtime library is initialized. +Functions with this pragma must return @code{void}. +@smallexample +pragma(crt_constructor) void init() @{ @} +@end smallexample + +@item pragma(crt_destructor) +@code{pragma(crt_destructor)} annotates a function so it is run after the D +runtime library is terminated and before the C runtime library is terminated. +Calling @code{exit} function also causes the annotated functions to run. +Functions with this pragma must return @code{void}. +@smallexample +pragma(crt_destructor) void init() @{ @} +@end smallexample + +@item pragma(inline) +@itemx pragma(inline, false) +@itemx pragma(inline, true) +@code{pragma(inline)} affects whether functions are declared inlined or not. +The pragma takes two forms. In the first form, inlining is controlled by the +command-line options for inlining. + +Functions annotated with @code{pragma(inline, false)} are marked uninlinable. +Functions annotated with @code{pragma(inline, true)} are always inlined. + +@item pragma(lib) +This pragma is accepted, but has no effect. +@smallexample +pragma(lib, "advapi32"); +@end smallexample + +@item pragma(linkerDirective) +This pragma is accepted, but has no effect. +@smallexample +pragma(linkerDirective, "/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2"); +@end smallexample + +@item pragma(mangle) +@code{pragma(mangle, "symbol_name")} overrides the default mangling for a +function or variable symbol. The symbol name can be any expression that must +evaluate at compile time to a string literal. This enables linking to a symbol +which is a D keyword, since an identifier cannot be a keyword. + +Targets are free to apply a prefix to the user label of the symbol name in +assembly. For example, on @code{x86_64-apple-darwin}, @samp{symbol_name} would +produce @samp{_symbol_name}. If the mangle string begins with @samp{*}, then +@code{pragma(mangle)} will output the rest of the string unchanged. + +@smallexample +pragma(mangle, "body") +extern(C) void body_func(); + +pragma(mangle, "function") +extern(C++) struct _function @{@} +@end smallexample + +@item pragma(msg) +@code{pragma(msg, "message")} causes the compiler to print an informational +message with the text @samp{message}. The pragma accepts multiple arguments, +each to which is evaluated at compile time and then all are combined into one +concatenated message. +@smallexample +pragma(msg, "compiling...", 6, 1.0); // prints "compiling...61.0" +@end smallexample + +@item pragma(printf) +@itemx pragma(scanf) + +@code{pragma(printf)} and @code{pragma(scanf)} specifies that a function +declaration with @code{printf} or @code{scanf} style arguments that should be +type-checked against a format string. + +A printf-like or scanf-like function can either be an @code{extern(C)} or +@code{extern(C++)} function with a @var{format} parameter accepting a pointer +to a 0-terminated @code{char} string, immediately followed by either a +@code{...} variadic argument list or a parameter of type @code{va_list} as the +last parameter. + +@smallexample +extern(C): +pragma(printf) +int printf(scope const char* format, scope const ...); + +pragma(scanf) +int vscanf(scope const char* format, va_list arg); +@end smallexample + +@item pragma(startaddress) +This pragma is accepted, but has no effect. +@smallexample +void foo() @{ @} +pragma(startaddress, foo); +@end smallexample + +@end table + + +@c -------------------------------------------------------- + +@node Predefined Versions +@section Predefined Versions +@cindex predefined versions +@cindex @code{version} + +Several conditional version identifiers are predefined; you use them without +supplying their definitions. They fall into three classes: standard, common, +and target-specific. + +Predefined version identifiers from this list cannot be set from the command +line or from version statements. This prevents things like both @code{Windows} +and @code{linux} being simultaneously set. + +@menu +* Standard Predefined Versions:: +* Common Predefined Versions:: +* Target Predefined Versions:: +@end menu + +@c -------------------------------------------------------- + +@node Standard Predefined Versions +@subsection Standard Predefined Versions +@cindex standard predefined versions + +The standard predefined versions are documented by the D language specification +hosted at @uref{https://dlang.org/spec/version.html#predefined-versions}. + +@table @code +@item all +@itemx none +Version @code{none} is never defined; used to just disable a section of code. +Version @code{all} is always defined; used as the opposite of @code{none}. + +@item BigEndian +@itemx LittleEndian +These versions reflect the byte order of multi-byte data in memory. +@code{LittleEndian} is set when the least significant byte is first. +@code{BigEndian} is set when the most significant byte is first. + +@item CRuntime_Bionic +@itemx CRuntime_Glibc +@itemx CRuntime_Microsoft +@itemx CRuntime_Musl +@itemx CRuntime_Newlib +@itemx CRuntime_UClibc + +These versions reflect which standard C library is being linked in. +@code{CRuntime_Bionic} is set when Bionic is the default C library. +@code{CRuntime_Glibc} is set when GLIBC is the default C library. +@code{CRuntime_Microsoft} is set when MSVCRT is the default C library. +@code{CRuntime_Musl} is set when musl is the default C library. +@code{CRuntime_Newlib} is set when Newlib is the default C library. +@code{CRuntime_UClibc} is set when uClibc is the default C library. + +@item CppRuntime_Gcc +This version is defined when the standard C++ library being linked in is @file{libstdc++}. + +@item D_BetterC +This version is defined when the standard D libraries are not being implicitly +linked in. This also implies that features of the D language that rely on +exceptions, module information, or run-time type information are disabled as +well. Enabled by @option{-fno-druntime}. + +@item D_Coverage +This version is defined when code coverage analysis instrumentation is being +generated. Enabled by @option{-ftest-coverage}. + +@item D_Ddoc +This version is defined when Ddoc documentation is being generated. Enabled by +@option{-fdoc}. + +@item D_Exceptions +This version is defined when exception handling is supported. Disabled by +@option{-fno-exceptions}. + +@item D_HardFloat +@itemx D_SoftFloat +These versions reflect the floating-point ABI in use by the target. +@code{D_HardFloat} is set when the target hardware has a floating-point unit. +@code{D_SoftFloat} is set when the target hardware does not have a +floating-point unit. + +@item D_Invariants +This version is defined when checks are being emitted for class invariants and +struct invariants. Enabled by @option{-finvariants}. + +@item D_LP64 +This version is defined when pointers are 64-bits. Not to be confused with +with C's @code{__LP64__} model. + +@item D_ModuleInfo +This version is defined when run-time module information (also known as +@code{ModuleInfo}) is supported. Disabled by @option{-fno-moduleinfo}. + +@item D_NoBoundsChecks +This version is defined when array bounds checks are disabled. Enabled by +@option{-fno-bounds-checks}. + +@item D_Optimized +This version is defined in all optimizing compilations. + +@item D_PIC +This version is defined when position-independent code is being generated. +Enabled by @option{-fPIC}. + +@item D_PIE +This version is defined when position-independent code that can be only linked +into executables is being generated. Enabled by @option{-fPIE}. + +@item D_PreConditions +This version is defined when checks are being emitted for @code{in} contracts. +Disabled by @option{-fno-preconditions}. + +@item D_PostConditions +This version is defined when checks are being emitted for @code{out} contracts. +Disabled by @option{-fno-postconditions}. + +@item D_TypeInfo +This version is defined when run-time type information (also known as +@code{TypeInfo}) is supported. Disabled by @option{-fno-rtti}. + +@item D_Version2 +This version defined when this is a D version 2 compiler. + +@item unittest +This version is defined when the @code{unittest} code is being compiled in. +Enabled by @option{-funittest}. + +@end table + +@c -------------------------------------------------------- + +@node Common Predefined Versions +@subsection Common Predefined Versions +@cindex common predefined versions + +The common predefined macros are GNU D extensions. They are available +with the same meanings regardless of the machine or operating system on +which you are using GNU D. Their names all start with @code{GNU}. + +@table @code + +@item GNU +This version is defined by the GNU D compiler. If all you need to know is +whether or not your D program is being compiled by GDC, or a non-GDC compiler, +you can simply test @code{version(GNU)}. + +@item GNU_DWARF2_Exceptions +@itemx GNU_SEH_Exceptions +@itemx GNU_SjLj_Exceptions +These versions reflect the mechanism that will be used for exception handling +by the target. @code{GNU_DWARF2_Exceptions} is defined when the target uses +DWARF 2 exceptions. @code{GNU_SEH_Exceptions} is defined when the target uses +SEH exceptions. @code{GNU_SjLj_Exceptions} is defined when the target uses the +@code{setjmp}/@code{longjmp}-based exception handling scheme. + +@item GNU_EMUTLS +This version is defined if the target does not support thread-local storage, +and an emulation layer is used instead. + +@item GNU_InlineAsm +This version is defined when @code{asm} statements use GNU D style syntax. +(@pxref{Inline Assembly}) + +@item GNU_StackGrowsDown +This version is defined if pushing a word onto the stack moves the stack +pointer to a smaller address, and is undefined otherwise. + +@end table + +@c -------------------------------------------------------- + +@node Target Predefined Versions +@subsection Target-specific Predefined Versions +@cindex target-specific predefined versions + +The D compiler normally predefines several versions that indicate what type of +system and machine is in use. They are obviously different on each target +supported by GCC. + +@table @code +@item AArch64 +Version relating to the AArch64 family of processors. + +@item Android +Version relating to the Android platform. + +@item ARM +@itemx ARM_HardFloat +@itemx ARM_SoftFloat +@itemx ARM_SoftFP +@itemx ARM_Thumb +Versions relating to the ARM family of processors. + +@item Cygwin +Version relating to the Cygwin environment. + +@item darwin +Deprecated; use @code{OSX} instead. + +@item DragonFlyBSD +Versions relating to DragonFlyBSD systems. + +@item FreeBSD +@item FreeBSD_9 +@item FreeBSD_10 +@item FreeBSD_11 +@item FreeBSD_... +Versions relating to FreeBSD systems. The FreeBSD major version number is +inferred from the target triplet. + +@item HPPA +@itemx HPPA64 +Versions relating to the HPPA family of processors. + +@item Hurd +Version relating to GNU Hurd systems. + +@item linux +Version relating to Linux systems. + +@item MinGW +Version relating to the MinGW environment. + +@item MIPS32 +@itemx MIPS64 +@itemx MIPS_EABI +@itemx MIPS_HardFloat +@itemx MIPS_N32 +@itemx MIPS_N64 +@itemx MIPS_O32 +@itemx MIPS_O64 +@itemx MIPS_SoftFloat +Versions relating to the MIPS family of processors. + +@item NetBSD +Version relating to NetBSD systems. + +@item OpenBSD +Version relating to OpenBSD systems. + +@item OSX +Version relating to OSX systems. + +@item Posix +Version relating to POSIX systems (includes Linux, FreeBSD, OSX, Solaris, etc). + +@item PPC +@itemx PPC64 +@itemx PPC_HardFloat +@itemx PPC_SoftFloat +Versions relating to the PowerPC family of processors. + +@item RISCV32 +@itemx RISCV64 +Versions relating to the RISC-V family of processors. + +@item S390 +@itemx SystemZ +Versions relating to the S/390 and System Z family of processors. + +@item S390X +Deprecated; use @code{SystemZ} instead. + +@item Solaris +Versions relating to Solaris systems. + +@item SPARC +@itemx SPARC64 +@itemx SPARC_HardFloat +@itemx SPARC_SoftFloat +@itemx SPARC_V8Plus +Versions relating to the SPARC family of processors. + +@item Thumb +Deprecated; use @code{ARM_Thumb} instead. + +@item D_X32 +@itemx X86 +@itemx X86_64 +Versions relating to the x86-32 and x86-64 family of processors. + +@item Windows +@itemx Win32 +@itemx Win64 +Versions relating to Microsoft Windows systems. + +@end table + + +@c -------------------------------------------------------- + +@node Special Enums +@section Special Enums +@cindex special enums + +Special @code{enum} names are used to represent types that do not have an +equivalent basic D type. For example, C++ types used by the C++ name mangler. + +Special enums are declared opaque, with a base type explicitly set. Unlike +regular opaque enums, special enums can be used as any other value type. They +have a default @code{.init} value, as well as other enum properties available +(@code{.min}, @code{.max}). Special enums can be declared in any module, and +will be recognized by the compiler. + +@smallexample +import gcc.builtins; +enum __c_long : __builtin_clong; +__c_long var = 0x800A; +@end smallexample + +@noindent +The following identifiers are recognized by GNU D. + +@table @code +@item __c_complex_double +C @code{_Complex double} type. +@item __c_complex_float +C @code{_Complex float} type. +@item __c_complex_real +C @code{_Complex long double} type. +@item __c_long +C++ @code{long} type. +@item __c_longlong +C++ @code{long long} type. +@item __c_long_double +C @code{long double} type. +@item __c_ulong +C++ @code{unsigned long} type. +@item __c_ulonglong +C++ @code{unsigned long long} type. +@item __c_wchar_t +C++ @code{wchar_t} type. +@end table + +The @code{core.stdc.config} module declares the following shorthand alias types +for convenience: @code{c_complex_double}, @code{c_complex_float}, +@code{c_complex_real}, @code{cpp_long}, @code{cpp_longlong}, +@code{c_long_double}, @code{cpp_ulong}, @code{cpp_ulonglong}. + + +@c -------------------------------------------------------- + +@node Traits +@section Traits +@cindex traits + +Traits are extensions to the D programming language to enable programs, at +compile time, to get at information internal to the compiler. This is also +known as compile time reflection. + +GNU D implements a @code{__traits(getTargetInfo)} trait that receives a string +key as its argument. The result is an expression describing the requested +target information. + +@smallexample +version (OSX) +@{ + static assert(__traits(getTargetInfo, "objectFormat") == "macho"); +@} +@end smallexample + +@noindent +Keys for the trait are implementation defined, allowing target-specific data +for exotic targets. A reliable subset exists which a D compiler must +recognize. These are documented by the D language specification hosted at +@uref{https://dlang.org/spec/traits.html#getTargetInfo}. + +The following keys are recognized by GNU D. + +@table @code +@item cppRuntimeLibrary +The C++ runtime library affinity for this toolchain. + +@item cppStd +The version of the C++ standard supported by @code{extern(C++)} code, +equivalent to the @code{__cplusplus} macro in a C++ compiler. + +@item floatAbi +Floating point ABI; may be @samp{hard}, @samp{soft}, or @samp{softfp}. + +@item objectFormat +Target object format. + +@end table + + +@c -------------------------------------------------------- + +@node Vector Extensions +@section Vector Extensions +@cindex vector extensions +@cindex simd + +CPUs often support specialized vector types and vector operations (aka media +instructions). Vector types are a fixed array of floating or integer types, +and vector operations operate simultaneously on them. + +@smallexample +alias int4 = __vector(int[4]); +@end smallexample + +@noindent +All the basic integer types can be used as base types, both as signed and as +unsigned: @code{byte}, @code{short}, @code{int}, @code{long}. In addition, +@code{float} and @code{double} can be used to build floating-point vector +types, and @code{void} to build vectors of untyped data. Only sizes that are +positive power-of-two multiples of the base type size are currently allowed. + +@noindent +The @code{core.simd} module has the following shorthand aliases for commonly +supported vector types: +@code{byte8}, @code{byte16}, @code{byte32}, @code{byte64}, +@code{double1}, @code{double2}, @code{double4}, @code{double8}, +@code{float2}, @code{float4}, @code{float8}, @code{float16}, +@code{int2}, @code{int4}, @code{int8}, @code{int16}, +@code{long1}, @code{long2}, @code{long4}, @code{long8}, +@code{short4}, @code{short8}, @code{short16}, @code{short32}, +@code{ubyte8}, @code{ubyte16}, @code{ubyte32}, @code{ubyte64}, +@code{uint2}, @code{uint4}, @code{uint8}, @code{uint16}, +@code{ulong1}, @code{ulong2}, @code{ulong4}, @code{ulong8}, +@code{ushort4}, @code{ushort8}, @code{ushort16}, @code{ushort32}, +@code{void8}, @code{void16}, @code{void32}, @code{void64}. +All these aliases correspond to @code{__vector(type[N])}. + +Which vector types are supported depends on the target. Only vector types that +are implemented for the current architecture are supported at compile-time. +Vector operations that are not supported in hardware cause GNU D to synthesize +the instructions using a narrower mode. + +@smallexample +alias v4i = __vector(int[4]); +alias v128f = __vector(float[128]); // Error: not supported on this platform + +int4 a, b, c; + +c = a * b; // Natively supported on x86 with SSE4 +c = a / b; // Always synthesized +@end smallexample + +@noindent +Vector types can be used with a subset of normal D operations. Currently, GNU +D allows using the following operators on these types: @code{+, -, *, /, +unary+, unary-}@. + +@smallexample +alias int4 = __vector(int[4]); + +int4 a, b, c; + +c = a + b; +@end smallexample + +@noindent +It is also possible to use shifting operators @code{<<}, @code{>>}, the modulus +operator @code{%}, logical operations @code{&, |, ^}, and the complement +operator @code{unary~} on integer-type vectors. + +For convenience, it is allowed to use a binary vector operation where one +operand is a scalar. In that case the compiler transforms the scalar operand +into a vector where each element is the scalar from the operation. The +transformation happens only if the scalar could be safely converted to the +vector-element type. Consider the following code. + +@smallexample +alias int4 = __vector(int[4]); + +int4 a, b; +long l; + +a = b + 1; // a = b + [1,1,1,1]; +a = 2 * b; // a = [2,2,2,2] * b; + +a = l + a; // Error, incompatible types. +@end smallexample + +@noindent +Vector comparison is supported with standard comparison operators: +@code{==, !=, <, <=, >, >=}. Comparison operands can be vector expressions of +integer-type or real-type. Comparison between integer-type vectors and +real-type vectors are not supported. The result of the comparison is a vector +of the same width and number of elements as the comparison operands with a +signed integral element type. + +Vectors are compared element-wise producing 0 when comparison is false +and -1 (constant of the appropriate type where all bits are set) +otherwise. Consider the following example. + +@smallexample +alias int4 = __vector(int[4]); + +int4 a = [1,2,3,4]; +int4 b = [3,2,1,4]; +int4 c; + +c = a > b; // The result would be [0, 0,-1, 0] +c = a == b; // The result would be [0,-1, 0,-1] +@end smallexample + + +@c -------------------------------------------------------- + +@node Vector Intrinsics +@section Vector Intrinsics +@cindex intrinsics, vector + +The following functions are a collection of vector operation intrinsics, +available by importing the @code{gcc.simd} module. + +@deftypefn {Template} {void} gcc.simd.prefetch (bool @var{rw}, @ + ubyte @var{locality}) @ + (const(void)* @var{addr}) + +Emit the prefetch instruction. The value of @var{addr} is the address of the +memory to prefetch. The value of @var{rw} is a compile-time constant one or +zero; one means that the prefetch is preparing for a write to the memory +address and zero, the default, means that the prefetch is preparing for a read. +The value @var{locality} must be a compile-time constant integer between zero +and three. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_prefetch}. + +@smallexample +for (i = 0; i < n; i++) +@{ + import gcc.simd : prefetch; + a[i] = a[i] + b[i]; + prefetch!(true, 1)(&a[i+j]); + prefetch!(false, 1)(&b[i+j]); + // @r{@dots{}} +@} +@end smallexample +@end deftypefn + +@deftypefn {Template} {V} gcc.simd.loadUnaligned (V)(const V* @var{p}) + +Load unaligned vector from the address @var{p}. + +@smallexample +float4 v; +ubyte[16] arr; + +v = loadUnaligned(cast(float4*)arr.ptr); +@end smallexample +@end deftypefn + +@deftypefn {Template} {V} gcc.simd.storeUnaligned (V)(V* @var{p}, V @var{value}) + +Store vector @var{value} to unaligned address @var{p}. + +@smallexample +float4 v; +ubyte[16] arr; + +storeUnaligned(cast(float4*)arr.ptr, v); +@end smallexample +@end deftypefn + +@deftypefn {Template} {V0} gcc.simd.shuffle (V0, V1, M)(V0 @var{op1}, @ + V1 @var{op2}, @ + M @var{mask}) +@deftypefnx {Template} {V} gcc.simd.shuffle (V, M)(V @var{op1}, M @var{mask}) + +Construct a permutation of elements from one or two vectors, returning a vector +of the same type as the input vector(s). The @var{mask} is an integral vector +with the same width and element count as the output vector. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_shuffle}. + +@smallexample +int4 a = [1, 2, 3, 4]; +int4 b = [5, 6, 7, 8]; +int4 mask1 = [0, 1, 1, 3]; +int4 mask2 = [0, 4, 2, 5]; +int4 res; + +res = shuffle(a, mask1); // res is [1,2,2,4] +res = shuffle(a, b, mask2); // res is [1,5,3,6] +@end smallexample +@end deftypefn + +@deftypefn {Template} {V} gcc.simd.shufflevector (V1, V2, M...)(V1 @var{op1}, @ + V2 @var{op2}, M @var{mask}) +@deftypefnx {Template} {V} gcc.simd.shufflevector (V, @var{mask}...)(V @ + @var{op1}, V @var{op2}) + +Construct a permutation of elements from two vectors, returning a vector with +the same element type as the input vector(s), and same length as the +@var{mask}. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_shufflevector}. + +@smallexample +int8 a = [1, -2, 3, -4, 5, -6, 7, -8]; +int4 b = shufflevector(a, a, 0, 2, 4, 6); // b is [1,3,5,7] +int4 c = [-2, -4, -6, -8]; +int8 d = shufflevector!(int8, 4, 0, 5, 1, 6, 2, 7, 3)(c, b); // d is a +@end smallexample +@end deftypefn + +@deftypefn {Template} {E} gcc.simd.extractelement (V, int idx)(V @var{val}) +Extracts a single scalar element from a vector @var{val} at a specified index +@var{idx}. + +@smallexample +int4 a = [0, 10, 20, 30]; +int k = extractelement!(int4, 2)(a); // a is 20 +@end smallexample +@end deftypefn + +@deftypefn {Template} {V} gcc.simd.insertelement (V, int idx)(V val, B @var{e}) +Inserts a scalar element @var{e} into a vector @var{val} at a specified index +@var{idx}. + +@smallexample +int4 a = [0, 10, 20, 30]; +int4 b = insertelement!(int4, 2)(a, 50); // b is [0,10,50,30] +@end smallexample +@end deftypefn + +@deftypefn {Template} {V} gcc.simd.convertvector (V, T)(T val) +Convert a vector @var{val} from one integral or floating vector type to +another. The result is an integral or floating vector that has had every +element cast to the element type of the return type. + +This intrinsic is the same as the GCC built-in function +@code{__builtin_convertvector}. + +@smallexample +int4 a = [1, -2, 3, -4]; +float4 b = [1.5, -2.5, 3, 7]; +float4 c = convertvector!float4(a); // c is [1,-2,3,-4] +double4 d = convertvector!double4(a); // d is [1,-2,3,-4] +double4 e = convertvector!double4(b); // e is [1.5,-2.5,3,7] +int4 f = convertvector!int4(b); // f is [1,-2,3,7] +@end smallexample +@end deftypefn + +@deftypefn {Template} {V0} gcc.simd.blendvector (V0, V1, M)(V0 @var{op0}, @ + V1 @var{op1}, @ + M @var{mask}) + +Construct a conditional merge of elements from two vectors, returning a vector +of the same type as the input vector(s). The @var{mask} is an integral vector +with the same width and element count as the output vector. + +@smallexample +int4 a = [1, 2, 3, 4]; +int4 b = [3, 2, 1, 4]; +auto c = blendvector(a, b, a > b); // c is [3,2,3,4] +auto d = blendvector(a, b, a < b); // d is [1,2,1,4] +@end smallexample +@end deftypefn + + +@c -------------------------------------------------------- + +@node Missing Features +@section Missing Features and Deviations +@cindex missing features +@cindex D spec deviations + +Some parts of the D specification are hard or impossible to implement with +GCC, they should be listed here. + +@table @asis +@item Bit Operation Intrinsics +The Digital Mars D compiler implements the @code{core.bitop} intrinsics +@code{inp}, @code{inpw}, @code{inpl}, @code{outp}, @code{outpw}, and +@code{outpl}. These are not recognized by GNU D. On most targets, equivalent +intrinsics that have the same effect would be @code{core.volatile.loadVolatile} +and @code{core.volatile.storeVolatile} respectively +(@pxref{Volatile Intrinsics}). + +On x86 targets, if an @code{in} or @code{out} instruction is specifically +required, that can be achieved using assembler statements instead. +@smallexample +ubyte inp(uint port) +@{ + ubyte value; + asm @{ "inb %w1, %b0" : "=a" (value) : "Nd" (port); @} + return value; +@} + +void outp(uint port, ushort value) +@{ + asm @{ "outb %b0, %w1" : : "a" (value), "Nd" (port); @} +@} +@end smallexample + +@item Floating-Point Intermediate Values + +GNU D uses a software compile-time floating-point type that assists in +cross-compilation and support for arbitrary target @code{real} precisions wider +than 80 bits. Because of this, the result of floating-point CTFE operations +may have different results in GNU D compared with other D compilers that use +the host's native floating-point type for storage and CTFE. In particular, GNU +D won't overflow or underflow when a target real features a higher precision +than the host. Differences also extend to @code{.stringof} representations of +intermediate values due to formatting differences with @code{sprintf("%Lg")}. +@smallexample +version(GNU) + assert((25.5).stringof ~ (3.01).stringof == "2.55e+13.01e+0"); +else + assert((25.5).stringof ~ (3.01).stringof == "25.53.01"); +@end smallexample + +@item Function Calling Conventions +GNU D does not implement the @code{extern(D)} calling convention for x86 as +described in the D specification hosted at +@uref{https://dlang.org/spec/abi.html#function_calling_conventions}. + +Instead, there is no distinction between @code{extern(C)} and @code{extern(D)} +other than name mangling. + +@item ImportC Limitations +GNU D does not run the preprocessor automatically for any ImportC sources. +Instead all C files are expected to be manually preprocessed before they are +imported into the compilation. + +@item Inline Assembler +GNU D does not implement the D inline assembler for x86 and x86_64 as described +in the D specification hosted at @uref{https://dlang.org/spec/iasm.html}. Nor +does GNU D predefine the @code{D_InlineAsm_X86} and @code{D_InlineAsm_X86_64} +version identifiers to indicate support. + +The GNU D compiler uses an alternative, GCC-based syntax for inline assembler +(@pxref{Inline Assembly}). + +@item Interfacing to Objective-C +GNU D does not support interfacing with Objective-C, nor its protocols, +classes, subclasses, instance variables, instance methods and class methods. +The @code{extern(Objective-C)} linkage is ignored, as are the @code{@@optional} +and @code{@@selector} attributes. The @code{D_ObjectiveC} version identifier +is not predefined for compilations. + +@item Pragma Directives +Pragmas that are designed to embed information into object files or otherwise +pass options to the linker are not supported by GNU D. These include +@code{pragma(lib)}, @code{pragma(linkerDirective)}, and +@code{pragma(startaddress)}. + +@item SIMD Intrinsics +The Digital Mars D compiler implements the @code{core.simd} intrinsics +@code{__simd}, @code{__simd_ib}, @code{__simd_sto}. These are not recognized +by GNU D, nor does GNU D predefine the @code{D_SIMD} version identifier to +indicate support. + +On x86 targets, all intrinsics are available as functions in the +@code{gcc.builtins} module, and have predictable equivalents. +@smallexample +version (DigitalMars) +@{ + __simd(XMM.PSLLW, op1, op2); + __simd_ib(XMM.PSLLW, op1, imm8); +@} +version (GNU) +@{ + __builtin_ia32_psllw(op1, op2); + __builtin_ia32_psllwi(op1, imm8); +@} +@end smallexample + +@end table