working on code
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 27 Jan 2021 05:26:27 +0000 (21:26 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Wed, 27 Jan 2021 05:26:27 +0000 (21:26 -0800)
12 files changed:
.gitignore
Makefile
compile_flags.txt
include/simplev_cpp.h
tests/test_add/expected.s [new file with mode: 0644]
tests/test_add/test.cpp [new file with mode: 0644]
tests/test_include/test.cpp
tests/test_include_c/test.c
tests/test_setvl/expected.s
tests/test_setvl/test.cpp
tests/test_sub/expected.s [new file with mode: 0644]
tests/test_sub/test.cpp [new file with mode: 0644]

index 7f07300b58e7b54f30f3da402bb77b8e5b89419c..9b867a96cb33d0b12e81bd6e99db29c2339472a5 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 # See Notices.txt for copyright information
-\.cache
\ No newline at end of file
+/.cache
+/.vscode
index 80e96b620cf246c1b35b8d1618115495ed7a9a9e..30d97c4a0bcf689ff9147eb5dfce83d62e0896f7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
 
 CC = powerpc64le-linux-gnu-gcc
 CXX = powerpc64le-linux-gnu-g++
-CFLAGS = -O3 -Iinclude -g0 -mno-altivec -mno-vsx
+CFLAGS = -O3 -Iinclude -g0 -mno-altivec -mno-vsx -Wall
 CXXFLAGS = -std=gnu++17
 
 all: tests
@@ -14,20 +14,21 @@ 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)
 
 build/tests/%/:
        mkdir -p $@
 
-build/tests/%/out.s: tests/%/test.cpp Makefile | build/tests/%/
+build/tests/%/out.s: tests/%/test.cpp $(EXTRA_DEPS) | build/tests/%/
        $(CXX) -S $(CFLAGS) $(CXXFLAGS) $< -o $@
 
-build/tests/%/out.s: tests/%/test.c Makefile | build/tests/%/
+build/tests/%/out.s: tests/%/test.c $(EXTRA_DEPS) | build/tests/%/
        $(CC) -S $(CFLAGS) $< -o $@
 
-build/tests/%/filtered-out.s: build/tests/%/out.s Makefile
+build/tests/%/filtered-out.s: build/tests/%/out.s $(EXTRA_DEPS)
        sed 's/\(^\t.ident\t"\).*"/\1GCC"/' < $< > $@
 
-build/tests/%/diff.txt: tests/%/expected.s build/tests/%/filtered-out.s Makefile
+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/%/
index 7d483f5374a4f5b7b6427dddfd834b70eba8aba8..18b5a51aa76cd54de183f796ee3a50c163ae36bc 100644 (file)
@@ -15,6 +15,7 @@
 /usr/powerpc64le-linux-gnu/include
 -isystem
 /usr/include
+-Wall
 -O3
 -Iinclude
 -g0
index 297f71ba52b19cf0759ab3e06aedd0a947e1c7fd..23941a21bab4c42cec5afd894208642c4449e531 100644 (file)
@@ -2,6 +2,8 @@
 // See Notices.txt for copyright information
 #pragma once
 
+#include <bits/c++config.h>
+#include <sys/cdefs.h>
 #ifndef __cplusplus
 #error to use SimpleV Cpp with C, include "simplev_c.h"
 #endif
 #include <cstdint>
 #include <type_traits>
 
-template <typename ElementType, std::size_t MAX_VL, typename = void>
-struct SVVecTypeStruct;
+// we need to use the register keyword as part of assigning particular variables to registers for
+// inline assembly
+#define DECLARE_ASM_REG(type, name, reg, value)                                       \
+    _Pragma("GCC diagnostic push")                                                    \
+        _Pragma("GCC diagnostic ignored \"-Wregister\"") register type name asm(reg); \
+    _Pragma("GCC diagnostic pop") name = value;
 
