tgt-vlog95: Don't strip leading null-bytes from string literals

When a string literal is used in a context where it needs to be wider than
it is it will get left-padded with null-bytes. When the vlog95 backend
emits the string literal it will strip the leading null-bytes as it results
in much more legible code.

Unfortunately there are some corner cases where this results in a change of
behavior of the generated code compared to the original. E.g. if the
context that caused the width expansion has been removed by optimization.
`$display(0 ? "Yes" : "No")` should print " No" due to width expansion, but
when running through the vlog95 backend it will print "No".

Another scenario where there is a change in behavior is when a null byte
was explicitly added at the front of a string literal. E.g. $bits("\000ab")
should print 24, but will print 16 when running through the vlog95 backend.

To mitigate this remove the stripping of the leading null-bytes from the
vlog95 backend. This results in slightly less legible code being generated
in some cases, but makes sure that the code is always correct.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2023-01-02 11:55:26 -08:00
parent 3cfbd7345f
commit 2e12e47a2b
1 changed files with 2 additions and 6 deletions

View File

@ -346,13 +346,9 @@ static void remove_two_chars(char* str)
void emit_string(const char* string)
{
char *buffer = strdup(string);
char *bptr = buffer;
char *cptr;
fprintf(vlog_out, "\"");
/* Prune any leading escaped NULL bytes. */
while ((bptr[0] == '\\') && (bptr[1] == '0') &&
(bptr[2] == '0') && (bptr[3] == '0')) bptr += 4;
for (cptr = bptr; *cptr; cptr += 1) {
for (cptr = buffer; *cptr; cptr += 1) {
if (*cptr == '\\') {
/* Replace any \011 with \t */
if ((cptr[1] == '0') && (cptr[2] == '1') &&
@ -381,7 +377,7 @@ void emit_string(const char* string)
} else cptr += 3;
}
}
if (*bptr) fprintf(vlog_out, "%s", bptr);
if (*buffer) fprintf(vlog_out, "%s", buffer);
free(buffer);
fprintf(vlog_out, "\"");
}