blob: e5f79aa5dc1fe9b59f2bb9b3e2e4b34df5ade4dc [file] [log] [blame]
/* { dg-do run { target int128 } } */
/* { dg-require-effective-target vsx_hw } */
/* { dg-options "-mvsx -O2" } */
/* This test should run the same on any target that supports vsx
instructions. Intentionally not specifying cpu in order to test
all code generation paths. */
#include <stdlib.h>
#include <stddef.h>
#include <altivec.h>
#include <stdio.h>
static vector unsigned __int128
deoptimize_uint128 (vector unsigned __int128 a)
{
__asm__ (" # %x0" : "+v" (a));
return a;
}
static vector unsigned long long int
deoptimize_ulong (vector unsigned long long int a)
{
__asm__ (" # %x0" : "+v" (a));
return a;
}
static vector unsigned int
deoptimize_uint (vector unsigned int a)
{
__asm__ (" # %x0" : "+v" (a));
return a;
}
static vector unsigned char
deoptimize_uchar (vector unsigned char a)
{
__asm__ (" # %x0" : "+v" (a));
return a;
}
static vector unsigned short
deoptimize_ushort (vector unsigned short a)
{
__asm__ (" # %x0" : "+v" (a));
return a;
}
__attribute ((noinline)) unsigned __int128
get_auto_n_uint128 (vector unsigned __int128 a, int n)
{
return __builtin_vec_extract (a, n);
}
__attribute ((noinline)) unsigned long long int
get_auto_n_ulong (vector unsigned long long int a, int n)
{
return __builtin_vec_extract (a, n);
}
__attribute ((noinline))
unsigned int get_auto_n_uint (vector unsigned int a, int n)
{
return __builtin_vec_extract (a, n);
}
__attribute ((noinline))
unsigned char get_auto_n_uchar (vector unsigned char a, int n)
{
return __builtin_vec_extract (a, n);
}
__attribute ((noinline))
unsigned short get_auto_n_ushort (vector unsigned short a, int n)
{
return __builtin_vec_extract (a, n);
}
int check_uint128_element (int i, unsigned __int128 entry)
{
printf ("checking uint128 entry at index %d\n", i);
return (entry == ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
| 0x0706050403020100ULL));
}
int check_ulong_element (int i, unsigned long long int entry)
{
printf ("checking ulong entry 0x%llx at index %d\n", entry, i);
switch (i % 2)
{
case 0: return (entry == 0x9999901010ULL);
case 1: return (entry == 0x7777733333ULL);
default:
return 0;
}
}
int check_uint_element (int i, unsigned int entry)
{
printf ("checking uint entry 0x%x at index %d\n", entry, i);
switch (i % 4)
{
case 0: return (entry == 0x99999);
case 1: return (entry == 0x01010);
case 2: return (entry == 0x77777);
case 3: return (entry == 0x33333);
default:
return 0;
}
}
int check_uchar_element (int i, unsigned char entry)
{
printf ("checking uchar entry 0x%x at index %d\n", entry, i);
switch (i % 16)
{
case 0: return (entry == 0x90);
case 1: return (entry == 0x80);
case 2: return (entry == 0x70);
case 3: return (entry == 0x60);
case 4: return (entry == 0x50);
case 5: return (entry == 0x40);
case 6: return (entry == 0x30);
case 7: return (entry == 0x20);
case 8: return (entry == 0x10);
case 9: return (entry == 0xf0);
case 10: return (entry == 0xe0);
case 11: return (entry == 0xd0);
case 12: return (entry == 0xc0);
case 13: return (entry == 0xb0);
case 14: return (entry == 0xa0);
case 15: return (entry == 0xff);
default:
return 0;
}
}
int check_ushort_element (int i, unsigned short entry)
{
printf ("checking ushort entry 0x%x at index %d\n", entry, i);
switch (i % 8)
{
case 0: return (entry == 0x9988);
case 1: return (entry == 0x8877);
case 2: return (entry == 0x7766);
case 3: return (entry == 0x6655);
case 4: return (entry == 0x5544);
case 5: return (entry == 0x4433);
case 6: return (entry == 0x3322);
case 7: return (entry == 0x2211);
default:
return 0;
}
}
void do_auto_uint128 ( vector unsigned __int128 a )
{
int i;
unsigned __int128 c;
for (i = 0; i < 32; i += 3)
{
c = get_auto_n_uint128 (a,i);
if (!check_uint128_element (i, c)) abort ();
}
}
void do_auto_ulong ( vector unsigned long long int a )
{
int i;
unsigned long long int c;
for (i = 0; i < 32; i += 3)
{
c = get_auto_n_ulong (a,i);
if (!check_ulong_element (i, c)) abort ();
}
}
void do_auto_uint ( vector unsigned int a )
{
int i;
unsigned int c;
for (i = 0; i < 32; i += 3)
{
c = get_auto_n_uint (a,i);
if (!check_uint_element (i, c)) abort ();
}
}
void do_auto_ushort ( vector unsigned short a )
{
int i;
unsigned short c;
for (i = 0; i < 32; i += 3)
{
c = get_auto_n_ushort (a,i);
if (!check_ushort_element (i, c)) abort ();
}
}
void do_auto_uchar ( vector unsigned char a )
{
int i;
unsigned char c;
for (i = 0; i < 32; i += 3)
{
c = get_auto_n_uchar (a,i);
if (!check_uchar_element (i, c)) abort ();
}
}
int
main (void)
{
size_t i;
vector unsigned __int128 u = {
((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
| 0x0706050403020100ULL) };
vector unsigned __int128 du;
vector unsigned long long int v = { 0x9999901010ULL, 0x7777733333ULL };
vector unsigned long long int dv;
vector unsigned int x = { 0x99999, 0x01010, 0x77777, 0x33333 };
vector unsigned int dx;
vector unsigned char y = { 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20,
0x10, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0xff };
vector unsigned char dy;
vector unsigned short z = { 0x9988, 0x8877, 0x7766, 0x6655,
0x5544, 0x4433, 0x3322, 0x2211 };
vector unsigned short dz;
do_auto_uint128 (u);
do_auto_ulong (v);
do_auto_uint (x);
do_auto_uchar (y);
do_auto_ushort (z);
du = deoptimize_uint128 (u);
dv = deoptimize_ulong (v);
dx = deoptimize_uint (x);
dy = deoptimize_uchar (y);
dz = deoptimize_ushort (z);
do_auto_uint128 (du);
do_auto_ulong (dv);
do_auto_uint (dx);
do_auto_uchar (dy);
do_auto_ushort (dz);
return 0;
}