1use crate::intrinsics::simd::*;
4
5pub(super) const trait SimdExt: Sized {
11 type Elem;
12
13 unsafe fn splat(v: i64) -> Self;
14}
15
16#[rustfmt::skip] macro_rules! impl_simd_ext {
18 ($v:ident, $e:ty) => {
19 #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
20 const impl SimdExt for crate::core_arch::simd::$v {
21 type Elem = $e;
22
23 #[inline(always)]
24 unsafe fn splat(v: i64) -> Self {
25 simd_splat(v as Self::Elem)
26 }
27 }
28 };
29}
30
31impl_simd_ext!(i8x16, i8);
32impl_simd_ext!(i8x32, i8);
33impl_simd_ext!(u8x16, u8);
34impl_simd_ext!(u8x32, u8);
35impl_simd_ext!(i16x8, i16);
36impl_simd_ext!(i16x16, i16);
37impl_simd_ext!(i16x32, i16);
38impl_simd_ext!(u16x8, u16);
39impl_simd_ext!(u16x16, u16);
40impl_simd_ext!(u16x32, u16);
41impl_simd_ext!(i32x4, i32);
42impl_simd_ext!(i32x8, i32);
43impl_simd_ext!(i32x16, i32);
44impl_simd_ext!(u32x4, u32);
45impl_simd_ext!(u32x8, u32);
46impl_simd_ext!(u32x16, u32);
47impl_simd_ext!(i64x2, i64);
48impl_simd_ext!(i64x4, i64);
49impl_simd_ext!(i64x8, i64);
50impl_simd_ext!(u64x2, u64);
51impl_simd_ext!(u64x4, u64);
52impl_simd_ext!(u64x8, u64);
53impl_simd_ext!(i128x2, i128);
54impl_simd_ext!(u128x2, u128);
55impl_simd_ext!(i128x4, i128);
56impl_simd_ext!(u128x4, u128);
57
58#[inline(always)]
59#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
60pub(super) const unsafe fn simd_ext_abs<T: Copy + const SimdExt>(a: T) -> T {
61 let m: T = simd_lt(a, simd_ext_splat(0));
62 simd_select(m, simd_neg(a), a)
63}
64
65#[inline(always)]
66#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
67pub(super) const unsafe fn simd_ext_absd<T: Copy>(a: T, b: T) -> T {
68 let m: T = simd_gt(a, b);
69 simd_select(m, simd_sub(a, b), simd_sub(b, a))
70}
71
72#[inline(always)]
73#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
74pub(super) const unsafe fn simd_ext_adda<T: Copy + const SimdExt>(a: T, b: T) -> T {
75 simd_add(simd_ext_abs(a), simd_ext_abs(b))
76}
77
78#[inline(always)]
79#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
80pub(super) const unsafe fn simd_ext_andn<T: Copy + const SimdExt>(a: T, b: T) -> T {
81 simd_and(simd_ext_not(a), b)
82}
83
84#[inline(always)]
85#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
86pub(super) const unsafe fn simd_ext_bitclr<T: Copy + const SimdExt>(a: T, b: T) -> T {
87 simd_ext_andn(simd_ext_shl(simd_ext_splat(1), b), a)
88}
89
90#[inline(always)]
91#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
92pub(super) const unsafe fn simd_ext_bitrev<T: Copy + const SimdExt>(a: T, b: T) -> T {
93 simd_xor(simd_ext_shl(simd_ext_splat(1), b), a)
94}
95
96#[inline(always)]
97#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
98pub(super) const unsafe fn simd_ext_bitset<T: Copy + const SimdExt>(a: T, b: T) -> T {
99 simd_or(simd_ext_shl(simd_ext_splat(1), b), a)
100}
101
102#[inline(always)]
103#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
104pub(super) const unsafe fn simd_ext_fmsub<T: Copy>(a: T, b: T, c: T) -> T {
105 simd_fma(a, b, simd_neg(c))
106}
107
108#[inline(always)]
109#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
110pub(super) const unsafe fn simd_ext_fnmadd<T: Copy>(a: T, b: T, c: T) -> T {
111 simd_neg(simd_fma(a, b, c))
112}
113
114#[inline(always)]
115#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
116pub(super) const unsafe fn simd_ext_fnmsub<T: Copy>(a: T, b: T, c: T) -> T {
117 simd_neg(simd_ext_fmsub(a, b, c))
118}
119
120#[inline(always)]
121#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
122pub(super) const unsafe fn simd_ext_frecip_s<T: Copy>(a: T) -> T {
123 simd_div(simd_splat(1.0f32), a)
124}
125
126#[inline(always)]
127#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
128pub(super) const unsafe fn simd_ext_frecip_d<T: Copy>(a: T) -> T {
129 simd_div(simd_splat(1.0f64), a)
130}
131
132#[inline(always)]
133pub(super) unsafe fn simd_ext_frsqrt_s<T: Copy>(a: T) -> T {
134 simd_ext_frecip_s(simd_fsqrt(a))
135}
136
137#[inline(always)]
138pub(super) unsafe fn simd_ext_frsqrt_d<T: Copy>(a: T) -> T {
139 simd_ext_frecip_d(simd_fsqrt(a))
140}
141
142#[inline(always)]
143#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
144pub(super) const unsafe fn simd_ext_ld<const I: i32, T: Copy>(a: *const i8) -> T {
145 let a = a.offset(I as isize) as *const T;
146 core::ptr::read_unaligned(a)
147}
148
149#[inline(always)]
150#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
151pub(super) const unsafe fn simd_ext_ldi<const I: i32, T: Copy + const SimdExt>() -> T {
152 use crate::core_arch::simd::{i8x8, i16x4, i32x2};
153 use crate::mem::transmute;
154
155 #[inline(always)]
156 const fn sext(v: i32, bits: u32) -> i64 {
157 ((v as i64) << (64 - bits)) >> (64 - bits)
158 }
159
160 #[inline(always)]
161 const fn expand_u8(imm: i32) -> u64 {
162 let mut v = imm as u64;
163 v = (v | (v << 28)) & 0x0000000f0000000f;
164 v = (v | (v << 14)) & 0x0003000300030003;
165 v = (v | (v << 7)) & 0x0101010101010101;
166 v.wrapping_mul(0xff)
167 }
168
169 #[inline(always)]
170 const fn fp32_imm(imm: i32) -> i32 {
171 ((imm & 0x80) << 24)
172 | ((!imm & 0x40) << 24)
173 | (((imm & 0x40) >> 6).wrapping_mul(0x1f) << 25)
174 | ((imm & 0x3f) << 19)
175 }
176
177 #[inline(always)]
178 const fn fp64_imm(imm: i32) -> i64 {
179 ((((imm & 0x80) << 24)
180 | ((!imm & 0x40) << 24)
181 | (((imm & 0x40) >> 6).wrapping_mul(0xff) << 22)
182 | ((imm & 0x3f) << 16)) as i64)
183 << 32
184 }
185
186 let imm8 = I & 0xff;
187 let imm10 = I & 0x3ff;
188
189 let r = if (I & 0x1000) == 0 {
190 match (I >> 10) & 3 {
191 0 => transmute(i8x8::splat(imm8 as i8)),
192 1 => transmute(i16x4::splat(sext(imm10, 10) as i16)),
193 2 => transmute(i32x2::splat(sext(imm10, 10) as i32)),
194 3 => sext(imm10, 10),
195 _ => unreachable!(),
196 }
197 } else {
198 match (I >> 8) & 0xf {
199 0..=3 => transmute(i32x2::splat(imm8 << (8 * ((I >> 8) & 3)))),
200 4..=5 => transmute(i16x4::splat((imm8 as i16) << (8 * ((I >> 8) & 1)))),
201 6 => transmute(i32x2::splat((imm8 << 8) | 0xff)),
202 7 => transmute(i32x2::splat((imm8 << 16) | 0xffff)),
203 8 => transmute(i8x8::splat(imm8 as i8)),
204 9 => expand_u8(imm8) as i64,
205 10 => transmute(i32x2::splat(fp32_imm(I))),
206 11 => transmute(i32x2::from_array([fp32_imm(I), 0])),
207 12 => fp64_imm(I),
208 _ => unreachable!(),
209 }
210 };
211
212 simd_ext_splat(r)
213}
214
215#[inline(always)]
216#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
217pub(super) const unsafe fn simd_ext_ldx<T: Copy>(a: *const i8, b: i64) -> T {
218 let a = a.offset(b as isize) as *const T;
219 core::ptr::read_unaligned(a)
220}
221
222#[inline(always)]
223#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
224pub(super) const unsafe fn simd_ext_madd<T: Copy>(a: T, b: T, c: T) -> T {
225 simd_add(a, simd_mul(b, c))
226}
227
228#[inline(always)]
229#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
230pub(super) const unsafe fn simd_ext_msub<T: Copy>(a: T, b: T, c: T) -> T {
231 simd_sub(a, simd_mul(b, c))
232}
233
234#[inline(always)]
235#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
236pub(super) const unsafe fn simd_ext_muh<T: Copy, W: Copy + const SimdExt>(a: T, b: T) -> T {
237 let a: W = simd_cast(a);
238 let b: W = simd_cast(b);
239 let p = simd_mul(a, b);
240 simd_cast(simd_shr(
241 p,
242 simd_ext_splat((size_of::<W::Elem>() * 8 / 2) as i64),
243 ))
244}
245
246#[inline(always)]
247#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
248pub(super) const unsafe fn simd_ext_nor<T: Copy + const SimdExt>(a: T, b: T) -> T {
249 simd_ext_not(simd_or(a, b))
250}
251
252#[inline(always)]
253#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
254pub(super) const unsafe fn simd_ext_not<T: Copy + const SimdExt>(a: T) -> T {
255 simd_xor(a, simd_ext_splat(!0))
256}
257
258#[inline(always)]
259#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
260pub(super) const unsafe fn simd_ext_orn<T: Copy + const SimdExt>(a: T, b: T) -> T {
261 simd_or(a, simd_ext_not(b))
262}
263
264#[inline(always)]
265#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
266pub(super) const unsafe fn simd_ext_rotr<T: Copy + const SimdExt>(a: T, b: T) -> T {
267 let m = (size_of::<T::Elem>() * 8 - 1) as i64;
268 let r = simd_and(b, simd_ext_splat(m));
269 let l = simd_and(simd_sub(simd_ext_splat(m + 1), r), simd_ext_splat(m));
270 simd_or(simd_shr(a, r), simd_shl(a, l))
271}
272
273#[inline(always)]
274#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
275pub(super) const unsafe fn simd_ext_shl<T: Copy + const SimdExt>(a: T, b: T) -> T {
276 let m = (size_of::<T::Elem>() * 8 - 1) as i64;
277 simd_shl(a, simd_and(b, simd_ext_splat(m)))
278}
279
280#[inline(always)]
281#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
282pub(super) const unsafe fn simd_ext_shr<T: Copy + const SimdExt>(a: T, b: T) -> T {
283 let m = (size_of::<T::Elem>() * 8 - 1) as i64;
284 simd_shr(a, simd_and(b, simd_ext_splat(m)))
285}
286
287#[inline(always)]
288#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
289pub(super) const unsafe fn simd_ext_splat<T: Copy + const SimdExt>(a: i64) -> T {
290 T::splat(a)
291}
292
293#[inline(always)]
294#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
295pub(super) const unsafe fn simd_ext_st<const I: i32, T: Copy>(a: T, b: *mut i8) {
296 let b = b.offset(I as isize) as *mut T;
297 core::ptr::write_unaligned(b, a);
298}
299
300#[inline(always)]
301#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
302pub(super) const unsafe fn simd_ext_stx<T: Copy>(a: T, b: *mut i8, c: i64) {
303 let b = b.offset(c as isize) as *mut T;
304 core::ptr::write_unaligned(b, a);
305}
306
307macro_rules! impl_vavg {
308 ($ft:literal, $name:ident, $oty:ty, $ity:ty, $wty:ty) => {
309 #[inline]
310 #[target_feature(enable = $ft)]
311 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
312 pub fn $name(a: $oty, b: $oty) -> $oty {
313 unsafe {
314 let a: $wty = simd_cast(transmute::<_, $ity>(a));
315 let b: $wty = simd_cast(transmute::<_, $ity>(b));
316 let r: $ity = simd_cast(simd_shr(simd_add(a, b), <$wty>::splat(1)));
317 transmute(r)
318 }
319 }
320 };
321}
322
323macro_rules! impl_vavgr {
324 ($ft:literal, $name:ident, $oty:ty, $ity:ty, $wty:ty) => {
325 #[inline]
326 #[target_feature(enable = $ft)]
327 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
328 pub fn $name(a: $oty, b: $oty) -> $oty {
329 unsafe {
330 let a: $wty = simd_cast(transmute::<_, $ity>(a));
331 let b: $wty = simd_cast(transmute::<_, $ity>(b));
332 let r: $ity = simd_cast(simd_shr(
333 simd_add(simd_add(a, b), <$wty>::splat(1)),
334 <$wty>::splat(1),
335 ));
336 transmute(r)
337 }
338 }
339 };
340}
341
342pub(super) use impl_vavg;
343pub(super) use impl_vavgr;
344
345macro_rules! impl_vv {
346 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ty) => {
347 #[inline]
348 #[target_feature(enable = $ft)]
349 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
350 pub fn $name(a: $oty) -> $oty {
351 unsafe {
352 let a: $ity = transmute(a);
353 let r: $ity = $op(a);
354 transmute(r)
355 }
356 }
357 };
358}
359
360pub(super) use impl_vv;
361
362macro_rules! impl_gv {
363 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty) => {
364 #[inline]
365 #[target_feature(enable = $ft)]
366 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
367 pub fn $name(a: $gty) -> $oty {
368 unsafe {
369 let r: $ity = $op(a.into());
370 transmute(r)
371 }
372 }
373 };
374}
375
376pub(super) use impl_gv;
377
378macro_rules! impl_ggv {
379 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty, $xty:ty, unsafe) => {
380 #[inline]
381 #[target_feature(enable = $ft)]
382 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
383 pub unsafe fn $name(a: $gty, b: $xty) -> $oty {
384 let r: $ity = $op(a, b);
385 transmute(r)
386 }
387 };
388}
389
390pub(super) use impl_ggv;
391
392macro_rules! impl_gsv {
393 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty, $ibs:expr, const, unsafe) => {
394 #[inline]
395 #[target_feature(enable = $ft)]
396 #[rustc_legacy_const_generics(1)]
397 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
398 pub unsafe fn $name<const IMM: i32>(a: $gty) -> $oty {
399 static_assert_simm_bits!(IMM, $ibs);
400 let r: $ity = $op::<IMM, _>(a);
401 transmute(r)
402 }
403 };
404}
405
406pub(super) use impl_gsv;
407
408macro_rules! impl_sv {
409 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $ibs:expr) => {
410 #[inline]
411 #[target_feature(enable = $ft)]
412 #[rustc_legacy_const_generics(0)]
413 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
414 pub fn $name<const IMM: i32>() -> $oty {
415 static_assert_simm_bits!(IMM, $ibs);
416 unsafe {
417 let r: $ity = $op(IMM.into());
418 transmute(r)
419 }
420 }
421 };
422 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $ibs:expr, const) => {
423 #[inline]
424 #[target_feature(enable = $ft)]
425 #[rustc_legacy_const_generics(0)]
426 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
427 pub fn $name<const IMM: i32>() -> $oty {
428 static_assert_simm_bits!(IMM, $ibs);
429 unsafe {
430 let r: $ity = $op::<IMM, _>();
431 transmute(r)
432 }
433 }
434 };
435}
436
437pub(super) use impl_sv;
438
439macro_rules! impl_vvv {
440 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ty) => {
441 #[inline]
442 #[target_feature(enable = $ft)]
443 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
444 pub fn $name(a: $oty, b: $oty) -> $oty {
445 unsafe {
446 let a: $ity = transmute(a);
447 let b: $ity = transmute(b);
448 let r: $ity = $op(a, b);
449 transmute(r)
450 }
451 }
452 };
453 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ty, $wty:ty) => {
454 #[inline]
455 #[target_feature(enable = $ft)]
456 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
457 pub fn $name(a: $oty, b: $oty) -> $oty {
458 unsafe {
459 let a: $ity = transmute(a);
460 let b: $ity = transmute(b);
461 let r: $ity = $op::<$ity, $wty>(a, b);
462 transmute(r)
463 }
464 }
465 };
466}
467
468pub(super) use impl_vvv;
469
470macro_rules! impl_vgg {
471 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty, $xty:ty, unsafe) => {
472 #[inline]
473 #[target_feature(enable = $ft)]
474 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
475 pub unsafe fn $name(a: $oty, b: $gty, c: $xty) {
476 $op(a, b, c);
477 }
478 };
479}
480
481pub(super) use impl_vgg;
482
483macro_rules! impl_vgs {
484 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty, $ibs:expr, const, unsafe) => {
485 #[inline]
486 #[target_feature(enable = $ft)]
487 #[rustc_legacy_const_generics(2)]
488 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
489 pub unsafe fn $name<const IMM: i32>(a: $oty, b: $gty) {
490 static_assert_simm_bits!(IMM, $ibs);
491 $op::<IMM, _>(a, b);
492 }
493 };
494}
495
496pub(super) use impl_vgs;
497
498macro_rules! impl_vuv {
499 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident) => {
500 #[inline]
501 #[target_feature(enable = $ft)]
502 #[rustc_legacy_const_generics(1)]
503 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
504 pub fn $name<const IMM: u32>(a: $oty) -> $oty {
505 static_assert_uimm_bits!(IMM, (size_of::<<$ity as SimdExt>::Elem>() * 8).ilog2());
506 unsafe {
507 let a: $ity = transmute(a);
508 let b: $ity = simd_ext_splat(IMM.into());
509 let r: $ity = $op(a, b);
510 transmute(r)
511 }
512 }
513 };
514 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $ibs:expr) => {
515 #[inline]
516 #[target_feature(enable = $ft)]
517 #[rustc_legacy_const_generics(1)]
518 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
519 pub fn $name<const IMM: u32>(a: $oty) -> $oty {
520 static_assert_uimm_bits!(IMM, $ibs);
521 unsafe {
522 let a: $ity = transmute(a);
523 let b: $ity = simd_ext_splat(IMM.into());
524 let r: $ity = $op(a, b);
525 transmute(r)
526 }
527 }
528 };
529 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $ibs:expr, const) => {
530 #[inline]
531 #[target_feature(enable = $ft)]
532 #[rustc_legacy_const_generics(1)]
533 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
534 pub fn $name<const IMM: u32>(a: $oty) -> $oty {
535 static_assert_uimm_bits!(IMM, $ibs);
536 unsafe {
537 let a: $ity = transmute(a);
538 let r: $ity = $op::<IMM, _>(a);
539 transmute(r)
540 }
541 }
542 };
543}
544
545pub(super) use impl_vuv;
546
547macro_rules! impl_vug {
548 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty, $ibs:expr) => {
549 #[inline]
550 #[target_feature(enable = $ft)]
551 #[rustc_legacy_const_generics(1)]
552 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
553 pub fn $name<const IMM: u32>(a: $oty) -> $gty {
554 static_assert_uimm_bits!(IMM, $ibs);
555 unsafe {
556 let a: $ity = transmute(a);
557 let r: <$ity as SimdExt>::Elem = $op(a, IMM);
558 r as $gty
559 }
560 }
561 };
562}
563
564pub(super) use impl_vug;
565
566macro_rules! impl_vsv {
567 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $ibs:expr) => {
568 #[inline]
569 #[target_feature(enable = $ft)]
570 #[rustc_legacy_const_generics(1)]
571 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
572 pub fn $name<const IMM: i32>(a: $oty) -> $oty {
573 static_assert_simm_bits!(IMM, $ibs);
574 unsafe {
575 let a: $ity = transmute(a);
576 let b: $ity = simd_ext_splat(IMM.into());
577 let r: $ity = $op(a, b);
578 transmute(r)
579 }
580 }
581 };
582}
583
584pub(super) use impl_vsv;
585
586macro_rules! impl_vvvv {
587 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ty) => {
588 #[inline]
589 #[target_feature(enable = $ft)]
590 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
591 pub fn $name(a: $oty, b: $oty, c: $oty) -> $oty {
592 unsafe {
593 let a: $ity = transmute(a);
594 let b: $ity = transmute(b);
595 let c: $ity = transmute(c);
596 let r: $ity = $op(a, b, c);
597 transmute(r)
598 }
599 }
600 };
601}
602
603pub(super) use impl_vvvv;
604
605macro_rules! impl_vvuv {
606 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $ibs:expr, const) => {
607 #[inline]
608 #[target_feature(enable = $ft)]
609 #[rustc_legacy_const_generics(2)]
610 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
611 pub fn $name<const IMM: u32>(a: $oty, b: $oty) -> $oty {
612 static_assert_uimm_bits!(IMM, $ibs);
613 unsafe {
614 let a: $ity = transmute(a);
615 let b: $ity = transmute(b);
616 let r: $ity = $op::<IMM, _>(a, b);
617 transmute(r)
618 }
619 }
620 };
621}
622
623pub(super) use impl_vvuv;
624
625macro_rules! impl_vugv {
626 ($ft:literal, $name:ident, $op:ident, $oty:ty, $ity:ident, $gty:ty, $ibs:expr) => {
627 #[inline]
628 #[target_feature(enable = $ft)]
629 #[rustc_legacy_const_generics(2)]
630 #[unstable(feature = "stdarch_loongarch", issue = "117427")]
631 pub fn $name<const IMM: u32>(a: $oty, b: $gty) -> $oty {
632 static_assert_uimm_bits!(IMM, $ibs);
633 unsafe {
634 let a: $ity = transmute(a);
635 let r: $ity = $op(a, IMM, b as <$ity as SimdExt>::Elem);
636 transmute(r)
637 }
638 }
639 };
640}
641
642pub(super) use impl_vugv;