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

📄 codegeneration.java

📁 用Java实现的编译器。把源代码编译成SPARC汇编程序
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
					asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.getReg(), new SPARCAddress(SPARCRegister.fp, SPARCRegister.g1)));		
				}
		
		}else{
				
				if(locOffset >= -4096 && locOffset <= 4095){
					asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.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));
					asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.getReg(), new SPARCAddress(SPARCRegister.g2, SPARCRegister.g1)));
				}
		}
				
		n.exp1_.releaseReg();
		
		//create a label for ForCondition
		asm.appendEntry(new ASMLabel(".ForCondition"+cnt));
		n.exp2_.accept(this);
		//use a compare inst to check if condition is false
		asm.appendEntry(SPARCOpcode.cmp_instr(SPARCRegister.g0, n.exp2_.getReg()));
		//release the exp2 register
		n.exp2_.releaseReg();

		//if false jump to the end branch
		asm.appendEntry(SPARCOpcode.be_instr(".End"+cnt));
		asm.appendEntry(SPARCOpcode.nop_instr());

		//for true condition, enter the for loop block
		n.block_.accept(this);

		//increment before checking the condition again
		n.exp3_.accept(this);	
		locOffset = n.identifier3_.offset;
		if(!(n.identifier3_.glbVarFlag)){
			
			
			if(-locOffset >= -4096 && -locOffset <= 4095){
				asm.appendEntry(SPARCOpcode.st_instr(n.exp3_.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.exp3_.getReg(), new SPARCAddress(SPARCRegister.fp, SPARCRegister.g1)));		
			}
			
		}else{
			
			
			if(locOffset >= -4096 && locOffset <= 4095){
				asm.appendEntry(SPARCOpcode.st_instr(n.exp3_.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));
				asm.appendEntry(SPARCOpcode.st_instr(n.exp3_.getReg(), new SPARCAddress(SPARCRegister.g2, SPARCRegister.g1)));		
			}
		}
		n.exp3_.releaseReg();

		//loop back to the condition
		asm.appendEntry(SPARCOpcode.b_instr(".ForCondition"+cnt));
		asm.appendEntry(SPARCOpcode.nop_instr());

		asm.appendEntry(new ASMLabel(".End"+cnt));
	}	
	public void visit(StmtIfElse n){
		int cnt = ++labelCnt;
		
		// calling the acept method for evaluating the condition
		n.exp_.accept(this);
		
		//now use the cmp_inst to check if condition is false
		//use branches true for true block and end for for continuing the instructions after the if loop
		asm.appendEntry(SPARCOpcode.cmp_instr(SPARCRegister.g0, n.exp_.getReg()));
		
		//release the exp local register
		n.exp_.releaseReg();
		
		asm.appendEntry(SPARCOpcode.be_instr(".False"+cnt));
		asm.appendEntry(SPARCOpcode.nop_instr());

		//true block starts here
		n.ifBlock_.accept(this);
		//after the true block branch to end
		// see if you can get rid of this jump instruction if there is no else block
		asm.appendEntry(SPARCOpcode.b_instr(".End"+cnt));
		asm.appendEntry(SPARCOpcode.nop_instr());
		
		//else block is here
		asm.appendEntry(new ASMLabel(".False"+cnt));
		if(n.elseBlock_!=null) {  //else block could be empty
			n.elseBlock_.accept(this);		
		}
			
		//branch for end block
		asm.appendEntry(new ASMLabel(".End"+cnt));
		
	
	}	
	public void visit(StmtReturn n){

		if(n.exp_ != null) {//could return nothing
			n.exp_.accept(this);	
			//copy the result into callee's i0, later converted to caller's o0
			asm.appendEntry(SPARCOpcode.mov_instr(n.exp_.getReg(), SPARCRegister.i0));
			n.exp_.releaseReg();
		}
		asm.appendEntry(new ASMComment("Return statement for method:"));		
		asm.appendEntry(SPARCOpcode.ret_instr());
		asm.appendEntry(SPARCOpcode.restore_instr());		
	}		
	public void visit(StmtWhileLoop n){
		int cnt = ++labelCnt;
		
		// create a label for the condition to loop back
		asm.appendEntry(new ASMLabel(".WhileCondition"+cnt));

		//evaluate the condition
		n.exp_.accept(this);

		//check if the condition is false
		asm.appendEntry(SPARCOpcode.cmp_instr(SPARCRegister.g0, n.exp_.getReg()));

		//release the exp register
		n.exp_.releaseReg();
		
		//if false branch out to the end
		asm.appendEntry(SPARCOpcode.be_instr(".End"+cnt));
		asm.appendEntry(SPARCOpcode.nop_instr());

		//if condition is true block accept is called
		n.block_.accept(this);
		asm.appendEntry(SPARCOpcode.b_instr(".WhileCondition"+cnt));
		asm.appendEntry(SPARCOpcode.nop_instr());

		//the end branch is creted to come out of the while loop
		asm.appendEntry(new ASMLabel(".End"+cnt));
	
	}			
   	public void visit(Literal n){}//abstract
	public void visit(Exp n){}//abstract
	public void visit(ExpPlus n){
		
		n.exp1_.accept(this);  

		//check if the register is the last register
		// with 2, we are effectively reserving 3 registers
		// 1  is for final result
		// 1 is for literal / unary
		// 1 is in case that e1 is parameter such that cannot be released
		if(SPARCRegister.getLocalAvailable() == 2){

			//before calling the second expression, store the first expression value in the stack
			//decrement stack pointer by 8
			asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));
			//load exp1 register to address sp + size
			asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.getReg(), new SPARCAddress(SPARCRegister.sp, 92)));
			//release exp1 register
			n.exp1_.releaseReg();

			//now accept the second expression
			n.exp2_.accept(this);

			asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.sp, 92), SPARCRegister.g1));

			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));

			n.setReg(SPARCRegister.getNextRegLocal());

			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.g1,n.exp2_.getReg(), n.getReg()));

			n.exp2_.releaseReg();
			
		}else{
			n.exp2_.accept(this);

			n.setReg(SPARCRegister.getNextRegLocal());
			
			asm.appendEntry(SPARCOpcode.add_instr(n.exp1_.getReg(),n.exp2_.getReg(), n.getReg()));
			
			n.exp1_.releaseReg();
			n.exp2_.releaseReg();
			
		
		}
			
        }
	public void visit(ExpMinus n){
		n.exp1_.accept(this);  

		//check if the register is the last register
		if(SPARCRegister.getLocalAvailable() == 2){

			//before calling the second expression, store the first expression value in the stack
			//decrement stack pointer by 8
			asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));
			//load exp1 register to address sp + size
			asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.getReg(), new SPARCAddress(SPARCRegister.sp, 92)));
			//release exp1 register
			n.exp1_.releaseReg();

			//now accept the second expression
			n.exp2_.accept(this);

			asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.sp, 92), SPARCRegister.g1));

			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));

			n.setReg(SPARCRegister.getNextRegLocal());

			asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.g1,n.exp2_.getReg(), n.getReg()));

			n.exp2_.releaseReg();
			
		}else{
			n.exp2_.accept(this);

			n.setReg(SPARCRegister.getNextRegLocal());
			
			asm.appendEntry(SPARCOpcode.sub_instr(n.exp1_.getReg(),n.exp2_.getReg(), n.getReg()));
			
			n.exp1_.releaseReg();
			n.exp2_.releaseReg();
			
		
		}
	}
	public void visit(ExpTimes n){
		boolean optimizedFlag = false;
		//check if either of the expressions is equal to 3
		if(algebraicSimplification){
			if(n.exp1_ instanceof LtrInt){
			if(( (LtrInt) n.exp1_).ltrInt_ == 3){
				// add the other exp 3 times instead of multiplication
	                     n.exp2_.accept(this);
	                     n.setReg(SPARCRegister.getNextRegLocal());
	                     asm.appendEntry(SPARCOpcode.add_instr(n.exp2_.getReg(), n.exp2_.getReg(), n.getReg()));
	                     asm.appendEntry(SPARCOpcode.add_instr(n.exp2_.getReg(), n.getReg(), n.getReg()));
	                     n.exp2_.releaseReg();
				optimizedFlag = true;		 
			}
			}else if(n.exp2_ instanceof LtrInt){
				if(( (LtrInt) n.exp2_).ltrInt_ == 3){
					// add the other exp 3 times instead of multiplication
		                     n.exp1_.accept(this);
		                     n.setReg(SPARCRegister.getNextRegLocal());
		                     asm.appendEntry(SPARCOpcode.add_instr(n.exp1_.getReg(), n.exp1_.getReg(), n.getReg()));
		                     asm.appendEntry(SPARCOpcode.add_instr(n.exp1_.getReg(), n.getReg(), n.getReg()));
		                     n.exp1_.releaseReg();
					optimizedFlag = true;		 
				}
			}	
		}		
		if(!optimizedFlag){
			n.exp1_.accept(this);  
			//check if the register is the last register
			if(SPARCRegister.getLocalAvailable() == 2){

				//before calling the second expression, store the first expression value in the stack
				//decrement stack pointer by 8
				asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));
				//load exp1 register to address sp + size
				asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.getReg(), new SPARCAddress(SPARCRegister.sp, 92)));
				//release exp1 register
				n.exp1_.releaseReg();

				//now accept the second expression
				n.exp2_.accept(this);

				asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.sp, 92), SPARCRegister.g1));

				asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));

				n.setReg(SPARCRegister.getNextRegLocal());

				asm.appendEntry(SPARCOpcode.smul_instr(SPARCRegister.g1,n.exp2_.getReg(), n.getReg()));

				n.exp2_.releaseReg();
				
			}else{
				n.exp2_.accept(this);

				n.setReg(SPARCRegister.getNextRegLocal());
				
				asm.appendEntry(SPARCOpcode.smul_instr(n.exp1_.getReg(),n.exp2_.getReg(), n.getReg()));
				
				n.exp1_.releaseReg();
				n.exp2_.releaseReg();
				
			
			}
		}		
	}
	public void visit(ExpDivide n){
		int count = ++labelCnt;
		n.exp1_.accept(this);  

		if(SPARCRegister.getLocalAvailable() == 2){

			//before calling the second expression, store the first expression value in the stack
			//decrement stack pointer by 8
			asm.appendEntry(SPARCOpcode.sub_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));
			//load exp1 register to address sp + size
			asm.appendEntry(SPARCOpcode.st_instr(n.exp1_.getReg(), new SPARCAddress(SPARCRegister.sp, 92)));
			//release exp1 register
			n.exp1_.releaseReg();

			//now accept the second expression
			n.exp2_.accept(this);

			asm.appendEntry(SPARCOpcode.cmp_instr(n.exp2_.getReg(), new SPARCImmed(0)));
			//branch
			asm.appendEntry(SPARCOpcode.bne_instr(".DenominatorNotZero"+count));
			asm.appendEntry(SPARCOpcode.nop_instr());
			//.False:
			asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".DIVISION_ZERO")), SPARCRegister.o0));
			asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o0, new SPARCLoOp(new ASMLabel(".DIVISION_ZERO")), SPARCRegister.o0));
			int lineno = n.exp2_.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.call_instr("printf"));
			asm.appendEntry(SPARCOpcode.nop_instr());
			asm.appendEntry(SPARCOpcode.call_instr("exit"));	
			asm.appendEntry(SPARCOpcode.nop_instr());
			
			//.True:			
			asm.appendEntry(new ASMLabel(".DenominatorNotZero"+count));

			asm.appendEntry(SPARCOpcode.ld_instr(new SPARCAddress(SPARCRegister.sp, 92), SPARCRegister.g1));
			asm.appendEntry(SPARCOpcode.add_instr(SPARCRegister.sp, new SPARCImmed(8), SPARCRegister.sp));
			n.setReg(SPARCRegister.getNextRegLocal());
			asm.appendEntry(SPARCOpcode.sdiv_instr(SPARCRegister.g1,n.exp2_.getReg(), n.getReg()));
			n.exp2_.releaseReg();
		}

⌨️ 快捷键说明

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