| ... | @@ -1759,6 +1759,584 @@ fn __hexagon_sqrtdf2() align(32) callconv(.naked) noreturn { | ... | @@ -1759,6 +1759,584 @@ fn __hexagon_sqrtdf2() align(32) callconv(.naked) noreturn { |
| 1759 | ); | 1759 | ); |
| 1760 | } | 1760 | } |
| 1761 | | 1761 | |
| | 1762 | fn __qf_convert_hf_to_b_rne() align(32) callconv(.naked) noreturn { |
| | 1763 | asm volatile ( |
| | 1764 | \\ //V0 and V1 have input |
| | 1765 | \\ //First rnd, replaces V0.h=V0.hf |
| | 1766 | \\ //Convert input vector to half word |
| | 1767 | \\ { |
| | 1768 | \\ R1=#0x3800 //+.5 |
| | 1769 | \\ R2=#0xB800 //-.5 |
| | 1770 | \\ V7.h=V0.hf //Convert and truncate half precision |
| | 1771 | \\ } |
| | 1772 | \\ { |
| | 1773 | \\ V6=#0 |
| | 1774 | \\ R3=#0x00010001 |
| | 1775 | \\ R4=#0x37FF |
| | 1776 | \\ } |
| | 1777 | \\ { |
| | 1778 | \\ V10=vsplat(R3) |
| | 1779 | \\ V12.h=vsplat(R4) |
| | 1780 | \\ V15.hf=V7.h //Convert truncated back to hf |
| | 1781 | \\ } |
| | 1782 | \\ { |
| | 1783 | \\ V23.h=vsplat(R1) //V3 = +.5 |
| | 1784 | \\ V24.h=vsplat(R2) //V4 = -.5 |
| | 1785 | \\ V5.qf16=vsub(V0.hf,V15.hf) //Sub truncated value from original value |
| | 1786 | \\ R0=#0x7FFF //Mask off sign bit of IEEE-754 |
| | 1787 | \\ } |
| | 1788 | \\ { |
| | 1789 | \\ Q0=vcmp.gt(V0.hf,V6.hf) // hf value is pos (hf > 0) |
| | 1790 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 1791 | \\ V22.h=vsplat(R0) //Splat R0 to Mask off sign bit |
| | 1792 | \\ } |
| | 1793 | \\ { |
| | 1794 | \\ V15=vmux(Q0,V23,V24) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 1795 | \\ V2=vand(V22,V5) //V2=abs(frac) |
| | 1796 | \\ V13=vand(V0,V22) //V13 = abs(input) |
| | 1797 | \\ } |
| | 1798 | \\ { |
| | 1799 | \\ Q1=vcmp.eq(V2.h,V23.h) // frac == .5 (0x3800) |
| | 1800 | \\ V15=vsplat(R3) //V1=1 |
| | 1801 | \\ V4.qf16=vadd(V0.hf,V15.hf) // Add +.5 or -.5 to V0 |
| | 1802 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 1803 | \\ } |
| | 1804 | \\ { |
| | 1805 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 1806 | \\ V3.h = vadd(V15.h,V15.h) //V3 is 2 |
| | 1807 | \\ } |
| | 1808 | \\ { |
| | 1809 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 1810 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 1811 | \\ } |
| | 1812 | \\ { |
| | 1813 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 1814 | \\ if (Q0) V15.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 1815 | \\ V4=vmux(Q3,V6,V4) |
| | 1816 | \\ } |
| | 1817 | \\ { |
| | 1818 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 1819 | \\ V15=vmux(Q1,V15,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 1820 | \\ } |
| | 1821 | \\ { |
| | 1822 | \\ //Second rnd, replaces V1.h=V1.hf //Convert input vector to half word |
| | 1823 | \\ V7.h=V1.hf //Convert and truncate half precision |
| | 1824 | \\ } |
| | 1825 | \\ { |
| | 1826 | \\ V16.h = vadd(V4.h,V15.h) //Add +1/-1 or 0. V4 has the result |
| | 1827 | \\ V1.hf=V7.h //Convert truncated back to hf |
| | 1828 | \\ } |
| | 1829 | \\ { |
| | 1830 | \\ V5.qf16=vsub(V0.hf,V1.hf) //Sub truncated value from original value |
| | 1831 | \\ R0=#0x7FFF //Mask off sign bit of IEEE-754 |
| | 1832 | \\ } |
| | 1833 | \\ { |
| | 1834 | \\ Q0=vcmp.gt(V0.hf,V6.hf) // hf value is pos (hf > 0) |
| | 1835 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 1836 | \\ } |
| | 1837 | \\ { |
| | 1838 | \\ V1=vmux(Q0,V23,V24) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 1839 | \\ V2=vand(V22,V5) //V2=abs(frac) |
| | 1840 | \\ V13=vand(V0,V22) //V13 = abs(input) |
| | 1841 | \\ } |
| | 1842 | \\ { |
| | 1843 | \\ Q1=vcmp.eq(V2.h,V23.h) // frac == .5 (0x3800) |
| | 1844 | \\ V1=vsplat(R3) //V1=1 |
| | 1845 | \\ V4.qf16=vadd(V0.hf,V1.hf) // Add +.5 or -.5 to V0 |
| | 1846 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 1847 | \\ } |
| | 1848 | \\ { |
| | 1849 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 1850 | \\ V3.h = vadd(V1.h,V1.h) //V3 is 2 |
| | 1851 | \\ } |
| | 1852 | \\ { |
| | 1853 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 1854 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 1855 | \\ } |
| | 1856 | \\ { |
| | 1857 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 1858 | \\ if (Q0) V1.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 1859 | \\ V4=vmux(Q3,V6,V4) |
| | 1860 | \\ } |
| | 1861 | \\ { |
| | 1862 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 1863 | \\ V1=vmux(Q1,V1,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 1864 | \\ } |
| | 1865 | \\ { |
| | 1866 | \\ V17.h = vadd(V4.h,V1.h) //Add +1/-1 or 0. V4 has the result |
| | 1867 | \\ } |
| | 1868 | \\ { |
| | 1869 | \\ V0.b = vpack(V17.h,V16.h):sat |
| | 1870 | \\ } |
| | 1871 | \\ { |
| | 1872 | \\ V0.h=vshuff(V0.h) |
| | 1873 | \\ jumpr R31 |
| | 1874 | \\ } |
| | 1875 | ); |
| | 1876 | } |
| | 1877 | |
| | 1878 | fn __qf_convert_hf_to_h_rne() align(32) callconv(.naked) noreturn { |
| | 1879 | asm volatile ( |
| | 1880 | \\ { |
| | 1881 | \\ R1=#0x3800 //+.5 |
| | 1882 | \\ R2=#0xB800 //-.5 |
| | 1883 | \\ V7.h=V0.hf //Convert and truncate half precision |
| | 1884 | \\ } |
| | 1885 | \\ { |
| | 1886 | \\ V6=#0 |
| | 1887 | \\ R3=#0x00010001 |
| | 1888 | \\ R4=#0x37FF |
| | 1889 | \\ } |
| | 1890 | \\ { |
| | 1891 | \\ V10=vsplat(R3) |
| | 1892 | \\ V12.h=vsplat(R4) |
| | 1893 | \\ V1.hf=V7.h //Convert truncated back to hf |
| | 1894 | \\ } |
| | 1895 | \\ { |
| | 1896 | \\ V3.h=vsplat(R1) //V3 = +.5 |
| | 1897 | \\ V4.h=vsplat(R2) //V4 = -.5 |
| | 1898 | \\ V5.qf16=vsub(V0.hf,V1.hf) //Sub truncated value from original value |
| | 1899 | \\ R0=#0x7FFF //Mask off sign bit of IEEE-754 |
| | 1900 | \\ } |
| | 1901 | \\ { |
| | 1902 | \\ Q0=vcmp.gt(V0.hf,V6.hf) // hf value is pos (hf > 0) |
| | 1903 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 1904 | \\ V2.h=vsplat(R0) //Splat R0 to Mask off sign bit |
| | 1905 | \\ } |
| | 1906 | \\ { |
| | 1907 | \\ V1=vmux(Q0,V3,V4) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 1908 | \\ V2=vand(V2,V5) //V2=abs(frac) |
| | 1909 | \\ V13=vand(V0,V2) //V13 = abs(input) |
| | 1910 | \\ } |
| | 1911 | \\ { |
| | 1912 | \\ Q1=vcmp.eq(V2.h,V3.h) // frac == .5 (0x3800) |
| | 1913 | \\ V1=vsplat(R3) //V1=1 |
| | 1914 | \\ V4.qf16=vadd(V0.hf,V1.hf) // Add +.5 or -.5 to V0 |
| | 1915 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 1916 | \\ } |
| | 1917 | \\ { |
| | 1918 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 1919 | \\ V3.h = vadd(V1.h,V1.h) //V3 is 2 |
| | 1920 | \\ } |
| | 1921 | \\ { |
| | 1922 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 1923 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 1924 | \\ } |
| | 1925 | \\ { |
| | 1926 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 1927 | \\ if (Q0) V1.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 1928 | \\ V4=vmux(Q3,V6,V4) |
| | 1929 | \\ } |
| | 1930 | \\ { |
| | 1931 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 1932 | \\ V1=vmux(Q1,V1,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 1933 | \\ } |
| | 1934 | \\ { |
| | 1935 | \\ V0.h = vadd(V4.h,V1.h) //Add +1/-1 or 0. V4 has the result |
| | 1936 | \\ jumpr LR |
| | 1937 | \\ } |
| | 1938 | ); |
| | 1939 | } |
| | 1940 | |
| | 1941 | fn __qf_convert_hf_to_ub_rne() align(32) callconv(.naked) noreturn { |
| | 1942 | asm volatile ( |
| | 1943 | \\ //V0 and V1 have input |
| | 1944 | \\ //First rnd, replaces V0.h=V0.hf |
| | 1945 | \\ //Convert input vector to half word |
| | 1946 | \\ { |
| | 1947 | \\ R1=#0x3800 //+.5 |
| | 1948 | \\ R2=#0xB800 //-.5 |
| | 1949 | \\ V7.h=V0.hf //Convert and truncate half precision |
| | 1950 | \\ } |
| | 1951 | \\ { |
| | 1952 | \\ V6=#0 |
| | 1953 | \\ R3=#0x00010001 |
| | 1954 | \\ R4=#0x37FF |
| | 1955 | \\ } |
| | 1956 | \\ { |
| | 1957 | \\ V10=vsplat(R3) |
| | 1958 | \\ V12.h=vsplat(R4) |
| | 1959 | \\ V15.hf=V7.h //Convert truncated back to hf |
| | 1960 | \\ } |
| | 1961 | \\ { |
| | 1962 | \\ V23.h=vsplat(R1) //V3 = +.5 |
| | 1963 | \\ V24.h=vsplat(R2) //V4 = -.5 |
| | 1964 | \\ V5.qf16=vsub(V0.hf,V15.hf) //Sub truncated value from original value |
| | 1965 | \\ R0=#0x7FFF //Mask off sign bit of IEEE-754 |
| | 1966 | \\ } |
| | 1967 | \\ { |
| | 1968 | \\ Q0=vcmp.gt(V0.hf,V6.hf) // hf value is pos (hf > 0) |
| | 1969 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 1970 | \\ V22.h=vsplat(R0) //Splat R0 to Mask off sign bit |
| | 1971 | \\ } |
| | 1972 | \\ { |
| | 1973 | \\ V15=vmux(Q0,V23,V24) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 1974 | \\ V2=vand(V22,V5) //V2=abs(frac) |
| | 1975 | \\ V13=vand(V0,V22) //V13 = abs(input) |
| | 1976 | \\ } |
| | 1977 | \\ { |
| | 1978 | \\ Q1=vcmp.eq(V2.h,V23.h) // frac == .5 (0x3800) |
| | 1979 | \\ V15=vsplat(R3) //V1=1 |
| | 1980 | \\ V4.qf16=vadd(V0.hf,V15.hf) // Add +.5 or -.5 to V0 |
| | 1981 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 1982 | \\ } |
| | 1983 | \\ { |
| | 1984 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 1985 | \\ V3.h = vadd(V15.h,V15.h) //V3 is 2 |
| | 1986 | \\ } |
| | 1987 | \\ { |
| | 1988 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 1989 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 1990 | \\ } |
| | 1991 | \\ { |
| | 1992 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 1993 | \\ if (Q0) V15.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 1994 | \\ V4=vmux(Q3,V6,V4) |
| | 1995 | \\ } |
| | 1996 | \\ { |
| | 1997 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 1998 | \\ V15=vmux(Q1,V15,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 1999 | \\ } |
| | 2000 | \\ { |
| | 2001 | \\ //Second rnd, replaces V1.h=V1.hf //Convert input vector to half word |
| | 2002 | \\ V7.h=V1.hf //Convert and truncate half precision |
| | 2003 | \\ } |
| | 2004 | \\ { |
| | 2005 | \\ V16.h = vadd(V4.h,V15.h) //Add +1/-1 or 0. V4 has the result |
| | 2006 | \\ V1.hf=V7.h //Convert truncated back to hf |
| | 2007 | \\ } |
| | 2008 | \\ { |
| | 2009 | \\ V5.qf16=vsub(V0.hf,V1.hf) //Sub truncated value from original value |
| | 2010 | \\ R0=#0x7FFF //Mask off sign bit of IEEE-754 |
| | 2011 | \\ } |
| | 2012 | \\ { |
| | 2013 | \\ Q0=vcmp.gt(V0.hf,V6.hf) // hf value is pos (hf > 0) |
| | 2014 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 2015 | \\ } |
| | 2016 | \\ { |
| | 2017 | \\ V1=vmux(Q0,V23,V24) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 2018 | \\ V2=vand(V22,V5) //V2=abs(frac) |
| | 2019 | \\ V13=vand(V0,V22) //V13 = abs(input) |
| | 2020 | \\ } |
| | 2021 | \\ { |
| | 2022 | \\ Q1=vcmp.eq(V2.h,V23.h) // frac == .5 (0x3800) |
| | 2023 | \\ V1=vsplat(R3) //V1=1 |
| | 2024 | \\ V4.qf16=vadd(V0.hf,V1.hf) // Add +.5 or -.5 to V0 |
| | 2025 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 2026 | \\ } |
| | 2027 | \\ { |
| | 2028 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 2029 | \\ V3.h = vadd(V1.h,V1.h) //V3 is 2 |
| | 2030 | \\ } |
| | 2031 | \\ { |
| | 2032 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 2033 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 2034 | \\ } |
| | 2035 | \\ { |
| | 2036 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 2037 | \\ if (Q0) V1.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 2038 | \\ V4=vmux(Q3,V6,V4) |
| | 2039 | \\ } |
| | 2040 | \\ { |
| | 2041 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 2042 | \\ V1=vmux(Q1,V1,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 2043 | \\ } |
| | 2044 | \\ { |
| | 2045 | \\ V17.h = vadd(V4.h,V1.h) //Add +1/-1 or 0. V4 has the result |
| | 2046 | \\ } |
| | 2047 | \\ { |
| | 2048 | \\ V0.ub = vpack(V17.h,V16.h):sat |
| | 2049 | \\ } |
| | 2050 | \\ { |
| | 2051 | \\ V0.h=vshuff(V0.h) |
| | 2052 | \\ jumpr LR |
| | 2053 | \\ } |
| | 2054 | ); |
| | 2055 | } |
| | 2056 | |
| | 2057 | fn __qf_convert_hf_to_uh_rne() align(32) callconv(.naked) noreturn { |
| | 2058 | asm volatile ( |
| | 2059 | \\ { |
| | 2060 | \\ R20=#0x38003800 //.5 |
| | 2061 | \\ R21=#0x77FF //Number right before 2^15 |
| | 2062 | \\ R22=#1 |
| | 2063 | \\ R23=#0x7BFF //num right under Inf |
| | 2064 | \\ } |
| | 2065 | \\ { |
| | 2066 | \\ V21=#0 |
| | 2067 | \\ V23.qf16=vmpy(V0.hf,R20.hf) //Multiply .5 |
| | 2068 | \\ } |
| | 2069 | \\ //First rnd, replaces V22.h=V0.hf |
| | 2070 | \\ //Convert input vector to half word |
| | 2071 | \\ { |
| | 2072 | \\ R1=#0x3800 //+.5 |
| | 2073 | \\ R2=#0xB800 //-.5 |
| | 2074 | \\ V7.h=V0.hf //Convert and truncate half precision |
| | 2075 | \\ } |
| | 2076 | \\ { |
| | 2077 | \\ V6=#0 |
| | 2078 | \\ R3=#0x00010001 |
| | 2079 | \\ R4=#0x37FF |
| | 2080 | \\ } |
| | 2081 | \\ { |
| | 2082 | \\ V10=vsplat(R3) |
| | 2083 | \\ V12.h=vsplat(R4) |
| | 2084 | \\ V1.hf=V7.h //Convert truncated back to hf |
| | 2085 | \\ } |
| | 2086 | \\ { |
| | 2087 | \\ V26.h=vsplat(R1) //V3 = +.5 |
| | 2088 | \\ V27.h=vsplat(R2) //V4 = -.5 |
| | 2089 | \\ V5.qf16=vsub(V0.hf,V1.hf) //Sub truncated value from original value |
| | 2090 | \\ R0=#0x7FFF //Mask off sign bit of IEEE-754 |
| | 2091 | \\ } |
| | 2092 | \\ { |
| | 2093 | \\ Q0=vcmp.gt(V0.hf,V6.hf) // hf value is pos (hf > 0) |
| | 2094 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 2095 | \\ V25.h=vsplat(R0) //Splat R0 to Mask off sign bit |
| | 2096 | \\ } |
| | 2097 | \\ { |
| | 2098 | \\ V1=vmux(Q0,V26,V27) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 2099 | \\ V2=vand(V25,V5) //V2=abs(frac) |
| | 2100 | \\ V13=vand(V0,V25) //V13 = abs(input) |
| | 2101 | \\ } |
| | 2102 | \\ { |
| | 2103 | \\ Q1=vcmp.eq(V2.h,V26.h) // frac == .5 (0x3800) |
| | 2104 | \\ V1=vsplat(R3) //V1=1 |
| | 2105 | \\ V4.qf16=vadd(V0.hf,V1.hf) // Add +.5 or -.5 to V0 |
| | 2106 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 2107 | \\ } |
| | 2108 | \\ { |
| | 2109 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 2110 | \\ V3.h = vadd(V1.h,V1.h) //V3 is 2 |
| | 2111 | \\ } |
| | 2112 | \\ { |
| | 2113 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 2114 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 2115 | \\ } |
| | 2116 | \\ { |
| | 2117 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 2118 | \\ if (Q0) V1.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 2119 | \\ V4=vmux(Q3,V6,V4) |
| | 2120 | \\ } |
| | 2121 | \\ { |
| | 2122 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 2123 | \\ V1=vmux(Q1,V1,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 2124 | \\ } |
| | 2125 | \\ { |
| | 2126 | \\ V22.h = vadd(V4.h,V1.h) //Add +1/-1 or 0. V4 has the result |
| | 2127 | \\ } |
| | 2128 | \\ { |
| | 2129 | \\ V23.hf=V23.qf16 //Convert multiply back to hf |
| | 2130 | \\ V21.h=vmax(V21.h,V22.h) //Filter out anything lower than 0 |
| | 2131 | \\ } |
| | 2132 | \\ { |
| | 2133 | \\ V22.h=vsplat(R21) //Splat overflow value for compare |
| | 2134 | \\ //Second rnd, replaces V23.h=V23.hf |
| | 2135 | \\ //Convert input vector to half word |
| | 2136 | \\ V7.h=V23.hf //Convert and truncate half precision |
| | 2137 | \\ } |
| | 2138 | \\ { |
| | 2139 | \\ V1.hf=V7.h //Convert truncated back to hf |
| | 2140 | \\ } |
| | 2141 | \\ { |
| | 2142 | \\ V5.qf16=vsub(V23.hf,V1.hf) //Sub truncated value from original value |
| | 2143 | \\ } |
| | 2144 | \\ { |
| | 2145 | \\ Q0=vcmp.gt(V23.hf,V6.hf) // hf value is pos (hf > 0) |
| | 2146 | \\ V5.hf=V5.qf16 //V5 is the fractional of original value |
| | 2147 | \\ } |
| | 2148 | \\ { |
| | 2149 | \\ V1=vmux(Q0,V26,V27) //If input is pos value, use +.5. If neg value, use -.5 (Q in prev packet) |
| | 2150 | \\ V2=vand(V25,V5) //V2=abs(frac) |
| | 2151 | \\ V13=vand(V23,V25) //V13 = abs(input) |
| | 2152 | \\ } |
| | 2153 | \\ { |
| | 2154 | \\ Q1=vcmp.eq(V2.h,V26.h) // frac == .5 (0x3800) |
| | 2155 | \\ V1=vsplat(R3) //V1=1 |
| | 2156 | \\ V4.qf16=vadd(V23.hf,V1.hf) // Add +.5 or -.5 to V0 |
| | 2157 | \\ Q3=vcmp.eq(V13.h,V12.h) //Q3 = if(input == abs(.4998)) |
| | 2158 | \\ } |
| | 2159 | \\ { |
| | 2160 | \\ V11=vand(V7,V10) //Mask off all the lower bits |
| | 2161 | \\ V3.h = vadd(V1.h,V1.h) //V3 is 2 |
| | 2162 | \\ } |
| | 2163 | \\ { |
| | 2164 | \\ Q2=vcmp.eq(V11.h,V10.h) //Is input value odd if halfword equals 0x1 |
| | 2165 | \\ V4.hf=V4.qf16 //hf value after add/sub .5 |
| | 2166 | \\ } |
| | 2167 | \\ { |
| | 2168 | \\ Q1=and(Q1,!Q2) //Is frac .5 and input is even |
| | 2169 | \\ if (Q0) V1.h-=V3.h //If input is pos, sub 2 so V1 is -1 |
| | 2170 | \\ V4=vmux(Q3,V6,V4) |
| | 2171 | \\ } |
| | 2172 | \\ { |
| | 2173 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 2174 | \\ V1=vmux(Q1,V1,V6) //If frac == .5 and input is even, use +1/-1. Else 0 |
| | 2175 | \\ } |
| | 2176 | \\ { |
| | 2177 | \\ V23.h = vadd(V4.h,V1.h) //Add +1/-1 or 0. V4 has the result |
| | 2178 | \\ } |
| | 2179 | \\ { |
| | 2180 | \\ Q1=vcmp.gt(V22.hf,V0.hf) //Q1 is if value doesn't overflow on hf=h convert (V0 is input, V2 is right before 2^15) |
| | 2181 | \\ V23.h=vasl(V23.h,R22) //Left shift converted value |
| | 2182 | \\ V24.h=vsplat(R23) //Splat inf |
| | 2183 | \\ } |
| | 2184 | \\ { |
| | 2185 | \\ Q1|=vcmp.gt(V0.uh,V24.uh) //Q1 is value is < inf/nan |
| | 2186 | \\ } |
| | 2187 | \\ { |
| | 2188 | \\ V0=vmux(Q1,V21,V23) //If value is not overflow or input is Inf, set to converted input. Else, set to overflow |
| | 2189 | \\ jumpr LR |
| | 2190 | \\ } |
| | 2191 | ); |
| | 2192 | } |
| | 2193 | |
| | 2194 | fn __qf_fast_convert_hf_to_b_rne() align(32) callconv(.naked) noreturn { |
| | 2195 | asm volatile ( |
| | 2196 | \\ //V0.hf and V1.hf has value to be converted |
| | 2197 | \\ { |
| | 2198 | \\ R1=#0x3800 //+.5 |
| | 2199 | \\ R2=#0xB800 //-.5 |
| | 2200 | \\ V2=#0 |
| | 2201 | \\ } |
| | 2202 | \\ { |
| | 2203 | \\ Q0=vcmp.gt(V0.hf,V2.hf) // hf value is pos (hf > 0) |
| | 2204 | \\ Q1=vcmp.gt(V1.hf,V2.hf) // hf value is pos (hf > 0) |
| | 2205 | \\ V2.h=vsplat(R1) //V1 = +.5 |
| | 2206 | \\ V3.h=vsplat(R2) //V2 = -.5 |
| | 2207 | \\ } |
| | 2208 | \\ { |
| | 2209 | \\ V2=vmux(Q0,V2,V3) //If pos value, use +.5. If neg value, use -.5 |
| | 2210 | \\ V3=vmux(Q1,V2,V3) //If pos value, use +.5. If neg value, use -.5 |
| | 2211 | \\ } |
| | 2212 | \\ { |
| | 2213 | \\ V4.qf16=vadd(V0.hf,V2.hf) // Add +.5 or -.5 to V0 |
| | 2214 | \\ } |
| | 2215 | \\ { |
| | 2216 | \\ V5.qf16=vadd(V1.hf,V3.hf) // Add +.5 or -.5 to V1 |
| | 2217 | \\ } |
| | 2218 | \\ { |
| | 2219 | \\ V4.hf=V4.qf16 |
| | 2220 | \\ } |
| | 2221 | \\ { |
| | 2222 | \\ V5.hf=V5.qf16 |
| | 2223 | \\ } |
| | 2224 | \\ { |
| | 2225 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 2226 | \\ } |
| | 2227 | \\ { |
| | 2228 | \\ V5.h=V5.hf //Truncate, V5 has converted value |
| | 2229 | \\ } |
| | 2230 | \\ { |
| | 2231 | \\ V0.ub = vpack(V4.h,V5.h):sat |
| | 2232 | \\ } |
| | 2233 | \\ { |
| | 2234 | \\ V0.h = vshuff(V0.h) |
| | 2235 | \\ jumpr LR |
| | 2236 | \\ } |
| | 2237 | ); |
| | 2238 | } |
| | 2239 | |
| | 2240 | fn __qf_fast_convert_hf_to_h_rne() align(32) callconv(.naked) noreturn { |
| | 2241 | asm volatile ( |
| | 2242 | \\ //V0.hf has value to be converted |
| | 2243 | \\ { |
| | 2244 | \\ R1=#0x3800 //+.5 |
| | 2245 | \\ R2=#0xB800 //-.5 |
| | 2246 | \\ V1=#0 |
| | 2247 | \\ } |
| | 2248 | \\ { |
| | 2249 | \\ Q0=vcmp.gt(V0.hf,V1.hf) // hf value is pos (hf > 0) |
| | 2250 | \\ V1.h=vsplat(R1) //V1 = +.5 |
| | 2251 | \\ V2.h=vsplat(R2) //V2 = -.5 |
| | 2252 | \\ } |
| | 2253 | \\ { |
| | 2254 | \\ V1=vmux(Q0,V1,V2) //If pos value, use +.5. If neg value, use -.5 |
| | 2255 | \\ } |
| | 2256 | \\ { |
| | 2257 | \\ V4.qf16=vadd(V0.hf,V1.hf) // Add +.5 or -.5 to V0 |
| | 2258 | \\ } |
| | 2259 | \\ { |
| | 2260 | \\ V4.hf=V4.qf16 |
| | 2261 | \\ } |
| | 2262 | \\ { |
| | 2263 | \\ V0.h=V4.hf //Truncate, V4 has converted value |
| | 2264 | \\ jumpr LR |
| | 2265 | \\ } |
| | 2266 | ); |
| | 2267 | } |
| | 2268 | |
| | 2269 | fn __qf_fast_convert_hf_to_ub_rne() align(32) callconv(.naked) noreturn { |
| | 2270 | asm volatile ( |
| | 2271 | \\ //V0.hf and V1.hf have value to be converted |
| | 2272 | \\ { |
| | 2273 | \\ R1=#0x3800 //+.5 |
| | 2274 | \\ V3=#0 |
| | 2275 | \\ } |
| | 2276 | \\ { |
| | 2277 | \\ Q0=vcmp.gt(V0.hf,V3.hf) // hf value is pos (hf > 0) |
| | 2278 | \\ Q1=vcmp.gt(V1.hf,V3.hf) // hf value is pos (hf > 0) |
| | 2279 | \\ V2.h=vsplat(R1) //V1 = +.5 |
| | 2280 | \\ } |
| | 2281 | \\ { |
| | 2282 | \\ V4.qf16=vadd(V0.hf,V2.hf) // Add +.5 |
| | 2283 | \\ } |
| | 2284 | \\ { |
| | 2285 | \\ V5.qf16=vadd(V1.hf,V2.hf) // Add +.5 |
| | 2286 | \\ } |
| | 2287 | \\ { |
| | 2288 | \\ V4.hf=V4.qf16 |
| | 2289 | \\ } |
| | 2290 | \\ { |
| | 2291 | \\ V5.hf=V5.qf16 |
| | 2292 | \\ } |
| | 2293 | \\ { |
| | 2294 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 2295 | \\ } |
| | 2296 | \\ { |
| | 2297 | \\ V5.h=V5.hf //Truncate, V5 has converted value |
| | 2298 | \\ } |
| | 2299 | \\ { |
| | 2300 | \\ V4=vmux(Q0,V4,V3) //If original pos value, use converted. Else 0 |
| | 2301 | \\ V5=vmux(Q0,V5,V3) //If original pos value, use converted. Else 0 |
| | 2302 | \\ } |
| | 2303 | \\ { |
| | 2304 | \\ V0.ub = vpack(V4.h,V5.h):sat |
| | 2305 | \\ } |
| | 2306 | \\ { |
| | 2307 | \\ V0.h = vshuff(V0.h) |
| | 2308 | \\ jumpr LR |
| | 2309 | \\ } |
| | 2310 | ); |
| | 2311 | } |
| | 2312 | |
| | 2313 | fn __qf_fast_convert_hf_to_uh_rne() align(32) callconv(.naked) noreturn { |
| | 2314 | asm volatile ( |
| | 2315 | \\ //V0.hf has value to be converted |
| | 2316 | \\ { |
| | 2317 | \\ R1=#0x3800 //+.5 |
| | 2318 | \\ V3=#0 |
| | 2319 | \\ } |
| | 2320 | \\ { |
| | 2321 | \\ Q0=vcmp.gt(V0.hf,V3.hf) // hf value is pos (hf > 0) |
| | 2322 | \\ V1.h=vsplat(R1) //V1 = +.5 |
| | 2323 | \\ } |
| | 2324 | \\ { |
| | 2325 | \\ V4.qf16=vadd(V0.hf,V1.hf) // Add +.5 |
| | 2326 | \\ } |
| | 2327 | \\ { |
| | 2328 | \\ V4.hf=V4.qf16 |
| | 2329 | \\ } |
| | 2330 | \\ { |
| | 2331 | \\ V4.h=V4.hf //Truncate, V4 has converted value |
| | 2332 | \\ } |
| | 2333 | \\ { |
| | 2334 | \\ V0=vmux(Q0,V4,V3) //If original pos value, use converted. Else 0 |
| | 2335 | \\ jumpr LR |
| | 2336 | \\ } |
| | 2337 | ); |
| | 2338 | } |
| | 2339 | |
| 1762 | comptime { | 2340 | comptime { |
| 1763 | if (builtin.cpu.arch == .hexagon) { | 2341 | if (builtin.cpu.arch == .hexagon) { |
| 1764 | symbol(&__hexagon_adddf3, "__hexagon_adddf3"); | 2342 | symbol(&__hexagon_adddf3, "__hexagon_adddf3"); |
| ... | @@ -1785,5 +2363,15 @@ comptime { | ... | @@ -1785,5 +2363,15 @@ comptime { |
| 1785 | symbol(&__hexagon_modsi3, "__hexagon_modsi3"); | 2363 | symbol(&__hexagon_modsi3, "__hexagon_modsi3"); |
| 1786 | symbol(&__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes, "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes"); | 2364 | symbol(&__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes, "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes"); |
| 1787 | symbol(&__hexagon_udivsi3, "__hexagon_udivsi3"); | 2365 | symbol(&__hexagon_udivsi3, "__hexagon_udivsi3"); |
| | 2366 | if (builtin.cpu.has(.hexagon, .hvxv79)) { |
| | 2367 | symbol(&__qf_convert_hf_to_b_rne, "__qf_convert_hf_to_b_rne"); |
| | 2368 | symbol(&__qf_fast_convert_hf_to_b_rne, "__qf_fast_convert_hf_to_b_rne"); |
| | 2369 | symbol(&__qf_convert_hf_to_h_rne, "__qf_convert_hf_to_h_rne"); |
| | 2370 | symbol(&__qf_fast_convert_hf_to_h_rne, "__qf_fast_convert_hf_to_h_rne"); |
| | 2371 | symbol(&__qf_convert_hf_to_ub_rne, "__qf_convert_hf_to_ub_rne"); |
| | 2372 | symbol(&__qf_fast_convert_hf_to_ub_rne, "__qf_fast_convert_hf_to_ub_rne"); |
| | 2373 | symbol(&__qf_convert_hf_to_uh_rne, "__qf_convert_hf_to_uh_rne"); |
| | 2374 | symbol(&__qf_fast_convert_hf_to_uh_rne, "__qf_fast_convert_hf_to_uh_rne"); |
| | 2375 | } |
| 1788 | } | 2376 | } |
| 1789 | } | 2377 | } |