From a448e97b0dac3da08e455c0a7b29f517c6a4ebcf Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 12 Mar 2021 16:55:57 -0800 Subject: [PATCH] generating setvl function works --- .clang-format | 47 ++++++++++++++++++++ .gitignore | 1 + Makefile | 24 +++++++--- generate_headers.py | 106 +++++++++++++++++++++++++++++++++++--------- 4 files changed, 151 insertions(+), 27 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..05b61e6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,47 @@ +--- +Language: Cpp +BasedOnStyle: Google +AccessModifierOffset: -4 +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +PointerAlignment: Right +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: Never +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never +... diff --git a/.gitignore b/.gitignore index 9b867a9..d17f11a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ # See Notices.txt for copyright information /.cache /.vscode +/include/simplev_cpp_generated.h \ No newline at end of file diff --git a/Makefile b/Makefile index 30d97c4..f503978 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: LGPL-2.1-or-later # See Notices.txt for copyright information -.PHONY: all tests clean fix-tests +.PHONY: all tests clean fix-tests format-tests build-tests + +SHELL=/bin/bash CC = powerpc64le-linux-gnu-gcc CXX = powerpc64le-linux-gnu-g++ @@ -14,7 +16,10 @@ TESTS_DIR := $(dir $(TESTS_SOURCE)) TESTS_BUILD_DIR := $(addprefix build/,$(TESTS_DIR)) TESTS_DIFF := $(addsuffix diff.txt,$(TESTS_BUILD_DIR)) TESTS_FILTERED_OUT := $(addsuffix filtered-out.s,$(TESTS_BUILD_DIR)) -EXTRA_DEPS := Makefile $(wildcard include/*.h) +EXTRA_DEPS := Makefile $(wildcard include/*.h) include/simplev_cpp_generated.h + +include/simplev_cpp_generated.h: Makefile generate_headers.py + python3 generate_headers.py build/tests/%/: mkdir -p $@ @@ -31,9 +36,11 @@ build/tests/%/filtered-out.s: build/tests/%/out.s $(EXTRA_DEPS) build/tests/%/diff.txt: tests/%/expected.s build/tests/%/filtered-out.s $(EXTRA_DEPS) diff -u $< build/$(dir $<)filtered-out.s > $@ || true -.PRECIOUS: build/tests/%/out.s build/tests/%/filtered-out.s build/tests/%/ +.PRECIOUS: build/tests/%/out.s build/tests/%/filtered-out.s build/tests/%/ include/simplev_cpp_generated.h + +tests: build-tests format-tests -tests: $(TESTS_DIFF) +build-tests: $(TESTS_DIFF) @failed=0; \ for i in $+; do \ if [ -s "$$i" -o ! -e "$$i" ]; then \ @@ -62,5 +69,12 @@ fix-tests: $(TESTS_FILTERED_OUT) fi; \ done +format-tests: Makefile include/simplev_cpp_generated.h .clang-format + @if ! which clang-format-11 > /dev/null; then \ + echo "clang-format-11 not found -- skipping format test"; \ + else \ + diff -u <(clang-format-11 < include/simplev_cpp_generated.h) include/simplev_cpp_generated.h; \ + fi + clean: - rm -rf build/tests \ No newline at end of file + rm -rf build/tests include/simplev_cpp_generated.h \ No newline at end of file diff --git a/generate_headers.py b/generate_headers.py index e498a21..633683c 100755 --- a/generate_headers.py +++ b/generate_headers.py @@ -2,18 +2,13 @@ # SPDX-License-Identifier: LGPL-2.1-or-later # See Notices.txt for copyright information +import sys +from io import StringIO from typing import List -from soc.decoder.isa.caller import (SVP64PrefixFields, SV64P_MAJOR_SIZE, - SV64P_PID_SIZE, SVP64RMFields, - SVP64RM_EXTRA2_SPEC_SIZE, - SVP64RM_EXTRA3_SPEC_SIZE, - SVP64RM_MODE_SIZE, SVP64RM_SMASK_SIZE, - SVP64RM_MMODE_SIZE, SVP64RM_MASK_SIZE, - SVP64RM_SUBVL_SIZE, SVP64RM_EWSRC_SIZE, - SVP64RM_ELWIDTH_SIZE) from soc.decoder.pseudo.pagereader import ISA -from soc.decoder.power_svp64 import SVP64RM, get_regtype, decode_extra +from soc.decoder.power_svp64 import SVP64RM from soc.decoder.power_fields import DecodeFields +from soc.decoder.power_decoder import create_pdecode class InclusiveRange: @@ -97,7 +92,8 @@ class RangesField: self.ranges.append(InclusiveRange(value)) def endian_reversed(self, word_length) -> "RangesField": - return RangesField([i.endian_reversed(word_length) for i in reversed(self.ranges)]) + return RangesField([i.endian_reversed(word_length) + for i in reversed(self.ranges)]) @property def contiguous(self) -> bool: @@ -119,30 +115,85 @@ class RangesField: return self.ranges[0].width -isa = ISA() -svp64rm = SVP64RM() -decode_fields = DecodeFields(bitkls=RangesField) -decode_fields.create_specs() +try: + # shut-up excessive printing + old_stdout = sys.stdout + new_stdout = StringIO() + sys.stdout = new_stdout + isa = ISA() + svp64rm = SVP64RM() + decode_fields = DecodeFields(bitkls=RangesField) + decode_fields.create_specs() + decoder = create_pdecode() + sys.stdout = old_stdout +except: + sys.stdout = old_stdout + print(new_stdout.getvalue()) + raise + + +def flatten(v): + if isinstance(v, list): + for i in v: + yield from flatten(i) + else: + yield v + + +def find_opcode(internal_op): + retval = None + for primary_subdecoder in decoder.dec: + for extended_subdecoder in flatten(primary_subdecoder.subdecoders): + for opcode in extended_subdecoder.opcodes: + if opcode['internal op'] == internal_op: + if retval is not None: + raise ValueError(f"internal_op={internal_op!r} " + "found more than once") + retval = extended_subdecoder.pattern, \ + int(opcode['opcode'], base=0) + if retval is None: + raise ValueError(f"internal_op={internal_op!r} not found") + return retval + + +SETVL_PO, SETVL_XO = find_opcode("OP_SETVL") PO_FIELD: RangesField = decode_fields.PO RT_FIELD: RangesField = decode_fields.RT RA_FIELD: RangesField = decode_fields.RA +SVL_SVi_FIELD: RangesField = decode_fields.FormSVL.SVi +SVL_vs_FIELD: RangesField = decode_fields.FormSVL.vs +SVL_ms_FIELD: RangesField = decode_fields.FormSVL.ms +SVL_XO_FIELD: RangesField = decode_fields.FormSVL.XO +SVL_Rc_FIELD: RangesField = decode_fields.FormSVL.Rc +print(f"SETVL_PO={SETVL_PO}") +print(f"SETVL_XO={SETVL_XO}") print(f"PO_FIELD={PO_FIELD}") print(f"RT_FIELD={RT_FIELD}") print(f"RA_FIELD={RA_FIELD}") +print(f"SVL_SVi_FIELD={SVL_SVi_FIELD}") +print(f"SVL_vs_FIELD={SVL_vs_FIELD}") +print(f"SVL_ms_FIELD={SVL_ms_FIELD}") +print(f"SVL_XO_FIELD={SVL_XO_FIELD}") +print(f"SVL_Rc_FIELD={SVL_Rc_FIELD}") WORD_LENGTH = 32 -PRIMARY_OPCODE_SHIFT = PO_FIELD.endian_reversed(WORD_LENGTH).start -# unofficial value. see https://libre-soc.org/openpower/sv/setvl/ -# FIXME: incorrect extended opcode value -SETVL_OPCODE = (19 << PRIMARY_OPCODE_SHIFT) | (0 << 1) -SETVL_IMMEDIATE_SHIFT = 32 - 7 - 16 -REG_FIELD_WIDTH = 5 +PO_SHIFT = PO_FIELD.endian_reversed(WORD_LENGTH).start RT_SHIFT = RT_FIELD.endian_reversed(WORD_LENGTH).start RA_SHIFT = RA_FIELD.endian_reversed(WORD_LENGTH).start +SVL_SVi_SHIFT = SVL_SVi_FIELD.endian_reversed(WORD_LENGTH).start +SVL_vs_SHIFT = SVL_vs_FIELD.endian_reversed(WORD_LENGTH).start +SVL_ms_SHIFT = SVL_ms_FIELD.endian_reversed(WORD_LENGTH).start +SVL_XO_SHIFT = SVL_XO_FIELD.endian_reversed(WORD_LENGTH).start +SVL_Rc_SHIFT = SVL_Rc_FIELD.endian_reversed(WORD_LENGTH).start print(f"RT_SHIFT={RT_SHIFT}") print(f"RA_SHIFT={RA_SHIFT}") -print(f"PRIMARY_OPCODE_SHIFT={PRIMARY_OPCODE_SHIFT}") +print(f"PO_SHIFT={PO_SHIFT}") +print(f"SVL_SVi_SHIFT={SVL_SVi_SHIFT}") +print(f"SVL_vs_SHIFT={SVL_vs_SHIFT}") +print(f"SVL_ms_SHIFT={SVL_ms_SHIFT}") +print(f"SVL_XO_SHIFT={SVL_XO_SHIFT}") +print(f"SVL_Rc_SHIFT={SVL_Rc_SHIFT}") def is_power_of_2(i): @@ -153,6 +204,8 @@ def is_power_of_2(i): with open("include/simplev_cpp_generated.h", mode="w", encoding="utf-8") as o: o.write("""// SPDX-License-Identifier: LGPL-2.1-or-later // See Notices.txt for copyright information +// This file is automatically generated by generate_headers.py, +// do not edit by hand #pragma once #include #include @@ -214,7 +267,16 @@ inline __attribute__((always_inline)) VL setvl(std::size_t vl) "# setvl %[retval], %[vl], MVL=%[max_vl]\\n\\t" ".long %[instr] | (%[retval] << %[rt_shift]) | (%[vl] << %[ra_shift])" : [retval] "=b"(retval.value) - : [vl] "b"(vl), [max_vl] "n"(MAX_VL), [instr] "n"({FIXME___FINISH})); + : [vl] "b"(vl), + [max_vl] "n"(MAX_VL), + [instr] "n"(((MAX_VL - 1) << {SVL_SVi_SHIFT}) | {hex( + (1 << SVL_vs_SHIFT) + | (1 << SVL_ms_SHIFT) + | (SETVL_XO << SVL_XO_SHIFT) + | (SETVL_PO << PO_SHIFT))}), + [rt_shift] "n"({RT_SHIFT}), + [ra_shift] "n"({RA_SHIFT}) + : "memory"); return retval; }} }} // namespace sv -- 2.30.2