News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

GCC libquadmath

Started by jj2007, July 21, 2017, 06:42:35 PM

Previous topic - Next topic

jj2007

Anybody able to compile that without errors?

#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

Hi Johen,

I was able to compile this on Ubuntu 14.04 :


#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

Thanks :icon14:
No luck on Windows, though.

TWell

#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;
}
123.456000

jj2007

#4
Thanks, Tim, and congrats :icon_mrgreen:

So are these your linker options?

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

My results:
C:\TDM-GCC-32\bin\gcc.exe -Wl,-Bstatic -lquadmath -o tmp.exe "Tmp.cpp"
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:#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:

qWord

The order of modules and libraries must match the dependency order:
Quote from: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html-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

Miracles happen :greenclp:
#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

Work in progress:

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


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

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

Thanks, Jack :t

There are quite a number of them:__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:
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

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

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

#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

Quote from: jack on July 30, 2017, 10:17:02 PMyou 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

#13
deleted

qWord

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!