[cfe-commits] r41463 - /cfe/trunk/CodeGen/CGExprComplex.cpp
Chris Lattner
sabre at nondot.org
Sun Aug 26 15:09:01 PDT 2007
Author: lattner
Date: Sun Aug 26 17:09:01 2007
New Revision: 41463
URL: http://llvm.org/viewvc/llvm-project?rev=41463&view=rev
Log:
implement codegen of compound assignment operators for complex.
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=41463&r1=41462&r2=41463&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/CodeGen/CGExprComplex.cpp Sun Aug 26 17:09:01 2007
@@ -57,6 +57,10 @@
/// specified value pointer.
void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
+ /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
+ ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
+ QualType DestType);
+
//===--------------------------------------------------------------------===//
// Visitor Methods
//===--------------------------------------------------------------------===//
@@ -114,16 +118,54 @@
return Visit(E->getSubExpr());
}
- ComplexPairTy VisitBinMul (const BinaryOperator *E);
- ComplexPairTy VisitBinAdd (const BinaryOperator *E);
- ComplexPairTy VisitBinSub (const BinaryOperator *E);
- ComplexPairTy VisitBinDiv (const BinaryOperator *E);
+ struct BinOpInfo {
+ ComplexPairTy LHS;
+ ComplexPairTy RHS;
+ QualType Ty; // Computation Type.
+ };
+
+ BinOpInfo EmitBinOps(const BinaryOperator *E);
+ ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
+ ComplexPairTy (ComplexExprEmitter::*Func)
+ (const BinOpInfo &));
+
+ ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
+ ComplexPairTy EmitBinSub(const BinOpInfo &Op);
+ ComplexPairTy EmitBinMul(const BinOpInfo &Op);
+ ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
+
+ ComplexPairTy VisitBinMul(const BinaryOperator *E) {
+ return EmitBinMul(EmitBinOps(E));
+ }
+ ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
+ return EmitBinAdd(EmitBinOps(E));
+ }
+ ComplexPairTy VisitBinSub(const BinaryOperator *E) {
+ return EmitBinSub(EmitBinOps(E));
+ }
+ ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
+ return EmitBinDiv(EmitBinOps(E));
+ }
+
+ // Compound assignments.
+ ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
+ return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
+ }
+ ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
+ return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
+ }
+ ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
+ return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
+ }
+ ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
+ return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
+ }
+
// GCC rejects rem/and/or/xor for integer complex.
// Logical and/or always return int, never complex.
// No comparisons produce a complex result.
ComplexPairTy VisitBinAssign (const BinaryOperator *E);
- // FIXME: Compound assignment operators.
ComplexPairTy VisitBinComma (const BinaryOperator *E);
@@ -192,21 +234,27 @@
return EmitLoadOfComplex(AggPtr, false);
}
-ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
- // Get the destination element type.
- DestTy = cast<ComplexType>(DestTy.getCanonicalType())->getElementType();
+/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
+ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
+ QualType SrcType,
+ QualType DestType) {
+ // Get the src/dest element type.
+ SrcType = cast<ComplexType>(SrcType.getCanonicalType())->getElementType();
+ DestType = cast<ComplexType>(DestType.getCanonicalType())->getElementType();
+
+ // C99 6.3.1.6: When a value of complextype is converted to another
+ // complex type, both the real and imaginary parts followthe conversion
+ // rules for the corresponding real types.
+ Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
+ Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
+ return Val;
+}
+ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
// Two cases here: cast from (complex to complex) and (scalar to complex).
- if (const ComplexType *CT = Op->getType()->getAsComplexType()) {
- // C99 6.3.1.6: When a value of complextype is converted to another
- // complex type, both the real and imaginary parts followthe conversion
- // rules for the corresponding real types.
- ComplexPairTy Res = Visit(Op);
- QualType SrcEltTy = CT->getElementType();
- Res.first = CGF.EmitScalarConversion(Res.first, SrcEltTy, DestTy);
- Res.second = CGF.EmitScalarConversion(Res.second, SrcEltTy, DestTy);
- return Res;
- }
+ if (Op->getType()->isComplexType())
+ return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
+
// C99 6.3.1.7: When a value of real type is converted to a complex type, the
// real part of the complex result value is determined by the rules of
// conversion to the corresponding real type and the imaginary part of the
@@ -214,6 +262,7 @@
llvm::Value *Elt = CGF.EmitScalarExpr(Op);
// Convert the input element to the element type of the complex.
+ DestTy = cast<ComplexType>(DestTy.getCanonicalType())->getElementType();
Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
// Return (realval, 0).
@@ -261,47 +310,33 @@
return ComplexPairTy(Op.first, ResI);
}
-ComplexPairTy ComplexExprEmitter::VisitBinAdd(const BinaryOperator *E) {
- ComplexPairTy LHS = Visit(E->getLHS());
- ComplexPairTy RHS = Visit(E->getRHS());
-
- llvm::Value *ResR = Builder.CreateAdd(LHS.first, RHS.first, "add.r");
- llvm::Value *ResI = Builder.CreateAdd(LHS.second, RHS.second, "add.i");
-
+ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
+ llvm::Value *ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");
+ llvm::Value *ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
return ComplexPairTy(ResR, ResI);
}
-ComplexPairTy ComplexExprEmitter::VisitBinSub(const BinaryOperator *E) {
- ComplexPairTy LHS = Visit(E->getLHS());
- ComplexPairTy RHS = Visit(E->getRHS());
-
- llvm::Value *ResR = Builder.CreateSub(LHS.first, RHS.first, "sub.r");
- llvm::Value *ResI = Builder.CreateSub(LHS.second, RHS.second, "sub.i");
-
+ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
+ llvm::Value *ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
+ llvm::Value *ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
return ComplexPairTy(ResR, ResI);
}
-ComplexPairTy ComplexExprEmitter::VisitBinMul(const BinaryOperator *E) {
- ComplexPairTy LHS = Visit(E->getLHS());
- ComplexPairTy RHS = Visit(E->getRHS());
-
- llvm::Value *ResRl = Builder.CreateMul(LHS.first, RHS.first, "mul.rl");
- llvm::Value *ResRr = Builder.CreateMul(LHS.second, RHS.second, "mul.rr");
+ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
+ llvm::Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
+ llvm::Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
- llvm::Value *ResIl = Builder.CreateMul(LHS.second, RHS.first, "mul.il");
- llvm::Value *ResIr = Builder.CreateMul(LHS.first, RHS.second, "mul.ir");
+ llvm::Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
+ llvm::Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
-
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;
+ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
+ llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
+ llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.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
@@ -321,8 +356,7 @@
DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
} else {
- QualType ExprTy = E->getType().getCanonicalType();
- if (cast<ComplexType>(ExprTy)->getElementType()->isUnsignedIntegerType()) {
+ if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) {
DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
} else {
@@ -334,6 +368,45 @@
return ComplexPairTy(DSTr, DSTi);
}
+ComplexExprEmitter::BinOpInfo
+ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
+ BinOpInfo Ops;
+ Ops.LHS = Visit(E->getLHS());
+ Ops.RHS = Visit(E->getRHS());
+ Ops.Ty = E->getType();
+ return Ops;
+}
+
+
+// Compound assignments.
+ComplexPairTy ComplexExprEmitter::
+EmitCompoundAssign(const CompoundAssignOperator *E,
+ ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
+ QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
+
+ // Load the LHS and RHS operands.
+ LValue LHSLV = CGF.EmitLValue(E->getLHS());
+
+ BinOpInfo OpInfo;
+ OpInfo.Ty = E->getComputationType();
+
+ // We know the LHS is a complex lvalue.
+ OpInfo.LHS = EmitLoadOfComplex(LHSLV.getAddress(), false);// FIXME: Volatile.
+ OpInfo.LHS = EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
+
+ // It is possible for the RHS to be complex or scalar.
+ OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
+
+ // Expand the binary operator.
+ ComplexPairTy Result = (this->*Func)(OpInfo);
+
+ // Truncate the result back to the LHS type.
+ Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
+
+ // Store the result value into the LHS lvalue.
+ EmitStoreOfComplex(Result, LHSLV.getAddress(), false); // FIXME: VOLATILE
+ return Result;
+}
ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
assert(E->getLHS()->getType().getCanonicalType() ==
More information about the cfe-commits
mailing list