News:

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

Main Menu

Re: X64 ABI, REAL8 passed in xmmreg?

Started by jj2007, April 09, 2021, 11:23:41 PM

Previous topic - Next topic

jj2007

This one uses the Masm64 SDK and really intrigues me - it works like a charm:
include \masm32\include64\masm64rt.inc
include \masm32\include64\msvcrt.inc
includelib \masm32\lib64\msvcrt.lib

.data?
buffer db 100 dup(?)

.code
txTitle db "Expected value: 12345.678", 0
txFormat db "Test %f", 13, 10, 0
MyR8 REAL8 12345.67890

entry_point proc
  invoke vc_sprintf, addr buffer, addr txFormat, MyR8
  invoke MessageBox, 0, addr buffer, addr txTitle, MB_OK
  invoke ExitProcess, 0
  ret
entry_point endp

end


Here is a nice x64 ABI tutorial, see in particular Mixing parameter types

HSE

Quote from: jj2007 on April 09, 2021, 11:23:41 PM
Here is a nice x64 ABI tutorial, see in particular Mixing parameter types

:eusa_naughty: Tutorial is against x64 ABI

Floats in 4 first positions must be in XMM and GPR (both)!

The function sprintf read from GPR.
Equations in Assembly: SmplMath

jj2007

Quote from: HSE on April 09, 2021, 11:53:12 PM
Floats in 4 first positions must be in XMM and GPR (both)!

You are right, good point :thumbsup:

Parameter passing

QuoteAny floating-point and double-precision arguments in the first four parameters are passed in XMM0 - XMM3, depending on position. Floating-point values are only placed in the integer registers RCX, RDX, R8, and R9 when there are varargs arguments.

HSE

QuoteFor floating-point values only, both the integer register and the floating-point register must contain the value, in case the callee expects the value in the integer registers.

:thumbsup: At this point invoke macro don't make distintions. That was removed from ml because M$ relly in compilers to do that.
Equations in Assembly: SmplMath

jj2007

Quote from: HSE on April 10, 2021, 12:22:25 AM
QuoteFor floating-point values only, both the integer register and the floating-point register must contain the value, in case the callee expects the value in the integer registers.

:thumbsup: At this point invoke macro don't make distintions. That was removed from ml because M$ relly in compilers to do that.

The next version of jinvoke will make distinctions :cool:

HSE

Equations in Assembly: SmplMath

hutch--

In MASM, a 64 bit hole is a 64 bit hole, if you are passing REAL8 args, they fit into 64 bit integer registers with no problems. You can also return a 64 bit result in RAX as long as you transfer it to a 64 bit REAL8 to work on as FP.

jj2007

Quote from: hutch-- on April 10, 2021, 11:28:37 AM
if you are passing REAL8 args, they fit into 64 bit integer registers with no problems.

That's correct, but it doesn't respect the x64 ABI, and some WinAPIs may not find the double they expect in xmm0...xmm3 :cool:

hutch--

Well the obvious is that a 128 bit register and a 64 bit integer register are different animals and the two should not be confused. If an API expects an XMM register, that is what you pass it, if instead it expects a 64 bit memory operand or a 64 bit register, either a REAL8 or a QWORD, then you pass the 64 bit format.

I mentioned the obvious, a QWORD and a REAL8 fit the same hole and you can successfully pass a return value in RAX as long as you load it into a REAL8 memory operand for further processing. We are not dealing with strongly typed compilers here, we are dealing with an assembler.

HSE

x64 calling convention make a clear distinction between Prototyped functions, Vararg functions and Unprototyped functions then, and I'm sure Hutch will dislike this, Prototypes are an essential part the x64 ABI.

ML deal directly with prototypes. M$ maked something different with ML64 because are compilers (used as preprocessors to generate assembly code) what deal with prototypes. Then to use ML64 following x64 ABI requiere a lot more effort, or to use some macros that deal with prototypes. And that part of more effort dislike me :biggrin:
Equations in Assembly: SmplMath

