Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:51:41

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2018 Wave Computing, Inc.
0005 // Written by:
0006 //   Chris Larsen
0007 //   Alexey Frunze (afrunze@wavecomp.com)
0008 //
0009 // This Source Code Form is subject to the terms of the Mozilla
0010 // Public License v. 2.0. If a copy of the MPL was not distributed
0011 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0012 
0013 #ifndef EIGEN_COMPLEX_MSA_H
0014 #define EIGEN_COMPLEX_MSA_H
0015 
0016 #include <iostream>
0017 
0018 namespace Eigen {
0019 
0020 namespace internal {
0021 
0022 //---------- float ----------
0023 struct Packet2cf {
0024   EIGEN_STRONG_INLINE Packet2cf() {
0025   }
0026   EIGEN_STRONG_INLINE explicit Packet2cf(const std::complex<float>& a,
0027                                          const std::complex<float>& b) {
0028     Packet4f t = { std::real(a), std::imag(a), std::real(b), std::imag(b) };
0029     v = t;
0030   }
0031   EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {
0032   }
0033   EIGEN_STRONG_INLINE Packet2cf(const Packet2cf& a) : v(a.v) {
0034   }
0035   EIGEN_STRONG_INLINE Packet2cf& operator=(const Packet2cf& b) {
0036     v = b.v;
0037     return *this;
0038   }
0039   EIGEN_STRONG_INLINE Packet2cf conjugate(void) const {
0040     return Packet2cf((Packet4f)__builtin_msa_bnegi_d((v2u64)v, 63));
0041   }
0042   EIGEN_STRONG_INLINE Packet2cf& operator*=(const Packet2cf& b) {
0043     Packet4f v1, v2;
0044 
0045     // Get the real values of a | a1_re | a1_re | a2_re | a2_re |
0046     v1 = (Packet4f)__builtin_msa_ilvev_w((v4i32)v, (v4i32)v);
0047     // Get the imag values of a | a1_im | a1_im | a2_im | a2_im |
0048     v2 = (Packet4f)__builtin_msa_ilvod_w((v4i32)v, (v4i32)v);
0049     // Multiply the real a with b
0050     v1 = pmul(v1, b.v);
0051     // Multiply the imag a with b
0052     v2 = pmul(v2, b.v);
0053     // Conjugate v2
0054     v2 = Packet2cf(v2).conjugate().v;
0055     // Swap real/imag elements in v2.
0056     v2 = (Packet4f)__builtin_msa_shf_w((v4i32)v2, EIGEN_MSA_SHF_I8(1, 0, 3, 2));
0057     // Add and return the result
0058     v = padd(v1, v2);
0059     return *this;
0060   }
0061   EIGEN_STRONG_INLINE Packet2cf operator*(const Packet2cf& b) const {
0062     return Packet2cf(*this) *= b;
0063   }
0064   EIGEN_STRONG_INLINE Packet2cf& operator+=(const Packet2cf& b) {
0065     v = padd(v, b.v);
0066     return *this;
0067   }
0068   EIGEN_STRONG_INLINE Packet2cf operator+(const Packet2cf& b) const {
0069     return Packet2cf(*this) += b;
0070   }
0071   EIGEN_STRONG_INLINE Packet2cf& operator-=(const Packet2cf& b) {
0072     v = psub(v, b.v);
0073     return *this;
0074   }
0075   EIGEN_STRONG_INLINE Packet2cf operator-(const Packet2cf& b) const {
0076     return Packet2cf(*this) -= b;
0077   }
0078   EIGEN_STRONG_INLINE Packet2cf& operator/=(const Packet2cf& b) {
0079     *this *= b.conjugate();
0080     Packet4f s = pmul<Packet4f>(b.v, b.v);
0081     s = padd(s, (Packet4f)__builtin_msa_shf_w((v4i32)s, EIGEN_MSA_SHF_I8(1, 0, 3, 2)));
0082     v = pdiv(v, s);
0083     return *this;
0084   }
0085   EIGEN_STRONG_INLINE Packet2cf operator/(const Packet2cf& b) const {
0086     return Packet2cf(*this) /= b;
0087   }
0088   EIGEN_STRONG_INLINE Packet2cf operator-(void) const {
0089     return Packet2cf(pnegate(v));
0090   }
0091 
0092   Packet4f v;
0093 };
0094 
0095 inline std::ostream& operator<<(std::ostream& os, const Packet2cf& value) {
0096   os << "[ (" << value.v[0] << ", " << value.v[1]
0097      << "i),"
0098         "  ("
0099      << value.v[2] << ", " << value.v[3] << "i) ]";
0100   return os;
0101 }
0102 
0103 template <>
0104 struct packet_traits<std::complex<float> > : default_packet_traits {
0105   typedef Packet2cf type;
0106   typedef Packet2cf half;
0107   enum {
0108     Vectorizable = 1,
0109     AlignedOnScalar = 1,
0110     size = 2,
0111     HasHalfPacket = 0,
0112 
0113     HasAdd = 1,
0114     HasSub = 1,
0115     HasMul = 1,
0116     HasDiv = 1,
0117     HasNegate = 1,
0118     HasAbs = 0,
0119     HasAbs2 = 0,
0120     HasMin = 0,
0121     HasMax = 0,
0122     HasSetLinear = 0,
0123     HasBlend = 1
0124   };
0125 };
0126 
0127 template <>
0128 struct unpacket_traits<Packet2cf> {
0129   typedef std::complex<float> type;
0130   enum { size = 2, alignment = Aligned16, vectorizable=true, masked_load_available=false, masked_store_available=false };
0131   typedef Packet2cf half;
0132 };
0133 
0134 template <>
0135 EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from) {
0136   EIGEN_MSA_DEBUG;
0137 
0138   float f0 = from.real(), f1 = from.imag();
0139   Packet4f v0 = { f0, f0, f0, f0 };
0140   Packet4f v1 = { f1, f1, f1, f1 };
0141   return Packet2cf((Packet4f)__builtin_msa_ilvr_w((Packet4i)v1, (Packet4i)v0));
0142 }
0143 
0144 template <>
0145 EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0146   EIGEN_MSA_DEBUG;
0147 
0148   return a + b;
0149 }
0150 
0151 template <>
0152 EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0153   EIGEN_MSA_DEBUG;
0154 
0155   return a - b;
0156 }
0157 
0158 template <>
0159 EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) {
0160   EIGEN_MSA_DEBUG;
0161 
0162   return -a;
0163 }
0164 
0165 template <>
0166 EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) {
0167   EIGEN_MSA_DEBUG;
0168 
0169   return a.conjugate();
0170 }
0171 
0172 template <>
0173 EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0174   EIGEN_MSA_DEBUG;
0175 
0176   return a * b;
0177 }
0178 
0179 template <>
0180 EIGEN_STRONG_INLINE Packet2cf pand<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0181   EIGEN_MSA_DEBUG;
0182 
0183   return Packet2cf(pand(a.v, b.v));
0184 }
0185 
0186 template <>
0187 EIGEN_STRONG_INLINE Packet2cf por<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0188   EIGEN_MSA_DEBUG;
0189 
0190   return Packet2cf(por(a.v, b.v));
0191 }
0192 
0193 template <>
0194 EIGEN_STRONG_INLINE Packet2cf pxor<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0195   EIGEN_MSA_DEBUG;
0196 
0197   return Packet2cf(pxor(a.v, b.v));
0198 }
0199 
0200 template <>
0201 EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0202   EIGEN_MSA_DEBUG;
0203 
0204   return Packet2cf(pandnot(a.v, b.v));
0205 }
0206 
0207 template <>
0208 EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) {
0209   EIGEN_MSA_DEBUG;
0210 
0211   EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from));
0212 }
0213 
0214 template <>
0215 EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) {
0216   EIGEN_MSA_DEBUG;
0217 
0218   EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from));
0219 }
0220 
0221 template <>
0222 EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) {
0223   EIGEN_MSA_DEBUG;
0224 
0225   return pset1<Packet2cf>(*from);
0226 }
0227 
0228 template <>
0229 EIGEN_STRONG_INLINE void pstore<std::complex<float> >(std::complex<float>* to,
0230                                                       const Packet2cf& from) {
0231   EIGEN_MSA_DEBUG;
0232 
0233   EIGEN_DEBUG_ALIGNED_STORE pstore<float>((float*)to, from.v);
0234 }
0235 
0236 template <>
0237 EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float>* to,
0238                                                        const Packet2cf& from) {
0239   EIGEN_MSA_DEBUG;
0240 
0241   EIGEN_DEBUG_UNALIGNED_STORE pstoreu<float>((float*)to, from.v);
0242 }
0243 
0244 template <>
0245 EIGEN_DEVICE_FUNC inline Packet2cf pgather<std::complex<float>, Packet2cf>(
0246     const std::complex<float>* from, Index stride) {
0247   EIGEN_MSA_DEBUG;
0248 
0249   return Packet2cf(from[0 * stride], from[1 * stride]);
0250 }
0251 
0252 template <>
0253 EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf>(std::complex<float>* to,
0254                                                                        const Packet2cf& from,
0255                                                                        Index stride) {
0256   EIGEN_MSA_DEBUG;
0257 
0258   *to = std::complex<float>(from.v[0], from.v[1]);
0259   to += stride;
0260   *to = std::complex<float>(from.v[2], from.v[3]);
0261 }
0262 
0263 template <>
0264 EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float>* addr) {
0265   EIGEN_MSA_DEBUG;
0266 
0267   prefetch(reinterpret_cast<const float*>(addr));
0268 }
0269 
0270 template <>
0271 EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a) {
0272   EIGEN_MSA_DEBUG;
0273 
0274   return std::complex<float>(a.v[0], a.v[1]);
0275 }
0276 
0277 template <>
0278 EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) {
0279   EIGEN_MSA_DEBUG;
0280 
0281   return Packet2cf((Packet4f)__builtin_msa_shf_w((v4i32)a.v, EIGEN_MSA_SHF_I8(2, 3, 0, 1)));
0282 }
0283 
0284 template <>
0285 EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& a) {
0286   EIGEN_MSA_DEBUG;
0287 
0288   return Packet2cf((Packet4f)__builtin_msa_shf_w((v4i32)a.v, EIGEN_MSA_SHF_I8(1, 0, 3, 2)));
0289 }
0290 
0291 template <>
0292 EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a) {
0293   EIGEN_MSA_DEBUG;
0294 
0295   Packet4f value = (Packet4f)preverse((Packet2d)a.v);
0296   value += a.v;
0297   return std::complex<float>(value[0], value[1]);
0298 }
0299 
0300 template <>
0301 EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a) {
0302   EIGEN_MSA_DEBUG;
0303 
0304   return std::complex<float>((a.v[0] * a.v[2]) - (a.v[1] * a.v[3]),
0305                              (a.v[0] * a.v[3]) + (a.v[1] * a.v[2]));
0306 }
0307 
0308 EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf, Packet4f)
0309 
0310 template <>
0311 EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
0312   EIGEN_MSA_DEBUG;
0313 
0314   return a / b;
0315 }
0316 
0317 inline std::ostream& operator<<(std::ostream& os, const PacketBlock<Packet2cf, 2>& value) {
0318   os << "[ " << value.packet[0] << ", " << std::endl << "  " << value.packet[1] << " ]";
0319   return os;
0320 }
0321 
0322 EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2cf, 2>& kernel) {
0323   EIGEN_MSA_DEBUG;
0324 
0325   Packet4f tmp =
0326       (Packet4f)__builtin_msa_ilvl_d((v2i64)kernel.packet[1].v, (v2i64)kernel.packet[0].v);
0327   kernel.packet[0].v =
0328       (Packet4f)__builtin_msa_ilvr_d((v2i64)kernel.packet[1].v, (v2i64)kernel.packet[0].v);
0329   kernel.packet[1].v = tmp;
0330 }
0331 
0332 template <>
0333 EIGEN_STRONG_INLINE Packet2cf pblend(const Selector<2>& ifPacket, const Packet2cf& thenPacket,
0334                                      const Packet2cf& elsePacket) {
0335   return (Packet2cf)(Packet4f)pblend<Packet2d>(ifPacket, (Packet2d)thenPacket.v,
0336                                                (Packet2d)elsePacket.v);
0337 }
0338 
0339 //---------- double ----------
0340 
0341 struct Packet1cd {
0342   EIGEN_STRONG_INLINE Packet1cd() {
0343   }
0344   EIGEN_STRONG_INLINE explicit Packet1cd(const std::complex<double>& a) {
0345     v[0] = std::real(a);
0346     v[1] = std::imag(a);
0347   }
0348   EIGEN_STRONG_INLINE explicit Packet1cd(const Packet2d& a) : v(a) {
0349   }
0350   EIGEN_STRONG_INLINE Packet1cd(const Packet1cd& a) : v(a.v) {
0351   }
0352   EIGEN_STRONG_INLINE Packet1cd& operator=(const Packet1cd& b) {
0353     v = b.v;
0354     return *this;
0355   }
0356   EIGEN_STRONG_INLINE Packet1cd conjugate(void) const {
0357     static const v2u64 p2ul_CONJ_XOR = { 0x0, 0x8000000000000000 };
0358     return (Packet1cd)pxor(v, (Packet2d)p2ul_CONJ_XOR);
0359   }
0360   EIGEN_STRONG_INLINE Packet1cd& operator*=(const Packet1cd& b) {
0361     Packet2d v1, v2;
0362 
0363     // Get the real values of a | a1_re | a1_re
0364     v1 = (Packet2d)__builtin_msa_ilvev_d((v2i64)v, (v2i64)v);
0365     // Get the imag values of a | a1_im | a1_im
0366     v2 = (Packet2d)__builtin_msa_ilvod_d((v2i64)v, (v2i64)v);
0367     // Multiply the real a with b
0368     v1 = pmul(v1, b.v);
0369     // Multiply the imag a with b
0370     v2 = pmul(v2, b.v);
0371     // Conjugate v2
0372     v2 = Packet1cd(v2).conjugate().v;
0373     // Swap real/imag elements in v2.
0374     v2 = (Packet2d)__builtin_msa_shf_w((v4i32)v2, EIGEN_MSA_SHF_I8(2, 3, 0, 1));
0375     // Add and return the result
0376     v = padd(v1, v2);
0377     return *this;
0378   }
0379   EIGEN_STRONG_INLINE Packet1cd operator*(const Packet1cd& b) const {
0380     return Packet1cd(*this) *= b;
0381   }
0382   EIGEN_STRONG_INLINE Packet1cd& operator+=(const Packet1cd& b) {
0383     v = padd(v, b.v);
0384     return *this;
0385   }
0386   EIGEN_STRONG_INLINE Packet1cd operator+(const Packet1cd& b) const {
0387     return Packet1cd(*this) += b;
0388   }
0389   EIGEN_STRONG_INLINE Packet1cd& operator-=(const Packet1cd& b) {
0390     v = psub(v, b.v);
0391     return *this;
0392   }
0393   EIGEN_STRONG_INLINE Packet1cd operator-(const Packet1cd& b) const {
0394     return Packet1cd(*this) -= b;
0395   }
0396   EIGEN_STRONG_INLINE Packet1cd& operator/=(const Packet1cd& b) {
0397     *this *= b.conjugate();
0398     Packet2d s = pmul<Packet2d>(b.v, b.v);
0399     s = padd(s, preverse<Packet2d>(s));
0400     v = pdiv(v, s);
0401     return *this;
0402   }
0403   EIGEN_STRONG_INLINE Packet1cd operator/(const Packet1cd& b) const {
0404     return Packet1cd(*this) /= b;
0405   }
0406   EIGEN_STRONG_INLINE Packet1cd operator-(void) const {
0407     return Packet1cd(pnegate(v));
0408   }
0409 
0410   Packet2d v;
0411 };
0412 
0413 inline std::ostream& operator<<(std::ostream& os, const Packet1cd& value) {
0414   os << "[ (" << value.v[0] << ", " << value.v[1] << "i) ]";
0415   return os;
0416 }
0417 
0418 template <>
0419 struct packet_traits<std::complex<double> > : default_packet_traits {
0420   typedef Packet1cd type;
0421   typedef Packet1cd half;
0422   enum {
0423     Vectorizable = 1,
0424     AlignedOnScalar = 0,
0425     size = 1,
0426     HasHalfPacket = 0,
0427 
0428     HasAdd = 1,
0429     HasSub = 1,
0430     HasMul = 1,
0431     HasDiv = 1,
0432     HasNegate = 1,
0433     HasAbs = 0,
0434     HasAbs2 = 0,
0435     HasMin = 0,
0436     HasMax = 0,
0437     HasSetLinear = 0
0438   };
0439 };
0440 
0441 template <>
0442 struct unpacket_traits<Packet1cd> {
0443   typedef std::complex<double> type;
0444   enum { size = 1, alignment = Aligned16, vectorizable=true, masked_load_available=false, masked_store_available=false };
0445   typedef Packet1cd half;
0446 };
0447 
0448 template <>
0449 EIGEN_STRONG_INLINE Packet1cd pload<Packet1cd>(const std::complex<double>* from) {
0450   EIGEN_MSA_DEBUG;
0451 
0452   EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload<Packet2d>((const double*)from));
0453 }
0454 
0455 template <>
0456 EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from) {
0457   EIGEN_MSA_DEBUG;
0458 
0459   EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu<Packet2d>((const double*)from));
0460 }
0461 
0462 template <>
0463 EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>& from) {
0464   EIGEN_MSA_DEBUG;
0465 
0466   return Packet1cd(from);
0467 }
0468 
0469 template <>
0470 EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0471   EIGEN_MSA_DEBUG;
0472 
0473   return a + b;
0474 }
0475 
0476 template <>
0477 EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0478   EIGEN_MSA_DEBUG;
0479 
0480   return a - b;
0481 }
0482 
0483 template <>
0484 EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) {
0485   EIGEN_MSA_DEBUG;
0486 
0487   return -a;
0488 }
0489 
0490 template <>
0491 EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) {
0492   EIGEN_MSA_DEBUG;
0493 
0494   return a.conjugate();
0495 }
0496 
0497 template <>
0498 EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0499   EIGEN_MSA_DEBUG;
0500 
0501   return a * b;
0502 }
0503 
0504 template <>
0505 EIGEN_STRONG_INLINE Packet1cd pand<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0506   EIGEN_MSA_DEBUG;
0507 
0508   return Packet1cd(pand(a.v, b.v));
0509 }
0510 
0511 template <>
0512 EIGEN_STRONG_INLINE Packet1cd por<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0513   EIGEN_MSA_DEBUG;
0514 
0515   return Packet1cd(por(a.v, b.v));
0516 }
0517 
0518 template <>
0519 EIGEN_STRONG_INLINE Packet1cd pxor<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0520   EIGEN_MSA_DEBUG;
0521 
0522   return Packet1cd(pxor(a.v, b.v));
0523 }
0524 
0525 template <>
0526 EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0527   EIGEN_MSA_DEBUG;
0528 
0529   return Packet1cd(pandnot(a.v, b.v));
0530 }
0531 
0532 template <>
0533 EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) {
0534   EIGEN_MSA_DEBUG;
0535 
0536   return pset1<Packet1cd>(*from);
0537 }
0538 
0539 template <>
0540 EIGEN_STRONG_INLINE void pstore<std::complex<double> >(std::complex<double>* to,
0541                                                        const Packet1cd& from) {
0542   EIGEN_MSA_DEBUG;
0543 
0544   EIGEN_DEBUG_ALIGNED_STORE pstore<double>((double*)to, from.v);
0545 }
0546 
0547 template <>
0548 EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double>* to,
0549                                                         const Packet1cd& from) {
0550   EIGEN_MSA_DEBUG;
0551 
0552   EIGEN_DEBUG_UNALIGNED_STORE pstoreu<double>((double*)to, from.v);
0553 }
0554 
0555 template <>
0556 EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double>* addr) {
0557   EIGEN_MSA_DEBUG;
0558 
0559   prefetch(reinterpret_cast<const double*>(addr));
0560 }
0561 
0562 template <>
0563 EIGEN_DEVICE_FUNC inline Packet1cd pgather<std::complex<double>, Packet1cd>(
0564     const std::complex<double>* from, Index stride __attribute__((unused))) {
0565   EIGEN_MSA_DEBUG;
0566 
0567   Packet1cd res;
0568   res.v[0] = std::real(from[0]);
0569   res.v[1] = std::imag(from[0]);
0570   return res;
0571 }
0572 
0573 template <>
0574 EIGEN_DEVICE_FUNC inline void pscatter<std::complex<double>, Packet1cd>(std::complex<double>* to,
0575                                                                         const Packet1cd& from,
0576                                                                         Index stride
0577                                                                         __attribute__((unused))) {
0578   EIGEN_MSA_DEBUG;
0579 
0580   pstore(to, from);
0581 }
0582 
0583 template <>
0584 EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet1cd>(const Packet1cd& a) {
0585   EIGEN_MSA_DEBUG;
0586 
0587   return std::complex<double>(a.v[0], a.v[1]);
0588 }
0589 
0590 template <>
0591 EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) {
0592   EIGEN_MSA_DEBUG;
0593 
0594   return a;
0595 }
0596 
0597 template <>
0598 EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a) {
0599   EIGEN_MSA_DEBUG;
0600 
0601   return pfirst(a);
0602 }
0603 
0604 template <>
0605 EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a) {
0606   EIGEN_MSA_DEBUG;
0607 
0608   return pfirst(a);
0609 }
0610 
0611 EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd, Packet2d)
0612 
0613 template <>
0614 EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
0615   EIGEN_MSA_DEBUG;
0616 
0617   return a / b;
0618 }
0619 
0620 EIGEN_STRONG_INLINE Packet1cd pcplxflip /*<Packet1cd>*/ (const Packet1cd& x) {
0621   EIGEN_MSA_DEBUG;
0622 
0623   return Packet1cd(preverse(Packet2d(x.v)));
0624 }
0625 
0626 inline std::ostream& operator<<(std::ostream& os, const PacketBlock<Packet1cd, 2>& value) {
0627   os << "[ " << value.packet[0] << ", " << std::endl << "  " << value.packet[1] << " ]";
0628   return os;
0629 }
0630 
0631 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet1cd, 2>& kernel) {
0632   EIGEN_MSA_DEBUG;
0633 
0634   Packet2d v1, v2;
0635 
0636   v1 = (Packet2d)__builtin_msa_ilvev_d((v2i64)kernel.packet[0].v, (v2i64)kernel.packet[1].v);
0637   // Get the imag values of a
0638   v2 = (Packet2d)__builtin_msa_ilvod_d((v2i64)kernel.packet[0].v, (v2i64)kernel.packet[1].v);
0639 
0640   kernel.packet[0].v = v1;
0641   kernel.packet[1].v = v2;
0642 }
0643 
0644 }  // end namespace internal
0645 
0646 }  // end namespace Eigen
0647 
0648 #endif  // EIGEN_COMPLEX_MSA_H