-template <typename ElementType, std::size_t MAX_VL>
-using SVVecType = typename SVVecTypeStruct<ElementType, MAX_VL>::Type;
+namespace sv
+{
+template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL, typename = void>
+struct VecTypeStruct;
+
+template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
+using VecType = typename VecTypeStruct<ElementType, SUB_VL, 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)));                 \
+#define MAKE_VEC_TYPE(size)                                                                 \
+    template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>                 \
+    struct VecTypeStruct<ElementType,                                                       \
+                         SUB_VL,                                                            \
+                         MAX_VL,                                                            \
+                         std::enable_if_t<sizeof(ElementType) * SUB_VL * MAX_VL == (size)>> \
+        final                                                                               \
+    {                                                                                       \
+        typedef ElementType Type __attribute__((vector_size(size)));                        \
     };
 
 MAKE_VEC_TYPE(1)
@@ -38,10 +50,12 @@ MAKE_VEC_TYPE(8)
 
 #undef MAKE_VEC_TYPE
 
-template <typename ElementType, std::size_t MAX_VL>
-struct SVVec final
+template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
+struct Vec final
 {
-    using Type = SVVecType<ElementType, MAX_VL>;
+    static_assert(MAX_VL > 0 && MAX_VL <= 64);
+    static_assert(SUB_VL >= 1 && SUB_VL <= 4);
+    using Type = VecType<ElementType, SUB_VL, MAX_VL>;
     Type value;
 };
 
