generating setvl function works
authorJacob Lifshay <programmerjake@gmail.com>
Sat, 13 Mar 2021 00:55:57 +0000 (16:55 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Sat, 13 Mar 2021 00:55:57 +0000 (16:55 -0800)
.clang-format [new file with mode: 0644]
.gitignore
Makefile
generate_headers.py

diff --git a/.clang-format b/.clang-format
new file mode 100644 (file)
index 0000000..05b61e6
--- /dev/null
@@ -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
+...
index 9b867a96cb33d0b12e81bd6e99db29c2339472a5..d17f11aa7bc76eab540d48997e1895677125c75c 100644 (file)
@@ -2,3 +2,4 @@
 # See Notices.txt for copyright information
 /.cache
 /.vscode
+/include/simplev_cpp_generated.h
\ No newline at end of file
index 30d97c4a0bcf689ff9147eb5dfce83d62e0896f7..f50397847187395e9acf8c752166f1e645d10dab 100644 (file)
--- 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
index e498a213289bff2275d24898b1898fb0c3da8a8a..633683c72e0552d7d581fdc4cbba53f1e3a6065d 100755 (executable)
@@ -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 <cstddef>
 #include <cstdint>
@@ -214,7 +267,16 @@ inline __attribute__((always_inline)) VL<MAX_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