* All types of stuff to support different assemblers.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 5 Apr 2000 01:31:45 +0000 (01:31 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 5 Apr 2000 01:31:45 +0000 (01:31 +0000)
* Added seperate areadata for rgbasm
* Split off mappings, added default asxxxx mapping.

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@218 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCglobl.h
src/SDCCglue.c
src/SDCChasht.c
src/SDCChasht.h
src/asm.c [new file with mode: 0644]
src/asm.h [new file with mode: 0644]
src/avr/main.c
src/mcs51/main.c

index a0b75c2a62d54708254ab5b762bad95f3d99c364..8be1ab06afcd6da688d1a15330c44881f40d11e4 100644 (file)
@@ -249,4 +249,18 @@ void parseWithComma (char **,char *) ;
 */
 FILE *tempfile(void);
 
+/** Creates a duplicate of the string 'sz' a'la strdup but using
+    libgc.
+*/
+char *gc_strdup(const char *sz);
+
+/** An assert() macro that will go out through sdcc's error
+    system.
+*/
+#define wassertl(a,s)  ((a) ? 0 : \
+        (werror (E_INTERNAL_ERROR,__FILE__,__LINE__, s), 0))
+
+#define wassert(a)    wassertl(a,"code generator internal error")
+
+
 #endif
index 151ea6d2ebf0e8c116cb04473435bb3c74e906d3..731e8368159f4deb4b0f9834174d25dd488f99b2 100644 (file)
@@ -140,8 +140,13 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 {
     symbol *sym;
     
-    if (addPublics)
-       tfprintf(map->oFile, "\t!area\n", map->sname);
+    if (addPublics) {
+       /* PENDING: special case here - should remove */
+       if (!strcmp(map->sname, DATA_NAME))
+           tfprintf(map->oFile, "\t!areadata\n", map->sname);
+       else
+           tfprintf(map->oFile, "\t!area\n", map->sname);
+    }
     
     /* print the area name */
     for (sym = setFirstItem (map->syms); sym;
@@ -784,7 +789,7 @@ void createInterruptVect (FILE * vFile)
        return;
     }
     
-    tfprintf(vFile, "\t!area\n", CODE_NAME);
+    tfprintf(vFile, "\t!areacode\n", CODE_NAME);
     fprintf (vFile, "__interrupt_vect:\n");
 
     
@@ -932,7 +937,7 @@ static void emitOverlay(FILE *afile)
                    fprintf(afile,"==.\n");
        
                /* allocate space */
-               tfprintf(afile, "\t!labeldef\n", sym->rname);
+               tfprintf(afile, "!labeldef\n", sym->rname);
                tfprintf(afile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff);
            }
            
@@ -1132,7 +1137,7 @@ void glue ()
     fprintf (asmFile, "%s", iComments2);
     fprintf (asmFile, "; code\n");
     fprintf (asmFile, "%s", iComments2);
-    tfprintf(asmFile, "\t!area\n", port->mem.code_name);
+    tfprintf(asmFile, "\t!areacode\n", CODE_NAME);
     if (mainf && mainf->fbody) {
        
        /* entry point @ start of CSEG */
@@ -1183,3 +1188,11 @@ FILE *tempfile(void)
     }
     return tmpfile();
 }
+
+char *gc_strdup(const char *s)
+{
+    char *ret;
+    ALLOC_ATOMIC(ret, strlen(s)+1);
+    strcpy(ret, s);
+    return ret;
+}
index df23760b376ba87593ec57e077c3ff0b509aa643..1343a762d77e4b64cf38231245877abc276f9cc6 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include <limits.h>
+#include <assert.h>
 #include "SDCChasht.h"
 
-
 #define DEFAULT_HTAB_SIZE 128
 
 /*-----------------------------------------------------------------*/
 /* newHashtItem - creates a new hashtable Item                     */
 /*-----------------------------------------------------------------*/
- hashtItem *newHashtItem (int key, void *item)
+static hashtItem *_newHashtItem (int key, void *pkey, void *item)
 {
     hashtItem *htip;
 
     ALLOC(htip,sizeof(hashtItem));
     
     htip->key = key ;
+    htip->pkey = pkey;
     htip->item = item;
     htip->next = NULL ;
     return htip;
@@ -64,11 +65,8 @@ hTab *newHashTable (int size)
 }
 
 
