github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/vector/compare/axpy_arm64.s (about)

     1  #include "textflag.h"
     2  
     3  // func ArmAxpyUnsafe(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
     4  TEXT ·ArmAxpyUnsafe(SB), NOSPLIT, $0-48
     5  	FMOVS alpha+0(FP), F0
     6  
     7  	MOVD  xs+8(FP),    R0
     8  	MOVD  incx+16(FP), R1
     9  
    10  	MOVD  ys+24(FP),   R2
    11  	MOVD  incy+32(FP), R3
    12  
    13  	MOVD  n+40(FP), R4
    14  
    15  	MOVD ZR, R5 // i
    16  	MOVD ZR, R6 // xi
    17  	MOVD ZR, R7 // yi
    18  
    19  	JMP   check_limit
    20  
    21  loop:
    22  	FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
    23  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
    24  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
    25  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
    26  
    27  	ADD  $1, R5, R5 // i++
    28  	ADD  R6, R1, R6 // xi += incx
    29  	ADD  R7, R3, R7 // yi += incy
    30  
    31  check_limit:
    32  	CMP  R5, R4
    33  	BHI  loop
    34  	RET
    35  
    36  // func ArmAxpyUnsafeX(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
    37  TEXT ·ArmAxpyUnsafeX(SB), NOSPLIT, $0-48
    38  	FMOVS alpha+0(FP), F0
    39  
    40  	MOVD  xs+8(FP),    R0
    41  	MOVD  incx+16(FP), R1
    42  
    43  	MOVD  ys+24(FP),   R2
    44  	MOVD  incy+32(FP), R3
    45  
    46  	MOVD  n+40(FP), R4
    47  
    48  	MOVD ZR, R6 // xi
    49  	MOVD ZR, R7 // yi
    50  
    51  	JMP   check_limit
    52  
    53  loop:
    54  	FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
    55  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
    56  	// FMADDS A, B, C, D ==> D := A*C + B
    57  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
    58  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
    59  
    60  	SUB  $1, R4, R4 // n--
    61  	ADD  R6, R1, R6 // xi += incx
    62  	ADD  R7, R3, R7 // yi += incy
    63  
    64  check_limit:
    65  	CBNZ R4, loop
    66  	RET
    67  
    68  // func ArmAxpyPointer(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
    69  TEXT ·ArmAxpyPointer(SB), NOSPLIT, $0-48
    70  	FMOVS alpha+0(FP), F0
    71  
    72  	MOVD  xs+8(FP),    R0
    73  	MOVD  incx+16(FP), R1
    74  
    75  	MOVD  ys+24(FP),   R2
    76  	MOVD  incy+32(FP), R3
    77  
    78  	MOVD  n+40(FP), R4
    79  	LSL   $2, R4, R4
    80  	MADD  R4, R0, R1, R4  // MADD A, B, C, D ==> D := A*C + B
    81  
    82  	JMP   check_limit
    83  
    84  loop:
    85  	FMOVS  (R0), F1        // f1 = *xs
    86  	FMOVS  (R2), F2        // f2 = *ys
    87  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
    88  	FMOVS  F2, (R2)        // ys[yi] = f1
    89  
    90  	ADD  R1<<2, R0, R0 // xs++
    91  	ADD  R3<<2, R2, R2 // ys++
    92  
    93  check_limit:
    94  	CMP  R0, R4
    95  	BHI  loop
    96  	RET
    97  
    98  // func ArmAxpyPointerLoop(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
    99  TEXT ·ArmAxpyPointerLoop(SB), NOSPLIT, $0-48
   100  	FMOVS alpha+0(FP), F0
   101  
   102  	MOVD  xs+8(FP),    R0
   103  	MOVD  incx+16(FP), R1
   104  
   105  	MOVD  ys+24(FP),   R2
   106  	MOVD  incy+32(FP), R3
   107  
   108  	MOVD  n+40(FP), R4
   109  	MOVD  ZR, R5
   110  
   111  	JMP   check_limit
   112  
   113  loop:
   114  	FMOVS  (R0), F1        // f1 = *xs
   115  	FMOVS  (R2), F2        // f2 = *ys
   116  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
   117  	FMOVS  F2, (R2)        // ys[yi] = f1
   118  
   119  	ADD  $1, R5, R5
   120  	ADD  R1<<2, R0, R0 // xs++
   121  	ADD  R3<<2, R2, R2 // ys++
   122  
   123  check_limit:
   124  	CMP  R5, R4
   125  	BHI  loop
   126  	RET
   127  
   128  // func ArmAxpyPointerLoopX(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
   129  TEXT ·ArmAxpyPointerLoopX(SB), NOSPLIT, $0-48
   130  	FMOVS alpha+0(FP), F0
   131  
   132  	MOVD  xs+8(FP),    R0
   133  	MOVD  incx+16(FP), R1
   134  
   135  	MOVD  ys+24(FP),   R2
   136  	MOVD  incy+32(FP), R3
   137  
   138  	MOVD  n+40(FP), R4
   139  
   140  	JMP   check_limit
   141  
   142  loop:
   143  	FMOVS  (R0), F1        // f1 = *xs
   144  	FMOVS  (R2), F2        // f2 = *ys
   145  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
   146  	FMOVS  F2, (R2)        // ys[yi] = f1
   147  
   148  	SUB  $1, R4, R4
   149  	ADD  R1<<2, R0, R0 // xs++
   150  	ADD  R3<<2, R2, R2 // ys++
   151  
   152  check_limit:
   153  	CBNZ  R4, loop
   154  	RET
   155  
   156  // func ArmAxpyUnsafeXR4(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
   157  TEXT ·ArmAxpyUnsafeXR4(SB), NOSPLIT, $0-48
   158  	FMOVS alpha+0(FP), F0
   159  
   160  	MOVD  xs+8(FP),    R0
   161  	MOVD  incx+16(FP), R1
   162  
   163  	MOVD  ys+24(FP),   R2
   164  	MOVD  incy+32(FP), R3
   165  
   166  	MOVD  n+40(FP), R4 // n
   167  
   168  	MOVD ZR, R6 // xi
   169  	MOVD ZR, R7 // yi
   170  
   171  	JMP  check_limit_unroll
   172  
   173  loop_unroll:
   174      FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   175  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
   176  	FMADDS F0, F2, F1, F2  // f1 = alpha * f1 + f2
   177  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
   178  
   179  	ADD  R6, R1, R6 // xi += incx
   180  	ADD  R7, R3, R7 // yi += incy
   181  	FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   182  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
   183  	FMADDS F0, F2, F1, F2  // f1 = alpha * f1 + f2
   184  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
   185  
   186  	ADD  R6, R1, R6 // xi += incx
   187  	ADD  R7, R3, R7 // yi += incy
   188      FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   189  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
   190  	FMADDS F0, F2, F1, F2  // f1 = alpha * f1 + f2
   191  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
   192  
   193  	ADD  R6, R1, R6 // xi += incx
   194  	ADD  R7, R3, R7 // yi += incy
   195      FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   196  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
   197  	FMADDS F0, F2, F1, F2  // f1 = alpha * f1 + f2
   198  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
   199  
   200  	ADD  R6, R1, R6 // xi += incx
   201  	ADD  R7, R3, R7 // yi += incy
   202  	SUB  $4, R4, R4    // n -= 4
   203  
   204  check_limit_unroll:
   205  	CMP  $0x04, R4
   206  	BHS  loop_unroll
   207  	JMP  check_limit
   208  
   209  loop:
   210  	FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   211  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
   212  	// FMADDS A, B, C, D ==> D := A*C + B
   213  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
   214  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
   215  
   216  	SUB  $1, R4, R4 // n--
   217  	ADD  R6, R1, R6 // xi += incx
   218  	ADD  R7, R3, R7 // yi += incy
   219  
   220  check_limit:
   221  	CBNZ R4, loop
   222  	RET
   223  
   224  // func ArmAxpyUnsafeInterleaveXR4(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
   225  TEXT ·ArmAxpyUnsafeInterleaveXR4(SB), NOSPLIT, $0-48
   226  	FMOVS alpha+0(FP), F0
   227  
   228  	MOVD  xs+8(FP),    R0
   229  	MOVD  incx+16(FP), R1
   230  
   231  	MOVD  ys+24(FP),   R2
   232  	MOVD  incy+32(FP), R3
   233  
   234  	MOVD  n+40(FP), R4 // n
   235  
   236  	MOVD ZR, R6 // xi
   237  	MOVD ZR, R7 // yi
   238  
   239  	JMP  check_limit_unroll
   240  
   241  loop_unroll:
   242  	FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   243  	ADD  R6, R1, R6 // xi += incx
   244  	FMOVS  (R0)(R6<<2), F2 // f1 = xs[xi]
   245  	ADD  R6, R1, R6 // xi += incx
   246  	FMOVS  (R0)(R6<<2), F3 // f1 = xs[xi]
   247  	ADD  R6, R1, R6 // xi += incx
   248  	FMOVS  (R0)(R6<<2), F4 // f1 = xs[xi]
   249  	ADD  R6, R1, R6 // xi += incx
   250  
   251  	FMOVS  (R2)(R7<<2), F5 // f2 = ys[yi]
   252  	FMADDS F0, F5, F1, F5  // f1 = alpha * f1 + f2
   253  	FMOVS  F5, (R2)(R7<<2) // ys[yi] = f1
   254  	ADD  R7, R3, R7 // yi += incy
   255  
   256  	FMOVS  (R2)(R7<<2), F5 // f2 = ys[yi]
   257  	FMADDS F0, F5, F2, F5  // f1 = alpha * f1 + f2
   258  	FMOVS  F5, (R2)(R7<<2) // ys[yi] = f1
   259  	ADD  R7, R3, R7 // yi += incy
   260  
   261  	FMOVS  (R2)(R7<<2), F5 // f2 = ys[yi]
   262  	FMADDS F0, F5, F3, F5  // f1 = alpha * f1 + f2
   263  	FMOVS  F5, (R2)(R7<<2) // ys[yi] = f1
   264  	ADD  R7, R3, R7 // yi += incy
   265  
   266  	FMOVS  (R2)(R7<<2), F5 // f2 = ys[yi]
   267  	FMADDS F0, F5, F4, F5  // f1 = alpha * f1 + f2
   268  	FMOVS  F5, (R2)(R7<<2) // ys[yi] = f1
   269  	ADD  R7, R3, R7 // yi += incy
   270  
   271  	SUB  $4, R4, R4    // n -= 4
   272  
   273  check_limit_unroll:
   274  	CMP  $0x04, R4
   275  	BHS  loop_unroll
   276  	JMP  check_limit
   277  
   278  loop:
   279  	FMOVS  (R0)(R6<<2), F1 // f1 = xs[xi]
   280  	FMOVS  (R2)(R7<<2), F2 // f2 = ys[yi]
   281  	// FMADDS A, B, C, D ==> D := A*C + B
   282  	FMADDS F0, F2, F1, F2  // f1 = alpha * xs[xi] + ys[yi]
   283  	FMOVS  F2, (R2)(R7<<2) // ys[yi] = f1
   284  
   285  	SUB  $1, R4, R4 // n--
   286  	ADD  R6, R1, R6 // xi += incx
   287  	ADD  R7, R3, R7 // yi += incy
   288  
   289  check_limit:
   290  	CBNZ R4, loop
   291  	RET
   292  
   293  
   294  // func ArmAxpyPointerLoopXR4(alpha float32, xs *float32, incx uintptr, ys *float32, incy uintptr, n uintptr)
   295  TEXT ·ArmAxpyPointerLoopXR4(SB), NOSPLIT, $0-48
   296  	FMOVS alpha+0(FP), F0
   297  
   298  	MOVD  xs+8(FP),    R0
   299  	MOVD  incx+16(FP), R1
   300  
   301  	MOVD  ys+24(FP),   R2
   302  	MOVD  incy+32(FP), R3
   303  
   304  	MOVD  n+40(FP), R4
   305  
   306  	JMP   check_limit_unroll
   307  
   308  loop_unroll:
   309  	FMOVS  (R0), F1        // f1 = *xs
   310  	FMOVS  (R2), F2        // f2 = *ys
   311  	FMADDS F0, F2, F1, F2  // f1 = alpha * *xs + *ys
   312  	FMOVS  F2, (R2)        // *ys = f1
   313  	ADD    R1<<2, R0, R0   // xs += incx * 4
   314  	ADD    R3<<2, R2, R2   // ys += incy * 4
   315  
   316  	FMOVS  (R0), F1        // f1 = *xs
   317  	FMOVS  (R2), F2        // f2 = *ys
   318  	FMADDS F0, F2, F1, F2  // f1 = alpha * *xs + *ys
   319  	FMOVS  F2, (R2)        // *ys = f1
   320  	ADD    R1<<2, R0, R0   // xs += incx * 4
   321  	ADD    R3<<2, R2, R2   // ys += incy * 4
   322  
   323  	FMOVS  (R0), F1        // f1 = *xs
   324  	FMOVS  (R2), F2        // f2 = *ys
   325  	FMADDS F0, F2, F1, F2  // f1 = alpha * *xs + *ys
   326  	FMOVS  F2, (R2)        // *ys = f1
   327  	ADD    R1<<2, R0, R0   // xs += incx * 4
   328  	ADD    R3<<2, R2, R2   // ys += incy * 4
   329  
   330  	FMOVS  (R0), F1        // f1 = *xs
   331  	FMOVS  (R2), F2        // f2 = *ys
   332  	FMADDS F0, F2, F1, F2  // f1 = alpha * *xs + *ys
   333  	FMOVS  F2, (R2)        // *ys = f1
   334  	ADD    R1<<2, R0, R0   // xs += incx * 4
   335  	ADD    R3<<2, R2, R2   // ys += incy * 4
   336  
   337  	SUB  $4, R4, R4
   338  
   339  check_limit_unroll:
   340  	CMP  $0x04, R4
   341  	BHS  loop_unroll
   342  	JMP   check_limit
   343  
   344  loop:
   345  	FMOVS  (R0), F1        // f1 = *xs
   346  	FMOVS  (R2), F2        // f2 = *ys
   347  	FMADDS F0, F2, F1, F2  // f1 = alpha * *xs + *ys
   348  	FMOVS  F2, (R2)        // *ys = f1
   349  	ADD    R1<<2, R0, R0   // xs += incx * 4
   350  	ADD    R3<<2, R2, R2   // ys += incy * 4
   351  
   352  	SUB $1, R4, R4
   353  
   354  check_limit:
   355  	CBNZ  R4, loop
   356  
   357  	RET