Revision 6ddbc6e4 targetarm/helper.c
b/targetarm/helper.c  

1922  1922 
} 
1923  1923  
1924  1924 
#endif 
1925  
1926 
/* Note that signed overflow is undefined in C. The following routines are 

1927 
careful to use unsigned types where modulo arithmetic is required. 

1928 
Failure to do so _will_ break on newer gcc. */ 

1929  
1930 
/* Signed saturating arithmetic. */ 

1931  
1932 
/* Perform 16bit signed satruating addition. */ 

1933 
static inline uint16_t add16_sat(uint16_t a, uint16_t b) 

1934 
{ 

1935 
uint16_t res; 

1936  
1937 
res = a + b; 

1938 
if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) { 

1939 
if (a & 0x8000) 

1940 
res = 0x8000; 

1941 
else 

1942 
res = 0x7fff; 

1943 
} 

1944 
return res; 

1945 
} 

1946  
1947 
/* Perform 8bit signed satruating addition. */ 

1948 
static inline uint8_t add8_sat(uint8_t a, uint8_t b) 

1949 
{ 

1950 
uint8_t res; 

1951  
1952 
res = a + b; 

1953 
if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) { 

1954 
if (a & 0x80) 

1955 
res = 0x80; 

1956 
else 

1957 
res = 0x7f; 

1958 
} 

1959 
return res; 

1960 
} 

1961  
1962 
/* Perform 16bit signed satruating subtraction. */ 

1963 
static inline uint16_t sub16_sat(uint16_t a, uint16_t b) 

1964 
{ 

1965 
uint16_t res; 

1966  
1967 
res = a  b; 

1968 
if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) { 

1969 
if (a & 0x8000) 

1970 
res = 0x8000; 

1971 
else 

1972 
res = 0x7fff; 

1973 
} 

1974 
return res; 

1975 
} 

1976  
1977 
/* Perform 8bit signed satruating subtraction. */ 

1978 
static inline uint8_t sub8_sat(uint8_t a, uint8_t b) 

1979 
{ 

1980 
uint8_t res; 

1981  
1982 
res = a  b; 

1983 
if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) { 

1984 
if (a & 0x80) 

1985 
res = 0x80; 

1986 
else 

1987 
res = 0x7f; 

1988 
} 

1989 
return res; 

1990 
} 

1991  
1992 
#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16); 

1993 
#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16); 

1994 
#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8); 

1995 
#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8); 

1996 
#define PFX q 

1997  
1998 
#include "op_addsub.h" 

1999  
2000 
/* Unsigned saturating arithmetic. */ 

2001 
static inline uint16_t add16_usat(uint16_t a, uint8_t b) 

2002 
{ 

2003 
uint16_t res; 

2004 
res = a + b; 

2005 
if (res < a) 

2006 
res = 0xffff; 

2007 
return res; 

2008 
} 

2009  
2010 
static inline uint16_t sub16_usat(uint16_t a, uint8_t b) 

2011 
{ 

2012 
if (a < b) 

2013 
return a  b; 

2014 
else 

2015 
return 0; 

2016 
} 

2017  
2018 
static inline uint8_t add8_usat(uint8_t a, uint8_t b) 

2019 
{ 

2020 
uint8_t res; 

2021 
res = a + b; 

2022 
if (res < a) 

2023 
res = 0xff; 

2024 
return res; 

2025 
} 

2026  
2027 
static inline uint8_t sub8_usat(uint8_t a, uint8_t b) 

2028 
{ 

2029 
if (a < b) 

2030 
return a  b; 

2031 
else 

2032 
return 0; 

2033 
} 

2034  
2035 
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16); 

2036 
#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16); 

2037 
#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8); 

2038 
#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8); 

2039 
#define PFX uq 

2040  
2041 
#include "op_addsub.h" 

2042  
2043 
/* Signed modulo arithmetic. */ 

2044 
#define SARITH16(a, b, n, op) do { \ 

2045 
int32_t sum; \ 

2046 
sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \ 

2047 
RESULT(sum, n, 16); \ 

2048 
if (sum >= 0) \ 

2049 
ge = 3 << (n * 2); \ 

2050 
} while(0) 

2051  
2052 
#define SARITH8(a, b, n, op) do { \ 

2053 
int32_t sum; \ 

2054 
sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \ 

2055 
RESULT(sum, n, 8); \ 

2056 
if (sum >= 0) \ 

2057 
ge = 1 << n; \ 

2058 
} while(0) 

2059  
2060  
2061 
#define ADD16(a, b, n) SARITH16(a, b, n, +) 

2062 
#define SUB16(a, b, n) SARITH16(a, b, n, ) 

