blob: ba2bb9825f0238ade927f57ddb1c5970775c5ec2 [file] [log] [blame]
/* { dg-do compile } */
/* { dg-options "-std=c++17 -O2 -mfloat-abi=hard -mcpu=generic-armv7-a" } */
// { dg-require-effective-target arm_hard_ok }
// { dg-require-effective-target arm_neon_ok }
// { dg-add-options arm_neon }
#include <arm_neon.h>
typedef uint16x4_t e;
typedef int16x4_t f;
typedef int32x4_t g;
typedef float32x4_t h;
typedef uint32x4_t i;
g j, p;
g k(int l) { return vdupq_n_s32(l); }
i n(f l) { return (i)vmovl_u16((e)l); }
template <int, typename> struct q;
template <int r, typename aa> q<r, aa> operator<(aa s, q<r, aa> t) {
return q<r, aa>(s) < t;
}
template <typename ab, typename ac, int r> q<r, ab> ad(const q<r, ac> &);
typedef q<4, int> ae;
template <> class q<4, float> {
public:
q(h af) : ag(af) {}
q(float) {}
static q ah(void *ai) {
float *l = (float *)ai;
return vld1q_f32(l);
}
q operator+(q o) {
h l = ag, m = o.ag;
return vaddq_f32(l, m);
}
q operator*(q) {
h l = ag, m;
return vmulq_f32(l, m);
}
h ag;
};
template <> class q<4, unsigned short> {
public:
q(f af) : ag(af) {}
static q ah(void *ai) {
unsigned short *l = (unsigned short *)ai;
return (f)vld1_s16((int16_t *)l);
}
void aj() {
f m = ag;
vst1_u16(0, (e)m);
}
f ag;
};
template <> class q<4, int> {
public:
q(g af) : ag(af) {}
q(int u) { ag = k(u); }
static q ah(void *ai) {
int32_t *l = (int32_t *)ai;
return vld1q_s32(l);
}
q operator&(q o) {
g v = ag & o.ag;
return v;
}
q operator|(q o) {
g w = ag | o.ag;
return w;
}
q operator^(q) {
g x = ag ^ p;
return x;
}
q operator>>(int ak) { return ag >> q(ak).ag; }
q operator<(q) {
g y, z = j < ag;
y = (g)z;
return y;
}
g ag;
};
template <> ae ad(const q<4, unsigned short> &al) { return g(n(al.ag)); }
template <> q<4, unsigned short> ad(const ae &al) {
i l(i(al.ag));
return (f)vmovn_s32((g)l);
}
q<4, float> am(long long an) {
q ao = q<4, unsigned short>::ah(&an);
ae ak = ad<int>(ao), ap = ak & 8000, aq = ak ^ ap, ar = 55 < aq, as(aq);
q at = as & ar;
ae au = ap | at;
return q<4, float>::ah(&au);
}
q<4, unsigned short> av(q<4, float> aw) {
ae ak = ae::ah(&aw), ap = ak & 80000000, aq = ap, ax = 5, as = aq >> 3,
ay = 6;
q az = ax & as;
ae au = ay | az;
return ad<unsigned short>(au);
}
struct ba {
typedef int bb;
static q<4, float> bc(int s) { return am(s); }
};
q<4, float> bd(q<4, float> s) { return s * 0; }
template <typename be> void bf(void *bg, void *al, int bh, int bi) {
int bj;
auto bk(static_cast<typename be::bb *>(al) + bh),
d = static_cast<typename be::bb *>(bg),
bl = be::bc(static_cast<typename be::bb *>(al)[0]), bm = be::bc(0),
c = bm;
for (; bi;) {
auto a = c, bn = be::bc(static_cast<typename be::bb *>(al)[1]),
bo = be::bc(1);
q bp = bn;
q bq = bp;
auto b = bq + bo;
bl = be::bc(static_cast<typename be::bb *>(al)[2]);
bm = be::bc(bk[2]);
c = bl + bm;
q br = a + b;
auto bs = br;
q bt = bd(bs);
av(bt).aj();
d[0] = bj;
}
}
int bu;
void bv() { bf<ba>(0, 0, 0, bu); }