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;
251 iCodeTable *icTab = getTableEntry (ic->op);
253 dbuf_init (&tmpBuf, 1024);
255 if (INLINEASM == ic->op)
256 dbuf_append (&tmpBuf, "inline", (sizeof "inline") - 1);
259 /* stuff the temporary file with the readable icode */
260 icTab->iCodePrint (&tmpBuf, ic, icTab->printName);
263 len = dbuf_get_length (&tmpBuf);
265 /* null terminate the buffer */
266 dbuf_c_str (&tmpBuf);
267 verbalICode = dbuf_detach (&tmpBuf);
269 /* kill the trailing NL */
270 if (len > 0 && '\n' == verbalICode[len - 1])
271 verbalICode[--len] = '\0';
273 /* and throw it up */
278 /*-----------------------------------------------------------------*/
279 /* skipLine - skip the line from file infp */
280 /*-----------------------------------------------------------------*/
282 skipLine (FILE *infp)
285 static char is_eof = 0;
291 while ((c = getc(infp)) != '\n' && EOF != c)
298 /* EOF in the middle of the line */
309 /*-----------------------------------------------------------------*/
310 /* printCLine - return the c-code for this lineno */
311 /*-----------------------------------------------------------------*/
314 printCLine (const char *srcFile, int lineno)
316 static FILE *inFile = NULL;
317 static struct dbuf_s line;
318 static struct dbuf_s lastSrcFile;
319 static char dbufInitialized = 0;
320 static int inLineNo = 0;
323 if (!dbufInitialized)
325 dbuf_init (&line, 1024);
326 dbuf_init (&lastSrcFile, PATH_MAX);
331 /* empty the dynamic buffer */
332 dbuf_set_length (&line, 0);
337 if (strcmp (dbuf_c_str (&lastSrcFile), srcFile) != 0)
342 dbuf_set_length (&lastSrcFile, 0);
343 dbuf_append_str (&lastSrcFile, srcFile);
349 if (!(inFile = fopen(srcFile, "r")))
351 /* can't open the file:
352 don't panic, just return the error message */
353 dbuf_printf(&line, "ERROR: %s", strerror(errno));
355 return dbuf_c_str (&line);
359 dbuf_set_length (&lastSrcFile, 0);
360 dbuf_append_str (&lastSrcFile, srcFile);
364 if (inLineNo > lineno)
366 /* past the lineno: rewind the file pointer */
372 /* skip lines until lineno */
373 while (inLineNo + 1 < lineno)
375 if (!skipLine (inFile))
381 if (0 != (len = dbuf_getline (&line, inFile)))
383 const char *inLineString = dbuf_c_str (&line);
387 /* remove the trailing NL */
388 if (len > 0 &&'\n' == inLineString[len - 1])
390 dbuf_set_length (&line, --len);
391 inLineString = dbuf_c_str (&line);
394 /* skip leading spaces */
395 while (isspace (*inLineString))
402 dbuf_printf(&line, "ERROR: no line number %d in file %s", lineno, srcFile);
404 return dbuf_c_str (&line);
407 static const ASM_MAPPING _asxxxx_mapping[] =
409 {"labeldef", "%s::"},
410 {"slabeldef", "%s:"},
411 {"tlabeldef", "%05d$:"},
416 {"area", ".area %s"},
417 {"areacode", ".area %s"},
418 {"areadata", ".area %s"},
419 {"areahome", ".area %s"},
420 {"ascii", ".ascii \"%s\""},
426 {"constbyte", "0x%02X"},
427 {"constword", "0x%04X"},
428 {"immedword", "#0x%04X"},
429 {"immedbyte", "#0x%02X"},
430 {"hashedstr", "#%s"},
431 {"lsbimmeds", "#<%s"},
432 {"msbimmeds", "#>%s"},
433 {"module", ".module %s"},
434 {"global", ".globl %s"},
437 "; ---------------------------------\n"
439 "; ---------------------------------"
441 {"functionlabeldef", "%s:"},
442 {"bankimmeds", "0 ; PENDING: bank support"},
443 {"los", "(%s & 0xFF)"},
444 {"his", "(%s >> 8)"},
445 {"hihis", "(%s >> 16)"},
446 {"hihihis", "(%s >> 24)"},
447 {"lod", "(%d & 0xFF)"},
448 {"hid", "(%d >> 8)"},
449 {"hihid", "(%d >> 16)"},
450 {"hihihid", "(%d >> 24)"},
451 {"lol", "(%05d$ & 0xFF)"},
452 {"hil", "(%05d$ >> 8)"},
453 {"hihil", "(%05d$ >> 16)"},
454 {"hihihil", "(%05d$ >> 24)"},
456 {"org", ".org 0x%04X"},
460 static const ASM_MAPPING _gas_mapping[] =
462 {"labeldef", "%s::"},
463 {"slabeldef", "%s:"},
464 {"tlabeldef", "%05d$:"},
469 {"area", ".section %s"},
470 {"areacode", ".section %s"},
471 {"areadata", ".section %s"},
472 {"areahome", ".section %s"},
473 {"ascii", ".ascii \"%s\""},
479 {"constbyte", "0x%02X"},
480 {"constword", "0x%04X"},
481 {"immedword", "#0x%04X"},
482 {"immedbyte", "#0x%02X"},
483 {"hashedstr", "#%s"},
484 {"lsbimmeds", "#<%s"},
485 {"msbimmeds", "#>%s"},
486 {"module", ".file \"%s.c\""},
487 {"global", ".globl %s"},
488 {"extern", ".globl %s"},
491 "; ---------------------------------\n"
493 "; ---------------------------------"
495 {"functionlabeldef", "%s:"},
496 {"bankimmeds", "0 ; PENDING: bank support"},
500 static const ASM_MAPPING _a390_mapping[] =
503 {"slabeldef", "%s:"},
504 {"tlabeldef", "L%05d:"},
509 {"area", "; SECTION NOT SUPPORTED"},
510 {"areacode", "; SECTION NOT SUPPORTED"},
511 {"areadata", "; SECTION NOT SUPPORTED"},
512 {"areahome", "; SECTION NOT SUPPORTED"},
513 {"ascii", "db \"%s\""},
514 {"ds", "; STORAGE NOT SUPPORTED"},
516 {"dbs", "db \"%s\""},
519 {"constbyte", "0%02xh"},
520 {"constword", "0%04xh"},
521 {"immedword", "#0%04Xh"},
522 {"immedbyte", "#0%02Xh"},
523 {"hashedstr", "#%s"},
524 {"lsbimmeds", "#<%s"},
525 {"msbimmeds", "#>%s"},
526 {"module", "; .file \"%s.c\""},
527 {"global", "; .globl %s"},
530 "; ---------------------------------\n"
532 "; ---------------------------------"
534 {"functionlabeldef", "%s:"},
535 {"bankimmeds", "0 ; PENDING: bank support"},
536 {"los", "(%s & 0FFh)"},
537 {"his", "((%s / 256) & 0FFh)"},
538 {"hihis", "((%s / 65536) & 0FFh)"},
539 {"hihihis", "((%s / 16777216) & 0FFh)"},
540 {"lod", "(%d & 0FFh)"},
541 {"hid", "((%d / 256) & 0FFh)"},
542 {"hihid", "((%d / 65536) & 0FFh)"},
543 {"hihihid", "((%d / 16777216) & 0FFh)"},
544 {"lol", "(L%05d & 0FFh)"},
545 {"hil", "((L%05d / 256) & 0FFh)"},
546 {"hihil", "((L%05d / 65536) & 0FFh)"},
547 {"hihihil", "((L%09d / 16777216) & 0FFh)"},
549 {"org", ".org 0x%04X"},
553 static const ASM_MAPPING _xa_asm_mapping[] =
556 {"slabeldef", "%s:"},
557 {"tlabeldef", "L%05d:"},
562 {"area", ".area %s"},
563 {"areacode", ".area %s"},
564 {"areadata", ".area %s"},
565 {"areahome", ".area %s"},
566 {"ascii", ".db \"%s\""},
569 {"dbs", ".db \"%s\""},
572 {"constbyte", "0x%02x"},
573 {"constword", "0x%04x"},
574 {"immedword", "0x%04x"},
575 {"immedbyte", "0x%02x"},
576 {"hashedstr", "#%s"},
577 {"lsbimmeds", "#<%s"},
578 {"msbimmeds", "#>%s"},
579 {"module", "; .module %s"},
580 {"global", ".globl %s"},
583 "; ---------------------------------\n"
585 "; ---------------------------------"
587 {"functionlabeldef", "%s:"},
588 {"bankimmeds", "0 ; PENDING: bank support"},
589 {"los", "(%s & 0FFh)"},
590 {"his", "((%s / 256) & 0FFh)"},
591 {"hihis", "((%s / 65536) & 0FFh)"},
592 {"hihihis", "((%s / 16777216) & 0FFh)"},
593 {"lod", "(%d & 0FFh)"},
594 {"hid", "((%d / 256) & 0FFh)"},
595 {"hihid", "((%d / 65536) & 0FFh)"},
596 {"hihihid", "((%d / 16777216) & 0FFh)"},
597 {"lol", "(L%05d & 0FFh)"},
598 {"hil", "((L%05d / 256) & 0FFh)"},
599 {"hihil", "((L%05d / 65536) & 0FFh)"},
600 {"hihihil", "((L%09d / 16777216) & 0FFh)"},
605 const ASM_MAPPINGS asm_asxxxx_mapping =
611 const ASM_MAPPINGS asm_gas_mapping =
617 const ASM_MAPPINGS asm_a390_mapping =
623 const ASM_MAPPINGS asm_xa_asm_mapping =