diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 08cbba952ccc8..1be29cf3c94b9 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -37,9 +37,13 @@ ArrayRef MipsABIInfo::GetByValArgRegs() const { llvm_unreachable("Unhandled ABI"); } -ArrayRef MipsABIInfo::GetVarArgRegs() const { - if (IsO32()) - return ArrayRef(O32IntRegs); +ArrayRef MipsABIInfo::getVarArgRegs(bool isGP64bit) const { + if (IsO32()) { + if (isGP64bit) + return ArrayRef(Mips64IntRegs); + else + return ArrayRef(O32IntRegs); + } if (IsN32() || IsN64()) return ArrayRef(Mips64IntRegs); llvm_unreachable("Unhandled ABI"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h index 41f80771142de..44b023c7c3ef6 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h @@ -46,7 +46,7 @@ class MipsABIInfo { ArrayRef GetByValArgRegs() const; /// The registers to use for the variable argument list. - ArrayRef GetVarArgRegs() const; + ArrayRef getVarArgRegs(bool isGP64bit) const; /// Obtain the size of the area allocated by the callee for arguments. /// CallingConv::FastCall affects the value for O32. diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp index b856290211277..01c9d0b38323e 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.cpp +++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp @@ -406,7 +406,8 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, return false; if (F.isVarArg()) { - ArrayRef ArgRegs = ABI.GetVarArgRegs(); + ArrayRef ArgRegs = + ABI.getVarArgRegs(MF.getSubtarget().isGP64bit()); unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs); int VaArgOffset; diff --git a/llvm/lib/Target/Mips/MipsCallingConv.td b/llvm/lib/Target/Mips/MipsCallingConv.td index 25384a3fe8de3..3c60114f507b9 100644 --- a/llvm/lib/Target/Mips/MipsCallingConv.td +++ b/llvm/lib/Target/Mips/MipsCallingConv.td @@ -339,7 +339,7 @@ def CC_Mips_FixedArg : CallingConv<[ CCIfCC<"CallingConv::Fast", CCDelegateTo>, - CCIfSubtarget<"isABI_O32()", CCDelegateTo>, + CCIfSubtarget<"isABI_O32()", CCIfSubtargetNot<"isGP64bit()", CCDelegateTo>>, CCDelegateTo ]>; diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index e737c5aeb43c6..59207f68ebd47 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -3400,7 +3400,6 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SDValue StackPtr = DAG.getCopyFromReg(Chain, DL, ABI.IsN64() ? Mips::SP_64 : Mips::SP, getPointerTy(DAG.getDataLayout())); - std::deque> RegsToPass; SmallVector MemOpChains; @@ -4640,7 +4639,7 @@ void MipsTargetLowering::writeVarArgRegs(std::vector &OutChains, SDValue Chain, const SDLoc &DL, SelectionDAG &DAG, CCState &State) const { - ArrayRef ArgRegs = ABI.GetVarArgRegs(); + ArrayRef ArgRegs = ABI.getVarArgRegs(Subtarget.isGP64bit()); unsigned Idx = State.getFirstUnallocated(ArgRegs); unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8); diff --git a/llvm/test/CodeGen/Mips/vararg.ll b/llvm/test/CodeGen/Mips/vararg.ll new file mode 100644 index 0000000000000..ed4a805af0c0c --- /dev/null +++ b/llvm/test/CodeGen/Mips/vararg.ll @@ -0,0 +1,54 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi o32 < %s | FileCheck %s -check-prefixes=MIPS3-O32 +; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n32 < %s | FileCheck %s -check-prefixes=MIPS3-N32 +; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n64 < %s | FileCheck %s -check-prefixes=MIPS3-N64 + +define void @func(ptr nocapture %x, ...) nounwind { +; MIPS3-O32-LABEL: func: +; MIPS32-O32: # %bb.0: # %entry +; MIPS32-O32-NEXT: addiu $sp, $sp, -48 +; MIPS32-O32-NEXT: sd $11, 56($sp) +; MIPS32-O32-NEXT: sd $10, 48($sp) +; MIPS32-O32-NEXT: sd $9, 40($sp) +; MIPS32-O32-NEXT: sd $8, 32($sp) +; MIPS32-O32-NEXT: sd $7, 24($sp) +; MIPS32-O32-NEXT: sd $6, 16($sp) +; MIPS32-O32-NEXT: sd $5, 8($sp) +; MIPS32-O32-NEXT: sw $4, 4($sp) +; MIPS32-O32-NEXT: jr $ra +; MIPS32-O32-NEXT: addiu $sp, $sp, 48 +; +; MIPS3-N32-LABEL: func: +; MIPS32-N32: # %bb.0: # %entry +; MIPS32-N32-NEXT: addiu $sp, $sp, -64 +; MIPS32-N32-NEXT: sd $11, 56($sp) +; MIPS32-N32-NEXT: sd $10, 48($sp) +; MIPS32-N32-NEXT: sd $9, 40($sp) +; MIPS32-N32-NEXT: sd $8, 32($sp) +; MIPS32-N32-NEXT: sd $7, 24($sp) +; MIPS32-N32-NEXT: sd $6, 16($sp) +; MIPS32-N32-NEXT: sd $5, 8($sp) +; MIPS32-N32-NEXT: sw $4, 4($sp) +; MIPS32-N32-NEXT: jr $ra +; MIPS32-N32-NEXT: addiu $sp, $sp, 64 +; +; MIPS3-N64-LABEL: func: +; MIPS32-N64: # %bb.0: # %entry +; MIPS32-N64-NEXT: addiu $sp, $sp, -64 +; MIPS32-N64-NEXT: sdl $4, 7($sp) +; MIPS32-N64-NEXT: sd $11, 56($sp) +; MIPS32-N64-NEXT: sd $10, 48($sp) +; MIPS32-N64-NEXT: sd $9, 40($sp) +; MIPS32-N64-NEXT: sd $8, 32($sp) +; MIPS32-N64-NEXT: sd $7, 24($sp) +; MIPS32-N64-NEXT: sd $6, 16($sp) +; MIPS32-N64-NEXT: sd $5, 8($sp) +; MIPS32-N64-NEXT: sw $4, 4($sp) +; MIPS32-N64-NEXT: jr $ra +; MIPS32-N64-NEXT: addiu $sp, $sp, 64 + +entry: + %x.addr = alloca ptr, align 4 + store ptr %x, ptr %x.addr, align 4 + ret void +}