change docdir to share/sdcc/doc
[fw/sdcc] / src / asm.c
index 8d92b3778410c9d4654ce3e58964112a585e599a..d31b0ea154e871dc96b071ae33243d187be0c732 100644 (file)
--- a/src/asm.c
+++ b/src/asm.c
@@ -20,6 +20,10 @@ FileBaseName (char *fileFullName)
 {
   char *p = fileFullName;
 
+  if (!fileFullName) {
+    return "unknown";
+  }
+
   while (*fileFullName)
     {
       if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
@@ -38,122 +42,6 @@ _findMapping (const char *szKey)
   return shash_find (_h, szKey);
 }
 
-#if 0
-static void 
-_iprintf (char *pInto, const char *sz, va_list * pap)
-{
-  char format[MAX_TOKEN_LEN];
-  char *pStart = pInto;
-  static int count;
-
-  while (*sz)
-    {
-      if (*sz == '%')
-       {
-         switch (*++sz)
-           {
-             /* See if it's a special emitter */
-           case 'r':
-             wassert (0);
-             break;
-             /* Name of the code segment */
-           case 'C':
-             strcpy (pInto, CODE_NAME);
-             pInto = pStart + strlen (pStart);
-             sz++;
-             break;
-           case 'F':
-             strcpy (pInto, srcFileName);
-             pInto = pStart + strlen (pStart);
-             sz++;
-             break;
-           case 'I':
-             sprintf (pInto, "%u", ++count);
-             pInto = pStart + strlen (pStart);
-             sz++;
-             break;
-           default:
-             {
-               /* Scan out the arg and pass it on to sprintf */
-               char *p = format;
-               *p++ = '%';
-               while (isdigit (*sz))
-                 *p++ = *sz++;
-               *p++ = *sz++;
-               *p = '\0';
-               vsprintf (pInto, format, *pap);
-               /* PENDING: Assume that the arg length was an int */
-               (void) va_arg (*pap, int);
-             }
-           }
-         pInto = pStart + strlen (pStart);
-       }
-      else
-       {
-         *pInto++ = *sz++;
-       }
-    }
-  *pInto = '\0';
-}
-
-void 
-tvsprintf (char *buffer, const char *sz, va_list ap)
-{
-  char *pInto = buffer;
-  char *p;
-  char token[MAX_TOKEN_LEN];
-
-  buffer[0] = '\0';
-
-  while (*sz)
-    {
-      if (*sz == '!')
-       {
-         /* Start of a token.  Search until the first
-            [non alplha, *] and call it a token. */
-         const char *t;
-         p = token;
-         sz++;
-         while (isalpha (*sz) || *sz == '*')
-           {
-             *p++ = *sz++;
-           }
-         *p = '\0';
-         /* Now find the token in the token list */
-         if ((t = _findMapping (token)))
-           {
-             printf ("tvsprintf: found token \"%s\" to \"%s\"\n", token, t);
-             _iprintf (pInto, t, &ap);
-             pInto = buffer + strlen (buffer);
-           }
-         else
-           {
-             fprintf (stderr, "Cant find token \"%s\"\n", token);
-             wassert (0);
-           }
-       }
-      else if (*sz == '%')
-       {
-         p = token;
-         *p++ = *sz++;
-         while (!isalpha (*sz))
-           {
-             *p++ = *sz++;
-           }
-         *p++ = *sz++;
-         *p = '\0';
-         vsprintf (pInto, token, ap);
-         pInto = buffer + strlen (buffer);
-         (void) va_arg (ap, int);
-       }
-      else
-       {
-         *pInto++ = *sz++;
-       }
-    }
-  *pInto = '\0';
-}
-#else
 // Append a string onto another, and update the pointer to the end of
 // the new string.
 static char *
@@ -173,14 +61,15 @@ tvsprintf (char *buffer, const char *format, va_list ap)
 
   // Supports:
   //  !tokens
-  //  %[CIF] - special formats with no argument (ie list isnt touched)
+  //  %[CIFN] - special formats with no argument (ie list isnt touched)
   //  All of the system formats
 
   // This is acheived by expanding the tokens and zero arg formats into
   // one big format string, which is passed to the native printf.
   static int count;
-  char newformat[MAX_INLINEASM];
-  char *pInto = newformat;
+  char noTokens[INITIAL_INLINEASM];
+  char newFormat[INITIAL_INLINEASM];
+  char *pInto = noTokens;
   char *p;
   char token[MAX_TOKEN_LEN];
   const char *sz = format;
@@ -188,6 +77,7 @@ tvsprintf (char *buffer, const char *format, va_list ap)
   // NULL terminate it to let strlen work.
   *pInto = '\0';
 
+  /* First pass: expand all of the macros */
   while (*sz)
     {
       if (*sz == '!')
@@ -205,7 +95,7 @@ tvsprintf (char *buffer, const char *format, va_list ap)
          /* Now find the token in the token list */
          if ((t = _findMapping (token)))
            {
-             pInto = _appendAt (pInto, newformat, t);
+             pInto = _appendAt (pInto, noTokens, t);
            }
          else
            {
@@ -213,7 +103,21 @@ tvsprintf (char *buffer, const char *format, va_list ap)
              wassert (0);
            }
        }
-      else if (*sz == '%')
+      else
+        {
+          *pInto++ = *sz++;
+        }
+    }
+
+  *pInto = '\0';
+
+  /* Second pass: Expand any macros that we own */
+  sz = noTokens;
+  pInto = newFormat;
+
+  while (*sz)
+    {
+      if (*sz == '%')
        {
          // See if its one that we handle.
          sz++;
@@ -221,18 +125,26 @@ tvsprintf (char *buffer, const char *format, va_list ap)
            {
            case 'C':
              // Code segment name.
-             pInto = _appendAt (pInto, newformat, CODE_NAME);
+             pInto = _appendAt (pInto, newFormat, CODE_NAME);
+              sz++;
              break;
            case 'F':
              // Source file name.
-             pInto = _appendAt (pInto, newformat, srcFileName);
+             pInto = _appendAt (pInto, newFormat, fullSrcFileName);
+              sz++;
              break;
+            case 'N':
+              // Current function name.
+              pInto = _appendAt (pInto, newFormat, currFunc->rname);
+              sz++;
+              break;
            case 'I':
              {
                // Unique ID.
                char id[20];
                sprintf (id, "%u", ++count);
-               pInto = _appendAt (pInto, newformat, id);
+               pInto = _appendAt (pInto, newFormat, id);
+                sz++;
                break;
              }
            default:
@@ -250,18 +162,18 @@ tvsprintf (char *buffer, const char *format, va_list ap)
          *pInto++ = *sz++;
        }
     }
+
   *pInto = '\0';
 
   // Now do the actual printing
-  vsprintf (buffer, newformat, ap);
+  vsprintf (buffer, newFormat, ap);
 }
