*/
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
{
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;
return;
}
- tfprintf(vFile, "\t!area\n", CODE_NAME);
+ tfprintf(vFile, "\t!areacode\n", CODE_NAME);
fprintf (vFile, "__interrupt_vect:\n");
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);
}
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 */
}
return tmpfile();
}
+
+char *gc_strdup(const char *s)
+{
+ char *ret;
+ ALLOC_ATOMIC(ret, strlen(s)+1);
+ strcpy(ret, s);
+ return ret;
+}
#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;
}
-/*-----------------------------------------------------------------*/
-/* 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 ;
(*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])) {
(*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 ;
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;
}
/*-----------------------------------------------------------------*/
-/* hTabClearAll - clear all entries inthe table (does not free) */
+/* hTabClearAll - clear all entries in the table (does not free) */
/*-----------------------------------------------------------------*/
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;
}
}
/*-----------------------------------------------------------------*/
-/* hTabItemWithKey - returns the first item with the gievn key */
+/* hTabItemWithKey - returns the first item with the given key */
/*-----------------------------------------------------------------*/
void *hTabItemWithKey (hTab *htab, int key )
{
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);
+}
/* 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 ;
int nItems ;
} hTab ;
-
-
-enum {
+typedef enum {
DELETE_CHAIN = 1,
- DELETE_ITEM };
+ DELETE_ITEM
+} DELETE_ACTION;
/*-----------------------------------------------------------------*/
/* 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 *);
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
--- /dev/null
+#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
+};
+
--- /dev/null
+#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
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;
{
1
},
- NULL,
+ _avr_init,
_avr_parseOptions,
_avr_finaliseOptions,
_avr_setDefaultOptions,
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;
{
1
},
- NULL,
+ _mcs51_init,
_mcs51_parseOptions,
_mcs51_finaliseOptions,
_mcs51_setDefaultOptions,