mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
Interim fix for Issue #897.
This commit is contained in:
parent
0ed41db478
commit
e435da6234
@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
char Reg;
|
||||
CodeEntry* E;
|
||||
CodeLabel* Label;
|
||||
const char* ArgBase = Arg;
|
||||
int IsLabel = 0;
|
||||
|
||||
/* Read the first token and skip white space after it */
|
||||
L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo)));
|
||||
@ -448,31 +450,43 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
|
||||
}
|
||||
|
||||
/* If the instruction is a branch, check for the label and generate it
|
||||
** if it does not exist. This may lead to unused labels (if the label
|
||||
/* We do now have the addressing mode in AM. Allocate a new CodeEntry
|
||||
** structure and half-initialize it. We'll set the argument and the label
|
||||
** later.
|
||||
*/
|
||||
E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI);
|
||||
|
||||
/* If the instruction is a branch or accessing memory data, check if for
|
||||
** the argument could refer to a label. If it does but the label does not
|
||||
** exist yet, generate it. This may lead to unused labels (if the label
|
||||
** is actually an external one) which are removed by the CS_MergeLabels
|
||||
** function later.
|
||||
*/
|
||||
Label = 0;
|
||||
if (AM == AM65_BRA) {
|
||||
if ((E->Info & OF_CALL) == 0 &&
|
||||
(E->ArgInfo & AIF_HAS_NAME) != 0) {
|
||||
ArgBase = E->ArgBase;
|
||||
IsLabel = (E->ArgInfo & AIF_LOCAL) != 0;
|
||||
}
|
||||
|
||||
if (AM == AM65_BRA || IsLabel) {
|
||||
|
||||
/* Generate the hash over the label, then search for the label */
|
||||
unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE;
|
||||
Label = CS_FindLabel (S, Arg, Hash);
|
||||
unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE;
|
||||
Label = CS_FindLabel (S, ArgBase, Hash);
|
||||
|
||||
/* If we don't have the label, it's a forward ref - create it unless
|
||||
** it's an external function.
|
||||
*/
|
||||
if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) {
|
||||
if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) {
|
||||
/* Generate a new label */
|
||||
Label = CS_NewCodeLabel (S, Arg, Hash);
|
||||
}
|
||||
Label = CS_NewCodeLabel (S, ArgBase, Hash);
|
||||
}
|
||||
|
||||
/* We do now have the addressing mode in AM. Allocate a new CodeEntry
|
||||
** structure and initialize it.
|
||||
*/
|
||||
E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI);
|
||||
if (Label != 0) {
|
||||
/* Assign the jump */
|
||||
CL_AddRef (Label, E);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the new code entry */
|
||||
return E;
|
||||
@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
|
||||
/* Be sure that code entry references a label */
|
||||
PRECONDITION (OldLabel != 0);
|
||||
|
||||
/* Remove the reference to our label */
|
||||
CS_RemoveLabelRef (S, E);
|
||||
/* Delete the entry from the label */
|
||||
CollDeleteItem (&OldLabel->JumpFrom, E);
|
||||
|
||||
/* If there are no more references, delete the label */
|
||||
if (CollCount (&OldLabel->JumpFrom) == 0) {
|
||||
CS_DelLabel (S, OldLabel);
|
||||
}
|
||||
|
||||
/* Use the new label */
|
||||
CL_AddRef (L, E);
|
||||
|
Loading…
x
Reference in New Issue
Block a user