CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name) /* Add a code label for the next instruction to follow */ { /* Calculate the hash from the name */ unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE; /* Try to find the code label if it does already exist */ CodeLabel* L = CS_FindLabel (S, Name, Hash); /* Did we find it? */ if (L) { /* We found it - be sure it does not already have an owner */ if (L->Owner) { Error ("ASM label `%s' is already defined", Name); return L; } } else { /* Not found - create a new one */ L = CS_NewCodeLabel (S, Name, Hash); } /* Safety. This call is quite costly, but safety is better */ if (CollIndex (&S->Labels, L) >= 0) { Error ("ASM label `%s' is already defined", Name); return L; } /* We do now have a valid label. Remember it for later */ CollAppend (&S->Labels, L); /* Return the label */ return L; }
unsigned CS_GetEntryIndex (CodeSeg* S, struct CodeEntry* E) /* Return the index of a code entry */ { int Index = CollIndex (&S->Entries, E); CHECK (Index >= 0); return Index; }
void CS_DelCodeAfter (CodeSeg* S, unsigned Last) /* Delete all entries including the given one */ { /* Get the number of entries in this segment */ unsigned Count = CS_GetEntryCount (S); /* First pass: Delete all references to labels. If the reference count * for a label drops to zero, delete it. */ unsigned C = Count; while (Last < C--) { /* Get the next entry */ CodeEntry* E = CS_GetEntry (S, C); /* Check if this entry has a label reference */ if (E->JumpTo) { /* If the label is a label in the label pool and this is the last * reference to the label, remove the label from the pool. */ CodeLabel* L = E->JumpTo; int Index = CollIndex (&S->Labels, L); if (Index >= 0 && CollCount (&L->JumpFrom) == 1) { /* Delete it from the pool */ CollDelete (&S->Labels, Index); } /* Remove the reference to the label */ CS_RemoveLabelRef (S, E); } } /* Second pass: Delete the instructions. If a label attached to an * instruction still has references, it must be references from outside * the deleted area. Don't delete the label in this case, just make it * ownerless and move it to the label pool. */ C = Count; while (Last < C--) { /* Get the next entry */ CodeEntry* E = CS_GetEntry (S, C); /* Check if this entry has a label attached */ if (CE_HasLabel (E)) { /* Move the labels to the pool and clear the owner pointer */ CS_MoveLabelsToPool (S, E); } /* Delete the pointer to the entry */ CollDelete (&S->Entries, C); /* Delete the entry itself */ FreeCodeEntry (E); } }
HashValue MultiJoin::topHash() { selectionPred().clear(); HashValue result = RelExpr::topHash(); result ^= jbbSubset_.getJBBCs(); result ^= CollIndex(jbbSubset_.getGB()); return result; }
void CollDeleteItem (Collection* C, const void* Item) /* Delete the item pointer from the collection. The item must be in the ** collection, otherwise FAIL will be called. */ { /* Get the index of the entry */ int Index = CollIndex (C, Item); CHECK (Index >= 0); /* Delete the item with this index */ --C->Count; memmove (C->Items+Index, C->Items+Index+1, (C->Count-Index) * sizeof (void*)); }
int CE_UseLoadFlags (CodeEntry* E) /* Return true if the instruction uses any flags that are set by a load of ** a register (N and Z). */ { /* Follow unconditional branches, but beware of endless loops. After this, ** E will point to the first entry that is not a branch. */ if (E->Info & OF_UBRA) { Collection C = AUTO_COLLECTION_INITIALIZER; /* Follow the chain */ while (E->Info & OF_UBRA) { /* Remember the entry so we can detect loops */ CollAppend (&C, E); /* Check the target */ if (E->JumpTo == 0 || CollIndex (&C, E->JumpTo->Owner) >= 0) { /* Unconditional jump to external symbol, or endless loop. */ DoneCollection (&C); return 0; /* Flags not used */ } /* Follow the chain */ E = E->JumpTo->Owner; } /* Delete the collection */ DoneCollection (&C); } /* A branch will use the flags */ if (E->Info & OF_FBRA) { return 1; } /* Call of a boolean transformer routine will also use the flags */ if (E->OPC == OP65_JSR) { /* Get the condition that is evaluated and check it */ switch (FindBoolCmpCond (E->Arg)) { case CMP_EQ: case CMP_NE: case CMP_GT: case CMP_GE: case CMP_LT: case CMP_LE: case CMP_UGT: case CMP_ULE: /* Will use the N or Z flags */ return 1; case CMP_UGE: /* Uses only carry */ case CMP_ULT: /* Dito */ default: /* No bool transformer subroutine */ return 0; } } /* Anything else */ return 0; }
void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last) /* Delete all entries between first and last, both inclusive. The function * can only handle basic blocks (First is the only entry, Last the only exit) * and no open labels. It will call FAIL if any of these preconditions are * violated. */ { unsigned I; CodeEntry* FirstEntry; /* Do some sanity checks */ CHECK (First <= Last && Last < CS_GetEntryCount (S)); /* If Last is actually the last insn, call CS_DelCodeAfter instead, which * is more flexible in this case. */ if (Last == CS_GetEntryCount (S) - 1) { CS_DelCodeAfter (S, First); return; } /* Get the first entry and check if it has any labels. If it has, move * them to the insn following Last. If Last is the last insn of the code * segment, make them ownerless and move them to the label pool. */ FirstEntry = CS_GetEntry (S, First); if (CE_HasLabel (FirstEntry)) { /* Get the entry following last */ CodeEntry* FollowingEntry = CS_GetNextEntry (S, Last); if (FollowingEntry) { /* There is an entry after Last - move the labels */ CS_MoveLabels (S, FirstEntry, FollowingEntry); } else { /* Move the labels to the pool and clear the owner pointer */ CS_MoveLabelsToPool (S, FirstEntry); } } /* First pass: Delete all references to labels. If the reference count * for a label drops to zero, delete it. */ for (I = Last; I >= First; --I) { /* Get the next entry */ CodeEntry* E = CS_GetEntry (S, I); /* Check if this entry has a label reference */ if (E->JumpTo) { /* If the label is a label in the label pool, this is an error */ CodeLabel* L = E->JumpTo; CHECK (CollIndex (&S->Labels, L) < 0); /* Remove the reference to the label */ CS_RemoveLabelRef (S, E); } } /* Second pass: Delete the instructions. If a label attached to an * instruction still has references, it must be references from outside * the deleted area, which is an error. */ for (I = Last; I >= First; --I) { /* Get the next entry */ CodeEntry* E = CS_GetEntry (S, I); /* Check if this entry has a label attached */ CHECK (!CE_HasLabel (E)); /* Delete the pointer to the entry */ CollDelete (&S->Entries, I); /* Delete the entry itself */ FreeCodeEntry (E); } }