@@ -876,6 +876,22 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
876
876
if (const auto *AT = RHSType->getAs <AtomicType>())
877
877
RHSType = AT->getValueType ();
878
878
879
+ // For ComplexComplex Mul, we have special ops to make their implementation
880
+ // easier.
881
+ BinaryOperatorKind Op = E->getOpcode ();
882
+ if (Op == BO_Mul && LHSType->isAnyComplexType () &&
883
+ RHSType->isAnyComplexType ()) {
884
+ assert (classifyPrim (LHSType->getAs <ComplexType>()->getElementType ()) ==
885
+ classifyPrim (RHSType->getAs <ComplexType>()->getElementType ()));
886
+ PrimType ElemT =
887
+ classifyPrim (LHSType->getAs <ComplexType>()->getElementType ());
888
+ if (!this ->visit (LHS))
889
+ return false ;
890
+ if (!this ->visit (RHS))
891
+ return false ;
892
+ return this ->emitMulc (ElemT, E);
893
+ }
894
+
879
895
// Evaluate LHS and save value to LHSOffset.
880
896
bool LHSIsComplex;
881
897
unsigned LHSOffset;
@@ -919,38 +935,37 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
919
935
// For both LHS and RHS, either load the value from the complex pointer, or
920
936
// directly from the local variable. For index 1 (i.e. the imaginary part),
921
937
// just load 0 and do the operation anyway.
922
- auto loadComplexValue = [this ](bool IsComplex, unsigned ElemIndex,
923
- unsigned Offset, const Expr *E) -> bool {
938
+ auto loadComplexValue = [this ](bool IsComplex, bool LoadZero,
939
+ unsigned ElemIndex, unsigned Offset,
940
+ const Expr *E) -> bool {
924
941
if (IsComplex) {
925
942
if (!this ->emitGetLocal (PT_Ptr, Offset, E))
926
943
return false ;
927
944
return this ->emitArrayElemPop (classifyComplexElementType (E->getType ()),
928
945
ElemIndex, E);
929
946
}
930
- if (ElemIndex == 0 )
947
+ if (ElemIndex == 0 || !LoadZero )
931
948
return this ->emitGetLocal (classifyPrim (E->getType ()), Offset, E);
932
949
return this ->visitZeroInitializer (classifyPrim (E->getType ()), E->getType (),
933
950
E);
934
951
};
935
952
936
953
// Now we can get pointers to the LHS and RHS from the offsets above.
937
- BinaryOperatorKind Op = E->getOpcode ();
938
954
for (unsigned ElemIndex = 0 ; ElemIndex != 2 ; ++ElemIndex) {
939
955
// Result pointer for the store later.
940
956
if (!this ->DiscardResult ) {
941
957
if (!this ->emitGetLocal (PT_Ptr, ResultOffset, E))
942
958
return false ;
943
959
}
944
960
945
- if (!loadComplexValue (LHSIsComplex, ElemIndex, LHSOffset, LHS))
946
- return false ;
947
-
948
- if (!loadComplexValue (RHSIsComplex, ElemIndex, RHSOffset, RHS))
949
- return false ;
950
-
951
961
// The actual operation.
952
962
switch (Op) {
953
963
case BO_Add:
964
+ if (!loadComplexValue (LHSIsComplex, true , ElemIndex, LHSOffset, LHS))
965
+ return false ;
966
+
967
+ if (!loadComplexValue (RHSIsComplex, true , ElemIndex, RHSOffset, RHS))
968
+ return false ;
954
969
if (ResultElemT == PT_Float) {
955
970
if (!this ->emitAddf (getRoundingMode (E), E))
956
971
return false ;
@@ -960,6 +975,11 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
960
975
}
961
976
break ;
962
977
case BO_Sub:
978
+ if (!loadComplexValue (LHSIsComplex, true , ElemIndex, LHSOffset, LHS))
979
+ return false ;
980
+
981
+ if (!loadComplexValue (RHSIsComplex, true , ElemIndex, RHSOffset, RHS))
982
+ return false ;
963
983
if (ResultElemT == PT_Float) {
964
984
if (!this ->emitSubf (getRoundingMode (E), E))
965
985
return false ;
@@ -968,6 +988,21 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
968
988
return false ;
969
989
}
970
990
break ;
991
+ case BO_Mul:
992
+ if (!loadComplexValue (LHSIsComplex, false , ElemIndex, LHSOffset, LHS))
993
+ return false ;
994
+
995
+ if (!loadComplexValue (RHSIsComplex, false , ElemIndex, RHSOffset, RHS))
996
+ return false ;
997
+
998
+ if (ResultElemT == PT_Float) {
999
+ if (!this ->emitMulf (getRoundingMode (E), E))
1000
+ return false ;
1001
+ } else {
1002
+ if (!this ->emitMul (ResultElemT, E))
1003
+ return false ;
1004
+ }
1005
+ break ;
971
1006
972
1007
default :
973
1008
return false ;
0 commit comments