Interim fix for Issue #897.

This commit is contained in:
acqn
2020-09-18 20:21:51 +08:00
committed by Oliver Schmidt
parent 0ed41db478
commit e435da6234

View File

@@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
char Reg; char Reg;
CodeEntry* E; CodeEntry* E;
CodeLabel* Label; CodeLabel* Label;
const char* ArgBase = Arg;
int IsLabel = 0;
/* Read the first token and skip white space after it */ /* Read the first token and skip white space after it */
L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); 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 /* We do now have the addressing mode in AM. Allocate a new CodeEntry
** if it does not exist. This may lead to unused labels (if the label ** 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 ** is actually an external one) which are removed by the CS_MergeLabels
** function later. ** function later.
*/ */
Label = 0; if ((E->Info & OF_CALL) == 0 &&
if (AM == AM65_BRA) { (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 */ /* Generate the hash over the label, then search for the label */
unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE;
Label = CS_FindLabel (S, Arg, Hash); Label = CS_FindLabel (S, ArgBase, Hash);
/* If we don't have the label, it's a forward ref - create it unless /* If we don't have the label, it's a forward ref - create it unless
** it's an external function. ** 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 */ /* 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 the new code entry */
return E; return E;
} }
@@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
/* Be sure that code entry references a label */ /* Be sure that code entry references a label */
PRECONDITION (OldLabel != 0); PRECONDITION (OldLabel != 0);
/* Remove the reference to our label */ /* Delete the entry from the label */
CS_RemoveLabelRef (S, E); 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 */ /* Use the new label */
CL_AddRef (L, E); CL_AddRef (L, E);