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 #if defined __MINGW32__
13 // for O_BINARY in _pipe()
15 #elif !defined(__BORLANDC__) && !defined(_MSC_VER)
20 /* A 'token' is like !blah or %24f and is under the programmers
22 #define MAX_TOKEN_LEN 64
27 FileBaseName (char *fileFullName)
29 char *p = fileFullName;
37 if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
48 _findMapping (const char *szKey)
50 return shash_find (_h, szKey);
53 // Append a string onto another, and update the pointer to the end of
56 _appendAt (char *at, char *onto, const char *sz, size_t *max)
58 wassert (at && onto && sz);
59 strncpyz (at, sz, *max);
61 return at + strlen (at);
65 tvsprintf (char *buffer, size_t len, const char *format, va_list ap)
67 // Under Linux PPC va_list is a structure instead of a primitive type,
68 // and doesnt like being passed around. This version turns everything
73 // %[CIFN] - special formats with no argument (ie list isnt touched)
74 // All of the system formats
76 // This is acheived by expanding the tokens and zero arg formats into
77 // one big format string, which is passed to the native printf.
79 char noTokens[INITIAL_INLINEASM];
80 char newFormat[INITIAL_INLINEASM];
81 char *pInto = noTokens;
82 size_t pIntoLen = sizeof(noTokens);
84 char token[MAX_TOKEN_LEN];
85 const char *sz = format;
87 // NULL terminate it to let strlen work.
90 /* First pass: expand all of the macros */
91 while (pIntoLen && *sz)
95 /* Start of a token. Search until the first
96 [non alpha, *] and call it a token. */
100 while (isalpha (*sz) || *sz == '*')
105 /* Now find the token in the token list */
106 if ((t = _findMapping (token)))
108 pInto = _appendAt (pInto, noTokens, t, &pIntoLen);
112 fprintf (stderr, "Cant find token \"%s\"\n", token);
126 "Internal error: tvsprintf overflowed on pass one.\n");
127 // Might as well go on...
132 /* Second pass: Expand any macros that we own */
135 pIntoLen = sizeof(newFormat);
137 while (pIntoLen && *sz)
141 // See if its one that we handle.
146 // Code segment name.
147 pInto = _appendAt (pInto, newFormat, CODE_NAME, &pIntoLen);
152 pInto = _appendAt (pInto, newFormat, fullSrcFileName, &pIntoLen);
156 // Current function name.
157 pInto = _appendAt (pInto, newFormat, currFunc->rname, &pIntoLen);
164 SNPRINTF (id, sizeof(id), "%u", ++count);
165 pInto = _appendAt (pInto, newFormat, id, &pIntoLen);
170 // Not one of ours. Copy until the end.
173 while (pIntoLen && !isalpha (*sz))
195 "Internal error: tvsprintf overflowed on pass two.\n");
196 // Might as well go on...
201 // Now do the actual printing
202 #if defined(HAVE_VSNPRINTF)
205 wrlen = vsnprintf (buffer, len, newFormat, ap);
207 if (wrlen < 0 || wrlen >= len)
209 fprintf(stderr, "Internal error: tvsprintf truncated.\n");
214 vsprintf (buffer, newFormat, ap);
215 if (strlen(buffer) >= len)
217 fprintf(stderr, "Internal error: tvsprintf overflowed.\n");
223 tfprintf (FILE * fp, const char *szFormat,...)
226 char buffer[INITIAL_INLINEASM];
228 va_start (ap, szFormat);
229 tvsprintf (buffer, INITIAL_INLINEASM, szFormat, ap);
235 tsprintf (char *buffer, size_t len, const char *szFormat,...)
238 va_start (ap, szFormat);
239 tvsprintf (buffer, len, szFormat, ap);
244 asm_addTree (const ASM_MAPPINGS * pMappings)
246 const ASM_MAPPING *pMap;
248 /* Traverse down first */
249 if (pMappings->pParent)
250 asm_addTree (pMappings->pParent);
251 pMap = pMappings->pMappings;
252 while (pMap->szKey && pMap->szValue) {
253 shash_add (&_h, pMap->szKey, pMap->szValue);
258 /*-----------------------------------------------------------------*/
259 /* printILine - return the readable i-code for this ic */
261 /* iCodePrint wants a file stream so we need a pipe to fool it */
262 /*-----------------------------------------------------------------*/
263 static char verbalICode[1024];
265 char *printILine (iCode *ic) {
268 iCodeTable *icTab=getTableEntry(ic->op);
270 #if defined __MINGW32__
271 assert(_pipe(filedes, 256, O_BINARY)!=-1); // forget it
273 assert(pipe(filedes)!=-1); // forget it
276 // stuff the pipe with the readable icode
277 pipeStream=fdopen(filedes[1],"w");
278 icTab->iCodePrint(pipeStream, ic, icTab->printName);
279 // it really needs an extra push
282 pipeStream=fdopen(filedes[0],"r");
283 fgets(verbalICode, sizeof(verbalICode), pipeStream);
284 // clean up the mess, we'll return here for all icodes!!
285 assert(!close (filedes[0]));
286 assert(!close (filedes[1]));
287 // kill the trailing NL
288 verbalICode[strlen(verbalICode)-1]='\0';
293 /*-----------------------------------------------------------------*/
294 /* printCLine - return the c-code for this lineno */
295 /*-----------------------------------------------------------------*/
296 static FILE *inFile=NULL;
297 static char inLineString[1024];
298 static int inLineNo=0;
299 static char lastSrcFile[PATH_MAX];
302 char *printCLine (char *srcFile, int lineno) {
303 char *ilsP=inLineString;
306 if (strcmp (lastSrcFile, srcFile) != 0) {
313 inFile=fopen(srcFile, "r");
315 perror ("printCLine");
318 strncpyz (lastSrcFile, srcFile, PATH_MAX);
320 if (lineno<inLineNo) {
321 fseek (inFile, 0, SEEK_SET);
325 while (fgets (inLineString, 1024, inFile)) {
327 if (inLineNo==lineno) {
328 // remove the trailing NL
329 inLineString[strlen(inLineString)-1]='\0';
333 while (isspace ((int)*ilsP))
339 static const ASM_MAPPING _asxxxx_mapping[] =
341 {"labeldef", "%s::"},
342 {"slabeldef", "%s:"},
343 {"tlabeldef", "%05d$:"},
348 {"area", ".area %s"},
349 {"areacode", ".area %s"},
350 {"areadata", ".area %s"},
351 {"areahome", ".area %s"},
352 {"ascii", ".ascii \"%s\""},
358 {"constbyte", "0x%02X"},
359 {"constword", "0x%04X"},
360 {"immedword", "#0x%04X"},
361 {"immedbyte", "#0x%02X"},
362 {"hashedstr", "#%s"},
363 {"lsbimmeds", "#<%s"},
364 {"msbimmeds", "#>%s"},
365 {"module", ".module %s"},
366 {"global", ".globl %s"},
369 "; ---------------------------------\n"
371 "; ---------------------------------"
373 {"functionlabeldef", "%s:"},
374 {"bankimmeds", "0 ; PENDING: bank support"},
375 {"los","(%s & 0xFF)"},
377 {"hihis","(%s >> 16)"},
378 {"hihihis","(%s >> 24)"},
379 {"lod","(%d & 0xFF)"},
381 {"hihid","(%d >> 16)"},
382 {"hihihid","(%d >> 24)"},
383 {"lol","(%05d$ & 0xFF)"},
384 {"hil","(%05d$ >> 8)"},
385 {"hihil","(%05d$ >> 16)"},
386 {"hihihil","(%05d$ >> 24)"},
391 static const ASM_MAPPING _gas_mapping[] =
393 {"labeldef", "%s::"},
394 {"slabeldef", "%s:"},
395 {"tlabeldef", "%05d$:"},
400 {"area", ".section %s"},
401 {"areacode", ".section %s"},
402 {"areadata", ".section %s"},
403 {"areahome", ".section %s"},
404 {"ascii", ".ascii \"%s\""},
410 {"constbyte", "0x%02X"},
411 {"constword", "0x%04X"},
412 {"immedword", "#0x%04X"},
413 {"immedbyte", "#0x%02X"},
414 {"hashedstr", "#%s"},
415 {"lsbimmeds", "#<%s"},
416 {"msbimmeds", "#>%s"},
417 {"module", ".file \"%s.c\""},
418 {"global", ".globl %s"},
419 {"extern", ".globl %s"},
422 "; ---------------------------------\n"
424 "; ---------------------------------"
426 {"functionlabeldef", "%s:"},
427 {"bankimmeds", "0 ; PENDING: bank support"},
431 static const ASM_MAPPING _a390_mapping[] =
434 {"slabeldef", "%s:"},
435 {"tlabeldef", "L%05d:"},
440 {"area", "; SECTION NOT SUPPORTED"},
441 {"areacode", "; SECTION NOT SUPPORTED"},
442 {"areadata", "; SECTION NOT SUPPORTED"},
443 {"areahome", "; SECTION NOT SUPPORTED"},
444 {"ascii", "db \"%s\""},
445 {"ds", "; STORAGE NOT SUPPORTED"},
447 {"dbs", "db \"%s\""},
450 {"constbyte", "0%02xh"},
451 {"constword", "0%04xh"},
452 {"immedword", "#0%04Xh"},
453 {"immedbyte", "#0%02Xh"},
454 {"hashedstr", "#%s"},
455 {"lsbimmeds", "#<%s"},
456 {"msbimmeds", "#>%s"},
457 {"module", "; .file \"%s.c\""},
458 {"global", "; .globl %s"},
461 "; ---------------------------------\n"
463 "; ---------------------------------"
465 {"functionlabeldef", "%s:"},
466 {"bankimmeds", "0 ; PENDING: bank support"},
467 {"los","(%s & 0FFh)"},
468 {"his","((%s / 256) & 0FFh)"},
469 {"hihis","((%s / 65536) & 0FFh)"},
470 {"hihihis","((%s / 16777216) & 0FFh)"},
471 {"lod","(%d & 0FFh)"},
472 {"hid","((%d / 256) & 0FFh)"},
473 {"hihid","((%d / 65536) & 0FFh)"},
474 {"hihihid","((%d / 16777216) & 0FFh)"},
475 {"lol","(L%05d & 0FFh)"},
476 {"hil","((L%05d / 256) & 0FFh)"},
477 {"hihil","((L%05d / 65536) & 0FFh)"},
478 {"hihihil","((L%09d / 16777216) & 0FFh)"},
483 static const ASM_MAPPING _xa_asm_mapping[] =
486 {"slabeldef", "%s:"},
487 {"tlabeldef", "L%05d:"},
492 {"area", ".area %s"},
493 {"areacode", ".area %s"},
494 {"areadata", ".area %s"},
495 {"areahome", ".area %s"},
496 {"ascii", ".db \"%s\""},
499 {"dbs", ".db \"%s\""},
502 {"constbyte", "0x%02x"},
503 {"constword", "0x%04x"},
504 {"immedword", "0x%04x"},
505 {"immedbyte", "0x%02x"},
506 {"hashedstr", "#%s"},
507 {"lsbimmeds", "#<%s"},
508 {"msbimmeds", "#>%s"},
509 {"module", "; .module %s"},
510 {"global", ".globl %s"},
513 "; ---------------------------------\n"
515 "; ---------------------------------"
517 {"functionlabeldef", "%s:"},
518 {"bankimmeds", "0 ; PENDING: bank support"},
519 {"los","(%s & 0FFh)"},
520 {"his","((%s / 256) & 0FFh)"},
521 {"hihis","((%s / 65536) & 0FFh)"},
522 {"hihihis","((%s / 16777216) & 0FFh)"},
523 {"lod","(%d & 0FFh)"},
524 {"hid","((%d / 256) & 0FFh)"},
525 {"hihid","((%d / 65536) & 0FFh)"},
526 {"hihihid","((%d / 16777216) & 0FFh)"},
527 {"lol","(L%05d & 0FFh)"},
528 {"hil","((L%05d / 256) & 0FFh)"},
529 {"hihil","((L%05d / 65536) & 0FFh)"},
530 {"hihihil","((L%09d / 16777216) & 0FFh)"},
535 const ASM_MAPPINGS asm_asxxxx_mapping =
541 const ASM_MAPPINGS asm_gas_mapping =
547 const ASM_MAPPINGS asm_a390_mapping =
553 const ASM_MAPPINGS asm_xa_asm_mapping =