📄 codegeneration.java
字号:
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 + -