/* A 'token' is like !blah or %24f and is under the programmers
control. */
-#define MAX_TOKEN_LEN 64
+#define MAX_TOKEN_LEN 64
static hTab *_h;
while (*fileFullName)
{
if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
- {
- p = fileFullName;
- p++;
- }
+ {
+ p = fileFullName;
+ p++;
+ }
fileFullName++;
}
return p;
return shash_find (_h, szKey);
}
-#if 0
-static void
-_iprintf (char *pInto, const char *sz, va_list * pap)
-{
- char format[MAX_TOKEN_LEN];
- char *pStart = pInto;
- static int count;
-
- while (*sz)
- {
- if (*sz == '%')
- {
- switch (*++sz)
- {
- /* See if it's a special emitter */
- case 'r':
- wassert (0);
- break;
- /* Name of the code segment */
- case 'C':
- strcpy (pInto, CODE_NAME);
- pInto = pStart + strlen (pStart);
- sz++;
- break;
- case 'F':
- strcpy (pInto, srcFileName);
- pInto = pStart + strlen (pStart);
- sz++;
- break;
- case 'I':
- sprintf (pInto, "%u", ++count);
- pInto = pStart + strlen (pStart);
- sz++;
- break;
- default:
- {
- /* Scan out the arg and pass it on to sprintf */
- char *p = format;
- *p++ = '%';
- while (isdigit (*sz))
- *p++ = *sz++;
- *p++ = *sz++;
- *p = '\0';
- vsprintf (pInto, format, *pap);
- /* PENDING: Assume that the arg length was an int */
- (void) va_arg (*pap, int);
- }
- }
- pInto = pStart + strlen (pStart);
- }
- else
- {
- *pInto++ = *sz++;
- }
- }
- *pInto = '\0';
-}
-
-void
-tvsprintf (char *buffer, const char *sz, va_list ap)
-{
- char *pInto = buffer;
- char *p;
- char token[MAX_TOKEN_LEN];
-
- buffer[0] = '\0';
-
- while (*sz)
- {
- if (*sz == '!')
- {
- /* Start of a token. Search until the first
- [non alplha, *] and call it a token. */
- const char *t;
- p = token;
- sz++;
- while (isalpha (*sz) || *sz == '*')
- {
- *p++ = *sz++;
- }
- *p = '\0';
- /* Now find the token in the token list */
- if ((t = _findMapping (token)))
- {
- printf ("tvsprintf: found token \"%s\" to \"%s\"\n", token, t);
- _iprintf (pInto, t, &ap);
- pInto = buffer + strlen (buffer);
- }
- else
- {
- fprintf (stderr, "Cant find token \"%s\"\n", token);
- wassert (0);
- }
- }
- else if (*sz == '%')
- {
- p = token;
- *p++ = *sz++;
- while (!isalpha (*sz))
- {
- *p++ = *sz++;
- }
- *p++ = *sz++;
- *p = '\0';
- vsprintf (pInto, token, ap);
- pInto = buffer + strlen (buffer);
- (void) va_arg (ap, int);
- }
- else
- {
- *pInto++ = *sz++;
- }
- }
- *pInto = '\0';
-}
-#else
// Append a string onto another, and update the pointer to the end of
// the new string.
static char *
-_appendAt (char *at, char *onto, const char *sz)
+_appendAt (char *at, char *onto, const char *sz, size_t *max)
{
wassert (at && onto && sz);
- strcpy (at, sz);
- return at + strlen (sz);
+ strncpyz (at, sz, *max);
+ *max -= strlen (at);
+ return at + strlen (at);
}
-void
-tvsprintf (char *buffer, const char *format, va_list ap)
+void
+tvsprintf (char *buffer, size_t len, const char *format, va_list ap)
{
// Under Linux PPC va_list is a structure instead of a primitive type,
// and doesnt like being passed around. This version turns everything
// Supports:
// !tokens
- // %[CIF] - special formats with no argument (ie list isnt touched)
+ // %[CIFN] - special formats with no argument (ie list isnt touched)
// All of the system formats
// This is acheived by expanding the tokens and zero arg formats into
// one big format string, which is passed to the native printf.
- static int count;
- char newformat[INITIAL_INLINEASM];
- char *pInto = newformat;
- char *p;
- char token[MAX_TOKEN_LEN];
- const char *sz = format;
+ static int count;
+ char noTokens[INITIAL_INLINEASM];
+ char newFormat[INITIAL_INLINEASM];
+ char *pInto = noTokens;
+ size_t pIntoLen = sizeof(noTokens);
+ char *p;
+ char token[MAX_TOKEN_LEN];
+ const char *sz = format;
// NULL terminate it to let strlen work.
*pInto = '\0';
- while (*sz)
+ /* First pass: expand all of the macros */
+ while (pIntoLen && *sz)
{
if (*sz == '!')
- {
- /* Start of a token. Search until the first
- [non alpha, *] and call it a token. */
- const char *t;
- p = token;
- sz++;
- while (isalpha (*sz) || *sz == '*')
- {
- *p++ = *sz++;
- }
- *p = '\0';
- /* Now find the token in the token list */
- if ((t = _findMapping (token)))
- {
- pInto = _appendAt (pInto, newformat, t);
- }
- else
- {
- fprintf (stderr, "Cant find token \"%s\"\n", token);
- wassert (0);
- }
- }
- else if (*sz == '%')
- {
- // See if its one that we handle.
- sz++;
- switch (*sz)
- {
- case 'C':
- // Code segment name.
- pInto = _appendAt (pInto, newformat, CODE_NAME);
- break;
- case 'F':
- // Source file name.
- pInto = _appendAt (pInto, newformat, srcFileName);
- break;
- case 'I':
- {
- // Unique ID.
- char id[20];
- sprintf (id, "%u", ++count);
- pInto = _appendAt (pInto, newformat, id);
- break;
- }
- default:
- // Not one of ours. Copy until the end.
- *pInto++ = '%';
- while (!isalpha (*sz))
- {
- *pInto++ = *sz++;
- }
- *pInto++ = *sz++;
- }
- }
+ {
+ /* Start of a token. Search until the first
+ [non alpha, *] and call it a token. */
+ const char *t;
+ p = token;
+ sz++;
+ while (isalpha ((unsigned char)*sz) || *sz == '*')
+ {
+ *p++ = *sz++;
+ }
+ *p = '\0';
+ /* Now find the token in the token list */
+ if ((t = _findMapping (token)))
+ {
+ pInto = _appendAt (pInto, noTokens, t, &pIntoLen);
+ }
+ else
+ {
+ fprintf (stderr, "Cant find token \"%s\"\n", token);
+ wassert (0);
+ }
+ }
+ else
+ {
+ *pInto++ = *sz++;
+ pIntoLen--;
+ }
+ }
+
+ if (!pIntoLen)
+ {
+ fprintf(stderr,
+ "Internal error: tvsprintf overflowed on pass one.\n");
+ // Might as well go on...
+ }
+
+ *pInto = '\0';
+
+ /* Second pass: Expand any macros that we own */
+ sz = noTokens;
+ pInto = newFormat;
+ pIntoLen = sizeof(newFormat);
+
+ while (pIntoLen && *sz)
+ {
+ if (*sz == '%')
+ {
+ // See if its one that we handle.
+ sz++;
+ switch (*sz)
+ {
+ case 'C':
+ // Code segment name.
+ pInto = _appendAt (pInto, newFormat, CODE_NAME, &pIntoLen);
+ sz++;
+ break;
+ case 'F':
+ // Source file name.
+ pInto = _appendAt (pInto, newFormat, fullSrcFileName, &pIntoLen);
+ sz++;
+ break;
+ case 'N':
+ // Current function name.
+ pInto = _appendAt (pInto, newFormat, currFunc->rname, &pIntoLen);
+ sz++;
+ break;
+ case 'I':
+ {
+ // Unique ID.
+ char id[20];
+ SNPRINTF (id, sizeof(id), "%u", ++count);
+ pInto = _appendAt (pInto, newFormat, id, &pIntoLen);
+ sz++;
+ break;
+ }
+ default:
+ // Not one of ours. Copy until the end.
+ *pInto++ = '%';
+ pIntoLen--;
+ while (pIntoLen && !isalpha ((unsigned char)*sz))
+ {
+ *pInto++ = *sz++;
+ pIntoLen--;
+ }
+ if (pIntoLen)
+ {
+ *pInto++ = *sz++;
+ pIntoLen--;
+ }
+ }
+ }
else
- {
- *pInto++ = *sz++;
- }
+ {
+ *pInto++ = *sz++;
+ pIntoLen--;
+ }
}
+
+ if (!pIntoLen)
+ {
+ fprintf(stderr,
+ "Internal error: tvsprintf overflowed on pass two.\n");
+ // Might as well go on...
+ }
+
*pInto = '\0';
// Now do the actual printing
- vsprintf (buffer, newformat, ap);
-}
+#if defined(HAVE_VSNPRINTF)
+ {
+ int wrlen;
+ wrlen = vsnprintf (buffer, len, newFormat, ap);
+
+ if (wrlen < 0 || (size_t)wrlen >= len)
+ {
+ fprintf(stderr, "Internal error: tvsprintf truncated.\n");
+ }
+ }
+
+#else
+ vsprintf (buffer, newFormat, ap);
+ if (strlen(buffer) >= len)
+ {
+ fprintf(stderr, "Internal error: tvsprintf overflowed.\n");
+ }
#endif
+}
-void
+void
tfprintf (FILE * fp, const char *szFormat,...)
{
va_list ap;
char buffer[INITIAL_INLINEASM];
va_start (ap, szFormat);
- tvsprintf (buffer, szFormat, ap);
+ tvsprintf (buffer, INITIAL_INLINEASM, szFormat, ap);
+ va_end(ap);
fputs (buffer, fp);
}
-void
-tsprintf (char *buffer, const char *szFormat,...)
+void
+tsprintf (char *buffer, size_t len, const char *szFormat,...)
{
va_list ap;
va_start (ap, szFormat);
- tvsprintf (buffer, szFormat, ap);
+ tvsprintf (buffer, len, szFormat, ap);
+ va_end(ap);
}
-void
+void
asm_addTree (const ASM_MAPPINGS * pMappings)
{
const ASM_MAPPING *pMap;
}
}
+/*-----------------------------------------------------------------*/
+/* printILine - return the readable i-code for this ic */
+/* */
+/* iCodePrint wants a file stream so we need a temporary file to */
+/* fool it */
+/*-----------------------------------------------------------------*/
+char *
+printILine (iCode *ic)
+{
+ static char verbalICode[1024];
+ FILE *tmpFile;
+ iCodeTable *icTab=getTableEntry(ic->op);
+ int ret;
+
+ if (INLINEASM == ic->op)
+ return "inline";
+
+ tmpFile = tempfile();
+ assert(NULL != tmpFile);
+ if (NULL == tmpFile)
+ return ""; /* return empty line if temporary file creation failed */
+
+ addSetHead(&tmpfileSet, tmpFile);
+
+ /* stuff the temporary file with the readable icode */
+ icTab->iCodePrint(tmpFile, ic, icTab->printName);
+
+ /* now swallow it */
+ rewind(tmpFile);
+ fgets(verbalICode, sizeof(verbalICode), tmpFile);
+
+ /* clean up the mess, we'll return here for all icodes!!
+ * Actually the temporary file is only closed. It will be
+ * removed by rm_tmpfiles().
+ */
+ ret = fclose(tmpFile);
+ assert(!ret);
+ deleteSetItem(&tmpfileSet, tmpFile);
+
+ /* kill the trailing NL */
+ if ('\n' == verbalICode[strlen(verbalICode) - 1])
+ verbalICode[strlen(verbalICode) - 1] = '\0';
+
+ /* and throw it up */
+ return verbalICode;
+}
+
+/*-----------------------------------------------------------------*/
+/* printCLine - return the c-code for this lineno */
+/*-----------------------------------------------------------------*/
+/* int rewinds=0; */
+char *
+printCLine (char *srcFile, int lineno)
+{
+ static FILE *inFile=NULL;
+ static char inLineString[1024];
+ static int inLineNo=0;
+ static char lastSrcFile[PATH_MAX];
+ char *ilsP=inLineString;
+
+ if (inFile) {
+ if (strcmp (lastSrcFile, srcFile) != 0) {
+ fclose (inFile);
+ inFile = NULL;
+ inLineNo = 0;
+ }
+ }
+ if (!inFile) {
+ inFile=fopen(srcFile, "r");
+ if (!inFile) {
+ perror ("printCLine");
+ exit (1);
+ }
+ strncpyz (lastSrcFile, srcFile, PATH_MAX);
+ }
+ if (lineno<inLineNo) {
+ fseek (inFile, 0, SEEK_SET);
+ inLineNo=0;
+ /* rewinds++; */
+ }
+ while (fgets (inLineString, 1024, inFile)) {
+ inLineNo++;
+ if (inLineNo==lineno) {
+ // remove the trailing NL
+ inLineString[strlen(inLineString)-1]='\0';
+ break;
+ }
+ }
+ while (isspace ((unsigned char)*ilsP))
+ ilsP++;
+
+ return ilsP;
+}
+
static const ASM_MAPPING _asxxxx_mapping[] =
{
{"labeldef", "%s::"},
"; ---------------------------------"
},
{"functionlabeldef", "%s:"},
- {"bankimmeds", "0 ; PENDING: bank support"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {"los","(%s & 0xFF)"},
+ {"his","(%s >> 8)"},
+ {"hihis","(%s >> 16)"},
+ {"hihihis","(%s >> 24)"},
+ {"lod","(%d & 0xFF)"},
+ {"hid","(%d >> 8)"},
+ {"hihid","(%d >> 16)"},
+ {"hihihid","(%d >> 24)"},
+ {"lol","(%05d$ & 0xFF)"},
+ {"hil","(%05d$ >> 8)"},
+ {"hihil","(%05d$ >> 16)"},
+ {"hihihil","(%05d$ >> 24)"},
+ {"equ","="},
+ {"org", ".org %04X"},
{NULL, NULL}
};
{"msbimmeds", "#>%s"},
{"module", ".file \"%s.c\""},
{"global", ".globl %s"},
+ {"extern", ".globl %s"},
{"fileprelude", ""},
{"functionheader",
"; ---------------------------------\n"
"; ---------------------------------"
},
{"functionlabeldef", "%s:"},
- {"bankimmeds", "0 ; PENDING: bank support"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {NULL, NULL}
+};
+
+static const ASM_MAPPING _a390_mapping[] =
+{
+ {"labeldef", "%s:"},
+ {"slabeldef", "%s:"},
+ {"tlabeldef", "L%05d:"},
+ {"tlabel", "L%05d"},
+ {"immed", "#"},
+ {"zero", "#0"},
+ {"one", "#1"},
+ {"area", "; SECTION NOT SUPPORTED"},
+ {"areacode", "; SECTION NOT SUPPORTED"},
+ {"areadata", "; SECTION NOT SUPPORTED"},
+ {"areahome", "; SECTION NOT SUPPORTED"},
+ {"ascii", "db \"%s\""},
+ {"ds", "; STORAGE NOT SUPPORTED"},
+ {"db", "db"},
+ {"dbs", "db \"%s\""},
+ {"dw", "dw"},
+ {"dws", "dw %s"},
+ {"constbyte", "0%02xh"},
+ {"constword", "0%04xh"},
+ {"immedword", "#0%04Xh"},
+ {"immedbyte", "#0%02Xh"},
+ {"hashedstr", "#%s"},
+ {"lsbimmeds", "#<%s"},
+ {"msbimmeds", "#>%s"},
+ {"module", "; .file \"%s.c\""},
+ {"global", "; .globl %s"},
+ {"fileprelude", ""},
+ {"functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ {"functionlabeldef", "%s:"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {"los","(%s & 0FFh)"},
+ {"his","((%s / 256) & 0FFh)"},
+ {"hihis","((%s / 65536) & 0FFh)"},
+ {"hihihis","((%s / 16777216) & 0FFh)"},
+ {"lod","(%d & 0FFh)"},
+ {"hid","((%d / 256) & 0FFh)"},
+ {"hihid","((%d / 65536) & 0FFh)"},
+ {"hihihid","((%d / 16777216) & 0FFh)"},
+ {"lol","(L%05d & 0FFh)"},
+ {"hil","((L%05d / 256) & 0FFh)"},
+ {"hihil","((L%05d / 65536) & 0FFh)"},
+ {"hihihil","((L%09d / 16777216) & 0FFh)"},
+ {"equ"," equ"},
+ {NULL, NULL}
+};
+
+static const ASM_MAPPING _xa_asm_mapping[] =
+{
+ {"labeldef", "%s:"},
+ {"slabeldef", "%s:"},
+ {"tlabeldef", "L%05d:"},
+ {"tlabel", "L%05d"},
+ {"immed", "#"},
+ {"zero", "#0"},
+ {"one", "#1"},
+ {"area", ".area %s"},
+ {"areacode", ".area %s"},
+ {"areadata", ".area %s"},
+ {"areahome", ".area %s"},
+ {"ascii", ".db \"%s\""},
+ {"ds", ".ds %d"},
+ {"db", ".db"},
+ {"dbs", ".db \"%s\""},
+ {"dw", ".dw"},
+ {"dws", ".dw %s"},
+ {"constbyte", "0x%02x"},
+ {"constword", "0x%04x"},
+ {"immedword", "0x%04x"},
+ {"immedbyte", "0x%02x"},
+ {"hashedstr", "#%s"},
+ {"lsbimmeds", "#<%s"},
+ {"msbimmeds", "#>%s"},
+ {"module", "; .module %s"},
+ {"global", ".globl %s"},
+ {"fileprelude", ""},
+ {"functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ {"functionlabeldef", "%s:"},
+ {"bankimmeds", "0 ; PENDING: bank support"},
+ {"los","(%s & 0FFh)"},
+ {"his","((%s / 256) & 0FFh)"},
+ {"hihis","((%s / 65536) & 0FFh)"},
+ {"hihihis","((%s / 16777216) & 0FFh)"},
+ {"lod","(%d & 0FFh)"},
+ {"hid","((%d / 256) & 0FFh)"},
+ {"hihid","((%d / 65536) & 0FFh)"},
+ {"hihihid","((%d / 16777216) & 0FFh)"},
+ {"lol","(L%05d & 0FFh)"},
+ {"hil","((L%05d / 256) & 0FFh)"},
+ {"hihil","((L%05d / 65536) & 0FFh)"},
+ {"hihihil","((L%09d / 16777216) & 0FFh)"},
+ {"equ"," equ"},
{NULL, NULL}
};
NULL,
_gas_mapping
};
+
+const ASM_MAPPINGS asm_a390_mapping =
+{
+ NULL,
+ _a390_mapping
+};
+
+const ASM_MAPPINGS asm_xa_asm_mapping =
+{
+ NULL,
+ _xa_asm_mapping
+};