static void insertArc (PCALL_GRAPH pcallGraph, PPROC newProc) /* Inserts an outEdge at the current callGraph pointer if the newProc does * not exist. */ { CALL_GRAPH *pcg; Int i; /* Check if procedure already exists */ for (i = 0; i < pcallGraph->numOutEdges; i++) if (pcallGraph->outEdges[i]->proc == newProc) return; /* Check if need to allocate more space */ if (pcallGraph->numOutEdges == pcallGraph->numAlloc) { pcallGraph->numAlloc += NUM_PROCS_DELTA; pcallGraph->outEdges = allocVar(pcallGraph->outEdges, pcallGraph->numAlloc * sizeof(PCALL_GRAPH)); } /* Include new arc */ pcg = allocStruc(CALL_GRAPH); memset (pcg, 0, sizeof(CALL_GRAPH)); pcg->proc = newProc; pcallGraph->outEdges[pcallGraph->numOutEdges] = pcg; pcallGraph->numOutEdges++; }
/* Inserts the new index at the end of the list. If there is need to allocate extra storage, it does so. */ void insertIdx(IDX_ARRAY *list, int idx) { if (list->csym == list->alloc) { list->alloc += IDX_ARRAY_DELTA; list->idx = allocVar(list->idx, list->alloc * sizeof(int)); } list->idx[list->csym] = idx; list->csym++; }
void allocStkArgs (PICODE picode, Int num) /* Allocates num arguments in the actual argument list of the current * icode picode. */ { PSTKFRAME ps; ps = picode->ic.hl.oper.call.args; ps->alloc = num; ps->csym = num; ps->numArgs = num; ps->sym = allocVar(ps->sym, ps->alloc * sizeof(STKSYM)); }
/* Creates a new identifier node of type t and returns it. @locSym: local long symbol table @t: type of LONG identifier @f: frame where this variable is located */ static void newIdent(LOCAL_ID *locSym, hlType t, frameType f) { if (locSym->csym == locSym->alloc) { locSym->alloc += LOCAL_ID_DELTA; locSym->id = allocVar(locSym->id, locSym->alloc * sizeof(ID)); memset(&locSym->id[locSym->csym], 0, LOCAL_ID_DELTA * sizeof(ID)); } locSym->id[locSym->csym].type = t; locSym->id[locSym->csym].loc = f; locSym->csym++; }
boolT newStkArg (PICODE picode, COND_EXPR *exp, llIcode opcode, PPROC pproc) /* Inserts the new expression (ie. the actual parameter) on the argument * list. * Returns: TRUE if it was a near call that made use of a segment register. * FALSE elsewhere */ { PSTKFRAME ps; byte regi; /* Check for far procedure call, in which case, references to segment * registers are not be considered another parameter (i.e. they are * long references to another segment) */ if (exp) { if ((exp->type == IDENTIFIER) && (exp->expr.ident.idType == REGISTER)) { regi = pproc->localId.id[exp->expr.ident.idNode.regiIdx].id.regi; if ((regi >= rES) && (regi <= rDS)) if (opcode == iCALLF) return (FALSE); else return (TRUE); } } /* Place register argument on the argument list */ ps = picode->ic.hl.oper.call.args; if (ps->csym == ps->alloc) { ps->alloc += 5; ps->sym = allocVar(ps->sym, ps->alloc * sizeof(STKSYM)); } ps->sym[ps->csym].actual = exp; ps->csym++; ps->numArgs++; return (FALSE); }
void newRegArg (PPROC pproc, PICODE picode, PICODE ticode) /* Updates the argument table by including the register(s) (ie. lhs of * picode) and the actual expression (ie. rhs of picode). * Note: register(s) are only included once in the table. */ { COND_EXPR *lhs; PSTKFRAME ps, ts; ID *id; Int i, tidx; boolT regExist; condId type; PPROC tproc; byte regL, regH; /* Registers involved in arguments */ /* Flag ticode as having register arguments */ tproc = ticode->ic.hl.oper.call.proc; tproc->flg |= REG_ARGS; /* Get registers and index into target procedure's local list */ ps = ticode->ic.hl.oper.call.args; ts = &tproc->args; lhs = picode->ic.hl.oper.asgn.lhs; type = lhs->expr.ident.idType; if (type == REGISTER) { regL = pproc->localId.id[lhs->expr.ident.idNode.regiIdx].id.regi; if (regL < rAL) tidx = newByteWordRegId (&tproc->localId, TYPE_WORD_SIGN, regL); else tidx = newByteWordRegId (&tproc->localId, TYPE_BYTE_SIGN, regL); } else if (type == LONG_VAR) { regL = pproc->localId.id[lhs->expr.ident.idNode.longIdx].id.longId.l; regH = pproc->localId.id[lhs->expr.ident.idNode.longIdx].id.longId.h; tidx = newLongRegId (&tproc->localId, TYPE_LONG_SIGN, regH, regL, 0); } /* Check if register argument already on the formal argument list */ regExist = FALSE; for (i = 0; i < ts->csym; i++) { if (type == REGISTER) { if ((ts->sym[i].regs != NULL) && (ts->sym[i].regs->expr.ident.idNode.regiIdx == tidx)) { regExist = TRUE; i = ts->csym; } } else if (type == LONG_VAR) { if ((ts->sym[i].regs != NULL) && (ts->sym[i].regs->expr.ident.idNode.longIdx == tidx)) { regExist = TRUE; i = ts->csym; } } } /* Do ts (formal arguments) */ if (regExist == FALSE) { if (ts->csym == ts->alloc) { ts->alloc += 5; ts->sym = allocVar(ts->sym, ts->alloc * sizeof(STKSYM)); } sprintf (ts->sym[ts->csym].name, "arg%ld", ts->csym); if (type == REGISTER) { if (regL < rAL) { ts->sym[ts->csym].type = TYPE_WORD_SIGN; ts->sym[ts->csym].regs = idCondExpRegIdx (tidx, WORD_REG); } else { ts->sym[ts->csym].type = TYPE_BYTE_SIGN; ts->sym[ts->csym].regs = idCondExpRegIdx (tidx, BYTE_REG); } sprintf (tproc->localId.id[tidx].name, "arg%ld", ts->csym); } else if (type == LONG_VAR) { ts->sym[ts->csym].regs = idCondExpLongIdx (tidx); ts->sym[ts->csym].type = TYPE_LONG_SIGN; sprintf (tproc->localId.id[tidx].name, "arg%ld", ts->csym); propLongId (&tproc->localId, regL, regH, tproc->localId.id[tidx].name); } ts->csym++; ts->numArgs++; } /* Do ps (actual arguments) */ if (ps->csym == ps->alloc) { ps->alloc += 5; ps->sym = allocVar(ps->sym, ps->alloc * sizeof(STKSYM)); } sprintf (ps->sym[ps->csym].name, "arg%ld", ps->csym); ps->sym[ps->csym].actual = picode->ic.hl.oper.asgn.rhs; ps->sym[ps->csym].regs = lhs; /* Mask off high and low register(s) in picode */ switch (type) { case REGISTER: id = &pproc->localId.id[lhs->expr.ident.idNode.regiIdx]; picode->du.def &= maskDuReg[id->id.regi]; if (id->id.regi < rAL) ps->sym[ps->csym].type = TYPE_WORD_SIGN; else ps->sym[ps->csym].type = TYPE_BYTE_SIGN; break; case LONG_VAR: id = &pproc->localId.id[lhs->expr.ident.idNode.longIdx]; picode->du.def &= maskDuReg[id->id.longId.h]; picode->du.def &= maskDuReg[id->id.longId.l]; ps->sym[ps->csym].type = TYPE_LONG_SIGN; break; } ps->csym++; ps->numArgs++; }