Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
00062e9
Add files for MSVC intrinsic implementations.
just-harry Apr 12, 2024
320e23b
Scaffold some versions for the MSVC intrinsic implementations.
just-harry Apr 12, 2024
e394210
Implement the MSVC intrinsics for extended-width multiplication.
just-harry Apr 12, 2024
a6ae4f9
Implement the MSVC intrinsics for extended-width division.
just-harry Apr 12, 2024
612d6da
Implement the MSVC intrinsics for the x86 `cpuid` instruction.
just-harry Apr 12, 2024
920d4aa
Define `gccBuiltins` privately for the MSVC intrinsic implementations.
just-harry Apr 12, 2024
1a06f80
Implement the MSVC intrinsics for fast float conversion.
just-harry Apr 12, 2024
5bc4e69
Implement the MSVC intrinsics for fast double conversion.
just-harry Apr 12, 2024
6269dd6
Implement the MSVC intrinsics for saturating float conversion.
just-harry Apr 12, 2024
d1e582e
Implement the MSVC intrinsics for saturating double conversion.
just-harry Apr 12, 2024
338ee6d
Implement the MSVC intrinsics for sentinel-on-invalid float conversion.
just-harry Apr 12, 2024
fd2313c
Implement the MSVC intrinsics for sentinel-on-invalid double conversion.
just-harry Apr 12, 2024
f855148
Implement the `__halt` MSVC intrinsic.
just-harry Apr 12, 2024
44a0ed4
Implement the `<op><g/f>s<size>` MSVC intrinsics.
just-harry Apr 12, 2024
27a4f3a
Implement the `<op>x18<size>` MSVC intrinsics.
just-harry Jun 27, 2026
c13655f
Implement the `__debugbreak` MSVC intrinsic.
just-harry Apr 12, 2024
a79ec4f
Implement the `__fastfail` MSVC intrinsic.
just-harry Apr 12, 2024
fa377bf
Implement the `__faststorefence` MSVC intrinsic.
just-harry Apr 12, 2024
9c3d39b
Implement the `_disable` MSVC intrinsic.
just-harry Apr 12, 2024
41d2d55
Implement the `_enable` MSVC intrinsic.
just-harry Apr 12, 2024
d37afcb
Implement the `_mm_pause` MSVC intrinsic.
just-harry Apr 19, 2024
fa2c1e9
Implement the MSVC intrinsics for ARM memory barriers.
just-harry Apr 21, 2024
7d2fc41
Implement the MSVC intrinsics for interlocked additions.
just-harry Apr 12, 2024
f5127cb
Implement the MSVC intrinsics for interlocked and-ing.
just-harry Apr 12, 2024
440000a
Implement the MSVC intrinsics for interlocked bit-test-and-resets.
just-harry Apr 12, 2024
f4cbb2b
Implement the MSVC intrinsics for interlocked bit-test-and-sets.
just-harry Apr 12, 2024
0337d1c
Implement the MSVC intrinsics for interlocked compare-and-exchanges.
just-harry Apr 12, 2024
e289597
Implement the MSVC intrinsics for 128-bit interlocked compare-and-exc…
just-harry Apr 12, 2024
5f18233
Implement the MSVC intrinsics for interlocked pointer compare-and-exc…
just-harry Apr 12, 2024
303a340
Implement the MSVC intrinsics for interlocked decrements.
just-harry Apr 12, 2024
bd19846
Implement the MSVC intrinsics for interlocked exchanges.
just-harry Apr 12, 2024
c765e2e
Implement the MSVC intrinsics for interlocked exchange-additions.
just-harry Apr 12, 2024
940fec2
Implement the MSVC intrinsics for interlocked pointer exchanges.
just-harry Apr 12, 2024
336daa5
Implement the MSVC intrinsics for interlocked increments.
just-harry Apr 12, 2024
dfd9e28
Implement the MSVC intrinsics for interlocked or-ing.
just-harry Apr 12, 2024
2ab6e6c
Implement the MSVC intrinsics for interlocked xor-ing.
just-harry Apr 12, 2024
78efe07
Implement the MSVC intrinsics for x86 I/O port handling.
just-harry Apr 12, 2024
4ba8674
Implement the `__int2c` MSVC intrinsic.
just-harry Apr 12, 2024
934946c
Implement the `__invlpg` MSVC intrinsic.
just-harry Apr 12, 2024
3d6f6e2
Implement the `__lidt` MSVC intrinsic.
just-harry Apr 12, 2024
6fcd7c3
Implement the MSVC intrinsics for 64-bit bit-shifts.
just-harry Apr 12, 2024
4d9532d
Implement the MSVC intrinsics for `lzcnt`.
just-harry Apr 12, 2024
adb47d5
Implement the MSVC intrinsics for SSE float<->integer conversion.
just-harry Apr 12, 2024
3930ee2
Implement the MSVC intrinsics for `tzcnt`.
just-harry Apr 21, 2024
614f14a
Implement the MSVC intrinsics for some SSE4a instructions.
just-harry Apr 12, 2024
d70b542
Implement the `_mm_stream_si64x` MSVC intrinsic.
just-harry Apr 12, 2024
db0360b
Implement the MSVC intrinsics for the x86 `rep movs` instruction.
just-harry Apr 12, 2024
70e86da
Implement the `__noop` MSVC intrinsic.
just-harry Apr 12, 2024
db5bfdd
Implement the `__nop` MSVC intrinsic.
just-harry Apr 12, 2024
3e63f7a
Implement the MSVC intrinsics for `popcnt`.
just-harry Apr 12, 2024
116b559
Implement the MSVC intrinsics for the x86 `rdtsc` instructions.
just-harry Apr 12, 2024
d9aa2eb
Implement the `__readcr<number>` MSVC intrinsics.
just-harry Apr 12, 2024
0ef9334
Implement the `__readdr` MSVC intrinsic.
just-harry Apr 12, 2024
c846346
Implement the `__readeflags` MSVC intrinsic.
just-harry Apr 12, 2024
341d3df
Implement the `__readmsr` MSVC intrinsic.
just-harry Apr 12, 2024
98acd14
Implement the `__readpmc` MSVC intrinsic.
just-harry Apr 12, 2024
348842f
Implement the `__segmentlimit` MSVC intrinsic.
just-harry Apr 12, 2024
38ea329
Implement the MSVC intrinsics for 128-bit bit-shifts.
just-harry Apr 12, 2024
960ee02
Implement the `__sidt` MSVC intrinsic.
just-harry Apr 12, 2024
8299d5f
Implement the MSVC intrinsics for the x86 `rep stos` instruction.
just-harry Apr 12, 2024
c921469
Implement the MSVC intrinsics for the AMD x86 SVM instruction set.
just-harry Apr 12, 2024
f4f3ed3
Implement the `__ud2` MSVC intrinsic.
just-harry Apr 12, 2024
dc62a56
Implement the MSVC intrinsics for the Intel x86 VMX instruction set.
just-harry Apr 12, 2024
31c6c7d
Implement the `__wbinvd` MSVC intrinsic.
just-harry Apr 12, 2024
348f5b4
Implement the `__writecr<number>` MSVC intrinsics.
just-harry Apr 12, 2024
2ebd70f
Implement the `__writedr` MSVC intrinsic.
just-harry Apr 12, 2024
32d8b9b
Implement the `__writeeflags` MSVC intrinsic.
just-harry Apr 12, 2024
ceeb101
Implement the `__writemsr` MSVC intrinsic.
just-harry Apr 12, 2024
f412f62
Implement the MSVC intrinsics for non-atomic read/write barriers.
just-harry Apr 12, 2024
9a924f1
Implement the MSVC intrinsics for bit-scanning.
just-harry Apr 12, 2024
6ece64b
Implement the MSVC intrinsics for bit-test operations.
just-harry Apr 12, 2024
fd8660b
Implement the MSVC intrinsics for byte-swapping.
just-harry Apr 12, 2024
52d817f
Implement the MSVC intrinsics for bit-rotation.
just-harry Apr 12, 2024
6fed743
Implement the `__yield` MSVC intrinsic.
just-harry Apr 19, 2024
04bfe0c
Implement the MSVC intrinsics for prefetching.
just-harry Jun 27, 2026
813f571
Implement the `_mm_clflush` MSVC intrinsic.
just-harry Jun 27, 2026
817e22b
Implement the MSVC intrinsics for loading/storing the x86 MXCSR regis…
just-harry Jun 27, 2026
e1ffcfb
Implement the MSVC intrinsics for AArch64 acquire/release atomic load…
just-harry Jun 27, 2026
9aebeaf
Implement the MSVC intrinsics for x86 memory fences.
just-harry Jun 27, 2026
979553a
Implement the MSVC intrinsics for volatile stores and loads.
just-harry Jun 27, 2026
3799caa
Define `__IMPORTC_DMD__` in `importc.h` to make it possible to detect…
just-harry Jul 3, 2026
828c65c
Implement the `__assume` MSVC intrinsic.
just-harry Apr 13, 2024
2dfa644
Apply `#pragma function_decl(ignore)` to the MSVC intrinsics implemen…
just-harry Jul 3, 2026
d473a1d
Pass the resolved path of `<path>/importc.h/../include` to the C prep…
just-harry Apr 23, 2024
1234559
Add a test for checking that MSVC intrinsics are actually available f…
just-harry Apr 21, 2024
2b2796d
Document the alternative licence of 0BSD for the MSVC intrinsics impl…
just-harry Jul 3, 2026
cf2cd6e
Document the ImportC `include` directory in ImportC's specification.
just-harry Jul 3, 2026
f4e0954
Document the `__builtins_msvc` module in ImportC's specification.
just-harry Jul 3, 2026
a5c4b3b
Add a changelog entry for ImportC supporting some of MSVC's intrinsics.
just-harry Apr 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions changelog/druntime.importc-initial-msvc-intrinsics.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ImportC implements the vast majority of MSVC's intrinsics: 461 of them to be exact.

