[cfe-commits] r41457 - /cfe/trunk/CodeGen/CGExprComplex.cpp

Chris Lattner sabre at nondot.org
Sun Aug 26 14:24:19 PDT 2007


Author: lattner
Date: Sun Aug 26 16:24:19 2007
New Revision: 41457

URL: http://llvm.org/viewvc/llvm-project?rev=41457&view=rev
Log:
implement complex division

Modified:
    cfe/trunk/CodeGen/CGExprComplex.cpp

Modified: cfe/trunk/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprComplex.cpp?rev=41457&r1=41456&r2=41457&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/CodeGen/CGExprComplex.cpp Sun Aug 26 16:24:19 2007
@@ -117,6 +117,7 @@
   ComplexPairTy VisitBinMul        (const BinaryOperator *E);
   ComplexPairTy VisitBinAdd        (const BinaryOperator *E);
   ComplexPairTy VisitBinSub        (const BinaryOperator *E);
+  ComplexPairTy VisitBinDiv        (const BinaryOperator *E);
   // FIXME: div/rem
   // GCC rejects and/or/xor for integer complex.
   // Logical and/or always return int, never complex.
@@ -297,6 +298,44 @@
   return ComplexPairTy(ResR, ResI);
 }
 
+ComplexPairTy ComplexExprEmitter::VisitBinDiv(const BinaryOperator *E) {
+  ComplexPairTy LHS = Visit(E->getLHS());
+  ComplexPairTy RHS = Visit(E->getRHS());
+  llvm::Value *LHSr = LHS.first, *LHSi = LHS.second;
+  llvm::Value *RHSr = RHS.first, *RHSi = RHS.second;
+  
+  // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
+  llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
+  llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
+  llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
+  
+  llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
+  llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
+  llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
+  
+  llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
+  llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
+  llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
+
+  llvm::Value *DSTr, *DSTi;
+  if (Tmp3->getType()->isFloatingPoint()) {
+    DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
+    DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
+  } else {
+    QualType ExprTy = E->getType().getCanonicalType();
+    if (cast<ComplexType>(ExprTy)->getElementType()->isUnsignedIntegerType()) {
+      DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
+      DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
+    } else {
+      DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
+      DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
+    }
+  }
+    
+  return ComplexPairTy(DSTr, DSTi);
+}
+
+
 ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
   assert(E->getLHS()->getType().getCanonicalType() ==
          E->getRHS()->getType().getCanonicalType() && "Invalid assignment");





More information about the cfe-commits mailing list