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, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2014 by Delphix. All rights reserved.
  29  */
  30 
  31 /*
  32  * Architecture specific definition for bitmap related routines.
  33  * These may be implemented using ISA specific instructions.
  34  */
  35 #include <sys/bitmap.h>
  36 
  37 /*
  38  * Find highest one bit set.
  39  *      Returns bit number + 1 of highest bit that is set, otherwise returns 0.
  40  */
  41 int
  42 highbit64(uint64_t i)
  43 {
  44         int h = 1;
  45 
  46         if (i == 0)
  47                 return (0);
  48         if (i & 0xffffffff00000000ULL) {
  49                 h += 32; i >>= 32;
  50         }
  51         if (i & 0xffff0000) {
  52                 h += 16; i >>= 16;
  53         }
  54         if (i & 0xff00) {
  55                 h += 8; i >>= 8;
  56         }
  57         if (i & 0xf0) {
  58                 h += 4; i >>= 4;
  59         }
  60         if (i & 0xc) {
  61                 h += 2; i >>= 2;
  62         }
  63         if (i & 0x2) {
  64                 h += 1;
  65         }
  66         return (h);
  67 }
  68 
  69 /*
  70  * Find highest one bit set.
  71  *      Returns bit number + 1 of highest bit that is set, otherwise returns 0.
  72  * High order bit is 31 (or 63 in _LP64 kernel).
  73  */
  74 int
  75 highbit(ulong_t i)
  76 {
  77         register int h = 1;
  78 
  79         if (i == 0)
  80                 return (0);
  81 #ifdef _LP64
  82         if (i & 0xffffffff00000000ul) {
  83                 h += 32; i >>= 32;
  84         }
  85 #endif
  86         if (i & 0xffff0000) {
  87                 h += 16; i >>= 16;
  88         }
  89         if (i & 0xff00) {
  90                 h += 8; i >>= 8;
  91         }
  92         if (i & 0xf0) {
  93                 h += 4; i >>= 4;
  94         }
  95         if (i & 0xc) {
  96                 h += 2; i >>= 2;
  97         }
  98         if (i & 0x2) {
  99                 h += 1;
 100         }
 101         return (h);
 102 }
 103 
 104 /*
 105  * Find lowest one bit set.
 106  *      Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
 107  * Low order bit is 0.
 108  */
 109 int
 110 lowbit(ulong_t i)
 111 {
 112         register int h = 1;
 113 
 114         if (i == 0)
 115                 return (0);
 116 
 117 #ifdef _LP64
 118         if (!(i & 0xffffffff)) {
 119                 h += 32; i >>= 32;
 120         }
 121 #endif
 122         if (!(i & 0xffff)) {
 123                 h += 16; i >>= 16;
 124         }
 125         if (!(i & 0xff)) {
 126                 h += 8; i >>= 8;
 127         }
 128         if (!(i & 0xf)) {
 129                 h += 4; i >>= 4;
 130         }
 131         if (!(i & 0x3)) {
 132                 h += 2; i >>= 2;
 133         }
 134         if (!(i & 0x1)) {
 135                 h += 1;
 136         }
 137         return (h);
 138 }