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."); } }
public ExpMem(TreeExp address) { Address = address; }
public ExpESeq(TreeStm stm, TreeExp exp) { Stm = stm; Exp = exp; }
public ExpCall(TreeExp func, List <TreeExp> args) { Function = func; Args = args; }
public ExpBinOp(Op op, TreeExp left, TreeExp right) { Operator = op; Left = left; Right = right; }
public StmMove(TreeExp dest, TreeExp source) { Dest = dest; Source = source; }
public StmJump(TreeExp dest, List <Label> targets) { Dest = dest; PossibleTargets = targets; }