| /* { 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)) |
| vector unsigned __int128 |
| set_auto_n_uint128 (vector unsigned __int128 a, int n, unsigned __int128 x) |
| { |
| return vec_insert (x, a, n); |
| } |
| |
| __attribute ((noinline)) |
| vector unsigned long long int |
| set_auto_n_ulong (vector unsigned long long int a, int n, |
| unsigned long long int x) |
| { |
| return vec_insert (x, a, n); |
| } |
| |
| __attribute ((noinline)) |
| vector unsigned int |
| set_auto_n_uint (vector unsigned int a, int n, unsigned int x) |
| { |
| return vec_insert (x, a, n); |
| } |
| |
| __attribute ((noinline)) |
| vector unsigned char |
| set_auto_n_uchar (vector unsigned char a, int n, unsigned char x) |
| { |
| return vec_insert (x, a, n); |
| } |
| |
| __attribute ((noinline)) |
| vector unsigned short |
| set_auto_n_ushort (vector unsigned short a, int n, unsigned short x) |
| { |
| return vec_insert (x, a, n); |
| } |
| |
| __attribute ((noinline)) |
| unsigned __int128 |
| get_auto_n_uint128 (vector unsigned __int128 a, int n) |
| { |
| return vec_extract (a, n); |
| } |
| |
| __attribute ((noinline)) |
| unsigned long long int |
| get_auto_n_ulong (vector unsigned long long int a, int n) |
| { |
| return vec_extract (a, n); |
| } |
| |
| __attribute ((noinline)) |
| unsigned int |
| get_auto_n_uint (vector unsigned int a, int n) |
| { |
| return vec_extract (a, n); |
| } |
| |
| __attribute ((noinline)) |
| unsigned char |
| get_auto_n_uchar (vector unsigned char a, int n) |
| { |
| return vec_extract (a, n); |
| } |
| |
| __attribute ((noinline)) |
| unsigned short |
| get_auto_n_ushort (vector unsigned short a, int n) |
| { |
| return 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)); |
| } |
| |
| unsigned __int128 get_uint128_element (int i) |
| { |
| return ((((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; |
| } |
| } |
| |
| unsigned long long int get_ulong_element (int i) |
| { |
| switch (i % 2) |
| { |
| case 0: return 0x9999901010ULL; |
| case 1: return 0x7777733333ULL; |
| } |
| } |
| |
| 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; |
| } |
| } |
| |
| unsigned int get_uint_element (int i) |
| { |
| switch (i % 4) |
| { |
| case 0: return 0x99999; |
| case 1: return 0x01010; |
| case 2: return 0x77777; |
| case 3: return 0x33333; |
| } |
| } |
| |
| 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; |
| } |
| } |
| |
| unsigned char get_uchar_element (int i) |
| { |
| switch (i % 16) |
| { |
| case 0: return 0x90; |
| case 1: return 0x80; |
| case 2: return 0x70; |
| case 3: return 0x60; |
| case 4: return 0x50; |
| case 5: return 0x40; |
| case 6: return 0x30; |
| case 7: return 0x20; |
| case 8: return 0x10; |
| case 9: return 0xf0; |
| case 10: return 0xe0; |
| case 11: return 0xd0; |
| case 12: return 0xc0; |
| case 13: return 0xb0; |
| case 14: return 0xa0; |
| case 15: return 0xff; |
| } |
| } |
| |
| 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; |
| } |
| } |
| |
| unsigned short get_ushort_element (int i) |
| { |
| switch (i % 8) |
| { |
| case 0: return 0x9988; |
| case 1: return 0x8877; |
| case 2: return 0x7766; |
| case 3: return 0x6655; |
| case 4: return 0x5544; |
| case 5: return 0x4433; |
| case 6: return 0x3322; |
| case 7: return 0x2211; |
| } |
| } |
| |
| vector unsigned __int128 |
| init_auto_uint128 (vector unsigned __int128 a) |
| { |
| int i; |
| for (i = 0; i < 32; i += 3) |
| a = set_auto_n_uint128 (a, i, get_uint128_element (i)); |
| return a; |
| } |
| |
| 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 (); |
| } |
| } |
| |
| vector unsigned long long int |
| init_auto_ulong (vector unsigned long long int a) |
| { |
| int i; |
| for (i = 0; i < 32; i += 3) |
| a = set_auto_n_ulong (a, i, get_ulong_element (i)); |
| return a; |
| } |
| |
| 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 (); |
| } |
| } |
| |
| vector unsigned int init_auto_uint (vector unsigned int a) |
| { |
| int i; |
| for (i = 0; i < 32; i += 3) |
| a = set_auto_n_uint (a, i, get_uint_element (i)); |
| return a; |
| } |
| |
| 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 (); |
| } |
| } |
| |
| vector unsigned short init_auto_ushort ( vector unsigned short a ) |
| { |
| int i; |
| for (i = 0; i < 32; i += 3) |
| a = set_auto_n_ushort (a, i, get_ushort_element (i)); |
| return a; |
| } |
| |
| 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 (); |
| } |
| } |
| |
| vector unsigned char init_auto_uchar (vector unsigned char a) |
| { |
| int i; |
| for (i = 0; i < 32; i += 3) |
| a = set_auto_n_uchar (a, i, get_uchar_element (i)); |
| return a; |
| } |
| |
| 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 = { 0 }; |
| vector unsigned __int128 du; |
| |
| vector unsigned long long int v = { 0, 0 }; |
| vector unsigned long long int dv; |
| |
| vector unsigned int x = { 0, 0, 0, 0 }; |
| vector unsigned int dx; |
| |
| vector unsigned char y = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
| vector unsigned char dy; |
| |
| vector unsigned short z = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| vector unsigned short dz; |
| |
| du = init_auto_uint128 (u); |
| dv = init_auto_ulong (v); |
| dx = init_auto_uint (x); |
| dy = init_auto_uchar (y); |
| dz = init_auto_ushort (z); |
| |
| du = deoptimize_uint128 (du); |
| dv = deoptimize_ulong (dv); |
| dx = deoptimize_uint (dx); |
| dy = deoptimize_uchar (dy); |
| dz = deoptimize_ushort (dz); |
| |
| do_auto_uint128 (du); |
| do_auto_ulong (dv); |
| do_auto_uint (dx); |
| do_auto_uchar (dy); |
| do_auto_ushort (dz); |
| return 0; |
| } |