📄 codegeneration.java
字号:
/**
*This class is used for expressions using the AND operation.
*This class extends the Exp abstract class
**/
package CatDecaf.CG;
import CatDecaf.IR.*;
import CatDecaf.Utilities.*;
import java6035.tools.ASM.*;
import java.io.*;
import java.util.*;
import CatDecaf.SymTable.*;
public class CodeGeneration implements Visitor{
public static int tab;
public ASM asm;
static int labelCnt;
public List dataLabelList;
public static boolean algebraicSimplification;
public CodeGeneration(){
labelCnt = 0;
asm = new ASM();
SPARCRegister.releaseAllRegisters();
dataLabelList = new ArrayList();
tab=0;
}
public void generate(String outfile){
//append the data section
asm.appendEntry(new ASMComment("Datasection"));
Iterator i = dataLabelList.iterator();
while(i.hasNext()){
asm.appendEntry((ASMEntry)(i.next()));
}
try {
/*
* For the heck of it, let's build an ASM file.
*/
FileOutputStream out = new FileOutputStream(outfile);
SPARCGenerator sparcgen =
new SPARCGenerator(out);
/*
* Generate SPARC asm file
*/
sparcgen.gen(asm);
sparcgen.done();
/*
* Close file
*/
out.close();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public void visit(Ir n){ } //abstract class
public void visit(IrProg n){
asm.appendEntry(new dSection(".data"));
asm.appendEntry(new ASMLabel(".GLOBALFIELD"));
Iterator it = parser.parser.classProgram.fieldVar.getDescriptorTable().values().iterator();
while(it.hasNext()){
IDDescriptor idd = (IDDescriptor)it.next();
if(!idd.isArrayType()){
asm.appendEntry(new dAlign(4));
asm.appendEntry(new dWord(1));
}else{
asm.appendEntry(new dAlign(4));
//Long[] l = {idd.getArraySize()};
asm.appendEntry(new dWord(new Long[] {new Long(idd.getArraySize())}));
//asm.appendEntry(new dWord(idd.getArraySize()));
asm.appendEntry(new dSkip(idd.getArraySize() * 4));
}
}
asm.appendEntry(new ASMLabel(".ARRAY_OUT_OF_BOUND"));
asm.appendEntry(new dAsciz(parser.parser.infile + ":%d: runtime error: array out of bound; accessing: %d, array size: %d\n"));
asm.appendEntry(new dAlign(4));
asm.appendEntry(new ASMLabel(".DIVISION_ZERO"));
asm.appendEntry(new dAsciz(parser.parser.infile + ":%d: runtime error: division to zero\n"));
asm.appendEntry(new dAlign(4));
asm.appendEntry(new ASMLabel(".CONTROL_FALLING_OFF"));
asm.appendEntry(new dAsciz(parser.parser.infile + ":%s: runtime error: control falling off the end of the method: %s , missing a return value\n"));
asm.appendEntry(new dAlign(4));
asm.appendEntry(new dSection(".text"));
asm.appendEntry(new dAlign(4));
asm.appendEntry(new dGlobal("main"));
//if(n.fdDeclList_!=null)
// n.fdDeclList_.accept(this);
if(n.mdDeclList_ == null) System.out.println("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!");
n.mdDeclList_.accept(this); //this should never be empty
}
public void visit(FdDeclList n){ //not printing List classes
while(n!= null)
{
n.fdDecl_.accept(this);
n = n.fdDeclList_;
}
}
public void visit(FdDecl n){
if(n.glbVarList_==null) System.out.println("ERROR!!!!!!!!!!!!!!!");
n.typ_.accept(this);
n.glbVarList_.accept(this);
}
public void visit(GlbVar n){ } //abstract class
public void visit(GlbVarArray n){
n.identifier_.accept(this);
n.ltrInt_.accept(this);
}
public void visit(GlbVarId n){
n.identifier_.accept(this);
}
public void visit(GlbVarList n){ //not printing List classes
while(n!= null)
{
n.glbVar_.accept(this);
n = n.glbVarList_;
}
}
public void visit(Typ n){ } //abstract class
public void visit(TypInt n){
}
public void visit(TypBool n){
}
public void visit(TypVoid n){
}
public void visit(MdDeclList n){ //not printing List classes
while(n!= null)
{
n.mdDecl_.accept(this);
n = n.mdDeclList_;
}
}
public void visit(MdDecl n){
asm.appendEntry( new ASMLabel(n.identifier_.identifier_) );
if(n.identifier_.identifier_.equals("main")){
asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".GLOBALFIELD")), SPARCRegister.g2));
asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g2, new SPARCLoOp(new ASMLabel(".GLOBALFIELD")), SPARCRegister.g2));
}
//5000 problem - Vinh The's Problem
int reserveSize = n.getReserveSize();
if(-reserveSize >= -4096 && -reserveSize <= 4095){
asm.appendEntry(SPARCOpcode.save_instr(SPARCRegister.sp, -reserveSize, SPARCRegister.sp));
}else{
asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(-reserveSize), SPARCRegister.g1));
asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(-reserveSize), SPARCRegister.g1));
asm.appendEntry(SPARCOpcode.save_instr(SPARCRegister.sp, SPARCRegister.g1, SPARCRegister.sp));
}
//default initializtion to zero for all local variables
for (int i=4; i<= reserveSize - 92; i+=4){
if(-i >= -4096 && -i <= 4095){
asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g0, new SPARCAddress(SPARCRegister.fp,-i)));
}else{
asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(-i), SPARCRegister.g1));
asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.g1, new SPARCLoOp(-i), SPARCRegister.g1));
asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g0, new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1)));
}
}
//int memSize = n.getReserveSize();
//for (int i=0;i<n.getReserveSize();i+=4){
// asm.appendEntry(SPARCOpcode.st_instr(SPARCRegister.g0, new SPARCAddress(SPARCRegister.sp, i) ));
//}
//n.typ_.accept(this);
//n.identifier_.accept(this);
if(n.mdParaList_ !=null){ //method parameter list could be NULL
n.mdParaList_.accept(this);
}
n.block_.accept(this);
if (n.typ_ instanceof TypVoid){ //void type is reurn upon closing '}'
asm.appendEntry(new ASMComment("Return statement for method:"));
asm.appendEntry(SPARCOpcode.ret_instr());
asm.appendEntry(SPARCOpcode.restore_instr());
}else{ //catch the control falling off error here.
//error message
asm.appendEntry(new ASMComment("Run time error: Control falling off detected and reported here:"));
asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".CONTROL_FALLING_OFF")), SPARCRegister.o0));
asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o0, new SPARCLoOp(new ASMLabel(".CONTROL_FALLING_OFF")), SPARCRegister.o0));
//line number
asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_+"_LINE_NO")), SPARCRegister.o1));
asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o1, new SPARCLoOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_+"_LINE_NO")), SPARCRegister.o1));
//method name
asm.appendEntry(SPARCOpcode.sethi_instr(new SPARCHiOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_)), SPARCRegister.o2));
asm.appendEntry(SPARCOpcode.or_instr(SPARCRegister.o2, new SPARCLoOp(new ASMLabel(".MDNAME_"+n.identifier_.identifier_)), SPARCRegister.o2));
asm.appendEntry(SPARCOpcode.call_instr("printf"));
asm.appendEntry(SPARCOpcode.nop_instr());
asm.appendEntry(SPARCOpcode.call_instr("exit"));
asm.appendEntry(SPARCOpcode.nop_instr());
}
//data for error message printing only
dataLabelList.add(new ASMLabel(".MDNAME_"+n.identifier_.identifier_));
dataLabelList.add(new dAsciz("'"+n.identifier_.identifier_+"( )'"));
dataLabelList.add(new dAlign(8));
dataLabelList.add(new ASMLabel(".MDNAME_"+n.identifier_.identifier_+"_LINE_NO"));
dataLabelList.add(new dAsciz(""+n.block_.lineNo_));
dataLabelList.add(new dAlign(8));
}
public void visit(MdParaList n){ //not printing List classes
while(n!= null)
{
n.mdPara_.accept(this);
n = n.mdParaList_;
}
}
public void visit(MdPara n){
n.typ_.accept(this);
n.identifier_.accept(this);
}
public void visit(Block n){
if(n.varDeclList_!=null) //var declaration list could be empty
n.varDeclList_.accept(this);
if(n.stmtList_!=null)//list can be empty
n.stmtList_.accept(this);
}
public void visit(VarDecl n){
//n.typ_.accept(this);
if(n.locVarList_==null) System.out.println("ERROR!!!!!!!!!!!!!!!");
n.locVarList_.accept(this);
}
public void visit(VarDeclList n){ //not printing List classes
while(n!= null)
{
n.varDecl_.accept(this);
n = n.varDeclList_;
}
}
public void visit(LocVar n){
n.identifier_.accept(this);
}
public void visit(LocVarList n){ //not printing List classes
while(n!= null)
{
n.locVar_.accept(this);
n = n.locVarList_;
}
}
public void visit(StmtList n){ //not printing List classes
while(n!= null)
{
n.stmt_.accept(this);
n = n.stmtList_;
}
}
public void visit(Stmt n){ } //abstract class
public void visit(StmtLocation n){
n.exp_.accept(this);
//n.location_.accept(this);
if(n.location_ instanceof LocationId) { //LocationID
int locOffset = ((LocationId)n.location_).identifier_.offset;
if( !((LocationId)n.location_).identifier_.glbVarFlag){
if(!((LocationId)n.location_).identifier_.paramFlag){ //non-parameter handling
asm.appendEntry(new ASMComment("Location id store instruction for stmt location: "+ ((LocationId)n.location_).identifier_.identifier_ + " = expression"));
if(-locOffset >= -4096 && -locOffset <= 4095){
asm.appendEntry(SPARCOpcode.st_instr(n.exp_.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.exp_.getReg(), new SPARCAddress(SPARCRegister.fp,SPARCRegister.g1)));
}
}
else{//paramenter handling
asm.appendEntry(new ASMComment("Location id store instruction for stmt location for Parameter: "+ ((LocationId)n.location_).identifier_.identifier_ + " = expression"));
int paramIndex = ((LocationId)n.location_).identifier_.offset/4;
if (paramIndex <= 5){//handing parameters within 6th
// locate the right rigister holding parameters
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 result to register directly
asm.appendEntry(new ASMComment(" Store parameter -> Ri: " ));
asm.appendEntry(SPARCOpcode.mov_instr(n.exp_.getReg(), Ri));
}else{//handling parameters past 6th
//store it into some address
int spaceForOthers = (16+1+6)*4;
int offset = (paramIndex-6)*4;
offset = offset + spaceForOthers;
//store the parameter in %sp+offset
asm.appendEntry(new ASMComment(" Store parameter -> %fp+offset: " ));
if(offset >= -4096 && offset <= 4095){
asm.appendEntry(SPARCOpcode.st_instr(n.exp_.getReg(), new SPARCAddress(SPARCRegister.fp,+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)));
}
}
}
}else{
//SPARCRegister reg1 = SPARCRegister.getNextRegLocal(); reg1.status = 1;
asm.appendEntry(new ASMComment("Global Location id store instruction for stmt location: "+ ((LocationId)n.location_).identifier_.identifier_ + " = expression"));
//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.st_instr(n.exp_.getReg(), new SPARCAddress(reg1, locOffset)));
if(locOffset >= -4096 && locOffset <= 4095){
asm.appendEntry(SPARCOpcode.st_instr(n.exp_.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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -