Handle extract hi/lo with common code
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105666
91177308-0d34-0410-b5e6-
96231b3b80d8
// Generate the string "(argtype a, argtype b, ...)"
static std::string GenArgs(const std::string &proto, StringRef typestr) {
// Generate the string "(argtype a, argtype b, ...)"
static std::string GenArgs(const std::string &proto, StringRef typestr) {
+ bool define = proto.find('i') != std::string::npos;
char arg = 'a';
std::string s;
s += "(";
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
char arg = 'a';
std::string s;
s += "(";
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
- s += TypeString(proto[i], typestr);
- s.push_back(' ');
+ if (!define) {
+ s += TypeString(proto[i], typestr);
+ s.push_back(' ');
+ }
s.push_back(arg);
if ((i + 1) < e)
s += ", ";
s.push_back(arg);
if ((i + 1) < e)
s += ", ";
s += "__builtin_shufflevector((__neon_int64x1_t)" + a;
s += ", (__neon_int64x1_t)" + b + ", 0, 1)";
break;
s += "__builtin_shufflevector((__neon_int64x1_t)" + a;
s += ", (__neon_int64x1_t)" + b + ", 0, 1)";
break;
+ case OpHi:
+ s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[1])";
+ break;
+ case OpLo:
+ s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[0])";
+ break;
case OpDup:
s += "(__neon_" + ts + "){ ";
for (unsigned i = 0; i != nElts; ++i) {
case OpDup:
s += "(__neon_" + ts + "){ ";
for (unsigned i = 0; i != nElts; ++i) {
std::string s;
bool unioning = (proto[0] == '2' || proto[0] == '3' || proto[0] == '4');
std::string s;
bool unioning = (proto[0] == '2' || proto[0] == '3' || proto[0] == '4');
+ bool define = proto.find('i') != std::string::npos;
// If all types are the same size, bitcasting the args will take care
// of arg checking. The actual signedness etc. will be taken care of with
// If all types are the same size, bitcasting the args will take care
// of arg checking. The actual signedness etc. will be taken care of with
ck = ClassB;
if (proto[0] != 'v') {
ck = ClassB;
if (proto[0] != 'v') {
- if (unioning) {
- s += "union { ";
- s += TypeString(proto[0], typestr, true) + " val; ";
- s += TypeString(proto[0], typestr, false) + " s; ";
- s += "} r;";
+ std::string ts = TypeString(proto[0], typestr);
+
+ if (define) {
+ if (proto[0] != 's')
+ s += "(" + ts + "){(__neon_" + ts + ")";
- s += TypeString(proto[0], typestr);
+ if (unioning) {
+ s += "union { ";
+ s += TypeString(proto[0], typestr, true) + " val; ";
+ s += TypeString(proto[0], typestr, false) + " s; ";
+ s += "} r;";
+ } else {
+ s += ts;
+ }
+
+ s += " r; r";
+ if (structTypes && proto[0] != 's' && proto[0] != 'i' && proto[0] != 'l')
+ s += ".val";
+
+ s += " = ";
-
- s += " r; r";
- if (structTypes && proto[0] != 's' && proto[0] != 'i' && proto[0] != 'l')
- s += ".val";
-
- s += " = ";
}
s += "__builtin_neon_";
}
s += "__builtin_neon_";
if (ck == ClassB)
s += ", " + utostr(GetNeonEnum(proto, typestr));
if (ck == ClassB)
s += ", " + utostr(GetNeonEnum(proto, typestr));
+ if (define)
+ s += ")";
+ else
+ s += ");";
- if (unioning)
- s += " return r.s;";
- else
- s += " return r;";
+ if (define) {
+ if (proto[0] != 's')
+ s += "}";
+ } else {
+ if (unioning)
+ s += " return r.s;";
+ else
+ s += " return r;";
+ }
OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
+ bool define = Proto.find('i') != std::string::npos;
+
for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
assert(!Proto.empty() && "");
// static always inline + return type
for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
assert(!Proto.empty() && "");
// static always inline + return type
- OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
+ if (define)
+ OS << "#define";
+ else
+ OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
// Function name with type suffix
OS << " " << MangleName(name, TypeVec[ti], ClassS);
// Function name with type suffix
OS << " " << MangleName(name, TypeVec[ti], ClassS);
OS << GenArgs(Proto, TypeVec[ti]);
// Definition.
OS << GenArgs(Proto, TypeVec[ti]);
// Definition.
+ if (define)
+ OS << " ";
+ else
+ OS << " { ";
if (k != OpNone) {
OS << GenOpString(k, Proto, TypeVec[ti]);
if (k != OpNone) {
OS << GenOpString(k, Proto, TypeVec[ti]);
throw TGError(R->getLoc(), "Builtin has no class kind");
OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
}
throw TGError(R->getLoc(), "Builtin has no class kind");
OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
}
+ if (!define)
+ OS << " }";
+ OS << "\n";
OpOrNot,
OpCast,
OpConcat,
OpOrNot,
OpCast,
OpConcat,
OpMap["OP_ORN"] = OpOrNot;
OpMap["OP_CAST"] = OpCast;
OpMap["OP_CONC"] = OpConcat;
OpMap["OP_ORN"] = OpOrNot;
OpMap["OP_CAST"] = OpCast;
OpMap["OP_CONC"] = OpConcat;
+ OpMap["OP_HI"] = OpHi;
+ OpMap["OP_LO"] = OpLo;
OpMap["OP_DUP"] = OpDup;
Record *SI = R.getClass("SInst");
OpMap["OP_DUP"] = OpDup;
Record *SI = R.getClass("SInst");