Skip to content

Commit

Permalink
fmt,cxxrtl: support {,PLUS_,SPACE_}MINUS integer formats.
Browse files Browse the repository at this point in the history
The first two were already supported with the `plus` boolean flag.
The third one is a new specifier, which is allocated the ` ` character.
In addition, `MINUS` is now allocated the `-` character, but old format
where there is no `+`, `-`, or `-` in the respective position is also
accepted for compatibility.
  • Loading branch information
whitequark committed Mar 28, 2024
1 parent fce5df3 commit f413a8e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
13 changes: 10 additions & 3 deletions backends/cxxrtl/runtime/cxxrtl/cxxrtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,11 @@ struct fmt_part {
// INTEGER type
unsigned base; // = 10;
bool signed_; // = false;
bool plus; // = false;
enum {
MINUS = 0,
PLUS_MINUS = 1,
SPACE_MINUS = 2,
} sign; // = MINUS;
bool hex_upper; // = false;

// VLOG_TIME type
Expand Down Expand Up @@ -1105,8 +1109,11 @@ struct fmt_part {
buf += '0' + remainder.template trunc<4>().template get<uint8_t>();
xval = quotient;
}
if (negative || plus)
buf += negative ? '-' : '+';
switch (sign) {
case MINUS: buf += negative ? "-" : ""; break;
case PLUS_MINUS: buf += negative ? "-" : "+"; break;
case SPACE_MINUS: buf += negative ? "-" : " "; break;
}
std::reverse(buf.begin(), buf.end());
} else assert(false && "Unsupported base for fmt_part");
break;
Expand Down
41 changes: 29 additions & 12 deletions kernel/fmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,20 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) {
log_assert(false && "Unexpected end in format substitution");

if (part.type == FmtPart::INTEGER) {
if (fmt[i] == '+') {
part.plus = true;
if (fmt[i] == '-') {
part.sign = FmtPart::MINUS;
if (++i == fmt.size())
log_assert(false && "Unexpected end in format substitution");
} else if (fmt[i] == '+') {
part.sign = FmtPart::PLUS_MINUS;
if (++i == fmt.size())
log_assert(false && "Unexpected end in format substitution");
} else if (fmt[i] == ' ') {
part.sign = FmtPart::SPACE_MINUS;
if (++i == fmt.size())
log_assert(false && "Unexpected end in format substitution");
} else {
// also accept no sign character and treat like MINUS for compatibility
}

if (fmt[i] == 'u')
Expand Down Expand Up @@ -204,8 +214,11 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const {
case 16: fmt += part.hex_upper ? 'H' : 'h'; break;
default: log_abort();
}
if (part.plus)
fmt += '+';
switch (part.sign) {
case FmtPart::MINUS: fmt += '-'; break;
case FmtPart::PLUS_MINUS: fmt += '+'; break;
case FmtPart::SPACE_MINUS: fmt += ' '; break;
}
fmt += part.signed_ ? 's' : 'u';
} else if (part.type == FmtPart::STRING) {
fmt += 'c';
Expand Down Expand Up @@ -379,7 +392,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
part.justify = FmtPart::LEFT;
} else if (fmt[i] == '+') {
// always show sign; not in IEEE 1800-2017 or verilator but iverilog has it
part.plus = true;
part.sign = FmtPart::PLUS_MINUS;
} else break;
}
if (i == fmt.size()) {
Expand Down Expand Up @@ -442,7 +455,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
if (part.padding == '\0')
part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' ';

if (part.type == FmtPart::INTEGER && part.base != 10 && part.plus)
if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS)
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);

if (part.type == FmtPart::INTEGER && !has_leading_zero)
Expand Down Expand Up @@ -495,8 +508,8 @@ std::vector<VerilogFmtArg> Fmt::emit_verilog() const
args.push_back(arg);

fmt.str += '%';
if (part.plus)
fmt.str += '+';
if (part.sign == FmtPart::PLUS_MINUS || part.sign == FmtPart::SPACE_MINUS)
fmt.str += '+'; // treat space/minus as plus/minus
if (part.justify == FmtPart::LEFT)
fmt.str += '-';
if (part.width == 0) {
Expand Down Expand Up @@ -553,7 +566,8 @@ std::vector<VerilogFmtArg> Fmt::emit_verilog() const
args.push_back(arg);

fmt.str += '%';
if (part.plus)
log_assert(part.sign == FmtPart::MINUS || part.sign == FmtPart::PLUS_MINUS);
if (part.sign == FmtPart::PLUS_MINUS)
fmt.str += '+';
if (part.justify == FmtPart::LEFT)
fmt.str += '-';
Expand Down Expand Up @@ -620,7 +634,7 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function<void(c
os << part.width << ", ";
os << part.base << ", ";
os << part.signed_ << ", ";
os << part.plus << ", ";
os << part.sign << ", ";
os << part.hex_upper << ", ";
os << part.realtime;
os << " }.render(";
Expand Down Expand Up @@ -718,8 +732,11 @@ std::string Fmt::render() const
buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int();
absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size());
}
if (negative || part.plus)
buf += negative ? '-' : '+';
switch (part.sign) {
case FmtPart::MINUS: buf += negative ? "-" : ""; break;
case FmtPart::PLUS_MINUS: buf += negative ? "-" : "+"; break;
case FmtPart::SPACE_MINUS: buf += negative ? "-" : " "; break;
}
std::reverse(buf.begin(), buf.end());
}
} else log_abort();
Expand Down
6 changes: 5 additions & 1 deletion kernel/fmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ struct FmtPart {
// INTEGER type
unsigned base = 10;
bool signed_ = false;
bool plus = false;
enum {
MINUS = 0,
PLUS_MINUS = 1,
SPACE_MINUS = 2,
} sign = MINUS;
bool hex_upper = false;

// VLOG_TIME type
Expand Down

0 comments on commit f413a8e

Please sign in to comment.