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 <intrin.h>` 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?

Reply via email to