1 /*
2  * ARM NEON vector operations.
3  *
4  * Copyright (c) 2007, 2008 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licenced under the GNU GPL v2.
8  */
9 #include <stdlib.h>
10 #include <stdio.h>
11 
12 #include "cpu.h"
13 #include "exec-all.h"
14 #include "helpers.h"
15 
16 #define SIGNBIT (uint32_t)0x80000000
17 #define SIGNBIT64 ((uint64_t)1 << 63)
18 
19 #define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] = CPSR_Q
20 
21 static float_status neon_float_status;
22 #define NFS &neon_float_status
23 
24 /* Helper routines to perform bitwise copies between float and int.  */
vfp_itos(uint32_t i)25 static inline float32 vfp_itos(uint32_t i)
26 {
27     union {
28         uint32_t i;
29         float32 s;
30     } v;
31 
32     v.i = i;
33     return v.s;
34 }
35 
vfp_stoi(float32 s)36 static inline uint32_t vfp_stoi(float32 s)
37 {
38     union {
39         uint32_t i;
40         float32 s;
41     } v;
42 
43     v.s = s;
44     return v.i;
45 }
46 
47 #define NEON_TYPE1(name, type) \
48 typedef struct \
49 { \
50     type v1; \
51 } neon_##name;
52 #ifdef HOST_WORDS_BIGENDIAN
53 #define NEON_TYPE2(name, type) \
54 typedef struct \
55 { \
56     type v2; \
57     type v1; \
58 } neon_##name;
59 #define NEON_TYPE4(name, type) \
60 typedef struct \
61 { \
62     type v4; \
63     type v3; \
64     type v2; \
65     type v1; \
66 } neon_##name;
67 #else
68 #define NEON_TYPE2(name, type) \
69 typedef struct \
70 { \
71     type v1; \
72     type v2; \
73 } neon_##name;
74 #define NEON_TYPE4(name, type) \
75 typedef struct \
76 { \
77     type v1; \
78     type v2; \
79     type v3; \
80     type v4; \
81 } neon_##name;
82 #endif
83 
NEON_TYPE4(s8,int8_t)84 NEON_TYPE4(s8, int8_t)
85 NEON_TYPE4(u8, uint8_t)
86 NEON_TYPE2(s16, int16_t)
87 NEON_TYPE2(u16, uint16_t)
88 NEON_TYPE1(s32, int32_t)
89 NEON_TYPE1(u32, uint32_t)
90 #undef NEON_TYPE4
91 #undef NEON_TYPE2
92 #undef NEON_TYPE1
93 
94 /* Copy from a uint32_t to a vector structure type.  */
95 #define NEON_UNPACK(vtype, dest, val) do { \
96     union { \
97         vtype v; \
98         uint32_t i; \
99     } conv_u; \
100     conv_u.i = (val); \
101     dest = conv_u.v; \
102     } while(0)
103 
104 /* Copy from a vector structure type to a uint32_t.  */
105 #define NEON_PACK(vtype, dest, val) do { \
106     union { \
107         vtype v; \
108         uint32_t i; \
109     } conv_u; \
110     conv_u.v = (val); \
111     dest = conv_u.i; \
112     } while(0)
113 
114 #define NEON_DO1 \
115     NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1);
116 #define NEON_DO2 \
117     NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
118     NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2);
119 #define NEON_DO4 \
120     NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
121     NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2); \
122     NEON_FN(vdest.v3, vsrc1.v3, vsrc2.v3); \
123     NEON_FN(vdest.v4, vsrc1.v4, vsrc2.v4);
124 
125 #define NEON_VOP_BODY(vtype, n) \
126 { \
127     uint32_t res; \
128     vtype vsrc1; \
129     vtype vsrc2; \
130     vtype vdest; \
131     NEON_UNPACK(vtype, vsrc1, arg1); \
132     NEON_UNPACK(vtype, vsrc2, arg2); \
133     NEON_DO##n; \
134     NEON_PACK(vtype, res, vdest); \
135     return res; \
136 }
137 
138 #define NEON_VOP(name, vtype, n) \
139 uint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
140 NEON_VOP_BODY(vtype, n)
141 
142 #define NEON_VOP_ENV(name, vtype, n) \
143 uint32_t HELPER(glue(neon_,name))(CPUState *env, uint32_t arg1, uint32_t arg2) \
144 NEON_VOP_BODY(vtype, n)
145 
146 /* Pairwise operations.  */
147 /* For 32-bit elements each segment only contains a single element, so
148    the elementwise and pairwise operations are the same.  */
149 #define NEON_PDO2 \
150     NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
151     NEON_FN(vdest.v2, vsrc2.v1, vsrc2.v2);
152 #define NEON_PDO4 \
153     NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
154     NEON_FN(vdest.v2, vsrc1.v3, vsrc1.v4); \
155     NEON_FN(vdest.v3, vsrc2.v1, vsrc2.v2); \
156     NEON_FN(vdest.v4, vsrc2.v3, vsrc2.v4); \
157 
158 #define NEON_POP(name, vtype, n) \
159 uint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
160 { \
161     uint32_t res; \
162     vtype vsrc1; \
163     vtype vsrc2; \
164     vtype vdest; \
165     NEON_UNPACK(vtype, vsrc1, arg1); \
166     NEON_UNPACK(vtype, vsrc2, arg2); \
167     NEON_PDO##n; \
168     NEON_PACK(vtype, res, vdest); \
169     return res; \
170 }
171 
172 /* Unary operators.  */
173 #define NEON_VOP1(name, vtype, n) \
174 uint32_t HELPER(glue(neon_,name))(uint32_t arg) \
175 { \
176     vtype vsrc1; \
177     vtype vdest; \
178     NEON_UNPACK(vtype, vsrc1, arg); \
179     NEON_DO##n; \
180     NEON_PACK(vtype, arg, vdest); \
181     return arg; \
182 }
183 
184 
185 #define NEON_USAT(dest, src1, src2, type) do { \
186     uint32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
187     if (tmp != (type)tmp) { \
188         SET_QC(); \
189         dest = ~0; \
190     } else { \
191         dest = tmp; \
192     }} while(0)
193 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
194 NEON_VOP_ENV(qadd_u8, neon_u8, 4)
195 #undef NEON_FN
196 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
197 NEON_VOP_ENV(qadd_u16, neon_u16, 2)
198 #undef NEON_FN
199 #undef NEON_USAT
200 
201 uint32_t HELPER(neon_qadd_u32)(CPUState *env, uint32_t a, uint32_t b)
202 {
203     uint32_t res = a + b;
204     if (res < a) {
205         SET_QC();
206         res = ~0;
207     }
208     return res;
209 }
210 
HELPER(neon_qadd_u64)211 uint64_t HELPER(neon_qadd_u64)(CPUState *env, uint64_t src1, uint64_t src2)
212 {
213     uint64_t res;
214 
215     res = src1 + src2;
216     if (res < src1) {
217         SET_QC();
218         res = ~(uint64_t)0;
219     }
220     return res;
221 }
222 
223 #define NEON_SSAT(dest, src1, src2, type) do { \
224     int32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
225     if (tmp != (type)tmp) { \
226         SET_QC(); \
227         if (src2 > 0) { \
228             tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
229         } else { \
230             tmp = 1 << (sizeof(type) * 8 - 1); \
231         } \
232     } \
233     dest = tmp; \
234     } while(0)
235 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
236 NEON_VOP_ENV(qadd_s8, neon_s8, 4)
237 #undef NEON_FN
238 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
239 NEON_VOP_ENV(qadd_s16, neon_s16, 2)
240 #undef NEON_FN
241 #undef NEON_SSAT
242 
243 uint32_t HELPER(neon_qadd_s32)(CPUState *env, uint32_t a, uint32_t b)
244 {
245     uint32_t res = a + b;
246     if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
247         SET_QC();
248         res = ~(((int32_t)a >> 31) ^ SIGNBIT);
249     }
250     return res;
251 }
252 
HELPER(neon_qadd_s64)253 uint64_t HELPER(neon_qadd_s64)(CPUState *env, uint64_t src1, uint64_t src2)
254 {
255     uint64_t res;
256 
257     res = src1 + src2;
258     if (((res ^ src1) & SIGNBIT64) && !((src1 ^ src2) & SIGNBIT64)) {
259         SET_QC();
260         res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
261     }
262     return res;
263 }
264 
265 #define NEON_USAT(dest, src1, src2, type) do { \
266     uint32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
267     if (tmp != (type)tmp) { \
268         SET_QC(); \
269         dest = 0; \
270     } else { \
271         dest = tmp; \
272     }} while(0)
273 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
274 NEON_VOP_ENV(qsub_u8, neon_u8, 4)
275 #undef NEON_FN
276 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
277 NEON_VOP_ENV(qsub_u16, neon_u16, 2)
278 #undef NEON_FN
279 #undef NEON_USAT
280 
281 uint32_t HELPER(neon_qsub_u32)(CPUState *env, uint32_t a, uint32_t b)
282 {
283     uint32_t res = a - b;
284     if (res > a) {
285         SET_QC();
286         res = 0;
287     }
288     return res;
289 }
290 
HELPER(neon_qsub_u64)291 uint64_t HELPER(neon_qsub_u64)(CPUState *env, uint64_t src1, uint64_t src2)
292 {
293     uint64_t res;
294 
295     if (src1 < src2) {
296         SET_QC();
297         res = 0;
298     } else {
299         res = src1 - src2;
300     }
301     return res;
302 }
303 
304 #define NEON_SSAT(dest, src1, src2, type) do { \
305     int32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
306     if (tmp != (type)tmp) { \
307         SET_QC(); \
308         if (src2 < 0) { \
309             tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
310         } else { \
311             tmp = 1 << (sizeof(type) * 8 - 1); \
312         } \
313     } \
314     dest = tmp; \
315     } while(0)
316 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
317 NEON_VOP_ENV(qsub_s8, neon_s8, 4)
318 #undef NEON_FN
319 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
320 NEON_VOP_ENV(qsub_s16, neon_s16, 2)
321 #undef NEON_FN
322 #undef NEON_SSAT
323 
324 uint32_t HELPER(neon_qsub_s32)(CPUState *env, uint32_t a, uint32_t b)
325 {
326     uint32_t res = a - b;
327     if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
328         SET_QC();
329         res = ~(((int32_t)a >> 31) ^ SIGNBIT);
330     }
331     return res;
332 }
333 
HELPER(neon_qsub_s64)334 uint64_t HELPER(neon_qsub_s64)(CPUState *env, uint64_t src1, uint64_t src2)
335 {
336     uint64_t res;
337 
338     res = src1 - src2;
339     if (((res ^ src1) & SIGNBIT64) && ((src1 ^ src2) & SIGNBIT64)) {
340         SET_QC();
341         res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
342     }
343     return res;
344 }
345 
346 #define NEON_FN(dest, src1, src2) dest = (src1 + src2) >> 1
347 NEON_VOP(hadd_s8, neon_s8, 4)
348 NEON_VOP(hadd_u8, neon_u8, 4)
349 NEON_VOP(hadd_s16, neon_s16, 2)
350 NEON_VOP(hadd_u16, neon_u16, 2)
351 #undef NEON_FN
352 
353 int32_t HELPER(neon_hadd_s32)(int32_t src1, int32_t src2)
354 {
355     int32_t dest;
356 
357     dest = (src1 >> 1) + (src2 >> 1);
358     if (src1 & src2 & 1)
359         dest++;
360     return dest;
361 }
362 
HELPER(neon_hadd_u32)363 uint32_t HELPER(neon_hadd_u32)(uint32_t src1, uint32_t src2)
364 {
365     uint32_t dest;
366 
367     dest = (src1 >> 1) + (src2 >> 1);
368     if (src1 & src2 & 1)
369         dest++;
370     return dest;
371 }
372 
373 #define NEON_FN(dest, src1, src2) dest = (src1 + src2 + 1) >> 1
374 NEON_VOP(rhadd_s8, neon_s8, 4)
375 NEON_VOP(rhadd_u8, neon_u8, 4)
376 NEON_VOP(rhadd_s16, neon_s16, 2)
377 NEON_VOP(rhadd_u16, neon_u16, 2)
378 #undef NEON_FN
379 
380 int32_t HELPER(neon_rhadd_s32)(int32_t src1, int32_t src2)
381 {
382     int32_t dest;
383 
384     dest = (src1 >> 1) + (src2 >> 1);
385     if ((src1 | src2) & 1)
386         dest++;
387     return dest;
388 }
389 
HELPER(neon_rhadd_u32)390 uint32_t HELPER(neon_rhadd_u32)(uint32_t src1, uint32_t src2)
391 {
392     uint32_t dest;
393 
394     dest = (src1 >> 1) + (src2 >> 1);
395     if ((src1 | src2) & 1)
396         dest++;
397     return dest;
398 }
399 
400 #define NEON_FN(dest, src1, src2) dest = (src1 - src2) >> 1
401 NEON_VOP(hsub_s8, neon_s8, 4)
402 NEON_VOP(hsub_u8, neon_u8, 4)
403 NEON_VOP(hsub_s16, neon_s16, 2)
404 NEON_VOP(hsub_u16, neon_u16, 2)
405 #undef NEON_FN
406 
407 int32_t HELPER(neon_hsub_s32)(int32_t src1, int32_t src2)
408 {
409     int32_t dest;
410 
411     dest = (src1 >> 1) - (src2 >> 1);
412     if ((~src1) & src2 & 1)
413         dest--;
414     return dest;
415 }
416 
HELPER(neon_hsub_u32)417 uint32_t HELPER(neon_hsub_u32)(uint32_t src1, uint32_t src2)
418 {
419     uint32_t dest;
420 
421     dest = (src1 >> 1) - (src2 >> 1);
422     if ((~src1) & src2 & 1)
423         dest--;
424     return dest;
425 }
426 
427 #define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? ~0 : 0
428 NEON_VOP(cgt_s8, neon_s8, 4)
429 NEON_VOP(cgt_u8, neon_u8, 4)
430 NEON_VOP(cgt_s16, neon_s16, 2)
431 NEON_VOP(cgt_u16, neon_u16, 2)
432 NEON_VOP(cgt_s32, neon_s32, 1)
433 NEON_VOP(cgt_u32, neon_u32, 1)
434 #undef NEON_FN
435 
436 #define NEON_FN(dest, src1, src2) dest = (src1 >= src2) ? ~0 : 0
437 NEON_VOP(cge_s8, neon_s8, 4)
438 NEON_VOP(cge_u8, neon_u8, 4)
439 NEON_VOP(cge_s16, neon_s16, 2)
440 NEON_VOP(cge_u16, neon_u16, 2)
441 NEON_VOP(cge_s32, neon_s32, 1)
442 NEON_VOP(cge_u32, neon_u32, 1)
443 #undef NEON_FN
444 
445 #define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
446 NEON_VOP(min_s8, neon_s8, 4)
447 NEON_VOP(min_u8, neon_u8, 4)
448 NEON_VOP(min_s16, neon_s16, 2)
449 NEON_VOP(min_u16, neon_u16, 2)
450 NEON_VOP(min_s32, neon_s32, 1)
451 NEON_VOP(min_u32, neon_u32, 1)
452 NEON_POP(pmin_s8, neon_s8, 4)
453 NEON_POP(pmin_u8, neon_u8, 4)
454 NEON_POP(pmin_s16, neon_s16, 2)
455 NEON_POP(pmin_u16, neon_u16, 2)
456 #undef NEON_FN
457 
458 #define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? src1 : src2
459 NEON_VOP(max_s8, neon_s8, 4)
460 NEON_VOP(max_u8, neon_u8, 4)
461 NEON_VOP(max_s16, neon_s16, 2)
462 NEON_VOP(max_u16, neon_u16, 2)
463 NEON_VOP(max_s32, neon_s32, 1)
464 NEON_VOP(max_u32, neon_u32, 1)
465 NEON_POP(pmax_s8, neon_s8, 4)
466 NEON_POP(pmax_u8, neon_u8, 4)
467 NEON_POP(pmax_s16, neon_s16, 2)
468 NEON_POP(pmax_u16, neon_u16, 2)
469 #undef NEON_FN
470 
471 #define NEON_FN(dest, src1, src2) \
472     dest = (src1 > src2) ? (src1 - src2) : (src2 - src1)
473 NEON_VOP(abd_s8, neon_s8, 4)
474 NEON_VOP(abd_u8, neon_u8, 4)
475 NEON_VOP(abd_s16, neon_s16, 2)
476 NEON_VOP(abd_u16, neon_u16, 2)
477 NEON_VOP(abd_s32, neon_s32, 1)
478 NEON_VOP(abd_u32, neon_u32, 1)
479 #undef NEON_FN
480 
481 #define NEON_FN(dest, src1, src2) do { \
482     int8_t tmp; \
483     tmp = (int8_t)src2; \
484     if (tmp >= (ssize_t)sizeof(src1) * 8 || \
485         tmp <= -(ssize_t)sizeof(src1) * 8) { \
486         dest = 0; \
487     } else if (tmp < 0) { \
488         dest = src1 >> -tmp; \
489     } else { \
490         dest = src1 << tmp; \
491     }} while (0)
492 NEON_VOP(shl_u8, neon_u8, 4)
493 NEON_VOP(shl_u16, neon_u16, 2)
494 NEON_VOP(shl_u32, neon_u32, 1)
495 #undef NEON_FN
496 
497 uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
498 {
499     int8_t shift = (int8_t)shiftop;
500     if (shift >= 64 || shift <= -64) {
501         val = 0;
502     } else if (shift < 0) {
503         val >>= -shift;
504     } else {
505         val <<= shift;
506     }
507     return val;
508 }
509 
510 #define NEON_FN(dest, src1, src2) do { \
511     int8_t tmp; \
512     tmp = (int8_t)src2; \
513     if (tmp >= (ssize_t)sizeof(src1) * 8) { \
514         dest = 0; \
515     } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
516         dest = src1 >> (sizeof(src1) * 8 - 1); \
517     } else if (tmp < 0) { \
518         dest = src1 >> -tmp; \
519     } else { \
520         dest = src1 << tmp; \
521     }} while (0)
522 NEON_VOP(shl_s8, neon_s8, 4)
523 NEON_VOP(shl_s16, neon_s16, 2)
524 NEON_VOP(shl_s32, neon_s32, 1)
525 #undef NEON_FN
526 
527 uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
528 {
529     int8_t shift = (int8_t)shiftop;
530     int64_t val = valop;
531     if (shift >= 64) {
532         val = 0;
533     } else if (shift <= -64) {
534         val >>= 63;
535     } else if (shift < 0) {
536         val >>= -shift;
537     } else {
538         val <<= shift;
539     }
540     return val;
541 }
542 
543 #define NEON_FN(dest, src1, src2) do { \
544     int8_t tmp; \
545     tmp = (int8_t)src2; \
546     if (tmp >= (ssize_t)sizeof(src1) * 8) { \
547         dest = 0; \
548     } else if (tmp < -(ssize_t)sizeof(src1) * 8) { \
549         dest = src1 >> (sizeof(src1) * 8 - 1); \
550     } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
551         dest = src1 >> (tmp - 1); \
552         dest++; \
553         dest >>= 1; \
554     } else if (tmp < 0) { \
555         dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
556     } else { \
557         dest = src1 << tmp; \
558     }} while (0)
559 NEON_VOP(rshl_s8, neon_s8, 4)
560 NEON_VOP(rshl_s16, neon_s16, 2)
561 NEON_VOP(rshl_s32, neon_s32, 1)
562 #undef NEON_FN
563 
564 uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
565 {
566     int8_t shift = (int8_t)shiftop;
567     int64_t val = valop;
568     if (shift >= 64) {
569         val = 0;
570     } else if (shift < -64) {
571         val >>= 63;
572     } else if (shift == -63) {
573         val >>= 63;
574         val++;
575         val >>= 1;
576     } else if (shift < 0) {
577         val = (val + ((int64_t)1 << (-1 - shift))) >> -shift;
578     } else {
579         val <<= shift;
580     }
581     return val;
582 }
583 
584 #define NEON_FN(dest, src1, src2) do { \
585     int8_t tmp; \
586     tmp = (int8_t)src2; \
587     if (tmp >= (ssize_t)sizeof(src1) * 8 || \
588         tmp < -(ssize_t)sizeof(src1) * 8) { \
589         dest = 0; \
590     } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
591         dest = src1 >> (tmp - 1); \
592     } else if (tmp < 0) { \
593         dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
594     } else { \
595         dest = src1 << tmp; \
596     }} while (0)
597 NEON_VOP(rshl_u8, neon_u8, 4)
598 NEON_VOP(rshl_u16, neon_u16, 2)
599 NEON_VOP(rshl_u32, neon_u32, 1)
600 #undef NEON_FN
601 
602 uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
603 {
604     int8_t shift = (uint8_t)shiftop;
605     if (shift >= 64 || shift < 64) {
606         val = 0;
607     } else if (shift == -64) {
608         /* Rounding a 1-bit result just preserves that bit.  */
609         val >>= 63;
610     } if (shift < 0) {
611         val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift;
612         val >>= -shift;
613     } else {
614         val <<= shift;
615     }
616     return val;
617 }
618 
619 #define NEON_FN(dest, src1, src2) do { \
620     int8_t tmp; \
621     tmp = (int8_t)src2; \
622     if (tmp >= (ssize_t)sizeof(src1) * 8) { \
623         if (src1) { \
624             SET_QC(); \
625             dest = ~0; \
626         } else { \
627             dest = 0; \
628         } \
629     } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
630         dest = 0; \
631     } else if (tmp < 0) { \
632         dest = src1 >> -tmp; \
633     } else { \
634         dest = src1 << tmp; \
635         if ((dest >> tmp) != src1) { \
636             SET_QC(); \
637             dest = ~0; \
638         } \
639     }} while (0)
640 NEON_VOP_ENV(qshl_u8, neon_u8, 4)
641 NEON_VOP_ENV(qshl_u16, neon_u16, 2)
642 NEON_VOP_ENV(qshl_u32, neon_u32, 1)
643 #undef NEON_FN
644 
645 uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
646 {
647     int8_t shift = (int8_t)shiftop;
648     if (shift >= 64) {
649         if (val) {
650             val = ~(uint64_t)0;
651             SET_QC();
652         }
653     } else if (shift <= -64) {
654         val = 0;
655     } else if (shift < 0) {
656         val >>= -shift;
657     } else {
658         uint64_t tmp = val;
659         val <<= shift;
660         if ((val >> shift) != tmp) {
661             SET_QC();
662             val = ~(uint64_t)0;
663         }
664     }
665     return val;
666 }
667 
668 #define NEON_FN(dest, src1, src2) do { \
669     int8_t tmp; \
670     tmp = (int8_t)src2; \
671     if (tmp >= (ssize_t)sizeof(src1) * 8) { \
672         if (src1) { \
673             SET_QC(); \
674             dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
675             if (src1 > 0) { \
676                 dest--; \
677             } \
678         } else { \
679             dest = src1; \
680         } \
681     } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
682         dest = src1 >> 31; \
683     } else if (tmp < 0) { \
684         dest = src1 >> -tmp; \
685     } else { \
686         dest = src1 << tmp; \
687         if ((dest >> tmp) != src1) { \
688             SET_QC(); \
689             dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
690             if (src1 > 0) { \
691                 dest--; \
692             } \
693         } \
694     }} while (0)
695 NEON_VOP_ENV(qshl_s8, neon_s8, 4)
696 NEON_VOP_ENV(qshl_s16, neon_s16, 2)
697 NEON_VOP_ENV(qshl_s32, neon_s32, 1)
698 #undef NEON_FN
699 
700 uint64_t HELPER(neon_qshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
701 {
702     int8_t shift = (uint8_t)shiftop;
703     int64_t val = valop;
704     if (shift >= 64) {
705         if (val) {
706             SET_QC();
707             val = (val >> 63) ^ ~SIGNBIT64;
708         }
709     } else if (shift <= -64) {
710         val >>= 63;
711     } else if (shift < 0) {
712         val >>= -shift;
713     } else {
714         int64_t tmp = val;
715         val <<= shift;
716         if ((val >> shift) != tmp) {
717             SET_QC();
718             val = (tmp >> 63) ^ ~SIGNBIT64;
719         }
720     }
721     return val;
722 }
723 
724 #define NEON_FN(dest, src1, src2) do { \
725     if (src1 & (1 << (sizeof(src1) * 8 - 1))) { \
726         SET_QC(); \
727         dest = 0; \
728     } else { \
729         int8_t tmp; \
730         tmp = (int8_t)src2; \
731         if (tmp >= (ssize_t)sizeof(src1) * 8) { \
732             if (src1) { \
733                 SET_QC(); \
734                 dest = ~0; \
735             } else { \
736                 dest = 0; \
737             } \
738         } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
739             dest = 0; \
740         } else if (tmp < 0) { \
741             dest = src1 >> -tmp; \
742         } else { \
743             dest = src1 << tmp; \
744             if ((dest >> tmp) != src1) { \
745                 SET_QC(); \
746                 dest = ~0; \
747             } \
748         } \
749     }} while (0)
750 NEON_VOP_ENV(qshlu_s8, neon_u8, 4)
751 NEON_VOP_ENV(qshlu_s16, neon_u16, 2)
752 #undef NEON_FN
753 
754 uint32_t HELPER(neon_qshlu_s32)(CPUState *env, uint32_t valop, uint32_t shiftop)
755 {
756     if ((int32_t)valop < 0) {
757         SET_QC();
758         return 0;
759     }
760     return helper_neon_qshl_u32(env, valop, shiftop);
761 }
762 
HELPER(neon_qshlu_s64)763 uint64_t HELPER(neon_qshlu_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
764 {
765     if ((int64_t)valop < 0) {
766         SET_QC();
767         return 0;
768     }
769     return helper_neon_qshl_u64(env, valop, shiftop);
770 }
771 
772 /* FIXME: This is wrong.  */
773 #define NEON_FN(dest, src1, src2) do { \
774     int8_t tmp; \
775     tmp = (int8_t)src2; \
776     if (tmp < 0) { \
777         dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
778     } else { \
779         dest = src1 << tmp; \
780         if ((dest >> tmp) != src1) { \
781             SET_QC(); \
782             dest = ~0; \
783         } \
784     }} while (0)
785 NEON_VOP_ENV(qrshl_u8, neon_u8, 4)
786 NEON_VOP_ENV(qrshl_u16, neon_u16, 2)
787 NEON_VOP_ENV(qrshl_u32, neon_u32, 1)
788 #undef NEON_FN
789 
790 uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
791 {
792     int8_t shift = (int8_t)shiftop;
793     if (shift < 0) {
794         val = (val + (1 << (-1 - shift))) >> -shift;
795     } else { \
796         uint64_t tmp = val;
797         val <<= shift;
798         if ((val >> shift) != tmp) {
799             SET_QC();
800             val = ~0;
801         }
802     }
803     return val;
804 }
805 
806 #define NEON_FN(dest, src1, src2) do { \
807     int8_t tmp; \
808     tmp = (int8_t)src2; \
809     if (tmp < 0) { \
810         dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
811     } else { \
812         dest = src1 << tmp; \
813         if ((dest >> tmp) != src1) { \
814             SET_QC(); \
815             dest = src1 >> 31; \
816         } \
817     }} while (0)
818 NEON_VOP_ENV(qrshl_s8, neon_s8, 4)
819 NEON_VOP_ENV(qrshl_s16, neon_s16, 2)
820 NEON_VOP_ENV(qrshl_s32, neon_s32, 1)
821 #undef NEON_FN
822 
823 uint64_t HELPER(neon_qrshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
824 {
825     int8_t shift = (uint8_t)shiftop;
826     int64_t val = valop;
827 
828     if (shift < 0) {
829         val = (val + (1 << (-1 - shift))) >> -shift;
830     } else {
831         int64_t tmp = val;;
832         val <<= shift;
833         if ((val >> shift) != tmp) {
834             SET_QC();
835             val = tmp >> 31;
836         }
837     }
838     return val;
839 }
840 
HELPER(neon_add_u8)841 uint32_t HELPER(neon_add_u8)(uint32_t a, uint32_t b)
842 {
843     uint32_t mask;
844     mask = (a ^ b) & 0x80808080u;
845     a &= ~0x80808080u;
846     b &= ~0x80808080u;
847     return (a + b) ^ mask;
848 }
849 
HELPER(neon_add_u16)850 uint32_t HELPER(neon_add_u16)(uint32_t a, uint32_t b)
851 {
852     uint32_t mask;
853     mask = (a ^ b) & 0x80008000u;
854     a &= ~0x80008000u;
855     b &= ~0x80008000u;
856     return (a + b) ^ mask;
857 }
858 
859 #define NEON_FN(dest, src1, src2) dest = src1 + src2
860 NEON_POP(padd_u8, neon_u8, 4)
861 NEON_POP(padd_u16, neon_u16, 2)
862 #undef NEON_FN
863 
864 #define NEON_FN(dest, src1, src2) dest = src1 - src2
865 NEON_VOP(sub_u8, neon_u8, 4)
866 NEON_VOP(sub_u16, neon_u16, 2)
867 #undef NEON_FN
868 
869 #define NEON_FN(dest, src1, src2) dest = src1 * src2
870 NEON_VOP(mul_u8, neon_u8, 4)
871 NEON_VOP(mul_u16, neon_u16, 2)
872 #undef NEON_FN
873 
874 /* Polynomial multiplication is like integer multiplication except the
875    partial products are XORed, not added.  */
876 uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
877 {
878     uint32_t mask;
879     uint32_t result;
880     result = 0;
881     while (op1) {
882         mask = 0;
883         if (op1 & 1)
884             mask |= 0xff;
885         if (op1 & (1 << 8))
886             mask |= (0xff << 8);
887         if (op1 & (1 << 16))
888             mask |= (0xff << 16);
889         if (op1 & (1 << 24))
890             mask |= (0xff << 24);
891         result ^= op2 & mask;
892         op1 = (op1 >> 1) & 0x7f7f7f7f;
893         op2 = (op2 << 1) & 0xfefefefe;
894     }
895     return result;
896 }
897 
898 #define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
899 NEON_VOP(tst_u8, neon_u8, 4)
900 NEON_VOP(tst_u16, neon_u16, 2)
901 NEON_VOP(tst_u32, neon_u32, 1)
902 #undef NEON_FN
903 
904 #define NEON_FN(dest, src1, src2) dest = (src1 == src2) ? -1 : 0
905 NEON_VOP(ceq_u8, neon_u8, 4)
906 NEON_VOP(ceq_u16, neon_u16, 2)
907 NEON_VOP(ceq_u32, neon_u32, 1)
908 #undef NEON_FN
909 
910 #define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
911 NEON_VOP1(abs_s8, neon_s8, 4)
912 NEON_VOP1(abs_s16, neon_s16, 2)
913 #undef NEON_FN
914 
915 /* Count Leading Sign/Zero Bits.  */
916 static inline int do_clz8(uint8_t x)
917 {
918     int n;
919     for (n = 8; x; n--)
920         x >>= 1;
921     return n;
922 }
923 
do_clz16(uint16_t x)924 static inline int do_clz16(uint16_t x)
925 {
926     int n;
927     for (n = 16; x; n--)
928         x >>= 1;
929     return n;
930 }
931 
932 #define NEON_FN(dest, src, dummy) dest = do_clz8(src)
933 NEON_VOP1(clz_u8, neon_u8, 4)
934 #undef NEON_FN
935 
936 #define NEON_FN(dest, src, dummy) dest = do_clz16(src)
937 NEON_VOP1(clz_u16, neon_u16, 2)
938 #undef NEON_FN
939 
940 #define NEON_FN(dest, src, dummy) dest = do_clz8((src < 0) ? ~src : src) - 1
941 NEON_VOP1(cls_s8, neon_s8, 4)
942 #undef NEON_FN
943 
944 #define NEON_FN(dest, src, dummy) dest = do_clz16((src < 0) ? ~src : src) - 1
945 NEON_VOP1(cls_s16, neon_s16, 2)
946 #undef NEON_FN
947 
948 uint32_t HELPER(neon_cls_s32)(uint32_t x)
949 {
950     int count;
951     if ((int32_t)x < 0)
952         x = ~x;
953     for (count = 32; x; count--)
954         x = x >> 1;
955     return count - 1;
956 }
957 
958 /* Bit count.  */
HELPER(neon_cnt_u8)959 uint32_t HELPER(neon_cnt_u8)(uint32_t x)
960 {
961     x = (x & 0x55555555) + ((x >>  1) & 0x55555555);
962     x = (x & 0x33333333) + ((x >>  2) & 0x33333333);
963     x = (x & 0x0f0f0f0f) + ((x >>  4) & 0x0f0f0f0f);
964     return x;
965 }
966 
967 #define NEON_QDMULH16(dest, src1, src2, round) do { \
968     uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \
969     if ((tmp ^ (tmp << 1)) & SIGNBIT) { \
970         SET_QC(); \
971         tmp = (tmp >> 31) ^ ~SIGNBIT; \
972     } else { \
973         tmp <<= 1; \
974     } \
975     if (round) { \
976         int32_t old = tmp; \
977         tmp += 1 << 15; \
978         if ((int32_t)tmp < old) { \
979             SET_QC(); \
980             tmp = SIGNBIT - 1; \
981         } \
982     } \
983     dest = tmp >> 16; \
984     } while(0)
985 #define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 0)
986 NEON_VOP_ENV(qdmulh_s16, neon_s16, 2)
987 #undef NEON_FN
988 #define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 1)
989 NEON_VOP_ENV(qrdmulh_s16, neon_s16, 2)
990 #undef NEON_FN
991 #undef NEON_QDMULH16
992 
993 #define NEON_QDMULH32(dest, src1, src2, round) do { \
994     uint64_t tmp = (int64_t)(int32_t) src1 * (int32_t) src2; \
995     if ((tmp ^ (tmp << 1)) & SIGNBIT64) { \
996         SET_QC(); \
997         tmp = (tmp >> 63) ^ ~SIGNBIT64; \
998     } else { \
999         tmp <<= 1; \
1000     } \
1001     if (round) { \
1002         int64_t old = tmp; \
1003         tmp += (int64_t)1 << 31; \
1004         if ((int64_t)tmp < old) { \
1005             SET_QC(); \
1006             tmp = SIGNBIT64 - 1; \
1007         } \
1008     } \
1009     dest = tmp >> 32; \
1010     } while(0)
1011 #define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 0)
1012 NEON_VOP_ENV(qdmulh_s32, neon_s32, 1)
1013 #undef NEON_FN
1014 #define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 1)
1015 NEON_VOP_ENV(qrdmulh_s32, neon_s32, 1)
1016 #undef NEON_FN
1017 #undef NEON_QDMULH32
1018 
1019 uint32_t HELPER(neon_narrow_u8)(uint64_t x)
1020 {
1021     return (x & 0xffu) | ((x >> 8) & 0xff00u) | ((x >> 16) & 0xff0000u)
1022            | ((x >> 24) & 0xff000000u);
1023 }
1024 
HELPER(neon_narrow_u16)1025 uint32_t HELPER(neon_narrow_u16)(uint64_t x)
1026 {
1027     return (x & 0xffffu) | ((x >> 16) & 0xffff0000u);
1028 }
1029 
HELPER(neon_narrow_high_u8)1030 uint32_t HELPER(neon_narrow_high_u8)(uint64_t x)
1031 {
1032     return ((x >> 8) & 0xff) | ((x >> 16) & 0xff00)
1033             | ((x >> 24) & 0xff0000) | ((x >> 32) & 0xff000000);
1034 }
1035 
HELPER(neon_narrow_high_u16)1036 uint32_t HELPER(neon_narrow_high_u16)(uint64_t x)
1037 {
1038     return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
1039 }
1040 
HELPER(neon_narrow_round_high_u8)1041 uint32_t HELPER(neon_narrow_round_high_u8)(uint64_t x)
1042 {
1043     x &= 0xff80ff80ff80ff80ull;
1044     x += 0x0080008000800080ull;
1045     return ((x >> 8) & 0xff) | ((x >> 16) & 0xff00)
1046             | ((x >> 24) & 0xff0000) | ((x >> 32) & 0xff000000);
1047 }
1048 
HELPER(neon_narrow_round_high_u16)1049 uint32_t HELPER(neon_narrow_round_high_u16)(uint64_t x)
1050 {
1051     x &= 0xffff8000ffff8000ull;
1052     x += 0x0000800000008000ull;
1053     return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
1054 }
1055 
HELPER(neon_narrow_sat_u8)1056 uint32_t HELPER(neon_narrow_sat_u8)(CPUState *env, uint64_t x)
1057 {
1058     uint16_t s;
1059     uint8_t d;
1060     uint32_t res = 0;
1061 #define SAT8(n) \
1062     s = x >> n; \
1063     if (s > 0xff) { \
1064         d = 0xff; \
1065         SET_QC(); \
1066     } else  { \
1067         d = s; \
1068     } \
1069     res |= (uint32_t)d << (n / 2);
1070 
1071     SAT8(0);
1072     SAT8(16);
1073     SAT8(32);
1074     SAT8(48);
1075 #undef SAT8
1076     return res;
1077 }
1078 
HELPER(neon_narrow_sat_s8)1079 uint32_t HELPER(neon_narrow_sat_s8)(CPUState *env, uint64_t x)
1080 {
1081     int16_t s;
1082     uint8_t d;
1083     uint32_t res = 0;
1084 #define SAT8(n) \
1085     s = x >> n; \
1086     if (s != (int8_t)s) { \
1087         d = (s >> 15) ^ 0x7f; \
1088         SET_QC(); \
1089     } else  { \
1090         d = s; \
1091     } \
1092     res |= (uint32_t)d << (n / 2);
1093 
1094     SAT8(0);
1095     SAT8(16);
1096     SAT8(32);
1097     SAT8(48);
1098 #undef SAT8
1099     return res;
1100 }
1101 
HELPER(neon_narrow_sat_u16)1102 uint32_t HELPER(neon_narrow_sat_u16)(CPUState *env, uint64_t x)
1103 {
1104     uint32_t high;
1105     uint32_t low;
1106     low = x;
1107     if (low > 0xffff) {
1108         low = 0xffff;
1109         SET_QC();
1110     }
1111     high = x >> 32;
1112     if (high > 0xffff) {
1113         high = 0xffff;
1114         SET_QC();
1115     }
1116     return low | (high << 16);
1117 }
1118 
HELPER(neon_narrow_sat_s16)1119 uint32_t HELPER(neon_narrow_sat_s16)(CPUState *env, uint64_t x)
1120 {
1121     int32_t low;
1122     int32_t high;
1123     low = x;
1124     if (low != (int16_t)low) {
1125         low = (low >> 31) ^ 0x7fff;
1126         SET_QC();
1127     }
1128     high = x >> 32;
1129     if (high != (int16_t)high) {
1130         high = (high >> 31) ^ 0x7fff;
1131         SET_QC();
1132     }
1133     return (uint16_t)low | (high << 16);
1134 }
1135 
HELPER(neon_narrow_sat_u32)1136 uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x)
1137 {
1138     if (x > 0xffffffffu) {
1139         SET_QC();
1140         return 0xffffffffu;
1141     }
1142     return x;
1143 }
1144 
HELPER(neon_narrow_sat_s32)1145 uint32_t HELPER(neon_narrow_sat_s32)(CPUState *env, uint64_t x)
1146 {
1147     if ((int64_t)x != (int32_t)x) {
1148         SET_QC();
1149         return (x >> 63) ^ 0x7fffffff;
1150     }
1151     return x;
1152 }
1153 
HELPER(neon_widen_u8)1154 uint64_t HELPER(neon_widen_u8)(uint32_t x)
1155 {
1156     uint64_t tmp;
1157     uint64_t ret;
1158     ret = (uint8_t)x;
1159     tmp = (uint8_t)(x >> 8);
1160     ret |= tmp << 16;
1161     tmp = (uint8_t)(x >> 16);
1162     ret |= tmp << 32;
1163     tmp = (uint8_t)(x >> 24);
1164     ret |= tmp << 48;
1165     return ret;
1166 }
1167 
HELPER(neon_widen_s8)1168 uint64_t HELPER(neon_widen_s8)(uint32_t x)
1169 {
1170     uint64_t tmp;
1171     uint64_t ret;
1172     ret = (uint16_t)(int8_t)x;
1173     tmp = (uint16_t)(int8_t)(x >> 8);
1174     ret |= tmp << 16;
1175     tmp = (uint16_t)(int8_t)(x >> 16);
1176     ret |= tmp << 32;
1177     tmp = (uint16_t)(int8_t)(x >> 24);
1178     ret |= tmp << 48;
1179     return ret;
1180 }
1181 
HELPER(neon_widen_u16)1182 uint64_t HELPER(neon_widen_u16)(uint32_t x)
1183 {
1184     uint64_t high = (uint16_t)(x >> 16);
1185     return ((uint16_t)x) | (high << 32);
1186 }
1187 
HELPER(neon_widen_s16)1188 uint64_t HELPER(neon_widen_s16)(uint32_t x)
1189 {
1190     uint64_t high = (int16_t)(x >> 16);
1191     return ((uint32_t)(int16_t)x) | (high << 32);
1192 }
1193 
HELPER(neon_addl_u16)1194 uint64_t HELPER(neon_addl_u16)(uint64_t a, uint64_t b)
1195 {
1196     uint64_t mask;
1197     mask = (a ^ b) & 0x8000800080008000ull;
1198     a &= ~0x8000800080008000ull;
1199     b &= ~0x8000800080008000ull;
1200     return (a + b) ^ mask;
1201 }
1202 
HELPER(neon_addl_u32)1203 uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b)
1204 {
1205     uint64_t mask;
1206     mask = (a ^ b) & 0x8000000080000000ull;
1207     a &= ~0x8000000080000000ull;
1208     b &= ~0x8000000080000000ull;
1209     return (a + b) ^ mask;
1210 }
1211 
HELPER(neon_paddl_u16)1212 uint64_t HELPER(neon_paddl_u16)(uint64_t a, uint64_t b)
1213 {
1214     uint64_t tmp;
1215     uint64_t tmp2;
1216 
1217     tmp = a & 0x0000ffff0000ffffull;
1218     tmp += (a >> 16) & 0x0000ffff0000ffffull;
1219     tmp2 = b & 0xffff0000ffff0000ull;
1220     tmp2 += (b << 16) & 0xffff0000ffff0000ull;
1221     return    ( tmp         & 0xffff)
1222             | ((tmp  >> 16) & 0xffff0000ull)
1223             | ((tmp2 << 16) & 0xffff00000000ull)
1224             | ( tmp2        & 0xffff000000000000ull);
1225 }
1226 
HELPER(neon_paddl_u32)1227 uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b)
1228 {
1229     uint32_t low = a + (a >> 32);
1230     uint32_t high = b + (b >> 32);
1231     return low + ((uint64_t)high << 32);
1232 }
1233 
HELPER(neon_subl_u16)1234 uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b)
1235 {
1236     uint64_t mask;
1237     mask = (a ^ ~b) & 0x8000800080008000ull;
1238     a |= 0x8000800080008000ull;
1239     b &= ~0x8000800080008000ull;
1240     return (a - b) ^ mask;
1241 }
1242 
HELPER(neon_subl_u32)1243 uint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b)
1244 {
1245     uint64_t mask;
1246     mask = (a ^ ~b) & 0x8000000080000000ull;
1247     a |= 0x8000000080000000ull;
1248     b &= ~0x8000000080000000ull;
1249     return (a - b) ^ mask;
1250 }
1251 
HELPER(neon_addl_saturate_s32)1252 uint64_t HELPER(neon_addl_saturate_s32)(CPUState *env, uint64_t a, uint64_t b)
1253 {
1254     uint32_t x, y;
1255     uint32_t low, high;
1256 
1257     x = a;
1258     y = b;
1259     low = x + y;
1260     if (((low ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) {
1261         SET_QC();
1262         low = ((int32_t)x >> 31) ^ ~SIGNBIT;
1263     }
1264     x = a >> 32;
1265     y = b >> 32;
1266     high = x + y;
1267     if (((high ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) {
1268         SET_QC();
1269         high = ((int32_t)x >> 31) ^ ~SIGNBIT;
1270     }
1271     return low | ((uint64_t)high << 32);
1272 }
1273 
HELPER(neon_addl_saturate_s64)1274 uint64_t HELPER(neon_addl_saturate_s64)(CPUState *env, uint64_t a, uint64_t b)
1275 {
1276     uint64_t result;
1277 
1278     result = a + b;
1279     if (((result ^ a) & SIGNBIT64) && !((a ^ b) & SIGNBIT64)) {
1280         SET_QC();
1281         result = ((int64_t)a >> 63) ^ ~SIGNBIT64;
1282     }
1283     return result;
1284 }
1285 
1286 #define DO_ABD(dest, x, y, type) do { \
1287     type tmp_x = x; \
1288     type tmp_y = y; \
1289     dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \
1290     } while(0)
1291 
HELPER(neon_abdl_u16)1292 uint64_t HELPER(neon_abdl_u16)(uint32_t a, uint32_t b)
1293 {
1294     uint64_t tmp;
1295     uint64_t result;
1296     DO_ABD(result, a, b, uint8_t);
1297     DO_ABD(tmp, a >> 8, b >> 8, uint8_t);
1298     result |= tmp << 16;
1299     DO_ABD(tmp, a >> 16, b >> 16, uint8_t);
1300     result |= tmp << 32;
1301     DO_ABD(tmp, a >> 24, b >> 24, uint8_t);
1302     result |= tmp << 48;
1303     return result;
1304 }
1305 
HELPER(neon_abdl_s16)1306 uint64_t HELPER(neon_abdl_s16)(uint32_t a, uint32_t b)
1307 {
1308     uint64_t tmp;
1309     uint64_t result;
1310     DO_ABD(result, a, b, int8_t);
1311     DO_ABD(tmp, a >> 8, b >> 8, int8_t);
1312     result |= tmp << 16;
1313     DO_ABD(tmp, a >> 16, b >> 16, int8_t);
1314     result |= tmp << 32;
1315     DO_ABD(tmp, a >> 24, b >> 24, int8_t);
1316     result |= tmp << 48;
1317     return result;
1318 }
1319 
HELPER(neon_abdl_u32)1320 uint64_t HELPER(neon_abdl_u32)(uint32_t a, uint32_t b)
1321 {
1322     uint64_t tmp;
1323     uint64_t result;
1324     DO_ABD(result, a, b, uint16_t);
1325     DO_ABD(tmp, a >> 16, b >> 16, uint16_t);
1326     return result | (tmp << 32);
1327 }
1328 
HELPER(neon_abdl_s32)1329 uint64_t HELPER(neon_abdl_s32)(uint32_t a, uint32_t b)
1330 {
1331     uint64_t tmp;
1332     uint64_t result;
1333     DO_ABD(result, a, b, int16_t);
1334     DO_ABD(tmp, a >> 16, b >> 16, int16_t);
1335     return result | (tmp << 32);
1336 }
1337 
HELPER(neon_abdl_u64)1338 uint64_t HELPER(neon_abdl_u64)(uint32_t a, uint32_t b)
1339 {
1340     uint64_t result;
1341     DO_ABD(result, a, b, uint32_t);
1342     return result;
1343 }
1344 
HELPER(neon_abdl_s64)1345 uint64_t HELPER(neon_abdl_s64)(uint32_t a, uint32_t b)
1346 {
1347     uint64_t result;
1348     DO_ABD(result, a, b, int32_t);
1349     return result;
1350 }
1351 #undef DO_ABD
1352 
1353 /* Widening multiply. Named type is the source type.  */
1354 #define DO_MULL(dest, x, y, type1, type2) do { \
1355     type1 tmp_x = x; \
1356     type1 tmp_y = y; \
1357     dest = (type2)((type2)tmp_x * (type2)tmp_y); \
1358     } while(0)
1359 
HELPER(neon_mull_u8)1360 uint64_t HELPER(neon_mull_u8)(uint32_t a, uint32_t b)
1361 {
1362     uint64_t tmp;
1363     uint64_t result;
1364 
1365     DO_MULL(result, a, b, uint8_t, uint16_t);
1366     DO_MULL(tmp, a >> 8, b >> 8, uint8_t, uint16_t);
1367     result |= tmp << 16;
1368     DO_MULL(tmp, a >> 16, b >> 16, uint8_t, uint16_t);
1369     result |= tmp << 32;
1370     DO_MULL(tmp, a >> 24, b >> 24, uint8_t, uint16_t);
1371     result |= tmp << 48;
1372     return result;
1373 }
1374 
HELPER(neon_mull_s8)1375 uint64_t HELPER(neon_mull_s8)(uint32_t a, uint32_t b)
1376 {
1377     uint64_t tmp;
1378     uint64_t result;
1379 
1380     DO_MULL(result, a, b, int8_t, uint16_t);
1381     DO_MULL(tmp, a >> 8, b >> 8, int8_t, uint16_t);
1382     result |= tmp << 16;
1383     DO_MULL(tmp, a >> 16, b >> 16, int8_t, uint16_t);
1384     result |= tmp << 32;
1385     DO_MULL(tmp, a >> 24, b >> 24, int8_t, uint16_t);
1386     result |= tmp << 48;
1387     return result;
1388 }
1389 
HELPER(neon_mull_u16)1390 uint64_t HELPER(neon_mull_u16)(uint32_t a, uint32_t b)
1391 {
1392     uint64_t tmp;
1393     uint64_t result;
1394 
1395     DO_MULL(result, a, b, uint16_t, uint32_t);
1396     DO_MULL(tmp, a >> 16, b >> 16, uint16_t, uint32_t);
1397     return result | (tmp << 32);
1398 }
1399 
HELPER(neon_mull_s16)1400 uint64_t HELPER(neon_mull_s16)(uint32_t a, uint32_t b)
1401 {
1402     uint64_t tmp;
1403     uint64_t result;
1404 
1405     DO_MULL(result, a, b, int16_t, uint32_t);
1406     DO_MULL(tmp, a >> 16, b >> 16, int16_t, uint32_t);
1407     return result | (tmp << 32);
1408 }
1409 
HELPER(neon_negl_u16)1410 uint64_t HELPER(neon_negl_u16)(uint64_t x)
1411 {
1412     uint16_t tmp;
1413     uint64_t result;
1414     result = (uint16_t)-x;
1415     tmp = -(x >> 16);
1416     result |= (uint64_t)tmp << 16;
1417     tmp = -(x >> 32);
1418     result |= (uint64_t)tmp << 32;
1419     tmp = -(x >> 48);
1420     result |= (uint64_t)tmp << 48;
1421     return result;
1422 }
1423 
1424 #include <stdio.h>
HELPER(neon_negl_u32)1425 uint64_t HELPER(neon_negl_u32)(uint64_t x)
1426 {
1427     uint32_t low = -x;
1428     uint32_t high = -(x >> 32);
1429     return low | ((uint64_t)high << 32);
1430 }
1431 
1432 /* FIXME:  There should be a native op for this.  */
HELPER(neon_negl_u64)1433 uint64_t HELPER(neon_negl_u64)(uint64_t x)
1434 {
1435     return -x;
1436 }
1437 
1438 /* Saturnating sign manuipulation.  */
1439 /* ??? Make these use NEON_VOP1 */
1440 #define DO_QABS8(x) do { \
1441     if (x == (int8_t)0x80) { \
1442         x = 0x7f; \
1443         SET_QC(); \
1444     } else if (x < 0) { \
1445         x = -x; \
1446     }} while (0)
HELPER(neon_qabs_s8)1447 uint32_t HELPER(neon_qabs_s8)(CPUState *env, uint32_t x)
1448 {
1449     neon_s8 vec;
1450     NEON_UNPACK(neon_s8, vec, x);
1451     DO_QABS8(vec.v1);
1452     DO_QABS8(vec.v2);
1453     DO_QABS8(vec.v3);
1454     DO_QABS8(vec.v4);
1455     NEON_PACK(neon_s8, x, vec);
1456     return x;
1457 }
1458 #undef DO_QABS8
1459 
1460 #define DO_QNEG8(x) do { \
1461     if (x == (int8_t)0x80) { \
1462         x = 0x7f; \
1463         SET_QC(); \
1464     } else { \
1465         x = -x; \
1466     }} while (0)
HELPER(neon_qneg_s8)1467 uint32_t HELPER(neon_qneg_s8)(CPUState *env, uint32_t x)
1468 {
1469     neon_s8 vec;
1470     NEON_UNPACK(neon_s8, vec, x);
1471     DO_QNEG8(vec.v1);
1472     DO_QNEG8(vec.v2);
1473     DO_QNEG8(vec.v3);
1474     DO_QNEG8(vec.v4);
1475     NEON_PACK(neon_s8, x, vec);
1476     return x;
1477 }
1478 #undef DO_QNEG8
1479 
1480 #define DO_QABS16(x) do { \
1481     if (x == (int16_t)0x8000) { \
1482         x = 0x7fff; \
1483         SET_QC(); \
1484     } else if (x < 0) { \
1485         x = -x; \
1486     }} while (0)
HELPER(neon_qabs_s16)1487 uint32_t HELPER(neon_qabs_s16)(CPUState *env, uint32_t x)
1488 {
1489     neon_s16 vec;
1490     NEON_UNPACK(neon_s16, vec, x);
1491     DO_QABS16(vec.v1);
1492     DO_QABS16(vec.v2);
1493     NEON_PACK(neon_s16, x, vec);
1494     return x;
1495 }
1496 #undef DO_QABS16
1497 
1498 #define DO_QNEG16(x) do { \
1499     if (x == (int16_t)0x8000) { \
1500         x = 0x7fff; \
1501         SET_QC(); \
1502     } else { \
1503         x = -x; \
1504     }} while (0)
HELPER(neon_qneg_s16)1505 uint32_t HELPER(neon_qneg_s16)(CPUState *env, uint32_t x)
1506 {
1507     neon_s16 vec;
1508     NEON_UNPACK(neon_s16, vec, x);
1509     DO_QNEG16(vec.v1);
1510     DO_QNEG16(vec.v2);
1511     NEON_PACK(neon_s16, x, vec);
1512     return x;
1513 }
1514 #undef DO_QNEG16
1515 
HELPER(neon_qabs_s32)1516 uint32_t HELPER(neon_qabs_s32)(CPUState *env, uint32_t x)
1517 {
1518     if (x == SIGNBIT) {
1519         SET_QC();
1520         x = ~SIGNBIT;
1521     } else if ((int32_t)x < 0) {
1522         x = -x;
1523     }
1524     return x;
1525 }
1526 
HELPER(neon_qneg_s32)1527 uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x)
1528 {
1529     if (x == SIGNBIT) {
1530         SET_QC();
1531         x = ~SIGNBIT;
1532     } else {
1533         x = -x;
1534     }
1535     return x;
1536 }
1537 
1538 /* NEON Float helpers.  */
HELPER(neon_min_f32)1539 uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b)
1540 {
1541     float32 f0 = vfp_itos(a);
1542     float32 f1 = vfp_itos(b);
1543     return (float32_compare_quiet(f0, f1, NFS) == -1) ? a : b;
1544 }
1545 
HELPER(neon_max_f32)1546 uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b)
1547 {
1548     float32 f0 = vfp_itos(a);
1549     float32 f1 = vfp_itos(b);
1550     return (float32_compare_quiet(f0, f1, NFS) == 1) ? a : b;
1551 }
1552 
HELPER(neon_abd_f32)1553 uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b)
1554 {
1555     float32 f0 = vfp_itos(a);
1556     float32 f1 = vfp_itos(b);
1557     return vfp_stoi((float32_compare_quiet(f0, f1, NFS) == 1)
1558                     ? float32_sub(f0, f1, NFS)
1559                     : float32_sub(f1, f0, NFS));
1560 }
1561 
HELPER(neon_add_f32)1562 uint32_t HELPER(neon_add_f32)(uint32_t a, uint32_t b)
1563 {
1564     return vfp_stoi(float32_add(vfp_itos(a), vfp_itos(b), NFS));
1565 }
1566 
HELPER(neon_sub_f32)1567 uint32_t HELPER(neon_sub_f32)(uint32_t a, uint32_t b)
1568 {
1569     return vfp_stoi(float32_sub(vfp_itos(a), vfp_itos(b), NFS));
1570 }
1571 
HELPER(neon_mul_f32)1572 uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b)
1573 {
1574     return vfp_stoi(float32_mul(vfp_itos(a), vfp_itos(b), NFS));
1575 }
1576 
1577 /* Floating point comparisons produce an integer result.  */
1578 #define NEON_VOP_FCMP(name, cmp) \
1579 uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \
1580 { \
1581     if (float32_compare_quiet(vfp_itos(a), vfp_itos(b), NFS) cmp 0) \
1582         return ~0; \
1583     else \
1584         return 0; \
1585 }
1586 
1587 NEON_VOP_FCMP(ceq_f32, ==)
1588 NEON_VOP_FCMP(cge_f32, >=)
1589 NEON_VOP_FCMP(cgt_f32, >)
1590 
1591 uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b)
1592 {
1593     float32 f0 = float32_abs(vfp_itos(a));
1594     float32 f1 = float32_abs(vfp_itos(b));
1595     return (float32_compare_quiet(f0, f1,NFS) >= 0) ? ~0 : 0;
1596 }
1597 
HELPER(neon_acgt_f32)1598 uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b)
1599 {
1600     float32 f0 = float32_abs(vfp_itos(a));
1601     float32 f1 = float32_abs(vfp_itos(b));
1602     return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0;
1603 }
1604