2063 
#define ADD8(a, b, n) SARITH8(a, b, n, +) 

2064 
#define SUB8(a, b, n) SARITH8(a, b, n, ) 

2065 
#define PFX s 

2066 
#define ARITH_GE 

2067  
2068 
#include "op_addsub.h" 

2069  
2070 
/* Unsigned modulo arithmetic. */ 

2071 
#define ADD16(a, b, n) do { \ 

2072 
uint32_t sum; \ 

2073 
sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \ 

2074 
RESULT(sum, n, 16); \ 

2075 
if ((sum >> 16) == 0) \ 

2076 
ge = 3 << (n * 2); \ 

2077 
} while(0) 

2078  
2079 
#define ADD8(a, b, n) do { \ 

2080 
uint32_t sum; \ 

2081 
sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \ 

2082 
RESULT(sum, n, 8); \ 

2083 
if ((sum >> 8) == 0) \ 

2084 
ge = 3 << (n * 2); \ 

2085 
} while(0) 

2086  
2087 
#define SUB16(a, b, n) do { \ 

2088 
uint32_t sum; \ 

2089 
sum = (uint32_t)(uint16_t)(a)  (uint32_t)(uint16_t)(b); \ 

2090 
RESULT(sum, n, 16); \ 

2091 
if ((sum >> 16) == 0) \ 

2092 
ge = 3 << (n * 2); \ 

2093 
} while(0) 

2094  
2095 
#define SUB8(a, b, n) do { \ 

2096 
uint32_t sum; \ 

2097 
sum = (uint32_t)(uint8_t)(a)  (uint32_t)(uint8_t)(b); \ 

2098 
RESULT(sum, n, 8); \ 

2099 
if ((sum >> 8) == 0) \ 

2100 
ge = 3 << (n * 2); \ 

2101 
} while(0) 

2102  
2103 
#define PFX u 

2104 
#define ARITH_GE 

2105  
2106 
#include "op_addsub.h" 

2107  
2108 
/* Halved signed arithmetic. */ 

2109 
#define ADD16(a, b, n) \ 

2110 
RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16) 

2111 
#define SUB16(a, b, n) \ 

2112 
RESULT(((int32_t)(int16_t)(a)  (int32_t)(int16_t)(b)) >> 1, n, 16) 

2113 
#define ADD8(a, b, n) \ 

2114 
RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8) 

2115 
#define SUB8(a, b, n) \ 

2116 
RESULT(((int32_t)(int8_t)(a)  (int32_t)(int8_t)(b)) >> 1, n, 8) 

2117 
#define PFX sh 

2118  
2119 
#include "op_addsub.h" 

2120  
2121 
/* Halved unsigned arithmetic. */ 

2122 
#define ADD16(a, b, n) \ 

2123 
RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16) 

2124 
#define SUB16(a, b, n) \ 

2125 
RESULT(((uint32_t)(uint16_t)(a)  (uint32_t)(uint16_t)(b)) >> 1, n, 16) 

2126 
#define ADD8(a, b, n) \ 

2127 
RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8) 

2128 
#define SUB8(a, b, n) \ 

2129 
RESULT(((uint32_t)(uint8_t)(a)  (uint32_t)(uint8_t)(b)) >> 1, n, 8) 

2130 
#define PFX uh 

2131  
2132 
#include "op_addsub.h" 

2133  
2134 
static inline uint8_t do_usad(uint8_t a, uint8_t b) 

2135 
{ 

2136 
if (a > b) 

2137 
return a  b; 

2138 
else 

2139 
return b  a; 

2140 
} 

2141  
2142 
/* Unsigned sum of absolute byte differences. */ 

2143 
uint32_t HELPER(usad8)(uint32_t a, uint32_t b) 

2144 
{ 

2145 
uint32_t sum; 

2146 
sum = do_usad(a, b); 

2147 
sum += do_usad(a >> 8, b >> 8); 

2148 
sum += do_usad(a >> 16, b >>16); 

2149 
sum += do_usad(a >> 24, b >> 24); 

2150 
return sum; 

2151 
} 

2152  
2153 
/* For ARMv6 SEL instruction. */ 

2154 
uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) 

2155 
{ 

2156 
uint32_t mask; 

2157  
2158 
mask = 0; 

2159 
if (flags & 1) 

2160 
mask = 0xff; 

2161 
if (flags & 2) 

2162 
mask = 0xff00; 

2163 
if (flags & 4) 

2164 
mask = 0xff0000; 

2165 
if (flags & 8) 

2166 
mask = 0xff000000; 

2167 
return (a & mask)  (b & ~mask); 

2168 
} 

2169 
Also available in: Unified diff