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

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

Update copyright notices.

  • 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) 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  unsigned 
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#ifdef __GNUC__
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  register natural _sp __asm__("%rsp");
129#endif
130#ifdef X8632
131  register natural _sp __asm__("%esp");
132#endif
133  return _sp;
134}
135#else
136natural
137current_stack_pointer(void);
138#endif
139
140#ifdef __GNUC__
141static __inline__ unsigned
142count_leading_zeros(natural w) __attribute__((always_inline));
143
144
145/* Beware: on some platforms, __builtin_clz[ll](0) returns an undefined
146   result */
147
148static __inline__ unsigned
149count_leading_zeros(natural w)
150{
151#if __GNUC__ >= 4
152#if WORD_SIZE == 64
153  return __builtin_clzll(w); 
154#else
155  return __builtin_clz(w); 
156#endif
157#else /* __GNUC__ < 4 */
158  natural lz;
159#ifdef PPC
160#ifdef PPC64
161  __asm__  ("cntlzd %0,%1" : "=r" (lz) : "r" (w));
162#else
163  __asm__  ("cntlzw %0,%1" : "=r" (lz) : "r" (w));
164#endif
165#endif /* PPC */
166#ifdef X86
167#ifdef X8664
168  __asm__ ("bsr %1,%0" : "=r" (lz) : "r" (w));
169  __asm__ ("xor $63,%0" : "=r" (lz));
170#else
171  __asm__ ("bsr %1,%0" : "=r" (lz) : "r" (w));
172  __asm__ ("xor $31,%0" : "=r" (lz));
173#endif
174#endif
175  return lz;
176#endif
177}
178#else /* not __GNUC__ */
179unsigned
180count_leading_zeros(natural);
181#endif
182                                       
183#endif /* __bits_h__ */
Note: See TracBrowser for help on using the repository browser.