* All types of stuff to support different assemblers.
[fw/sdcc] / src / asm.c
1 #include "common.h"
2 #include "asm.h"
3
4 static hTab *_h;
5
6 static const char *_findMapping(const char *szKey)
7 {
8     return shash_find(_h, szKey);
9 }
10
11 static va_list _iprintf(char *pInto, const char *szFormat, va_list ap)
12 {
13     char *pStart = pInto;
14     char *sz = gc_strdup(szFormat);
15
16     while (*sz) {
17         if (*sz == '%') {
18             switch (*++sz) {
19                 /* See if it's a special emitter */
20             case 'r':
21                 wassert(0);
22                 break;
23             default:
24                 {
25                     /* Scan out the arg and pass it on to sprintf */
26                     char *p = sz-1, tmp;
27                     while (isdigit(*sz))
28                         sz++;
29                     /* Skip the format */
30                     tmp = *++sz;
31                     *sz = '\0';
32                     vsprintf(pInto, p, ap);
33                     /* PENDING: Assume that the arg length was an int */
34                     va_arg(ap, int);
35                     *sz = tmp;
36                 }
37             }
38             pInto = pStart + strlen(pStart);
39         }
40         else {
41             *pInto++ = *sz++;
42         }
43     }
44     *pInto = '\0';
45
46     return ap;
47 }
48
49 void tvsprintf(char *buffer, const char *szFormat, va_list ap)
50 {
51     char *sz = gc_strdup(szFormat);
52     char *pInto = buffer, *p;
53
54     buffer[0] = '\0';
55     
56     while (*sz) {
57         if (*sz == '!') {
58             /* Start of a token.  Search until the first
59                [non alplha, *] and call it a token. */
60             char old;
61             const char *t;
62             p = ++sz;
63             while (isalpha(*sz) || *sz == '*') {
64                 sz++;
65             }
66             old = *sz;
67             *sz = '\0';
68             /* Now find the token in the token list */
69             if ((t = _findMapping(p))) {
70                 ap = _iprintf(pInto, t, ap);
71                 pInto = buffer + strlen(buffer);
72             }
73             else {
74                 fprintf(stderr, "Cant find token \"%s\"\n", p);
75                 wassert(0);
76             }
77             *sz = old;
78         }
79         else if (*sz == '%') {
80             char *pFormat = sz;
81             char old;
82             sz++;
83             while (!isalpha(*sz))
84                 sz++;
85             sz++;
86             old = *sz;
87             *sz = '\0';
88             vsprintf(pInto, pFormat, ap);
89             pInto = buffer + strlen(buffer);
90             *sz = old;
91             va_arg(ap, int);
92         }
93         else {
94             *pInto++ = *sz++;
95         }
96     }
97     *pInto = '\0';
98 }
99
100 void tfprintf(FILE *fp, const char *szFormat, ...)
101 {
102     va_list ap;
103     char buffer[MAX_INLINEASM];
104
105     va_start(ap, szFormat);
106     tvsprintf(buffer, szFormat, ap);
107     fputs(buffer, fp);
108 }
109
110 void tsprintf(char *buffer, const char *szFormat, ...)
111 {
112     va_list ap;
113     va_start(ap, szFormat);
114     tvsprintf(buffer, szFormat, ap);
115 }
116
117 void asm_addTree(const ASM_MAPPINGS *pMappings)
118 {
119     const ASM_MAPPING *pMap;
120     /* Traverse down first */
121     if (pMappings->pParent)
122         asm_addTree(pMappings->pParent);
123     pMap = pMappings->pMappings;
124     while (pMap->szKey && pMap->szValue) {
125         shash_add(&_h, pMap->szKey, pMap->szValue);
126         pMap++;
127     }
128 }
129
130 static const ASM_MAPPING _asxxxx_mapping[] = {
131     { "labeldef", "%s::" },
132     { "tlabeldef", "%05d$:" },
133     { "tlabel", "%05d$" },
134     { "immed", "#" },
135     { "zero", "#0x00" },
136     { "one", "#0x01" },
137     { "area", ".area %s" },
138     { "areacode", ".area %s" },
139     { "areadata", ".area %s" },
140     { "ascii", ".ascii \"%s\"" },
141     { "ds", ".ds %d" },
142     { "db", ".db %d" },
143     { "dbs", ".db %s" },
144     { "dw", ".dw %d" },
145     { "dws", ".dw %s" },
146     { "constbyte", "0x%02X" },
147     { "constword", "0x%04X" },
148     { "immedword", "#0x%04X" },
149     { "immedbyte", "#0x%02X" },
150     { "hashedstr", "#%s" },
151     { "lsbimmeds", "#<%s" },
152     { "msbimmeds", "#>%s" },
153     { "module", ".module %s" },
154     { "global", ".globl %s" },
155     { "fileprelude", "" },
156     { "functionheader", 
157       "; ---------------------------------\n"
158       "; Function %s\n"
159       "; ---------------------------------"
160     },
161     { "functionlabeldef", "%s:" },
162     { NULL, NULL }
163 };
164
165 const ASM_MAPPINGS asm_asxxxx_mapping = {
166     NULL,
167     _asxxxx_mapping
168 };
169