[llvm] 21bfd06 - [AArch64] Add support for the GNU ILP32 ABI

Amanieu d'Antras via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 20 05:36:15 PST 2021


Author: Amanieu d'Antras
Date: 2021-01-20T13:34:47Z
New Revision: 21bfd068b32ece1c6fbc912208e7cd1782a8c3fc

URL: https://github.com/llvm/llvm-project/commit/21bfd068b32ece1c6fbc912208e7cd1782a8c3fc
DIFF: https://github.com/llvm/llvm-project/commit/21bfd068b32ece1c6fbc912208e7cd1782a8c3fc.diff

LOG: [AArch64] Add support for the GNU ILP32 ABI

Add the aarch64[_be]-*-gnu_ilp32 targets to support the GNU ILP32 ABI for AArch64.

The needed codegen changes were mostly already implemented in D61259, which added support for the watchOS ILP32 ABI. The main changes are:
- Wiring up the new target to enable ILP32 codegen and MC.
- ILP32 va_list support.
- ILP32 TLSDESC relocation support.

There was existing MC support for ELF ILP32 relocations from D25159 which could be enabled by passing "-target-abi ilp32" to llvm-mc. This was changed to check for "gnu_ilp32" in the target triple instead. This shouldn't cause any issues since the existing support was slightly broken: it was generating ELF64 objects instead of the ELF32 object files expected by the GNU ILP32 toolchain.

This target has been tested by running the full rustc testsuite on a big-endian ILP32 system based on the GCC ILP32 toolchain.

Reviewed By: kristof.beyls

Differential Revision: https://reviews.llvm.org/D94143

Added: 
    llvm/test/CodeGen/AArch64/ilp32-tlsdesc.ll
    llvm/test/CodeGen/AArch64/ilp32-va.ll

Modified: 
    llvm/include/llvm/ADT/Triple.h
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/Support/Triple.cpp
    llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/lib/Target/AArch64/AArch64Subtarget.h
    llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
    llvm/test/MC/AArch64/adrp-relocation.s
    llvm/test/MC/AArch64/arm32-elf-relocs.s
    llvm/test/MC/AArch64/arm64-elf-reloc-condbr.s
    llvm/test/MC/AArch64/arm64-ilp32.s
    llvm/test/MC/AArch64/elf-reloc-ldrlit.s
    llvm/test/MC/AArch64/elf-reloc-tstb.s
    llvm/test/MC/AArch64/elf-reloc-uncondbrimm.s
    llvm/test/MC/AArch64/ilp32-diagnostics.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
