Interim fix for Issue #897.
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user