2 #include "arm-neon-ref.h"
3 #include "compute-ref-data.h"
5 /* Expected values of cumulative_saturation flag. */
6 int VECT_VAR(expected_cumulative_sat
,int,16,4) = 0;
7 int VECT_VAR(expected_cumulative_sat
,int,32,2) = 0;
8 int VECT_VAR(expected_cumulative_sat
,int,16,8) = 0;
9 int VECT_VAR(expected_cumulative_sat
,int,32,4) = 0;
11 /* Expected results. */
12 VECT_VAR_DECL(expected
,int,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
13 VECT_VAR_DECL(expected
,int,32,2) [] = { 0x0, 0x0 };
14 VECT_VAR_DECL(expected
,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
16 VECT_VAR_DECL(expected
,int,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
18 /* Expected values of cumulative_saturation flag when multiplication
20 int VECT_VAR(expected_cumulative_sat_mul
,int,16,4) = 1;
21 int VECT_VAR(expected_cumulative_sat_mul
,int,32,2) = 1;
22 int VECT_VAR(expected_cumulative_sat_mul
,int,16,8) = 1;
23 int VECT_VAR(expected_cumulative_sat_mul
,int,32,4) = 1;
25 /* Expected results when multiplication saturates. */
26 VECT_VAR_DECL(expected_mul
,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
27 VECT_VAR_DECL(expected_mul
,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
28 VECT_VAR_DECL(expected_mul
,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
29 0x7fff, 0x7fff, 0x7fff, 0x7fff };
30 VECT_VAR_DECL(expected_mul
,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
31 0x7fffffff, 0x7fffffff };
33 /* Expected values of cumulative_saturation flag when rounding
34 should not cause saturation. */
35 int VECT_VAR(expected_cumulative_sat_round
,int,16,4) = 0;
36 int VECT_VAR(expected_cumulative_sat_round
,int,32,2) = 0;
37 int VECT_VAR(expected_cumulative_sat_round
,int,16,8) = 0;
38 int VECT_VAR(expected_cumulative_sat_round
,int,32,4) = 0;
40 /* Expected results when rounding should not cause saturation. */
41 VECT_VAR_DECL(expected_round
,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
42 VECT_VAR_DECL(expected_round
,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
43 VECT_VAR_DECL(expected_round
,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
44 0x7fff, 0x7fff, 0x7fff, 0x7fff };
45 VECT_VAR_DECL(expected_round
,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
46 0x7fffffff, 0x7fffffff };
49 #define TEST_MSG "VQRDMULH_LANE"
51 #define FNNAME1(NAME) void exec_ ## NAME ## _lane (void)
52 #define FNNAME(NAME) FNNAME1(NAME)
56 /* vector_res = vqrdmulh_lane(vector,vector2,lane), then store the result. */
57 #define TEST_VQRDMULH_LANE2(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT) \
58 Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, T1, W, N)); \
59 VECT_VAR(vector_res, T1, W, N) = \
60 INSN##Q##_lane_##T2##W(VECT_VAR(vector, T1, W, N), \
61 VECT_VAR(vector2, T1, W, N2), \
63 vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
64 VECT_VAR(vector_res, T1, W, N)); \
65 CHECK_CUMULATIVE_SAT(TEST_MSG, T1, W, N, EXPECTED_CUMULATIVE_SAT, CMT)
67 /* Two auxliary macros are necessary to expand INSN */
68 #define TEST_VQRDMULH_LANE1(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT) \
69 TEST_VQRDMULH_LANE2(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT)
71 #define TEST_VQRDMULH_LANE(Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT) \
72 TEST_VQRDMULH_LANE1(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT)
75 DECL_VARIABLE(vector
, int, 16, 4);
76 DECL_VARIABLE(vector
, int, 32, 2);
77 DECL_VARIABLE(vector
, int, 16, 8);
78 DECL_VARIABLE(vector
, int, 32, 4);
80 DECL_VARIABLE(vector_res
, int, 16, 4);
81 DECL_VARIABLE(vector_res
, int, 32, 2);
82 DECL_VARIABLE(vector_res
, int, 16, 8);
83 DECL_VARIABLE(vector_res
, int, 32, 4);
85 /* vector2: vqrdmulh_lane and vqrdmulhq_lane have a 2nd argument with
86 the same number of elements, so we need only one variable of each
88 DECL_VARIABLE(vector2
, int, 16, 4);
89 DECL_VARIABLE(vector2
, int, 32, 2);
93 VLOAD(vector
, buffer
, , int, s
, 16, 4);
94 VLOAD(vector
, buffer
, , int, s
, 32, 2);
96 VLOAD(vector
, buffer
, q
, int, s
, 16, 8);
97 VLOAD(vector
, buffer
, q
, int, s
, 32, 4);
99 /* Initialize vector2. */
100 VDUP(vector2
, , int, s
, 16, 4, 0x55);
101 VDUP(vector2
, , int, s
, 32, 2, 0xBB);
103 /* Choose lane arbitrarily. */
105 TEST_VQRDMULH_LANE(, int, s
, 16, 4, 4, 2, expected_cumulative_sat
, CMT
);
106 TEST_VQRDMULH_LANE(, int, s
, 32, 2, 2, 1, expected_cumulative_sat
, CMT
);
107 TEST_VQRDMULH_LANE(q
, int, s
, 16, 8, 4, 3, expected_cumulative_sat
, CMT
);
108 TEST_VQRDMULH_LANE(q
, int, s
, 32, 4, 2, 0, expected_cumulative_sat
, CMT
);
110 CHECK(TEST_MSG
, int, 16, 4, PRIx16
, expected
, CMT
);
111 CHECK(TEST_MSG
, int, 32, 2, PRIx32
, expected
, CMT
);
112 CHECK(TEST_MSG
, int, 16, 8, PRIx16
, expected
, CMT
);
113 CHECK(TEST_MSG
, int, 32, 4, PRIx32
, expected
, CMT
);
115 /* Now use input values such that the multiplication causes
117 #define TEST_MSG_MUL " (check mul cumulative saturation)"
118 VDUP(vector
, , int, s
, 16, 4, 0x8000);
119 VDUP(vector
, , int, s
, 32, 2, 0x80000000);
120 VDUP(vector
, q
, int, s
, 16, 8, 0x8000);
121 VDUP(vector
, q
, int, s
, 32, 4, 0x80000000);
122 VDUP(vector2
, , int, s
, 16, 4, 0x8000);
123 VDUP(vector2
, , int, s
, 32, 2, 0x80000000);
125 TEST_VQRDMULH_LANE(, int, s
, 16, 4, 4, 2, expected_cumulative_sat_mul
,
127 TEST_VQRDMULH_LANE(, int, s
, 32, 2, 2, 1, expected_cumulative_sat_mul
,
129 TEST_VQRDMULH_LANE(q
, int, s
, 16, 8, 4, 3, expected_cumulative_sat_mul
,
131 TEST_VQRDMULH_LANE(q
, int, s
, 32, 4, 2, 0, expected_cumulative_sat_mul
,
134 CHECK(TEST_MSG
, int, 16, 4, PRIx16
, expected_mul
, TEST_MSG_MUL
);
135 CHECK(TEST_MSG
, int, 32, 2, PRIx32
, expected_mul
, TEST_MSG_MUL
);
136 CHECK(TEST_MSG
, int, 16, 8, PRIx16
, expected_mul
, TEST_MSG_MUL
);
137 CHECK(TEST_MSG
, int, 32, 4, PRIx32
, expected_mul
, TEST_MSG_MUL
);
139 VDUP(vector
, , int, s
, 16, 4, 0x8000);
140 VDUP(vector
, , int, s
, 32, 2, 0x80000000);
141 VDUP(vector
, q
, int, s
, 16, 8, 0x8000);
142 VDUP(vector
, q
, int, s
, 32, 4, 0x80000000);
143 VDUP(vector2
, , int, s
, 16, 4, 0x8001);
144 VDUP(vector2
, , int, s
, 32, 2, 0x80000001);
146 /* Use input values where rounding produces a result equal to the
147 saturation value, but does not set the saturation flag. */
148 #define TEST_MSG_ROUND " (check rounding)"
149 TEST_VQRDMULH_LANE(, int, s
, 16, 4, 4, 2, expected_cumulative_sat_round
,
151 TEST_VQRDMULH_LANE(, int, s
, 32, 2, 2, 1, expected_cumulative_sat_round
,
153 TEST_VQRDMULH_LANE(q
, int, s
, 16, 8, 4, 3, expected_cumulative_sat_round
,
155 TEST_VQRDMULH_LANE(q
, int, s
, 32, 4, 2, 0, expected_cumulative_sat_round
,
158 CHECK(TEST_MSG
, int, 16, 4, PRIx16
, expected_round
, TEST_MSG_ROUND
);
159 CHECK(TEST_MSG
, int, 32, 2, PRIx32
, expected_round
, TEST_MSG_ROUND
);
160 CHECK(TEST_MSG
, int, 16, 8, PRIx16
, expected_round
, TEST_MSG_ROUND
);
161 CHECK(TEST_MSG
, int, 32, 4, PRIx32
, expected_round
, TEST_MSG_ROUND
);
166 exec_vqrdmulh_lane ();