use @ for comments
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 25 Aug 2006 17:55:16 +0000 (17:55 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 25 Aug 2006 17:55:16 +0000 (17:55 +0000)
store LR in an arbitrary stack slot
add support for writing varargs functions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29876 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMFrameInfo.h
lib/Target/ARM/ARMISelDAGToDAG.cpp

index bd123963f75c743158c023e895702f6d65419e07..61534f660e7cd4d9caf21ceb679d46ff05845c5c 100644 (file)
@@ -43,7 +43,7 @@ namespace {
       Data32bitsDirective = "\t.word\t";
       Data64bitsDirective = 0;
       ZeroDirective = "\t.skip\t";
-      CommentString = "#";
+      CommentString = "@";
       ConstantPoolSection = "\t.text\n";
       AlignmentIsInBytes = false;
     }
index d25ec9c3f152d2413395043ac2c970ed0b29608d..5bd7f676671c3b74fe05c35700f3d9780d6adb9e 100644 (file)
 namespace llvm {
 
 class ARMFrameInfo: public TargetFrameInfo {
-  std::pair<unsigned, int> LR[1];
 
 public:
   ARMFrameInfo()
     : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
-    LR[0].first = ARM::R14;
-    LR[0].second = -4;
   }
 
-  const std::pair<unsigned, int> *
-  getCalleeSaveSpillSlots(unsigned &NumEntries) const {
-    NumEntries = 1;
-    return &LR[0];
-  }
 };
 
 } // End llvm namespace
index 75253b92cd0c6165067fe6666e4965c6e6db9d1f..33a068d9962504c21331e4dcefaeeb20a936c6a7 100644 (file)
@@ -32,6 +32,7 @@ using namespace llvm;
 
 namespace {
   class ARMTargetLowering : public TargetLowering {
+    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
   public:
     ARMTargetLowering(TargetMachine &TM);
     virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
@@ -55,6 +56,9 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
 
+  setOperationAction(ISD::VASTART,       MVT::Other, Custom);
+  setOperationAction(ISD::VAEND,         MVT::Other, Expand);
+
   setSchedulingPreference(SchedulingForRegPressure);
   computeRegisterProperties();
 }
@@ -238,6 +242,7 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
 }
 
 static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
+                                     unsigned *vRegs,
                                      unsigned ArgNo) {
   MachineFunction &MF = DAG.getMachineFunction();
   MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
@@ -253,6 +258,7 @@ static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
   if(ArgNo < num_regs) {
     unsigned VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass);
     MF.addLiveIn(REGS[ArgNo], VReg);
+    vRegs[ArgNo] = VReg;
     return DAG.getCopyFromReg(Root, VReg, MVT::i32);
   } else {
     // If the argument is actually used, emit a load from the right stack
@@ -291,18 +297,65 @@ static SDOperand LowerGlobalAddress(SDOperand Op,
                     DAG.getSrcValue(NULL));
 }
 
-static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
+static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
+                              unsigned VarArgsFrameIndex) {
+  // vastart just stores the address of the VarArgsFrameIndex slot into the
+  // memory location argument.
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
+  return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, 
+                     Op.getOperand(1), Op.getOperand(2));
+}
+
+static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
+                                      int &VarArgsFrameIndex) {
   std::vector<SDOperand> ArgValues;
   SDOperand Root = Op.getOperand(0);
+  unsigned VRegs[4];
 
-  for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
-    SDOperand ArgVal = LowerFORMAL_ARGUMENT(Op, DAG, ArgNo);
+  unsigned NumArgs = Op.Val->getNumValues()-1;
+  for (unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo) {
+    SDOperand ArgVal = LowerFORMAL_ARGUMENT(Op, DAG, VRegs, ArgNo);
 
     ArgValues.push_back(ArgVal);
   }
 
   bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
-  assert(!isVarArg);
+  if (isVarArg) {
+    MachineFunction &MF = DAG.getMachineFunction();
+    SSARegMap *RegMap = MF.getSSARegMap();
+    MachineFrameInfo *MFI = MF.getFrameInfo();
+    VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(MVT::i32)/8,
+                                               -16 + NumArgs * 4);
+
+
+    static const unsigned REGS[] = {
+      ARM::R0, ARM::R1, ARM::R2, ARM::R3
+    };
+    // If this function is vararg, store r0-r3 to their spots on the stack
+    // so that they may be loaded by deferencing the result of va_next.
+    SmallVector<SDOperand, 4> MemOps;
+    for (unsigned ArgNo = 0; ArgNo < 4; ++ArgNo) {
+      int ArgOffset = - (4 - ArgNo) * 4;
+      int FI = MFI->CreateFixedObject(MVT::getSizeInBits(MVT::i32)/8,
+                                     ArgOffset);
+      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+
+      unsigned VReg;
+      if (ArgNo < NumArgs)
+       VReg = VRegs[ArgNo];
+      else
+       VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass);
+      if (ArgNo >= NumArgs)
+       MF.addLiveIn(REGS[ArgNo], VReg);
+
+      SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+      SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
+                                    Val, FIN, DAG.getSrcValue(NULL));
+      MemOps.push_back(Store);
+    }
+    Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
+  }
 
   ArgValues.push_back(Root);
 
@@ -346,7 +399,7 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::GlobalAddress:
     return LowerGlobalAddress(Op, DAG);
   case ISD::FORMAL_ARGUMENTS:
-    return LowerFORMAL_ARGUMENTS(Op, DAG);
+    return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
   case ISD::CALL:
     return LowerCALL(Op, DAG);
   case ISD::RET:
@@ -355,6 +408,8 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     return LowerSELECT_CC(Op, DAG);
   case ISD::BR_CC:
     return LowerBR_CC(Op, DAG);
+  case ISD::VASTART:
+    return LowerVASTART(Op, DAG, VarArgsFrameIndex);
   }
 }