diff mbox series

[committed] d: Add language reference section to documentation files.

Message ID 20221130214812.554893-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Add language reference section to documentation files. | expand

Commit Message

Iain Buclaw Nov. 30, 2022, 9:48 p.m. UTC
Hi,

This adds an initial body of documentation for the D front-end - other
than the existing documentation for command-line usage/the man page.

Documentation covers code generation choices specific to GNU D - what
attributes are supported, intrinsics, pragmas, predefined versions,
language extensions, missing features and deviations from spec.

More could be added or elaborated upon, such as what linkage do
different symbols get, mixed language programming with C and C++, the
anatomy of a TypeInfo and ModuleInfo object, and so on.  This is enough
as a first wave just to get it off the ground.

Tested with `make html', and committed to mainline.

Regards,
Iain

---
gcc/d/ChangeLog:

	* Make-lang.in (D_TEXI_FILES): Add d/implement-d.texi.
	* gdc.texi: Adjust introduction, include implement-d.texi.
	* implement-d.texi: New file.
---
 gcc/d/Make-lang.in     |    1 +
 gcc/d/gdc.texi         |   12 +-
 gcc/d/implement-d.texi | 2514 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 2523 insertions(+), 4 deletions(-)
 create mode 100644 gcc/d/implement-d.texi
diff mbox series

Patch

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