1// +build amd64,!appengine,!gccgo 2 3#define ROUND(v0, v1, v2, v3) \ 4 ADDQ v1, v0; \ 5 RORQ $51, v1; \ 6 ADDQ v3, v2; \ 7 XORQ v0, v1; \ 8 RORQ $48, v3; \ 9 RORQ $32, v0; \ 10 XORQ v2, v3; \ 11 ADDQ v1, v2; \ 12 ADDQ v3, v0; \ 13 RORQ $43, v3; \ 14 RORQ $47, v1; \ 15 XORQ v0, v3; \ 16 XORQ v2, v1; \ 17 RORQ $32, v2 18 19// blocks(d *digest, data []uint8) 20TEXT ·blocks(SB),4,$0-32 21 MOVQ d+0(FP), BX 22 MOVQ 0(BX), R9 // R9 = v0 23 MOVQ 8(BX), R10 // R10 = v1 24 MOVQ 16(BX), R11 // R11 = v2 25 MOVQ 24(BX), R12 // R12 = v3 26 MOVQ data+8(FP), DI // DI = *uint64 27 MOVQ data_len+16(FP), SI// SI = nblocks 28 XORL DX, DX // DX = index (0) 29 SHRQ $3, SI // SI /= 8 30body: 31 CMPQ DX, SI 32 JGE end 33 MOVQ 0(DI)(DX*8), CX // CX = m 34 XORQ CX, R12 35 ROUND(R9, R10, R11, R12) 36 ROUND(R9, R10, R11, R12) 37 XORQ CX, R9 38 ADDQ $1, DX 39 JMP body 40end: 41 MOVQ R9, 0(BX) 42 MOVQ R10, 8(BX) 43 MOVQ R11, 16(BX) 44 MOVQ R12, 24(BX) 45 RET 46 47// once(d *digest) 48TEXT ·once(SB),4,$0-8 49 MOVQ d+0(FP), BX 50 MOVQ 0(BX), R9 // R9 = v0 51 MOVQ 8(BX), R10 // R10 = v1 52 MOVQ 16(BX), R11 // R11 = v2 53 MOVQ 24(BX), R12 // R12 = v3 54 MOVQ 48(BX), CX // CX = d.x[:] 55 XORQ CX, R12 56 ROUND(R9, R10, R11, R12) 57 ROUND(R9, R10, R11, R12) 58 XORQ CX, R9 59 MOVQ R9, 0(BX) 60 MOVQ R10, 8(BX) 61 MOVQ R11, 16(BX) 62 MOVQ R12, 24(BX) 63 RET 64 65// finalize(d *digest) uint64 66TEXT ·finalize(SB),4,$0-16 67 MOVQ d+0(FP), BX 68 MOVQ 0(BX), R9 // R9 = v0 69 MOVQ 8(BX), R10 // R10 = v1 70 MOVQ 16(BX), R11 // R11 = v2 71 MOVQ 24(BX), R12 // R12 = v3 72 MOVQ 48(BX), CX // CX = d.x[:] 73 XORQ CX, R12 74 ROUND(R9, R10, R11, R12) 75 ROUND(R9, R10, R11, R12) 76 XORQ CX, R9 77 NOTB R11 78 ROUND(R9, R10, R11, R12) 79 ROUND(R9, R10, R11, R12) 80 ROUND(R9, R10, R11, R12) 81 ROUND(R9, R10, R11, R12) 82 XORQ R12, R11 83 XORQ R10, R9 84 XORQ R11, R9 85 MOVQ R9, ret+8(FP) 86 RET 87 88