1 /*-------------------------------------------------------------------------
2 SDCCasm.c - header file for all types of stuff to support different assemblers.
5 Written By - Michael Hope <michaelh@juju.net.nz> 2000
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
26 /* Provides output functions that modify the output string
27 based on the input tokens and the assembler token mapping
30 Note that the functions below only handle digit format modifiers.
31 eg %02X is ok, but %lu and %.4u will fail.
37 #include "dbuf_string.h"
39 /* A 'token' is like !blah or %24f and is under the programmers
45 FileBaseName (char *fileFullName)
47 char *p = fileFullName;
55 if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
66 dbuf_tvprintf (struct dbuf_s *dbuf, const char *format, va_list ap)
68 // Under Linux PPC va_list is a structure instead of a primitive type,
69 // and doesnt like being passed around. This version turns everything
74 // %[CIFN] - special formats with no argument (ie list isnt touched)
75 // All of the system formats
77 // This is acheived by expanding the tokens and zero arg formats into
78 // one big format string, which is passed to the native printf.
80 struct dbuf_s tmpDBuf;
82 const char *sz = format;
84 dbuf_init(&tmpDBuf, INITIAL_INLINEASM);
86 /* First pass: expand all of the macros */
91 /* Start of a token. Search until the first
92 [non alpha, *] and call it a token. */
96 dbuf_init (&token, 64);
98 while (isalpha ((unsigned char)*sz) || *sz == '*')
100 dbuf_append (&token, sz++, 1);
102 /* Now find the token in the token list */
103 if ((t = shash_find (_h, dbuf_c_str(&token))))
105 dbuf_append_str (&tmpDBuf, t);
109 fprintf (stderr, "Cant find token \"%s\"\n", dbuf_c_str(&token));
112 dbuf_destroy (&token);
116 dbuf_append_char (&tmpDBuf, *sz++);
120 /* Second pass: Expand any macros that we own */
121 dbuf_c_str (&tmpDBuf);
122 sz = noTokens = dbuf_detach (&tmpDBuf);
124 /* recycle tmpDBuf */
125 dbuf_init (&tmpDBuf, INITIAL_INLINEASM);
131 // See if its one that we handle.
136 // Code segment name.
137 dbuf_append_str (&tmpDBuf, CODE_NAME);
143 dbuf_append_str (&tmpDBuf, fullSrcFileName);
148 // Current function name.
149 dbuf_append_str (&tmpDBuf, currFunc->rname);
155 dbuf_printf (&tmpDBuf, "%u", ++count);
160 // Not one of ours. Copy until the end.
161 dbuf_append_char (&tmpDBuf, '%');
162 while (!isalpha ((unsigned char)*sz))
163 dbuf_append_char (&tmpDBuf, *sz++);
165 dbuf_append_char (&tmpDBuf, *sz++);
170 dbuf_append_char (&tmpDBuf, *sz++);
174 dbuf_free (noTokens);
176 dbuf_vprintf (dbuf, dbuf_c_str (&tmpDBuf), ap);
178 dbuf_destroy (&tmpDBuf);
182 dbuf_tprintf (struct dbuf_s *dbuf, const char *szFormat,...)
185 va_start (ap, szFormat);
186 dbuf_tvprintf (dbuf, szFormat, ap);
191 tsprintf (char *buffer, size_t len, const char *szFormat,...)
197 dbuf_init (&dbuf, INITIAL_INLINEASM);
199 va_start (ap, szFormat);
200 dbuf_tvprintf (&dbuf, szFormat, ap);
203 copyLen = min (len - 1, dbuf_get_length (&dbuf));
204 memcpy (buffer, dbuf_get_buf (&dbuf), copyLen);
205 buffer[copyLen] = '\0';
206 dbuf_destroy (&dbuf);
210 tfprintf (FILE *fp, const char *szFormat,...)
216 dbuf_init (&dbuf, INITIAL_INLINEASM);
218 va_start (ap, szFormat);
219 dbuf_tvprintf (&dbuf, szFormat, ap);
222 len = dbuf_get_length (&dbuf);
223 fwrite(dbuf_get_buf (&dbuf), 1, len, fp);
224 dbuf_destroy (&dbuf);
228 asm_addTree (const ASM_MAPPINGS *pMappings)
230 const ASM_MAPPING *pMap;
232 /* Traverse down first */
233 if (pMappings->pParent)
234 asm_addTree (pMappings->pParent);
235 pMap = pMappings->pMappings;
236 while (pMap->szKey && pMap->szValue) {
237 shash_add (&_h, pMap->szKey, pMap->szValue);
242 /*-----------------------------------------------------------------*/
243 /* printILine - return the readable i-code for this ic */
244 /*-----------------------------------------------------------------*/
246 printILine (iCode *ic)
249 struct dbuf_s tmpBuf;
250 iCodeTable *icTab = getTableEntry (ic->op);
252 dbuf_init (&tmpBuf, 1024);
254 if (INLINEASM == ic->op)
255 dbuf_append (&tmpBuf, "inline", (sizeof "inline") - 1);
258 /* stuff the temporary file with the readable icode */
259 icTab->iCodePrint (&tmpBuf, ic, icTab->printName);
262 /* null terminate the buffer */
263 dbuf_c_str (&tmpBuf);
264 verbalICode = dbuf_detach (&tmpBuf);
266 /* kill the trailing NL */
267 if ('\n' == verbalICode[strlen(verbalICode) - 1])
268 verbalICode[strlen(verbalICode) - 1] = '\0';
270 /* and throw it up */
275 /*-----------------------------------------------------------------*/
276 /* skipLine - skip the line from file infp */
277 /*-----------------------------------------------------------------*/
279 skipLine (FILE *infp)
283 while ((c = getc(infp)) != '\n' && EOF != c)
289 /*-----------------------------------------------------------------*/
290 /* printCLine - return the c-code for this lineno */
291 /*-----------------------------------------------------------------*/
294 printCLine (const char *srcFile, int lineno)
296 static FILE *inFile = NULL;
297 static struct dbuf_s line;
298 static struct dbuf_s lastSrcFile;
299 static char dbufInitialized = 0;
300 static int inLineNo = 0;
302 if (!dbufInitialized)
304 dbuf_init (&line, 1024);
305 dbuf_init (&lastSrcFile, 1024);
310 /* empty the dynamic buffer */
311 dbuf_set_length (&line, 0);
316 if (strcmp (dbuf_c_str (&lastSrcFile), srcFile) != 0)
321 dbuf_set_length (&lastSrcFile, 0);
322 dbuf_append_str (&lastSrcFile, srcFile);
326 if (!inFile && !(inFile = fopen(srcFile, "r")))
328 /* can't open the file:
329 don't panic, just return the error message */
330 dbuf_printf(&line, "ERROR: %s", strerror(errno));
332 return dbuf_c_str (&line);
336 if (lineno < inLineNo)
338 /* past the lineno: rewind the file pointer */
339 fseek (inFile, 0, SEEK_SET);
344 /* skip lines until lineno */
345 while (inLineNo + 1 < lineno)
347 if (!skipLine (inFile))
352 if (dbuf_getline (&line, inFile))
355 if (inLineNo == lineno)
357 const char *inLineString = dbuf_c_str (&line);
358 size_t len = strlen (inLineString);
360 /* remove the trailing NL */
361 if ('\n' == inLineString[len - 1])
363 dbuf_set_length (&line, len - 1);
364 inLineString = dbuf_c_str (&line);
367 /* skip leading spaces */
368 while (isspace (*inLineString))
376 dbuf_printf(&line, "ERROR: no line number %d in file %s", lineno, srcFile);
378 return dbuf_c_str (&line);
382 static const ASM_MAPPING _asxxxx_mapping[] =
384 {"labeldef", "%s::"},
385 {"slabeldef", "%s:"},
386 {"tlabeldef", "%05d$:"},
391 {"area", ".area %s"},
392 {"areacode", ".area %s"},
393 {"areadata", ".area %s"},
394 {"areahome", ".area %s"},
395 {"ascii", ".ascii \"%s\""},
401 {"constbyte", "0x%02X"},
402 {"constword", "0x%04X"},
403 {"immedword", "#0x%04X"},
404 {"immedbyte", "#0x%02X"},
405 {"hashedstr", "#%s"},
406 {"lsbimmeds", "#<%s"},
407 {"msbimmeds", "#>%s"},
408 {"module", ".module %s"},
409 {"global", ".globl %s"},
412 "; ---------------------------------\n"
414 "; ---------------------------------"
416 {"functionlabeldef", "%s:"},
417 {"bankimmeds", "0 ; PENDING: bank support"},
418 {"los","(%s & 0xFF)"},
420 {"hihis","(%s >> 16)"},
421 {"hihihis","(%s >> 24)"},
422 {"lod","(%d & 0xFF)"},
424 {"hihid","(%d >> 16)"},
425 {"hihihid","(%d >> 24)"},
426 {"lol","(%05d$ & 0xFF)"},
427 {"hil","(%05d$ >> 8)"},
428 {"hihil","(%05d$ >> 16)"},
429 {"hihihil","(%05d$ >> 24)"},
431 {"org", ".org 0x%04X"},
435 static const ASM_MAPPING _gas_mapping[] =
437 {"labeldef", "%s::"},
438 {"slabeldef", "%s:"},
439 {"tlabeldef", "%05d$:"},
444 {"area", ".section %s"},
445 {"areacode", ".section %s"},
446 {"areadata", ".section %s"},
447 {"areahome", ".section %s"},
448 {"ascii", ".ascii \"%s\""},
454 {"constbyte", "0x%02X"},
455 {"constword", "0x%04X"},
456 {"immedword", "#0x%04X"},
457 {"immedbyte", "#0x%02X"},
458 {"hashedstr", "#%s"},
459 {"lsbimmeds", "#<%s"},
460 {"msbimmeds", "#>%s"},
461 {"module", ".file \"%s.c\""},
462 {"global", ".globl %s"},
463 {"extern", ".globl %s"},
466 "; ---------------------------------\n"
468 "; ---------------------------------"
470 {"functionlabeldef", "%s:"},
471 {"bankimmeds", "0 ; PENDING: bank support"},
475 static const ASM_MAPPING _a390_mapping[] =
478 {"slabeldef", "%s:"},
479 {"tlabeldef", "L%05d:"},
484 {"area", "; SECTION NOT SUPPORTED"},
485 {"areacode", "; SECTION NOT SUPPORTED"},
486 {"areadata", "; SECTION NOT SUPPORTED"},
487 {"areahome", "; SECTION NOT SUPPORTED"},
488 {"ascii", "db \"%s\""},
489 {"ds", "; STORAGE NOT SUPPORTED"},
491 {"dbs", "db \"%s\""},
494 {"constbyte", "0%02xh"},
495 {"constword", "0%04xh"},
496 {"immedword", "#0%04Xh"},
497 {"immedbyte", "#0%02Xh"},
498 {"hashedstr", "#%s"},
499 {"lsbimmeds", "#<%s"},
500 {"msbimmeds", "#>%s"},
501 {"module", "; .file \"%s.c\""},
502 {"global", "; .globl %s"},
505 "; ---------------------------------\n"
507 "; ---------------------------------"
509 {"functionlabeldef", "%s:"},
510 {"bankimmeds", "0 ; PENDING: bank support"},
511 {"los","(%s & 0FFh)"},
512 {"his","((%s / 256) & 0FFh)"},
513 {"hihis","((%s / 65536) & 0FFh)"},
514 {"hihihis","((%s / 16777216) & 0FFh)"},
515 {"lod","(%d & 0FFh)"},
516 {"hid","((%d / 256) & 0FFh)"},
517 {"hihid","((%d / 65536) & 0FFh)"},
518 {"hihihid","((%d / 16777216) & 0FFh)"},
519 {"lol","(L%05d & 0FFh)"},
520 {"hil","((L%05d / 256) & 0FFh)"},
521 {"hihil","((L%05d / 65536) & 0FFh)"},
522 {"hihihil","((L%09d / 16777216) & 0FFh)"},
524 {"org", ".org 0x%04X"},
528 static const ASM_MAPPING _xa_asm_mapping[] =
531 {"slabeldef", "%s:"},
532 {"tlabeldef", "L%05d:"},
537 {"area", ".area %s"},
538 {"areacode", ".area %s"},
539 {"areadata", ".area %s"},
540 {"areahome", ".area %s"},
541 {"ascii", ".db \"%s\""},
544 {"dbs", ".db \"%s\""},
547 {"constbyte", "0x%02x"},
548 {"constword", "0x%04x"},
549 {"immedword", "0x%04x"},
550 {"immedbyte", "0x%02x"},
551 {"hashedstr", "#%s"},
552 {"lsbimmeds", "#<%s"},
553 {"msbimmeds", "#>%s"},
554 {"module", "; .module %s"},
555 {"global", ".globl %s"},
558 "; ---------------------------------\n"
560 "; ---------------------------------"
562 {"functionlabeldef", "%s:"},
563 {"bankimmeds", "0 ; PENDING: bank support"},
564 {"los","(%s & 0FFh)"},
565 {"his","((%s / 256) & 0FFh)"},
566 {"hihis","((%s / 65536) & 0FFh)"},
567 {"hihihis","((%s / 16777216) & 0FFh)"},
568 {"lod","(%d & 0FFh)"},
569 {"hid","((%d / 256) & 0FFh)"},
570 {"hihid","((%d / 65536) & 0FFh)"},
571 {"hihihid","((%d / 16777216) & 0FFh)"},
572 {"lol","(L%05d & 0FFh)"},
573 {"hil","((L%05d / 256) & 0FFh)"},
574 {"hihil","((L%05d / 65536) & 0FFh)"},
575 {"hihihil","((L%09d / 16777216) & 0FFh)"},
580 const ASM_MAPPINGS asm_asxxxx_mapping =
586 const ASM_MAPPINGS asm_gas_mapping =
592 const ASM_MAPPINGS asm_a390_mapping =
598 const ASM_MAPPINGS asm_xa_asm_mapping =