| ... | ... | @@ -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 | 2340 | comptime { |
| 1763 | 2341 | if (builtin.cpu.arch == .hexagon) { |
| 1764 | 2342 | symbol(&__hexagon_adddf3, "__hexagon_adddf3"); |
| ... | ... | @@ -1785,5 +2363,15 @@ comptime { |
| 1785 | 2363 | symbol(&__hexagon_modsi3, "__hexagon_modsi3"); |
| 1786 | 2364 | symbol(&__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes, "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes"); |
| 1787 | 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 | } |