HSE


Quote from: hutch-- on April 10, 2021, 11:28:37 AM
In MASM, a 64 bit hole is a 64 bit hole, if you are passing REAL8 args, they fit into 64 bit integer registers with no problems. You can also return a 64 bit result in RAX as long as you transfer it to a 64 bit REAL8 to work on as FP.

That could be a nice world. You perhaps don't need stronger prototypes in that world. For some reason people solve problems in strange ways.
I think everybody must use REAL8, but all GPU, SIMD, graffics engines,  etc. insist to use REAL4!!!. For sure they are totally wrong  :biggrin: :biggrin: :biggrin:
Equations in Assembly: SmplMath

hutch--

Hector,

You are confusing compilers and assemblers with prototypes. MASM does not support them.  :tongue:

> I think everybody must use REAL8, but all GPU, SIMD, graffics engines,  etc. insist to use REAL4!!!. For sure they are totally wrong

Games and number crunching are different animals. The only problems with 64 bit FP is the precision is not high enough for all tasks. 80 bit x87 is higher but not even recognised in x64 although it runs OK.

You probably understand why I am not a consensus person or you would be using a visual garbage generator.  :dazzled:

jj2007

Coming soon - work in progress :biggrin:

include \Masm32\MasmBasic\Res\JBasic.inc ; ## builds in 32- or 64-bit mode with UAsm, ML, AsmC ##

DefProc SayHi proc argString:SIZE_P, argDword, argDouble:REAL8 ; #1 is a pointer size argument
Local v1, v2:REAL8, rc:RECT
  Print Str$("\nThe locals are cleared: %i %i %i...%i\n", v1, v2, rc.left, rc.bottom)
  Print Str$("\nThe arguments:\n%s\n%i\n%f\n", argString, argDword, argDouble)
  ret
SayHi endp

SetGlobals MyDW=12345 ; OPT_64 1 ; put 0 for 32 bit, 1 for 64 bit assembly
Init
  ; jinvoke SayHi, Chr$("Argument #1 is a string"), 22222, FP8(33.3), 1 ; ## line 12: too many arguments for SayHi ##
  ; jinvoke SayHi, Chr$("Argument #1 is a string"), 22222 ; ## line 13: not enough arguments for SayHi ##
  ; jinvoke SayHi, Chr$("Argument #1 is a string"), 22222, MyDW ; ## line 14: argument #3 should be REAL8 ##
  ; jinvoke SayHi, Chr$("Argument #1 is a string"), 22222, 123456789 ; ## line 15: argument #3 should be REAL8 ##
  jinvoke SayHi, Chr$("Argument #1 is a string"), 22222, FP8(33.3) ; OK!
  PrintLine Chr$("This program was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format.")
EndOfCode XP ; add an XP manifest (not with ML64)

HSE

Hi Hutch!
Quote from: hutch-- on April 11, 2021, 01:07:03 AM
You are confusing compilers and assemblers with prototypes. MASM does not support them.  :tongue:
MASM is just the programming tool. x64 ABI require prototypes. (I said it, you don't like that  :thumbsup:

Quote from: hutch-- on April 11, 2021, 01:07:03 AM
The only problems with 64 bit FP is the precision is not high enough for all tasks. 80 bit x87 is higher but not even recognised in x64 although it runs OK.
By design, programmers never have to use 80 bit x87. For precisions higher than REAL8 there is BigNumbers libraries. Long time ago REAL8 only existed in libraries.

Quote from: hutch-- on April 11, 2021, 01:07:03 AM
You probably understand why I am not a consensus person or you would be using a visual garbage generator.  :dazzled:
:biggrin: There is thousands of other places for consensus persons.
Equations in Assembly: SmplMath

HSE

Quote from: jj2007 on April 11, 2021, 01:32:55 AM
Coming soon - work in progress :biggrin:

:thumbsup: Remember we need prototypes for share libraries. It's almost irrelevant for our own internal functions.
Equations in Assembly: SmplMath