m3front/src/exprs/CopyExpr.m3


Copyright (C) 1994, Digital Equipment Corp.
File: CopyExpr.m3 Last Modified On Fri Feb 24 16:42:26 PST 1995 By kalsow Modified On Sun Dec 23 08:07:22 1990 By muller

MODULE CopyExpr;

IMPORT M3, CG, Expr, ExprRep, Type, Target, TInt;
IMPORT AssignStmt, OpenArrayType;

TYPE
  P = Expr.T BRANDED "CopyExpr" OBJECT
        expr   : Expr.T;
	tipe   : Type.T;
        tmp    : CG.Var;
      OVERRIDES
        typeOf       := ExprRep.NoType;
        check        := Check;
        need_addr    := NeedsAddress;
        prep         := Prep;
        compile      := Compile;
        prepLV       := Prep;
        compileLV    := CompileLV;
        prepBR       := ExprRep.PrepNoBranch;
        compileBR    := ExprRep.NoBranch;
        evaluate     := Fold;
        isEqual      := EqCheck;
        getBounds    := Bounder;
        isWritable   := ExprRep.IsNever;
        isDesignator := ExprRep.IsAlways;
	isZeroes     := ExprRep.IsNever;
	genFPLiteral := ExprRep.NoFPLiteral;
	prepLiteral  := ExprRep.NoPrepLiteral;
	genLiteral   := ExprRep.NoLiteral;
        note_write   := NoteWrites;
      END;

PROCEDURE New (a: Expr.T; t: Type.T): Expr.T =
  VAR p: P;
  BEGIN
    p := NEW (P);
    ExprRep.Init (p);
    p.expr   := a;
    p.tipe   := t;
    p.type   := t;
    p.tmp    := NIL;
    RETURN p;
  END New;

PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =
  BEGIN
    Expr.TypeCheck (p.expr, cs);
    p.tipe := Type.Check (p.tipe);
  END Check;

PROCEDURE EqCheck (a: P;  e: Expr.T;  x: M3.EqAssumption): BOOLEAN =
  BEGIN
    TYPECASE e OF
    | NULL => RETURN FALSE;
    | P(b) => RETURN Type.IsEqual (a.tipe, b.tipe, x)
                 AND Expr.IsEqual (a.expr, b.expr, x);
    ELSE      RETURN FALSE;
    END;
  END EqCheck;

PROCEDURE NeedsAddress (<*UNUSED*> p: P) =
  BEGIN
    (* yep, that's the whole reason for a Copy! *)
  END NeedsAddress;

PROCEDURE Prep (p: P) =
  VAR
    e  := p.expr;
    t  := p.tipe;
    sz, align: INTEGER;
    t_info: Type.Info;
  BEGIN
    t := Type.CheckInfo (t, t_info);
    sz := t_info.size;
    align := t_info.alignment;
    Type.Compile (t);
    IF (t_info.class = Type.Class.OpenArray) THEN
      sz := Target.Address.pack
             + OpenArrayType.OpenDepth(t) * Target.Integer.pack;
    END;
    Expr.Prep (e);
    p.tmp := CG.Declare_temp (sz, align, t_info.cg_type, in_memory := TRUE);
    CG.Load_addr_of (p.tmp, 0, align);
    AssignStmt.Emit (t, e);
  END Prep;

PROCEDURE Compile (p: P) =
  VAR
    t  := p.tipe;
    t_info: Type.Info;
    align: INTEGER;
  BEGIN
    t := Type.CheckInfo (t, t_info);
    align := t_info.alignment;

    IF Type.IsStructured (t) THEN
      CG.Load_addr_of_temp (p.tmp, 0, align);
    ELSE
      CG.Load (p.tmp, 0, t_info.size, align, t_info.cg_type);
      CG.Free_temp (p.tmp);
    END;
    p.tmp := NIL;
  END Compile;

PROCEDURE CompileLV (p: P) =
  VAR
    t  := p.tipe;
    t_info: Type.Info;
  BEGIN
    EVAL Type.CheckInfo (t, t_info);
    CG.Load_addr_of_temp (p.tmp, 0, t_info.alignment);
    p.tmp := NIL;
  END CompileLV;

PROCEDURE Fold (p: P): Expr.T =
  BEGIN
    RETURN Expr.ConstValue (p.expr);
    (********* WKK 11/21/91 ??? **********************
    e := Expr.ConstValue (p.expr);
    IF (e = NIL) THEN RETURN NIL END;
    p.expr := e;
    RETURN p;
    *****************************************************)
  END Fold;

PROCEDURE Bounder (p: P;  VAR min, max: Target.Int) =
  VAR min1, max1: Target.Int;
  BEGIN
    Expr.GetBounds (p.expr, min, max);
    EVAL Type.GetBounds (p.tipe, min1, max1);
    IF TInt.LT (min, min1) THEN min := min1 END;
    IF TInt.LT (max1, max) THEN max := max1 END;
  END Bounder;

PROCEDURE NoteWrites (<*UNUSED*> p: P) =
  BEGIN
    (* nothing to trace *)
  END NoteWrites;

BEGIN
END CopyExpr.