Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement some of MSVC's intrinsics, for ImportC. #16372

Draft
wants to merge 77 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
ecbba93
Add files for MSVC intrinsic implementations.
just-harry Apr 12, 2024
24aa28a
Scaffold some versions for the MSVC intrinsic implementations.
just-harry Apr 12, 2024
43dd036
Implement the MSVC intrinsics for extended-width multiplication.
just-harry Apr 12, 2024
60166f2
Implement the MSVC intrinsics for extended-width division.
just-harry Apr 12, 2024
b6492f5
Implement the MSVC intrinsics for the x86 `cpuid` instruction.
just-harry Apr 12, 2024
f4b3f66
Define `gccBuiltins` privately for the MSVC intrinsic implementations.
just-harry Apr 12, 2024
4c65293
Implement the MSVC intrinsics for fast float conversion.
just-harry Apr 12, 2024
e38fd2e
Implement the MSVC intrinsics for fast double conversion.
just-harry Apr 12, 2024
5f74909
Implement the MSVC intrinsics for saturating float conversion.
just-harry Apr 12, 2024
f7b5f6b
Implement the MSVC intrinsics for saturating double conversion.
just-harry Apr 12, 2024
4234335
Implement the MSVC intrinsics for sentinel-on-invalid float conversion.
just-harry Apr 12, 2024
8b7146d
Implement the MSVC intrinsics for sentinel-on-invalid double conversion.
just-harry Apr 12, 2024
77320e2
Implement the `__halt` MSVC intrinsic.
just-harry Apr 12, 2024
bc3bd9c
Implement the `<op><g/f>s<size>` MSVC intrinsics.
just-harry Apr 12, 2024
a93f5e7
Implement the `__debugbreak` MSVC intrinsic.
just-harry Apr 12, 2024
a296b5d
Implement the `__fastfail` MSVC intrinsic.
just-harry Apr 12, 2024
b093f81
Implement the `__faststorefence` MSVC intrinsic.
just-harry Apr 12, 2024
ab099a1
Implement the `_disable` MSVC intrinsic.
just-harry Apr 12, 2024
1080ba4
Implement the `_enable` MSVC intrinsic.
just-harry Apr 12, 2024
dd6fba8
Implement the `_mm_pause` MSVC intrinsic.
just-harry Apr 19, 2024
dcf6a68
Implement the MSVC intrinsics for ARM memory barriers.
just-harry Apr 21, 2024
66f81a0
Implement the MSVC intrinsics for interlocked additions.
just-harry Apr 12, 2024
0aaa7e2
Implement the MSVC intrinsics for interlocked and-ing.
just-harry Apr 12, 2024
a11d4d4
Implement the MSVC intrinsics for interlocked bit-test-and-resets.
just-harry Apr 12, 2024
2000ddb
Implement the MSVC intrinsics for interlocked bit-test-and-sets.
just-harry Apr 12, 2024
bf21b2f
Implement the MSVC intrinsics for interlocked compare-and-exchanges.
just-harry Apr 12, 2024
4b837c0
Implement the MSVC intrinsics for 128-bit interlocked compare-and-exc…
just-harry Apr 12, 2024
4f570b6
Implement the MSVC intrinsics for interlocked pointer compare-and-exc…
just-harry Apr 12, 2024
df4671d
Implement the MSVC intrinsics for interlocked decrements.
just-harry Apr 12, 2024
56477ff
Implement the MSVC intrinsics for interlocked exchanges.
just-harry Apr 12, 2024
9fae166
Implement the MSVC intrinsics for interlocked exchange-additions.
just-harry Apr 12, 2024
6dc78ba
Implement the MSVC intrinsics for interlocked pointer exchanges.
just-harry Apr 12, 2024
963dc18
Implement the MSVC intrinsics for interlocked increments.
just-harry Apr 12, 2024
dff65ce
Implement the MSVC intrinsics for interlocked or-ing.
just-harry Apr 12, 2024
f639225
Implement the MSVC intrinsics for interlocked xor-ing.
just-harry Apr 12, 2024
ba0258c
Implement the MSVC intrinsics for x86 I/O port handling.
just-harry Apr 12, 2024
b171362
Implement the `__int2c` MSVC intrinsic.
just-harry Apr 12, 2024
9a07e14
Implement the `__invlpg` MSVC intrinsic.
just-harry Apr 12, 2024
e2430b7
Implement the `__lidt` MSVC intrinsic.
just-harry Apr 12, 2024
9239dcf
Implement the MSVC intrinsics for 64-bit bit-shifts.
just-harry Apr 12, 2024
057dafd
Implement the MSVC intrinsics for `lzcnt`.
just-harry Apr 12, 2024
a110bba
Implement the MSVC intrinsics for SSE float<->integer conversion.
just-harry Apr 12, 2024
7fa4f3a
Implement the MSVC intrinsics for `tzcnt`.
just-harry Apr 21, 2024
ee52a5a
Implement the MSVC intrinsics for some SSE4a instructions.
just-harry Apr 12, 2024
78b5f16
Implement the `_mm_stream_si64x` MSVC intrinsic.
just-harry Apr 12, 2024
b06915b
Implement the MSVC intrinsics for the x86 `rep movs` instruction.
just-harry Apr 12, 2024
f8ecf6a
Implement the `__noop` MSVC intrinsic.
just-harry Apr 12, 2024
5238c1e
Implement the `__nop` MSVC intrinsic.
just-harry Apr 12, 2024
1fae0ea
Implement the MSVC intrinsics for `popcnt`.
just-harry Apr 12, 2024
5d03c5e
Implement the MSVC intrinsics for the x86 `rdtsc` instructions.
just-harry Apr 12, 2024
8f8c848
Implement the `__readcr<number>` MSVC intrinsics.
just-harry Apr 12, 2024
044234e
Implement the `__readdr` MSVC intrinsic.
just-harry Apr 12, 2024
3d08c2b
Implement the `__readeflags` MSVC intrinsic.
just-harry Apr 12, 2024
5c492d3
Implement the `__readmsr` MSVC intrinsic.
just-harry Apr 12, 2024
dd712e4
Implement the `__readpmc` MSVC intrinsic.
just-harry Apr 12, 2024
f94b260
Implement the `__segmentlimit` MSVC intrinsic.
just-harry Apr 12, 2024
ae65093
Implement the MSVC intrinsics for 128-bit bit-shifts.
just-harry Apr 12, 2024
5654b47
Implement the `__sidt` MSVC intrinsic.
just-harry Apr 12, 2024
e3570d4
Implement the MSVC intrinsics for the x86 `rep stos` instruction.
just-harry Apr 12, 2024
6b44396
Implement the MSVC intrinsics for the AMD x86 SVM instruction set.
just-harry Apr 12, 2024
8922844
Implement the `__ud2` MSVC intrinsic.
just-harry Apr 12, 2024
b3c5b9e
Implement the MSVC intrinsics for the Intel x86 VMX instruction set.
just-harry Apr 12, 2024
e5a1064
Implement the `__wbinvd` MSVC intrinsic.
just-harry Apr 12, 2024
5d7eab9
Implement the `__writecr<number>` MSVC intrinsics.
just-harry Apr 12, 2024
72b72f0
Implement the `__writedr` MSVC intrinsic.
just-harry Apr 12, 2024
f0be56a
Implement the `__writeeflags` MSVC intrinsic.
just-harry Apr 12, 2024
d8c3ff1
Implement the `__writemsr` MSVC intrinsic.
just-harry Apr 12, 2024
68cde5f
Implement the MSVC intrinsics for non-atomic read/write barriers.
just-harry Apr 12, 2024
22dfc7b
Implement the MSVC intrinsics for bit-scanning.
just-harry Apr 12, 2024
72200e1
Implement the MSVC intrinsics for bit-test operations.
just-harry Apr 12, 2024
7057097
Implement the MSVC intrinsics for byte-swapping.
just-harry Apr 12, 2024
761cf9e
Implement the MSVC intrinsics for bit-rotation.
just-harry Apr 12, 2024
9b1ab22
Implement the `__assume` MSVC intrinsic.
just-harry Apr 13, 2024
356c06e
Implement the `__yield` MSVC intrinsic.
just-harry Apr 19, 2024
158fb52
Add a test for checking that MSVC intrinsics are actually available f…
just-harry Apr 21, 2024
4e8a34b
Pass `<path>/importc.h/../include` to the C preprocessor as an includ…
just-harry Apr 23, 2024
045fe87
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
4 changes: 4 additions & 0 deletions changelog/druntime.importc-initial-msvc-intrinsics.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ImportC implements all but three of the MSVC 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), and a handful of undocumented intrinsics.

