]> granicus.if.org Git - clang/commitdiff
Revert r214497: [mips] Defer va_arg expansion to the backend.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Fri, 1 Aug 2014 13:26:28 +0000 (13:26 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Fri, 1 Aug 2014 13:26:28 +0000 (13:26 +0000)
It appears that the backend does not handle all cases that were handled by clang.
In particular, it does not handle structs as used in
SingleSource/UnitTests/2003-05-07-VarArgs.

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

lib/CodeGen/TargetInfo.cpp
test/CodeGen/mips-vaarg.c [deleted file]

index 3870f72487d9ff811748e58242057d1bc5af2e02..ca99ba580a57ff5766964d039874d4f2c460a0f0 100644 (file)
@@ -5560,7 +5560,39 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
 
 llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                     CodeGenFunction &CGF) const {
-  return nullptr;
+  llvm::Type *BP = CGF.Int8PtrTy;
+  llvm::Type *BPP = CGF.Int8PtrPtrTy;
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  int64_t TypeAlign = getContext().getTypeAlign(Ty) / 8;
+  llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+  llvm::Value *AddrTyped;
+  unsigned PtrWidth = getTarget().getPointerWidth(0);
+  llvm::IntegerType *IntTy = (PtrWidth == 32) ? CGF.Int32Ty : CGF.Int64Ty;
+
+  if (TypeAlign > MinABIStackAlignInBytes) {
+    llvm::Value *AddrAsInt = CGF.Builder.CreatePtrToInt(Addr, IntTy);
+    llvm::Value *Inc = llvm::ConstantInt::get(IntTy, TypeAlign - 1);
+    llvm::Value *Mask = llvm::ConstantInt::get(IntTy, -TypeAlign);
+    llvm::Value *Add = CGF.Builder.CreateAdd(AddrAsInt, Inc);
+    llvm::Value *And = CGF.Builder.CreateAnd(Add, Mask);
+    AddrTyped = CGF.Builder.CreateIntToPtr(And, PTy);
+  }
+  else
+    AddrTyped = Builder.CreateBitCast(Addr, PTy);  
+
+  llvm::Value *AlignedAddr = Builder.CreateBitCast(AddrTyped, BP);
+  TypeAlign = std::max((unsigned)TypeAlign, MinABIStackAlignInBytes);
+  uint64_t Offset =
+    llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, TypeAlign);
+  llvm::Value *NextAddr =
+    Builder.CreateGEP(AlignedAddr, llvm::ConstantInt::get(IntTy, Offset),
+                      "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+  
+  return AddrTyped;
 }
 
 bool
diff --git a/test/CodeGen/mips-vaarg.c b/test/CodeGen/mips-vaarg.c
deleted file mode 100644 (file)
index f685ed8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: %clang -target mips-unknown-linux     -S -o - -emit-llvm %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
-// RUN: %clang -target mipsel-unknown-linux   -S -o - -emit-llvm %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
-// RUN: %clang -target mips64-unknown-linux   -S -o - -emit-llvm %s -mabi=n32 | FileCheck --check-prefix=ALL --check-prefix=N32 %s
-// RUN: %clang -target mips64el-unknown-linux -S -o - -emit-llvm %s -mabi=n32 | FileCheck --check-prefix=ALL --check-prefix=N32 %s
-// RUN: %clang -target mips64-unknown-linux   -S -o - -emit-llvm %s -mabi=64  | FileCheck --check-prefix=ALL --check-prefix=N64 %s
-// RUN: %clang -target mips64el-unknown-linux -S -o - -emit-llvm %s -mabi=64  | FileCheck --check-prefix=ALL --check-prefix=N64 %s
-
-int foo (int a, ...)
-{
-    // ALL-LABEL: define i32 @foo(i32 %a, ...)
-
-    __builtin_va_list va;
-    // O32: %va = alloca i8*, align 4
-    // N32: %va = alloca i8*, align 4
-    // N64: %va = alloca i8*, align 8
-
-    __builtin_va_start (va, a);
-    // ALL: %va1 = bitcast i8** %va to i8*
-    // ALL: call void @llvm.va_start(i8* %va1)
-
-    int n = __builtin_va_arg (va, int);
-    // ALL: %{{[0-9]+}} = va_arg i8** %va, i32
-    
-    __builtin_va_end (va);
-    // ALL: %va2 = bitcast i8** %va to i8*
-    // ALL: call void @llvm.va_end(i8* %va2)
-
-    return n;
-}