-/*-----------------------------------------------------------------*/
-/* hTabAddItem - adds an item to the hash table                    */
-/*-----------------------------------------------------------------*/
-void hTabAddItem (hTab **htab, int key, void *item )
-{   
+void hTabAddItemLong(hTab **htab, int key, void *pkey, void *item)
+{
     hashtItem *htip ;
     hashtItem *last ;
 
@@ -92,7 +90,7 @@ void hTabAddItem (hTab **htab, int key, void *item )
        (*htab)->minKey = key ;
 
     /* create the item */
-    htip = newHashtItem (key,item);
+    htip = _newHashtItem(key, pkey, item);
 
     /* if there is a clash then goto end of chain */
     if ((last = (*htab)->table[key])) {
@@ -105,12 +103,20 @@ void hTabAddItem (hTab **htab, int key, void *item )
     (*htab)->nItems++ ;
 }
 
+/*-----------------------------------------------------------------*/
+/* hTabAddItem - adds an item to the hash table                    */
+/*-----------------------------------------------------------------*/
+void hTabAddItem (hTab **htab, int key, void *item )
+{   
+    hTabAddItemLong(htab, key, NULL, item);
+}
+
 /*-----------------------------------------------------------------*/
 /* hTabDeleteItem - either delete an item                          */
 /*-----------------------------------------------------------------*/
 void hTabDeleteItem (hTab **htab, int key ,
-                     void *item, int action ,
-                     int (*compareFunc)(void *,void *))
+                     const void *item, DELETE_ACTION action,
+                     int (*compareFunc)(const void *, const void *))
 {
     hashtItem *htip, **htipp ;
     
@@ -134,7 +140,7 @@ void hTabDeleteItem (hTab **htab, int key ,
         htip = (*htab)->table[key];
         for (; htip; htip = htip->next) {
            
-            if (compareFunc ? (*compareFunc)(item,htip->item) :
+            if (compareFunc ? compareFunc(item,htip->item) :
                (item == htip->item) ) {
                 *htipp=htip->next;
                 break;
@@ -177,7 +183,7 @@ void hTabDeleteAll(hTab * p)
 }
 
 /*-----------------------------------------------------------------*/
-/* hTabClearAll - clear all entries inthe table (does not free)    */
+/* hTabClearAll - clear all entries in the table (does not free)    */
 /*-----------------------------------------------------------------*/
 void hTabClearAll (hTab *htab)
 {
@@ -192,24 +198,91 @@ void hTabClearAll (hTab *htab)
     htab->currKey = htab->nItems = htab->maxKey = 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* hTabIsInTable - will determine if an Item is in the hasht       */
-/*-----------------------------------------------------------------*/
-int hTabIsInTable (hTab *htab, int key, 
-                  void *item , int (*compareFunc)(void *,void *))
+static const hashtItem *_findItem(hTab *htab, int key, void *item, int (*compareFunc)(void *, void *))
 {
-    hashtItem *htip ;
+    hashtItem *htip;
 
     for (htip = htab->table[key] ; htip ; htip = htip->next ) {
        /* if a compare function is given use it */
-       if (compareFunc && (*compareFunc)(item,htip->item))
-           break ;
+       if (compareFunc && compareFunc(item,htip->item))
+           break;
        else
            if (item == htip->item)
                break;
     }
+    return htip;
+}
+
+static const hashtItem *_findByKey(hTab *htab, int key, const void *pkey, int (*compare)(const void *, const void *))
+{
+    hashtItem *htip;
+
+    assert(compare);
+
+    if (!htab)
+       return NULL;
+    
+    for (htip = htab->table[key] ; htip ; htip = htip->next ) {
+       /* if a compare function is given use it */
+       if (compare && compare(pkey, htip->pkey))
+           break;
+       else
+           if (pkey == htip->pkey)
+               break;
+    }
+    return htip;
+}
+
+void *hTabFindByKey(hTab *h, int key, const void *pkey, int (*compare)(const void *, const void *))
+{
+    const hashtItem *item;
+
+    if ((item = _findByKey(h, key, pkey, compare)))
+       return item->item;
+    return NULL;
+}
+
+int hTabDeleteByKey(hTab **h, int key, const void *pkey, int (*compare)(const void *, const void *))
+{
+    hashtItem *htip, **htipp ;
+    
+    if (!(*h))
+        return 0;
+    
+    /* first check if anything exists in the slot */
+    if (! (*h)->table[key] )
+        return 0;
+    
+    /* delete specific item */
+    /* if a compare function is given then use the compare */
+    /* function to find the item, else just compare the items */
+    
+    htipp = &((*h)->table[key]);
+    htip = (*h)->table[key];
+    for (; htip; htip = htip->next) {
+       if (
+           (compare && compare(pkey, htip->pkey)) ||
+           pkey == htip->pkey) {
+           *htipp=htip->next;
+           break;
+       }
+       htipp=&(htip->next);
+    }
+    (*h)->nItems-- ;
+    
+    if (!(*h)->nItems) {
+        *h = NULL;
+    }
+    return 1;
+}
 
-    if ( htip)
+/*-----------------------------------------------------------------*/
+/* hTabIsInTable - will determine if an Item is in the hasht       */
+/*-----------------------------------------------------------------*/
+int hTabIsInTable (hTab *htab, int key, 
+                  void *item , int (*compareFunc)(void *,void *))
+{
+    if (_findItem(htab, key, item, compareFunc))
        return 1;
     return 0;
 }
@@ -368,7 +441,7 @@ hashtItem *hTabSearch (hTab *htab, int key )
 }
 
 /*-----------------------------------------------------------------*/
-/* hTabItemWithKey - returns the first item with the gievn key     */
+/* hTabItemWithKey - returns the first item with the given key     */
 /*-----------------------------------------------------------------*/
 void *hTabItemWithKey (hTab *htab, int key )
 {
@@ -395,3 +468,35 @@ void hTabAddItemIfNotP (hTab **htab, int key, void *item)
 
     hTabAddItem(htab,key,item);
 }
+
+/** Simple implementation of a hash table which uses
+    string (key, value) pairs.  If a key already exists in the
+    table, the newly added value will replace it.
+    This is used for the assembler token table.  The replace existing
+    condition is used to implement inheritance.
+*/
+static int _compare(const void *s1, const void *s2)
+{
+    return !strcmp(s1, s2);
+}
+
+static int _hash(const char *sz)
+{
+    /* Dumb for now */
+    return *sz;
+}
+
+void shash_add(hTab **h, const char *szKey, const char *szValue)
+{
+    int key = _hash(szKey);
+    /* First, delete any that currently exist */
+    hTabDeleteByKey(h, key, szKey, _compare);
+    /* Now add in ours */
+    hTabAddItemLong(h, key, gc_strdup(szKey), gc_strdup(szValue));
+}
+
+const char *shash_find(hTab *h, const char *szKey)
+{
+    int key = _hash(szKey);
+    return (char *)hTabFindByKey(h, key, szKey, _compare);
+}
index cd00908e46572e29a154c79119fa6d03ae98a7b7..2d8536315af684e2d3e70df1d39bb9a04cf0437c 100644 (file)
 /* hashtable item */
 typedef struct hashtItem
 {
-    int key ;
-    void *item ;
+    int key;
+    /* Pointer to the key that was hashed for key.
+       Used for a hash table with unique keys. */
+    void *pkey;
+    void *item;
     struct hashtItem *next ;
 } hashtItem ;
 
@@ -79,11 +82,10 @@ typedef struct hTab
     int nItems ;
 } hTab ;
 
-
-
-enum {
+typedef enum {
     DELETE_CHAIN = 1,
-    DELETE_ITEM };
+    DELETE_ITEM 
+} DELETE_ACTION;
 
 
 /*-----------------------------------------------------------------*/
@@ -92,10 +94,32 @@ enum {
 
 /* hashtable related functions */
 hTab        *newHashTable      (int);
-void         hTabAddItem (hTab **, int , void * );
-void         hTabDeleteItem (hTab **, int  ,
-                                 void *, int  ,
-                                 int (*compareFunc)(void *,void *));
+void         hTabAddItem (hTab **, int key, void *item);
+/** Adds a new item to the hash table.
+    @param h           The hash table to add to
+    @param key         A hashed version of pkey
+    @param pkey                A copy of the key.  Owned by the
+                       hash table after this function.
+    @param item                Value for this key.
+*/
+void        hTabAddItemLong(hTab **h, int key, void *pkey, void *item);
+/** Finds a item by exact key.
+    Searches all items in the key 'key' for a key that
+    according to 'compare' matches pkey.
+    @param h           The hash table to search
+    @param key         A hashed version of pkey.
+    @param pkey                The key to search for
+    @param compare     Returns 0 if pkey == this
+*/
+void *      hTabFindByKey(hTab *h, int key, const void *pkey, int (*compare)(const void *, const void *));
+/** Deletes an item with the exact key 'pkey'
+    @see hTabFindByKey
+*/
+int         hTabDeleteByKey(hTab **h, int key, const void *pkey, int (*compare)(const void *, const void *));
+
+void         hTabDeleteItem (hTab **, int key,
+                            const void *item, DELETE_ACTION action,
+                            int (*compareFunc)(const void *,const void *));
 int          hTabIsInTable (hTab *, int , void * , 
                                 int (*compareFunc)(void *,void *));
 void         *hTabFirstItem (hTab *, int *);
@@ -110,5 +134,14 @@ void        *hTabFirstItemWK (hTab *htab, int wk);
 void        *hTabNextItemWK (hTab *htab );
 void         hTabClearAll (hTab *htab);
 
+/** Find the first item that either is 'item' or which
+    according to 'compareFunc' is the same as item.
+    @param compareFunc         strcmp like compare function, may be null.
+*/
+void *hTabFindItem(hTab *htab, int key, 
+                  void *item, int (*compareFunc)(void *,void *));
+
+void shash_add(hTab **h, const char *szKey, const char *szValue);
+const char *shash_find(hTab *h, const char *szKey);
 
 #endif
diff --git a/src/asm.c b/src/asm.c
new file mode 100644 (file)
index 0000000..998e8f7
--- /dev/null
+++ b/src/asm.c
@@ -0,0 +1,169 @@
+#include "common.h"
+#include "asm.h"
+
+static hTab *_h;
+
+static const char *_findMapping(const char *szKey)
+{
+    return shash_find(_h, szKey);
+}
+
+static va_list _iprintf(char *pInto, const char *szFormat, va_list ap)
+{
+    char *pStart = pInto;
+    char *sz = gc_strdup(szFormat);
+
+    while (*sz) {
+       if (*sz == '%') {
+           switch (*++sz) {
+               /* See if it's a special emitter */
+           case 'r':
+               wassert(0);
+               break;
+           default:
+               {
+                   /* Scan out the arg and pass it on to sprintf */
+                   char *p = sz-1, tmp;
+                   while (isdigit(*sz))
+                       sz++;
+                   /* Skip the format */
+                   tmp = *++sz;
+                   *sz = '\0';
+                   vsprintf(pInto, p, ap);
+                   /* PENDING: Assume that the arg length was an int */
+                   va_arg(ap, int);
+                   *sz = tmp;
+               }
+           }
+           pInto = pStart + strlen(pStart);
+       }
+       else {
+           *pInto++ = *sz++;
+       }
+    }
+    *pInto = '\0';
+
+    return ap;
+}
+
+void tvsprintf(char *buffer, const char *szFormat, va_list ap)
+{
+    char *sz = gc_strdup(szFormat);
+    char *pInto = buffer, *p;
+
+    buffer[0] = '\0';
+    
+    while (*sz) {
+       if (*sz == '!') {
+           /* Start of a token.  Search until the first
+              [non alplha, *] and call it a token. */
+           char old;
+           const char *t;
+           p = ++sz;
+           while (isalpha(*sz) || *sz == '*') {
+               sz++;
+           }
+           old = *sz;
+           *sz = '\0';
+           /* Now find the token in the token list */
+           if ((t = _findMapping(p))) {
+               ap = _iprintf(pInto, t, ap);
+               pInto = buffer + strlen(buffer);
+           }
+           else {
+               fprintf(stderr, "Cant find token \"%s\"\n", p);
+               wassert(0);
+           }
+           *sz = old;
+       }
+       else if (*sz == '%') {
+           char *pFormat = sz;
+           char old;
+           sz++;
+           while (!isalpha(*sz))
+               sz++;
+           sz++;
+           old = *sz;
+           *sz = '\0';
+           vsprintf(pInto, pFormat, ap);
+           pInto = buffer + strlen(buffer);
+           *sz = old;
+           va_arg(ap, int);
+       }
+       else {
+           *pInto++ = *sz++;
+       }
+    }
+    *pInto = '\0';
+}
+
+void tfprintf(FILE *fp, const char *szFormat, ...)
+{
+    va_list ap;
+    char buffer[MAX_INLINEASM];
+
+    va_start(ap, szFormat);
+    tvsprintf(buffer, szFormat, ap);
+    fputs(buffer, fp);
+}
+
+void tsprintf(char *buffer, const char *szFormat, ...)
+{
+    va_list ap;
+    va_start(ap, szFormat);
+    tvsprintf(buffer, szFormat, ap);
+}
+
+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) {
+       shash_add(&_h, pMap->szKey, pMap->szValue);
+       pMap++;
+    }
+}
+
+static const ASM_MAPPING _asxxxx_mapping[] = {
+    { "labeldef", "%s::" },
+    { "tlabeldef", "%05d$:" },
+    { "tlabel", "%05d$" },
+    { "immed", "#" },
+    { "zero", "#0x00" },
+    { "one", "#0x01" },
+    { "area", ".area %s" },
+    { "areacode", ".area %s" },
+    { "areadata", ".area %s" },
+    { "ascii", ".ascii \"%s\"" },
+    { "ds", ".ds %d" },
+    { "db", ".db %d" },
+    { "dbs", ".db %s" },
+    { "dw", ".dw %d" },
+    { "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:" },
+    { NULL, NULL }
+};
+
+const ASM_MAPPINGS asm_asxxxx_mapping = {
+    NULL,
+    _asxxxx_mapping
+};
+
diff --git a/src/asm.h b/src/asm.h
new file mode 100644 (file)
index 0000000..8a75766
--- /dev/null
+++ b/src/asm.h
@@ -0,0 +1,30 @@
+#ifndef ASM_PORT_INCLUDE
+#define ASM_PORT_INCLUDE
+
+void tfprintf(FILE *fp, const char *szFormat, ...);
+void tsprintf(char *buffer, const char *szFormat, ...);
+void tvsprintf(char *buffer, const char *szFormat, va_list ap);
+
+typedef struct {
+    const char *szKey;
+    const char *szValue;
+} ASM_MAPPING;
+
+typedef struct _ASM_MAPPINGS ASM_MAPPINGS;
+
+/* PENDING: could include the peephole rules here as well.
+*/
+struct _ASM_MAPPINGS {
+    const ASM_MAPPINGS *pParent;
+    const ASM_MAPPING *pMappings;
+};
+
+/* The default asxxxx token mapping.
+ */
+extern const ASM_MAPPINGS asm_asxxxx_mapping;
+
+/** Last entry has szKey = NULL.
+ */
+void asm_addTree(const ASM_MAPPINGS *pMappings);
+
+#endif
index 4ec5e617919b72840d40c0d01bf38545623383b2..0bdfbc5533e739efaf9d54af8545e0c5a9e1b767 100644 (file)
@@ -37,6 +37,11 @@ static char *_avr_keywords[] =     {
 
 static int regParmFlg = 0; /* determine if we can register a parameter */
 
+static void _avr_init(void)
+{
+    asm_addTree(&asm_asxxxx_mapping);
+}
+
 static void _avr_reset_regparm()
 {
     regParmFlg = 0;
@@ -174,7 +179,7 @@ PORT avr_port = {
     {
        1
     },
-    NULL,
+    _avr_init,
     _avr_parseOptions,
     _avr_finaliseOptions,
     _avr_setDefaultOptions,
index 6463be1c7c6339f9807b37369ca2ae332c7f77e0..c77535c364bca10daf6e961574b2c1a5563aa6fd 100644 (file)
@@ -46,6 +46,11 @@ void mcs51_assignRegisters (eBBlock **ebbs, int count);
 
 static int regParmFlg = 0; /* determine if we can register a parameter */
 
+static void _mcs51_init(void)
+{
+    asm_addTree(&asm_asxxxx_mapping);
+}
+
 static void _mcs51_reset_regparm()
 {
     regParmFlg = 0;
@@ -231,7 +236,7 @@ PORT mcs51_port = {
     {
        1
     },
-    NULL,
+    _mcs51_init,
     _mcs51_parseOptions,
     _mcs51_finaliseOptions,
     _mcs51_setDefaultOptions,