1diff --git a/include/cpuinfo.h b/include/cpuinfo.h
2index 6c67c34..85ce174 100644
3--- a/include/cpuinfo.h
4+++ b/include/cpuinfo.h
5@@ -417,6 +417,8 @@ enum cpuinfo_uarch {
6 	cpuinfo_uarch_cortex_a76   = 0x00300376,
7 	/** ARM Cortex-A77. */
8 	cpuinfo_uarch_cortex_a77   = 0x00300377,
9+	/** ARM Cortex-A78. */
10+	cpuinfo_uarch_cortex_a78   = 0x00300378,
11
12 	/** ARM Neoverse N1. */
13 	cpuinfo_uarch_neoverse_n1  = 0x00300400,
14@@ -1434,6 +1436,7 @@ static inline bool cpuinfo_has_x86_sha(void) {
15 			bool armv6k;
16 			bool armv7;
17 			bool armv7mp;
18+			bool armv8;
19 			bool idiv;
20
21 			bool vfpv2;
22@@ -1521,6 +1524,16 @@ static inline bool cpuinfo_has_arm_v7mp(void) {
23 	#endif
24 }
25
26+static inline bool cpuinfo_has_arm_v8(void) {
27+	#if CPUINFO_ARCH_ARM64
28+		return true;
29+	#elif CPUINFO_ARCH_ARM
30+		return cpuinfo_isa.armv8;
31+	#else
32+		return false;
33+	#endif
34+}
35+
36 static inline bool cpuinfo_has_arm_idiv(void) {
37 	#if CPUINFO_ARCH_ARM64
38 		return true;
39@@ -1645,6 +1658,16 @@ static inline bool cpuinfo_has_arm_neon_fma(void) {
40 	#endif
41 }
42
43+static inline bool cpuinfo_has_arm_neon_v8(void) {
44+	#if CPUINFO_ARCH_ARM64
45+		return true;
46+	#elif CPUINFO_ARCH_ARM
47+		return cpuinfo_isa.neon && cpuinfo_isa.armv8;
48+	#else
49+		return false;
50+	#endif
51+}
52+
53 static inline bool cpuinfo_has_arm_atomics(void) {
54 	#if CPUINFO_ARCH_ARM64
55 		return cpuinfo_isa.atomics;
56diff --git a/src/arm/linux/aarch32-isa.c b/src/arm/linux/aarch32-isa.c
57index 64dd168..41f9972 100644
58--- a/src/arm/linux/aarch32-isa.c
59+++ b/src/arm/linux/aarch32-isa.c
60@@ -43,6 +43,7 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
61 		isa->armv6k  = true;
62 		isa->armv7   = true;
63 		isa->armv7mp = true;
64+		isa->armv8   = true;
65 		isa->thumb  = true;
66 		isa->thumb2 = true;
67 		isa->idiv = true;
68diff --git a/src/arm/mach/init.c b/src/arm/mach/init.c
69index 058cfc2..e912de6 100644
70--- a/src/arm/mach/init.c
71+++ b/src/arm/mach/init.c
72@@ -307,6 +307,7 @@ void cpuinfo_arm_mach_init(void) {
73 		case CPU_TYPE_ARM:
74 			switch (cpu_subtype) {
75 				case CPU_SUBTYPE_ARM_V8:
76+					cpuinfo_isa.armv8 = true;
77 					cpuinfo_isa.aes = true;
78 					cpuinfo_isa.sha1 = true;
79 					cpuinfo_isa.sha2 = true;
80diff --git a/src/arm/midr.h b/src/arm/midr.h
81index 34d7780..2638517 100644
82--- a/src/arm/midr.h
83+++ b/src/arm/midr.h
84@@ -183,6 +183,7 @@ inline static uint32_t midr_score_core(uint32_t midr) {
85 		case UINT32_C(0x51008000): /* Kryo 260 / 280 Gold */
86 		case UINT32_C(0x51002050): /* Kryo Gold */
87 		case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
88+		case UINT32_C(0x4100D410): /* Cortex-A78 */
89 		case UINT32_C(0x4100D0D0): /* Cortex-A77 */
90 		case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
91 		case UINT32_C(0x4100D0B0): /* Cortex-A76 */
92diff --git a/src/arm/uarch.c b/src/arm/uarch.c
93index 55b61df..0d7a7d7 100644
94--- a/src/arm/uarch.c
95+++ b/src/arm/uarch.c
96@@ -91,6 +91,9 @@ void cpuinfo_arm_decode_vendor_uarch(
97 				case 0xD0E: /* Cortex-A76AE */
98 					*uarch = cpuinfo_uarch_cortex_a76;
99 					break;
100+				case 0xD41: /* Cortex-A78 */
101+					*uarch = cpuinfo_uarch_cortex_a78;
102+					break;
103 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
104 				case 0xD4A:
105 					*uarch = cpuinfo_uarch_neoverse_e1;
106diff --git a/tools/cpu-info.c b/tools/cpu-info.c
107index 2759068..429bbfa 100644
108--- a/tools/cpu-info.c
109+++ b/tools/cpu-info.c
110@@ -183,6 +183,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
111 			return "Cortex-A76";
112 		case cpuinfo_uarch_cortex_a77:
113 			return "Cortex-A77";
114+		case cpuinfo_uarch_cortex_a78:
115+			return "Cortex-A78";
116 		case cpuinfo_uarch_scorpion:
117 			return "Scorpion";
118 		case cpuinfo_uarch_krait:
119diff --git a/tools/isa-info.c b/tools/isa-info.c
120index 98ef919..8365846 100644
121--- a/tools/isa-info.c
122+++ b/tools/isa-info.c
123@@ -121,6 +121,7 @@ int main(int argc, char** argv) {
124 		printf("\tARMv6-K: %s\n", cpuinfo_has_arm_v6k() ? "yes" : "no");
125 		printf("\tARMv7: %s\n", cpuinfo_has_arm_v7() ? "yes" : "no");
126 		printf("\tARMv7 MP: %s\n", cpuinfo_has_arm_v7mp() ? "yes" : "no");
127+		printf("\tARMv8: %s\n", cpuinfo_has_arm_v8() ? "yes" : "no");
128 		printf("\tIDIV: %s\n", cpuinfo_has_arm_idiv() ? "yes" : "no");
129
130 	printf("Floating-Point support:\n");
131