/** * Add an identifier to the symbol table and store its offset in the activation record. * This function is called by dlinkApply1. * * @param node a node on a linked list containing the symbol table index of a variable * delcared in a program * @param data a structure containing the symbol table index of the type of the variable, * the symbol table, and the current offset in the activation record. */ void addIdToSymtab(DNode node, AddIdStructPtr data) { int symIndex = (int)dlinkNodeAtom(node); int typeIndex = (int)SymGetFieldByIndex(data->idSymtab,symIndex,SYMTAB_TYPE_INDEX_FIELD); if (typeIndex == -1) { SymPutFieldByIndex(data->idSymtab,symIndex,SYMTAB_TYPE_INDEX_FIELD,(Generic)data->typeIndex); typeIndex = data->typeIndex; } int size = (int)SymGetFieldByIndex(data->typeSymtab,typeIndex,SYMTAB_SIZE_FIELD); SymPutFieldByIndex(data->idSymtab,symIndex,SYMTAB_OFFSET_FIELD,(Generic)(data->offset)); data->offset += size; }
/** * Get the symbol table index of a free integer register * * @param symtab a symbol table * @return the symbol table index of a free integer register */ int getFreeIntegerRegisterIndex(SymTable symtab) { int reg = allocateIntegerRegister(); char* symReg = getIntegerRegisterName(reg); int regIndex; if ((regIndex = SymQueryIndex(symtab,symReg)) == SYM_INVALID_INDEX) { regIndex = SymIndex(symtab,symReg); SymPutFieldByIndex(symtab,regIndex,SYMTAB_REGISTER_INDEX_FIELD,(Generic)reg); SymPutFieldByIndex(symtab,regIndex,SYMTAB_TYPE_INDEX_FIELD, (Generic)SymQueryIndex(symtab,SYMTAB_INTEGER_TYPE_STRING)); } return regIndex; }
/** * emitPostCall * * Save callee-saved regs * extend AR for locals * find static data area * initialize locals * fall through to code * @return index to label in symbol table for caller methods */ void emitPostCall(DList instList, SymtabStack symtabStack, int index, int frameSize){ SymTable symtab = currentSymtab(symtabStack); SymTable symtab_0 = lastSymtab(symtabStack); char* name = (char*)SymGetFieldByIndex(symtab_0, index,SYM_NAME_FIELD); char* inst = nssave(2,name,":"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //save $ra inst = ssave("\tsw $ra,76($sp)"); dlinkAppend(instList,dlinkNodeAlloc(inst)); char regN[5]; char frameStr[10]; int si = 0; //save s0-s7 regs for( ; si<8; si++){ sprintf(regN,"$s%d,%d($sp)",si,(si*4)+4); inst = nssave(2,"\tsw ",regN); dlinkAppend(instList,dlinkNodeAlloc(inst)); } inst = ssave("\tmove $fp,$sp"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //allocate room for any local variables if (frameSize != 0) { sprintf(frameStr,"%d",frameSize); inst = nssave(2,"\taddi $sp,$sp,",frameStr); dlinkAppend(instList,dlinkNodeAlloc(inst)); //store any local variables on the stack(kind of) int i = 0; int max = SymMaxIndex(symtab); int offset = 0; for(;i<=max;i++) { offset = -(int)SymGetFieldByIndex(symtab,i,SYMTAB_OFFSET_FIELD); SymPutFieldByIndex(symtab,i,SYMTAB_OFFSET_FIELD,(Generic)offset); } } }
/** * Push a new symbol table on the stack when entering a new scope region * * @param stack a stack of symbol tables * @return a new symbol table */ SymTable beginScope(SymtabStack stack) { SymTable symtab = SymInit(SYMTABLE_SIZE); SymInitField(symtab,SYMTAB_OFFSET_FIELD,(Generic)-1,NULL); SymInitField(symtab,SYMTAB_REGISTER_INDEX_FIELD,(Generic)-1,NULL); int intIndex = SymIndex(symtab,SYMTAB_INTEGER_TYPE_STRING); int errorIndex = SymIndex(symtab,SYMTAB_ERROR_TYPE_STRING); int voidIndex = SymIndex(symtab,SYMTAB_VOID_TYPE_STRING); SymPutFieldByIndex(symtab,intIndex,SYMTAB_SIZE_FIELD,(Generic)INTEGER_SIZE); SymPutFieldByIndex(symtab,errorIndex,SYMTAB_SIZE_FIELD,(Generic)0); SymPutFieldByIndex(symtab,voidIndex,SYMTAB_SIZE_FIELD,(Generic)0); SymPutFieldByIndex(symtab,intIndex,SYMTAB_BASIC_TYPE_FIELD,(Generic)INTEGER_TYPE); SymPutFieldByIndex(symtab,errorIndex,SYMTAB_BASIC_TYPE_FIELD,(Generic)ERROR_TYPE); SymPutFieldByIndex(symtab,voidIndex,SYMTAB_BASIC_TYPE_FIELD,(Generic)VOID_TYPE); dlinkPush(dlinkNodeAlloc((Generic)symtab),stack); int *size = (int*)dlinkListAtom(stack); (*size)++; return symtab; }