Welcome to mirror list, hosted at ThFree Co, Russian Federation.

aarch64-isa.c « linux « arm « src - github.com/pytorch/cpuinfo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 44a8f4dccc66e2973fe5283c0afefbab2c0d402d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdint.h>

#include <arm/linux/api.h>
#include <cpuinfo/log.h>


void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
	uint32_t features,
	uint32_t features2,
	uint32_t midr,
	const struct cpuinfo_arm_chipset chipset[restrict static 1],
	struct cpuinfo_arm_isa isa[restrict static 1])
{
	if (features & CPUINFO_ARM_LINUX_FEATURE_AES) {
		isa->aes = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_PMULL) {
		isa->pmull = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_SHA1) {
		isa->sha1 = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_SHA2) {
		isa->sha2 = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_CRC32) {
		isa->crc32 = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) {
		isa->atomics = true;
	}

	/*
	 * Some phones ship with an old kernel configuration that doesn't report NEON FP16 compute extension and SQRDMLAH/SQRDMLSH/UQRDMLAH/UQRDMLSH instructions.
	 * Use a MIDR-based heuristic to whitelist processors known to support it:
	 * - Processors with Cortex-A55 cores
	 * - Processors with Cortex-A65 cores
	 * - Processors with Cortex-A75 cores
	 * - Processors with Cortex-A76 cores
	 * - Processors with Cortex-A77 cores
	 * - Processors with Exynos M4 cores
	 * - Processors with Exynos M5 cores
	 * - Neoverse N1 cores
	 * - Neoverse V1 cores
	 * - Neoverse N2 cores
	 */
	if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
		/* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */
		cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions");
	} else {
		const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP;
		switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
			case UINT32_C(0x4100D050): /* Cortex-A55 */
			case UINT32_C(0x4100D060): /* Cortex-A65 */
			case UINT32_C(0x4100D0B0): /* Cortex-A76 */
			case UINT32_C(0x4100D0C0): /* Neoverse N1 */
			case UINT32_C(0x4100D0D0): /* Cortex-A77 */
			case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
			case UINT32_C(0x4100D400): /* Neoverse V1 */
			case UINT32_C(0x4100D490): /* Neoverse N2 */
			case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
			case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
			case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
			case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
			case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
			case UINT32_C(0x53000030): /* Exynos M4 */
			case UINT32_C(0x53000040): /* Exynos M5 */
				isa->fp16arith = true;
				isa->rdm = true;
				break;
			default:
				if ((features & fp16arith_mask) == fp16arith_mask) {
					isa->fp16arith = true;
				} else if (features & CPUINFO_ARM_LINUX_FEATURE_FPHP) {
					cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for scalar operations");
				} else if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDHP) {
					cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for SIMD operations");
				}
				if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) {
					isa->rdm = true;
				}
				break;
		}
	}
	if (features2 & CPUINFO_ARM_LINUX_FEATURE2_I8MM) {
		isa->i8mm = true;
	}

	/*
	 * Many phones ship with an old kernel configuration that doesn't report UDOT/SDOT instructions.
	 * Use a MIDR-based heuristic to whitelist processors known to support it.
	 */
	switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
		case UINT32_C(0x4100D060): /* Cortex-A65 */
		case UINT32_C(0x4100D0B0): /* Cortex-A76 */
		case UINT32_C(0x4100D0C0): /* Neoverse N1 */
		case UINT32_C(0x4100D0D0): /* Cortex-A77 */
		case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
		case UINT32_C(0x4100D400): /* Neoverse V1 */
		case UINT32_C(0x4100D490): /* Neoverse N2 */
		case UINT32_C(0x4100D4A0): /* Neoverse E1 */
		case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
		case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
		case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
		case UINT32_C(0x53000030): /* Exynos-M4 */
		case UINT32_C(0x53000040): /* Exynos-M5 */
			isa->dot = true;
			break;
		case UINT32_C(0x4100D050): /* Cortex A55: revision 1 or later only */
			isa->dot = !!(midr_get_variant(midr) >= 1);
			break;
		case UINT32_C(0x4100D0A0): /* Cortex A75: revision 2 or later only */
			isa->dot = !!(midr_get_variant(midr) >= 2);
			break;
		default:
			if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDDP) {
				isa->dot = true;
			}
			break;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) {
		isa->jscvt = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) {
		isa->jscvt = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_FCMA) {
		isa->fcma = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_SVE) {
		isa->sve = true;
	}
	if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) {
		isa->sve2 = true;
	}
	// SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16 feature flag
	// was added in Linux kernel before the BF16 feature flag, so we check for either.
	if (features2 & (CPUINFO_ARM_LINUX_FEATURE2_BF16 | CPUINFO_ARM_LINUX_FEATURE2_SVEBF16)) {
		isa->bf16 = true;
	}
	if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM) {
		isa->fhm = true;
	}
}