add __ctzdi2 to sparc64 kernel
authorjsg <jsg@openbsd.org>
Wed, 14 Dec 2022 23:50:31 +0000 (23:50 +0000)
committerjsg <jsg@openbsd.org>
Wed, 14 Dec 2022 23:50:31 +0000 (23:50 +0000)
If __builtin_ctzl() is used on sparc64, gcc 4.2 will emit a call to
__ctzdi2.  For userland this is in libgcc or compiler-rt.  In the kernel
we put these functions in libkern.

'looks good' deraadt@ miod@

sys/arch/sparc64/conf/files.sparc64
sys/lib/libkern/ctzdi2.c [new file with mode: 0644]

index cfc824e..f49cf0c 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: files.sparc64,v 1.154 2020/08/13 10:04:37 jca Exp $
+#      $OpenBSD: files.sparc64,v 1.155 2022/12/14 23:50:31 jsg Exp $
 #      $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
 
 # maxpartitions must be first item in files.${ARCH}
@@ -341,6 +341,8 @@ file        arch/sparc64/sparc64/db_interface.c     ddb
 file   arch/sparc64/sparc64/db_trace.c         ddb
 file   arch/sparc64/sparc64/db_disasm.c        ddb
 
+file   lib/libkern/ctzdi2.c
+
 #
 # Machine-independent SCSI drivers
 #
diff --git a/sys/lib/libkern/ctzdi2.c b/sys/lib/libkern/ctzdi2.c
new file mode 100644 (file)
index 0000000..495657b
--- /dev/null
@@ -0,0 +1,61 @@
+/*     $OpenBSD: ctzdi2.c,v 1.1 2022/12/14 23:50:31 jsg Exp $  */
+
+/*
+ * Public domain.
+ * Written by Dale Rahn.
+ */
+
+#include <lib/libkern/libkern.h>
+
+/*
+ * ffsl -- vax ffs instruction with long arg
+ */
+
+#ifdef __LP64__
+static int
+ffsl(long mask)
+{
+       int bit;
+       unsigned long r = mask;
+       static const signed char t[16] = {
+               -60, 1, 2, 1,
+                 3, 1, 2, 1,
+                 4, 1, 2, 1,
+                 3, 1, 2, 1
+       };
+
+       bit = 0;
+       if (!(r & 0xffffffff)) {
+               bit += 32;
+               r >>= 32;
+       }
+       if (!(r & 0xffff)) {
+               bit += 16;
+               r >>= 16;
+       }
+       if (!(r & 0xff)) {
+               bit += 8;
+               r >>= 8;
+       }
+       if (!(r & 0xf)) {
+               bit += 4;
+               r >>= 4;
+       }
+
+       return (bit + t[ r & 0xf ]);
+}
+#else
+static int
+ffsl(long mask)
+{
+       return ffs(mask);
+}
+#endif
+
+int
+__ctzdi2(long mask)
+{
+       if (mask == 0)
+               return 0;
+       return ffsl(mask) - 1;
+}