-#endif
 
 void 
 tfprintf (FILE * fp, const char *szFormat,...)
 {
   va_list ap;
-  char buffer[MAX_INLINEASM];
+  char buffer[INITIAL_INLINEASM];
 
   va_start (ap, szFormat);
   tvsprintf (buffer, szFormat, ap);
@@ -280,15 +192,61 @@ void
 asm_addTree (const ASM_MAPPINGS * pMappings)
 {
   const ASM_MAPPING *pMap;
+
   /* Traverse down first */
   if (pMappings->pParent)
     asm_addTree (pMappings->pParent);
   pMap = pMappings->pMappings;
-  while (pMap->szKey && pMap->szValue)
-    {
+  while (pMap->szKey && pMap->szValue) {
       shash_add (&_h, pMap->szKey, pMap->szValue);
       pMap++;
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* printCLine - try to find the c-code for this lineno             */
+/*-----------------------------------------------------------------*/
+static FILE *inFile=NULL;
+static char inLineString[1024];
+static int inLineNo=0;
+static char lastSrcFile[PATH_MAX];
+int rewinds=0;
+
+char *printCLine (char *srcFile, int lineno) {
+  char *ilsP=inLineString;
+
+  if (inFile) {
+    if (strcmp (lastSrcFile, srcFile) != 0) {
+      fclose (inFile);
+      inFile = NULL;
+      inLineNo = 0;
     }
+  }
+  if (!inFile) {
+    inFile=fopen(srcFile, "r");
+    if (!inFile) {
+      perror ("printCLine");
+      exit (1);
+    }
+    strcpy (lastSrcFile, srcFile);
+  }
+  if (lineno<inLineNo) {
+    fseek (inFile, 0, SEEK_SET);
+    inLineNo=0;
+    rewinds++;
+  }
+  while (fgets (inLineString, 1024, inFile)) {
+    inLineNo++;
+    if (inLineNo==lineno) {
+      // remove the trailing NL
+      inLineString[strlen(inLineString)-1]='\0';
+      break;
+    }
+  }
+  while (isspace ((int)*ilsP))
+    ilsP++;
+
+  return ilsP;
 }
 
 static const ASM_MAPPING _asxxxx_mapping[] =
@@ -327,6 +285,163 @@ static const ASM_MAPPING _asxxxx_mapping[] =
   },
   {"functionlabeldef", "%s:"},
   {"bankimmeds", "0    ; PENDING: bank support"},
+  {"los","(%s & 0xFF)"},
+  {"his","(%s >> 8)"},
+  {"hihis","(%s >> 16)"},
+  {"hihihis","(%s >> 24)"},
+  {"lod","(%d & 0xFF)"},
+  {"hid","(%d >> 8)"},
+  {"hihid","(%d >> 16)"},
+  {"hihihid","(%d >> 24)"},
+  {"lol","(%05d$ & 0xFF)"},
+  {"hil","(%05d$ >> 8)"},
+  {"hihil","(%05d$ >> 16)"},
+  {"hihihil","(%05d$ >> 24)"},
+  {"equ","="},
+  {NULL, NULL}
+};
+
+static const ASM_MAPPING _gas_mapping[] =
+{
+  {"labeldef", "%s::"},
+  {"slabeldef", "%s:"},
+  {"tlabeldef", "%05d$:"},
+  {"tlabel", "%05d$"},
+  {"immed", "#"},
+  {"zero", "#0x00"},
+  {"one", "#0x01"},
+  {"area", ".section %s"},
+  {"areacode", ".section %s"},
+  {"areadata", ".section %s"},
+  {"areahome", ".section %s"},
+  {"ascii", ".ascii \"%s\""},
+  {"ds", ".ds %d"},
+  {"db", ".db"},
+  {"dbs", ".db %s"},
+  {"dw", ".dw"},
+  {"dws", ".dw %s"},
+  {"constbyte", "0x%02X"},
+  {"constword", "0x%04X"},
+  {"immedword", "#0x%04X"},
+  {"immedbyte", "#0x%02X"},
+  {"hashedstr", "#%s"},
+  {"lsbimmeds", "#<%s"},
+  {"msbimmeds", "#>%s"},
+  {"module", ".file \"%s.c\""},
+  {"global", ".globl %s"},
+  {"extern", ".globl %s"},
+  {"fileprelude", ""},
+  {"functionheader",
+   "; ---------------------------------\n"
+   "; Function %s\n"
+   "; ---------------------------------"
+  },
+  {"functionlabeldef", "%s:"},
+  {"bankimmeds", "0    ; PENDING: bank support"},  
+  {NULL, NULL}
+};
+
+static const ASM_MAPPING _a390_mapping[] =
+{
+  {"labeldef", "%s:"},
+  {"slabeldef", "%s:"},
+  {"tlabeldef", "L%05d:"},
+  {"tlabel", "L%05d"},
+  {"immed", "#"},
+  {"zero", "#0"},
+  {"one", "#1"},
+  {"area", "; SECTION NOT SUPPORTED"},
+  {"areacode", "; SECTION NOT SUPPORTED"},
+  {"areadata", "; SECTION NOT SUPPORTED"},
+  {"areahome", "; SECTION NOT SUPPORTED"},
+  {"ascii", "db \"%s\""},
+  {"ds", "; STORAGE NOT SUPPORTED"},
+  {"db", "db"},
+  {"dbs", "db \"%s\""},
+  {"dw", "dw"},
+  {"dws", "dw %s"},
+  {"constbyte", "0%02xh"},
+  {"constword", "0%04xh"},
+  {"immedword", "#0%04Xh"},
+  {"immedbyte", "#0%02Xh"},
+  {"hashedstr", "#%s"},
+  {"lsbimmeds", "#<%s"},
+  {"msbimmeds", "#>%s"},
+  {"module", "; .file \"%s.c\""},
+  {"global", "; .globl %s"},
+  {"fileprelude", ""},
+  {"functionheader",
+   "; ---------------------------------\n"
+   "; Function %s\n"
+   "; ---------------------------------"
+  },
+  {"functionlabeldef", "%s:"},
+  {"bankimmeds", "0    ; PENDING: bank support"},  
+  {"los","(%s & 0FFh)"},
+  {"his","((%s / 256) & 0FFh)"},
+  {"hihis","((%s / 65536) & 0FFh)"},
+  {"hihihis","((%s / 16777216) & 0FFh)"},
+  {"lod","(%d & 0FFh)"},
+  {"hid","((%d / 256) & 0FFh)"},
+  {"hihid","((%d / 65536) & 0FFh)"},
+  {"hihihid","((%d / 16777216) & 0FFh)"},
+  {"lol","(L%05d & 0FFh)"},
+  {"hil","((L%05d / 256) & 0FFh)"},
+  {"hihil","((L%05d / 65536) & 0FFh)"},
+  {"hihihil","((L%09d / 16777216) & 0FFh)"},
+  {"equ"," equ"},
+  {NULL, NULL}
+};
+
+static const ASM_MAPPING _xa_asm_mapping[] =
+{
+  {"labeldef", "%s:"},
+  {"slabeldef", "%s:"},
+  {"tlabeldef", "L%05d:"},
+  {"tlabel", "L%05d"},
+  {"immed", "#"},
+  {"zero", "#0"},
+  {"one", "#1"},
+  {"area", ".area %s"},
+  {"areacode", ".area %s"},
+  {"areadata", ".area %s"},
+  {"areahome", ".area %s"},
+  {"ascii", ".db \"%s\""},
+  {"ds", ".ds %d"},
+  {"db", ".db"},
+  {"dbs", ".db \"%s\""},
+  {"dw", ".dw"},
+  {"dws", ".dw %s"},
+  {"constbyte", "0x%02x"},
+  {"constword", "0x%04x"},
+  {"immedword", "0x%04x"},
+  {"immedbyte", "0x%02x"},
+  {"hashedstr", "#%s"},
+  {"lsbimmeds", "#<%s"},
+  {"msbimmeds", "#>%s"},
+  {"module", "; .module %s"},
+  {"global", ".globl %s"},
+  {"fileprelude", ""},
+  {"functionheader",
+   "; ---------------------------------\n"
+   "; Function %s\n"
+   "; ---------------------------------"
+  },
+  {"functionlabeldef", "%s:"},
+  {"bankimmeds", "0    ; PENDING: bank support"},  
+  {"los","(%s & 0FFh)"},
+  {"his","((%s / 256) & 0FFh)"},
+  {"hihis","((%s / 65536) & 0FFh)"},
+  {"hihihis","((%s / 16777216) & 0FFh)"},
+  {"lod","(%d & 0FFh)"},
+  {"hid","((%d / 256) & 0FFh)"},
+  {"hihid","((%d / 65536) & 0FFh)"},
+  {"hihihid","((%d / 16777216) & 0FFh)"},
+  {"lol","(L%05d & 0FFh)"},
+  {"hil","((L%05d / 256) & 0FFh)"},
+  {"hihil","((L%05d / 65536) & 0FFh)"},
+  {"hihihil","((L%09d / 16777216) & 0FFh)"},
+  {"equ"," equ"},
   {NULL, NULL}
 };
 
@@ -335,3 +450,21 @@ const ASM_MAPPINGS asm_asxxxx_mapping =
   NULL,
   _asxxxx_mapping
 };
+
+const ASM_MAPPINGS asm_gas_mapping =
+{
+  NULL,
+  _gas_mapping
+};
+
+const ASM_MAPPINGS asm_a390_mapping =
+{
+  NULL,
+  _a390_mapping
+};
+
+const ASM_MAPPINGS asm_xa_asm_mapping =
+{
+  NULL,
+  _xa_asm_mapping
+};