I have got the earlier macro to work on different data notations and it seems to be working OK. I got a notation to work in an invoke call if it is used as the last argument.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include64\masm64rt.inc
; *************************************************************
load_xmm_regs MACRO args:VARARG
LOCAL buff,aattr
buff equ <>
cnt = 0
;; ---------------------------------------------------------
for arg, <args>
aattr = getattr(arg) ;; get the argument attribute
IF aattr EQ 36 ;; INT immediate, exit on error
.err < ---{ notation error, missing floating point }--->
%echo ------------------------------------------------------------------
%echo ERROR => arg : x86-64 does not support loading immediate integers
%echo in an XMM register. Use FP format value instead => arg.0
%echo Assembly is TERMINATED at this point
%echo ------------------------------------------------------------------
EXITM <> ;; stop the macro here on error
END ;; terminate the assembly
ENDIF
IF aattr EQ 0
buff CATSTR <loadsd >,<xmm>,%cnt,<, >,<arg> ;; pseudo immediate
goto writeit
ENDIF
IF aattr EQ 98
buff CATSTR <movsd >,<xmm>,%cnt,<, >,<arg> ;; LOCAL var
goto writeit
ENDIF
IF aattr EQ 42
buff CATSTR <movsd >,<xmm>,%cnt,<, >,<arg> ;; GLOBAL var
goto writeit
ENDIF
IF aattr EQ 48
buff CATSTR <movsd >,<xmm>,%cnt,<, >,<arg> ;; XMM register
goto writeit
ENDIF
:writeit
% buff ;; output as string
cnt = cnt + 1 ;; increment register counter
ENDM
;; ---------------------------------------------------------
ENDM
; *************************************************************
xrv MACRO pname:REQ, args :VARARG ;; function form
load_xmm_regs args
call pname ;; call the procedure
EXITM < xmm0>
ENDM
xinvoke MACRO pname:REQ, args :VARARG ;; statement form
load_xmm_regs args
call pname ;; call the procedure
ENDM
xload MACRO args:VARARG
load_xmm_regs args ;; load XMM regs only
ENDM
xloadrv MACRO args:VARARG
load_xmm_regs args ;; load XMM regs only
EXITM <> ;; allow empty function form
ENDM
; *************************************************************
.data?
gvar REAL8 ? ; global for testing
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
entry_point proc
LOCAL lvar :REAL8
LOCAL tvar :REAL8
LOCAL pbuf :QWORD
LOCAL buff[64] :BYTE
mov pbuf, ptr$(buff)
movsd lvar, xrv(XmmTest,1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0)
rcall fptoa,lvar,pbuf
conout " Result = ",pbuf,lf
xinvoke XmmTest,1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0
movsd lvar, xmm0
rcall fptoa,lvar,pbuf
conout " Result = ",pbuf,lf,lf
; -------------------------------------------------------------------
; with invoke, the integer args must come first. FP load must be last
; -------------------------------------------------------------------
invoke LoadTest,1111,2222,3333,4444, xloadrv(1234.1234, 5678.5678)
waitkey
.exit
entry_point endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
NOSTACKFRAME
XmmTest proc
addsd xmm0, xmm1
addsd xmm0, xmm2
addsd xmm0, xmm3
addsd xmm0, xmm4
addsd xmm0, xmm5
addsd xmm0, xmm6
addsd xmm0, xmm7
ret
XmmTest endp
STACKFRAME
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
LoadTest proc
USING r12,r13,r14,r15
LOCAL var1 :REAL8
LOCAL var2 :REAL8
LOCAL ptxt :QWORD
LOCAL text[64]:BYTE
SaveRegs
movsd var1, xmm0 ; copy to REAL8 first
movsd var2, xmm1 ; something in fptoa over writes at least one XMM register
mov ptxt, ptr$(text)
mov r12, rcx
mov r13, rdx
mov r14, r8
mov r15, r9
conout " Integer ",str$(r12),lf
conout " Integer ",str$(r13),lf
conout " Integer ",str$(r14),lf
conout " Integer ",str$(r15),lf,lf
invoke fptoa,var1,ptxt
conout " SD Float ",ptxt,lf
invoke fptoa,var2,ptxt
conout " SD Float ",ptxt,lf
RestoreRegs
ret
LoadTest endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end