neon.c 1.7 KB

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