Author Topic: GCC libquadmath  (Read 839 times)

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
GCC libquadmath
« on: July 21, 2017, 06:42:35 PM »
Anybody able to compile that without errors?

Code: [Select]
#include <conio.h>
#include <C:\MinGW\lib\gcc\mingw32\4.8.1\include\quadmath.h>
// OPT_Linker C:\MinGW\lib\gcc\mingw32\4.8.1\libquadmath.a

int main ()
{
  __float128 r;

  r = strtoflt128("1.2345678", NULL); // undefined reference to `strtoflt128'
  r = 123.456; // OK

  _getch();
}

See How to output 128 bits to the screen?

GoneFishing

  • Member
  • ****
  • Posts: 950
  • Gone fishing
Re: GCC libquadmath
« Reply #1 on: July 21, 2017, 08:55:04 PM »
Hi Johen,

I was able to compile this on Ubuntu 14.04 :

Code: [Select]
#include <stdio.h>
#include <quadmath.h>
// gcc ./quadmath.c  -o quadmath -lquadmath

int main ()
{
  __float128 r;

  r = strtoflt128("1.2345678", NULL); // undefined reference to `strtoflt128'
  r = 123.456; // OK

  getchar();
}

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #2 on: July 21, 2017, 09:24:55 PM »
Thanks :icon14:
No luck on Windows, though.

TWell

  • Member
  • ****
  • Posts: 748
Re: GCC libquadmath
« Reply #3 on: July 21, 2017, 10:46:27 PM »
Code: [Select]
#include <stdio.h>
#include <quadmath.h>
// gcc ./quadmath.c  -o quadmath -lquadmath
// gcc quadmath.c -o quadmath -Wl,-Bstatic -lquadmath

int main ()
{
  __float128 r;
  char buf[128];

  r = strtoflt128("1.2345678", NULL); // undefined reference to `strtoflt128'
  r = 123.456; // OK
//  quadmath_snprintf (buf, sizeof buf, "%Qa", r);
  quadmath_snprintf (buf, sizeof buf, "%Qf\n", r);
  printf(buf);
  getchar();
  return 0;
}
Code: [Select]
123.456000

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #4 on: July 21, 2017, 10:58:51 PM »
Thanks, Tim, and congrats :icon_mrgreen:

So are these your linker options?

gcc quadmath.c -o quadmath -Wl,-Bstatic -lquadmath

My results:
Code: [Select]
C:\TDM-GCC-32\bin\gcc.exe -Wl,-Bstatic -lquadmath -o tmp.exe "Tmp.cpp"
Code: [Select]
C:\Users\Jochen\AppData\Local\Temp\cceeec7X.o:Tmp.cpp:(.text+0x29): undefined reference to `strtoflt128'
C:\Users\Jochen\AppData\Local\Temp\cceeec7X.o:Tmp.cpp:(.text+0xc9): undefined reference to `quadmath_snprintf'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/4.9.2/../../../../mingw32/bin/ld.exe: C:\Users\Jochen\AppData\Local\Temp\cceeec7X.o: bad reloc address 0x7 in section `.text$getchar[_getchar]'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/4.9.2/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status

If I remove the comma (-Wl -Bstatic), it tells me unrecognized command line option '-Wl', so I assume the comma has a meaning.

