]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/ssa/rewriteARM64.go
84274bd506f6cd064ea8d1a27a69c98ed7861665
[gostls13.git] / src / cmd / compile / internal / ssa / rewriteARM64.go
1 // Code generated from _gen/ARM64.rules using 'go generate'; DO NOT EDIT.
2
3 package ssa
4
5 import "cmd/compile/internal/types"
6
7 func rewriteValueARM64(v *Value) bool {
8         switch v.Op {
9         case OpARM64ADCSflags:
10                 return rewriteValueARM64_OpARM64ADCSflags(v)
11         case OpARM64ADD:
12                 return rewriteValueARM64_OpARM64ADD(v)
13         case OpARM64ADDSflags:
14                 return rewriteValueARM64_OpARM64ADDSflags(v)
15         case OpARM64ADDconst:
16                 return rewriteValueARM64_OpARM64ADDconst(v)
17         case OpARM64ADDshiftLL:
18                 return rewriteValueARM64_OpARM64ADDshiftLL(v)
19         case OpARM64ADDshiftRA:
20                 return rewriteValueARM64_OpARM64ADDshiftRA(v)
21         case OpARM64ADDshiftRL:
22                 return rewriteValueARM64_OpARM64ADDshiftRL(v)
23         case OpARM64AND:
24                 return rewriteValueARM64_OpARM64AND(v)
25         case OpARM64ANDconst:
26                 return rewriteValueARM64_OpARM64ANDconst(v)
27         case OpARM64ANDshiftLL:
28                 return rewriteValueARM64_OpARM64ANDshiftLL(v)
29         case OpARM64ANDshiftRA:
30                 return rewriteValueARM64_OpARM64ANDshiftRA(v)
31         case OpARM64ANDshiftRL:
32                 return rewriteValueARM64_OpARM64ANDshiftRL(v)
33         case OpARM64ANDshiftRO:
34                 return rewriteValueARM64_OpARM64ANDshiftRO(v)
35         case OpARM64BIC:
36                 return rewriteValueARM64_OpARM64BIC(v)
37         case OpARM64BICshiftLL:
38                 return rewriteValueARM64_OpARM64BICshiftLL(v)
39         case OpARM64BICshiftRA:
40                 return rewriteValueARM64_OpARM64BICshiftRA(v)
41         case OpARM64BICshiftRL:
42                 return rewriteValueARM64_OpARM64BICshiftRL(v)
43         case OpARM64BICshiftRO:
44                 return rewriteValueARM64_OpARM64BICshiftRO(v)
45         case OpARM64CMN:
46                 return rewriteValueARM64_OpARM64CMN(v)
47         case OpARM64CMNW:
48                 return rewriteValueARM64_OpARM64CMNW(v)
49         case OpARM64CMNWconst:
50                 return rewriteValueARM64_OpARM64CMNWconst(v)
51         case OpARM64CMNconst:
52                 return rewriteValueARM64_OpARM64CMNconst(v)
53         case OpARM64CMNshiftLL:
54                 return rewriteValueARM64_OpARM64CMNshiftLL(v)
55         case OpARM64CMNshiftRA:
56                 return rewriteValueARM64_OpARM64CMNshiftRA(v)
57         case OpARM64CMNshiftRL:
58                 return rewriteValueARM64_OpARM64CMNshiftRL(v)
59         case OpARM64CMP:
60                 return rewriteValueARM64_OpARM64CMP(v)
61         case OpARM64CMPW:
62                 return rewriteValueARM64_OpARM64CMPW(v)
63         case OpARM64CMPWconst:
64                 return rewriteValueARM64_OpARM64CMPWconst(v)
65         case OpARM64CMPconst:
66                 return rewriteValueARM64_OpARM64CMPconst(v)
67         case OpARM64CMPshiftLL:
68                 return rewriteValueARM64_OpARM64CMPshiftLL(v)
69         case OpARM64CMPshiftRA:
70                 return rewriteValueARM64_OpARM64CMPshiftRA(v)
71         case OpARM64CMPshiftRL:
72                 return rewriteValueARM64_OpARM64CMPshiftRL(v)
73         case OpARM64CSEL:
74                 return rewriteValueARM64_OpARM64CSEL(v)
75         case OpARM64CSEL0:
76                 return rewriteValueARM64_OpARM64CSEL0(v)
77         case OpARM64CSETM:
78                 return rewriteValueARM64_OpARM64CSETM(v)
79         case OpARM64CSINC:
80                 return rewriteValueARM64_OpARM64CSINC(v)
81         case OpARM64CSINV:
82                 return rewriteValueARM64_OpARM64CSINV(v)
83         case OpARM64CSNEG:
84                 return rewriteValueARM64_OpARM64CSNEG(v)
85         case OpARM64DIV:
86                 return rewriteValueARM64_OpARM64DIV(v)
87         case OpARM64DIVW:
88                 return rewriteValueARM64_OpARM64DIVW(v)
89         case OpARM64EON:
90                 return rewriteValueARM64_OpARM64EON(v)
91         case OpARM64EONshiftLL:
92                 return rewriteValueARM64_OpARM64EONshiftLL(v)
93         case OpARM64EONshiftRA:
94                 return rewriteValueARM64_OpARM64EONshiftRA(v)
95         case OpARM64EONshiftRL:
96                 return rewriteValueARM64_OpARM64EONshiftRL(v)
97         case OpARM64EONshiftRO:
98                 return rewriteValueARM64_OpARM64EONshiftRO(v)
99         case OpARM64Equal:
100                 return rewriteValueARM64_OpARM64Equal(v)
101         case OpARM64FADDD:
102                 return rewriteValueARM64_OpARM64FADDD(v)
103         case OpARM64FADDS:
104                 return rewriteValueARM64_OpARM64FADDS(v)
105         case OpARM64FCMPD:
106                 return rewriteValueARM64_OpARM64FCMPD(v)
107         case OpARM64FCMPS:
108                 return rewriteValueARM64_OpARM64FCMPS(v)
109         case OpARM64FMOVDfpgp:
110                 return rewriteValueARM64_OpARM64FMOVDfpgp(v)
111         case OpARM64FMOVDgpfp:
112                 return rewriteValueARM64_OpARM64FMOVDgpfp(v)
113         case OpARM64FMOVDload:
114                 return rewriteValueARM64_OpARM64FMOVDload(v)
115         case OpARM64FMOVDloadidx:
116                 return rewriteValueARM64_OpARM64FMOVDloadidx(v)
117         case OpARM64FMOVDloadidx8:
118                 return rewriteValueARM64_OpARM64FMOVDloadidx8(v)
119         case OpARM64FMOVDstore:
120                 return rewriteValueARM64_OpARM64FMOVDstore(v)
121         case OpARM64FMOVDstoreidx:
122                 return rewriteValueARM64_OpARM64FMOVDstoreidx(v)
123         case OpARM64FMOVDstoreidx8:
124                 return rewriteValueARM64_OpARM64FMOVDstoreidx8(v)
125         case OpARM64FMOVSload:
126                 return rewriteValueARM64_OpARM64FMOVSload(v)
127         case OpARM64FMOVSloadidx:
128                 return rewriteValueARM64_OpARM64FMOVSloadidx(v)
129         case OpARM64FMOVSloadidx4:
130                 return rewriteValueARM64_OpARM64FMOVSloadidx4(v)
131         case OpARM64FMOVSstore:
132                 return rewriteValueARM64_OpARM64FMOVSstore(v)
133         case OpARM64FMOVSstoreidx:
134                 return rewriteValueARM64_OpARM64FMOVSstoreidx(v)
135         case OpARM64FMOVSstoreidx4:
136                 return rewriteValueARM64_OpARM64FMOVSstoreidx4(v)
137         case OpARM64FMULD:
138                 return rewriteValueARM64_OpARM64FMULD(v)
139         case OpARM64FMULS:
140                 return rewriteValueARM64_OpARM64FMULS(v)
141         case OpARM64FNEGD:
142                 return rewriteValueARM64_OpARM64FNEGD(v)
143         case OpARM64FNEGS:
144                 return rewriteValueARM64_OpARM64FNEGS(v)
145         case OpARM64FNMULD:
146                 return rewriteValueARM64_OpARM64FNMULD(v)
147         case OpARM64FNMULS:
148                 return rewriteValueARM64_OpARM64FNMULS(v)
149         case OpARM64FSUBD:
150                 return rewriteValueARM64_OpARM64FSUBD(v)
151         case OpARM64FSUBS:
152                 return rewriteValueARM64_OpARM64FSUBS(v)
153         case OpARM64GreaterEqual:
154                 return rewriteValueARM64_OpARM64GreaterEqual(v)
155         case OpARM64GreaterEqualF:
156                 return rewriteValueARM64_OpARM64GreaterEqualF(v)
157         case OpARM64GreaterEqualU:
158                 return rewriteValueARM64_OpARM64GreaterEqualU(v)
159         case OpARM64GreaterThan:
160                 return rewriteValueARM64_OpARM64GreaterThan(v)
161         case OpARM64GreaterThanF:
162                 return rewriteValueARM64_OpARM64GreaterThanF(v)
163         case OpARM64GreaterThanU:
164                 return rewriteValueARM64_OpARM64GreaterThanU(v)
165         case OpARM64LDP:
166                 return rewriteValueARM64_OpARM64LDP(v)
167         case OpARM64LessEqual:
168                 return rewriteValueARM64_OpARM64LessEqual(v)
169         case OpARM64LessEqualF:
170                 return rewriteValueARM64_OpARM64LessEqualF(v)
171         case OpARM64LessEqualU:
172                 return rewriteValueARM64_OpARM64LessEqualU(v)
173         case OpARM64LessThan:
174                 return rewriteValueARM64_OpARM64LessThan(v)
175         case OpARM64LessThanF:
176                 return rewriteValueARM64_OpARM64LessThanF(v)
177         case OpARM64LessThanU:
178                 return rewriteValueARM64_OpARM64LessThanU(v)
179         case OpARM64MADD:
180                 return rewriteValueARM64_OpARM64MADD(v)
181         case OpARM64MADDW:
182                 return rewriteValueARM64_OpARM64MADDW(v)
183         case OpARM64MNEG:
184                 return rewriteValueARM64_OpARM64MNEG(v)
185         case OpARM64MNEGW:
186                 return rewriteValueARM64_OpARM64MNEGW(v)
187         case OpARM64MOD:
188                 return rewriteValueARM64_OpARM64MOD(v)
189         case OpARM64MODW:
190                 return rewriteValueARM64_OpARM64MODW(v)
191         case OpARM64MOVBUload:
192                 return rewriteValueARM64_OpARM64MOVBUload(v)
193         case OpARM64MOVBUloadidx:
194                 return rewriteValueARM64_OpARM64MOVBUloadidx(v)
195         case OpARM64MOVBUreg:
196                 return rewriteValueARM64_OpARM64MOVBUreg(v)
197         case OpARM64MOVBload:
198                 return rewriteValueARM64_OpARM64MOVBload(v)
199         case OpARM64MOVBloadidx:
200                 return rewriteValueARM64_OpARM64MOVBloadidx(v)
201         case OpARM64MOVBreg:
202                 return rewriteValueARM64_OpARM64MOVBreg(v)
203         case OpARM64MOVBstore:
204                 return rewriteValueARM64_OpARM64MOVBstore(v)
205         case OpARM64MOVBstoreidx:
206                 return rewriteValueARM64_OpARM64MOVBstoreidx(v)
207         case OpARM64MOVBstorezero:
208                 return rewriteValueARM64_OpARM64MOVBstorezero(v)
209         case OpARM64MOVBstorezeroidx:
210                 return rewriteValueARM64_OpARM64MOVBstorezeroidx(v)
211         case OpARM64MOVDload:
212                 return rewriteValueARM64_OpARM64MOVDload(v)
213         case OpARM64MOVDloadidx:
214                 return rewriteValueARM64_OpARM64MOVDloadidx(v)
215         case OpARM64MOVDloadidx8:
216                 return rewriteValueARM64_OpARM64MOVDloadidx8(v)
217         case OpARM64MOVDnop:
218                 return rewriteValueARM64_OpARM64MOVDnop(v)
219         case OpARM64MOVDreg:
220                 return rewriteValueARM64_OpARM64MOVDreg(v)
221         case OpARM64MOVDstore:
222                 return rewriteValueARM64_OpARM64MOVDstore(v)
223         case OpARM64MOVDstoreidx:
224                 return rewriteValueARM64_OpARM64MOVDstoreidx(v)
225         case OpARM64MOVDstoreidx8:
226                 return rewriteValueARM64_OpARM64MOVDstoreidx8(v)
227         case OpARM64MOVDstorezero:
228                 return rewriteValueARM64_OpARM64MOVDstorezero(v)
229         case OpARM64MOVDstorezeroidx:
230                 return rewriteValueARM64_OpARM64MOVDstorezeroidx(v)
231         case OpARM64MOVDstorezeroidx8:
232                 return rewriteValueARM64_OpARM64MOVDstorezeroidx8(v)
233         case OpARM64MOVHUload:
234                 return rewriteValueARM64_OpARM64MOVHUload(v)
235         case OpARM64MOVHUloadidx:
236                 return rewriteValueARM64_OpARM64MOVHUloadidx(v)
237         case OpARM64MOVHUloadidx2:
238                 return rewriteValueARM64_OpARM64MOVHUloadidx2(v)
239         case OpARM64MOVHUreg:
240                 return rewriteValueARM64_OpARM64MOVHUreg(v)
241         case OpARM64MOVHload:
242                 return rewriteValueARM64_OpARM64MOVHload(v)
243         case OpARM64MOVHloadidx:
244                 return rewriteValueARM64_OpARM64MOVHloadidx(v)
245         case OpARM64MOVHloadidx2:
246                 return rewriteValueARM64_OpARM64MOVHloadidx2(v)
247         case OpARM64MOVHreg:
248                 return rewriteValueARM64_OpARM64MOVHreg(v)
249         case OpARM64MOVHstore:
250                 return rewriteValueARM64_OpARM64MOVHstore(v)
251         case OpARM64MOVHstoreidx:
252                 return rewriteValueARM64_OpARM64MOVHstoreidx(v)
253         case OpARM64MOVHstoreidx2:
254                 return rewriteValueARM64_OpARM64MOVHstoreidx2(v)
255         case OpARM64MOVHstorezero:
256                 return rewriteValueARM64_OpARM64MOVHstorezero(v)
257         case OpARM64MOVHstorezeroidx:
258                 return rewriteValueARM64_OpARM64MOVHstorezeroidx(v)
259         case OpARM64MOVHstorezeroidx2:
260                 return rewriteValueARM64_OpARM64MOVHstorezeroidx2(v)
261         case OpARM64MOVQstorezero:
262                 return rewriteValueARM64_OpARM64MOVQstorezero(v)
263         case OpARM64MOVWUload:
264                 return rewriteValueARM64_OpARM64MOVWUload(v)
265         case OpARM64MOVWUloadidx:
266                 return rewriteValueARM64_OpARM64MOVWUloadidx(v)
267         case OpARM64MOVWUloadidx4:
268                 return rewriteValueARM64_OpARM64MOVWUloadidx4(v)
269         case OpARM64MOVWUreg:
270                 return rewriteValueARM64_OpARM64MOVWUreg(v)
271         case OpARM64MOVWload:
272                 return rewriteValueARM64_OpARM64MOVWload(v)
273         case OpARM64MOVWloadidx:
274                 return rewriteValueARM64_OpARM64MOVWloadidx(v)
275         case OpARM64MOVWloadidx4:
276                 return rewriteValueARM64_OpARM64MOVWloadidx4(v)
277         case OpARM64MOVWreg:
278                 return rewriteValueARM64_OpARM64MOVWreg(v)
279         case OpARM64MOVWstore:
280                 return rewriteValueARM64_OpARM64MOVWstore(v)
281         case OpARM64MOVWstoreidx:
282                 return rewriteValueARM64_OpARM64MOVWstoreidx(v)
283         case OpARM64MOVWstoreidx4:
284                 return rewriteValueARM64_OpARM64MOVWstoreidx4(v)
285         case OpARM64MOVWstorezero:
286                 return rewriteValueARM64_OpARM64MOVWstorezero(v)
287         case OpARM64MOVWstorezeroidx:
288                 return rewriteValueARM64_OpARM64MOVWstorezeroidx(v)
289         case OpARM64MOVWstorezeroidx4:
290                 return rewriteValueARM64_OpARM64MOVWstorezeroidx4(v)
291         case OpARM64MSUB:
292                 return rewriteValueARM64_OpARM64MSUB(v)
293         case OpARM64MSUBW:
294                 return rewriteValueARM64_OpARM64MSUBW(v)
295         case OpARM64MUL:
296                 return rewriteValueARM64_OpARM64MUL(v)
297         case OpARM64MULW:
298                 return rewriteValueARM64_OpARM64MULW(v)
299         case OpARM64MVN:
300                 return rewriteValueARM64_OpARM64MVN(v)
301         case OpARM64MVNshiftLL:
302                 return rewriteValueARM64_OpARM64MVNshiftLL(v)
303         case OpARM64MVNshiftRA:
304                 return rewriteValueARM64_OpARM64MVNshiftRA(v)
305         case OpARM64MVNshiftRL:
306                 return rewriteValueARM64_OpARM64MVNshiftRL(v)
307         case OpARM64MVNshiftRO:
308                 return rewriteValueARM64_OpARM64MVNshiftRO(v)
309         case OpARM64NEG:
310                 return rewriteValueARM64_OpARM64NEG(v)
311         case OpARM64NEGshiftLL:
312                 return rewriteValueARM64_OpARM64NEGshiftLL(v)
313         case OpARM64NEGshiftRA:
314                 return rewriteValueARM64_OpARM64NEGshiftRA(v)
315         case OpARM64NEGshiftRL:
316                 return rewriteValueARM64_OpARM64NEGshiftRL(v)
317         case OpARM64NotEqual:
318                 return rewriteValueARM64_OpARM64NotEqual(v)
319         case OpARM64OR:
320                 return rewriteValueARM64_OpARM64OR(v)
321         case OpARM64ORN:
322                 return rewriteValueARM64_OpARM64ORN(v)
323         case OpARM64ORNshiftLL:
324                 return rewriteValueARM64_OpARM64ORNshiftLL(v)
325         case OpARM64ORNshiftRA:
326                 return rewriteValueARM64_OpARM64ORNshiftRA(v)
327         case OpARM64ORNshiftRL:
328                 return rewriteValueARM64_OpARM64ORNshiftRL(v)
329         case OpARM64ORNshiftRO:
330                 return rewriteValueARM64_OpARM64ORNshiftRO(v)
331         case OpARM64ORconst:
332                 return rewriteValueARM64_OpARM64ORconst(v)
333         case OpARM64ORshiftLL:
334                 return rewriteValueARM64_OpARM64ORshiftLL(v)
335         case OpARM64ORshiftRA:
336                 return rewriteValueARM64_OpARM64ORshiftRA(v)
337         case OpARM64ORshiftRL:
338                 return rewriteValueARM64_OpARM64ORshiftRL(v)
339         case OpARM64ORshiftRO:
340                 return rewriteValueARM64_OpARM64ORshiftRO(v)
341         case OpARM64REV:
342                 return rewriteValueARM64_OpARM64REV(v)
343         case OpARM64REVW:
344                 return rewriteValueARM64_OpARM64REVW(v)
345         case OpARM64ROR:
346                 return rewriteValueARM64_OpARM64ROR(v)
347         case OpARM64RORW:
348                 return rewriteValueARM64_OpARM64RORW(v)
349         case OpARM64SBCSflags:
350                 return rewriteValueARM64_OpARM64SBCSflags(v)
351         case OpARM64SLL:
352                 return rewriteValueARM64_OpARM64SLL(v)
353         case OpARM64SLLconst:
354                 return rewriteValueARM64_OpARM64SLLconst(v)
355         case OpARM64SRA:
356                 return rewriteValueARM64_OpARM64SRA(v)
357         case OpARM64SRAconst:
358                 return rewriteValueARM64_OpARM64SRAconst(v)
359         case OpARM64SRL:
360                 return rewriteValueARM64_OpARM64SRL(v)
361         case OpARM64SRLconst:
362                 return rewriteValueARM64_OpARM64SRLconst(v)
363         case OpARM64STP:
364                 return rewriteValueARM64_OpARM64STP(v)
365         case OpARM64SUB:
366                 return rewriteValueARM64_OpARM64SUB(v)
367         case OpARM64SUBconst:
368                 return rewriteValueARM64_OpARM64SUBconst(v)
369         case OpARM64SUBshiftLL:
370                 return rewriteValueARM64_OpARM64SUBshiftLL(v)
371         case OpARM64SUBshiftRA:
372                 return rewriteValueARM64_OpARM64SUBshiftRA(v)
373         case OpARM64SUBshiftRL:
374                 return rewriteValueARM64_OpARM64SUBshiftRL(v)
375         case OpARM64TST:
376                 return rewriteValueARM64_OpARM64TST(v)
377         case OpARM64TSTW:
378                 return rewriteValueARM64_OpARM64TSTW(v)
379         case OpARM64TSTWconst:
380                 return rewriteValueARM64_OpARM64TSTWconst(v)
381         case OpARM64TSTconst:
382                 return rewriteValueARM64_OpARM64TSTconst(v)
383         case OpARM64TSTshiftLL:
384                 return rewriteValueARM64_OpARM64TSTshiftLL(v)
385         case OpARM64TSTshiftRA:
386                 return rewriteValueARM64_OpARM64TSTshiftRA(v)
387         case OpARM64TSTshiftRL:
388                 return rewriteValueARM64_OpARM64TSTshiftRL(v)
389         case OpARM64TSTshiftRO:
390                 return rewriteValueARM64_OpARM64TSTshiftRO(v)
391         case OpARM64UBFIZ:
392                 return rewriteValueARM64_OpARM64UBFIZ(v)
393         case OpARM64UBFX:
394                 return rewriteValueARM64_OpARM64UBFX(v)
395         case OpARM64UDIV:
396                 return rewriteValueARM64_OpARM64UDIV(v)
397         case OpARM64UDIVW:
398                 return rewriteValueARM64_OpARM64UDIVW(v)
399         case OpARM64UMOD:
400                 return rewriteValueARM64_OpARM64UMOD(v)
401         case OpARM64UMODW:
402                 return rewriteValueARM64_OpARM64UMODW(v)
403         case OpARM64XOR:
404                 return rewriteValueARM64_OpARM64XOR(v)
405         case OpARM64XORconst:
406                 return rewriteValueARM64_OpARM64XORconst(v)
407         case OpARM64XORshiftLL:
408                 return rewriteValueARM64_OpARM64XORshiftLL(v)
409         case OpARM64XORshiftRA:
410                 return rewriteValueARM64_OpARM64XORshiftRA(v)
411         case OpARM64XORshiftRL:
412                 return rewriteValueARM64_OpARM64XORshiftRL(v)
413         case OpARM64XORshiftRO:
414                 return rewriteValueARM64_OpARM64XORshiftRO(v)
415         case OpAbs:
416                 v.Op = OpARM64FABSD
417                 return true
418         case OpAdd16:
419                 v.Op = OpARM64ADD
420                 return true
421         case OpAdd32:
422                 v.Op = OpARM64ADD
423                 return true
424         case OpAdd32F:
425                 v.Op = OpARM64FADDS
426                 return true
427         case OpAdd64:
428                 v.Op = OpARM64ADD
429                 return true
430         case OpAdd64F:
431                 v.Op = OpARM64FADDD
432                 return true
433         case OpAdd8:
434                 v.Op = OpARM64ADD
435                 return true
436         case OpAddPtr:
437                 v.Op = OpARM64ADD
438                 return true
439         case OpAddr:
440                 return rewriteValueARM64_OpAddr(v)
441         case OpAnd16:
442                 v.Op = OpARM64AND
443                 return true
444         case OpAnd32:
445                 v.Op = OpARM64AND
446                 return true
447         case OpAnd64:
448                 v.Op = OpARM64AND
449                 return true
450         case OpAnd8:
451                 v.Op = OpARM64AND
452                 return true
453         case OpAndB:
454                 v.Op = OpARM64AND
455                 return true
456         case OpAtomicAdd32:
457                 v.Op = OpARM64LoweredAtomicAdd32
458                 return true
459         case OpAtomicAdd32Variant:
460                 v.Op = OpARM64LoweredAtomicAdd32Variant
461                 return true
462         case OpAtomicAdd64:
463                 v.Op = OpARM64LoweredAtomicAdd64
464                 return true
465         case OpAtomicAdd64Variant:
466                 v.Op = OpARM64LoweredAtomicAdd64Variant
467                 return true
468         case OpAtomicAnd32:
469                 return rewriteValueARM64_OpAtomicAnd32(v)
470         case OpAtomicAnd32Variant:
471                 return rewriteValueARM64_OpAtomicAnd32Variant(v)
472         case OpAtomicAnd8:
473                 return rewriteValueARM64_OpAtomicAnd8(v)
474         case OpAtomicAnd8Variant:
475                 return rewriteValueARM64_OpAtomicAnd8Variant(v)
476         case OpAtomicCompareAndSwap32:
477                 v.Op = OpARM64LoweredAtomicCas32
478                 return true
479         case OpAtomicCompareAndSwap32Variant:
480                 v.Op = OpARM64LoweredAtomicCas32Variant
481                 return true
482         case OpAtomicCompareAndSwap64:
483                 v.Op = OpARM64LoweredAtomicCas64
484                 return true
485         case OpAtomicCompareAndSwap64Variant:
486                 v.Op = OpARM64LoweredAtomicCas64Variant
487                 return true
488         case OpAtomicExchange32:
489                 v.Op = OpARM64LoweredAtomicExchange32
490                 return true
491         case OpAtomicExchange32Variant:
492                 v.Op = OpARM64LoweredAtomicExchange32Variant
493                 return true
494         case OpAtomicExchange64:
495                 v.Op = OpARM64LoweredAtomicExchange64
496                 return true
497         case OpAtomicExchange64Variant:
498                 v.Op = OpARM64LoweredAtomicExchange64Variant
499                 return true
500         case OpAtomicLoad32:
501                 v.Op = OpARM64LDARW
502                 return true
503         case OpAtomicLoad64:
504                 v.Op = OpARM64LDAR
505                 return true
506         case OpAtomicLoad8:
507                 v.Op = OpARM64LDARB
508                 return true
509         case OpAtomicLoadPtr:
510                 v.Op = OpARM64LDAR
511                 return true
512         case OpAtomicOr32:
513                 return rewriteValueARM64_OpAtomicOr32(v)
514         case OpAtomicOr32Variant:
515                 return rewriteValueARM64_OpAtomicOr32Variant(v)
516         case OpAtomicOr8:
517                 return rewriteValueARM64_OpAtomicOr8(v)
518         case OpAtomicOr8Variant:
519                 return rewriteValueARM64_OpAtomicOr8Variant(v)
520         case OpAtomicStore32:
521                 v.Op = OpARM64STLRW
522                 return true
523         case OpAtomicStore64:
524                 v.Op = OpARM64STLR
525                 return true
526         case OpAtomicStore8:
527                 v.Op = OpARM64STLRB
528                 return true
529         case OpAtomicStorePtrNoWB:
530                 v.Op = OpARM64STLR
531                 return true
532         case OpAvg64u:
533                 return rewriteValueARM64_OpAvg64u(v)
534         case OpBitLen32:
535                 return rewriteValueARM64_OpBitLen32(v)
536         case OpBitLen64:
537                 return rewriteValueARM64_OpBitLen64(v)
538         case OpBitRev16:
539                 return rewriteValueARM64_OpBitRev16(v)
540         case OpBitRev32:
541                 v.Op = OpARM64RBITW
542                 return true
543         case OpBitRev64:
544                 v.Op = OpARM64RBIT
545                 return true
546         case OpBitRev8:
547                 return rewriteValueARM64_OpBitRev8(v)
548         case OpBswap16:
549                 v.Op = OpARM64REV16W
550                 return true
551         case OpBswap32:
552                 v.Op = OpARM64REVW
553                 return true
554         case OpBswap64:
555                 v.Op = OpARM64REV
556                 return true
557         case OpCeil:
558                 v.Op = OpARM64FRINTPD
559                 return true
560         case OpClosureCall:
561                 v.Op = OpARM64CALLclosure
562                 return true
563         case OpCom16:
564                 v.Op = OpARM64MVN
565                 return true
566         case OpCom32:
567                 v.Op = OpARM64MVN
568                 return true
569         case OpCom64:
570                 v.Op = OpARM64MVN
571                 return true
572         case OpCom8:
573                 v.Op = OpARM64MVN
574                 return true
575         case OpCondSelect:
576                 return rewriteValueARM64_OpCondSelect(v)
577         case OpConst16:
578                 return rewriteValueARM64_OpConst16(v)
579         case OpConst32:
580                 return rewriteValueARM64_OpConst32(v)
581         case OpConst32F:
582                 return rewriteValueARM64_OpConst32F(v)
583         case OpConst64:
584                 return rewriteValueARM64_OpConst64(v)
585         case OpConst64F:
586                 return rewriteValueARM64_OpConst64F(v)
587         case OpConst8:
588                 return rewriteValueARM64_OpConst8(v)
589         case OpConstBool:
590                 return rewriteValueARM64_OpConstBool(v)
591         case OpConstNil:
592                 return rewriteValueARM64_OpConstNil(v)
593         case OpCtz16:
594                 return rewriteValueARM64_OpCtz16(v)
595         case OpCtz16NonZero:
596                 v.Op = OpCtz32
597                 return true
598         case OpCtz32:
599                 return rewriteValueARM64_OpCtz32(v)
600         case OpCtz32NonZero:
601                 v.Op = OpCtz32
602                 return true
603         case OpCtz64:
604                 return rewriteValueARM64_OpCtz64(v)
605         case OpCtz64NonZero:
606                 v.Op = OpCtz64
607                 return true
608         case OpCtz8:
609                 return rewriteValueARM64_OpCtz8(v)
610         case OpCtz8NonZero:
611                 v.Op = OpCtz32
612                 return true
613         case OpCvt32Fto32:
614                 v.Op = OpARM64FCVTZSSW
615                 return true
616         case OpCvt32Fto32U:
617                 v.Op = OpARM64FCVTZUSW
618                 return true
619         case OpCvt32Fto64:
620                 v.Op = OpARM64FCVTZSS
621                 return true
622         case OpCvt32Fto64F:
623                 v.Op = OpARM64FCVTSD
624                 return true
625         case OpCvt32Fto64U:
626                 v.Op = OpARM64FCVTZUS
627                 return true
628         case OpCvt32Uto32F:
629                 v.Op = OpARM64UCVTFWS
630                 return true
631         case OpCvt32Uto64F:
632                 v.Op = OpARM64UCVTFWD
633                 return true
634         case OpCvt32to32F:
635                 v.Op = OpARM64SCVTFWS
636                 return true
637         case OpCvt32to64F:
638                 v.Op = OpARM64SCVTFWD
639                 return true
640         case OpCvt64Fto32:
641                 v.Op = OpARM64FCVTZSDW
642                 return true
643         case OpCvt64Fto32F:
644                 v.Op = OpARM64FCVTDS
645                 return true
646         case OpCvt64Fto32U:
647                 v.Op = OpARM64FCVTZUDW
648                 return true
649         case OpCvt64Fto64:
650                 v.Op = OpARM64FCVTZSD
651                 return true
652         case OpCvt64Fto64U:
653                 v.Op = OpARM64FCVTZUD
654                 return true
655         case OpCvt64Uto32F:
656                 v.Op = OpARM64UCVTFS
657                 return true
658         case OpCvt64Uto64F:
659                 v.Op = OpARM64UCVTFD
660                 return true
661         case OpCvt64to32F:
662                 v.Op = OpARM64SCVTFS
663                 return true
664         case OpCvt64to64F:
665                 v.Op = OpARM64SCVTFD
666                 return true
667         case OpCvtBoolToUint8:
668                 v.Op = OpCopy
669                 return true
670         case OpDiv16:
671                 return rewriteValueARM64_OpDiv16(v)
672         case OpDiv16u:
673                 return rewriteValueARM64_OpDiv16u(v)
674         case OpDiv32:
675                 return rewriteValueARM64_OpDiv32(v)
676         case OpDiv32F:
677                 v.Op = OpARM64FDIVS
678                 return true
679         case OpDiv32u:
680                 v.Op = OpARM64UDIVW
681                 return true
682         case OpDiv64:
683                 return rewriteValueARM64_OpDiv64(v)
684         case OpDiv64F:
685                 v.Op = OpARM64FDIVD
686                 return true
687         case OpDiv64u:
688                 v.Op = OpARM64UDIV
689                 return true
690         case OpDiv8:
691                 return rewriteValueARM64_OpDiv8(v)
692         case OpDiv8u:
693                 return rewriteValueARM64_OpDiv8u(v)
694         case OpEq16:
695                 return rewriteValueARM64_OpEq16(v)
696         case OpEq32:
697                 return rewriteValueARM64_OpEq32(v)
698         case OpEq32F:
699                 return rewriteValueARM64_OpEq32F(v)
700         case OpEq64:
701                 return rewriteValueARM64_OpEq64(v)
702         case OpEq64F:
703                 return rewriteValueARM64_OpEq64F(v)
704         case OpEq8:
705                 return rewriteValueARM64_OpEq8(v)
706         case OpEqB:
707                 return rewriteValueARM64_OpEqB(v)
708         case OpEqPtr:
709                 return rewriteValueARM64_OpEqPtr(v)
710         case OpFMA:
711                 return rewriteValueARM64_OpFMA(v)
712         case OpFloor:
713                 v.Op = OpARM64FRINTMD
714                 return true
715         case OpGetCallerPC:
716                 v.Op = OpARM64LoweredGetCallerPC
717                 return true
718         case OpGetCallerSP:
719                 v.Op = OpARM64LoweredGetCallerSP
720                 return true
721         case OpGetClosurePtr:
722                 v.Op = OpARM64LoweredGetClosurePtr
723                 return true
724         case OpHmul32:
725                 return rewriteValueARM64_OpHmul32(v)
726         case OpHmul32u:
727                 return rewriteValueARM64_OpHmul32u(v)
728         case OpHmul64:
729                 v.Op = OpARM64MULH
730                 return true
731         case OpHmul64u:
732                 v.Op = OpARM64UMULH
733                 return true
734         case OpInterCall:
735                 v.Op = OpARM64CALLinter
736                 return true
737         case OpIsInBounds:
738                 return rewriteValueARM64_OpIsInBounds(v)
739         case OpIsNonNil:
740                 return rewriteValueARM64_OpIsNonNil(v)
741         case OpIsSliceInBounds:
742                 return rewriteValueARM64_OpIsSliceInBounds(v)
743         case OpLeq16:
744                 return rewriteValueARM64_OpLeq16(v)
745         case OpLeq16U:
746                 return rewriteValueARM64_OpLeq16U(v)
747         case OpLeq32:
748                 return rewriteValueARM64_OpLeq32(v)
749         case OpLeq32F:
750                 return rewriteValueARM64_OpLeq32F(v)
751         case OpLeq32U:
752                 return rewriteValueARM64_OpLeq32U(v)
753         case OpLeq64:
754                 return rewriteValueARM64_OpLeq64(v)
755         case OpLeq64F:
756                 return rewriteValueARM64_OpLeq64F(v)
757         case OpLeq64U:
758                 return rewriteValueARM64_OpLeq64U(v)
759         case OpLeq8:
760                 return rewriteValueARM64_OpLeq8(v)
761         case OpLeq8U:
762                 return rewriteValueARM64_OpLeq8U(v)
763         case OpLess16:
764                 return rewriteValueARM64_OpLess16(v)
765         case OpLess16U:
766                 return rewriteValueARM64_OpLess16U(v)
767         case OpLess32:
768                 return rewriteValueARM64_OpLess32(v)
769         case OpLess32F:
770                 return rewriteValueARM64_OpLess32F(v)
771         case OpLess32U:
772                 return rewriteValueARM64_OpLess32U(v)
773         case OpLess64:
774                 return rewriteValueARM64_OpLess64(v)
775         case OpLess64F:
776                 return rewriteValueARM64_OpLess64F(v)
777         case OpLess64U:
778                 return rewriteValueARM64_OpLess64U(v)
779         case OpLess8:
780                 return rewriteValueARM64_OpLess8(v)
781         case OpLess8U:
782                 return rewriteValueARM64_OpLess8U(v)
783         case OpLoad:
784                 return rewriteValueARM64_OpLoad(v)
785         case OpLocalAddr:
786                 return rewriteValueARM64_OpLocalAddr(v)
787         case OpLsh16x16:
788                 return rewriteValueARM64_OpLsh16x16(v)
789         case OpLsh16x32:
790                 return rewriteValueARM64_OpLsh16x32(v)
791         case OpLsh16x64:
792                 return rewriteValueARM64_OpLsh16x64(v)
793         case OpLsh16x8:
794                 return rewriteValueARM64_OpLsh16x8(v)
795         case OpLsh32x16:
796                 return rewriteValueARM64_OpLsh32x16(v)
797         case OpLsh32x32:
798                 return rewriteValueARM64_OpLsh32x32(v)
799         case OpLsh32x64:
800                 return rewriteValueARM64_OpLsh32x64(v)
801         case OpLsh32x8:
802                 return rewriteValueARM64_OpLsh32x8(v)
803         case OpLsh64x16:
804                 return rewriteValueARM64_OpLsh64x16(v)
805         case OpLsh64x32:
806                 return rewriteValueARM64_OpLsh64x32(v)
807         case OpLsh64x64:
808                 return rewriteValueARM64_OpLsh64x64(v)
809         case OpLsh64x8:
810                 return rewriteValueARM64_OpLsh64x8(v)
811         case OpLsh8x16:
812                 return rewriteValueARM64_OpLsh8x16(v)
813         case OpLsh8x32:
814                 return rewriteValueARM64_OpLsh8x32(v)
815         case OpLsh8x64:
816                 return rewriteValueARM64_OpLsh8x64(v)
817         case OpLsh8x8:
818                 return rewriteValueARM64_OpLsh8x8(v)
819         case OpMax32F:
820                 v.Op = OpARM64FMAXS
821                 return true
822         case OpMax64F:
823                 v.Op = OpARM64FMAXD
824                 return true
825         case OpMin32F:
826                 v.Op = OpARM64FMINS
827                 return true
828         case OpMin64F:
829                 v.Op = OpARM64FMIND
830                 return true
831         case OpMod16:
832                 return rewriteValueARM64_OpMod16(v)
833         case OpMod16u:
834                 return rewriteValueARM64_OpMod16u(v)
835         case OpMod32:
836                 return rewriteValueARM64_OpMod32(v)
837         case OpMod32u:
838                 v.Op = OpARM64UMODW
839                 return true
840         case OpMod64:
841                 return rewriteValueARM64_OpMod64(v)
842         case OpMod64u:
843                 v.Op = OpARM64UMOD
844                 return true
845         case OpMod8:
846                 return rewriteValueARM64_OpMod8(v)
847         case OpMod8u:
848                 return rewriteValueARM64_OpMod8u(v)
849         case OpMove:
850                 return rewriteValueARM64_OpMove(v)
851         case OpMul16:
852                 v.Op = OpARM64MULW
853                 return true
854         case OpMul32:
855                 v.Op = OpARM64MULW
856                 return true
857         case OpMul32F:
858                 v.Op = OpARM64FMULS
859                 return true
860         case OpMul64:
861                 v.Op = OpARM64MUL
862                 return true
863         case OpMul64F:
864                 v.Op = OpARM64FMULD
865                 return true
866         case OpMul8:
867                 v.Op = OpARM64MULW
868                 return true
869         case OpNeg16:
870                 v.Op = OpARM64NEG
871                 return true
872         case OpNeg32:
873                 v.Op = OpARM64NEG
874                 return true
875         case OpNeg32F:
876                 v.Op = OpARM64FNEGS
877                 return true
878         case OpNeg64:
879                 v.Op = OpARM64NEG
880                 return true
881         case OpNeg64F:
882                 v.Op = OpARM64FNEGD
883                 return true
884         case OpNeg8:
885                 v.Op = OpARM64NEG
886                 return true
887         case OpNeq16:
888                 return rewriteValueARM64_OpNeq16(v)
889         case OpNeq32:
890                 return rewriteValueARM64_OpNeq32(v)
891         case OpNeq32F:
892                 return rewriteValueARM64_OpNeq32F(v)
893         case OpNeq64:
894                 return rewriteValueARM64_OpNeq64(v)
895         case OpNeq64F:
896                 return rewriteValueARM64_OpNeq64F(v)
897         case OpNeq8:
898                 return rewriteValueARM64_OpNeq8(v)
899         case OpNeqB:
900                 v.Op = OpARM64XOR
901                 return true
902         case OpNeqPtr:
903                 return rewriteValueARM64_OpNeqPtr(v)
904         case OpNilCheck:
905                 v.Op = OpARM64LoweredNilCheck
906                 return true
907         case OpNot:
908                 return rewriteValueARM64_OpNot(v)
909         case OpOffPtr:
910                 return rewriteValueARM64_OpOffPtr(v)
911         case OpOr16:
912                 v.Op = OpARM64OR
913                 return true
914         case OpOr32:
915                 v.Op = OpARM64OR
916                 return true
917         case OpOr64:
918                 v.Op = OpARM64OR
919                 return true
920         case OpOr8:
921                 v.Op = OpARM64OR
922                 return true
923         case OpOrB:
924                 v.Op = OpARM64OR
925                 return true
926         case OpPanicBounds:
927                 return rewriteValueARM64_OpPanicBounds(v)
928         case OpPopCount16:
929                 return rewriteValueARM64_OpPopCount16(v)
930         case OpPopCount32:
931                 return rewriteValueARM64_OpPopCount32(v)
932         case OpPopCount64:
933                 return rewriteValueARM64_OpPopCount64(v)
934         case OpPrefetchCache:
935                 return rewriteValueARM64_OpPrefetchCache(v)
936         case OpPrefetchCacheStreamed:
937                 return rewriteValueARM64_OpPrefetchCacheStreamed(v)
938         case OpPubBarrier:
939                 return rewriteValueARM64_OpPubBarrier(v)
940         case OpRotateLeft16:
941                 return rewriteValueARM64_OpRotateLeft16(v)
942         case OpRotateLeft32:
943                 return rewriteValueARM64_OpRotateLeft32(v)
944         case OpRotateLeft64:
945                 return rewriteValueARM64_OpRotateLeft64(v)
946         case OpRotateLeft8:
947                 return rewriteValueARM64_OpRotateLeft8(v)
948         case OpRound:
949                 v.Op = OpARM64FRINTAD
950                 return true
951         case OpRound32F:
952                 v.Op = OpARM64LoweredRound32F
953                 return true
954         case OpRound64F:
955                 v.Op = OpARM64LoweredRound64F
956                 return true
957         case OpRoundToEven:
958                 v.Op = OpARM64FRINTND
959                 return true
960         case OpRsh16Ux16:
961                 return rewriteValueARM64_OpRsh16Ux16(v)
962         case OpRsh16Ux32:
963                 return rewriteValueARM64_OpRsh16Ux32(v)
964         case OpRsh16Ux64:
965                 return rewriteValueARM64_OpRsh16Ux64(v)
966         case OpRsh16Ux8:
967                 return rewriteValueARM64_OpRsh16Ux8(v)
968         case OpRsh16x16:
969                 return rewriteValueARM64_OpRsh16x16(v)
970         case OpRsh16x32:
971                 return rewriteValueARM64_OpRsh16x32(v)
972         case OpRsh16x64:
973                 return rewriteValueARM64_OpRsh16x64(v)
974         case OpRsh16x8:
975                 return rewriteValueARM64_OpRsh16x8(v)
976         case OpRsh32Ux16:
977                 return rewriteValueARM64_OpRsh32Ux16(v)
978         case OpRsh32Ux32:
979                 return rewriteValueARM64_OpRsh32Ux32(v)
980         case OpRsh32Ux64:
981                 return rewriteValueARM64_OpRsh32Ux64(v)
982         case OpRsh32Ux8:
983                 return rewriteValueARM64_OpRsh32Ux8(v)
984         case OpRsh32x16:
985                 return rewriteValueARM64_OpRsh32x16(v)
986         case OpRsh32x32:
987                 return rewriteValueARM64_OpRsh32x32(v)
988         case OpRsh32x64:
989                 return rewriteValueARM64_OpRsh32x64(v)
990         case OpRsh32x8:
991                 return rewriteValueARM64_OpRsh32x8(v)
992         case OpRsh64Ux16:
993                 return rewriteValueARM64_OpRsh64Ux16(v)
994         case OpRsh64Ux32:
995                 return rewriteValueARM64_OpRsh64Ux32(v)
996         case OpRsh64Ux64:
997                 return rewriteValueARM64_OpRsh64Ux64(v)
998         case OpRsh64Ux8:
999                 return rewriteValueARM64_OpRsh64Ux8(v)
1000         case OpRsh64x16:
1001                 return rewriteValueARM64_OpRsh64x16(v)
1002         case OpRsh64x32:
1003                 return rewriteValueARM64_OpRsh64x32(v)
1004         case OpRsh64x64:
1005                 return rewriteValueARM64_OpRsh64x64(v)
1006         case OpRsh64x8:
1007                 return rewriteValueARM64_OpRsh64x8(v)
1008         case OpRsh8Ux16:
1009                 return rewriteValueARM64_OpRsh8Ux16(v)
1010         case OpRsh8Ux32:
1011                 return rewriteValueARM64_OpRsh8Ux32(v)
1012         case OpRsh8Ux64:
1013                 return rewriteValueARM64_OpRsh8Ux64(v)
1014         case OpRsh8Ux8:
1015                 return rewriteValueARM64_OpRsh8Ux8(v)
1016         case OpRsh8x16:
1017                 return rewriteValueARM64_OpRsh8x16(v)
1018         case OpRsh8x32:
1019                 return rewriteValueARM64_OpRsh8x32(v)
1020         case OpRsh8x64:
1021                 return rewriteValueARM64_OpRsh8x64(v)
1022         case OpRsh8x8:
1023                 return rewriteValueARM64_OpRsh8x8(v)
1024         case OpSelect0:
1025                 return rewriteValueARM64_OpSelect0(v)
1026         case OpSelect1:
1027                 return rewriteValueARM64_OpSelect1(v)
1028         case OpSelectN:
1029                 return rewriteValueARM64_OpSelectN(v)
1030         case OpSignExt16to32:
1031                 v.Op = OpARM64MOVHreg
1032                 return true
1033         case OpSignExt16to64:
1034                 v.Op = OpARM64MOVHreg
1035                 return true
1036         case OpSignExt32to64:
1037                 v.Op = OpARM64MOVWreg
1038                 return true
1039         case OpSignExt8to16:
1040                 v.Op = OpARM64MOVBreg
1041                 return true
1042         case OpSignExt8to32:
1043                 v.Op = OpARM64MOVBreg
1044                 return true
1045         case OpSignExt8to64:
1046                 v.Op = OpARM64MOVBreg
1047                 return true
1048         case OpSlicemask:
1049                 return rewriteValueARM64_OpSlicemask(v)
1050         case OpSqrt:
1051                 v.Op = OpARM64FSQRTD
1052                 return true
1053         case OpSqrt32:
1054                 v.Op = OpARM64FSQRTS
1055                 return true
1056         case OpStaticCall:
1057                 v.Op = OpARM64CALLstatic
1058                 return true
1059         case OpStore:
1060                 return rewriteValueARM64_OpStore(v)
1061         case OpSub16:
1062                 v.Op = OpARM64SUB
1063                 return true
1064         case OpSub32:
1065                 v.Op = OpARM64SUB
1066                 return true
1067         case OpSub32F:
1068                 v.Op = OpARM64FSUBS
1069                 return true
1070         case OpSub64:
1071                 v.Op = OpARM64SUB
1072                 return true
1073         case OpSub64F:
1074                 v.Op = OpARM64FSUBD
1075                 return true
1076         case OpSub8:
1077                 v.Op = OpARM64SUB
1078                 return true
1079         case OpSubPtr:
1080                 v.Op = OpARM64SUB
1081                 return true
1082         case OpTailCall:
1083                 v.Op = OpARM64CALLtail
1084                 return true
1085         case OpTrunc:
1086                 v.Op = OpARM64FRINTZD
1087                 return true
1088         case OpTrunc16to8:
1089                 v.Op = OpCopy
1090                 return true
1091         case OpTrunc32to16:
1092                 v.Op = OpCopy
1093                 return true
1094         case OpTrunc32to8:
1095                 v.Op = OpCopy
1096                 return true
1097         case OpTrunc64to16:
1098                 v.Op = OpCopy
1099                 return true
1100         case OpTrunc64to32:
1101                 v.Op = OpCopy
1102                 return true
1103         case OpTrunc64to8:
1104                 v.Op = OpCopy
1105                 return true
1106         case OpWB:
1107                 v.Op = OpARM64LoweredWB
1108                 return true
1109         case OpXor16:
1110                 v.Op = OpARM64XOR
1111                 return true
1112         case OpXor32:
1113                 v.Op = OpARM64XOR
1114                 return true
1115         case OpXor64:
1116                 v.Op = OpARM64XOR
1117                 return true
1118         case OpXor8:
1119                 v.Op = OpARM64XOR
1120                 return true
1121         case OpZero:
1122                 return rewriteValueARM64_OpZero(v)
1123         case OpZeroExt16to32:
1124                 v.Op = OpARM64MOVHUreg
1125                 return true
1126         case OpZeroExt16to64:
1127                 v.Op = OpARM64MOVHUreg
1128                 return true
1129         case OpZeroExt32to64:
1130                 v.Op = OpARM64MOVWUreg
1131                 return true
1132         case OpZeroExt8to16:
1133                 v.Op = OpARM64MOVBUreg
1134                 return true
1135         case OpZeroExt8to32:
1136                 v.Op = OpARM64MOVBUreg
1137                 return true
1138         case OpZeroExt8to64:
1139                 v.Op = OpARM64MOVBUreg
1140                 return true
1141         }
1142         return false
1143 }
1144 func rewriteValueARM64_OpARM64ADCSflags(v *Value) bool {
1145         v_2 := v.Args[2]
1146         v_1 := v.Args[1]
1147         v_0 := v.Args[0]
1148         b := v.Block
1149         typ := &b.Func.Config.Types
1150         // match: (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (ADCzerocarry <typ.UInt64> c))))
1151         // result: (ADCSflags x y c)
1152         for {
1153                 x := v_0
1154                 y := v_1
1155                 if v_2.Op != OpSelect1 || v_2.Type != types.TypeFlags {
1156                         break
1157                 }
1158                 v_2_0 := v_2.Args[0]
1159                 if v_2_0.Op != OpARM64ADDSconstflags || auxIntToInt64(v_2_0.AuxInt) != -1 {
1160                         break
1161                 }
1162                 v_2_0_0 := v_2_0.Args[0]
1163                 if v_2_0_0.Op != OpARM64ADCzerocarry || v_2_0_0.Type != typ.UInt64 {
1164                         break
1165                 }
1166                 c := v_2_0_0.Args[0]
1167                 v.reset(OpARM64ADCSflags)
1168                 v.AddArg3(x, y, c)
1169                 return true
1170         }
1171         // match: (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (MOVDconst [0]))))
1172         // result: (ADDSflags x y)
1173         for {
1174                 x := v_0
1175                 y := v_1
1176                 if v_2.Op != OpSelect1 || v_2.Type != types.TypeFlags {
1177                         break
1178                 }
1179                 v_2_0 := v_2.Args[0]
1180                 if v_2_0.Op != OpARM64ADDSconstflags || auxIntToInt64(v_2_0.AuxInt) != -1 {
1181                         break
1182                 }
1183                 v_2_0_0 := v_2_0.Args[0]
1184                 if v_2_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 {
1185                         break
1186                 }
1187                 v.reset(OpARM64ADDSflags)
1188                 v.AddArg2(x, y)
1189                 return true
1190         }
1191         return false
1192 }
1193 func rewriteValueARM64_OpARM64ADD(v *Value) bool {
1194         v_1 := v.Args[1]
1195         v_0 := v.Args[0]
1196         // match: (ADD x (MOVDconst <t> [c]))
1197         // cond: !t.IsPtr()
1198         // result: (ADDconst [c] x)
1199         for {
1200                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1201                         x := v_0
1202                         if v_1.Op != OpARM64MOVDconst {
1203                                 continue
1204                         }
1205                         t := v_1.Type
1206                         c := auxIntToInt64(v_1.AuxInt)
1207                         if !(!t.IsPtr()) {
1208                                 continue
1209                         }
1210                         v.reset(OpARM64ADDconst)
1211                         v.AuxInt = int64ToAuxInt(c)
1212                         v.AddArg(x)
1213                         return true
1214                 }
1215                 break
1216         }
1217         // match: (ADD a l:(MUL x y))
1218         // cond: l.Uses==1 && clobber(l)
1219         // result: (MADD a x y)
1220         for {
1221                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1222                         a := v_0
1223                         l := v_1
1224                         if l.Op != OpARM64MUL {
1225                                 continue
1226                         }
1227                         y := l.Args[1]
1228                         x := l.Args[0]
1229                         if !(l.Uses == 1 && clobber(l)) {
1230                                 continue
1231                         }
1232                         v.reset(OpARM64MADD)
1233                         v.AddArg3(a, x, y)
1234                         return true
1235                 }
1236                 break
1237         }
1238         // match: (ADD a l:(MNEG x y))
1239         // cond: l.Uses==1 && clobber(l)
1240         // result: (MSUB a x y)
1241         for {
1242                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1243                         a := v_0
1244                         l := v_1
1245                         if l.Op != OpARM64MNEG {
1246                                 continue
1247                         }
1248                         y := l.Args[1]
1249                         x := l.Args[0]
1250                         if !(l.Uses == 1 && clobber(l)) {
1251                                 continue
1252                         }
1253                         v.reset(OpARM64MSUB)
1254                         v.AddArg3(a, x, y)
1255                         return true
1256                 }
1257                 break
1258         }
1259         // match: (ADD a l:(MULW x y))
1260         // cond: v.Type.Size() <= 4 && l.Uses==1 && clobber(l)
1261         // result: (MADDW a x y)
1262         for {
1263                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1264                         a := v_0
1265                         l := v_1
1266                         if l.Op != OpARM64MULW {
1267                                 continue
1268                         }
1269                         y := l.Args[1]
1270                         x := l.Args[0]
1271                         if !(v.Type.Size() <= 4 && l.Uses == 1 && clobber(l)) {
1272                                 continue
1273                         }
1274                         v.reset(OpARM64MADDW)
1275                         v.AddArg3(a, x, y)
1276                         return true
1277                 }
1278                 break
1279         }
1280         // match: (ADD a l:(MNEGW x y))
1281         // cond: v.Type.Size() <= 4 && l.Uses==1 && clobber(l)
1282         // result: (MSUBW a x y)
1283         for {
1284                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1285                         a := v_0
1286                         l := v_1
1287                         if l.Op != OpARM64MNEGW {
1288                                 continue
1289                         }
1290                         y := l.Args[1]
1291                         x := l.Args[0]
1292                         if !(v.Type.Size() <= 4 && l.Uses == 1 && clobber(l)) {
1293                                 continue
1294                         }
1295                         v.reset(OpARM64MSUBW)
1296                         v.AddArg3(a, x, y)
1297                         return true
1298                 }
1299                 break
1300         }
1301         // match: (ADD x (NEG y))
1302         // result: (SUB x y)
1303         for {
1304                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1305                         x := v_0
1306                         if v_1.Op != OpARM64NEG {
1307                                 continue
1308                         }
1309                         y := v_1.Args[0]
1310                         v.reset(OpARM64SUB)
1311                         v.AddArg2(x, y)
1312                         return true
1313                 }
1314                 break
1315         }
1316         // match: (ADD x0 x1:(SLLconst [c] y))
1317         // cond: clobberIfDead(x1)
1318         // result: (ADDshiftLL x0 y [c])
1319         for {
1320                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1321                         x0 := v_0
1322                         x1 := v_1
1323                         if x1.Op != OpARM64SLLconst {
1324                                 continue
1325                         }
1326                         c := auxIntToInt64(x1.AuxInt)
1327                         y := x1.Args[0]
1328                         if !(clobberIfDead(x1)) {
1329                                 continue
1330                         }
1331                         v.reset(OpARM64ADDshiftLL)
1332                         v.AuxInt = int64ToAuxInt(c)
1333                         v.AddArg2(x0, y)
1334                         return true
1335                 }
1336                 break
1337         }
1338         // match: (ADD x0 x1:(SRLconst [c] y))
1339         // cond: clobberIfDead(x1)
1340         // result: (ADDshiftRL x0 y [c])
1341         for {
1342                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1343                         x0 := v_0
1344                         x1 := v_1
1345                         if x1.Op != OpARM64SRLconst {
1346                                 continue
1347                         }
1348                         c := auxIntToInt64(x1.AuxInt)
1349                         y := x1.Args[0]
1350                         if !(clobberIfDead(x1)) {
1351                                 continue
1352                         }
1353                         v.reset(OpARM64ADDshiftRL)
1354                         v.AuxInt = int64ToAuxInt(c)
1355                         v.AddArg2(x0, y)
1356                         return true
1357                 }
1358                 break
1359         }
1360         // match: (ADD x0 x1:(SRAconst [c] y))
1361         // cond: clobberIfDead(x1)
1362         // result: (ADDshiftRA x0 y [c])
1363         for {
1364                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1365                         x0 := v_0
1366                         x1 := v_1
1367                         if x1.Op != OpARM64SRAconst {
1368                                 continue
1369                         }
1370                         c := auxIntToInt64(x1.AuxInt)
1371                         y := x1.Args[0]
1372                         if !(clobberIfDead(x1)) {
1373                                 continue
1374                         }
1375                         v.reset(OpARM64ADDshiftRA)
1376                         v.AuxInt = int64ToAuxInt(c)
1377                         v.AddArg2(x0, y)
1378                         return true
1379                 }
1380                 break
1381         }
1382         return false
1383 }
1384 func rewriteValueARM64_OpARM64ADDSflags(v *Value) bool {
1385         v_1 := v.Args[1]
1386         v_0 := v.Args[0]
1387         // match: (ADDSflags x (MOVDconst [c]))
1388         // result: (ADDSconstflags [c] x)
1389         for {
1390                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1391                         x := v_0
1392                         if v_1.Op != OpARM64MOVDconst {
1393                                 continue
1394                         }
1395                         c := auxIntToInt64(v_1.AuxInt)
1396                         v.reset(OpARM64ADDSconstflags)
1397                         v.AuxInt = int64ToAuxInt(c)
1398                         v.AddArg(x)
1399                         return true
1400                 }
1401                 break
1402         }
1403         return false
1404 }
1405 func rewriteValueARM64_OpARM64ADDconst(v *Value) bool {
1406         v_0 := v.Args[0]
1407         // match: (ADDconst [off1] (MOVDaddr [off2] {sym} ptr))
1408         // cond: is32Bit(off1+int64(off2))
1409         // result: (MOVDaddr [int32(off1)+off2] {sym} ptr)
1410         for {
1411                 off1 := auxIntToInt64(v.AuxInt)
1412                 if v_0.Op != OpARM64MOVDaddr {
1413                         break
1414                 }
1415                 off2 := auxIntToInt32(v_0.AuxInt)
1416                 sym := auxToSym(v_0.Aux)
1417                 ptr := v_0.Args[0]
1418                 if !(is32Bit(off1 + int64(off2))) {
1419                         break
1420                 }
1421                 v.reset(OpARM64MOVDaddr)
1422                 v.AuxInt = int32ToAuxInt(int32(off1) + off2)
1423                 v.Aux = symToAux(sym)
1424                 v.AddArg(ptr)
1425                 return true
1426         }
1427         // match: (ADDconst [c] y)
1428         // cond: c < 0
1429         // result: (SUBconst [-c] y)
1430         for {
1431                 c := auxIntToInt64(v.AuxInt)
1432                 y := v_0
1433                 if !(c < 0) {
1434                         break
1435                 }
1436                 v.reset(OpARM64SUBconst)
1437                 v.AuxInt = int64ToAuxInt(-c)
1438                 v.AddArg(y)
1439                 return true
1440         }
1441         // match: (ADDconst [0] x)
1442         // result: x
1443         for {
1444                 if auxIntToInt64(v.AuxInt) != 0 {
1445                         break
1446                 }
1447                 x := v_0
1448                 v.copyOf(x)
1449                 return true
1450         }
1451         // match: (ADDconst [c] (MOVDconst [d]))
1452         // result: (MOVDconst [c+d])
1453         for {
1454                 c := auxIntToInt64(v.AuxInt)
1455                 if v_0.Op != OpARM64MOVDconst {
1456                         break
1457                 }
1458                 d := auxIntToInt64(v_0.AuxInt)
1459                 v.reset(OpARM64MOVDconst)
1460                 v.AuxInt = int64ToAuxInt(c + d)
1461                 return true
1462         }
1463         // match: (ADDconst [c] (ADDconst [d] x))
1464         // result: (ADDconst [c+d] x)
1465         for {
1466                 c := auxIntToInt64(v.AuxInt)
1467                 if v_0.Op != OpARM64ADDconst {
1468                         break
1469                 }
1470                 d := auxIntToInt64(v_0.AuxInt)
1471                 x := v_0.Args[0]
1472                 v.reset(OpARM64ADDconst)
1473                 v.AuxInt = int64ToAuxInt(c + d)
1474                 v.AddArg(x)
1475                 return true
1476         }
1477         // match: (ADDconst [c] (SUBconst [d] x))
1478         // result: (ADDconst [c-d] x)
1479         for {
1480                 c := auxIntToInt64(v.AuxInt)
1481                 if v_0.Op != OpARM64SUBconst {
1482                         break
1483                 }
1484                 d := auxIntToInt64(v_0.AuxInt)
1485                 x := v_0.Args[0]
1486                 v.reset(OpARM64ADDconst)
1487                 v.AuxInt = int64ToAuxInt(c - d)
1488                 v.AddArg(x)
1489                 return true
1490         }
1491         return false
1492 }
1493 func rewriteValueARM64_OpARM64ADDshiftLL(v *Value) bool {
1494         v_1 := v.Args[1]
1495         v_0 := v.Args[0]
1496         b := v.Block
1497         typ := &b.Func.Config.Types
1498         // match: (ADDshiftLL (MOVDconst [c]) x [d])
1499         // result: (ADDconst [c] (SLLconst <x.Type> x [d]))
1500         for {
1501                 d := auxIntToInt64(v.AuxInt)
1502                 if v_0.Op != OpARM64MOVDconst {
1503                         break
1504                 }
1505                 c := auxIntToInt64(v_0.AuxInt)
1506                 x := v_1
1507                 v.reset(OpARM64ADDconst)
1508                 v.AuxInt = int64ToAuxInt(c)
1509                 v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
1510                 v0.AuxInt = int64ToAuxInt(d)
1511                 v0.AddArg(x)
1512                 v.AddArg(v0)
1513                 return true
1514         }
1515         // match: (ADDshiftLL x (MOVDconst [c]) [d])
1516         // result: (ADDconst x [int64(uint64(c)<<uint64(d))])
1517         for {
1518                 d := auxIntToInt64(v.AuxInt)
1519                 x := v_0
1520                 if v_1.Op != OpARM64MOVDconst {
1521                         break
1522                 }
1523                 c := auxIntToInt64(v_1.AuxInt)
1524                 v.reset(OpARM64ADDconst)
1525                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
1526                 v.AddArg(x)
1527                 return true
1528         }
1529         // match: (ADDshiftLL <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
1530         // result: (REV16W x)
1531         for {
1532                 if v.Type != typ.UInt16 || auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || v_0.Type != typ.UInt16 || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 8) {
1533                         break
1534                 }
1535                 x := v_0.Args[0]
1536                 if x != v_1 {
1537                         break
1538                 }
1539                 v.reset(OpARM64REV16W)
1540                 v.AddArg(x)
1541                 return true
1542         }
1543         // match: (ADDshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
1544         // cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
1545         // result: (REV16W x)
1546         for {
1547                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
1548                         break
1549                 }
1550                 v_0_0 := v_0.Args[0]
1551                 if v_0_0.Op != OpARM64ANDconst {
1552                         break
1553                 }
1554                 c1 := auxIntToInt64(v_0_0.AuxInt)
1555                 x := v_0_0.Args[0]
1556                 if v_1.Op != OpARM64ANDconst {
1557                         break
1558                 }
1559                 c2 := auxIntToInt64(v_1.AuxInt)
1560                 if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
1561                         break
1562                 }
1563                 v.reset(OpARM64REV16W)
1564                 v.AddArg(x)
1565                 return true
1566         }
1567         // match: (ADDshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
1568         // cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
1569         // result: (REV16 x)
1570         for {
1571                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
1572                         break
1573                 }
1574                 v_0_0 := v_0.Args[0]
1575                 if v_0_0.Op != OpARM64ANDconst {
1576                         break
1577                 }
1578                 c1 := auxIntToInt64(v_0_0.AuxInt)
1579                 x := v_0_0.Args[0]
1580                 if v_1.Op != OpARM64ANDconst {
1581                         break
1582                 }
1583                 c2 := auxIntToInt64(v_1.AuxInt)
1584                 if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
1585                         break
1586                 }
1587                 v.reset(OpARM64REV16)
1588                 v.AddArg(x)
1589                 return true
1590         }
1591         // match: (ADDshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
1592         // cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
1593         // result: (REV16 (ANDconst <x.Type> [0xffffffff] x))
1594         for {
1595                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
1596                         break
1597                 }
1598                 v_0_0 := v_0.Args[0]
1599                 if v_0_0.Op != OpARM64ANDconst {
1600                         break
1601                 }
1602                 c1 := auxIntToInt64(v_0_0.AuxInt)
1603                 x := v_0_0.Args[0]
1604                 if v_1.Op != OpARM64ANDconst {
1605                         break
1606                 }
1607                 c2 := auxIntToInt64(v_1.AuxInt)
1608                 if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
1609                         break
1610                 }
1611                 v.reset(OpARM64REV16)
1612                 v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
1613                 v0.AuxInt = int64ToAuxInt(0xffffffff)
1614                 v0.AddArg(x)
1615                 v.AddArg(v0)
1616                 return true
1617         }
1618         // match: (ADDshiftLL [c] (SRLconst x [64-c]) x2)
1619         // result: (EXTRconst [64-c] x2 x)
1620         for {
1621                 c := auxIntToInt64(v.AuxInt)
1622                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
1623                         break
1624                 }
1625                 x := v_0.Args[0]
1626                 x2 := v_1
1627                 v.reset(OpARM64EXTRconst)
1628                 v.AuxInt = int64ToAuxInt(64 - c)
1629                 v.AddArg2(x2, x)
1630                 return true
1631         }
1632         // match: (ADDshiftLL <t> [c] (UBFX [bfc] x) x2)
1633         // cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
1634         // result: (EXTRWconst [32-c] x2 x)
1635         for {
1636                 t := v.Type
1637                 c := auxIntToInt64(v.AuxInt)
1638                 if v_0.Op != OpARM64UBFX {
1639                         break
1640                 }
1641                 bfc := auxIntToArm64BitField(v_0.AuxInt)
1642                 x := v_0.Args[0]
1643                 x2 := v_1
1644                 if !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
1645                         break
1646                 }
1647                 v.reset(OpARM64EXTRWconst)
1648                 v.AuxInt = int64ToAuxInt(32 - c)
1649                 v.AddArg2(x2, x)
1650                 return true
1651         }
1652         return false
1653 }
1654 func rewriteValueARM64_OpARM64ADDshiftRA(v *Value) bool {
1655         v_1 := v.Args[1]
1656         v_0 := v.Args[0]
1657         b := v.Block
1658         // match: (ADDshiftRA (MOVDconst [c]) x [d])
1659         // result: (ADDconst [c] (SRAconst <x.Type> x [d]))
1660         for {
1661                 d := auxIntToInt64(v.AuxInt)
1662                 if v_0.Op != OpARM64MOVDconst {
1663                         break
1664                 }
1665                 c := auxIntToInt64(v_0.AuxInt)
1666                 x := v_1
1667                 v.reset(OpARM64ADDconst)
1668                 v.AuxInt = int64ToAuxInt(c)
1669                 v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
1670                 v0.AuxInt = int64ToAuxInt(d)
1671                 v0.AddArg(x)
1672                 v.AddArg(v0)
1673                 return true
1674         }
1675         // match: (ADDshiftRA x (MOVDconst [c]) [d])
1676         // result: (ADDconst x [c>>uint64(d)])
1677         for {
1678                 d := auxIntToInt64(v.AuxInt)
1679                 x := v_0
1680                 if v_1.Op != OpARM64MOVDconst {
1681                         break
1682                 }
1683                 c := auxIntToInt64(v_1.AuxInt)
1684                 v.reset(OpARM64ADDconst)
1685                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
1686                 v.AddArg(x)
1687                 return true
1688         }
1689         return false
1690 }
1691 func rewriteValueARM64_OpARM64ADDshiftRL(v *Value) bool {
1692         v_1 := v.Args[1]
1693         v_0 := v.Args[0]
1694         b := v.Block
1695         // match: (ADDshiftRL (MOVDconst [c]) x [d])
1696         // result: (ADDconst [c] (SRLconst <x.Type> x [d]))
1697         for {
1698                 d := auxIntToInt64(v.AuxInt)
1699                 if v_0.Op != OpARM64MOVDconst {
1700                         break
1701                 }
1702                 c := auxIntToInt64(v_0.AuxInt)
1703                 x := v_1
1704                 v.reset(OpARM64ADDconst)
1705                 v.AuxInt = int64ToAuxInt(c)
1706                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
1707                 v0.AuxInt = int64ToAuxInt(d)
1708                 v0.AddArg(x)
1709                 v.AddArg(v0)
1710                 return true
1711         }
1712         // match: (ADDshiftRL x (MOVDconst [c]) [d])
1713         // result: (ADDconst x [int64(uint64(c)>>uint64(d))])
1714         for {
1715                 d := auxIntToInt64(v.AuxInt)
1716                 x := v_0
1717                 if v_1.Op != OpARM64MOVDconst {
1718                         break
1719                 }
1720                 c := auxIntToInt64(v_1.AuxInt)
1721                 v.reset(OpARM64ADDconst)
1722                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
1723                 v.AddArg(x)
1724                 return true
1725         }
1726         return false
1727 }
1728 func rewriteValueARM64_OpARM64AND(v *Value) bool {
1729         v_1 := v.Args[1]
1730         v_0 := v.Args[0]
1731         // match: (AND x (MOVDconst [c]))
1732         // result: (ANDconst [c] x)
1733         for {
1734                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1735                         x := v_0
1736                         if v_1.Op != OpARM64MOVDconst {
1737                                 continue
1738                         }
1739                         c := auxIntToInt64(v_1.AuxInt)
1740                         v.reset(OpARM64ANDconst)
1741                         v.AuxInt = int64ToAuxInt(c)
1742                         v.AddArg(x)
1743                         return true
1744                 }
1745                 break
1746         }
1747         // match: (AND x x)
1748         // result: x
1749         for {
1750                 x := v_0
1751                 if x != v_1 {
1752                         break
1753                 }
1754                 v.copyOf(x)
1755                 return true
1756         }
1757         // match: (AND x (MVN y))
1758         // result: (BIC x y)
1759         for {
1760                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1761                         x := v_0
1762                         if v_1.Op != OpARM64MVN {
1763                                 continue
1764                         }
1765                         y := v_1.Args[0]
1766                         v.reset(OpARM64BIC)
1767                         v.AddArg2(x, y)
1768                         return true
1769                 }
1770                 break
1771         }
1772         // match: (AND x0 x1:(SLLconst [c] y))
1773         // cond: clobberIfDead(x1)
1774         // result: (ANDshiftLL x0 y [c])
1775         for {
1776                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1777                         x0 := v_0
1778                         x1 := v_1
1779                         if x1.Op != OpARM64SLLconst {
1780                                 continue
1781                         }
1782                         c := auxIntToInt64(x1.AuxInt)
1783                         y := x1.Args[0]
1784                         if !(clobberIfDead(x1)) {
1785                                 continue
1786                         }
1787                         v.reset(OpARM64ANDshiftLL)
1788                         v.AuxInt = int64ToAuxInt(c)
1789                         v.AddArg2(x0, y)
1790                         return true
1791                 }
1792                 break
1793         }
1794         // match: (AND x0 x1:(SRLconst [c] y))
1795         // cond: clobberIfDead(x1)
1796         // result: (ANDshiftRL x0 y [c])
1797         for {
1798                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1799                         x0 := v_0
1800                         x1 := v_1
1801                         if x1.Op != OpARM64SRLconst {
1802                                 continue
1803                         }
1804                         c := auxIntToInt64(x1.AuxInt)
1805                         y := x1.Args[0]
1806                         if !(clobberIfDead(x1)) {
1807                                 continue
1808                         }
1809                         v.reset(OpARM64ANDshiftRL)
1810                         v.AuxInt = int64ToAuxInt(c)
1811                         v.AddArg2(x0, y)
1812                         return true
1813                 }
1814                 break
1815         }
1816         // match: (AND x0 x1:(SRAconst [c] y))
1817         // cond: clobberIfDead(x1)
1818         // result: (ANDshiftRA x0 y [c])
1819         for {
1820                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1821                         x0 := v_0
1822                         x1 := v_1
1823                         if x1.Op != OpARM64SRAconst {
1824                                 continue
1825                         }
1826                         c := auxIntToInt64(x1.AuxInt)
1827                         y := x1.Args[0]
1828                         if !(clobberIfDead(x1)) {
1829                                 continue
1830                         }
1831                         v.reset(OpARM64ANDshiftRA)
1832                         v.AuxInt = int64ToAuxInt(c)
1833                         v.AddArg2(x0, y)
1834                         return true
1835                 }
1836                 break
1837         }
1838         // match: (AND x0 x1:(RORconst [c] y))
1839         // cond: clobberIfDead(x1)
1840         // result: (ANDshiftRO x0 y [c])
1841         for {
1842                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
1843                         x0 := v_0
1844                         x1 := v_1
1845                         if x1.Op != OpARM64RORconst {
1846                                 continue
1847                         }
1848                         c := auxIntToInt64(x1.AuxInt)
1849                         y := x1.Args[0]
1850                         if !(clobberIfDead(x1)) {
1851                                 continue
1852                         }
1853                         v.reset(OpARM64ANDshiftRO)
1854                         v.AuxInt = int64ToAuxInt(c)
1855                         v.AddArg2(x0, y)
1856                         return true
1857                 }
1858                 break
1859         }
1860         return false
1861 }
1862 func rewriteValueARM64_OpARM64ANDconst(v *Value) bool {
1863         v_0 := v.Args[0]
1864         // match: (ANDconst [0] _)
1865         // result: (MOVDconst [0])
1866         for {
1867                 if auxIntToInt64(v.AuxInt) != 0 {
1868                         break
1869                 }
1870                 v.reset(OpARM64MOVDconst)
1871                 v.AuxInt = int64ToAuxInt(0)
1872                 return true
1873         }
1874         // match: (ANDconst [-1] x)
1875         // result: x
1876         for {
1877                 if auxIntToInt64(v.AuxInt) != -1 {
1878                         break
1879                 }
1880                 x := v_0
1881                 v.copyOf(x)
1882                 return true
1883         }
1884         // match: (ANDconst [c] (MOVDconst [d]))
1885         // result: (MOVDconst [c&d])
1886         for {
1887                 c := auxIntToInt64(v.AuxInt)
1888                 if v_0.Op != OpARM64MOVDconst {
1889                         break
1890                 }
1891                 d := auxIntToInt64(v_0.AuxInt)
1892                 v.reset(OpARM64MOVDconst)
1893                 v.AuxInt = int64ToAuxInt(c & d)
1894                 return true
1895         }
1896         // match: (ANDconst [c] (ANDconst [d] x))
1897         // result: (ANDconst [c&d] x)
1898         for {
1899                 c := auxIntToInt64(v.AuxInt)
1900                 if v_0.Op != OpARM64ANDconst {
1901                         break
1902                 }
1903                 d := auxIntToInt64(v_0.AuxInt)
1904                 x := v_0.Args[0]
1905                 v.reset(OpARM64ANDconst)
1906                 v.AuxInt = int64ToAuxInt(c & d)
1907                 v.AddArg(x)
1908                 return true
1909         }
1910         // match: (ANDconst [c] (MOVWUreg x))
1911         // result: (ANDconst [c&(1<<32-1)] x)
1912         for {
1913                 c := auxIntToInt64(v.AuxInt)
1914                 if v_0.Op != OpARM64MOVWUreg {
1915                         break
1916                 }
1917                 x := v_0.Args[0]
1918                 v.reset(OpARM64ANDconst)
1919                 v.AuxInt = int64ToAuxInt(c & (1<<32 - 1))
1920                 v.AddArg(x)
1921                 return true
1922         }
1923         // match: (ANDconst [c] (MOVHUreg x))
1924         // result: (ANDconst [c&(1<<16-1)] x)
1925         for {
1926                 c := auxIntToInt64(v.AuxInt)
1927                 if v_0.Op != OpARM64MOVHUreg {
1928                         break
1929                 }
1930                 x := v_0.Args[0]
1931                 v.reset(OpARM64ANDconst)
1932                 v.AuxInt = int64ToAuxInt(c & (1<<16 - 1))
1933                 v.AddArg(x)
1934                 return true
1935         }
1936         // match: (ANDconst [c] (MOVBUreg x))
1937         // result: (ANDconst [c&(1<<8-1)] x)
1938         for {
1939                 c := auxIntToInt64(v.AuxInt)
1940                 if v_0.Op != OpARM64MOVBUreg {
1941                         break
1942                 }
1943                 x := v_0.Args[0]
1944                 v.reset(OpARM64ANDconst)
1945                 v.AuxInt = int64ToAuxInt(c & (1<<8 - 1))
1946                 v.AddArg(x)
1947                 return true
1948         }
1949         // match: (ANDconst [ac] (SLLconst [sc] x))
1950         // cond: isARM64BFMask(sc, ac, sc)
1951         // result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
1952         for {
1953                 ac := auxIntToInt64(v.AuxInt)
1954                 if v_0.Op != OpARM64SLLconst {
1955                         break
1956                 }
1957                 sc := auxIntToInt64(v_0.AuxInt)
1958                 x := v_0.Args[0]
1959                 if !(isARM64BFMask(sc, ac, sc)) {
1960                         break
1961                 }
1962                 v.reset(OpARM64UBFIZ)
1963                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc, arm64BFWidth(ac, sc)))
1964                 v.AddArg(x)
1965                 return true
1966         }
1967         // match: (ANDconst [ac] (SRLconst [sc] x))
1968         // cond: isARM64BFMask(sc, ac, 0)
1969         // result: (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
1970         for {
1971                 ac := auxIntToInt64(v.AuxInt)
1972                 if v_0.Op != OpARM64SRLconst {
1973                         break
1974                 }
1975                 sc := auxIntToInt64(v_0.AuxInt)
1976                 x := v_0.Args[0]
1977                 if !(isARM64BFMask(sc, ac, 0)) {
1978                         break
1979                 }
1980                 v.reset(OpARM64UBFX)
1981                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc, arm64BFWidth(ac, 0)))
1982                 v.AddArg(x)
1983                 return true
1984         }
1985         // match: (ANDconst [c] (UBFX [bfc] x))
1986         // cond: isARM64BFMask(0, c, 0)
1987         // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
1988         for {
1989                 c := auxIntToInt64(v.AuxInt)
1990                 if v_0.Op != OpARM64UBFX {
1991                         break
1992                 }
1993                 bfc := auxIntToArm64BitField(v_0.AuxInt)
1994                 x := v_0.Args[0]
1995                 if !(isARM64BFMask(0, c, 0)) {
1996                         break
1997                 }
1998                 v.reset(OpARM64UBFX)
1999                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0))))
2000                 v.AddArg(x)
2001                 return true
2002         }
2003         return false
2004 }
2005 func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool {
2006         v_1 := v.Args[1]
2007         v_0 := v.Args[0]
2008         b := v.Block
2009         // match: (ANDshiftLL (MOVDconst [c]) x [d])
2010         // result: (ANDconst [c] (SLLconst <x.Type> x [d]))
2011         for {
2012                 d := auxIntToInt64(v.AuxInt)
2013                 if v_0.Op != OpARM64MOVDconst {
2014                         break
2015                 }
2016                 c := auxIntToInt64(v_0.AuxInt)
2017                 x := v_1
2018                 v.reset(OpARM64ANDconst)
2019                 v.AuxInt = int64ToAuxInt(c)
2020                 v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
2021                 v0.AuxInt = int64ToAuxInt(d)
2022                 v0.AddArg(x)
2023                 v.AddArg(v0)
2024                 return true
2025         }
2026         // match: (ANDshiftLL x (MOVDconst [c]) [d])
2027         // result: (ANDconst x [int64(uint64(c)<<uint64(d))])
2028         for {
2029                 d := auxIntToInt64(v.AuxInt)
2030                 x := v_0
2031                 if v_1.Op != OpARM64MOVDconst {
2032                         break
2033                 }
2034                 c := auxIntToInt64(v_1.AuxInt)
2035                 v.reset(OpARM64ANDconst)
2036                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
2037                 v.AddArg(x)
2038                 return true
2039         }
2040         // match: (ANDshiftLL y:(SLLconst x [c]) x [c])
2041         // result: y
2042         for {
2043                 c := auxIntToInt64(v.AuxInt)
2044                 y := v_0
2045                 if y.Op != OpARM64SLLconst || auxIntToInt64(y.AuxInt) != c {
2046                         break
2047                 }
2048                 x := y.Args[0]
2049                 if x != v_1 {
2050                         break
2051                 }
2052                 v.copyOf(y)
2053                 return true
2054         }
2055         return false
2056 }
2057 func rewriteValueARM64_OpARM64ANDshiftRA(v *Value) bool {
2058         v_1 := v.Args[1]
2059         v_0 := v.Args[0]
2060         b := v.Block
2061         // match: (ANDshiftRA (MOVDconst [c]) x [d])
2062         // result: (ANDconst [c] (SRAconst <x.Type> x [d]))
2063         for {
2064                 d := auxIntToInt64(v.AuxInt)
2065                 if v_0.Op != OpARM64MOVDconst {
2066                         break
2067                 }
2068                 c := auxIntToInt64(v_0.AuxInt)
2069                 x := v_1
2070                 v.reset(OpARM64ANDconst)
2071                 v.AuxInt = int64ToAuxInt(c)
2072                 v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
2073                 v0.AuxInt = int64ToAuxInt(d)
2074                 v0.AddArg(x)
2075                 v.AddArg(v0)
2076                 return true
2077         }
2078         // match: (ANDshiftRA x (MOVDconst [c]) [d])
2079         // result: (ANDconst x [c>>uint64(d)])
2080         for {
2081                 d := auxIntToInt64(v.AuxInt)
2082                 x := v_0
2083                 if v_1.Op != OpARM64MOVDconst {
2084                         break
2085                 }
2086                 c := auxIntToInt64(v_1.AuxInt)
2087                 v.reset(OpARM64ANDconst)
2088                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
2089                 v.AddArg(x)
2090                 return true
2091         }
2092         // match: (ANDshiftRA y:(SRAconst x [c]) x [c])
2093         // result: y
2094         for {
2095                 c := auxIntToInt64(v.AuxInt)
2096                 y := v_0
2097                 if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
2098                         break
2099                 }
2100                 x := y.Args[0]
2101                 if x != v_1 {
2102                         break
2103                 }
2104                 v.copyOf(y)
2105                 return true
2106         }
2107         return false
2108 }
2109 func rewriteValueARM64_OpARM64ANDshiftRL(v *Value) bool {
2110         v_1 := v.Args[1]
2111         v_0 := v.Args[0]
2112         b := v.Block
2113         // match: (ANDshiftRL (MOVDconst [c]) x [d])
2114         // result: (ANDconst [c] (SRLconst <x.Type> x [d]))
2115         for {
2116                 d := auxIntToInt64(v.AuxInt)
2117                 if v_0.Op != OpARM64MOVDconst {
2118                         break
2119                 }
2120                 c := auxIntToInt64(v_0.AuxInt)
2121                 x := v_1
2122                 v.reset(OpARM64ANDconst)
2123                 v.AuxInt = int64ToAuxInt(c)
2124                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
2125                 v0.AuxInt = int64ToAuxInt(d)
2126                 v0.AddArg(x)
2127                 v.AddArg(v0)
2128                 return true
2129         }
2130         // match: (ANDshiftRL x (MOVDconst [c]) [d])
2131         // result: (ANDconst x [int64(uint64(c)>>uint64(d))])
2132         for {
2133                 d := auxIntToInt64(v.AuxInt)
2134                 x := v_0
2135                 if v_1.Op != OpARM64MOVDconst {
2136                         break
2137                 }
2138                 c := auxIntToInt64(v_1.AuxInt)
2139                 v.reset(OpARM64ANDconst)
2140                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
2141                 v.AddArg(x)
2142                 return true
2143         }
2144         // match: (ANDshiftRL y:(SRLconst x [c]) x [c])
2145         // result: y
2146         for {
2147                 c := auxIntToInt64(v.AuxInt)
2148                 y := v_0
2149                 if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
2150                         break
2151                 }
2152                 x := y.Args[0]
2153                 if x != v_1 {
2154                         break
2155                 }
2156                 v.copyOf(y)
2157                 return true
2158         }
2159         return false
2160 }
2161 func rewriteValueARM64_OpARM64ANDshiftRO(v *Value) bool {
2162         v_1 := v.Args[1]
2163         v_0 := v.Args[0]
2164         b := v.Block
2165         // match: (ANDshiftRO (MOVDconst [c]) x [d])
2166         // result: (ANDconst [c] (RORconst <x.Type> x [d]))
2167         for {
2168                 d := auxIntToInt64(v.AuxInt)
2169                 if v_0.Op != OpARM64MOVDconst {
2170                         break
2171                 }
2172                 c := auxIntToInt64(v_0.AuxInt)
2173                 x := v_1
2174                 v.reset(OpARM64ANDconst)
2175                 v.AuxInt = int64ToAuxInt(c)
2176                 v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
2177                 v0.AuxInt = int64ToAuxInt(d)
2178                 v0.AddArg(x)
2179                 v.AddArg(v0)
2180                 return true
2181         }
2182         // match: (ANDshiftRO x (MOVDconst [c]) [d])
2183         // result: (ANDconst x [rotateRight64(c, d)])
2184         for {
2185                 d := auxIntToInt64(v.AuxInt)
2186                 x := v_0
2187                 if v_1.Op != OpARM64MOVDconst {
2188                         break
2189                 }
2190                 c := auxIntToInt64(v_1.AuxInt)
2191                 v.reset(OpARM64ANDconst)
2192                 v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
2193                 v.AddArg(x)
2194                 return true
2195         }
2196         // match: (ANDshiftRO y:(RORconst x [c]) x [c])
2197         // result: y
2198         for {
2199                 c := auxIntToInt64(v.AuxInt)
2200                 y := v_0
2201                 if y.Op != OpARM64RORconst || auxIntToInt64(y.AuxInt) != c {
2202                         break
2203                 }
2204                 x := y.Args[0]
2205                 if x != v_1 {
2206                         break
2207                 }
2208                 v.copyOf(y)
2209                 return true
2210         }
2211         return false
2212 }
2213 func rewriteValueARM64_OpARM64BIC(v *Value) bool {
2214         v_1 := v.Args[1]
2215         v_0 := v.Args[0]
2216         // match: (BIC x (MOVDconst [c]))
2217         // result: (ANDconst [^c] x)
2218         for {
2219                 x := v_0
2220                 if v_1.Op != OpARM64MOVDconst {
2221                         break
2222                 }
2223                 c := auxIntToInt64(v_1.AuxInt)
2224                 v.reset(OpARM64ANDconst)
2225                 v.AuxInt = int64ToAuxInt(^c)
2226                 v.AddArg(x)
2227                 return true
2228         }
2229         // match: (BIC x x)
2230         // result: (MOVDconst [0])
2231         for {
2232                 x := v_0
2233                 if x != v_1 {
2234                         break
2235                 }
2236                 v.reset(OpARM64MOVDconst)
2237                 v.AuxInt = int64ToAuxInt(0)
2238                 return true
2239         }
2240         // match: (BIC x0 x1:(SLLconst [c] y))
2241         // cond: clobberIfDead(x1)
2242         // result: (BICshiftLL x0 y [c])
2243         for {
2244                 x0 := v_0
2245                 x1 := v_1
2246                 if x1.Op != OpARM64SLLconst {
2247                         break
2248                 }
2249                 c := auxIntToInt64(x1.AuxInt)
2250                 y := x1.Args[0]
2251                 if !(clobberIfDead(x1)) {
2252                         break
2253                 }
2254                 v.reset(OpARM64BICshiftLL)
2255                 v.AuxInt = int64ToAuxInt(c)
2256                 v.AddArg2(x0, y)
2257                 return true
2258         }
2259         // match: (BIC x0 x1:(SRLconst [c] y))
2260         // cond: clobberIfDead(x1)
2261         // result: (BICshiftRL x0 y [c])
2262         for {
2263                 x0 := v_0
2264                 x1 := v_1
2265                 if x1.Op != OpARM64SRLconst {
2266                         break
2267                 }
2268                 c := auxIntToInt64(x1.AuxInt)
2269                 y := x1.Args[0]
2270                 if !(clobberIfDead(x1)) {
2271                         break
2272                 }
2273                 v.reset(OpARM64BICshiftRL)
2274                 v.AuxInt = int64ToAuxInt(c)
2275                 v.AddArg2(x0, y)
2276                 return true
2277         }
2278         // match: (BIC x0 x1:(SRAconst [c] y))
2279         // cond: clobberIfDead(x1)
2280         // result: (BICshiftRA x0 y [c])
2281         for {
2282                 x0 := v_0
2283                 x1 := v_1
2284                 if x1.Op != OpARM64SRAconst {
2285                         break
2286                 }
2287                 c := auxIntToInt64(x1.AuxInt)
2288                 y := x1.Args[0]
2289                 if !(clobberIfDead(x1)) {
2290                         break
2291                 }
2292                 v.reset(OpARM64BICshiftRA)
2293                 v.AuxInt = int64ToAuxInt(c)
2294                 v.AddArg2(x0, y)
2295                 return true
2296         }
2297         // match: (BIC x0 x1:(RORconst [c] y))
2298         // cond: clobberIfDead(x1)
2299         // result: (BICshiftRO x0 y [c])
2300         for {
2301                 x0 := v_0
2302                 x1 := v_1
2303                 if x1.Op != OpARM64RORconst {
2304                         break
2305                 }
2306                 c := auxIntToInt64(x1.AuxInt)
2307                 y := x1.Args[0]
2308                 if !(clobberIfDead(x1)) {
2309                         break
2310                 }
2311                 v.reset(OpARM64BICshiftRO)
2312                 v.AuxInt = int64ToAuxInt(c)
2313                 v.AddArg2(x0, y)
2314                 return true
2315         }
2316         return false
2317 }
2318 func rewriteValueARM64_OpARM64BICshiftLL(v *Value) bool {
2319         v_1 := v.Args[1]
2320         v_0 := v.Args[0]
2321         // match: (BICshiftLL x (MOVDconst [c]) [d])
2322         // result: (ANDconst x [^int64(uint64(c)<<uint64(d))])
2323         for {
2324                 d := auxIntToInt64(v.AuxInt)
2325                 x := v_0
2326                 if v_1.Op != OpARM64MOVDconst {
2327                         break
2328                 }
2329                 c := auxIntToInt64(v_1.AuxInt)
2330                 v.reset(OpARM64ANDconst)
2331                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) << uint64(d)))
2332                 v.AddArg(x)
2333                 return true
2334         }
2335         // match: (BICshiftLL (SLLconst x [c]) x [c])
2336         // result: (MOVDconst [0])
2337         for {
2338                 c := auxIntToInt64(v.AuxInt)
2339                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
2340                         break
2341                 }
2342                 x := v_0.Args[0]
2343                 if x != v_1 {
2344                         break
2345                 }
2346                 v.reset(OpARM64MOVDconst)
2347                 v.AuxInt = int64ToAuxInt(0)
2348                 return true
2349         }
2350         return false
2351 }
2352 func rewriteValueARM64_OpARM64BICshiftRA(v *Value) bool {
2353         v_1 := v.Args[1]
2354         v_0 := v.Args[0]
2355         // match: (BICshiftRA x (MOVDconst [c]) [d])
2356         // result: (ANDconst x [^(c>>uint64(d))])
2357         for {
2358                 d := auxIntToInt64(v.AuxInt)
2359                 x := v_0
2360                 if v_1.Op != OpARM64MOVDconst {
2361                         break
2362                 }
2363                 c := auxIntToInt64(v_1.AuxInt)
2364                 v.reset(OpARM64ANDconst)
2365                 v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
2366                 v.AddArg(x)
2367                 return true
2368         }
2369         // match: (BICshiftRA (SRAconst x [c]) x [c])
2370         // result: (MOVDconst [0])
2371         for {
2372                 c := auxIntToInt64(v.AuxInt)
2373                 if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
2374                         break
2375                 }
2376                 x := v_0.Args[0]
2377                 if x != v_1 {
2378                         break
2379                 }
2380                 v.reset(OpARM64MOVDconst)
2381                 v.AuxInt = int64ToAuxInt(0)
2382                 return true
2383         }
2384         return false
2385 }
2386 func rewriteValueARM64_OpARM64BICshiftRL(v *Value) bool {
2387         v_1 := v.Args[1]
2388         v_0 := v.Args[0]
2389         // match: (BICshiftRL x (MOVDconst [c]) [d])
2390         // result: (ANDconst x [^int64(uint64(c)>>uint64(d))])
2391         for {
2392                 d := auxIntToInt64(v.AuxInt)
2393                 x := v_0
2394                 if v_1.Op != OpARM64MOVDconst {
2395                         break
2396                 }
2397                 c := auxIntToInt64(v_1.AuxInt)
2398                 v.reset(OpARM64ANDconst)
2399                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
2400                 v.AddArg(x)
2401                 return true
2402         }
2403         // match: (BICshiftRL (SRLconst x [c]) x [c])
2404         // result: (MOVDconst [0])
2405         for {
2406                 c := auxIntToInt64(v.AuxInt)
2407                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
2408                         break
2409                 }
2410                 x := v_0.Args[0]
2411                 if x != v_1 {
2412                         break
2413                 }
2414                 v.reset(OpARM64MOVDconst)
2415                 v.AuxInt = int64ToAuxInt(0)
2416                 return true
2417         }
2418         return false
2419 }
2420 func rewriteValueARM64_OpARM64BICshiftRO(v *Value) bool {
2421         v_1 := v.Args[1]
2422         v_0 := v.Args[0]
2423         // match: (BICshiftRO x (MOVDconst [c]) [d])
2424         // result: (ANDconst x [^rotateRight64(c, d)])
2425         for {
2426                 d := auxIntToInt64(v.AuxInt)
2427                 x := v_0
2428                 if v_1.Op != OpARM64MOVDconst {
2429                         break
2430                 }
2431                 c := auxIntToInt64(v_1.AuxInt)
2432                 v.reset(OpARM64ANDconst)
2433                 v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
2434                 v.AddArg(x)
2435                 return true
2436         }
2437         // match: (BICshiftRO (RORconst x [c]) x [c])
2438         // result: (MOVDconst [0])
2439         for {
2440                 c := auxIntToInt64(v.AuxInt)
2441                 if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
2442                         break
2443                 }
2444                 x := v_0.Args[0]
2445                 if x != v_1 {
2446                         break
2447                 }
2448                 v.reset(OpARM64MOVDconst)
2449                 v.AuxInt = int64ToAuxInt(0)
2450                 return true
2451         }
2452         return false
2453 }
2454 func rewriteValueARM64_OpARM64CMN(v *Value) bool {
2455         v_1 := v.Args[1]
2456         v_0 := v.Args[0]
2457         // match: (CMN x (MOVDconst [c]))
2458         // result: (CMNconst [c] x)
2459         for {
2460                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
2461                         x := v_0
2462                         if v_1.Op != OpARM64MOVDconst {
2463                                 continue
2464                         }
2465                         c := auxIntToInt64(v_1.AuxInt)
2466                         v.reset(OpARM64CMNconst)
2467                         v.AuxInt = int64ToAuxInt(c)
2468                         v.AddArg(x)
2469                         return true
2470                 }
2471                 break
2472         }
2473         // match: (CMN x0 x1:(SLLconst [c] y))
2474         // cond: clobberIfDead(x1)
2475         // result: (CMNshiftLL x0 y [c])
2476         for {
2477                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
2478                         x0 := v_0
2479                         x1 := v_1
2480                         if x1.Op != OpARM64SLLconst {
2481                                 continue
2482                         }
2483                         c := auxIntToInt64(x1.AuxInt)
2484                         y := x1.Args[0]
2485                         if !(clobberIfDead(x1)) {
2486                                 continue
2487                         }
2488                         v.reset(OpARM64CMNshiftLL)
2489                         v.AuxInt = int64ToAuxInt(c)
2490                         v.AddArg2(x0, y)
2491                         return true
2492                 }
2493                 break
2494         }
2495         // match: (CMN x0 x1:(SRLconst [c] y))
2496         // cond: clobberIfDead(x1)
2497         // result: (CMNshiftRL x0 y [c])
2498         for {
2499                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
2500                         x0 := v_0
2501                         x1 := v_1
2502                         if x1.Op != OpARM64SRLconst {
2503                                 continue
2504                         }
2505                         c := auxIntToInt64(x1.AuxInt)
2506                         y := x1.Args[0]
2507                         if !(clobberIfDead(x1)) {
2508                                 continue
2509                         }
2510                         v.reset(OpARM64CMNshiftRL)
2511                         v.AuxInt = int64ToAuxInt(c)
2512                         v.AddArg2(x0, y)
2513                         return true
2514                 }
2515                 break
2516         }
2517         // match: (CMN x0 x1:(SRAconst [c] y))
2518         // cond: clobberIfDead(x1)
2519         // result: (CMNshiftRA x0 y [c])
2520         for {
2521                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
2522                         x0 := v_0
2523                         x1 := v_1
2524                         if x1.Op != OpARM64SRAconst {
2525                                 continue
2526                         }
2527                         c := auxIntToInt64(x1.AuxInt)
2528                         y := x1.Args[0]
2529                         if !(clobberIfDead(x1)) {
2530                                 continue
2531                         }
2532                         v.reset(OpARM64CMNshiftRA)
2533                         v.AuxInt = int64ToAuxInt(c)
2534                         v.AddArg2(x0, y)
2535                         return true
2536                 }
2537                 break
2538         }
2539         return false
2540 }
2541 func rewriteValueARM64_OpARM64CMNW(v *Value) bool {
2542         v_1 := v.Args[1]
2543         v_0 := v.Args[0]
2544         // match: (CMNW x (MOVDconst [c]))
2545         // result: (CMNWconst [int32(c)] x)
2546         for {
2547                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
2548                         x := v_0
2549                         if v_1.Op != OpARM64MOVDconst {
2550                                 continue
2551                         }
2552                         c := auxIntToInt64(v_1.AuxInt)
2553                         v.reset(OpARM64CMNWconst)
2554                         v.AuxInt = int32ToAuxInt(int32(c))
2555                         v.AddArg(x)
2556                         return true
2557                 }
2558                 break
2559         }
2560         return false
2561 }
2562 func rewriteValueARM64_OpARM64CMNWconst(v *Value) bool {
2563         v_0 := v.Args[0]
2564         // match: (CMNWconst [c] y)
2565         // cond: c < 0 && c != -1<<31
2566         // result: (CMPWconst [-c] y)
2567         for {
2568                 c := auxIntToInt32(v.AuxInt)
2569                 y := v_0
2570                 if !(c < 0 && c != -1<<31) {
2571                         break
2572                 }
2573                 v.reset(OpARM64CMPWconst)
2574                 v.AuxInt = int32ToAuxInt(-c)
2575                 v.AddArg(y)
2576                 return true
2577         }
2578         // match: (CMNWconst (MOVDconst [x]) [y])
2579         // result: (FlagConstant [addFlags32(int32(x),y)])
2580         for {
2581                 y := auxIntToInt32(v.AuxInt)
2582                 if v_0.Op != OpARM64MOVDconst {
2583                         break
2584                 }
2585                 x := auxIntToInt64(v_0.AuxInt)
2586                 v.reset(OpARM64FlagConstant)
2587                 v.AuxInt = flagConstantToAuxInt(addFlags32(int32(x), y))
2588                 return true
2589         }
2590         return false
2591 }
2592 func rewriteValueARM64_OpARM64CMNconst(v *Value) bool {
2593         v_0 := v.Args[0]
2594         // match: (CMNconst [c] y)
2595         // cond: c < 0 && c != -1<<63
2596         // result: (CMPconst [-c] y)
2597         for {
2598                 c := auxIntToInt64(v.AuxInt)
2599                 y := v_0
2600                 if !(c < 0 && c != -1<<63) {
2601                         break
2602                 }
2603                 v.reset(OpARM64CMPconst)
2604                 v.AuxInt = int64ToAuxInt(-c)
2605                 v.AddArg(y)
2606                 return true
2607         }
2608         // match: (CMNconst (MOVDconst [x]) [y])
2609         // result: (FlagConstant [addFlags64(x,y)])
2610         for {
2611                 y := auxIntToInt64(v.AuxInt)
2612                 if v_0.Op != OpARM64MOVDconst {
2613                         break
2614                 }
2615                 x := auxIntToInt64(v_0.AuxInt)
2616                 v.reset(OpARM64FlagConstant)
2617                 v.AuxInt = flagConstantToAuxInt(addFlags64(x, y))
2618                 return true
2619         }
2620         return false
2621 }
2622 func rewriteValueARM64_OpARM64CMNshiftLL(v *Value) bool {
2623         v_1 := v.Args[1]
2624         v_0 := v.Args[0]
2625         b := v.Block
2626         // match: (CMNshiftLL (MOVDconst [c]) x [d])
2627         // result: (CMNconst [c] (SLLconst <x.Type> x [d]))
2628         for {
2629                 d := auxIntToInt64(v.AuxInt)
2630                 if v_0.Op != OpARM64MOVDconst {
2631                         break
2632                 }
2633                 c := auxIntToInt64(v_0.AuxInt)
2634                 x := v_1
2635                 v.reset(OpARM64CMNconst)
2636                 v.AuxInt = int64ToAuxInt(c)
2637                 v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
2638                 v0.AuxInt = int64ToAuxInt(d)
2639                 v0.AddArg(x)
2640                 v.AddArg(v0)
2641                 return true
2642         }
2643         // match: (CMNshiftLL x (MOVDconst [c]) [d])
2644         // result: (CMNconst x [int64(uint64(c)<<uint64(d))])
2645         for {
2646                 d := auxIntToInt64(v.AuxInt)
2647                 x := v_0
2648                 if v_1.Op != OpARM64MOVDconst {
2649                         break
2650                 }
2651                 c := auxIntToInt64(v_1.AuxInt)
2652                 v.reset(OpARM64CMNconst)
2653                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
2654                 v.AddArg(x)
2655                 return true
2656         }
2657         return false
2658 }
2659 func rewriteValueARM64_OpARM64CMNshiftRA(v *Value) bool {
2660         v_1 := v.Args[1]
2661         v_0 := v.Args[0]
2662         b := v.Block
2663         // match: (CMNshiftRA (MOVDconst [c]) x [d])
2664         // result: (CMNconst [c] (SRAconst <x.Type> x [d]))
2665         for {
2666                 d := auxIntToInt64(v.AuxInt)
2667                 if v_0.Op != OpARM64MOVDconst {
2668                         break
2669                 }
2670                 c := auxIntToInt64(v_0.AuxInt)
2671                 x := v_1
2672                 v.reset(OpARM64CMNconst)
2673                 v.AuxInt = int64ToAuxInt(c)
2674                 v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
2675                 v0.AuxInt = int64ToAuxInt(d)
2676                 v0.AddArg(x)
2677                 v.AddArg(v0)
2678                 return true
2679         }
2680         // match: (CMNshiftRA x (MOVDconst [c]) [d])
2681         // result: (CMNconst x [c>>uint64(d)])
2682         for {
2683                 d := auxIntToInt64(v.AuxInt)
2684                 x := v_0
2685                 if v_1.Op != OpARM64MOVDconst {
2686                         break
2687                 }
2688                 c := auxIntToInt64(v_1.AuxInt)
2689                 v.reset(OpARM64CMNconst)
2690                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
2691                 v.AddArg(x)
2692                 return true
2693         }
2694         return false
2695 }
2696 func rewriteValueARM64_OpARM64CMNshiftRL(v *Value) bool {
2697         v_1 := v.Args[1]
2698         v_0 := v.Args[0]
2699         b := v.Block
2700         // match: (CMNshiftRL (MOVDconst [c]) x [d])
2701         // result: (CMNconst [c] (SRLconst <x.Type> x [d]))
2702         for {
2703                 d := auxIntToInt64(v.AuxInt)
2704                 if v_0.Op != OpARM64MOVDconst {
2705                         break
2706                 }
2707                 c := auxIntToInt64(v_0.AuxInt)
2708                 x := v_1
2709                 v.reset(OpARM64CMNconst)
2710                 v.AuxInt = int64ToAuxInt(c)
2711                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
2712                 v0.AuxInt = int64ToAuxInt(d)
2713                 v0.AddArg(x)
2714                 v.AddArg(v0)
2715                 return true
2716         }
2717         // match: (CMNshiftRL x (MOVDconst [c]) [d])
2718         // result: (CMNconst x [int64(uint64(c)>>uint64(d))])
2719         for {
2720                 d := auxIntToInt64(v.AuxInt)
2721                 x := v_0
2722                 if v_1.Op != OpARM64MOVDconst {
2723                         break
2724                 }
2725                 c := auxIntToInt64(v_1.AuxInt)
2726                 v.reset(OpARM64CMNconst)
2727                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
2728                 v.AddArg(x)
2729                 return true
2730         }
2731         return false
2732 }
2733 func rewriteValueARM64_OpARM64CMP(v *Value) bool {
2734         v_1 := v.Args[1]
2735         v_0 := v.Args[0]
2736         b := v.Block
2737         // match: (CMP x (MOVDconst [c]))
2738         // result: (CMPconst [c] x)
2739         for {
2740                 x := v_0
2741                 if v_1.Op != OpARM64MOVDconst {
2742                         break
2743                 }
2744                 c := auxIntToInt64(v_1.AuxInt)
2745                 v.reset(OpARM64CMPconst)
2746                 v.AuxInt = int64ToAuxInt(c)
2747                 v.AddArg(x)
2748                 return true
2749         }
2750         // match: (CMP (MOVDconst [c]) x)
2751         // result: (InvertFlags (CMPconst [c] x))
2752         for {
2753                 if v_0.Op != OpARM64MOVDconst {
2754                         break
2755                 }
2756                 c := auxIntToInt64(v_0.AuxInt)
2757                 x := v_1
2758                 v.reset(OpARM64InvertFlags)
2759                 v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
2760                 v0.AuxInt = int64ToAuxInt(c)
2761                 v0.AddArg(x)
2762                 v.AddArg(v0)
2763                 return true
2764         }
2765         // match: (CMP x y)
2766         // cond: canonLessThan(x,y)
2767         // result: (InvertFlags (CMP y x))
2768         for {
2769                 x := v_0
2770                 y := v_1
2771                 if !(canonLessThan(x, y)) {
2772                         break
2773                 }
2774                 v.reset(OpARM64InvertFlags)
2775                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
2776                 v0.AddArg2(y, x)
2777                 v.AddArg(v0)
2778                 return true
2779         }
2780         // match: (CMP x0 x1:(SLLconst [c] y))
2781         // cond: clobberIfDead(x1)
2782         // result: (CMPshiftLL x0 y [c])
2783         for {
2784                 x0 := v_0
2785                 x1 := v_1
2786                 if x1.Op != OpARM64SLLconst {
2787                         break
2788                 }
2789                 c := auxIntToInt64(x1.AuxInt)
2790                 y := x1.Args[0]
2791                 if !(clobberIfDead(x1)) {
2792                         break
2793                 }
2794                 v.reset(OpARM64CMPshiftLL)
2795                 v.AuxInt = int64ToAuxInt(c)
2796                 v.AddArg2(x0, y)
2797                 return true
2798         }
2799         // match: (CMP x0:(SLLconst [c] y) x1)
2800         // cond: clobberIfDead(x0)
2801         // result: (InvertFlags (CMPshiftLL x1 y [c]))
2802         for {
2803                 x0 := v_0
2804                 if x0.Op != OpARM64SLLconst {
2805                         break
2806                 }
2807                 c := auxIntToInt64(x0.AuxInt)
2808                 y := x0.Args[0]
2809                 x1 := v_1
2810                 if !(clobberIfDead(x0)) {
2811                         break
2812                 }
2813                 v.reset(OpARM64InvertFlags)
2814                 v0 := b.NewValue0(v.Pos, OpARM64CMPshiftLL, types.TypeFlags)
2815                 v0.AuxInt = int64ToAuxInt(c)
2816                 v0.AddArg2(x1, y)
2817                 v.AddArg(v0)
2818                 return true
2819         }
2820         // match: (CMP x0 x1:(SRLconst [c] y))
2821         // cond: clobberIfDead(x1)
2822         // result: (CMPshiftRL x0 y [c])
2823         for {
2824                 x0 := v_0
2825                 x1 := v_1
2826                 if x1.Op != OpARM64SRLconst {
2827                         break
2828                 }
2829                 c := auxIntToInt64(x1.AuxInt)
2830                 y := x1.Args[0]
2831                 if !(clobberIfDead(x1)) {
2832                         break
2833                 }
2834                 v.reset(OpARM64CMPshiftRL)
2835                 v.AuxInt = int64ToAuxInt(c)
2836                 v.AddArg2(x0, y)
2837                 return true
2838         }
2839         // match: (CMP x0:(SRLconst [c] y) x1)
2840         // cond: clobberIfDead(x0)
2841         // result: (InvertFlags (CMPshiftRL x1 y [c]))
2842         for {
2843                 x0 := v_0
2844                 if x0.Op != OpARM64SRLconst {
2845                         break
2846                 }
2847                 c := auxIntToInt64(x0.AuxInt)
2848                 y := x0.Args[0]
2849                 x1 := v_1
2850                 if !(clobberIfDead(x0)) {
2851                         break
2852                 }
2853                 v.reset(OpARM64InvertFlags)
2854                 v0 := b.NewValue0(v.Pos, OpARM64CMPshiftRL, types.TypeFlags)
2855                 v0.AuxInt = int64ToAuxInt(c)
2856                 v0.AddArg2(x1, y)
2857                 v.AddArg(v0)
2858                 return true
2859         }
2860         // match: (CMP x0 x1:(SRAconst [c] y))
2861         // cond: clobberIfDead(x1)
2862         // result: (CMPshiftRA x0 y [c])
2863         for {
2864                 x0 := v_0
2865                 x1 := v_1
2866                 if x1.Op != OpARM64SRAconst {
2867                         break
2868                 }
2869                 c := auxIntToInt64(x1.AuxInt)
2870                 y := x1.Args[0]
2871                 if !(clobberIfDead(x1)) {
2872                         break
2873                 }
2874                 v.reset(OpARM64CMPshiftRA)
2875                 v.AuxInt = int64ToAuxInt(c)
2876                 v.AddArg2(x0, y)
2877                 return true
2878         }
2879         // match: (CMP x0:(SRAconst [c] y) x1)
2880         // cond: clobberIfDead(x0)
2881         // result: (InvertFlags (CMPshiftRA x1 y [c]))
2882         for {
2883                 x0 := v_0
2884                 if x0.Op != OpARM64SRAconst {
2885                         break
2886                 }
2887                 c := auxIntToInt64(x0.AuxInt)
2888                 y := x0.Args[0]
2889                 x1 := v_1
2890                 if !(clobberIfDead(x0)) {
2891                         break
2892                 }
2893                 v.reset(OpARM64InvertFlags)
2894                 v0 := b.NewValue0(v.Pos, OpARM64CMPshiftRA, types.TypeFlags)
2895                 v0.AuxInt = int64ToAuxInt(c)
2896                 v0.AddArg2(x1, y)
2897                 v.AddArg(v0)
2898                 return true
2899         }
2900         return false
2901 }
2902 func rewriteValueARM64_OpARM64CMPW(v *Value) bool {
2903         v_1 := v.Args[1]
2904         v_0 := v.Args[0]
2905         b := v.Block
2906         // match: (CMPW x (MOVDconst [c]))
2907         // result: (CMPWconst [int32(c)] x)
2908         for {
2909                 x := v_0
2910                 if v_1.Op != OpARM64MOVDconst {
2911                         break
2912                 }
2913                 c := auxIntToInt64(v_1.AuxInt)
2914                 v.reset(OpARM64CMPWconst)
2915                 v.AuxInt = int32ToAuxInt(int32(c))
2916                 v.AddArg(x)
2917                 return true
2918         }
2919         // match: (CMPW (MOVDconst [c]) x)
2920         // result: (InvertFlags (CMPWconst [int32(c)] x))
2921         for {
2922                 if v_0.Op != OpARM64MOVDconst {
2923                         break
2924                 }
2925                 c := auxIntToInt64(v_0.AuxInt)
2926                 x := v_1
2927                 v.reset(OpARM64InvertFlags)
2928                 v0 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags)
2929                 v0.AuxInt = int32ToAuxInt(int32(c))
2930                 v0.AddArg(x)
2931                 v.AddArg(v0)
2932                 return true
2933         }
2934         // match: (CMPW x y)
2935         // cond: canonLessThan(x,y)
2936         // result: (InvertFlags (CMPW y x))
2937         for {
2938                 x := v_0
2939                 y := v_1
2940                 if !(canonLessThan(x, y)) {
2941                         break
2942                 }
2943                 v.reset(OpARM64InvertFlags)
2944                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
2945                 v0.AddArg2(y, x)
2946                 v.AddArg(v0)
2947                 return true
2948         }
2949         return false
2950 }
2951 func rewriteValueARM64_OpARM64CMPWconst(v *Value) bool {
2952         v_0 := v.Args[0]
2953         // match: (CMPWconst [c] y)
2954         // cond: c < 0 && c != -1<<31
2955         // result: (CMNWconst [-c] y)
2956         for {
2957                 c := auxIntToInt32(v.AuxInt)
2958                 y := v_0
2959                 if !(c < 0 && c != -1<<31) {
2960                         break
2961                 }
2962                 v.reset(OpARM64CMNWconst)
2963                 v.AuxInt = int32ToAuxInt(-c)
2964                 v.AddArg(y)
2965                 return true
2966         }
2967         // match: (CMPWconst (MOVDconst [x]) [y])
2968         // result: (FlagConstant [subFlags32(int32(x),y)])
2969         for {
2970                 y := auxIntToInt32(v.AuxInt)
2971                 if v_0.Op != OpARM64MOVDconst {
2972                         break
2973                 }
2974                 x := auxIntToInt64(v_0.AuxInt)
2975                 v.reset(OpARM64FlagConstant)
2976                 v.AuxInt = flagConstantToAuxInt(subFlags32(int32(x), y))
2977                 return true
2978         }
2979         // match: (CMPWconst (MOVBUreg _) [c])
2980         // cond: 0xff < c
2981         // result: (FlagConstant [subFlags64(0,1)])
2982         for {
2983                 c := auxIntToInt32(v.AuxInt)
2984                 if v_0.Op != OpARM64MOVBUreg || !(0xff < c) {
2985                         break
2986                 }
2987                 v.reset(OpARM64FlagConstant)
2988                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
2989                 return true
2990         }
2991         // match: (CMPWconst (MOVHUreg _) [c])
2992         // cond: 0xffff < c
2993         // result: (FlagConstant [subFlags64(0,1)])
2994         for {
2995                 c := auxIntToInt32(v.AuxInt)
2996                 if v_0.Op != OpARM64MOVHUreg || !(0xffff < c) {
2997                         break
2998                 }
2999                 v.reset(OpARM64FlagConstant)
3000                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
3001                 return true
3002         }
3003         return false
3004 }
3005 func rewriteValueARM64_OpARM64CMPconst(v *Value) bool {
3006         v_0 := v.Args[0]
3007         // match: (CMPconst [c] y)
3008         // cond: c < 0 && c != -1<<63
3009         // result: (CMNconst [-c] y)
3010         for {
3011                 c := auxIntToInt64(v.AuxInt)
3012                 y := v_0
3013                 if !(c < 0 && c != -1<<63) {
3014                         break
3015                 }
3016                 v.reset(OpARM64CMNconst)
3017                 v.AuxInt = int64ToAuxInt(-c)
3018                 v.AddArg(y)
3019                 return true
3020         }
3021         // match: (CMPconst (MOVDconst [x]) [y])
3022         // result: (FlagConstant [subFlags64(x,y)])
3023         for {
3024                 y := auxIntToInt64(v.AuxInt)
3025                 if v_0.Op != OpARM64MOVDconst {
3026                         break
3027                 }
3028                 x := auxIntToInt64(v_0.AuxInt)
3029                 v.reset(OpARM64FlagConstant)
3030                 v.AuxInt = flagConstantToAuxInt(subFlags64(x, y))
3031                 return true
3032         }
3033         // match: (CMPconst (MOVBUreg _) [c])
3034         // cond: 0xff < c
3035         // result: (FlagConstant [subFlags64(0,1)])
3036         for {
3037                 c := auxIntToInt64(v.AuxInt)
3038                 if v_0.Op != OpARM64MOVBUreg || !(0xff < c) {
3039                         break
3040                 }
3041                 v.reset(OpARM64FlagConstant)
3042                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
3043                 return true
3044         }
3045         // match: (CMPconst (MOVHUreg _) [c])
3046         // cond: 0xffff < c
3047         // result: (FlagConstant [subFlags64(0,1)])
3048         for {
3049                 c := auxIntToInt64(v.AuxInt)
3050                 if v_0.Op != OpARM64MOVHUreg || !(0xffff < c) {
3051                         break
3052                 }
3053                 v.reset(OpARM64FlagConstant)
3054                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
3055                 return true
3056         }
3057         // match: (CMPconst (MOVWUreg _) [c])
3058         // cond: 0xffffffff < c
3059         // result: (FlagConstant [subFlags64(0,1)])
3060         for {
3061                 c := auxIntToInt64(v.AuxInt)
3062                 if v_0.Op != OpARM64MOVWUreg || !(0xffffffff < c) {
3063                         break
3064                 }
3065                 v.reset(OpARM64FlagConstant)
3066                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
3067                 return true
3068         }
3069         // match: (CMPconst (ANDconst _ [m]) [n])
3070         // cond: 0 <= m && m < n
3071         // result: (FlagConstant [subFlags64(0,1)])
3072         for {
3073                 n := auxIntToInt64(v.AuxInt)
3074                 if v_0.Op != OpARM64ANDconst {
3075                         break
3076                 }
3077                 m := auxIntToInt64(v_0.AuxInt)
3078                 if !(0 <= m && m < n) {
3079                         break
3080                 }
3081                 v.reset(OpARM64FlagConstant)
3082                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
3083                 return true
3084         }
3085         // match: (CMPconst (SRLconst _ [c]) [n])
3086         // cond: 0 <= n && 0 < c && c <= 63 && (1<<uint64(64-c)) <= uint64(n)
3087         // result: (FlagConstant [subFlags64(0,1)])
3088         for {
3089                 n := auxIntToInt64(v.AuxInt)
3090                 if v_0.Op != OpARM64SRLconst {
3091                         break
3092                 }
3093                 c := auxIntToInt64(v_0.AuxInt)
3094                 if !(0 <= n && 0 < c && c <= 63 && (1<<uint64(64-c)) <= uint64(n)) {
3095                         break
3096                 }
3097                 v.reset(OpARM64FlagConstant)
3098                 v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
3099                 return true
3100         }
3101         return false
3102 }
3103 func rewriteValueARM64_OpARM64CMPshiftLL(v *Value) bool {
3104         v_1 := v.Args[1]
3105         v_0 := v.Args[0]
3106         b := v.Block
3107         // match: (CMPshiftLL (MOVDconst [c]) x [d])
3108         // result: (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
3109         for {
3110                 d := auxIntToInt64(v.AuxInt)
3111                 if v_0.Op != OpARM64MOVDconst {
3112                         break
3113                 }
3114                 c := auxIntToInt64(v_0.AuxInt)
3115                 x := v_1
3116                 v.reset(OpARM64InvertFlags)
3117                 v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
3118                 v0.AuxInt = int64ToAuxInt(c)
3119                 v1 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
3120                 v1.AuxInt = int64ToAuxInt(d)
3121                 v1.AddArg(x)
3122                 v0.AddArg(v1)
3123                 v.AddArg(v0)
3124                 return true
3125         }
3126         // match: (CMPshiftLL x (MOVDconst [c]) [d])
3127         // result: (CMPconst x [int64(uint64(c)<<uint64(d))])
3128         for {
3129                 d := auxIntToInt64(v.AuxInt)
3130                 x := v_0
3131                 if v_1.Op != OpARM64MOVDconst {
3132                         break
3133                 }
3134                 c := auxIntToInt64(v_1.AuxInt)
3135                 v.reset(OpARM64CMPconst)
3136                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
3137                 v.AddArg(x)
3138                 return true
3139         }
3140         return false
3141 }
3142 func rewriteValueARM64_OpARM64CMPshiftRA(v *Value) bool {
3143         v_1 := v.Args[1]
3144         v_0 := v.Args[0]
3145         b := v.Block
3146         // match: (CMPshiftRA (MOVDconst [c]) x [d])
3147         // result: (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
3148         for {
3149                 d := auxIntToInt64(v.AuxInt)
3150                 if v_0.Op != OpARM64MOVDconst {
3151                         break
3152                 }
3153                 c := auxIntToInt64(v_0.AuxInt)
3154                 x := v_1
3155                 v.reset(OpARM64InvertFlags)
3156                 v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
3157                 v0.AuxInt = int64ToAuxInt(c)
3158                 v1 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
3159                 v1.AuxInt = int64ToAuxInt(d)
3160                 v1.AddArg(x)
3161                 v0.AddArg(v1)
3162                 v.AddArg(v0)
3163                 return true
3164         }
3165         // match: (CMPshiftRA x (MOVDconst [c]) [d])
3166         // result: (CMPconst x [c>>uint64(d)])
3167         for {
3168                 d := auxIntToInt64(v.AuxInt)
3169                 x := v_0
3170                 if v_1.Op != OpARM64MOVDconst {
3171                         break
3172                 }
3173                 c := auxIntToInt64(v_1.AuxInt)
3174                 v.reset(OpARM64CMPconst)
3175                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
3176                 v.AddArg(x)
3177                 return true
3178         }
3179         return false
3180 }
3181 func rewriteValueARM64_OpARM64CMPshiftRL(v *Value) bool {
3182         v_1 := v.Args[1]
3183         v_0 := v.Args[0]
3184         b := v.Block
3185         // match: (CMPshiftRL (MOVDconst [c]) x [d])
3186         // result: (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
3187         for {
3188                 d := auxIntToInt64(v.AuxInt)
3189                 if v_0.Op != OpARM64MOVDconst {
3190                         break
3191                 }
3192                 c := auxIntToInt64(v_0.AuxInt)
3193                 x := v_1
3194                 v.reset(OpARM64InvertFlags)
3195                 v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
3196                 v0.AuxInt = int64ToAuxInt(c)
3197                 v1 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
3198                 v1.AuxInt = int64ToAuxInt(d)
3199                 v1.AddArg(x)
3200                 v0.AddArg(v1)
3201                 v.AddArg(v0)
3202                 return true
3203         }
3204         // match: (CMPshiftRL x (MOVDconst [c]) [d])
3205         // result: (CMPconst x [int64(uint64(c)>>uint64(d))])
3206         for {
3207                 d := auxIntToInt64(v.AuxInt)
3208                 x := v_0
3209                 if v_1.Op != OpARM64MOVDconst {
3210                         break
3211                 }
3212                 c := auxIntToInt64(v_1.AuxInt)
3213                 v.reset(OpARM64CMPconst)
3214                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
3215                 v.AddArg(x)
3216                 return true
3217         }
3218         return false
3219 }
3220 func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
3221         v_2 := v.Args[2]
3222         v_1 := v.Args[1]
3223         v_0 := v.Args[0]
3224         // match: (CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag)
3225         // result: (CSETM [cc] flag)
3226         for {
3227                 cc := auxIntToOp(v.AuxInt)
3228                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != -1 || v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
3229                         break
3230                 }
3231                 flag := v_2
3232                 v.reset(OpARM64CSETM)
3233                 v.AuxInt = opToAuxInt(cc)
3234                 v.AddArg(flag)
3235                 return true
3236         }
3237         // match: (CSEL [cc] (MOVDconst [0]) (MOVDconst [-1]) flag)
3238         // result: (CSETM [arm64Negate(cc)] flag)
3239         for {
3240                 cc := auxIntToOp(v.AuxInt)
3241                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 || v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
3242                         break
3243                 }
3244                 flag := v_2
3245                 v.reset(OpARM64CSETM)
3246                 v.AuxInt = opToAuxInt(arm64Negate(cc))
3247                 v.AddArg(flag)
3248                 return true
3249         }
3250         // match: (CSEL [cc] x (MOVDconst [0]) flag)
3251         // result: (CSEL0 [cc] x flag)
3252         for {
3253                 cc := auxIntToOp(v.AuxInt)
3254                 x := v_0
3255                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
3256                         break
3257                 }
3258                 flag := v_2
3259                 v.reset(OpARM64CSEL0)
3260                 v.AuxInt = opToAuxInt(cc)
3261                 v.AddArg2(x, flag)
3262                 return true
3263         }
3264         // match: (CSEL [cc] (MOVDconst [0]) y flag)
3265         // result: (CSEL0 [arm64Negate(cc)] y flag)
3266         for {
3267                 cc := auxIntToOp(v.AuxInt)
3268                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 {
3269                         break
3270                 }
3271                 y := v_1
3272                 flag := v_2
3273                 v.reset(OpARM64CSEL0)
3274                 v.AuxInt = opToAuxInt(arm64Negate(cc))
3275                 v.AddArg2(y, flag)
3276                 return true
3277         }
3278         // match: (CSEL [cc] x (ADDconst [1] a) flag)
3279         // result: (CSINC [cc] x a flag)
3280         for {
3281                 cc := auxIntToOp(v.AuxInt)
3282                 x := v_0
3283                 if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
3284                         break
3285                 }
3286                 a := v_1.Args[0]
3287                 flag := v_2
3288                 v.reset(OpARM64CSINC)
3289                 v.AuxInt = opToAuxInt(cc)
3290                 v.AddArg3(x, a, flag)
3291                 return true
3292         }
3293         // match: (CSEL [cc] (ADDconst [1] a) x flag)
3294         // result: (CSINC [arm64Negate(cc)] x a flag)
3295         for {
3296                 cc := auxIntToOp(v.AuxInt)
3297                 if v_0.Op != OpARM64ADDconst || auxIntToInt64(v_0.AuxInt) != 1 {
3298                         break
3299                 }
3300                 a := v_0.Args[0]
3301                 x := v_1
3302                 flag := v_2
3303                 v.reset(OpARM64CSINC)
3304                 v.AuxInt = opToAuxInt(arm64Negate(cc))
3305                 v.AddArg3(x, a, flag)
3306                 return true
3307         }
3308         // match: (CSEL [cc] x (MVN a) flag)
3309         // result: (CSINV [cc] x a flag)
3310         for {
3311                 cc := auxIntToOp(v.AuxInt)
3312                 x := v_0
3313                 if v_1.Op != OpARM64MVN {
3314                         break
3315                 }
3316                 a := v_1.Args[0]
3317                 flag := v_2
3318                 v.reset(OpARM64CSINV)
3319                 v.AuxInt = opToAuxInt(cc)
3320                 v.AddArg3(x, a, flag)
3321                 return true
3322         }
3323         // match: (CSEL [cc] (MVN a) x flag)
3324         // result: (CSINV [arm64Negate(cc)] x a flag)
3325         for {
3326                 cc := auxIntToOp(v.AuxInt)
3327                 if v_0.Op != OpARM64MVN {
3328                         break
3329                 }
3330                 a := v_0.Args[0]
3331                 x := v_1
3332                 flag := v_2
3333                 v.reset(OpARM64CSINV)
3334                 v.AuxInt = opToAuxInt(arm64Negate(cc))
3335                 v.AddArg3(x, a, flag)
3336                 return true
3337         }
3338         // match: (CSEL [cc] x (NEG a) flag)
3339         // result: (CSNEG [cc] x a flag)
3340         for {
3341                 cc := auxIntToOp(v.AuxInt)
3342                 x := v_0
3343                 if v_1.Op != OpARM64NEG {
3344                         break
3345                 }
3346                 a := v_1.Args[0]
3347                 flag := v_2
3348                 v.reset(OpARM64CSNEG)
3349                 v.AuxInt = opToAuxInt(cc)
3350                 v.AddArg3(x, a, flag)
3351                 return true
3352         }
3353         // match: (CSEL [cc] (NEG a) x flag)
3354         // result: (CSNEG [arm64Negate(cc)] x a flag)
3355         for {
3356                 cc := auxIntToOp(v.AuxInt)
3357                 if v_0.Op != OpARM64NEG {
3358                         break
3359                 }
3360                 a := v_0.Args[0]
3361                 x := v_1
3362                 flag := v_2
3363                 v.reset(OpARM64CSNEG)
3364                 v.AuxInt = opToAuxInt(arm64Negate(cc))
3365                 v.AddArg3(x, a, flag)
3366                 return true
3367         }
3368         // match: (CSEL [cc] x y (InvertFlags cmp))
3369         // result: (CSEL [arm64Invert(cc)] x y cmp)
3370         for {
3371                 cc := auxIntToOp(v.AuxInt)
3372                 x := v_0
3373                 y := v_1
3374                 if v_2.Op != OpARM64InvertFlags {
3375                         break
3376                 }
3377                 cmp := v_2.Args[0]
3378                 v.reset(OpARM64CSEL)
3379                 v.AuxInt = opToAuxInt(arm64Invert(cc))
3380                 v.AddArg3(x, y, cmp)
3381                 return true
3382         }
3383         // match: (CSEL [cc] x _ flag)
3384         // cond: ccARM64Eval(cc, flag) > 0
3385         // result: x
3386         for {
3387                 cc := auxIntToOp(v.AuxInt)
3388                 x := v_0
3389                 flag := v_2
3390                 if !(ccARM64Eval(cc, flag) > 0) {
3391                         break
3392                 }
3393                 v.copyOf(x)
3394                 return true
3395         }
3396         // match: (CSEL [cc] _ y flag)
3397         // cond: ccARM64Eval(cc, flag) < 0
3398         // result: y
3399         for {
3400                 cc := auxIntToOp(v.AuxInt)
3401                 y := v_1
3402                 flag := v_2
3403                 if !(ccARM64Eval(cc, flag) < 0) {
3404                         break
3405                 }
3406                 v.copyOf(y)
3407                 return true
3408         }
3409         // match: (CSEL [cc] x y (CMPWconst [0] boolval))
3410         // cond: cc == OpARM64NotEqual && flagArg(boolval) != nil
3411         // result: (CSEL [boolval.Op] x y flagArg(boolval))
3412         for {
3413                 cc := auxIntToOp(v.AuxInt)
3414                 x := v_0
3415                 y := v_1
3416                 if v_2.Op != OpARM64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
3417                         break
3418                 }
3419                 boolval := v_2.Args[0]
3420                 if !(cc == OpARM64NotEqual && flagArg(boolval) != nil) {
3421                         break
3422                 }
3423                 v.reset(OpARM64CSEL)
3424                 v.AuxInt = opToAuxInt(boolval.Op)
3425                 v.AddArg3(x, y, flagArg(boolval))
3426                 return true
3427         }
3428         // match: (CSEL [cc] x y (CMPWconst [0] boolval))
3429         // cond: cc == OpARM64Equal && flagArg(boolval) != nil
3430         // result: (CSEL [arm64Negate(boolval.Op)] x y flagArg(boolval))
3431         for {
3432                 cc := auxIntToOp(v.AuxInt)
3433                 x := v_0
3434                 y := v_1
3435                 if v_2.Op != OpARM64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
3436                         break
3437                 }
3438                 boolval := v_2.Args[0]
3439                 if !(cc == OpARM64Equal && flagArg(boolval) != nil) {
3440                         break
3441                 }
3442                 v.reset(OpARM64CSEL)
3443                 v.AuxInt = opToAuxInt(arm64Negate(boolval.Op))
3444                 v.AddArg3(x, y, flagArg(boolval))
3445                 return true
3446         }
3447         return false
3448 }
3449 func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
3450         v_1 := v.Args[1]
3451         v_0 := v.Args[0]
3452         // match: (CSEL0 [cc] x (InvertFlags cmp))
3453         // result: (CSEL0 [arm64Invert(cc)] x cmp)
3454         for {
3455                 cc := auxIntToOp(v.AuxInt)
3456                 x := v_0
3457                 if v_1.Op != OpARM64InvertFlags {
3458                         break
3459                 }
3460                 cmp := v_1.Args[0]
3461                 v.reset(OpARM64CSEL0)
3462                 v.AuxInt = opToAuxInt(arm64Invert(cc))
3463                 v.AddArg2(x, cmp)
3464                 return true
3465         }
3466         // match: (CSEL0 [cc] x flag)
3467         // cond: ccARM64Eval(cc, flag) > 0
3468         // result: x
3469         for {
3470                 cc := auxIntToOp(v.AuxInt)
3471                 x := v_0
3472                 flag := v_1
3473                 if !(ccARM64Eval(cc, flag) > 0) {
3474                         break
3475                 }
3476                 v.copyOf(x)
3477                 return true
3478         }
3479         // match: (CSEL0 [cc] _ flag)
3480         // cond: ccARM64Eval(cc, flag) < 0
3481         // result: (MOVDconst [0])
3482         for {
3483                 cc := auxIntToOp(v.AuxInt)
3484                 flag := v_1
3485                 if !(ccARM64Eval(cc, flag) < 0) {
3486                         break
3487                 }
3488                 v.reset(OpARM64MOVDconst)
3489                 v.AuxInt = int64ToAuxInt(0)
3490                 return true
3491         }
3492         // match: (CSEL0 [cc] x (CMPWconst [0] boolval))
3493         // cond: cc == OpARM64NotEqual && flagArg(boolval) != nil
3494         // result: (CSEL0 [boolval.Op] x flagArg(boolval))
3495         for {
3496                 cc := auxIntToOp(v.AuxInt)
3497                 x := v_0
3498                 if v_1.Op != OpARM64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
3499                         break
3500                 }
3501                 boolval := v_1.Args[0]
3502                 if !(cc == OpARM64NotEqual && flagArg(boolval) != nil) {
3503                         break
3504                 }
3505                 v.reset(OpARM64CSEL0)
3506                 v.AuxInt = opToAuxInt(boolval.Op)
3507                 v.AddArg2(x, flagArg(boolval))
3508                 return true
3509         }
3510         // match: (CSEL0 [cc] x (CMPWconst [0] boolval))
3511         // cond: cc == OpARM64Equal && flagArg(boolval) != nil
3512         // result: (CSEL0 [arm64Negate(boolval.Op)] x flagArg(boolval))
3513         for {
3514                 cc := auxIntToOp(v.AuxInt)
3515                 x := v_0
3516                 if v_1.Op != OpARM64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
3517                         break
3518                 }
3519                 boolval := v_1.Args[0]
3520                 if !(cc == OpARM64Equal && flagArg(boolval) != nil) {
3521                         break
3522                 }
3523                 v.reset(OpARM64CSEL0)
3524                 v.AuxInt = opToAuxInt(arm64Negate(boolval.Op))
3525                 v.AddArg2(x, flagArg(boolval))
3526                 return true
3527         }
3528         return false
3529 }
3530 func rewriteValueARM64_OpARM64CSETM(v *Value) bool {
3531         v_0 := v.Args[0]
3532         // match: (CSETM [cc] (InvertFlags cmp))
3533         // result: (CSETM [arm64Invert(cc)] cmp)
3534         for {
3535                 cc := auxIntToOp(v.AuxInt)
3536                 if v_0.Op != OpARM64InvertFlags {
3537                         break
3538                 }
3539                 cmp := v_0.Args[0]
3540                 v.reset(OpARM64CSETM)
3541                 v.AuxInt = opToAuxInt(arm64Invert(cc))
3542                 v.AddArg(cmp)
3543                 return true
3544         }
3545         // match: (CSETM [cc] flag)
3546         // cond: ccARM64Eval(cc, flag) > 0
3547         // result: (MOVDconst [-1])
3548         for {
3549                 cc := auxIntToOp(v.AuxInt)
3550                 flag := v_0
3551                 if !(ccARM64Eval(cc, flag) > 0) {
3552                         break
3553                 }
3554                 v.reset(OpARM64MOVDconst)
3555                 v.AuxInt = int64ToAuxInt(-1)
3556                 return true
3557         }
3558         // match: (CSETM [cc] flag)
3559         // cond: ccARM64Eval(cc, flag) < 0
3560         // result: (MOVDconst [0])
3561         for {
3562                 cc := auxIntToOp(v.AuxInt)
3563                 flag := v_0
3564                 if !(ccARM64Eval(cc, flag) < 0) {
3565                         break
3566                 }
3567                 v.reset(OpARM64MOVDconst)
3568                 v.AuxInt = int64ToAuxInt(0)
3569                 return true
3570         }
3571         return false
3572 }
3573 func rewriteValueARM64_OpARM64CSINC(v *Value) bool {
3574         v_2 := v.Args[2]
3575         v_1 := v.Args[1]
3576         v_0 := v.Args[0]
3577         // match: (CSINC [cc] x y (InvertFlags cmp))
3578         // result: (CSINC [arm64Invert(cc)] x y cmp)
3579         for {
3580                 cc := auxIntToOp(v.AuxInt)
3581                 x := v_0
3582                 y := v_1
3583                 if v_2.Op != OpARM64InvertFlags {
3584                         break
3585                 }
3586                 cmp := v_2.Args[0]
3587                 v.reset(OpARM64CSINC)
3588                 v.AuxInt = opToAuxInt(arm64Invert(cc))
3589                 v.AddArg3(x, y, cmp)
3590                 return true
3591         }
3592         // match: (CSINC [cc] x _ flag)
3593         // cond: ccARM64Eval(cc, flag) > 0
3594         // result: x
3595         for {
3596                 cc := auxIntToOp(v.AuxInt)
3597                 x := v_0
3598                 flag := v_2
3599                 if !(ccARM64Eval(cc, flag) > 0) {
3600                         break
3601                 }
3602                 v.copyOf(x)
3603                 return true
3604         }
3605         // match: (CSINC [cc] _ y flag)
3606         // cond: ccARM64Eval(cc, flag) < 0
3607         // result: (ADDconst [1] y)
3608         for {
3609                 cc := auxIntToOp(v.AuxInt)
3610                 y := v_1
3611                 flag := v_2
3612                 if !(ccARM64Eval(cc, flag) < 0) {
3613                         break
3614                 }
3615                 v.reset(OpARM64ADDconst)
3616                 v.AuxInt = int64ToAuxInt(1)
3617                 v.AddArg(y)
3618                 return true
3619         }
3620         return false
3621 }
3622 func rewriteValueARM64_OpARM64CSINV(v *Value) bool {
3623         v_2 := v.Args[2]
3624         v_1 := v.Args[1]
3625         v_0 := v.Args[0]
3626         // match: (CSINV [cc] x y (InvertFlags cmp))
3627         // result: (CSINV [arm64Invert(cc)] x y cmp)
3628         for {
3629                 cc := auxIntToOp(v.AuxInt)
3630                 x := v_0
3631                 y := v_1
3632                 if v_2.Op != OpARM64InvertFlags {
3633                         break
3634                 }
3635                 cmp := v_2.Args[0]
3636                 v.reset(OpARM64CSINV)
3637                 v.AuxInt = opToAuxInt(arm64Invert(cc))
3638                 v.AddArg3(x, y, cmp)
3639                 return true
3640         }
3641         // match: (CSINV [cc] x _ flag)
3642         // cond: ccARM64Eval(cc, flag) > 0
3643         // result: x
3644         for {
3645                 cc := auxIntToOp(v.AuxInt)
3646                 x := v_0
3647                 flag := v_2
3648                 if !(ccARM64Eval(cc, flag) > 0) {
3649                         break
3650                 }
3651                 v.copyOf(x)
3652                 return true
3653         }
3654         // match: (CSINV [cc] _ y flag)
3655         // cond: ccARM64Eval(cc, flag) < 0
3656         // result: (Not y)
3657         for {
3658                 cc := auxIntToOp(v.AuxInt)
3659                 y := v_1
3660                 flag := v_2
3661                 if !(ccARM64Eval(cc, flag) < 0) {
3662                         break
3663                 }
3664                 v.reset(OpNot)
3665                 v.AddArg(y)
3666                 return true
3667         }
3668         return false
3669 }
3670 func rewriteValueARM64_OpARM64CSNEG(v *Value) bool {
3671         v_2 := v.Args[2]
3672         v_1 := v.Args[1]
3673         v_0 := v.Args[0]
3674         // match: (CSNEG [cc] x y (InvertFlags cmp))
3675         // result: (CSNEG [arm64Invert(cc)] x y cmp)
3676         for {
3677                 cc := auxIntToOp(v.AuxInt)
3678                 x := v_0
3679                 y := v_1
3680                 if v_2.Op != OpARM64InvertFlags {
3681                         break
3682                 }
3683                 cmp := v_2.Args[0]
3684                 v.reset(OpARM64CSNEG)
3685                 v.AuxInt = opToAuxInt(arm64Invert(cc))
3686                 v.AddArg3(x, y, cmp)
3687                 return true
3688         }
3689         // match: (CSNEG [cc] x _ flag)
3690         // cond: ccARM64Eval(cc, flag) > 0
3691         // result: x
3692         for {
3693                 cc := auxIntToOp(v.AuxInt)
3694                 x := v_0
3695                 flag := v_2
3696                 if !(ccARM64Eval(cc, flag) > 0) {
3697                         break
3698                 }
3699                 v.copyOf(x)
3700                 return true
3701         }
3702         // match: (CSNEG [cc] _ y flag)
3703         // cond: ccARM64Eval(cc, flag) < 0
3704         // result: (NEG y)
3705         for {
3706                 cc := auxIntToOp(v.AuxInt)
3707                 y := v_1
3708                 flag := v_2
3709                 if !(ccARM64Eval(cc, flag) < 0) {
3710                         break
3711                 }
3712                 v.reset(OpARM64NEG)
3713                 v.AddArg(y)
3714                 return true
3715         }
3716         return false
3717 }
3718 func rewriteValueARM64_OpARM64DIV(v *Value) bool {
3719         v_1 := v.Args[1]
3720         v_0 := v.Args[0]
3721         // match: (DIV (MOVDconst [c]) (MOVDconst [d]))
3722         // cond: d != 0
3723         // result: (MOVDconst [c/d])
3724         for {
3725                 if v_0.Op != OpARM64MOVDconst {
3726                         break
3727                 }
3728                 c := auxIntToInt64(v_0.AuxInt)
3729                 if v_1.Op != OpARM64MOVDconst {
3730                         break
3731                 }
3732                 d := auxIntToInt64(v_1.AuxInt)
3733                 if !(d != 0) {
3734                         break
3735                 }
3736                 v.reset(OpARM64MOVDconst)
3737                 v.AuxInt = int64ToAuxInt(c / d)
3738                 return true
3739         }
3740         return false
3741 }
3742 func rewriteValueARM64_OpARM64DIVW(v *Value) bool {
3743         v_1 := v.Args[1]
3744         v_0 := v.Args[0]
3745         // match: (DIVW (MOVDconst [c]) (MOVDconst [d]))
3746         // cond: d != 0
3747         // result: (MOVDconst [int64(uint32(int32(c)/int32(d)))])
3748         for {
3749                 if v_0.Op != OpARM64MOVDconst {
3750                         break
3751                 }
3752                 c := auxIntToInt64(v_0.AuxInt)
3753                 if v_1.Op != OpARM64MOVDconst {
3754                         break
3755                 }
3756                 d := auxIntToInt64(v_1.AuxInt)
3757                 if !(d != 0) {
3758                         break
3759                 }
3760                 v.reset(OpARM64MOVDconst)
3761                 v.AuxInt = int64ToAuxInt(int64(uint32(int32(c) / int32(d))))
3762                 return true
3763         }
3764         return false
3765 }
3766 func rewriteValueARM64_OpARM64EON(v *Value) bool {
3767         v_1 := v.Args[1]
3768         v_0 := v.Args[0]
3769         // match: (EON x (MOVDconst [c]))
3770         // result: (XORconst [^c] x)
3771         for {
3772                 x := v_0
3773                 if v_1.Op != OpARM64MOVDconst {
3774                         break
3775                 }
3776                 c := auxIntToInt64(v_1.AuxInt)
3777                 v.reset(OpARM64XORconst)
3778                 v.AuxInt = int64ToAuxInt(^c)
3779                 v.AddArg(x)
3780                 return true
3781         }
3782         // match: (EON x x)
3783         // result: (MOVDconst [-1])
3784         for {
3785                 x := v_0
3786                 if x != v_1 {
3787                         break
3788                 }
3789                 v.reset(OpARM64MOVDconst)
3790                 v.AuxInt = int64ToAuxInt(-1)
3791                 return true
3792         }
3793         // match: (EON x0 x1:(SLLconst [c] y))
3794         // cond: clobberIfDead(x1)
3795         // result: (EONshiftLL x0 y [c])
3796         for {
3797                 x0 := v_0
3798                 x1 := v_1
3799                 if x1.Op != OpARM64SLLconst {
3800                         break
3801                 }
3802                 c := auxIntToInt64(x1.AuxInt)
3803                 y := x1.Args[0]
3804                 if !(clobberIfDead(x1)) {
3805                         break
3806                 }
3807                 v.reset(OpARM64EONshiftLL)
3808                 v.AuxInt = int64ToAuxInt(c)
3809                 v.AddArg2(x0, y)
3810                 return true
3811         }
3812         // match: (EON x0 x1:(SRLconst [c] y))
3813         // cond: clobberIfDead(x1)
3814         // result: (EONshiftRL x0 y [c])
3815         for {
3816                 x0 := v_0
3817                 x1 := v_1
3818                 if x1.Op != OpARM64SRLconst {
3819                         break
3820                 }
3821                 c := auxIntToInt64(x1.AuxInt)
3822                 y := x1.Args[0]
3823                 if !(clobberIfDead(x1)) {
3824                         break
3825                 }
3826                 v.reset(OpARM64EONshiftRL)
3827                 v.AuxInt = int64ToAuxInt(c)
3828                 v.AddArg2(x0, y)
3829                 return true
3830         }
3831         // match: (EON x0 x1:(SRAconst [c] y))
3832         // cond: clobberIfDead(x1)
3833         // result: (EONshiftRA x0 y [c])
3834         for {
3835                 x0 := v_0
3836                 x1 := v_1
3837                 if x1.Op != OpARM64SRAconst {
3838                         break
3839                 }
3840                 c := auxIntToInt64(x1.AuxInt)
3841                 y := x1.Args[0]
3842                 if !(clobberIfDead(x1)) {
3843                         break
3844                 }
3845                 v.reset(OpARM64EONshiftRA)
3846                 v.AuxInt = int64ToAuxInt(c)
3847                 v.AddArg2(x0, y)
3848                 return true
3849         }
3850         // match: (EON x0 x1:(RORconst [c] y))
3851         // cond: clobberIfDead(x1)
3852         // result: (EONshiftRO x0 y [c])
3853         for {
3854                 x0 := v_0
3855                 x1 := v_1
3856                 if x1.Op != OpARM64RORconst {
3857                         break
3858                 }
3859                 c := auxIntToInt64(x1.AuxInt)
3860                 y := x1.Args[0]
3861                 if !(clobberIfDead(x1)) {
3862                         break
3863                 }
3864                 v.reset(OpARM64EONshiftRO)
3865                 v.AuxInt = int64ToAuxInt(c)
3866                 v.AddArg2(x0, y)
3867                 return true
3868         }
3869         return false
3870 }
3871 func rewriteValueARM64_OpARM64EONshiftLL(v *Value) bool {
3872         v_1 := v.Args[1]
3873         v_0 := v.Args[0]
3874         // match: (EONshiftLL x (MOVDconst [c]) [d])
3875         // result: (XORconst x [^int64(uint64(c)<<uint64(d))])
3876         for {
3877                 d := auxIntToInt64(v.AuxInt)
3878                 x := v_0
3879                 if v_1.Op != OpARM64MOVDconst {
3880                         break
3881                 }
3882                 c := auxIntToInt64(v_1.AuxInt)
3883                 v.reset(OpARM64XORconst)
3884                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) << uint64(d)))
3885                 v.AddArg(x)
3886                 return true
3887         }
3888         // match: (EONshiftLL (SLLconst x [c]) x [c])
3889         // result: (MOVDconst [-1])
3890         for {
3891                 c := auxIntToInt64(v.AuxInt)
3892                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
3893                         break
3894                 }
3895                 x := v_0.Args[0]
3896                 if x != v_1 {
3897                         break
3898                 }
3899                 v.reset(OpARM64MOVDconst)
3900                 v.AuxInt = int64ToAuxInt(-1)
3901                 return true
3902         }
3903         return false
3904 }
3905 func rewriteValueARM64_OpARM64EONshiftRA(v *Value) bool {
3906         v_1 := v.Args[1]
3907         v_0 := v.Args[0]
3908         // match: (EONshiftRA x (MOVDconst [c]) [d])
3909         // result: (XORconst x [^(c>>uint64(d))])
3910         for {
3911                 d := auxIntToInt64(v.AuxInt)
3912                 x := v_0
3913                 if v_1.Op != OpARM64MOVDconst {
3914                         break
3915                 }
3916                 c := auxIntToInt64(v_1.AuxInt)
3917                 v.reset(OpARM64XORconst)
3918                 v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
3919                 v.AddArg(x)
3920                 return true
3921         }
3922         // match: (EONshiftRA (SRAconst x [c]) x [c])
3923         // result: (MOVDconst [-1])
3924         for {
3925                 c := auxIntToInt64(v.AuxInt)
3926                 if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
3927                         break
3928                 }
3929                 x := v_0.Args[0]
3930                 if x != v_1 {
3931                         break
3932                 }
3933                 v.reset(OpARM64MOVDconst)
3934                 v.AuxInt = int64ToAuxInt(-1)
3935                 return true
3936         }
3937         return false
3938 }
3939 func rewriteValueARM64_OpARM64EONshiftRL(v *Value) bool {
3940         v_1 := v.Args[1]
3941         v_0 := v.Args[0]
3942         // match: (EONshiftRL x (MOVDconst [c]) [d])
3943         // result: (XORconst x [^int64(uint64(c)>>uint64(d))])
3944         for {
3945                 d := auxIntToInt64(v.AuxInt)
3946                 x := v_0
3947                 if v_1.Op != OpARM64MOVDconst {
3948                         break
3949                 }
3950                 c := auxIntToInt64(v_1.AuxInt)
3951                 v.reset(OpARM64XORconst)
3952                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
3953                 v.AddArg(x)
3954                 return true
3955         }
3956         // match: (EONshiftRL (SRLconst x [c]) x [c])
3957         // result: (MOVDconst [-1])
3958         for {
3959                 c := auxIntToInt64(v.AuxInt)
3960                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
3961                         break
3962                 }
3963                 x := v_0.Args[0]
3964                 if x != v_1 {
3965                         break
3966                 }
3967                 v.reset(OpARM64MOVDconst)
3968                 v.AuxInt = int64ToAuxInt(-1)
3969                 return true
3970         }
3971         return false
3972 }
3973 func rewriteValueARM64_OpARM64EONshiftRO(v *Value) bool {
3974         v_1 := v.Args[1]
3975         v_0 := v.Args[0]
3976         // match: (EONshiftRO x (MOVDconst [c]) [d])
3977         // result: (XORconst x [^rotateRight64(c, d)])
3978         for {
3979                 d := auxIntToInt64(v.AuxInt)
3980                 x := v_0
3981                 if v_1.Op != OpARM64MOVDconst {
3982                         break
3983                 }
3984                 c := auxIntToInt64(v_1.AuxInt)
3985                 v.reset(OpARM64XORconst)
3986                 v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
3987                 v.AddArg(x)
3988                 return true
3989         }
3990         // match: (EONshiftRO (RORconst x [c]) x [c])
3991         // result: (MOVDconst [-1])
3992         for {
3993                 c := auxIntToInt64(v.AuxInt)
3994                 if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
3995                         break
3996                 }
3997                 x := v_0.Args[0]
3998                 if x != v_1 {
3999                         break
4000                 }
4001                 v.reset(OpARM64MOVDconst)
4002                 v.AuxInt = int64ToAuxInt(-1)
4003                 return true
4004         }
4005         return false
4006 }
4007 func rewriteValueARM64_OpARM64Equal(v *Value) bool {
4008         v_0 := v.Args[0]
4009         b := v.Block
4010         // match: (Equal (CMPconst [0] z:(AND x y)))
4011         // cond: z.Uses == 1
4012         // result: (Equal (TST x y))
4013         for {
4014                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
4015                         break
4016                 }
4017                 z := v_0.Args[0]
4018                 if z.Op != OpARM64AND {
4019                         break
4020                 }
4021                 y := z.Args[1]
4022                 x := z.Args[0]
4023                 if !(z.Uses == 1) {
4024                         break
4025                 }
4026                 v.reset(OpARM64Equal)
4027                 v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
4028                 v0.AddArg2(x, y)
4029                 v.AddArg(v0)
4030                 return true
4031         }
4032         // match: (Equal (CMPWconst [0] x:(ANDconst [c] y)))
4033         // cond: x.Uses == 1
4034         // result: (Equal (TSTWconst [int32(c)] y))
4035         for {
4036                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
4037                         break
4038                 }
4039                 x := v_0.Args[0]
4040                 if x.Op != OpARM64ANDconst {
4041                         break
4042                 }
4043                 c := auxIntToInt64(x.AuxInt)
4044                 y := x.Args[0]
4045                 if !(x.Uses == 1) {
4046                         break
4047                 }
4048                 v.reset(OpARM64Equal)
4049                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
4050                 v0.AuxInt = int32ToAuxInt(int32(c))
4051                 v0.AddArg(y)
4052                 v.AddArg(v0)
4053                 return true
4054         }
4055         // match: (Equal (CMPWconst [0] z:(AND x y)))
4056         // cond: z.Uses == 1
4057         // result: (Equal (TSTW x y))
4058         for {
4059                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
4060                         break
4061                 }
4062                 z := v_0.Args[0]
4063                 if z.Op != OpARM64AND {
4064                         break
4065                 }
4066                 y := z.Args[1]
4067                 x := z.Args[0]
4068                 if !(z.Uses == 1) {
4069                         break
4070                 }
4071                 v.reset(OpARM64Equal)
4072                 v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
4073                 v0.AddArg2(x, y)
4074                 v.AddArg(v0)
4075                 return true
4076         }
4077         // match: (Equal (CMPconst [0] x:(ANDconst [c] y)))
4078         // cond: x.Uses == 1
4079         // result: (Equal (TSTconst [c] y))
4080         for {
4081                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
4082                         break
4083                 }
4084                 x := v_0.Args[0]
4085                 if x.Op != OpARM64ANDconst {
4086                         break
4087                 }
4088                 c := auxIntToInt64(x.AuxInt)
4089                 y := x.Args[0]
4090                 if !(x.Uses == 1) {
4091                         break
4092                 }
4093                 v.reset(OpARM64Equal)
4094                 v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
4095                 v0.AuxInt = int64ToAuxInt(c)
4096                 v0.AddArg(y)
4097                 v.AddArg(v0)
4098                 return true
4099         }
4100         // match: (Equal (CMP x z:(NEG y)))
4101         // cond: z.Uses == 1
4102         // result: (Equal (CMN x y))
4103         for {
4104                 if v_0.Op != OpARM64CMP {
4105                         break
4106                 }
4107                 _ = v_0.Args[1]
4108                 x := v_0.Args[0]
4109                 z := v_0.Args[1]
4110                 if z.Op != OpARM64NEG {
4111                         break
4112                 }
4113                 y := z.Args[0]
4114                 if !(z.Uses == 1) {
4115                         break
4116                 }
4117                 v.reset(OpARM64Equal)
4118                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
4119                 v0.AddArg2(x, y)
4120                 v.AddArg(v0)
4121                 return true
4122         }
4123         // match: (Equal (CMPW x z:(NEG y)))
4124         // cond: z.Uses == 1
4125         // result: (Equal (CMNW x y))
4126         for {
4127                 if v_0.Op != OpARM64CMPW {
4128                         break
4129                 }
4130                 _ = v_0.Args[1]
4131                 x := v_0.Args[0]
4132                 z := v_0.Args[1]
4133                 if z.Op != OpARM64NEG {
4134                         break
4135                 }
4136                 y := z.Args[0]
4137                 if !(z.Uses == 1) {
4138                         break
4139                 }
4140                 v.reset(OpARM64Equal)
4141                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
4142                 v0.AddArg2(x, y)
4143                 v.AddArg(v0)
4144                 return true
4145         }
4146         // match: (Equal (CMPconst [0] x:(ADDconst [c] y)))
4147         // cond: x.Uses == 1
4148         // result: (Equal (CMNconst [c] y))
4149         for {
4150                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
4151                         break
4152                 }
4153                 x := v_0.Args[0]
4154                 if x.Op != OpARM64ADDconst {
4155                         break
4156                 }
4157                 c := auxIntToInt64(x.AuxInt)
4158                 y := x.Args[0]
4159                 if !(x.Uses == 1) {
4160                         break
4161                 }
4162                 v.reset(OpARM64Equal)
4163                 v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
4164                 v0.AuxInt = int64ToAuxInt(c)
4165                 v0.AddArg(y)
4166                 v.AddArg(v0)
4167                 return true
4168         }
4169         // match: (Equal (CMPWconst [0] x:(ADDconst [c] y)))
4170         // cond: x.Uses == 1
4171         // result: (Equal (CMNWconst [int32(c)] y))
4172         for {
4173                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
4174                         break
4175                 }
4176                 x := v_0.Args[0]
4177                 if x.Op != OpARM64ADDconst {
4178                         break
4179                 }
4180                 c := auxIntToInt64(x.AuxInt)
4181                 y := x.Args[0]
4182                 if !(x.Uses == 1) {
4183                         break
4184                 }
4185                 v.reset(OpARM64Equal)
4186                 v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
4187                 v0.AuxInt = int32ToAuxInt(int32(c))
4188                 v0.AddArg(y)
4189                 v.AddArg(v0)
4190                 return true
4191         }
4192         // match: (Equal (CMPconst [0] z:(ADD x y)))
4193         // cond: z.Uses == 1
4194         // result: (Equal (CMN x y))
4195         for {
4196                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
4197                         break
4198                 }
4199                 z := v_0.Args[0]
4200                 if z.Op != OpARM64ADD {
4201                         break
4202                 }
4203                 y := z.Args[1]
4204                 x := z.Args[0]
4205                 if !(z.Uses == 1) {
4206                         break
4207                 }
4208                 v.reset(OpARM64Equal)
4209                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
4210                 v0.AddArg2(x, y)
4211                 v.AddArg(v0)
4212                 return true
4213         }
4214         // match: (Equal (CMPWconst [0] z:(ADD x y)))
4215         // cond: z.Uses == 1
4216         // result: (Equal (CMNW x y))
4217         for {
4218                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
4219                         break
4220                 }
4221                 z := v_0.Args[0]
4222                 if z.Op != OpARM64ADD {
4223                         break
4224                 }
4225                 y := z.Args[1]
4226                 x := z.Args[0]
4227                 if !(z.Uses == 1) {
4228                         break
4229                 }
4230                 v.reset(OpARM64Equal)
4231                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
4232                 v0.AddArg2(x, y)
4233                 v.AddArg(v0)
4234                 return true
4235         }
4236         // match: (Equal (CMPconst [0] z:(MADD a x y)))
4237         // cond: z.Uses == 1
4238         // result: (Equal (CMN a (MUL <x.Type> x y)))
4239         for {
4240                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
4241                         break
4242                 }
4243                 z := v_0.Args[0]
4244                 if z.Op != OpARM64MADD {
4245                         break
4246                 }
4247                 y := z.Args[2]
4248                 a := z.Args[0]
4249                 x := z.Args[1]
4250                 if !(z.Uses == 1) {
4251                         break
4252                 }
4253                 v.reset(OpARM64Equal)
4254                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
4255                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
4256                 v1.AddArg2(x, y)
4257                 v0.AddArg2(a, v1)
4258                 v.AddArg(v0)
4259                 return true
4260         }
4261         // match: (Equal (CMPconst [0] z:(MSUB a x y)))
4262         // cond: z.Uses == 1
4263         // result: (Equal (CMP a (MUL <x.Type> x y)))
4264         for {
4265                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
4266                         break
4267                 }
4268                 z := v_0.Args[0]
4269                 if z.Op != OpARM64MSUB {
4270                         break
4271                 }
4272                 y := z.Args[2]
4273                 a := z.Args[0]
4274                 x := z.Args[1]
4275                 if !(z.Uses == 1) {
4276                         break
4277                 }
4278                 v.reset(OpARM64Equal)
4279                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
4280                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
4281                 v1.AddArg2(x, y)
4282                 v0.AddArg2(a, v1)
4283                 v.AddArg(v0)
4284                 return true
4285         }
4286         // match: (Equal (CMPWconst [0] z:(MADDW a x y)))
4287         // cond: z.Uses == 1
4288         // result: (Equal (CMNW a (MULW <x.Type> x y)))
4289         for {
4290                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
4291                         break
4292                 }
4293                 z := v_0.Args[0]
4294                 if z.Op != OpARM64MADDW {
4295                         break
4296                 }
4297                 y := z.Args[2]
4298                 a := z.Args[0]
4299                 x := z.Args[1]
4300                 if !(z.Uses == 1) {
4301                         break
4302                 }
4303                 v.reset(OpARM64Equal)
4304                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
4305                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
4306                 v1.AddArg2(x, y)
4307                 v0.AddArg2(a, v1)
4308                 v.AddArg(v0)
4309                 return true
4310         }
4311         // match: (Equal (CMPWconst [0] z:(MSUBW a x y)))
4312         // cond: z.Uses == 1
4313         // result: (Equal (CMPW a (MULW <x.Type> x y)))
4314         for {
4315                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
4316                         break
4317                 }
4318                 z := v_0.Args[0]
4319                 if z.Op != OpARM64MSUBW {
4320                         break
4321                 }
4322                 y := z.Args[2]
4323                 a := z.Args[0]
4324                 x := z.Args[1]
4325                 if !(z.Uses == 1) {
4326                         break
4327                 }
4328                 v.reset(OpARM64Equal)
4329                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
4330                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
4331                 v1.AddArg2(x, y)
4332                 v0.AddArg2(a, v1)
4333                 v.AddArg(v0)
4334                 return true
4335         }
4336         // match: (Equal (FlagConstant [fc]))
4337         // result: (MOVDconst [b2i(fc.eq())])
4338         for {
4339                 if v_0.Op != OpARM64FlagConstant {
4340                         break
4341                 }
4342                 fc := auxIntToFlagConstant(v_0.AuxInt)
4343                 v.reset(OpARM64MOVDconst)
4344                 v.AuxInt = int64ToAuxInt(b2i(fc.eq()))
4345                 return true
4346         }
4347         // match: (Equal (InvertFlags x))
4348         // result: (Equal x)
4349         for {
4350                 if v_0.Op != OpARM64InvertFlags {
4351                         break
4352                 }
4353                 x := v_0.Args[0]
4354                 v.reset(OpARM64Equal)
4355                 v.AddArg(x)
4356                 return true
4357         }
4358         return false
4359 }
4360 func rewriteValueARM64_OpARM64FADDD(v *Value) bool {
4361         v_1 := v.Args[1]
4362         v_0 := v.Args[0]
4363         // match: (FADDD a (FMULD x y))
4364         // cond: a.Block.Func.useFMA(v)
4365         // result: (FMADDD a x y)
4366         for {
4367                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
4368                         a := v_0
4369                         if v_1.Op != OpARM64FMULD {
4370                                 continue
4371                         }
4372                         y := v_1.Args[1]
4373                         x := v_1.Args[0]
4374                         if !(a.Block.Func.useFMA(v)) {
4375                                 continue
4376                         }
4377                         v.reset(OpARM64FMADDD)
4378                         v.AddArg3(a, x, y)
4379                         return true
4380                 }
4381                 break
4382         }
4383         // match: (FADDD a (FNMULD x y))
4384         // cond: a.Block.Func.useFMA(v)
4385         // result: (FMSUBD a x y)
4386         for {
4387                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
4388                         a := v_0
4389                         if v_1.Op != OpARM64FNMULD {
4390                                 continue
4391                         }
4392                         y := v_1.Args[1]
4393                         x := v_1.Args[0]
4394                         if !(a.Block.Func.useFMA(v)) {
4395                                 continue
4396                         }
4397                         v.reset(OpARM64FMSUBD)
4398                         v.AddArg3(a, x, y)
4399                         return true
4400                 }
4401                 break
4402         }
4403         return false
4404 }
4405 func rewriteValueARM64_OpARM64FADDS(v *Value) bool {
4406         v_1 := v.Args[1]
4407         v_0 := v.Args[0]
4408         // match: (FADDS a (FMULS x y))
4409         // cond: a.Block.Func.useFMA(v)
4410         // result: (FMADDS a x y)
4411         for {
4412                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
4413                         a := v_0
4414                         if v_1.Op != OpARM64FMULS {
4415                                 continue
4416                         }
4417                         y := v_1.Args[1]
4418                         x := v_1.Args[0]
4419                         if !(a.Block.Func.useFMA(v)) {
4420                                 continue
4421                         }
4422                         v.reset(OpARM64FMADDS)
4423                         v.AddArg3(a, x, y)
4424                         return true
4425                 }
4426                 break
4427         }
4428         // match: (FADDS a (FNMULS x y))
4429         // cond: a.Block.Func.useFMA(v)
4430         // result: (FMSUBS a x y)
4431         for {
4432                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
4433                         a := v_0
4434                         if v_1.Op != OpARM64FNMULS {
4435                                 continue
4436                         }
4437                         y := v_1.Args[1]
4438                         x := v_1.Args[0]
4439                         if !(a.Block.Func.useFMA(v)) {
4440                                 continue
4441                         }
4442                         v.reset(OpARM64FMSUBS)
4443                         v.AddArg3(a, x, y)
4444                         return true
4445                 }
4446                 break
4447         }
4448         return false
4449 }
4450 func rewriteValueARM64_OpARM64FCMPD(v *Value) bool {
4451         v_1 := v.Args[1]
4452         v_0 := v.Args[0]
4453         b := v.Block
4454         // match: (FCMPD x (FMOVDconst [0]))
4455         // result: (FCMPD0 x)
4456         for {
4457                 x := v_0
4458                 if v_1.Op != OpARM64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != 0 {
4459                         break
4460                 }
4461                 v.reset(OpARM64FCMPD0)
4462                 v.AddArg(x)
4463                 return true
4464         }
4465         // match: (FCMPD (FMOVDconst [0]) x)
4466         // result: (InvertFlags (FCMPD0 x))
4467         for {
4468                 if v_0.Op != OpARM64FMOVDconst || auxIntToFloat64(v_0.AuxInt) != 0 {
4469                         break
4470                 }
4471                 x := v_1
4472                 v.reset(OpARM64InvertFlags)
4473                 v0 := b.NewValue0(v.Pos, OpARM64FCMPD0, types.TypeFlags)
4474                 v0.AddArg(x)
4475                 v.AddArg(v0)
4476                 return true
4477         }
4478         return false
4479 }
4480 func rewriteValueARM64_OpARM64FCMPS(v *Value) bool {
4481         v_1 := v.Args[1]
4482         v_0 := v.Args[0]
4483         b := v.Block
4484         // match: (FCMPS x (FMOVSconst [0]))
4485         // result: (FCMPS0 x)
4486         for {
4487                 x := v_0
4488                 if v_1.Op != OpARM64FMOVSconst || auxIntToFloat64(v_1.AuxInt) != 0 {
4489                         break
4490                 }
4491                 v.reset(OpARM64FCMPS0)
4492                 v.AddArg(x)
4493                 return true
4494         }
4495         // match: (FCMPS (FMOVSconst [0]) x)
4496         // result: (InvertFlags (FCMPS0 x))
4497         for {
4498                 if v_0.Op != OpARM64FMOVSconst || auxIntToFloat64(v_0.AuxInt) != 0 {
4499                         break
4500                 }
4501                 x := v_1
4502                 v.reset(OpARM64InvertFlags)
4503                 v0 := b.NewValue0(v.Pos, OpARM64FCMPS0, types.TypeFlags)
4504                 v0.AddArg(x)
4505                 v.AddArg(v0)
4506                 return true
4507         }
4508         return false
4509 }
4510 func rewriteValueARM64_OpARM64FMOVDfpgp(v *Value) bool {
4511         v_0 := v.Args[0]
4512         b := v.Block
4513         // match: (FMOVDfpgp <t> (Arg [off] {sym}))
4514         // result: @b.Func.Entry (Arg <t> [off] {sym})
4515         for {
4516                 t := v.Type
4517                 if v_0.Op != OpArg {
4518                         break
4519                 }
4520                 off := auxIntToInt32(v_0.AuxInt)
4521                 sym := auxToSym(v_0.Aux)
4522                 b = b.Func.Entry
4523                 v0 := b.NewValue0(v.Pos, OpArg, t)
4524                 v.copyOf(v0)
4525                 v0.AuxInt = int32ToAuxInt(off)
4526                 v0.Aux = symToAux(sym)
4527                 return true
4528         }
4529         return false
4530 }
4531 func rewriteValueARM64_OpARM64FMOVDgpfp(v *Value) bool {
4532         v_0 := v.Args[0]
4533         b := v.Block
4534         // match: (FMOVDgpfp <t> (Arg [off] {sym}))
4535         // result: @b.Func.Entry (Arg <t> [off] {sym})
4536         for {
4537                 t := v.Type
4538                 if v_0.Op != OpArg {
4539                         break
4540                 }
4541                 off := auxIntToInt32(v_0.AuxInt)
4542                 sym := auxToSym(v_0.Aux)
4543                 b = b.Func.Entry
4544                 v0 := b.NewValue0(v.Pos, OpArg, t)
4545                 v.copyOf(v0)
4546                 v0.AuxInt = int32ToAuxInt(off)
4547                 v0.Aux = symToAux(sym)
4548                 return true
4549         }
4550         return false
4551 }
4552 func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
4553         v_1 := v.Args[1]
4554         v_0 := v.Args[0]
4555         b := v.Block
4556         config := b.Func.Config
4557         // match: (FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr val _))
4558         // result: (FMOVDgpfp val)
4559         for {
4560                 off := auxIntToInt32(v.AuxInt)
4561                 sym := auxToSym(v.Aux)
4562                 ptr := v_0
4563                 if v_1.Op != OpARM64MOVDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
4564                         break
4565                 }
4566                 val := v_1.Args[1]
4567                 if ptr != v_1.Args[0] {
4568                         break
4569                 }
4570                 v.reset(OpARM64FMOVDgpfp)
4571                 v.AddArg(val)
4572                 return true
4573         }
4574         // match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
4575         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
4576         // result: (FMOVDload [off1+int32(off2)] {sym} ptr mem)
4577         for {
4578                 off1 := auxIntToInt32(v.AuxInt)
4579                 sym := auxToSym(v.Aux)
4580                 if v_0.Op != OpARM64ADDconst {
4581                         break
4582                 }
4583                 off2 := auxIntToInt64(v_0.AuxInt)
4584                 ptr := v_0.Args[0]
4585                 mem := v_1
4586                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
4587                         break
4588                 }
4589                 v.reset(OpARM64FMOVDload)
4590                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
4591                 v.Aux = symToAux(sym)
4592                 v.AddArg2(ptr, mem)
4593                 return true
4594         }
4595         // match: (FMOVDload [off] {sym} (ADD ptr idx) mem)
4596         // cond: off == 0 && sym == nil
4597         // result: (FMOVDloadidx ptr idx mem)
4598         for {
4599                 off := auxIntToInt32(v.AuxInt)
4600                 sym := auxToSym(v.Aux)
4601                 if v_0.Op != OpARM64ADD {
4602                         break
4603                 }
4604                 idx := v_0.Args[1]
4605                 ptr := v_0.Args[0]
4606                 mem := v_1
4607                 if !(off == 0 && sym == nil) {
4608                         break
4609                 }
4610                 v.reset(OpARM64FMOVDloadidx)
4611                 v.AddArg3(ptr, idx, mem)
4612                 return true
4613         }
4614         // match: (FMOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem)
4615         // cond: off == 0 && sym == nil
4616         // result: (FMOVDloadidx8 ptr idx mem)
4617         for {
4618                 off := auxIntToInt32(v.AuxInt)
4619                 sym := auxToSym(v.Aux)
4620                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
4621                         break
4622                 }
4623                 idx := v_0.Args[1]
4624                 ptr := v_0.Args[0]
4625                 mem := v_1
4626                 if !(off == 0 && sym == nil) {
4627                         break
4628                 }
4629                 v.reset(OpARM64FMOVDloadidx8)
4630                 v.AddArg3(ptr, idx, mem)
4631                 return true
4632         }
4633         // match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
4634         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
4635         // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
4636         for {
4637                 off1 := auxIntToInt32(v.AuxInt)
4638                 sym1 := auxToSym(v.Aux)
4639                 if v_0.Op != OpARM64MOVDaddr {
4640                         break
4641                 }
4642                 off2 := auxIntToInt32(v_0.AuxInt)
4643                 sym2 := auxToSym(v_0.Aux)
4644                 ptr := v_0.Args[0]
4645                 mem := v_1
4646                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
4647                         break
4648                 }
4649                 v.reset(OpARM64FMOVDload)
4650                 v.AuxInt = int32ToAuxInt(off1 + off2)
4651                 v.Aux = symToAux(mergeSym(sym1, sym2))
4652                 v.AddArg2(ptr, mem)
4653                 return true
4654         }
4655         return false
4656 }
4657 func rewriteValueARM64_OpARM64FMOVDloadidx(v *Value) bool {
4658         v_2 := v.Args[2]
4659         v_1 := v.Args[1]
4660         v_0 := v.Args[0]
4661         // match: (FMOVDloadidx ptr (MOVDconst [c]) mem)
4662         // cond: is32Bit(c)
4663         // result: (FMOVDload [int32(c)] ptr mem)
4664         for {
4665                 ptr := v_0
4666                 if v_1.Op != OpARM64MOVDconst {
4667                         break
4668                 }
4669                 c := auxIntToInt64(v_1.AuxInt)
4670                 mem := v_2
4671                 if !(is32Bit(c)) {
4672                         break
4673                 }
4674                 v.reset(OpARM64FMOVDload)
4675                 v.AuxInt = int32ToAuxInt(int32(c))
4676                 v.AddArg2(ptr, mem)
4677                 return true
4678         }
4679         // match: (FMOVDloadidx (MOVDconst [c]) ptr mem)
4680         // cond: is32Bit(c)
4681         // result: (FMOVDload [int32(c)] ptr mem)
4682         for {
4683                 if v_0.Op != OpARM64MOVDconst {
4684                         break
4685                 }
4686                 c := auxIntToInt64(v_0.AuxInt)
4687                 ptr := v_1
4688                 mem := v_2
4689                 if !(is32Bit(c)) {
4690                         break
4691                 }
4692                 v.reset(OpARM64FMOVDload)
4693                 v.AuxInt = int32ToAuxInt(int32(c))
4694                 v.AddArg2(ptr, mem)
4695                 return true
4696         }
4697         // match: (FMOVDloadidx ptr (SLLconst [3] idx) mem)
4698         // result: (FMOVDloadidx8 ptr idx mem)
4699         for {
4700                 ptr := v_0
4701                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
4702                         break
4703                 }
4704                 idx := v_1.Args[0]
4705                 mem := v_2
4706                 v.reset(OpARM64FMOVDloadidx8)
4707                 v.AddArg3(ptr, idx, mem)
4708                 return true
4709         }
4710         // match: (FMOVDloadidx (SLLconst [3] idx) ptr mem)
4711         // result: (FMOVDloadidx8 ptr idx mem)
4712         for {
4713                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
4714                         break
4715                 }
4716                 idx := v_0.Args[0]
4717                 ptr := v_1
4718                 mem := v_2
4719                 v.reset(OpARM64FMOVDloadidx8)
4720                 v.AddArg3(ptr, idx, mem)
4721                 return true
4722         }
4723         return false
4724 }
4725 func rewriteValueARM64_OpARM64FMOVDloadidx8(v *Value) bool {
4726         v_2 := v.Args[2]
4727         v_1 := v.Args[1]
4728         v_0 := v.Args[0]
4729         // match: (FMOVDloadidx8 ptr (MOVDconst [c]) mem)
4730         // cond: is32Bit(c<<3)
4731         // result: (FMOVDload ptr [int32(c)<<3] mem)
4732         for {
4733                 ptr := v_0
4734                 if v_1.Op != OpARM64MOVDconst {
4735                         break
4736                 }
4737                 c := auxIntToInt64(v_1.AuxInt)
4738                 mem := v_2
4739                 if !(is32Bit(c << 3)) {
4740                         break
4741                 }
4742                 v.reset(OpARM64FMOVDload)
4743                 v.AuxInt = int32ToAuxInt(int32(c) << 3)
4744                 v.AddArg2(ptr, mem)
4745                 return true
4746         }
4747         return false
4748 }
4749 func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
4750         v_2 := v.Args[2]
4751         v_1 := v.Args[1]
4752         v_0 := v.Args[0]
4753         b := v.Block
4754         config := b.Func.Config
4755         // match: (FMOVDstore [off] {sym} ptr (FMOVDgpfp val) mem)
4756         // result: (MOVDstore [off] {sym} ptr val mem)
4757         for {
4758                 off := auxIntToInt32(v.AuxInt)
4759                 sym := auxToSym(v.Aux)
4760                 ptr := v_0
4761                 if v_1.Op != OpARM64FMOVDgpfp {
4762                         break
4763                 }
4764                 val := v_1.Args[0]
4765                 mem := v_2
4766                 v.reset(OpARM64MOVDstore)
4767                 v.AuxInt = int32ToAuxInt(off)
4768                 v.Aux = symToAux(sym)
4769                 v.AddArg3(ptr, val, mem)
4770                 return true
4771         }
4772         // match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
4773         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
4774         // result: (FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
4775         for {
4776                 off1 := auxIntToInt32(v.AuxInt)
4777                 sym := auxToSym(v.Aux)
4778                 if v_0.Op != OpARM64ADDconst {
4779                         break
4780                 }
4781                 off2 := auxIntToInt64(v_0.AuxInt)
4782                 ptr := v_0.Args[0]
4783                 val := v_1
4784                 mem := v_2
4785                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
4786                         break
4787                 }
4788                 v.reset(OpARM64FMOVDstore)
4789                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
4790                 v.Aux = symToAux(sym)
4791                 v.AddArg3(ptr, val, mem)
4792                 return true
4793         }
4794         // match: (FMOVDstore [off] {sym} (ADD ptr idx) val mem)
4795         // cond: off == 0 && sym == nil
4796         // result: (FMOVDstoreidx ptr idx val mem)
4797         for {
4798                 off := auxIntToInt32(v.AuxInt)
4799                 sym := auxToSym(v.Aux)
4800                 if v_0.Op != OpARM64ADD {
4801                         break
4802                 }
4803                 idx := v_0.Args[1]
4804                 ptr := v_0.Args[0]
4805                 val := v_1
4806                 mem := v_2
4807                 if !(off == 0 && sym == nil) {
4808                         break
4809                 }
4810                 v.reset(OpARM64FMOVDstoreidx)
4811                 v.AddArg4(ptr, idx, val, mem)
4812                 return true
4813         }
4814         // match: (FMOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem)
4815         // cond: off == 0 && sym == nil
4816         // result: (FMOVDstoreidx8 ptr idx val mem)
4817         for {
4818                 off := auxIntToInt32(v.AuxInt)
4819                 sym := auxToSym(v.Aux)
4820                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
4821                         break
4822                 }
4823                 idx := v_0.Args[1]
4824                 ptr := v_0.Args[0]
4825                 val := v_1
4826                 mem := v_2
4827                 if !(off == 0 && sym == nil) {
4828                         break
4829                 }
4830                 v.reset(OpARM64FMOVDstoreidx8)
4831                 v.AddArg4(ptr, idx, val, mem)
4832                 return true
4833         }
4834         // match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
4835         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
4836         // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
4837         for {
4838                 off1 := auxIntToInt32(v.AuxInt)
4839                 sym1 := auxToSym(v.Aux)
4840                 if v_0.Op != OpARM64MOVDaddr {
4841                         break
4842                 }
4843                 off2 := auxIntToInt32(v_0.AuxInt)
4844                 sym2 := auxToSym(v_0.Aux)
4845                 ptr := v_0.Args[0]
4846                 val := v_1
4847                 mem := v_2
4848                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
4849                         break
4850                 }
4851                 v.reset(OpARM64FMOVDstore)
4852                 v.AuxInt = int32ToAuxInt(off1 + off2)
4853                 v.Aux = symToAux(mergeSym(sym1, sym2))
4854                 v.AddArg3(ptr, val, mem)
4855                 return true
4856         }
4857         return false
4858 }
4859 func rewriteValueARM64_OpARM64FMOVDstoreidx(v *Value) bool {
4860         v_3 := v.Args[3]
4861         v_2 := v.Args[2]
4862         v_1 := v.Args[1]
4863         v_0 := v.Args[0]
4864         // match: (FMOVDstoreidx ptr (MOVDconst [c]) val mem)
4865         // cond: is32Bit(c)
4866         // result: (FMOVDstore [int32(c)] ptr val mem)
4867         for {
4868                 ptr := v_0
4869                 if v_1.Op != OpARM64MOVDconst {
4870                         break
4871                 }
4872                 c := auxIntToInt64(v_1.AuxInt)
4873                 val := v_2
4874                 mem := v_3
4875                 if !(is32Bit(c)) {
4876                         break
4877                 }
4878                 v.reset(OpARM64FMOVDstore)
4879                 v.AuxInt = int32ToAuxInt(int32(c))
4880                 v.AddArg3(ptr, val, mem)
4881                 return true
4882         }
4883         // match: (FMOVDstoreidx (MOVDconst [c]) idx val mem)
4884         // cond: is32Bit(c)
4885         // result: (FMOVDstore [int32(c)] idx val mem)
4886         for {
4887                 if v_0.Op != OpARM64MOVDconst {
4888                         break
4889                 }
4890                 c := auxIntToInt64(v_0.AuxInt)
4891                 idx := v_1
4892                 val := v_2
4893                 mem := v_3
4894                 if !(is32Bit(c)) {
4895                         break
4896                 }
4897                 v.reset(OpARM64FMOVDstore)
4898                 v.AuxInt = int32ToAuxInt(int32(c))
4899                 v.AddArg3(idx, val, mem)
4900                 return true
4901         }
4902         // match: (FMOVDstoreidx ptr (SLLconst [3] idx) val mem)
4903         // result: (FMOVDstoreidx8 ptr idx val mem)
4904         for {
4905                 ptr := v_0
4906                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
4907                         break
4908                 }
4909                 idx := v_1.Args[0]
4910                 val := v_2
4911                 mem := v_3
4912                 v.reset(OpARM64FMOVDstoreidx8)
4913                 v.AddArg4(ptr, idx, val, mem)
4914                 return true
4915         }
4916         // match: (FMOVDstoreidx (SLLconst [3] idx) ptr val mem)
4917         // result: (FMOVDstoreidx8 ptr idx val mem)
4918         for {
4919                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
4920                         break
4921                 }
4922                 idx := v_0.Args[0]
4923                 ptr := v_1
4924                 val := v_2
4925                 mem := v_3
4926                 v.reset(OpARM64FMOVDstoreidx8)
4927                 v.AddArg4(ptr, idx, val, mem)
4928                 return true
4929         }
4930         return false
4931 }
4932 func rewriteValueARM64_OpARM64FMOVDstoreidx8(v *Value) bool {
4933         v_3 := v.Args[3]
4934         v_2 := v.Args[2]
4935         v_1 := v.Args[1]
4936         v_0 := v.Args[0]
4937         // match: (FMOVDstoreidx8 ptr (MOVDconst [c]) val mem)
4938         // cond: is32Bit(c<<3)
4939         // result: (FMOVDstore [int32(c)<<3] ptr val mem)
4940         for {
4941                 ptr := v_0
4942                 if v_1.Op != OpARM64MOVDconst {
4943                         break
4944                 }
4945                 c := auxIntToInt64(v_1.AuxInt)
4946                 val := v_2
4947                 mem := v_3
4948                 if !(is32Bit(c << 3)) {
4949                         break
4950                 }
4951                 v.reset(OpARM64FMOVDstore)
4952                 v.AuxInt = int32ToAuxInt(int32(c) << 3)
4953                 v.AddArg3(ptr, val, mem)
4954                 return true
4955         }
4956         return false
4957 }
4958 func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
4959         v_1 := v.Args[1]
4960         v_0 := v.Args[0]
4961         b := v.Block
4962         config := b.Func.Config
4963         // match: (FMOVSload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _))
4964         // result: (FMOVSgpfp val)
4965         for {
4966                 off := auxIntToInt32(v.AuxInt)
4967                 sym := auxToSym(v.Aux)
4968                 ptr := v_0
4969                 if v_1.Op != OpARM64MOVWstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
4970                         break
4971                 }
4972                 val := v_1.Args[1]
4973                 if ptr != v_1.Args[0] {
4974                         break
4975                 }
4976                 v.reset(OpARM64FMOVSgpfp)
4977                 v.AddArg(val)
4978                 return true
4979         }
4980         // match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
4981         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
4982         // result: (FMOVSload [off1+int32(off2)] {sym} ptr mem)
4983         for {
4984                 off1 := auxIntToInt32(v.AuxInt)
4985                 sym := auxToSym(v.Aux)
4986                 if v_0.Op != OpARM64ADDconst {
4987                         break
4988                 }
4989                 off2 := auxIntToInt64(v_0.AuxInt)
4990                 ptr := v_0.Args[0]
4991                 mem := v_1
4992                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
4993                         break
4994                 }
4995                 v.reset(OpARM64FMOVSload)
4996                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
4997                 v.Aux = symToAux(sym)
4998                 v.AddArg2(ptr, mem)
4999                 return true
5000         }
5001         // match: (FMOVSload [off] {sym} (ADD ptr idx) mem)
5002         // cond: off == 0 && sym == nil
5003         // result: (FMOVSloadidx ptr idx mem)
5004         for {
5005                 off := auxIntToInt32(v.AuxInt)
5006                 sym := auxToSym(v.Aux)
5007                 if v_0.Op != OpARM64ADD {
5008                         break
5009                 }
5010                 idx := v_0.Args[1]
5011                 ptr := v_0.Args[0]
5012                 mem := v_1
5013                 if !(off == 0 && sym == nil) {
5014                         break
5015                 }
5016                 v.reset(OpARM64FMOVSloadidx)
5017                 v.AddArg3(ptr, idx, mem)
5018                 return true
5019         }
5020         // match: (FMOVSload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
5021         // cond: off == 0 && sym == nil
5022         // result: (FMOVSloadidx4 ptr idx mem)
5023         for {
5024                 off := auxIntToInt32(v.AuxInt)
5025                 sym := auxToSym(v.Aux)
5026                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
5027                         break
5028                 }
5029                 idx := v_0.Args[1]
5030                 ptr := v_0.Args[0]
5031                 mem := v_1
5032                 if !(off == 0 && sym == nil) {
5033                         break
5034                 }
5035                 v.reset(OpARM64FMOVSloadidx4)
5036                 v.AddArg3(ptr, idx, mem)
5037                 return true
5038         }
5039         // match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
5040         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
5041         // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
5042         for {
5043                 off1 := auxIntToInt32(v.AuxInt)
5044                 sym1 := auxToSym(v.Aux)
5045                 if v_0.Op != OpARM64MOVDaddr {
5046                         break
5047                 }
5048                 off2 := auxIntToInt32(v_0.AuxInt)
5049                 sym2 := auxToSym(v_0.Aux)
5050                 ptr := v_0.Args[0]
5051                 mem := v_1
5052                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
5053                         break
5054                 }
5055                 v.reset(OpARM64FMOVSload)
5056                 v.AuxInt = int32ToAuxInt(off1 + off2)
5057                 v.Aux = symToAux(mergeSym(sym1, sym2))
5058                 v.AddArg2(ptr, mem)
5059                 return true
5060         }
5061         return false
5062 }
5063 func rewriteValueARM64_OpARM64FMOVSloadidx(v *Value) bool {
5064         v_2 := v.Args[2]
5065         v_1 := v.Args[1]
5066         v_0 := v.Args[0]
5067         // match: (FMOVSloadidx ptr (MOVDconst [c]) mem)
5068         // cond: is32Bit(c)
5069         // result: (FMOVSload [int32(c)] ptr mem)
5070         for {
5071                 ptr := v_0
5072                 if v_1.Op != OpARM64MOVDconst {
5073                         break
5074                 }
5075                 c := auxIntToInt64(v_1.AuxInt)
5076                 mem := v_2
5077                 if !(is32Bit(c)) {
5078                         break
5079                 }
5080                 v.reset(OpARM64FMOVSload)
5081                 v.AuxInt = int32ToAuxInt(int32(c))
5082                 v.AddArg2(ptr, mem)
5083                 return true
5084         }
5085         // match: (FMOVSloadidx (MOVDconst [c]) ptr mem)
5086         // cond: is32Bit(c)
5087         // result: (FMOVSload [int32(c)] ptr mem)
5088         for {
5089                 if v_0.Op != OpARM64MOVDconst {
5090                         break
5091                 }
5092                 c := auxIntToInt64(v_0.AuxInt)
5093                 ptr := v_1
5094                 mem := v_2
5095                 if !(is32Bit(c)) {
5096                         break
5097                 }
5098                 v.reset(OpARM64FMOVSload)
5099                 v.AuxInt = int32ToAuxInt(int32(c))
5100                 v.AddArg2(ptr, mem)
5101                 return true
5102         }
5103         // match: (FMOVSloadidx ptr (SLLconst [2] idx) mem)
5104         // result: (FMOVSloadidx4 ptr idx mem)
5105         for {
5106                 ptr := v_0
5107                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
5108                         break
5109                 }
5110                 idx := v_1.Args[0]
5111                 mem := v_2
5112                 v.reset(OpARM64FMOVSloadidx4)
5113                 v.AddArg3(ptr, idx, mem)
5114                 return true
5115         }
5116         // match: (FMOVSloadidx (SLLconst [2] idx) ptr mem)
5117         // result: (FMOVSloadidx4 ptr idx mem)
5118         for {
5119                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
5120                         break
5121                 }
5122                 idx := v_0.Args[0]
5123                 ptr := v_1
5124                 mem := v_2
5125                 v.reset(OpARM64FMOVSloadidx4)
5126                 v.AddArg3(ptr, idx, mem)
5127                 return true
5128         }
5129         return false
5130 }
5131 func rewriteValueARM64_OpARM64FMOVSloadidx4(v *Value) bool {
5132         v_2 := v.Args[2]
5133         v_1 := v.Args[1]
5134         v_0 := v.Args[0]
5135         // match: (FMOVSloadidx4 ptr (MOVDconst [c]) mem)
5136         // cond: is32Bit(c<<2)
5137         // result: (FMOVSload ptr [int32(c)<<2] mem)
5138         for {
5139                 ptr := v_0
5140                 if v_1.Op != OpARM64MOVDconst {
5141                         break
5142                 }
5143                 c := auxIntToInt64(v_1.AuxInt)
5144                 mem := v_2
5145                 if !(is32Bit(c << 2)) {
5146                         break
5147                 }
5148                 v.reset(OpARM64FMOVSload)
5149                 v.AuxInt = int32ToAuxInt(int32(c) << 2)
5150                 v.AddArg2(ptr, mem)
5151                 return true
5152         }
5153         return false
5154 }
5155 func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
5156         v_2 := v.Args[2]
5157         v_1 := v.Args[1]
5158         v_0 := v.Args[0]
5159         b := v.Block
5160         config := b.Func.Config
5161         // match: (FMOVSstore [off] {sym} ptr (FMOVSgpfp val) mem)
5162         // result: (MOVWstore [off] {sym} ptr val mem)
5163         for {
5164                 off := auxIntToInt32(v.AuxInt)
5165                 sym := auxToSym(v.Aux)
5166                 ptr := v_0
5167                 if v_1.Op != OpARM64FMOVSgpfp {
5168                         break
5169                 }
5170                 val := v_1.Args[0]
5171                 mem := v_2
5172                 v.reset(OpARM64MOVWstore)
5173                 v.AuxInt = int32ToAuxInt(off)
5174                 v.Aux = symToAux(sym)
5175                 v.AddArg3(ptr, val, mem)
5176                 return true
5177         }
5178         // match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
5179         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
5180         // result: (FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
5181         for {
5182                 off1 := auxIntToInt32(v.AuxInt)
5183                 sym := auxToSym(v.Aux)
5184                 if v_0.Op != OpARM64ADDconst {
5185                         break
5186                 }
5187                 off2 := auxIntToInt64(v_0.AuxInt)
5188                 ptr := v_0.Args[0]
5189                 val := v_1
5190                 mem := v_2
5191                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
5192                         break
5193                 }
5194                 v.reset(OpARM64FMOVSstore)
5195                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
5196                 v.Aux = symToAux(sym)
5197                 v.AddArg3(ptr, val, mem)
5198                 return true
5199         }
5200         // match: (FMOVSstore [off] {sym} (ADD ptr idx) val mem)
5201         // cond: off == 0 && sym == nil
5202         // result: (FMOVSstoreidx ptr idx val mem)
5203         for {
5204                 off := auxIntToInt32(v.AuxInt)
5205                 sym := auxToSym(v.Aux)
5206                 if v_0.Op != OpARM64ADD {
5207                         break
5208                 }
5209                 idx := v_0.Args[1]
5210                 ptr := v_0.Args[0]
5211                 val := v_1
5212                 mem := v_2
5213                 if !(off == 0 && sym == nil) {
5214                         break
5215                 }
5216                 v.reset(OpARM64FMOVSstoreidx)
5217                 v.AddArg4(ptr, idx, val, mem)
5218                 return true
5219         }
5220         // match: (FMOVSstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem)
5221         // cond: off == 0 && sym == nil
5222         // result: (FMOVSstoreidx4 ptr idx val mem)
5223         for {
5224                 off := auxIntToInt32(v.AuxInt)
5225                 sym := auxToSym(v.Aux)
5226                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
5227                         break
5228                 }
5229                 idx := v_0.Args[1]
5230                 ptr := v_0.Args[0]
5231                 val := v_1
5232                 mem := v_2
5233                 if !(off == 0 && sym == nil) {
5234                         break
5235                 }
5236                 v.reset(OpARM64FMOVSstoreidx4)
5237                 v.AddArg4(ptr, idx, val, mem)
5238                 return true
5239         }
5240         // match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
5241         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
5242         // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
5243         for {
5244                 off1 := auxIntToInt32(v.AuxInt)
5245                 sym1 := auxToSym(v.Aux)
5246                 if v_0.Op != OpARM64MOVDaddr {
5247                         break
5248                 }
5249                 off2 := auxIntToInt32(v_0.AuxInt)
5250                 sym2 := auxToSym(v_0.Aux)
5251                 ptr := v_0.Args[0]
5252                 val := v_1
5253                 mem := v_2
5254                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
5255                         break
5256                 }
5257                 v.reset(OpARM64FMOVSstore)
5258                 v.AuxInt = int32ToAuxInt(off1 + off2)
5259                 v.Aux = symToAux(mergeSym(sym1, sym2))
5260                 v.AddArg3(ptr, val, mem)
5261                 return true
5262         }
5263         return false
5264 }
5265 func rewriteValueARM64_OpARM64FMOVSstoreidx(v *Value) bool {
5266         v_3 := v.Args[3]
5267         v_2 := v.Args[2]
5268         v_1 := v.Args[1]
5269         v_0 := v.Args[0]
5270         // match: (FMOVSstoreidx ptr (MOVDconst [c]) val mem)
5271         // cond: is32Bit(c)
5272         // result: (FMOVSstore [int32(c)] ptr val mem)
5273         for {
5274                 ptr := v_0
5275                 if v_1.Op != OpARM64MOVDconst {
5276                         break
5277                 }
5278                 c := auxIntToInt64(v_1.AuxInt)
5279                 val := v_2
5280                 mem := v_3
5281                 if !(is32Bit(c)) {
5282                         break
5283                 }
5284                 v.reset(OpARM64FMOVSstore)
5285                 v.AuxInt = int32ToAuxInt(int32(c))
5286                 v.AddArg3(ptr, val, mem)
5287                 return true
5288         }
5289         // match: (FMOVSstoreidx (MOVDconst [c]) idx val mem)
5290         // cond: is32Bit(c)
5291         // result: (FMOVSstore [int32(c)] idx val mem)
5292         for {
5293                 if v_0.Op != OpARM64MOVDconst {
5294                         break
5295                 }
5296                 c := auxIntToInt64(v_0.AuxInt)
5297                 idx := v_1
5298                 val := v_2
5299                 mem := v_3
5300                 if !(is32Bit(c)) {
5301                         break
5302                 }
5303                 v.reset(OpARM64FMOVSstore)
5304                 v.AuxInt = int32ToAuxInt(int32(c))
5305                 v.AddArg3(idx, val, mem)
5306                 return true
5307         }
5308         // match: (FMOVSstoreidx ptr (SLLconst [2] idx) val mem)
5309         // result: (FMOVSstoreidx4 ptr idx val mem)
5310         for {
5311                 ptr := v_0
5312                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
5313                         break
5314                 }
5315                 idx := v_1.Args[0]
5316                 val := v_2
5317                 mem := v_3
5318                 v.reset(OpARM64FMOVSstoreidx4)
5319                 v.AddArg4(ptr, idx, val, mem)
5320                 return true
5321         }
5322         // match: (FMOVSstoreidx (SLLconst [2] idx) ptr val mem)
5323         // result: (FMOVSstoreidx4 ptr idx val mem)
5324         for {
5325                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
5326                         break
5327                 }
5328                 idx := v_0.Args[0]
5329                 ptr := v_1
5330                 val := v_2
5331                 mem := v_3
5332                 v.reset(OpARM64FMOVSstoreidx4)
5333                 v.AddArg4(ptr, idx, val, mem)
5334                 return true
5335         }
5336         return false
5337 }
5338 func rewriteValueARM64_OpARM64FMOVSstoreidx4(v *Value) bool {
5339         v_3 := v.Args[3]
5340         v_2 := v.Args[2]
5341         v_1 := v.Args[1]
5342         v_0 := v.Args[0]
5343         // match: (FMOVSstoreidx4 ptr (MOVDconst [c]) val mem)
5344         // cond: is32Bit(c<<2)
5345         // result: (FMOVSstore [int32(c)<<2] ptr val mem)
5346         for {
5347                 ptr := v_0
5348                 if v_1.Op != OpARM64MOVDconst {
5349                         break
5350                 }
5351                 c := auxIntToInt64(v_1.AuxInt)
5352                 val := v_2
5353                 mem := v_3
5354                 if !(is32Bit(c << 2)) {
5355                         break
5356                 }
5357                 v.reset(OpARM64FMOVSstore)
5358                 v.AuxInt = int32ToAuxInt(int32(c) << 2)
5359                 v.AddArg3(ptr, val, mem)
5360                 return true
5361         }
5362         return false
5363 }
5364 func rewriteValueARM64_OpARM64FMULD(v *Value) bool {
5365         v_1 := v.Args[1]
5366         v_0 := v.Args[0]
5367         // match: (FMULD (FNEGD x) y)
5368         // result: (FNMULD x y)
5369         for {
5370                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
5371                         if v_0.Op != OpARM64FNEGD {
5372                                 continue
5373                         }
5374                         x := v_0.Args[0]
5375                         y := v_1
5376                         v.reset(OpARM64FNMULD)
5377                         v.AddArg2(x, y)
5378                         return true
5379                 }
5380                 break
5381         }
5382         return false
5383 }
5384 func rewriteValueARM64_OpARM64FMULS(v *Value) bool {
5385         v_1 := v.Args[1]
5386         v_0 := v.Args[0]
5387         // match: (FMULS (FNEGS x) y)
5388         // result: (FNMULS x y)
5389         for {
5390                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
5391                         if v_0.Op != OpARM64FNEGS {
5392                                 continue
5393                         }
5394                         x := v_0.Args[0]
5395                         y := v_1
5396                         v.reset(OpARM64FNMULS)
5397                         v.AddArg2(x, y)
5398                         return true
5399                 }
5400                 break
5401         }
5402         return false
5403 }
5404 func rewriteValueARM64_OpARM64FNEGD(v *Value) bool {
5405         v_0 := v.Args[0]
5406         // match: (FNEGD (FMULD x y))
5407         // result: (FNMULD x y)
5408         for {
5409                 if v_0.Op != OpARM64FMULD {
5410                         break
5411                 }
5412                 y := v_0.Args[1]
5413                 x := v_0.Args[0]
5414                 v.reset(OpARM64FNMULD)
5415                 v.AddArg2(x, y)
5416                 return true
5417         }
5418         // match: (FNEGD (FNMULD x y))
5419         // result: (FMULD x y)
5420         for {
5421                 if v_0.Op != OpARM64FNMULD {
5422                         break
5423                 }
5424                 y := v_0.Args[1]
5425                 x := v_0.Args[0]
5426                 v.reset(OpARM64FMULD)
5427                 v.AddArg2(x, y)
5428                 return true
5429         }
5430         return false
5431 }
5432 func rewriteValueARM64_OpARM64FNEGS(v *Value) bool {
5433         v_0 := v.Args[0]
5434         // match: (FNEGS (FMULS x y))
5435         // result: (FNMULS x y)
5436         for {
5437                 if v_0.Op != OpARM64FMULS {
5438                         break
5439                 }
5440                 y := v_0.Args[1]
5441                 x := v_0.Args[0]
5442                 v.reset(OpARM64FNMULS)
5443                 v.AddArg2(x, y)
5444                 return true
5445         }
5446         // match: (FNEGS (FNMULS x y))
5447         // result: (FMULS x y)
5448         for {
5449                 if v_0.Op != OpARM64FNMULS {
5450                         break
5451                 }
5452                 y := v_0.Args[1]
5453                 x := v_0.Args[0]
5454                 v.reset(OpARM64FMULS)
5455                 v.AddArg2(x, y)
5456                 return true
5457         }
5458         return false
5459 }
5460 func rewriteValueARM64_OpARM64FNMULD(v *Value) bool {
5461         v_1 := v.Args[1]
5462         v_0 := v.Args[0]
5463         // match: (FNMULD (FNEGD x) y)
5464         // result: (FMULD x y)
5465         for {
5466                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
5467                         if v_0.Op != OpARM64FNEGD {
5468                                 continue
5469                         }
5470                         x := v_0.Args[0]
5471                         y := v_1
5472                         v.reset(OpARM64FMULD)
5473                         v.AddArg2(x, y)
5474                         return true
5475                 }
5476                 break
5477         }
5478         return false
5479 }
5480 func rewriteValueARM64_OpARM64FNMULS(v *Value) bool {
5481         v_1 := v.Args[1]
5482         v_0 := v.Args[0]
5483         // match: (FNMULS (FNEGS x) y)
5484         // result: (FMULS x y)
5485         for {
5486                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
5487                         if v_0.Op != OpARM64FNEGS {
5488                                 continue
5489                         }
5490                         x := v_0.Args[0]
5491                         y := v_1
5492                         v.reset(OpARM64FMULS)
5493                         v.AddArg2(x, y)
5494                         return true
5495                 }
5496                 break
5497         }
5498         return false
5499 }
5500 func rewriteValueARM64_OpARM64FSUBD(v *Value) bool {
5501         v_1 := v.Args[1]
5502         v_0 := v.Args[0]
5503         // match: (FSUBD a (FMULD x y))
5504         // cond: a.Block.Func.useFMA(v)
5505         // result: (FMSUBD a x y)
5506         for {
5507                 a := v_0
5508                 if v_1.Op != OpARM64FMULD {
5509                         break
5510                 }
5511                 y := v_1.Args[1]
5512                 x := v_1.Args[0]
5513                 if !(a.Block.Func.useFMA(v)) {
5514                         break
5515                 }
5516                 v.reset(OpARM64FMSUBD)
5517                 v.AddArg3(a, x, y)
5518                 return true
5519         }
5520         // match: (FSUBD (FMULD x y) a)
5521         // cond: a.Block.Func.useFMA(v)
5522         // result: (FNMSUBD a x y)
5523         for {
5524                 if v_0.Op != OpARM64FMULD {
5525                         break
5526                 }
5527                 y := v_0.Args[1]
5528                 x := v_0.Args[0]
5529                 a := v_1
5530                 if !(a.Block.Func.useFMA(v)) {
5531                         break
5532                 }
5533                 v.reset(OpARM64FNMSUBD)
5534                 v.AddArg3(a, x, y)
5535                 return true
5536         }
5537         // match: (FSUBD a (FNMULD x y))
5538         // cond: a.Block.Func.useFMA(v)
5539         // result: (FMADDD a x y)
5540         for {
5541                 a := v_0
5542                 if v_1.Op != OpARM64FNMULD {
5543                         break
5544                 }
5545                 y := v_1.Args[1]
5546                 x := v_1.Args[0]
5547                 if !(a.Block.Func.useFMA(v)) {
5548                         break
5549                 }
5550                 v.reset(OpARM64FMADDD)
5551                 v.AddArg3(a, x, y)
5552                 return true
5553         }
5554         // match: (FSUBD (FNMULD x y) a)
5555         // cond: a.Block.Func.useFMA(v)
5556         // result: (FNMADDD a x y)
5557         for {
5558                 if v_0.Op != OpARM64FNMULD {
5559                         break
5560                 }
5561                 y := v_0.Args[1]
5562                 x := v_0.Args[0]
5563                 a := v_1
5564                 if !(a.Block.Func.useFMA(v)) {
5565                         break
5566                 }
5567                 v.reset(OpARM64FNMADDD)
5568                 v.AddArg3(a, x, y)
5569                 return true
5570         }
5571         return false
5572 }
5573 func rewriteValueARM64_OpARM64FSUBS(v *Value) bool {
5574         v_1 := v.Args[1]
5575         v_0 := v.Args[0]
5576         // match: (FSUBS a (FMULS x y))
5577         // cond: a.Block.Func.useFMA(v)
5578         // result: (FMSUBS a x y)
5579         for {
5580                 a := v_0
5581                 if v_1.Op != OpARM64FMULS {
5582                         break
5583                 }
5584                 y := v_1.Args[1]
5585                 x := v_1.Args[0]
5586                 if !(a.Block.Func.useFMA(v)) {
5587                         break
5588                 }
5589                 v.reset(OpARM64FMSUBS)
5590                 v.AddArg3(a, x, y)
5591                 return true
5592         }
5593         // match: (FSUBS (FMULS x y) a)
5594         // cond: a.Block.Func.useFMA(v)
5595         // result: (FNMSUBS a x y)
5596         for {
5597                 if v_0.Op != OpARM64FMULS {
5598                         break
5599                 }
5600                 y := v_0.Args[1]
5601                 x := v_0.Args[0]
5602                 a := v_1
5603                 if !(a.Block.Func.useFMA(v)) {
5604                         break
5605                 }
5606                 v.reset(OpARM64FNMSUBS)
5607                 v.AddArg3(a, x, y)
5608                 return true
5609         }
5610         // match: (FSUBS a (FNMULS x y))
5611         // cond: a.Block.Func.useFMA(v)
5612         // result: (FMADDS a x y)
5613         for {
5614                 a := v_0
5615                 if v_1.Op != OpARM64FNMULS {
5616                         break
5617                 }
5618                 y := v_1.Args[1]
5619                 x := v_1.Args[0]
5620                 if !(a.Block.Func.useFMA(v)) {
5621                         break
5622                 }
5623                 v.reset(OpARM64FMADDS)
5624                 v.AddArg3(a, x, y)
5625                 return true
5626         }
5627         // match: (FSUBS (FNMULS x y) a)
5628         // cond: a.Block.Func.useFMA(v)
5629         // result: (FNMADDS a x y)
5630         for {
5631                 if v_0.Op != OpARM64FNMULS {
5632                         break
5633                 }
5634                 y := v_0.Args[1]
5635                 x := v_0.Args[0]
5636                 a := v_1
5637                 if !(a.Block.Func.useFMA(v)) {
5638                         break
5639                 }
5640                 v.reset(OpARM64FNMADDS)
5641                 v.AddArg3(a, x, y)
5642                 return true
5643         }
5644         return false
5645 }
5646 func rewriteValueARM64_OpARM64GreaterEqual(v *Value) bool {
5647         v_0 := v.Args[0]
5648         b := v.Block
5649         // match: (GreaterEqual (CMPconst [0] z:(AND x y)))
5650         // cond: z.Uses == 1
5651         // result: (GreaterEqual (TST x y))
5652         for {
5653                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
5654                         break
5655                 }
5656                 z := v_0.Args[0]
5657                 if z.Op != OpARM64AND {
5658                         break
5659                 }
5660                 y := z.Args[1]
5661                 x := z.Args[0]
5662                 if !(z.Uses == 1) {
5663                         break
5664                 }
5665                 v.reset(OpARM64GreaterEqual)
5666                 v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
5667                 v0.AddArg2(x, y)
5668                 v.AddArg(v0)
5669                 return true
5670         }
5671         // match: (GreaterEqual (CMPWconst [0] x:(ANDconst [c] y)))
5672         // cond: x.Uses == 1
5673         // result: (GreaterEqual (TSTWconst [int32(c)] y))
5674         for {
5675                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
5676                         break
5677                 }
5678                 x := v_0.Args[0]
5679                 if x.Op != OpARM64ANDconst {
5680                         break
5681                 }
5682                 c := auxIntToInt64(x.AuxInt)
5683                 y := x.Args[0]
5684                 if !(x.Uses == 1) {
5685                         break
5686                 }
5687                 v.reset(OpARM64GreaterEqual)
5688                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
5689                 v0.AuxInt = int32ToAuxInt(int32(c))
5690                 v0.AddArg(y)
5691                 v.AddArg(v0)
5692                 return true
5693         }
5694         // match: (GreaterEqual (CMPWconst [0] z:(AND x y)))
5695         // cond: z.Uses == 1
5696         // result: (GreaterEqual (TSTW x y))
5697         for {
5698                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
5699                         break
5700                 }
5701                 z := v_0.Args[0]
5702                 if z.Op != OpARM64AND {
5703                         break
5704                 }
5705                 y := z.Args[1]
5706                 x := z.Args[0]
5707                 if !(z.Uses == 1) {
5708                         break
5709                 }
5710                 v.reset(OpARM64GreaterEqual)
5711                 v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
5712                 v0.AddArg2(x, y)
5713                 v.AddArg(v0)
5714                 return true
5715         }
5716         // match: (GreaterEqual (CMPconst [0] x:(ANDconst [c] y)))
5717         // cond: x.Uses == 1
5718         // result: (GreaterEqual (TSTconst [c] y))
5719         for {
5720                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
5721                         break
5722                 }
5723                 x := v_0.Args[0]
5724                 if x.Op != OpARM64ANDconst {
5725                         break
5726                 }
5727                 c := auxIntToInt64(x.AuxInt)
5728                 y := x.Args[0]
5729                 if !(x.Uses == 1) {
5730                         break
5731                 }
5732                 v.reset(OpARM64GreaterEqual)
5733                 v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
5734                 v0.AuxInt = int64ToAuxInt(c)
5735                 v0.AddArg(y)
5736                 v.AddArg(v0)
5737                 return true
5738         }
5739         // match: (GreaterEqual (CMPconst [0] x:(ADDconst [c] y)))
5740         // cond: x.Uses == 1
5741         // result: (GreaterEqualNoov (CMNconst [c] y))
5742         for {
5743                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
5744                         break
5745                 }
5746                 x := v_0.Args[0]
5747                 if x.Op != OpARM64ADDconst {
5748                         break
5749                 }
5750                 c := auxIntToInt64(x.AuxInt)
5751                 y := x.Args[0]
5752                 if !(x.Uses == 1) {
5753                         break
5754                 }
5755                 v.reset(OpARM64GreaterEqualNoov)
5756                 v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
5757                 v0.AuxInt = int64ToAuxInt(c)
5758                 v0.AddArg(y)
5759                 v.AddArg(v0)
5760                 return true
5761         }
5762         // match: (GreaterEqual (CMPWconst [0] x:(ADDconst [c] y)))
5763         // cond: x.Uses == 1
5764         // result: (GreaterEqualNoov (CMNWconst [int32(c)] y))
5765         for {
5766                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
5767                         break
5768                 }
5769                 x := v_0.Args[0]
5770                 if x.Op != OpARM64ADDconst {
5771                         break
5772                 }
5773                 c := auxIntToInt64(x.AuxInt)
5774                 y := x.Args[0]
5775                 if !(x.Uses == 1) {
5776                         break
5777                 }
5778                 v.reset(OpARM64GreaterEqualNoov)
5779                 v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
5780                 v0.AuxInt = int32ToAuxInt(int32(c))
5781                 v0.AddArg(y)
5782                 v.AddArg(v0)
5783                 return true
5784         }
5785         // match: (GreaterEqual (CMPconst [0] z:(ADD x y)))
5786         // cond: z.Uses == 1
5787         // result: (GreaterEqualNoov (CMN x y))
5788         for {
5789                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
5790                         break
5791                 }
5792                 z := v_0.Args[0]
5793                 if z.Op != OpARM64ADD {
5794                         break
5795                 }
5796                 y := z.Args[1]
5797                 x := z.Args[0]
5798                 if !(z.Uses == 1) {
5799                         break
5800                 }
5801                 v.reset(OpARM64GreaterEqualNoov)
5802                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
5803                 v0.AddArg2(x, y)
5804                 v.AddArg(v0)
5805                 return true
5806         }
5807         // match: (GreaterEqual (CMPWconst [0] z:(ADD x y)))
5808         // cond: z.Uses == 1
5809         // result: (GreaterEqualNoov (CMNW x y))
5810         for {
5811                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
5812                         break
5813                 }
5814                 z := v_0.Args[0]
5815                 if z.Op != OpARM64ADD {
5816                         break
5817                 }
5818                 y := z.Args[1]
5819                 x := z.Args[0]
5820                 if !(z.Uses == 1) {
5821                         break
5822                 }
5823                 v.reset(OpARM64GreaterEqualNoov)
5824                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
5825                 v0.AddArg2(x, y)
5826                 v.AddArg(v0)
5827                 return true
5828         }
5829         // match: (GreaterEqual (CMPconst [0] z:(MADD a x y)))
5830         // cond: z.Uses == 1
5831         // result: (GreaterEqualNoov (CMN a (MUL <x.Type> x y)))
5832         for {
5833                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
5834                         break
5835                 }
5836                 z := v_0.Args[0]
5837                 if z.Op != OpARM64MADD {
5838                         break
5839                 }
5840                 y := z.Args[2]
5841                 a := z.Args[0]
5842                 x := z.Args[1]
5843                 if !(z.Uses == 1) {
5844                         break
5845                 }
5846                 v.reset(OpARM64GreaterEqualNoov)
5847                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
5848                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
5849                 v1.AddArg2(x, y)
5850                 v0.AddArg2(a, v1)
5851                 v.AddArg(v0)
5852                 return true
5853         }
5854         // match: (GreaterEqual (CMPconst [0] z:(MSUB a x y)))
5855         // cond: z.Uses == 1
5856         // result: (GreaterEqualNoov (CMP a (MUL <x.Type> x y)))
5857         for {
5858                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
5859                         break
5860                 }
5861                 z := v_0.Args[0]
5862                 if z.Op != OpARM64MSUB {
5863                         break
5864                 }
5865                 y := z.Args[2]
5866                 a := z.Args[0]
5867                 x := z.Args[1]
5868                 if !(z.Uses == 1) {
5869                         break
5870                 }
5871                 v.reset(OpARM64GreaterEqualNoov)
5872                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
5873                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
5874                 v1.AddArg2(x, y)
5875                 v0.AddArg2(a, v1)
5876                 v.AddArg(v0)
5877                 return true
5878         }
5879         // match: (GreaterEqual (CMPWconst [0] z:(MADDW a x y)))
5880         // cond: z.Uses == 1
5881         // result: (GreaterEqualNoov (CMNW a (MULW <x.Type> x y)))
5882         for {
5883                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
5884                         break
5885                 }
5886                 z := v_0.Args[0]
5887                 if z.Op != OpARM64MADDW {
5888                         break
5889                 }
5890                 y := z.Args[2]
5891                 a := z.Args[0]
5892                 x := z.Args[1]
5893                 if !(z.Uses == 1) {
5894                         break
5895                 }
5896                 v.reset(OpARM64GreaterEqualNoov)
5897                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
5898                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
5899                 v1.AddArg2(x, y)
5900                 v0.AddArg2(a, v1)
5901                 v.AddArg(v0)
5902                 return true
5903         }
5904         // match: (GreaterEqual (CMPWconst [0] z:(MSUBW a x y)))
5905         // cond: z.Uses == 1
5906         // result: (GreaterEqualNoov (CMPW a (MULW <x.Type> x y)))
5907         for {
5908                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
5909                         break
5910                 }
5911                 z := v_0.Args[0]
5912                 if z.Op != OpARM64MSUBW {
5913                         break
5914                 }
5915                 y := z.Args[2]
5916                 a := z.Args[0]
5917                 x := z.Args[1]
5918                 if !(z.Uses == 1) {
5919                         break
5920                 }
5921                 v.reset(OpARM64GreaterEqualNoov)
5922                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
5923                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
5924                 v1.AddArg2(x, y)
5925                 v0.AddArg2(a, v1)
5926                 v.AddArg(v0)
5927                 return true
5928         }
5929         // match: (GreaterEqual (FlagConstant [fc]))
5930         // result: (MOVDconst [b2i(fc.ge())])
5931         for {
5932                 if v_0.Op != OpARM64FlagConstant {
5933                         break
5934                 }
5935                 fc := auxIntToFlagConstant(v_0.AuxInt)
5936                 v.reset(OpARM64MOVDconst)
5937                 v.AuxInt = int64ToAuxInt(b2i(fc.ge()))
5938                 return true
5939         }
5940         // match: (GreaterEqual (InvertFlags x))
5941         // result: (LessEqual x)
5942         for {
5943                 if v_0.Op != OpARM64InvertFlags {
5944                         break
5945                 }
5946                 x := v_0.Args[0]
5947                 v.reset(OpARM64LessEqual)
5948                 v.AddArg(x)
5949                 return true
5950         }
5951         return false
5952 }
5953 func rewriteValueARM64_OpARM64GreaterEqualF(v *Value) bool {
5954         v_0 := v.Args[0]
5955         // match: (GreaterEqualF (InvertFlags x))
5956         // result: (LessEqualF x)
5957         for {
5958                 if v_0.Op != OpARM64InvertFlags {
5959                         break
5960                 }
5961                 x := v_0.Args[0]
5962                 v.reset(OpARM64LessEqualF)
5963                 v.AddArg(x)
5964                 return true
5965         }
5966         return false
5967 }
5968 func rewriteValueARM64_OpARM64GreaterEqualU(v *Value) bool {
5969         v_0 := v.Args[0]
5970         // match: (GreaterEqualU (FlagConstant [fc]))
5971         // result: (MOVDconst [b2i(fc.uge())])
5972         for {
5973                 if v_0.Op != OpARM64FlagConstant {
5974                         break
5975                 }
5976                 fc := auxIntToFlagConstant(v_0.AuxInt)
5977                 v.reset(OpARM64MOVDconst)
5978                 v.AuxInt = int64ToAuxInt(b2i(fc.uge()))
5979                 return true
5980         }
5981         // match: (GreaterEqualU (InvertFlags x))
5982         // result: (LessEqualU x)
5983         for {
5984                 if v_0.Op != OpARM64InvertFlags {
5985                         break
5986                 }
5987                 x := v_0.Args[0]
5988                 v.reset(OpARM64LessEqualU)
5989                 v.AddArg(x)
5990                 return true
5991         }
5992         return false
5993 }
5994 func rewriteValueARM64_OpARM64GreaterThan(v *Value) bool {
5995         v_0 := v.Args[0]
5996         b := v.Block
5997         // match: (GreaterThan (CMPconst [0] z:(AND x y)))
5998         // cond: z.Uses == 1
5999         // result: (GreaterThan (TST x y))
6000         for {
6001                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6002                         break
6003                 }
6004                 z := v_0.Args[0]
6005                 if z.Op != OpARM64AND {
6006                         break
6007                 }
6008                 y := z.Args[1]
6009                 x := z.Args[0]
6010                 if !(z.Uses == 1) {
6011                         break
6012                 }
6013                 v.reset(OpARM64GreaterThan)
6014                 v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
6015                 v0.AddArg2(x, y)
6016                 v.AddArg(v0)
6017                 return true
6018         }
6019         // match: (GreaterThan (CMPWconst [0] x:(ANDconst [c] y)))
6020         // cond: x.Uses == 1
6021         // result: (GreaterThan (TSTWconst [int32(c)] y))
6022         for {
6023                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6024                         break
6025                 }
6026                 x := v_0.Args[0]
6027                 if x.Op != OpARM64ANDconst {
6028                         break
6029                 }
6030                 c := auxIntToInt64(x.AuxInt)
6031                 y := x.Args[0]
6032                 if !(x.Uses == 1) {
6033                         break
6034                 }
6035                 v.reset(OpARM64GreaterThan)
6036                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
6037                 v0.AuxInt = int32ToAuxInt(int32(c))
6038                 v0.AddArg(y)
6039                 v.AddArg(v0)
6040                 return true
6041         }
6042         // match: (GreaterThan (CMPWconst [0] z:(AND x y)))
6043         // cond: z.Uses == 1
6044         // result: (GreaterThan (TSTW x y))
6045         for {
6046                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6047                         break
6048                 }
6049                 z := v_0.Args[0]
6050                 if z.Op != OpARM64AND {
6051                         break
6052                 }
6053                 y := z.Args[1]
6054                 x := z.Args[0]
6055                 if !(z.Uses == 1) {
6056                         break
6057                 }
6058                 v.reset(OpARM64GreaterThan)
6059                 v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
6060                 v0.AddArg2(x, y)
6061                 v.AddArg(v0)
6062                 return true
6063         }
6064         // match: (GreaterThan (CMPconst [0] x:(ANDconst [c] y)))
6065         // cond: x.Uses == 1
6066         // result: (GreaterThan (TSTconst [c] y))
6067         for {
6068                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6069                         break
6070                 }
6071                 x := v_0.Args[0]
6072                 if x.Op != OpARM64ANDconst {
6073                         break
6074                 }
6075                 c := auxIntToInt64(x.AuxInt)
6076                 y := x.Args[0]
6077                 if !(x.Uses == 1) {
6078                         break
6079                 }
6080                 v.reset(OpARM64GreaterThan)
6081                 v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
6082                 v0.AuxInt = int64ToAuxInt(c)
6083                 v0.AddArg(y)
6084                 v.AddArg(v0)
6085                 return true
6086         }
6087         // match: (GreaterThan (FlagConstant [fc]))
6088         // result: (MOVDconst [b2i(fc.gt())])
6089         for {
6090                 if v_0.Op != OpARM64FlagConstant {
6091                         break
6092                 }
6093                 fc := auxIntToFlagConstant(v_0.AuxInt)
6094                 v.reset(OpARM64MOVDconst)
6095                 v.AuxInt = int64ToAuxInt(b2i(fc.gt()))
6096                 return true
6097         }
6098         // match: (GreaterThan (InvertFlags x))
6099         // result: (LessThan x)
6100         for {
6101                 if v_0.Op != OpARM64InvertFlags {
6102                         break
6103                 }
6104                 x := v_0.Args[0]
6105                 v.reset(OpARM64LessThan)
6106                 v.AddArg(x)
6107                 return true
6108         }
6109         return false
6110 }
6111 func rewriteValueARM64_OpARM64GreaterThanF(v *Value) bool {
6112         v_0 := v.Args[0]
6113         // match: (GreaterThanF (InvertFlags x))
6114         // result: (LessThanF x)
6115         for {
6116                 if v_0.Op != OpARM64InvertFlags {
6117                         break
6118                 }
6119                 x := v_0.Args[0]
6120                 v.reset(OpARM64LessThanF)
6121                 v.AddArg(x)
6122                 return true
6123         }
6124         return false
6125 }
6126 func rewriteValueARM64_OpARM64GreaterThanU(v *Value) bool {
6127         v_0 := v.Args[0]
6128         // match: (GreaterThanU (FlagConstant [fc]))
6129         // result: (MOVDconst [b2i(fc.ugt())])
6130         for {
6131                 if v_0.Op != OpARM64FlagConstant {
6132                         break
6133                 }
6134                 fc := auxIntToFlagConstant(v_0.AuxInt)
6135                 v.reset(OpARM64MOVDconst)
6136                 v.AuxInt = int64ToAuxInt(b2i(fc.ugt()))
6137                 return true
6138         }
6139         // match: (GreaterThanU (InvertFlags x))
6140         // result: (LessThanU x)
6141         for {
6142                 if v_0.Op != OpARM64InvertFlags {
6143                         break
6144                 }
6145                 x := v_0.Args[0]
6146                 v.reset(OpARM64LessThanU)
6147                 v.AddArg(x)
6148                 return true
6149         }
6150         return false
6151 }
6152 func rewriteValueARM64_OpARM64LDP(v *Value) bool {
6153         v_1 := v.Args[1]
6154         v_0 := v.Args[0]
6155         b := v.Block
6156         config := b.Func.Config
6157         // match: (LDP [off1] {sym} (ADDconst [off2] ptr) mem)
6158         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
6159         // result: (LDP [off1+int32(off2)] {sym} ptr mem)
6160         for {
6161                 off1 := auxIntToInt32(v.AuxInt)
6162                 sym := auxToSym(v.Aux)
6163                 if v_0.Op != OpARM64ADDconst {
6164                         break
6165                 }
6166                 off2 := auxIntToInt64(v_0.AuxInt)
6167                 ptr := v_0.Args[0]
6168                 mem := v_1
6169                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
6170                         break
6171                 }
6172                 v.reset(OpARM64LDP)
6173                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
6174                 v.Aux = symToAux(sym)
6175                 v.AddArg2(ptr, mem)
6176                 return true
6177         }
6178         // match: (LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
6179         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
6180         // result: (LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
6181         for {
6182                 off1 := auxIntToInt32(v.AuxInt)
6183                 sym1 := auxToSym(v.Aux)
6184                 if v_0.Op != OpARM64MOVDaddr {
6185                         break
6186                 }
6187                 off2 := auxIntToInt32(v_0.AuxInt)
6188                 sym2 := auxToSym(v_0.Aux)
6189                 ptr := v_0.Args[0]
6190                 mem := v_1
6191                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
6192                         break
6193                 }
6194                 v.reset(OpARM64LDP)
6195                 v.AuxInt = int32ToAuxInt(off1 + off2)
6196                 v.Aux = symToAux(mergeSym(sym1, sym2))
6197                 v.AddArg2(ptr, mem)
6198                 return true
6199         }
6200         return false
6201 }
6202 func rewriteValueARM64_OpARM64LessEqual(v *Value) bool {
6203         v_0 := v.Args[0]
6204         b := v.Block
6205         // match: (LessEqual (CMPconst [0] z:(AND x y)))
6206         // cond: z.Uses == 1
6207         // result: (LessEqual (TST x y))
6208         for {
6209                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6210                         break
6211                 }
6212                 z := v_0.Args[0]
6213                 if z.Op != OpARM64AND {
6214                         break
6215                 }
6216                 y := z.Args[1]
6217                 x := z.Args[0]
6218                 if !(z.Uses == 1) {
6219                         break
6220                 }
6221                 v.reset(OpARM64LessEqual)
6222                 v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
6223                 v0.AddArg2(x, y)
6224                 v.AddArg(v0)
6225                 return true
6226         }
6227         // match: (LessEqual (CMPWconst [0] x:(ANDconst [c] y)))
6228         // cond: x.Uses == 1
6229         // result: (LessEqual (TSTWconst [int32(c)] y))
6230         for {
6231                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6232                         break
6233                 }
6234                 x := v_0.Args[0]
6235                 if x.Op != OpARM64ANDconst {
6236                         break
6237                 }
6238                 c := auxIntToInt64(x.AuxInt)
6239                 y := x.Args[0]
6240                 if !(x.Uses == 1) {
6241                         break
6242                 }
6243                 v.reset(OpARM64LessEqual)
6244                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
6245                 v0.AuxInt = int32ToAuxInt(int32(c))
6246                 v0.AddArg(y)
6247                 v.AddArg(v0)
6248                 return true
6249         }
6250         // match: (LessEqual (CMPWconst [0] z:(AND x y)))
6251         // cond: z.Uses == 1
6252         // result: (LessEqual (TSTW x y))
6253         for {
6254                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6255                         break
6256                 }
6257                 z := v_0.Args[0]
6258                 if z.Op != OpARM64AND {
6259                         break
6260                 }
6261                 y := z.Args[1]
6262                 x := z.Args[0]
6263                 if !(z.Uses == 1) {
6264                         break
6265                 }
6266                 v.reset(OpARM64LessEqual)
6267                 v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
6268                 v0.AddArg2(x, y)
6269                 v.AddArg(v0)
6270                 return true
6271         }
6272         // match: (LessEqual (CMPconst [0] x:(ANDconst [c] y)))
6273         // cond: x.Uses == 1
6274         // result: (LessEqual (TSTconst [c] y))
6275         for {
6276                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6277                         break
6278                 }
6279                 x := v_0.Args[0]
6280                 if x.Op != OpARM64ANDconst {
6281                         break
6282                 }
6283                 c := auxIntToInt64(x.AuxInt)
6284                 y := x.Args[0]
6285                 if !(x.Uses == 1) {
6286                         break
6287                 }
6288                 v.reset(OpARM64LessEqual)
6289                 v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
6290                 v0.AuxInt = int64ToAuxInt(c)
6291                 v0.AddArg(y)
6292                 v.AddArg(v0)
6293                 return true
6294         }
6295         // match: (LessEqual (FlagConstant [fc]))
6296         // result: (MOVDconst [b2i(fc.le())])
6297         for {
6298                 if v_0.Op != OpARM64FlagConstant {
6299                         break
6300                 }
6301                 fc := auxIntToFlagConstant(v_0.AuxInt)
6302                 v.reset(OpARM64MOVDconst)
6303                 v.AuxInt = int64ToAuxInt(b2i(fc.le()))
6304                 return true
6305         }
6306         // match: (LessEqual (InvertFlags x))
6307         // result: (GreaterEqual x)
6308         for {
6309                 if v_0.Op != OpARM64InvertFlags {
6310                         break
6311                 }
6312                 x := v_0.Args[0]
6313                 v.reset(OpARM64GreaterEqual)
6314                 v.AddArg(x)
6315                 return true
6316         }
6317         return false
6318 }
6319 func rewriteValueARM64_OpARM64LessEqualF(v *Value) bool {
6320         v_0 := v.Args[0]
6321         // match: (LessEqualF (InvertFlags x))
6322         // result: (GreaterEqualF x)
6323         for {
6324                 if v_0.Op != OpARM64InvertFlags {
6325                         break
6326                 }
6327                 x := v_0.Args[0]
6328                 v.reset(OpARM64GreaterEqualF)
6329                 v.AddArg(x)
6330                 return true
6331         }
6332         return false
6333 }
6334 func rewriteValueARM64_OpARM64LessEqualU(v *Value) bool {
6335         v_0 := v.Args[0]
6336         // match: (LessEqualU (FlagConstant [fc]))
6337         // result: (MOVDconst [b2i(fc.ule())])
6338         for {
6339                 if v_0.Op != OpARM64FlagConstant {
6340                         break
6341                 }
6342                 fc := auxIntToFlagConstant(v_0.AuxInt)
6343                 v.reset(OpARM64MOVDconst)
6344                 v.AuxInt = int64ToAuxInt(b2i(fc.ule()))
6345                 return true
6346         }
6347         // match: (LessEqualU (InvertFlags x))
6348         // result: (GreaterEqualU x)
6349         for {
6350                 if v_0.Op != OpARM64InvertFlags {
6351                         break
6352                 }
6353                 x := v_0.Args[0]
6354                 v.reset(OpARM64GreaterEqualU)
6355                 v.AddArg(x)
6356                 return true
6357         }
6358         return false
6359 }
6360 func rewriteValueARM64_OpARM64LessThan(v *Value) bool {
6361         v_0 := v.Args[0]
6362         b := v.Block
6363         // match: (LessThan (CMPconst [0] z:(AND x y)))
6364         // cond: z.Uses == 1
6365         // result: (LessThan (TST x y))
6366         for {
6367                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6368                         break
6369                 }
6370                 z := v_0.Args[0]
6371                 if z.Op != OpARM64AND {
6372                         break
6373                 }
6374                 y := z.Args[1]
6375                 x := z.Args[0]
6376                 if !(z.Uses == 1) {
6377                         break
6378                 }
6379                 v.reset(OpARM64LessThan)
6380                 v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
6381                 v0.AddArg2(x, y)
6382                 v.AddArg(v0)
6383                 return true
6384         }
6385         // match: (LessThan (CMPWconst [0] x:(ANDconst [c] y)))
6386         // cond: x.Uses == 1
6387         // result: (LessThan (TSTWconst [int32(c)] y))
6388         for {
6389                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6390                         break
6391                 }
6392                 x := v_0.Args[0]
6393                 if x.Op != OpARM64ANDconst {
6394                         break
6395                 }
6396                 c := auxIntToInt64(x.AuxInt)
6397                 y := x.Args[0]
6398                 if !(x.Uses == 1) {
6399                         break
6400                 }
6401                 v.reset(OpARM64LessThan)
6402                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
6403                 v0.AuxInt = int32ToAuxInt(int32(c))
6404                 v0.AddArg(y)
6405                 v.AddArg(v0)
6406                 return true
6407         }
6408         // match: (LessThan (CMPWconst [0] z:(AND x y)))
6409         // cond: z.Uses == 1
6410         // result: (LessThan (TSTW x y))
6411         for {
6412                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6413                         break
6414                 }
6415                 z := v_0.Args[0]
6416                 if z.Op != OpARM64AND {
6417                         break
6418                 }
6419                 y := z.Args[1]
6420                 x := z.Args[0]
6421                 if !(z.Uses == 1) {
6422                         break
6423                 }
6424                 v.reset(OpARM64LessThan)
6425                 v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
6426                 v0.AddArg2(x, y)
6427                 v.AddArg(v0)
6428                 return true
6429         }
6430         // match: (LessThan (CMPconst [0] x:(ANDconst [c] y)))
6431         // cond: x.Uses == 1
6432         // result: (LessThan (TSTconst [c] y))
6433         for {
6434                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6435                         break
6436                 }
6437                 x := v_0.Args[0]
6438                 if x.Op != OpARM64ANDconst {
6439                         break
6440                 }
6441                 c := auxIntToInt64(x.AuxInt)
6442                 y := x.Args[0]
6443                 if !(x.Uses == 1) {
6444                         break
6445                 }
6446                 v.reset(OpARM64LessThan)
6447                 v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
6448                 v0.AuxInt = int64ToAuxInt(c)
6449                 v0.AddArg(y)
6450                 v.AddArg(v0)
6451                 return true
6452         }
6453         // match: (LessThan (CMPconst [0] x:(ADDconst [c] y)))
6454         // cond: x.Uses == 1
6455         // result: (LessThanNoov (CMNconst [c] y))
6456         for {
6457                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6458                         break
6459                 }
6460                 x := v_0.Args[0]
6461                 if x.Op != OpARM64ADDconst {
6462                         break
6463                 }
6464                 c := auxIntToInt64(x.AuxInt)
6465                 y := x.Args[0]
6466                 if !(x.Uses == 1) {
6467                         break
6468                 }
6469                 v.reset(OpARM64LessThanNoov)
6470                 v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
6471                 v0.AuxInt = int64ToAuxInt(c)
6472                 v0.AddArg(y)
6473                 v.AddArg(v0)
6474                 return true
6475         }
6476         // match: (LessThan (CMPWconst [0] x:(ADDconst [c] y)))
6477         // cond: x.Uses == 1
6478         // result: (LessThanNoov (CMNWconst [int32(c)] y))
6479         for {
6480                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6481                         break
6482                 }
6483                 x := v_0.Args[0]
6484                 if x.Op != OpARM64ADDconst {
6485                         break
6486                 }
6487                 c := auxIntToInt64(x.AuxInt)
6488                 y := x.Args[0]
6489                 if !(x.Uses == 1) {
6490                         break
6491                 }
6492                 v.reset(OpARM64LessThanNoov)
6493                 v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
6494                 v0.AuxInt = int32ToAuxInt(int32(c))
6495                 v0.AddArg(y)
6496                 v.AddArg(v0)
6497                 return true
6498         }
6499         // match: (LessThan (CMPconst [0] z:(ADD x y)))
6500         // cond: z.Uses == 1
6501         // result: (LessThanNoov (CMN x y))
6502         for {
6503                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6504                         break
6505                 }
6506                 z := v_0.Args[0]
6507                 if z.Op != OpARM64ADD {
6508                         break
6509                 }
6510                 y := z.Args[1]
6511                 x := z.Args[0]
6512                 if !(z.Uses == 1) {
6513                         break
6514                 }
6515                 v.reset(OpARM64LessThanNoov)
6516                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
6517                 v0.AddArg2(x, y)
6518                 v.AddArg(v0)
6519                 return true
6520         }
6521         // match: (LessThan (CMPWconst [0] z:(ADD x y)))
6522         // cond: z.Uses == 1
6523         // result: (LessThanNoov (CMNW x y))
6524         for {
6525                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6526                         break
6527                 }
6528                 z := v_0.Args[0]
6529                 if z.Op != OpARM64ADD {
6530                         break
6531                 }
6532                 y := z.Args[1]
6533                 x := z.Args[0]
6534                 if !(z.Uses == 1) {
6535                         break
6536                 }
6537                 v.reset(OpARM64LessThanNoov)
6538                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
6539                 v0.AddArg2(x, y)
6540                 v.AddArg(v0)
6541                 return true
6542         }
6543         // match: (LessThan (CMPconst [0] z:(MADD a x y)))
6544         // cond: z.Uses == 1
6545         // result: (LessThanNoov (CMN a (MUL <x.Type> x y)))
6546         for {
6547                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6548                         break
6549                 }
6550                 z := v_0.Args[0]
6551                 if z.Op != OpARM64MADD {
6552                         break
6553                 }
6554                 y := z.Args[2]
6555                 a := z.Args[0]
6556                 x := z.Args[1]
6557                 if !(z.Uses == 1) {
6558                         break
6559                 }
6560                 v.reset(OpARM64LessThanNoov)
6561                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
6562                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
6563                 v1.AddArg2(x, y)
6564                 v0.AddArg2(a, v1)
6565                 v.AddArg(v0)
6566                 return true
6567         }
6568         // match: (LessThan (CMPconst [0] z:(MSUB a x y)))
6569         // cond: z.Uses == 1
6570         // result: (LessThanNoov (CMP a (MUL <x.Type> x y)))
6571         for {
6572                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
6573                         break
6574                 }
6575                 z := v_0.Args[0]
6576                 if z.Op != OpARM64MSUB {
6577                         break
6578                 }
6579                 y := z.Args[2]
6580                 a := z.Args[0]
6581                 x := z.Args[1]
6582                 if !(z.Uses == 1) {
6583                         break
6584                 }
6585                 v.reset(OpARM64LessThanNoov)
6586                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
6587                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
6588                 v1.AddArg2(x, y)
6589                 v0.AddArg2(a, v1)
6590                 v.AddArg(v0)
6591                 return true
6592         }
6593         // match: (LessThan (CMPWconst [0] z:(MADDW a x y)))
6594         // cond: z.Uses == 1
6595         // result: (LessThanNoov (CMNW a (MULW <x.Type> x y)))
6596         for {
6597                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6598                         break
6599                 }
6600                 z := v_0.Args[0]
6601                 if z.Op != OpARM64MADDW {
6602                         break
6603                 }
6604                 y := z.Args[2]
6605                 a := z.Args[0]
6606                 x := z.Args[1]
6607                 if !(z.Uses == 1) {
6608                         break
6609                 }
6610                 v.reset(OpARM64LessThanNoov)
6611                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
6612                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
6613                 v1.AddArg2(x, y)
6614                 v0.AddArg2(a, v1)
6615                 v.AddArg(v0)
6616                 return true
6617         }
6618         // match: (LessThan (CMPWconst [0] z:(MSUBW a x y)))
6619         // cond: z.Uses == 1
6620         // result: (LessThanNoov (CMPW a (MULW <x.Type> x y)))
6621         for {
6622                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
6623                         break
6624                 }
6625                 z := v_0.Args[0]
6626                 if z.Op != OpARM64MSUBW {
6627                         break
6628                 }
6629                 y := z.Args[2]
6630                 a := z.Args[0]
6631                 x := z.Args[1]
6632                 if !(z.Uses == 1) {
6633                         break
6634                 }
6635                 v.reset(OpARM64LessThanNoov)
6636                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
6637                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
6638                 v1.AddArg2(x, y)
6639                 v0.AddArg2(a, v1)
6640                 v.AddArg(v0)
6641                 return true
6642         }
6643         // match: (LessThan (FlagConstant [fc]))
6644         // result: (MOVDconst [b2i(fc.lt())])
6645         for {
6646                 if v_0.Op != OpARM64FlagConstant {
6647                         break
6648                 }
6649                 fc := auxIntToFlagConstant(v_0.AuxInt)
6650                 v.reset(OpARM64MOVDconst)
6651                 v.AuxInt = int64ToAuxInt(b2i(fc.lt()))
6652                 return true
6653         }
6654         // match: (LessThan (InvertFlags x))
6655         // result: (GreaterThan x)
6656         for {
6657                 if v_0.Op != OpARM64InvertFlags {
6658                         break
6659                 }
6660                 x := v_0.Args[0]
6661                 v.reset(OpARM64GreaterThan)
6662                 v.AddArg(x)
6663                 return true
6664         }
6665         return false
6666 }
6667 func rewriteValueARM64_OpARM64LessThanF(v *Value) bool {
6668         v_0 := v.Args[0]
6669         // match: (LessThanF (InvertFlags x))
6670         // result: (GreaterThanF x)
6671         for {
6672                 if v_0.Op != OpARM64InvertFlags {
6673                         break
6674                 }
6675                 x := v_0.Args[0]
6676                 v.reset(OpARM64GreaterThanF)
6677                 v.AddArg(x)
6678                 return true
6679         }
6680         return false
6681 }
6682 func rewriteValueARM64_OpARM64LessThanU(v *Value) bool {
6683         v_0 := v.Args[0]
6684         // match: (LessThanU (FlagConstant [fc]))
6685         // result: (MOVDconst [b2i(fc.ult())])
6686         for {
6687                 if v_0.Op != OpARM64FlagConstant {
6688                         break
6689                 }
6690                 fc := auxIntToFlagConstant(v_0.AuxInt)
6691                 v.reset(OpARM64MOVDconst)
6692                 v.AuxInt = int64ToAuxInt(b2i(fc.ult()))
6693                 return true
6694         }
6695         // match: (LessThanU (InvertFlags x))
6696         // result: (GreaterThanU x)
6697         for {
6698                 if v_0.Op != OpARM64InvertFlags {
6699                         break
6700                 }
6701                 x := v_0.Args[0]
6702                 v.reset(OpARM64GreaterThanU)
6703                 v.AddArg(x)
6704                 return true
6705         }
6706         return false
6707 }
6708 func rewriteValueARM64_OpARM64MADD(v *Value) bool {
6709         v_2 := v.Args[2]
6710         v_1 := v.Args[1]
6711         v_0 := v.Args[0]
6712         b := v.Block
6713         // match: (MADD a x (MOVDconst [-1]))
6714         // result: (SUB a x)
6715         for {
6716                 a := v_0
6717                 x := v_1
6718                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != -1 {
6719                         break
6720                 }
6721                 v.reset(OpARM64SUB)
6722                 v.AddArg2(a, x)
6723                 return true
6724         }
6725         // match: (MADD a _ (MOVDconst [0]))
6726         // result: a
6727         for {
6728                 a := v_0
6729                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
6730                         break
6731                 }
6732                 v.copyOf(a)
6733                 return true
6734         }
6735         // match: (MADD a x (MOVDconst [1]))
6736         // result: (ADD a x)
6737         for {
6738                 a := v_0
6739                 x := v_1
6740                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 1 {
6741                         break
6742                 }
6743                 v.reset(OpARM64ADD)
6744                 v.AddArg2(a, x)
6745                 return true
6746         }
6747         // match: (MADD a x (MOVDconst [c]))
6748         // cond: isPowerOfTwo64(c)
6749         // result: (ADDshiftLL a x [log64(c)])
6750         for {
6751                 a := v_0
6752                 x := v_1
6753                 if v_2.Op != OpARM64MOVDconst {
6754                         break
6755                 }
6756                 c := auxIntToInt64(v_2.AuxInt)
6757                 if !(isPowerOfTwo64(c)) {
6758                         break
6759                 }
6760                 v.reset(OpARM64ADDshiftLL)
6761                 v.AuxInt = int64ToAuxInt(log64(c))
6762                 v.AddArg2(a, x)
6763                 return true
6764         }
6765         // match: (MADD a x (MOVDconst [c]))
6766         // cond: isPowerOfTwo64(c-1) && c>=3
6767         // result: (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
6768         for {
6769                 a := v_0
6770                 x := v_1
6771                 if v_2.Op != OpARM64MOVDconst {
6772                         break
6773                 }
6774                 c := auxIntToInt64(v_2.AuxInt)
6775                 if !(isPowerOfTwo64(c-1) && c >= 3) {
6776                         break
6777                 }
6778                 v.reset(OpARM64ADD)
6779                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
6780                 v0.AuxInt = int64ToAuxInt(log64(c - 1))
6781                 v0.AddArg2(x, x)
6782                 v.AddArg2(a, v0)
6783                 return true
6784         }
6785         // match: (MADD a x (MOVDconst [c]))
6786         // cond: isPowerOfTwo64(c+1) && c>=7
6787         // result: (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
6788         for {
6789                 a := v_0
6790                 x := v_1
6791                 if v_2.Op != OpARM64MOVDconst {
6792                         break
6793                 }
6794                 c := auxIntToInt64(v_2.AuxInt)
6795                 if !(isPowerOfTwo64(c+1) && c >= 7) {
6796                         break
6797                 }
6798                 v.reset(OpARM64SUB)
6799                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
6800                 v0.AuxInt = int64ToAuxInt(log64(c + 1))
6801                 v0.AddArg2(x, x)
6802                 v.AddArg2(a, v0)
6803                 return true
6804         }
6805         // match: (MADD a x (MOVDconst [c]))
6806         // cond: c%3 == 0 && isPowerOfTwo64(c/3)
6807         // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
6808         for {
6809                 a := v_0
6810                 x := v_1
6811                 if v_2.Op != OpARM64MOVDconst {
6812                         break
6813                 }
6814                 c := auxIntToInt64(v_2.AuxInt)
6815                 if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
6816                         break
6817                 }
6818                 v.reset(OpARM64SUBshiftLL)
6819                 v.AuxInt = int64ToAuxInt(log64(c / 3))
6820                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
6821                 v0.AuxInt = int64ToAuxInt(2)
6822                 v0.AddArg2(x, x)
6823                 v.AddArg2(a, v0)
6824                 return true
6825         }
6826         // match: (MADD a x (MOVDconst [c]))
6827         // cond: c%5 == 0 && isPowerOfTwo64(c/5)
6828         // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
6829         for {
6830                 a := v_0
6831                 x := v_1
6832                 if v_2.Op != OpARM64MOVDconst {
6833                         break
6834                 }
6835                 c := auxIntToInt64(v_2.AuxInt)
6836                 if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
6837                         break
6838                 }
6839                 v.reset(OpARM64ADDshiftLL)
6840                 v.AuxInt = int64ToAuxInt(log64(c / 5))
6841                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
6842                 v0.AuxInt = int64ToAuxInt(2)
6843                 v0.AddArg2(x, x)
6844                 v.AddArg2(a, v0)
6845                 return true
6846         }
6847         // match: (MADD a x (MOVDconst [c]))
6848         // cond: c%7 == 0 && isPowerOfTwo64(c/7)
6849         // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
6850         for {
6851                 a := v_0
6852                 x := v_1
6853                 if v_2.Op != OpARM64MOVDconst {
6854                         break
6855                 }
6856                 c := auxIntToInt64(v_2.AuxInt)
6857                 if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
6858                         break
6859                 }
6860                 v.reset(OpARM64SUBshiftLL)
6861                 v.AuxInt = int64ToAuxInt(log64(c / 7))
6862                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
6863                 v0.AuxInt = int64ToAuxInt(3)
6864                 v0.AddArg2(x, x)
6865                 v.AddArg2(a, v0)
6866                 return true
6867         }
6868         // match: (MADD a x (MOVDconst [c]))
6869         // cond: c%9 == 0 && isPowerOfTwo64(c/9)
6870         // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
6871         for {
6872                 a := v_0
6873                 x := v_1
6874                 if v_2.Op != OpARM64MOVDconst {
6875                         break
6876                 }
6877                 c := auxIntToInt64(v_2.AuxInt)
6878                 if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
6879                         break
6880                 }
6881                 v.reset(OpARM64ADDshiftLL)
6882                 v.AuxInt = int64ToAuxInt(log64(c / 9))
6883                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
6884                 v0.AuxInt = int64ToAuxInt(3)
6885                 v0.AddArg2(x, x)
6886                 v.AddArg2(a, v0)
6887                 return true
6888         }
6889         // match: (MADD a (MOVDconst [-1]) x)
6890         // result: (SUB a x)
6891         for {
6892                 a := v_0
6893                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
6894                         break
6895                 }
6896                 x := v_2
6897                 v.reset(OpARM64SUB)
6898                 v.AddArg2(a, x)
6899                 return true
6900         }
6901         // match: (MADD a (MOVDconst [0]) _)
6902         // result: a
6903         for {
6904                 a := v_0
6905                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
6906                         break
6907                 }
6908                 v.copyOf(a)
6909                 return true
6910         }
6911         // match: (MADD a (MOVDconst [1]) x)
6912         // result: (ADD a x)
6913         for {
6914                 a := v_0
6915                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
6916                         break
6917                 }
6918                 x := v_2
6919                 v.reset(OpARM64ADD)
6920                 v.AddArg2(a, x)
6921                 return true
6922         }
6923         // match: (MADD a (MOVDconst [c]) x)
6924         // cond: isPowerOfTwo64(c)
6925         // result: (ADDshiftLL a x [log64(c)])
6926         for {
6927                 a := v_0
6928                 if v_1.Op != OpARM64MOVDconst {
6929                         break
6930                 }
6931                 c := auxIntToInt64(v_1.AuxInt)
6932                 x := v_2
6933                 if !(isPowerOfTwo64(c)) {
6934                         break
6935                 }
6936                 v.reset(OpARM64ADDshiftLL)
6937                 v.AuxInt = int64ToAuxInt(log64(c))
6938                 v.AddArg2(a, x)
6939                 return true
6940         }
6941         // match: (MADD a (MOVDconst [c]) x)
6942         // cond: isPowerOfTwo64(c-1) && c>=3
6943         // result: (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
6944         for {
6945                 a := v_0
6946                 if v_1.Op != OpARM64MOVDconst {
6947                         break
6948                 }
6949                 c := auxIntToInt64(v_1.AuxInt)
6950                 x := v_2
6951                 if !(isPowerOfTwo64(c-1) && c >= 3) {
6952                         break
6953                 }
6954                 v.reset(OpARM64ADD)
6955                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
6956                 v0.AuxInt = int64ToAuxInt(log64(c - 1))
6957                 v0.AddArg2(x, x)
6958                 v.AddArg2(a, v0)
6959                 return true
6960         }
6961         // match: (MADD a (MOVDconst [c]) x)
6962         // cond: isPowerOfTwo64(c+1) && c>=7
6963         // result: (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
6964         for {
6965                 a := v_0
6966                 if v_1.Op != OpARM64MOVDconst {
6967                         break
6968                 }
6969                 c := auxIntToInt64(v_1.AuxInt)
6970                 x := v_2
6971                 if !(isPowerOfTwo64(c+1) && c >= 7) {
6972                         break
6973                 }
6974                 v.reset(OpARM64SUB)
6975                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
6976                 v0.AuxInt = int64ToAuxInt(log64(c + 1))
6977                 v0.AddArg2(x, x)
6978                 v.AddArg2(a, v0)
6979                 return true
6980         }
6981         // match: (MADD a (MOVDconst [c]) x)
6982         // cond: c%3 == 0 && isPowerOfTwo64(c/3)
6983         // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
6984         for {
6985                 a := v_0
6986                 if v_1.Op != OpARM64MOVDconst {
6987                         break
6988                 }
6989                 c := auxIntToInt64(v_1.AuxInt)
6990                 x := v_2
6991                 if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
6992                         break
6993                 }
6994                 v.reset(OpARM64SUBshiftLL)
6995                 v.AuxInt = int64ToAuxInt(log64(c / 3))
6996                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
6997                 v0.AuxInt = int64ToAuxInt(2)
6998                 v0.AddArg2(x, x)
6999                 v.AddArg2(a, v0)
7000                 return true
7001         }
7002         // match: (MADD a (MOVDconst [c]) x)
7003         // cond: c%5 == 0 && isPowerOfTwo64(c/5)
7004         // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
7005         for {
7006                 a := v_0
7007                 if v_1.Op != OpARM64MOVDconst {
7008                         break
7009                 }
7010                 c := auxIntToInt64(v_1.AuxInt)
7011                 x := v_2
7012                 if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
7013                         break
7014                 }
7015                 v.reset(OpARM64ADDshiftLL)
7016                 v.AuxInt = int64ToAuxInt(log64(c / 5))
7017                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7018                 v0.AuxInt = int64ToAuxInt(2)
7019                 v0.AddArg2(x, x)
7020                 v.AddArg2(a, v0)
7021                 return true
7022         }
7023         // match: (MADD a (MOVDconst [c]) x)
7024         // cond: c%7 == 0 && isPowerOfTwo64(c/7)
7025         // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
7026         for {
7027                 a := v_0
7028                 if v_1.Op != OpARM64MOVDconst {
7029                         break
7030                 }
7031                 c := auxIntToInt64(v_1.AuxInt)
7032                 x := v_2
7033                 if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
7034                         break
7035                 }
7036                 v.reset(OpARM64SUBshiftLL)
7037                 v.AuxInt = int64ToAuxInt(log64(c / 7))
7038                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7039                 v0.AuxInt = int64ToAuxInt(3)
7040                 v0.AddArg2(x, x)
7041                 v.AddArg2(a, v0)
7042                 return true
7043         }
7044         // match: (MADD a (MOVDconst [c]) x)
7045         // cond: c%9 == 0 && isPowerOfTwo64(c/9)
7046         // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
7047         for {
7048                 a := v_0
7049                 if v_1.Op != OpARM64MOVDconst {
7050                         break
7051                 }
7052                 c := auxIntToInt64(v_1.AuxInt)
7053                 x := v_2
7054                 if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
7055                         break
7056                 }
7057                 v.reset(OpARM64ADDshiftLL)
7058                 v.AuxInt = int64ToAuxInt(log64(c / 9))
7059                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7060                 v0.AuxInt = int64ToAuxInt(3)
7061                 v0.AddArg2(x, x)
7062                 v.AddArg2(a, v0)
7063                 return true
7064         }
7065         // match: (MADD (MOVDconst [c]) x y)
7066         // result: (ADDconst [c] (MUL <x.Type> x y))
7067         for {
7068                 if v_0.Op != OpARM64MOVDconst {
7069                         break
7070                 }
7071                 c := auxIntToInt64(v_0.AuxInt)
7072                 x := v_1
7073                 y := v_2
7074                 v.reset(OpARM64ADDconst)
7075                 v.AuxInt = int64ToAuxInt(c)
7076                 v0 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
7077                 v0.AddArg2(x, y)
7078                 v.AddArg(v0)
7079                 return true
7080         }
7081         // match: (MADD a (MOVDconst [c]) (MOVDconst [d]))
7082         // result: (ADDconst [c*d] a)
7083         for {
7084                 a := v_0
7085                 if v_1.Op != OpARM64MOVDconst {
7086                         break
7087                 }
7088                 c := auxIntToInt64(v_1.AuxInt)
7089                 if v_2.Op != OpARM64MOVDconst {
7090                         break
7091                 }
7092                 d := auxIntToInt64(v_2.AuxInt)
7093                 v.reset(OpARM64ADDconst)
7094                 v.AuxInt = int64ToAuxInt(c * d)
7095                 v.AddArg(a)
7096                 return true
7097         }
7098         return false
7099 }
7100 func rewriteValueARM64_OpARM64MADDW(v *Value) bool {
7101         v_2 := v.Args[2]
7102         v_1 := v.Args[1]
7103         v_0 := v.Args[0]
7104         b := v.Block
7105         // match: (MADDW a x (MOVDconst [c]))
7106         // cond: int32(c)==-1
7107         // result: (MOVWUreg (SUB <a.Type> a x))
7108         for {
7109                 a := v_0
7110                 x := v_1
7111                 if v_2.Op != OpARM64MOVDconst {
7112                         break
7113                 }
7114                 c := auxIntToInt64(v_2.AuxInt)
7115                 if !(int32(c) == -1) {
7116                         break
7117                 }
7118                 v.reset(OpARM64MOVWUreg)
7119                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
7120                 v0.AddArg2(a, x)
7121                 v.AddArg(v0)
7122                 return true
7123         }
7124         // match: (MADDW a _ (MOVDconst [c]))
7125         // cond: int32(c)==0
7126         // result: (MOVWUreg a)
7127         for {
7128                 a := v_0
7129                 if v_2.Op != OpARM64MOVDconst {
7130                         break
7131                 }
7132                 c := auxIntToInt64(v_2.AuxInt)
7133                 if !(int32(c) == 0) {
7134                         break
7135                 }
7136                 v.reset(OpARM64MOVWUreg)
7137                 v.AddArg(a)
7138                 return true
7139         }
7140         // match: (MADDW a x (MOVDconst [c]))
7141         // cond: int32(c)==1
7142         // result: (MOVWUreg (ADD <a.Type> a x))
7143         for {
7144                 a := v_0
7145                 x := v_1
7146                 if v_2.Op != OpARM64MOVDconst {
7147                         break
7148                 }
7149                 c := auxIntToInt64(v_2.AuxInt)
7150                 if !(int32(c) == 1) {
7151                         break
7152                 }
7153                 v.reset(OpARM64MOVWUreg)
7154                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
7155                 v0.AddArg2(a, x)
7156                 v.AddArg(v0)
7157                 return true
7158         }
7159         // match: (MADDW a x (MOVDconst [c]))
7160         // cond: isPowerOfTwo64(c)
7161         // result: (MOVWUreg (ADDshiftLL <a.Type> a x [log64(c)]))
7162         for {
7163                 a := v_0
7164                 x := v_1
7165                 if v_2.Op != OpARM64MOVDconst {
7166                         break
7167                 }
7168                 c := auxIntToInt64(v_2.AuxInt)
7169                 if !(isPowerOfTwo64(c)) {
7170                         break
7171                 }
7172                 v.reset(OpARM64MOVWUreg)
7173                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
7174                 v0.AuxInt = int64ToAuxInt(log64(c))
7175                 v0.AddArg2(a, x)
7176                 v.AddArg(v0)
7177                 return true
7178         }
7179         // match: (MADDW a x (MOVDconst [c]))
7180         // cond: isPowerOfTwo64(c-1) && int32(c)>=3
7181         // result: (MOVWUreg (ADD <a.Type> a (ADDshiftLL <x.Type> x x [log64(c-1)])))
7182         for {
7183                 a := v_0
7184                 x := v_1
7185                 if v_2.Op != OpARM64MOVDconst {
7186                         break
7187                 }
7188                 c := auxIntToInt64(v_2.AuxInt)
7189                 if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
7190                         break
7191                 }
7192                 v.reset(OpARM64MOVWUreg)
7193                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
7194                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7195                 v1.AuxInt = int64ToAuxInt(log64(c - 1))
7196                 v1.AddArg2(x, x)
7197                 v0.AddArg2(a, v1)
7198                 v.AddArg(v0)
7199                 return true
7200         }
7201         // match: (MADDW a x (MOVDconst [c]))
7202         // cond: isPowerOfTwo64(c+1) && int32(c)>=7
7203         // result: (MOVWUreg (SUB <a.Type> a (SUBshiftLL <x.Type> x x [log64(c+1)])))
7204         for {
7205                 a := v_0
7206                 x := v_1
7207                 if v_2.Op != OpARM64MOVDconst {
7208                         break
7209                 }
7210                 c := auxIntToInt64(v_2.AuxInt)
7211                 if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
7212                         break
7213                 }
7214                 v.reset(OpARM64MOVWUreg)
7215                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
7216                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7217                 v1.AuxInt = int64ToAuxInt(log64(c + 1))
7218                 v1.AddArg2(x, x)
7219                 v0.AddArg2(a, v1)
7220                 v.AddArg(v0)
7221                 return true
7222         }
7223         // match: (MADDW a x (MOVDconst [c]))
7224         // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
7225         // result: (MOVWUreg (SUBshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]))
7226         for {
7227                 a := v_0
7228                 x := v_1
7229                 if v_2.Op != OpARM64MOVDconst {
7230                         break
7231                 }
7232                 c := auxIntToInt64(v_2.AuxInt)
7233                 if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
7234                         break
7235                 }
7236                 v.reset(OpARM64MOVWUreg)
7237                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
7238                 v0.AuxInt = int64ToAuxInt(log64(c / 3))
7239                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7240                 v1.AuxInt = int64ToAuxInt(2)
7241                 v1.AddArg2(x, x)
7242                 v0.AddArg2(a, v1)
7243                 v.AddArg(v0)
7244                 return true
7245         }
7246         // match: (MADDW a x (MOVDconst [c]))
7247         // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
7248         // result: (MOVWUreg (ADDshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]))
7249         for {
7250                 a := v_0
7251                 x := v_1
7252                 if v_2.Op != OpARM64MOVDconst {
7253                         break
7254                 }
7255                 c := auxIntToInt64(v_2.AuxInt)
7256                 if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
7257                         break
7258                 }
7259                 v.reset(OpARM64MOVWUreg)
7260                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
7261                 v0.AuxInt = int64ToAuxInt(log64(c / 5))
7262                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7263                 v1.AuxInt = int64ToAuxInt(2)
7264                 v1.AddArg2(x, x)
7265                 v0.AddArg2(a, v1)
7266                 v.AddArg(v0)
7267                 return true
7268         }
7269         // match: (MADDW a x (MOVDconst [c]))
7270         // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
7271         // result: (MOVWUreg (SUBshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]))
7272         for {
7273                 a := v_0
7274                 x := v_1
7275                 if v_2.Op != OpARM64MOVDconst {
7276                         break
7277                 }
7278                 c := auxIntToInt64(v_2.AuxInt)
7279                 if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
7280                         break
7281                 }
7282                 v.reset(OpARM64MOVWUreg)
7283                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
7284                 v0.AuxInt = int64ToAuxInt(log64(c / 7))
7285                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7286                 v1.AuxInt = int64ToAuxInt(3)
7287                 v1.AddArg2(x, x)
7288                 v0.AddArg2(a, v1)
7289                 v.AddArg(v0)
7290                 return true
7291         }
7292         // match: (MADDW a x (MOVDconst [c]))
7293         // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
7294         // result: (MOVWUreg (ADDshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]))
7295         for {
7296                 a := v_0
7297                 x := v_1
7298                 if v_2.Op != OpARM64MOVDconst {
7299                         break
7300                 }
7301                 c := auxIntToInt64(v_2.AuxInt)
7302                 if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
7303                         break
7304                 }
7305                 v.reset(OpARM64MOVWUreg)
7306                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
7307                 v0.AuxInt = int64ToAuxInt(log64(c / 9))
7308                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7309                 v1.AuxInt = int64ToAuxInt(3)
7310                 v1.AddArg2(x, x)
7311                 v0.AddArg2(a, v1)
7312                 v.AddArg(v0)
7313                 return true
7314         }
7315         // match: (MADDW a (MOVDconst [c]) x)
7316         // cond: int32(c)==-1
7317         // result: (MOVWUreg (SUB <a.Type> a x))
7318         for {
7319                 a := v_0
7320                 if v_1.Op != OpARM64MOVDconst {
7321                         break
7322                 }
7323                 c := auxIntToInt64(v_1.AuxInt)
7324                 x := v_2
7325                 if !(int32(c) == -1) {
7326                         break
7327                 }
7328                 v.reset(OpARM64MOVWUreg)
7329                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
7330                 v0.AddArg2(a, x)
7331                 v.AddArg(v0)
7332                 return true
7333         }
7334         // match: (MADDW a (MOVDconst [c]) _)
7335         // cond: int32(c)==0
7336         // result: (MOVWUreg a)
7337         for {
7338                 a := v_0
7339                 if v_1.Op != OpARM64MOVDconst {
7340                         break
7341                 }
7342                 c := auxIntToInt64(v_1.AuxInt)
7343                 if !(int32(c) == 0) {
7344                         break
7345                 }
7346                 v.reset(OpARM64MOVWUreg)
7347                 v.AddArg(a)
7348                 return true
7349         }
7350         // match: (MADDW a (MOVDconst [c]) x)
7351         // cond: int32(c)==1
7352         // result: (MOVWUreg (ADD <a.Type> a x))
7353         for {
7354                 a := v_0
7355                 if v_1.Op != OpARM64MOVDconst {
7356                         break
7357                 }
7358                 c := auxIntToInt64(v_1.AuxInt)
7359                 x := v_2
7360                 if !(int32(c) == 1) {
7361                         break
7362                 }
7363                 v.reset(OpARM64MOVWUreg)
7364                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
7365                 v0.AddArg2(a, x)
7366                 v.AddArg(v0)
7367                 return true
7368         }
7369         // match: (MADDW a (MOVDconst [c]) x)
7370         // cond: isPowerOfTwo64(c)
7371         // result: (MOVWUreg (ADDshiftLL <a.Type> a x [log64(c)]))
7372         for {
7373                 a := v_0
7374                 if v_1.Op != OpARM64MOVDconst {
7375                         break
7376                 }
7377                 c := auxIntToInt64(v_1.AuxInt)
7378                 x := v_2
7379                 if !(isPowerOfTwo64(c)) {
7380                         break
7381                 }
7382                 v.reset(OpARM64MOVWUreg)
7383                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
7384                 v0.AuxInt = int64ToAuxInt(log64(c))
7385                 v0.AddArg2(a, x)
7386                 v.AddArg(v0)
7387                 return true
7388         }
7389         // match: (MADDW a (MOVDconst [c]) x)
7390         // cond: isPowerOfTwo64(c-1) && int32(c)>=3
7391         // result: (MOVWUreg (ADD <a.Type> a (ADDshiftLL <x.Type> x x [log64(c-1)])))
7392         for {
7393                 a := v_0
7394                 if v_1.Op != OpARM64MOVDconst {
7395                         break
7396                 }
7397                 c := auxIntToInt64(v_1.AuxInt)
7398                 x := v_2
7399                 if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
7400                         break
7401                 }
7402                 v.reset(OpARM64MOVWUreg)
7403                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
7404                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7405                 v1.AuxInt = int64ToAuxInt(log64(c - 1))
7406                 v1.AddArg2(x, x)
7407                 v0.AddArg2(a, v1)
7408                 v.AddArg(v0)
7409                 return true
7410         }
7411         // match: (MADDW a (MOVDconst [c]) x)
7412         // cond: isPowerOfTwo64(c+1) && int32(c)>=7
7413         // result: (MOVWUreg (SUB <a.Type> a (SUBshiftLL <x.Type> x x [log64(c+1)])))
7414         for {
7415                 a := v_0
7416                 if v_1.Op != OpARM64MOVDconst {
7417                         break
7418                 }
7419                 c := auxIntToInt64(v_1.AuxInt)
7420                 x := v_2
7421                 if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
7422                         break
7423                 }
7424                 v.reset(OpARM64MOVWUreg)
7425                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
7426                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7427                 v1.AuxInt = int64ToAuxInt(log64(c + 1))
7428                 v1.AddArg2(x, x)
7429                 v0.AddArg2(a, v1)
7430                 v.AddArg(v0)
7431                 return true
7432         }
7433         // match: (MADDW a (MOVDconst [c]) x)
7434         // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
7435         // result: (MOVWUreg (SUBshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]))
7436         for {
7437                 a := v_0
7438                 if v_1.Op != OpARM64MOVDconst {
7439                         break
7440                 }
7441                 c := auxIntToInt64(v_1.AuxInt)
7442                 x := v_2
7443                 if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
7444                         break
7445                 }
7446                 v.reset(OpARM64MOVWUreg)
7447                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
7448                 v0.AuxInt = int64ToAuxInt(log64(c / 3))
7449                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7450                 v1.AuxInt = int64ToAuxInt(2)
7451                 v1.AddArg2(x, x)
7452                 v0.AddArg2(a, v1)
7453                 v.AddArg(v0)
7454                 return true
7455         }
7456         // match: (MADDW a (MOVDconst [c]) x)
7457         // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
7458         // result: (MOVWUreg (ADDshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]))
7459         for {
7460                 a := v_0
7461                 if v_1.Op != OpARM64MOVDconst {
7462                         break
7463                 }
7464                 c := auxIntToInt64(v_1.AuxInt)
7465                 x := v_2
7466                 if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
7467                         break
7468                 }
7469                 v.reset(OpARM64MOVWUreg)
7470                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
7471                 v0.AuxInt = int64ToAuxInt(log64(c / 5))
7472                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7473                 v1.AuxInt = int64ToAuxInt(2)
7474                 v1.AddArg2(x, x)
7475                 v0.AddArg2(a, v1)
7476                 v.AddArg(v0)
7477                 return true
7478         }
7479         // match: (MADDW a (MOVDconst [c]) x)
7480         // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
7481         // result: (MOVWUreg (SUBshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]))
7482         for {
7483                 a := v_0
7484                 if v_1.Op != OpARM64MOVDconst {
7485                         break
7486                 }
7487                 c := auxIntToInt64(v_1.AuxInt)
7488                 x := v_2
7489                 if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
7490                         break
7491                 }
7492                 v.reset(OpARM64MOVWUreg)
7493                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
7494                 v0.AuxInt = int64ToAuxInt(log64(c / 7))
7495                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7496                 v1.AuxInt = int64ToAuxInt(3)
7497                 v1.AddArg2(x, x)
7498                 v0.AddArg2(a, v1)
7499                 v.AddArg(v0)
7500                 return true
7501         }
7502         // match: (MADDW a (MOVDconst [c]) x)
7503         // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
7504         // result: (MOVWUreg (ADDshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]))
7505         for {
7506                 a := v_0
7507                 if v_1.Op != OpARM64MOVDconst {
7508                         break
7509                 }
7510                 c := auxIntToInt64(v_1.AuxInt)
7511                 x := v_2
7512                 if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
7513                         break
7514                 }
7515                 v.reset(OpARM64MOVWUreg)
7516                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
7517                 v0.AuxInt = int64ToAuxInt(log64(c / 9))
7518                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7519                 v1.AuxInt = int64ToAuxInt(3)
7520                 v1.AddArg2(x, x)
7521                 v0.AddArg2(a, v1)
7522                 v.AddArg(v0)
7523                 return true
7524         }
7525         // match: (MADDW (MOVDconst [c]) x y)
7526         // result: (MOVWUreg (ADDconst <x.Type> [c] (MULW <x.Type> x y)))
7527         for {
7528                 if v_0.Op != OpARM64MOVDconst {
7529                         break
7530                 }
7531                 c := auxIntToInt64(v_0.AuxInt)
7532                 x := v_1
7533                 y := v_2
7534                 v.reset(OpARM64MOVWUreg)
7535                 v0 := b.NewValue0(v.Pos, OpARM64ADDconst, x.Type)
7536                 v0.AuxInt = int64ToAuxInt(c)
7537                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
7538                 v1.AddArg2(x, y)
7539                 v0.AddArg(v1)
7540                 v.AddArg(v0)
7541                 return true
7542         }
7543         // match: (MADDW a (MOVDconst [c]) (MOVDconst [d]))
7544         // result: (MOVWUreg (ADDconst <a.Type> [c*d] a))
7545         for {
7546                 a := v_0
7547                 if v_1.Op != OpARM64MOVDconst {
7548                         break
7549                 }
7550                 c := auxIntToInt64(v_1.AuxInt)
7551                 if v_2.Op != OpARM64MOVDconst {
7552                         break
7553                 }
7554                 d := auxIntToInt64(v_2.AuxInt)
7555                 v.reset(OpARM64MOVWUreg)
7556                 v0 := b.NewValue0(v.Pos, OpARM64ADDconst, a.Type)
7557                 v0.AuxInt = int64ToAuxInt(c * d)
7558                 v0.AddArg(a)
7559                 v.AddArg(v0)
7560                 return true
7561         }
7562         return false
7563 }
7564 func rewriteValueARM64_OpARM64MNEG(v *Value) bool {
7565         v_1 := v.Args[1]
7566         v_0 := v.Args[0]
7567         b := v.Block
7568         // match: (MNEG x (MOVDconst [-1]))
7569         // result: x
7570         for {
7571                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7572                         x := v_0
7573                         if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
7574                                 continue
7575                         }
7576                         v.copyOf(x)
7577                         return true
7578                 }
7579                 break
7580         }
7581         // match: (MNEG _ (MOVDconst [0]))
7582         // result: (MOVDconst [0])
7583         for {
7584                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7585                         if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
7586                                 continue
7587                         }
7588                         v.reset(OpARM64MOVDconst)
7589                         v.AuxInt = int64ToAuxInt(0)
7590                         return true
7591                 }
7592                 break
7593         }
7594         // match: (MNEG x (MOVDconst [1]))
7595         // result: (NEG x)
7596         for {
7597                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7598                         x := v_0
7599                         if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
7600                                 continue
7601                         }
7602                         v.reset(OpARM64NEG)
7603                         v.AddArg(x)
7604                         return true
7605                 }
7606                 break
7607         }
7608         // match: (MNEG x (MOVDconst [c]))
7609         // cond: isPowerOfTwo64(c)
7610         // result: (NEG (SLLconst <x.Type> [log64(c)] x))
7611         for {
7612                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7613                         x := v_0
7614                         if v_1.Op != OpARM64MOVDconst {
7615                                 continue
7616                         }
7617                         c := auxIntToInt64(v_1.AuxInt)
7618                         if !(isPowerOfTwo64(c)) {
7619                                 continue
7620                         }
7621                         v.reset(OpARM64NEG)
7622                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7623                         v0.AuxInt = int64ToAuxInt(log64(c))
7624                         v0.AddArg(x)
7625                         v.AddArg(v0)
7626                         return true
7627                 }
7628                 break
7629         }
7630         // match: (MNEG x (MOVDconst [c]))
7631         // cond: isPowerOfTwo64(c-1) && c >= 3
7632         // result: (NEG (ADDshiftLL <x.Type> x x [log64(c-1)]))
7633         for {
7634                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7635                         x := v_0
7636                         if v_1.Op != OpARM64MOVDconst {
7637                                 continue
7638                         }
7639                         c := auxIntToInt64(v_1.AuxInt)
7640                         if !(isPowerOfTwo64(c-1) && c >= 3) {
7641                                 continue
7642                         }
7643                         v.reset(OpARM64NEG)
7644                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7645                         v0.AuxInt = int64ToAuxInt(log64(c - 1))
7646                         v0.AddArg2(x, x)
7647                         v.AddArg(v0)
7648                         return true
7649                 }
7650                 break
7651         }
7652         // match: (MNEG x (MOVDconst [c]))
7653         // cond: isPowerOfTwo64(c+1) && c >= 7
7654         // result: (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)]))
7655         for {
7656                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7657                         x := v_0
7658                         if v_1.Op != OpARM64MOVDconst {
7659                                 continue
7660                         }
7661                         c := auxIntToInt64(v_1.AuxInt)
7662                         if !(isPowerOfTwo64(c+1) && c >= 7) {
7663                                 continue
7664                         }
7665                         v.reset(OpARM64NEG)
7666                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7667                         v0.AuxInt = int64ToAuxInt(log64(c + 1))
7668                         v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
7669                         v1.AddArg(x)
7670                         v0.AddArg2(v1, x)
7671                         v.AddArg(v0)
7672                         return true
7673                 }
7674                 break
7675         }
7676         // match: (MNEG x (MOVDconst [c]))
7677         // cond: c%3 == 0 && isPowerOfTwo64(c/3)
7678         // result: (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2]))
7679         for {
7680                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7681                         x := v_0
7682                         if v_1.Op != OpARM64MOVDconst {
7683                                 continue
7684                         }
7685                         c := auxIntToInt64(v_1.AuxInt)
7686                         if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
7687                                 continue
7688                         }
7689                         v.reset(OpARM64SLLconst)
7690                         v.Type = x.Type
7691                         v.AuxInt = int64ToAuxInt(log64(c / 3))
7692                         v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7693                         v0.AuxInt = int64ToAuxInt(2)
7694                         v0.AddArg2(x, x)
7695                         v.AddArg(v0)
7696                         return true
7697                 }
7698                 break
7699         }
7700         // match: (MNEG x (MOVDconst [c]))
7701         // cond: c%5 == 0 && isPowerOfTwo64(c/5)
7702         // result: (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2])))
7703         for {
7704                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7705                         x := v_0
7706                         if v_1.Op != OpARM64MOVDconst {
7707                                 continue
7708                         }
7709                         c := auxIntToInt64(v_1.AuxInt)
7710                         if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
7711                                 continue
7712                         }
7713                         v.reset(OpARM64NEG)
7714                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7715                         v0.AuxInt = int64ToAuxInt(log64(c / 5))
7716                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7717                         v1.AuxInt = int64ToAuxInt(2)
7718                         v1.AddArg2(x, x)
7719                         v0.AddArg(v1)
7720                         v.AddArg(v0)
7721                         return true
7722                 }
7723                 break
7724         }
7725         // match: (MNEG x (MOVDconst [c]))
7726         // cond: c%7 == 0 && isPowerOfTwo64(c/7)
7727         // result: (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3]))
7728         for {
7729                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7730                         x := v_0
7731                         if v_1.Op != OpARM64MOVDconst {
7732                                 continue
7733                         }
7734                         c := auxIntToInt64(v_1.AuxInt)
7735                         if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
7736                                 continue
7737                         }
7738                         v.reset(OpARM64SLLconst)
7739                         v.Type = x.Type
7740                         v.AuxInt = int64ToAuxInt(log64(c / 7))
7741                         v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7742                         v0.AuxInt = int64ToAuxInt(3)
7743                         v0.AddArg2(x, x)
7744                         v.AddArg(v0)
7745                         return true
7746                 }
7747                 break
7748         }
7749         // match: (MNEG x (MOVDconst [c]))
7750         // cond: c%9 == 0 && isPowerOfTwo64(c/9)
7751         // result: (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3])))
7752         for {
7753                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7754                         x := v_0
7755                         if v_1.Op != OpARM64MOVDconst {
7756                                 continue
7757                         }
7758                         c := auxIntToInt64(v_1.AuxInt)
7759                         if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
7760                                 continue
7761                         }
7762                         v.reset(OpARM64NEG)
7763                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7764                         v0.AuxInt = int64ToAuxInt(log64(c / 9))
7765                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7766                         v1.AuxInt = int64ToAuxInt(3)
7767                         v1.AddArg2(x, x)
7768                         v0.AddArg(v1)
7769                         v.AddArg(v0)
7770                         return true
7771                 }
7772                 break
7773         }
7774         // match: (MNEG (MOVDconst [c]) (MOVDconst [d]))
7775         // result: (MOVDconst [-c*d])
7776         for {
7777                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7778                         if v_0.Op != OpARM64MOVDconst {
7779                                 continue
7780                         }
7781                         c := auxIntToInt64(v_0.AuxInt)
7782                         if v_1.Op != OpARM64MOVDconst {
7783                                 continue
7784                         }
7785                         d := auxIntToInt64(v_1.AuxInt)
7786                         v.reset(OpARM64MOVDconst)
7787                         v.AuxInt = int64ToAuxInt(-c * d)
7788                         return true
7789                 }
7790                 break
7791         }
7792         return false
7793 }
7794 func rewriteValueARM64_OpARM64MNEGW(v *Value) bool {
7795         v_1 := v.Args[1]
7796         v_0 := v.Args[0]
7797         b := v.Block
7798         // match: (MNEGW x (MOVDconst [c]))
7799         // cond: int32(c)==-1
7800         // result: (MOVWUreg x)
7801         for {
7802                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7803                         x := v_0
7804                         if v_1.Op != OpARM64MOVDconst {
7805                                 continue
7806                         }
7807                         c := auxIntToInt64(v_1.AuxInt)
7808                         if !(int32(c) == -1) {
7809                                 continue
7810                         }
7811                         v.reset(OpARM64MOVWUreg)
7812                         v.AddArg(x)
7813                         return true
7814                 }
7815                 break
7816         }
7817         // match: (MNEGW _ (MOVDconst [c]))
7818         // cond: int32(c)==0
7819         // result: (MOVDconst [0])
7820         for {
7821                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7822                         if v_1.Op != OpARM64MOVDconst {
7823                                 continue
7824                         }
7825                         c := auxIntToInt64(v_1.AuxInt)
7826                         if !(int32(c) == 0) {
7827                                 continue
7828                         }
7829                         v.reset(OpARM64MOVDconst)
7830                         v.AuxInt = int64ToAuxInt(0)
7831                         return true
7832                 }
7833                 break
7834         }
7835         // match: (MNEGW x (MOVDconst [c]))
7836         // cond: int32(c)==1
7837         // result: (MOVWUreg (NEG <x.Type> x))
7838         for {
7839                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7840                         x := v_0
7841                         if v_1.Op != OpARM64MOVDconst {
7842                                 continue
7843                         }
7844                         c := auxIntToInt64(v_1.AuxInt)
7845                         if !(int32(c) == 1) {
7846                                 continue
7847                         }
7848                         v.reset(OpARM64MOVWUreg)
7849                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
7850                         v0.AddArg(x)
7851                         v.AddArg(v0)
7852                         return true
7853                 }
7854                 break
7855         }
7856         // match: (MNEGW x (MOVDconst [c]))
7857         // cond: isPowerOfTwo64(c)
7858         // result: (NEG (SLLconst <x.Type> [log64(c)] x))
7859         for {
7860                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7861                         x := v_0
7862                         if v_1.Op != OpARM64MOVDconst {
7863                                 continue
7864                         }
7865                         c := auxIntToInt64(v_1.AuxInt)
7866                         if !(isPowerOfTwo64(c)) {
7867                                 continue
7868                         }
7869                         v.reset(OpARM64NEG)
7870                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7871                         v0.AuxInt = int64ToAuxInt(log64(c))
7872                         v0.AddArg(x)
7873                         v.AddArg(v0)
7874                         return true
7875                 }
7876                 break
7877         }
7878         // match: (MNEGW x (MOVDconst [c]))
7879         // cond: isPowerOfTwo64(c-1) && int32(c) >= 3
7880         // result: (MOVWUreg (NEG <x.Type> (ADDshiftLL <x.Type> x x [log64(c-1)])))
7881         for {
7882                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7883                         x := v_0
7884                         if v_1.Op != OpARM64MOVDconst {
7885                                 continue
7886                         }
7887                         c := auxIntToInt64(v_1.AuxInt)
7888                         if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
7889                                 continue
7890                         }
7891                         v.reset(OpARM64MOVWUreg)
7892                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
7893                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7894                         v1.AuxInt = int64ToAuxInt(log64(c - 1))
7895                         v1.AddArg2(x, x)
7896                         v0.AddArg(v1)
7897                         v.AddArg(v0)
7898                         return true
7899                 }
7900                 break
7901         }
7902         // match: (MNEGW x (MOVDconst [c]))
7903         // cond: isPowerOfTwo64(c+1) && int32(c) >= 7
7904         // result: (MOVWUreg (NEG <x.Type> (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)])))
7905         for {
7906                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7907                         x := v_0
7908                         if v_1.Op != OpARM64MOVDconst {
7909                                 continue
7910                         }
7911                         c := auxIntToInt64(v_1.AuxInt)
7912                         if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
7913                                 continue
7914                         }
7915                         v.reset(OpARM64MOVWUreg)
7916                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
7917                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7918                         v1.AuxInt = int64ToAuxInt(log64(c + 1))
7919                         v2 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
7920                         v2.AddArg(x)
7921                         v1.AddArg2(v2, x)
7922                         v0.AddArg(v1)
7923                         v.AddArg(v0)
7924                         return true
7925                 }
7926                 break
7927         }
7928         // match: (MNEGW x (MOVDconst [c]))
7929         // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
7930         // result: (MOVWUreg (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2])))
7931         for {
7932                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7933                         x := v_0
7934                         if v_1.Op != OpARM64MOVDconst {
7935                                 continue
7936                         }
7937                         c := auxIntToInt64(v_1.AuxInt)
7938                         if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
7939                                 continue
7940                         }
7941                         v.reset(OpARM64MOVWUreg)
7942                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7943                         v0.AuxInt = int64ToAuxInt(log64(c / 3))
7944                         v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7945                         v1.AuxInt = int64ToAuxInt(2)
7946                         v1.AddArg2(x, x)
7947                         v0.AddArg(v1)
7948                         v.AddArg(v0)
7949                         return true
7950                 }
7951                 break
7952         }
7953         // match: (MNEGW x (MOVDconst [c]))
7954         // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
7955         // result: (MOVWUreg (NEG <x.Type> (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))))
7956         for {
7957                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7958                         x := v_0
7959                         if v_1.Op != OpARM64MOVDconst {
7960                                 continue
7961                         }
7962                         c := auxIntToInt64(v_1.AuxInt)
7963                         if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
7964                                 continue
7965                         }
7966                         v.reset(OpARM64MOVWUreg)
7967                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
7968                         v1 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7969                         v1.AuxInt = int64ToAuxInt(log64(c / 5))
7970                         v2 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
7971                         v2.AuxInt = int64ToAuxInt(2)
7972                         v2.AddArg2(x, x)
7973                         v1.AddArg(v2)
7974                         v0.AddArg(v1)
7975                         v.AddArg(v0)
7976                         return true
7977                 }
7978                 break
7979         }
7980         // match: (MNEGW x (MOVDconst [c]))
7981         // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
7982         // result: (MOVWUreg (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3])))
7983         for {
7984                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
7985                         x := v_0
7986                         if v_1.Op != OpARM64MOVDconst {
7987                                 continue
7988                         }
7989                         c := auxIntToInt64(v_1.AuxInt)
7990                         if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
7991                                 continue
7992                         }
7993                         v.reset(OpARM64MOVWUreg)
7994                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
7995                         v0.AuxInt = int64ToAuxInt(log64(c / 7))
7996                         v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
7997                         v1.AuxInt = int64ToAuxInt(3)
7998                         v1.AddArg2(x, x)
7999                         v0.AddArg(v1)
8000                         v.AddArg(v0)
8001                         return true
8002                 }
8003                 break
8004         }
8005         // match: (MNEGW x (MOVDconst [c]))
8006         // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
8007         // result: (MOVWUreg (NEG <x.Type> (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))))
8008         for {
8009                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
8010                         x := v_0
8011                         if v_1.Op != OpARM64MOVDconst {
8012                                 continue
8013                         }
8014                         c := auxIntToInt64(v_1.AuxInt)
8015                         if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
8016                                 continue
8017                         }
8018                         v.reset(OpARM64MOVWUreg)
8019                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
8020                         v1 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
8021                         v1.AuxInt = int64ToAuxInt(log64(c / 9))
8022                         v2 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
8023                         v2.AuxInt = int64ToAuxInt(3)
8024                         v2.AddArg2(x, x)
8025                         v1.AddArg(v2)
8026                         v0.AddArg(v1)
8027                         v.AddArg(v0)
8028                         return true
8029                 }
8030                 break
8031         }
8032         // match: (MNEGW (MOVDconst [c]) (MOVDconst [d]))
8033         // result: (MOVDconst [int64(uint32(-c*d))])
8034         for {
8035                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
8036                         if v_0.Op != OpARM64MOVDconst {
8037                                 continue
8038                         }
8039                         c := auxIntToInt64(v_0.AuxInt)
8040                         if v_1.Op != OpARM64MOVDconst {
8041                                 continue
8042                         }
8043                         d := auxIntToInt64(v_1.AuxInt)
8044                         v.reset(OpARM64MOVDconst)
8045                         v.AuxInt = int64ToAuxInt(int64(uint32(-c * d)))
8046                         return true
8047                 }
8048                 break
8049         }
8050         return false
8051 }
8052 func rewriteValueARM64_OpARM64MOD(v *Value) bool {
8053         v_1 := v.Args[1]
8054         v_0 := v.Args[0]
8055         // match: (MOD (MOVDconst [c]) (MOVDconst [d]))
8056         // cond: d != 0
8057         // result: (MOVDconst [c%d])
8058         for {
8059                 if v_0.Op != OpARM64MOVDconst {
8060                         break
8061                 }
8062                 c := auxIntToInt64(v_0.AuxInt)
8063                 if v_1.Op != OpARM64MOVDconst {
8064                         break
8065                 }
8066                 d := auxIntToInt64(v_1.AuxInt)
8067                 if !(d != 0) {
8068                         break
8069                 }
8070                 v.reset(OpARM64MOVDconst)
8071                 v.AuxInt = int64ToAuxInt(c % d)
8072                 return true
8073         }
8074         return false
8075 }
8076 func rewriteValueARM64_OpARM64MODW(v *Value) bool {
8077         v_1 := v.Args[1]
8078         v_0 := v.Args[0]
8079         // match: (MODW (MOVDconst [c]) (MOVDconst [d]))
8080         // cond: d != 0
8081         // result: (MOVDconst [int64(uint32(int32(c)%int32(d)))])
8082         for {
8083                 if v_0.Op != OpARM64MOVDconst {
8084                         break
8085                 }
8086                 c := auxIntToInt64(v_0.AuxInt)
8087                 if v_1.Op != OpARM64MOVDconst {
8088                         break
8089                 }
8090                 d := auxIntToInt64(v_1.AuxInt)
8091                 if !(d != 0) {
8092                         break
8093                 }
8094                 v.reset(OpARM64MOVDconst)
8095                 v.AuxInt = int64ToAuxInt(int64(uint32(int32(c) % int32(d))))
8096                 return true
8097         }
8098         return false
8099 }
8100 func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
8101         v_1 := v.Args[1]
8102         v_0 := v.Args[0]
8103         b := v.Block
8104         config := b.Func.Config
8105         // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
8106         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
8107         // result: (MOVBUload [off1+int32(off2)] {sym} ptr mem)
8108         for {
8109                 off1 := auxIntToInt32(v.AuxInt)
8110                 sym := auxToSym(v.Aux)
8111                 if v_0.Op != OpARM64ADDconst {
8112                         break
8113                 }
8114                 off2 := auxIntToInt64(v_0.AuxInt)
8115                 ptr := v_0.Args[0]
8116                 mem := v_1
8117                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
8118                         break
8119                 }
8120                 v.reset(OpARM64MOVBUload)
8121                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
8122                 v.Aux = symToAux(sym)
8123                 v.AddArg2(ptr, mem)
8124                 return true
8125         }
8126         // match: (MOVBUload [off] {sym} (ADD ptr idx) mem)
8127         // cond: off == 0 && sym == nil
8128         // result: (MOVBUloadidx ptr idx mem)
8129         for {
8130                 off := auxIntToInt32(v.AuxInt)
8131                 sym := auxToSym(v.Aux)
8132                 if v_0.Op != OpARM64ADD {
8133                         break
8134                 }
8135                 idx := v_0.Args[1]
8136                 ptr := v_0.Args[0]
8137                 mem := v_1
8138                 if !(off == 0 && sym == nil) {
8139                         break
8140                 }
8141                 v.reset(OpARM64MOVBUloadidx)
8142                 v.AddArg3(ptr, idx, mem)
8143                 return true
8144         }
8145         // match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
8146         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
8147         // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
8148         for {
8149                 off1 := auxIntToInt32(v.AuxInt)
8150                 sym1 := auxToSym(v.Aux)
8151                 if v_0.Op != OpARM64MOVDaddr {
8152                         break
8153                 }
8154                 off2 := auxIntToInt32(v_0.AuxInt)
8155                 sym2 := auxToSym(v_0.Aux)
8156                 ptr := v_0.Args[0]
8157                 mem := v_1
8158                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
8159                         break
8160                 }
8161                 v.reset(OpARM64MOVBUload)
8162                 v.AuxInt = int32ToAuxInt(off1 + off2)
8163                 v.Aux = symToAux(mergeSym(sym1, sym2))
8164                 v.AddArg2(ptr, mem)
8165                 return true
8166         }
8167         // match: (MOVBUload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _))
8168         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
8169         // result: (MOVDconst [0])
8170         for {
8171                 off := auxIntToInt32(v.AuxInt)
8172                 sym := auxToSym(v.Aux)
8173                 ptr := v_0
8174                 if v_1.Op != OpARM64MOVBstorezero {
8175                         break
8176                 }
8177                 off2 := auxIntToInt32(v_1.AuxInt)
8178                 sym2 := auxToSym(v_1.Aux)
8179                 ptr2 := v_1.Args[0]
8180                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
8181                         break
8182                 }
8183                 v.reset(OpARM64MOVDconst)
8184                 v.AuxInt = int64ToAuxInt(0)
8185                 return true
8186         }
8187         // match: (MOVBUload [off] {sym} (SB) _)
8188         // cond: symIsRO(sym)
8189         // result: (MOVDconst [int64(read8(sym, int64(off)))])
8190         for {
8191                 off := auxIntToInt32(v.AuxInt)
8192                 sym := auxToSym(v.Aux)
8193                 if v_0.Op != OpSB || !(symIsRO(sym)) {
8194                         break
8195                 }
8196                 v.reset(OpARM64MOVDconst)
8197                 v.AuxInt = int64ToAuxInt(int64(read8(sym, int64(off))))
8198                 return true
8199         }
8200         return false
8201 }
8202 func rewriteValueARM64_OpARM64MOVBUloadidx(v *Value) bool {
8203         v_2 := v.Args[2]
8204         v_1 := v.Args[1]
8205         v_0 := v.Args[0]
8206         // match: (MOVBUloadidx ptr (MOVDconst [c]) mem)
8207         // cond: is32Bit(c)
8208         // result: (MOVBUload [int32(c)] ptr mem)
8209         for {
8210                 ptr := v_0
8211                 if v_1.Op != OpARM64MOVDconst {
8212                         break
8213                 }
8214                 c := auxIntToInt64(v_1.AuxInt)
8215                 mem := v_2
8216                 if !(is32Bit(c)) {
8217                         break
8218                 }
8219                 v.reset(OpARM64MOVBUload)
8220                 v.AuxInt = int32ToAuxInt(int32(c))
8221                 v.AddArg2(ptr, mem)
8222                 return true
8223         }
8224         // match: (MOVBUloadidx (MOVDconst [c]) ptr mem)
8225         // cond: is32Bit(c)
8226         // result: (MOVBUload [int32(c)] ptr mem)
8227         for {
8228                 if v_0.Op != OpARM64MOVDconst {
8229                         break
8230                 }
8231                 c := auxIntToInt64(v_0.AuxInt)
8232                 ptr := v_1
8233                 mem := v_2
8234                 if !(is32Bit(c)) {
8235                         break
8236                 }
8237                 v.reset(OpARM64MOVBUload)
8238                 v.AuxInt = int32ToAuxInt(int32(c))
8239                 v.AddArg2(ptr, mem)
8240                 return true
8241         }
8242         // match: (MOVBUloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
8243         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
8244         // result: (MOVDconst [0])
8245         for {
8246                 ptr := v_0
8247                 idx := v_1
8248                 if v_2.Op != OpARM64MOVBstorezeroidx {
8249                         break
8250                 }
8251                 idx2 := v_2.Args[1]
8252                 ptr2 := v_2.Args[0]
8253                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
8254                         break
8255                 }
8256                 v.reset(OpARM64MOVDconst)
8257                 v.AuxInt = int64ToAuxInt(0)
8258                 return true
8259         }
8260         return false
8261 }
8262 func rewriteValueARM64_OpARM64MOVBUreg(v *Value) bool {
8263         v_0 := v.Args[0]
8264         // match: (MOVBUreg x:(MOVBUload _ _))
8265         // result: (MOVDreg x)
8266         for {
8267                 x := v_0
8268                 if x.Op != OpARM64MOVBUload {
8269                         break
8270                 }
8271                 v.reset(OpARM64MOVDreg)
8272                 v.AddArg(x)
8273                 return true
8274         }
8275         // match: (MOVBUreg x:(MOVBUloadidx _ _ _))
8276         // result: (MOVDreg x)
8277         for {
8278                 x := v_0
8279                 if x.Op != OpARM64MOVBUloadidx {
8280                         break
8281                 }
8282                 v.reset(OpARM64MOVDreg)
8283                 v.AddArg(x)
8284                 return true
8285         }
8286         // match: (MOVBUreg x:(MOVBUreg _))
8287         // result: (MOVDreg x)
8288         for {
8289                 x := v_0
8290                 if x.Op != OpARM64MOVBUreg {
8291                         break
8292                 }
8293                 v.reset(OpARM64MOVDreg)
8294                 v.AddArg(x)
8295                 return true
8296         }
8297         // match: (MOVBUreg (ANDconst [c] x))
8298         // result: (ANDconst [c&(1<<8-1)] x)
8299         for {
8300                 if v_0.Op != OpARM64ANDconst {
8301                         break
8302                 }
8303                 c := auxIntToInt64(v_0.AuxInt)
8304                 x := v_0.Args[0]
8305                 v.reset(OpARM64ANDconst)
8306                 v.AuxInt = int64ToAuxInt(c & (1<<8 - 1))
8307                 v.AddArg(x)
8308                 return true
8309         }
8310         // match: (MOVBUreg (MOVDconst [c]))
8311         // result: (MOVDconst [int64(uint8(c))])
8312         for {
8313                 if v_0.Op != OpARM64MOVDconst {
8314                         break
8315                 }
8316                 c := auxIntToInt64(v_0.AuxInt)
8317                 v.reset(OpARM64MOVDconst)
8318                 v.AuxInt = int64ToAuxInt(int64(uint8(c)))
8319                 return true
8320         }
8321         // match: (MOVBUreg x:(Equal _))
8322         // result: (MOVDreg x)
8323         for {
8324                 x := v_0
8325                 if x.Op != OpARM64Equal {
8326                         break
8327                 }
8328                 v.reset(OpARM64MOVDreg)
8329                 v.AddArg(x)
8330                 return true
8331         }
8332         // match: (MOVBUreg x:(NotEqual _))
8333         // result: (MOVDreg x)
8334         for {
8335                 x := v_0
8336                 if x.Op != OpARM64NotEqual {
8337                         break
8338                 }
8339                 v.reset(OpARM64MOVDreg)
8340                 v.AddArg(x)
8341                 return true
8342         }
8343         // match: (MOVBUreg x:(LessThan _))
8344         // result: (MOVDreg x)
8345         for {
8346                 x := v_0
8347                 if x.Op != OpARM64LessThan {
8348                         break
8349                 }
8350                 v.reset(OpARM64MOVDreg)
8351                 v.AddArg(x)
8352                 return true
8353         }
8354         // match: (MOVBUreg x:(LessThanU _))
8355         // result: (MOVDreg x)
8356         for {
8357                 x := v_0
8358                 if x.Op != OpARM64LessThanU {
8359                         break
8360                 }
8361                 v.reset(OpARM64MOVDreg)
8362                 v.AddArg(x)
8363                 return true
8364         }
8365         // match: (MOVBUreg x:(LessThanF _))
8366         // result: (MOVDreg x)
8367         for {
8368                 x := v_0
8369                 if x.Op != OpARM64LessThanF {
8370                         break
8371                 }
8372                 v.reset(OpARM64MOVDreg)
8373                 v.AddArg(x)
8374                 return true
8375         }
8376         // match: (MOVBUreg x:(LessEqual _))
8377         // result: (MOVDreg x)
8378         for {
8379                 x := v_0
8380                 if x.Op != OpARM64LessEqual {
8381                         break
8382                 }
8383                 v.reset(OpARM64MOVDreg)
8384                 v.AddArg(x)
8385                 return true
8386         }
8387         // match: (MOVBUreg x:(LessEqualU _))
8388         // result: (MOVDreg x)
8389         for {
8390                 x := v_0
8391                 if x.Op != OpARM64LessEqualU {
8392                         break
8393                 }
8394                 v.reset(OpARM64MOVDreg)
8395                 v.AddArg(x)
8396                 return true
8397         }
8398         // match: (MOVBUreg x:(LessEqualF _))
8399         // result: (MOVDreg x)
8400         for {
8401                 x := v_0
8402                 if x.Op != OpARM64LessEqualF {
8403                         break
8404                 }
8405                 v.reset(OpARM64MOVDreg)
8406                 v.AddArg(x)
8407                 return true
8408         }
8409         // match: (MOVBUreg x:(GreaterThan _))
8410         // result: (MOVDreg x)
8411         for {
8412                 x := v_0
8413                 if x.Op != OpARM64GreaterThan {
8414                         break
8415                 }
8416                 v.reset(OpARM64MOVDreg)
8417                 v.AddArg(x)
8418                 return true
8419         }
8420         // match: (MOVBUreg x:(GreaterThanU _))
8421         // result: (MOVDreg x)
8422         for {
8423                 x := v_0
8424                 if x.Op != OpARM64GreaterThanU {
8425                         break
8426                 }
8427                 v.reset(OpARM64MOVDreg)
8428                 v.AddArg(x)
8429                 return true
8430         }
8431         // match: (MOVBUreg x:(GreaterThanF _))
8432         // result: (MOVDreg x)
8433         for {
8434                 x := v_0
8435                 if x.Op != OpARM64GreaterThanF {
8436                         break
8437                 }
8438                 v.reset(OpARM64MOVDreg)
8439                 v.AddArg(x)
8440                 return true
8441         }
8442         // match: (MOVBUreg x:(GreaterEqual _))
8443         // result: (MOVDreg x)
8444         for {
8445                 x := v_0
8446                 if x.Op != OpARM64GreaterEqual {
8447                         break
8448                 }
8449                 v.reset(OpARM64MOVDreg)
8450                 v.AddArg(x)
8451                 return true
8452         }
8453         // match: (MOVBUreg x:(GreaterEqualU _))
8454         // result: (MOVDreg x)
8455         for {
8456                 x := v_0
8457                 if x.Op != OpARM64GreaterEqualU {
8458                         break
8459                 }
8460                 v.reset(OpARM64MOVDreg)
8461                 v.AddArg(x)
8462                 return true
8463         }
8464         // match: (MOVBUreg x:(GreaterEqualF _))
8465         // result: (MOVDreg x)
8466         for {
8467                 x := v_0
8468                 if x.Op != OpARM64GreaterEqualF {
8469                         break
8470                 }
8471                 v.reset(OpARM64MOVDreg)
8472                 v.AddArg(x)
8473                 return true
8474         }
8475         // match: (MOVBUreg x)
8476         // cond: v.Type.Size() <= 1
8477         // result: x
8478         for {
8479                 x := v_0
8480                 if !(v.Type.Size() <= 1) {
8481                         break
8482                 }
8483                 v.copyOf(x)
8484                 return true
8485         }
8486         // match: (MOVBUreg (SLLconst [lc] x))
8487         // cond: lc >= 8
8488         // result: (MOVDconst [0])
8489         for {
8490                 if v_0.Op != OpARM64SLLconst {
8491                         break
8492                 }
8493                 lc := auxIntToInt64(v_0.AuxInt)
8494                 if !(lc >= 8) {
8495                         break
8496                 }
8497                 v.reset(OpARM64MOVDconst)
8498                 v.AuxInt = int64ToAuxInt(0)
8499                 return true
8500         }
8501         // match: (MOVBUreg (SLLconst [lc] x))
8502         // cond: lc < 8
8503         // result: (UBFIZ [armBFAuxInt(lc, 8-lc)] x)
8504         for {
8505                 if v_0.Op != OpARM64SLLconst {
8506                         break
8507                 }
8508                 lc := auxIntToInt64(v_0.AuxInt)
8509                 x := v_0.Args[0]
8510                 if !(lc < 8) {
8511                         break
8512                 }
8513                 v.reset(OpARM64UBFIZ)
8514                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 8-lc))
8515                 v.AddArg(x)
8516                 return true
8517         }
8518         // match: (MOVBUreg (SRLconst [rc] x))
8519         // cond: rc < 8
8520         // result: (UBFX [armBFAuxInt(rc, 8)] x)
8521         for {
8522                 if v_0.Op != OpARM64SRLconst {
8523                         break
8524                 }
8525                 rc := auxIntToInt64(v_0.AuxInt)
8526                 x := v_0.Args[0]
8527                 if !(rc < 8) {
8528                         break
8529                 }
8530                 v.reset(OpARM64UBFX)
8531                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 8))
8532                 v.AddArg(x)
8533                 return true
8534         }
8535         // match: (MOVBUreg (UBFX [bfc] x))
8536         // cond: bfc.getARM64BFwidth() <= 8
8537         // result: (UBFX [bfc] x)
8538         for {
8539                 if v_0.Op != OpARM64UBFX {
8540                         break
8541                 }
8542                 bfc := auxIntToArm64BitField(v_0.AuxInt)
8543                 x := v_0.Args[0]
8544                 if !(bfc.getARM64BFwidth() <= 8) {
8545                         break
8546                 }
8547                 v.reset(OpARM64UBFX)
8548                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
8549                 v.AddArg(x)
8550                 return true
8551         }
8552         return false
8553 }
8554 func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
8555         v_1 := v.Args[1]
8556         v_0 := v.Args[0]
8557         b := v.Block
8558         config := b.Func.Config
8559         // match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
8560         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
8561         // result: (MOVBload [off1+int32(off2)] {sym} ptr mem)
8562         for {
8563                 off1 := auxIntToInt32(v.AuxInt)
8564                 sym := auxToSym(v.Aux)
8565                 if v_0.Op != OpARM64ADDconst {
8566                         break
8567                 }
8568                 off2 := auxIntToInt64(v_0.AuxInt)
8569                 ptr := v_0.Args[0]
8570                 mem := v_1
8571                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
8572                         break
8573                 }
8574                 v.reset(OpARM64MOVBload)
8575                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
8576                 v.Aux = symToAux(sym)
8577                 v.AddArg2(ptr, mem)
8578                 return true
8579         }
8580         // match: (MOVBload [off] {sym} (ADD ptr idx) mem)
8581         // cond: off == 0 && sym == nil
8582         // result: (MOVBloadidx ptr idx mem)
8583         for {
8584                 off := auxIntToInt32(v.AuxInt)
8585                 sym := auxToSym(v.Aux)
8586                 if v_0.Op != OpARM64ADD {
8587                         break
8588                 }
8589                 idx := v_0.Args[1]
8590                 ptr := v_0.Args[0]
8591                 mem := v_1
8592                 if !(off == 0 && sym == nil) {
8593                         break
8594                 }
8595                 v.reset(OpARM64MOVBloadidx)
8596                 v.AddArg3(ptr, idx, mem)
8597                 return true
8598         }
8599         // match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
8600         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
8601         // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
8602         for {
8603                 off1 := auxIntToInt32(v.AuxInt)
8604                 sym1 := auxToSym(v.Aux)
8605                 if v_0.Op != OpARM64MOVDaddr {
8606                         break
8607                 }
8608                 off2 := auxIntToInt32(v_0.AuxInt)
8609                 sym2 := auxToSym(v_0.Aux)
8610                 ptr := v_0.Args[0]
8611                 mem := v_1
8612                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
8613                         break
8614                 }
8615                 v.reset(OpARM64MOVBload)
8616                 v.AuxInt = int32ToAuxInt(off1 + off2)
8617                 v.Aux = symToAux(mergeSym(sym1, sym2))
8618                 v.AddArg2(ptr, mem)
8619                 return true
8620         }
8621         // match: (MOVBload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _))
8622         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
8623         // result: (MOVDconst [0])
8624         for {
8625                 off := auxIntToInt32(v.AuxInt)
8626                 sym := auxToSym(v.Aux)
8627                 ptr := v_0
8628                 if v_1.Op != OpARM64MOVBstorezero {
8629                         break
8630                 }
8631                 off2 := auxIntToInt32(v_1.AuxInt)
8632                 sym2 := auxToSym(v_1.Aux)
8633                 ptr2 := v_1.Args[0]
8634                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
8635                         break
8636                 }
8637                 v.reset(OpARM64MOVDconst)
8638                 v.AuxInt = int64ToAuxInt(0)
8639                 return true
8640         }
8641         return false
8642 }
8643 func rewriteValueARM64_OpARM64MOVBloadidx(v *Value) bool {
8644         v_2 := v.Args[2]
8645         v_1 := v.Args[1]
8646         v_0 := v.Args[0]
8647         // match: (MOVBloadidx ptr (MOVDconst [c]) mem)
8648         // cond: is32Bit(c)
8649         // result: (MOVBload [int32(c)] ptr mem)
8650         for {
8651                 ptr := v_0
8652                 if v_1.Op != OpARM64MOVDconst {
8653                         break
8654                 }
8655                 c := auxIntToInt64(v_1.AuxInt)
8656                 mem := v_2
8657                 if !(is32Bit(c)) {
8658                         break
8659                 }
8660                 v.reset(OpARM64MOVBload)
8661                 v.AuxInt = int32ToAuxInt(int32(c))
8662                 v.AddArg2(ptr, mem)
8663                 return true
8664         }
8665         // match: (MOVBloadidx (MOVDconst [c]) ptr mem)
8666         // cond: is32Bit(c)
8667         // result: (MOVBload [int32(c)] ptr mem)
8668         for {
8669                 if v_0.Op != OpARM64MOVDconst {
8670                         break
8671                 }
8672                 c := auxIntToInt64(v_0.AuxInt)
8673                 ptr := v_1
8674                 mem := v_2
8675                 if !(is32Bit(c)) {
8676                         break
8677                 }
8678                 v.reset(OpARM64MOVBload)
8679                 v.AuxInt = int32ToAuxInt(int32(c))
8680                 v.AddArg2(ptr, mem)
8681                 return true
8682         }
8683         // match: (MOVBloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
8684         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
8685         // result: (MOVDconst [0])
8686         for {
8687                 ptr := v_0
8688                 idx := v_1
8689                 if v_2.Op != OpARM64MOVBstorezeroidx {
8690                         break
8691                 }
8692                 idx2 := v_2.Args[1]
8693                 ptr2 := v_2.Args[0]
8694                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
8695                         break
8696                 }
8697                 v.reset(OpARM64MOVDconst)
8698                 v.AuxInt = int64ToAuxInt(0)
8699                 return true
8700         }
8701         return false
8702 }
8703 func rewriteValueARM64_OpARM64MOVBreg(v *Value) bool {
8704         v_0 := v.Args[0]
8705         // match: (MOVBreg x:(MOVBload _ _))
8706         // result: (MOVDreg x)
8707         for {
8708                 x := v_0
8709                 if x.Op != OpARM64MOVBload {
8710                         break
8711                 }
8712                 v.reset(OpARM64MOVDreg)
8713                 v.AddArg(x)
8714                 return true
8715         }
8716         // match: (MOVBreg x:(MOVBloadidx _ _ _))
8717         // result: (MOVDreg x)
8718         for {
8719                 x := v_0
8720                 if x.Op != OpARM64MOVBloadidx {
8721                         break
8722                 }
8723                 v.reset(OpARM64MOVDreg)
8724                 v.AddArg(x)
8725                 return true
8726         }
8727         // match: (MOVBreg x:(MOVBreg _))
8728         // result: (MOVDreg x)
8729         for {
8730                 x := v_0
8731                 if x.Op != OpARM64MOVBreg {
8732                         break
8733                 }
8734                 v.reset(OpARM64MOVDreg)
8735                 v.AddArg(x)
8736                 return true
8737         }
8738         // match: (MOVBreg (MOVDconst [c]))
8739         // result: (MOVDconst [int64(int8(c))])
8740         for {
8741                 if v_0.Op != OpARM64MOVDconst {
8742                         break
8743                 }
8744                 c := auxIntToInt64(v_0.AuxInt)
8745                 v.reset(OpARM64MOVDconst)
8746                 v.AuxInt = int64ToAuxInt(int64(int8(c)))
8747                 return true
8748         }
8749         // match: (MOVBreg x)
8750         // cond: v.Type.Size() <= 1
8751         // result: x
8752         for {
8753                 x := v_0
8754                 if !(v.Type.Size() <= 1) {
8755                         break
8756                 }
8757                 v.copyOf(x)
8758                 return true
8759         }
8760         // match: (MOVBreg <t> (ANDconst x [c]))
8761         // cond: uint64(c) & uint64(0xffffffffffffff80) == 0
8762         // result: (ANDconst <t> x [c])
8763         for {
8764                 t := v.Type
8765                 if v_0.Op != OpARM64ANDconst {
8766                         break
8767                 }
8768                 c := auxIntToInt64(v_0.AuxInt)
8769                 x := v_0.Args[0]
8770                 if !(uint64(c)&uint64(0xffffffffffffff80) == 0) {
8771                         break
8772                 }
8773                 v.reset(OpARM64ANDconst)
8774                 v.Type = t
8775                 v.AuxInt = int64ToAuxInt(c)
8776                 v.AddArg(x)
8777                 return true
8778         }
8779         // match: (MOVBreg (SLLconst [lc] x))
8780         // cond: lc < 8
8781         // result: (SBFIZ [armBFAuxInt(lc, 8-lc)] x)
8782         for {
8783                 if v_0.Op != OpARM64SLLconst {
8784                         break
8785                 }
8786                 lc := auxIntToInt64(v_0.AuxInt)
8787                 x := v_0.Args[0]
8788                 if !(lc < 8) {
8789                         break
8790                 }
8791                 v.reset(OpARM64SBFIZ)
8792                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 8-lc))
8793                 v.AddArg(x)
8794                 return true
8795         }
8796         // match: (MOVBreg (SBFX [bfc] x))
8797         // cond: bfc.getARM64BFwidth() <= 8
8798         // result: (SBFX [bfc] x)
8799         for {
8800                 if v_0.Op != OpARM64SBFX {
8801                         break
8802                 }
8803                 bfc := auxIntToArm64BitField(v_0.AuxInt)
8804                 x := v_0.Args[0]
8805                 if !(bfc.getARM64BFwidth() <= 8) {
8806                         break
8807                 }
8808                 v.reset(OpARM64SBFX)
8809                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
8810                 v.AddArg(x)
8811                 return true
8812         }
8813         return false
8814 }
8815 func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
8816         v_2 := v.Args[2]
8817         v_1 := v.Args[1]
8818         v_0 := v.Args[0]
8819         b := v.Block
8820         config := b.Func.Config
8821         // match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
8822         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
8823         // result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
8824         for {
8825                 off1 := auxIntToInt32(v.AuxInt)
8826                 sym := auxToSym(v.Aux)
8827                 if v_0.Op != OpARM64ADDconst {
8828                         break
8829                 }
8830                 off2 := auxIntToInt64(v_0.AuxInt)
8831                 ptr := v_0.Args[0]
8832                 val := v_1
8833                 mem := v_2
8834                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
8835                         break
8836                 }
8837                 v.reset(OpARM64MOVBstore)
8838                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
8839                 v.Aux = symToAux(sym)
8840                 v.AddArg3(ptr, val, mem)
8841                 return true
8842         }
8843         // match: (MOVBstore [off] {sym} (ADD ptr idx) val mem)
8844         // cond: off == 0 && sym == nil
8845         // result: (MOVBstoreidx ptr idx val mem)
8846         for {
8847                 off := auxIntToInt32(v.AuxInt)
8848                 sym := auxToSym(v.Aux)
8849                 if v_0.Op != OpARM64ADD {
8850                         break
8851                 }
8852                 idx := v_0.Args[1]
8853                 ptr := v_0.Args[0]
8854                 val := v_1
8855                 mem := v_2
8856                 if !(off == 0 && sym == nil) {
8857                         break
8858                 }
8859                 v.reset(OpARM64MOVBstoreidx)
8860                 v.AddArg4(ptr, idx, val, mem)
8861                 return true
8862         }
8863         // match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
8864         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
8865         // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
8866         for {
8867                 off1 := auxIntToInt32(v.AuxInt)
8868                 sym1 := auxToSym(v.Aux)
8869                 if v_0.Op != OpARM64MOVDaddr {
8870                         break
8871                 }
8872                 off2 := auxIntToInt32(v_0.AuxInt)
8873                 sym2 := auxToSym(v_0.Aux)
8874                 ptr := v_0.Args[0]
8875                 val := v_1
8876                 mem := v_2
8877                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
8878                         break
8879                 }
8880                 v.reset(OpARM64MOVBstore)
8881                 v.AuxInt = int32ToAuxInt(off1 + off2)
8882                 v.Aux = symToAux(mergeSym(sym1, sym2))
8883                 v.AddArg3(ptr, val, mem)
8884                 return true
8885         }
8886         // match: (MOVBstore [off] {sym} ptr (MOVDconst [0]) mem)
8887         // result: (MOVBstorezero [off] {sym} ptr mem)
8888         for {
8889                 off := auxIntToInt32(v.AuxInt)
8890                 sym := auxToSym(v.Aux)
8891                 ptr := v_0
8892                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
8893                         break
8894                 }
8895                 mem := v_2
8896                 v.reset(OpARM64MOVBstorezero)
8897                 v.AuxInt = int32ToAuxInt(off)
8898                 v.Aux = symToAux(sym)
8899                 v.AddArg2(ptr, mem)
8900                 return true
8901         }
8902         // match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem)
8903         // result: (MOVBstore [off] {sym} ptr x mem)
8904         for {
8905                 off := auxIntToInt32(v.AuxInt)
8906                 sym := auxToSym(v.Aux)
8907                 ptr := v_0
8908                 if v_1.Op != OpARM64MOVBreg {
8909                         break
8910                 }
8911                 x := v_1.Args[0]
8912                 mem := v_2
8913                 v.reset(OpARM64MOVBstore)
8914                 v.AuxInt = int32ToAuxInt(off)
8915                 v.Aux = symToAux(sym)
8916                 v.AddArg3(ptr, x, mem)
8917                 return true
8918         }
8919         // match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem)
8920         // result: (MOVBstore [off] {sym} ptr x mem)
8921         for {
8922                 off := auxIntToInt32(v.AuxInt)
8923                 sym := auxToSym(v.Aux)
8924                 ptr := v_0
8925                 if v_1.Op != OpARM64MOVBUreg {
8926                         break
8927                 }
8928                 x := v_1.Args[0]
8929                 mem := v_2
8930                 v.reset(OpARM64MOVBstore)
8931                 v.AuxInt = int32ToAuxInt(off)
8932                 v.Aux = symToAux(sym)
8933                 v.AddArg3(ptr, x, mem)
8934                 return true
8935         }
8936         // match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem)
8937         // result: (MOVBstore [off] {sym} ptr x mem)
8938         for {
8939                 off := auxIntToInt32(v.AuxInt)
8940                 sym := auxToSym(v.Aux)
8941                 ptr := v_0
8942                 if v_1.Op != OpARM64MOVHreg {
8943                         break
8944                 }
8945                 x := v_1.Args[0]
8946                 mem := v_2
8947                 v.reset(OpARM64MOVBstore)
8948                 v.AuxInt = int32ToAuxInt(off)
8949                 v.Aux = symToAux(sym)
8950                 v.AddArg3(ptr, x, mem)
8951                 return true
8952         }
8953         // match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem)
8954         // result: (MOVBstore [off] {sym} ptr x mem)
8955         for {
8956                 off := auxIntToInt32(v.AuxInt)
8957                 sym := auxToSym(v.Aux)
8958                 ptr := v_0
8959                 if v_1.Op != OpARM64MOVHUreg {
8960                         break
8961                 }
8962                 x := v_1.Args[0]
8963                 mem := v_2
8964                 v.reset(OpARM64MOVBstore)
8965                 v.AuxInt = int32ToAuxInt(off)
8966                 v.Aux = symToAux(sym)
8967                 v.AddArg3(ptr, x, mem)
8968                 return true
8969         }
8970         // match: (MOVBstore [off] {sym} ptr (MOVWreg x) mem)
8971         // result: (MOVBstore [off] {sym} ptr x mem)
8972         for {
8973                 off := auxIntToInt32(v.AuxInt)
8974                 sym := auxToSym(v.Aux)
8975                 ptr := v_0
8976                 if v_1.Op != OpARM64MOVWreg {
8977                         break
8978                 }
8979                 x := v_1.Args[0]
8980                 mem := v_2
8981                 v.reset(OpARM64MOVBstore)
8982                 v.AuxInt = int32ToAuxInt(off)
8983                 v.Aux = symToAux(sym)
8984                 v.AddArg3(ptr, x, mem)
8985                 return true
8986         }
8987         // match: (MOVBstore [off] {sym} ptr (MOVWUreg x) mem)
8988         // result: (MOVBstore [off] {sym} ptr x mem)
8989         for {
8990                 off := auxIntToInt32(v.AuxInt)
8991                 sym := auxToSym(v.Aux)
8992                 ptr := v_0
8993                 if v_1.Op != OpARM64MOVWUreg {
8994                         break
8995                 }
8996                 x := v_1.Args[0]
8997                 mem := v_2
8998                 v.reset(OpARM64MOVBstore)
8999                 v.AuxInt = int32ToAuxInt(off)
9000                 v.Aux = symToAux(sym)
9001                 v.AddArg3(ptr, x, mem)
9002                 return true
9003         }
9004         return false
9005 }
9006 func rewriteValueARM64_OpARM64MOVBstoreidx(v *Value) bool {
9007         v_3 := v.Args[3]
9008         v_2 := v.Args[2]
9009         v_1 := v.Args[1]
9010         v_0 := v.Args[0]
9011         // match: (MOVBstoreidx ptr (MOVDconst [c]) val mem)
9012         // cond: is32Bit(c)
9013         // result: (MOVBstore [int32(c)] ptr val mem)
9014         for {
9015                 ptr := v_0
9016                 if v_1.Op != OpARM64MOVDconst {
9017                         break
9018                 }
9019                 c := auxIntToInt64(v_1.AuxInt)
9020                 val := v_2
9021                 mem := v_3
9022                 if !(is32Bit(c)) {
9023                         break
9024                 }
9025                 v.reset(OpARM64MOVBstore)
9026                 v.AuxInt = int32ToAuxInt(int32(c))
9027                 v.AddArg3(ptr, val, mem)
9028                 return true
9029         }
9030         // match: (MOVBstoreidx (MOVDconst [c]) idx val mem)
9031         // cond: is32Bit(c)
9032         // result: (MOVBstore [int32(c)] idx val mem)
9033         for {
9034                 if v_0.Op != OpARM64MOVDconst {
9035                         break
9036                 }
9037                 c := auxIntToInt64(v_0.AuxInt)
9038                 idx := v_1
9039                 val := v_2
9040                 mem := v_3
9041                 if !(is32Bit(c)) {
9042                         break
9043                 }
9044                 v.reset(OpARM64MOVBstore)
9045                 v.AuxInt = int32ToAuxInt(int32(c))
9046                 v.AddArg3(idx, val, mem)
9047                 return true
9048         }
9049         // match: (MOVBstoreidx ptr idx (MOVDconst [0]) mem)
9050         // result: (MOVBstorezeroidx ptr idx mem)
9051         for {
9052                 ptr := v_0
9053                 idx := v_1
9054                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
9055                         break
9056                 }
9057                 mem := v_3
9058                 v.reset(OpARM64MOVBstorezeroidx)
9059                 v.AddArg3(ptr, idx, mem)
9060                 return true
9061         }
9062         // match: (MOVBstoreidx ptr idx (MOVBreg x) mem)
9063         // result: (MOVBstoreidx ptr idx x mem)
9064         for {
9065                 ptr := v_0
9066                 idx := v_1
9067                 if v_2.Op != OpARM64MOVBreg {
9068                         break
9069                 }
9070                 x := v_2.Args[0]
9071                 mem := v_3
9072                 v.reset(OpARM64MOVBstoreidx)
9073                 v.AddArg4(ptr, idx, x, mem)
9074                 return true
9075         }
9076         // match: (MOVBstoreidx ptr idx (MOVBUreg x) mem)
9077         // result: (MOVBstoreidx ptr idx x mem)
9078         for {
9079                 ptr := v_0
9080                 idx := v_1
9081                 if v_2.Op != OpARM64MOVBUreg {
9082                         break
9083                 }
9084                 x := v_2.Args[0]
9085                 mem := v_3
9086                 v.reset(OpARM64MOVBstoreidx)
9087                 v.AddArg4(ptr, idx, x, mem)
9088                 return true
9089         }
9090         // match: (MOVBstoreidx ptr idx (MOVHreg x) mem)
9091         // result: (MOVBstoreidx ptr idx x mem)
9092         for {
9093                 ptr := v_0
9094                 idx := v_1
9095                 if v_2.Op != OpARM64MOVHreg {
9096                         break
9097                 }
9098                 x := v_2.Args[0]
9099                 mem := v_3
9100                 v.reset(OpARM64MOVBstoreidx)
9101                 v.AddArg4(ptr, idx, x, mem)
9102                 return true
9103         }
9104         // match: (MOVBstoreidx ptr idx (MOVHUreg x) mem)
9105         // result: (MOVBstoreidx ptr idx x mem)
9106         for {
9107                 ptr := v_0
9108                 idx := v_1
9109                 if v_2.Op != OpARM64MOVHUreg {
9110                         break
9111                 }
9112                 x := v_2.Args[0]
9113                 mem := v_3
9114                 v.reset(OpARM64MOVBstoreidx)
9115                 v.AddArg4(ptr, idx, x, mem)
9116                 return true
9117         }
9118         // match: (MOVBstoreidx ptr idx (MOVWreg x) mem)
9119         // result: (MOVBstoreidx ptr idx x mem)
9120         for {
9121                 ptr := v_0
9122                 idx := v_1
9123                 if v_2.Op != OpARM64MOVWreg {
9124                         break
9125                 }
9126                 x := v_2.Args[0]
9127                 mem := v_3
9128                 v.reset(OpARM64MOVBstoreidx)
9129                 v.AddArg4(ptr, idx, x, mem)
9130                 return true
9131         }
9132         // match: (MOVBstoreidx ptr idx (MOVWUreg x) mem)
9133         // result: (MOVBstoreidx ptr idx x mem)
9134         for {
9135                 ptr := v_0
9136                 idx := v_1
9137                 if v_2.Op != OpARM64MOVWUreg {
9138                         break
9139                 }
9140                 x := v_2.Args[0]
9141                 mem := v_3
9142                 v.reset(OpARM64MOVBstoreidx)
9143                 v.AddArg4(ptr, idx, x, mem)
9144                 return true
9145         }
9146         return false
9147 }
9148 func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
9149         v_1 := v.Args[1]
9150         v_0 := v.Args[0]
9151         b := v.Block
9152         config := b.Func.Config
9153         // match: (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
9154         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9155         // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
9156         for {
9157                 off1 := auxIntToInt32(v.AuxInt)
9158                 sym := auxToSym(v.Aux)
9159                 if v_0.Op != OpARM64ADDconst {
9160                         break
9161                 }
9162                 off2 := auxIntToInt64(v_0.AuxInt)
9163                 ptr := v_0.Args[0]
9164                 mem := v_1
9165                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9166                         break
9167                 }
9168                 v.reset(OpARM64MOVBstorezero)
9169                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
9170                 v.Aux = symToAux(sym)
9171                 v.AddArg2(ptr, mem)
9172                 return true
9173         }
9174         // match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
9175         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9176         // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
9177         for {
9178                 off1 := auxIntToInt32(v.AuxInt)
9179                 sym1 := auxToSym(v.Aux)
9180                 if v_0.Op != OpARM64MOVDaddr {
9181                         break
9182                 }
9183                 off2 := auxIntToInt32(v_0.AuxInt)
9184                 sym2 := auxToSym(v_0.Aux)
9185                 ptr := v_0.Args[0]
9186                 mem := v_1
9187                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9188                         break
9189                 }
9190                 v.reset(OpARM64MOVBstorezero)
9191                 v.AuxInt = int32ToAuxInt(off1 + off2)
9192                 v.Aux = symToAux(mergeSym(sym1, sym2))
9193                 v.AddArg2(ptr, mem)
9194                 return true
9195         }
9196         // match: (MOVBstorezero [off] {sym} (ADD ptr idx) mem)
9197         // cond: off == 0 && sym == nil
9198         // result: (MOVBstorezeroidx ptr idx mem)
9199         for {
9200                 off := auxIntToInt32(v.AuxInt)
9201                 sym := auxToSym(v.Aux)
9202                 if v_0.Op != OpARM64ADD {
9203                         break
9204                 }
9205                 idx := v_0.Args[1]
9206                 ptr := v_0.Args[0]
9207                 mem := v_1
9208                 if !(off == 0 && sym == nil) {
9209                         break
9210                 }
9211                 v.reset(OpARM64MOVBstorezeroidx)
9212                 v.AddArg3(ptr, idx, mem)
9213                 return true
9214         }
9215         return false
9216 }
9217 func rewriteValueARM64_OpARM64MOVBstorezeroidx(v *Value) bool {
9218         v_2 := v.Args[2]
9219         v_1 := v.Args[1]
9220         v_0 := v.Args[0]
9221         // match: (MOVBstorezeroidx ptr (MOVDconst [c]) mem)
9222         // cond: is32Bit(c)
9223         // result: (MOVBstorezero [int32(c)] ptr mem)
9224         for {
9225                 ptr := v_0
9226                 if v_1.Op != OpARM64MOVDconst {
9227                         break
9228                 }
9229                 c := auxIntToInt64(v_1.AuxInt)
9230                 mem := v_2
9231                 if !(is32Bit(c)) {
9232                         break
9233                 }
9234                 v.reset(OpARM64MOVBstorezero)
9235                 v.AuxInt = int32ToAuxInt(int32(c))
9236                 v.AddArg2(ptr, mem)
9237                 return true
9238         }
9239         // match: (MOVBstorezeroidx (MOVDconst [c]) idx mem)
9240         // cond: is32Bit(c)
9241         // result: (MOVBstorezero [int32(c)] idx mem)
9242         for {
9243                 if v_0.Op != OpARM64MOVDconst {
9244                         break
9245                 }
9246                 c := auxIntToInt64(v_0.AuxInt)
9247                 idx := v_1
9248                 mem := v_2
9249                 if !(is32Bit(c)) {
9250                         break
9251                 }
9252                 v.reset(OpARM64MOVBstorezero)
9253                 v.AuxInt = int32ToAuxInt(int32(c))
9254                 v.AddArg2(idx, mem)
9255                 return true
9256         }
9257         return false
9258 }
9259 func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
9260         v_1 := v.Args[1]
9261         v_0 := v.Args[0]
9262         b := v.Block
9263         config := b.Func.Config
9264         // match: (MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr val _))
9265         // result: (FMOVDfpgp val)
9266         for {
9267                 off := auxIntToInt32(v.AuxInt)
9268                 sym := auxToSym(v.Aux)
9269                 ptr := v_0
9270                 if v_1.Op != OpARM64FMOVDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
9271                         break
9272                 }
9273                 val := v_1.Args[1]
9274                 if ptr != v_1.Args[0] {
9275                         break
9276                 }
9277                 v.reset(OpARM64FMOVDfpgp)
9278                 v.AddArg(val)
9279                 return true
9280         }
9281         // match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
9282         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9283         // result: (MOVDload [off1+int32(off2)] {sym} ptr mem)
9284         for {
9285                 off1 := auxIntToInt32(v.AuxInt)
9286                 sym := auxToSym(v.Aux)
9287                 if v_0.Op != OpARM64ADDconst {
9288                         break
9289                 }
9290                 off2 := auxIntToInt64(v_0.AuxInt)
9291                 ptr := v_0.Args[0]
9292                 mem := v_1
9293                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9294                         break
9295                 }
9296                 v.reset(OpARM64MOVDload)
9297                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
9298                 v.Aux = symToAux(sym)
9299                 v.AddArg2(ptr, mem)
9300                 return true
9301         }
9302         // match: (MOVDload [off] {sym} (ADD ptr idx) mem)
9303         // cond: off == 0 && sym == nil
9304         // result: (MOVDloadidx ptr idx mem)
9305         for {
9306                 off := auxIntToInt32(v.AuxInt)
9307                 sym := auxToSym(v.Aux)
9308                 if v_0.Op != OpARM64ADD {
9309                         break
9310                 }
9311                 idx := v_0.Args[1]
9312                 ptr := v_0.Args[0]
9313                 mem := v_1
9314                 if !(off == 0 && sym == nil) {
9315                         break
9316                 }
9317                 v.reset(OpARM64MOVDloadidx)
9318                 v.AddArg3(ptr, idx, mem)
9319                 return true
9320         }
9321         // match: (MOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem)
9322         // cond: off == 0 && sym == nil
9323         // result: (MOVDloadidx8 ptr idx mem)
9324         for {
9325                 off := auxIntToInt32(v.AuxInt)
9326                 sym := auxToSym(v.Aux)
9327                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
9328                         break
9329                 }
9330                 idx := v_0.Args[1]
9331                 ptr := v_0.Args[0]
9332                 mem := v_1
9333                 if !(off == 0 && sym == nil) {
9334                         break
9335                 }
9336                 v.reset(OpARM64MOVDloadidx8)
9337                 v.AddArg3(ptr, idx, mem)
9338                 return true
9339         }
9340         // match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
9341         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9342         // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
9343         for {
9344                 off1 := auxIntToInt32(v.AuxInt)
9345                 sym1 := auxToSym(v.Aux)
9346                 if v_0.Op != OpARM64MOVDaddr {
9347                         break
9348                 }
9349                 off2 := auxIntToInt32(v_0.AuxInt)
9350                 sym2 := auxToSym(v_0.Aux)
9351                 ptr := v_0.Args[0]
9352                 mem := v_1
9353                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9354                         break
9355                 }
9356                 v.reset(OpARM64MOVDload)
9357                 v.AuxInt = int32ToAuxInt(off1 + off2)
9358                 v.Aux = symToAux(mergeSym(sym1, sym2))
9359                 v.AddArg2(ptr, mem)
9360                 return true
9361         }
9362         // match: (MOVDload [off] {sym} ptr (MOVDstorezero [off2] {sym2} ptr2 _))
9363         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
9364         // result: (MOVDconst [0])
9365         for {
9366                 off := auxIntToInt32(v.AuxInt)
9367                 sym := auxToSym(v.Aux)
9368                 ptr := v_0
9369                 if v_1.Op != OpARM64MOVDstorezero {
9370                         break
9371                 }
9372                 off2 := auxIntToInt32(v_1.AuxInt)
9373                 sym2 := auxToSym(v_1.Aux)
9374                 ptr2 := v_1.Args[0]
9375                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
9376                         break
9377                 }
9378                 v.reset(OpARM64MOVDconst)
9379                 v.AuxInt = int64ToAuxInt(0)
9380                 return true
9381         }
9382         // match: (MOVDload [off] {sym} (SB) _)
9383         // cond: symIsRO(sym)
9384         // result: (MOVDconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
9385         for {
9386                 off := auxIntToInt32(v.AuxInt)
9387                 sym := auxToSym(v.Aux)
9388                 if v_0.Op != OpSB || !(symIsRO(sym)) {
9389                         break
9390                 }
9391                 v.reset(OpARM64MOVDconst)
9392                 v.AuxInt = int64ToAuxInt(int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder)))
9393                 return true
9394         }
9395         return false
9396 }
9397 func rewriteValueARM64_OpARM64MOVDloadidx(v *Value) bool {
9398         v_2 := v.Args[2]
9399         v_1 := v.Args[1]
9400         v_0 := v.Args[0]
9401         // match: (MOVDloadidx ptr (MOVDconst [c]) mem)
9402         // cond: is32Bit(c)
9403         // result: (MOVDload [int32(c)] ptr mem)
9404         for {
9405                 ptr := v_0
9406                 if v_1.Op != OpARM64MOVDconst {
9407                         break
9408                 }
9409                 c := auxIntToInt64(v_1.AuxInt)
9410                 mem := v_2
9411                 if !(is32Bit(c)) {
9412                         break
9413                 }
9414                 v.reset(OpARM64MOVDload)
9415                 v.AuxInt = int32ToAuxInt(int32(c))
9416                 v.AddArg2(ptr, mem)
9417                 return true
9418         }
9419         // match: (MOVDloadidx (MOVDconst [c]) ptr mem)
9420         // cond: is32Bit(c)
9421         // result: (MOVDload [int32(c)] ptr mem)
9422         for {
9423                 if v_0.Op != OpARM64MOVDconst {
9424                         break
9425                 }
9426                 c := auxIntToInt64(v_0.AuxInt)
9427                 ptr := v_1
9428                 mem := v_2
9429                 if !(is32Bit(c)) {
9430                         break
9431                 }
9432                 v.reset(OpARM64MOVDload)
9433                 v.AuxInt = int32ToAuxInt(int32(c))
9434                 v.AddArg2(ptr, mem)
9435                 return true
9436         }
9437         // match: (MOVDloadidx ptr (SLLconst [3] idx) mem)
9438         // result: (MOVDloadidx8 ptr idx mem)
9439         for {
9440                 ptr := v_0
9441                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
9442                         break
9443                 }
9444                 idx := v_1.Args[0]
9445                 mem := v_2
9446                 v.reset(OpARM64MOVDloadidx8)
9447                 v.AddArg3(ptr, idx, mem)
9448                 return true
9449         }
9450         // match: (MOVDloadidx (SLLconst [3] idx) ptr mem)
9451         // result: (MOVDloadidx8 ptr idx mem)
9452         for {
9453                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
9454                         break
9455                 }
9456                 idx := v_0.Args[0]
9457                 ptr := v_1
9458                 mem := v_2
9459                 v.reset(OpARM64MOVDloadidx8)
9460                 v.AddArg3(ptr, idx, mem)
9461                 return true
9462         }
9463         // match: (MOVDloadidx ptr idx (MOVDstorezeroidx ptr2 idx2 _))
9464         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
9465         // result: (MOVDconst [0])
9466         for {
9467                 ptr := v_0
9468                 idx := v_1
9469                 if v_2.Op != OpARM64MOVDstorezeroidx {
9470                         break
9471                 }
9472                 idx2 := v_2.Args[1]
9473                 ptr2 := v_2.Args[0]
9474                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
9475                         break
9476                 }
9477                 v.reset(OpARM64MOVDconst)
9478                 v.AuxInt = int64ToAuxInt(0)
9479                 return true
9480         }
9481         return false
9482 }
9483 func rewriteValueARM64_OpARM64MOVDloadidx8(v *Value) bool {
9484         v_2 := v.Args[2]
9485         v_1 := v.Args[1]
9486         v_0 := v.Args[0]
9487         // match: (MOVDloadidx8 ptr (MOVDconst [c]) mem)
9488         // cond: is32Bit(c<<3)
9489         // result: (MOVDload [int32(c)<<3] ptr mem)
9490         for {
9491                 ptr := v_0
9492                 if v_1.Op != OpARM64MOVDconst {
9493                         break
9494                 }
9495                 c := auxIntToInt64(v_1.AuxInt)
9496                 mem := v_2
9497                 if !(is32Bit(c << 3)) {
9498                         break
9499                 }
9500                 v.reset(OpARM64MOVDload)
9501                 v.AuxInt = int32ToAuxInt(int32(c) << 3)
9502                 v.AddArg2(ptr, mem)
9503                 return true
9504         }
9505         // match: (MOVDloadidx8 ptr idx (MOVDstorezeroidx8 ptr2 idx2 _))
9506         // cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
9507         // result: (MOVDconst [0])
9508         for {
9509                 ptr := v_0
9510                 idx := v_1
9511                 if v_2.Op != OpARM64MOVDstorezeroidx8 {
9512                         break
9513                 }
9514                 idx2 := v_2.Args[1]
9515                 ptr2 := v_2.Args[0]
9516                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
9517                         break
9518                 }
9519                 v.reset(OpARM64MOVDconst)
9520                 v.AuxInt = int64ToAuxInt(0)
9521                 return true
9522         }
9523         return false
9524 }
9525 func rewriteValueARM64_OpARM64MOVDnop(v *Value) bool {
9526         v_0 := v.Args[0]
9527         // match: (MOVDnop (MOVDconst [c]))
9528         // result: (MOVDconst [c])
9529         for {
9530                 if v_0.Op != OpARM64MOVDconst {
9531                         break
9532                 }
9533                 c := auxIntToInt64(v_0.AuxInt)
9534                 v.reset(OpARM64MOVDconst)
9535                 v.AuxInt = int64ToAuxInt(c)
9536                 return true
9537         }
9538         return false
9539 }
9540 func rewriteValueARM64_OpARM64MOVDreg(v *Value) bool {
9541         v_0 := v.Args[0]
9542         // match: (MOVDreg x)
9543         // cond: x.Uses == 1
9544         // result: (MOVDnop x)
9545         for {
9546                 x := v_0
9547                 if !(x.Uses == 1) {
9548                         break
9549                 }
9550                 v.reset(OpARM64MOVDnop)
9551                 v.AddArg(x)
9552                 return true
9553         }
9554         // match: (MOVDreg (MOVDconst [c]))
9555         // result: (MOVDconst [c])
9556         for {
9557                 if v_0.Op != OpARM64MOVDconst {
9558                         break
9559                 }
9560                 c := auxIntToInt64(v_0.AuxInt)
9561                 v.reset(OpARM64MOVDconst)
9562                 v.AuxInt = int64ToAuxInt(c)
9563                 return true
9564         }
9565         return false
9566 }
9567 func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool {
9568         v_2 := v.Args[2]
9569         v_1 := v.Args[1]
9570         v_0 := v.Args[0]
9571         b := v.Block
9572         config := b.Func.Config
9573         // match: (MOVDstore [off] {sym} ptr (FMOVDfpgp val) mem)
9574         // result: (FMOVDstore [off] {sym} ptr val mem)
9575         for {
9576                 off := auxIntToInt32(v.AuxInt)
9577                 sym := auxToSym(v.Aux)
9578                 ptr := v_0
9579                 if v_1.Op != OpARM64FMOVDfpgp {
9580                         break
9581                 }
9582                 val := v_1.Args[0]
9583                 mem := v_2
9584                 v.reset(OpARM64FMOVDstore)
9585                 v.AuxInt = int32ToAuxInt(off)
9586                 v.Aux = symToAux(sym)
9587                 v.AddArg3(ptr, val, mem)
9588                 return true
9589         }
9590         // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
9591         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9592         // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
9593         for {
9594                 off1 := auxIntToInt32(v.AuxInt)
9595                 sym := auxToSym(v.Aux)
9596                 if v_0.Op != OpARM64ADDconst {
9597                         break
9598                 }
9599                 off2 := auxIntToInt64(v_0.AuxInt)
9600                 ptr := v_0.Args[0]
9601                 val := v_1
9602                 mem := v_2
9603                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9604                         break
9605                 }
9606                 v.reset(OpARM64MOVDstore)
9607                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
9608                 v.Aux = symToAux(sym)
9609                 v.AddArg3(ptr, val, mem)
9610                 return true
9611         }
9612         // match: (MOVDstore [off] {sym} (ADD ptr idx) val mem)
9613         // cond: off == 0 && sym == nil
9614         // result: (MOVDstoreidx ptr idx val mem)
9615         for {
9616                 off := auxIntToInt32(v.AuxInt)
9617                 sym := auxToSym(v.Aux)
9618                 if v_0.Op != OpARM64ADD {
9619                         break
9620                 }
9621                 idx := v_0.Args[1]
9622                 ptr := v_0.Args[0]
9623                 val := v_1
9624                 mem := v_2
9625                 if !(off == 0 && sym == nil) {
9626                         break
9627                 }
9628                 v.reset(OpARM64MOVDstoreidx)
9629                 v.AddArg4(ptr, idx, val, mem)
9630                 return true
9631         }
9632         // match: (MOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem)
9633         // cond: off == 0 && sym == nil
9634         // result: (MOVDstoreidx8 ptr idx val mem)
9635         for {
9636                 off := auxIntToInt32(v.AuxInt)
9637                 sym := auxToSym(v.Aux)
9638                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
9639                         break
9640                 }
9641                 idx := v_0.Args[1]
9642                 ptr := v_0.Args[0]
9643                 val := v_1
9644                 mem := v_2
9645                 if !(off == 0 && sym == nil) {
9646                         break
9647                 }
9648                 v.reset(OpARM64MOVDstoreidx8)
9649                 v.AddArg4(ptr, idx, val, mem)
9650                 return true
9651         }
9652         // match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
9653         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9654         // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
9655         for {
9656                 off1 := auxIntToInt32(v.AuxInt)
9657                 sym1 := auxToSym(v.Aux)
9658                 if v_0.Op != OpARM64MOVDaddr {
9659                         break
9660                 }
9661                 off2 := auxIntToInt32(v_0.AuxInt)
9662                 sym2 := auxToSym(v_0.Aux)
9663                 ptr := v_0.Args[0]
9664                 val := v_1
9665                 mem := v_2
9666                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9667                         break
9668                 }
9669                 v.reset(OpARM64MOVDstore)
9670                 v.AuxInt = int32ToAuxInt(off1 + off2)
9671                 v.Aux = symToAux(mergeSym(sym1, sym2))
9672                 v.AddArg3(ptr, val, mem)
9673                 return true
9674         }
9675         // match: (MOVDstore [off] {sym} ptr (MOVDconst [0]) mem)
9676         // result: (MOVDstorezero [off] {sym} ptr mem)
9677         for {
9678                 off := auxIntToInt32(v.AuxInt)
9679                 sym := auxToSym(v.Aux)
9680                 ptr := v_0
9681                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
9682                         break
9683                 }
9684                 mem := v_2
9685                 v.reset(OpARM64MOVDstorezero)
9686                 v.AuxInt = int32ToAuxInt(off)
9687                 v.Aux = symToAux(sym)
9688                 v.AddArg2(ptr, mem)
9689                 return true
9690         }
9691         return false
9692 }
9693 func rewriteValueARM64_OpARM64MOVDstoreidx(v *Value) bool {
9694         v_3 := v.Args[3]
9695         v_2 := v.Args[2]
9696         v_1 := v.Args[1]
9697         v_0 := v.Args[0]
9698         // match: (MOVDstoreidx ptr (MOVDconst [c]) val mem)
9699         // cond: is32Bit(c)
9700         // result: (MOVDstore [int32(c)] ptr val mem)
9701         for {
9702                 ptr := v_0
9703                 if v_1.Op != OpARM64MOVDconst {
9704                         break
9705                 }
9706                 c := auxIntToInt64(v_1.AuxInt)
9707                 val := v_2
9708                 mem := v_3
9709                 if !(is32Bit(c)) {
9710                         break
9711                 }
9712                 v.reset(OpARM64MOVDstore)
9713                 v.AuxInt = int32ToAuxInt(int32(c))
9714                 v.AddArg3(ptr, val, mem)
9715                 return true
9716         }
9717         // match: (MOVDstoreidx (MOVDconst [c]) idx val mem)
9718         // cond: is32Bit(c)
9719         // result: (MOVDstore [int32(c)] idx val mem)
9720         for {
9721                 if v_0.Op != OpARM64MOVDconst {
9722                         break
9723                 }
9724                 c := auxIntToInt64(v_0.AuxInt)
9725                 idx := v_1
9726                 val := v_2
9727                 mem := v_3
9728                 if !(is32Bit(c)) {
9729                         break
9730                 }
9731                 v.reset(OpARM64MOVDstore)
9732                 v.AuxInt = int32ToAuxInt(int32(c))
9733                 v.AddArg3(idx, val, mem)
9734                 return true
9735         }
9736         // match: (MOVDstoreidx ptr (SLLconst [3] idx) val mem)
9737         // result: (MOVDstoreidx8 ptr idx val mem)
9738         for {
9739                 ptr := v_0
9740                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
9741                         break
9742                 }
9743                 idx := v_1.Args[0]
9744                 val := v_2
9745                 mem := v_3
9746                 v.reset(OpARM64MOVDstoreidx8)
9747                 v.AddArg4(ptr, idx, val, mem)
9748                 return true
9749         }
9750         // match: (MOVDstoreidx (SLLconst [3] idx) ptr val mem)
9751         // result: (MOVDstoreidx8 ptr idx val mem)
9752         for {
9753                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
9754                         break
9755                 }
9756                 idx := v_0.Args[0]
9757                 ptr := v_1
9758                 val := v_2
9759                 mem := v_3
9760                 v.reset(OpARM64MOVDstoreidx8)
9761                 v.AddArg4(ptr, idx, val, mem)
9762                 return true
9763         }
9764         // match: (MOVDstoreidx ptr idx (MOVDconst [0]) mem)
9765         // result: (MOVDstorezeroidx ptr idx mem)
9766         for {
9767                 ptr := v_0
9768                 idx := v_1
9769                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
9770                         break
9771                 }
9772                 mem := v_3
9773                 v.reset(OpARM64MOVDstorezeroidx)
9774                 v.AddArg3(ptr, idx, mem)
9775                 return true
9776         }
9777         return false
9778 }
9779 func rewriteValueARM64_OpARM64MOVDstoreidx8(v *Value) bool {
9780         v_3 := v.Args[3]
9781         v_2 := v.Args[2]
9782         v_1 := v.Args[1]
9783         v_0 := v.Args[0]
9784         // match: (MOVDstoreidx8 ptr (MOVDconst [c]) val mem)
9785         // cond: is32Bit(c<<3)
9786         // result: (MOVDstore [int32(c)<<3] ptr val mem)
9787         for {
9788                 ptr := v_0
9789                 if v_1.Op != OpARM64MOVDconst {
9790                         break
9791                 }
9792                 c := auxIntToInt64(v_1.AuxInt)
9793                 val := v_2
9794                 mem := v_3
9795                 if !(is32Bit(c << 3)) {
9796                         break
9797                 }
9798                 v.reset(OpARM64MOVDstore)
9799                 v.AuxInt = int32ToAuxInt(int32(c) << 3)
9800                 v.AddArg3(ptr, val, mem)
9801                 return true
9802         }
9803         // match: (MOVDstoreidx8 ptr idx (MOVDconst [0]) mem)
9804         // result: (MOVDstorezeroidx8 ptr idx mem)
9805         for {
9806                 ptr := v_0
9807                 idx := v_1
9808                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
9809                         break
9810                 }
9811                 mem := v_3
9812                 v.reset(OpARM64MOVDstorezeroidx8)
9813                 v.AddArg3(ptr, idx, mem)
9814                 return true
9815         }
9816         return false
9817 }
9818 func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
9819         v_1 := v.Args[1]
9820         v_0 := v.Args[0]
9821         b := v.Block
9822         config := b.Func.Config
9823         // match: (MOVDstorezero {s} [i] ptr x:(MOVDstorezero {s} [i+8] ptr mem))
9824         // cond: x.Uses == 1 && clobber(x)
9825         // result: (MOVQstorezero {s} [i] ptr mem)
9826         for {
9827                 i := auxIntToInt32(v.AuxInt)
9828                 s := auxToSym(v.Aux)
9829                 ptr := v_0
9830                 x := v_1
9831                 if x.Op != OpARM64MOVDstorezero || auxIntToInt32(x.AuxInt) != i+8 || auxToSym(x.Aux) != s {
9832                         break
9833                 }
9834                 mem := x.Args[1]
9835                 if ptr != x.Args[0] || !(x.Uses == 1 && clobber(x)) {
9836                         break
9837                 }
9838                 v.reset(OpARM64MOVQstorezero)
9839                 v.AuxInt = int32ToAuxInt(i)
9840                 v.Aux = symToAux(s)
9841                 v.AddArg2(ptr, mem)
9842                 return true
9843         }
9844         // match: (MOVDstorezero {s} [i] ptr x:(MOVDstorezero {s} [i-8] ptr mem))
9845         // cond: x.Uses == 1 && clobber(x)
9846         // result: (MOVQstorezero {s} [i-8] ptr mem)
9847         for {
9848                 i := auxIntToInt32(v.AuxInt)
9849                 s := auxToSym(v.Aux)
9850                 ptr := v_0
9851                 x := v_1
9852                 if x.Op != OpARM64MOVDstorezero || auxIntToInt32(x.AuxInt) != i-8 || auxToSym(x.Aux) != s {
9853                         break
9854                 }
9855                 mem := x.Args[1]
9856                 if ptr != x.Args[0] || !(x.Uses == 1 && clobber(x)) {
9857                         break
9858                 }
9859                 v.reset(OpARM64MOVQstorezero)
9860                 v.AuxInt = int32ToAuxInt(i - 8)
9861                 v.Aux = symToAux(s)
9862                 v.AddArg2(ptr, mem)
9863                 return true
9864         }
9865         // match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
9866         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9867         // result: (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
9868         for {
9869                 off1 := auxIntToInt32(v.AuxInt)
9870                 sym := auxToSym(v.Aux)
9871                 if v_0.Op != OpARM64ADDconst {
9872                         break
9873                 }
9874                 off2 := auxIntToInt64(v_0.AuxInt)
9875                 ptr := v_0.Args[0]
9876                 mem := v_1
9877                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9878                         break
9879                 }
9880                 v.reset(OpARM64MOVDstorezero)
9881                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
9882                 v.Aux = symToAux(sym)
9883                 v.AddArg2(ptr, mem)
9884                 return true
9885         }
9886         // match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
9887         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
9888         // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
9889         for {
9890                 off1 := auxIntToInt32(v.AuxInt)
9891                 sym1 := auxToSym(v.Aux)
9892                 if v_0.Op != OpARM64MOVDaddr {
9893                         break
9894                 }
9895                 off2 := auxIntToInt32(v_0.AuxInt)
9896                 sym2 := auxToSym(v_0.Aux)
9897                 ptr := v_0.Args[0]
9898                 mem := v_1
9899                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
9900                         break
9901                 }
9902                 v.reset(OpARM64MOVDstorezero)
9903                 v.AuxInt = int32ToAuxInt(off1 + off2)
9904                 v.Aux = symToAux(mergeSym(sym1, sym2))
9905                 v.AddArg2(ptr, mem)
9906                 return true
9907         }
9908         // match: (MOVDstorezero [off] {sym} (ADD ptr idx) mem)
9909         // cond: off == 0 && sym == nil
9910         // result: (MOVDstorezeroidx ptr idx mem)
9911         for {
9912                 off := auxIntToInt32(v.AuxInt)
9913                 sym := auxToSym(v.Aux)
9914                 if v_0.Op != OpARM64ADD {
9915                         break
9916                 }
9917                 idx := v_0.Args[1]
9918                 ptr := v_0.Args[0]
9919                 mem := v_1
9920                 if !(off == 0 && sym == nil) {
9921                         break
9922                 }
9923                 v.reset(OpARM64MOVDstorezeroidx)
9924                 v.AddArg3(ptr, idx, mem)
9925                 return true
9926         }
9927         // match: (MOVDstorezero [off] {sym} (ADDshiftLL [3] ptr idx) mem)
9928         // cond: off == 0 && sym == nil
9929         // result: (MOVDstorezeroidx8 ptr idx mem)
9930         for {
9931                 off := auxIntToInt32(v.AuxInt)
9932                 sym := auxToSym(v.Aux)
9933                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
9934                         break
9935                 }
9936                 idx := v_0.Args[1]
9937                 ptr := v_0.Args[0]
9938                 mem := v_1
9939                 if !(off == 0 && sym == nil) {
9940                         break
9941                 }
9942                 v.reset(OpARM64MOVDstorezeroidx8)
9943                 v.AddArg3(ptr, idx, mem)
9944                 return true
9945         }
9946         return false
9947 }
9948 func rewriteValueARM64_OpARM64MOVDstorezeroidx(v *Value) bool {
9949         v_2 := v.Args[2]
9950         v_1 := v.Args[1]
9951         v_0 := v.Args[0]
9952         // match: (MOVDstorezeroidx ptr (MOVDconst [c]) mem)
9953         // cond: is32Bit(c)
9954         // result: (MOVDstorezero [int32(c)] ptr mem)
9955         for {
9956                 ptr := v_0
9957                 if v_1.Op != OpARM64MOVDconst {
9958                         break
9959                 }
9960                 c := auxIntToInt64(v_1.AuxInt)
9961                 mem := v_2
9962                 if !(is32Bit(c)) {
9963                         break
9964                 }
9965                 v.reset(OpARM64MOVDstorezero)
9966                 v.AuxInt = int32ToAuxInt(int32(c))
9967                 v.AddArg2(ptr, mem)
9968                 return true
9969         }
9970         // match: (MOVDstorezeroidx (MOVDconst [c]) idx mem)
9971         // cond: is32Bit(c)
9972         // result: (MOVDstorezero [int32(c)] idx mem)
9973         for {
9974                 if v_0.Op != OpARM64MOVDconst {
9975                         break
9976                 }
9977                 c := auxIntToInt64(v_0.AuxInt)
9978                 idx := v_1
9979                 mem := v_2
9980                 if !(is32Bit(c)) {
9981                         break
9982                 }
9983                 v.reset(OpARM64MOVDstorezero)
9984                 v.AuxInt = int32ToAuxInt(int32(c))
9985                 v.AddArg2(idx, mem)
9986                 return true
9987         }
9988         // match: (MOVDstorezeroidx ptr (SLLconst [3] idx) mem)
9989         // result: (MOVDstorezeroidx8 ptr idx mem)
9990         for {
9991                 ptr := v_0
9992                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
9993                         break
9994                 }
9995                 idx := v_1.Args[0]
9996                 mem := v_2
9997                 v.reset(OpARM64MOVDstorezeroidx8)
9998                 v.AddArg3(ptr, idx, mem)
9999                 return true
10000         }
10001         // match: (MOVDstorezeroidx (SLLconst [3] idx) ptr mem)
10002         // result: (MOVDstorezeroidx8 ptr idx mem)
10003         for {
10004                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
10005                         break
10006                 }
10007                 idx := v_0.Args[0]
10008                 ptr := v_1
10009                 mem := v_2
10010                 v.reset(OpARM64MOVDstorezeroidx8)
10011                 v.AddArg3(ptr, idx, mem)
10012                 return true
10013         }
10014         return false
10015 }
10016 func rewriteValueARM64_OpARM64MOVDstorezeroidx8(v *Value) bool {
10017         v_2 := v.Args[2]
10018         v_1 := v.Args[1]
10019         v_0 := v.Args[0]
10020         // match: (MOVDstorezeroidx8 ptr (MOVDconst [c]) mem)
10021         // cond: is32Bit(c<<3)
10022         // result: (MOVDstorezero [int32(c<<3)] ptr mem)
10023         for {
10024                 ptr := v_0
10025                 if v_1.Op != OpARM64MOVDconst {
10026                         break
10027                 }
10028                 c := auxIntToInt64(v_1.AuxInt)
10029                 mem := v_2
10030                 if !(is32Bit(c << 3)) {
10031                         break
10032                 }
10033                 v.reset(OpARM64MOVDstorezero)
10034                 v.AuxInt = int32ToAuxInt(int32(c << 3))
10035                 v.AddArg2(ptr, mem)
10036                 return true
10037         }
10038         return false
10039 }
10040 func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool {
10041         v_1 := v.Args[1]
10042         v_0 := v.Args[0]
10043         b := v.Block
10044         config := b.Func.Config
10045         // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
10046         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
10047         // result: (MOVHUload [off1+int32(off2)] {sym} ptr mem)
10048         for {
10049                 off1 := auxIntToInt32(v.AuxInt)
10050                 sym := auxToSym(v.Aux)
10051                 if v_0.Op != OpARM64ADDconst {
10052                         break
10053                 }
10054                 off2 := auxIntToInt64(v_0.AuxInt)
10055                 ptr := v_0.Args[0]
10056                 mem := v_1
10057                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
10058                         break
10059                 }
10060                 v.reset(OpARM64MOVHUload)
10061                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
10062                 v.Aux = symToAux(sym)
10063                 v.AddArg2(ptr, mem)
10064                 return true
10065         }
10066         // match: (MOVHUload [off] {sym} (ADD ptr idx) mem)
10067         // cond: off == 0 && sym == nil
10068         // result: (MOVHUloadidx ptr idx mem)
10069         for {
10070                 off := auxIntToInt32(v.AuxInt)
10071                 sym := auxToSym(v.Aux)
10072                 if v_0.Op != OpARM64ADD {
10073                         break
10074                 }
10075                 idx := v_0.Args[1]
10076                 ptr := v_0.Args[0]
10077                 mem := v_1
10078                 if !(off == 0 && sym == nil) {
10079                         break
10080                 }
10081                 v.reset(OpARM64MOVHUloadidx)
10082                 v.AddArg3(ptr, idx, mem)
10083                 return true
10084         }
10085         // match: (MOVHUload [off] {sym} (ADDshiftLL [1] ptr idx) mem)
10086         // cond: off == 0 && sym == nil
10087         // result: (MOVHUloadidx2 ptr idx mem)
10088         for {
10089                 off := auxIntToInt32(v.AuxInt)
10090                 sym := auxToSym(v.Aux)
10091                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
10092                         break
10093                 }
10094                 idx := v_0.Args[1]
10095                 ptr := v_0.Args[0]
10096                 mem := v_1
10097                 if !(off == 0 && sym == nil) {
10098                         break
10099                 }
10100                 v.reset(OpARM64MOVHUloadidx2)
10101                 v.AddArg3(ptr, idx, mem)
10102                 return true
10103         }
10104         // match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
10105         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
10106         // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
10107         for {
10108                 off1 := auxIntToInt32(v.AuxInt)
10109                 sym1 := auxToSym(v.Aux)
10110                 if v_0.Op != OpARM64MOVDaddr {
10111                         break
10112                 }
10113                 off2 := auxIntToInt32(v_0.AuxInt)
10114                 sym2 := auxToSym(v_0.Aux)
10115                 ptr := v_0.Args[0]
10116                 mem := v_1
10117                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
10118                         break
10119                 }
10120                 v.reset(OpARM64MOVHUload)
10121                 v.AuxInt = int32ToAuxInt(off1 + off2)
10122                 v.Aux = symToAux(mergeSym(sym1, sym2))
10123                 v.AddArg2(ptr, mem)
10124                 return true
10125         }
10126         // match: (MOVHUload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _))
10127         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
10128         // result: (MOVDconst [0])
10129         for {
10130                 off := auxIntToInt32(v.AuxInt)
10131                 sym := auxToSym(v.Aux)
10132                 ptr := v_0
10133                 if v_1.Op != OpARM64MOVHstorezero {
10134                         break
10135                 }
10136                 off2 := auxIntToInt32(v_1.AuxInt)
10137                 sym2 := auxToSym(v_1.Aux)
10138                 ptr2 := v_1.Args[0]
10139                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
10140                         break
10141                 }
10142                 v.reset(OpARM64MOVDconst)
10143                 v.AuxInt = int64ToAuxInt(0)
10144                 return true
10145         }
10146         // match: (MOVHUload [off] {sym} (SB) _)
10147         // cond: symIsRO(sym)
10148         // result: (MOVDconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
10149         for {
10150                 off := auxIntToInt32(v.AuxInt)
10151                 sym := auxToSym(v.Aux)
10152                 if v_0.Op != OpSB || !(symIsRO(sym)) {
10153                         break
10154                 }
10155                 v.reset(OpARM64MOVDconst)
10156                 v.AuxInt = int64ToAuxInt(int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder)))
10157                 return true
10158         }
10159         return false
10160 }
10161 func rewriteValueARM64_OpARM64MOVHUloadidx(v *Value) bool {
10162         v_2 := v.Args[2]
10163         v_1 := v.Args[1]
10164         v_0 := v.Args[0]
10165         // match: (MOVHUloadidx ptr (MOVDconst [c]) mem)
10166         // cond: is32Bit(c)
10167         // result: (MOVHUload [int32(c)] ptr mem)
10168         for {
10169                 ptr := v_0
10170                 if v_1.Op != OpARM64MOVDconst {
10171                         break
10172                 }
10173                 c := auxIntToInt64(v_1.AuxInt)
10174                 mem := v_2
10175                 if !(is32Bit(c)) {
10176                         break
10177                 }
10178                 v.reset(OpARM64MOVHUload)
10179                 v.AuxInt = int32ToAuxInt(int32(c))
10180                 v.AddArg2(ptr, mem)
10181                 return true
10182         }
10183         // match: (MOVHUloadidx (MOVDconst [c]) ptr mem)
10184         // cond: is32Bit(c)
10185         // result: (MOVHUload [int32(c)] ptr mem)
10186         for {
10187                 if v_0.Op != OpARM64MOVDconst {
10188                         break
10189                 }
10190                 c := auxIntToInt64(v_0.AuxInt)
10191                 ptr := v_1
10192                 mem := v_2
10193                 if !(is32Bit(c)) {
10194                         break
10195                 }
10196                 v.reset(OpARM64MOVHUload)
10197                 v.AuxInt = int32ToAuxInt(int32(c))
10198                 v.AddArg2(ptr, mem)
10199                 return true
10200         }
10201         // match: (MOVHUloadidx ptr (SLLconst [1] idx) mem)
10202         // result: (MOVHUloadidx2 ptr idx mem)
10203         for {
10204                 ptr := v_0
10205                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
10206                         break
10207                 }
10208                 idx := v_1.Args[0]
10209                 mem := v_2
10210                 v.reset(OpARM64MOVHUloadidx2)
10211                 v.AddArg3(ptr, idx, mem)
10212                 return true
10213         }
10214         // match: (MOVHUloadidx ptr (ADD idx idx) mem)
10215         // result: (MOVHUloadidx2 ptr idx mem)
10216         for {
10217                 ptr := v_0
10218                 if v_1.Op != OpARM64ADD {
10219                         break
10220                 }
10221                 idx := v_1.Args[1]
10222                 if idx != v_1.Args[0] {
10223                         break
10224                 }
10225                 mem := v_2
10226                 v.reset(OpARM64MOVHUloadidx2)
10227                 v.AddArg3(ptr, idx, mem)
10228                 return true
10229         }
10230         // match: (MOVHUloadidx (ADD idx idx) ptr mem)
10231         // result: (MOVHUloadidx2 ptr idx mem)
10232         for {
10233                 if v_0.Op != OpARM64ADD {
10234                         break
10235                 }
10236                 idx := v_0.Args[1]
10237                 if idx != v_0.Args[0] {
10238                         break
10239                 }
10240                 ptr := v_1
10241                 mem := v_2
10242                 v.reset(OpARM64MOVHUloadidx2)
10243                 v.AddArg3(ptr, idx, mem)
10244                 return true
10245         }
10246         // match: (MOVHUloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
10247         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
10248         // result: (MOVDconst [0])
10249         for {
10250                 ptr := v_0
10251                 idx := v_1
10252                 if v_2.Op != OpARM64MOVHstorezeroidx {
10253                         break
10254                 }
10255                 idx2 := v_2.Args[1]
10256                 ptr2 := v_2.Args[0]
10257                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
10258                         break
10259                 }
10260                 v.reset(OpARM64MOVDconst)
10261                 v.AuxInt = int64ToAuxInt(0)
10262                 return true
10263         }
10264         return false
10265 }
10266 func rewriteValueARM64_OpARM64MOVHUloadidx2(v *Value) bool {
10267         v_2 := v.Args[2]
10268         v_1 := v.Args[1]
10269         v_0 := v.Args[0]
10270         // match: (MOVHUloadidx2 ptr (MOVDconst [c]) mem)
10271         // cond: is32Bit(c<<1)
10272         // result: (MOVHUload [int32(c)<<1] ptr mem)
10273         for {
10274                 ptr := v_0
10275                 if v_1.Op != OpARM64MOVDconst {
10276                         break
10277                 }
10278                 c := auxIntToInt64(v_1.AuxInt)
10279                 mem := v_2
10280                 if !(is32Bit(c << 1)) {
10281                         break
10282                 }
10283                 v.reset(OpARM64MOVHUload)
10284                 v.AuxInt = int32ToAuxInt(int32(c) << 1)
10285                 v.AddArg2(ptr, mem)
10286                 return true
10287         }
10288         // match: (MOVHUloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _))
10289         // cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
10290         // result: (MOVDconst [0])
10291         for {
10292                 ptr := v_0
10293                 idx := v_1
10294                 if v_2.Op != OpARM64MOVHstorezeroidx2 {
10295                         break
10296                 }
10297                 idx2 := v_2.Args[1]
10298                 ptr2 := v_2.Args[0]
10299                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
10300                         break
10301                 }
10302                 v.reset(OpARM64MOVDconst)
10303                 v.AuxInt = int64ToAuxInt(0)
10304                 return true
10305         }
10306         return false
10307 }
10308 func rewriteValueARM64_OpARM64MOVHUreg(v *Value) bool {
10309         v_0 := v.Args[0]
10310         // match: (MOVHUreg x:(MOVBUload _ _))
10311         // result: (MOVDreg x)
10312         for {
10313                 x := v_0
10314                 if x.Op != OpARM64MOVBUload {
10315                         break
10316                 }
10317                 v.reset(OpARM64MOVDreg)
10318                 v.AddArg(x)
10319                 return true
10320         }
10321         // match: (MOVHUreg x:(MOVHUload _ _))
10322         // result: (MOVDreg x)
10323         for {
10324                 x := v_0
10325                 if x.Op != OpARM64MOVHUload {
10326                         break
10327                 }
10328                 v.reset(OpARM64MOVDreg)
10329                 v.AddArg(x)
10330                 return true
10331         }
10332         // match: (MOVHUreg x:(MOVBUloadidx _ _ _))
10333         // result: (MOVDreg x)
10334         for {
10335                 x := v_0
10336                 if x.Op != OpARM64MOVBUloadidx {
10337                         break
10338                 }
10339                 v.reset(OpARM64MOVDreg)
10340                 v.AddArg(x)
10341                 return true
10342         }
10343         // match: (MOVHUreg x:(MOVHUloadidx _ _ _))
10344         // result: (MOVDreg x)
10345         for {
10346                 x := v_0
10347                 if x.Op != OpARM64MOVHUloadidx {
10348                         break
10349                 }
10350                 v.reset(OpARM64MOVDreg)
10351                 v.AddArg(x)
10352                 return true
10353         }
10354         // match: (MOVHUreg x:(MOVHUloadidx2 _ _ _))
10355         // result: (MOVDreg x)
10356         for {
10357                 x := v_0
10358                 if x.Op != OpARM64MOVHUloadidx2 {
10359                         break
10360                 }
10361                 v.reset(OpARM64MOVDreg)
10362                 v.AddArg(x)
10363                 return true
10364         }
10365         // match: (MOVHUreg x:(MOVBUreg _))
10366         // result: (MOVDreg x)
10367         for {
10368                 x := v_0
10369                 if x.Op != OpARM64MOVBUreg {
10370                         break
10371                 }
10372                 v.reset(OpARM64MOVDreg)
10373                 v.AddArg(x)
10374                 return true
10375         }
10376         // match: (MOVHUreg x:(MOVHUreg _))
10377         // result: (MOVDreg x)
10378         for {
10379                 x := v_0
10380                 if x.Op != OpARM64MOVHUreg {
10381                         break
10382                 }
10383                 v.reset(OpARM64MOVDreg)
10384                 v.AddArg(x)
10385                 return true
10386         }
10387         // match: (MOVHUreg (ANDconst [c] x))
10388         // result: (ANDconst [c&(1<<16-1)] x)
10389         for {
10390                 if v_0.Op != OpARM64ANDconst {
10391                         break
10392                 }
10393                 c := auxIntToInt64(v_0.AuxInt)
10394                 x := v_0.Args[0]
10395                 v.reset(OpARM64ANDconst)
10396                 v.AuxInt = int64ToAuxInt(c & (1<<16 - 1))
10397                 v.AddArg(x)
10398                 return true
10399         }
10400         // match: (MOVHUreg (MOVDconst [c]))
10401         // result: (MOVDconst [int64(uint16(c))])
10402         for {
10403                 if v_0.Op != OpARM64MOVDconst {
10404                         break
10405                 }
10406                 c := auxIntToInt64(v_0.AuxInt)
10407                 v.reset(OpARM64MOVDconst)
10408                 v.AuxInt = int64ToAuxInt(int64(uint16(c)))
10409                 return true
10410         }
10411         // match: (MOVHUreg x)
10412         // cond: v.Type.Size() <= 2
10413         // result: x
10414         for {
10415                 x := v_0
10416                 if !(v.Type.Size() <= 2) {
10417                         break
10418                 }
10419                 v.copyOf(x)
10420                 return true
10421         }
10422         // match: (MOVHUreg (SLLconst [lc] x))
10423         // cond: lc >= 16
10424         // result: (MOVDconst [0])
10425         for {
10426                 if v_0.Op != OpARM64SLLconst {
10427                         break
10428                 }
10429                 lc := auxIntToInt64(v_0.AuxInt)
10430                 if !(lc >= 16) {
10431                         break
10432                 }
10433                 v.reset(OpARM64MOVDconst)
10434                 v.AuxInt = int64ToAuxInt(0)
10435                 return true
10436         }
10437         // match: (MOVHUreg (SLLconst [lc] x))
10438         // cond: lc < 16
10439         // result: (UBFIZ [armBFAuxInt(lc, 16-lc)] x)
10440         for {
10441                 if v_0.Op != OpARM64SLLconst {
10442                         break
10443                 }
10444                 lc := auxIntToInt64(v_0.AuxInt)
10445                 x := v_0.Args[0]
10446                 if !(lc < 16) {
10447                         break
10448                 }
10449                 v.reset(OpARM64UBFIZ)
10450                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 16-lc))
10451                 v.AddArg(x)
10452                 return true
10453         }
10454         // match: (MOVHUreg (SRLconst [rc] x))
10455         // cond: rc < 16
10456         // result: (UBFX [armBFAuxInt(rc, 16)] x)
10457         for {
10458                 if v_0.Op != OpARM64SRLconst {
10459                         break
10460                 }
10461                 rc := auxIntToInt64(v_0.AuxInt)
10462                 x := v_0.Args[0]
10463                 if !(rc < 16) {
10464                         break
10465                 }
10466                 v.reset(OpARM64UBFX)
10467                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 16))
10468                 v.AddArg(x)
10469                 return true
10470         }
10471         // match: (MOVHUreg (UBFX [bfc] x))
10472         // cond: bfc.getARM64BFwidth() <= 16
10473         // result: (UBFX [bfc] x)
10474         for {
10475                 if v_0.Op != OpARM64UBFX {
10476                         break
10477                 }
10478                 bfc := auxIntToArm64BitField(v_0.AuxInt)
10479                 x := v_0.Args[0]
10480                 if !(bfc.getARM64BFwidth() <= 16) {
10481                         break
10482                 }
10483                 v.reset(OpARM64UBFX)
10484                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
10485                 v.AddArg(x)
10486                 return true
10487         }
10488         return false
10489 }
10490 func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
10491         v_1 := v.Args[1]
10492         v_0 := v.Args[0]
10493         b := v.Block
10494         config := b.Func.Config
10495         // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
10496         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
10497         // result: (MOVHload [off1+int32(off2)] {sym} ptr mem)
10498         for {
10499                 off1 := auxIntToInt32(v.AuxInt)
10500                 sym := auxToSym(v.Aux)
10501                 if v_0.Op != OpARM64ADDconst {
10502                         break
10503                 }
10504                 off2 := auxIntToInt64(v_0.AuxInt)
10505                 ptr := v_0.Args[0]
10506                 mem := v_1
10507                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
10508                         break
10509                 }
10510                 v.reset(OpARM64MOVHload)
10511                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
10512                 v.Aux = symToAux(sym)
10513                 v.AddArg2(ptr, mem)
10514                 return true
10515         }
10516         // match: (MOVHload [off] {sym} (ADD ptr idx) mem)
10517         // cond: off == 0 && sym == nil
10518         // result: (MOVHloadidx ptr idx mem)
10519         for {
10520                 off := auxIntToInt32(v.AuxInt)
10521                 sym := auxToSym(v.Aux)
10522                 if v_0.Op != OpARM64ADD {
10523                         break
10524                 }
10525                 idx := v_0.Args[1]
10526                 ptr := v_0.Args[0]
10527                 mem := v_1
10528                 if !(off == 0 && sym == nil) {
10529                         break
10530                 }
10531                 v.reset(OpARM64MOVHloadidx)
10532                 v.AddArg3(ptr, idx, mem)
10533                 return true
10534         }
10535         // match: (MOVHload [off] {sym} (ADDshiftLL [1] ptr idx) mem)
10536         // cond: off == 0 && sym == nil
10537         // result: (MOVHloadidx2 ptr idx mem)
10538         for {
10539                 off := auxIntToInt32(v.AuxInt)
10540                 sym := auxToSym(v.Aux)
10541                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
10542                         break
10543                 }
10544                 idx := v_0.Args[1]
10545                 ptr := v_0.Args[0]
10546                 mem := v_1
10547                 if !(off == 0 && sym == nil) {
10548                         break
10549                 }
10550                 v.reset(OpARM64MOVHloadidx2)
10551                 v.AddArg3(ptr, idx, mem)
10552                 return true
10553         }
10554         // match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
10555         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
10556         // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
10557         for {
10558                 off1 := auxIntToInt32(v.AuxInt)
10559                 sym1 := auxToSym(v.Aux)
10560                 if v_0.Op != OpARM64MOVDaddr {
10561                         break
10562                 }
10563                 off2 := auxIntToInt32(v_0.AuxInt)
10564                 sym2 := auxToSym(v_0.Aux)
10565                 ptr := v_0.Args[0]
10566                 mem := v_1
10567                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
10568                         break
10569                 }
10570                 v.reset(OpARM64MOVHload)
10571                 v.AuxInt = int32ToAuxInt(off1 + off2)
10572                 v.Aux = symToAux(mergeSym(sym1, sym2))
10573                 v.AddArg2(ptr, mem)
10574                 return true
10575         }
10576         // match: (MOVHload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _))
10577         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
10578         // result: (MOVDconst [0])
10579         for {
10580                 off := auxIntToInt32(v.AuxInt)
10581                 sym := auxToSym(v.Aux)
10582                 ptr := v_0
10583                 if v_1.Op != OpARM64MOVHstorezero {
10584                         break
10585                 }
10586                 off2 := auxIntToInt32(v_1.AuxInt)
10587                 sym2 := auxToSym(v_1.Aux)
10588                 ptr2 := v_1.Args[0]
10589                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
10590                         break
10591                 }
10592                 v.reset(OpARM64MOVDconst)
10593                 v.AuxInt = int64ToAuxInt(0)
10594                 return true
10595         }
10596         return false
10597 }
10598 func rewriteValueARM64_OpARM64MOVHloadidx(v *Value) bool {
10599         v_2 := v.Args[2]
10600         v_1 := v.Args[1]
10601         v_0 := v.Args[0]
10602         // match: (MOVHloadidx ptr (MOVDconst [c]) mem)
10603         // cond: is32Bit(c)
10604         // result: (MOVHload [int32(c)] ptr mem)
10605         for {
10606                 ptr := v_0
10607                 if v_1.Op != OpARM64MOVDconst {
10608                         break
10609                 }
10610                 c := auxIntToInt64(v_1.AuxInt)
10611                 mem := v_2
10612                 if !(is32Bit(c)) {
10613                         break
10614                 }
10615                 v.reset(OpARM64MOVHload)
10616                 v.AuxInt = int32ToAuxInt(int32(c))
10617                 v.AddArg2(ptr, mem)
10618                 return true
10619         }
10620         // match: (MOVHloadidx (MOVDconst [c]) ptr mem)
10621         // cond: is32Bit(c)
10622         // result: (MOVHload [int32(c)] ptr mem)
10623         for {
10624                 if v_0.Op != OpARM64MOVDconst {
10625                         break
10626                 }
10627                 c := auxIntToInt64(v_0.AuxInt)
10628                 ptr := v_1
10629                 mem := v_2
10630                 if !(is32Bit(c)) {
10631                         break
10632                 }
10633                 v.reset(OpARM64MOVHload)
10634                 v.AuxInt = int32ToAuxInt(int32(c))
10635                 v.AddArg2(ptr, mem)
10636                 return true
10637         }
10638         // match: (MOVHloadidx ptr (SLLconst [1] idx) mem)
10639         // result: (MOVHloadidx2 ptr idx mem)
10640         for {
10641                 ptr := v_0
10642                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
10643                         break
10644                 }
10645                 idx := v_1.Args[0]
10646                 mem := v_2
10647                 v.reset(OpARM64MOVHloadidx2)
10648                 v.AddArg3(ptr, idx, mem)
10649                 return true
10650         }
10651         // match: (MOVHloadidx ptr (ADD idx idx) mem)
10652         // result: (MOVHloadidx2 ptr idx mem)
10653         for {
10654                 ptr := v_0
10655                 if v_1.Op != OpARM64ADD {
10656                         break
10657                 }
10658                 idx := v_1.Args[1]
10659                 if idx != v_1.Args[0] {
10660                         break
10661                 }
10662                 mem := v_2
10663                 v.reset(OpARM64MOVHloadidx2)
10664                 v.AddArg3(ptr, idx, mem)
10665                 return true
10666         }
10667         // match: (MOVHloadidx (ADD idx idx) ptr mem)
10668         // result: (MOVHloadidx2 ptr idx mem)
10669         for {
10670                 if v_0.Op != OpARM64ADD {
10671                         break
10672                 }
10673                 idx := v_0.Args[1]
10674                 if idx != v_0.Args[0] {
10675                         break
10676                 }
10677                 ptr := v_1
10678                 mem := v_2
10679                 v.reset(OpARM64MOVHloadidx2)
10680                 v.AddArg3(ptr, idx, mem)
10681                 return true
10682         }
10683         // match: (MOVHloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
10684         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
10685         // result: (MOVDconst [0])
10686         for {
10687                 ptr := v_0
10688                 idx := v_1
10689                 if v_2.Op != OpARM64MOVHstorezeroidx {
10690                         break
10691                 }
10692                 idx2 := v_2.Args[1]
10693                 ptr2 := v_2.Args[0]
10694                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
10695                         break
10696                 }
10697                 v.reset(OpARM64MOVDconst)
10698                 v.AuxInt = int64ToAuxInt(0)
10699                 return true
10700         }
10701         return false
10702 }
10703 func rewriteValueARM64_OpARM64MOVHloadidx2(v *Value) bool {
10704         v_2 := v.Args[2]
10705         v_1 := v.Args[1]
10706         v_0 := v.Args[0]
10707         // match: (MOVHloadidx2 ptr (MOVDconst [c]) mem)
10708         // cond: is32Bit(c<<1)
10709         // result: (MOVHload [int32(c)<<1] ptr mem)
10710         for {
10711                 ptr := v_0
10712                 if v_1.Op != OpARM64MOVDconst {
10713                         break
10714                 }
10715                 c := auxIntToInt64(v_1.AuxInt)
10716                 mem := v_2
10717                 if !(is32Bit(c << 1)) {
10718                         break
10719                 }
10720                 v.reset(OpARM64MOVHload)
10721                 v.AuxInt = int32ToAuxInt(int32(c) << 1)
10722                 v.AddArg2(ptr, mem)
10723                 return true
10724         }
10725         // match: (MOVHloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _))
10726         // cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
10727         // result: (MOVDconst [0])
10728         for {
10729                 ptr := v_0
10730                 idx := v_1
10731                 if v_2.Op != OpARM64MOVHstorezeroidx2 {
10732                         break
10733                 }
10734                 idx2 := v_2.Args[1]
10735                 ptr2 := v_2.Args[0]
10736                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
10737                         break
10738                 }
10739                 v.reset(OpARM64MOVDconst)
10740                 v.AuxInt = int64ToAuxInt(0)
10741                 return true
10742         }
10743         return false
10744 }
10745 func rewriteValueARM64_OpARM64MOVHreg(v *Value) bool {
10746         v_0 := v.Args[0]
10747         // match: (MOVHreg x:(MOVBload _ _))
10748         // result: (MOVDreg x)
10749         for {
10750                 x := v_0
10751                 if x.Op != OpARM64MOVBload {
10752                         break
10753                 }
10754                 v.reset(OpARM64MOVDreg)
10755                 v.AddArg(x)
10756                 return true
10757         }
10758         // match: (MOVHreg x:(MOVBUload _ _))
10759         // result: (MOVDreg x)
10760         for {
10761                 x := v_0
10762                 if x.Op != OpARM64MOVBUload {
10763                         break
10764                 }
10765                 v.reset(OpARM64MOVDreg)
10766                 v.AddArg(x)
10767                 return true
10768         }
10769         // match: (MOVHreg x:(MOVHload _ _))
10770         // result: (MOVDreg x)
10771         for {
10772                 x := v_0
10773                 if x.Op != OpARM64MOVHload {
10774                         break
10775                 }
10776                 v.reset(OpARM64MOVDreg)
10777                 v.AddArg(x)
10778                 return true
10779         }
10780         // match: (MOVHreg x:(MOVBloadidx _ _ _))
10781         // result: (MOVDreg x)
10782         for {
10783                 x := v_0
10784                 if x.Op != OpARM64MOVBloadidx {
10785                         break
10786                 }
10787                 v.reset(OpARM64MOVDreg)
10788                 v.AddArg(x)
10789                 return true
10790         }
10791         // match: (MOVHreg x:(MOVBUloadidx _ _ _))
10792         // result: (MOVDreg x)
10793         for {
10794                 x := v_0
10795                 if x.Op != OpARM64MOVBUloadidx {
10796                         break
10797                 }
10798                 v.reset(OpARM64MOVDreg)
10799                 v.AddArg(x)
10800                 return true
10801         }
10802         // match: (MOVHreg x:(MOVHloadidx _ _ _))
10803         // result: (MOVDreg x)
10804         for {
10805                 x := v_0
10806                 if x.Op != OpARM64MOVHloadidx {
10807                         break
10808                 }
10809                 v.reset(OpARM64MOVDreg)
10810                 v.AddArg(x)
10811                 return true
10812         }
10813         // match: (MOVHreg x:(MOVHloadidx2 _ _ _))
10814         // result: (MOVDreg x)
10815         for {
10816                 x := v_0
10817                 if x.Op != OpARM64MOVHloadidx2 {
10818                         break
10819                 }
10820                 v.reset(OpARM64MOVDreg)
10821                 v.AddArg(x)
10822                 return true
10823         }
10824         // match: (MOVHreg x:(MOVBreg _))
10825         // result: (MOVDreg x)
10826         for {
10827                 x := v_0
10828                 if x.Op != OpARM64MOVBreg {
10829                         break
10830                 }
10831                 v.reset(OpARM64MOVDreg)
10832                 v.AddArg(x)
10833                 return true
10834         }
10835         // match: (MOVHreg x:(MOVBUreg _))
10836         // result: (MOVDreg x)
10837         for {
10838                 x := v_0
10839                 if x.Op != OpARM64MOVBUreg {
10840                         break
10841                 }
10842                 v.reset(OpARM64MOVDreg)
10843                 v.AddArg(x)
10844                 return true
10845         }
10846         // match: (MOVHreg x:(MOVHreg _))
10847         // result: (MOVDreg x)
10848         for {
10849                 x := v_0
10850                 if x.Op != OpARM64MOVHreg {
10851                         break
10852                 }
10853                 v.reset(OpARM64MOVDreg)
10854                 v.AddArg(x)
10855                 return true
10856         }
10857         // match: (MOVHreg (MOVDconst [c]))
10858         // result: (MOVDconst [int64(int16(c))])
10859         for {
10860                 if v_0.Op != OpARM64MOVDconst {
10861                         break
10862                 }
10863                 c := auxIntToInt64(v_0.AuxInt)
10864                 v.reset(OpARM64MOVDconst)
10865                 v.AuxInt = int64ToAuxInt(int64(int16(c)))
10866                 return true
10867         }
10868         // match: (MOVHreg x)
10869         // cond: v.Type.Size() <= 2
10870         // result: x
10871         for {
10872                 x := v_0
10873                 if !(v.Type.Size() <= 2) {
10874                         break
10875                 }
10876                 v.copyOf(x)
10877                 return true
10878         }
10879         // match: (MOVHreg <t> (ANDconst x [c]))
10880         // cond: uint64(c) & uint64(0xffffffffffff8000) == 0
10881         // result: (ANDconst <t> x [c])
10882         for {
10883                 t := v.Type
10884                 if v_0.Op != OpARM64ANDconst {
10885                         break
10886                 }
10887                 c := auxIntToInt64(v_0.AuxInt)
10888                 x := v_0.Args[0]
10889                 if !(uint64(c)&uint64(0xffffffffffff8000) == 0) {
10890                         break
10891                 }
10892                 v.reset(OpARM64ANDconst)
10893                 v.Type = t
10894                 v.AuxInt = int64ToAuxInt(c)
10895                 v.AddArg(x)
10896                 return true
10897         }
10898         // match: (MOVHreg (SLLconst [lc] x))
10899         // cond: lc < 16
10900         // result: (SBFIZ [armBFAuxInt(lc, 16-lc)] x)
10901         for {
10902                 if v_0.Op != OpARM64SLLconst {
10903                         break
10904                 }
10905                 lc := auxIntToInt64(v_0.AuxInt)
10906                 x := v_0.Args[0]
10907                 if !(lc < 16) {
10908                         break
10909                 }
10910                 v.reset(OpARM64SBFIZ)
10911                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 16-lc))
10912                 v.AddArg(x)
10913                 return true
10914         }
10915         // match: (MOVHreg (SBFX [bfc] x))
10916         // cond: bfc.getARM64BFwidth() <= 16
10917         // result: (SBFX [bfc] x)
10918         for {
10919                 if v_0.Op != OpARM64SBFX {
10920                         break
10921                 }
10922                 bfc := auxIntToArm64BitField(v_0.AuxInt)
10923                 x := v_0.Args[0]
10924                 if !(bfc.getARM64BFwidth() <= 16) {
10925                         break
10926                 }
10927                 v.reset(OpARM64SBFX)
10928                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
10929                 v.AddArg(x)
10930                 return true
10931         }
10932         return false
10933 }
10934 func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
10935         v_2 := v.Args[2]
10936         v_1 := v.Args[1]
10937         v_0 := v.Args[0]
10938         b := v.Block
10939         config := b.Func.Config
10940         // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
10941         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
10942         // result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
10943         for {
10944                 off1 := auxIntToInt32(v.AuxInt)
10945                 sym := auxToSym(v.Aux)
10946                 if v_0.Op != OpARM64ADDconst {
10947                         break
10948                 }
10949                 off2 := auxIntToInt64(v_0.AuxInt)
10950                 ptr := v_0.Args[0]
10951                 val := v_1
10952                 mem := v_2
10953                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
10954                         break
10955                 }
10956                 v.reset(OpARM64MOVHstore)
10957                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
10958                 v.Aux = symToAux(sym)
10959                 v.AddArg3(ptr, val, mem)
10960                 return true
10961         }
10962         // match: (MOVHstore [off] {sym} (ADD ptr idx) val mem)
10963         // cond: off == 0 && sym == nil
10964         // result: (MOVHstoreidx ptr idx val mem)
10965         for {
10966                 off := auxIntToInt32(v.AuxInt)
10967                 sym := auxToSym(v.Aux)
10968                 if v_0.Op != OpARM64ADD {
10969                         break
10970                 }
10971                 idx := v_0.Args[1]
10972                 ptr := v_0.Args[0]
10973                 val := v_1
10974                 mem := v_2
10975                 if !(off == 0 && sym == nil) {
10976                         break
10977                 }
10978                 v.reset(OpARM64MOVHstoreidx)
10979                 v.AddArg4(ptr, idx, val, mem)
10980                 return true
10981         }
10982         // match: (MOVHstore [off] {sym} (ADDshiftLL [1] ptr idx) val mem)
10983         // cond: off == 0 && sym == nil
10984         // result: (MOVHstoreidx2 ptr idx val mem)
10985         for {
10986                 off := auxIntToInt32(v.AuxInt)
10987                 sym := auxToSym(v.Aux)
10988                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
10989                         break
10990                 }
10991                 idx := v_0.Args[1]
10992                 ptr := v_0.Args[0]
10993                 val := v_1
10994                 mem := v_2
10995                 if !(off == 0 && sym == nil) {
10996                         break
10997                 }
10998                 v.reset(OpARM64MOVHstoreidx2)
10999                 v.AddArg4(ptr, idx, val, mem)
11000                 return true
11001         }
11002         // match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
11003         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11004         // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
11005         for {
11006                 off1 := auxIntToInt32(v.AuxInt)
11007                 sym1 := auxToSym(v.Aux)
11008                 if v_0.Op != OpARM64MOVDaddr {
11009                         break
11010                 }
11011                 off2 := auxIntToInt32(v_0.AuxInt)
11012                 sym2 := auxToSym(v_0.Aux)
11013                 ptr := v_0.Args[0]
11014                 val := v_1
11015                 mem := v_2
11016                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11017                         break
11018                 }
11019                 v.reset(OpARM64MOVHstore)
11020                 v.AuxInt = int32ToAuxInt(off1 + off2)
11021                 v.Aux = symToAux(mergeSym(sym1, sym2))
11022                 v.AddArg3(ptr, val, mem)
11023                 return true
11024         }
11025         // match: (MOVHstore [off] {sym} ptr (MOVDconst [0]) mem)
11026         // result: (MOVHstorezero [off] {sym} ptr mem)
11027         for {
11028                 off := auxIntToInt32(v.AuxInt)
11029                 sym := auxToSym(v.Aux)
11030                 ptr := v_0
11031                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
11032                         break
11033                 }
11034                 mem := v_2
11035                 v.reset(OpARM64MOVHstorezero)
11036                 v.AuxInt = int32ToAuxInt(off)
11037                 v.Aux = symToAux(sym)
11038                 v.AddArg2(ptr, mem)
11039                 return true
11040         }
11041         // match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem)
11042         // result: (MOVHstore [off] {sym} ptr x mem)
11043         for {
11044                 off := auxIntToInt32(v.AuxInt)
11045                 sym := auxToSym(v.Aux)
11046                 ptr := v_0
11047                 if v_1.Op != OpARM64MOVHreg {
11048                         break
11049                 }
11050                 x := v_1.Args[0]
11051                 mem := v_2
11052                 v.reset(OpARM64MOVHstore)
11053                 v.AuxInt = int32ToAuxInt(off)
11054                 v.Aux = symToAux(sym)
11055                 v.AddArg3(ptr, x, mem)
11056                 return true
11057         }
11058         // match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem)
11059         // result: (MOVHstore [off] {sym} ptr x mem)
11060         for {
11061                 off := auxIntToInt32(v.AuxInt)
11062                 sym := auxToSym(v.Aux)
11063                 ptr := v_0
11064                 if v_1.Op != OpARM64MOVHUreg {
11065                         break
11066                 }
11067                 x := v_1.Args[0]
11068                 mem := v_2
11069                 v.reset(OpARM64MOVHstore)
11070                 v.AuxInt = int32ToAuxInt(off)
11071                 v.Aux = symToAux(sym)
11072                 v.AddArg3(ptr, x, mem)
11073                 return true
11074         }
11075         // match: (MOVHstore [off] {sym} ptr (MOVWreg x) mem)
11076         // result: (MOVHstore [off] {sym} ptr x mem)
11077         for {
11078                 off := auxIntToInt32(v.AuxInt)
11079                 sym := auxToSym(v.Aux)
11080                 ptr := v_0
11081                 if v_1.Op != OpARM64MOVWreg {
11082                         break
11083                 }
11084                 x := v_1.Args[0]
11085                 mem := v_2
11086                 v.reset(OpARM64MOVHstore)
11087                 v.AuxInt = int32ToAuxInt(off)
11088                 v.Aux = symToAux(sym)
11089                 v.AddArg3(ptr, x, mem)
11090                 return true
11091         }
11092         // match: (MOVHstore [off] {sym} ptr (MOVWUreg x) mem)
11093         // result: (MOVHstore [off] {sym} ptr x mem)
11094         for {
11095                 off := auxIntToInt32(v.AuxInt)
11096                 sym := auxToSym(v.Aux)
11097                 ptr := v_0
11098                 if v_1.Op != OpARM64MOVWUreg {
11099                         break
11100                 }
11101                 x := v_1.Args[0]
11102                 mem := v_2
11103                 v.reset(OpARM64MOVHstore)
11104                 v.AuxInt = int32ToAuxInt(off)
11105                 v.Aux = symToAux(sym)
11106                 v.AddArg3(ptr, x, mem)
11107                 return true
11108         }
11109         return false
11110 }
11111 func rewriteValueARM64_OpARM64MOVHstoreidx(v *Value) bool {
11112         v_3 := v.Args[3]
11113         v_2 := v.Args[2]
11114         v_1 := v.Args[1]
11115         v_0 := v.Args[0]
11116         // match: (MOVHstoreidx ptr (MOVDconst [c]) val mem)
11117         // cond: is32Bit(c)
11118         // result: (MOVHstore [int32(c)] ptr val mem)
11119         for {
11120                 ptr := v_0
11121                 if v_1.Op != OpARM64MOVDconst {
11122                         break
11123                 }
11124                 c := auxIntToInt64(v_1.AuxInt)
11125                 val := v_2
11126                 mem := v_3
11127                 if !(is32Bit(c)) {
11128                         break
11129                 }
11130                 v.reset(OpARM64MOVHstore)
11131                 v.AuxInt = int32ToAuxInt(int32(c))
11132                 v.AddArg3(ptr, val, mem)
11133                 return true
11134         }
11135         // match: (MOVHstoreidx (MOVDconst [c]) idx val mem)
11136         // cond: is32Bit(c)
11137         // result: (MOVHstore [int32(c)] idx val mem)
11138         for {
11139                 if v_0.Op != OpARM64MOVDconst {
11140                         break
11141                 }
11142                 c := auxIntToInt64(v_0.AuxInt)
11143                 idx := v_1
11144                 val := v_2
11145                 mem := v_3
11146                 if !(is32Bit(c)) {
11147                         break
11148                 }
11149                 v.reset(OpARM64MOVHstore)
11150                 v.AuxInt = int32ToAuxInt(int32(c))
11151                 v.AddArg3(idx, val, mem)
11152                 return true
11153         }
11154         // match: (MOVHstoreidx ptr (SLLconst [1] idx) val mem)
11155         // result: (MOVHstoreidx2 ptr idx val mem)
11156         for {
11157                 ptr := v_0
11158                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
11159                         break
11160                 }
11161                 idx := v_1.Args[0]
11162                 val := v_2
11163                 mem := v_3
11164                 v.reset(OpARM64MOVHstoreidx2)
11165                 v.AddArg4(ptr, idx, val, mem)
11166                 return true
11167         }
11168         // match: (MOVHstoreidx ptr (ADD idx idx) val mem)
11169         // result: (MOVHstoreidx2 ptr idx val mem)
11170         for {
11171                 ptr := v_0
11172                 if v_1.Op != OpARM64ADD {
11173                         break
11174                 }
11175                 idx := v_1.Args[1]
11176                 if idx != v_1.Args[0] {
11177                         break
11178                 }
11179                 val := v_2
11180                 mem := v_3
11181                 v.reset(OpARM64MOVHstoreidx2)
11182                 v.AddArg4(ptr, idx, val, mem)
11183                 return true
11184         }
11185         // match: (MOVHstoreidx (SLLconst [1] idx) ptr val mem)
11186         // result: (MOVHstoreidx2 ptr idx val mem)
11187         for {
11188                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 1 {
11189                         break
11190                 }
11191                 idx := v_0.Args[0]
11192                 ptr := v_1
11193                 val := v_2
11194                 mem := v_3
11195                 v.reset(OpARM64MOVHstoreidx2)
11196                 v.AddArg4(ptr, idx, val, mem)
11197                 return true
11198         }
11199         // match: (MOVHstoreidx (ADD idx idx) ptr val mem)
11200         // result: (MOVHstoreidx2 ptr idx val mem)
11201         for {
11202                 if v_0.Op != OpARM64ADD {
11203                         break
11204                 }
11205                 idx := v_0.Args[1]
11206                 if idx != v_0.Args[0] {
11207                         break
11208                 }
11209                 ptr := v_1
11210                 val := v_2
11211                 mem := v_3
11212                 v.reset(OpARM64MOVHstoreidx2)
11213                 v.AddArg4(ptr, idx, val, mem)
11214                 return true
11215         }
11216         // match: (MOVHstoreidx ptr idx (MOVDconst [0]) mem)
11217         // result: (MOVHstorezeroidx ptr idx mem)
11218         for {
11219                 ptr := v_0
11220                 idx := v_1
11221                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
11222                         break
11223                 }
11224                 mem := v_3
11225                 v.reset(OpARM64MOVHstorezeroidx)
11226                 v.AddArg3(ptr, idx, mem)
11227                 return true
11228         }
11229         // match: (MOVHstoreidx ptr idx (MOVHreg x) mem)
11230         // result: (MOVHstoreidx ptr idx x mem)
11231         for {
11232                 ptr := v_0
11233                 idx := v_1
11234                 if v_2.Op != OpARM64MOVHreg {
11235                         break
11236                 }
11237                 x := v_2.Args[0]
11238                 mem := v_3
11239                 v.reset(OpARM64MOVHstoreidx)
11240                 v.AddArg4(ptr, idx, x, mem)
11241                 return true
11242         }
11243         // match: (MOVHstoreidx ptr idx (MOVHUreg x) mem)
11244         // result: (MOVHstoreidx ptr idx x mem)
11245         for {
11246                 ptr := v_0
11247                 idx := v_1
11248                 if v_2.Op != OpARM64MOVHUreg {
11249                         break
11250                 }
11251                 x := v_2.Args[0]
11252                 mem := v_3
11253                 v.reset(OpARM64MOVHstoreidx)
11254                 v.AddArg4(ptr, idx, x, mem)
11255                 return true
11256         }
11257         // match: (MOVHstoreidx ptr idx (MOVWreg x) mem)
11258         // result: (MOVHstoreidx ptr idx x mem)
11259         for {
11260                 ptr := v_0
11261                 idx := v_1
11262                 if v_2.Op != OpARM64MOVWreg {
11263                         break
11264                 }
11265                 x := v_2.Args[0]
11266                 mem := v_3
11267                 v.reset(OpARM64MOVHstoreidx)
11268                 v.AddArg4(ptr, idx, x, mem)
11269                 return true
11270         }
11271         // match: (MOVHstoreidx ptr idx (MOVWUreg x) mem)
11272         // result: (MOVHstoreidx ptr idx x mem)
11273         for {
11274                 ptr := v_0
11275                 idx := v_1
11276                 if v_2.Op != OpARM64MOVWUreg {
11277                         break
11278                 }
11279                 x := v_2.Args[0]
11280                 mem := v_3
11281                 v.reset(OpARM64MOVHstoreidx)
11282                 v.AddArg4(ptr, idx, x, mem)
11283                 return true
11284         }
11285         return false
11286 }
11287 func rewriteValueARM64_OpARM64MOVHstoreidx2(v *Value) bool {
11288         v_3 := v.Args[3]
11289         v_2 := v.Args[2]
11290         v_1 := v.Args[1]
11291         v_0 := v.Args[0]
11292         // match: (MOVHstoreidx2 ptr (MOVDconst [c]) val mem)
11293         // cond: is32Bit(c<<1)
11294         // result: (MOVHstore [int32(c)<<1] ptr val mem)
11295         for {
11296                 ptr := v_0
11297                 if v_1.Op != OpARM64MOVDconst {
11298                         break
11299                 }
11300                 c := auxIntToInt64(v_1.AuxInt)
11301                 val := v_2
11302                 mem := v_3
11303                 if !(is32Bit(c << 1)) {
11304                         break
11305                 }
11306                 v.reset(OpARM64MOVHstore)
11307                 v.AuxInt = int32ToAuxInt(int32(c) << 1)
11308                 v.AddArg3(ptr, val, mem)
11309                 return true
11310         }
11311         // match: (MOVHstoreidx2 ptr idx (MOVDconst [0]) mem)
11312         // result: (MOVHstorezeroidx2 ptr idx mem)
11313         for {
11314                 ptr := v_0
11315                 idx := v_1
11316                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
11317                         break
11318                 }
11319                 mem := v_3
11320                 v.reset(OpARM64MOVHstorezeroidx2)
11321                 v.AddArg3(ptr, idx, mem)
11322                 return true
11323         }
11324         // match: (MOVHstoreidx2 ptr idx (MOVHreg x) mem)
11325         // result: (MOVHstoreidx2 ptr idx x mem)
11326         for {
11327                 ptr := v_0
11328                 idx := v_1
11329                 if v_2.Op != OpARM64MOVHreg {
11330                         break
11331                 }
11332                 x := v_2.Args[0]
11333                 mem := v_3
11334                 v.reset(OpARM64MOVHstoreidx2)
11335                 v.AddArg4(ptr, idx, x, mem)
11336                 return true
11337         }
11338         // match: (MOVHstoreidx2 ptr idx (MOVHUreg x) mem)
11339         // result: (MOVHstoreidx2 ptr idx x mem)
11340         for {
11341                 ptr := v_0
11342                 idx := v_1
11343                 if v_2.Op != OpARM64MOVHUreg {
11344                         break
11345                 }
11346                 x := v_2.Args[0]
11347                 mem := v_3
11348                 v.reset(OpARM64MOVHstoreidx2)
11349                 v.AddArg4(ptr, idx, x, mem)
11350                 return true
11351         }
11352         // match: (MOVHstoreidx2 ptr idx (MOVWreg x) mem)
11353         // result: (MOVHstoreidx2 ptr idx x mem)
11354         for {
11355                 ptr := v_0
11356                 idx := v_1
11357                 if v_2.Op != OpARM64MOVWreg {
11358                         break
11359                 }
11360                 x := v_2.Args[0]
11361                 mem := v_3
11362                 v.reset(OpARM64MOVHstoreidx2)
11363                 v.AddArg4(ptr, idx, x, mem)
11364                 return true
11365         }
11366         // match: (MOVHstoreidx2 ptr idx (MOVWUreg x) mem)
11367         // result: (MOVHstoreidx2 ptr idx x mem)
11368         for {
11369                 ptr := v_0
11370                 idx := v_1
11371                 if v_2.Op != OpARM64MOVWUreg {
11372                         break
11373                 }
11374                 x := v_2.Args[0]
11375                 mem := v_3
11376                 v.reset(OpARM64MOVHstoreidx2)
11377                 v.AddArg4(ptr, idx, x, mem)
11378                 return true
11379         }
11380         return false
11381 }
11382 func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
11383         v_1 := v.Args[1]
11384         v_0 := v.Args[0]
11385         b := v.Block
11386         config := b.Func.Config
11387         // match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
11388         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11389         // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
11390         for {
11391                 off1 := auxIntToInt32(v.AuxInt)
11392                 sym := auxToSym(v.Aux)
11393                 if v_0.Op != OpARM64ADDconst {
11394                         break
11395                 }
11396                 off2 := auxIntToInt64(v_0.AuxInt)
11397                 ptr := v_0.Args[0]
11398                 mem := v_1
11399                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11400                         break
11401                 }
11402                 v.reset(OpARM64MOVHstorezero)
11403                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
11404                 v.Aux = symToAux(sym)
11405                 v.AddArg2(ptr, mem)
11406                 return true
11407         }
11408         // match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
11409         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11410         // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
11411         for {
11412                 off1 := auxIntToInt32(v.AuxInt)
11413                 sym1 := auxToSym(v.Aux)
11414                 if v_0.Op != OpARM64MOVDaddr {
11415                         break
11416                 }
11417                 off2 := auxIntToInt32(v_0.AuxInt)
11418                 sym2 := auxToSym(v_0.Aux)
11419                 ptr := v_0.Args[0]
11420                 mem := v_1
11421                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11422                         break
11423                 }
11424                 v.reset(OpARM64MOVHstorezero)
11425                 v.AuxInt = int32ToAuxInt(off1 + off2)
11426                 v.Aux = symToAux(mergeSym(sym1, sym2))
11427                 v.AddArg2(ptr, mem)
11428                 return true
11429         }
11430         // match: (MOVHstorezero [off] {sym} (ADD ptr idx) mem)
11431         // cond: off == 0 && sym == nil
11432         // result: (MOVHstorezeroidx ptr idx mem)
11433         for {
11434                 off := auxIntToInt32(v.AuxInt)
11435                 sym := auxToSym(v.Aux)
11436                 if v_0.Op != OpARM64ADD {
11437                         break
11438                 }
11439                 idx := v_0.Args[1]
11440                 ptr := v_0.Args[0]
11441                 mem := v_1
11442                 if !(off == 0 && sym == nil) {
11443                         break
11444                 }
11445                 v.reset(OpARM64MOVHstorezeroidx)
11446                 v.AddArg3(ptr, idx, mem)
11447                 return true
11448         }
11449         // match: (MOVHstorezero [off] {sym} (ADDshiftLL [1] ptr idx) mem)
11450         // cond: off == 0 && sym == nil
11451         // result: (MOVHstorezeroidx2 ptr idx mem)
11452         for {
11453                 off := auxIntToInt32(v.AuxInt)
11454                 sym := auxToSym(v.Aux)
11455                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
11456                         break
11457                 }
11458                 idx := v_0.Args[1]
11459                 ptr := v_0.Args[0]
11460                 mem := v_1
11461                 if !(off == 0 && sym == nil) {
11462                         break
11463                 }
11464                 v.reset(OpARM64MOVHstorezeroidx2)
11465                 v.AddArg3(ptr, idx, mem)
11466                 return true
11467         }
11468         return false
11469 }
11470 func rewriteValueARM64_OpARM64MOVHstorezeroidx(v *Value) bool {
11471         v_2 := v.Args[2]
11472         v_1 := v.Args[1]
11473         v_0 := v.Args[0]
11474         // match: (MOVHstorezeroidx ptr (MOVDconst [c]) mem)
11475         // cond: is32Bit(c)
11476         // result: (MOVHstorezero [int32(c)] ptr mem)
11477         for {
11478                 ptr := v_0
11479                 if v_1.Op != OpARM64MOVDconst {
11480                         break
11481                 }
11482                 c := auxIntToInt64(v_1.AuxInt)
11483                 mem := v_2
11484                 if !(is32Bit(c)) {
11485                         break
11486                 }
11487                 v.reset(OpARM64MOVHstorezero)
11488                 v.AuxInt = int32ToAuxInt(int32(c))
11489                 v.AddArg2(ptr, mem)
11490                 return true
11491         }
11492         // match: (MOVHstorezeroidx (MOVDconst [c]) idx mem)
11493         // cond: is32Bit(c)
11494         // result: (MOVHstorezero [int32(c)] idx mem)
11495         for {
11496                 if v_0.Op != OpARM64MOVDconst {
11497                         break
11498                 }
11499                 c := auxIntToInt64(v_0.AuxInt)
11500                 idx := v_1
11501                 mem := v_2
11502                 if !(is32Bit(c)) {
11503                         break
11504                 }
11505                 v.reset(OpARM64MOVHstorezero)
11506                 v.AuxInt = int32ToAuxInt(int32(c))
11507                 v.AddArg2(idx, mem)
11508                 return true
11509         }
11510         // match: (MOVHstorezeroidx ptr (SLLconst [1] idx) mem)
11511         // result: (MOVHstorezeroidx2 ptr idx mem)
11512         for {
11513                 ptr := v_0
11514                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
11515                         break
11516                 }
11517                 idx := v_1.Args[0]
11518                 mem := v_2
11519                 v.reset(OpARM64MOVHstorezeroidx2)
11520                 v.AddArg3(ptr, idx, mem)
11521                 return true
11522         }
11523         // match: (MOVHstorezeroidx ptr (ADD idx idx) mem)
11524         // result: (MOVHstorezeroidx2 ptr idx mem)
11525         for {
11526                 ptr := v_0
11527                 if v_1.Op != OpARM64ADD {
11528                         break
11529                 }
11530                 idx := v_1.Args[1]
11531                 if idx != v_1.Args[0] {
11532                         break
11533                 }
11534                 mem := v_2
11535                 v.reset(OpARM64MOVHstorezeroidx2)
11536                 v.AddArg3(ptr, idx, mem)
11537                 return true
11538         }
11539         // match: (MOVHstorezeroidx (SLLconst [1] idx) ptr mem)
11540         // result: (MOVHstorezeroidx2 ptr idx mem)
11541         for {
11542                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 1 {
11543                         break
11544                 }
11545                 idx := v_0.Args[0]
11546                 ptr := v_1
11547                 mem := v_2
11548                 v.reset(OpARM64MOVHstorezeroidx2)
11549                 v.AddArg3(ptr, idx, mem)
11550                 return true
11551         }
11552         // match: (MOVHstorezeroidx (ADD idx idx) ptr mem)
11553         // result: (MOVHstorezeroidx2 ptr idx mem)
11554         for {
11555                 if v_0.Op != OpARM64ADD {
11556                         break
11557                 }
11558                 idx := v_0.Args[1]
11559                 if idx != v_0.Args[0] {
11560                         break
11561                 }
11562                 ptr := v_1
11563                 mem := v_2
11564                 v.reset(OpARM64MOVHstorezeroidx2)
11565                 v.AddArg3(ptr, idx, mem)
11566                 return true
11567         }
11568         return false
11569 }
11570 func rewriteValueARM64_OpARM64MOVHstorezeroidx2(v *Value) bool {
11571         v_2 := v.Args[2]
11572         v_1 := v.Args[1]
11573         v_0 := v.Args[0]
11574         // match: (MOVHstorezeroidx2 ptr (MOVDconst [c]) mem)
11575         // cond: is32Bit(c<<1)
11576         // result: (MOVHstorezero [int32(c<<1)] ptr mem)
11577         for {
11578                 ptr := v_0
11579                 if v_1.Op != OpARM64MOVDconst {
11580                         break
11581                 }
11582                 c := auxIntToInt64(v_1.AuxInt)
11583                 mem := v_2
11584                 if !(is32Bit(c << 1)) {
11585                         break
11586                 }
11587                 v.reset(OpARM64MOVHstorezero)
11588                 v.AuxInt = int32ToAuxInt(int32(c << 1))
11589                 v.AddArg2(ptr, mem)
11590                 return true
11591         }
11592         return false
11593 }
11594 func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
11595         v_1 := v.Args[1]
11596         v_0 := v.Args[0]
11597         b := v.Block
11598         config := b.Func.Config
11599         // match: (MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
11600         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11601         // result: (MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
11602         for {
11603                 off1 := auxIntToInt32(v.AuxInt)
11604                 sym := auxToSym(v.Aux)
11605                 if v_0.Op != OpARM64ADDconst {
11606                         break
11607                 }
11608                 off2 := auxIntToInt64(v_0.AuxInt)
11609                 ptr := v_0.Args[0]
11610                 mem := v_1
11611                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11612                         break
11613                 }
11614                 v.reset(OpARM64MOVQstorezero)
11615                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
11616                 v.Aux = symToAux(sym)
11617                 v.AddArg2(ptr, mem)
11618                 return true
11619         }
11620         // match: (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
11621         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11622         // result: (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
11623         for {
11624                 off1 := auxIntToInt32(v.AuxInt)
11625                 sym1 := auxToSym(v.Aux)
11626                 if v_0.Op != OpARM64MOVDaddr {
11627                         break
11628                 }
11629                 off2 := auxIntToInt32(v_0.AuxInt)
11630                 sym2 := auxToSym(v_0.Aux)
11631                 ptr := v_0.Args[0]
11632                 mem := v_1
11633                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11634                         break
11635                 }
11636                 v.reset(OpARM64MOVQstorezero)
11637                 v.AuxInt = int32ToAuxInt(off1 + off2)
11638                 v.Aux = symToAux(mergeSym(sym1, sym2))
11639                 v.AddArg2(ptr, mem)
11640                 return true
11641         }
11642         return false
11643 }
11644 func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool {
11645         v_1 := v.Args[1]
11646         v_0 := v.Args[0]
11647         b := v.Block
11648         config := b.Func.Config
11649         // match: (MOVWUload [off] {sym} ptr (FMOVSstore [off] {sym} ptr val _))
11650         // result: (FMOVSfpgp val)
11651         for {
11652                 off := auxIntToInt32(v.AuxInt)
11653                 sym := auxToSym(v.Aux)
11654                 ptr := v_0
11655                 if v_1.Op != OpARM64FMOVSstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
11656                         break
11657                 }
11658                 val := v_1.Args[1]
11659                 if ptr != v_1.Args[0] {
11660                         break
11661                 }
11662                 v.reset(OpARM64FMOVSfpgp)
11663                 v.AddArg(val)
11664                 return true
11665         }
11666         // match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
11667         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11668         // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem)
11669         for {
11670                 off1 := auxIntToInt32(v.AuxInt)
11671                 sym := auxToSym(v.Aux)
11672                 if v_0.Op != OpARM64ADDconst {
11673                         break
11674                 }
11675                 off2 := auxIntToInt64(v_0.AuxInt)
11676                 ptr := v_0.Args[0]
11677                 mem := v_1
11678                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11679                         break
11680                 }
11681                 v.reset(OpARM64MOVWUload)
11682                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
11683                 v.Aux = symToAux(sym)
11684                 v.AddArg2(ptr, mem)
11685                 return true
11686         }
11687         // match: (MOVWUload [off] {sym} (ADD ptr idx) mem)
11688         // cond: off == 0 && sym == nil
11689         // result: (MOVWUloadidx ptr idx mem)
11690         for {
11691                 off := auxIntToInt32(v.AuxInt)
11692                 sym := auxToSym(v.Aux)
11693                 if v_0.Op != OpARM64ADD {
11694                         break
11695                 }
11696                 idx := v_0.Args[1]
11697                 ptr := v_0.Args[0]
11698                 mem := v_1
11699                 if !(off == 0 && sym == nil) {
11700                         break
11701                 }
11702                 v.reset(OpARM64MOVWUloadidx)
11703                 v.AddArg3(ptr, idx, mem)
11704                 return true
11705         }
11706         // match: (MOVWUload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
11707         // cond: off == 0 && sym == nil
11708         // result: (MOVWUloadidx4 ptr idx mem)
11709         for {
11710                 off := auxIntToInt32(v.AuxInt)
11711                 sym := auxToSym(v.Aux)
11712                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
11713                         break
11714                 }
11715                 idx := v_0.Args[1]
11716                 ptr := v_0.Args[0]
11717                 mem := v_1
11718                 if !(off == 0 && sym == nil) {
11719                         break
11720                 }
11721                 v.reset(OpARM64MOVWUloadidx4)
11722                 v.AddArg3(ptr, idx, mem)
11723                 return true
11724         }
11725         // match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
11726         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
11727         // result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
11728         for {
11729                 off1 := auxIntToInt32(v.AuxInt)
11730                 sym1 := auxToSym(v.Aux)
11731                 if v_0.Op != OpARM64MOVDaddr {
11732                         break
11733                 }
11734                 off2 := auxIntToInt32(v_0.AuxInt)
11735                 sym2 := auxToSym(v_0.Aux)
11736                 ptr := v_0.Args[0]
11737                 mem := v_1
11738                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
11739                         break
11740                 }
11741                 v.reset(OpARM64MOVWUload)
11742                 v.AuxInt = int32ToAuxInt(off1 + off2)
11743                 v.Aux = symToAux(mergeSym(sym1, sym2))
11744                 v.AddArg2(ptr, mem)
11745                 return true
11746         }
11747         // match: (MOVWUload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _))
11748         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
11749         // result: (MOVDconst [0])
11750         for {
11751                 off := auxIntToInt32(v.AuxInt)
11752                 sym := auxToSym(v.Aux)
11753                 ptr := v_0
11754                 if v_1.Op != OpARM64MOVWstorezero {
11755                         break
11756                 }
11757                 off2 := auxIntToInt32(v_1.AuxInt)
11758                 sym2 := auxToSym(v_1.Aux)
11759                 ptr2 := v_1.Args[0]
11760                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
11761                         break
11762                 }
11763                 v.reset(OpARM64MOVDconst)
11764                 v.AuxInt = int64ToAuxInt(0)
11765                 return true
11766         }
11767         // match: (MOVWUload [off] {sym} (SB) _)
11768         // cond: symIsRO(sym)
11769         // result: (MOVDconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
11770         for {
11771                 off := auxIntToInt32(v.AuxInt)
11772                 sym := auxToSym(v.Aux)
11773                 if v_0.Op != OpSB || !(symIsRO(sym)) {
11774                         break
11775                 }
11776                 v.reset(OpARM64MOVDconst)
11777                 v.AuxInt = int64ToAuxInt(int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder)))
11778                 return true
11779         }
11780         return false
11781 }
11782 func rewriteValueARM64_OpARM64MOVWUloadidx(v *Value) bool {
11783         v_2 := v.Args[2]
11784         v_1 := v.Args[1]
11785         v_0 := v.Args[0]
11786         // match: (MOVWUloadidx ptr (MOVDconst [c]) mem)
11787         // cond: is32Bit(c)
11788         // result: (MOVWUload [int32(c)] ptr mem)
11789         for {
11790                 ptr := v_0
11791                 if v_1.Op != OpARM64MOVDconst {
11792                         break
11793                 }
11794                 c := auxIntToInt64(v_1.AuxInt)
11795                 mem := v_2
11796                 if !(is32Bit(c)) {
11797                         break
11798                 }
11799                 v.reset(OpARM64MOVWUload)
11800                 v.AuxInt = int32ToAuxInt(int32(c))
11801                 v.AddArg2(ptr, mem)
11802                 return true
11803         }
11804         // match: (MOVWUloadidx (MOVDconst [c]) ptr mem)
11805         // cond: is32Bit(c)
11806         // result: (MOVWUload [int32(c)] ptr mem)
11807         for {
11808                 if v_0.Op != OpARM64MOVDconst {
11809                         break
11810                 }
11811                 c := auxIntToInt64(v_0.AuxInt)
11812                 ptr := v_1
11813                 mem := v_2
11814                 if !(is32Bit(c)) {
11815                         break
11816                 }
11817                 v.reset(OpARM64MOVWUload)
11818                 v.AuxInt = int32ToAuxInt(int32(c))
11819                 v.AddArg2(ptr, mem)
11820                 return true
11821         }
11822         // match: (MOVWUloadidx ptr (SLLconst [2] idx) mem)
11823         // result: (MOVWUloadidx4 ptr idx mem)
11824         for {
11825                 ptr := v_0
11826                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
11827                         break
11828                 }
11829                 idx := v_1.Args[0]
11830                 mem := v_2
11831                 v.reset(OpARM64MOVWUloadidx4)
11832                 v.AddArg3(ptr, idx, mem)
11833                 return true
11834         }
11835         // match: (MOVWUloadidx (SLLconst [2] idx) ptr mem)
11836         // result: (MOVWUloadidx4 ptr idx mem)
11837         for {
11838                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
11839                         break
11840                 }
11841                 idx := v_0.Args[0]
11842                 ptr := v_1
11843                 mem := v_2
11844                 v.reset(OpARM64MOVWUloadidx4)
11845                 v.AddArg3(ptr, idx, mem)
11846                 return true
11847         }
11848         // match: (MOVWUloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
11849         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
11850         // result: (MOVDconst [0])
11851         for {
11852                 ptr := v_0
11853                 idx := v_1
11854                 if v_2.Op != OpARM64MOVWstorezeroidx {
11855                         break
11856                 }
11857                 idx2 := v_2.Args[1]
11858                 ptr2 := v_2.Args[0]
11859                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
11860                         break
11861                 }
11862                 v.reset(OpARM64MOVDconst)
11863                 v.AuxInt = int64ToAuxInt(0)
11864                 return true
11865         }
11866         return false
11867 }
11868 func rewriteValueARM64_OpARM64MOVWUloadidx4(v *Value) bool {
11869         v_2 := v.Args[2]
11870         v_1 := v.Args[1]
11871         v_0 := v.Args[0]
11872         // match: (MOVWUloadidx4 ptr (MOVDconst [c]) mem)
11873         // cond: is32Bit(c<<2)
11874         // result: (MOVWUload [int32(c)<<2] ptr mem)
11875         for {
11876                 ptr := v_0
11877                 if v_1.Op != OpARM64MOVDconst {
11878                         break
11879                 }
11880                 c := auxIntToInt64(v_1.AuxInt)
11881                 mem := v_2
11882                 if !(is32Bit(c << 2)) {
11883                         break
11884                 }
11885                 v.reset(OpARM64MOVWUload)
11886                 v.AuxInt = int32ToAuxInt(int32(c) << 2)
11887                 v.AddArg2(ptr, mem)
11888                 return true
11889         }
11890         // match: (MOVWUloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _))
11891         // cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
11892         // result: (MOVDconst [0])
11893         for {
11894                 ptr := v_0
11895                 idx := v_1
11896                 if v_2.Op != OpARM64MOVWstorezeroidx4 {
11897                         break
11898                 }
11899                 idx2 := v_2.Args[1]
11900                 ptr2 := v_2.Args[0]
11901                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
11902                         break
11903                 }
11904                 v.reset(OpARM64MOVDconst)
11905                 v.AuxInt = int64ToAuxInt(0)
11906                 return true
11907         }
11908         return false
11909 }
11910 func rewriteValueARM64_OpARM64MOVWUreg(v *Value) bool {
11911         v_0 := v.Args[0]
11912         // match: (MOVWUreg x:(MOVBUload _ _))
11913         // result: (MOVDreg x)
11914         for {
11915                 x := v_0
11916                 if x.Op != OpARM64MOVBUload {
11917                         break
11918                 }
11919                 v.reset(OpARM64MOVDreg)
11920                 v.AddArg(x)
11921                 return true
11922         }
11923         // match: (MOVWUreg x:(MOVHUload _ _))
11924         // result: (MOVDreg x)
11925         for {
11926                 x := v_0
11927                 if x.Op != OpARM64MOVHUload {
11928                         break
11929                 }
11930                 v.reset(OpARM64MOVDreg)
11931                 v.AddArg(x)
11932                 return true
11933         }
11934         // match: (MOVWUreg x:(MOVWUload _ _))
11935         // result: (MOVDreg x)
11936         for {
11937                 x := v_0
11938                 if x.Op != OpARM64MOVWUload {
11939                         break
11940                 }
11941                 v.reset(OpARM64MOVDreg)
11942                 v.AddArg(x)
11943                 return true
11944         }
11945         // match: (MOVWUreg x:(MOVBUloadidx _ _ _))
11946         // result: (MOVDreg x)
11947         for {
11948                 x := v_0
11949                 if x.Op != OpARM64MOVBUloadidx {
11950                         break
11951                 }
11952                 v.reset(OpARM64MOVDreg)
11953                 v.AddArg(x)
11954                 return true
11955         }
11956         // match: (MOVWUreg x:(MOVHUloadidx _ _ _))
11957         // result: (MOVDreg x)
11958         for {
11959                 x := v_0
11960                 if x.Op != OpARM64MOVHUloadidx {
11961                         break
11962                 }
11963                 v.reset(OpARM64MOVDreg)
11964                 v.AddArg(x)
11965                 return true
11966         }
11967         // match: (MOVWUreg x:(MOVWUloadidx _ _ _))
11968         // result: (MOVDreg x)
11969         for {
11970                 x := v_0
11971                 if x.Op != OpARM64MOVWUloadidx {
11972                         break
11973                 }
11974                 v.reset(OpARM64MOVDreg)
11975                 v.AddArg(x)
11976                 return true
11977         }
11978         // match: (MOVWUreg x:(MOVHUloadidx2 _ _ _))
11979         // result: (MOVDreg x)
11980         for {
11981                 x := v_0
11982                 if x.Op != OpARM64MOVHUloadidx2 {
11983                         break
11984                 }
11985                 v.reset(OpARM64MOVDreg)
11986                 v.AddArg(x)
11987                 return true
11988         }
11989         // match: (MOVWUreg x:(MOVWUloadidx4 _ _ _))
11990         // result: (MOVDreg x)
11991         for {
11992                 x := v_0
11993                 if x.Op != OpARM64MOVWUloadidx4 {
11994                         break
11995                 }
11996                 v.reset(OpARM64MOVDreg)
11997                 v.AddArg(x)
11998                 return true
11999         }
12000         // match: (MOVWUreg x:(MOVBUreg _))
12001         // result: (MOVDreg x)
12002         for {
12003                 x := v_0
12004                 if x.Op != OpARM64MOVBUreg {
12005                         break
12006                 }
12007                 v.reset(OpARM64MOVDreg)
12008                 v.AddArg(x)
12009                 return true
12010         }
12011         // match: (MOVWUreg x:(MOVHUreg _))
12012         // result: (MOVDreg x)
12013         for {
12014                 x := v_0
12015                 if x.Op != OpARM64MOVHUreg {
12016                         break
12017                 }
12018                 v.reset(OpARM64MOVDreg)
12019                 v.AddArg(x)
12020                 return true
12021         }
12022         // match: (MOVWUreg x:(MOVWUreg _))
12023         // result: (MOVDreg x)
12024         for {
12025                 x := v_0
12026                 if x.Op != OpARM64MOVWUreg {
12027                         break
12028                 }
12029                 v.reset(OpARM64MOVDreg)
12030                 v.AddArg(x)
12031                 return true
12032         }
12033         // match: (MOVWUreg (ANDconst [c] x))
12034         // result: (ANDconst [c&(1<<32-1)] x)
12035         for {
12036                 if v_0.Op != OpARM64ANDconst {
12037                         break
12038                 }
12039                 c := auxIntToInt64(v_0.AuxInt)
12040                 x := v_0.Args[0]
12041                 v.reset(OpARM64ANDconst)
12042                 v.AuxInt = int64ToAuxInt(c & (1<<32 - 1))
12043                 v.AddArg(x)
12044                 return true
12045         }
12046         // match: (MOVWUreg (MOVDconst [c]))
12047         // result: (MOVDconst [int64(uint32(c))])
12048         for {
12049                 if v_0.Op != OpARM64MOVDconst {
12050                         break
12051                 }
12052                 c := auxIntToInt64(v_0.AuxInt)
12053                 v.reset(OpARM64MOVDconst)
12054                 v.AuxInt = int64ToAuxInt(int64(uint32(c)))
12055                 return true
12056         }
12057         // match: (MOVWUreg x)
12058         // cond: v.Type.Size() <= 4
12059         // result: x
12060         for {
12061                 x := v_0
12062                 if !(v.Type.Size() <= 4) {
12063                         break
12064                 }
12065                 v.copyOf(x)
12066                 return true
12067         }
12068         // match: (MOVWUreg x)
12069         // cond: zeroUpper32Bits(x, 3)
12070         // result: x
12071         for {
12072                 x := v_0
12073                 if !(zeroUpper32Bits(x, 3)) {
12074                         break
12075                 }
12076                 v.copyOf(x)
12077                 return true
12078         }
12079         // match: (MOVWUreg (SLLconst [lc] x))
12080         // cond: lc >= 32
12081         // result: (MOVDconst [0])
12082         for {
12083                 if v_0.Op != OpARM64SLLconst {
12084                         break
12085                 }
12086                 lc := auxIntToInt64(v_0.AuxInt)
12087                 if !(lc >= 32) {
12088                         break
12089                 }
12090                 v.reset(OpARM64MOVDconst)
12091                 v.AuxInt = int64ToAuxInt(0)
12092                 return true
12093         }
12094         // match: (MOVWUreg (SLLconst [lc] x))
12095         // cond: lc < 32
12096         // result: (UBFIZ [armBFAuxInt(lc, 32-lc)] x)
12097         for {
12098                 if v_0.Op != OpARM64SLLconst {
12099                         break
12100                 }
12101                 lc := auxIntToInt64(v_0.AuxInt)
12102                 x := v_0.Args[0]
12103                 if !(lc < 32) {
12104                         break
12105                 }
12106                 v.reset(OpARM64UBFIZ)
12107                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 32-lc))
12108                 v.AddArg(x)
12109                 return true
12110         }
12111         // match: (MOVWUreg (SRLconst [rc] x))
12112         // cond: rc < 32
12113         // result: (UBFX [armBFAuxInt(rc, 32)] x)
12114         for {
12115                 if v_0.Op != OpARM64SRLconst {
12116                         break
12117                 }
12118                 rc := auxIntToInt64(v_0.AuxInt)
12119                 x := v_0.Args[0]
12120                 if !(rc < 32) {
12121                         break
12122                 }
12123                 v.reset(OpARM64UBFX)
12124                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 32))
12125                 v.AddArg(x)
12126                 return true
12127         }
12128         // match: (MOVWUreg (UBFX [bfc] x))
12129         // cond: bfc.getARM64BFwidth() <= 32
12130         // result: (UBFX [bfc] x)
12131         for {
12132                 if v_0.Op != OpARM64UBFX {
12133                         break
12134                 }
12135                 bfc := auxIntToArm64BitField(v_0.AuxInt)
12136                 x := v_0.Args[0]
12137                 if !(bfc.getARM64BFwidth() <= 32) {
12138                         break
12139                 }
12140                 v.reset(OpARM64UBFX)
12141                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
12142                 v.AddArg(x)
12143                 return true
12144         }
12145         return false
12146 }
12147 func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
12148         v_1 := v.Args[1]
12149         v_0 := v.Args[0]
12150         b := v.Block
12151         config := b.Func.Config
12152         // match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
12153         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
12154         // result: (MOVWload [off1+int32(off2)] {sym} ptr mem)
12155         for {
12156                 off1 := auxIntToInt32(v.AuxInt)
12157                 sym := auxToSym(v.Aux)
12158                 if v_0.Op != OpARM64ADDconst {
12159                         break
12160                 }
12161                 off2 := auxIntToInt64(v_0.AuxInt)
12162                 ptr := v_0.Args[0]
12163                 mem := v_1
12164                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
12165                         break
12166                 }
12167                 v.reset(OpARM64MOVWload)
12168                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
12169                 v.Aux = symToAux(sym)
12170                 v.AddArg2(ptr, mem)
12171                 return true
12172         }
12173         // match: (MOVWload [off] {sym} (ADD ptr idx) mem)
12174         // cond: off == 0 && sym == nil
12175         // result: (MOVWloadidx ptr idx mem)
12176         for {
12177                 off := auxIntToInt32(v.AuxInt)
12178                 sym := auxToSym(v.Aux)
12179                 if v_0.Op != OpARM64ADD {
12180                         break
12181                 }
12182                 idx := v_0.Args[1]
12183                 ptr := v_0.Args[0]
12184                 mem := v_1
12185                 if !(off == 0 && sym == nil) {
12186                         break
12187                 }
12188                 v.reset(OpARM64MOVWloadidx)
12189                 v.AddArg3(ptr, idx, mem)
12190                 return true
12191         }
12192         // match: (MOVWload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
12193         // cond: off == 0 && sym == nil
12194         // result: (MOVWloadidx4 ptr idx mem)
12195         for {
12196                 off := auxIntToInt32(v.AuxInt)
12197                 sym := auxToSym(v.Aux)
12198                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
12199                         break
12200                 }
12201                 idx := v_0.Args[1]
12202                 ptr := v_0.Args[0]
12203                 mem := v_1
12204                 if !(off == 0 && sym == nil) {
12205                         break
12206                 }
12207                 v.reset(OpARM64MOVWloadidx4)
12208                 v.AddArg3(ptr, idx, mem)
12209                 return true
12210         }
12211         // match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
12212         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
12213         // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
12214         for {
12215                 off1 := auxIntToInt32(v.AuxInt)
12216                 sym1 := auxToSym(v.Aux)
12217                 if v_0.Op != OpARM64MOVDaddr {
12218                         break
12219                 }
12220                 off2 := auxIntToInt32(v_0.AuxInt)
12221                 sym2 := auxToSym(v_0.Aux)
12222                 ptr := v_0.Args[0]
12223                 mem := v_1
12224                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
12225                         break
12226                 }
12227                 v.reset(OpARM64MOVWload)
12228                 v.AuxInt = int32ToAuxInt(off1 + off2)
12229                 v.Aux = symToAux(mergeSym(sym1, sym2))
12230                 v.AddArg2(ptr, mem)
12231                 return true
12232         }
12233         // match: (MOVWload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _))
12234         // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
12235         // result: (MOVDconst [0])
12236         for {
12237                 off := auxIntToInt32(v.AuxInt)
12238                 sym := auxToSym(v.Aux)
12239                 ptr := v_0
12240                 if v_1.Op != OpARM64MOVWstorezero {
12241                         break
12242                 }
12243                 off2 := auxIntToInt32(v_1.AuxInt)
12244                 sym2 := auxToSym(v_1.Aux)
12245                 ptr2 := v_1.Args[0]
12246                 if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
12247                         break
12248                 }
12249                 v.reset(OpARM64MOVDconst)
12250                 v.AuxInt = int64ToAuxInt(0)
12251                 return true
12252         }
12253         return false
12254 }
12255 func rewriteValueARM64_OpARM64MOVWloadidx(v *Value) bool {
12256         v_2 := v.Args[2]
12257         v_1 := v.Args[1]
12258         v_0 := v.Args[0]
12259         // match: (MOVWloadidx ptr (MOVDconst [c]) mem)
12260         // cond: is32Bit(c)
12261         // result: (MOVWload [int32(c)] ptr mem)
12262         for {
12263                 ptr := v_0
12264                 if v_1.Op != OpARM64MOVDconst {
12265                         break
12266                 }
12267                 c := auxIntToInt64(v_1.AuxInt)
12268                 mem := v_2
12269                 if !(is32Bit(c)) {
12270                         break
12271                 }
12272                 v.reset(OpARM64MOVWload)
12273                 v.AuxInt = int32ToAuxInt(int32(c))
12274                 v.AddArg2(ptr, mem)
12275                 return true
12276         }
12277         // match: (MOVWloadidx (MOVDconst [c]) ptr mem)
12278         // cond: is32Bit(c)
12279         // result: (MOVWload [int32(c)] ptr mem)
12280         for {
12281                 if v_0.Op != OpARM64MOVDconst {
12282                         break
12283                 }
12284                 c := auxIntToInt64(v_0.AuxInt)
12285                 ptr := v_1
12286                 mem := v_2
12287                 if !(is32Bit(c)) {
12288                         break
12289                 }
12290                 v.reset(OpARM64MOVWload)
12291                 v.AuxInt = int32ToAuxInt(int32(c))
12292                 v.AddArg2(ptr, mem)
12293                 return true
12294         }
12295         // match: (MOVWloadidx ptr (SLLconst [2] idx) mem)
12296         // result: (MOVWloadidx4 ptr idx mem)
12297         for {
12298                 ptr := v_0
12299                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
12300                         break
12301                 }
12302                 idx := v_1.Args[0]
12303                 mem := v_2
12304                 v.reset(OpARM64MOVWloadidx4)
12305                 v.AddArg3(ptr, idx, mem)
12306                 return true
12307         }
12308         // match: (MOVWloadidx (SLLconst [2] idx) ptr mem)
12309         // result: (MOVWloadidx4 ptr idx mem)
12310         for {
12311                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
12312                         break
12313                 }
12314                 idx := v_0.Args[0]
12315                 ptr := v_1
12316                 mem := v_2
12317                 v.reset(OpARM64MOVWloadidx4)
12318                 v.AddArg3(ptr, idx, mem)
12319                 return true
12320         }
12321         // match: (MOVWloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
12322         // cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
12323         // result: (MOVDconst [0])
12324         for {
12325                 ptr := v_0
12326                 idx := v_1
12327                 if v_2.Op != OpARM64MOVWstorezeroidx {
12328                         break
12329                 }
12330                 idx2 := v_2.Args[1]
12331                 ptr2 := v_2.Args[0]
12332                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
12333                         break
12334                 }
12335                 v.reset(OpARM64MOVDconst)
12336                 v.AuxInt = int64ToAuxInt(0)
12337                 return true
12338         }
12339         return false
12340 }
12341 func rewriteValueARM64_OpARM64MOVWloadidx4(v *Value) bool {
12342         v_2 := v.Args[2]
12343         v_1 := v.Args[1]
12344         v_0 := v.Args[0]
12345         // match: (MOVWloadidx4 ptr (MOVDconst [c]) mem)
12346         // cond: is32Bit(c<<2)
12347         // result: (MOVWload [int32(c)<<2] ptr mem)
12348         for {
12349                 ptr := v_0
12350                 if v_1.Op != OpARM64MOVDconst {
12351                         break
12352                 }
12353                 c := auxIntToInt64(v_1.AuxInt)
12354                 mem := v_2
12355                 if !(is32Bit(c << 2)) {
12356                         break
12357                 }
12358                 v.reset(OpARM64MOVWload)
12359                 v.AuxInt = int32ToAuxInt(int32(c) << 2)
12360                 v.AddArg2(ptr, mem)
12361                 return true
12362         }
12363         // match: (MOVWloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _))
12364         // cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
12365         // result: (MOVDconst [0])
12366         for {
12367                 ptr := v_0
12368                 idx := v_1
12369                 if v_2.Op != OpARM64MOVWstorezeroidx4 {
12370                         break
12371                 }
12372                 idx2 := v_2.Args[1]
12373                 ptr2 := v_2.Args[0]
12374                 if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
12375                         break
12376                 }
12377                 v.reset(OpARM64MOVDconst)
12378                 v.AuxInt = int64ToAuxInt(0)
12379                 return true
12380         }
12381         return false
12382 }
12383 func rewriteValueARM64_OpARM64MOVWreg(v *Value) bool {
12384         v_0 := v.Args[0]
12385         // match: (MOVWreg x:(MOVBload _ _))
12386         // result: (MOVDreg x)
12387         for {
12388                 x := v_0
12389                 if x.Op != OpARM64MOVBload {
12390                         break
12391                 }
12392                 v.reset(OpARM64MOVDreg)
12393                 v.AddArg(x)
12394                 return true
12395         }
12396         // match: (MOVWreg x:(MOVBUload _ _))
12397         // result: (MOVDreg x)
12398         for {
12399                 x := v_0
12400                 if x.Op != OpARM64MOVBUload {
12401                         break
12402                 }
12403                 v.reset(OpARM64MOVDreg)
12404                 v.AddArg(x)
12405                 return true
12406         }
12407         // match: (MOVWreg x:(MOVHload _ _))
12408         // result: (MOVDreg x)
12409         for {
12410                 x := v_0
12411                 if x.Op != OpARM64MOVHload {
12412                         break
12413                 }
12414                 v.reset(OpARM64MOVDreg)
12415                 v.AddArg(x)
12416                 return true
12417         }
12418         // match: (MOVWreg x:(MOVHUload _ _))
12419         // result: (MOVDreg x)
12420         for {
12421                 x := v_0
12422                 if x.Op != OpARM64MOVHUload {
12423                         break
12424                 }
12425                 v.reset(OpARM64MOVDreg)
12426                 v.AddArg(x)
12427                 return true
12428         }
12429         // match: (MOVWreg x:(MOVWload _ _))
12430         // result: (MOVDreg x)
12431         for {
12432                 x := v_0
12433                 if x.Op != OpARM64MOVWload {
12434                         break
12435                 }
12436                 v.reset(OpARM64MOVDreg)
12437                 v.AddArg(x)
12438                 return true
12439         }
12440         // match: (MOVWreg x:(MOVBloadidx _ _ _))
12441         // result: (MOVDreg x)
12442         for {
12443                 x := v_0
12444                 if x.Op != OpARM64MOVBloadidx {
12445                         break
12446                 }
12447                 v.reset(OpARM64MOVDreg)
12448                 v.AddArg(x)
12449                 return true
12450         }
12451         // match: (MOVWreg x:(MOVBUloadidx _ _ _))
12452         // result: (MOVDreg x)
12453         for {
12454                 x := v_0
12455                 if x.Op != OpARM64MOVBUloadidx {
12456                         break
12457                 }
12458                 v.reset(OpARM64MOVDreg)
12459                 v.AddArg(x)
12460                 return true
12461         }
12462         // match: (MOVWreg x:(MOVHloadidx _ _ _))
12463         // result: (MOVDreg x)
12464         for {
12465                 x := v_0
12466                 if x.Op != OpARM64MOVHloadidx {
12467                         break
12468                 }
12469                 v.reset(OpARM64MOVDreg)
12470                 v.AddArg(x)
12471                 return true
12472         }
12473         // match: (MOVWreg x:(MOVHUloadidx _ _ _))
12474         // result: (MOVDreg x)
12475         for {
12476                 x := v_0
12477                 if x.Op != OpARM64MOVHUloadidx {
12478                         break
12479                 }
12480                 v.reset(OpARM64MOVDreg)
12481                 v.AddArg(x)
12482                 return true
12483         }
12484         // match: (MOVWreg x:(MOVWloadidx _ _ _))
12485         // result: (MOVDreg x)
12486         for {
12487                 x := v_0
12488                 if x.Op != OpARM64MOVWloadidx {
12489                         break
12490                 }
12491                 v.reset(OpARM64MOVDreg)
12492                 v.AddArg(x)
12493                 return true
12494         }
12495         // match: (MOVWreg x:(MOVHloadidx2 _ _ _))
12496         // result: (MOVDreg x)
12497         for {
12498                 x := v_0
12499                 if x.Op != OpARM64MOVHloadidx2 {
12500                         break
12501                 }
12502                 v.reset(OpARM64MOVDreg)
12503                 v.AddArg(x)
12504                 return true
12505         }
12506         // match: (MOVWreg x:(MOVHUloadidx2 _ _ _))
12507         // result: (MOVDreg x)
12508         for {
12509                 x := v_0
12510                 if x.Op != OpARM64MOVHUloadidx2 {
12511                         break
12512                 }
12513                 v.reset(OpARM64MOVDreg)
12514                 v.AddArg(x)
12515                 return true
12516         }
12517         // match: (MOVWreg x:(MOVWloadidx4 _ _ _))
12518         // result: (MOVDreg x)
12519         for {
12520                 x := v_0
12521                 if x.Op != OpARM64MOVWloadidx4 {
12522                         break
12523                 }
12524                 v.reset(OpARM64MOVDreg)
12525                 v.AddArg(x)
12526                 return true
12527         }
12528         // match: (MOVWreg x:(MOVBreg _))
12529         // result: (MOVDreg x)
12530         for {
12531                 x := v_0
12532                 if x.Op != OpARM64MOVBreg {
12533                         break
12534                 }
12535                 v.reset(OpARM64MOVDreg)
12536                 v.AddArg(x)
12537                 return true
12538         }
12539         // match: (MOVWreg x:(MOVBUreg _))
12540         // result: (MOVDreg x)
12541         for {
12542                 x := v_0
12543                 if x.Op != OpARM64MOVBUreg {
12544                         break
12545                 }
12546                 v.reset(OpARM64MOVDreg)
12547                 v.AddArg(x)
12548                 return true
12549         }
12550         // match: (MOVWreg x:(MOVHreg _))
12551         // result: (MOVDreg x)
12552         for {
12553                 x := v_0
12554                 if x.Op != OpARM64MOVHreg {
12555                         break
12556                 }
12557                 v.reset(OpARM64MOVDreg)
12558                 v.AddArg(x)
12559                 return true
12560         }
12561         // match: (MOVWreg x:(MOVWreg _))
12562         // result: (MOVDreg x)
12563         for {
12564                 x := v_0
12565                 if x.Op != OpARM64MOVWreg {
12566                         break
12567                 }
12568                 v.reset(OpARM64MOVDreg)
12569                 v.AddArg(x)
12570                 return true
12571         }
12572         // match: (MOVWreg (MOVDconst [c]))
12573         // result: (MOVDconst [int64(int32(c))])
12574         for {
12575                 if v_0.Op != OpARM64MOVDconst {
12576                         break
12577                 }
12578                 c := auxIntToInt64(v_0.AuxInt)
12579                 v.reset(OpARM64MOVDconst)
12580                 v.AuxInt = int64ToAuxInt(int64(int32(c)))
12581                 return true
12582         }
12583         // match: (MOVWreg x)
12584         // cond: v.Type.Size() <= 4
12585         // result: x
12586         for {
12587                 x := v_0
12588                 if !(v.Type.Size() <= 4) {
12589                         break
12590                 }
12591                 v.copyOf(x)
12592                 return true
12593         }
12594         // match: (MOVWreg <t> (ANDconst x [c]))
12595         // cond: uint64(c) & uint64(0xffffffff80000000) == 0
12596         // result: (ANDconst <t> x [c])
12597         for {
12598                 t := v.Type
12599                 if v_0.Op != OpARM64ANDconst {
12600                         break
12601                 }
12602                 c := auxIntToInt64(v_0.AuxInt)
12603                 x := v_0.Args[0]
12604                 if !(uint64(c)&uint64(0xffffffff80000000) == 0) {
12605                         break
12606                 }
12607                 v.reset(OpARM64ANDconst)
12608                 v.Type = t
12609                 v.AuxInt = int64ToAuxInt(c)
12610                 v.AddArg(x)
12611                 return true
12612         }
12613         // match: (MOVWreg (SLLconst [lc] x))
12614         // cond: lc < 32
12615         // result: (SBFIZ [armBFAuxInt(lc, 32-lc)] x)
12616         for {
12617                 if v_0.Op != OpARM64SLLconst {
12618                         break
12619                 }
12620                 lc := auxIntToInt64(v_0.AuxInt)
12621                 x := v_0.Args[0]
12622                 if !(lc < 32) {
12623                         break
12624                 }
12625                 v.reset(OpARM64SBFIZ)
12626                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 32-lc))
12627                 v.AddArg(x)
12628                 return true
12629         }
12630         // match: (MOVWreg (SBFX [bfc] x))
12631         // cond: bfc.getARM64BFwidth() <= 32
12632         // result: (SBFX [bfc] x)
12633         for {
12634                 if v_0.Op != OpARM64SBFX {
12635                         break
12636                 }
12637                 bfc := auxIntToArm64BitField(v_0.AuxInt)
12638                 x := v_0.Args[0]
12639                 if !(bfc.getARM64BFwidth() <= 32) {
12640                         break
12641                 }
12642                 v.reset(OpARM64SBFX)
12643                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
12644                 v.AddArg(x)
12645                 return true
12646         }
12647         return false
12648 }
12649 func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
12650         v_2 := v.Args[2]
12651         v_1 := v.Args[1]
12652         v_0 := v.Args[0]
12653         b := v.Block
12654         config := b.Func.Config
12655         // match: (MOVWstore [off] {sym} ptr (FMOVSfpgp val) mem)
12656         // result: (FMOVSstore [off] {sym} ptr val mem)
12657         for {
12658                 off := auxIntToInt32(v.AuxInt)
12659                 sym := auxToSym(v.Aux)
12660                 ptr := v_0
12661                 if v_1.Op != OpARM64FMOVSfpgp {
12662                         break
12663                 }
12664                 val := v_1.Args[0]
12665                 mem := v_2
12666                 v.reset(OpARM64FMOVSstore)
12667                 v.AuxInt = int32ToAuxInt(off)
12668                 v.Aux = symToAux(sym)
12669                 v.AddArg3(ptr, val, mem)
12670                 return true
12671         }
12672         // match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
12673         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
12674         // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
12675         for {
12676                 off1 := auxIntToInt32(v.AuxInt)
12677                 sym := auxToSym(v.Aux)
12678                 if v_0.Op != OpARM64ADDconst {
12679                         break
12680                 }
12681                 off2 := auxIntToInt64(v_0.AuxInt)
12682                 ptr := v_0.Args[0]
12683                 val := v_1
12684                 mem := v_2
12685                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
12686                         break
12687                 }
12688                 v.reset(OpARM64MOVWstore)
12689                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
12690                 v.Aux = symToAux(sym)
12691                 v.AddArg3(ptr, val, mem)
12692                 return true
12693         }
12694         // match: (MOVWstore [off] {sym} (ADD ptr idx) val mem)
12695         // cond: off == 0 && sym == nil
12696         // result: (MOVWstoreidx ptr idx val mem)
12697         for {
12698                 off := auxIntToInt32(v.AuxInt)
12699                 sym := auxToSym(v.Aux)
12700                 if v_0.Op != OpARM64ADD {
12701                         break
12702                 }
12703                 idx := v_0.Args[1]
12704                 ptr := v_0.Args[0]
12705                 val := v_1
12706                 mem := v_2
12707                 if !(off == 0 && sym == nil) {
12708                         break
12709                 }
12710                 v.reset(OpARM64MOVWstoreidx)
12711                 v.AddArg4(ptr, idx, val, mem)
12712                 return true
12713         }
12714         // match: (MOVWstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem)
12715         // cond: off == 0 && sym == nil
12716         // result: (MOVWstoreidx4 ptr idx val mem)
12717         for {
12718                 off := auxIntToInt32(v.AuxInt)
12719                 sym := auxToSym(v.Aux)
12720                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
12721                         break
12722                 }
12723                 idx := v_0.Args[1]
12724                 ptr := v_0.Args[0]
12725                 val := v_1
12726                 mem := v_2
12727                 if !(off == 0 && sym == nil) {
12728                         break
12729                 }
12730                 v.reset(OpARM64MOVWstoreidx4)
12731                 v.AddArg4(ptr, idx, val, mem)
12732                 return true
12733         }
12734         // match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
12735         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
12736         // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
12737         for {
12738                 off1 := auxIntToInt32(v.AuxInt)
12739                 sym1 := auxToSym(v.Aux)
12740                 if v_0.Op != OpARM64MOVDaddr {
12741                         break
12742                 }
12743                 off2 := auxIntToInt32(v_0.AuxInt)
12744                 sym2 := auxToSym(v_0.Aux)
12745                 ptr := v_0.Args[0]
12746                 val := v_1
12747                 mem := v_2
12748                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
12749                         break
12750                 }
12751                 v.reset(OpARM64MOVWstore)
12752                 v.AuxInt = int32ToAuxInt(off1 + off2)
12753                 v.Aux = symToAux(mergeSym(sym1, sym2))
12754                 v.AddArg3(ptr, val, mem)
12755                 return true
12756         }
12757         // match: (MOVWstore [off] {sym} ptr (MOVDconst [0]) mem)
12758         // result: (MOVWstorezero [off] {sym} ptr mem)
12759         for {
12760                 off := auxIntToInt32(v.AuxInt)
12761                 sym := auxToSym(v.Aux)
12762                 ptr := v_0
12763                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
12764                         break
12765                 }
12766                 mem := v_2
12767                 v.reset(OpARM64MOVWstorezero)
12768                 v.AuxInt = int32ToAuxInt(off)
12769                 v.Aux = symToAux(sym)
12770                 v.AddArg2(ptr, mem)
12771                 return true
12772         }
12773         // match: (MOVWstore [off] {sym} ptr (MOVWreg x) mem)
12774         // result: (MOVWstore [off] {sym} ptr x mem)
12775         for {
12776                 off := auxIntToInt32(v.AuxInt)
12777                 sym := auxToSym(v.Aux)
12778                 ptr := v_0
12779                 if v_1.Op != OpARM64MOVWreg {
12780                         break
12781                 }
12782                 x := v_1.Args[0]
12783                 mem := v_2
12784                 v.reset(OpARM64MOVWstore)
12785                 v.AuxInt = int32ToAuxInt(off)
12786                 v.Aux = symToAux(sym)
12787                 v.AddArg3(ptr, x, mem)
12788                 return true
12789         }
12790         // match: (MOVWstore [off] {sym} ptr (MOVWUreg x) mem)
12791         // result: (MOVWstore [off] {sym} ptr x mem)
12792         for {
12793                 off := auxIntToInt32(v.AuxInt)
12794                 sym := auxToSym(v.Aux)
12795                 ptr := v_0
12796                 if v_1.Op != OpARM64MOVWUreg {
12797                         break
12798                 }
12799                 x := v_1.Args[0]
12800                 mem := v_2
12801                 v.reset(OpARM64MOVWstore)
12802                 v.AuxInt = int32ToAuxInt(off)
12803                 v.Aux = symToAux(sym)
12804                 v.AddArg3(ptr, x, mem)
12805                 return true
12806         }
12807         return false
12808 }
12809 func rewriteValueARM64_OpARM64MOVWstoreidx(v *Value) bool {
12810         v_3 := v.Args[3]
12811         v_2 := v.Args[2]
12812         v_1 := v.Args[1]
12813         v_0 := v.Args[0]
12814         // match: (MOVWstoreidx ptr (MOVDconst [c]) val mem)
12815         // cond: is32Bit(c)
12816         // result: (MOVWstore [int32(c)] ptr val mem)
12817         for {
12818                 ptr := v_0
12819                 if v_1.Op != OpARM64MOVDconst {
12820                         break
12821                 }
12822                 c := auxIntToInt64(v_1.AuxInt)
12823                 val := v_2
12824                 mem := v_3
12825                 if !(is32Bit(c)) {
12826                         break
12827                 }
12828                 v.reset(OpARM64MOVWstore)
12829                 v.AuxInt = int32ToAuxInt(int32(c))
12830                 v.AddArg3(ptr, val, mem)
12831                 return true
12832         }
12833         // match: (MOVWstoreidx (MOVDconst [c]) idx val mem)
12834         // cond: is32Bit(c)
12835         // result: (MOVWstore [int32(c)] idx val mem)
12836         for {
12837                 if v_0.Op != OpARM64MOVDconst {
12838                         break
12839                 }
12840                 c := auxIntToInt64(v_0.AuxInt)
12841                 idx := v_1
12842                 val := v_2
12843                 mem := v_3
12844                 if !(is32Bit(c)) {
12845                         break
12846                 }
12847                 v.reset(OpARM64MOVWstore)
12848                 v.AuxInt = int32ToAuxInt(int32(c))
12849                 v.AddArg3(idx, val, mem)
12850                 return true
12851         }
12852         // match: (MOVWstoreidx ptr (SLLconst [2] idx) val mem)
12853         // result: (MOVWstoreidx4 ptr idx val mem)
12854         for {
12855                 ptr := v_0
12856                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
12857                         break
12858                 }
12859                 idx := v_1.Args[0]
12860                 val := v_2
12861                 mem := v_3
12862                 v.reset(OpARM64MOVWstoreidx4)
12863                 v.AddArg4(ptr, idx, val, mem)
12864                 return true
12865         }
12866         // match: (MOVWstoreidx (SLLconst [2] idx) ptr val mem)
12867         // result: (MOVWstoreidx4 ptr idx val mem)
12868         for {
12869                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
12870                         break
12871                 }
12872                 idx := v_0.Args[0]
12873                 ptr := v_1
12874                 val := v_2
12875                 mem := v_3
12876                 v.reset(OpARM64MOVWstoreidx4)
12877                 v.AddArg4(ptr, idx, val, mem)
12878                 return true
12879         }
12880         // match: (MOVWstoreidx ptr idx (MOVDconst [0]) mem)
12881         // result: (MOVWstorezeroidx ptr idx mem)
12882         for {
12883                 ptr := v_0
12884                 idx := v_1
12885                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
12886                         break
12887                 }
12888                 mem := v_3
12889                 v.reset(OpARM64MOVWstorezeroidx)
12890                 v.AddArg3(ptr, idx, mem)
12891                 return true
12892         }
12893         // match: (MOVWstoreidx ptr idx (MOVWreg x) mem)
12894         // result: (MOVWstoreidx ptr idx x mem)
12895         for {
12896                 ptr := v_0
12897                 idx := v_1
12898                 if v_2.Op != OpARM64MOVWreg {
12899                         break
12900                 }
12901                 x := v_2.Args[0]
12902                 mem := v_3
12903                 v.reset(OpARM64MOVWstoreidx)
12904                 v.AddArg4(ptr, idx, x, mem)
12905                 return true
12906         }
12907         // match: (MOVWstoreidx ptr idx (MOVWUreg x) mem)
12908         // result: (MOVWstoreidx ptr idx x mem)
12909         for {
12910                 ptr := v_0
12911                 idx := v_1
12912                 if v_2.Op != OpARM64MOVWUreg {
12913                         break
12914                 }
12915                 x := v_2.Args[0]
12916                 mem := v_3
12917                 v.reset(OpARM64MOVWstoreidx)
12918                 v.AddArg4(ptr, idx, x, mem)
12919                 return true
12920         }
12921         return false
12922 }
12923 func rewriteValueARM64_OpARM64MOVWstoreidx4(v *Value) bool {
12924         v_3 := v.Args[3]
12925         v_2 := v.Args[2]
12926         v_1 := v.Args[1]
12927         v_0 := v.Args[0]
12928         // match: (MOVWstoreidx4 ptr (MOVDconst [c]) val mem)
12929         // cond: is32Bit(c<<2)
12930         // result: (MOVWstore [int32(c)<<2] ptr val mem)
12931         for {
12932                 ptr := v_0
12933                 if v_1.Op != OpARM64MOVDconst {
12934                         break
12935                 }
12936                 c := auxIntToInt64(v_1.AuxInt)
12937                 val := v_2
12938                 mem := v_3
12939                 if !(is32Bit(c << 2)) {
12940                         break
12941                 }
12942                 v.reset(OpARM64MOVWstore)
12943                 v.AuxInt = int32ToAuxInt(int32(c) << 2)
12944                 v.AddArg3(ptr, val, mem)
12945                 return true
12946         }
12947         // match: (MOVWstoreidx4 ptr idx (MOVDconst [0]) mem)
12948         // result: (MOVWstorezeroidx4 ptr idx mem)
12949         for {
12950                 ptr := v_0
12951                 idx := v_1
12952                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
12953                         break
12954                 }
12955                 mem := v_3
12956                 v.reset(OpARM64MOVWstorezeroidx4)
12957                 v.AddArg3(ptr, idx, mem)
12958                 return true
12959         }
12960         // match: (MOVWstoreidx4 ptr idx (MOVWreg x) mem)
12961         // result: (MOVWstoreidx4 ptr idx x mem)
12962         for {
12963                 ptr := v_0
12964                 idx := v_1
12965                 if v_2.Op != OpARM64MOVWreg {
12966                         break
12967                 }
12968                 x := v_2.Args[0]
12969                 mem := v_3
12970                 v.reset(OpARM64MOVWstoreidx4)
12971                 v.AddArg4(ptr, idx, x, mem)
12972                 return true
12973         }
12974         // match: (MOVWstoreidx4 ptr idx (MOVWUreg x) mem)
12975         // result: (MOVWstoreidx4 ptr idx x mem)
12976         for {
12977                 ptr := v_0
12978                 idx := v_1
12979                 if v_2.Op != OpARM64MOVWUreg {
12980                         break
12981                 }
12982                 x := v_2.Args[0]
12983                 mem := v_3
12984                 v.reset(OpARM64MOVWstoreidx4)
12985                 v.AddArg4(ptr, idx, x, mem)
12986                 return true
12987         }
12988         return false
12989 }
12990 func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
12991         v_1 := v.Args[1]
12992         v_0 := v.Args[0]
12993         b := v.Block
12994         config := b.Func.Config
12995         // match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
12996         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
12997         // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
12998         for {
12999                 off1 := auxIntToInt32(v.AuxInt)
13000                 sym := auxToSym(v.Aux)
13001                 if v_0.Op != OpARM64ADDconst {
13002                         break
13003                 }
13004                 off2 := auxIntToInt64(v_0.AuxInt)
13005                 ptr := v_0.Args[0]
13006                 mem := v_1
13007                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
13008                         break
13009                 }
13010                 v.reset(OpARM64MOVWstorezero)
13011                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
13012                 v.Aux = symToAux(sym)
13013                 v.AddArg2(ptr, mem)
13014                 return true
13015         }
13016         // match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
13017         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
13018         // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
13019         for {
13020                 off1 := auxIntToInt32(v.AuxInt)
13021                 sym1 := auxToSym(v.Aux)
13022                 if v_0.Op != OpARM64MOVDaddr {
13023                         break
13024                 }
13025                 off2 := auxIntToInt32(v_0.AuxInt)
13026                 sym2 := auxToSym(v_0.Aux)
13027                 ptr := v_0.Args[0]
13028                 mem := v_1
13029                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
13030                         break
13031                 }
13032                 v.reset(OpARM64MOVWstorezero)
13033                 v.AuxInt = int32ToAuxInt(off1 + off2)
13034                 v.Aux = symToAux(mergeSym(sym1, sym2))
13035                 v.AddArg2(ptr, mem)
13036                 return true
13037         }
13038         // match: (MOVWstorezero [off] {sym} (ADD ptr idx) mem)
13039         // cond: off == 0 && sym == nil
13040         // result: (MOVWstorezeroidx ptr idx mem)
13041         for {
13042                 off := auxIntToInt32(v.AuxInt)
13043                 sym := auxToSym(v.Aux)
13044                 if v_0.Op != OpARM64ADD {
13045                         break
13046                 }
13047                 idx := v_0.Args[1]
13048                 ptr := v_0.Args[0]
13049                 mem := v_1
13050                 if !(off == 0 && sym == nil) {
13051                         break
13052                 }
13053                 v.reset(OpARM64MOVWstorezeroidx)
13054                 v.AddArg3(ptr, idx, mem)
13055                 return true
13056         }
13057         // match: (MOVWstorezero [off] {sym} (ADDshiftLL [2] ptr idx) mem)
13058         // cond: off == 0 && sym == nil
13059         // result: (MOVWstorezeroidx4 ptr idx mem)
13060         for {
13061                 off := auxIntToInt32(v.AuxInt)
13062                 sym := auxToSym(v.Aux)
13063                 if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
13064                         break
13065                 }
13066                 idx := v_0.Args[1]
13067                 ptr := v_0.Args[0]
13068                 mem := v_1
13069                 if !(off == 0 && sym == nil) {
13070                         break
13071                 }
13072                 v.reset(OpARM64MOVWstorezeroidx4)
13073                 v.AddArg3(ptr, idx, mem)
13074                 return true
13075         }
13076         return false
13077 }
13078 func rewriteValueARM64_OpARM64MOVWstorezeroidx(v *Value) bool {
13079         v_2 := v.Args[2]
13080         v_1 := v.Args[1]
13081         v_0 := v.Args[0]
13082         // match: (MOVWstorezeroidx ptr (MOVDconst [c]) mem)
13083         // cond: is32Bit(c)
13084         // result: (MOVWstorezero [int32(c)] ptr mem)
13085         for {
13086                 ptr := v_0
13087                 if v_1.Op != OpARM64MOVDconst {
13088                         break
13089                 }
13090                 c := auxIntToInt64(v_1.AuxInt)
13091                 mem := v_2
13092                 if !(is32Bit(c)) {
13093                         break
13094                 }
13095                 v.reset(OpARM64MOVWstorezero)
13096                 v.AuxInt = int32ToAuxInt(int32(c))
13097                 v.AddArg2(ptr, mem)
13098                 return true
13099         }
13100         // match: (MOVWstorezeroidx (MOVDconst [c]) idx mem)
13101         // cond: is32Bit(c)
13102         // result: (MOVWstorezero [int32(c)] idx mem)
13103         for {
13104                 if v_0.Op != OpARM64MOVDconst {
13105                         break
13106                 }
13107                 c := auxIntToInt64(v_0.AuxInt)
13108                 idx := v_1
13109                 mem := v_2
13110                 if !(is32Bit(c)) {
13111                         break
13112                 }
13113                 v.reset(OpARM64MOVWstorezero)
13114                 v.AuxInt = int32ToAuxInt(int32(c))
13115                 v.AddArg2(idx, mem)
13116                 return true
13117         }
13118         // match: (MOVWstorezeroidx ptr (SLLconst [2] idx) mem)
13119         // result: (MOVWstorezeroidx4 ptr idx mem)
13120         for {
13121                 ptr := v_0
13122                 if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
13123                         break
13124                 }
13125                 idx := v_1.Args[0]
13126                 mem := v_2
13127                 v.reset(OpARM64MOVWstorezeroidx4)
13128                 v.AddArg3(ptr, idx, mem)
13129                 return true
13130         }
13131         // match: (MOVWstorezeroidx (SLLconst [2] idx) ptr mem)
13132         // result: (MOVWstorezeroidx4 ptr idx mem)
13133         for {
13134                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
13135                         break
13136                 }
13137                 idx := v_0.Args[0]
13138                 ptr := v_1
13139                 mem := v_2
13140                 v.reset(OpARM64MOVWstorezeroidx4)
13141                 v.AddArg3(ptr, idx, mem)
13142                 return true
13143         }
13144         return false
13145 }
13146 func rewriteValueARM64_OpARM64MOVWstorezeroidx4(v *Value) bool {
13147         v_2 := v.Args[2]
13148         v_1 := v.Args[1]
13149         v_0 := v.Args[0]
13150         // match: (MOVWstorezeroidx4 ptr (MOVDconst [c]) mem)
13151         // cond: is32Bit(c<<2)
13152         // result: (MOVWstorezero [int32(c<<2)] ptr mem)
13153         for {
13154                 ptr := v_0
13155                 if v_1.Op != OpARM64MOVDconst {
13156                         break
13157                 }
13158                 c := auxIntToInt64(v_1.AuxInt)
13159                 mem := v_2
13160                 if !(is32Bit(c << 2)) {
13161                         break
13162                 }
13163                 v.reset(OpARM64MOVWstorezero)
13164                 v.AuxInt = int32ToAuxInt(int32(c << 2))
13165                 v.AddArg2(ptr, mem)
13166                 return true
13167         }
13168         return false
13169 }
13170 func rewriteValueARM64_OpARM64MSUB(v *Value) bool {
13171         v_2 := v.Args[2]
13172         v_1 := v.Args[1]
13173         v_0 := v.Args[0]
13174         b := v.Block
13175         // match: (MSUB a x (MOVDconst [-1]))
13176         // result: (ADD a x)
13177         for {
13178                 a := v_0
13179                 x := v_1
13180                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != -1 {
13181                         break
13182                 }
13183                 v.reset(OpARM64ADD)
13184                 v.AddArg2(a, x)
13185                 return true
13186         }
13187         // match: (MSUB a _ (MOVDconst [0]))
13188         // result: a
13189         for {
13190                 a := v_0
13191                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
13192                         break
13193                 }
13194                 v.copyOf(a)
13195                 return true
13196         }
13197         // match: (MSUB a x (MOVDconst [1]))
13198         // result: (SUB a x)
13199         for {
13200                 a := v_0
13201                 x := v_1
13202                 if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 1 {
13203                         break
13204                 }
13205                 v.reset(OpARM64SUB)
13206                 v.AddArg2(a, x)
13207                 return true
13208         }
13209         // match: (MSUB a x (MOVDconst [c]))
13210         // cond: isPowerOfTwo64(c)
13211         // result: (SUBshiftLL a x [log64(c)])
13212         for {
13213                 a := v_0
13214                 x := v_1
13215                 if v_2.Op != OpARM64MOVDconst {
13216                         break
13217                 }
13218                 c := auxIntToInt64(v_2.AuxInt)
13219                 if !(isPowerOfTwo64(c)) {
13220                         break
13221                 }
13222                 v.reset(OpARM64SUBshiftLL)
13223                 v.AuxInt = int64ToAuxInt(log64(c))
13224                 v.AddArg2(a, x)
13225                 return true
13226         }
13227         // match: (MSUB a x (MOVDconst [c]))
13228         // cond: isPowerOfTwo64(c-1) && c>=3
13229         // result: (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
13230         for {
13231                 a := v_0
13232                 x := v_1
13233                 if v_2.Op != OpARM64MOVDconst {
13234                         break
13235                 }
13236                 c := auxIntToInt64(v_2.AuxInt)
13237                 if !(isPowerOfTwo64(c-1) && c >= 3) {
13238                         break
13239                 }
13240                 v.reset(OpARM64SUB)
13241                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13242                 v0.AuxInt = int64ToAuxInt(log64(c - 1))
13243                 v0.AddArg2(x, x)
13244                 v.AddArg2(a, v0)
13245                 return true
13246         }
13247         // match: (MSUB a x (MOVDconst [c]))
13248         // cond: isPowerOfTwo64(c+1) && c>=7
13249         // result: (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
13250         for {
13251                 a := v_0
13252                 x := v_1
13253                 if v_2.Op != OpARM64MOVDconst {
13254                         break
13255                 }
13256                 c := auxIntToInt64(v_2.AuxInt)
13257                 if !(isPowerOfTwo64(c+1) && c >= 7) {
13258                         break
13259                 }
13260                 v.reset(OpARM64ADD)
13261                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13262                 v0.AuxInt = int64ToAuxInt(log64(c + 1))
13263                 v0.AddArg2(x, x)
13264                 v.AddArg2(a, v0)
13265                 return true
13266         }
13267         // match: (MSUB a x (MOVDconst [c]))
13268         // cond: c%3 == 0 && isPowerOfTwo64(c/3)
13269         // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
13270         for {
13271                 a := v_0
13272                 x := v_1
13273                 if v_2.Op != OpARM64MOVDconst {
13274                         break
13275                 }
13276                 c := auxIntToInt64(v_2.AuxInt)
13277                 if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
13278                         break
13279                 }
13280                 v.reset(OpARM64ADDshiftLL)
13281                 v.AuxInt = int64ToAuxInt(log64(c / 3))
13282                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13283                 v0.AuxInt = int64ToAuxInt(2)
13284                 v0.AddArg2(x, x)
13285                 v.AddArg2(a, v0)
13286                 return true
13287         }
13288         // match: (MSUB a x (MOVDconst [c]))
13289         // cond: c%5 == 0 && isPowerOfTwo64(c/5)
13290         // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
13291         for {
13292                 a := v_0
13293                 x := v_1
13294                 if v_2.Op != OpARM64MOVDconst {
13295                         break
13296                 }
13297                 c := auxIntToInt64(v_2.AuxInt)
13298                 if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
13299                         break
13300                 }
13301                 v.reset(OpARM64SUBshiftLL)
13302                 v.AuxInt = int64ToAuxInt(log64(c / 5))
13303                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13304                 v0.AuxInt = int64ToAuxInt(2)
13305                 v0.AddArg2(x, x)
13306                 v.AddArg2(a, v0)
13307                 return true
13308         }
13309         // match: (MSUB a x (MOVDconst [c]))
13310         // cond: c%7 == 0 && isPowerOfTwo64(c/7)
13311         // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
13312         for {
13313                 a := v_0
13314                 x := v_1
13315                 if v_2.Op != OpARM64MOVDconst {
13316                         break
13317                 }
13318                 c := auxIntToInt64(v_2.AuxInt)
13319                 if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
13320                         break
13321                 }
13322                 v.reset(OpARM64ADDshiftLL)
13323                 v.AuxInt = int64ToAuxInt(log64(c / 7))
13324                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13325                 v0.AuxInt = int64ToAuxInt(3)
13326                 v0.AddArg2(x, x)
13327                 v.AddArg2(a, v0)
13328                 return true
13329         }
13330         // match: (MSUB a x (MOVDconst [c]))
13331         // cond: c%9 == 0 && isPowerOfTwo64(c/9)
13332         // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
13333         for {
13334                 a := v_0
13335                 x := v_1
13336                 if v_2.Op != OpARM64MOVDconst {
13337                         break
13338                 }
13339                 c := auxIntToInt64(v_2.AuxInt)
13340                 if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
13341                         break
13342                 }
13343                 v.reset(OpARM64SUBshiftLL)
13344                 v.AuxInt = int64ToAuxInt(log64(c / 9))
13345                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13346                 v0.AuxInt = int64ToAuxInt(3)
13347                 v0.AddArg2(x, x)
13348                 v.AddArg2(a, v0)
13349                 return true
13350         }
13351         // match: (MSUB a (MOVDconst [-1]) x)
13352         // result: (ADD a x)
13353         for {
13354                 a := v_0
13355                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
13356                         break
13357                 }
13358                 x := v_2
13359                 v.reset(OpARM64ADD)
13360                 v.AddArg2(a, x)
13361                 return true
13362         }
13363         // match: (MSUB a (MOVDconst [0]) _)
13364         // result: a
13365         for {
13366                 a := v_0
13367                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
13368                         break
13369                 }
13370                 v.copyOf(a)
13371                 return true
13372         }
13373         // match: (MSUB a (MOVDconst [1]) x)
13374         // result: (SUB a x)
13375         for {
13376                 a := v_0
13377                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
13378                         break
13379                 }
13380                 x := v_2
13381                 v.reset(OpARM64SUB)
13382                 v.AddArg2(a, x)
13383                 return true
13384         }
13385         // match: (MSUB a (MOVDconst [c]) x)
13386         // cond: isPowerOfTwo64(c)
13387         // result: (SUBshiftLL a x [log64(c)])
13388         for {
13389                 a := v_0
13390                 if v_1.Op != OpARM64MOVDconst {
13391                         break
13392                 }
13393                 c := auxIntToInt64(v_1.AuxInt)
13394                 x := v_2
13395                 if !(isPowerOfTwo64(c)) {
13396                         break
13397                 }
13398                 v.reset(OpARM64SUBshiftLL)
13399                 v.AuxInt = int64ToAuxInt(log64(c))
13400                 v.AddArg2(a, x)
13401                 return true
13402         }
13403         // match: (MSUB a (MOVDconst [c]) x)
13404         // cond: isPowerOfTwo64(c-1) && c>=3
13405         // result: (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
13406         for {
13407                 a := v_0
13408                 if v_1.Op != OpARM64MOVDconst {
13409                         break
13410                 }
13411                 c := auxIntToInt64(v_1.AuxInt)
13412                 x := v_2
13413                 if !(isPowerOfTwo64(c-1) && c >= 3) {
13414                         break
13415                 }
13416                 v.reset(OpARM64SUB)
13417                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13418                 v0.AuxInt = int64ToAuxInt(log64(c - 1))
13419                 v0.AddArg2(x, x)
13420                 v.AddArg2(a, v0)
13421                 return true
13422         }
13423         // match: (MSUB a (MOVDconst [c]) x)
13424         // cond: isPowerOfTwo64(c+1) && c>=7
13425         // result: (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
13426         for {
13427                 a := v_0
13428                 if v_1.Op != OpARM64MOVDconst {
13429                         break
13430                 }
13431                 c := auxIntToInt64(v_1.AuxInt)
13432                 x := v_2
13433                 if !(isPowerOfTwo64(c+1) && c >= 7) {
13434                         break
13435                 }
13436                 v.reset(OpARM64ADD)
13437                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13438                 v0.AuxInt = int64ToAuxInt(log64(c + 1))
13439                 v0.AddArg2(x, x)
13440                 v.AddArg2(a, v0)
13441                 return true
13442         }
13443         // match: (MSUB a (MOVDconst [c]) x)
13444         // cond: c%3 == 0 && isPowerOfTwo64(c/3)
13445         // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
13446         for {
13447                 a := v_0
13448                 if v_1.Op != OpARM64MOVDconst {
13449                         break
13450                 }
13451                 c := auxIntToInt64(v_1.AuxInt)
13452                 x := v_2
13453                 if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
13454                         break
13455                 }
13456                 v.reset(OpARM64ADDshiftLL)
13457                 v.AuxInt = int64ToAuxInt(log64(c / 3))
13458                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13459                 v0.AuxInt = int64ToAuxInt(2)
13460                 v0.AddArg2(x, x)
13461                 v.AddArg2(a, v0)
13462                 return true
13463         }
13464         // match: (MSUB a (MOVDconst [c]) x)
13465         // cond: c%5 == 0 && isPowerOfTwo64(c/5)
13466         // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
13467         for {
13468                 a := v_0
13469                 if v_1.Op != OpARM64MOVDconst {
13470                         break
13471                 }
13472                 c := auxIntToInt64(v_1.AuxInt)
13473                 x := v_2
13474                 if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
13475                         break
13476                 }
13477                 v.reset(OpARM64SUBshiftLL)
13478                 v.AuxInt = int64ToAuxInt(log64(c / 5))
13479                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13480                 v0.AuxInt = int64ToAuxInt(2)
13481                 v0.AddArg2(x, x)
13482                 v.AddArg2(a, v0)
13483                 return true
13484         }
13485         // match: (MSUB a (MOVDconst [c]) x)
13486         // cond: c%7 == 0 && isPowerOfTwo64(c/7)
13487         // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
13488         for {
13489                 a := v_0
13490                 if v_1.Op != OpARM64MOVDconst {
13491                         break
13492                 }
13493                 c := auxIntToInt64(v_1.AuxInt)
13494                 x := v_2
13495                 if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
13496                         break
13497                 }
13498                 v.reset(OpARM64ADDshiftLL)
13499                 v.AuxInt = int64ToAuxInt(log64(c / 7))
13500                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13501                 v0.AuxInt = int64ToAuxInt(3)
13502                 v0.AddArg2(x, x)
13503                 v.AddArg2(a, v0)
13504                 return true
13505         }
13506         // match: (MSUB a (MOVDconst [c]) x)
13507         // cond: c%9 == 0 && isPowerOfTwo64(c/9)
13508         // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
13509         for {
13510                 a := v_0
13511                 if v_1.Op != OpARM64MOVDconst {
13512                         break
13513                 }
13514                 c := auxIntToInt64(v_1.AuxInt)
13515                 x := v_2
13516                 if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
13517                         break
13518                 }
13519                 v.reset(OpARM64SUBshiftLL)
13520                 v.AuxInt = int64ToAuxInt(log64(c / 9))
13521                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13522                 v0.AuxInt = int64ToAuxInt(3)
13523                 v0.AddArg2(x, x)
13524                 v.AddArg2(a, v0)
13525                 return true
13526         }
13527         // match: (MSUB (MOVDconst [c]) x y)
13528         // result: (ADDconst [c] (MNEG <x.Type> x y))
13529         for {
13530                 if v_0.Op != OpARM64MOVDconst {
13531                         break
13532                 }
13533                 c := auxIntToInt64(v_0.AuxInt)
13534                 x := v_1
13535                 y := v_2
13536                 v.reset(OpARM64ADDconst)
13537                 v.AuxInt = int64ToAuxInt(c)
13538                 v0 := b.NewValue0(v.Pos, OpARM64MNEG, x.Type)
13539                 v0.AddArg2(x, y)
13540                 v.AddArg(v0)
13541                 return true
13542         }
13543         // match: (MSUB a (MOVDconst [c]) (MOVDconst [d]))
13544         // result: (SUBconst [c*d] a)
13545         for {
13546                 a := v_0
13547                 if v_1.Op != OpARM64MOVDconst {
13548                         break
13549                 }
13550                 c := auxIntToInt64(v_1.AuxInt)
13551                 if v_2.Op != OpARM64MOVDconst {
13552                         break
13553                 }
13554                 d := auxIntToInt64(v_2.AuxInt)
13555                 v.reset(OpARM64SUBconst)
13556                 v.AuxInt = int64ToAuxInt(c * d)
13557                 v.AddArg(a)
13558                 return true
13559         }
13560         return false
13561 }
13562 func rewriteValueARM64_OpARM64MSUBW(v *Value) bool {
13563         v_2 := v.Args[2]
13564         v_1 := v.Args[1]
13565         v_0 := v.Args[0]
13566         b := v.Block
13567         // match: (MSUBW a x (MOVDconst [c]))
13568         // cond: int32(c)==-1
13569         // result: (MOVWUreg (ADD <a.Type> a x))
13570         for {
13571                 a := v_0
13572                 x := v_1
13573                 if v_2.Op != OpARM64MOVDconst {
13574                         break
13575                 }
13576                 c := auxIntToInt64(v_2.AuxInt)
13577                 if !(int32(c) == -1) {
13578                         break
13579                 }
13580                 v.reset(OpARM64MOVWUreg)
13581                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
13582                 v0.AddArg2(a, x)
13583                 v.AddArg(v0)
13584                 return true
13585         }
13586         // match: (MSUBW a _ (MOVDconst [c]))
13587         // cond: int32(c)==0
13588         // result: (MOVWUreg a)
13589         for {
13590                 a := v_0
13591                 if v_2.Op != OpARM64MOVDconst {
13592                         break
13593                 }
13594                 c := auxIntToInt64(v_2.AuxInt)
13595                 if !(int32(c) == 0) {
13596                         break
13597                 }
13598                 v.reset(OpARM64MOVWUreg)
13599                 v.AddArg(a)
13600                 return true
13601         }
13602         // match: (MSUBW a x (MOVDconst [c]))
13603         // cond: int32(c)==1
13604         // result: (MOVWUreg (SUB <a.Type> a x))
13605         for {
13606                 a := v_0
13607                 x := v_1
13608                 if v_2.Op != OpARM64MOVDconst {
13609                         break
13610                 }
13611                 c := auxIntToInt64(v_2.AuxInt)
13612                 if !(int32(c) == 1) {
13613                         break
13614                 }
13615                 v.reset(OpARM64MOVWUreg)
13616                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
13617                 v0.AddArg2(a, x)
13618                 v.AddArg(v0)
13619                 return true
13620         }
13621         // match: (MSUBW a x (MOVDconst [c]))
13622         // cond: isPowerOfTwo64(c)
13623         // result: (MOVWUreg (SUBshiftLL <a.Type> a x [log64(c)]))
13624         for {
13625                 a := v_0
13626                 x := v_1
13627                 if v_2.Op != OpARM64MOVDconst {
13628                         break
13629                 }
13630                 c := auxIntToInt64(v_2.AuxInt)
13631                 if !(isPowerOfTwo64(c)) {
13632                         break
13633                 }
13634                 v.reset(OpARM64MOVWUreg)
13635                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
13636                 v0.AuxInt = int64ToAuxInt(log64(c))
13637                 v0.AddArg2(a, x)
13638                 v.AddArg(v0)
13639                 return true
13640         }
13641         // match: (MSUBW a x (MOVDconst [c]))
13642         // cond: isPowerOfTwo64(c-1) && int32(c)>=3
13643         // result: (MOVWUreg (SUB <a.Type> a (ADDshiftLL <x.Type> x x [log64(c-1)])))
13644         for {
13645                 a := v_0
13646                 x := v_1
13647                 if v_2.Op != OpARM64MOVDconst {
13648                         break
13649                 }
13650                 c := auxIntToInt64(v_2.AuxInt)
13651                 if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
13652                         break
13653                 }
13654                 v.reset(OpARM64MOVWUreg)
13655                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
13656                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13657                 v1.AuxInt = int64ToAuxInt(log64(c - 1))
13658                 v1.AddArg2(x, x)
13659                 v0.AddArg2(a, v1)
13660                 v.AddArg(v0)
13661                 return true
13662         }
13663         // match: (MSUBW a x (MOVDconst [c]))
13664         // cond: isPowerOfTwo64(c+1) && int32(c)>=7
13665         // result: (MOVWUreg (ADD <a.Type> a (SUBshiftLL <x.Type> x x [log64(c+1)])))
13666         for {
13667                 a := v_0
13668                 x := v_1
13669                 if v_2.Op != OpARM64MOVDconst {
13670                         break
13671                 }
13672                 c := auxIntToInt64(v_2.AuxInt)
13673                 if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
13674                         break
13675                 }
13676                 v.reset(OpARM64MOVWUreg)
13677                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
13678                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13679                 v1.AuxInt = int64ToAuxInt(log64(c + 1))
13680                 v1.AddArg2(x, x)
13681                 v0.AddArg2(a, v1)
13682                 v.AddArg(v0)
13683                 return true
13684         }
13685         // match: (MSUBW a x (MOVDconst [c]))
13686         // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
13687         // result: (MOVWUreg (ADDshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]))
13688         for {
13689                 a := v_0
13690                 x := v_1
13691                 if v_2.Op != OpARM64MOVDconst {
13692                         break
13693                 }
13694                 c := auxIntToInt64(v_2.AuxInt)
13695                 if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
13696                         break
13697                 }
13698                 v.reset(OpARM64MOVWUreg)
13699                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
13700                 v0.AuxInt = int64ToAuxInt(log64(c / 3))
13701                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13702                 v1.AuxInt = int64ToAuxInt(2)
13703                 v1.AddArg2(x, x)
13704                 v0.AddArg2(a, v1)
13705                 v.AddArg(v0)
13706                 return true
13707         }
13708         // match: (MSUBW a x (MOVDconst [c]))
13709         // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
13710         // result: (MOVWUreg (SUBshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]))
13711         for {
13712                 a := v_0
13713                 x := v_1
13714                 if v_2.Op != OpARM64MOVDconst {
13715                         break
13716                 }
13717                 c := auxIntToInt64(v_2.AuxInt)
13718                 if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
13719                         break
13720                 }
13721                 v.reset(OpARM64MOVWUreg)
13722                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
13723                 v0.AuxInt = int64ToAuxInt(log64(c / 5))
13724                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13725                 v1.AuxInt = int64ToAuxInt(2)
13726                 v1.AddArg2(x, x)
13727                 v0.AddArg2(a, v1)
13728                 v.AddArg(v0)
13729                 return true
13730         }
13731         // match: (MSUBW a x (MOVDconst [c]))
13732         // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
13733         // result: (MOVWUreg (ADDshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]))
13734         for {
13735                 a := v_0
13736                 x := v_1
13737                 if v_2.Op != OpARM64MOVDconst {
13738                         break
13739                 }
13740                 c := auxIntToInt64(v_2.AuxInt)
13741                 if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
13742                         break
13743                 }
13744                 v.reset(OpARM64MOVWUreg)
13745                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
13746                 v0.AuxInt = int64ToAuxInt(log64(c / 7))
13747                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13748                 v1.AuxInt = int64ToAuxInt(3)
13749                 v1.AddArg2(x, x)
13750                 v0.AddArg2(a, v1)
13751                 v.AddArg(v0)
13752                 return true
13753         }
13754         // match: (MSUBW a x (MOVDconst [c]))
13755         // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
13756         // result: (MOVWUreg (SUBshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]))
13757         for {
13758                 a := v_0
13759                 x := v_1
13760                 if v_2.Op != OpARM64MOVDconst {
13761                         break
13762                 }
13763                 c := auxIntToInt64(v_2.AuxInt)
13764                 if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
13765                         break
13766                 }
13767                 v.reset(OpARM64MOVWUreg)
13768                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
13769                 v0.AuxInt = int64ToAuxInt(log64(c / 9))
13770                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13771                 v1.AuxInt = int64ToAuxInt(3)
13772                 v1.AddArg2(x, x)
13773                 v0.AddArg2(a, v1)
13774                 v.AddArg(v0)
13775                 return true
13776         }
13777         // match: (MSUBW a (MOVDconst [c]) x)
13778         // cond: int32(c)==-1
13779         // result: (MOVWUreg (ADD <a.Type> a x))
13780         for {
13781                 a := v_0
13782                 if v_1.Op != OpARM64MOVDconst {
13783                         break
13784                 }
13785                 c := auxIntToInt64(v_1.AuxInt)
13786                 x := v_2
13787                 if !(int32(c) == -1) {
13788                         break
13789                 }
13790                 v.reset(OpARM64MOVWUreg)
13791                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
13792                 v0.AddArg2(a, x)
13793                 v.AddArg(v0)
13794                 return true
13795         }
13796         // match: (MSUBW a (MOVDconst [c]) _)
13797         // cond: int32(c)==0
13798         // result: (MOVWUreg a)
13799         for {
13800                 a := v_0
13801                 if v_1.Op != OpARM64MOVDconst {
13802                         break
13803                 }
13804                 c := auxIntToInt64(v_1.AuxInt)
13805                 if !(int32(c) == 0) {
13806                         break
13807                 }
13808                 v.reset(OpARM64MOVWUreg)
13809                 v.AddArg(a)
13810                 return true
13811         }
13812         // match: (MSUBW a (MOVDconst [c]) x)
13813         // cond: int32(c)==1
13814         // result: (MOVWUreg (SUB <a.Type> a x))
13815         for {
13816                 a := v_0
13817                 if v_1.Op != OpARM64MOVDconst {
13818                         break
13819                 }
13820                 c := auxIntToInt64(v_1.AuxInt)
13821                 x := v_2
13822                 if !(int32(c) == 1) {
13823                         break
13824                 }
13825                 v.reset(OpARM64MOVWUreg)
13826                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
13827                 v0.AddArg2(a, x)
13828                 v.AddArg(v0)
13829                 return true
13830         }
13831         // match: (MSUBW a (MOVDconst [c]) x)
13832         // cond: isPowerOfTwo64(c)
13833         // result: (MOVWUreg (SUBshiftLL <a.Type> a x [log64(c)]))
13834         for {
13835                 a := v_0
13836                 if v_1.Op != OpARM64MOVDconst {
13837                         break
13838                 }
13839                 c := auxIntToInt64(v_1.AuxInt)
13840                 x := v_2
13841                 if !(isPowerOfTwo64(c)) {
13842                         break
13843                 }
13844                 v.reset(OpARM64MOVWUreg)
13845                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
13846                 v0.AuxInt = int64ToAuxInt(log64(c))
13847                 v0.AddArg2(a, x)
13848                 v.AddArg(v0)
13849                 return true
13850         }
13851         // match: (MSUBW a (MOVDconst [c]) x)
13852         // cond: isPowerOfTwo64(c-1) && int32(c)>=3
13853         // result: (MOVWUreg (SUB <a.Type> a (ADDshiftLL <x.Type> x x [log64(c-1)])))
13854         for {
13855                 a := v_0
13856                 if v_1.Op != OpARM64MOVDconst {
13857                         break
13858                 }
13859                 c := auxIntToInt64(v_1.AuxInt)
13860                 x := v_2
13861                 if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
13862                         break
13863                 }
13864                 v.reset(OpARM64MOVWUreg)
13865                 v0 := b.NewValue0(v.Pos, OpARM64SUB, a.Type)
13866                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13867                 v1.AuxInt = int64ToAuxInt(log64(c - 1))
13868                 v1.AddArg2(x, x)
13869                 v0.AddArg2(a, v1)
13870                 v.AddArg(v0)
13871                 return true
13872         }
13873         // match: (MSUBW a (MOVDconst [c]) x)
13874         // cond: isPowerOfTwo64(c+1) && int32(c)>=7
13875         // result: (MOVWUreg (ADD <a.Type> a (SUBshiftLL <x.Type> x x [log64(c+1)])))
13876         for {
13877                 a := v_0
13878                 if v_1.Op != OpARM64MOVDconst {
13879                         break
13880                 }
13881                 c := auxIntToInt64(v_1.AuxInt)
13882                 x := v_2
13883                 if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
13884                         break
13885                 }
13886                 v.reset(OpARM64MOVWUreg)
13887                 v0 := b.NewValue0(v.Pos, OpARM64ADD, a.Type)
13888                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13889                 v1.AuxInt = int64ToAuxInt(log64(c + 1))
13890                 v1.AddArg2(x, x)
13891                 v0.AddArg2(a, v1)
13892                 v.AddArg(v0)
13893                 return true
13894         }
13895         // match: (MSUBW a (MOVDconst [c]) x)
13896         // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
13897         // result: (MOVWUreg (ADDshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]))
13898         for {
13899                 a := v_0
13900                 if v_1.Op != OpARM64MOVDconst {
13901                         break
13902                 }
13903                 c := auxIntToInt64(v_1.AuxInt)
13904                 x := v_2
13905                 if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
13906                         break
13907                 }
13908                 v.reset(OpARM64MOVWUreg)
13909                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
13910                 v0.AuxInt = int64ToAuxInt(log64(c / 3))
13911                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13912                 v1.AuxInt = int64ToAuxInt(2)
13913                 v1.AddArg2(x, x)
13914                 v0.AddArg2(a, v1)
13915                 v.AddArg(v0)
13916                 return true
13917         }
13918         // match: (MSUBW a (MOVDconst [c]) x)
13919         // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
13920         // result: (MOVWUreg (SUBshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]))
13921         for {
13922                 a := v_0
13923                 if v_1.Op != OpARM64MOVDconst {
13924                         break
13925                 }
13926                 c := auxIntToInt64(v_1.AuxInt)
13927                 x := v_2
13928                 if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
13929                         break
13930                 }
13931                 v.reset(OpARM64MOVWUreg)
13932                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
13933                 v0.AuxInt = int64ToAuxInt(log64(c / 5))
13934                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13935                 v1.AuxInt = int64ToAuxInt(2)
13936                 v1.AddArg2(x, x)
13937                 v0.AddArg2(a, v1)
13938                 v.AddArg(v0)
13939                 return true
13940         }
13941         // match: (MSUBW a (MOVDconst [c]) x)
13942         // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
13943         // result: (MOVWUreg (ADDshiftLL <a.Type> a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]))
13944         for {
13945                 a := v_0
13946                 if v_1.Op != OpARM64MOVDconst {
13947                         break
13948                 }
13949                 c := auxIntToInt64(v_1.AuxInt)
13950                 x := v_2
13951                 if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
13952                         break
13953                 }
13954                 v.reset(OpARM64MOVWUreg)
13955                 v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, a.Type)
13956                 v0.AuxInt = int64ToAuxInt(log64(c / 7))
13957                 v1 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
13958                 v1.AuxInt = int64ToAuxInt(3)
13959                 v1.AddArg2(x, x)
13960                 v0.AddArg2(a, v1)
13961                 v.AddArg(v0)
13962                 return true
13963         }
13964         // match: (MSUBW a (MOVDconst [c]) x)
13965         // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
13966         // result: (MOVWUreg (SUBshiftLL <a.Type> a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]))
13967         for {
13968                 a := v_0
13969                 if v_1.Op != OpARM64MOVDconst {
13970                         break
13971                 }
13972                 c := auxIntToInt64(v_1.AuxInt)
13973                 x := v_2
13974                 if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
13975                         break
13976                 }
13977                 v.reset(OpARM64MOVWUreg)
13978                 v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, a.Type)
13979                 v0.AuxInt = int64ToAuxInt(log64(c / 9))
13980                 v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
13981                 v1.AuxInt = int64ToAuxInt(3)
13982                 v1.AddArg2(x, x)
13983                 v0.AddArg2(a, v1)
13984                 v.AddArg(v0)
13985                 return true
13986         }
13987         // match: (MSUBW (MOVDconst [c]) x y)
13988         // result: (MOVWUreg (ADDconst <x.Type> [c] (MNEGW <x.Type> x y)))
13989         for {
13990                 if v_0.Op != OpARM64MOVDconst {
13991                         break
13992                 }
13993                 c := auxIntToInt64(v_0.AuxInt)
13994                 x := v_1
13995                 y := v_2
13996                 v.reset(OpARM64MOVWUreg)
13997                 v0 := b.NewValue0(v.Pos, OpARM64ADDconst, x.Type)
13998                 v0.AuxInt = int64ToAuxInt(c)
13999                 v1 := b.NewValue0(v.Pos, OpARM64MNEGW, x.Type)
14000                 v1.AddArg2(x, y)
14001                 v0.AddArg(v1)
14002                 v.AddArg(v0)
14003                 return true
14004         }
14005         // match: (MSUBW a (MOVDconst [c]) (MOVDconst [d]))
14006         // result: (MOVWUreg (SUBconst <a.Type> [c*d] a))
14007         for {
14008                 a := v_0
14009                 if v_1.Op != OpARM64MOVDconst {
14010                         break
14011                 }
14012                 c := auxIntToInt64(v_1.AuxInt)
14013                 if v_2.Op != OpARM64MOVDconst {
14014                         break
14015                 }
14016                 d := auxIntToInt64(v_2.AuxInt)
14017                 v.reset(OpARM64MOVWUreg)
14018                 v0 := b.NewValue0(v.Pos, OpARM64SUBconst, a.Type)
14019                 v0.AuxInt = int64ToAuxInt(c * d)
14020                 v0.AddArg(a)
14021                 v.AddArg(v0)
14022                 return true
14023         }
14024         return false
14025 }
14026 func rewriteValueARM64_OpARM64MUL(v *Value) bool {
14027         v_1 := v.Args[1]
14028         v_0 := v.Args[0]
14029         b := v.Block
14030         // match: (MUL (NEG x) y)
14031         // result: (MNEG x y)
14032         for {
14033                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14034                         if v_0.Op != OpARM64NEG {
14035                                 continue
14036                         }
14037                         x := v_0.Args[0]
14038                         y := v_1
14039                         v.reset(OpARM64MNEG)
14040                         v.AddArg2(x, y)
14041                         return true
14042                 }
14043                 break
14044         }
14045         // match: (MUL x (MOVDconst [-1]))
14046         // result: (NEG x)
14047         for {
14048                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14049                         x := v_0
14050                         if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
14051                                 continue
14052                         }
14053                         v.reset(OpARM64NEG)
14054                         v.AddArg(x)
14055                         return true
14056                 }
14057                 break
14058         }
14059         // match: (MUL _ (MOVDconst [0]))
14060         // result: (MOVDconst [0])
14061         for {
14062                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14063                         if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
14064                                 continue
14065                         }
14066                         v.reset(OpARM64MOVDconst)
14067                         v.AuxInt = int64ToAuxInt(0)
14068                         return true
14069                 }
14070                 break
14071         }
14072         // match: (MUL x (MOVDconst [1]))
14073         // result: x
14074         for {
14075                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14076                         x := v_0
14077                         if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
14078                                 continue
14079                         }
14080                         v.copyOf(x)
14081                         return true
14082                 }
14083                 break
14084         }
14085         // match: (MUL x (MOVDconst [c]))
14086         // cond: isPowerOfTwo64(c)
14087         // result: (SLLconst [log64(c)] x)
14088         for {
14089                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14090                         x := v_0
14091                         if v_1.Op != OpARM64MOVDconst {
14092                                 continue
14093                         }
14094                         c := auxIntToInt64(v_1.AuxInt)
14095                         if !(isPowerOfTwo64(c)) {
14096                                 continue
14097                         }
14098                         v.reset(OpARM64SLLconst)
14099                         v.AuxInt = int64ToAuxInt(log64(c))
14100                         v.AddArg(x)
14101                         return true
14102                 }
14103                 break
14104         }
14105         // match: (MUL x (MOVDconst [c]))
14106         // cond: isPowerOfTwo64(c-1) && c >= 3
14107         // result: (ADDshiftLL x x [log64(c-1)])
14108         for {
14109                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14110                         x := v_0
14111                         if v_1.Op != OpARM64MOVDconst {
14112                                 continue
14113                         }
14114                         c := auxIntToInt64(v_1.AuxInt)
14115                         if !(isPowerOfTwo64(c-1) && c >= 3) {
14116                                 continue
14117                         }
14118                         v.reset(OpARM64ADDshiftLL)
14119                         v.AuxInt = int64ToAuxInt(log64(c - 1))
14120                         v.AddArg2(x, x)
14121                         return true
14122                 }
14123                 break
14124         }
14125         // match: (MUL x (MOVDconst [c]))
14126         // cond: isPowerOfTwo64(c+1) && c >= 7
14127         // result: (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)])
14128         for {
14129                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14130                         x := v_0
14131                         if v_1.Op != OpARM64MOVDconst {
14132                                 continue
14133                         }
14134                         c := auxIntToInt64(v_1.AuxInt)
14135                         if !(isPowerOfTwo64(c+1) && c >= 7) {
14136                                 continue
14137                         }
14138                         v.reset(OpARM64ADDshiftLL)
14139                         v.AuxInt = int64ToAuxInt(log64(c + 1))
14140                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
14141                         v0.AddArg(x)
14142                         v.AddArg2(v0, x)
14143                         return true
14144                 }
14145                 break
14146         }
14147         // match: (MUL x (MOVDconst [c]))
14148         // cond: c%3 == 0 && isPowerOfTwo64(c/3)
14149         // result: (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1]))
14150         for {
14151                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14152                         x := v_0
14153                         if v_1.Op != OpARM64MOVDconst {
14154                                 continue
14155                         }
14156                         c := auxIntToInt64(v_1.AuxInt)
14157                         if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
14158                                 continue
14159                         }
14160                         v.reset(OpARM64SLLconst)
14161                         v.AuxInt = int64ToAuxInt(log64(c / 3))
14162                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14163                         v0.AuxInt = int64ToAuxInt(1)
14164                         v0.AddArg2(x, x)
14165                         v.AddArg(v0)
14166                         return true
14167                 }
14168                 break
14169         }
14170         // match: (MUL x (MOVDconst [c]))
14171         // cond: c%5 == 0 && isPowerOfTwo64(c/5)
14172         // result: (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))
14173         for {
14174                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14175                         x := v_0
14176                         if v_1.Op != OpARM64MOVDconst {
14177                                 continue
14178                         }
14179                         c := auxIntToInt64(v_1.AuxInt)
14180                         if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
14181                                 continue
14182                         }
14183                         v.reset(OpARM64SLLconst)
14184                         v.AuxInt = int64ToAuxInt(log64(c / 5))
14185                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14186                         v0.AuxInt = int64ToAuxInt(2)
14187                         v0.AddArg2(x, x)
14188                         v.AddArg(v0)
14189                         return true
14190                 }
14191                 break
14192         }
14193         // match: (MUL x (MOVDconst [c]))
14194         // cond: c%7 == 0 && isPowerOfTwo64(c/7)
14195         // result: (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))
14196         for {
14197                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14198                         x := v_0
14199                         if v_1.Op != OpARM64MOVDconst {
14200                                 continue
14201                         }
14202                         c := auxIntToInt64(v_1.AuxInt)
14203                         if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
14204                                 continue
14205                         }
14206                         v.reset(OpARM64SLLconst)
14207                         v.AuxInt = int64ToAuxInt(log64(c / 7))
14208                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14209                         v0.AuxInt = int64ToAuxInt(3)
14210                         v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
14211                         v1.AddArg(x)
14212                         v0.AddArg2(v1, x)
14213                         v.AddArg(v0)
14214                         return true
14215                 }
14216                 break
14217         }
14218         // match: (MUL x (MOVDconst [c]))
14219         // cond: c%9 == 0 && isPowerOfTwo64(c/9)
14220         // result: (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))
14221         for {
14222                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14223                         x := v_0
14224                         if v_1.Op != OpARM64MOVDconst {
14225                                 continue
14226                         }
14227                         c := auxIntToInt64(v_1.AuxInt)
14228                         if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
14229                                 continue
14230                         }
14231                         v.reset(OpARM64SLLconst)
14232                         v.AuxInt = int64ToAuxInt(log64(c / 9))
14233                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14234                         v0.AuxInt = int64ToAuxInt(3)
14235                         v0.AddArg2(x, x)
14236                         v.AddArg(v0)
14237                         return true
14238                 }
14239                 break
14240         }
14241         // match: (MUL (MOVDconst [c]) (MOVDconst [d]))
14242         // result: (MOVDconst [c*d])
14243         for {
14244                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14245                         if v_0.Op != OpARM64MOVDconst {
14246                                 continue
14247                         }
14248                         c := auxIntToInt64(v_0.AuxInt)
14249                         if v_1.Op != OpARM64MOVDconst {
14250                                 continue
14251                         }
14252                         d := auxIntToInt64(v_1.AuxInt)
14253                         v.reset(OpARM64MOVDconst)
14254                         v.AuxInt = int64ToAuxInt(c * d)
14255                         return true
14256                 }
14257                 break
14258         }
14259         return false
14260 }
14261 func rewriteValueARM64_OpARM64MULW(v *Value) bool {
14262         v_1 := v.Args[1]
14263         v_0 := v.Args[0]
14264         b := v.Block
14265         // match: (MULW (NEG x) y)
14266         // result: (MNEGW x y)
14267         for {
14268                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14269                         if v_0.Op != OpARM64NEG {
14270                                 continue
14271                         }
14272                         x := v_0.Args[0]
14273                         y := v_1
14274                         v.reset(OpARM64MNEGW)
14275                         v.AddArg2(x, y)
14276                         return true
14277                 }
14278                 break
14279         }
14280         // match: (MULW x (MOVDconst [c]))
14281         // cond: int32(c)==-1
14282         // result: (MOVWUreg (NEG <x.Type> x))
14283         for {
14284                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14285                         x := v_0
14286                         if v_1.Op != OpARM64MOVDconst {
14287                                 continue
14288                         }
14289                         c := auxIntToInt64(v_1.AuxInt)
14290                         if !(int32(c) == -1) {
14291                                 continue
14292                         }
14293                         v.reset(OpARM64MOVWUreg)
14294                         v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
14295                         v0.AddArg(x)
14296                         v.AddArg(v0)
14297                         return true
14298                 }
14299                 break
14300         }
14301         // match: (MULW _ (MOVDconst [c]))
14302         // cond: int32(c)==0
14303         // result: (MOVDconst [0])
14304         for {
14305                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14306                         if v_1.Op != OpARM64MOVDconst {
14307                                 continue
14308                         }
14309                         c := auxIntToInt64(v_1.AuxInt)
14310                         if !(int32(c) == 0) {
14311                                 continue
14312                         }
14313                         v.reset(OpARM64MOVDconst)
14314                         v.AuxInt = int64ToAuxInt(0)
14315                         return true
14316                 }
14317                 break
14318         }
14319         // match: (MULW x (MOVDconst [c]))
14320         // cond: int32(c)==1
14321         // result: (MOVWUreg x)
14322         for {
14323                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14324                         x := v_0
14325                         if v_1.Op != OpARM64MOVDconst {
14326                                 continue
14327                         }
14328                         c := auxIntToInt64(v_1.AuxInt)
14329                         if !(int32(c) == 1) {
14330                                 continue
14331                         }
14332                         v.reset(OpARM64MOVWUreg)
14333                         v.AddArg(x)
14334                         return true
14335                 }
14336                 break
14337         }
14338         // match: (MULW x (MOVDconst [c]))
14339         // cond: isPowerOfTwo64(c)
14340         // result: (MOVWUreg (SLLconst <x.Type> [log64(c)] x))
14341         for {
14342                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14343                         x := v_0
14344                         if v_1.Op != OpARM64MOVDconst {
14345                                 continue
14346                         }
14347                         c := auxIntToInt64(v_1.AuxInt)
14348                         if !(isPowerOfTwo64(c)) {
14349                                 continue
14350                         }
14351                         v.reset(OpARM64MOVWUreg)
14352                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
14353                         v0.AuxInt = int64ToAuxInt(log64(c))
14354                         v0.AddArg(x)
14355                         v.AddArg(v0)
14356                         return true
14357                 }
14358                 break
14359         }
14360         // match: (MULW x (MOVDconst [c]))
14361         // cond: isPowerOfTwo64(c-1) && int32(c) >= 3
14362         // result: (MOVWUreg (ADDshiftLL <x.Type> x x [log64(c-1)]))
14363         for {
14364                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14365                         x := v_0
14366                         if v_1.Op != OpARM64MOVDconst {
14367                                 continue
14368                         }
14369                         c := auxIntToInt64(v_1.AuxInt)
14370                         if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
14371                                 continue
14372                         }
14373                         v.reset(OpARM64MOVWUreg)
14374                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14375                         v0.AuxInt = int64ToAuxInt(log64(c - 1))
14376                         v0.AddArg2(x, x)
14377                         v.AddArg(v0)
14378                         return true
14379                 }
14380                 break
14381         }
14382         // match: (MULW x (MOVDconst [c]))
14383         // cond: isPowerOfTwo64(c+1) && int32(c) >= 7
14384         // result: (MOVWUreg (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)]))
14385         for {
14386                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14387                         x := v_0
14388                         if v_1.Op != OpARM64MOVDconst {
14389                                 continue
14390                         }
14391                         c := auxIntToInt64(v_1.AuxInt)
14392                         if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
14393                                 continue
14394                         }
14395                         v.reset(OpARM64MOVWUreg)
14396                         v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14397                         v0.AuxInt = int64ToAuxInt(log64(c + 1))
14398                         v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
14399                         v1.AddArg(x)
14400                         v0.AddArg2(v1, x)
14401                         v.AddArg(v0)
14402                         return true
14403                 }
14404                 break
14405         }
14406         // match: (MULW x (MOVDconst [c]))
14407         // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
14408         // result: (MOVWUreg (SLLconst <x.Type> [log64(c/3)] (ADDshiftLL <x.Type> x x [1])))
14409         for {
14410                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14411                         x := v_0
14412                         if v_1.Op != OpARM64MOVDconst {
14413                                 continue
14414                         }
14415                         c := auxIntToInt64(v_1.AuxInt)
14416                         if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
14417                                 continue
14418                         }
14419                         v.reset(OpARM64MOVWUreg)
14420                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
14421                         v0.AuxInt = int64ToAuxInt(log64(c / 3))
14422                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14423                         v1.AuxInt = int64ToAuxInt(1)
14424                         v1.AddArg2(x, x)
14425                         v0.AddArg(v1)
14426                         v.AddArg(v0)
14427                         return true
14428                 }
14429                 break
14430         }
14431         // match: (MULW x (MOVDconst [c]))
14432         // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
14433         // result: (MOVWUreg (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2])))
14434         for {
14435                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14436                         x := v_0
14437                         if v_1.Op != OpARM64MOVDconst {
14438                                 continue
14439                         }
14440                         c := auxIntToInt64(v_1.AuxInt)
14441                         if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
14442                                 continue
14443                         }
14444                         v.reset(OpARM64MOVWUreg)
14445                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
14446                         v0.AuxInt = int64ToAuxInt(log64(c / 5))
14447                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14448                         v1.AuxInt = int64ToAuxInt(2)
14449                         v1.AddArg2(x, x)
14450                         v0.AddArg(v1)
14451                         v.AddArg(v0)
14452                         return true
14453                 }
14454                 break
14455         }
14456         // match: (MULW x (MOVDconst [c]))
14457         // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
14458         // result: (MOVWUreg (SLLconst <x.Type> [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])))
14459         for {
14460                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14461                         x := v_0
14462                         if v_1.Op != OpARM64MOVDconst {
14463                                 continue
14464                         }
14465                         c := auxIntToInt64(v_1.AuxInt)
14466                         if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
14467                                 continue
14468                         }
14469                         v.reset(OpARM64MOVWUreg)
14470                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
14471                         v0.AuxInt = int64ToAuxInt(log64(c / 7))
14472                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14473                         v1.AuxInt = int64ToAuxInt(3)
14474                         v2 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
14475                         v2.AddArg(x)
14476                         v1.AddArg2(v2, x)
14477                         v0.AddArg(v1)
14478                         v.AddArg(v0)
14479                         return true
14480                 }
14481                 break
14482         }
14483         // match: (MULW x (MOVDconst [c]))
14484         // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
14485         // result: (MOVWUreg (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3])))
14486         for {
14487                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14488                         x := v_0
14489                         if v_1.Op != OpARM64MOVDconst {
14490                                 continue
14491                         }
14492                         c := auxIntToInt64(v_1.AuxInt)
14493                         if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
14494                                 continue
14495                         }
14496                         v.reset(OpARM64MOVWUreg)
14497                         v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
14498                         v0.AuxInt = int64ToAuxInt(log64(c / 9))
14499                         v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
14500                         v1.AuxInt = int64ToAuxInt(3)
14501                         v1.AddArg2(x, x)
14502                         v0.AddArg(v1)
14503                         v.AddArg(v0)
14504                         return true
14505                 }
14506                 break
14507         }
14508         // match: (MULW (MOVDconst [c]) (MOVDconst [d]))
14509         // result: (MOVDconst [int64(uint32(c*d))])
14510         for {
14511                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
14512                         if v_0.Op != OpARM64MOVDconst {
14513                                 continue
14514                         }
14515                         c := auxIntToInt64(v_0.AuxInt)
14516                         if v_1.Op != OpARM64MOVDconst {
14517                                 continue
14518                         }
14519                         d := auxIntToInt64(v_1.AuxInt)
14520                         v.reset(OpARM64MOVDconst)
14521                         v.AuxInt = int64ToAuxInt(int64(uint32(c * d)))
14522                         return true
14523                 }
14524                 break
14525         }
14526         return false
14527 }
14528 func rewriteValueARM64_OpARM64MVN(v *Value) bool {
14529         v_0 := v.Args[0]
14530         // match: (MVN (XOR x y))
14531         // result: (EON x y)
14532         for {
14533                 if v_0.Op != OpARM64XOR {
14534                         break
14535                 }
14536                 y := v_0.Args[1]
14537                 x := v_0.Args[0]
14538                 v.reset(OpARM64EON)
14539                 v.AddArg2(x, y)
14540                 return true
14541         }
14542         // match: (MVN (MOVDconst [c]))
14543         // result: (MOVDconst [^c])
14544         for {
14545                 if v_0.Op != OpARM64MOVDconst {
14546                         break
14547                 }
14548                 c := auxIntToInt64(v_0.AuxInt)
14549                 v.reset(OpARM64MOVDconst)
14550                 v.AuxInt = int64ToAuxInt(^c)
14551                 return true
14552         }
14553         // match: (MVN x:(SLLconst [c] y))
14554         // cond: clobberIfDead(x)
14555         // result: (MVNshiftLL [c] y)
14556         for {
14557                 x := v_0
14558                 if x.Op != OpARM64SLLconst {
14559                         break
14560                 }
14561                 c := auxIntToInt64(x.AuxInt)
14562                 y := x.Args[0]
14563                 if !(clobberIfDead(x)) {
14564                         break
14565                 }
14566                 v.reset(OpARM64MVNshiftLL)
14567                 v.AuxInt = int64ToAuxInt(c)
14568                 v.AddArg(y)
14569                 return true
14570         }
14571         // match: (MVN x:(SRLconst [c] y))
14572         // cond: clobberIfDead(x)
14573         // result: (MVNshiftRL [c] y)
14574         for {
14575                 x := v_0
14576                 if x.Op != OpARM64SRLconst {
14577                         break
14578                 }
14579                 c := auxIntToInt64(x.AuxInt)
14580                 y := x.Args[0]
14581                 if !(clobberIfDead(x)) {
14582                         break
14583                 }
14584                 v.reset(OpARM64MVNshiftRL)
14585                 v.AuxInt = int64ToAuxInt(c)
14586                 v.AddArg(y)
14587                 return true
14588         }
14589         // match: (MVN x:(SRAconst [c] y))
14590         // cond: clobberIfDead(x)
14591         // result: (MVNshiftRA [c] y)
14592         for {
14593                 x := v_0
14594                 if x.Op != OpARM64SRAconst {
14595                         break
14596                 }
14597                 c := auxIntToInt64(x.AuxInt)
14598                 y := x.Args[0]
14599                 if !(clobberIfDead(x)) {
14600                         break
14601                 }
14602                 v.reset(OpARM64MVNshiftRA)
14603                 v.AuxInt = int64ToAuxInt(c)
14604                 v.AddArg(y)
14605                 return true
14606         }
14607         // match: (MVN x:(RORconst [c] y))
14608         // cond: clobberIfDead(x)
14609         // result: (MVNshiftRO [c] y)
14610         for {
14611                 x := v_0
14612                 if x.Op != OpARM64RORconst {
14613                         break
14614                 }
14615                 c := auxIntToInt64(x.AuxInt)
14616                 y := x.Args[0]
14617                 if !(clobberIfDead(x)) {
14618                         break
14619                 }
14620                 v.reset(OpARM64MVNshiftRO)
14621                 v.AuxInt = int64ToAuxInt(c)
14622                 v.AddArg(y)
14623                 return true
14624         }
14625         return false
14626 }
14627 func rewriteValueARM64_OpARM64MVNshiftLL(v *Value) bool {
14628         v_0 := v.Args[0]
14629         // match: (MVNshiftLL (MOVDconst [c]) [d])
14630         // result: (MOVDconst [^int64(uint64(c)<<uint64(d))])
14631         for {
14632                 d := auxIntToInt64(v.AuxInt)
14633                 if v_0.Op != OpARM64MOVDconst {
14634                         break
14635                 }
14636                 c := auxIntToInt64(v_0.AuxInt)
14637                 v.reset(OpARM64MOVDconst)
14638                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) << uint64(d)))
14639                 return true
14640         }
14641         return false
14642 }
14643 func rewriteValueARM64_OpARM64MVNshiftRA(v *Value) bool {
14644         v_0 := v.Args[0]
14645         // match: (MVNshiftRA (MOVDconst [c]) [d])
14646         // result: (MOVDconst [^(c>>uint64(d))])
14647         for {
14648                 d := auxIntToInt64(v.AuxInt)
14649                 if v_0.Op != OpARM64MOVDconst {
14650                         break
14651                 }
14652                 c := auxIntToInt64(v_0.AuxInt)
14653                 v.reset(OpARM64MOVDconst)
14654                 v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
14655                 return true
14656         }
14657         return false
14658 }
14659 func rewriteValueARM64_OpARM64MVNshiftRL(v *Value) bool {
14660         v_0 := v.Args[0]
14661         // match: (MVNshiftRL (MOVDconst [c]) [d])
14662         // result: (MOVDconst [^int64(uint64(c)>>uint64(d))])
14663         for {
14664                 d := auxIntToInt64(v.AuxInt)
14665                 if v_0.Op != OpARM64MOVDconst {
14666                         break
14667                 }
14668                 c := auxIntToInt64(v_0.AuxInt)
14669                 v.reset(OpARM64MOVDconst)
14670                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
14671                 return true
14672         }
14673         return false
14674 }
14675 func rewriteValueARM64_OpARM64MVNshiftRO(v *Value) bool {
14676         v_0 := v.Args[0]
14677         // match: (MVNshiftRO (MOVDconst [c]) [d])
14678         // result: (MOVDconst [^rotateRight64(c, d)])
14679         for {
14680                 d := auxIntToInt64(v.AuxInt)
14681                 if v_0.Op != OpARM64MOVDconst {
14682                         break
14683                 }
14684                 c := auxIntToInt64(v_0.AuxInt)
14685                 v.reset(OpARM64MOVDconst)
14686                 v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
14687                 return true
14688         }
14689         return false
14690 }
14691 func rewriteValueARM64_OpARM64NEG(v *Value) bool {
14692         v_0 := v.Args[0]
14693         // match: (NEG (MUL x y))
14694         // result: (MNEG x y)
14695         for {
14696                 if v_0.Op != OpARM64MUL {
14697                         break
14698                 }
14699                 y := v_0.Args[1]
14700                 x := v_0.Args[0]
14701                 v.reset(OpARM64MNEG)
14702                 v.AddArg2(x, y)
14703                 return true
14704         }
14705         // match: (NEG (MULW x y))
14706         // cond: v.Type.Size() <= 4
14707         // result: (MNEGW x y)
14708         for {
14709                 if v_0.Op != OpARM64MULW {
14710                         break
14711                 }
14712                 y := v_0.Args[1]
14713                 x := v_0.Args[0]
14714                 if !(v.Type.Size() <= 4) {
14715                         break
14716                 }
14717                 v.reset(OpARM64MNEGW)
14718                 v.AddArg2(x, y)
14719                 return true
14720         }
14721         // match: (NEG (NEG x))
14722         // result: x
14723         for {
14724                 if v_0.Op != OpARM64NEG {
14725                         break
14726                 }
14727                 x := v_0.Args[0]
14728                 v.copyOf(x)
14729                 return true
14730         }
14731         // match: (NEG (MOVDconst [c]))
14732         // result: (MOVDconst [-c])
14733         for {
14734                 if v_0.Op != OpARM64MOVDconst {
14735                         break
14736                 }
14737                 c := auxIntToInt64(v_0.AuxInt)
14738                 v.reset(OpARM64MOVDconst)
14739                 v.AuxInt = int64ToAuxInt(-c)
14740                 return true
14741         }
14742         // match: (NEG x:(SLLconst [c] y))
14743         // cond: clobberIfDead(x)
14744         // result: (NEGshiftLL [c] y)
14745         for {
14746                 x := v_0
14747                 if x.Op != OpARM64SLLconst {
14748                         break
14749                 }
14750                 c := auxIntToInt64(x.AuxInt)
14751                 y := x.Args[0]
14752                 if !(clobberIfDead(x)) {
14753                         break
14754                 }
14755                 v.reset(OpARM64NEGshiftLL)
14756                 v.AuxInt = int64ToAuxInt(c)
14757                 v.AddArg(y)
14758                 return true
14759         }
14760         // match: (NEG x:(SRLconst [c] y))
14761         // cond: clobberIfDead(x)
14762         // result: (NEGshiftRL [c] y)
14763         for {
14764                 x := v_0
14765                 if x.Op != OpARM64SRLconst {
14766                         break
14767                 }
14768                 c := auxIntToInt64(x.AuxInt)
14769                 y := x.Args[0]
14770                 if !(clobberIfDead(x)) {
14771                         break
14772                 }
14773                 v.reset(OpARM64NEGshiftRL)
14774                 v.AuxInt = int64ToAuxInt(c)
14775                 v.AddArg(y)
14776                 return true
14777         }
14778         // match: (NEG x:(SRAconst [c] y))
14779         // cond: clobberIfDead(x)
14780         // result: (NEGshiftRA [c] y)
14781         for {
14782                 x := v_0
14783                 if x.Op != OpARM64SRAconst {
14784                         break
14785                 }
14786                 c := auxIntToInt64(x.AuxInt)
14787                 y := x.Args[0]
14788                 if !(clobberIfDead(x)) {
14789                         break
14790                 }
14791                 v.reset(OpARM64NEGshiftRA)
14792                 v.AuxInt = int64ToAuxInt(c)
14793                 v.AddArg(y)
14794                 return true
14795         }
14796         return false
14797 }
14798 func rewriteValueARM64_OpARM64NEGshiftLL(v *Value) bool {
14799         v_0 := v.Args[0]
14800         // match: (NEGshiftLL (MOVDconst [c]) [d])
14801         // result: (MOVDconst [-int64(uint64(c)<<uint64(d))])
14802         for {
14803                 d := auxIntToInt64(v.AuxInt)
14804                 if v_0.Op != OpARM64MOVDconst {
14805                         break
14806                 }
14807                 c := auxIntToInt64(v_0.AuxInt)
14808                 v.reset(OpARM64MOVDconst)
14809                 v.AuxInt = int64ToAuxInt(-int64(uint64(c) << uint64(d)))
14810                 return true
14811         }
14812         return false
14813 }
14814 func rewriteValueARM64_OpARM64NEGshiftRA(v *Value) bool {
14815         v_0 := v.Args[0]
14816         // match: (NEGshiftRA (MOVDconst [c]) [d])
14817         // result: (MOVDconst [-(c>>uint64(d))])
14818         for {
14819                 d := auxIntToInt64(v.AuxInt)
14820                 if v_0.Op != OpARM64MOVDconst {
14821                         break
14822                 }
14823                 c := auxIntToInt64(v_0.AuxInt)
14824                 v.reset(OpARM64MOVDconst)
14825                 v.AuxInt = int64ToAuxInt(-(c >> uint64(d)))
14826                 return true
14827         }
14828         return false
14829 }
14830 func rewriteValueARM64_OpARM64NEGshiftRL(v *Value) bool {
14831         v_0 := v.Args[0]
14832         // match: (NEGshiftRL (MOVDconst [c]) [d])
14833         // result: (MOVDconst [-int64(uint64(c)>>uint64(d))])
14834         for {
14835                 d := auxIntToInt64(v.AuxInt)
14836                 if v_0.Op != OpARM64MOVDconst {
14837                         break
14838                 }
14839                 c := auxIntToInt64(v_0.AuxInt)
14840                 v.reset(OpARM64MOVDconst)
14841                 v.AuxInt = int64ToAuxInt(-int64(uint64(c) >> uint64(d)))
14842                 return true
14843         }
14844         return false
14845 }
14846 func rewriteValueARM64_OpARM64NotEqual(v *Value) bool {
14847         v_0 := v.Args[0]
14848         b := v.Block
14849         // match: (NotEqual (CMPconst [0] z:(AND x y)))
14850         // cond: z.Uses == 1
14851         // result: (NotEqual (TST x y))
14852         for {
14853                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
14854                         break
14855                 }
14856                 z := v_0.Args[0]
14857                 if z.Op != OpARM64AND {
14858                         break
14859                 }
14860                 y := z.Args[1]
14861                 x := z.Args[0]
14862                 if !(z.Uses == 1) {
14863                         break
14864                 }
14865                 v.reset(OpARM64NotEqual)
14866                 v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
14867                 v0.AddArg2(x, y)
14868                 v.AddArg(v0)
14869                 return true
14870         }
14871         // match: (NotEqual (CMPWconst [0] x:(ANDconst [c] y)))
14872         // cond: x.Uses == 1
14873         // result: (NotEqual (TSTWconst [int32(c)] y))
14874         for {
14875                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
14876                         break
14877                 }
14878                 x := v_0.Args[0]
14879                 if x.Op != OpARM64ANDconst {
14880                         break
14881                 }
14882                 c := auxIntToInt64(x.AuxInt)
14883                 y := x.Args[0]
14884                 if !(x.Uses == 1) {
14885                         break
14886                 }
14887                 v.reset(OpARM64NotEqual)
14888                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
14889                 v0.AuxInt = int32ToAuxInt(int32(c))
14890                 v0.AddArg(y)
14891                 v.AddArg(v0)
14892                 return true
14893         }
14894         // match: (NotEqual (CMPWconst [0] z:(AND x y)))
14895         // cond: z.Uses == 1
14896         // result: (NotEqual (TSTW x y))
14897         for {
14898                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
14899                         break
14900                 }
14901                 z := v_0.Args[0]
14902                 if z.Op != OpARM64AND {
14903                         break
14904                 }
14905                 y := z.Args[1]
14906                 x := z.Args[0]
14907                 if !(z.Uses == 1) {
14908                         break
14909                 }
14910                 v.reset(OpARM64NotEqual)
14911                 v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
14912                 v0.AddArg2(x, y)
14913                 v.AddArg(v0)
14914                 return true
14915         }
14916         // match: (NotEqual (CMPconst [0] x:(ANDconst [c] y)))
14917         // cond: x.Uses == 1
14918         // result: (NotEqual (TSTconst [c] y))
14919         for {
14920                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
14921                         break
14922                 }
14923                 x := v_0.Args[0]
14924                 if x.Op != OpARM64ANDconst {
14925                         break
14926                 }
14927                 c := auxIntToInt64(x.AuxInt)
14928                 y := x.Args[0]
14929                 if !(x.Uses == 1) {
14930                         break
14931                 }
14932                 v.reset(OpARM64NotEqual)
14933                 v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
14934                 v0.AuxInt = int64ToAuxInt(c)
14935                 v0.AddArg(y)
14936                 v.AddArg(v0)
14937                 return true
14938         }
14939         // match: (NotEqual (CMP x z:(NEG y)))
14940         // cond: z.Uses == 1
14941         // result: (NotEqual (CMN x y))
14942         for {
14943                 if v_0.Op != OpARM64CMP {
14944                         break
14945                 }
14946                 _ = v_0.Args[1]
14947                 x := v_0.Args[0]
14948                 z := v_0.Args[1]
14949                 if z.Op != OpARM64NEG {
14950                         break
14951                 }
14952                 y := z.Args[0]
14953                 if !(z.Uses == 1) {
14954                         break
14955                 }
14956                 v.reset(OpARM64NotEqual)
14957                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
14958                 v0.AddArg2(x, y)
14959                 v.AddArg(v0)
14960                 return true
14961         }
14962         // match: (NotEqual (CMPW x z:(NEG y)))
14963         // cond: z.Uses == 1
14964         // result: (NotEqual (CMNW x y))
14965         for {
14966                 if v_0.Op != OpARM64CMPW {
14967                         break
14968                 }
14969                 _ = v_0.Args[1]
14970                 x := v_0.Args[0]
14971                 z := v_0.Args[1]
14972                 if z.Op != OpARM64NEG {
14973                         break
14974                 }
14975                 y := z.Args[0]
14976                 if !(z.Uses == 1) {
14977                         break
14978                 }
14979                 v.reset(OpARM64NotEqual)
14980                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
14981                 v0.AddArg2(x, y)
14982                 v.AddArg(v0)
14983                 return true
14984         }
14985         // match: (NotEqual (CMPconst [0] x:(ADDconst [c] y)))
14986         // cond: x.Uses == 1
14987         // result: (NotEqual (CMNconst [c] y))
14988         for {
14989                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
14990                         break
14991                 }
14992                 x := v_0.Args[0]
14993                 if x.Op != OpARM64ADDconst {
14994                         break
14995                 }
14996                 c := auxIntToInt64(x.AuxInt)
14997                 y := x.Args[0]
14998                 if !(x.Uses == 1) {
14999                         break
15000                 }
15001                 v.reset(OpARM64NotEqual)
15002                 v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
15003                 v0.AuxInt = int64ToAuxInt(c)
15004                 v0.AddArg(y)
15005                 v.AddArg(v0)
15006                 return true
15007         }
15008         // match: (NotEqual (CMPWconst [0] x:(ADDconst [c] y)))
15009         // cond: x.Uses == 1
15010         // result: (NotEqual (CMNWconst [int32(c)] y))
15011         for {
15012                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
15013                         break
15014                 }
15015                 x := v_0.Args[0]
15016                 if x.Op != OpARM64ADDconst {
15017                         break
15018                 }
15019                 c := auxIntToInt64(x.AuxInt)
15020                 y := x.Args[0]
15021                 if !(x.Uses == 1) {
15022                         break
15023                 }
15024                 v.reset(OpARM64NotEqual)
15025                 v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
15026                 v0.AuxInt = int32ToAuxInt(int32(c))
15027                 v0.AddArg(y)
15028                 v.AddArg(v0)
15029                 return true
15030         }
15031         // match: (NotEqual (CMPconst [0] z:(ADD x y)))
15032         // cond: z.Uses == 1
15033         // result: (NotEqual (CMN x y))
15034         for {
15035                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
15036                         break
15037                 }
15038                 z := v_0.Args[0]
15039                 if z.Op != OpARM64ADD {
15040                         break
15041                 }
15042                 y := z.Args[1]
15043                 x := z.Args[0]
15044                 if !(z.Uses == 1) {
15045                         break
15046                 }
15047                 v.reset(OpARM64NotEqual)
15048                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
15049                 v0.AddArg2(x, y)
15050                 v.AddArg(v0)
15051                 return true
15052         }
15053         // match: (NotEqual (CMPWconst [0] z:(ADD x y)))
15054         // cond: z.Uses == 1
15055         // result: (NotEqual (CMNW x y))
15056         for {
15057                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
15058                         break
15059                 }
15060                 z := v_0.Args[0]
15061                 if z.Op != OpARM64ADD {
15062                         break
15063                 }
15064                 y := z.Args[1]
15065                 x := z.Args[0]
15066                 if !(z.Uses == 1) {
15067                         break
15068                 }
15069                 v.reset(OpARM64NotEqual)
15070                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
15071                 v0.AddArg2(x, y)
15072                 v.AddArg(v0)
15073                 return true
15074         }
15075         // match: (NotEqual (CMPconst [0] z:(MADD a x y)))
15076         // cond: z.Uses == 1
15077         // result: (NotEqual (CMN a (MUL <x.Type> x y)))
15078         for {
15079                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
15080                         break
15081                 }
15082                 z := v_0.Args[0]
15083                 if z.Op != OpARM64MADD {
15084                         break
15085                 }
15086                 y := z.Args[2]
15087                 a := z.Args[0]
15088                 x := z.Args[1]
15089                 if !(z.Uses == 1) {
15090                         break
15091                 }
15092                 v.reset(OpARM64NotEqual)
15093                 v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
15094                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
15095                 v1.AddArg2(x, y)
15096                 v0.AddArg2(a, v1)
15097                 v.AddArg(v0)
15098                 return true
15099         }
15100         // match: (NotEqual (CMPconst [0] z:(MSUB a x y)))
15101         // cond: z.Uses == 1
15102         // result: (NotEqual (CMP a (MUL <x.Type> x y)))
15103         for {
15104                 if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
15105                         break
15106                 }
15107                 z := v_0.Args[0]
15108                 if z.Op != OpARM64MSUB {
15109                         break
15110                 }
15111                 y := z.Args[2]
15112                 a := z.Args[0]
15113                 x := z.Args[1]
15114                 if !(z.Uses == 1) {
15115                         break
15116                 }
15117                 v.reset(OpARM64NotEqual)
15118                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
15119                 v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
15120                 v1.AddArg2(x, y)
15121                 v0.AddArg2(a, v1)
15122                 v.AddArg(v0)
15123                 return true
15124         }
15125         // match: (NotEqual (CMPWconst [0] z:(MADDW a x y)))
15126         // cond: z.Uses == 1
15127         // result: (NotEqual (CMNW a (MULW <x.Type> x y)))
15128         for {
15129                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
15130                         break
15131                 }
15132                 z := v_0.Args[0]
15133                 if z.Op != OpARM64MADDW {
15134                         break
15135                 }
15136                 y := z.Args[2]
15137                 a := z.Args[0]
15138                 x := z.Args[1]
15139                 if !(z.Uses == 1) {
15140                         break
15141                 }
15142                 v.reset(OpARM64NotEqual)
15143                 v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
15144                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
15145                 v1.AddArg2(x, y)
15146                 v0.AddArg2(a, v1)
15147                 v.AddArg(v0)
15148                 return true
15149         }
15150         // match: (NotEqual (CMPWconst [0] z:(MSUBW a x y)))
15151         // cond: z.Uses == 1
15152         // result: (NotEqual (CMPW a (MULW <x.Type> x y)))
15153         for {
15154                 if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
15155                         break
15156                 }
15157                 z := v_0.Args[0]
15158                 if z.Op != OpARM64MSUBW {
15159                         break
15160                 }
15161                 y := z.Args[2]
15162                 a := z.Args[0]
15163                 x := z.Args[1]
15164                 if !(z.Uses == 1) {
15165                         break
15166                 }
15167                 v.reset(OpARM64NotEqual)
15168                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
15169                 v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
15170                 v1.AddArg2(x, y)
15171                 v0.AddArg2(a, v1)
15172                 v.AddArg(v0)
15173                 return true
15174         }
15175         // match: (NotEqual (FlagConstant [fc]))
15176         // result: (MOVDconst [b2i(fc.ne())])
15177         for {
15178                 if v_0.Op != OpARM64FlagConstant {
15179                         break
15180                 }
15181                 fc := auxIntToFlagConstant(v_0.AuxInt)
15182                 v.reset(OpARM64MOVDconst)
15183                 v.AuxInt = int64ToAuxInt(b2i(fc.ne()))
15184                 return true
15185         }
15186         // match: (NotEqual (InvertFlags x))
15187         // result: (NotEqual x)
15188         for {
15189                 if v_0.Op != OpARM64InvertFlags {
15190                         break
15191                 }
15192                 x := v_0.Args[0]
15193                 v.reset(OpARM64NotEqual)
15194                 v.AddArg(x)
15195                 return true
15196         }
15197         return false
15198 }
15199 func rewriteValueARM64_OpARM64OR(v *Value) bool {
15200         v_1 := v.Args[1]
15201         v_0 := v.Args[0]
15202         // match: (OR x (MOVDconst [c]))
15203         // result: (ORconst [c] x)
15204         for {
15205                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15206                         x := v_0
15207                         if v_1.Op != OpARM64MOVDconst {
15208                                 continue
15209                         }
15210                         c := auxIntToInt64(v_1.AuxInt)
15211                         v.reset(OpARM64ORconst)
15212                         v.AuxInt = int64ToAuxInt(c)
15213                         v.AddArg(x)
15214                         return true
15215                 }
15216                 break
15217         }
15218         // match: (OR x x)
15219         // result: x
15220         for {
15221                 x := v_0
15222                 if x != v_1 {
15223                         break
15224                 }
15225                 v.copyOf(x)
15226                 return true
15227         }
15228         // match: (OR x (MVN y))
15229         // result: (ORN x y)
15230         for {
15231                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15232                         x := v_0
15233                         if v_1.Op != OpARM64MVN {
15234                                 continue
15235                         }
15236                         y := v_1.Args[0]
15237                         v.reset(OpARM64ORN)
15238                         v.AddArg2(x, y)
15239                         return true
15240                 }
15241                 break
15242         }
15243         // match: (OR x0 x1:(SLLconst [c] y))
15244         // cond: clobberIfDead(x1)
15245         // result: (ORshiftLL x0 y [c])
15246         for {
15247                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15248                         x0 := v_0
15249                         x1 := v_1
15250                         if x1.Op != OpARM64SLLconst {
15251                                 continue
15252                         }
15253                         c := auxIntToInt64(x1.AuxInt)
15254                         y := x1.Args[0]
15255                         if !(clobberIfDead(x1)) {
15256                                 continue
15257                         }
15258                         v.reset(OpARM64ORshiftLL)
15259                         v.AuxInt = int64ToAuxInt(c)
15260                         v.AddArg2(x0, y)
15261                         return true
15262                 }
15263                 break
15264         }
15265         // match: (OR x0 x1:(SRLconst [c] y))
15266         // cond: clobberIfDead(x1)
15267         // result: (ORshiftRL x0 y [c])
15268         for {
15269                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15270                         x0 := v_0
15271                         x1 := v_1
15272                         if x1.Op != OpARM64SRLconst {
15273                                 continue
15274                         }
15275                         c := auxIntToInt64(x1.AuxInt)
15276                         y := x1.Args[0]
15277                         if !(clobberIfDead(x1)) {
15278                                 continue
15279                         }
15280                         v.reset(OpARM64ORshiftRL)
15281                         v.AuxInt = int64ToAuxInt(c)
15282                         v.AddArg2(x0, y)
15283                         return true
15284                 }
15285                 break
15286         }
15287         // match: (OR x0 x1:(SRAconst [c] y))
15288         // cond: clobberIfDead(x1)
15289         // result: (ORshiftRA x0 y [c])
15290         for {
15291                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15292                         x0 := v_0
15293                         x1 := v_1
15294                         if x1.Op != OpARM64SRAconst {
15295                                 continue
15296                         }
15297                         c := auxIntToInt64(x1.AuxInt)
15298                         y := x1.Args[0]
15299                         if !(clobberIfDead(x1)) {
15300                                 continue
15301                         }
15302                         v.reset(OpARM64ORshiftRA)
15303                         v.AuxInt = int64ToAuxInt(c)
15304                         v.AddArg2(x0, y)
15305                         return true
15306                 }
15307                 break
15308         }
15309         // match: (OR x0 x1:(RORconst [c] y))
15310         // cond: clobberIfDead(x1)
15311         // result: (ORshiftRO x0 y [c])
15312         for {
15313                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15314                         x0 := v_0
15315                         x1 := v_1
15316                         if x1.Op != OpARM64RORconst {
15317                                 continue
15318                         }
15319                         c := auxIntToInt64(x1.AuxInt)
15320                         y := x1.Args[0]
15321                         if !(clobberIfDead(x1)) {
15322                                 continue
15323                         }
15324                         v.reset(OpARM64ORshiftRO)
15325                         v.AuxInt = int64ToAuxInt(c)
15326                         v.AddArg2(x0, y)
15327                         return true
15328                 }
15329                 break
15330         }
15331         // match: (OR (UBFIZ [bfc] x) (ANDconst [ac] y))
15332         // cond: ac == ^((1<<uint(bfc.getARM64BFwidth())-1) << uint(bfc.getARM64BFlsb()))
15333         // result: (BFI [bfc] y x)
15334         for {
15335                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15336                         if v_0.Op != OpARM64UBFIZ {
15337                                 continue
15338                         }
15339                         bfc := auxIntToArm64BitField(v_0.AuxInt)
15340                         x := v_0.Args[0]
15341                         if v_1.Op != OpARM64ANDconst {
15342                                 continue
15343                         }
15344                         ac := auxIntToInt64(v_1.AuxInt)
15345                         y := v_1.Args[0]
15346                         if !(ac == ^((1<<uint(bfc.getARM64BFwidth()) - 1) << uint(bfc.getARM64BFlsb()))) {
15347                                 continue
15348                         }
15349                         v.reset(OpARM64BFI)
15350                         v.AuxInt = arm64BitFieldToAuxInt(bfc)
15351                         v.AddArg2(y, x)
15352                         return true
15353                 }
15354                 break
15355         }
15356         // match: (OR (UBFX [bfc] x) (ANDconst [ac] y))
15357         // cond: ac == ^(1<<uint(bfc.getARM64BFwidth())-1)
15358         // result: (BFXIL [bfc] y x)
15359         for {
15360                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
15361                         if v_0.Op != OpARM64UBFX {
15362                                 continue
15363                         }
15364                         bfc := auxIntToArm64BitField(v_0.AuxInt)
15365                         x := v_0.Args[0]
15366                         if v_1.Op != OpARM64ANDconst {
15367                                 continue
15368                         }
15369                         ac := auxIntToInt64(v_1.AuxInt)
15370                         y := v_1.Args[0]
15371                         if !(ac == ^(1<<uint(bfc.getARM64BFwidth()) - 1)) {
15372                                 continue
15373                         }
15374                         v.reset(OpARM64BFXIL)
15375                         v.AuxInt = arm64BitFieldToAuxInt(bfc)
15376                         v.AddArg2(y, x)
15377                         return true
15378                 }
15379                 break
15380         }
15381         return false
15382 }
15383 func rewriteValueARM64_OpARM64ORN(v *Value) bool {
15384         v_1 := v.Args[1]
15385         v_0 := v.Args[0]
15386         // match: (ORN x (MOVDconst [c]))
15387         // result: (ORconst [^c] x)
15388         for {
15389                 x := v_0
15390                 if v_1.Op != OpARM64MOVDconst {
15391                         break
15392                 }
15393                 c := auxIntToInt64(v_1.AuxInt)
15394                 v.reset(OpARM64ORconst)
15395                 v.AuxInt = int64ToAuxInt(^c)
15396                 v.AddArg(x)
15397                 return true
15398         }
15399         // match: (ORN x x)
15400         // result: (MOVDconst [-1])
15401         for {
15402                 x := v_0
15403                 if x != v_1 {
15404                         break
15405                 }
15406                 v.reset(OpARM64MOVDconst)
15407                 v.AuxInt = int64ToAuxInt(-1)
15408                 return true
15409         }
15410         // match: (ORN x0 x1:(SLLconst [c] y))
15411         // cond: clobberIfDead(x1)
15412         // result: (ORNshiftLL x0 y [c])
15413         for {
15414                 x0 := v_0
15415                 x1 := v_1
15416                 if x1.Op != OpARM64SLLconst {
15417                         break
15418                 }
15419                 c := auxIntToInt64(x1.AuxInt)
15420                 y := x1.Args[0]
15421                 if !(clobberIfDead(x1)) {
15422                         break
15423                 }
15424                 v.reset(OpARM64ORNshiftLL)
15425                 v.AuxInt = int64ToAuxInt(c)
15426                 v.AddArg2(x0, y)
15427                 return true
15428         }
15429         // match: (ORN x0 x1:(SRLconst [c] y))
15430         // cond: clobberIfDead(x1)
15431         // result: (ORNshiftRL x0 y [c])
15432         for {
15433                 x0 := v_0
15434                 x1 := v_1
15435                 if x1.Op != OpARM64SRLconst {
15436                         break
15437                 }
15438                 c := auxIntToInt64(x1.AuxInt)
15439                 y := x1.Args[0]
15440                 if !(clobberIfDead(x1)) {
15441                         break
15442                 }
15443                 v.reset(OpARM64ORNshiftRL)
15444                 v.AuxInt = int64ToAuxInt(c)
15445                 v.AddArg2(x0, y)
15446                 return true
15447         }
15448         // match: (ORN x0 x1:(SRAconst [c] y))
15449         // cond: clobberIfDead(x1)
15450         // result: (ORNshiftRA x0 y [c])
15451         for {
15452                 x0 := v_0
15453                 x1 := v_1
15454                 if x1.Op != OpARM64SRAconst {
15455                         break
15456                 }
15457                 c := auxIntToInt64(x1.AuxInt)
15458                 y := x1.Args[0]
15459                 if !(clobberIfDead(x1)) {
15460                         break
15461                 }
15462                 v.reset(OpARM64ORNshiftRA)
15463                 v.AuxInt = int64ToAuxInt(c)
15464                 v.AddArg2(x0, y)
15465                 return true
15466         }
15467         // match: (ORN x0 x1:(RORconst [c] y))
15468         // cond: clobberIfDead(x1)
15469         // result: (ORNshiftRO x0 y [c])
15470         for {
15471                 x0 := v_0
15472                 x1 := v_1
15473                 if x1.Op != OpARM64RORconst {
15474                         break
15475                 }
15476                 c := auxIntToInt64(x1.AuxInt)
15477                 y := x1.Args[0]
15478                 if !(clobberIfDead(x1)) {
15479                         break
15480                 }
15481                 v.reset(OpARM64ORNshiftRO)
15482                 v.AuxInt = int64ToAuxInt(c)
15483                 v.AddArg2(x0, y)
15484                 return true
15485         }
15486         return false
15487 }
15488 func rewriteValueARM64_OpARM64ORNshiftLL(v *Value) bool {
15489         v_1 := v.Args[1]
15490         v_0 := v.Args[0]
15491         // match: (ORNshiftLL x (MOVDconst [c]) [d])
15492         // result: (ORconst x [^int64(uint64(c)<<uint64(d))])
15493         for {
15494                 d := auxIntToInt64(v.AuxInt)
15495                 x := v_0
15496                 if v_1.Op != OpARM64MOVDconst {
15497                         break
15498                 }
15499                 c := auxIntToInt64(v_1.AuxInt)
15500                 v.reset(OpARM64ORconst)
15501                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) << uint64(d)))
15502                 v.AddArg(x)
15503                 return true
15504         }
15505         // match: (ORNshiftLL (SLLconst x [c]) x [c])
15506         // result: (MOVDconst [-1])
15507         for {
15508                 c := auxIntToInt64(v.AuxInt)
15509                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
15510                         break
15511                 }
15512                 x := v_0.Args[0]
15513                 if x != v_1 {
15514                         break
15515                 }
15516                 v.reset(OpARM64MOVDconst)
15517                 v.AuxInt = int64ToAuxInt(-1)
15518                 return true
15519         }
15520         return false
15521 }
15522 func rewriteValueARM64_OpARM64ORNshiftRA(v *Value) bool {
15523         v_1 := v.Args[1]
15524         v_0 := v.Args[0]
15525         // match: (ORNshiftRA x (MOVDconst [c]) [d])
15526         // result: (ORconst x [^(c>>uint64(d))])
15527         for {
15528                 d := auxIntToInt64(v.AuxInt)
15529                 x := v_0
15530                 if v_1.Op != OpARM64MOVDconst {
15531                         break
15532                 }
15533                 c := auxIntToInt64(v_1.AuxInt)
15534                 v.reset(OpARM64ORconst)
15535                 v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
15536                 v.AddArg(x)
15537                 return true
15538         }
15539         // match: (ORNshiftRA (SRAconst x [c]) x [c])
15540         // result: (MOVDconst [-1])
15541         for {
15542                 c := auxIntToInt64(v.AuxInt)
15543                 if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
15544                         break
15545                 }
15546                 x := v_0.Args[0]
15547                 if x != v_1 {
15548                         break
15549                 }
15550                 v.reset(OpARM64MOVDconst)
15551                 v.AuxInt = int64ToAuxInt(-1)
15552                 return true
15553         }
15554         return false
15555 }
15556 func rewriteValueARM64_OpARM64ORNshiftRL(v *Value) bool {
15557         v_1 := v.Args[1]
15558         v_0 := v.Args[0]
15559         // match: (ORNshiftRL x (MOVDconst [c]) [d])
15560         // result: (ORconst x [^int64(uint64(c)>>uint64(d))])
15561         for {
15562                 d := auxIntToInt64(v.AuxInt)
15563                 x := v_0
15564                 if v_1.Op != OpARM64MOVDconst {
15565                         break
15566                 }
15567                 c := auxIntToInt64(v_1.AuxInt)
15568                 v.reset(OpARM64ORconst)
15569                 v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
15570                 v.AddArg(x)
15571                 return true
15572         }
15573         // match: (ORNshiftRL (SRLconst x [c]) x [c])
15574         // result: (MOVDconst [-1])
15575         for {
15576                 c := auxIntToInt64(v.AuxInt)
15577                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
15578                         break
15579                 }
15580                 x := v_0.Args[0]
15581                 if x != v_1 {
15582                         break
15583                 }
15584                 v.reset(OpARM64MOVDconst)
15585                 v.AuxInt = int64ToAuxInt(-1)
15586                 return true
15587         }
15588         return false
15589 }
15590 func rewriteValueARM64_OpARM64ORNshiftRO(v *Value) bool {
15591         v_1 := v.Args[1]
15592         v_0 := v.Args[0]
15593         // match: (ORNshiftRO x (MOVDconst [c]) [d])
15594         // result: (ORconst x [^rotateRight64(c, d)])
15595         for {
15596                 d := auxIntToInt64(v.AuxInt)
15597                 x := v_0
15598                 if v_1.Op != OpARM64MOVDconst {
15599                         break
15600                 }
15601                 c := auxIntToInt64(v_1.AuxInt)
15602                 v.reset(OpARM64ORconst)
15603                 v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
15604                 v.AddArg(x)
15605                 return true
15606         }
15607         // match: (ORNshiftRO (RORconst x [c]) x [c])
15608         // result: (MOVDconst [-1])
15609         for {
15610                 c := auxIntToInt64(v.AuxInt)
15611                 if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
15612                         break
15613                 }
15614                 x := v_0.Args[0]
15615                 if x != v_1 {
15616                         break
15617                 }
15618                 v.reset(OpARM64MOVDconst)
15619                 v.AuxInt = int64ToAuxInt(-1)
15620                 return true
15621         }
15622         return false
15623 }
15624 func rewriteValueARM64_OpARM64ORconst(v *Value) bool {
15625         v_0 := v.Args[0]
15626         // match: (ORconst [0] x)
15627         // result: x
15628         for {
15629                 if auxIntToInt64(v.AuxInt) != 0 {
15630                         break
15631                 }
15632                 x := v_0
15633                 v.copyOf(x)
15634                 return true
15635         }
15636         // match: (ORconst [-1] _)
15637         // result: (MOVDconst [-1])
15638         for {
15639                 if auxIntToInt64(v.AuxInt) != -1 {
15640                         break
15641                 }
15642                 v.reset(OpARM64MOVDconst)
15643                 v.AuxInt = int64ToAuxInt(-1)
15644                 return true
15645         }
15646         // match: (ORconst [c] (MOVDconst [d]))
15647         // result: (MOVDconst [c|d])
15648         for {
15649                 c := auxIntToInt64(v.AuxInt)
15650                 if v_0.Op != OpARM64MOVDconst {
15651                         break
15652                 }
15653                 d := auxIntToInt64(v_0.AuxInt)
15654                 v.reset(OpARM64MOVDconst)
15655                 v.AuxInt = int64ToAuxInt(c | d)
15656                 return true
15657         }
15658         // match: (ORconst [c] (ORconst [d] x))
15659         // result: (ORconst [c|d] x)
15660         for {
15661                 c := auxIntToInt64(v.AuxInt)
15662                 if v_0.Op != OpARM64ORconst {
15663                         break
15664                 }
15665                 d := auxIntToInt64(v_0.AuxInt)
15666                 x := v_0.Args[0]
15667                 v.reset(OpARM64ORconst)
15668                 v.AuxInt = int64ToAuxInt(c | d)
15669                 v.AddArg(x)
15670                 return true
15671         }
15672         // match: (ORconst [c1] (ANDconst [c2] x))
15673         // cond: c2|c1 == ^0
15674         // result: (ORconst [c1] x)
15675         for {
15676                 c1 := auxIntToInt64(v.AuxInt)
15677                 if v_0.Op != OpARM64ANDconst {
15678                         break
15679                 }
15680                 c2 := auxIntToInt64(v_0.AuxInt)
15681                 x := v_0.Args[0]
15682                 if !(c2|c1 == ^0) {
15683                         break
15684                 }
15685                 v.reset(OpARM64ORconst)
15686                 v.AuxInt = int64ToAuxInt(c1)
15687                 v.AddArg(x)
15688                 return true
15689         }
15690         return false
15691 }
15692 func rewriteValueARM64_OpARM64ORshiftLL(v *Value) bool {
15693         v_1 := v.Args[1]
15694         v_0 := v.Args[0]
15695         b := v.Block
15696         typ := &b.Func.Config.Types
15697         // match: (ORshiftLL (MOVDconst [c]) x [d])
15698         // result: (ORconst [c] (SLLconst <x.Type> x [d]))
15699         for {
15700                 d := auxIntToInt64(v.AuxInt)
15701                 if v_0.Op != OpARM64MOVDconst {
15702                         break
15703                 }
15704                 c := auxIntToInt64(v_0.AuxInt)
15705                 x := v_1
15706                 v.reset(OpARM64ORconst)
15707                 v.AuxInt = int64ToAuxInt(c)
15708                 v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
15709                 v0.AuxInt = int64ToAuxInt(d)
15710                 v0.AddArg(x)
15711                 v.AddArg(v0)
15712                 return true
15713         }
15714         // match: (ORshiftLL x (MOVDconst [c]) [d])
15715         // result: (ORconst x [int64(uint64(c)<<uint64(d))])
15716         for {
15717                 d := auxIntToInt64(v.AuxInt)
15718                 x := v_0
15719                 if v_1.Op != OpARM64MOVDconst {
15720                         break
15721                 }
15722                 c := auxIntToInt64(v_1.AuxInt)
15723                 v.reset(OpARM64ORconst)
15724                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
15725                 v.AddArg(x)
15726                 return true
15727         }
15728         // match: (ORshiftLL y:(SLLconst x [c]) x [c])
15729         // result: y
15730         for {
15731                 c := auxIntToInt64(v.AuxInt)
15732                 y := v_0
15733                 if y.Op != OpARM64SLLconst || auxIntToInt64(y.AuxInt) != c {
15734                         break
15735                 }
15736                 x := y.Args[0]
15737                 if x != v_1 {
15738                         break
15739                 }
15740                 v.copyOf(y)
15741                 return true
15742         }
15743         // match: (ORshiftLL <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
15744         // result: (REV16W x)
15745         for {
15746                 if v.Type != typ.UInt16 || auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || v_0.Type != typ.UInt16 || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 8) {
15747                         break
15748                 }
15749                 x := v_0.Args[0]
15750                 if x != v_1 {
15751                         break
15752                 }
15753                 v.reset(OpARM64REV16W)
15754                 v.AddArg(x)
15755                 return true
15756         }
15757         // match: (ORshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
15758         // cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
15759         // result: (REV16W x)
15760         for {
15761                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
15762                         break
15763                 }
15764                 v_0_0 := v_0.Args[0]
15765                 if v_0_0.Op != OpARM64ANDconst {
15766                         break
15767                 }
15768                 c1 := auxIntToInt64(v_0_0.AuxInt)
15769                 x := v_0_0.Args[0]
15770                 if v_1.Op != OpARM64ANDconst {
15771                         break
15772                 }
15773                 c2 := auxIntToInt64(v_1.AuxInt)
15774                 if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
15775                         break
15776                 }
15777                 v.reset(OpARM64REV16W)
15778                 v.AddArg(x)
15779                 return true
15780         }
15781         // match: (ORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
15782         // cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
15783         // result: (REV16 x)
15784         for {
15785                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
15786                         break
15787                 }
15788                 v_0_0 := v_0.Args[0]
15789                 if v_0_0.Op != OpARM64ANDconst {
15790                         break
15791                 }
15792                 c1 := auxIntToInt64(v_0_0.AuxInt)
15793                 x := v_0_0.Args[0]
15794                 if v_1.Op != OpARM64ANDconst {
15795                         break
15796                 }
15797                 c2 := auxIntToInt64(v_1.AuxInt)
15798                 if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
15799                         break
15800                 }
15801                 v.reset(OpARM64REV16)
15802                 v.AddArg(x)
15803                 return true
15804         }
15805         // match: (ORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
15806         // cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
15807         // result: (REV16 (ANDconst <x.Type> [0xffffffff] x))
15808         for {
15809                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
15810                         break
15811                 }
15812                 v_0_0 := v_0.Args[0]
15813                 if v_0_0.Op != OpARM64ANDconst {
15814                         break
15815                 }
15816                 c1 := auxIntToInt64(v_0_0.AuxInt)
15817                 x := v_0_0.Args[0]
15818                 if v_1.Op != OpARM64ANDconst {
15819                         break
15820                 }
15821                 c2 := auxIntToInt64(v_1.AuxInt)
15822                 if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
15823                         break
15824                 }
15825                 v.reset(OpARM64REV16)
15826                 v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
15827                 v0.AuxInt = int64ToAuxInt(0xffffffff)
15828                 v0.AddArg(x)
15829                 v.AddArg(v0)
15830                 return true
15831         }
15832         // match: ( ORshiftLL [c] (SRLconst x [64-c]) x2)
15833         // result: (EXTRconst [64-c] x2 x)
15834         for {
15835                 c := auxIntToInt64(v.AuxInt)
15836                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
15837                         break
15838                 }
15839                 x := v_0.Args[0]
15840                 x2 := v_1
15841                 v.reset(OpARM64EXTRconst)
15842                 v.AuxInt = int64ToAuxInt(64 - c)
15843                 v.AddArg2(x2, x)
15844                 return true
15845         }
15846         // match: ( ORshiftLL <t> [c] (UBFX [bfc] x) x2)
15847         // cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
15848         // result: (EXTRWconst [32-c] x2 x)
15849         for {
15850                 t := v.Type
15851                 c := auxIntToInt64(v.AuxInt)
15852                 if v_0.Op != OpARM64UBFX {
15853                         break
15854                 }
15855                 bfc := auxIntToArm64BitField(v_0.AuxInt)
15856                 x := v_0.Args[0]
15857                 x2 := v_1
15858                 if !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
15859                         break
15860                 }
15861                 v.reset(OpARM64EXTRWconst)
15862                 v.AuxInt = int64ToAuxInt(32 - c)
15863                 v.AddArg2(x2, x)
15864                 return true
15865         }
15866         // match: (ORshiftLL [sc] (UBFX [bfc] x) (SRLconst [sc] y))
15867         // cond: sc == bfc.getARM64BFwidth()
15868         // result: (BFXIL [bfc] y x)
15869         for {
15870                 sc := auxIntToInt64(v.AuxInt)
15871                 if v_0.Op != OpARM64UBFX {
15872                         break
15873                 }
15874                 bfc := auxIntToArm64BitField(v_0.AuxInt)
15875                 x := v_0.Args[0]
15876                 if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != sc {
15877                         break
15878                 }
15879                 y := v_1.Args[0]
15880                 if !(sc == bfc.getARM64BFwidth()) {
15881                         break
15882                 }
15883                 v.reset(OpARM64BFXIL)
15884                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
15885                 v.AddArg2(y, x)
15886                 return true
15887         }
15888         return false
15889 }
15890 func rewriteValueARM64_OpARM64ORshiftRA(v *Value) bool {
15891         v_1 := v.Args[1]
15892         v_0 := v.Args[0]
15893         b := v.Block
15894         // match: (ORshiftRA (MOVDconst [c]) x [d])
15895         // result: (ORconst [c] (SRAconst <x.Type> x [d]))
15896         for {
15897                 d := auxIntToInt64(v.AuxInt)
15898                 if v_0.Op != OpARM64MOVDconst {
15899                         break
15900                 }
15901                 c := auxIntToInt64(v_0.AuxInt)
15902                 x := v_1
15903                 v.reset(OpARM64ORconst)
15904                 v.AuxInt = int64ToAuxInt(c)
15905                 v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
15906                 v0.AuxInt = int64ToAuxInt(d)
15907                 v0.AddArg(x)
15908                 v.AddArg(v0)
15909                 return true
15910         }
15911         // match: (ORshiftRA x (MOVDconst [c]) [d])
15912         // result: (ORconst x [c>>uint64(d)])
15913         for {
15914                 d := auxIntToInt64(v.AuxInt)
15915                 x := v_0
15916                 if v_1.Op != OpARM64MOVDconst {
15917                         break
15918                 }
15919                 c := auxIntToInt64(v_1.AuxInt)
15920                 v.reset(OpARM64ORconst)
15921                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
15922                 v.AddArg(x)
15923                 return true
15924         }
15925         // match: (ORshiftRA y:(SRAconst x [c]) x [c])
15926         // result: y
15927         for {
15928                 c := auxIntToInt64(v.AuxInt)
15929                 y := v_0
15930                 if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
15931                         break
15932                 }
15933                 x := y.Args[0]
15934                 if x != v_1 {
15935                         break
15936                 }
15937                 v.copyOf(y)
15938                 return true
15939         }
15940         return false
15941 }
15942 func rewriteValueARM64_OpARM64ORshiftRL(v *Value) bool {
15943         v_1 := v.Args[1]
15944         v_0 := v.Args[0]
15945         b := v.Block
15946         // match: (ORshiftRL (MOVDconst [c]) x [d])
15947         // result: (ORconst [c] (SRLconst <x.Type> x [d]))
15948         for {
15949                 d := auxIntToInt64(v.AuxInt)
15950                 if v_0.Op != OpARM64MOVDconst {
15951                         break
15952                 }
15953                 c := auxIntToInt64(v_0.AuxInt)
15954                 x := v_1
15955                 v.reset(OpARM64ORconst)
15956                 v.AuxInt = int64ToAuxInt(c)
15957                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
15958                 v0.AuxInt = int64ToAuxInt(d)
15959                 v0.AddArg(x)
15960                 v.AddArg(v0)
15961                 return true
15962         }
15963         // match: (ORshiftRL x (MOVDconst [c]) [d])
15964         // result: (ORconst x [int64(uint64(c)>>uint64(d))])
15965         for {
15966                 d := auxIntToInt64(v.AuxInt)
15967                 x := v_0
15968                 if v_1.Op != OpARM64MOVDconst {
15969                         break
15970                 }
15971                 c := auxIntToInt64(v_1.AuxInt)
15972                 v.reset(OpARM64ORconst)
15973                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
15974                 v.AddArg(x)
15975                 return true
15976         }
15977         // match: (ORshiftRL y:(SRLconst x [c]) x [c])
15978         // result: y
15979         for {
15980                 c := auxIntToInt64(v.AuxInt)
15981                 y := v_0
15982                 if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
15983                         break
15984                 }
15985                 x := y.Args[0]
15986                 if x != v_1 {
15987                         break
15988                 }
15989                 v.copyOf(y)
15990                 return true
15991         }
15992         // match: (ORshiftRL [rc] (ANDconst [ac] x) (SLLconst [lc] y))
15993         // cond: lc > rc && ac == ^((1<<uint(64-lc)-1) << uint64(lc-rc))
15994         // result: (BFI [armBFAuxInt(lc-rc, 64-lc)] x y)
15995         for {
15996                 rc := auxIntToInt64(v.AuxInt)
15997                 if v_0.Op != OpARM64ANDconst {
15998                         break
15999                 }
16000                 ac := auxIntToInt64(v_0.AuxInt)
16001                 x := v_0.Args[0]
16002                 if v_1.Op != OpARM64SLLconst {
16003                         break
16004                 }
16005                 lc := auxIntToInt64(v_1.AuxInt)
16006                 y := v_1.Args[0]
16007                 if !(lc > rc && ac == ^((1<<uint(64-lc)-1)<<uint64(lc-rc))) {
16008                         break
16009                 }
16010                 v.reset(OpARM64BFI)
16011                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc-rc, 64-lc))
16012                 v.AddArg2(x, y)
16013                 return true
16014         }
16015         // match: (ORshiftRL [rc] (ANDconst [ac] y) (SLLconst [lc] x))
16016         // cond: lc < rc && ac == ^((1<<uint(64-rc)-1))
16017         // result: (BFXIL [armBFAuxInt(rc-lc, 64-rc)] y x)
16018         for {
16019                 rc := auxIntToInt64(v.AuxInt)
16020                 if v_0.Op != OpARM64ANDconst {
16021                         break
16022                 }
16023                 ac := auxIntToInt64(v_0.AuxInt)
16024                 y := v_0.Args[0]
16025                 if v_1.Op != OpARM64SLLconst {
16026                         break
16027                 }
16028                 lc := auxIntToInt64(v_1.AuxInt)
16029                 x := v_1.Args[0]
16030                 if !(lc < rc && ac == ^(1<<uint(64-rc)-1)) {
16031                         break
16032                 }
16033                 v.reset(OpARM64BFXIL)
16034                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc-lc, 64-rc))
16035                 v.AddArg2(y, x)
16036                 return true
16037         }
16038         return false
16039 }
16040 func rewriteValueARM64_OpARM64ORshiftRO(v *Value) bool {
16041         v_1 := v.Args[1]
16042         v_0 := v.Args[0]
16043         b := v.Block
16044         // match: (ORshiftRO (MOVDconst [c]) x [d])
16045         // result: (ORconst [c] (RORconst <x.Type> x [d]))
16046         for {
16047                 d := auxIntToInt64(v.AuxInt)
16048                 if v_0.Op != OpARM64MOVDconst {
16049                         break
16050                 }
16051                 c := auxIntToInt64(v_0.AuxInt)
16052                 x := v_1
16053                 v.reset(OpARM64ORconst)
16054                 v.AuxInt = int64ToAuxInt(c)
16055                 v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
16056                 v0.AuxInt = int64ToAuxInt(d)
16057                 v0.AddArg(x)
16058                 v.AddArg(v0)
16059                 return true
16060         }
16061         // match: (ORshiftRO x (MOVDconst [c]) [d])
16062         // result: (ORconst x [rotateRight64(c, d)])
16063         for {
16064                 d := auxIntToInt64(v.AuxInt)
16065                 x := v_0
16066                 if v_1.Op != OpARM64MOVDconst {
16067                         break
16068                 }
16069                 c := auxIntToInt64(v_1.AuxInt)
16070                 v.reset(OpARM64ORconst)
16071                 v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
16072                 v.AddArg(x)
16073                 return true
16074         }
16075         // match: (ORshiftRO y:(RORconst x [c]) x [c])
16076         // result: y
16077         for {
16078                 c := auxIntToInt64(v.AuxInt)
16079                 y := v_0
16080                 if y.Op != OpARM64RORconst || auxIntToInt64(y.AuxInt) != c {
16081                         break
16082                 }
16083                 x := y.Args[0]
16084                 if x != v_1 {
16085                         break
16086                 }
16087                 v.copyOf(y)
16088                 return true
16089         }
16090         return false
16091 }
16092 func rewriteValueARM64_OpARM64REV(v *Value) bool {
16093         v_0 := v.Args[0]
16094         // match: (REV (REV p))
16095         // result: p
16096         for {
16097                 if v_0.Op != OpARM64REV {
16098                         break
16099                 }
16100                 p := v_0.Args[0]
16101                 v.copyOf(p)
16102                 return true
16103         }
16104         return false
16105 }
16106 func rewriteValueARM64_OpARM64REVW(v *Value) bool {
16107         v_0 := v.Args[0]
16108         // match: (REVW (REVW p))
16109         // result: p
16110         for {
16111                 if v_0.Op != OpARM64REVW {
16112                         break
16113                 }
16114                 p := v_0.Args[0]
16115                 v.copyOf(p)
16116                 return true
16117         }
16118         return false
16119 }
16120 func rewriteValueARM64_OpARM64ROR(v *Value) bool {
16121         v_1 := v.Args[1]
16122         v_0 := v.Args[0]
16123         // match: (ROR x (MOVDconst [c]))
16124         // result: (RORconst x [c&63])
16125         for {
16126                 x := v_0
16127                 if v_1.Op != OpARM64MOVDconst {
16128                         break
16129                 }
16130                 c := auxIntToInt64(v_1.AuxInt)
16131                 v.reset(OpARM64RORconst)
16132                 v.AuxInt = int64ToAuxInt(c & 63)
16133                 v.AddArg(x)
16134                 return true
16135         }
16136         return false
16137 }
16138 func rewriteValueARM64_OpARM64RORW(v *Value) bool {
16139         v_1 := v.Args[1]
16140         v_0 := v.Args[0]
16141         // match: (RORW x (MOVDconst [c]))
16142         // result: (RORWconst x [c&31])
16143         for {
16144                 x := v_0
16145                 if v_1.Op != OpARM64MOVDconst {
16146                         break
16147                 }
16148                 c := auxIntToInt64(v_1.AuxInt)
16149                 v.reset(OpARM64RORWconst)
16150                 v.AuxInt = int64ToAuxInt(c & 31)
16151                 v.AddArg(x)
16152                 return true
16153         }
16154         return false
16155 }
16156 func rewriteValueARM64_OpARM64SBCSflags(v *Value) bool {
16157         v_2 := v.Args[2]
16158         v_1 := v.Args[1]
16159         v_0 := v.Args[0]
16160         b := v.Block
16161         typ := &b.Func.Config.Types
16162         // match: (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> bo)))))
16163         // result: (SBCSflags x y bo)
16164         for {
16165                 x := v_0
16166                 y := v_1
16167                 if v_2.Op != OpSelect1 || v_2.Type != types.TypeFlags {
16168                         break
16169                 }
16170                 v_2_0 := v_2.Args[0]
16171                 if v_2_0.Op != OpARM64NEGSflags {
16172                         break
16173                 }
16174                 v_2_0_0 := v_2_0.Args[0]
16175                 if v_2_0_0.Op != OpARM64NEG || v_2_0_0.Type != typ.UInt64 {
16176                         break
16177                 }
16178                 v_2_0_0_0 := v_2_0_0.Args[0]
16179                 if v_2_0_0_0.Op != OpARM64NGCzerocarry || v_2_0_0_0.Type != typ.UInt64 {
16180                         break
16181                 }
16182                 bo := v_2_0_0_0.Args[0]
16183                 v.reset(OpARM64SBCSflags)
16184                 v.AddArg3(x, y, bo)
16185                 return true
16186         }
16187         // match: (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (MOVDconst [0]))))
16188         // result: (SUBSflags x y)
16189         for {
16190                 x := v_0
16191                 y := v_1
16192                 if v_2.Op != OpSelect1 || v_2.Type != types.TypeFlags {
16193                         break
16194                 }
16195                 v_2_0 := v_2.Args[0]
16196                 if v_2_0.Op != OpARM64NEGSflags {
16197                         break
16198                 }
16199                 v_2_0_0 := v_2_0.Args[0]
16200                 if v_2_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 {
16201                         break
16202                 }
16203                 v.reset(OpARM64SUBSflags)
16204                 v.AddArg2(x, y)
16205                 return true
16206         }
16207         return false
16208 }
16209 func rewriteValueARM64_OpARM64SLL(v *Value) bool {
16210         v_1 := v.Args[1]
16211         v_0 := v.Args[0]
16212         // match: (SLL x (MOVDconst [c]))
16213         // result: (SLLconst x [c&63])
16214         for {
16215                 x := v_0
16216                 if v_1.Op != OpARM64MOVDconst {
16217                         break
16218                 }
16219                 c := auxIntToInt64(v_1.AuxInt)
16220                 v.reset(OpARM64SLLconst)
16221                 v.AuxInt = int64ToAuxInt(c & 63)
16222                 v.AddArg(x)
16223                 return true
16224         }
16225         // match: (SLL x (ANDconst [63] y))
16226         // result: (SLL x y)
16227         for {
16228                 x := v_0
16229                 if v_1.Op != OpARM64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 {
16230                         break
16231                 }
16232                 y := v_1.Args[0]
16233                 v.reset(OpARM64SLL)
16234                 v.AddArg2(x, y)
16235                 return true
16236         }
16237         return false
16238 }
16239 func rewriteValueARM64_OpARM64SLLconst(v *Value) bool {
16240         v_0 := v.Args[0]
16241         // match: (SLLconst [c] (MOVDconst [d]))
16242         // result: (MOVDconst [d<<uint64(c)])
16243         for {
16244                 c := auxIntToInt64(v.AuxInt)
16245                 if v_0.Op != OpARM64MOVDconst {
16246                         break
16247                 }
16248                 d := auxIntToInt64(v_0.AuxInt)
16249                 v.reset(OpARM64MOVDconst)
16250                 v.AuxInt = int64ToAuxInt(d << uint64(c))
16251                 return true
16252         }
16253         // match: (SLLconst [c] (SRLconst [c] x))
16254         // cond: 0 < c && c < 64
16255         // result: (ANDconst [^(1<<uint(c)-1)] x)
16256         for {
16257                 c := auxIntToInt64(v.AuxInt)
16258                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
16259                         break
16260                 }
16261                 x := v_0.Args[0]
16262                 if !(0 < c && c < 64) {
16263                         break
16264                 }
16265                 v.reset(OpARM64ANDconst)
16266                 v.AuxInt = int64ToAuxInt(^(1<<uint(c) - 1))
16267                 v.AddArg(x)
16268                 return true
16269         }
16270         // match: (SLLconst [lc] (MOVWreg x))
16271         // result: (SBFIZ [armBFAuxInt(lc, min(32, 64-lc))] x)
16272         for {
16273                 lc := auxIntToInt64(v.AuxInt)
16274                 if v_0.Op != OpARM64MOVWreg {
16275                         break
16276                 }
16277                 x := v_0.Args[0]
16278                 v.reset(OpARM64SBFIZ)
16279                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, min(32, 64-lc)))
16280                 v.AddArg(x)
16281                 return true
16282         }
16283         // match: (SLLconst [lc] (MOVHreg x))
16284         // result: (SBFIZ [armBFAuxInt(lc, min(16, 64-lc))] x)
16285         for {
16286                 lc := auxIntToInt64(v.AuxInt)
16287                 if v_0.Op != OpARM64MOVHreg {
16288                         break
16289                 }
16290                 x := v_0.Args[0]
16291                 v.reset(OpARM64SBFIZ)
16292                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, min(16, 64-lc)))
16293                 v.AddArg(x)
16294                 return true
16295         }
16296         // match: (SLLconst [lc] (MOVBreg x))
16297         // result: (SBFIZ [armBFAuxInt(lc, min(8, 64-lc))] x)
16298         for {
16299                 lc := auxIntToInt64(v.AuxInt)
16300                 if v_0.Op != OpARM64MOVBreg {
16301                         break
16302                 }
16303                 x := v_0.Args[0]
16304                 v.reset(OpARM64SBFIZ)
16305                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, min(8, 64-lc)))
16306                 v.AddArg(x)
16307                 return true
16308         }
16309         // match: (SLLconst [lc] (MOVWUreg x))
16310         // result: (UBFIZ [armBFAuxInt(lc, min(32, 64-lc))] x)
16311         for {
16312                 lc := auxIntToInt64(v.AuxInt)
16313                 if v_0.Op != OpARM64MOVWUreg {
16314                         break
16315                 }
16316                 x := v_0.Args[0]
16317                 v.reset(OpARM64UBFIZ)
16318                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, min(32, 64-lc)))
16319                 v.AddArg(x)
16320                 return true
16321         }
16322         // match: (SLLconst [lc] (MOVHUreg x))
16323         // result: (UBFIZ [armBFAuxInt(lc, min(16, 64-lc))] x)
16324         for {
16325                 lc := auxIntToInt64(v.AuxInt)
16326                 if v_0.Op != OpARM64MOVHUreg {
16327                         break
16328                 }
16329                 x := v_0.Args[0]
16330                 v.reset(OpARM64UBFIZ)
16331                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, min(16, 64-lc)))
16332                 v.AddArg(x)
16333                 return true
16334         }
16335         // match: (SLLconst [lc] (MOVBUreg x))
16336         // result: (UBFIZ [armBFAuxInt(lc, min(8, 64-lc))] x)
16337         for {
16338                 lc := auxIntToInt64(v.AuxInt)
16339                 if v_0.Op != OpARM64MOVBUreg {
16340                         break
16341                 }
16342                 x := v_0.Args[0]
16343                 v.reset(OpARM64UBFIZ)
16344                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, min(8, 64-lc)))
16345                 v.AddArg(x)
16346                 return true
16347         }
16348         // match: (SLLconst [sc] (ANDconst [ac] x))
16349         // cond: isARM64BFMask(sc, ac, 0)
16350         // result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
16351         for {
16352                 sc := auxIntToInt64(v.AuxInt)
16353                 if v_0.Op != OpARM64ANDconst {
16354                         break
16355                 }
16356                 ac := auxIntToInt64(v_0.AuxInt)
16357                 x := v_0.Args[0]
16358                 if !(isARM64BFMask(sc, ac, 0)) {
16359                         break
16360                 }
16361                 v.reset(OpARM64UBFIZ)
16362                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc, arm64BFWidth(ac, 0)))
16363                 v.AddArg(x)
16364                 return true
16365         }
16366         // match: (SLLconst [sc] (UBFIZ [bfc] x))
16367         // cond: sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
16368         // result: (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
16369         for {
16370                 sc := auxIntToInt64(v.AuxInt)
16371                 if v_0.Op != OpARM64UBFIZ {
16372                         break
16373                 }
16374                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16375                 x := v_0.Args[0]
16376                 if !(sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64) {
16377                         break
16378                 }
16379                 v.reset(OpARM64UBFIZ)
16380                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()))
16381                 v.AddArg(x)
16382                 return true
16383         }
16384         return false
16385 }
16386 func rewriteValueARM64_OpARM64SRA(v *Value) bool {
16387         v_1 := v.Args[1]
16388         v_0 := v.Args[0]
16389         // match: (SRA x (MOVDconst [c]))
16390         // result: (SRAconst x [c&63])
16391         for {
16392                 x := v_0
16393                 if v_1.Op != OpARM64MOVDconst {
16394                         break
16395                 }
16396                 c := auxIntToInt64(v_1.AuxInt)
16397                 v.reset(OpARM64SRAconst)
16398                 v.AuxInt = int64ToAuxInt(c & 63)
16399                 v.AddArg(x)
16400                 return true
16401         }
16402         // match: (SRA x (ANDconst [63] y))
16403         // result: (SRA x y)
16404         for {
16405                 x := v_0
16406                 if v_1.Op != OpARM64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 {
16407                         break
16408                 }
16409                 y := v_1.Args[0]
16410                 v.reset(OpARM64SRA)
16411                 v.AddArg2(x, y)
16412                 return true
16413         }
16414         return false
16415 }
16416 func rewriteValueARM64_OpARM64SRAconst(v *Value) bool {
16417         v_0 := v.Args[0]
16418         // match: (SRAconst [c] (MOVDconst [d]))
16419         // result: (MOVDconst [d>>uint64(c)])
16420         for {
16421                 c := auxIntToInt64(v.AuxInt)
16422                 if v_0.Op != OpARM64MOVDconst {
16423                         break
16424                 }
16425                 d := auxIntToInt64(v_0.AuxInt)
16426                 v.reset(OpARM64MOVDconst)
16427                 v.AuxInt = int64ToAuxInt(d >> uint64(c))
16428                 return true
16429         }
16430         // match: (SRAconst [rc] (SLLconst [lc] x))
16431         // cond: lc > rc
16432         // result: (SBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
16433         for {
16434                 rc := auxIntToInt64(v.AuxInt)
16435                 if v_0.Op != OpARM64SLLconst {
16436                         break
16437                 }
16438                 lc := auxIntToInt64(v_0.AuxInt)
16439                 x := v_0.Args[0]
16440                 if !(lc > rc) {
16441                         break
16442                 }
16443                 v.reset(OpARM64SBFIZ)
16444                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc-rc, 64-lc))
16445                 v.AddArg(x)
16446                 return true
16447         }
16448         // match: (SRAconst [rc] (SLLconst [lc] x))
16449         // cond: lc <= rc
16450         // result: (SBFX [armBFAuxInt(rc-lc, 64-rc)] x)
16451         for {
16452                 rc := auxIntToInt64(v.AuxInt)
16453                 if v_0.Op != OpARM64SLLconst {
16454                         break
16455                 }
16456                 lc := auxIntToInt64(v_0.AuxInt)
16457                 x := v_0.Args[0]
16458                 if !(lc <= rc) {
16459                         break
16460                 }
16461                 v.reset(OpARM64SBFX)
16462                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc-lc, 64-rc))
16463                 v.AddArg(x)
16464                 return true
16465         }
16466         // match: (SRAconst [rc] (MOVWreg x))
16467         // cond: rc < 32
16468         // result: (SBFX [armBFAuxInt(rc, 32-rc)] x)
16469         for {
16470                 rc := auxIntToInt64(v.AuxInt)
16471                 if v_0.Op != OpARM64MOVWreg {
16472                         break
16473                 }
16474                 x := v_0.Args[0]
16475                 if !(rc < 32) {
16476                         break
16477                 }
16478                 v.reset(OpARM64SBFX)
16479                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 32-rc))
16480                 v.AddArg(x)
16481                 return true
16482         }
16483         // match: (SRAconst [rc] (MOVHreg x))
16484         // cond: rc < 16
16485         // result: (SBFX [armBFAuxInt(rc, 16-rc)] x)
16486         for {
16487                 rc := auxIntToInt64(v.AuxInt)
16488                 if v_0.Op != OpARM64MOVHreg {
16489                         break
16490                 }
16491                 x := v_0.Args[0]
16492                 if !(rc < 16) {
16493                         break
16494                 }
16495                 v.reset(OpARM64SBFX)
16496                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 16-rc))
16497                 v.AddArg(x)
16498                 return true
16499         }
16500         // match: (SRAconst [rc] (MOVBreg x))
16501         // cond: rc < 8
16502         // result: (SBFX [armBFAuxInt(rc, 8-rc)] x)
16503         for {
16504                 rc := auxIntToInt64(v.AuxInt)
16505                 if v_0.Op != OpARM64MOVBreg {
16506                         break
16507                 }
16508                 x := v_0.Args[0]
16509                 if !(rc < 8) {
16510                         break
16511                 }
16512                 v.reset(OpARM64SBFX)
16513                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 8-rc))
16514                 v.AddArg(x)
16515                 return true
16516         }
16517         // match: (SRAconst [sc] (SBFIZ [bfc] x))
16518         // cond: sc < bfc.getARM64BFlsb()
16519         // result: (SBFIZ [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
16520         for {
16521                 sc := auxIntToInt64(v.AuxInt)
16522                 if v_0.Op != OpARM64SBFIZ {
16523                         break
16524                 }
16525                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16526                 x := v_0.Args[0]
16527                 if !(sc < bfc.getARM64BFlsb()) {
16528                         break
16529                 }
16530                 v.reset(OpARM64SBFIZ)
16531                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth()))
16532                 v.AddArg(x)
16533                 return true
16534         }
16535         // match: (SRAconst [sc] (SBFIZ [bfc] x))
16536         // cond: sc >= bfc.getARM64BFlsb() && sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
16537         // result: (SBFX [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
16538         for {
16539                 sc := auxIntToInt64(v.AuxInt)
16540                 if v_0.Op != OpARM64SBFIZ {
16541                         break
16542                 }
16543                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16544                 x := v_0.Args[0]
16545                 if !(sc >= bfc.getARM64BFlsb() && sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()) {
16546                         break
16547                 }
16548                 v.reset(OpARM64SBFX)
16549                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc))
16550                 v.AddArg(x)
16551                 return true
16552         }
16553         return false
16554 }
16555 func rewriteValueARM64_OpARM64SRL(v *Value) bool {
16556         v_1 := v.Args[1]
16557         v_0 := v.Args[0]
16558         // match: (SRL x (MOVDconst [c]))
16559         // result: (SRLconst x [c&63])
16560         for {
16561                 x := v_0
16562                 if v_1.Op != OpARM64MOVDconst {
16563                         break
16564                 }
16565                 c := auxIntToInt64(v_1.AuxInt)
16566                 v.reset(OpARM64SRLconst)
16567                 v.AuxInt = int64ToAuxInt(c & 63)
16568                 v.AddArg(x)
16569                 return true
16570         }
16571         // match: (SRL x (ANDconst [63] y))
16572         // result: (SRL x y)
16573         for {
16574                 x := v_0
16575                 if v_1.Op != OpARM64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 {
16576                         break
16577                 }
16578                 y := v_1.Args[0]
16579                 v.reset(OpARM64SRL)
16580                 v.AddArg2(x, y)
16581                 return true
16582         }
16583         return false
16584 }
16585 func rewriteValueARM64_OpARM64SRLconst(v *Value) bool {
16586         v_0 := v.Args[0]
16587         // match: (SRLconst [c] (MOVDconst [d]))
16588         // result: (MOVDconst [int64(uint64(d)>>uint64(c))])
16589         for {
16590                 c := auxIntToInt64(v.AuxInt)
16591                 if v_0.Op != OpARM64MOVDconst {
16592                         break
16593                 }
16594                 d := auxIntToInt64(v_0.AuxInt)
16595                 v.reset(OpARM64MOVDconst)
16596                 v.AuxInt = int64ToAuxInt(int64(uint64(d) >> uint64(c)))
16597                 return true
16598         }
16599         // match: (SRLconst [c] (SLLconst [c] x))
16600         // cond: 0 < c && c < 64
16601         // result: (ANDconst [1<<uint(64-c)-1] x)
16602         for {
16603                 c := auxIntToInt64(v.AuxInt)
16604                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
16605                         break
16606                 }
16607                 x := v_0.Args[0]
16608                 if !(0 < c && c < 64) {
16609                         break
16610                 }
16611                 v.reset(OpARM64ANDconst)
16612                 v.AuxInt = int64ToAuxInt(1<<uint(64-c) - 1)
16613                 v.AddArg(x)
16614                 return true
16615         }
16616         // match: (SRLconst [rc] (MOVWUreg x))
16617         // cond: rc >= 32
16618         // result: (MOVDconst [0])
16619         for {
16620                 rc := auxIntToInt64(v.AuxInt)
16621                 if v_0.Op != OpARM64MOVWUreg {
16622                         break
16623                 }
16624                 if !(rc >= 32) {
16625                         break
16626                 }
16627                 v.reset(OpARM64MOVDconst)
16628                 v.AuxInt = int64ToAuxInt(0)
16629                 return true
16630         }
16631         // match: (SRLconst [rc] (MOVHUreg x))
16632         // cond: rc >= 16
16633         // result: (MOVDconst [0])
16634         for {
16635                 rc := auxIntToInt64(v.AuxInt)
16636                 if v_0.Op != OpARM64MOVHUreg {
16637                         break
16638                 }
16639                 if !(rc >= 16) {
16640                         break
16641                 }
16642                 v.reset(OpARM64MOVDconst)
16643                 v.AuxInt = int64ToAuxInt(0)
16644                 return true
16645         }
16646         // match: (SRLconst [rc] (MOVBUreg x))
16647         // cond: rc >= 8
16648         // result: (MOVDconst [0])
16649         for {
16650                 rc := auxIntToInt64(v.AuxInt)
16651                 if v_0.Op != OpARM64MOVBUreg {
16652                         break
16653                 }
16654                 if !(rc >= 8) {
16655                         break
16656                 }
16657                 v.reset(OpARM64MOVDconst)
16658                 v.AuxInt = int64ToAuxInt(0)
16659                 return true
16660         }
16661         // match: (SRLconst [rc] (SLLconst [lc] x))
16662         // cond: lc > rc
16663         // result: (UBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
16664         for {
16665                 rc := auxIntToInt64(v.AuxInt)
16666                 if v_0.Op != OpARM64SLLconst {
16667                         break
16668                 }
16669                 lc := auxIntToInt64(v_0.AuxInt)
16670                 x := v_0.Args[0]
16671                 if !(lc > rc) {
16672                         break
16673                 }
16674                 v.reset(OpARM64UBFIZ)
16675                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc-rc, 64-lc))
16676                 v.AddArg(x)
16677                 return true
16678         }
16679         // match: (SRLconst [rc] (SLLconst [lc] x))
16680         // cond: lc < rc
16681         // result: (UBFX [armBFAuxInt(rc-lc, 64-rc)] x)
16682         for {
16683                 rc := auxIntToInt64(v.AuxInt)
16684                 if v_0.Op != OpARM64SLLconst {
16685                         break
16686                 }
16687                 lc := auxIntToInt64(v_0.AuxInt)
16688                 x := v_0.Args[0]
16689                 if !(lc < rc) {
16690                         break
16691                 }
16692                 v.reset(OpARM64UBFX)
16693                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc-lc, 64-rc))
16694                 v.AddArg(x)
16695                 return true
16696         }
16697         // match: (SRLconst [rc] (MOVWUreg x))
16698         // cond: rc < 32
16699         // result: (UBFX [armBFAuxInt(rc, 32-rc)] x)
16700         for {
16701                 rc := auxIntToInt64(v.AuxInt)
16702                 if v_0.Op != OpARM64MOVWUreg {
16703                         break
16704                 }
16705                 x := v_0.Args[0]
16706                 if !(rc < 32) {
16707                         break
16708                 }
16709                 v.reset(OpARM64UBFX)
16710                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 32-rc))
16711                 v.AddArg(x)
16712                 return true
16713         }
16714         // match: (SRLconst [rc] (MOVHUreg x))
16715         // cond: rc < 16
16716         // result: (UBFX [armBFAuxInt(rc, 16-rc)] x)
16717         for {
16718                 rc := auxIntToInt64(v.AuxInt)
16719                 if v_0.Op != OpARM64MOVHUreg {
16720                         break
16721                 }
16722                 x := v_0.Args[0]
16723                 if !(rc < 16) {
16724                         break
16725                 }
16726                 v.reset(OpARM64UBFX)
16727                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 16-rc))
16728                 v.AddArg(x)
16729                 return true
16730         }
16731         // match: (SRLconst [rc] (MOVBUreg x))
16732         // cond: rc < 8
16733         // result: (UBFX [armBFAuxInt(rc, 8-rc)] x)
16734         for {
16735                 rc := auxIntToInt64(v.AuxInt)
16736                 if v_0.Op != OpARM64MOVBUreg {
16737                         break
16738                 }
16739                 x := v_0.Args[0]
16740                 if !(rc < 8) {
16741                         break
16742                 }
16743                 v.reset(OpARM64UBFX)
16744                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 8-rc))
16745                 v.AddArg(x)
16746                 return true
16747         }
16748         // match: (SRLconst [sc] (ANDconst [ac] x))
16749         // cond: isARM64BFMask(sc, ac, sc)
16750         // result: (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
16751         for {
16752                 sc := auxIntToInt64(v.AuxInt)
16753                 if v_0.Op != OpARM64ANDconst {
16754                         break
16755                 }
16756                 ac := auxIntToInt64(v_0.AuxInt)
16757                 x := v_0.Args[0]
16758                 if !(isARM64BFMask(sc, ac, sc)) {
16759                         break
16760                 }
16761                 v.reset(OpARM64UBFX)
16762                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc, arm64BFWidth(ac, sc)))
16763                 v.AddArg(x)
16764                 return true
16765         }
16766         // match: (SRLconst [sc] (UBFX [bfc] x))
16767         // cond: sc < bfc.getARM64BFwidth()
16768         // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
16769         for {
16770                 sc := auxIntToInt64(v.AuxInt)
16771                 if v_0.Op != OpARM64UBFX {
16772                         break
16773                 }
16774                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16775                 x := v_0.Args[0]
16776                 if !(sc < bfc.getARM64BFwidth()) {
16777                         break
16778                 }
16779                 v.reset(OpARM64UBFX)
16780                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc))
16781                 v.AddArg(x)
16782                 return true
16783         }
16784         // match: (SRLconst [sc] (UBFIZ [bfc] x))
16785         // cond: sc == bfc.getARM64BFlsb()
16786         // result: (ANDconst [1<<uint(bfc.getARM64BFwidth())-1] x)
16787         for {
16788                 sc := auxIntToInt64(v.AuxInt)
16789                 if v_0.Op != OpARM64UBFIZ {
16790                         break
16791                 }
16792                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16793                 x := v_0.Args[0]
16794                 if !(sc == bfc.getARM64BFlsb()) {
16795                         break
16796                 }
16797                 v.reset(OpARM64ANDconst)
16798                 v.AuxInt = int64ToAuxInt(1<<uint(bfc.getARM64BFwidth()) - 1)
16799                 v.AddArg(x)
16800                 return true
16801         }
16802         // match: (SRLconst [sc] (UBFIZ [bfc] x))
16803         // cond: sc < bfc.getARM64BFlsb()
16804         // result: (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
16805         for {
16806                 sc := auxIntToInt64(v.AuxInt)
16807                 if v_0.Op != OpARM64UBFIZ {
16808                         break
16809                 }
16810                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16811                 x := v_0.Args[0]
16812                 if !(sc < bfc.getARM64BFlsb()) {
16813                         break
16814                 }
16815                 v.reset(OpARM64UBFIZ)
16816                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth()))
16817                 v.AddArg(x)
16818                 return true
16819         }
16820         // match: (SRLconst [sc] (UBFIZ [bfc] x))
16821         // cond: sc > bfc.getARM64BFlsb() && sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
16822         // result: (UBFX [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
16823         for {
16824                 sc := auxIntToInt64(v.AuxInt)
16825                 if v_0.Op != OpARM64UBFIZ {
16826                         break
16827                 }
16828                 bfc := auxIntToArm64BitField(v_0.AuxInt)
16829                 x := v_0.Args[0]
16830                 if !(sc > bfc.getARM64BFlsb() && sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()) {
16831                         break
16832                 }
16833                 v.reset(OpARM64UBFX)
16834                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc))
16835                 v.AddArg(x)
16836                 return true
16837         }
16838         return false
16839 }
16840 func rewriteValueARM64_OpARM64STP(v *Value) bool {
16841         v_3 := v.Args[3]
16842         v_2 := v.Args[2]
16843         v_1 := v.Args[1]
16844         v_0 := v.Args[0]
16845         b := v.Block
16846         config := b.Func.Config
16847         // match: (STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem)
16848         // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
16849         // result: (STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
16850         for {
16851                 off1 := auxIntToInt32(v.AuxInt)
16852                 sym := auxToSym(v.Aux)
16853                 if v_0.Op != OpARM64ADDconst {
16854                         break
16855                 }
16856                 off2 := auxIntToInt64(v_0.AuxInt)
16857                 ptr := v_0.Args[0]
16858                 val1 := v_1
16859                 val2 := v_2
16860                 mem := v_3
16861                 if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
16862                         break
16863                 }
16864                 v.reset(OpARM64STP)
16865                 v.AuxInt = int32ToAuxInt(off1 + int32(off2))
16866                 v.Aux = symToAux(sym)
16867                 v.AddArg4(ptr, val1, val2, mem)
16868                 return true
16869         }
16870         // match: (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
16871         // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
16872         // result: (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
16873         for {
16874                 off1 := auxIntToInt32(v.AuxInt)
16875                 sym1 := auxToSym(v.Aux)
16876                 if v_0.Op != OpARM64MOVDaddr {
16877                         break
16878                 }
16879                 off2 := auxIntToInt32(v_0.AuxInt)
16880                 sym2 := auxToSym(v_0.Aux)
16881                 ptr := v_0.Args[0]
16882                 val1 := v_1
16883                 val2 := v_2
16884                 mem := v_3
16885                 if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
16886                         break
16887                 }
16888                 v.reset(OpARM64STP)
16889                 v.AuxInt = int32ToAuxInt(off1 + off2)
16890                 v.Aux = symToAux(mergeSym(sym1, sym2))
16891                 v.AddArg4(ptr, val1, val2, mem)
16892                 return true
16893         }
16894         // match: (STP [off] {sym} ptr (MOVDconst [0]) (MOVDconst [0]) mem)
16895         // result: (MOVQstorezero [off] {sym} ptr mem)
16896         for {
16897                 off := auxIntToInt32(v.AuxInt)
16898                 sym := auxToSym(v.Aux)
16899                 ptr := v_0
16900                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 || v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
16901                         break
16902                 }
16903                 mem := v_3
16904                 v.reset(OpARM64MOVQstorezero)
16905                 v.AuxInt = int32ToAuxInt(off)
16906                 v.Aux = symToAux(sym)
16907                 v.AddArg2(ptr, mem)
16908                 return true
16909         }
16910         return false
16911 }
16912 func rewriteValueARM64_OpARM64SUB(v *Value) bool {
16913         v_1 := v.Args[1]
16914         v_0 := v.Args[0]
16915         b := v.Block
16916         // match: (SUB x (MOVDconst [c]))
16917         // result: (SUBconst [c] x)
16918         for {
16919                 x := v_0
16920                 if v_1.Op != OpARM64MOVDconst {
16921                         break
16922                 }
16923                 c := auxIntToInt64(v_1.AuxInt)
16924                 v.reset(OpARM64SUBconst)
16925                 v.AuxInt = int64ToAuxInt(c)
16926                 v.AddArg(x)
16927                 return true
16928         }
16929         // match: (SUB a l:(MUL x y))
16930         // cond: l.Uses==1 && clobber(l)
16931         // result: (MSUB a x y)
16932         for {
16933                 a := v_0
16934                 l := v_1
16935                 if l.Op != OpARM64MUL {
16936                         break
16937                 }
16938                 y := l.Args[1]
16939                 x := l.Args[0]
16940                 if !(l.Uses == 1 && clobber(l)) {
16941                         break
16942                 }
16943                 v.reset(OpARM64MSUB)
16944                 v.AddArg3(a, x, y)
16945                 return true
16946         }
16947         // match: (SUB a l:(MNEG x y))
16948         // cond: l.Uses==1 && clobber(l)
16949         // result: (MADD a x y)
16950         for {
16951                 a := v_0
16952                 l := v_1
16953                 if l.Op != OpARM64MNEG {
16954                         break
16955                 }
16956                 y := l.Args[1]
16957                 x := l.Args[0]
16958                 if !(l.Uses == 1 && clobber(l)) {
16959                         break
16960                 }
16961                 v.reset(OpARM64MADD)
16962                 v.AddArg3(a, x, y)
16963                 return true
16964         }
16965         // match: (SUB a l:(MULW x y))
16966         // cond: v.Type.Size() <= 4 && l.Uses==1 && clobber(l)
16967         // result: (MSUBW a x y)
16968         for {
16969                 a := v_0
16970                 l := v_1
16971                 if l.Op != OpARM64MULW {
16972                         break
16973                 }
16974                 y := l.Args[1]
16975                 x := l.Args[0]
16976                 if !(v.Type.Size() <= 4 && l.Uses == 1 && clobber(l)) {
16977                         break
16978                 }
16979                 v.reset(OpARM64MSUBW)
16980                 v.AddArg3(a, x, y)
16981                 return true
16982         }
16983         // match: (SUB a l:(MNEGW x y))
16984         // cond: v.Type.Size() <= 4 && l.Uses==1 && clobber(l)
16985         // result: (MADDW a x y)
16986         for {
16987                 a := v_0
16988                 l := v_1
16989                 if l.Op != OpARM64MNEGW {
16990                         break
16991                 }
16992                 y := l.Args[1]
16993                 x := l.Args[0]
16994                 if !(v.Type.Size() <= 4 && l.Uses == 1 && clobber(l)) {
16995                         break
16996                 }
16997                 v.reset(OpARM64MADDW)
16998                 v.AddArg3(a, x, y)
16999                 return true
17000         }
17001         // match: (SUB x x)
17002         // result: (MOVDconst [0])
17003         for {
17004                 x := v_0
17005                 if x != v_1 {
17006                         break
17007                 }
17008                 v.reset(OpARM64MOVDconst)
17009                 v.AuxInt = int64ToAuxInt(0)
17010                 return true
17011         }
17012         // match: (SUB x (SUB y z))
17013         // result: (SUB (ADD <v.Type> x z) y)
17014         for {
17015                 x := v_0
17016                 if v_1.Op != OpARM64SUB {
17017                         break
17018                 }
17019                 z := v_1.Args[1]
17020                 y := v_1.Args[0]
17021                 v.reset(OpARM64SUB)
17022                 v0 := b.NewValue0(v.Pos, OpARM64ADD, v.Type)
17023                 v0.AddArg2(x, z)
17024                 v.AddArg2(v0, y)
17025                 return true
17026         }
17027         // match: (SUB (SUB x y) z)
17028         // result: (SUB x (ADD <y.Type> y z))
17029         for {
17030                 if v_0.Op != OpARM64SUB {
17031                         break
17032                 }
17033                 y := v_0.Args[1]
17034                 x := v_0.Args[0]
17035                 z := v_1
17036                 v.reset(OpARM64SUB)
17037                 v0 := b.NewValue0(v.Pos, OpARM64ADD, y.Type)
17038                 v0.AddArg2(y, z)
17039                 v.AddArg2(x, v0)
17040                 return true
17041         }
17042         // match: (SUB x0 x1:(SLLconst [c] y))
17043         // cond: clobberIfDead(x1)
17044         // result: (SUBshiftLL x0 y [c])
17045         for {
17046                 x0 := v_0
17047                 x1 := v_1
17048                 if x1.Op != OpARM64SLLconst {
17049                         break
17050                 }
17051                 c := auxIntToInt64(x1.AuxInt)
17052                 y := x1.Args[0]
17053                 if !(clobberIfDead(x1)) {
17054                         break
17055                 }
17056                 v.reset(OpARM64SUBshiftLL)
17057                 v.AuxInt = int64ToAuxInt(c)
17058                 v.AddArg2(x0, y)
17059                 return true
17060         }
17061         // match: (SUB x0 x1:(SRLconst [c] y))
17062         // cond: clobberIfDead(x1)
17063         // result: (SUBshiftRL x0 y [c])
17064         for {
17065                 x0 := v_0
17066                 x1 := v_1
17067                 if x1.Op != OpARM64SRLconst {
17068                         break
17069                 }
17070                 c := auxIntToInt64(x1.AuxInt)
17071                 y := x1.Args[0]
17072                 if !(clobberIfDead(x1)) {
17073                         break
17074                 }
17075                 v.reset(OpARM64SUBshiftRL)
17076                 v.AuxInt = int64ToAuxInt(c)
17077                 v.AddArg2(x0, y)
17078                 return true
17079         }
17080         // match: (SUB x0 x1:(SRAconst [c] y))
17081         // cond: clobberIfDead(x1)
17082         // result: (SUBshiftRA x0 y [c])
17083         for {
17084                 x0 := v_0
17085                 x1 := v_1
17086                 if x1.Op != OpARM64SRAconst {
17087                         break
17088                 }
17089                 c := auxIntToInt64(x1.AuxInt)
17090                 y := x1.Args[0]
17091                 if !(clobberIfDead(x1)) {
17092                         break
17093                 }
17094                 v.reset(OpARM64SUBshiftRA)
17095                 v.AuxInt = int64ToAuxInt(c)
17096                 v.AddArg2(x0, y)
17097                 return true
17098         }
17099         return false
17100 }
17101 func rewriteValueARM64_OpARM64SUBconst(v *Value) bool {
17102         v_0 := v.Args[0]
17103         // match: (SUBconst [0] x)
17104         // result: x
17105         for {
17106                 if auxIntToInt64(v.AuxInt) != 0 {
17107                         break
17108                 }
17109                 x := v_0
17110                 v.copyOf(x)
17111                 return true
17112         }
17113         // match: (SUBconst [c] (MOVDconst [d]))
17114         // result: (MOVDconst [d-c])
17115         for {
17116                 c := auxIntToInt64(v.AuxInt)
17117                 if v_0.Op != OpARM64MOVDconst {
17118                         break
17119                 }
17120                 d := auxIntToInt64(v_0.AuxInt)
17121                 v.reset(OpARM64MOVDconst)
17122                 v.AuxInt = int64ToAuxInt(d - c)
17123                 return true
17124         }
17125         // match: (SUBconst [c] (SUBconst [d] x))
17126         // result: (ADDconst [-c-d] x)
17127         for {
17128                 c := auxIntToInt64(v.AuxInt)
17129                 if v_0.Op != OpARM64SUBconst {
17130                         break
17131                 }
17132                 d := auxIntToInt64(v_0.AuxInt)
17133                 x := v_0.Args[0]
17134                 v.reset(OpARM64ADDconst)
17135                 v.AuxInt = int64ToAuxInt(-c - d)
17136                 v.AddArg(x)
17137                 return true
17138         }
17139         // match: (SUBconst [c] (ADDconst [d] x))
17140         // result: (ADDconst [-c+d] x)
17141         for {
17142                 c := auxIntToInt64(v.AuxInt)
17143                 if v_0.Op != OpARM64ADDconst {
17144                         break
17145                 }
17146                 d := auxIntToInt64(v_0.AuxInt)
17147                 x := v_0.Args[0]
17148                 v.reset(OpARM64ADDconst)
17149                 v.AuxInt = int64ToAuxInt(-c + d)
17150                 v.AddArg(x)
17151                 return true
17152         }
17153         return false
17154 }
17155 func rewriteValueARM64_OpARM64SUBshiftLL(v *Value) bool {
17156         v_1 := v.Args[1]
17157         v_0 := v.Args[0]
17158         // match: (SUBshiftLL x (MOVDconst [c]) [d])
17159         // result: (SUBconst x [int64(uint64(c)<<uint64(d))])
17160         for {
17161                 d := auxIntToInt64(v.AuxInt)
17162                 x := v_0
17163                 if v_1.Op != OpARM64MOVDconst {
17164                         break
17165                 }
17166                 c := auxIntToInt64(v_1.AuxInt)
17167                 v.reset(OpARM64SUBconst)
17168                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
17169                 v.AddArg(x)
17170                 return true
17171         }
17172         // match: (SUBshiftLL (SLLconst x [c]) x [c])
17173         // result: (MOVDconst [0])
17174         for {
17175                 c := auxIntToInt64(v.AuxInt)
17176                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
17177                         break
17178                 }
17179                 x := v_0.Args[0]
17180                 if x != v_1 {
17181                         break
17182                 }
17183                 v.reset(OpARM64MOVDconst)
17184                 v.AuxInt = int64ToAuxInt(0)
17185                 return true
17186         }
17187         return false
17188 }
17189 func rewriteValueARM64_OpARM64SUBshiftRA(v *Value) bool {
17190         v_1 := v.Args[1]
17191         v_0 := v.Args[0]
17192         // match: (SUBshiftRA x (MOVDconst [c]) [d])
17193         // result: (SUBconst x [c>>uint64(d)])
17194         for {
17195                 d := auxIntToInt64(v.AuxInt)
17196                 x := v_0
17197                 if v_1.Op != OpARM64MOVDconst {
17198                         break
17199                 }
17200                 c := auxIntToInt64(v_1.AuxInt)
17201                 v.reset(OpARM64SUBconst)
17202                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
17203                 v.AddArg(x)
17204                 return true
17205         }
17206         // match: (SUBshiftRA (SRAconst x [c]) x [c])
17207         // result: (MOVDconst [0])
17208         for {
17209                 c := auxIntToInt64(v.AuxInt)
17210                 if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
17211                         break
17212                 }
17213                 x := v_0.Args[0]
17214                 if x != v_1 {
17215                         break
17216                 }
17217                 v.reset(OpARM64MOVDconst)
17218                 v.AuxInt = int64ToAuxInt(0)
17219                 return true
17220         }
17221         return false
17222 }
17223 func rewriteValueARM64_OpARM64SUBshiftRL(v *Value) bool {
17224         v_1 := v.Args[1]
17225         v_0 := v.Args[0]
17226         // match: (SUBshiftRL x (MOVDconst [c]) [d])
17227         // result: (SUBconst x [int64(uint64(c)>>uint64(d))])
17228         for {
17229                 d := auxIntToInt64(v.AuxInt)
17230                 x := v_0
17231                 if v_1.Op != OpARM64MOVDconst {
17232                         break
17233                 }
17234                 c := auxIntToInt64(v_1.AuxInt)
17235                 v.reset(OpARM64SUBconst)
17236                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
17237                 v.AddArg(x)
17238                 return true
17239         }
17240         // match: (SUBshiftRL (SRLconst x [c]) x [c])
17241         // result: (MOVDconst [0])
17242         for {
17243                 c := auxIntToInt64(v.AuxInt)
17244                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
17245                         break
17246                 }
17247                 x := v_0.Args[0]
17248                 if x != v_1 {
17249                         break
17250                 }
17251                 v.reset(OpARM64MOVDconst)
17252                 v.AuxInt = int64ToAuxInt(0)
17253                 return true
17254         }
17255         return false
17256 }
17257 func rewriteValueARM64_OpARM64TST(v *Value) bool {
17258         v_1 := v.Args[1]
17259         v_0 := v.Args[0]
17260         // match: (TST x (MOVDconst [c]))
17261         // result: (TSTconst [c] x)
17262         for {
17263                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17264                         x := v_0
17265                         if v_1.Op != OpARM64MOVDconst {
17266                                 continue
17267                         }
17268                         c := auxIntToInt64(v_1.AuxInt)
17269                         v.reset(OpARM64TSTconst)
17270                         v.AuxInt = int64ToAuxInt(c)
17271                         v.AddArg(x)
17272                         return true
17273                 }
17274                 break
17275         }
17276         // match: (TST x0 x1:(SLLconst [c] y))
17277         // cond: clobberIfDead(x1)
17278         // result: (TSTshiftLL x0 y [c])
17279         for {
17280                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17281                         x0 := v_0
17282                         x1 := v_1
17283                         if x1.Op != OpARM64SLLconst {
17284                                 continue
17285                         }
17286                         c := auxIntToInt64(x1.AuxInt)
17287                         y := x1.Args[0]
17288                         if !(clobberIfDead(x1)) {
17289                                 continue
17290                         }
17291                         v.reset(OpARM64TSTshiftLL)
17292                         v.AuxInt = int64ToAuxInt(c)
17293                         v.AddArg2(x0, y)
17294                         return true
17295                 }
17296                 break
17297         }
17298         // match: (TST x0 x1:(SRLconst [c] y))
17299         // cond: clobberIfDead(x1)
17300         // result: (TSTshiftRL x0 y [c])
17301         for {
17302                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17303                         x0 := v_0
17304                         x1 := v_1
17305                         if x1.Op != OpARM64SRLconst {
17306                                 continue
17307                         }
17308                         c := auxIntToInt64(x1.AuxInt)
17309                         y := x1.Args[0]
17310                         if !(clobberIfDead(x1)) {
17311                                 continue
17312                         }
17313                         v.reset(OpARM64TSTshiftRL)
17314                         v.AuxInt = int64ToAuxInt(c)
17315                         v.AddArg2(x0, y)
17316                         return true
17317                 }
17318                 break
17319         }
17320         // match: (TST x0 x1:(SRAconst [c] y))
17321         // cond: clobberIfDead(x1)
17322         // result: (TSTshiftRA x0 y [c])
17323         for {
17324                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17325                         x0 := v_0
17326                         x1 := v_1
17327                         if x1.Op != OpARM64SRAconst {
17328                                 continue
17329                         }
17330                         c := auxIntToInt64(x1.AuxInt)
17331                         y := x1.Args[0]
17332                         if !(clobberIfDead(x1)) {
17333                                 continue
17334                         }
17335                         v.reset(OpARM64TSTshiftRA)
17336                         v.AuxInt = int64ToAuxInt(c)
17337                         v.AddArg2(x0, y)
17338                         return true
17339                 }
17340                 break
17341         }
17342         // match: (TST x0 x1:(RORconst [c] y))
17343         // cond: clobberIfDead(x1)
17344         // result: (TSTshiftRO x0 y [c])
17345         for {
17346                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17347                         x0 := v_0
17348                         x1 := v_1
17349                         if x1.Op != OpARM64RORconst {
17350                                 continue
17351                         }
17352                         c := auxIntToInt64(x1.AuxInt)
17353                         y := x1.Args[0]
17354                         if !(clobberIfDead(x1)) {
17355                                 continue
17356                         }
17357                         v.reset(OpARM64TSTshiftRO)
17358                         v.AuxInt = int64ToAuxInt(c)
17359                         v.AddArg2(x0, y)
17360                         return true
17361                 }
17362                 break
17363         }
17364         return false
17365 }
17366 func rewriteValueARM64_OpARM64TSTW(v *Value) bool {
17367         v_1 := v.Args[1]
17368         v_0 := v.Args[0]
17369         // match: (TSTW x (MOVDconst [c]))
17370         // result: (TSTWconst [int32(c)] x)
17371         for {
17372                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17373                         x := v_0
17374                         if v_1.Op != OpARM64MOVDconst {
17375                                 continue
17376                         }
17377                         c := auxIntToInt64(v_1.AuxInt)
17378                         v.reset(OpARM64TSTWconst)
17379                         v.AuxInt = int32ToAuxInt(int32(c))
17380                         v.AddArg(x)
17381                         return true
17382                 }
17383                 break
17384         }
17385         return false
17386 }
17387 func rewriteValueARM64_OpARM64TSTWconst(v *Value) bool {
17388         v_0 := v.Args[0]
17389         // match: (TSTWconst (MOVDconst [x]) [y])
17390         // result: (FlagConstant [logicFlags32(int32(x)&y)])
17391         for {
17392                 y := auxIntToInt32(v.AuxInt)
17393                 if v_0.Op != OpARM64MOVDconst {
17394                         break
17395                 }
17396                 x := auxIntToInt64(v_0.AuxInt)
17397                 v.reset(OpARM64FlagConstant)
17398                 v.AuxInt = flagConstantToAuxInt(logicFlags32(int32(x) & y))
17399                 return true
17400         }
17401         return false
17402 }
17403 func rewriteValueARM64_OpARM64TSTconst(v *Value) bool {
17404         v_0 := v.Args[0]
17405         // match: (TSTconst (MOVDconst [x]) [y])
17406         // result: (FlagConstant [logicFlags64(x&y)])
17407         for {
17408                 y := auxIntToInt64(v.AuxInt)
17409                 if v_0.Op != OpARM64MOVDconst {
17410                         break
17411                 }
17412                 x := auxIntToInt64(v_0.AuxInt)
17413                 v.reset(OpARM64FlagConstant)
17414                 v.AuxInt = flagConstantToAuxInt(logicFlags64(x & y))
17415                 return true
17416         }
17417         return false
17418 }
17419 func rewriteValueARM64_OpARM64TSTshiftLL(v *Value) bool {
17420         v_1 := v.Args[1]
17421         v_0 := v.Args[0]
17422         b := v.Block
17423         // match: (TSTshiftLL (MOVDconst [c]) x [d])
17424         // result: (TSTconst [c] (SLLconst <x.Type> x [d]))
17425         for {
17426                 d := auxIntToInt64(v.AuxInt)
17427                 if v_0.Op != OpARM64MOVDconst {
17428                         break
17429                 }
17430                 c := auxIntToInt64(v_0.AuxInt)
17431                 x := v_1
17432                 v.reset(OpARM64TSTconst)
17433                 v.AuxInt = int64ToAuxInt(c)
17434                 v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
17435                 v0.AuxInt = int64ToAuxInt(d)
17436                 v0.AddArg(x)
17437                 v.AddArg(v0)
17438                 return true
17439         }
17440         // match: (TSTshiftLL x (MOVDconst [c]) [d])
17441         // result: (TSTconst x [int64(uint64(c)<<uint64(d))])
17442         for {
17443                 d := auxIntToInt64(v.AuxInt)
17444                 x := v_0
17445                 if v_1.Op != OpARM64MOVDconst {
17446                         break
17447                 }
17448                 c := auxIntToInt64(v_1.AuxInt)
17449                 v.reset(OpARM64TSTconst)
17450                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
17451                 v.AddArg(x)
17452                 return true
17453         }
17454         return false
17455 }
17456 func rewriteValueARM64_OpARM64TSTshiftRA(v *Value) bool {
17457         v_1 := v.Args[1]
17458         v_0 := v.Args[0]
17459         b := v.Block
17460         // match: (TSTshiftRA (MOVDconst [c]) x [d])
17461         // result: (TSTconst [c] (SRAconst <x.Type> x [d]))
17462         for {
17463                 d := auxIntToInt64(v.AuxInt)
17464                 if v_0.Op != OpARM64MOVDconst {
17465                         break
17466                 }
17467                 c := auxIntToInt64(v_0.AuxInt)
17468                 x := v_1
17469                 v.reset(OpARM64TSTconst)
17470                 v.AuxInt = int64ToAuxInt(c)
17471                 v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
17472                 v0.AuxInt = int64ToAuxInt(d)
17473                 v0.AddArg(x)
17474                 v.AddArg(v0)
17475                 return true
17476         }
17477         // match: (TSTshiftRA x (MOVDconst [c]) [d])
17478         // result: (TSTconst x [c>>uint64(d)])
17479         for {
17480                 d := auxIntToInt64(v.AuxInt)
17481                 x := v_0
17482                 if v_1.Op != OpARM64MOVDconst {
17483                         break
17484                 }
17485                 c := auxIntToInt64(v_1.AuxInt)
17486                 v.reset(OpARM64TSTconst)
17487                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
17488                 v.AddArg(x)
17489                 return true
17490         }
17491         return false
17492 }
17493 func rewriteValueARM64_OpARM64TSTshiftRL(v *Value) bool {
17494         v_1 := v.Args[1]
17495         v_0 := v.Args[0]
17496         b := v.Block
17497         // match: (TSTshiftRL (MOVDconst [c]) x [d])
17498         // result: (TSTconst [c] (SRLconst <x.Type> x [d]))
17499         for {
17500                 d := auxIntToInt64(v.AuxInt)
17501                 if v_0.Op != OpARM64MOVDconst {
17502                         break
17503                 }
17504                 c := auxIntToInt64(v_0.AuxInt)
17505                 x := v_1
17506                 v.reset(OpARM64TSTconst)
17507                 v.AuxInt = int64ToAuxInt(c)
17508                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
17509                 v0.AuxInt = int64ToAuxInt(d)
17510                 v0.AddArg(x)
17511                 v.AddArg(v0)
17512                 return true
17513         }
17514         // match: (TSTshiftRL x (MOVDconst [c]) [d])
17515         // result: (TSTconst x [int64(uint64(c)>>uint64(d))])
17516         for {
17517                 d := auxIntToInt64(v.AuxInt)
17518                 x := v_0
17519                 if v_1.Op != OpARM64MOVDconst {
17520                         break
17521                 }
17522                 c := auxIntToInt64(v_1.AuxInt)
17523                 v.reset(OpARM64TSTconst)
17524                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
17525                 v.AddArg(x)
17526                 return true
17527         }
17528         return false
17529 }
17530 func rewriteValueARM64_OpARM64TSTshiftRO(v *Value) bool {
17531         v_1 := v.Args[1]
17532         v_0 := v.Args[0]
17533         b := v.Block
17534         // match: (TSTshiftRO (MOVDconst [c]) x [d])
17535         // result: (TSTconst [c] (RORconst <x.Type> x [d]))
17536         for {
17537                 d := auxIntToInt64(v.AuxInt)
17538                 if v_0.Op != OpARM64MOVDconst {
17539                         break
17540                 }
17541                 c := auxIntToInt64(v_0.AuxInt)
17542                 x := v_1
17543                 v.reset(OpARM64TSTconst)
17544                 v.AuxInt = int64ToAuxInt(c)
17545                 v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
17546                 v0.AuxInt = int64ToAuxInt(d)
17547                 v0.AddArg(x)
17548                 v.AddArg(v0)
17549                 return true
17550         }
17551         // match: (TSTshiftRO x (MOVDconst [c]) [d])
17552         // result: (TSTconst x [rotateRight64(c, d)])
17553         for {
17554                 d := auxIntToInt64(v.AuxInt)
17555                 x := v_0
17556                 if v_1.Op != OpARM64MOVDconst {
17557                         break
17558                 }
17559                 c := auxIntToInt64(v_1.AuxInt)
17560                 v.reset(OpARM64TSTconst)
17561                 v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
17562                 v.AddArg(x)
17563                 return true
17564         }
17565         return false
17566 }
17567 func rewriteValueARM64_OpARM64UBFIZ(v *Value) bool {
17568         v_0 := v.Args[0]
17569         // match: (UBFIZ [bfc] (SLLconst [sc] x))
17570         // cond: sc < bfc.getARM64BFwidth()
17571         // result: (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
17572         for {
17573                 bfc := auxIntToArm64BitField(v.AuxInt)
17574                 if v_0.Op != OpARM64SLLconst {
17575                         break
17576                 }
17577                 sc := auxIntToInt64(v_0.AuxInt)
17578                 x := v_0.Args[0]
17579                 if !(sc < bfc.getARM64BFwidth()) {
17580                         break
17581                 }
17582                 v.reset(OpARM64UBFIZ)
17583                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc))
17584                 v.AddArg(x)
17585                 return true
17586         }
17587         return false
17588 }
17589 func rewriteValueARM64_OpARM64UBFX(v *Value) bool {
17590         v_0 := v.Args[0]
17591         // match: (UBFX [bfc] (ANDconst [c] x))
17592         // cond: isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0)
17593         // result: (UBFX [bfc] x)
17594         for {
17595                 bfc := auxIntToArm64BitField(v.AuxInt)
17596                 if v_0.Op != OpARM64ANDconst {
17597                         break
17598                 }
17599                 c := auxIntToInt64(v_0.AuxInt)
17600                 x := v_0.Args[0]
17601                 if !(isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb()+bfc.getARM64BFwidth() <= arm64BFWidth(c, 0)) {
17602                         break
17603                 }
17604                 v.reset(OpARM64UBFX)
17605                 v.AuxInt = arm64BitFieldToAuxInt(bfc)
17606                 v.AddArg(x)
17607                 return true
17608         }
17609         // match: (UBFX [bfc] (SRLconst [sc] x))
17610         // cond: sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
17611         // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
17612         for {
17613                 bfc := auxIntToArm64BitField(v.AuxInt)
17614                 if v_0.Op != OpARM64SRLconst {
17615                         break
17616                 }
17617                 sc := auxIntToInt64(v_0.AuxInt)
17618                 x := v_0.Args[0]
17619                 if !(sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64) {
17620                         break
17621                 }
17622                 v.reset(OpARM64UBFX)
17623                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()))
17624                 v.AddArg(x)
17625                 return true
17626         }
17627         // match: (UBFX [bfc] (SLLconst [sc] x))
17628         // cond: sc == bfc.getARM64BFlsb()
17629         // result: (ANDconst [1<<uint(bfc.getARM64BFwidth())-1] x)
17630         for {
17631                 bfc := auxIntToArm64BitField(v.AuxInt)
17632                 if v_0.Op != OpARM64SLLconst {
17633                         break
17634                 }
17635                 sc := auxIntToInt64(v_0.AuxInt)
17636                 x := v_0.Args[0]
17637                 if !(sc == bfc.getARM64BFlsb()) {
17638                         break
17639                 }
17640                 v.reset(OpARM64ANDconst)
17641                 v.AuxInt = int64ToAuxInt(1<<uint(bfc.getARM64BFwidth()) - 1)
17642                 v.AddArg(x)
17643                 return true
17644         }
17645         // match: (UBFX [bfc] (SLLconst [sc] x))
17646         // cond: sc < bfc.getARM64BFlsb()
17647         // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
17648         for {
17649                 bfc := auxIntToArm64BitField(v.AuxInt)
17650                 if v_0.Op != OpARM64SLLconst {
17651                         break
17652                 }
17653                 sc := auxIntToInt64(v_0.AuxInt)
17654                 x := v_0.Args[0]
17655                 if !(sc < bfc.getARM64BFlsb()) {
17656                         break
17657                 }
17658                 v.reset(OpARM64UBFX)
17659                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth()))
17660                 v.AddArg(x)
17661                 return true
17662         }
17663         // match: (UBFX [bfc] (SLLconst [sc] x))
17664         // cond: sc > bfc.getARM64BFlsb() && sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
17665         // result: (UBFIZ [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
17666         for {
17667                 bfc := auxIntToArm64BitField(v.AuxInt)
17668                 if v_0.Op != OpARM64SLLconst {
17669                         break
17670                 }
17671                 sc := auxIntToInt64(v_0.AuxInt)
17672                 x := v_0.Args[0]
17673                 if !(sc > bfc.getARM64BFlsb() && sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()) {
17674                         break
17675                 }
17676                 v.reset(OpARM64UBFIZ)
17677                 v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc))
17678                 v.AddArg(x)
17679                 return true
17680         }
17681         return false
17682 }
17683 func rewriteValueARM64_OpARM64UDIV(v *Value) bool {
17684         v_1 := v.Args[1]
17685         v_0 := v.Args[0]
17686         // match: (UDIV x (MOVDconst [1]))
17687         // result: x
17688         for {
17689                 x := v_0
17690                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
17691                         break
17692                 }
17693                 v.copyOf(x)
17694                 return true
17695         }
17696         // match: (UDIV x (MOVDconst [c]))
17697         // cond: isPowerOfTwo64(c)
17698         // result: (SRLconst [log64(c)] x)
17699         for {
17700                 x := v_0
17701                 if v_1.Op != OpARM64MOVDconst {
17702                         break
17703                 }
17704                 c := auxIntToInt64(v_1.AuxInt)
17705                 if !(isPowerOfTwo64(c)) {
17706                         break
17707                 }
17708                 v.reset(OpARM64SRLconst)
17709                 v.AuxInt = int64ToAuxInt(log64(c))
17710                 v.AddArg(x)
17711                 return true
17712         }
17713         // match: (UDIV (MOVDconst [c]) (MOVDconst [d]))
17714         // cond: d != 0
17715         // result: (MOVDconst [int64(uint64(c)/uint64(d))])
17716         for {
17717                 if v_0.Op != OpARM64MOVDconst {
17718                         break
17719                 }
17720                 c := auxIntToInt64(v_0.AuxInt)
17721                 if v_1.Op != OpARM64MOVDconst {
17722                         break
17723                 }
17724                 d := auxIntToInt64(v_1.AuxInt)
17725                 if !(d != 0) {
17726                         break
17727                 }
17728                 v.reset(OpARM64MOVDconst)
17729                 v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d)))
17730                 return true
17731         }
17732         return false
17733 }
17734 func rewriteValueARM64_OpARM64UDIVW(v *Value) bool {
17735         v_1 := v.Args[1]
17736         v_0 := v.Args[0]
17737         b := v.Block
17738         // match: (UDIVW x (MOVDconst [c]))
17739         // cond: uint32(c)==1
17740         // result: (MOVWUreg x)
17741         for {
17742                 x := v_0
17743                 if v_1.Op != OpARM64MOVDconst {
17744                         break
17745                 }
17746                 c := auxIntToInt64(v_1.AuxInt)
17747                 if !(uint32(c) == 1) {
17748                         break
17749                 }
17750                 v.reset(OpARM64MOVWUreg)
17751                 v.AddArg(x)
17752                 return true
17753         }
17754         // match: (UDIVW x (MOVDconst [c]))
17755         // cond: isPowerOfTwo64(c) && is32Bit(c)
17756         // result: (SRLconst [log64(c)] (MOVWUreg <v.Type> x))
17757         for {
17758                 x := v_0
17759                 if v_1.Op != OpARM64MOVDconst {
17760                         break
17761                 }
17762                 c := auxIntToInt64(v_1.AuxInt)
17763                 if !(isPowerOfTwo64(c) && is32Bit(c)) {
17764                         break
17765                 }
17766                 v.reset(OpARM64SRLconst)
17767                 v.AuxInt = int64ToAuxInt(log64(c))
17768                 v0 := b.NewValue0(v.Pos, OpARM64MOVWUreg, v.Type)
17769                 v0.AddArg(x)
17770                 v.AddArg(v0)
17771                 return true
17772         }
17773         // match: (UDIVW (MOVDconst [c]) (MOVDconst [d]))
17774         // cond: d != 0
17775         // result: (MOVDconst [int64(uint32(c)/uint32(d))])
17776         for {
17777                 if v_0.Op != OpARM64MOVDconst {
17778                         break
17779                 }
17780                 c := auxIntToInt64(v_0.AuxInt)
17781                 if v_1.Op != OpARM64MOVDconst {
17782                         break
17783                 }
17784                 d := auxIntToInt64(v_1.AuxInt)
17785                 if !(d != 0) {
17786                         break
17787                 }
17788                 v.reset(OpARM64MOVDconst)
17789                 v.AuxInt = int64ToAuxInt(int64(uint32(c) / uint32(d)))
17790                 return true
17791         }
17792         return false
17793 }
17794 func rewriteValueARM64_OpARM64UMOD(v *Value) bool {
17795         v_1 := v.Args[1]
17796         v_0 := v.Args[0]
17797         b := v.Block
17798         typ := &b.Func.Config.Types
17799         // match: (UMOD <typ.UInt64> x y)
17800         // result: (MSUB <typ.UInt64> x y (UDIV <typ.UInt64> x y))
17801         for {
17802                 if v.Type != typ.UInt64 {
17803                         break
17804                 }
17805                 x := v_0
17806                 y := v_1
17807                 v.reset(OpARM64MSUB)
17808                 v.Type = typ.UInt64
17809                 v0 := b.NewValue0(v.Pos, OpARM64UDIV, typ.UInt64)
17810                 v0.AddArg2(x, y)
17811                 v.AddArg3(x, y, v0)
17812                 return true
17813         }
17814         // match: (UMOD _ (MOVDconst [1]))
17815         // result: (MOVDconst [0])
17816         for {
17817                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
17818                         break
17819                 }
17820                 v.reset(OpARM64MOVDconst)
17821                 v.AuxInt = int64ToAuxInt(0)
17822                 return true
17823         }
17824         // match: (UMOD x (MOVDconst [c]))
17825         // cond: isPowerOfTwo64(c)
17826         // result: (ANDconst [c-1] x)
17827         for {
17828                 x := v_0
17829                 if v_1.Op != OpARM64MOVDconst {
17830                         break
17831                 }
17832                 c := auxIntToInt64(v_1.AuxInt)
17833                 if !(isPowerOfTwo64(c)) {
17834                         break
17835                 }
17836                 v.reset(OpARM64ANDconst)
17837                 v.AuxInt = int64ToAuxInt(c - 1)
17838                 v.AddArg(x)
17839                 return true
17840         }
17841         // match: (UMOD (MOVDconst [c]) (MOVDconst [d]))
17842         // cond: d != 0
17843         // result: (MOVDconst [int64(uint64(c)%uint64(d))])
17844         for {
17845                 if v_0.Op != OpARM64MOVDconst {
17846                         break
17847                 }
17848                 c := auxIntToInt64(v_0.AuxInt)
17849                 if v_1.Op != OpARM64MOVDconst {
17850                         break
17851                 }
17852                 d := auxIntToInt64(v_1.AuxInt)
17853                 if !(d != 0) {
17854                         break
17855                 }
17856                 v.reset(OpARM64MOVDconst)
17857                 v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d)))
17858                 return true
17859         }
17860         return false
17861 }
17862 func rewriteValueARM64_OpARM64UMODW(v *Value) bool {
17863         v_1 := v.Args[1]
17864         v_0 := v.Args[0]
17865         b := v.Block
17866         typ := &b.Func.Config.Types
17867         // match: (UMODW <typ.UInt32> x y)
17868         // result: (MSUBW <typ.UInt32> x y (UDIVW <typ.UInt32> x y))
17869         for {
17870                 if v.Type != typ.UInt32 {
17871                         break
17872                 }
17873                 x := v_0
17874                 y := v_1
17875                 v.reset(OpARM64MSUBW)
17876                 v.Type = typ.UInt32
17877                 v0 := b.NewValue0(v.Pos, OpARM64UDIVW, typ.UInt32)
17878                 v0.AddArg2(x, y)
17879                 v.AddArg3(x, y, v0)
17880                 return true
17881         }
17882         // match: (UMODW _ (MOVDconst [c]))
17883         // cond: uint32(c)==1
17884         // result: (MOVDconst [0])
17885         for {
17886                 if v_1.Op != OpARM64MOVDconst {
17887                         break
17888                 }
17889                 c := auxIntToInt64(v_1.AuxInt)
17890                 if !(uint32(c) == 1) {
17891                         break
17892                 }
17893                 v.reset(OpARM64MOVDconst)
17894                 v.AuxInt = int64ToAuxInt(0)
17895                 return true
17896         }
17897         // match: (UMODW x (MOVDconst [c]))
17898         // cond: isPowerOfTwo64(c) && is32Bit(c)
17899         // result: (ANDconst [c-1] x)
17900         for {
17901                 x := v_0
17902                 if v_1.Op != OpARM64MOVDconst {
17903                         break
17904                 }
17905                 c := auxIntToInt64(v_1.AuxInt)
17906                 if !(isPowerOfTwo64(c) && is32Bit(c)) {
17907                         break
17908                 }
17909                 v.reset(OpARM64ANDconst)
17910                 v.AuxInt = int64ToAuxInt(c - 1)
17911                 v.AddArg(x)
17912                 return true
17913         }
17914         // match: (UMODW (MOVDconst [c]) (MOVDconst [d]))
17915         // cond: d != 0
17916         // result: (MOVDconst [int64(uint32(c)%uint32(d))])
17917         for {
17918                 if v_0.Op != OpARM64MOVDconst {
17919                         break
17920                 }
17921                 c := auxIntToInt64(v_0.AuxInt)
17922                 if v_1.Op != OpARM64MOVDconst {
17923                         break
17924                 }
17925                 d := auxIntToInt64(v_1.AuxInt)
17926                 if !(d != 0) {
17927                         break
17928                 }
17929                 v.reset(OpARM64MOVDconst)
17930                 v.AuxInt = int64ToAuxInt(int64(uint32(c) % uint32(d)))
17931                 return true
17932         }
17933         return false
17934 }
17935 func rewriteValueARM64_OpARM64XOR(v *Value) bool {
17936         v_1 := v.Args[1]
17937         v_0 := v.Args[0]
17938         // match: (XOR x (MOVDconst [c]))
17939         // result: (XORconst [c] x)
17940         for {
17941                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17942                         x := v_0
17943                         if v_1.Op != OpARM64MOVDconst {
17944                                 continue
17945                         }
17946                         c := auxIntToInt64(v_1.AuxInt)
17947                         v.reset(OpARM64XORconst)
17948                         v.AuxInt = int64ToAuxInt(c)
17949                         v.AddArg(x)
17950                         return true
17951                 }
17952                 break
17953         }
17954         // match: (XOR x x)
17955         // result: (MOVDconst [0])
17956         for {
17957                 x := v_0
17958                 if x != v_1 {
17959                         break
17960                 }
17961                 v.reset(OpARM64MOVDconst)
17962                 v.AuxInt = int64ToAuxInt(0)
17963                 return true
17964         }
17965         // match: (XOR x (MVN y))
17966         // result: (EON x y)
17967         for {
17968                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17969                         x := v_0
17970                         if v_1.Op != OpARM64MVN {
17971                                 continue
17972                         }
17973                         y := v_1.Args[0]
17974                         v.reset(OpARM64EON)
17975                         v.AddArg2(x, y)
17976                         return true
17977                 }
17978                 break
17979         }
17980         // match: (XOR x0 x1:(SLLconst [c] y))
17981         // cond: clobberIfDead(x1)
17982         // result: (XORshiftLL x0 y [c])
17983         for {
17984                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
17985                         x0 := v_0
17986                         x1 := v_1
17987                         if x1.Op != OpARM64SLLconst {
17988                                 continue
17989                         }
17990                         c := auxIntToInt64(x1.AuxInt)
17991                         y := x1.Args[0]
17992                         if !(clobberIfDead(x1)) {
17993                                 continue
17994                         }
17995                         v.reset(OpARM64XORshiftLL)
17996                         v.AuxInt = int64ToAuxInt(c)
17997                         v.AddArg2(x0, y)
17998                         return true
17999                 }
18000                 break
18001         }
18002         // match: (XOR x0 x1:(SRLconst [c] y))
18003         // cond: clobberIfDead(x1)
18004         // result: (XORshiftRL x0 y [c])
18005         for {
18006                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
18007                         x0 := v_0
18008                         x1 := v_1
18009                         if x1.Op != OpARM64SRLconst {
18010                                 continue
18011                         }
18012                         c := auxIntToInt64(x1.AuxInt)
18013                         y := x1.Args[0]
18014                         if !(clobberIfDead(x1)) {
18015                                 continue
18016                         }
18017                         v.reset(OpARM64XORshiftRL)
18018                         v.AuxInt = int64ToAuxInt(c)
18019                         v.AddArg2(x0, y)
18020                         return true
18021                 }
18022                 break
18023         }
18024         // match: (XOR x0 x1:(SRAconst [c] y))
18025         // cond: clobberIfDead(x1)
18026         // result: (XORshiftRA x0 y [c])
18027         for {
18028                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
18029                         x0 := v_0
18030                         x1 := v_1
18031                         if x1.Op != OpARM64SRAconst {
18032                                 continue
18033                         }
18034                         c := auxIntToInt64(x1.AuxInt)
18035                         y := x1.Args[0]
18036                         if !(clobberIfDead(x1)) {
18037                                 continue
18038                         }
18039                         v.reset(OpARM64XORshiftRA)
18040                         v.AuxInt = int64ToAuxInt(c)
18041                         v.AddArg2(x0, y)
18042                         return true
18043                 }
18044                 break
18045         }
18046         // match: (XOR x0 x1:(RORconst [c] y))
18047         // cond: clobberIfDead(x1)
18048         // result: (XORshiftRO x0 y [c])
18049         for {
18050                 for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
18051                         x0 := v_0
18052                         x1 := v_1
18053                         if x1.Op != OpARM64RORconst {
18054                                 continue
18055                         }
18056                         c := auxIntToInt64(x1.AuxInt)
18057                         y := x1.Args[0]
18058                         if !(clobberIfDead(x1)) {
18059                                 continue
18060                         }
18061                         v.reset(OpARM64XORshiftRO)
18062                         v.AuxInt = int64ToAuxInt(c)
18063                         v.AddArg2(x0, y)
18064                         return true
18065                 }
18066                 break
18067         }
18068         return false
18069 }
18070 func rewriteValueARM64_OpARM64XORconst(v *Value) bool {
18071         v_0 := v.Args[0]
18072         // match: (XORconst [0] x)
18073         // result: x
18074         for {
18075                 if auxIntToInt64(v.AuxInt) != 0 {
18076                         break
18077                 }
18078                 x := v_0
18079                 v.copyOf(x)
18080                 return true
18081         }
18082         // match: (XORconst [-1] x)
18083         // result: (MVN x)
18084         for {
18085                 if auxIntToInt64(v.AuxInt) != -1 {
18086                         break
18087                 }
18088                 x := v_0
18089                 v.reset(OpARM64MVN)
18090                 v.AddArg(x)
18091                 return true
18092         }
18093         // match: (XORconst [c] (MOVDconst [d]))
18094         // result: (MOVDconst [c^d])
18095         for {
18096                 c := auxIntToInt64(v.AuxInt)
18097                 if v_0.Op != OpARM64MOVDconst {
18098                         break
18099                 }
18100                 d := auxIntToInt64(v_0.AuxInt)
18101                 v.reset(OpARM64MOVDconst)
18102                 v.AuxInt = int64ToAuxInt(c ^ d)
18103                 return true
18104         }
18105         // match: (XORconst [c] (XORconst [d] x))
18106         // result: (XORconst [c^d] x)
18107         for {
18108                 c := auxIntToInt64(v.AuxInt)
18109                 if v_0.Op != OpARM64XORconst {
18110                         break
18111                 }
18112                 d := auxIntToInt64(v_0.AuxInt)
18113                 x := v_0.Args[0]
18114                 v.reset(OpARM64XORconst)
18115                 v.AuxInt = int64ToAuxInt(c ^ d)
18116                 v.AddArg(x)
18117                 return true
18118         }
18119         return false
18120 }
18121 func rewriteValueARM64_OpARM64XORshiftLL(v *Value) bool {
18122         v_1 := v.Args[1]
18123         v_0 := v.Args[0]
18124         b := v.Block
18125         typ := &b.Func.Config.Types
18126         // match: (XORshiftLL (MOVDconst [c]) x [d])
18127         // result: (XORconst [c] (SLLconst <x.Type> x [d]))
18128         for {
18129                 d := auxIntToInt64(v.AuxInt)
18130                 if v_0.Op != OpARM64MOVDconst {
18131                         break
18132                 }
18133                 c := auxIntToInt64(v_0.AuxInt)
18134                 x := v_1
18135                 v.reset(OpARM64XORconst)
18136                 v.AuxInt = int64ToAuxInt(c)
18137                 v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
18138                 v0.AuxInt = int64ToAuxInt(d)
18139                 v0.AddArg(x)
18140                 v.AddArg(v0)
18141                 return true
18142         }
18143         // match: (XORshiftLL x (MOVDconst [c]) [d])
18144         // result: (XORconst x [int64(uint64(c)<<uint64(d))])
18145         for {
18146                 d := auxIntToInt64(v.AuxInt)
18147                 x := v_0
18148                 if v_1.Op != OpARM64MOVDconst {
18149                         break
18150                 }
18151                 c := auxIntToInt64(v_1.AuxInt)
18152                 v.reset(OpARM64XORconst)
18153                 v.AuxInt = int64ToAuxInt(int64(uint64(c) << uint64(d)))
18154                 v.AddArg(x)
18155                 return true
18156         }
18157         // match: (XORshiftLL (SLLconst x [c]) x [c])
18158         // result: (MOVDconst [0])
18159         for {
18160                 c := auxIntToInt64(v.AuxInt)
18161                 if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
18162                         break
18163                 }
18164                 x := v_0.Args[0]
18165                 if x != v_1 {
18166                         break
18167                 }
18168                 v.reset(OpARM64MOVDconst)
18169                 v.AuxInt = int64ToAuxInt(0)
18170                 return true
18171         }
18172         // match: (XORshiftLL <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
18173         // result: (REV16W x)
18174         for {
18175                 if v.Type != typ.UInt16 || auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || v_0.Type != typ.UInt16 || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 8) {
18176                         break
18177                 }
18178                 x := v_0.Args[0]
18179                 if x != v_1 {
18180                         break
18181                 }
18182                 v.reset(OpARM64REV16W)
18183                 v.AddArg(x)
18184                 return true
18185         }
18186         // match: (XORshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
18187         // cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
18188         // result: (REV16W x)
18189         for {
18190                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
18191                         break
18192                 }
18193                 v_0_0 := v_0.Args[0]
18194                 if v_0_0.Op != OpARM64ANDconst {
18195                         break
18196                 }
18197                 c1 := auxIntToInt64(v_0_0.AuxInt)
18198                 x := v_0_0.Args[0]
18199                 if v_1.Op != OpARM64ANDconst {
18200                         break
18201                 }
18202                 c2 := auxIntToInt64(v_1.AuxInt)
18203                 if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
18204                         break
18205                 }
18206                 v.reset(OpARM64REV16W)
18207                 v.AddArg(x)
18208                 return true
18209         }
18210         // match: (XORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
18211         // cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
18212         // result: (REV16 x)
18213         for {
18214                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
18215                         break
18216                 }
18217                 v_0_0 := v_0.Args[0]
18218                 if v_0_0.Op != OpARM64ANDconst {
18219                         break
18220                 }
18221                 c1 := auxIntToInt64(v_0_0.AuxInt)
18222                 x := v_0_0.Args[0]
18223                 if v_1.Op != OpARM64ANDconst {
18224                         break
18225                 }
18226                 c2 := auxIntToInt64(v_1.AuxInt)
18227                 if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
18228                         break
18229                 }
18230                 v.reset(OpARM64REV16)
18231                 v.AddArg(x)
18232                 return true
18233         }
18234         // match: (XORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
18235         // cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
18236         // result: (REV16 (ANDconst <x.Type> [0xffffffff] x))
18237         for {
18238                 if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
18239                         break
18240                 }
18241                 v_0_0 := v_0.Args[0]
18242                 if v_0_0.Op != OpARM64ANDconst {
18243                         break
18244                 }
18245                 c1 := auxIntToInt64(v_0_0.AuxInt)
18246                 x := v_0_0.Args[0]
18247                 if v_1.Op != OpARM64ANDconst {
18248                         break
18249                 }
18250                 c2 := auxIntToInt64(v_1.AuxInt)
18251                 if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
18252                         break
18253                 }
18254                 v.reset(OpARM64REV16)
18255                 v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
18256                 v0.AuxInt = int64ToAuxInt(0xffffffff)
18257                 v0.AddArg(x)
18258                 v.AddArg(v0)
18259                 return true
18260         }
18261         // match: (XORshiftLL [c] (SRLconst x [64-c]) x2)
18262         // result: (EXTRconst [64-c] x2 x)
18263         for {
18264                 c := auxIntToInt64(v.AuxInt)
18265                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
18266                         break
18267                 }
18268                 x := v_0.Args[0]
18269                 x2 := v_1
18270                 v.reset(OpARM64EXTRconst)
18271                 v.AuxInt = int64ToAuxInt(64 - c)
18272                 v.AddArg2(x2, x)
18273                 return true
18274         }
18275         // match: (XORshiftLL <t> [c] (UBFX [bfc] x) x2)
18276         // cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
18277         // result: (EXTRWconst [32-c] x2 x)
18278         for {
18279                 t := v.Type
18280                 c := auxIntToInt64(v.AuxInt)
18281                 if v_0.Op != OpARM64UBFX {
18282                         break
18283                 }
18284                 bfc := auxIntToArm64BitField(v_0.AuxInt)
18285                 x := v_0.Args[0]
18286                 x2 := v_1
18287                 if !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
18288                         break
18289                 }
18290                 v.reset(OpARM64EXTRWconst)
18291                 v.AuxInt = int64ToAuxInt(32 - c)
18292                 v.AddArg2(x2, x)
18293                 return true
18294         }
18295         return false
18296 }
18297 func rewriteValueARM64_OpARM64XORshiftRA(v *Value) bool {
18298         v_1 := v.Args[1]
18299         v_0 := v.Args[0]
18300         b := v.Block
18301         // match: (XORshiftRA (MOVDconst [c]) x [d])
18302         // result: (XORconst [c] (SRAconst <x.Type> x [d]))
18303         for {
18304                 d := auxIntToInt64(v.AuxInt)
18305                 if v_0.Op != OpARM64MOVDconst {
18306                         break
18307                 }
18308                 c := auxIntToInt64(v_0.AuxInt)
18309                 x := v_1
18310                 v.reset(OpARM64XORconst)
18311                 v.AuxInt = int64ToAuxInt(c)
18312                 v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
18313                 v0.AuxInt = int64ToAuxInt(d)
18314                 v0.AddArg(x)
18315                 v.AddArg(v0)
18316                 return true
18317         }
18318         // match: (XORshiftRA x (MOVDconst [c]) [d])
18319         // result: (XORconst x [c>>uint64(d)])
18320         for {
18321                 d := auxIntToInt64(v.AuxInt)
18322                 x := v_0
18323                 if v_1.Op != OpARM64MOVDconst {
18324                         break
18325                 }
18326                 c := auxIntToInt64(v_1.AuxInt)
18327                 v.reset(OpARM64XORconst)
18328                 v.AuxInt = int64ToAuxInt(c >> uint64(d))
18329                 v.AddArg(x)
18330                 return true
18331         }
18332         // match: (XORshiftRA (SRAconst x [c]) x [c])
18333         // result: (MOVDconst [0])
18334         for {
18335                 c := auxIntToInt64(v.AuxInt)
18336                 if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
18337                         break
18338                 }
18339                 x := v_0.Args[0]
18340                 if x != v_1 {
18341                         break
18342                 }
18343                 v.reset(OpARM64MOVDconst)
18344                 v.AuxInt = int64ToAuxInt(0)
18345                 return true
18346         }
18347         return false
18348 }
18349 func rewriteValueARM64_OpARM64XORshiftRL(v *Value) bool {
18350         v_1 := v.Args[1]
18351         v_0 := v.Args[0]
18352         b := v.Block
18353         // match: (XORshiftRL (MOVDconst [c]) x [d])
18354         // result: (XORconst [c] (SRLconst <x.Type> x [d]))
18355         for {
18356                 d := auxIntToInt64(v.AuxInt)
18357                 if v_0.Op != OpARM64MOVDconst {
18358                         break
18359                 }
18360                 c := auxIntToInt64(v_0.AuxInt)
18361                 x := v_1
18362                 v.reset(OpARM64XORconst)
18363                 v.AuxInt = int64ToAuxInt(c)
18364                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
18365                 v0.AuxInt = int64ToAuxInt(d)
18366                 v0.AddArg(x)
18367                 v.AddArg(v0)
18368                 return true
18369         }
18370         // match: (XORshiftRL x (MOVDconst [c]) [d])
18371         // result: (XORconst x [int64(uint64(c)>>uint64(d))])
18372         for {
18373                 d := auxIntToInt64(v.AuxInt)
18374                 x := v_0
18375                 if v_1.Op != OpARM64MOVDconst {
18376                         break
18377                 }
18378                 c := auxIntToInt64(v_1.AuxInt)
18379                 v.reset(OpARM64XORconst)
18380                 v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
18381                 v.AddArg(x)
18382                 return true
18383         }
18384         // match: (XORshiftRL (SRLconst x [c]) x [c])
18385         // result: (MOVDconst [0])
18386         for {
18387                 c := auxIntToInt64(v.AuxInt)
18388                 if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
18389                         break
18390                 }
18391                 x := v_0.Args[0]
18392                 if x != v_1 {
18393                         break
18394                 }
18395                 v.reset(OpARM64MOVDconst)
18396                 v.AuxInt = int64ToAuxInt(0)
18397                 return true
18398         }
18399         return false
18400 }
18401 func rewriteValueARM64_OpARM64XORshiftRO(v *Value) bool {
18402         v_1 := v.Args[1]
18403         v_0 := v.Args[0]
18404         b := v.Block
18405         // match: (XORshiftRO (MOVDconst [c]) x [d])
18406         // result: (XORconst [c] (RORconst <x.Type> x [d]))
18407         for {
18408                 d := auxIntToInt64(v.AuxInt)
18409                 if v_0.Op != OpARM64MOVDconst {
18410                         break
18411                 }
18412                 c := auxIntToInt64(v_0.AuxInt)
18413                 x := v_1
18414                 v.reset(OpARM64XORconst)
18415                 v.AuxInt = int64ToAuxInt(c)
18416                 v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
18417                 v0.AuxInt = int64ToAuxInt(d)
18418                 v0.AddArg(x)
18419                 v.AddArg(v0)
18420                 return true
18421         }
18422         // match: (XORshiftRO x (MOVDconst [c]) [d])
18423         // result: (XORconst x [rotateRight64(c, d)])
18424         for {
18425                 d := auxIntToInt64(v.AuxInt)
18426                 x := v_0
18427                 if v_1.Op != OpARM64MOVDconst {
18428                         break
18429                 }
18430                 c := auxIntToInt64(v_1.AuxInt)
18431                 v.reset(OpARM64XORconst)
18432                 v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
18433                 v.AddArg(x)
18434                 return true
18435         }
18436         // match: (XORshiftRO (RORconst x [c]) x [c])
18437         // result: (MOVDconst [0])
18438         for {
18439                 c := auxIntToInt64(v.AuxInt)
18440                 if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
18441                         break
18442                 }
18443                 x := v_0.Args[0]
18444                 if x != v_1 {
18445                         break
18446                 }
18447                 v.reset(OpARM64MOVDconst)
18448                 v.AuxInt = int64ToAuxInt(0)
18449                 return true
18450         }
18451         return false
18452 }
18453 func rewriteValueARM64_OpAddr(v *Value) bool {
18454         v_0 := v.Args[0]
18455         // match: (Addr {sym} base)
18456         // result: (MOVDaddr {sym} base)
18457         for {
18458                 sym := auxToSym(v.Aux)
18459                 base := v_0
18460                 v.reset(OpARM64MOVDaddr)
18461                 v.Aux = symToAux(sym)
18462                 v.AddArg(base)
18463                 return true
18464         }
18465 }
18466 func rewriteValueARM64_OpAtomicAnd32(v *Value) bool {
18467         v_2 := v.Args[2]
18468         v_1 := v.Args[1]
18469         v_0 := v.Args[0]
18470         b := v.Block
18471         typ := &b.Func.Config.Types
18472         // match: (AtomicAnd32 ptr val mem)
18473         // result: (Select1 (LoweredAtomicAnd32 ptr val mem))
18474         for {
18475                 ptr := v_0
18476                 val := v_1
18477                 mem := v_2
18478                 v.reset(OpSelect1)
18479                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd32, types.NewTuple(typ.UInt32, types.TypeMem))
18480                 v0.AddArg3(ptr, val, mem)
18481                 v.AddArg(v0)
18482                 return true
18483         }
18484 }
18485 func rewriteValueARM64_OpAtomicAnd32Variant(v *Value) bool {
18486         v_2 := v.Args[2]
18487         v_1 := v.Args[1]
18488         v_0 := v.Args[0]
18489         b := v.Block
18490         typ := &b.Func.Config.Types
18491         // match: (AtomicAnd32Variant ptr val mem)
18492         // result: (Select1 (LoweredAtomicAnd32Variant ptr val mem))
18493         for {
18494                 ptr := v_0
18495                 val := v_1
18496                 mem := v_2
18497                 v.reset(OpSelect1)
18498                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd32Variant, types.NewTuple(typ.UInt32, types.TypeMem))
18499                 v0.AddArg3(ptr, val, mem)
18500                 v.AddArg(v0)
18501                 return true
18502         }
18503 }
18504 func rewriteValueARM64_OpAtomicAnd8(v *Value) bool {
18505         v_2 := v.Args[2]
18506         v_1 := v.Args[1]
18507         v_0 := v.Args[0]
18508         b := v.Block
18509         typ := &b.Func.Config.Types
18510         // match: (AtomicAnd8 ptr val mem)
18511         // result: (Select1 (LoweredAtomicAnd8 ptr val mem))
18512         for {
18513                 ptr := v_0
18514                 val := v_1
18515                 mem := v_2
18516                 v.reset(OpSelect1)
18517                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd8, types.NewTuple(typ.UInt8, types.TypeMem))
18518                 v0.AddArg3(ptr, val, mem)
18519                 v.AddArg(v0)
18520                 return true
18521         }
18522 }
18523 func rewriteValueARM64_OpAtomicAnd8Variant(v *Value) bool {
18524         v_2 := v.Args[2]
18525         v_1 := v.Args[1]
18526         v_0 := v.Args[0]
18527         b := v.Block
18528         typ := &b.Func.Config.Types
18529         // match: (AtomicAnd8Variant ptr val mem)
18530         // result: (Select1 (LoweredAtomicAnd8Variant ptr val mem))
18531         for {
18532                 ptr := v_0
18533                 val := v_1
18534                 mem := v_2
18535                 v.reset(OpSelect1)
18536                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd8Variant, types.NewTuple(typ.UInt8, types.TypeMem))
18537                 v0.AddArg3(ptr, val, mem)
18538                 v.AddArg(v0)
18539                 return true
18540         }
18541 }
18542 func rewriteValueARM64_OpAtomicOr32(v *Value) bool {
18543         v_2 := v.Args[2]
18544         v_1 := v.Args[1]
18545         v_0 := v.Args[0]
18546         b := v.Block
18547         typ := &b.Func.Config.Types
18548         // match: (AtomicOr32 ptr val mem)
18549         // result: (Select1 (LoweredAtomicOr32 ptr val mem))
18550         for {
18551                 ptr := v_0
18552                 val := v_1
18553                 mem := v_2
18554                 v.reset(OpSelect1)
18555                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr32, types.NewTuple(typ.UInt32, types.TypeMem))
18556                 v0.AddArg3(ptr, val, mem)
18557                 v.AddArg(v0)
18558                 return true
18559         }
18560 }
18561 func rewriteValueARM64_OpAtomicOr32Variant(v *Value) bool {
18562         v_2 := v.Args[2]
18563         v_1 := v.Args[1]
18564         v_0 := v.Args[0]
18565         b := v.Block
18566         typ := &b.Func.Config.Types
18567         // match: (AtomicOr32Variant ptr val mem)
18568         // result: (Select1 (LoweredAtomicOr32Variant ptr val mem))
18569         for {
18570                 ptr := v_0
18571                 val := v_1
18572                 mem := v_2
18573                 v.reset(OpSelect1)
18574                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr32Variant, types.NewTuple(typ.UInt32, types.TypeMem))
18575                 v0.AddArg3(ptr, val, mem)
18576                 v.AddArg(v0)
18577                 return true
18578         }
18579 }
18580 func rewriteValueARM64_OpAtomicOr8(v *Value) bool {
18581         v_2 := v.Args[2]
18582         v_1 := v.Args[1]
18583         v_0 := v.Args[0]
18584         b := v.Block
18585         typ := &b.Func.Config.Types
18586         // match: (AtomicOr8 ptr val mem)
18587         // result: (Select1 (LoweredAtomicOr8 ptr val mem))
18588         for {
18589                 ptr := v_0
18590                 val := v_1
18591                 mem := v_2
18592                 v.reset(OpSelect1)
18593                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr8, types.NewTuple(typ.UInt8, types.TypeMem))
18594                 v0.AddArg3(ptr, val, mem)
18595                 v.AddArg(v0)
18596                 return true
18597         }
18598 }
18599 func rewriteValueARM64_OpAtomicOr8Variant(v *Value) bool {
18600         v_2 := v.Args[2]
18601         v_1 := v.Args[1]
18602         v_0 := v.Args[0]
18603         b := v.Block
18604         typ := &b.Func.Config.Types
18605         // match: (AtomicOr8Variant ptr val mem)
18606         // result: (Select1 (LoweredAtomicOr8Variant ptr val mem))
18607         for {
18608                 ptr := v_0
18609                 val := v_1
18610                 mem := v_2
18611                 v.reset(OpSelect1)
18612                 v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr8Variant, types.NewTuple(typ.UInt8, types.TypeMem))
18613                 v0.AddArg3(ptr, val, mem)
18614                 v.AddArg(v0)
18615                 return true
18616         }
18617 }
18618 func rewriteValueARM64_OpAvg64u(v *Value) bool {
18619         v_1 := v.Args[1]
18620         v_0 := v.Args[0]
18621         b := v.Block
18622         // match: (Avg64u <t> x y)
18623         // result: (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
18624         for {
18625                 t := v.Type
18626                 x := v_0
18627                 y := v_1
18628                 v.reset(OpARM64ADD)
18629                 v0 := b.NewValue0(v.Pos, OpARM64SRLconst, t)
18630                 v0.AuxInt = int64ToAuxInt(1)
18631                 v1 := b.NewValue0(v.Pos, OpARM64SUB, t)
18632                 v1.AddArg2(x, y)
18633                 v0.AddArg(v1)
18634                 v.AddArg2(v0, y)
18635                 return true
18636         }
18637 }
18638 func rewriteValueARM64_OpBitLen32(v *Value) bool {
18639         v_0 := v.Args[0]
18640         b := v.Block
18641         typ := &b.Func.Config.Types
18642         // match: (BitLen32 x)
18643         // result: (SUB (MOVDconst [32]) (CLZW <typ.Int> x))
18644         for {
18645                 x := v_0
18646                 v.reset(OpARM64SUB)
18647                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
18648                 v0.AuxInt = int64ToAuxInt(32)
18649                 v1 := b.NewValue0(v.Pos, OpARM64CLZW, typ.Int)
18650                 v1.AddArg(x)
18651                 v.AddArg2(v0, v1)
18652                 return true
18653         }
18654 }
18655 func rewriteValueARM64_OpBitLen64(v *Value) bool {
18656         v_0 := v.Args[0]
18657         b := v.Block
18658         typ := &b.Func.Config.Types
18659         // match: (BitLen64 x)
18660         // result: (SUB (MOVDconst [64]) (CLZ <typ.Int> x))
18661         for {
18662                 x := v_0
18663                 v.reset(OpARM64SUB)
18664                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
18665                 v0.AuxInt = int64ToAuxInt(64)
18666                 v1 := b.NewValue0(v.Pos, OpARM64CLZ, typ.Int)
18667                 v1.AddArg(x)
18668                 v.AddArg2(v0, v1)
18669                 return true
18670         }
18671 }
18672 func rewriteValueARM64_OpBitRev16(v *Value) bool {
18673         v_0 := v.Args[0]
18674         b := v.Block
18675         typ := &b.Func.Config.Types
18676         // match: (BitRev16 x)
18677         // result: (SRLconst [48] (RBIT <typ.UInt64> x))
18678         for {
18679                 x := v_0
18680                 v.reset(OpARM64SRLconst)
18681                 v.AuxInt = int64ToAuxInt(48)
18682                 v0 := b.NewValue0(v.Pos, OpARM64RBIT, typ.UInt64)
18683                 v0.AddArg(x)
18684                 v.AddArg(v0)
18685                 return true
18686         }
18687 }
18688 func rewriteValueARM64_OpBitRev8(v *Value) bool {
18689         v_0 := v.Args[0]
18690         b := v.Block
18691         typ := &b.Func.Config.Types
18692         // match: (BitRev8 x)
18693         // result: (SRLconst [56] (RBIT <typ.UInt64> x))
18694         for {
18695                 x := v_0
18696                 v.reset(OpARM64SRLconst)
18697                 v.AuxInt = int64ToAuxInt(56)
18698                 v0 := b.NewValue0(v.Pos, OpARM64RBIT, typ.UInt64)
18699                 v0.AddArg(x)
18700                 v.AddArg(v0)
18701                 return true
18702         }
18703 }
18704 func rewriteValueARM64_OpCondSelect(v *Value) bool {
18705         v_2 := v.Args[2]
18706         v_1 := v.Args[1]
18707         v_0 := v.Args[0]
18708         b := v.Block
18709         // match: (CondSelect x y boolval)
18710         // cond: flagArg(boolval) != nil
18711         // result: (CSEL [boolval.Op] x y flagArg(boolval))
18712         for {
18713                 x := v_0
18714                 y := v_1
18715                 boolval := v_2
18716                 if !(flagArg(boolval) != nil) {
18717                         break
18718                 }
18719                 v.reset(OpARM64CSEL)
18720                 v.AuxInt = opToAuxInt(boolval.Op)
18721                 v.AddArg3(x, y, flagArg(boolval))
18722                 return true
18723         }
18724         // match: (CondSelect x y boolval)
18725         // cond: flagArg(boolval) == nil
18726         // result: (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval))
18727         for {
18728                 x := v_0
18729                 y := v_1
18730                 boolval := v_2
18731                 if !(flagArg(boolval) == nil) {
18732                         break
18733                 }
18734                 v.reset(OpARM64CSEL)
18735                 v.AuxInt = opToAuxInt(OpARM64NotEqual)
18736                 v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
18737                 v0.AuxInt = int32ToAuxInt(1)
18738                 v0.AddArg(boolval)
18739                 v.AddArg3(x, y, v0)
18740                 return true
18741         }
18742         return false
18743 }
18744 func rewriteValueARM64_OpConst16(v *Value) bool {
18745         // match: (Const16 [val])
18746         // result: (MOVDconst [int64(val)])
18747         for {
18748                 val := auxIntToInt16(v.AuxInt)
18749                 v.reset(OpARM64MOVDconst)
18750                 v.AuxInt = int64ToAuxInt(int64(val))
18751                 return true
18752         }
18753 }
18754 func rewriteValueARM64_OpConst32(v *Value) bool {
18755         // match: (Const32 [val])
18756         // result: (MOVDconst [int64(val)])
18757         for {
18758                 val := auxIntToInt32(v.AuxInt)
18759                 v.reset(OpARM64MOVDconst)
18760                 v.AuxInt = int64ToAuxInt(int64(val))
18761                 return true
18762         }
18763 }
18764 func rewriteValueARM64_OpConst32F(v *Value) bool {
18765         // match: (Const32F [val])
18766         // result: (FMOVSconst [float64(val)])
18767         for {
18768                 val := auxIntToFloat32(v.AuxInt)
18769                 v.reset(OpARM64FMOVSconst)
18770                 v.AuxInt = float64ToAuxInt(float64(val))
18771                 return true
18772         }
18773 }
18774 func rewriteValueARM64_OpConst64(v *Value) bool {
18775         // match: (Const64 [val])
18776         // result: (MOVDconst [int64(val)])
18777         for {
18778                 val := auxIntToInt64(v.AuxInt)
18779                 v.reset(OpARM64MOVDconst)
18780                 v.AuxInt = int64ToAuxInt(int64(val))
18781                 return true
18782         }
18783 }
18784 func rewriteValueARM64_OpConst64F(v *Value) bool {
18785         // match: (Const64F [val])
18786         // result: (FMOVDconst [float64(val)])
18787         for {
18788                 val := auxIntToFloat64(v.AuxInt)
18789                 v.reset(OpARM64FMOVDconst)
18790                 v.AuxInt = float64ToAuxInt(float64(val))
18791                 return true
18792         }
18793 }
18794 func rewriteValueARM64_OpConst8(v *Value) bool {
18795         // match: (Const8 [val])
18796         // result: (MOVDconst [int64(val)])
18797         for {
18798                 val := auxIntToInt8(v.AuxInt)
18799                 v.reset(OpARM64MOVDconst)
18800                 v.AuxInt = int64ToAuxInt(int64(val))
18801                 return true
18802         }
18803 }
18804 func rewriteValueARM64_OpConstBool(v *Value) bool {
18805         // match: (ConstBool [t])
18806         // result: (MOVDconst [b2i(t)])
18807         for {
18808                 t := auxIntToBool(v.AuxInt)
18809                 v.reset(OpARM64MOVDconst)
18810                 v.AuxInt = int64ToAuxInt(b2i(t))
18811                 return true
18812         }
18813 }
18814 func rewriteValueARM64_OpConstNil(v *Value) bool {
18815         // match: (ConstNil)
18816         // result: (MOVDconst [0])
18817         for {
18818                 v.reset(OpARM64MOVDconst)
18819                 v.AuxInt = int64ToAuxInt(0)
18820                 return true
18821         }
18822 }
18823 func rewriteValueARM64_OpCtz16(v *Value) bool {
18824         v_0 := v.Args[0]
18825         b := v.Block
18826         typ := &b.Func.Config.Types
18827         // match: (Ctz16 <t> x)
18828         // result: (CLZW <t> (RBITW <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
18829         for {
18830                 t := v.Type
18831                 x := v_0
18832                 v.reset(OpARM64CLZW)
18833                 v.Type = t
18834                 v0 := b.NewValue0(v.Pos, OpARM64RBITW, typ.UInt32)
18835                 v1 := b.NewValue0(v.Pos, OpARM64ORconst, typ.UInt32)
18836                 v1.AuxInt = int64ToAuxInt(0x10000)
18837                 v1.AddArg(x)
18838                 v0.AddArg(v1)
18839                 v.AddArg(v0)
18840                 return true
18841         }
18842 }
18843 func rewriteValueARM64_OpCtz32(v *Value) bool {
18844         v_0 := v.Args[0]
18845         b := v.Block
18846         // match: (Ctz32 <t> x)
18847         // result: (CLZW (RBITW <t> x))
18848         for {
18849                 t := v.Type
18850                 x := v_0
18851                 v.reset(OpARM64CLZW)
18852                 v0 := b.NewValue0(v.Pos, OpARM64RBITW, t)
18853                 v0.AddArg(x)
18854                 v.AddArg(v0)
18855                 return true
18856         }
18857 }
18858 func rewriteValueARM64_OpCtz64(v *Value) bool {
18859         v_0 := v.Args[0]
18860         b := v.Block
18861         // match: (Ctz64 <t> x)
18862         // result: (CLZ (RBIT <t> x))
18863         for {
18864                 t := v.Type
18865                 x := v_0
18866                 v.reset(OpARM64CLZ)
18867                 v0 := b.NewValue0(v.Pos, OpARM64RBIT, t)
18868                 v0.AddArg(x)
18869                 v.AddArg(v0)
18870                 return true
18871         }
18872 }
18873 func rewriteValueARM64_OpCtz8(v *Value) bool {
18874         v_0 := v.Args[0]
18875         b := v.Block
18876         typ := &b.Func.Config.Types
18877         // match: (Ctz8 <t> x)
18878         // result: (CLZW <t> (RBITW <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
18879         for {
18880                 t := v.Type
18881                 x := v_0
18882                 v.reset(OpARM64CLZW)
18883                 v.Type = t
18884                 v0 := b.NewValue0(v.Pos, OpARM64RBITW, typ.UInt32)
18885                 v1 := b.NewValue0(v.Pos, OpARM64ORconst, typ.UInt32)
18886                 v1.AuxInt = int64ToAuxInt(0x100)
18887                 v1.AddArg(x)
18888                 v0.AddArg(v1)
18889                 v.AddArg(v0)
18890                 return true
18891         }
18892 }
18893 func rewriteValueARM64_OpDiv16(v *Value) bool {
18894         v_1 := v.Args[1]
18895         v_0 := v.Args[0]
18896         b := v.Block
18897         typ := &b.Func.Config.Types
18898         // match: (Div16 [false] x y)
18899         // result: (DIVW (SignExt16to32 x) (SignExt16to32 y))
18900         for {
18901                 if auxIntToBool(v.AuxInt) != false {
18902                         break
18903                 }
18904                 x := v_0
18905                 y := v_1
18906                 v.reset(OpARM64DIVW)
18907                 v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
18908                 v0.AddArg(x)
18909                 v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
18910                 v1.AddArg(y)
18911                 v.AddArg2(v0, v1)
18912                 return true
18913         }
18914         return false
18915 }
18916 func rewriteValueARM64_OpDiv16u(v *Value) bool {
18917         v_1 := v.Args[1]
18918         v_0 := v.Args[0]
18919         b := v.Block
18920         typ := &b.Func.Config.Types
18921         // match: (Div16u x y)
18922         // result: (UDIVW (ZeroExt16to32 x) (ZeroExt16to32 y))
18923         for {
18924                 x := v_0
18925                 y := v_1
18926                 v.reset(OpARM64UDIVW)
18927                 v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
18928                 v0.AddArg(x)
18929                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
18930                 v1.AddArg(y)
18931                 v.AddArg2(v0, v1)
18932                 return true
18933         }
18934 }
18935 func rewriteValueARM64_OpDiv32(v *Value) bool {
18936         v_1 := v.Args[1]
18937         v_0 := v.Args[0]
18938         // match: (Div32 [false] x y)
18939         // result: (DIVW x y)
18940         for {
18941                 if auxIntToBool(v.AuxInt) != false {
18942                         break
18943                 }
18944                 x := v_0
18945                 y := v_1
18946                 v.reset(OpARM64DIVW)
18947                 v.AddArg2(x, y)
18948                 return true
18949         }
18950         return false
18951 }
18952 func rewriteValueARM64_OpDiv64(v *Value) bool {
18953         v_1 := v.Args[1]
18954         v_0 := v.Args[0]
18955         // match: (Div64 [false] x y)
18956         // result: (DIV x y)
18957         for {
18958                 if auxIntToBool(v.AuxInt) != false {
18959                         break
18960                 }
18961                 x := v_0
18962                 y := v_1
18963                 v.reset(OpARM64DIV)
18964                 v.AddArg2(x, y)
18965                 return true
18966         }
18967         return false
18968 }
18969 func rewriteValueARM64_OpDiv8(v *Value) bool {
18970         v_1 := v.Args[1]
18971         v_0 := v.Args[0]
18972         b := v.Block
18973         typ := &b.Func.Config.Types
18974         // match: (Div8 x y)
18975         // result: (DIVW (SignExt8to32 x) (SignExt8to32 y))
18976         for {
18977                 x := v_0
18978                 y := v_1
18979                 v.reset(OpARM64DIVW)
18980                 v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
18981                 v0.AddArg(x)
18982                 v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
18983                 v1.AddArg(y)
18984                 v.AddArg2(v0, v1)
18985                 return true
18986         }
18987 }
18988 func rewriteValueARM64_OpDiv8u(v *Value) bool {
18989         v_1 := v.Args[1]
18990         v_0 := v.Args[0]
18991         b := v.Block
18992         typ := &b.Func.Config.Types
18993         // match: (Div8u x y)
18994         // result: (UDIVW (ZeroExt8to32 x) (ZeroExt8to32 y))
18995         for {
18996                 x := v_0
18997                 y := v_1
18998                 v.reset(OpARM64UDIVW)
18999                 v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19000                 v0.AddArg(x)
19001                 v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19002                 v1.AddArg(y)
19003                 v.AddArg2(v0, v1)
19004                 return true
19005         }
19006 }
19007 func rewriteValueARM64_OpEq16(v *Value) bool {
19008         v_1 := v.Args[1]
19009         v_0 := v.Args[0]
19010         b := v.Block
19011         typ := &b.Func.Config.Types
19012         // match: (Eq16 x y)
19013         // result: (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
19014         for {
19015                 x := v_0
19016                 y := v_1
19017                 v.reset(OpARM64Equal)
19018                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19019                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
19020                 v1.AddArg(x)
19021                 v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
19022                 v2.AddArg(y)
19023                 v0.AddArg2(v1, v2)
19024                 v.AddArg(v0)
19025                 return true
19026         }
19027 }
19028 func rewriteValueARM64_OpEq32(v *Value) bool {
19029         v_1 := v.Args[1]
19030         v_0 := v.Args[0]
19031         b := v.Block
19032         // match: (Eq32 x y)
19033         // result: (Equal (CMPW x y))
19034         for {
19035                 x := v_0
19036                 y := v_1
19037                 v.reset(OpARM64Equal)
19038                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19039                 v0.AddArg2(x, y)
19040                 v.AddArg(v0)
19041                 return true
19042         }
19043 }
19044 func rewriteValueARM64_OpEq32F(v *Value) bool {
19045         v_1 := v.Args[1]
19046         v_0 := v.Args[0]
19047         b := v.Block
19048         // match: (Eq32F x y)
19049         // result: (Equal (FCMPS x y))
19050         for {
19051                 x := v_0
19052                 y := v_1
19053                 v.reset(OpARM64Equal)
19054                 v0 := b.NewValue0(v.Pos, OpARM64FCMPS, types.TypeFlags)
19055                 v0.AddArg2(x, y)
19056                 v.AddArg(v0)
19057                 return true
19058         }
19059 }
19060 func rewriteValueARM64_OpEq64(v *Value) bool {
19061         v_1 := v.Args[1]
19062         v_0 := v.Args[0]
19063         b := v.Block
19064         // match: (Eq64 x y)
19065         // result: (Equal (CMP x y))
19066         for {
19067                 x := v_0
19068                 y := v_1
19069                 v.reset(OpARM64Equal)
19070                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19071                 v0.AddArg2(x, y)
19072                 v.AddArg(v0)
19073                 return true
19074         }
19075 }
19076 func rewriteValueARM64_OpEq64F(v *Value) bool {
19077         v_1 := v.Args[1]
19078         v_0 := v.Args[0]
19079         b := v.Block
19080         // match: (Eq64F x y)
19081         // result: (Equal (FCMPD x y))
19082         for {
19083                 x := v_0
19084                 y := v_1
19085                 v.reset(OpARM64Equal)
19086                 v0 := b.NewValue0(v.Pos, OpARM64FCMPD, types.TypeFlags)
19087                 v0.AddArg2(x, y)
19088                 v.AddArg(v0)
19089                 return true
19090         }
19091 }
19092 func rewriteValueARM64_OpEq8(v *Value) bool {
19093         v_1 := v.Args[1]
19094         v_0 := v.Args[0]
19095         b := v.Block
19096         typ := &b.Func.Config.Types
19097         // match: (Eq8 x y)
19098         // result: (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
19099         for {
19100                 x := v_0
19101                 y := v_1
19102                 v.reset(OpARM64Equal)
19103                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19104                 v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19105                 v1.AddArg(x)
19106                 v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19107                 v2.AddArg(y)
19108                 v0.AddArg2(v1, v2)
19109                 v.AddArg(v0)
19110                 return true
19111         }
19112 }
19113 func rewriteValueARM64_OpEqB(v *Value) bool {
19114         v_1 := v.Args[1]
19115         v_0 := v.Args[0]
19116         b := v.Block
19117         typ := &b.Func.Config.Types
19118         // match: (EqB x y)
19119         // result: (XOR (MOVDconst [1]) (XOR <typ.Bool> x y))
19120         for {
19121                 x := v_0
19122                 y := v_1
19123                 v.reset(OpARM64XOR)
19124                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19125                 v0.AuxInt = int64ToAuxInt(1)
19126                 v1 := b.NewValue0(v.Pos, OpARM64XOR, typ.Bool)
19127                 v1.AddArg2(x, y)
19128                 v.AddArg2(v0, v1)
19129                 return true
19130         }
19131 }
19132 func rewriteValueARM64_OpEqPtr(v *Value) bool {
19133         v_1 := v.Args[1]
19134         v_0 := v.Args[0]
19135         b := v.Block
19136         // match: (EqPtr x y)
19137         // result: (Equal (CMP x y))
19138         for {
19139                 x := v_0
19140                 y := v_1
19141                 v.reset(OpARM64Equal)
19142                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19143                 v0.AddArg2(x, y)
19144                 v.AddArg(v0)
19145                 return true
19146         }
19147 }
19148 func rewriteValueARM64_OpFMA(v *Value) bool {
19149         v_2 := v.Args[2]
19150         v_1 := v.Args[1]
19151         v_0 := v.Args[0]
19152         // match: (FMA x y z)
19153         // result: (FMADDD z x y)
19154         for {
19155                 x := v_0
19156                 y := v_1
19157                 z := v_2
19158                 v.reset(OpARM64FMADDD)
19159                 v.AddArg3(z, x, y)
19160                 return true
19161         }
19162 }
19163 func rewriteValueARM64_OpHmul32(v *Value) bool {
19164         v_1 := v.Args[1]
19165         v_0 := v.Args[0]
19166         b := v.Block
19167         typ := &b.Func.Config.Types
19168         // match: (Hmul32 x y)
19169         // result: (SRAconst (MULL <typ.Int64> x y) [32])
19170         for {
19171                 x := v_0
19172                 y := v_1
19173                 v.reset(OpARM64SRAconst)
19174                 v.AuxInt = int64ToAuxInt(32)
19175                 v0 := b.NewValue0(v.Pos, OpARM64MULL, typ.Int64)
19176                 v0.AddArg2(x, y)
19177                 v.AddArg(v0)
19178                 return true
19179         }
19180 }
19181 func rewriteValueARM64_OpHmul32u(v *Value) bool {
19182         v_1 := v.Args[1]
19183         v_0 := v.Args[0]
19184         b := v.Block
19185         typ := &b.Func.Config.Types
19186         // match: (Hmul32u x y)
19187         // result: (SRAconst (UMULL <typ.UInt64> x y) [32])
19188         for {
19189                 x := v_0
19190                 y := v_1
19191                 v.reset(OpARM64SRAconst)
19192                 v.AuxInt = int64ToAuxInt(32)
19193                 v0 := b.NewValue0(v.Pos, OpARM64UMULL, typ.UInt64)
19194                 v0.AddArg2(x, y)
19195                 v.AddArg(v0)
19196                 return true
19197         }
19198 }
19199 func rewriteValueARM64_OpIsInBounds(v *Value) bool {
19200         v_1 := v.Args[1]
19201         v_0 := v.Args[0]
19202         b := v.Block
19203         // match: (IsInBounds idx len)
19204         // result: (LessThanU (CMP idx len))
19205         for {
19206                 idx := v_0
19207                 len := v_1
19208                 v.reset(OpARM64LessThanU)
19209                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19210                 v0.AddArg2(idx, len)
19211                 v.AddArg(v0)
19212                 return true
19213         }
19214 }
19215 func rewriteValueARM64_OpIsNonNil(v *Value) bool {
19216         v_0 := v.Args[0]
19217         b := v.Block
19218         // match: (IsNonNil ptr)
19219         // result: (NotEqual (CMPconst [0] ptr))
19220         for {
19221                 ptr := v_0
19222                 v.reset(OpARM64NotEqual)
19223                 v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
19224                 v0.AuxInt = int64ToAuxInt(0)
19225                 v0.AddArg(ptr)
19226                 v.AddArg(v0)
19227                 return true
19228         }
19229 }
19230 func rewriteValueARM64_OpIsSliceInBounds(v *Value) bool {
19231         v_1 := v.Args[1]
19232         v_0 := v.Args[0]
19233         b := v.Block
19234         // match: (IsSliceInBounds idx len)
19235         // result: (LessEqualU (CMP idx len))
19236         for {
19237                 idx := v_0
19238                 len := v_1
19239                 v.reset(OpARM64LessEqualU)
19240                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19241                 v0.AddArg2(idx, len)
19242                 v.AddArg(v0)
19243                 return true
19244         }
19245 }
19246 func rewriteValueARM64_OpLeq16(v *Value) bool {
19247         v_1 := v.Args[1]
19248         v_0 := v.Args[0]
19249         b := v.Block
19250         typ := &b.Func.Config.Types
19251         // match: (Leq16 x y)
19252         // result: (LessEqual (CMPW (SignExt16to32 x) (SignExt16to32 y)))
19253         for {
19254                 x := v_0
19255                 y := v_1
19256                 v.reset(OpARM64LessEqual)
19257                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19258                 v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
19259                 v1.AddArg(x)
19260                 v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
19261                 v2.AddArg(y)
19262                 v0.AddArg2(v1, v2)
19263                 v.AddArg(v0)
19264                 return true
19265         }
19266 }
19267 func rewriteValueARM64_OpLeq16U(v *Value) bool {
19268         v_1 := v.Args[1]
19269         v_0 := v.Args[0]
19270         b := v.Block
19271         typ := &b.Func.Config.Types
19272         // match: (Leq16U x zero:(MOVDconst [0]))
19273         // result: (Eq16 x zero)
19274         for {
19275                 x := v_0
19276                 zero := v_1
19277                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19278                         break
19279                 }
19280                 v.reset(OpEq16)
19281                 v.AddArg2(x, zero)
19282                 return true
19283         }
19284         // match: (Leq16U (MOVDconst [1]) x)
19285         // result: (Neq16 (MOVDconst [0]) x)
19286         for {
19287                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 1 {
19288                         break
19289                 }
19290                 x := v_1
19291                 v.reset(OpNeq16)
19292                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19293                 v0.AuxInt = int64ToAuxInt(0)
19294                 v.AddArg2(v0, x)
19295                 return true
19296         }
19297         // match: (Leq16U x y)
19298         // result: (LessEqualU (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
19299         for {
19300                 x := v_0
19301                 y := v_1
19302                 v.reset(OpARM64LessEqualU)
19303                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19304                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
19305                 v1.AddArg(x)
19306                 v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
19307                 v2.AddArg(y)
19308                 v0.AddArg2(v1, v2)
19309                 v.AddArg(v0)
19310                 return true
19311         }
19312 }
19313 func rewriteValueARM64_OpLeq32(v *Value) bool {
19314         v_1 := v.Args[1]
19315         v_0 := v.Args[0]
19316         b := v.Block
19317         // match: (Leq32 x y)
19318         // result: (LessEqual (CMPW x y))
19319         for {
19320                 x := v_0
19321                 y := v_1
19322                 v.reset(OpARM64LessEqual)
19323                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19324                 v0.AddArg2(x, y)
19325                 v.AddArg(v0)
19326                 return true
19327         }
19328 }
19329 func rewriteValueARM64_OpLeq32F(v *Value) bool {
19330         v_1 := v.Args[1]
19331         v_0 := v.Args[0]
19332         b := v.Block
19333         // match: (Leq32F x y)
19334         // result: (LessEqualF (FCMPS x y))
19335         for {
19336                 x := v_0
19337                 y := v_1
19338                 v.reset(OpARM64LessEqualF)
19339                 v0 := b.NewValue0(v.Pos, OpARM64FCMPS, types.TypeFlags)
19340                 v0.AddArg2(x, y)
19341                 v.AddArg(v0)
19342                 return true
19343         }
19344 }
19345 func rewriteValueARM64_OpLeq32U(v *Value) bool {
19346         v_1 := v.Args[1]
19347         v_0 := v.Args[0]
19348         b := v.Block
19349         typ := &b.Func.Config.Types
19350         // match: (Leq32U x zero:(MOVDconst [0]))
19351         // result: (Eq32 x zero)
19352         for {
19353                 x := v_0
19354                 zero := v_1
19355                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19356                         break
19357                 }
19358                 v.reset(OpEq32)
19359                 v.AddArg2(x, zero)
19360                 return true
19361         }
19362         // match: (Leq32U (MOVDconst [1]) x)
19363         // result: (Neq32 (MOVDconst [0]) x)
19364         for {
19365                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 1 {
19366                         break
19367                 }
19368                 x := v_1
19369                 v.reset(OpNeq32)
19370                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19371                 v0.AuxInt = int64ToAuxInt(0)
19372                 v.AddArg2(v0, x)
19373                 return true
19374         }
19375         // match: (Leq32U x y)
19376         // result: (LessEqualU (CMPW x y))
19377         for {
19378                 x := v_0
19379                 y := v_1
19380                 v.reset(OpARM64LessEqualU)
19381                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19382                 v0.AddArg2(x, y)
19383                 v.AddArg(v0)
19384                 return true
19385         }
19386 }
19387 func rewriteValueARM64_OpLeq64(v *Value) bool {
19388         v_1 := v.Args[1]
19389         v_0 := v.Args[0]
19390         b := v.Block
19391         // match: (Leq64 x y)
19392         // result: (LessEqual (CMP x y))
19393         for {
19394                 x := v_0
19395                 y := v_1
19396                 v.reset(OpARM64LessEqual)
19397                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19398                 v0.AddArg2(x, y)
19399                 v.AddArg(v0)
19400                 return true
19401         }
19402 }
19403 func rewriteValueARM64_OpLeq64F(v *Value) bool {
19404         v_1 := v.Args[1]
19405         v_0 := v.Args[0]
19406         b := v.Block
19407         // match: (Leq64F x y)
19408         // result: (LessEqualF (FCMPD x y))
19409         for {
19410                 x := v_0
19411                 y := v_1
19412                 v.reset(OpARM64LessEqualF)
19413                 v0 := b.NewValue0(v.Pos, OpARM64FCMPD, types.TypeFlags)
19414                 v0.AddArg2(x, y)
19415                 v.AddArg(v0)
19416                 return true
19417         }
19418 }
19419 func rewriteValueARM64_OpLeq64U(v *Value) bool {
19420         v_1 := v.Args[1]
19421         v_0 := v.Args[0]
19422         b := v.Block
19423         typ := &b.Func.Config.Types
19424         // match: (Leq64U x zero:(MOVDconst [0]))
19425         // result: (Eq64 x zero)
19426         for {
19427                 x := v_0
19428                 zero := v_1
19429                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19430                         break
19431                 }
19432                 v.reset(OpEq64)
19433                 v.AddArg2(x, zero)
19434                 return true
19435         }
19436         // match: (Leq64U (MOVDconst [1]) x)
19437         // result: (Neq64 (MOVDconst [0]) x)
19438         for {
19439                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 1 {
19440                         break
19441                 }
19442                 x := v_1
19443                 v.reset(OpNeq64)
19444                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19445                 v0.AuxInt = int64ToAuxInt(0)
19446                 v.AddArg2(v0, x)
19447                 return true
19448         }
19449         // match: (Leq64U x y)
19450         // result: (LessEqualU (CMP x y))
19451         for {
19452                 x := v_0
19453                 y := v_1
19454                 v.reset(OpARM64LessEqualU)
19455                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19456                 v0.AddArg2(x, y)
19457                 v.AddArg(v0)
19458                 return true
19459         }
19460 }
19461 func rewriteValueARM64_OpLeq8(v *Value) bool {
19462         v_1 := v.Args[1]
19463         v_0 := v.Args[0]
19464         b := v.Block
19465         typ := &b.Func.Config.Types
19466         // match: (Leq8 x y)
19467         // result: (LessEqual (CMPW (SignExt8to32 x) (SignExt8to32 y)))
19468         for {
19469                 x := v_0
19470                 y := v_1
19471                 v.reset(OpARM64LessEqual)
19472                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19473                 v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
19474                 v1.AddArg(x)
19475                 v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
19476                 v2.AddArg(y)
19477                 v0.AddArg2(v1, v2)
19478                 v.AddArg(v0)
19479                 return true
19480         }
19481 }
19482 func rewriteValueARM64_OpLeq8U(v *Value) bool {
19483         v_1 := v.Args[1]
19484         v_0 := v.Args[0]
19485         b := v.Block
19486         typ := &b.Func.Config.Types
19487         // match: (Leq8U x zero:(MOVDconst [0]))
19488         // result: (Eq8 x zero)
19489         for {
19490                 x := v_0
19491                 zero := v_1
19492                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19493                         break
19494                 }
19495                 v.reset(OpEq8)
19496                 v.AddArg2(x, zero)
19497                 return true
19498         }
19499         // match: (Leq8U (MOVDconst [1]) x)
19500         // result: (Neq8 (MOVDconst [0]) x)
19501         for {
19502                 if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 1 {
19503                         break
19504                 }
19505                 x := v_1
19506                 v.reset(OpNeq8)
19507                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19508                 v0.AuxInt = int64ToAuxInt(0)
19509                 v.AddArg2(v0, x)
19510                 return true
19511         }
19512         // match: (Leq8U x y)
19513         // result: (LessEqualU (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
19514         for {
19515                 x := v_0
19516                 y := v_1
19517                 v.reset(OpARM64LessEqualU)
19518                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19519                 v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19520                 v1.AddArg(x)
19521                 v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19522                 v2.AddArg(y)
19523                 v0.AddArg2(v1, v2)
19524                 v.AddArg(v0)
19525                 return true
19526         }
19527 }
19528 func rewriteValueARM64_OpLess16(v *Value) bool {
19529         v_1 := v.Args[1]
19530         v_0 := v.Args[0]
19531         b := v.Block
19532         typ := &b.Func.Config.Types
19533         // match: (Less16 x y)
19534         // result: (LessThan (CMPW (SignExt16to32 x) (SignExt16to32 y)))
19535         for {
19536                 x := v_0
19537                 y := v_1
19538                 v.reset(OpARM64LessThan)
19539                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19540                 v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
19541                 v1.AddArg(x)
19542                 v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
19543                 v2.AddArg(y)
19544                 v0.AddArg2(v1, v2)
19545                 v.AddArg(v0)
19546                 return true
19547         }
19548 }
19549 func rewriteValueARM64_OpLess16U(v *Value) bool {
19550         v_1 := v.Args[1]
19551         v_0 := v.Args[0]
19552         b := v.Block
19553         typ := &b.Func.Config.Types
19554         // match: (Less16U zero:(MOVDconst [0]) x)
19555         // result: (Neq16 zero x)
19556         for {
19557                 zero := v_0
19558                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19559                         break
19560                 }
19561                 x := v_1
19562                 v.reset(OpNeq16)
19563                 v.AddArg2(zero, x)
19564                 return true
19565         }
19566         // match: (Less16U x (MOVDconst [1]))
19567         // result: (Eq16 x (MOVDconst [0]))
19568         for {
19569                 x := v_0
19570                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
19571                         break
19572                 }
19573                 v.reset(OpEq16)
19574                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19575                 v0.AuxInt = int64ToAuxInt(0)
19576                 v.AddArg2(x, v0)
19577                 return true
19578         }
19579         // match: (Less16U x y)
19580         // result: (LessThanU (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
19581         for {
19582                 x := v_0
19583                 y := v_1
19584                 v.reset(OpARM64LessThanU)
19585                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19586                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
19587                 v1.AddArg(x)
19588                 v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
19589                 v2.AddArg(y)
19590                 v0.AddArg2(v1, v2)
19591                 v.AddArg(v0)
19592                 return true
19593         }
19594 }
19595 func rewriteValueARM64_OpLess32(v *Value) bool {
19596         v_1 := v.Args[1]
19597         v_0 := v.Args[0]
19598         b := v.Block
19599         // match: (Less32 x y)
19600         // result: (LessThan (CMPW x y))
19601         for {
19602                 x := v_0
19603                 y := v_1
19604                 v.reset(OpARM64LessThan)
19605                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19606                 v0.AddArg2(x, y)
19607                 v.AddArg(v0)
19608                 return true
19609         }
19610 }
19611 func rewriteValueARM64_OpLess32F(v *Value) bool {
19612         v_1 := v.Args[1]
19613         v_0 := v.Args[0]
19614         b := v.Block
19615         // match: (Less32F x y)
19616         // result: (LessThanF (FCMPS x y))
19617         for {
19618                 x := v_0
19619                 y := v_1
19620                 v.reset(OpARM64LessThanF)
19621                 v0 := b.NewValue0(v.Pos, OpARM64FCMPS, types.TypeFlags)
19622                 v0.AddArg2(x, y)
19623                 v.AddArg(v0)
19624                 return true
19625         }
19626 }
19627 func rewriteValueARM64_OpLess32U(v *Value) bool {
19628         v_1 := v.Args[1]
19629         v_0 := v.Args[0]
19630         b := v.Block
19631         typ := &b.Func.Config.Types
19632         // match: (Less32U zero:(MOVDconst [0]) x)
19633         // result: (Neq32 zero x)
19634         for {
19635                 zero := v_0
19636                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19637                         break
19638                 }
19639                 x := v_1
19640                 v.reset(OpNeq32)
19641                 v.AddArg2(zero, x)
19642                 return true
19643         }
19644         // match: (Less32U x (MOVDconst [1]))
19645         // result: (Eq32 x (MOVDconst [0]))
19646         for {
19647                 x := v_0
19648                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
19649                         break
19650                 }
19651                 v.reset(OpEq32)
19652                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19653                 v0.AuxInt = int64ToAuxInt(0)
19654                 v.AddArg2(x, v0)
19655                 return true
19656         }
19657         // match: (Less32U x y)
19658         // result: (LessThanU (CMPW x y))
19659         for {
19660                 x := v_0
19661                 y := v_1
19662                 v.reset(OpARM64LessThanU)
19663                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19664                 v0.AddArg2(x, y)
19665                 v.AddArg(v0)
19666                 return true
19667         }
19668 }
19669 func rewriteValueARM64_OpLess64(v *Value) bool {
19670         v_1 := v.Args[1]
19671         v_0 := v.Args[0]
19672         b := v.Block
19673         // match: (Less64 x y)
19674         // result: (LessThan (CMP x y))
19675         for {
19676                 x := v_0
19677                 y := v_1
19678                 v.reset(OpARM64LessThan)
19679                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19680                 v0.AddArg2(x, y)
19681                 v.AddArg(v0)
19682                 return true
19683         }
19684 }
19685 func rewriteValueARM64_OpLess64F(v *Value) bool {
19686         v_1 := v.Args[1]
19687         v_0 := v.Args[0]
19688         b := v.Block
19689         // match: (Less64F x y)
19690         // result: (LessThanF (FCMPD x y))
19691         for {
19692                 x := v_0
19693                 y := v_1
19694                 v.reset(OpARM64LessThanF)
19695                 v0 := b.NewValue0(v.Pos, OpARM64FCMPD, types.TypeFlags)
19696                 v0.AddArg2(x, y)
19697                 v.AddArg(v0)
19698                 return true
19699         }
19700 }
19701 func rewriteValueARM64_OpLess64U(v *Value) bool {
19702         v_1 := v.Args[1]
19703         v_0 := v.Args[0]
19704         b := v.Block
19705         typ := &b.Func.Config.Types
19706         // match: (Less64U zero:(MOVDconst [0]) x)
19707         // result: (Neq64 zero x)
19708         for {
19709                 zero := v_0
19710                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19711                         break
19712                 }
19713                 x := v_1
19714                 v.reset(OpNeq64)
19715                 v.AddArg2(zero, x)
19716                 return true
19717         }
19718         // match: (Less64U x (MOVDconst [1]))
19719         // result: (Eq64 x (MOVDconst [0]))
19720         for {
19721                 x := v_0
19722                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
19723                         break
19724                 }
19725                 v.reset(OpEq64)
19726                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19727                 v0.AuxInt = int64ToAuxInt(0)
19728                 v.AddArg2(x, v0)
19729                 return true
19730         }
19731         // match: (Less64U x y)
19732         // result: (LessThanU (CMP x y))
19733         for {
19734                 x := v_0
19735                 y := v_1
19736                 v.reset(OpARM64LessThanU)
19737                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
19738                 v0.AddArg2(x, y)
19739                 v.AddArg(v0)
19740                 return true
19741         }
19742 }
19743 func rewriteValueARM64_OpLess8(v *Value) bool {
19744         v_1 := v.Args[1]
19745         v_0 := v.Args[0]
19746         b := v.Block
19747         typ := &b.Func.Config.Types
19748         // match: (Less8 x y)
19749         // result: (LessThan (CMPW (SignExt8to32 x) (SignExt8to32 y)))
19750         for {
19751                 x := v_0
19752                 y := v_1
19753                 v.reset(OpARM64LessThan)
19754                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19755                 v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
19756                 v1.AddArg(x)
19757                 v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
19758                 v2.AddArg(y)
19759                 v0.AddArg2(v1, v2)
19760                 v.AddArg(v0)
19761                 return true
19762         }
19763 }
19764 func rewriteValueARM64_OpLess8U(v *Value) bool {
19765         v_1 := v.Args[1]
19766         v_0 := v.Args[0]
19767         b := v.Block
19768         typ := &b.Func.Config.Types
19769         // match: (Less8U zero:(MOVDconst [0]) x)
19770         // result: (Neq8 zero x)
19771         for {
19772                 zero := v_0
19773                 if zero.Op != OpARM64MOVDconst || auxIntToInt64(zero.AuxInt) != 0 {
19774                         break
19775                 }
19776                 x := v_1
19777                 v.reset(OpNeq8)
19778                 v.AddArg2(zero, x)
19779                 return true
19780         }
19781         // match: (Less8U x (MOVDconst [1]))
19782         // result: (Eq8 x (MOVDconst [0]))
19783         for {
19784                 x := v_0
19785                 if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
19786                         break
19787                 }
19788                 v.reset(OpEq8)
19789                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
19790                 v0.AuxInt = int64ToAuxInt(0)
19791                 v.AddArg2(x, v0)
19792                 return true
19793         }
19794         // match: (Less8U x y)
19795         // result: (LessThanU (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
19796         for {
19797                 x := v_0
19798                 y := v_1
19799                 v.reset(OpARM64LessThanU)
19800                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
19801                 v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19802                 v1.AddArg(x)
19803                 v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
19804                 v2.AddArg(y)
19805                 v0.AddArg2(v1, v2)
19806                 v.AddArg(v0)
19807                 return true
19808         }
19809 }
19810 func rewriteValueARM64_OpLoad(v *Value) bool {
19811         v_1 := v.Args[1]
19812         v_0 := v.Args[0]
19813         // match: (Load <t> ptr mem)
19814         // cond: t.IsBoolean()
19815         // result: (MOVBUload ptr mem)
19816         for {
19817                 t := v.Type
19818                 ptr := v_0
19819                 mem := v_1
19820                 if !(t.IsBoolean()) {
19821                         break
19822                 }
19823                 v.reset(OpARM64MOVBUload)
19824                 v.AddArg2(ptr, mem)
19825                 return true
19826         }
19827         // match: (Load <t> ptr mem)
19828         // cond: (is8BitInt(t) && t.IsSigned())
19829         // result: (MOVBload ptr mem)
19830         for {
19831                 t := v.Type
19832                 ptr := v_0
19833                 mem := v_1
19834                 if !(is8BitInt(t) && t.IsSigned()) {
19835                         break
19836                 }
19837                 v.reset(OpARM64MOVBload)
19838                 v.AddArg2(ptr, mem)
19839                 return true
19840         }
19841         // match: (Load <t> ptr mem)
19842         // cond: (is8BitInt(t) && !t.IsSigned())
19843         // result: (MOVBUload ptr mem)
19844         for {
19845                 t := v.Type
19846                 ptr := v_0
19847                 mem := v_1
19848                 if !(is8BitInt(t) && !t.IsSigned()) {
19849                         break
19850                 }
19851                 v.reset(OpARM64MOVBUload)
19852                 v.AddArg2(ptr, mem)
19853                 return true
19854         }
19855         // match: (Load <t> ptr mem)
19856         // cond: (is16BitInt(t) && t.IsSigned())
19857         // result: (MOVHload ptr mem)
19858         for {
19859                 t := v.Type
19860                 ptr := v_0
19861                 mem := v_1
19862                 if !(is16BitInt(t) && t.IsSigned()) {
19863                         break
19864                 }
19865                 v.reset(OpARM64MOVHload)
19866                 v.AddArg2(ptr, mem)
19867                 return true
19868         }
19869         // match: (Load <t> ptr mem)
19870         // cond: (is16BitInt(t) && !t.IsSigned())
19871         // result: (MOVHUload ptr mem)
19872         for {
19873                 t := v.Type
19874                 ptr := v_0
19875                 mem := v_1
19876                 if !(is16BitInt(t) && !t.IsSigned()) {
19877                         break
19878                 }
19879                 v.reset(OpARM64MOVHUload)
19880                 v.AddArg2(ptr, mem)
19881                 return true
19882         }
19883         // match: (Load <t> ptr mem)
19884         // cond: (is32BitInt(t) && t.IsSigned())
19885         // result: (MOVWload ptr mem)
19886         for {
19887                 t := v.Type
19888                 ptr := v_0
19889                 mem := v_1
19890                 if !(is32BitInt(t) && t.IsSigned()) {
19891                         break
19892                 }
19893                 v.reset(OpARM64MOVWload)
19894                 v.AddArg2(ptr, mem)
19895                 return true
19896         }
19897         // match: (Load <t> ptr mem)
19898         // cond: (is32BitInt(t) && !t.IsSigned())
19899         // result: (MOVWUload ptr mem)
19900         for {
19901                 t := v.Type
19902                 ptr := v_0
19903                 mem := v_1
19904                 if !(is32BitInt(t) && !t.IsSigned()) {
19905                         break
19906                 }
19907                 v.reset(OpARM64MOVWUload)
19908                 v.AddArg2(ptr, mem)
19909                 return true
19910         }
19911         // match: (Load <t> ptr mem)
19912         // cond: (is64BitInt(t) || isPtr(t))
19913         // result: (MOVDload ptr mem)
19914         for {
19915                 t := v.Type
19916                 ptr := v_0
19917                 mem := v_1
19918                 if !(is64BitInt(t) || isPtr(t)) {
19919                         break
19920                 }
19921                 v.reset(OpARM64MOVDload)
19922                 v.AddArg2(ptr, mem)
19923                 return true
19924         }
19925         // match: (Load <t> ptr mem)
19926         // cond: is32BitFloat(t)
19927         // result: (FMOVSload ptr mem)
19928         for {
19929                 t := v.Type
19930                 ptr := v_0
19931                 mem := v_1
19932                 if !(is32BitFloat(t)) {
19933                         break
19934                 }
19935                 v.reset(OpARM64FMOVSload)
19936                 v.AddArg2(ptr, mem)
19937                 return true
19938         }
19939         // match: (Load <t> ptr mem)
19940         // cond: is64BitFloat(t)
19941         // result: (FMOVDload ptr mem)
19942         for {
19943                 t := v.Type
19944                 ptr := v_0
19945                 mem := v_1
19946                 if !(is64BitFloat(t)) {
19947                         break
19948                 }
19949                 v.reset(OpARM64FMOVDload)
19950                 v.AddArg2(ptr, mem)
19951                 return true
19952         }
19953         return false
19954 }
19955 func rewriteValueARM64_OpLocalAddr(v *Value) bool {
19956         v_1 := v.Args[1]
19957         v_0 := v.Args[0]
19958         b := v.Block
19959         typ := &b.Func.Config.Types
19960         // match: (LocalAddr <t> {sym} base mem)
19961         // cond: t.Elem().HasPointers()
19962         // result: (MOVDaddr {sym} (SPanchored base mem))
19963         for {
19964                 t := v.Type
19965                 sym := auxToSym(v.Aux)
19966                 base := v_0
19967                 mem := v_1
19968                 if !(t.Elem().HasPointers()) {
19969                         break
19970                 }
19971                 v.reset(OpARM64MOVDaddr)
19972                 v.Aux = symToAux(sym)
19973                 v0 := b.NewValue0(v.Pos, OpSPanchored, typ.Uintptr)
19974                 v0.AddArg2(base, mem)
19975                 v.AddArg(v0)
19976                 return true
19977         }
19978         // match: (LocalAddr <t> {sym} base _)
19979         // cond: !t.Elem().HasPointers()
19980         // result: (MOVDaddr {sym} base)
19981         for {
19982                 t := v.Type
19983                 sym := auxToSym(v.Aux)
19984                 base := v_0
19985                 if !(!t.Elem().HasPointers()) {
19986                         break
19987                 }
19988                 v.reset(OpARM64MOVDaddr)
19989                 v.Aux = symToAux(sym)
19990                 v.AddArg(base)
19991                 return true
19992         }
19993         return false
19994 }
19995 func rewriteValueARM64_OpLsh16x16(v *Value) bool {
19996         v_1 := v.Args[1]
19997         v_0 := v.Args[0]
19998         b := v.Block
19999         typ := &b.Func.Config.Types
20000         // match: (Lsh16x16 <t> x y)
20001         // cond: shiftIsBounded(v)
20002         // result: (SLL <t> x y)
20003         for {
20004                 t := v.Type
20005                 x := v_0
20006                 y := v_1
20007                 if !(shiftIsBounded(v)) {
20008                         break
20009                 }
20010                 v.reset(OpARM64SLL)
20011                 v.Type = t
20012                 v.AddArg2(x, y)
20013                 return true
20014         }
20015         // match: (Lsh16x16 <t> x y)
20016         // cond: !shiftIsBounded(v)
20017         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
20018         for {
20019                 t := v.Type
20020                 x := v_0
20021                 y := v_1
20022                 if !(!shiftIsBounded(v)) {
20023                         break
20024                 }
20025                 v.reset(OpARM64CSEL)
20026                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20027                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20028                 v0.AddArg2(x, y)
20029                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20030                 v1.AuxInt = int64ToAuxInt(0)
20031                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20032                 v2.AuxInt = int64ToAuxInt(64)
20033                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
20034                 v3.AddArg(y)
20035                 v2.AddArg(v3)
20036                 v.AddArg3(v0, v1, v2)
20037                 return true
20038         }
20039         return false
20040 }
20041 func rewriteValueARM64_OpLsh16x32(v *Value) bool {
20042         v_1 := v.Args[1]
20043         v_0 := v.Args[0]
20044         b := v.Block
20045         typ := &b.Func.Config.Types
20046         // match: (Lsh16x32 <t> x y)
20047         // cond: shiftIsBounded(v)
20048         // result: (SLL <t> x y)
20049         for {
20050                 t := v.Type
20051                 x := v_0
20052                 y := v_1
20053                 if !(shiftIsBounded(v)) {
20054                         break
20055                 }
20056                 v.reset(OpARM64SLL)
20057                 v.Type = t
20058                 v.AddArg2(x, y)
20059                 return true
20060         }
20061         // match: (Lsh16x32 <t> x y)
20062         // cond: !shiftIsBounded(v)
20063         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
20064         for {
20065                 t := v.Type
20066                 x := v_0
20067                 y := v_1
20068                 if !(!shiftIsBounded(v)) {
20069                         break
20070                 }
20071                 v.reset(OpARM64CSEL)
20072                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20073                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20074                 v0.AddArg2(x, y)
20075                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20076                 v1.AuxInt = int64ToAuxInt(0)
20077                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20078                 v2.AuxInt = int64ToAuxInt(64)
20079                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
20080                 v3.AddArg(y)
20081                 v2.AddArg(v3)
20082                 v.AddArg3(v0, v1, v2)
20083                 return true
20084         }
20085         return false
20086 }
20087 func rewriteValueARM64_OpLsh16x64(v *Value) bool {
20088         v_1 := v.Args[1]
20089         v_0 := v.Args[0]
20090         b := v.Block
20091         // match: (Lsh16x64 <t> x y)
20092         // cond: shiftIsBounded(v)
20093         // result: (SLL <t> x y)
20094         for {
20095                 t := v.Type
20096                 x := v_0
20097                 y := v_1
20098                 if !(shiftIsBounded(v)) {
20099                         break
20100                 }
20101                 v.reset(OpARM64SLL)
20102                 v.Type = t
20103                 v.AddArg2(x, y)
20104                 return true
20105         }
20106         // match: (Lsh16x64 <t> x y)
20107         // cond: !shiftIsBounded(v)
20108         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
20109         for {
20110                 t := v.Type
20111                 x := v_0
20112                 y := v_1
20113                 if !(!shiftIsBounded(v)) {
20114                         break
20115                 }
20116                 v.reset(OpARM64CSEL)
20117                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20118                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20119                 v0.AddArg2(x, y)
20120                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20121                 v1.AuxInt = int64ToAuxInt(0)
20122                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20123                 v2.AuxInt = int64ToAuxInt(64)
20124                 v2.AddArg(y)
20125                 v.AddArg3(v0, v1, v2)
20126                 return true
20127         }
20128         return false
20129 }
20130 func rewriteValueARM64_OpLsh16x8(v *Value) bool {
20131         v_1 := v.Args[1]
20132         v_0 := v.Args[0]
20133         b := v.Block
20134         typ := &b.Func.Config.Types
20135         // match: (Lsh16x8 <t> x y)
20136         // cond: shiftIsBounded(v)
20137         // result: (SLL <t> x y)
20138         for {
20139                 t := v.Type
20140                 x := v_0
20141                 y := v_1
20142                 if !(shiftIsBounded(v)) {
20143                         break
20144                 }
20145                 v.reset(OpARM64SLL)
20146                 v.Type = t
20147                 v.AddArg2(x, y)
20148                 return true
20149         }
20150         // match: (Lsh16x8 <t> x y)
20151         // cond: !shiftIsBounded(v)
20152         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
20153         for {
20154                 t := v.Type
20155                 x := v_0
20156                 y := v_1
20157                 if !(!shiftIsBounded(v)) {
20158                         break
20159                 }
20160                 v.reset(OpARM64CSEL)
20161                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20162                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20163                 v0.AddArg2(x, y)
20164                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20165                 v1.AuxInt = int64ToAuxInt(0)
20166                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20167                 v2.AuxInt = int64ToAuxInt(64)
20168                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
20169                 v3.AddArg(y)
20170                 v2.AddArg(v3)
20171                 v.AddArg3(v0, v1, v2)
20172                 return true
20173         }
20174         return false
20175 }
20176 func rewriteValueARM64_OpLsh32x16(v *Value) bool {
20177         v_1 := v.Args[1]
20178         v_0 := v.Args[0]
20179         b := v.Block
20180         typ := &b.Func.Config.Types
20181         // match: (Lsh32x16 <t> x y)
20182         // cond: shiftIsBounded(v)
20183         // result: (SLL <t> x y)
20184         for {
20185                 t := v.Type
20186                 x := v_0
20187                 y := v_1
20188                 if !(shiftIsBounded(v)) {
20189                         break
20190                 }
20191                 v.reset(OpARM64SLL)
20192                 v.Type = t
20193                 v.AddArg2(x, y)
20194                 return true
20195         }
20196         // match: (Lsh32x16 <t> x y)
20197         // cond: !shiftIsBounded(v)
20198         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
20199         for {
20200                 t := v.Type
20201                 x := v_0
20202                 y := v_1
20203                 if !(!shiftIsBounded(v)) {
20204                         break
20205                 }
20206                 v.reset(OpARM64CSEL)
20207                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20208                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20209                 v0.AddArg2(x, y)
20210                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20211                 v1.AuxInt = int64ToAuxInt(0)
20212                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20213                 v2.AuxInt = int64ToAuxInt(64)
20214                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
20215                 v3.AddArg(y)
20216                 v2.AddArg(v3)
20217                 v.AddArg3(v0, v1, v2)
20218                 return true
20219         }
20220         return false
20221 }
20222 func rewriteValueARM64_OpLsh32x32(v *Value) bool {
20223         v_1 := v.Args[1]
20224         v_0 := v.Args[0]
20225         b := v.Block
20226         typ := &b.Func.Config.Types
20227         // match: (Lsh32x32 <t> x y)
20228         // cond: shiftIsBounded(v)
20229         // result: (SLL <t> x y)
20230         for {
20231                 t := v.Type
20232                 x := v_0
20233                 y := v_1
20234                 if !(shiftIsBounded(v)) {
20235                         break
20236                 }
20237                 v.reset(OpARM64SLL)
20238                 v.Type = t
20239                 v.AddArg2(x, y)
20240                 return true
20241         }
20242         // match: (Lsh32x32 <t> x y)
20243         // cond: !shiftIsBounded(v)
20244         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
20245         for {
20246                 t := v.Type
20247                 x := v_0
20248                 y := v_1
20249                 if !(!shiftIsBounded(v)) {
20250                         break
20251                 }
20252                 v.reset(OpARM64CSEL)
20253                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20254                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20255                 v0.AddArg2(x, y)
20256                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20257                 v1.AuxInt = int64ToAuxInt(0)
20258                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20259                 v2.AuxInt = int64ToAuxInt(64)
20260                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
20261                 v3.AddArg(y)
20262                 v2.AddArg(v3)
20263                 v.AddArg3(v0, v1, v2)
20264                 return true
20265         }
20266         return false
20267 }
20268 func rewriteValueARM64_OpLsh32x64(v *Value) bool {
20269         v_1 := v.Args[1]
20270         v_0 := v.Args[0]
20271         b := v.Block
20272         // match: (Lsh32x64 <t> x y)
20273         // cond: shiftIsBounded(v)
20274         // result: (SLL <t> x y)
20275         for {
20276                 t := v.Type
20277                 x := v_0
20278                 y := v_1
20279                 if !(shiftIsBounded(v)) {
20280                         break
20281                 }
20282                 v.reset(OpARM64SLL)
20283                 v.Type = t
20284                 v.AddArg2(x, y)
20285                 return true
20286         }
20287         // match: (Lsh32x64 <t> x y)
20288         // cond: !shiftIsBounded(v)
20289         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
20290         for {
20291                 t := v.Type
20292                 x := v_0
20293                 y := v_1
20294                 if !(!shiftIsBounded(v)) {
20295                         break
20296                 }
20297                 v.reset(OpARM64CSEL)
20298                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20299                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20300                 v0.AddArg2(x, y)
20301                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20302                 v1.AuxInt = int64ToAuxInt(0)
20303                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20304                 v2.AuxInt = int64ToAuxInt(64)
20305                 v2.AddArg(y)
20306                 v.AddArg3(v0, v1, v2)
20307                 return true
20308         }
20309         return false
20310 }
20311 func rewriteValueARM64_OpLsh32x8(v *Value) bool {
20312         v_1 := v.Args[1]
20313         v_0 := v.Args[0]
20314         b := v.Block
20315         typ := &b.Func.Config.Types
20316         // match: (Lsh32x8 <t> x y)
20317         // cond: shiftIsBounded(v)
20318         // result: (SLL <t> x y)
20319         for {
20320                 t := v.Type
20321                 x := v_0
20322                 y := v_1
20323                 if !(shiftIsBounded(v)) {
20324                         break
20325                 }
20326                 v.reset(OpARM64SLL)
20327                 v.Type = t
20328                 v.AddArg2(x, y)
20329                 return true
20330         }
20331         // match: (Lsh32x8 <t> x y)
20332         // cond: !shiftIsBounded(v)
20333         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
20334         for {
20335                 t := v.Type
20336                 x := v_0
20337                 y := v_1
20338                 if !(!shiftIsBounded(v)) {
20339                         break
20340                 }
20341                 v.reset(OpARM64CSEL)
20342                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20343                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20344                 v0.AddArg2(x, y)
20345                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20346                 v1.AuxInt = int64ToAuxInt(0)
20347                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20348                 v2.AuxInt = int64ToAuxInt(64)
20349                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
20350                 v3.AddArg(y)
20351                 v2.AddArg(v3)
20352                 v.AddArg3(v0, v1, v2)
20353                 return true
20354         }
20355         return false
20356 }
20357 func rewriteValueARM64_OpLsh64x16(v *Value) bool {
20358         v_1 := v.Args[1]
20359         v_0 := v.Args[0]
20360         b := v.Block
20361         typ := &b.Func.Config.Types
20362         // match: (Lsh64x16 <t> x y)
20363         // cond: shiftIsBounded(v)
20364         // result: (SLL <t> x y)
20365         for {
20366                 t := v.Type
20367                 x := v_0
20368                 y := v_1
20369                 if !(shiftIsBounded(v)) {
20370                         break
20371                 }
20372                 v.reset(OpARM64SLL)
20373                 v.Type = t
20374                 v.AddArg2(x, y)
20375                 return true
20376         }
20377         // match: (Lsh64x16 <t> x y)
20378         // cond: !shiftIsBounded(v)
20379         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
20380         for {
20381                 t := v.Type
20382                 x := v_0
20383                 y := v_1
20384                 if !(!shiftIsBounded(v)) {
20385                         break
20386                 }
20387                 v.reset(OpARM64CSEL)
20388                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20389                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20390                 v0.AddArg2(x, y)
20391                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20392                 v1.AuxInt = int64ToAuxInt(0)
20393                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20394                 v2.AuxInt = int64ToAuxInt(64)
20395                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
20396                 v3.AddArg(y)
20397                 v2.AddArg(v3)
20398                 v.AddArg3(v0, v1, v2)
20399                 return true
20400         }
20401         return false
20402 }
20403 func rewriteValueARM64_OpLsh64x32(v *Value) bool {
20404         v_1 := v.Args[1]
20405         v_0 := v.Args[0]
20406         b := v.Block
20407         typ := &b.Func.Config.Types
20408         // match: (Lsh64x32 <t> x y)
20409         // cond: shiftIsBounded(v)
20410         // result: (SLL <t> x y)
20411         for {
20412                 t := v.Type
20413                 x := v_0
20414                 y := v_1
20415                 if !(shiftIsBounded(v)) {
20416                         break
20417                 }
20418                 v.reset(OpARM64SLL)
20419                 v.Type = t
20420                 v.AddArg2(x, y)
20421                 return true
20422         }
20423         // match: (Lsh64x32 <t> x y)
20424         // cond: !shiftIsBounded(v)
20425         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
20426         for {
20427                 t := v.Type
20428                 x := v_0
20429                 y := v_1
20430                 if !(!shiftIsBounded(v)) {
20431                         break
20432                 }
20433                 v.reset(OpARM64CSEL)
20434                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20435                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20436                 v0.AddArg2(x, y)
20437                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20438                 v1.AuxInt = int64ToAuxInt(0)
20439                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20440                 v2.AuxInt = int64ToAuxInt(64)
20441                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
20442                 v3.AddArg(y)
20443                 v2.AddArg(v3)
20444                 v.AddArg3(v0, v1, v2)
20445                 return true
20446         }
20447         return false
20448 }
20449 func rewriteValueARM64_OpLsh64x64(v *Value) bool {
20450         v_1 := v.Args[1]
20451         v_0 := v.Args[0]
20452         b := v.Block
20453         // match: (Lsh64x64 <t> x y)
20454         // cond: shiftIsBounded(v)
20455         // result: (SLL <t> x y)
20456         for {
20457                 t := v.Type
20458                 x := v_0
20459                 y := v_1
20460                 if !(shiftIsBounded(v)) {
20461                         break
20462                 }
20463                 v.reset(OpARM64SLL)
20464                 v.Type = t
20465                 v.AddArg2(x, y)
20466                 return true
20467         }
20468         // match: (Lsh64x64 <t> x y)
20469         // cond: !shiftIsBounded(v)
20470         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
20471         for {
20472                 t := v.Type
20473                 x := v_0
20474                 y := v_1
20475                 if !(!shiftIsBounded(v)) {
20476                         break
20477                 }
20478                 v.reset(OpARM64CSEL)
20479                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20480                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20481                 v0.AddArg2(x, y)
20482                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20483                 v1.AuxInt = int64ToAuxInt(0)
20484                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20485                 v2.AuxInt = int64ToAuxInt(64)
20486                 v2.AddArg(y)
20487                 v.AddArg3(v0, v1, v2)
20488                 return true
20489         }
20490         return false
20491 }
20492 func rewriteValueARM64_OpLsh64x8(v *Value) bool {
20493         v_1 := v.Args[1]
20494         v_0 := v.Args[0]
20495         b := v.Block
20496         typ := &b.Func.Config.Types
20497         // match: (Lsh64x8 <t> x y)
20498         // cond: shiftIsBounded(v)
20499         // result: (SLL <t> x y)
20500         for {
20501                 t := v.Type
20502                 x := v_0
20503                 y := v_1
20504                 if !(shiftIsBounded(v)) {
20505                         break
20506                 }
20507                 v.reset(OpARM64SLL)
20508                 v.Type = t
20509                 v.AddArg2(x, y)
20510                 return true
20511         }
20512         // match: (Lsh64x8 <t> x y)
20513         // cond: !shiftIsBounded(v)
20514         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
20515         for {
20516                 t := v.Type
20517                 x := v_0
20518                 y := v_1
20519                 if !(!shiftIsBounded(v)) {
20520                         break
20521                 }
20522                 v.reset(OpARM64CSEL)
20523                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20524                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20525                 v0.AddArg2(x, y)
20526                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20527                 v1.AuxInt = int64ToAuxInt(0)
20528                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20529                 v2.AuxInt = int64ToAuxInt(64)
20530                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
20531                 v3.AddArg(y)
20532                 v2.AddArg(v3)
20533                 v.AddArg3(v0, v1, v2)
20534                 return true
20535         }
20536         return false
20537 }
20538 func rewriteValueARM64_OpLsh8x16(v *Value) bool {
20539         v_1 := v.Args[1]
20540         v_0 := v.Args[0]
20541         b := v.Block
20542         typ := &b.Func.Config.Types
20543         // match: (Lsh8x16 <t> x y)
20544         // cond: shiftIsBounded(v)
20545         // result: (SLL <t> x y)
20546         for {
20547                 t := v.Type
20548                 x := v_0
20549                 y := v_1
20550                 if !(shiftIsBounded(v)) {
20551                         break
20552                 }
20553                 v.reset(OpARM64SLL)
20554                 v.Type = t
20555                 v.AddArg2(x, y)
20556                 return true
20557         }
20558         // match: (Lsh8x16 <t> x y)
20559         // cond: !shiftIsBounded(v)
20560         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
20561         for {
20562                 t := v.Type
20563                 x := v_0
20564                 y := v_1
20565                 if !(!shiftIsBounded(v)) {
20566                         break
20567                 }
20568                 v.reset(OpARM64CSEL)
20569                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20570                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20571                 v0.AddArg2(x, y)
20572                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20573                 v1.AuxInt = int64ToAuxInt(0)
20574                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20575                 v2.AuxInt = int64ToAuxInt(64)
20576                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
20577                 v3.AddArg(y)
20578                 v2.AddArg(v3)
20579                 v.AddArg3(v0, v1, v2)
20580                 return true
20581         }
20582         return false
20583 }
20584 func rewriteValueARM64_OpLsh8x32(v *Value) bool {
20585         v_1 := v.Args[1]
20586         v_0 := v.Args[0]
20587         b := v.Block
20588         typ := &b.Func.Config.Types
20589         // match: (Lsh8x32 <t> x y)
20590         // cond: shiftIsBounded(v)
20591         // result: (SLL <t> x y)
20592         for {
20593                 t := v.Type
20594                 x := v_0
20595                 y := v_1
20596                 if !(shiftIsBounded(v)) {
20597                         break
20598                 }
20599                 v.reset(OpARM64SLL)
20600                 v.Type = t
20601                 v.AddArg2(x, y)
20602                 return true
20603         }
20604         // match: (Lsh8x32 <t> x y)
20605         // cond: !shiftIsBounded(v)
20606         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
20607         for {
20608                 t := v.Type
20609                 x := v_0
20610                 y := v_1
20611                 if !(!shiftIsBounded(v)) {
20612                         break
20613                 }
20614                 v.reset(OpARM64CSEL)
20615                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20616                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20617                 v0.AddArg2(x, y)
20618                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20619                 v1.AuxInt = int64ToAuxInt(0)
20620                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20621                 v2.AuxInt = int64ToAuxInt(64)
20622                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
20623                 v3.AddArg(y)
20624                 v2.AddArg(v3)
20625                 v.AddArg3(v0, v1, v2)
20626                 return true
20627         }
20628         return false
20629 }
20630 func rewriteValueARM64_OpLsh8x64(v *Value) bool {
20631         v_1 := v.Args[1]
20632         v_0 := v.Args[0]
20633         b := v.Block
20634         // match: (Lsh8x64 <t> x y)
20635         // cond: shiftIsBounded(v)
20636         // result: (SLL <t> x y)
20637         for {
20638                 t := v.Type
20639                 x := v_0
20640                 y := v_1
20641                 if !(shiftIsBounded(v)) {
20642                         break
20643                 }
20644                 v.reset(OpARM64SLL)
20645                 v.Type = t
20646                 v.AddArg2(x, y)
20647                 return true
20648         }
20649         // match: (Lsh8x64 <t> x y)
20650         // cond: !shiftIsBounded(v)
20651         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
20652         for {
20653                 t := v.Type
20654                 x := v_0
20655                 y := v_1
20656                 if !(!shiftIsBounded(v)) {
20657                         break
20658                 }
20659                 v.reset(OpARM64CSEL)
20660                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20661                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20662                 v0.AddArg2(x, y)
20663                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20664                 v1.AuxInt = int64ToAuxInt(0)
20665                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20666                 v2.AuxInt = int64ToAuxInt(64)
20667                 v2.AddArg(y)
20668                 v.AddArg3(v0, v1, v2)
20669                 return true
20670         }
20671         return false
20672 }
20673 func rewriteValueARM64_OpLsh8x8(v *Value) bool {
20674         v_1 := v.Args[1]
20675         v_0 := v.Args[0]
20676         b := v.Block
20677         typ := &b.Func.Config.Types
20678         // match: (Lsh8x8 <t> x y)
20679         // cond: shiftIsBounded(v)
20680         // result: (SLL <t> x y)
20681         for {
20682                 t := v.Type
20683                 x := v_0
20684                 y := v_1
20685                 if !(shiftIsBounded(v)) {
20686                         break
20687                 }
20688                 v.reset(OpARM64SLL)
20689                 v.Type = t
20690                 v.AddArg2(x, y)
20691                 return true
20692         }
20693         // match: (Lsh8x8 <t> x y)
20694         // cond: !shiftIsBounded(v)
20695         // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
20696         for {
20697                 t := v.Type
20698                 x := v_0
20699                 y := v_1
20700                 if !(!shiftIsBounded(v)) {
20701                         break
20702                 }
20703                 v.reset(OpARM64CSEL)
20704                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
20705                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
20706                 v0.AddArg2(x, y)
20707                 v1 := b.NewValue0(v.Pos, OpConst64, t)
20708                 v1.AuxInt = int64ToAuxInt(0)
20709                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
20710                 v2.AuxInt = int64ToAuxInt(64)
20711                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
20712                 v3.AddArg(y)
20713                 v2.AddArg(v3)
20714                 v.AddArg3(v0, v1, v2)
20715                 return true
20716         }
20717         return false
20718 }
20719 func rewriteValueARM64_OpMod16(v *Value) bool {
20720         v_1 := v.Args[1]
20721         v_0 := v.Args[0]
20722         b := v.Block
20723         typ := &b.Func.Config.Types
20724         // match: (Mod16 x y)
20725         // result: (MODW (SignExt16to32 x) (SignExt16to32 y))
20726         for {
20727                 x := v_0
20728                 y := v_1
20729                 v.reset(OpARM64MODW)
20730                 v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
20731                 v0.AddArg(x)
20732                 v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
20733                 v1.AddArg(y)
20734                 v.AddArg2(v0, v1)
20735                 return true
20736         }
20737 }
20738 func rewriteValueARM64_OpMod16u(v *Value) bool {
20739         v_1 := v.Args[1]
20740         v_0 := v.Args[0]
20741         b := v.Block
20742         typ := &b.Func.Config.Types
20743         // match: (Mod16u x y)
20744         // result: (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y))
20745         for {
20746                 x := v_0
20747                 y := v_1
20748                 v.reset(OpARM64UMODW)
20749                 v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
20750                 v0.AddArg(x)
20751                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
20752                 v1.AddArg(y)
20753                 v.AddArg2(v0, v1)
20754                 return true
20755         }
20756 }
20757 func rewriteValueARM64_OpMod32(v *Value) bool {
20758         v_1 := v.Args[1]
20759         v_0 := v.Args[0]
20760         // match: (Mod32 x y)
20761         // result: (MODW x y)
20762         for {
20763                 x := v_0
20764                 y := v_1
20765                 v.reset(OpARM64MODW)
20766                 v.AddArg2(x, y)
20767                 return true
20768         }
20769 }
20770 func rewriteValueARM64_OpMod64(v *Value) bool {
20771         v_1 := v.Args[1]
20772         v_0 := v.Args[0]
20773         // match: (Mod64 x y)
20774         // result: (MOD x y)
20775         for {
20776                 x := v_0
20777                 y := v_1
20778                 v.reset(OpARM64MOD)
20779                 v.AddArg2(x, y)
20780                 return true
20781         }
20782 }
20783 func rewriteValueARM64_OpMod8(v *Value) bool {
20784         v_1 := v.Args[1]
20785         v_0 := v.Args[0]
20786         b := v.Block
20787         typ := &b.Func.Config.Types
20788         // match: (Mod8 x y)
20789         // result: (MODW (SignExt8to32 x) (SignExt8to32 y))
20790         for {
20791                 x := v_0
20792                 y := v_1
20793                 v.reset(OpARM64MODW)
20794                 v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
20795                 v0.AddArg(x)
20796                 v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
20797                 v1.AddArg(y)
20798                 v.AddArg2(v0, v1)
20799                 return true
20800         }
20801 }
20802 func rewriteValueARM64_OpMod8u(v *Value) bool {
20803         v_1 := v.Args[1]
20804         v_0 := v.Args[0]
20805         b := v.Block
20806         typ := &b.Func.Config.Types
20807         // match: (Mod8u x y)
20808         // result: (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y))
20809         for {
20810                 x := v_0
20811                 y := v_1
20812                 v.reset(OpARM64UMODW)
20813                 v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
20814                 v0.AddArg(x)
20815                 v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
20816                 v1.AddArg(y)
20817                 v.AddArg2(v0, v1)
20818                 return true
20819         }
20820 }
20821 func rewriteValueARM64_OpMove(v *Value) bool {
20822         v_2 := v.Args[2]
20823         v_1 := v.Args[1]
20824         v_0 := v.Args[0]
20825         b := v.Block
20826         config := b.Func.Config
20827         typ := &b.Func.Config.Types
20828         // match: (Move [0] _ _ mem)
20829         // result: mem
20830         for {
20831                 if auxIntToInt64(v.AuxInt) != 0 {
20832                         break
20833                 }
20834                 mem := v_2
20835                 v.copyOf(mem)
20836                 return true
20837         }
20838         // match: (Move [1] dst src mem)
20839         // result: (MOVBstore dst (MOVBUload src mem) mem)
20840         for {
20841                 if auxIntToInt64(v.AuxInt) != 1 {
20842                         break
20843                 }
20844                 dst := v_0
20845                 src := v_1
20846                 mem := v_2
20847                 v.reset(OpARM64MOVBstore)
20848                 v0 := b.NewValue0(v.Pos, OpARM64MOVBUload, typ.UInt8)
20849                 v0.AddArg2(src, mem)
20850                 v.AddArg3(dst, v0, mem)
20851                 return true
20852         }
20853         // match: (Move [2] dst src mem)
20854         // result: (MOVHstore dst (MOVHUload src mem) mem)
20855         for {
20856                 if auxIntToInt64(v.AuxInt) != 2 {
20857                         break
20858                 }
20859                 dst := v_0
20860                 src := v_1
20861                 mem := v_2
20862                 v.reset(OpARM64MOVHstore)
20863                 v0 := b.NewValue0(v.Pos, OpARM64MOVHUload, typ.UInt16)
20864                 v0.AddArg2(src, mem)
20865                 v.AddArg3(dst, v0, mem)
20866                 return true
20867         }
20868         // match: (Move [3] dst src mem)
20869         // result: (MOVBstore [2] dst (MOVBUload [2] src mem) (MOVHstore dst (MOVHUload src mem) mem))
20870         for {
20871                 if auxIntToInt64(v.AuxInt) != 3 {
20872                         break
20873                 }
20874                 dst := v_0
20875                 src := v_1
20876                 mem := v_2
20877                 v.reset(OpARM64MOVBstore)
20878                 v.AuxInt = int32ToAuxInt(2)
20879                 v0 := b.NewValue0(v.Pos, OpARM64MOVBUload, typ.UInt8)
20880                 v0.AuxInt = int32ToAuxInt(2)
20881                 v0.AddArg2(src, mem)
20882                 v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
20883                 v2 := b.NewValue0(v.Pos, OpARM64MOVHUload, typ.UInt16)
20884                 v2.AddArg2(src, mem)
20885                 v1.AddArg3(dst, v2, mem)
20886                 v.AddArg3(dst, v0, v1)
20887                 return true
20888         }
20889         // match: (Move [4] dst src mem)
20890         // result: (MOVWstore dst (MOVWUload src mem) mem)
20891         for {
20892                 if auxIntToInt64(v.AuxInt) != 4 {
20893                         break
20894                 }
20895                 dst := v_0
20896                 src := v_1
20897                 mem := v_2
20898                 v.reset(OpARM64MOVWstore)
20899                 v0 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
20900                 v0.AddArg2(src, mem)
20901                 v.AddArg3(dst, v0, mem)
20902                 return true
20903         }
20904         // match: (Move [5] dst src mem)
20905         // result: (MOVBstore [4] dst (MOVBUload [4] src mem) (MOVWstore dst (MOVWUload src mem) mem))
20906         for {
20907                 if auxIntToInt64(v.AuxInt) != 5 {
20908                         break
20909                 }
20910                 dst := v_0
20911                 src := v_1
20912                 mem := v_2
20913                 v.reset(OpARM64MOVBstore)
20914                 v.AuxInt = int32ToAuxInt(4)
20915                 v0 := b.NewValue0(v.Pos, OpARM64MOVBUload, typ.UInt8)
20916                 v0.AuxInt = int32ToAuxInt(4)
20917                 v0.AddArg2(src, mem)
20918                 v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
20919                 v2 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
20920                 v2.AddArg2(src, mem)
20921                 v1.AddArg3(dst, v2, mem)
20922                 v.AddArg3(dst, v0, v1)
20923                 return true
20924         }
20925         // match: (Move [6] dst src mem)
20926         // result: (MOVHstore [4] dst (MOVHUload [4] src mem) (MOVWstore dst (MOVWUload src mem) mem))
20927         for {
20928                 if auxIntToInt64(v.AuxInt) != 6 {
20929                         break
20930                 }
20931                 dst := v_0
20932                 src := v_1
20933                 mem := v_2
20934                 v.reset(OpARM64MOVHstore)
20935                 v.AuxInt = int32ToAuxInt(4)
20936                 v0 := b.NewValue0(v.Pos, OpARM64MOVHUload, typ.UInt16)
20937                 v0.AuxInt = int32ToAuxInt(4)
20938                 v0.AddArg2(src, mem)
20939                 v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
20940                 v2 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
20941                 v2.AddArg2(src, mem)
20942                 v1.AddArg3(dst, v2, mem)
20943                 v.AddArg3(dst, v0, v1)
20944                 return true
20945         }
20946         // match: (Move [7] dst src mem)
20947         // result: (MOVWstore [3] dst (MOVWUload [3] src mem) (MOVWstore dst (MOVWUload src mem) mem))
20948         for {
20949                 if auxIntToInt64(v.AuxInt) != 7 {
20950                         break
20951                 }
20952                 dst := v_0
20953                 src := v_1
20954                 mem := v_2
20955                 v.reset(OpARM64MOVWstore)
20956                 v.AuxInt = int32ToAuxInt(3)
20957                 v0 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
20958                 v0.AuxInt = int32ToAuxInt(3)
20959                 v0.AddArg2(src, mem)
20960                 v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
20961                 v2 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
20962                 v2.AddArg2(src, mem)
20963                 v1.AddArg3(dst, v2, mem)
20964                 v.AddArg3(dst, v0, v1)
20965                 return true
20966         }
20967         // match: (Move [8] dst src mem)
20968         // result: (MOVDstore dst (MOVDload src mem) mem)
20969         for {
20970                 if auxIntToInt64(v.AuxInt) != 8 {
20971                         break
20972                 }
20973                 dst := v_0
20974                 src := v_1
20975                 mem := v_2
20976                 v.reset(OpARM64MOVDstore)
20977                 v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
20978                 v0.AddArg2(src, mem)
20979                 v.AddArg3(dst, v0, mem)
20980                 return true
20981         }
20982         // match: (Move [9] dst src mem)
20983         // result: (MOVBstore [8] dst (MOVBUload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))
20984         for {
20985                 if auxIntToInt64(v.AuxInt) != 9 {
20986                         break
20987                 }
20988                 dst := v_0
20989                 src := v_1
20990                 mem := v_2
20991                 v.reset(OpARM64MOVBstore)
20992                 v.AuxInt = int32ToAuxInt(8)
20993                 v0 := b.NewValue0(v.Pos, OpARM64MOVBUload, typ.UInt8)
20994                 v0.AuxInt = int32ToAuxInt(8)
20995                 v0.AddArg2(src, mem)
20996                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
20997                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
20998                 v2.AddArg2(src, mem)
20999                 v1.AddArg3(dst, v2, mem)
21000                 v.AddArg3(dst, v0, v1)
21001                 return true
21002         }
21003         // match: (Move [10] dst src mem)
21004         // result: (MOVHstore [8] dst (MOVHUload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))
21005         for {
21006                 if auxIntToInt64(v.AuxInt) != 10 {
21007                         break
21008                 }
21009                 dst := v_0
21010                 src := v_1
21011                 mem := v_2
21012                 v.reset(OpARM64MOVHstore)
21013                 v.AuxInt = int32ToAuxInt(8)
21014                 v0 := b.NewValue0(v.Pos, OpARM64MOVHUload, typ.UInt16)
21015                 v0.AuxInt = int32ToAuxInt(8)
21016                 v0.AddArg2(src, mem)
21017                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
21018                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21019                 v2.AddArg2(src, mem)
21020                 v1.AddArg3(dst, v2, mem)
21021                 v.AddArg3(dst, v0, v1)
21022                 return true
21023         }
21024         // match: (Move [11] dst src mem)
21025         // result: (MOVDstore [3] dst (MOVDload [3] src mem) (MOVDstore dst (MOVDload src mem) mem))
21026         for {
21027                 if auxIntToInt64(v.AuxInt) != 11 {
21028                         break
21029                 }
21030                 dst := v_0
21031                 src := v_1
21032                 mem := v_2
21033                 v.reset(OpARM64MOVDstore)
21034                 v.AuxInt = int32ToAuxInt(3)
21035                 v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21036                 v0.AuxInt = int32ToAuxInt(3)
21037                 v0.AddArg2(src, mem)
21038                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
21039                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21040                 v2.AddArg2(src, mem)
21041                 v1.AddArg3(dst, v2, mem)
21042                 v.AddArg3(dst, v0, v1)
21043                 return true
21044         }
21045         // match: (Move [12] dst src mem)
21046         // result: (MOVWstore [8] dst (MOVWUload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))
21047         for {
21048                 if auxIntToInt64(v.AuxInt) != 12 {
21049                         break
21050                 }
21051                 dst := v_0
21052                 src := v_1
21053                 mem := v_2
21054                 v.reset(OpARM64MOVWstore)
21055                 v.AuxInt = int32ToAuxInt(8)
21056                 v0 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
21057                 v0.AuxInt = int32ToAuxInt(8)
21058                 v0.AddArg2(src, mem)
21059                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
21060                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21061                 v2.AddArg2(src, mem)
21062                 v1.AddArg3(dst, v2, mem)
21063                 v.AddArg3(dst, v0, v1)
21064                 return true
21065         }
21066         // match: (Move [13] dst src mem)
21067         // result: (MOVDstore [5] dst (MOVDload [5] src mem) (MOVDstore dst (MOVDload src mem) mem))
21068         for {
21069                 if auxIntToInt64(v.AuxInt) != 13 {
21070                         break
21071                 }
21072                 dst := v_0
21073                 src := v_1
21074                 mem := v_2
21075                 v.reset(OpARM64MOVDstore)
21076                 v.AuxInt = int32ToAuxInt(5)
21077                 v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21078                 v0.AuxInt = int32ToAuxInt(5)
21079                 v0.AddArg2(src, mem)
21080                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
21081                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21082                 v2.AddArg2(src, mem)
21083                 v1.AddArg3(dst, v2, mem)
21084                 v.AddArg3(dst, v0, v1)
21085                 return true
21086         }
21087         // match: (Move [14] dst src mem)
21088         // result: (MOVDstore [6] dst (MOVDload [6] src mem) (MOVDstore dst (MOVDload src mem) mem))
21089         for {
21090                 if auxIntToInt64(v.AuxInt) != 14 {
21091                         break
21092                 }
21093                 dst := v_0
21094                 src := v_1
21095                 mem := v_2
21096                 v.reset(OpARM64MOVDstore)
21097                 v.AuxInt = int32ToAuxInt(6)
21098                 v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21099                 v0.AuxInt = int32ToAuxInt(6)
21100                 v0.AddArg2(src, mem)
21101                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
21102                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21103                 v2.AddArg2(src, mem)
21104                 v1.AddArg3(dst, v2, mem)
21105                 v.AddArg3(dst, v0, v1)
21106                 return true
21107         }
21108         // match: (Move [15] dst src mem)
21109         // result: (MOVDstore [7] dst (MOVDload [7] src mem) (MOVDstore dst (MOVDload src mem) mem))
21110         for {
21111                 if auxIntToInt64(v.AuxInt) != 15 {
21112                         break
21113                 }
21114                 dst := v_0
21115                 src := v_1
21116                 mem := v_2
21117                 v.reset(OpARM64MOVDstore)
21118                 v.AuxInt = int32ToAuxInt(7)
21119                 v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21120                 v0.AuxInt = int32ToAuxInt(7)
21121                 v0.AddArg2(src, mem)
21122                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
21123                 v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
21124                 v2.AddArg2(src, mem)
21125                 v1.AddArg3(dst, v2, mem)
21126                 v.AddArg3(dst, v0, v1)
21127                 return true
21128         }
21129         // match: (Move [16] dst src mem)
21130         // result: (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem)
21131         for {
21132                 if auxIntToInt64(v.AuxInt) != 16 {
21133                         break
21134                 }
21135                 dst := v_0
21136                 src := v_1
21137                 mem := v_2
21138                 v.reset(OpARM64STP)
21139                 v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21140                 v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21141                 v1.AddArg2(src, mem)
21142                 v0.AddArg(v1)
21143                 v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21144                 v2.AddArg(v1)
21145                 v.AddArg4(dst, v0, v2, mem)
21146                 return true
21147         }
21148         // match: (Move [32] dst src mem)
21149         // result: (STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem)) (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))
21150         for {
21151                 if auxIntToInt64(v.AuxInt) != 32 {
21152                         break
21153                 }
21154                 dst := v_0
21155                 src := v_1
21156                 mem := v_2
21157                 v.reset(OpARM64STP)
21158                 v.AuxInt = int32ToAuxInt(16)
21159                 v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21160                 v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21161                 v1.AuxInt = int32ToAuxInt(16)
21162                 v1.AddArg2(src, mem)
21163                 v0.AddArg(v1)
21164                 v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21165                 v2.AddArg(v1)
21166                 v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
21167                 v4 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21168                 v5 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21169                 v5.AddArg2(src, mem)
21170                 v4.AddArg(v5)
21171                 v6 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21172                 v6.AddArg(v5)
21173                 v3.AddArg4(dst, v4, v6, mem)
21174                 v.AddArg4(dst, v0, v2, v3)
21175                 return true
21176         }
21177         // match: (Move [48] dst src mem)
21178         // result: (STP [32] dst (Select0 <typ.UInt64> (LDP [32] src mem)) (Select1 <typ.UInt64> (LDP [32] src mem)) (STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem)) (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem)))
21179         for {
21180                 if auxIntToInt64(v.AuxInt) != 48 {
21181                         break
21182                 }
21183                 dst := v_0
21184                 src := v_1
21185                 mem := v_2
21186                 v.reset(OpARM64STP)
21187                 v.AuxInt = int32ToAuxInt(32)
21188                 v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21189                 v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21190                 v1.AuxInt = int32ToAuxInt(32)
21191                 v1.AddArg2(src, mem)
21192                 v0.AddArg(v1)
21193                 v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21194                 v2.AddArg(v1)
21195                 v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
21196                 v3.AuxInt = int32ToAuxInt(16)
21197                 v4 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21198                 v5 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21199                 v5.AuxInt = int32ToAuxInt(16)
21200                 v5.AddArg2(src, mem)
21201                 v4.AddArg(v5)
21202                 v6 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21203                 v6.AddArg(v5)
21204                 v7 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
21205                 v8 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21206                 v9 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21207                 v9.AddArg2(src, mem)
21208                 v8.AddArg(v9)
21209                 v10 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21210                 v10.AddArg(v9)
21211                 v7.AddArg4(dst, v8, v10, mem)
21212                 v3.AddArg4(dst, v4, v6, v7)
21213                 v.AddArg4(dst, v0, v2, v3)
21214                 return true
21215         }
21216         // match: (Move [64] dst src mem)
21217         // result: (STP [48] dst (Select0 <typ.UInt64> (LDP [48] src mem)) (Select1 <typ.UInt64> (LDP [48] src mem)) (STP [32] dst (Select0 <typ.UInt64> (LDP [32] src mem)) (Select1 <typ.UInt64> (LDP [32] src mem)) (STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem)) (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))))
21218         for {
21219                 if auxIntToInt64(v.AuxInt) != 64 {
21220                         break
21221                 }
21222                 dst := v_0
21223                 src := v_1
21224                 mem := v_2
21225                 v.reset(OpARM64STP)
21226                 v.AuxInt = int32ToAuxInt(48)
21227                 v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21228                 v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21229                 v1.AuxInt = int32ToAuxInt(48)
21230                 v1.AddArg2(src, mem)
21231                 v0.AddArg(v1)
21232                 v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21233                 v2.AddArg(v1)
21234                 v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
21235                 v3.AuxInt = int32ToAuxInt(32)
21236                 v4 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21237                 v5 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21238                 v5.AuxInt = int32ToAuxInt(32)
21239                 v5.AddArg2(src, mem)
21240                 v4.AddArg(v5)
21241                 v6 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21242                 v6.AddArg(v5)
21243                 v7 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
21244                 v7.AuxInt = int32ToAuxInt(16)
21245                 v8 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21246                 v9 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21247                 v9.AuxInt = int32ToAuxInt(16)
21248                 v9.AddArg2(src, mem)
21249                 v8.AddArg(v9)
21250                 v10 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21251                 v10.AddArg(v9)
21252                 v11 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
21253                 v12 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
21254                 v13 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
21255                 v13.AddArg2(src, mem)
21256                 v12.AddArg(v13)
21257                 v14 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
21258                 v14.AddArg(v13)
21259                 v11.AddArg4(dst, v12, v14, mem)
21260                 v7.AddArg4(dst, v8, v10, v11)
21261                 v3.AddArg4(dst, v4, v6, v7)
21262                 v.AddArg4(dst, v0, v2, v3)
21263                 return true
21264         }
21265         // match: (Move [s] dst src mem)
21266         // cond: s%16 != 0 && s%16 <= 8 && s > 16
21267         // result: (Move [8] (OffPtr <dst.Type> dst [s-8]) (OffPtr <src.Type> src [s-8]) (Move [s-s%16] dst src mem))
21268         for {
21269                 s := auxIntToInt64(v.AuxInt)
21270                 dst := v_0
21271                 src := v_1
21272                 mem := v_2
21273                 if !(s%16 != 0 && s%16 <= 8 && s > 16) {
21274                         break
21275                 }
21276                 v.reset(OpMove)
21277                 v.AuxInt = int64ToAuxInt(8)
21278                 v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
21279                 v0.AuxInt = int64ToAuxInt(s - 8)
21280                 v0.AddArg(dst)
21281                 v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
21282                 v1.AuxInt = int64ToAuxInt(s - 8)
21283                 v1.AddArg(src)
21284                 v2 := b.NewValue0(v.Pos, OpMove, types.TypeMem)
21285                 v2.AuxInt = int64ToAuxInt(s - s%16)
21286                 v2.AddArg3(dst, src, mem)
21287                 v.AddArg3(v0, v1, v2)
21288                 return true
21289         }
21290         // match: (Move [s] dst src mem)
21291         // cond: s%16 != 0 && s%16 > 8 && s > 16
21292         // result: (Move [16] (OffPtr <dst.Type> dst [s-16]) (OffPtr <src.Type> src [s-16]) (Move [s-s%16] dst src mem))
21293         for {
21294                 s := auxIntToInt64(v.AuxInt)
21295                 dst := v_0
21296                 src := v_1
21297                 mem := v_2
21298                 if !(s%16 != 0 && s%16 > 8 && s > 16) {
21299                         break
21300                 }
21301                 v.reset(OpMove)
21302                 v.AuxInt = int64ToAuxInt(16)
21303                 v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
21304                 v0.AuxInt = int64ToAuxInt(s - 16)
21305                 v0.AddArg(dst)
21306                 v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
21307                 v1.AuxInt = int64ToAuxInt(s - 16)
21308                 v1.AddArg(src)
21309                 v2 := b.NewValue0(v.Pos, OpMove, types.TypeMem)
21310                 v2.AuxInt = int64ToAuxInt(s - s%16)
21311                 v2.AddArg3(dst, src, mem)
21312                 v.AddArg3(v0, v1, v2)
21313                 return true
21314         }
21315         // match: (Move [s] dst src mem)
21316         // cond: s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s)
21317         // result: (DUFFCOPY [8 * (64 - s/16)] dst src mem)
21318         for {
21319                 s := auxIntToInt64(v.AuxInt)
21320                 dst := v_0
21321                 src := v_1
21322                 mem := v_2
21323                 if !(s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s)) {
21324                         break
21325                 }
21326                 v.reset(OpARM64DUFFCOPY)
21327                 v.AuxInt = int64ToAuxInt(8 * (64 - s/16))
21328                 v.AddArg3(dst, src, mem)
21329                 return true
21330         }
21331         // match: (Move [s] dst src mem)
21332         // cond: s%16 == 0 && (s > 16*64 || config.noDuffDevice) && logLargeCopy(v, s)
21333         // result: (LoweredMove dst src (ADDconst <src.Type> src [s-16]) mem)
21334         for {
21335                 s := auxIntToInt64(v.AuxInt)
21336                 dst := v_0
21337                 src := v_1
21338                 mem := v_2
21339                 if !(s%16 == 0 && (s > 16*64 || config.noDuffDevice) && logLargeCopy(v, s)) {
21340                         break
21341                 }
21342                 v.reset(OpARM64LoweredMove)
21343                 v0 := b.NewValue0(v.Pos, OpARM64ADDconst, src.Type)
21344                 v0.AuxInt = int64ToAuxInt(s - 16)
21345                 v0.AddArg(src)
21346                 v.AddArg4(dst, src, v0, mem)
21347                 return true
21348         }
21349         return false
21350 }
21351 func rewriteValueARM64_OpNeq16(v *Value) bool {
21352         v_1 := v.Args[1]
21353         v_0 := v.Args[0]
21354         b := v.Block
21355         typ := &b.Func.Config.Types
21356         // match: (Neq16 x y)
21357         // result: (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
21358         for {
21359                 x := v_0
21360                 y := v_1
21361                 v.reset(OpARM64NotEqual)
21362                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
21363                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
21364                 v1.AddArg(x)
21365                 v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
21366                 v2.AddArg(y)
21367                 v0.AddArg2(v1, v2)
21368                 v.AddArg(v0)
21369                 return true
21370         }
21371 }
21372 func rewriteValueARM64_OpNeq32(v *Value) bool {
21373         v_1 := v.Args[1]
21374         v_0 := v.Args[0]
21375         b := v.Block
21376         // match: (Neq32 x y)
21377         // result: (NotEqual (CMPW x y))
21378         for {
21379                 x := v_0
21380                 y := v_1
21381                 v.reset(OpARM64NotEqual)
21382                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
21383                 v0.AddArg2(x, y)
21384                 v.AddArg(v0)
21385                 return true
21386         }
21387 }
21388 func rewriteValueARM64_OpNeq32F(v *Value) bool {
21389         v_1 := v.Args[1]
21390         v_0 := v.Args[0]
21391         b := v.Block
21392         // match: (Neq32F x y)
21393         // result: (NotEqual (FCMPS x y))
21394         for {
21395                 x := v_0
21396                 y := v_1
21397                 v.reset(OpARM64NotEqual)
21398                 v0 := b.NewValue0(v.Pos, OpARM64FCMPS, types.TypeFlags)
21399                 v0.AddArg2(x, y)
21400                 v.AddArg(v0)
21401                 return true
21402         }
21403 }
21404 func rewriteValueARM64_OpNeq64(v *Value) bool {
21405         v_1 := v.Args[1]
21406         v_0 := v.Args[0]
21407         b := v.Block
21408         // match: (Neq64 x y)
21409         // result: (NotEqual (CMP x y))
21410         for {
21411                 x := v_0
21412                 y := v_1
21413                 v.reset(OpARM64NotEqual)
21414                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
21415                 v0.AddArg2(x, y)
21416                 v.AddArg(v0)
21417                 return true
21418         }
21419 }
21420 func rewriteValueARM64_OpNeq64F(v *Value) bool {
21421         v_1 := v.Args[1]
21422         v_0 := v.Args[0]
21423         b := v.Block
21424         // match: (Neq64F x y)
21425         // result: (NotEqual (FCMPD x y))
21426         for {
21427                 x := v_0
21428                 y := v_1
21429                 v.reset(OpARM64NotEqual)
21430                 v0 := b.NewValue0(v.Pos, OpARM64FCMPD, types.TypeFlags)
21431                 v0.AddArg2(x, y)
21432                 v.AddArg(v0)
21433                 return true
21434         }
21435 }
21436 func rewriteValueARM64_OpNeq8(v *Value) bool {
21437         v_1 := v.Args[1]
21438         v_0 := v.Args[0]
21439         b := v.Block
21440         typ := &b.Func.Config.Types
21441         // match: (Neq8 x y)
21442         // result: (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
21443         for {
21444                 x := v_0
21445                 y := v_1
21446                 v.reset(OpARM64NotEqual)
21447                 v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
21448                 v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
21449                 v1.AddArg(x)
21450                 v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
21451                 v2.AddArg(y)
21452                 v0.AddArg2(v1, v2)
21453                 v.AddArg(v0)
21454                 return true
21455         }
21456 }
21457 func rewriteValueARM64_OpNeqPtr(v *Value) bool {
21458         v_1 := v.Args[1]
21459         v_0 := v.Args[0]
21460         b := v.Block
21461         // match: (NeqPtr x y)
21462         // result: (NotEqual (CMP x y))
21463         for {
21464                 x := v_0
21465                 y := v_1
21466                 v.reset(OpARM64NotEqual)
21467                 v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
21468                 v0.AddArg2(x, y)
21469                 v.AddArg(v0)
21470                 return true
21471         }
21472 }
21473 func rewriteValueARM64_OpNot(v *Value) bool {
21474         v_0 := v.Args[0]
21475         b := v.Block
21476         typ := &b.Func.Config.Types
21477         // match: (Not x)
21478         // result: (XOR (MOVDconst [1]) x)
21479         for {
21480                 x := v_0
21481                 v.reset(OpARM64XOR)
21482                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
21483                 v0.AuxInt = int64ToAuxInt(1)
21484                 v.AddArg2(v0, x)
21485                 return true
21486         }
21487 }
21488 func rewriteValueARM64_OpOffPtr(v *Value) bool {
21489         v_0 := v.Args[0]
21490         // match: (OffPtr [off] ptr:(SP))
21491         // cond: is32Bit(off)
21492         // result: (MOVDaddr [int32(off)] ptr)
21493         for {
21494                 off := auxIntToInt64(v.AuxInt)
21495                 ptr := v_0
21496                 if ptr.Op != OpSP || !(is32Bit(off)) {
21497                         break
21498                 }
21499                 v.reset(OpARM64MOVDaddr)
21500                 v.AuxInt = int32ToAuxInt(int32(off))
21501                 v.AddArg(ptr)
21502                 return true
21503         }
21504         // match: (OffPtr [off] ptr)
21505         // result: (ADDconst [off] ptr)
21506         for {
21507                 off := auxIntToInt64(v.AuxInt)
21508                 ptr := v_0
21509                 v.reset(OpARM64ADDconst)
21510                 v.AuxInt = int64ToAuxInt(off)
21511                 v.AddArg(ptr)
21512                 return true
21513         }
21514 }
21515 func rewriteValueARM64_OpPanicBounds(v *Value) bool {
21516         v_2 := v.Args[2]
21517         v_1 := v.Args[1]
21518         v_0 := v.Args[0]
21519         // match: (PanicBounds [kind] x y mem)
21520         // cond: boundsABI(kind) == 0
21521         // result: (LoweredPanicBoundsA [kind] x y mem)
21522         for {
21523                 kind := auxIntToInt64(v.AuxInt)
21524                 x := v_0
21525                 y := v_1
21526                 mem := v_2
21527                 if !(boundsABI(kind) == 0) {
21528                         break
21529                 }
21530                 v.reset(OpARM64LoweredPanicBoundsA)
21531                 v.AuxInt = int64ToAuxInt(kind)
21532                 v.AddArg3(x, y, mem)
21533                 return true
21534         }
21535         // match: (PanicBounds [kind] x y mem)
21536         // cond: boundsABI(kind) == 1
21537         // result: (LoweredPanicBoundsB [kind] x y mem)
21538         for {
21539                 kind := auxIntToInt64(v.AuxInt)
21540                 x := v_0
21541                 y := v_1
21542                 mem := v_2
21543                 if !(boundsABI(kind) == 1) {
21544                         break
21545                 }
21546                 v.reset(OpARM64LoweredPanicBoundsB)
21547                 v.AuxInt = int64ToAuxInt(kind)
21548                 v.AddArg3(x, y, mem)
21549                 return true
21550         }
21551         // match: (PanicBounds [kind] x y mem)
21552         // cond: boundsABI(kind) == 2
21553         // result: (LoweredPanicBoundsC [kind] x y mem)
21554         for {
21555                 kind := auxIntToInt64(v.AuxInt)
21556                 x := v_0
21557                 y := v_1
21558                 mem := v_2
21559                 if !(boundsABI(kind) == 2) {
21560                         break
21561                 }
21562                 v.reset(OpARM64LoweredPanicBoundsC)
21563                 v.AuxInt = int64ToAuxInt(kind)
21564                 v.AddArg3(x, y, mem)
21565                 return true
21566         }
21567         return false
21568 }
21569 func rewriteValueARM64_OpPopCount16(v *Value) bool {
21570         v_0 := v.Args[0]
21571         b := v.Block
21572         typ := &b.Func.Config.Types
21573         // match: (PopCount16 <t> x)
21574         // result: (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> (ZeroExt16to64 x)))))
21575         for {
21576                 t := v.Type
21577                 x := v_0
21578                 v.reset(OpARM64FMOVDfpgp)
21579                 v.Type = t
21580                 v0 := b.NewValue0(v.Pos, OpARM64VUADDLV, typ.Float64)
21581                 v1 := b.NewValue0(v.Pos, OpARM64VCNT, typ.Float64)
21582                 v2 := b.NewValue0(v.Pos, OpARM64FMOVDgpfp, typ.Float64)
21583                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21584                 v3.AddArg(x)
21585                 v2.AddArg(v3)
21586                 v1.AddArg(v2)
21587                 v0.AddArg(v1)
21588                 v.AddArg(v0)
21589                 return true
21590         }
21591 }
21592 func rewriteValueARM64_OpPopCount32(v *Value) bool {
21593         v_0 := v.Args[0]
21594         b := v.Block
21595         typ := &b.Func.Config.Types
21596         // match: (PopCount32 <t> x)
21597         // result: (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> (ZeroExt32to64 x)))))
21598         for {
21599                 t := v.Type
21600                 x := v_0
21601                 v.reset(OpARM64FMOVDfpgp)
21602                 v.Type = t
21603                 v0 := b.NewValue0(v.Pos, OpARM64VUADDLV, typ.Float64)
21604                 v1 := b.NewValue0(v.Pos, OpARM64VCNT, typ.Float64)
21605                 v2 := b.NewValue0(v.Pos, OpARM64FMOVDgpfp, typ.Float64)
21606                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
21607                 v3.AddArg(x)
21608                 v2.AddArg(v3)
21609                 v1.AddArg(v2)
21610                 v0.AddArg(v1)
21611                 v.AddArg(v0)
21612                 return true
21613         }
21614 }
21615 func rewriteValueARM64_OpPopCount64(v *Value) bool {
21616         v_0 := v.Args[0]
21617         b := v.Block
21618         typ := &b.Func.Config.Types
21619         // match: (PopCount64 <t> x)
21620         // result: (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> x))))
21621         for {
21622                 t := v.Type
21623                 x := v_0
21624                 v.reset(OpARM64FMOVDfpgp)
21625                 v.Type = t
21626                 v0 := b.NewValue0(v.Pos, OpARM64VUADDLV, typ.Float64)
21627                 v1 := b.NewValue0(v.Pos, OpARM64VCNT, typ.Float64)
21628                 v2 := b.NewValue0(v.Pos, OpARM64FMOVDgpfp, typ.Float64)
21629                 v2.AddArg(x)
21630                 v1.AddArg(v2)
21631                 v0.AddArg(v1)
21632                 v.AddArg(v0)
21633                 return true
21634         }
21635 }
21636 func rewriteValueARM64_OpPrefetchCache(v *Value) bool {
21637         v_1 := v.Args[1]
21638         v_0 := v.Args[0]
21639         // match: (PrefetchCache addr mem)
21640         // result: (PRFM [0] addr mem)
21641         for {
21642                 addr := v_0
21643                 mem := v_1
21644                 v.reset(OpARM64PRFM)
21645                 v.AuxInt = int64ToAuxInt(0)
21646                 v.AddArg2(addr, mem)
21647                 return true
21648         }
21649 }
21650 func rewriteValueARM64_OpPrefetchCacheStreamed(v *Value) bool {
21651         v_1 := v.Args[1]
21652         v_0 := v.Args[0]
21653         // match: (PrefetchCacheStreamed addr mem)
21654         // result: (PRFM [1] addr mem)
21655         for {
21656                 addr := v_0
21657                 mem := v_1
21658                 v.reset(OpARM64PRFM)
21659                 v.AuxInt = int64ToAuxInt(1)
21660                 v.AddArg2(addr, mem)
21661                 return true
21662         }
21663 }
21664 func rewriteValueARM64_OpPubBarrier(v *Value) bool {
21665         v_0 := v.Args[0]
21666         // match: (PubBarrier mem)
21667         // result: (DMB [0xe] mem)
21668         for {
21669                 mem := v_0
21670                 v.reset(OpARM64DMB)
21671                 v.AuxInt = int64ToAuxInt(0xe)
21672                 v.AddArg(mem)
21673                 return true
21674         }
21675 }
21676 func rewriteValueARM64_OpRotateLeft16(v *Value) bool {
21677         v_1 := v.Args[1]
21678         v_0 := v.Args[0]
21679         b := v.Block
21680         typ := &b.Func.Config.Types
21681         // match: (RotateLeft16 <t> x (MOVDconst [c]))
21682         // result: (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
21683         for {
21684                 t := v.Type
21685                 x := v_0
21686                 if v_1.Op != OpARM64MOVDconst {
21687                         break
21688                 }
21689                 c := auxIntToInt64(v_1.AuxInt)
21690                 v.reset(OpOr16)
21691                 v0 := b.NewValue0(v.Pos, OpLsh16x64, t)
21692                 v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
21693                 v1.AuxInt = int64ToAuxInt(c & 15)
21694                 v0.AddArg2(x, v1)
21695                 v2 := b.NewValue0(v.Pos, OpRsh16Ux64, t)
21696                 v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
21697                 v3.AuxInt = int64ToAuxInt(-c & 15)
21698                 v2.AddArg2(x, v3)
21699                 v.AddArg2(v0, v2)
21700                 return true
21701         }
21702         // match: (RotateLeft16 <t> x y)
21703         // result: (RORW <t> (ORshiftLL <typ.UInt32> (ZeroExt16to32 x) (ZeroExt16to32 x) [16]) (NEG <typ.Int64> y))
21704         for {
21705                 t := v.Type
21706                 x := v_0
21707                 y := v_1
21708                 v.reset(OpARM64RORW)
21709                 v.Type = t
21710                 v0 := b.NewValue0(v.Pos, OpARM64ORshiftLL, typ.UInt32)
21711                 v0.AuxInt = int64ToAuxInt(16)
21712                 v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
21713                 v1.AddArg(x)
21714                 v0.AddArg2(v1, v1)
21715                 v2 := b.NewValue0(v.Pos, OpARM64NEG, typ.Int64)
21716                 v2.AddArg(y)
21717                 v.AddArg2(v0, v2)
21718                 return true
21719         }
21720 }
21721 func rewriteValueARM64_OpRotateLeft32(v *Value) bool {
21722         v_1 := v.Args[1]
21723         v_0 := v.Args[0]
21724         b := v.Block
21725         // match: (RotateLeft32 x y)
21726         // result: (RORW x (NEG <y.Type> y))
21727         for {
21728                 x := v_0
21729                 y := v_1
21730                 v.reset(OpARM64RORW)
21731                 v0 := b.NewValue0(v.Pos, OpARM64NEG, y.Type)
21732                 v0.AddArg(y)
21733                 v.AddArg2(x, v0)
21734                 return true
21735         }
21736 }
21737 func rewriteValueARM64_OpRotateLeft64(v *Value) bool {
21738         v_1 := v.Args[1]
21739         v_0 := v.Args[0]
21740         b := v.Block
21741         // match: (RotateLeft64 x y)
21742         // result: (ROR x (NEG <y.Type> y))
21743         for {
21744                 x := v_0
21745                 y := v_1
21746                 v.reset(OpARM64ROR)
21747                 v0 := b.NewValue0(v.Pos, OpARM64NEG, y.Type)
21748                 v0.AddArg(y)
21749                 v.AddArg2(x, v0)
21750                 return true
21751         }
21752 }
21753 func rewriteValueARM64_OpRotateLeft8(v *Value) bool {
21754         v_1 := v.Args[1]
21755         v_0 := v.Args[0]
21756         b := v.Block
21757         typ := &b.Func.Config.Types
21758         // match: (RotateLeft8 <t> x (MOVDconst [c]))
21759         // result: (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
21760         for {
21761                 t := v.Type
21762                 x := v_0
21763                 if v_1.Op != OpARM64MOVDconst {
21764                         break
21765                 }
21766                 c := auxIntToInt64(v_1.AuxInt)
21767                 v.reset(OpOr8)
21768                 v0 := b.NewValue0(v.Pos, OpLsh8x64, t)
21769                 v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
21770                 v1.AuxInt = int64ToAuxInt(c & 7)
21771                 v0.AddArg2(x, v1)
21772                 v2 := b.NewValue0(v.Pos, OpRsh8Ux64, t)
21773                 v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
21774                 v3.AuxInt = int64ToAuxInt(-c & 7)
21775                 v2.AddArg2(x, v3)
21776                 v.AddArg2(v0, v2)
21777                 return true
21778         }
21779         // match: (RotateLeft8 <t> x y)
21780         // result: (OR <t> (SLL <t> x (ANDconst <typ.Int64> [7] y)) (SRL <t> (ZeroExt8to64 x) (ANDconst <typ.Int64> [7] (NEG <typ.Int64> y))))
21781         for {
21782                 t := v.Type
21783                 x := v_0
21784                 y := v_1
21785                 v.reset(OpARM64OR)
21786                 v.Type = t
21787                 v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
21788                 v1 := b.NewValue0(v.Pos, OpARM64ANDconst, typ.Int64)
21789                 v1.AuxInt = int64ToAuxInt(7)
21790                 v1.AddArg(y)
21791                 v0.AddArg2(x, v1)
21792                 v2 := b.NewValue0(v.Pos, OpARM64SRL, t)
21793                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
21794                 v3.AddArg(x)
21795                 v4 := b.NewValue0(v.Pos, OpARM64ANDconst, typ.Int64)
21796                 v4.AuxInt = int64ToAuxInt(7)
21797                 v5 := b.NewValue0(v.Pos, OpARM64NEG, typ.Int64)
21798                 v5.AddArg(y)
21799                 v4.AddArg(v5)
21800                 v2.AddArg2(v3, v4)
21801                 v.AddArg2(v0, v2)
21802                 return true
21803         }
21804 }
21805 func rewriteValueARM64_OpRsh16Ux16(v *Value) bool {
21806         v_1 := v.Args[1]
21807         v_0 := v.Args[0]
21808         b := v.Block
21809         typ := &b.Func.Config.Types
21810         // match: (Rsh16Ux16 <t> x y)
21811         // cond: shiftIsBounded(v)
21812         // result: (SRL <t> (ZeroExt16to64 x) y)
21813         for {
21814                 t := v.Type
21815                 x := v_0
21816                 y := v_1
21817                 if !(shiftIsBounded(v)) {
21818                         break
21819                 }
21820                 v.reset(OpARM64SRL)
21821                 v.Type = t
21822                 v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21823                 v0.AddArg(x)
21824                 v.AddArg2(v0, y)
21825                 return true
21826         }
21827         // match: (Rsh16Ux16 <t> x y)
21828         // cond: !shiftIsBounded(v)
21829         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
21830         for {
21831                 t := v.Type
21832                 x := v_0
21833                 y := v_1
21834                 if !(!shiftIsBounded(v)) {
21835                         break
21836                 }
21837                 v.reset(OpARM64CSEL)
21838                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
21839                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
21840                 v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21841                 v1.AddArg(x)
21842                 v0.AddArg2(v1, y)
21843                 v2 := b.NewValue0(v.Pos, OpConst64, t)
21844                 v2.AuxInt = int64ToAuxInt(0)
21845                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
21846                 v3.AuxInt = int64ToAuxInt(64)
21847                 v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21848                 v4.AddArg(y)
21849                 v3.AddArg(v4)
21850                 v.AddArg3(v0, v2, v3)
21851                 return true
21852         }
21853         return false
21854 }
21855 func rewriteValueARM64_OpRsh16Ux32(v *Value) bool {
21856         v_1 := v.Args[1]
21857         v_0 := v.Args[0]
21858         b := v.Block
21859         typ := &b.Func.Config.Types
21860         // match: (Rsh16Ux32 <t> x y)
21861         // cond: shiftIsBounded(v)
21862         // result: (SRL <t> (ZeroExt16to64 x) y)
21863         for {
21864                 t := v.Type
21865                 x := v_0
21866                 y := v_1
21867                 if !(shiftIsBounded(v)) {
21868                         break
21869                 }
21870                 v.reset(OpARM64SRL)
21871                 v.Type = t
21872                 v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21873                 v0.AddArg(x)
21874                 v.AddArg2(v0, y)
21875                 return true
21876         }
21877         // match: (Rsh16Ux32 <t> x y)
21878         // cond: !shiftIsBounded(v)
21879         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
21880         for {
21881                 t := v.Type
21882                 x := v_0
21883                 y := v_1
21884                 if !(!shiftIsBounded(v)) {
21885                         break
21886                 }
21887                 v.reset(OpARM64CSEL)
21888                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
21889                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
21890                 v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21891                 v1.AddArg(x)
21892                 v0.AddArg2(v1, y)
21893                 v2 := b.NewValue0(v.Pos, OpConst64, t)
21894                 v2.AuxInt = int64ToAuxInt(0)
21895                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
21896                 v3.AuxInt = int64ToAuxInt(64)
21897                 v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
21898                 v4.AddArg(y)
21899                 v3.AddArg(v4)
21900                 v.AddArg3(v0, v2, v3)
21901                 return true
21902         }
21903         return false
21904 }
21905 func rewriteValueARM64_OpRsh16Ux64(v *Value) bool {
21906         v_1 := v.Args[1]
21907         v_0 := v.Args[0]
21908         b := v.Block
21909         typ := &b.Func.Config.Types
21910         // match: (Rsh16Ux64 <t> x y)
21911         // cond: shiftIsBounded(v)
21912         // result: (SRL <t> (ZeroExt16to64 x) y)
21913         for {
21914                 t := v.Type
21915                 x := v_0
21916                 y := v_1
21917                 if !(shiftIsBounded(v)) {
21918                         break
21919                 }
21920                 v.reset(OpARM64SRL)
21921                 v.Type = t
21922                 v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21923                 v0.AddArg(x)
21924                 v.AddArg2(v0, y)
21925                 return true
21926         }
21927         // match: (Rsh16Ux64 <t> x y)
21928         // cond: !shiftIsBounded(v)
21929         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
21930         for {
21931                 t := v.Type
21932                 x := v_0
21933                 y := v_1
21934                 if !(!shiftIsBounded(v)) {
21935                         break
21936                 }
21937                 v.reset(OpARM64CSEL)
21938                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
21939                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
21940                 v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21941                 v1.AddArg(x)
21942                 v0.AddArg2(v1, y)
21943                 v2 := b.NewValue0(v.Pos, OpConst64, t)
21944                 v2.AuxInt = int64ToAuxInt(0)
21945                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
21946                 v3.AuxInt = int64ToAuxInt(64)
21947                 v3.AddArg(y)
21948                 v.AddArg3(v0, v2, v3)
21949                 return true
21950         }
21951         return false
21952 }
21953 func rewriteValueARM64_OpRsh16Ux8(v *Value) bool {
21954         v_1 := v.Args[1]
21955         v_0 := v.Args[0]
21956         b := v.Block
21957         typ := &b.Func.Config.Types
21958         // match: (Rsh16Ux8 <t> x y)
21959         // cond: shiftIsBounded(v)
21960         // result: (SRL <t> (ZeroExt16to64 x) y)
21961         for {
21962                 t := v.Type
21963                 x := v_0
21964                 y := v_1
21965                 if !(shiftIsBounded(v)) {
21966                         break
21967                 }
21968                 v.reset(OpARM64SRL)
21969                 v.Type = t
21970                 v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21971                 v0.AddArg(x)
21972                 v.AddArg2(v0, y)
21973                 return true
21974         }
21975         // match: (Rsh16Ux8 <t> x y)
21976         // cond: !shiftIsBounded(v)
21977         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
21978         for {
21979                 t := v.Type
21980                 x := v_0
21981                 y := v_1
21982                 if !(!shiftIsBounded(v)) {
21983                         break
21984                 }
21985                 v.reset(OpARM64CSEL)
21986                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
21987                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
21988                 v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
21989                 v1.AddArg(x)
21990                 v0.AddArg2(v1, y)
21991                 v2 := b.NewValue0(v.Pos, OpConst64, t)
21992                 v2.AuxInt = int64ToAuxInt(0)
21993                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
21994                 v3.AuxInt = int64ToAuxInt(64)
21995                 v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
21996                 v4.AddArg(y)
21997                 v3.AddArg(v4)
21998                 v.AddArg3(v0, v2, v3)
21999                 return true
22000         }
22001         return false
22002 }
22003 func rewriteValueARM64_OpRsh16x16(v *Value) bool {
22004         v_1 := v.Args[1]
22005         v_0 := v.Args[0]
22006         b := v.Block
22007         typ := &b.Func.Config.Types
22008         // match: (Rsh16x16 <t> x y)
22009         // cond: shiftIsBounded(v)
22010         // result: (SRA <t> (SignExt16to64 x) y)
22011         for {
22012                 t := v.Type
22013                 x := v_0
22014                 y := v_1
22015                 if !(shiftIsBounded(v)) {
22016                         break
22017                 }
22018                 v.reset(OpARM64SRA)
22019                 v.Type = t
22020                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22021                 v0.AddArg(x)
22022                 v.AddArg2(v0, y)
22023                 return true
22024         }
22025         // match: (Rsh16x16 x y)
22026         // cond: !shiftIsBounded(v)
22027         // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
22028         for {
22029                 x := v_0
22030                 y := v_1
22031                 if !(!shiftIsBounded(v)) {
22032                         break
22033                 }
22034                 v.reset(OpARM64SRA)
22035                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22036                 v0.AddArg(x)
22037                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22038                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22039                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22040                 v2.AuxInt = int64ToAuxInt(63)
22041                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22042                 v3.AuxInt = int64ToAuxInt(64)
22043                 v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
22044                 v4.AddArg(y)
22045                 v3.AddArg(v4)
22046                 v1.AddArg3(y, v2, v3)
22047                 v.AddArg2(v0, v1)
22048                 return true
22049         }
22050         return false
22051 }
22052 func rewriteValueARM64_OpRsh16x32(v *Value) bool {
22053         v_1 := v.Args[1]
22054         v_0 := v.Args[0]
22055         b := v.Block
22056         typ := &b.Func.Config.Types
22057         // match: (Rsh16x32 <t> x y)
22058         // cond: shiftIsBounded(v)
22059         // result: (SRA <t> (SignExt16to64 x) y)
22060         for {
22061                 t := v.Type
22062                 x := v_0
22063                 y := v_1
22064                 if !(shiftIsBounded(v)) {
22065                         break
22066                 }
22067                 v.reset(OpARM64SRA)
22068                 v.Type = t
22069                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22070                 v0.AddArg(x)
22071                 v.AddArg2(v0, y)
22072                 return true
22073         }
22074         // match: (Rsh16x32 x y)
22075         // cond: !shiftIsBounded(v)
22076         // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
22077         for {
22078                 x := v_0
22079                 y := v_1
22080                 if !(!shiftIsBounded(v)) {
22081                         break
22082                 }
22083                 v.reset(OpARM64SRA)
22084                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22085                 v0.AddArg(x)
22086                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22087                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22088                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22089                 v2.AuxInt = int64ToAuxInt(63)
22090                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22091                 v3.AuxInt = int64ToAuxInt(64)
22092                 v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22093                 v4.AddArg(y)
22094                 v3.AddArg(v4)
22095                 v1.AddArg3(y, v2, v3)
22096                 v.AddArg2(v0, v1)
22097                 return true
22098         }
22099         return false
22100 }
22101 func rewriteValueARM64_OpRsh16x64(v *Value) bool {
22102         v_1 := v.Args[1]
22103         v_0 := v.Args[0]
22104         b := v.Block
22105         typ := &b.Func.Config.Types
22106         // match: (Rsh16x64 <t> x y)
22107         // cond: shiftIsBounded(v)
22108         // result: (SRA <t> (SignExt16to64 x) y)
22109         for {
22110                 t := v.Type
22111                 x := v_0
22112                 y := v_1
22113                 if !(shiftIsBounded(v)) {
22114                         break
22115                 }
22116                 v.reset(OpARM64SRA)
22117                 v.Type = t
22118                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22119                 v0.AddArg(x)
22120                 v.AddArg2(v0, y)
22121                 return true
22122         }
22123         // match: (Rsh16x64 x y)
22124         // cond: !shiftIsBounded(v)
22125         // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
22126         for {
22127                 x := v_0
22128                 y := v_1
22129                 if !(!shiftIsBounded(v)) {
22130                         break
22131                 }
22132                 v.reset(OpARM64SRA)
22133                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22134                 v0.AddArg(x)
22135                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22136                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22137                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22138                 v2.AuxInt = int64ToAuxInt(63)
22139                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22140                 v3.AuxInt = int64ToAuxInt(64)
22141                 v3.AddArg(y)
22142                 v1.AddArg3(y, v2, v3)
22143                 v.AddArg2(v0, v1)
22144                 return true
22145         }
22146         return false
22147 }
22148 func rewriteValueARM64_OpRsh16x8(v *Value) bool {
22149         v_1 := v.Args[1]
22150         v_0 := v.Args[0]
22151         b := v.Block
22152         typ := &b.Func.Config.Types
22153         // match: (Rsh16x8 <t> x y)
22154         // cond: shiftIsBounded(v)
22155         // result: (SRA <t> (SignExt16to64 x) y)
22156         for {
22157                 t := v.Type
22158                 x := v_0
22159                 y := v_1
22160                 if !(shiftIsBounded(v)) {
22161                         break
22162                 }
22163                 v.reset(OpARM64SRA)
22164                 v.Type = t
22165                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22166                 v0.AddArg(x)
22167                 v.AddArg2(v0, y)
22168                 return true
22169         }
22170         // match: (Rsh16x8 x y)
22171         // cond: !shiftIsBounded(v)
22172         // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
22173         for {
22174                 x := v_0
22175                 y := v_1
22176                 if !(!shiftIsBounded(v)) {
22177                         break
22178                 }
22179                 v.reset(OpARM64SRA)
22180                 v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
22181                 v0.AddArg(x)
22182                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22183                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22184                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22185                 v2.AuxInt = int64ToAuxInt(63)
22186                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22187                 v3.AuxInt = int64ToAuxInt(64)
22188                 v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22189                 v4.AddArg(y)
22190                 v3.AddArg(v4)
22191                 v1.AddArg3(y, v2, v3)
22192                 v.AddArg2(v0, v1)
22193                 return true
22194         }
22195         return false
22196 }
22197 func rewriteValueARM64_OpRsh32Ux16(v *Value) bool {
22198         v_1 := v.Args[1]
22199         v_0 := v.Args[0]
22200         b := v.Block
22201         typ := &b.Func.Config.Types
22202         // match: (Rsh32Ux16 <t> x y)
22203         // cond: shiftIsBounded(v)
22204         // result: (SRL <t> (ZeroExt32to64 x) y)
22205         for {
22206                 t := v.Type
22207                 x := v_0
22208                 y := v_1
22209                 if !(shiftIsBounded(v)) {
22210                         break
22211                 }
22212                 v.reset(OpARM64SRL)
22213                 v.Type = t
22214                 v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22215                 v0.AddArg(x)
22216                 v.AddArg2(v0, y)
22217                 return true
22218         }
22219         // match: (Rsh32Ux16 <t> x y)
22220         // cond: !shiftIsBounded(v)
22221         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
22222         for {
22223                 t := v.Type
22224                 x := v_0
22225                 y := v_1
22226                 if !(!shiftIsBounded(v)) {
22227                         break
22228                 }
22229                 v.reset(OpARM64CSEL)
22230                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22231                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22232                 v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22233                 v1.AddArg(x)
22234                 v0.AddArg2(v1, y)
22235                 v2 := b.NewValue0(v.Pos, OpConst64, t)
22236                 v2.AuxInt = int64ToAuxInt(0)
22237                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22238                 v3.AuxInt = int64ToAuxInt(64)
22239                 v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
22240                 v4.AddArg(y)
22241                 v3.AddArg(v4)
22242                 v.AddArg3(v0, v2, v3)
22243                 return true
22244         }
22245         return false
22246 }
22247 func rewriteValueARM64_OpRsh32Ux32(v *Value) bool {
22248         v_1 := v.Args[1]
22249         v_0 := v.Args[0]
22250         b := v.Block
22251         typ := &b.Func.Config.Types
22252         // match: (Rsh32Ux32 <t> x y)
22253         // cond: shiftIsBounded(v)
22254         // result: (SRL <t> (ZeroExt32to64 x) y)
22255         for {
22256                 t := v.Type
22257                 x := v_0
22258                 y := v_1
22259                 if !(shiftIsBounded(v)) {
22260                         break
22261                 }
22262                 v.reset(OpARM64SRL)
22263                 v.Type = t
22264                 v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22265                 v0.AddArg(x)
22266                 v.AddArg2(v0, y)
22267                 return true
22268         }
22269         // match: (Rsh32Ux32 <t> x y)
22270         // cond: !shiftIsBounded(v)
22271         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
22272         for {
22273                 t := v.Type
22274                 x := v_0
22275                 y := v_1
22276                 if !(!shiftIsBounded(v)) {
22277                         break
22278                 }
22279                 v.reset(OpARM64CSEL)
22280                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22281                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22282                 v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22283                 v1.AddArg(x)
22284                 v0.AddArg2(v1, y)
22285                 v2 := b.NewValue0(v.Pos, OpConst64, t)
22286                 v2.AuxInt = int64ToAuxInt(0)
22287                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22288                 v3.AuxInt = int64ToAuxInt(64)
22289                 v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22290                 v4.AddArg(y)
22291                 v3.AddArg(v4)
22292                 v.AddArg3(v0, v2, v3)
22293                 return true
22294         }
22295         return false
22296 }
22297 func rewriteValueARM64_OpRsh32Ux64(v *Value) bool {
22298         v_1 := v.Args[1]
22299         v_0 := v.Args[0]
22300         b := v.Block
22301         typ := &b.Func.Config.Types
22302         // match: (Rsh32Ux64 <t> x y)
22303         // cond: shiftIsBounded(v)
22304         // result: (SRL <t> (ZeroExt32to64 x) y)
22305         for {
22306                 t := v.Type
22307                 x := v_0
22308                 y := v_1
22309                 if !(shiftIsBounded(v)) {
22310                         break
22311                 }
22312                 v.reset(OpARM64SRL)
22313                 v.Type = t
22314                 v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22315                 v0.AddArg(x)
22316                 v.AddArg2(v0, y)
22317                 return true
22318         }
22319         // match: (Rsh32Ux64 <t> x y)
22320         // cond: !shiftIsBounded(v)
22321         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
22322         for {
22323                 t := v.Type
22324                 x := v_0
22325                 y := v_1
22326                 if !(!shiftIsBounded(v)) {
22327                         break
22328                 }
22329                 v.reset(OpARM64CSEL)
22330                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22331                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22332                 v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22333                 v1.AddArg(x)
22334                 v0.AddArg2(v1, y)
22335                 v2 := b.NewValue0(v.Pos, OpConst64, t)
22336                 v2.AuxInt = int64ToAuxInt(0)
22337                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22338                 v3.AuxInt = int64ToAuxInt(64)
22339                 v3.AddArg(y)
22340                 v.AddArg3(v0, v2, v3)
22341                 return true
22342         }
22343         return false
22344 }
22345 func rewriteValueARM64_OpRsh32Ux8(v *Value) bool {
22346         v_1 := v.Args[1]
22347         v_0 := v.Args[0]
22348         b := v.Block
22349         typ := &b.Func.Config.Types
22350         // match: (Rsh32Ux8 <t> x y)
22351         // cond: shiftIsBounded(v)
22352         // result: (SRL <t> (ZeroExt32to64 x) y)
22353         for {
22354                 t := v.Type
22355                 x := v_0
22356                 y := v_1
22357                 if !(shiftIsBounded(v)) {
22358                         break
22359                 }
22360                 v.reset(OpARM64SRL)
22361                 v.Type = t
22362                 v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22363                 v0.AddArg(x)
22364                 v.AddArg2(v0, y)
22365                 return true
22366         }
22367         // match: (Rsh32Ux8 <t> x y)
22368         // cond: !shiftIsBounded(v)
22369         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
22370         for {
22371                 t := v.Type
22372                 x := v_0
22373                 y := v_1
22374                 if !(!shiftIsBounded(v)) {
22375                         break
22376                 }
22377                 v.reset(OpARM64CSEL)
22378                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22379                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22380                 v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22381                 v1.AddArg(x)
22382                 v0.AddArg2(v1, y)
22383                 v2 := b.NewValue0(v.Pos, OpConst64, t)
22384                 v2.AuxInt = int64ToAuxInt(0)
22385                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22386                 v3.AuxInt = int64ToAuxInt(64)
22387                 v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22388                 v4.AddArg(y)
22389                 v3.AddArg(v4)
22390                 v.AddArg3(v0, v2, v3)
22391                 return true
22392         }
22393         return false
22394 }
22395 func rewriteValueARM64_OpRsh32x16(v *Value) bool {
22396         v_1 := v.Args[1]
22397         v_0 := v.Args[0]
22398         b := v.Block
22399         typ := &b.Func.Config.Types
22400         // match: (Rsh32x16 <t> x y)
22401         // cond: shiftIsBounded(v)
22402         // result: (SRA <t> (SignExt32to64 x) y)
22403         for {
22404                 t := v.Type
22405                 x := v_0
22406                 y := v_1
22407                 if !(shiftIsBounded(v)) {
22408                         break
22409                 }
22410                 v.reset(OpARM64SRA)
22411                 v.Type = t
22412                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22413                 v0.AddArg(x)
22414                 v.AddArg2(v0, y)
22415                 return true
22416         }
22417         // match: (Rsh32x16 x y)
22418         // cond: !shiftIsBounded(v)
22419         // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
22420         for {
22421                 x := v_0
22422                 y := v_1
22423                 if !(!shiftIsBounded(v)) {
22424                         break
22425                 }
22426                 v.reset(OpARM64SRA)
22427                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22428                 v0.AddArg(x)
22429                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22430                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22431                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22432                 v2.AuxInt = int64ToAuxInt(63)
22433                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22434                 v3.AuxInt = int64ToAuxInt(64)
22435                 v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
22436                 v4.AddArg(y)
22437                 v3.AddArg(v4)
22438                 v1.AddArg3(y, v2, v3)
22439                 v.AddArg2(v0, v1)
22440                 return true
22441         }
22442         return false
22443 }
22444 func rewriteValueARM64_OpRsh32x32(v *Value) bool {
22445         v_1 := v.Args[1]
22446         v_0 := v.Args[0]
22447         b := v.Block
22448         typ := &b.Func.Config.Types
22449         // match: (Rsh32x32 <t> x y)
22450         // cond: shiftIsBounded(v)
22451         // result: (SRA <t> (SignExt32to64 x) y)
22452         for {
22453                 t := v.Type
22454                 x := v_0
22455                 y := v_1
22456                 if !(shiftIsBounded(v)) {
22457                         break
22458                 }
22459                 v.reset(OpARM64SRA)
22460                 v.Type = t
22461                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22462                 v0.AddArg(x)
22463                 v.AddArg2(v0, y)
22464                 return true
22465         }
22466         // match: (Rsh32x32 x y)
22467         // cond: !shiftIsBounded(v)
22468         // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
22469         for {
22470                 x := v_0
22471                 y := v_1
22472                 if !(!shiftIsBounded(v)) {
22473                         break
22474                 }
22475                 v.reset(OpARM64SRA)
22476                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22477                 v0.AddArg(x)
22478                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22479                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22480                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22481                 v2.AuxInt = int64ToAuxInt(63)
22482                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22483                 v3.AuxInt = int64ToAuxInt(64)
22484                 v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22485                 v4.AddArg(y)
22486                 v3.AddArg(v4)
22487                 v1.AddArg3(y, v2, v3)
22488                 v.AddArg2(v0, v1)
22489                 return true
22490         }
22491         return false
22492 }
22493 func rewriteValueARM64_OpRsh32x64(v *Value) bool {
22494         v_1 := v.Args[1]
22495         v_0 := v.Args[0]
22496         b := v.Block
22497         typ := &b.Func.Config.Types
22498         // match: (Rsh32x64 <t> x y)
22499         // cond: shiftIsBounded(v)
22500         // result: (SRA <t> (SignExt32to64 x) y)
22501         for {
22502                 t := v.Type
22503                 x := v_0
22504                 y := v_1
22505                 if !(shiftIsBounded(v)) {
22506                         break
22507                 }
22508                 v.reset(OpARM64SRA)
22509                 v.Type = t
22510                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22511                 v0.AddArg(x)
22512                 v.AddArg2(v0, y)
22513                 return true
22514         }
22515         // match: (Rsh32x64 x y)
22516         // cond: !shiftIsBounded(v)
22517         // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
22518         for {
22519                 x := v_0
22520                 y := v_1
22521                 if !(!shiftIsBounded(v)) {
22522                         break
22523                 }
22524                 v.reset(OpARM64SRA)
22525                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22526                 v0.AddArg(x)
22527                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22528                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22529                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22530                 v2.AuxInt = int64ToAuxInt(63)
22531                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22532                 v3.AuxInt = int64ToAuxInt(64)
22533                 v3.AddArg(y)
22534                 v1.AddArg3(y, v2, v3)
22535                 v.AddArg2(v0, v1)
22536                 return true
22537         }
22538         return false
22539 }
22540 func rewriteValueARM64_OpRsh32x8(v *Value) bool {
22541         v_1 := v.Args[1]
22542         v_0 := v.Args[0]
22543         b := v.Block
22544         typ := &b.Func.Config.Types
22545         // match: (Rsh32x8 <t> x y)
22546         // cond: shiftIsBounded(v)
22547         // result: (SRA <t> (SignExt32to64 x) y)
22548         for {
22549                 t := v.Type
22550                 x := v_0
22551                 y := v_1
22552                 if !(shiftIsBounded(v)) {
22553                         break
22554                 }
22555                 v.reset(OpARM64SRA)
22556                 v.Type = t
22557                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22558                 v0.AddArg(x)
22559                 v.AddArg2(v0, y)
22560                 return true
22561         }
22562         // match: (Rsh32x8 x y)
22563         // cond: !shiftIsBounded(v)
22564         // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
22565         for {
22566                 x := v_0
22567                 y := v_1
22568                 if !(!shiftIsBounded(v)) {
22569                         break
22570                 }
22571                 v.reset(OpARM64SRA)
22572                 v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
22573                 v0.AddArg(x)
22574                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22575                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
22576                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
22577                 v2.AuxInt = int64ToAuxInt(63)
22578                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22579                 v3.AuxInt = int64ToAuxInt(64)
22580                 v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22581                 v4.AddArg(y)
22582                 v3.AddArg(v4)
22583                 v1.AddArg3(y, v2, v3)
22584                 v.AddArg2(v0, v1)
22585                 return true
22586         }
22587         return false
22588 }
22589 func rewriteValueARM64_OpRsh64Ux16(v *Value) bool {
22590         v_1 := v.Args[1]
22591         v_0 := v.Args[0]
22592         b := v.Block
22593         typ := &b.Func.Config.Types
22594         // match: (Rsh64Ux16 <t> x y)
22595         // cond: shiftIsBounded(v)
22596         // result: (SRL <t> x y)
22597         for {
22598                 t := v.Type
22599                 x := v_0
22600                 y := v_1
22601                 if !(shiftIsBounded(v)) {
22602                         break
22603                 }
22604                 v.reset(OpARM64SRL)
22605                 v.Type = t
22606                 v.AddArg2(x, y)
22607                 return true
22608         }
22609         // match: (Rsh64Ux16 <t> x y)
22610         // cond: !shiftIsBounded(v)
22611         // result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
22612         for {
22613                 t := v.Type
22614                 x := v_0
22615                 y := v_1
22616                 if !(!shiftIsBounded(v)) {
22617                         break
22618                 }
22619                 v.reset(OpARM64CSEL)
22620                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22621                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22622                 v0.AddArg2(x, y)
22623                 v1 := b.NewValue0(v.Pos, OpConst64, t)
22624                 v1.AuxInt = int64ToAuxInt(0)
22625                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22626                 v2.AuxInt = int64ToAuxInt(64)
22627                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
22628                 v3.AddArg(y)
22629                 v2.AddArg(v3)
22630                 v.AddArg3(v0, v1, v2)
22631                 return true
22632         }
22633         return false
22634 }
22635 func rewriteValueARM64_OpRsh64Ux32(v *Value) bool {
22636         v_1 := v.Args[1]
22637         v_0 := v.Args[0]
22638         b := v.Block
22639         typ := &b.Func.Config.Types
22640         // match: (Rsh64Ux32 <t> x y)
22641         // cond: shiftIsBounded(v)
22642         // result: (SRL <t> x y)
22643         for {
22644                 t := v.Type
22645                 x := v_0
22646                 y := v_1
22647                 if !(shiftIsBounded(v)) {
22648                         break
22649                 }
22650                 v.reset(OpARM64SRL)
22651                 v.Type = t
22652                 v.AddArg2(x, y)
22653                 return true
22654         }
22655         // match: (Rsh64Ux32 <t> x y)
22656         // cond: !shiftIsBounded(v)
22657         // result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
22658         for {
22659                 t := v.Type
22660                 x := v_0
22661                 y := v_1
22662                 if !(!shiftIsBounded(v)) {
22663                         break
22664                 }
22665                 v.reset(OpARM64CSEL)
22666                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22667                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22668                 v0.AddArg2(x, y)
22669                 v1 := b.NewValue0(v.Pos, OpConst64, t)
22670                 v1.AuxInt = int64ToAuxInt(0)
22671                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22672                 v2.AuxInt = int64ToAuxInt(64)
22673                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22674                 v3.AddArg(y)
22675                 v2.AddArg(v3)
22676                 v.AddArg3(v0, v1, v2)
22677                 return true
22678         }
22679         return false
22680 }
22681 func rewriteValueARM64_OpRsh64Ux64(v *Value) bool {
22682         v_1 := v.Args[1]
22683         v_0 := v.Args[0]
22684         b := v.Block
22685         // match: (Rsh64Ux64 <t> x y)
22686         // cond: shiftIsBounded(v)
22687         // result: (SRL <t> x y)
22688         for {
22689                 t := v.Type
22690                 x := v_0
22691                 y := v_1
22692                 if !(shiftIsBounded(v)) {
22693                         break
22694                 }
22695                 v.reset(OpARM64SRL)
22696                 v.Type = t
22697                 v.AddArg2(x, y)
22698                 return true
22699         }
22700         // match: (Rsh64Ux64 <t> x y)
22701         // cond: !shiftIsBounded(v)
22702         // result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
22703         for {
22704                 t := v.Type
22705                 x := v_0
22706                 y := v_1
22707                 if !(!shiftIsBounded(v)) {
22708                         break
22709                 }
22710                 v.reset(OpARM64CSEL)
22711                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22712                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22713                 v0.AddArg2(x, y)
22714                 v1 := b.NewValue0(v.Pos, OpConst64, t)
22715                 v1.AuxInt = int64ToAuxInt(0)
22716                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22717                 v2.AuxInt = int64ToAuxInt(64)
22718                 v2.AddArg(y)
22719                 v.AddArg3(v0, v1, v2)
22720                 return true
22721         }
22722         return false
22723 }
22724 func rewriteValueARM64_OpRsh64Ux8(v *Value) bool {
22725         v_1 := v.Args[1]
22726         v_0 := v.Args[0]
22727         b := v.Block
22728         typ := &b.Func.Config.Types
22729         // match: (Rsh64Ux8 <t> x y)
22730         // cond: shiftIsBounded(v)
22731         // result: (SRL <t> x y)
22732         for {
22733                 t := v.Type
22734                 x := v_0
22735                 y := v_1
22736                 if !(shiftIsBounded(v)) {
22737                         break
22738                 }
22739                 v.reset(OpARM64SRL)
22740                 v.Type = t
22741                 v.AddArg2(x, y)
22742                 return true
22743         }
22744         // match: (Rsh64Ux8 <t> x y)
22745         // cond: !shiftIsBounded(v)
22746         // result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
22747         for {
22748                 t := v.Type
22749                 x := v_0
22750                 y := v_1
22751                 if !(!shiftIsBounded(v)) {
22752                         break
22753                 }
22754                 v.reset(OpARM64CSEL)
22755                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22756                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22757                 v0.AddArg2(x, y)
22758                 v1 := b.NewValue0(v.Pos, OpConst64, t)
22759                 v1.AuxInt = int64ToAuxInt(0)
22760                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22761                 v2.AuxInt = int64ToAuxInt(64)
22762                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22763                 v3.AddArg(y)
22764                 v2.AddArg(v3)
22765                 v.AddArg3(v0, v1, v2)
22766                 return true
22767         }
22768         return false
22769 }
22770 func rewriteValueARM64_OpRsh64x16(v *Value) bool {
22771         v_1 := v.Args[1]
22772         v_0 := v.Args[0]
22773         b := v.Block
22774         typ := &b.Func.Config.Types
22775         // match: (Rsh64x16 <t> x y)
22776         // cond: shiftIsBounded(v)
22777         // result: (SRA <t> x y)
22778         for {
22779                 t := v.Type
22780                 x := v_0
22781                 y := v_1
22782                 if !(shiftIsBounded(v)) {
22783                         break
22784                 }
22785                 v.reset(OpARM64SRA)
22786                 v.Type = t
22787                 v.AddArg2(x, y)
22788                 return true
22789         }
22790         // match: (Rsh64x16 x y)
22791         // cond: !shiftIsBounded(v)
22792         // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
22793         for {
22794                 x := v_0
22795                 y := v_1
22796                 if !(!shiftIsBounded(v)) {
22797                         break
22798                 }
22799                 v.reset(OpARM64SRA)
22800                 v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22801                 v0.AuxInt = opToAuxInt(OpARM64LessThanU)
22802                 v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
22803                 v1.AuxInt = int64ToAuxInt(63)
22804                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22805                 v2.AuxInt = int64ToAuxInt(64)
22806                 v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
22807                 v3.AddArg(y)
22808                 v2.AddArg(v3)
22809                 v0.AddArg3(y, v1, v2)
22810                 v.AddArg2(x, v0)
22811                 return true
22812         }
22813         return false
22814 }
22815 func rewriteValueARM64_OpRsh64x32(v *Value) bool {
22816         v_1 := v.Args[1]
22817         v_0 := v.Args[0]
22818         b := v.Block
22819         typ := &b.Func.Config.Types
22820         // match: (Rsh64x32 <t> x y)
22821         // cond: shiftIsBounded(v)
22822         // result: (SRA <t> x y)
22823         for {
22824                 t := v.Type
22825                 x := v_0
22826                 y := v_1
22827                 if !(shiftIsBounded(v)) {
22828                         break
22829                 }
22830                 v.reset(OpARM64SRA)
22831                 v.Type = t
22832                 v.AddArg2(x, y)
22833                 return true
22834         }
22835         // match: (Rsh64x32 x y)
22836         // cond: !shiftIsBounded(v)
22837         // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
22838         for {
22839                 x := v_0
22840                 y := v_1
22841                 if !(!shiftIsBounded(v)) {
22842                         break
22843                 }
22844                 v.reset(OpARM64SRA)
22845                 v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22846                 v0.AuxInt = opToAuxInt(OpARM64LessThanU)
22847                 v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
22848                 v1.AuxInt = int64ToAuxInt(63)
22849                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22850                 v2.AuxInt = int64ToAuxInt(64)
22851                 v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
22852                 v3.AddArg(y)
22853                 v2.AddArg(v3)
22854                 v0.AddArg3(y, v1, v2)
22855                 v.AddArg2(x, v0)
22856                 return true
22857         }
22858         return false
22859 }
22860 func rewriteValueARM64_OpRsh64x64(v *Value) bool {
22861         v_1 := v.Args[1]
22862         v_0 := v.Args[0]
22863         b := v.Block
22864         // match: (Rsh64x64 <t> x y)
22865         // cond: shiftIsBounded(v)
22866         // result: (SRA <t> x y)
22867         for {
22868                 t := v.Type
22869                 x := v_0
22870                 y := v_1
22871                 if !(shiftIsBounded(v)) {
22872                         break
22873                 }
22874                 v.reset(OpARM64SRA)
22875                 v.Type = t
22876                 v.AddArg2(x, y)
22877                 return true
22878         }
22879         // match: (Rsh64x64 x y)
22880         // cond: !shiftIsBounded(v)
22881         // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
22882         for {
22883                 x := v_0
22884                 y := v_1
22885                 if !(!shiftIsBounded(v)) {
22886                         break
22887                 }
22888                 v.reset(OpARM64SRA)
22889                 v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22890                 v0.AuxInt = opToAuxInt(OpARM64LessThanU)
22891                 v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
22892                 v1.AuxInt = int64ToAuxInt(63)
22893                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22894                 v2.AuxInt = int64ToAuxInt(64)
22895                 v2.AddArg(y)
22896                 v0.AddArg3(y, v1, v2)
22897                 v.AddArg2(x, v0)
22898                 return true
22899         }
22900         return false
22901 }
22902 func rewriteValueARM64_OpRsh64x8(v *Value) bool {
22903         v_1 := v.Args[1]
22904         v_0 := v.Args[0]
22905         b := v.Block
22906         typ := &b.Func.Config.Types
22907         // match: (Rsh64x8 <t> x y)
22908         // cond: shiftIsBounded(v)
22909         // result: (SRA <t> x y)
22910         for {
22911                 t := v.Type
22912                 x := v_0
22913                 y := v_1
22914                 if !(shiftIsBounded(v)) {
22915                         break
22916                 }
22917                 v.reset(OpARM64SRA)
22918                 v.Type = t
22919                 v.AddArg2(x, y)
22920                 return true
22921         }
22922         // match: (Rsh64x8 x y)
22923         // cond: !shiftIsBounded(v)
22924         // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
22925         for {
22926                 x := v_0
22927                 y := v_1
22928                 if !(!shiftIsBounded(v)) {
22929                         break
22930                 }
22931                 v.reset(OpARM64SRA)
22932                 v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
22933                 v0.AuxInt = opToAuxInt(OpARM64LessThanU)
22934                 v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
22935                 v1.AuxInt = int64ToAuxInt(63)
22936                 v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22937                 v2.AuxInt = int64ToAuxInt(64)
22938                 v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22939                 v3.AddArg(y)
22940                 v2.AddArg(v3)
22941                 v0.AddArg3(y, v1, v2)
22942                 v.AddArg2(x, v0)
22943                 return true
22944         }
22945         return false
22946 }
22947 func rewriteValueARM64_OpRsh8Ux16(v *Value) bool {
22948         v_1 := v.Args[1]
22949         v_0 := v.Args[0]
22950         b := v.Block
22951         typ := &b.Func.Config.Types
22952         // match: (Rsh8Ux16 <t> x y)
22953         // cond: shiftIsBounded(v)
22954         // result: (SRL <t> (ZeroExt8to64 x) y)
22955         for {
22956                 t := v.Type
22957                 x := v_0
22958                 y := v_1
22959                 if !(shiftIsBounded(v)) {
22960                         break
22961                 }
22962                 v.reset(OpARM64SRL)
22963                 v.Type = t
22964                 v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22965                 v0.AddArg(x)
22966                 v.AddArg2(v0, y)
22967                 return true
22968         }
22969         // match: (Rsh8Ux16 <t> x y)
22970         // cond: !shiftIsBounded(v)
22971         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
22972         for {
22973                 t := v.Type
22974                 x := v_0
22975                 y := v_1
22976                 if !(!shiftIsBounded(v)) {
22977                         break
22978                 }
22979                 v.reset(OpARM64CSEL)
22980                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
22981                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
22982                 v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
22983                 v1.AddArg(x)
22984                 v0.AddArg2(v1, y)
22985                 v2 := b.NewValue0(v.Pos, OpConst64, t)
22986                 v2.AuxInt = int64ToAuxInt(0)
22987                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
22988                 v3.AuxInt = int64ToAuxInt(64)
22989                 v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
22990                 v4.AddArg(y)
22991                 v3.AddArg(v4)
22992                 v.AddArg3(v0, v2, v3)
22993                 return true
22994         }
22995         return false
22996 }
22997 func rewriteValueARM64_OpRsh8Ux32(v *Value) bool {
22998         v_1 := v.Args[1]
22999         v_0 := v.Args[0]
23000         b := v.Block
23001         typ := &b.Func.Config.Types
23002         // match: (Rsh8Ux32 <t> x y)
23003         // cond: shiftIsBounded(v)
23004         // result: (SRL <t> (ZeroExt8to64 x) y)
23005         for {
23006                 t := v.Type
23007                 x := v_0
23008                 y := v_1
23009                 if !(shiftIsBounded(v)) {
23010                         break
23011                 }
23012                 v.reset(OpARM64SRL)
23013                 v.Type = t
23014                 v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23015                 v0.AddArg(x)
23016                 v.AddArg2(v0, y)
23017                 return true
23018         }
23019         // match: (Rsh8Ux32 <t> x y)
23020         // cond: !shiftIsBounded(v)
23021         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
23022         for {
23023                 t := v.Type
23024                 x := v_0
23025                 y := v_1
23026                 if !(!shiftIsBounded(v)) {
23027                         break
23028                 }
23029                 v.reset(OpARM64CSEL)
23030                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
23031                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
23032                 v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23033                 v1.AddArg(x)
23034                 v0.AddArg2(v1, y)
23035                 v2 := b.NewValue0(v.Pos, OpConst64, t)
23036                 v2.AuxInt = int64ToAuxInt(0)
23037                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23038                 v3.AuxInt = int64ToAuxInt(64)
23039                 v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
23040                 v4.AddArg(y)
23041                 v3.AddArg(v4)
23042                 v.AddArg3(v0, v2, v3)
23043                 return true
23044         }
23045         return false
23046 }
23047 func rewriteValueARM64_OpRsh8Ux64(v *Value) bool {
23048         v_1 := v.Args[1]
23049         v_0 := v.Args[0]
23050         b := v.Block
23051         typ := &b.Func.Config.Types
23052         // match: (Rsh8Ux64 <t> x y)
23053         // cond: shiftIsBounded(v)
23054         // result: (SRL <t> (ZeroExt8to64 x) y)
23055         for {
23056                 t := v.Type
23057                 x := v_0
23058                 y := v_1
23059                 if !(shiftIsBounded(v)) {
23060                         break
23061                 }
23062                 v.reset(OpARM64SRL)
23063                 v.Type = t
23064                 v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23065                 v0.AddArg(x)
23066                 v.AddArg2(v0, y)
23067                 return true
23068         }
23069         // match: (Rsh8Ux64 <t> x y)
23070         // cond: !shiftIsBounded(v)
23071         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
23072         for {
23073                 t := v.Type
23074                 x := v_0
23075                 y := v_1
23076                 if !(!shiftIsBounded(v)) {
23077                         break
23078                 }
23079                 v.reset(OpARM64CSEL)
23080                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
23081                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
23082                 v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23083                 v1.AddArg(x)
23084                 v0.AddArg2(v1, y)
23085                 v2 := b.NewValue0(v.Pos, OpConst64, t)
23086                 v2.AuxInt = int64ToAuxInt(0)
23087                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23088                 v3.AuxInt = int64ToAuxInt(64)
23089                 v3.AddArg(y)
23090                 v.AddArg3(v0, v2, v3)
23091                 return true
23092         }
23093         return false
23094 }
23095 func rewriteValueARM64_OpRsh8Ux8(v *Value) bool {
23096         v_1 := v.Args[1]
23097         v_0 := v.Args[0]
23098         b := v.Block
23099         typ := &b.Func.Config.Types
23100         // match: (Rsh8Ux8 <t> x y)
23101         // cond: shiftIsBounded(v)
23102         // result: (SRL <t> (ZeroExt8to64 x) y)
23103         for {
23104                 t := v.Type
23105                 x := v_0
23106                 y := v_1
23107                 if !(shiftIsBounded(v)) {
23108                         break
23109                 }
23110                 v.reset(OpARM64SRL)
23111                 v.Type = t
23112                 v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23113                 v0.AddArg(x)
23114                 v.AddArg2(v0, y)
23115                 return true
23116         }
23117         // match: (Rsh8Ux8 <t> x y)
23118         // cond: !shiftIsBounded(v)
23119         // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
23120         for {
23121                 t := v.Type
23122                 x := v_0
23123                 y := v_1
23124                 if !(!shiftIsBounded(v)) {
23125                         break
23126                 }
23127                 v.reset(OpARM64CSEL)
23128                 v.AuxInt = opToAuxInt(OpARM64LessThanU)
23129                 v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
23130                 v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23131                 v1.AddArg(x)
23132                 v0.AddArg2(v1, y)
23133                 v2 := b.NewValue0(v.Pos, OpConst64, t)
23134                 v2.AuxInt = int64ToAuxInt(0)
23135                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23136                 v3.AuxInt = int64ToAuxInt(64)
23137                 v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23138                 v4.AddArg(y)
23139                 v3.AddArg(v4)
23140                 v.AddArg3(v0, v2, v3)
23141                 return true
23142         }
23143         return false
23144 }
23145 func rewriteValueARM64_OpRsh8x16(v *Value) bool {
23146         v_1 := v.Args[1]
23147         v_0 := v.Args[0]
23148         b := v.Block
23149         typ := &b.Func.Config.Types
23150         // match: (Rsh8x16 <t> x y)
23151         // cond: shiftIsBounded(v)
23152         // result: (SRA <t> (SignExt8to64 x) y)
23153         for {
23154                 t := v.Type
23155                 x := v_0
23156                 y := v_1
23157                 if !(shiftIsBounded(v)) {
23158                         break
23159                 }
23160                 v.reset(OpARM64SRA)
23161                 v.Type = t
23162                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23163                 v0.AddArg(x)
23164                 v.AddArg2(v0, y)
23165                 return true
23166         }
23167         // match: (Rsh8x16 x y)
23168         // cond: !shiftIsBounded(v)
23169         // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
23170         for {
23171                 x := v_0
23172                 y := v_1
23173                 if !(!shiftIsBounded(v)) {
23174                         break
23175                 }
23176                 v.reset(OpARM64SRA)
23177                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23178                 v0.AddArg(x)
23179                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
23180                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
23181                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
23182                 v2.AuxInt = int64ToAuxInt(63)
23183                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23184                 v3.AuxInt = int64ToAuxInt(64)
23185                 v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
23186                 v4.AddArg(y)
23187                 v3.AddArg(v4)
23188                 v1.AddArg3(y, v2, v3)
23189                 v.AddArg2(v0, v1)
23190                 return true
23191         }
23192         return false
23193 }
23194 func rewriteValueARM64_OpRsh8x32(v *Value) bool {
23195         v_1 := v.Args[1]
23196         v_0 := v.Args[0]
23197         b := v.Block
23198         typ := &b.Func.Config.Types
23199         // match: (Rsh8x32 <t> x y)
23200         // cond: shiftIsBounded(v)
23201         // result: (SRA <t> (SignExt8to64 x) y)
23202         for {
23203                 t := v.Type
23204                 x := v_0
23205                 y := v_1
23206                 if !(shiftIsBounded(v)) {
23207                         break
23208                 }
23209                 v.reset(OpARM64SRA)
23210                 v.Type = t
23211                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23212                 v0.AddArg(x)
23213                 v.AddArg2(v0, y)
23214                 return true
23215         }
23216         // match: (Rsh8x32 x y)
23217         // cond: !shiftIsBounded(v)
23218         // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
23219         for {
23220                 x := v_0
23221                 y := v_1
23222                 if !(!shiftIsBounded(v)) {
23223                         break
23224                 }
23225                 v.reset(OpARM64SRA)
23226                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23227                 v0.AddArg(x)
23228                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
23229                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
23230                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
23231                 v2.AuxInt = int64ToAuxInt(63)
23232                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23233                 v3.AuxInt = int64ToAuxInt(64)
23234                 v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
23235                 v4.AddArg(y)
23236                 v3.AddArg(v4)
23237                 v1.AddArg3(y, v2, v3)
23238                 v.AddArg2(v0, v1)
23239                 return true
23240         }
23241         return false
23242 }
23243 func rewriteValueARM64_OpRsh8x64(v *Value) bool {
23244         v_1 := v.Args[1]
23245         v_0 := v.Args[0]
23246         b := v.Block
23247         typ := &b.Func.Config.Types
23248         // match: (Rsh8x64 <t> x y)
23249         // cond: shiftIsBounded(v)
23250         // result: (SRA <t> (SignExt8to64 x) y)
23251         for {
23252                 t := v.Type
23253                 x := v_0
23254                 y := v_1
23255                 if !(shiftIsBounded(v)) {
23256                         break
23257                 }
23258                 v.reset(OpARM64SRA)
23259                 v.Type = t
23260                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23261                 v0.AddArg(x)
23262                 v.AddArg2(v0, y)
23263                 return true
23264         }
23265         // match: (Rsh8x64 x y)
23266         // cond: !shiftIsBounded(v)
23267         // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
23268         for {
23269                 x := v_0
23270                 y := v_1
23271                 if !(!shiftIsBounded(v)) {
23272                         break
23273                 }
23274                 v.reset(OpARM64SRA)
23275                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23276                 v0.AddArg(x)
23277                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
23278                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
23279                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
23280                 v2.AuxInt = int64ToAuxInt(63)
23281                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23282                 v3.AuxInt = int64ToAuxInt(64)
23283                 v3.AddArg(y)
23284                 v1.AddArg3(y, v2, v3)
23285                 v.AddArg2(v0, v1)
23286                 return true
23287         }
23288         return false
23289 }
23290 func rewriteValueARM64_OpRsh8x8(v *Value) bool {
23291         v_1 := v.Args[1]
23292         v_0 := v.Args[0]
23293         b := v.Block
23294         typ := &b.Func.Config.Types
23295         // match: (Rsh8x8 <t> x y)
23296         // cond: shiftIsBounded(v)
23297         // result: (SRA <t> (SignExt8to64 x) y)
23298         for {
23299                 t := v.Type
23300                 x := v_0
23301                 y := v_1
23302                 if !(shiftIsBounded(v)) {
23303                         break
23304                 }
23305                 v.reset(OpARM64SRA)
23306                 v.Type = t
23307                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23308                 v0.AddArg(x)
23309                 v.AddArg2(v0, y)
23310                 return true
23311         }
23312         // match: (Rsh8x8 x y)
23313         // cond: !shiftIsBounded(v)
23314         // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
23315         for {
23316                 x := v_0
23317                 y := v_1
23318                 if !(!shiftIsBounded(v)) {
23319                         break
23320                 }
23321                 v.reset(OpARM64SRA)
23322                 v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
23323                 v0.AddArg(x)
23324                 v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
23325                 v1.AuxInt = opToAuxInt(OpARM64LessThanU)
23326                 v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
23327                 v2.AuxInt = int64ToAuxInt(63)
23328                 v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23329                 v3.AuxInt = int64ToAuxInt(64)
23330                 v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
23331                 v4.AddArg(y)
23332                 v3.AddArg(v4)
23333                 v1.AddArg3(y, v2, v3)
23334                 v.AddArg2(v0, v1)
23335                 return true
23336         }
23337         return false
23338 }
23339 func rewriteValueARM64_OpSelect0(v *Value) bool {
23340         v_0 := v.Args[0]
23341         b := v.Block
23342         typ := &b.Func.Config.Types
23343         // match: (Select0 (Mul64uhilo x y))
23344         // result: (UMULH x y)
23345         for {
23346                 if v_0.Op != OpMul64uhilo {
23347                         break
23348                 }
23349                 y := v_0.Args[1]
23350                 x := v_0.Args[0]
23351                 v.reset(OpARM64UMULH)
23352                 v.AddArg2(x, y)
23353                 return true
23354         }
23355         // match: (Select0 (Add64carry x y c))
23356         // result: (Select0 <typ.UInt64> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c))))
23357         for {
23358                 if v_0.Op != OpAdd64carry {
23359                         break
23360                 }
23361                 c := v_0.Args[2]
23362                 x := v_0.Args[0]
23363                 y := v_0.Args[1]
23364                 v.reset(OpSelect0)
23365                 v.Type = typ.UInt64
23366                 v0 := b.NewValue0(v.Pos, OpARM64ADCSflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23367                 v1 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
23368                 v2 := b.NewValue0(v.Pos, OpARM64ADDSconstflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23369                 v2.AuxInt = int64ToAuxInt(-1)
23370                 v2.AddArg(c)
23371                 v1.AddArg(v2)
23372                 v0.AddArg3(x, y, v1)
23373                 v.AddArg(v0)
23374                 return true
23375         }
23376         // match: (Select0 (Sub64borrow x y bo))
23377         // result: (Select0 <typ.UInt64> (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags bo))))
23378         for {
23379                 if v_0.Op != OpSub64borrow {
23380                         break
23381                 }
23382                 bo := v_0.Args[2]
23383                 x := v_0.Args[0]
23384                 y := v_0.Args[1]
23385                 v.reset(OpSelect0)
23386                 v.Type = typ.UInt64
23387                 v0 := b.NewValue0(v.Pos, OpARM64SBCSflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23388                 v1 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
23389                 v2 := b.NewValue0(v.Pos, OpARM64NEGSflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23390                 v2.AddArg(bo)
23391                 v1.AddArg(v2)
23392                 v0.AddArg3(x, y, v1)
23393                 v.AddArg(v0)
23394                 return true
23395         }
23396         // match: (Select0 (Mul64uover x y))
23397         // result: (MUL x y)
23398         for {
23399                 if v_0.Op != OpMul64uover {
23400                         break
23401                 }
23402                 y := v_0.Args[1]
23403                 x := v_0.Args[0]
23404                 v.reset(OpARM64MUL)
23405                 v.AddArg2(x, y)
23406                 return true
23407         }
23408         return false
23409 }
23410 func rewriteValueARM64_OpSelect1(v *Value) bool {
23411         v_0 := v.Args[0]
23412         b := v.Block
23413         typ := &b.Func.Config.Types
23414         // match: (Select1 (Mul64uhilo x y))
23415         // result: (MUL x y)
23416         for {
23417                 if v_0.Op != OpMul64uhilo {
23418                         break
23419                 }
23420                 y := v_0.Args[1]
23421                 x := v_0.Args[0]
23422                 v.reset(OpARM64MUL)
23423                 v.AddArg2(x, y)
23424                 return true
23425         }
23426         // match: (Select1 (Add64carry x y c))
23427         // result: (ADCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c)))))
23428         for {
23429                 if v_0.Op != OpAdd64carry {
23430                         break
23431                 }
23432                 c := v_0.Args[2]
23433                 x := v_0.Args[0]
23434                 y := v_0.Args[1]
23435                 v.reset(OpARM64ADCzerocarry)
23436                 v.Type = typ.UInt64
23437                 v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
23438                 v1 := b.NewValue0(v.Pos, OpARM64ADCSflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23439                 v2 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
23440                 v3 := b.NewValue0(v.Pos, OpARM64ADDSconstflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23441                 v3.AuxInt = int64ToAuxInt(-1)
23442                 v3.AddArg(c)
23443                 v2.AddArg(v3)
23444                 v1.AddArg3(x, y, v2)
23445                 v0.AddArg(v1)
23446                 v.AddArg(v0)
23447                 return true
23448         }
23449         // match: (Select1 (Sub64borrow x y bo))
23450         // result: (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags bo))))))
23451         for {
23452                 if v_0.Op != OpSub64borrow {
23453                         break
23454                 }
23455                 bo := v_0.Args[2]
23456                 x := v_0.Args[0]
23457                 y := v_0.Args[1]
23458                 v.reset(OpARM64NEG)
23459                 v.Type = typ.UInt64
23460                 v0 := b.NewValue0(v.Pos, OpARM64NGCzerocarry, typ.UInt64)
23461                 v1 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
23462                 v2 := b.NewValue0(v.Pos, OpARM64SBCSflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23463                 v3 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
23464                 v4 := b.NewValue0(v.Pos, OpARM64NEGSflags, types.NewTuple(typ.UInt64, types.TypeFlags))
23465                 v4.AddArg(bo)
23466                 v3.AddArg(v4)
23467                 v2.AddArg3(x, y, v3)
23468                 v1.AddArg(v2)
23469                 v0.AddArg(v1)
23470                 v.AddArg(v0)
23471                 return true
23472         }
23473         // match: (Select1 (Mul64uover x y))
23474         // result: (NotEqual (CMPconst (UMULH <typ.UInt64> x y) [0]))
23475         for {
23476                 if v_0.Op != OpMul64uover {
23477                         break
23478                 }
23479                 y := v_0.Args[1]
23480                 x := v_0.Args[0]
23481                 v.reset(OpARM64NotEqual)
23482                 v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
23483                 v0.AuxInt = int64ToAuxInt(0)
23484                 v1 := b.NewValue0(v.Pos, OpARM64UMULH, typ.UInt64)
23485                 v1.AddArg2(x, y)
23486                 v0.AddArg(v1)
23487                 v.AddArg(v0)
23488                 return true
23489         }
23490         return false
23491 }
23492 func rewriteValueARM64_OpSelectN(v *Value) bool {
23493         v_0 := v.Args[0]
23494         b := v.Block
23495         config := b.Func.Config
23496         // match: (SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore _ src s3:(MOVDstore {t} _ dst mem)))))
23497         // cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1, s2, s3, call)
23498         // result: (Move [sz] dst src mem)
23499         for {
23500                 if auxIntToInt64(v.AuxInt) != 0 {
23501                         break
23502                 }
23503                 call := v_0
23504                 if call.Op != OpARM64CALLstatic || len(call.Args) != 1 {
23505                         break
23506                 }
23507                 sym := auxToCall(call.Aux)
23508                 s1 := call.Args[0]
23509                 if s1.Op != OpARM64MOVDstore {
23510                         break
23511                 }
23512                 _ = s1.Args[2]
23513                 s1_1 := s1.Args[1]
23514                 if s1_1.Op != OpARM64MOVDconst {
23515                         break
23516                 }
23517                 sz := auxIntToInt64(s1_1.AuxInt)
23518                 s2 := s1.Args[2]
23519                 if s2.Op != OpARM64MOVDstore {
23520                         break
23521                 }
23522                 _ = s2.Args[2]
23523                 src := s2.Args[1]
23524                 s3 := s2.Args[2]
23525                 if s3.Op != OpARM64MOVDstore {
23526                         break
23527                 }
23528                 mem := s3.Args[2]
23529                 dst := s3.Args[1]
23530                 if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1, s2, s3, call)) {
23531                         break
23532                 }
23533                 v.reset(OpMove)
23534                 v.AuxInt = int64ToAuxInt(sz)
23535                 v.AddArg3(dst, src, mem)
23536                 return true
23537         }
23538         // match: (SelectN [0] call:(CALLstatic {sym} dst src (MOVDconst [sz]) mem))
23539         // cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && call.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(call)
23540         // result: (Move [sz] dst src mem)
23541         for {
23542                 if auxIntToInt64(v.AuxInt) != 0 {
23543                         break
23544                 }
23545                 call := v_0
23546                 if call.Op != OpARM64CALLstatic || len(call.Args) != 4 {
23547                         break
23548                 }
23549                 sym := auxToCall(call.Aux)
23550                 mem := call.Args[3]
23551                 dst := call.Args[0]
23552                 src := call.Args[1]
23553                 call_2 := call.Args[2]
23554                 if call_2.Op != OpARM64MOVDconst {
23555                         break
23556                 }
23557                 sz := auxIntToInt64(call_2.AuxInt)
23558                 if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && call.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(call)) {
23559                         break
23560                 }
23561                 v.reset(OpMove)
23562                 v.AuxInt = int64ToAuxInt(sz)
23563                 v.AddArg3(dst, src, mem)
23564                 return true
23565         }
23566         return false
23567 }
23568 func rewriteValueARM64_OpSlicemask(v *Value) bool {
23569         v_0 := v.Args[0]
23570         b := v.Block
23571         // match: (Slicemask <t> x)
23572         // result: (SRAconst (NEG <t> x) [63])
23573         for {
23574                 t := v.Type
23575                 x := v_0
23576                 v.reset(OpARM64SRAconst)
23577                 v.AuxInt = int64ToAuxInt(63)
23578                 v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
23579                 v0.AddArg(x)
23580                 v.AddArg(v0)
23581                 return true
23582         }
23583 }
23584 func rewriteValueARM64_OpStore(v *Value) bool {
23585         v_2 := v.Args[2]
23586         v_1 := v.Args[1]
23587         v_0 := v.Args[0]
23588         // match: (Store {t} ptr val mem)
23589         // cond: t.Size() == 1
23590         // result: (MOVBstore ptr val mem)
23591         for {
23592                 t := auxToType(v.Aux)
23593                 ptr := v_0
23594                 val := v_1
23595                 mem := v_2
23596                 if !(t.Size() == 1) {
23597                         break
23598                 }
23599                 v.reset(OpARM64MOVBstore)
23600                 v.AddArg3(ptr, val, mem)
23601                 return true
23602         }
23603         // match: (Store {t} ptr val mem)
23604         // cond: t.Size() == 2
23605         // result: (MOVHstore ptr val mem)
23606         for {
23607                 t := auxToType(v.Aux)
23608                 ptr := v_0
23609                 val := v_1
23610                 mem := v_2
23611                 if !(t.Size() == 2) {
23612                         break
23613                 }
23614                 v.reset(OpARM64MOVHstore)
23615                 v.AddArg3(ptr, val, mem)
23616                 return true
23617         }
23618         // match: (Store {t} ptr val mem)
23619         // cond: t.Size() == 4 && !t.IsFloat()
23620         // result: (MOVWstore ptr val mem)
23621         for {
23622                 t := auxToType(v.Aux)
23623                 ptr := v_0
23624                 val := v_1
23625                 mem := v_2
23626                 if !(t.Size() == 4 && !t.IsFloat()) {
23627                         break
23628                 }
23629                 v.reset(OpARM64MOVWstore)
23630                 v.AddArg3(ptr, val, mem)
23631                 return true
23632         }
23633         // match: (Store {t} ptr val mem)
23634         // cond: t.Size() == 8 && !t.IsFloat()
23635         // result: (MOVDstore ptr val mem)
23636         for {
23637                 t := auxToType(v.Aux)
23638                 ptr := v_0
23639                 val := v_1
23640                 mem := v_2
23641                 if !(t.Size() == 8 && !t.IsFloat()) {
23642                         break
23643                 }
23644                 v.reset(OpARM64MOVDstore)
23645                 v.AddArg3(ptr, val, mem)
23646                 return true
23647         }
23648         // match: (Store {t} ptr val mem)
23649         // cond: t.Size() == 4 && t.IsFloat()
23650         // result: (FMOVSstore ptr val mem)
23651         for {
23652                 t := auxToType(v.Aux)
23653                 ptr := v_0
23654                 val := v_1
23655                 mem := v_2
23656                 if !(t.Size() == 4 && t.IsFloat()) {
23657                         break
23658                 }
23659                 v.reset(OpARM64FMOVSstore)
23660                 v.AddArg3(ptr, val, mem)
23661                 return true
23662         }
23663         // match: (Store {t} ptr val mem)
23664         // cond: t.Size() == 8 && t.IsFloat()
23665         // result: (FMOVDstore ptr val mem)
23666         for {
23667                 t := auxToType(v.Aux)
23668                 ptr := v_0
23669                 val := v_1
23670                 mem := v_2
23671                 if !(t.Size() == 8 && t.IsFloat()) {
23672                         break
23673                 }
23674                 v.reset(OpARM64FMOVDstore)
23675                 v.AddArg3(ptr, val, mem)
23676                 return true
23677         }
23678         return false
23679 }
23680 func rewriteValueARM64_OpZero(v *Value) bool {
23681         v_1 := v.Args[1]
23682         v_0 := v.Args[0]
23683         b := v.Block
23684         config := b.Func.Config
23685         typ := &b.Func.Config.Types
23686         // match: (Zero [0] _ mem)
23687         // result: mem
23688         for {
23689                 if auxIntToInt64(v.AuxInt) != 0 {
23690                         break
23691                 }
23692                 mem := v_1
23693                 v.copyOf(mem)
23694                 return true
23695         }
23696         // match: (Zero [1] ptr mem)
23697         // result: (MOVBstore ptr (MOVDconst [0]) mem)
23698         for {
23699                 if auxIntToInt64(v.AuxInt) != 1 {
23700                         break
23701                 }
23702                 ptr := v_0
23703                 mem := v_1
23704                 v.reset(OpARM64MOVBstore)
23705                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23706                 v0.AuxInt = int64ToAuxInt(0)
23707                 v.AddArg3(ptr, v0, mem)
23708                 return true
23709         }
23710         // match: (Zero [2] ptr mem)
23711         // result: (MOVHstore ptr (MOVDconst [0]) mem)
23712         for {
23713                 if auxIntToInt64(v.AuxInt) != 2 {
23714                         break
23715                 }
23716                 ptr := v_0
23717                 mem := v_1
23718                 v.reset(OpARM64MOVHstore)
23719                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23720                 v0.AuxInt = int64ToAuxInt(0)
23721                 v.AddArg3(ptr, v0, mem)
23722                 return true
23723         }
23724         // match: (Zero [4] ptr mem)
23725         // result: (MOVWstore ptr (MOVDconst [0]) mem)
23726         for {
23727                 if auxIntToInt64(v.AuxInt) != 4 {
23728                         break
23729                 }
23730                 ptr := v_0
23731                 mem := v_1
23732                 v.reset(OpARM64MOVWstore)
23733                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23734                 v0.AuxInt = int64ToAuxInt(0)
23735                 v.AddArg3(ptr, v0, mem)
23736                 return true
23737         }
23738         // match: (Zero [3] ptr mem)
23739         // result: (MOVBstore [2] ptr (MOVDconst [0]) (MOVHstore ptr (MOVDconst [0]) mem))
23740         for {
23741                 if auxIntToInt64(v.AuxInt) != 3 {
23742                         break
23743                 }
23744                 ptr := v_0
23745                 mem := v_1
23746                 v.reset(OpARM64MOVBstore)
23747                 v.AuxInt = int32ToAuxInt(2)
23748                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23749                 v0.AuxInt = int64ToAuxInt(0)
23750                 v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
23751                 v1.AddArg3(ptr, v0, mem)
23752                 v.AddArg3(ptr, v0, v1)
23753                 return true
23754         }
23755         // match: (Zero [5] ptr mem)
23756         // result: (MOVBstore [4] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem))
23757         for {
23758                 if auxIntToInt64(v.AuxInt) != 5 {
23759                         break
23760                 }
23761                 ptr := v_0
23762                 mem := v_1
23763                 v.reset(OpARM64MOVBstore)
23764                 v.AuxInt = int32ToAuxInt(4)
23765                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23766                 v0.AuxInt = int64ToAuxInt(0)
23767                 v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
23768                 v1.AddArg3(ptr, v0, mem)
23769                 v.AddArg3(ptr, v0, v1)
23770                 return true
23771         }
23772         // match: (Zero [6] ptr mem)
23773         // result: (MOVHstore [4] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem))
23774         for {
23775                 if auxIntToInt64(v.AuxInt) != 6 {
23776                         break
23777                 }
23778                 ptr := v_0
23779                 mem := v_1
23780                 v.reset(OpARM64MOVHstore)
23781                 v.AuxInt = int32ToAuxInt(4)
23782                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23783                 v0.AuxInt = int64ToAuxInt(0)
23784                 v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
23785                 v1.AddArg3(ptr, v0, mem)
23786                 v.AddArg3(ptr, v0, v1)
23787                 return true
23788         }
23789         // match: (Zero [7] ptr mem)
23790         // result: (MOVWstore [3] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem))
23791         for {
23792                 if auxIntToInt64(v.AuxInt) != 7 {
23793                         break
23794                 }
23795                 ptr := v_0
23796                 mem := v_1
23797                 v.reset(OpARM64MOVWstore)
23798                 v.AuxInt = int32ToAuxInt(3)
23799                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23800                 v0.AuxInt = int64ToAuxInt(0)
23801                 v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
23802                 v1.AddArg3(ptr, v0, mem)
23803                 v.AddArg3(ptr, v0, v1)
23804                 return true
23805         }
23806         // match: (Zero [8] ptr mem)
23807         // result: (MOVDstore ptr (MOVDconst [0]) mem)
23808         for {
23809                 if auxIntToInt64(v.AuxInt) != 8 {
23810                         break
23811                 }
23812                 ptr := v_0
23813                 mem := v_1
23814                 v.reset(OpARM64MOVDstore)
23815                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23816                 v0.AuxInt = int64ToAuxInt(0)
23817                 v.AddArg3(ptr, v0, mem)
23818                 return true
23819         }
23820         // match: (Zero [9] ptr mem)
23821         // result: (MOVBstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23822         for {
23823                 if auxIntToInt64(v.AuxInt) != 9 {
23824                         break
23825                 }
23826                 ptr := v_0
23827                 mem := v_1
23828                 v.reset(OpARM64MOVBstore)
23829                 v.AuxInt = int32ToAuxInt(8)
23830                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23831                 v0.AuxInt = int64ToAuxInt(0)
23832                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23833                 v1.AddArg3(ptr, v0, mem)
23834                 v.AddArg3(ptr, v0, v1)
23835                 return true
23836         }
23837         // match: (Zero [10] ptr mem)
23838         // result: (MOVHstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23839         for {
23840                 if auxIntToInt64(v.AuxInt) != 10 {
23841                         break
23842                 }
23843                 ptr := v_0
23844                 mem := v_1
23845                 v.reset(OpARM64MOVHstore)
23846                 v.AuxInt = int32ToAuxInt(8)
23847                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23848                 v0.AuxInt = int64ToAuxInt(0)
23849                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23850                 v1.AddArg3(ptr, v0, mem)
23851                 v.AddArg3(ptr, v0, v1)
23852                 return true
23853         }
23854         // match: (Zero [11] ptr mem)
23855         // result: (MOVDstore [3] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23856         for {
23857                 if auxIntToInt64(v.AuxInt) != 11 {
23858                         break
23859                 }
23860                 ptr := v_0
23861                 mem := v_1
23862                 v.reset(OpARM64MOVDstore)
23863                 v.AuxInt = int32ToAuxInt(3)
23864                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23865                 v0.AuxInt = int64ToAuxInt(0)
23866                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23867                 v1.AddArg3(ptr, v0, mem)
23868                 v.AddArg3(ptr, v0, v1)
23869                 return true
23870         }
23871         // match: (Zero [12] ptr mem)
23872         // result: (MOVWstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23873         for {
23874                 if auxIntToInt64(v.AuxInt) != 12 {
23875                         break
23876                 }
23877                 ptr := v_0
23878                 mem := v_1
23879                 v.reset(OpARM64MOVWstore)
23880                 v.AuxInt = int32ToAuxInt(8)
23881                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23882                 v0.AuxInt = int64ToAuxInt(0)
23883                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23884                 v1.AddArg3(ptr, v0, mem)
23885                 v.AddArg3(ptr, v0, v1)
23886                 return true
23887         }
23888         // match: (Zero [13] ptr mem)
23889         // result: (MOVDstore [5] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23890         for {
23891                 if auxIntToInt64(v.AuxInt) != 13 {
23892                         break
23893                 }
23894                 ptr := v_0
23895                 mem := v_1
23896                 v.reset(OpARM64MOVDstore)
23897                 v.AuxInt = int32ToAuxInt(5)
23898                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23899                 v0.AuxInt = int64ToAuxInt(0)
23900                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23901                 v1.AddArg3(ptr, v0, mem)
23902                 v.AddArg3(ptr, v0, v1)
23903                 return true
23904         }
23905         // match: (Zero [14] ptr mem)
23906         // result: (MOVDstore [6] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23907         for {
23908                 if auxIntToInt64(v.AuxInt) != 14 {
23909                         break
23910                 }
23911                 ptr := v_0
23912                 mem := v_1
23913                 v.reset(OpARM64MOVDstore)
23914                 v.AuxInt = int32ToAuxInt(6)
23915                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23916                 v0.AuxInt = int64ToAuxInt(0)
23917                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23918                 v1.AddArg3(ptr, v0, mem)
23919                 v.AddArg3(ptr, v0, v1)
23920                 return true
23921         }
23922         // match: (Zero [15] ptr mem)
23923         // result: (MOVDstore [7] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
23924         for {
23925                 if auxIntToInt64(v.AuxInt) != 15 {
23926                         break
23927                 }
23928                 ptr := v_0
23929                 mem := v_1
23930                 v.reset(OpARM64MOVDstore)
23931                 v.AuxInt = int32ToAuxInt(7)
23932                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23933                 v0.AuxInt = int64ToAuxInt(0)
23934                 v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
23935                 v1.AddArg3(ptr, v0, mem)
23936                 v.AddArg3(ptr, v0, v1)
23937                 return true
23938         }
23939         // match: (Zero [16] ptr mem)
23940         // result: (STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)
23941         for {
23942                 if auxIntToInt64(v.AuxInt) != 16 {
23943                         break
23944                 }
23945                 ptr := v_0
23946                 mem := v_1
23947                 v.reset(OpARM64STP)
23948                 v.AuxInt = int32ToAuxInt(0)
23949                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23950                 v0.AuxInt = int64ToAuxInt(0)
23951                 v.AddArg4(ptr, v0, v0, mem)
23952                 return true
23953         }
23954         // match: (Zero [32] ptr mem)
23955         // result: (STP [16] ptr (MOVDconst [0]) (MOVDconst [0]) (STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))
23956         for {
23957                 if auxIntToInt64(v.AuxInt) != 32 {
23958                         break
23959                 }
23960                 ptr := v_0
23961                 mem := v_1
23962                 v.reset(OpARM64STP)
23963                 v.AuxInt = int32ToAuxInt(16)
23964                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23965                 v0.AuxInt = int64ToAuxInt(0)
23966                 v1 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
23967                 v1.AuxInt = int32ToAuxInt(0)
23968                 v1.AddArg4(ptr, v0, v0, mem)
23969                 v.AddArg4(ptr, v0, v0, v1)
23970                 return true
23971         }
23972         // match: (Zero [48] ptr mem)
23973         // result: (STP [32] ptr (MOVDconst [0]) (MOVDconst [0]) (STP [16] ptr (MOVDconst [0]) (MOVDconst [0]) (STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)))
23974         for {
23975                 if auxIntToInt64(v.AuxInt) != 48 {
23976                         break
23977                 }
23978                 ptr := v_0
23979                 mem := v_1
23980                 v.reset(OpARM64STP)
23981                 v.AuxInt = int32ToAuxInt(32)
23982                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
23983                 v0.AuxInt = int64ToAuxInt(0)
23984                 v1 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
23985                 v1.AuxInt = int32ToAuxInt(16)
23986                 v2 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
23987                 v2.AuxInt = int32ToAuxInt(0)
23988                 v2.AddArg4(ptr, v0, v0, mem)
23989                 v1.AddArg4(ptr, v0, v0, v2)
23990                 v.AddArg4(ptr, v0, v0, v1)
23991                 return true
23992         }
23993         // match: (Zero [64] ptr mem)
23994         // result: (STP [48] ptr (MOVDconst [0]) (MOVDconst [0]) (STP [32] ptr (MOVDconst [0]) (MOVDconst [0]) (STP [16] ptr (MOVDconst [0]) (MOVDconst [0]) (STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))))
23995         for {
23996                 if auxIntToInt64(v.AuxInt) != 64 {
23997                         break
23998                 }
23999                 ptr := v_0
24000                 mem := v_1
24001                 v.reset(OpARM64STP)
24002                 v.AuxInt = int32ToAuxInt(48)
24003                 v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
24004                 v0.AuxInt = int64ToAuxInt(0)
24005                 v1 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
24006                 v1.AuxInt = int32ToAuxInt(32)
24007                 v2 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
24008                 v2.AuxInt = int32ToAuxInt(16)
24009                 v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
24010                 v3.AuxInt = int32ToAuxInt(0)
24011                 v3.AddArg4(ptr, v0, v0, mem)
24012                 v2.AddArg4(ptr, v0, v0, v3)
24013                 v1.AddArg4(ptr, v0, v0, v2)
24014                 v.AddArg4(ptr, v0, v0, v1)
24015                 return true
24016         }
24017         // match: (Zero [s] ptr mem)
24018         // cond: s%16 != 0 && s%16 <= 8 && s > 16
24019         // result: (Zero [8] (OffPtr <ptr.Type> ptr [s-8]) (Zero [s-s%16] ptr mem))
24020         for {
24021                 s := auxIntToInt64(v.AuxInt)
24022                 ptr := v_0
24023                 mem := v_1
24024                 if !(s%16 != 0 && s%16 <= 8 && s > 16) {
24025                         break
24026                 }
24027                 v.reset(OpZero)
24028                 v.AuxInt = int64ToAuxInt(8)
24029                 v0 := b.NewValue0(v.Pos, OpOffPtr, ptr.Type)
24030                 v0.AuxInt = int64ToAuxInt(s - 8)
24031                 v0.AddArg(ptr)
24032                 v1 := b.NewValue0(v.Pos, OpZero, types.TypeMem)
24033                 v1.AuxInt = int64ToAuxInt(s - s%16)
24034                 v1.AddArg2(ptr, mem)
24035                 v.AddArg2(v0, v1)
24036                 return true
24037         }
24038         // match: (Zero [s] ptr mem)
24039         // cond: s%16 != 0 && s%16 > 8 && s > 16
24040         // result: (Zero [16] (OffPtr <ptr.Type> ptr [s-16]) (Zero [s-s%16] ptr mem))
24041         for {
24042                 s := auxIntToInt64(v.AuxInt)
24043                 ptr := v_0
24044                 mem := v_1
24045                 if !(s%16 != 0 && s%16 > 8 && s > 16) {
24046                         break
24047                 }
24048                 v.reset(OpZero)
24049                 v.AuxInt = int64ToAuxInt(16)
24050                 v0 := b.NewValue0(v.Pos, OpOffPtr, ptr.Type)
24051                 v0.AuxInt = int64ToAuxInt(s - 16)
24052                 v0.AddArg(ptr)
24053                 v1 := b.NewValue0(v.Pos, OpZero, types.TypeMem)
24054                 v1.AuxInt = int64ToAuxInt(s - s%16)
24055                 v1.AddArg2(ptr, mem)
24056                 v.AddArg2(v0, v1)
24057                 return true
24058         }
24059         // match: (Zero [s] ptr mem)
24060         // cond: s%16 == 0 && s > 64 && s <= 16*64 && !config.noDuffDevice
24061         // result: (DUFFZERO [4 * (64 - s/16)] ptr mem)
24062         for {
24063                 s := auxIntToInt64(v.AuxInt)
24064                 ptr := v_0
24065                 mem := v_1
24066                 if !(s%16 == 0 && s > 64 && s <= 16*64 && !config.noDuffDevice) {
24067                         break
24068                 }
24069                 v.reset(OpARM64DUFFZERO)
24070                 v.AuxInt = int64ToAuxInt(4 * (64 - s/16))
24071                 v.AddArg2(ptr, mem)
24072                 return true
24073         }
24074         // match: (Zero [s] ptr mem)
24075         // cond: s%16 == 0 && (s > 16*64 || config.noDuffDevice)
24076         // result: (LoweredZero ptr (ADDconst <ptr.Type> [s-16] ptr) mem)
24077         for {
24078                 s := auxIntToInt64(v.AuxInt)
24079                 ptr := v_0
24080                 mem := v_1
24081                 if !(s%16 == 0 && (s > 16*64 || config.noDuffDevice)) {
24082                         break
24083                 }
24084                 v.reset(OpARM64LoweredZero)
24085                 v0 := b.NewValue0(v.Pos, OpARM64ADDconst, ptr.Type)
24086                 v0.AuxInt = int64ToAuxInt(s - 16)
24087                 v0.AddArg(ptr)
24088                 v.AddArg3(ptr, v0, mem)
24089                 return true
24090         }
24091         return false
24092 }
24093 func rewriteBlockARM64(b *Block) bool {
24094         typ := &b.Func.Config.Types
24095         switch b.Kind {
24096         case BlockARM64EQ:
24097                 // match: (EQ (CMPconst [0] z:(AND x y)) yes no)
24098                 // cond: z.Uses == 1
24099                 // result: (EQ (TST x y) yes no)
24100                 for b.Controls[0].Op == OpARM64CMPconst {
24101                         v_0 := b.Controls[0]
24102                         if auxIntToInt64(v_0.AuxInt) != 0 {
24103                                 break
24104                         }
24105                         z := v_0.Args[0]
24106                         if z.Op != OpARM64AND {
24107                                 break
24108                         }
24109                         _ = z.Args[1]
24110                         z_0 := z.Args[0]
24111                         z_1 := z.Args[1]
24112                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24113                                 x := z_0
24114                                 y := z_1
24115                                 if !(z.Uses == 1) {
24116                                         continue
24117                                 }
24118                                 v0 := b.NewValue0(v_0.Pos, OpARM64TST, types.TypeFlags)
24119                                 v0.AddArg2(x, y)
24120                                 b.resetWithControl(BlockARM64EQ, v0)
24121                                 return true
24122                         }
24123                         break
24124                 }
24125                 // match: (EQ (CMPconst [0] x:(ANDconst [c] y)) yes no)
24126                 // cond: x.Uses == 1
24127                 // result: (EQ (TSTconst [c] y) yes no)
24128                 for b.Controls[0].Op == OpARM64CMPconst {
24129                         v_0 := b.Controls[0]
24130                         if auxIntToInt64(v_0.AuxInt) != 0 {
24131                                 break
24132                         }
24133                         x := v_0.Args[0]
24134                         if x.Op != OpARM64ANDconst {
24135                                 break
24136                         }
24137                         c := auxIntToInt64(x.AuxInt)
24138                         y := x.Args[0]
24139                         if !(x.Uses == 1) {
24140                                 break
24141                         }
24142                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
24143                         v0.AuxInt = int64ToAuxInt(c)
24144                         v0.AddArg(y)
24145                         b.resetWithControl(BlockARM64EQ, v0)
24146                         return true
24147                 }
24148                 // match: (EQ (CMPWconst [0] z:(AND x y)) yes no)
24149                 // cond: z.Uses == 1
24150                 // result: (EQ (TSTW x y) yes no)
24151                 for b.Controls[0].Op == OpARM64CMPWconst {
24152                         v_0 := b.Controls[0]
24153                         if auxIntToInt32(v_0.AuxInt) != 0 {
24154                                 break
24155                         }
24156                         z := v_0.Args[0]
24157                         if z.Op != OpARM64AND {
24158                                 break
24159                         }
24160                         _ = z.Args[1]
24161                         z_0 := z.Args[0]
24162                         z_1 := z.Args[1]
24163                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24164                                 x := z_0
24165                                 y := z_1
24166                                 if !(z.Uses == 1) {
24167                                         continue
24168                                 }
24169                                 v0 := b.NewValue0(v_0.Pos, OpARM64TSTW, types.TypeFlags)
24170                                 v0.AddArg2(x, y)
24171                                 b.resetWithControl(BlockARM64EQ, v0)
24172                                 return true
24173                         }
24174                         break
24175                 }
24176                 // match: (EQ (CMPWconst [0] x:(ANDconst [c] y)) yes no)
24177                 // cond: x.Uses == 1
24178                 // result: (EQ (TSTWconst [int32(c)] y) yes no)
24179                 for b.Controls[0].Op == OpARM64CMPWconst {
24180                         v_0 := b.Controls[0]
24181                         if auxIntToInt32(v_0.AuxInt) != 0 {
24182                                 break
24183                         }
24184                         x := v_0.Args[0]
24185                         if x.Op != OpARM64ANDconst {
24186                                 break
24187                         }
24188                         c := auxIntToInt64(x.AuxInt)
24189                         y := x.Args[0]
24190                         if !(x.Uses == 1) {
24191                                 break
24192                         }
24193                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
24194                         v0.AuxInt = int32ToAuxInt(int32(c))
24195                         v0.AddArg(y)
24196                         b.resetWithControl(BlockARM64EQ, v0)
24197                         return true
24198                 }
24199                 // match: (EQ (CMPconst [0] x:(ADDconst [c] y)) yes no)
24200                 // cond: x.Uses == 1
24201                 // result: (EQ (CMNconst [c] y) yes no)
24202                 for b.Controls[0].Op == OpARM64CMPconst {
24203                         v_0 := b.Controls[0]
24204                         if auxIntToInt64(v_0.AuxInt) != 0 {
24205                                 break
24206                         }
24207                         x := v_0.Args[0]
24208                         if x.Op != OpARM64ADDconst {
24209                                 break
24210                         }
24211                         c := auxIntToInt64(x.AuxInt)
24212                         y := x.Args[0]
24213                         if !(x.Uses == 1) {
24214                                 break
24215                         }
24216                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNconst, types.TypeFlags)
24217                         v0.AuxInt = int64ToAuxInt(c)
24218                         v0.AddArg(y)
24219                         b.resetWithControl(BlockARM64EQ, v0)
24220                         return true
24221                 }
24222                 // match: (EQ (CMPWconst [0] x:(ADDconst [c] y)) yes no)
24223                 // cond: x.Uses == 1
24224                 // result: (EQ (CMNWconst [int32(c)] y) yes no)
24225                 for b.Controls[0].Op == OpARM64CMPWconst {
24226                         v_0 := b.Controls[0]
24227                         if auxIntToInt32(v_0.AuxInt) != 0 {
24228                                 break
24229                         }
24230                         x := v_0.Args[0]
24231                         if x.Op != OpARM64ADDconst {
24232                                 break
24233                         }
24234                         c := auxIntToInt64(x.AuxInt)
24235                         y := x.Args[0]
24236                         if !(x.Uses == 1) {
24237                                 break
24238                         }
24239                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNWconst, types.TypeFlags)
24240                         v0.AuxInt = int32ToAuxInt(int32(c))
24241                         v0.AddArg(y)
24242                         b.resetWithControl(BlockARM64EQ, v0)
24243                         return true
24244                 }
24245                 // match: (EQ (CMPconst [0] z:(ADD x y)) yes no)
24246                 // cond: z.Uses == 1
24247                 // result: (EQ (CMN x y) yes no)
24248                 for b.Controls[0].Op == OpARM64CMPconst {
24249                         v_0 := b.Controls[0]
24250                         if auxIntToInt64(v_0.AuxInt) != 0 {
24251                                 break
24252                         }
24253                         z := v_0.Args[0]
24254                         if z.Op != OpARM64ADD {
24255                                 break
24256                         }
24257                         _ = z.Args[1]
24258                         z_0 := z.Args[0]
24259                         z_1 := z.Args[1]
24260                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24261                                 x := z_0
24262                                 y := z_1
24263                                 if !(z.Uses == 1) {
24264                                         continue
24265                                 }
24266                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
24267                                 v0.AddArg2(x, y)
24268                                 b.resetWithControl(BlockARM64EQ, v0)
24269                                 return true
24270                         }
24271                         break
24272                 }
24273                 // match: (EQ (CMPWconst [0] z:(ADD x y)) yes no)
24274                 // cond: z.Uses == 1
24275                 // result: (EQ (CMNW x y) yes no)
24276                 for b.Controls[0].Op == OpARM64CMPWconst {
24277                         v_0 := b.Controls[0]
24278                         if auxIntToInt32(v_0.AuxInt) != 0 {
24279                                 break
24280                         }
24281                         z := v_0.Args[0]
24282                         if z.Op != OpARM64ADD {
24283                                 break
24284                         }
24285                         _ = z.Args[1]
24286                         z_0 := z.Args[0]
24287                         z_1 := z.Args[1]
24288                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24289                                 x := z_0
24290                                 y := z_1
24291                                 if !(z.Uses == 1) {
24292                                         continue
24293                                 }
24294                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
24295                                 v0.AddArg2(x, y)
24296                                 b.resetWithControl(BlockARM64EQ, v0)
24297                                 return true
24298                         }
24299                         break
24300                 }
24301                 // match: (EQ (CMP x z:(NEG y)) yes no)
24302                 // cond: z.Uses == 1
24303                 // result: (EQ (CMN x y) yes no)
24304                 for b.Controls[0].Op == OpARM64CMP {
24305                         v_0 := b.Controls[0]
24306                         _ = v_0.Args[1]
24307                         x := v_0.Args[0]
24308                         z := v_0.Args[1]
24309                         if z.Op != OpARM64NEG {
24310                                 break
24311                         }
24312                         y := z.Args[0]
24313                         if !(z.Uses == 1) {
24314                                 break
24315                         }
24316                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
24317                         v0.AddArg2(x, y)
24318                         b.resetWithControl(BlockARM64EQ, v0)
24319                         return true
24320                 }
24321                 // match: (EQ (CMPW x z:(NEG y)) yes no)
24322                 // cond: z.Uses == 1
24323                 // result: (EQ (CMNW x y) yes no)
24324                 for b.Controls[0].Op == OpARM64CMPW {
24325                         v_0 := b.Controls[0]
24326                         _ = v_0.Args[1]
24327                         x := v_0.Args[0]
24328                         z := v_0.Args[1]
24329                         if z.Op != OpARM64NEG {
24330                                 break
24331                         }
24332                         y := z.Args[0]
24333                         if !(z.Uses == 1) {
24334                                 break
24335                         }
24336                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
24337                         v0.AddArg2(x, y)
24338                         b.resetWithControl(BlockARM64EQ, v0)
24339                         return true
24340                 }
24341                 // match: (EQ (CMPconst [0] x) yes no)
24342                 // result: (Z x yes no)
24343                 for b.Controls[0].Op == OpARM64CMPconst {
24344                         v_0 := b.Controls[0]
24345                         if auxIntToInt64(v_0.AuxInt) != 0 {
24346                                 break
24347                         }
24348                         x := v_0.Args[0]
24349                         b.resetWithControl(BlockARM64Z, x)
24350                         return true
24351                 }
24352                 // match: (EQ (CMPWconst [0] x) yes no)
24353                 // result: (ZW x yes no)
24354                 for b.Controls[0].Op == OpARM64CMPWconst {
24355                         v_0 := b.Controls[0]
24356                         if auxIntToInt32(v_0.AuxInt) != 0 {
24357                                 break
24358                         }
24359                         x := v_0.Args[0]
24360                         b.resetWithControl(BlockARM64ZW, x)
24361                         return true
24362                 }
24363                 // match: (EQ (CMPconst [0] z:(MADD a x y)) yes no)
24364                 // cond: z.Uses==1
24365                 // result: (EQ (CMN a (MUL <x.Type> x y)) yes no)
24366                 for b.Controls[0].Op == OpARM64CMPconst {
24367                         v_0 := b.Controls[0]
24368                         if auxIntToInt64(v_0.AuxInt) != 0 {
24369                                 break
24370                         }
24371                         z := v_0.Args[0]
24372                         if z.Op != OpARM64MADD {
24373                                 break
24374                         }
24375                         y := z.Args[2]
24376                         a := z.Args[0]
24377                         x := z.Args[1]
24378                         if !(z.Uses == 1) {
24379                                 break
24380                         }
24381                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
24382                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
24383                         v1.AddArg2(x, y)
24384                         v0.AddArg2(a, v1)
24385                         b.resetWithControl(BlockARM64EQ, v0)
24386                         return true
24387                 }
24388                 // match: (EQ (CMPconst [0] z:(MSUB a x y)) yes no)
24389                 // cond: z.Uses==1
24390                 // result: (EQ (CMP a (MUL <x.Type> x y)) yes no)
24391                 for b.Controls[0].Op == OpARM64CMPconst {
24392                         v_0 := b.Controls[0]
24393                         if auxIntToInt64(v_0.AuxInt) != 0 {
24394                                 break
24395                         }
24396                         z := v_0.Args[0]
24397                         if z.Op != OpARM64MSUB {
24398                                 break
24399                         }
24400                         y := z.Args[2]
24401                         a := z.Args[0]
24402                         x := z.Args[1]
24403                         if !(z.Uses == 1) {
24404                                 break
24405                         }
24406                         v0 := b.NewValue0(v_0.Pos, OpARM64CMP, types.TypeFlags)
24407                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
24408                         v1.AddArg2(x, y)
24409                         v0.AddArg2(a, v1)
24410                         b.resetWithControl(BlockARM64EQ, v0)
24411                         return true
24412                 }
24413                 // match: (EQ (CMPWconst [0] z:(MADDW a x y)) yes no)
24414                 // cond: z.Uses==1
24415                 // result: (EQ (CMNW a (MULW <x.Type> x y)) yes no)
24416                 for b.Controls[0].Op == OpARM64CMPWconst {
24417                         v_0 := b.Controls[0]
24418                         if auxIntToInt32(v_0.AuxInt) != 0 {
24419                                 break
24420                         }
24421                         z := v_0.Args[0]
24422                         if z.Op != OpARM64MADDW {
24423                                 break
24424                         }
24425                         y := z.Args[2]
24426                         a := z.Args[0]
24427                         x := z.Args[1]
24428                         if !(z.Uses == 1) {
24429                                 break
24430                         }
24431                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
24432                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
24433                         v1.AddArg2(x, y)
24434                         v0.AddArg2(a, v1)
24435                         b.resetWithControl(BlockARM64EQ, v0)
24436                         return true
24437                 }
24438                 // match: (EQ (CMPWconst [0] z:(MSUBW a x y)) yes no)
24439                 // cond: z.Uses==1
24440                 // result: (EQ (CMPW a (MULW <x.Type> x y)) yes no)
24441                 for b.Controls[0].Op == OpARM64CMPWconst {
24442                         v_0 := b.Controls[0]
24443                         if auxIntToInt32(v_0.AuxInt) != 0 {
24444                                 break
24445                         }
24446                         z := v_0.Args[0]
24447                         if z.Op != OpARM64MSUBW {
24448                                 break
24449                         }
24450                         y := z.Args[2]
24451                         a := z.Args[0]
24452                         x := z.Args[1]
24453                         if !(z.Uses == 1) {
24454                                 break
24455                         }
24456                         v0 := b.NewValue0(v_0.Pos, OpARM64CMPW, types.TypeFlags)
24457                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
24458                         v1.AddArg2(x, y)
24459                         v0.AddArg2(a, v1)
24460                         b.resetWithControl(BlockARM64EQ, v0)
24461                         return true
24462                 }
24463                 // match: (EQ (TSTconst [c] x) yes no)
24464                 // cond: oneBit(c)
24465                 // result: (TBZ [int64(ntz64(c))] x yes no)
24466                 for b.Controls[0].Op == OpARM64TSTconst {
24467                         v_0 := b.Controls[0]
24468                         c := auxIntToInt64(v_0.AuxInt)
24469                         x := v_0.Args[0]
24470                         if !(oneBit(c)) {
24471                                 break
24472                         }
24473                         b.resetWithControl(BlockARM64TBZ, x)
24474                         b.AuxInt = int64ToAuxInt(int64(ntz64(c)))
24475                         return true
24476                 }
24477                 // match: (EQ (TSTWconst [c] x) yes no)
24478                 // cond: oneBit(int64(uint32(c)))
24479                 // result: (TBZ [int64(ntz64(int64(uint32(c))))] x yes no)
24480                 for b.Controls[0].Op == OpARM64TSTWconst {
24481                         v_0 := b.Controls[0]
24482                         c := auxIntToInt32(v_0.AuxInt)
24483                         x := v_0.Args[0]
24484                         if !(oneBit(int64(uint32(c)))) {
24485                                 break
24486                         }
24487                         b.resetWithControl(BlockARM64TBZ, x)
24488                         b.AuxInt = int64ToAuxInt(int64(ntz64(int64(uint32(c)))))
24489                         return true
24490                 }
24491                 // match: (EQ (FlagConstant [fc]) yes no)
24492                 // cond: fc.eq()
24493                 // result: (First yes no)
24494                 for b.Controls[0].Op == OpARM64FlagConstant {
24495                         v_0 := b.Controls[0]
24496                         fc := auxIntToFlagConstant(v_0.AuxInt)
24497                         if !(fc.eq()) {
24498                                 break
24499                         }
24500                         b.Reset(BlockFirst)
24501                         return true
24502                 }
24503                 // match: (EQ (FlagConstant [fc]) yes no)
24504                 // cond: !fc.eq()
24505                 // result: (First no yes)
24506                 for b.Controls[0].Op == OpARM64FlagConstant {
24507                         v_0 := b.Controls[0]
24508                         fc := auxIntToFlagConstant(v_0.AuxInt)
24509                         if !(!fc.eq()) {
24510                                 break
24511                         }
24512                         b.Reset(BlockFirst)
24513                         b.swapSuccessors()
24514                         return true
24515                 }
24516                 // match: (EQ (InvertFlags cmp) yes no)
24517                 // result: (EQ cmp yes no)
24518                 for b.Controls[0].Op == OpARM64InvertFlags {
24519                         v_0 := b.Controls[0]
24520                         cmp := v_0.Args[0]
24521                         b.resetWithControl(BlockARM64EQ, cmp)
24522                         return true
24523                 }
24524         case BlockARM64FGE:
24525                 // match: (FGE (InvertFlags cmp) yes no)
24526                 // result: (FLE cmp yes no)
24527                 for b.Controls[0].Op == OpARM64InvertFlags {
24528                         v_0 := b.Controls[0]
24529                         cmp := v_0.Args[0]
24530                         b.resetWithControl(BlockARM64FLE, cmp)
24531                         return true
24532                 }
24533         case BlockARM64FGT:
24534                 // match: (FGT (InvertFlags cmp) yes no)
24535                 // result: (FLT cmp yes no)
24536                 for b.Controls[0].Op == OpARM64InvertFlags {
24537                         v_0 := b.Controls[0]
24538                         cmp := v_0.Args[0]
24539                         b.resetWithControl(BlockARM64FLT, cmp)
24540                         return true
24541                 }
24542         case BlockARM64FLE:
24543                 // match: (FLE (InvertFlags cmp) yes no)
24544                 // result: (FGE cmp yes no)
24545                 for b.Controls[0].Op == OpARM64InvertFlags {
24546                         v_0 := b.Controls[0]
24547                         cmp := v_0.Args[0]
24548                         b.resetWithControl(BlockARM64FGE, cmp)
24549                         return true
24550                 }
24551         case BlockARM64FLT:
24552                 // match: (FLT (InvertFlags cmp) yes no)
24553                 // result: (FGT cmp yes no)
24554                 for b.Controls[0].Op == OpARM64InvertFlags {
24555                         v_0 := b.Controls[0]
24556                         cmp := v_0.Args[0]
24557                         b.resetWithControl(BlockARM64FGT, cmp)
24558                         return true
24559                 }
24560         case BlockARM64GE:
24561                 // match: (GE (CMPconst [0] z:(AND x y)) yes no)
24562                 // cond: z.Uses == 1
24563                 // result: (GE (TST x y) yes no)
24564                 for b.Controls[0].Op == OpARM64CMPconst {
24565                         v_0 := b.Controls[0]
24566                         if auxIntToInt64(v_0.AuxInt) != 0 {
24567                                 break
24568                         }
24569                         z := v_0.Args[0]
24570                         if z.Op != OpARM64AND {
24571                                 break
24572                         }
24573                         _ = z.Args[1]
24574                         z_0 := z.Args[0]
24575                         z_1 := z.Args[1]
24576                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24577                                 x := z_0
24578                                 y := z_1
24579                                 if !(z.Uses == 1) {
24580                                         continue
24581                                 }
24582                                 v0 := b.NewValue0(v_0.Pos, OpARM64TST, types.TypeFlags)
24583                                 v0.AddArg2(x, y)
24584                                 b.resetWithControl(BlockARM64GE, v0)
24585                                 return true
24586                         }
24587                         break
24588                 }
24589                 // match: (GE (CMPconst [0] x:(ANDconst [c] y)) yes no)
24590                 // cond: x.Uses == 1
24591                 // result: (GE (TSTconst [c] y) yes no)
24592                 for b.Controls[0].Op == OpARM64CMPconst {
24593                         v_0 := b.Controls[0]
24594                         if auxIntToInt64(v_0.AuxInt) != 0 {
24595                                 break
24596                         }
24597                         x := v_0.Args[0]
24598                         if x.Op != OpARM64ANDconst {
24599                                 break
24600                         }
24601                         c := auxIntToInt64(x.AuxInt)
24602                         y := x.Args[0]
24603                         if !(x.Uses == 1) {
24604                                 break
24605                         }
24606                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
24607                         v0.AuxInt = int64ToAuxInt(c)
24608                         v0.AddArg(y)
24609                         b.resetWithControl(BlockARM64GE, v0)
24610                         return true
24611                 }
24612                 // match: (GE (CMPWconst [0] z:(AND x y)) yes no)
24613                 // cond: z.Uses == 1
24614                 // result: (GE (TSTW x y) yes no)
24615                 for b.Controls[0].Op == OpARM64CMPWconst {
24616                         v_0 := b.Controls[0]
24617                         if auxIntToInt32(v_0.AuxInt) != 0 {
24618                                 break
24619                         }
24620                         z := v_0.Args[0]
24621                         if z.Op != OpARM64AND {
24622                                 break
24623                         }
24624                         _ = z.Args[1]
24625                         z_0 := z.Args[0]
24626                         z_1 := z.Args[1]
24627                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24628                                 x := z_0
24629                                 y := z_1
24630                                 if !(z.Uses == 1) {
24631                                         continue
24632                                 }
24633                                 v0 := b.NewValue0(v_0.Pos, OpARM64TSTW, types.TypeFlags)
24634                                 v0.AddArg2(x, y)
24635                                 b.resetWithControl(BlockARM64GE, v0)
24636                                 return true
24637                         }
24638                         break
24639                 }
24640                 // match: (GE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
24641                 // cond: x.Uses == 1
24642                 // result: (GE (TSTWconst [int32(c)] y) yes no)
24643                 for b.Controls[0].Op == OpARM64CMPWconst {
24644                         v_0 := b.Controls[0]
24645                         if auxIntToInt32(v_0.AuxInt) != 0 {
24646                                 break
24647                         }
24648                         x := v_0.Args[0]
24649                         if x.Op != OpARM64ANDconst {
24650                                 break
24651                         }
24652                         c := auxIntToInt64(x.AuxInt)
24653                         y := x.Args[0]
24654                         if !(x.Uses == 1) {
24655                                 break
24656                         }
24657                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
24658                         v0.AuxInt = int32ToAuxInt(int32(c))
24659                         v0.AddArg(y)
24660                         b.resetWithControl(BlockARM64GE, v0)
24661                         return true
24662                 }
24663                 // match: (GE (CMPconst [0] x:(ADDconst [c] y)) yes no)
24664                 // cond: x.Uses == 1
24665                 // result: (GEnoov (CMNconst [c] y) yes no)
24666                 for b.Controls[0].Op == OpARM64CMPconst {
24667                         v_0 := b.Controls[0]
24668                         if auxIntToInt64(v_0.AuxInt) != 0 {
24669                                 break
24670                         }
24671                         x := v_0.Args[0]
24672                         if x.Op != OpARM64ADDconst {
24673                                 break
24674                         }
24675                         c := auxIntToInt64(x.AuxInt)
24676                         y := x.Args[0]
24677                         if !(x.Uses == 1) {
24678                                 break
24679                         }
24680                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNconst, types.TypeFlags)
24681                         v0.AuxInt = int64ToAuxInt(c)
24682                         v0.AddArg(y)
24683                         b.resetWithControl(BlockARM64GEnoov, v0)
24684                         return true
24685                 }
24686                 // match: (GE (CMPWconst [0] x:(ADDconst [c] y)) yes no)
24687                 // cond: x.Uses == 1
24688                 // result: (GEnoov (CMNWconst [int32(c)] y) yes no)
24689                 for b.Controls[0].Op == OpARM64CMPWconst {
24690                         v_0 := b.Controls[0]
24691                         if auxIntToInt32(v_0.AuxInt) != 0 {
24692                                 break
24693                         }
24694                         x := v_0.Args[0]
24695                         if x.Op != OpARM64ADDconst {
24696                                 break
24697                         }
24698                         c := auxIntToInt64(x.AuxInt)
24699                         y := x.Args[0]
24700                         if !(x.Uses == 1) {
24701                                 break
24702                         }
24703                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNWconst, types.TypeFlags)
24704                         v0.AuxInt = int32ToAuxInt(int32(c))
24705                         v0.AddArg(y)
24706                         b.resetWithControl(BlockARM64GEnoov, v0)
24707                         return true
24708                 }
24709                 // match: (GE (CMPconst [0] z:(ADD x y)) yes no)
24710                 // cond: z.Uses == 1
24711                 // result: (GEnoov (CMN x y) yes no)
24712                 for b.Controls[0].Op == OpARM64CMPconst {
24713                         v_0 := b.Controls[0]
24714                         if auxIntToInt64(v_0.AuxInt) != 0 {
24715                                 break
24716                         }
24717                         z := v_0.Args[0]
24718                         if z.Op != OpARM64ADD {
24719                                 break
24720                         }
24721                         _ = z.Args[1]
24722                         z_0 := z.Args[0]
24723                         z_1 := z.Args[1]
24724                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24725                                 x := z_0
24726                                 y := z_1
24727                                 if !(z.Uses == 1) {
24728                                         continue
24729                                 }
24730                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
24731                                 v0.AddArg2(x, y)
24732                                 b.resetWithControl(BlockARM64GEnoov, v0)
24733                                 return true
24734                         }
24735                         break
24736                 }
24737                 // match: (GE (CMPWconst [0] z:(ADD x y)) yes no)
24738                 // cond: z.Uses == 1
24739                 // result: (GEnoov (CMNW x y) yes no)
24740                 for b.Controls[0].Op == OpARM64CMPWconst {
24741                         v_0 := b.Controls[0]
24742                         if auxIntToInt32(v_0.AuxInt) != 0 {
24743                                 break
24744                         }
24745                         z := v_0.Args[0]
24746                         if z.Op != OpARM64ADD {
24747                                 break
24748                         }
24749                         _ = z.Args[1]
24750                         z_0 := z.Args[0]
24751                         z_1 := z.Args[1]
24752                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24753                                 x := z_0
24754                                 y := z_1
24755                                 if !(z.Uses == 1) {
24756                                         continue
24757                                 }
24758                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
24759                                 v0.AddArg2(x, y)
24760                                 b.resetWithControl(BlockARM64GEnoov, v0)
24761                                 return true
24762                         }
24763                         break
24764                 }
24765                 // match: (GE (CMPconst [0] z:(MADD a x y)) yes no)
24766                 // cond: z.Uses==1
24767                 // result: (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
24768                 for b.Controls[0].Op == OpARM64CMPconst {
24769                         v_0 := b.Controls[0]
24770                         if auxIntToInt64(v_0.AuxInt) != 0 {
24771                                 break
24772                         }
24773                         z := v_0.Args[0]
24774                         if z.Op != OpARM64MADD {
24775                                 break
24776                         }
24777                         y := z.Args[2]
24778                         a := z.Args[0]
24779                         x := z.Args[1]
24780                         if !(z.Uses == 1) {
24781                                 break
24782                         }
24783                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
24784                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
24785                         v1.AddArg2(x, y)
24786                         v0.AddArg2(a, v1)
24787                         b.resetWithControl(BlockARM64GEnoov, v0)
24788                         return true
24789                 }
24790                 // match: (GE (CMPconst [0] z:(MSUB a x y)) yes no)
24791                 // cond: z.Uses==1
24792                 // result: (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
24793                 for b.Controls[0].Op == OpARM64CMPconst {
24794                         v_0 := b.Controls[0]
24795                         if auxIntToInt64(v_0.AuxInt) != 0 {
24796                                 break
24797                         }
24798                         z := v_0.Args[0]
24799                         if z.Op != OpARM64MSUB {
24800                                 break
24801                         }
24802                         y := z.Args[2]
24803                         a := z.Args[0]
24804                         x := z.Args[1]
24805                         if !(z.Uses == 1) {
24806                                 break
24807                         }
24808                         v0 := b.NewValue0(v_0.Pos, OpARM64CMP, types.TypeFlags)
24809                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
24810                         v1.AddArg2(x, y)
24811                         v0.AddArg2(a, v1)
24812                         b.resetWithControl(BlockARM64GEnoov, v0)
24813                         return true
24814                 }
24815                 // match: (GE (CMPWconst [0] z:(MADDW a x y)) yes no)
24816                 // cond: z.Uses==1
24817                 // result: (GEnoov (CMNW a (MULW <x.Type> x y)) yes no)
24818                 for b.Controls[0].Op == OpARM64CMPWconst {
24819                         v_0 := b.Controls[0]
24820                         if auxIntToInt32(v_0.AuxInt) != 0 {
24821                                 break
24822                         }
24823                         z := v_0.Args[0]
24824                         if z.Op != OpARM64MADDW {
24825                                 break
24826                         }
24827                         y := z.Args[2]
24828                         a := z.Args[0]
24829                         x := z.Args[1]
24830                         if !(z.Uses == 1) {
24831                                 break
24832                         }
24833                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
24834                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
24835                         v1.AddArg2(x, y)
24836                         v0.AddArg2(a, v1)
24837                         b.resetWithControl(BlockARM64GEnoov, v0)
24838                         return true
24839                 }
24840                 // match: (GE (CMPWconst [0] z:(MSUBW a x y)) yes no)
24841                 // cond: z.Uses==1
24842                 // result: (GEnoov (CMPW a (MULW <x.Type> x y)) yes no)
24843                 for b.Controls[0].Op == OpARM64CMPWconst {
24844                         v_0 := b.Controls[0]
24845                         if auxIntToInt32(v_0.AuxInt) != 0 {
24846                                 break
24847                         }
24848                         z := v_0.Args[0]
24849                         if z.Op != OpARM64MSUBW {
24850                                 break
24851                         }
24852                         y := z.Args[2]
24853                         a := z.Args[0]
24854                         x := z.Args[1]
24855                         if !(z.Uses == 1) {
24856                                 break
24857                         }
24858                         v0 := b.NewValue0(v_0.Pos, OpARM64CMPW, types.TypeFlags)
24859                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
24860                         v1.AddArg2(x, y)
24861                         v0.AddArg2(a, v1)
24862                         b.resetWithControl(BlockARM64GEnoov, v0)
24863                         return true
24864                 }
24865                 // match: (GE (CMPWconst [0] x) yes no)
24866                 // result: (TBZ [31] x yes no)
24867                 for b.Controls[0].Op == OpARM64CMPWconst {
24868                         v_0 := b.Controls[0]
24869                         if auxIntToInt32(v_0.AuxInt) != 0 {
24870                                 break
24871                         }
24872                         x := v_0.Args[0]
24873                         b.resetWithControl(BlockARM64TBZ, x)
24874                         b.AuxInt = int64ToAuxInt(31)
24875                         return true
24876                 }
24877                 // match: (GE (CMPconst [0] x) yes no)
24878                 // result: (TBZ [63] x yes no)
24879                 for b.Controls[0].Op == OpARM64CMPconst {
24880                         v_0 := b.Controls[0]
24881                         if auxIntToInt64(v_0.AuxInt) != 0 {
24882                                 break
24883                         }
24884                         x := v_0.Args[0]
24885                         b.resetWithControl(BlockARM64TBZ, x)
24886                         b.AuxInt = int64ToAuxInt(63)
24887                         return true
24888                 }
24889                 // match: (GE (FlagConstant [fc]) yes no)
24890                 // cond: fc.ge()
24891                 // result: (First yes no)
24892                 for b.Controls[0].Op == OpARM64FlagConstant {
24893                         v_0 := b.Controls[0]
24894                         fc := auxIntToFlagConstant(v_0.AuxInt)
24895                         if !(fc.ge()) {
24896                                 break
24897                         }
24898                         b.Reset(BlockFirst)
24899                         return true
24900                 }
24901                 // match: (GE (FlagConstant [fc]) yes no)
24902                 // cond: !fc.ge()
24903                 // result: (First no yes)
24904                 for b.Controls[0].Op == OpARM64FlagConstant {
24905                         v_0 := b.Controls[0]
24906                         fc := auxIntToFlagConstant(v_0.AuxInt)
24907                         if !(!fc.ge()) {
24908                                 break
24909                         }
24910                         b.Reset(BlockFirst)
24911                         b.swapSuccessors()
24912                         return true
24913                 }
24914                 // match: (GE (InvertFlags cmp) yes no)
24915                 // result: (LE cmp yes no)
24916                 for b.Controls[0].Op == OpARM64InvertFlags {
24917                         v_0 := b.Controls[0]
24918                         cmp := v_0.Args[0]
24919                         b.resetWithControl(BlockARM64LE, cmp)
24920                         return true
24921                 }
24922         case BlockARM64GEnoov:
24923                 // match: (GEnoov (FlagConstant [fc]) yes no)
24924                 // cond: fc.geNoov()
24925                 // result: (First yes no)
24926                 for b.Controls[0].Op == OpARM64FlagConstant {
24927                         v_0 := b.Controls[0]
24928                         fc := auxIntToFlagConstant(v_0.AuxInt)
24929                         if !(fc.geNoov()) {
24930                                 break
24931                         }
24932                         b.Reset(BlockFirst)
24933                         return true
24934                 }
24935                 // match: (GEnoov (FlagConstant [fc]) yes no)
24936                 // cond: !fc.geNoov()
24937                 // result: (First no yes)
24938                 for b.Controls[0].Op == OpARM64FlagConstant {
24939                         v_0 := b.Controls[0]
24940                         fc := auxIntToFlagConstant(v_0.AuxInt)
24941                         if !(!fc.geNoov()) {
24942                                 break
24943                         }
24944                         b.Reset(BlockFirst)
24945                         b.swapSuccessors()
24946                         return true
24947                 }
24948                 // match: (GEnoov (InvertFlags cmp) yes no)
24949                 // result: (LEnoov cmp yes no)
24950                 for b.Controls[0].Op == OpARM64InvertFlags {
24951                         v_0 := b.Controls[0]
24952                         cmp := v_0.Args[0]
24953                         b.resetWithControl(BlockARM64LEnoov, cmp)
24954                         return true
24955                 }
24956         case BlockARM64GT:
24957                 // match: (GT (CMPconst [0] z:(AND x y)) yes no)
24958                 // cond: z.Uses == 1
24959                 // result: (GT (TST x y) yes no)
24960                 for b.Controls[0].Op == OpARM64CMPconst {
24961                         v_0 := b.Controls[0]
24962                         if auxIntToInt64(v_0.AuxInt) != 0 {
24963                                 break
24964                         }
24965                         z := v_0.Args[0]
24966                         if z.Op != OpARM64AND {
24967                                 break
24968                         }
24969                         _ = z.Args[1]
24970                         z_0 := z.Args[0]
24971                         z_1 := z.Args[1]
24972                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
24973                                 x := z_0
24974                                 y := z_1
24975                                 if !(z.Uses == 1) {
24976                                         continue
24977                                 }
24978                                 v0 := b.NewValue0(v_0.Pos, OpARM64TST, types.TypeFlags)
24979                                 v0.AddArg2(x, y)
24980                                 b.resetWithControl(BlockARM64GT, v0)
24981                                 return true
24982                         }
24983                         break
24984                 }
24985                 // match: (GT (CMPconst [0] x:(ANDconst [c] y)) yes no)
24986                 // cond: x.Uses == 1
24987                 // result: (GT (TSTconst [c] y) yes no)
24988                 for b.Controls[0].Op == OpARM64CMPconst {
24989                         v_0 := b.Controls[0]
24990                         if auxIntToInt64(v_0.AuxInt) != 0 {
24991                                 break
24992                         }
24993                         x := v_0.Args[0]
24994                         if x.Op != OpARM64ANDconst {
24995                                 break
24996                         }
24997                         c := auxIntToInt64(x.AuxInt)
24998                         y := x.Args[0]
24999                         if !(x.Uses == 1) {
25000                                 break
25001                         }
25002                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
25003                         v0.AuxInt = int64ToAuxInt(c)
25004                         v0.AddArg(y)
25005                         b.resetWithControl(BlockARM64GT, v0)
25006                         return true
25007                 }
25008                 // match: (GT (CMPWconst [0] z:(AND x y)) yes no)
25009                 // cond: z.Uses == 1
25010                 // result: (GT (TSTW x y) yes no)
25011                 for b.Controls[0].Op == OpARM64CMPWconst {
25012                         v_0 := b.Controls[0]
25013                         if auxIntToInt32(v_0.AuxInt) != 0 {
25014                                 break
25015                         }
25016                         z := v_0.Args[0]
25017                         if z.Op != OpARM64AND {
25018                                 break
25019                         }
25020                         _ = z.Args[1]
25021                         z_0 := z.Args[0]
25022                         z_1 := z.Args[1]
25023                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25024                                 x := z_0
25025                                 y := z_1
25026                                 if !(z.Uses == 1) {
25027                                         continue
25028                                 }
25029                                 v0 := b.NewValue0(v_0.Pos, OpARM64TSTW, types.TypeFlags)
25030                                 v0.AddArg2(x, y)
25031                                 b.resetWithControl(BlockARM64GT, v0)
25032                                 return true
25033                         }
25034                         break
25035                 }
25036                 // match: (GT (CMPWconst [0] x:(ANDconst [c] y)) yes no)
25037                 // cond: x.Uses == 1
25038                 // result: (GT (TSTWconst [int32(c)] y) yes no)
25039                 for b.Controls[0].Op == OpARM64CMPWconst {
25040                         v_0 := b.Controls[0]
25041                         if auxIntToInt32(v_0.AuxInt) != 0 {
25042                                 break
25043                         }
25044                         x := v_0.Args[0]
25045                         if x.Op != OpARM64ANDconst {
25046                                 break
25047                         }
25048                         c := auxIntToInt64(x.AuxInt)
25049                         y := x.Args[0]
25050                         if !(x.Uses == 1) {
25051                                 break
25052                         }
25053                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
25054                         v0.AuxInt = int32ToAuxInt(int32(c))
25055                         v0.AddArg(y)
25056                         b.resetWithControl(BlockARM64GT, v0)
25057                         return true
25058                 }
25059                 // match: (GT (CMPconst [0] x:(ADDconst [c] y)) yes no)
25060                 // cond: x.Uses == 1
25061                 // result: (GTnoov (CMNconst [c] y) yes no)
25062                 for b.Controls[0].Op == OpARM64CMPconst {
25063                         v_0 := b.Controls[0]
25064                         if auxIntToInt64(v_0.AuxInt) != 0 {
25065                                 break
25066                         }
25067                         x := v_0.Args[0]
25068                         if x.Op != OpARM64ADDconst {
25069                                 break
25070                         }
25071                         c := auxIntToInt64(x.AuxInt)
25072                         y := x.Args[0]
25073                         if !(x.Uses == 1) {
25074                                 break
25075                         }
25076                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNconst, types.TypeFlags)
25077                         v0.AuxInt = int64ToAuxInt(c)
25078                         v0.AddArg(y)
25079                         b.resetWithControl(BlockARM64GTnoov, v0)
25080                         return true
25081                 }
25082                 // match: (GT (CMPWconst [0] x:(ADDconst [c] y)) yes no)
25083                 // cond: x.Uses == 1
25084                 // result: (GTnoov (CMNWconst [int32(c)] y) yes no)
25085                 for b.Controls[0].Op == OpARM64CMPWconst {
25086                         v_0 := b.Controls[0]
25087                         if auxIntToInt32(v_0.AuxInt) != 0 {
25088                                 break
25089                         }
25090                         x := v_0.Args[0]
25091                         if x.Op != OpARM64ADDconst {
25092                                 break
25093                         }
25094                         c := auxIntToInt64(x.AuxInt)
25095                         y := x.Args[0]
25096                         if !(x.Uses == 1) {
25097                                 break
25098                         }
25099                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNWconst, types.TypeFlags)
25100                         v0.AuxInt = int32ToAuxInt(int32(c))
25101                         v0.AddArg(y)
25102                         b.resetWithControl(BlockARM64GTnoov, v0)
25103                         return true
25104                 }
25105                 // match: (GT (CMPconst [0] z:(ADD x y)) yes no)
25106                 // cond: z.Uses == 1
25107                 // result: (GTnoov (CMN x y) yes no)
25108                 for b.Controls[0].Op == OpARM64CMPconst {
25109                         v_0 := b.Controls[0]
25110                         if auxIntToInt64(v_0.AuxInt) != 0 {
25111                                 break
25112                         }
25113                         z := v_0.Args[0]
25114                         if z.Op != OpARM64ADD {
25115                                 break
25116                         }
25117                         _ = z.Args[1]
25118                         z_0 := z.Args[0]
25119                         z_1 := z.Args[1]
25120                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25121                                 x := z_0
25122                                 y := z_1
25123                                 if !(z.Uses == 1) {
25124                                         continue
25125                                 }
25126                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
25127                                 v0.AddArg2(x, y)
25128                                 b.resetWithControl(BlockARM64GTnoov, v0)
25129                                 return true
25130                         }
25131                         break
25132                 }
25133                 // match: (GT (CMPWconst [0] z:(ADD x y)) yes no)
25134                 // cond: z.Uses == 1
25135                 // result: (GTnoov (CMNW x y) yes no)
25136                 for b.Controls[0].Op == OpARM64CMPWconst {
25137                         v_0 := b.Controls[0]
25138                         if auxIntToInt32(v_0.AuxInt) != 0 {
25139                                 break
25140                         }
25141                         z := v_0.Args[0]
25142                         if z.Op != OpARM64ADD {
25143                                 break
25144                         }
25145                         _ = z.Args[1]
25146                         z_0 := z.Args[0]
25147                         z_1 := z.Args[1]
25148                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25149                                 x := z_0
25150                                 y := z_1
25151                                 if !(z.Uses == 1) {
25152                                         continue
25153                                 }
25154                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
25155                                 v0.AddArg2(x, y)
25156                                 b.resetWithControl(BlockARM64GTnoov, v0)
25157                                 return true
25158                         }
25159                         break
25160                 }
25161                 // match: (GT (CMPconst [0] z:(MADD a x y)) yes no)
25162                 // cond: z.Uses==1
25163                 // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
25164                 for b.Controls[0].Op == OpARM64CMPconst {
25165                         v_0 := b.Controls[0]
25166                         if auxIntToInt64(v_0.AuxInt) != 0 {
25167                                 break
25168                         }
25169                         z := v_0.Args[0]
25170                         if z.Op != OpARM64MADD {
25171                                 break
25172                         }
25173                         y := z.Args[2]
25174                         a := z.Args[0]
25175                         x := z.Args[1]
25176                         if !(z.Uses == 1) {
25177                                 break
25178                         }
25179                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
25180                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
25181                         v1.AddArg2(x, y)
25182                         v0.AddArg2(a, v1)
25183                         b.resetWithControl(BlockARM64GTnoov, v0)
25184                         return true
25185                 }
25186                 // match: (GT (CMPconst [0] z:(MSUB a x y)) yes no)
25187                 // cond: z.Uses==1
25188                 // result: (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
25189                 for b.Controls[0].Op == OpARM64CMPconst {
25190                         v_0 := b.Controls[0]
25191                         if auxIntToInt64(v_0.AuxInt) != 0 {
25192                                 break
25193                         }
25194                         z := v_0.Args[0]
25195                         if z.Op != OpARM64MSUB {
25196                                 break
25197                         }
25198                         y := z.Args[2]
25199                         a := z.Args[0]
25200                         x := z.Args[1]
25201                         if !(z.Uses == 1) {
25202                                 break
25203                         }
25204                         v0 := b.NewValue0(v_0.Pos, OpARM64CMP, types.TypeFlags)
25205                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
25206                         v1.AddArg2(x, y)
25207                         v0.AddArg2(a, v1)
25208                         b.resetWithControl(BlockARM64GTnoov, v0)
25209                         return true
25210                 }
25211                 // match: (GT (CMPWconst [0] z:(MADDW a x y)) yes no)
25212                 // cond: z.Uses==1
25213                 // result: (GTnoov (CMNW a (MULW <x.Type> x y)) yes no)
25214                 for b.Controls[0].Op == OpARM64CMPWconst {
25215                         v_0 := b.Controls[0]
25216                         if auxIntToInt32(v_0.AuxInt) != 0 {
25217                                 break
25218                         }
25219                         z := v_0.Args[0]
25220                         if z.Op != OpARM64MADDW {
25221                                 break
25222                         }
25223                         y := z.Args[2]
25224                         a := z.Args[0]
25225                         x := z.Args[1]
25226                         if !(z.Uses == 1) {
25227                                 break
25228                         }
25229                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
25230                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
25231                         v1.AddArg2(x, y)
25232                         v0.AddArg2(a, v1)
25233                         b.resetWithControl(BlockARM64GTnoov, v0)
25234                         return true
25235                 }
25236                 // match: (GT (CMPWconst [0] z:(MSUBW a x y)) yes no)
25237                 // cond: z.Uses==1
25238                 // result: (GTnoov (CMPW a (MULW <x.Type> x y)) yes no)
25239                 for b.Controls[0].Op == OpARM64CMPWconst {
25240                         v_0 := b.Controls[0]
25241                         if auxIntToInt32(v_0.AuxInt) != 0 {
25242                                 break
25243                         }
25244                         z := v_0.Args[0]
25245                         if z.Op != OpARM64MSUBW {
25246                                 break
25247                         }
25248                         y := z.Args[2]
25249                         a := z.Args[0]
25250                         x := z.Args[1]
25251                         if !(z.Uses == 1) {
25252                                 break
25253                         }
25254                         v0 := b.NewValue0(v_0.Pos, OpARM64CMPW, types.TypeFlags)
25255                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
25256                         v1.AddArg2(x, y)
25257                         v0.AddArg2(a, v1)
25258                         b.resetWithControl(BlockARM64GTnoov, v0)
25259                         return true
25260                 }
25261                 // match: (GT (FlagConstant [fc]) yes no)
25262                 // cond: fc.gt()
25263                 // result: (First yes no)
25264                 for b.Controls[0].Op == OpARM64FlagConstant {
25265                         v_0 := b.Controls[0]
25266                         fc := auxIntToFlagConstant(v_0.AuxInt)
25267                         if !(fc.gt()) {
25268                                 break
25269                         }
25270                         b.Reset(BlockFirst)
25271                         return true
25272                 }
25273                 // match: (GT (FlagConstant [fc]) yes no)
25274                 // cond: !fc.gt()
25275                 // result: (First no yes)
25276                 for b.Controls[0].Op == OpARM64FlagConstant {
25277                         v_0 := b.Controls[0]
25278                         fc := auxIntToFlagConstant(v_0.AuxInt)
25279                         if !(!fc.gt()) {
25280                                 break
25281                         }
25282                         b.Reset(BlockFirst)
25283                         b.swapSuccessors()
25284                         return true
25285                 }
25286                 // match: (GT (InvertFlags cmp) yes no)
25287                 // result: (LT cmp yes no)
25288                 for b.Controls[0].Op == OpARM64InvertFlags {
25289                         v_0 := b.Controls[0]
25290                         cmp := v_0.Args[0]
25291                         b.resetWithControl(BlockARM64LT, cmp)
25292                         return true
25293                 }
25294         case BlockARM64GTnoov:
25295                 // match: (GTnoov (FlagConstant [fc]) yes no)
25296                 // cond: fc.gtNoov()
25297                 // result: (First yes no)
25298                 for b.Controls[0].Op == OpARM64FlagConstant {
25299                         v_0 := b.Controls[0]
25300                         fc := auxIntToFlagConstant(v_0.AuxInt)
25301                         if !(fc.gtNoov()) {
25302                                 break
25303                         }
25304                         b.Reset(BlockFirst)
25305                         return true
25306                 }
25307                 // match: (GTnoov (FlagConstant [fc]) yes no)
25308                 // cond: !fc.gtNoov()
25309                 // result: (First no yes)
25310                 for b.Controls[0].Op == OpARM64FlagConstant {
25311                         v_0 := b.Controls[0]
25312                         fc := auxIntToFlagConstant(v_0.AuxInt)
25313                         if !(!fc.gtNoov()) {
25314                                 break
25315                         }
25316                         b.Reset(BlockFirst)
25317                         b.swapSuccessors()
25318                         return true
25319                 }
25320                 // match: (GTnoov (InvertFlags cmp) yes no)
25321                 // result: (LTnoov cmp yes no)
25322                 for b.Controls[0].Op == OpARM64InvertFlags {
25323                         v_0 := b.Controls[0]
25324                         cmp := v_0.Args[0]
25325                         b.resetWithControl(BlockARM64LTnoov, cmp)
25326                         return true
25327                 }
25328         case BlockIf:
25329                 // match: (If (Equal cc) yes no)
25330                 // result: (EQ cc yes no)
25331                 for b.Controls[0].Op == OpARM64Equal {
25332                         v_0 := b.Controls[0]
25333                         cc := v_0.Args[0]
25334                         b.resetWithControl(BlockARM64EQ, cc)
25335                         return true
25336                 }
25337                 // match: (If (NotEqual cc) yes no)
25338                 // result: (NE cc yes no)
25339                 for b.Controls[0].Op == OpARM64NotEqual {
25340                         v_0 := b.Controls[0]
25341                         cc := v_0.Args[0]
25342                         b.resetWithControl(BlockARM64NE, cc)
25343                         return true
25344                 }
25345                 // match: (If (LessThan cc) yes no)
25346                 // result: (LT cc yes no)
25347                 for b.Controls[0].Op == OpARM64LessThan {
25348                         v_0 := b.Controls[0]
25349                         cc := v_0.Args[0]
25350                         b.resetWithControl(BlockARM64LT, cc)
25351                         return true
25352                 }
25353                 // match: (If (LessThanU cc) yes no)
25354                 // result: (ULT cc yes no)
25355                 for b.Controls[0].Op == OpARM64LessThanU {
25356                         v_0 := b.Controls[0]
25357                         cc := v_0.Args[0]
25358                         b.resetWithControl(BlockARM64ULT, cc)
25359                         return true
25360                 }
25361                 // match: (If (LessEqual cc) yes no)
25362                 // result: (LE cc yes no)
25363                 for b.Controls[0].Op == OpARM64LessEqual {
25364                         v_0 := b.Controls[0]
25365                         cc := v_0.Args[0]
25366                         b.resetWithControl(BlockARM64LE, cc)
25367                         return true
25368                 }
25369                 // match: (If (LessEqualU cc) yes no)
25370                 // result: (ULE cc yes no)
25371                 for b.Controls[0].Op == OpARM64LessEqualU {
25372                         v_0 := b.Controls[0]
25373                         cc := v_0.Args[0]
25374                         b.resetWithControl(BlockARM64ULE, cc)
25375                         return true
25376                 }
25377                 // match: (If (GreaterThan cc) yes no)
25378                 // result: (GT cc yes no)
25379                 for b.Controls[0].Op == OpARM64GreaterThan {
25380                         v_0 := b.Controls[0]
25381                         cc := v_0.Args[0]
25382                         b.resetWithControl(BlockARM64GT, cc)
25383                         return true
25384                 }
25385                 // match: (If (GreaterThanU cc) yes no)
25386                 // result: (UGT cc yes no)
25387                 for b.Controls[0].Op == OpARM64GreaterThanU {
25388                         v_0 := b.Controls[0]
25389                         cc := v_0.Args[0]
25390                         b.resetWithControl(BlockARM64UGT, cc)
25391                         return true
25392                 }
25393                 // match: (If (GreaterEqual cc) yes no)
25394                 // result: (GE cc yes no)
25395                 for b.Controls[0].Op == OpARM64GreaterEqual {
25396                         v_0 := b.Controls[0]
25397                         cc := v_0.Args[0]
25398                         b.resetWithControl(BlockARM64GE, cc)
25399                         return true
25400                 }
25401                 // match: (If (GreaterEqualU cc) yes no)
25402                 // result: (UGE cc yes no)
25403                 for b.Controls[0].Op == OpARM64GreaterEqualU {
25404                         v_0 := b.Controls[0]
25405                         cc := v_0.Args[0]
25406                         b.resetWithControl(BlockARM64UGE, cc)
25407                         return true
25408                 }
25409                 // match: (If (LessThanF cc) yes no)
25410                 // result: (FLT cc yes no)
25411                 for b.Controls[0].Op == OpARM64LessThanF {
25412                         v_0 := b.Controls[0]
25413                         cc := v_0.Args[0]
25414                         b.resetWithControl(BlockARM64FLT, cc)
25415                         return true
25416                 }
25417                 // match: (If (LessEqualF cc) yes no)
25418                 // result: (FLE cc yes no)
25419                 for b.Controls[0].Op == OpARM64LessEqualF {
25420                         v_0 := b.Controls[0]
25421                         cc := v_0.Args[0]
25422                         b.resetWithControl(BlockARM64FLE, cc)
25423                         return true
25424                 }
25425                 // match: (If (GreaterThanF cc) yes no)
25426                 // result: (FGT cc yes no)
25427                 for b.Controls[0].Op == OpARM64GreaterThanF {
25428                         v_0 := b.Controls[0]
25429                         cc := v_0.Args[0]
25430                         b.resetWithControl(BlockARM64FGT, cc)
25431                         return true
25432                 }
25433                 // match: (If (GreaterEqualF cc) yes no)
25434                 // result: (FGE cc yes no)
25435                 for b.Controls[0].Op == OpARM64GreaterEqualF {
25436                         v_0 := b.Controls[0]
25437                         cc := v_0.Args[0]
25438                         b.resetWithControl(BlockARM64FGE, cc)
25439                         return true
25440                 }
25441                 // match: (If cond yes no)
25442                 // result: (TBNZ [0] cond yes no)
25443                 for {
25444                         cond := b.Controls[0]
25445                         b.resetWithControl(BlockARM64TBNZ, cond)
25446                         b.AuxInt = int64ToAuxInt(0)
25447                         return true
25448                 }
25449         case BlockJumpTable:
25450                 // match: (JumpTable idx)
25451                 // result: (JUMPTABLE {makeJumpTableSym(b)} idx (MOVDaddr <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
25452                 for {
25453                         idx := b.Controls[0]
25454                         v0 := b.NewValue0(b.Pos, OpARM64MOVDaddr, typ.Uintptr)
25455                         v0.Aux = symToAux(makeJumpTableSym(b))
25456                         v1 := b.NewValue0(b.Pos, OpSB, typ.Uintptr)
25457                         v0.AddArg(v1)
25458                         b.resetWithControl2(BlockARM64JUMPTABLE, idx, v0)
25459                         b.Aux = symToAux(makeJumpTableSym(b))
25460                         return true
25461                 }
25462         case BlockARM64LE:
25463                 // match: (LE (CMPconst [0] z:(AND x y)) yes no)
25464                 // cond: z.Uses == 1
25465                 // result: (LE (TST x y) yes no)
25466                 for b.Controls[0].Op == OpARM64CMPconst {
25467                         v_0 := b.Controls[0]
25468                         if auxIntToInt64(v_0.AuxInt) != 0 {
25469                                 break
25470                         }
25471                         z := v_0.Args[0]
25472                         if z.Op != OpARM64AND {
25473                                 break
25474                         }
25475                         _ = z.Args[1]
25476                         z_0 := z.Args[0]
25477                         z_1 := z.Args[1]
25478                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25479                                 x := z_0
25480                                 y := z_1
25481                                 if !(z.Uses == 1) {
25482                                         continue
25483                                 }
25484                                 v0 := b.NewValue0(v_0.Pos, OpARM64TST, types.TypeFlags)
25485                                 v0.AddArg2(x, y)
25486                                 b.resetWithControl(BlockARM64LE, v0)
25487                                 return true
25488                         }
25489                         break
25490                 }
25491                 // match: (LE (CMPconst [0] x:(ANDconst [c] y)) yes no)
25492                 // cond: x.Uses == 1
25493                 // result: (LE (TSTconst [c] y) yes no)
25494                 for b.Controls[0].Op == OpARM64CMPconst {
25495                         v_0 := b.Controls[0]
25496                         if auxIntToInt64(v_0.AuxInt) != 0 {
25497                                 break
25498                         }
25499                         x := v_0.Args[0]
25500                         if x.Op != OpARM64ANDconst {
25501                                 break
25502                         }
25503                         c := auxIntToInt64(x.AuxInt)
25504                         y := x.Args[0]
25505                         if !(x.Uses == 1) {
25506                                 break
25507                         }
25508                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
25509                         v0.AuxInt = int64ToAuxInt(c)
25510                         v0.AddArg(y)
25511                         b.resetWithControl(BlockARM64LE, v0)
25512                         return true
25513                 }
25514                 // match: (LE (CMPWconst [0] z:(AND x y)) yes no)
25515                 // cond: z.Uses == 1
25516                 // result: (LE (TSTW x y) yes no)
25517                 for b.Controls[0].Op == OpARM64CMPWconst {
25518                         v_0 := b.Controls[0]
25519                         if auxIntToInt32(v_0.AuxInt) != 0 {
25520                                 break
25521                         }
25522                         z := v_0.Args[0]
25523                         if z.Op != OpARM64AND {
25524                                 break
25525                         }
25526                         _ = z.Args[1]
25527                         z_0 := z.Args[0]
25528                         z_1 := z.Args[1]
25529                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25530                                 x := z_0
25531                                 y := z_1
25532                                 if !(z.Uses == 1) {
25533                                         continue
25534                                 }
25535                                 v0 := b.NewValue0(v_0.Pos, OpARM64TSTW, types.TypeFlags)
25536                                 v0.AddArg2(x, y)
25537                                 b.resetWithControl(BlockARM64LE, v0)
25538                                 return true
25539                         }
25540                         break
25541                 }
25542                 // match: (LE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
25543                 // cond: x.Uses == 1
25544                 // result: (LE (TSTWconst [int32(c)] y) yes no)
25545                 for b.Controls[0].Op == OpARM64CMPWconst {
25546                         v_0 := b.Controls[0]
25547                         if auxIntToInt32(v_0.AuxInt) != 0 {
25548                                 break
25549                         }
25550                         x := v_0.Args[0]
25551                         if x.Op != OpARM64ANDconst {
25552                                 break
25553                         }
25554                         c := auxIntToInt64(x.AuxInt)
25555                         y := x.Args[0]
25556                         if !(x.Uses == 1) {
25557                                 break
25558                         }
25559                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
25560                         v0.AuxInt = int32ToAuxInt(int32(c))
25561                         v0.AddArg(y)
25562                         b.resetWithControl(BlockARM64LE, v0)
25563                         return true
25564                 }
25565                 // match: (LE (CMPconst [0] x:(ADDconst [c] y)) yes no)
25566                 // cond: x.Uses == 1
25567                 // result: (LEnoov (CMNconst [c] y) yes no)
25568                 for b.Controls[0].Op == OpARM64CMPconst {
25569                         v_0 := b.Controls[0]
25570                         if auxIntToInt64(v_0.AuxInt) != 0 {
25571                                 break
25572                         }
25573                         x := v_0.Args[0]
25574                         if x.Op != OpARM64ADDconst {
25575                                 break
25576                         }
25577                         c := auxIntToInt64(x.AuxInt)
25578                         y := x.Args[0]
25579                         if !(x.Uses == 1) {
25580                                 break
25581                         }
25582                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNconst, types.TypeFlags)
25583                         v0.AuxInt = int64ToAuxInt(c)
25584                         v0.AddArg(y)
25585                         b.resetWithControl(BlockARM64LEnoov, v0)
25586                         return true
25587                 }
25588                 // match: (LE (CMPWconst [0] x:(ADDconst [c] y)) yes no)
25589                 // cond: x.Uses == 1
25590                 // result: (LEnoov (CMNWconst [int32(c)] y) yes no)
25591                 for b.Controls[0].Op == OpARM64CMPWconst {
25592                         v_0 := b.Controls[0]
25593                         if auxIntToInt32(v_0.AuxInt) != 0 {
25594                                 break
25595                         }
25596                         x := v_0.Args[0]
25597                         if x.Op != OpARM64ADDconst {
25598                                 break
25599                         }
25600                         c := auxIntToInt64(x.AuxInt)
25601                         y := x.Args[0]
25602                         if !(x.Uses == 1) {
25603                                 break
25604                         }
25605                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNWconst, types.TypeFlags)
25606                         v0.AuxInt = int32ToAuxInt(int32(c))
25607                         v0.AddArg(y)
25608                         b.resetWithControl(BlockARM64LEnoov, v0)
25609                         return true
25610                 }
25611                 // match: (LE (CMPconst [0] z:(ADD x y)) yes no)
25612                 // cond: z.Uses == 1
25613                 // result: (LEnoov (CMN x y) yes no)
25614                 for b.Controls[0].Op == OpARM64CMPconst {
25615                         v_0 := b.Controls[0]
25616                         if auxIntToInt64(v_0.AuxInt) != 0 {
25617                                 break
25618                         }
25619                         z := v_0.Args[0]
25620                         if z.Op != OpARM64ADD {
25621                                 break
25622                         }
25623                         _ = z.Args[1]
25624                         z_0 := z.Args[0]
25625                         z_1 := z.Args[1]
25626                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25627                                 x := z_0
25628                                 y := z_1
25629                                 if !(z.Uses == 1) {
25630                                         continue
25631                                 }
25632                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
25633                                 v0.AddArg2(x, y)
25634                                 b.resetWithControl(BlockARM64LEnoov, v0)
25635                                 return true
25636                         }
25637                         break
25638                 }
25639                 // match: (LE (CMPWconst [0] z:(ADD x y)) yes no)
25640                 // cond: z.Uses == 1
25641                 // result: (LEnoov (CMNW x y) yes no)
25642                 for b.Controls[0].Op == OpARM64CMPWconst {
25643                         v_0 := b.Controls[0]
25644                         if auxIntToInt32(v_0.AuxInt) != 0 {
25645                                 break
25646                         }
25647                         z := v_0.Args[0]
25648                         if z.Op != OpARM64ADD {
25649                                 break
25650                         }
25651                         _ = z.Args[1]
25652                         z_0 := z.Args[0]
25653                         z_1 := z.Args[1]
25654                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25655                                 x := z_0
25656                                 y := z_1
25657                                 if !(z.Uses == 1) {
25658                                         continue
25659                                 }
25660                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
25661                                 v0.AddArg2(x, y)
25662                                 b.resetWithControl(BlockARM64LEnoov, v0)
25663                                 return true
25664                         }
25665                         break
25666                 }
25667                 // match: (LE (CMPconst [0] z:(MADD a x y)) yes no)
25668                 // cond: z.Uses==1
25669                 // result: (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
25670                 for b.Controls[0].Op == OpARM64CMPconst {
25671                         v_0 := b.Controls[0]
25672                         if auxIntToInt64(v_0.AuxInt) != 0 {
25673                                 break
25674                         }
25675                         z := v_0.Args[0]
25676                         if z.Op != OpARM64MADD {
25677                                 break
25678                         }
25679                         y := z.Args[2]
25680                         a := z.Args[0]
25681                         x := z.Args[1]
25682                         if !(z.Uses == 1) {
25683                                 break
25684                         }
25685                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
25686                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
25687                         v1.AddArg2(x, y)
25688                         v0.AddArg2(a, v1)
25689                         b.resetWithControl(BlockARM64LEnoov, v0)
25690                         return true
25691                 }
25692                 // match: (LE (CMPconst [0] z:(MSUB a x y)) yes no)
25693                 // cond: z.Uses==1
25694                 // result: (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
25695                 for b.Controls[0].Op == OpARM64CMPconst {
25696                         v_0 := b.Controls[0]
25697                         if auxIntToInt64(v_0.AuxInt) != 0 {
25698                                 break
25699                         }
25700                         z := v_0.Args[0]
25701                         if z.Op != OpARM64MSUB {
25702                                 break
25703                         }
25704                         y := z.Args[2]
25705                         a := z.Args[0]
25706                         x := z.Args[1]
25707                         if !(z.Uses == 1) {
25708                                 break
25709                         }
25710                         v0 := b.NewValue0(v_0.Pos, OpARM64CMP, types.TypeFlags)
25711                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
25712                         v1.AddArg2(x, y)
25713                         v0.AddArg2(a, v1)
25714                         b.resetWithControl(BlockARM64LEnoov, v0)
25715                         return true
25716                 }
25717                 // match: (LE (CMPWconst [0] z:(MADDW a x y)) yes no)
25718                 // cond: z.Uses==1
25719                 // result: (LEnoov (CMNW a (MULW <x.Type> x y)) yes no)
25720                 for b.Controls[0].Op == OpARM64CMPWconst {
25721                         v_0 := b.Controls[0]
25722                         if auxIntToInt32(v_0.AuxInt) != 0 {
25723                                 break
25724                         }
25725                         z := v_0.Args[0]
25726                         if z.Op != OpARM64MADDW {
25727                                 break
25728                         }
25729                         y := z.Args[2]
25730                         a := z.Args[0]
25731                         x := z.Args[1]
25732                         if !(z.Uses == 1) {
25733                                 break
25734                         }
25735                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
25736                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
25737                         v1.AddArg2(x, y)
25738                         v0.AddArg2(a, v1)
25739                         b.resetWithControl(BlockARM64LEnoov, v0)
25740                         return true
25741                 }
25742                 // match: (LE (CMPWconst [0] z:(MSUBW a x y)) yes no)
25743                 // cond: z.Uses==1
25744                 // result: (LEnoov (CMPW a (MULW <x.Type> x y)) yes no)
25745                 for b.Controls[0].Op == OpARM64CMPWconst {
25746                         v_0 := b.Controls[0]
25747                         if auxIntToInt32(v_0.AuxInt) != 0 {
25748                                 break
25749                         }
25750                         z := v_0.Args[0]
25751                         if z.Op != OpARM64MSUBW {
25752                                 break
25753                         }
25754                         y := z.Args[2]
25755                         a := z.Args[0]
25756                         x := z.Args[1]
25757                         if !(z.Uses == 1) {
25758                                 break
25759                         }
25760                         v0 := b.NewValue0(v_0.Pos, OpARM64CMPW, types.TypeFlags)
25761                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
25762                         v1.AddArg2(x, y)
25763                         v0.AddArg2(a, v1)
25764                         b.resetWithControl(BlockARM64LEnoov, v0)
25765                         return true
25766                 }
25767                 // match: (LE (FlagConstant [fc]) yes no)
25768                 // cond: fc.le()
25769                 // result: (First yes no)
25770                 for b.Controls[0].Op == OpARM64FlagConstant {
25771                         v_0 := b.Controls[0]
25772                         fc := auxIntToFlagConstant(v_0.AuxInt)
25773                         if !(fc.le()) {
25774                                 break
25775                         }
25776                         b.Reset(BlockFirst)
25777                         return true
25778                 }
25779                 // match: (LE (FlagConstant [fc]) yes no)
25780                 // cond: !fc.le()
25781                 // result: (First no yes)
25782                 for b.Controls[0].Op == OpARM64FlagConstant {
25783                         v_0 := b.Controls[0]
25784                         fc := auxIntToFlagConstant(v_0.AuxInt)
25785                         if !(!fc.le()) {
25786                                 break
25787                         }
25788                         b.Reset(BlockFirst)
25789                         b.swapSuccessors()
25790                         return true
25791                 }
25792                 // match: (LE (InvertFlags cmp) yes no)
25793                 // result: (GE cmp yes no)
25794                 for b.Controls[0].Op == OpARM64InvertFlags {
25795                         v_0 := b.Controls[0]
25796                         cmp := v_0.Args[0]
25797                         b.resetWithControl(BlockARM64GE, cmp)
25798                         return true
25799                 }
25800         case BlockARM64LEnoov:
25801                 // match: (LEnoov (FlagConstant [fc]) yes no)
25802                 // cond: fc.leNoov()
25803                 // result: (First yes no)
25804                 for b.Controls[0].Op == OpARM64FlagConstant {
25805                         v_0 := b.Controls[0]
25806                         fc := auxIntToFlagConstant(v_0.AuxInt)
25807                         if !(fc.leNoov()) {
25808                                 break
25809                         }
25810                         b.Reset(BlockFirst)
25811                         return true
25812                 }
25813                 // match: (LEnoov (FlagConstant [fc]) yes no)
25814                 // cond: !fc.leNoov()
25815                 // result: (First no yes)
25816                 for b.Controls[0].Op == OpARM64FlagConstant {
25817                         v_0 := b.Controls[0]
25818                         fc := auxIntToFlagConstant(v_0.AuxInt)
25819                         if !(!fc.leNoov()) {
25820                                 break
25821                         }
25822                         b.Reset(BlockFirst)
25823                         b.swapSuccessors()
25824                         return true
25825                 }
25826                 // match: (LEnoov (InvertFlags cmp) yes no)
25827                 // result: (GEnoov cmp yes no)
25828                 for b.Controls[0].Op == OpARM64InvertFlags {
25829                         v_0 := b.Controls[0]
25830                         cmp := v_0.Args[0]
25831                         b.resetWithControl(BlockARM64GEnoov, cmp)
25832                         return true
25833                 }
25834         case BlockARM64LT:
25835                 // match: (LT (CMPconst [0] z:(AND x y)) yes no)
25836                 // cond: z.Uses == 1
25837                 // result: (LT (TST x y) yes no)
25838                 for b.Controls[0].Op == OpARM64CMPconst {
25839                         v_0 := b.Controls[0]
25840                         if auxIntToInt64(v_0.AuxInt) != 0 {
25841                                 break
25842                         }
25843                         z := v_0.Args[0]
25844                         if z.Op != OpARM64AND {
25845                                 break
25846                         }
25847                         _ = z.Args[1]
25848                         z_0 := z.Args[0]
25849                         z_1 := z.Args[1]
25850                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25851                                 x := z_0
25852                                 y := z_1
25853                                 if !(z.Uses == 1) {
25854                                         continue
25855                                 }
25856                                 v0 := b.NewValue0(v_0.Pos, OpARM64TST, types.TypeFlags)
25857                                 v0.AddArg2(x, y)
25858                                 b.resetWithControl(BlockARM64LT, v0)
25859                                 return true
25860                         }
25861                         break
25862                 }
25863                 // match: (LT (CMPconst [0] x:(ANDconst [c] y)) yes no)
25864                 // cond: x.Uses == 1
25865                 // result: (LT (TSTconst [c] y) yes no)
25866                 for b.Controls[0].Op == OpARM64CMPconst {
25867                         v_0 := b.Controls[0]
25868                         if auxIntToInt64(v_0.AuxInt) != 0 {
25869                                 break
25870                         }
25871                         x := v_0.Args[0]
25872                         if x.Op != OpARM64ANDconst {
25873                                 break
25874                         }
25875                         c := auxIntToInt64(x.AuxInt)
25876                         y := x.Args[0]
25877                         if !(x.Uses == 1) {
25878                                 break
25879                         }
25880                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
25881                         v0.AuxInt = int64ToAuxInt(c)
25882                         v0.AddArg(y)
25883                         b.resetWithControl(BlockARM64LT, v0)
25884                         return true
25885                 }
25886                 // match: (LT (CMPWconst [0] z:(AND x y)) yes no)
25887                 // cond: z.Uses == 1
25888                 // result: (LT (TSTW x y) yes no)
25889                 for b.Controls[0].Op == OpARM64CMPWconst {
25890                         v_0 := b.Controls[0]
25891                         if auxIntToInt32(v_0.AuxInt) != 0 {
25892                                 break
25893                         }
25894                         z := v_0.Args[0]
25895                         if z.Op != OpARM64AND {
25896                                 break
25897                         }
25898                         _ = z.Args[1]
25899                         z_0 := z.Args[0]
25900                         z_1 := z.Args[1]
25901                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25902                                 x := z_0
25903                                 y := z_1
25904                                 if !(z.Uses == 1) {
25905                                         continue
25906                                 }
25907                                 v0 := b.NewValue0(v_0.Pos, OpARM64TSTW, types.TypeFlags)
25908                                 v0.AddArg2(x, y)
25909                                 b.resetWithControl(BlockARM64LT, v0)
25910                                 return true
25911                         }
25912                         break
25913                 }
25914                 // match: (LT (CMPWconst [0] x:(ANDconst [c] y)) yes no)
25915                 // cond: x.Uses == 1
25916                 // result: (LT (TSTWconst [int32(c)] y) yes no)
25917                 for b.Controls[0].Op == OpARM64CMPWconst {
25918                         v_0 := b.Controls[0]
25919                         if auxIntToInt32(v_0.AuxInt) != 0 {
25920                                 break
25921                         }
25922                         x := v_0.Args[0]
25923                         if x.Op != OpARM64ANDconst {
25924                                 break
25925                         }
25926                         c := auxIntToInt64(x.AuxInt)
25927                         y := x.Args[0]
25928                         if !(x.Uses == 1) {
25929                                 break
25930                         }
25931                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
25932                         v0.AuxInt = int32ToAuxInt(int32(c))
25933                         v0.AddArg(y)
25934                         b.resetWithControl(BlockARM64LT, v0)
25935                         return true
25936                 }
25937                 // match: (LT (CMPconst [0] x:(ADDconst [c] y)) yes no)
25938                 // cond: x.Uses == 1
25939                 // result: (LTnoov (CMNconst [c] y) yes no)
25940                 for b.Controls[0].Op == OpARM64CMPconst {
25941                         v_0 := b.Controls[0]
25942                         if auxIntToInt64(v_0.AuxInt) != 0 {
25943                                 break
25944                         }
25945                         x := v_0.Args[0]
25946                         if x.Op != OpARM64ADDconst {
25947                                 break
25948                         }
25949                         c := auxIntToInt64(x.AuxInt)
25950                         y := x.Args[0]
25951                         if !(x.Uses == 1) {
25952                                 break
25953                         }
25954                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNconst, types.TypeFlags)
25955                         v0.AuxInt = int64ToAuxInt(c)
25956                         v0.AddArg(y)
25957                         b.resetWithControl(BlockARM64LTnoov, v0)
25958                         return true
25959                 }
25960                 // match: (LT (CMPWconst [0] x:(ADDconst [c] y)) yes no)
25961                 // cond: x.Uses == 1
25962                 // result: (LTnoov (CMNWconst [int32(c)] y) yes no)
25963                 for b.Controls[0].Op == OpARM64CMPWconst {
25964                         v_0 := b.Controls[0]
25965                         if auxIntToInt32(v_0.AuxInt) != 0 {
25966                                 break
25967                         }
25968                         x := v_0.Args[0]
25969                         if x.Op != OpARM64ADDconst {
25970                                 break
25971                         }
25972                         c := auxIntToInt64(x.AuxInt)
25973                         y := x.Args[0]
25974                         if !(x.Uses == 1) {
25975                                 break
25976                         }
25977                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNWconst, types.TypeFlags)
25978                         v0.AuxInt = int32ToAuxInt(int32(c))
25979                         v0.AddArg(y)
25980                         b.resetWithControl(BlockARM64LTnoov, v0)
25981                         return true
25982                 }
25983                 // match: (LT (CMPconst [0] z:(ADD x y)) yes no)
25984                 // cond: z.Uses == 1
25985                 // result: (LTnoov (CMN x y) yes no)
25986                 for b.Controls[0].Op == OpARM64CMPconst {
25987                         v_0 := b.Controls[0]
25988                         if auxIntToInt64(v_0.AuxInt) != 0 {
25989                                 break
25990                         }
25991                         z := v_0.Args[0]
25992                         if z.Op != OpARM64ADD {
25993                                 break
25994                         }
25995                         _ = z.Args[1]
25996                         z_0 := z.Args[0]
25997                         z_1 := z.Args[1]
25998                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
25999                                 x := z_0
26000                                 y := z_1
26001                                 if !(z.Uses == 1) {
26002                                         continue
26003                                 }
26004                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
26005                                 v0.AddArg2(x, y)
26006                                 b.resetWithControl(BlockARM64LTnoov, v0)
26007                                 return true
26008                         }
26009                         break
26010                 }
26011                 // match: (LT (CMPWconst [0] z:(ADD x y)) yes no)
26012                 // cond: z.Uses == 1
26013                 // result: (LTnoov (CMNW x y) yes no)
26014                 for b.Controls[0].Op == OpARM64CMPWconst {
26015                         v_0 := b.Controls[0]
26016                         if auxIntToInt32(v_0.AuxInt) != 0 {
26017                                 break
26018                         }
26019                         z := v_0.Args[0]
26020                         if z.Op != OpARM64ADD {
26021                                 break
26022                         }
26023                         _ = z.Args[1]
26024                         z_0 := z.Args[0]
26025                         z_1 := z.Args[1]
26026                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
26027                                 x := z_0
26028                                 y := z_1
26029                                 if !(z.Uses == 1) {
26030                                         continue
26031                                 }
26032                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
26033                                 v0.AddArg2(x, y)
26034                                 b.resetWithControl(BlockARM64LTnoov, v0)
26035                                 return true
26036                         }
26037                         break
26038                 }
26039                 // match: (LT (CMPconst [0] z:(MADD a x y)) yes no)
26040                 // cond: z.Uses==1
26041                 // result: (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
26042                 for b.Controls[0].Op == OpARM64CMPconst {
26043                         v_0 := b.Controls[0]
26044                         if auxIntToInt64(v_0.AuxInt) != 0 {
26045                                 break
26046                         }
26047                         z := v_0.Args[0]
26048                         if z.Op != OpARM64MADD {
26049                                 break
26050                         }
26051                         y := z.Args[2]
26052                         a := z.Args[0]
26053                         x := z.Args[1]
26054                         if !(z.Uses == 1) {
26055                                 break
26056                         }
26057                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
26058                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
26059                         v1.AddArg2(x, y)
26060                         v0.AddArg2(a, v1)
26061                         b.resetWithControl(BlockARM64LTnoov, v0)
26062                         return true
26063                 }
26064                 // match: (LT (CMPconst [0] z:(MSUB a x y)) yes no)
26065                 // cond: z.Uses==1
26066                 // result: (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
26067                 for b.Controls[0].Op == OpARM64CMPconst {
26068                         v_0 := b.Controls[0]
26069                         if auxIntToInt64(v_0.AuxInt) != 0 {
26070                                 break
26071                         }
26072                         z := v_0.Args[0]
26073                         if z.Op != OpARM64MSUB {
26074                                 break
26075                         }
26076                         y := z.Args[2]
26077                         a := z.Args[0]
26078                         x := z.Args[1]
26079                         if !(z.Uses == 1) {
26080                                 break
26081                         }
26082                         v0 := b.NewValue0(v_0.Pos, OpARM64CMP, types.TypeFlags)
26083                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
26084                         v1.AddArg2(x, y)
26085                         v0.AddArg2(a, v1)
26086                         b.resetWithControl(BlockARM64LTnoov, v0)
26087                         return true
26088                 }
26089                 // match: (LT (CMPWconst [0] z:(MADDW a x y)) yes no)
26090                 // cond: z.Uses==1
26091                 // result: (LTnoov (CMNW a (MULW <x.Type> x y)) yes no)
26092                 for b.Controls[0].Op == OpARM64CMPWconst {
26093                         v_0 := b.Controls[0]
26094                         if auxIntToInt32(v_0.AuxInt) != 0 {
26095                                 break
26096                         }
26097                         z := v_0.Args[0]
26098                         if z.Op != OpARM64MADDW {
26099                                 break
26100                         }
26101                         y := z.Args[2]
26102                         a := z.Args[0]
26103                         x := z.Args[1]
26104                         if !(z.Uses == 1) {
26105                                 break
26106                         }
26107                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
26108                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
26109                         v1.AddArg2(x, y)
26110                         v0.AddArg2(a, v1)
26111                         b.resetWithControl(BlockARM64LTnoov, v0)
26112                         return true
26113                 }
26114                 // match: (LT (CMPWconst [0] z:(MSUBW a x y)) yes no)
26115                 // cond: z.Uses==1
26116                 // result: (LTnoov (CMPW a (MULW <x.Type> x y)) yes no)
26117                 for b.Controls[0].Op == OpARM64CMPWconst {
26118                         v_0 := b.Controls[0]
26119                         if auxIntToInt32(v_0.AuxInt) != 0 {
26120                                 break
26121                         }
26122                         z := v_0.Args[0]
26123                         if z.Op != OpARM64MSUBW {
26124                                 break
26125                         }
26126                         y := z.Args[2]
26127                         a := z.Args[0]
26128                         x := z.Args[1]
26129                         if !(z.Uses == 1) {
26130                                 break
26131                         }
26132                         v0 := b.NewValue0(v_0.Pos, OpARM64CMPW, types.TypeFlags)
26133                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
26134                         v1.AddArg2(x, y)
26135                         v0.AddArg2(a, v1)
26136                         b.resetWithControl(BlockARM64LTnoov, v0)
26137                         return true
26138                 }
26139                 // match: (LT (CMPWconst [0] x) yes no)
26140                 // result: (TBNZ [31] x yes no)
26141                 for b.Controls[0].Op == OpARM64CMPWconst {
26142                         v_0 := b.Controls[0]
26143                         if auxIntToInt32(v_0.AuxInt) != 0 {
26144                                 break
26145                         }
26146                         x := v_0.Args[0]
26147                         b.resetWithControl(BlockARM64TBNZ, x)
26148                         b.AuxInt = int64ToAuxInt(31)
26149                         return true
26150                 }
26151                 // match: (LT (CMPconst [0] x) yes no)
26152                 // result: (TBNZ [63] x yes no)
26153                 for b.Controls[0].Op == OpARM64CMPconst {
26154                         v_0 := b.Controls[0]
26155                         if auxIntToInt64(v_0.AuxInt) != 0 {
26156                                 break
26157                         }
26158                         x := v_0.Args[0]
26159                         b.resetWithControl(BlockARM64TBNZ, x)
26160                         b.AuxInt = int64ToAuxInt(63)
26161                         return true
26162                 }
26163                 // match: (LT (FlagConstant [fc]) yes no)
26164                 // cond: fc.lt()
26165                 // result: (First yes no)
26166                 for b.Controls[0].Op == OpARM64FlagConstant {
26167                         v_0 := b.Controls[0]
26168                         fc := auxIntToFlagConstant(v_0.AuxInt)
26169                         if !(fc.lt()) {
26170                                 break
26171                         }
26172                         b.Reset(BlockFirst)
26173                         return true
26174                 }
26175                 // match: (LT (FlagConstant [fc]) yes no)
26176                 // cond: !fc.lt()
26177                 // result: (First no yes)
26178                 for b.Controls[0].Op == OpARM64FlagConstant {
26179                         v_0 := b.Controls[0]
26180                         fc := auxIntToFlagConstant(v_0.AuxInt)
26181                         if !(!fc.lt()) {
26182                                 break
26183                         }
26184                         b.Reset(BlockFirst)
26185                         b.swapSuccessors()
26186                         return true
26187                 }
26188                 // match: (LT (InvertFlags cmp) yes no)
26189                 // result: (GT cmp yes no)
26190                 for b.Controls[0].Op == OpARM64InvertFlags {
26191                         v_0 := b.Controls[0]
26192                         cmp := v_0.Args[0]
26193                         b.resetWithControl(BlockARM64GT, cmp)
26194                         return true
26195                 }
26196         case BlockARM64LTnoov:
26197                 // match: (LTnoov (FlagConstant [fc]) yes no)
26198                 // cond: fc.ltNoov()
26199                 // result: (First yes no)
26200                 for b.Controls[0].Op == OpARM64FlagConstant {
26201                         v_0 := b.Controls[0]
26202                         fc := auxIntToFlagConstant(v_0.AuxInt)
26203                         if !(fc.ltNoov()) {
26204                                 break
26205                         }
26206                         b.Reset(BlockFirst)
26207                         return true
26208                 }
26209                 // match: (LTnoov (FlagConstant [fc]) yes no)
26210                 // cond: !fc.ltNoov()
26211                 // result: (First no yes)
26212                 for b.Controls[0].Op == OpARM64FlagConstant {
26213                         v_0 := b.Controls[0]
26214                         fc := auxIntToFlagConstant(v_0.AuxInt)
26215                         if !(!fc.ltNoov()) {
26216                                 break
26217                         }
26218                         b.Reset(BlockFirst)
26219                         b.swapSuccessors()
26220                         return true
26221                 }
26222                 // match: (LTnoov (InvertFlags cmp) yes no)
26223                 // result: (GTnoov cmp yes no)
26224                 for b.Controls[0].Op == OpARM64InvertFlags {
26225                         v_0 := b.Controls[0]
26226                         cmp := v_0.Args[0]
26227                         b.resetWithControl(BlockARM64GTnoov, cmp)
26228                         return true
26229                 }
26230         case BlockARM64NE:
26231                 // match: (NE (CMPconst [0] z:(AND x y)) yes no)
26232                 // cond: z.Uses == 1
26233                 // result: (NE (TST x y) yes no)
26234                 for b.Controls[0].Op == OpARM64CMPconst {
26235                         v_0 := b.Controls[0]
26236                         if auxIntToInt64(v_0.AuxInt) != 0 {
26237                                 break
26238                         }
26239                         z := v_0.Args[0]
26240                         if z.Op != OpARM64AND {
26241                                 break
26242                         }
26243                         _ = z.Args[1]
26244                         z_0 := z.Args[0]
26245                         z_1 := z.Args[1]
26246                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
26247                                 x := z_0
26248                                 y := z_1
26249                                 if !(z.Uses == 1) {
26250                                         continue
26251                                 }
26252                                 v0 := b.NewValue0(v_0.Pos, OpARM64TST, types.TypeFlags)
26253                                 v0.AddArg2(x, y)
26254                                 b.resetWithControl(BlockARM64NE, v0)
26255                                 return true
26256                         }
26257                         break
26258                 }
26259                 // match: (NE (CMPconst [0] x:(ANDconst [c] y)) yes no)
26260                 // cond: x.Uses == 1
26261                 // result: (NE (TSTconst [c] y) yes no)
26262                 for b.Controls[0].Op == OpARM64CMPconst {
26263                         v_0 := b.Controls[0]
26264                         if auxIntToInt64(v_0.AuxInt) != 0 {
26265                                 break
26266                         }
26267                         x := v_0.Args[0]
26268                         if x.Op != OpARM64ANDconst {
26269                                 break
26270                         }
26271                         c := auxIntToInt64(x.AuxInt)
26272                         y := x.Args[0]
26273                         if !(x.Uses == 1) {
26274                                 break
26275                         }
26276                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
26277                         v0.AuxInt = int64ToAuxInt(c)
26278                         v0.AddArg(y)
26279                         b.resetWithControl(BlockARM64NE, v0)
26280                         return true
26281                 }
26282                 // match: (NE (CMPWconst [0] z:(AND x y)) yes no)
26283                 // cond: z.Uses == 1
26284                 // result: (NE (TSTW x y) yes no)
26285                 for b.Controls[0].Op == OpARM64CMPWconst {
26286                         v_0 := b.Controls[0]
26287                         if auxIntToInt32(v_0.AuxInt) != 0 {
26288                                 break
26289                         }
26290                         z := v_0.Args[0]
26291                         if z.Op != OpARM64AND {
26292                                 break
26293                         }
26294                         _ = z.Args[1]
26295                         z_0 := z.Args[0]
26296                         z_1 := z.Args[1]
26297                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
26298                                 x := z_0
26299                                 y := z_1
26300                                 if !(z.Uses == 1) {
26301                                         continue
26302                                 }
26303                                 v0 := b.NewValue0(v_0.Pos, OpARM64TSTW, types.TypeFlags)
26304                                 v0.AddArg2(x, y)
26305                                 b.resetWithControl(BlockARM64NE, v0)
26306                                 return true
26307                         }
26308                         break
26309                 }
26310                 // match: (NE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
26311                 // cond: x.Uses == 1
26312                 // result: (NE (TSTWconst [int32(c)] y) yes no)
26313                 for b.Controls[0].Op == OpARM64CMPWconst {
26314                         v_0 := b.Controls[0]
26315                         if auxIntToInt32(v_0.AuxInt) != 0 {
26316                                 break
26317                         }
26318                         x := v_0.Args[0]
26319                         if x.Op != OpARM64ANDconst {
26320                                 break
26321                         }
26322                         c := auxIntToInt64(x.AuxInt)
26323                         y := x.Args[0]
26324                         if !(x.Uses == 1) {
26325                                 break
26326                         }
26327                         v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
26328                         v0.AuxInt = int32ToAuxInt(int32(c))
26329                         v0.AddArg(y)
26330                         b.resetWithControl(BlockARM64NE, v0)
26331                         return true
26332                 }
26333                 // match: (NE (CMPconst [0] x:(ADDconst [c] y)) yes no)
26334                 // cond: x.Uses == 1
26335                 // result: (NE (CMNconst [c] y) yes no)
26336                 for b.Controls[0].Op == OpARM64CMPconst {
26337                         v_0 := b.Controls[0]
26338                         if auxIntToInt64(v_0.AuxInt) != 0 {
26339                                 break
26340                         }
26341                         x := v_0.Args[0]
26342                         if x.Op != OpARM64ADDconst {
26343                                 break
26344                         }
26345                         c := auxIntToInt64(x.AuxInt)
26346                         y := x.Args[0]
26347                         if !(x.Uses == 1) {
26348                                 break
26349                         }
26350                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNconst, types.TypeFlags)
26351                         v0.AuxInt = int64ToAuxInt(c)
26352                         v0.AddArg(y)
26353                         b.resetWithControl(BlockARM64NE, v0)
26354                         return true
26355                 }
26356                 // match: (NE (CMPWconst [0] x:(ADDconst [c] y)) yes no)
26357                 // cond: x.Uses == 1
26358                 // result: (NE (CMNWconst [int32(c)] y) yes no)
26359                 for b.Controls[0].Op == OpARM64CMPWconst {
26360                         v_0 := b.Controls[0]
26361                         if auxIntToInt32(v_0.AuxInt) != 0 {
26362                                 break
26363                         }
26364                         x := v_0.Args[0]
26365                         if x.Op != OpARM64ADDconst {
26366                                 break
26367                         }
26368                         c := auxIntToInt64(x.AuxInt)
26369                         y := x.Args[0]
26370                         if !(x.Uses == 1) {
26371                                 break
26372                         }
26373                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNWconst, types.TypeFlags)
26374                         v0.AuxInt = int32ToAuxInt(int32(c))
26375                         v0.AddArg(y)
26376                         b.resetWithControl(BlockARM64NE, v0)
26377                         return true
26378                 }
26379                 // match: (NE (CMPconst [0] z:(ADD x y)) yes no)
26380                 // cond: z.Uses == 1
26381                 // result: (NE (CMN x y) yes no)
26382                 for b.Controls[0].Op == OpARM64CMPconst {
26383                         v_0 := b.Controls[0]
26384                         if auxIntToInt64(v_0.AuxInt) != 0 {
26385                                 break
26386                         }
26387                         z := v_0.Args[0]
26388                         if z.Op != OpARM64ADD {
26389                                 break
26390                         }
26391                         _ = z.Args[1]
26392                         z_0 := z.Args[0]
26393                         z_1 := z.Args[1]
26394                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
26395                                 x := z_0
26396                                 y := z_1
26397                                 if !(z.Uses == 1) {
26398                                         continue
26399                                 }
26400                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
26401                                 v0.AddArg2(x, y)
26402                                 b.resetWithControl(BlockARM64NE, v0)
26403                                 return true
26404                         }
26405                         break
26406                 }
26407                 // match: (NE (CMPWconst [0] z:(ADD x y)) yes no)
26408                 // cond: z.Uses == 1
26409                 // result: (NE (CMNW x y) yes no)
26410                 for b.Controls[0].Op == OpARM64CMPWconst {
26411                         v_0 := b.Controls[0]
26412                         if auxIntToInt32(v_0.AuxInt) != 0 {
26413                                 break
26414                         }
26415                         z := v_0.Args[0]
26416                         if z.Op != OpARM64ADD {
26417                                 break
26418                         }
26419                         _ = z.Args[1]
26420                         z_0 := z.Args[0]
26421                         z_1 := z.Args[1]
26422                         for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 {
26423                                 x := z_0
26424                                 y := z_1
26425                                 if !(z.Uses == 1) {
26426                                         continue
26427                                 }
26428                                 v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
26429                                 v0.AddArg2(x, y)
26430                                 b.resetWithControl(BlockARM64NE, v0)
26431                                 return true
26432                         }
26433                         break
26434                 }
26435                 // match: (NE (CMP x z:(NEG y)) yes no)
26436                 // cond: z.Uses == 1
26437                 // result: (NE (CMN x y) yes no)
26438                 for b.Controls[0].Op == OpARM64CMP {
26439                         v_0 := b.Controls[0]
26440                         _ = v_0.Args[1]
26441                         x := v_0.Args[0]
26442                         z := v_0.Args[1]
26443                         if z.Op != OpARM64NEG {
26444                                 break
26445                         }
26446                         y := z.Args[0]
26447                         if !(z.Uses == 1) {
26448                                 break
26449                         }
26450                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
26451                         v0.AddArg2(x, y)
26452                         b.resetWithControl(BlockARM64NE, v0)
26453                         return true
26454                 }
26455                 // match: (NE (CMPW x z:(NEG y)) yes no)
26456                 // cond: z.Uses == 1
26457                 // result: (NE (CMNW x y) yes no)
26458                 for b.Controls[0].Op == OpARM64CMPW {
26459                         v_0 := b.Controls[0]
26460                         _ = v_0.Args[1]
26461                         x := v_0.Args[0]
26462                         z := v_0.Args[1]
26463                         if z.Op != OpARM64NEG {
26464                                 break
26465                         }
26466                         y := z.Args[0]
26467                         if !(z.Uses == 1) {
26468                                 break
26469                         }
26470                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
26471                         v0.AddArg2(x, y)
26472                         b.resetWithControl(BlockARM64NE, v0)
26473                         return true
26474                 }
26475                 // match: (NE (CMPconst [0] x) yes no)
26476                 // result: (NZ x yes no)
26477                 for b.Controls[0].Op == OpARM64CMPconst {
26478                         v_0 := b.Controls[0]
26479                         if auxIntToInt64(v_0.AuxInt) != 0 {
26480                                 break
26481                         }
26482                         x := v_0.Args[0]
26483                         b.resetWithControl(BlockARM64NZ, x)
26484                         return true
26485                 }
26486                 // match: (NE (CMPWconst [0] x) yes no)
26487                 // result: (NZW x yes no)
26488                 for b.Controls[0].Op == OpARM64CMPWconst {
26489                         v_0 := b.Controls[0]
26490                         if auxIntToInt32(v_0.AuxInt) != 0 {
26491                                 break
26492                         }
26493                         x := v_0.Args[0]
26494                         b.resetWithControl(BlockARM64NZW, x)
26495                         return true
26496                 }
26497                 // match: (NE (CMPconst [0] z:(MADD a x y)) yes no)
26498                 // cond: z.Uses==1
26499                 // result: (NE (CMN a (MUL <x.Type> x y)) yes no)
26500                 for b.Controls[0].Op == OpARM64CMPconst {
26501                         v_0 := b.Controls[0]
26502                         if auxIntToInt64(v_0.AuxInt) != 0 {
26503                                 break
26504                         }
26505                         z := v_0.Args[0]
26506                         if z.Op != OpARM64MADD {
26507                                 break
26508                         }
26509                         y := z.Args[2]
26510                         a := z.Args[0]
26511                         x := z.Args[1]
26512                         if !(z.Uses == 1) {
26513                                 break
26514                         }
26515                         v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
26516                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
26517                         v1.AddArg2(x, y)
26518                         v0.AddArg2(a, v1)
26519                         b.resetWithControl(BlockARM64NE, v0)
26520                         return true
26521                 }
26522                 // match: (NE (CMPconst [0] z:(MSUB a x y)) yes no)
26523                 // cond: z.Uses==1
26524                 // result: (NE (CMP a (MUL <x.Type> x y)) yes no)
26525                 for b.Controls[0].Op == OpARM64CMPconst {
26526                         v_0 := b.Controls[0]
26527                         if auxIntToInt64(v_0.AuxInt) != 0 {
26528                                 break
26529                         }
26530                         z := v_0.Args[0]
26531                         if z.Op != OpARM64MSUB {
26532                                 break
26533                         }
26534                         y := z.Args[2]
26535                         a := z.Args[0]
26536                         x := z.Args[1]
26537                         if !(z.Uses == 1) {
26538                                 break
26539                         }
26540                         v0 := b.NewValue0(v_0.Pos, OpARM64CMP, types.TypeFlags)
26541                         v1 := b.NewValue0(v_0.Pos, OpARM64MUL, x.Type)
26542                         v1.AddArg2(x, y)
26543                         v0.AddArg2(a, v1)
26544                         b.resetWithControl(BlockARM64NE, v0)
26545                         return true
26546                 }
26547                 // match: (NE (CMPWconst [0] z:(MADDW a x y)) yes no)
26548                 // cond: z.Uses==1
26549                 // result: (NE (CMNW a (MULW <x.Type> x y)) yes no)
26550                 for b.Controls[0].Op == OpARM64CMPWconst {
26551                         v_0 := b.Controls[0]
26552                         if auxIntToInt32(v_0.AuxInt) != 0 {
26553                                 break
26554                         }
26555                         z := v_0.Args[0]
26556                         if z.Op != OpARM64MADDW {
26557                                 break
26558                         }
26559                         y := z.Args[2]
26560                         a := z.Args[0]
26561                         x := z.Args[1]
26562                         if !(z.Uses == 1) {
26563                                 break
26564                         }
26565                         v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
26566                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
26567                         v1.AddArg2(x, y)
26568                         v0.AddArg2(a, v1)
26569                         b.resetWithControl(BlockARM64NE, v0)
26570                         return true
26571                 }
26572                 // match: (NE (CMPWconst [0] z:(MSUBW a x y)) yes no)
26573                 // cond: z.Uses==1
26574                 // result: (NE (CMPW a (MULW <x.Type> x y)) yes no)
26575                 for b.Controls[0].Op == OpARM64CMPWconst {
26576                         v_0 := b.Controls[0]
26577                         if auxIntToInt32(v_0.AuxInt) != 0 {
26578                                 break
26579                         }
26580                         z := v_0.Args[0]
26581                         if z.Op != OpARM64MSUBW {
26582                                 break
26583                         }
26584                         y := z.Args[2]
26585                         a := z.Args[0]
26586                         x := z.Args[1]
26587                         if !(z.Uses == 1) {
26588                                 break
26589                         }
26590                         v0 := b.NewValue0(v_0.Pos, OpARM64CMPW, types.TypeFlags)
26591                         v1 := b.NewValue0(v_0.Pos, OpARM64MULW, x.Type)
26592                         v1.AddArg2(x, y)
26593                         v0.AddArg2(a, v1)
26594                         b.resetWithControl(BlockARM64NE, v0)
26595                         return true
26596                 }
26597                 // match: (NE (TSTconst [c] x) yes no)
26598                 // cond: oneBit(c)
26599                 // result: (TBNZ [int64(ntz64(c))] x yes no)
26600                 for b.Controls[0].Op == OpARM64TSTconst {
26601                         v_0 := b.Controls[0]
26602                         c := auxIntToInt64(v_0.AuxInt)
26603                         x := v_0.Args[0]
26604                         if !(oneBit(c)) {
26605                                 break
26606                         }
26607                         b.resetWithControl(BlockARM64TBNZ, x)
26608                         b.AuxInt = int64ToAuxInt(int64(ntz64(c)))
26609                         return true
26610                 }
26611                 // match: (NE (TSTWconst [c] x) yes no)
26612                 // cond: oneBit(int64(uint32(c)))
26613                 // result: (TBNZ [int64(ntz64(int64(uint32(c))))] x yes no)
26614                 for b.Controls[0].Op == OpARM64TSTWconst {
26615                         v_0 := b.Controls[0]
26616                         c := auxIntToInt32(v_0.AuxInt)
26617                         x := v_0.Args[0]
26618                         if !(oneBit(int64(uint32(c)))) {
26619                                 break
26620                         }
26621                         b.resetWithControl(BlockARM64TBNZ, x)
26622                         b.AuxInt = int64ToAuxInt(int64(ntz64(int64(uint32(c)))))
26623                         return true
26624                 }
26625                 // match: (NE (FlagConstant [fc]) yes no)
26626                 // cond: fc.ne()
26627                 // result: (First yes no)
26628                 for b.Controls[0].Op == OpARM64FlagConstant {
26629                         v_0 := b.Controls[0]
26630                         fc := auxIntToFlagConstant(v_0.AuxInt)
26631                         if !(fc.ne()) {
26632                                 break
26633                         }
26634                         b.Reset(BlockFirst)
26635                         return true
26636                 }
26637                 // match: (NE (FlagConstant [fc]) yes no)
26638                 // cond: !fc.ne()
26639                 // result: (First no yes)
26640                 for b.Controls[0].Op == OpARM64FlagConstant {
26641                         v_0 := b.Controls[0]
26642                         fc := auxIntToFlagConstant(v_0.AuxInt)
26643                         if !(!fc.ne()) {
26644                                 break
26645                         }
26646                         b.Reset(BlockFirst)
26647                         b.swapSuccessors()
26648                         return true
26649                 }
26650                 // match: (NE (InvertFlags cmp) yes no)
26651                 // result: (NE cmp yes no)
26652                 for b.Controls[0].Op == OpARM64InvertFlags {
26653                         v_0 := b.Controls[0]
26654                         cmp := v_0.Args[0]
26655                         b.resetWithControl(BlockARM64NE, cmp)
26656                         return true
26657                 }
26658         case BlockARM64NZ:
26659                 // match: (NZ (Equal cc) yes no)
26660                 // result: (EQ cc yes no)
26661                 for b.Controls[0].Op == OpARM64Equal {
26662                         v_0 := b.Controls[0]
26663                         cc := v_0.Args[0]
26664                         b.resetWithControl(BlockARM64EQ, cc)
26665                         return true
26666                 }
26667                 // match: (NZ (NotEqual cc) yes no)
26668                 // result: (NE cc yes no)
26669                 for b.Controls[0].Op == OpARM64NotEqual {
26670                         v_0 := b.Controls[0]
26671                         cc := v_0.Args[0]
26672                         b.resetWithControl(BlockARM64NE, cc)
26673                         return true
26674                 }
26675                 // match: (NZ (LessThan cc) yes no)
26676                 // result: (LT cc yes no)
26677                 for b.Controls[0].Op == OpARM64LessThan {
26678                         v_0 := b.Controls[0]
26679                         cc := v_0.Args[0]
26680                         b.resetWithControl(BlockARM64LT, cc)
26681                         return true
26682                 }
26683                 // match: (NZ (LessThanU cc) yes no)
26684                 // result: (ULT cc yes no)
26685                 for b.Controls[0].Op == OpARM64LessThanU {
26686                         v_0 := b.Controls[0]
26687                         cc := v_0.Args[0]
26688                         b.resetWithControl(BlockARM64ULT, cc)
26689                         return true
26690                 }
26691                 // match: (NZ (LessEqual cc) yes no)
26692                 // result: (LE cc yes no)
26693                 for b.Controls[0].Op == OpARM64LessEqual {
26694                         v_0 := b.Controls[0]
26695                         cc := v_0.Args[0]
26696                         b.resetWithControl(BlockARM64LE, cc)
26697                         return true
26698                 }
26699                 // match: (NZ (LessEqualU cc) yes no)
26700                 // result: (ULE cc yes no)
26701                 for b.Controls[0].Op == OpARM64LessEqualU {
26702                         v_0 := b.Controls[0]
26703                         cc := v_0.Args[0]
26704                         b.resetWithControl(BlockARM64ULE, cc)
26705                         return true
26706                 }
26707                 // match: (NZ (GreaterThan cc) yes no)
26708                 // result: (GT cc yes no)
26709                 for b.Controls[0].Op == OpARM64GreaterThan {
26710                         v_0 := b.Controls[0]
26711                         cc := v_0.Args[0]
26712                         b.resetWithControl(BlockARM64GT, cc)
26713                         return true
26714                 }
26715                 // match: (NZ (GreaterThanU cc) yes no)
26716                 // result: (UGT cc yes no)
26717                 for b.Controls[0].Op == OpARM64GreaterThanU {
26718                         v_0 := b.Controls[0]
26719                         cc := v_0.Args[0]
26720                         b.resetWithControl(BlockARM64UGT, cc)
26721                         return true
26722                 }
26723                 // match: (NZ (GreaterEqual cc) yes no)
26724                 // result: (GE cc yes no)
26725                 for b.Controls[0].Op == OpARM64GreaterEqual {
26726                         v_0 := b.Controls[0]
26727                         cc := v_0.Args[0]
26728                         b.resetWithControl(BlockARM64GE, cc)
26729                         return true
26730                 }
26731                 // match: (NZ (GreaterEqualU cc) yes no)
26732                 // result: (UGE cc yes no)
26733                 for b.Controls[0].Op == OpARM64GreaterEqualU {
26734                         v_0 := b.Controls[0]
26735                         cc := v_0.Args[0]
26736                         b.resetWithControl(BlockARM64UGE, cc)
26737                         return true
26738                 }
26739                 // match: (NZ (LessThanF cc) yes no)
26740                 // result: (FLT cc yes no)
26741                 for b.Controls[0].Op == OpARM64LessThanF {
26742                         v_0 := b.Controls[0]
26743                         cc := v_0.Args[0]
26744                         b.resetWithControl(BlockARM64FLT, cc)
26745                         return true
26746                 }
26747                 // match: (NZ (LessEqualF cc) yes no)
26748                 // result: (FLE cc yes no)
26749                 for b.Controls[0].Op == OpARM64LessEqualF {
26750                         v_0 := b.Controls[0]
26751                         cc := v_0.Args[0]
26752                         b.resetWithControl(BlockARM64FLE, cc)
26753                         return true
26754                 }
26755                 // match: (NZ (GreaterThanF cc) yes no)
26756                 // result: (FGT cc yes no)
26757                 for b.Controls[0].Op == OpARM64GreaterThanF {
26758                         v_0 := b.Controls[0]
26759                         cc := v_0.Args[0]
26760                         b.resetWithControl(BlockARM64FGT, cc)
26761                         return true
26762                 }
26763                 // match: (NZ (GreaterEqualF cc) yes no)
26764                 // result: (FGE cc yes no)
26765                 for b.Controls[0].Op == OpARM64GreaterEqualF {
26766                         v_0 := b.Controls[0]
26767                         cc := v_0.Args[0]
26768                         b.resetWithControl(BlockARM64FGE, cc)
26769                         return true
26770                 }
26771                 // match: (NZ (ANDconst [c] x) yes no)
26772                 // cond: oneBit(c)
26773                 // result: (TBNZ [int64(ntz64(c))] x yes no)
26774                 for b.Controls[0].Op == OpARM64ANDconst {
26775                         v_0 := b.Controls[0]
26776                         c := auxIntToInt64(v_0.AuxInt)
26777                         x := v_0.Args[0]
26778                         if !(oneBit(c)) {
26779                                 break
26780                         }
26781                         b.resetWithControl(BlockARM64TBNZ, x)
26782                         b.AuxInt = int64ToAuxInt(int64(ntz64(c)))
26783                         return true
26784                 }
26785                 // match: (NZ (MOVDconst [0]) yes no)
26786                 // result: (First no yes)
26787                 for b.Controls[0].Op == OpARM64MOVDconst {
26788                         v_0 := b.Controls[0]
26789                         if auxIntToInt64(v_0.AuxInt) != 0 {
26790                                 break
26791                         }
26792                         b.Reset(BlockFirst)
26793                         b.swapSuccessors()
26794                         return true
26795                 }
26796                 // match: (NZ (MOVDconst [c]) yes no)
26797                 // cond: c != 0
26798                 // result: (First yes no)
26799                 for b.Controls[0].Op == OpARM64MOVDconst {
26800                         v_0 := b.Controls[0]
26801                         c := auxIntToInt64(v_0.AuxInt)
26802                         if !(c != 0) {
26803                                 break
26804                         }
26805                         b.Reset(BlockFirst)
26806                         return true
26807                 }
26808         case BlockARM64NZW:
26809                 // match: (NZW (ANDconst [c] x) yes no)
26810                 // cond: oneBit(int64(uint32(c)))
26811                 // result: (TBNZ [int64(ntz64(int64(uint32(c))))] x yes no)
26812                 for b.Controls[0].Op == OpARM64ANDconst {
26813                         v_0 := b.Controls[0]
26814                         c := auxIntToInt64(v_0.AuxInt)
26815                         x := v_0.Args[0]
26816                         if !(oneBit(int64(uint32(c)))) {
26817                                 break
26818                         }
26819                         b.resetWithControl(BlockARM64TBNZ, x)
26820                         b.AuxInt = int64ToAuxInt(int64(ntz64(int64(uint32(c)))))
26821                         return true
26822                 }
26823                 // match: (NZW (MOVDconst [c]) yes no)
26824                 // cond: int32(c) == 0
26825                 // result: (First no yes)
26826                 for b.Controls[0].Op == OpARM64MOVDconst {
26827                         v_0 := b.Controls[0]
26828                         c := auxIntToInt64(v_0.AuxInt)
26829                         if !(int32(c) == 0) {
26830                                 break
26831                         }
26832                         b.Reset(BlockFirst)
26833                         b.swapSuccessors()
26834                         return true
26835                 }
26836                 // match: (NZW (MOVDconst [c]) yes no)
26837                 // cond: int32(c) != 0
26838                 // result: (First yes no)
26839                 for b.Controls[0].Op == OpARM64MOVDconst {
26840                         v_0 := b.Controls[0]
26841                         c := auxIntToInt64(v_0.AuxInt)
26842                         if !(int32(c) != 0) {
26843                                 break
26844                         }
26845                         b.Reset(BlockFirst)
26846                         return true
26847                 }
26848         case BlockARM64TBNZ:
26849                 // match: (TBNZ [0] (Equal cc) yes no)
26850                 // result: (EQ cc yes no)
26851                 for b.Controls[0].Op == OpARM64Equal {
26852                         v_0 := b.Controls[0]
26853                         cc := v_0.Args[0]
26854                         if auxIntToInt64(b.AuxInt) != 0 {
26855                                 break
26856                         }
26857                         b.resetWithControl(BlockARM64EQ, cc)
26858                         return true
26859                 }
26860                 // match: (TBNZ [0] (NotEqual cc) yes no)
26861                 // result: (NE cc yes no)
26862                 for b.Controls[0].Op == OpARM64NotEqual {
26863                         v_0 := b.Controls[0]
26864                         cc := v_0.Args[0]
26865                         if auxIntToInt64(b.AuxInt) != 0 {
26866                                 break
26867                         }
26868                         b.resetWithControl(BlockARM64NE, cc)
26869                         return true
26870                 }
26871                 // match: (TBNZ [0] (LessThan cc) yes no)
26872                 // result: (LT cc yes no)
26873                 for b.Controls[0].Op == OpARM64LessThan {
26874                         v_0 := b.Controls[0]
26875                         cc := v_0.Args[0]
26876                         if auxIntToInt64(b.AuxInt) != 0 {
26877                                 break
26878                         }
26879                         b.resetWithControl(BlockARM64LT, cc)
26880                         return true
26881                 }
26882                 // match: (TBNZ [0] (LessThanU cc) yes no)
26883                 // result: (ULT cc yes no)
26884                 for b.Controls[0].Op == OpARM64LessThanU {
26885                         v_0 := b.Controls[0]
26886                         cc := v_0.Args[0]
26887                         if auxIntToInt64(b.AuxInt) != 0 {
26888                                 break
26889                         }
26890                         b.resetWithControl(BlockARM64ULT, cc)
26891                         return true
26892                 }
26893                 // match: (TBNZ [0] (LessEqual cc) yes no)
26894                 // result: (LE cc yes no)
26895                 for b.Controls[0].Op == OpARM64LessEqual {
26896                         v_0 := b.Controls[0]
26897                         cc := v_0.Args[0]
26898                         if auxIntToInt64(b.AuxInt) != 0 {
26899                                 break
26900                         }
26901                         b.resetWithControl(BlockARM64LE, cc)
26902                         return true
26903                 }
26904                 // match: (TBNZ [0] (LessEqualU cc) yes no)
26905                 // result: (ULE cc yes no)
26906                 for b.Controls[0].Op == OpARM64LessEqualU {
26907                         v_0 := b.Controls[0]
26908                         cc := v_0.Args[0]
26909                         if auxIntToInt64(b.AuxInt) != 0 {
26910                                 break
26911                         }
26912                         b.resetWithControl(BlockARM64ULE, cc)
26913                         return true
26914                 }
26915                 // match: (TBNZ [0] (GreaterThan cc) yes no)
26916                 // result: (GT cc yes no)
26917                 for b.Controls[0].Op == OpARM64GreaterThan {
26918                         v_0 := b.Controls[0]
26919                         cc := v_0.Args[0]
26920                         if auxIntToInt64(b.AuxInt) != 0 {
26921                                 break
26922                         }
26923                         b.resetWithControl(BlockARM64GT, cc)
26924                         return true
26925                 }
26926                 // match: (TBNZ [0] (GreaterThanU cc) yes no)
26927                 // result: (UGT cc yes no)
26928                 for b.Controls[0].Op == OpARM64GreaterThanU {
26929                         v_0 := b.Controls[0]
26930                         cc := v_0.Args[0]
26931                         if auxIntToInt64(b.AuxInt) != 0 {
26932                                 break
26933                         }
26934                         b.resetWithControl(BlockARM64UGT, cc)
26935                         return true
26936                 }
26937                 // match: (TBNZ [0] (GreaterEqual cc) yes no)
26938                 // result: (GE cc yes no)
26939                 for b.Controls[0].Op == OpARM64GreaterEqual {
26940                         v_0 := b.Controls[0]
26941                         cc := v_0.Args[0]
26942                         if auxIntToInt64(b.AuxInt) != 0 {
26943                                 break
26944                         }
26945                         b.resetWithControl(BlockARM64GE, cc)
26946                         return true
26947                 }
26948                 // match: (TBNZ [0] (GreaterEqualU cc) yes no)
26949                 // result: (UGE cc yes no)
26950                 for b.Controls[0].Op == OpARM64GreaterEqualU {
26951                         v_0 := b.Controls[0]
26952                         cc := v_0.Args[0]
26953                         if auxIntToInt64(b.AuxInt) != 0 {
26954                                 break
26955                         }
26956                         b.resetWithControl(BlockARM64UGE, cc)
26957                         return true
26958                 }
26959                 // match: (TBNZ [0] (LessThanF cc) yes no)
26960                 // result: (FLT cc yes no)
26961                 for b.Controls[0].Op == OpARM64LessThanF {
26962                         v_0 := b.Controls[0]
26963                         cc := v_0.Args[0]
26964                         if auxIntToInt64(b.AuxInt) != 0 {
26965                                 break
26966                         }
26967                         b.resetWithControl(BlockARM64FLT, cc)
26968                         return true
26969                 }
26970                 // match: (TBNZ [0] (LessEqualF cc) yes no)
26971                 // result: (FLE cc yes no)
26972                 for b.Controls[0].Op == OpARM64LessEqualF {
26973                         v_0 := b.Controls[0]
26974                         cc := v_0.Args[0]
26975                         if auxIntToInt64(b.AuxInt) != 0 {
26976                                 break
26977                         }
26978                         b.resetWithControl(BlockARM64FLE, cc)
26979                         return true
26980                 }
26981                 // match: (TBNZ [0] (GreaterThanF cc) yes no)
26982                 // result: (FGT cc yes no)
26983                 for b.Controls[0].Op == OpARM64GreaterThanF {
26984                         v_0 := b.Controls[0]
26985                         cc := v_0.Args[0]
26986                         if auxIntToInt64(b.AuxInt) != 0 {
26987                                 break
26988                         }
26989                         b.resetWithControl(BlockARM64FGT, cc)
26990                         return true
26991                 }
26992                 // match: (TBNZ [0] (GreaterEqualF cc) yes no)
26993                 // result: (FGE cc yes no)
26994                 for b.Controls[0].Op == OpARM64GreaterEqualF {
26995                         v_0 := b.Controls[0]
26996                         cc := v_0.Args[0]
26997                         if auxIntToInt64(b.AuxInt) != 0 {
26998                                 break
26999                         }
27000                         b.resetWithControl(BlockARM64FGE, cc)
27001                         return true
27002                 }
27003         case BlockARM64UGE:
27004                 // match: (UGE (FlagConstant [fc]) yes no)
27005                 // cond: fc.uge()
27006                 // result: (First yes no)
27007                 for b.Controls[0].Op == OpARM64FlagConstant {
27008                         v_0 := b.Controls[0]
27009                         fc := auxIntToFlagConstant(v_0.AuxInt)
27010                         if !(fc.uge()) {
27011                                 break
27012                         }
27013                         b.Reset(BlockFirst)
27014                         return true
27015                 }
27016                 // match: (UGE (FlagConstant [fc]) yes no)
27017                 // cond: !fc.uge()
27018                 // result: (First no yes)
27019                 for b.Controls[0].Op == OpARM64FlagConstant {
27020                         v_0 := b.Controls[0]
27021                         fc := auxIntToFlagConstant(v_0.AuxInt)
27022                         if !(!fc.uge()) {
27023                                 break
27024                         }
27025                         b.Reset(BlockFirst)
27026                         b.swapSuccessors()
27027                         return true
27028                 }
27029                 // match: (UGE (InvertFlags cmp) yes no)
27030                 // result: (ULE cmp yes no)
27031                 for b.Controls[0].Op == OpARM64InvertFlags {
27032                         v_0 := b.Controls[0]
27033                         cmp := v_0.Args[0]
27034                         b.resetWithControl(BlockARM64ULE, cmp)
27035                         return true
27036                 }
27037         case BlockARM64UGT:
27038                 // match: (UGT (FlagConstant [fc]) yes no)
27039                 // cond: fc.ugt()
27040                 // result: (First yes no)
27041                 for b.Controls[0].Op == OpARM64FlagConstant {
27042                         v_0 := b.Controls[0]
27043                         fc := auxIntToFlagConstant(v_0.AuxInt)
27044                         if !(fc.ugt()) {
27045                                 break
27046                         }
27047                         b.Reset(BlockFirst)
27048                         return true
27049                 }
27050                 // match: (UGT (FlagConstant [fc]) yes no)
27051                 // cond: !fc.ugt()
27052                 // result: (First no yes)
27053                 for b.Controls[0].Op == OpARM64FlagConstant {
27054                         v_0 := b.Controls[0]
27055                         fc := auxIntToFlagConstant(v_0.AuxInt)
27056                         if !(!fc.ugt()) {
27057                                 break
27058                         }
27059                         b.Reset(BlockFirst)
27060                         b.swapSuccessors()
27061                         return true
27062                 }
27063                 // match: (UGT (InvertFlags cmp) yes no)
27064                 // result: (ULT cmp yes no)
27065                 for b.Controls[0].Op == OpARM64InvertFlags {
27066                         v_0 := b.Controls[0]
27067                         cmp := v_0.Args[0]
27068                         b.resetWithControl(BlockARM64ULT, cmp)
27069                         return true
27070                 }
27071         case BlockARM64ULE:
27072                 // match: (ULE (FlagConstant [fc]) yes no)
27073                 // cond: fc.ule()
27074                 // result: (First yes no)
27075                 for b.Controls[0].Op == OpARM64FlagConstant {
27076                         v_0 := b.Controls[0]
27077                         fc := auxIntToFlagConstant(v_0.AuxInt)
27078                         if !(fc.ule()) {
27079                                 break
27080                         }
27081                         b.Reset(BlockFirst)
27082                         return true
27083                 }
27084                 // match: (ULE (FlagConstant [fc]) yes no)
27085                 // cond: !fc.ule()
27086                 // result: (First no yes)
27087                 for b.Controls[0].Op == OpARM64FlagConstant {
27088                         v_0 := b.Controls[0]
27089                         fc := auxIntToFlagConstant(v_0.AuxInt)
27090                         if !(!fc.ule()) {
27091                                 break
27092                         }
27093                         b.Reset(BlockFirst)
27094                         b.swapSuccessors()
27095                         return true
27096                 }
27097                 // match: (ULE (InvertFlags cmp) yes no)
27098                 // result: (UGE cmp yes no)
27099                 for b.Controls[0].Op == OpARM64InvertFlags {
27100                         v_0 := b.Controls[0]
27101                         cmp := v_0.Args[0]
27102                         b.resetWithControl(BlockARM64UGE, cmp)
27103                         return true
27104                 }
27105         case BlockARM64ULT:
27106                 // match: (ULT (FlagConstant [fc]) yes no)
27107                 // cond: fc.ult()
27108                 // result: (First yes no)
27109                 for b.Controls[0].Op == OpARM64FlagConstant {
27110                         v_0 := b.Controls[0]
27111                         fc := auxIntToFlagConstant(v_0.AuxInt)
27112                         if !(fc.ult()) {
27113                                 break
27114                         }
27115                         b.Reset(BlockFirst)
27116                         return true
27117                 }
27118                 // match: (ULT (FlagConstant [fc]) yes no)
27119                 // cond: !fc.ult()
27120                 // result: (First no yes)
27121                 for b.Controls[0].Op == OpARM64FlagConstant {
27122                         v_0 := b.Controls[0]
27123                         fc := auxIntToFlagConstant(v_0.AuxInt)
27124                         if !(!fc.ult()) {
27125                                 break
27126                         }
27127                         b.Reset(BlockFirst)
27128                         b.swapSuccessors()
27129                         return true
27130                 }
27131                 // match: (ULT (InvertFlags cmp) yes no)
27132                 // result: (UGT cmp yes no)
27133                 for b.Controls[0].Op == OpARM64InvertFlags {
27134                         v_0 := b.Controls[0]
27135                         cmp := v_0.Args[0]
27136                         b.resetWithControl(BlockARM64UGT, cmp)
27137                         return true
27138                 }
27139         case BlockARM64Z:
27140                 // match: (Z (ANDconst [c] x) yes no)
27141                 // cond: oneBit(c)
27142                 // result: (TBZ [int64(ntz64(c))] x yes no)
27143                 for b.Controls[0].Op == OpARM64ANDconst {
27144                         v_0 := b.Controls[0]
27145                         c := auxIntToInt64(v_0.AuxInt)
27146                         x := v_0.Args[0]
27147                         if !(oneBit(c)) {
27148                                 break
27149                         }
27150                         b.resetWithControl(BlockARM64TBZ, x)
27151                         b.AuxInt = int64ToAuxInt(int64(ntz64(c)))
27152                         return true
27153                 }
27154                 // match: (Z (MOVDconst [0]) yes no)
27155                 // result: (First yes no)
27156                 for b.Controls[0].Op == OpARM64MOVDconst {
27157                         v_0 := b.Controls[0]
27158                         if auxIntToInt64(v_0.AuxInt) != 0 {
27159                                 break
27160                         }
27161                         b.Reset(BlockFirst)
27162                         return true
27163                 }
27164                 // match: (Z (MOVDconst [c]) yes no)
27165                 // cond: c != 0
27166                 // result: (First no yes)
27167                 for b.Controls[0].Op == OpARM64MOVDconst {
27168                         v_0 := b.Controls[0]
27169                         c := auxIntToInt64(v_0.AuxInt)
27170                         if !(c != 0) {
27171                                 break
27172                         }
27173                         b.Reset(BlockFirst)
27174                         b.swapSuccessors()
27175                         return true
27176                 }
27177         case BlockARM64ZW:
27178                 // match: (ZW (ANDconst [c] x) yes no)
27179                 // cond: oneBit(int64(uint32(c)))
27180                 // result: (TBZ [int64(ntz64(int64(uint32(c))))] x yes no)
27181                 for b.Controls[0].Op == OpARM64ANDconst {
27182                         v_0 := b.Controls[0]
27183                         c := auxIntToInt64(v_0.AuxInt)
27184                         x := v_0.Args[0]
27185                         if !(oneBit(int64(uint32(c)))) {
27186                                 break
27187                         }
27188                         b.resetWithControl(BlockARM64TBZ, x)
27189                         b.AuxInt = int64ToAuxInt(int64(ntz64(int64(uint32(c)))))
27190                         return true
27191                 }
27192                 // match: (ZW (MOVDconst [c]) yes no)
27193                 // cond: int32(c) == 0
27194                 // result: (First yes no)
27195                 for b.Controls[0].Op == OpARM64MOVDconst {
27196                         v_0 := b.Controls[0]
27197                         c := auxIntToInt64(v_0.AuxInt)
27198                         if !(int32(c) == 0) {
27199                                 break
27200                         }
27201                         b.Reset(BlockFirst)
27202                         return true
27203                 }
27204                 // match: (ZW (MOVDconst [c]) yes no)
27205                 // cond: int32(c) != 0
27206                 // result: (First no yes)
27207                 for b.Controls[0].Op == OpARM64MOVDconst {
27208                         v_0 := b.Controls[0]
27209                         c := auxIntToInt64(v_0.AuxInt)
27210                         if !(int32(c) != 0) {
27211                                 break
27212                         }
27213                         b.Reset(BlockFirst)
27214                         b.swapSuccessors()
27215                         return true
27216                 }
27217         }
27218         return false
27219 }