index f6f015577351..eed315c929ad 100644
--- a/llvm/include/llvm/ADT/Triple.h
+++ b/llvm/include/llvm/ADT/Triple.h
@@ -209,6 +209,7 @@ class Triple {
     GNUEABI,
     GNUEABIHF,
     GNUX32,
+    GNUILP32,
     CODE16,
     EABI,
     EABIHF,
@@ -728,7 +729,10 @@ class Triple {
     assert(PointerWidth == 64 || PointerWidth == 32);
     if (!isAArch64())
       return false;
-    return isArch64Bit() ? PointerWidth == 64 : PointerWidth == 32;
+    return getArch() == Triple::aarch64_32 ||
+                   getEnvironment() == Triple::GNUILP32
+               ? PointerWidth == 32
+               : PointerWidth == 64;
   }
 
   /// Tests whether the target is MIPS 32-bit (little and big endian).

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 32e8393a88e5..4971838b08a0 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -181,11 +181,20 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
     // will be in memory. Most of these could end up >2GB away so even a signed
     // pc-relative 32-bit address is insufficient, theoretically.
     if (isPositionIndependent()) {
-      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
-        dwarf::DW_EH_PE_sdata8;
-      LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
-      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
-        dwarf::DW_EH_PE_sdata8;
+      // ILP32 uses sdata4 instead of sdata8
+      if (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32) {
+        PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+                              dwarf::DW_EH_PE_sdata4;
+        LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+        TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+                        dwarf::DW_EH_PE_sdata4;
+      } else {
+        PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+                              dwarf::DW_EH_PE_sdata8;
+        LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+        TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+                        dwarf::DW_EH_PE_sdata8;
+      }
     } else {
       PersonalityEncoding = dwarf::DW_EH_PE_absptr;
       LSDAEncoding = dwarf::DW_EH_PE_absptr;

diff  --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index 862087648067..1483684dd8e5 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -240,6 +240,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) {
   case GNUEABI: return "gnueabi";
   case GNUEABIHF: return "gnueabihf";
   case GNUX32: return "gnux32";
+  case GNUILP32: return "gnu_ilp32";
   case Itanium: return "itanium";
   case MSVC: return "msvc";
   case MacABI: return "macabi";
@@ -535,26 +536,27 @@ static Triple::OSType parseOS(StringRef OSName) {
 
 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
   return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
-    .StartsWith("eabihf", Triple::EABIHF)
-    .StartsWith("eabi", Triple::EABI)
-    .StartsWith("gnuabin32", Triple::GNUABIN32)
-    .StartsWith("gnuabi64", Triple::GNUABI64)
-    .StartsWith("gnueabihf", Triple::GNUEABIHF)
-    .StartsWith("gnueabi", Triple::GNUEABI)
-    .StartsWith("gnux32", Triple::GNUX32)
-    .StartsWith("code16", Triple::CODE16)
-    .StartsWith("gnu", Triple::GNU)
-    .StartsWith("android", Triple::Android)
-    .StartsWith("musleabihf", Triple::MuslEABIHF)
-    .StartsWith("musleabi", Triple::MuslEABI)
-    .StartsWith("musl", Triple::Musl)
-    .StartsWith("msvc", Triple::MSVC)
-    .StartsWith("itanium", Triple::Itanium)
-    .StartsWith("cygnus", Triple::Cygnus)
-    .StartsWith("coreclr", Triple::CoreCLR)
-    .StartsWith("simulator", Triple::Simulator)
-    .StartsWith("macabi", Triple::MacABI)
-    .Default(Triple::UnknownEnvironment);
+      .StartsWith("eabihf", Triple::EABIHF)
+      .StartsWith("eabi", Triple::EABI)
+      .StartsWith("gnuabin32", Triple::GNUABIN32)
+      .StartsWith("gnuabi64", Triple::GNUABI64)
+      .StartsWith("gnueabihf", Triple::GNUEABIHF)
+      .StartsWith("gnueabi", Triple::GNUEABI)
+      .StartsWith("gnux32", Triple::GNUX32)
+      .StartsWith("gnu_ilp32", Triple::GNUILP32)
+      .StartsWith("code16", Triple::CODE16)
+      .StartsWith("gnu", Triple::GNU)
+      .StartsWith("android", Triple::Android)
+      .StartsWith("musleabihf", Triple::MuslEABIHF)
+      .StartsWith("musleabi", Triple::MuslEABI)
+      .StartsWith("musl", Triple::Musl)
+      .StartsWith("msvc", Triple::MSVC)
+      .StartsWith("itanium", Triple::Itanium)
+      .StartsWith("cygnus", Triple::Cygnus)
+      .StartsWith("coreclr", Triple::CoreCLR)
+      .StartsWith("simulator", Triple::Simulator)
+      .StartsWith("macabi", Triple::MacABI)
+      .Default(Triple::UnknownEnvironment);
 }
 
 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {

diff  --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index c7fa49c965a8..a0c5498ee620 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -1272,17 +1272,28 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     EmitToStreamer(*OutStreamer, Adrp);
 
     MCInst Ldr;
-    Ldr.setOpcode(AArch64::LDRXui);
-    Ldr.addOperand(MCOperand::createReg(AArch64::X1));
+    if (STI->isTargetILP32()) {
+      Ldr.setOpcode(AArch64::LDRWui);
+      Ldr.addOperand(MCOperand::createReg(AArch64::W1));
+    } else {
+      Ldr.setOpcode(AArch64::LDRXui);
+      Ldr.addOperand(MCOperand::createReg(AArch64::X1));
+    }
     Ldr.addOperand(MCOperand::createReg(AArch64::X0));
     Ldr.addOperand(SymTLSDescLo12);
     Ldr.addOperand(MCOperand::createImm(0));
     EmitToStreamer(*OutStreamer, Ldr);
 
     MCInst Add;
-    Add.setOpcode(AArch64::ADDXri);
-    Add.addOperand(MCOperand::createReg(AArch64::X0));
-    Add.addOperand(MCOperand::createReg(AArch64::X0));
+    if (STI->isTargetILP32()) {
+      Add.setOpcode(AArch64::ADDWri);
+      Add.addOperand(MCOperand::createReg(AArch64::W0));
+      Add.addOperand(MCOperand::createReg(AArch64::W0));
+    } else {
+      Add.setOpcode(AArch64::ADDXri);
+      Add.addOperand(MCOperand::createReg(AArch64::X0));
+      Add.addOperand(MCOperand::createReg(AArch64::X0));
+    }
     Add.addOperand(SymTLSDescLo12);
     Add.addOperand(MCOperand::createImm(AArch64_AM::getShiftValue(0)));
     EmitToStreamer(*OutStreamer, Add);

diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index cc64e0e03ad8..c7bcd4de046c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7011,11 +7011,13 @@ SDValue AArch64TargetLowering::LowerWin64_VASTART(SDValue Op,
 }
 
 SDValue AArch64TargetLowering::LowerAAPCS_VASTART(SDValue Op,
-                                                SelectionDAG &DAG) const {
+                                                  SelectionDAG &DAG) const {
   // The layout of the va_list struct is specified in the AArch64 Procedure Call
   // Standard, section B.3.
   MachineFunction &MF = DAG.getMachineFunction();
   AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
+  unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8;
+  auto PtrMemVT = getPointerMemTy(DAG.getDataLayout());
   auto PtrVT = getPointerTy(DAG.getDataLayout());
   SDLoc DL(Op);
 
@@ -7025,54 +7027,64 @@ SDValue AArch64TargetLowering::LowerAAPCS_VASTART(SDValue Op,
   SmallVector<SDValue, 4> MemOps;
 
   // void *__stack at offset 0
+  unsigned Offset = 0;
   SDValue Stack = DAG.getFrameIndex(FuncInfo->getVarArgsStackIndex(), PtrVT);
-  MemOps.push_back(
-      DAG.getStore(Chain, DL, Stack, VAList, MachinePointerInfo(SV), Align(8)));
+  Stack = DAG.getZExtOrTrunc(Stack, DL, PtrMemVT);
+  MemOps.push_back(DAG.getStore(Chain, DL, Stack, VAList,
+                                MachinePointerInfo(SV), Align(PtrSize)));
 
-  // void *__gr_top at offset 8
+  // void *__gr_top at offset 8 (4 on ILP32)
+  Offset += PtrSize;
   int GPRSize = FuncInfo->getVarArgsGPRSize();
   if (GPRSize > 0) {
     SDValue GRTop, GRTopAddr;
 
-    GRTopAddr =
-        DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getConstant(8, DL, PtrVT));
+    GRTopAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
+                            DAG.getConstant(Offset, DL, PtrVT));
 
     GRTop = DAG.getFrameIndex(FuncInfo->getVarArgsGPRIndex(), PtrVT);
     GRTop = DAG.getNode(ISD::ADD, DL, PtrVT, GRTop,
                         DAG.getConstant(GPRSize, DL, PtrVT));
+    GRTop = DAG.getZExtOrTrunc(GRTop, DL, PtrMemVT);
 
     MemOps.push_back(DAG.getStore(Chain, DL, GRTop, GRTopAddr,
-                                  MachinePointerInfo(SV, 8), Align(8)));
+                                  MachinePointerInfo(SV, Offset),
+                                  Align(PtrSize)));
   }
 
-  // void *__vr_top at offset 16
+  // void *__vr_top at offset 16 (8 on ILP32)
+  Offset += PtrSize;
   int FPRSize = FuncInfo->getVarArgsFPRSize();
   if (FPRSize > 0) {
     SDValue VRTop, VRTopAddr;
     VRTopAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
-                            DAG.getConstant(16, DL, PtrVT));
+                            DAG.getConstant(Offset, DL, PtrVT));
 
     VRTop = DAG.getFrameIndex(FuncInfo->getVarArgsFPRIndex(), PtrVT);
     VRTop = DAG.getNode(ISD::ADD, DL, PtrVT, VRTop,
                         DAG.getConstant(FPRSize, DL, PtrVT));
