-/*****************************************************************************/
-/* Functions for parsing instructions */
-/*****************************************************************************/
-
-
-
static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash)
/* Create a new label and insert it into the label hash table */
{
+static void RemoveLabelFromHash (CodeSeg* S, CodeLabel* L)
+/* Remove the given code label from the hash list */
+{
+ /* Get the first entry in the hash chain */
+ CodeLabel* List = S->LabelHash[L->Hash];
+ CHECK (List != 0);
+
+ /* First, remove the label from the hash chain */
+ if (List == L) {
+ /* First entry in hash chain */
+ S->LabelHash[L->Hash] = L->Next;
+ } else {
+ /* Must search through the chain */
+ while (List->Next != L) {
+ /* If we've reached the end of the chain, something is *really* wrong */
+ CHECK (List->Next != 0);
+ /* Next entry */
+ List = List->Next;
+ }
+ /* The next entry is the one, we have been searching for */
+ List->Next = L->Next;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Functions for parsing instructions */
+/*****************************************************************************/
+
+
+
static const char* SkipSpace (const char* S)
/* Skip white space and return an updated pointer */
{
case ';':
/* Comment or hint, ignore it for now */
- break;
+ break;
case '.':
/* Control instruction */
unsigned Count = GetCodeLabelCount (E);
if (Count > 0) {
- /* The instruction has labels attached. Check if there is a next
- * instruction.
- */
- if (Index == GetCodeEntryCount (S)-1) {
+ /* The instruction has labels attached. Check if there is a next
+ * instruction.
+ */
+ if (Index == GetCodeEntryCount (S)-1) {
- /* No next instruction, move to the codeseg label pool */
- MoveLabelsToPool (S, E);
+ /* No next instruction, move to the codeseg label pool */
+ MoveLabelsToPool (S, E);
- } else {
+ } else {
- /* There is a next insn, get it */
- CodeEntry* N = GetCodeEntry (S, Index+1);
+ /* There is a next insn, get it */
+ CodeEntry* N = GetCodeEntry (S, Index+1);
- /* Move labels to the next entry */
- MoveCodeLabels (S, E, N);
+ /* Move labels to the next entry */
+ MoveCodeLabels (S, E, N);
- }
+ }
}
/* If this insn references a label, remove the reference. And, if the
L = NewCodeSegLabel (S, Name, Hash);
}
+ /* Safety. This call is quite costly, but safety is better */
+ if (CollIndex (&S->Labels, L) >= 0) {
+ Internal ("AddCodeLabel: Label `%s' already defined", Name);
+ }
+
/* We do now have a valid label. Remember it for later */
CollAppend (&S->Labels, L);
}
{
unsigned Count, I;
- /* Get the first entry in the hash chain */
- CodeLabel* List = S->LabelHash[L->Hash];
-
/* First, remove the label from the hash chain */
- if (List == L) {
- /* First entry in hash chain */
- S->LabelHash[L->Hash] = L->Next;
- } else {
- /* Must search through the chain */
- while (List->Next != L) {
- /* If we've reached the end of the chain, something is *really* wrong */
- CHECK (List->Next != 0);
- /* Next entry */
- List = List->Next;
- }
- /* The next entry is the one, we have been searching for */
- List->Next = L->Next;
- }
+ RemoveLabelFromHash (S, L);
/* Remove references from insns jumping to this label */
Count = CollCount (&L->JumpFrom);
}
CollDeleteAll (&L->JumpFrom);
- /* Remove the reference to the owning instruction */
- CollDeleteItem (&L->Owner->Labels, L);
+ /* Remove the reference to the owning instruction if it has one. The
+ * function may be called for a label without an owner when deleting
+ * unfinished parts of the code. This is unfortunate since it allows
+ * errors to slip through.
+ */
+ if (L->Owner) {
+ CollDeleteItem (&L->Owner->Labels, L);
+ }
/* All references removed, delete the label itself */
FreeCodeLabel (L);
/* Get a pointer to the next entry */
CodeEntry* E = GetCodeEntry (S, I);
- /* If this entry has zero labels, continue with the next one */
+ /* If this entry has zero labels, continue with the next one */
unsigned LabelCount = GetCodeLabelCount (E);
if (LabelCount == 0) {
continue;
CodeLabel* L = GetCodeLabel (E, J);
/* Move all references from this label to the reference label */
- MoveLabelRefs (L, RefLab);
+ MoveLabelRefs (L, RefLab);
/* Remove the label completely. */
DelCodeLabel (S, L);
/* Delete the label */
DelCodeLabel (S, OldLabel);
- }
+ }
} else {
-void RemoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E)
+void RemoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E)
/* Remove the reference between E and the label it jumps to. The reference
* will be removed on both sides and E->JumpTo will be 0 after that. If
* the reference was the only one for the label, the label will get
/* Get the number of entries in this segment */
unsigned Count = GetCodeEntryCount (S);
- /* Remove all entries after the given one */
- while (Last < Count) {
+ /* Check if we have to delete anything */
+ if (Last < Count) {
+
+ /* Remove all entries after the given one */
+ while (Last < Count--) {
- /* Get the next entry */
- CodeEntry* E = GetCodeEntry (S, Count-1);
+ /* Get the next entry */
+ CodeEntry* E = GetCodeEntry (S, Count);
- /* We have to transfer all labels to the code segment label pool */
- MoveLabelsToPool (S, E);
+ /* If the code entry has labels, delete them */
+ while (CodeEntryHasLabel (E)) {
- /* Remove the code entry */
- FreeCodeEntry (E);
- CollDelete (&S->Entries, Count-1);
- --Count;
+ /* Get the label */
+ CodeLabel* L = GetCodeLabel (E, 0);
+
+ /* Delete it */
+ DelCodeLabel (S, L);
+
+ }
+
+ /* Delete the entry itself */
+ DelCodeEntry (S, Count);
+ }
}
}