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