3 // Copyright 2018 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
9 // ------------------ //
11 // ------------------ //
13 func lshConst64x64(v int64) int64 {
15 // riscv64:"SLLI",-"AND",-"SLTIU"
16 return v << uint64(33)
19 func rshConst64Ux64(v uint64) uint64 {
21 // riscv64:"SRLI\t",-"AND",-"SLTIU"
22 return v >> uint64(33)
25 func rshConst64x64(v int64) int64 {
27 // riscv64:"SRAI\t",-"OR",-"SLTIU"
28 return v >> uint64(33)
31 func lshConst32x64(v int32) int32 {
33 // riscv64:"SLLI",-"AND",-"SLTIU", -"MOVW"
34 return v << uint64(29)
37 func rshConst32Ux64(v uint32) uint32 {
39 // riscv64:"SRLIW",-"AND",-"SLTIU", -"MOVW"
40 return v >> uint64(29)
43 func rshConst32x64(v int32) int32 {
45 // riscv64:"SRAIW",-"OR",-"SLTIU", -"MOVW"
46 return v >> uint64(29)
49 func lshConst64x32(v int64) int64 {
51 // riscv64:"SLLI",-"AND",-"SLTIU"
52 return v << uint32(33)
55 func rshConst64Ux32(v uint64) uint64 {
57 // riscv64:"SRLI\t",-"AND",-"SLTIU"
58 return v >> uint32(33)
61 func rshConst64x32(v int64) int64 {
63 // riscv64:"SRAI\t",-"OR",-"SLTIU"
64 return v >> uint32(33)
67 // ------------------ //
69 // ------------------ //
71 func lshMask64x64(v int64, s uint64) int64 {
73 // ppc64x:"RLDICL",-"ORN",-"ISEL"
74 // riscv64:"SLL",-"AND\t",-"SLTIU"
75 // s390x:-"RISBGZ",-"AND",-"LOCGR"
79 func rshMask64Ux64(v uint64, s uint64) uint64 {
80 // arm64:"LSR",-"AND",-"CSEL"
81 // ppc64x:"RLDICL",-"ORN",-"ISEL"
82 // riscv64:"SRL\t",-"AND\t",-"SLTIU"
83 // s390x:-"RISBGZ",-"AND",-"LOCGR"
87 func rshMask64x64(v int64, s uint64) int64 {
88 // arm64:"ASR",-"AND",-"CSEL"
89 // ppc64x:"RLDICL",-"ORN",-"ISEL"
90 // riscv64:"SRA\t",-"OR",-"SLTIU"
91 // s390x:-"RISBGZ",-"AND",-"LOCGR"
95 func lshMask32x64(v int32, s uint64) int32 {
97 // ppc64x:"ISEL",-"ORN"
98 // riscv64:"SLL",-"AND\t",-"SLTIU"
99 // s390x:-"RISBGZ",-"AND",-"LOCGR"
103 func rshMask32Ux64(v uint32, s uint64) uint32 {
104 // arm64:"LSR",-"AND"
105 // ppc64x:"ISEL",-"ORN"
106 // riscv64:"SRLW","SLTIU","NEG","AND\t",-"SRL\t"
107 // s390x:-"RISBGZ",-"AND",-"LOCGR"
111 func rsh5Mask32Ux64(v uint32, s uint64) uint32 {
112 // riscv64:"SRLW",-"AND\t",-"SLTIU",-"SRL\t"
116 func rshMask32x64(v int32, s uint64) int32 {
117 // arm64:"ASR",-"AND"
118 // ppc64x:"ISEL",-"ORN"
119 // riscv64:"SRAW","OR","SLTIU"
120 // s390x:-"RISBGZ",-"AND",-"LOCGR"
124 func rsh5Mask32x64(v int32, s uint64) int32 {
125 // riscv64:"SRAW",-"OR",-"SLTIU"
129 func lshMask64x32(v int64, s uint32) int64 {
130 // arm64:"LSL",-"AND"
131 // ppc64x:"RLDICL",-"ORN"
132 // riscv64:"SLL",-"AND\t",-"SLTIU"
133 // s390x:-"RISBGZ",-"AND",-"LOCGR"
137 func rshMask64Ux32(v uint64, s uint32) uint64 {
138 // arm64:"LSR",-"AND",-"CSEL"
139 // ppc64x:"RLDICL",-"ORN"
140 // riscv64:"SRL\t",-"AND\t",-"SLTIU"
141 // s390x:-"RISBGZ",-"AND",-"LOCGR"
145 func rshMask64x32(v int64, s uint32) int64 {
146 // arm64:"ASR",-"AND",-"CSEL"
147 // ppc64x:"RLDICL",-"ORN",-"ISEL"
148 // riscv64:"SRA\t",-"OR",-"SLTIU"
149 // s390x:-"RISBGZ",-"AND",-"LOCGR"
153 func lshMask64x32Ext(v int64, s int32) int64 {
154 // ppc64x:"RLDICL",-"ORN",-"ISEL"
155 // riscv64:"SLL",-"AND\t",-"SLTIU"
156 // s390x:-"RISBGZ",-"AND",-"LOCGR"
157 return v << uint(s&63)
160 func rshMask64Ux32Ext(v uint64, s int32) uint64 {
161 // ppc64x:"RLDICL",-"ORN",-"ISEL"
162 // riscv64:"SRL\t",-"AND\t",-"SLTIU"
163 // s390x:-"RISBGZ",-"AND",-"LOCGR"
164 return v >> uint(s&63)
167 func rshMask64x32Ext(v int64, s int32) int64 {
168 // ppc64x:"RLDICL",-"ORN",-"ISEL"
169 // riscv64:"SRA\t",-"OR",-"SLTIU"
170 // s390x:-"RISBGZ",-"AND",-"LOCGR"
171 return v >> uint(s&63)
174 // --------------- //
176 // --------------- //
178 // We do want to generate a test + panicshift for these cases.
179 func lshSigned(v8 int8, v16 int16, v32 int32, v64 int64, x int) {
190 // We want to avoid generating a test + panicshift for these cases.
191 func lshSignedMasked(v8 int8, v16 int16, v32 int32, v64 int64, x int) {
202 // ------------------ //
204 // ------------------ //
206 func lshGuarded64(v int64, s uint) int64 {
208 // riscv64:"SLL",-"AND",-"SLTIU"
209 // s390x:-"RISBGZ",-"AND",-"LOCGR"
210 // wasm:-"Select",-".*LtU"
211 // arm64:"LSL",-"CSEL"
214 panic("shift too large")
217 func rshGuarded64U(v uint64, s uint) uint64 {
219 // riscv64:"SRL\t",-"AND",-"SLTIU"
220 // s390x:-"RISBGZ",-"AND",-"LOCGR"
221 // wasm:-"Select",-".*LtU"
222 // arm64:"LSR",-"CSEL"
225 panic("shift too large")
228 func rshGuarded64(v int64, s uint) int64 {
230 // riscv64:"SRA\t",-"OR",-"SLTIU"
231 // s390x:-"RISBGZ",-"AND",-"LOCGR"
232 // wasm:-"Select",-".*LtU"
233 // arm64:"ASR",-"CSEL"
236 panic("shift too large")
239 func provedUnsignedShiftLeft(val64 uint64, val32 uint32, val16 uint16, val8 uint8, shift int) (r1 uint64, r2 uint32, r3 uint16, r4 uint8) {
240 if shift >= 0 && shift < 64 {
241 // arm64:"LSL",-"CSEL"
244 if shift >= 0 && shift < 32 {
245 // arm64:"LSL",-"CSEL"
248 if shift >= 0 && shift < 16 {
249 // arm64:"LSL",-"CSEL"
252 if shift >= 0 && shift < 8 {
253 // arm64:"LSL",-"CSEL"
256 return r1, r2, r3, r4
259 func provedSignedShiftLeft(val64 int64, val32 int32, val16 int16, val8 int8, shift int) (r1 int64, r2 int32, r3 int16, r4 int8) {
260 if shift >= 0 && shift < 64 {
261 // arm64:"LSL",-"CSEL"
264 if shift >= 0 && shift < 32 {
265 // arm64:"LSL",-"CSEL"
268 if shift >= 0 && shift < 16 {
269 // arm64:"LSL",-"CSEL"
272 if shift >= 0 && shift < 8 {
273 // arm64:"LSL",-"CSEL"
276 return r1, r2, r3, r4
279 func provedUnsignedShiftRight(val64 uint64, val32 uint32, val16 uint16, val8 uint8, shift int) (r1 uint64, r2 uint32, r3 uint16, r4 uint8) {
280 if shift >= 0 && shift < 64 {
281 // arm64:"LSR",-"CSEL"
284 if shift >= 0 && shift < 32 {
285 // arm64:"LSR",-"CSEL"
288 if shift >= 0 && shift < 16 {
289 // arm64:"LSR",-"CSEL"
292 if shift >= 0 && shift < 8 {
293 // arm64:"LSR",-"CSEL"
296 return r1, r2, r3, r4
299 func provedSignedShiftRight(val64 int64, val32 int32, val16 int16, val8 int8, shift int) (r1 int64, r2 int32, r3 int16, r4 int8) {
300 if shift >= 0 && shift < 64 {
301 // arm64:"ASR",-"CSEL"
304 if shift >= 0 && shift < 32 {
305 // arm64:"ASR",-"CSEL"
308 if shift >= 0 && shift < 16 {
309 // arm64:"ASR",-"CSEL"
312 if shift >= 0 && shift < 8 {
313 // arm64:"ASR",-"CSEL"
316 return r1, r2, r3, r4
319 func checkUnneededTrunc(tab *[100000]uint32, d uint64, v uint32, h uint16, b byte) (uint32, uint64) {
321 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
323 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
325 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
327 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
328 f += tab[uint16(v)&h]
329 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
330 f += tab[uint16(v)^h]
331 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
332 f += tab[uint16(v)|h]
333 // ppc64x:-".*AND",-"RLDICR",".*CLRLSLDI"
335 // ppc64x:-".*AND",".*CLRLSLWI"
336 f += 2 * uint32(uint16(d))
337 // ppc64x:-".*AND",-"RLDICR",".*CLRLSLDI"
338 g := 2 * uint64(uint32(d))
342 func checkCombinedShifts(v8 uint8, v16 uint16, v32 uint32, x32 int32, v64 uint64) (uint8, uint16, uint32, uint64, int64) {
344 // ppc64x:-"AND","CLRLSLWI"
348 // ppc64x:-"AND","CLRLSLWI"
349 g := (v16 & 0xFF) << 3
350 // ppc64x:-"AND","CLRLSLWI"
351 h := (v32 & 0xFFFFF) << 2
353 i := (v64 & 0xFFFFFFFF) << 5
354 // ppc64x:-"CLRLSLDI"
355 i += (v64 & 0xFFFFFFF) << 38
356 // ppc64x/power9:-"CLRLSLDI"
357 i += (v64 & 0xFFFF00) << 10
358 // ppc64x/power9:-"SLD","EXTSWSLI"
359 j := int64(x32+32) * 8
363 func checkWidenAfterShift(v int64, u uint64) (int64, uint64) {
383 return int64(h), uint64(g)
386 func checkShiftAndMask32(v []uint32) {
389 // ppc64x: "RLWNM\t[$]24, R[0-9]+, [$]12, [$]19, R[0-9]+"
390 v[i] = (v[i] & 0xFF00000) >> 8
392 // ppc64x: "RLWNM\t[$]26, R[0-9]+, [$]22, [$]29, R[0-9]+"
393 v[i] = (v[i] & 0xFF00) >> 6
395 // ppc64x: "MOVW\tR0"
396 v[i] = (v[i] & 0xFF) >> 8
398 // ppc64x: "MOVW\tR0"
399 v[i] = (v[i] & 0xF000000) >> 28
401 // ppc64x: "RLWNM\t[$]26, R[0-9]+, [$]24, [$]31, R[0-9]+"
402 v[i] = (v[i] >> 6) & 0xFF
404 // ppc64x: "RLWNM\t[$]26, R[0-9]+, [$]12, [$]19, R[0-9]+"
405 v[i] = (v[i] >> 6) & 0xFF000
407 // ppc64x: "MOVW\tR0"
408 v[i] = (v[i] >> 20) & 0xFF000
410 // ppc64x: "MOVW\tR0"
411 v[i] = (v[i] >> 24) & 0xFF00
415 func checkMergedShifts32(a [256]uint32, b [256]uint64, u uint32, v uint32) {
416 // ppc64x: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]29, R[0-9]+"
417 a[0] = a[uint8(v>>24)]
418 // ppc64x: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]21, [$]28, R[0-9]+"
419 b[0] = b[uint8(v>>24)]
420 // ppc64x: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
421 b[1] = b[(v>>20)&0xFF]
422 // ppc64x: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]28, R[0-9]+"
428 func check128bitShifts(x, y uint64, bits uint) (uint64, uint64) {
430 ŝ := (64 - bits) & 63
431 // check that the shift operation has two commas (three operands)
432 // amd64:"SHRQ.*,.*,"
434 // amd64:"SHLQ.*,.*,"
439 func checkShiftToMask(u []uint64, s []int64) {
440 // amd64:-"SHR",-"SHL","ANDQ"
441 u[0] = u[0] >> 5 << 5
442 // amd64:-"SAR",-"SHL","ANDQ"
443 s[0] = s[0] >> 5 << 5
444 // amd64:-"SHR",-"SHL","ANDQ"
445 u[1] = u[1] << 5 >> 5