954 bitAnd:anInteger |
954 bitAnd:anInteger |
955 "return the bitwise-and of the receiver and the argument, anInteger" |
955 "return the bitwise-and of the receiver and the argument, anInteger" |
956 |
956 |
957 %{ /* NOCONTEXT */ |
957 %{ /* NOCONTEXT */ |
958 if (__isSmallInteger(anInteger)) { |
958 if (__isSmallInteger(anInteger)) { |
959 INT v2 = __intVal(anInteger); |
959 INT v2 = __intVal(anInteger); |
960 INT v1; |
960 INT v1; |
961 #if defined(__LSBFIRST__) |
961 #if defined(__LSBFIRST__) |
962 v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray))); |
962 v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray))); |
963 #else |
963 #else |
964 unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray))); |
964 unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray))); |
965 |
965 |
966 v1 = digits[0] & 0xFF; |
966 v1 = digits[0] & 0xFF; |
967 v1 = v1 | ((digits[1] & 0xFF)<<8); |
967 v1 = v1 | ((digits[1] & 0xFF)<<8); |
968 v1 = v1 | ((digits[2] & 0xFF)<<16); |
968 v1 = v1 | ((digits[2] & 0xFF)<<16); |
969 v1 = v1 | ((digits[3] & 0xFF)<<24); |
969 v1 = v1 | ((digits[3] & 0xFF)<<24); |
970 # if (__POINTER_SIZE__ == 8) |
970 # if (__POINTER_SIZE__ == 8) |
971 v1 = v1 | ((digits[4] & 0xFF)<<32); |
971 v1 = v1 | ((digits[4] & 0xFF)<<32); |
972 v1 = v1 | ((digits[5] & 0xFF)<<40); |
972 v1 = v1 | ((digits[5] & 0xFF)<<40); |
973 v1 = v1 | ((digits[6] & 0xFF)<<48); |
973 v1 = v1 | ((digits[6] & 0xFF)<<48); |
974 v1 = v1 | ((digits[7] & 0xFF)<<56); |
974 v1 = v1 | ((digits[7] & 0xFF)<<56); |
975 #endif |
975 #endif |
976 #endif |
976 #endif |
977 RETURN ( __mkSmallInteger(v1 & v2) ); |
977 RETURN ( __mkSmallInteger(v1 & v2) ); |
978 } |
978 } |
979 |
979 |
980 if (__isLargeInteger(anInteger)) { |
980 if (__isLargeInteger(anInteger)) { |
981 OBJ _myDigitByteArray = __INST(digitByteArray); |
981 OBJ _myDigitByteArray = __INST(digitByteArray); |
982 OBJ _otherDigitByteArray = __LargeIntegerInstPtr(anInteger)->l_digits; |
982 OBJ _otherDigitByteArray = __LargeIntegerInstPtr(anInteger)->l_digits; |
983 |
983 |
984 if (__isByteArray(_myDigitByteArray) |
984 if (__isByteArray(_myDigitByteArray) |
985 && __isByteArray(_otherDigitByteArray)) { |
985 && __isByteArray(_otherDigitByteArray)) { |
986 unsigned char *pDigits1, *pDigits2; |
986 unsigned char *pDigits1, *pDigits2; |
987 int size1, size2, minSize; |
987 int size1, size2, minSize; |
988 union { |
988 union { |
989 double d; // force align |
989 double d; // force align |
990 unsigned char chars[2048+8]; |
990 unsigned char chars[2048+8]; |
991 } buffer; |
991 } buffer; |
992 unsigned char *pRslt; |
992 unsigned char *pRslt; |
993 OBJ newDigits, newLarge; |
993 OBJ newDigits, newLarge; |
994 |
994 |
995 pDigits1 = (unsigned char *)(__byteArrayVal(_myDigitByteArray)); |
995 pDigits1 = (unsigned char *)(__byteArrayVal(_myDigitByteArray)); |
996 pDigits2 = (unsigned char *)(__byteArrayVal(_otherDigitByteArray)); |
996 pDigits2 = (unsigned char *)(__byteArrayVal(_otherDigitByteArray)); |
997 pRslt = (void *)(buffer.chars); |
997 pRslt = (void *)(buffer.chars); |
998 |
998 |
999 size1 = __byteArraySize(_myDigitByteArray); |
999 size1 = __byteArraySize(_myDigitByteArray); |
1000 size2 = __byteArraySize(_otherDigitByteArray); |
1000 size2 = __byteArraySize(_otherDigitByteArray); |
1001 minSize = (size1 < size2) ? size1 : size2; |
1001 minSize = (size1 < size2) ? size1 : size2; |
1002 if (minSize <= sizeof(buffer.chars)) { |
1002 if (minSize <= sizeof(buffer.chars)) { |
1003 int n = minSize; |
1003 int n = minSize; |
1004 |
1004 |
1005 /* not worth it - but a nice try and first testbed for mmx... */ |
1005 /* not worth it - but a nice try and first testbed for mmx... */ |
1006 #define x__USE_MMX__ |
1006 #define x__USE_MMX__ |
1007 #ifdef __USE_MMX__ |
1007 #ifdef __USE_MMX__ |
1008 #ifdef __VISUALC__ |
1008 #ifdef __VISUALC__ |
1009 if (((INT)pRslt & 7) == 0) { // 8-byte aligned |
1009 if (((INT)pRslt & 7) == 0) { // 8-byte aligned |
1010 if (((INT)pDigits1 & 7) == ((INT)pDigits2 & 7)) { // same align |
1010 if (((INT)pDigits1 & 7) == ((INT)pDigits2 & 7)) { // same align |
1011 while (((INT)pDigits1 & 7) && (n >= sizeof(int))) { |
1011 while (((INT)pDigits1 & 7) && (n >= sizeof(int))) { |
1012 ((int *)pRslt)[0] = ((int *)pDigits1)[0] & ((int *)pDigits2)[0]; |
1012 ((int *)pRslt)[0] = ((int *)pDigits1)[0] & ((int *)pDigits2)[0]; |
1013 pRslt += sizeof(int); |
1013 pRslt += sizeof(int); |
1014 pDigits1 += sizeof(int); |
1014 pDigits1 += sizeof(int); |
1015 pDigits2 += sizeof(int); |
1015 pDigits2 += sizeof(int); |
1016 pDigits2 += sizeof(int); |
1016 pDigits2 += sizeof(int); |
1017 n -= sizeof(int); |
1017 n -= sizeof(int); |
1018 } |
1018 } |
1019 for (; n >= 8; n -= 8) { |
1019 for (; n >= 8; n -= 8) { |
1020 __asm { |
1020 __asm { |
1021 mov eax, pDigits1 |
1021 mov eax, pDigits1 |
1022 movq mm0, [eax] |
1022 movq mm0, [eax] |
1023 mov eax, pDigits2 |
1023 mov eax, pDigits2 |
1024 movq mm1, [eax] |
1024 movq mm1, [eax] |
1025 pand mm0, mm1 |
1025 pand mm0, mm1 |
1026 mov eax, pRslt |
1026 mov eax, pRslt |
1027 movq [eax], mm0 |
1027 movq [eax], mm0 |
1028 } |
1028 } |
1029 pDigits1 += 8; |
1029 pDigits1 += 8; |
1030 pDigits2 += 8; |
1030 pDigits2 += 8; |
1031 pRslt += 8; |
1031 pRslt += 8; |
1032 } |
1032 } |
1033 __asm { |
1033 __asm { |
1034 emms ; switch back to FPU state. |
1034 emms ; switch back to FPU state. |
1035 } |
1035 } |
1036 } |
1036 } |
1037 } |
1037 } |
1038 #endif /* __VISUALC__ */ |
1038 #endif /* __VISUALC__ */ |
1039 #endif /* __USE_MMX__ */ |
1039 #endif /* __USE_MMX__ */ |
1040 |
1040 |
1041 for (; n >= sizeof(INT)*4; n -= sizeof(INT)*4) { |
1041 for (; n >= sizeof(INT)*4; n -= sizeof(INT)*4) { |
1042 ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0]; |
1042 ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0]; |
1043 ((INT *)pRslt)[1] = ((INT *)pDigits1)[1] & ((INT *)pDigits2)[1]; |
1043 ((INT *)pRslt)[1] = ((INT *)pDigits1)[1] & ((INT *)pDigits2)[1]; |
1044 ((INT *)pRslt)[2] = ((INT *)pDigits1)[2] & ((INT *)pDigits2)[2]; |
1044 ((INT *)pRslt)[2] = ((INT *)pDigits1)[2] & ((INT *)pDigits2)[2]; |
1045 ((INT *)pRslt)[3] = ((INT *)pDigits1)[3] & ((INT *)pDigits2)[3]; |
1045 ((INT *)pRslt)[3] = ((INT *)pDigits1)[3] & ((INT *)pDigits2)[3]; |
1046 pRslt += sizeof(INT)*4; |
1046 pRslt += sizeof(INT)*4; |
1047 pDigits1 += sizeof(INT)*4; |
1047 pDigits1 += sizeof(INT)*4; |
1048 pDigits2 += sizeof(INT)*4; |
1048 pDigits2 += sizeof(INT)*4; |
1049 } |
1049 } |
1050 for (; n >= sizeof(INT); n -= sizeof(INT)) { |
1050 for (; n >= sizeof(INT); n -= sizeof(INT)) { |
1051 ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0]; |
1051 ((INT *)pRslt)[0] = ((INT *)pDigits1)[0] & ((INT *)pDigits2)[0]; |
1052 pRslt += sizeof(INT); |
1052 pRslt += sizeof(INT); |
1053 pDigits1 += sizeof(INT); |
1053 pDigits1 += sizeof(INT); |
1054 pDigits2 += sizeof(INT); |
1054 pDigits2 += sizeof(INT); |
1055 } |
1055 } |
1056 for (; n > 0; n--) { |
1056 for (; n > 0; n--) { |
1057 *pRslt = *pDigits1 & *pDigits2; |
1057 *pRslt = *pDigits1 & *pDigits2; |
1058 pRslt++; |
1058 pRslt++; |
1059 pDigits1++; |
1059 pDigits1++; |
1060 pDigits2++; |
1060 pDigits2++; |
1061 } |
1061 } |
1062 // normalize |
1062 // normalize |
1063 while ((pRslt[-1]==0) && (pRslt > buffer.chars)) { |
1063 while ((pRslt[-1]==0) && (pRslt > buffer.chars)) { |
1064 pRslt--; |
1064 pRslt--; |
1065 } |
1065 } |
1066 |
1066 |
1067 // allocate result |
1067 // allocate result |
1068 n = pRslt-buffer.chars; |
1068 n = pRslt-buffer.chars; |
1069 if (n <= sizeof(INT)) { |
1069 if (n <= sizeof(INT)) { |
1070 INT val = 0; |
1070 INT val = 0; |
1071 |
1071 |
1072 // make it a smallInteger / 32bitInteger |
1072 // make it a smallInteger / 32bitInteger |
1073 while (n > 0) { |
1073 while (n > 0) { |
1074 val = (val << 8) + buffer.chars[--n]; |
1074 val = (val << 8) + buffer.chars[--n]; |
1075 } |
1075 } |
1076 RETURN (__MKUINT(val)); |
1076 RETURN (__MKUINT(val)); |
1077 } |
1077 } |
1078 newDigits = __MKBYTEARRAY(buffer.chars, n); |
1078 newDigits = __MKBYTEARRAY(buffer.chars, n); |
1079 if (newDigits) { |
1079 if (newDigits) { |
1080 __PROTECT__(newDigits); |
1080 __PROTECT__(newDigits); |
1081 newLarge = __STX___new(sizeof(struct __LargeInteger)); |
1081 newLarge = __STX___new(sizeof(struct __LargeInteger)); |
1082 __UNPROTECT__(newDigits); |
1082 __UNPROTECT__(newDigits); |
1083 if (newLarge) { |
1083 if (newLarge) { |
1084 __InstPtr(newLarge)->o_class = LargeInteger; __STORE(newLarge, LargeInteger); |
1084 __InstPtr(newLarge)->o_class = LargeInteger; __STORE(newLarge, LargeInteger); |
1085 __LargeIntegerInstPtr(newLarge)->l_digits = newDigits; __STORE(newLarge, newDigits); |
1085 __LargeIntegerInstPtr(newLarge)->l_digits = newDigits; __STORE(newLarge, newDigits); |
1086 __LargeIntegerInstPtr(newLarge)->l_sign = __MKSMALLINT(1); |
1086 __LargeIntegerInstPtr(newLarge)->l_sign = __MKSMALLINT(1); |
1087 RETURN (newLarge); |
1087 RETURN (newLarge); |
1088 } |
1088 } |
1089 } |
1089 } |
1090 } |
1090 } |
1091 } |
1091 } |
1092 } |
1092 } |
1093 %}. |
1093 %}. |
1094 ^ super bitAnd:anInteger |
1094 ^ super bitAnd:anInteger |
1095 |
1095 |
1096 " |
1096 " |
1816 |
1816 |
1817 %{ /* NOCONTEXT */ |
1817 %{ /* NOCONTEXT */ |
1818 OBJ t; |
1818 OBJ t; |
1819 |
1819 |
1820 if (__INST(sign) == __mkSmallInteger(0)) { |
1820 if (__INST(sign) == __mkSmallInteger(0)) { |
1821 RETURN (__mkSmallInteger(0)); |
1821 RETURN (__mkSmallInteger(0)); |
1822 } |
1822 } |
1823 |
1823 |
1824 t = __INST(digitByteArray); |
1824 t = __INST(digitByteArray); |
1825 if (__isByteArray(t)) { |
1825 if (__isByteArray(t)) { |
1826 unsigned char *__digitBytes = __ByteArrayInstPtr(t)->ba_element; |
1826 unsigned char *__digitBytes = __ByteArrayInstPtr(t)->ba_element; |
1827 int _idx, _idx0; |
1827 int _idx, _idx0; |
1828 INT _val; |
1828 INT _val; |
1829 |
1829 |
1830 _idx = _idx0 = __byteArraySize(t); |
1830 _idx = _idx0 = __byteArraySize(t); |
1831 while ((_idx > 0) && (__digitBytes[_idx - 1] == 0)) { |
1831 while ((_idx > 0) && (__digitBytes[_idx - 1] == 0)) { |
1832 _idx--; |
1832 _idx--; |
1833 } |
1833 } |
1834 #if __POINTER_SIZE__ == 8 |
1834 #if __POINTER_SIZE__ == 8 |
1835 switch (_idx) { |
1835 switch (_idx) { |
1836 case 8: |
1836 case 8: |
1837 _val = __digitBytes[7]; |
1837 _val = __digitBytes[7]; |
1838 if (_val <= 0x40) { |
1838 if (_val <= 0x40) { |
1839 _val = (_val<<8); |
1839 _val = (_val<<8); |
1840 _val = (_val + __digitBytes[6]) << 8; |
1840 _val = (_val + __digitBytes[6]) << 8; |
1841 _val = (_val + __digitBytes[5]) << 8; |
1841 _val = (_val + __digitBytes[5]) << 8; |
1842 _val = (_val + __digitBytes[4]) << 8; |
1842 _val = (_val + __digitBytes[4]) << 8; |
1843 _val = (_val + __digitBytes[3]) << 8; |
1843 _val = (_val + __digitBytes[3]) << 8; |
1844 _val = (_val + __digitBytes[2]) << 8; |
1844 _val = (_val + __digitBytes[2]) << 8; |
1845 _val = (_val + __digitBytes[1]) << 8; |
1845 _val = (_val + __digitBytes[1]) << 8; |
1846 _val += __digitBytes[0]; |
1846 _val += __digitBytes[0]; |
1847 if (__INST(sign) == __mkSmallInteger(-1)) |
1847 if (__INST(sign) == __mkSmallInteger(-1)) |
1848 _val = -_val; |
1848 _val = -_val; |
1849 if (__ISVALIDINTEGER(_val)) { |
1849 if (__ISVALIDINTEGER(_val)) { |
1850 RETURN (__mkSmallInteger(_val)); |
1850 RETURN (__mkSmallInteger(_val)); |
1851 } |
1851 } |
1852 } |
1852 } |
1853 break; |
1853 break; |
1854 case 7: |
1854 case 7: |
1855 # if defined(__LSBFIRST__) |
1855 # if defined(__LSBFIRST__) |
1856 _val = ((INT *)__digitBytes)[0] & 0x00FFFFFFFFFFFFFFL; |
1856 _val = ((INT *)__digitBytes)[0] & 0x00FFFFFFFFFFFFFFL; |
1857 # else |
1857 # else |
1858 _val = (__digitBytes[6]<<8); |
1858 _val = (__digitBytes[6]<<8); |
1859 _val = (_val + __digitBytes[5]) << 8; |
1859 _val = (_val + __digitBytes[5]) << 8; |
1860 _val = (_val + __digitBytes[4]) << 8; |
1860 _val = (_val + __digitBytes[4]) << 8; |
1861 _val = (_val + __digitBytes[3]) << 8; |
1861 _val = (_val + __digitBytes[3]) << 8; |
1862 _val = (_val + __digitBytes[2]) << 8; |
1862 _val = (_val + __digitBytes[2]) << 8; |
1863 _val = (_val + __digitBytes[1]) << 8; |
1863 _val = (_val + __digitBytes[1]) << 8; |
1864 _val += __digitBytes[0]; |
1864 _val += __digitBytes[0]; |
1865 # endif |
1865 # endif |
1866 if (__INST(sign) == __mkSmallInteger(-1)) |
1866 if (__INST(sign) == __mkSmallInteger(-1)) |
1867 _val = -_val; |
1867 _val = -_val; |
1868 RETURN (__mkSmallInteger(_val)); |
1868 RETURN (__mkSmallInteger(_val)); |
1869 case 6: |
1869 case 6: |
1870 # if defined(__LSBFIRST__) |
1870 # if defined(__LSBFIRST__) |
1871 _val = ((INT *)__digitBytes)[0] & 0x0000FFFFFFFFFFFFL; |
1871 _val = ((INT *)__digitBytes)[0] & 0x0000FFFFFFFFFFFFL; |
1872 # else |
1872 # else |
1873 _val = (__digitBytes[5]<<8); |
1873 _val = (__digitBytes[5]<<8); |
1874 _val = (_val + __digitBytes[4]) << 8; |
1874 _val = (_val + __digitBytes[4]) << 8; |
1875 _val = (_val + __digitBytes[3]) << 8; |
1875 _val = (_val + __digitBytes[3]) << 8; |
1876 _val = (_val + __digitBytes[2]) << 8; |
1876 _val = (_val + __digitBytes[2]) << 8; |
1877 _val = (_val + __digitBytes[1]) << 8; |
1877 _val = (_val + __digitBytes[1]) << 8; |
1878 _val += __digitBytes[0]; |
1878 _val += __digitBytes[0]; |
1879 # endif |
1879 # endif |
1880 if (__INST(sign) == __mkSmallInteger(-1)) |
1880 if (__INST(sign) == __mkSmallInteger(-1)) |
1881 _val = -_val; |
1881 _val = -_val; |
1882 RETURN (__mkSmallInteger(_val)); |
1882 RETURN (__mkSmallInteger(_val)); |
1883 case 5: |
1883 case 5: |
1884 # if defined(__LSBFIRST__) |
1884 # if defined(__LSBFIRST__) |
1885 _val = ((INT *)__digitBytes)[0] & 0x000000FFFFFFFFFFL; |
1885 _val = ((INT *)__digitBytes)[0] & 0x000000FFFFFFFFFFL; |
1886 # else |
1886 # else |
1887 _val = (__digitBytes[4]<<8); |
1887 _val = (__digitBytes[4]<<8); |
1888 _val = (_val + __digitBytes[3]) << 8; |
1888 _val = (_val + __digitBytes[3]) << 8; |
1889 _val = (_val + __digitBytes[2]) << 8; |
1889 _val = (_val + __digitBytes[2]) << 8; |
1890 _val = (_val + __digitBytes[1]) << 8; |
1890 _val = (_val + __digitBytes[1]) << 8; |
1891 _val += __digitBytes[0]; |
1891 _val += __digitBytes[0]; |
1892 # endif |
1892 # endif |
1893 if (__INST(sign) == __mkSmallInteger(-1)) |
1893 if (__INST(sign) == __mkSmallInteger(-1)) |
1894 _val = -_val; |
1894 _val = -_val; |
1895 RETURN (__mkSmallInteger(_val)); |
1895 RETURN (__mkSmallInteger(_val)); |
1896 case 4: |
1896 case 4: |
1897 # if defined(__LSBFIRST__) |
1897 # if defined(__LSBFIRST__) |
1898 _val = ((INT *)__digitBytes)[0] & 0x00000000FFFFFFFFL; |
1898 _val = ((INT *)__digitBytes)[0] & 0x00000000FFFFFFFFL; |
1899 # else |
1899 # else |
1900 _val = (__digitBytes[3]<<8); |
1900 _val = (__digitBytes[3]<<8); |
1901 _val = (_val + __digitBytes[2]) << 8; |
1901 _val = (_val + __digitBytes[2]) << 8; |
1902 _val = (_val + __digitBytes[1]) << 8; |
1902 _val = (_val + __digitBytes[1]) << 8; |
1903 _val += __digitBytes[0]; |
1903 _val += __digitBytes[0]; |
1904 # endif |
1904 # endif |
1905 if (__INST(sign) == __mkSmallInteger(-1)) |
1905 if (__INST(sign) == __mkSmallInteger(-1)) |
1906 _val = -_val; |
1906 _val = -_val; |
1907 RETURN (__mkSmallInteger(_val)); |
1907 RETURN (__mkSmallInteger(_val)); |
1908 case 3: |
1908 case 3: |
1909 # if defined(__LSBFIRST__) |
1909 # if defined(__LSBFIRST__) |
1910 _val = ((int *)__digitBytes)[0] & 0x00FFFFFF; |
1910 _val = ((int *)__digitBytes)[0] & 0x00FFFFFF; |
1911 # else |
1911 # else |
1912 _val = (__digitBytes[2]<<8); |
1912 _val = (__digitBytes[2]<<8); |
1913 _val = (_val + __digitBytes[1]) << 8; |
1913 _val = (_val + __digitBytes[1]) << 8; |
1914 _val += __digitBytes[0]; |
1914 _val += __digitBytes[0]; |
1915 # endif |
1915 # endif |
1916 if (__INST(sign) == __mkSmallInteger(-1)) |
1916 if (__INST(sign) == __mkSmallInteger(-1)) |
1917 _val = -_val; |
1917 _val = -_val; |
1918 RETURN (__mkSmallInteger(_val)); |
1918 RETURN (__mkSmallInteger(_val)); |
1919 case 2: |
1919 case 2: |
1920 # if defined(__LSBFIRST__) |
1920 # if defined(__LSBFIRST__) |
1921 _val = ((int *)__digitBytes)[0] & 0x0000FFFF; |
1921 _val = ((int *)__digitBytes)[0] & 0x0000FFFF; |
1922 # else |
1922 # else |
1923 _val = (__digitBytes[1]<<8) + __digitBytes[0]; |
1923 _val = (__digitBytes[1]<<8) + __digitBytes[0]; |
1924 # endif |
1924 # endif |
1925 if (__INST(sign) == __mkSmallInteger(-1)) |
1925 if (__INST(sign) == __mkSmallInteger(-1)) |
1926 _val = -_val; |
1926 _val = -_val; |
1927 RETURN (__mkSmallInteger(_val)); |
1927 RETURN (__mkSmallInteger(_val)); |
1928 case 1: |
1928 case 1: |
1929 _val = __digitBytes[0]; |
1929 _val = __digitBytes[0]; |
1930 if (__INST(sign) == __mkSmallInteger(-1)) |
1930 if (__INST(sign) == __mkSmallInteger(-1)) |
1931 _val = -_val; |
1931 _val = -_val; |
1932 RETURN (__mkSmallInteger(_val)); |
1932 RETURN (__mkSmallInteger(_val)); |
1933 case 0: |
1933 case 0: |
1934 RETURN (__mkSmallInteger(0)); |
1934 RETURN (__mkSmallInteger(0)); |
1935 |
1935 |
1936 } |
1936 } |
1937 #else |
1937 #else |
1938 if (_idx <= 4) { |
1938 if (_idx <= 4) { |
1939 if (_idx <= 2) { |
1939 if (_idx <= 2) { |
1940 if (_idx == 0) { |
1940 if (_idx == 0) { |
1941 RETURN (__mkSmallInteger(0)); |
1941 RETURN (__mkSmallInteger(0)); |
1942 } |
1942 } |
1943 if (_idx == 1) { |
1943 if (_idx == 1) { |
1944 _val = __digitBytes[0]; |
1944 _val = __digitBytes[0]; |
1945 if (__INST(sign) == __mkSmallInteger(-1)) |
1945 if (__INST(sign) == __mkSmallInteger(-1)) |
1946 _val = -_val; |
1946 _val = -_val; |
1947 RETURN (__mkSmallInteger(_val)); |
1947 RETURN (__mkSmallInteger(_val)); |
1948 } |
1948 } |
1949 # if defined(__LSBFIRST__) |
1949 # if defined(__LSBFIRST__) |
1950 _val = ((int *)__digitBytes)[0] & 0x0000FFFF; |
1950 _val = ((int *)__digitBytes)[0] & 0x0000FFFF; |
1951 # else |
1951 # else |
1952 _val = (__digitBytes[1]<<8) + __digitBytes[0]; |
1952 _val = (__digitBytes[1]<<8) + __digitBytes[0]; |
1953 # endif |
1953 # endif |
1954 if (__INST(sign) == __mkSmallInteger(-1)) |
1954 if (__INST(sign) == __mkSmallInteger(-1)) |
1955 _val = -_val; |
1955 _val = -_val; |
1956 RETURN (__mkSmallInteger(_val)); |
1956 RETURN (__mkSmallInteger(_val)); |
1957 } |
1957 } |
1958 if (_idx == 3) { |
1958 if (_idx == 3) { |
1959 # if defined(__LSBFIRST__) |
1959 # if defined(__LSBFIRST__) |
1960 _val = ((int *)__digitBytes)[0] & 0x00FFFFFF; |
1960 _val = ((int *)__digitBytes)[0] & 0x00FFFFFF; |
1961 # else |
1961 # else |
1962 _val = (((__digitBytes[2]<<8) + __digitBytes[1])<<8) + __digitBytes[0]; |
1962 _val = (((__digitBytes[2]<<8) + __digitBytes[1])<<8) + __digitBytes[0]; |
1963 # endif |
1963 # endif |
1964 if (__INST(sign) == __mkSmallInteger(-1)) |
1964 if (__INST(sign) == __mkSmallInteger(-1)) |
1965 _val = -_val; |
1965 _val = -_val; |
1966 RETURN (__mkSmallInteger(_val)); |
1966 RETURN (__mkSmallInteger(_val)); |
1967 } |
1967 } |
1968 _val = __digitBytes[3]; |
1968 _val = __digitBytes[3]; |
1969 if (_val <= 0x40) { |
1969 if (_val <= 0x40) { |
1970 # if defined(__LSBFIRST__) |
1970 # if defined(__LSBFIRST__) |
1971 _val = ((int *)__digitBytes)[0]; |
1971 _val = ((int *)__digitBytes)[0]; |
1972 # else |
1972 # else |
1973 _val = (((((_val<<8) + __digitBytes[2])<<8) + __digitBytes[1])<<8) + __digitBytes[0]; |
1973 _val = (((((_val<<8) + __digitBytes[2])<<8) + __digitBytes[1])<<8) + __digitBytes[0]; |
1974 # endif |
1974 # endif |
1975 if (__INST(sign) == __mkSmallInteger(-1)) |
1975 if (__INST(sign) == __mkSmallInteger(-1)) |
1976 _val = -_val; |
1976 _val = -_val; |
1977 if (__ISVALIDINTEGER(_val)) { |
1977 if (__ISVALIDINTEGER(_val)) { |
1978 RETURN (__mkSmallInteger(_val)); |
1978 RETURN (__mkSmallInteger(_val)); |
1979 } |
1979 } |
1980 } |
1980 } |
1981 } |
1981 } |
1982 #endif |
1982 #endif |
1983 |
1983 |
1984 if (_idx == _idx0) { |
1984 if (_idx == _idx0) { |
1985 RETURN (self); |
1985 RETURN (self); |
1986 } |
1986 } |
1987 |
1987 |
1988 /* |
1988 /* |
1989 * must copy & cut off some (zero)bytes |
1989 * must copy & cut off some (zero)bytes |
1990 */ |
1990 */ |
1991 { |
1991 { |
1992 OBJ newDigits; |
1992 OBJ newDigits; |
1993 OBJ oldDigits; |
1993 OBJ oldDigits; |
1994 |
1994 |
1995 /* |
1995 /* |
1996 * careful - there is no context here to protect |
1996 * careful - there is no context here to protect |
1997 * the receiver ... |
1997 * the receiver ... |
1998 */ |
1998 */ |
1999 __PROTECT__(self); |
1999 __PROTECT__(self); |
2000 __PROTECT__(__INST(digitByteArray)); |
2000 __PROTECT__(__INST(digitByteArray)); |
2001 newDigits = __BYTEARRAY_UNINITIALIZED_NEW_INT(_idx); |
2001 newDigits = __BYTEARRAY_UNINITIALIZED_NEW_INT(_idx); |
2002 __UNPROTECT__(oldDigits); |
2002 __UNPROTECT__(oldDigits); |
2003 __UNPROTECT__(self); |
2003 __UNPROTECT__(self); |
2004 if (newDigits) { |
2004 if (newDigits) { |
2005 bcopy(__ByteArrayInstPtr(oldDigits)->ba_element, |
2005 bcopy(__ByteArrayInstPtr(oldDigits)->ba_element, |
2006 __ByteArrayInstPtr(newDigits)->ba_element, |
2006 __ByteArrayInstPtr(newDigits)->ba_element, |
2007 _idx); |
2007 _idx); |
2008 __INST(digitByteArray) = newDigits; __STORE(self, newDigits); |
2008 __INST(digitByteArray) = newDigits; __STORE(self, newDigits); |
2009 RETURN (self); |
2009 RETURN (self); |
2010 } |
2010 } |
2011 /* |
2011 /* |
2012 * allocation failed ... |
2012 * allocation failed ... |
2013 * ... fall through to trigger the error |
2013 * ... fall through to trigger the error |
2014 */ |
2014 */ |
2015 } |
2015 } |
2016 } |
2016 } |
2017 %}. |
2017 %}. |
2018 index0 := index := digitByteArray size. |
2018 index0 := index := digitByteArray size. |
2019 [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[ |
2019 [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[ |
2020 index := index - 1 |
2020 index := index - 1 |
2021 ]. |
2021 ]. |
2022 "/ ((index < SmallInteger maxBytes) |
2022 "/ ((index < SmallInteger maxBytes) |
2023 "/ or:[(index == SmallInteger maxBytes) |
2023 "/ or:[(index == SmallInteger maxBytes) |
2024 "/ and:[(digitByteArray at:index) < 16r20]]) |
2024 "/ and:[(digitByteArray at:index) < 16r20]]) |
2025 "/ ifTrue:[ |
2025 "/ ifTrue:[ |
2070 could have simply created a 4-byte largeinteger and normalize it. |
2070 could have simply created a 4-byte largeinteger and normalize it. |
2071 The code below does the normalize right away, avoiding the |
2071 The code below does the normalize right away, avoiding the |
2072 overhead of producing any intermediate byte-arrays (and the scanning) |
2072 overhead of producing any intermediate byte-arrays (and the scanning) |
2073 " |
2073 " |
2074 (aSmallInteger == 0) ifTrue: [ |
2074 (aSmallInteger == 0) ifTrue: [ |
2075 digitByteArray := ByteArray with:0. |
2075 digitByteArray := ByteArray with:0. |
2076 sign := 0. |
2076 sign := 0. |
2077 ^ self |
2077 ^ self |
2078 ]. |
2078 ]. |
2079 |
2079 |
2080 (aSmallInteger < 0) ifTrue: [ |
2080 (aSmallInteger < 0) ifTrue: [ |
2081 sign := -1. |
2081 sign := -1. |
2082 absValue := aSmallInteger negated |
2082 absValue := aSmallInteger negated |
2083 ] ifFalse: [ |
2083 ] ifFalse: [ |
2084 sign := 1. |
2084 sign := 1. |
2085 absValue := aSmallInteger |
2085 absValue := aSmallInteger |
2086 ]. |
2086 ]. |
2087 |
2087 |
2088 b1 := absValue bitAnd:16rFF. |
2088 b1 := absValue bitAnd:16rFF. |
2089 absValue := absValue bitShift:-8. |
2089 absValue := absValue bitShift:-8. |
2090 absValue == 0 ifTrue:[ |
2090 absValue == 0 ifTrue:[ |
2091 digitByteArray := ByteArray with:b1 |
2091 digitByteArray := ByteArray with:b1 |
2092 ] ifFalse:[ |
2092 ] ifFalse:[ |
2093 b2 := absValue bitAnd:16rFF. |
2093 b2 := absValue bitAnd:16rFF. |
2094 absValue := absValue bitShift:-8. |
2094 absValue := absValue bitShift:-8. |
2095 absValue == 0 ifTrue:[ |
2095 absValue == 0 ifTrue:[ |
2096 digitByteArray := ByteArray with:b1 with:b2 |
2096 digitByteArray := ByteArray with:b1 with:b2 |
2097 ] ifFalse:[ |
2097 ] ifFalse:[ |
2098 b3 := absValue bitAnd:16rFF. |
2098 b3 := absValue bitAnd:16rFF. |
2099 absValue := absValue bitShift:-8. |
2099 absValue := absValue bitShift:-8. |
2100 absValue == 0 ifTrue:[ |
2100 absValue == 0 ifTrue:[ |
2101 digitByteArray := ByteArray with:b1 with:b2 with:b3 |
2101 digitByteArray := ByteArray with:b1 with:b2 with:b3 |
2102 ] ifFalse:[ |
2102 ] ifFalse:[ |
2103 b4 := absValue bitAnd:16rFF. |
2103 b4 := absValue bitAnd:16rFF. |
2104 absValue := absValue bitShift:-8. |
2104 absValue := absValue bitShift:-8. |
2105 absValue == 0 ifTrue:[ |
2105 absValue == 0 ifTrue:[ |
2106 digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4 |
2106 digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4 |
2107 ] ifFalse:[ |
2107 ] ifFalse:[ |
2108 b5 := absValue bitAnd:16rFF. |
2108 b5 := absValue bitAnd:16rFF. |
2109 absValue := absValue bitShift:-8. |
2109 absValue := absValue bitShift:-8. |
2110 absValue == 0 ifTrue:[ |
2110 absValue == 0 ifTrue:[ |
2111 digitByteArray := ByteArray new:5. |
2111 digitByteArray := ByteArray new:5. |
2112 digitByteArray at:1 put:b1. |
2112 digitByteArray at:1 put:b1. |
2113 digitByteArray at:2 put:b2. |
2113 digitByteArray at:2 put:b2. |
2114 digitByteArray at:3 put:b3. |
2114 digitByteArray at:3 put:b3. |
2115 digitByteArray at:4 put:b4. |
2115 digitByteArray at:4 put:b4. |
2116 digitByteArray at:5 put:b5. |
2116 digitByteArray at:5 put:b5. |
2117 ] ifFalse:[ |
2117 ] ifFalse:[ |
2118 b6 := absValue bitAnd:16rFF. |
2118 b6 := absValue bitAnd:16rFF. |
2119 absValue := absValue bitShift:-8. |
2119 absValue := absValue bitShift:-8. |
2120 absValue == 0 ifTrue:[ |
2120 absValue == 0 ifTrue:[ |
2121 digitByteArray := ByteArray new:6. |
2121 digitByteArray := ByteArray new:6. |
2122 digitByteArray at:1 put:b1. |
2122 digitByteArray at:1 put:b1. |
2123 digitByteArray at:2 put:b2. |
2123 digitByteArray at:2 put:b2. |
2124 digitByteArray at:3 put:b3. |
2124 digitByteArray at:3 put:b3. |
2125 digitByteArray at:4 put:b4. |
2125 digitByteArray at:4 put:b4. |
2126 digitByteArray at:5 put:b5. |
2126 digitByteArray at:5 put:b5. |
2127 digitByteArray at:6 put:b6. |
2127 digitByteArray at:6 put:b6. |
2128 ] ifFalse:[ |
2128 ] ifFalse:[ |
2129 b7 := absValue bitAnd:16rFF. |
2129 b7 := absValue bitAnd:16rFF. |
2130 absValue := absValue bitShift:-8. |
2130 absValue := absValue bitShift:-8. |
2131 absValue == 0 ifTrue:[ |
2131 absValue == 0 ifTrue:[ |
2132 digitByteArray := ByteArray new:7. |
2132 digitByteArray := ByteArray new:7. |
2133 digitByteArray at:1 put:b1. |
2133 digitByteArray at:1 put:b1. |
2134 digitByteArray at:2 put:b2. |
2134 digitByteArray at:2 put:b2. |
2135 digitByteArray at:3 put:b3. |
2135 digitByteArray at:3 put:b3. |
2136 digitByteArray at:4 put:b4. |
2136 digitByteArray at:4 put:b4. |
2137 digitByteArray at:5 put:b5. |
2137 digitByteArray at:5 put:b5. |
2138 digitByteArray at:6 put:b6. |
2138 digitByteArray at:6 put:b6. |
2139 digitByteArray at:7 put:b7. |
2139 digitByteArray at:7 put:b7. |
2140 ] ifFalse:[ |
2140 ] ifFalse:[ |
2141 digitByteArray := ByteArray new:8. |
2141 digitByteArray := ByteArray new:8. |
2142 digitByteArray at:1 put:b1. |
2142 digitByteArray at:1 put:b1. |
2143 digitByteArray at:2 put:b2. |
2143 digitByteArray at:2 put:b2. |
2144 digitByteArray at:3 put:b3. |
2144 digitByteArray at:3 put:b3. |
2145 digitByteArray at:4 put:b4. |
2145 digitByteArray at:4 put:b4. |
2146 digitByteArray at:5 put:b5. |
2146 digitByteArray at:5 put:b5. |
2147 digitByteArray at:6 put:b6. |
2147 digitByteArray at:6 put:b6. |
2148 digitByteArray at:7 put:b7. |
2148 digitByteArray at:7 put:b7. |
2149 digitByteArray at:8 put:absValue. |
2149 digitByteArray at:8 put:absValue. |
2150 ] |
2150 ] |
2151 ] |
2151 ] |
2152 ] |
2152 ] |
2153 ] |
2153 ] |
2154 ] |
2154 ] |
2155 ] |
2155 ] |
2156 ] |
2156 ] |
2157 |
2157 |
2158 "Modified: / 26.5.1999 / 22:18:14 / cg" |
2158 "Modified: / 26.5.1999 / 22:18:14 / cg" |
2159 ! ! |
2159 ! ! |
2160 |
2160 |
3009 __digits = __INST(digitByteArray); |
3009 __digits = __INST(digitByteArray); |
3010 |
3010 |
3011 if (__isByteArray(__digits) |
3011 if (__isByteArray(__digits) |
3012 && __isByteArray(newDigitByteArray) |
3012 && __isByteArray(newDigitByteArray) |
3013 && __bothSmallInteger(count, aPositiveSmallInteger)) { |
3013 && __bothSmallInteger(count, aPositiveSmallInteger)) { |
3014 unsigned INT rest = 0; |
3014 unsigned INT rest = 0; |
3015 int index = __intVal(count); |
3015 int index = __intVal(count); |
3016 int index0; |
3016 int index0; |
3017 unsigned INT divisor = __intVal(aPositiveSmallInteger); |
3017 unsigned INT divisor = __intVal(aPositiveSmallInteger); |
3018 unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element; |
3018 unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element; |
3019 unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element; |
3019 unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element; |
3020 |
3020 |
3021 index0 = index - 1; |
3021 index0 = index - 1; |
3022 |
3022 |
3023 # if (__POINTER_SIZE__ == 8) |
3023 # if (__POINTER_SIZE__ == 8) |
3024 if (sizeof(int) == 4) { |
3024 if (sizeof(int) == 4) { |
3025 /* |
3025 /* |
3026 * divide int-wise |
3026 * divide int-wise |
3027 */ |
3027 */ |
3028 if (divisor <= 0xFFFFFFFF) { |
3028 if (divisor <= 0xFFFFFFFF) { |
3029 if ((index & 3) == 0) { /* even number of int32's */ |
3029 if ((index & 3) == 0) { /* even number of int32's */ |
3030 while (index > 3) { |
3030 while (index > 3) { |
3031 unsigned INT t; |
3031 unsigned INT t; |
3032 unsigned INT div; |
3032 unsigned INT div; |
3033 |
3033 |
3034 index -= 4; |
3034 index -= 4; |
3035 # if defined(__LSBFIRST__) |
3035 # if defined(__LSBFIRST__) |
3036 t = *((unsigned int *)(&digitBytes[index])); |
3036 t = *((unsigned int *)(&digitBytes[index])); |
3037 # else |
3037 # else |
3038 t = digitBytes[index+3]; |
3038 t = digitBytes[index+3]; |
3039 t = (t << 8) | digitBytes[index+2]; |
3039 t = (t << 8) | digitBytes[index+2]; |
3040 t = (t << 8) | digitBytes[index+1]; |
3040 t = (t << 8) | digitBytes[index+1]; |
3041 t = (t << 8) | digitBytes[index]; |
3041 t = (t << 8) | digitBytes[index]; |
3042 # endif |
3042 # endif |
3043 t = t | (rest << 32); |
3043 t = t | (rest << 32); |
3044 div = t / divisor; |
3044 div = t / divisor; |
3045 rest = t % divisor; |
3045 rest = t % divisor; |
3046 # if defined(__LSBFIRST__) |
3046 # if defined(__LSBFIRST__) |
3047 *((unsigned int *)(&resultBytes[index])) = (div & 0xFFFFFFFF); |
3047 *((unsigned int *)(&resultBytes[index])) = (div & 0xFFFFFFFF); |
3048 # else |
3048 # else |
3049 resultBytes[index+3] = div >> 24; |
3049 resultBytes[index+3] = div >> 24; |
3050 resultBytes[index+2] = div >> 16; |
3050 resultBytes[index+2] = div >> 16; |
3051 resultBytes[index+1] = div >> 8; |
3051 resultBytes[index+1] = div >> 8; |
3052 resultBytes[index] = div /* & 0xFF */; |
3052 resultBytes[index] = div /* & 0xFF */; |
3053 # endif |
3053 # endif |
3054 } |
3054 } |
3055 } |
3055 } |
3056 } |
3056 } |
3057 } |
3057 } |
3058 #endif |
3058 #endif |
3059 /* |
3059 /* |
3060 * divide short-wise |
3060 * divide short-wise |
3061 */ |
3061 */ |
3062 if (divisor <= 0xFFFF) { |
3062 if (divisor <= 0xFFFF) { |
3063 if ((index & 1) == 0) { /* even number of bytes */ |
3063 if ((index & 1) == 0) { /* even number of bytes */ |
3064 while (index > 1) { |
3064 while (index > 1) { |
3065 unsigned INT t; |
3065 unsigned INT t; |
3066 unsigned INT div; |
3066 unsigned INT div; |
3067 |
3067 |
3068 index -= 2; |
3068 index -= 2; |
3069 #if defined(__LSBFIRST__) |
3069 #if defined(__LSBFIRST__) |
3070 t = *((unsigned short *)(&digitBytes[index])); |
3070 t = *((unsigned short *)(&digitBytes[index])); |
3071 #else |
3071 #else |
3072 t = digitBytes[index+1]; |
3072 t = digitBytes[index+1]; |
3073 t = (t << 8) | digitBytes[index]; |
3073 t = (t << 8) | digitBytes[index]; |
3074 #endif |
3074 #endif |
3075 t = t | (rest << 16); |
3075 t = t | (rest << 16); |
3076 div = t / divisor; |
3076 div = t / divisor; |
3077 rest = t % divisor; |
3077 rest = t % divisor; |
3078 #if defined(__LSBFIRST__) |
3078 #if defined(__LSBFIRST__) |
3079 *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF); |
3079 *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF); |
3080 #else |
3080 #else |
3081 resultBytes[index+1] = div >> 8; |
3081 resultBytes[index+1] = div >> 8; |
3082 resultBytes[index] = div /* & 0xFF */; |
3082 resultBytes[index] = div /* & 0xFF */; |
3083 #endif |
3083 #endif |
3084 } |
3084 } |
3085 } |
3085 } |
3086 } |
3086 } |
3087 while (index > 0) { |
3087 while (index > 0) { |
3088 unsigned INT t; |
3088 unsigned INT t; |
3089 |
3089 |
3090 index--; |
3090 index--; |
3091 t = digitBytes[index]; |
3091 t = digitBytes[index]; |
3092 t = t | (rest << 8); |
3092 t = t | (rest << 8); |
3093 resultBytes[index] = t / divisor; |
3093 resultBytes[index] = t / divisor; |
3094 rest = t % divisor; |
3094 rest = t % divisor; |
3095 } |
3095 } |
3096 prevRest = __mkSmallInteger(rest); |
3096 prevRest = __mkSmallInteger(rest); |
3097 |
3097 |
3098 /* |
3098 /* |
3099 * no need to normalize ? |
3099 * no need to normalize ? |
3100 */ |
3100 */ |
3101 index = index0; |
3101 index = index0; |
3102 while ((index >= sizeof(INT)) && (resultBytes[index]==0)) { |
3102 while ((index >= sizeof(INT)) && (resultBytes[index]==0)) { |
3103 index--; |
3103 index--; |
3104 } |
3104 } |
3105 |
3105 |
3106 if (index == index0) { |
3106 if (index == index0) { |
3107 if (index > sizeof(INT)) { |
3107 if (index > sizeof(INT)) { |
3108 RETURN ( __ARRAY_WITH2(result, prevRest)); |
3108 RETURN ( __ARRAY_WITH2(result, prevRest)); |
3109 } |
3109 } |
3110 if ((index == sizeof(INT)) |
3110 if ((index == sizeof(INT)) |
3111 && resultBytes[index0] >= 0x40) { |
3111 && resultBytes[index0] >= 0x40) { |
3112 RETURN ( __ARRAY_WITH2(result, prevRest)); |
3112 RETURN ( __ARRAY_WITH2(result, prevRest)); |
3113 } |
3113 } |
3114 } |
3114 } |
3115 |
3115 |
3116 /* |
3116 /* |
3117 * must compress |
3117 * must compress |
3118 */ |
3118 */ |
3119 ok = true; |
3119 ok = true; |
3120 } |
3120 } |
3121 %}. |
3121 %}. |
3122 " |
3122 " |
3123 slow code - not normally reached |
3123 slow code - not normally reached |
3124 (could also do a primitiveFailure here) |
3124 (could also do a primitiveFailure here) |
3125 " |
3125 " |
3126 ok ifFalse:[ |
3126 ok ifFalse:[ |
3127 ^ self absDivMod:(self class value:aPositiveSmallInteger). |
3127 ^ self absDivMod:(self class value:aPositiveSmallInteger). |
3128 ]. |
3128 ]. |
3129 |
3129 |
3130 ^ Array with:(result compressed) with:prevRest |
3130 ^ Array with:(result compressed) with:prevRest |
3131 |
3131 |
3132 " |
3132 " |
3168 borrow := aSmallInteger abs. |
3168 borrow := aSmallInteger abs. |
3169 |
3169 |
3170 %{ |
3170 %{ |
3171 if (__isByteArray(__INST(digitByteArray)) |
3171 if (__isByteArray(__INST(digitByteArray)) |
3172 && __isByteArray(resultDigitByteArray)) { |
3172 && __isByteArray(resultDigitByteArray)) { |
3173 unsigned INT __borrow = __intVal(borrow); |
3173 unsigned INT __borrow = __intVal(borrow); |
3174 INT __diff; |
3174 INT __diff; |
3175 int __index = 1; |
3175 int __index = 1; |
3176 int __len = __intVal(len); |
3176 int __len = __intVal(len); |
3177 unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
3177 unsigned char *__digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
3178 unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
3178 unsigned char *__resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
3179 int __len3; |
3179 int __len3; |
3180 |
3180 |
3181 #if defined(__LSBFIRST__) |
3181 #if defined(__LSBFIRST__) |
3182 # if (__POINTER_SIZE__ == 8) |
3182 # if (__POINTER_SIZE__ == 8) |
3183 /* |
3183 /* |
3184 * subtract int-wise |
3184 * subtract int-wise |
3185 */ |
3185 */ |
3186 __len3 = __len - 3; |
3186 __len3 = __len - 3; |
3187 while (__index < __len3) { |
3187 while (__index < __len3) { |
3188 /* do not make this into one expression - ask cg why */ |
3188 /* do not make this into one expression - ask cg why */ |
3189 __diff = ((unsigned int *)(__digitP + __index-1))[0]; |
3189 __diff = ((unsigned int *)(__digitP + __index-1))[0]; |
3190 __diff -= (__borrow & 0xFFFFFFFFL); |
3190 __diff -= (__borrow & 0xFFFFFFFFL); |
3191 __borrow >>= 32; |
3191 __borrow >>= 32; |
3192 if (__diff < 0) { |
3192 if (__diff < 0) { |
3193 /* __diff += 0x100000000; */ |
3193 /* __diff += 0x100000000; */ |
3194 __borrow++; |
3194 __borrow++; |
3195 } |
3195 } |
3196 ((unsigned int *)(__resultP+__index-1))[0] = __diff; |
3196 ((unsigned int *)(__resultP+__index-1))[0] = __diff; |
3197 __index += 4; |
3197 __index += 4; |
3198 } |
3198 } |
3199 # endif |
3199 # endif |
3200 /* |
3200 /* |
3201 * subtract short-wise |
3201 * subtract short-wise |
3202 */ |
3202 */ |
3203 while (__index < __len) { |
3203 while (__index < __len) { |
3204 /* do not make this into one expression - ask cg why */ |
3204 /* do not make this into one expression - ask cg why */ |
3205 __diff = ((unsigned short *)(__digitP+__index-1))[0]; |
3205 __diff = ((unsigned short *)(__digitP+__index-1))[0]; |
3206 __diff -= (__borrow & 0xFFFF); |
3206 __diff -= (__borrow & 0xFFFF); |
3207 __borrow >>= 16; |
3207 __borrow >>= 16; |
3208 if (__diff < 0) { |
3208 if (__diff < 0) { |
3209 /* __diff += 0x10000; */ |
3209 /* __diff += 0x10000; */ |
3210 __borrow++; |
3210 __borrow++; |
3211 } else { |
3211 } else { |
3212 if (__borrow == 0) { |
3212 if (__borrow == 0) { |
3213 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
3213 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
3214 __index += 2; |
3214 __index += 2; |
3215 |
3215 |
3216 /* nothing more to subtract .. */ |
3216 /* nothing more to subtract .. */ |
3217 while (__index < __len) { |
3217 while (__index < __len) { |
3218 ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0]; |
3218 ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0]; |
3219 __index += 2; |
3219 __index += 2; |
3220 } |
3220 } |
3221 if (__index <= __len) { |
3221 if (__index <= __len) { |
3222 __resultP[__index-1] = __digitP[__index-1]; |
3222 __resultP[__index-1] = __digitP[__index-1]; |
3223 } |
3223 } |
3224 break; |
3224 break; |
3225 } |
3225 } |
3226 } |
3226 } |
3227 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
3227 ((unsigned short *)(__resultP+__index-1))[0] = __diff; |
3228 __index += 2; |
3228 __index += 2; |
3229 } |
3229 } |
3230 #endif |
3230 #endif |
3231 /* |
3231 /* |
3232 * subtract byte-wise |
3232 * subtract byte-wise |
3233 */ |
3233 */ |
3234 while (__index <= __len) { |
3234 while (__index <= __len) { |
3235 __diff = __digitP[__index-1]; |
3235 __diff = __digitP[__index-1]; |
3236 __diff -= (__borrow & 0xFF); |
3236 __diff -= (__borrow & 0xFF); |
3237 __borrow >>= 8; |
3237 __borrow >>= 8; |
3238 if (__diff < 0) { |
3238 if (__diff < 0) { |
3239 /* __diff += 0x100; */ |
3239 /* __diff += 0x100; */ |
3240 __borrow++; |
3240 __borrow++; |
3241 } else { |
3241 } else { |
3242 if (__borrow == 0) { |
3242 if (__borrow == 0) { |
3243 __resultP[__index-1] = __diff; |
3243 __resultP[__index-1] = __diff; |
3244 __index++; |
3244 __index++; |
3245 |
3245 |
3246 /* nothing more to subtract .. */ |
3246 /* nothing more to subtract .. */ |
3247 while (__index <= __len) { |
3247 while (__index <= __len) { |
3248 __resultP[__index-1] = __digitP[__index-1]; |
3248 __resultP[__index-1] = __digitP[__index-1]; |
3249 __index++; |
3249 __index++; |
3250 } |
3250 } |
3251 break; |
3251 break; |
3252 } |
3252 } |
3253 } |
3253 } |
3254 __resultP[__index-1] = __diff; |
3254 __resultP[__index-1] = __diff; |
3255 __index++; |
3255 __index++; |
3256 } |
3256 } |
3257 lastDigit = __mkSmallInteger( __resultP[__index-1-1] ); |
3257 lastDigit = __mkSmallInteger( __resultP[__index-1-1] ); |
3258 ok = true; |
3258 ok = true; |
3259 } |
3259 } |
3260 %}. |
3260 %}. |
3261 |
3261 |
3262 ok == true ifFalse:[ "/ cannot happen |
3262 ok == true ifFalse:[ "/ cannot happen |
3263 index := 1. |
3263 index := 1. |
3264 [borrow ~~ 0] whileTrue:[ |
3264 [borrow ~~ 0] whileTrue:[ |
3265 (index <= len) ifTrue:[ |
3265 (index <= len) ifTrue:[ |
3266 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF). |
3266 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF). |
3267 borrow := borrow bitShift:-8. |
3267 borrow := borrow bitShift:-8. |
3268 diff < 0 ifTrue:[ |
3268 diff < 0 ifTrue:[ |
3269 diff := diff + 256. |
3269 diff := diff + 256. |
3270 borrow := borrow + 1. |
3270 borrow := borrow + 1. |
3271 ] |
3271 ] |
3272 ] ifFalse:[ |
3272 ] ifFalse:[ |
3273 diff := borrow bitAnd:255. |
3273 diff := borrow bitAnd:255. |
3274 borrow := borrow bitShift:-8. |
3274 borrow := borrow bitShift:-8. |
3275 ]. |
3275 ]. |
3276 resultDigitByteArray basicAt:index put:(lastDigit := diff). |
3276 resultDigitByteArray basicAt:index put:(lastDigit := diff). |
3277 index := index + 1 |
3277 index := index + 1 |
3278 ]. |
3278 ]. |
3279 [index <= len] whileTrue:[ |
3279 [index <= len] whileTrue:[ |
3280 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
3280 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
3281 index := index + 1 |
3281 index := index + 1 |
3282 ]. |
3282 ]. |
3283 (index <= rsltLen) ifTrue:[ |
3283 (index <= rsltLen) ifTrue:[ |
3284 lastDigit := 0. |
3284 lastDigit := 0. |
3285 ] |
3285 ] |
3286 ]. |
3286 ]. |
3287 |
3287 |
3288 (lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[ |
3288 (lastDigit == 0 or:[rsltLen <= SmallInteger maxBytes]) ifTrue:[ |
3289 ^ result compressed. |
3289 ^ result compressed. |
3290 ]. |
3290 ]. |
3291 ^ result |
3291 ^ result |
3292 |
3292 |
3293 " |
3293 " |
3294 12345678900000000000 absFastMinus:1 sign:1 |
3294 12345678900000000000 absFastMinus:1 sign:1 |
3351 |
3351 |
3352 %{ |
3352 %{ |
3353 if (__isByteArray(__INST(digitByteArray)) |
3353 if (__isByteArray(__INST(digitByteArray)) |
3354 && __isByteArray(resultDigitByteArray) |
3354 && __isByteArray(resultDigitByteArray) |
3355 && __isSmallInteger(aSmallInteger)) { |
3355 && __isSmallInteger(aSmallInteger)) { |
3356 /* carry is NOT unsigned (see negation below) */ |
3356 /* carry is NOT unsigned (see negation below) */ |
3357 INT __carry = __intVal(aSmallInteger); |
3357 INT __carry = __intVal(aSmallInteger); |
3358 int __index = 1; |
3358 int __index = 1; |
3359 int __len = __intVal(len); |
3359 int __len = __intVal(len); |
3360 unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element); |
3360 unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element); |
3361 unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element); |
3361 unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element); |
3362 INT __ptrDelta = __dst - __src; |
3362 INT __ptrDelta = __dst - __src; |
3363 unsigned char *__srcLast = __src + __len - 1; |
3363 unsigned char *__srcLast = __src + __len - 1; |
3364 int __rsltLen = __intVal(rsltLen); |
3364 int __rsltLen = __intVal(rsltLen); |
3365 |
3365 |
3366 if (__carry < 0) { |
3366 if (__carry < 0) { |
3367 __carry = -__carry; |
3367 __carry = -__carry; |
3368 } |
3368 } |
3369 |
3369 |
3370 #if defined(__LSBFIRST__) |
3370 #if defined(__LSBFIRST__) |
3371 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4) |
3371 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4) |
3372 # if 0 /* NOTICE - the code below is 20% slower ... - why */ |
3372 # if 0 /* NOTICE - the code below is 20% slower ... - why */ |
3373 /* |
3373 /* |
3374 * add long-wise |
3374 * add long-wise |
3375 */ |
3375 */ |
3376 asm(" jecxz nothingToDo \n\ |
3376 asm(" jecxz nothingToDo \n\ |
3377 movl %%eax, %%esi /* __src input */ \n\ |
3377 movl %%eax, %%esi /* __src input */ \n\ |
3378 movl %%ebx, %%edi /* __dst input */ \n\ |
3378 movl %%ebx, %%edi /* __dst input */ \n\ |
3379 \n\ |
3379 \n\ |
3380 /* the first 4-byte int */ \n\ |
3380 /* the first 4-byte int */ \n\ |
3381 lodsl /* fetch */ \n\ |
3381 lodsl /* fetch */ \n\ |
3382 addl %%edx, %%eax /* add */ \n\ |
3382 addl %%edx, %%eax /* add */ \n\ |
3383 stosl /* store */ \n\ |
3383 stosl /* store */ \n\ |
3384 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3384 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3385 jecxz doneLoop /* any more ? */ \n\ |
3385 jecxz doneLoop /* any more ? */ \n\ |
3386 /* remaining 4-byte ints */ \n\ |
3386 /* remaining 4-byte ints */ \n\ |
3387 jmp addLoop \n\ |
3387 jmp addLoop \n\ |
3388 \n\ |
3388 \n\ |
3389 .align 8 \n\ |
3389 .align 8 \n\ |
3390 addLoop: \n\ |
3390 addLoop: \n\ |
3391 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3391 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3392 jnc copyLoop2 \n\ |
3392 jnc copyLoop2 \n\ |
3393 movl $0, %%eax \n\ |
3393 movl $0, %%eax \n\ |
3394 leal 4(%%esi), %%esi \n\ |
3394 leal 4(%%esi), %%esi \n\ |
3395 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3395 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3396 leal 8(%%edi), %%edi \n\ |
3396 leal 8(%%edi), %%edi \n\ |
3397 movl %%eax, -8(%%edi) /* store */ \n\ |
3397 movl %%eax, -8(%%edi) /* store */ \n\ |
3398 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3398 leal -1(%%ecx),%%ecx /* do not clobber carry */ \n\ |
3399 jecxz doneLoop /* any more ? */ \n\ |
3399 jecxz doneLoop /* any more ? */ \n\ |
3400 \n\ |
3400 \n\ |
3401 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3401 movl 0(%%esi), %%ebx /* fetch */ \n\ |
3402 movl $0, %%eax \n\ |
3402 movl $0, %%eax \n\ |
3403 leal 4(%%esi), %%esi \ |
3403 leal 4(%%esi), %%esi \ |
3404 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3404 adcl %%ebx, %%eax /* & add carry from prev int */\n\ |
3405 movl %%eax, -4(%%edi) /* store */ \n\ |
3405 movl %%eax, -4(%%edi) /* store */ \n\ |
3406 \n\ |
3406 \n\ |
3407 loop addLoop \n\ |
3407 loop addLoop \n\ |
3408 jmp doneLoop \n\ |
3408 jmp doneLoop \n\ |
3409 \n\ |
3409 \n\ |
3410 .align 8 \n\ |
3410 .align 8 \n\ |
3411 copyLoop: \n\ |
3411 copyLoop: \n\ |
3412 movl 0(%%esi), %%ebx \n\ |
3412 movl 0(%%esi), %%ebx \n\ |
3413 copyLoop2: \n\ |
3413 copyLoop2: \n\ |
3414 add $4, %%esi \n\ |
3414 add $4, %%esi \n\ |
3415 add $4, %%edi \n\ |
3415 add $4, %%edi \n\ |
3416 movl %%ebx, -4(%%edi) \n\ |
3416 movl %%ebx, -4(%%edi) \n\ |
3417 loop copyLoop \n\ |
3417 loop copyLoop \n\ |
3418 \n\ |
3418 \n\ |
3419 doneLoop: \n\ |
3419 doneLoop: \n\ |
3420 movl $0, %%edx /* do not clobber carry (xorl clears it) */ \n\ |
3420 movl $0, %%edx /* do not clobber carry (xorl clears it) */ \n\ |
3421 adcl $0, %%edx \n\ |
3421 adcl $0, %%edx \n\ |
3422 movl %%esi, %%eax /* __src output */ \n\ |
3422 movl %%esi, %%eax /* __src output */ \n\ |
3423 nothingToDo: \n\ |
3423 nothingToDo: \n\ |
3424 " : "=d" ((unsigned long)(__carry)), |
3424 " : "=d" ((unsigned long)(__carry)), |
3425 "=a" (__src) |
3425 "=a" (__src) |
3426 : "1" (__src), |
3426 : "1" (__src), |
3427 "b" (__dst), |
3427 "b" (__dst), |
3428 "c" (__len / 4), |
3428 "c" (__len / 4), |
3429 "0" (__carry) |
3429 "0" (__carry) |
3430 : "esi", "edi"); |
3430 : "esi", "edi"); |
3431 |
3431 |
3432 # else |
3432 # else |
3433 { |
3433 { |
3434 unsigned char *__srcLastX; |
3434 unsigned char *__srcLastX; |
3435 |
3435 |
3436 __srcLastX = __srcLast - 3 - 4; |
3436 __srcLastX = __srcLast - 3 - 4; |
3437 while (__src <= __srcLastX) { |
3437 while (__src <= __srcLastX) { |
3438 unsigned int __sum, __sum2; |
3438 unsigned int __sum, __sum2; |
3439 unsigned __digit1, __digit2; |
3439 unsigned __digit1, __digit2; |
3440 |
3440 |
3441 __digit1 = ((unsigned *)__src)[0]; |
3441 __digit1 = ((unsigned *)__src)[0]; |
3442 __digit2 = ((unsigned *)__src)[1]; |
3442 __digit2 = ((unsigned *)__src)[1]; |
3443 asm ("addl %%edx,%%ecx \n\ |
3443 asm ("addl %%edx,%%ecx \n\ |
3444 adcl $0, %%eax \n\ |
3444 adcl $0, %%eax \n\ |
3445 movl $0, %%edx \n\ |
3445 movl $0, %%edx \n\ |
3446 adcl $0, %%edx" |
3446 adcl $0, %%edx" |
3447 : "=d" ((unsigned long)(__carry)), |
3447 : "=d" ((unsigned long)(__carry)), |
3448 "=c" ((unsigned long)(__sum)), |
3448 "=c" ((unsigned long)(__sum)), |
3449 "=a" ((unsigned long)(__sum2)) |
3449 "=a" ((unsigned long)(__sum2)) |
3450 : "0" ((unsigned long)(__carry)), |
3450 : "0" ((unsigned long)(__carry)), |
3451 "1" (__digit1), |
3451 "1" (__digit1), |
3452 "2" (__digit2)); |
3452 "2" (__digit2)); |
3453 |
3453 |
3454 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3454 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3455 ((unsigned int *)(__src + __ptrDelta))[1] = __sum2; |
3455 ((unsigned int *)(__src + __ptrDelta))[1] = __sum2; |
3456 |
3456 |
3457 __src += 8; |
3457 __src += 8; |
3458 |
3458 |
3459 if (__carry == 0) { |
3459 if (__carry == 0) { |
3460 while (__src <= __srcLastX) { |
3460 while (__src <= __srcLastX) { |
3461 /* copy over words */ |
3461 /* copy over words */ |
3462 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3462 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3463 ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1]; |
3463 ((unsigned int *)(__src + __ptrDelta))[1] = ((unsigned int *)__src)[1]; |
3464 __src += 8; |
3464 __src += 8; |
3465 } |
3465 } |
3466 while (__src <= __srcLast) { |
3466 while (__src <= __srcLast) { |
3467 /* copy over bytes */ |
3467 /* copy over bytes */ |
3468 __src[__ptrDelta] = __src[0]; |
3468 __src[__ptrDelta] = __src[0]; |
3469 __src ++; |
3469 __src ++; |
3470 } |
3470 } |
3471 goto doneSource; |
3471 goto doneSource; |
3472 } |
3472 } |
3473 } |
3473 } |
3474 |
3474 |
3475 __srcLastX = __srcLastX + 4; |
3475 __srcLastX = __srcLastX + 4; |
3476 if (__src <= __srcLastX) { |
3476 if (__src <= __srcLastX) { |
3477 unsigned int __sum, __digit; |
3477 unsigned int __sum, __digit; |
3478 |
3478 |
3479 __digit = ((unsigned *)__src)[0]; |
3479 __digit = ((unsigned *)__src)[0]; |
3480 |
3480 |
3481 asm ("addl %%eax,%%edx \n\ |
3481 asm ("addl %%eax,%%edx \n\ |
3482 movl $0,%%eax \n\ |
3482 movl $0,%%eax \n\ |
3483 adcl $0,%%eax" |
3483 adcl $0,%%eax" |
3484 : "=a" ((unsigned long)(__carry)), |
3484 : "=a" ((unsigned long)(__carry)), |
3485 "=d" ((unsigned long)(__sum)) |
3485 "=d" ((unsigned long)(__sum)) |
3486 : "0" ((unsigned long)(__carry)), |
3486 : "0" ((unsigned long)(__carry)), |
3487 "1" (__digit) ); |
3487 "1" (__digit) ); |
3488 |
3488 |
3489 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3489 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3490 __src += 4; |
3490 __src += 4; |
3491 |
3491 |
3492 if (__carry == 0) { |
3492 if (__carry == 0) { |
3493 while (__src <= __srcLast) { |
3493 while (__src <= __srcLast) { |
3494 /* copy over bytes */ |
3494 /* copy over bytes */ |
3495 __src[__ptrDelta] = __src[0]; |
3495 __src[__ptrDelta] = __src[0]; |
3496 __src ++; |
3496 __src ++; |
3497 } |
3497 } |
3498 goto doneSource; |
3498 goto doneSource; |
3499 } |
3499 } |
3500 } |
3500 } |
3501 } |
3501 } |
3502 # endif |
3502 # endif |
3503 # else /* not i386-GNUC */ |
3503 # else /* not i386-GNUC */ |
3504 # if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4) |
3504 # if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4) |
3505 { |
3505 { |
3506 unsigned char *__srcLast4; |
3506 unsigned char *__srcLast4; |
3507 |
3507 |
3508 /* |
3508 /* |
3509 * add long-wise |
3509 * add long-wise |
3510 */ |
3510 */ |
3511 __srcLast4 = __srcLast - 3; |
3511 __srcLast4 = __srcLast - 3; |
3512 while (__src <= __srcLast4) { |
3512 while (__src <= __srcLast4) { |
3513 unsigned int __sum; |
3513 unsigned int __sum; |
3514 |
3514 |
3515 __sum = ((unsigned int *)__src)[0]; |
3515 __sum = ((unsigned int *)__src)[0]; |
3516 asm { |
3516 asm { |
3517 mov eax, __sum |
3517 mov eax, __sum |
3518 add eax, __carry |
3518 add eax, __carry |
3519 mov edx, 0 |
3519 mov edx, 0 |
3520 adc edx, 0 |
3520 adc edx, 0 |
3521 mov __sum, eax |
3521 mov __sum, eax |
3522 mov __carry, edx |
3522 mov __carry, edx |
3523 } |
3523 } |
3524 |
3524 |
3525 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3525 ((unsigned int *)(__src + __ptrDelta))[0] = __sum; |
3526 __src += 4; |
3526 __src += 4; |
3527 if (__carry == 0) { |
3527 if (__carry == 0) { |
3528 while (__src <= __srcLast4) { |
3528 while (__src <= __srcLast4) { |
3529 /* copy over words */ |
3529 /* copy over words */ |
3530 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3530 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3531 __src += 4; |
3531 __src += 4; |
3532 } |
3532 } |
3533 while (__src <= __srcLast) { |
3533 while (__src <= __srcLast) { |
3534 /* copy over bytes */ |
3534 /* copy over bytes */ |
3535 __src[__ptrDelta] = __src[0]; |
3535 __src[__ptrDelta] = __src[0]; |
3536 __src ++; |
3536 __src ++; |
3537 } |
3537 } |
3538 goto doneSource; |
3538 goto doneSource; |
3539 } |
3539 } |
3540 } |
3540 } |
3541 } |
3541 } |
3542 # else /* not i386-WIN32 */ |
3542 # else /* not i386-WIN32 */ |
3543 # if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8) |
3543 # if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8) |
3544 { |
3544 { |
3545 unsigned char *__srcLast4; |
3545 unsigned char *__srcLast4; |
3546 |
3546 |
3547 /* |
3547 /* |
3548 * add long-wise |
3548 * add long-wise |
3549 */ |
3549 */ |
3550 __srcLast4 = __srcLast - 3; |
3550 __srcLast4 = __srcLast - 3; |
3551 while (__src <= __srcLast4) { |
3551 while (__src <= __srcLast4) { |
3552 unsigned INT __sum; |
3552 unsigned INT __sum; |
3553 |
3553 |
3554 __sum = ((unsigned int *)__src)[0] + __carry; |
3554 __sum = ((unsigned int *)__src)[0] + __carry; |
3555 ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */; |
3555 ((unsigned int *)(__src + __ptrDelta))[0] = __sum /* & 0xFFFF */; |
3556 __src += 4; |
3556 __src += 4; |
3557 __carry = __sum >> 32; |
3557 __carry = __sum >> 32; |
3558 if (__carry == 0) { |
3558 if (__carry == 0) { |
3559 while (__src <= __srcLast4) { |
3559 while (__src <= __srcLast4) { |
3560 /* copy over words */ |
3560 /* copy over words */ |
3561 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3561 ((unsigned int *)(__src + __ptrDelta))[0] = ((unsigned int *)__src)[0]; |
3562 __src += 4; |
3562 __src += 4; |
3563 } |
3563 } |
3564 while (__src <= __srcLast) { |
3564 while (__src <= __srcLast) { |
3565 /* copy over bytes */ |
3565 /* copy over bytes */ |
3566 __src[__ptrDelta] = __src[0]; |
3566 __src[__ptrDelta] = __src[0]; |
3567 __src ++; |
3567 __src ++; |
3568 } |
3568 } |
3569 goto doneSource; |
3569 goto doneSource; |
3570 } |
3570 } |
3571 } |
3571 } |
3572 } |
3572 } |
3573 # endif /* LSB+64bit */ |
3573 # endif /* LSB+64bit */ |
3574 # endif /* __i386__ & WIN32 */ |
3574 # endif /* __i386__ & WIN32 */ |
3575 # endif /* __i386__ & GNUC */ |
3575 # endif /* __i386__ & GNUC */ |
3576 |
3576 |
3577 /* |
3577 /* |
3578 * add short-wise |
3578 * add short-wise |
3579 */ |
3579 */ |
3580 while (__src < __srcLast) { |
3580 while (__src < __srcLast) { |
3581 __carry += ((unsigned short *)__src)[0]; |
3581 __carry += ((unsigned short *)__src)[0]; |
3582 ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */; |
3582 ((unsigned short *)(__src + __ptrDelta))[0] = __carry /* & 0xFFFF */; |
3583 __carry >>= 16; |
3583 __carry >>= 16; |
3584 __src += 2; |
3584 __src += 2; |
3585 } |
3585 } |
3586 /* |
3586 /* |
3587 * last (odd) byte |
3587 * last (odd) byte |
3588 */ |
3588 */ |
3589 if (__src <= __srcLast) { |
3589 if (__src <= __srcLast) { |
3590 __carry += __src[0]; |
3590 __carry += __src[0]; |
3591 __src[__ptrDelta] = __carry /* & 0xFF */; |
3591 __src[__ptrDelta] = __carry /* & 0xFF */; |
3592 __carry >>= 8; |
3592 __carry >>= 8; |
3593 __src++; |
3593 __src++; |
3594 } |
3594 } |
3595 #else /* not __LSBFIRST__ */ |
3595 #else /* not __LSBFIRST__ */ |
3596 |
3596 |
3597 /* |
3597 /* |
3598 * add byte-wise |
3598 * add byte-wise |
3599 */ |
3599 */ |
3600 while (__src <= __srcLast) { |
3600 while (__src <= __srcLast) { |
3601 __carry += __src[0]; |
3601 __carry += __src[0]; |
3602 __src[__ptrDelta] = __carry /* & 0xFF */; |
3602 __src[__ptrDelta] = __carry /* & 0xFF */; |
3603 __src++; |
3603 __src++; |
3604 __carry >>= 8; |
3604 __carry >>= 8; |
3605 |
3605 |
3606 if (__carry == 0) { |
3606 if (__carry == 0) { |
3607 while (__src <= __srcLast) { |
3607 while (__src <= __srcLast) { |
3608 /* copy over rest */ |
3608 /* copy over rest */ |
3609 __src[__ptrDelta] = __src[0]; |
3609 __src[__ptrDelta] = __src[0]; |
3610 __src++; |
3610 __src++; |
3611 } |
3611 } |
3612 goto doneSource; |
3612 goto doneSource; |
3613 } |
3613 } |
3614 } |
3614 } |
3615 #endif /* __LSBFIRST__ */ |
3615 #endif /* __LSBFIRST__ */ |
3616 |
3616 |
3617 doneSource: ; |
3617 doneSource: ; |
3618 /* |
3618 /* |
3619 * now, at most one other byte is to be stored ... |
3619 * now, at most one other byte is to be stored ... |
3620 */ |
3620 */ |
3621 if (__len < __rsltLen) { |
3621 if (__len < __rsltLen) { |
3622 __src[__ptrDelta] = __carry /* & 0xFF */; |
3622 __src[__ptrDelta] = __carry /* & 0xFF */; |
3623 __src++; |
3623 __src++; |
3624 } |
3624 } |
3625 |
3625 |
3626 if (__src[__ptrDelta-1]) { /* lastDigit */ |
3626 if (__src[__ptrDelta-1]) { /* lastDigit */ |
3627 RETURN (result); |
3627 RETURN (result); |
3628 } |
3628 } |
3629 ok = true; |
3629 ok = true; |
3630 } |
3630 } |
3631 %}. |
3631 %}. |
3632 |
3632 |
3633 ok ~~ true ifTrue:[ |
3633 ok ~~ true ifTrue:[ |
3634 index := 1. |
3634 index := 1. |
3635 carry := aSmallInteger abs. |
3635 carry := aSmallInteger abs. |
3636 |
3636 |
3637 [carry ~~ 0] whileTrue:[ |
3637 [carry ~~ 0] whileTrue:[ |
3638 (index <= len) ifTrue:[ |
3638 (index <= len) ifTrue:[ |
3639 carry := (digitByteArray basicAt:index) + carry. |
3639 carry := (digitByteArray basicAt:index) + carry. |
3640 ]. |
3640 ]. |
3641 resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF). |
3641 resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF). |
3642 carry := carry bitShift:-8. |
3642 carry := carry bitShift:-8. |
3643 index := index + 1 |
3643 index := index + 1 |
3644 ]. |
3644 ]. |
3645 |
3645 |
3646 (index <= rsltLen) ifTrue:[ |
3646 (index <= rsltLen) ifTrue:[ |
3647 [index <= len] whileTrue:[ |
3647 [index <= len] whileTrue:[ |
3648 resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index). |
3648 resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index). |
3649 index := index + 1 |
3649 index := index + 1 |
3650 ]. |
3650 ]. |
3651 lastDigit := 0. |
3651 lastDigit := 0. |
3652 ]. |
3652 ]. |
3653 |
3653 |
3654 (lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[ |
3654 (lastDigit ~~ 0 and:[rsltLen > SmallInteger maxBytes]) ifTrue:[ |
3655 ^ result |
3655 ^ result |
3656 ]. |
3656 ]. |
3657 ]. |
3657 ]. |
3658 |
3658 |
3659 ^ result compressed |
3659 ^ result compressed |
3660 |
3660 |
3661 "Modified: 24.3.1997 / 21:32:41 / cg" |
3661 "Modified: 24.3.1997 / 21:32:41 / cg" |
4597 %{ |
4597 %{ |
4598 OBJ _digitByteArray = __INST(digitByteArray); |
4598 OBJ _digitByteArray = __INST(digitByteArray); |
4599 |
4599 |
4600 if (__isByteArray(_digitByteArray) |
4600 if (__isByteArray(_digitByteArray) |
4601 && __isByteArray(otherDigitByteArray)) { |
4601 && __isByteArray(otherDigitByteArray)) { |
4602 int _len1, _len2, _newLen; |
4602 int _len1, _len2, _newLen; |
4603 unsigned char *_myDigits, *_otherDigits, *_newDigits; |
4603 unsigned char *_myDigits, *_otherDigits, *_newDigits; |
4604 int _index, _carry; |
4604 int _index, _carry; |
4605 int _comLen; |
4605 int _comLen; |
4606 |
4606 |
4607 _len1 = __byteArraySize(_digitByteArray); |
4607 _len1 = __byteArraySize(_digitByteArray); |
4608 _len2 = __byteArraySize(otherDigitByteArray); |
4608 _len2 = __byteArraySize(otherDigitByteArray); |
4609 |
4609 |
4610 _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
4610 _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
4611 _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
4611 _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
4612 |
4612 |
4613 if (_len1 < _len2) { |
4613 if (_len1 < _len2) { |
4614 _comLen = _len1; |
4614 _comLen = _len1; |
4615 _newLen = _len2; |
4615 _newLen = _len2; |
4616 if (_otherDigits[_len2 - 1] == 0xFF) _newLen++; |
4616 if (_otherDigits[_len2 - 1] == 0xFF) _newLen++; |
4617 } else if (_len2 < _len1) { |
4617 } else if (_len2 < _len1) { |
4618 _comLen = _len2; |
4618 _comLen = _len2; |
4619 _newLen = _len1; |
4619 _newLen = _len1; |
4620 if (_myDigits[_len1 - 1] == 0xFF) _newLen++; |
4620 if (_myDigits[_len1 - 1] == 0xFF) _newLen++; |
4621 } else { |
4621 } else { |
4622 /* |
4622 /* |
4623 * there can only be an overflow from the high bytes, |
4623 * there can only be an overflow from the high bytes, |
4624 * if their sum is >= 255 |
4624 * if their sum is >= 255 |
4625 * (with sum==255, a carry could still occur from the next lower bytes) |
4625 * (with sum==255, a carry could still occur from the next lower bytes) |
4626 */ |
4626 */ |
4627 _newLen = _len1; |
4627 _newLen = _len1; |
4628 if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) { |
4628 if ((_otherDigits[_len2 - 1] + _myDigits[_len1 - 1]) >= 0xFF) { |
4629 _newLen++; |
4629 _newLen++; |
4630 } else { |
4630 } else { |
4631 if (_newLen == sizeof(INT)) { |
4631 if (_newLen == sizeof(INT)) { |
4632 OBJ _uint; |
4632 OBJ _uint; |
4633 |
4633 |
4634 /* |
4634 /* |
4635 * two word-sized numbers, no carry - a very common case ... |
4635 * two word-sized numbers, no carry - a very common case ... |
4636 */ |
4636 */ |
4637 #if defined(__LSB_FIRST__) |
4637 #if defined(__LSB_FIRST__) |
4638 unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits; |
4638 unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits; |
4639 #else |
4639 #else |
4640 unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger); |
4640 unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger); |
4641 #endif /* not LSB_FIRST */ |
4641 #endif /* not LSB_FIRST */ |
4642 if (_sum <= _MAX_INT) { |
4642 if (_sum <= _MAX_INT) { |
4643 _uint = __mkSmallInteger(_sum * __intVal(newSign)); |
4643 _uint = __mkSmallInteger(_sum * __intVal(newSign)); |
4644 } else { |
4644 } else { |
4645 _uint = __MKULARGEINT(_sum); |
4645 _uint = __MKULARGEINT(_sum); |
4646 __LargeIntegerInstPtr(_uint)->l_sign = newSign; |
4646 __LargeIntegerInstPtr(_uint)->l_sign = newSign; |
4647 } |
4647 } |
4648 RETURN (_uint); |
4648 RETURN (_uint); |
4649 } |
4649 } |
4650 } |
4650 } |
4651 _comLen = _len1; |
4651 _comLen = _len1; |
4652 } |
4652 } |
4653 resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen); |
4653 resultDigitByteArray = __BYTEARRAY_UNINITIALIZED_NEW_INT(_newLen); |
4654 |
4654 |
4655 /* |
4655 /* |
4656 * must refetch - GC could have been invoked |
4656 * must refetch - GC could have been invoked |
4657 */ |
4657 */ |
4658 _digitByteArray = __INST(digitByteArray); |
4658 _digitByteArray = __INST(digitByteArray); |
4659 |
4659 |
4660 _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
4660 _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
4661 _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
4661 _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
4662 _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
4662 _newDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
4663 |
4663 |
4664 /* |
4664 /* |
4665 * add them ... |
4665 * add them ... |
4666 */ |
4666 */ |
4667 _index = 1; |
4667 _index = 1; |
4668 _carry = 0; |
4668 _carry = 0; |
4669 |
4669 |
4670 #if defined(__LSBFIRST__) |
4670 #if defined(__LSBFIRST__) |
4671 # if (__POINTER_SIZE__ == 8) && defined(__GNUC__) |
4671 # if (__POINTER_SIZE__ == 8) && defined(__GNUC__) |
4672 # if 0 /* not faster (on alpha) */ |
4672 # if 0 /* not faster (on alpha) */ |
4673 { |
4673 { |
4674 int _comLen7; |
4674 int _comLen7; |
4675 |
4675 |
4676 /* |
4676 /* |
4677 * have a 64bit integers; |
4677 * have a 64bit integers; |
4678 * add quad-wise |
4678 * add quad-wise |
4679 * accessing bytes at: [index-1][index][index+1]..[index+6] |
4679 * accessing bytes at: [index-1][index][index+1]..[index+6] |
4680 */ |
4680 */ |
4681 _comLen7 = _comLen - 3 - 4; |
4681 _comLen7 = _comLen - 3 - 4; |
4682 while (_index <= _comLen7) { |
4682 while (_index <= _comLen7) { |
4683 UINT64 _sum, _t1, _t2; |
4683 UINT64 _sum, _t1, _t2; |
4684 |
4684 |
4685 asm ("addq %5,%6,%1 /* sum */ \n\ |
4685 asm ("addq %5,%6,%1 /* sum */ \n\ |
4686 addq %0,%1,%1 /* plus carryIn */ \n\ |
4686 addq %0,%1,%1 /* plus carryIn */ \n\ |
4687 cmpult %1,%5,%2 /* was there a carry ? */ \n\ |
4687 cmpult %1,%5,%2 /* was there a carry ? */ \n\ |
4688 cmpult %1,%6,%3 /* was there a carry ? */ \n\ |
4688 cmpult %1,%6,%3 /* was there a carry ? */ \n\ |
4689 bis %2,%3,%0 /* carryOut */ \n\ |
4689 bis %2,%3,%0 /* carryOut */ \n\ |
4690 " |
4690 " |
4691 : "=r" (_carry), |
4691 : "=r" (_carry), |
4692 "=r" (_sum), |
4692 "=r" (_sum), |
4693 "r" (_t1), |
4693 "r" (_t1), |
4694 "r" (_t2) |
4694 "r" (_t2) |
4695 : "r" (_carry), |
4695 : "r" (_carry), |
4696 "r" (((unsigned long *)(&(_myDigits[_index - 1])))[0]), |
4696 "r" (((unsigned long *)(&(_myDigits[_index - 1])))[0]), |
4697 "r" (((unsigned long *)(&(_otherDigits[_index - 1])))[0]) |
4697 "r" (((unsigned long *)(&(_otherDigits[_index - 1])))[0]) |
4698 ); |
4698 ); |
4699 /* _sum = _sum & 0xFFFFFFFF; */ |
4699 /* _sum = _sum & 0xFFFFFFFF; */ |
4700 ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum; |
4700 ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum; |
4701 _index += 8; |
4701 _index += 8; |
4702 } |
4702 } |
4703 } |
4703 } |
4704 # endif |
4704 # endif |
4705 # endif /* 64bit */ |
4705 # endif /* 64bit */ |
4706 |
4706 |
4707 # if (__POINTER_SIZE__ == 8) |
4707 # if (__POINTER_SIZE__ == 8) |
4708 # if 0 /* not faster (on alpha) */ |
4708 # if 0 /* not faster (on alpha) */ |
4709 { |
4709 { |
4710 int _comLen7; |
4710 int _comLen7; |
4711 |
4711 |
4712 /* |
4712 /* |
4713 * have a 64bit integers; |
4713 * have a 64bit integers; |
4714 * add quad-wise |
4714 * add quad-wise |
4715 * accessing bytes at: [index-1][index][index+1]..[index+6] |
4715 * accessing bytes at: [index-1][index][index+1]..[index+6] |
4716 */ |
4716 */ |
4717 _comLen7 = _comLen - 3 - 4; |
4717 _comLen7 = _comLen - 3 - 4; |
4718 while (_index <= _comLen7) { |
4718 while (_index <= _comLen7) { |
4719 UINT64 _sum, _t1, _t2; |
4719 UINT64 _sum, _t1, _t2; |
4720 |
4720 |
4721 _t1 = ((UINT64 *)(&(_myDigits[_index - 1])))[0]; |
4721 _t1 = ((UINT64 *)(&(_myDigits[_index - 1])))[0]; |
4722 _t2 = ((UINT64 *)(&(_otherDigits[_index - 1])))[0]; |
4722 _t2 = ((UINT64 *)(&(_otherDigits[_index - 1])))[0]; |
4723 _sum = _t1 + _t2 + _carry; |
4723 _sum = _t1 + _t2 + _carry; |
4724 ((UINT64 *)(&(_newDigits[_index - 1])))[0] = _sum; |
4724 ((UINT64 *)(&(_newDigits[_index - 1])))[0] = _sum; |
4725 _carry = (_sum < _t1) | (_sum < _t2); |
4725 _carry = (_sum < _t1) | (_sum < _t2); |
4726 _index += 8; |
4726 _index += 8; |
4727 } |
4727 } |
4728 } |
4728 } |
4729 # endif |
4729 # endif |
4730 # endif /* 64bit */ |
4730 # endif /* 64bit */ |
4731 |
4731 |
4732 # ifdef UINT64 |
4732 # ifdef UINT64 |
4733 { |
4733 { |
4734 int _comLen3; |
4734 int _comLen3; |
4735 |
4735 |
4736 /* |
4736 /* |
4737 * have a 64bit integer type; |
4737 * have a 64bit integer type; |
4738 * add int-wise |
4738 * add int-wise |
4739 * accessing bytes at: [index-1][index][index+1][index+2] |
4739 * accessing bytes at: [index-1][index][index+1][index+2] |
4740 */ |
4740 */ |
4741 _comLen3 = _comLen - 3; |
4741 _comLen3 = _comLen - 3; |
4742 while (_index <= _comLen3) { |
4742 while (_index <= _comLen3) { |
4743 UINT64 _sum; |
4743 UINT64 _sum; |
4744 |
4744 |
4745 /* do not merge the 3 lines below into one - |
4745 /* do not merge the 3 lines below into one - |
4746 * (will do sign extension then, which is wrong here) |
4746 * (will do sign extension then, which is wrong here) |
4747 */ |
4747 */ |
4748 _sum = (unsigned)_carry; |
4748 _sum = (unsigned)_carry; |
4749 _sum += ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4749 _sum += ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4750 _sum += ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4750 _sum += ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4751 _carry = _sum >> 32; |
4751 _carry = _sum >> 32; |
4752 /* _sum = _sum & 0xFFFFFFFF; */ |
4752 /* _sum = _sum & 0xFFFFFFFF; */ |
4753 ((unsigned int *)(&(_newDigits[_index - 1])))[0] = _sum; |
4753 ((unsigned int *)(&(_newDigits[_index - 1])))[0] = _sum; |
4754 _index += 4; |
4754 _index += 4; |
4755 } |
4755 } |
4756 } |
4756 } |
4757 # else |
4757 # else |
4758 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4) |
4758 # if defined(__i386__) && defined(__GNUC__) && (__POINTER_SIZE__ == 4) |
4759 { |
4759 { |
4760 int _comLen3; |
4760 int _comLen3; |
4761 |
4761 |
4762 _comLen3 = _comLen - 3 - 4; |
4762 _comLen3 = _comLen - 3 - 4; |
4763 while (_index <= _comLen3) { |
4763 while (_index <= _comLen3) { |
4764 unsigned int _sum, _sum2; |
4764 unsigned int _sum, _sum2; |
4765 unsigned int __in1A, __in1B, __in2A, __in2B; |
4765 unsigned int __in1A, __in1B, __in2A, __in2B; |
4766 |
4766 |
4767 __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4767 __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4768 __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1]; |
4768 __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1]; |
4769 __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4769 __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4770 __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1]; |
4770 __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1]; |
4771 |
4771 |
4772 asm ("addl %%edx,%%eax \n\ |
4772 asm ("addl %%edx,%%eax \n\ |
4773 movl $0,%%edx \n\ |
4773 movl $0,%%edx \n\ |
4774 adcl $0,%%edx \n\ |
4774 adcl $0,%%edx \n\ |
4775 addl %5,%%eax \n\ |
4775 addl %5,%%eax \n\ |
4776 adcl $0,%%edx \n\ |
4776 adcl $0,%%edx \n\ |
4777 \n\ |
4777 \n\ |
4778 addl %%edx,%%ecx \n\ |
4778 addl %%edx,%%ecx \n\ |
4779 movl $0,%%edx \n\ |
4779 movl $0,%%edx \n\ |
4780 adcl $0,%%edx \n\ |
4780 adcl $0,%%edx \n\ |
4781 addl %7,%%ecx \n\ |
4781 addl %7,%%ecx \n\ |
4782 adcl $0,%%edx \n\ |
4782 adcl $0,%%edx \n\ |
4783 " |
4783 " |
4784 : "=d" (_carry), |
4784 : "=d" (_carry), |
4785 "=a" (_sum), |
4785 "=a" (_sum), |
4786 "=c" (_sum2) |
4786 "=c" (_sum2) |
4787 : "0" (_carry), |
4787 : "0" (_carry), |
4788 "1" (__in1A), |
4788 "1" (__in1A), |
4789 "rm" (__in1B), |
4789 "rm" (__in1B), |
4790 "2" (__in2A), |
4790 "2" (__in2A), |
4791 "rm" (__in2B) |
4791 "rm" (__in2B) |
4792 ); |
4792 ); |
4793 |
4793 |
4794 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum; |
4794 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum; |
4795 ((unsigned *)(&(_newDigits[_index - 1])))[1] = _sum2; |
4795 ((unsigned *)(&(_newDigits[_index - 1])))[1] = _sum2; |
4796 _index += 8; |
4796 _index += 8; |
4797 } |
4797 } |
4798 /* |
4798 /* |
4799 * add int-wise |
4799 * add int-wise |
4800 * accessing bytes at: [index-1][index][index+1][index+2] |
4800 * accessing bytes at: [index-1][index][index+1][index+2] |
4801 */ |
4801 */ |
4802 _comLen3 = _comLen3 + 4; |
4802 _comLen3 = _comLen3 + 4; |
4803 if (_index <= _comLen3) { |
4803 if (_index <= _comLen3) { |
4804 unsigned int _sum; |
4804 unsigned int _sum; |
4805 unsigned int __inA, __inB; |
4805 unsigned int __inA, __inB; |
4806 |
4806 |
4807 __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4807 __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4808 __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4808 __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4809 |
4809 |
4810 asm ("addl %%edx,%%eax \n\ |
4810 asm ("addl %%edx,%%eax \n\ |
4811 movl $0,%%edx \n\ |
4811 movl $0,%%edx \n\ |
4812 adcl $0,%%edx \n\ |
4812 adcl $0,%%edx \n\ |
4813 addl %4,%%eax \n\ |
4813 addl %4,%%eax \n\ |
4814 adcl $0,%%edx" |
4814 adcl $0,%%edx" |
4815 : "=d" (_carry), |
4815 : "=d" (_carry), |
4816 "=a" (_sum) |
4816 "=a" (_sum) |
4817 : "0" (_carry), |
4817 : "0" (_carry), |
4818 "1" (__inA), |
4818 "1" (__inA), |
4819 "rm" (__inB) |
4819 "rm" (__inB) |
4820 ); |
4820 ); |
4821 |
4821 |
4822 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum; |
4822 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum; |
4823 _index += 4; |
4823 _index += 4; |
4824 } |
4824 } |
4825 } |
4825 } |
4826 # endif /* __i386__ && GNUC */ |
4826 # endif /* __i386__ && GNUC */ |
4827 # if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4) |
4827 # if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4) |
4828 { |
4828 { |
4829 int _comLen3; |
4829 int _comLen3; |
4830 |
4830 |
4831 /* |
4831 /* |
4832 * add long-wise |
4832 * add long-wise |
4833 * accessing bytes at: [index-1][index][index+1][index+2] |
4833 * accessing bytes at: [index-1][index][index+1][index+2] |
4834 */ |
4834 */ |
4835 _comLen3 = _comLen - 3; |
4835 _comLen3 = _comLen - 3; |
4836 while (_index <= _comLen3) { |
4836 while (_index <= _comLen3) { |
4837 unsigned int _sum, _v1, _v2; |
4837 unsigned int _sum, _v1, _v2; |
4838 |
4838 |
4839 _v1 = ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4839 _v1 = ((unsigned int *)(&(_myDigits[_index - 1])))[0]; |
4840 _v2 = ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4840 _v2 = ((unsigned int *)(&(_otherDigits[_index - 1])))[0]; |
4841 asm { |
4841 asm { |
4842 mov eax, _v1 |
4842 mov eax, _v1 |
4843 add eax, _v2 |
4843 add eax, _v2 |
4844 mov edx, 0 |
4844 mov edx, 0 |
4845 adc edx, 0 |
4845 adc edx, 0 |
4846 add eax, _carry |
4846 add eax, _carry |
4847 adc edx, 0 |
4847 adc edx, 0 |
4848 mov _carry, edx |
4848 mov _carry, edx |
4849 mov _sum, eax |
4849 mov _sum, eax |
4850 } |
4850 } |
4851 |
4851 |
4852 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum; |
4852 ((unsigned *)(&(_newDigits[_index - 1])))[0] = _sum; |
4853 _index += 4; |
4853 _index += 4; |
4854 } |
4854 } |
4855 } |
4855 } |
4856 # endif /* __i386__ && WIN32 */ |
4856 # endif /* __i386__ && WIN32 */ |
4857 # endif /* INT64 */ |
4857 # endif /* INT64 */ |
4858 /* |
4858 /* |
4859 * add short-wise |
4859 * add short-wise |
4860 * accessing bytes at: [index-1][index] |
4860 * accessing bytes at: [index-1][index] |
4861 */ |
4861 */ |
4862 while (_index < _comLen) { |
4862 while (_index < _comLen) { |
4863 unsigned int _sum; |
4863 unsigned int _sum; |
4864 |
4864 |
4865 _sum = _carry |
4865 _sum = _carry |
4866 + ((unsigned short *)(&(_myDigits[_index - 1])))[0] |
4866 + ((unsigned short *)(&(_myDigits[_index - 1])))[0] |
4867 + ((unsigned short *)(&(_otherDigits[_index - 1])))[0]; |
4867 + ((unsigned short *)(&(_otherDigits[_index - 1])))[0]; |
4868 _carry = _sum >> 16; |
4868 _carry = _sum >> 16; |
4869 /* _sum = _sum & 0xFFFF; */ |
4869 /* _sum = _sum & 0xFFFF; */ |
4870 *(unsigned short *)(&(_newDigits[_index - 1])) = _sum; |
4870 *(unsigned short *)(&(_newDigits[_index - 1])) = _sum; |
4871 _index += 2; |
4871 _index += 2; |
4872 } |
4872 } |
4873 #else |
4873 #else |
4874 # ifdef __sparc__ |
4874 # ifdef __sparc__ |
4875 /* |
4875 /* |
4876 * add short-wise |
4876 * add short-wise |
4877 * accessing bytes at: [index-1][index] |
4877 * accessing bytes at: [index-1][index] |
4878 */ |
4878 */ |
4879 while (_index < _comLen) { |
4879 while (_index < _comLen) { |
4880 unsigned int _sum; |
4880 unsigned int _sum; |
4881 unsigned short _v1, _v2; |
4881 unsigned short _v1, _v2; |
4882 |
4882 |
4883 _v1 = ((unsigned short *)(&(_myDigits[_index - 1])))[0]; |
4883 _v1 = ((unsigned short *)(&(_myDigits[_index - 1])))[0]; |
4884 _v2 = ((unsigned short *)(&(_otherDigits[_index - 1])))[0]; |
4884 _v2 = ((unsigned short *)(&(_otherDigits[_index - 1])))[0]; |
4885 _sum = _carry + (_v1>>8) + (_v2>>8); |
4885 _sum = _carry + (_v1>>8) + (_v2>>8); |
4886 _carry = _sum >> 8; |
4886 _carry = _sum >> 8; |
4887 _newDigits[_index - 1] = _sum; |
4887 _newDigits[_index - 1] = _sum; |
4888 |
4888 |
4889 _sum = _carry + (_v1 & 0xFF) + (_v2 & 0xFF); |
4889 _sum = _carry + (_v1 & 0xFF) + (_v2 & 0xFF); |
4890 _carry = _sum >> 8; |
4890 _carry = _sum >> 8; |
4891 _newDigits[_index] = _sum; |
4891 _newDigits[_index] = _sum; |
4892 _index += 2; |
4892 _index += 2; |
4893 } |
4893 } |
4894 # endif |
4894 # endif |
4895 #endif /* __LSBFIRST__ */ |
4895 #endif /* __LSBFIRST__ */ |
4896 |
4896 |
4897 /* |
4897 /* |
4898 * add byte-wise |
4898 * add byte-wise |
4899 */ |
4899 */ |
4900 while (_index <= _comLen) { |
4900 while (_index <= _comLen) { |
4901 unsigned int _sum; |
4901 unsigned int _sum; |
4902 |
4902 |
4903 _sum = _carry |
4903 _sum = _carry |
4904 + _myDigits[_index - 1] |
4904 + _myDigits[_index - 1] |
4905 + _otherDigits[_index - 1]; |
4905 + _otherDigits[_index - 1]; |
4906 _carry = _sum >> 8; |
4906 _carry = _sum >> 8; |
4907 /* _sum = _sum & 0xFF; */ |
4907 /* _sum = _sum & 0xFF; */ |
4908 _newDigits[_index - 1] = _sum; |
4908 _newDigits[_index - 1] = _sum; |
4909 _index++; |
4909 _index++; |
4910 } |
4910 } |
4911 |
4911 |
4912 /* |
4912 /* |
4913 * rest |
4913 * rest |
4914 */ |
4914 */ |
4915 if (_len1 > _len2) { |
4915 if (_len1 > _len2) { |
4916 #if defined(__LSBFIRST__) |
4916 #if defined(__LSBFIRST__) |
4917 if (_index <= _len1) { |
4917 if (_index <= _len1) { |
4918 if ((_index - 1) & 1) { |
4918 if ((_index - 1) & 1) { |
4919 /* odd byte */ |
4919 /* odd byte */ |
4920 unsigned int _sum; |
4920 unsigned int _sum; |
4921 |
4921 |
4922 _sum = _carry + _myDigits[_index - 1]; |
4922 _sum = _carry + _myDigits[_index - 1]; |
4923 _carry = _sum >> 8; |
4923 _carry = _sum >> 8; |
4924 /* _sum = _sum & 0xFF; */ |
4924 /* _sum = _sum & 0xFF; */ |
4925 _newDigits[_index - 1] = _sum; |
4925 _newDigits[_index - 1] = _sum; |
4926 _index++; |
4926 _index++; |
4927 } |
4927 } |
4928 |
4928 |
4929 while (_index < _len1) { |
4929 while (_index < _len1) { |
4930 /* shorts */ |
4930 /* shorts */ |
4931 unsigned int _sum; |
4931 unsigned int _sum; |
4932 |
4932 |
4933 _sum = _carry + *(unsigned short *)(&(_myDigits[_index - 1])); |
4933 _sum = _carry + *(unsigned short *)(&(_myDigits[_index - 1])); |
4934 _carry = _sum >> 16; |
4934 _carry = _sum >> 16; |
4935 /* _sum = _sum & 0xFFFF; */ |
4935 /* _sum = _sum & 0xFFFF; */ |
4936 *(unsigned short *)(&(_newDigits[_index - 1])) = _sum; |
4936 *(unsigned short *)(&(_newDigits[_index - 1])) = _sum; |
4937 _index += 2; |
4937 _index += 2; |
4938 } |
4938 } |
4939 |
4939 |
4940 if (_index <= _len1) { |
4940 if (_index <= _len1) { |
4941 /* last byte */ |
4941 /* last byte */ |
4942 unsigned int _sum; |
4942 unsigned int _sum; |
4943 |
4943 |
4944 _sum = _carry + _myDigits[_index - 1]; |
4944 _sum = _carry + _myDigits[_index - 1]; |
4945 _carry = _sum >> 8; |
4945 _carry = _sum >> 8; |
4946 /* _sum = _sum & 0xFF; */ |
4946 /* _sum = _sum & 0xFF; */ |
4947 _newDigits[_index - 1] = _sum; |
4947 _newDigits[_index - 1] = _sum; |
4948 _index++; |
4948 _index++; |
4949 } |
4949 } |
4950 } |
4950 } |
4951 #else |
4951 #else |
4952 while (_index <= _len1) { |
4952 while (_index <= _len1) { |
4953 unsigned int _sum; |
4953 unsigned int _sum; |
4954 |
4954 |
4955 _sum = _carry + _myDigits[_index - 1]; |
4955 _sum = _carry + _myDigits[_index - 1]; |
4956 _carry = _sum >> 8; |
4956 _carry = _sum >> 8; |
4957 /* _sum = _sum & 0xFF; */ |
4957 /* _sum = _sum & 0xFF; */ |
4958 _newDigits[_index - 1] = _sum; |
4958 _newDigits[_index - 1] = _sum; |
4959 _index++; |
4959 _index++; |
4960 } |
4960 } |
4961 #endif /* not LSB */ |
4961 #endif /* not LSB */ |
4962 } else { |
4962 } else { |
4963 if (_len2 > _len1) { |
4963 if (_len2 > _len1) { |
4964 #if defined(__LSBFIRST__) |
4964 #if defined(__LSBFIRST__) |
4965 if (_index <= _len2) { |
4965 if (_index <= _len2) { |
4966 if ((_index - 1) & 1) { |
4966 if ((_index - 1) & 1) { |
4967 /* odd byte */ |
4967 /* odd byte */ |
4968 unsigned int _sum; |
4968 unsigned int _sum; |
4969 |
4969 |
4970 _sum = _carry + _otherDigits[_index - 1]; |
4970 _sum = _carry + _otherDigits[_index - 1]; |
4971 _carry = _sum >> 8; |
4971 _carry = _sum >> 8; |
4972 /* _sum = _sum & 0xFF; */ |
4972 /* _sum = _sum & 0xFF; */ |
4973 _newDigits[_index - 1] = _sum; |
4973 _newDigits[_index - 1] = _sum; |
4974 _index++; |
4974 _index++; |
4975 } |
4975 } |
4976 |
4976 |
4977 while (_index < _len2) { |
4977 while (_index < _len2) { |
4978 /* shorts */ |
4978 /* shorts */ |
4979 unsigned int _sum; |
4979 unsigned int _sum; |
4980 |
4980 |
4981 _sum = _carry + *(unsigned short *)(&(_otherDigits[_index - 1])); |
4981 _sum = _carry + *(unsigned short *)(&(_otherDigits[_index - 1])); |
4982 _carry = _sum >> 16; |
4982 _carry = _sum >> 16; |
4983 /* _sum = _sum & 0xFFFF; */ |
4983 /* _sum = _sum & 0xFFFF; */ |
4984 *(unsigned short *)(&(_newDigits[_index - 1])) = _sum; |
4984 *(unsigned short *)(&(_newDigits[_index - 1])) = _sum; |
4985 _index += 2; |
4985 _index += 2; |
4986 } |
4986 } |
4987 |
4987 |
4988 if (_index <= _len2) { |
4988 if (_index <= _len2) { |
4989 /* last byte */ |
4989 /* last byte */ |
4990 unsigned int _sum; |
4990 unsigned int _sum; |
4991 |
4991 |
4992 _sum = _carry + _otherDigits[_index - 1]; |
4992 _sum = _carry + _otherDigits[_index - 1]; |
4993 _carry = _sum >> 8; |
4993 _carry = _sum >> 8; |
4994 /* _sum = _sum & 0xFF; */ |
4994 /* _sum = _sum & 0xFF; */ |
4995 _newDigits[_index - 1] = _sum; |
4995 _newDigits[_index - 1] = _sum; |
4996 _index++; |
4996 _index++; |
4997 } |
4997 } |
4998 } |
4998 } |
4999 #else |
4999 #else |
5000 while (_index <= _len2) { |
5000 while (_index <= _len2) { |
5001 unsigned int _sum; |
5001 unsigned int _sum; |
5002 |
5002 |
5003 _sum = _carry + _otherDigits[_index - 1]; |
5003 _sum = _carry + _otherDigits[_index - 1]; |
5004 _carry = _sum >> 8; |
5004 _carry = _sum >> 8; |
5005 /* _sum = _sum & 0xFF; */ |
5005 /* _sum = _sum & 0xFF; */ |
5006 _newDigits[_index - 1] = _sum; |
5006 _newDigits[_index - 1] = _sum; |
5007 _index++; |
5007 _index++; |
5008 } |
5008 } |
5009 #endif /* not LSB */ |
5009 #endif /* not LSB */ |
5010 } |
5010 } |
5011 } |
5011 } |
5012 |
5012 |
5013 while (_index <= _newLen) { |
5013 while (_index <= _newLen) { |
5014 unsigned int _sum; |
5014 unsigned int _sum; |
5015 |
5015 |
5016 _sum = _carry; |
5016 _sum = _carry; |
5017 _carry = _sum >> 8; |
5017 _carry = _sum >> 8; |
5018 /* _sum = _sum & 0xFF; */ |
5018 /* _sum = _sum & 0xFF; */ |
5019 _newDigits[_index - 1] = _sum; |
5019 _newDigits[_index - 1] = _sum; |
5020 _index++; |
5020 _index++; |
5021 } |
5021 } |
5022 } |
5022 } |
5023 %}. |
5023 %}. |
5024 resultDigitByteArray notNil ifTrue:[ |
5024 resultDigitByteArray notNil ifTrue:[ |
5025 result := self class basicNew. |
5025 result := self class basicNew. |
5026 result setDigits:resultDigitByteArray. |
5026 result setDigits:resultDigitByteArray. |
5027 result setSign:newSign. |
5027 result setSign:newSign. |
5028 ] ifFalse:[ |
5028 ] ifFalse:[ |
5029 len1 := digitByteArray size. |
5029 len1 := digitByteArray size. |
5030 len2 := otherDigitByteArray size. |
5030 len2 := otherDigitByteArray size. |
5031 |
5031 |
5032 "/ earlier versions estimated the newLength as: |
5032 "/ earlier versions estimated the newLength as: |
5033 "/ (len1 max:len2) + 1 |
5033 "/ (len1 max:len2) + 1 |
5034 "/ and reduced the result. |
5034 "/ and reduced the result. |
5035 "/ however, if one of the addends is smaller, |
5035 "/ however, if one of the addends is smaller, |
5036 "/ the result will never require another digit, |
5036 "/ the result will never require another digit, |
5037 "/ if the highest digit of the larger addent is |
5037 "/ if the highest digit of the larger addent is |
5038 "/ not equal to 255. Therefore, in most cases, |
5038 "/ not equal to 255. Therefore, in most cases, |
5039 "/ we can avoid the computation and resizing |
5039 "/ we can avoid the computation and resizing |
5040 "/ in #reduced. |
5040 "/ in #reduced. |
5041 |
5041 |
5042 len1 < len2 ifTrue:[ |
5042 len1 < len2 ifTrue:[ |
5043 newLen := len2. |
5043 newLen := len2. |
5044 (otherDigitByteArray at:len2) == 16rFF ifTrue:[ |
5044 (otherDigitByteArray at:len2) == 16rFF ifTrue:[ |
5045 newLen := newLen + 1 |
5045 newLen := newLen + 1 |
5046 ] |
5046 ] |
5047 ] ifFalse:[ |
5047 ] ifFalse:[ |
5048 len2 < len1 ifTrue:[ |
5048 len2 < len1 ifTrue:[ |
5049 newLen := len1. |
5049 newLen := len1. |
5050 (digitByteArray at:len1) == 16rFF ifTrue:[ |
5050 (digitByteArray at:len1) == 16rFF ifTrue:[ |
5051 newLen := newLen + 1 |
5051 newLen := newLen + 1 |
5052 ] |
5052 ] |
5053 ] ifFalse:[ |
5053 ] ifFalse:[ |
5054 newLen := len1 + 1. |
5054 newLen := len1 + 1. |
5055 ] |
5055 ] |
5056 ]. |
5056 ]. |
5057 |
5057 |
5058 result := self class basicNew numberOfDigits:newLen. |
5058 result := self class basicNew numberOfDigits:newLen. |
5059 result sign:newSign. |
5059 result sign:newSign. |
5060 resultDigitByteArray := result digitBytes. |
5060 resultDigitByteArray := result digitBytes. |
5061 |
5061 |
5062 index := 1. |
5062 index := 1. |
5063 carry := 0. |
5063 carry := 0. |
5064 |
5064 |
5065 done := false. |
5065 done := false. |
5066 [done] whileFalse:[ |
5066 [done] whileFalse:[ |
5067 sum := carry. |
5067 sum := carry. |
5068 (index <= len1) ifTrue:[ |
5068 (index <= len1) ifTrue:[ |
5069 sum := sum + (digitByteArray basicAt:index). |
5069 sum := sum + (digitByteArray basicAt:index). |
5070 (index <= len2) ifTrue:[ |
5070 (index <= len2) ifTrue:[ |
5071 sum := sum + (otherDigitByteArray basicAt:index) |
5071 sum := sum + (otherDigitByteArray basicAt:index) |
5072 ] |
5072 ] |
5073 ] ifFalse:[ |
5073 ] ifFalse:[ |
5074 (index <= len2) ifTrue:[ |
5074 (index <= len2) ifTrue:[ |
5075 sum := sum + (otherDigitByteArray basicAt:index) |
5075 sum := sum + (otherDigitByteArray basicAt:index) |
5076 ] ifFalse:[ |
5076 ] ifFalse:[ |
5077 "end reached" |
5077 "end reached" |
5078 done := true |
5078 done := true |
5079 ] |
5079 ] |
5080 ]. |
5080 ]. |
5081 (sum >= 16r100) ifTrue:[ |
5081 (sum >= 16r100) ifTrue:[ |
5082 carry := 1. |
5082 carry := 1. |
5083 sum := sum - 16r100 |
5083 sum := sum - 16r100 |
5084 ] ifFalse:[ |
5084 ] ifFalse:[ |
5085 carry := 0 |
5085 carry := 0 |
5086 ]. |
5086 ]. |
5087 resultDigitByteArray basicAt:index put:sum. |
5087 resultDigitByteArray basicAt:index put:sum. |
5088 index := index + 1 |
5088 index := index + 1 |
5089 ]. |
5089 ]. |
5090 ]. |
5090 ]. |
5091 |
5091 |
5092 ^ result compressed |
5092 ^ result compressed |
5093 |
5093 |
5094 "Modified: 11.8.1997 / 03:23:37 / cg" |
5094 "Modified: 11.8.1997 / 03:23:37 / cg" |
5095 ! |
5095 ! |
5096 |
5096 |
5097 absSubtract:aLargeInteger |
5097 absSubtract:aLargeInteger |
5098 "private helper for division: |
5098 "private helper for division: |
5099 destructively subtract aLargeInteger from myself |
5099 destructively subtract aLargeInteger from myself |
5100 AND return true, if the result is non-zero, false otherwise. |
5100 AND return true, if the result is non-zero, false otherwise. |
5101 (i.e. this method has both a return value and a side-effect |
5101 (i.e. this method has both a return value and a side-effect |
5102 on the receiver) |
5102 on the receiver) |
5103 Only allowed for positive receiver and argument |
5103 Only allowed for positive receiver and argument |
5104 The receiver must be >= the argument. |
5104 The receiver must be >= the argument. |
5105 The receiver must be a temporary scratch-number" |
5105 The receiver must be a temporary scratch-number" |
5106 |
5106 |
5107 |otherDigitByteArray |
5107 |otherDigitByteArray |
5108 len1 "{ Class: SmallInteger }" |
5108 len1 "{ Class: SmallInteger }" |
5109 len2 "{ Class: SmallInteger }" |
5109 len2 "{ Class: SmallInteger }" |
5110 index "{ Class: SmallInteger }" |
5110 index "{ Class: SmallInteger }" |
5116 notZero := false. |
5116 notZero := false. |
5117 len1 := digitByteArray size. |
5117 len1 := digitByteArray size. |
5118 otherDigitByteArray := aLargeInteger digitBytes. |
5118 otherDigitByteArray := aLargeInteger digitBytes. |
5119 len2 := otherDigitByteArray size. |
5119 len2 := otherDigitByteArray size. |
5120 len2 > len1 ifTrue:[ |
5120 len2 > len1 ifTrue:[ |
5121 [(otherDigitByteArray at:len2) == 0] whileTrue:[ |
5121 [(otherDigitByteArray at:len2) == 0] whileTrue:[ |
5122 len2 := len2 - 1 |
5122 len2 := len2 - 1 |
5123 ]. |
5123 ]. |
5124 len2 > len1 ifTrue:[ |
5124 len2 > len1 ifTrue:[ |
5125 self error:'operation failed' "/ may not be called that way |
5125 self error:'operation failed' "/ may not be called that way |
5126 ]. |
5126 ]. |
5127 ]. |
5127 ]. |
5128 "/ knowing that len2 is <= len1 |
5128 "/ knowing that len2 is <= len1 |
5129 %{ |
5129 %{ |
5130 |
5130 |
5131 OBJ _digitByteArray = __INST(digitByteArray); |
5131 OBJ _digitByteArray = __INST(digitByteArray); |
5132 |
5132 |
5133 if (__isByteArray(_digitByteArray) |
5133 if (__isByteArray(_digitByteArray) |
5134 && __isByteArray(otherDigitByteArray)) { |
5134 && __isByteArray(otherDigitByteArray)) { |
5135 int _len1 = __intVal(len1), |
5135 int _len1 = __intVal(len1), |
5136 _len2 = __intVal(len2); |
5136 _len2 = __intVal(len2); |
5137 unsigned char *_myDigits, *_otherDigits; |
5137 unsigned char *_myDigits, *_otherDigits; |
5138 int _index = 1, _borrow = 0; |
5138 int _index = 1, _borrow = 0; |
5139 INT _diff; |
5139 INT _diff; |
5140 int anyBitNonZero = 0; |
5140 int anyBitNonZero = 0; |
5141 |
5141 |
5142 _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
5142 _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
5143 _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
5143 _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
5144 |
5144 |
5145 #if defined(__LSBFIRST__) |
5145 #if defined(__LSBFIRST__) |
5146 # if __POINTER_SIZE__ == 8 |
5146 # if __POINTER_SIZE__ == 8 |
5147 { |
5147 { |
5148 int _len2Q; |
5148 int _len2Q; |
5149 /* |
5149 /* |
5150 * subtract int-wise |
5150 * subtract int-wise |
5151 */ |
5151 */ |
5152 _len2Q = _len2-2; |
5152 _len2Q = _len2-2; |
5153 while (_index < _len2Q) { |
5153 while (_index < _len2Q) { |
5154 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5154 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5155 _diff = ((unsigned int *)(_myDigits+_index-1))[0]; |
5155 _diff = ((unsigned int *)(_myDigits+_index-1))[0]; |
5156 _diff -= ((unsigned int *)(_otherDigits+_index-1))[0]; |
5156 _diff -= ((unsigned int *)(_otherDigits+_index-1))[0]; |
5157 _diff -= _borrow; |
5157 _diff -= _borrow; |
5158 if (_diff >= 0) { |
5158 if (_diff >= 0) { |
5159 _borrow = 0; |
5159 _borrow = 0; |
5160 } else { |
5160 } else { |
5161 _borrow = 1; |
5161 _borrow = 1; |
5162 /* _diff += 0x10000; */ |
5162 /* _diff += 0x10000; */ |
5163 } |
5163 } |
5164 ((unsigned int *)(_myDigits+_index-1))[0] = _diff; |
5164 ((unsigned int *)(_myDigits+_index-1))[0] = _diff; |
5165 anyBitNonZero |= (_diff & 0xFFFFFFFFL); |
5165 anyBitNonZero |= (_diff & 0xFFFFFFFFL); |
5166 _index += 4; |
5166 _index += 4; |
5167 } |
5167 } |
5168 } |
5168 } |
5169 # endif |
5169 # endif |
5170 |
5170 |
5171 /* |
5171 /* |
5172 * subtract short-wise |
5172 * subtract short-wise |
5173 */ |
5173 */ |
5174 while (_index < _len2) { |
5174 while (_index < _len2) { |
5175 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5175 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5176 _diff = ((unsigned short *)(_myDigits+_index-1))[0]; |
5176 _diff = ((unsigned short *)(_myDigits+_index-1))[0]; |
5177 _diff -= ((unsigned short *)(_otherDigits+_index-1))[0]; |
5177 _diff -= ((unsigned short *)(_otherDigits+_index-1))[0]; |
5178 _diff -= _borrow; |
5178 _diff -= _borrow; |
5179 if (_diff >= 0) { |
5179 if (_diff >= 0) { |
5180 _borrow = 0; |
5180 _borrow = 0; |
5181 } else { |
5181 } else { |
5182 _borrow = 1; |
5182 _borrow = 1; |
5183 /* _diff += 0x10000; */ |
5183 /* _diff += 0x10000; */ |
5184 } |
5184 } |
5185 ((unsigned short *)(_myDigits+_index-1))[0] = _diff; |
5185 ((unsigned short *)(_myDigits+_index-1))[0] = _diff; |
5186 anyBitNonZero |= (_diff & 0xFFFF); |
5186 anyBitNonZero |= (_diff & 0xFFFF); |
5187 _index += 2; |
5187 _index += 2; |
5188 } |
5188 } |
5189 |
5189 |
5190 if (_index <= _len2) { |
5190 if (_index <= _len2) { |
5191 /* |
5191 /* |
5192 * cannot continue with shorts - there is an odd number of |
5192 * cannot continue with shorts - there is an odd number of |
5193 * bytes in the minuent |
5193 * bytes in the minuent |
5194 */ |
5194 */ |
5195 } else { |
5195 } else { |
5196 while (_index < _len1) { |
5196 while (_index < _len1) { |
5197 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5197 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5198 _diff = ((unsigned short *)(_myDigits+_index-1))[0]; |
5198 _diff = ((unsigned short *)(_myDigits+_index-1))[0]; |
5199 _diff -= _borrow; |
5199 _diff -= _borrow; |
5200 if (_diff >= 0) { |
5200 if (_diff >= 0) { |
5201 /* _borrow = 0; */ |
5201 /* _borrow = 0; */ |
5202 ((unsigned short *)(_myDigits+_index-1))[0] = _diff; |
5202 ((unsigned short *)(_myDigits+_index-1))[0] = _diff; |
5203 anyBitNonZero |= (_diff & 0xFFFF); |
5203 anyBitNonZero |= (_diff & 0xFFFF); |
5204 _index += 2; |
5204 _index += 2; |
5205 while (_index < _len1) { |
5205 while (_index < _len1) { |
5206 anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0]; |
5206 anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0]; |
5207 if (anyBitNonZero) { |
5207 if (anyBitNonZero) { |
5208 RETURN (true); |
5208 RETURN (true); |
5209 } |
5209 } |
5210 _index += 2; |
5210 _index += 2; |
5211 } |
5211 } |
5212 /* last odd index */ |
5212 /* last odd index */ |
5213 if (_index <= _len1) { |
5213 if (_index <= _len1) { |
5214 anyBitNonZero |= _myDigits[_index - 1];; |
5214 anyBitNonZero |= _myDigits[_index - 1];; |
5215 if (anyBitNonZero) { |
5215 if (anyBitNonZero) { |
5216 RETURN (true); |
5216 RETURN (true); |
5217 } |
5217 } |
5218 _index++; |
5218 _index++; |
5219 } |
5219 } |
5220 RETURN (anyBitNonZero ? true : false); |
5220 RETURN (anyBitNonZero ? true : false); |
5221 } |
5221 } |
5222 _borrow = 1; |
5222 _borrow = 1; |
5223 /* _diff += 0x10000; */ |
5223 /* _diff += 0x10000; */ |
5224 |
5224 |
5225 ((unsigned short *)(_myDigits+_index-1))[0] = _diff; |
5225 ((unsigned short *)(_myDigits+_index-1))[0] = _diff; |
5226 anyBitNonZero |= (_diff & 0xFFFF); |
5226 anyBitNonZero |= (_diff & 0xFFFF); |
5227 _index += 2; |
5227 _index += 2; |
5228 } |
5228 } |
5229 } |
5229 } |
5230 #endif |
5230 #endif |
5231 /* |
5231 /* |
5232 * subtract byte-wise |
5232 * subtract byte-wise |
5233 */ |
5233 */ |
5234 while (_index <= _len2) { |
5234 while (_index <= _len2) { |
5235 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5235 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5236 _diff = _myDigits[_index - 1]; |
5236 _diff = _myDigits[_index - 1]; |
5237 _diff -= _otherDigits[_index - 1]; |
5237 _diff -= _otherDigits[_index - 1]; |
5238 _diff -= _borrow; |
5238 _diff -= _borrow; |
5239 if (_diff >= 0) { |
5239 if (_diff >= 0) { |
5240 _borrow = 0; |
5240 _borrow = 0; |
5241 } else { |
5241 } else { |
5242 _borrow = 1; |
5242 _borrow = 1; |
5243 /* _diff += 0x100; */ |
5243 /* _diff += 0x100; */ |
5244 } |
5244 } |
5245 _myDigits[_index - 1] = _diff; |
5245 _myDigits[_index - 1] = _diff; |
5246 anyBitNonZero |= (_diff & 0xFF); |
5246 anyBitNonZero |= (_diff & 0xFF); |
5247 _index++; |
5247 _index++; |
5248 } |
5248 } |
5249 |
5249 |
5250 while (_index <= _len1) { |
5250 while (_index <= _len1) { |
5251 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5251 /* do not combine the expression below (may lead to unsigned result on some machines */ |
5252 _diff = _myDigits[_index - 1]; |
5252 _diff = _myDigits[_index - 1]; |
5253 _diff -= _borrow; |
5253 _diff -= _borrow; |
5254 if (_diff >= 0) { |
5254 if (_diff >= 0) { |
5255 /* _borrow = 0; */ |
5255 /* _borrow = 0; */ |
5256 _myDigits[_index - 1] = _diff; |
5256 _myDigits[_index - 1] = _diff; |
5257 anyBitNonZero |= (_diff & 0xFF); |
5257 anyBitNonZero |= (_diff & 0xFF); |
5258 _index++; |
5258 _index++; |
5259 while (_index <= _len1) { |
5259 while (_index <= _len1) { |
5260 anyBitNonZero |= _myDigits[_index - 1]; |
5260 anyBitNonZero |= _myDigits[_index - 1]; |
5261 if (anyBitNonZero) { |
5261 if (anyBitNonZero) { |
5262 RETURN (true); |
5262 RETURN (true); |
5263 } |
5263 } |
5264 _index++; |
5264 _index++; |
5265 } |
5265 } |
5266 break; |
5266 break; |
5267 } |
5267 } |
5268 _borrow = 1; |
5268 _borrow = 1; |
5269 /* _diff += 0x100; */ |
5269 /* _diff += 0x100; */ |
5270 |
5270 |
5271 _myDigits[_index - 1] = _diff; |
5271 _myDigits[_index - 1] = _diff; |
5272 anyBitNonZero |= (_diff & 0xFF); |
5272 anyBitNonZero |= (_diff & 0xFF); |
5273 _index++; |
5273 _index++; |
5274 } |
5274 } |
5275 RETURN (anyBitNonZero ? true : false); |
5275 RETURN (anyBitNonZero ? true : false); |
5276 } |
5276 } |
5277 %}. |
5277 %}. |
5278 |
5278 |
5279 index := 1. |
5279 index := 1. |
5280 borrow := 0. |
5280 borrow := 0. |
5281 |
5281 |
5282 [index <= len1] whileTrue:[ |
5282 [index <= len1] whileTrue:[ |
5283 diff := borrow. |
5283 diff := borrow. |
5284 diff := diff + (digitByteArray basicAt:index). |
5284 diff := diff + (digitByteArray basicAt:index). |
5285 index <= len2 ifTrue:[ |
5285 index <= len2 ifTrue:[ |
5286 diff := diff - (otherDigitByteArray basicAt:index). |
5286 diff := diff - (otherDigitByteArray basicAt:index). |
5287 ]. |
5287 ]. |
5288 |
5288 |
5289 "/ workaround for |
5289 "/ workaround for |
5290 "/ gcc code generator bug |
5290 "/ gcc code generator bug |
5291 |
5291 |
5292 (diff >= 0) ifTrue:[ |
5292 (diff >= 0) ifTrue:[ |
5293 borrow := 0 |
5293 borrow := 0 |
5294 ] ifFalse:[ |
5294 ] ifFalse:[ |
5295 borrow := -1. |
5295 borrow := -1. |
5296 diff := diff + 16r100 |
5296 diff := diff + 16r100 |
5297 ]. |
5297 ]. |
5298 diff ~~ 0 ifTrue:[ |
5298 diff ~~ 0 ifTrue:[ |
5299 notZero := true |
5299 notZero := true |
5300 ]. |
5300 ]. |
5301 digitByteArray basicAt:index put:diff. |
5301 digitByteArray basicAt:index put:diff. |
5302 index := index + 1 |
5302 index := index + 1 |
5303 ]. |
5303 ]. |
5304 |
5304 |
5305 ^ notZero |
5305 ^ notZero |
5306 |
5306 |
5307 "Created: / 5.11.1996 / 16:23:47 / cg" |
5307 "Created: / 5.11.1996 / 16:23:47 / cg" |