1 /*-------------------------------------------------------------------------
2 SDCCasm.c - header file for all types of stuff to support different assemblers.
4 Copyright (C) 2000, Michael Hope <michaelh@juju.net.nz>
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
21 /* Provides output functions that modify the output string
22 based on the input tokens and the assembler token mapping
25 Note that the functions below only handle digit format modifiers.
26 eg %02X is ok, but %lu and %.4u will fail.
28 A 'token' is like !blah or %24f and is under the programmers
34 #include "dbuf_string.h"
39 FileBaseName (const char *fileFullName
)
48 for (p
= fileFullName
+ strlen (fileFullName
) - 1;
49 p
>= fileFullName
&& (*p
!= '/' && *p
!= '\\' && *p
!= ':');
57 dbuf_tvprintf (struct dbuf_s
*dbuf
, const char *format
, va_list ap
)
60 Under Linux PPC va_list is a structure instead of a primitive type,
61 and doesn't like being passed around. This version turns everything
66 %[CIFN] - special formats with no argument (ie list isnt touched)
67 All of the system formats
69 This is acheived by expanding the tokens and zero arg formats into
70 one big format string, which is passed to the native printf.
73 struct dbuf_s tmpDBuf
;
75 const char *sz
= format
;
76 const char *begin
= NULL
;
78 /* First pass: expand all of the macros */
79 dbuf_init (&tmpDBuf
, INITIAL_INLINEASM
);
85 /* Start of a token. Search until the first
86 [non alpha, *] and call it a token. */
92 /* copy what we have until now */
93 dbuf_append (&tmpDBuf
, begin
, sz
- begin
);
97 dbuf_init (&token
, 64);
99 while (isalpha ((unsigned char) *sz
) || *sz
== '*')
101 dbuf_append (&token
, sz
++, 1);
103 /* Now find the token in the token list */
104 if ((t
= shash_find (_h
, dbuf_c_str (&token
))))
106 dbuf_append_str (&tmpDBuf
, t
);
110 /* Token not recognized as a valid macro: macro is not expanded */
111 dbuf_append_char (&tmpDBuf
, '!');
112 dbuf_append (&tmpDBuf
, dbuf_get_buf (&token
), dbuf_get_length (&token
));
114 dbuf_destroy (&token
);
126 /* copy what we have until now */
127 dbuf_append (&tmpDBuf
, begin
, sz
- begin
);
131 /* Second pass: Expand any macros that we own */
132 sz
= noTokens
= dbuf_detach_c_str (&tmpDBuf
);
134 /* recycle tmpDBuf */
135 dbuf_init (&tmpDBuf
, INITIAL_INLINEASM
);
143 /* copy what we have until now */
144 dbuf_append (&tmpDBuf
, begin
, sz
- begin
);
148 // See if its one that we handle.
153 // Code segment name.
154 dbuf_append_str (&tmpDBuf
, CODE_NAME
);
160 dbuf_append_str (&tmpDBuf
, fullSrcFileName
);
165 // Current function name.
166 dbuf_append_str (&tmpDBuf
, currFunc
->rname
);
172 dbuf_printf (&tmpDBuf
, "%u", ++count
);
177 // Not one of ours. Copy until the end.
178 dbuf_append_char (&tmpDBuf
, '%');
179 while (!isalpha ((unsigned char) *sz
))
180 dbuf_append_char (&tmpDBuf
, *sz
++);
182 dbuf_append_char (&tmpDBuf
, *sz
++);
196 /* copy what we have until now */
197 dbuf_append (&tmpDBuf
, begin
, sz
- begin
);
201 dbuf_free (noTokens
);
203 dbuf_vprintf (dbuf
, dbuf_c_str (&tmpDBuf
), ap
);
205 dbuf_destroy (&tmpDBuf
);
209 dbuf_tprintf (struct dbuf_s
*dbuf
, const char *szFormat
, ...)
212 va_start (ap
, szFormat
);
213 dbuf_tvprintf (dbuf
, szFormat
, ap
);
218 tfprintf (FILE *fp
, const char *szFormat
, ...)
223 dbuf_init (&dbuf
, INITIAL_INLINEASM
);
225 va_start (ap
, szFormat
);
226 dbuf_tvprintf (&dbuf
, szFormat
, ap
);
229 fwrite (dbuf_get_buf (&dbuf
), 1, dbuf_get_length (&dbuf
), fp
);
230 dbuf_destroy (&dbuf
);
234 asm_addTree (const ASM_MAPPINGS
* pMappings
)
236 const ASM_MAPPING
*pMap
;
238 /* Traverse down first */
239 if (pMappings
->pParent
)
240 asm_addTree (pMappings
->pParent
);
241 pMap
= pMappings
->pMappings
;
242 while (pMap
->szKey
&& pMap
->szValue
)
244 shash_add (&_h
, pMap
->szKey
, pMap
->szValue
);
249 /*-----------------------------------------------------------------*/
250 /* printILine - return the readable i-code for this ic */
251 /*-----------------------------------------------------------------*/
253 printILine (iCode
* ic
)
255 struct dbuf_s tmpBuf
;
256 iCodeTable
*icTab
= getTableEntry (ic
->op
);
260 dbuf_init (&tmpBuf
, 1024);
262 if (INLINEASM
== ic
->op
)
263 dbuf_append_str (&tmpBuf
, "inline");
266 /* stuff the temporary file with the readable icode */
267 icTab
->iCodePrint (&tmpBuf
, ic
, icTab
->printName
);
270 /* null terminate the buffer */
271 dbuf_chomp (&tmpBuf
);
273 return dbuf_detach_c_str (&tmpBuf
);
276 /*-----------------------------------------------------------------*/
277 /* skipLine - skip the line from file infp */
278 /*-----------------------------------------------------------------*/
280 skipLine (FILE * infp
)
283 static char is_eof
= 0;
289 while ((c
= getc (infp
)) != '\n' && EOF
!= c
)
296 /* EOF in the middle of the line */
307 /*-----------------------------------------------------------------*/
308 /* printCLine - return the c-code for this lineno */
309 /*-----------------------------------------------------------------*/
312 printCLine (const char *srcFile
, int lineno
)
314 static FILE *inFile
= NULL
;
315 static struct dbuf_s line
;
316 static struct dbuf_s lastSrcFile
;
317 static char dbufInitialized
= 0;
318 static int inLineNo
= 0;
321 if (!dbufInitialized
)
323 dbuf_init (&line
, 1024);
324 dbuf_init (&lastSrcFile
, PATH_MAX
);
329 /* empty the dynamic buffer */
330 dbuf_set_length (&line
, 0);
335 if (strcmp (dbuf_c_str (&lastSrcFile
), srcFile
) != 0)
340 dbuf_set_length (&lastSrcFile
, 0);
341 dbuf_append_str (&lastSrcFile
, srcFile
);
347 if (!(inFile
= fopen (srcFile
, "r")))
349 /* can't open the file:
350 don't panic, just return the error message */
351 dbuf_printf (&line
, "ERROR: %s", strerror (errno
));
353 return dbuf_detach_c_str (&line
);
357 dbuf_set_length (&lastSrcFile
, 0);
358 dbuf_append_str (&lastSrcFile
, srcFile
);
362 if (inLineNo
> lineno
)
364 /* past the lineno: rewind the file pointer */
370 /* skip lines until lineno */
371 while (inLineNo
+ 1 < lineno
)
373 if (!skipLine (inFile
))
379 if (0 != (len
= dbuf_getline (&line
, inFile
)))
381 const char *inLineString
;
385 /* remove the trailing NL */
388 inLineString
= dbuf_detach_c_str (&line
);
390 /* skip leading spaces */
391 while (isspace (*inLineString
))
398 dbuf_printf (&line
, "ERROR: no line number %d in file %s", lineno
, srcFile
);
400 return dbuf_detach_c_str (&line
);
403 static const ASM_MAPPING _asxxxx_mapping
[] = {
404 {"labeldef", "%s::"},
405 {"slabeldef", "%s:"},
406 {"tlabeldef", "%05d$:"},
411 {"area", ".area %s"},
412 {"areacode", ".area %s"},
413 {"areadata", ".area %s"},
414 {"areahome", ".area %s"},
415 {"ascii", ".ascii \"%s\""},
421 {"constbyte", "0x%02x"},
422 {"constword", "0x%04x"},
423 {"immedword", "#0x%04x"},
424 {"immedbyte", "#0x%02x"},
425 {"hashedstr", "#%s"},
426 {"lsbimmeds", "#<(%s)"},
427 {"msbimmeds", "#>(%s)"},
428 {"module", ".module %s"},
429 {"global", ".globl %s"},
432 "; ---------------------------------\n"
434 "; ---------------------------------"},
435 {"functionlabeldef", "%s:"},
436 {"globalfunctionlabeldef", "%s::"},
437 {"bankimmeds", "b%s"},
438 {"hashedbankimmeds", "#b%s"},
439 {"los", "(%s & 0xFF)"},
440 {"his", "(%s >> 8)"},
441 {"hihis", "(%s >> 16)"},
442 {"hihihis", "(%s >> 24)"},
443 {"lod", "(%d & 0xFF)"},
444 {"hid", "(%d >> 8)"},
445 {"hihid", "(%d >> 16)"},
446 {"hihihid", "(%d >> 24)"},
447 {"lol", "(%05d$ & 0xFF)"},
448 {"hil", "(%05d$ >> 8)"},
449 {"hihil", "(%05d$ >> 16)"},
450 {"hihihil", "(%05d$ >> 24)"},
452 {"bequ", "b%s = %i"},
453 {"org", ".org 0x%04X"},
457 static const ASM_MAPPING _asxxxx_smallpdk_mapping
[] = {
458 {"labeldef", "%s::"},
459 {"slabeldef", "%s:"},
460 {"tlabeldef", "%05d$:"},
465 {"area", ".area %s"},
466 {"areacode", ".area %s"},
467 {"areadata", ".area %s"},
468 {"areahome", ".area %s"},
469 {"ascii", ".ascii \"%s\""},
475 {"constbyte", "#0x%02x"},
476 {"constword", "0x%04x"},
477 {"immedword", "#0x%04x"},
478 {"immedbyte", "#0x%02x"},
479 {"hashedstr", "#%s"},
480 {"lsbimmeds", "#<(%s)"},
481 {"msbimmeds", "#>(%s)"},
482 {"module", ".module %s"},
483 {"global", ".globl %s"},
486 "; ---------------------------------\n"
488 "; ---------------------------------"},
489 {"functionlabeldef", "%s:"},
490 {"globalfunctionlabeldef", "%s::"},
491 {"bankimmeds", "b%s"},
492 {"hashedbankimmeds", "#b%s"},
493 {"los", "(%s & 0xFF)"},
494 {"his", "(%s >> 8)"},
495 {"hihis", "(%s >> 16)"},
496 {"hihihis", "(%s >> 24)"},
497 {"lod", "(%d & 0xFF)"},
498 {"hid", "(%d >> 8)"},
499 {"hihid", "(%d >> 16)"},
500 {"hihihid", "(%d >> 24)"},
501 {"lol", "(%05d$ & 0xFF)"},
502 {"hil", "(%05d$ >> 8)"},
503 {"hihil", "(%05d$ >> 16)"},
504 {"hihihil", "(%05d$ >> 24)"},
506 {"org", ".org 0x%04X"},
510 static const ASM_MAPPING _gas_mapping
[] = {
512 {"slabeldef", "%s:"},
513 {"tlabeldef", "%05d$:"},
518 {"area", ".section %s"},
519 {"areacode", ".section %s,\"ax\""},
520 {"areadata", ".section %s,\"rw\""},
521 {"areahome", ".section %s,\"ax\""},
522 {"ascii", ".ascii\t\"%s\""},
528 {"constbyte", "0x%02X"},
529 {"constword", "0x%04X"},
530 {"immedword", "#0x%04X"},
531 {"immedbyte", "#0x%02X"},
532 {"hashedstr", "#%s"},
533 {"lsbimmeds", "#<%s"},
534 {"msbimmeds", "#>%s"},
535 {"module", ".file\t\"%s.c\""},
536 {"global", ".globl\t%s"},
537 {"extern", ".extern\t%s"},
540 "; ---------------------------------\n"
542 "; ---------------------------------"},
543 {"functionlabeldef", "%s:"},
544 {"globalfunctionlabeldef", "%s:"},
545 {"bankimmeds", "b%s"},
546 {"hashedbankimmeds", "#b%s"},
547 {"los", "%s & 0xFF"},
549 {"hihis", "%s >> 16"},
550 {"hihihis", "%s >> 24"},
551 {"lod", "%d & 0xFF"},
553 {"hihid", "%d >> 16"},
554 {"hihihid", "%d >> 24"},
555 {"lol", "%05d$ & 0xFF"},
556 {"hil", "%05d$ >> 8"},
557 {"hihil", "%05d$ >> 16"},
558 {"hihihil", "%05d$ >> 24"},
562 static const ASM_MAPPING _a390_mapping
[] = {
564 {"slabeldef", "%s:"},
565 {"tlabeldef", "L%05d:"},
570 {"area", "; SECTION NOT SUPPORTED"},
571 {"areacode", "; SECTION NOT SUPPORTED"},
572 {"areadata", "; SECTION NOT SUPPORTED"},
573 {"areahome", "; SECTION NOT SUPPORTED"},
574 {"ascii", "db \"%s\""},
575 {"ds", "; STORAGE NOT SUPPORTED"},
577 {"dbs", "db \"%s\""},
580 {"constbyte", "0%02xh"},
581 {"constword", "0%04xh"},
582 {"immedword", "#0%04Xh"},
583 {"immedbyte", "#0%02Xh"},
584 {"hashedstr", "#%s"},
585 {"lsbimmeds", "#<%s"},
586 {"msbimmeds", "#>%s"},
587 {"module", "; .file \"%s.c\""},
588 {"global", "; .globl %s"},
591 "; ---------------------------------\n"
593 "; ---------------------------------"},
594 {"functionlabeldef", "%s:"},
595 {"globalfunctionlabeldef", "%s::"},
596 {"bankimmeds", "b%s"},
597 {"hashedbankimmeds", "#b%s"},
598 {"los", "(%s & 0FFh)"},
599 {"his", "((%s / 256) & 0FFh)"},
600 {"hihis", "((%s / 65536) & 0FFh)"},
601 {"hihihis", "((%s / 16777216) & 0FFh)"},
602 {"lod", "(%d & 0FFh)"},
603 {"hid", "((%d / 256) & 0FFh)"},
604 {"hihid", "((%d / 65536) & 0FFh)"},
605 {"hihihid", "((%d / 16777216) & 0FFh)"},
606 {"lol", "(L%05d & 0FFh)"},
607 {"hil", "((L%05d / 256) & 0FFh)"},
608 {"hihil", "((L%05d / 65536) & 0FFh)"},
609 {"hihihil", "((L%09d / 16777216) & 0FFh)"},
611 {"org", ".org 0x%04X"},
615 const ASM_MAPPINGS asm_asxxxx_mapping
= {
620 const ASM_MAPPINGS asm_asxxxx_smallpdk_mapping
= {
622 _asxxxx_smallpdk_mapping
625 const ASM_MAPPINGS asm_gas_mapping
= {
630 const ASM_MAPPINGS asm_a390_mapping
= {