@@ -53,11 +67,10 @@ struct Mask final
 template <size_t MAX_VL = 64>
 struct VL final
 {
+    static_assert(MAX_VL > 0 && MAX_VL <= 64);
     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
@@ -66,7 +79,181 @@ 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
+
+constexpr std::uint32_t encode_sv_prefix(std::uint32_t remapped_bits24)
+{
+    std::uint32_t expanded26bits = (remapped_bits24 & 0x3FFFFFUL)
+                                   | ((remapped_bits24 & 0x400000UL) << 1)
+                                   | ((remapped_bits24 & 0x800000UL) << 2);
+    expanded26bits |= 0x01400000UL; // set 2 constant-1 bits
+    return expanded26bits | (1UL << PRIMARY_OPCODE_SHIFT);
+}
+
+enum class MaskMode : std::uint32_t
+{
+    Int = 0,
+    CR = 1,
+};
+
+enum class MaskField : std::uint32_t
+{
+    Always = 0,
+    OneShlR3 = 1, // 1 << R3
+    R3 = 2,
+    NotR3 = 3,
+    R10 = 4,
+    NotR10 = 5,
+    R30 = 6,
+    NotR30 = 7,
+
+    Lt = 0,
+    NL = 1,
+    Gt = 2,
+    NG = 3,
+    Eq = 4,
+    NE = 5,
+    SO = 6,
+    NS = 7,
+};
+
+enum class Mode : std::uint32_t
+{
+    Normal = 0,
+    // TODO: fill out
+};
+
+enum class ElementWidth : std::uint32_t
+{
+    I8 = 3,
+    I16 = 2,
+    I32 = 1,
+    I64 = 0,
+    Default = 0,
+    F64 = 0,
+    F32 = 1,
+    F16 = 2,
+    BF16 = 3,
+};
+
+template <typename ElementType,
+          std::size_t ELEMENT_SIZE = sizeof(ElementType),
+          bool IS_INTEGRAL = std::is_integral_v<ElementType>>
+struct ElementProperties;
+
+template <typename ElementType>
+struct ElementProperties<ElementType, 1, true> final
+{
+    static inline constexpr ElementWidth element_width = ElementWidth::I8;
+};
+
+template <typename ElementType>
+struct ElementProperties<ElementType, 2, true> final
+{
+    static inline constexpr ElementWidth element_width = ElementWidth::I16;
+};
+
+template <typename ElementType>
+struct ElementProperties<ElementType, 4, true> final
+{
+    static inline constexpr ElementWidth element_width = ElementWidth::I32;
+};
+
+template <typename ElementType>
+struct ElementProperties<ElementType, 8, true> final
+{
+    static inline constexpr ElementWidth element_width = ElementWidth::I64;
+};
+
+template <>
+struct ElementProperties<float, 4, false> final
+{
+    static inline constexpr ElementWidth element_width = ElementWidth::F32;
+};
+
+template <>
+struct ElementProperties<double, 8, false> final
+{
+    static inline constexpr ElementWidth element_width = ElementWidth::F64;
+};
+
+template <typename ElementType>
+inline constexpr ElementWidth element_width_for = ElementProperties<ElementType>::element_width;
+
+template <std::size_t SUB_VL>
+constexpr std::uint32_t encode_sv_prefix(MaskMode mask_mode,
+                                         MaskField mask_field,
+                                         ElementWidth elwidth,
+                                         ElementWidth elwidth_src,
+                                         Mode mode,
+                                         std::uint32_t remapped_bits24)
+{
+    static_assert(SUB_VL >= 1 && SUB_VL <= 4);
+    remapped_bits24 |= static_cast<std::uint32_t>(mask_mode) << (23 - 0);
+    remapped_bits24 |= static_cast<std::uint32_t>(mask_field) << (23 - 3);
+    remapped_bits24 |= static_cast<std::uint32_t>(elwidth) << (23 - 5);
+    remapped_bits24 |= static_cast<std::uint32_t>(elwidth_src) << (23 - 7);
+    remapped_bits24 |= static_cast<std::uint32_t>(SUB_VL - 1) << (23 - 9);
+    remapped_bits24 |= static_cast<std::uint32_t>(mode);
+    return remapped_bits24;
+}
+
+enum class RegExtra2 : std::uint32_t
+{
+    Scalar0 = 0,
+    Scalar1 = 1,
+    Vector0 = 2,
+    Vector1 = 3,
+};
+
+enum class RegExtra3 : std::uint32_t
+{
+    Scalar0 = 0,
+    Scalar1 = 1,
+    Scalar2 = 2,
+    Scalar3 = 3,
+    Vector0 = 4,
+    Vector1 = 5,
+    Vector2 = 6,
+    Vector3 = 7,
+};
+
+template <std::size_t SUB_VL>
+constexpr std::uint32_t encode_sv_prefix_rm_1p_3s1d(MaskMode mask_mode,
+                                                    MaskField mask_field,
+                                                    ElementWidth elwidth,
+                                                    ElementWidth elwidth_src,
+                                                    Mode mode,
+                                                    RegExtra2 rdest_extra2,
+                                                    RegExtra2 rsrc1_extra2,
+                                                    RegExtra2 rsrc2_extra2,
+                                                    RegExtra2 rsrc3_extra2)
+{
+    std::uint32_t remapped_bits24 = 0;
+    remapped_bits24 |= static_cast<std::uint32_t>(rdest_extra2) << (23 - 11);
+    remapped_bits24 |= static_cast<std::uint32_t>(rsrc1_extra2) << (23 - 13);
+    remapped_bits24 |= static_cast<std::uint32_t>(rsrc2_extra2) << (23 - 15);
+    remapped_bits24 |= static_cast<std::uint32_t>(rsrc3_extra2) << (23 - 17);
+    return encode_sv_prefix<SUB_VL>(
+        mask_mode, mask_field, elwidth, elwidth_src, mode, remapped_bits24);
+}
+
+template <std::size_t SUB_VL>
+constexpr std::uint32_t encode_sv_prefix_rm_1p_2s1d(MaskMode mask_mode,
+                                                    MaskField mask_field,
+                                                    ElementWidth elwidth,
+                                                    ElementWidth elwidth_src,
+                                                    Mode mode,
+                                                    RegExtra3 rdest_extra3,
+                                                    RegExtra3 rsrc1_extra3,
+                                                    RegExtra3 rsrc2_extra3)
+{
+    std::uint32_t remapped_bits24 = 0;
+    remapped_bits24 |= static_cast<std::uint32_t>(rdest_extra3) << (23 - 12);
+    remapped_bits24 |= static_cast<std::uint32_t>(rsrc1_extra3) << (23 - 15);
+    remapped_bits24 |= static_cast<std::uint32_t>(rsrc2_extra3) << (23 - 18);
+    return encode_sv_prefix<SUB_VL>(
+        mask_mode, mask_field, elwidth, elwidth_src, mode, remapped_bits24);
+}
 
 #define SETVL_ASM(retval, vl)                                            \
     "# setvl " retval ", " vl                                            \
@@ -74,19 +261,97 @@ inline constexpr std::size_t XL_FORM_RA_SHIFT = 32 - REG_FIELD_WIDTH - 11;
     ".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)
+#define SETVL_ASM_INPUT_ARGS()                                                                    \
+    [setvl_opcode] "n"(sv::SETVL_OPCODE), [setvl_immediate_shift] "n"(sv::SETVL_IMMEDIATE_SHIFT), \
+        [xl_form_rt_shift] "n"(sv::XL_FORM_RT_SHIFT), [xl_form_ra_shift] "n"(sv::XL_FORM_RA_SHIFT)
 
 template <std::size_t MAX_VL>
-inline __attribute__((always_inline)) VL<MAX_VL> sv_setvl(std::size_t vl)
+inline __attribute__((always_inline)) VL<MAX_VL> 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;
 }
