neon.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/lib/raid6/neon.c - RAID6 syndrome calculation using ARM NEON intrinsics
  4. *
  5. * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  6. */
  7. #include <linux/raid/pq.h>
  8. #ifdef __KERNEL__
  9. #include <asm/simd.h>
  10. #else
  11. #define scoped_ksimd()
  12. #define cpu_has_neon() (1)
  13. #endif
  14. /*
  15. * There are 2 reasons these wrappers are kept in a separate compilation unit
  16. * from the actual implementations in neonN.c (generated from neon.uc by
  17. * unroll.awk):
  18. * - the actual implementations use NEON intrinsics, and the GCC support header
  19. * (arm_neon.h) is not fully compatible (type wise) with the kernel;
  20. * - the neonN.c files are compiled with -mfpu=neon and optimization enabled,
  21. * and we have to make sure that we never use *any* NEON/VFP instructions
  22. * outside a kernel_neon_begin()/kernel_neon_end() pair.
  23. */
  24. #define RAID6_NEON_WRAPPER(_n) \
  25. static void raid6_neon ## _n ## _gen_syndrome(int disks, \
  26. size_t bytes, void **ptrs) \
  27. { \
  28. void raid6_neon ## _n ## _gen_syndrome_real(int, \
  29. unsigned long, void**); \
  30. scoped_ksimd() \
  31. raid6_neon ## _n ## _gen_syndrome_real(disks, \
  32. (unsigned long)bytes, ptrs); \
  33. } \
  34. static void raid6_neon ## _n ## _xor_syndrome(int disks, \
  35. int start, int stop, \
  36. size_t bytes, void **ptrs) \
  37. { \
  38. void raid6_neon ## _n ## _xor_syndrome_real(int, \
  39. int, int, unsigned long, void**); \
  40. scoped_ksimd() \
  41. raid6_neon ## _n ## _xor_syndrome_real(disks, \
  42. start, stop, (unsigned long)bytes, ptrs);\
  43. } \
  44. struct raid6_calls const raid6_neonx ## _n = { \
  45. raid6_neon ## _n ## _gen_syndrome, \
  46. raid6_neon ## _n ## _xor_syndrome, \
  47. raid6_have_neon, \
  48. "neonx" #_n, \
  49. 0 \
  50. }
  51. static int raid6_have_neon(void)
  52. {
  53. return cpu_has_neon();
  54. }
  55. RAID6_NEON_WRAPPER(1);
  56. RAID6_NEON_WRAPPER(2);
  57. RAID6_NEON_WRAPPER(4);
  58. RAID6_NEON_WRAPPER(8);