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",-"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:"SRAI",-"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",-"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",-"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:"SRA",-"OR",-"SLTIU"
120 // s390x:-"RISBGZ",-"AND",-"LOCGR"
124 func lshMask64x32(v int64, s uint32) int64 {
125 // arm64:"LSL",-"AND"
126 // ppc64x:"RLDICL",-"ORN"
127 // riscv64:"SLL",-"AND\t",-"SLTIU"
128 // s390x:-"RISBGZ",-"AND",-"LOCGR"
132 func rshMask64Ux32(v uint64, s uint32) uint64 {
133 // arm64:"LSR",-"AND",-"CSEL"
134 // ppc64x:"RLDICL",-"ORN"
135 // riscv64:"SRL\t",-"AND\t",-"SLTIU"
136 // s390x:-"RISBGZ",-"AND",-"LOCGR"
140 func rshMask64x32(v int64, s uint32) int64 {
141 // arm64:"ASR",-"AND",-"CSEL"
142 // ppc64x:"RLDICL",-"ORN",-"ISEL"
143 // riscv64:"SRA",-"OR",-"SLTIU"
144 // s390x:-"RISBGZ",-"AND",-"LOCGR"
148 func lshMask64x32Ext(v int64, s int32) int64 {
149 // ppc64x:"RLDICL",-"ORN",-"ISEL"
150 // riscv64:"SLL",-"AND\t",-"SLTIU"
151 // s390x:-"RISBGZ",-"AND",-"LOCGR"
152 return v << uint(s&63)
155 func rshMask64Ux32Ext(v uint64, s int32) uint64 {
156 // ppc64x:"RLDICL",-"ORN",-"ISEL"
157 // riscv64:"SRL\t",-"AND\t",-"SLTIU"
158 // s390x:-"RISBGZ",-"AND",-"LOCGR"
159 return v >> uint(s&63)
162 func rshMask64x32Ext(v int64, s int32) int64 {
163 // ppc64x:"RLDICL",-"ORN",-"ISEL"
164 // riscv64:"SRA",-"OR",-"SLTIU"
165 // s390x:-"RISBGZ",-"AND",-"LOCGR"
166 return v >> uint(s&63)
169 // --------------- //
171 // --------------- //
173 // We do want to generate a test + panicshift for these cases.
174 func lshSigned(v8 int8, v16 int16, v32 int32, v64 int64, x int) {
185 // We want to avoid generating a test + panicshift for these cases.
186 func lshSignedMasked(v8 int8, v16 int16, v32 int32, v64 int64, x int) {
197 // ------------------ //
199 // ------------------ //
201 func lshGuarded64(v int64, s uint) int64 {
203 // riscv64:"SLL",-"AND",-"SLTIU"
204 // s390x:-"RISBGZ",-"AND",-"LOCGR"
205 // wasm:-"Select",-".*LtU"
206 // arm64:"LSL",-"CSEL"
209 panic("shift too large")
212 func rshGuarded64U(v uint64, s uint) uint64 {
214 // riscv64:"SRL\t",-"AND",-"SLTIU"
215 // s390x:-"RISBGZ",-"AND",-"LOCGR"
216 // wasm:-"Select",-".*LtU"
217 // arm64:"LSR",-"CSEL"
220 panic("shift too large")
223 func rshGuarded64(v int64, s uint) int64 {
225 // riscv64:"SRA",-"OR",-"SLTIU"
226 // s390x:-"RISBGZ",-"AND",-"LOCGR"
227 // wasm:-"Select",-".*LtU"
228 // arm64:"ASR",-"CSEL"
231 panic("shift too large")
234 func provedUnsignedShiftLeft(val64 uint64, val32 uint32, val16 uint16, val8 uint8, shift int) (r1 uint64, r2 uint32, r3 uint16, r4 uint8) {
235 if shift >= 0 && shift < 64 {
236 // arm64:"LSL",-"CSEL"
239 if shift >= 0 && shift < 32 {
240 // arm64:"LSL",-"CSEL"
243 if shift >= 0 && shift < 16 {
244 // arm64:"LSL",-"CSEL"
247 if shift >= 0 && shift < 8 {
248 // arm64:"LSL",-"CSEL"
251 return r1, r2, r3, r4
254 func provedSignedShiftLeft(val64 int64, val32 int32, val16 int16, val8 int8, shift int) (r1 int64, r2 int32, r3 int16, r4 int8) {
255 if shift >= 0 && shift < 64 {
256 // arm64:"LSL",-"CSEL"
259 if shift >= 0 && shift < 32 {
260 // arm64:"LSL",-"CSEL"
263 if shift >= 0 && shift < 16 {
264 // arm64:"LSL",-"CSEL"
267 if shift >= 0 && shift < 8 {
268 // arm64:"LSL",-"CSEL"
271 return r1, r2, r3, r4
274 func provedUnsignedShiftRight(val64 uint64, val32 uint32, val16 uint16, val8 uint8, shift int) (r1 uint64, r2 uint32, r3 uint16, r4 uint8) {
275 if shift >= 0 && shift < 64 {
276 // arm64:"LSR",-"CSEL"
279 if shift >= 0 && shift < 32 {
280 // arm64:"LSR",-"CSEL"
283 if shift >= 0 && shift < 16 {
284 // arm64:"LSR",-"CSEL"
287 if shift >= 0 && shift < 8 {
288 // arm64:"LSR",-"CSEL"
291 return r1, r2, r3, r4
294 func provedSignedShiftRight(val64 int64, val32 int32, val16 int16, val8 int8, shift int) (r1 int64, r2 int32, r3 int16, r4 int8) {
295 if shift >= 0 && shift < 64 {
296 // arm64:"ASR",-"CSEL"
299 if shift >= 0 && shift < 32 {
300 // arm64:"ASR",-"CSEL"
303 if shift >= 0 && shift < 16 {
304 // arm64:"ASR",-"CSEL"
307 if shift >= 0 && shift < 8 {
308 // arm64:"ASR",-"CSEL"
311 return r1, r2, r3, r4
314 func checkUnneededTrunc(tab *[100000]uint32, d uint64, v uint32, h uint16, b byte) (uint32, uint64) {
316 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
318 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
320 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
322 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
323 f += tab[uint16(v)&h]
324 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
325 f += tab[uint16(v)^h]
326 // ppc64x:-".*RLWINM",-".*RLDICR",".*CLRLSLDI"
327 f += tab[uint16(v)|h]
328 // ppc64x:-".*AND",-"RLDICR",".*CLRLSLDI"
330 // ppc64x:-".*AND",".*CLRLSLWI"
331 f += 2 * uint32(uint16(d))
332 // ppc64x:-".*AND",-"RLDICR",".*CLRLSLDI"
333 g := 2 * uint64(uint32(d))
337 func checkCombinedShifts(v8 uint8, v16 uint16, v32 uint32, x32 int32, v64 uint64) (uint8, uint16, uint32, uint64, int64) {
339 // ppc64x:-"AND","CLRLSLWI"
343 // ppc64x:-"AND","CLRLSLWI"
344 g := (v16 & 0xFF) << 3
345 // ppc64x:-"AND","CLRLSLWI"
346 h := (v32 & 0xFFFFF) << 2
348 i := (v64 & 0xFFFFFFFF) << 5
349 // ppc64x:-"CLRLSLDI"
350 i += (v64 & 0xFFFFFFF) << 38
351 // ppc64x/power9:-"CLRLSLDI"
352 i += (v64 & 0xFFFF00) << 10
353 // ppc64x/power9:-"SLD","EXTSWSLI"
354 j := int64(x32+32) * 8
358 func checkWidenAfterShift(v int64, u uint64) (int64, uint64) {
378 return int64(h), uint64(g)
381 func checkShiftAndMask32(v []uint32) {
384 // ppc64x: "RLWNM\t[$]24, R[0-9]+, [$]12, [$]19, R[0-9]+"
385 v[i] = (v[i] & 0xFF00000) >> 8
387 // ppc64x: "RLWNM\t[$]26, R[0-9]+, [$]22, [$]29, R[0-9]+"
388 v[i] = (v[i] & 0xFF00) >> 6
390 // ppc64x: "MOVW\tR0"
391 v[i] = (v[i] & 0xFF) >> 8
393 // ppc64x: "MOVW\tR0"
394 v[i] = (v[i] & 0xF000000) >> 28
396 // ppc64x: "RLWNM\t[$]26, R[0-9]+, [$]24, [$]31, R[0-9]+"
397 v[i] = (v[i] >> 6) & 0xFF
399 // ppc64x: "RLWNM\t[$]26, R[0-9]+, [$]12, [$]19, R[0-9]+"
400 v[i] = (v[i] >> 6) & 0xFF000
402 // ppc64x: "MOVW\tR0"
403 v[i] = (v[i] >> 20) & 0xFF000
405 // ppc64x: "MOVW\tR0"
406 v[i] = (v[i] >> 24) & 0xFF00
410 func checkMergedShifts32(a [256]uint32, b [256]uint64, u uint32, v uint32) {
411 // ppc64x: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]29, R[0-9]+"
412 a[0] = a[uint8(v>>24)]
413 // ppc64x: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]21, [$]28, R[0-9]+"
414 b[0] = b[uint8(v>>24)]
415 // ppc64x: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
416 b[1] = b[(v>>20)&0xFF]
417 // ppc64x: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]28, R[0-9]+"
423 func check128bitShifts(x, y uint64, bits uint) (uint64, uint64) {
425 ŝ := (64 - bits) & 63
426 // check that the shift operation has two commas (three operands)
427 // amd64:"SHRQ.*,.*,"
429 // amd64:"SHLQ.*,.*,"
434 func checkShiftToMask(u []uint64, s []int64) {
435 // amd64:-"SHR",-"SHL","ANDQ"
436 u[0] = u[0] >> 5 << 5
437 // amd64:-"SAR",-"SHL","ANDQ"
438 s[0] = s[0] >> 5 << 5
439 // amd64:-"SHR",-"SHL","ANDQ"
440 u[1] = u[1] << 5 >> 5