diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp index 29930402daf..ac641b184e5 100644 --- a/utils/TableGen/NeonEmitter.cpp +++ b/utils/TableGen/NeonEmitter.cpp @@ -368,6 +368,52 @@ static std::string BuiltinTypeString(const char mod, StringRef typestr, return quad ? "V16c" : "V8c"; } +/// StructTag - generate the name of the struct tag for a type. +/// These names are mandated by ARM's ABI. +static std::string StructTag(StringRef typestr) { + bool quad = false; + bool poly = false; + bool usgn = false; + + // base type to get the type string for. + char type = ClassifyType(typestr, quad, poly, usgn); + + SmallString<128> s; + s += "__simd"; + s += quad ? "128_" : "64_"; + if (usgn) + s.push_back('u'); + + switch (type) { + case 'c': + s += poly ? "poly8" : "int8"; + break; + case 's': + s += poly ? "poly16" : "int16"; + break; + case 'i': + s += "int32"; + break; + case 'l': + s += "int64"; + break; + case 'h': + s += "float16"; + break; + case 'f': + s += "float32"; + break; + default: + throw "unhandled type!"; + break; + } + + // Append _t, finishing the struct tag name. + s += "_t"; + + return s.str(); +} + /// MangleName - Append a type or width suffix to a base neon function name, /// and insert a 'q' in the appropriate location if the operation works on /// 128b rather than 64b. E.g. turn "vst2_lane" into "vst2q_lane_f32", etc. @@ -878,10 +924,11 @@ void NeonEmitter::run(raw_ostream &OS) { // Emit struct typedefs. for (unsigned vi = 1; vi != 5; ++vi) { for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { - std::string ts = TypeString('d', TDTypeVec[i]); - std::string vs = (vi > 1) ? TypeString('0' + vi, TDTypeVec[i]) : ts; - OS << "typedef struct __" << vs << " {\n"; - OS << " __neon_" << ts << " val"; + std::string ts = TypeString('d', TDTypeVec[i], vi == 1); + std::string vs = TypeString((vi > 1) ? '0' + vi : 'd', TDTypeVec[i]); + std::string tag = (vi > 1) ? vs : StructTag(TDTypeVec[i]); + OS << "typedef struct " << tag << " {\n"; + OS << " " << ts << " val"; if (vi > 1) OS << "[" << utostr(vi) << "]"; OS << ";\n} " << vs << ";\n\n";