+    VRTop = DAG.getZExtOrTrunc(VRTop, DL, PtrMemVT);
 
     MemOps.push_back(DAG.getStore(Chain, DL, VRTop, VRTopAddr,
-                                  MachinePointerInfo(SV, 16), Align(8)));
+                                  MachinePointerInfo(SV, Offset),
+                                  Align(PtrSize)));
   }
 
-  // int __gr_offs at offset 24
-  SDValue GROffsAddr =
-      DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getConstant(24, DL, PtrVT));
+  // int __gr_offs at offset 24 (12 on ILP32)
+  Offset += PtrSize;
+  SDValue GROffsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
+                                   DAG.getConstant(Offset, DL, PtrVT));
   MemOps.push_back(
       DAG.getStore(Chain, DL, DAG.getConstant(-GPRSize, DL, MVT::i32),
-                   GROffsAddr, MachinePointerInfo(SV, 24), Align(4)));
+                   GROffsAddr, MachinePointerInfo(SV, Offset), Align(4)));
 
-  // int __vr_offs at offset 28
-  SDValue VROffsAddr =
-      DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getConstant(28, DL, PtrVT));
+  // int __vr_offs at offset 28 (16 on ILP32)
+  Offset += 4;
+  SDValue VROffsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
+                                   DAG.getConstant(Offset, DL, PtrVT));
   MemOps.push_back(
       DAG.getStore(Chain, DL, DAG.getConstant(-FPRSize, DL, MVT::i32),
-                   VROffsAddr, MachinePointerInfo(SV, 28), Align(4)));
+                   VROffsAddr, MachinePointerInfo(SV, Offset), Align(4)));
 
   return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
 }
