mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
Allow labels in user supplied asm statements
git-svn-id: svn://svn.cc65.org/cc65/trunk@1041 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
de7da529f0
commit
799459fdd5
@ -160,6 +160,48 @@ static void CS_RemoveLabelFromHash (CodeSeg* S, CodeLabel* L)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static CodeLabel* CS_AddLabelInternal (CodeSeg* S, const char* Name, int UserCode)
|
||||||
|
/* Add a code label for the next instruction to follow */
|
||||||
|
{
|
||||||
|
/* Calculate the hash from the name */
|
||||||
|
unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;
|
||||||
|
|
||||||
|
/* Try to find the code label if it does already exist */
|
||||||
|
CodeLabel* L = CS_FindLabel (S, Name, Hash);
|
||||||
|
|
||||||
|
/* Did we find it? */
|
||||||
|
if (L) {
|
||||||
|
/* We found it - be sure it does not already have an owner */
|
||||||
|
if (L->Owner) {
|
||||||
|
if (UserCode) {
|
||||||
|
Error ("ASM label `%s' is already defined", Name);
|
||||||
|
} else {
|
||||||
|
Internal ("CS_AddLabelInternal: Label `%s' already defined", Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Not found - create a new one */
|
||||||
|
L = CS_NewCodeLabel (S, Name, Hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Safety. This call is quite costly, but safety is better */
|
||||||
|
if (CollIndex (&S->Labels, L) >= 0) {
|
||||||
|
if (UserCode) {
|
||||||
|
Error ("ASM label `%s' is already defined", Name);
|
||||||
|
} else {
|
||||||
|
Internal ("CS_AddLabelInternal: Label `%s' already defined", Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We do now have a valid label. Remember it for later */
|
||||||
|
CollAppend (&S->Labels, L);
|
||||||
|
|
||||||
|
/* Return the label */
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Functions for parsing instructions */
|
/* Functions for parsing instructions */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -223,8 +265,27 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
|||||||
CodeEntry* E;
|
CodeEntry* E;
|
||||||
CodeLabel* Label;
|
CodeLabel* Label;
|
||||||
|
|
||||||
/* Mnemonic */
|
/* Read the first token and skip white space after it */
|
||||||
L = ReadToken (L, " \t", Mnemo, sizeof (Mnemo));
|
L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo)));
|
||||||
|
|
||||||
|
/* Check if we have a label */
|
||||||
|
if (*L == ':') {
|
||||||
|
|
||||||
|
/* Skip the colon and following white space */
|
||||||
|
L = SkipSpace (L+1);
|
||||||
|
|
||||||
|
/* Add the label */
|
||||||
|
CS_AddLabelInternal (S, Mnemo, 1);
|
||||||
|
|
||||||
|
/* If we have reached end of line, bail out, otherwise a mnemonic
|
||||||
|
* may follow.
|
||||||
|
*/
|
||||||
|
if (*L == '\0') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
L = SkipSpace (ReadToken (L, " \t", Mnemo, sizeof (Mnemo)));
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to find the opcode description for the mnemonic */
|
/* Try to find the opcode description for the mnemonic */
|
||||||
OPC = FindOP65 (Mnemo);
|
OPC = FindOP65 (Mnemo);
|
||||||
@ -235,9 +296,6 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip separator white space */
|
|
||||||
L = SkipSpace (L);
|
|
||||||
|
|
||||||
/* Get the addressing mode */
|
/* Get the addressing mode */
|
||||||
Arg[0] = '\0';
|
Arg[0] = '\0';
|
||||||
switch (*L) {
|
switch (*L) {
|
||||||
@ -669,31 +727,7 @@ unsigned CS_GetEntryIndex (CodeSeg* S, struct CodeEntry* E)
|
|||||||
CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name)
|
CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name)
|
||||||
/* Add a code label for the next instruction to follow */
|
/* Add a code label for the next instruction to follow */
|
||||||
{
|
{
|
||||||
/* Calculate the hash from the name */
|
return CS_AddLabelInternal (S, Name, 0);
|
||||||
unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;
|
|
||||||
|
|
||||||
/* Try to find the code label if it does already exist */
|
|
||||||
CodeLabel* L = CS_FindLabel (S, Name, Hash);
|
|
||||||
|
|
||||||
/* Did we find it? */
|
|
||||||
if (L) {
|
|
||||||
/* We found it - be sure it does not already have an owner */
|
|
||||||
CHECK (L->Owner == 0);
|
|
||||||
} else {
|
|
||||||
/* Not found - create a new one */
|
|
||||||
L = CS_NewCodeLabel (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 */
|
|
||||||
CollAppend (&S->Labels, L);
|
|
||||||
|
|
||||||
/* Return the label */
|
|
||||||
return L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user