go rotate 源码

  • 2022-07-15
  • 浏览 (898)

golang rotate 代码

文件路径:/test/codegen/rotate.go

// asmcheck

// 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.

package codegen

import "math/bits"

// ------------------- //
//    const rotates    //
// ------------------- //

func rot64(x uint64) uint64 {
	var a uint64

	// amd64:"ROLQ\t[$]7"
	// ppc64:"ROTL\t[$]7"
	// ppc64le:"ROTL\t[$]7"
	a += x<<7 | x>>57

	// amd64:"ROLQ\t[$]8"
	// arm64:"ROR\t[$]56"
	// s390x:"RISBGZ\t[$]0, [$]63, [$]8, "
	// ppc64:"ROTL\t[$]8"
	// ppc64le:"ROTL\t[$]8"
	a += x<<8 + x>>56

	// amd64:"ROLQ\t[$]9"
	// arm64:"ROR\t[$]55"
	// s390x:"RISBGZ\t[$]0, [$]63, [$]9, "
	// ppc64:"ROTL\t[$]9"
	// ppc64le:"ROTL\t[$]9"
	a += x<<9 ^ x>>55

	// amd64:"ROLQ\t[$]10"
	// arm64:"ROR\t[$]54"
	// s390x:"RISBGZ\t[$]0, [$]63, [$]10, "
	// ppc64:"ROTL\t[$]10"
	// ppc64le:"ROTL\t[$]10"
	// arm64:"ROR\t[$]57" // TODO this is not great line numbering, but then again, the instruction did appear
	// s390x:"RISBGZ\t[$]0, [$]63, [$]7, " // TODO ditto
	a += bits.RotateLeft64(x, 10)

	return a
}

func rot32(x uint32) uint32 {
	var a uint32

	// amd64:"ROLL\t[$]7"
	// arm:"MOVW\tR\\d+@>25"
	// ppc64:"ROTLW\t[$]7"
	// ppc64le:"ROTLW\t[$]7"
	a += x<<7 | x>>25

	// amd64:`ROLL\t[$]8`
	// arm:"MOVW\tR\\d+@>24"
	// arm64:"RORW\t[$]24"
	// s390x:"RLL\t[$]8"
	// ppc64:"ROTLW\t[$]8"
	// ppc64le:"ROTLW\t[$]8"
	a += x<<8 + x>>24

	// amd64:"ROLL\t[$]9"
	// arm:"MOVW\tR\\d+@>23"
	// arm64:"RORW\t[$]23"
	// s390x:"RLL\t[$]9"
	// ppc64:"ROTLW\t[$]9"
	// ppc64le:"ROTLW\t[$]9"
	a += x<<9 ^ x>>23

	// amd64:"ROLL\t[$]10"
	// arm:"MOVW\tR\\d+@>22"
	// arm64:"RORW\t[$]22"
	// s390x:"RLL\t[$]10"
	// ppc64:"ROTLW\t[$]10"
	// ppc64le:"ROTLW\t[$]10"
	// arm64:"RORW\t[$]25" // TODO this is not great line numbering, but then again, the instruction did appear
	// s390x:"RLL\t[$]7" // TODO ditto
	a += bits.RotateLeft32(x, 10)

	return a
}

func rot16(x uint16) uint16 {
	var a uint16

	// amd64:"ROLW\t[$]7"
	a += x<<7 | x>>9

	// amd64:`ROLW\t[$]8`
	a += x<<8 + x>>8

	// amd64:"ROLW\t[$]9"
	a += x<<9 ^ x>>7

	return a
}

func rot8(x uint8) uint8 {
	var a uint8

	// amd64:"ROLB\t[$]5"
	a += x<<5 | x>>3

	// amd64:`ROLB\t[$]6`
	a += x<<6 + x>>2

	// amd64:"ROLB\t[$]7"
	a += x<<7 ^ x>>1

	return a
}

// ----------------------- //
//    non-const rotates    //
// ----------------------- //

func rot64nc(x uint64, z uint) uint64 {
	var a uint64

	z &= 63

	// amd64:"ROLQ"
	// ppc64:"ROTL"
	// ppc64le:"ROTL"
	a += x<<z | x>>(64-z)

	// amd64:"RORQ"
	a += x>>z | x<<(64-z)

	return a
}

func rot32nc(x uint32, z uint) uint32 {
	var a uint32

	z &= 31

	// amd64:"ROLL"
	// ppc64:"ROTLW"
	// ppc64le:"ROTLW"
	a += x<<z | x>>(32-z)

	// amd64:"RORL"
	a += x>>z | x<<(32-z)

	return a
}

func rot16nc(x uint16, z uint) uint16 {
	var a uint16

	z &= 15

	// amd64:"ROLW"
	a += x<<z | x>>(16-z)

	// amd64:"RORW"
	a += x>>z | x<<(16-z)

	return a
}

func rot8nc(x uint8, z uint) uint8 {
	var a uint8

	z &= 7

	// amd64:"ROLB"
	a += x<<z | x>>(8-z)

	// amd64:"RORB"
	a += x>>z | x<<(8-z)

	return a
}

// Issue 18254: rotate after inlining
func f32(x uint32) uint32 {
	// amd64:"ROLL\t[$]7"
	return rot32nc(x, 7)
}

// --------------------------------------- //
//    Combined Rotate + Masking operations //
// --------------------------------------- //

func checkMaskedRotate32(a []uint32, r int) {
	i := 0

	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
	a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000
	i++
	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
	a[i] = bits.RotateLeft32(a[i]&0xFF, 16)
	i++
	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
	a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0
	i++
	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
	a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16)
	i++

	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
	a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000
	i++
	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
	a[i] = bits.RotateLeft32(a[3], r) & 0xFF00
	i++

	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
	a[i] = bits.RotateLeft32(a[3], r) & 0xFFF00FFF
	i++
	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
	a[i] = bits.RotateLeft32(a[3], 4) & 0xFFF00FFF
	i++
}

// combined arithmetic and rotate on arm64
func checkArithmeticWithRotate(a *[1000]uint64) {
	// arm64: "AND\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
	a[2] = a[1] & bits.RotateLeft64(a[0], 13)
	// arm64: "ORR\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
	a[5] = a[4] | bits.RotateLeft64(a[3], 13)
	// arm64: "EOR\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
	a[8] = a[7] ^ bits.RotateLeft64(a[6], 13)
	// arm64: "MVN\tR[0-9]+@>51, R[0-9]+"
	a[10] = ^bits.RotateLeft64(a[9], 13)
	// arm64: "BIC\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
	a[13] = a[12] &^ bits.RotateLeft64(a[11], 13)
	// arm64: "EON\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
	a[16] = a[15] ^ ^bits.RotateLeft64(a[14], 13)
	// arm64: "ORN\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
	a[19] = a[18] | ^bits.RotateLeft64(a[17], 13)
	// arm64: "TST\tR[0-9]+@>51, R[0-9]+"
	if a[18]&bits.RotateLeft64(a[19], 13) == 0 {
		a[20] = 1
	}

}

相关信息

go 源码目录

相关文章

go addrcalc 源码

go alloc 源码

go arithmetic 源码

go bitfield 源码

go bits 源码

go bmi 源码

go bool 源码

go clobberdead 源码

go clobberdeadreg 源码

go compare_and_branch 源码

0  赞