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