+
+template <typename ElementType,
+          std::size_t SUB_VL,
+          std::size_t MAX_VL,
+          typename = std::enable_if_t<std::is_integral_v<ElementType>>>
+inline __attribute__((always_inline)) Vec<ElementType, SUB_VL, MAX_VL> add(
+    Vec<ElementType, SUB_VL, MAX_VL> ra,
+    Vec<ElementType, SUB_VL, MAX_VL> rb,
+    VL<MAX_VL> vl = VL<MAX_VL>(),
+    Mask mask = Mask())
+{
+    constexpr std::uint32_t prefix =
+        encode_sv_prefix_rm_1p_2s1d<SUB_VL>(MaskMode::Int,
+                                            MaskField::R10,
+                                            element_width_for<ElementType>,
+                                            element_width_for<ElementType>,
+                                            Mode::Normal,
+                                            RegExtra3::Vector0,
+                                            RegExtra3::Vector0,
+                                            RegExtra3::Vector0);
+    Vec<ElementType, SUB_VL, MAX_VL> retval;
+    DECLARE_ASM_REG(std::uint64_t, mask_r10, "r10", mask.value)
+    asm(SETVL_ASM("0", "%[vl]") "\n\t"
+        "# sv.add ew=%[el_width], subvl=%[sub_vl], m=%[mask], %[retval].v, %[ra].v, %[rb].v\n\t"
+        ".long %[prefix]\n\t"
+        "add %[retval], %[ra], %[rb]"
+        : [retval] "=&b"(retval.value)
+        : [vl] "b"(vl),
+          [max_vl] "n"(MAX_VL),
+          [sub_vl] "n"(SUB_VL),
+          [mask] "b"(mask_r10),
+          [ra] "b"(ra.value),
+          [rb] "b"(rb.value),
+          [el_width] "n"(8 * sizeof(ElementType)),
+          [prefix] "n"(prefix),
+          SETVL_ASM_INPUT_ARGS());
+    return retval;
+}
+
+template <typename ElementType,
+          std::size_t SUB_VL,
+          std::size_t MAX_VL,
+          typename = std::enable_if_t<std::is_integral_v<ElementType>>>
+inline __attribute__((always_inline)) Vec<ElementType, SUB_VL, MAX_VL> sub(
+    Vec<ElementType, SUB_VL, MAX_VL> rb, // intentionally reversed since we use sv.subf instruction
+    Vec<ElementType, SUB_VL, MAX_VL> ra,
+    VL<MAX_VL> vl = VL<MAX_VL>(),
+    Mask mask = Mask())
+{
+    constexpr std::uint32_t prefix =
+        encode_sv_prefix_rm_1p_2s1d<SUB_VL>(MaskMode::Int,
+                                            MaskField::R10,
+                                            element_width_for<ElementType>,
+                                            element_width_for<ElementType>,
+                                            Mode::Normal,
+                                            RegExtra3::Vector0,
+                                            RegExtra3::Vector0,
+                                            RegExtra3::Vector0);
+    Vec<ElementType, SUB_VL, MAX_VL> retval;
+    DECLARE_ASM_REG(std::uint64_t, mask_r10, "r10", mask.value)
+    asm(SETVL_ASM("0", "%[vl]") "\n\t"
+        "# sv.subf ew=%[el_width], subvl=%[sub_vl], m=%[mask], %[retval].v, %[ra].v, %[rb].v\n\t"
+        ".long %[prefix]\n\t"
+        "subf %[retval], %[ra], %[rb]"
+        : [retval] "=&b"(retval.value)
+        : [vl] "b"(vl),
+          [max_vl] "n"(MAX_VL),
+          [sub_vl] "n"(SUB_VL),
+          [mask] "b"(mask_r10),
+          [ra] "b"(ra.value),
+          [rb] "b"(rb.value),
+          [el_width] "n"(8 * sizeof(ElementType)),
+          [prefix] "n"(prefix),
+          SETVL_ASM_INPUT_ARGS());
+    return retval;
+}
+
+#undef SETVL_ASM
+#undef SETVL_ASM_INPUT_ARGS
+#undef DECLARE_ASM_REG
+} // namespace sv
diff --git a/tests/test_add/expected.s b/tests/test_add/expected.s
new file mode 100644 (file)
index 0000000..15e9cd2
--- /dev/null
@@ -0,0 +1,90 @@
+       .file   "test.cpp"
+       .abiversion 2
+       .section        ".text"
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_add_1N2sv3VecIhLm1ELm4EEES1_
+       .type   _Z10test_add_1N2sv3VecIhLm1ELm4EEES1_, @function
+_Z10test_add_1N2sv3VecIhLm1ELm4EEES1_:
+.LFB27:
+       .cfi_startproc
+       li 9,4
+       li 10,-1
+#APP
+ # 312 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.add ew=8, subvl=1, m=10, 8.v, 3.v, 4.v
+       .long 5186688
+       add 8, 3, 4
+ # 0 "" 2
+#NO_APP
+       mr 3,8
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE27:
+       .size   _Z10test_add_1N2sv3VecIhLm1ELm4EEES1_,.-_Z10test_add_1N2sv3VecIhLm1ELm4EEES1_
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_add_2N2sv3VecItLm1ELm4EEES1_
+       .type   _Z10test_add_2N2sv3VecItLm1ELm4EEES1_, @function
+_Z10test_add_2N2sv3VecItLm1ELm4EEES1_:
+.LFB34:
+       .cfi_startproc
+       li 9,4
+       li 10,-1
+#APP
+ # 312 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.add ew=16, subvl=1, m=10, 8.v, 3.v, 4.v
+       .long 4859008
+       add 8, 3, 4
+ # 0 "" 2
+#NO_APP
+       mr 3,8
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE34:
+       .size   _Z10test_add_2N2sv3VecItLm1ELm4EEES1_,.-_Z10test_add_2N2sv3VecItLm1ELm4EEES1_
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_add_3N2sv3VecItLm1ELm4EEES1_S1_
+       .type   _Z10test_add_3N2sv3VecItLm1ELm4EEES1_S1_, @function
+_Z10test_add_3N2sv3VecItLm1ELm4EEES1_S1_:
+.LFB35:
+       .cfi_startproc
+       li 9,4
+       li 10,-1
+#APP
+ # 312 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.add ew=16, subvl=1, m=10, 8.v, 4.v, 5.v
+       .long 4859008
+       add 8, 4, 5
+ # 0 "" 2
+#NO_APP
+       mr 5,8
+#APP
+ # 312 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.add ew=16, subvl=1, m=10, 8.v, 3.v, 5.v
+       .long 4859008
+       add 8, 3, 5
+ # 0 "" 2
+#NO_APP
+       mr 3,8
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE35:
+       .size   _Z10test_add_3N2sv3VecItLm1ELm4EEES1_S1_,.-_Z10test_add_3N2sv3VecItLm1ELm4EEES1_S1_
+       .ident  "GCC"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test_add/test.cpp b/tests/test_add/test.cpp
new file mode 100644 (file)
index 0000000..68adce0
--- /dev/null
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// See Notices.txt for copyright information
+#include <cstddef>
+#include <cstdint>
+
+#include "simplev_cpp.h"
+
+using u8x4 = sv::Vec<std::uint8_t, 1, 4>;
+using u16x4 = sv::Vec<std::uint16_t, 1, 4>;
+
+u8x4 test_add_1(u8x4 a, u8x4 b)
+{
+    return sv::add(a, b);
+}
+
+u16x4 test_add_2(u16x4 a, u16x4 b)
+{
+    return sv::add(a, b);
+}
+
+u16x4 test_add_3(u16x4 a, u16x4 b, u16x4 c)
+{
+    return sv::add(a, sv::add(b, c));
+}
\ No newline at end of file
index 5aeb04c3dc519893319a1f91e73c19aa2411185e..b7328ed52b5ac781d8d87321ac8561d5ba71f239 100644 (file)
@@ -1,2 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// See Notices.txt for copyright information
+
 // test just including file
 #include "simplev_cpp.h"
