github.com/gopherd/gonum@v0.0.4/internal/asm/f64/abssuminc_amd64.s (about)

     1  // Copyright ©2016 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build !noasm,!gccgo,!safe
     6  
     7  #include "textflag.h"
     8  
     9  // func L1NormInc(x []float64, n, incX int) (sum float64)
    10  TEXT ·L1NormInc(SB), NOSPLIT, $0
    11  	MOVQ  x_base+0(FP), SI // SI = &x
    12  	MOVQ  n+24(FP), CX     // CX = n
    13  	MOVQ  incX+32(FP), AX  // AX =  increment * sizeof( float64 )
    14  	SHLQ  $3, AX
    15  	MOVQ  AX, DX           // DX = AX * 3
    16  	IMULQ $3, DX
    17  	PXOR  X0, X0           // p_sum_i = 0
    18  	PXOR  X1, X1
    19  	PXOR  X2, X2
    20  	PXOR  X3, X3
    21  	PXOR  X4, X4
    22  	PXOR  X5, X5
    23  	PXOR  X6, X6
    24  	PXOR  X7, X7
    25  	CMPQ  CX, $0           // if CX == 0 { return 0 }
    26  	JE    absum_end
    27  	MOVQ  CX, BX
    28  	ANDQ  $7, BX           // BX = n % 8
    29  	SHRQ  $3, CX           // CX = floor( n / 8 )
    30  	JZ    absum_tail_start // if CX == 0 { goto absum_tail_start }
    31  
    32  absum_loop: // do {
    33  	// p_sum = max( p_sum + x[i], p_sum - x[i] )
    34  	MOVSD  (SI), X8        // X_i[0] = x[i]
    35  	MOVSD  (SI)(AX*1), X9
    36  	MOVSD  (SI)(AX*2), X10
    37  	MOVSD  (SI)(DX*1), X11
    38  	LEAQ   (SI)(AX*4), SI  // SI = SI + 4
    39  	MOVHPD (SI), X8        // X_i[1] = x[i+4]
    40  	MOVHPD (SI)(AX*1), X9
    41  	MOVHPD (SI)(AX*2), X10
    42  	MOVHPD (SI)(DX*1), X11
    43  	ADDPD  X8, X0          // p_sum_i += X_i  ( positive values )
    44  	ADDPD  X9, X2
    45  	ADDPD  X10, X4
    46  	ADDPD  X11, X6
    47  	SUBPD  X8, X1          // p_sum_(i+1) -= X_i  ( negative values )
    48  	SUBPD  X9, X3
    49  	SUBPD  X10, X5
    50  	SUBPD  X11, X7
    51  	MAXPD  X1, X0          // p_sum_i = max( p_sum_i, p_sum_(i+1) )
    52  	MAXPD  X3, X2
    53  	MAXPD  X5, X4
    54  	MAXPD  X7, X6
    55  	MOVAPS X0, X1          // p_sum_(i+1) = p_sum_i
    56  	MOVAPS X2, X3
    57  	MOVAPS X4, X5
    58  	MOVAPS X6, X7
    59  	LEAQ   (SI)(AX*4), SI  // SI = SI + 4
    60  	LOOP   absum_loop      // } while --CX > 0
    61  
    62  	// p_sum_0 = \sum_{i=1}^{3}( p_sum_(i*2) )
    63  	ADDPD X3, X0
    64  	ADDPD X5, X7
    65  	ADDPD X7, X0
    66  
    67  	// p_sum_0[0] = p_sum_0[0] + p_sum_0[1]
    68  	MOVAPS X0, X1
    69  	SHUFPD $0x3, X0, X0 // lower( p_sum_0 ) = upper( p_sum_0 )
    70  	ADDSD  X1, X0
    71  	CMPQ   BX, $0
    72  	JE     absum_end    // if BX == 0 { goto absum_end }
    73  
    74  absum_tail_start: // Reset loop registers
    75  	MOVQ  BX, CX // Loop counter:  CX = BX
    76  	XORPS X8, X8 // X_8 = 0
    77  
    78  absum_tail: // do {
    79  	// p_sum += max( p_sum + x[i], p_sum - x[i] )
    80  	MOVSD (SI), X8   // X_8 = x[i]
    81  	MOVSD X0, X1     // p_sum_1 = p_sum_0
    82  	ADDSD X8, X0     // p_sum_0 += X_8
    83  	SUBSD X8, X1     // p_sum_1 -= X_8
    84  	MAXSD X1, X0     // p_sum_0 = max( p_sum_0, p_sum_1 )
    85  	ADDQ  AX, SI     // i++
    86  	LOOP  absum_tail // } while --CX > 0
    87  
    88  absum_end: // return p_sum_0
    89  	MOVSD X0, sum+40(FP)
    90  	RET