New Advanced SIMD intrinsics tests.
[platform/upstream/gcc49.git] / gcc / testsuite / gcc.target / aarch64 / advsimd-intrinsics / README
1 This directory contains executable tests for ARM/AArch64 Advanced SIMD
2 (Neon) intrinsics.
3
4 It is meant to cover execution cases of all the Advanced SIMD
5 intrinsics, but does not scan the generated assembler code.
6
7 The general framework is composed as follows:
8 - advsimd-intrinsics.exp: main dejagnu driver
9 - *.c: actual tests, generally one per intrinsinc family
10 - arm-neon-ref.h: contains macro definitions to save typing in actual
11   test files
12 - compute-ref-data.h: contains input vectors definitions
13 - *.inc: generic tests, shared by several families of intrinsics. For
14    instance, unary or binary operators
15
16 A typical .c test file starts with the following contents (look at
17 vld1.c and vaba.c for sample cases):
18 #include <arm_neon.h>
19 #include "arm-neon-ref.h"
20 #include "compute-ref-data.h"
21
22 Then, definitions of expected results, based on common input values,
23 as defined in compute-ref-data.h.
24 For example:
25 VECT_VAR_DECL(expected,int,16,4) [] = { 0x16, 0x17, 0x18, 0x19 };
26 defines the expected results of an operator generating int16x4 values.
27
28 The common input values defined in compute-ref-data.h have been chosen
29 to avoid corner-case values for most operators, yet exposing negative
30 values for signed operators. For this reason, their range is also
31 limited. For instance, the initialization of buffer_int16x4 will be
32 { -16, -15, -14, -13 }.
33
34 The initialization of floating-point values is done via hex notation,
35 to avoid potential rounding problems.
36
37 To test special values and corner cases, specific initialization
38 values should be used in dedicated tests, to ensure proper coverage.
39 An example of this is vshl.
40
41 When a variant of an intrinsic is not available, its expected result
42 should be defined to the value of CLEAN_PATTERN_8 as defined in
43 arm-neon-ref.h. For example:
44 VECT_VAR_DECL(expected,int,64,1) [] = { 0x3333333333333333 };
45 if the given intrinsic has no variant producing an int64x1 result,
46 like the vcmp family (eg. vclt).
47
48 This is because the helper function (check_results(), defined in
49 arm-neon-ref.h), iterates over all the possible variants, to save
50 typing in each individual test file. Alternatively, one can directly
51 call the CHECK/CHECK_FP macros to check only a few expected results
52 (see vabs.c for an example).
53
54 Then, define the TEST_MSG string, which will be used when reporting errors.
55
56 Next, define the function performing the actual tests, in general
57 relying on the helpers provided by arm-neon-ref.h, which means:
58
59 * declare necessary vectors of suitable types: using
60   DECL_VARIABLE_ALL_VARIANTS when all variants are supported, or the
61   relevant of subset calls to DECL_VARIABLE.
62
63 * call clean_results() to initialize the 'results' buffers.
64
65 * initialize the input vectors, using VLOAD, VDUP or VSET_LANE (vld*
66   tests do not need this step, since their actual purpose is to
67   initialize vectors).
68
69 * execute the intrinsic on relevant variants, for instance using
70   TEST_MACRO_ALL_VARIANTS_2_5.
71
72 * call check_results() to check that the results match the expected
73   values.
74
75 A template test file could be:
76 =================================================================
77 #include <arm_neon.h>
78 #include "arm-neon-ref.h"
79 #include "compute-ref-data.h"
80
81 /* Expected results.  */
82 VECT_VAR_DECL(expected,int,8,8) [] = { 0xf6, 0xf7, 0xf8, 0xf9,
83                                        0xfa, 0xfb, 0xfc, 0xfd };
84 /* and as many others as necessary.  */
85
86 #define TEST_MSG "VMYINTRINSIC"
87 void exec_myintrinsic (void)
88 {
89   /* my test: v4=vmyintrinsic(v1,v2,v3), then store the result.  */
90 #define TEST_VMYINTR(Q, T1, T2, W, N)                                   \
91   VECT_VAR(vector_res, T1, W, N) =                                      \
92     vmyintr##Q##_##T2##W(VECT_VAR(vector1, T1, W, N),                   \
93                          VECT_VAR(vector2, T1, W, N),                   \
94                          VECT_VAR(vector3, T1, W, N));                  \
95   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vector_res, T1, W, N))
96
97 #define DECL_VMYINTR_VAR(VAR)                   \
98   DECL_VARIABLE(VAR, int, 8, 8);
99 /* And as many others as necessary.  */
100
101   DECL_VMYINTR_VAR(vector1);
102   DECL_VMYINTR_VAR(vector2);
103   DECL_VMYINTR_VAR(vector3);
104   DECL_VMYINTR_VAR(vector_res);
105
106   clean_results ();
107
108   /* Initialize input "vector1" from "buffer".  */
109   VLOAD(vector1, buffer, , int, s, 8, 8);
110 /* And as many others as necessary.  */
111
112   /* Choose init value arbitrarily.  */
113   VDUP(vector2, , int, s, 8, 8, 1);
114 /* And as many others as necessary.  */
115
116   /* Choose init value arbitrarily.  */
117   VDUP(vector3, , int, s, 8, 8, -5);
118 /* And as many others as necessary.  */
119
120   /* Execute the tests.  */
121   TEST_VMYINTR(, int, s, 8, 8);
122 /* And as many others as necessary.  */
123
124   check_results (TEST_MSG, "");
125 }
126
127 int main (void)
128 {
129   exec_vmyintrinsic ();
130   return 0;
131 }
132 =================================================================