xor.c 2.8 KB

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