Skip to content

Commit cc2a997

Browse files
tongxuetingMQ-mengqing
tongxueting
authored andcommitted
Add limited support for LoongArch
This add basic support for LoongArch. Signed-off-by: Jinyang He <[email protected]> # Rebase pytorch#92
1 parent 8a1772a commit cc2a997

22 files changed

+2412
-9
lines changed

CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ IF(NOT CMAKE_SYSTEM_PROCESSOR)
9595
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
9696
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
9797
ENDIF()
98-
ELSEIF(NOT CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?|armv[5-8].*|aarch64|arm64.*|ARM64.*|riscv(32|64))$")
98+
ELSEIF(NOT CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?|armv[5-8].*|aarch64|arm64.*|ARM64.*|riscv(32|64)|loongarch64)$")
9999
MESSAGE(WARNING
100100
"Target processor architecture \"${CPUINFO_TARGET_PROCESSOR}\" is not supported in cpuinfo. "
101101
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
@@ -224,6 +224,20 @@ IF(CPUINFO_SUPPORTED_PLATFORM)
224224
src/riscv/linux/riscv-hw.c
225225
src/riscv/linux/riscv-isa.c)
226226
ENDIF()
227+
ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(loongarch64)$")
228+
LIST(APPEND CPUINFO_SRCS
229+
src/loongarch/uarch.c
230+
src/loongarch/cache.c)
231+
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
232+
LIST(APPEND CPUINFO_SRCS
233+
src/loongarch/linux/init.c
234+
src/loongarch/linux/cpuinfo.c
235+
src/loongarch/linux/clusters.c
236+
src/loongarch/linux/chipset.c
237+
src/loongarch/linux/cpucfg.c
238+
src/loongarch/linux/hwcap.c
239+
src/loongarch/linux/loongarch64-isa.c)
240+
ENDIF()
227241
ENDIF()
228242

229243
IF(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")

configure.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ def main(args):
6363
"riscv/linux/riscv-isa.c",
6464
]
6565

66+
if build.target.is_loongarch64:
67+
sources += ["loongarch/uarch.c", "loongarch/cache.c"]
68+
if build.target.is_linux:
69+
sources += [
70+
"loongarch/linux/init.c",
71+
"loongarch/linux/cpuinfo.c",
72+
"loongarch/linux/clusters.c",
73+
"loongarch/linux/cpucfg.c",
74+
"loongarch/linux/chipset.c",
75+
"loongarch/linux/hwcap.c",
76+
"loongarch/linux/loongarch64-isa.c",
77+
]
78+
6679
if build.target.is_macos:
6780
sources += ["mach/topology.c"]
6881
if build.target.is_linux or build.target.is_android:

include/cpuinfo-mock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ void CPUINFO_ABI cpuinfo_set_hwcap(uint32_t hwcap);
6262
#if CPUINFO_ARCH_ARM
6363
void CPUINFO_ABI cpuinfo_set_hwcap2(uint64_t hwcap2);
6464
#endif
65+
#if CPUINFO_ARCH_LOONGARCH64
66+
void CPUINFO_ABI cpuinfo_set_hwcap(uint32_t hwcap);
67+
#endif
6568
#endif
6669

6770
#if defined(__ANDROID__)

include/cpuinfo.h

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
#endif
5555
#endif
5656

57+
#if defined(__loongarch64)
58+
#define CPUINFO_ARCH_LOONGARCH64 1
59+
#endif
60+
5761
/* Define other architecture-specific macros as 0 */
5862

5963
#ifndef CPUINFO_ARCH_X86
@@ -96,6 +100,10 @@
96100
#define CPUINFO_ARCH_RISCV64 0
97101
#endif
98102

103+
#ifndef CPUINFO_ARCH_LOONGARCH64
104+
#define CPUINFO_ARCH_LOONGARCH64 0
105+
#endif
106+
99107
#if CPUINFO_ARCH_X86 && defined(_MSC_VER)
100108
#define CPUINFO_ABI __cdecl
101109
#elif CPUINFO_ARCH_X86 && defined(__GNUC__)
@@ -304,6 +312,10 @@ enum cpuinfo_vendor {
304312
* in 1997.
305313
*/
306314
cpuinfo_vendor_dec = 57,
315+
/**
316+
* Loongson. Vendor of LOONGARCH processor microarchitecture.
317+
*/
318+
cpuinfo_vendor_loongson = 58,
307319
};
308320

