From 7101cc7a320f90236345a21d826856dcfc360cf7 Mon Sep 17 00:00:00 2001 From: michaelh Date: Wed, 5 Apr 2000 01:31:45 +0000 Subject: [PATCH] * All types of stuff to support different assemblers. * 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 | 14 ++++ src/SDCCglue.c | 23 +++++-- src/SDCChasht.c | 149 +++++++++++++++++++++++++++++++++++------ src/SDCChasht.h | 53 ++++++++++++--- src/asm.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++ src/asm.h | 30 +++++++++ src/avr/main.c | 7 +- src/mcs51/main.c | 7 +- 8 files changed, 413 insertions(+), 39 deletions(-) create mode 100644 src/asm.c create mode 100644 src/asm.h diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index a0b75c2a..8be1ab06 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -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 diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 151ea6d2..731e8368 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -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; +} diff --git a/src/SDCChasht.c b/src/SDCChasht.c index df23760b..1343a762 100644 --- a/src/SDCChasht.c +++ b/src/SDCChasht.c @@ -25,21 +25,22 @@ #include #include #include +#include #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); +} diff --git a/src/SDCChasht.h b/src/SDCChasht.h index cd00908e..2d853631 100644 --- a/src/SDCChasht.h +++ b/src/SDCChasht.h @@ -62,8 +62,11 @@ /* 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 index 00000000..998e8f76 --- /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 index 00000000..8a75766c --- /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 diff --git a/src/avr/main.c b/src/avr/main.c index 4ec5e617..0bdfbc55 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -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, diff --git a/src/mcs51/main.c b/src/mcs51/main.c index 6463be1c..c77535c3 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -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, -- 2.30.2