mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-13 08:35:46 +00:00
Handle instructions which need to be #defines for the purpose of capturing constant arguments
Handle extract hi/lo with common code git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105666 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c3c2517fed
commit
6c060dbf84
@ -411,14 +411,17 @@ static std::string MangleName(const std::string &name, StringRef typestr,
|
|||||||
|
|
||||||
// Generate the string "(argtype a, argtype b, ...)"
|
// Generate the string "(argtype a, argtype b, ...)"
|
||||||
static std::string GenArgs(const std::string &proto, StringRef typestr) {
|
static std::string GenArgs(const std::string &proto, StringRef typestr) {
|
||||||
|
bool define = proto.find('i') != std::string::npos;
|
||||||
char arg = 'a';
|
char arg = 'a';
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
s += "(";
|
s += "(";
|
||||||
|
|
||||||
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
|
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
|
||||||
|
if (!define) {
|
||||||
s += TypeString(proto[i], typestr);
|
s += TypeString(proto[i], typestr);
|
||||||
s.push_back(' ');
|
s.push_back(' ');
|
||||||
|
}
|
||||||
s.push_back(arg);
|
s.push_back(arg);
|
||||||
if ((i + 1) < e)
|
if ((i + 1) < e)
|
||||||
s += ", ";
|
s += ", ";
|
||||||
@ -519,6 +522,12 @@ static std::string GenOpString(OpKind op, const std::string &proto,
|
|||||||
s += "__builtin_shufflevector((__neon_int64x1_t)" + a;
|
s += "__builtin_shufflevector((__neon_int64x1_t)" + a;
|
||||||
s += ", (__neon_int64x1_t)" + b + ", 0, 1)";
|
s += ", (__neon_int64x1_t)" + b + ", 0, 1)";
|
||||||
break;
|
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:
|
case OpDup:
|
||||||
s += "(__neon_" + ts + "){ ";
|
s += "(__neon_" + ts + "){ ";
|
||||||
for (unsigned i = 0; i != nElts; ++i) {
|
for (unsigned i = 0; i != nElts; ++i) {
|
||||||
@ -597,6 +606,7 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
|
|||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
bool unioning = (proto[0] == '2' || proto[0] == '3' || proto[0] == '4');
|
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
|
// 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
|
// of arg checking. The actual signedness etc. will be taken care of with
|
||||||
@ -605,13 +615,19 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
|
|||||||
ck = ClassB;
|
ck = ClassB;
|
||||||
|
|
||||||
if (proto[0] != 'v') {
|
if (proto[0] != 'v') {
|
||||||
|
std::string ts = TypeString(proto[0], typestr);
|
||||||
|
|
||||||
|
if (define) {
|
||||||
|
if (proto[0] != 's')
|
||||||
|
s += "(" + ts + "){(__neon_" + ts + ")";
|
||||||
|
} else {
|
||||||
if (unioning) {
|
if (unioning) {
|
||||||
s += "union { ";
|
s += "union { ";
|
||||||
s += TypeString(proto[0], typestr, true) + " val; ";
|
s += TypeString(proto[0], typestr, true) + " val; ";
|
||||||
s += TypeString(proto[0], typestr, false) + " s; ";
|
s += TypeString(proto[0], typestr, false) + " s; ";
|
||||||
s += "} r;";
|
s += "} r;";
|
||||||
} else {
|
} else {
|
||||||
s += TypeString(proto[0], typestr);
|
s += ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
s += " r; r";
|
s += " r; r";
|
||||||
@ -620,6 +636,7 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
|
|||||||
|
|
||||||
s += " = ";
|
s += " = ";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s += "__builtin_neon_";
|
s += "__builtin_neon_";
|
||||||
s += MangleName(name, typestr, ck);
|
s += MangleName(name, typestr, ck);
|
||||||
@ -655,14 +672,22 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
|
|||||||
if (ck == ClassB)
|
if (ck == ClassB)
|
||||||
s += ", " + utostr(GetNeonEnum(proto, typestr));
|
s += ", " + utostr(GetNeonEnum(proto, typestr));
|
||||||
|
|
||||||
|
if (define)
|
||||||
|
s += ")";
|
||||||
|
else
|
||||||
s += ");";
|
s += ");";
|
||||||
|
|
||||||
if (proto[0] != 'v') {
|
if (proto[0] != 'v') {
|
||||||
|
if (define) {
|
||||||
|
if (proto[0] != 's')
|
||||||
|
s += "}";
|
||||||
|
} else {
|
||||||
if (unioning)
|
if (unioning)
|
||||||
s += " return r.s;";
|
s += " return r.s;";
|
||||||
else
|
else
|
||||||
s += " return r;";
|
s += " return r;";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,10 +792,15 @@ void NeonEmitter::run(raw_ostream &OS) {
|
|||||||
|
|
||||||
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) {
|
for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
|
||||||
assert(!Proto.empty() && "");
|
assert(!Proto.empty() && "");
|
||||||
|
|
||||||
// static always inline + return type
|
// static always inline + return type
|
||||||
|
if (define)
|
||||||
|
OS << "#define";
|
||||||
|
else
|
||||||
OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
|
OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
|
||||||
|
|
||||||
// Function name with type suffix
|
// Function name with type suffix
|
||||||
@ -780,6 +810,9 @@ void NeonEmitter::run(raw_ostream &OS) {
|
|||||||
OS << GenArgs(Proto, TypeVec[ti]);
|
OS << GenArgs(Proto, TypeVec[ti]);
|
||||||
|
|
||||||
// Definition.
|
// Definition.
|
||||||
|
if (define)
|
||||||
|
OS << " ";
|
||||||
|
else
|
||||||
OS << " { ";
|
OS << " { ";
|
||||||
|
|
||||||
if (k != OpNone) {
|
if (k != OpNone) {
|
||||||
@ -794,8 +827,9 @@ void NeonEmitter::run(raw_ostream &OS) {
|
|||||||
throw TGError(R->getLoc(), "Builtin has no class kind");
|
throw TGError(R->getLoc(), "Builtin has no class kind");
|
||||||
OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
|
OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
|
||||||
}
|
}
|
||||||
|
if (!define)
|
||||||
OS << " }\n";
|
OS << " }";
|
||||||
|
OS << "\n";
|
||||||
}
|
}
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,9 @@ enum OpKind {
|
|||||||
OpOrNot,
|
OpOrNot,
|
||||||
OpCast,
|
OpCast,
|
||||||
OpConcat,
|
OpConcat,
|
||||||
OpDup
|
OpDup,
|
||||||
|
OpHi,
|
||||||
|
OpLo
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ClassKind {
|
enum ClassKind {
|
||||||
@ -82,6 +84,8 @@ namespace llvm {
|
|||||||
OpMap["OP_ORN"] = OpOrNot;
|
OpMap["OP_ORN"] = OpOrNot;
|
||||||
OpMap["OP_CAST"] = OpCast;
|
OpMap["OP_CAST"] = OpCast;
|
||||||
OpMap["OP_CONC"] = OpConcat;
|
OpMap["OP_CONC"] = OpConcat;
|
||||||
|
OpMap["OP_HI"] = OpHi;
|
||||||
|
OpMap["OP_LO"] = OpLo;
|
||||||
OpMap["OP_DUP"] = OpDup;
|
OpMap["OP_DUP"] = OpDup;
|
||||||
|
|
||||||
Record *SI = R.getClass("SInst");
|
Record *SI = R.getClass("SInst");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user