/** * Grammar production: * f0 -> "CJUMP" * f1 -> Temp() * f2 -> Label() */ public void visit(CJumpStmt n, ARGU argu) { String t1 = ReadTemp(n.f1, argu, 0); OutPut.con(" CJUMP " + t1 + " "); n.f2.accept(this, argu); OutPut.con("\n"); }
/** * Grammar production: * f0 -> "HSTORE" * f1 -> Temp() * f2 -> IntegerLiteral() * f3 -> Temp() */ public void visit(HStoreStmt n,ARGU argu) { String t1 = ReadTemp(n.f1, argu, 0); String t2 = ReadTemp(n.f3, argu, 1); OutPut.con(" HSTORE " + t1 + " "); n.f2.accept(this, argu); OutPut.con(" " + t2 + "\n"); }
/*public void visit(Call n, ARGU argu) { int size = n.f3.size(); int i; Proc currProc = (Proc)argu; Iterator<Node> Itr = n.f3.nodes.iterator(); for(i=0;i<4&&i<size;i++) {//将参数放在a0-a3里 String t1 = ReadTemp((Temp)Itr.next(), argu, 0); OutPut.con(" MOVE " + "a" + i + " " + t1 + "\n"); } int j=1; for(;i<size;i++,j++) {//如果参数多于4个,都将其放到栈里 String t1 = ReadTemp((Temp)Itr.next(),argu, 0); OutPut.con(" PASSARG " + j + " " + t1 + "\n"); } String t1 = SimpleExpCode(n.f1, argu,0); OutPut.con(" CALL " + t1 + "\n"); if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+ "\n"); else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+ "\n"); } */ public void visit(Operator n, ARGU argu) { switch(n.f0.which) { case 0: OutPut.con(" LT ");return; case 1: OutPut.con(" PLUS ");return; case 2: OutPut.con(" MINUS "); return; case 3: OutPut.con(" TIMES "); return; } }
public void visit(Label n, ARGU argu) { String s = n.f0.toString(); if (argu==null) { OutPut.con(" "+s+" "); } else { Proc currProc=(Proc)argu; OutPut.con(" " +currProc.GetLab( s )+ " "); } }
public void FuncEnd(ARGU argu,int ParaNum) {//函数结束,恢复所有的寄存器 Proc currProc = (Proc)argu; Vector<String> Registers= currProc.TakenRegs(); if(ParaNum-4>0) //如果参数数目大于4,因为大于4的参数在栈里面,所以恢复寄存器的时候要从f1-3开始往下恢复,f1代表参数数目 for(int i=ParaNum-4,j=0;i<ParaNum-4+Registers.size();i++,j++) OutPut.con(" ALOAD " + Registers.get(j) + " SPILLEDARG " + i + "\n"); else//如果参数数目小于等于4,因为没有参数在栈里面,所以恢复寄存器的时候从0开始往下恢复即可 for(int i=0,j=0;i<Registers.size();i++,j++) OutPut.con(" ALOAD " + Registers.get(j) + " SPILLEDARG " + i + "\n"); OutPut.con("END\n"); }
/** * Grammar production: * f0 -> "HLOAD" * f1 -> Temp() * f2 -> Temp() * f3 -> IntegerLiteral() */ public void visit(HLoadStmt n,ARGU argu) { Proc currProc = (Proc)argu; String t = currProc.GetReg(Integer.parseInt(n.f1.f1.f0.tokenImage)); if(t==null) { OutPut.con(" NOOP \n"); return; } String t1 = WriteTemp(n.f1,argu, 0); String t2 = ReadTemp(n.f2,argu, 0); OutPut.con(" HLOAD " + t1 + " " + t2 + " "); n.f3.accept(this, argu); OutPut.con("\n"); SpillToStack(n.f1,argu,0); }
public void SpillToStack(Temp n, ARGU argu,int vRegister) {//如果转换之前HLOAD的第一个寄存器是注定要溢出的,那么用v0或v1先存放HLOAD进来的值,然后把该值溢出到栈里 Proc currProc = (Proc)argu; String t1 = currProc.GetReg(Integer.parseInt(n.f1.f0.tokenImage)); if(t1.equals("OverFlow")) { if( !currProc.StackRecorder.contains(Integer.parseInt(n.f1.f0.tokenImage))) { OutPut.con(" ASTORE " + " SPILLEDARG " + currProc.StackRecorder.size()+ " " + RegPlan.RegList[vRegister+4] + "\n"); currProc.StackRecorder.add(Integer.parseInt(n.f1.f0.tokenImage)); } else OutPut.con(" ASTORE " + " SPILLEDARG " + currProc.StackRecorder.indexOf(Integer.parseInt(n.f1.f0.tokenImage))+ " " + RegPlan.RegList[vRegister+4] + "\n"); } return ; }
public String ReadTemp(Temp n,ARGU argu, int vRegister) { Proc currProc = (Proc)argu; String t1 = currProc.GetReg(Integer.parseInt(n.f1.f0.tokenImage)); if(t1.equals("OverFlow")) { OutPut.con(" ALOAD " + RegPlan.RegList[vRegister+4] + " SPILLEDARG " +currProc.StackRecorder.indexOf(Integer.parseInt(n.f1.f0.tokenImage))+ "\n"); return RegPlan.RegList[vRegister+4]; } else//如果当前temp 要占用寄存器的话 return t1; }
public void FuncBegin(String funcName,ARGU argu,int ParaNum, int MaxStack, int MaxPara) {//函数开始,保存所有的寄存器 Proc currProc = (Proc)argu; Vector<String> Registers= currProc.TakenRegs(); OutPut.con(funcName + " [ " + ParaNum + " ] [ " + MaxStack + " ] [ " +MaxPara+ " ]\n"); for(int i=4;i<ParaNum;i++) currProc.StackRecorder.add(i);//放父函数传进来的参数 if(ParaNum-4>0)//如果参数数目大于4,因为大于4的参数都要放到栈里面,所以存放寄存器的栈要接着存放参数的栈单元即为f1-3的位置往下增长,这里f1代表参数数目 { int i,j; for(i=ParaNum-4,j=0;i<ParaNum-4+Registers.size();i++,j++) { OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + Registers.get(j) + "\n"); currProc.StackRecorder.add(-1); }//存放所有使用的寄存器但除了a0-a3,因为不是temp溢出,所以不用存放temp号,这里用-1代替temp号 for(j=0;j<currProc.ParaStack.size();j++,i++) { OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + currProc.ParaStack.get(j) + "\n"); currProc.StackRecorder.add(-1); }//存放a0->a3,因为不是temp溢出,所以不用存放temp号,这里用-1代替temp号 } else { int i,j; for(i=0,j=0;i<Registers.size();i++,j++) { OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + Registers.get(j) + "\n"); currProc.StackRecorder.add(-1); }//如果参数数目小于等于4,因为参数都不放到栈里面,所以存放寄存器的栈从0开始增长即可 for(j=0;j<currProc.ParaStack.size();j++,i++) { OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + currProc.ParaStack.get(j) + "\n"); currProc.StackRecorder.add(-1); }//存放a0->a3,因为不是temp溢出,所以不用存放temp号,这里用-1代替temp号 } }
/** * Grammar production: * f0 -> "MOVE" * f1 -> Temp() * f2 -> Exp() * Exp() Grammar production: * f0 -> Call() * | HAllocate() * | BinOp() * | SimpleExp() */ public void visit(MoveStmt n,ARGU argu) { Proc currProc = (Proc)argu; String t = currProc.GetReg(Integer.parseInt(n.f1.f1.f0.tokenImage));; if(t==null) //************************************************ { OutPut.con(" NOOP \n" ); return; } //************************************************* int i = n.f2.f0.which; if(i == 0)//是call语句 { n.f2.accept(this, argu); OutPut.con("\n"); String t1 = WriteTemp(n.f1,argu, 0); OutPut.con(" MOVE " + t1 + " v0\n" ); SpillToStack(n.f1,argu,0); return; } else if(i == 1)//是HALLOCATE { String t1 = SimpleExpCode(((HAllocate)n.f2.f0.choice).f1, argu,0);//s1 返回的是个数值 String t2 = WriteTemp(n.f1, argu, 0); OutPut.con(" MOVE " + t2 + " HALLOCATE " + t1 + "\n"); SpillToStack(n.f1,argu,0); return; } else if(i == 2)//是binop { String t1 = ReadTemp(((BinOp)n.f2.f0.choice).f1, argu, 0);//b.f1是个寄存器 String t2 = SimpleExpCode(((BinOp)n.f2.f0.choice).f2, argu,1);//s1 返回的是个数值 String t3 = WriteTemp(n.f1, argu, 0); OutPut.con(" MOVE " + t3 + " "); ((BinOp)n.f2.f0.choice).f0.accept(this, argu);//b.f0是个运算符 OutPut.con(" " + t1 + " " + t2 + "\n"); SpillToStack(n.f1,argu,0); } else if(i == 3)//是简单表达式 { String t1 = WriteTemp(n.f1,argu, 0); String t2 = SimpleExpCode(((SimpleExp)n.f2.f0.choice), argu,0);//s1 返回的是个数值 OutPut.con(" MOVE " + t1 + " " + t2 + "\n"); SpillToStack(n.f1,argu,0); } return; }
/** * Grammar production: * f0 -> "JUMP" * f1 -> Label() */ public void visit(JumpStmt n, ARGU argu) { OutPut.con(" JUMP "); n.f1.accept(this, argu); OutPut.con("\n"); }
/** * Grammar production: * f0 -> "PRINT" * f1 -> SimpleExp() */ public void visit(PrintStmt n,ARGU argu) { String s1 = SimpleExpCode(n.f1,argu,0); OutPut.con(" PRINT " + s1 + "\n"); }
public void visit(ErrorStmt n, ARGU argu) { OutPut.con(" ERROR\n"); }
public void visit(NoOpStmt n, ARGU argu) { OutPut.con(" NOOP\n"); }
/** * Grammar production: * f0 -> "BEGIN" * f1 -> StmtList() * f2 -> "RETURN" * f3 -> SimpleExp() * f4 -> "END" */ public void visit(StmtExp n, ARGU argu) { n.f1.accept(this, argu); String t1 = SimpleExpCode(n.f3, argu,0);//处理返回值 OutPut.con(" MOVE " + "v0 " + t1 + "\n"); }
/*public void visit(Call n, ARGU argu)//////////////////// { int size = n.f3.size(); int i; Proc currProc = (Proc)argu; Iterator<Node> Itr = n.f3.nodes.iterator(); if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ASTORE " + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n"); else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ASTORE " + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n"); for(i=0;i<4&&i<size;i++) {//将参数放在a0-a3里 String t1 = ReadTemp((Temp)Itr.next(), argu, 0); if (t1.charAt(0)=='a') { String s =""+t1.charAt(1); if(currProc.ParaNum>4) OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n"); else OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n"); OutPut.con("MOVE "+"a" +i+" v0\n"); } else { OutPut.con(" MOVE " + "a" + i + " "+t1+"\n"); } } int j=1; for(;i<size;i++,j++) {//如果参数多于4个,都将其放到栈里 String t1 = ReadTemp((Temp)Itr.next(),argu, 0); OutPut.con(" PASSARG " + j + " " + t1 + "\n"); } String t1 = SimpleExpCode(n.f1, argu,0); OutPut.con(" CALL " + t1 + "\n"); if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+ "\n"); else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+ "\n"); }*/ public void visit(Call n, ARGU argu)//////////////////// { int size = n.f3.size(); int i; Proc currProc = (Proc)argu; Iterator<Node> Itr = n.f3.nodes.iterator(); if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ASTORE " + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n"); else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ASTORE " + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n"); for(i=0;i<4&&i<size;i++) {//将参数放在a0-a3里 String t1 = ReadTemp((Temp)Itr.next(), argu, 0); if (t1.charAt(0)=='a') { String s =""+t1.charAt(1); if(currProc.ParaNum>4) OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n"); else OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n"); OutPut.con("MOVE "+"a" +i+" v0\n"); } else { OutPut.con(" MOVE " + "a" + i + " "+t1+"\n"); } } int j=1; for(;i<size;i++,j++) {//如果参数多于4个,都将其放到栈里 String t1 = ReadTemp((Temp)Itr.next(), argu, 0); if (t1.charAt(0)=='a') { String s =""+t1.charAt(1); OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n"); OutPut.con(" PASSARG " + j + " v0 \n"); } else { OutPut.con(" PASSARG " + j + " " + t1 + "\n"); } // String t1 = ReadTemp((Temp)Itr.next(),argu, 0); // OutPut.con(" PASSARG " + j + " " + t1 + "\n"); } String t1 = SimpleExpCode(n.f1, argu,0); OutPut.con(" CALL " + t1 + "\n"); if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+ "\n"); else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元 for(int k=0;k<currProc.ParaStack.size();k++) OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+ "\n"); }
public void visit(IntegerLiteral n, ARGU argu) { String s = n.f0.toString(); OutPut.con(" " + s + " "); }