com32: add a centralized bitops header
authorH. Peter Anvin <hpa@zytor.com>
Sun, 14 Nov 2010 21:09:48 +0000 (13:09 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sun, 14 Nov 2010 21:09:48 +0000 (13:09 -0800)
Add a centralized bitops header <sys/bitops.h> which uses x86 bitops
instructions.  This is necessary to keep gcc 4.5 from aborting
compilation due to the inlined code being larger than the non-inlined
version, and well, we should really use the bitops.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
com32/gplinclude/cpuid.h
com32/include/sys/bitops.h [new file with mode: 0644]
com32/lib/vsscanf.c

index bc9df17..53a0808 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 #include <cpufeature.h>
+#include <sys/bitops.h>
 #include <sys/cpu.h>
 #include <klibc/compiler.h>
 
@@ -173,11 +174,6 @@ typedef struct {
 #define X86_VENDOR_NUM 9
 #define X86_VENDOR_UNKNOWN 0xff
 
-static inline __purefunc bool test_bit(int nr, const uint32_t * addr)
-{
-    return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
-}
-
 #define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
 
 /*
diff --git a/com32/include/sys/bitops.h b/com32/include/sys/bitops.h
new file mode 100644 (file)
index 0000000..06cf9f3
--- /dev/null
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * bitops.h
+ *
+ * Simple bitwise operations
+ */
+
+#ifndef _BITOPS_H
+#define _BITOPS_H
+
+#include <klibc/compiler.h>
+
+static inline void set_bit(long __bit, void *__bitmap)
+{
+    asm volatile("btsl %1,%0" : "+m" (__bitmap) : "Ir" (__bit) : "memory");
+}
+
+static inline void clr_bit(long __bit, void *__bitmap)
+{
+    asm volatile("btcl %1,%0" : "+m" (__bitmap) : "Ir" (__bit) : "memory");
+}
+
+static inline int __purefunc test_bit(long __bit, const void *__bitmap)
+{
+    unsigned char __r;
+    asm("btl %2,%1; setnz %0"
+       : "=r" (__r)
+       : "m" (__bitmap), "Ir" (__bit));
+    return __r;
+}
+
+#endif /* _BITOPS_H */
index 153dbbd..d9fec51 100644 (file)
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <limits.h>
 #include <stdio.h>
+#include <sys/bitops.h>
 
 #ifndef LONG_BIT
 #define LONG_BIT (CHAR_BIT*sizeof(long))
@@ -46,25 +47,13 @@ enum bail {
     bail_err                   /* Conversion mismatch */
 };
 
-static inline const char *skipspace(const char *p)
+static const char *skipspace(const char *p)
 {
     while (isspace((unsigned char)*p))
        p++;
     return p;
 }
 
-#undef set_bit
-static inline void set_bit(unsigned long *bitmap, unsigned int bit)
-{
-    bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
-}
-
-#undef test_bit
-static inline int test_bit(unsigned long *bitmap, unsigned int bit)
-{
-    return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1;
-}
-
 int vsscanf(const char *buffer, const char *format, va_list ap)
 {
     const char *p = format;
@@ -323,7 +312,7 @@ set_integer:
            if (ch == '^' && !(flags & FL_INV)) {
                matchinv = 1;
            } else {
-               set_bit(matchmap, (unsigned char)ch);
+               set_bit((unsigned char)ch, matchmap);
                state = st_match;
            }
            break;
@@ -335,18 +324,18 @@ set_integer:
                range_start = (unsigned char)ch;
                state = st_match_range;
            } else {
-               set_bit(matchmap, (unsigned char)ch);
+               set_bit((unsigned char)ch, matchmap);
            }
            break;
 
        case st_match_range:    /* %[ match after - */
            if (ch == ']') {
-               set_bit(matchmap, (unsigned char)'-');  /* - was last character */
+               set_bit((unsigned char)'-', matchmap);  /* - was last character */
                goto match_run;
            } else {
                int i;
                for (i = range_start; i < (unsigned char)ch; i++)
-                   set_bit(matchmap, i);
+                   set_bit(i, matchmap);
                state = st_match;
            }
            break;
@@ -354,7 +343,7 @@ set_integer:
 match_run:                     /* Match expression finished */
            qq = q;
            while (width && *q
-                  && test_bit(matchmap, (unsigned char)*q) ^ matchinv) {
+                  && test_bit((unsigned char)*q, matchmap) ^ matchinv) {
                *sarg++ = *q++;
            }
            if (q != qq) {