2018-02-27 01:59:58 +01:00
|
|
|
// asmcheck
|
|
|
|
|
|
2018-03-02 21:06:09 +01:00
|
|
|
// Copyright 2018 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
2018-02-27 01:59:58 +01:00
|
|
|
package codegen
|
|
|
|
|
|
2020-10-23 12:12:34 -05:00
|
|
|
import "math/bits"
|
|
|
|
|
|
2018-03-10 23:51:05 +01:00
|
|
|
// ------------------- //
|
|
|
|
|
// const rotates //
|
|
|
|
|
// ------------------- //
|
|
|
|
|
|
|
|
|
|
func rot64(x uint64) uint64 {
|
|
|
|
|
var a uint64
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLQ [$]7"
|
|
|
|
|
// ppc64x:"ROTL [$]7"
|
|
|
|
|
// loong64: "ROTRV [$]57"
|
|
|
|
|
// riscv64: "RORI [$]57"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<7 | x>>57
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLQ [$]8"
|
|
|
|
|
// arm64:"ROR [$]56"
|
|
|
|
|
// s390x:"RISBGZ [$]0, [$]63, [$]8, "
|
|
|
|
|
// ppc64x:"ROTL [$]8"
|
|
|
|
|
// loong64: "ROTRV [$]56"
|
|
|
|
|
// riscv64: "RORI [$]56"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<8 + x>>56
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLQ [$]9"
|
|
|
|
|
// arm64:"ROR [$]55"
|
|
|
|
|
// s390x:"RISBGZ [$]0, [$]63, [$]9, "
|
|
|
|
|
// ppc64x:"ROTL [$]9"
|
|
|
|
|
// loong64: "ROTRV [$]55"
|
|
|
|
|
// riscv64: "RORI [$]55"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<9 ^ x>>55
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLQ [$]10"
|
|
|
|
|
// arm64:"ROR [$]54"
|
|
|
|
|
// s390x:"RISBGZ [$]0, [$]63, [$]10, "
|
|
|
|
|
// ppc64x:"ROTL [$]10"
|
|
|
|
|
// arm64:"ROR [$]54"
|
|
|
|
|
// s390x:"RISBGZ [$]0, [$]63, [$]10, "
|
|
|
|
|
// loong64: "ROTRV [$]54"
|
|
|
|
|
// riscv64: "RORI [$]54"
|
2021-09-19 09:09:55 -07:00
|
|
|
a += bits.RotateLeft64(x, 10)
|
|
|
|
|
|
2018-03-10 23:51:05 +01:00
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-27 01:59:58 +01:00
|
|
|
func rot32(x uint32) uint32 {
|
|
|
|
|
var a uint32
|
2018-03-10 23:51:05 +01:00
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLL [$]7"
|
|
|
|
|
// arm:"MOVW R\\d+@>25"
|
|
|
|
|
// ppc64x:"ROTLW [$]7"
|
|
|
|
|
// loong64: "ROTR [$]25"
|
|
|
|
|
// riscv64: "RORIW [$]25"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<7 | x>>25
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:`ROLL [$]8`
|
|
|
|
|
// arm:"MOVW R\\d+@>24"
|
|
|
|
|
// arm64:"RORW [$]24"
|
|
|
|
|
// s390x:"RLL [$]8"
|
|
|
|
|
// ppc64x:"ROTLW [$]8"
|
|
|
|
|
// loong64: "ROTR [$]24"
|
|
|
|
|
// riscv64: "RORIW [$]24"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<8 + x>>24
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLL [$]9"
|
|
|
|
|
// arm:"MOVW R\\d+@>23"
|
|
|
|
|
// arm64:"RORW [$]23"
|
|
|
|
|
// s390x:"RLL [$]9"
|
|
|
|
|
// ppc64x:"ROTLW [$]9"
|
|
|
|
|
// loong64: "ROTR [$]23"
|
|
|
|
|
// riscv64: "RORIW [$]23"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<9 ^ x>>23
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLL [$]10"
|
|
|
|
|
// arm:"MOVW R\\d+@>22"
|
|
|
|
|
// arm64:"RORW [$]22"
|
|
|
|
|
// s390x:"RLL [$]10"
|
|
|
|
|
// ppc64x:"ROTLW [$]10"
|
|
|
|
|
// arm64:"RORW [$]22"
|
|
|
|
|
// s390x:"RLL [$]10"
|
|
|
|
|
// loong64: "ROTR [$]22"
|
|
|
|
|
// riscv64: "RORIW [$]22"
|
2021-09-19 09:09:55 -07:00
|
|
|
a += bits.RotateLeft32(x, 10)
|
|
|
|
|
|
2018-02-27 01:59:58 +01:00
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-10 23:51:05 +01:00
|
|
|
func rot16(x uint16) uint16 {
|
|
|
|
|
var a uint16
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLW [$]7"
|
|
|
|
|
// riscv64: "OR" "SLLI" "SRLI" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<7 | x>>9
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:`ROLW [$]8`
|
|
|
|
|
// riscv64: "OR" "SLLI" "SRLI" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<8 + x>>8
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLW [$]9"
|
|
|
|
|
// riscv64: "OR" "SLLI" "SRLI" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<9 ^ x>>7
|
|
|
|
|
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func rot8(x uint8) uint8 {
|
|
|
|
|
var a uint8
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLB [$]5"
|
|
|
|
|
// riscv64: "OR" "SLLI" "SRLI" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<5 | x>>3
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:`ROLB [$]6`
|
|
|
|
|
// riscv64: "OR" "SLLI" "SRLI" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<6 + x>>2
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLB [$]7"
|
|
|
|
|
// riscv64: "OR" "SLLI" "SRLI" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<7 ^ x>>1
|
|
|
|
|
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------- //
|
|
|
|
|
// non-const rotates //
|
|
|
|
|
// ----------------------- //
|
|
|
|
|
|
|
|
|
|
func rot64nc(x uint64, z uint) uint64 {
|
2018-02-27 01:59:58 +01:00
|
|
|
var a uint64
|
2018-03-10 23:51:05 +01:00
|
|
|
|
|
|
|
|
z &= 63
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLQ" -"AND"
|
|
|
|
|
// arm64:"ROR" "NEG" -"AND"
|
|
|
|
|
// ppc64x:"ROTL" -"NEG" -"AND"
|
2022-08-09 23:53:37 +08:00
|
|
|
// loong64: "ROTRV", -"AND"
|
2025-10-26 22:51:14 -04:00
|
|
|
// riscv64: "ROL" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<z | x>>(64-z)
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"RORQ" -"AND"
|
|
|
|
|
// arm64:"ROR" -"NEG" -"AND"
|
|
|
|
|
// ppc64x:"ROTL" "NEG" -"AND"
|
2022-08-09 23:53:37 +08:00
|
|
|
// loong64: "ROTRV", -"AND"
|
2025-10-26 22:51:14 -04:00
|
|
|
// riscv64: "ROR" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x>>z | x<<(64-z)
|
|
|
|
|
|
2018-02-27 01:59:58 +01:00
|
|
|
return a
|
|
|
|
|
}
|
2018-03-10 23:51:05 +01:00
|
|
|
|
|
|
|
|
func rot32nc(x uint32, z uint) uint32 {
|
|
|
|
|
var a uint32
|
|
|
|
|
|
|
|
|
|
z &= 31
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLL" -"AND"
|
|
|
|
|
// arm64:"ROR" "NEG" -"AND"
|
|
|
|
|
// ppc64x:"ROTLW" -"NEG" -"AND"
|
2022-08-09 23:53:37 +08:00
|
|
|
// loong64: "ROTR", -"AND"
|
2025-10-26 22:51:14 -04:00
|
|
|
// riscv64: "ROLW" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<z | x>>(32-z)
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"RORL" -"AND"
|
|
|
|
|
// arm64:"ROR" -"NEG" -"AND"
|
|
|
|
|
// ppc64x:"ROTLW" "NEG" -"AND"
|
2022-08-09 23:53:37 +08:00
|
|
|
// loong64: "ROTR", -"AND"
|
2025-10-26 22:51:14 -04:00
|
|
|
// riscv64: "RORW" -"AND"
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x>>z | x<<(32-z)
|
|
|
|
|
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func rot16nc(x uint16, z uint) uint16 {
|
|
|
|
|
var a uint16
|
|
|
|
|
|
|
|
|
|
z &= 15
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLW" -"ANDQ"
|
|
|
|
|
// riscv64: "OR" "SLL" "SRL" -"AND "
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<z | x>>(16-z)
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"RORW" -"ANDQ"
|
|
|
|
|
// riscv64: "OR" "SLL" "SRL" -"AND "
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x>>z | x<<(16-z)
|
|
|
|
|
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func rot8nc(x uint8, z uint) uint8 {
|
|
|
|
|
var a uint8
|
|
|
|
|
|
|
|
|
|
z &= 7
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLB" -"ANDQ"
|
|
|
|
|
// riscv64: "OR" "SLL" "SRL" -"AND "
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x<<z | x>>(8-z)
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"RORB" -"ANDQ"
|
|
|
|
|
// riscv64: "OR" "SLL" "SRL" -"AND "
|
2018-03-10 23:51:05 +01:00
|
|
|
a += x>>z | x<<(8-z)
|
|
|
|
|
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Issue 18254: rotate after inlining
|
|
|
|
|
func f32(x uint32) uint32 {
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLL [$]7"
|
2018-03-10 23:51:05 +01:00
|
|
|
return rot32nc(x, 7)
|
|
|
|
|
}
|
2020-10-23 12:12:34 -05:00
|
|
|
|
2022-08-18 14:13:33 -07:00
|
|
|
func doubleRotate(x uint64) uint64 {
|
|
|
|
|
x = (x << 5) | (x >> 59)
|
2025-10-26 22:51:14 -04:00
|
|
|
// amd64:"ROLQ [$]15"
|
|
|
|
|
// arm64:"ROR [$]49"
|
2022-08-18 14:13:33 -07:00
|
|
|
x = (x << 10) | (x >> 54)
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-23 12:12:34 -05:00
|
|
|
// --------------------------------------- //
|
|
|
|
|
// Combined Rotate + Masking operations //
|
|
|
|
|
// --------------------------------------- //
|
|
|
|
|
|
|
|
|
|
func checkMaskedRotate32(a []uint32, r int) {
|
|
|
|
|
i := 0
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM [$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
2020-10-23 12:12:34 -05:00
|
|
|
a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000
|
|
|
|
|
i++
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM [$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
2020-10-23 12:12:34 -05:00
|
|
|
a[i] = bits.RotateLeft32(a[i]&0xFF, 16)
|
|
|
|
|
i++
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM [$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
|
2020-10-23 12:12:34 -05:00
|
|
|
a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0
|
|
|
|
|
i++
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM [$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
|
2020-10-23 12:12:34 -05:00
|
|
|
a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16)
|
|
|
|
|
i++
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM R[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
2020-10-23 12:12:34 -05:00
|
|
|
a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000
|
|
|
|
|
i++
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM R[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
|
2022-08-18 14:13:33 -07:00
|
|
|
a[i] = bits.RotateLeft32(a[i], r) & 0xFF00
|
2020-10-23 12:12:34 -05:00
|
|
|
i++
|
|
|
|
|
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM R[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
|
2022-08-18 14:13:33 -07:00
|
|
|
a[i] = bits.RotateLeft32(a[i], r) & 0xFFF00FFF
|
2020-10-23 12:12:34 -05:00
|
|
|
i++
|
2025-10-26 22:51:14 -04:00
|
|
|
// ppc64x: "RLWNM [$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
|
2022-08-18 14:13:33 -07:00
|
|
|
a[i] = bits.RotateLeft32(a[i], 4) & 0xFFF00FFF
|
2020-10-23 12:12:34 -05:00
|
|
|
i++
|
|
|
|
|
}
|
2021-09-19 13:51:37 -07:00
|
|
|
|
|
|
|
|
// combined arithmetic and rotate on arm64
|
|
|
|
|
func checkArithmeticWithRotate(a *[1000]uint64) {
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "AND R[0-9]+@>51, R[0-9]+, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[2] = a[1] & bits.RotateLeft64(a[0], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "ORR R[0-9]+@>51, R[0-9]+, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[5] = a[4] | bits.RotateLeft64(a[3], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "EOR R[0-9]+@>51, R[0-9]+, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[8] = a[7] ^ bits.RotateLeft64(a[6], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "MVN R[0-9]+@>51, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[10] = ^bits.RotateLeft64(a[9], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "BIC R[0-9]+@>51, R[0-9]+, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[13] = a[12] &^ bits.RotateLeft64(a[11], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "EON R[0-9]+@>51, R[0-9]+, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[16] = a[15] ^ ^bits.RotateLeft64(a[14], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "ORN R[0-9]+@>51, R[0-9]+, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
a[19] = a[18] | ^bits.RotateLeft64(a[17], 13)
|
2025-10-26 22:51:14 -04:00
|
|
|
// arm64: "TST R[0-9]+@>51, R[0-9]+"
|
2021-09-19 13:51:37 -07:00
|
|
|
if a[18]&bits.RotateLeft64(a[19], 13) == 0 {
|
|
|
|
|
a[20] = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|