diff --git a/compiler-rt/lib/scudo/standalone/checksum.cpp b/compiler-rt/lib/scudo/standalone/checksum.cpp index 2c277391a2ec1..efa4055bcbc1e 100644 --- a/compiler-rt/lib/scudo/standalone/checksum.cpp +++ b/compiler-rt/lib/scudo/standalone/checksum.cpp @@ -19,6 +19,8 @@ #else #include #endif +#elif defined(__loongarch__) +#include #endif namespace scudo { @@ -75,6 +77,20 @@ bool hasHardwareCRC32() { return !!(getauxval(AT_HWCAP) & HWCAP_CRC32); #endif // SCUDO_FUCHSIA } +#elif defined(__loongarch__) +// The definition is only pulled in by since glibc 2.38, so +// supply it if missing. +#ifndef HWCAP_LOONGARCH_CRC32 +#define HWCAP_LOONGARCH_CRC32 (1 << 6) +#endif +// Query HWCAP for platform capability, according to *Software Development and +// Build Convention for LoongArch Architectures* v0.1, Section 9.1. +// +// Link: +// https://github.com/loongson/la-softdev-convention/blob/v0.1/la-softdev-convention.adoc#kernel-development +bool hasHardwareCRC32() { + return !!(getauxval(AT_HWCAP) & HWCAP_LOONGARCH_CRC32); +} #else // No hardware CRC32 implemented in Scudo for other architectures. bool hasHardwareCRC32() { return false; } diff --git a/compiler-rt/lib/scudo/standalone/checksum.h b/compiler-rt/lib/scudo/standalone/checksum.h index f8eda81fd9128..32ca372b097f6 100644 --- a/compiler-rt/lib/scudo/standalone/checksum.h +++ b/compiler-rt/lib/scudo/standalone/checksum.h @@ -30,6 +30,10 @@ #include #define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd) #endif +#ifdef __loongarch__ +#include +#define CRC32_INTRINSIC FIRST_32_SECOND_64(__crcc_w_w_w, __crcc_w_d_w) +#endif namespace scudo { diff --git a/compiler-rt/lib/scudo/standalone/crc32_hw.cpp b/compiler-rt/lib/scudo/standalone/crc32_hw.cpp index 73f2ae000c63d..910cf9460313f 100644 --- a/compiler-rt/lib/scudo/standalone/crc32_hw.cpp +++ b/compiler-rt/lib/scudo/standalone/crc32_hw.cpp @@ -17,4 +17,13 @@ u32 computeHardwareCRC32(u32 Crc, uptr Data) { #endif // defined(__CRC32__) || defined(__SSE4_2__) || // defined(__ARM_FEATURE_CRC32) +#if defined(__loongarch__) +u32 computeHardwareCRC32(u32 Crc, uptr Data) { + // The LoongArch CRC intrinsics have the two input arguments swapped, and + // expect them to be signed. + return static_cast( + CRC32_INTRINSIC(static_cast(Data), static_cast(Crc))); +} +#endif // defined(__loongarch__) + } // namespace scudo