|
|
@@ -973,6 +973,8 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
kind, op, rop: INTEGER;
|
|
|
folded, isR, isCh: BOOLEAN;
|
|
|
i: CARDINAL; el: AST.Node;
|
|
|
+ lw, rw, mw: CARDINAL; idx: INTEGER; fok, isL: BOOLEAN;
|
|
|
+ lt, rt: SymTab.TypeIndex; qw: QbeGen.QVal;
|
|
|
BEGIN
|
|
|
IF AST.Kind(n) = AST.NkDesignator THEN
|
|
|
LowerDesign(n, t, k, q, qn, sfx);
|
|
|
@@ -1097,28 +1099,82 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
ELSE
|
|
|
LowerExpr(AST.Child(n, 0), t, q);
|
|
|
LowerExpr(AST.Child(n, 1), t2, q2);
|
|
|
- kind := 0;
|
|
|
- IF op = AST.OpSub THEN kind := 1
|
|
|
- ELSIF op = AST.OpMul THEN kind := 2
|
|
|
- ELSIF op = AST.OpDiv THEN kind := 3
|
|
|
- ELSIF op = AST.OpMod THEN kind := 4
|
|
|
- END;
|
|
|
- folded := FALSE;
|
|
|
- IF QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- folded := QbeGen.Fold2(kind, q, q2, qf)
|
|
|
- END;
|
|
|
- IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- ELSE
|
|
|
- QbeGen.NewTemp(qt);
|
|
|
- IF op = AST.OpAdd THEN QbeGen.Op3("add", qt, q, q2, FALSE)
|
|
|
- ELSIF op = AST.OpSub THEN QbeGen.Op3("sub", qt, q, q2, FALSE)
|
|
|
- ELSIF op = AST.OpMul THEN QbeGen.Op3("mul", qt, q, q2, FALSE)
|
|
|
- ELSIF op = AST.OpDiv THEN QbeGen.Op3("div", qt, q, q2, FALSE)
|
|
|
- ELSE QbeGen.Op3("rem", qt, q, q2, FALSE)
|
|
|
+ IF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ (* set union/diff (Add/Sub) or intersection/symdiff (Mul/Div) *)
|
|
|
+ lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ mw := lw; IF rw > mw THEN mw := rw END;
|
|
|
+ IF op = AST.OpAdd THEN idx := 0
|
|
|
+ ELSIF op = AST.OpSub THEN idx := 2
|
|
|
+ ELSIF op = AST.OpMul THEN idx := 1
|
|
|
+ ELSE idx := 3
|
|
|
END;
|
|
|
+ QbeGen.SetBinOp(idx, q, q2, lw, rw, qt);
|
|
|
+ t := SymTab.NewSet(SymTab.NewSubR(0, VAL(INTEGER, mw) * 32 - 1));
|
|
|
QbeGen.CopyOp(qt, q)
|
|
|
- END;
|
|
|
- t := SymTab.IntType()
|
|
|
+ ELSIF (op = AST.OpAdd)
|
|
|
+ AND (SymTab.StrCompat(t, t2)
|
|
|
+ OR (SymTab.IsStrType(t) AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ OR ((SymTab.ClassOf(t) = SymTab.ClChar) AND SymTab.IsStrType(t2))) THEN
|
|
|
+ QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2), qt, fok);
|
|
|
+ IF NOT fok THEN
|
|
|
+ IF SymTab.StrCompat(t, t2) THEN QbeGen.StrCat(q, q2, qt)
|
|
|
+ ELSIF SymTab.IsStrType(t) THEN
|
|
|
+ QbeGen.DeclCharStr(q2, qs); QbeGen.StrCat(q, qs, qt)
|
|
|
+ ELSE
|
|
|
+ QbeGen.DeclCharStr(q, qs); QbeGen.StrCat(qs, q2, qt)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ t := SymTab.NewStr(); QbeGen.CopyOp(qt, q)
|
|
|
+ ELSE
|
|
|
+ lt := t; rt := t2;
|
|
|
+ IF (SymTab.ClassOf(lt) = SymTab.ClReal)
|
|
|
+ OR (SymTab.ClassOf(rt) = SymTab.ClReal) THEN
|
|
|
+ t := SymTab.RealType()
|
|
|
+ ELSIF SymTab.IsLongFamily(lt) OR SymTab.IsLongFamily(rt) THEN
|
|
|
+ t := SymTab.LongType()
|
|
|
+ ELSE t := SymTab.IntType()
|
|
|
+ END;
|
|
|
+ isL := SymTab.IsLongFamily(t);
|
|
|
+ isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ kind := 0;
|
|
|
+ IF op = AST.OpSub THEN kind := 1
|
|
|
+ ELSIF op = AST.OpMul THEN kind := 2
|
|
|
+ ELSIF op = AST.OpDiv THEN kind := 3
|
|
|
+ ELSIF op = AST.OpMod THEN kind := 4
|
|
|
+ END;
|
|
|
+ folded := FALSE;
|
|
|
+ IF (NOT isL) AND (NOT isR) AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ folded := QbeGen.Fold2(kind, q, q2, qf)
|
|
|
+ END;
|
|
|
+ IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ ELSE
|
|
|
+ IF isL THEN
|
|
|
+ IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ QbeGen.WidenLong(q, qw); QbeGen.CopyOp(qw, q)
|
|
|
+ END;
|
|
|
+ IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ QbeGen.WidenLong(q2, qw); QbeGen.CopyOp(qw, q2)
|
|
|
+ END;
|
|
|
+ QbeGen.NewTemp(qt);
|
|
|
+ IF op = AST.OpAdd THEN QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ ELSIF op = AST.OpSub THEN QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ ELSIF op = AST.OpMul THEN QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ ELSE QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ END
|
|
|
+ ELSE
|
|
|
+ QbeGen.NewTemp(qt);
|
|
|
+ IF op = AST.OpAdd THEN QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ ELSIF op = AST.OpSub THEN QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ ELSIF op = AST.OpMul THEN QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ ELSIF op = AST.OpDiv THEN QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ ELSE QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ QbeGen.CopyOp(qt, q)
|
|
|
+ END
|
|
|
+ END
|
|
|
END
|
|
|
END
|
|
|
END LowerExprFull;
|