@@ -7095,8 +7107,10 @@ SDValue AArch64TargetLowering::LowerVACOPY(SDValue Op,
   // pointer.
   SDLoc DL(Op);
   unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8;
-  unsigned VaListSize = (Subtarget->isTargetDarwin() ||
-                         Subtarget->isTargetWindows()) ? PtrSize : 32;
+  unsigned VaListSize =
+      (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
+          ? PtrSize
+          : Subtarget->isTargetILP32() ? 20 : 32;
   const Value *DestSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
   const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
 

diff  --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 1b89b87d41d2..b34911eafdd2 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -482,7 +482,10 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
 
-  bool isTargetILP32() const { return TargetTriple.isArch32Bit(); }
+  bool isTargetILP32() const {
+    return TargetTriple.isArch32Bit() ||
+           TargetTriple.getEnvironment() == Triple::GNUILP32;
+  }
 
   bool useAA() const override { return UseAA; }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index 154aebf16936..bec1758a931b 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -215,8 +215,6 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
 static std::string computeDataLayout(const Triple &TT,
                                      const MCTargetOptions &Options,
                                      bool LittleEndian) {
-  if (Options.getABIName() == "ilp32")
-    return "e-m:e-p:32:32-i8:8-i16:16-i64:64-S128";
   if (TT.isOSBinFormatMachO()) {
     if (TT.getArch() == Triple::aarch64_32)
       return "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128";
@@ -224,9 +222,10 @@ static std::string computeDataLayout(const Triple &TT,
   }
   if (TT.isOSBinFormatCOFF())
     return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128";
-  if (LittleEndian)
-    return "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
-  return "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
+  std::string Endian = LittleEndian ? "e" : "E";
+  std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
+  return Endian + "-m:e" + Ptr32 +
+         "-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
 }
 
 static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) {
@@ -318,6 +317,7 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
   // MachO/CodeModel::Large, which GlobalISel does not support.
   if (getOptLevel() <= EnableGlobalISelAtO &&
       TT.getArch() != Triple::aarch64_32 &&
+      TT.getEnvironment() != Triple::GNUILP32 &&
       !(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO())) {
     setGlobalISel(true);
     setGlobalISelAbort(GlobalISelAbortMode::Disable);

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 2df9a8050e66..ac719335f254 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -271,7 +271,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
                    const MCInstrInfo &MII, const MCTargetOptions &Options)
     : MCTargetAsmParser(Options, STI, MII) {
-    IsILP32 = Options.getABIName() == "ilp32";
+    IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
     MCAsmParserExtension::Initialize(Parser);
     MCStreamer &S = getParser().getStreamer();
     if (S.getTargetStreamer() == nullptr)

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index a355cbf30d31..75a9f2f5c80e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -758,7 +758,7 @@ MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T,
   assert(TheTriple.isOSBinFormatELF() && "Invalid target");
 
   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
-  bool IsILP32 = Options.getABIName() == "ilp32";
+  bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
   return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/true,
                                   IsILP32);
 }
@@ -771,7 +771,7 @@ MCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T,
   assert(TheTriple.isOSBinFormatELF() &&
          "Big endian is only supported for ELF targets!");
   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
-  bool IsILP32 = Options.getABIName() == "ilp32";
+  bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
   return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/false,
                                   IsILP32);
 }

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index e5637dcab941..4a1b4f36af70 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -43,7 +43,7 @@ class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
 } // end anonymous namespace
 
 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
