/** * emitPreCall * * allocate AR * store return address & fp * save caller-saved regs * jump to callee */ void emitPreCall(DList instList, SymTable symtab, int index){ //get name for func char* funcName = (char*)SymGetFieldByIndex(symtab,index,SYM_NAME_FIELD); //save $ra char* inst = ssave("\tsw $ra,-4($sp)"); dlinkAppend(instList,dlinkNodeAlloc(inst)); char regN[5]; int si = 0; //save t0-t9 regs for( ; si<10; si++){ sprintf(regN,"$t%d,%d($sp)",si,(-si*4)-8); inst = nssave(2,"\tsw ",regN); dlinkAppend(instList,dlinkNodeAlloc(inst)); } //allocate AR inst = ssave("\taddi $sp,$sp,-80"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //save fp inst = ssave("\tsw $fp,0($sp)"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //jump to callee char * insta = nssave(2,"\tjal\t",funcName); dlinkAppend(instList,dlinkNodeAlloc(insta)); }
/** * Add the instructions needed to write a value using the print system call. * * @param instList a Dlist of instructions * @param symtab a symbol table * @param regIndex the symbol table index of the register to be printed (must be addres if string) * @param syscallService the system call print service to use */ void emitWriteExpression(DList instList,SymTable symtab, int regIndex, char* syscallService) { char *inst; inst = nssave(2,"\tmove $a0, ", (char*)SymGetFieldByIndex(symtab,regIndex,SYM_NAME_FIELD)); dlinkAppend(instList,dlinkNodeAlloc(inst)); freeIntegerRegister((int)SymGetFieldByIndex(symtab,regIndex,SYMTAB_REGISTER_INDEX_FIELD)); inst = nssave(2,"\tli $v0, ",syscallService); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = ssave("\tsyscall"); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = nssave(2,"\tli $v0, ",SYSCALL_PRINT_STRING); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = ssave("\tla, $a0, .newline"); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = ssave("\tsyscall"); dlinkAppend(instList,dlinkNodeAlloc(inst)); }
/** * emitPreReturn * restore callee-saved regs * discard local data * restore callers fp * jump to return address */ void emitPreReturn(DList instList){ //discard local data char* inst = ssave("\tmove $sp,$fp"); dlinkAppend(instList,dlinkNodeAlloc(inst)); int si = 0; char regN[5]; //restore callee-saved regs ($s0-$s7) for( ; si<8; si++) { sprintf(regN,"$s%d,%d($sp)",si,(si*4)+4); inst = nssave(2,"\tlw ",regN); dlinkAppend(instList,dlinkNodeAlloc(inst)); } //restore callers fp inst = ssave("\tlw $fp,($fp)"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //load return address into $ra inst = ssave("\tlw $ra,76($sp)"); dlinkAppend(instList,dlinkNodeAlloc(inst)); /* //save return value from $v0 into stack where ra was before inst = ssave("\tsw $v0 76($sp)"); dlinkAppend(instList,dlinkNodeAlloc(inst)); */ //jump to return address inst = ssave("\tjr\t$ra"); dlinkAppend(instList,dlinkNodeAlloc(inst)); }
void emitExit(DList instList) { char *inst = nssave(2,"\tli $v0, ",SYSCALL_EXIT); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = ssave("\tsyscall"); dlinkAppend(instList,dlinkNodeAlloc(inst)); }
/** * emitPostReturn * dallocate basic AR * restore caller-saved regs * restore reference parameters */ int emitPostReturn(DList instList,SymTable symtab){ //get new reg int regIndex = getFreeIntegerRegisterIndex(symtab); char* regName = (char*)SymGetFieldByIndex(symtab,regIndex,SYM_NAME_FIELD); //deallocate basic AR char* inst = ssave("\taddi $sp, $sp,80"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //return inst = nssave(3,"\tmove ",regName,", $v0"); dlinkAppend(instList,dlinkNodeAlloc(inst)); //restore t0-t9 regs char regN[5]; int si = 0; for( ; si<10; si++){ sprintf(regN,"$t%d,%d($sp)",si,(-si*4)-8); inst = nssave(2,"\tlw ",regN); dlinkAppend(instList,dlinkNodeAlloc(inst)); } return regIndex; }
static int SymFieldIndex(SymTable ip, char* field) { int i = 0, found; found = SymFieldFind(ip, field, &i); /* two possible cases * found = 1 ---> we've got a sparse index in i * ip->FieldNames[i] == 0 ---> we've got a sparse index in i and * we must initialize it */ #ifdef DEBUG fprintf(stderr, "\n\tsuccess: %d.\n",i); #endif if (ip->FieldNames[i] == (char*)0) { ip->FieldNames[i] = ssave(field); ip->FieldVals[i]= (Generic*) malloc(sizeof(Generic)*ip->NumSlots); bzero((char *)ip->FieldVals[i], sizeof(Generic)*ip->NumSlots); /* JMC -- initially 0 */ ip->InitVals[i] = 0; ip->CleanupFns[i] = (SymCleanupFunc)0; } return i; }
void MultiNewton::step(doublereal* x, doublereal* step, OneDim& r, MultiJac& jac, int loglevel) { size_t iok; size_t sz = r.size(); r.eval(npos, x, step); #undef DEBUG_STEP #ifdef DEBUG_STEP vector_fp ssave(sz, 0.0); for (size_t n = 0; n < sz; n++) { step[n] = -step[n]; ssave[n] = step[n]; } #else for (size_t n = 0; n < sz; n++) { step[n] = -step[n]; } #endif iok = jac.solve(step, step); // if iok is non-zero, then solve failed if (iok != 0) { iok--; size_t nd = r.nDomains(); size_t n; for (n = nd-1; n != npos; n--) if (iok >= r.start(n)) { break; } Domain1D& dom = r.domain(n); size_t offset = iok - r.start(n); size_t pt = offset/dom.nComponents(); size_t comp = offset - pt*dom.nComponents(); throw CanteraError("MultiNewton::step", "Jacobian is singular for domain "+ dom.id() + ", component " +dom.componentName(comp)+" at point " +int2str(pt)+"\n(Matrix row " +int2str(iok)+") \nsee file bandmatrix.csv\n"); } else if (int(iok) < 0) throw CanteraError("MultiNewton::step", "iok = "+int2str(iok)); #ifdef DEBUG_STEP bool ok = false; Domain1D* d; if (!ok) { for (size_t n = 0; n < sz; n++) { d = r.pointDomain(n); int nvd = d->nComponents(); int pt = (n - d->loc())/nvd; cout << "step: " << pt << " " << r.pointDomain(n)->componentName(n - d->loc() - nvd*pt) << " " << x[n] << " " << ssave[n] << " " << step[n] << endl; } } #endif }
/** * 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); } } }
void MainWindow::connections() { connect(open, SIGNAL(triggered()), this, SLOT(sopen())); connect(save, SIGNAL(triggered()), this, SLOT(ssave())); connect(revert, SIGNAL(triggered()), this, SLOT(srevert())); connect(close, SIGNAL(triggered()), this, SLOT(sclose())); connect(calculator, SIGNAL(triggered()), this, SLOT(scalculator())); connect(bnPlus, SIGNAL(pressed()), this, SLOT(plus())); connect(bnMinus, SIGNAL(pressed()), this, SLOT(minus())); connect(bnTimes, SIGNAL(pressed()), this, SLOT(times())); connect(bnDivide, SIGNAL(pressed()), this, SLOT(divide())); }
/** * Add the instructions needed to read a variable using the read system call. * * @param instList a DList of instructions * @param symtab a symbol table * @param addrIndex the symbol table index of the register holding the address that is to be read into */ void emitReadVariable(DList instList, SymTable symtab, int addrIndex) { char* inst; inst = nssave(2,"\tli $v0, ", SYSCALL_READ_INTEGER); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = ssave("\tsyscall"); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = nssave(3,"\tsw $v0, 0(", (char*)SymGetFieldByIndex(symtab,addrIndex,SYM_NAME_FIELD),")"); dlinkAppend(instList,dlinkNodeAlloc(inst)); freeIntegerRegister((int)SymGetFieldByIndex(symtab,addrIndex,SYMTAB_REGISTER_INDEX_FIELD)); }
/** * Emit the assembly prologue for a procedure * * @param frameSize The number of bytes need for local variables declared in main */ void emitProcedurePrologue(DList instList,SymTable symtab, int index, int frameSize) { char *name = (char*)SymGetFieldByIndex(symtab,index,SYM_NAME_FIELD); char* inst = nssave(2,"\t.globl ",name); dlinkAppend(instList,dlinkNodeAlloc(inst)); inst = nssave(2,name,":\tnop"); dlinkAppend(instList,dlinkNodeAlloc(inst)); char frameStr[10]; inst = ssave("\tmove $fp,$sp"); dlinkAppend(instList,dlinkNodeAlloc(inst)); if (frameSize != 0) { sprintf(frameStr,"%d",frameSize); inst = nssave(2,"\tadd $sp, $sp, ",frameStr); dlinkAppend(instList,dlinkNodeAlloc(inst)); } globalOffset = frameSize; }
/** * * returns an index for "name". If "name" is not in the symbol table, * then it is inserted in an empty slot. * * @param ip a symbol table * @param name a key to lookup in 'ip' * @return see above */ int SymIndex(SymTable ip, char* name) { register int i, initial, found, count; char **Names; Names = (char**) ip->FieldVals[ip->NameField]; initial = hash_string(name, ip->NumIndices); i = initial; found = 0; count = 1; #ifdef DEBUG fprintf(stderr, "SymIndex(%d,%s).\n\tinitial probe: %d", ip, name, i); #endif while(ip->Index[i] != -1 && found == 0) { if (strcmp(name, Names[ip->Index[i]]) == 0) found = 1; else /* 16 is relatively prime to a Mersenne prime! */ { count++; i = (i + 16) % ip->NumIndices; #ifdef DEBUG fprintf(stderr, "\tre-probe: %d", i); if ((count % 4) == 0) fprintf(stderr,"\n"); #endif if ((count > 10 && /* too many collisions! */ ip->NextSlot + ip->NextSlot > ip->NumIndices) || /* limit it!*/ (i == initial)) /* or a full table */ { OverflowIndex(ip); return SymIndex(ip,name); /* real sloppy loop exit - kdc */ } } } /* two possible cases * found = 1 ---> we've got a sparse index in i * ip->Index[i] == -1 ---> we've got a sparse index in i and * we must initialize it */ #ifdef DEBUG fprintf(stderr, "\n\tsuccess: %d.\n", i); #endif if (ip->Index[i] == -1) { ip->Index[i] = ip->NextSlot++; Names[ip->Index[i]] = ssave(name); if (ip->NextSlot == ip->NumSlots) OverflowVectors(ip); } return ip->Index[i]; }