xor.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Optimized xor_block operation for RAID4/5
  4. *
  5. * Copyright IBM Corp. 2016
  6. * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  7. */
  8. #include <linux/types.h>
  9. #include <linux/export.h>
  10. #include <linux/raid/xor.h>
  11. static void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
  12. {
  13. asm volatile(
  14. " larl 1,2f\n"
  15. " aghi %0,-1\n"
  16. " jm 3f\n"
  17. " srlg 0,%0,8\n"
  18. " ltgr 0,0\n"
  19. " jz 1f\n"
  20. "0: xc 0(256,%1),0(%2)\n"
  21. " la %1,256(%1)\n"
  22. " la %2,256(%2)\n"
  23. " brctg 0,0b\n"
  24. "1: ex %0,0(1)\n"
  25. " j 3f\n"
  26. "2: xc 0(1,%1),0(%2)\n"
  27. "3:\n"
  28. : : "d" (bytes), "a" (p1), "a" (p2)
  29. : "0", "1", "cc", "memory");
  30. }
  31. static void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
  32. unsigned long *p3)
  33. {
  34. asm volatile(
  35. " larl 1,2f\n"
  36. " aghi %0,-1\n"
  37. " jm 3f\n"
  38. " srlg 0,%0,8\n"
  39. " ltgr 0,0\n"
  40. " jz 1f\n"
  41. "0: xc 0(256,%1),0(%2)\n"
  42. " xc 0(256,%1),0(%3)\n"
  43. " la %1,256(%1)\n"
  44. " la %2,256(%2)\n"
  45. " la %3,256(%3)\n"
  46. " brctg 0,0b\n"
  47. "1: ex %0,0(1)\n"
  48. " ex %0,6(1)\n"
  49. " j 3f\n"
  50. "2: xc 0(1,%1),0(%2)\n"
  51. " xc 0(1,%1),0(%3)\n"
  52. "3:\n"
  53. : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
  54. : : "0", "1", "cc", "memory");
  55. }
  56. static void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
  57. unsigned long *p3, unsigned long *p4)
  58. {
  59. asm volatile(
  60. " larl 1,2f\n"
  61. " aghi %0,-1\n"
  62. " jm 3f\n"
  63. " srlg 0,%0,8\n"
  64. " ltgr 0,0\n"
  65. " jz 1f\n"
  66. "0: xc 0(256,%1),0(%2)\n"
  67. " xc 0(256,%1),0(%3)\n"
  68. " xc 0(256,%1),0(%4)\n"
  69. " la %1,256(%1)\n"
  70. " la %2,256(%2)\n"
  71. " la %3,256(%3)\n"
  72. " la %4,256(%4)\n"
  73. " brctg 0,0b\n"
  74. "1: ex %0,0(1)\n"
  75. " ex %0,6(1)\n"
  76. " ex %0,12(1)\n"
  77. " j 3f\n"
  78. "2: xc 0(1,%1),0(%2)\n"
  79. " xc 0(1,%1),0(%3)\n"
  80. " xc 0(1,%1),0(%4)\n"
  81. "3:\n"
  82. : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
  83. : : "0", "1", "cc", "memory");
  84. }
  85. static void xor_xc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
  86. unsigned long *p3, unsigned long *p4, unsigned long *p5)
  87. {
  88. /* Get around a gcc oddity */
  89. register unsigned long *reg7 asm ("7") = p5;
  90. asm volatile(
  91. " larl 1,2f\n"
  92. " aghi %0,-1\n"
  93. " jm 3f\n"
  94. " srlg 0,%0,8\n"
  95. " ltgr 0,0\n"
  96. " jz 1f\n"
  97. "0: xc 0(256,%1),0(%2)\n"
  98. " xc 0(256,%1),0(%3)\n"
  99. " xc 0(256,%1),0(%4)\n"
  100. " xc 0(256,%1),0(%5)\n"
  101. " la %1,256(%1)\n"
  102. " la %2,256(%2)\n"
  103. " la %3,256(%3)\n"
  104. " la %4,256(%4)\n"
  105. " la %5,256(%5)\n"
  106. " brctg 0,0b\n"
  107. "1: ex %0,0(1)\n"
  108. " ex %0,6(1)\n"
  109. " ex %0,12(1)\n"
  110. " ex %0,18(1)\n"
  111. " j 3f\n"
  112. "2: xc 0(1,%1),0(%2)\n"
  113. " xc 0(1,%1),0(%3)\n"
  114. " xc 0(1,%1),0(%4)\n"
  115. " xc 0(1,%1),0(%5)\n"
  116. "3:\n"
  117. : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
  118. "+a" (reg7)
  119. : : "0", "1", "cc", "memory");
  120. }
  121. struct xor_block_template xor_block_xc = {
  122. .name = "xc",
  123. .do_2 = xor_xc_2,
  124. .do_3 = xor_xc_3,
  125. .do_4 = xor_xc_4,
  126. .do_5 = xor_xc_5,
  127. };
  128. EXPORT_SYMBOL(xor_block_xc);