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

Last change on this file was 16685, checked in by rme, 5 years ago

Update copyright/license headers in files.

  • 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 1994-2009 Clozure Associates
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
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  natural
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#if defined(__GNUC__) && !defined(__clang__)
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  natural _sp;
128  __asm__("movq %%rsp,%0" : "=r" (_sp));
129#endif
130#ifdef X8632
131  natural _sp;
132  __asm__("movl %%esp,%0" : "=r" (_sp));
133#endif
134#ifdef ARM
135  register natural _sp __asm__("sp");
136#endif
137  return _sp;
138}
139#else
140natural
141current_stack_pointer(void);
142#endif
143
144#ifdef __GNUC__
145static __inline__ unsigned
146count_leading_zeros(natural w) __attribute__((always_inline));
147
148
149/* Beware: on some platforms, __builtin_clz[ll](0) returns an undefined
150   result */
151
152static __inline__ unsigned
153count_leading_zeros(natural w)
154{
155#if __GNUC__ >= 4
156#if WORD_SIZE == 64
157  return __builtin_clzll(w); 
158#else
159  return __builtin_clz(w); 
160#endif
161#else /* __GNUC__ < 4 */
162  natural lz;
163#ifdef PPC
164#ifdef PPC64
165  __asm__ __volatile__("cntlzd %0,%1" : "=r" (lz) : "r" (w));
166#else
167  __asm__ __volatile__("cntlzw %0,%1" : "=r" (lz) : "r" (w));
168#endif
169#endif /* PPC */
170#ifdef X86
171#ifdef X8664
172  __asm__ __volatile__("bsr %1,%0" : "=r" (lz) : "r" (w));
173  __asm__ __volatile__("xor $63,%0" : "=r" (lz));
174#else
175  __asm__ __volatile__("bsr %1,%0" : "=r" (lz) : "r" (w));
176  __asm__ __volatile__("xor $31,%0" : "=r" (lz));
177#endif
178#endif
179  return lz;
180#endif
181}
182#else /* not __GNUC__ */
183unsigned
184count_leading_zeros(natural);
185#endif
186                                       
187#endif /* __bits_h__ */
Note: See TracBrowser for help on using the repository browser.