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