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

📄 codegeneration.java

📁 用Java实现的编译器。把源代码编译成SPARC汇编程序
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
				//store the parameter in %sp+offset
				asm.appendEntry(new ASMComment(" Preparing parameter -> sp%+offset:  " ));

				if(n.exp_ instanceof LocationId){
					//Vinh The's Job==================================================
					//calculating the variable address.
					asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(-((LocationId)n.exp_).identifier_.offset), SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.fp, SPARCRegister.g1, SPARCRegister.g1));
					asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g1, new SPARCAddress(SPARCRegister.sp,offset)));
				}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{ //normal handling
		
		
			n.exp_.accept(this);
			
			int paramIndex = n.getIndex();

			int paramSize = n.listSize;
			int spaceForOthers = (16+1+6)*4;
			int startingOffsetForExtraParam = spaceForOthers;
			int startingOffsetForNormalParam = spaceForOthers + (paramSize >= 6? (paramSize-6)*4:0);

			int offset = 0;
			if(paramIndex <=5)
				offset = startingOffsetForNormalParam + paramIndex*4;
			else
				offset = startingOffsetForExtraParam + (paramIndex-6)*4;
	
			//store the parameter in %sp+offset
			asm.appendEntry(new ASMComment(" Preparing parameter -> sp%+offset:  " ));
			
			
			if(offset >= -4096 && offset <= 4095){
				asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.sp,+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)));							
			}

			n.exp_.releaseReg();
		}
	}
	
	public void visit(CallOutArgStr n){


		
		int cnt = ++labelCnt;
		//n.ltrString_.accept(this);

		//LABLEING DATA to be appended at the end
		dataLabelList.add(new ASMLabel(".CalloutArg"+cnt));
		dataLabelList.add(new dAsciz(n.ltrString_.ltrString_));
		dataLabelList.add(new dAlign(8));

		if(n.scanf_Flag){

			if(n.index != 0){
				System.out.println("Error: Scanf can't store value to a string");
				return;
			}
			
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".CalloutArg"+cnt)), SPARCRegister.g1));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(new ASMLabel(".CalloutArg"+cnt)), SPARCRegister.g1));

			asm.appendEntry(new ASMComment(" Preparing Scanf  " ));

			asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g1, SPARCRegister.o0));
	
			return;
		}

		int paramIndex = n.getIndex();
		int paramSize = n.listSize;
		int spaceForOthers = (16+1+6)*4;
		int startingOffsetForExtraParam = spaceForOthers;
		int startingOffsetForNormalParam = spaceForOthers + (paramSize >= 6? (paramSize-6)*4:0);

		int offset = 0;
		if(paramIndex <=5)
			offset = startingOffsetForNormalParam + paramIndex*4;
		else
			offset = startingOffsetForExtraParam + (paramIndex-6)*4;
		

		asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".CalloutArg"+cnt)), SPARCRegister.g1));
		asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(new ASMLabel(".CalloutArg"+cnt)), SPARCRegister.g1));
		//store the parameter in %sp+offset
		asm.appendEntry(new ASMComment(" Preparing parameter -> sp% + offset:  " ));
		
		if(offset >= -4096 && offset <= 4095){
			asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g1, new SPARCAddress(SPARCRegister.sp,+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(SPARCRegister.g1, new SPARCAddress(SPARCRegister.sp,SPARCRegister.g1)));			
		}
		
		
		

	}
	public void visit(MdCall n){	}	//abstract class
	public void visit(MdCallOut n){
		//n.ltrString_.accept(this);
                /**
                 * If the callout is for a scanf function,
                 * then the address of the acllout arguments will be sent instead of its value
                **/
                boolean scanfFlag = false;
                if(n.ltrString_.ltrString_.equals("scanf") && n.callOutArgList_ != null){
                  n.callOutArgList_.setScanf_Flag();
                  scanfFlag = true;
                }


                //dynamically allocate space for extra parameters if needed

                int paramSize = n.paramSize;
                int moreSpace = 0;
                SPARCRegister reg = null;
	if(scanfFlag){     //scanf            
                if (paramSize > 6)
			moreSpace = (paramSize - 6)*4;
       }
	else //non scanf
                	moreSpace = (paramSize )*4;


	
			if (moreSpace % 8 != 0) moreSpace+=4;
			//Vinh The, please check the 5000 thing here =======================================



			if(moreSpace >= -4096 && moreSpace <= 4095){
				asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(moreSpace), SPARCRegister.g3));
			}else{							
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g1, SPARCRegister.g3));			
			}
			
			asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.sp, SPARCRegister.g3, SPARCRegister.sp));

                //}
	
                if(n.callOutArgList_!=null){ //could be empty
                	n.callOutArgList_.listSize = paramSize;
			n.callOutArgList_.accept(this);
		}

                
		//you can retirve the number of arguments here
		//int noOfArguments = SPARCRegister.noOfOutputRegistersUsed();
		asm.appendEntry(SPARCOpcode.call_instr(n.ltrString_.ltrString_));
		asm.appendEntry(SPARCOpcode.nop_instr());
		SPARCRegister.releaseAllOutputRegisters();

		//copy the result of callout
		n.setReg(SPARCRegister.getNextRegLocal());
		asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.o0, n.getReg()));


		//move back the memory stack pointer
		//Vinh The, please check the 5000 thing here =======================================
		//if (paramSize > 6){
			if(moreSpace >= -4096 && moreSpace <= 4095){
				asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(moreSpace), SPARCRegister.g3));
			}else{							
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g1, SPARCRegister.g3));			
			}
			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.sp, SPARCRegister.g3, SPARCRegister.sp));

		//}


		
	}
	public void visit(MdCallIn n){
		//n.identifier_.accept(this);

		//always dynamically allocate space for extra parameters if needed

	    int paramSize = n.paramSize/4;
            int moreSpace = 0;
            SPARCRegister reg = null;
            //if (paramSize > 6){
			//moreSpace = (paramSize - 6)*4;
            		moreSpace = (paramSize )*4;
			if (moreSpace % 8 != 0) moreSpace+=4;
			//Vinh The, please check the 5000 thing here =======================================

			if(moreSpace >= -4096 && moreSpace <= 4095){
				asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(moreSpace), SPARCRegister.g3));
			}else{							
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g1, SPARCRegister.g3));			
			}			asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.sp, SPARCRegister.g3, SPARCRegister.sp));

	     // }
                
		if(n.expList_!=null) {//could be empty
			n.expList_.listSize = paramSize;
			n.expList_.accept(this);
		}
		//you can retirve the number of arguments here
		//int noOfArguments = SPARCRegister.noOfOutputRegistersUsed();
		asm.appendEntry(SPARCOpcode.call_instr(n.identifier_.identifier_));
		asm.appendEntry(SPARCOpcode.nop_instr());
		SPARCRegister.releaseAllOutputRegisters();
		
		//copy the result of callout
		n.setReg(SPARCRegister.getNextRegLocal());
		asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.o0, n.getReg()));	
		
		//move back the memory stack pointer
		 //if (paramSize > 6){
			//Vinh The, please check the 5000 thing here =======================================
			if(moreSpace >= -4096 && moreSpace <= 4095){
				asm.appendEntry(SPARCOpcode.mov_instr(new SPARCImmed(moreSpace), SPARCRegister.g3));
			}else{							
				asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(moreSpace), SPARCRegister.g1));
				asm.appendEntry(SPARCOpcode.mov_instr(SPARCRegister.g1, SPARCRegister.g3));			
			}			
			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.sp, SPARCRegister.g3, SPARCRegister.sp));
	
		// }

	



		


	}	
	public void visit(ExpList n){ //not printing List classes
		int index = -1;

		int paramSize = n.listSize;

		int spaceForOthers = (16+1+6)*4;
		int startingOffsetForExtraParam = spaceForOthers;
		int startingOffsetForNormalParam = spaceForOthers + (paramSize >= 6? (paramSize-6)*4:0);
		
		
		//go through the rest of the list first
		while(n!= null)
		{	
			index++;
			int paramIndex = index;
			n.exp_.accept(this);

			int offset = 0;
			if(paramIndex <=5)
				offset = startingOffsetForNormalParam + paramIndex*4;
			else
				offset = startingOffsetForExtraParam + (paramIndex-6)*4;
	
			//store the parameter in %sp+offset
			asm.appendEntry(new ASMComment(" Preparing parameter -> %sp + offset:  " ));
			
			
			if(offset >= -4096 && offset <= 4095){
				asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.sp,+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.sp,SPARCRegister.g1)));		
			}

			n.exp_.releaseReg();			
			n = n.expList_;
		}


		//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(StmtForLoop n){
		int cnt = ++labelCnt;
		int locOffset;
		
		//for loop initialization
		//we are obtaining the offset for identifier and assigning the exp1 value to it at its address
		n.exp1_.accept(this);
		locOffset = n.identifier1_.offset;	

		if(!(n.identifier1_.glbVarFlag)){				
				
				
				if(-locOffset >= -4096 && -locOffset <= 4095){
					asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.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));

⌨️ 快捷键说明

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