diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-11-14 13:09:48 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-11-14 13:09:48 -0800 |
commit | db74cf6c4182f40ecf7fad1f04799d09d82f896d (patch) | |
tree | 489451b230b21ffd410107dab91b7037a2e5af4f /com32 | |
parent | dd0a971cb6315a5f30c8d378a92f8db9f7ed4eb0 (diff) | |
download | syslinux-db74cf6c4182f40ecf7fad1f04799d09d82f896d.tar.gz syslinux-db74cf6c4182f40ecf7fad1f04799d09d82f896d.tar.xz syslinux-db74cf6c4182f40ecf7fad1f04799d09d82f896d.zip |
com32: add a centralized bitops header
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>
Diffstat (limited to 'com32')
-rw-r--r-- | com32/gplinclude/cpuid.h | 6 | ||||
-rw-r--r-- | com32/include/sys/bitops.h | 58 | ||||
-rw-r--r-- | com32/lib/vsscanf.c | 25 |
3 files changed, 66 insertions, 23 deletions
diff --git a/com32/gplinclude/cpuid.h b/com32/gplinclude/cpuid.h index bc9df171..53a08085 100644 --- a/com32/gplinclude/cpuid.h +++ b/com32/gplinclude/cpuid.h @@ -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 index 00000000..06cf9f3e --- /dev/null +++ b/com32/include/sys/bitops.h @@ -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 */ diff --git a/com32/lib/vsscanf.c b/com32/lib/vsscanf.c index 153dbbdd..d9fec51c 100644 --- a/com32/lib/vsscanf.c +++ b/com32/lib/vsscanf.c @@ -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) { |