github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/math/big/arith_s390x.s (about) 1 // Copyright 2016 The Go 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 !math_big_pure_go,s390x 6 7 #include "textflag.h" 8 9 // This file provides fast assembly versions for the elementary 10 // arithmetic operations on vectors implemented in arith.go. 11 12 TEXT ·hasVectorFacility(SB),NOSPLIT,$24-1 13 MOVD $x-24(SP), R1 14 XC $24, 0(R1), 0(R1) // clear the storage 15 MOVD $2, R0 // R0 is the number of double words stored -1 16 WORD $0xB2B01000 // STFLE 0(R1) 17 XOR R0, R0 // reset the value of R0 18 MOVBZ z-8(SP), R1 19 AND $0x40, R1 20 BEQ novector 21 vectorinstalled: 22 // check if the vector instruction has been enabled 23 VLEIB $0, $0xF, V16 24 VLGVB $0, V16, R1 25 CMPBNE R1, $0xF, novector 26 MOVB $1, ret+0(FP) // have vx 27 RET 28 novector: 29 MOVB $0, ret+0(FP) // no vx 30 RET 31 32 TEXT ·mulWW(SB),NOSPLIT,$0 33 MOVD x+0(FP), R3 34 MOVD y+8(FP), R4 35 MULHDU R3, R4 36 MOVD R10, z1+16(FP) 37 MOVD R11, z0+24(FP) 38 RET 39 40 // func divWW(x1, x0, y Word) (q, r Word) 41 TEXT ·divWW(SB),NOSPLIT,$0 42 MOVD x1+0(FP), R10 43 MOVD x0+8(FP), R11 44 MOVD y+16(FP), R5 45 WORD $0xb98700a5 // dlgr r10,r5 46 MOVD R11, q+24(FP) 47 MOVD R10, r+32(FP) 48 RET 49 50 // DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11 51 // func addVV(z, x, y []Word) (c Word) 52 53 54 TEXT ·addVV(SB),NOSPLIT,$0 55 MOVD addvectorfacility+0x00(SB),R1 56 BR (R1) 57 58 TEXT ·addVV_check(SB),NOSPLIT, $0 59 MOVB ·hasVX(SB), R1 60 CMPBEQ R1, $1, vectorimpl // vectorfacility = 1, vector supported 61 MOVD $addvectorfacility+0x00(SB), R1 62 MOVD $·addVV_novec(SB), R2 63 MOVD R2, 0(R1) 64 //MOVD $·addVV_novec(SB), 0(R1) 65 BR ·addVV_novec(SB) 66 vectorimpl: 67 MOVD $addvectorfacility+0x00(SB), R1 68 MOVD $·addVV_vec(SB), R2 69 MOVD R2, 0(R1) 70 //MOVD $·addVV_vec(SB), 0(R1) 71 BR ·addVV_vec(SB) 72 73 GLOBL addvectorfacility+0x00(SB), NOPTR, $8 74 DATA addvectorfacility+0x00(SB)/8, $·addVV_check(SB) 75 76 TEXT ·addVV_vec(SB),NOSPLIT,$0 77 MOVD z_len+8(FP), R3 78 MOVD x+24(FP), R8 79 MOVD y+48(FP), R9 80 MOVD z+0(FP), R2 81 82 MOVD $0, R4 // c = 0 83 MOVD $0, R0 // make sure it's zero 84 MOVD $0, R10 // i = 0 85 86 87 // s/JL/JMP/ below to disable the unrolled loop 88 SUB $4, R3 89 BLT v1 90 SUB $12, R3 // n -= 16 91 BLT A1 // if n < 0 goto A1 92 93 MOVD R8, R5 94 MOVD R9, R6 95 MOVD R2, R7 96 // n >= 0 97 // regular loop body unrolled 16x 98 VZERO V0 // c = 0 99 UU1: VLM 0(R5), V1, V4 // 64-bytes into V1..V8 100 ADD $64, R5 101 VPDI $0x4,V1,V1,V1 // flip the doublewords to big-endian order 102 VPDI $0x4,V2,V2,V2 // flip the doublewords to big-endian order 103 104 105 VLM 0(R6), V9, V12 // 64-bytes into V9..V16 106 ADD $64, R6 107 VPDI $0x4,V9,V9,V9 // flip the doublewords to big-endian order 108 VPDI $0x4,V10,V10,V10 // flip the doublewords to big-endian order 109 110 VACCCQ V1, V9, V0, V25 111 VACQ V1, V9, V0, V17 112 VACCCQ V2, V10, V25, V26 113 VACQ V2, V10, V25, V18 114 115 116 VLM 0(R5), V5, V6 // 32-bytes into V1..V8 117 VLM 0(R6), V13, V14 // 32-bytes into V9..V16 118 ADD $32, R5 119 ADD $32, R6 120 121 VPDI $0x4,V3,V3,V3 // flip the doublewords to big-endian order 122 VPDI $0x4,V4,V4,V4 // flip the doublewords to big-endian order 123 VPDI $0x4,V11,V11,V11 // flip the doublewords to big-endian order 124 VPDI $0x4,V12,V12,V12 // flip the doublewords to big-endian order 125 126 VACCCQ V3, V11, V26, V27 127 VACQ V3, V11, V26, V19 128 VACCCQ V4, V12, V27, V28 129 VACQ V4, V12, V27, V20 130 131 VLM 0(R5), V7, V8 // 32-bytes into V1..V8 132 VLM 0(R6), V15, V16 // 32-bytes into V9..V16 133 ADD $32, R5 134 ADD $32, R6 135 136 VPDI $0x4,V5,V5,V5 // flip the doublewords to big-endian order 137 VPDI $0x4,V6,V6,V6 // flip the doublewords to big-endian order 138 VPDI $0x4,V13,V13,V13 // flip the doublewords to big-endian order 139 VPDI $0x4,V14,V14,V14 // flip the doublewords to big-endian order 140 141 VACCCQ V5, V13, V28, V29 142 VACQ V5, V13, V28, V21 143 VACCCQ V6, V14, V29, V30 144 VACQ V6, V14, V29, V22 145 146 VPDI $0x4,V7,V7,V7 // flip the doublewords to big-endian order 147 VPDI $0x4,V8,V8,V8 // flip the doublewords to big-endian order 148 VPDI $0x4,V15,V15,V15 // flip the doublewords to big-endian order 149 VPDI $0x4,V16,V16,V16 // flip the doublewords to big-endian order 150 151 VACCCQ V7, V15, V30, V31 152 VACQ V7, V15, V30, V23 153 VACCCQ V8, V16, V31, V0 //V0 has carry-over 154 VACQ V8, V16, V31, V24 155 156 VPDI $0x4,V17,V17,V17 // flip the doublewords to big-endian order 157 VPDI $0x4,V18,V18,V18 // flip the doublewords to big-endian order 158 VPDI $0x4,V19,V19,V19 // flip the doublewords to big-endian order 159 VPDI $0x4,V20,V20,V20 // flip the doublewords to big-endian order 160 VPDI $0x4,V21,V21,V21 // flip the doublewords to big-endian order 161 VPDI $0x4,V22,V22,V22 // flip the doublewords to big-endian order 162 VPDI $0x4,V23,V23,V23 // flip the doublewords to big-endian order 163 VPDI $0x4,V24,V24,V24 // flip the doublewords to big-endian order 164 VSTM V17, V24, 0(R7) // 128-bytes into z 165 ADD $128, R7 166 ADD $128, R10 // i += 16 167 SUB $16, R3 // n -= 16 168 BGE UU1 // if n >= 0 goto U1 169 VLGVG $1, V0, R4 // put cf into R4 170 NEG R4, R4 // save cf 171 172 A1: ADD $12, R3 // n += 16 173 174 175 // s/JL/JMP/ below to disable the unrolled loop 176 BLT v1 // if n < 0 goto v1 177 178 U1: // n >= 0 179 // regular loop body unrolled 4x 180 MOVD 0(R8)(R10*1), R5 181 MOVD 8(R8)(R10*1), R6 182 MOVD 16(R8)(R10*1), R7 183 MOVD 24(R8)(R10*1), R1 184 ADDC R4, R4 // restore CF 185 MOVD 0(R9)(R10*1), R11 186 ADDE R11, R5 187 MOVD 8(R9)(R10*1), R11 188 ADDE R11, R6 189 MOVD 16(R9)(R10*1), R11 190 ADDE R11, R7 191 MOVD 24(R9)(R10*1), R11 192 ADDE R11, R1 193 MOVD R0, R4 194 ADDE R4, R4 // save CF 195 NEG R4, R4 196 MOVD R5, 0(R2)(R10*1) 197 MOVD R6, 8(R2)(R10*1) 198 MOVD R7, 16(R2)(R10*1) 199 MOVD R1, 24(R2)(R10*1) 200 201 202 ADD $32, R10 // i += 4 203 SUB $4, R3 // n -= 4 204 BGE U1 // if n >= 0 goto U1 205 206 v1: ADD $4, R3 // n += 4 207 BLE E1 // if n <= 0 goto E1 208 209 L1: // n > 0 210 ADDC R4, R4 // restore CF 211 MOVD 0(R8)(R10*1), R5 212 MOVD 0(R9)(R10*1), R11 213 ADDE R11, R5 214 MOVD R5, 0(R2)(R10*1) 215 MOVD R0, R4 216 ADDE R4, R4 // save CF 217 NEG R4, R4 218 219 ADD $8, R10 // i++ 220 SUB $1, R3 // n-- 221 BGT L1 // if n > 0 goto L1 222 223 E1: NEG R4, R4 224 MOVD R4, c+72(FP) // return c 225 RET 226 227 TEXT ·addVV_novec(SB),NOSPLIT,$0 228 novec: 229 MOVD z_len+8(FP), R3 230 MOVD x+24(FP), R8 231 MOVD y+48(FP), R9 232 MOVD z+0(FP), R2 233 234 MOVD $0, R4 // c = 0 235 MOVD $0, R0 // make sure it's zero 236 MOVD $0, R10 // i = 0 237 238 // s/JL/JMP/ below to disable the unrolled loop 239 SUB $4, R3 // n -= 4 240 BLT v1n // if n < 0 goto v1n 241 U1n: // n >= 0 242 // regular loop body unrolled 4x 243 MOVD 0(R8)(R10*1), R5 244 MOVD 8(R8)(R10*1), R6 245 MOVD 16(R8)(R10*1), R7 246 MOVD 24(R8)(R10*1), R1 247 ADDC R4, R4 // restore CF 248 MOVD 0(R9)(R10*1), R11 249 ADDE R11, R5 250 MOVD 8(R9)(R10*1), R11 251 ADDE R11, R6 252 MOVD 16(R9)(R10*1), R11 253 ADDE R11, R7 254 MOVD 24(R9)(R10*1), R11 255 ADDE R11, R1 256 MOVD R0, R4 257 ADDE R4, R4 // save CF 258 NEG R4, R4 259 MOVD R5, 0(R2)(R10*1) 260 MOVD R6, 8(R2)(R10*1) 261 MOVD R7, 16(R2)(R10*1) 262 MOVD R1, 24(R2)(R10*1) 263 264 265 ADD $32, R10 // i += 4 266 SUB $4, R3 // n -= 4 267 BGE U1n // if n >= 0 goto U1n 268 269 v1n: ADD $4, R3 // n += 4 270 BLE E1n // if n <= 0 goto E1n 271 272 L1n: // n > 0 273 ADDC R4, R4 // restore CF 274 MOVD 0(R8)(R10*1), R5 275 MOVD 0(R9)(R10*1), R11 276 ADDE R11, R5 277 MOVD R5, 0(R2)(R10*1) 278 MOVD R0, R4 279 ADDE R4, R4 // save CF 280 NEG R4, R4 281 282 ADD $8, R10 // i++ 283 SUB $1, R3 // n-- 284 BGT L1n // if n > 0 goto L1n 285 286 E1n: NEG R4, R4 287 MOVD R4, c+72(FP) // return c 288 RET 289 290 291 TEXT ·subVV(SB),NOSPLIT,$0 292 MOVD subvectorfacility+0x00(SB),R1 293 BR (R1) 294 295 TEXT ·subVV_check(SB),NOSPLIT,$0 296 MOVB ·hasVX(SB), R1 297 CMPBEQ R1, $1, vectorimpl // vectorfacility = 1, vector supported 298 MOVD $subvectorfacility+0x00(SB), R1 299 MOVD $·subVV_novec(SB), R2 300 MOVD R2, 0(R1) 301 //MOVD $·subVV_novec(SB), 0(R1) 302 BR ·subVV_novec(SB) 303 vectorimpl: 304 MOVD $subvectorfacility+0x00(SB), R1 305 MOVD $·subVV_vec(SB), R2 306 MOVD R2, 0(R1) 307 //MOVD $·subVV_vec(SB), 0(R1) 308 BR ·subVV_vec(SB) 309 310 GLOBL subvectorfacility+0x00(SB), NOPTR, $8 311 DATA subvectorfacility+0x00(SB)/8, $·subVV_check(SB) 312 313 // DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11 314 // func subVV(z, x, y []Word) (c Word) 315 // (same as addVV except for SUBC/SUBE instead of ADDC/ADDE and label names) 316 TEXT ·subVV_vec(SB),NOSPLIT,$0 317 MOVD z_len+8(FP), R3 318 MOVD x+24(FP), R8 319 MOVD y+48(FP), R9 320 MOVD z+0(FP), R2 321 MOVD $0, R4 // c = 0 322 MOVD $0, R0 // make sure it's zero 323 MOVD $0, R10 // i = 0 324 325 // s/JL/JMP/ below to disable the unrolled loop 326 SUB $4, R3 // n -= 4 327 BLT v1 // if n < 0 goto v1 328 SUB $12, R3 // n -= 16 329 BLT A1 // if n < 0 goto A1 330 331 MOVD R8, R5 332 MOVD R9, R6 333 MOVD R2, R7 334 335 // n >= 0 336 // regular loop body unrolled 16x 337 VZERO V0 // cf = 0 338 MOVD $1, R4 // for 390 subtraction cf starts as 1 (no borrow) 339 VLVGG $1, R4, V0 //put carry into V0 340 341 UU1: VLM 0(R5), V1, V4 // 64-bytes into V1..V8 342 ADD $64, R5 343 VPDI $0x4,V1,V1,V1 // flip the doublewords to big-endian order 344 VPDI $0x4,V2,V2,V2 // flip the doublewords to big-endian order 345 346 347 VLM 0(R6), V9, V12 // 64-bytes into V9..V16 348 ADD $64, R6 349 VPDI $0x4,V9,V9,V9 // flip the doublewords to big-endian order 350 VPDI $0x4,V10,V10,V10 // flip the doublewords to big-endian order 351 352 VSBCBIQ V1, V9, V0, V25 353 VSBIQ V1, V9, V0, V17 354 VSBCBIQ V2, V10, V25, V26 355 VSBIQ V2, V10, V25, V18 356 357 358 VLM 0(R5), V5, V6 // 32-bytes into V1..V8 359 VLM 0(R6), V13, V14 // 32-bytes into V9..V16 360 ADD $32, R5 361 ADD $32, R6 362 363 VPDI $0x4,V3,V3,V3 // flip the doublewords to big-endian order 364 VPDI $0x4,V4,V4,V4 // flip the doublewords to big-endian order 365 VPDI $0x4,V11,V11,V11 // flip the doublewords to big-endian order 366 VPDI $0x4,V12,V12,V12 // flip the doublewords to big-endian order 367 368 VSBCBIQ V3, V11, V26, V27 369 VSBIQ V3, V11, V26, V19 370 VSBCBIQ V4, V12, V27, V28 371 VSBIQ V4, V12, V27, V20 372 373 VLM 0(R5), V7, V8 // 32-bytes into V1..V8 374 VLM 0(R6), V15, V16 // 32-bytes into V9..V16 375 ADD $32, R5 376 ADD $32, R6 377 378 VPDI $0x4,V5,V5,V5 // flip the doublewords to big-endian order 379 VPDI $0x4,V6,V6,V6 // flip the doublewords to big-endian order 380 VPDI $0x4,V13,V13,V13 // flip the doublewords to big-endian order 381 VPDI $0x4,V14,V14,V14 // flip the doublewords to big-endian order 382 383 VSBCBIQ V5, V13, V28, V29 384 VSBIQ V5, V13, V28, V21 385 VSBCBIQ V6, V14, V29, V30 386 VSBIQ V6, V14, V29, V22 387 388 VPDI $0x4,V7,V7,V7 // flip the doublewords to big-endian order 389 VPDI $0x4,V8,V8,V8 // flip the doublewords to big-endian order 390 VPDI $0x4,V15,V15,V15 // flip the doublewords to big-endian order 391 VPDI $0x4,V16,V16,V16 // flip the doublewords to big-endian order 392 393 VSBCBIQ V7, V15, V30, V31 394 VSBIQ V7, V15, V30, V23 395 VSBCBIQ V8, V16, V31, V0 //V0 has carry-over 396 VSBIQ V8, V16, V31, V24 397 398 VPDI $0x4,V17,V17,V17 // flip the doublewords to big-endian order 399 VPDI $0x4,V18,V18,V18 // flip the doublewords to big-endian order 400 VPDI $0x4,V19,V19,V19 // flip the doublewords to big-endian order 401 VPDI $0x4,V20,V20,V20 // flip the doublewords to big-endian order 402 VPDI $0x4,V21,V21,V21 // flip the doublewords to big-endian order 403 VPDI $0x4,V22,V22,V22 // flip the doublewords to big-endian order 404 VPDI $0x4,V23,V23,V23 // flip the doublewords to big-endian order 405 VPDI $0x4,V24,V24,V24 // flip the doublewords to big-endian order 406 VSTM V17, V24, 0(R7) // 128-bytes into z 407 ADD $128, R7 408 ADD $128, R10 // i += 16 409 SUB $16, R3 // n -= 16 410 BGE UU1 // if n >= 0 goto U1 411 VLGVG $1, V0, R4 // put cf into R4 412 SUB $1, R4 // save cf 413 414 A1: ADD $12, R3 // n += 16 415 BLT v1 // if n < 0 goto v1 416 417 U1: // n >= 0 418 // regular loop body unrolled 4x 419 MOVD 0(R8)(R10*1), R5 420 MOVD 8(R8)(R10*1), R6 421 MOVD 16(R8)(R10*1), R7 422 MOVD 24(R8)(R10*1), R1 423 MOVD R0, R11 424 SUBC R4, R11 // restore CF 425 MOVD 0(R9)(R10*1), R11 426 SUBE R11, R5 427 MOVD 8(R9)(R10*1), R11 428 SUBE R11, R6 429 MOVD 16(R9)(R10*1), R11 430 SUBE R11, R7 431 MOVD 24(R9)(R10*1), R11 432 SUBE R11, R1 433 MOVD R0, R4 434 SUBE R4, R4 // save CF 435 MOVD R5, 0(R2)(R10*1) 436 MOVD R6, 8(R2)(R10*1) 437 MOVD R7, 16(R2)(R10*1) 438 MOVD R1, 24(R2)(R10*1) 439 440 ADD $32, R10 // i += 4 441 SUB $4, R3 // n -= 4 442 BGE U1 // if n >= 0 goto U1n 443 444 v1: ADD $4, R3 // n += 4 445 BLE E1 // if n <= 0 goto E1 446 447 L1: // n > 0 448 MOVD R0, R11 449 SUBC R4, R11 // restore CF 450 MOVD 0(R8)(R10*1), R5 451 MOVD 0(R9)(R10*1), R11 452 SUBE R11, R5 453 MOVD R5, 0(R2)(R10*1) 454 MOVD R0, R4 455 SUBE R4, R4 // save CF 456 457 ADD $8, R10 // i++ 458 SUB $1, R3 // n-- 459 BGT L1 // if n > 0 goto L1n 460 461 E1: NEG R4, R4 462 MOVD R4, c+72(FP) // return c 463 RET 464 465 466 // DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11 467 // func subVV(z, x, y []Word) (c Word) 468 // (same as addVV except for SUBC/SUBE instead of ADDC/ADDE and label names) 469 TEXT ·subVV_novec(SB),NOSPLIT,$0 470 MOVD z_len+8(FP), R3 471 MOVD x+24(FP), R8 472 MOVD y+48(FP), R9 473 MOVD z+0(FP), R2 474 475 MOVD $0, R4 // c = 0 476 MOVD $0, R0 // make sure it's zero 477 MOVD $0, R10 // i = 0 478 479 // s/JL/JMP/ below to disable the unrolled loop 480 SUB $4, R3 // n -= 4 481 BLT v1 // if n < 0 goto v1 482 483 U1: // n >= 0 484 // regular loop body unrolled 4x 485 MOVD 0(R8)(R10*1), R5 486 MOVD 8(R8)(R10*1), R6 487 MOVD 16(R8)(R10*1), R7 488 MOVD 24(R8)(R10*1), R1 489 MOVD R0, R11 490 SUBC R4, R11 // restore CF 491 MOVD 0(R9)(R10*1), R11 492 SUBE R11, R5 493 MOVD 8(R9)(R10*1), R11 494 SUBE R11, R6 495 MOVD 16(R9)(R10*1), R11 496 SUBE R11, R7 497 MOVD 24(R9)(R10*1), R11 498 SUBE R11, R1 499 MOVD R0, R4 500 SUBE R4, R4 // save CF 501 MOVD R5, 0(R2)(R10*1) 502 MOVD R6, 8(R2)(R10*1) 503 MOVD R7, 16(R2)(R10*1) 504 MOVD R1, 24(R2)(R10*1) 505 506 507 ADD $32, R10 // i += 4 508 SUB $4, R3 // n -= 4 509 BGE U1 // if n >= 0 goto U1 510 511 v1: ADD $4, R3 // n += 4 512 BLE E1 // if n <= 0 goto E1 513 514 L1: // n > 0 515 MOVD R0, R11 516 SUBC R4, R11 // restore CF 517 MOVD 0(R8)(R10*1), R5 518 MOVD 0(R9)(R10*1), R11 519 SUBE R11, R5 520 MOVD R5, 0(R2)(R10*1) 521 MOVD R0, R4 522 SUBE R4, R4 // save CF 523 524 ADD $8, R10 // i++ 525 SUB $1, R3 // n-- 526 BGT L1 // if n > 0 goto L1 527 528 E1: NEG R4, R4 529 MOVD R4, c+72(FP) // return c 530 RET 531 532 TEXT ·addVW(SB),NOSPLIT,$0 533 MOVD addwvectorfacility+0x00(SB),R1 534 BR (R1) 535 536 TEXT ·addVW_check(SB),NOSPLIT,$0 537 MOVB ·hasVX(SB), R1 538 CMPBEQ R1, $1, vectorimpl // vectorfacility = 1, vector supported 539 MOVD $addwvectorfacility+0x00(SB), R1 540 MOVD $·addVW_novec(SB), R2 541 MOVD R2, 0(R1) 542 //MOVD $·addVW_novec(SB), 0(R1) 543 BR ·addVW_novec(SB) 544 vectorimpl: 545 MOVD $addwvectorfacility+0x00(SB), R1 546 MOVD $·addVW_vec(SB), R2 547 MOVD R2, 0(R1) 548 //MOVD $·addVW_vec(SB), 0(R1) 549 BR ·addVW_vec(SB) 550 551 GLOBL addwvectorfacility+0x00(SB), NOPTR, $8 552 DATA addwvectorfacility+0x00(SB)/8, $·addVW_check(SB) 553 554 555 // func addVW_vec(z, x []Word, y Word) (c Word) 556 TEXT ·addVW_vec(SB),NOSPLIT,$0 557 MOVD z_len+8(FP), R3 558 MOVD x+24(FP), R8 559 MOVD y+48(FP), R4 // c = y 560 MOVD z+0(FP), R2 561 562 MOVD $0, R0 // make sure it's zero 563 MOVD $0, R10 // i = 0 564 MOVD R8, R5 565 MOVD R2, R7 566 567 // s/JL/JMP/ below to disable the unrolled loop 568 SUB $4, R3 // n -= 4 569 BLT v10 // if n < 0 goto v10 570 SUB $12, R3 571 BLT A10 572 573 // n >= 0 574 // regular loop body unrolled 16x 575 576 VZERO V0 // prepare V0 to be final carry register 577 VZERO V9 // to ensure upper half is zero 578 VLVGG $1, R4, V9 579 UU1: VLM 0(R5), V1, V4 // 64-bytes into V1..V4 580 ADD $64, R5 581 VPDI $0x4,V1,V1,V1 // flip the doublewords to big-endian order 582 VPDI $0x4,V2,V2,V2 // flip the doublewords to big-endian order 583 584 585 VACCCQ V1, V9, V0, V25 586 VACQ V1, V9, V0, V17 587 VZERO V9 588 VACCCQ V2, V9, V25, V26 589 VACQ V2, V9, V25, V18 590 591 592 VLM 0(R5), V5, V6 // 32-bytes into V5..V6 593 ADD $32, R5 594 595 VPDI $0x4,V3,V3,V3 // flip the doublewords to big-endian order 596 VPDI $0x4,V4,V4,V4 // flip the doublewords to big-endian order 597 598 VACCCQ V3, V9, V26, V27 599 VACQ V3, V9, V26, V19 600 VACCCQ V4, V9, V27, V28 601 VACQ V4, V9, V27, V20 602 603 VLM 0(R5), V7, V8 // 32-bytes into V7..V8 604 ADD $32, R5 605 606 VPDI $0x4,V5,V5,V5 // flip the doublewords to big-endian order 607 VPDI $0x4,V6,V6,V6 // flip the doublewords to big-endian order 608 609 VACCCQ V5, V9, V28, V29 610 VACQ V5, V9, V28, V21 611 VACCCQ V6, V9, V29, V30 612 VACQ V6, V9, V29, V22 613 614 VPDI $0x4,V7,V7,V7 // flip the doublewords to big-endian order 615 VPDI $0x4,V8,V8,V8 // flip the doublewords to big-endian order 616 617 VACCCQ V7, V9, V30, V31 618 VACQ V7, V9, V30, V23 619 VACCCQ V8, V9, V31, V0 //V0 has carry-over 620 VACQ V8, V9, V31, V24 621 622 VPDI $0x4,V17,V17,V17 // flip the doublewords to big-endian order 623 VPDI $0x4,V18,V18,V18 // flip the doublewords to big-endian order 624 VPDI $0x4,V19,V19,V19 // flip the doublewords to big-endian order 625 VPDI $0x4,V20,V20,V20 // flip the doublewords to big-endian order 626 VPDI $0x4,V21,V21,V21 // flip the doublewords to big-endian order 627 VPDI $0x4,V22,V22,V22 // flip the doublewords to big-endian order 628 VPDI $0x4,V23,V23,V23 // flip the doublewords to big-endian order 629 VPDI $0x4,V24,V24,V24 // flip the doublewords to big-endian order 630 VSTM V17, V24, 0(R7) // 128-bytes into z 631 ADD $128, R7 632 ADD $128, R10 // i += 16 633 SUB $16, R3 // n -= 16 634 BGE UU1 // if n >= 0 goto U1 635 VLGVG $1, V0, R4 // put cf into R4 in case we branch to v10 636 637 A10: ADD $12, R3 // n += 16 638 639 640 // s/JL/JMP/ below to disable the unrolled loop 641 642 BLT v10 // if n < 0 goto v10 643 644 645 U4: // n >= 0 646 // regular loop body unrolled 4x 647 MOVD 0(R8)(R10*1), R5 648 MOVD 8(R8)(R10*1), R6 649 MOVD 16(R8)(R10*1), R7 650 MOVD 24(R8)(R10*1), R1 651 ADDC R4, R5 652 ADDE R0, R6 653 ADDE R0, R7 654 ADDE R0, R1 655 ADDE R0, R0 656 MOVD R0, R4 // save CF 657 SUB R0, R0 658 MOVD R5, 0(R2)(R10*1) 659 MOVD R6, 8(R2)(R10*1) 660 MOVD R7, 16(R2)(R10*1) 661 MOVD R1, 24(R2)(R10*1) 662 663 ADD $32, R10 // i += 4 -> i +=32 664 SUB $4, R3 // n -= 4 665 BGE U4 // if n >= 0 goto U4 666 667 v10: ADD $4, R3 // n += 4 668 BLE E10 // if n <= 0 goto E4 669 670 671 L4: // n > 0 672 MOVD 0(R8)(R10*1), R5 673 ADDC R4, R5 674 ADDE R0, R0 675 MOVD R0, R4 // save CF 676 SUB R0, R0 677 MOVD R5, 0(R2)(R10*1) 678 679 ADD $8, R10 // i++ 680 SUB $1, R3 // n-- 681 BGT L4 // if n > 0 goto L4 682 683 E10: MOVD R4, c+56(FP) // return c 684 685 RET 686 687 688 TEXT ·addVW_novec(SB),NOSPLIT,$0 689 //DI = R3, CX = R4, SI = r10, r8 = r8, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) 690 MOVD z_len+8(FP), R3 691 MOVD x+24(FP), R8 692 MOVD y+48(FP), R4 // c = y 693 MOVD z+0(FP), R2 694 MOVD $0, R0 // make sure it's 0 695 MOVD $0, R10 // i = 0 696 697 // s/JL/JMP/ below to disable the unrolled loop 698 SUB $4, R3 // n -= 4 699 BLT v4 // if n < 4 goto v4 700 701 U4: // n >= 0 702 // regular loop body unrolled 4x 703 MOVD 0(R8)(R10*1), R5 704 MOVD 8(R8)(R10*1), R6 705 MOVD 16(R8)(R10*1), R7 706 MOVD 24(R8)(R10*1), R1 707 ADDC R4, R5 708 ADDE R0, R6 709 ADDE R0, R7 710 ADDE R0, R1 711 ADDE R0, R0 712 MOVD R0, R4 // save CF 713 SUB R0, R0 714 MOVD R5, 0(R2)(R10*1) 715 MOVD R6, 8(R2)(R10*1) 716 MOVD R7, 16(R2)(R10*1) 717 MOVD R1, 24(R2)(R10*1) 718 719 ADD $32, R10 // i += 4 -> i +=32 720 SUB $4, R3 // n -= 4 721 BGE U4 // if n >= 0 goto U4 722 723 v4: ADD $4, R3 // n += 4 724 BLE E4 // if n <= 0 goto E4 725 726 L4: // n > 0 727 MOVD 0(R8)(R10*1), R5 728 ADDC R4, R5 729 ADDE R0, R0 730 MOVD R0, R4 // save CF 731 SUB R0, R0 732 MOVD R5, 0(R2)(R10*1) 733 734 ADD $8, R10 // i++ 735 SUB $1, R3 // n-- 736 BGT L4 // if n > 0 goto L4 737 738 E4: MOVD R4, c+56(FP) // return c 739 740 RET 741 742 TEXT ·subVW(SB),NOSPLIT,$0 743 MOVD subwvectorfacility+0x00(SB),R1 744 BR (R1) 745 746 TEXT ·subVW_check(SB),NOSPLIT,$0 747 MOVB ·hasVX(SB), R1 748 CMPBEQ R1, $1, vectorimpl // vectorfacility = 1, vector supported 749 MOVD $subwvectorfacility+0x00(SB), R1 750 MOVD $·subVW_novec(SB), R2 751 MOVD R2, 0(R1) 752 //MOVD $·subVW_novec(SB), 0(R1) 753 BR ·subVW_novec(SB) 754 vectorimpl: 755 MOVD $subwvectorfacility+0x00(SB), R1 756 MOVD $·subVW_vec(SB), R2 757 MOVD R2, 0(R1) 758 //MOVD $·subVW_vec(SB), 0(R1) 759 BR ·subVW_vec(SB) 760 761 GLOBL subwvectorfacility+0x00(SB), NOPTR, $8 762 DATA subwvectorfacility+0x00(SB)/8, $·subVW_check(SB) 763 764 // func subVW(z, x []Word, y Word) (c Word) 765 TEXT ·subVW_vec(SB),NOSPLIT,$0 766 MOVD z_len+8(FP), R3 767 MOVD x+24(FP), R8 768 MOVD y+48(FP), R4 // c = y 769 MOVD z+0(FP), R2 770 771 MOVD $0, R0 // make sure it's zero 772 MOVD $0, R10 // i = 0 773 MOVD R8, R5 774 MOVD R2, R7 775 776 // s/JL/JMP/ below to disable the unrolled loop 777 SUB $4, R3 // n -= 4 778 BLT v11 // if n < 0 goto v11 779 SUB $12, R3 780 BLT A11 781 782 VZERO V0 783 MOVD $1, R6 // prepare V0 to be final carry register 784 VLVGG $1, R6, V0 // borrow is initially "no borrow" 785 VZERO V9 // to ensure upper half is zero 786 VLVGG $1, R4, V9 787 788 // n >= 0 789 // regular loop body unrolled 16x 790 791 792 UU1: VLM 0(R5), V1, V4 // 64-bytes into V1..V4 793 ADD $64, R5 794 VPDI $0x4,V1,V1,V1 // flip the doublewords to big-endian order 795 VPDI $0x4,V2,V2,V2 // flip the doublewords to big-endian order 796 797 798 VSBCBIQ V1, V9, V0, V25 799 VSBIQ V1, V9, V0, V17 800 VZERO V9 801 VSBCBIQ V2, V9, V25, V26 802 VSBIQ V2, V9, V25, V18 803 804 VLM 0(R5), V5, V6 // 32-bytes into V5..V6 805 ADD $32, R5 806 807 VPDI $0x4,V3,V3,V3 // flip the doublewords to big-endian order 808 VPDI $0x4,V4,V4,V4 // flip the doublewords to big-endian order 809 810 811 VSBCBIQ V3, V9, V26, V27 812 VSBIQ V3, V9, V26, V19 813 VSBCBIQ V4, V9, V27, V28 814 VSBIQ V4, V9, V27, V20 815 816 VLM 0(R5), V7, V8 // 32-bytes into V7..V8 817 ADD $32, R5 818 819 VPDI $0x4,V5,V5,V5 // flip the doublewords to big-endian order 820 VPDI $0x4,V6,V6,V6 // flip the doublewords to big-endian order 821 822 VSBCBIQ V5, V9, V28, V29 823 VSBIQ V5, V9, V28, V21 824 VSBCBIQ V6, V9, V29, V30 825 VSBIQ V6, V9, V29, V22 826 827 VPDI $0x4,V7,V7,V7 // flip the doublewords to big-endian order 828 VPDI $0x4,V8,V8,V8 // flip the doublewords to big-endian order 829 830 VSBCBIQ V7, V9, V30, V31 831 VSBIQ V7, V9, V30, V23 832 VSBCBIQ V8, V9, V31, V0 // V0 has carry-over 833 VSBIQ V8, V9, V31, V24 834 835 VPDI $0x4,V17,V17,V17 // flip the doublewords to big-endian order 836 VPDI $0x4,V18,V18,V18 // flip the doublewords to big-endian order 837 VPDI $0x4,V19,V19,V19 // flip the doublewords to big-endian order 838 VPDI $0x4,V20,V20,V20 // flip the doublewords to big-endian order 839 VPDI $0x4,V21,V21,V21 // flip the doublewords to big-endian order 840 VPDI $0x4,V22,V22,V22 // flip the doublewords to big-endian order 841 VPDI $0x4,V23,V23,V23 // flip the doublewords to big-endian order 842 VPDI $0x4,V24,V24,V24 // flip the doublewords to big-endian order 843 VSTM V17, V24, 0(R7) // 128-bytes into z 844 ADD $128, R7 845 ADD $128, R10 // i += 16 846 SUB $16, R3 // n -= 16 847 BGE UU1 // if n >= 0 goto U1 848 VLGVG $1, V0, R4 // put cf into R4 in case we branch to v10 849 SUB $1, R4 // save cf 850 NEG R4, R4 851 A11: ADD $12, R3 // n += 16 852 853 BLT v11 // if n < 0 goto v11 854 855 // n >= 0 856 // regular loop body unrolled 4x 857 858 U4: // n >= 0 859 // regular loop body unrolled 4x 860 MOVD 0(R8)(R10*1), R5 861 MOVD 8(R8)(R10*1), R6 862 MOVD 16(R8)(R10*1), R7 863 MOVD 24(R8)(R10*1), R1 864 SUBC R4, R5 //SLGR -> SUBC 865 SUBE R0, R6 //SLBGR -> SUBE 866 SUBE R0, R7 867 SUBE R0, R1 868 SUBE R4, R4 // save CF 869 NEG R4, R4 870 MOVD R5, 0(R2)(R10*1) 871 MOVD R6, 8(R2)(R10*1) 872 MOVD R7, 16(R2)(R10*1) 873 MOVD R1, 24(R2)(R10*1) 874 875 ADD $32, R10 // i += 4 -> i +=32 876 SUB $4, R3 // n -= 4 877 BGE U4 // if n >= 0 goto U4 878 879 v11: ADD $4, R3 // n += 4 880 BLE E11 // if n <= 0 goto E4 881 882 L4: // n > 0 883 884 MOVD 0(R8)(R10*1), R5 885 SUBC R4, R5 886 SUBE R4, R4 // save CF 887 NEG R4, R4 888 MOVD R5, 0(R2)(R10*1) 889 890 ADD $8, R10 // i++ 891 SUB $1, R3 // n-- 892 BGT L4 // if n > 0 goto L4 893 894 E11: MOVD R4, c+56(FP) // return c 895 896 RET 897 898 //DI = R3, CX = R4, SI = r10, r8 = r8, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) 899 // func subVW(z, x []Word, y Word) (c Word) 900 // (same as addVW except for SUBC/SUBE instead of ADDC/ADDE and label names) 901 TEXT ·subVW_novec(SB),NOSPLIT,$0 902 MOVD z_len+8(FP), R3 903 MOVD x+24(FP), R8 904 MOVD y+48(FP), R4 // c = y 905 MOVD z+0(FP), R2 906 MOVD $0, R0 // make sure it's 0 907 MOVD $0, R10 // i = 0 908 909 // s/JL/JMP/ below to disable the unrolled loop 910 SUB $4, R3 // n -= 4 911 BLT v4 // if n < 4 goto v4 912 913 U4: // n >= 0 914 // regular loop body unrolled 4x 915 MOVD 0(R8)(R10*1), R5 916 MOVD 8(R8)(R10*1), R6 917 MOVD 16(R8)(R10*1), R7 918 MOVD 24(R8)(R10*1), R1 919 SUBC R4, R5 //SLGR -> SUBC 920 SUBE R0, R6 //SLBGR -> SUBE 921 SUBE R0, R7 922 SUBE R0, R1 923 SUBE R4, R4 // save CF 924 NEG R4, R4 925 MOVD R5, 0(R2)(R10*1) 926 MOVD R6, 8(R2)(R10*1) 927 MOVD R7, 16(R2)(R10*1) 928 MOVD R1, 24(R2)(R10*1) 929 930 ADD $32, R10 // i += 4 -> i +=32 931 SUB $4, R3 // n -= 4 932 BGE U4 // if n >= 0 goto U4 933 934 v4: ADD $4, R3 // n += 4 935 BLE E4 // if n <= 0 goto E4 936 937 L4: // n > 0 938 MOVD 0(R8)(R10*1), R5 939 SUBC R4, R5 940 SUBE R4, R4 // save CF 941 NEG R4, R4 942 MOVD R5, 0(R2)(R10*1) 943 944 ADD $8, R10 // i++ 945 SUB $1, R3 // n-- 946 BGT L4 // if n > 0 goto L4 947 948 E4: MOVD R4, c+56(FP) // return c 949 950 RET 951 952 // func shlVU(z, x []Word, s uint) (c Word) 953 TEXT ·shlVU(SB),NOSPLIT,$0 954 MOVD z_len+8(FP), R5 955 MOVD $0, R0 956 SUB $1, R5 // n-- 957 BLT X8b // n < 0 (n <= 0) 958 959 // n > 0 960 MOVD s+48(FP), R4 961 CMPBEQ R0, R4, Z80 //handle 0 case beq 962 MOVD $64, R6 963 CMPBEQ R6, R4, Z864 //handle 64 case beq 964 MOVD z+0(FP), R2 965 MOVD x+24(FP), R8 966 SLD $3, R5 // n = n*8 967 SUB R4, R6, R7 968 MOVD (R8)(R5*1), R10 // w1 = x[i-1] 969 SRD R7, R10, R3 970 MOVD R3, c+56(FP) 971 972 MOVD $0, R1 // i = 0 973 BR E8 974 975 // i < n-1 976 L8: MOVD R10, R3 // w = w1 977 MOVD -8(R8)(R5*1), R10 // w1 = x[i+1] 978 979 SLD R4, R3 // w<<s | w1>>ŝ 980 SRD R7, R10, R6 981 OR R6, R3 982 MOVD R3, (R2)(R5*1) // z[i] = w<<s | w1>>ŝ 983 SUB $8, R5 // i-- 984 985 E8: CMPBGT R5, R0, L8 // i < n-1 986 987 // i >= n-1 988 X8a: SLD R4, R10 // w1<<s 989 MOVD R10, (R2) // z[0] = w1<<s 990 RET 991 992 X8b: MOVD R0, c+56(FP) 993 RET 994 995 Z80: MOVD z+0(FP), R2 996 MOVD x+24(FP), R8 997 SLD $3, R5 // n = n*8 998 999 MOVD (R8), R10 1000 MOVD $0, R3 1001 MOVD R3, c+56(FP) 1002 1003 MOVD $0, R1 // i = 0 1004 BR E8Z 1005 1006 // i < n-1 1007 L8Z: MOVD R10, R3 1008 MOVD 8(R8)(R1*1), R10 1009 1010 MOVD R3, (R2)(R1*1) 1011 ADD $8, R1 1012 1013 E8Z: CMPBLT R1, R5, L8Z 1014 1015 // i >= n-1 1016 MOVD R10, (R2)(R5*1) 1017 RET 1018 1019 Z864: MOVD z+0(FP), R2 1020 MOVD x+24(FP), R8 1021 SLD $3, R5 // n = n*8 1022 MOVD (R8)(R5*1), R3 // w1 = x[n-1] 1023 MOVD R3, c+56(FP) // z[i] = x[n-1] 1024 1025 BR E864 1026 1027 // i < n-1 1028 L864: MOVD -8(R8)(R5*1), R3 1029 1030 MOVD R3, (R2)(R5*1) // z[i] = x[n-1] 1031 SUB $8, R5 // i-- 1032 1033 E864: CMPBGT R5, R0, L864 // i < n-1 1034 1035 MOVD R0, (R2) // z[n-1] = 0 1036 RET 1037 1038 1039 // CX = R4, r8 = r8, r10 = r2 , r11 = r5, DX = r3, AX = r10 , BX = R1 , 64-count = r7 (R0 set to 0) temp = R6 1040 // func shrVU(z, x []Word, s uint) (c Word) 1041 TEXT ·shrVU(SB),NOSPLIT,$0 1042 MOVD z_len+8(FP), R5 1043 MOVD $0, R0 1044 SUB $1, R5 // n-- 1045 BLT X9b // n < 0 (n <= 0) 1046 1047 // n > 0 1048 MOVD s+48(FP), R4 1049 CMPBEQ R0, R4, ZB0 //handle 0 case beq 1050 MOVD $64, R6 1051 CMPBEQ R6, R4, ZB64 //handle 64 case beq 1052 MOVD z+0(FP), R2 1053 MOVD x+24(FP), R8 1054 SLD $3, R5 // n = n*8 1055 SUB R4, R6, R7 1056 MOVD (R8), R10 // w1 = x[0] 1057 SLD R7, R10, R3 1058 MOVD R3, c+56(FP) 1059 1060 MOVD $0, R1 // i = 0 1061 BR E9 1062 1063 // i < n-1 1064 L9: MOVD R10, R3 // w = w1 1065 MOVD 8(R8)(R1*1), R10 // w1 = x[i+1] 1066 1067 SRD R4, R3 // w>>s | w1<<s 1068 SLD R7, R10, R6 1069 OR R6, R3 1070 MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<<s 1071 ADD $8, R1 // i++ 1072 1073 E9: CMPBLT R1, R5, L9 // i < n-1 1074 1075 // i >= n-1 1076 X9a: SRD R4, R10 // w1>>s 1077 MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s 1078 RET 1079 1080 X9b: MOVD R0, c+56(FP) 1081 RET 1082 1083 ZB0: MOVD z+0(FP), R2 1084 MOVD x+24(FP), R8 1085 SLD $3, R5 // n = n*8 1086 1087 MOVD (R8), R10 // w1 = x[0] 1088 MOVD $0, R3 // R10 << 64 1089 MOVD R3, c+56(FP) 1090 1091 MOVD $0, R1 // i = 0 1092 BR E9Z 1093 1094 // i < n-1 1095 L9Z: MOVD R10, R3 // w = w1 1096 MOVD 8(R8)(R1*1), R10 // w1 = x[i+1] 1097 1098 MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<<s 1099 ADD $8, R1 // i++ 1100 1101 E9Z: CMPBLT R1, R5, L9Z // i < n-1 1102 1103 // i >= n-1 1104 MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s 1105 RET 1106 1107 ZB64: MOVD z+0(FP), R2 1108 MOVD x+24(FP), R8 1109 SLD $3, R5 // n = n*8 1110 MOVD (R8), R3 // w1 = x[0] 1111 MOVD R3, c+56(FP) 1112 1113 MOVD $0, R1 // i = 0 1114 BR E964 1115 1116 // i < n-1 1117 L964: MOVD 8(R8)(R1*1), R3 // w1 = x[i+1] 1118 1119 MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<<s 1120 ADD $8, R1 // i++ 1121 1122 E964: CMPBLT R1, R5, L964 // i < n-1 1123 1124 // i >= n-1 1125 MOVD $0, R10 // w1>>s 1126 MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s 1127 RET 1128 1129 // CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, DX = r3, AX = r6 , BX = R1 , (R0 set to 0) + use R11 + use R7 for i 1130 // func mulAddVWW(z, x []Word, y, r Word) (c Word) 1131 TEXT ·mulAddVWW(SB),NOSPLIT,$0 1132 MOVD z+0(FP), R2 1133 MOVD x+24(FP), R8 1134 MOVD y+48(FP), R9 1135 MOVD r+56(FP), R4 // c = r 1136 MOVD z_len+8(FP), R5 1137 MOVD $0, R1 // i = 0 1138 MOVD $0, R7 // i*8 = 0 1139 MOVD $0, R0 // make sure it's zero 1140 BR E5 1141 1142 L5: MOVD (R8)(R1*1), R6 1143 MULHDU R9, R6 1144 ADDC R4, R11 //add to low order bits 1145 ADDE R0, R6 1146 MOVD R11, (R2)(R1*1) 1147 MOVD R6, R4 1148 ADD $8, R1 // i*8 + 8 1149 ADD $1, R7 // i++ 1150 1151 E5: CMPBLT R7, R5, L5 // i < n 1152 1153 MOVD R4, c+64(FP) 1154 RET 1155 1156 // func addMulVVW(z, x []Word, y Word) (c Word) 1157 // CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, AX = r11, DX = R6, r12=r12, BX = R1 , (R0 set to 0) + use R11 + use R7 for i 1158 TEXT ·addMulVVW(SB),NOSPLIT,$0 1159 MOVD z+0(FP), R2 1160 MOVD x+24(FP), R8 1161 MOVD y+48(FP), R9 1162 MOVD z_len+8(FP), R5 1163 1164 MOVD $0, R1 // i*8 = 0 1165 MOVD $0, R7 // i = 0 1166 MOVD $0, R0 // make sure it's zero 1167 MOVD $0, R4 // c = 0 1168 1169 MOVD R5, R12 1170 AND $-2, R12 1171 CMPBGE R5, $2, A6 1172 BR E6 1173 1174 A6: MOVD (R8)(R1*1), R6 1175 MULHDU R9, R6 1176 MOVD (R2)(R1*1), R10 1177 ADDC R10, R11 //add to low order bits 1178 ADDE R0, R6 1179 ADDC R4, R11 1180 ADDE R0, R6 1181 MOVD R6, R4 1182 MOVD R11, (R2)(R1*1) 1183 1184 MOVD (8)(R8)(R1*1), R6 1185 MULHDU R9, R6 1186 MOVD (8)(R2)(R1*1), R10 1187 ADDC R10, R11 //add to low order bits 1188 ADDE R0, R6 1189 ADDC R4, R11 1190 ADDE R0, R6 1191 MOVD R6, R4 1192 MOVD R11, (8)(R2)(R1*1) 1193 1194 ADD $16, R1 // i*8 + 8 1195 ADD $2, R7 // i++ 1196 1197 CMPBLT R7, R12, A6 1198 BR E6 1199 1200 L6: MOVD (R8)(R1*1), R6 1201 MULHDU R9, R6 1202 MOVD (R2)(R1*1), R10 1203 ADDC R10, R11 //add to low order bits 1204 ADDE R0, R6 1205 ADDC R4, R11 1206 ADDE R0, R6 1207 MOVD R6, R4 1208 MOVD R11, (R2)(R1*1) 1209 1210 ADD $8, R1 // i*8 + 8 1211 ADD $1, R7 // i++ 1212 1213 E6: CMPBLT R7, R5, L6 // i < n 1214 1215 MOVD R4, c+56(FP) 1216 RET 1217 1218 // func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) 1219 // CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, AX = r11, DX = R6, r12=r12, BX = R1(*8) , (R0 set to 0) + use R11 + use R7 for i 1220 TEXT ·divWVW(SB),NOSPLIT,$0 1221 MOVD z+0(FP), R2 1222 MOVD xn+24(FP), R10 // r = xn 1223 MOVD x+32(FP), R8 1224 MOVD y+56(FP), R9 1225 MOVD z_len+8(FP), R7 // i = z 1226 SLD $3, R7, R1 // i*8 1227 MOVD $0, R0 // make sure it's zero 1228 BR E7 1229 1230 L7: MOVD (R8)(R1*1), R11 1231 WORD $0xB98700A9 //DLGR R10,R9 1232 MOVD R11, (R2)(R1*1) 1233 1234 E7: SUB $1, R7 // i-- 1235 SUB $8, R1 1236 BGE L7 // i >= 0 1237 1238 MOVD R10, r+64(FP) 1239 RET 1240 1241 // func bitLen(x Word) (n int) 1242 TEXT ·bitLen(SB),NOSPLIT,$0 1243 MOVD x+0(FP), R2 1244 FLOGR R2, R2 // clobbers R3 1245 MOVD $64, R3 1246 SUB R2, R3 1247 MOVD R3, n+8(FP) 1248 RET 1249