Author Topic: GCC libquadmath  (Read 824 times)

jj2007

  • Member
  • *****
  • Posts: 7553
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #15 on: July 31, 2017, 04:56:15 AM »
The FPU handles up to REAL10.

Floats above must be emulated.

Compliments, you read the manual :t

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

Good. Now the same from assembler, and we can have some fun :biggrin:

Attached the beta version, MasmBasic version 1 August is needed to build this example:

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals REAL16 quadPI, Num1, Num2
  Init quad
  PrintLine "real PI:", Tb$, "3.14159265358979323846264338327950"
  MovVal quadPI, "3.1415926535897932384626433832795028841971"   ; string to REAL16
  PrintLine "quadPI=   ", Tb$, Quad$(quadPI)
  FpuPush quadPI                        ; REAL16 -> REAL10
  PrintLine Str$("FpuPush=\t%Jf", ST(0)v)
  fldpi                                 ; same with built-in FPU opcode
  PrintLine Str$("fldpi  =\t%Jf", ST(0)v)
  MovVal Num1, "1.234567890123456789012345678901234567890"      ; string to REAL16
  MovVal Num2, "2.222222222222222222222222222222222222222"      ; string to REAL16
  PrintLine "Num1=", Tb$, Tb$, Quad$(Num1)
  PrintLine "Num2=", Tb$, Tb$, Quad$(Num2)
  PrintLine "Num1+Num2=", Tb$, Quad$(QuadMath(__addtf3, Num1, Num2))
  PrintLine "Num1-Num2=", Tb$, Quad$(QuadMath(__subtf3, Num1, Num2))
  PrintLine "Num1*Num2=", Tb$, Quad$(QuadMath(__multf3, Num1, Num2))
  Inkey "Num1/Num2=", Tb$, Quad$(QuadMath(__divtf3, Num1, Num2))
EndOfCode


Output:
Code: [Select]
real PI:        3.14159265358979323846264338327950
quadPI=         3.14159265358979323846264338327950e+00
FpuPush=        3.141592653589793238
fldpi  =        3.141592653589793238
Num1=           1.23456789012345678901234567890123e+00
Num2=           2.22222222222222222222222222222222e+00
Num1+Num2=      3.45679011234567901123456790112346e+00
Num1-Num2=      -9.87654332098765433209876543320988e-01
Num1*Num2=      2.74348420027434842002743484200274e+00
Num1/Num2=      5.55555550555555555055555555505556e-01

As mentioned earlier, it needs C:\TDM-GCC-32\bin\libquadmath-0.dll

If your GCC is elsewhere, use ...
Code: [Select]
QuadLib$ equ <yourpath\bin\libquadmath-0>
GccLib$ equ <yourpath\bin\libgcc_s_dw2-1>

... shortly before Init.
« Last Edit: August 01, 2017, 09:40:37 AM by jj2007 »

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: GCC libquadmath
« Reply #16 on: July 31, 2017, 05:46:17 AM »
Compliments, you read the manual :t

 :biggrin:

Yep, I do.

These EMU functions are called by the C compilers so they need to be supplied by the library.

What qword was hinting (I assume) was that if you write the emulation yourself you don't need to use the GCC-libs.

jj2007

  • Member
  • *****
  • Posts: 7553
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #17 on: July 31, 2017, 06:41:53 AM »
if you write the emulation yourself you don't need to use the GCC-libs.

Sure, but why reinvent the wheel if GCC has already 100 REAL16 functions? Many people have a GCC installation anyway, and it works just fine. Why should an assembler programmer not use the wealth of libraries that are the only real advantage of C/C++?

I attach an update of the Printing a sinus via the FPU, the CRT, the GSL, and Python source. Requires Python 3, the Gnu Scientific Library, and GCC QuadMath.

