This reduces the overhead for auto-detecting and setting up an MSVC
toolchain from a very rough 1 second to about 8 milliseconds on my box.
Enabling the auto-detection by default (and so preferring MSVC over the
'internal' toolchain if there's a Visual C++ installation) is now
possible, fixing issues like #3402.
The MSVC setup now consists of the bare minimum - prepending 3
directories to the LIB env var and 1-2 directories to PATH.
Instead, error out whenever requested by an expression-less
`synchronized` statement, including source LoC to track it down.
This is safer, especially since the previous initial warning may likely
be suppressed, and makes this host-agnostic.
Also suppress previous warnings about unknown `` and `none` OS, treating
these like `unknown`.
Bail out on unsupported vector ops (not checking the rhs type for binops
though) in the frontend instead of causing LLVM errors.
Also precompute the target's critical section size once at startup, like
DMD.
Make the existing 64-bit code in argtypes.d DMD-specific (required due
to codegen issues) and add a new separate implementation for the SysV
x86_64 ABI to be used by LDC/GDC, closely following the algorithm laid
out in the spec [1].
Also don't needlessly compute a struct's argtypes for Win64 and
non-x86[_64] targets.
This fixes LDC ABI issues wrt. C[++] compatibility on Posix x86_64,
e.g., https://issues.dlang.org/show_bug.cgi?id=13957.
I went with signed integers to represent GP registers, and float/double/
__vector(double[N]) for vector registers (SSE + AVX); integer signedness
and vector element type are arbitrary.
[1] https://www.uclibc.org/docs/psABI-x86_64.pdf
Primarily not to break size_t interop. A size_t is probably much more
frequently used than `(unsigned) long long` (which Apple sadly chose for
their C++ `(u)int64_t`).
Which is a serious problem if the host real_t is a double and the target
`real` features a higher precision (cross-compilation).
`Target::RealProperties` are set up for the target's `real`, so
max/min_normal/epsilon may over/underflow, and so would
`DoubleProperties` if aliased.
By using upstream's Target.prefixName(), which prepends an additional
underscore on OSX/Darwin for C++ symbols.
We then need to prevent LLVM from implicitly prepending a third one.
As 'processing' a signalling NaN may convert it to a quiet NaN. Apparently
happening on 32-bit x86 using the x87 FPU, but not on x86_64 with SSE.
This fixes potential issues with different constants being used when
mixing natively and cross-compiled objects/libs and failing bitwise `is`
comparisons etc.
See https://forum.dlang.org/post/nsp1ql$ivu$1@digitalmars.com for Martin
Nowak's summarized findings.
While parsing of floating-point literals and CTFE still operate with the
host LDC's real type, compile-time reals can in principle be emitted in
arbitrary precision via LLVM software conversion, therefore paving the way
for cross-compilation to all targets.
The representable constants are still limited by the compile-time real_t
precision. E.g., LDC on Windows with its 64-bit reals can't hold and emit
an 80-bit `real.max` when cross-compiling to a non-Windows x86(_64)
target; the compile-time value will silently overflow to infinity and
later be emitted as 80-bit infinity.
LDC on AArch64 with its 128-bit quad-precision reals on the other hand can
hold and emit reals for all targets, making it a universal cross-compiler
with quad-precision compile-time reals in hardware.
We don't use the strange 2x64-bit PPC double-double format (see
`getRealType()` in `ir/irtype.cpp`), but would more or less support it
(the type properties (max, min_normal...) still need to be determined;
LLVM isn't sure about those either...).
The part needing most attention was ddmd.root.ctfloat, ddmd.target (incl.
gen/target.cpp) and ddmd.builtin. The front-end is now prepared for
elaborate compile-time floating-point types to allow for proper cross-
compilation.
This version still uses the host's `real` type for compile-time reals,
except for MSVC hosts, which still use 64-bit doubles (when compiled with
DMD host compiler too).
Some other changes:
* semantic*() of Statements extracted from statement.d to statementsem.d
* mangle() -> mangleToBuffer()
* Identifier::string -> toChars()
* Token::float80value => floatvalue
* Dsymbol::isAggregateMember() => isMember()
* BoolExp is no more
* ddmd.root.ctfloat: LDC-specific CTFE builtins
The missing alignment is a front-end bug; this is a combined backport
of dlang/dmd@b9aa6ed and dlang/dmd@a93fa3c.
For POSIX targets, the critical section size was assumed to be identical
to the host compiler's, which generally isn't true when cross-compiling.
DtoMutexType() wasn't used anywhere, so I removed it.