Author Topic: Re: X64 ABI, REAL8 passed in xmmreg?  (Read 2060 times)

jj2007

  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: X64 ABI, REAL8 passed in xmmreg?
« on: April 09, 2021, 11:23:41 PM »
This one uses the Masm64 SDK and really intrigues me - it works like a charm:
Code: [Select]
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

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #1 on: April 09, 2021, 11:53:12 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.

jj2007

  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #2 on: April 10, 2021, 12:00:41 AM »
Floats in 4 first positions must be in XMM and GPR (both)!

You are right, good point :thumbsup:

Parameter passing

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

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #3 on: April 10, 2021, 12:22:25 AM »
Quote
For 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.

jj2007

  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #4 on: April 10, 2021, 12:24:11 AM »
Quote
For 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

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #5 on: April 10, 2021, 12:31:17 AM »
The next version of jinvoke will make distinctions :cool:

Great!!

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 8491
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #6 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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

jj2007

  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #7 on: April 10, 2021, 06:10:05 PM »
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--

  • Administrator
  • Member
  • ******
  • Posts: 8491
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #8 on: April 10, 2021, 06:48:19 PM »
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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

HSE

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #9 on: April 10, 2021, 11:00:43 PM »
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:

HSE

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #10 on: April 11, 2021, 12:20:49 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:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 8491
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #11 on: April 11, 2021, 01:07:03 AM »
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:
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

jj2007

  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #12 on: April 11, 2021, 01:32:55 AM »
Coming soon - work in progress :biggrin:

Code: [Select]
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

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #13 on: April 11, 2021, 01:40:07 AM »
Hi Hutch!
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:

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.

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.

HSE

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Re: Re: X64 ABI, REAL8 passed in xmmreg?
« Reply #14 on: April 11, 2021, 01:50:15 AM »
Coming soon - work in progress :biggrin:

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