2 Provides output functions that modify the output string
3 based on the input tokens and the assembler token mapping
6 Note that the functions below only handle digit format modifiers.
7 eg %02X is ok, but %lu and %.4u will fail.
12 /* A 'token' is like !blah or %24f and is under the programmers
14 #define MAX_TOKEN_LEN 64
19 FileBaseName (char *fileFullName)
21 char *p = fileFullName;
29 if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
40 _findMapping (const char *szKey)
42 return shash_find (_h, szKey);
45 // Append a string onto another, and update the pointer to the end of
48 _appendAt (char *at, char *onto, const char *sz, size_t *max)
50 wassert (at && onto && sz);
51 strncpyz (at, sz, *max);
53 return at + strlen (at);
57 tvsprintf (char *buffer, size_t len, const char *format, va_list ap)
59 // Under Linux PPC va_list is a structure instead of a primitive type,
60 // and doesnt like being passed around. This version turns everything
65 // %[CIFN] - special formats with no argument (ie list isnt touched)
66 // All of the system formats
68 // This is acheived by expanding the tokens and zero arg formats into
69 // one big format string, which is passed to the native printf.
71 char noTokens[INITIAL_INLINEASM];
72 char newFormat[INITIAL_INLINEASM];
73 char *pInto = noTokens;
74 size_t pIntoLen = sizeof(noTokens);
76 char token[MAX_TOKEN_LEN];
77 const char *sz = format;
79 // NULL terminate it to let strlen work.
82 /* First pass: expand all of the macros */
83 while (pIntoLen && *sz)
87 /* Start of a token. Search until the first
88 [non alpha, *] and call it a token. */
92 while (isalpha (*sz) || *sz == '*')
97 /* Now find the token in the token list */
98 if ((t = _findMapping (token)))
100 pInto = _appendAt (pInto, noTokens, t, &pIntoLen);
104 fprintf (stderr, "Cant find token \"%s\"\n", token);
118 "Internal error: tvsprintf overflowed on pass one.\n");
119 // Might as well go on...
124 /* Second pass: Expand any macros that we own */
127 pIntoLen = sizeof(newFormat);
129 while (pIntoLen && *sz)
133 // See if its one that we handle.
138 // Code segment name.
139 pInto = _appendAt (pInto, newFormat, CODE_NAME, &pIntoLen);
144 pInto = _appendAt (pInto, newFormat, fullSrcFileName, &pIntoLen);
148 // Current function name.
149 pInto = _appendAt (pInto, newFormat, currFunc->rname, &pIntoLen);
156 SNPRINTF (id, sizeof(id), "%u", ++count);
157 pInto = _appendAt (pInto, newFormat, id, &pIntoLen);
162 // Not one of ours. Copy until the end.
165 while (pIntoLen && !isalpha (*sz))
187 "Internal error: tvsprintf overflowed on pass two.\n");
188 // Might as well go on...
193 // Now do the actual printing
194 #if defined(HAVE_VSNPRINTF)
197 wrlen = vsnprintf (buffer, len, newFormat, ap);
199 if (wrlen < 0 || (size_t)wrlen >= len)
201 fprintf(stderr, "Internal error: tvsprintf truncated.\n");
206 vsprintf (buffer, newFormat, ap);
207 if (strlen(buffer) >= len)
209 fprintf(stderr, "Internal error: tvsprintf overflowed.\n");
215 tfprintf (FILE * fp, const char *szFormat,...)
218 char buffer[INITIAL_INLINEASM];
220 va_start (ap, szFormat);
221 tvsprintf (buffer, INITIAL_INLINEASM, szFormat, ap);
227 tsprintf (char *buffer, size_t len, const char *szFormat,...)
230 va_start (ap, szFormat);
231 tvsprintf (buffer, len, szFormat, ap);
236 asm_addTree (const ASM_MAPPINGS * pMappings)
238 const ASM_MAPPING *pMap;
240 /* Traverse down first */
241 if (pMappings->pParent)
242 asm_addTree (pMappings->pParent);
243 pMap = pMappings->pMappings;
244 while (pMap->szKey && pMap->szValue) {
245 shash_add (&_h, pMap->szKey, pMap->szValue);
250 /*-----------------------------------------------------------------*/
251 /* printILine - return the readable i-code for this ic */
253 /* iCodePrint wants a file stream so we need a temporary file to */
255 /*-----------------------------------------------------------------*/
257 printILine (iCode *ic)
259 static char verbalICode[1024];
261 iCodeTable *icTab=getTableEntry(ic->op);
263 if (INLINEASM == ic->op)
266 tmpFile = tempfile();
267 assert(NULL != tmpFile);
269 return ""; /* return empty line if temporary file creation failed */
271 addSetHead(&tmpfileSet, tmpFile);
273 /* stuff the temporary file with the readable icode */
274 icTab->iCodePrint(tmpFile, ic, icTab->printName);
278 fgets(verbalICode, sizeof(verbalICode), tmpFile);
280 /* clean up the mess, we'll return here for all icodes!!
281 * Actually the temporary file is only closed. It will be
282 * removed by rm_tmpfiles().
284 assert(!fclose(tmpFile));
285 deleteSetItem(&tmpfileSet, tmpFile);
287 /* kill the trailing NL */
288 if ('\n' == verbalICode[strlen(verbalICode) - 1])
289 verbalICode[strlen(verbalICode) - 1] = '\0';
291 /* and throw it up */
295 /*-----------------------------------------------------------------*/
296 /* printCLine - return the c-code for this lineno */
297 /*-----------------------------------------------------------------*/
300 printCLine (char *srcFile, int lineno)
302 static FILE *inFile=NULL;
303 static char inLineString[1024];
304 static int inLineNo=0;
305 static char lastSrcFile[PATH_MAX];
306 char *ilsP=inLineString;
309 if (strcmp (lastSrcFile, srcFile) != 0) {
316 inFile=fopen(srcFile, "r");
318 perror ("printCLine");
321 strncpyz (lastSrcFile, srcFile, PATH_MAX);
323 if (lineno<inLineNo) {
324 fseek (inFile, 0, SEEK_SET);
328 while (fgets (inLineString, 1024, inFile)) {
330 if (inLineNo==lineno) {
331 // remove the trailing NL
332 inLineString[strlen(inLineString)-1]='\0';
336 while (isspace ((int)*ilsP))
342 static const ASM_MAPPING _asxxxx_mapping[] =
344 {"labeldef", "%s::"},
345 {"slabeldef", "%s:"},
346 {"tlabeldef", "%05d$:"},
351 {"area", ".area %s"},
352 {"areacode", ".area %s"},
353 {"areadata", ".area %s"},
354 {"areahome", ".area %s"},
355 {"ascii", ".ascii \"%s\""},
361 {"constbyte", "0x%02X"},
362 {"constword", "0x%04X"},
363 {"immedword", "#0x%04X"},
364 {"immedbyte", "#0x%02X"},
365 {"hashedstr", "#%s"},
366 {"lsbimmeds", "#<%s"},
367 {"msbimmeds", "#>%s"},
368 {"module", ".module %s"},
369 {"global", ".globl %s"},
372 "; ---------------------------------\n"
374 "; ---------------------------------"
376 {"functionlabeldef", "%s:"},
377 {"bankimmeds", "0 ; PENDING: bank support"},
378 {"los","(%s & 0xFF)"},
380 {"hihis","(%s >> 16)"},
381 {"hihihis","(%s >> 24)"},
382 {"lod","(%d & 0xFF)"},
384 {"hihid","(%d >> 16)"},
385 {"hihihid","(%d >> 24)"},
386 {"lol","(%05d$ & 0xFF)"},
387 {"hil","(%05d$ >> 8)"},
388 {"hihil","(%05d$ >> 16)"},
389 {"hihihil","(%05d$ >> 24)"},
394 static const ASM_MAPPING _gas_mapping[] =
396 {"labeldef", "%s::"},
397 {"slabeldef", "%s:"},
398 {"tlabeldef", "%05d$:"},
403 {"area", ".section %s"},
404 {"areacode", ".section %s"},
405 {"areadata", ".section %s"},
406 {"areahome", ".section %s"},
407 {"ascii", ".ascii \"%s\""},
413 {"constbyte", "0x%02X"},
414 {"constword", "0x%04X"},
415 {"immedword", "#0x%04X"},
416 {"immedbyte", "#0x%02X"},
417 {"hashedstr", "#%s"},
418 {"lsbimmeds", "#<%s"},
419 {"msbimmeds", "#>%s"},
420 {"module", ".file \"%s.c\""},
421 {"global", ".globl %s"},
422 {"extern", ".globl %s"},
425 "; ---------------------------------\n"
427 "; ---------------------------------"
429 {"functionlabeldef", "%s:"},
430 {"bankimmeds", "0 ; PENDING: bank support"},
434 static const ASM_MAPPING _a390_mapping[] =
437 {"slabeldef", "%s:"},
438 {"tlabeldef", "L%05d:"},
443 {"area", "; SECTION NOT SUPPORTED"},
444 {"areacode", "; SECTION NOT SUPPORTED"},
445 {"areadata", "; SECTION NOT SUPPORTED"},
446 {"areahome", "; SECTION NOT SUPPORTED"},
447 {"ascii", "db \"%s\""},
448 {"ds", "; STORAGE NOT SUPPORTED"},
450 {"dbs", "db \"%s\""},
453 {"constbyte", "0%02xh"},
454 {"constword", "0%04xh"},
455 {"immedword", "#0%04Xh"},
456 {"immedbyte", "#0%02Xh"},
457 {"hashedstr", "#%s"},
458 {"lsbimmeds", "#<%s"},
459 {"msbimmeds", "#>%s"},
460 {"module", "; .file \"%s.c\""},
461 {"global", "; .globl %s"},
464 "; ---------------------------------\n"
466 "; ---------------------------------"
468 {"functionlabeldef", "%s:"},
469 {"bankimmeds", "0 ; PENDING: bank support"},
470 {"los","(%s & 0FFh)"},
471 {"his","((%s / 256) & 0FFh)"},
472 {"hihis","((%s / 65536) & 0FFh)"},
473 {"hihihis","((%s / 16777216) & 0FFh)"},
474 {"lod","(%d & 0FFh)"},
475 {"hid","((%d / 256) & 0FFh)"},
476 {"hihid","((%d / 65536) & 0FFh)"},
477 {"hihihid","((%d / 16777216) & 0FFh)"},
478 {"lol","(L%05d & 0FFh)"},
479 {"hil","((L%05d / 256) & 0FFh)"},
480 {"hihil","((L%05d / 65536) & 0FFh)"},
481 {"hihihil","((L%09d / 16777216) & 0FFh)"},
486 static const ASM_MAPPING _xa_asm_mapping[] =
489 {"slabeldef", "%s:"},
490 {"tlabeldef", "L%05d:"},
495 {"area", ".area %s"},
496 {"areacode", ".area %s"},
497 {"areadata", ".area %s"},
498 {"areahome", ".area %s"},
499 {"ascii", ".db \"%s\""},
502 {"dbs", ".db \"%s\""},
505 {"constbyte", "0x%02x"},
506 {"constword", "0x%04x"},
507 {"immedword", "0x%04x"},
508 {"immedbyte", "0x%02x"},
509 {"hashedstr", "#%s"},
510 {"lsbimmeds", "#<%s"},
511 {"msbimmeds", "#>%s"},
512 {"module", "; .module %s"},
513 {"global", ".globl %s"},
516 "; ---------------------------------\n"
518 "; ---------------------------------"
520 {"functionlabeldef", "%s:"},
521 {"bankimmeds", "0 ; PENDING: bank support"},
522 {"los","(%s & 0FFh)"},
523 {"his","((%s / 256) & 0FFh)"},
524 {"hihis","((%s / 65536) & 0FFh)"},
525 {"hihihis","((%s / 16777216) & 0FFh)"},
526 {"lod","(%d & 0FFh)"},
527 {"hid","((%d / 256) & 0FFh)"},
528 {"hihid","((%d / 65536) & 0FFh)"},
529 {"hihihid","((%d / 16777216) & 0FFh)"},
530 {"lol","(L%05d & 0FFh)"},
531 {"hil","((L%05d / 256) & 0FFh)"},
532 {"hihil","((L%05d / 65536) & 0FFh)"},
533 {"hihihil","((L%09d / 16777216) & 0FFh)"},
538 const ASM_MAPPINGS asm_asxxxx_mapping =
544 const ASM_MAPPINGS asm_gas_mapping =
550 const ASM_MAPPINGS asm_a390_mapping =
556 const ASM_MAPPINGS asm_xa_asm_mapping =