Source file src/vendor/golang.org/x/sys/cpu/cpu_arm64.go

     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 cpu
     6  
     7  import "runtime"
     8  
     9  // cacheLineSize is used to prevent false sharing of cache lines.
    10  // We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
    11  // It doesn't cost much and is much more future-proof.
    12  const cacheLineSize = 128
    13  
    14  func initOptions() {
    15  	options = []option{
    16  		{Name: "fp", Feature: &ARM64.HasFP},
    17  		{Name: "asimd", Feature: &ARM64.HasASIMD},
    18  		{Name: "evstrm", Feature: &ARM64.HasEVTSTRM},
    19  		{Name: "aes", Feature: &ARM64.HasAES},
    20  		{Name: "fphp", Feature: &ARM64.HasFPHP},
    21  		{Name: "jscvt", Feature: &ARM64.HasJSCVT},
    22  		{Name: "lrcpc", Feature: &ARM64.HasLRCPC},
    23  		{Name: "pmull", Feature: &ARM64.HasPMULL},
    24  		{Name: "sha1", Feature: &ARM64.HasSHA1},
    25  		{Name: "sha2", Feature: &ARM64.HasSHA2},
    26  		{Name: "sha3", Feature: &ARM64.HasSHA3},
    27  		{Name: "sha512", Feature: &ARM64.HasSHA512},
    28  		{Name: "sm3", Feature: &ARM64.HasSM3},
    29  		{Name: "sm4", Feature: &ARM64.HasSM4},
    30  		{Name: "sve", Feature: &ARM64.HasSVE},
    31  		{Name: "crc32", Feature: &ARM64.HasCRC32},
    32  		{Name: "atomics", Feature: &ARM64.HasATOMICS},
    33  		{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
    34  		{Name: "cpuid", Feature: &ARM64.HasCPUID},
    35  		{Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
    36  		{Name: "fcma", Feature: &ARM64.HasFCMA},
    37  		{Name: "dcpop", Feature: &ARM64.HasDCPOP},
    38  		{Name: "asimddp", Feature: &ARM64.HasASIMDDP},
    39  		{Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
    40  	}
    41  }
    42  
    43  func archInit() {
    44  	switch runtime.GOOS {
    45  	case "freebsd":
    46  		readARM64Registers()
    47  	case "linux", "netbsd", "openbsd":
    48  		doinit()
    49  	default:
    50  		// Many platforms don't seem to allow reading these registers.
    51  		setMinimalFeatures()
    52  	}
    53  }
    54  
    55  // setMinimalFeatures fakes the minimal ARM64 features expected by
    56  // TestARM64minimalFeatures.
    57  func setMinimalFeatures() {
    58  	ARM64.HasASIMD = true
    59  	ARM64.HasFP = true
    60  }
    61  
    62  func readARM64Registers() {
    63  	Initialized = true
    64  
    65  	parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
    66  }
    67  
    68  func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
    69  	// ID_AA64ISAR0_EL1
    70  	switch extractBits(isar0, 4, 7) {
    71  	case 1:
    72  		ARM64.HasAES = true
    73  	case 2:
    74  		ARM64.HasAES = true
    75  		ARM64.HasPMULL = true
    76  	}
    77  
    78  	switch extractBits(isar0, 8, 11) {
    79  	case 1:
    80  		ARM64.HasSHA1 = true
    81  	}
    82  
    83  	switch extractBits(isar0, 12, 15) {
    84  	case 1:
    85  		ARM64.HasSHA2 = true
    86  	case 2:
    87  		ARM64.HasSHA2 = true
    88  		ARM64.HasSHA512 = true
    89  	}
    90  
    91  	switch extractBits(isar0, 16, 19) {
    92  	case 1:
    93  		ARM64.HasCRC32 = true
    94  	}
    95  
    96  	switch extractBits(isar0, 20, 23) {
    97  	case 2:
    98  		ARM64.HasATOMICS = true
    99  	}
   100  
   101  	switch extractBits(isar0, 28, 31) {
   102  	case 1:
   103  		ARM64.HasASIMDRDM = true
   104  	}
   105  
   106  	switch extractBits(isar0, 32, 35) {
   107  	case 1:
   108  		ARM64.HasSHA3 = true
   109  	}
   110  
   111  	switch extractBits(isar0, 36, 39) {
   112  	case 1:
   113  		ARM64.HasSM3 = true
   114  	}
   115  
   116  	switch extractBits(isar0, 40, 43) {
   117  	case 1:
   118  		ARM64.HasSM4 = true
   119  	}
   120  
   121  	switch extractBits(isar0, 44, 47) {
   122  	case 1:
   123  		ARM64.HasASIMDDP = true
   124  	}
   125  
   126  	// ID_AA64ISAR1_EL1
   127  	switch extractBits(isar1, 0, 3) {
   128  	case 1:
   129  		ARM64.HasDCPOP = true
   130  	}
   131  
   132  	switch extractBits(isar1, 12, 15) {
   133  	case 1:
   134  		ARM64.HasJSCVT = true
   135  	}
   136  
   137  	switch extractBits(isar1, 16, 19) {
   138  	case 1:
   139  		ARM64.HasFCMA = true
   140  	}
   141  
   142  	switch extractBits(isar1, 20, 23) {
   143  	case 1:
   144  		ARM64.HasLRCPC = true
   145  	}
   146  
   147  	// ID_AA64PFR0_EL1
   148  	switch extractBits(pfr0, 16, 19) {
   149  	case 0:
   150  		ARM64.HasFP = true
   151  	case 1:
   152  		ARM64.HasFP = true
   153  		ARM64.HasFPHP = true
   154  	}
   155  
   156  	switch extractBits(pfr0, 20, 23) {
   157  	case 0:
   158  		ARM64.HasASIMD = true
   159  	case 1:
   160  		ARM64.HasASIMD = true
   161  		ARM64.HasASIMDHP = true
   162  	}
   163  
   164  	switch extractBits(pfr0, 32, 35) {
   165  	case 1:
   166  		ARM64.HasSVE = true
   167  	}
   168  }
   169  
   170  func extractBits(data uint64, start, end uint) uint {
   171  	return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
   172  }
   173  

View as plain text