// Establish pointers between each block in the graph and its successor blocks private void LinkSuccessors(SortedDictionary <int, int> firsts, SortedDictionary <int, int> lasts) { foreach (KeyValuePair <int, IRBlock> pair in this.blocks) { IRBlock block = pair.Value; IRTuple tup = block.GetLast(); // Get last statement in block if (tup.getOp() == IrOp.JMP) { foreach (KeyValuePair <int, IRBlock> pair0 in this.blocks) { IRBlock block0 = pair0.Value; IRTuple tup0 = block0.GetFirst(); if (tup0.getOp() == IrOp.LABEL && tup0.getDest() == tup.getDest()) { block.AddSuccessor(block0); } } } else if (tup.getOp() == IrOp.JMPF) { foreach (KeyValuePair <int, IRBlock> pair0 in this.blocks) { IRBlock block0 = pair0.Value; IRTuple tup0 = block0.GetFirst(); if (tup0.getOp() == IrOp.LABEL && tup0.getDest() == ((IRTupleOneOpIdent)tup).getDest()) { block.AddSuccessor(block0); } else if (firsts[block0.GetIndex()] == lasts[block.GetIndex()] + 1) { block.AddSuccessor(block0); } } } else { foreach (KeyValuePair <int, IRBlock> pair0 in this.blocks) { IRBlock block0 = pair0.Value; if (firsts[block0.GetIndex()] == lasts[block.GetIndex()] + 1) { block.AddSuccessor(block0); } } } } }
public static string IRToARM(IRTuple IR) { IRTupleOneOpIdent IROOI = IR as IRTupleOneOpIdent; IRTupleOneOpImm<string> IROOImm = IR as IRTupleOneOpImm<string>; IRTupleTwoOp IRTO = IR as IRTupleTwoOp; if(IR.getOp() == IrOp.NEG){ return "Neg " + IROOI.getDest(); } if(IR.getOp() == IrOp.ADD){ return "ADD " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2(); } if(IR.getOp() == IrOp.SUB){ return "SUB " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2(); } if(IR.getOp() == IrOp.AND){ return "AND " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2(); } if(IR.getOp() == IrOp.MUL){ if(IRTO.getDest() != IRTO.getSrc1()){ return "MUL " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2(); } else{ return "MUL " + IRTO.getDest() + ", " + IRTO.getSrc2() + ", " + IRTO.getSrc1(); } } if(IR.getOp() == IrOp.CALL){ string str = "STRMFD sp, {R1-R12, lr}\n"; str += "BL " + IROOI.getDest(); if(IR.getDest()[0] == 'R'){ str = "MOV " + IROOI.getSrc1() + ", R0"; } else{ str = "LDR " + IROOI.getSrc1() + ", R0"; } return str; } if(IR.getOp() == IrOp.RET){ string str = ""; if(IR.getDest()[0] == 'R'){ str = "MOV R0, " + IR.getDest(); } else{ str = "LDR R0, " + IR.getDest(); } str += "\nLDMFD sp, {R1-R12, pc}"; return str; } // DIV if(IR.getOp() == IrOp.EQU){ string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() +'\n'; str += "MOVEQ " + IRTO.getDest() + ", #1\n"; str += "MOVNE " + IRTO.getDest() + ", #0"; return str; } if(IR.getOp() == IrOp.NEQ){ string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() +'\n'; str += "MOVEQ " + IRTO.getDest() + ", #0\n"; str += "MOVNE " + IRTO.getDest() + ", #1"; return str; } if(IR.getOp() == IrOp.LT){ string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() +'\n'; str += "MOVGE " + IRTO.getDest() + ", #0\n"; str += "MOVLT " + IRTO.getDest() + ", #1"; return str; } if(IR.getOp() == IrOp.GT){ string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() +'\n'; str += "MOVLE " + IRTO.getDest() + ", #0\n"; str += "MOVGT " + IRTO.getDest() + ", #1"; return str; } if(IR.getOp() == IrOp.JMP){ return "JMP " + IR.getDest(); } if(IR.getOp() == IrOp.JMPF){ string str = "CMP " + IROOI.getSrc1() + ", #0\n"; str += "JMPEQ " + IROOI.getDest(); return str; } if(IR.getOp() == IrOp.LABEL){ return IR.getDest() + ':'; } if(IR.getOp() == IrOp.FUNC) { return IR.getDest() + ':'; } // MOD if(IR.getOp() == IrOp.NOT){ return "MVN " + IROOI.getDest() + ", " + IROOI.getSrc1(); } if(IR.getOp() == IrOp.OR){ return "ORR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2(); } if(IR.getOp() == IrOp.XOR){ return "EOR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2(); } if(IR.getOp() == IrOp.STORE){ if(IR.getDest()[0] == 'R'){ return "LDR " + IROOI.getDest() + ", " + IROOI.getSrc1(); } return "STR " + IROOI.getDest() + ", " + IROOI.getSrc1(); } IR.Print(); return ""; }
// Return whether a tuple is of the type that may terminate a block private bool IsTerminator(IRTuple tuple) { return(tuple.getOp() == IrOp.JMP || tuple.getOp() == IrOp.JMPF || tuple.getOp() == IrOp.RET); }
// Return whether a tuple is of the type that may start a block private bool IsLeader(IRTuple tuple) { return(tuple.getOp() == IrOp.FUNC || tuple.getOp() == IrOp.LABEL); }
public static string IRToARM(IRTuple IR) { IRTupleOneOpIdent IROOI = IR as IRTupleOneOpIdent; IRTupleOneOpImm <string> IROOImm = IR as IRTupleOneOpImm <string>; IRTupleTwoOp IRTO = IR as IRTupleTwoOp; if (IR.getOp() == IrOp.NEG) { return("Neg " + IROOI.getDest()); } if (IR.getOp() == IrOp.ADD) { return("ADD " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2()); } if (IR.getOp() == IrOp.SUB) { return("SUB " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2()); } if (IR.getOp() == IrOp.AND) { return("AND " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2()); } if (IR.getOp() == IrOp.MUL) { if (IRTO.getDest() != IRTO.getSrc1()) { return("MUL " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2()); } else { return("MUL " + IRTO.getDest() + ", " + IRTO.getSrc2() + ", " + IRTO.getSrc1()); } } if (IR.getOp() == IrOp.CALL) { string str = "STRMFD sp, {R1-R12, lr}\n"; str += "BL " + IROOI.getDest(); if (IR.getDest()[0] == 'R') { str = "MOV " + IROOI.getSrc1() + ", R0"; } else { str = "LDR " + IROOI.getSrc1() + ", R0"; } return(str); } if (IR.getOp() == IrOp.RET) { string str = ""; if (IR.getDest()[0] == 'R') { str = "MOV R0, " + IR.getDest(); } else { str = "LDR R0, " + IR.getDest(); } str += "\nLDMFD sp, {R1-R12, pc}"; return(str); } // DIV if (IR.getOp() == IrOp.EQU) { string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n'; str += "MOVEQ " + IRTO.getDest() + ", #1\n"; str += "MOVNE " + IRTO.getDest() + ", #0"; return(str); } if (IR.getOp() == IrOp.NEQ) { string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n'; str += "MOVEQ " + IRTO.getDest() + ", #0\n"; str += "MOVNE " + IRTO.getDest() + ", #1"; return(str); } if (IR.getOp() == IrOp.LT) { string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n'; str += "MOVGE " + IRTO.getDest() + ", #0\n"; str += "MOVLT " + IRTO.getDest() + ", #1"; return(str); } if (IR.getOp() == IrOp.GT) { string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n'; str += "MOVLE " + IRTO.getDest() + ", #0\n"; str += "MOVGT " + IRTO.getDest() + ", #1"; return(str); } if (IR.getOp() == IrOp.JMP) { return("JMP " + IR.getDest()); } if (IR.getOp() == IrOp.JMPF) { string str = "CMP " + IROOI.getSrc1() + ", #0\n"; str += "JMPEQ " + IROOI.getDest(); return(str); } if (IR.getOp() == IrOp.LABEL) { return(IR.getDest() + ':'); } if (IR.getOp() == IrOp.FUNC) { return(IR.getDest() + ':'); } // MOD if (IR.getOp() == IrOp.NOT) { return("MVN " + IROOI.getDest() + ", " + IROOI.getSrc1()); } if (IR.getOp() == IrOp.OR) { return("ORR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2()); } if (IR.getOp() == IrOp.XOR) { return("EOR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2()); } if (IR.getOp() == IrOp.STORE) { if (IR.getDest()[0] == 'R') { return("LDR " + IROOI.getDest() + ", " + IROOI.getSrc1()); } return("STR " + IROOI.getDest() + ", " + IROOI.getSrc1()); } IR.Print(); return(""); }