Source file test/codegen/rotate.go
1 // asmcheck 2 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. 6 7 package codegen 8 9 import "math/bits" 10 11 // ------------------- // 12 // const rotates // 13 // ------------------- // 14 15 func rot64(x uint64) uint64 { 16 var a uint64 17 18 // amd64:"ROLQ\t[$]7" 19 // ppc64x:"ROTL\t[$]7" 20 // loong64: "ROTRV\t[$]57" 21 a += x<<7 | x>>57 22 23 // amd64:"ROLQ\t[$]8" 24 // arm64:"ROR\t[$]56" 25 // s390x:"RISBGZ\t[$]0, [$]63, [$]8, " 26 // ppc64x:"ROTL\t[$]8" 27 // loong64: "ROTRV\t[$]56" 28 a += x<<8 + x>>56 29 30 // amd64:"ROLQ\t[$]9" 31 // arm64:"ROR\t[$]55" 32 // s390x:"RISBGZ\t[$]0, [$]63, [$]9, " 33 // ppc64x:"ROTL\t[$]9" 34 // loong64: "ROTRV\t[$]55" 35 a += x<<9 ^ x>>55 36 37 // amd64:"ROLQ\t[$]10" 38 // arm64:"ROR\t[$]54" 39 // s390x:"RISBGZ\t[$]0, [$]63, [$]10, " 40 // ppc64x:"ROTL\t[$]10" 41 // arm64:"ROR\t[$]54" 42 // s390x:"RISBGZ\t[$]0, [$]63, [$]10, " 43 // loong64: "ROTRV\t[$]54" 44 a += bits.RotateLeft64(x, 10) 45 46 return a 47 } 48 49 func rot32(x uint32) uint32 { 50 var a uint32 51 52 // amd64:"ROLL\t[$]7" 53 // arm:"MOVW\tR\\d+@>25" 54 // ppc64x:"ROTLW\t[$]7" 55 // loong64: "ROTR\t[$]25" 56 a += x<<7 | x>>25 57 58 // amd64:`ROLL\t[$]8` 59 // arm:"MOVW\tR\\d+@>24" 60 // arm64:"RORW\t[$]24" 61 // s390x:"RLL\t[$]8" 62 // ppc64x:"ROTLW\t[$]8" 63 // loong64: "ROTR\t[$]24" 64 a += x<<8 + x>>24 65 66 // amd64:"ROLL\t[$]9" 67 // arm:"MOVW\tR\\d+@>23" 68 // arm64:"RORW\t[$]23" 69 // s390x:"RLL\t[$]9" 70 // ppc64x:"ROTLW\t[$]9" 71 // loong64: "ROTR\t[$]23" 72 a += x<<9 ^ x>>23 73 74 // amd64:"ROLL\t[$]10" 75 // arm:"MOVW\tR\\d+@>22" 76 // arm64:"RORW\t[$]22" 77 // s390x:"RLL\t[$]10" 78 // ppc64x:"ROTLW\t[$]10" 79 // arm64:"RORW\t[$]22" 80 // s390x:"RLL\t[$]10" 81 // loong64: "ROTR\t[$]22" 82 a += bits.RotateLeft32(x, 10) 83 84 return a 85 } 86 87 func rot16(x uint16) uint16 { 88 var a uint16 89 90 // amd64:"ROLW\t[$]7" 91 a += x<<7 | x>>9 92 93 // amd64:`ROLW\t[$]8` 94 a += x<<8 + x>>8 95 96 // amd64:"ROLW\t[$]9" 97 a += x<<9 ^ x>>7 98 99 return a 100 } 101 102 func rot8(x uint8) uint8 { 103 var a uint8 104 105 // amd64:"ROLB\t[$]5" 106 a += x<<5 | x>>3 107 108 // amd64:`ROLB\t[$]6` 109 a += x<<6 + x>>2 110 111 // amd64:"ROLB\t[$]7" 112 a += x<<7 ^ x>>1 113 114 return a 115 } 116 117 // ----------------------- // 118 // non-const rotates // 119 // ----------------------- // 120 121 func rot64nc(x uint64, z uint) uint64 { 122 var a uint64 123 124 z &= 63 125 126 // amd64:"ROLQ",-"AND" 127 // arm64:"ROR","NEG",-"AND" 128 // ppc64x:"ROTL",-"NEG",-"AND" 129 // loong64: "ROTRV", -"AND" 130 a += x<<z | x>>(64-z) 131 132 // amd64:"RORQ",-"AND" 133 // arm64:"ROR",-"NEG",-"AND" 134 // ppc64x:"ROTL","NEG",-"AND" 135 // loong64: "ROTRV", -"AND" 136 a += x>>z | x<<(64-z) 137 138 return a 139 } 140 141 func rot32nc(x uint32, z uint) uint32 { 142 var a uint32 143 144 z &= 31 145 146 // amd64:"ROLL",-"AND" 147 // arm64:"ROR","NEG",-"AND" 148 // ppc64x:"ROTLW",-"NEG",-"AND" 149 // loong64: "ROTR", -"AND" 150 a += x<<z | x>>(32-z) 151 152 // amd64:"RORL",-"AND" 153 // arm64:"ROR",-"NEG",-"AND" 154 // ppc64x:"ROTLW","NEG",-"AND" 155 // loong64: "ROTR", -"AND" 156 a += x>>z | x<<(32-z) 157 158 return a 159 } 160 161 func rot16nc(x uint16, z uint) uint16 { 162 var a uint16 163 164 z &= 15 165 166 // amd64:"ROLW",-"ANDQ" 167 a += x<<z | x>>(16-z) 168 169 // amd64:"RORW",-"ANDQ" 170 a += x>>z | x<<(16-z) 171 172 return a 173 } 174 175 func rot8nc(x uint8, z uint) uint8 { 176 var a uint8 177 178 z &= 7 179 180 // amd64:"ROLB",-"ANDQ" 181 a += x<<z | x>>(8-z) 182 183 // amd64:"RORB",-"ANDQ" 184 a += x>>z | x<<(8-z) 185 186 return a 187 } 188 189 // Issue 18254: rotate after inlining 190 func f32(x uint32) uint32 { 191 // amd64:"ROLL\t[$]7" 192 return rot32nc(x, 7) 193 } 194 195 func doubleRotate(x uint64) uint64 { 196 x = (x << 5) | (x >> 59) 197 // amd64:"ROLQ\t[$]15" 198 // arm64:"ROR\t[$]49" 199 x = (x << 10) | (x >> 54) 200 return x 201 } 202 203 // --------------------------------------- // 204 // Combined Rotate + Masking operations // 205 // --------------------------------------- // 206 207 func checkMaskedRotate32(a []uint32, r int) { 208 i := 0 209 210 // ppc64x: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+" 211 a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000 212 i++ 213 // ppc64x: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+" 214 a[i] = bits.RotateLeft32(a[i]&0xFF, 16) 215 i++ 216 // ppc64x: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+" 217 a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0 218 i++ 219 // ppc64x: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+" 220 a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16) 221 i++ 222 223 // ppc64x: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+" 224 a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000 225 i++ 226 // ppc64x: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+" 227 a[i] = bits.RotateLeft32(a[i], r) & 0xFF00 228 i++ 229 230 // ppc64x: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+" 231 a[i] = bits.RotateLeft32(a[i], r) & 0xFFF00FFF 232 i++ 233 // ppc64x: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+" 234 a[i] = bits.RotateLeft32(a[i], 4) & 0xFFF00FFF 235 i++ 236 } 237 238 // combined arithmetic and rotate on arm64 239 func checkArithmeticWithRotate(a *[1000]uint64) { 240 // arm64: "AND\tR[0-9]+@>51, R[0-9]+, R[0-9]+" 241 a[2] = a[1] & bits.RotateLeft64(a[0], 13) 242 // arm64: "ORR\tR[0-9]+@>51, R[0-9]+, R[0-9]+" 243 a[5] = a[4] | bits.RotateLeft64(a[3], 13) 244 // arm64: "EOR\tR[0-9]+@>51, R[0-9]+, R[0-9]+" 245 a[8] = a[7] ^ bits.RotateLeft64(a[6], 13) 246 // arm64: "MVN\tR[0-9]+@>51, R[0-9]+" 247 a[10] = ^bits.RotateLeft64(a[9], 13) 248 // arm64: "BIC\tR[0-9]+@>51, R[0-9]+, R[0-9]+" 249 a[13] = a[12] &^ bits.RotateLeft64(a[11], 13) 250 // arm64: "EON\tR[0-9]+@>51, R[0-9]+, R[0-9]+" 251 a[16] = a[15] ^ ^bits.RotateLeft64(a[14], 13) 252 // arm64: "ORN\tR[0-9]+@>51, R[0-9]+, R[0-9]+" 253 a[19] = a[18] | ^bits.RotateLeft64(a[17], 13) 254 // arm64: "TST\tR[0-9]+@>51, R[0-9]+" 255 if a[18]&bits.RotateLeft64(a[19], 13) == 0 { 256 a[20] = 1 257 } 258 259 } 260