github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/runtime/internal/sys/intrinsics_common.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sys 6 7 // Copied from math/bits to avoid dependence. 8 9 const len8tab = "" + 10 "\x00\x01\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04\x04\x04" + 11 "\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05" + 12 "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" + 13 "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" + 14 "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + 15 "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + 16 "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + 17 "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + 18 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 19 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 20 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 21 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 22 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 23 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 24 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + 25 "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" 26 27 // len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0. 28 // 29 // nosplit because this is used in src/runtime/histogram.go, which make run in sensitive contexts. 30 // 31 //go:nosplit 32 func Len64(x uint64) (n int) { 33 if x >= 1<<32 { 34 x >>= 32 35 n = 32 36 } 37 if x >= 1<<16 { 38 x >>= 16 39 n += 16 40 } 41 if x >= 1<<8 { 42 x >>= 8 43 n += 8 44 } 45 return n + int(len8tab[x]) 46 } 47 48 // --- OnesCount --- 49 50 const m0 = 0x5555555555555555 // 01010101 ... 51 const m1 = 0x3333333333333333 // 00110011 ... 52 const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ... 53 54 // OnesCount64 returns the number of one bits ("population count") in x. 55 func OnesCount64(x uint64) int { 56 // Implementation: Parallel summing of adjacent bits. 57 // See "Hacker's Delight", Chap. 5: Counting Bits. 58 // The following pattern shows the general approach: 59 // 60 // x = x>>1&(m0&m) + x&(m0&m) 61 // x = x>>2&(m1&m) + x&(m1&m) 62 // x = x>>4&(m2&m) + x&(m2&m) 63 // x = x>>8&(m3&m) + x&(m3&m) 64 // x = x>>16&(m4&m) + x&(m4&m) 65 // x = x>>32&(m5&m) + x&(m5&m) 66 // return int(x) 67 // 68 // Masking (& operations) can be left away when there's no 69 // danger that a field's sum will carry over into the next 70 // field: Since the result cannot be > 64, 8 bits is enough 71 // and we can ignore the masks for the shifts by 8 and up. 72 // Per "Hacker's Delight", the first line can be simplified 73 // more, but it saves at best one instruction, so we leave 74 // it alone for clarity. 75 const m = 1<<64 - 1 76 x = x>>1&(m0&m) + x&(m0&m) 77 x = x>>2&(m1&m) + x&(m1&m) 78 x = (x>>4 + x) & (m2 & m) 79 x += x >> 8 80 x += x >> 16 81 x += x >> 32 82 return int(x) & (1<<7 - 1) 83 } 84 85 // LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0. 86 func LeadingZeros64(x uint64) int { return 64 - Len64(x) } 87 88 // LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0. 89 func LeadingZeros8(x uint8) int { return 8 - Len8(x) } 90 91 // Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0. 92 func Len8(x uint8) int { 93 return int(len8tab[x]) 94 } 95 96 // Prefetch prefetches data from memory addr to cache 97 // 98 // AMD64: Produce PREFETCHT0 instruction 99 // 100 // ARM64: Produce PRFM instruction with PLDL1KEEP option 101 func Prefetch(addr uintptr) {} 102 103 // PrefetchStreamed prefetches data from memory addr, with a hint that this data is being streamed. 104 // That is, it is likely to be accessed very soon, but only once. If possible, this will avoid polluting the cache. 105 // 106 // AMD64: Produce PREFETCHNTA instruction 107 // 108 // ARM64: Produce PRFM instruction with PLDL1STRM option 109 func PrefetchStreamed(addr uintptr) {}