]> git.sur5r.net Git - cc65/blobdiff - src/cc65/asmstmt.c
Since we have now builtin search paths, we need to be able to forget them,
[cc65] / src / cc65 / asmstmt.c
index d680f0b694a004a7d33866517f8dad959b9e7c76..b54771aa9332080baa0b851b1329ca8e379dc771 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/* (C) 2001-2008 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@musoftware.de                                            */
 /*                                                                           */
@@ -39,6 +39,7 @@
 #include "xsprintf.h"
 
 /* cc65 */
+#include "asmlabel.h"
 #include "codegen.h"
 #include "datatype.h"
 #include "error.h"
@@ -46,6 +47,7 @@
 #include "function.h"
 #include "litpool.h"
 #include "scanner.h"
+#include "stackptr.h"
 #include "symtab.h"
 #include "asmstmt.h"
 
@@ -132,23 +134,23 @@ static void ParseByteArg (StrBuf* T, unsigned Arg)
     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);
@@ -166,23 +168,23 @@ static void ParseWordArg (StrBuf* T, unsigned Arg)
     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);
@@ -200,10 +202,10 @@ static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused)))
     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);
@@ -222,8 +224,8 @@ static void ParseGVarArg (StrBuf* T, unsigned Arg)
     }
 
     /* 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);
@@ -265,7 +267,7 @@ static void ParseLVarArg (StrBuf* T, unsigned Arg)
     }
 
     /* 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);
@@ -274,6 +276,31 @@ static void ParseLVarArg (StrBuf* T, unsigned Arg)
 
 
 
+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 */
 {
@@ -300,8 +327,8 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused)))
             break;
 
         default:
-            ConstSubExpr (hie1, InitExprDesc (&Expr));
-            xsprintf (Buf, sizeof (Buf), "%ld", Expr.ConstVal);
+            ConstAbsIntExpr (hie1, &Expr);
+            xsprintf (Buf, sizeof (Buf), "%ld", Expr.IVal);
             SB_AppendStr (T, Buf);
             break;
     }
@@ -339,6 +366,7 @@ static void ParseAsm (void)
      *   %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
      */
@@ -358,13 +386,14 @@ static void ParseAsm (void)
                    ++Arg;
             C = SB_Get (&S);
             switch (C) {
-                case '%':   SB_AppendChar (&T, '%');        break;
-                case 'b':   ParseByteArg (&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;
+                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 ();
@@ -386,8 +415,8 @@ static void ParseAsm (void)
 
 Done:
     /* Call the string buf destructors */
-    DoneStrBuf (&S);
-    DoneStrBuf (&T);
+    SB_Done (&S);
+    SB_Done (&T);
 }