/*-----------------------------------------------------------------*/ void setUserbpCommand (int bpnum, char *cmds) { breakp *bp; int k; Dprintf(D_break, ("break: setUserbpCommand %d: commands:\n%send\n", bpnum, cmds)); for ( bp = hTabFirstItem(bptable,&k); bp ; bp = hTabNextItem(bptable,&k)) { if ((bp->bpType == USER || bp->bpType == TMPUSER ) && ( bp->bpnum == bpnum )) { if ( bp->commands ) Safe_free(bp->commands); bp->commands = cmds; return; } } fprintf(stderr,"No breakpoint number %d.\n",bpnum); }
/*-----------------------------------------------------------------*/ void deleteNEXTbp () { breakp *bp; int k; Dprintf(D_break, ("break: Deleting all NEXT BPs\n")); /* for break points delete if they are NEXT */ for ( bp = hTabFirstItem(bptable,&k); bp ; bp = hTabNextItem(bptable,&k)) { /* if this is a step then delete */ if (bp->bpType == NEXT) { hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL); Safe_free(bp); } } }
/*-----------------------------------------------------------------*/ void dumpLiveRanges (int id, hTab * liveRanges) { FILE *file; symbol *sym; int k; if (id) { file=createDumpFile(id); } else { file = stdout; } if (currFunc) fprintf(file,"------------- Func %s -------------\n",currFunc->name); for (sym = hTabFirstItem (liveRanges, &k); sym; sym = hTabNextItem (liveRanges, &k)) { fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}", (sym->rname[0] ? sym->rname : sym->name), sym->key, sym->liveFrom, sym->liveTo, sym->stack, sym->isreqv, sym->remat ); fprintf (file, "{"); printTypeChain (sym->type, file); if (sym->usl.spillLoc) { fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname); } fprintf (file, "} clashes with "); bitVectDebugOn(sym->clashes,file); fprintf (file, "\n"); } fflush(file); }
/*-----------------------------------------------------------------*/ void deleteUSERbp (int bpnum) { breakp *bp; int k; Dprintf(D_break, ("break: deleteUSERbp %d\n", bpnum)); /* for break points delete if they are STEP */ for ( bp = hTabFirstItem(bptable,&k); bp ; bp = hTabNextItem(bptable,&k)) { /* if this is a user then delete if break point matches or bpnumber == -1 (meaning delete all user break points */ if ((bp->bpType == USER || bp->bpType == TMPUSER ) && ( bp->bpnum == bpnum || bpnum == -1)) { hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL); /* if this leaves no other break points then send command to simulator to delete bp from this addr */ if (hTabSearch(bptable,bp->addr) == NULL) { simClearBP (bp->addr); Dprintf(D_break, ("break: deleteUSERbp:simClearBP 0x%x\n", bp->addr)); } fprintf(stdout,"Deleted breakpoint %d\n",bp->bpnum); userBpPresent-- ; freeUSERbp(bp); if (bpnum == -1) continue ; else break; } } if (!bp && bpnum != -1) fprintf(stderr,"No breakpoint number %d.\n",bpnum); }
/*-----------------------------------------------------------------*/ static bool checkLabelRef (void) { int key; labelHashEntry *entry; if (!labelHash) { /* no labels at all: no problems ;-) */ return TRUE; } for (entry = (labelHashEntry *) hTabFirstItem (labelHash, &key); entry; entry = (labelHashEntry *) hTabNextItem (labelHash, &key)) { /* In our path we passed a label, but we didn't meet all references (jumps) to this label. This means that the code jumps from outside into this path. */ if (entry->passedLabel && entry->jmpToCount != entry->refCount) { return FALSE; } /* In our path we jumped to (referenced) a label, but we we didn't pass it. This means that there's a code path into our path. */ if (!entry->passedLabel && entry->jmpToCount != 0) { return FALSE; } } return TRUE; }
/*-----------------------------------------------------------------*/ void recomputeLiveRanges (eBBlock **ebbs, int count, bool emitWarnings) { symbol * sym; int key; /* clear all rlive bitVectors */ rliveClear (ebbs, count); sym = hTabFirstItem (liveRanges, &key); if (sym) { do { sym->used = 0; sym->liveFrom = 0; sym->liveTo = 0; freeBitVect (sym->clashes); sym->clashes = NULL; } while ( (sym = hTabNextItem (liveRanges, &key))); } /* do the LR computation again */ computeLiveRanges (ebbs, count, emitWarnings); }
/*-----------------------------------------------------------------*/ static void regTypeNum (void) { symbol *sym; int k; /* for each live range do */ for (sym = hTabFirstItem (liveRanges, &k); sym; sym = hTabNextItem (liveRanges, &k)) { /* if used zero times then no registers needed. Exception: Variables larger than 4 bytes - these might need a spill location when they are return values */ if ((sym->liveTo - sym->liveFrom) == 0 && getSize (sym->type) <= 4) continue; D (D_ALLOC, ("regTypeNum: loop on sym %p\n", sym)); /* if the live range is a temporary */ if (sym->isitmp) { /* if the type is marked as a conditional */ if (sym->regType == REG_CND) continue; /* if used in return only then we don't need registers */ if (sym->ruonly || sym->accuse) { if (IS_AGGREGATE (sym->type) || sym->isptr) sym->type = aggrToPtr (sym->type, FALSE); continue; } /* if not then we require registers */ D (D_ALLOC, ("regTypeNum: isagg %u nRegs %u type %p\n", IS_AGGREGATE (sym->type) || sym->isptr, sym->nRegs, sym->type)); sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ? getSize (sym->type = aggrToPtr (sym->type, FALSE)) : getSize (sym->type)); D (D_ALLOC, ("regTypeNum: setting nRegs of %s (%p) to %u\n", sym->name, sym, sym->nRegs)); D (D_ALLOC, ("regTypeNum: setup to assign regs sym %p\n", sym)); if (sym->nRegs > 8) { fprintf (stderr, "allocated more than 8 registers for type "); printTypeChain (sym->type, stderr); fprintf (stderr, "\n"); } /* determine the type of register required */ /* Always general purpose */ sym->regType = REG_GPR; } else { /* for the first run we don't provide */ /* registers for true symbols we will */ /* see how things go */ D (D_ALLOC, ("regTypeNum: #2 setting num of %p to 0\n", sym)); sym->nRegs = 0; } } }