#include "textflag.h"
#define R10 g
#define ROUND()\
	ADD.S	R2,R0,R0;\
	ADC	R3,R1,R1;\
	EOR	R2<<13,R0,R8;\
	EOR	R3>>19,R8,R8;\
	EOR	R2>>19,R1,R11;\
	EOR	R3<<13,R11,R11;\
	ADD.S	R6,R4,R4;\
	ADC	R7,R5,R5;\
	EOR	R6<<16,R4,R2;\
	EOR	R7>>16,R2,R2;\
	EOR	R6>>16,R5,R3;\
	EOR	R7<<16,R3,R3;\
	ADD.S	R2,R1,R1;\
	ADC	R3,R0,R0;\
	EOR	R2<<21,R1,R6;\
	EOR	R3>>11,R6,R6;\
	EOR	R2>>11,R0,R7;\
	EOR	R3<<21,R7,R7;\
	ADD.S	R8,R4,R4;\
	ADC	R11,R5,R5;\
	EOR	R8<<17,R4,R2;\
	EOR	R11>>15,R2,R2;\
	EOR	R8>>15,R5,R3;\
	EOR	R11<<17,R3,R3;\
	ADD.S	R2,R1,R1;\
	ADC	R3,R0,R0;\
	EOR	R2<<13,R1,R8;\
	EOR	R3>>19,R8,R8;\
	EOR	R2>>19,R0,R11;\
	EOR	R3<<13,R11,R11;\
	ADD.S	R6,R5,R5;\
	ADC	R7,R4,R4;\
	EOR	R6<<16,R5,R2;\
	EOR	R7>>16,R2,R2;\
	EOR	R6>>16,R4,R3;\
	EOR	R7<<16,R3,R3;\
	ADD.S	R2,R0,R0;\
	ADC	R3,R1,R1;\
	EOR	R2<<21,R0,R6;\
	EOR	R3>>11,R6,R6;\
	EOR	R2>>11,R1,R7;\
	EOR	R3<<21,R7,R7;\
	ADD.S	R8,R5,R5;\
	ADC	R11,R4,R4;\
	EOR	R8<<17,R5,R2;\
	EOR	R11>>15,R2,R2;\
	EOR	R8>>15,R4,R3;\
	EOR	R11<<17,R3,R3;\

// Hash(k0, k1 uint64, b []byte) uint64
TEXT ·Hash(SB),NOSPLIT,$8-36
	MOVW	R10,sav-8(SP)
	MOVW	k0_lo+0(FP),R12
	MOVW	k0_hi+4(FP),R14
	MOVW	$0x70736575,R0
	MOVW	$0x736f6d65,R1
	MOVW	$0x6e657261,R4
	MOVW	$0x6c796765,R5
	EOR	R12,R0,R0
	EOR	R14,R1,R1
	EOR	R12,R4,R4
	EOR	R14,R5,R5
	MOVW	k1_lo+8(FP),R12
	MOVW	k1_hi+12(FP),R14
	MOVW	$0x6e646f6d,R2
	MOVW	$0x646f7261,R3
	MOVW	$0x79746573,R6
	MOVW	$0x74656462,R7
	EOR	R12,R2,R2
	EOR	R14,R3,R3
	EOR	R12,R6,R6
	EOR	R14,R7,R7
	MOVW	b+16(FP),R10
	MOVW	b_len+20(FP),R11
	ADD	R10,R11,R11
	MOVW	R11,endb-4(SP)
	AND.S	$3,R10,R8
	BNE	hashloopunaligned
hashloop:
	MOVW	endb-4(SP),R11
	SUB	R10,R11,R11
	SUB.S	$8,R11
	BLO	hashend
	MOVM.IA.W (R10),[R12,R14]
	EOR	R12,R6,R6
	EOR	R14,R7,R7
	ROUND()
	EOR	R12,R0,R0
	EOR	R14,R1,R1
	B	hashloop
hashloopunaligned:
	MOVW	endb-4(SP),R11
	SUB	R10,R11,R11
	SUB.S	$8,R11
	BLO	hashend
	MOVB	(R10),R12
	MOVB	1(R10),R11
	ORR	R11<<8,R12,R12
	MOVB	2(R10),R11
	ORR	R11<<16,R12,R12
	MOVB	3(R10),R11
	ORR	R11<<24,R12,R12
	MOVB	4(R10),R14
	MOVB	5(R10),R11
	ORR	R11<<8,R14,R14
	MOVB	6(R10),R11
	ORR	R11<<16,R14,R14
	MOVB	7(R10),R11
	ORR	R11<<24,R14,R14
	ADD	$8,R10,R10
	EOR	R12,R6,R6
	EOR	R14,R7,R7
	ROUND()
	EOR	R12,R0,R0
	EOR	R14,R1,R1
	B	hashloopunaligned
hashend:
	MOVW	$0x0,R12
	MOVW	$0x0,R14
	RSB	$0,R11,R11
	AND.S	$7,R11
	BEQ	hashlast
	MOVW	(R10),R12
	SLL	$3,R11
	AND	$63,R11
	SUB.S	$32,R11,R11
	BEQ	hashlast
	BLO	hashhi
	MOVW	R12<<R11,R12
	MOVW	R12>>R11,R12
	B	hashlast
hashhi:
	ADD	$32,R11
	MOVW	4(R10),R14
	MOVW	R14<<R11,R14
	MOVW	R14>>R11,R14
hashlast:
	MOVW	b_len+20(FP),R11
	ORR	R11<<24,R14,R14
	EOR	R12,R6,R6
	EOR	R14,R7,R7
	ROUND()
	EOR	R12,R0,R0
	EOR	R14,R1,R1
	EOR	$255,R4
	ROUND()
	ROUND()
	EOR	R2,R0,R0
	EOR	R3,R1,R1
	EOR	R6,R4,R4
	EOR	R7,R5,R5
	EOR	R4,R0,R0
	EOR	R5,R1,R1
	MOVW	sav-8(SP),R10
	MOVW	R0,ret_lo+28(FP)
	MOVW	R1,ret_hi+32(FP)
	RET
