1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * bitops.c --- Bitmap frobbing code. See bitops.h for the inlined
3*6a54128fSAndroid Build Coastguard Worker * routines.
4*6a54128fSAndroid Build Coastguard Worker *
5*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6*6a54128fSAndroid Build Coastguard Worker *
7*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
8*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Library
9*6a54128fSAndroid Build Coastguard Worker * General Public License, version 2.
10*6a54128fSAndroid Build Coastguard Worker * %End-Header%
11*6a54128fSAndroid Build Coastguard Worker */
12*6a54128fSAndroid Build Coastguard Worker
13*6a54128fSAndroid Build Coastguard Worker #include "config.h"
14*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
15*6a54128fSAndroid Build Coastguard Worker #if HAVE_SYS_TYPES_H
16*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
17*6a54128fSAndroid Build Coastguard Worker #endif
18*6a54128fSAndroid Build Coastguard Worker
19*6a54128fSAndroid Build Coastguard Worker #include "ext2_fs.h"
20*6a54128fSAndroid Build Coastguard Worker #include "ext2fs.h"
21*6a54128fSAndroid Build Coastguard Worker
22*6a54128fSAndroid Build Coastguard Worker /*
23*6a54128fSAndroid Build Coastguard Worker * C language bitmap functions written by Theodore Ts'o, 9/26/92.
24*6a54128fSAndroid Build Coastguard Worker * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian
25*6a54128fSAndroid Build Coastguard Worker * systems, as well as non-32 bit systems.
26*6a54128fSAndroid Build Coastguard Worker */
27*6a54128fSAndroid Build Coastguard Worker
ext2fs_set_bit(unsigned int nr,void * addr)28*6a54128fSAndroid Build Coastguard Worker int ext2fs_set_bit(unsigned int nr,void * addr)
29*6a54128fSAndroid Build Coastguard Worker {
30*6a54128fSAndroid Build Coastguard Worker int mask, retval;
31*6a54128fSAndroid Build Coastguard Worker unsigned char *ADDR = (unsigned char *) addr;
32*6a54128fSAndroid Build Coastguard Worker
33*6a54128fSAndroid Build Coastguard Worker ADDR += nr >> 3;
34*6a54128fSAndroid Build Coastguard Worker mask = 1 << (nr & 0x07);
35*6a54128fSAndroid Build Coastguard Worker retval = mask & *ADDR;
36*6a54128fSAndroid Build Coastguard Worker *ADDR |= mask;
37*6a54128fSAndroid Build Coastguard Worker return retval;
38*6a54128fSAndroid Build Coastguard Worker }
39*6a54128fSAndroid Build Coastguard Worker
ext2fs_clear_bit(unsigned int nr,void * addr)40*6a54128fSAndroid Build Coastguard Worker int ext2fs_clear_bit(unsigned int nr, void * addr)
41*6a54128fSAndroid Build Coastguard Worker {
42*6a54128fSAndroid Build Coastguard Worker int mask, retval;
43*6a54128fSAndroid Build Coastguard Worker unsigned char *ADDR = (unsigned char *) addr;
44*6a54128fSAndroid Build Coastguard Worker
45*6a54128fSAndroid Build Coastguard Worker ADDR += nr >> 3;
46*6a54128fSAndroid Build Coastguard Worker mask = 1 << (nr & 0x07);
47*6a54128fSAndroid Build Coastguard Worker retval = mask & *ADDR;
48*6a54128fSAndroid Build Coastguard Worker *ADDR &= ~mask;
49*6a54128fSAndroid Build Coastguard Worker return retval;
50*6a54128fSAndroid Build Coastguard Worker }
51*6a54128fSAndroid Build Coastguard Worker
ext2fs_test_bit(unsigned int nr,const void * addr)52*6a54128fSAndroid Build Coastguard Worker int ext2fs_test_bit(unsigned int nr, const void * addr)
53*6a54128fSAndroid Build Coastguard Worker {
54*6a54128fSAndroid Build Coastguard Worker int mask;
55*6a54128fSAndroid Build Coastguard Worker const unsigned char *ADDR = (const unsigned char *) addr;
56*6a54128fSAndroid Build Coastguard Worker
57*6a54128fSAndroid Build Coastguard Worker ADDR += nr >> 3;
58*6a54128fSAndroid Build Coastguard Worker mask = 1 << (nr & 0x07);
59*6a54128fSAndroid Build Coastguard Worker return (mask & *ADDR);
60*6a54128fSAndroid Build Coastguard Worker }
61*6a54128fSAndroid Build Coastguard Worker
ext2fs_warn_bitmap(errcode_t errcode,unsigned long arg,const char * description)62*6a54128fSAndroid Build Coastguard Worker void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
63*6a54128fSAndroid Build Coastguard Worker const char *description)
64*6a54128fSAndroid Build Coastguard Worker {
65*6a54128fSAndroid Build Coastguard Worker #ifndef OMIT_COM_ERR
66*6a54128fSAndroid Build Coastguard Worker if (description)
67*6a54128fSAndroid Build Coastguard Worker com_err(0, errcode, "#%lu for %s", arg, description);
68*6a54128fSAndroid Build Coastguard Worker else
69*6a54128fSAndroid Build Coastguard Worker com_err(0, errcode, "#%lu", arg);
70*6a54128fSAndroid Build Coastguard Worker #endif
71*6a54128fSAndroid Build Coastguard Worker }
72*6a54128fSAndroid Build Coastguard Worker
73*6a54128fSAndroid Build Coastguard Worker /* Bitmap functions that take a 64-bit offset */
74*6a54128fSAndroid Build Coastguard Worker
ext2fs_set_bit64(__u64 nr,void * addr)75*6a54128fSAndroid Build Coastguard Worker int ext2fs_set_bit64(__u64 nr, void * addr)
76*6a54128fSAndroid Build Coastguard Worker {
77*6a54128fSAndroid Build Coastguard Worker int mask, retval;
78*6a54128fSAndroid Build Coastguard Worker unsigned char *ADDR = (unsigned char *) addr;
79*6a54128fSAndroid Build Coastguard Worker
80*6a54128fSAndroid Build Coastguard Worker ADDR += nr >> 3;
81*6a54128fSAndroid Build Coastguard Worker mask = 1 << (nr & 0x07);
82*6a54128fSAndroid Build Coastguard Worker retval = mask & *ADDR;
83*6a54128fSAndroid Build Coastguard Worker *ADDR |= mask;
84*6a54128fSAndroid Build Coastguard Worker return retval;
85*6a54128fSAndroid Build Coastguard Worker }
86*6a54128fSAndroid Build Coastguard Worker
ext2fs_clear_bit64(__u64 nr,void * addr)87*6a54128fSAndroid Build Coastguard Worker int ext2fs_clear_bit64(__u64 nr, void * addr)
88*6a54128fSAndroid Build Coastguard Worker {
89*6a54128fSAndroid Build Coastguard Worker int mask, retval;
90*6a54128fSAndroid Build Coastguard Worker unsigned char *ADDR = (unsigned char *) addr;
91*6a54128fSAndroid Build Coastguard Worker
92*6a54128fSAndroid Build Coastguard Worker ADDR += nr >> 3;
93*6a54128fSAndroid Build Coastguard Worker mask = 1 << (nr & 0x07);
94*6a54128fSAndroid Build Coastguard Worker retval = mask & *ADDR;
95*6a54128fSAndroid Build Coastguard Worker *ADDR &= ~mask;
96*6a54128fSAndroid Build Coastguard Worker return retval;
97*6a54128fSAndroid Build Coastguard Worker }
98*6a54128fSAndroid Build Coastguard Worker
ext2fs_test_bit64(__u64 nr,const void * addr)99*6a54128fSAndroid Build Coastguard Worker int ext2fs_test_bit64(__u64 nr, const void * addr)
100*6a54128fSAndroid Build Coastguard Worker {
101*6a54128fSAndroid Build Coastguard Worker int mask;
102*6a54128fSAndroid Build Coastguard Worker const unsigned char *ADDR = (const unsigned char *) addr;
103*6a54128fSAndroid Build Coastguard Worker
104*6a54128fSAndroid Build Coastguard Worker ADDR += nr >> 3;
105*6a54128fSAndroid Build Coastguard Worker mask = 1 << (nr & 0x07);
106*6a54128fSAndroid Build Coastguard Worker return (mask & *ADDR);
107*6a54128fSAndroid Build Coastguard Worker }
108*6a54128fSAndroid Build Coastguard Worker
popcount8(unsigned int w)109*6a54128fSAndroid Build Coastguard Worker static unsigned int popcount8(unsigned int w)
110*6a54128fSAndroid Build Coastguard Worker {
111*6a54128fSAndroid Build Coastguard Worker unsigned int res = w - ((w >> 1) & 0x55);
112*6a54128fSAndroid Build Coastguard Worker res = (res & 0x33) + ((res >> 2) & 0x33);
113*6a54128fSAndroid Build Coastguard Worker return (res + (res >> 4)) & 0x0F;
114*6a54128fSAndroid Build Coastguard Worker }
115*6a54128fSAndroid Build Coastguard Worker
popcount32(unsigned int w)116*6a54128fSAndroid Build Coastguard Worker static unsigned int popcount32(unsigned int w)
117*6a54128fSAndroid Build Coastguard Worker {
118*6a54128fSAndroid Build Coastguard Worker unsigned int res = w - ((w >> 1) & 0x55555555);
119*6a54128fSAndroid Build Coastguard Worker res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
120*6a54128fSAndroid Build Coastguard Worker res = (res + (res >> 4)) & 0x0F0F0F0F;
121*6a54128fSAndroid Build Coastguard Worker res = res + (res >> 8);
122*6a54128fSAndroid Build Coastguard Worker return (res + (res >> 16)) & 0x000000FF;
123*6a54128fSAndroid Build Coastguard Worker }
124*6a54128fSAndroid Build Coastguard Worker
ext2fs_bitcount(const void * addr,unsigned int nbytes)125*6a54128fSAndroid Build Coastguard Worker unsigned int ext2fs_bitcount(const void *addr, unsigned int nbytes)
126*6a54128fSAndroid Build Coastguard Worker {
127*6a54128fSAndroid Build Coastguard Worker const unsigned char *cp = addr;
128*6a54128fSAndroid Build Coastguard Worker const __u32 *p;
129*6a54128fSAndroid Build Coastguard Worker unsigned int res = 0;
130*6a54128fSAndroid Build Coastguard Worker
131*6a54128fSAndroid Build Coastguard Worker while (((((uintptr_t) cp) & 3) != 0) && (nbytes > 0)) {
132*6a54128fSAndroid Build Coastguard Worker res += popcount8(*cp++);
133*6a54128fSAndroid Build Coastguard Worker nbytes--;
134*6a54128fSAndroid Build Coastguard Worker }
135*6a54128fSAndroid Build Coastguard Worker p = (const __u32 *) cp;
136*6a54128fSAndroid Build Coastguard Worker
137*6a54128fSAndroid Build Coastguard Worker while (nbytes > 4) {
138*6a54128fSAndroid Build Coastguard Worker res += popcount32(*p++);
139*6a54128fSAndroid Build Coastguard Worker nbytes -= 4;
140*6a54128fSAndroid Build Coastguard Worker }
141*6a54128fSAndroid Build Coastguard Worker cp = (const unsigned char *) p;
142*6a54128fSAndroid Build Coastguard Worker
143*6a54128fSAndroid Build Coastguard Worker while (nbytes > 0) {
144*6a54128fSAndroid Build Coastguard Worker res += popcount8(*cp++);
145*6a54128fSAndroid Build Coastguard Worker nbytes--;
146*6a54128fSAndroid Build Coastguard Worker }
147*6a54128fSAndroid Build Coastguard Worker return res;
148*6a54128fSAndroid Build Coastguard Worker }
149