c++ - 返回 ARM NEON 下的 Z 标志

标签 c++ gcc arm clang neon

我有一个 NEON 函数在做一些比较:

inline bool all_ones(int32x4_t v) noexcept
{
  v = ~v;

  ::std::uint32_t r;

  auto high(vget_high_s32(int32x4_t(v)));
  auto low(vget_low_s32(int32x4_t(v)));

  asm volatile ("VSLI.I32 %0, %1, #16" : "+w"(high), "+w"(low));
  asm volatile ("VCMP.F64 %0, #0" : "=w"(high));
  asm volatile ("VMRS %0, FPSCR" : "=r"(r) : "w"(high));

  return r & (1 << 30);
}

v 的组件(4 个整数)只能全为 1 或全为 0。如果所有 4 个组件都是 1,则函数返回 true,否则返回 false。返回部分扩展为 3 条指令,这对我来说很多。有没有更好的方法来返回 Z 标志?

编辑:经过长时间的苦思冥想,上面的内容可以被替换为:

inline bool all_ones(int32x4_t const v) noexcept
{
  return int32_t(-1) == int32x2_t(
    vtbl2_s8(
      int8x8x2_t{
        int8x8_t(vget_low_s32(int32x4_t(v))),
        int8x8_t(vget_high_s32(int32x4_t(v)))
      },
      int8x8_t{0, 4, 8, 12}
    )
  )[0];
}

NEON中存在掩码提取指令。

最佳答案

如果可以避免,您真的不想将 NEON 与 VFP 混合使用。

我建议:

bool all_ones(int32x4_t v) {
    int32x2_t l = vget_low_s32(v), h = vget_high_s32(v);
    uint32x2_t m = vpmin_u32(vreinterpret_u32_s32(l),
                             vreinterpret_u32_s32(h));
    m = vpmin_u32(m, m);
    return vget_lane_u32(m, 0) == 0xffffffff;
}

如果您真的确定唯一的非零值将是 0xffffffff,那么您可以放弃比较。独立编译它可能有几个不必要的操作,但是当它被内联时编译器应该修复它。

关于c++ - 返回 ARM NEON 下的 Z 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29832175/

相关文章:

c++ - 获取非静态方法参数计数

c++ - OpenMP 仅使用一个线程

iphone - 使用适用于 ARM7 的 OCI

arm - 带有可重定位代码的静态局部变量的问题

c - Atmel Cortex-M0+ SAMC21 在 SysTick_Config 之后挂起

c++ - 在 CPP 中运行 tensorflow 模型

c++ - 在面向对象的 C++ 中处理大数字变量

c++ - 多重继承使私有(private)成员可访问

c++ - 包装 PropertySheet;如何处理回调?

GCC 内部结构 : Where are fake dereferences removed?