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@
-# $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}
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
#
--- /dev/null
+/* $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;
+}