Bug 24412 – No predefined version for 64bit ?!

Status
NEW
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-02-26T06:28:11Z
Last change time
2024-12-13T19:33:27Z
Assigned to
No Owner
Creator
Manu
Moved to GitHub: dmd#20406 →

Comments

Comment #0 by turkeyman — 2024-02-26T06:28:11Z
Surprisingly, I was looking for a version that identifies if the target arch is 64bit, and there's no such thing! I need to know if the target has 64bit registers and can perform 64bit arithmetic. It's surprising there's nothing that identifies this. Please add a new predefined version.
Comment #1 by dkorpel — 2024-02-26T17:56:56Z
The usual check for this is `static if (size_t.sizeof == 8)`.
Comment #2 by turkeyman — 2024-02-26T19:16:58Z
That would tell you if you have 64bit address space. Not the same thing.
Comment #3 by dkorpel — 2024-02-27T11:59:36Z
It usually is, so people tend to use it that way. Are you programming for the Nintendo 64 perhaps? :) I'm looking how other languages check for 64-bit registers, and in C, it seems like people also query sizes of pointer / integer types, or query a specific ISA (like x86-64): https://stackoverflow.com/a/33867847/8411666 So without precedence, the name could be something like 'D_64bitRegister' or 'D_64bitArithmetic'. But what do you want to do with this information exactly? Is this to provide your own alternative 64-bit emulation when there's no 'native' 64-bit math? Because that could be tricky: consider WebAssembly without wasm64. It has 32-bit pointers and 64-bit math instructions, but it's not an actual processor architecture: the speed depends on the execution environment, so would 'D_64bitRegister' be set in that case?
Comment #4 by turkeyman — 2024-02-27T12:38:59Z
> It usually is, so people tend to use it that way. But it's not actually the same thing, and people using it that way have likely written a bug... > Are you programming for the Nintendo 64 perhaps? :) I do have a lifetime of experience writing software for such 64bit systems with 32bit pointers. They are a real thing that exists. > [...] or query a specific ISA [...] Yes, in C++ we wrangle this information ourselves from whatever material the compiler makes available to determine the facts. Everyone has such a global header file that does this wrangling. I'm specifically looking to avoid that here. > Is this to provide your own alternative 64-bit emulation when there's no 'native' 64-bit math? Exactly; if there are no 64bit registers, it can be the case that some alternative algorithm is superior. There do exist algorithms that only work efficiently with 64bits. > [...] consider WebAssembly without wasm64 [...] would 'D_64bitRegister' be set in that case? Maybe not define it for webasm since 32bit machines can run web browsers too. I mean, you're running in a web browser; your concern about maximising architectural perf is already forfeit. It's difficult to imagine a case where this could be used where it's a compatibility issue; it's basically for optimisation opportunities, and nothing else.
Comment #5 by dkorpel — 2024-02-27T13:19:07Z
> It's difficult to imagine a case where this could be used where it's a compatibility issue; it's basically for optimisation opportunities, and nothing else. Since versions are usually about compatibility (i.e. `version(HasFeatureX) useFeatureX()`), perhaps it would be better to define a 'fast int' type in druntime, somewhat similar to C's `int_fast32_t` or `intmax_t`, but one that represents the largest integer type with native math instructions (excluding SIMD). That would also generalize better to 16 and 128 bit. Would that work?
Comment #6 by turkeyman — 2024-02-27T15:00:33Z
I think that's over-complicating it. Version is fine.
Comment #7 by bugzilla — 2024-03-26T04:46:02Z
https://dlang.org/spec/version.html Says: ``` D_LP64 Pointers are 64 bits (command line switch -m64). (Do not confuse this with C's LP64 model) D_X32 Pointers are 32 bits, but words are still 64 bits (x32 ABI) (This can be defined in parallel to X86_64) ``` What the implementation actually does is: ``` if (tgt.isX86_64) { VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86_64"); VersionCondition.addPredefinedGlobalIdent("X86_64"); } else { VersionCondition.addPredefinedGlobalIdent("D_InlineAsm"); //legacy VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86"); VersionCondition.addPredefinedGlobalIdent("X86"); } if (tgt.isLP64) VersionCondition.addPredefinedGlobalIdent("D_LP64"); else if (tgt.isX86_64) VersionCondition.addPredefinedGlobalIdent("X32"); ``` Note how something simple turned into a monstrosity that nobody can figure out, and the documentation is both wrong and incomplete. Sigh. I suspect that the undocumented X32 is what Manu is looking for, but dmd never generates it. Does gdc or ldc?
Comment #8 by ibuclaw — 2024-03-26T14:36:55Z
(In reply to Dennis from comment #1) > The usual check for this is `static if (size_t.sizeof == 8)`. `version(D_LP64)` would be a better alternative to that.
Comment #9 by ibuclaw — 2024-03-26T15:06:52Z
(In reply to Walter Bright from comment #7) > https://dlang.org/spec/version.html > > Says: > > ``` > D_LP64 Pointers are 64 bits (command line switch -m64). (Do not confuse > this with C's LP64 model) > D_X32 Pointers are 32 bits, but words are still 64 bits (x32 ABI) (This > can be defined in parallel to X86_64) > ``` Introduced by https://github.com/dlang/dlang.org/pull/175 As one comment pointed out: """ X32 is a specific implementation for x86-64 hardware, but the description refers to an abstract concept """ Adding "x32 ABI" was the compromise, but I don't think it's explicit enough. Pick any wiki, and the description is better: """ X32 is an alternative ABI for x86-64 that uses the full 64-bit x86-64 instruction and register set and 32-bit pointers and longs. """ https://sourceware.org/glibc/wiki/x32 """ The x32 ABI provides 32-bit integers, long and pointers (ILP32) on Intel and AMD 64-bit hardware """ https://en.wikipedia.org/wiki/X32_ABI > Note how something simple turned into a monstrosity that nobody can figure > out, and the documentation is both wrong and incomplete. Sigh. > > I suspect that the undocumented X32 is what Manu is looking for, but dmd > never generates it. Does gdc or ldc? That is a typo in dmd, introduced by https://github.com/dlang/dmd/pull/12508 D_X32 is predefined by gdc on X32 targets, itself is now a deprecated ABI of X86_64. I had and still have doubts that DMD would support such a `-target` anyway. A more informative version identifier for it would have been X86_64_X32, but this was added at a time where brevity was preferred over clarity for some reason. Which also left in the spec D_AVX and D_AVX2 (yuck!) instead of X86_64_AVX and X86_64_AVX2.
Comment #10 by ibuclaw — 2024-03-26T15:14:22Z
(In reply to Manu from comment #2) > That would tell you if you have 64bit address space. Not the same thing. ``` import gcc.builtins : ___builtin_machine_int; static if (__builtin_machine_int.sizeof == 8): ```
Comment #11 by bugzilla — 2024-03-27T00:51:57Z
Comment #12 by turkeyman — 2024-03-27T02:03:13Z
This issue is strictly about the arch, and pointer width/ABI matters is explicitly NOT what this request is about. The thing Iain shows: ``` import gcc.builtins : ___builtin_machine_int; static if (__builtin_machine_int.sizeof == 8): ``` This is what should be expressed by a standard version token present for all compilers/architectures. On the tangent regarding X32; it is deprecated for linux, but cross compilers will need to express this concept for all time. For my money, D_X32 should continue to exist, and the spec adjusted to require this constant for all targets where 32bit pointers are used on a 64bit arch, which would include the X32 ABI for X86, but also similar ABI's for other architectures too. It's not strictly necessary, because we can test size_t.sizeof, but since it's already there and removing it would be a breaking change, the spec could be slightly adjusted to make it generally useful.
Comment #13 by robert.schadek — 2024-12-13T19:33:27Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20406 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB