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

📄 codegeneration.java

📁 用Java实现的编译器。把源代码编译成SPARC汇编程序
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
					asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.g2,SPARCRegister.g1)));							
				}
				
				//reg1.status = 0;
			}
			n.exp_.releaseReg();
		}
		else{//Location Array
			//asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(n.location_.getReg())));
			int locOffset = ((LocationArray)n.location_).identifier_.offset;
			int count = ++labelCnt;  
			((LocationArray)n.location_).exp_.accept(this);
			asm.appendEntry(new ASMComment(" Store instruction for the array identifier:  " + ((LocationArray)n.location_).identifier_.identifier_));
			
			//SPARCRegister reg2 = SPARCRegister.getNextRegLocal();  reg2.status = 1;
			
			
			if(locOffset >= -4096 && locOffset <= 4095){
				asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.g2, locOffset), SPARCRegister.g3)); //arraysize
			}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.ld_instr(new SPARCAddress(SPARCRegister.g2, SPARCRegister.g1), SPARCRegister.g3));							
			}
			
			SPARCRegister reg3 =  ((LocationArray)n.location_).exp_.getReg(); //index of array
			
			//compare
			asm.appendEntry(SPARCOpcode.cmp_instr(reg3, SPARCRegister.g3));
			//branch
			asm.appendEntry(SPARCOpcode.bge_instr(".ArrayOutBound"+count));
			asm.appendEntry(SPARCOpcode.nop_instr());
			
			
			asm.appendEntry(SPARCOpcode.cmp_instr(reg3, SPARCRegister.g0));
			asm.appendEntry(SPARCOpcode.bge_instr(".True"+count));
			asm.appendEntry(SPARCOpcode.nop_instr());
			//.False:
			asm.appendEntry(new ASMLabel(".ArrayOutBound"+count));
			
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".ARRAY_OUT_OF_BOUND")), SPARCRegister.o0));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o0, new SPARCLoOp(new ASMLabel(".ARRAY_OUT_OF_BOUND")), SPARCRegister.o0));
			int lineno = ((LocationArray)n.location_).exp_.getExpLineNo();
			if(lineno <= 4095 && lineno >= -4096){
				asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(lineno), SPARCRegister.o1));
			}else{
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(lineno), SPARCRegister.o1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o1, new SPARCLoOp(lineno), SPARCRegister.o1));
			}
			asm.appendEntry(SPARCOpcode.mov_instr(reg3,SPARCRegister.o2));
			asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g3,SPARCRegister.o3));
			
			asm.appendEntry(SPARCOpcode.call_instr("printf"));
			asm.appendEntry(SPARCOpcode.nop_instr());

			asm.appendEntry(SPARCOpcode.call_instr("exit"));	
			asm.appendEntry(SPARCOpcode.nop_instr());

			
			//.True:
			asm.appendEntry(new ASMLabel(".True"+count));
			asm.appendEntry(SPARCOpcode.smul_instr(reg3, new SPARCImmed(4), SPARCRegister.g3));
			reg3.status = 0;
			locOffset += 4;		
											
			if(locOffset >= -4096 && locOffset <= 4095){
				asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.g3, new SPARCImmed(locOffset), SPARCRegister.g3));
			}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.add_instr(SPARCRegister.g3, SPARCRegister.g1, SPARCRegister.g3));							
			}

			asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.g2, SPARCRegister.g3)));					
								
			n.exp_.releaseReg();
			//reg1.status = 0;
			//reg2.status = 0;
			
			
		}

		//location = exp;
	}		
	public void visit(StmtBlock n){
		n.block_.accept(this);
	}	
	public void visit(StmtMdCall n){
		n.mdCall_.accept(this);
		//release the register since no return value needed 
		n.mdCall_.releaseReg();
	}	
	public void visit(Location n){	}	//abstract class
	
	public void visit(LocationId n){
		//n.identifier_.accept(this); 
		
		if( !n.identifier_.glbVarFlag ){
			if (!n.identifier_.paramFlag){//non-parameter handling
				//set a register to hold the value
				n.setReg(SPARCRegister.getNextRegLocal());
				asm.appendEntry(new ASMComment(" Load instruction for the location identifier:  " + n.identifier_.identifier_));															
				
				if(-n.identifier_.offset >= -4096 && -n.identifier_.offset <= 4095){
					asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.fp,-n.identifier_.offset), n.getReg()));
				}else{							
					asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(-n.identifier_.offset), SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(-n.identifier_.offset), SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1), n.getReg()));
				}
				
				
			}else{ //parameter handling
				asm.appendEntry(new ASMComment(" Load instruction for the parameter identifier: no need to load  " + n.identifier_.identifier_));
				int paramIndex = n.identifier_.offset/4;
				if (paramIndex <= 5){//handing parameters within 6th
					// no need to set new local register, will just use the local if within 6
					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 input register directly
					asm.appendEntry(new ASMComment(" Loading parameter <- Ri:  " ));
					n.setReg(Ri);
				}else{//handling parameters past 6th
					//set a register to hold the value
					n.setReg(SPARCRegister.getNextRegLocal());


					int spaceForOthers = (16+1+6)*4;
					int offset = (paramIndex-6)*4;
					offset = offset + spaceForOthers;
			
					//store the parameter in %sp+offset
					asm.appendEntry(new ASMComment(" Loading parameter <- fp%+offset:  " ));
					
					if(offset >= -4096 && offset <= 4095){
						asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.fp,+offset), n.getReg()));
					}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.ld_instr(new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1), n.getReg()));				
					}										
					
				}
			}
		}else{ //global variable
			//set a register to hold the value
			n.setReg(SPARCRegister.getNextRegLocal());
			
			//SPARCRegister reg1 = SPARCRegister.getNextRegLocal(); reg1.status = 1;
			asm.appendEntry(new ASMComment("Global Location id load instruction for stmt location:   "+ n.identifier_.identifier_));
			//asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".GLOBALFIELD")), reg1));
			//asm.appendEntry(SPARCOpcode.or_instr(reg1, new SPARCLoOp(new ASMLabel(".GLOBALFIELD")), reg1)); 
			
			
			if(n.identifier_.offset >= -4096 && n.identifier_.offset <= 4095){
				asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.g2, n.identifier_.offset), n.getReg()));
			}else{							
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(n.identifier_.offset), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(n.identifier_.offset), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.g2, SPARCRegister.g1), n.getReg()));				
			}
			//reg1.status = 0;
		}
	}
	public void visit(LocationArray n){
		n.exp_.accept(this);
		int count = ++labelCnt;
		int locOffset = n.identifier_.offset;
		//SPARCRegister reg1 = SPARCRegister.getNextRegLocal();
		//reg1.status = 1;

		asm.appendEntry(new ASMComment(" Load instruction for the array identifier:  " + n.identifier_.identifier_));
		//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.add_instr(reg1, new SPARCImmed(n.identifier_.offset), reg1));		
		//SPARCRegister reg2 = SPARCRegister.getNextRegLocal(); reg2.status = 1; //offset of array
		
		
		if(locOffset >= -4096 && locOffset <= 4095){
			asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.g2, locOffset), SPARCRegister.g3)); //arraysize
		}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.ld_instr(new SPARCAddress(SPARCRegister.g2, SPARCRegister.g1), SPARCRegister.g3)); //arraysize				
		}
			
		SPARCRegister reg3 =  n.exp_.getReg(); //index of array
		//compare
		asm.appendEntry(SPARCOpcode.cmp_instr(reg3, SPARCRegister.g3));
		//branch
		asm.appendEntry(SPARCOpcode.bge_instr(".ArrayOutBound"+count));
		asm.appendEntry(SPARCOpcode.nop_instr());
		
		
		asm.appendEntry(SPARCOpcode.cmp_instr(reg3, SPARCRegister.g0));
		asm.appendEntry(SPARCOpcode.bge_instr(".True"+count));
		asm.appendEntry(SPARCOpcode.nop_instr());
		//.False:
		asm.appendEntry(new ASMLabel(".ArrayOutBound"+count));
		asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".ARRAY_OUT_OF_BOUND")), SPARCRegister.o0));
		asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o0, new SPARCLoOp(new ASMLabel(".ARRAY_OUT_OF_BOUND")), SPARCRegister.o0));
		int lineno = n.exp_.getExpLineNo();
		if(lineno <= 4095 && lineno >= -4096){
			asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(lineno), SPARCRegister.o1));
		}else{
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(lineno), SPARCRegister.o1));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o1, new SPARCLoOp(lineno), SPARCRegister.o1));
		}
		
		asm.appendEntry(SPARCOpcode.mov_instr(reg3,SPARCRegister.o2));
		asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g3,SPARCRegister.o3));
		asm.appendEntry(SPARCOpcode.call_instr("printf"));
		asm.appendEntry(SPARCOpcode.nop_instr());
		asm.appendEntry(SPARCOpcode.call_instr("exit"));	
		asm.appendEntry(SPARCOpcode.nop_instr());

		//.True:
		asm.appendEntry(new ASMLabel(".True"+count));
		asm.appendEntry(SPARCOpcode.smul_instr(reg3, new SPARCImmed(4), SPARCRegister.g3));
		reg3.status = 0;	//release reg3
		locOffset += 4;
		
				
		if(locOffset >= -4096 && locOffset <= 4095){
			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.g3, new SPARCImmed(locOffset), SPARCRegister.g3));
		}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.add_instr(SPARCRegister.g3, SPARCRegister.g1, SPARCRegister.g3));			
		}
		n.setReg(SPARCRegister.getNextRegLocal());
		asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.g2, SPARCRegister.g3), n.getReg()));
		
		//reg1.status = 0;
	

		//n.identifier_.accept(this);
	
	}

	public void visit(CallOutArgList n){ //not printing List classes

		int paramSize = n.listSize;
		boolean isScanf = n.scanf_Flag;
		
                while(n!= null)
		{
                   if( n.scanf_Flag == true ){
                    		n.callOutArg_.setScanf_Flag();
                    if(n.callOutArgList_!=null)
                    		n.callOutArgList_.setScanf_Flag();
                   }

		     n.callOutArg_.setListSize(paramSize);
                   n.callOutArg_.accept(this);
                   n = n.callOutArgList_;
		}

                //if not scanf, need to move 6 param from stack to register
               if(!isScanf){
			int spaceForOthers = (16+1+6)*4;
			int startingOffsetForExtraParam = spaceForOthers;
			int startingOffsetForNormalParam = spaceForOthers + (paramSize >= 6? (paramSize-6)*4:0);
			
			//load the first 6 parameters to register after the whole expression list is processed
			int firstSixParamSize = paramSize> 6? 6: paramSize;
			for (int i=0;i<firstSixParamSize;i++){
				// find the right output register based on the parameter index
				SPARCRegister Ro = null;
				switch(i){
					case 0: Ro = SPARCRegister.o0; break;
					case 1: Ro = SPARCRegister.o1; break;
					case 2: Ro = SPARCRegister.o2; break;
					case 3: Ro = SPARCRegister.o3; break;
					case 4: Ro = SPARCRegister.o4; break;
					case 5: Ro = SPARCRegister.o5; break;
				}
				int offset = startingOffsetForNormalParam + i*4; 
				//out put it 
				asm.appendEntry(new ASMComment(" Preparing parameter -> Ro:  " ));

				if(offset >= -4096 && offset <= 4095){
					asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.sp,+offset), Ro));
				}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.ld_instr(new SPARCAddress(SPARCRegister.sp,SPARCRegister.g1), Ro));						
				}

				


			}

               }  

	}
	public void visit(CallOutArg n){	}	//abstract class
	public void visit(CallOutArgExp n){

		if (n.scanf_Flag ){ //scanf
		
			int paramIndex = n.getIndex();
			if (paramIndex <= 5){//handing parameters within 6th
				// find the right output register based on the parameter index
				SPARCRegister Ro = null;
				switch(paramIndex){
					case 0: Ro = SPARCRegister.o0; break;
					case 1: Ro = SPARCRegister.o1; break;
					case 2: Ro = SPARCRegister.o2; break;
					case 3: Ro = SPARCRegister.o3; break;
					case 4: Ro = SPARCRegister.o4; break;
					case 5: Ro = SPARCRegister.o5; break;
				}
				//out put it
				asm.appendEntry(new ASMComment(" Preparing parameter -> Ro:  " ));
				if(n.exp_ instanceof LocationId){
					//Vinh The's Job==================================================					
					asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.fp, new SPARCImmed(-((LocationId)n.exp_).identifier_.offset), Ro));
				}else if(n.exp_ instanceof LocationArray){
					System.out.println("Scanf Error: scanf not supporting global variables");
				}else{ //scanf error
					System.out.println("Scanf Error: scanf can only take addressable variables");
				}

			}else{//handling parameters past 6th
				int spaceForOthers = (16+1+6)*4;
				int offset = (paramIndex-6)*4;
				offset = offset + spaceForOthers;

⌨️ 快捷键说明

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