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"); }
/*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 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号 } }