nb_kernel400_ia32_sse.intel_syntax.s

来自「最著名最快的分子模拟软件」· S 代码 · 共 1,730 行 · 第 1/3 页

S
1,730
字号
;#;# $Id: nb_kernel400_ia32_sse.intel_syntax.s,v 1.1.2.1 2006/03/01 15:18:31 lindahl Exp $;#;# Gromacs 4.0                         Copyright (c) 1991-2003 ;# David van der Spoel, Erik Lindahl;#;# This program is free software; you can redistribute it and/or;# modify it under the terms of the GNU General Public License;# as published by the Free Software Foundation; either version 2;# of the License, or (at your option) any later version.;#;# To help us fund GROMACS development, we humbly ask that you cite;# the research papers on the package. Check out http://www.gromacs.org;# ;# And Hey:;# Gnomes, ROck Monsters And Chili Sauce;#;# These files require GNU binutils 2.10 or later, since we;# use intel syntax for portability, or a recent version ;# of NASM that understands Extended 3DNow and SSE2 instructions.;# (NASM is normally only used with MS Visual C++).;# Since NASM and gnu as disagree on some definitions and use ;# completely different preprocessing options I have to introduce a;# trick: NASM uses ';' for comments, while gnu as uses '#' on x86.;# Gnu as treats ';' as a line break, i.e. ignores it. This is the;# reason why all comments need both symbols...;# The source is written for GNU as, with intel syntax. When you use;# NASM we redefine a couple of things. The false if-statement around ;# the following code is seen by GNU as, but NASM doesn't see it, so ;# the code inside is read by NASM but not gcc.; .if 0    # block below only read by NASM%define .section	section%define .long		dd%define .align		align%define .globl		global;# NASM only wants 'dword', not 'dword ptr'.%define ptr.equiv          .equiv                  2   %1 equ %2%endmacro; .endif                   # End of NASM-specific block; .intel_syntax noprefix   # Line only read by gnu as	.globl nb_kernel400_ia32_sse.globl _nb_kernel400_ia32_ssenb_kernel400_ia32_sse:	_nb_kernel400_ia32_sse:	.equiv          nb400_p_nri,            8.equiv          nb400_iinr,             12.equiv          nb400_jindex,           16.equiv          nb400_jjnr,             20.equiv          nb400_shift,            24.equiv          nb400_shiftvec,         28.equiv          nb400_fshift,           32.equiv          nb400_gid,              36.equiv          nb400_pos,              40.equiv          nb400_faction,          44.equiv          nb400_charge,           48.equiv          nb400_p_facel,          52.equiv          nb400_argkrf,           56.equiv          nb400_argcrf,           60.equiv          nb400_Vc,               64.equiv          nb400_type,             68.equiv          nb400_p_ntype,          72.equiv          nb400_vdwparam,         76.equiv          nb400_Vvdw,             80.equiv          nb400_p_tabscale,       84.equiv          nb400_VFtab,            88.equiv          nb400_invsqrta,         92.equiv          nb400_dvda,             96.equiv          nb400_p_gbtabscale,     100.equiv          nb400_GBtab,            104.equiv          nb400_p_nthreads,       108.equiv          nb400_count,            112.equiv          nb400_mtx,              116.equiv          nb400_outeriter,        120.equiv          nb400_inneriter,        124.equiv          nb400_work,             128	;# stack offsets for local variables  	;# bottom of stack is cache-aligned for sse use .equiv          nb400_ix,               0.equiv          nb400_iy,               16.equiv          nb400_iz,               32.equiv          nb400_iq,               48.equiv          nb400_dx,               64.equiv          nb400_dy,               80.equiv          nb400_dz,               96.equiv          nb400_two,              112.equiv          nb400_gbtsc,            128.equiv          nb400_qq,               144.equiv          nb400_r,                160.equiv          nb400_vctot,            176.equiv          nb400_fix,              192.equiv          nb400_fiy,              208.equiv          nb400_fiz,              224.equiv          nb400_half,             240.equiv          nb400_three,            256.equiv          nb400_isai,             272.equiv          nb400_isaprod,          288.equiv          nb400_dvdasum,          304.equiv          nb400_gbscale,          320.equiv          nb400_is3,              336.equiv          nb400_ii3,              340.equiv          nb400_ii,               344.equiv          nb400_innerjjnr,        348.equiv          nb400_innerk,           352.equiv          nb400_n,                356.equiv          nb400_nn1,              360.equiv          nb400_jnra,             364.equiv          nb400_jnrb,             368.equiv          nb400_jnrc,             372.equiv          nb400_jnrd,             376.equiv          nb400_nri,              380.equiv          nb400_facel,            384.equiv          nb400_nouter,           388.equiv          nb400_ninner,           392.equiv          nb400_salign,           396	push ebp	mov ebp,esp	    	push eax    	push ebx    	push ecx    	push edx	push esi	push edi	sub esp, 400		;# local stack space 	mov  eax, esp	and  eax, 0xf	sub esp, eax	mov [esp + nb400_salign], eax	emms	;# Move args passed by reference to stack	mov ecx, [ebp + nb400_p_nri]	mov esi, [ebp + nb400_p_facel]	mov ecx, [ecx]	mov esi, [esi]	mov [esp + nb400_nri], ecx	mov [esp + nb400_facel], esi	;# zero iteration counters	mov eax, 0	mov [esp + nb400_nouter], eax	mov [esp + nb400_ninner], eax	mov eax, [ebp + nb400_p_gbtabscale]	movss xmm3, [eax]	shufps xmm3, xmm3, 0	movaps [esp + nb400_gbtsc], xmm3	;# create constant floating-point factors on stack	mov eax, 0x3f000000     ;# constant 0.5 in IEEE (hex)	mov [esp + nb400_half], eax	movss xmm1, [esp + nb400_half]	shufps xmm1, xmm1, 0    ;# splat to all elements	movaps xmm2, xmm1       	addps  xmm2, xmm2	;# constant 1.0	movaps xmm3, xmm2	addps  xmm2, xmm2	;# constant 2.0	addps  xmm3, xmm2	;# constant 3.0	movaps [esp + nb400_half],  xmm1	movaps [esp + nb400_two],  xmm2	movaps [esp + nb400_three],  xmm3.nb400_threadloop:        mov   esi, [ebp + nb400_count]          ;# pointer to sync counter        mov   eax, [esi].nb400_spinlock:        mov   ebx, eax                          ;# ebx=*count=nn0        add   ebx, 1                           ;# ebx=nn1=nn0+10        lock        cmpxchg [esi], ebx                      ;# write nn1 to *counter,                                                ;# if it hasnt changed.                                                ;# or reread *counter to eax.        pause                                   ;# -> better p4 performance        jnz .nb400_spinlock        ;# if(nn1>nri) nn1=nri        mov ecx, [esp + nb400_nri]        mov edx, ecx        sub ecx, ebx        cmovle ebx, edx                         ;# if(nn1>nri) nn1=nri        ;# Cleared the spinlock if we got here.        ;# eax contains nn0, ebx contains nn1.        mov [esp + nb400_n], eax        mov [esp + nb400_nn1], ebx        sub ebx, eax                            ;# calc number of outer lists	mov esi, eax				;# copy n to esi        jg  .nb400_outerstart        jmp .nb400_end.nb400_outerstart:	;# ebx contains number of outer iterations	add ebx, [esp + nb400_nouter]	mov [esp + nb400_nouter], ebx.nb400_outer:	mov   eax, [ebp + nb400_shift]      ;# eax = pointer into shift[] 	mov   ebx, [eax + esi*4]		;# ebx=shift[n] 		lea   ebx, [ebx + ebx*2]    ;# ebx=3*is 	mov   [esp + nb400_is3],ebx    	;# store is3 	mov   eax, [ebp + nb400_shiftvec]   ;# eax = base of shiftvec[] 	movss xmm0, [eax + ebx*4]	movss xmm1, [eax + ebx*4 + 4]	movss xmm2, [eax + ebx*4 + 8] 	mov   ecx, [ebp + nb400_iinr]       ;# ecx = pointer into iinr[] 		mov   ebx, [ecx + esi*4]	    ;# ebx =ii 	mov   [esp + nb400_ii], ebx		mov   edx, [ebp + nb400_charge]	movss xmm3, [edx + ebx*4]		mulss xmm3, [esp + nb400_facel]	shufps xmm3, xmm3, 0	mov   edx, [ebp + nb400_invsqrta]	;# load invsqrta[ii]	movss xmm4, [edx + ebx*4]	shufps xmm4, xmm4, 0	lea   ebx, [ebx + ebx*2]	;# ebx = 3*ii=ii3 	mov   eax, [ebp + nb400_pos]    ;# eax = base of pos[]  	addss xmm0, [eax + ebx*4]	addss xmm1, [eax + ebx*4 + 4]	addss xmm2, [eax + ebx*4 + 8]	movaps [esp + nb400_iq], xmm3	movaps [esp + nb400_isai], xmm4		shufps xmm0, xmm0, 0	shufps xmm1, xmm1, 0	shufps xmm2, xmm2, 0	movaps [esp + nb400_ix], xmm0	movaps [esp + nb400_iy], xmm1	movaps [esp + nb400_iz], xmm2	mov   [esp + nb400_ii3], ebx		;# clear vctot and i forces 	xorps xmm4, xmm4	movaps [esp + nb400_vctot], xmm4	movaps [esp + nb400_dvdasum], xmm4	movaps [esp + nb400_fix], xmm4	movaps [esp + nb400_fiy], xmm4	movaps [esp + nb400_fiz], xmm4		mov   eax, [ebp + nb400_jindex]	mov   ecx, [eax + esi*4]	     ;# jindex[n] 	mov   edx, [eax + esi*4 + 4]	     ;# jindex[n+1] 	sub   edx, ecx               ;# number of innerloop atoms 	mov   esi, [ebp + nb400_pos]	mov   edi, [ebp + nb400_faction]		mov   eax, [ebp + nb400_jjnr]	shl   ecx, 2	add   eax, ecx	mov   [esp + nb400_innerjjnr], eax     ;# pointer to jjnr[nj0] 	mov   ecx, edx	sub   edx,  4	add   ecx, [esp + nb400_ninner]	mov   [esp + nb400_ninner], ecx	add   edx, 0	mov   [esp + nb400_innerk], edx    ;# number of innerloop atoms 	jge   .nb400_unroll_loop	jmp   .nb400_finish_inner.nb400_unroll_loop:		;# quad-unroll innerloop here 	mov   edx, [esp + nb400_innerjjnr]     ;# pointer to jjnr[k] 	mov   eax, [edx]		mov   ebx, [edx + 4]              	mov   ecx, [edx + 8]            	mov   edx, [edx + 12]         ;# eax-edx=jnr1-4 	add dword ptr [esp + nb400_innerjjnr],  16 ;# advance pointer (unrolled 4) 	;# load isaj	mov esi, [ebp + nb400_invsqrta]	movss xmm3, [esi + eax*4]	movss xmm4, [esi + ecx*4]	movss xmm6, [esi + ebx*4]	movss xmm7, [esi + edx*4]	movaps xmm2, [esp + nb400_isai]	shufps xmm3, xmm6, 0 	shufps xmm4, xmm7, 0 	shufps xmm3, xmm4, 136  ;# constant 10001000 ;# all isaj in xmm3 	mulps  xmm2, xmm3			movaps [esp + nb400_isaprod], xmm2		movaps xmm1, xmm2	mulps xmm1, [esp + nb400_gbtsc]	movaps [esp + nb400_gbscale], xmm1		mov esi, [ebp + nb400_charge]    ;# base of charge[] 		movss xmm3, [esi + eax*4]	movss xmm4, [esi + ecx*4]	movss xmm6, [esi + ebx*4]	movss xmm7, [esi + edx*4]	mulps xmm2, [esp + nb400_iq]	shufps xmm3, xmm6, 0 	shufps xmm4, xmm7, 0 	shufps xmm3, xmm4, 136  ;# constant 10001000 ;# all charges in xmm3  	mulps  xmm3, xmm2	movaps [esp + nb400_qq], xmm3			mov esi, [ebp + nb400_pos]       ;# base of pos[] 	mov [esp + nb400_jnra], eax	mov [esp + nb400_jnrb], ebx	mov [esp + nb400_jnrc], ecx	mov [esp + nb400_jnrd], edx		lea   eax, [eax + eax*2]     ;# replace jnr with j3 	lea   ebx, [ebx + ebx*2]		lea   ecx, [ecx + ecx*2]    	lea   edx, [edx + edx*2]		;# move four coordinates to xmm0-xmm2 		movlps xmm4, [esi + eax*4]	movlps xmm5, [esi + ecx*4]	movss xmm2, [esi + eax*4 + 8]	movss xmm6, [esi + ecx*4 + 8]	movhps xmm4, [esi + ebx*4]	movhps xmm5, [esi + edx*4]	movss xmm0, [esi + ebx*4 + 8]	movss xmm1, [esi + edx*4 + 8]	shufps xmm2, xmm0, 0	shufps xmm6, xmm1, 0		movaps xmm0, xmm4	movaps xmm1, xmm4	shufps xmm2, xmm6, 136  ;# constant 10001000		shufps xmm0, xmm5, 136  ;# constant 10001000	shufps xmm1, xmm5, 221  ;# constant 11011101			;# move ix-iz to xmm4-xmm6 	movaps xmm4, [esp + nb400_ix]	movaps xmm5, [esp + nb400_iy]	movaps xmm6, [esp + nb400_iz]	;# calc dr 	subps xmm4, xmm0	subps xmm5, xmm1	subps xmm6, xmm2	;# store dr 	movaps [esp + nb400_dx], xmm4	movaps [esp + nb400_dy], xmm5	movaps [esp + nb400_dz], xmm6	;# square it 	mulps xmm4,xmm4	mulps xmm5,xmm5	mulps xmm6,xmm6	addps xmm4, xmm5	addps xmm4, xmm6	;# rsq in xmm4 	rsqrtps xmm5, xmm4	;# lookup seed in xmm5 	movaps xmm2, xmm5	mulps xmm5, xmm5	movaps xmm1, [esp + nb400_three]	mulps xmm5, xmm4	;# rsq*lu*lu 				movaps xmm0, [esp + nb400_half]	subps xmm1, xmm5	;# constant 30-rsq*lu*lu 	mulps xmm1, xmm2		mulps xmm0, xmm1	;# xmm0=rinv 	mulps xmm4, xmm0	;# xmm4=r	movaps [esp + nb400_r], xmm4	mulps xmm4, [esp + nb400_gbscale]	movhlps xmm5, xmm4	cvttps2pi mm6, xmm4	cvttps2pi mm7, xmm5	;# mm6/mm7 contain lu indices 	cvtpi2ps xmm6, mm6	cvtpi2ps xmm5, mm7	movlhps xmm6, xmm5	subps xmm4, xmm6		movaps xmm1, xmm4	;# xmm1=eps 	movaps xmm2, xmm1		mulps  xmm2, xmm2	;# xmm2=eps2 	pslld mm6, 2	pslld mm7, 2	movd mm0, eax		movd mm1, ebx	movd mm2, ecx	movd mm3, edx	mov  esi, [ebp + nb400_GBtab]	movd eax, mm6	psrlq mm6, 32	movd ecx, mm7	psrlq mm7, 32	movd ebx, mm6	movd edx, mm7	;# load coulomb table	movaps xmm4, [esi + eax*4]	movaps xmm5, [esi + ebx*4]	movaps xmm6, [esi + ecx*4]	movaps xmm7, [esi + edx*4]	;# transpose, using xmm3 for scratch	movaps xmm3, xmm6	shufps xmm3, xmm7, 0xEE 	shufps xmm6, xmm7, 0x44	movaps xmm7, xmm4	shufps xmm7, xmm5, 0xEE	shufps xmm4, xmm5, 0x44	movaps xmm5, xmm4	shufps xmm5, xmm6, 0xDD	shufps xmm4, xmm6, 0x88	movaps xmm6, xmm7	shufps xmm6, xmm3, 0x88	shufps xmm7, xmm3, 0xDD	;# coulomb table ready, in xmm4-xmm7  			mulps  xmm6, xmm1	;# xmm6=Geps 	mulps  xmm7, xmm2	;# xmm7=Heps2 	addps  xmm5, xmm6	addps  xmm5, xmm7	;# xmm5=Fp 		mulps  xmm7, [esp + nb400_two]	;# two*Heps2 	movaps xmm3, [esp + nb400_qq]	addps  xmm7, xmm6	addps  xmm7, xmm5 ;# xmm7=FF 	mulps  xmm5, xmm1 ;# xmm5=eps*Fp 	addps  xmm5, xmm4 ;# xmm5=VV 	mulps  xmm5, xmm3 ;# vcoul=qq*VV  	mulps  xmm3, xmm7 ;# fijC=FF*qq 	;# at this point mm5 contains vcoul and mm3 fijC	;# get jnr from stack	mov eax, [esp + nb400_jnra]	mov ebx, [esp + nb400_jnrb]	mov ecx, [esp + nb400_jnrc]	mov edx, [esp + nb400_jnrd]		mov esi, [ebp + nb400_dvda]		;# Calculate dVda	xorps  xmm7, xmm7	mulps xmm3, [esp + nb400_gbscale]	movaps xmm6, xmm3	mulps  xmm6, [esp + nb400_r]	addps  xmm6, xmm5	addps  xmm5, [esp + nb400_vctot]	movaps [esp + nb400_vctot], xmm5 	;# xmm6=(vcoul+fijC*r)	subps  xmm7, xmm6	movaps xmm6, xmm7		;# update dvdasum	addps  xmm7, [esp + nb400_dvdasum]	movaps [esp + nb400_dvdasum], xmm7 	;# update j atoms dvdaj	movhlps xmm7, xmm6	movaps  xmm5, xmm6	movaps  xmm4, xmm7	shufps  xmm5, xmm5, 0x1	shufps  xmm4, xmm4, 0x1	;# xmm6=dvdaj1 xmm5=dvdaj2 xmm7=dvdaj3 xmm4=dvdaj4	addss  xmm6, [esi + eax*4]	addss  xmm5, [esi + ebx*4]	addss  xmm7, [esi + ecx*4]	addss  xmm4, [esi + edx*4]	movss  [esi + eax*4], xmm6	movss  [esi + ebx*4], xmm5	movss  [esi + ecx*4], xmm7	movss  [esi + edx*4], xmm4		xorps  xmm4, xmm4		mulps xmm3, xmm0	subps  xmm4, xmm3	movaps xmm0, [esp + nb400_dx]	movaps xmm1, [esp + nb400_dy]	movaps xmm2, [esp + nb400_dz]	movd eax, mm0		movd ebx, mm1	movd ecx, mm2	movd edx, mm3	mov    edi, [ebp + nb400_faction]	mulps  xmm0, xmm4	mulps  xmm1, xmm4	mulps  xmm2, xmm4	;# xmm0-xmm2 contains tx-tz (partial force) 	;# now update f_i 	movaps xmm3, [esp + nb400_fix]	movaps xmm4, [esp + nb400_fiy]	movaps xmm5, [esp + nb400_fiz]	addps  xmm3, xmm0	addps  xmm4, xmm1	addps  xmm5, xmm2	movaps [esp + nb400_fix], xmm3	movaps [esp + nb400_fiy], xmm4	movaps [esp + nb400_fiz], xmm5	;# the fj's - start by accumulating x & y forces from memory 	movlps xmm4, [edi + eax*4]	movlps xmm6, [edi + ecx*4]	movhps xmm4, [edi + ebx*4]	movhps xmm6, [edi + edx*4]	movaps xmm3, xmm4	shufps xmm3, xmm6, 136  ;# constant 10001000	shufps xmm4, xmm6, 221  ;# constant 11011101			      	;# now xmm3-xmm5 contains fjx, fjy, fjz 	subps  xmm3, xmm0	subps  xmm4, xmm1		;# unpack them back so we can store them - first x & y in xmm3/xmm4 	movaps xmm6, xmm3	unpcklps xmm6, xmm4	unpckhps xmm3, xmm4		;# xmm6(l)=x & y for j1, (h) for j2 	;# xmm3(l)=x & y for j3, (h) for j4 	movlps [edi + eax*4], xmm6	movlps [edi + ecx*4], xmm3		movhps [edi + ebx*4], xmm6	movhps [edi + edx*4], xmm3	;# and the z forces 	movss  xmm4, [edi + eax*4 + 8]	movss  xmm5, [edi + ebx*4 + 8]	movss  xmm6, [edi + ecx*4 + 8]	movss  xmm7, [edi + edx*4 + 8]	subss  xmm4, xmm2	shufps xmm2, xmm2, 229  ;# constant 11100101	subss  xmm5, xmm2	shufps xmm2, xmm2, 234  ;# constant 11101010	subss  xmm6, xmm2	shufps xmm2, xmm2, 255  ;# constant 11111111	subss  xmm7, xmm2	movss  [edi + eax*4 + 8], xmm4	movss  [edi + ebx*4 + 8], xmm5	movss  [edi + ecx*4 + 8], xmm6	movss  [edi + edx*4 + 8], xmm7		;# should we do one more iteration? 	sub dword ptr [esp + nb400_innerk],  4	jl    .nb400_finish_inner	jmp   .nb400_unroll_loop.nb400_finish_inner:	;# check if at least two particles remain 	add dword ptr [esp + nb400_innerk],  4	mov   edx, [esp + nb400_innerk]	and   edx, 2	jnz   .nb400_dopair	jmp   .nb400_checksingle.nb400_dopair:		mov   ecx, [esp + nb400_innerjjnr]	

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?