2 * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 static int sfrecipa(int Rs
, int Rt
, int *pred_result
)
25 asm volatile("%0,p0 = sfrecipa(%2, %3)\n\t"
27 : "+r"(result
), "=r"(predval
)
30 *pred_result
= predval
;
34 static int sfinvsqrta(int Rs
, int *pred_result
)
39 asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
41 : "+r"(result
), "=r"(predval
)
44 *pred_result
= predval
;
48 static long long vacsh(long long Rxx
, long long Rss
, long long Rtt
,
49 int *pred_result
, int *ovf_result
)
51 long long result
= Rxx
;
56 * This instruction can set bit 0 (OVF/overflow) in usr
57 * Clear the bit first, then return that bit to the caller
59 asm volatile("r2 = usr\n\t"
60 "r2 = clrbit(r2, #0)\n\t" /* clear overflow bit */
62 "%0,p0 = vacsh(%3, %4)\n\t"
65 : "+r"(result
), "=r"(predval
), "=r"(usr
)
68 *pred_result
= predval
;
69 *ovf_result
= (usr
& 1);
73 static long long vminub(long long Rtt
, long long Rss
,
79 asm volatile("%0,p0 = vminub(%2, %3)\n\t"
81 : "=r"(result
), "=r"(predval
)
84 *pred_result
= predval
;
88 static long long add_carry(long long Rss
, long long Rtt
,
89 int pred_in
, int *pred_result
)
92 int predval
= pred_in
;
94 asm volatile("p0 = %1\n\t"
95 "%0 = add(%2, %3, p0):carry\n\t"
97 : "=r"(result
), "+r"(predval
)
100 *pred_result
= predval
;
104 static long long sub_carry(long long Rss
, long long Rtt
,
105 int pred_in
, int *pred_result
)
108 int predval
= pred_in
;
110 asm volatile("p0 = !cmp.eq(%1, #0)\n\t"
111 "%0 = sub(%2, %3, p0):carry\n\t"
113 : "=r"(result
), "+r"(predval
)
116 *pred_result
= predval
;
122 static void check_ll(long long val
, long long expect
)
125 printf("ERROR: 0x%016llx != 0x%016llx\n", val
, expect
);
130 static void check(int val
, int expect
)
133 printf("ERROR: 0x%08x != 0x%08x\n", val
, expect
);
138 static void check_p(int val
, int expect
)
141 printf("ERROR: 0x%02x != 0x%02x\n", val
, expect
);
146 static void test_sfrecipa()
151 res
= sfrecipa(0x04030201, 0x05060708, &pred_result
);
152 check(res
, 0x59f38001);
153 check_p(pred_result
, 0x00);
156 static void test_sfinvsqrta()
161 res
= sfinvsqrta(0x04030201, &pred_result
);
162 check(res
, 0x4d330000);
163 check_p(pred_result
, 0xe0);
165 res
= sfinvsqrta(0x0, &pred_result
);
166 check(res
, 0x3f800000);
167 check_p(pred_result
, 0x0);
170 static void test_vacsh()
176 res64
= vacsh(0x0004000300020001LL
,
177 0x0001000200030004LL
,
178 0x0000000000000000LL
, &pred_result
, &ovf_result
);
179 check_ll(res64
, 0x0004000300030004LL
);
180 check_p(pred_result
, 0xf0);
181 check(ovf_result
, 0);
183 res64
= vacsh(0x0004000300020001LL
,
184 0x0001000200030004LL
,
185 0x000affff000d0000LL
, &pred_result
, &ovf_result
);
186 check_ll(res64
, 0x000e0003000f0004LL
);
187 check_p(pred_result
, 0xcc);
188 check(ovf_result
, 0);
190 res64
= vacsh(0x00047fff00020001LL
,
191 0x00017fff00030004LL
,
192 0x000a0fff000d0000LL
, &pred_result
, &ovf_result
);
193 check_ll(res64
, 0x000e7fff000f0004LL
);
194 check_p(pred_result
, 0xfc);
195 check(ovf_result
, 1);
197 res64
= vacsh(0x0004000300020001LL
,
198 0x0001000200030009LL
,
199 0x000affff000d0001LL
, &pred_result
, &ovf_result
);
200 check_ll(res64
, 0x000e0003000f0008LL
);
201 check_p(pred_result
, 0xcc);
202 check(ovf_result
, 0);
205 static void test_vminub()
210 res64
= vminub(0x0807060504030201LL
,
211 0x0102030405060708LL
,
213 check_ll(res64
, 0x0102030404030201LL
);
214 check_p(pred_result
, 0xf0);
216 res64
= vminub(0x0802060405030701LL
,
217 0x0107030504060208LL
,
219 check_ll(res64
, 0x0102030404030201LL
);
220 check_p(pred_result
, 0xaa);
223 static void test_add_carry()
228 res64
= add_carry(0x0000000000000000LL
,
229 0xffffffffffffffffLL
,
231 check_ll(res64
, 0x0000000000000000LL
);
232 check_p(pred_result
, 0xff);
234 res64
= add_carry(0x0000000100000000LL
,
235 0xffffffffffffffffLL
,
237 check_ll(res64
, 0x00000000ffffffffLL
);
238 check_p(pred_result
, 0xff);
240 res64
= add_carry(0x0000000100000000LL
,
241 0xffffffffffffffffLL
,
243 check_ll(res64
, 0x00000000ffffffffLL
);
244 check_p(pred_result
, 0xff);
247 static void test_sub_carry()
252 res64
= sub_carry(0x0000000000000000LL
,
253 0x0000000000000000LL
,
255 check_ll(res64
, 0x0000000000000000LL
);
256 check_p(pred_result
, 0xff);
258 res64
= sub_carry(0x0000000100000000LL
,
259 0x0000000000000000LL
,
261 check_ll(res64
, 0x00000000ffffffffLL
);
262 check_p(pred_result
, 0xff);
264 res64
= sub_carry(0x0000000100000000LL
,
265 0x0000000000000000LL
,
267 check_ll(res64
, 0x00000000ffffffffLL
);
268 check_p(pred_result
, 0xff);
280 puts(err
? "FAIL" : "PASS");