Author Topic: 64 bit and REAL10 values  (Read 8194 times)

Gunther

  • Member
  • *****
  • Posts: 3585
  • Forgive your enemies, but never forget their names
64 bit and REAL10 values
« on: September 23, 2012, 11:44:10 PM »
At the moment I've only running a 64 bit Linux system. In a few weeks I'll buy a new machine with, at least, Windows 7 (64 bit). So, what's the question. Is it possible to work with REAL10 values (long double) under 64 bit Windows? The libc of Microsoft Visual C doesn't support that data type.

Gunther
Get your facts first, and then you can distort them.

jj2007

  • Member
  • *****
  • Posts: 10445
  • Assembler is fun ;-)
    • MasmBasic
Re: 64 bit and REAL10 values
« Reply #1 on: September 24, 2012, 12:30:13 AM »
AFAIK with 32-bit code, the FPU remains "as is", so no problem. With 64-bit code, no idea.
Attention with xmm regs: perfectly working 32-bit code with SSE2 may mysteriously fail on a 64-bit OS because some XMMs are being trashed by Win API calls.

qWord

  • Member
  • *****
  • Posts: 1473
  • The base type of a type is the type itself
    • SmplMath macros
Re: 64 bit and REAL10 values
« Reply #2 on: September 24, 2012, 01:19:39 AM »
The FPU is still available for ring3 applications. As for x32, all FPU registers are volatile; the stack must be empty before calling functions.
MREAL macros - when you need floating point arithmetic while assembling!

Gunther

  • Member
  • *****
  • Posts: 3585
  • Forgive your enemies, but never forget their names
Re: 64 bit and REAL10 values
« Reply #3 on: September 24, 2012, 07:41:35 AM »
Hi qword,

The FPU is still available for ring3 applications. As for x32, all FPU registers are volatile; the stack must be empty before calling functions.

that's clear. But how is, for example, to print such a REAL 10 value? The printf doesn't work, because it uses the Windows libc.

Gunther
Get your facts first, and then you can distort them.

qWord

  • Member
  • *****
  • Posts: 1473
  • The base type of a type is the type itself
    • SmplMath macros
Re: 64 bit and REAL10 values
« Reply #4 on: September 24, 2012, 09:51:50 AM »
But how is, for example, to print such a REAL 10 value? The printf doesn't work, because it uses the Windows libc.
You need to roll your own or translate existing code (e.g. fpulib) - but maybe some has already done this...
MREAL macros - when you need floating point arithmetic while assembling!

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: 64 bit and REAL10 values
« Reply #5 on: September 24, 2012, 10:10:39 AM »
I have tried multiple times before to find a CRT where printf properly supported REAL10, that could be reasonably used from a Windows app coded in MASM. This time I tried the CRT from the lcc-win compiler system, that I got here:

http://www.cs.virginia.edu/~lcc-win32/

The good parts are that the CRT printf (and related) functions do support long double, and that the CRT appears to be, at least functionally, encapsulated in a DLL. The not so good part is that I don’t see a full 19 digits of precision.
Code: [Select]
;==============================================================================
; Build as a console app.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
    hMod dd 0
    r8   REAL8 ?
    r10  REAL10 ?
.code
;==============================================================================
start:
;==============================================================================
    invoke LoadLibrary, chr$("C:\lcc\bin\lcclibc.dll")
    mov hMod, eax
    printf("%Xh\n",hMod)
    invoke GetProcAddress, hMod, chr$("_printf")
    mov ebx, eax
    printf("%Xh\n\n",ebx)
    printf("3.141592653589793238462...\n")
    fldpi
    fstp r10
    fldpi
    fstp r8
    printf("%.20f\n",r8)
    push DWORD PTR r10+8
    push DWORD PTR r10+4
    push DWORD PTR r10+0
    push cfm$("%.20Lf\n\n")
    call ebx
    add esp, 16
    inkey
    exit
;==============================================================================
end start
Code: [Select]
10000000h
10008544h

3.141592653589793238462...
3.14159265358979310000
3.14159265358979324000

For reference, with an old DOS version of Turbo C I got:

3.14159265358979324000

And with a Digital Mars C/C++ compiler from 2007 (which used its own CRT instead of MSVCRT):

3.14159265358979323850

A few details that I noticed in doing this:

Long double is supported under Win64, but instead of the size being 12 bytes as it is for Win32 it had to be increased to 16 bytes.

Although not built in, there is support for a "qfloat" 352-bit floating-point type.
« Last Edit: September 24, 2012, 11:40:23 AM by MichaelW »
Well Microsoft, here’s another nice mess you’ve gotten us into.

Gunther

  • Member
  • *****
  • Posts: 3585
  • Forgive your enemies, but never forget their names
Re: 64 bit and REAL10 values
« Reply #6 on: September 25, 2012, 06:21:22 AM »
Hi Michael,

thank you for the hint. I'll give it a try.

Long double is supported under Win64, but instead of the size being 12 bytes as it is for Win32 it had to be increased to 16 bytes.

It's the same in 64 bit Linux. It seems that the 16 byte size is for alignment reasons.

Gunther
Get your facts first, and then you can distort them.