Pelles C forum

C language => Expert questions => Topic started by: Akko on May 24, 2023, 12:21:06 AM

Title: 128-bit intrinsic math buggy?
Post by: Akko on May 24, 2023, 12:21:06 AM
The following code works in MSVC (64-bit) but I cannot make it run in PC12 (64-bit console):

// Intrinsic 128-bit multiplication/division test

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <intrin.h>

int main(void) {
   uint64_t upl,uph,uq,ur=7;
   upl=_umul128(-1,2,&uph);
   printf("\nuph=1?%d upl=-2?%d",(int)uph,(int)upl);
   uq=_udiv128(uph,upl,2,&ur);
   printf("\nuq=-1?%d ur=0?%d",(int)uq,(int)ur);
   return 0;
}

I tried /Ze compiler flags et cetera, but PC12 always struggles with the division  :-(
Multiplication is no issue.
Title: Re: 128-bit intrinsic math buggy?
Post by: frankie on May 26, 2023, 11:49:40 PM
It seems that for the functions _umul128() and _udiv128() the compiler don't emits the intrinsic code, but emits a call to the specific function that, obviously, is missing (doesn't exist in any library).
For me is a compiler bug.
Title: Re: 128-bit intrinsic math buggy?
Post by: Pelle on May 27, 2023, 01:12:52 PM
Confirmed.

The compiler internal intrinsic signature for __udiv128 (and _udiv128 if you insist on using the /Ze option) contains (signed) __int64 while the externally visible signature contains (the correct) unsigned __int64. The signatures will never match, so you get the default behavior of calling an external function.

AFAICT this has been broken since __udiv128 and _udiv128 were introduced in version 10 (you guys did a poor job of testing...  :P). With version 12 being done, this will be fixed in some possible future version.
Title: Re: 128-bit intrinsic math buggy?
Post by: frankie on May 27, 2023, 04:00:40 PM
Confirmed.
....

AFAICT this has been broken since __udiv128 and _udiv128 were introduced in version 10 (you guys did a poor job of testing...  :P).
LOL ;D :D ;D :D ;D :D ;D :D ;D

Of course you're absolutely right Pelle.   ;)
Title: Re: 128-bit intrinsic math buggy?
Post by: Akko on May 27, 2023, 11:54:41 PM
AFAICT also clang has/had similar difficulties with compiling (u)int128_t intrinsics.
Here clang lags behind gcc that has working builtins since long.

I can understand why Pelles C does not support a 64-bit assembler, but for such cases
it would be nice to have one. Long division (eg shift-subtract) in C is painfully slow.   
Title: Re: 128-bit intrinsic math buggy?
Post by: Pelle on May 28, 2023, 10:59:59 AM
As explained in the help file ("Appendix" : "The inline assembler for X64"), mixing inline assembly and C code in the same function is a bad idea. When creating a whole function using inline assembly, it shouldn't be too hard moving this code to a separate file and use POASM. If problems, ask and someone in this forum will surely help you.
Title: Re: 128-bit intrinsic math buggy?
Post by: Akko on June 05, 2023, 08:42:52 AM
The signed _mul128 intrinsic is buggy too. Perhaps the similar problem as with _udiv128 ...

Test code (ph should be 0):

// Intrinsic 128-bit multiplication test

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <intrin.h>

int main(void) {
   int64_t ph=-7, pl=7;
   pl=_mul128((int64_t)-3,(int64_t)-3,&ph);
   printf("\npl=9?%d ph=0?%d",(int)pl,(int)ph);
   return 0;
}