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.
13 // for O_BINARY in _pipe()
21 /* A 'token' is like !blah or %24f and is under the programmers
23 #define MAX_TOKEN_LEN 64
28 FileBaseName (char *fileFullName)
30 char *p = fileFullName;
38 if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
49 _findMapping (const char *szKey)
51 return shash_find (_h, szKey);
54 // Append a string onto another, and update the pointer to the end of
57 _appendAt (char *at, char *onto, const char *sz, size_t *max)
59 wassert (at && onto && sz);
60 strncpyz (at, sz, *max);
62 return at + strlen (at);
66 tvsprintf (char *buffer, size_t len, 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 char noTokens[INITIAL_INLINEASM];
81 char newFormat[INITIAL_INLINEASM];
82 char *pInto = noTokens;
83 size_t pIntoLen = sizeof(noTokens);
85 char token[MAX_TOKEN_LEN];
86 const char *sz = format;
88 // NULL terminate it to let strlen work.
91 /* First pass: expand all of the macros */
92 while (pIntoLen && *sz)
96 /* Start of a token. Search until the first
97 [non alpha, *] and call it a token. */
101 while (isalpha (*sz) || *sz == '*')
106 /* Now find the token in the token list */
107 if ((t = _findMapping (token)))
109 pInto = _appendAt (pInto, noTokens, t, &pIntoLen);
113 fprintf (stderr, "Cant find token \"%s\"\n", token);
127 "Internal error: tvsprintf overflowed on pass one.\n");
128 // Might as well go on...
133 /* Second pass: Expand any macros that we own */
136 pIntoLen = sizeof(newFormat);
138 while (pIntoLen && *sz)
142 // See if its one that we handle.
147 // Code segment name.
148 pInto = _appendAt (pInto, newFormat, CODE_NAME, &pIntoLen);
153 pInto = _appendAt (pInto, newFormat, fullSrcFileName, &pIntoLen);
157 // Current function name.
158 pInto = _appendAt (pInto, newFormat, currFunc->rname, &pIntoLen);
165 SNPRINTF (id, sizeof(id), "%u", ++count);
166 pInto = _appendAt (pInto, newFormat, id, &pIntoLen);
171 // Not one of ours. Copy until the end.
174 while (pIntoLen && !isalpha (*sz))
196 "Internal error: tvsprintf overflowed on pass two.\n");
197 // Might as well go on...
202 // Now do the actual printing
203 #if defined(HAVE_VSNPRINTF)
206 wrlen = vsnprintf (buffer, len, newFormat, ap);
208 if (wrlen < 0 || wrlen >= len)
210 fprintf(stderr, "Internal error: tvsprintf truncated.\n");
215 vsprintf (buffer, newFormat, ap);
216 if (strlen(buffer) >= len)
218 fprintf(stderr, "Internal error: tvsprintf overflowed.\n");
224 tfprintf (FILE * fp, const char *szFormat,...)
227 char buffer[INITIAL_INLINEASM];
229 va_start (ap, szFormat);
230 tvsprintf (buffer, INITIAL_INLINEASM, szFormat, ap);
236 tsprintf (char *buffer, size_t len, const char *szFormat,...)
239 va_start (ap, szFormat);
240 tvsprintf (buffer, len, szFormat, ap);
245 asm_addTree (const ASM_MAPPINGS * pMappings)
247 const ASM_MAPPING *pMap;
249 /* Traverse down first */
250 if (pMappings->pParent)
251 asm_addTree (pMappings->pParent);
252 pMap = pMappings->pMappings;
253 while (pMap->szKey && pMap->szValue) {
254 shash_add (&_h, pMap->szKey, pMap->szValue);
259 /*-----------------------------------------------------------------*/
260 /* printILine - return the readable i-code for this ic */
262 /* iCodePrint wants a file stream so we need a pipe to fool it */
263 /*-----------------------------------------------------------------*/
264 static char verbalICode[1024];
266 char *printILine (iCode *ic) {
269 iCodeTable *icTab=getTableEntry(ic->op);
273 res = _pipe(filedes, 256, O_BINARY);
277 assert(res != -1); // forget it
279 return ""; // return empty line if pipe creation failed
281 // stuff the pipe with the readable icode
282 pipeStream=fdopen(filedes[1],"w");
283 if (ic->op != INLINEASM)
284 icTab->iCodePrint(pipeStream, ic, icTab->printName);
286 fprintf(pipeStream, "inline\n");
287 // it really needs an extra push
290 pipeStream=fdopen(filedes[0],"r");
291 fgets(verbalICode, sizeof(verbalICode), pipeStream);
292 // clean up the mess, we'll return here for all icodes!!
293 assert(!close (filedes[0]));
294 assert(!close (filedes[1]));
295 // kill the trailing NL
296 verbalICode[strlen(verbalICode)-1]='\0';
301 /*-----------------------------------------------------------------*/
302 /* printCLine - return the c-code for this lineno */
303 /*-----------------------------------------------------------------*/
304 static FILE *inFile=NULL;
305 static char inLineString[1024];
306 static int inLineNo=0;
307 static char lastSrcFile[PATH_MAX];
310 char *printCLine (char *srcFile, int lineno) {
311 char *ilsP=inLineString;
314 if (strcmp (lastSrcFile, srcFile) != 0) {
321 inFile=fopen(srcFile, "r");
323 perror ("printCLine");
326 strncpyz (lastSrcFile, srcFile, PATH_MAX);
328 if (lineno<inLineNo) {
329 fseek (inFile, 0, SEEK_SET);
333 while (fgets (inLineString, 1024, inFile)) {
335 if (inLineNo==lineno) {
336 // remove the trailing NL
337 inLineString[strlen(inLineString)-1]='\0';
341 while (isspace ((int)*ilsP))
347 static const ASM_MAPPING _asxxxx_mapping[] =
349 {"labeldef", "%s::"},
350 {"slabeldef", "%s:"},
351 {"tlabeldef", "%05d$:"},
356 {"area", ".area %s"},
357 {"areacode", ".area %s"},
358 {"areadata", ".area %s"},
359 {"areahome", ".area %s"},
360 {"ascii", ".ascii \"%s\""},
366 {"constbyte", "0x%02X"},
367 {"constword", "0x%04X"},
368 {"immedword", "#0x%04X"},
369 {"immedbyte", "#0x%02X"},
370 {"hashedstr", "#%s"},
371 {"lsbimmeds", "#<%s"},
372 {"msbimmeds", "#>%s"},
373 {"module", ".module %s"},
374 {"global", ".globl %s"},
377 "; ---------------------------------\n"
379 "; ---------------------------------"
381 {"functionlabeldef", "%s:"},
382 {"bankimmeds", "0 ; PENDING: bank support"},
383 {"los","(%s & 0xFF)"},
385 {"hihis","(%s >> 16)"},
386 {"hihihis","(%s >> 24)"},
387 {"lod","(%d & 0xFF)"},
389 {"hihid","(%d >> 16)"},
390 {"hihihid","(%d >> 24)"},
391 {"lol","(%05d$ & 0xFF)"},
392 {"hil","(%05d$ >> 8)"},
393 {"hihil","(%05d$ >> 16)"},
394 {"hihihil","(%05d$ >> 24)"},
399 static const ASM_MAPPING _gas_mapping[] =
401 {"labeldef", "%s::"},
402 {"slabeldef", "%s:"},
403 {"tlabeldef", "%05d$:"},
408 {"area", ".section %s"},
409 {"areacode", ".section %s"},
410 {"areadata", ".section %s"},
411 {"areahome", ".section %s"},
412 {"ascii", ".ascii \"%s\""},
418 {"constbyte", "0x%02X"},
419 {"constword", "0x%04X"},
420 {"immedword", "#0x%04X"},
421 {"immedbyte", "#0x%02X"},
422 {"hashedstr", "#%s"},
423 {"lsbimmeds", "#<%s"},
424 {"msbimmeds", "#>%s"},
425 {"module", ".file \"%s.c\""},
426 {"global", ".globl %s"},
427 {"extern", ".globl %s"},
430 "; ---------------------------------\n"
432 "; ---------------------------------"
434 {"functionlabeldef", "%s:"},
435 {"bankimmeds", "0 ; PENDING: bank support"},
439 static const ASM_MAPPING _a390_mapping[] =
442 {"slabeldef", "%s:"},
443 {"tlabeldef", "L%05d:"},
448 {"area", "; SECTION NOT SUPPORTED"},
449 {"areacode", "; SECTION NOT SUPPORTED"},
450 {"areadata", "; SECTION NOT SUPPORTED"},
451 {"areahome", "; SECTION NOT SUPPORTED"},
452 {"ascii", "db \"%s\""},
453 {"ds", "; STORAGE NOT SUPPORTED"},
455 {"dbs", "db \"%s\""},
458 {"constbyte", "0%02xh"},
459 {"constword", "0%04xh"},
460 {"immedword", "#0%04Xh"},
461 {"immedbyte", "#0%02Xh"},
462 {"hashedstr", "#%s"},
463 {"lsbimmeds", "#<%s"},
464 {"msbimmeds", "#>%s"},
465 {"module", "; .file \"%s.c\""},
466 {"global", "; .globl %s"},
469 "; ---------------------------------\n"
471 "; ---------------------------------"
473 {"functionlabeldef", "%s:"},
474 {"bankimmeds", "0 ; PENDING: bank support"},
475 {"los","(%s & 0FFh)"},
476 {"his","((%s / 256) & 0FFh)"},
477 {"hihis","((%s / 65536) & 0FFh)"},
478 {"hihihis","((%s / 16777216) & 0FFh)"},
479 {"lod","(%d & 0FFh)"},
480 {"hid","((%d / 256) & 0FFh)"},
481 {"hihid","((%d / 65536) & 0FFh)"},
482 {"hihihid","((%d / 16777216) & 0FFh)"},
483 {"lol","(L%05d & 0FFh)"},
484 {"hil","((L%05d / 256) & 0FFh)"},
485 {"hihil","((L%05d / 65536) & 0FFh)"},
486 {"hihihil","((L%09d / 16777216) & 0FFh)"},
491 static const ASM_MAPPING _xa_asm_mapping[] =
494 {"slabeldef", "%s:"},
495 {"tlabeldef", "L%05d:"},
500 {"area", ".area %s"},
501 {"areacode", ".area %s"},
502 {"areadata", ".area %s"},
503 {"areahome", ".area %s"},
504 {"ascii", ".db \"%s\""},
507 {"dbs", ".db \"%s\""},
510 {"constbyte", "0x%02x"},
511 {"constword", "0x%04x"},
512 {"immedword", "0x%04x"},
513 {"immedbyte", "0x%02x"},
514 {"hashedstr", "#%s"},
515 {"lsbimmeds", "#<%s"},
516 {"msbimmeds", "#>%s"},
517 {"module", "; .module %s"},
518 {"global", ".globl %s"},
521 "; ---------------------------------\n"
523 "; ---------------------------------"
525 {"functionlabeldef", "%s:"},
526 {"bankimmeds", "0 ; PENDING: bank support"},
527 {"los","(%s & 0FFh)"},
528 {"his","((%s / 256) & 0FFh)"},
529 {"hihis","((%s / 65536) & 0FFh)"},
530 {"hihihis","((%s / 16777216) & 0FFh)"},
531 {"lod","(%d & 0FFh)"},
532 {"hid","((%d / 256) & 0FFh)"},
533 {"hihid","((%d / 65536) & 0FFh)"},
534 {"hihihid","((%d / 16777216) & 0FFh)"},
535 {"lol","(L%05d & 0FFh)"},
536 {"hil","((L%05d / 256) & 0FFh)"},
537 {"hihil","((L%05d / 65536) & 0FFh)"},
538 {"hihihil","((L%09d / 16777216) & 0FFh)"},
543 const ASM_MAPPINGS asm_asxxxx_mapping =
549 const ASM_MAPPINGS asm_gas_mapping =
555 const ASM_MAPPINGS asm_a390_mapping =
561 const ASM_MAPPINGS asm_xa_asm_mapping =