Esempio n. 1
0
 public StmCJump(Relation rel, TreeExp left, TreeExp right, Label ltrue, Label lfalse)
 {
     Rel        = rel;
     Left       = left;
     Right      = right;
     LabelTrue  = ltrue;
     LabelFalse = lfalse;
 }
        private CanonizedExp CanonExpression(TreeExp exp)
        {
            switch (exp)
            {
            case ExpCall call:
            {
                CanonizedExp cfunc = CanonNoTopCall(call.Function);

                List <CanonizedExp> cargs = new List <CanonizedExp>();
                foreach (var arg in call.Args)
                {
                    cargs.Add(CanonNoTopCall(arg));
                }

                return(CanonizedExp.Combine(cfunc, cargs, (a, b) => new ExpCall(a, b)));
            }

            case ExpConst constant:
            {
                return(new CanonizedExp(constant));
            }

            case ExpName name:
            {
                return(new CanonizedExp(name));
            }

            case ExpTemp temp:
            {
                return(new CanonizedExp(temp));
            }

            case ExpParam para:
            {
                return(new CanonizedExp(para));
            }

            case ExpMem mem:
            {
                return(CanonNoTopCall(mem.Address).MapExp((a) => new ExpMem(a)));
            }

            case ExpBinOp binop:
            {
                return(CanonizedExp.Combine(CanonNoTopCall(binop.Left), CanonNoTopCall(binop.Right),
                                            (l, r) => new ExpBinOp(binop.Operator, l, r)));
            }

            case ExpESeq eseq:
            {
                CanonizedExp b1   = new CanonizedExp(CanonStm(eseq.Stm), new ExpConst(0));
                CanonizedExp cres = CanonNoTopCall(eseq.Exp);
                return(CanonizedExp.Combine(b1, cres, (nop, e) => e));
            }

            default: throw new Exception("Shiiiit");
            }
        }
        CanonizedExp CanonNoTopCall(TreeExp e)
        {
            CanonizedExp ce = CanonExpression(e);

            if (ce.Exp is ExpCall)
            {
                TreeExp        call = ce.Exp;
                TreeExp        t    = new ExpTemp(new Temp());
                List <TreeStm> stms = new List <TreeStm>(ce.Body);
                stms.Add(new StmMove(t, call));
                ce = new CanonizedExp(stms, t);
            }
            return(ce);
        }
        Operand MunchExp(TreeExp exp)
        {
            switch (exp)
            {
            case ExpBinOp binop:
            {
                InstrBinary.Kind operation;

                switch (binop.Operator)
                {
                case ExpBinOp.Op.AND:
                {
                    operation = InstrBinary.Kind.AND;
                    break;
                }

                case ExpBinOp.Op.ARSHIFT:
                {
                    operation = InstrBinary.Kind.SHR;
                    break;
                }

                case ExpBinOp.Op.DIV:
                {
                    Emit(new InstrBinary(InstrBinary.Kind.MOV, new Operand.Reg(EAX), MunchExp(binop.Left)));
                    Operand     op   = MunchExp(binop.Right);
                    Operand.Reg temp = new Operand.Reg(new Temp());
                    if (op is Operand.Reg)
                    {
                        Emit(new InstrNullary(InstrNullary.Kind.CDQ));
                        Emit(new InstrUnary(InstrUnary.Kind.IDIV, op));
                    }
                    else
                    {
                        Emit(new InstrBinary(InstrBinary.Kind.MOV, temp, op));
                        Emit(new InstrNullary(InstrNullary.Kind.CDQ));
                        Emit(new InstrUnary(InstrUnary.Kind.IDIV, temp));
                    }
                    return(new Operand.Reg(EAX));
                }

                case ExpBinOp.Op.LSHIFT:
                {
                    operation = InstrBinary.Kind.SHL;
                    break;
                }

                case ExpBinOp.Op.MINUS:
                {
                    operation = InstrBinary.Kind.SUB;
                    break;
                }

                case ExpBinOp.Op.MUL:
                {
                    operation = InstrBinary.Kind.IMUL;
                    break;
                }

                case ExpBinOp.Op.OR:
                {
                    operation = InstrBinary.Kind.OR;
                    break;
                }

                case ExpBinOp.Op.PLUS:
                {
                    operation = InstrBinary.Kind.ADD;
                    break;
                }

                default: throw new Exception("not matched");
                }

                Operand tempOp = new Operand.Reg(new Temp());
                Emit(new InstrBinary(InstrBinary.Kind.MOV, tempOp, MunchExp(binop.Left)));
                Emit(new InstrBinary(operation, tempOp, MunchExp(binop.Right)));
                return(tempOp);
            }

            case ExpCall call:
            {
                ExpName name;

                if (call.Function is ExpName n)
                {
                    name = n;
                }
                else
                {
                    throw new Exception("No label");
                }

                for (int i = 0; i < call.Args.Count; i++)
                {
                    Temp argTemp = new Temp();
                    Emit(new InstrBinary(InstrBinary.Kind.MOV, new Operand.Reg(argTemp), MunchExp(call.Args[i])));
                    Emit(new InstrUnary(InstrUnary.Kind.PUSH, new Operand.Reg(argTemp)));
                }

                //Emit(new InstrBinary(InstrBinary.Kind.SUB, ))
                Emit(new InstrJump(InstrJump.Kind.CALL, name.Label, new List <RegTemp> {
                        (RegTemp)EAX, (RegTemp)ECX, (RegTemp)EDX
                    }));
                Emit(new InstrBinary(InstrBinary.Kind.ADD, new Operand.Reg(ESP), new Operand.Imm(call.Args.Count * 4)));
                return(new Operand.Reg(EAX));
            }

            case ExpConst con:
            {
                return(new Operand.Imm(con.Value));
            }

            case ExpMem mem:
            {
                // very confusing

                Temp bas = new Temp(); Temp index = new Temp();
                Emit(new InstrBinary(InstrBinary.Kind.MOV, new Operand.Reg(bas), MunchExp(mem.Address)));
                return(new Operand.Mem(bas));
            }

            case ExpName name:
            {
                Emit(new InstrLabel(name.Label));
                return(new Operand.Reg(new Temp()));
            }

            case ExpParam param:
            {
                //Temp parTemp = new Temp();
                //Emit(new InstrBinary(InstrBinary.Kind.MOV, new Operand.Reg(parTemp), new Operand.Mem(EBP, 0, null, (currentParamCount - param.Number) * 4 + 8)));
                //return new Operand.Reg(parTemp);
                return(new Operand.Mem(EBP, 0, null, (currentParamCount - param.Number) * 4 + 8));
            }

            case ExpTemp temp:
            {
                return(new Operand.Reg(temp.Temp));
            }

            default: throw new Exception("No expression matched.");
            }
        }
 public CanonizedExp(List <TreeStm> body, TreeExp exp)
 {
     Body = body;
     Exp  = exp;
 }
 public CanonizedExp(TreeExp exp)
 {
     Body     = Enumerable.Empty <TreeStm>().ToList();
     this.Exp = exp;
 }
 private static bool Commute(List <TreeStm> stms, TreeExp e)
 {
     return(stms.Any(s => Commute(s, e) == true));
 }
 private static bool Commute(TreeStm s, TreeExp e)
 {
     return((e is ExpName) || (e is ExpConst));
 }
        private List <TreeStm> CanonStm(TreeStm s)
        {
            switch (s)
            {
            case StmMove move:
            {
                if (move.Dest is ExpMem mem)
                {
                    TreeExp addr = ((ExpMem)move.Dest).Address;
                    CanonExpression(addr);
                    return(CanonizedExp.ToStm(CanonNoTopCall(addr), CanonNoTopCall(move.Source),
                                              (eaddr, esrc) => new StmMove(new ExpMem(eaddr), esrc)));
                }
                else if (move.Dest is ExpTemp)
                {
                    return(CanonExpression(move.Source).ToStm(esrc => new StmMove(move.Dest, esrc)));
                }
                else if (move.Dest is ExpParam)
                {
                    return(CanonExpression(move.Source).ToStm(esrc => new StmMove(move.Dest, esrc)));
                }
                else if (move.Dest is ExpESeq dst)
                {
                    return(CanonStm(new StmSeq(new List <TreeStm> {
                            dst.Stm, new StmMove(dst.Exp, move.Source)
                        })));
                }
                else
                {
                    throw new Exception("Left-hand side of MOVE must be TEMP, PARAM, MEM or ESEQ.");
                }
            }

            case StmJump jump:
            {
                return(CanonNoTopCall(jump.Dest).ToStm(e => new StmJump(e, jump.PossibleTargets)));
            }

            case StmCJump cjump:
            {
                return(CanonizedExp.ToStm(CanonNoTopCall(cjump.Left), CanonNoTopCall(cjump.Right),
                                          (l, r) => new StmCJump(cjump.Rel, l, r, cjump.LabelTrue, cjump.LabelFalse)));
            }

            case StmSeq seq:
            {
                List <TreeStm> cstms = new List <TreeStm>();
                foreach (var stat in seq.Stms)
                {
                    cstms.AddRange(CanonStm(stat));
                }
                return(cstms);
            }

            case StmLabel label:
            {
                List <TreeStm> stms = new List <TreeStm>();
                stms.Add(label);
                return(stms);
            }

            default: throw new Exception("Ya know, did not match any Statement.");
            }
        }
Esempio n. 10
0
 public ExpMem(TreeExp address)
 {
     Address = address;
 }
Esempio n. 11
0
 public ExpESeq(TreeStm stm, TreeExp exp)
 {
     Stm = stm;
     Exp = exp;
 }
Esempio n. 12
0
 public ExpCall(TreeExp func, List <TreeExp> args)
 {
     Function = func;
     Args     = args;
 }
Esempio n. 13
0
 public ExpBinOp(Op op, TreeExp left, TreeExp right)
 {
     Operator = op;
     Left     = left;
     Right    = right;
 }
Esempio n. 14
0
 public StmMove(TreeExp dest, TreeExp source)
 {
     Dest   = dest;
     Source = source;
 }
Esempio n. 15
0
 public StmJump(TreeExp dest, List <Label> targets)
 {
     Dest            = dest;
     PossibleTargets = targets;
 }