Skip to content

Instantly share code, notes, and snippets.

@colemancda
Last active November 3, 2022 07:36
Show Gist options
  • Save colemancda/252c3c30d7c9dd1e9ea574d1063a8b39 to your computer and use it in GitHub Desktop.
Save colemancda/252c3c30d7c9dd1e9ea574d1063a8b39 to your computer and use it in GitHub Desktop.
Swift 5.7 StdLib patches for RISCV64
From a2e3e205250b3f0eddf06e5b0bc3c45231b85350 Mon Sep 17 00:00:00 2001
From: Alsey Coleman Miller <alseycmiller@gmail.com>
Date: Thu, 3 Nov 2022 00:27:15 -0700
Subject: [PATCH 1/1] [stdlib] Add RISCV64 support
---
CMakeLists.txt | 2 ++
cmake/modules/SwiftConfigureSDK.cmake | 2 +-
cmake/modules/SwiftSetIfArchBitness.cmake | 3 ++-
lib/Basic/LangOptions.cpp | 5 +++++
stdlib/cmake/modules/SwiftSource.cmake | 4 ++++
stdlib/public/core/AtomicInt.swift.gyb | 8 ++++----
stdlib/public/runtime/HeapObject.cpp | 2 +-
stdlib/public/stubs/MathStubs.cpp | 1 +
test/ClangImporter/ctypes_parse.swift | 2 +-
.../clang-importer-sdk/swift-modules/CoreFoundation.swift | 2 +-
.../clang-importer-sdk/swift-modules/CoreGraphics.swift | 2 +-
test/Interpreter/builtin_bridge_object.swift | 6 ++++++
test/stdlib/Inputs/FloatingPointConversion.swift.gyb | 2 +-
test/stdlib/Runtime.swift.gyb | 4 ++--
test/stdlib/UnsafePointer.swift.gyb | 4 ++--
validation-test/stdlib/Bitset.swift | 4 ++--
validation-test/stdlib/FixedPoint.swift.gyb | 8 ++++----
.../stdlib/Prototypes/PersistentVector.swift.gyb | 2 +-
18 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 06e1f3f94b9..cb12d4a0814 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -766,6 +766,8 @@ else()
set(SWIFT_HOST_VARIANT_ARCH_default "i686")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "wasm32")
set(SWIFT_HOST_VARIANT_ARCH_default "wasm32")
+ elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "riscv64")
+ set(SWIFT_HOST_VARIANT_ARCH_default "riscv64")
else()
message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake
index 8af84ce5309..967326b0bd3 100644
--- a/cmake/modules/SwiftConfigureSDK.cmake
+++ b/cmake/modules/SwiftConfigureSDK.cmake
@@ -323,7 +323,7 @@ macro(configure_sdk_unix name architectures)
set(SWIFT_SDK_LINUX_ARCH_${arch}_TRIPLE "${arch}-unknown-linux-gnueabi")
elseif(arch MATCHES "(armv6|armv7)")
set(SWIFT_SDK_LINUX_ARCH_${arch}_TRIPLE "${arch}-unknown-linux-gnueabihf")
- elseif(arch MATCHES "(aarch64|i686|powerpc|powerpc64|powerpc64le|s390x|x86_64)")
+ elseif(arch MATCHES "(aarch64|i686|powerpc|powerpc64|powerpc64le|s390x|x86_64|riscv64)")
set(SWIFT_SDK_LINUX_ARCH_${arch}_TRIPLE "${arch}-unknown-linux-gnu")
else()
message(FATAL_ERROR "unknown arch for ${prefix}: ${arch}")
diff --git a/cmake/modules/SwiftSetIfArchBitness.cmake b/cmake/modules/SwiftSetIfArchBitness.cmake
index b7f20af5f02..9038302669e 100644
--- a/cmake/modules/SwiftSetIfArchBitness.cmake
+++ b/cmake/modules/SwiftSetIfArchBitness.cmake
@@ -25,7 +25,8 @@ function(set_if_arch_bitness var_name)
"${SIA_ARCH}" STREQUAL "aarch64" OR
"${SIA_ARCH}" STREQUAL "powerpc64" OR
"${SIA_ARCH}" STREQUAL "powerpc64le" OR
- "${SIA_ARCH}" STREQUAL "s390x")
+ "${SIA_ARCH}" STREQUAL "s390x" OR
+ "${SIA_ARCH}" STREQUAL "riscv64")
set("${var_name}" "${SIA_CASE_64_BIT}" PARENT_SCOPE)
else()
message(FATAL_ERROR "Unknown architecture: ${SIA_ARCH}")
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index 0b30ccfac9b..c8280b39712 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -67,6 +67,7 @@ static const SupportedConditionalValue SupportedConditionalCompilationArches[] =
"powerpc64le",
"s390x",
"wasm32",
+ "riscv64",
};
static const SupportedConditionalValue SupportedConditionalCompilationEndianness[] = {
@@ -334,6 +335,9 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
case llvm::Triple::ArchType::wasm32:
addPlatformConditionValue(PlatformConditionKind::Arch, "wasm32");
break;
+ case llvm::Triple::ArchType::riscv64:
+ addPlatformConditionValue(PlatformConditionKind::Arch, "riscv64");
+ break;
default:
UnsupportedArch = true;
}
@@ -352,6 +356,7 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
case llvm::Triple::ArchType::wasm32:
case llvm::Triple::ArchType::x86:
case llvm::Triple::ArchType::x86_64:
+ case llvm::Triple::ArchType::riscv64:
addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
case llvm::Triple::ArchType::ppc64:
diff --git a/stdlib/cmake/modules/SwiftSource.cmake b/stdlib/cmake/modules/SwiftSource.cmake
index ca1f0077c30..b56d16a0bd8 100644
--- a/stdlib/cmake/modules/SwiftSource.cmake
+++ b/stdlib/cmake/modules/SwiftSource.cmake
@@ -548,6 +548,10 @@ function(_compile_swift_files
list(APPEND swift_flags ${SWIFT_STDLIB_EXTRA_SWIFT_COMPILE_FLAGS})
+ if(CFLAGS_ARCH STREQUAL "riscv64")
+ list(APPEND swift_flags "-Xcc" "-mno-relax" "-Xcc" "-mabi=lp64d" "-Xcc" "-march=rv64imafd")
+ endif()
+
list(APPEND swift_flags ${SWIFT_EXPERIMENTAL_EXTRA_FLAGS})
if(SWIFTFILE_OPT_FLAGS)
diff --git a/stdlib/public/core/AtomicInt.swift.gyb b/stdlib/public/core/AtomicInt.swift.gyb
index 56fed2cb117..e367a62cc52 100644
--- a/stdlib/public/core/AtomicInt.swift.gyb
+++ b/stdlib/public/core/AtomicInt.swift.gyb
@@ -68,7 +68,7 @@ internal func _swift_stdlib_atomicCompareExchangeStrongInt(
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
target._rawValue, expected.pointee._value, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
target._rawValue, expected.pointee._value, desired._value)
#endif
@@ -85,7 +85,7 @@ func _swift_stdlib_atomicLoadInt(
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
return Int(value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
return Int(value)
#endif
@@ -97,7 +97,7 @@ internal func _swift_stdlib_atomicStoreInt(
desired: Int) {
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
#endif
}
@@ -115,7 +115,7 @@ func _swift_stdlib_atomicFetch${operation}Int(
let value = _swift_stdlib_atomicFetch${operation}Int32(
object: rawTarget.assumingMemoryBound(to: Int32.self),
operand: Int32(operand))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
let value = _swift_stdlib_atomicFetch${operation}Int64(
object: rawTarget.assumingMemoryBound(to: Int64.self),
operand: Int64(operand))
diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp
index 32f5b6aaf30..87fc4c53df3 100644
--- a/stdlib/public/runtime/HeapObject.cpp
+++ b/stdlib/public/runtime/HeapObject.cpp
@@ -71,7 +71,7 @@ static inline bool isValidPointerForNativeRetain(const void *p) {
// Check the top of the second byte instead, since Android AArch64 reserves
// the top byte for its own pointer tagging since Android 11.
return (intptr_t)((uintptr_t)p << 8) > 0;
-#elif defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__s390x__) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__))
+#elif defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__))
// On these platforms, except s390x, the upper half of address space is reserved for the
// kernel, so we can assume that pointer values in this range are invalid.
// On s390x it is theoretically possible to have high bit set but in practice
diff --git a/stdlib/public/stubs/MathStubs.cpp b/stdlib/public/stubs/MathStubs.cpp
index 72b05a1f6bf..211100c70e1 100644
--- a/stdlib/public/stubs/MathStubs.cpp
+++ b/stdlib/public/stubs/MathStubs.cpp
@@ -64,6 +64,7 @@ extern "C" {
(defined(__linux__) && defined(__aarch64__)) || \
(defined(__linux__) && defined(__powerpc64__)) || \
(defined(__linux__) && defined(__s390x__)) || \
+ (defined(__linux__) && defined(__riscv) && __riscv_xlen == 64) || \
(defined(__ANDROID__) && defined(__aarch64__))
SWIFT_RUNTIME_STDLIB_API
diff --git a/test/ClangImporter/ctypes_parse.swift b/test/ClangImporter/ctypes_parse.swift
index 6dd8fa9539f..644ed597088 100644
--- a/test/ClangImporter/ctypes_parse.swift
+++ b/test/ClangImporter/ctypes_parse.swift
@@ -39,7 +39,7 @@ func testAnonEnum() {
verifyIsInt(&a)
#elseif arch(i386) || arch(arm) || arch(arm64_32)
verifyIsUInt64(&a)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
verifyIsUInt(&a)
#endif
}
diff --git a/test/Inputs/clang-importer-sdk/swift-modules/CoreFoundation.swift b/test/Inputs/clang-importer-sdk/swift-modules/CoreFoundation.swift
index eeeb043da13..3ba0fae3875 100644
--- a/test/Inputs/clang-importer-sdk/swift-modules/CoreFoundation.swift
+++ b/test/Inputs/clang-importer-sdk/swift-modules/CoreFoundation.swift
@@ -6,7 +6,7 @@ protocol _CFObject: Hashable {}
public struct CGFloat {
#if arch(i386) || arch(arm) || arch(arm64_32)
public typealias UnderlyingType = Float
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
public typealias UnderlyingType = Double
#endif
diff --git a/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift b/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
index 30a49170d2e..23a0438ba85 100644
--- a/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+++ b/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
@@ -9,7 +9,7 @@ public func == (lhs: CGPoint, rhs: CGPoint) -> Bool {
public struct CGFloat {
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
public typealias UnderlyingType = Float
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
public typealias UnderlyingType = Double
#endif
diff --git a/test/Interpreter/builtin_bridge_object.swift b/test/Interpreter/builtin_bridge_object.swift
index 3c473b06d95..aec5bd9b6a5 100644
--- a/test/Interpreter/builtin_bridge_object.swift
+++ b/test/Interpreter/builtin_bridge_object.swift
@@ -43,6 +43,12 @@ let OBJC_TAGGED_POINTER_BITS: UInt = 0
let NATIVE_SPARE_BITS: UInt = 0x0000_0000_0000_0007
let OBJC_TAGGED_POINTER_BITS: UInt = 0
+#elseif arch(riscv64)
+
+// We have no ObjC tagged pointers, and three low spare bits due to alignment.
+let NATIVE_SPARE_BITS: UInt = 0x0000_0000_0000_0007
+let OBJC_TAGGED_POINTER_BITS: UInt = 0
+
#endif
func bitPattern(_ x: Builtin.BridgeObject) -> UInt {
diff --git a/test/stdlib/Inputs/FloatingPointConversion.swift.gyb b/test/stdlib/Inputs/FloatingPointConversion.swift.gyb
index 433c2327338..6d712145db4 100644
--- a/test/stdlib/Inputs/FloatingPointConversion.swift.gyb
+++ b/test/stdlib/Inputs/FloatingPointConversion.swift.gyb
@@ -136,7 +136,7 @@ FloatingPointConversionFailures.test("${OtherFloat}To${Self}Conversion/AlwaysSuc
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
% int_types = all_integer_types(32)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
% int_types = all_integer_types(64)
#else
_UnimplementedError()
diff --git a/test/stdlib/Runtime.swift.gyb b/test/stdlib/Runtime.swift.gyb
index eda30383b33..fee028a559d 100644
--- a/test/stdlib/Runtime.swift.gyb
+++ b/test/stdlib/Runtime.swift.gyb
@@ -688,7 +688,7 @@ var BitTwiddlingTestSuite = TestSuite("BitTwiddling")
BitTwiddlingTestSuite.test("_pointerSize") {
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
expectEqual(4, MemoryLayout<Optional<AnyObject>>.size)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
expectEqual(8, MemoryLayout<Optional<AnyObject>>.size)
#else
fatalError("implement")
@@ -712,7 +712,7 @@ BitTwiddlingTestSuite.test("_isPowerOf2/Int") {
expectTrue(_isPowerOf2(asInt(1024)))
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
// Not applicable to 32-bit architectures.
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
expectTrue(_isPowerOf2(asInt(0x8000_0000)))
#else
fatalError("implement")
diff --git a/test/stdlib/UnsafePointer.swift.gyb b/test/stdlib/UnsafePointer.swift.gyb
index eb24e850589..64e707b5596 100644
--- a/test/stdlib/UnsafePointer.swift.gyb
+++ b/test/stdlib/UnsafePointer.swift.gyb
@@ -409,7 +409,7 @@ ${SelfName}TestSuite.test("customMirror") {
expectEqual(1, mirror.children.count)
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
expectEqual("18446744071562067968", String(describing: mirror.children.first!.1))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
expectEqual("9223372036854775808", String(describing: mirror.children.first!.1))
#else
fatalError("Unimplemented")
@@ -424,7 +424,7 @@ ${SelfName}TestSuite.test("customPlaygroundQuickLook") {
if case let .text(desc) = ptr.customPlaygroundQuickLook {
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
expectEqual("${SelfName}(0xFFFFFFFF80000000)", desc)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
expectEqual("${SelfName}(0x8000000000000000)", desc)
#else
fatalError("Unimplemented")
diff --git a/validation-test/stdlib/Bitset.swift b/validation-test/stdlib/Bitset.swift
index ba5cbed4771..8e387722385 100644
--- a/validation-test/stdlib/Bitset.swift
+++ b/validation-test/stdlib/Bitset.swift
@@ -20,7 +20,7 @@ BitsetTests.test("_UnsafeBitset.wordCount(forCapacity:)") {
for i in 97...128 {
expectEqual(4, _UnsafeBitset.wordCount(forCapacity: i), "i=\(i)")
}
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
for i in 1...64 {
expectEqual(1, _UnsafeBitset.wordCount(forCapacity: i), "i=\(i)")
}
@@ -57,7 +57,7 @@ BitsetTests.test("_UnsafeBitset.split(_:)") {
expectEqual(3, comps.word, "i=\(i)")
expectEqual(i - 96, comps.bit, "i=\(i)")
}
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
for i in 0...63 {
let comps = _UnsafeBitset.split(i)
expectEqual(0, comps.word, "i=\(i)")
diff --git a/validation-test/stdlib/FixedPoint.swift.gyb b/validation-test/stdlib/FixedPoint.swift.gyb
index effeb100601..7ae8bd49fc4 100644
--- a/validation-test/stdlib/FixedPoint.swift.gyb
+++ b/validation-test/stdlib/FixedPoint.swift.gyb
@@ -70,7 +70,7 @@ FixedPoint.test("Integers.Stride") {
expectEqualType(Int.self, ${Self}.Stride.self)
% end
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
% for self_ty in all_integer_types(64):
% Self = self_ty.stdlib_name
@@ -139,7 +139,7 @@ FixedPoint.test("${Dst}(truncatingIfNeeded:) from ${Src}(${bit_pattern})") {
test_bit_patterns=test_bit_patterns,
word_bits=32)}
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
${gyb.execute_template(
truncating_bit_pattern_test_template,
@@ -211,7 +211,7 @@ FixedPoint.test("${Dst}(bitPattern:) from ${Src}(${bit_pattern})") {
test_bit_patterns=test_bit_patterns,
word_bits=32)}
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
${gyb.execute_template(
bit_pattern_test_template,
@@ -276,7 +276,7 @@ FixedPoint.test("${Self}.hash(into:)") {
test_bit_patterns=test_bit_patterns,
word_bits=32)}
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
${gyb.execute_template(
hash_value_test_template,
diff --git a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
index 9432e15066b..8a68e4a3234 100644
--- a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
+++ b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
@@ -195,7 +195,7 @@ struct _${name}Bitmap {
% if underlyingType == 'UInt':
#if arch(i386) || arch(arm) || arch(arm64_32)
return Int(Builtin.int_ctpop_Int32(_bits._value))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) || arch(riscv64)
return Int(Builtin.int_ctpop_Int64(_bits._value))
#endif
% elif underlyingType == 'UInt32':
--
2.30.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment