blob: 770189caf504e666e6bcf5db011055f7b5ef9431 [file] [log] [blame]
@ignore
Copyright (C) 2022-2024 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
@cindex @code{alloc_size} function attribute
@cindex @code{alloc_size} variable attribute
@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}))
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
@cindex @code{always_inline} function attribute
@item @@(gcc.attributes.always_inline)
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
@cindex @code{cold} function attribute
@item @@(gcc.attributes.cold)
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
@cindex @code{flatten} function attribute
@item @@(gcc.attributes.flatten)
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
@cindex @code{no_icf} function attribute
@item @@(gcc.attributes.no_icf)
The @code{@@no_icf} attribute prevents a function from being merged with
another semantically equivalent function.
@smallexample
@@no_icf int func();
@end smallexample
@cindex @code{no_sanitize} function attribute
@item @@(gcc.attributes.no_sanitize ("@var{sanitize_option}"))
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
@cindex @code{noclone} function attribute
@item @@(gcc.attributes.noclone)
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
@cindex @code{noinline} function attribute
@item @@(gcc.attributes.noinline)
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
@cindex @code{noipa} function attribute
@item @@(gcc.attributes.noipa)
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
@cindex @code{noplt} function attribute
@item @@(gcc.attributes.noplt)
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
@cindex @code{optimize} function attribute
@item @@(gcc.attributes.optimize (@var{arguments}))
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
@cindex @code{register} variable attribute
@item @@(gcc.attributes.register ("@var{registerName}"))
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
@cindex @code{restrict} parameter attribute
@item @@(gcc.attributes.restrict)
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
@cindex @code{section} function attribute
@cindex @code{section} variable attribute
@item @@(gcc.attributes.section ("@var{sectionName}"))
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
@cindex @code{simd} function attribute
@item @@(gcc.attributes.simd)
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
@cindex @code{simd_clones} function attribute
@item @@(gcc.attributes.simd_clones ("@var{mask}"))
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
@cindex @code{symver} function attribute
@item @@(gcc.attributes.symver ("@var{arguments}"))
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
@cindex @code{target} function attribute
@item @@(gcc.attributes.target ("@var{options}"))
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
@cindex @code{target_clones} function attribute
@item @@(gcc.attributes.target_clones ("@var{options}"))
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
@cindex @code{used} function attribute
@cindex @code{used} variable attribute
@item @@(gcc.attributes.used)
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
@cindex @code{visibility} function attribute
@cindex @code{visibility} variable attribute
@item @@(gcc.attributes.visibility ("@var{visibilityName}"))
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
@cindex @code{weak} function attribute
@cindex @code{weak} variable attribute
@item @@(gcc.attributes.weak)
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
@cindex @code{allocSize} function attribute
@item @@(gcc.attributes.allocSize (@var{sizeArgIdx}))
@itemx @@(gcc.attributes.allocSize (@var{sizeArgIdx}, @var{numArgIdx}))
@item @@(gcc.attributes.allocSize (@var{sizeArgIdx}))
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.
@cindex @code{assumeUsed} function attribute
@cindex @code{assumeUsed} variable attribute
@item @@(gcc.attributes.assumeUsed)
This attribute is a synonym for @code{@@used}.
@cindex @code{dynamicCompile} function attribute
@item @@(gcc.attributes.dynamicCompile)
@itemx @@(gcc.attributes.dynamicCompileConst)
@itemx @@(gcc.attributes.dynamicCompileEmit)
These attributes are accepted, but have no effect.
@cindex @code{fastmath} function attribute
@item @@(gcc.attributes.fastmath)
This attribute is a synonym for @code{@@optimize("Ofast")}. Explicitly sets
"fast-math" for a function, enabling aggressive math optimizations.
@cindex @code{hidden} function attribute
@cindex @code{hidden} variable attribute
@item @@(gcc.attributes.hidden)
This attribute is a synonym for @code{@@visibility("hidden")}. Sets the
visibility of a function or global variable to "hidden".
@cindex @code{naked} function attribute
@item @@(gcc.attributes.naked)
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.
@cindex @code{noSanitize} function attribute
@item @@(gcc.attributes.noSanitize ("@var{sanitize_option}"))
This attribute is a synonym for @code{@@no_sanitize("sanitize_option")}.
@cindex @code{optStrategy} function attribute
@item @@(gcc.attributes.optStrategy ("@var{strategy}"))
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}.
It may cause undefined behavior at runtime if a special enum is declared with a
base type that has a different size to the target C/C++ type it is
representing. The GNU D compiler will catch such declarations and emit a
warning when the @option{-Wmismatched-special-enum} option is seen on the
command-line.
@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
@item TypeInfo-based va_arg
The Digital Mars D compiler implements a version of @code{core.vararg.va_arg}
that accepts a run-time @code{TypeInfo} argument for use when the static type
is not known. This function is not implemented by GNU D. It is more portable
to use variadic template functions instead.
@end table