return s;
}
-// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
-static std::string GenOpString(OpKind op, const std::string &proto,
- StringRef typestr) {
- bool dummy, quad = false;
+static unsigned GetNumElements(StringRef typestr, bool &quad) {
+ quad = false;
+ bool dummy = false;
char type = ClassifyType(typestr, quad, dummy, dummy);
unsigned nElts = 0;
switch (type) {
- case 'c': nElts = 8; break;
- case 's': nElts = 4; break;
- case 'i': nElts = 2; break;
- case 'l': nElts = 1; break;
- case 'h': nElts = 4; break;
- case 'f': nElts = 2; break;
+ case 'c': nElts = 8; break;
+ case 's': nElts = 4; break;
+ case 'i': nElts = 2; break;
+ case 'l': nElts = 1; break;
+ case 'h': nElts = 4; break;
+ case 'f': nElts = 2; break;
+ default:
+ throw "unhandled type!";
+ break;
}
+ if (quad) nElts <<= 1;
+ return nElts;
+}
+
+// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
+static std::string GenOpString(OpKind op, const std::string &proto,
+ StringRef typestr) {
+ bool quad;
+ unsigned nElts = GetNumElements(typestr, quad);
std::string ts = TypeString(proto[0], typestr);
std::string s;
s += "a - b";
break;
case OpMulN:
- s += "a * " + Duplicate(nElts << (int)quad, typestr, "b");
+ s += "a * " + Duplicate(nElts, typestr, "b");
break;
case OpMul:
s += "a * b";
break;
case OpMlaN:
- s += "a + (b * " + Duplicate(nElts << (int)quad, typestr, "c") + ")";
+ s += "a + (b * " + Duplicate(nElts, typestr, "c") + ")";
break;
case OpMla:
s += "a + (b * c)";
break;
case OpMlsN:
- s += "a - (b * " + Duplicate(nElts << (int)quad, typestr, "c") + ")";
+ s += "a - (b * " + Duplicate(nElts, typestr, "c") + ")";
break;
case OpMls:
s += "a - (b * c)";
s += "(((float64x2_t)a)[0])";
break;
case OpDup:
- s += Duplicate(nElts << (int)quad, typestr, "a");
+ s += Duplicate(nElts, typestr, "a");
break;
case OpSelect:
// ((0 & 1) | (~0 & 2))
break;
case OpRev16:
s += "__builtin_shufflevector(a, a";
- for (unsigned i = 2; i <= nElts << (int)quad; i += 2)
+ for (unsigned i = 2; i <= nElts; i += 2)
for (unsigned j = 0; j != 2; ++j)
s += ", " + utostr(i - j - 1);
s += ")";
break;
- case OpRev32:
- nElts >>= 1;
+ case OpRev32: {
+ unsigned WordElts = nElts >> (1 + (int)quad);
s += "__builtin_shufflevector(a, a";
- for (unsigned i = nElts; i <= nElts << (1 + (int)quad); i += nElts)
- for (unsigned j = 0; j != nElts; ++j)
+ for (unsigned i = WordElts; i <= nElts; i += WordElts)
+ for (unsigned j = 0; j != WordElts; ++j)
s += ", " + utostr(i - j - 1);
s += ")";
break;
- case OpRev64:
+ }
+ case OpRev64: {
+ unsigned DblWordElts = nElts >> (int)quad;
s += "__builtin_shufflevector(a, a";
- for (unsigned i = nElts; i <= nElts << (int)quad; i += nElts)
- for (unsigned j = 0; j != nElts; ++j)
+ for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts)
+ for (unsigned j = 0; j != DblWordElts; ++j)
s += ", " + utostr(i - j - 1);
s += ")";
break;
+ }
default:
throw "unknown OpKind!";
break;
// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
static std::string GenBuiltin(const std::string &name, const std::string &proto,
StringRef typestr, ClassKind ck) {
- bool dummy, quad = false;
- char type = ClassifyType(typestr, quad, dummy, dummy);
- unsigned nElts = 0;
- switch (type) {
- case 'c': nElts = 8; break;
- case 's': nElts = 4; break;
- case 'i': nElts = 2; break;
- case 'l': nElts = 1; break;
- case 'h': nElts = 4; break;
- case 'f': nElts = 2; break;
- }
- if (quad) nElts <<= 1;
-
+ bool quad;
+ unsigned nElts = GetNumElements(typestr, quad);
char arg = 'a';
std::string s;
// Emit NEON-specific scalar typedefs.
OS << "typedef float float32_t;\n";
- OS << "typedef uint8_t poly8_t;\n";
- OS << "typedef uint16_t poly16_t;\n";
+ OS << "typedef int8_t poly8_t;\n";
+ OS << "typedef int16_t poly16_t;\n";
OS << "typedef uint16_t float16_t;\n";
// Emit Neon vector typedefs.
// Emit vector typedefs.
for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
- bool dummy, quad = false;
- (void) ClassifyType(TDTypeVec[i], quad, dummy, dummy);
- OS << "typedef __attribute__(( __vector_size__(";
+ bool dummy, quad = false, poly = false;
+ (void) ClassifyType(TDTypeVec[i], quad, poly, dummy);
+ if (poly)
+ OS << "typedef __attribute__((neon_polyvector_type(";
+ else
+ OS << "typedef __attribute__((neon_vector_type(";
- OS << utostr(8*(quad ? 2 : 1)) << ") )) ";
- if (!quad)
+ unsigned nElts = GetNumElements(TDTypeVec[i], quad);
+ OS << utostr(nElts) << "))) ";
+ if (nElts < 10)
OS << " ";
OS << TypeString('s', TDTypeVec[i]);
OS << " " << TypeString('d', TDTypeVec[i]) << ";\n";
}
OS << "\n";
- OS << "typedef __attribute__(( __vector_size__(8) )) "
+ OS << "typedef __attribute__((__vector_size__(8))) "
"double float64x1_t;\n";
- OS << "typedef __attribute__(( __vector_size__(16) )) "
+ OS << "typedef __attribute__((__vector_size__(16))) "
"double float64x2_t;\n";
OS << "\n";