diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index 144d5b88483..b5264613db0 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 45dc544e83f..c99c36558a9 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 00000000000..8f3f825e797
--- /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
