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: "sve2", Feature: &ARM64.HasSVE2},
    32  		{Name: "crc32", Feature: &ARM64.HasCRC32},
    33  		{Name: "atomics", Feature: &ARM64.HasATOMICS},
    34  		{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
    35  		{Name: "cpuid", Feature: &ARM64.HasCPUID},
    36  		{Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
    37  		{Name: "fcma", Feature: &ARM64.HasFCMA},
    38  		{Name: "dcpop", Feature: &ARM64.HasDCPOP},
    39  		{Name: "asimddp", Feature: &ARM64.HasASIMDDP},
    40  		{Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
    41  		{Name: "dit", Feature: &ARM64.HasDIT},
    42  		{Name: "i8mm", Feature: &ARM64.HasI8MM},
    43  	}
    44  }
    45  
    46  func archInit() {
    47  	switch runtime.GOOS {
    48  	case "freebsd":
    49  		readARM64Registers()
    50  	case "linux", "netbsd", "openbsd":
    51  		doinit()
    52  	default:
    53  		// Many platforms don't seem to allow reading these registers.
    54  		setMinimalFeatures()
    55  	}
    56  }
    57  
    58  // setMinimalFeatures fakes the minimal ARM64 features expected by
    59  // TestARM64minimalFeatures.
    60  func setMinimalFeatures() {
    61  	ARM64.HasASIMD = true
    62  	ARM64.HasFP = true
    63  }
    64  
    65  func readARM64Registers() {
    66  	Initialized = true
    67  
    68  	parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
    69  }
    70  
    71  func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
    72  	// ID_AA64ISAR0_EL1
    73  	switch extractBits(isar0, 4, 7) {
    74  	case 1:
    75  		ARM64.HasAES = true
    76  	case 2:
    77  		ARM64.HasAES = true
    78  		ARM64.HasPMULL = true
    79  	}
    80  
    81  	switch extractBits(isar0, 8, 11) {
    82  	case 1:
    83  		ARM64.HasSHA1 = true
    84  	}
    85  
    86  	switch extractBits(isar0, 12, 15) {
    87  	case 1:
    88  		ARM64.HasSHA2 = true
    89  	case 2:
    90  		ARM64.HasSHA2 = true
    91  		ARM64.HasSHA512 = true
    92  	}
    93  
    94  	switch extractBits(isar0, 16, 19) {
    95  	case 1:
    96  		ARM64.HasCRC32 = true
    97  	}
    98  
    99  	switch extractBits(isar0, 20, 23) {
   100  	case 2:
   101  		ARM64.HasATOMICS = true
   102  	}
   103  
   104  	switch extractBits(isar0, 28, 31) {
   105  	case 1:
   106  		ARM64.HasASIMDRDM = true
   107  	}
   108  
   109  	switch extractBits(isar0, 32, 35) {
   110  	case 1:
   111  		ARM64.HasSHA3 = true
   112  	}
   113  
   114  	switch extractBits(isar0, 36, 39) {
   115  	case 1:
   116  		ARM64.HasSM3 = true
   117  	}
   118  
   119  	switch extractBits(isar0, 40, 43) {
   120  	case 1:
   121  		ARM64.HasSM4 = true
   122  	}
   123  
   124  	switch extractBits(isar0, 44, 47) {
   125  	case 1:
   126  		ARM64.HasASIMDDP = true
   127  	}
   128  
   129  	// ID_AA64ISAR1_EL1
   130  	switch extractBits(isar1, 0, 3) {
   131  	case 1:
   132  		ARM64.HasDCPOP = true
   133  	}
   134  
   135  	switch extractBits(isar1, 12, 15) {
   136  	case 1:
   137  		ARM64.HasJSCVT = true
   138  	}
   139  
   140  	switch extractBits(isar1, 16, 19) {
   141  	case 1:
   142  		ARM64.HasFCMA = true
   143  	}
   144  
   145  	switch extractBits(isar1, 20, 23) {
   146  	case 1:
   147  		ARM64.HasLRCPC = true
   148  	}
   149  
   150  	switch extractBits(isar1, 52, 55) {
   151  	case 1:
   152  		ARM64.HasI8MM = true
   153  	}
   154  
   155  	// ID_AA64PFR0_EL1
   156  	switch extractBits(pfr0, 16, 19) {
   157  	case 0:
   158  		ARM64.HasFP = true
   159  	case 1:
   160  		ARM64.HasFP = true
   161  		ARM64.HasFPHP = true
   162  	}
   163  
   164  	switch extractBits(pfr0, 20, 23) {
   165  	case 0:
   166  		ARM64.HasASIMD = true
   167  	case 1:
   168  		ARM64.HasASIMD = true
   169  		ARM64.HasASIMDHP = true
   170  	}
   171  
   172  	switch extractBits(pfr0, 32, 35) {
   173  	case 1:
   174  		ARM64.HasSVE = true
   175  
   176  		parseARM64SVERegister(getzfr0())
   177  	}
   178  
   179  	switch extractBits(pfr0, 48, 51) {
   180  	case 1:
   181  		ARM64.HasDIT = true
   182  	}
   183  }
   184  
   185  func parseARM64SVERegister(zfr0 uint64) {
   186  	switch extractBits(zfr0, 0, 3) {
   187  	case 1:
   188  		ARM64.HasSVE2 = true
   189  	}
   190  }
   191  
   192  func extractBits(data uint64, start, end uint) uint {
   193  	return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
   194  }
   195  

View as plain text