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