1// asmcheck 2 3// Copyright 2021 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 7package codegen 8 9func andn64(x, y int64) int64 { 10 // amd64/v3:"ANDNQ" 11 return x &^ y 12} 13 14func andn32(x, y int32) int32 { 15 // amd64/v3:"ANDNL" 16 return x &^ y 17} 18 19func blsi64(x int64) int64 { 20 // amd64/v3:"BLSIQ" 21 return x & -x 22} 23 24func blsi32(x int32) int32 { 25 // amd64/v3:"BLSIL" 26 return x & -x 27} 28 29func blsmsk64(x int64) int64 { 30 // amd64/v3:"BLSMSKQ" 31 return x ^ (x - 1) 32} 33 34func blsmsk32(x int32) int32 { 35 // amd64/v3:"BLSMSKL" 36 return x ^ (x - 1) 37} 38 39func blsr64(x int64) int64 { 40 // amd64/v3:"BLSRQ" 41 return x & (x - 1) 42} 43 44func blsr32(x int32) int32 { 45 // amd64/v3:"BLSRL" 46 return x & (x - 1) 47} 48 49func isPowerOfTwo64(x int64) bool { 50 // amd64/v3:"BLSRQ",-"TESTQ",-"CALL" 51 return blsr64(x) == 0 52} 53 54func isPowerOfTwo32(x int32) bool { 55 // amd64/v3:"BLSRL",-"TESTL",-"CALL" 56 return blsr32(x) == 0 57} 58 59func isPowerOfTwoSelect64(x, a, b int64) int64 { 60 var r int64 61 // amd64/v3:"BLSRQ",-"TESTQ",-"CALL" 62 if isPowerOfTwo64(x) { 63 r = a 64 } else { 65 r = b 66 } 67 // amd64/v3:"CMOVQEQ",-"TESTQ",-"CALL" 68 return r * 2 // force return blocks joining 69} 70 71func isPowerOfTwoSelect32(x, a, b int32) int32 { 72 var r int32 73 // amd64/v3:"BLSRL",-"TESTL",-"CALL" 74 if isPowerOfTwo32(x) { 75 r = a 76 } else { 77 r = b 78 } 79 // amd64/v3:"CMOVLEQ",-"TESTL",-"CALL" 80 return r * 2 // force return blocks joining 81} 82 83func isPowerOfTwoBranch64(x int64, a func(bool), b func(string)) { 84 // amd64/v3:"BLSRQ",-"TESTQ",-"CALL" 85 if isPowerOfTwo64(x) { 86 a(true) 87 } else { 88 b("false") 89 } 90} 91 92func isPowerOfTwoBranch32(x int32, a func(bool), b func(string)) { 93 // amd64/v3:"BLSRL",-"TESTL",-"CALL" 94 if isPowerOfTwo32(x) { 95 a(true) 96 } else { 97 b("false") 98 } 99} 100 101func isNotPowerOfTwo64(x int64) bool { 102 // amd64/v3:"BLSRQ",-"TESTQ",-"CALL" 103 return blsr64(x) != 0 104} 105 106func isNotPowerOfTwo32(x int32) bool { 107 // amd64/v3:"BLSRL",-"TESTL",-"CALL" 108 return blsr32(x) != 0 109} 110 111func isNotPowerOfTwoSelect64(x, a, b int64) int64 { 112 var r int64 113 // amd64/v3:"BLSRQ",-"TESTQ",-"CALL" 114 if isNotPowerOfTwo64(x) { 115 r = a 116 } else { 117 r = b 118 } 119 // amd64/v3:"CMOVQNE",-"TESTQ",-"CALL" 120 return r * 2 // force return blocks joining 121} 122 123func isNotPowerOfTwoSelect32(x, a, b int32) int32 { 124 var r int32 125 // amd64/v3:"BLSRL",-"TESTL",-"CALL" 126 if isNotPowerOfTwo32(x) { 127 r = a 128 } else { 129 r = b 130 } 131 // amd64/v3:"CMOVLNE",-"TESTL",-"CALL" 132 return r * 2 // force return blocks joining 133} 134 135func isNotPowerOfTwoBranch64(x int64, a func(bool), b func(string)) { 136 // amd64/v3:"BLSRQ",-"TESTQ",-"CALL" 137 if isNotPowerOfTwo64(x) { 138 a(true) 139 } else { 140 b("false") 141 } 142} 143 144func isNotPowerOfTwoBranch32(x int32, a func(bool), b func(string)) { 145 // amd64/v3:"BLSRL",-"TESTL",-"CALL" 146 if isNotPowerOfTwo32(x) { 147 a(true) 148 } else { 149 b("false") 150 } 151} 152 153func sarx64(x, y int64) int64 { 154 // amd64/v3:"SARXQ" 155 return x >> y 156} 157 158func sarx32(x, y int32) int32 { 159 // amd64/v3:"SARXL" 160 return x >> y 161} 162 163func sarx64_load(x []int64, i int) int64 { 164 // amd64/v3: `SARXQ\t[A-Z]+[0-9]*, \([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\), [A-Z]+[0-9]*` 165 s := x[i] >> (i & 63) 166 // amd64/v3: `SARXQ\t[A-Z]+[0-9]*, 8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\), [A-Z]+[0-9]*` 167 s = x[i+1] >> (s & 63) 168 return s 169} 170 171func sarx32_load(x []int32, i int) int32 { 172 // amd64/v3: `SARXL\t[A-Z]+[0-9]*, \([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\), [A-Z]+[0-9]*` 173 s := x[i] >> (i & 63) 174 // amd64/v3: `SARXL\t[A-Z]+[0-9]*, 4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\), [A-Z]+[0-9]*` 175 s = x[i+1] >> (s & 63) 176 return s 177} 178 179func shlrx64(x, y uint64) uint64 { 180 // amd64/v3:"SHRXQ" 181 s := x >> y 182 // amd64/v3:"SHLXQ" 183 s = s << y 184 return s 185} 186 187func shlrx32(x, y uint32) uint32 { 188 // amd64/v3:"SHRXL" 189 s := x >> y 190 // amd64/v3:"SHLXL" 191 s = s << y 192 return s 193} 194 195func shlrx64_load(x []uint64, i int, s uint64) uint64 { 196 // amd64/v3: `SHRXQ\t[A-Z]+[0-9]*, \([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\), [A-Z]+[0-9]*` 197 s = x[i] >> i 198 // amd64/v3: `SHLXQ\t[A-Z]+[0-9]*, 8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\), [A-Z]+[0-9]*` 199 s = x[i+1] << s 200 return s 201} 202 203func shlrx32_load(x []uint32, i int, s uint32) uint32 { 204 // amd64/v3: `SHRXL\t[A-Z]+[0-9]*, \([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\), [A-Z]+[0-9]*` 205 s = x[i] >> i 206 // amd64/v3: `SHLXL\t[A-Z]+[0-9]*, 4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\), [A-Z]+[0-9]*` 207 s = x[i+1] << s 208 return s 209} 210