ImportC now implements the vast majority of MSVC's intrinsics: 461 of them to be exact.
All but three of the intrinsics [listed here](https://web.archive.org/web/20240412171516/https://learn.microsoft.com/en-ie/cpp/intrinsics/alphabetical-listing-of-intrinsic-functions?view=msvc-170) are implemented, alongside a handful of undocumented intrinsics, accompanied by a smattering of ISA-specific intrinsics.

The presence of these intrinsics greatly improves ImportC's ability to successfully import C headers when targeting Windows.
Notably, `Windows.h` can now be successfully included by ImportC.

To make use of MSVC intrinsics in ImportC, simply `#include` the `importc_msvc_builtins.h` header before any C code that uses MSVC intrinsics:
```c
#include &lt;importc_msvc_builtins.h&gt;
#include &lt;windows.h&gt;
```
MSVC intrinsics are available when targeting the Microsoft C runtime (that is, when the `CRuntime_Microsoft` version identifier is defined).

Every intrinsic implemented has received optimised code for LDC, GDC, and DMD.
Each intrinsic, where possible, has a CTFE-compatible code path.

(Owing to the newness of DMD's AArch64 backend, MSVC intrinsics have not yet been implemented for DMD AArch64 targets. They have been implemented for LDC and GDC AArch64 targets.)
4 changes: 3 additions & 1 deletion compiler/src/dmd/cpreprocess.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ DArray!ubyte preprocess(FileName csrcfile, Loc loc, ref OutBuffer defines)
//printf("preprocess %s\n", csrcfile.toChars());
version (runPreprocessor)
{
const includePath = FileName.replaceName(toDString(importc_h), "include");
scope(exit) FileName.free(includePath.ptr);
const command = global.params.cpp ? toDString(global.params.cpp) : cppCommand();
DArray!ubyte text;
int status = runPreprocessor(loc, command, csrcfile.toString(), importc_h, global.params.cppswitches, global.params.v.verbose, global.errorSink, defines, text);
int status = runPreprocessor(loc, command, csrcfile.toString(), importc_h, includePath, global.params.cppswitches, global.params.v.verbose, global.errorSink, defines, text);
if (status)
fatal();
return text;
Expand Down
17 changes: 16 additions & 1 deletion compiler/src/dmd/link.d
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ public int runProgram(const char[] exefile, const char*[] runargs, bool verbose,
* cpp = name of C preprocessor program
* filename = C source file name
* importc_h = filename of importc.h
* includePath = path passed to the preprocessor as an include path
* cppswitches = array of switches to pass to C preprocessor
* verbose = print progress to eSink
* eSink = for verbose messages and error messages
Expand All @@ -976,7 +977,7 @@ public int runProgram(const char[] exefile, const char*[] runargs, bool verbose,
* Returns:
* error status, 0 for success
*/
public int runPreprocessor(Loc loc, const(char)[] cpp, const(char)[] filename, const(char)* importc_h, ref Array!(const(char)*) cppswitches,
public int runPreprocessor(Loc loc, const(char)[] cpp, const(char)[] filename, const(char)* importc_h, const(char)[] includePath, ref Array!(const(char)*) cppswitches,
bool verbose, ErrorSink eSink, ref OutBuffer defines, out DArray!ubyte text)
{
//printf("runPreprocessor() cpp: %.*s filename: %.*s\n", cast(int)cpp.length, cpp.ptr, cast(int)filename.length, filename.ptr);
Expand Down Expand Up @@ -1026,6 +1027,13 @@ public int runPreprocessor(Loc loc, const(char)[] cpp, const(char)[] filename, c
buf.printf(" /std:c11 /P /Zc:preprocessor /PD /nologo /utf-8 \"%.*s\" \"/FI%s\" \"/Fi%.*s\"",
cast(int)filename.length, filename.ptr, importc_h, cast(int)output.length, output.ptr);

/* Append the include path, if it was provided
*/
if (includePath)
{
buf.printf(` "/I%.*s"`, cast(int)includePath.length, includePath.ptr);
}
Comment on lines +1030 to +1035

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change will need to be made in LDC also.

I assume the same applies to GDC, although as I understand it GDC doesn't support targeting Windows, so whether GDC implements this change or not is immaterial at present.

To clarify, the reason for this change is to make importc_msvc_builtins.h available to the C preprocessor.

In future, other ImportC/DRuntime-provided headers can be placed in this directory, so this is a one-time change.

Pre-emptive LDC PR: ldc-developers/ldc#5169


/* Append preprocessor switches to command line
*/
foreach (a; cppswitches)
Expand Down Expand Up @@ -1196,6 +1204,13 @@ public int runPreprocessor(Loc loc, const(char)[] cpp, const(char)[] filename, c
// need to redefine some macros in importc.h
argv.push("-Wno-builtin-macro-redefined");

// append the include path, if it was provided
if (includePath)
{
argv.push("-I");
argv.push(includePath.xarraydup.ptr);
}

if (target.os == Target.OS.OSX)
{
argv.push("-fno-blocks"); // disable clang blocks extension
Expand Down
42 changes: 42 additions & 0 deletions compiler/test/compilable/msvc_intrinsics.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// DISABLED: osx linux freebsd openbsd netbsd dragonflybsd hurd
// LINK(windows):
// PERMUTE_ARGS: -betterC
// Checking that the MSVC intrinsics reimplemented for ImportC are actually available from C.

#include <importc_msvc_builtins.h>

#ifndef __IMPORTC_MSVC_BUILTINS__
#error importc_msvc_builtins.h should define __IMPORTC_MSVC_BUILTINS__.
#endif

// It should be safe to include importc_msvc_builtins.h multiple times.
#include <importc_msvc_builtins.h>

// Are the MSVC intrinsics actually usable from C?
#if defined(_M_AMD64)
unsigned long long multiplyU128(unsigned long long a, unsigned long long b, unsigned long long* high)
{
return _umul128(a, b, high);
}
#elif defined(_M_IX86)
int interlockedAddLarge(long long *target, int value)
{
return _InterlockedAddLargeStatistic(target, value);
}
#elif defined(_M_ARM64)
unsigned long long multiplyUHigh64(unsigned long long a, unsigned long long b)
{
return __umulh(a, b);
}
#elif defined(_M_ARM)
void dmb(void)
{
__dmb(11);
}
#endif

int main(void)
{
__assume(1);
return 0;
}
2 changes: 2 additions & 0 deletions druntime/mak/COPY
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
COPY=\
$(IMPDIR)\object.d \
$(IMPDIR)\__importc_builtins.di \
$(IMPDIR)\__builtins_msvc.d \
$(IMPDIR)\importc.h \
$(IMPDIR)\include\importc_msvc_builtins.h \
\
$(IMPDIR)\core\gc\config.d \
$(IMPDIR)\core\gc\gcinterface.d \
Expand Down
Loading
Loading