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