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
9 TEXT ·IndexByte<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40
10 #ifndef GOEXPERIMENT_regabiargs
11 MOVD b_base+0(FP), R2// b_base => R2
12 MOVD b_len+8(FP), R3 // b_len => R3
13 MOVBZ c+24(FP), R4 // c => R4
14 MOVD $ret+32(FP), R5 // &ret => R5
15 #else
16 MOVD R5, R4
17 AND $0xff, R4
18 #endif
19 BR indexbytebody<>(SB)
20
21 TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
22 #ifndef GOEXPERIMENT_regabiargs
23 MOVD s_base+0(FP), R2 // s_base => R2
24 MOVD s_len+8(FP), R3 // s_len => R3
25 MOVBZ c+16(FP), R4 // c => R4
26 MOVD $ret+24(FP), R5 // &ret => R5
27 #else
28 AND $0xff, R4
29 #endif
30 BR indexbytebody<>(SB)
31
32 // input:
33 // R2: s
34 // R3: s_len
35 // R4: c -- byte sought
36 // For regabiargs output value(index) stored in R2
37 // For !regabiargs address of output value(index) stored in R5
38 TEXT indexbytebody<>(SB),NOSPLIT|NOFRAME,$0
39 CMPBEQ R3, $0, notfound
40 MOVD R2, R6 // store base for later
41 ADD R2, R3, R8 // the address after the end of the string
42 //if the length is small, use loop; otherwise, use vector or srst search
43 CMPBGE R3, $16, large
44
45 residual:
46 CMPBEQ R2, R8, notfound
47 MOVBZ 0(R2), R7
48 LA 1(R2), R2
49 CMPBNE R7, R4, residual
50
51 found:
52 SUB R6, R2
53 SUB $1, R2
54 #ifndef GOEXPERIMENT_regabiargs
55 MOVD R2, 0(R5)
56 #endif
57 RET
58
59 notfound:
60 #ifndef GOEXPERIMENT_regabiargs
61 MOVD $-1, 0(R5)
62 #else
63 MOVD $-1, R2
64 #endif
65 RET
66
67 large:
68 MOVBZ internal∕cpu·S390X+const_offsetS390xHasVX(SB), R1
69 CMPBNE R1, $0, vectorimpl
70
71 srstimpl: // no vector facility
72 MOVBZ R4, R0 // c needs to be in R0, leave until last minute as currently R0 is expected to be 0
73 srstloop:
74 WORD $0xB25E0082 // srst %r8, %r2 (search the range [R2, R8))
75 BVS srstloop // interrupted - continue
76 BGT notfoundr0
77 foundr0:
78 XOR R0, R0 // reset R0
79 SUB R6, R8 // remove base
80 #ifndef GOEXPERIMENT_regabiargs
81 MOVD R8, 0(R5)
82 #else
83 MOVD R8, R2
84 #endif
85 RET
86 notfoundr0:
87 XOR R0, R0 // reset R0
88 #ifndef GOEXPERIMENT_regabiargs
89 MOVD $-1, 0(R5)
90 #else
91 MOVD $-1, R2
92 #endif
93 RET
94
95 vectorimpl:
96 //if the address is not 16byte aligned, use loop for the header
97 MOVD R2, R8
98 AND $15, R8
99 CMPBGT R8, $0, notaligned
100
101 aligned:
102 ADD R6, R3, R8
103 MOVD R8, R7
104 AND $-16, R7
105 // replicate c across V17
106 VLVGB $0, R4, V19
107 VREPB $0, V19, V17
108
109 vectorloop:
110 CMPBGE R2, R7, residual
111 VL 0(R2), V16 // load string to be searched into V16
112 ADD $16, R2
113 VFEEBS V16, V17, V18 // search V17 in V16 and set conditional code accordingly
114 BVS vectorloop
115
116 // when vector search found c in the string
117 VLGVB $7, V18, R7 // load 7th element of V18 containing index into R7
118 SUB $16, R2
119 SUB R6, R2
120 ADD R2, R7
121 #ifndef GOEXPERIMENT_regabiargs
122 MOVD R7, 0(R5)
123 #else
124 MOVD R7, R2
125 #endif
126 RET
127
128 notaligned:
129 MOVD R2, R8
130 AND $-16, R8
131 ADD $16, R8
132 notalignedloop:
133 CMPBEQ R2, R8, aligned
134 MOVBZ 0(R2), R7
135 LA 1(R2), R2
136 CMPBNE R7, R4, notalignedloop
137 BR found
138
139
View as plain text