LGTM Reviewed-by:Sid Manning <[email protected]> On Sat, Sep 5, 2026 at 1:10 PM Brian Cain <[email protected]> wrote:
> Test the interleave/deinterleave 64-bit bit-manipulation instructions > and the cround instruction. > > Signed-off-by: Brian Cain <[email protected]> > --- > tests/tcg/hexagon/test_bitops.c | 98 +++++++++++++++++++++++++++++++++ > tests/tcg/hexagon/meson.build | 1 + > 2 files changed, 99 insertions(+) > create mode 100644 tests/tcg/hexagon/test_bitops.c > > diff --git a/tests/tcg/hexagon/test_bitops.c > b/tests/tcg/hexagon/test_bitops.c > new file mode 100644 > index 00000000000..3e9274ddddd > --- /dev/null > +++ b/tests/tcg/hexagon/test_bitops.c > @@ -0,0 +1,98 @@ > +/* > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +/* > + * Test bit interleave/deinterleave and convergent rounding. > + */ > + > +#include <stdio.h> > +#include <stdint.h> > +#include <hexagon_protos.h> > + > +int err; > + > +#include "hex_test.h" > + > +static void check_interleave(void) > +{ > + uint64_t input; > + uint64_t inter; > + uint64_t deinter; > + > + /* > + * interleave takes the 32 even bits and 32 odd bits of Rss and > + * interleaves them: even[0] goes to bit 0, odd[0] to bit 1, > + * even[1] to bit 2, odd[1] to bit 3, etc. > + * > + * Input: low 32 bits (even half), high 32 bits (odd half) > + * If low = 0xFFFFFFFF, high = 0x00000000: > + * result has every even bit set, every odd bit clear > + * = 0x5555555555555555 > + */ > + input = 0x00000000FFFFFFFFULL; > + inter = Q6_P_interleave_P(input); > + check64(inter, 0x5555555555555555ULL); > + > + /* All ones should stay all ones */ > + input = 0xFFFFFFFFFFFFFFFFULL; > + inter = Q6_P_interleave_P(input); > + check64(inter, 0xFFFFFFFFFFFFFFFFULL); > + > + /* All zeros should stay all zeros */ > + input = 0x0000000000000000ULL; > + inter = Q6_P_interleave_P(input); > + check64(inter, 0x0000000000000000ULL); > + > + /* > + * deinterleave is the inverse of interleave. > + * deinterleave(interleave(x)) should equal x. > + */ > + input = 0xDEADBEEFCAFEBABEULL; > + inter = Q6_P_interleave_P(input); > + deinter = Q6_P_deinterleave_P(inter); > + check64(deinter, input); > + > + /* deinterleave of 0x5555...5555 -> low half all 1s, high half all 0s > */ > + deinter = Q6_P_deinterleave_P(0x5555555555555555ULL); > + check64(deinter, 0x00000000FFFFFFFFULL); > +} > + > +static void check_cround(void) > +{ > + /* > + * cround(0x300, #8) -> 3 (exact shift, no rounding needed). > + * 0x300 >> 8 = 3 > + */ > + check32(Q6_R_cround_RI(0x300, 8), 3); > + > + /* > + * cround(0x380, #8) -> 4 (0x380 >> 8 = 3.5, rounds to even = 4) > + */ > + check32(Q6_R_cround_RI(0x380, 8), 4); > + > + /* > + * cround(0x280, #8) -> 2 (0x280 >> 8 = 2.5, rounds to even = 2) > + */ > + check32(Q6_R_cround_RI(0x280, 8), 2); > + > + /* > + * cround(0x3C0, #8) -> 4 (0x3C0 >> 8 = 3.75, rounds up to 4) > + */ > + check32(Q6_R_cround_RI(0x3C0, 8), 4); > + > + /* > + * Shift by 0 -> return the input unchanged. > + */ > + check32(Q6_R_cround_RI(42, 0), 42); > +} > + > +int main(void) > +{ > + check_interleave(); > + check_cround(); > + > + puts(err ? "FAIL" : "PASS"); > + return err ? 1 : 0; > +} > diff --git a/tests/tcg/hexagon/meson.build b/tests/tcg/hexagon/meson.build > index 4a2826c4276..6c8e26876af 100644 > --- a/tests/tcg/hexagon/meson.build > +++ b/tests/tcg/hexagon/meson.build > @@ -69,6 +69,7 @@ tests += { > 'test_abs.S': {'cflags': asmflags}, > 'test_bitcnt.S': {'cflags': asmflags}, > 'test_bitsplit.S': {'cflags': asmflags}, > + 'test_bitops.c': {'cflags': cflags}, > 'test_call.S': {'cflags': asmflags}, > 'test_clobber.S': {'cflags': asmflags}, > 'test_cmp.S': {'cflags': asmflags}, > -- > 2.34.1 > >