index 01ff6eb7057fad9abaa983c8551065861a391988..1e97e4f304c8c2272edff025b4d8620c1564d0ed 100644 (file)
@@ -1,2 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// See Notices.txt for copyright information
+
 // test just including file
 #include "simplev_c.h"
index a376ebbd9c5a28d06444b51aaa59150873a409dd..a9d1764b4c62c34fe3acce3bd147e9c424a6f7c9 100644 (file)
@@ -6,10 +6,10 @@
        .globl _Z10test_setvlm
        .type   _Z10test_setvlm, @function
 _Z10test_setvlm:
-.LFB21:
+.LFB27:
        .cfi_startproc
 #APP
- # 90 "include/simplev_cpp.h" 1
+ # 274 "include/simplev_cpp.h" 1
        # setvl 3, 3, MVL=8
        .long 1275068416 | (3 << 21) | (3 << 16) | ((8 - 1) << 9)
  # 0 "" 2
@@ -18,7 +18,7 @@ _Z10test_setvlm:
        .long 0
        .byte 0,9,0,0,0,0,0,0
        .cfi_endproc
-.LFE21:
+.LFE27:
        .size   _Z10test_setvlm,.-_Z10test_setvlm
        .ident  "GCC"
        .section        .note.GNU-stack,"",@progbits
