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