source: trunk/source/lisp-kernel/bits.h @ 13066

Last change on this file since 13066 was 13066, checked in by rme, 11 years ago

Change "OpenMCL" to "Clozure CL" in comments and docstrings.

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