5 #if V8_TARGET_ARCH_ARM64 8 #include "src/arm64/simulator-arm64.h" 13 #if defined(USE_SIMULATOR) 18 inline double FPRoundToDouble(
int64_t sign,
int64_t exponent, uint64_t mantissa,
19 FPRounding round_mode) {
20 uint64_t bits = FPRound<uint64_t, kDoubleExponentBits, kDoubleMantissaBits>(
21 sign, exponent, mantissa, round_mode);
22 return bit_cast<
double>(bits);
26 inline float FPRoundToFloat(
int64_t sign,
int64_t exponent, uint64_t mantissa,
27 FPRounding round_mode) {
28 uint32_t bits = FPRound<uint32_t, kFloatExponentBits, kFloatMantissaBits>(
29 sign, exponent, mantissa, round_mode);
30 return bit_cast<
float>(bits);
35 uint64_t mantissa, FPRounding round_mode) {
36 return FPRound<float16, kFloat16ExponentBits, kFloat16MantissaBits>(
37 sign, exponent, mantissa, round_mode);
42 double Simulator::FixedToDouble(
int64_t src,
int fbits, FPRounding round) {
44 return UFixedToDouble(src, fbits, round);
45 }
else if (src == INT64_MIN) {
46 return -UFixedToDouble(src, fbits, round);
48 return -UFixedToDouble(-src, fbits, round);
52 double Simulator::UFixedToDouble(uint64_t src,
int fbits, FPRounding round) {
61 const int highest_significant_bit = 63 - CountLeadingZeros(src, 64);
62 const int64_t exponent = highest_significant_bit - fbits;
64 return FPRoundToDouble(0, exponent, src, round);
67 float Simulator::FixedToFloat(
int64_t src,
int fbits, FPRounding round) {
69 return UFixedToFloat(src, fbits, round);
70 }
else if (src == INT64_MIN) {
71 return -UFixedToFloat(src, fbits, round);
73 return -UFixedToFloat(-src, fbits, round);
77 float Simulator::UFixedToFloat(uint64_t src,
int fbits, FPRounding round) {
86 const int highest_significant_bit = 63 - CountLeadingZeros(src, 64);
87 const int32_t exponent = highest_significant_bit - fbits;
89 return FPRoundToFloat(0, exponent, src, round);
92 double Simulator::FPToDouble(
float value) {
93 switch (std::fpclassify(value)) {
95 if (IsSignallingNaN(value)) {
98 if (DN())
return kFP64DefaultNaN;
107 uint64_t sign = raw >> 31;
108 uint64_t exponent = (1 << kDoubleExponentBits) - 1;
109 uint64_t mantissa = unsigned_bitextract_64(21, 0, raw);
112 mantissa <<= (kDoubleMantissaBits - kFloatMantissaBits);
115 mantissa |= (UINT64_C(1) << (kDoubleMantissaBits - 1));
117 return double_pack(sign, exponent, mantissa);
127 return static_cast<double>(value);
134 float Simulator::FPToFloat(float16 value) {
137 unsigned_bitextract_32(kFloat16MantissaBits + kFloat16ExponentBits - 1,
138 kFloat16MantissaBits, value);
140 unsigned_bitextract_32(kFloat16MantissaBits - 1, 0, value);
142 switch (float16classify(value)) {
144 return (sign == 0) ? 0.0f : -0.0f;
147 return (sign == 0) ? kFP32PositiveInfinity : kFP32NegativeInfinity;
152 int shift = CountLeadingZeros(mantissa << (32 - 10), 32);
155 mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits) + shift + 1;
156 mantissa &= (1 << kFloatMantissaBits) - 1;
159 exponent = exponent - shift + (kFloatExponentBias - kFloat16ExponentBias);
164 if (IsSignallingNaN(value)) {
165 FPProcessException();
167 if (DN())
return kFP32DefaultNaN;
174 exponent = (1 << kFloatExponentBits) - 1;
177 mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
178 mantissa |= 1 << (kFloatMantissaBits - 1);
184 mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
187 exponent += (kFloatExponentBias - kFloat16ExponentBias);
194 return float_pack(sign, exponent, mantissa);
197 float16 Simulator::FPToFloat16(
float value, FPRounding round_mode) {
199 DCHECK_EQ(round_mode, FPTieEven);
202 int64_t sign = float_sign(value);
204 static_cast<int64_t>(float_exp(value)) - kFloatExponentBias;
205 uint32_t mantissa = float_mantissa(value);
207 switch (std::fpclassify(value)) {
209 if (IsSignallingNaN(value)) {
210 FPProcessException();
212 if (DN())
return kFP16DefaultNaN;
219 (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
220 result |= mantissa >> (kFloatMantissaBits - kFloat16MantissaBits);
221 result |= (1 << (kFloat16MantissaBits - 1));
226 return (sign == 0) ? 0 : 0x8000;
229 return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
237 mantissa += (1 << kFloatMantissaBits);
238 return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
245 float16 Simulator::FPToFloat16(
double value, FPRounding round_mode) {
247 DCHECK_EQ(round_mode, FPTieEven);
250 int64_t sign = double_sign(value);
252 static_cast<int64_t>(double_exp(value)) - kDoubleExponentBias;
253 uint64_t mantissa = double_mantissa(value);
255 switch (std::fpclassify(value)) {
257 if (IsSignallingNaN(value)) {
258 FPProcessException();
260 if (DN())
return kFP16DefaultNaN;
267 (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
268 result |= mantissa >> (kDoubleMantissaBits - kFloat16MantissaBits);
269 result |= (1 << (kFloat16MantissaBits - 1));
274 return (sign == 0) ? 0 : 0x8000;
277 return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
285 mantissa += (UINT64_C(1) << kDoubleMantissaBits);
286 return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
293 float Simulator::FPToFloat(
double value, FPRounding round_mode) {
295 DCHECK((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
298 switch (std::fpclassify(value)) {
300 if (IsSignallingNaN(value)) {
301 FPProcessException();
303 if (DN())
return kFP32DefaultNaN;
310 uint64_t raw = bit_cast<uint64_t>(value);
315 50, kDoubleMantissaBits - kFloatMantissaBits, raw));
316 mantissa |= (1 << (kFloatMantissaBits - 1));
318 return float_pack(sign, exponent, mantissa);
325 return static_cast<float>(value);
334 static_cast<int64_t>(double_exp(value)) - kDoubleExponentBias;
335 uint64_t mantissa = double_mantissa(value);
336 if (std::fpclassify(value) == FP_NORMAL) {
338 mantissa |= (UINT64_C(1) << kDoubleMantissaBits);
340 return FPRoundToFloat(sign, exponent, mantissa, round_mode);
347 void Simulator::ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr) {
348 dst.ClearForWrite(vform);
349 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
350 dst.ReadUintFromMem(vform,
i, addr);
351 addr += LaneSizeInBytesFromFormat(vform);
355 void Simulator::ld1(VectorFormat vform, LogicVRegister dst,
int index,
357 dst.ReadUintFromMem(vform, index, addr);
360 void Simulator::ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr) {
361 dst.ClearForWrite(vform);
362 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
363 dst.ReadUintFromMem(vform,
i, addr);
367 void Simulator::ld2(VectorFormat vform, LogicVRegister dst1,
368 LogicVRegister dst2, uint64_t addr1) {
369 dst1.ClearForWrite(vform);
370 dst2.ClearForWrite(vform);
371 int esize = LaneSizeInBytesFromFormat(vform);
372 uint64_t addr2 = addr1 + esize;
373 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
374 dst1.ReadUintFromMem(vform,
i, addr1);
375 dst2.ReadUintFromMem(vform,
i, addr2);
381 void Simulator::ld2(VectorFormat vform, LogicVRegister dst1,
382 LogicVRegister dst2,
int index, uint64_t addr1) {
383 dst1.ClearForWrite(vform);
384 dst2.ClearForWrite(vform);
385 uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
386 dst1.ReadUintFromMem(vform, index, addr1);
387 dst2.ReadUintFromMem(vform, index, addr2);
390 void Simulator::ld2r(VectorFormat vform, LogicVRegister dst1,
391 LogicVRegister dst2, uint64_t addr) {
392 dst1.ClearForWrite(vform);
393 dst2.ClearForWrite(vform);
394 uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
395 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
396 dst1.ReadUintFromMem(vform,
i, addr);
397 dst2.ReadUintFromMem(vform,
i, addr2);
401 void Simulator::ld3(VectorFormat vform, LogicVRegister dst1,
402 LogicVRegister dst2, LogicVRegister dst3, uint64_t addr1) {
403 dst1.ClearForWrite(vform);
404 dst2.ClearForWrite(vform);
405 dst3.ClearForWrite(vform);
406 int esize = LaneSizeInBytesFromFormat(vform);
407 uint64_t addr2 = addr1 + esize;
408 uint64_t addr3 = addr2 + esize;
409 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
410 dst1.ReadUintFromMem(vform,
i, addr1);
411 dst2.ReadUintFromMem(vform,
i, addr2);
412 dst3.ReadUintFromMem(vform,
i, addr3);
419 void Simulator::ld3(VectorFormat vform, LogicVRegister dst1,
420 LogicVRegister dst2, LogicVRegister dst3,
int index,
422 dst1.ClearForWrite(vform);
423 dst2.ClearForWrite(vform);
424 dst3.ClearForWrite(vform);
425 uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
426 uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
427 dst1.ReadUintFromMem(vform, index, addr1);
428 dst2.ReadUintFromMem(vform, index, addr2);
429 dst3.ReadUintFromMem(vform, index, addr3);
432 void Simulator::ld3r(VectorFormat vform, LogicVRegister dst1,
433 LogicVRegister dst2, LogicVRegister dst3, uint64_t addr) {
434 dst1.ClearForWrite(vform);
435 dst2.ClearForWrite(vform);
436 dst3.ClearForWrite(vform);
437 uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
438 uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
439 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
440 dst1.ReadUintFromMem(vform,
i, addr);
441 dst2.ReadUintFromMem(vform,
i, addr2);
442 dst3.ReadUintFromMem(vform,
i, addr3);
446 void Simulator::ld4(VectorFormat vform, LogicVRegister dst1,
447 LogicVRegister dst2, LogicVRegister dst3,
448 LogicVRegister dst4, uint64_t addr1) {
449 dst1.ClearForWrite(vform);
450 dst2.ClearForWrite(vform);
451 dst3.ClearForWrite(vform);
452 dst4.ClearForWrite(vform);
453 int esize = LaneSizeInBytesFromFormat(vform);
454 uint64_t addr2 = addr1 + esize;
455 uint64_t addr3 = addr2 + esize;
456 uint64_t addr4 = addr3 + esize;
457 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
458 dst1.ReadUintFromMem(vform,
i, addr1);
459 dst2.ReadUintFromMem(vform,
i, addr2);
460 dst3.ReadUintFromMem(vform,
i, addr3);
461 dst4.ReadUintFromMem(vform,
i, addr4);
469 void Simulator::ld4(VectorFormat vform, LogicVRegister dst1,
470 LogicVRegister dst2, LogicVRegister dst3,
471 LogicVRegister dst4,
int index, uint64_t addr1) {
472 dst1.ClearForWrite(vform);
473 dst2.ClearForWrite(vform);
474 dst3.ClearForWrite(vform);
475 dst4.ClearForWrite(vform);
476 uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
477 uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
478 uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
479 dst1.ReadUintFromMem(vform, index, addr1);
480 dst2.ReadUintFromMem(vform, index, addr2);
481 dst3.ReadUintFromMem(vform, index, addr3);
482 dst4.ReadUintFromMem(vform, index, addr4);
485 void Simulator::ld4r(VectorFormat vform, LogicVRegister dst1,
486 LogicVRegister dst2, LogicVRegister dst3,
487 LogicVRegister dst4, uint64_t addr) {
488 dst1.ClearForWrite(vform);
489 dst2.ClearForWrite(vform);
490 dst3.ClearForWrite(vform);
491 dst4.ClearForWrite(vform);
492 uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
493 uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
494 uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
495 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
496 dst1.ReadUintFromMem(vform,
i, addr);
497 dst2.ReadUintFromMem(vform,
i, addr2);
498 dst3.ReadUintFromMem(vform,
i, addr3);
499 dst4.ReadUintFromMem(vform,
i, addr4);
503 void Simulator::st1(VectorFormat vform, LogicVRegister src, uint64_t addr) {
504 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
505 src.WriteUintToMem(vform,
i, addr);
506 addr += LaneSizeInBytesFromFormat(vform);
510 void Simulator::st1(VectorFormat vform, LogicVRegister src,
int index,
512 src.WriteUintToMem(vform, index, addr);
515 void Simulator::st2(VectorFormat vform, LogicVRegister dst, LogicVRegister dst2,
517 int esize = LaneSizeInBytesFromFormat(vform);
518 uint64_t addr2 = addr + esize;
519 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
520 dst.WriteUintToMem(vform,
i, addr);
521 dst2.WriteUintToMem(vform,
i, addr2);
527 void Simulator::st2(VectorFormat vform, LogicVRegister dst, LogicVRegister dst2,
528 int index, uint64_t addr) {
529 int esize = LaneSizeInBytesFromFormat(vform);
530 dst.WriteUintToMem(vform, index, addr);
531 dst2.WriteUintToMem(vform, index, addr + 1 * esize);
534 void Simulator::st3(VectorFormat vform, LogicVRegister dst, LogicVRegister dst2,
535 LogicVRegister dst3, uint64_t addr) {
536 int esize = LaneSizeInBytesFromFormat(vform);
537 uint64_t addr2 = addr + esize;
538 uint64_t addr3 = addr2 + esize;
539 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
540 dst.WriteUintToMem(vform,
i, addr);
541 dst2.WriteUintToMem(vform,
i, addr2);
542 dst3.WriteUintToMem(vform,
i, addr3);
549 void Simulator::st3(VectorFormat vform, LogicVRegister dst, LogicVRegister dst2,
550 LogicVRegister dst3,
int index, uint64_t addr) {
551 int esize = LaneSizeInBytesFromFormat(vform);
552 dst.WriteUintToMem(vform, index, addr);
553 dst2.WriteUintToMem(vform, index, addr + 1 * esize);
554 dst3.WriteUintToMem(vform, index, addr + 2 * esize);
557 void Simulator::st4(VectorFormat vform, LogicVRegister dst, LogicVRegister dst2,
558 LogicVRegister dst3, LogicVRegister dst4, uint64_t addr) {
559 int esize = LaneSizeInBytesFromFormat(vform);
560 uint64_t addr2 = addr + esize;
561 uint64_t addr3 = addr2 + esize;
562 uint64_t addr4 = addr3 + esize;
563 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
564 dst.WriteUintToMem(vform,
i, addr);
565 dst2.WriteUintToMem(vform,
i, addr2);
566 dst3.WriteUintToMem(vform,
i, addr3);
567 dst4.WriteUintToMem(vform,
i, addr4);
575 void Simulator::st4(VectorFormat vform, LogicVRegister dst, LogicVRegister dst2,
576 LogicVRegister dst3, LogicVRegister dst4,
int index,
578 int esize = LaneSizeInBytesFromFormat(vform);
579 dst.WriteUintToMem(vform, index, addr);
580 dst2.WriteUintToMem(vform, index, addr + 1 * esize);
581 dst3.WriteUintToMem(vform, index, addr + 2 * esize);
582 dst4.WriteUintToMem(vform, index, addr + 3 * esize);
585 LogicVRegister Simulator::cmp(VectorFormat vform, LogicVRegister dst,
586 const LogicVRegister& src1,
587 const LogicVRegister& src2, Condition cond) {
588 dst.ClearForWrite(vform);
589 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
592 uint64_t ua = src1.Uint(vform,
i);
593 uint64_t ub = src2.Uint(vform,
i);
620 dst.SetUint(vform,
i, result ? MaxUintFromFormat(vform) : 0);
625 LogicVRegister Simulator::cmp(VectorFormat vform, LogicVRegister dst,
626 const LogicVRegister& src1,
int imm,
629 LogicVRegister imm_reg = dup_immediate(vform, temp, imm);
630 return cmp(vform, dst, src1, imm_reg, cond);
633 LogicVRegister Simulator::cmptst(VectorFormat vform, LogicVRegister dst,
634 const LogicVRegister& src1,
635 const LogicVRegister& src2) {
636 dst.ClearForWrite(vform);
637 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
638 uint64_t ua = src1.Uint(vform,
i);
639 uint64_t ub = src2.Uint(vform,
i);
640 dst.SetUint(vform,
i, ((ua & ub) != 0) ? MaxUintFromFormat(vform) : 0);
645 LogicVRegister Simulator::add(VectorFormat vform, LogicVRegister dst,
646 const LogicVRegister& src1,
647 const LogicVRegister& src2) {
648 int lane_size = LaneSizeInBitsFromFormat(vform);
649 dst.ClearForWrite(vform);
650 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
652 uint64_t ua = src1.UintLeftJustified(vform,
i);
653 uint64_t ub = src2.UintLeftJustified(vform,
i);
654 uint64_t ur = ua + ub;
656 dst.SetUnsignedSat(
i,
true);
660 bool pos_a = (ua >> 63) == 0;
661 bool pos_b = (ub >> 63) == 0;
662 bool pos_r = (ur >> 63) == 0;
665 if ((pos_a == pos_b) && (pos_a != pos_r)) {
666 dst.SetSignedSat(
i, pos_a);
669 dst.SetInt(vform,
i, ur >> (64 - lane_size));
674 LogicVRegister Simulator::addp(VectorFormat vform, LogicVRegister dst,
675 const LogicVRegister& src1,
676 const LogicVRegister& src2) {
677 SimVRegister temp1, temp2;
678 uzp1(vform, temp1, src1, src2);
679 uzp2(vform, temp2, src1, src2);
680 add(vform, dst, temp1, temp2);
684 LogicVRegister Simulator::mla(VectorFormat vform, LogicVRegister dst,
685 const LogicVRegister& src1,
686 const LogicVRegister& src2) {
688 mul(vform, temp, src1, src2);
689 add(vform, dst, dst, temp);
693 LogicVRegister Simulator::mls(VectorFormat vform, LogicVRegister dst,
694 const LogicVRegister& src1,
695 const LogicVRegister& src2) {
697 mul(vform, temp, src1, src2);
698 sub(vform, dst, dst, temp);
702 LogicVRegister Simulator::mul(VectorFormat vform, LogicVRegister dst,
703 const LogicVRegister& src1,
704 const LogicVRegister& src2) {
705 dst.ClearForWrite(vform);
706 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
707 dst.SetUint(vform,
i, src1.Uint(vform,
i) * src2.Uint(vform,
i));
712 LogicVRegister Simulator::mul(VectorFormat vform, LogicVRegister dst,
713 const LogicVRegister& src1,
714 const LogicVRegister& src2,
int index) {
716 VectorFormat indexform = VectorFormatFillQ(vform);
717 return mul(vform, dst, src1, dup_element(indexform, temp, src2, index));
720 LogicVRegister Simulator::mla(VectorFormat vform, LogicVRegister dst,
721 const LogicVRegister& src1,
722 const LogicVRegister& src2,
int index) {
724 VectorFormat indexform = VectorFormatFillQ(vform);
725 return mla(vform, dst, src1, dup_element(indexform, temp, src2, index));
728 LogicVRegister Simulator::mls(VectorFormat vform, LogicVRegister dst,
729 const LogicVRegister& src1,
730 const LogicVRegister& src2,
int index) {
732 VectorFormat indexform = VectorFormatFillQ(vform);
733 return mls(vform, dst, src1, dup_element(indexform, temp, src2, index));
736 LogicVRegister Simulator::smull(VectorFormat vform, LogicVRegister dst,
737 const LogicVRegister& src1,
738 const LogicVRegister& src2,
int index) {
740 VectorFormat indexform =
741 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
742 return smull(vform, dst, src1, dup_element(indexform, temp, src2, index));
745 LogicVRegister Simulator::smull2(VectorFormat vform, LogicVRegister dst,
746 const LogicVRegister& src1,
747 const LogicVRegister& src2,
int index) {
749 VectorFormat indexform =
750 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
751 return smull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
754 LogicVRegister Simulator::umull(VectorFormat vform, LogicVRegister dst,
755 const LogicVRegister& src1,
756 const LogicVRegister& src2,
int index) {
758 VectorFormat indexform =
759 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
760 return umull(vform, dst, src1, dup_element(indexform, temp, src2, index));
763 LogicVRegister Simulator::umull2(VectorFormat vform, LogicVRegister dst,
764 const LogicVRegister& src1,
765 const LogicVRegister& src2,
int index) {
767 VectorFormat indexform =
768 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
769 return umull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
772 LogicVRegister Simulator::smlal(VectorFormat vform, LogicVRegister dst,
773 const LogicVRegister& src1,
774 const LogicVRegister& src2,
int index) {
776 VectorFormat indexform =
777 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
778 return smlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
781 LogicVRegister Simulator::smlal2(VectorFormat vform, LogicVRegister dst,
782 const LogicVRegister& src1,
783 const LogicVRegister& src2,
int index) {
785 VectorFormat indexform =
786 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
787 return smlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
790 LogicVRegister Simulator::umlal(VectorFormat vform, LogicVRegister dst,
791 const LogicVRegister& src1,
792 const LogicVRegister& src2,
int index) {
794 VectorFormat indexform =
795 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
796 return umlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
799 LogicVRegister Simulator::umlal2(VectorFormat vform, LogicVRegister dst,
800 const LogicVRegister& src1,
801 const LogicVRegister& src2,
int index) {
803 VectorFormat indexform =
804 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
805 return umlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
808 LogicVRegister Simulator::smlsl(VectorFormat vform, LogicVRegister dst,
809 const LogicVRegister& src1,
810 const LogicVRegister& src2,
int index) {
812 VectorFormat indexform =
813 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
814 return smlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
817 LogicVRegister Simulator::smlsl2(VectorFormat vform, LogicVRegister dst,
818 const LogicVRegister& src1,
819 const LogicVRegister& src2,
int index) {
821 VectorFormat indexform =
822 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
823 return smlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
826 LogicVRegister Simulator::umlsl(VectorFormat vform, LogicVRegister dst,
827 const LogicVRegister& src1,
828 const LogicVRegister& src2,
int index) {
830 VectorFormat indexform =
831 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
832 return umlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
835 LogicVRegister Simulator::umlsl2(VectorFormat vform, LogicVRegister dst,
836 const LogicVRegister& src1,
837 const LogicVRegister& src2,
int index) {
839 VectorFormat indexform =
840 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
841 return umlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
844 LogicVRegister Simulator::sqdmull(VectorFormat vform, LogicVRegister dst,
845 const LogicVRegister& src1,
846 const LogicVRegister& src2,
int index) {
848 VectorFormat indexform =
849 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
850 return sqdmull(vform, dst, src1, dup_element(indexform, temp, src2, index));
853 LogicVRegister Simulator::sqdmull2(VectorFormat vform, LogicVRegister dst,
854 const LogicVRegister& src1,
855 const LogicVRegister& src2,
int index) {
857 VectorFormat indexform =
858 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
859 return sqdmull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
862 LogicVRegister Simulator::sqdmlal(VectorFormat vform, LogicVRegister dst,
863 const LogicVRegister& src1,
864 const LogicVRegister& src2,
int index) {
866 VectorFormat indexform =
867 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
868 return sqdmlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
871 LogicVRegister Simulator::sqdmlal2(VectorFormat vform, LogicVRegister dst,
872 const LogicVRegister& src1,
873 const LogicVRegister& src2,
int index) {
875 VectorFormat indexform =
876 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
877 return sqdmlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
880 LogicVRegister Simulator::sqdmlsl(VectorFormat vform, LogicVRegister dst,
881 const LogicVRegister& src1,
882 const LogicVRegister& src2,
int index) {
884 VectorFormat indexform =
885 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
886 return sqdmlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
889 LogicVRegister Simulator::sqdmlsl2(VectorFormat vform, LogicVRegister dst,
890 const LogicVRegister& src1,
891 const LogicVRegister& src2,
int index) {
893 VectorFormat indexform =
894 VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
895 return sqdmlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
898 LogicVRegister Simulator::sqdmulh(VectorFormat vform, LogicVRegister dst,
899 const LogicVRegister& src1,
900 const LogicVRegister& src2,
int index) {
902 VectorFormat indexform = VectorFormatFillQ(vform);
903 return sqdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
906 LogicVRegister Simulator::sqrdmulh(VectorFormat vform, LogicVRegister dst,
907 const LogicVRegister& src1,
908 const LogicVRegister& src2,
int index) {
910 VectorFormat indexform = VectorFormatFillQ(vform);
911 return sqrdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
914 uint16_t Simulator::PolynomialMult(uint8_t op1, uint8_t op2) {
916 uint16_t extended_op2 = op2;
917 for (
int i = 0;
i < 8; ++
i) {
918 if ((op1 >>
i) & 1) {
919 result = result ^ (extended_op2 <<
i);
925 LogicVRegister Simulator::pmul(VectorFormat vform, LogicVRegister dst,
926 const LogicVRegister& src1,
927 const LogicVRegister& src2) {
928 dst.ClearForWrite(vform);
929 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
930 dst.SetUint(vform,
i,
931 PolynomialMult(src1.Uint(vform,
i), src2.Uint(vform,
i)));
936 LogicVRegister Simulator::pmull(VectorFormat vform, LogicVRegister dst,
937 const LogicVRegister& src1,
938 const LogicVRegister& src2) {
939 VectorFormat vform_src = VectorFormatHalfWidth(vform);
940 dst.ClearForWrite(vform);
941 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
944 PolynomialMult(src1.Uint(vform_src,
i), src2.Uint(vform_src,
i)));
949 LogicVRegister Simulator::pmull2(VectorFormat vform, LogicVRegister dst,
950 const LogicVRegister& src1,
951 const LogicVRegister& src2) {
952 VectorFormat vform_src = VectorFormatHalfWidthDoubleLanes(vform);
953 dst.ClearForWrite(vform);
954 int lane_count = LaneCountFromFormat(vform);
955 for (
int i = 0;
i < lane_count;
i++) {
956 dst.SetUint(vform,
i,
957 PolynomialMult(src1.Uint(vform_src, lane_count +
i),
958 src2.Uint(vform_src, lane_count +
i)));
963 LogicVRegister Simulator::sub(VectorFormat vform, LogicVRegister dst,
964 const LogicVRegister& src1,
965 const LogicVRegister& src2) {
966 int lane_size = LaneSizeInBitsFromFormat(vform);
967 dst.ClearForWrite(vform);
968 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
970 uint64_t ua = src1.UintLeftJustified(vform,
i);
971 uint64_t ub = src2.UintLeftJustified(vform,
i);
972 uint64_t ur = ua - ub;
974 dst.SetUnsignedSat(
i,
false);
978 bool pos_a = (ua >> 63) == 0;
979 bool pos_b = (ub >> 63) == 0;
980 bool pos_r = (ur >> 63) == 0;
983 if ((pos_a != pos_b) && (pos_a != pos_r)) {
984 dst.SetSignedSat(
i, pos_a);
987 dst.SetInt(vform,
i, ur >> (64 - lane_size));
992 LogicVRegister Simulator::and_(VectorFormat vform, LogicVRegister dst,
993 const LogicVRegister& src1,
994 const LogicVRegister& src2) {
995 dst.ClearForWrite(vform);
996 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
997 dst.SetUint(vform,
i, src1.Uint(vform,
i) & src2.Uint(vform,
i));
1002 LogicVRegister Simulator::orr(VectorFormat vform, LogicVRegister dst,
1003 const LogicVRegister& src1,
1004 const LogicVRegister& src2) {
1005 dst.ClearForWrite(vform);
1006 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1007 dst.SetUint(vform,
i, src1.Uint(vform,
i) | src2.Uint(vform,
i));
1012 LogicVRegister Simulator::orn(VectorFormat vform, LogicVRegister dst,
1013 const LogicVRegister& src1,
1014 const LogicVRegister& src2) {
1015 dst.ClearForWrite(vform);
1016 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1017 dst.SetUint(vform,
i, src1.Uint(vform,
i) | ~src2.Uint(vform,
i));
1022 LogicVRegister Simulator::eor(VectorFormat vform, LogicVRegister dst,
1023 const LogicVRegister& src1,
1024 const LogicVRegister& src2) {
1025 dst.ClearForWrite(vform);
1026 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1027 dst.SetUint(vform,
i, src1.Uint(vform,
i) ^ src2.Uint(vform,
i));
1032 LogicVRegister Simulator::bic(VectorFormat vform, LogicVRegister dst,
1033 const LogicVRegister& src1,
1034 const LogicVRegister& src2) {
1035 dst.ClearForWrite(vform);
1036 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1037 dst.SetUint(vform,
i, src1.Uint(vform,
i) & ~src2.Uint(vform,
i));
1042 LogicVRegister Simulator::bic(VectorFormat vform, LogicVRegister dst,
1043 const LogicVRegister& src, uint64_t imm) {
1044 uint64_t result[16];
1045 int laneCount = LaneCountFromFormat(vform);
1046 for (
int i = 0;
i < laneCount; ++
i) {
1047 result[
i] = src.Uint(vform,
i) & ~imm;
1049 dst.SetUintArray(vform, result);
1053 LogicVRegister Simulator::bif(VectorFormat vform, LogicVRegister dst,
1054 const LogicVRegister& src1,
1055 const LogicVRegister& src2) {
1056 dst.ClearForWrite(vform);
1057 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1058 uint64_t operand1 = dst.Uint(vform,
i);
1059 uint64_t operand2 = ~src2.Uint(vform,
i);
1060 uint64_t operand3 = src1.Uint(vform,
i);
1061 uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1062 dst.SetUint(vform,
i, result);
1067 LogicVRegister Simulator::bit(VectorFormat vform, LogicVRegister dst,
1068 const LogicVRegister& src1,
1069 const LogicVRegister& src2) {
1070 dst.ClearForWrite(vform);
1071 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1072 uint64_t operand1 = dst.Uint(vform,
i);
1073 uint64_t operand2 = src2.Uint(vform,
i);
1074 uint64_t operand3 = src1.Uint(vform,
i);
1075 uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1076 dst.SetUint(vform,
i, result);
1081 LogicVRegister Simulator::bsl(VectorFormat vform, LogicVRegister dst,
1082 const LogicVRegister& src1,
1083 const LogicVRegister& src2) {
1084 dst.ClearForWrite(vform);
1085 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1086 uint64_t operand1 = src2.Uint(vform,
i);
1087 uint64_t operand2 = dst.Uint(vform,
i);
1088 uint64_t operand3 = src1.Uint(vform,
i);
1089 uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1090 dst.SetUint(vform,
i, result);
1095 LogicVRegister Simulator::SMinMax(VectorFormat vform, LogicVRegister dst,
1096 const LogicVRegister& src1,
1097 const LogicVRegister& src2,
bool max) {
1098 dst.ClearForWrite(vform);
1099 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1100 int64_t src1_val = src1.Int(vform,
i);
1101 int64_t src2_val = src2.Int(vform,
i);
1104 dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1106 dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1108 dst.SetInt(vform,
i, dst_val);
1113 LogicVRegister Simulator::smax(VectorFormat vform, LogicVRegister dst,
1114 const LogicVRegister& src1,
1115 const LogicVRegister& src2) {
1116 return SMinMax(vform, dst, src1, src2,
true);
1119 LogicVRegister Simulator::smin(VectorFormat vform, LogicVRegister dst,
1120 const LogicVRegister& src1,
1121 const LogicVRegister& src2) {
1122 return SMinMax(vform, dst, src1, src2,
false);
1125 LogicVRegister Simulator::SMinMaxP(VectorFormat vform, LogicVRegister dst,
1126 const LogicVRegister& src1,
1127 const LogicVRegister& src2,
bool max) {
1128 int lanes = LaneCountFromFormat(vform);
1129 int64_t result[kMaxLanesPerVector];
1130 const LogicVRegister* src = &src1;
1131 for (
int j = 0; j < 2; j++) {
1132 for (
int i = 0;
i < lanes;
i += 2) {
1133 int64_t first_val = src->Int(vform,
i);
1134 int64_t second_val = src->Int(vform,
i + 1);
1137 dst_val = (first_val > second_val) ? first_val : second_val;
1139 dst_val = (first_val < second_val) ? first_val : second_val;
1141 DCHECK_LT((
i >> 1) + (j * lanes / 2), kMaxLanesPerVector);
1142 result[(
i >> 1) + (j * lanes / 2)] = dst_val;
1146 dst.SetIntArray(vform, result);
1150 LogicVRegister Simulator::smaxp(VectorFormat vform, LogicVRegister dst,
1151 const LogicVRegister& src1,
1152 const LogicVRegister& src2) {
1153 return SMinMaxP(vform, dst, src1, src2,
true);
1156 LogicVRegister Simulator::sminp(VectorFormat vform, LogicVRegister dst,
1157 const LogicVRegister& src1,
1158 const LogicVRegister& src2) {
1159 return SMinMaxP(vform, dst, src1, src2,
false);
1162 LogicVRegister Simulator::addp(VectorFormat vform, LogicVRegister dst,
1163 const LogicVRegister& src) {
1164 DCHECK_EQ(vform, kFormatD);
1166 uint64_t dst_val = src.Uint(kFormat2D, 0) + src.Uint(kFormat2D, 1);
1167 dst.ClearForWrite(vform);
1168 dst.SetUint(vform, 0, dst_val);
1172 LogicVRegister Simulator::addv(VectorFormat vform, LogicVRegister dst,
1173 const LogicVRegister& src) {
1174 VectorFormat vform_dst =
1175 ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
1178 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1179 dst_val += src.Int(vform,
i);
1182 dst.ClearForWrite(vform_dst);
1183 dst.SetInt(vform_dst, 0, dst_val);
1187 LogicVRegister Simulator::saddlv(VectorFormat vform, LogicVRegister dst,
1188 const LogicVRegister& src) {
1189 VectorFormat vform_dst =
1190 ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
1193 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1194 dst_val += src.Int(vform,
i);
1197 dst.ClearForWrite(vform_dst);
1198 dst.SetInt(vform_dst, 0, dst_val);
1202 LogicVRegister Simulator::uaddlv(VectorFormat vform, LogicVRegister dst,
1203 const LogicVRegister& src) {
1204 VectorFormat vform_dst =
1205 ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
1207 uint64_t dst_val = 0;
1208 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1209 dst_val += src.Uint(vform,
i);
1212 dst.ClearForWrite(vform_dst);
1213 dst.SetUint(vform_dst, 0, dst_val);
1217 LogicVRegister Simulator::SMinMaxV(VectorFormat vform, LogicVRegister dst,
1218 const LogicVRegister& src,
bool max) {
1219 int64_t dst_val = max ? INT64_MIN : INT64_MAX;
1220 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1221 int64_t src_val = src.Int(vform,
i);
1223 dst_val = (src_val > dst_val) ? src_val : dst_val;
1225 dst_val = (src_val < dst_val) ? src_val : dst_val;
1228 dst.ClearForWrite(ScalarFormatFromFormat(vform));
1229 dst.SetInt(vform, 0, dst_val);
1233 LogicVRegister Simulator::smaxv(VectorFormat vform, LogicVRegister dst,
1234 const LogicVRegister& src) {
1235 SMinMaxV(vform, dst, src,
true);
1239 LogicVRegister Simulator::sminv(VectorFormat vform, LogicVRegister dst,
1240 const LogicVRegister& src) {
1241 SMinMaxV(vform, dst, src,
false);
1245 LogicVRegister Simulator::UMinMax(VectorFormat vform, LogicVRegister dst,
1246 const LogicVRegister& src1,
1247 const LogicVRegister& src2,
bool max) {
1248 dst.ClearForWrite(vform);
1249 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1250 uint64_t src1_val = src1.Uint(vform,
i);
1251 uint64_t src2_val = src2.Uint(vform,
i);
1254 dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1256 dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1258 dst.SetUint(vform,
i, dst_val);
1263 LogicVRegister Simulator::umax(VectorFormat vform, LogicVRegister dst,
1264 const LogicVRegister& src1,
1265 const LogicVRegister& src2) {
1266 return UMinMax(vform, dst, src1, src2,
true);
1269 LogicVRegister Simulator::umin(VectorFormat vform, LogicVRegister dst,
1270 const LogicVRegister& src1,
1271 const LogicVRegister& src2) {
1272 return UMinMax(vform, dst, src1, src2,
false);
1275 LogicVRegister Simulator::UMinMaxP(VectorFormat vform, LogicVRegister dst,
1276 const LogicVRegister& src1,
1277 const LogicVRegister& src2,
bool max) {
1278 int lanes = LaneCountFromFormat(vform);
1279 uint64_t result[kMaxLanesPerVector];
1280 const LogicVRegister* src = &src1;
1281 for (
int j = 0; j < 2; j++) {
1282 for (
int i = 0;
i < LaneCountFromFormat(vform);
i += 2) {
1283 uint64_t first_val = src->Uint(vform,
i);
1284 uint64_t second_val = src->Uint(vform,
i + 1);
1287 dst_val = (first_val > second_val) ? first_val : second_val;
1289 dst_val = (first_val < second_val) ? first_val : second_val;
1291 DCHECK_LT((
i >> 1) + (j * lanes / 2), kMaxLanesPerVector);
1292 result[(
i >> 1) + (j * lanes / 2)] = dst_val;
1296 dst.SetUintArray(vform, result);
1300 LogicVRegister Simulator::umaxp(VectorFormat vform, LogicVRegister dst,
1301 const LogicVRegister& src1,
1302 const LogicVRegister& src2) {
1303 return UMinMaxP(vform, dst, src1, src2,
true);
1306 LogicVRegister Simulator::uminp(VectorFormat vform, LogicVRegister dst,
1307 const LogicVRegister& src1,
1308 const LogicVRegister& src2) {
1309 return UMinMaxP(vform, dst, src1, src2,
false);
1312 LogicVRegister Simulator::UMinMaxV(VectorFormat vform, LogicVRegister dst,
1313 const LogicVRegister& src,
bool max) {
1314 uint64_t dst_val = max ? 0 : UINT64_MAX;
1315 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1316 uint64_t src_val = src.Uint(vform,
i);
1318 dst_val = (src_val > dst_val) ? src_val : dst_val;
1320 dst_val = (src_val < dst_val) ? src_val : dst_val;
1323 dst.ClearForWrite(ScalarFormatFromFormat(vform));
1324 dst.SetUint(vform, 0, dst_val);
1328 LogicVRegister Simulator::umaxv(VectorFormat vform, LogicVRegister dst,
1329 const LogicVRegister& src) {
1330 UMinMaxV(vform, dst, src,
true);
1334 LogicVRegister Simulator::uminv(VectorFormat vform, LogicVRegister dst,
1335 const LogicVRegister& src) {
1336 UMinMaxV(vform, dst, src,
false);
1340 LogicVRegister Simulator::shl(VectorFormat vform, LogicVRegister dst,
1341 const LogicVRegister& src,
int shift) {
1342 DCHECK_GE(shift, 0);
1344 LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1345 return ushl(vform, dst, src, shiftreg);
1348 LogicVRegister Simulator::sshll(VectorFormat vform, LogicVRegister dst,
1349 const LogicVRegister& src,
int shift) {
1350 DCHECK_GE(shift, 0);
1351 SimVRegister temp1, temp2;
1352 LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1353 LogicVRegister extendedreg = sxtl(vform, temp2, src);
1354 return sshl(vform, dst, extendedreg, shiftreg);
1357 LogicVRegister Simulator::sshll2(VectorFormat vform, LogicVRegister dst,
1358 const LogicVRegister& src,
int shift) {
1359 DCHECK_GE(shift, 0);
1360 SimVRegister temp1, temp2;
1361 LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1362 LogicVRegister extendedreg = sxtl2(vform, temp2, src);
1363 return sshl(vform, dst, extendedreg, shiftreg);
1366 LogicVRegister Simulator::shll(VectorFormat vform, LogicVRegister dst,
1367 const LogicVRegister& src) {
1368 int shift = LaneSizeInBitsFromFormat(vform) / 2;
1369 return sshll(vform, dst, src, shift);
1372 LogicVRegister Simulator::shll2(VectorFormat vform, LogicVRegister dst,
1373 const LogicVRegister& src) {
1374 int shift = LaneSizeInBitsFromFormat(vform) / 2;
1375 return sshll2(vform, dst, src, shift);
1378 LogicVRegister Simulator::ushll(VectorFormat vform, LogicVRegister dst,
1379 const LogicVRegister& src,
int shift) {
1380 DCHECK_GE(shift, 0);
1381 SimVRegister temp1, temp2;
1382 LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1383 LogicVRegister extendedreg = uxtl(vform, temp2, src);
1384 return ushl(vform, dst, extendedreg, shiftreg);
1387 LogicVRegister Simulator::ushll2(VectorFormat vform, LogicVRegister dst,
1388 const LogicVRegister& src,
int shift) {
1389 DCHECK_GE(shift, 0);
1390 SimVRegister temp1, temp2;
1391 LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1392 LogicVRegister extendedreg = uxtl2(vform, temp2, src);
1393 return ushl(vform, dst, extendedreg, shiftreg);
1396 LogicVRegister Simulator::sli(VectorFormat vform, LogicVRegister dst,
1397 const LogicVRegister& src,
int shift) {
1398 dst.ClearForWrite(vform);
1399 int laneCount = LaneCountFromFormat(vform);
1400 for (
int i = 0;
i < laneCount;
i++) {
1401 uint64_t src_lane = src.Uint(vform,
i);
1402 uint64_t dst_lane = dst.Uint(vform,
i);
1403 uint64_t shifted = src_lane << shift;
1404 uint64_t mask = MaxUintFromFormat(vform) << shift;
1405 dst.SetUint(vform,
i, (dst_lane & ~mask) | shifted);
1410 LogicVRegister Simulator::sqshl(VectorFormat vform, LogicVRegister dst,
1411 const LogicVRegister& src,
int shift) {
1412 DCHECK_GE(shift, 0);
1414 LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1415 return sshl(vform, dst, src, shiftreg).SignedSaturate(vform);
1418 LogicVRegister Simulator::uqshl(VectorFormat vform, LogicVRegister dst,
1419 const LogicVRegister& src,
int shift) {
1420 DCHECK_GE(shift, 0);
1422 LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1423 return ushl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
1426 LogicVRegister Simulator::sqshlu(VectorFormat vform, LogicVRegister dst,
1427 const LogicVRegister& src,
int shift) {
1428 DCHECK_GE(shift, 0);
1430 LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1431 return sshl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
1434 LogicVRegister Simulator::sri(VectorFormat vform, LogicVRegister dst,
1435 const LogicVRegister& src,
int shift) {
1436 dst.ClearForWrite(vform);
1437 int laneCount = LaneCountFromFormat(vform);
1438 DCHECK((shift > 0) &&
1439 (shift <= static_cast<int>(LaneSizeInBitsFromFormat(vform))));
1440 for (
int i = 0;
i < laneCount;
i++) {
1441 uint64_t src_lane = src.Uint(vform,
i);
1442 uint64_t dst_lane = dst.Uint(vform,
i);
1449 shifted = src_lane >> shift;
1450 mask = MaxUintFromFormat(vform) >> shift;
1452 dst.SetUint(vform,
i, (dst_lane & ~mask) | shifted);
1457 LogicVRegister Simulator::ushr(VectorFormat vform, LogicVRegister dst,
1458 const LogicVRegister& src,
int shift) {
1459 DCHECK_GE(shift, 0);
1461 LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
1462 return ushl(vform, dst, src, shiftreg);
1465 LogicVRegister Simulator::sshr(VectorFormat vform, LogicVRegister dst,
1466 const LogicVRegister& src,
int shift) {
1467 DCHECK_GE(shift, 0);
1469 LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
1470 return sshl(vform, dst, src, shiftreg);
1473 LogicVRegister Simulator::ssra(VectorFormat vform, LogicVRegister dst,
1474 const LogicVRegister& src,
int shift) {
1476 LogicVRegister shifted_reg = sshr(vform, temp, src, shift);
1477 return add(vform, dst, dst, shifted_reg);
1480 LogicVRegister Simulator::usra(VectorFormat vform, LogicVRegister dst,
1481 const LogicVRegister& src,
int shift) {
1483 LogicVRegister shifted_reg = ushr(vform, temp, src, shift);
1484 return add(vform, dst, dst, shifted_reg);
1487 LogicVRegister Simulator::srsra(VectorFormat vform, LogicVRegister dst,
1488 const LogicVRegister& src,
int shift) {
1490 LogicVRegister shifted_reg = sshr(vform, temp, src, shift).Round(vform);
1491 return add(vform, dst, dst, shifted_reg);
1494 LogicVRegister Simulator::ursra(VectorFormat vform, LogicVRegister dst,
1495 const LogicVRegister& src,
int shift) {
1497 LogicVRegister shifted_reg = ushr(vform, temp, src, shift).Round(vform);
1498 return add(vform, dst, dst, shifted_reg);
1501 LogicVRegister Simulator::cls(VectorFormat vform, LogicVRegister dst,
1502 const LogicVRegister& src) {
1503 uint64_t result[16];
1504 int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
1505 int laneCount = LaneCountFromFormat(vform);
1506 for (
int i = 0;
i < laneCount;
i++) {
1507 result[
i] = CountLeadingSignBits(src.Int(vform,
i), laneSizeInBits);
1510 dst.SetUintArray(vform, result);
1514 LogicVRegister Simulator::clz(VectorFormat vform, LogicVRegister dst,
1515 const LogicVRegister& src) {
1516 uint64_t result[16];
1517 int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
1518 int laneCount = LaneCountFromFormat(vform);
1519 for (
int i = 0;
i < laneCount;
i++) {
1520 result[
i] = CountLeadingZeros(src.Uint(vform,
i), laneSizeInBits);
1523 dst.SetUintArray(vform, result);
1527 LogicVRegister Simulator::cnt(VectorFormat vform, LogicVRegister dst,
1528 const LogicVRegister& src) {
1529 uint64_t result[16];
1530 int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
1531 int laneCount = LaneCountFromFormat(vform);
1532 for (
int i = 0;
i < laneCount;
i++) {
1533 uint64_t value = src.Uint(vform,
i);
1535 for (
int j = 0; j < laneSizeInBits; j++) {
1536 result[
i] += (value & 1);
1541 dst.SetUintArray(vform, result);
1545 LogicVRegister Simulator::sshl(VectorFormat vform, LogicVRegister dst,
1546 const LogicVRegister& src1,
1547 const LogicVRegister& src2) {
1548 dst.ClearForWrite(vform);
1549 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1550 int8_t shift_val = src2.Int(vform,
i);
1551 int64_t lj_src_val = src1.IntLeftJustified(vform,
i);
1554 if ((shift_val > CountLeadingSignBits(lj_src_val, 64)) &&
1555 (lj_src_val != 0)) {
1556 dst.SetSignedSat(
i, lj_src_val >= 0);
1560 if (lj_src_val < 0) {
1561 dst.SetUnsignedSat(
i,
false);
1562 }
else if ((shift_val > CountLeadingZeros(lj_src_val, 64)) &&
1563 (lj_src_val != 0)) {
1564 dst.SetUnsignedSat(
i,
true);
1567 int64_t src_val = src1.Int(vform,
i);
1568 bool src_is_negative = src_val < 0;
1569 if (shift_val > 63) {
1570 dst.SetInt(vform,
i, 0);
1571 }
else if (shift_val < -63) {
1572 dst.SetRounding(
i, src_is_negative);
1573 dst.SetInt(vform,
i, src_is_negative ? -1 : 0);
1577 uint64_t usrc_val =
static_cast<uint64_t
>(src_val);
1579 if (shift_val < 0) {
1581 shift_val = -shift_val;
1585 if (((usrc_val >> (shift_val - 1)) & 1) == 1) {
1586 dst.SetRounding(
i,
true);
1589 usrc_val >>= shift_val;
1591 if (src_is_negative) {
1593 usrc_val |= (~UINT64_C(0) << (64 - shift_val));
1596 usrc_val <<= shift_val;
1598 dst.SetUint(vform,
i, usrc_val);
1604 LogicVRegister Simulator::ushl(VectorFormat vform, LogicVRegister dst,
1605 const LogicVRegister& src1,
1606 const LogicVRegister& src2) {
1607 dst.ClearForWrite(vform);
1608 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1609 int8_t shift_val = src2.Int(vform,
i);
1610 uint64_t lj_src_val = src1.UintLeftJustified(vform,
i);
1613 if ((shift_val > CountLeadingZeros(lj_src_val, 64)) && (lj_src_val != 0)) {
1614 dst.SetUnsignedSat(
i,
true);
1617 uint64_t src_val = src1.Uint(vform,
i);
1618 if ((shift_val > 63) || (shift_val < -64)) {
1619 dst.SetUint(vform,
i, 0);
1621 if (shift_val < 0) {
1623 if (((src_val >> (-shift_val - 1)) & 1) == 1) {
1624 dst.SetRounding(
i,
true);
1627 if (shift_val == -64) {
1630 src_val >>= -shift_val;
1633 src_val <<= shift_val;
1635 dst.SetUint(vform,
i, src_val);
1641 LogicVRegister Simulator::neg(VectorFormat vform, LogicVRegister dst,
1642 const LogicVRegister& src) {
1643 dst.ClearForWrite(vform);
1644 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1647 if (sa == MinIntFromFormat(vform)) {
1648 dst.SetSignedSat(
i,
true);
1650 dst.SetInt(vform,
i, (sa == INT64_MIN) ? sa : -sa);
1655 LogicVRegister Simulator::suqadd(VectorFormat vform, LogicVRegister dst,
1656 const LogicVRegister& src) {
1657 dst.ClearForWrite(vform);
1658 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1659 int64_t sa = dst.IntLeftJustified(vform,
i);
1660 uint64_t ub = src.UintLeftJustified(vform,
i);
1661 uint64_t ur = sa + ub;
1665 dst.SetInt(vform,
i, MaxIntFromFormat(vform));
1667 dst.SetUint(vform,
i, dst.Int(vform,
i) + src.Uint(vform,
i));
1673 LogicVRegister Simulator::usqadd(VectorFormat vform, LogicVRegister dst,
1674 const LogicVRegister& src) {
1675 dst.ClearForWrite(vform);
1676 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1677 uint64_t ua = dst.UintLeftJustified(vform,
i);
1678 int64_t sb = src.IntLeftJustified(vform,
i);
1679 uint64_t ur = ua + sb;
1681 if ((sb > 0) && (ur <= ua)) {
1682 dst.SetUint(vform,
i, MaxUintFromFormat(vform));
1683 }
else if ((sb < 0) && (ur >= ua)) {
1684 dst.SetUint(vform,
i, 0);
1686 dst.SetUint(vform,
i, dst.Uint(vform,
i) + src.Int(vform,
i));
1692 LogicVRegister Simulator::abs(VectorFormat vform, LogicVRegister dst,
1693 const LogicVRegister& src) {
1694 dst.ClearForWrite(vform);
1695 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1698 if (sa == MinIntFromFormat(vform)) {
1699 dst.SetSignedSat(
i,
true);
1702 dst.SetInt(vform,
i, (sa == INT64_MIN) ? sa : -sa);
1704 dst.SetInt(vform,
i, sa);
1710 LogicVRegister Simulator::ExtractNarrow(VectorFormat dstform,
1711 LogicVRegister dst,
bool dstIsSigned,
1712 const LogicVRegister& src,
1714 bool upperhalf =
false;
1715 VectorFormat srcform = kFormatUndefined;
1722 srcform = kFormat8H;
1726 srcform = kFormat8H;
1730 srcform = kFormat4S;
1734 srcform = kFormat4S;
1738 srcform = kFormat2D;
1742 srcform = kFormat2D;
1760 for (
int i = 0;
i < LaneCountFromFormat(srcform);
i++) {
1761 ssrc[
i] = src.Int(srcform,
i);
1762 usrc[
i] = src.Uint(srcform,
i);
1767 offset = LaneCountFromFormat(dstform) / 2;
1770 dst.ClearForWrite(dstform);
1773 for (
int i = 0;
i < LaneCountFromFormat(srcform);
i++) {
1775 if (ssrc[
i] > MaxIntFromFormat(dstform)) {
1776 dst.SetSignedSat(offset +
i,
true);
1777 }
else if (ssrc[
i] < MinIntFromFormat(dstform)) {
1778 dst.SetSignedSat(offset +
i,
false);
1783 if (ssrc[
i] > static_cast<int64_t>(MaxUintFromFormat(dstform))) {
1784 dst.SetUnsignedSat(offset +
i,
true);
1785 }
else if (ssrc[
i] < 0) {
1786 dst.SetUnsignedSat(offset +
i,
false);
1789 if (usrc[
i] > MaxUintFromFormat(dstform)) {
1790 dst.SetUnsignedSat(offset +
i,
true);
1796 result = ssrc[
i] & MaxUintFromFormat(dstform);
1798 result = usrc[
i] & MaxUintFromFormat(dstform);
1802 dst.SetInt(dstform, offset +
i, result);
1804 dst.SetUint(dstform, offset +
i, result);
1810 LogicVRegister Simulator::xtn(VectorFormat vform, LogicVRegister dst,
1811 const LogicVRegister& src) {
1812 return ExtractNarrow(vform, dst,
true, src,
true);
1815 LogicVRegister Simulator::sqxtn(VectorFormat vform, LogicVRegister dst,
1816 const LogicVRegister& src) {
1817 return ExtractNarrow(vform, dst,
true, src,
true).SignedSaturate(vform);
1820 LogicVRegister Simulator::sqxtun(VectorFormat vform, LogicVRegister dst,
1821 const LogicVRegister& src) {
1822 return ExtractNarrow(vform, dst,
false, src,
true).UnsignedSaturate(vform);
1825 LogicVRegister Simulator::uqxtn(VectorFormat vform, LogicVRegister dst,
1826 const LogicVRegister& src) {
1827 return ExtractNarrow(vform, dst,
false, src,
false).UnsignedSaturate(vform);
1830 LogicVRegister Simulator::AbsDiff(VectorFormat vform, LogicVRegister dst,
1831 const LogicVRegister& src1,
1832 const LogicVRegister& src2,
bool issigned) {
1833 dst.ClearForWrite(vform);
1834 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1836 int64_t sr = src1.Int(vform,
i) - src2.Int(vform,
i);
1837 sr = sr > 0 ? sr : -sr;
1838 dst.SetInt(vform,
i, sr);
1840 int64_t sr = src1.Uint(vform,
i) - src2.Uint(vform,
i);
1841 sr = sr > 0 ? sr : -sr;
1842 dst.SetUint(vform,
i, sr);
1848 LogicVRegister Simulator::saba(VectorFormat vform, LogicVRegister dst,
1849 const LogicVRegister& src1,
1850 const LogicVRegister& src2) {
1852 dst.ClearForWrite(vform);
1853 AbsDiff(vform, temp, src1, src2,
true);
1854 add(vform, dst, dst, temp);
1858 LogicVRegister Simulator::uaba(VectorFormat vform, LogicVRegister dst,
1859 const LogicVRegister& src1,
1860 const LogicVRegister& src2) {
1862 dst.ClearForWrite(vform);
1863 AbsDiff(vform, temp, src1, src2,
false);
1864 add(vform, dst, dst, temp);
1868 LogicVRegister Simulator::not_(VectorFormat vform, LogicVRegister dst,
1869 const LogicVRegister& src) {
1870 dst.ClearForWrite(vform);
1871 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
1872 dst.SetUint(vform,
i, ~src.Uint(vform,
i));
1877 LogicVRegister Simulator::rbit(VectorFormat vform, LogicVRegister dst,
1878 const LogicVRegister& src) {
1879 uint64_t result[16];
1880 int laneCount = LaneCountFromFormat(vform);
1881 int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
1882 uint64_t reversed_value;
1884 for (
int i = 0;
i < laneCount;
i++) {
1885 value = src.Uint(vform,
i);
1887 for (
int j = 0; j < laneSizeInBits; j++) {
1888 reversed_value = (reversed_value << 1) | (value & 1);
1891 result[
i] = reversed_value;
1894 dst.SetUintArray(vform, result);
1898 LogicVRegister Simulator::rev(VectorFormat vform, LogicVRegister dst,
1899 const LogicVRegister& src,
int revSize) {
1900 uint64_t result[16];
1901 int laneCount = LaneCountFromFormat(vform);
1902 int laneSize = LaneSizeInBytesFromFormat(vform);
1903 int lanesPerLoop = revSize / laneSize;
1904 for (
int i = 0;
i < laneCount;
i += lanesPerLoop) {
1905 for (
int j = 0; j < lanesPerLoop; j++) {
1906 result[
i + lanesPerLoop - 1 - j] = src.Uint(vform,
i + j);
1909 dst.SetUintArray(vform, result);
1913 LogicVRegister Simulator::rev16(VectorFormat vform, LogicVRegister dst,
1914 const LogicVRegister& src) {
1915 return rev(vform, dst, src, 2);
1918 LogicVRegister Simulator::rev32(VectorFormat vform, LogicVRegister dst,
1919 const LogicVRegister& src) {
1920 return rev(vform, dst, src, 4);
1923 LogicVRegister Simulator::rev64(VectorFormat vform, LogicVRegister dst,
1924 const LogicVRegister& src) {
1925 return rev(vform, dst, src, 8);
1928 LogicVRegister Simulator::addlp(VectorFormat vform, LogicVRegister dst,
1929 const LogicVRegister& src,
bool is_signed,
1930 bool do_accumulate) {
1931 VectorFormat vformsrc = VectorFormatHalfWidthDoubleLanes(vform);
1932 DCHECK_LE(LaneSizeInBitsFromFormat(vformsrc), 32U);
1933 DCHECK_LE(LaneCountFromFormat(vform), 8);
1936 int lane_count = LaneCountFromFormat(vform);
1937 for (
int i = 0;
i < lane_count;
i++) {
1939 result[
i] =
static_cast<uint64_t
>(src.Int(vformsrc, 2 *
i) +
1940 src.Int(vformsrc, 2 *
i + 1));
1942 result[
i] = src.Uint(vformsrc, 2 *
i) + src.Uint(vformsrc, 2 *
i + 1);
1946 dst.ClearForWrite(vform);
1947 for (
int i = 0;
i < lane_count; ++
i) {
1948 if (do_accumulate) {
1949 result[
i] += dst.Uint(vform,
i);
1951 dst.SetUint(vform,
i, result[
i]);
1957 LogicVRegister Simulator::saddlp(VectorFormat vform, LogicVRegister dst,
1958 const LogicVRegister& src) {
1959 return addlp(vform, dst, src,
true,
false);
1962 LogicVRegister Simulator::uaddlp(VectorFormat vform, LogicVRegister dst,
1963 const LogicVRegister& src) {
1964 return addlp(vform, dst, src,
false,
false);
1967 LogicVRegister Simulator::sadalp(VectorFormat vform, LogicVRegister dst,
1968 const LogicVRegister& src) {
1969 return addlp(vform, dst, src,
true,
true);
1972 LogicVRegister Simulator::uadalp(VectorFormat vform, LogicVRegister dst,
1973 const LogicVRegister& src) {
1974 return addlp(vform, dst, src,
false,
true);
1977 LogicVRegister Simulator::ext(VectorFormat vform, LogicVRegister dst,
1978 const LogicVRegister& src1,
1979 const LogicVRegister& src2,
int index) {
1981 int laneCount = LaneCountFromFormat(vform);
1982 for (
int i = 0;
i < laneCount - index; ++
i) {
1983 result[
i] = src1.Uint(vform,
i + index);
1985 for (
int i = 0;
i < index; ++
i) {
1986 result[laneCount - index +
i] = src2.Uint(vform,
i);
1988 dst.ClearForWrite(vform);
1989 for (
int i = 0;
i < laneCount; ++
i) {
1990 dst.SetUint(vform,
i, result[
i]);
1995 LogicVRegister Simulator::dup_element(VectorFormat vform, LogicVRegister dst,
1996 const LogicVRegister& src,
1998 int laneCount = LaneCountFromFormat(vform);
1999 uint64_t value = src.Uint(vform, src_index);
2000 dst.ClearForWrite(vform);
2001 for (
int i = 0;
i < laneCount; ++
i) {
2002 dst.SetUint(vform,
i, value);
2007 LogicVRegister Simulator::dup_immediate(VectorFormat vform, LogicVRegister dst,
2009 int laneCount = LaneCountFromFormat(vform);
2010 uint64_t value = imm & MaxUintFromFormat(vform);
2011 dst.ClearForWrite(vform);
2012 for (
int i = 0;
i < laneCount; ++
i) {
2013 dst.SetUint(vform,
i, value);
2018 LogicVRegister Simulator::ins_element(VectorFormat vform, LogicVRegister dst,
2019 int dst_index,
const LogicVRegister& src,
2021 dst.SetUint(vform, dst_index, src.Uint(vform, src_index));
2025 LogicVRegister Simulator::ins_immediate(VectorFormat vform, LogicVRegister dst,
2026 int dst_index, uint64_t imm) {
2027 uint64_t value = imm & MaxUintFromFormat(vform);
2028 dst.SetUint(vform, dst_index, value);
2032 LogicVRegister Simulator::movi(VectorFormat vform, LogicVRegister dst,
2034 int laneCount = LaneCountFromFormat(vform);
2035 dst.ClearForWrite(vform);
2036 for (
int i = 0;
i < laneCount; ++
i) {
2037 dst.SetUint(vform,
i, imm);
2042 LogicVRegister Simulator::mvni(VectorFormat vform, LogicVRegister dst,
2044 int laneCount = LaneCountFromFormat(vform);
2045 dst.ClearForWrite(vform);
2046 for (
int i = 0;
i < laneCount; ++
i) {
2047 dst.SetUint(vform,
i, ~imm);
2052 LogicVRegister Simulator::orr(VectorFormat vform, LogicVRegister dst,
2053 const LogicVRegister& src, uint64_t imm) {
2054 uint64_t result[16];
2055 int laneCount = LaneCountFromFormat(vform);
2056 for (
int i = 0;
i < laneCount; ++
i) {
2057 result[
i] = src.Uint(vform,
i) | imm;
2059 dst.SetUintArray(vform, result);
2063 LogicVRegister Simulator::uxtl(VectorFormat vform, LogicVRegister dst,
2064 const LogicVRegister& src) {
2065 VectorFormat vform_half = VectorFormatHalfWidth(vform);
2067 dst.ClearForWrite(vform);
2068 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
2069 dst.SetUint(vform,
i, src.Uint(vform_half,
i));
2074 LogicVRegister Simulator::sxtl(VectorFormat vform, LogicVRegister dst,
2075 const LogicVRegister& src) {
2076 VectorFormat vform_half = VectorFormatHalfWidth(vform);
2078 dst.ClearForWrite(vform);
2079 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
2080 dst.SetInt(vform,
i, src.Int(vform_half,
i));
2085 LogicVRegister Simulator::uxtl2(VectorFormat vform, LogicVRegister dst,
2086 const LogicVRegister& src) {
2087 VectorFormat vform_half = VectorFormatHalfWidth(vform);
2088 int lane_count = LaneCountFromFormat(vform);
2090 dst.ClearForWrite(vform);
2091 for (
int i = 0;
i < lane_count;
i++) {
2092 dst.SetUint(vform,
i, src.Uint(vform_half, lane_count +
i));
2097 LogicVRegister Simulator::sxtl2(VectorFormat vform, LogicVRegister dst,
2098 const LogicVRegister& src) {
2099 VectorFormat vform_half = VectorFormatHalfWidth(vform);
2100 int lane_count = LaneCountFromFormat(vform);
2102 dst.ClearForWrite(vform);
2103 for (
int i = 0;
i < lane_count;
i++) {
2104 dst.SetInt(vform,
i, src.Int(vform_half, lane_count +
i));
2109 LogicVRegister Simulator::shrn(VectorFormat vform, LogicVRegister dst,
2110 const LogicVRegister& src,
int shift) {
2112 VectorFormat vform_src = VectorFormatDoubleWidth(vform);
2113 VectorFormat vform_dst = vform;
2114 LogicVRegister shifted_src = ushr(vform_src, temp, src, shift);
2115 return ExtractNarrow(vform_dst, dst,
false, shifted_src,
false);
2118 LogicVRegister Simulator::shrn2(VectorFormat vform, LogicVRegister dst,
2119 const LogicVRegister& src,
int shift) {
2121 VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2122 VectorFormat vformdst = vform;
2123 LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift);
2124 return ExtractNarrow(vformdst, dst,
false, shifted_src,
false);
2127 LogicVRegister Simulator::rshrn(VectorFormat vform, LogicVRegister dst,
2128 const LogicVRegister& src,
int shift) {
2130 VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2131 VectorFormat vformdst = vform;
2132 LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
2133 return ExtractNarrow(vformdst, dst,
false, shifted_src,
false);
2136 LogicVRegister Simulator::rshrn2(VectorFormat vform, LogicVRegister dst,
2137 const LogicVRegister& src,
int shift) {
2139 VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2140 VectorFormat vformdst = vform;
2141 LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
2142 return ExtractNarrow(vformdst, dst,
false, shifted_src,
false);
2145 LogicVRegister Simulator::Table(VectorFormat vform, LogicVRegister dst,
2146 const LogicVRegister& ind,
2147 bool zero_out_of_bounds,
2148 const LogicVRegister* tab1,
2149 const LogicVRegister* tab2,
2150 const LogicVRegister* tab3,
2151 const LogicVRegister* tab4) {
2152 DCHECK_NOT_NULL(tab1);
2153 const LogicVRegister* tab[4] = {tab1, tab2, tab3, tab4};
2154 uint64_t result[kMaxLanesPerVector];
2155 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
2156 result[
i] = zero_out_of_bounds ? 0 : dst.Uint(kFormat16B,
i);
2158 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
2159 uint64_t j = ind.Uint(vform,
i);
2160 int tab_idx =
static_cast<int>(j >> 4);
2161 int j_idx =
static_cast<int>(j & 15);
2162 if ((tab_idx < 4) && (tab[tab_idx] !=
nullptr)) {
2163 result[
i] = tab[tab_idx]->Uint(kFormat16B, j_idx);
2166 dst.SetUintArray(vform, result);
2170 LogicVRegister Simulator::tbl(VectorFormat vform, LogicVRegister dst,
2171 const LogicVRegister& tab,
2172 const LogicVRegister& ind) {
2173 return Table(vform, dst, ind,
true, &tab);
2176 LogicVRegister Simulator::tbl(VectorFormat vform, LogicVRegister dst,
2177 const LogicVRegister& tab,
2178 const LogicVRegister& tab2,
2179 const LogicVRegister& ind) {
2180 return Table(vform, dst, ind,
true, &tab, &tab2);
2183 LogicVRegister Simulator::tbl(VectorFormat vform, LogicVRegister dst,
2184 const LogicVRegister& tab,
2185 const LogicVRegister& tab2,
2186 const LogicVRegister& tab3,
2187 const LogicVRegister& ind) {
2188 return Table(vform, dst, ind,
true, &tab, &tab2, &tab3);
2191 LogicVRegister Simulator::tbl(VectorFormat vform, LogicVRegister dst,
2192 const LogicVRegister& tab,
2193 const LogicVRegister& tab2,
2194 const LogicVRegister& tab3,
2195 const LogicVRegister& tab4,
2196 const LogicVRegister& ind) {
2197 return Table(vform, dst, ind,
true, &tab, &tab2, &tab3, &tab4);
2200 LogicVRegister Simulator::tbx(VectorFormat vform, LogicVRegister dst,
2201 const LogicVRegister& tab,
2202 const LogicVRegister& ind) {
2203 return Table(vform, dst, ind,
false, &tab);
2206 LogicVRegister Simulator::tbx(VectorFormat vform, LogicVRegister dst,
2207 const LogicVRegister& tab,
2208 const LogicVRegister& tab2,
2209 const LogicVRegister& ind) {
2210 return Table(vform, dst, ind,
false, &tab, &tab2);
2213 LogicVRegister Simulator::tbx(VectorFormat vform, LogicVRegister dst,
2214 const LogicVRegister& tab,
2215 const LogicVRegister& tab2,
2216 const LogicVRegister& tab3,
2217 const LogicVRegister& ind) {
2218 return Table(vform, dst, ind,
false, &tab, &tab2, &tab3);
2221 LogicVRegister Simulator::tbx(VectorFormat vform, LogicVRegister dst,
2222 const LogicVRegister& tab,
2223 const LogicVRegister& tab2,
2224 const LogicVRegister& tab3,
2225 const LogicVRegister& tab4,
2226 const LogicVRegister& ind) {
2227 return Table(vform, dst, ind,
false, &tab, &tab2, &tab3, &tab4);
2230 LogicVRegister Simulator::uqshrn(VectorFormat vform, LogicVRegister dst,
2231 const LogicVRegister& src,
int shift) {
2232 return shrn(vform, dst, src, shift).UnsignedSaturate(vform);
2235 LogicVRegister Simulator::uqshrn2(VectorFormat vform, LogicVRegister dst,
2236 const LogicVRegister& src,
int shift) {
2237 return shrn2(vform, dst, src, shift).UnsignedSaturate(vform);
2240 LogicVRegister Simulator::uqrshrn(VectorFormat vform, LogicVRegister dst,
2241 const LogicVRegister& src,
int shift) {
2242 return rshrn(vform, dst, src, shift).UnsignedSaturate(vform);
2245 LogicVRegister Simulator::uqrshrn2(VectorFormat vform, LogicVRegister dst,
2246 const LogicVRegister& src,
int shift) {
2247 return rshrn2(vform, dst, src, shift).UnsignedSaturate(vform);
2250 LogicVRegister Simulator::sqshrn(VectorFormat vform, LogicVRegister dst,
2251 const LogicVRegister& src,
int shift) {
2253 VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2254 VectorFormat vformdst = vform;
2255 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2256 return sqxtn(vformdst, dst, shifted_src);
2259 LogicVRegister Simulator::sqshrn2(VectorFormat vform, LogicVRegister dst,
2260 const LogicVRegister& src,
int shift) {
2262 VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2263 VectorFormat vformdst = vform;
2264 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2265 return sqxtn(vformdst, dst, shifted_src);
2268 LogicVRegister Simulator::sqrshrn(VectorFormat vform, LogicVRegister dst,
2269 const LogicVRegister& src,
int shift) {
2271 VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2272 VectorFormat vformdst = vform;
2273 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2274 return sqxtn(vformdst, dst, shifted_src);
2277 LogicVRegister Simulator::sqrshrn2(VectorFormat vform, LogicVRegister dst,
2278 const LogicVRegister& src,
int shift) {
2280 VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2281 VectorFormat vformdst = vform;
2282 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2283 return sqxtn(vformdst, dst, shifted_src);
2286 LogicVRegister Simulator::sqshrun(VectorFormat vform, LogicVRegister dst,
2287 const LogicVRegister& src,
int shift) {
2289 VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2290 VectorFormat vformdst = vform;
2291 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2292 return sqxtun(vformdst, dst, shifted_src);
2295 LogicVRegister Simulator::sqshrun2(VectorFormat vform, LogicVRegister dst,
2296 const LogicVRegister& src,
int shift) {
2298 VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2299 VectorFormat vformdst = vform;
2300 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2301 return sqxtun(vformdst, dst, shifted_src);
2304 LogicVRegister Simulator::sqrshrun(VectorFormat vform, LogicVRegister dst,
2305 const LogicVRegister& src,
int shift) {
2307 VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2308 VectorFormat vformdst = vform;
2309 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2310 return sqxtun(vformdst, dst, shifted_src);
2313 LogicVRegister Simulator::sqrshrun2(VectorFormat vform, LogicVRegister dst,
2314 const LogicVRegister& src,
int shift) {
2316 VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2317 VectorFormat vformdst = vform;
2318 LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2319 return sqxtun(vformdst, dst, shifted_src);
2322 LogicVRegister Simulator::uaddl(VectorFormat vform, LogicVRegister dst,
2323 const LogicVRegister& src1,
2324 const LogicVRegister& src2) {
2325 SimVRegister temp1, temp2;
2326 uxtl(vform, temp1, src1);
2327 uxtl(vform, temp2, src2);
2328 add(vform, dst, temp1, temp2);
2332 LogicVRegister Simulator::uaddl2(VectorFormat vform, LogicVRegister dst,
2333 const LogicVRegister& src1,
2334 const LogicVRegister& src2) {
2335 SimVRegister temp1, temp2;
2336 uxtl2(vform, temp1, src1);
2337 uxtl2(vform, temp2, src2);
2338 add(vform, dst, temp1, temp2);
2342 LogicVRegister Simulator::uaddw(VectorFormat vform, LogicVRegister dst,
2343 const LogicVRegister& src1,
2344 const LogicVRegister& src2) {
2346 uxtl(vform, temp, src2);
2347 add(vform, dst, src1, temp);
2351 LogicVRegister Simulator::uaddw2(VectorFormat vform, LogicVRegister dst,
2352 const LogicVRegister& src1,
2353 const LogicVRegister& src2) {
2355 uxtl2(vform, temp, src2);
2356 add(vform, dst, src1, temp);
2360 LogicVRegister Simulator::saddl(VectorFormat vform, LogicVRegister dst,
2361 const LogicVRegister& src1,
2362 const LogicVRegister& src2) {
2363 SimVRegister temp1, temp2;
2364 sxtl(vform, temp1, src1);
2365 sxtl(vform, temp2, src2);
2366 add(vform, dst, temp1, temp2);
2370 LogicVRegister Simulator::saddl2(VectorFormat vform, LogicVRegister dst,
2371 const LogicVRegister& src1,
2372 const LogicVRegister& src2) {
2373 SimVRegister temp1, temp2;
2374 sxtl2(vform, temp1, src1);
2375 sxtl2(vform, temp2, src2);
2376 add(vform, dst, temp1, temp2);
2380 LogicVRegister Simulator::saddw(VectorFormat vform, LogicVRegister dst,
2381 const LogicVRegister& src1,
2382 const LogicVRegister& src2) {
2384 sxtl(vform, temp, src2);
2385 add(vform, dst, src1, temp);
2389 LogicVRegister Simulator::saddw2(VectorFormat vform, LogicVRegister dst,
2390 const LogicVRegister& src1,
2391 const LogicVRegister& src2) {
2393 sxtl2(vform, temp, src2);
2394 add(vform, dst, src1, temp);
2398 LogicVRegister Simulator::usubl(VectorFormat vform, LogicVRegister dst,
2399 const LogicVRegister& src1,
2400 const LogicVRegister& src2) {
2401 SimVRegister temp1, temp2;
2402 uxtl(vform, temp1, src1);
2403 uxtl(vform, temp2, src2);
2404 sub(vform, dst, temp1, temp2);
2408 LogicVRegister Simulator::usubl2(VectorFormat vform, LogicVRegister dst,
2409 const LogicVRegister& src1,
2410 const LogicVRegister& src2) {
2411 SimVRegister temp1, temp2;
2412 uxtl2(vform, temp1, src1);
2413 uxtl2(vform, temp2, src2);
2414 sub(vform, dst, temp1, temp2);
2418 LogicVRegister Simulator::usubw(VectorFormat vform, LogicVRegister dst,
2419 const LogicVRegister& src1,
2420 const LogicVRegister& src2) {
2422 uxtl(vform, temp, src2);
2423 sub(vform, dst, src1, temp);
2427 LogicVRegister Simulator::usubw2(VectorFormat vform, LogicVRegister dst,
2428 const LogicVRegister& src1,
2429 const LogicVRegister& src2) {
2431 uxtl2(vform, temp, src2);
2432 sub(vform, dst, src1, temp);
2436 LogicVRegister Simulator::ssubl(VectorFormat vform, LogicVRegister dst,
2437 const LogicVRegister& src1,
2438 const LogicVRegister& src2) {
2439 SimVRegister temp1, temp2;
2440 sxtl(vform, temp1, src1);
2441 sxtl(vform, temp2, src2);
2442 sub(vform, dst, temp1, temp2);
2446 LogicVRegister Simulator::ssubl2(VectorFormat vform, LogicVRegister dst,
2447 const LogicVRegister& src1,
2448 const LogicVRegister& src2) {
2449 SimVRegister temp1, temp2;
2450 sxtl2(vform, temp1, src1);
2451 sxtl2(vform, temp2, src2);
2452 sub(vform, dst, temp1, temp2);
2456 LogicVRegister Simulator::ssubw(VectorFormat vform, LogicVRegister dst,
2457 const LogicVRegister& src1,
2458 const LogicVRegister& src2) {
2460 sxtl(vform, temp, src2);
2461 sub(vform, dst, src1, temp);
2465 LogicVRegister Simulator::ssubw2(VectorFormat vform, LogicVRegister dst,
2466 const LogicVRegister& src1,
2467 const LogicVRegister& src2) {
2469 sxtl2(vform, temp, src2);
2470 sub(vform, dst, src1, temp);
2474 LogicVRegister Simulator::uabal(VectorFormat vform, LogicVRegister dst,
2475 const LogicVRegister& src1,
2476 const LogicVRegister& src2) {
2477 SimVRegister temp1, temp2;
2478 uxtl(vform, temp1, src1);
2479 uxtl(vform, temp2, src2);
2480 uaba(vform, dst, temp1, temp2);
2484 LogicVRegister Simulator::uabal2(VectorFormat vform, LogicVRegister dst,
2485 const LogicVRegister& src1,
2486 const LogicVRegister& src2) {
2487 SimVRegister temp1, temp2;
2488 uxtl2(vform, temp1, src1);
2489 uxtl2(vform, temp2, src2);
2490 uaba(vform, dst, temp1, temp2);
2494 LogicVRegister Simulator::sabal(VectorFormat vform, LogicVRegister dst,
2495 const LogicVRegister& src1,
2496 const LogicVRegister& src2) {
2497 SimVRegister temp1, temp2;
2498 sxtl(vform, temp1, src1);
2499 sxtl(vform, temp2, src2);
2500 saba(vform, dst, temp1, temp2);
2504 LogicVRegister Simulator::sabal2(VectorFormat vform, LogicVRegister dst,
2505 const LogicVRegister& src1,
2506 const LogicVRegister& src2) {
2507 SimVRegister temp1, temp2;
2508 sxtl2(vform, temp1, src1);
2509 sxtl2(vform, temp2, src2);
2510 saba(vform, dst, temp1, temp2);
2514 LogicVRegister Simulator::uabdl(VectorFormat vform, LogicVRegister dst,
2515 const LogicVRegister& src1,
2516 const LogicVRegister& src2) {
2517 SimVRegister temp1, temp2;
2518 uxtl(vform, temp1, src1);
2519 uxtl(vform, temp2, src2);
2520 AbsDiff(vform, dst, temp1, temp2,
false);
2524 LogicVRegister Simulator::uabdl2(VectorFormat vform, LogicVRegister dst,
2525 const LogicVRegister& src1,
2526 const LogicVRegister& src2) {
2527 SimVRegister temp1, temp2;
2528 uxtl2(vform, temp1, src1);
2529 uxtl2(vform, temp2, src2);
2530 AbsDiff(vform, dst, temp1, temp2,
false);
2534 LogicVRegister Simulator::sabdl(VectorFormat vform, LogicVRegister dst,
2535 const LogicVRegister& src1,
2536 const LogicVRegister& src2) {
2537 SimVRegister temp1, temp2;
2538 sxtl(vform, temp1, src1);
2539 sxtl(vform, temp2, src2);
2540 AbsDiff(vform, dst, temp1, temp2,
true);
2544 LogicVRegister Simulator::sabdl2(VectorFormat vform, LogicVRegister dst,
2545 const LogicVRegister& src1,
2546 const LogicVRegister& src2) {
2547 SimVRegister temp1, temp2;
2548 sxtl2(vform, temp1, src1);
2549 sxtl2(vform, temp2, src2);
2550 AbsDiff(vform, dst, temp1, temp2,
true);
2554 LogicVRegister Simulator::umull(VectorFormat vform, LogicVRegister dst,
2555 const LogicVRegister& src1,
2556 const LogicVRegister& src2) {
2557 SimVRegister temp1, temp2;
2558 uxtl(vform, temp1, src1);
2559 uxtl(vform, temp2, src2);
2560 mul(vform, dst, temp1, temp2);
2564 LogicVRegister Simulator::umull2(VectorFormat vform, LogicVRegister dst,
2565 const LogicVRegister& src1,
2566 const LogicVRegister& src2) {
2567 SimVRegister temp1, temp2;
2568 uxtl2(vform, temp1, src1);
2569 uxtl2(vform, temp2, src2);
2570 mul(vform, dst, temp1, temp2);
2574 LogicVRegister Simulator::smull(VectorFormat vform, LogicVRegister dst,
2575 const LogicVRegister& src1,
2576 const LogicVRegister& src2) {
2577 SimVRegister temp1, temp2;
2578 sxtl(vform, temp1, src1);
2579 sxtl(vform, temp2, src2);
2580 mul(vform, dst, temp1, temp2);
2584 LogicVRegister Simulator::smull2(VectorFormat vform, LogicVRegister dst,
2585 const LogicVRegister& src1,
2586 const LogicVRegister& src2) {
2587 SimVRegister temp1, temp2;
2588 sxtl2(vform, temp1, src1);
2589 sxtl2(vform, temp2, src2);
2590 mul(vform, dst, temp1, temp2);
2594 LogicVRegister Simulator::umlsl(VectorFormat vform, LogicVRegister dst,
2595 const LogicVRegister& src1,
2596 const LogicVRegister& src2) {
2597 SimVRegister temp1, temp2;
2598 uxtl(vform, temp1, src1);
2599 uxtl(vform, temp2, src2);
2600 mls(vform, dst, temp1, temp2);
2604 LogicVRegister Simulator::umlsl2(VectorFormat vform, LogicVRegister dst,
2605 const LogicVRegister& src1,
2606 const LogicVRegister& src2) {
2607 SimVRegister temp1, temp2;
2608 uxtl2(vform, temp1, src1);
2609 uxtl2(vform, temp2, src2);
2610 mls(vform, dst, temp1, temp2);
2614 LogicVRegister Simulator::smlsl(VectorFormat vform, LogicVRegister dst,
2615 const LogicVRegister& src1,
2616 const LogicVRegister& src2) {
2617 SimVRegister temp1, temp2;
2618 sxtl(vform, temp1, src1);
2619 sxtl(vform, temp2, src2);
2620 mls(vform, dst, temp1, temp2);
2624 LogicVRegister Simulator::smlsl2(VectorFormat vform, LogicVRegister dst,
2625 const LogicVRegister& src1,
2626 const LogicVRegister& src2) {
2627 SimVRegister temp1, temp2;
2628 sxtl2(vform, temp1, src1);
2629 sxtl2(vform, temp2, src2);
2630 mls(vform, dst, temp1, temp2);
2634 LogicVRegister Simulator::umlal(VectorFormat vform, LogicVRegister dst,
2635 const LogicVRegister& src1,
2636 const LogicVRegister& src2) {
2637 SimVRegister temp1, temp2;
2638 uxtl(vform, temp1, src1);
2639 uxtl(vform, temp2, src2);
2640 mla(vform, dst, temp1, temp2);
2644 LogicVRegister Simulator::umlal2(VectorFormat vform, LogicVRegister dst,
2645 const LogicVRegister& src1,
2646 const LogicVRegister& src2) {
2647 SimVRegister temp1, temp2;
2648 uxtl2(vform, temp1, src1);
2649 uxtl2(vform, temp2, src2);
2650 mla(vform, dst, temp1, temp2);
2654 LogicVRegister Simulator::smlal(VectorFormat vform, LogicVRegister dst,
2655 const LogicVRegister& src1,
2656 const LogicVRegister& src2) {
2657 SimVRegister temp1, temp2;
2658 sxtl(vform, temp1, src1);
2659 sxtl(vform, temp2, src2);
2660 mla(vform, dst, temp1, temp2);
2664 LogicVRegister Simulator::smlal2(VectorFormat vform, LogicVRegister dst,
2665 const LogicVRegister& src1,
2666 const LogicVRegister& src2) {
2667 SimVRegister temp1, temp2;
2668 sxtl2(vform, temp1, src1);
2669 sxtl2(vform, temp2, src2);
2670 mla(vform, dst, temp1, temp2);
2674 LogicVRegister Simulator::sqdmlal(VectorFormat vform, LogicVRegister dst,
2675 const LogicVRegister& src1,
2676 const LogicVRegister& src2) {
2678 LogicVRegister product = sqdmull(vform, temp, src1, src2);
2679 return add(vform, dst, dst, product).SignedSaturate(vform);
2682 LogicVRegister Simulator::sqdmlal2(VectorFormat vform, LogicVRegister dst,
2683 const LogicVRegister& src1,
2684 const LogicVRegister& src2) {
2686 LogicVRegister product = sqdmull2(vform, temp, src1, src2);
2687 return add(vform, dst, dst, product).SignedSaturate(vform);
2690 LogicVRegister Simulator::sqdmlsl(VectorFormat vform, LogicVRegister dst,
2691 const LogicVRegister& src1,
2692 const LogicVRegister& src2) {
2694 LogicVRegister product = sqdmull(vform, temp, src1, src2);
2695 return sub(vform, dst, dst, product).SignedSaturate(vform);
2698 LogicVRegister Simulator::sqdmlsl2(VectorFormat vform, LogicVRegister dst,
2699 const LogicVRegister& src1,
2700 const LogicVRegister& src2) {
2702 LogicVRegister product = sqdmull2(vform, temp, src1, src2);
2703 return sub(vform, dst, dst, product).SignedSaturate(vform);
2706 LogicVRegister Simulator::sqdmull(VectorFormat vform, LogicVRegister dst,
2707 const LogicVRegister& src1,
2708 const LogicVRegister& src2) {
2710 LogicVRegister product = smull(vform, temp, src1, src2);
2711 return add(vform, dst, product, product).SignedSaturate(vform);
2714 LogicVRegister Simulator::sqdmull2(VectorFormat vform, LogicVRegister dst,
2715 const LogicVRegister& src1,
2716 const LogicVRegister& src2) {
2718 LogicVRegister product = smull2(vform, temp, src1, src2);
2719 return add(vform, dst, product, product).SignedSaturate(vform);
2722 LogicVRegister Simulator::sqrdmulh(VectorFormat vform, LogicVRegister dst,
2723 const LogicVRegister& src1,
2724 const LogicVRegister& src2,
bool round) {
2729 int esize = LaneSizeInBitsFromFormat(vform);
2730 int round_const = round ? (1 << (esize - 2)) : 0;
2733 dst.ClearForWrite(vform);
2734 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
2735 product = src1.Int(vform,
i) * src2.Int(vform,
i);
2736 product += round_const;
2737 product = product >> (esize - 1);
2739 if (product > MaxIntFromFormat(vform)) {
2740 product = MaxIntFromFormat(vform);
2741 }
else if (product < MinIntFromFormat(vform)) {
2742 product = MinIntFromFormat(vform);
2744 dst.SetInt(vform,
i, product);
2749 LogicVRegister Simulator::sqdmulh(VectorFormat vform, LogicVRegister dst,
2750 const LogicVRegister& src1,
2751 const LogicVRegister& src2) {
2752 return sqrdmulh(vform, dst, src1, src2,
false);
2755 LogicVRegister Simulator::addhn(VectorFormat vform, LogicVRegister dst,
2756 const LogicVRegister& src1,
2757 const LogicVRegister& src2) {
2759 add(VectorFormatDoubleWidth(vform), temp, src1, src2);
2760 shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2764 LogicVRegister Simulator::addhn2(VectorFormat vform, LogicVRegister dst,
2765 const LogicVRegister& src1,
2766 const LogicVRegister& src2) {
2768 add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
2769 shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2773 LogicVRegister Simulator::raddhn(VectorFormat vform, LogicVRegister dst,
2774 const LogicVRegister& src1,
2775 const LogicVRegister& src2) {
2777 add(VectorFormatDoubleWidth(vform), temp, src1, src2);
2778 rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2782 LogicVRegister Simulator::raddhn2(VectorFormat vform, LogicVRegister dst,
2783 const LogicVRegister& src1,
2784 const LogicVRegister& src2) {
2786 add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
2787 rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2791 LogicVRegister Simulator::subhn(VectorFormat vform, LogicVRegister dst,
2792 const LogicVRegister& src1,
2793 const LogicVRegister& src2) {
2795 sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
2796 shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2800 LogicVRegister Simulator::subhn2(VectorFormat vform, LogicVRegister dst,
2801 const LogicVRegister& src1,
2802 const LogicVRegister& src2) {
2804 sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
2805 shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2809 LogicVRegister Simulator::rsubhn(VectorFormat vform, LogicVRegister dst,
2810 const LogicVRegister& src1,
2811 const LogicVRegister& src2) {
2813 sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
2814 rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2818 LogicVRegister Simulator::rsubhn2(VectorFormat vform, LogicVRegister dst,
2819 const LogicVRegister& src1,
2820 const LogicVRegister& src2) {
2822 sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
2823 rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
2827 LogicVRegister Simulator::trn1(VectorFormat vform, LogicVRegister dst,
2828 const LogicVRegister& src1,
2829 const LogicVRegister& src2) {
2830 uint64_t result[16];
2831 int laneCount = LaneCountFromFormat(vform);
2832 int pairs = laneCount / 2;
2833 for (
int i = 0;
i < pairs; ++
i) {
2834 result[2 *
i] = src1.Uint(vform, 2 *
i);
2835 result[(2 *
i) + 1] = src2.Uint(vform, 2 *
i);
2838 dst.SetUintArray(vform, result);
2842 LogicVRegister Simulator::trn2(VectorFormat vform, LogicVRegister dst,
2843 const LogicVRegister& src1,
2844 const LogicVRegister& src2) {
2845 uint64_t result[16];
2846 int laneCount = LaneCountFromFormat(vform);
2847 int pairs = laneCount / 2;
2848 for (
int i = 0;
i < pairs; ++
i) {
2849 result[2 *
i] = src1.Uint(vform, (2 *
i) + 1);
2850 result[(2 *
i) + 1] = src2.Uint(vform, (2 *
i) + 1);
2853 dst.SetUintArray(vform, result);
2857 LogicVRegister Simulator::zip1(VectorFormat vform, LogicVRegister dst,
2858 const LogicVRegister& src1,
2859 const LogicVRegister& src2) {
2860 uint64_t result[16];
2861 int laneCount = LaneCountFromFormat(vform);
2862 int pairs = laneCount / 2;
2863 for (
int i = 0;
i < pairs; ++
i) {
2864 result[2 *
i] = src1.Uint(vform,
i);
2865 result[(2 *
i) + 1] = src2.Uint(vform,
i);
2868 dst.SetUintArray(vform, result);
2872 LogicVRegister Simulator::zip2(VectorFormat vform, LogicVRegister dst,
2873 const LogicVRegister& src1,
2874 const LogicVRegister& src2) {
2875 uint64_t result[16];
2876 int laneCount = LaneCountFromFormat(vform);
2877 int pairs = laneCount / 2;
2878 for (
int i = 0;
i < pairs; ++
i) {
2879 result[2 *
i] = src1.Uint(vform, pairs +
i);
2880 result[(2 *
i) + 1] = src2.Uint(vform, pairs +
i);
2883 dst.SetUintArray(vform, result);
2887 LogicVRegister Simulator::uzp1(VectorFormat vform, LogicVRegister dst,
2888 const LogicVRegister& src1,
2889 const LogicVRegister& src2) {
2890 uint64_t result[32];
2891 int laneCount = LaneCountFromFormat(vform);
2892 for (
int i = 0;
i < laneCount; ++
i) {
2893 result[
i] = src1.Uint(vform,
i);
2894 result[laneCount +
i] = src2.Uint(vform,
i);
2897 dst.ClearForWrite(vform);
2898 for (
int i = 0;
i < laneCount; ++
i) {
2899 dst.SetUint(vform,
i, result[2 *
i]);
2904 LogicVRegister Simulator::uzp2(VectorFormat vform, LogicVRegister dst,
2905 const LogicVRegister& src1,
2906 const LogicVRegister& src2) {
2907 uint64_t result[32];
2908 int laneCount = LaneCountFromFormat(vform);
2909 for (
int i = 0;
i < laneCount; ++
i) {
2910 result[
i] = src1.Uint(vform,
i);
2911 result[laneCount +
i] = src2.Uint(vform,
i);
2914 dst.ClearForWrite(vform);
2915 for (
int i = 0;
i < laneCount; ++
i) {
2916 dst.SetUint(vform,
i, result[(2 *
i) + 1]);
2921 template <
typename T>
2922 T Simulator::FPAdd(T op1, T op2) {
2923 T result = FPProcessNaNs(op1, op2);
2924 if (std::isnan(result))
return result;
2926 if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
2928 FPProcessException();
2929 return FPDefaultNaN<T>();
2936 template <
typename T>
2937 T Simulator::FPSub(T op1, T op2) {
2939 DCHECK(!std::isnan(op1) && !std::isnan(op2));
2941 if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
2943 FPProcessException();
2944 return FPDefaultNaN<T>();
2951 template <
typename T>
2952 T Simulator::FPMul(T op1, T op2) {
2954 DCHECK(!std::isnan(op1) && !std::isnan(op2));
2956 if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
2958 FPProcessException();
2959 return FPDefaultNaN<T>();
2966 template <
typename T>
2967 T Simulator::FPMulx(T op1, T op2) {
2968 if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
2971 return copysign(1.0, op1) * copysign(1.0, op2) * two;
2973 return FPMul(op1, op2);
2976 template <
typename T>
2977 T Simulator::FPMulAdd(T a, T op1, T op2) {
2978 T result = FPProcessNaNs3(a, op1, op2);
2980 T sign_a = copysign(1.0, a);
2981 T sign_prod = copysign(1.0, op1) * copysign(1.0, op2);
2982 bool isinf_prod = std::isinf(op1) || std::isinf(op2);
2983 bool operation_generates_nan =
2984 (std::isinf(op1) && (op2 == 0.0)) ||
2985 (std::isinf(op2) && (op1 == 0.0)) ||
2986 (std::isinf(a) && isinf_prod && (sign_a != sign_prod));
2988 if (std::isnan(result)) {
2990 if (operation_generates_nan && IsQuietNaN(a)) {
2991 FPProcessException();
2992 return FPDefaultNaN<T>();
2999 if (operation_generates_nan) {
3000 FPProcessException();
3001 return FPDefaultNaN<T>();
3006 if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
3007 return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
3010 result = FusedMultiplyAdd(op1, op2, a);
3011 DCHECK(!std::isnan(result));
3015 if ((a == 0.0) && (result == 0.0)) {
3016 return copysign(0.0, sign_prod);
3022 template <
typename T>
3023 T Simulator::FPDiv(T op1, T op2) {
3025 DCHECK(!std::isnan(op1) && !std::isnan(op2));
3027 if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
3029 FPProcessException();
3030 return FPDefaultNaN<T>();
3033 FPProcessException();
3034 if (!std::isnan(op1)) {
3035 double op1_sign = copysign(1.0, op1);
3036 double op2_sign = copysign(1.0, op2);
3037 return static_cast<T
>(op1_sign * op2_sign * kFP64PositiveInfinity);
3046 template <
typename T>
3047 T Simulator::FPSqrt(T op) {
3048 if (std::isnan(op)) {
3049 return FPProcessNaN(op);
3050 }
else if (op < 0.0) {
3051 FPProcessException();
3052 return FPDefaultNaN<T>();
3058 template <
typename T>
3059 T Simulator::FPMax(T a, T b) {
3060 T result = FPProcessNaNs(a, b);
3061 if (std::isnan(result))
return result;
3063 if ((a == 0.0) && (b == 0.0) && (copysign(1.0, a) != copysign(1.0, b))) {
3067 return (a > b) ? a : b;
3071 template <
typename T>
3072 T Simulator::FPMaxNM(T a, T b) {
3073 if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3074 a = kFP64NegativeInfinity;
3075 }
else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3076 b = kFP64NegativeInfinity;
3079 T result = FPProcessNaNs(a, b);
3080 return std::isnan(result) ? result : FPMax(a, b);
3083 template <
typename T>
3084 T Simulator::FPMin(T a, T b) {
3085 T result = FPProcessNaNs(a, b);
3086 if (std::isnan(result))
return result;
3088 if ((a == 0.0) && (b == 0.0) && (copysign(1.0, a) != copysign(1.0, b))) {
3092 return (a < b) ? a : b;
3096 template <
typename T>
3097 T Simulator::FPMinNM(T a, T b) {
3098 if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3099 a = kFP64PositiveInfinity;
3100 }
else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3101 b = kFP64PositiveInfinity;
3104 T result = FPProcessNaNs(a, b);
3105 return std::isnan(result) ? result : FPMin(a, b);
3108 template <
typename T>
3109 T Simulator::FPRecipStepFused(T op1, T op2) {
3111 if ((std::isinf(op1) && (op2 == 0.0)) ||
3112 ((op1 == 0.0) && (std::isinf(op2)))) {
3114 }
else if (std::isinf(op1) || std::isinf(op2)) {
3116 return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
3117 : kFP64NegativeInfinity;
3119 return FusedMultiplyAdd(op1, op2, two);
3123 template <
typename T>
3124 T Simulator::FPRSqrtStepFused(T op1, T op2) {
3125 const T one_point_five = 1.5;
3128 if ((std::isinf(op1) && (op2 == 0.0)) ||
3129 ((op1 == 0.0) && (std::isinf(op2)))) {
3130 return one_point_five;
3131 }
else if (std::isinf(op1) || std::isinf(op2)) {
3133 return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
3134 : kFP64NegativeInfinity;
3139 if (std::isnormal(op1 / two)) {
3140 return FusedMultiplyAdd(op1 / two, op2, one_point_five);
3141 }
else if (std::isnormal(op2 / two)) {
3142 return FusedMultiplyAdd(op1, op2 / two, one_point_five);
3146 return one_point_five;
3151 double Simulator::FPRoundInt(
double value, FPRounding round_mode) {
3152 if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
3153 (value == kFP64NegativeInfinity)) {
3155 }
else if (std::isnan(value)) {
3156 return FPProcessNaN(value);
3159 double int_result = std::floor(value);
3160 double error = value - int_result;
3161 switch (round_mode) {
3165 if ((-0.5 < value) && (value < 0.0)) {
3168 }
else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
3178 if ((-0.5 <= value) && (value < 0.0)) {
3183 }
else if ((error > 0.5) ||
3184 ((error == 0.5) && (std::fmod(int_result, 2) != 0))) {
3193 int_result = ceil(value);
3197 case FPNegativeInfinity: {
3201 case FPPositiveInfinity: {
3204 if ((-1.0 < value) && (value < 0.0)) {
3208 }
else if (error > 0.0) {
3219 int32_t Simulator::FPToInt32(
double value, FPRounding rmode) {
3220 value = FPRoundInt(value, rmode);
3221 if (value >= kWMaxInt) {
3223 }
else if (value < kWMinInt) {
3226 return std::isnan(value) ? 0 :
static_cast<int32_t
>(value);
3229 int64_t Simulator::FPToInt64(
double value, FPRounding rmode) {
3230 value = FPRoundInt(value, rmode);
3231 if (value >= kXMaxInt) {
3233 }
else if (value < kXMinInt) {
3236 return std::isnan(value) ? 0 :
static_cast<int64_t>(value);
3239 uint32_t Simulator::FPToUInt32(
double value, FPRounding rmode) {
3240 value = FPRoundInt(value, rmode);
3241 if (value >= kWMaxUInt) {
3243 }
else if (value < 0.0) {
3246 return std::isnan(value) ? 0 :
static_cast<uint32_t>(value);
3249 uint64_t Simulator::FPToUInt64(
double value, FPRounding rmode) {
3250 value = FPRoundInt(value, rmode);
3251 if (value >= kXMaxUInt) {
3253 }
else if (value < 0.0) {
3256 return std::isnan(value) ? 0 :
static_cast<uint64_t
>(value);
3259 #define DEFINE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \ 3260 template <typename T> \ 3261 LogicVRegister Simulator::FN(VectorFormat vform, LogicVRegister dst, \ 3262 const LogicVRegister& src1, \ 3263 const LogicVRegister& src2) { \ 3264 dst.ClearForWrite(vform); \ 3265 for (int i = 0; i < LaneCountFromFormat(vform); i++) { \ 3266 T op1 = src1.Float<T>(i); \ 3267 T op2 = src2.Float<T>(i); \ 3270 result = FPProcessNaNs(op1, op2); \ 3271 if (!std::isnan(result)) { \ 3272 result = OP(op1, op2); \ 3275 result = OP(op1, op2); \ 3277 dst.SetFloat(i, result); \ 3282 LogicVRegister Simulator::FN(VectorFormat vform, LogicVRegister dst, \ 3283 const LogicVRegister& src1, \ 3284 const LogicVRegister& src2) { \ 3285 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) { \ 3286 FN<float>(vform, dst, src1, src2); \ 3288 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize); \ 3289 FN<double>(vform, dst, src1, src2); \ 3293 NEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)
3294 #undef DEFINE_NEON_FP_VECTOR_OP 3296 LogicVRegister Simulator::fnmul(VectorFormat vform, LogicVRegister dst,
3297 const LogicVRegister& src1,
3298 const LogicVRegister& src2) {
3300 LogicVRegister product = fmul(vform, temp, src1, src2);
3301 return fneg(vform, dst, product);
3304 template <
typename T>
3305 LogicVRegister Simulator::frecps(VectorFormat vform, LogicVRegister dst,
3306 const LogicVRegister& src1,
3307 const LogicVRegister& src2) {
3308 dst.ClearForWrite(vform);
3309 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3310 T op1 = -src1.Float<T>(
i);
3311 T op2 = src2.Float<T>(
i);
3312 T result = FPProcessNaNs(op1, op2);
3313 dst.SetFloat(
i, std::isnan(result) ? result : FPRecipStepFused(op1, op2));
3318 LogicVRegister Simulator::frecps(VectorFormat vform, LogicVRegister dst,
3319 const LogicVRegister& src1,
3320 const LogicVRegister& src2) {
3321 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3322 frecps<float>(vform, dst, src1, src2);
3324 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3325 frecps<double>(vform, dst, src1, src2);
3330 template <
typename T>
3331 LogicVRegister Simulator::frsqrts(VectorFormat vform, LogicVRegister dst,
3332 const LogicVRegister& src1,
3333 const LogicVRegister& src2) {
3334 dst.ClearForWrite(vform);
3335 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3336 T op1 = -src1.Float<T>(
i);
3337 T op2 = src2.Float<T>(
i);
3338 T result = FPProcessNaNs(op1, op2);
3339 dst.SetFloat(
i, std::isnan(result) ? result : FPRSqrtStepFused(op1, op2));
3344 LogicVRegister Simulator::frsqrts(VectorFormat vform, LogicVRegister dst,
3345 const LogicVRegister& src1,
3346 const LogicVRegister& src2) {
3347 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3348 frsqrts<float>(vform, dst, src1, src2);
3350 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3351 frsqrts<double>(vform, dst, src1, src2);
3356 template <
typename T>
3357 LogicVRegister Simulator::fcmp(VectorFormat vform, LogicVRegister dst,
3358 const LogicVRegister& src1,
3359 const LogicVRegister& src2, Condition cond) {
3360 dst.ClearForWrite(vform);
3361 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3362 bool result =
false;
3363 T op1 = src1.Float<T>(
i);
3364 T op2 = src2.Float<T>(
i);
3365 T nan_result = FPProcessNaNs(op1, op2);
3366 if (!std::isnan(nan_result)) {
3369 result = (op1 == op2);
3372 result = (op1 >= op2);
3375 result = (op1 > op2);
3378 result = (op1 <= op2);
3381 result = (op1 < op2);
3387 dst.SetUint(vform,
i, result ? MaxUintFromFormat(vform) : 0);
3392 LogicVRegister Simulator::fcmp(VectorFormat vform, LogicVRegister dst,
3393 const LogicVRegister& src1,
3394 const LogicVRegister& src2, Condition cond) {
3395 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3396 fcmp<float>(vform, dst, src1, src2, cond);
3398 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3399 fcmp<double>(vform, dst, src1, src2, cond);
3404 LogicVRegister Simulator::fcmp_zero(VectorFormat vform, LogicVRegister dst,
3405 const LogicVRegister& src, Condition cond) {
3407 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3408 LogicVRegister zero_reg =
3409 dup_immediate(vform, temp, bit_cast<uint32_t>(0.0f));
3410 fcmp<float>(vform, dst, src, zero_reg, cond);
3412 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3413 LogicVRegister zero_reg =
3414 dup_immediate(vform, temp, bit_cast<uint64_t>(0.0));
3415 fcmp<double>(vform, dst, src, zero_reg, cond);
3420 LogicVRegister Simulator::fabscmp(VectorFormat vform, LogicVRegister dst,
3421 const LogicVRegister& src1,
3422 const LogicVRegister& src2, Condition cond) {
3423 SimVRegister temp1, temp2;
3424 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3425 LogicVRegister abs_src1 = fabs_<float>(vform, temp1, src1);
3426 LogicVRegister abs_src2 = fabs_<float>(vform, temp2, src2);
3427 fcmp<float>(vform, dst, abs_src1, abs_src2, cond);
3429 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3430 LogicVRegister abs_src1 = fabs_<double>(vform, temp1, src1);
3431 LogicVRegister abs_src2 = fabs_<double>(vform, temp2, src2);
3432 fcmp<double>(vform, dst, abs_src1, abs_src2, cond);
3437 template <
typename T>
3438 LogicVRegister Simulator::fmla(VectorFormat vform, LogicVRegister dst,
3439 const LogicVRegister& src1,
3440 const LogicVRegister& src2) {
3441 dst.ClearForWrite(vform);
3442 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3443 T op1 = src1.Float<T>(
i);
3444 T op2 = src2.Float<T>(
i);
3445 T acc = dst.Float<T>(
i);
3446 T result = FPMulAdd(acc, op1, op2);
3447 dst.SetFloat(
i, result);
3452 LogicVRegister Simulator::fmla(VectorFormat vform, LogicVRegister dst,
3453 const LogicVRegister& src1,
3454 const LogicVRegister& src2) {
3455 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3456 fmla<float>(vform, dst, src1, src2);
3458 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3459 fmla<double>(vform, dst, src1, src2);
3464 template <
typename T>
3465 LogicVRegister Simulator::fmls(VectorFormat vform, LogicVRegister dst,
3466 const LogicVRegister& src1,
3467 const LogicVRegister& src2) {
3468 dst.ClearForWrite(vform);
3469 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3470 T op1 = -src1.Float<T>(
i);
3471 T op2 = src2.Float<T>(
i);
3472 T acc = dst.Float<T>(
i);
3473 T result = FPMulAdd(acc, op1, op2);
3474 dst.SetFloat(
i, result);
3479 LogicVRegister Simulator::fmls(VectorFormat vform, LogicVRegister dst,
3480 const LogicVRegister& src1,
3481 const LogicVRegister& src2) {
3482 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3483 fmls<float>(vform, dst, src1, src2);
3485 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3486 fmls<double>(vform, dst, src1, src2);
3491 template <
typename T>
3492 LogicVRegister Simulator::fneg(VectorFormat vform, LogicVRegister dst,
3493 const LogicVRegister& src) {
3494 dst.ClearForWrite(vform);
3495 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3496 T op = src.Float<T>(
i);
3498 dst.SetFloat(
i, op);
3503 LogicVRegister Simulator::fneg(VectorFormat vform, LogicVRegister dst,
3504 const LogicVRegister& src) {
3505 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3506 fneg<float>(vform, dst, src);
3508 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3509 fneg<double>(vform, dst, src);
3514 template <
typename T>
3515 LogicVRegister Simulator::fabs_(VectorFormat vform, LogicVRegister dst,
3516 const LogicVRegister& src) {
3517 dst.ClearForWrite(vform);
3518 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3519 T op = src.Float<T>(
i);
3520 if (copysign(1.0, op) < 0.0) {
3523 dst.SetFloat(
i, op);
3528 LogicVRegister Simulator::fabs_(VectorFormat vform, LogicVRegister dst,
3529 const LogicVRegister& src) {
3530 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3531 fabs_<float>(vform, dst, src);
3533 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3534 fabs_<double>(vform, dst, src);
3539 LogicVRegister Simulator::fabd(VectorFormat vform, LogicVRegister dst,
3540 const LogicVRegister& src1,
3541 const LogicVRegister& src2) {
3543 fsub(vform, temp, src1, src2);
3544 fabs_(vform, dst, temp);
3548 LogicVRegister Simulator::fsqrt(VectorFormat vform, LogicVRegister dst,
3549 const LogicVRegister& src) {
3550 dst.ClearForWrite(vform);
3551 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3552 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3553 float result = FPSqrt(src.Float<
float>(
i));
3554 dst.SetFloat(
i, result);
3557 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3558 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3559 double result = FPSqrt(src.Float<
double>(
i));
3560 dst.SetFloat(
i, result);
3566 #define DEFINE_NEON_FP_PAIR_OP(FNP, FN, OP) \ 3567 LogicVRegister Simulator::FNP(VectorFormat vform, LogicVRegister dst, \ 3568 const LogicVRegister& src1, \ 3569 const LogicVRegister& src2) { \ 3570 SimVRegister temp1, temp2; \ 3571 uzp1(vform, temp1, src1, src2); \ 3572 uzp2(vform, temp2, src1, src2); \ 3573 FN(vform, dst, temp1, temp2); \ 3577 LogicVRegister Simulator::FNP(VectorFormat vform, LogicVRegister dst, \ 3578 const LogicVRegister& src) { \ 3579 if (vform == kFormatS) { \ 3580 float result = OP(src.Float<float>(0), src.Float<float>(1)); \ 3581 dst.SetFloat(0, result); \ 3583 DCHECK_EQ(vform, kFormatD); \ 3584 double result = OP(src.Float<double>(0), src.Float<double>(1)); \ 3585 dst.SetFloat(0, result); \ 3587 dst.ClearForWrite(vform); \ 3590 NEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)
3591 #undef DEFINE_NEON_FP_PAIR_OP 3593 LogicVRegister Simulator::FMinMaxV(VectorFormat vform, LogicVRegister dst,
3594 const LogicVRegister& src, FPMinMaxOp Op) {
3595 DCHECK_EQ(vform, kFormat4S);
3597 float result1 = (this->*Op)(src.Float<
float>(0), src.Float<
float>(1));
3598 float result2 = (this->*Op)(src.Float<
float>(2), src.Float<
float>(3));
3599 float result = (this->*Op)(result1, result2);
3600 dst.ClearForWrite(kFormatS);
3601 dst.SetFloat<
float>(0, result);
3605 LogicVRegister Simulator::fmaxv(VectorFormat vform, LogicVRegister dst,
3606 const LogicVRegister& src) {
3607 return FMinMaxV(vform, dst, src, &Simulator::FPMax);
3610 LogicVRegister Simulator::fminv(VectorFormat vform, LogicVRegister dst,
3611 const LogicVRegister& src) {
3612 return FMinMaxV(vform, dst, src, &Simulator::FPMin);
3615 LogicVRegister Simulator::fmaxnmv(VectorFormat vform, LogicVRegister dst,
3616 const LogicVRegister& src) {
3617 return FMinMaxV(vform, dst, src, &Simulator::FPMaxNM);
3620 LogicVRegister Simulator::fminnmv(VectorFormat vform, LogicVRegister dst,
3621 const LogicVRegister& src) {
3622 return FMinMaxV(vform, dst, src, &Simulator::FPMinNM);
3625 LogicVRegister Simulator::fmul(VectorFormat vform, LogicVRegister dst,
3626 const LogicVRegister& src1,
3627 const LogicVRegister& src2,
int index) {
3628 dst.ClearForWrite(vform);
3630 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3631 LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
3632 fmul<float>(vform, dst, src1, index_reg);
3634 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3635 LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
3636 fmul<double>(vform, dst, src1, index_reg);
3641 LogicVRegister Simulator::fmla(VectorFormat vform, LogicVRegister dst,
3642 const LogicVRegister& src1,
3643 const LogicVRegister& src2,
int index) {
3644 dst.ClearForWrite(vform);
3646 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3647 LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
3648 fmla<float>(vform, dst, src1, index_reg);
3650 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3651 LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
3652 fmla<double>(vform, dst, src1, index_reg);
3657 LogicVRegister Simulator::fmls(VectorFormat vform, LogicVRegister dst,
3658 const LogicVRegister& src1,
3659 const LogicVRegister& src2,
int index) {
3660 dst.ClearForWrite(vform);
3662 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3663 LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
3664 fmls<float>(vform, dst, src1, index_reg);
3666 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3667 LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
3668 fmls<double>(vform, dst, src1, index_reg);
3673 LogicVRegister Simulator::fmulx(VectorFormat vform, LogicVRegister dst,
3674 const LogicVRegister& src1,
3675 const LogicVRegister& src2,
int index) {
3676 dst.ClearForWrite(vform);
3678 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3679 LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
3680 fmulx<float>(vform, dst, src1, index_reg);
3683 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3684 LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
3685 fmulx<double>(vform, dst, src1, index_reg);
3690 LogicVRegister Simulator::frint(VectorFormat vform, LogicVRegister dst,
3691 const LogicVRegister& src,
3692 FPRounding rounding_mode,
3693 bool inexact_exception) {
3694 dst.ClearForWrite(vform);
3695 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3696 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3697 float input = src.Float<
float>(
i);
3698 float rounded = FPRoundInt(input, rounding_mode);
3699 if (inexact_exception && !std::isnan(input) && (input != rounded)) {
3700 FPProcessException();
3702 dst.SetFloat<
float>(
i, rounded);
3705 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3706 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3707 double input = src.Float<
double>(
i);
3708 double rounded = FPRoundInt(input, rounding_mode);
3709 if (inexact_exception && !std::isnan(input) && (input != rounded)) {
3710 FPProcessException();
3712 dst.SetFloat<
double>(
i, rounded);
3718 LogicVRegister Simulator::fcvts(VectorFormat vform, LogicVRegister dst,
3719 const LogicVRegister& src,
3720 FPRounding rounding_mode,
int fbits) {
3721 dst.ClearForWrite(vform);
3722 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3723 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3724 float op = src.Float<
float>(
i) * std::pow(2.0f, fbits);
3725 dst.SetInt(vform,
i, FPToInt32(op, rounding_mode));
3728 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3729 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3730 double op = src.Float<
double>(
i) * std::pow(2.0, fbits);
3731 dst.SetInt(vform,
i, FPToInt64(op, rounding_mode));
3737 LogicVRegister Simulator::fcvtu(VectorFormat vform, LogicVRegister dst,
3738 const LogicVRegister& src,
3739 FPRounding rounding_mode,
int fbits) {
3740 dst.ClearForWrite(vform);
3741 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3742 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3743 float op = src.Float<
float>(
i) * std::pow(2.0f, fbits);
3744 dst.SetUint(vform,
i, FPToUInt32(op, rounding_mode));
3747 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3748 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3749 double op = src.Float<
double>(
i) * std::pow(2.0, fbits);
3750 dst.SetUint(vform,
i, FPToUInt64(op, rounding_mode));
3756 LogicVRegister Simulator::fcvtl(VectorFormat vform, LogicVRegister dst,
3757 const LogicVRegister& src) {
3758 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3759 for (
int i = LaneCountFromFormat(vform) - 1;
i >= 0;
i--) {
3760 dst.SetFloat(
i, FPToFloat(src.Float<float16>(
i)));
3763 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3764 for (
int i = LaneCountFromFormat(vform) - 1;
i >= 0;
i--) {
3765 dst.SetFloat(
i, FPToDouble(src.Float<
float>(
i)));
3771 LogicVRegister Simulator::fcvtl2(VectorFormat vform, LogicVRegister dst,
3772 const LogicVRegister& src) {
3773 int lane_count = LaneCountFromFormat(vform);
3774 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3775 for (
int i = 0;
i < lane_count;
i++) {
3776 dst.SetFloat(
i, FPToFloat(src.Float<float16>(
i + lane_count)));
3779 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3780 for (
int i = 0;
i < lane_count;
i++) {
3781 dst.SetFloat(
i, FPToDouble(src.Float<
float>(
i + lane_count)));
3787 LogicVRegister Simulator::fcvtn(VectorFormat vform, LogicVRegister dst,
3788 const LogicVRegister& src) {
3789 if (LaneSizeInBytesFromFormat(vform) == kHRegSize) {
3790 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3791 dst.SetFloat(
i, FPToFloat16(src.Float<
float>(
i), FPTieEven));
3794 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kSRegSize);
3795 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3796 dst.SetFloat(
i, FPToFloat(src.Float<
double>(
i), FPTieEven));
3802 LogicVRegister Simulator::fcvtn2(VectorFormat vform, LogicVRegister dst,
3803 const LogicVRegister& src) {
3804 int lane_count = LaneCountFromFormat(vform) / 2;
3805 if (LaneSizeInBytesFromFormat(vform) == kHRegSize) {
3806 for (
int i = lane_count - 1;
i >= 0;
i--) {
3807 dst.SetFloat(
i + lane_count, FPToFloat16(src.Float<
float>(
i), FPTieEven));
3810 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kSRegSize);
3811 for (
int i = lane_count - 1;
i >= 0;
i--) {
3812 dst.SetFloat(
i + lane_count, FPToFloat(src.Float<
double>(
i), FPTieEven));
3818 LogicVRegister Simulator::fcvtxn(VectorFormat vform, LogicVRegister dst,
3819 const LogicVRegister& src) {
3820 dst.ClearForWrite(vform);
3821 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kSRegSize);
3822 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3823 dst.SetFloat(
i, FPToFloat(src.Float<
double>(
i), FPRoundOdd));
3828 LogicVRegister Simulator::fcvtxn2(VectorFormat vform, LogicVRegister dst,
3829 const LogicVRegister& src) {
3830 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kSRegSize);
3831 int lane_count = LaneCountFromFormat(vform) / 2;
3832 for (
int i = lane_count - 1;
i >= 0;
i--) {
3833 dst.SetFloat(
i + lane_count, FPToFloat(src.Float<
double>(
i), FPRoundOdd));
3839 double Simulator::recip_sqrt_estimate(
double a) {
3843 q0 =
static_cast<int>(a * 512.0);
3844 r = 1.0 / sqrt((static_cast<double>(q0) + 0.5) / 512.0);
3846 q1 =
static_cast<int>(a * 256.0);
3847 r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0);
3849 s =
static_cast<int>(256.0 * r + 0.5);
3850 return static_cast<double>(s) / 256.0;
3855 inline uint64_t Bits(uint64_t val,
int start_bit,
int end_bit) {
3856 return unsigned_bitextract_64(start_bit, end_bit, val);
3861 template <
typename T>
3862 T Simulator::FPRecipSqrtEstimate(T op) {
3863 static_assert(std::is_same<float, T>::value || std::is_same<double, T>::value,
3864 "T must be a float or double");
3866 if (std::isnan(op)) {
3867 return FPProcessNaN(op);
3868 }
else if (op == 0.0) {
3869 if (copysign(1.0, op) < 0.0) {
3870 return kFP64NegativeInfinity;
3872 return kFP64PositiveInfinity;
3874 }
else if (copysign(1.0, op) < 0.0) {
3875 FPProcessException();
3876 return FPDefaultNaN<T>();
3877 }
else if (std::isinf(op)) {
3881 int32_t exp, result_exp;
3883 if (
sizeof(T) ==
sizeof(float)) {
3884 exp =
static_cast<int32_t
>(float_exp(op));
3885 fraction = float_mantissa(op);
3888 exp =
static_cast<int32_t
>(double_exp(op));
3889 fraction = double_mantissa(op);
3893 while (Bits(fraction, 51, 51) == 0) {
3894 fraction = Bits(fraction, 50, 0) << 1;
3897 fraction = Bits(fraction, 50, 0) << 1;
3901 if (Bits(exp, 0, 0) == 0) {
3902 scaled = double_pack(0, 1022, Bits(fraction, 51, 44) << 44);
3904 scaled = double_pack(0, 1021, Bits(fraction, 51, 44) << 44);
3907 if (
sizeof(T) ==
sizeof(
float)) {
3908 result_exp = (380 - exp) / 2;
3910 result_exp = (3068 - exp) / 2;
3913 uint64_t estimate = bit_cast<uint64_t>(recip_sqrt_estimate(scaled));
3915 if (
sizeof(T) ==
sizeof(float)) {
3918 return float_pack(0, exp_bits, est_bits);
3920 return double_pack(0, Bits(result_exp, 10, 0), Bits(estimate, 51, 0));
3925 LogicVRegister Simulator::frsqrte(VectorFormat vform, LogicVRegister dst,
3926 const LogicVRegister& src) {
3927 dst.ClearForWrite(vform);
3928 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
3929 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3930 float input = src.Float<
float>(
i);
3931 dst.SetFloat(
i, FPRecipSqrtEstimate<float>(input));
3934 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
3935 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
3936 double input = src.Float<
double>(
i);
3937 dst.SetFloat(
i, FPRecipSqrtEstimate<double>(input));
3943 template <
typename T>
3944 T Simulator::FPRecipEstimate(T op, FPRounding rounding) {
3945 static_assert(std::is_same<float, T>::value || std::is_same<double, T>::value,
3946 "T must be a float or double");
3949 if (
sizeof(T) ==
sizeof(
float)) {
3950 sign = float_sign(op);
3952 sign = double_sign(op);
3955 if (std::isnan(op)) {
3956 return FPProcessNaN(op);
3957 }
else if (std::isinf(op)) {
3958 return (sign == 1) ? -0.0 : 0.0;
3959 }
else if (op == 0.0) {
3960 FPProcessException();
3961 return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
3962 }
else if (((
sizeof(T) ==
sizeof(
float)) &&
3963 (std::fabs(op) < std::pow(2.0, -128.0))) ||
3964 ((
sizeof(T) ==
sizeof(
double)) &&
3965 (std::fabs(op) < std::pow(2.0, -1024.0)))) {
3966 bool overflow_to_inf =
false;
3969 overflow_to_inf =
true;
3971 case FPPositiveInfinity:
3972 overflow_to_inf = (sign == 0);
3974 case FPNegativeInfinity:
3975 overflow_to_inf = (sign == 1);
3978 overflow_to_inf =
false;
3983 FPProcessException();
3984 if (overflow_to_inf) {
3985 return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
3988 if (
sizeof(T) ==
sizeof(
float)) {
3989 return float_pack(sign, 0xFE, 0x07FFFFF);
3991 return double_pack(sign, 0x7FE, 0x0FFFFFFFFFFFFFl);
3996 int32_t exp, result_exp;
3999 if (
sizeof(T) ==
sizeof(
float)) {
4000 sign = float_sign(op);
4001 exp =
static_cast<int32_t
>(float_exp(op));
4002 fraction = float_mantissa(op);
4005 sign = double_sign(op);
4006 exp =
static_cast<int32_t
>(double_exp(op));
4007 fraction = double_mantissa(op);
4011 if (Bits(fraction, 51, 51) == 0) {
4013 fraction = Bits(fraction, 49, 0) << 2;
4015 fraction = Bits(fraction, 50, 0) << 1;
4019 double scaled = double_pack(0, 1022, Bits(fraction, 51, 44) << 44);
4021 if (
sizeof(T) ==
sizeof(
float)) {
4022 result_exp = 253 - exp;
4024 result_exp = 2045 - exp;
4027 double estimate = recip_estimate(scaled);
4029 fraction = double_mantissa(estimate);
4030 if (result_exp == 0) {
4031 fraction = (UINT64_C(1) << 51) | Bits(fraction, 51, 1);
4032 }
else if (result_exp == -1) {
4033 fraction = (UINT64_C(1) << 50) | Bits(fraction, 51, 2);
4036 if (
sizeof(T) ==
sizeof(float)) {
4039 return float_pack(sign, exp_bits, frac_bits);
4041 return double_pack(sign, Bits(result_exp, 10, 0), Bits(fraction, 51, 0));
4046 LogicVRegister Simulator::frecpe(VectorFormat vform, LogicVRegister dst,
4047 const LogicVRegister& src, FPRounding round) {
4048 dst.ClearForWrite(vform);
4049 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
4050 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4051 float input = src.Float<
float>(
i);
4052 dst.SetFloat(
i, FPRecipEstimate<float>(input, round));
4055 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
4056 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4057 double input = src.Float<
double>(
i);
4058 dst.SetFloat(
i, FPRecipEstimate<double>(input, round));
4064 LogicVRegister Simulator::ursqrte(VectorFormat vform, LogicVRegister dst,
4065 const LogicVRegister& src) {
4066 dst.ClearForWrite(vform);
4069 double dp_operand, dp_result;
4070 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4071 operand = src.Uint(vform,
i);
4072 if (operand <= 0x3FFFFFFF) {
4073 result = 0xFFFFFFFF;
4075 dp_operand = operand * std::pow(2.0, -32);
4076 dp_result = recip_sqrt_estimate(dp_operand) * std::pow(2.0, 31);
4077 result =
static_cast<uint32_t>(dp_result);
4079 dst.SetUint(vform,
i, result);
4085 double Simulator::recip_estimate(
double a) {
4088 q =
static_cast<int>(a * 512.0);
4089 r = 1.0 / ((
static_cast<double>(q) + 0.5) / 512.0);
4090 s =
static_cast<int>(256.0 * r + 0.5);
4091 return static_cast<double>(s) / 256.0;
4094 LogicVRegister Simulator::urecpe(VectorFormat vform, LogicVRegister dst,
4095 const LogicVRegister& src) {
4096 dst.ClearForWrite(vform);
4099 double dp_operand, dp_result;
4100 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4101 operand = src.Uint(vform,
i);
4102 if (operand <= 0x7FFFFFFF) {
4103 result = 0xFFFFFFFF;
4105 dp_operand = operand * std::pow(2.0, -32);
4106 dp_result = recip_estimate(dp_operand) * std::pow(2.0, 31);
4107 result =
static_cast<uint32_t>(dp_result);
4109 dst.SetUint(vform,
i, result);
4114 template <
typename T>
4115 LogicVRegister Simulator::frecpx(VectorFormat vform, LogicVRegister dst,
4116 const LogicVRegister& src) {
4117 dst.ClearForWrite(vform);
4118 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4119 T op = src.Float<T>(
i);
4121 if (std::isnan(op)) {
4122 result = FPProcessNaN(op);
4126 if (
sizeof(T) ==
sizeof(
float)) {
4127 sign = float_sign(op);
4128 exp =
static_cast<int>(float_exp(op));
4129 exp = (exp == 0) ? (0xFF - 1) :
static_cast<int>(Bits(~exp, 7, 0));
4130 result = float_pack(sign, exp, 0);
4132 sign = double_sign(op);
4133 exp =
static_cast<int>(double_exp(op));
4134 exp = (exp == 0) ? (0x7FF - 1) :
static_cast<int>(Bits(~exp, 10, 0));
4135 result = double_pack(sign, exp, 0);
4138 dst.SetFloat(
i, result);
4143 LogicVRegister Simulator::frecpx(VectorFormat vform, LogicVRegister dst,
4144 const LogicVRegister& src) {
4145 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
4146 frecpx<float>(vform, dst, src);
4148 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
4149 frecpx<double>(vform, dst, src);
4154 LogicVRegister Simulator::scvtf(VectorFormat vform, LogicVRegister dst,
4155 const LogicVRegister& src,
int fbits,
4157 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4158 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
4159 float result = FixedToFloat(src.Int(kFormatS,
i), fbits, round);
4160 dst.SetFloat<
float>(
i, result);
4162 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
4163 double result = FixedToDouble(src.Int(kFormatD,
i), fbits, round);
4164 dst.SetFloat<
double>(
i, result);
4170 LogicVRegister Simulator::ucvtf(VectorFormat vform, LogicVRegister dst,
4171 const LogicVRegister& src,
int fbits,
4173 for (
int i = 0;
i < LaneCountFromFormat(vform);
i++) {
4174 if (LaneSizeInBytesFromFormat(vform) == kSRegSize) {
4175 float result = UFixedToFloat(src.Uint(kFormatS,
i), fbits, round);
4176 dst.SetFloat<
float>(
i, result);
4178 DCHECK_EQ(LaneSizeInBytesFromFormat(vform), kDRegSize);
4179 double result = UFixedToDouble(src.Uint(kFormatD,
i), fbits, round);
4180 dst.SetFloat<
double>(
i, result);
4186 #endif // USE_SIMULATOR 4191 #endif // V8_TARGET_ARCH_ARM64