diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -385,12 +385,29 @@ IntMaxType = SignedLong; Int64Type = SignedLong; + if (Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) { + switch (Triple.getEnvironment()){ + case llvm::Triple::ELFv1: + ABI = "elfv1"; + break; + default: + ABI = "elfv2"; + break; + } + } else { + if ((Triple.getOS() == llvm::Triple::FreeBSD) && + (Triple.getOSMajorVersion() < 13)) { + ABI = "elfv1"; + } else { + ABI = "elfv2"; + } + } + + if ((Triple.getArch() == llvm::Triple::ppc64le)) { resetDataLayout("e-m:e-i64:64-n32:64"); - ABI = "elfv2"; } else { resetDataLayout("E-m:e-i64:64-n32:64"); - ABI = Triple.getEnvironment() == llvm::Triple::ELFv2 ? "elfv2" : "elfv1"; } if (Triple.getOS() == llvm::Triple::AIX) diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp --- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -199,7 +199,7 @@ const TargetOptions &Options) { if (TT.isOSDarwin()) report_fatal_error("Darwin is no longer supported for PowerPC"); - + if (Options.MCOptions.getABIName().startswith("elfv1")) return PPCTargetMachine::PPC_ABI_ELFv1; else if (Options.MCOptions.getABIName().startswith("elfv2")) @@ -208,9 +208,28 @@ assert(Options.MCOptions.getABIName().empty() && "Unknown target-abi option!"); + if (TT.getEnvironment() == llvm::Triple::ELFv1) + return PPCTargetMachine::PPC_ABI_ELFv1; + else if (TT.getEnvironment() == llvm::Triple::ELFv2) + return PPCTargetMachine::PPC_ABI_ELFv2; + if (TT.isMacOSX()) return PPCTargetMachine::PPC_ABI_UNKNOWN; + if (TT.isOSFreeBSD()) { + switch (TT.getArch()) { + case Triple::ppc64le: + case Triple::ppc64: + if (TT.getOSMajorVersion() >= 13) + return PPCTargetMachine::PPC_ABI_ELFv2; + else + return PPCTargetMachine::PPC_ABI_ELFv1; + case Triple::ppc: + default: + return PPCTargetMachine::PPC_ABI_UNKNOWN; + } + } + switch (TT.getArch()) { case Triple::ppc64le: return PPCTargetMachine::PPC_ABI_ELFv2; diff --git a/llvm/test/CodeGen/PowerPC/ppc64-elf-abi.ll b/llvm/test/CodeGen/PowerPC/ppc64-elf-abi.ll --- a/llvm/test/CodeGen/PowerPC/ppc64-elf-abi.ll +++ b/llvm/test/CodeGen/PowerPC/ppc64-elf-abi.ll @@ -5,6 +5,30 @@ ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -target-abi elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -target-abi elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd11 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd12 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd13 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd14 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd11 -target-abi elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd11 -target-abi elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd12 -target-abi elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd12 -target-abi elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd13 -target-abi elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd13 -target-abi elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd14 -target-abi elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd14 -target-abi elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 + +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd11-elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd11-elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd12-elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd12-elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd13-elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd13-elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd14-elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd14-elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2 + +; FreeBSD target triple without OS version number is incorrect, but checking for regressions anyway +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd < %s | FileCheck %s -check-prefix=CHECK-ELFv1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd < %s | FileCheck %s -check-prefix=CHECK-ELFv1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd -target-abi elfv1 < %s | FileCheck %s -check-prefix=CHECK-ELFv1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-freebsd -target-abi elfv2 < %s | FileCheck %s -check-prefix=CHECK-ELFv2