News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

a couple of simd macros

Started by NightWare, July 13, 2009, 12:05:31 AM

Previous topic - Next topic

NightWare

hi, i'm not a macro aficionados (far from that...  :bdg), but sometimes it's usefull to use some of them, here a couple of macro to temporary store/restore XMMx registers using the MMx registers (to avoid mem access).

;
; Receive :
; an unused XMMx register XMMi (needed for the job, it's made for speed not for a safe usage)
; the XMMx register that will be restored
; the MMx register that contain the higher part
; the MMx register that contain the lower part
; (optionnal) repeat the operation 3 time (except for the unused register)
;
; Return :
; the XMMx register/s restored
;
; Syntax : RestoreFromMmx_Sse2 [XMMx_u],[XMMx],[MMx_h],[MMx_l],([XMMx],[MMx_h],[MMx_l])
;
RestoreFromMmx_Sse2 MACRO _Reg_XMMu_:REQ,_Reg_XMM0_:REQ,_Reg_MM1_:REQ,_Reg_MM0_:REQ,_Reg_XMM1_,_Reg_MM3_,_Reg_MM2_,_Reg_XMM2_,_Reg_MM5_,_Reg_MM4_,_Reg_XMM3_,_Reg_MM7_,_Reg_MM6_
movq2dq _Reg_XMMu_,_Reg_MM1_ ; _Reg_XMMu_ = _,_,y,y
movq2dq _Reg_XMM0_,_Reg_MM0_ ; _Reg_XMM0_ = _,_,x,x
movlhps _Reg_XMM0_,_Reg_XMMu_ ; _Reg_XMM0_ = y,y,x,x
IFNB <_Reg_MM2_>
movq2dq _Reg_XMMu_,_Reg_MM3_ ; _Reg_XMMu_ = _,_,y,y
movq2dq _Reg_XMM1_,_Reg_MM2_ ; _Reg_XMM1_ = _,_,x,x
movlhps _Reg_XMM1_,_Reg_XMMu_ ; _Reg_XMM1_ = y,y,x,x
ENDIF
IFNB <_Reg_MM4_>
movq2dq _Reg_XMMu_,_Reg_MM5_ ; _Reg_XMMu_ = _,_,y,y
movq2dq _Reg_XMM2_,_Reg_MM4_ ; _Reg_XMM3_ = _,_,x,x
movlhps _Reg_XMM2_,_Reg_XMMu_ ; _Reg_XMM3_ = y,y,x,x
ENDIF
IFNB <_Reg_MM6_>
movq2dq _Reg_XMMu_,_Reg_MM7_ ; _Reg_XMMu_ = _,_,y,y
movq2dq _Reg_XMM3_,_Reg_MM6_ ; _Reg_XMM3_ = _,_,x,x
movlhps _Reg_XMM3_,_Reg_XMMu_ ; _Reg_XMM3_ = y,y,x,x
ENDIF
ENDM


;
; Receive :
; the MMx register that will contain the higher part
; the MMx register that will contain the lower part
; the XMMx register to store
; (optionnal) repeat the operation 3 time
;
; Return :
; the XMMx register stored (WARNING ! the XMMx register is modified, it's made for speed not for a safe usage,
; anyway if we need to store an XMMx register, it's not to use the content just after, generally...)
;
; Syntax : StoreInMmx_Sse2 [MMx_h],[MMx_l],[XMMx],([MMx_h],[MMx_l],[XMMx])
;
StoreInMmx_Sse2 MACRO _Reg_MM0_:REQ,_Reg_MM1_:REQ,_Reg_XMM0_:REQ,_Reg_MM2_,_Reg_MM3_,_Reg_XMM1_,_Reg_MM4_,_Reg_MM5_,_Reg_XMM2_,_Reg_MM6_,_Reg_MM7_,_Reg_XMM3_
movdq2q _Reg_MM1_,_Reg_XMM0_ ; _Reg_MM0_ = x,x
IFNB <_Reg_XMM1_>
movdq2q _Reg_MM3_,_Reg_XMM1_ ; _Reg_MM2_ = x,x
ENDIF
IFNB <_Reg_XMM2_>
movdq2q _Reg_MM5_,_Reg_XMM2_ ; _Reg_MM4_ = x,x
ENDIF
IFNB <_Reg_XMM3_>
movdq2q _Reg_MM7_,_Reg_XMM3_ ; _Reg_MM6_ = x,x
movhlps _Reg_XMM3_,_Reg_XMM3_ ; _Reg_XMM3_ = _,_,y,y
ENDIF
IFNB <_Reg_XMM2_>
movhlps _Reg_XMM2_,_Reg_XMM2_ ; _Reg_XMM2_ = _,_,y,y
ENDIF
IFNB <_Reg_XMM1_>
movhlps _Reg_XMM1_,_Reg_XMM1_ ; _Reg_XMM1_ = _,_,y,y
ENDIF
movhlps _Reg_XMM0_,_Reg_XMM0_ ; _Reg_XMM0_ = _,_,y,y
movdq2q _Reg_MM0_,_Reg_XMM0_ ; _Reg_MM1_ = y,y
IFNB <_Reg_XMM1_>
movdq2q _Reg_MM2_,_Reg_XMM1_ ; _Reg_MM3_ = y,y
ENDIF
IFNB <_Reg_XMM2_>
movdq2q _Reg_MM4_,_Reg_XMM2_ ; _Reg_MM5_ = y,y
ENDIF
IFNB <_Reg_XMM3_>
movdq2q _Reg_MM6_,_Reg_XMM3_ ; _Reg_MM7_ = y,y
ENDIF
ENDM


example :
   StoreInMmx_Sse2 MM1,MM0,XMM0,MM3,MM2,XMM1,MM5,MM4,XMM2,MM7,MM6,XMM3   ; store XMM0, XMM1, XMM2, XMM3
   RestoreFromMmx_Sse2 XMM4,XMM6,MM1,MM0,XMM7,MM3,MM2   ; restore XMM0, XMM1 in XMM6, XMM7