github.com/SandwichDev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/bytealg/index_arm64.s (about)

     1  // Copyright 2018 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  #include "go_asm.h"
     6  #include "textflag.h"
     7  
     8  TEXT ·Index(SB),NOSPLIT,$0-56
     9  	MOVD	a_base+0(FP), R0
    10  	MOVD	a_len+8(FP), R1
    11  	MOVD	b_base+24(FP), R2
    12  	MOVD	b_len+32(FP), R3
    13  	MOVD	$ret+48(FP), R9
    14  	B	indexbody<>(SB)
    15  
    16  TEXT ·IndexString(SB),NOSPLIT,$0-40
    17  	MOVD	a_base+0(FP), R0
    18  	MOVD	a_len+8(FP), R1
    19  	MOVD	b_base+16(FP), R2
    20  	MOVD	b_len+24(FP), R3
    21  	MOVD	$ret+32(FP), R9
    22  	B	indexbody<>(SB)
    23  
    24  // input:
    25  //   R0: haystack
    26  //   R1: length of haystack
    27  //   R2: needle
    28  //   R3: length of needle (2 <= len <= 32)
    29  //   R9: address to put result
    30  TEXT indexbody<>(SB),NOSPLIT,$0-56
    31  	// main idea is to load 'sep' into separate register(s)
    32  	// to avoid repeatedly re-load it again and again
    33  	// for sebsequent substring comparisons
    34  	SUB	R3, R1, R4
    35  	// R4 contains the start of last substring for comparison
    36  	ADD	R0, R4, R4
    37  	ADD	$1, R0, R8
    38  
    39  	CMP	$8, R3
    40  	BHI	greater_8
    41  	TBZ	$3, R3, len_2_7
    42  len_8:
    43  	// R5 contains 8-byte of sep
    44  	MOVD	(R2), R5
    45  loop_8:
    46  	// R6 contains substring for comparison
    47  	CMP	R4, R0
    48  	BHI	not_found
    49  	MOVD.P	1(R0), R6
    50  	CMP	R5, R6
    51  	BNE	loop_8
    52  	B	found
    53  len_2_7:
    54  	TBZ	$2, R3, len_2_3
    55  	TBZ	$1, R3, len_4_5
    56  	TBZ	$0, R3, len_6
    57  len_7:
    58  	// R5 and R6 contain 7-byte of sep
    59  	MOVWU	(R2), R5
    60  	// 1-byte overlap with R5
    61  	MOVWU	3(R2), R6
    62  loop_7:
    63  	CMP	R4, R0
    64  	BHI	not_found
    65  	MOVWU.P	1(R0), R3
    66  	CMP	R5, R3
    67  	BNE	loop_7
    68  	MOVWU	2(R0), R3
    69  	CMP	R6, R3
    70  	BNE	loop_7
    71  	B	found
    72  len_6:
    73  	// R5 and R6 contain 6-byte of sep
    74  	MOVWU	(R2), R5
    75  	MOVHU	4(R2), R6
    76  loop_6:
    77  	CMP	R4, R0
    78  	BHI	not_found
    79  	MOVWU.P	1(R0), R3
    80  	CMP	R5, R3
    81  	BNE	loop_6
    82  	MOVHU	3(R0), R3
    83  	CMP	R6, R3
    84  	BNE	loop_6
    85  	B	found
    86  len_4_5:
    87  	TBZ	$0, R3, len_4
    88  len_5:
    89  	// R5 and R7 contain 5-byte of sep
    90  	MOVWU	(R2), R5
    91  	MOVBU	4(R2), R7
    92  loop_5:
    93  	CMP	R4, R0
    94  	BHI	not_found
    95  	MOVWU.P	1(R0), R3
    96  	CMP	R5, R3
    97  	BNE	loop_5
    98  	MOVBU	3(R0), R3
    99  	CMP	R7, R3
   100  	BNE	loop_5
   101  	B	found
   102  len_4:
   103  	// R5 contains 4-byte of sep
   104  	MOVWU	(R2), R5
   105  loop_4:
   106  	CMP	R4, R0
   107  	BHI	not_found
   108  	MOVWU.P	1(R0), R6
   109  	CMP	R5, R6
   110  	BNE	loop_4
   111  	B	found
   112  len_2_3:
   113  	TBZ	$0, R3, len_2
   114  len_3:
   115  	// R6 and R7 contain 3-byte of sep
   116  	MOVHU	(R2), R6
   117  	MOVBU	2(R2), R7
   118  loop_3:
   119  	CMP	R4, R0
   120  	BHI	not_found
   121  	MOVHU.P	1(R0), R3
   122  	CMP	R6, R3
   123  	BNE	loop_3
   124  	MOVBU	1(R0), R3
   125  	CMP	R7, R3
   126  	BNE	loop_3
   127  	B	found
   128  len_2:
   129  	// R5 contains 2-byte of sep
   130  	MOVHU	(R2), R5
   131  loop_2:
   132  	CMP	R4, R0
   133  	BHI	not_found
   134  	MOVHU.P	1(R0), R6
   135  	CMP	R5, R6
   136  	BNE	loop_2
   137  found:
   138  	SUB	R8, R0, R0
   139  	MOVD	R0, (R9)
   140  	RET
   141  not_found:
   142  	MOVD	$-1, R0
   143  	MOVD	R0, (R9)
   144  	RET
   145  greater_8:
   146  	SUB	$9, R3, R11	// len(sep) - 9, offset of R0 for last 8 bytes
   147  	CMP	$16, R3
   148  	BHI	greater_16
   149  len_9_16:
   150  	MOVD.P	8(R2), R5	// R5 contains the first 8-byte of sep
   151  	SUB	$16, R3, R7	// len(sep) - 16, offset of R2 for last 8 bytes
   152  	MOVD	(R2)(R7), R6	// R6 contains the last 8-byte of sep
   153  loop_9_16:
   154  	// search the first 8 bytes first
   155  	CMP	R4, R0
   156  	BHI	not_found
   157  	MOVD.P	1(R0), R7
   158  	CMP	R5, R7
   159  	BNE	loop_9_16
   160  	MOVD	(R0)(R11), R7
   161  	CMP	R6, R7		// compare the last 8 bytes
   162  	BNE	loop_9_16
   163  	B	found
   164  greater_16:
   165  	CMP	$24, R3
   166  	BHI	len_25_32
   167  len_17_24:
   168  	LDP.P	16(R2), (R5, R6)	// R5 and R6 contain the first 16-byte of sep
   169  	SUB	$24, R3, R10		// len(sep) - 24
   170  	MOVD	(R2)(R10), R7		// R7 contains the last 8-byte of sep
   171  loop_17_24:
   172  	// search the first 16 bytes first
   173  	CMP	R4, R0
   174  	BHI	not_found
   175  	MOVD.P	1(R0), R10
   176  	CMP	R5, R10
   177  	BNE	loop_17_24
   178  	MOVD	7(R0), R10
   179  	CMP	R6, R10
   180  	BNE	loop_17_24
   181  	MOVD	(R0)(R11), R10
   182  	CMP	R7, R10		// compare the last 8 bytes
   183  	BNE	loop_17_24
   184  	B	found
   185  len_25_32:
   186  	LDP.P	16(R2), (R5, R6)
   187  	MOVD.P	8(R2), R7	// R5, R6 and R7 contain the first 24-byte of sep
   188  	SUB	$32, R3, R12	// len(sep) - 32
   189  	MOVD	(R2)(R12), R10	// R10 contains the last 8-byte of sep
   190  loop_25_32:
   191  	// search the first 24 bytes first
   192  	CMP	R4, R0
   193  	BHI	not_found
   194  	MOVD.P	1(R0), R12
   195  	CMP	R5, R12
   196  	BNE	loop_25_32
   197  	MOVD	7(R0), R12
   198  	CMP	R6, R12
   199  	BNE	loop_25_32
   200  	MOVD	15(R0), R12
   201  	CMP	R7, R12
   202  	BNE	loop_25_32
   203  	MOVD	(R0)(R11), R12
   204  	CMP	R10, R12	// compare the last 8 bytes
   205  	BNE	loop_25_32
   206  	B	found