ImportC now implements all but three of the MSVC 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), and a handful of undocumented intrinsics.
The MSVC intrinsics are available when targeting the Microsoft C runtime (that is, when the `CRuntime_Microsoft` version identifier is defined).
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, ref const Loc loc, ref OutBuffer defi
//printf("preprocess %s\n", csrcfile.toChars());
version (runPreprocessor)
{
const includePath = FileName.replaceName(toDString(importc_h), "include");
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);
FileName.free(includePath.ptr);
if (status)
fatal();
return text;
Expand Down
18 changes: 17 additions & 1 deletion compiler/src/dmd/link.d
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,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 @@ -948,7 +949,7 @@ public int runProgram(const char[] exefile, const char*[] runargs, bool verbose,
* Returns:
* error status, 0 for success
*/
public int runPreprocessor(ref const Loc loc, const(char)[] cpp, const(char)[] filename, const(char)* importc_h, ref Array!(const(char)*) cppswitches,
public int runPreprocessor(ref const 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 @@ -994,6 +995,14 @@ public int runPreprocessor(ref const Loc loc, const(char)[] cpp, const(char)[] f
buf.printf(" /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.write(" /I");
buf.write(includePath);
}

/* Append preprocessor switches to command line
*/
foreach (a; cppswitches)
Expand Down Expand Up @@ -1159,6 +1168,13 @@ public int runPreprocessor(ref const Loc loc, const(char)[] cpp, const(char)[] f
// 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 @@
// LINK(windows):
// REQUIRED_ARGS: -os=windows
// PERMUTE_ARGS: -betterC -i
// 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

// Just so the linker doesn't complain.
int main(void)
{
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