Announcement

Collapse
No announcement yet.

Sample calculation in SSE.

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Sample calculation in SSE.

    This code does a simple pi r2 x length. The scalar (single value) sse instructions are reasonably easy to use and are SSE2 era technology.
    Code:
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
    FUNCTION PBmain as LONG
    
        LOCAL radi as DOUBLE
        LOCAL lnth as DOUBLE
        LOCAL pi   as DOUBLE
        LOCAL rslt as DOUBLE
    
        radi = 1.5
        lnth = 3.0
        pi   = 3.14159265
    
      ' ----------------------------------
      ' calculate the volume of a cylinder
      ' ----------------------------------
      PREFIX "!"
        movsd xmm0, radi        ; load radius
        mulsd xmm0, xmm0        ; squared
        mulsd xmm0, pi          ; * pi
        mulsd xmm0, lnth        ; * depth
        movsd rslt, xmm0        ; result to REAL8
      END PREFIX
    
        StdOut format$(rslt)
    
        waitkey$
    
    End FUNCTION
    
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    hutch at movsd dot com
    The MASM Forum

    www.masm32.com

  • #2
    The example below has been extended and has a set of macros dedicated to SSE floating point that shows both inlined SSE and a remote procedure with the values passed in xmm registers.

    The general drift is the scalar SSE instructions are reasonably easy to use so if you have a use for arithmetic using 64 bit DOUBLE, you can code this with no great difficulty.

    This is a list of instructions from the Intel manual but there may be more.
    Code:
    One arg must be an SSE register or both can be.
    
    movsd       ' move data in and out of registers
    addsd       ' add double to register
    subsd       ' sub dbl from register
    mulsd       ' mul 2 dbl values
    divsd       ' div one value by another
    
    sqrtsd      ' square root
    comisd      ' compare two dbl values and set eflags (jz jnz je jne etc...)
    roundsd     ' Round Scalar Double Precision Floating-Point Values
    ucomisd     ' Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
    cmpsd       ' Compare Scalar Double-Precision Floating-Point Value
    
    minsd       ' Return Minimum Scalar Double-Precision Floating-Point Value
    maxsd       ' Return Maximum Scalar Double-Precision Floating-Point Value
    
    cvtsd2si    ' Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
    cvtsd2ss    ' Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
    cvtsi2sd    ' Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
    cvtsd2si    ' Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
    cvttsd2si   ' Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Integer
    The example.
    Code:
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
      ' ---------------------------------------
      ' 1 to 4 argument macros, args are DOUBLE
      ' ---------------------------------------
        MACRO ssesd1(proc,arg1)
        PREFIX "!"
          movsd xmm0, arg1
          call proc
        END PREFIX
        END MACRO
    
        MACRO ssesd2(proc,arg1,arg2)
        PREFIX "!"
          movsd xmm0, arg1
          movsd xmm1, arg2
          call proc
        END PREFIX
        END MACRO
    
        MACRO ssesd3(proc,arg1,arg2,arg3)
        PREFIX "!"
          movsd xmm0, arg1
          movsd xmm1, arg2
          movsd xmm2, arg3
          call proc
        END PREFIX
        END MACRO
    
        MACRO ssesd4(proc,arg1,arg2,arg3,arg4)
        PREFIX "!"
          movsd xmm0, arg1
          movsd xmm1, arg2
          movsd xmm2, arg3
          movsd xmm3, arg4
          call proc
        END PREFIX
        END MACRO
    
        MACRO getxmm0(dbl)
        PREFIX "!"
          movsd dbl, xmm0
        END PREFIX
        END MACRO
      ' ---------------------------------------
    
        GLOBAL pi as DOUBLE
    
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
      ' ----------------------------------
      ' calculate the volume of a cylinder
      ' ----------------------------------
    
     FUNCTION PBmain as LONG
    
        #REGISTER NONE
    
        LOCAL radius as DOUBLE
        LOCAL length as DOUBLE
        LOCAL result as DOUBLE
    
        radius = 1.5
        length = 3.0
        pi     = 3.14159265
    
      ' ----------------------------------
      ' inline calculation
      ' ----------------------------------
      PREFIX "!"
        movsd xmm0, radius              ; load radius
        mulsd xmm0, xmm0                ; squared
        mulsd xmm0, pi                  ; * pi
        mulsd xmm0, length              ; * depth
        movsd result, xmm0              ; result to DOUBLE
      END PREFIX
    
        StdOut format$(result)
    
      ' ----------------------------------
      ; calculation via procedure
      ' ----------------------------------
        ssesd2(GetVol,radius,length)    ; call procedure with DBL arguments
        getxmm0(result)                 ; write result to DBL variable
    
        StdOut format$(result)
    
      ' ----------------------------------
    
        waitkey$
    
     End FUNCTION
    
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
     FASTPROC GetVol
    
      PREFIX "!"
        mulsd xmm0, xmm0        ; squared
        mulsd xmm0, pi          ; * pi
        mulsd xmm0, xmm1        ; * depth
        ret
      END PREFIX
    
     END FASTPROC
    
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    hutch at movsd dot com
    The MASM Forum

    www.masm32.com

    Comment

    Working...
    X