The MASM Forum

General => The Laboratory => Topic started by: hutch-- on July 13, 2020, 10:20:31 PM

Title: Macro for calling sse based procedures.
Post by: hutch-- on July 13, 2020, 10:20:31 PM
This is a test piece for direct XMM register argument passing with the return value always in xmm0. The procedures can be written with no stack frame and produce very low overhead.

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

    include \masm32\include64\masm64rt.inc

  ; -----------------------------------------------------------------------
  ; sdcall convention.
  ; arguments are passed from left to right up to a maximum of 8 arguments.
  ; each argument is written to an XMM register starting from xmm0 to xmm7
  ; return value is always in xmm0
  ; -----------------------------------------------------------------------
    sdcall MACRO procedure:REQ,dbl0,dbl1,dbl2,dbl3,dbl4,dbl5,dbl6,dbl7
    ;; -----------------
      IFNB <dbl7>
        movsd xmm7, dbl7
      ENDIF
    ;; -----------------
      IFNB <dbl6>
        movsd xmm6, dbl6
      ENDIF
    ;; -----------------
      IFNB <dbl5>
        movsd xmm5, dbl5
      ENDIF
    ;; -----------------
      IFNB <dbl4>
        movsd xmm4, dbl4
      ENDIF
    ;; -----------------
      IFNB <dbl3>
        movsd xmm3, dbl3
      ENDIF
    ;; -----------------
      IFNB <dbl2>
        movsd xmm2, dbl2
      ENDIF
    ;; -----------------
      IFNB <dbl1>
        movsd xmm1, dbl1
      ENDIF
    ;; -----------------
      IFNB <dbl0>
        movsd xmm0, dbl0
      ENDIF
    ;; -----------------
      call procedure
      EXITM <xmm0>
    ENDM

    .code

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

entry_point proc

    LOCAL result :REAL8
    LOCAL radius :REAL8
    LOCAL ptxt   :QWORD
    LOCAL text[64]:BYTE

    LOCAL ln1 :REAL8
    LOCAL ln2 :REAL8
    LOCAL ln3 :REAL8

    mov radius, dblval(10.0)

  ; |||||||||||||||||||||||||||||||||||||||||||

    movsd result, sdcall(spherical_area,radius)

  ; |||||||||||||||||||||||||||||||||||||||||||

    mov ptxt, ptr$(text)
    rcall fptoa,result,ptxt
    rcall truncate,ptxt,4
    conout ptxt," spherical_area",lf

    mov ln1, dblval(10.0)
    mov ln2, dblval(10.0)
    mov ln3, dblval(10.0)

  ; |||||||||||||||||||||||||||||||||||||||||||||||

    movsd result, sdcall(cuboid_volume,ln1,ln2,ln3)

  ; |||||||||||||||||||||||||||||||||||||||||||||||

    mov ptxt, ptr$(text)
    rcall fptoa,result,ptxt
    rcall truncate,ptxt,4
    conout ptxt," cuboid_volume",lf

    waitkey

    .exit

entry_point endp

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

NOSTACKFRAME

spherical_area proc                         ; surface area

  ; pi x 4 x (r x 2) = 4 pi r2

    movsd xmm1, AFL8(3.141592653589793)     ; pi
    mulsd xmm1, AFL8(4.0)                   ; * 4
    mulsd xmm0, xmm0                        ; squared
    mulsd xmm0, xmm1                        ; (pi * 4) x (r * 2)

    ret

spherical_area endp

STACKFRAME

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

NOSTACKFRAME

cuboid_volume proc

    mulsd xmm0, xmm1
    mulsd xmm0, xmm2

    ret

cuboid_volume endp

STACKFRAME

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

    end