My installation is less than three years old. Most of the time C/C++ code compiles and runs fine, but this one gives me the creeps :(

C:\MinGW\mingw32\lib\gcc\mingw32\4.8.1\libquadmath.a 570236 bytes, 5.10.2013
C:\MinGW\mingw32\lib\gcc\mingw32\4.8.1\include\quadmath.h 9030 bytes, 5.10.2013

P.S.: I love passing hours and hours on the Internet watching how others despair :t

But in the end, own trial and error may advance humanity more quickly :biggrin:
Code: [Select]
#include <stdio.h>
#include <quadmath.h>
// gcc ./quadmath.c  -o quadmath -lquadmath
// gcc quadmath.c -o quadmath
// OxPT_Linker -Wl,-Bstatic -lquadmath
// OxPT_Linker -Wl,-Bdynamic -lquadmath
// OxPT_Linker -Wl,-Bstatic "C:\MinGW\mingw32\lib\gcc\mingw32\4.8.1\libquadmath.a"
// OxPT_Linker -Wl,-Bdynamic C:\TDM-GCC-32\bin\libquadmath-0.dll
// OPT_Linker C:\TDM-GCC-32\bin\libquadmath-0.dll ; HEY, THIS ONE WORKS!!!!
int main ()
{
  __float128 r;
  char buf[128];
  for (int i=0;i<128;i++) buf[i]=0;
  // __asm("int $3");
  r = strtoflt128("1.2345678", NULL); // undefined reference to `strtoflt128'
  // __asm("nop");
  // r = 123.456; // OK
  quadmath_snprintf (buf, sizeof buf, "%Qa", r);
  quadmath_snprintf (buf, sizeof buf, "%Qf\n", r);
  printf("Buffer: [%s]", buf);
  getchar();
  return 0;
}

Output: Buffer: [0x1.3c0ca2a5b1d5d0818d3359c99ff2p+0]

Not yet the expected result, but since I've seen some similar results in desperate posts on the web (e.g. That code produced -3.8518598887744717061119558851698546e-34 error on my box), it can only be a question of weeks until I find the magic trick :icon_mrgreen:
« Last Edit: July 22, 2017, 12:05:34 AM by jj2007 »

qWord

  • Member
  • *****
  • Posts: 1454
  • The base type of a type is the type itself
    • SmplMath macros
Re: GCC libquadmath
« Reply #5 on: July 22, 2017, 12:08:20 AM »
The order of modules and libraries must match the dependency order:
-l library
    [...]
    It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded.

Conclusion: put -lquadmath to the end.
Also note that gcc use the file extension to get the language and c++ is maybe not what you want in general.
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #6 on: July 22, 2017, 12:28:00 AM »
Miracles happen :greenclp:
Code: [Select]
#include <stdio.h> // HEY, THIS ONE WORKS!!!!
#include <quadmath.h> // OPT_Linker C:\TDM-GCC-32\bin\libquadmath-0.dll
int main ()
{
  char buf[128];
  __float128 r = strtoflt128("1234567890.123456789012345678901234567890", NULL);
  quadmath_snprintf (buf, sizeof buf, "%#*.40Qe", 30, r);
  printf("expected:\t[1.2345678901234567890123456789012345678901e+09]\n", buf);
  printf("result:  \t[%s]\n", buf);
  getchar();
  return 0;
}
// Output
// expected:       [1.2345678901234567890123456789012345678901e+09]
// result:         [1.2345678901234567890123456789012345331810e+09]

@qWord: Thanks, your suggestion to put -lquadmath as last option works, too :t

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #7 on: July 29, 2017, 01:09:14 AM »
Work in progress:

  PrintLine "Two numbers: ", CrLf$, Quad$(numSmall), " and ", CrLf$, Quad$(numBig)
  Inkey Quad$(QuadMath(fminq, numSmall, numBig)), " is the smaller one"


Code: [Select]
Two numbers:
1.2345678901234567890294135408477e+40 and
1.2345678901234567891474727029195e+40
1.2345678901234567890294135408477e+40 is the smaller one

The interface works, but there is a big problem: simple arithmetics like adding and multiplying numbers :(

jack

  • Regular Member
  • *
  • Posts: 14
Re: GCC libquadmath
« Reply #8 on: July 30, 2017, 08:28:17 PM »
I found two symbols that have add in it: ___quadmath_mpn_addmul_1 and ___quadmath_mpn_add_n
for subtract: ___quadmath_mpn_submul_1 and ___quadmath_mpn_sub_n
for divide: ___quadmath_mpn_divrem
for multiply: ___quadmath_mpn_mul_1, ___quadmath_mpn_impn_mul_n_basecase, ___quadmath_mpn_impn_mul_n and ___quadmath_mpn_mul

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #9 on: July 30, 2017, 09:27:02 PM »
Thanks, Jack :t

There are quite a number of them:
Code: [Select]
__quadmath_do_pad
__quadmath_fpioconst_pow10
__quadmath_isinf_nsq
__quadmath_kernel_cosq
__quadmath_kernel_sincosq
__quadmath_kernel_sinq
__quadmath_mpn_add_n
__quadmath_mpn_addmul_1
__quadmath_mpn_cmp
__quadmath_mpn_construct_float128
__quadmath_mpn_divrem
__quadmath_mpn_extract_flt128
__quadmath_mpn_impn_mul_n
__quadmath_mpn_impn_mul_n_basecase
__quadmath_mpn_lshift
__quadmath_mpn_mul
__quadmath_mpn_mul_1
__quadmath_mpn_rshift
__quadmath_mpn_sub_n
__quadmath_mpn_submul_1
__quadmath_printf_fp
__quadmath_printf_fphex
__quadmath_rem_pio2q
__quadmath_tens
__quadmath_tens_in_limb
__quadmath_x2y2m1q

Problem is that they are not documented. There is a doc on Low-level Functions, but it concerns general GCC functions.

It would be great if we could decipher them, i.e. find out which paras they expect, and how they are passed. So far I have been successful with quite a number of the documented functions, and added conversion REAL10 <---> REAL16, printing etc:

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals REAL16:quadPI
  Init quad
  PrintLine "real PI:", Tb$, "3.14159265358979323846264338327950"
  MovVal quadPI, "3.14159265358979323846264338327950"   ; string to REAL16
  PrintLine "quadPI=   ", Tb$, Quad$(quadPI)
  FpuPush quadPI                        ; REAL16 -> REAL10
  PrintLine "FpuPush=", Tb$, Str$(ST(0)v)
  fldpi                                 ; same with built-in FPU opcode
  Inkey "fldpi  =", Tb$, Str$(ST(0)v)
EndOfCode


Output:
Code: [Select]
real PI:        3.14159265358979323846264338327950
quadPI=         3.14159265358979323846264338327950e+00
FpuPush=        3.141592653589793238
fldpi  =        3.141592653589793238

When the package is ready, I'll update the MovVal and FpuPush documentation asap.

qWord

  • Member
  • *****
  • Posts: 1454
  • The base type of a type is the type itself
    • SmplMath macros
Re: GCC libquadmath
« Reply #10 on: July 30, 2017, 10:01:50 PM »
The __float128-type is build-in thus the common operators can be used. Write your own functions to make the basic arithmetic available as lib.
MREAL macros - when you need floating point arithmetic while assembling!

jack

  • Regular Member
  • *
  • Posts: 14
Re: GCC libquadmath
« Reply #11 on: July 30, 2017, 10:17:02 PM »
jj2007, may I suggest you try the C explorer at https://godbolt.org
choose gcc as the compiler with compiler option -O3 and paste the following C code
Code: [Select]
#include <quadmath.h>
#include <stdlib.h>
#include <stdio.h>

int main ()
{
  __float128 a, b, r;
  char buf[128];
 
  printf("enter first 128-bit float ");
  scanf("%s", buf);
  a = strtoflt128 (buf, NULL);
  printf("enter second 128-bit float ");
  scanf("%s", buf);
  b = strtoflt128 (buf, NULL);
  r=a+b;
  quadmath_snprintf (buf, sizeof buf, "%+-#46.*Qe", r);
  return 0;
}
you will see that it calls __addtf3, which is part of libgcc, see https://github.com/gcc-mirror/gcc/tree/master/libgcc/soft-fp

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #12 on: July 31, 2017, 12:42:50 AM »
you will see that it calls __addtf3, which is part of libgcc, see https://github.com/gcc-mirror/gcc/tree/master/libgcc/soft-fp

Yep, that does the trick, thanks a lot :t

@qword: "Write your own functions"?

nidud

  • Member
  • *****
  • Posts: 1371
    • https://github.com/nidud/asmc
Re: GCC libquadmath
« Reply #13 on: July 31, 2017, 02:30:42 AM »
@qword: "Write your own functions"?

The FPU handles up to REAL10.

Floats above must be emulated.

qWord

  • Member
  • *****
  • Posts: 1454
  • The base type of a type is the type itself
    • SmplMath macros
Re: GCC libquadmath
« Reply #14 on: July 31, 2017, 03:41:02 AM »
e.g.

void myAdd(__float128 *const r, __float128 const *const a, __float128 const *const b) { *r = *a + *b; }

Has the advantage to rely only on GCC's public interface.
MREAL macros - when you need floating point arithmetic while assembling!