github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/bloom/xxhash/xxhash_amd64.s (about)

     1  //go:build !purego
     2  
     3  #include "textflag.h"
     4  
     5  #define PRIME1 0x9E3779B185EBCA87
     6  #define PRIME2 0xC2B2AE3D27D4EB4F
     7  #define PRIME3 0x165667B19E3779F9
     8  #define PRIME4 0x85EBCA77C2B2AE63
     9  #define PRIME5 0x27D4EB2F165667C5
    10  
    11  DATA prime3<>+0(SB)/8, $PRIME3
    12  GLOBL prime3<>(SB), RODATA|NOPTR, $8
    13  
    14  DATA prime5<>+0(SB)/8, $PRIME5
    15  GLOBL prime5<>(SB), RODATA|NOPTR, $8
    16  
    17  // Register allocation:
    18  // AX	h
    19  // SI	pointer to advance through b
    20  // DX	n
    21  // BX	loop end
    22  // R8	v1, k1
    23  // R9	v2
    24  // R10	v3
    25  // R11	v4
    26  // R12	tmp
    27  // R13	PRIME1
    28  // R14	PRIME2
    29  // DI	PRIME4
    30  
    31  // round reads from and advances the buffer pointer in SI.
    32  // It assumes that R13 has PRIME1 and R14 has PRIME2.
    33  #define round(r) \
    34  	MOVQ  (SI), R12 \
    35  	ADDQ  $8, SI    \
    36  	IMULQ R14, R12  \
    37  	ADDQ  R12, r    \
    38  	ROLQ  $31, r    \
    39  	IMULQ R13, r
    40  
    41  // mergeRound applies a merge round on the two registers acc and val.
    42  // It assumes that R13 has PRIME1, R14 has PRIME2, and DI has PRIME4.
    43  #define mergeRound(acc, val) \
    44  	IMULQ R14, val \
    45  	ROLQ  $31, val \
    46  	IMULQ R13, val \
    47  	XORQ  val, acc \
    48  	IMULQ R13, acc \
    49  	ADDQ  DI, acc
    50  
    51  // func Sum64(b []byte) uint64
    52  TEXT ·Sum64(SB), NOSPLIT, $0-32
    53  	// Load fixed primes.
    54  	MOVQ $PRIME1, R13
    55  	MOVQ $PRIME2, R14
    56  	MOVQ $PRIME4, DI
    57  
    58  	// Load slice.
    59  	MOVQ b_base+0(FP), SI
    60  	MOVQ b_len+8(FP), DX
    61  	LEAQ (SI)(DX*1), BX
    62  
    63  	// The first loop limit will be len(b)-32.
    64  	SUBQ $32, BX
    65  
    66  	// Check whether we have at least one block.
    67  	CMPQ DX, $32
    68  	JLT  noBlocks
    69  
    70  	// Set up initial state (v1, v2, v3, v4).
    71  	MOVQ R13, R8
    72  	ADDQ R14, R8
    73  	MOVQ R14, R9
    74  	XORQ R10, R10
    75  	XORQ R11, R11
    76  	SUBQ R13, R11
    77  
    78  	// Loop until SI > BX.
    79  blockLoop:
    80  	round(R8)
    81  	round(R9)
    82  	round(R10)
    83  	round(R11)
    84  
    85  	CMPQ SI, BX
    86  	JLE  blockLoop
    87  
    88  	MOVQ R8, AX
    89  	ROLQ $1, AX
    90  	MOVQ R9, R12
    91  	ROLQ $7, R12
    92  	ADDQ R12, AX
    93  	MOVQ R10, R12
    94  	ROLQ $12, R12
    95  	ADDQ R12, AX
    96  	MOVQ R11, R12
    97  	ROLQ $18, R12
    98  	ADDQ R12, AX
    99  
   100  	mergeRound(AX, R8)
   101  	mergeRound(AX, R9)
   102  	mergeRound(AX, R10)
   103  	mergeRound(AX, R11)
   104  
   105  	JMP afterBlocks
   106  
   107  noBlocks:
   108  	MOVQ $PRIME5, AX
   109  
   110  afterBlocks:
   111  	ADDQ DX, AX
   112  
   113  	// Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
   114  	ADDQ $24, BX
   115  
   116  	CMPQ SI, BX
   117  	JG   fourByte
   118  
   119  wordLoop:
   120  	// Calculate k1.
   121  	MOVQ  (SI), R8
   122  	ADDQ  $8, SI
   123  	IMULQ R14, R8
   124  	ROLQ  $31, R8
   125  	IMULQ R13, R8
   126  
   127  	XORQ  R8, AX
   128  	ROLQ  $27, AX
   129  	IMULQ R13, AX
   130  	ADDQ  DI, AX
   131  
   132  	CMPQ SI, BX
   133  	JLE  wordLoop
   134  
   135  fourByte:
   136  	ADDQ $4, BX
   137  	CMPQ SI, BX
   138  	JG   singles
   139  
   140  	MOVL  (SI), R8
   141  	ADDQ  $4, SI
   142  	IMULQ R13, R8
   143  	XORQ  R8, AX
   144  
   145  	ROLQ  $23, AX
   146  	IMULQ R14, AX
   147  	ADDQ  prime3<>(SB), AX
   148  
   149  singles:
   150  	ADDQ $4, BX
   151  	CMPQ SI, BX
   152  	JGE  finalize
   153  
   154  singlesLoop:
   155  	MOVBQZX (SI), R12
   156  	ADDQ    $1, SI
   157  	IMULQ   prime5<>(SB), R12
   158  	XORQ    R12, AX
   159  
   160  	ROLQ  $11, AX
   161  	IMULQ R13, AX
   162  
   163  	CMPQ SI, BX
   164  	JL   singlesLoop
   165  
   166  finalize:
   167  	MOVQ  AX, R12
   168  	SHRQ  $33, R12
   169  	XORQ  R12, AX
   170  	IMULQ R14, AX
   171  	MOVQ  AX, R12
   172  	SHRQ  $29, R12
   173  	XORQ  R12, AX
   174  	IMULQ prime3<>(SB), AX
   175  	MOVQ  AX, R12
   176  	SHRQ  $32, R12
   177  	XORQ  R12, AX
   178  
   179  	MOVQ AX, ret+24(FP)
   180  	RET