source: release/1.9/source/lisp-kernel/bits.h @ 16083

Last change on this file since 16083 was 15160, checked in by rme, 7 years ago

In the definition of current_stack_pointer(), use
different inline asm for the x86 targets.

This works around a bug in the llvm-gcc that Apple
ships with Xcode 4.2.1 (and maybe earlier versions).
When compiling with -g without -O, the previous inline
asm is miscompiled.

On my 10.7.2 system with Xcode 4.2.1, /usr/bin/cc
is a link to llvm-gcc. cc --verison reports:
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based
on Apple Inc. build 5658) (LLVM build 2336.1.00)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1/*
2   Copyright (C) 2009 Clozure Associates
3   Copyright (C) 1994-2001 Digitool, Inc
4   This file is part of Clozure CL. 
5
6   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
7   License , known as the LLGPL and distributed with Clozure CL as the
8   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
9   which is distributed with Clozure CL as the file "LGPL".  Where these
10   conflict, the preamble takes precedence. 
11
12   Clozure CL is referenced in the preamble as the "LIBRARY."
13
14   The LLGPL is also available online at
15   http://opensource.franz.com/preamble.html
16*/
17
18
19
20#ifndef __bits_h__
21#define __bits_h__ 1
22
23#include <string.h>
24
25typedef natural *bitvector;
26
27#if WORD_SIZE == 64
28#define bitmap_shift 6
29#define BIT0_MASK 0x8000000000000000ULL
30#define ALL_ONES  0xffffffffffffffffULL
31#define NATURAL1 1ULL
32#else
33#define bitmap_shift 5
34#define BIT0_MASK 0x80000000U
35#define ALL_ONES  0xFFFFFFFFU
36#define NATURAL1 1U
37#endif
38
39#define bitmap_shift_count_mask ((1<<bitmap_shift)-1)
40
41static inline int
42set_bit(bitvector bits,natural bitnum)  __attribute__((always_inline));
43
44static inline int
45set_bit(bitvector bits,natural bitnum)
46{
47  natural
48    windex = bitnum>>bitmap_shift, 
49    old = bits[windex],
50    new = old | (BIT0_MASK >> (bitnum & bitmap_shift_count_mask));
51  if (new == old) {
52    return 1;                   /* Was set */
53  } else {
54    bits[windex] = new;
55    return 0;                   /* Was clear */
56  }
57}
58
59static inline int 
60atomic_set_bit(bitvector bits ,natural bitnum)
61{
62  extern natural atomic_ior(bitvector, natural);
63  natural
64    windex = bitnum>>bitmap_shift,
65    mask = (BIT0_MASK >> (bitnum & bitmap_shift_count_mask));
66
67  return atomic_ior(bits + windex, mask);
68}
69
70void set_n_bits(bitvector,natural,natural);
71
72static inline int
73clr_bit(bitvector bits, natural bitnum)
74{
75  natural
76    windex = bitnum>>bitmap_shift, 
77    old = bits[windex],
78    new = old & ~(BIT0_MASK >> (bitnum & bitmap_shift_count_mask));
79  if (new == old) {
80    return 0;   /* Was clear */
81  } else {
82    bits[windex] = new;
83    return 1;   /* Was set */
84  }
85}
86
87
88static inline unsigned
89ref_bit(bitvector bits,natural bitnum) __attribute__((always_inline));
90
91static inline unsigned
92ref_bit(bitvector bits,natural bitnum)
93{
94  return ((bits[bitnum>>bitmap_shift] & (BIT0_MASK >> (bitnum & bitmap_shift_count_mask))) != 0);
95}
96
97void zero_bits(bitvector, natural);
98void ior_bits(bitvector,bitvector,natural);
99
100#define bits_word_index(bitnum) (((natural)(bitnum)) >> bitmap_shift)
101#define bits_bit_index(bitnum) (((natural)(bitnum)) & bitmap_shift_count_mask)
102#define bits_word_ptr(bits,bitnum) \
103  ((natural*) (((natural*) bits) + ((natural) (bits_word_index(bitnum)))))
104#define bits_word_mask(bitnum) ((BIT0_MASK) >> bits_bit_index(bitnum))
105#define bits_indexed_word(bitv,indexw) ((((natural*)(bitv))[indexw]))
106#define bits_word(bitv,bitnum) bits_indexed_word(bits,bits_word_index(bitnum))
107
108/* Evaluates some arguments twice */
109
110#define set_bits_vars(BITVvar,BITNUMvar,BITPvar,BITWvar,MASKvar) \
111{ BITPvar = bits_word_ptr(BITVvar,BITNUMvar); BITWvar = *BITPvar; MASKvar = bits_word_mask(BITNUMvar); }
112
113#define set_bitidx_vars(BITVvar,BITNUMvar,BITPvar,BITWvar,BITIDXvar) \
114{ BITPvar = bits_word_ptr(BITVvar,BITNUMvar); BITIDXvar = bits_bit_index(BITNUMvar); \
115    BITWvar = (*BITPvar << BITIDXvar) >> BITIDXvar; }
116
117#if defined(__GNUC__) && !defined(__clang__)
118static __inline__ natural
119current_stack_pointer(void) __attribute__((always_inline));
120
121static __inline__ natural
122current_stack_pointer(void)
123{
124#ifdef PPC
125  register natural _sp __asm__("r1");
126#endif
127#ifdef X8664
128  natural _sp;
129  __asm__("movq %%rsp,%0" : "=r" (_sp));
130#endif
131#ifdef X8632
132  natural _sp;
133  __asm__("movl %%esp,%0" : "=r" (_sp));
134#endif
135#ifdef ARM
136  register natural _sp __asm__("sp");
137#endif
138  return _sp;
139}
140#else
141natural
142current_stack_pointer(void);
143#endif
144
145#ifdef __GNUC__
146static __inline__ unsigned
147count_leading_zeros(natural w) __attribute__((always_inline));
148
149
150/* Beware: on some platforms, __builtin_clz[ll](0) returns an undefined
151   result */
152
153static __inline__ unsigned
154count_leading_zeros(natural w)
155{
156#if __GNUC__ >= 4
157#if WORD_SIZE == 64
158  return __builtin_clzll(w); 
159#else
160  return __builtin_clz(w); 
161#endif
162#else /* __GNUC__ < 4 */
163  natural lz;
164#ifdef PPC
165#ifdef PPC64
166  __asm__ __volatile__("cntlzd %0,%1" : "=r" (lz) : "r" (w));
167#else
168  __asm__ __volatile__("cntlzw %0,%1" : "=r" (lz) : "r" (w));
169#endif
170#endif /* PPC */
171#ifdef X86
172#ifdef X8664
173  __asm__ __volatile__("bsr %1,%0" : "=r" (lz) : "r" (w));
174  __asm__ __volatile__("xor $63,%0" : "=r" (lz));
175#else
176  __asm__ __volatile__("bsr %1,%0" : "=r" (lz) : "r" (w));
177  __asm__ __volatile__("xor $31,%0" : "=r" (lz));
178#endif
179#endif
180  return lz;
181#endif
182}
183#else /* not __GNUC__ */
184unsigned
185count_leading_zeros(natural);
186#endif
187                                       
188#endif /* __bits_h__ */
Note: See TracBrowser for help on using the repository browser.