News:

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

Main Menu

x64 and x87 floating point ...

Started by mainziman, August 20, 2017, 06:49:29 PM

Previous topic - Next topic

mainziman

here is the assember source
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:


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--

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--

LATER : Walter, would you post the actual source rather than the dump.

mainziman

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:

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

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:

#ifdef __cplusplus
extern "C" {
#endif
float funct(long long n);
#ifdef __cplusplus
}
#endif


usage: e.g.

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


Thanks,
Walter

hutch--

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

mainziman

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

Quote from: mainziman on August 21, 2017, 05:10:31 AMby 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


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--

mainziman,

The questions go away after a few posts, they are there to slow down robots and people who post garbage in the forum.