// case Expr::CastExprClass:
// case Expr::CallExprClass:
ComplexPairTy VisitBinaryOperator(const BinaryOperator *BO);
+ ComplexPairTy VisitBinMul (const BinaryOperator *E);
ComplexPairTy VisitBinAdd (const BinaryOperator *E);
ComplexPairTy VisitBinAssign (const BinaryOperator *E);
}
ComplexPairTy ComplexExprEmitter::VisitBinAdd(const BinaryOperator *E) {
- // This must be a complex number.
ComplexPairTy LHS = Visit(E->getLHS());
ComplexPairTy RHS = Visit(E->getRHS());
return ComplexPairTy(ResR, ResI);
}
+ComplexPairTy ComplexExprEmitter::VisitBinMul(const BinaryOperator *E) {
+ ComplexPairTy LHS = Visit(E->getLHS());
+ ComplexPairTy RHS = Visit(E->getRHS());
+
+ llvm::Value *ResRl = CGF.Builder.CreateMul(LHS.first, RHS.first, "mul.rl");
+ llvm::Value *ResRr = CGF.Builder.CreateMul(LHS.second, RHS.second, "mul.rr");
+ llvm::Value *ResR = CGF.Builder.CreateSub(ResRl, ResRr, "mul.r");
+
+ llvm::Value *ResIl = CGF.Builder.CreateMul(LHS.second, RHS.first, "mul.il");
+ llvm::Value *ResIr = CGF.Builder.CreateMul(LHS.first, RHS.second, "mul.ir");
+ llvm::Value *ResI = CGF.Builder.CreateAdd(ResIl, ResIr, "mul.i");
+
+ return ComplexPairTy(ResR, ResI);
+}
+
ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
assert(E->getLHS()->getType().getCanonicalType() ==
E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
RValue CodeGenFunction::EmitMul(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateMul(LHS.getVal(), RHS.getVal(), "mul"));
-
-#if 0
- // Otherwise, this must be a complex number.
- llvm::Value *LHSR, *LHSI, *RHSR, *RHSI;
-
- EmitLoadOfComplex(LHS, LHSR, LHSI);
- EmitLoadOfComplex(RHS, RHSR, RHSI);
-
- llvm::Value *ResRl = Builder.CreateMul(LHSR, RHSR, "mul.rl");
- llvm::Value *ResRr = Builder.CreateMul(LHSI, RHSI, "mul.rr");
- llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
-
- llvm::Value *ResIl = Builder.CreateMul(LHSI, RHSR, "mul.il");
- llvm::Value *ResIr = Builder.CreateMul(LHSR, RHSI, "mul.ir");
- llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
-
- llvm::Value *Res = CreateTempAlloca(ConvertType(ResTy));
- EmitStoreOfComplex(ResR, ResI, Res);
- return RValue::getAggregate(Res);
-#endif
}
RValue CodeGenFunction::EmitDiv(RValue LHS, RValue RHS, QualType ResTy) {
- if (LHS.isScalar()) {
- llvm::Value *RV;
- if (LHS.getVal()->getType()->isFloatingPoint())
- RV = Builder.CreateFDiv(LHS.getVal(), RHS.getVal(), "div");
- else if (ResTy->isUnsignedIntegerType())
- RV = Builder.CreateUDiv(LHS.getVal(), RHS.getVal(), "div");
- else
- RV = Builder.CreateSDiv(LHS.getVal(), RHS.getVal(), "div");
- return RValue::get(RV);
- }
- assert(0 && "FIXME: This doesn't handle complex operands yet");
+ if (LHS.getVal()->getType()->isFloatingPoint())
+ return RValue::get(Builder.CreateFDiv(LHS.getVal(), RHS.getVal(), "div"));
+ else if (ResTy->isUnsignedIntegerType())
+ return RValue::get(Builder.CreateUDiv(LHS.getVal(), RHS.getVal(), "div"));
+ else
+ return RValue::get(Builder.CreateSDiv(LHS.getVal(), RHS.getVal(), "div"));
}
RValue CodeGenFunction::EmitRem(RValue LHS, RValue RHS, QualType ResTy) {
- if (LHS.isScalar()) {
- llvm::Value *RV;
- // Rem in C can't be a floating point type: C99 6.5.5p2.
- if (ResTy->isUnsignedIntegerType())
- RV = Builder.CreateURem(LHS.getVal(), RHS.getVal(), "rem");
- else
- RV = Builder.CreateSRem(LHS.getVal(), RHS.getVal(), "rem");
- return RValue::get(RV);
- }
-
- assert(0 && "FIXME: This doesn't handle complex operands yet");
+ // Rem in C can't be a floating point type: C99 6.5.5p2.
+ if (ResTy->isUnsignedIntegerType())
+ return RValue::get(Builder.CreateURem(LHS.getVal(), RHS.getVal(), "rem"));
+ else
+ return RValue::get(Builder.CreateSRem(LHS.getVal(), RHS.getVal(), "rem"));
}
RValue CodeGenFunction::EmitAdd(RValue LHS, RValue RHS, QualType ResTy) {
}
RValue CodeGenFunction::EmitSub(RValue LHS, RValue RHS, QualType ResTy) {
- if (LHS.isScalar())
- return RValue::get(Builder.CreateSub(LHS.getVal(), RHS.getVal(), "sub"));
-
- assert(0 && "FIXME: This doesn't handle complex operands yet");
+ return RValue::get(Builder.CreateSub(LHS.getVal(), RHS.getVal(), "sub"));
}
RValue CodeGenFunction::EmitPointerSub(RValue LHS, QualType LHSTy,