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)); }
public ExpESeq(TreeStm stm, TreeExp exp) { Stm = stm; Exp = exp; }