On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
>
- 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 <intrin.h>
and contains an actual function for each missing intrinsic; e.g. for the missing __shiftright128 it has
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.
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
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 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?