Clang driver support for tilegx, including search patch support, vaarg support
etc.
Please review. thanks.
---
Regards,
Jiong
Tilera Corporation
http://llvm-reviews.chandlerc.com/D525
Files:
include/clang/Basic/TargetInfo.h
lib/AST/ASTContext.cpp
lib/Basic/Targets.cpp
lib/CodeGen/TargetInfo.cpp
lib/Driver/ToolChains.cpp
lib/Driver/Tools.cpp
lib/Driver/Tools.h
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -156,7 +156,13 @@
/// __builtin_va_list as defined by ARM AAPCS ABI
/// http://infocenter.arm.com
// /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
- AAPCSABIBuiltinVaList
+ AAPCSABIBuiltinVaList,
+
+ /// For tilegx, the VaList should be record type
+ /// which composed of two fields.
+ /// .val
+ /// .sp_at_entry
+ TileGXABIBuiltinVaList
};
protected:
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -5884,6 +5884,72 @@
return VaListTypeDecl;
}
+static TypedefDecl *
+CreateTileGXABIBuiltinVaListDecl(const ASTContext *Context) {
+ // typedef struct __va_list_tag {
+ RecordDecl *VaListTagDecl;
+ VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
+ Context->getTranslationUnitDecl(),
+ &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl->startDefinition();
+
+ const size_t NumFields = 2;
+ QualType FieldTypes[NumFields];
+ const char *FieldNames[NumFields];
+
+ // void* val;
+ FieldTypes[0] = Context->VoidPtrTy;
+ FieldNames[0] = "val";
+
+ // void* sp_at_entry;
+ FieldTypes[1] = Context->VoidPtrTy;
+ FieldNames[1] = "sp_at_entry";
+
+ // Create fields
+ for (unsigned i = 0; i < NumFields; ++i) {
+ FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
+ VaListTagDecl,
+ SourceLocation(),
+ SourceLocation(),
+ &Context->Idents.get(FieldNames[i]),
+ FieldTypes[i], /*TInfo=*/0,
+ /*BitWidth=*/0,
+ /*Mutable=*/false,
+ ICIS_NoInit);
+ Field->setAccess(AS_public);
+ VaListTagDecl->addDecl(Field);
+ }
+ VaListTagDecl->completeDefinition();
+ QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ Context->VaListTagTy = VaListTagType;
+
+ // } __va_list_tag;
+ TypedefDecl *VaListTagTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__va_list_tag"),
+ Context->getTrivialTypeSourceInfo(VaListTagType));
+ QualType VaListTagTypedefType =
+ Context->getTypedefType(VaListTagTypedefDecl);
+
+ // typedef __va_list_tag __builtin_va_list[1];
+ llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
+ QualType VaListTagArrayType
+ = Context->getConstantArrayType(VaListTagTypedefType,
+ Size, ArrayType::Normal,0);
+ TypeSourceInfo *TInfo
+ = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
+ TypedefDecl *VaListTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__builtin_va_list"),
+ TInfo);
+
+ return VaListTypedefDecl;
+}
+
static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
TargetInfo::BuiltinVaListKind Kind) {
switch (Kind) {
@@ -5901,6 +5967,8 @@
return CreatePNaClABIBuiltinVaListDecl(Context);
case TargetInfo::AAPCSABIBuiltinVaList:
return CreateAAPCSABIBuiltinVaListDecl(Context);
+ case TargetInfo::TileGXABIBuiltinVaList:
+ return CreateTileGXABIBuiltinVaListDecl(Context);
}
llvm_unreachable("Unhandled __builtin_va_list type kind");
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -4800,6 +4800,114 @@
} // end anonymous namespace.
namespace {
+class TileGXTargetInfo : public TargetInfo {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[];
+ static const char * const GCCRegNames[];
+ bool SoftFloat;
+public:
+ TileGXTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ LongWidth = LongAlign = 64;
+ PointerWidth = PointerAlign = 64;
+ }
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ StringRef Name,
+ bool Enabled) const {
+ if (Name == "soft-float")
+ Features[Name] = Enabled;
+ else
+ return false;
+
+ return true;
+ }
+ virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ SoftFloat = false;
+ for (unsigned i = 0, e = Features.size(); i != e; ++i)
+ if (Features[i] == "+soft-float")
+ SoftFloat = true;
+ }
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "tilegx", Opts);
+ Builder.defineMacro("__tile", "1");
+ Builder.defineMacro("__tile__", "1");
+ Builder.defineMacro("__tile_chip__", "10");
+ Builder.defineMacro("__tile_chip_rev__", "0");
+ Builder.defineMacro("__REGISTER_PREFIX__", "");
+ Builder.defineMacro("__LITTLE_ENDIAN__");
+
+ if (SoftFloat)
+ Builder.defineMacro("__tilegx_soft_float__", "1");
+ }
+
+ virtual bool hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("softfloat", SoftFloat)
+ .Case("tilegx", true)
+ .Default(false);
+ }
+
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const {
+ // FIXME: TileGX Builtins should be implemented here
+ }
+
+ virtual BuiltinVaListKind getBuiltinVaListKind() const {
+ return TargetInfo::TileGXABIBuiltinVaList;
+ }
+
+ int getEHDataRegisterNumber(unsigned RegNo) const {
+ if (RegNo == 0) return 12;
+ if (RegNo == 1) return 13;
+ return -1;
+ }
+
+ virtual void getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const;
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const;
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const {
+ // FIXME: Implement!
+ return false;
+ }
+ virtual const char *getClobbers() const {
+ // FIXME: Implement!
+ return "";
+ }
+};
+
+const char * const TileGXTargetInfo::GCCRegNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+ "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55"
+};
+
+void TileGXTargetInfo::getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const {
+ Names = GCCRegNames;
+ NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias TileGXTargetInfo::GCCRegAliases[] = {
+ { { "tp" }, "r53" },
+ { { "sp" }, "r54" },
+ { { "lr" }, "r55" },
+};
+
+void TileGXTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ Aliases = GCCRegAliases;
+ NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+} // end anonymous namespace.
+
+namespace {
class PNaClTargetInfo : public TargetInfo {
public:
PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) {
@@ -4970,6 +5078,9 @@
case llvm::Triple::hexagon:
return new HexagonTargetInfo(T);
+ case llvm::Triple::tilegx:
+ return new LinuxTargetInfo<TileGXTargetInfo>(T);
+
case llvm::Triple::aarch64:
switch (os) {
case llvm::Triple::Linux:
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -4810,6 +4810,262 @@
return AddrTyped;
}
+//===----------------------------------------------------------------------===//
+// TileGX ABI Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class TileGXABIInfo : public ABIInfo {
+
+ void CoerceToIntArgs(uint64_t TySize,
+ SmallVector<llvm::Type*, 10> &ArgList) const;
+ llvm::Type* HandleAggregates(QualType Ty, uint64_t TySize) const;
+ llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset) const;
+ llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const;
+public:
+ TileGXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
+ ABIArgInfo classifyReturnType(QualType RetTy) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
+
+ virtual void computeInfo(CGFunctionInfo &FI) const;
+
+ virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const;
+};
+
+class TileGXTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ TileGXTargetCodeGenInfo(CodeGenTypes &CGT)
+ :TargetCodeGenInfo(new TileGXABIInfo(CGT)) {}
+
+ int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+ return 54;
+ }
+};
+
+}
+
+llvm::Type*
+TileGXABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
+ SmallVector<llvm::Type*, 10> ArgList, IntArgList;
+
+ if (Ty->isComplexType())
+ return CGT.ConvertType(Ty);
+
+ const RecordType *RT = Ty->getAs<RecordType>();
+
+ // Unions/vectors are passed in integer registers.
+ if (!RT || !RT->isStructureOrClassType()) {
+ CoerceToIntArgs(TySize, ArgList);
+ return llvm::StructType::get(getVMContext(), ArgList);
+ }
+
+ const RecordDecl *RD = RT->getDecl();
+ const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+ assert(!(TySize % 8) && "Size of structure must be multiple of 8.");
+
+ uint64_t LastOffset = 0;
+ unsigned idx = 0;
+ llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
+
+ // Iterate over fields in the struct/class and check if there are any aligned
+ // double fields.
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i, ++idx) {
+ const QualType Ty = i->getType();
+ const BuiltinType *BT = Ty->getAs<BuiltinType>();
+
+ if (!BT || BT->getKind() != BuiltinType::Double)
+ continue;
+
+ uint64_t Offset = Layout.getFieldOffset(idx);
+ if (Offset % 64) // Ignore doubles that are not aligned.
+ continue;
+
+ // Add ((Offset - LastOffset) / 64) args of type i64.
+ for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j)
+ ArgList.push_back(I64);
+
+ // Add double type.
+ ArgList.push_back(llvm::Type::getDoubleTy(getVMContext()));
+ LastOffset = Offset + 64;
+ }
+
+ CoerceToIntArgs(TySize - LastOffset, IntArgList);
+ ArgList.append(IntArgList.begin(), IntArgList.end());
+
+ return llvm::StructType::get(getVMContext(), ArgList);
+}
+
+llvm::Type *
+TileGXABIInfo::getPaddingType(uint64_t Align, uint64_t Offset) const {
+ assert((Offset % 8) == 0);
+
+ if ((Align - 1) & Offset)
+ return llvm::IntegerType::get(getVMContext(), 64);
+
+ return 0;
+}
+
+
+void
+TileGXABIInfo::CoerceToIntArgs(uint64_t TySize,
+ SmallVector<llvm::Type*, 10> &ArgList) const {
+ llvm::IntegerType *IntTy =
+ llvm::IntegerType::get(getVMContext(), 64);
+
+ // Add (TySize / MinABIStackAlignInBytes) args of IntTy.
+ for (unsigned N = TySize / 64; N; --N)
+ ArgList.push_back(IntTy);
+
+ // If necessary, add one more integer type to ArgList.
+ unsigned R = TySize % 64;
+
+ if (R)
+ ArgList.push_back(llvm::IntegerType::get(getVMContext(), R));
+}
+
+
+llvm::Type*
+TileGXABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
+ const RecordType *RT = RetTy->getAs<RecordType>();
+ SmallVector<llvm::Type*, 10> RTList;
+
+ if (RT && RT->isStructureOrClassType()) {
+ const RecordDecl *RD = RT->getDecl();
+ const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+ unsigned FieldCnt = Layout.getFieldCount();
+
+ if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
+ RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
+ for (; b != e; ++b) {
+ const BuiltinType *BT = b->getType()->getAs<BuiltinType>();
+
+ if (!BT || !BT->isFloatingPoint())
+ break;
+
+ RTList.push_back(CGT.ConvertType(b->getType()));
+ }
+
+ if (b == e)
+ return llvm::StructType::get(getVMContext(), RTList,
+ RD->hasAttr<PackedAttr>());
+
+ RTList.clear();
+ }
+ }
+
+ CoerceToIntArgs(Size, RTList);
+ return llvm::StructType::get(getVMContext(), RTList);
+}
+
+ABIArgInfo
+TileGXABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
+ uint64_t OrigOffset = Offset;
+ uint64_t TySize = getContext().getTypeSize(Ty);
+ uint64_t Align = getContext().getTypeAlign(Ty) / 8;
+
+ Align = std::max(Align, (uint64_t)8);
+ Offset = llvm::RoundUpToAlignment(Offset, Align);
+ Offset += llvm::RoundUpToAlignment(TySize, Align * 8) / 8;
+
+ if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) {
+ // Ignore empty aggregates.
+ if (TySize == 0)
+ return ABIArgInfo::getIgnore();
+
+ // Records with non trivial destructors/constructors should not be passed
+ // by value.
+ if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) {
+ Offset = OrigOffset + 8;
+ return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ }
+
+ // If we have reached here, aggregates are passed directly by coercing to
+ // another structure type. Padding is inserted if the offset of the
+ // aggregate is unaligned.
+ return ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0,
+ getPaddingType(Align, OrigOffset));
+ }
+
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ Ty = EnumTy->getDecl()->getIntegerType();
+
+ if (Ty->isPromotableIntegerType())
+ return ABIArgInfo::getExtend();
+
+ return ABIArgInfo::getDirect(0, 0, getPaddingType(Align, OrigOffset));
+
+}
+
+ABIArgInfo
+TileGXABIInfo::classifyReturnType(QualType RetTy) const {
+ uint64_t Size = getContext().getTypeSize(RetTy);
+
+ if (RetTy->isVoidType()
+ || Size == 0)
+ return ABIArgInfo::getIgnore();
+
+ if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) {
+ if (Size <= (10 * 64)) {
+ if (RetTy->isAnyComplexType())
+ return ABIArgInfo::getDirect();
+
+ if (!isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy))
+ return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
+ }
+
+ return ABIArgInfo::getIndirect(0);
+ }
+
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+ RetTy = EnumTy->getDecl()->getIntegerType();
+
+ return (RetTy->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+}
+
+llvm::Value *
+TileGXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const {
+
+ if (!isAggregateTypeForABI(Ty))
+ return 0;
+
+ // FIXME: Need to handle alignment
+ llvm::Type *BPP = CGF.Int8PtrPtrTy;
+
+ CGBuilderTy &Builder = CGF.Builder;
+ llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
+ "ap");
+ llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+ llvm::Type *PTy =
+ llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+ llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
+
+ uint64_t Offset =
+ llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 8);
+ llvm::Value *NextAddr =
+ Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int64Ty, Offset),
+ "ap.next");
+ Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+ return AddrTyped;
+}
+
+void
+TileGXABIInfo::computeInfo(CGFunctionInfo &FI) const {
+ ABIArgInfo &RetInfo = FI.getReturnInfo();
+ RetInfo = classifyReturnType(FI.getReturnType());
+
+ uint64_t Offset = RetInfo.isIndirect() ? 8 : 0;
+ for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+ it != ie; ++it)
+ it->info = classifyArgumentType(it->type, Offset);
+}
const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
if (TheTargetCodeGenInfo)
@@ -4925,5 +5181,8 @@
}
case llvm::Triple::hexagon:
return *(TheTargetCodeGenInfo = new HexagonTargetCodeGenInfo(Types));
+
+ case llvm::Triple::tilegx:
+ return *(TheTargetCodeGenInfo = new TileGXTargetCodeGenInfo(Types));
}
}
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -1160,6 +1160,11 @@
"ppc64-redhat-linux"
};
+ static const char *const TileGXLibDirs[] = { "/lib" };
+ static const char *const TileGXTriples[] = {
+ "tilegx-redhat-linux"
+ };
+
switch (TargetTriple.getArch()) {
case llvm::Triple::aarch64:
LibDirs.append(AArch64LibDirs, AArch64LibDirs
@@ -1261,6 +1266,17 @@
PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
break;
+ case llvm::Triple::tilegx:
+ LibDirs.append(
+ TileGXLibDirs, TileGXLibDirs + llvm::array_lengthof(TileGXLibDirs));
+ TripleAliases.append(
+ TileGXTriples, TileGXTriples + llvm::array_lengthof(TileGXTriples));
+ MultiarchLibDirs.append(
+ TileGXLibDirs, TileGXLibDirs + llvm::array_lengthof(TileGXLibDirs));
+ MultiarchTripleAliases.append(
+ TileGXTriples, TileGXTriples + llvm::array_lengthof(TileGXTriples));
+ break;
+
default:
// By default, just rely on the standard lib directories and the original
// triple.
@@ -1285,7 +1301,8 @@
static StringRef getTargetMultiarchSuffix(llvm::Triple::ArchType TargetArch,
const ArgList &Args) {
if (TargetArch == llvm::Triple::x86_64 ||
- TargetArch == llvm::Triple::ppc64)
+ TargetArch == llvm::Triple::ppc64 ||
+ TargetArch == llvm::Triple::tilegx)
return "/64";
if (TargetArch == llvm::Triple::mips64 ||
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1316,6 +1316,34 @@
CmdArgs.push_back ("-machine-sink-split=0");
}
+void Clang::AddTileGXTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+
+ // Select the float ABI as determined by -msoft-float, -mhard-float, and
+ StringRef FloatABI;
+ if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
+ options::OPT_mhard_float)) {
+ if (A->getOption().matches(options::OPT_msoft_float))
+ FloatABI = "soft";
+ else if (A->getOption().matches(options::OPT_mhard_float))
+ FloatABI = "hard";
+ }
+
+ // If unspecified, choose the default based on the platform.
+ if (FloatABI.empty()) {
+ switch (getToolChain().getTriple().getOS()) {
+ default:
+ FloatABI = "soft";
+ break;
+ }
+ }
+
+ if (FloatABI == "soft")
+ CmdArgs.push_back("-msoft-float");
+ else
+ CmdArgs.push_back("-mhard-float");
+}
+
static bool
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
const llvm::Triple &Triple) {
@@ -2242,6 +2270,10 @@
case llvm::Triple::hexagon:
AddHexagonTargetArgs(Args, CmdArgs);
break;
+
+ case llvm::Triple::tilegx:
+ AddTileGXTargetArgs(Args, CmdArgs);
+ break;
}
@@ -5738,6 +5770,8 @@
else
CmdArgs.push_back("elf64ltsmip");
}
+ else if (ToolChain.getArch() == llvm::Triple::tilegx)
+ CmdArgs.push_back("elf64tilegx");
else
CmdArgs.push_back("elf_x86_64");
@@ -5786,6 +5820,8 @@
CmdArgs.push_back("/lib/ld.so.1");
else if (ToolChain.getArch() == llvm::Triple::ppc64)
CmdArgs.push_back("/lib64/ld64.so.1");
+ else if (ToolChain.getArch() == llvm::Triple::tilegx)
+ CmdArgs.push_back("/lib/ld.so.1");
else
CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2");
}
Index: lib/Driver/Tools.h
===================================================================
--- lib/Driver/Tools.h
+++ lib/Driver/Tools.h
@@ -54,6 +54,7 @@
void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const;
+ void AddTileGXTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const;
enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits