/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2001-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */
/* */
/* */
#include "xsprintf.h"
/* cc65 */
+#include "asmlabel.h"
#include "codegen.h"
#include "datatype.h"
#include "error.h"
#include "function.h"
#include "litpool.h"
#include "scanner.h"
+#include "stackptr.h"
#include "symtab.h"
#include "asmstmt.h"
ConsumeComma ();
/* Evaluate the expression */
- ConstSubExpr (hie1, &Expr);
+ ConstAbsIntExpr (hie1, &Expr);
/* Check the range but allow negative values if the type is signed */
if (IsSignUnsigned (Expr.Type)) {
- if (Expr.ConstVal < 0 || Expr.ConstVal > 0xFF) {
+ if (Expr.IVal < 0 || Expr.IVal > 0xFF) {
AsmRangeError (Arg);
- Expr.ConstVal = 0;
+ Expr.IVal = 0;
}
} else {
- if (Expr.ConstVal < -128 || Expr.ConstVal > 127) {
+ if (Expr.IVal < -128 || Expr.IVal > 127) {
AsmRangeError (Arg);
- Expr.ConstVal = 0;
+ Expr.IVal = 0;
}
}
/* Convert into a hex number */
- xsprintf (Buf, sizeof (Buf), "$%02lX", Expr.ConstVal & 0xFF);
+ xsprintf (Buf, sizeof (Buf), "$%02lX", Expr.IVal & 0xFF);
/* Add the number to the target buffer */
SB_AppendStr (T, Buf);
ConsumeComma ();
/* Evaluate the expression */
- ConstSubExpr (hie1, &Expr);
+ ConstAbsIntExpr (hie1, &Expr);
/* Check the range but allow negative values if the type is signed */
if (IsSignUnsigned (Expr.Type)) {
- if (Expr.ConstVal < 0 || Expr.ConstVal > 0xFFFF) {
+ if (Expr.IVal < 0 || Expr.IVal > 0xFFFF) {
AsmRangeError (Arg);
- Expr.ConstVal = 0;
+ Expr.IVal = 0;
}
} else {
- if (Expr.ConstVal < -32768 || Expr.ConstVal > 32767) {
+ if (Expr.IVal < -32768 || Expr.IVal > 32767) {
AsmRangeError (Arg);
- Expr.ConstVal = 0;
+ Expr.IVal = 0;
}
}
/* Convert into a hex number */
- xsprintf (Buf, sizeof (Buf), "$%04lX", Expr.ConstVal & 0xFFFF);
+ xsprintf (Buf, sizeof (Buf), "$%04lX", Expr.IVal & 0xFFFF);
/* Add the number to the target buffer */
SB_AppendStr (T, Buf);
ConsumeComma ();
/* Evaluate the expression */
- ConstSubExpr (hie1, &Expr);
+ ConstAbsIntExpr (hie1, &Expr);
/* Convert into a hex number */
- xsprintf (Buf, sizeof (Buf), "$%08lX", Expr.ConstVal & 0xFFFFFFFF);
+ xsprintf (Buf, sizeof (Buf), "$%08lX", Expr.IVal & 0xFFFFFFFF);
/* Add the number to the target buffer */
SB_AppendStr (T, Buf);
}
/* Check for external linkage */
- if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) {
- /* External linkage */
+ if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_FUNC)) {
+ /* External linkage or a function */
/* ### FIXME: Asm name should be generated by codegen */
SB_AppendChar (T, '_');
SB_AppendStr (T, Sym->Name);
+ } else if (Sym->Flags & SC_REGISTER) {
+ char Buf[32];
+ xsprintf (Buf, sizeof (Buf), "regbank+%d", Sym->V.R.RegOffs);
+ SB_AppendStr (T, Buf);
} else {
/* Static variable */
char Buf [16];
}
/* Calculate the current offset from SP */
- Offs = Sym->V.Offs - oursp;
+ Offs = Sym->V.Offs - StackPtr;
/* Output the offset */
xsprintf (Buf, sizeof (Buf), (Offs > 0xFF)? "$%04X" : "$%02X", Offs);
+static void ParseLabelArg (StrBuf* T, unsigned Arg attribute ((unused)))
+/* Parse the %g format specifier */
+{
+ /* We expect an identifier separated by a comma */
+ ConsumeComma ();
+ if (CurTok.Tok != TOK_IDENT) {
+
+ Error ("Label name expected");
+
+ } else {
+
+ /* Add a new label symbol if we don't have one until now */
+ SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF);
+
+ /* Append the label name to the buffer */
+ SB_AppendStr (T, LocalLabelName (Entry->V.Label));
+
+ /* Eat the label name */
+ NextToken ();
+
+ }
+}
+
+
+
+static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused)))
+/* Parse the %s format specifier */
+{
+ ExprDesc Expr;
+ char Buf [64];
+
+ /* We expect an argument separated by a comma */
+ ConsumeComma ();
+
+ /* Check what comes */
+ switch (CurTok.Tok) {
+
+ case TOK_IDENT:
+ /* Identifier */
+ SB_AppendStr (T, CurTok.Ident);
+ NextToken ();
+ break;
+
+ case TOK_SCONST:
+ /* String constant */
+ SB_AppendStr (T, GetLiteral (CurTok.IVal));
+ ResetLiteralPoolOffs (CurTok.IVal);
+ NextToken ();
+ break;
+
+ default:
+ ConstAbsIntExpr (hie1, &Expr);
+ xsprintf (Buf, sizeof (Buf), "%ld", Expr.IVal);
+ SB_AppendStr (T, Buf);
+ break;
+ }
+}
+
+
+
static void ParseAsm (void)
/* Parse the contents of the ASM statement */
{
- unsigned I;
unsigned Arg;
+ char C;
/* Create a target string buffer */
StrBuf T = AUTO_STRBUF_INITIALIZER;
* %l - Numerical 32 bit value
* %v - Assembler name of a (global) variable
* %o - Stack offset of a (local) variable
+ * %g - Assembler name of a C label
+ * %s - Any argument converted to a string (almost)
* %% - The % sign
*/
- I = 0;
Arg = 0;
- while (I < SB_GetLen (&S)) {
-
- /* Get the next character */
- char C = SB_AtUnchecked (&S, I++);
+ while ((C = SB_Get (&S)) != '\0') {
/* If it is a newline, the current line is ready to go */
if (C == '\n') {
/* Format specifier */
++Arg;
-
- /* Check if we have characters left */
- if (I >= SB_GetLen (&S)) {
- Error ("Error in __asm__ format specifier %u", Arg);
- AsmErrorSkip ();
- goto Done;
- } else {
- C = SB_AtUnchecked (&S, I++);
- switch (C) {
- case 'b': ParseByteArg (&T, Arg); break;
- case 'w': ParseWordArg (&T, Arg); break;
- case 'l': ParseLongArg (&T, Arg); break;
- case 'v': ParseGVarArg (&T, Arg); break;
- case 'o': ParseLVarArg (&T, Arg); break;
- case '%': SB_AppendChar (&T, '%'); break;
- default:
- Error ("Error in __asm__ format specifier %u", Arg);
- AsmErrorSkip ();
- goto Done;
- }
- }
+ C = SB_Get (&S);
+ switch (C) {
+ case '%': SB_AppendChar (&T, '%'); break;
+ case 'b': ParseByteArg (&T, Arg); break;
+ case 'g': ParseLabelArg (&T, Arg); break;
+ case 'l': ParseLongArg (&T, Arg); break;
+ case 'o': ParseLVarArg (&T, Arg); break;
+ case 's': ParseStrArg (&T, Arg); break;
+ case 'v': ParseGVarArg (&T, Arg); break;
+ case 'w': ParseWordArg (&T, Arg); break;
+ default:
+ Error ("Error in __asm__ format specifier %u", Arg);
+ AsmErrorSkip ();
+ goto Done;
+ }
} else {
Done:
/* Call the string buf destructors */
- DoneStrBuf (&S);
- DoneStrBuf (&T);
+ SB_Done (&S);
+ SB_Done (&T);
}
NextToken ();
/* Need left parenthesis */
- ConsumeLParen ();
+ if (!ConsumeLParen ()) {
+ return;
+ }
/* String literal */
if (CurTok.Tok != TOK_SCONST) {