Viewing file: p8vector-int128-2.c (4.31 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* { dg-do run } */ /* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target p8vector_hw } */ /* { dg-require-effective-target int128 } */ /* { dg-options "-mdejagnu-cpu=power8 -O2" } */
#include <stddef.h> #include <stdlib.h> #include <altivec.h>
#ifdef DEBUG #include <stdio.h> #define UNUSED
#ifdef __LITTLE_ENDIAN__ #define HI_WORD 1 #define LO_WORD 0 #else #define HI_WORD 0 #define LO_WORD 1 #endif
#else #define UNUSED __attribute__((__unused__)) #endif
#ifndef S_TYPE #define S_TYPE __uint128_t #endif
#ifndef V_TYPE #define V_TYPE vector S_TYPE #endif
static int compare (S_TYPE, V_TYPE, const char *, const char *) __attribute__((__noinline__));
static int compare (S_TYPE scalar, V_TYPE vect, const char *nl UNUSED, const char *which UNUSED) { unsigned long scalar_lo = (unsigned long) scalar; unsigned long scalar_hi = (unsigned long) (scalar >> 64); unsigned long vect_lo; unsigned long vect_hi; vector long long tmp; int ret;
__asm__ ("mfvsrd %0,%x3\n\t" "xxpermdi %x2,%x3,%x3,3\n\t" "mfvsrd %1,%x2" : "=r" (vect_hi), "=r" (vect_lo), "=wa" (tmp) : "wa" (vect));
ret = (scalar_lo != vect_lo) || (scalar_hi != vect_hi);
#ifdef DEBUG printf ("%s%s: 0x%.16lx %.16lx %s 0x%.16lx %.16lx\n", nl, which, scalar_hi, scalar_lo, (ret) ? "!=" : "==", vect_hi, vect_lo);
fflush (stdout); #endif
return ret; }
static void convert_via_mem (V_TYPE *, S_TYPE *) __attribute__((__noinline__));
static void convert_via_mem (V_TYPE *v, S_TYPE *s) { *v = (V_TYPE) { *s }; __asm__ volatile ("nop" : "+m" (*s), "+m" (*v) : : "memory");
}
/* Check if vadduqm returns the same values as normal 128-bit add. */
/* Values to add together. */ const static struct { unsigned long hi_1; unsigned long lo_1; unsigned long hi_2; unsigned long lo_2; } values[] = { { 0x0000000000000000UL, 0xfffffffffffffffeUL, 0x0000000000000000UL, 0x0000000000000002UL }, { 0x0000000000000000UL, 0x0000000000000002UL, 0x0000000000000000UL, 0xfffffffffffffffeUL }, { 0xffffffffffffffffUL, 0xfffffffffffffffeUL, 0x0000000000000000UL, 0x0000000000000002UL }, { 0xfffffffffffffff2UL, 0xffffffffffffffffUL, 0x0000000000000002UL, 0x0000000000000000UL }, { 0x7fffffffffffffffUL, 0xfffffffffffffffeUL, 0x0000000000000000UL, 0x0000000000000002UL }, { 0x7ffffffffffffff2UL, 0xffffffffffffffffUL, 0x0000000000000002UL, 0x0000000000000000UL }, };
int main (void) { int reg_errors = 0; int mem_errors = 0; size_t i; const char *nl = "";
for (i = 0; i < sizeof (values) / sizeof (values[0]); i++) { S_TYPE s_reg_res, s_reg_in1, s_reg_in2, s_mem_res, s_mem_in1, s_mem_in2; V_TYPE v_reg_res, v_reg_in1, v_reg_in2, v_mem_res, v_mem_in1, v_mem_in2;
s_reg_in1 = ((((S_TYPE)values[i].hi_1 << 64)) + ((S_TYPE)values[i].lo_1)); reg_errors += compare (s_reg_in1, (V_TYPE) { s_reg_in1 }, nl, "reg, in1");
s_reg_in2 = ((((S_TYPE)values[i].hi_2 << 64)) + ((S_TYPE)values[i].lo_2)); reg_errors += compare (s_reg_in2, (V_TYPE) { s_reg_in2 }, "", "reg, in2");
s_reg_res = s_reg_in1 + s_reg_in2;
v_reg_in1 = (V_TYPE) { s_reg_in1 }; v_reg_in2 = (V_TYPE) { s_reg_in2 }; v_reg_res = vec_vadduqm (v_reg_in1, v_reg_in2); reg_errors += compare (s_reg_res, v_reg_res, "", "reg, res");
s_mem_in1 = s_reg_in1; convert_via_mem (&v_mem_in1, &s_mem_in1); mem_errors += compare (s_mem_in1, (V_TYPE) { s_mem_in1 }, "\n", "mem, in1");
s_mem_in2 = s_reg_in2; convert_via_mem (&v_mem_in2, &s_mem_in2); mem_errors += compare (s_mem_in2, (V_TYPE) { s_mem_in2 }, "", "mem, in2");
s_mem_res = s_mem_in1 + s_mem_in2; v_mem_res = vec_vadduqm (v_mem_in1, v_mem_in2); mem_errors += compare (s_mem_res, v_mem_res, "", "mem, res");
nl = "\n"; }
#ifdef DEBUG putchar ('\n');
if (!reg_errors) fputs ("no errors found on register operations\n", stdout); else printf ("%d error%s found on register operations\n", reg_errors, (reg_errors == 1) ? "s" : "");
if (!mem_errors) fputs ("no errors found on memory operations\n", stdout); else printf ("%d error%s found on memory operations\n", mem_errors, (mem_errors == 1) ? "s" : "");
fflush (stdout); #endif
if ((reg_errors + mem_errors) != 0) abort ();
return 0; }
|