diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMRegisterInfo.cpp | 25 | ||||
| -rw-r--r-- | llvm/test/Regression/CodeGen/ARM/vargs.ll | 12 | 
3 files changed, 49 insertions, 12 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index 915684ad17e..1ef5bf48ca6 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -79,7 +79,6 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {    unsigned CallConv  = cast<ConstantSDNode>(Op.getOperand(1))->getValue();    assert(CallConv == CallingConv::C && "unknown calling convention");    bool isVarArg      = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; -  assert(isVarArg == false && "VarArg not supported");    bool isTailCall    = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;    assert(isTailCall == false && "tail call not supported");    SDOperand Callee   = Op.getOperand(4); @@ -89,23 +88,40 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {    // only the link register.    unsigned NumBytes = 4; -  assert(NumOps <= 4); //no args on the stack +  // Add up all the space actually used. +  for (unsigned i = 4; i < NumOps; ++i) +    NumBytes += MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8;    // Adjust the stack pointer for the new arguments...    // These operations are automatically eliminated by the prolog/epilog pass    Chain = DAG.getCALLSEQ_START(Chain,                                 DAG.getConstant(NumBytes, MVT::i32)); -  static const unsigned regs[] = { +  SDOperand StackPtr = DAG.getRegister(ARM::R13, MVT::i32); + +  static const unsigned int num_regs = 4; +  static const unsigned regs[num_regs] = {      ARM::R0, ARM::R1, ARM::R2, ARM::R3    };    std::vector<std::pair<unsigned, SDOperand> > RegsToPass; +  std::vector<SDOperand> MemOpChains;    for (unsigned i = 0; i != NumOps; ++i) {      SDOperand Arg = Op.getOperand(5+2*i); -    RegsToPass.push_back(std::make_pair(regs[i], Arg)); +    assert(Arg.getValueType() == MVT::i32); +    if (i < num_regs) +      RegsToPass.push_back(std::make_pair(regs[i], Arg)); +    else { +      unsigned ArgOffset = (i - num_regs) * 4; +      SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); +      MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, +                                          Arg, PtrOff, DAG.getSrcValue(NULL))); +    }    } +  if (!MemOpChains.empty()) +    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOpChains);    // Build a sequence of copy-to-reg nodes chained together with token chain    // and flag operands which copy the outgoing args into the appropriate regs. diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp index a9fe7056678..719ce321e0a 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp @@ -124,10 +124,21 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {    //hack    assert(NumBytes == 0); -  //sub sp, sp, #4 -  BuildMI(MBB, MBBI, ARM::subri, 2, ARM::R13).addReg(ARM::R13).addImm(4); -  //str lr, [sp] -  BuildMI(MBB, MBBI, ARM::str, 1, ARM::R14).addReg(ARM::R13); +  if (MFI->hasCalls()) { +    // We reserve argument space for call sites in the function immediately on +    // entry to the current function.  This eliminates the need for add/sub +    // brackets around call sites. +    NumBytes += MFI->getMaxCallFrameSize(); +  } + +  MFI->setStackSize(NumBytes); + +  //sub sp, sp, #NumBytes +  BuildMI(MBB, MBBI, ARM::subri, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes); +  //add ip, sp, #NumBytes - 4 +  BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R12).addReg(ARM::R13).addImm(NumBytes - 4); +  //str lr, [ip] +  BuildMI(MBB, MBBI, ARM::str, 1, ARM::R14).addReg(ARM::R12);  }  void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, @@ -138,13 +149,11 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,    MachineFrameInfo *MFI = MF.getFrameInfo();    int          NumBytes = (int) MFI->getStackSize(); -  //hack -  assert(NumBytes == 0);    //ldr lr, [sp]    BuildMI(MBB, MBBI, ARM::ldr, 2, ARM::R14).addImm(0).addReg(ARM::R13); -  //add sp, sp, #4 -  BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R13).addReg(ARM::R13).addImm(4); +  //add sp, sp, #NumBytes +  BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);  }  unsigned ARMRegisterInfo::getRARegister() const { diff --git a/llvm/test/Regression/CodeGen/ARM/vargs.ll b/llvm/test/Regression/CodeGen/ARM/vargs.ll new file mode 100644 index 00000000000..858c463c58d --- /dev/null +++ b/llvm/test/Regression/CodeGen/ARM/vargs.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -march=arm  +%str = internal constant [43 x sbyte] c"Hello World %d %d %d %d %d %d %d %d %d %d\0A\00"		; <[43 x sbyte]*> [#uses=1] + +implementation   ; Functions: + +int %main() { +entry: +	%tmp = call int (sbyte*, ...)* %printf( sbyte* getelementptr ([43 x sbyte]* %str, int 0, uint 0), int 1, int 2, int 3, int 4, int 5, int 6, int 7, int 8, int 9, int 10 )		; <int> [#uses=0] +	ret int 0 +} + +declare int %printf(sbyte*, ...)  | 