-    : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
+    : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
                               /*HasRelocationAddend*/ true),
       IsILP32(IsILP32) {}
 

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index 9a63e26dec19..37c924d879b1 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -73,7 +73,7 @@ AArch64MCAsmInfoELF::AArch64MCAsmInfoELF(const Triple &T) {
   // targeting ELF.
   AssemblerDialect = AsmWriterVariant == Default ? Generic : AsmWriterVariant;
 
-  CodePointerSize = 8;
+  CodePointerSize = T.getEnvironment() == Triple::GNUILP32 ? 4 : 8;
 
   // ".comm align is in bytes but .align is pow-2."
   AlignmentIsInBytes = false;

diff  --git a/llvm/test/CodeGen/AArch64/ilp32-tlsdesc.ll b/llvm/test/CodeGen/AArch64/ilp32-tlsdesc.ll
new file mode 100644
index 000000000000..89a8fff47f4f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ilp32-tlsdesc.ll
@@ -0,0 +1,22 @@
+; RUN: llc -mtriple=aarch64-linux-gnu_ilp32 -relocation-model=pic %s -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-linux-gnu_ilp32 -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
+
+ at var = thread_local global i32 zeroinitializer
+
+define i32 @test_thread_local() {
+; CHECK-LABEL: test_thread_local:
+
+  %val = load i32, i32* @var
+  ret i32 %val
+
+; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:var
+; CHECK-NEXT: ldr w[[CALLEE:[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:var]
+; CHECK-NEXT: add w0, w[[TLSDESC_HI]], :tlsdesc_lo12:var
+; CHECK-NEXT: .tlsdesccall var
+; CHECK-NEXT: blr x[[CALLEE]]
+
+; CHECK-RELOC: R_AARCH64_P32_TLSDESC_ADR_PAGE21
+; CHECK-RELOC: R_AARCH64_P32_TLSDESC_LD32_LO12
+; CHECK-RELOC: R_AARCH64_P32_TLSDESC_ADD_LO12
+; CHECK-RELOC: R_AARCH64_P32_TLSDESC_CALL
+}

diff  --git a/llvm/test/CodeGen/AArch64/ilp32-va.ll b/llvm/test/CodeGen/AArch64/ilp32-va.ll
new file mode 100644
index 000000000000..402fb6971ab0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ilp32-va.ll
@@ -0,0 +1,142 @@
+; RUN: llc -aarch64-load-store-renaming=true -verify-machineinstrs -mtriple=arm64-linux-gnu_ilp32 -pre-RA-sched=linearize -enable-misched=false -disable-post-ra < %s | FileCheck %s
+
+%va_list = type {i8*, i8*, i8*, i32, i32}
+
+ at var = dso_local global %va_list zeroinitializer, align 8
+
+declare void @llvm.va_start(i8*)
+
+define dso_local void @test_simple(i32 %n, ...) {
+; CHECK-LABEL: test_simple:
+; CHECK: sub sp, sp, #[[STACKSIZE:[0-9]+]]
+; CHECK: add x[[STACK_TOP:[0-9]+]], sp, #[[STACKSIZE]]
+
+; CHECK: adrp x[[VA_LIST_HI:[0-9]+]], var
+; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, :lo12:var
+
+; CHECK-DAG: stp x6, x7, [sp, #
+; ... omit middle ones ...
+; CHECK-DAG: str x1, [sp, #[[GR_BASE:[0-9]+]]]
+
+; CHECK-DAG: stp q0, q1, [sp]
+; ... omit middle ones ...
+; CHECK-DAG: stp q6, q7, [sp, #
+
+; CHECK: str w[[STACK_TOP]], [x[[VA_LIST]]]
+
+; CHECK: add x[[GR_TOPTMP:[0-9]+]], sp, #[[GR_BASE]]
+; CHECK: add [[GR_TOP:w[0-9]+]], w[[GR_TOPTMP]], #56
+
+
+; CHECK: mov x[[VR_TOPTMP:[0-9]+]], sp
+; CHECK: add [[VR_TOP:w[0-9]+]], w[[VR_TOPTMP]], #128
+; CHECK: stp [[GR_TOP]], [[VR_TOP]], [x[[VA_LIST]], #4]
+
+; CHECK: mov     [[GRVR:x[0-9]+]], #-56
+; CHECK: movk    [[GRVR]], #65408, lsl #32
+; CHECK: stur    [[GRVR]], [x[[VA_LIST]], #12]
+
+  %addr = bitcast %va_list* @var to i8*
+  call void @llvm.va_start(i8* %addr)
+
+  ret void
+}
+
+define dso_local void @test_fewargs(i32 %n, i32 %n1, i32 %n2, float %m, ...) {
+; CHECK-LABEL: test_fewargs:
+; CHECK: sub sp, sp, #[[STACKSIZE:[0-9]+]]
+; CHECK: add x[[STACK_TOP:[0-9]+]], sp, #[[STACKSIZE]]
+
+; CHECK: adrp x[[VA_LIST_HI:[0-9]+]], var
+; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, :lo12:var
+
+; CHECK-DAG: stp x6, x7, [sp, #
+; ... omit middle ones ...
+; CHECK-DAG: str x3, [sp, #[[GR_BASE:[0-9]+]]]
+
+; CHECK-DAG: stp q6, q7, [sp, #80]
+; ... omit middle ones ...
+; CHECK-DAG: str q1, [sp]
+
+; CHECK: str w[[STACK_TOP]], [x[[VA_LIST]]]
+
+; CHECK: add x[[GR_TOPTMP:[0-9]+]], sp, #[[GR_BASE]]
+; CHECK: add [[GR_TOP:w[0-9]+]], w[[GR_TOPTMP]], #40
+
+; CHECK: mov x[[VR_TOPTMP:[0-9]+]], sp
+; CHECK: add [[VR_TOP:w[0-9]+]], w[[VR_TOPTMP]], #112
+; CHECK: stp [[GR_TOP]], [[VR_TOP]], [x[[VA_LIST]], #4]
+
+; CHECK: mov  [[GRVR_OFFS:x[0-9]+]], #-40
+; CHECK: movk [[GRVR_OFFS]], #65424, lsl #32
+; CHECK: stur [[GRVR_OFFS]], [x[[VA_LIST]], #12]
+
+  %addr = bitcast %va_list* @var to i8*
+  call void @llvm.va_start(i8* %addr)
+
+  ret void
+}
+
+define dso_local void @test_nospare([8 x i64], [8 x float], ...) {
+; CHECK-LABEL: test_nospare:
+
+  %addr = bitcast %va_list* @var to i8*
+  call void @llvm.va_start(i8* %addr)
+; CHECK-NOT: sub sp, sp
+; CHECK: mov x[[STACK:[0-9]+]], sp
+; CHECK: add x[[VAR:[0-9]+]], {{x[0-9]+}}, :lo12:var
+; CHECK: str w[[STACK]], [x[[VAR]]]
+
+  ret void
+}
+
+; If there are non-variadic arguments on the stack (here two i64s) then the
+; __stack field should point just past them.
+define dso_local void @test_offsetstack([8 x i64], [2 x i64], [3 x float], ...) {
+; CHECK-LABEL: test_offsetstack:
+
+; CHECK-DAG: stp {{q[0-9]+}}, {{q[0-9]+}}, [sp, #48]
+; CHECK-DAG: stp {{q[0-9]+}}, {{q[0-9]+}}, [sp, #16]
+; CHECK-DAG: str {{q[0-9]+}}, [sp]
+; CHECK-DAG: add x[[STACK_TOP:[0-9]+]], sp, #96
+; CHECK-DAG: add x[[VAR:[0-9]+]], {{x[0-9]+}}, :lo12:var
+; CHECK-DAG: str w[[STACK_TOP]], [x[[VAR]]]
+
+  %addr = bitcast %va_list* @var to i8*
+  call void @llvm.va_start(i8* %addr)
+  ret void
+}
+
+declare void @llvm.va_end(i8*)
+
+define dso_local void @test_va_end() nounwind {
+; CHECK-LABEL: test_va_end:
+; CHECK-NEXT: %bb.0
+
+  %addr = bitcast %va_list* @var to i8*
+  call void @llvm.va_end(i8* %addr)
+
+  ret void
+; CHECK-NEXT: ret
+}
+
+declare void @llvm.va_copy(i8* %dest, i8* %src)
+
+ at second_list = dso_local global %va_list zeroinitializer
+
+define dso_local void @test_va_copy() {
+; CHECK-LABEL: test_va_copy:
+  %srcaddr = bitcast %va_list* @var to i8*
+  %dstaddr = bitcast %va_list* @second_list to i8*
+  call void @llvm.va_copy(i8* %dstaddr, i8* %srcaddr)
+
+; CHECK: add x[[SRC:[0-9]+]], {{x[0-9]+}}, :lo12:var
+
+; CHECK: ldr [[BLOCK:q[0-9]+]], [x[[SRC]]]
+; CHECK: add x[[DST:[0-9]+]], {{x[0-9]+}}, :lo12:second_list
+; CHECK: ldr [[BLOCK:w[0-9]+]], [x[[SRC]], #16]
+; CHECK: str [[BLOCK:q[0-9]+]], [x[[DST]]]
+; CHECK: str [[BLOCK:w[0-9]+]], [x[[DST]], #16]
+  ret void
+; CHECK: ret
+}

diff  --git a/llvm/test/MC/AArch64/adrp-relocation.s b/llvm/test/MC/AArch64/adrp-relocation.s
index 474a1ee5145a..62c6ef0fb9a1 100644
--- a/llvm/test/MC/AArch64/adrp-relocation.s
+++ b/llvm/test/MC/AArch64/adrp-relocation.s
@@ -1,5 +1,5 @@
 // RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj -o - %s| llvm-readobj -r - | FileCheck %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=aarch64-linux-gnu -filetype=obj \
+// RUN: llvm-mc -triple=aarch64-linux-gnu_ilp32 -filetype=obj \
 // RUN: -o - %s| llvm-readobj -r - | FileCheck -check-prefix=CHECK-ILP32 %s
         .text
 // This tests that LLVM doesn't think it can deal with the relocation on the ADRP

diff  --git a/llvm/test/MC/AArch64/arm32-elf-relocs.s b/llvm/test/MC/AArch64/arm32-elf-relocs.s
index a4d2ebd80e1e..3c0218cd3d44 100644
--- a/llvm/test/MC/AArch64/arm32-elf-relocs.s
+++ b/llvm/test/MC/AArch64/arm32-elf-relocs.s
@@ -1,8 +1,7 @@
-// RUN: llvm-mc -target-abi=ilp32 -triple=arm64-linux-gnu -o - < %s | \
-// RUN:   FileCheck %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=arm64-linux-gnu -show-encoding \
+// RUN: llvm-mc -triple=arm64-linux-gnu_ilp32 -o - < %s | FileCheck %s
+// RUN: llvm-mc -triple=arm64-linux-gnu_ilp32 -show-encoding \
 // RUN:    -o - < %s | FileCheck --check-prefix=CHECK-ENCODING %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=arm64-linux-gnu -filetype=obj < %s | \
+// RUN: llvm-mc -triple=arm64-linux-gnu_ilp32 -filetype=obj < %s | \
 // RUN:   llvm-objdump --triple=arm64-linux-gnu - -r | \
 // RUN:   FileCheck %s --check-prefix=CHECK-OBJ-ILP32
 

diff  --git a/llvm/test/MC/AArch64/arm64-elf-reloc-condbr.s b/llvm/test/MC/AArch64/arm64-elf-reloc-condbr.s
index 80c94f6df423..78cff7c3411a 100644
--- a/llvm/test/MC/AArch64/arm64-elf-reloc-condbr.s
+++ b/llvm/test/MC/AArch64/arm64-elf-reloc-condbr.s
@@ -1,7 +1,6 @@
 // RUN: llvm-mc -triple=arm64-none-linux-gnu -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=arm64-none-linux-gnu -filetype=obj \
-// RUN:   %s -o - | \
+// RUN: llvm-mc -triple=arm64-none-linux-gnu_ilp32 -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ-ILP32 %s
 
         b.eq somewhere

diff  --git a/llvm/test/MC/AArch64/arm64-ilp32.s b/llvm/test/MC/AArch64/arm64-ilp32.s
index 182d2d4c9e74..7de114e878f9 100644
--- a/llvm/test/MC/AArch64/arm64-ilp32.s
+++ b/llvm/test/MC/AArch64/arm64-ilp32.s
@@ -1,6 +1,6 @@
-// RUN: llvm-mc -target-abi=ilp32 -triple aarch64-non-linux-gnu -filetype=obj \
+// RUN: llvm-mc -triple aarch64-non-linux-gnu_ilp32 -filetype=obj \
 // RUN:  %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-ILP32 %s
-// RUN: llvm-mc                   -triple aarch64-non-linux-gnu -filetype=obj \
+// RUN: llvm-mc -triple aarch64-non-linux-gnu -filetype=obj \
 // RUN:  %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-LP64 %s
 	.text
 	.file	"../projects/clang/test/Driver/arm64-ilp32.c"
@@ -10,8 +10,8 @@
 foo:                                    // @foo
 // %bb.0:                               // %entry
 	sub	sp, sp, #16             // =16
-// CHECK-ILP32: 0000000000000004 R_AARCH64_P32_ADR_PREL_PG_HI21 sizes
-// CHECK-ILP32: 0000000000000008 R_AARCH64_P32_ADD_ABS_LO12_NC sizes
+// CHECK-ILP32: 00000004 R_AARCH64_P32_ADR_PREL_PG_HI21 sizes
+// CHECK-ILP32: 00000008 R_AARCH64_P32_ADD_ABS_LO12_NC sizes
 // CHECK-LP64:  0000000000000004 R_AARCH64_ADR_PREL_PG_HI21 sizes
 // CHECK-LP64:  0000000000000008 R_AARCH64_ADD_ABS_LO12_NC sizes
 	adrp	x8, sizes

diff  --git a/llvm/test/MC/AArch64/elf-reloc-ldrlit.s b/llvm/test/MC/AArch64/elf-reloc-ldrlit.s
index 6a23aae41032..b3abc946ffa3 100644
--- a/llvm/test/MC/AArch64/elf-reloc-ldrlit.s
+++ b/llvm/test/MC/AArch64/elf-reloc-ldrlit.s
@@ -1,7 +1,6 @@
 // RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=aarch64-none-linux-gnu \
-// RUN:   -filetype=obj %s -o - | \
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu_ilp32 -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ-ILP32 %s
 
         ldr x0, some_label

diff  --git a/llvm/test/MC/AArch64/elf-reloc-tstb.s b/llvm/test/MC/AArch64/elf-reloc-tstb.s
index 5d8a91ec4707..b6852b182ec6 100644
--- a/llvm/test/MC/AArch64/elf-reloc-tstb.s
+++ b/llvm/test/MC/AArch64/elf-reloc-tstb.s
@@ -1,7 +1,6 @@
 // RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=aarch64-none-linux-gnu \
-// RUN:   -filetype=obj %s -o - | \
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu_ilp32 -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ-ILP32 %s
 
         tbz x6, #45, somewhere

diff  --git a/llvm/test/MC/AArch64/elf-reloc-uncondbrimm.s b/llvm/test/MC/AArch64/elf-reloc-uncondbrimm.s
index ac788815b789..71dbbf5ebf74 100644
--- a/llvm/test/MC/AArch64/elf-reloc-uncondbrimm.s
+++ b/llvm/test/MC/AArch64/elf-reloc-uncondbrimm.s
@@ -1,7 +1,6 @@
 // RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ %s
-// RUN: llvm-mc -target-abi=ilp32 -triple=aarch64-none-linux-gnu \
-// RUN:   -filetype=obj %s -o - | \
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu_ilp32 -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r - | FileCheck -check-prefix=OBJ-ILP32 %s
 
         b somewhere

diff  --git a/llvm/test/MC/AArch64/ilp32-diagnostics.s b/llvm/test/MC/AArch64/ilp32-diagnostics.s
index f8fd41cfa2f3..65c9e4ea5a1c 100644
--- a/llvm/test/MC/AArch64/ilp32-diagnostics.s
+++ b/llvm/test/MC/AArch64/ilp32-diagnostics.s
@@ -1,4 +1,4 @@
-// RUN: not llvm-mc -triple aarch64-none-linux-gnu -target-abi=ilp32 \
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu_ilp32 \
 // RUN:  < %s 2> %t2 -filetype=obj >/dev/null
 // RUN: FileCheck --check-prefix=CHECK-ERROR %s < %t2
 


        


More information about the llvm-commits mailing list