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 5package runtime 6 7import "internal/cpu" 8 9const ( 10 hwcap_FP = 1 << 0 11 hwcap_ASIMD = 1 << 1 12 hwcap_EVTSTRM = 1 << 2 13 hwcap_AES = 1 << 3 14 hwcap_PMULL = 1 << 4 15 hwcap_SHA1 = 1 << 5 16 hwcap_SHA2 = 1 << 6 17 hwcap_CRC32 = 1 << 7 18 hwcap_ATOMICS = 1 << 8 19 hwcap_FPHP = 1 << 9 20 hwcap_ASIMDHP = 1 << 10 21 hwcap_CPUID = 1 << 11 22 hwcap_ASIMDRDM = 1 << 12 23 hwcap_JSCVT = 1 << 13 24 hwcap_FCMA = 1 << 14 25 hwcap_LRCPC = 1 << 15 26 hwcap_DCPOP = 1 << 16 27 hwcap_SHA3 = 1 << 17 28 hwcap_SM3 = 1 << 18 29 hwcap_SM4 = 1 << 19 30 hwcap_ASIMDDP = 1 << 20 31 hwcap_SHA512 = 1 << 21 32 hwcap_SVE = 1 << 22 33 hwcap_ASIMDFHM = 1 << 23 34) 35 36func getisar0() uint64 37func getisar1() uint64 38func getpfr0() uint64 39 40// no hwcap support on FreeBSD aarch64, we need to retrieve the info from 41// ID_AA64ISAR0_EL1, ID_AA64ISAR1_EL1 and ID_AA64PFR0_EL1 42func archauxv(tag, val uintptr) { 43 var isar0, isar1, pfr0 uint64 44 45 isar0 = getisar0() 46 isar1 = getisar1() 47 pfr0 = getpfr0() 48 49 // ID_AA64ISAR0_EL1 50 switch extractBits(isar0, 4, 7) { 51 case 1: 52 cpu.HWCap |= hwcap_AES 53 case 2: 54 cpu.HWCap |= hwcap_PMULL | hwcap_AES 55 } 56 57 switch extractBits(isar0, 8, 11) { 58 case 1: 59 cpu.HWCap |= hwcap_SHA1 60 } 61 62 switch extractBits(isar0, 12, 15) { 63 case 1: 64 cpu.HWCap |= hwcap_SHA2 65 case 2: 66 cpu.HWCap |= hwcap_SHA2 | hwcap_SHA512 67 } 68 69 switch extractBits(isar0, 16, 19) { 70 case 1: 71 cpu.HWCap |= hwcap_CRC32 72 } 73 74 switch extractBits(isar0, 20, 23) { 75 case 2: 76 cpu.HWCap |= hwcap_ATOMICS 77 } 78 79 switch extractBits(isar0, 28, 31) { 80 case 1: 81 cpu.HWCap |= hwcap_ASIMDRDM 82 } 83 84 switch extractBits(isar0, 32, 35) { 85 case 1: 86 cpu.HWCap |= hwcap_SHA3 87 } 88 89 switch extractBits(isar0, 36, 39) { 90 case 1: 91 cpu.HWCap |= hwcap_SM3 92 } 93 94 switch extractBits(isar0, 40, 43) { 95 case 1: 96 cpu.HWCap |= hwcap_SM4 97 } 98 99 switch extractBits(isar0, 44, 47) { 100 case 1: 101 cpu.HWCap |= hwcap_ASIMDDP 102 } 103 104 // ID_AA64ISAR1_EL1 105 switch extractBits(isar1, 0, 3) { 106 case 1: 107 cpu.HWCap |= hwcap_DCPOP 108 } 109 110 switch extractBits(isar1, 12, 15) { 111 case 1: 112 cpu.HWCap |= hwcap_JSCVT 113 } 114 115 switch extractBits(isar1, 16, 19) { 116 case 1: 117 cpu.HWCap |= hwcap_FCMA 118 } 119 120 switch extractBits(isar1, 20, 23) { 121 case 1: 122 cpu.HWCap |= hwcap_LRCPC 123 } 124 125 // ID_AA64PFR0_EL1 126 switch extractBits(pfr0, 16, 19) { 127 case 0: 128 cpu.HWCap |= hwcap_FP 129 case 1: 130 cpu.HWCap |= hwcap_FP | hwcap_FPHP 131 } 132 133 switch extractBits(pfr0, 20, 23) { 134 case 0: 135 cpu.HWCap |= hwcap_ASIMD 136 case 1: 137 cpu.HWCap |= hwcap_ASIMD | hwcap_ASIMDHP 138 } 139 140 switch extractBits(pfr0, 32, 35) { 141 case 1: 142 cpu.HWCap |= hwcap_SVE 143 } 144} 145 146func extractBits(data uint64, start, end uint) uint { 147 return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) 148} 149 150//go:nosplit 151func cputicks() int64 { 152 // Currently cputicks() is used in blocking profiler and to seed fastrand(). 153 // nanotime() is a poor approximation of CPU ticks that is enough for the profiler. 154 return nanotime() 155} 156