]>
Commit | Line | Data |
---|---|---|
5fd1486c PJ |
1 | /* sat_arithmetic.c -- Builtins for HSAIL saturating arithmetic instructions. |
2 | ||
8d9254fc | 3 | Copyright (C) 2015-2020 Free Software Foundation, Inc. |
5fd1486c PJ |
4 | Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com> |
5 | for General Processor Tech. | |
6 | ||
7 | Permission is hereby granted, free of charge, to any person obtaining a | |
8 | copy of this software and associated documentation files | |
9 | (the "Software"), to deal in the Software without restriction, including | |
10 | without limitation the rights to use, copy, modify, merge, publish, | |
11 | distribute, sublicense, and/or sell copies of the Software, and to | |
12 | permit persons to whom the Software is furnished to do so, subject to | |
13 | the following conditions: | |
14 | ||
15 | The above copyright notice and this permission notice shall be included | |
16 | in all copies or substantial portions of the Software. | |
17 | ||
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
19 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
22 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
23 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
24 | USE OR OTHER DEALINGS IN THE SOFTWARE. | |
25 | */ | |
26 | ||
27 | #include <stdint.h> | |
28 | ||
29 | uint8_t | |
30 | __hsail_sat_add_u8 (uint8_t a, uint8_t b) | |
31 | { | |
32 | uint16_t c = (uint16_t) a + (uint16_t) b; | |
33 | if (c > UINT8_MAX) | |
34 | return UINT8_MAX; | |
35 | else | |
36 | return c; | |
37 | } | |
38 | ||
39 | uint16_t | |
40 | __hsail_sat_add_u16 (uint16_t a, uint16_t b) | |
41 | { | |
42 | uint32_t c = (uint32_t) a + (uint32_t) b; | |
43 | if (c > UINT16_MAX) | |
44 | return UINT16_MAX; | |
45 | else | |
46 | return c; | |
47 | } | |
48 | ||
49 | uint32_t | |
50 | __hsail_sat_add_u32 (uint32_t a, uint32_t b) | |
51 | { | |
315405b6 JJ |
52 | uint32_t c; |
53 | if (__builtin_add_overflow (a, b, &c)) | |
5fd1486c | 54 | return UINT32_MAX; |
315405b6 | 55 | return c; |
5fd1486c PJ |
56 | } |
57 | ||
58 | uint64_t | |
59 | __hsail_sat_add_u64 (uint64_t a, uint64_t b) | |
60 | { | |
315405b6 JJ |
61 | uint64_t c; |
62 | if (__builtin_add_overflow (a, b, &c)) | |
5fd1486c | 63 | return UINT64_MAX; |
315405b6 | 64 | return c; |
5fd1486c PJ |
65 | } |
66 | ||
67 | int8_t | |
68 | __hsail_sat_add_s8 (int8_t a, int8_t b) | |
69 | { | |
70 | int16_t c = (int16_t) a + (int16_t) b; | |
71 | if (c > INT8_MAX) | |
72 | return INT8_MAX; | |
73 | else if (c < INT8_MIN) | |
74 | return INT8_MIN; | |
75 | else | |
76 | return c; | |
77 | } | |
78 | ||
79 | int16_t | |
80 | __hsail_sat_add_s16 (int16_t a, int16_t b) | |
81 | { | |
82 | int32_t c = (int32_t) a + (int32_t) b; | |
83 | if (c > INT16_MAX) | |
84 | return INT16_MAX; | |
85 | else if (c < INT16_MIN) | |
86 | return INT16_MIN; | |
87 | else | |
88 | return c; | |
89 | } | |
90 | ||
91 | int32_t | |
92 | __hsail_sat_add_s32 (int32_t a, int32_t b) | |
93 | { | |
315405b6 JJ |
94 | int32_t c; |
95 | if (__builtin_add_overflow (a, b, &c)) | |
96 | return b < 0 ? INT32_MIN : INT32_MAX; | |
97 | return c; | |
5fd1486c PJ |
98 | } |
99 | ||
100 | int64_t | |
101 | __hsail_sat_add_s64 (int64_t a, int64_t b) | |
102 | { | |
315405b6 JJ |
103 | int64_t c; |
104 | if (__builtin_add_overflow (a, b, &c)) | |
105 | return b < 0 ? INT64_MIN : INT64_MAX; | |
106 | return c; | |
5fd1486c PJ |
107 | } |
108 | ||
109 | uint8_t | |
110 | __hsail_sat_sub_u8 (uint8_t a, uint8_t b) | |
111 | { | |
112 | int16_t c = (uint16_t) a - (uint16_t) b; | |
113 | if (c < 0) | |
114 | return 0; | |
5fd1486c PJ |
115 | else |
116 | return c; | |
117 | } | |
118 | ||
119 | uint16_t | |
120 | __hsail_sat_sub_u16 (uint16_t a, uint16_t b) | |
121 | { | |
122 | int32_t c = (uint32_t) a - (uint32_t) b; | |
123 | if (c < 0) | |
124 | return 0; | |
5fd1486c PJ |
125 | else |
126 | return c; | |
127 | } | |
128 | ||
129 | uint32_t | |
130 | __hsail_sat_sub_u32 (uint32_t a, uint32_t b) | |
131 | { | |
315405b6 JJ |
132 | uint32_t c; |
133 | if (__builtin_sub_overflow (a, b, &c)) | |
5fd1486c | 134 | return 0; |
315405b6 | 135 | return c; |
5fd1486c PJ |
136 | } |
137 | ||
138 | uint64_t | |
139 | __hsail_sat_sub_u64 (uint64_t a, uint64_t b) | |
140 | { | |
315405b6 JJ |
141 | uint64_t c; |
142 | if (__builtin_sub_overflow (a, b, &c)) | |
5fd1486c | 143 | return 0; |
315405b6 | 144 | return c; |
5fd1486c PJ |
145 | } |
146 | ||
147 | int8_t | |
148 | __hsail_sat_sub_s8 (int8_t a, int8_t b) | |
149 | { | |
150 | int16_t c = (int16_t) a - (int16_t) b; | |
151 | if (c > INT8_MAX) | |
152 | return INT8_MAX; | |
153 | else if (c < INT8_MIN) | |
154 | return INT8_MIN; | |
155 | else | |
156 | return c; | |
157 | } | |
158 | ||
159 | int16_t | |
160 | __hsail_sat_sub_s16 (int16_t a, int16_t b) | |
161 | { | |
162 | int32_t c = (int32_t) a - (int32_t) b; | |
163 | if (c > INT16_MAX) | |
164 | return INT16_MAX; | |
165 | else if (c < INT16_MIN) | |
166 | return INT16_MIN; | |
167 | else | |
168 | return c; | |
169 | } | |
170 | ||
171 | int32_t | |
172 | __hsail_sat_sub_s32 (int32_t a, int32_t b) | |
173 | { | |
315405b6 JJ |
174 | int32_t c; |
175 | if (__builtin_sub_overflow (a, b, &c)) | |
176 | return b < 0 ? INT32_MAX : INT32_MIN; | |
177 | return c; | |
5fd1486c PJ |
178 | } |
179 | ||
180 | int64_t | |
181 | __hsail_sat_sub_s64 (int64_t a, int64_t b) | |
182 | { | |
315405b6 JJ |
183 | int64_t c; |
184 | if (__builtin_sub_overflow (a, b, &c)) | |
185 | return b < 0 ? INT64_MAX : INT64_MIN; | |
186 | return c; | |
5fd1486c PJ |
187 | } |
188 | ||
189 | uint8_t | |
190 | __hsail_sat_mul_u8 (uint8_t a, uint8_t b) | |
191 | { | |
192 | uint16_t c = (uint16_t) a * (uint16_t) b; | |
193 | if (c > UINT8_MAX) | |
194 | return UINT8_MAX; | |
195 | else | |
196 | return c; | |
197 | } | |
198 | ||
199 | uint16_t | |
200 | __hsail_sat_mul_u16 (uint16_t a, uint16_t b) | |
201 | { | |
202 | uint32_t c = (uint32_t) a * (uint32_t) b; | |
203 | if (c > UINT16_MAX) | |
204 | return UINT16_MAX; | |
205 | else | |
206 | return c; | |
207 | } | |
208 | ||
209 | uint32_t | |
210 | __hsail_sat_mul_u32 (uint32_t a, uint32_t b) | |
211 | { | |
315405b6 JJ |
212 | uint32_t c; |
213 | if (__builtin_mul_overflow (a, b, &c)) | |
5fd1486c | 214 | return UINT32_MAX; |
315405b6 | 215 | return c; |
5fd1486c PJ |
216 | } |
217 | ||
218 | uint64_t | |
219 | __hsail_sat_mul_u64 (uint64_t a, uint64_t b) | |
220 | { | |
315405b6 JJ |
221 | uint64_t c; |
222 | if (__builtin_mul_overflow (a, b, &c)) | |
5fd1486c | 223 | return UINT64_MAX; |
315405b6 | 224 | return c; |
5fd1486c PJ |
225 | } |
226 | ||
227 | int8_t | |
228 | __hsail_sat_mul_s8 (int8_t a, int8_t b) | |
229 | { | |
230 | int16_t c = (int16_t) a * (int16_t) b; | |
231 | if (c > INT8_MAX) | |
232 | return INT8_MAX; | |
233 | else if (c < INT8_MIN) | |
234 | return INT8_MIN; | |
235 | else | |
236 | return c; | |
237 | } | |
238 | ||
239 | int16_t | |
240 | __hsail_sat_mul_s16 (int16_t a, int16_t b) | |
241 | { | |
242 | int32_t c = (int32_t) a * (int32_t) b; | |
243 | if (c > INT16_MAX) | |
244 | return INT16_MAX; | |
245 | else if (c < INT16_MIN) | |
246 | return INT16_MIN; | |
247 | else | |
248 | return c; | |
249 | } | |
250 | ||
251 | int32_t | |
252 | __hsail_sat_mul_s32 (int32_t a, int32_t b) | |
253 | { | |
315405b6 JJ |
254 | int32_t c; |
255 | if (__builtin_mul_overflow (a, b, &c)) | |
256 | return ((a > 0) ^ (b > 0)) ? INT32_MIN : INT32_MAX; | |
257 | return c; | |
5fd1486c PJ |
258 | } |
259 | ||
260 | int64_t | |
261 | __hsail_sat_mul_s64 (int64_t a, int64_t b) | |
262 | { | |
315405b6 JJ |
263 | int64_t c; |
264 | if (__builtin_mul_overflow (a, b, &c)) | |
265 | return ((a > 0) ^ (b > 0)) ? INT64_MIN : INT64_MAX; | |
266 | return c; | |
5fd1486c | 267 | } |