Add support for the new varargs intrinsics and instructions
authorChris Lattner <sabre@nondot.org>
Sat, 18 Oct 2003 05:57:43 +0000 (05:57 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 18 Oct 2003 05:57:43 +0000 (05:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9226 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/CBackend/CBackend.cpp
lib/Target/CBackend/Writer.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Instruction.cpp
lib/VMCore/Verifier.cpp

index a34f3f7712505e59ec5ed920ec0b76c1798013f9..00ad0e3bb1b9843590a22732445076f2605fa3e5 100644 (file)
@@ -90,7 +90,7 @@ namespace {
       // emit it inline where it would go.
       if (I.getType() == Type::VoidTy || !I.hasOneUse() ||
           isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) || 
-          isa<LoadInst>(I) || isa<VarArgInst>(I))
+          isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<VANextInst>(I))
         // Don't inline a load across a store or other bad things!
         return false;
 
@@ -135,7 +135,8 @@ namespace {
     void visitLoadInst  (LoadInst   &I);
     void visitStoreInst (StoreInst  &I);
     void visitGetElementPtrInst(GetElementPtrInst &I);
-    void visitVarArgInst(VarArgInst &I);
+    void visitVANextInst(VANextInst &I);
+    void visitVAArgInst (VAArgInst &I);
 
     void visitInstruction(Instruction &I) {
       std::cerr << "C Writer does not know about " << I;
@@ -1181,26 +1182,25 @@ void CWriter::visitCallInst(CallInst &I) {
       switch (ID) {
       default:  assert(0 && "Unknown LLVM intrinsic!");
       case LLVMIntrinsic::va_start: 
-        Out << "va_start(*(va_list*)";
-        writeOperand(I.getOperand(1));
-        Out << ", ";
+        Out << "0; ";
+        
+        Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", ";
         // Output the last argument to the enclosing function...
         writeOperand(&I.getParent()->getParent()->aback());
         Out << ")";
         return;
       case LLVMIntrinsic::va_end:
-        Out << "va_end(*(va_list*)";
+        Out << "va_end(*(va_list*)&";
         writeOperand(I.getOperand(1));
         Out << ")";
         return;
       case LLVMIntrinsic::va_copy:
-        Out << "va_copy(*(va_list*)";
+        Out << "0;";
+        Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", ";
+        Out << "*(va_list*)&";
         writeOperand(I.getOperand(1));
-        Out << ", (va_list)";
-        writeOperand(I.getOperand(2));
         Out << ")";
         return;
-
       case LLVMIntrinsic::setjmp:
       case LLVMIntrinsic::sigsetjmp:
         // This intrinsic should never exist in the program, but until we get
@@ -1346,12 +1346,21 @@ void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
   printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
 }
 
-void CWriter::visitVarArgInst(VarArgInst &I) {
-  Out << "va_arg((va_list)*";
+void CWriter::visitVANextInst(VANextInst &I) {
+  Out << Mang->getValueName(I.getOperand(0));
+  Out << ";  va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", ";
+  printType(Out, I.getArgType(), "", /*ignoreName*/false,
+            /*namedContext*/false);
+  Out << ")";  
+}
+
+void CWriter::visitVAArgInst(VAArgInst &I) {
+  Out << "0;\n";
+  Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&";
   writeOperand(I.getOperand(0));
-  Out << ", ";
+  Out << ");\n  " << Mang->getValueName(&I) << " = va_arg(Tmp, ";
   printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false);
-  Out << ")";  
+  Out << ");\n  va_end(Tmp); }";
 }
 
 
index a34f3f7712505e59ec5ed920ec0b76c1798013f9..00ad0e3bb1b9843590a22732445076f2605fa3e5 100644 (file)
@@ -90,7 +90,7 @@ namespace {
       // emit it inline where it would go.
       if (I.getType() == Type::VoidTy || !I.hasOneUse() ||
           isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) || 
-          isa<LoadInst>(I) || isa<VarArgInst>(I))
+          isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<VANextInst>(I))
         // Don't inline a load across a store or other bad things!
         return false;
 
@@ -135,7 +135,8 @@ namespace {
     void visitLoadInst  (LoadInst   &I);
     void visitStoreInst (StoreInst  &I);
     void visitGetElementPtrInst(GetElementPtrInst &I);
-    void visitVarArgInst(VarArgInst &I);
+    void visitVANextInst(VANextInst &I);
+    void visitVAArgInst (VAArgInst &I);
 
     void visitInstruction(Instruction &I) {
       std::cerr << "C Writer does not know about " << I;
@@ -1181,26 +1182,25 @@ void CWriter::visitCallInst(CallInst &I) {
       switch (ID) {
       default:  assert(0 && "Unknown LLVM intrinsic!");
       case LLVMIntrinsic::va_start: 
-        Out << "va_start(*(va_list*)";
-        writeOperand(I.getOperand(1));
-        Out << ", ";
+        Out << "0; ";
+        
+        Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", ";
         // Output the last argument to the enclosing function...
         writeOperand(&I.getParent()->getParent()->aback());
         Out << ")";
         return;
       case LLVMIntrinsic::va_end:
-        Out << "va_end(*(va_list*)";
+        Out << "va_end(*(va_list*)&";
         writeOperand(I.getOperand(1));
         Out << ")";
         return;
       case LLVMIntrinsic::va_copy:
-        Out << "va_copy(*(va_list*)";
+        Out << "0;";
+        Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", ";
+        Out << "*(va_list*)&";
         writeOperand(I.getOperand(1));
-        Out << ", (va_list)";
-        writeOperand(I.getOperand(2));
         Out << ")";
         return;
-
       case LLVMIntrinsic::setjmp:
       case LLVMIntrinsic::sigsetjmp:
         // This intrinsic should never exist in the program, but until we get
@@ -1346,12 +1346,21 @@ void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
   printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
 }
 
-void CWriter::visitVarArgInst(VarArgInst &I) {
-  Out << "va_arg((va_list)*";
+void CWriter::visitVANextInst(VANextInst &I) {
+  Out << Mang->getValueName(I.getOperand(0));
+  Out << ";  va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", ";
+  printType(Out, I.getArgType(), "", /*ignoreName*/false,
+            /*namedContext*/false);
+  Out << ")";  
+}
+
+void CWriter::visitVAArgInst(VAArgInst &I) {
+  Out << "0;\n";
+  Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&";
   writeOperand(I.getOperand(0));
-  Out << ", ";
+  Out << ");\n  " << Mang->getValueName(&I) << " = va_arg(Tmp, ";
   printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false);
-  Out << ")";  
+  Out << ");\n  va_end(Tmp); }";
 }
 
 
index 3601dffe4240974a41a216ca2a46a66ab38df855..f8716757db0d82b3b6c4f27d26890f7a5fa5105d 100644 (file)
@@ -661,7 +661,10 @@ void AssemblyWriter::printFunction(const Function *F) {
     }
 
   printType(F->getReturnType()) << " ";
-  if (!F->getName().empty()) Out << getLLVMName(F->getName());
+  if (!F->getName().empty())
+    Out << getLLVMName(F->getName());
+  else
+    Out << "\"\"";
   Out << "(";
   Table.incorporateFunction(F);
 
@@ -882,10 +885,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     writeOperand(Operand, true);
     Out << " to ";
     printType(I.getType());
-  } else if (isa<VarArgInst>(I)) {
+  } else if (isa<VAArgInst>(I)) {
     writeOperand(Operand, true);
     Out << ", ";
     printType(I.getType());
+  } else if (const VANextInst *VAN = dyn_cast<VANextInst>(&I)) {
+    writeOperand(Operand, true);
+    Out << ", ";
+    printType(VAN->getArgType());
   } else if (Operand) {   // Print the normal way...
 
     // PrintAllTypes - Instructions who have operands of all the same type 
index e5e6501bd3d74f76d7d170cc1003247fddf0c279..179a988eb56d3873c14f9037e0891203924a51ad 100644 (file)
@@ -92,7 +92,8 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
   case Call:    return "call";
   case Shl:     return "shl";
   case Shr:     return "shr";
-  case VarArg:  return "va_arg";
+  case VANext:  return "vanext";
+  case VAArg:   return "vaarg";
 
   default: return "<Invalid operator> ";
   }
index 1d4ac258eb305a61f5636a7fdd5e9ad5243df37e..5c70b93fc511a81793b3e887e922afa079311fb0 100644 (file)
@@ -131,7 +131,8 @@ namespace {  // Anonymous namespace for class
     void visitPHINode(PHINode &PN);
     void visitBinaryOperator(BinaryOperator &B);
     void visitShiftInst(ShiftInst &SI);
-    void visitVarArgInst(VarArgInst &VAI) { visitInstruction(VAI); }
+    void visitVANextInst(VANextInst &VAN) { visitInstruction(VAN); }
+    void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
     void visitCallInst(CallInst &CI);
     void visitGetElementPtrInst(GetElementPtrInst &GEP);
     void visitLoadInst(LoadInst &LI);
@@ -505,10 +506,10 @@ void Verifier::visitIntrinsicFunctionCall(LLVMIntrinsic::ID ID, CallInst &CI) {
     Assert1(CI.getParent()->getParent()->getFunctionType()->isVarArg(),
             "llvm.va_start intrinsic may only occur in function with variable"
             " args!", &CI);
-    NumArgs = 1;
+    NumArgs = 0;
     break;
   case LLVMIntrinsic::va_end:          NumArgs = 1; break;
-  case LLVMIntrinsic::va_copy:         NumArgs = 2; break;
+  case LLVMIntrinsic::va_copy:         NumArgs = 1; break;
 
   case LLVMIntrinsic::setjmp:          NumArgs = 1; break;
   case LLVMIntrinsic::longjmp:         NumArgs = 2; break;