| #include <stdlib.h> |
| #include <stddef.h> |
| #include <altivec.h> |
| |
| #ifndef RTYPE |
| #define RTYPE TYPE |
| #endif |
| |
| #ifdef DO_TRACE |
| #include <stdio.h> |
| |
| #define TRACE(STRING, NUM) \ |
| do \ |
| { \ |
| fprintf (stderr, "%s: %2d\n", STRING, (int) NUM); \ |
| fflush (stderr); \ |
| } \ |
| while (0) |
| |
| #ifndef FAIL_FORMAT |
| #define FAIL_FORMAT "%ld" |
| #define FAIL_CAST(X) ((long)(X)) |
| #endif |
| |
| #define FAIL(EXP, GOT) \ |
| do \ |
| { \ |
| fprintf (stderr, "Expected: " FAIL_FORMAT ", got " FAIL_FORMAT "\n", \ |
| FAIL_CAST (EXP), FAIL_CAST (GOT)); \ |
| fflush (stderr); \ |
| abort (); \ |
| } \ |
| while (0) |
| |
| #else |
| #define TRACE(STRING, NUM) |
| #define FAIL(EXP, GOT) abort () |
| #endif |
| |
| static void |
| check (RTYPE, RTYPE) __attribute__((__noinline__)); |
| |
| static vector TYPE |
| deoptimize (vector TYPE) __attribute__((__noinline__)); |
| |
| static vector TYPE |
| *deoptimize_ptr (vector TYPE *) __attribute__((__noinline__)); |
| |
| static void |
| check (RTYPE expected, RTYPE got) |
| { |
| if (expected != got) |
| FAIL (expected, got); |
| } |
| |
| static vector TYPE |
| deoptimize (vector TYPE a) |
| { |
| __asm__ (" # %x0" : "+v" (a)); |
| return a; |
| } |
| |
| static vector TYPE * |
| deoptimize_ptr (vector TYPE *p) |
| { |
| __asm__ (" # %0" : "+r" (p)); |
| return p; |
| } |
| |
| |
| RTYPE |
| get_auto_0 (vector TYPE a) |
| { |
| TRACE ("get_auto_", 0); |
| return (RTYPE) vec_extract (a, 0); |
| } |
| |
| RTYPE |
| get_auto_1 (vector TYPE a) |
| { |
| TRACE ("get_auto_", 1); |
| return (RTYPE) vec_extract (a, 1); |
| } |
| |
| #if ELEMENTS >= 4 |
| RTYPE |
| get_auto_2 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 2); |
| } |
| |
| RTYPE |
| get_auto_3 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 3); |
| } |
| |
| #if ELEMENTS >= 8 |
| RTYPE |
| get_auto_4 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 4); |
| } |
| |
| RTYPE |
| get_auto_5 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 5); |
| } |
| |
| RTYPE |
| get_auto_6 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 6); |
| } |
| |
| RTYPE |
| get_auto_7 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 7); |
| } |
| |
| #if ELEMENTS >= 16 |
| RTYPE |
| get_auto_8 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 8); |
| } |
| |
| RTYPE |
| get_auto_9 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 9); |
| } |
| |
| RTYPE |
| get_auto_10 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 10); |
| } |
| |
| RTYPE |
| get_auto_11 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 11); |
| } |
| |
| RTYPE |
| get_auto_12 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 12); |
| } |
| |
| RTYPE |
| get_auto_13 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 13); |
| } |
| |
| RTYPE |
| get_auto_14 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 14); |
| } |
| |
| RTYPE |
| get_auto_15 (vector TYPE a) |
| { |
| return (RTYPE) vec_extract (a, 15); |
| } |
| |
| #endif |
| #endif |
| #endif |
| |
| |
| /* Tests for the normal case of vec_extract where the vector is in a register |
| and returning the result in a register as a return value. */ |
| #ifdef DISABLE_INLINE_OF_GET_AUTO_N |
| __attribute__ ((__noinline__)) |
| #else |
| /* gcc issues warning: always_inline function might not be inlinable |
| |
| __attribute__ ((__always_inline__)) |
| */ |
| #endif |
| RTYPE |
| get_auto_n (vector TYPE a, ssize_t n) |
| { |
| return (RTYPE) vec_extract (a, n); |
| } |
| |
| typedef RTYPE (*auto_func_type) (vector TYPE); |
| |
| static auto_func_type get_auto_const[] = { |
| get_auto_0, |
| get_auto_1, |
| #if ELEMENTS >= 4 |
| get_auto_2, |
| get_auto_3, |
| #if ELEMENTS >= 8 |
| get_auto_4, |
| get_auto_5, |
| get_auto_6, |
| get_auto_7, |
| #if ELEMENTS >= 16 |
| get_auto_8, |
| get_auto_9, |
| get_auto_10, |
| get_auto_11, |
| get_auto_12, |
| get_auto_13, |
| get_auto_14, |
| get_auto_15, |
| #endif |
| #endif |
| #endif |
| }; |
| |
| extern void do_auto (vector TYPE a) __attribute__((__noinline__)); |
| |
| void |
| do_auto (vector TYPE a) |
| { |
| size_t i; |
| |
| for (i = 1; i < 40; i += 3) |
| { |
| TRACE ("do_auto, i: ", i); |
| TRACE (" get_auto_const[i] returns: ", |
| (*get_auto_const [i % ELEMENTS]) (a)); |
| TRACE (" get_auto_n returns", get_auto_n (a, i)); |
| check (get_auto_n (a, i), (*get_auto_const [i % ELEMENTS]) (a)); |
| } |
| } |
| |
| |
| |
| /* Main program to test all of the possibilities. */ |
| int |
| main (void) |
| { |
| size_t i; |
| vector TYPE x = INITIAL; |
| vector TYPE *p, *p2, a, y; |
| vector TYPE z[2]; |
| |
| a = deoptimize (x); |
| |
| do_auto (a); |
| |
| return 0; |
| } |