⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codegeneration.java

📁 用Java实现的编译器。把源代码编译成SPARC汇编程序
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/**
*This class is used for expressions using the AND operation.
*This class extends the Exp abstract class
**/
package CatDecaf.CG;
import CatDecaf.IR.*;
import CatDecaf.Utilities.*;
import java6035.tools.ASM.*;
import java.io.*;
import java.util.*;
import CatDecaf.SymTable.*;

public class CodeGeneration implements Visitor{

public static int tab;
public ASM asm;
static int labelCnt;
public List dataLabelList;
public static boolean algebraicSimplification;

	public CodeGeneration(){
		labelCnt = 0;
		asm = new ASM();
		SPARCRegister.releaseAllRegisters();	
		
		dataLabelList = new ArrayList();
		
		tab=0;
		
	}

	public void generate(String outfile){
		//append the data section
		asm.appendEntry(new ASMComment("Datasection"));

		Iterator i = dataLabelList.iterator();
		while(i.hasNext()){
			asm.appendEntry((ASMEntry)(i.next()));
		}


		    try {

			/*
			 * For the heck of it, let's build an ASM file.
			 */
			FileOutputStream out = new FileOutputStream(outfile);
			SPARCGenerator sparcgen = 
			    new SPARCGenerator(out);

			/*
			 * Generate SPARC asm file
			 */
			sparcgen.gen(asm);
			sparcgen.done();

			/*
			 * Close file
			 */
			out.close();

		    } catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
		    }		
	}
	
	
	public void visit(Ir n){        } //abstract class
	public void visit(IrProg n){
				asm.appendEntry(new dSection(".data"));
		asm.appendEntry(new ASMLabel(".GLOBALFIELD"));
		Iterator it = parser.parser.classProgram.fieldVar.getDescriptorTable().values().iterator();
		while(it.hasNext()){
			IDDescriptor idd = (IDDescriptor)it.next();
			if(!idd.isArrayType()){
				asm.appendEntry(new dAlign(4));
				asm.appendEntry(new dWord(1));
			}else{
				asm.appendEntry(new dAlign(4));
				//Long[] l = {idd.getArraySize()};
				asm.appendEntry(new dWord(new Long[] {new Long(idd.getArraySize())}));				
				//asm.appendEntry(new dWord(idd.getArraySize()));
				asm.appendEntry(new dSkip(idd.getArraySize() * 4));
			}
		}
		asm.appendEntry(new ASMLabel(".ARRAY_OUT_OF_BOUND"));
		asm.appendEntry(new dAsciz(parser.parser.infile + ":%d: runtime error: array out of bound; accessing: %d, array size: %d\n"));
		asm.appendEntry(new dAlign(4));
		asm.appendEntry(new ASMLabel(".DIVISION_ZERO"));
		asm.appendEntry(new dAsciz(parser.parser.infile + ":%d: runtime error: division to zero\n"));
		asm.appendEntry(new dAlign(4));
		asm.appendEntry(new ASMLabel(".CONTROL_FALLING_OFF"));
		asm.appendEntry(new dAsciz(parser.parser.infile + ":%s: runtime error: control falling off the end of the method: %s , missing a return value\n"));
		asm.appendEntry(new dAlign(4));		
		asm.appendEntry(new dSection(".text"));
		asm.appendEntry(new dAlign(4));
		asm.appendEntry(new dGlobal("main"));
		

		//if(n.fdDeclList_!=null)
		//	n.fdDeclList_.accept(this);
		if(n.mdDeclList_ == null) System.out.println("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!");
			n.mdDeclList_.accept(this);  //this should never be empty

	}
	public void visit(FdDeclList n){ //not printing List classes
		while(n!= null)
		{	
			n.fdDecl_.accept(this);
			n = n.fdDeclList_;
		}
	}
	public void visit(FdDecl n){

		if(n.glbVarList_==null) System.out.println("ERROR!!!!!!!!!!!!!!!");
		n.typ_.accept(this);
		n.glbVarList_.accept(this);

	}
	public void visit(GlbVar n){ } //abstract class
	public void visit(GlbVarArray n){

		n.identifier_.accept(this);
		n.ltrInt_.accept(this);

	}	
	public void visit(GlbVarId n){

		n.identifier_.accept(this);

	}	
	public void visit(GlbVarList n){ //not printing List classes
		while(n!= null)
		{	
			n.glbVar_.accept(this);
			n = n.glbVarList_;
		}
	}	
	public void visit(Typ n){	}	//abstract class
	public void visit(TypInt n){

	}
	public void visit(TypBool n){


	}
	public void visit(TypVoid n){

	}
	public void visit(MdDeclList n){ //not printing List classes
		while(n!= null)
		{	
			n.mdDecl_.accept(this);
			n = n.mdDeclList_;
		}
	}	
	public void visit(MdDecl n){
		asm.appendEntry( new ASMLabel(n.identifier_.identifier_) );
		if(n.identifier_.identifier_.equals("main")){
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".GLOBALFIELD")), SPARCRegister.g2));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g2, new SPARCLoOp(new ASMLabel(".GLOBALFIELD")), SPARCRegister.g2));
		}
		//5000 problem - Vinh The's Problem
		int reserveSize = n.getReserveSize();
		if(-reserveSize >= -4096 && -reserveSize <= 4095){
				asm.appendEntry(SPARCOpcode.save_instr(SPARCRegister.sp, -reserveSize, SPARCRegister.sp));
		}else{							
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(-reserveSize), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(-reserveSize), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.save_instr(SPARCRegister.sp, SPARCRegister.g1, SPARCRegister.sp));
		}		

		//default initializtion to zero for all local variables
		for (int i=4; i<= reserveSize - 92; i+=4){
			if(-i >= -4096 && -i <= 4095){
					asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g0, new SPARCAddress(SPARCRegister.fp,-i)));
			}else{							
					asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(-i), SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(-i), SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g0, new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1)));
			}
		}
		//int memSize = n.getReserveSize();
		//for (int i=0;i<n.getReserveSize();i+=4){
		//	asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g0, new SPARCAddress(SPARCRegister.sp, i) ));
		//}
		//n.typ_.accept(this);
		//n.identifier_.accept(this);
		if(n.mdParaList_ !=null){ //method parameter list could be NULL
			n.mdParaList_.accept(this);
		}
		n.block_.accept(this);

		if (n.typ_ instanceof TypVoid){ //void type is reurn upon closing '}'
			asm.appendEntry(new ASMComment("Return statement for method:"));	
			asm.appendEntry(SPARCOpcode.ret_instr());
			asm.appendEntry(SPARCOpcode.restore_instr());
		}else{ //catch the control falling off error here.
			//error message
			asm.appendEntry(new ASMComment("Run time error: Control falling off detected and reported here:"));	
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".CONTROL_FALLING_OFF")), SPARCRegister.o0));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o0, new SPARCLoOp(new ASMLabel(".CONTROL_FALLING_OFF")), SPARCRegister.o0));
			//line number
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_+"_LINE_NO")), SPARCRegister.o1));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o1, new SPARCLoOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_+"_LINE_NO")), SPARCRegister.o1));
			//method name
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_)), SPARCRegister.o2));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o2, new SPARCLoOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_)), SPARCRegister.o2));
			
			asm.appendEntry(SPARCOpcode.call_instr("printf"));
			asm.appendEntry(SPARCOpcode.nop_instr());
			asm.appendEntry(SPARCOpcode.call_instr("exit"));	
			asm.appendEntry(SPARCOpcode.nop_instr());		
		}

		//data for error message printing only 		
		dataLabelList.add(new ASMLabel(".MDNAME_"+n.identifier_.identifier_));
		dataLabelList.add(new dAsciz("'"+n.identifier_.identifier_+"( )'"));
		dataLabelList.add(new dAlign(8));
		dataLabelList.add(new ASMLabel(".MDNAME_"+n.identifier_.identifier_+"_LINE_NO"));
		dataLabelList.add(new dAsciz(""+n.block_.lineNo_));
		dataLabelList.add(new dAlign(8));		
	}	
	public void visit(MdParaList n){ //not printing List classes
		while(n!= null)
		{	
			n.mdPara_.accept(this);
			n = n.mdParaList_;
		}
	}	
	public void visit(MdPara n){
		n.typ_.accept(this);
		n.identifier_.accept(this);
	}	
	public void visit(Block n){
		if(n.varDeclList_!=null) //var declaration list could be empty
			n.varDeclList_.accept(this);
		if(n.stmtList_!=null)//list can be empty
			n.stmtList_.accept(this);
	}
	public void visit(VarDecl n){
		//n.typ_.accept(this);
		if(n.locVarList_==null) System.out.println("ERROR!!!!!!!!!!!!!!!");
			n.locVarList_.accept(this);

	}	
	public void visit(VarDeclList n){ //not printing List classes
		while(n!= null)
		{	
			n.varDecl_.accept(this);
			n = n.varDeclList_;
		}
	}
	public void visit(LocVar n){
		n.identifier_.accept(this);	
	}	
	public void visit(LocVarList n){ //not printing List classes
		while(n!= null)
		{	
			n.locVar_.accept(this);
			n = n.locVarList_;
		}
	}
	public void visit(StmtList n){ //not printing List classes
		while(n!= null)
		{	
			n.stmt_.accept(this);
			n = n.stmtList_;
		}
	}
	public void visit(Stmt n){	}	 //abstract class
	public void visit(StmtLocation n){

		n.exp_.accept(this);
		//n.location_.accept(this);
		
		if(n.location_ instanceof LocationId) { //LocationID
			int locOffset = ((LocationId)n.location_).identifier_.offset;	
			if( !((LocationId)n.location_).identifier_.glbVarFlag){
				if(!((LocationId)n.location_).identifier_.paramFlag){ //non-parameter handling
					asm.appendEntry(new ASMComment("Location id store instruction for stmt location:   "+ ((LocationId)n.location_).identifier_.identifier_ + " = expression"));
					
					if(-locOffset >= -4096 && -locOffset <= 4095){
							asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.fp, -locOffset)));
					}else{							
							asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(-locOffset), SPARCRegister.g1));
							asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(-locOffset), SPARCRegister.g1));
							asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1)));							
					}															
				}
				else{//paramenter handling
					asm.appendEntry(new ASMComment("Location id store instruction for stmt location for Parameter:   "+ ((LocationId)n.location_).identifier_.identifier_ + " = expression"));
					int paramIndex = ((LocationId)n.location_).identifier_.offset/4;
					if (paramIndex <= 5){//handing parameters within 6th
						// locate the right rigister holding parameters
						SPARCRegister Ri = null;
						switch(paramIndex){
							case 0: Ri = SPARCRegister.i0; break;
							case 1: Ri = SPARCRegister.i1; break;
							case 2: Ri = SPARCRegister.i2; break;
							case 3: Ri = SPARCRegister.i3; break;
							case 4: Ri = SPARCRegister.i4; break;
							case 5: Ri = SPARCRegister.i5; break;
						}
						//pass the result to register directly
						asm.appendEntry(new ASMComment(" Store parameter -> Ri:  " ));
						asm.appendEntry(SPARCOpcode.mov_instr(n.exp_.getReg(), Ri));
					}else{//handling parameters past 6th
						//store it into some address
						int spaceForOthers = (16+1+6)*4;
						int offset = (paramIndex-6)*4;
						offset = offset + spaceForOthers;
				
						//store the parameter in %sp+offset
						asm.appendEntry(new ASMComment(" Store parameter -> %fp+offset:  " ));
						if(offset >= -4096 && offset <= 4095){
							asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.fp,+offset)));
						}else{							
							asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(offset), SPARCRegister.g1));
							asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(offset), SPARCRegister.g1));
							asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1)));							
						}
					}
				}
			}else{
				//SPARCRegister reg1 = SPARCRegister.getNextRegLocal(); reg1.status = 1;
				asm.appendEntry(new ASMComment("Global Location id store instruction for stmt location:   "+ ((LocationId)n.location_).identifier_.identifier_ + " = expression"));
				//asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".GLOBALFIELD")), reg1));
				//asm.appendEntry(SPARCOpcode.or_instr(reg1, new SPARCLoOp(new ASMLabel(".GLOBALFIELD")), reg1)); 
				//asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(reg1, locOffset)));
	
				if(locOffset >= -4096 && locOffset <= 4095){
					asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.g2, locOffset)));
				}else{							
					asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(locOffset), SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(locOffset), SPARCRegister.g1));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -