1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _S390_BITOPS_H
14#define _S390_BITOPS_H
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <linux/config.h>
36
37
38
39
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
51extern const char _oi_bitmap[];
52extern const char _ni_bitmap[];
53extern const char _zb_findmap[];
54
55#ifdef CONFIG_SMP
56
57
58
59static __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"
65 " ngr %2,%1\n"
66 " xgr %1,%2\n"
67 " sllg %2,%2,3\n"
68 " agr %0,%2\n"
69#endif
70 " lghi %2,63\n"
71 " nr %2,%0\n"
72 " xr %0,%2\n"
73 " srlg %0,%0,3\n"
74 " lghi %3,1\n"
75 " la %1,0(%0,%1)\n"
76 " sllg %3,%3,0(%2)\n"
77 " lg %0,0(%1)\n"
78 "0: lgr %2,%0\n"
79 " ogr %2,%3\n"
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
88
89static __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"
95 " ngr %2,%1\n"
96 " xgr %1,%2\n"
97 " sllg %2,%2,3\n"
98 " agr %0,%2\n"
99#endif
100 " lghi %2,63\n"
101 " nr %2,%0\n"
102 " xr %0,%2\n"
103 " srlg %0,%0,3\n"
104 " lghi %3,-2\n"
105 " la %1,0(%0,%1)\n"
106 " lghi %3,-2\n"
107 " rllg %3,%3,0(%2)\n"
108 " lg %0,0(%1)\n"
109 "0: lgr %2,%0\n"
110 " ngr %2,%3\n"
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
119
120static __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"
126 " ngr %2,%1\n"
127 " xgr %1,%2\n"
128 " sllg %2,%2,3\n"
129 " agr %0,%2\n"
130#endif
131 " lghi %2,63\n"
132 " nr %2,%0\n"
133 " xr %0,%2\n"
134 " srlg %0,%0,3\n"
135 " lghi %3,1\n"
136 " la %1,0(%0,%1)\n"
137 " sllg %3,%3,0(%2)\n"
138 " lg %0,0(%1)\n"
139 "0: lgr %2,%0\n"
140 " xgr %2,%3\n"
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
149
150static __inline__ int
151test_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"
157 " ngr %2,%1\n"
158 " xgr %1,%2\n"
159 " sllg %2,%2,3\n"
160 " agr %0,%2\n"
161#endif
162 " lghi %2,63\n"
163 " nr %2,%0\n"
164 " xr %0,%2\n"
165 " srlg %0,%0,3\n"
166 " lghi %3,1\n"
167 " la %1,0(%0,%1)\n"
168 " sllg %3,%3,0(%2)\n"
169 " lg %0,0(%1)\n"
170 "0: lgr %2,%0\n"
171 " ogr %2,%3\n"
172 " csg %0,%2,0(%1)\n"
173 " jl 0b\n"
174 " ngr %0,%3\n"
175 : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
176 : "cc", "memory" );
177 return nr != 0;
178}
179
180
181
182
183static __inline__ int
184test_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"
190 " ngr %2,%1\n"
191 " xgr %1,%2\n"
192 " sllg %2,%2,3\n"
193 " agr %0,%2\n"
194#endif
195 " lghi %2,63\n"
196 " nr %2,%0\n"
197 " xr %0,%2\n"
198 " srlg %0,%0,3\n"
199 " lghi %3,-2\n"
200 " la %1,0(%0,%1)\n"
201 " rllg %3,%3,0(%2)\n"
202 " lg %0,0(%1)\n"
203 "0: lgr %2,%0\n"
204 " ngr %2,%3\n"
205 " csg %0,%2,0(%1)\n"
206 " jl 0b\n"
207 " xgr %0,%2\n"
208 : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
209 : "cc", "memory" );
210 return nr != 0;
211}
212
213
214
215
216static __inline__ int
217test_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"
223 " ngr %2,%1\n"
224 " xgr %1,%2\n"
225 " sllg %2,%2,3\n"
226 " agr %0,%2\n"
227#endif
228 " lghi %2,63\n"
229 " nr %2,%0\n"
230 " xr %0,%2\n"
231 " srlg %0,%0,3\n"
232 " lghi %3,1\n"
233 " la %1,0(%0,%1)\n"
234 " sllg %3,%3,0(%2)\n"
235 " lg %0,0(%1)\n"
236 "0: lgr %2,%0\n"
237 " xgr %2,%3\n"
238 " csg %0,%2,0(%1)\n"
239 " jl 0b\n"
240 " ngr %0,%3\n"
241 : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
242 : "cc", "memory" );
243 return nr != 0;
244}
245#endif
246
247
248
249
250static __inline__ void __set_bit(unsigned long nr, volatile void * addr)
251{
252 unsigned long reg1, reg2;
253 __asm__ __volatile__(
254 " lghi %1,56\n"
255 " lghi %0,7\n"
256 " xgr %1,%2\n"
257 " nr %0,%2\n"
258 " srlg %1,%1,3\n"
259 " la %1,0(%1,%3)\n"
260 " la %0,0(%0,%4)\n"
261 " oc 0(1,%1),0(%0)"
262 : "=&a" (reg1), "=&a" (reg2)
263 : "a" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
264}
265
266static __inline__ void
267__constant_set_bit(const unsigned long nr, volatile void * addr)
268{
269 switch (nr&7) {
270 case 0:
271 __asm__ __volatile__ ("la 1,%0\n\t"
272 "oi 0(1),0x01"
273 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
274 : : "1", "cc", "memory");
275 break;
276 case 1:
277 __asm__ __volatile__ ("la 1,%0\n\t"
278 "oi 0(1),0x02"
279 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
280 : : "1", "cc", "memory" );
281 break;
282 case 2:
283 __asm__ __volatile__ ("la 1,%0\n\t"
284 "oi 0(1),0x04"
285 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
286 : : "1", "cc", "memory" );
287 break;
288 case 3:
289 __asm__ __volatile__ ("la 1,%0\n\t"
290 "oi 0(1),0x08"
291 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
292 : : "1", "cc", "memory" );
293 break;
294 case 4:
295 __asm__ __volatile__ ("la 1,%0\n\t"
296 "oi 0(1),0x10"
297 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
298 : : "1", "cc", "memory" );
299 break;
300 case 5:
301 __asm__ __volatile__ ("la 1,%0\n\t"
302 "oi 0(1),0x20"
303 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
304 : : "1", "cc", "memory" );
305 break;
306 case 6:
307 __asm__ __volatile__ ("la 1,%0\n\t"
308 "oi 0(1),0x40"
309 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
310 : : "1", "cc", "memory" );
311 break;
312 case 7:
313 __asm__ __volatile__ ("la 1,%0\n\t"
314 "oi 0(1),0x80"
315 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
316 : : "1", "cc", "memory" );
317 break;
318 }
319}
320
321#define set_bit_simple(nr,addr) \
322(__builtin_constant_p((nr)) ? \
323 __constant_set_bit((nr),(addr)) : \
324 __set_bit((nr),(addr)) )
325
326
327
328
329static __inline__ void
330__clear_bit(unsigned long nr, volatile void * addr)
331{
332 unsigned long reg1, reg2;
333 __asm__ __volatile__(
334 " lghi %1,56\n"
335 " lghi %0,7\n"
336 " xgr %1,%2\n"
337 " nr %0,%2\n"
338 " srlg %1,%1,3\n"
339 " la %1,0(%1,%3)\n"
340 " la %0,0(%0,%4)\n"
341 " nc 0(1,%1),0(%0)"
342 : "=&a" (reg1), "=&a" (reg2)
343 : "d" (nr), "a" (addr), "a" (&_ni_bitmap) : "cc", "memory" );
344}
345
346static __inline__ void
347__constant_clear_bit(const unsigned long nr, volatile void * addr)
348{
349 switch (nr&7) {
350 case 0:
351 __asm__ __volatile__ ("la 1,%0\n\t"
352 "ni 0(1),0xFE"
353 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
354 : : "1", "cc", "memory" );
355 break;
356 case 1:
357 __asm__ __volatile__ ("la 1,%0\n\t"
358 "ni 0(1),0xFD"
359 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
360 : : "1", "cc", "memory" );
361 break;
362 case 2:
363 __asm__ __volatile__ ("la 1,%0\n\t"
364 "ni 0(1),0xFB"
365 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
366 : : "1", "cc", "memory" );
367 break;
368 case 3:
369 __asm__ __volatile__ ("la 1,%0\n\t"
370 "ni 0(1),0xF7"
371 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
372 : : "1", "cc", "memory" );
373 break;
374 case 4:
375 __asm__ __volatile__ ("la 1,%0\n\t"
376 "ni 0(1),0xEF"
377 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
378 : : "cc", "memory" );
379 break;
380 case 5:
381 __asm__ __volatile__ ("la 1,%0\n\t"
382 "ni 0(1),0xDF"
383 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
384 : : "1", "cc", "memory" );
385 break;
386 case 6:
387 __asm__ __volatile__ ("la 1,%0\n\t"
388 "ni 0(1),0xBF"
389 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
390 : : "1", "cc", "memory" );
391 break;
392 case 7:
393 __asm__ __volatile__ ("la 1,%0\n\t"
394 "ni 0(1),0x7F"
395 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
396 : : "1", "cc", "memory" );
397 break;
398 }
399}
400
401#define clear_bit_simple(nr,addr) \
402(__builtin_constant_p((nr)) ? \
403 __constant_clear_bit((nr),(addr)) : \
404 __clear_bit((nr),(addr)) )
405
406
407
408
409static __inline__ void __change_bit(unsigned long nr, volatile void * addr)
410{
411 unsigned long reg1, reg2;
412 __asm__ __volatile__(
413 " lghi %1,56\n"
414 " lghi %0,7\n"
415 " xgr %1,%2\n"
416 " nr %0,%2\n"
417 " srlg %1,%1,3\n"
418 " la %1,0(%1,%3)\n"
419 " la %0,0(%0,%4)\n"
420 " xc 0(1,%1),0(%0)"
421 : "=&a" (reg1), "=&a" (reg2)
422 : "d" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
423}
424
425static __inline__ void
426__constant_change_bit(const unsigned long nr, volatile void * addr)
427{
428 switch (nr&7) {
429 case 0:
430 __asm__ __volatile__ ("la 1,%0\n\t"
431 "xi 0(1),0x01"
432 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
433 : : "cc", "memory" );
434 break;
435 case 1:
436 __asm__ __volatile__ ("la 1,%0\n\t"
437 "xi 0(1),0x02"
438 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
439 : : "cc", "memory" );
440 break;
441 case 2:
442 __asm__ __volatile__ ("la 1,%0\n\t"
443 "xi 0(1),0x04"
444 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
445 : : "cc", "memory" );
446 break;
447 case 3:
448 __asm__ __volatile__ ("la 1,%0\n\t"
449 "xi 0(1),0x08"
450 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
451 : : "cc", "memory" );
452 break;
453 case 4:
454 __asm__ __volatile__ ("la 1,%0\n\t"
455 "xi 0(1),0x10"
456 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
457 : : "cc", "memory" );
458 break;
459 case 5:
460 __asm__ __volatile__ ("la 1,%0\n\t"
461 "xi 0(1),0x20"
462 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
463 : : "1", "cc", "memory" );
464 break;
465 case 6:
466 __asm__ __volatile__ ("la 1,%0\n\t"
467 "xi 0(1),0x40"
468 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
469 : : "1", "cc", "memory" );
470 break;
471 case 7:
472 __asm__ __volatile__ ("la 1,%0\n\t"
473 "xi 0(1),0x80"
474 : "=m" (*((volatile char *) addr + ((nr>>3)^7)))
475 : : "1", "cc", "memory" );
476 break;
477 }
478}
479
480#define change_bit_simple(nr,addr) \
481(__builtin_constant_p((nr)) ? \
482 __constant_change_bit((nr),(addr)) : \
483 __change_bit((nr),(addr)) )
484
485
486
487
488static __inline__ int
489test_and_set_bit_simple(unsigned long nr, volatile void * addr)
490{
491 unsigned long reg1, reg2;
492 int oldbit;
493 __asm__ __volatile__(
494 " lghi %1,56\n"
495 " lghi %2,7\n"
496 " xgr %1,%3\n"
497 " nr %2,%3\n"
498 " srlg %1,%1,3\n"
499 " la %1,0(%1,%4)\n"
500 " ic %0,0(%1)\n"
501 " srl %0,0(%2)\n"
502 " la %2,0(%2,%5)\n"
503 " oc 0(1,%1),0(%2)"
504 : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
505 : "d" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
506 return oldbit & 1;
507}
508#define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
509
510
511
512
513static __inline__ int
514test_and_clear_bit_simple(unsigned long nr, volatile void * addr)
515{
516 unsigned long reg1, reg2;
517 int oldbit;
518
519 __asm__ __volatile__(
520 " lghi %1,56\n"
521 " lghi %2,7\n"
522 " xgr %1,%3\n"
523 " nr %2,%3\n"
524 " srlg %1,%1,3\n"
525 " la %1,0(%1,%4)\n"
526 " ic %0,0(%1)\n"
527 " srl %0,0(%2)\n"
528 " la %2,0(%2,%5)\n"
529 " nc 0(1,%1),0(%2)"
530 : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
531 : "d" (nr), "a" (addr), "a" (&_ni_bitmap) : "cc", "memory" );
532 return oldbit & 1;
533}
534#define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
535
536
537
538
539static __inline__ int
540test_and_change_bit_simple(unsigned long nr, volatile void * addr)
541{
542 unsigned long reg1, reg2;
543 int oldbit;
544
545 __asm__ __volatile__(
546 " lghi %1,56\n"
547 " lghi %2,7\n"
548 " xgr %1,%3\n"
549 " nr %2,%3\n"
550 " srlg %1,%1,3\n"
551 " la %1,0(%1,%4)\n"
552 " ic %0,0(%1)\n"
553 " srl %0,0(%2)\n"
554 " la %2,0(%2,%5)\n"
555 " xc 0(1,%1),0(%2)"
556 : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
557 : "d" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
558 return oldbit & 1;
559}
560#define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
561
562#ifdef CONFIG_SMP
563#define set_bit set_bit_cs
564#define clear_bit clear_bit_cs
565#define change_bit change_bit_cs
566#define test_and_set_bit test_and_set_bit_cs
567#define test_and_clear_bit test_and_clear_bit_cs
568#define test_and_change_bit test_and_change_bit_cs
569#else
570#define set_bit set_bit_simple
571#define clear_bit clear_bit_simple
572#define change_bit change_bit_simple
573#define test_and_set_bit test_and_set_bit_simple
574#define test_and_clear_bit test_and_clear_bit_simple
575#define test_and_change_bit test_and_change_bit_simple
576#endif
577
578
579
580
581
582
583static __inline__ int __test_bit(unsigned long nr, volatile void * addr)
584{
585 unsigned long reg1, reg2;
586 int oldbit;
587
588 __asm__ __volatile__(
589 " lghi %2,56\n"
590 " lghi %1,7\n"
591 " xgr %2,%3\n"
592 " nr %1,%3\n"
593 " srlg %2,%2,3\n"
594 " ic %0,0(%2,%4)\n"
595 " srl %0,0(%1)\n"
596 : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
597 : "d" (nr), "a" (addr) : "cc" );
598 return oldbit & 1;
599}
600
601static __inline__ int
602__constant_test_bit(unsigned long nr, volatile void * addr) {
603 return (((volatile char *) addr)[(nr>>3)^7] & (1<<(nr&7))) != 0;
604}
605
606#define test_bit(nr,addr) \
607(__builtin_constant_p((nr)) ? \
608 __constant_test_bit((nr),(addr)) : \
609 __test_bit((nr),(addr)) )
610
611
612
613
614static __inline__ unsigned long
615find_first_zero_bit(void * addr, unsigned long size)
616{
617 unsigned long res, cmp, count;
618
619 if (!size)
620 return 0;
621 __asm__(" lghi %1,-1\n"
622 " lgr %2,%3\n"
623 " slgr %0,%0\n"
624 " aghi %2,63\n"
625 " srlg %2,%2,6\n"
626 "0: cg %1,0(%0,%4)\n"
627 " jne 1f\n"
628 " aghi %0,8\n"
629 " brct %2,0b\n"
630 " lgr %0,%3\n"
631 " j 5f\n"
632 "1: lg %2,0(%0,%4)\n"
633 " sllg %0,%0,3\n"
634 " clr %2,%1\n"
635 " jne 2f\n"
636 " aghi %0,32\n"
637 " srlg %2,%2,32\n"
638 "2: lghi %1,0xff\n"
639 " tmll %2,0xffff\n"
640 " jno 3f\n"
641 " aghi %0,16\n"
642 " srl %2,16\n"
643 "3: tmll %2,0x00ff\n"
644 " jno 4f\n"
645 " aghi %0,8\n"
646 " srl %2,8\n"
647 "4: ngr %2,%1\n"
648 " ic %2,0(%2,%5)\n"
649 " algr %0,%2\n"
650 "5:"
651 : "=&a" (res), "=&d" (cmp), "=&a" (count)
652 : "a" (size), "a" (addr), "a" (&_zb_findmap) : "cc" );
653 return (res < size) ? res : size;
654}
655
656static __inline__ unsigned long
657find_next_zero_bit (void * addr, unsigned long size, unsigned long offset)
658{
659 unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
660 unsigned long bitvec, reg;
661 unsigned long set, bit = offset & 63, res;
662
663 if (bit) {
664
665
666
667 bitvec = (*p) >> bit;
668 __asm__(" lhi %2,-1\n"
669 " slgr %0,%0\n"
670 " clr %1,%2\n"
671 " jne 0f\n"
672 " aghi %0,32\n"
673 " srlg %1,%1,32\n"
674 "0: lghi %2,0xff\n"
675 " tmll %1,0xffff\n"
676 " jno 1f\n"
677 " aghi %0,16\n"
678 " srlg %1,%1,16\n"
679 "1: tmll %1,0x00ff\n"
680 " jno 2f\n"
681 " aghi %0,8\n"
682 " srlg %1,%1,8\n"
683 "2: ngr %1,%2\n"
684 " ic %1,0(%1,%3)\n"
685 " algr %0,%1"
686 : "=&d" (set), "+a" (bitvec), "=&d" (reg)
687 : "a" (&_zb_findmap) : "cc" );
688 if (set < (64 - bit))
689 return set + offset;
690 offset += 64 - bit;
691 p++;
692 }
693
694
695
696 res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr));
697 return (offset + res);
698}
699
700
701
702
703
704static __inline__ unsigned long ffz(unsigned long word)
705{
706 unsigned long reg;
707 int result;
708
709 __asm__(" lhi %2,-1\n"
710 " slgr %0,%0\n"
711 " clr %1,%2\n"
712 " jne 0f\n"
713 " aghi %0,32\n"
714 " srlg %1,%1,32\n"
715 "0: lghi %2,0xff\n"
716 " tmll %1,0xffff\n"
717 " jno 1f\n"
718 " aghi %0,16\n"
719 " srlg %1,%1,16\n"
720 "1: tmll %1,0x00ff\n"
721 " jno 2f\n"
722 " aghi %0,8\n"
723 " srlg %1,%1,8\n"
724 "2: ngr %1,%2\n"
725 " ic %1,0(%1,%3)\n"
726 " algr %0,%1"
727 : "=&d" (result), "+a" (word), "=&d" (reg)
728 : "a" (&_zb_findmap) : "cc" );
729 return result;
730}
731
732
733
734
735
736
737
738extern int __inline__ ffs (int x)
739{
740 int r;
741
742 if (x == 0)
743 return 0;
744 __asm__(" slr %0,%0\n"
745 " tml %1,0xffff\n"
746 " jnz 0f\n"
747 " ahi %0,16\n"
748 " srl %1,16\n"
749 "0: tml %1,0x00ff\n"
750 " jnz 1f\n"
751 " ahi %0,8\n"
752 " srl %1,8\n"
753 "1: tml %1,0x000f\n"
754 " jnz 2f\n"
755 " ahi %0,4\n"
756 " srl %1,4\n"
757 "2: tml %1,0x0003\n"
758 " jnz 3f\n"
759 " ahi %0,2\n"
760 " srl %1,2\n"
761 "3: tml %1,0x0001\n"
762 " jnz 4f\n"
763 " ahi %0,1\n"
764 "4:"
765 : "=&d" (r), "+d" (x) : : "cc" );
766 return r+1;
767}
768
769
770
771
772
773
774#define hweight32(x) generic_hweight32(x)
775#define hweight16(x) generic_hweight16(x)
776#define hweight8(x) generic_hweight8(x)
777
778
779#ifdef __KERNEL__
780
781
782
783
784
785
786
787
788
789
790
791#define ext2_set_bit(nr, addr) test_and_set_bit((nr)^56, addr)
792#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr)^56, addr)
793#define ext2_test_bit(nr, addr) test_bit((nr)^56, addr)
794static __inline__ unsigned long
795ext2_find_first_zero_bit(void *vaddr, unsigned long size)
796{
797 unsigned long res, cmp, count;
798
799 if (!size)
800 return 0;
801 __asm__(" lghi %1,-1\n"
802 " lgr %2,%3\n"
803 " aghi %2,63\n"
804 " srlg %2,%2,6\n"
805 " slgr %0,%0\n"
806 "0: clg %1,0(%0,%4)\n"
807 " jne 1f\n"
808 " aghi %0,8\n"
809 " brct %2,0b\n"
810 " lgr %0,%3\n"
811 " j 5f\n"
812 "1: cl %1,0(%0,%4)\n"
813 " jne 2f\n"
814 " aghi %0,4\n"
815 "2: l %2,0(%0,%4)\n"
816 " sllg %0,%0,3\n"
817 " aghi %0,24\n"
818 " lghi %1,0xff\n"
819 " tmlh %2,0xffff\n"
820 " jo 3f\n"
821 " aghi %0,-16\n"
822 " srl %2,16\n"
823 "3: tmll %2,0xff00\n"
824 " jo 4f\n"
825 " aghi %0,-8\n"
826 " srl %2,8\n"
827 "4: ngr %2,%1\n"
828 " ic %2,0(%2,%5)\n"
829 " algr %0,%2\n"
830 "5:"
831 : "=&a" (res), "=&d" (cmp), "=&a" (count)
832 : "a" (size), "a" (vaddr), "a" (&_zb_findmap) : "cc" );
833 return (res < size) ? res : size;
834}
835
836static __inline__ unsigned long
837ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
838{
839 unsigned long *addr = vaddr;
840 unsigned long *p = addr + (offset >> 6);
841 unsigned long word, reg;
842 unsigned long bit = offset & 63UL, res;
843
844 if (offset >= size)
845 return size;
846
847 if (bit) {
848 __asm__(" lrvg %0,%1"
849 : "=a" (word) : "m" (*p) );
850 word >>= bit;
851 res = bit;
852
853 __asm__(" lghi %2,0xff\n"
854 " tmll %1,0xffff\n"
855 " jno 2f\n"
856 " ahi %0,16\n"
857 " srlg %1,%1,16\n"
858 "0: tmll %1,0xffff\n"
859 " jno 2f\n"
860 " ahi %0,16\n"
861 " srlg %1,%1,16\n"
862 "1: tmll %1,0xffff\n"
863 " jno 2f\n"
864 " ahi %0,16\n"
865 " srl %1,16\n"
866 "2: tmll %1,0x00ff\n"
867 " jno 3f\n"
868 " ahi %0,8\n"
869 " srl %1,8\n"
870 "3: ngr %1,%2\n"
871 " ic %1,0(%1,%3)\n"
872 " alr %0,%1"
873 : "+&d" (res), "+a" (word), "=&d" (reg)
874 : "a" (&_zb_findmap) : "cc" );
875 if (res < 64)
876 return (p - addr)*64 + res;
877 p++;
878 }
879
880 res = ext2_find_first_zero_bit (p, size - 64 * (p - addr));
881 return (p - addr) * 64 + res;
882}
883
884
885
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
893
894#endif
895