1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Several bug fixes

git-svn-id: svn://svn.cc65.org/cc65/trunk@720 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-05-07 22:07:59 +00:00
parent 989aacec2c
commit a961f00997
2 changed files with 86 additions and 62 deletions

View File

@ -93,12 +93,6 @@ static CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
/*****************************************************************************/
/* Functions for parsing instructions */
/*****************************************************************************/
static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash) static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash)
/* Create a new label and insert it into the label hash table */ /* Create a new label and insert it into the label hash table */
{ {
@ -115,6 +109,38 @@ static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash)
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) static const char* SkipSpace (const char* S)
/* Skip white space and return an updated pointer */ /* Skip white space and return an updated pointer */
{ {
@ -386,7 +412,7 @@ void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap)
case ';': case ';':
/* Comment or hint, ignore it for now */ /* Comment or hint, ignore it for now */
break; break;
case '.': case '.':
/* Control instruction */ /* Control instruction */
@ -443,23 +469,23 @@ void DelCodeEntry (CodeSeg* S, unsigned Index)
unsigned Count = GetCodeLabelCount (E); unsigned Count = GetCodeLabelCount (E);
if (Count > 0) { if (Count > 0) {
/* The instruction has labels attached. Check if there is a next /* The instruction has labels attached. Check if there is a next
* instruction. * instruction.
*/ */
if (Index == GetCodeEntryCount (S)-1) { if (Index == GetCodeEntryCount (S)-1) {
/* No next instruction, move to the codeseg label pool */ /* No next instruction, move to the codeseg label pool */
MoveLabelsToPool (S, E); MoveLabelsToPool (S, E);
} else { } else {
/* There is a next insn, get it */ /* There is a next insn, get it */
CodeEntry* N = GetCodeEntry (S, Index+1); CodeEntry* N = GetCodeEntry (S, Index+1);
/* Move labels to the next entry */ /* Move labels to the next entry */
MoveCodeLabels (S, E, N); MoveCodeLabels (S, E, N);
} }
} }
/* If this insn references a label, remove the reference. And, if the /* If this insn references a label, remove the reference. And, if the
@ -515,6 +541,11 @@ void AddCodeLabel (CodeSeg* S, const char* Name)
L = NewCodeSegLabel (S, Name, Hash); 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 */ /* We do now have a valid label. Remember it for later */
CollAppend (&S->Labels, L); CollAppend (&S->Labels, L);
} }
@ -560,24 +591,8 @@ void DelCodeLabel (CodeSeg* S, CodeLabel* L)
{ {
unsigned Count, I; 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 */ /* First, remove the label from the hash chain */
if (List == L) { RemoveLabelFromHash (S, 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;
}
/* Remove references from insns jumping to this label */ /* Remove references from insns jumping to this label */
Count = CollCount (&L->JumpFrom); Count = CollCount (&L->JumpFrom);
@ -589,8 +604,14 @@ void DelCodeLabel (CodeSeg* S, CodeLabel* L)
} }
CollDeleteAll (&L->JumpFrom); CollDeleteAll (&L->JumpFrom);
/* Remove the reference to the owning instruction */ /* Remove the reference to the owning instruction if it has one. The
CollDeleteItem (&L->Owner->Labels, L); * 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 */ /* All references removed, delete the label itself */
FreeCodeLabel (L); FreeCodeLabel (L);
@ -615,7 +636,7 @@ void MergeCodeLabels (CodeSeg* S)
/* Get a pointer to the next entry */ /* Get a pointer to the next entry */
CodeEntry* E = GetCodeEntry (S, I); 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); unsigned LabelCount = GetCodeLabelCount (E);
if (LabelCount == 0) { if (LabelCount == 0) {
continue; continue;
@ -635,7 +656,7 @@ void MergeCodeLabels (CodeSeg* S)
CodeLabel* L = GetCodeLabel (E, J); CodeLabel* L = GetCodeLabel (E, J);
/* Move all references from this label to the reference label */ /* Move all references from this label to the reference label */
MoveLabelRefs (L, RefLab); MoveLabelRefs (L, RefLab);
/* Remove the label completely. */ /* Remove the label completely. */
DelCodeLabel (S, L); DelCodeLabel (S, L);
@ -680,7 +701,7 @@ void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
/* Delete the label */ /* Delete the label */
DelCodeLabel (S, OldLabel); DelCodeLabel (S, OldLabel);
} }
} else { } else {
@ -697,7 +718,7 @@ void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
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 /* 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 * 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 * the reference was the only one for the label, the label will get
@ -769,19 +790,29 @@ void DelCodeSegAfter (CodeSeg* S, unsigned Last)
/* Get the number of entries in this segment */ /* Get the number of entries in this segment */
unsigned Count = GetCodeEntryCount (S); unsigned Count = GetCodeEntryCount (S);
/* Remove all entries after the given one */ /* Check if we have to delete anything */
while (Last < Count) { if (Last < Count) {
/* Get the next entry */ /* Remove all entries after the given one */
CodeEntry* E = GetCodeEntry (S, Count-1); while (Last < Count--) {
/* We have to transfer all labels to the code segment label pool */ /* Get the next entry */
MoveLabelsToPool (S, E); CodeEntry* E = GetCodeEntry (S, Count);
/* Remove the code entry */ /* If the code entry has labels, delete them */
FreeCodeEntry (E); while (CodeEntryHasLabel (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);
}
} }
} }

View File

@ -2615,16 +2615,9 @@ static int hieQuest (struct expent *lval)
Mark2 = GetCodePos (); /* Remember position */ Mark2 = GetCodePos (); /* Remember position */
g_typecast (TypeOf (rtype), TypeOf (type2)); g_typecast (TypeOf (rtype), TypeOf (type2));
/* If the typecast did not produce code, remove the jump, /* Jump here around the typecase code. */
* otherwise output the label. g_defcodelabel (labf);
*/ labt = 0; /* Mark other label as invalid */
if (GetCodePos() == Mark2) {
RemoveCode (Mark1); /* Remove code */
} else {
/* We have typecast code, output label */
g_defcodelabel (labf);
labt = 0; /* Mark other label as invalid */
}
} else if (IsClassPtr (type2) && IsClassPtr (type3)) { } else if (IsClassPtr (type2) && IsClassPtr (type3)) {
/* Must point to same type */ /* Must point to same type */