diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 69 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 9 |
3 files changed, 68 insertions, 22 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 09f7779146b..01fd8e7d79a 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -575,6 +575,9 @@ public: bool d, bool p, bool w, unsigned r) :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, w, r)) {} + static bool isStructReturnInRegABI( + const llvm::Triple &Triple, const CodeGenOptions &Opts); + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const; @@ -1293,8 +1296,9 @@ static std::string qualifyWindowsLibrary(llvm::StringRef Lib) { class WinX86_32TargetCodeGenInfo : public X86_32TargetCodeGenInfo { public: - WinX86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned RegParms) - : X86_32TargetCodeGenInfo(CGT, false, true, true, RegParms) {} + WinX86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, + bool d, bool p, bool w, unsigned RegParms) + : X86_32TargetCodeGenInfo(CGT, d, p, w, RegParms) {} void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const { @@ -4444,6 +4448,36 @@ llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return ResAddr; } +bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( + const llvm::Triple &Triple, const CodeGenOptions &Opts) { + assert(Triple.getArch() == llvm::Triple::x86); + + switch (Opts.getStructReturnConvention()) { + case CodeGenOptions::SRCK_Default: + break; + case CodeGenOptions::SRCK_OnStack: // -fpcc-struct-return + return false; + case CodeGenOptions::SRCK_InRegs: // -freg-struct-return + return true; + } + + if (Triple.isOSDarwin()) + return true; + + switch (Triple.getOS()) { + case llvm::Triple::Cygwin: + case llvm::Triple::MinGW32: + case llvm::Triple::AuroraUX: + case llvm::Triple::DragonFly: + case llvm::Triple::FreeBSD: + case llvm::Triple::OpenBSD: + case llvm::Triple::Bitrig: + case llvm::Triple::Win32: + return true; + default: + return false; + } +} ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const { if (RetTy->isVoidType()) @@ -5506,31 +5540,22 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types)); case llvm::Triple::x86: { - if (Triple.isOSDarwin()) - return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, true, true, false, - CodeGenOpts.NumRegisterParameters)); + bool IsDarwinVectorABI = Triple.isOSDarwin(); + bool IsSmallStructInRegABI = + X86_32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts); + bool IsWin32FloatStructABI = (Triple.getOS() == llvm::Triple::Win32); - switch (Triple.getOS()) { - case llvm::Triple::Cygwin: - case llvm::Triple::MinGW32: - case llvm::Triple::AuroraUX: - case llvm::Triple::DragonFly: - case llvm::Triple::FreeBSD: - case llvm::Triple::OpenBSD: - case llvm::Triple::Bitrig: - return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, true, false, - CodeGenOpts.NumRegisterParameters)); - - case llvm::Triple::Win32: + if (Triple.getOS() == llvm::Triple::Win32) { return *(TheTargetCodeGenInfo = new WinX86_32TargetCodeGenInfo(Types, + IsDarwinVectorABI, IsSmallStructInRegABI, + IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters)); - - default: + } else { return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, false, false, + new X86_32TargetCodeGenInfo(Types, + IsDarwinVectorABI, IsSmallStructInRegABI, + IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters)); } } diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index add0c623aa2..373939cd933 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2165,6 +2165,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue()); } + if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return, options::OPT_freg_struct_return)) { + if (getToolChain().getTriple().getArch() != llvm::Triple::x86) { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << getToolChain().getTriple().str(); + } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) { + CmdArgs.push_back("-fpcc-struct-return"); + } else { + assert(A->getOption().matches(options::OPT_freg_struct_return)); + CmdArgs.push_back("-freg-struct-return"); + } + } + if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) CmdArgs.push_back("-mrtd"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 4e62fda4a34..1407e105f24 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -478,6 +478,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return)) { + if (A->getOption().matches(OPT_fpcc_struct_return)) { + Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack); + } else { + assert(A->getOption().matches(OPT_freg_struct_return)); + Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs); + } + } + return Success; } |