# See Notices.txt for copyright information
import sys
-from pprint import pprint
from io import StringIO
-from typing import List
+from typing import Any, Dict, List
from soc.decoder.pseudo.pagereader import ISA
from soc.decoder.power_svp64 import SVP64RM
from soc.decoder.power_fields import DecodeFields
from soc.decoder.power_decoder import create_pdecode
+# generated text should wrap at 80 columns
+OUTPUT_WIDTH = 80
+
+
+def wcwidth(text: str) -> int:
+ """ return the number of columns that `text` takes up if printed to a terminal.
+ returns -1 if any characters are not printable.
+ """
+ # TODO: replace with wcwidth from wcwidth
+ # package when we add pip packaging files
+ if text.isprintable():
+ return len(text)
+ return -1
+
+
+class TableEntry:
+ def __init__(self, key: str, value: Any):
+ self.key = repr(key)
+ self.key_lines = self.key.splitlines()
+ for i in range(len(self.key_lines)):
+ self.key_lines[i] = self.key_lines[i].rstrip()
+ self.value = repr(value)
+ self.value_lines = self.value.splitlines()
+ for i in range(len(self.value_lines)):
+ self.value_lines[i] = self.value_lines[i].rstrip()
+ self.width = max(max(map(wcwidth, self.key_lines)),
+ max(map(wcwidth, self.value_lines)))
+
+
+def format_dict_as_tables(d: Dict[str, Any], column_width: int) -> List[str]:
+ entries = [TableEntry(k, v) for k, v in d.items()]
+ entries.sort(key=lambda entry: entry.key)
+ entries.reverse()
+ col_sep_start = '| '
+ col_sep_start_top_line = '+-'
+ col_sep_start_mid_line = '+='
+ col_sep_start_bottom_line = '+-'
+ col_sep_start_width = wcwidth(col_sep_start)
+ col_sep_mid = ' | '
+ col_sep_mid_top_line = '-+-'
+ col_sep_mid_mid_line = '=+='
+ col_sep_mid_bottom_line = '-+-'
+ col_sep_mid_width = wcwidth(col_sep_mid)
+ col_sep_end = ' |'
+ col_sep_end_top_line = '-+'
+ col_sep_end_mid_line = '=+'
+ col_sep_end_bottom_line = '-+'
+ col_sep_end_width = wcwidth(col_sep_end)
+ col_top_line_char = '-'
+ col_mid_line_char = '='
+ col_bottom_line_char = '-'
+ retval: List[str] = []
+ while len(entries) != 0:
+ total_width = col_sep_start_width - col_sep_mid_width
+ column_entries: List[TableEntry] = []
+ key_line_count = 0
+ value_line_count = 0
+ while len(entries) != 0:
+ entry = entries.pop()
+ next_total_width = total_width + col_sep_mid_width
+ next_total_width += entry.width
+ if len(column_entries) != 0 and \
+ next_total_width + col_sep_end_width >= column_width:
+ entries.append(entry)
+ break
+ total_width = next_total_width
+ column_entries.append(entry)
+ key_line_count = max(key_line_count, len(entry.key_lines))
+ value_line_count = max(value_line_count, len(entry.value_lines))
+ top_line = col_sep_start_top_line
+ mid_line = col_sep_start_mid_line
+ bottom_line = col_sep_start_bottom_line
+ key_lines = [col_sep_start] * key_line_count
+ value_lines = [col_sep_start] * value_line_count
+ for i in range(len(column_entries)):
+ last = (i == len(column_entries) - 1)
+ entry = column_entries[i]
+
+ def extend_line(line, entry_text, fill_char,
+ col_sep_mid, col_sep_end):
+ line += entry_text
+ line += fill_char * (entry.width - wcwidth(entry_text))
+ line += col_sep_end if last else col_sep_mid
+ return line
+
+ top_line = extend_line(line=top_line, entry_text='',
+ fill_char=col_top_line_char,
+ col_sep_mid=col_sep_mid_top_line,
+ col_sep_end=col_sep_end_top_line)
+ mid_line = extend_line(line=mid_line, entry_text='',
+ fill_char=col_mid_line_char,
+ col_sep_mid=col_sep_mid_mid_line,
+ col_sep_end=col_sep_end_mid_line)
+ bottom_line = extend_line(line=bottom_line, entry_text='',
+ fill_char=col_bottom_line_char,
+ col_sep_mid=col_sep_mid_bottom_line,
+ col_sep_end=col_sep_end_bottom_line)
+
+ def extend_lines(lines, entry_lines):
+ for j in range(len(lines)):
+ entry_text = ''
+ if j < len(entry_lines):
+ entry_text = entry_lines[j]
+ lines[j] = extend_line(line=lines[j],
+ entry_text=entry_text,
+ fill_char=' ',
+ col_sep_mid=col_sep_mid,
+ col_sep_end=col_sep_end)
+
+ extend_lines(key_lines, entry.key_lines)
+ extend_lines(value_lines, entry.value_lines)
+ retval.append(top_line)
+ retval.extend(key_lines)
+ retval.append(mid_line)
+ retval.extend(value_lines)
+ retval.append(bottom_line)
+ return retval
+
+
class InclusiveRange:
__slots__ = "start", "stop"
yield from visit_subdecoders(decoder.dec)
-def make_opcodes_dict():
+def make_opcodes_dict() -> Dict[str, Dict[str, Any]]:
retval = {}
for subdecoder in subdecoders():
for opcode in subdecoder.opcodes:
else:
assert SV_Ptype == 'P1'
# TODO
- o.write(f"""/// (not yet implemented)
-template <typename... Args>
+ o.write("/// (not yet implemented)\n")
+ instr_without_subdecoder = instr.copy()
+ del instr_without_subdecoder['subdecoder']
+ comment = "/// "
+ for line in format_dict_as_tables(instr_without_subdecoder,
+ OUTPUT_WIDTH - wcwidth(comment)):
+ o.write((comment + line).rstrip() + '\n')
+ o.write(f"""template <typename... Args>
void {function_name}(Args &&...) = delete;
""")
o.write(f"""}} // namespace sv