Merge tag 'v9.0.0-rc3'
[qemu/ar7.git] / tests / tcg / hexagon / multi_result.c
blob38ee369e7687942a1f8f97d7584ab08c2090c96b
1 /*
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/>.
18 #include <stdio.h>
19 #include <stdint.h>
20 #include <stdbool.h>
22 int err;
24 #include "hex_test.h"
26 static int32_t sfrecipa(int32_t Rs, int32_t Rt, bool *pred_result)
28 int32_t result;
29 bool predval;
31 asm volatile("%0,p0 = sfrecipa(%2, %3)\n\t"
32 "%1 = p0\n\t"
33 : "+r"(result), "=r"(predval)
34 : "r"(Rs), "r"(Rt)
35 : "p0");
36 *pred_result = predval;
37 return result;
40 static int32_t sfinvsqrta(int32_t Rs, int32_t *pred_result)
42 int32_t result;
43 int32_t predval;
45 asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
46 "%1 = p0\n\t"
47 : "+r"(result), "=r"(predval)
48 : "r"(Rs)
49 : "p0");
50 *pred_result = predval;
51 return result;
54 static int64_t vacsh(int64_t Rxx, int64_t Rss, int64_t Rtt,
55 int *pred_result, bool *ovf_result)
57 int64_t result = Rxx;
58 int predval;
59 uint32_t usr;
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 */
67 "usr = r2\n\t"
68 "%0,p0 = vacsh(%3, %4)\n\t"
69 "%1 = p0\n\t"
70 "%2 = usr\n\t"
71 : "+r"(result), "=r"(predval), "=r"(usr)
72 : "r"(Rss), "r"(Rtt)
73 : "r2", "p0", "usr");
74 *pred_result = predval;
75 *ovf_result = (usr & 1);
76 return result;
79 static int64_t vminub(int64_t Rtt, int64_t Rss, int32_t *pred_result)
81 int64_t result;
82 int32_t predval;
84 asm volatile("%0,p0 = vminub(%2, %3)\n\t"
85 "%1 = p0\n\t"
86 : "=r"(result), "=r"(predval)
87 : "r"(Rtt), "r"(Rss)
88 : "p0");
89 *pred_result = predval;
90 return result;
93 static int64_t add_carry(int64_t Rss, int64_t Rtt,
94 int32_t pred_in, int32_t *pred_result)
96 int64_t result;
97 int32_t predval = pred_in;
99 asm volatile("p0 = %1\n\t"
100 "%0 = add(%2, %3, p0):carry\n\t"
101 "%1 = p0\n\t"
102 : "=r"(result), "+r"(predval)
103 : "r"(Rss), "r"(Rtt)
104 : "p0");
105 *pred_result = predval;
106 return result;
109 static int64_t sub_carry(int64_t Rss, int64_t Rtt,
110 int32_t pred_in, int32_t *pred_result)
112 int64_t 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"
117 "%1 = p0\n\t"
118 : "=r"(result), "+r"(predval)
119 : "r"(Rss), "r"(Rtt)
120 : "p0");
121 *pred_result = predval;
122 return result;
125 static void test_sfrecipa()
127 int32_t res;
128 bool pred_result;
130 res = sfrecipa(0x04030201, 0x05060708, &pred_result);
131 check32(res, 0x59f38001);
132 check32(pred_result, false);
135 static void test_sfinvsqrta()
137 int32_t res;
138 int32_t pred_result;
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()
151 int64_t res64;
152 int32_t pred_result;
153 bool ovf_result;
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()
186 int64_t res64;
187 int32_t pred_result;
189 res64 = vminub(0x0807060504030201LL,
190 0x0102030405060708LL,
191 &pred_result);
192 check64(res64, 0x0102030404030201LL);
193 check32(pred_result, 0xf0);
195 res64 = vminub(0x0802060405030701LL,
196 0x0107030504060208LL,
197 &pred_result);
198 check64(res64, 0x0102030404030201LL);
199 check32(pred_result, 0xaa);
202 static void test_add_carry()
204 int64_t res64;
205 int32_t pred_result;
207 res64 = add_carry(0x0000000000000000LL,
208 0xffffffffffffffffLL,
209 1, &pred_result);
210 check64(res64, 0x0000000000000000LL);
211 check32(pred_result, 0xff);
213 res64 = add_carry(0x0000000100000000LL,
214 0xffffffffffffffffLL,
215 0, &pred_result);
216 check64(res64, 0x00000000ffffffffLL);
217 check32(pred_result, 0xff);
219 res64 = add_carry(0x0000000100000000LL,
220 0xffffffffffffffffLL,
221 0, &pred_result);
222 check64(res64, 0x00000000ffffffffLL);
223 check32(pred_result, 0xff);
226 static void test_sub_carry()
228 int64_t res64;
229 int32_t pred_result;
231 res64 = sub_carry(0x0000000000000000LL,
232 0x0000000000000000LL,
233 1, &pred_result);
234 check64(res64, 0x0000000000000000LL);
235 check32(pred_result, 0xff);
237 res64 = sub_carry(0x0000000100000000LL,
238 0x0000000000000000LL,
239 0, &pred_result);
240 check64(res64, 0x00000000ffffffffLL);
241 check32(pred_result, 0xff);
243 res64 = sub_carry(0x0000000100000000LL,
244 0x0000000000000000LL,
245 0, &pred_result);
246 check64(res64, 0x00000000ffffffffLL);
247 check32(pred_result, 0xff);
250 int main()
252 test_sfrecipa();
253 test_sfinvsqrta();
254 test_vacsh();
255 test_vminub();
256 test_add_carry();
257 test_sub_carry();
259 puts(err ? "FAIL" : "PASS");
260 return err;