Author Topic: x64 and x87 floating point ...  (Read 259 times)

mainziman

  • Regular Member
  • *
  • Posts: 3
x64 and x87 floating point ...
« on: August 20, 2017, 06:49:29 PM »
here is the assember source
Code: [Select]
public funct
.code
funct PROC
    push rbp
    mov rbp, rsp                   ; Setup stack frame
                                   ; RSP aligned to 16 bytes at this point
    push rbx

    mov [rbp+16],rcx               ; 32 byte shadow space is just above the return address
                                   ; at RBP+16 (this address is 16 byte aligned). Rather
                                   ; than use a temporary variable in the data section to
                                   ; store the value of RCX, we just store it to the
                                   ; shadow space on the stack.
    fild QWORD ptr[rbp+16]         ; Load and convert 64-bit integer into st(0)
    fldpi                          ; st(0) => st(1), st(0) = pi
    fmulp                          ; st(1)=st(1)*st(0), st(1) => st(0)
    fstp REAL4 ptr [rbp+16]        ; Store result to shadow space as 32-bit float
    movss xmm0, REAL4 ptr [rbp+16] ; Store single scalar (32-bit float) to xmm0
                                   ; XMM0 = return value for 32(and 64-bit) floats
                                   ;        in 64-bit code.

    pop rbx
    mov rsp, rbp                   ; Remove stack frame
    pop rbp
    ret
funct ENDP
END

and here what ml64 generates with ml64 /Fl /Sa mod.asm:

Code: [Select]
Microsoft (R) Macro Assembler (AMD64) Version 8.00.40310.39 08/20/17 09:53:34
mod.asm      Page 1 - 1


public funct
 00000000 .code
 00000000 funct PROC
 00000000  55     push rbp
 00000001  48/ 8B EC     mov rbp, rsp                   ; Setup stack frame
                                   ; RSP aligned to 16 bytes at this point
 00000004  53     push rbx

 00000005  48/ 89 4D 10     mov [rbp+16],rcx               ; 32 byte shadow space is just above the return address
                                   ; at RBP+16 (this address is 16 byte aligned). Rather
                                   ; than use a temporary variable in the data section to
                                   ; store the value of RCX, we just store it to the
                                   ; shadow space on the stack.
    fild QWORD ptr[rbp+16]         ; Load and convert 64-bit integer into st(0)
mod.asm(17) : error A2222: x87 and MMX instructions disallowed; legacy FP state not saved in Win64
    fldpi                          ; st(0) => st(1), st(0) = pi, 3.14159...
mod.asm(18) : error A2222: x87 and MMX instructions disallowed; legacy FP state not saved in Win64
    fmulp                          ; st(1)=st(1)*st(0), st(1) => st(0)
mod.asm(19) : error A2222: x87 and MMX instructions disallowed; legacy FP state not saved in Win64
    fstp REAL4 ptr [rbp+16]        ; Store result to shadow space as 32-bit float
mod.asm(20) : error A2222: x87 and MMX instructions disallowed; legacy FP state not saved in Win64
 00000009  F3/ 0F 10 45     movss xmm0, REAL4 ptr [rbp+16] ; Store single scalar (32-bit float) to xmm0
   10
                                   ; XMM0 = return value for 32(and 64-bit) floats
                                   ;        in 64-bit code.

 0000000E  5B     pop rbx
 0000000F  48/ 8B E5     mov rsp, rbp                   ; Remove stack frame
 00000012  5D     pop rbp
 00000013  C3     ret
 00000014 funct ENDP
END
Microsoft (R) Macro Assembler (AMD64) Version 8.00.40310.39 08/20/17 09:53:34
mod.asm      Symbols 2 - 1




Procedures, parameters, and locals:

                N a m e                 Type     Value    Attr

funct  . . . . . . . . . . . . . P 00000000 _TEXT Length= 00000014 Public

   0 Warnings
   4 Errors

please can someone tell me how I can use x87 floating point in 64-bit mode
(this is just an example, I have some sophisticated calculations in assembly,
 which I want to move to 64-bit)

Thanks,
Walter

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 4813
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: x64 and x87 floating point ...
« Reply #1 on: August 20, 2017, 07:00:07 PM »
Walter,

