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