void MunchStm(TreeStm stm)
        {
            switch (stm)
            {
            case StmCJump cjump:
            {
                if (cjump.Left is ExpConst c)
                {
                    Temp constTemp = new Temp();
                    Emit(new InstrBinary(InstrBinary.Kind.MOV, new Operand.Reg(constTemp), new Operand.Imm(c.Value)));
                    Emit(new InstrBinary(InstrBinary.Kind.CMP, new Operand.Reg(constTemp), MunchExp(cjump.Right)));
                }
                else
                {
                    Operand op1 = MunchExp(cjump.Left);
                    Operand op2 = MunchExp(cjump.Right);

                    if (op1 is Operand.Mem && op2 is Operand.Mem)
                    {
                        Operand.Reg memTemp = new Operand.Reg(new Temp());
                        Emit(new InstrBinary(InstrBinary.Kind.MOV, memTemp, op1));
                        Emit(new InstrBinary(InstrBinary.Kind.CMP, memTemp, op2));
                    }
                    else
                    {
                        Emit(new InstrBinary(InstrBinary.Kind.CMP, op1, op2));
                    }
                    //Emit(new InstrBinary(InstrBinary.Kind.CMP, MunchExp(cjump.Left), MunchExp(cjump.Right)));
                }

                InstrJump.Cond cond;

                switch (cjump.Rel)
                {
                case StmCJump.Relation.EQ:
                {
                    cond = InstrJump.Cond.NE;
                    break;
                }

                case StmCJump.Relation.GE:
                {
                    cond = InstrJump.Cond.L;
                    break;
                }

                case StmCJump.Relation.GT:
                {
                    cond = InstrJump.Cond.LE;
                    break;
                }

                case StmCJump.Relation.LE:
                {
                    cond = InstrJump.Cond.G;
                    break;
                }

                case StmCJump.Relation.LT:
                {
                    cond = InstrJump.Cond.GE;
                    break;
                }

                case StmCJump.Relation.NE:
                {
                    cond = InstrJump.Cond.E;
                    break;
                }

                default: throw new Exception("No Relation matched!");
                }
                Emit(new InstrJump(cond, cjump.LabelFalse));
                break;
            }

            case StmJump jump:
            {
                Emit(new InstrJump(InstrJump.Kind.JMP, jump.PossibleTargets[0]));
                break;
            }

            case StmLabel label:
            {
                Emit(new InstrLabel(label.Label));
                break;
            }

            case StmMove move:
            {
                Operand op1 = MunchExp(move.Dest);
                Operand op2 = MunchExp(move.Source);

                if (op1 is Operand.Mem && op2 is Operand.Mem)
                {
                    Operand.Reg t = new Operand.Reg(new Temp());

                    Emit(new InstrBinary(InstrBinary.Kind.MOV, t, op2));
                    Emit(new InstrBinary(InstrBinary.Kind.MOV, op1, t));
                }
                else
                {
                    Emit(new InstrBinary(InstrBinary.Kind.MOV, op1, op2));
                }

                break;
            }

            case StmSeq seq:
            {
                throw new Exception("No Sequences allowed!");
            }

            default:
            {
                throw new Exception("No case matched!");
            }
            }
        }
        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.");
            }
        }
 private static bool Commute(TreeStm s, TreeExp e)
 {
     return((e is ExpName) || (e is ExpConst));
 }
Exemple #4
0
 public ExpESeq(TreeStm stm, TreeExp exp)
 {
     Stm = stm;
     Exp = exp;
 }