cgen: tweak arm_neon_utility.make_u16x4_multiple The -O3 codegen is the same (https://godbolt.org/z/5ecWrEq77) but this avoids compound literals, not part of C++11, and can trigger "compound literals are a C99-specific feature [-Werror,-Wc99-extensions]". Fixes #181
diff --git a/internal/cgen/base/fundamental-public.h b/internal/cgen/base/fundamental-public.h index 001c7c9..9ef789c 100644 --- a/internal/cgen/base/fundamental-public.h +++ b/internal/cgen/base/fundamental-public.h
@@ -1401,6 +1401,44 @@ #endif } +// -------- + +static inline uint64_t // +wuffs_base__pack_u8x8le_as_u64(uint8_t a0, + uint8_t a1, + uint8_t a2, + uint8_t a3, + uint8_t a4, + uint8_t a5, + uint8_t a6, + uint8_t a7) { + return (((uint64_t)a0) << 0) | // + (((uint64_t)a1) << 8) | // + (((uint64_t)a2) << 16) | // + (((uint64_t)a3) << 24) | // + (((uint64_t)a4) << 32) | // + (((uint64_t)a5) << 40) | // + (((uint64_t)a6) << 48) | // + (((uint64_t)a7) << 56); +} + +static inline uint64_t // +wuffs_base__pack_u16x4le_as_u64(uint16_t a0, + uint16_t a1, + uint16_t a2, + uint16_t a3) { + return (((uint64_t)a0) << 0) | // + (((uint64_t)a1) << 16) | // + (((uint64_t)a2) << 32) | // + (((uint64_t)a3) << 48); +} + +static inline uint64_t // +wuffs_base__pack_u32x2le_as_u64(uint32_t a0, uint32_t a1) { + return (((uint64_t)a0) << 0) | // + (((uint64_t)a1) << 32); +} + // ---------------- Slices and Tables // WUFFS_BASE__SLICE is a 1-dimensional buffer.
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go index 18e2e99..147f732 100644 --- a/internal/cgen/builtin.go +++ b/internal/cgen/builtin.go
@@ -514,26 +514,37 @@ func (g *gen) writeBuiltinCPUArchARMNeon(b *buffer, recv *a.Expr, method t.ID, args []*a.Node, sideEffectsOnly bool, depth uint32) error { methodStr := method.Str(g.tm) if strings.HasPrefix(methodStr, "make_") { - before, after, ptr := "", ")", false + before, middle, after, ptr := "", "", ")", false if strings.HasSuffix(methodStr, "_multiple") { - after = "})" switch methodStr { case "make_u8x8_multiple": - before = "((uint8x8_t){" + before = "vreinterpret_u8_u64(vcreate_u64(wuffs_base__pack_u8x8le_as_u64(" + after = ")))" case "make_u16x4_multiple": - before = "((uint16x4_t){" + before = "vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(" + after = ")))" case "make_u32x2_multiple": - before = "((uint32x2_t){" + before = "vreinterpret_u32_u64(vcreate_u64(wuffs_base__pack_u32x2le_as_u64(" + after = ")))" case "make_u64x1_multiple": - before = "((uint64x1_t){" + before = "vcreate_u64(" + after = ")" case "make_u8x16_multiple": - before = "((uint8x16_t){" + before = "vcombine_u8(vreinterpret_u8_u64(vcreate_u64(wuffs_base__pack_u8x8le_as_u64(" + middle = "))), vreinterpret_u8_u64(vcreate_u64(wuffs_base__pack_u8x8le_as_u64(" + after = "))))" case "make_u16x8_multiple": - before = "((uint16x8_t){" + before = "vcombine_u16(vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(" + middle = "))), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(" + after = "))))" case "make_u32x4_multiple": - before = "((uint32x4_t){" + before = "vcombine_u32(vreinterpret_u32_u64(vcreate_u64(wuffs_base__pack_u32x2le_as_u64(" + middle = "))), vreinterpret_u32_u64(vcreate_u64(wuffs_base__pack_u32x2le_as_u64(" + after = "))))" case "make_u64x2_multiple": - before = "((uint64x2_t){" + before = "vcombine_u64(vcreate_u64(" + middle = "), vcreate_u64(" + after = "))" } } else { switch methodStr { @@ -563,7 +574,9 @@ } b.writes(before) for i, o := range args { - if i > 0 { + if (i == (len(args) / 2)) && (middle != "") { + b.writes(middle) + } else if i > 0 { b.writes(", ") } if ptr {
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c index 1b28825..d2d3670 100644 --- a/release/c/wuffs-unsupported-snapshot.c +++ b/release/c/wuffs-unsupported-snapshot.c
@@ -1691,6 +1691,44 @@ #endif } +// -------- + +static inline uint64_t // +wuffs_base__pack_u8x8le_as_u64(uint8_t a0, + uint8_t a1, + uint8_t a2, + uint8_t a3, + uint8_t a4, + uint8_t a5, + uint8_t a6, + uint8_t a7) { + return (((uint64_t)a0) << 0) | // + (((uint64_t)a1) << 8) | // + (((uint64_t)a2) << 16) | // + (((uint64_t)a3) << 24) | // + (((uint64_t)a4) << 32) | // + (((uint64_t)a5) << 40) | // + (((uint64_t)a6) << 48) | // + (((uint64_t)a7) << 56); +} + +static inline uint64_t // +wuffs_base__pack_u16x4le_as_u64(uint16_t a0, + uint16_t a1, + uint16_t a2, + uint16_t a3) { + return (((uint64_t)a0) << 0) | // + (((uint64_t)a1) << 16) | // + (((uint64_t)a2) << 32) | // + (((uint64_t)a3) << 48); +} + +static inline uint64_t // +wuffs_base__pack_u32x2le_as_u64(uint32_t a0, uint32_t a1) { + return (((uint64_t)a0) << 0) | // + (((uint64_t)a1) << 32); +} + // ---------------- Slices and Tables // WUFFS_BASE__SLICE is a 1-dimensional buffer. @@ -35960,14 +35998,14 @@ v_p.len = 0; } v_v2 = vshlq_n_u32(v_v2, 5u); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32u, 31u, 30u, 29u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28u, 27u, 26u, 25u})); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24u, 23u, 22u, 21u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20u, 19u, 18u, 17u})); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16u, 15u, 14u, 13u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12u, 11u, 10u, 9u})); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8u, 7u, 6u, 5u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4u, 3u, 2u, 1u})); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(32u, 31u, 30u, 29u)))); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(28u, 27u, 26u, 25u)))); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(24u, 23u, 22u, 21u)))); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(20u, 19u, 18u, 17u)))); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(16u, 15u, 14u, 13u)))); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(12u, 11u, 10u, 9u)))); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(8u, 7u, 6u, 5u)))); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), vreinterpret_u16_u64(vcreate_u64(wuffs_base__pack_u16x4le_as_u64(4u, 3u, 2u, 1u)))); v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1)); v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2)); v_sum12 = vpadd_u32(v_sum1, v_sum2);