brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 66d2437 Raw
116 lines · c
1//===-- Bcmp implementation for aarch64 -------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8#ifndef LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H9#define LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H10 11#include "src/__support/macros/attributes.h"   // LIBC_INLINE12#include "src/__support/macros/config.h"       // LIBC_NAMESPACE_DECL13#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY14#include "src/string/memory_utils/op_aarch64.h"15#include "src/string/memory_utils/op_generic.h"16#include "src/string/memory_utils/utils.h" // Ptr, CPtr17 18#include <stddef.h> // size_t19 20namespace LIBC_NAMESPACE_DECL {21 22[[maybe_unused]] LIBC_INLINE BcmpReturnType23inline_bcmp_aarch64_no_fp(CPtr p1, CPtr p2, size_t count) {24  if (LIBC_LIKELY(count < 16)) {25    switch (count) {26    case 0:27      return BcmpReturnType::zero();28    case 1:29      return generic::Bcmp<uint8_t>::block(p1, p2);30    case 2:31      return generic::Bcmp<uint16_t>::block(p1, p2);32    case 3:33      return generic::Bcmp<uint16_t>::head_tail(p1, p2, count);34    case 4:35      return generic::Bcmp<uint32_t>::block(p1, p2);36    case 5:37    case 6:38    case 7:39      return generic::Bcmp<uint32_t>::head_tail(p1, p2, count);40    case 8:41      return generic::Bcmp<uint64_t>::block(p1, p2);42    case 9:43    case 10:44    case 11:45    case 12:46    case 13:47    case 14:48    case 15:49      return generic::Bcmp<uint64_t>::head_tail(p1, p2, count);50    }51  }52 53  return generic::Bcmp<uint64_t>::loop_and_tail_align_above(256, p1, p2, count);54}55 56#ifdef __ARM_NEON57[[maybe_unused]] LIBC_INLINE BcmpReturnType58inline_bcmp_aarch64_with_fp(CPtr p1, CPtr p2, size_t count) {59  if (LIBC_LIKELY(count <= 32)) {60    if (LIBC_UNLIKELY(count >= 16)) {61      return aarch64::Bcmp<16>::head_tail(p1, p2, count);62    }63    switch (count) {64    case 0:65      return BcmpReturnType::zero();66    case 1:67      return generic::Bcmp<uint8_t>::block(p1, p2);68    case 2:69      return generic::Bcmp<uint16_t>::block(p1, p2);70    case 3:71      return generic::Bcmp<uint16_t>::head_tail(p1, p2, count);72    case 4:73      return generic::Bcmp<uint32_t>::block(p1, p2);74    case 5:75    case 6:76    case 7:77      return generic::Bcmp<uint32_t>::head_tail(p1, p2, count);78    case 8:79      return generic::Bcmp<uint64_t>::block(p1, p2);80    case 9:81    case 10:82    case 11:83    case 12:84    case 13:85    case 14:86    case 15:87      return generic::Bcmp<uint64_t>::head_tail(p1, p2, count);88    }89  }90 91  if (count <= 64)92    return aarch64::Bcmp<32>::head_tail(p1, p2, count);93 94  // Aligned loop if > 256, otherwise normal loop95  if (LIBC_UNLIKELY(count > 256)) {96    if (auto value = aarch64::Bcmp<32>::block(p1, p2))97      return value;98    align_to_next_boundary<16, Arg::P1>(p1, p2, count);99  }100  return aarch64::Bcmp<32>::loop_and_tail(p1, p2, count);101}102#endif103 104[[gnu::flatten]] LIBC_INLINE BcmpReturnType105inline_bcmp_aarch64_dispatch(CPtr p1, CPtr p2, size_t count) {106#if defined(__ARM_NEON)107  return inline_bcmp_aarch64_with_fp(p1, p2, count);108#else109  return inline_bcmp_aarch64_no_fp(p1, p2, count);110#endif111}112 113} // namespace LIBC_NAMESPACE_DECL114 115#endif // LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H116