diff options
Diffstat (limited to 'include/asm-s390/bitops.h')
| -rw-r--r-- | include/asm-s390/bitops.h | 440 |
1 files changed, 140 insertions, 300 deletions
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 16bb08499c7f..8651524217fd 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h | |||
| @@ -527,13 +527,64 @@ __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { | |||
| 527 | __constant_test_bit((nr),(addr)) : \ | 527 | __constant_test_bit((nr),(addr)) : \ |
| 528 | __test_bit((nr),(addr)) ) | 528 | __test_bit((nr),(addr)) ) |
| 529 | 529 | ||
| 530 | #ifndef __s390x__ | 530 | /* |
| 531 | * ffz = Find First Zero in word. Undefined if no zero exists, | ||
| 532 | * so code should check against ~0UL first.. | ||
| 533 | */ | ||
| 534 | static inline unsigned long ffz(unsigned long word) | ||
| 535 | { | ||
| 536 | unsigned long bit = 0; | ||
| 537 | |||
| 538 | #ifdef __s390x__ | ||
| 539 | if (likely((word & 0xffffffff) == 0xffffffff)) { | ||
| 540 | word >>= 32; | ||
| 541 | bit += 32; | ||
| 542 | } | ||
| 543 | #endif | ||
| 544 | if (likely((word & 0xffff) == 0xffff)) { | ||
| 545 | word >>= 16; | ||
| 546 | bit += 16; | ||
| 547 | } | ||
| 548 | if (likely((word & 0xff) == 0xff)) { | ||
| 549 | word >>= 8; | ||
| 550 | bit += 8; | ||
| 551 | } | ||
| 552 | return bit + _zb_findmap[word & 0xff]; | ||
| 553 | } | ||
| 554 | |||
| 555 | /* | ||
| 556 | * __ffs = find first bit in word. Undefined if no bit exists, | ||
| 557 | * so code should check against 0UL first.. | ||
| 558 | */ | ||
| 559 | static inline unsigned long __ffs (unsigned long word) | ||
| 560 | { | ||
| 561 | unsigned long bit = 0; | ||
| 562 | |||
| 563 | #ifdef __s390x__ | ||
| 564 | if (likely((word & 0xffffffff) == 0)) { | ||
| 565 | word >>= 32; | ||
| 566 | bit += 32; | ||
| 567 | } | ||
| 568 | #endif | ||
| 569 | if (likely((word & 0xffff) == 0)) { | ||
| 570 | word >>= 16; | ||
| 571 | bit += 16; | ||
| 572 | } | ||
| 573 | if (likely((word & 0xff) == 0)) { | ||
| 574 | word >>= 8; | ||
| 575 | bit += 8; | ||
| 576 | } | ||
| 577 | return bit + _sb_findmap[word & 0xff]; | ||
| 578 | } | ||
| 531 | 579 | ||
| 532 | /* | 580 | /* |
| 533 | * Find-bit routines.. | 581 | * Find-bit routines.. |
| 534 | */ | 582 | */ |
| 583 | |||
| 584 | #ifndef __s390x__ | ||
| 585 | |||
| 535 | static inline int | 586 | static inline int |
| 536 | find_first_zero_bit(const unsigned long * addr, unsigned int size) | 587 | find_first_zero_bit(const unsigned long * addr, unsigned long size) |
| 537 | { | 588 | { |
| 538 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | 589 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; |
| 539 | unsigned long cmp, count; | 590 | unsigned long cmp, count; |
| @@ -548,7 +599,7 @@ find_first_zero_bit(const unsigned long * addr, unsigned int size) | |||
| 548 | " srl %2,5\n" | 599 | " srl %2,5\n" |
| 549 | "0: c %1,0(%0,%4)\n" | 600 | "0: c %1,0(%0,%4)\n" |
| 550 | " jne 1f\n" | 601 | " jne 1f\n" |
| 551 | " ahi %0,4\n" | 602 | " la %0,4(%0)\n" |
| 552 | " brct %2,0b\n" | 603 | " brct %2,0b\n" |
| 553 | " lr %0,%3\n" | 604 | " lr %0,%3\n" |
| 554 | " j 4f\n" | 605 | " j 4f\n" |
| @@ -574,7 +625,7 @@ find_first_zero_bit(const unsigned long * addr, unsigned int size) | |||
| 574 | } | 625 | } |
| 575 | 626 | ||
| 576 | static inline int | 627 | static inline int |
| 577 | find_first_bit(const unsigned long * addr, unsigned int size) | 628 | find_first_bit(const unsigned long * addr, unsigned long size) |
| 578 | { | 629 | { |
| 579 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | 630 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; |
| 580 | unsigned long cmp, count; | 631 | unsigned long cmp, count; |
| @@ -589,7 +640,7 @@ find_first_bit(const unsigned long * addr, unsigned int size) | |||
| 589 | " srl %2,5\n" | 640 | " srl %2,5\n" |
| 590 | "0: c %1,0(%0,%4)\n" | 641 | "0: c %1,0(%0,%4)\n" |
| 591 | " jne 1f\n" | 642 | " jne 1f\n" |
| 592 | " ahi %0,4\n" | 643 | " la %0,4(%0)\n" |
| 593 | " brct %2,0b\n" | 644 | " brct %2,0b\n" |
| 594 | " lr %0,%3\n" | 645 | " lr %0,%3\n" |
| 595 | " j 4f\n" | 646 | " j 4f\n" |
| @@ -614,89 +665,8 @@ find_first_bit(const unsigned long * addr, unsigned int size) | |||
| 614 | return (res < size) ? res : size; | 665 | return (res < size) ? res : size; |
| 615 | } | 666 | } |
| 616 | 667 | ||
| 617 | static inline int | ||
| 618 | find_next_zero_bit (const unsigned long * addr, int size, int offset) | ||
| 619 | { | ||
| 620 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | ||
| 621 | unsigned long bitvec, reg; | ||
| 622 | int set, bit = offset & 31, res; | ||
| 623 | |||
| 624 | if (bit) { | ||
| 625 | /* | ||
| 626 | * Look for zero in first word | ||
| 627 | */ | ||
| 628 | bitvec = (*p) >> bit; | ||
| 629 | __asm__(" slr %0,%0\n" | ||
| 630 | " lhi %2,0xff\n" | ||
| 631 | " tml %1,0xffff\n" | ||
| 632 | " jno 0f\n" | ||
| 633 | " ahi %0,16\n" | ||
| 634 | " srl %1,16\n" | ||
| 635 | "0: tml %1,0x00ff\n" | ||
| 636 | " jno 1f\n" | ||
| 637 | " ahi %0,8\n" | ||
| 638 | " srl %1,8\n" | ||
| 639 | "1: nr %1,%2\n" | ||
| 640 | " ic %1,0(%1,%3)\n" | ||
| 641 | " alr %0,%1" | ||
| 642 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
| 643 | : "a" (&_zb_findmap) : "cc" ); | ||
| 644 | if (set < (32 - bit)) | ||
| 645 | return set + offset; | ||
| 646 | offset += 32 - bit; | ||
| 647 | p++; | ||
| 648 | } | ||
| 649 | /* | ||
| 650 | * No zero yet, search remaining full words for a zero | ||
| 651 | */ | ||
| 652 | res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); | ||
| 653 | return (offset + res); | ||
| 654 | } | ||
| 655 | |||
| 656 | static inline int | ||
| 657 | find_next_bit (const unsigned long * addr, int size, int offset) | ||
| 658 | { | ||
| 659 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | ||
| 660 | unsigned long bitvec, reg; | ||
| 661 | int set, bit = offset & 31, res; | ||
| 662 | |||
| 663 | if (bit) { | ||
| 664 | /* | ||
| 665 | * Look for set bit in first word | ||
| 666 | */ | ||
| 667 | bitvec = (*p) >> bit; | ||
| 668 | __asm__(" slr %0,%0\n" | ||
| 669 | " lhi %2,0xff\n" | ||
| 670 | " tml %1,0xffff\n" | ||
| 671 | " jnz 0f\n" | ||
| 672 | " ahi %0,16\n" | ||
| 673 | " srl %1,16\n" | ||
| 674 | "0: tml %1,0x00ff\n" | ||
| 675 | " jnz 1f\n" | ||
| 676 | " ahi %0,8\n" | ||
| 677 | " srl %1,8\n" | ||
| 678 | "1: nr %1,%2\n" | ||
| 679 | " ic %1,0(%1,%3)\n" | ||
| 680 | " alr %0,%1" | ||
| 681 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
| 682 | : "a" (&_sb_findmap) : "cc" ); | ||
| 683 | if (set < (32 - bit)) | ||
| 684 | return set + offset; | ||
| 685 | offset += 32 - bit; | ||
| 686 | p++; | ||
| 687 | } | ||
| 688 | /* | ||
| 689 | * No set bit yet, search remaining full words for a bit | ||
| 690 | */ | ||
| 691 | res = find_first_bit (p, size - 32 * (p - (unsigned long *) addr)); | ||
| 692 | return (offset + res); | ||
| 693 | } | ||
| 694 | |||
| 695 | #else /* __s390x__ */ | 668 | #else /* __s390x__ */ |
| 696 | 669 | ||
| 697 | /* | ||
| 698 | * Find-bit routines.. | ||
| 699 | */ | ||
| 700 | static inline unsigned long | 670 | static inline unsigned long |
| 701 | find_first_zero_bit(const unsigned long * addr, unsigned long size) | 671 | find_first_zero_bit(const unsigned long * addr, unsigned long size) |
| 702 | { | 672 | { |
| @@ -712,7 +682,7 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size) | |||
| 712 | " srlg %2,%2,6\n" | 682 | " srlg %2,%2,6\n" |
| 713 | "0: cg %1,0(%0,%4)\n" | 683 | "0: cg %1,0(%0,%4)\n" |
| 714 | " jne 1f\n" | 684 | " jne 1f\n" |
| 715 | " aghi %0,8\n" | 685 | " la %0,8(%0)\n" |
| 716 | " brct %2,0b\n" | 686 | " brct %2,0b\n" |
| 717 | " lgr %0,%3\n" | 687 | " lgr %0,%3\n" |
| 718 | " j 5f\n" | 688 | " j 5f\n" |
| @@ -785,143 +755,66 @@ find_first_bit(const unsigned long * addr, unsigned long size) | |||
| 785 | return (res < size) ? res : size; | 755 | return (res < size) ? res : size; |
| 786 | } | 756 | } |
| 787 | 757 | ||
| 788 | static inline unsigned long | ||
| 789 | find_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset) | ||
| 790 | { | ||
| 791 | unsigned long * p = ((unsigned long *) addr) + (offset >> 6); | ||
| 792 | unsigned long bitvec, reg; | ||
| 793 | unsigned long set, bit = offset & 63, res; | ||
| 794 | |||
| 795 | if (bit) { | ||
| 796 | /* | ||
| 797 | * Look for zero in first word | ||
| 798 | */ | ||
| 799 | bitvec = (*p) >> bit; | ||
| 800 | __asm__(" lhi %2,-1\n" | ||
| 801 | " slgr %0,%0\n" | ||
| 802 | " clr %1,%2\n" | ||
| 803 | " jne 0f\n" | ||
| 804 | " aghi %0,32\n" | ||
| 805 | " srlg %1,%1,32\n" | ||
| 806 | "0: lghi %2,0xff\n" | ||
| 807 | " tmll %1,0xffff\n" | ||
| 808 | " jno 1f\n" | ||
| 809 | " aghi %0,16\n" | ||
| 810 | " srlg %1,%1,16\n" | ||
| 811 | "1: tmll %1,0x00ff\n" | ||
| 812 | " jno 2f\n" | ||
| 813 | " aghi %0,8\n" | ||
| 814 | " srlg %1,%1,8\n" | ||
| 815 | "2: ngr %1,%2\n" | ||
| 816 | " ic %1,0(%1,%3)\n" | ||
| 817 | " algr %0,%1" | ||
| 818 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
| 819 | : "a" (&_zb_findmap) : "cc" ); | ||
| 820 | if (set < (64 - bit)) | ||
| 821 | return set + offset; | ||
| 822 | offset += 64 - bit; | ||
| 823 | p++; | ||
| 824 | } | ||
| 825 | /* | ||
| 826 | * No zero yet, search remaining full words for a zero | ||
| 827 | */ | ||
| 828 | res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr)); | ||
| 829 | return (offset + res); | ||
| 830 | } | ||
| 831 | |||
| 832 | static inline unsigned long | ||
| 833 | find_next_bit (const unsigned long * addr, unsigned long size, unsigned long offset) | ||
| 834 | { | ||
| 835 | unsigned long * p = ((unsigned long *) addr) + (offset >> 6); | ||
| 836 | unsigned long bitvec, reg; | ||
| 837 | unsigned long set, bit = offset & 63, res; | ||
| 838 | |||
| 839 | if (bit) { | ||
| 840 | /* | ||
| 841 | * Look for zero in first word | ||
| 842 | */ | ||
| 843 | bitvec = (*p) >> bit; | ||
| 844 | __asm__(" slgr %0,%0\n" | ||
| 845 | " ltr %1,%1\n" | ||
| 846 | " jnz 0f\n" | ||
| 847 | " aghi %0,32\n" | ||
| 848 | " srlg %1,%1,32\n" | ||
| 849 | "0: lghi %2,0xff\n" | ||
| 850 | " tmll %1,0xffff\n" | ||
| 851 | " jnz 1f\n" | ||
| 852 | " aghi %0,16\n" | ||
| 853 | " srlg %1,%1,16\n" | ||
| 854 | "1: tmll %1,0x00ff\n" | ||
| 855 | " jnz 2f\n" | ||
| 856 | " aghi %0,8\n" | ||
| 857 | " srlg %1,%1,8\n" | ||
| 858 | "2: ngr %1,%2\n" | ||
| 859 | " ic %1,0(%1,%3)\n" | ||
| 860 | " algr %0,%1" | ||
| 861 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
| 862 | : "a" (&_sb_findmap) : "cc" ); | ||
| 863 | if (set < (64 - bit)) | ||
| 864 | return set + offset; | ||
| 865 | offset += 64 - bit; | ||
| 866 | p++; | ||
| 867 | } | ||
| 868 | /* | ||
| 869 | * No set bit yet, search remaining full words for a bit | ||
| 870 | */ | ||
| 871 | res = find_first_bit (p, size - 64 * (p - (unsigned long *) addr)); | ||
| 872 | return (offset + res); | ||
| 873 | } | ||
| 874 | |||
| 875 | #endif /* __s390x__ */ | 758 | #endif /* __s390x__ */ |
| 876 | 759 | ||
| 877 | /* | 760 | static inline int |
| 878 | * ffz = Find First Zero in word. Undefined if no zero exists, | 761 | find_next_zero_bit (const unsigned long * addr, unsigned long size, |
| 879 | * so code should check against ~0UL first.. | 762 | unsigned long offset) |
| 880 | */ | ||
| 881 | static inline unsigned long ffz(unsigned long word) | ||
| 882 | { | 763 | { |
| 883 | unsigned long bit = 0; | 764 | const unsigned long *p; |
| 884 | 765 | unsigned long bit, set; | |
| 885 | #ifdef __s390x__ | 766 | |
| 886 | if (likely((word & 0xffffffff) == 0xffffffff)) { | 767 | if (offset >= size) |
| 887 | word >>= 32; | 768 | return size; |
| 888 | bit += 32; | 769 | bit = offset & (__BITOPS_WORDSIZE - 1); |
| 889 | } | 770 | offset -= bit; |
| 890 | #endif | 771 | size -= offset; |
| 891 | if (likely((word & 0xffff) == 0xffff)) { | 772 | p = addr + offset / __BITOPS_WORDSIZE; |
| 892 | word >>= 16; | 773 | if (bit) { |
| 893 | bit += 16; | 774 | /* |
| 775 | * s390 version of ffz returns __BITOPS_WORDSIZE | ||
| 776 | * if no zero bit is present in the word. | ||
| 777 | */ | ||
| 778 | set = ffz(*p >> bit) + bit; | ||
| 779 | if (set >= size) | ||
| 780 | return size + offset; | ||
| 781 | if (set < __BITOPS_WORDSIZE) | ||
| 782 | return set + offset; | ||
| 783 | offset += __BITOPS_WORDSIZE; | ||
| 784 | size -= __BITOPS_WORDSIZE; | ||
| 785 | p++; | ||
| 894 | } | 786 | } |
| 895 | if (likely((word & 0xff) == 0xff)) { | 787 | return offset + find_first_zero_bit(p, size); |
| 896 | word >>= 8; | ||
| 897 | bit += 8; | ||
| 898 | } | ||
| 899 | return bit + _zb_findmap[word & 0xff]; | ||
| 900 | } | 788 | } |
| 901 | 789 | ||
| 902 | /* | 790 | static inline int |
| 903 | * __ffs = find first bit in word. Undefined if no bit exists, | 791 | find_next_bit (const unsigned long * addr, unsigned long size, |
| 904 | * so code should check against 0UL first.. | 792 | unsigned long offset) |
| 905 | */ | ||
| 906 | static inline unsigned long __ffs (unsigned long word) | ||
| 907 | { | 793 | { |
| 908 | unsigned long bit = 0; | 794 | const unsigned long *p; |
| 909 | 795 | unsigned long bit, set; | |
| 910 | #ifdef __s390x__ | 796 | |
| 911 | if (likely((word & 0xffffffff) == 0)) { | 797 | if (offset >= size) |
| 912 | word >>= 32; | 798 | return size; |
| 913 | bit += 32; | 799 | bit = offset & (__BITOPS_WORDSIZE - 1); |
| 800 | offset -= bit; | ||
| 801 | size -= offset; | ||
| 802 | p = addr + offset / __BITOPS_WORDSIZE; | ||
| 803 | if (bit) { | ||
| 804 | /* | ||
| 805 | * s390 version of __ffs returns __BITOPS_WORDSIZE | ||
| 806 | * if no one bit is present in the word. | ||
| 807 | */ | ||
| 808 | set = __ffs(*p & (~0UL << bit)); | ||
| 809 | if (set >= size) | ||
| 810 | return size + offset; | ||
| 811 | if (set < __BITOPS_WORDSIZE) | ||
| 812 | return set + offset; | ||
| 813 | offset += __BITOPS_WORDSIZE; | ||
| 814 | size -= __BITOPS_WORDSIZE; | ||
| 815 | p++; | ||
| 914 | } | 816 | } |
| 915 | #endif | 817 | return offset + find_first_bit(p, size); |
| 916 | if (likely((word & 0xffff) == 0)) { | ||
| 917 | word >>= 16; | ||
| 918 | bit += 16; | ||
| 919 | } | ||
| 920 | if (likely((word & 0xff) == 0)) { | ||
| 921 | word >>= 8; | ||
| 922 | bit += 8; | ||
| 923 | } | ||
| 924 | return bit + _sb_findmap[word & 0xff]; | ||
| 925 | } | 818 | } |
| 926 | 819 | ||
| 927 | /* | 820 | /* |
| @@ -1031,49 +924,6 @@ ext2_find_first_zero_bit(void *vaddr, unsigned int size) | |||
| 1031 | return (res < size) ? res : size; | 924 | return (res < size) ? res : size; |
| 1032 | } | 925 | } |
| 1033 | 926 | ||
| 1034 | static inline int | ||
| 1035 | ext2_find_next_zero_bit(void *vaddr, unsigned int size, unsigned offset) | ||
| 1036 | { | ||
| 1037 | unsigned long *addr = vaddr; | ||
| 1038 | unsigned long *p = addr + (offset >> 5); | ||
| 1039 | unsigned long word, reg; | ||
| 1040 | unsigned int bit = offset & 31UL, res; | ||
| 1041 | |||
| 1042 | if (offset >= size) | ||
| 1043 | return size; | ||
| 1044 | |||
| 1045 | if (bit) { | ||
| 1046 | __asm__(" ic %0,0(%1)\n" | ||
| 1047 | " icm %0,2,1(%1)\n" | ||
| 1048 | " icm %0,4,2(%1)\n" | ||
| 1049 | " icm %0,8,3(%1)" | ||
| 1050 | : "=&a" (word) : "a" (p) : "cc" ); | ||
| 1051 | word >>= bit; | ||
| 1052 | res = bit; | ||
| 1053 | /* Look for zero in first longword */ | ||
| 1054 | __asm__(" lhi %2,0xff\n" | ||
| 1055 | " tml %1,0xffff\n" | ||
| 1056 | " jno 0f\n" | ||
| 1057 | " ahi %0,16\n" | ||
| 1058 | " srl %1,16\n" | ||
| 1059 | "0: tml %1,0x00ff\n" | ||
| 1060 | " jno 1f\n" | ||
| 1061 | " ahi %0,8\n" | ||
| 1062 | " srl %1,8\n" | ||
| 1063 | "1: nr %1,%2\n" | ||
| 1064 | " ic %1,0(%1,%3)\n" | ||
| 1065 | " alr %0,%1" | ||
| 1066 | : "+&d" (res), "+&a" (word), "=&d" (reg) | ||
| 1067 | : "a" (&_zb_findmap) : "cc" ); | ||
| 1068 | if (res < 32) | ||
| 1069 | return (p - addr)*32 + res; | ||
| 1070 | p++; | ||
| 1071 | } | ||
| 1072 | /* No zero yet, search remaining full bytes for a zero */ | ||
| 1073 | res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); | ||
| 1074 | return (p - addr) * 32 + res; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | #else /* __s390x__ */ | 927 | #else /* __s390x__ */ |
| 1078 | 928 | ||
| 1079 | static inline unsigned long | 929 | static inline unsigned long |
| @@ -1120,56 +970,46 @@ ext2_find_first_zero_bit(void *vaddr, unsigned long size) | |||
| 1120 | return (res < size) ? res : size; | 970 | return (res < size) ? res : size; |
| 1121 | } | 971 | } |
| 1122 | 972 | ||
| 1123 | static inline unsigned long | 973 | #endif /* __s390x__ */ |
| 974 | |||
| 975 | static inline int | ||
| 1124 | ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) | 976 | ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) |
| 1125 | { | 977 | { |
| 1126 | unsigned long *addr = vaddr; | 978 | unsigned long *addr = vaddr, *p; |
| 1127 | unsigned long *p = addr + (offset >> 6); | 979 | unsigned long word, bit, set; |
| 1128 | unsigned long word, reg; | ||
| 1129 | unsigned long bit = offset & 63UL, res; | ||
| 1130 | 980 | ||
| 1131 | if (offset >= size) | 981 | if (offset >= size) |
| 1132 | return size; | 982 | return size; |
| 1133 | 983 | bit = offset & (__BITOPS_WORDSIZE - 1); | |
| 984 | offset -= bit; | ||
| 985 | size -= offset; | ||
| 986 | p = addr + offset / __BITOPS_WORDSIZE; | ||
| 1134 | if (bit) { | 987 | if (bit) { |
| 1135 | __asm__(" lrvg %0,%1" /* load reversed, neat instruction */ | 988 | #ifndef __s390x__ |
| 1136 | : "=a" (word) : "m" (*p) ); | 989 | asm(" ic %0,0(%1)\n" |
| 1137 | word >>= bit; | 990 | " icm %0,2,1(%1)\n" |
| 1138 | res = bit; | 991 | " icm %0,4,2(%1)\n" |
| 1139 | /* Look for zero in first 8 byte word */ | 992 | " icm %0,8,3(%1)" |
| 1140 | __asm__(" lghi %2,0xff\n" | 993 | : "=&a" (word) : "a" (p), "m" (*p) : "cc" ); |
| 1141 | " tmll %1,0xffff\n" | 994 | #else |
| 1142 | " jno 2f\n" | 995 | asm(" lrvg %0,%1" : "=a" (word) : "m" (*p) ); |
| 1143 | " ahi %0,16\n" | 996 | #endif |
| 1144 | " srlg %1,%1,16\n" | 997 | /* |
| 1145 | "0: tmll %1,0xffff\n" | 998 | * s390 version of ffz returns __BITOPS_WORDSIZE |
| 1146 | " jno 2f\n" | 999 | * if no zero bit is present in the word. |
| 1147 | " ahi %0,16\n" | 1000 | */ |
| 1148 | " srlg %1,%1,16\n" | 1001 | set = ffz(word >> bit) + bit; |
| 1149 | "1: tmll %1,0xffff\n" | 1002 | if (set >= size) |
| 1150 | " jno 2f\n" | 1003 | return size + offset; |
| 1151 | " ahi %0,16\n" | 1004 | if (set < __BITOPS_WORDSIZE) |
| 1152 | " srl %1,16\n" | 1005 | return set + offset; |
| 1153 | "2: tmll %1,0x00ff\n" | 1006 | offset += __BITOPS_WORDSIZE; |
| 1154 | " jno 3f\n" | 1007 | size -= __BITOPS_WORDSIZE; |
| 1155 | " ahi %0,8\n" | 1008 | p++; |
| 1156 | " srl %1,8\n" | ||
| 1157 | "3: ngr %1,%2\n" | ||
| 1158 | " ic %1,0(%1,%3)\n" | ||
| 1159 | " alr %0,%1" | ||
| 1160 | : "+&d" (res), "+a" (word), "=&d" (reg) | ||
| 1161 | : "a" (&_zb_findmap) : "cc" ); | ||
| 1162 | if (res < 64) | ||
| 1163 | return (p - addr)*64 + res; | ||
| 1164 | p++; | ||
| 1165 | } | 1009 | } |
| 1166 | /* No zero yet, search remaining full bytes for a zero */ | 1010 | return offset + ext2_find_first_zero_bit(p, size); |
| 1167 | res = ext2_find_first_zero_bit (p, size - 64 * (p - addr)); | ||
| 1168 | return (p - addr) * 64 + res; | ||
| 1169 | } | 1011 | } |
| 1170 | 1012 | ||
| 1171 | #endif /* __s390x__ */ | ||
| 1172 | |||
| 1173 | /* Bitmap functions for the minix filesystem. */ | 1013 | /* Bitmap functions for the minix filesystem. */ |
| 1174 | /* FIXME !!! */ | 1014 | /* FIXME !!! */ |
| 1175 | #define minix_test_and_set_bit(nr,addr) \ | 1015 | #define minix_test_and_set_bit(nr,addr) \ |
