1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 #pragma ident "@(#)bits.c 1.9 09/05/26 SMI" 23 24 /* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #include <sys/types.h> 30 /*LINTED*/ 31 #include "bits.h" 32 /* 33 * simple bit counting routines. 34 */ 35 static const char bit_counts[] = { 36 0 /* 0 */, 37 1 /* 0x1 */, 38 1 /* 0x2 */, 39 2 /* 0x3 */, 40 1 /* 0x4 */, 41 2 /* 0x5 */, 42 2 /* 0x6 */, 43 3 /* 0x7 */, 44 1 /* 0x8 */, 45 2 /* 0x9 */, 46 2 /* 0xa */, 47 3 /* 0xb */, 48 2 /* 0xc */, 49 3 /* 0xd */, 50 3 /* 0xe */, 51 4 /* 0xf */, 52 1 /* 0x10 */, 53 2 /* 0x11 */, 54 2 /* 0x12 */, 55 3 /* 0x13 */, 56 2 /* 0x14 */, 57 3 /* 0x15 */, 58 3 /* 0x16 */, 59 4 /* 0x17 */, 60 2 /* 0x18 */, 61 3 /* 0x19 */, 62 3 /* 0x1a */, 63 4 /* 0x1b */, 64 3 /* 0x1c */, 65 4 /* 0x1d */, 66 4 /* 0x1e */, 67 5 /* 0x1f */, 68 1 /* 0x20 */, 69 2 /* 0x21 */, 70 2 /* 0x22 */, 71 3 /* 0x23 */, 72 2 /* 0x24 */, 73 3 /* 0x25 */, 74 3 /* 0x26 */, 75 4 /* 0x27 */, 76 2 /* 0x28 */, 77 3 /* 0x29 */, 78 3 /* 0x2a */, 79 4 /* 0x2b */, 80 3 /* 0x2c */, 81 4 /* 0x2d */, 82 4 /* 0x2e */, 83 5 /* 0x2f */, 84 2 /* 0x30 */, 85 3 /* 0x31 */, 86 3 /* 0x32 */, 87 4 /* 0x33 */, 88 3 /* 0x34 */, 89 4 /* 0x35 */, 90 4 /* 0x36 */, 91 5 /* 0x37 */, 92 3 /* 0x38 */, 93 4 /* 0x39 */, 94 4 /* 0x3a */, 95 5 /* 0x3b */, 96 4 /* 0x3c */, 97 5 /* 0x3d */, 98 5 /* 0x3e */, 99 6 /* 0x3f */, 100 1 /* 0x40 */, 101 2 /* 0x41 */, 102 2 /* 0x42 */, 103 3 /* 0x43 */, 104 2 /* 0x44 */, 105 3 /* 0x45 */, 106 3 /* 0x46 */, 107 4 /* 0x47 */, 108 2 /* 0x48 */, 109 3 /* 0x49 */, 110 3 /* 0x4a */, 111 4 /* 0x4b */, 112 3 /* 0x4c */, 113 4 /* 0x4d */, 114 4 /* 0x4e */, 115 5 /* 0x4f */, 116 2 /* 0x50 */, 117 3 /* 0x51 */, 118 3 /* 0x52 */, 119 4 /* 0x53 */, 120 3 /* 0x54 */, 121 4 /* 0x55 */, 122 4 /* 0x56 */, 123 5 /* 0x57 */, 124 3 /* 0x58 */, 125 4 /* 0x59 */, 126 4 /* 0x5a */, 127 5 /* 0x5b */, 128 4 /* 0x5c */, 129 5 /* 0x5d */, 130 5 /* 0x5e */, 131 6 /* 0x5f */, 132 2 /* 0x60 */, 133 3 /* 0x61 */, 134 3 /* 0x62 */, 135 4 /* 0x63 */, 136 3 /* 0x64 */, 137 4 /* 0x65 */, 138 4 /* 0x66 */, 139 5 /* 0x67 */, 140 3 /* 0x68 */, 141 4 /* 0x69 */, 142 4 /* 0x6a */, 143 5 /* 0x6b */, 144 4 /* 0x6c */, 145 5 /* 0x6d */, 146 5 /* 0x6e */, 147 6 /* 0x6f */, 148 3 /* 0x70 */, 149 4 /* 0x71 */, 150 4 /* 0x72 */, 151 5 /* 0x73 */, 152 4 /* 0x74 */, 153 5 /* 0x75 */, 154 5 /* 0x76 */, 155 6 /* 0x77 */, 156 4 /* 0x78 */, 157 5 /* 0x79 */, 158 5 /* 0x7a */, 159 6 /* 0x7b */, 160 5 /* 0x7c */, 161 6 /* 0x7d */, 162 6 /* 0x7e */, 163 7 /* 0x7f */, 164 1 /* 0x80 */, 165 2 /* 0x81 */, 166 2 /* 0x82 */, 167 3 /* 0x83 */, 168 2 /* 0x84 */, 169 3 /* 0x85 */, 170 3 /* 0x86 */, 171 4 /* 0x87 */, 172 2 /* 0x88 */, 173 3 /* 0x89 */, 174 3 /* 0x8a */, 175 4 /* 0x8b */, 176 3 /* 0x8c */, 177 4 /* 0x8d */, 178 4 /* 0x8e */, 179 5 /* 0x8f */, 180 2 /* 0x90 */, 181 3 /* 0x91 */, 182 3 /* 0x92 */, 183 4 /* 0x93 */, 184 3 /* 0x94 */, 185 4 /* 0x95 */, 186 4 /* 0x96 */, 187 5 /* 0x97 */, 188 3 /* 0x98 */, 189 4 /* 0x99 */, 190 4 /* 0x9a */, 191 5 /* 0x9b */, 192 4 /* 0x9c */, 193 5 /* 0x9d */, 194 5 /* 0x9e */, 195 6 /* 0x9f */, 196 2 /* 0xa0 */, 197 3 /* 0xa1 */, 198 3 /* 0xa2 */, 199 4 /* 0xa3 */, 200 3 /* 0xa4 */, 201 4 /* 0xa5 */, 202 4 /* 0xa6 */, 203 5 /* 0xa7 */, 204 3 /* 0xa8 */, 205 4 /* 0xa9 */, 206 4 /* 0xaa */, 207 5 /* 0xab */, 208 4 /* 0xac */, 209 5 /* 0xad */, 210 5 /* 0xae */, 211 6 /* 0xaf */, 212 3 /* 0xb0 */, 213 4 /* 0xb1 */, 214 4 /* 0xb2 */, 215 5 /* 0xb3 */, 216 4 /* 0xb4 */, 217 5 /* 0xb5 */, 218 5 /* 0xb6 */, 219 6 /* 0xb7 */, 220 4 /* 0xb8 */, 221 5 /* 0xb9 */, 222 5 /* 0xba */, 223 6 /* 0xbb */, 224 5 /* 0xbc */, 225 6 /* 0xbd */, 226 6 /* 0xbe */, 227 7 /* 0xbf */, 228 2 /* 0xc0 */, 229 3 /* 0xc1 */, 230 3 /* 0xc2 */, 231 4 /* 0xc3 */, 232 3 /* 0xc4 */, 233 4 /* 0xc5 */, 234 4 /* 0xc6 */, 235 5 /* 0xc7 */, 236 3 /* 0xc8 */, 237 4 /* 0xc9 */, 238 4 /* 0xca */, 239 5 /* 0xcb */, 240 4 /* 0xcc */, 241 5 /* 0xcd */, 242 5 /* 0xce */, 243 6 /* 0xcf */, 244 3 /* 0xd0 */, 245 4 /* 0xd1 */, 246 4 /* 0xd2 */, 247 5 /* 0xd3 */, 248 4 /* 0xd4 */, 249 5 /* 0xd5 */, 250 5 /* 0xd6 */, 251 6 /* 0xd7 */, 252 4 /* 0xd8 */, 253 5 /* 0xd9 */, 254 5 /* 0xda */, 255 6 /* 0xdb */, 256 5 /* 0xdc */, 257 6 /* 0xdd */, 258 6 /* 0xde */, 259 7 /* 0xdf */, 260 3 /* 0xe0 */, 261 4 /* 0xe1 */, 262 4 /* 0xe2 */, 263 5 /* 0xe3 */, 264 4 /* 0xe4 */, 265 5 /* 0xe5 */, 266 5 /* 0xe6 */, 267 6 /* 0xe7 */, 268 4 /* 0xe8 */, 269 5 /* 0xe9 */, 270 5 /* 0xea */, 271 6 /* 0xeb */, 272 5 /* 0xec */, 273 6 /* 0xed */, 274 6 /* 0xee */, 275 7 /* 0xef */, 276 4 /* 0xf0 */, 277 5 /* 0xf1 */, 278 5 /* 0xf2 */, 279 6 /* 0xf3 */, 280 5 /* 0xf4 */, 281 6 /* 0xf5 */, 282 6 /* 0xf6 */, 283 7 /* 0xf7 */, 284 5 /* 0xf8 */, 285 6 /* 0xf9 */, 286 6 /* 0xfa */, 287 7 /* 0xfb */, 288 6 /* 0xfc */, 289 7 /* 0xfd */, 290 7 /* 0xfe */, 291 8 /* 0xff */ 292 }; 293 294 int 295 count_uint8_bits(uchar_t x) 296 { 297 return (bit_counts[x]); 298 } 299 300 int 301 count_uint16_bits(uint16_t x) 302 { 303 union { 304 uint16_t i; 305 uchar_t c[sizeof (uint16_t)]; 306 } u; 307 int i, tot; 308 309 u.i = x; 310 311 for (i = tot = 0; i < sizeof (uint16_t); i++) 312 tot += count_uint8_bits(u.c[i]); 313 return (tot); 314 } 315 316 int 317 count_uint32_bits(uint32_t x) 318 { 319 union { 320 uint32_t i; 321 uchar_t c[sizeof (uint32_t)]; 322 } u; 323 int i, tot; 324 325 u.i = x; 326 327 for (i = tot = 0; i < sizeof (uint32_t); i++) 328 tot += count_uint8_bits(u.c[i]); 329 return (tot); 330 } 331 332 int 333 count_uint64_bits(uint64_t x) 334 { 335 union { 336 uint64_t i; 337 uchar_t c[sizeof (uint64_t)]; 338 } u; 339 int i, tot; 340 341 u.i = x; 342 343 for (i = tot = 0; i < sizeof (uint64_t); i++) 344 tot += count_uint8_bits(u.c[i]); 345 return (tot); 346 } 347 348 static void 349 uint8_bits_set(uint8_t bit, char off, char **res) 350 { 351 char i; 352 int x = 1; 353 354 for (i = 0; i < 8; i++) { 355 if (x & bit) { 356 **res = i + off; 357 (*res)++; 358 } 359 x <<= 1; 360 } 361 } 362 363 void 364 what_uint8_bits_set(uint8_t bit, char *res) 365 { 366 uint8_bits_set(bit, 0, &res); 367 } 368 369 #ifdef _BIG_ENDIAN 370 #define GET_CHAR(U, I) (U.c[(sizeof (U.v) - 1) - I]) 371 #elif defined(_LITTLE_ENDIAN) 372 #define GET_CHAR(U, I) (U.c[I]) 373 #else 374 #error "niether _BIG_ENDIAN or _LITTLE_ENDIAN defined" 375 #endif 376 377 void 378 what_uint16_bits_set(uint16_t bit, char *res) 379 { 380 union { 381 uint16_t v; 382 uint8_t c[sizeof (uint16_t) / sizeof (uint8_t)]; 383 } x; 384 char i; 385 386 x.v = bit; 387 388 for (i = 0; i < (sizeof (uint16_t) / sizeof (uint8_t)); i++) { 389 uint8_bits_set(GET_CHAR(x, i), i * 8, &res); 390 } 391 } 392 393 void 394 what_uint32_bits_set(uint32_t bit, char *res) 395 { 396 union { 397 uint32_t v; 398 uint8_t c[sizeof (uint32_t) / sizeof (uint8_t)]; 399 } x; 400 char i; 401 402 x.v = bit; 403 404 for (i = 0; i < (sizeof (uint32_t) / sizeof (uint8_t)); i++) { 405 uint8_bits_set(GET_CHAR(x, i), i * 8, &res); 406 } 407 } 408 409 void 410 what_uint64_bits_set(uint64_t bit, char *res) 411 { 412 union { 413 uint64_t v; 414 uint8_t c[sizeof (uint64_t) / sizeof (uint8_t)]; 415 } x; 416 char i; 417 418 x.v = bit; 419 420 for (i = 0; i < (sizeof (uint64_t) / sizeof (uint8_t)); i++) { 421 uint8_bits_set(GET_CHAR(x, i), i * 8, &res); 422 } 423 } 424