On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
2. C code referring to MSVC-specific compiler intrinsics. At
least InterlockedExchangeAdd, InterlockedExchangeAdd64 and
_stosb are such intrinsics. This is harder to resolve. There
are two ways forward here: either implement a shim function
that replicates the intrinsic's functionality if possible or
add support for these intrinsics to DMD.
Thanks for the explanation, on the strength of which I found a
way to deal with this correctly.
I made `intrinsics1.c` that has `#include ` and
contains an actual function for each missing intrinsic; e.g. for
the missing __shiftright128 it has
```C
unsigned __int64 D__shiftright128(
unsigned __int64 LowPart,
unsigned __int64 HighPart,
unsigned char Shift
)
{ return __shiftright128(LowPart, HighPart, Shift); }
```
where I got the prototypes from this [list of
intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/alphabetical-listing-of-intrinsic-functions?view=msvc-170).
Compiling this with MSVC `cl -c intrinsics1.c` produces a COFF
object `intrinsics1.obj` containing an actual function to link to
for each intrinsic. So this stage writes the code so we don't
have to.
As a matter of necessity, the names of the functions in
`intrinsics1.c` representing the MSVC intrinsics are not the same
as their actual names. By my convention above they are prefixed
with "D". Now we could simply write an extern(C) D function in a
module say `vcintrinsics.d`, that has exactly the intrinsic's
name, and calls the "D" prefixed function linked from
`intrinsics1.obj`, e.g. for the above example `vcintrinsics.d`
could contain
```D
extern(C):
extern ulong D__shiftright128(ulong LowPart, ulong HighPart,
ubyte Shift);
ulong __shiftright128(ulong LowPart, ulong HighPart, ubyte Shift){
return D__shiftright128(LowPart, HighPart, Shift);
}
```
As DMD doesn't know of these intrinsics, it won't complain about
defining a function with exactly the same name as an intrinsic so
as to implement that intrinsic as an actual function, solving the
problem. `dmd -lib vcintrinsics.d intrinsics1.obj` then produces
a library that resolves the linkage issue.
An alternative not involving having two function calls to
implement an intrinsic is to compile `intrinsics1.c` with MSVC
into a DLL, and using a DEF file that renames the exports just
like part of the solution
[here](https://forum.dlang.org/post/ruupyklfkrvnjtker...@forum.dlang.org) make those functions available under their original names when linking to its import library.
A lot of both of the above is boilerplate and can be automated.
It would be even nicer if the MSVC tools could be persuaded to
proceed in a similar way with DEF file renaming when building a
static library, but I have not succeeded in making this happen.
Anyone?