index a6df168adf1890b5f1cce97b1cc4cd39caf7d0f4..473a2cb55a51d8cffc8f9fd287f3480246e78151 100644 (file)
@@ -1,9 +1,12 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// See Notices.txt for copyright information
+
 #include <cstddef>
 #include <cstdint>
 
 #include "simplev_cpp.h"
 
-VL<8> test_setvl(std::size_t v)
+sv::VL<8> test_setvl(std::size_t v)
 {
-    return sv_setvl<8>(v);
+    return sv::setvl<8>(v);
 }
\ No newline at end of file
diff --git a/tests/test_sub/expected.s b/tests/test_sub/expected.s
new file mode 100644 (file)
index 0000000..e4d457e
--- /dev/null
@@ -0,0 +1,90 @@
+       .file   "test.cpp"
+       .abiversion 2
+       .section        ".text"
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_sub_1N2sv3VecIhLm1ELm4EEES1_
+       .type   _Z10test_sub_1N2sv3VecIhLm1ELm4EEES1_, @function
+_Z10test_sub_1N2sv3VecIhLm1ELm4EEES1_:
+.LFB27:
+       .cfi_startproc
+       li 9,4
+       li 10,-1
+#APP
+ # 350 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.subf ew=8, subvl=1, m=10, 8.v, 4.v, 3.v
+       .long 5186688
+       subf 8, 4, 3
+ # 0 "" 2
+#NO_APP
+       mr 3,8
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE27:
+       .size   _Z10test_sub_1N2sv3VecIhLm1ELm4EEES1_,.-_Z10test_sub_1N2sv3VecIhLm1ELm4EEES1_
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_sub_2N2sv3VecItLm1ELm4EEES1_
+       .type   _Z10test_sub_2N2sv3VecItLm1ELm4EEES1_, @function
+_Z10test_sub_2N2sv3VecItLm1ELm4EEES1_:
+.LFB34:
+       .cfi_startproc
+       li 9,4
+       li 10,-1
+#APP
+ # 350 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.subf ew=16, subvl=1, m=10, 8.v, 4.v, 3.v
+       .long 4859008
+       subf 8, 4, 3
+ # 0 "" 2
+#NO_APP
+       mr 3,8
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE34:
+       .size   _Z10test_sub_2N2sv3VecItLm1ELm4EEES1_,.-_Z10test_sub_2N2sv3VecItLm1ELm4EEES1_
+       .align 2
+       .p2align 4,,15
+       .globl _Z10test_sub_3N2sv3VecItLm1ELm4EEES1_S1_
+       .type   _Z10test_sub_3N2sv3VecItLm1ELm4EEES1_S1_, @function
+_Z10test_sub_3N2sv3VecItLm1ELm4EEES1_S1_:
+.LFB35:
+       .cfi_startproc
+       li 9,4
+       li 10,-1
+#APP
+ # 350 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.subf ew=16, subvl=1, m=10, 8.v, 5.v, 4.v
+       .long 4859008
+       subf 8, 5, 4
+ # 0 "" 2
+#NO_APP
+       mr 5,8
+#APP
+ # 350 "include/simplev_cpp.h" 1
+       # setvl 0, 9, MVL=4
+       .long 1275068416 | (0 << 21) | (9 << 16) | ((4 - 1) << 9)
+       # sv.subf ew=16, subvl=1, m=10, 8.v, 5.v, 3.v
+       .long 4859008
+       subf 8, 5, 3
+ # 0 "" 2
+#NO_APP
+       mr 3,8
+       blr
+       .long 0
+       .byte 0,9,0,0,0,0,0,0
+       .cfi_endproc
+.LFE35:
+       .size   _Z10test_sub_3N2sv3VecItLm1ELm4EEES1_S1_,.-_Z10test_sub_3N2sv3VecItLm1ELm4EEES1_S1_
+       .ident  "GCC"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/tests/test_sub/test.cpp b/tests/test_sub/test.cpp
new file mode 100644 (file)
index 0000000..06ad9d8
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// See Notices.txt for copyright information
+
+#include <cstddef>
+#include <cstdint>
+
+#include "simplev_cpp.h"
+
+using u8x4 = sv::Vec<std::uint8_t, 1, 4>;
+using u16x4 = sv::Vec<std::uint16_t, 1, 4>;
+
+u8x4 test_sub_1(u8x4 a, u8x4 b)
+{
+    return sv::sub(a, b);
+}
+
+u16x4 test_sub_2(u16x4 a, u16x4 b)
+{
+    return sv::sub(a, b);
+}
+
+u16x4 test_sub_3(u16x4 a, u16x4 b, u16x4 c)
+{
+    return sv::sub(a, sv::sub(b, c));
+}
\ No newline at end of file