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:
parent
989aacec2c
commit
a961f00997
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user