I am sorry but I have not had time to work on FP code in 64 bit yet, perhaps one of the other members can help you out. I would not mix MMX and FP instructions as they work on the same registers and note that in win64 the MMX and FP registers are not specified in the Windows 64 bit ABI so you cannot make any assumptions on them remaining the same between procedure calls.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 4813
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: x64 and x87 floating point ...
« Reply #2 on: August 20, 2017, 09:37:28 PM »
LATER : Walter, would you post the actual source rather than the dump.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

mainziman

  • Regular Member
  • *
  • Posts: 3
Re: x64 and x87 floating point ...
« Reply #3 on: August 20, 2017, 09:51:18 PM »
Hello,

I know; for me only FP x87 is important, the MMX I don't need, and never have used ...

how could these samples here be assembed?
http://masm32.com/board/index.php?topic=4880.0

there I see at the first sample this:
Code: [Select]
include win64a.inc
include msvcrt.inc
is there something I need to have in order to tell ml64 to accept FP x87?
from where can I download these two INCLUDE files?

this is the actual source
Code: [Select]
public funct
.code
funct PROC
    push rbp
    mov rbp, rsp                   ; Setup stack frame
                                   ; RSP aligned to 16 bytes at this point
    push rbx

    mov [rbp+16],rcx               ; 32 byte shadow space is just above the return address
                                   ; at RBP+16 (this address is 16 byte aligned). Rather
                                   ; than use a temporary variable in the data section to
                                   ; store the value of RCX, we just store it to the
                                   ; shadow space on the stack.
    fild QWORD ptr[rbp+16]         ; Load and convert 64-bit integer into st(0)
    fldpi                          ; st(0) => st(1), st(0) = pi, 3.14159...
    fmulp                          ; st(1)=st(1)*st(0), st(1) => st(0)
    fstp REAL4 ptr [rbp+16]        ; Store result to shadow space as 32-bit float
    movss xmm0, REAL4 ptr [rbp+16] ; Store single scalar (32-bit float) to xmm0
                                   ; XMM0 = return value for 32(and 64-bit) floats
                                   ;        in 64-bit code.

    pop rbx
    mov rsp, rbp                   ; Remove stack frame
    pop rbp
    ret
funct ENDP
END

and it is called from C/C++ like this:

function prototype:
Code: [Select]
#ifdef __cplusplus
extern "C" {
#endif
float funct(long long n);
#ifdef __cplusplus
}
#endif

usage: e.g.
Code: [Select]
long long llVal = 57765;
float fltVal = funct( llVal );

Thanks,
Walter

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 4813
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: x64 and x87 floating point ...
« Reply #4 on: August 20, 2017, 10:23:54 PM »
The code you posted builds with no errors. This is what I tried out.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    mov rcx, 57765
    call funct

    waitkey

    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 NOSTACKFRAME

 funct PROC

    mov [rbp+16],rcx
    fild QWORD ptr[rbp+16]
    fldpi
    fmulp
    fstp REAL4 ptr [rbp+16]
    movss xmm0, REAL4 ptr [rbp+16]

    ret

 funct ENDP

 STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 ;     long long llVal = 57765;
 ;     float fltVal = funct( llVal );

    end
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

mainziman

  • Regular Member
  • *
  • Posts: 3
Re: x64 and x87 floating point ...
« Reply #5 on: August 21, 2017, 05:10:31 AM »
seems to be a problem with ml64.exe 8.x,  ml64.exe 9.x or later don't give such an error ... and
build with no error ... strange ...

by the way, why do I have to enter several strange questions every time when posting?

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: x64 and x87 floating point ...
« Reply #6 on: August 21, 2017, 07:48:41 AM »
by the way, why do I have to enter several strange questions every time when posting?

Must be an error with the manual you are reading ::)

include \Masm32\MasmBasic\Res\JBasic.inc        ; # requires MasmBasic #
.data?
MyRes  REAL8 ?
Init           ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format", 13, 10)
  fldpi
  jinvoke Sleep, 100  ; just a test - give the OS some time to destroy the FPU between task switches
  fstp MyRes
  Inkey Str$("The CRT has never been very precise: %1.17f - but the FPU works in 64-bit land!!", MyRes)
EndOfCode


Code: [Select]
This code was assembled with ml64 in 64-bit format

The CRT has never been very precise: 3.14159265358979310 - but the FPU works in 64-bit land!

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 4813
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: x64 and x87 floating point ...
« Reply #7 on: August 21, 2017, 10:33:18 AM »
mainziman,

The questions go away after a few posts, they are there to slow down robots and people who post garbage in the forum.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin: