1#define FNNAME1(NAME) exec_ ## NAME ## _lane
2#define FNNAME(NAME) FNNAME1 (NAME)
3
4void FNNAME (INSN) (void)
5{
6  /* vector_res = vqrdmlXh_lane (vector, vector2, vector3, lane),
7     then store the result.  */
8#define TEST_VQRDMLXH_LANE2(INSN, Q, T1, T2, W, N, N2, L,		\
9			    EXPECTED_CUMULATIVE_SAT, CMT)		\
10  Set_Neon_Cumulative_Sat (0, VECT_VAR (vector_res, T1, W, N));		\
11  VECT_VAR (vector_res, T1, W, N) =					\
12    INSN##Q##_lane_##T2##W (VECT_VAR (vector, T1, W, N),		\
13			    VECT_VAR (vector2, T1, W, N),		\
14			    VECT_VAR (vector3, T1, W, N2),		\
15			    L);						\
16  vst1##Q##_##T2##W (VECT_VAR (result, T1, W, N),			\
17		     VECT_VAR (vector_res, T1, W, N));			\
18  CHECK_CUMULATIVE_SAT (TEST_MSG, T1, W, N, EXPECTED_CUMULATIVE_SAT, CMT)
19
20  /* Two auxliary macros are necessary to expand INSN.  */
21#define TEST_VQRDMLXH_LANE1(INSN, Q, T1, T2, W, N, N2, L,	\
22			    EXPECTED_CUMULATIVE_SAT, CMT)	\
23  TEST_VQRDMLXH_LANE2 (INSN, Q, T1, T2, W, N, N2, L,		\
24		       EXPECTED_CUMULATIVE_SAT, CMT)
25
26#define TEST_VQRDMLXH_LANE(Q, T1, T2, W, N, N2, L,		\
27			   EXPECTED_CUMULATIVE_SAT, CMT)	\
28  TEST_VQRDMLXH_LANE1 (INSN, Q, T1, T2, W, N, N2, L,		\
29		       EXPECTED_CUMULATIVE_SAT, CMT)
30
31
32  DECL_VARIABLE (vector, int, 16, 4);
33  DECL_VARIABLE (vector, int, 32, 2);
34  DECL_VARIABLE (vector, int, 16, 8);
35  DECL_VARIABLE (vector, int, 32, 4);
36
37  DECL_VARIABLE (vector_res, int, 16, 4);
38  DECL_VARIABLE (vector_res, int, 32, 2);
39  DECL_VARIABLE (vector_res, int, 16, 8);
40  DECL_VARIABLE (vector_res, int, 32, 4);
41
42  DECL_VARIABLE (vector2, int, 16, 4);
43  DECL_VARIABLE (vector2, int, 32, 2);
44  DECL_VARIABLE (vector2, int, 16, 8);
45  DECL_VARIABLE (vector2, int, 32, 4);
46
47  DECL_VARIABLE (vector3, int, 16, 4);
48  DECL_VARIABLE (vector3, int, 32, 2);
49  DECL_VARIABLE (vector3, int, 16, 8);
50  DECL_VARIABLE (vector3, int, 32, 4);
51
52  clean_results ();
53
54  VLOAD (vector, buffer, , int, s, 16, 4);
55  VLOAD (vector, buffer, , int, s, 32, 2);
56
57  VLOAD (vector, buffer, q, int, s, 16, 8);
58  VLOAD (vector, buffer, q, int, s, 32, 4);
59
60  /* Initialize vector2.  */
61  VDUP (vector2, , int, s, 16, 4, 0x5555);
62  VDUP (vector2, , int, s, 32, 2, 0xBB);
63  VDUP (vector2, q, int, s, 16, 8, 0xBB);
64  VDUP (vector2, q, int, s, 32, 4, 0x22);
65
66  /* Initialize vector3.  */
67  VDUP (vector3, , int, s, 16, 4, 0x5555);
68  VDUP (vector3, , int, s, 32, 2, 0xBB);
69  VDUP (vector3, q, int, s, 16, 8, 0x33);
70  VDUP (vector3, q, int, s, 32, 4, 0x22);
71
72  /* Choose lane arbitrarily.  */
73#define CMT ""
74  TEST_VQRDMLXH_LANE (, int, s, 16, 4, 4, 2, expected_cumulative_sat, CMT);
75  TEST_VQRDMLXH_LANE (, int, s, 32, 2, 2, 1, expected_cumulative_sat, CMT);
76  TEST_VQRDMLXH_LANE (q, int, s, 16, 8, 4, 3, expected_cumulative_sat, CMT);
77  TEST_VQRDMLXH_LANE (q, int, s, 32, 4, 2, 0, expected_cumulative_sat, CMT);
78
79  CHECK (TEST_MSG, int, 16, 4, PRIx16, expected, CMT);
80  CHECK (TEST_MSG, int, 32, 2, PRIx32, expected, CMT);
81  CHECK (TEST_MSG, int, 16, 8, PRIx16, expected, CMT);
82  CHECK (TEST_MSG, int, 32, 4, PRIx32, expected, CMT);
83
84  /* Now use input values such that the multiplication causes
85     saturation.  */
86#define TEST_MSG_MUL " (check mul cumulative saturation)"
87  VDUP (vector, , int, s, 16, 4, 0x8000);
88  VDUP (vector, , int, s, 32, 2, 0x80000000);
89  VDUP (vector, q, int, s, 16, 8, 0x8000);
90  VDUP (vector, q, int, s, 32, 4, 0x80000000);
91
92  VDUP (vector2, , int, s, 16, 4, 0x8000);
93  VDUP (vector2, , int, s, 32, 2, 0x80000000);
94  VDUP (vector2, q, int, s, 16, 8, 0x8000);
95  VDUP (vector2, q, int, s, 32, 4, 0x80000000);
96
97  VDUP (vector3, , int, s, 16, 4, 0x8000);
98  VDUP (vector3, , int, s, 32, 2, 0x80000000);
99  VDUP (vector3, q, int, s, 16, 8, 0x8000);
100  VDUP (vector3, q, int, s, 32, 4, 0x80000000);
101
102  TEST_VQRDMLXH_LANE (, int, s, 16, 4, 4, 2, expected_cumulative_sat_mul,
103		      TEST_MSG_MUL);
104  TEST_VQRDMLXH_LANE (, int, s, 32, 2, 2, 1, expected_cumulative_sat_mul,
105		      TEST_MSG_MUL);
106  TEST_VQRDMLXH_LANE (q, int, s, 16, 8, 4, 3, expected_cumulative_sat_mul,
107		      TEST_MSG_MUL);
108  TEST_VQRDMLXH_LANE (q, int, s, 32, 4, 2, 0, expected_cumulative_sat_mul,
109		      TEST_MSG_MUL);
110
111  CHECK (TEST_MSG, int, 16, 4, PRIx16, expected_mul, TEST_MSG_MUL);
112  CHECK (TEST_MSG, int, 32, 2, PRIx32, expected_mul, TEST_MSG_MUL);
113  CHECK (TEST_MSG, int, 16, 8, PRIx16, expected_mul, TEST_MSG_MUL);
114  CHECK (TEST_MSG, int, 32, 4, PRIx32, expected_mul, TEST_MSG_MUL);
115
116  VDUP (vector, , int, s, 16, 4, 0x8000);
117  VDUP (vector, , int, s, 32, 2, 0x80000000);
118  VDUP (vector, q, int, s, 16, 8, 0x8000);
119  VDUP (vector, q, int, s, 32, 4, 0x80000000);
120
121  VDUP (vector2, , int, s, 16, 4, 0x8001);
122  VDUP (vector2, , int, s, 32, 2, 0x80000001);
123  VDUP (vector2, q, int, s, 16, 8, 0x8001);
124  VDUP (vector2, q, int, s, 32, 4, 0x80000001);
125
126  VDUP (vector3, , int, s, 16, 4, 0x8001);
127  VDUP (vector3, , int, s, 32, 2, 0x80000001);
128  VDUP (vector3, q, int, s, 16, 8, 0x8001);
129  VDUP (vector3, q, int, s, 32, 4, 0x80000001);
130
131  /* Use input values where rounding produces a result equal to the
132     saturation value, but does not set the saturation flag.  */
133#define TEST_MSG_ROUND " (check rounding)"
134  TEST_VQRDMLXH_LANE (, int, s, 16, 4, 4, 2, expected_cumulative_sat_round,
135		      TEST_MSG_ROUND);
136  TEST_VQRDMLXH_LANE (, int, s, 32, 2, 2, 1, expected_cumulative_sat_round,
137		      TEST_MSG_ROUND);
138  TEST_VQRDMLXH_LANE (q, int, s, 16, 8, 4, 3, expected_cumulative_sat_round,
139		      TEST_MSG_ROUND);
140  TEST_VQRDMLXH_LANE (q, int, s, 32, 4, 2, 0, expected_cumulative_sat_round,
141		      TEST_MSG_ROUND);
142
143  CHECK (TEST_MSG, int, 16, 4, PRIx16, expected_round, TEST_MSG_ROUND);
144  CHECK (TEST_MSG, int, 32, 2, PRIx32, expected_round, TEST_MSG_ROUND);
145  CHECK (TEST_MSG, int, 16, 8, PRIx16, expected_round, TEST_MSG_ROUND);
146  CHECK (TEST_MSG, int, 32, 4, PRIx32, expected_round, TEST_MSG_ROUND);
147}
148
149int
150main (void)
151{
152  FNNAME (INSN) ();
153  return 0;
154}
155