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 7package codegen 8 9import "math/bits" 10 11var sval64 [8]int64 12var sval32 [8]int32 13var sval16 [8]int16 14var sval8 [8]int8 15var val64 [8]uint64 16var val32 [8]uint32 17var val16 [8]uint16 18var val8 [8]uint8 19 20// Avoid zero/sign extensions following a load 21// which has extended the value correctly. 22// Note: No tests are done for int8 since 23// an extra extension is usually needed due to 24// no signed byte load. 25 26func set16(x8 int8, u8 *uint8, y8 int8, z8 uint8) { 27 // Truncate not needed, load does sign/zero extend 28 29 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 30 val16[0] = uint16(*u8) 31 32 // AND not needed due to size 33 // ppc64x:-"ANDCC" 34 sval16[1] = 255 & int16(x8+y8) 35 36 // ppc64x:-"ANDCC" 37 val16[1] = 255 & uint16(*u8+z8) 38 39} 40func shiftidx(u8 *uint8, x16 *int16, u16 *uint16) { 41 42 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 43 val16[0] = uint16(sval16[*u8>>2]) 44 45 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 46 sval16[1] = int16(val16[*x16>>1]) 47 48 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 49 val16[1] = uint16(sval16[*u16>>2]) 50 51} 52 53func setnox(x8 int8, u8 *uint8, y8 *int8, z8 *uint8, x16 *int16, u16 *uint16, x32 *int32, u32 *uint32) { 54 55 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 56 val16[0] = uint16(*u8) 57 58 // AND not needed due to size 59 // ppc64x:-"ANDCC" 60 sval16[1] = 255 & int16(x8+*y8) 61 62 // ppc64x:-"ANDCC" 63 val16[1] = 255 & uint16(*u8+*z8) 64 65 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 66 sval32[1] = int32(*x16) 67 68 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 69 val32[0] = uint32(*u8) 70 71 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 72 val32[1] = uint32(*u16) 73 74 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 75 sval64[1] = int64(*x16) 76 77 // ppc64x:-"MOVW\tR\\d+,\\sR\\d+" 78 sval64[2] = int64(*x32) 79 80 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 81 val64[0] = uint64(*u8) 82 83 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 84 val64[1] = uint64(*u16) 85 86 // ppc64x:-"MOVWZ\tR\\d+,\\sR\\d+" 87 val64[2] = uint64(*u32) 88} 89 90func cmp16(u8 *uint8, x32 *int32, u32 *uint32, x64 *int64, u64 *uint64) bool { 91 92 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 93 if uint16(*u8) == val16[0] { 94 return true 95 } 96 97 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 98 if uint16(*u32>>16) == val16[0] { 99 return true 100 } 101 102 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 103 if uint16(*u64>>48) == val16[0] { 104 return true 105 } 106 107 // Verify the truncates are using the correct sign. 108 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 109 if int16(*x32) == sval16[0] { 110 return true 111 } 112 113 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 114 if uint16(*u32) == val16[0] { 115 return true 116 } 117 118 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 119 if int16(*x64) == sval16[0] { 120 return true 121 } 122 123 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 124 if uint16(*u64) == val16[0] { 125 return true 126 } 127 128 return false 129} 130 131func cmp32(u8 *uint8, x16 *int16, u16 *uint16, x64 *int64, u64 *uint64) bool { 132 133 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 134 if uint32(*u8) == val32[0] { 135 return true 136 } 137 138 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 139 if int32(*x16) == sval32[0] { 140 return true 141 } 142 143 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 144 if uint32(*u16) == val32[0] { 145 return true 146 } 147 148 // Verify the truncates are using the correct sign. 149 // ppc64x:-"MOVWZ\tR\\d+,\\sR\\d+" 150 if int32(*x64) == sval32[0] { 151 return true 152 } 153 154 // ppc64x:-"MOVW\tR\\d+,\\sR\\d+" 155 if uint32(*u64) == val32[0] { 156 return true 157 } 158 159 return false 160} 161 162func cmp64(u8 *uint8, x16 *int16, u16 *uint16, x32 *int32, u32 *uint32) bool { 163 164 // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+" 165 if uint64(*u8) == val64[0] { 166 return true 167 } 168 169 // ppc64x:-"MOVH\tR\\d+,\\sR\\d+" 170 if int64(*x16) == sval64[0] { 171 return true 172 } 173 174 // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+" 175 if uint64(*u16) == val64[0] { 176 return true 177 } 178 179 // ppc64x:-"MOVW\tR\\d+,\\sR\\d+" 180 if int64(*x32) == sval64[0] { 181 return true 182 } 183 184 // ppc64x:-"MOVWZ\tR\\d+,\\sR\\d+" 185 if uint64(*u32) == val64[0] { 186 return true 187 } 188 return false 189} 190 191// no unsign extension following 32 bits ops 192 193func noUnsignEXT(t1, t2, t3, t4 uint32, k int64) uint64 { 194 var ret uint64 195 196 // arm64:"RORW",-"MOVWU" 197 ret += uint64(bits.RotateLeft32(t1, 7)) 198 199 // arm64:"MULW",-"MOVWU" 200 ret *= uint64(t1 * t2) 201 202 // arm64:"MNEGW",-"MOVWU" 203 ret += uint64(-t1 * t3) 204 205 // arm64:"UDIVW",-"MOVWU" 206 ret += uint64(t1 / t4) 207 208 // arm64:-"MOVWU" 209 ret += uint64(t2 % t3) 210 211 // arm64:"MSUBW",-"MOVWU" 212 ret += uint64(t1 - t2*t3) 213 214 // arm64:"MADDW",-"MOVWU" 215 ret += uint64(t3*t4 + t2) 216 217 // arm64:"REVW",-"MOVWU" 218 ret += uint64(bits.ReverseBytes32(t1)) 219 220 // arm64:"RBITW",-"MOVWU" 221 ret += uint64(bits.Reverse32(t1)) 222 223 // arm64:"CLZW",-"MOVWU" 224 ret += uint64(bits.LeadingZeros32(t1)) 225 226 // arm64:"REV16W",-"MOVWU" 227 ret += uint64(((t1 & 0xff00ff00) >> 8) | ((t1 & 0x00ff00ff) << 8)) 228 229 // arm64:"EXTRW",-"MOVWU" 230 ret += uint64((t1 << 25) | (t2 >> 7)) 231 232 return ret 233} 234 235// no sign extension when the upper bits of the result are zero 236 237func noSignEXT(x int) int64 { 238 t1 := int32(x) 239 240 var ret int64 241 242 // arm64:-"MOVW" 243 ret += int64(t1 & 1) 244 245 // arm64:-"MOVW" 246 ret += int64(int32(x & 0x7fffffff)) 247 248 // arm64:-"MOVH" 249 ret += int64(int16(x & 0x7fff)) 250 251 // arm64:-"MOVB" 252 ret += int64(int8(x & 0x7f)) 253 254 return ret 255} 256 257// corner cases that sign extension must not be omitted 258 259func shouldSignEXT(x int) int64 { 260 t1 := int32(x) 261 262 var ret int64 263 264 // arm64:"MOVW" 265 ret += int64(t1 & (-1)) 266 267 // arm64:"MOVW" 268 ret += int64(int32(x & 0x80000000)) 269 270 // arm64:"MOVW" 271 ret += int64(int32(x & 0x1100000011111111)) 272 273 // arm64:"MOVH" 274 ret += int64(int16(x & 0x1100000000001111)) 275 276 // arm64:"MOVB" 277 ret += int64(int8(x & 0x1100000000000011)) 278 279 return ret 280} 281 282func noIntermediateExtension(a, b, c uint32) uint32 { 283 // arm64:-"MOVWU" 284 return a*b*9 + c 285} 286