add setvl
authorJacob Lifshay <programmerjake@gmail.com>
Tue, 26 Jan 2021 03:29:13 +0000 (19:29 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Tue, 26 Jan 2021 03:29:13 +0000 (19:29 -0800)
15 files changed:
.gitignore
Makefile
compile_flags.txt [new file with mode: 0644]
include/simplev_c.h [new file with mode: 0644]
include/simplev_cpp.h
tests/test1/expected.s [deleted file]
tests/test1/test.c [deleted file]
tests/test2/expected.s [deleted file]
tests/test2/test.cpp [deleted file]
tests/test_include/expected.s [new file with mode: 0644]
tests/test_include/test.cpp [new file with mode: 0644]
tests/test_include_c/expected.s [new file with mode: 0644]
tests/test_include_c/test.c [new file with mode: 0644]
tests/test_setvl/expected.s [new file with mode: 0644]
tests/test_setvl/test.cpp [new file with mode: 0644]

index d30def24c7a165732140412347670a993a27d9ee..7f07300b58e7b54f30f3da402bb77b8e5b89419c 100644 (file)
@@ -1,4 +1,3 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 # See Notices.txt for copyright information
-\.cache
-compile_commands.json
\ No newline at end of file
+\.cache
\ No newline at end of file
index dd92083d01e2fc883ffd10b71f9086d7b3c6d725..80e96b620cf246c1b35b8d1618115495ed7a9a9e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
 
 CC = powerpc64le-linux-gnu-gcc
 CXX = powerpc64le-linux-gnu-g++
-CFLAGS = -O3 -Iinclude -g0
+CFLAGS = -O3 -Iinclude -g0 -mno-altivec -mno-vsx
 CXXFLAGS = -std=gnu++17
 
 all: tests
@@ -55,7 +55,7 @@ fix-tests: $(TESTS_FILTERED_OUT)
                [ "$(FORCE_FIX_TESTS)" = "$$target" ] || status="$$(git status --porcelain "$$target")"; \
                if [ -z "$$status" ]; then \
                        cp -v "$$i" "$$target"; \
-               else \
+               elif ! cmp "$$i" "$$target"; then \
                        echo "$$target has uncommitted changes, not overwriting -- commit changes or run make with FORCE_FIX_TESTS=$$target" >&2; \
                        exit 1; \
                fi; \
diff --git a/compile_flags.txt b/compile_flags.txt
new file mode 100644 (file)
index 0000000..37fd6b4
--- /dev/null
@@ -0,0 +1,22 @@
+-xc++
+-S
+--target=powerpc64le-linux-gnu
+-isystem
+/usr/powerpc64le-linux-gnu/include/c++/7
+-isystem
+/usr/powerpc64le-linux-gnu/include/c++/7/powerpc64le-linux-gnu
+-isystem
+/usr/powerpc64le-linux-gnu/include/c++/7/backward
+-isystem
+/usr/lib/gcc-cross/powerpc64le-linux-gnu/7/include
+-isystem
+/usr/lib/gcc-cross/powerpc64le-linux-gnu/7/include-fixed
+-isystem
+/usr/powerpc64le-linux-gnu/include
+-isystem
+/usr/include
+-O3
+-Iinclude
+-g0
+-std=gnu++17
+-D__clangd
\ No newline at end of file
diff --git a/include/simplev_c.h b/include/simplev_c.h
new file mode 100644 (file)
index 0000000..c77ce6f
--- /dev/null
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// See Notices.txt for copyright information
+#pragma once
+
+#warning currently not implemented
index 7d9d40d002985dae2f23e9fecb8d225d9c242ed7..297f71ba52b19cf0759ab3e06aedd0a947e1c7fd 100644 (file)
@@ -1,3 +1,92 @@
 // SPDX-License-Identifier: LGPL-2.1-or-later
 // See Notices.txt for copyright information
-#pragma once
\ No newline at end of file
+#pragma once
+
+#ifndef __cplusplus
+#error to use SimpleV Cpp with C, include "simplev_c.h"
+#endif
+
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+
+template <typename ElementType, std::size_t MAX_VL, typename = void>
+struct SVVecTypeStruct;
+
+template <typename ElementType, std::size_t MAX_VL>
+using SVVecType = typename SVVecTypeStruct<ElementType, MAX_VL>::Type;
+
+
+#define MAKE_VEC_TYPE(size)                                                          \
+    template <typename ElementType, std::size_t MAX_VL>                              \
+    struct SVVecTypeStruct<ElementType,                                              \
+                           MAX_VL,                                                   \
+                           std::enable_if_t<sizeof(ElementType) * MAX_VL == (size)>> \
+        final                                                                        \
+    {                                                                                \
+        typedef ElementType Type __attribute__((vector_size(size)));                 \
+    };
+
+MAKE_VEC_TYPE(1)
+MAKE_VEC_TYPE(2)
+MAKE_VEC_TYPE(3)
+MAKE_VEC_TYPE(4)
+MAKE_VEC_TYPE(5)
+MAKE_VEC_TYPE(6)
+MAKE_VEC_TYPE(7)
+MAKE_VEC_TYPE(8)
+
+#undef MAKE_VEC_TYPE
+
+template <typename ElementType, std::size_t MAX_VL>
+struct SVVec final
+{
+    using Type = SVVecType<ElementType, MAX_VL>;
+    Type value;
+};
+
+struct Mask final
+{
+    std::uint64_t value = ~0ULL;
+};
+
+template <size_t MAX_VL = 64>
+struct VL final
+{
+    std::size_t value = MAX_VL;
+};
+
+namespace opcodes
+{
+inline constexpr std::size_t PRIMARY_OPCODE_SHIFT = 32 - 6;
+/// unofficial value. see https://libre-soc.org/openpower/sv/setvl/
+/// FIXME: incorrect extended opcode value
+inline constexpr std::uint32_t SETVL_OPCODE = (19 << PRIMARY_OPCODE_SHIFT) | (0 << 1);
+inline constexpr std::size_t SETVL_IMMEDIATE_SHIFT = 32 - 7 - 16;
+inline constexpr std::size_t REG_FIELD_WIDTH = 5;
+inline constexpr std::size_t XL_FORM_RT_SHIFT = 32 - REG_FIELD_WIDTH - 6;
+inline constexpr std::size_t XL_FORM_RA_SHIFT = 32 - REG_FIELD_WIDTH - 11;
+} // namespace opcodes
+
+#define SETVL_ASM(retval, vl)                                            \
+    "# setvl " retval ", " vl                                            \
+    ", MVL=%[max_vl]\n\t"                                                \
+    ".long %[setvl_opcode] | (" retval " << %[xl_form_rt_shift]) | (" vl \
+    " << %[xl_form_ra_shift]) | ((%[max_vl] - 1) << %[setvl_immediate_shift])"
+
+#define SETVL_ASM_INPUT_ARGS()                                       \
+    [setvl_opcode] "n"(opcodes::SETVL_OPCODE),                       \
+        [setvl_immediate_shift] "n"(opcodes::SETVL_IMMEDIATE_SHIFT), \
+        [xl_form_rt_shift] "n"(opcodes::XL_FORM_RT_SHIFT),           \
+        [xl_form_ra_shift] "n"(opcodes::XL_FORM_RA_SHIFT)
+
+template <std::size_t MAX_VL>
+inline __attribute__((always_inline)) VL<MAX_VL> sv_setvl(std::size_t vl)
+{
+    static_assert(MAX_VL > 0 && MAX_VL < 64);
+    VL<MAX_VL> retval;
+    asm(SETVL_ASM("%[retval]", "%[vl]")
+        : [retval] "=b"(retval.value)
+        : [vl] "b"(vl), [max_vl] "n"(MAX_VL), SETVL_ASM_INPUT_ARGS());
+    return retval;
+}
diff --git a/tests/test1/expected.s b/tests/test1/expected.s
deleted file mode 100644 (file)
index d1e7561..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-       .file   "test.c"
-       .abiversion 2
-       .section        ".text"
-       .ident  "GCC"
-       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test1/test.c b/tests/test1/test.c
deleted file mode 100644 (file)
index 86ef605..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "simplev_cpp.h"
\ No newline at end of file
diff --git a/tests/test2/expected.s b/tests/test2/expected.s
deleted file mode 100644 (file)
index d41ecc2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-       .file   "test.cpp"
-       .abiversion 2
-       .section        ".text"
-       .align 2
-       .p2align 4,,15
-       .globl _Z1fv
-       .type   _Z1fv, @function
-_Z1fv:
-.LFB0:
-       .cfi_startproc
-       blr
-       .long 0
-       .byte 0,9,0,0,0,0,0,0
-       .cfi_endproc
-.LFE0:
-       .size   _Z1fv,.-_Z1fv
-       .ident  "GCC"
-       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test2/test.cpp b/tests/test2/test.cpp
deleted file mode 100644 (file)
index 7333c1a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "simplev_cpp.h"
-
-void f()
-{
-}
\ No newline at end of file
diff --git a/tests/test_include/expected.s b/tests/test_include/expected.s
new file mode 100644 (file)
index 0000000..45bca36
--- /dev/null
@@ -0,0 +1,5 @@
+       .file   "test.cpp"
+       .abiversion 2
+       .section        ".text"
+       .ident  "GCC"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test_include/test.cpp b/tests/test_include/test.cpp
new file mode 100644 (file)
index 0000000..5aeb04c
--- /dev/null
@@ -0,0 +1,2 @@
+// test just including file
+#include "simplev_cpp.h"
diff --git a/tests/test_include_c/expected.s b/tests/test_include_c/expected.s
new file mode 100644 (file)
index 0000000..d1e7561
--- /dev/null
@@ -0,0 +1,5 @@
+       .file   "test.c"
+       .abiversion 2
+       .section        ".text"
+       .ident  "GCC"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test_include_c/test.c b/tests/test_include_c/test.c
new file mode 100644 (file)
index 0000000..01ff6eb
--- /dev/null
@@ -0,0 +1,2 @@
+// test just including file
+#include "simplev_c.h"
diff --git a/tests/test_setvl/expected.s b/tests/test_setvl/expected.s
new file mode 100644 (file)
index 0000000..a376ebb
--- /dev/null
@@ -0,0 +1,24 @@
+       .file   "test.cpp"
+       .abiversion 2
+       .section        ".text"
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_setvlm
+       .type   _Z10test_setvlm, @function
+_Z10test_setvlm:
+.LFB21:
+       .cfi_startproc
+#APP
+ # 90 "include/simplev_cpp.h" 1
+       # setvl 3, 3, MVL=8
+       .long 1275068416 | (3 << 21) | (3 << 16) | ((8 - 1) << 9)
+ # 0 "" 2
+#NO_APP
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE21:
+       .size   _Z10test_setvlm,.-_Z10test_setvlm
+       .ident  "GCC"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test_setvl/test.cpp b/tests/test_setvl/test.cpp
new file mode 100644 (file)
index 0000000..a6df168
--- /dev/null
@@ -0,0 +1,9 @@
+#include <cstddef>
+#include <cstdint>
+
+#include "simplev_cpp.h"
+
+VL<8> test_setvl(std::size_t v)
+{
+    return sv_setvl<8>(v);
+}
\ No newline at end of file