diff --git a/clang/lib/Driver/ToolChains/AIX.h b/clang/lib/Driver/ToolChains/AIX.h --- a/clang/lib/Driver/ToolChains/AIX.h +++ b/clang/lib/Driver/ToolChains/AIX.h @@ -16,10 +16,21 @@ namespace driver { namespace tools { -/// aix -- Directly call system default linker. -// TODO: Enable direct call to system default assembler. +/// aix -- Directly call system default assembler and linker. namespace aix { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { +public: + Assembler(const ToolChain &TC) : Tool("aix::Assembler", "assembler", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; + class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: Linker(const ToolChain &TC) : Tool("aix::Linker", "linker", TC) {} @@ -53,6 +64,7 @@ bool isPICDefaultForced() const override { return true; } protected: + Tool *buildAssembler() const override; Tool *buildLinker() const override; }; diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -20,6 +20,47 @@ using namespace llvm::opt; +void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + claimNoWarnArgs(Args); + ArgStringList CmdArgs; + + const bool IsArch32Bit = getToolChain().getTriple().isArch32Bit(); + const bool IsArch64Bit = getToolChain().getTriple().isArch64Bit(); + // Only support 32 and 64 bit. + if (!IsArch32Bit && !IsArch64Bit) + llvm_unreachable("Unsupported bit width value."); + + // Specify the mode in which the as command operates. + if (IsArch32Bit) { + CmdArgs.push_back("-a32"); + } else { + // Must be 64-bit, otherwise asserted already. + CmdArgs.push_back("-a64"); + } + // Acccept any mixture of instructions. + CmdArgs.push_back("-many"); + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); + + // Specify assembler output file. + assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } + + // Specify assembler input file(s). + for (const auto &II : Inputs) + CmdArgs.push_back(II.getFilename()); + + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); + C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); +} + void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -42,7 +83,7 @@ if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - } + } // Set linking mode (i.e., 32/64-bit) and the address of // text and data sections based on arch bit width. @@ -92,11 +133,12 @@ C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); } -/// AIX - AIX tool chain which can call ld(1) directly. -// TODO: Enable direct call to as(1). +/// AIX - AIX tool chain which can call as(1) and ld(1) directly. AIX::AIX(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : ToolChain(D, Triple, Args) { getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); } +auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); } + auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); } diff --git a/clang/test/Driver/aix-as.c b/clang/test/Driver/aix-as.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/aix-as.c @@ -0,0 +1,48 @@ +// General tests that as invocations on AIX targets are sane. Note that we +// only test assembler functionalities in this suite. + +// Check powerpc-ibm-aix7.1.0.0, 32-bit. +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target powerpc-ibm-aix7.1.0.0 \ +// RUN: | FileCheck --check-prefix=CHECK-AS32 %s +// CHECK-AS32-NOT: warning: +// CHECK-AS32: {{.*}}clang{{(.exe)?}}" "-cc1" "-triple" "powerpc-ibm-aix7.1.0.0" +// CHECK-AS32: "{{.*}}as{{(.exe)?}}" +// CHECK-AS32: "-a32" +// CHECK-AS32: "-many" + +// Check powerpc64-ibm-aix7.1.0.0, 64-bit. +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -target powerpc64-ibm-aix7.1.0.0 \ +// RUN: | FileCheck --check-prefix=CHECK-AS64 %s +// CHECK-AS64-NOT: warning: +// CHECK-AS64: {{.*}}clang{{(.exe)?}}" "-cc1" "-triple" "powerpc64-ibm-aix7.1.0.0" +// CHECK-AS64: "{{.*}}as{{(.exe)?}}" +// CHECK-AS64: "-a64" +// CHECK-AS64: "-many" + + +// Check powerpc-ibm-aix7.1.0.0, 32-bit. -Xassembler option. +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -Xassembler -w \ +// RUN: -target powerpc-ibm-aix7.1.0.0 \ +// RUN: | FileCheck --check-prefix=CHECK-AS32-PTHREAD %s +// CHECK-AS32-PTHREAD-NOT: warning: +// CHECK-AS32-PTHREAD: {{.*}}clang{{(.exe)?}}" "-cc1" "-triple" "powerpc-ibm-aix7.1.0.0" +// CHECK-AS32-PTHREAD: "{{.*}}as{{(.exe)?}}" +// CHECK-AS32-PTHREAD: "-a32" +// CHECK-AS32-PTHREAD: "-many" +// CHECK-AS32-PTHREAD: "-w" + +// Check powerpc-ibm-aix7.1.0.0, 64-bit. -Wa,, option. +// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \ +// RUN: -Wa,-v,-w \ +// RUN: -target powerpc64-ibm-aix7.1.0.0 \ +// RUN: | FileCheck --check-prefix=CHECK-AS64-PTHREAD %s +// CHECK-AS64-PTHREAD-NOT: warning: +// CHECK-AS64-PTHREAD: {{.*}}clang{{(.exe)?}}" "-cc1" "-triple" "powerpc64-ibm-aix7.1.0.0" +// CHECK-AS64-PTHREAD: "{{.*}}as{{(.exe)?}}" +// CHECK-AS64-PTHREAD: "-a64" +// CHECK-AS64-PTHREAD: "-many" +// CHECK-AS64-PTHREAD: "-v" +// CHECK-AS64-PTHREAD: "-w"