2 * Copyright(c) 2019-2023 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/>.
26 static int32_t sfrecipa(int32_t Rs
, int32_t Rt
, bool *pred_result
)
31 asm volatile("%0,p0 = sfrecipa(%2, %3)\n\t"
33 : "+r"(result
), "=r"(predval
)
36 *pred_result
= predval
;
40 static int32_t sfinvsqrta(int32_t Rs
, int32_t *pred_result
)
45 asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
47 : "+r"(result
), "=r"(predval
)
50 *pred_result
= predval
;
54 static int64_t vacsh(int64_t Rxx
, int64_t Rss
, int64_t Rtt
,
55 int *pred_result
, bool *ovf_result
)
62 * This instruction can set bit 0 (OVF/overflow) in usr
63 * Clear the bit first, then return that bit to the caller
65 asm volatile("r2 = usr\n\t"
66 "r2 = clrbit(r2, #0)\n\t" /* clear overflow bit */
68 "%0,p0 = vacsh(%3, %4)\n\t"
71 : "+r"(result
), "=r"(predval
), "=r"(usr
)
74 *pred_result
= predval
;
75 *ovf_result
= (usr
& 1);
79 static int64_t vminub(int64_t Rtt
, int64_t Rss
, int32_t *pred_result
)
84 asm volatile("%0,p0 = vminub(%2, %3)\n\t"
86 : "=r"(result
), "=r"(predval
)
89 *pred_result
= predval
;
93 static int64_t add_carry(int64_t Rss
, int64_t Rtt
,
94 int32_t pred_in
, int32_t *pred_result
)
97 int32_t predval
= pred_in
;
99 asm volatile("p0 = %1\n\t"
100 "%0 = add(%2, %3, p0):carry\n\t"
102 : "=r"(result
), "+r"(predval
)
105 *pred_result
= predval
;
109 static int64_t sub_carry(int64_t Rss
, int64_t Rtt
,
110 int32_t pred_in
, int32_t *pred_result
)
113 int32_t predval
= pred_in
;
115 asm volatile("p0 = !cmp.eq(%1, #0)\n\t"
116 "%0 = sub(%2, %3, p0):carry\n\t"
118 : "=r"(result
), "+r"(predval
)
121 *pred_result
= predval
;
125 static void test_sfrecipa()
130 res
= sfrecipa(0x04030201, 0x05060708, &pred_result
);
131 check32(res
, 0x59f38001);
132 check32(pred_result
, false);
135 static void test_sfinvsqrta()
140 res
= sfinvsqrta(0x04030201, &pred_result
);
141 check32(res
, 0x4d330000);
142 check32(pred_result
, 0xe0);
144 res
= sfinvsqrta(0x0, &pred_result
);
145 check32(res
, 0x3f800000);
146 check32(pred_result
, 0x0);
149 static void test_vacsh()
155 res64
= vacsh(0x0004000300020001LL
,
156 0x0001000200030004LL
,
157 0x0000000000000000LL
, &pred_result
, &ovf_result
);
158 check64(res64
, 0x0004000300030004LL
);
159 check32(pred_result
, 0xf0);
160 check32(ovf_result
, false);
162 res64
= vacsh(0x0004000300020001LL
,
163 0x0001000200030004LL
,
164 0x000affff000d0000LL
, &pred_result
, &ovf_result
);
165 check64(res64
, 0x000e0003000f0004LL
);
166 check32(pred_result
, 0xcc);
167 check32(ovf_result
, false);
169 res64
= vacsh(0x00047fff00020001LL
,
170 0x00017fff00030004LL
,
171 0x000a0fff000d0000LL
, &pred_result
, &ovf_result
);
172 check64(res64
, 0x000e7fff000f0004LL
);
173 check32(pred_result
, 0xfc);
174 check32(ovf_result
, true);
176 res64
= vacsh(0x0004000300020001LL
,
177 0x0001000200030009LL
,
178 0x000affff000d0001LL
, &pred_result
, &ovf_result
);
179 check64(res64
, 0x000e0003000f0008LL
);
180 check32(pred_result
, 0xcc);
181 check32(ovf_result
, false);
184 static void test_vminub()
189 res64
= vminub(0x0807060504030201LL
,
190 0x0102030405060708LL
,
192 check64(res64
, 0x0102030404030201LL
);
193 check32(pred_result
, 0xf0);
195 res64
= vminub(0x0802060405030701LL
,
196 0x0107030504060208LL
,
198 check64(res64
, 0x0102030404030201LL
);
199 check32(pred_result
, 0xaa);
202 static void test_add_carry()
207 res64
= add_carry(0x0000000000000000LL
,
208 0xffffffffffffffffLL
,
210 check64(res64
, 0x0000000000000000LL
);
211 check32(pred_result
, 0xff);
213 res64
= add_carry(0x0000000100000000LL
,
214 0xffffffffffffffffLL
,
216 check64(res64
, 0x00000000ffffffffLL
);
217 check32(pred_result
, 0xff);
219 res64
= add_carry(0x0000000100000000LL
,
220 0xffffffffffffffffLL
,
222 check64(res64
, 0x00000000ffffffffLL
);
223 check32(pred_result
, 0xff);
226 static void test_sub_carry()
231 res64
= sub_carry(0x0000000000000000LL
,
232 0x0000000000000000LL
,
234 check64(res64
, 0x0000000000000000LL
);
235 check32(pred_result
, 0xff);
237 res64
= sub_carry(0x0000000100000000LL
,
238 0x0000000000000000LL
,
240 check64(res64
, 0x00000000ffffffffLL
);
241 check32(pred_result
, 0xff);
243 res64
= sub_carry(0x0000000100000000LL
,
244 0x0000000000000000LL
,
246 check64(res64
, 0x00000000ffffffffLL
);
247 check32(pred_result
, 0xff);
259 puts(err
? "FAIL" : "PASS");