Code: [Select]
Printing the sinus of 3.0 in various languages:
Sinus(3)= 0.1411200080598672    Python 3.4.3
Sinus(3)= 0.1411200080598672135 GSL, global var
Sinus(3)= 0.1411200080598672135 GSL, immediate
Sinus(3)= 0.1411200080598672135 CRT, global var
Sinus(3)= 0.1411200080598672135 CRT, immediate
Sinus(3)= 0.1411200080598672221 Assembler/Fpu
Sinus(3)= 0.14112000805986722210074480280811      QuadMath
Exact:    0.1411200080598672221007448028081103... Wolfram Alpha

EDIT:
What qword was hinting (I assume) was that if you write the emulation yourself you don't need to use the GCC-libs.

Reading his post again, it seems he means we could write a DLL or LIB in GCC that exports the 128 bit arithmetic functions. Not a bad idea, actually:
+: no GCC installation needed
-: but the DLL or LIB would bloat the MB package beyond this forum's 512k limit ;)

EDIT(2): On Win10, Python may not run properly. If it hangs, press Ctrl C.
« Last Edit: August 01, 2017, 09:42:21 AM by jj2007 »

jack

  • Regular Member
  • *
  • Posts: 14
Re: GCC libquadmath
« Reply #18 on: August 01, 2017, 05:53:29 AM »
hello jj2007
I am trying to use the function __addtf3 in FreeBasic but the result is wrong, how do you call the function in asm?

jj2007

  • Member
  • *****
  • Posts: 7553
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #19 on: August 01, 2017, 06:03:30 AM »
Put an int 3 and launch olly. Check what happens in qmP proc. Can't do more now, no access to my computer.

In version 1 August 17 of MasmBasic, the QuadMath interface is now implemented. To test it, click in RichMasm File/New Masm source, then QuadMath in the lower left corner.
« Last Edit: August 01, 2017, 09:49:04 AM by jj2007 »

jj2007

  • Member
  • *****
  • Posts: 7553
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #20 on: August 03, 2017, 09:12:23 AM »
Minor bugfix in version 3 August, details here.

jj2007

  • Member
  • *****
  • Posts: 7553
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC libquadmath
« Reply #21 on: August 05, 2017, 02:51:02 AM »
A QuadMath array demo:

include \masm32\MasmBasic\MasmBasic.inc     ; download
  Init quad
  PrintCpu 0
  NanoTimer()
  Dim MyQ() As REAL16               ; ** demo showing how to use a float128 array **
  Loops=1000000                     ; create one Million elements
  For_ ecx=0 To Loops-1
        push Rand64()               ; returns eax
        push edx                    ; and edx
        movlps xmm0, qword ptr stack
        void Str$("%Jf", xmm0)      ; assign a random value
        ; deb 10, "ct", ecx, $eax   ; activate to debug the first 10 iterations
        MovVal MyQ(ecx), eax        ; string to quad
        add esp, QWORD              ; correct the stack
        ; no good: MovVal MyQ(ecx), Str$("%Jf", number)  ; chokes
  Next
  Print Str$("%i ms for creating one Million array elements\n", NanoTimer(ms))
  ; not possible: ArraySort MyQ()    sorry but sorting quads is not implemented!

  PrintLine "digits", Tb$, "1.234567890123456789012"
  For_ ecx=0 To 9
        PrintLine Str$("%i\t", ecx), Quad$(MyQ(ecx), "%*.32Qg", 24)         ; see doc on format
  Next

  Inkey "-- hit any key --"
EndOfCode


Output:
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
657 ms for creating one Million array elements
digits  1.234567890123456789012
0      8334395503510177650.000
1      1329069443230085730.000
2      2521605505399485735.000
3      -2513648910981773731.00
4      -6348034448820748366.00
5      -3307815091408750516.00
6      4066175164584430395.000
7      -3922227355712582401.00
8      428641309453789440.0000
9      -8910786329316853516.00

Instead of fumbling the stack, this works, too:

                void Rand64()               ; create a random value
                void Str$("%Jf", edx::eax)  ; convert to a string
                MovVal MyQ(ecx), eax        ; convert to a float128