1/* { dg-do run } */ 2/* { dg-options "-O2 -msse2" } */ 3/* { dg-require-effective-target sse2 } */ 4 5#include "sse2-check.h" 6 7#include <mmintrin.h> 8 9#define N 4 10 11unsigned long long a[N], b[N], result[N]; 12 13unsigned long long check[N] = 14 { 0x101010101010100full, 15 0x1010101010101010ull, 16 0x1010101010101010ull, 17 0x1010101010101010ull }; 18 19__m64 20unsigned_add3 (const __m64 * a, const __m64 * b, 21 __m64 * result, unsigned int count) 22{ 23 __m64 _a, _b, one, sum, carry, onesCarry; 24 25 unsigned int i; 26 27 carry = _mm_setzero_si64 (); 28 29 one = _mm_cmpeq_pi8 (carry, carry); 30 one = _mm_sub_si64 (carry, one); 31 32 for (i = 0; i < count; i++) 33 { 34 _a = a[i]; 35 _b = b[i]; 36 37 sum = _mm_add_si64 (_a, _b); 38 sum = _mm_add_si64 (sum, carry); 39 40 result[i] = sum; 41 42 onesCarry = _mm_and_si64 (_mm_xor_si64 (_a, _b), carry); 43 onesCarry = _mm_or_si64 (_mm_and_si64 (_a, _b), onesCarry); 44 onesCarry = _mm_and_si64 (onesCarry, one); 45 46 _a = _mm_srli_si64 (_a, 1); 47 _b = _mm_srli_si64 (_b, 1); 48 49 carry = _mm_add_si64 (_mm_add_si64 (_a, _b), onesCarry); 50 carry = _mm_srli_si64 (carry, 63); 51 } 52 53 return carry; 54} 55 56void __attribute__((noinline)) 57sse2_test (void) 58{ 59 unsigned long long carry; 60 int i; 61 62 /* Really long numbers. */ 63 a[3] = a[2] = a[1] = a[0] = 0xd3d3d3d3d3d3d3d3ull; 64 b[3] = b[2] = b[1] = b[0] = 0x3c3c3c3c3c3c3c3cull; 65 66 carry = (unsigned long long) unsigned_add3 67 ((__m64 *)a, (__m64 *)b, (__m64 *)result, N); 68 69 _mm_empty (); 70 71 if (carry != 1) 72 abort (); 73 74 for (i = 0; i < N; i++) 75 if (result [i] != check[i]) 76 abort (); 77} 78