]> granicus.if.org Git - clang/commitdiff
Add folding for complex mul and fix some major bugs in complex float
authorDaniel Dunbar <daniel@zuster.org>
Thu, 29 Jan 2009 01:32:56 +0000 (01:32 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 29 Jan 2009 01:32:56 +0000 (01:32 +0000)
evaluation (alternate part of real/imag init was being set to 3 not 0
because the wrong APFloat constructor was being called).
 - Test cases coming once some more support is in.

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

lib/AST/ExprConstant.cpp

index af50de6f948147bbe4d6ca54f48de258b7a4d991..c444a199f6c37cb89827b4649c53690e731d9fd7 100644 (file)
@@ -1257,7 +1257,7 @@ public:
       if (!EvaluateFloat(SubExpr, Result, Info))
         return APValue();
     
-      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), 
+      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false), 
                      Result);
     } else {
       assert(SubExpr->getType()->isIntegerType() && 
@@ -1283,7 +1283,7 @@ public:
         return APValue();
       
       return APValue(Result, 
-                     APFloat(Result.getSemantics(), APFloat::fcZero));
+                     APFloat(Result.getSemantics(), APFloat::fcZero, false));
     } else if (SubExpr->getType()->isIntegerType()) {
       APSInt Result;
                      
@@ -1324,6 +1324,8 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
   if (!EvaluateComplex(E->getRHS(), RHS, Info))
     return APValue();
 
+  assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
+         "Invalid operands to binary operator.");
   switch (E->getOpcode()) {
   default: return APValue();
   case BinaryOperator::Add:
@@ -1336,6 +1338,7 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
       Result.getComplexIntReal() += RHS.getComplexIntReal();
       Result.getComplexIntImag() += RHS.getComplexIntImag();
     }
+    break;
   case BinaryOperator::Sub:
     if (Result.isComplexFloat()) {
       Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
@@ -1346,6 +1349,38 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
       Result.getComplexIntReal() -= RHS.getComplexIntReal();
       Result.getComplexIntImag() -= RHS.getComplexIntImag();
     }
+    break;
+  case BinaryOperator::Mul:
+    if (Result.isComplexFloat()) {
+      APValue LHS = Result;
+      APFloat &LHS_r = LHS.getComplexFloatReal();
+      APFloat &LHS_i = LHS.getComplexFloatImag();
+      APFloat &RHS_r = RHS.getComplexFloatReal();
+      APFloat &RHS_i = RHS.getComplexFloatImag();
+      
+      APFloat Tmp = LHS_r;
+      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatReal() = Tmp;
+      Tmp = LHS_i;
+      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven);
+
+      Tmp = LHS_r;
+      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag() = Tmp;
+      Tmp = LHS_i;
+      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
+    } else {
+      APValue LHS = Result;
+      Result.getComplexIntReal() = 
+        (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
+         LHS.getComplexIntImag() * RHS.getComplexIntImag());
+      Result.getComplexIntImag() = 
+        (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
+         LHS.getComplexIntImag() * RHS.getComplexIntReal());
+    }
+    break;
   }
 
   return Result;