diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -209,6 +209,7 @@ GNUEABI, GNUEABIHF, GNUX32, + GNUILP32, CODE16, EABI, EABIHF, @@ -222,7 +223,7 @@ Cygnus, CoreCLR, Simulator, // Simulator variants of other systems, e.g., Apple's iOS - MacABI, // Mac Catalyst variant of Apple's iOS deployment target. + MacABI, // Mac Catalyst variant of Apple's iOS deployment target. LastEnvironmentType = MacABI }; enum ObjectFormatType { @@ -728,7 +729,10 @@ 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 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -181,11 +181,20 @@ // 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 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -240,6 +240,8 @@ 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 +537,27 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { return StringSwitch(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 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1272,17 +1272,28 @@ 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 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -6934,11 +6934,13 @@ } 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(); + unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8; + auto PtrMemVT = getPointerMemTy(DAG.getDataLayout()); auto PtrVT = getPointerTy(DAG.getDataLayout()); SDLoc DL(Op); @@ -6948,54 +6950,64 @@ SmallVector 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); } @@ -7018,8 +7030,10 @@ // 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(Op.getOperand(3))->getValue(); const Value *SrcSV = cast(Op.getOperand(4))->getValue(); diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -479,7 +479,10 @@ 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 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -215,8 +215,6 @@ 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 @@ } 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 @@ // 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 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -270,7 +270,7 @@ 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 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -758,7 +758,7 @@ 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 @@ 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 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -43,7 +43,7 @@ } // 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 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp @@ -73,7 +73,7 @@ // 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 --- /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 + +@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 --- /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} + +@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) + +@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 --- 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 --- 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 --- 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 --- 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 --- 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 --- 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 --- 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 --- 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