309321
/**
@@ -601,6 +613,9 @@ enum cpuinfo_uarch {
601613

602614
/** HiSilicon TaiShan v110 (Huawei Kunpeng 920 series processors). */
603615
cpuinfo_uarch_taishan_v110 = 0x00C00100,
616+
617+
/** Loongson LA4 64 (Loongarch3 series processors). */
618+
cpuinfo_uarch_LA464 = 0x00D00100,
604619
};
605620

606621
struct cpuinfo_processor {
@@ -635,6 +650,10 @@ struct cpuinfo_processor {
635650
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
636651
/** APIC ID (unique x86-specific ID of the logical processor) */
637652
uint32_t apic_id;
653+
#endif
654+
#if CPUINFO_ARCH_LOONGARCH64
655+
/** CPUCFG ID (unique loongarch-specific ID of the logical processor) */
656+
uint32_t cpucfg_id;
638657
#endif
639658
struct {
640659
/** Level 1 instruction cache */
@@ -671,6 +690,9 @@ struct cpuinfo_core {
671690
#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
672691
/** Value of Main ID Register (MIDR) for this core */
673692
uint32_t midr;
693+
#elif CPUINFO_ARCH_LOONGARCH64
694+
/** Value of CPUCFG for this core */
695+
uint32_t cpucfg;
674696
#endif
675697
/** Clock rate (non-Turbo) of the core, in Hz */
676698
uint64_t frequency;
@@ -699,6 +721,9 @@ struct cpuinfo_cluster {
699721
#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
700722
/** Value of Main ID Register (MIDR) of the cores in the cluster */
701723
uint32_t midr;
724+
#elif CPUINFO_ARCH_LOONGARCH64
725+
/** Value of CPUCFG for this cores in the cluster */
726+
uint32_t cpucfg;
702727
#endif
703728
/** Clock rate (non-Turbo) of the cores in the cluster, in Hz */
704729
uint64_t frequency;
@@ -732,6 +757,9 @@ struct cpuinfo_uarch_info {
732757
#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
733758
/** Value of Main ID Register (MIDR) for the microarchitecture */
734759
uint32_t midr;
760+
#elif CPUINFO_ARCH_LOONGARCH64
761+
/** Value of CPUCFG for the microarchitecture */
762+
uint32_t cpucfg;
735763
#endif
736764
/** Number of logical processors with the microarchitecture */
737765
uint32_t processor_count;
@@ -2227,6 +2255,132 @@ static inline bool cpuinfo_has_riscv_v(void) {
22272255
#endif
22282256
}
22292257

2258+
#if CPUINFO_ARCH_LOONGARCH64
2259+
/* This structure is not a part of stable API. Use cpuinfo_has_loongarch_* functions instead. */
2260+
struct cpuinfo_loongarch_isa {
2261+
bool cpucfg;
2262+
bool lam;
2263+
bool ual;
2264+
bool fpu;
2265+
bool lsx;
2266+
bool lasx;
2267+
2268+
bool crc32;
2269+
bool complex;
2270+
bool crypto;
2271+
bool lvz;
2272+
bool lbt_x86;
2273+
bool lbt_arm;
2274+
bool lbt_mips;
2275+
};
2276+
2277+
extern struct cpuinfo_loongarch_isa cpuinfo_isa;
2278+
#endif
2279+
2280+
static inline bool cpuinfo_has_loongarch_cpucfg(void) {
2281+
#if CPUINFO_ARCH_LOONGARCH64
2282+
return cpuinfo_isa.cpucfg;
2283+
#else
2284+
return false;
2285+
#endif
2286+
}
2287+
2288+
static inline bool cpuinfo_has_loongarch_lam(void) {
2289+
#if CPUINFO_ARCH_LOONGARCH64
2290+
return cpuinfo_isa.lam;
2291+
#else
2292+
return false;
2293+
#endif
2294+
}
2295+
2296+
static inline bool cpuinfo_has_loongarch_ual(void) {
2297+
#if CPUINFO_ARCH_LOONGARCH64
2298+
return cpuinfo_isa.ual;
2299+
#else
2300+
return false;
2301+
#endif
2302+
}
2303+
2304+
static inline bool cpuinfo_has_loongarch_fpu(void) {
2305+
#if CPUINFO_ARCH_LOONGARCH64
2306+
return cpuinfo_isa.fpu;
2307+
#else
2308+
return false;
2309+
#endif
2310+
}
2311+
2312+
static inline bool cpuinfo_has_loongarch_lsx(void) {
2313+
#if CPUINFO_ARCH_LOONGARCH64
2314+
return cpuinfo_isa.lsx;
2315+
#else
2316+
return false;
2317+
#endif
2318+
}
2319+
2320+
static inline bool cpuinfo_has_loongarch_lasx(void) {
2321+
#if CPUINFO_ARCH_LOONGARCH64
2322+
return cpuinfo_isa.lasx;
2323+
#else
2324+
return false;
2325+
#endif
2326+
}
2327+
2328+
static inline bool cpuinfo_has_loongarch_crc32(void) {
2329+
#if CPUINFO_ARCH_LOONGARCH64
2330+
return cpuinfo_isa.crc32;
2331+
#else
2332+
return false;
2333+
#endif
2334+
}
2335+
2336+
static inline bool cpuinfo_has_loongarch_complex(void) {
2337+
#if CPUINFO_ARCH_LOONGARCH64
2338+
return cpuinfo_isa.complex;
2339+
#else
2340+
return false;
2341+
#endif
2342+
}
2343+
2344+
static inline bool cpuinfo_has_loongarch_crypto(void) {
2345+
#if CPUINFO_ARCH_LOONGARCH64
2346+
return cpuinfo_isa.crypto;
2347+
#else
2348+
return false;
2349+
#endif
2350+
}
2351+
2352+
static inline bool cpuinfo_has_loongarch_lvz(void) {
2353+
#if CPUINFO_ARCH_LOONGARCH64
2354+
return cpuinfo_isa.lvz;
2355+
#else
2356+
return false;
2357+
#endif
2358+
}
2359+
2360+
static inline bool cpuinfo_has_loongarch_lbt_x86(void) {
2361+
#if CPUINFO_ARCH_LOONGARCH64
2362+
return cpuinfo_isa.lbt_x86;
2363+
#else
2364+
return false;
2365+
#endif
2366+
}
2367+
2368+
static inline bool cpuinfo_has_loongarch_lbt_arm(void) {
2369+
#if CPUINFO_ARCH_LOONGARCH64
2370+
return cpuinfo_isa.lbt_arm;
2371+
#else
2372+
return false;
2373+
#endif
2374+
}
2375+
2376+
static inline bool cpuinfo_has_loongarch_lbt_mips(void) {
2377+
#if CPUINFO_ARCH_LOONGARCH64
2378+
return cpuinfo_isa.lbt_mips;
2379+
#else
2380+
return false;
2381+
#endif
2382+
}
2383+
22302384
const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processors(void);
22312385
const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_cores(void);
22322386
const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_clusters(void);

src/api.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ uint32_t cpuinfo_packages_count = 0;
3030
uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max] = {0};
3131
uint32_t cpuinfo_max_cache_size = 0;
3232

33-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
33+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 || CPUINFO_ARCH_LOONGARCH64
3434
struct cpuinfo_uarch_info* cpuinfo_uarchs = NULL;
3535
uint32_t cpuinfo_uarchs_count = 0;
3636
#else
@@ -41,7 +41,7 @@ struct cpuinfo_uarch_info cpuinfo_global_uarch = {cpuinfo_uarch_unknown};
4141
uint32_t cpuinfo_linux_cpu_max = 0;
4242
const struct cpuinfo_processor** cpuinfo_linux_cpu_to_processor_map = NULL;
4343
const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_map = NULL;
44-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
44+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 || CPUINFO_ARCH_LOONGARCH64
4545
const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map = NULL;
4646
#endif
4747
#endif
@@ -78,7 +78,7 @@ const struct cpuinfo_uarch_info* cpuinfo_get_uarchs() {
7878
if (!cpuinfo_is_initialized) {
7979
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs");
8080
}
81-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
81+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 || CPUINFO_ARCH_LOONGARCH64
8282
return cpuinfo_uarchs;
8383
#else
8484
return &cpuinfo_global_uarch;
@@ -129,7 +129,7 @@ const struct cpuinfo_uarch_info* cpuinfo_get_uarch(uint32_t index) {
129129
if (!cpuinfo_is_initialized) {
130130
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarch");
131131
}
132-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
132+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 || CPUINFO_ARCH_LOONGARCH64
133133
if CPUINFO_UNLIKELY (index >= cpuinfo_uarchs_count) {
134134
return NULL;
135135
}
@@ -174,7 +174,7 @@ uint32_t cpuinfo_get_uarchs_count(void) {
174174
if (!cpuinfo_is_initialized) {
175175
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs_count");
176176
}
177-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
177+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 || CPUINFO_ARCH_LOONGARCH64
178178
return cpuinfo_uarchs_count;
179179
#else
180180
return 1;

src/cpuinfo/internal-api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extern CPUINFO_INTERNAL uint32_t cpuinfo_packages_count;
3434
extern CPUINFO_INTERNAL uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max];
3535
extern CPUINFO_INTERNAL uint32_t cpuinfo_max_cache_size;
3636

37-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
37+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 || CPUINFO_ARCH_LOONGARCH64
3838
extern CPUINFO_INTERNAL struct cpuinfo_uarch_info* cpuinfo_uarchs;
3939
extern CPUINFO_INTERNAL uint32_t cpuinfo_uarchs_count;
4040
#else
@@ -61,6 +61,7 @@ CPUINFO_PRIVATE void cpuinfo_arm_mach_init(void);
6161
CPUINFO_PRIVATE void cpuinfo_arm_linux_init(void);
6262
CPUINFO_PRIVATE void cpuinfo_riscv_linux_init(void);
6363
CPUINFO_PRIVATE void cpuinfo_emscripten_init(void);
64+
CPUINFO_PRIVATE void cpuinfo_loongarch_linux_init(void);
6465

6566
CPUINFO_PRIVATE uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor);
6667

src/init.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ bool CPUINFO_ABI cpuinfo_initialize(void) {
5858
}
5959
init_guard = true;
6060
#endif
61+
#elif CPUINFO_ARCH_LOONGARCH64
62+
#if defined(__linux__)
63+
pthread_once(&init_guard, &cpuinfo_loongarch_linux_init);
64+
#else
65+
cpuinfo_log_error("loongarch operating system is not supported in cpuinfo");
66+
#endif
6167
#else
6268
cpuinfo_log_error("processor architecture is not supported in cpuinfo");
6369
#endif

src/linux/processors.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ uint32_t cpuinfo_linux_get_max_possible_processor(uint32_t max_processors_count)
293293
uint32_t max_possible_processor = 0;
294294
if (!cpuinfo_linux_parse_cpulist(
295295
POSSIBLE_CPULIST_FILENAME, max_processor_number_parser, &max_possible_processor)) {
296-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
296+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_LOONGARCH64
297297
cpuinfo_log_error("failed to parse the list of possible processors in %s", POSSIBLE_CPULIST_FILENAME);
298298
#else
299299
cpuinfo_log_warning("failed to parse the list of possible processors in %s", POSSIBLE_CPULIST_FILENAME);
@@ -315,7 +315,7 @@ uint32_t cpuinfo_linux_get_max_present_processor(uint32_t max_processors_count)
315315
uint32_t max_present_processor = 0;
316316
if (!cpuinfo_linux_parse_cpulist(
317317
PRESENT_CPULIST_FILENAME, max_processor_number_parser, &max_present_processor)) {
318-
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
318+
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_LOONGARCH64
319319
cpuinfo_log_error("failed to parse the list of present processors in %s", PRESENT_CPULIST_FILENAME);
320320
#else
321321
cpuinfo_log_warning("failed to parse the list of present processors in %s", PRESENT_CPULIST_FILENAME);

0 commit comments

Comments
 (0)