| /* { dg-do run } */ |
| /* { dg-options "-O3 --save-temps" } */ |
| |
| #include <arm_neon.h> |
| |
| extern void abort (void); |
| |
| #define MAPs(size, xx) int##size##xx##_t |
| #define MAPu(size, xx) uint##size##xx##_t |
| |
| |
| #define TEST_VMLA(q, su, size, in1_lanes, in2_lanes) \ |
| static void \ |
| test_vmlaq_lane##q##_##su##size (MAP##su (size, ) * res, \ |
| const MAP##su(size, ) *in1, \ |
| const MAP##su(size, ) *in2) \ |
| { \ |
| MAP##su (size, x##in1_lanes) a = vld1q_##su##size (res); \ |
| MAP##su (size, x##in1_lanes) b = vld1q_##su##size (in1); \ |
| MAP##su (size, x##in2_lanes) c = vld1##q##_##su##size (in2); \ |
| a = vmlaq_lane##q##_##su##size (a, b, c, 1); \ |
| vst1q_##su##size (res, a); \ |
| } |
| |
| #define BUILD_VARS(width, n_lanes, n_half_lanes) \ |
| TEST_VMLA (, s, width, n_lanes, n_half_lanes) \ |
| TEST_VMLA (q, s, width, n_lanes, n_lanes) \ |
| TEST_VMLA (, u, width, n_lanes, n_half_lanes) \ |
| TEST_VMLA (q, u, width, n_lanes, n_lanes) \ |
| |
| BUILD_VARS (32, 4, 2) |
| BUILD_VARS (16, 8, 4) |
| |
| #define POOL4 {0, 1, 2, 3} |
| #define POOL8 {0, 1, 2, 3, 4, 5, 6, 7} |
| #define EMPTY4 {0, 0, 0, 0} |
| #define EMPTY8 {0, 0, 0, 0, 0, 0, 0, 0} |
| |
| #define BUILD_TEST(su, size, lanes) \ |
| static void \ |
| test_##su##size (void) \ |
| { \ |
| int i; \ |
| MAP##su (size,) pool[lanes] = POOL##lanes; \ |
| MAP##su (size,) res[lanes] = EMPTY##lanes; \ |
| MAP##su (size,) res2[lanes] = EMPTY##lanes; \ |
| \ |
| /* Forecfully avoid optimization. */ \ |
| asm volatile ("" : : : "memory"); \ |
| test_vmlaq_lane_##su##size (res, pool, pool); \ |
| for (i = 0; i < lanes; i++) \ |
| if (res[i] != pool[i]) \ |
| abort (); \ |
| \ |
| /* Forecfully avoid optimization. */ \ |
| asm volatile ("" : : : "memory"); \ |
| test_vmlaq_laneq_##su##size (res2, pool, pool); \ |
| for (i = 0; i < lanes; i++) \ |
| if (res2[i] != pool[i]) \ |
| abort (); \ |
| } |
| |
| #undef BUILD_VARS |
| #define BUILD_VARS(size, lanes) \ |
| BUILD_TEST (s, size, lanes) \ |
| BUILD_TEST (u, size, lanes) |
| |
| BUILD_VARS (32, 4) |
| BUILD_VARS (16, 8) |
| |
| int |
| main (int argc, char **argv) |
| { |
| test_s32 (); |
| test_u32 (); |
| test_s16 (); |
| test_u16 (); |
| return 0; |
| } |
| |
| /* { dg-final { scan-assembler-times "mla\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s\\\[\[0-9\]+\\\]" 4 } } */ |
| /* { dg-final { scan-assembler-times "mla\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h\\\[\[0-9\]+\\\]" 4 } } */ |
| |