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
[ "$(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; \
// 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;
+}