diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -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,32 +450,44 @@ 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); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* 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); - /* 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);