File: /usr/src/linux/include/asm-s390x/bitops.h
1 /*
2 * include/asm-s390/bitops.h
3 *
4 * S390 version
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
7 *
8 * Derived from "include/asm-i386/bitops.h"
9 * Copyright (C) 1992, Linus Torvalds
10 *
11 */
12
13 #ifndef _S390_BITOPS_H
14 #define _S390_BITOPS_H
15
16 /*
17 * bit 0 is the LSB of *addr; bit 63 is the MSB of *addr;
18 * bit 64 is the LSB of *(addr+8). That combined with the
19 * big endian byte order on S390 give the following bit
20 * order in memory:
21 * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30
22 * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20
23 * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10
24 * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
25 * after that follows the next long with bit numbers
26 * 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70
27 * 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60
28 * 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50
29 * 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40
30 * The reason for this bit ordering is the fact that
31 * in the architecture independent code bits operations
32 * of the form "flags |= (1 << bitnr)" are used INTERMIXED
33 * with operation of the form "set_bit(bitnr, flags)".
34 */
35 #include <linux/config.h>
36
37 /* set ALIGN_CS to 1 if the SMP safe bit operations should
38 * align the address to 4 byte boundary. It seems to work
39 * without the alignment.
40 */
41 #ifdef __KERNEL__
42 #define ALIGN_CS 0
43 #else
44 #define ALIGN_CS 1
45 #ifndef CONFIG_SMP
46 #error "bitops won't work without CONFIG_SMP"
47 #endif
48 #endif
49
50 /* bitmap tables from arch/S390/kernel/bitmap.S */
51 extern const char _oi_bitmap[];
52 extern const char _ni_bitmap[];
53 extern const char _zb_findmap[];
54
55 #ifdef CONFIG_SMP
56 /*
57 * SMP save set_bit routine based on compare and swap (CS)
58 */
59 static __inline__ void set_bit_cs(unsigned long nr, volatile void * addr)
60 {
61 unsigned long bits, mask;
62 __asm__ __volatile__(
63 #if ALIGN_CS == 1
64 " lghi %2,7\n" /* CS must be aligned on 4 byte b. */
65 " ngr %2,%1\n" /* isolate last 2 bits of address */
66 " xgr %1,%2\n" /* make addr % 4 == 0 */
67 " sllg %2,%2,3\n"
68 " agr %0,%2\n" /* add alignement to bitnr */
69 #endif
70 " lghi %2,63\n"
71 " nr %2,%0\n" /* make shift value */
72 " xr %0,%2\n"
73 " srlg %0,%0,3\n"
74 " lghi %3,1\n"
75 " la %1,0(%0,%1)\n" /* calc. address for CS */
76 " sllg %3,%3,0(%2)\n" /* make OR mask */
77 " lg %0,0(%1)\n"
78 "0: lgr %2,%0\n" /* CS loop starts here */
79 " ogr %2,%3\n" /* set bit */
80 " csg %0,%2,0(%1)\n"
81 " jl 0b"
82 : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
83 : "cc", "memory" );
84 }
85
86 /*
87 * SMP save clear_bit routine based on compare and swap (CS)
88 */
89 static __inline__ void clear_bit_cs(unsigned long nr, volatile void * addr)
90 {
91 unsigned long bits, mask;
92 __asm__ __volatile__(
93 #if ALIGN_CS == 1
94 " lghi %2,7\n" /* CS must be aligned on 4 byte b. */
95 " ngr %2,%1\n" /* isolate last 2 bits of address */
96 " xgr %1,%2\n" /* make addr % 4 == 0 */
97 " sllg %2,%2,3\n"
98 " agr %0,%2\n" /* add alignement to bitnr */
99 #endif
100 " lghi %2,63\n"
101 " nr %2,%0\n" /* make shift value */
102 " xr %0,%2\n"
103 " srlg %0,%0,3\n"
104 " lghi %3,-2\n"
105 " la %1,0(%0,%1)\n" /* calc. address for CS */
106 " lghi %3,-2\n"
107 " rllg %3,%3,0(%2)\n" /* make AND mask */
108 " lg %0,0(%1)\n"
109 "0: lgr %2,%0\n" /* CS loop starts here */
110 " ngr %2,%3\n" /* clear bit */
111 " csg %0,%2,0(%1)\n"
112 " jl 0b"
113 : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
114 : "cc", "memory" );
115 }
116
117 /*
118 * SMP save change_bit routine based on compare and swap (CS)
119 */
120 static __inline__ void change_bit_cs(unsigned long nr, volatile void * addr)
121 {
122 unsigned long bits, mask;
123 __asm__ __volatile__(
124 #if ALIGN_CS == 1
125 " lghi %2,7\n" /* CS must be aligned on 4 byte b. */
126 " ngr %2,%1\n" /* isolate last 2 bits of address */
127 " xgr %1,%2\n" /* make addr % 4 == 0 */
128 " sllg %2,%2,3\n"
129 " agr %0,%2\n" /* add alignement to bitnr */
130 #endif
131 " lghi %2,63\n"
132 " nr %2,%0\n" /* make shift value */
133 " xr %0,%2\n"
134 " srlg %0,%0,3\n"
135 " lghi %3,1\n"
136 " la %1,0(%0,%1)\n" /* calc. address for CS */
137 " sllg %3,%3,0(%2)\n" /* make XR mask */
138 " lg %0,0(%1)\n"
139 "0: lgr %2,%0\n" /* CS loop starts here */
140 " xgr %2,%3\n" /* change bit */
141 " csg %0,%2,0(%1)\n"
142 " jl 0b"
143 : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
144 : "cc", "memory" );
145 }
146
147 /*
148 * SMP save test_and_set_bit routine based on compare and swap (CS)
149 */
150 static __inline__ int
151 test_and_set_bit_cs(unsigned long nr, volatile void * addr)
152 {
153 unsigned long bits, mask;
154 __asm__ __volatile__(
155 #if ALIGN_CS == 1
156 " lghi %2,7\n" /* CS must be aligned on 4 byte b. */
157 " ngr %2,%1\n" /* isolate last 2 bits of address */
158 " xgr %1,%2\n" /* make addr % 4 == 0 */
159 " sllg %2,%2,3\n"
160 " agr %0,%2\n" /* add alignement to bitnr */
161 #endif
162 " lghi %2,63\n"
163 " nr %2,%0\n" /* make shift value */
164 " xr %0,%2\n"
165 " srlg %0,%0,3\n"
166 " lghi %3,1\n"
167 " la %1,0(%0,%1)\n" /* calc. address for CS */
168 " sllg %3,%3,0(%2)\n" /* make OR mask */
169 " lg %0,0(%1)\n"
170 "0: lgr %2,%0\n" /* CS loop starts here */
171 " ogr %2,%3\n" /* set bit */
172 " csg %0,%2,0(%1)\n"
173 " jl 0b\n"
174 " ngr %0,%3\n" /* isolate old bit */
175 : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
176 : "cc", "memory" );
177 return nr != 0;
178 }
179
180 /*
181 * SMP save test_and_clear_bit routine based on compare and swap (CS)
182 */
183 static __inline__ int
184 test_and_clear_bit_cs(unsigned long nr, volatile void * addr)
185 {
186 unsigned long bits, mask;
187 __asm__ __volatile__(
188 #if ALIGN_CS == 1
189 " lghi %2,7\n" /* CS must be aligned on 4 byte b. */
190 " ngr %2,%1\n" /* isolate last 2 bits of address */
191 " xgr %1,%2\n" /* make addr % 4 == 0 */
192 " sllg %2,%2,3\n"
193 " agr %0,%2\n" /* add alignement to bitnr */
194 #endif
195 " lghi %2,63\n"
196 " nr %2,%0\n" /* make shift value */
197 " xr %0,%2\n"
198 " srlg %0,%0,3\n"
199 " lghi %3,-2\n"
200 " la %1,0(%0,%1)\n" /* calc. address for CS */
201 " rllg %3,%3,0(%2)\n" /* make AND mask */
202 " lg %0,0(%1)\n"
203 "0: lgr %2,%0\n" /* CS loop starts here */
204 " ngr %2,%3\n" /* clear bit */
205 " csg %0,%2,0(%1)\n"
206 " jl 0b\n"
207 " xgr %0,%2\n" /* isolate old bit */
208 : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
209 : "cc", "memory" );
210 return nr != 0;
211 }
212
213 /*
214 * SMP save test_and_change_bit routine based on compare and swap (CS)
215 */
216 static __inline__ int
217 test_and_change_bit_cs(unsigned long nr, volatile void * addr)
218 {
219 unsigned long bits, mask;
220 __asm__ __volatile__(
221 #if ALIGN_CS == 1
222 " lghi %2,7\n" /* CS must be aligned on 4 byte b. */
223 " ngr %2,%1\n" /* isolate last 2 bits of address */
224 " xgr %1,%2\n" /* make addr % 4 == 0 */
225 " sllg %2,%2,3\n"
226 " agr %0,%2\n" /* add alignement to bitnr */
227 #endif
228 " lghi %2,63\n"
229 " nr %2,%0\n" /* make shift value */
230 " xr %0,%2\n"
231 " srlg %0,%0,3\n"
232 " lghi %3,1\n"
233 " la %1,0(%0,%1)\n" /* calc. address for CS */
234 " sllg %3,%3,0(%2)\n" /* make OR mask */
235 " lg %0,0(%1)\n"
236 "0: lgr %2,%0\n" /* CS loop starts here */
237 " xgr %2,%3\n" /* change bit */
238 " csg %0,%2,0(%1)\n"
239 " jl 0b\n"
240 " ngr %0,%3\n" /* isolate old bit */
241 : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
242 : "cc", "memory" );
243 return nr != 0;
244 }
245 #endif /* CONFIG_SMP */
246
247 /*
248 * fast, non-SMP set_bit routine
249 */
250 static __inline__ void __set_bit(unsigned long nr, volatile void * addr)
251 {
252 __asm__ __volatile__(
253 " lghi 2,56\n"
254 " lghi 1,7\n"
255 " xgr 2,%0\n"
256 " nr 1,%0\n"
257 " srlg 2,2,3\n"
258 " la 2,0(2,%1)\n"
259 " la 1,0(1,%2)\n"
260 " oc 0(1,2),0(1)"
261 : : "a" (nr), "a" (addr), "a" (&_oi_bitmap)
262 : "cc", "memory", "1", "2" );
263 }
264
265 static __inline__ void
266 __constant_set_bit(const unsigned long nr, volatile void * addr)
267 {
268 switch (nr&7) {
269 case 0:
270 __asm__ __volatile__ ("la 1,%0\n\t"
271 "oi 0(1),0x01"
272 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
273 : : "1", "cc", "memory");
274 break;
275 case 1:
276 __asm__ __volatile__ ("la 1,%0\n\t"
277 "oi 0(1),0x02"
278 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
279 : : "1", "cc", "memory" );
280 break;
281 case 2:
282 __asm__ __volatile__ ("la 1,%0\n\t"
283 "oi 0(1),0x04"
284 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
285 : : "1", "cc", "memory" );
286 break;
287 case 3:
288 __asm__ __volatile__ ("la 1,%0\n\t"
289 "oi 0(1),0x08"
290 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
291 : : "1", "cc", "memory" );
292 break;
293 case 4:
294 __asm__ __volatile__ ("la 1,%0\n\t"
295 "oi 0(1),0x10"
296 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
297 : : "1", "cc", "memory" );
298 break;
299 case 5:
300 __asm__ __volatile__ ("la 1,%0\n\t"
301 "oi 0(1),0x20"
302 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
303 : : "1", "cc", "memory" );
304 break;
305 case 6:
306 __asm__ __volatile__ ("la 1,%0\n\t"
307 "oi 0(1),0x40"
308 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
309 : : "1", "cc", "memory" );
310 break;
311 case 7:
312 __asm__ __volatile__ ("la 1,%0\n\t"
313 "oi 0(1),0x80"
314 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
315 : : "1", "cc", "memory" );
316 break;
317 }
318 }
319
320 #define set_bit_simple(nr,addr) \
321 (__builtin_constant_p((nr)) ? \
322 __constant_set_bit((nr),(addr)) : \
323 __set_bit((nr),(addr)) )
324
325 /*
326 * fast, non-SMP clear_bit routine
327 */
328 static __inline__ void
329 __clear_bit(unsigned long nr, volatile void * addr)
330 {
331 __asm__ __volatile__(
332 " lghi 2,56\n"
333 " lghi 1,7\n"
334 " xgr 2,%0\n"
335 " nr 1,%0\n"
336 " srlg 2,2,3\n"
337 " la 2,0(2,%1)\n"
338 " la 1,0(1,%2)\n"
339 " nc 0(1,2),0(1)"
340 : : "d" (nr), "a" (addr), "a" (&_ni_bitmap)
341 : "cc", "memory", "1", "2" );
342 }
343
344 static __inline__ void
345 __constant_clear_bit(const unsigned long nr, volatile void * addr)
346 {
347 switch (nr&7) {
348 case 0:
349 __asm__ __volatile__ ("la 1,%0\n\t"
350 "ni 0(1),0xFE"
351 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
352 : : "1", "cc", "memory" );
353 break;
354 case 1:
355 __asm__ __volatile__ ("la 1,%0\n\t"
356 "ni 0(1),0xFD"
357 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
358 : : "1", "cc", "memory" );
359 break;
360 case 2:
361 __asm__ __volatile__ ("la 1,%0\n\t"
362 "ni 0(1),0xFB"
363 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
364 : : "1", "cc", "memory" );
365 break;
366 case 3:
367 __asm__ __volatile__ ("la 1,%0\n\t"
368 "ni 0(1),0xF7"
369 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
370 : : "1", "cc", "memory" );
371 break;
372 case 4:
373 __asm__ __volatile__ ("la 1,%0\n\t"
374 "ni 0(1),0xEF"
375 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
376 : : "cc", "memory" );
377 break;
378 case 5:
379 __asm__ __volatile__ ("la 1,%0\n\t"
380 "ni 0(1),0xDF"
381 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
382 : : "1", "cc", "memory" );
383 break;
384 case 6:
385 __asm__ __volatile__ ("la 1,%0\n\t"
386 "ni 0(1),0xBF"
387 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
388 : : "1", "cc", "memory" );
389 break;
390 case 7:
391 __asm__ __volatile__ ("la 1,%0\n\t"
392 "ni 0(1),0x7F"
393 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
394 : : "1", "cc", "memory" );
395 break;
396 }
397 }
398
399 #define clear_bit_simple(nr,addr) \
400 (__builtin_constant_p((nr)) ? \
401 __constant_clear_bit((nr),(addr)) : \
402 __clear_bit((nr),(addr)) )
403
404 /*
405 * fast, non-SMP change_bit routine
406 */
407 static __inline__ void __change_bit(unsigned long nr, volatile void * addr)
408 {
409 __asm__ __volatile__(
410 " lghi 2,56\n"
411 " lghi 1,7\n"
412 " xgr 2,%0\n"
413 " nr 1,%0\n"
414 " srlg 2,2,3\n"
415 " la 2,0(2,%1)\n"
416 " la 1,0(1,%2)\n"
417 " xc 0(1,2),0(1)"
418 : : "d" (nr), "a" (addr), "a" (&_oi_bitmap)
419 : "cc", "memory", "1", "2" );
420 }
421
422 static __inline__ void
423 __constant_change_bit(const unsigned long nr, volatile void * addr)
424 {
425 switch (nr&7) {
426 case 0:
427 __asm__ __volatile__ ("la 1,%0\n\t"
428 "xi 0(1),0x01"
429 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
430 : : "cc", "memory" );
431 break;
432 case 1:
433 __asm__ __volatile__ ("la 1,%0\n\t"
434 "xi 0(1),0x02"
435 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
436 : : "cc", "memory" );
437 break;
438 case 2:
439 __asm__ __volatile__ ("la 1,%0\n\t"
440 "xi 0(1),0x04"
441 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
442 : : "cc", "memory" );
443 break;
444 case 3:
445 __asm__ __volatile__ ("la 1,%0\n\t"
446 "xi 0(1),0x08"
447 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
448 : : "cc", "memory" );
449 break;
450 case 4:
451 __asm__ __volatile__ ("la 1,%0\n\t"
452 "xi 0(1),0x10"
453 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
454 : : "cc", "memory" );
455 break;
456 case 5:
457 __asm__ __volatile__ ("la 1,%0\n\t"
458 "xi 0(1),0x20"
459 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
460 : : "1", "cc", "memory" );
461 break;
462 case 6:
463 __asm__ __volatile__ ("la 1,%0\n\t"
464 "xi 0(1),0x40"
465 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
466 : : "1", "cc", "memory" );
467 break;
468 case 7:
469 __asm__ __volatile__ ("la 1,%0\n\t"
470 "xi 0(1),0x80"
471 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
472 : : "1", "cc", "memory" );
473 break;
474 }
475 }
476
477 #define change_bit_simple(nr,addr) \
478 (__builtin_constant_p((nr)) ? \
479 __constant_change_bit((nr),(addr)) : \
480 __change_bit((nr),(addr)) )
481
482 /*
483 * fast, non-SMP test_and_set_bit routine
484 */
485 static __inline__ int
486 test_and_set_bit_simple(unsigned long nr, volatile void * addr)
487 {
488 int oldbit;
489 __asm__ __volatile__(
490 " lghi 1,56\n"
491 " lghi 2,7\n"
492 " xgr 1,%1\n"
493 " nr 2,%1\n"
494 " srlg 1,1,3\n"
495 " la 1,0(1,%2)\n"
496 " ic %0,0(1)\n"
497 " srl %0,0(2)\n"
498 " la 2,0(2,%3)\n"
499 " oc 0(1,1),0(2)"
500 : "=&d" (oldbit) : "d" (nr), "a" (addr), "a" (&_oi_bitmap)
501 : "cc", "memory", "1", "2" );
502 return oldbit & 1;
503 }
504 #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
505
506 /*
507 * fast, non-SMP test_and_clear_bit routine
508 */
509 static __inline__ int
510 test_and_clear_bit_simple(unsigned long nr, volatile void * addr)
511 {
512 int oldbit;
513
514 __asm__ __volatile__(
515 " lghi 1,56\n"
516 " lghi 2,7\n"
517 " xgr 1,%1\n"
518 " nr 2,%1\n"
519 " srlg 1,1,3\n"
520 " la 1,0(1,%2)\n"
521 " ic %0,0(1)\n"
522 " srl %0,0(2)\n"
523 " la 2,0(2,%3)\n"
524 " nc 0(1,1),0(2)"
525 : "=&d" (oldbit) : "d" (nr), "a" (addr), "a" (&_ni_bitmap)
526 : "cc", "memory", "1", "2" );
527 return oldbit & 1;
528 }
529 #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
530
531 /*
532 * fast, non-SMP test_and_change_bit routine
533 */
534 static __inline__ int
535 test_and_change_bit_simple(unsigned long nr, volatile void * addr)
536 {
537 int oldbit;
538
539 __asm__ __volatile__(
540 " lghi 1,56\n"
541 " lghi 2,7\n"
542 " xgr 1,%1\n"
543 " nr 2,%1\n"
544 " srlg 1,1,3\n"
545 " la 1,0(1,%2)\n"
546 " ic %0,0(1)\n"
547 " srl %0,0(2)\n"
548 " la 2,0(2,%3)\n"
549 " xc 0(1,1),0(2)"
550 : "=&d" (oldbit) : "d" (nr), "a" (addr), "a" (&_oi_bitmap)
551 : "cc", "memory", "1", "2" );
552 return oldbit & 1;
553 }
554 #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
555
556 #ifdef CONFIG_SMP
557 #define set_bit set_bit_cs
558 #define clear_bit clear_bit_cs
559 #define change_bit change_bit_cs
560 #define test_and_set_bit test_and_set_bit_cs
561 #define test_and_clear_bit test_and_clear_bit_cs
562 #define test_and_change_bit test_and_change_bit_cs
563 #else
564 #define set_bit set_bit_simple
565 #define clear_bit clear_bit_simple
566 #define change_bit change_bit_simple
567 #define test_and_set_bit test_and_set_bit_simple
568 #define test_and_clear_bit test_and_clear_bit_simple
569 #define test_and_change_bit test_and_change_bit_simple
570 #endif
571
572
573 /*
574 * This routine doesn't need to be atomic.
575 */
576
577 static __inline__ int __test_bit(unsigned long nr, volatile void * addr)
578 {
579 int oldbit;
580
581 __asm__ __volatile__(
582 " lghi 2,56\n"
583 " lghi 1,7\n"
584 " xgr 2,%1\n"
585 " nr 1,%1\n"
586 " srlg 2,2,3\n"
587 " ic %0,0(2,%2)\n"
588 " srl %0,0(1)\n"
589 : "=&d" (oldbit) : "d" (nr), "a" (addr)
590 : "cc", "1", "2" );
591 return oldbit & 1;
592 }
593
594 static __inline__ int
595 __constant_test_bit(unsigned long nr, volatile void * addr) {
596 return (((volatile char *) addr)[(nr>>3)^7] & (1<<(nr&7))) != 0;
597 }
598
599 #define test_bit(nr,addr) \
600 (__builtin_constant_p((nr)) ? \
601 __constant_test_bit((nr),(addr)) : \
602 __test_bit((nr),(addr)) )
603
604 /*
605 * Find-bit routines..
606 */
607 static __inline__ unsigned long
608 find_first_zero_bit(void * addr, unsigned long size)
609 {
610 unsigned long res;
611
612 if (!size)
613 return 0;
614 __asm__(" lghi 0,-1\n"
615 " lgr 1,%1\n"
616 " slgr %0,%0\n"
617 " aghi 1,63\n"
618 " srlg 1,1,6\n"
619 "0: cg 0,0(%0,%2)\n"
620 " jne 1f\n"
621 " aghi %0,8\n"
622 " brct 1,0b\n"
623 " lgr %0,%1\n"
624 " j 5f\n"
625 "1: lg 1,0(%0,%2)\n"
626 " sllg %0,%0,3\n"
627 " clr 1,0\n"
628 " jne 2f\n"
629 " aghi %0,32\n"
630 " srlg 1,1,32\n"
631 "2: lghi 0,0xff\n"
632 " tmll 1,0xffff\n"
633 " jno 3f\n"
634 " aghi %0,16\n"
635 " srl 1,16\n"
636 "3: tmll 1,0x00ff\n"
637 " jno 4f\n"
638 " aghi %0,8\n"
639 " srl 1,8\n"
640 "4: ngr 1,0\n"
641 " ic 1,0(1,%3)\n"
642 " algr %0,1\n"
643 "5:"
644 : "=&a" (res) : "a" (size), "a" (addr), "a" (&_zb_findmap)
645 : "cc", "0", "1" );
646 return (res < size) ? res : size;
647 }
648
649 static __inline__ unsigned long
650 find_next_zero_bit (void * addr, unsigned long size, unsigned long offset)
651 {
652 unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
653 unsigned long bitvec;
654 unsigned long set, bit = offset & 63, res;
655
656 if (bit) {
657 /*
658 * Look for zero in first word
659 */
660 bitvec = (*p) >> bit;
661 __asm__(" lhi 0,-1\n"
662 " lgr 1,%1\n"
663 " slgr %0,%0\n"
664 " clr 1,0\n"
665 " jne 0f\n"
666 " aghi %0,32\n"
667 " srlg 1,1,32\n"
668 "0: lghi 0,0xff\n"
669 " tmll 1,0xffff\n"
670 " jno 1f\n"
671 " aghi %0,16\n"
672 " srlg 1,1,16\n"
673 "1: tmll 1,0x00ff\n"
674 " jno 2f\n"
675 " aghi %0,8\n"
676 " srlg 1,1,8\n"
677 "2: ngr 1,0\n"
678 " ic 1,0(1,%2)\n"
679 " algr %0,1"
680 : "=&d" (set)
681 : "d" (bitvec), "a" (&_zb_findmap)
682 : "cc", "0", "1" );
683 if (set < (64 - bit))
684 return set + offset;
685 offset += 64 - bit;
686 p++;
687 }
688 /*
689 * No zero yet, search remaining full words for a zero
690 */
691 res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr));
692 return (offset + res);
693 }
694
695 /*
696 * ffz = Find First Zero in word. Undefined if no zero exists,
697 * so code should check against ~0UL first..
698 */
699 static __inline__ unsigned long ffz(unsigned long word)
700 {
701 int result;
702
703 __asm__(" lhi 0,-1\n"
704 " lgr 1,%1\n"
705 " slgr %0,%0\n"
706 " clr 1,0\n"
707 " jne 0f\n"
708 " aghi %0,32\n"
709 " srlg 1,1,32\n"
710 "0: lghi 0,0xff\n"
711 " tmll 1,0xffff\n"
712 " jno 1f\n"
713 " aghi %0,16\n"
714 " srlg 1,1,16\n"
715 "1: tmll 1,0x00ff\n"
716 " jno 2f\n"
717 " aghi %0,8\n"
718 " srlg 1,1,8\n"
719 "2: ngr 1,0\n"
720 " ic 1,0(1,%2)\n"
721 " algr %0,1"
722 : "=&d" (result)
723 : "d" (word), "a" (&_zb_findmap)
724 : "cc", "0", "1" );
725
726 return result;
727 }
728
729 /*
730 * ffs: find first bit set. This is defined the same way as
731 * the libc and compiler builtin ffs routines, therefore
732 * differs in spirit from the above ffz (man ffs).
733 */
734
735 extern int __inline__ ffs (int x)
736 {
737 int r;
738
739 if (x == 0)
740 return 0;
741 __asm__(" lr 1,%1\n"
742 " slr %0,%0\n"
743 " tml 1,0xFFFF\n"
744 " jnz 0f\n"
745 " ahi %0,16\n"
746 " srl 1,16\n"
747 "0: tml 1,0x00FF\n"
748 " jnz 1f\n"
749 " ahi %0,8\n"
750 " srl 1,8\n"
751 "1: tml 1,0x000F\n"
752 " jnz 2f\n"
753 " ahi %0,4\n"
754 " srl 1,4\n"
755 "2: tml 1,0x0003\n"
756 " jnz 3f\n"
757 " ahi %0,2\n"
758 " srl 1,2\n"
759 "3: tml 1,0x0001\n"
760 " jnz 4f\n"
761 " ahi %0,1\n"
762 "4:"
763 : "=&d" (r) : "d" (x) : "cc", "1" );
764 return r+1;
765 }
766
767 /*
768 * hweightN: returns the hamming weight (i.e. the number
769 * of bits set) of a N-bit word
770 */
771
772 #define hweight32(x) generic_hweight32(x)
773 #define hweight16(x) generic_hweight16(x)
774 #define hweight8(x) generic_hweight8(x)
775
776
777 #ifdef __KERNEL__
778
779 /*
780 * ATTENTION: intel byte ordering convention for ext2 and minix !!
781 * bit 0 is the LSB of addr; bit 31 is the MSB of addr;
782 * bit 32 is the LSB of (addr+4).
783 * That combined with the little endian byte order of Intel gives the
784 * following bit order in memory:
785 * 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 \
786 * 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
787 */
788
789 #define ext2_set_bit(nr, addr) test_and_set_bit((nr)^56, addr)
790 #define ext2_clear_bit(nr, addr) test_and_clear_bit((nr)^56, addr)
791 #define ext2_test_bit(nr, addr) test_bit((nr)^56, addr)
792 static __inline__ unsigned long
793 ext2_find_first_zero_bit(void *vaddr, unsigned long size)
794 {
795 unsigned long res;
796
797 if (!size)
798 return 0;
799 __asm__(" lghi 0,-1\n"
800 " lgr 1,%1\n"
801 " aghi 1,63\n"
802 " srlg 1,1,6\n"
803 " slgr %0,%0\n"
804 "0: clg 0,0(%0,%2)\n"
805 " jne 1f\n"
806 " aghi %0,8\n"
807 " brct 1,0b\n"
808 " lgr %0,%1\n"
809 " j 5f\n"
810 "1: cl 0,0(%0,%2)\n"
811 " jne 2f\n"
812 " aghi %0,4\n"
813 "2: l 1,0(%0,%2)\n"
814 " sllg %0,%0,3\n"
815 " aghi %0,24\n"
816 " lghi 0,0xff\n"
817 " tmlh 1,0xffff\n"
818 " jo 3f\n"
819 " aghi %0,-16\n"
820 " srl 1,16\n"
821 "3: tmll 1,0xff00\n"
822 " jo 4f\n"
823 " aghi %0,-8\n"
824 " srl 1,8\n"
825 "4: ngr 1,0\n"
826 " ic 1,0(1,%3)\n"
827 " algr %0,1\n"
828 "5:"
829 : "=&a" (res) : "a" (size), "a" (vaddr), "a" (&_zb_findmap)
830 : "cc", "0", "1" );
831 return (res < size) ? res : size;
832 }
833
834 static __inline__ unsigned long
835 ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
836 {
837 unsigned long *addr = vaddr;
838 unsigned long *p = addr + (offset >> 6);
839 unsigned long word;
840 unsigned long bit = offset & 63UL, res;
841
842 if (offset >= size)
843 return size;
844
845 if (bit) {
846 __asm__(" lrvg %0,%1" /* load reversed, neat instruction */
847 : "=a" (word) : "m" (*p) );
848 word >>= bit;
849 res = bit;
850 /* Look for zero in first 8 byte word */
851 __asm__(" lgr 1,%1\n"
852 " lghi 0,0xff\n"
853 " tmll 1,0xffff\n"
854 " jno 2f\n"
855 " ahi %0,16\n"
856 " srlg 1,1,16\n"
857 "0: tmll 1,0xffff\n"
858 " jno 2f\n"
859 " ahi %0,16\n"
860 " srlg 1,1,16\n"
861 "1: tmll 1,0xffff\n"
862 " jno 2f\n"
863 " ahi %0,16\n"
864 " srl 1,16\n"
865 "2: tmll 1,0x00ff\n"
866 " jno 3f\n"
867 " ahi %0,8\n"
868 " srl 1,8\n"
869 "3: ngr 1,0\n"
870 " ic 1,0(1,%2)\n"
871 " alr %0,1"
872 : "+&d" (res)
873 : "d" (word), "a" (&_zb_findmap)
874 : "cc", "0", "1" );
875 if (res < 64)
876 return (p - addr)*64 + res;
877 p++;
878 }
879 /* No zero yet, search remaining full bytes for a zero */
880 res = ext2_find_first_zero_bit (p, size - 64 * (p - addr));
881 return (p - addr) * 64 + res;
882 }
883
884 /* Bitmap functions for the minix filesystem. */
885 /* FIXME !!! */
886 #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
887 #define minix_set_bit(nr,addr) set_bit(nr,addr)
888 #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
889 #define minix_test_bit(nr,addr) test_bit(nr,addr)
890 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
891
892 #endif /* __KERNEL__ */
893
894 #endif /* _S390_BITOPS_H */
895