blob: 3faf52cbc4602d556f821497a0af75324da69364 [file] [log] [blame]
Song Gaoa0c94002023-05-04 20:27:28 +08001/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
Song Gao1dc33f22023-09-14 10:25:49 +08003 * QEMU LoongArch vector helper functions.
Song Gaoa0c94002023-05-04 20:27:28 +08004 *
5 * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
6 */
Song Gaoc037fbc2023-05-04 20:27:34 +08007
8#include "qemu/osdep.h"
9#include "cpu.h"
10#include "exec/exec-all.h"
11#include "exec/helper-proto.h"
Song Gaoaca67472023-05-04 20:27:59 +080012#include "fpu/softfloat.h"
13#include "internals.h"
Song Gaod0dfa192023-05-04 20:28:03 +080014#include "tcg/tcg.h"
Song Gao008a3b12023-09-14 10:25:59 +080015#include "vec.h"
Song Gao64cf6b92023-09-14 10:26:07 +080016#include "tcg/tcg-gvec-desc.h"
Song Gaoc037fbc2023-05-04 20:27:34 +080017
Song Gaoc037fbc2023-05-04 20:27:34 +080018#define DO_ODD_EVEN(NAME, BIT, E1, E2, DO_OP) \
Song Gao04711da2023-09-14 10:25:54 +080019void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gaoc037fbc2023-05-04 20:27:34 +080020{ \
21 int i; \
Song Gao04711da2023-09-14 10:25:54 +080022 VReg *Vd = (VReg *)vd; \
23 VReg *Vj = (VReg *)vj; \
24 VReg *Vk = (VReg *)vk; \
Song Gaoc037fbc2023-05-04 20:27:34 +080025 typedef __typeof(Vd->E1(0)) TD; \
Song Gao64cf6b92023-09-14 10:26:07 +080026 int oprsz = simd_oprsz(desc); \
Song Gaoc037fbc2023-05-04 20:27:34 +080027 \
Song Gao64cf6b92023-09-14 10:26:07 +080028 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gaoc037fbc2023-05-04 20:27:34 +080029 Vd->E1(i) = DO_OP((TD)Vj->E2(2 * i + 1), (TD)Vk->E2(2 * i)); \
30 } \
31}
32
33DO_ODD_EVEN(vhaddw_h_b, 16, H, B, DO_ADD)
34DO_ODD_EVEN(vhaddw_w_h, 32, W, H, DO_ADD)
35DO_ODD_EVEN(vhaddw_d_w, 64, D, W, DO_ADD)
36
Song Gao04711da2023-09-14 10:25:54 +080037void HELPER(vhaddw_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gaoc037fbc2023-05-04 20:27:34 +080038{
Song Gao64cf6b92023-09-14 10:26:07 +080039 int i;
Song Gao04711da2023-09-14 10:25:54 +080040 VReg *Vd = (VReg *)vd;
41 VReg *Vj = (VReg *)vj;
42 VReg *Vk = (VReg *)vk;
Song Gao64cf6b92023-09-14 10:26:07 +080043 int oprsz = simd_oprsz(desc);
Song Gaoc037fbc2023-05-04 20:27:34 +080044
Song Gao64cf6b92023-09-14 10:26:07 +080045 for (i = 0; i < oprsz / 16 ; i++) {
46 Vd->Q(i) = int128_add(int128_makes64(Vj->D(2 * i + 1)),
47 int128_makes64(Vk->D(2 * i)));
48 }
Song Gaoc037fbc2023-05-04 20:27:34 +080049}
50
51DO_ODD_EVEN(vhsubw_h_b, 16, H, B, DO_SUB)
52DO_ODD_EVEN(vhsubw_w_h, 32, W, H, DO_SUB)
53DO_ODD_EVEN(vhsubw_d_w, 64, D, W, DO_SUB)
54
Song Gao04711da2023-09-14 10:25:54 +080055void HELPER(vhsubw_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gaoc037fbc2023-05-04 20:27:34 +080056{
Song Gao64cf6b92023-09-14 10:26:07 +080057 int i;
Song Gao04711da2023-09-14 10:25:54 +080058 VReg *Vd = (VReg *)vd;
59 VReg *Vj = (VReg *)vj;
60 VReg *Vk = (VReg *)vk;
Song Gao64cf6b92023-09-14 10:26:07 +080061 int oprsz = simd_oprsz(desc);
Song Gaoc037fbc2023-05-04 20:27:34 +080062
Song Gao64cf6b92023-09-14 10:26:07 +080063 for (i = 0; i < oprsz / 16; i++) {
64 Vd->Q(i) = int128_sub(int128_makes64(Vj->D(2 * i + 1)),
65 int128_makes64(Vk->D(2 * i)));
66 }
Song Gaoc037fbc2023-05-04 20:27:34 +080067}
68
69DO_ODD_EVEN(vhaddw_hu_bu, 16, UH, UB, DO_ADD)
70DO_ODD_EVEN(vhaddw_wu_hu, 32, UW, UH, DO_ADD)
71DO_ODD_EVEN(vhaddw_du_wu, 64, UD, UW, DO_ADD)
72
Song Gao04711da2023-09-14 10:25:54 +080073void HELPER(vhaddw_qu_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gaoc037fbc2023-05-04 20:27:34 +080074{
Song Gao64cf6b92023-09-14 10:26:07 +080075 int i;
Song Gao04711da2023-09-14 10:25:54 +080076 VReg *Vd = (VReg *)vd;
77 VReg *Vj = (VReg *)vj;
78 VReg *Vk = (VReg *)vk;
Song Gao64cf6b92023-09-14 10:26:07 +080079 int oprsz = simd_oprsz(desc);
Song Gaoc037fbc2023-05-04 20:27:34 +080080
Song Gao64cf6b92023-09-14 10:26:07 +080081 for (i = 0; i < oprsz / 16; i ++) {
82 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i + 1)),
83 int128_make64(Vk->UD(2 * i)));
84 }
Song Gaoc037fbc2023-05-04 20:27:34 +080085}
86
87DO_ODD_EVEN(vhsubw_hu_bu, 16, UH, UB, DO_SUB)
88DO_ODD_EVEN(vhsubw_wu_hu, 32, UW, UH, DO_SUB)
89DO_ODD_EVEN(vhsubw_du_wu, 64, UD, UW, DO_SUB)
90
Song Gao04711da2023-09-14 10:25:54 +080091void HELPER(vhsubw_qu_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gaoc037fbc2023-05-04 20:27:34 +080092{
Song Gao64cf6b92023-09-14 10:26:07 +080093 int i;
Song Gao04711da2023-09-14 10:25:54 +080094 VReg *Vd = (VReg *)vd;
95 VReg *Vj = (VReg *)vj;
96 VReg *Vk = (VReg *)vk;
Song Gao64cf6b92023-09-14 10:26:07 +080097 int oprsz = simd_oprsz(desc);
Song Gaoc037fbc2023-05-04 20:27:34 +080098
Song Gao64cf6b92023-09-14 10:26:07 +080099 for (i = 0; i < oprsz / 16; i++) {
100 Vd->Q(i) = int128_sub(int128_make64(Vj->UD(2 * i + 1)),
101 int128_make64(Vk->UD(2 * i)));
102 }
Song Gaoc037fbc2023-05-04 20:27:34 +0800103}
Song Gao2d5f9502023-05-04 20:27:35 +0800104
105#define DO_EVEN(NAME, BIT, E1, E2, DO_OP) \
Song Gao85995f02023-09-14 10:26:08 +0800106void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gao2d5f9502023-05-04 20:27:35 +0800107{ \
108 int i; \
109 VReg *Vd = (VReg *)vd; \
110 VReg *Vj = (VReg *)vj; \
111 VReg *Vk = (VReg *)vk; \
112 typedef __typeof(Vd->E1(0)) TD; \
Song Gao85995f02023-09-14 10:26:08 +0800113 int oprsz = simd_oprsz(desc); \
114 \
115 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao2d5f9502023-05-04 20:27:35 +0800116 Vd->E1(i) = DO_OP((TD)Vj->E2(2 * i) ,(TD)Vk->E2(2 * i)); \
117 } \
118}
119
120#define DO_ODD(NAME, BIT, E1, E2, DO_OP) \
Song Gao85995f02023-09-14 10:26:08 +0800121void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gao2d5f9502023-05-04 20:27:35 +0800122{ \
123 int i; \
124 VReg *Vd = (VReg *)vd; \
125 VReg *Vj = (VReg *)vj; \
126 VReg *Vk = (VReg *)vk; \
127 typedef __typeof(Vd->E1(0)) TD; \
Song Gao85995f02023-09-14 10:26:08 +0800128 int oprsz = simd_oprsz(desc); \
129 \
130 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao2d5f9502023-05-04 20:27:35 +0800131 Vd->E1(i) = DO_OP((TD)Vj->E2(2 * i + 1), (TD)Vk->E2(2 * i + 1)); \
132 } \
133}
134
Song Gao85995f02023-09-14 10:26:08 +0800135void HELPER(vaddwev_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800136{
Song Gao85995f02023-09-14 10:26:08 +0800137 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800138 VReg *Vd = (VReg *)vd;
139 VReg *Vj = (VReg *)vj;
140 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800141 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800142
Song Gao85995f02023-09-14 10:26:08 +0800143 for (i = 0; i < oprsz / 16; i++) {
144 Vd->Q(i) = int128_add(int128_makes64(Vj->D(2 * i)),
145 int128_makes64(Vk->D(2 * i)));
146 }
Song Gao2d5f9502023-05-04 20:27:35 +0800147}
148
149DO_EVEN(vaddwev_h_b, 16, H, B, DO_ADD)
150DO_EVEN(vaddwev_w_h, 32, W, H, DO_ADD)
151DO_EVEN(vaddwev_d_w, 64, D, W, DO_ADD)
152
Song Gao85995f02023-09-14 10:26:08 +0800153void HELPER(vaddwod_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800154{
Song Gao85995f02023-09-14 10:26:08 +0800155 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800156 VReg *Vd = (VReg *)vd;
157 VReg *Vj = (VReg *)vj;
158 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800159 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800160
Song Gao85995f02023-09-14 10:26:08 +0800161 for (i = 0; i < oprsz / 16; i++) {
162 Vd->Q(i) = int128_add(int128_makes64(Vj->D(2 * i +1)),
163 int128_makes64(Vk->D(2 * i +1)));
164 }
Song Gao2d5f9502023-05-04 20:27:35 +0800165}
166
167DO_ODD(vaddwod_h_b, 16, H, B, DO_ADD)
168DO_ODD(vaddwod_w_h, 32, W, H, DO_ADD)
169DO_ODD(vaddwod_d_w, 64, D, W, DO_ADD)
170
Song Gao85995f02023-09-14 10:26:08 +0800171void HELPER(vsubwev_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800172{
Song Gao85995f02023-09-14 10:26:08 +0800173 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800174 VReg *Vd = (VReg *)vd;
175 VReg *Vj = (VReg *)vj;
176 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800177 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800178
Song Gao85995f02023-09-14 10:26:08 +0800179 for (i = 0; i < oprsz / 16; i++) {
180 Vd->Q(i) = int128_sub(int128_makes64(Vj->D(2 * i)),
181 int128_makes64(Vk->D(2 * i)));
182 }
Song Gao2d5f9502023-05-04 20:27:35 +0800183}
184
185DO_EVEN(vsubwev_h_b, 16, H, B, DO_SUB)
186DO_EVEN(vsubwev_w_h, 32, W, H, DO_SUB)
187DO_EVEN(vsubwev_d_w, 64, D, W, DO_SUB)
188
Song Gao85995f02023-09-14 10:26:08 +0800189void HELPER(vsubwod_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800190{
Song Gao85995f02023-09-14 10:26:08 +0800191 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800192 VReg *Vd = (VReg *)vd;
193 VReg *Vj = (VReg *)vj;
194 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800195 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800196
Song Gao85995f02023-09-14 10:26:08 +0800197 for (i = 0; i < oprsz / 16; i++) {
198 Vd->Q(i) = int128_sub(int128_makes64(Vj->D(2 * i + 1)),
199 int128_makes64(Vk->D(2 * i + 1)));
200 }
Song Gao2d5f9502023-05-04 20:27:35 +0800201}
202
203DO_ODD(vsubwod_h_b, 16, H, B, DO_SUB)
204DO_ODD(vsubwod_w_h, 32, W, H, DO_SUB)
205DO_ODD(vsubwod_d_w, 64, D, W, DO_SUB)
206
Song Gao85995f02023-09-14 10:26:08 +0800207void HELPER(vaddwev_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800208{
Song Gao85995f02023-09-14 10:26:08 +0800209 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800210 VReg *Vd = (VReg *)vd;
211 VReg *Vj = (VReg *)vj;
212 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800213 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800214
Song Gao85995f02023-09-14 10:26:08 +0800215 for (i = 0; i < oprsz / 16; i++) {
216 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i)),
217 int128_make64(Vk->UD(2 * i)));
218 }
Song Gao2d5f9502023-05-04 20:27:35 +0800219}
220
221DO_EVEN(vaddwev_h_bu, 16, UH, UB, DO_ADD)
222DO_EVEN(vaddwev_w_hu, 32, UW, UH, DO_ADD)
223DO_EVEN(vaddwev_d_wu, 64, UD, UW, DO_ADD)
224
Song Gao85995f02023-09-14 10:26:08 +0800225void HELPER(vaddwod_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800226{
Song Gao85995f02023-09-14 10:26:08 +0800227 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800228 VReg *Vd = (VReg *)vd;
229 VReg *Vj = (VReg *)vj;
230 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800231 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800232
Song Gao85995f02023-09-14 10:26:08 +0800233 for (i = 0; i < oprsz / 16; i++) {
234 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i + 1)),
235 int128_make64(Vk->UD(2 * i + 1)));
236 }
Song Gao2d5f9502023-05-04 20:27:35 +0800237}
238
239DO_ODD(vaddwod_h_bu, 16, UH, UB, DO_ADD)
240DO_ODD(vaddwod_w_hu, 32, UW, UH, DO_ADD)
241DO_ODD(vaddwod_d_wu, 64, UD, UW, DO_ADD)
242
Song Gao85995f02023-09-14 10:26:08 +0800243void HELPER(vsubwev_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800244{
Song Gao85995f02023-09-14 10:26:08 +0800245 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800246 VReg *Vd = (VReg *)vd;
247 VReg *Vj = (VReg *)vj;
248 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800249 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800250
Song Gao85995f02023-09-14 10:26:08 +0800251 for (i = 0; i < oprsz / 16; i++) {
252 Vd->Q(i) = int128_sub(int128_make64(Vj->UD(2 * i)),
253 int128_make64(Vk->UD(2 * i)));
254 }
Song Gao2d5f9502023-05-04 20:27:35 +0800255}
256
257DO_EVEN(vsubwev_h_bu, 16, UH, UB, DO_SUB)
258DO_EVEN(vsubwev_w_hu, 32, UW, UH, DO_SUB)
259DO_EVEN(vsubwev_d_wu, 64, UD, UW, DO_SUB)
260
Song Gao85995f02023-09-14 10:26:08 +0800261void HELPER(vsubwod_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800262{
Song Gao85995f02023-09-14 10:26:08 +0800263 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800264 VReg *Vd = (VReg *)vd;
265 VReg *Vj = (VReg *)vj;
266 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800267 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800268
Song Gao85995f02023-09-14 10:26:08 +0800269 for (i = 0; i < oprsz / 16; i++) {
270 Vd->Q(i) = int128_sub(int128_make64(Vj->UD(2 * i + 1)),
271 int128_make64(Vk->UD(2 * i + 1)));
272 }
Song Gao2d5f9502023-05-04 20:27:35 +0800273}
274
275DO_ODD(vsubwod_h_bu, 16, UH, UB, DO_SUB)
276DO_ODD(vsubwod_w_hu, 32, UW, UH, DO_SUB)
277DO_ODD(vsubwod_d_wu, 64, UD, UW, DO_SUB)
278
279#define DO_EVEN_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
Song Gao85995f02023-09-14 10:26:08 +0800280void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gao2d5f9502023-05-04 20:27:35 +0800281{ \
282 int i; \
283 VReg *Vd = (VReg *)vd; \
284 VReg *Vj = (VReg *)vj; \
285 VReg *Vk = (VReg *)vk; \
286 typedef __typeof(Vd->ES1(0)) TDS; \
287 typedef __typeof(Vd->EU1(0)) TDU; \
Song Gao85995f02023-09-14 10:26:08 +0800288 int oprsz = simd_oprsz(desc); \
289 \
290 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao2d5f9502023-05-04 20:27:35 +0800291 Vd->ES1(i) = DO_OP((TDU)Vj->EU2(2 * i) ,(TDS)Vk->ES2(2 * i)); \
292 } \
293}
294
295#define DO_ODD_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
Song Gao85995f02023-09-14 10:26:08 +0800296void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gao2d5f9502023-05-04 20:27:35 +0800297{ \
298 int i; \
299 VReg *Vd = (VReg *)vd; \
300 VReg *Vj = (VReg *)vj; \
301 VReg *Vk = (VReg *)vk; \
302 typedef __typeof(Vd->ES1(0)) TDS; \
303 typedef __typeof(Vd->EU1(0)) TDU; \
Song Gao85995f02023-09-14 10:26:08 +0800304 int oprsz = simd_oprsz(desc); \
305 \
306 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao2d5f9502023-05-04 20:27:35 +0800307 Vd->ES1(i) = DO_OP((TDU)Vj->EU2(2 * i + 1), (TDS)Vk->ES2(2 * i + 1)); \
308 } \
309}
310
Song Gao85995f02023-09-14 10:26:08 +0800311void HELPER(vaddwev_q_du_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800312{
Song Gao85995f02023-09-14 10:26:08 +0800313 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800314 VReg *Vd = (VReg *)vd;
315 VReg *Vj = (VReg *)vj;
316 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800317 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800318
Song Gao85995f02023-09-14 10:26:08 +0800319 for (i = 0; i < oprsz / 16; i++) {
320 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i)),
321 int128_makes64(Vk->D(2 * i)));
322 }
Song Gao2d5f9502023-05-04 20:27:35 +0800323}
324
325DO_EVEN_U_S(vaddwev_h_bu_b, 16, H, UH, B, UB, DO_ADD)
326DO_EVEN_U_S(vaddwev_w_hu_h, 32, W, UW, H, UH, DO_ADD)
327DO_EVEN_U_S(vaddwev_d_wu_w, 64, D, UD, W, UW, DO_ADD)
328
Song Gao85995f02023-09-14 10:26:08 +0800329void HELPER(vaddwod_q_du_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gao2d5f9502023-05-04 20:27:35 +0800330{
Song Gao85995f02023-09-14 10:26:08 +0800331 int i;
Song Gao2d5f9502023-05-04 20:27:35 +0800332 VReg *Vd = (VReg *)vd;
333 VReg *Vj = (VReg *)vj;
334 VReg *Vk = (VReg *)vk;
Song Gao85995f02023-09-14 10:26:08 +0800335 int oprsz = simd_oprsz(desc);
Song Gao2d5f9502023-05-04 20:27:35 +0800336
Song Gao85995f02023-09-14 10:26:08 +0800337 for (i = 0; i < oprsz / 16; i++) {
338 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i + 1)),
339 int128_makes64(Vk->D(2 * i + 1)));
340 }
Song Gao2d5f9502023-05-04 20:27:35 +0800341}
342
343DO_ODD_U_S(vaddwod_h_bu_b, 16, H, UH, B, UB, DO_ADD)
344DO_ODD_U_S(vaddwod_w_hu_h, 32, W, UW, H, UH, DO_ADD)
345DO_ODD_U_S(vaddwod_d_wu_w, 64, D, UD, W, UW, DO_ADD)
Song Gao39e9b0a2023-05-04 20:27:36 +0800346
Song Gaoee7250d2023-09-14 10:26:09 +0800347#define DO_3OP(NAME, BIT, E, DO_OP) \
348void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
349{ \
350 int i; \
351 VReg *Vd = (VReg *)vd; \
352 VReg *Vj = (VReg *)vj; \
353 VReg *Vk = (VReg *)vk; \
354 int oprsz = simd_oprsz(desc); \
355 \
356 for (i = 0; i < oprsz / (BIT / 8); i++) { \
357 Vd->E(i) = DO_OP(Vj->E(i), Vk->E(i)); \
358 } \
Song Gao39e9b0a2023-05-04 20:27:36 +0800359}
360
361DO_3OP(vavg_b, 8, B, DO_VAVG)
362DO_3OP(vavg_h, 16, H, DO_VAVG)
363DO_3OP(vavg_w, 32, W, DO_VAVG)
364DO_3OP(vavg_d, 64, D, DO_VAVG)
365DO_3OP(vavgr_b, 8, B, DO_VAVGR)
366DO_3OP(vavgr_h, 16, H, DO_VAVGR)
367DO_3OP(vavgr_w, 32, W, DO_VAVGR)
368DO_3OP(vavgr_d, 64, D, DO_VAVGR)
369DO_3OP(vavg_bu, 8, UB, DO_VAVG)
370DO_3OP(vavg_hu, 16, UH, DO_VAVG)
371DO_3OP(vavg_wu, 32, UW, DO_VAVG)
372DO_3OP(vavg_du, 64, UD, DO_VAVG)
373DO_3OP(vavgr_bu, 8, UB, DO_VAVGR)
374DO_3OP(vavgr_hu, 16, UH, DO_VAVGR)
375DO_3OP(vavgr_wu, 32, UW, DO_VAVGR)
376DO_3OP(vavgr_du, 64, UD, DO_VAVGR)
Song Gao49725652023-05-04 20:27:37 +0800377
Song Gao49725652023-05-04 20:27:37 +0800378DO_3OP(vabsd_b, 8, B, DO_VABSD)
379DO_3OP(vabsd_h, 16, H, DO_VABSD)
380DO_3OP(vabsd_w, 32, W, DO_VABSD)
381DO_3OP(vabsd_d, 64, D, DO_VABSD)
382DO_3OP(vabsd_bu, 8, UB, DO_VABSD)
383DO_3OP(vabsd_hu, 16, UH, DO_VABSD)
384DO_3OP(vabsd_wu, 32, UW, DO_VABSD)
385DO_3OP(vabsd_du, 64, UD, DO_VABSD)
Song Gaoaf448cb2023-05-04 20:27:38 +0800386
Song Gao27f54852023-09-14 10:26:11 +0800387#define DO_VADDA(NAME, BIT, E) \
388void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
389{ \
390 int i; \
391 VReg *Vd = (VReg *)vd; \
392 VReg *Vj = (VReg *)vj; \
393 VReg *Vk = (VReg *)vk; \
394 int oprsz = simd_oprsz(desc); \
395 \
396 for (i = 0; i < oprsz / (BIT / 8); i++) { \
397 Vd->E(i) = DO_VABS(Vj->E(i)) + DO_VABS(Vk->E(i)); \
398 } \
Song Gaoaf448cb2023-05-04 20:27:38 +0800399}
400
Song Gao27f54852023-09-14 10:26:11 +0800401DO_VADDA(vadda_b, 8, B)
402DO_VADDA(vadda_h, 16, H)
403DO_VADDA(vadda_w, 32, W)
404DO_VADDA(vadda_d, 64, D)
Song Gao9ab29522023-05-04 20:27:39 +0800405
Song Gaoc09360f2023-09-14 10:26:12 +0800406#define VMINMAXI(NAME, BIT, E, DO_OP) \
407void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
408{ \
409 int i; \
410 VReg *Vd = (VReg *)vd; \
411 VReg *Vj = (VReg *)vj; \
412 typedef __typeof(Vd->E(0)) TD; \
413 int oprsz = simd_oprsz(desc); \
414 \
415 for (i = 0; i < oprsz / (BIT / 8); i++) { \
416 Vd->E(i) = DO_OP(Vj->E(i), (TD)imm); \
417 } \
Song Gao9ab29522023-05-04 20:27:39 +0800418}
419
420VMINMAXI(vmini_b, 8, B, DO_MIN)
421VMINMAXI(vmini_h, 16, H, DO_MIN)
422VMINMAXI(vmini_w, 32, W, DO_MIN)
423VMINMAXI(vmini_d, 64, D, DO_MIN)
424VMINMAXI(vmaxi_b, 8, B, DO_MAX)
425VMINMAXI(vmaxi_h, 16, H, DO_MAX)
426VMINMAXI(vmaxi_w, 32, W, DO_MAX)
427VMINMAXI(vmaxi_d, 64, D, DO_MAX)
428VMINMAXI(vmini_bu, 8, UB, DO_MIN)
429VMINMAXI(vmini_hu, 16, UH, DO_MIN)
430VMINMAXI(vmini_wu, 32, UW, DO_MIN)
431VMINMAXI(vmini_du, 64, UD, DO_MIN)
432VMINMAXI(vmaxi_bu, 8, UB, DO_MAX)
433VMINMAXI(vmaxi_hu, 16, UH, DO_MAX)
434VMINMAXI(vmaxi_wu, 32, UW, DO_MAX)
435VMINMAXI(vmaxi_du, 64, UD, DO_MAX)
Song Gaocd1c49a2023-05-04 20:27:40 +0800436
Song Gao342dc1c2023-09-14 10:26:13 +0800437#define DO_VMUH(NAME, BIT, E1, E2, DO_OP) \
438void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
439{ \
440 int i; \
441 VReg *Vd = (VReg *)vd; \
442 VReg *Vj = (VReg *)vj; \
443 VReg *Vk = (VReg *)vk; \
444 typedef __typeof(Vd->E1(0)) T; \
445 int oprsz = simd_oprsz(desc); \
446 \
447 for (i = 0; i < oprsz / (BIT / 8); i++) { \
448 Vd->E2(i) = ((T)Vj->E2(i)) * ((T)Vk->E2(i)) >> BIT; \
449 } \
Song Gaocd1c49a2023-05-04 20:27:40 +0800450}
451
Song Gao342dc1c2023-09-14 10:26:13 +0800452void HELPER(vmuh_d)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gaocd1c49a2023-05-04 20:27:40 +0800453{
Song Gao342dc1c2023-09-14 10:26:13 +0800454 int i;
455 uint64_t l, h;
Song Gaocd1c49a2023-05-04 20:27:40 +0800456 VReg *Vd = (VReg *)vd;
457 VReg *Vj = (VReg *)vj;
458 VReg *Vk = (VReg *)vk;
Song Gao342dc1c2023-09-14 10:26:13 +0800459 int oprsz = simd_oprsz(desc);
Song Gaocd1c49a2023-05-04 20:27:40 +0800460
Song Gao342dc1c2023-09-14 10:26:13 +0800461 for (i = 0; i < oprsz / 8; i++) {
462 muls64(&l, &h, Vj->D(i), Vk->D(i));
463 Vd->D(i) = h;
464 }
Song Gaocd1c49a2023-05-04 20:27:40 +0800465}
466
467DO_VMUH(vmuh_b, 8, H, B, DO_MUH)
468DO_VMUH(vmuh_h, 16, W, H, DO_MUH)
469DO_VMUH(vmuh_w, 32, D, W, DO_MUH)
470
Song Gao342dc1c2023-09-14 10:26:13 +0800471void HELPER(vmuh_du)(void *vd, void *vj, void *vk, uint32_t desc)
Song Gaocd1c49a2023-05-04 20:27:40 +0800472{
Song Gao342dc1c2023-09-14 10:26:13 +0800473 int i;
474 uint64_t l, h;
Song Gaocd1c49a2023-05-04 20:27:40 +0800475 VReg *Vd = (VReg *)vd;
476 VReg *Vj = (VReg *)vj;
477 VReg *Vk = (VReg *)vk;
Song Gao342dc1c2023-09-14 10:26:13 +0800478 int oprsz = simd_oprsz(desc);
Song Gaocd1c49a2023-05-04 20:27:40 +0800479
Song Gao342dc1c2023-09-14 10:26:13 +0800480 for (i = 0; i < oprsz / 8; i++) {
481 mulu64(&l, &h, Vj->D(i), Vk->D(i));
482 Vd->D(i) = h;
483 }
Song Gaocd1c49a2023-05-04 20:27:40 +0800484}
485
486DO_VMUH(vmuh_bu, 8, UH, UB, DO_MUH)
487DO_VMUH(vmuh_hu, 16, UW, UH, DO_MUH)
488DO_VMUH(vmuh_wu, 32, UD, UW, DO_MUH)
489
Song Gaocd1c49a2023-05-04 20:27:40 +0800490DO_EVEN(vmulwev_h_b, 16, H, B, DO_MUL)
491DO_EVEN(vmulwev_w_h, 32, W, H, DO_MUL)
492DO_EVEN(vmulwev_d_w, 64, D, W, DO_MUL)
493
494DO_ODD(vmulwod_h_b, 16, H, B, DO_MUL)
495DO_ODD(vmulwod_w_h, 32, W, H, DO_MUL)
496DO_ODD(vmulwod_d_w, 64, D, W, DO_MUL)
497
498DO_EVEN(vmulwev_h_bu, 16, UH, UB, DO_MUL)
499DO_EVEN(vmulwev_w_hu, 32, UW, UH, DO_MUL)
500DO_EVEN(vmulwev_d_wu, 64, UD, UW, DO_MUL)
501
502DO_ODD(vmulwod_h_bu, 16, UH, UB, DO_MUL)
503DO_ODD(vmulwod_w_hu, 32, UW, UH, DO_MUL)
504DO_ODD(vmulwod_d_wu, 64, UD, UW, DO_MUL)
505
506DO_EVEN_U_S(vmulwev_h_bu_b, 16, H, UH, B, UB, DO_MUL)
507DO_EVEN_U_S(vmulwev_w_hu_h, 32, W, UW, H, UH, DO_MUL)
508DO_EVEN_U_S(vmulwev_d_wu_w, 64, D, UD, W, UW, DO_MUL)
509
510DO_ODD_U_S(vmulwod_h_bu_b, 16, H, UH, B, UB, DO_MUL)
511DO_ODD_U_S(vmulwod_w_hu_h, 32, W, UW, H, UH, DO_MUL)
512DO_ODD_U_S(vmulwod_d_wu_w, 64, D, UD, W, UW, DO_MUL)
Song Gaod3aec652023-05-04 20:27:41 +0800513
Song Gao3f450c12023-09-14 10:26:14 +0800514#define VMADDSUB(NAME, BIT, E, DO_OP) \
515void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
516{ \
517 int i; \
518 VReg *Vd = (VReg *)vd; \
519 VReg *Vj = (VReg *)vj; \
520 VReg *Vk = (VReg *)vk; \
521 int oprsz = simd_oprsz(desc); \
522 \
523 for (i = 0; i < oprsz / (BIT / 8); i++) { \
524 Vd->E(i) = DO_OP(Vd->E(i), Vj->E(i) ,Vk->E(i)); \
525 } \
Song Gaod3aec652023-05-04 20:27:41 +0800526}
527
528VMADDSUB(vmadd_b, 8, B, DO_MADD)
529VMADDSUB(vmadd_h, 16, H, DO_MADD)
530VMADDSUB(vmadd_w, 32, W, DO_MADD)
531VMADDSUB(vmadd_d, 64, D, DO_MADD)
532VMADDSUB(vmsub_b, 8, B, DO_MSUB)
533VMADDSUB(vmsub_h, 16, H, DO_MSUB)
534VMADDSUB(vmsub_w, 32, W, DO_MSUB)
535VMADDSUB(vmsub_d, 64, D, DO_MSUB)
536
537#define VMADDWEV(NAME, BIT, E1, E2, DO_OP) \
Song Gao3f450c12023-09-14 10:26:14 +0800538void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gaod3aec652023-05-04 20:27:41 +0800539{ \
540 int i; \
541 VReg *Vd = (VReg *)vd; \
542 VReg *Vj = (VReg *)vj; \
543 VReg *Vk = (VReg *)vk; \
544 typedef __typeof(Vd->E1(0)) TD; \
Song Gao3f450c12023-09-14 10:26:14 +0800545 int oprsz = simd_oprsz(desc); \
Song Gaod3aec652023-05-04 20:27:41 +0800546 \
Song Gao3f450c12023-09-14 10:26:14 +0800547 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gaod3aec652023-05-04 20:27:41 +0800548 Vd->E1(i) += DO_OP((TD)Vj->E2(2 * i), (TD)Vk->E2(2 * i)); \
549 } \
550}
551
552VMADDWEV(vmaddwev_h_b, 16, H, B, DO_MUL)
553VMADDWEV(vmaddwev_w_h, 32, W, H, DO_MUL)
554VMADDWEV(vmaddwev_d_w, 64, D, W, DO_MUL)
555VMADDWEV(vmaddwev_h_bu, 16, UH, UB, DO_MUL)
556VMADDWEV(vmaddwev_w_hu, 32, UW, UH, DO_MUL)
557VMADDWEV(vmaddwev_d_wu, 64, UD, UW, DO_MUL)
558
Song Gao3f450c12023-09-14 10:26:14 +0800559#define VMADDWOD(NAME, BIT, E1, E2, DO_OP) \
560void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
561{ \
562 int i; \
563 VReg *Vd = (VReg *)vd; \
564 VReg *Vj = (VReg *)vj; \
565 VReg *Vk = (VReg *)vk; \
566 typedef __typeof(Vd->E1(0)) TD; \
567 int oprsz = simd_oprsz(desc); \
568 \
569 for (i = 0; i < oprsz / (BIT / 8); i++) { \
570 Vd->E1(i) += DO_OP((TD)Vj->E2(2 * i + 1), \
571 (TD)Vk->E2(2 * i + 1)); \
572 } \
Song Gaod3aec652023-05-04 20:27:41 +0800573}
574
575VMADDWOD(vmaddwod_h_b, 16, H, B, DO_MUL)
576VMADDWOD(vmaddwod_w_h, 32, W, H, DO_MUL)
577VMADDWOD(vmaddwod_d_w, 64, D, W, DO_MUL)
578VMADDWOD(vmaddwod_h_bu, 16, UH, UB, DO_MUL)
579VMADDWOD(vmaddwod_w_hu, 32, UW, UH, DO_MUL)
580VMADDWOD(vmaddwod_d_wu, 64, UD, UW, DO_MUL)
581
Song Gao3f450c12023-09-14 10:26:14 +0800582#define VMADDWEV_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
583void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
584{ \
585 int i; \
586 VReg *Vd = (VReg *)vd; \
587 VReg *Vj = (VReg *)vj; \
588 VReg *Vk = (VReg *)vk; \
589 typedef __typeof(Vd->ES1(0)) TS1; \
590 typedef __typeof(Vd->EU1(0)) TU1; \
591 int oprsz = simd_oprsz(desc); \
592 \
593 for (i = 0; i < oprsz / (BIT / 8); i++) { \
594 Vd->ES1(i) += DO_OP((TU1)Vj->EU2(2 * i), \
595 (TS1)Vk->ES2(2 * i)); \
596 } \
Song Gaod3aec652023-05-04 20:27:41 +0800597}
598
599VMADDWEV_U_S(vmaddwev_h_bu_b, 16, H, UH, B, UB, DO_MUL)
600VMADDWEV_U_S(vmaddwev_w_hu_h, 32, W, UW, H, UH, DO_MUL)
601VMADDWEV_U_S(vmaddwev_d_wu_w, 64, D, UD, W, UW, DO_MUL)
602
Song Gao3f450c12023-09-14 10:26:14 +0800603#define VMADDWOD_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
604void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
605{ \
606 int i; \
607 VReg *Vd = (VReg *)vd; \
608 VReg *Vj = (VReg *)vj; \
609 VReg *Vk = (VReg *)vk; \
610 typedef __typeof(Vd->ES1(0)) TS1; \
611 typedef __typeof(Vd->EU1(0)) TU1; \
612 int oprsz = simd_oprsz(desc); \
613 \
614 for (i = 0; i < oprsz / (BIT / 8); i++) { \
615 Vd->ES1(i) += DO_OP((TU1)Vj->EU2(2 * i + 1), \
616 (TS1)Vk->ES2(2 * i + 1)); \
617 } \
Song Gaod3aec652023-05-04 20:27:41 +0800618}
619
620VMADDWOD_U_S(vmaddwod_h_bu_b, 16, H, UH, B, UB, DO_MUL)
621VMADDWOD_U_S(vmaddwod_w_hu_h, 32, W, UW, H, UH, DO_MUL)
622VMADDWOD_U_S(vmaddwod_d_wu_w, 64, D, UD, W, UW, DO_MUL)
Song Gao4cc4c0f2023-05-04 20:27:42 +0800623
Song Gao04711da2023-09-14 10:25:54 +0800624#define VDIV(NAME, BIT, E, DO_OP) \
625void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
626{ \
627 int i; \
628 VReg *Vd = (VReg *)vd; \
629 VReg *Vj = (VReg *)vj; \
630 VReg *Vk = (VReg *)vk; \
Song Gaoabb693d2023-09-14 10:26:15 +0800631 int oprsz = simd_oprsz(desc); \
632 \
633 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao04711da2023-09-14 10:25:54 +0800634 Vd->E(i) = DO_OP(Vj->E(i), Vk->E(i)); \
635 } \
Song Gao4cc4c0f2023-05-04 20:27:42 +0800636}
637
638VDIV(vdiv_b, 8, B, DO_DIV)
639VDIV(vdiv_h, 16, H, DO_DIV)
640VDIV(vdiv_w, 32, W, DO_DIV)
641VDIV(vdiv_d, 64, D, DO_DIV)
642VDIV(vdiv_bu, 8, UB, DO_DIVU)
643VDIV(vdiv_hu, 16, UH, DO_DIVU)
644VDIV(vdiv_wu, 32, UW, DO_DIVU)
645VDIV(vdiv_du, 64, UD, DO_DIVU)
646VDIV(vmod_b, 8, B, DO_REM)
647VDIV(vmod_h, 16, H, DO_REM)
648VDIV(vmod_w, 32, W, DO_REM)
649VDIV(vmod_d, 64, D, DO_REM)
650VDIV(vmod_bu, 8, UB, DO_REMU)
651VDIV(vmod_hu, 16, UH, DO_REMU)
652VDIV(vmod_wu, 32, UW, DO_REMU)
653VDIV(vmod_du, 64, UD, DO_REMU)
Song Gaocbe44192023-05-04 20:27:43 +0800654
Song Gaoe5c7f032023-09-14 10:26:16 +0800655#define VSAT_S(NAME, BIT, E) \
656void HELPER(NAME)(void *vd, void *vj, uint64_t max, uint32_t desc) \
657{ \
658 int i; \
659 VReg *Vd = (VReg *)vd; \
660 VReg *Vj = (VReg *)vj; \
661 typedef __typeof(Vd->E(0)) TD; \
662 int oprsz = simd_oprsz(desc); \
663 \
664 for (i = 0; i < oprsz / (BIT / 8); i++) { \
665 Vd->E(i) = Vj->E(i) > (TD)max ? (TD)max : \
666 Vj->E(i) < (TD)~max ? (TD)~max: Vj->E(i); \
667 } \
Song Gaocbe44192023-05-04 20:27:43 +0800668}
669
670VSAT_S(vsat_b, 8, B)
671VSAT_S(vsat_h, 16, H)
672VSAT_S(vsat_w, 32, W)
673VSAT_S(vsat_d, 64, D)
674
Song Gaoe5c7f032023-09-14 10:26:16 +0800675#define VSAT_U(NAME, BIT, E) \
676void HELPER(NAME)(void *vd, void *vj, uint64_t max, uint32_t desc) \
677{ \
678 int i; \
679 VReg *Vd = (VReg *)vd; \
680 VReg *Vj = (VReg *)vj; \
681 typedef __typeof(Vd->E(0)) TD; \
682 int oprsz = simd_oprsz(desc); \
683 \
684 for (i = 0; i < oprsz / (BIT / 8); i++) { \
685 Vd->E(i) = Vj->E(i) > (TD)max ? (TD)max : Vj->E(i); \
686 } \
Song Gaocbe44192023-05-04 20:27:43 +0800687}
688
689VSAT_U(vsat_bu, 8, UB)
690VSAT_U(vsat_hu, 16, UH)
691VSAT_U(vsat_wu, 32, UW)
692VSAT_U(vsat_du, 64, UD)
Song Gao3734ad92023-05-04 20:27:44 +0800693
Song Gaof0db0be2023-09-14 10:26:17 +0800694#define VEXTH(NAME, BIT, E1, E2) \
695void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
696{ \
697 int i, j, ofs; \
698 VReg *Vd = (VReg *)vd; \
699 VReg *Vj = (VReg *)vj; \
700 int oprsz = simd_oprsz(desc); \
701 \
702 ofs = LSX_LEN / BIT; \
703 for (i = 0; i < oprsz / 16; i++) { \
704 for (j = 0; j < ofs; j++) { \
705 Vd->E1(j + i * ofs) = Vj->E2(j + ofs + ofs * 2 * i); \
706 } \
707 } \
Song Gao3734ad92023-05-04 20:27:44 +0800708}
709
Song Gaoff27e332023-09-14 10:25:56 +0800710void HELPER(vexth_q_d)(void *vd, void *vj, uint32_t desc)
Song Gao3734ad92023-05-04 20:27:44 +0800711{
Song Gaof0db0be2023-09-14 10:26:17 +0800712 int i;
Song Gaoff27e332023-09-14 10:25:56 +0800713 VReg *Vd = (VReg *)vd;
714 VReg *Vj = (VReg *)vj;
Song Gaof0db0be2023-09-14 10:26:17 +0800715 int oprsz = simd_oprsz(desc);
Song Gao3734ad92023-05-04 20:27:44 +0800716
Song Gaof0db0be2023-09-14 10:26:17 +0800717 for (i = 0; i < oprsz / 16; i++) {
718 Vd->Q(i) = int128_makes64(Vj->D(2 * i + 1));
719 }
Song Gao3734ad92023-05-04 20:27:44 +0800720}
721
Song Gaoff27e332023-09-14 10:25:56 +0800722void HELPER(vexth_qu_du)(void *vd, void *vj, uint32_t desc)
Song Gao3734ad92023-05-04 20:27:44 +0800723{
Song Gaof0db0be2023-09-14 10:26:17 +0800724 int i;
Song Gaoff27e332023-09-14 10:25:56 +0800725 VReg *Vd = (VReg *)vd;
726 VReg *Vj = (VReg *)vj;
Song Gaof0db0be2023-09-14 10:26:17 +0800727 int oprsz = simd_oprsz(desc);
Song Gao3734ad92023-05-04 20:27:44 +0800728
Song Gaof0db0be2023-09-14 10:26:17 +0800729 for (i = 0; i < oprsz / 16; i++) {
730 Vd->Q(i) = int128_make64(Vj->UD(2 * i + 1));
731 }
Song Gao3734ad92023-05-04 20:27:44 +0800732}
733
734VEXTH(vexth_h_b, 16, H, B)
735VEXTH(vexth_w_h, 32, W, H)
736VEXTH(vexth_d_w, 64, D, W)
737VEXTH(vexth_hu_bu, 16, UH, UB)
738VEXTH(vexth_wu_hu, 32, UW, UH)
739VEXTH(vexth_du_wu, 64, UD, UW)
Song Gaof0e395d2023-05-04 20:27:45 +0800740
Song Gao790acb22023-09-14 10:26:18 +0800741#define VEXT2XV(NAME, BIT, E1, E2) \
742void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
743{ \
744 int i; \
745 VReg temp = {}; \
746 VReg *Vd = (VReg *)vd; \
747 VReg *Vj = (VReg *)vj; \
748 int oprsz = simd_oprsz(desc); \
749 \
750 for (i = 0; i < oprsz / (BIT / 8); i++) { \
751 temp.E1(i) = Vj->E2(i); \
752 } \
753 *Vd = temp; \
754}
755
756VEXT2XV(vext2xv_h_b, 16, H, B)
757VEXT2XV(vext2xv_w_b, 32, W, B)
758VEXT2XV(vext2xv_d_b, 64, D, B)
759VEXT2XV(vext2xv_w_h, 32, W, H)
760VEXT2XV(vext2xv_d_h, 64, D, H)
761VEXT2XV(vext2xv_d_w, 64, D, W)
762VEXT2XV(vext2xv_hu_bu, 16, UH, UB)
763VEXT2XV(vext2xv_wu_bu, 32, UW, UB)
764VEXT2XV(vext2xv_du_bu, 64, UD, UB)
765VEXT2XV(vext2xv_wu_hu, 32, UW, UH)
766VEXT2XV(vext2xv_du_hu, 64, UD, UH)
767VEXT2XV(vext2xv_du_wu, 64, UD, UW)
768
Song Gaof0e395d2023-05-04 20:27:45 +0800769DO_3OP(vsigncov_b, 8, B, DO_SIGNCOV)
770DO_3OP(vsigncov_h, 16, H, DO_SIGNCOV)
771DO_3OP(vsigncov_w, 32, W, DO_SIGNCOV)
772DO_3OP(vsigncov_d, 64, D, DO_SIGNCOV)
Song Gao789f4a42023-05-04 20:27:46 +0800773
774static uint64_t do_vmskltz_b(int64_t val)
775{
776 uint64_t m = 0x8080808080808080ULL;
777 uint64_t c = val & m;
778 c |= c << 7;
779 c |= c << 14;
780 c |= c << 28;
781 return c >> 56;
782}
783
Song Gaoff27e332023-09-14 10:25:56 +0800784void HELPER(vmskltz_b)(void *vd, void *vj, uint32_t desc)
Song Gao789f4a42023-05-04 20:27:46 +0800785{
Song Gao97074672023-09-14 10:26:20 +0800786 int i;
Song Gao789f4a42023-05-04 20:27:46 +0800787 uint16_t temp = 0;
Song Gaoff27e332023-09-14 10:25:56 +0800788 VReg *Vd = (VReg *)vd;
789 VReg *Vj = (VReg *)vj;
Song Gao97074672023-09-14 10:26:20 +0800790 int oprsz = simd_oprsz(desc);
Song Gao789f4a42023-05-04 20:27:46 +0800791
Song Gao97074672023-09-14 10:26:20 +0800792 for (i = 0; i < oprsz / 16; i++) {
793 temp = 0;
794 temp = do_vmskltz_b(Vj->D(2 * i));
795 temp |= (do_vmskltz_b(Vj->D(2 * i + 1)) << 8);
796 Vd->D(2 * i) = temp;
797 Vd->D(2 * i + 1) = 0;
798 }
Song Gao789f4a42023-05-04 20:27:46 +0800799}
800
801static uint64_t do_vmskltz_h(int64_t val)
802{
803 uint64_t m = 0x8000800080008000ULL;
804 uint64_t c = val & m;
805 c |= c << 15;
806 c |= c << 30;
807 return c >> 60;
808}
809
Song Gaoff27e332023-09-14 10:25:56 +0800810void HELPER(vmskltz_h)(void *vd, void *vj, uint32_t desc)
Song Gao789f4a42023-05-04 20:27:46 +0800811{
Song Gao97074672023-09-14 10:26:20 +0800812 int i;
Song Gao789f4a42023-05-04 20:27:46 +0800813 uint16_t temp = 0;
Song Gaoff27e332023-09-14 10:25:56 +0800814 VReg *Vd = (VReg *)vd;
815 VReg *Vj = (VReg *)vj;
Song Gao97074672023-09-14 10:26:20 +0800816 int oprsz = simd_oprsz(desc);
Song Gao789f4a42023-05-04 20:27:46 +0800817
Song Gao97074672023-09-14 10:26:20 +0800818 for (i = 0; i < oprsz / 16; i++) {
819 temp = 0;
820 temp = do_vmskltz_h(Vj->D(2 * i));
821 temp |= (do_vmskltz_h(Vj->D(2 * i + 1)) << 4);
822 Vd->D(2 * i) = temp;
823 Vd->D(2 * i + 1) = 0;
824 }
Song Gao789f4a42023-05-04 20:27:46 +0800825}
826
827static uint64_t do_vmskltz_w(int64_t val)
828{
829 uint64_t m = 0x8000000080000000ULL;
830 uint64_t c = val & m;
831 c |= c << 31;
832 return c >> 62;
833}
834
Song Gaoff27e332023-09-14 10:25:56 +0800835void HELPER(vmskltz_w)(void *vd, void *vj, uint32_t desc)
Song Gao789f4a42023-05-04 20:27:46 +0800836{
Song Gao97074672023-09-14 10:26:20 +0800837 int i;
Song Gao789f4a42023-05-04 20:27:46 +0800838 uint16_t temp = 0;
Song Gaoff27e332023-09-14 10:25:56 +0800839 VReg *Vd = (VReg *)vd;
840 VReg *Vj = (VReg *)vj;
Song Gao97074672023-09-14 10:26:20 +0800841 int oprsz = simd_oprsz(desc);
Song Gao789f4a42023-05-04 20:27:46 +0800842
Song Gao97074672023-09-14 10:26:20 +0800843 for (i = 0; i < oprsz / 16; i++) {
844 temp = 0;
845 temp = do_vmskltz_w(Vj->D(2 * i));
846 temp |= (do_vmskltz_w(Vj->D(2 * i + 1)) << 2);
847 Vd->D(2 * i) = temp;
848 Vd->D(2 * i + 1) = 0;
849 }
Song Gao789f4a42023-05-04 20:27:46 +0800850}
851
852static uint64_t do_vmskltz_d(int64_t val)
853{
854 return (uint64_t)val >> 63;
855}
Song Gaoff27e332023-09-14 10:25:56 +0800856void HELPER(vmskltz_d)(void *vd, void *vj, uint32_t desc)
Song Gao789f4a42023-05-04 20:27:46 +0800857{
Song Gao97074672023-09-14 10:26:20 +0800858 int i;
Song Gao789f4a42023-05-04 20:27:46 +0800859 uint16_t temp = 0;
Song Gaoff27e332023-09-14 10:25:56 +0800860 VReg *Vd = (VReg *)vd;
861 VReg *Vj = (VReg *)vj;
Song Gao97074672023-09-14 10:26:20 +0800862 int oprsz = simd_oprsz(desc);
Song Gao789f4a42023-05-04 20:27:46 +0800863
Song Gao97074672023-09-14 10:26:20 +0800864 for (i = 0; i < oprsz / 16; i++) {
865 temp = 0;
866 temp = do_vmskltz_d(Vj->D(2 * i));
867 temp |= (do_vmskltz_d(Vj->D(2 * i + 1)) << 1);
868 Vd->D(2 * i) = temp;
869 Vd->D(2 * i + 1) = 0;
870 }
Song Gao789f4a42023-05-04 20:27:46 +0800871}
872
Song Gaoff27e332023-09-14 10:25:56 +0800873void HELPER(vmskgez_b)(void *vd, void *vj, uint32_t desc)
Song Gao789f4a42023-05-04 20:27:46 +0800874{
Song Gao97074672023-09-14 10:26:20 +0800875 int i;
Song Gao789f4a42023-05-04 20:27:46 +0800876 uint16_t temp = 0;
Song Gaoff27e332023-09-14 10:25:56 +0800877 VReg *Vd = (VReg *)vd;
878 VReg *Vj = (VReg *)vj;
Song Gao97074672023-09-14 10:26:20 +0800879 int oprsz = simd_oprsz(desc);
Song Gao789f4a42023-05-04 20:27:46 +0800880
Song Gao97074672023-09-14 10:26:20 +0800881 for (i = 0; i < oprsz / 16; i++) {
882 temp = 0;
883 temp = do_vmskltz_b(Vj->D(2 * i));
884 temp |= (do_vmskltz_b(Vj->D(2 * i + 1)) << 8);
885 Vd->D(2 * i) = (uint16_t)(~temp);
886 Vd->D(2 * i + 1) = 0;
887 }
Song Gao789f4a42023-05-04 20:27:46 +0800888}
889
890static uint64_t do_vmskez_b(uint64_t a)
891{
892 uint64_t m = 0x7f7f7f7f7f7f7f7fULL;
893 uint64_t c = ~(((a & m) + m) | a | m);
894 c |= c << 7;
895 c |= c << 14;
896 c |= c << 28;
897 return c >> 56;
898}
899
Song Gaoff27e332023-09-14 10:25:56 +0800900void HELPER(vmsknz_b)(void *vd, void *vj, uint32_t desc)
Song Gao789f4a42023-05-04 20:27:46 +0800901{
Song Gao97074672023-09-14 10:26:20 +0800902 int i;
Song Gao789f4a42023-05-04 20:27:46 +0800903 uint16_t temp = 0;
Song Gaoff27e332023-09-14 10:25:56 +0800904 VReg *Vd = (VReg *)vd;
905 VReg *Vj = (VReg *)vj;
Song Gao97074672023-09-14 10:26:20 +0800906 int oprsz = simd_oprsz(desc);
Song Gao789f4a42023-05-04 20:27:46 +0800907
Song Gao97074672023-09-14 10:26:20 +0800908 for (i = 0; i < oprsz / 16; i++) {
909 temp = 0;
910 temp = do_vmskez_b(Vj->D(2 * i));
911 temp |= (do_vmskez_b(Vj->D(2 * i + 1)) << 8);
912 Vd->D(2 * i) = (uint16_t)(~temp);
913 Vd->D(2 * i + 1) = 0;
914 }
Song Gao789f4a42023-05-04 20:27:46 +0800915}
Song Gaof205a532023-05-04 20:27:47 +0800916
Song Gao4472a452023-09-14 10:26:22 +0800917void HELPER(vnori_b)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaof205a532023-05-04 20:27:47 +0800918{
919 int i;
920 VReg *Vd = (VReg *)vd;
921 VReg *Vj = (VReg *)vj;
922
Song Gao4472a452023-09-14 10:26:22 +0800923 for (i = 0; i < simd_oprsz(desc); i++) {
Song Gaof205a532023-05-04 20:27:47 +0800924 Vd->B(i) = ~(Vj->B(i) | (uint8_t)imm);
925 }
926}
Song Gao9b21a7a2023-05-04 20:27:49 +0800927
Song Gao6567eac2023-09-14 10:26:24 +0800928#define VSLLWIL(NAME, BIT, E1, E2) \
929void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
930{ \
931 int i, j, ofs; \
932 VReg temp = {}; \
933 VReg *Vd = (VReg *)vd; \
934 VReg *Vj = (VReg *)vj; \
935 int oprsz = simd_oprsz(desc); \
936 typedef __typeof(temp.E1(0)) TD; \
937 \
938 ofs = LSX_LEN / BIT; \
939 for (i = 0; i < oprsz / 16; i++) { \
940 for (j = 0; j < ofs; j++) { \
941 temp.E1(j + ofs * i) = (TD)Vj->E2(j + ofs * 2 * i) << (imm % BIT); \
942 } \
943 } \
944 *Vd = temp; \
Song Gao9b21a7a2023-05-04 20:27:49 +0800945}
946
Song Gao6567eac2023-09-14 10:26:24 +0800947
Song Gaoff27e332023-09-14 10:25:56 +0800948void HELPER(vextl_q_d)(void *vd, void *vj, uint32_t desc)
Song Gao9b21a7a2023-05-04 20:27:49 +0800949{
Song Gao6567eac2023-09-14 10:26:24 +0800950 int i;
Song Gaoff27e332023-09-14 10:25:56 +0800951 VReg *Vd = (VReg *)vd;
952 VReg *Vj = (VReg *)vj;
Song Gao6567eac2023-09-14 10:26:24 +0800953 int oprsz = simd_oprsz(desc);
Song Gao9b21a7a2023-05-04 20:27:49 +0800954
Song Gao6567eac2023-09-14 10:26:24 +0800955 for (i = 0; i < oprsz / 16; i++) {
956 Vd->Q(i) = int128_makes64(Vj->D(2 * i));
957 }
Song Gao9b21a7a2023-05-04 20:27:49 +0800958}
959
Song Gaoff27e332023-09-14 10:25:56 +0800960void HELPER(vextl_qu_du)(void *vd, void *vj, uint32_t desc)
Song Gao9b21a7a2023-05-04 20:27:49 +0800961{
Song Gao6567eac2023-09-14 10:26:24 +0800962 int i;
Song Gaoff27e332023-09-14 10:25:56 +0800963 VReg *Vd = (VReg *)vd;
964 VReg *Vj = (VReg *)vj;
Song Gao6567eac2023-09-14 10:26:24 +0800965 int oprsz = simd_oprsz(desc);
Song Gao9b21a7a2023-05-04 20:27:49 +0800966
Song Gao6567eac2023-09-14 10:26:24 +0800967 for (i = 0; i < oprsz / 16; i++) {
968 Vd->Q(i) = int128_make64(Vj->UD(2 * i));
969 }
Song Gao9b21a7a2023-05-04 20:27:49 +0800970}
971
972VSLLWIL(vsllwil_h_b, 16, H, B)
973VSLLWIL(vsllwil_w_h, 32, W, H)
974VSLLWIL(vsllwil_d_w, 64, D, W)
975VSLLWIL(vsllwil_hu_bu, 16, UH, UB)
976VSLLWIL(vsllwil_wu_hu, 32, UW, UH)
977VSLLWIL(vsllwil_du_wu, 64, UD, UW)
Song Gaoecb93712023-05-04 20:27:50 +0800978
979#define do_vsrlr(E, T) \
980static T do_vsrlr_ ##E(T s1, int sh) \
981{ \
982 if (sh == 0) { \
983 return s1; \
984 } else { \
985 return (s1 >> sh) + ((s1 >> (sh - 1)) & 0x1); \
986 } \
987}
988
989do_vsrlr(B, uint8_t)
990do_vsrlr(H, uint16_t)
991do_vsrlr(W, uint32_t)
992do_vsrlr(D, uint64_t)
993
994#define VSRLR(NAME, BIT, T, E) \
Song Gao04711da2023-09-14 10:25:54 +0800995void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gaoecb93712023-05-04 20:27:50 +0800996{ \
997 int i; \
Song Gao04711da2023-09-14 10:25:54 +0800998 VReg *Vd = (VReg *)vd; \
999 VReg *Vj = (VReg *)vj; \
1000 VReg *Vk = (VReg *)vk; \
Song Gao8c272fe2023-09-14 10:26:25 +08001001 int oprsz = simd_oprsz(desc); \
Song Gaoecb93712023-05-04 20:27:50 +08001002 \
Song Gao8c272fe2023-09-14 10:26:25 +08001003 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gaoecb93712023-05-04 20:27:50 +08001004 Vd->E(i) = do_vsrlr_ ## E(Vj->E(i), ((T)Vk->E(i))%BIT); \
1005 } \
1006}
1007
1008VSRLR(vsrlr_b, 8, uint8_t, B)
1009VSRLR(vsrlr_h, 16, uint16_t, H)
1010VSRLR(vsrlr_w, 32, uint32_t, W)
1011VSRLR(vsrlr_d, 64, uint64_t, D)
1012
Song Gao329517d2023-09-14 10:25:57 +08001013#define VSRLRI(NAME, BIT, E) \
1014void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1015{ \
1016 int i; \
1017 VReg *Vd = (VReg *)vd; \
1018 VReg *Vj = (VReg *)vj; \
Song Gao8c272fe2023-09-14 10:26:25 +08001019 int oprsz = simd_oprsz(desc); \
Song Gao329517d2023-09-14 10:25:57 +08001020 \
Song Gao8c272fe2023-09-14 10:26:25 +08001021 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao329517d2023-09-14 10:25:57 +08001022 Vd->E(i) = do_vsrlr_ ## E(Vj->E(i), imm); \
1023 } \
Song Gaoecb93712023-05-04 20:27:50 +08001024}
1025
1026VSRLRI(vsrlri_b, 8, B)
1027VSRLRI(vsrlri_h, 16, H)
1028VSRLRI(vsrlri_w, 32, W)
1029VSRLRI(vsrlri_d, 64, D)
1030
1031#define do_vsrar(E, T) \
1032static T do_vsrar_ ##E(T s1, int sh) \
1033{ \
1034 if (sh == 0) { \
1035 return s1; \
1036 } else { \
1037 return (s1 >> sh) + ((s1 >> (sh - 1)) & 0x1); \
1038 } \
1039}
1040
1041do_vsrar(B, int8_t)
1042do_vsrar(H, int16_t)
1043do_vsrar(W, int32_t)
1044do_vsrar(D, int64_t)
1045
1046#define VSRAR(NAME, BIT, T, E) \
Song Gao04711da2023-09-14 10:25:54 +08001047void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
Song Gaoecb93712023-05-04 20:27:50 +08001048{ \
1049 int i; \
Song Gao04711da2023-09-14 10:25:54 +08001050 VReg *Vd = (VReg *)vd; \
1051 VReg *Vj = (VReg *)vj; \
1052 VReg *Vk = (VReg *)vk; \
Song Gao8c272fe2023-09-14 10:26:25 +08001053 int oprsz = simd_oprsz(desc); \
Song Gaoecb93712023-05-04 20:27:50 +08001054 \
Song Gao8c272fe2023-09-14 10:26:25 +08001055 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gaoecb93712023-05-04 20:27:50 +08001056 Vd->E(i) = do_vsrar_ ## E(Vj->E(i), ((T)Vk->E(i))%BIT); \
1057 } \
1058}
1059
1060VSRAR(vsrar_b, 8, uint8_t, B)
1061VSRAR(vsrar_h, 16, uint16_t, H)
1062VSRAR(vsrar_w, 32, uint32_t, W)
1063VSRAR(vsrar_d, 64, uint64_t, D)
1064
Song Gao329517d2023-09-14 10:25:57 +08001065#define VSRARI(NAME, BIT, E) \
1066void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1067{ \
1068 int i; \
1069 VReg *Vd = (VReg *)vd; \
1070 VReg *Vj = (VReg *)vj; \
Song Gao8c272fe2023-09-14 10:26:25 +08001071 int oprsz = simd_oprsz(desc); \
Song Gao329517d2023-09-14 10:25:57 +08001072 \
Song Gao8c272fe2023-09-14 10:26:25 +08001073 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao329517d2023-09-14 10:25:57 +08001074 Vd->E(i) = do_vsrar_ ## E(Vj->E(i), imm); \
1075 } \
Song Gaoecb93712023-05-04 20:27:50 +08001076}
1077
1078VSRARI(vsrari_b, 8, B)
1079VSRARI(vsrari_h, 16, H)
1080VSRARI(vsrari_w, 32, W)
1081VSRARI(vsrari_d, 64, D)
Song Gaod79fb8d2023-05-04 20:27:51 +08001082
Song Gao40c76742023-09-14 10:26:26 +08001083#define VSRLN(NAME, BIT, E1, E2) \
1084void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1085{ \
1086 int i, j, ofs; \
1087 VReg *Vd = (VReg *)vd; \
1088 VReg *Vj = (VReg *)vj; \
1089 VReg *Vk = (VReg *)vk; \
1090 int oprsz = simd_oprsz(desc); \
1091 \
1092 ofs = LSX_LEN / BIT; \
1093 for (i = 0; i < oprsz / 16; i++) { \
1094 for (j = 0; j < ofs; j++) { \
1095 Vd->E1(j + ofs * 2 * i) = R_SHIFT(Vj->E2(j + ofs * i), \
1096 Vk->E2(j + ofs * i) % BIT); \
1097 } \
1098 Vd->D(2 * i + 1) = 0; \
1099 } \
Song Gaod79fb8d2023-05-04 20:27:51 +08001100}
1101
Song Gao40c76742023-09-14 10:26:26 +08001102VSRLN(vsrln_b_h, 16, B, UH)
1103VSRLN(vsrln_h_w, 32, H, UW)
1104VSRLN(vsrln_w_d, 64, W, UD)
Song Gaod79fb8d2023-05-04 20:27:51 +08001105
Song Gao40c76742023-09-14 10:26:26 +08001106#define VSRAN(NAME, BIT, E1, E2, E3) \
1107void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1108{ \
1109 int i, j, ofs; \
1110 VReg *Vd = (VReg *)vd; \
1111 VReg *Vj = (VReg *)vj; \
1112 VReg *Vk = (VReg *)vk; \
1113 int oprsz = simd_oprsz(desc); \
1114 \
1115 ofs = LSX_LEN / BIT; \
1116 for (i = 0; i < oprsz / 16; i++) { \
1117 for (j = 0; j < ofs; j++) { \
1118 Vd->E1(j + ofs * 2 * i) = R_SHIFT(Vj->E2(j + ofs * i), \
1119 Vk->E3(j + ofs * i) % BIT); \
1120 } \
1121 Vd->D(2 * i + 1) = 0; \
1122 } \
Song Gaod79fb8d2023-05-04 20:27:51 +08001123}
1124
Song Gao40c76742023-09-14 10:26:26 +08001125VSRAN(vsran_b_h, 16, B, H, UH)
1126VSRAN(vsran_h_w, 32, H, W, UW)
1127VSRAN(vsran_w_d, 64, W, D, UD)
Song Gaod79fb8d2023-05-04 20:27:51 +08001128
Song Gao40c76742023-09-14 10:26:26 +08001129#define VSRLNI(NAME, BIT, E1, E2) \
1130void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1131{ \
1132 int i, j, ofs; \
1133 VReg temp = {}; \
1134 VReg *Vd = (VReg *)vd; \
1135 VReg *Vj = (VReg *)vj; \
1136 int oprsz = simd_oprsz(desc); \
1137 \
1138 ofs = LSX_LEN / BIT; \
1139 for (i = 0; i < oprsz / 16; i++) { \
1140 for (j = 0; j < ofs; j++) { \
1141 temp.E1(j + ofs * 2 * i) = R_SHIFT(Vj->E2(j + ofs * i), imm); \
1142 temp.E1(j + ofs * (2 * i + 1)) = R_SHIFT(Vd->E2(j + ofs * i), \
1143 imm); \
1144 } \
1145 } \
1146 *Vd = temp; \
Song Gaod79fb8d2023-05-04 20:27:51 +08001147}
1148
Song Gao329517d2023-09-14 10:25:57 +08001149void HELPER(vsrlni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaod79fb8d2023-05-04 20:27:51 +08001150{
Song Gao40c76742023-09-14 10:26:26 +08001151 int i;
1152 VReg temp = {};
Song Gao329517d2023-09-14 10:25:57 +08001153 VReg *Vd = (VReg *)vd;
1154 VReg *Vj = (VReg *)vj;
Song Gaod79fb8d2023-05-04 20:27:51 +08001155
Song Gao40c76742023-09-14 10:26:26 +08001156 for (i = 0; i < 2; i++) {
1157 temp.D(2 * i) = int128_getlo(int128_urshift(Vj->Q(i), imm % 128));
1158 temp.D(2 * i +1) = int128_getlo(int128_urshift(Vd->Q(i), imm % 128));
1159 }
Song Gaod79fb8d2023-05-04 20:27:51 +08001160 *Vd = temp;
1161}
1162
Song Gao40c76742023-09-14 10:26:26 +08001163VSRLNI(vsrlni_b_h, 16, B, UH)
1164VSRLNI(vsrlni_h_w, 32, H, UW)
1165VSRLNI(vsrlni_w_d, 64, W, UD)
Song Gaod79fb8d2023-05-04 20:27:51 +08001166
Song Gao40c76742023-09-14 10:26:26 +08001167#define VSRANI(NAME, BIT, E1, E2) \
1168void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1169{ \
1170 int i, j, ofs; \
1171 VReg temp = {}; \
1172 VReg *Vd = (VReg *)vd; \
1173 VReg *Vj = (VReg *)vj; \
1174 int oprsz = simd_oprsz(desc); \
1175 \
1176 ofs = LSX_LEN / BIT; \
1177 for (i = 0; i < oprsz / 16; i++) { \
1178 for (j = 0; j < ofs; j++) { \
1179 temp.E1(j + ofs * 2 * i) = R_SHIFT(Vj->E2(j + ofs * i), imm); \
1180 temp.E1(j + ofs * (2 * i + 1)) = R_SHIFT(Vd->E2(j + ofs * i), \
1181 imm); \
1182 } \
1183 } \
1184 *Vd = temp; \
Song Gaod79fb8d2023-05-04 20:27:51 +08001185}
1186
Song Gao329517d2023-09-14 10:25:57 +08001187void HELPER(vsrani_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaod79fb8d2023-05-04 20:27:51 +08001188{
Song Gao40c76742023-09-14 10:26:26 +08001189 int i;
1190 VReg temp = {};
Song Gao329517d2023-09-14 10:25:57 +08001191 VReg *Vd = (VReg *)vd;
1192 VReg *Vj = (VReg *)vj;
Song Gaod79fb8d2023-05-04 20:27:51 +08001193
Song Gao40c76742023-09-14 10:26:26 +08001194 for (i = 0; i < 2; i++) {
1195 temp.D(2 * i) = int128_getlo(int128_rshift(Vj->Q(i), imm % 128));
1196 temp.D(2 * i + 1) = int128_getlo(int128_rshift(Vd->Q(i), imm % 128));
1197 }
Song Gaod79fb8d2023-05-04 20:27:51 +08001198 *Vd = temp;
1199}
1200
1201VSRANI(vsrani_b_h, 16, B, H)
1202VSRANI(vsrani_h_w, 32, H, W)
1203VSRANI(vsrani_w_d, 64, W, D)
Song Gaoa5200a12023-05-04 20:27:52 +08001204
Song Gaoc50ce382023-09-14 10:26:27 +08001205#define VSRLRN(NAME, BIT, E1, E2, E3) \
1206void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1207{ \
1208 int i, j, ofs; \
1209 VReg *Vd = (VReg *)vd; \
1210 VReg *Vj = (VReg *)vj; \
1211 VReg *Vk = (VReg *)vk; \
1212 int oprsz = simd_oprsz(desc); \
1213 \
1214 ofs = LSX_LEN / BIT; \
1215 for (i = 0; i < oprsz / 16; i++) { \
1216 for (j = 0; j < ofs; j++) { \
1217 Vd->E1(j + ofs * 2 * i) = do_vsrlr_ ##E2(Vj->E2(j + ofs * i), \
1218 Vk->E3(j + ofs * i) % BIT); \
1219 } \
1220 Vd->D(2 * i + 1) = 0; \
1221 } \
Song Gaoa5200a12023-05-04 20:27:52 +08001222}
1223
Song Gaoc50ce382023-09-14 10:26:27 +08001224VSRLRN(vsrlrn_b_h, 16, B, H, UH)
1225VSRLRN(vsrlrn_h_w, 32, H, W, UW)
1226VSRLRN(vsrlrn_w_d, 64, W, D, UD)
Song Gaoa5200a12023-05-04 20:27:52 +08001227
Song Gaoc50ce382023-09-14 10:26:27 +08001228#define VSRARN(NAME, BIT, E1, E2, E3) \
1229void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1230{ \
1231 int i, j, ofs; \
1232 VReg *Vd = (VReg *)vd; \
1233 VReg *Vj = (VReg *)vj; \
1234 VReg *Vk = (VReg *)vk; \
1235 int oprsz = simd_oprsz(desc); \
1236 \
1237 ofs = LSX_LEN / BIT; \
1238 for (i = 0; i < oprsz / 16; i++) { \
1239 for (j = 0; j < ofs; j++) { \
1240 Vd->E1(j + ofs * 2 * i) = do_vsrar_ ## E2(Vj->E2(j + ofs * i), \
1241 Vk->E3(j + ofs * i) % BIT); \
1242 } \
1243 Vd->D(2 * i + 1) = 0; \
1244 } \
Song Gaoa5200a12023-05-04 20:27:52 +08001245}
1246
Song Gaoc50ce382023-09-14 10:26:27 +08001247VSRARN(vsrarn_b_h, 16, B, H, UH)
1248VSRARN(vsrarn_h_w, 32, H, W, UW)
1249VSRARN(vsrarn_w_d, 64, W, D, UD)
Song Gaoa5200a12023-05-04 20:27:52 +08001250
Song Gaoc50ce382023-09-14 10:26:27 +08001251#define VSRLRNI(NAME, BIT, E1, E2) \
1252void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1253{ \
1254 int i, j, ofs; \
1255 VReg temp = {}; \
1256 VReg *Vd = (VReg *)vd; \
1257 VReg *Vj = (VReg *)vj; \
1258 int oprsz = simd_oprsz(desc); \
1259 \
1260 ofs = LSX_LEN / BIT; \
1261 for (i = 0; i < oprsz / 16; i++) { \
1262 for (j = 0; j < ofs; j++) { \
1263 temp.E1(j + ofs * 2 * i) = do_vsrlr_ ## E2(Vj->E2(j + ofs * i), imm); \
1264 temp.E1(j + ofs * (2 * i + 1)) = do_vsrlr_ ## E2(Vd->E2(j + ofs * i), \
1265 imm); \
1266 } \
1267 } \
1268 *Vd = temp; \
Song Gaoa5200a12023-05-04 20:27:52 +08001269}
1270
Song Gao329517d2023-09-14 10:25:57 +08001271void HELPER(vsrlrni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaoa5200a12023-05-04 20:27:52 +08001272{
Song Gaoc50ce382023-09-14 10:26:27 +08001273 int i;
1274 VReg temp = {};
Song Gao329517d2023-09-14 10:25:57 +08001275 VReg *Vd = (VReg *)vd;
1276 VReg *Vj = (VReg *)vj;
Song Gaoc50ce382023-09-14 10:26:27 +08001277 Int128 r[4];
1278 int oprsz = simd_oprsz(desc);
Song Gaoa5200a12023-05-04 20:27:52 +08001279
Song Gaoc50ce382023-09-14 10:26:27 +08001280 for (i = 0; i < oprsz / 16; i++) {
1281 if (imm == 0) {
1282 temp.D(2 * i) = int128_getlo(Vj->Q(i));
1283 temp.D(2 * i + 1) = int128_getlo(Vd->Q(i));
1284 } else {
1285 r[2 * i] = int128_and(int128_urshift(Vj->Q(i), (imm - 1)),
1286 int128_one());
1287 r[2 * i + 1] = int128_and(int128_urshift(Vd->Q(i), (imm - 1)),
1288 int128_one());
1289 temp.D(2 * i) = int128_getlo(int128_add(int128_urshift(Vj->Q(i),
1290 imm), r[2 * i]));
1291 temp.D(2 * i + 1) = int128_getlo(int128_add(int128_urshift(Vd->Q(i),
1292 imm), r[ 2 * i + 1]));
1293 }
Song Gaoa5200a12023-05-04 20:27:52 +08001294 }
1295 *Vd = temp;
1296}
1297
1298VSRLRNI(vsrlrni_b_h, 16, B, H)
1299VSRLRNI(vsrlrni_h_w, 32, H, W)
1300VSRLRNI(vsrlrni_w_d, 64, W, D)
1301
Song Gaoc50ce382023-09-14 10:26:27 +08001302#define VSRARNI(NAME, BIT, E1, E2) \
1303void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1304{ \
1305 int i, j, ofs; \
1306 VReg temp = {}; \
1307 VReg *Vd = (VReg *)vd; \
1308 VReg *Vj = (VReg *)vj; \
1309 int oprsz = simd_oprsz(desc); \
1310 \
1311 ofs = LSX_LEN / BIT; \
1312 for (i = 0; i < oprsz / 16; i++) { \
1313 for (j = 0; j < ofs; j++) { \
1314 temp.E1(j + ofs * 2 * i) = do_vsrar_ ## E2(Vj->E2(j + ofs * i), imm); \
1315 temp.E1(j + ofs * (2 * i + 1)) = do_vsrar_ ## E2(Vd->E2(j + ofs * i), \
1316 imm); \
1317 } \
1318 } \
1319 *Vd = temp; \
Song Gaoa5200a12023-05-04 20:27:52 +08001320}
1321
Song Gao329517d2023-09-14 10:25:57 +08001322void HELPER(vsrarni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaoa5200a12023-05-04 20:27:52 +08001323{
Song Gaoc50ce382023-09-14 10:26:27 +08001324 int i;
1325 VReg temp = {};
Song Gao329517d2023-09-14 10:25:57 +08001326 VReg *Vd = (VReg *)vd;
1327 VReg *Vj = (VReg *)vj;
Song Gaoc50ce382023-09-14 10:26:27 +08001328 Int128 r[4];
1329 int oprsz = simd_oprsz(desc);
Song Gaoa5200a12023-05-04 20:27:52 +08001330
Song Gaoc50ce382023-09-14 10:26:27 +08001331 for (i = 0; i < oprsz / 16; i++) {
1332 if (imm == 0) {
1333 temp.D(2 * i) = int128_getlo(Vj->Q(i));
1334 temp.D(2 * i + 1) = int128_getlo(Vd->Q(i));
1335 } else {
1336 r[2 * i] = int128_and(int128_rshift(Vj->Q(i), (imm - 1)),
1337 int128_one());
1338 r[2 * i + 1] = int128_and(int128_rshift(Vd->Q(i), (imm - 1)),
1339 int128_one());
1340 temp.D(2 * i) = int128_getlo(int128_add(int128_rshift(Vj->Q(i),
1341 imm), r[2 * i]));
1342 temp.D(2 * i + 1) = int128_getlo(int128_add(int128_rshift(Vd->Q(i),
1343 imm), r[2 * i + 1]));
1344 }
Song Gaoa5200a12023-05-04 20:27:52 +08001345 }
1346 *Vd = temp;
1347}
1348
1349VSRARNI(vsrarni_b_h, 16, B, H)
1350VSRARNI(vsrarni_h_w, 32, H, W)
1351VSRARNI(vsrarni_w_d, 64, W, D)
Song Gao83b38152023-05-04 20:27:53 +08001352
1353#define SSRLNS(NAME, T1, T2, T3) \
1354static T1 do_ssrlns_ ## NAME(T2 e2, int sa, int sh) \
1355{ \
1356 T1 shft_res; \
1357 if (sa == 0) { \
1358 shft_res = e2; \
1359 } else { \
1360 shft_res = (((T1)e2) >> sa); \
1361 } \
1362 T3 mask; \
1363 mask = (1ull << sh) -1; \
1364 if (shft_res > mask) { \
1365 return mask; \
1366 } else { \
1367 return shft_res; \
1368 } \
1369}
1370
1371SSRLNS(B, uint16_t, int16_t, uint8_t)
1372SSRLNS(H, uint32_t, int32_t, uint16_t)
1373SSRLNS(W, uint64_t, int64_t, uint32_t)
1374
Song Gao6256c8c2023-09-14 10:26:28 +08001375#define VSSRLN(NAME, BIT, E1, E2, E3) \
1376void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1377{ \
1378 int i, j, ofs; \
1379 VReg *Vd = (VReg *)vd; \
1380 VReg *Vj = (VReg *)vj; \
1381 VReg *Vk = (VReg *)vk; \
1382 int oprsz = simd_oprsz(desc); \
1383 \
1384 ofs = LSX_LEN / BIT; \
1385 for (i = 0; i < oprsz / 16; i++) { \
1386 for (j = 0; j < ofs; j++) { \
1387 Vd->E1(j + ofs * 2 * i) = do_ssrlns_ ## E1(Vj->E2(j + ofs * i), \
1388 Vk->E3(j + ofs * i) % BIT, \
1389 BIT / 2 - 1); \
1390 } \
1391 Vd->D(2 * i + 1) = 0; \
1392 } \
Song Gao83b38152023-05-04 20:27:53 +08001393}
1394
Song Gao6256c8c2023-09-14 10:26:28 +08001395VSSRLN(vssrln_b_h, 16, B, H, UH)
1396VSSRLN(vssrln_h_w, 32, H, W, UW)
1397VSSRLN(vssrln_w_d, 64, W, D, UD)
Song Gao83b38152023-05-04 20:27:53 +08001398
1399#define SSRANS(E, T1, T2) \
1400static T1 do_ssrans_ ## E(T1 e2, int sa, int sh) \
1401{ \
1402 T1 shft_res; \
1403 if (sa == 0) { \
1404 shft_res = e2; \
1405 } else { \
1406 shft_res = e2 >> sa; \
1407 } \
1408 T2 mask; \
Song Gao6256c8c2023-09-14 10:26:28 +08001409 mask = (1ll << sh) - 1; \
Song Gao83b38152023-05-04 20:27:53 +08001410 if (shft_res > mask) { \
1411 return mask; \
Song Gao6256c8c2023-09-14 10:26:28 +08001412 } else if (shft_res < -(mask + 1)) { \
Song Gao83b38152023-05-04 20:27:53 +08001413 return ~mask; \
1414 } else { \
1415 return shft_res; \
1416 } \
1417}
1418
1419SSRANS(B, int16_t, int8_t)
1420SSRANS(H, int32_t, int16_t)
1421SSRANS(W, int64_t, int32_t)
1422
Song Gao6256c8c2023-09-14 10:26:28 +08001423#define VSSRAN(NAME, BIT, E1, E2, E3) \
1424void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1425{ \
1426 int i, j, ofs; \
1427 VReg *Vd = (VReg *)vd; \
1428 VReg *Vj = (VReg *)vj; \
1429 VReg *Vk = (VReg *)vk; \
1430 int oprsz = simd_oprsz(desc); \
1431 \
1432 ofs = LSX_LEN / BIT; \
1433 for (i = 0; i < oprsz / 16; i++) { \
1434 for (j = 0; j < ofs; j++) { \
1435 Vd->E1(j + ofs * 2 * i) = do_ssrans_ ## E1(Vj->E2(j + ofs * i), \
1436 Vk->E3(j + ofs * i) % BIT, \
1437 BIT / 2 - 1); \
1438 } \
1439 Vd->D(2 * i + 1) = 0; \
1440 } \
Song Gao83b38152023-05-04 20:27:53 +08001441}
1442
Song Gao6256c8c2023-09-14 10:26:28 +08001443VSSRAN(vssran_b_h, 16, B, H, UH)
1444VSSRAN(vssran_h_w, 32, H, W, UW)
1445VSSRAN(vssran_w_d, 64, W, D, UD)
Song Gao83b38152023-05-04 20:27:53 +08001446
1447#define SSRLNU(E, T1, T2, T3) \
1448static T1 do_ssrlnu_ ## E(T3 e2, int sa, int sh) \
1449{ \
1450 T1 shft_res; \
1451 if (sa == 0) { \
1452 shft_res = e2; \
1453 } else { \
1454 shft_res = (((T1)e2) >> sa); \
1455 } \
1456 T2 mask; \
Song Gao6256c8c2023-09-14 10:26:28 +08001457 mask = (1ull << sh) - 1; \
Song Gao83b38152023-05-04 20:27:53 +08001458 if (shft_res > mask) { \
1459 return mask; \
1460 } else { \
1461 return shft_res; \
1462 } \
1463}
1464
1465SSRLNU(B, uint16_t, uint8_t, int16_t)
1466SSRLNU(H, uint32_t, uint16_t, int32_t)
1467SSRLNU(W, uint64_t, uint32_t, int64_t)
1468
Song Gao6256c8c2023-09-14 10:26:28 +08001469#define VSSRLNU(NAME, BIT, E1, E2, E3) \
1470void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1471{ \
1472 int i, j, ofs; \
1473 VReg *Vd = (VReg *)vd; \
1474 VReg *Vj = (VReg *)vj; \
1475 VReg *Vk = (VReg *)vk; \
1476 int oprsz = simd_oprsz(desc); \
1477 \
1478 ofs = LSX_LEN / BIT; \
1479 for (i = 0; i < oprsz / 16; i++) { \
1480 for (j = 0; j < ofs; j++) { \
1481 Vd->E1(j + ofs * 2 * i) = do_ssrlnu_ ## E1(Vj->E2(j + ofs * i), \
1482 Vk->E3(j + ofs * i) % BIT, \
1483 BIT / 2); \
1484 } \
1485 Vd->D(2 * i + 1) = 0; \
1486 } \
Song Gao83b38152023-05-04 20:27:53 +08001487}
1488
Song Gao6256c8c2023-09-14 10:26:28 +08001489VSSRLNU(vssrln_bu_h, 16, B, H, UH)
1490VSSRLNU(vssrln_hu_w, 32, H, W, UW)
1491VSSRLNU(vssrln_wu_d, 64, W, D, UD)
Song Gao83b38152023-05-04 20:27:53 +08001492
1493#define SSRANU(E, T1, T2, T3) \
1494static T1 do_ssranu_ ## E(T3 e2, int sa, int sh) \
1495{ \
1496 T1 shft_res; \
1497 if (sa == 0) { \
1498 shft_res = e2; \
1499 } else { \
1500 shft_res = e2 >> sa; \
1501 } \
1502 if (e2 < 0) { \
1503 shft_res = 0; \
1504 } \
1505 T2 mask; \
Song Gao6256c8c2023-09-14 10:26:28 +08001506 mask = (1ull << sh) - 1; \
Song Gao83b38152023-05-04 20:27:53 +08001507 if (shft_res > mask) { \
1508 return mask; \
1509 } else { \
1510 return shft_res; \
1511 } \
1512}
1513
1514SSRANU(B, uint16_t, uint8_t, int16_t)
1515SSRANU(H, uint32_t, uint16_t, int32_t)
1516SSRANU(W, uint64_t, uint32_t, int64_t)
1517
Song Gao6256c8c2023-09-14 10:26:28 +08001518#define VSSRANU(NAME, BIT, E1, E2, E3) \
1519void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1520{ \
1521 int i, j, ofs; \
1522 VReg *Vd = (VReg *)vd; \
1523 VReg *Vj = (VReg *)vj; \
1524 VReg *Vk = (VReg *)vk; \
1525 int oprsz = simd_oprsz(desc); \
1526 \
1527 ofs = LSX_LEN / BIT; \
1528 for (i = 0; i < oprsz / 16; i++) { \
1529 for (j = 0; j < ofs; j++) { \
1530 Vd->E1(j + ofs * 2 * i) = do_ssranu_ ## E1(Vj->E2(j + ofs * i), \
1531 Vk->E3(j + ofs * i) % BIT, \
1532 BIT / 2); \
1533 } \
1534 Vd->D(2 * i + 1) = 0; \
1535 } \
Song Gao83b38152023-05-04 20:27:53 +08001536}
1537
Song Gao6256c8c2023-09-14 10:26:28 +08001538VSSRANU(vssran_bu_h, 16, B, H, UH)
1539VSSRANU(vssran_hu_w, 32, H, W, UW)
1540VSSRANU(vssran_wu_d, 64, W, D, UD)
Song Gao83b38152023-05-04 20:27:53 +08001541
Song Gao6256c8c2023-09-14 10:26:28 +08001542#define VSSRLNI(NAME, BIT, E1, E2) \
1543void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1544{ \
1545 int i, j, ofs; \
1546 VReg temp = {}; \
1547 VReg *Vd = (VReg *)vd; \
1548 VReg *Vj = (VReg *)vj; \
1549 int oprsz = simd_oprsz(desc); \
1550 \
1551 ofs = LSX_LEN / BIT; \
1552 for (i = 0; i < oprsz / 16; i++) { \
1553 for (j = 0; j < ofs; j++) { \
1554 temp.E1(j + ofs * 2 * i) = do_ssrlns_ ## E1(Vj->E2(j + ofs * i), \
1555 imm, BIT / 2 - 1); \
1556 temp.E1(j + ofs * (2 * i + 1)) = do_ssrlns_ ## E1(Vd->E2(j + ofs * i), \
1557 imm, BIT / 2 - 1); \
1558 } \
1559 } \
1560 *Vd = temp; \
1561}
1562
1563static void do_vssrlni_q(VReg *Vd, VReg *Vj,
1564 uint64_t imm, int idx, Int128 mask)
1565{
1566 Int128 shft_res1, shft_res2;
1567
1568 if (imm == 0) {
1569 shft_res1 = Vj->Q(idx);
1570 shft_res2 = Vd->Q(idx);
1571 } else {
1572 shft_res1 = int128_urshift(Vj->Q(idx), imm);
1573 shft_res2 = int128_urshift(Vd->Q(idx), imm);
1574 }
1575
1576 if (int128_ult(mask, shft_res1)) {
1577 Vd->D(idx * 2) = int128_getlo(mask);
1578 }else {
1579 Vd->D(idx * 2) = int128_getlo(shft_res1);
1580 }
1581
1582 if (int128_ult(mask, shft_res2)) {
1583 Vd->D(idx * 2 + 1) = int128_getlo(mask);
1584 }else {
1585 Vd->D(idx * 2 + 1) = int128_getlo(shft_res2);
1586 }
Song Gao83b38152023-05-04 20:27:53 +08001587}
1588
Song Gao329517d2023-09-14 10:25:57 +08001589void HELPER(vssrlni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gao83b38152023-05-04 20:27:53 +08001590{
Song Gao6256c8c2023-09-14 10:26:28 +08001591 int i;
1592 Int128 mask;
Song Gao329517d2023-09-14 10:25:57 +08001593 VReg *Vd = (VReg *)vd;
1594 VReg *Vj = (VReg *)vj;
Song Gao6256c8c2023-09-14 10:26:28 +08001595 int oprsz = simd_oprsz(desc);
Song Gao83b38152023-05-04 20:27:53 +08001596
Song Gao83b38152023-05-04 20:27:53 +08001597 mask = int128_sub(int128_lshift(int128_one(), 63), int128_one());
1598
Song Gao6256c8c2023-09-14 10:26:28 +08001599 for (i = 0; i < oprsz / 16; i++) {
1600 do_vssrlni_q(Vd, Vj, imm, i, mask);
Song Gao83b38152023-05-04 20:27:53 +08001601 }
1602}
1603
1604VSSRLNI(vssrlni_b_h, 16, B, H)
1605VSSRLNI(vssrlni_h_w, 32, H, W)
1606VSSRLNI(vssrlni_w_d, 64, W, D)
1607
Song Gao6256c8c2023-09-14 10:26:28 +08001608#define VSSRANI(NAME, BIT, E1, E2) \
1609void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1610{ \
1611 int i, j, ofs; \
1612 VReg temp = {}; \
1613 VReg *Vd = (VReg *)vd; \
1614 VReg *Vj = (VReg *)vj; \
1615 int oprsz = simd_oprsz(desc); \
1616 \
1617 ofs = LSX_LEN / BIT; \
1618 for (i = 0; i < oprsz / 16; i++) { \
1619 for (j = 0; j < ofs; j++) { \
1620 temp.E1(j + ofs * 2 * i) = do_ssrans_ ## E1(Vj->E2(j + ofs * i), \
1621 imm, BIT / 2 - 1); \
1622 temp.E1(j + ofs * (2 * i + 1)) = do_ssrans_ ## E1(Vd->E2(j + ofs * i), \
1623 imm, BIT / 2 - 1); \
1624 } \
1625 } \
1626 *Vd = temp; \
1627}
1628
1629static void do_vssrani_d_q(VReg *Vd, VReg *Vj,
1630 uint64_t imm, int idx, Int128 mask, Int128 min)
1631{
1632 Int128 shft_res1, shft_res2;
1633
1634 if (imm == 0) {
1635 shft_res1 = Vj->Q(idx);
1636 shft_res2 = Vd->Q(idx);
1637 } else {
1638 shft_res1 = int128_rshift(Vj->Q(idx), imm);
1639 shft_res2 = int128_rshift(Vd->Q(idx), imm);
1640 }
1641
1642 if (int128_gt(shft_res1, mask)) {
1643 Vd->D(idx * 2) = int128_getlo(mask);
1644 } else if (int128_lt(shft_res1, int128_neg(min))) {
1645 Vd->D(idx * 2) = int128_getlo(min);
1646 } else {
1647 Vd->D(idx * 2) = int128_getlo(shft_res1);
1648 }
1649
1650 if (int128_gt(shft_res2, mask)) {
1651 Vd->D(idx * 2 + 1) = int128_getlo(mask);
1652 } else if (int128_lt(shft_res2, int128_neg(min))) {
1653 Vd->D(idx * 2 + 1) = int128_getlo(min);
1654 } else {
1655 Vd->D(idx * 2 + 1) = int128_getlo(shft_res2);
1656 }
Song Gao83b38152023-05-04 20:27:53 +08001657}
1658
Song Gao329517d2023-09-14 10:25:57 +08001659void HELPER(vssrani_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gao83b38152023-05-04 20:27:53 +08001660{
Song Gao6256c8c2023-09-14 10:26:28 +08001661 int i;
1662 Int128 mask, min;
Song Gao329517d2023-09-14 10:25:57 +08001663 VReg *Vd = (VReg *)vd;
1664 VReg *Vj = (VReg *)vj;
Song Gao6256c8c2023-09-14 10:26:28 +08001665 int oprsz = simd_oprsz(desc);
Song Gao83b38152023-05-04 20:27:53 +08001666
Song Gao83b38152023-05-04 20:27:53 +08001667 mask = int128_sub(int128_lshift(int128_one(), 63), int128_one());
1668 min = int128_lshift(int128_one(), 63);
1669
Song Gao6256c8c2023-09-14 10:26:28 +08001670 for (i = 0; i < oprsz / 16; i++) {
1671 do_vssrani_d_q(Vd, Vj, imm, i, mask, min);
Song Gao83b38152023-05-04 20:27:53 +08001672 }
1673}
1674
Song Gao6256c8c2023-09-14 10:26:28 +08001675
Song Gao83b38152023-05-04 20:27:53 +08001676VSSRANI(vssrani_b_h, 16, B, H)
1677VSSRANI(vssrani_h_w, 32, H, W)
1678VSSRANI(vssrani_w_d, 64, W, D)
1679
Song Gao6256c8c2023-09-14 10:26:28 +08001680#define VSSRLNUI(NAME, BIT, E1, E2) \
1681void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1682{ \
1683 int i, j, ofs; \
1684 VReg temp = {}; \
1685 VReg *Vd = (VReg *)vd; \
1686 VReg *Vj = (VReg *)vj; \
1687 int oprsz = simd_oprsz(desc); \
1688 \
1689 ofs = LSX_LEN / BIT; \
1690 for (i = 0; i < oprsz / 16; i++) { \
1691 for (j = 0; j < ofs; j++) { \
1692 temp.E1(j + ofs * 2 * i) = do_ssrlnu_ ## E1(Vj->E2(j + ofs * i), \
1693 imm, BIT / 2); \
1694 temp.E1(j + ofs * (2 * i + 1)) = do_ssrlnu_ ## E1(Vd->E2(j + ofs * i), \
1695 imm, BIT / 2); \
1696 } \
1697 } \
1698 *Vd = temp; \
Song Gao83b38152023-05-04 20:27:53 +08001699}
1700
Song Gao329517d2023-09-14 10:25:57 +08001701void HELPER(vssrlni_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gao83b38152023-05-04 20:27:53 +08001702{
Song Gao6256c8c2023-09-14 10:26:28 +08001703 int i;
1704 Int128 mask;
Song Gao329517d2023-09-14 10:25:57 +08001705 VReg *Vd = (VReg *)vd;
1706 VReg *Vj = (VReg *)vj;
Song Gao6256c8c2023-09-14 10:26:28 +08001707 int oprsz = simd_oprsz(desc);
Song Gao83b38152023-05-04 20:27:53 +08001708
Song Gao83b38152023-05-04 20:27:53 +08001709 mask = int128_sub(int128_lshift(int128_one(), 64), int128_one());
1710
Song Gao6256c8c2023-09-14 10:26:28 +08001711 for (i = 0; i < oprsz / 16; i++) {
1712 do_vssrlni_q(Vd, Vj, imm, i, mask);
Song Gao83b38152023-05-04 20:27:53 +08001713 }
1714}
1715
1716VSSRLNUI(vssrlni_bu_h, 16, B, H)
1717VSSRLNUI(vssrlni_hu_w, 32, H, W)
1718VSSRLNUI(vssrlni_wu_d, 64, W, D)
1719
Song Gao6256c8c2023-09-14 10:26:28 +08001720#define VSSRANUI(NAME, BIT, E1, E2) \
1721void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1722{ \
1723 int i, j, ofs; \
1724 VReg temp = {}; \
1725 VReg *Vd = (VReg *)vd; \
1726 VReg *Vj = (VReg *)vj; \
1727 int oprsz = simd_oprsz(desc); \
1728 \
1729 ofs = LSX_LEN / BIT; \
1730 for (i = 0; i < oprsz / 16; i++) { \
1731 for (j = 0; j < ofs; j++) { \
1732 temp.E1(j + ofs * 2 * i) = do_ssranu_ ## E1(Vj->E2(j + ofs * i), \
1733 imm, BIT / 2); \
1734 temp.E1(j + ofs * (2 * i + 1)) = do_ssranu_ ## E1(Vd->E2(j + ofs * i), \
1735 imm, BIT / 2); \
1736 } \
1737 } \
1738 *Vd = temp; \
1739}
1740
1741static void do_vssrani_du_q(VReg *Vd, VReg *Vj,
1742 uint64_t imm, int idx, Int128 mask)
1743{
1744 Int128 shft_res1, shft_res2;
1745
1746 if (imm == 0) {
1747 shft_res1 = Vj->Q(idx);
1748 shft_res2 = Vd->Q(idx);
1749 } else {
1750 shft_res1 = int128_rshift(Vj->Q(idx), imm);
1751 shft_res2 = int128_rshift(Vd->Q(idx), imm);
1752 }
1753
1754 if (int128_lt(Vj->Q(idx), int128_zero())) {
1755 shft_res1 = int128_zero();
1756 }
1757
1758 if (int128_lt(Vd->Q(idx), int128_zero())) {
1759 shft_res2 = int128_zero();
1760 }
1761 if (int128_ult(mask, shft_res1)) {
1762 Vd->D(idx * 2) = int128_getlo(mask);
1763 }else {
1764 Vd->D(idx * 2) = int128_getlo(shft_res1);
1765 }
1766
1767 if (int128_ult(mask, shft_res2)) {
1768 Vd->D(idx * 2 + 1) = int128_getlo(mask);
1769 }else {
1770 Vd->D(idx * 2 + 1) = int128_getlo(shft_res2);
1771 }
1772
Song Gao83b38152023-05-04 20:27:53 +08001773}
1774
Song Gao329517d2023-09-14 10:25:57 +08001775void HELPER(vssrani_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gao83b38152023-05-04 20:27:53 +08001776{
Song Gao6256c8c2023-09-14 10:26:28 +08001777 int i;
1778 Int128 mask;
Song Gao329517d2023-09-14 10:25:57 +08001779 VReg *Vd = (VReg *)vd;
1780 VReg *Vj = (VReg *)vj;
Song Gao6256c8c2023-09-14 10:26:28 +08001781 int oprsz = simd_oprsz(desc);
Song Gao83b38152023-05-04 20:27:53 +08001782
1783 mask = int128_sub(int128_lshift(int128_one(), 64), int128_one());
1784
Song Gao6256c8c2023-09-14 10:26:28 +08001785 for (i = 0; i < oprsz / 16; i++) {
1786 do_vssrani_du_q(Vd, Vj, imm, i, mask);
Song Gao83b38152023-05-04 20:27:53 +08001787 }
1788}
1789
1790VSSRANUI(vssrani_bu_h, 16, B, H)
1791VSSRANUI(vssrani_hu_w, 32, H, W)
1792VSSRANUI(vssrani_wu_d, 64, W, D)
Song Gao162cd322023-05-04 20:27:54 +08001793
1794#define SSRLRNS(E1, E2, T1, T2, T3) \
1795static T1 do_ssrlrns_ ## E1(T2 e2, int sa, int sh) \
1796{ \
1797 T1 shft_res; \
1798 \
1799 shft_res = do_vsrlr_ ## E2(e2, sa); \
1800 T1 mask; \
Song Gao77fca792023-09-14 10:26:29 +08001801 mask = (1ull << sh) - 1; \
Song Gao162cd322023-05-04 20:27:54 +08001802 if (shft_res > mask) { \
1803 return mask; \
1804 } else { \
1805 return shft_res; \
1806 } \
1807}
1808
1809SSRLRNS(B, H, uint16_t, int16_t, uint8_t)
1810SSRLRNS(H, W, uint32_t, int32_t, uint16_t)
1811SSRLRNS(W, D, uint64_t, int64_t, uint32_t)
1812
Song Gao77fca792023-09-14 10:26:29 +08001813#define VSSRLRN(NAME, BIT, E1, E2, E3) \
1814void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1815{ \
1816 int i, j, ofs; \
1817 VReg *Vd = (VReg *)vd; \
1818 VReg *Vj = (VReg *)vj; \
1819 VReg *Vk = (VReg *)vk; \
1820 int oprsz = simd_oprsz(desc); \
1821 \
1822 ofs = LSX_LEN / BIT; \
1823 for (i = 0; i < oprsz / 16; i++) { \
1824 for (j = 0; j < ofs; j++) { \
1825 Vd->E1(j + ofs * 2 * i) = do_ssrlrns_ ## E1(Vj->E2(j + ofs * i), \
1826 Vk->E3(j + ofs * i) % BIT, \
1827 BIT / 2 - 1); \
1828 } \
1829 Vd->D(2 * i + 1) = 0; \
1830 } \
Song Gao162cd322023-05-04 20:27:54 +08001831}
1832
Song Gao77fca792023-09-14 10:26:29 +08001833VSSRLRN(vssrlrn_b_h, 16, B, H, UH)
1834VSSRLRN(vssrlrn_h_w, 32, H, W, UW)
1835VSSRLRN(vssrlrn_w_d, 64, W, D, UD)
Song Gao162cd322023-05-04 20:27:54 +08001836
1837#define SSRARNS(E1, E2, T1, T2) \
1838static T1 do_ssrarns_ ## E1(T1 e2, int sa, int sh) \
1839{ \
1840 T1 shft_res; \
1841 \
1842 shft_res = do_vsrar_ ## E2(e2, sa); \
1843 T2 mask; \
Song Gao77fca792023-09-14 10:26:29 +08001844 mask = (1ll << sh) - 1; \
Song Gao162cd322023-05-04 20:27:54 +08001845 if (shft_res > mask) { \
1846 return mask; \
1847 } else if (shft_res < -(mask +1)) { \
1848 return ~mask; \
1849 } else { \
1850 return shft_res; \
1851 } \
1852}
1853
1854SSRARNS(B, H, int16_t, int8_t)
1855SSRARNS(H, W, int32_t, int16_t)
1856SSRARNS(W, D, int64_t, int32_t)
1857
Song Gao77fca792023-09-14 10:26:29 +08001858#define VSSRARN(NAME, BIT, E1, E2, E3) \
1859void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1860{ \
1861 int i, j, ofs; \
1862 VReg *Vd = (VReg *)vd; \
1863 VReg *Vj = (VReg *)vj; \
1864 VReg *Vk = (VReg *)vk; \
1865 int oprsz = simd_oprsz(desc); \
1866 \
1867 ofs = LSX_LEN / BIT; \
1868 for (i = 0; i < oprsz / 16; i++) { \
1869 for (j = 0; j < ofs; j++) { \
1870 Vd->E1(j + ofs * 2 * i) = do_ssrarns_ ## E1(Vj->E2(j + ofs * i), \
1871 Vk->E3(j + ofs * i) % BIT, \
1872 BIT/ 2 - 1); \
1873 } \
1874 Vd->D(2 * i + 1) = 0; \
1875 } \
Song Gao162cd322023-05-04 20:27:54 +08001876}
1877
Song Gao77fca792023-09-14 10:26:29 +08001878VSSRARN(vssrarn_b_h, 16, B, H, UH)
1879VSSRARN(vssrarn_h_w, 32, H, W, UW)
1880VSSRARN(vssrarn_w_d, 64, W, D, UD)
Song Gao162cd322023-05-04 20:27:54 +08001881
1882#define SSRLRNU(E1, E2, T1, T2, T3) \
1883static T1 do_ssrlrnu_ ## E1(T3 e2, int sa, int sh) \
1884{ \
1885 T1 shft_res; \
1886 \
1887 shft_res = do_vsrlr_ ## E2(e2, sa); \
1888 \
1889 T2 mask; \
Song Gao77fca792023-09-14 10:26:29 +08001890 mask = (1ull << sh) - 1; \
Song Gao162cd322023-05-04 20:27:54 +08001891 if (shft_res > mask) { \
1892 return mask; \
1893 } else { \
1894 return shft_res; \
1895 } \
1896}
1897
1898SSRLRNU(B, H, uint16_t, uint8_t, int16_t)
1899SSRLRNU(H, W, uint32_t, uint16_t, int32_t)
1900SSRLRNU(W, D, uint64_t, uint32_t, int64_t)
1901
Song Gao77fca792023-09-14 10:26:29 +08001902#define VSSRLRNU(NAME, BIT, E1, E2, E3) \
1903void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1904{ \
1905 int i, j, ofs; \
1906 VReg *Vd = (VReg *)vd; \
1907 VReg *Vj = (VReg *)vj; \
1908 VReg *Vk = (VReg *)vk; \
1909 int oprsz = simd_oprsz(desc); \
1910 \
1911 ofs = LSX_LEN / BIT; \
1912 for (i = 0; i < oprsz / 16; i++) { \
1913 for (j = 0; j < ofs; j++) { \
1914 Vd->E1(j + ofs * 2 * i) = do_ssrlrnu_ ## E1(Vj->E2(j + ofs * i), \
1915 Vk->E3(j + ofs * i) % BIT, \
1916 BIT / 2); \
1917 } \
1918 Vd->D(2 * i + 1) = 0; \
1919 } \
Song Gao162cd322023-05-04 20:27:54 +08001920}
1921
Song Gao77fca792023-09-14 10:26:29 +08001922VSSRLRNU(vssrlrn_bu_h, 16, B, H, UH)
1923VSSRLRNU(vssrlrn_hu_w, 32, H, W, UW)
1924VSSRLRNU(vssrlrn_wu_d, 64, W, D, UD)
Song Gao162cd322023-05-04 20:27:54 +08001925
1926#define SSRARNU(E1, E2, T1, T2, T3) \
1927static T1 do_ssrarnu_ ## E1(T3 e2, int sa, int sh) \
1928{ \
1929 T1 shft_res; \
1930 \
1931 if (e2 < 0) { \
1932 shft_res = 0; \
1933 } else { \
1934 shft_res = do_vsrar_ ## E2(e2, sa); \
1935 } \
1936 T2 mask; \
Song Gao77fca792023-09-14 10:26:29 +08001937 mask = (1ull << sh) - 1; \
Song Gao162cd322023-05-04 20:27:54 +08001938 if (shft_res > mask) { \
1939 return mask; \
1940 } else { \
1941 return shft_res; \
1942 } \
1943}
1944
1945SSRARNU(B, H, uint16_t, uint8_t, int16_t)
1946SSRARNU(H, W, uint32_t, uint16_t, int32_t)
1947SSRARNU(W, D, uint64_t, uint32_t, int64_t)
1948
Song Gao77fca792023-09-14 10:26:29 +08001949#define VSSRARNU(NAME, BIT, E1, E2, E3) \
1950void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1951{ \
1952 int i, j, ofs; \
1953 VReg *Vd = (VReg *)vd; \
1954 VReg *Vj = (VReg *)vj; \
1955 VReg *Vk = (VReg *)vk; \
1956 int oprsz = simd_oprsz(desc); \
1957 \
1958 ofs = LSX_LEN / BIT; \
1959 for (i = 0; i < oprsz / 16; i++) { \
1960 for (j = 0; j < ofs; j++) { \
1961 Vd->E1(j + ofs * 2 * i) = do_ssrarnu_ ## E1(Vj->E2(j + ofs * i), \
1962 Vk->E3(j + ofs * i) % BIT, \
1963 BIT / 2); \
1964 } \
1965 Vd->D(2 * i + 1) = 0; \
1966 } \
Song Gao162cd322023-05-04 20:27:54 +08001967}
1968
Song Gao77fca792023-09-14 10:26:29 +08001969VSSRARNU(vssrarn_bu_h, 16, B, H, UH)
1970VSSRARNU(vssrarn_hu_w, 32, H, W, UW)
1971VSSRARNU(vssrarn_wu_d, 64, W, D, UD)
Song Gao162cd322023-05-04 20:27:54 +08001972
Song Gao77fca792023-09-14 10:26:29 +08001973#define VSSRLRNI(NAME, BIT, E1, E2) \
1974void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1975{ \
1976 int i, j, ofs; \
1977 VReg temp = {}; \
1978 VReg *Vd = (VReg *)vd; \
1979 VReg *Vj = (VReg *)vj; \
1980 int oprsz = simd_oprsz(desc); \
1981 \
1982 ofs = LSX_LEN / BIT; \
1983 for (i = 0; i < oprsz / 16; i++) { \
1984 for (j = 0; j < ofs; j++) { \
1985 temp.E1(j + ofs * 2 * i) = do_ssrlrns_ ## E1(Vj->E2(j + ofs * i), \
1986 imm, BIT / 2 - 1); \
1987 temp.E1(j + ofs * (2 * i + 1)) = do_ssrlrns_ ## E1(Vd->E2(j + ofs * i), \
1988 imm, BIT / 2 - 1); \
1989 } \
1990 } \
1991 *Vd = temp; \
Song Gao162cd322023-05-04 20:27:54 +08001992}
1993
Song Gao77fca792023-09-14 10:26:29 +08001994static void do_vssrlrni_q(VReg *Vd, VReg * Vj,
1995 uint64_t imm, int idx, Int128 mask)
1996{
1997 Int128 shft_res1, shft_res2, r1, r2;
1998 if (imm == 0) {
1999 shft_res1 = Vj->Q(idx);
2000 shft_res2 = Vd->Q(idx);
2001 } else {
2002 r1 = int128_and(int128_urshift(Vj->Q(idx), (imm - 1)), int128_one());
2003 r2 = int128_and(int128_urshift(Vd->Q(idx), (imm - 1)), int128_one());
2004 shft_res1 = (int128_add(int128_urshift(Vj->Q(idx), imm), r1));
2005 shft_res2 = (int128_add(int128_urshift(Vd->Q(idx), imm), r2));
2006 }
2007
2008 if (int128_ult(mask, shft_res1)) {
2009 Vd->D(idx * 2) = int128_getlo(mask);
2010 }else {
2011 Vd->D(idx * 2) = int128_getlo(shft_res1);
2012 }
2013
2014 if (int128_ult(mask, shft_res2)) {
2015 Vd->D(idx * 2 + 1) = int128_getlo(mask);
2016 }else {
2017 Vd->D(idx * 2 + 1) = int128_getlo(shft_res2);
2018 }
2019}
2020
2021void HELPER(vssrlrni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
2022{
2023 int i;
2024 Int128 mask;
2025 VReg *Vd = (VReg *)vd;
2026 VReg *Vj = (VReg *)vj;
2027 int oprsz = simd_oprsz(desc);
2028
2029 mask = int128_sub(int128_lshift(int128_one(), 63), int128_one());
2030
2031 for (i = 0; i < oprsz / 16; i++) {
2032 do_vssrlrni_q(Vd, Vj, imm, i, mask);
2033 }
Song Gao162cd322023-05-04 20:27:54 +08002034}
2035
2036VSSRLRNI(vssrlrni_b_h, 16, B, H)
2037VSSRLRNI(vssrlrni_h_w, 32, H, W)
2038VSSRLRNI(vssrlrni_w_d, 64, W, D)
Song Gao162cd322023-05-04 20:27:54 +08002039
Song Gao77fca792023-09-14 10:26:29 +08002040#define VSSRARNI(NAME, BIT, E1, E2) \
2041void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2042{ \
2043 int i, j, ofs; \
2044 VReg temp = {}; \
2045 VReg *Vd = (VReg *)vd; \
2046 VReg *Vj = (VReg *)vj; \
2047 int oprsz = simd_oprsz(desc); \
2048 \
2049 ofs = LSX_LEN / BIT; \
2050 for (i = 0; i < oprsz / 16; i++) { \
2051 for (j = 0; j < ofs; j++) { \
2052 temp.E1(j + ofs * 2 * i) = do_ssrarns_ ## E1(Vj->E2(j + ofs * i), \
2053 imm, BIT / 2 - 1); \
2054 temp.E1(j + ofs * (2 * i + 1)) = do_ssrarns_ ## E1(Vd->E2(j + ofs * i), \
2055 imm, BIT / 2 - 1); \
2056 } \
2057 } \
2058 *Vd = temp; \
2059}
2060
2061static void do_vssrarni_d_q(VReg *Vd, VReg *Vj,
2062 uint64_t imm, int idx, Int128 mask1, Int128 mask2)
2063{
2064 Int128 shft_res1, shft_res2, r1, r2;
2065
2066 if (imm == 0) {
2067 shft_res1 = Vj->Q(idx);
2068 shft_res2 = Vd->Q(idx);
2069 } else {
2070 r1 = int128_and(int128_rshift(Vj->Q(idx), (imm - 1)), int128_one());
2071 r2 = int128_and(int128_rshift(Vd->Q(idx), (imm - 1)), int128_one());
2072 shft_res1 = int128_add(int128_rshift(Vj->Q(idx), imm), r1);
2073 shft_res2 = int128_add(int128_rshift(Vd->Q(idx), imm), r2);
2074 }
2075 if (int128_gt(shft_res1, mask1)) {
2076 Vd->D(idx * 2) = int128_getlo(mask1);
2077 } else if (int128_lt(shft_res1, int128_neg(mask2))) {
2078 Vd->D(idx * 2) = int128_getlo(mask2);
2079 } else {
2080 Vd->D(idx * 2) = int128_getlo(shft_res1);
2081 }
2082
2083 if (int128_gt(shft_res2, mask1)) {
2084 Vd->D(idx * 2 + 1) = int128_getlo(mask1);
2085 } else if (int128_lt(shft_res2, int128_neg(mask2))) {
2086 Vd->D(idx * 2 + 1) = int128_getlo(mask2);
2087 } else {
2088 Vd->D(idx * 2 + 1) = int128_getlo(shft_res2);
2089 }
Song Gao162cd322023-05-04 20:27:54 +08002090}
2091
Song Gao329517d2023-09-14 10:25:57 +08002092void HELPER(vssrarni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gao162cd322023-05-04 20:27:54 +08002093{
Song Gao77fca792023-09-14 10:26:29 +08002094 int i;
2095 Int128 mask1, mask2;
Song Gao329517d2023-09-14 10:25:57 +08002096 VReg *Vd = (VReg *)vd;
2097 VReg *Vj = (VReg *)vj;
Song Gao77fca792023-09-14 10:26:29 +08002098 int oprsz = simd_oprsz(desc);
Song Gao162cd322023-05-04 20:27:54 +08002099
2100 mask1 = int128_sub(int128_lshift(int128_one(), 63), int128_one());
2101 mask2 = int128_lshift(int128_one(), 63);
2102
Song Gao77fca792023-09-14 10:26:29 +08002103 for (i = 0; i < oprsz / 16; i++) {
2104 do_vssrarni_d_q(Vd, Vj, imm, i, mask1, mask2);
Song Gao162cd322023-05-04 20:27:54 +08002105 }
2106}
2107
2108VSSRARNI(vssrarni_b_h, 16, B, H)
2109VSSRARNI(vssrarni_h_w, 32, H, W)
2110VSSRARNI(vssrarni_w_d, 64, W, D)
2111
Song Gao77fca792023-09-14 10:26:29 +08002112#define VSSRLRNUI(NAME, BIT, E1, E2) \
2113void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2114{ \
2115 int i, j, ofs; \
2116 VReg temp = {}; \
2117 VReg *Vd = (VReg *)vd; \
2118 VReg *Vj = (VReg *)vj; \
2119 int oprsz = simd_oprsz(desc); \
2120 \
2121 ofs = LSX_LEN / BIT; \
2122 for (i = 0; i < oprsz / 16; i++) { \
2123 for (j = 0; j < ofs; j++) { \
2124 temp.E1(j + ofs * 2 * i) = do_ssrlrnu_ ## E1(Vj->E2(j + ofs * i), \
2125 imm, BIT / 2); \
2126 temp.E1(j + ofs * (2 * i + 1)) = do_ssrlrnu_ ## E1(Vd->E2(j + ofs * i), \
2127 imm, BIT / 2); \
2128 } \
2129 } \
2130 *Vd = temp; \
2131}
2132
2133void HELPER(vssrlrni_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
2134{
2135 int i;
2136 Int128 mask;
2137 VReg *Vd = (VReg *)vd;
2138 VReg *Vj = (VReg *)vj;
2139 int oprsz = simd_oprsz(desc);
2140
2141 mask = int128_sub(int128_lshift(int128_one(), 64), int128_one());
2142
2143 for (i = 0; i < oprsz / 16; i++) {
2144 do_vssrlrni_q(Vd, Vj, imm, i, mask);
2145 }
Song Gao162cd322023-05-04 20:27:54 +08002146}
2147
2148VSSRLRNUI(vssrlrni_bu_h, 16, B, H)
2149VSSRLRNUI(vssrlrni_hu_w, 32, H, W)
2150VSSRLRNUI(vssrlrni_wu_d, 64, W, D)
Song Gao162cd322023-05-04 20:27:54 +08002151
Song Gao77fca792023-09-14 10:26:29 +08002152#define VSSRARNUI(NAME, BIT, E1, E2) \
2153void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2154{ \
2155 int i, j, ofs; \
2156 VReg temp = {}; \
2157 VReg *Vd = (VReg *)vd; \
2158 VReg *Vj = (VReg *)vj; \
2159 int oprsz = simd_oprsz(desc); \
2160 \
2161 ofs = LSX_LEN / BIT; \
2162 for (i = 0; i < oprsz / 16; i++) { \
2163 for (j = 0; j < ofs; j++) { \
2164 temp.E1(j + ofs * 2 * i) = do_ssrarnu_ ## E1(Vj->E2(j + ofs * i), \
2165 imm, BIT / 2); \
2166 temp.E1(j + ofs * (2 * i + 1)) = do_ssrarnu_ ## E1(Vd->E2(j + ofs * i), \
2167 imm, BIT / 2); \
2168 } \
2169 } \
2170 *Vd = temp; \
2171}
2172
2173static void do_vssrarni_du_q(VReg *Vd, VReg *Vj,
2174 uint64_t imm, int idx, Int128 mask1, Int128 mask2)
2175{
2176 Int128 shft_res1, shft_res2, r1, r2;
2177
2178 if (imm == 0) {
2179 shft_res1 = Vj->Q(idx);
2180 shft_res2 = Vd->Q(idx);
2181 } else {
2182 r1 = int128_and(int128_rshift(Vj->Q(idx), (imm - 1)), int128_one());
2183 r2 = int128_and(int128_rshift(Vd->Q(idx), (imm - 1)), int128_one());
2184 shft_res1 = int128_add(int128_rshift(Vj->Q(idx), imm), r1);
2185 shft_res2 = int128_add(int128_rshift(Vd->Q(idx), imm), r2);
2186 }
2187
2188 if (int128_lt(Vj->Q(idx), int128_zero())) {
2189 shft_res1 = int128_zero();
2190 }
2191 if (int128_lt(Vd->Q(idx), int128_zero())) {
2192 shft_res2 = int128_zero();
2193 }
2194
2195 if (int128_gt(shft_res1, mask1)) {
2196 Vd->D(idx * 2) = int128_getlo(mask1);
2197 } else if (int128_lt(shft_res1, int128_neg(mask2))) {
2198 Vd->D(idx * 2) = int128_getlo(mask2);
2199 } else {
2200 Vd->D(idx * 2) = int128_getlo(shft_res1);
2201 }
2202
2203 if (int128_gt(shft_res2, mask1)) {
2204 Vd->D(idx * 2 + 1) = int128_getlo(mask1);
2205 } else if (int128_lt(shft_res2, int128_neg(mask2))) {
2206 Vd->D(idx * 2 + 1) = int128_getlo(mask2);
2207 } else {
2208 Vd->D(idx * 2 + 1) = int128_getlo(shft_res2);
2209 }
Song Gao162cd322023-05-04 20:27:54 +08002210}
2211
Song Gao329517d2023-09-14 10:25:57 +08002212void HELPER(vssrarni_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gao162cd322023-05-04 20:27:54 +08002213{
Song Gao77fca792023-09-14 10:26:29 +08002214 int i;
2215 Int128 mask1, mask2;
Song Gao329517d2023-09-14 10:25:57 +08002216 VReg *Vd = (VReg *)vd;
2217 VReg *Vj = (VReg *)vj;
Song Gao77fca792023-09-14 10:26:29 +08002218 int oprsz = simd_oprsz(desc);
Song Gao162cd322023-05-04 20:27:54 +08002219
2220 mask1 = int128_sub(int128_lshift(int128_one(), 64), int128_one());
2221 mask2 = int128_lshift(int128_one(), 64);
2222
Song Gao77fca792023-09-14 10:26:29 +08002223 for (i = 0; i < oprsz / 16; i++) {
2224 do_vssrarni_du_q(Vd, Vj, imm, i, mask1, mask2);
Song Gao162cd322023-05-04 20:27:54 +08002225 }
2226}
2227
2228VSSRARNUI(vssrarni_bu_h, 16, B, H)
2229VSSRARNUI(vssrarni_hu_w, 32, H, W)
2230VSSRARNUI(vssrarni_wu_d, 64, W, D)
Song Gao2e105e12023-05-04 20:27:55 +08002231
Song Gaoff27e332023-09-14 10:25:56 +08002232#define DO_2OP(NAME, BIT, E, DO_OP) \
2233void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
2234{ \
2235 int i; \
2236 VReg *Vd = (VReg *)vd; \
2237 VReg *Vj = (VReg *)vj; \
Song Gao12ad1332023-09-14 10:26:30 +08002238 int oprsz = simd_oprsz(desc); \
Song Gaoff27e332023-09-14 10:25:56 +08002239 \
Song Gao12ad1332023-09-14 10:26:30 +08002240 for (i = 0; i < oprsz / (BIT / 8); i++) \
Song Gaoff27e332023-09-14 10:25:56 +08002241 { \
2242 Vd->E(i) = DO_OP(Vj->E(i)); \
2243 } \
Song Gao2e105e12023-05-04 20:27:55 +08002244}
2245
Song Gao2e105e12023-05-04 20:27:55 +08002246DO_2OP(vclo_b, 8, UB, DO_CLO_B)
2247DO_2OP(vclo_h, 16, UH, DO_CLO_H)
2248DO_2OP(vclo_w, 32, UW, DO_CLO_W)
2249DO_2OP(vclo_d, 64, UD, DO_CLO_D)
2250DO_2OP(vclz_b, 8, UB, DO_CLZ_B)
2251DO_2OP(vclz_h, 16, UH, DO_CLZ_H)
2252DO_2OP(vclz_w, 32, UW, DO_CLZ_W)
2253DO_2OP(vclz_d, 64, UD, DO_CLZ_D)
Song Gaobb22ee52023-05-04 20:27:56 +08002254
Song Gaoff27e332023-09-14 10:25:56 +08002255#define VPCNT(NAME, BIT, E, FN) \
2256void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
2257{ \
2258 int i; \
2259 VReg *Vd = (VReg *)vd; \
2260 VReg *Vj = (VReg *)vj; \
Song Gao956dec72023-09-14 10:26:31 +08002261 int oprsz = simd_oprsz(desc); \
Song Gaoff27e332023-09-14 10:25:56 +08002262 \
Song Gao956dec72023-09-14 10:26:31 +08002263 for (i = 0; i < oprsz / (BIT / 8); i++) \
Song Gaoff27e332023-09-14 10:25:56 +08002264 { \
2265 Vd->E(i) = FN(Vj->E(i)); \
2266 } \
Song Gaobb22ee52023-05-04 20:27:56 +08002267}
2268
2269VPCNT(vpcnt_b, 8, UB, ctpop8)
2270VPCNT(vpcnt_h, 16, UH, ctpop16)
2271VPCNT(vpcnt_w, 32, UW, ctpop32)
2272VPCNT(vpcnt_d, 64, UD, ctpop64)
Song Gao0b1e6702023-05-04 20:27:57 +08002273
Song Gao1b3e2422023-09-14 10:26:32 +08002274#define DO_BIT(NAME, BIT, E, DO_OP) \
2275void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2276{ \
2277 int i; \
2278 VReg *Vd = (VReg *)vd; \
2279 VReg *Vj = (VReg *)vj; \
2280 VReg *Vk = (VReg *)vk; \
2281 int oprsz = simd_oprsz(desc); \
2282 \
2283 for (i = 0; i < oprsz / (BIT / 8); i++) { \
2284 Vd->E(i) = DO_OP(Vj->E(i), Vk->E(i)%BIT); \
2285 } \
Song Gao0b1e6702023-05-04 20:27:57 +08002286}
2287
2288DO_BIT(vbitclr_b, 8, UB, DO_BITCLR)
2289DO_BIT(vbitclr_h, 16, UH, DO_BITCLR)
2290DO_BIT(vbitclr_w, 32, UW, DO_BITCLR)
2291DO_BIT(vbitclr_d, 64, UD, DO_BITCLR)
2292DO_BIT(vbitset_b, 8, UB, DO_BITSET)
2293DO_BIT(vbitset_h, 16, UH, DO_BITSET)
2294DO_BIT(vbitset_w, 32, UW, DO_BITSET)
2295DO_BIT(vbitset_d, 64, UD, DO_BITSET)
2296DO_BIT(vbitrev_b, 8, UB, DO_BITREV)
2297DO_BIT(vbitrev_h, 16, UH, DO_BITREV)
2298DO_BIT(vbitrev_w, 32, UW, DO_BITREV)
2299DO_BIT(vbitrev_d, 64, UD, DO_BITREV)
2300
Song Gao1b3e2422023-09-14 10:26:32 +08002301#define DO_BITI(NAME, BIT, E, DO_OP) \
2302void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2303{ \
2304 int i; \
2305 VReg *Vd = (VReg *)vd; \
2306 VReg *Vj = (VReg *)vj; \
2307 int oprsz = simd_oprsz(desc); \
2308 \
2309 for (i = 0; i < oprsz / (BIT / 8); i++) { \
2310 Vd->E(i) = DO_OP(Vj->E(i), imm); \
2311 } \
Song Gao0b1e6702023-05-04 20:27:57 +08002312}
2313
2314DO_BITI(vbitclri_b, 8, UB, DO_BITCLR)
2315DO_BITI(vbitclri_h, 16, UH, DO_BITCLR)
2316DO_BITI(vbitclri_w, 32, UW, DO_BITCLR)
2317DO_BITI(vbitclri_d, 64, UD, DO_BITCLR)
2318DO_BITI(vbitseti_b, 8, UB, DO_BITSET)
2319DO_BITI(vbitseti_h, 16, UH, DO_BITSET)
2320DO_BITI(vbitseti_w, 32, UW, DO_BITSET)
2321DO_BITI(vbitseti_d, 64, UD, DO_BITSET)
2322DO_BITI(vbitrevi_b, 8, UB, DO_BITREV)
2323DO_BITI(vbitrevi_h, 16, UH, DO_BITREV)
2324DO_BITI(vbitrevi_w, 32, UW, DO_BITREV)
2325DO_BITI(vbitrevi_d, 64, UD, DO_BITREV)
Song Gaoac95a0b2023-05-04 20:27:58 +08002326
Song Gao04711da2023-09-14 10:25:54 +08002327#define VFRSTP(NAME, BIT, MASK, E) \
2328void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2329{ \
Song Gaoabee1682023-09-14 10:26:33 +08002330 int i, j, m, ofs; \
Song Gao04711da2023-09-14 10:25:54 +08002331 VReg *Vd = (VReg *)vd; \
2332 VReg *Vj = (VReg *)vj; \
2333 VReg *Vk = (VReg *)vk; \
Song Gaoabee1682023-09-14 10:26:33 +08002334 int oprsz = simd_oprsz(desc); \
Song Gao04711da2023-09-14 10:25:54 +08002335 \
Song Gaoabee1682023-09-14 10:26:33 +08002336 ofs = LSX_LEN / BIT; \
2337 for (i = 0; i < oprsz / 16; i++) { \
2338 m = Vk->E(i * ofs) & MASK; \
2339 for (j = 0; j < ofs; j++) { \
2340 if (Vj->E(j + ofs * i) < 0) { \
2341 break; \
2342 } \
Song Gao04711da2023-09-14 10:25:54 +08002343 } \
Song Gaoabee1682023-09-14 10:26:33 +08002344 Vd->E(m + i * ofs) = j; \
Song Gao04711da2023-09-14 10:25:54 +08002345 } \
Song Gaoac95a0b2023-05-04 20:27:58 +08002346}
2347
2348VFRSTP(vfrstp_b, 8, 0xf, B)
2349VFRSTP(vfrstp_h, 16, 0x7, H)
2350
Song Gao329517d2023-09-14 10:25:57 +08002351#define VFRSTPI(NAME, BIT, E) \
2352void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2353{ \
Song Gaoabee1682023-09-14 10:26:33 +08002354 int i, j, m, ofs; \
Song Gao329517d2023-09-14 10:25:57 +08002355 VReg *Vd = (VReg *)vd; \
2356 VReg *Vj = (VReg *)vj; \
Song Gaoabee1682023-09-14 10:26:33 +08002357 int oprsz = simd_oprsz(desc); \
Song Gao329517d2023-09-14 10:25:57 +08002358 \
Song Gaoabee1682023-09-14 10:26:33 +08002359 ofs = LSX_LEN / BIT; \
2360 m = imm % ofs; \
2361 for (i = 0; i < oprsz / 16; i++) { \
2362 for (j = 0; j < ofs; j++) { \
2363 if (Vj->E(j + ofs * i) < 0) { \
2364 break; \
2365 } \
Song Gao329517d2023-09-14 10:25:57 +08002366 } \
Song Gaoabee1682023-09-14 10:26:33 +08002367 Vd->E(m + i * ofs) = j; \
Song Gao329517d2023-09-14 10:25:57 +08002368 } \
Song Gaoac95a0b2023-05-04 20:27:58 +08002369}
2370
2371VFRSTPI(vfrstpi_b, 8, B)
2372VFRSTPI(vfrstpi_h, 16, H)
Song Gaoaca67472023-05-04 20:27:59 +08002373
2374static void vec_update_fcsr0_mask(CPULoongArchState *env,
2375 uintptr_t pc, int mask)
2376{
2377 int flags = get_float_exception_flags(&env->fp_status);
2378
2379 set_float_exception_flags(0, &env->fp_status);
2380
2381 flags &= ~mask;
2382
2383 if (flags) {
2384 flags = ieee_ex_to_loongarch(flags);
2385 UPDATE_FP_CAUSE(env->fcsr0, flags);
2386 }
2387
2388 if (GET_FP_ENABLES(env->fcsr0) & flags) {
2389 do_raise_exception(env, EXCCODE_FPE, pc);
2390 } else {
2391 UPDATE_FP_FLAGS(env->fcsr0, flags);
2392 }
2393}
2394
2395static void vec_update_fcsr0(CPULoongArchState *env, uintptr_t pc)
2396{
2397 vec_update_fcsr0_mask(env, pc, 0);
2398}
2399
2400static inline void vec_clear_cause(CPULoongArchState *env)
2401{
2402 SET_FP_CAUSE(env->fcsr0, 0);
2403}
2404
2405#define DO_3OP_F(NAME, BIT, E, FN) \
Song Gao3b286752023-09-14 10:25:53 +08002406void HELPER(NAME)(void *vd, void *vj, void *vk, \
2407 CPULoongArchState *env, uint32_t desc) \
Song Gaoaca67472023-05-04 20:27:59 +08002408{ \
2409 int i; \
Song Gao3b286752023-09-14 10:25:53 +08002410 VReg *Vd = (VReg *)vd; \
2411 VReg *Vj = (VReg *)vj; \
2412 VReg *Vk = (VReg *)vk; \
Song Gaoc9caf152023-09-14 10:26:34 +08002413 int oprsz = simd_oprsz(desc); \
Song Gaoaca67472023-05-04 20:27:59 +08002414 \
2415 vec_clear_cause(env); \
Song Gaoc9caf152023-09-14 10:26:34 +08002416 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gaoaca67472023-05-04 20:27:59 +08002417 Vd->E(i) = FN(Vj->E(i), Vk->E(i), &env->fp_status); \
2418 vec_update_fcsr0(env, GETPC()); \
2419 } \
2420}
2421
2422DO_3OP_F(vfadd_s, 32, UW, float32_add)
2423DO_3OP_F(vfadd_d, 64, UD, float64_add)
2424DO_3OP_F(vfsub_s, 32, UW, float32_sub)
2425DO_3OP_F(vfsub_d, 64, UD, float64_sub)
2426DO_3OP_F(vfmul_s, 32, UW, float32_mul)
2427DO_3OP_F(vfmul_d, 64, UD, float64_mul)
2428DO_3OP_F(vfdiv_s, 32, UW, float32_div)
2429DO_3OP_F(vfdiv_d, 64, UD, float64_div)
2430DO_3OP_F(vfmax_s, 32, UW, float32_maxnum)
2431DO_3OP_F(vfmax_d, 64, UD, float64_maxnum)
2432DO_3OP_F(vfmin_s, 32, UW, float32_minnum)
2433DO_3OP_F(vfmin_d, 64, UD, float64_minnum)
2434DO_3OP_F(vfmaxa_s, 32, UW, float32_maxnummag)
2435DO_3OP_F(vfmaxa_d, 64, UD, float64_maxnummag)
2436DO_3OP_F(vfmina_s, 32, UW, float32_minnummag)
2437DO_3OP_F(vfmina_d, 64, UD, float64_minnummag)
2438
2439#define DO_4OP_F(NAME, BIT, E, FN, flags) \
Song Gaoe2600da2023-09-14 10:25:51 +08002440void HELPER(NAME)(void *vd, void *vj, void *vk, void *va, \
2441 CPULoongArchState *env, uint32_t desc) \
Song Gaoaca67472023-05-04 20:27:59 +08002442{ \
2443 int i; \
Song Gaoe2600da2023-09-14 10:25:51 +08002444 VReg *Vd = (VReg *)vd; \
2445 VReg *Vj = (VReg *)vj; \
2446 VReg *Vk = (VReg *)vk; \
2447 VReg *Va = (VReg *)va; \
Song Gaoc9caf152023-09-14 10:26:34 +08002448 int oprsz = simd_oprsz(desc); \
Song Gaoaca67472023-05-04 20:27:59 +08002449 \
2450 vec_clear_cause(env); \
Song Gaoc9caf152023-09-14 10:26:34 +08002451 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gaoaca67472023-05-04 20:27:59 +08002452 Vd->E(i) = FN(Vj->E(i), Vk->E(i), Va->E(i), flags, &env->fp_status); \
2453 vec_update_fcsr0(env, GETPC()); \
2454 } \
2455}
2456
2457DO_4OP_F(vfmadd_s, 32, UW, float32_muladd, 0)
2458DO_4OP_F(vfmadd_d, 64, UD, float64_muladd, 0)
2459DO_4OP_F(vfmsub_s, 32, UW, float32_muladd, float_muladd_negate_c)
2460DO_4OP_F(vfmsub_d, 64, UD, float64_muladd, float_muladd_negate_c)
2461DO_4OP_F(vfnmadd_s, 32, UW, float32_muladd, float_muladd_negate_result)
2462DO_4OP_F(vfnmadd_d, 64, UD, float64_muladd, float_muladd_negate_result)
2463DO_4OP_F(vfnmsub_s, 32, UW, float32_muladd,
2464 float_muladd_negate_c | float_muladd_negate_result)
2465DO_4OP_F(vfnmsub_d, 64, UD, float64_muladd,
2466 float_muladd_negate_c | float_muladd_negate_result)
2467
Song Gao226bf882023-09-14 10:25:55 +08002468#define DO_2OP_F(NAME, BIT, E, FN) \
2469void HELPER(NAME)(void *vd, void *vj, \
2470 CPULoongArchState *env, uint32_t desc) \
2471{ \
2472 int i; \
2473 VReg *Vd = (VReg *)vd; \
2474 VReg *Vj = (VReg *)vj; \
Song Gaoc9caf152023-09-14 10:26:34 +08002475 int oprsz = simd_oprsz(desc); \
Song Gao226bf882023-09-14 10:25:55 +08002476 \
2477 vec_clear_cause(env); \
Song Gaoc9caf152023-09-14 10:26:34 +08002478 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao226bf882023-09-14 10:25:55 +08002479 Vd->E(i) = FN(env, Vj->E(i)); \
2480 } \
Song Gaoaca67472023-05-04 20:27:59 +08002481}
2482
2483#define FLOGB(BIT, T) \
2484static T do_flogb_## BIT(CPULoongArchState *env, T fj) \
2485{ \
2486 T fp, fd; \
2487 float_status *status = &env->fp_status; \
2488 FloatRoundMode old_mode = get_float_rounding_mode(status); \
2489 \
2490 set_float_rounding_mode(float_round_down, status); \
2491 fp = float ## BIT ##_log2(fj, status); \
2492 fd = float ## BIT ##_round_to_int(fp, status); \
2493 set_float_rounding_mode(old_mode, status); \
2494 vec_update_fcsr0_mask(env, GETPC(), float_flag_inexact); \
2495 return fd; \
2496}
2497
2498FLOGB(32, uint32_t)
2499FLOGB(64, uint64_t)
2500
Song Gao226bf882023-09-14 10:25:55 +08002501#define FCLASS(NAME, BIT, E, FN) \
2502void HELPER(NAME)(void *vd, void *vj, \
2503 CPULoongArchState *env, uint32_t desc) \
2504{ \
2505 int i; \
2506 VReg *Vd = (VReg *)vd; \
2507 VReg *Vj = (VReg *)vj; \
Song Gaoc9caf152023-09-14 10:26:34 +08002508 int oprsz = simd_oprsz(desc); \
Song Gao226bf882023-09-14 10:25:55 +08002509 \
Song Gaoc9caf152023-09-14 10:26:34 +08002510 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao226bf882023-09-14 10:25:55 +08002511 Vd->E(i) = FN(env, Vj->E(i)); \
2512 } \
Song Gaoaca67472023-05-04 20:27:59 +08002513}
2514
2515FCLASS(vfclass_s, 32, UW, helper_fclass_s)
2516FCLASS(vfclass_d, 64, UD, helper_fclass_d)
2517
2518#define FSQRT(BIT, T) \
2519static T do_fsqrt_## BIT(CPULoongArchState *env, T fj) \
2520{ \
2521 T fd; \
2522 fd = float ## BIT ##_sqrt(fj, &env->fp_status); \
2523 vec_update_fcsr0(env, GETPC()); \
2524 return fd; \
2525}
2526
2527FSQRT(32, uint32_t)
2528FSQRT(64, uint64_t)
2529
2530#define FRECIP(BIT, T) \
2531static T do_frecip_## BIT(CPULoongArchState *env, T fj) \
2532{ \
2533 T fd; \
2534 fd = float ## BIT ##_div(float ## BIT ##_one, fj, &env->fp_status); \
2535 vec_update_fcsr0(env, GETPC()); \
2536 return fd; \
2537}
2538
2539FRECIP(32, uint32_t)
2540FRECIP(64, uint64_t)
2541
2542#define FRSQRT(BIT, T) \
2543static T do_frsqrt_## BIT(CPULoongArchState *env, T fj) \
2544{ \
2545 T fd, fp; \
2546 fp = float ## BIT ##_sqrt(fj, &env->fp_status); \
2547 fd = float ## BIT ##_div(float ## BIT ##_one, fp, &env->fp_status); \
2548 vec_update_fcsr0(env, GETPC()); \
2549 return fd; \
2550}
2551
2552FRSQRT(32, uint32_t)
2553FRSQRT(64, uint64_t)
2554
2555DO_2OP_F(vflogb_s, 32, UW, do_flogb_32)
2556DO_2OP_F(vflogb_d, 64, UD, do_flogb_64)
2557DO_2OP_F(vfsqrt_s, 32, UW, do_fsqrt_32)
2558DO_2OP_F(vfsqrt_d, 64, UD, do_fsqrt_64)
2559DO_2OP_F(vfrecip_s, 32, UW, do_frecip_32)
2560DO_2OP_F(vfrecip_d, 64, UD, do_frecip_64)
2561DO_2OP_F(vfrsqrt_s, 32, UW, do_frsqrt_32)
2562DO_2OP_F(vfrsqrt_d, 64, UD, do_frsqrt_64)
Song Gao399665d2023-05-04 20:28:00 +08002563
2564static uint32_t float16_cvt_float32(uint16_t h, float_status *status)
2565{
2566 return float16_to_float32(h, true, status);
2567}
2568static uint64_t float32_cvt_float64(uint32_t s, float_status *status)
2569{
2570 return float32_to_float64(s, status);
2571}
2572
2573static uint16_t float32_cvt_float16(uint32_t s, float_status *status)
2574{
2575 return float32_to_float16(s, true, status);
2576}
2577static uint32_t float64_cvt_float32(uint64_t d, float_status *status)
2578{
2579 return float64_to_float32(d, status);
2580}
2581
Song Gao226bf882023-09-14 10:25:55 +08002582void HELPER(vfcvtl_s_h)(void *vd, void *vj,
2583 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002584{
Song Gao60df31a2023-09-14 10:26:35 +08002585 int i, j, ofs;
2586 VReg temp = {};
Song Gao226bf882023-09-14 10:25:55 +08002587 VReg *Vd = (VReg *)vd;
2588 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002589 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002590
Song Gao60df31a2023-09-14 10:26:35 +08002591 ofs = LSX_LEN / 32;
Song Gao399665d2023-05-04 20:28:00 +08002592 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002593 for (i = 0; i < oprsz / 16; i++) {
2594 for (j = 0; j < ofs; j++) {
2595 temp.UW(j + ofs * i) =float16_cvt_float32(Vj->UH(j + ofs * 2 * i),
2596 &env->fp_status);
2597 }
Song Gao399665d2023-05-04 20:28:00 +08002598 vec_update_fcsr0(env, GETPC());
2599 }
2600 *Vd = temp;
2601}
2602
Song Gao226bf882023-09-14 10:25:55 +08002603void HELPER(vfcvtl_d_s)(void *vd, void *vj,
2604 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002605{
Song Gao60df31a2023-09-14 10:26:35 +08002606 int i, j, ofs;
2607 VReg temp = {};
Song Gao226bf882023-09-14 10:25:55 +08002608 VReg *Vd = (VReg *)vd;
2609 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002610 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002611
Song Gao60df31a2023-09-14 10:26:35 +08002612 ofs = LSX_LEN / 64;
Song Gao399665d2023-05-04 20:28:00 +08002613 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002614 for (i = 0; i < oprsz / 16; i++) {
2615 for (j = 0; j < ofs; j++) {
2616 temp.UD(j + ofs * i) = float32_cvt_float64(Vj->UW(j + ofs * 2 * i),
2617 &env->fp_status);
2618 }
Song Gao399665d2023-05-04 20:28:00 +08002619 vec_update_fcsr0(env, GETPC());
2620 }
2621 *Vd = temp;
2622}
2623
Song Gao226bf882023-09-14 10:25:55 +08002624void HELPER(vfcvth_s_h)(void *vd, void *vj,
2625 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002626{
Song Gao60df31a2023-09-14 10:26:35 +08002627 int i, j, ofs;
2628 VReg temp = {};
Song Gao226bf882023-09-14 10:25:55 +08002629 VReg *Vd = (VReg *)vd;
2630 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002631 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002632
Song Gao60df31a2023-09-14 10:26:35 +08002633 ofs = LSX_LEN / 32;
Song Gao399665d2023-05-04 20:28:00 +08002634 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002635 for (i = 0; i < oprsz / 16; i++) {
2636 for (j = 0; j < ofs; j++) {
2637 temp.UW(j + ofs * i) = float16_cvt_float32(Vj->UH(j + ofs * (2 * i + 1)),
2638 &env->fp_status);
2639 }
Song Gao399665d2023-05-04 20:28:00 +08002640 vec_update_fcsr0(env, GETPC());
2641 }
2642 *Vd = temp;
2643}
2644
Song Gao226bf882023-09-14 10:25:55 +08002645void HELPER(vfcvth_d_s)(void *vd, void *vj,
2646 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002647{
Song Gao60df31a2023-09-14 10:26:35 +08002648 int i, j, ofs;
2649 VReg temp = {};
Song Gao226bf882023-09-14 10:25:55 +08002650 VReg *Vd = (VReg *)vd;
2651 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002652 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002653
Song Gao60df31a2023-09-14 10:26:35 +08002654 ofs = LSX_LEN / 64;
Song Gao399665d2023-05-04 20:28:00 +08002655 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002656 for (i = 0; i < oprsz / 16; i++) {
2657 for (j = 0; j < ofs; j++) {
2658 temp.UD(j + ofs * i) = float32_cvt_float64(Vj->UW(j + ofs * (2 * i + 1)),
2659 &env->fp_status);
2660 }
Song Gao399665d2023-05-04 20:28:00 +08002661 vec_update_fcsr0(env, GETPC());
2662 }
2663 *Vd = temp;
2664}
2665
Song Gao3b286752023-09-14 10:25:53 +08002666void HELPER(vfcvt_h_s)(void *vd, void *vj, void *vk,
2667 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002668{
Song Gao60df31a2023-09-14 10:26:35 +08002669 int i, j, ofs;
2670 VReg temp = {};
Song Gao3b286752023-09-14 10:25:53 +08002671 VReg *Vd = (VReg *)vd;
2672 VReg *Vj = (VReg *)vj;
2673 VReg *Vk = (VReg *)vk;
Song Gao60df31a2023-09-14 10:26:35 +08002674 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002675
Song Gao60df31a2023-09-14 10:26:35 +08002676 ofs = LSX_LEN / 32;
Song Gao399665d2023-05-04 20:28:00 +08002677 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002678 for(i = 0; i < oprsz / 16; i++) {
2679 for (j = 0; j < ofs; j++) {
2680 temp.UH(j + ofs * (2 * i + 1)) = float32_cvt_float16(Vj->UW(j + ofs * i),
2681 &env->fp_status);
2682 temp.UH(j + ofs * 2 * i) = float32_cvt_float16(Vk->UW(j + ofs * i),
2683 &env->fp_status);
2684 }
Song Gao399665d2023-05-04 20:28:00 +08002685 vec_update_fcsr0(env, GETPC());
2686 }
2687 *Vd = temp;
2688}
2689
Song Gao3b286752023-09-14 10:25:53 +08002690void HELPER(vfcvt_s_d)(void *vd, void *vj, void *vk,
2691 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002692{
Song Gao60df31a2023-09-14 10:26:35 +08002693 int i, j, ofs;
2694 VReg temp = {};
Song Gao3b286752023-09-14 10:25:53 +08002695 VReg *Vd = (VReg *)vd;
2696 VReg *Vj = (VReg *)vj;
2697 VReg *Vk = (VReg *)vk;
Song Gao60df31a2023-09-14 10:26:35 +08002698 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002699
Song Gao60df31a2023-09-14 10:26:35 +08002700 ofs = LSX_LEN / 64;
Song Gao399665d2023-05-04 20:28:00 +08002701 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002702 for(i = 0; i < oprsz / 16; i++) {
2703 for (j = 0; j < ofs; j++) {
2704 temp.UW(j + ofs * (2 * i + 1)) = float64_cvt_float32(Vj->UD(j + ofs * i),
2705 &env->fp_status);
2706 temp.UW(j + ofs * 2 * i) = float64_cvt_float32(Vk->UD(j + ofs * i),
2707 &env->fp_status);
2708 }
Song Gao399665d2023-05-04 20:28:00 +08002709 vec_update_fcsr0(env, GETPC());
2710 }
2711 *Vd = temp;
2712}
2713
Song Gao226bf882023-09-14 10:25:55 +08002714void HELPER(vfrint_s)(void *vd, void *vj,
2715 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002716{
2717 int i;
Song Gao226bf882023-09-14 10:25:55 +08002718 VReg *Vd = (VReg *)vd;
2719 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002720 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002721
2722 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002723 for (i = 0; i < oprsz / 4; i++) {
Song Gao399665d2023-05-04 20:28:00 +08002724 Vd->W(i) = float32_round_to_int(Vj->UW(i), &env->fp_status);
2725 vec_update_fcsr0(env, GETPC());
2726 }
2727}
2728
Song Gao226bf882023-09-14 10:25:55 +08002729void HELPER(vfrint_d)(void *vd, void *vj,
2730 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002731{
2732 int i;
Song Gao226bf882023-09-14 10:25:55 +08002733 VReg *Vd = (VReg *)vd;
2734 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002735 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002736
2737 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002738 for (i = 0; i < oprsz / 8; i++) {
Song Gao399665d2023-05-04 20:28:00 +08002739 Vd->D(i) = float64_round_to_int(Vj->UD(i), &env->fp_status);
2740 vec_update_fcsr0(env, GETPC());
2741 }
2742}
2743
2744#define FCVT_2OP(NAME, BIT, E, MODE) \
Song Gao226bf882023-09-14 10:25:55 +08002745void HELPER(NAME)(void *vd, void *vj, \
2746 CPULoongArchState *env, uint32_t desc) \
Song Gao399665d2023-05-04 20:28:00 +08002747{ \
2748 int i; \
Song Gao226bf882023-09-14 10:25:55 +08002749 VReg *Vd = (VReg *)vd; \
2750 VReg *Vj = (VReg *)vj; \
Song Gao60df31a2023-09-14 10:26:35 +08002751 int oprsz = simd_oprsz(desc); \
Song Gao399665d2023-05-04 20:28:00 +08002752 \
2753 vec_clear_cause(env); \
Song Gao60df31a2023-09-14 10:26:35 +08002754 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao399665d2023-05-04 20:28:00 +08002755 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); \
2756 set_float_rounding_mode(MODE, &env->fp_status); \
2757 Vd->E(i) = float## BIT ## _round_to_int(Vj->E(i), &env->fp_status); \
2758 set_float_rounding_mode(old_mode, &env->fp_status); \
2759 vec_update_fcsr0(env, GETPC()); \
2760 } \
2761}
2762
2763FCVT_2OP(vfrintrne_s, 32, UW, float_round_nearest_even)
2764FCVT_2OP(vfrintrne_d, 64, UD, float_round_nearest_even)
2765FCVT_2OP(vfrintrz_s, 32, UW, float_round_to_zero)
2766FCVT_2OP(vfrintrz_d, 64, UD, float_round_to_zero)
2767FCVT_2OP(vfrintrp_s, 32, UW, float_round_up)
2768FCVT_2OP(vfrintrp_d, 64, UD, float_round_up)
2769FCVT_2OP(vfrintrm_s, 32, UW, float_round_down)
2770FCVT_2OP(vfrintrm_d, 64, UD, float_round_down)
2771
2772#define FTINT(NAME, FMT1, FMT2, T1, T2, MODE) \
2773static T2 do_ftint ## NAME(CPULoongArchState *env, T1 fj) \
2774{ \
2775 T2 fd; \
2776 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); \
2777 \
2778 set_float_rounding_mode(MODE, &env->fp_status); \
2779 fd = do_## FMT1 ##_to_## FMT2(env, fj); \
2780 set_float_rounding_mode(old_mode, &env->fp_status); \
2781 return fd; \
2782}
2783
2784#define DO_FTINT(FMT1, FMT2, T1, T2) \
2785static T2 do_## FMT1 ##_to_## FMT2(CPULoongArchState *env, T1 fj) \
2786{ \
2787 T2 fd; \
2788 \
2789 fd = FMT1 ##_to_## FMT2(fj, &env->fp_status); \
2790 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) { \
2791 if (FMT1 ##_is_any_nan(fj)) { \
2792 fd = 0; \
2793 } \
2794 } \
2795 vec_update_fcsr0(env, GETPC()); \
2796 return fd; \
2797}
2798
2799DO_FTINT(float32, int32, uint32_t, uint32_t)
2800DO_FTINT(float64, int64, uint64_t, uint64_t)
2801DO_FTINT(float32, uint32, uint32_t, uint32_t)
2802DO_FTINT(float64, uint64, uint64_t, uint64_t)
2803DO_FTINT(float64, int32, uint64_t, uint32_t)
2804DO_FTINT(float32, int64, uint32_t, uint64_t)
2805
2806FTINT(rne_w_s, float32, int32, uint32_t, uint32_t, float_round_nearest_even)
2807FTINT(rne_l_d, float64, int64, uint64_t, uint64_t, float_round_nearest_even)
2808FTINT(rp_w_s, float32, int32, uint32_t, uint32_t, float_round_up)
2809FTINT(rp_l_d, float64, int64, uint64_t, uint64_t, float_round_up)
2810FTINT(rz_w_s, float32, int32, uint32_t, uint32_t, float_round_to_zero)
2811FTINT(rz_l_d, float64, int64, uint64_t, uint64_t, float_round_to_zero)
2812FTINT(rm_w_s, float32, int32, uint32_t, uint32_t, float_round_down)
2813FTINT(rm_l_d, float64, int64, uint64_t, uint64_t, float_round_down)
2814
2815DO_2OP_F(vftintrne_w_s, 32, UW, do_ftintrne_w_s)
2816DO_2OP_F(vftintrne_l_d, 64, UD, do_ftintrne_l_d)
2817DO_2OP_F(vftintrp_w_s, 32, UW, do_ftintrp_w_s)
2818DO_2OP_F(vftintrp_l_d, 64, UD, do_ftintrp_l_d)
2819DO_2OP_F(vftintrz_w_s, 32, UW, do_ftintrz_w_s)
2820DO_2OP_F(vftintrz_l_d, 64, UD, do_ftintrz_l_d)
2821DO_2OP_F(vftintrm_w_s, 32, UW, do_ftintrm_w_s)
2822DO_2OP_F(vftintrm_l_d, 64, UD, do_ftintrm_l_d)
2823DO_2OP_F(vftint_w_s, 32, UW, do_float32_to_int32)
2824DO_2OP_F(vftint_l_d, 64, UD, do_float64_to_int64)
2825
2826FTINT(rz_wu_s, float32, uint32, uint32_t, uint32_t, float_round_to_zero)
2827FTINT(rz_lu_d, float64, uint64, uint64_t, uint64_t, float_round_to_zero)
2828
2829DO_2OP_F(vftintrz_wu_s, 32, UW, do_ftintrz_wu_s)
2830DO_2OP_F(vftintrz_lu_d, 64, UD, do_ftintrz_lu_d)
2831DO_2OP_F(vftint_wu_s, 32, UW, do_float32_to_uint32)
2832DO_2OP_F(vftint_lu_d, 64, UD, do_float64_to_uint64)
2833
2834FTINT(rm_w_d, float64, int32, uint64_t, uint32_t, float_round_down)
2835FTINT(rp_w_d, float64, int32, uint64_t, uint32_t, float_round_up)
2836FTINT(rz_w_d, float64, int32, uint64_t, uint32_t, float_round_to_zero)
2837FTINT(rne_w_d, float64, int32, uint64_t, uint32_t, float_round_nearest_even)
2838
Song Gao60df31a2023-09-14 10:26:35 +08002839#define FTINT_W_D(NAME, FN) \
2840void HELPER(NAME)(void *vd, void *vj, void *vk, \
2841 CPULoongArchState *env, uint32_t desc) \
2842{ \
2843 int i, j, ofs; \
2844 VReg temp = {}; \
2845 VReg *Vd = (VReg *)vd; \
2846 VReg *Vj = (VReg *)vj; \
2847 VReg *Vk = (VReg *)vk; \
2848 int oprsz = simd_oprsz(desc); \
2849 \
2850 ofs = LSX_LEN / 64; \
2851 vec_clear_cause(env); \
2852 for (i = 0; i < oprsz / 16; i++) { \
2853 for (j = 0; j < ofs; j++) { \
2854 temp.W(j + ofs * (2 * i + 1)) = FN(env, Vj->UD(j + ofs * i)); \
2855 temp.W(j + ofs * 2 * i) = FN(env, Vk->UD(j + ofs * i)); \
2856 } \
2857 } \
2858 *Vd = temp; \
Song Gao399665d2023-05-04 20:28:00 +08002859}
2860
2861FTINT_W_D(vftint_w_d, do_float64_to_int32)
2862FTINT_W_D(vftintrm_w_d, do_ftintrm_w_d)
2863FTINT_W_D(vftintrp_w_d, do_ftintrp_w_d)
2864FTINT_W_D(vftintrz_w_d, do_ftintrz_w_d)
2865FTINT_W_D(vftintrne_w_d, do_ftintrne_w_d)
2866
2867FTINT(rml_l_s, float32, int64, uint32_t, uint64_t, float_round_down)
2868FTINT(rpl_l_s, float32, int64, uint32_t, uint64_t, float_round_up)
2869FTINT(rzl_l_s, float32, int64, uint32_t, uint64_t, float_round_to_zero)
2870FTINT(rnel_l_s, float32, int64, uint32_t, uint64_t, float_round_nearest_even)
2871FTINT(rmh_l_s, float32, int64, uint32_t, uint64_t, float_round_down)
2872FTINT(rph_l_s, float32, int64, uint32_t, uint64_t, float_round_up)
2873FTINT(rzh_l_s, float32, int64, uint32_t, uint64_t, float_round_to_zero)
2874FTINT(rneh_l_s, float32, int64, uint32_t, uint64_t, float_round_nearest_even)
2875
Song Gao60df31a2023-09-14 10:26:35 +08002876#define FTINTL_L_S(NAME, FN) \
2877void HELPER(NAME)(void *vd, void *vj, \
2878 CPULoongArchState *env, uint32_t desc) \
2879{ \
2880 int i, j, ofs; \
2881 VReg temp; \
2882 VReg *Vd = (VReg *)vd; \
2883 VReg *Vj = (VReg *)vj; \
2884 int oprsz = simd_oprsz(desc); \
2885 \
2886 ofs = LSX_LEN / 64; \
2887 vec_clear_cause(env); \
2888 for (i = 0; i < oprsz / 16; i++) { \
2889 for (j = 0; j < ofs; j++) { \
2890 temp.D(j + ofs * i) = FN(env, Vj->UW(j + ofs * 2 * i)); \
2891 } \
2892 } \
2893 *Vd = temp; \
Song Gao399665d2023-05-04 20:28:00 +08002894}
2895
2896FTINTL_L_S(vftintl_l_s, do_float32_to_int64)
2897FTINTL_L_S(vftintrml_l_s, do_ftintrml_l_s)
2898FTINTL_L_S(vftintrpl_l_s, do_ftintrpl_l_s)
2899FTINTL_L_S(vftintrzl_l_s, do_ftintrzl_l_s)
2900FTINTL_L_S(vftintrnel_l_s, do_ftintrnel_l_s)
2901
Song Gao60df31a2023-09-14 10:26:35 +08002902#define FTINTH_L_S(NAME, FN) \
2903void HELPER(NAME)(void *vd, void *vj, \
2904 CPULoongArchState *env, uint32_t desc) \
2905{ \
2906 int i, j, ofs; \
2907 VReg temp = {}; \
2908 VReg *Vd = (VReg *)vd; \
2909 VReg *Vj = (VReg *)vj; \
2910 int oprsz = simd_oprsz(desc); \
2911 \
2912 ofs = LSX_LEN / 64; \
2913 vec_clear_cause(env); \
2914 for (i = 0; i < oprsz / 16; i++) { \
2915 for (j = 0; j < ofs; j++) { \
2916 temp.D(j + ofs * i) = FN(env, Vj->UW(j + ofs * (2 * i + 1))); \
2917 } \
2918 } \
2919 *Vd = temp; \
Song Gao399665d2023-05-04 20:28:00 +08002920}
2921
2922FTINTH_L_S(vftinth_l_s, do_float32_to_int64)
2923FTINTH_L_S(vftintrmh_l_s, do_ftintrmh_l_s)
2924FTINTH_L_S(vftintrph_l_s, do_ftintrph_l_s)
2925FTINTH_L_S(vftintrzh_l_s, do_ftintrzh_l_s)
2926FTINTH_L_S(vftintrneh_l_s, do_ftintrneh_l_s)
2927
2928#define FFINT(NAME, FMT1, FMT2, T1, T2) \
2929static T2 do_ffint_ ## NAME(CPULoongArchState *env, T1 fj) \
2930{ \
2931 T2 fd; \
2932 \
2933 fd = FMT1 ##_to_## FMT2(fj, &env->fp_status); \
2934 vec_update_fcsr0(env, GETPC()); \
2935 return fd; \
2936}
2937
2938FFINT(s_w, int32, float32, int32_t, uint32_t)
2939FFINT(d_l, int64, float64, int64_t, uint64_t)
2940FFINT(s_wu, uint32, float32, uint32_t, uint32_t)
2941FFINT(d_lu, uint64, float64, uint64_t, uint64_t)
2942
2943DO_2OP_F(vffint_s_w, 32, W, do_ffint_s_w)
2944DO_2OP_F(vffint_d_l, 64, D, do_ffint_d_l)
2945DO_2OP_F(vffint_s_wu, 32, UW, do_ffint_s_wu)
2946DO_2OP_F(vffint_d_lu, 64, UD, do_ffint_d_lu)
2947
Song Gao226bf882023-09-14 10:25:55 +08002948void HELPER(vffintl_d_w)(void *vd, void *vj,
2949 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002950{
Song Gao60df31a2023-09-14 10:26:35 +08002951 int i, j, ofs;
2952 VReg temp = {};
Song Gao226bf882023-09-14 10:25:55 +08002953 VReg *Vd = (VReg *)vd;
2954 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002955 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002956
Song Gao60df31a2023-09-14 10:26:35 +08002957 ofs = LSX_LEN / 64;
Song Gao399665d2023-05-04 20:28:00 +08002958 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002959 for (i = 0; i < oprsz / 16; i++) {
2960 for (j = 0; j < ofs; j++) {
2961 temp.D(j + ofs * i) = int32_to_float64(Vj->W(j + ofs * 2 * i),
2962 &env->fp_status);
2963 }
Song Gao399665d2023-05-04 20:28:00 +08002964 vec_update_fcsr0(env, GETPC());
2965 }
2966 *Vd = temp;
2967}
2968
Song Gao226bf882023-09-14 10:25:55 +08002969void HELPER(vffinth_d_w)(void *vd, void *vj,
2970 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002971{
Song Gao60df31a2023-09-14 10:26:35 +08002972 int i, j, ofs;
2973 VReg temp = {};
Song Gao226bf882023-09-14 10:25:55 +08002974 VReg *Vd = (VReg *)vd;
2975 VReg *Vj = (VReg *)vj;
Song Gao60df31a2023-09-14 10:26:35 +08002976 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002977
Song Gao60df31a2023-09-14 10:26:35 +08002978 ofs = LSX_LEN / 64;
Song Gao399665d2023-05-04 20:28:00 +08002979 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08002980 for (i = 0; i < oprsz /16; i++) {
2981 for (j = 0; j < ofs; j++) {
2982 temp.D(j + ofs * i) = int32_to_float64(Vj->W(j + ofs * (2 * i + 1)),
2983 &env->fp_status);
2984 }
Song Gao399665d2023-05-04 20:28:00 +08002985 vec_update_fcsr0(env, GETPC());
2986 }
2987 *Vd = temp;
2988}
2989
Song Gao3b286752023-09-14 10:25:53 +08002990void HELPER(vffint_s_l)(void *vd, void *vj, void *vk,
2991 CPULoongArchState *env, uint32_t desc)
Song Gao399665d2023-05-04 20:28:00 +08002992{
Song Gao60df31a2023-09-14 10:26:35 +08002993 int i, j, ofs;
2994 VReg temp = {};
Song Gao3b286752023-09-14 10:25:53 +08002995 VReg *Vd = (VReg *)vd;
2996 VReg *Vj = (VReg *)vj;
2997 VReg *Vk = (VReg *)vk;
Song Gao60df31a2023-09-14 10:26:35 +08002998 int oprsz = simd_oprsz(desc);
Song Gao399665d2023-05-04 20:28:00 +08002999
Song Gao60df31a2023-09-14 10:26:35 +08003000 ofs = LSX_LEN / 64;
Song Gao399665d2023-05-04 20:28:00 +08003001 vec_clear_cause(env);
Song Gao60df31a2023-09-14 10:26:35 +08003002 for (i = 0; i < oprsz / 16; i++) {
3003 for (j = 0; j < ofs; j++) {
3004 temp.W(j + ofs * (2 * i + 1)) = int64_to_float32(Vj->D(j + ofs * i),
3005 &env->fp_status);
3006 temp.W(j + ofs * 2 * i) = int64_to_float32(Vk->D(j + ofs * i),
3007 &env->fp_status);
3008 }
Song Gao399665d2023-05-04 20:28:00 +08003009 vec_update_fcsr0(env, GETPC());
3010 }
3011 *Vd = temp;
3012}
Song Gaof435e1e2023-05-04 20:28:01 +08003013
Song Gao4da72d42023-09-14 10:26:36 +08003014#define VCMPI(NAME, BIT, E, DO_OP) \
3015void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
3016{ \
3017 int i; \
3018 VReg *Vd = (VReg *)vd; \
3019 VReg *Vj = (VReg *)vj; \
3020 typedef __typeof(Vd->E(0)) TD; \
3021 int oprsz = simd_oprsz(desc); \
3022 \
3023 for (i = 0; i < oprsz / (BIT / 8); i++) { \
3024 Vd->E(i) = DO_OP(Vj->E(i), (TD)imm); \
3025 } \
Song Gaof435e1e2023-05-04 20:28:01 +08003026}
3027
3028VCMPI(vseqi_b, 8, B, VSEQ)
3029VCMPI(vseqi_h, 16, H, VSEQ)
3030VCMPI(vseqi_w, 32, W, VSEQ)
3031VCMPI(vseqi_d, 64, D, VSEQ)
3032VCMPI(vslei_b, 8, B, VSLE)
3033VCMPI(vslei_h, 16, H, VSLE)
3034VCMPI(vslei_w, 32, W, VSLE)
3035VCMPI(vslei_d, 64, D, VSLE)
3036VCMPI(vslei_bu, 8, UB, VSLE)
3037VCMPI(vslei_hu, 16, UH, VSLE)
3038VCMPI(vslei_wu, 32, UW, VSLE)
3039VCMPI(vslei_du, 64, UD, VSLE)
3040VCMPI(vslti_b, 8, B, VSLT)
3041VCMPI(vslti_h, 16, H, VSLT)
3042VCMPI(vslti_w, 32, W, VSLT)
3043VCMPI(vslti_d, 64, D, VSLT)
3044VCMPI(vslti_bu, 8, UB, VSLT)
3045VCMPI(vslti_hu, 16, UH, VSLT)
3046VCMPI(vslti_wu, 32, UW, VSLT)
3047VCMPI(vslti_du, 64, UD, VSLT)
Song Gao386c4e82023-05-04 20:28:02 +08003048
3049static uint64_t vfcmp_common(CPULoongArchState *env,
3050 FloatRelation cmp, uint32_t flags)
3051{
3052 uint64_t ret = 0;
3053
3054 switch (cmp) {
3055 case float_relation_less:
3056 ret = (flags & FCMP_LT);
3057 break;
3058 case float_relation_equal:
3059 ret = (flags & FCMP_EQ);
3060 break;
3061 case float_relation_greater:
3062 ret = (flags & FCMP_GT);
3063 break;
3064 case float_relation_unordered:
3065 ret = (flags & FCMP_UN);
3066 break;
3067 default:
3068 g_assert_not_reached();
3069 }
3070
3071 if (ret) {
3072 ret = -1;
3073 }
3074
3075 return ret;
3076}
3077
3078#define VFCMP(NAME, BIT, E, FN) \
Song Gao3eeda5f2023-09-14 10:26:37 +08003079void HELPER(NAME)(CPULoongArchState *env, uint32_t oprsz, \
Song Gao386c4e82023-05-04 20:28:02 +08003080 uint32_t vd, uint32_t vj, uint32_t vk, uint32_t flags) \
3081{ \
3082 int i; \
3083 VReg t; \
3084 VReg *Vd = &(env->fpr[vd].vreg); \
3085 VReg *Vj = &(env->fpr[vj].vreg); \
3086 VReg *Vk = &(env->fpr[vk].vreg); \
3087 \
3088 vec_clear_cause(env); \
Song Gao3eeda5f2023-09-14 10:26:37 +08003089 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao386c4e82023-05-04 20:28:02 +08003090 FloatRelation cmp; \
3091 cmp = FN(Vj->E(i), Vk->E(i), &env->fp_status); \
3092 t.E(i) = vfcmp_common(env, cmp, flags); \
3093 vec_update_fcsr0(env, GETPC()); \
3094 } \
3095 *Vd = t; \
3096}
3097
3098VFCMP(vfcmp_c_s, 32, UW, float32_compare_quiet)
3099VFCMP(vfcmp_s_s, 32, UW, float32_compare)
3100VFCMP(vfcmp_c_d, 64, UD, float64_compare_quiet)
3101VFCMP(vfcmp_s_d, 64, UD, float64_compare)
Song Gaod0dfa192023-05-04 20:28:03 +08003102
Song Gaof3dfcc82023-09-14 10:26:38 +08003103void HELPER(vbitseli_b)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaod0dfa192023-05-04 20:28:03 +08003104{
3105 int i;
3106 VReg *Vd = (VReg *)vd;
3107 VReg *Vj = (VReg *)vj;
3108
Song Gaof3dfcc82023-09-14 10:26:38 +08003109 for (i = 0; i < simd_oprsz(desc); i++) {
Song Gaod0dfa192023-05-04 20:28:03 +08003110 Vd->B(i) = (~Vd->B(i) & Vj->B(i)) | (Vd->B(i) & imm);
3111 }
3112}
3113
3114/* Copy from target/arm/tcg/sve_helper.c */
3115static inline bool do_match2(uint64_t n, uint64_t m0, uint64_t m1, int esz)
3116{
Song Gaof3dfcc82023-09-14 10:26:38 +08003117 int bits = 8 << esz;
Song Gaod0dfa192023-05-04 20:28:03 +08003118 uint64_t ones = dup_const(esz, 1);
3119 uint64_t signs = ones << (bits - 1);
3120 uint64_t cmp0, cmp1;
3121
3122 cmp1 = dup_const(esz, n);
3123 cmp0 = cmp1 ^ m0;
3124 cmp1 = cmp1 ^ m1;
3125 cmp0 = (cmp0 - ones) & ~cmp0;
3126 cmp1 = (cmp1 - ones) & ~cmp1;
3127 return (cmp0 | cmp1) & signs;
3128}
3129
Song Gaof3dfcc82023-09-14 10:26:38 +08003130#define SETANYEQZ(NAME, MO) \
3131void HELPER(NAME)(CPULoongArchState *env, \
3132 uint32_t oprsz, uint32_t cd, uint32_t vj) \
3133{ \
3134 VReg *Vj = &(env->fpr[vj].vreg); \
3135 \
3136 env->cf[cd & 0x7] = do_match2(0, Vj->D(0), Vj->D(1), MO); \
3137 if (oprsz == 32) { \
3138 env->cf[cd & 0x7] = env->cf[cd & 0x7] || \
3139 do_match2(0, Vj->D(2), Vj->D(3), MO); \
3140 } \
Song Gaod0dfa192023-05-04 20:28:03 +08003141}
Song Gaof3dfcc82023-09-14 10:26:38 +08003142
Song Gaod0dfa192023-05-04 20:28:03 +08003143SETANYEQZ(vsetanyeqz_b, MO_8)
3144SETANYEQZ(vsetanyeqz_h, MO_16)
3145SETANYEQZ(vsetanyeqz_w, MO_32)
3146SETANYEQZ(vsetanyeqz_d, MO_64)
3147
Song Gaof3dfcc82023-09-14 10:26:38 +08003148#define SETALLNEZ(NAME, MO) \
3149void HELPER(NAME)(CPULoongArchState *env, \
3150 uint32_t oprsz, uint32_t cd, uint32_t vj) \
3151{ \
3152 VReg *Vj = &(env->fpr[vj].vreg); \
3153 \
3154 env->cf[cd & 0x7]= !do_match2(0, Vj->D(0), Vj->D(1), MO); \
3155 if (oprsz == 32) { \
3156 env->cf[cd & 0x7] = env->cf[cd & 0x7] && \
3157 !do_match2(0, Vj->D(2), Vj->D(3), MO); \
3158 } \
Song Gaod0dfa192023-05-04 20:28:03 +08003159}
Song Gaof3dfcc82023-09-14 10:26:38 +08003160
Song Gaod0dfa192023-05-04 20:28:03 +08003161SETALLNEZ(vsetallnez_b, MO_8)
3162SETALLNEZ(vsetallnez_h, MO_16)
3163SETALLNEZ(vsetallnez_w, MO_32)
3164SETALLNEZ(vsetallnez_d, MO_64)
Song Gaod5e55632023-05-04 20:28:05 +08003165
Song Gaodf97f332023-09-14 10:26:40 +08003166#define XVINSVE0(NAME, E, MASK) \
3167void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
3168{ \
3169 VReg *Vd = (VReg *)vd; \
3170 VReg *Vj = (VReg *)vj; \
3171 Vd->E(imm & MASK) = Vj->E(0); \
3172}
3173
3174XVINSVE0(xvinsve0_w, W, 0x7)
3175XVINSVE0(xvinsve0_d, D, 0x3)
3176
3177#define XVPICKVE(NAME, E, BIT, MASK) \
3178void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
3179{ \
3180 int i; \
3181 VReg *Vd = (VReg *)vd; \
3182 VReg *Vj = (VReg *)vj; \
3183 int oprsz = simd_oprsz(desc); \
3184 \
3185 Vd->E(0) = Vj->E(imm & MASK); \
3186 for (i = 1; i < oprsz / (BIT / 8); i++) { \
3187 Vd->E(i) = 0; \
3188 } \
3189}
3190
3191XVPICKVE(xvpickve_w, W, 32, 0x7)
3192XVPICKVE(xvpickve_d, D, 64, 0x3)
3193
Song Gao04711da2023-09-14 10:25:54 +08003194#define VPACKEV(NAME, BIT, E) \
3195void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3196{ \
3197 int i; \
Song Gaoad292142023-09-14 10:26:41 +08003198 VReg temp = {}; \
Song Gao04711da2023-09-14 10:25:54 +08003199 VReg *Vd = (VReg *)vd; \
3200 VReg *Vj = (VReg *)vj; \
3201 VReg *Vk = (VReg *)vk; \
Song Gaoad292142023-09-14 10:26:41 +08003202 int oprsz = simd_oprsz(desc); \
Song Gao04711da2023-09-14 10:25:54 +08003203 \
Song Gaoad292142023-09-14 10:26:41 +08003204 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao04711da2023-09-14 10:25:54 +08003205 temp.E(2 * i + 1) = Vj->E(2 * i); \
3206 temp.E(2 *i) = Vk->E(2 * i); \
3207 } \
3208 *Vd = temp; \
Song Gaod5e55632023-05-04 20:28:05 +08003209}
3210
3211VPACKEV(vpackev_b, 16, B)
3212VPACKEV(vpackev_h, 32, H)
3213VPACKEV(vpackev_w, 64, W)
3214VPACKEV(vpackev_d, 128, D)
3215
Song Gao04711da2023-09-14 10:25:54 +08003216#define VPACKOD(NAME, BIT, E) \
3217void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3218{ \
3219 int i; \
Song Gaoad292142023-09-14 10:26:41 +08003220 VReg temp = {}; \
Song Gao04711da2023-09-14 10:25:54 +08003221 VReg *Vd = (VReg *)vd; \
3222 VReg *Vj = (VReg *)vj; \
3223 VReg *Vk = (VReg *)vk; \
Song Gaoad292142023-09-14 10:26:41 +08003224 int oprsz = simd_oprsz(desc); \
Song Gao04711da2023-09-14 10:25:54 +08003225 \
Song Gaoad292142023-09-14 10:26:41 +08003226 for (i = 0; i < oprsz / (BIT / 8); i++) { \
Song Gao04711da2023-09-14 10:25:54 +08003227 temp.E(2 * i + 1) = Vj->E(2 * i + 1); \
3228 temp.E(2 * i) = Vk->E(2 * i + 1); \
3229 } \
3230 *Vd = temp; \
Song Gaod5e55632023-05-04 20:28:05 +08003231}
3232
3233VPACKOD(vpackod_b, 16, B)
3234VPACKOD(vpackod_h, 32, H)
3235VPACKOD(vpackod_w, 64, W)
3236VPACKOD(vpackod_d, 128, D)
3237
Song Gaoad292142023-09-14 10:26:41 +08003238#define VPICKEV(NAME, BIT, E) \
3239void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3240{ \
3241 int i, j, ofs; \
3242 VReg temp = {}; \
3243 VReg *Vd = (VReg *)vd; \
3244 VReg *Vj = (VReg *)vj; \
3245 VReg *Vk = (VReg *)vk; \
3246 int oprsz = simd_oprsz(desc); \
3247 \
3248 ofs = LSX_LEN / BIT; \
3249 for (i = 0; i < oprsz / 16; i++) { \
3250 for (j = 0; j < ofs; j++) { \
3251 temp.E(j + ofs * (2 * i + 1)) = Vj->E(2 * (j + ofs * i)); \
3252 temp.E(j + ofs * 2 * i) = Vk->E(2 * (j + ofs * i)); \
3253 } \
3254 } \
3255 *Vd = temp; \
Song Gaod5e55632023-05-04 20:28:05 +08003256}
3257
3258VPICKEV(vpickev_b, 16, B)
3259VPICKEV(vpickev_h, 32, H)
3260VPICKEV(vpickev_w, 64, W)
3261VPICKEV(vpickev_d, 128, D)
3262
Song Gaoad292142023-09-14 10:26:41 +08003263#define VPICKOD(NAME, BIT, E) \
3264void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3265{ \
3266 int i, j, ofs; \
3267 VReg temp = {}; \
3268 VReg *Vd = (VReg *)vd; \
3269 VReg *Vj = (VReg *)vj; \
3270 VReg *Vk = (VReg *)vk; \
3271 int oprsz = simd_oprsz(desc); \
3272 \
3273 ofs = LSX_LEN / BIT; \
3274 for (i = 0; i < oprsz / 16; i++) { \
3275 for (j = 0; j < ofs; j++) { \
3276 temp.E(j + ofs * (2 * i + 1)) = Vj->E(2 * (j + ofs * i) + 1); \
3277 temp.E(j + ofs * 2 * i) = Vk->E(2 * (j + ofs * i) + 1); \
3278 } \
3279 } \
3280 *Vd = temp; \
Song Gaod5e55632023-05-04 20:28:05 +08003281}
3282
3283VPICKOD(vpickod_b, 16, B)
3284VPICKOD(vpickod_h, 32, H)
3285VPICKOD(vpickod_w, 64, W)
3286VPICKOD(vpickod_d, 128, D)
Song Gaoe93dd432023-05-04 20:28:06 +08003287
Song Gaoad292142023-09-14 10:26:41 +08003288#define VILVL(NAME, BIT, E) \
3289void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3290{ \
3291 int i, j, ofs; \
3292 VReg temp = {}; \
3293 VReg *Vd = (VReg *)vd; \
3294 VReg *Vj = (VReg *)vj; \
3295 VReg *Vk = (VReg *)vk; \
3296 int oprsz = simd_oprsz(desc); \
3297 \
3298 ofs = LSX_LEN / BIT; \
3299 for (i = 0; i < oprsz / 16; i++) { \
3300 for (j = 0; j < ofs; j++) { \
3301 temp.E(2 * (j + ofs * i) + 1) = Vj->E(j + ofs * 2 * i); \
3302 temp.E(2 * (j + ofs * i)) = Vk->E(j + ofs * 2 * i); \
3303 } \
3304 } \
3305 *Vd = temp; \
Song Gaoe93dd432023-05-04 20:28:06 +08003306}
3307
3308VILVL(vilvl_b, 16, B)
3309VILVL(vilvl_h, 32, H)
3310VILVL(vilvl_w, 64, W)
3311VILVL(vilvl_d, 128, D)
3312
Song Gaoad292142023-09-14 10:26:41 +08003313#define VILVH(NAME, BIT, E) \
3314void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3315{ \
3316 int i, j, ofs; \
3317 VReg temp = {}; \
3318 VReg *Vd = (VReg *)vd; \
3319 VReg *Vj = (VReg *)vj; \
3320 VReg *Vk = (VReg *)vk; \
3321 int oprsz = simd_oprsz(desc); \
3322 \
3323 ofs = LSX_LEN / BIT; \
3324 for (i = 0; i < oprsz / 16; i++) { \
3325 for (j = 0; j < ofs; j++) { \
3326 temp.E(2 * (j + ofs * i) + 1) = Vj->E(j + ofs * (2 * i + 1)); \
3327 temp.E(2 * (j + ofs * i)) = Vk->E(j + ofs * (2 * i + 1)); \
3328 } \
3329 } \
3330 *Vd = temp; \
Song Gaoe93dd432023-05-04 20:28:06 +08003331}
3332
3333VILVH(vilvh_b, 16, B)
3334VILVH(vilvh_h, 32, H)
3335VILVH(vilvh_w, 64, W)
3336VILVH(vilvh_d, 128, D)
3337
Song Gaoeb48ab22023-09-14 10:25:52 +08003338void HELPER(vshuf_b)(void *vd, void *vj, void *vk, void *va, uint32_t desc)
Song Gaoe93dd432023-05-04 20:28:06 +08003339{
Song Gao513e88a2023-09-14 10:26:42 +08003340 int i, j, m;
3341 VReg temp = {};
Song Gaoeb48ab22023-09-14 10:25:52 +08003342 VReg *Vd = (VReg *)vd;
3343 VReg *Vj = (VReg *)vj;
3344 VReg *Vk = (VReg *)vk;
3345 VReg *Va = (VReg *)va;
Song Gao513e88a2023-09-14 10:26:42 +08003346 int oprsz = simd_oprsz(desc);
Song Gaoe93dd432023-05-04 20:28:06 +08003347
Song Gao513e88a2023-09-14 10:26:42 +08003348 m = LSX_LEN / 8;
3349 for (i = 0; i < (oprsz / 16) * m; i++) {
3350 j = i < m ? 0 : 1;
Song Gaoe93dd432023-05-04 20:28:06 +08003351 uint64_t k = (uint8_t)Va->B(i) % (2 * m);
Song Gao513e88a2023-09-14 10:26:42 +08003352 temp.B(i) = k < m ? Vk->B(k + j * m): Vj->B(k + (j - 1) * m);
Song Gaoe93dd432023-05-04 20:28:06 +08003353 }
3354 *Vd = temp;
3355}
3356
Song Gao513e88a2023-09-14 10:26:42 +08003357#define VSHUF(NAME, BIT, E) \
3358void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
3359{ \
3360 int i, j, m; \
3361 VReg temp = {}; \
3362 VReg *Vd = (VReg *)vd; \
3363 VReg *Vj = (VReg *)vj; \
3364 VReg *Vk = (VReg *)vk; \
3365 int oprsz = simd_oprsz(desc); \
3366 \
3367 m = LSX_LEN / BIT; \
3368 for (i = 0; i < (oprsz / 16) * m; i++) { \
3369 j = i < m ? 0 : 1; \
3370 uint64_t k = ((uint8_t)Vd->E(i)) % (2 * m); \
3371 temp.E(i) = k < m ? Vk->E(k + j * m) : Vj->E(k + (j - 1) * m); \
3372 } \
3373 *Vd = temp; \
Song Gaoe93dd432023-05-04 20:28:06 +08003374}
3375
3376VSHUF(vshuf_h, 16, H)
3377VSHUF(vshuf_w, 32, W)
3378VSHUF(vshuf_d, 64, D)
3379
Song Gao513e88a2023-09-14 10:26:42 +08003380#define VSHUF4I(NAME, BIT, E) \
3381void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
3382{ \
3383 int i, j, max; \
3384 VReg temp = {}; \
3385 VReg *Vd = (VReg *)vd; \
3386 VReg *Vj = (VReg *)vj; \
3387 int oprsz = simd_oprsz(desc); \
3388 \
3389 max = LSX_LEN / BIT; \
3390 for (i = 0; i < oprsz / (BIT / 8); i++) { \
3391 j = i < max ? 1 : 2; \
3392 temp.E(i) = Vj->E(SHF_POS(i - ((j -1)* max), imm) + (j - 1) * max); \
3393 } \
3394 *Vd = temp; \
Song Gaoe93dd432023-05-04 20:28:06 +08003395}
3396
3397VSHUF4I(vshuf4i_b, 8, B)
3398VSHUF4I(vshuf4i_h, 16, H)
3399VSHUF4I(vshuf4i_w, 32, W)
3400
Song Gao329517d2023-09-14 10:25:57 +08003401void HELPER(vshuf4i_d)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaoe93dd432023-05-04 20:28:06 +08003402{
Song Gao513e88a2023-09-14 10:26:42 +08003403 int i;
3404 VReg temp = {};
Song Gao329517d2023-09-14 10:25:57 +08003405 VReg *Vd = (VReg *)vd;
3406 VReg *Vj = (VReg *)vj;
Song Gao513e88a2023-09-14 10:26:42 +08003407 int oprsz = simd_oprsz(desc);
Song Gaoe93dd432023-05-04 20:28:06 +08003408
Song Gao513e88a2023-09-14 10:26:42 +08003409 for (i = 0; i < oprsz / 16; i++) {
3410 temp.D(2 * i) = (imm & 2 ? Vj : Vd)->D((imm & 1) + 2 * i);
3411 temp.D(2 * i + 1) = (imm & 8 ? Vj : Vd)->D(((imm >> 2) & 1) + 2 * i);
3412 }
3413 *Vd = temp;
3414}
3415
3416void HELPER(vperm_w)(void *vd, void *vj, void *vk, uint32_t desc)
3417{
3418 int i, m;
3419 VReg temp = {};
3420 VReg *Vd = (VReg *)vd;
3421 VReg *Vj = (VReg *)vj;
3422 VReg *Vk = (VReg *)vk;
3423
3424 m = LASX_LEN / 32;
3425 for (i = 0; i < m ; i++) {
3426 uint64_t k = (uint8_t)Vk->W(i) % 8;
3427 temp.W(i) = Vj->W(k);
3428 }
Song Gaoe93dd432023-05-04 20:28:06 +08003429 *Vd = temp;
3430}
3431
Song Gao329517d2023-09-14 10:25:57 +08003432void HELPER(vpermi_w)(void *vd, void *vj, uint64_t imm, uint32_t desc)
Song Gaoe93dd432023-05-04 20:28:06 +08003433{
Song Gao513e88a2023-09-14 10:26:42 +08003434 int i;
3435 VReg temp = {};
3436 VReg *Vd = (VReg *)vd;
3437 VReg *Vj = (VReg *)vj;
3438 int oprsz = simd_oprsz(desc);
3439
3440 for (i = 0; i < oprsz / 16; i++) {
3441 temp.W(4 * i) = Vj->W((imm & 0x3) + 4 * i);
3442 temp.W(4 * i + 1) = Vj->W(((imm >> 2) & 0x3) + 4 * i);
3443 temp.W(4 * i + 2) = Vd->W(((imm >> 4) & 0x3) + 4 * i);
3444 temp.W(4 * i + 3) = Vd->W(((imm >> 6) & 0x3) + 4 * i);
3445 }
3446 *Vd = temp;
3447}
3448
3449void HELPER(vpermi_d)(void *vd, void *vj, uint64_t imm, uint32_t desc)
3450{
3451 VReg temp = {};
3452 VReg *Vd = (VReg *)vd;
3453 VReg *Vj = (VReg *)vj;
3454
3455 temp.D(0) = Vj->D(imm & 0x3);
3456 temp.D(1) = Vj->D((imm >> 2) & 0x3);
3457 temp.D(2) = Vj->D((imm >> 4) & 0x3);
3458 temp.D(3) = Vj->D((imm >> 6) & 0x3);
3459 *Vd = temp;
3460}
3461
3462void HELPER(vpermi_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
3463{
3464 int i;
Song Gaoe93dd432023-05-04 20:28:06 +08003465 VReg temp;
Song Gao329517d2023-09-14 10:25:57 +08003466 VReg *Vd = (VReg *)vd;
3467 VReg *Vj = (VReg *)vj;
Song Gaoe93dd432023-05-04 20:28:06 +08003468
Song Gao513e88a2023-09-14 10:26:42 +08003469 for (i = 0; i < 2; i++, imm >>= 4) {
3470 temp.Q(i) = (imm & 2 ? Vd: Vj)->Q(imm & 1);
3471 }
Song Gaoe93dd432023-05-04 20:28:06 +08003472 *Vd = temp;
3473}
3474
Song Gao329517d2023-09-14 10:25:57 +08003475#define VEXTRINS(NAME, BIT, E, MASK) \
3476void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
3477{ \
Song Gao513e88a2023-09-14 10:26:42 +08003478 int i, ins, extr, max; \
Song Gao329517d2023-09-14 10:25:57 +08003479 VReg *Vd = (VReg *)vd; \
3480 VReg *Vj = (VReg *)vj; \
Song Gao513e88a2023-09-14 10:26:42 +08003481 int oprsz = simd_oprsz(desc); \
Song Gao329517d2023-09-14 10:25:57 +08003482 \
Song Gao513e88a2023-09-14 10:26:42 +08003483 max = LSX_LEN / BIT; \
Song Gao329517d2023-09-14 10:25:57 +08003484 ins = (imm >> 4) & MASK; \
3485 extr = imm & MASK; \
Song Gao513e88a2023-09-14 10:26:42 +08003486 for (i = 0; i < oprsz / 16; i++) { \
3487 Vd->E(ins + i * max) = Vj->E(extr + i * max); \
3488 } \
Song Gaoe93dd432023-05-04 20:28:06 +08003489}
3490
3491VEXTRINS(vextrins_b, 8, B, 0xf)
3492VEXTRINS(vextrins_h, 16, H, 0x7)
3493VEXTRINS(vextrins_w, 32, W, 0x3)
3494VEXTRINS(vextrins_d, 64, D, 0x1)