; MCS macro file for Microsoft compilers with SSE2 support ; ; Triple register is xmm0 ; MUL_START. Initialise registers. Make ebx and esi point to multipliers a ; and b. edi points at result c. ; Initialise Triple register to 0 ; See makemcs.txt for more information about this file. ; MACRO PMUL_START ASM { push PBP push DDI push DSI mov PBX,a mov DSI,b mov PDI,c xor DCX,DCX mov DBP,sn ENDM MACRO PMUL mov DAX,DBP mul POINTER [PBX+N*%d] add DAX,DCX adc DDX,0 mov DCX,DDX mov POINTER [PSI+N*%d],0 mov [PDI+N*%d],DAX ENDM MACRO PMUL_END mov DAX,DBP mul DCX mov [PSI],DAX mov [PSI+N],DDX pop DSI pop DDI pop PBP } ENDM MACRO MUL_START ASM { push DDI push DSI mov PBX,a mov PSI,b mov PDI,c pxor xmm0,xmm0 ENDM ; ; STEP macro. Calculates a double-register partial product ; and adds it to the triple register total ; Parameters 1 & 2: Indices i and j for partial product multipliers a[i] ; and b[j] MACRO STEP movd xmm1,[PBX+N*%d] movd xmm2,[PSI+N*%d] pmuludq xmm1,xmm2 pshufd xmm1,xmm1,0xd8 paddq xmm0,xmm1 ENDM MACRO STEP1M movd xmm1,[PBX+N*%d] movd xmm2,[PSI+N*%d] pmuludq xmm1,xmm2 ENDM MACRO STEP1A pshufd xmm1,xmm1,0xd8 paddq xmm0,xmm1 ENDM MACRO STEP2M movd xmm3,[PBX+N*%d] movd xmm4,[PSI+N*%d] pmuludq xmm3,xmm4 ENDM MACRO STEP2A pshufd xmm3,xmm3,0xd8 paddq xmm0,xmm3 ENDM ; ; MFIN macro. Finish column calculation. Store Sum for this column ; and get Carry for next ; Parameter 1: Index k for Column Sum c[k] MACRO MFIN movd [PDI+N*%d],xmm0 movq xmm7,xmm0 psrlq xmm7,MIRACL psrldq xmm0,MIRACL/4 paddq xmm0,xmm7 ENDM ; ; MUL_END ; Parameter 1: Index for final carry c[.] MACRO MUL_END movd [PDI+N*%d],xmm0 pop DSI pop DDI } ENDM ; ; LAST ; MACRO LAST movd xmm1,[PBX+N*%d] movd xmm2,[PSI+N*%d] pmuludq xmm1,xmm2 paddq xmm0,xmm1 ENDM ; ; SQR_START ; MACRO SQR_START ASM { push DDI push DSI mov PBX,a mov PSI,c pxor xmm0,xmm0 ENDM ; ; DSTEP macro. Calculates a double-register partial product ; and add it twice to a triple register total ; Parameters 1 & 2 : Indices of partial product multipliers MACRO DSTEP movd xmm1,[PBX+N*%d] movd xmm2,[PBX+N*%d] pmuludq xmm1,xmm2 pshufd xmm1,xmm1,0xd8 paddq xmm0,xmm1 paddq xmm0,xmm1 ENDM MACRO DSTEP1M movd xmm1,[PBX+N*%d] movd xmm2,[PBX+N*%d] pmuludq xmm1,xmm2 ENDM MACRO DSTEP1A pshufd xmm1,xmm1,0xd8 paddq xmm0,xmm1 paddq xmm0,xmm1 ENDM MACRO DSTEP2M movd xmm3,[PBX+N*%d] movd xmm4,[PBX+N*%d] pmuludq xmm3,xmm4 ENDM MACRO DSTEP2A pshufd xmm3,xmm3,0xd8 paddq xmm0,xmm3 paddq xmm0,xmm3 ENDM ; ; SELF macro. Calculate the double-register square and ; add it to a triple register total ; Parameter 1 : Index of diagonal element MACRO SELF movd xmm1,[PBX+N*%d] pmuludq xmm1,xmm1 pshufd xmm1,xmm1,0xd8 paddq xmm0,xmm1 ENDM ; ; SFIN macro. Finish column calculation for squaring. Store Sum ; and get Carry for next column. ; Parameter 1: Index of Column Sum MACRO SFIN movd [PSI+N*%d],xmm0 movq xmm7,xmm0 psrlq xmm7,MIRACL psrldq xmm0,MIRACL/4 paddq xmm0,xmm7 ENDM ; ; SQR_END ; Parameter 1: Index for final carry MACRO SQR_END movd [PSI+N*%d],xmm0 pop DSI pop DDI } ENDM ; ; REDC_START macro ; MACRO REDC_START ASM { push DDI push DSI mov PBX,a mov PSI,b movd xmm6,ndash movd xmm0,[PBX] ENDM ; ; RFINU macro ; MACRO RFINU movq xmm7,xmm0 pmuludq xmm7,xmm6 movd [PBX+N*%d],xmm7 movd xmm1,[PSI] pmuludq xmm1,xmm7 pshufd xmm1,xmm1,0xd8 paddq xmm0,xmm1 movq xmm7,xmm0 psrlq xmm7,MIRACL psrldq xmm0,MIRACL/4 paddq xmm0,xmm7 movd xmm1,[PBX+N*(%d+1)] paddq xmm0,xmm1 ENDM ; ; RFIND macro ; MACRO RFIND movd [PBX+N*%d],xmm0 movq xmm7,xmm0 psrlq xmm7,MIRACL psrldq xmm0,MIRACL/4 paddq xmm0,xmm7 movd xmm1,[PBX+N*(%d+1)] paddq xmm0,xmm1 ENDM ; ; REDC_END ; MACRO REDC_END movd [PBX+N*%d],xmm0 movq xmm7,xmm0 psrlq xmm7,MIRACL psrldq xmm0,MIRACL/4 paddq xmm0,xmm7 movd [PBX+N*(%d+1)],xmm0 pop DSI pop DDI } ENDM ; ; ADD_START macro - initialise for add/subtract. Do the first one. ; MACRO ADD_START ASM { push PSI push PDI mov PSI,a mov PBX,b mov PDI,c mov DAX,[PSI] add DAX,[PBX] mov [PDI],DAX ENDM ; ; ADD macro. Add two numbers from memory and store result in memory. ; Don't forget carry bit ; MACRO ADD mov DAX,[PSI+N*%d] adc DAX,[PBX+N*%d] mov [PDI+N*%d],DAX ENDM ; ; ADD_END macro. Catch Carry ; MACRO ADD_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI pop PSI } ENDM ; ; DOUBLE_START macro ; MACRO DOUBLE_START ASM { mov PBX,a mov DAX,[PBX] add [PBX],DAX ENDM ; ; DOUBLE macro ; MACRO DOUBLE mov DAX,[PBX+N*%d] adc [PBX+N*%d],DAX ENDM ; ; DOUBLE_END ; MACRO DOUBLE_END mov DAX,0 adc DAX,DAX mov carry,DAX } ENDM ; ; INC_START macro - initialise for increment/decrement. Do first one. ; MACRO INC_START ASM { push PDI mov PBX,b mov PDI,a mov DAX,[PBX] add [PDI],DAX ENDM ; ; INC macro. Increment number in memory. Don't forget carry ; MACRO INC mov DAX,[PBX+N*%d] adc [PDI+N*%d],DAX ENDM ; ; INC_END macro. Catch Carry ; MACRO INC_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI } ENDM ; ; SUB_START macro. Do first one ; MACRO SUB_START ASM { push PSI push PDI mov PSI,a mov PBX,b mov PDI,c mov DAX,[PSI] sub DAX,[PBX] mov [PDI],DAX ENDM ; ; SUB macro. Subtract two numbers in memory and store result in memory. ; MACRO SUB mov eax,[PSI+N*%d] sbb eax,[PBX+N*%d] mov [PDI+N*%d],DAX ENDM ; ; SUB_END macro ; MACRO SUB_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI pop PSI } ENDM ; ; DEC_START macro ; MACRO DEC_START ASM { push PDI mov PBX,b mov PDI,a mov DAX,[PBX] sub [PDI],DAX ENDM ; ; DEC macro. Decrement from number in memory. Don't forget borrow. ; MACRO DEC mov DAX,[PBX+N*%d] sbb [PDI+N*%d],DAX ENDM ; ; DEC_END macro. Catch carry ; MACRO DEC_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI } ENDM ; ; KADD_START macro. Zero carry flag. ; MACRO KADD_START ASM { push PSI push PDI mov PSI,a mov PBX,b mov PDI,c mov PCX,n xor DAX,DAX k%d: ENDM ; ; KASL macro. Important that carry flag is undisturbed ; MACRO KASL dec PCX je k%d lea PSI,[PSI+N*%d] lea PBX,[PBX+N*%d] lea PDI,[PDI+N*%d] jmp k%d k%d: ENDM ; ; KADD_END macro ; MACRO KADD_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI pop PSI } ENDM ; ; KINC_START macro. Zero Carry Flag ; MACRO KINC_START ASM { push PDI mov PDI,a mov PBX,b mov PCX,n xor DAX,DAX k%d: ENDM ; ; KIDL macro. Important that carry flag is undisturbed! ; MACRO KIDL dec PCX je k%d lea PBX,[PBX+N*%d] lea PDI,[PDI+N*%d] jmp k%d k%d: ENDM ; ; KINC_END macro ; MACRO KINC_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI } ENDM ; ; KDEC_START macro. Zero Carry flag ; MACRO KDEC_START ASM { push PDI mov PDI,a mov PBX,b mov PCX,n xor DAX,DAX k%d: ENDM ; ; KDEC_END macro ; MACRO KDEC_END mov DAX,0 adc DAX,DAX mov carry,DAX pop PDI } ENDM