io-readsw-armv4.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * linux/arch/arm/lib/io-readsw-armv4.S
  4. *
  5. * Copyright (C) 1995-2000 Russell King
  6. */
  7. #include <linux/linkage.h>
  8. #include <asm/assembler.h>
  9. .macro pack, rd, hw1, hw2
  10. #ifndef __ARMEB__
  11. orr \rd, \hw1, \hw2, lsl #16
  12. #else
  13. orr \rd, \hw2, \hw1, lsl #16
  14. #endif
  15. .endm
  16. .Linsw_align: movs ip, r1, lsl #31
  17. bne .Linsw_noalign
  18. ldrh ip, [r0]
  19. sub r2, r2, #1
  20. strh ip, [r1], #2
  21. ENTRY(__raw_readsw)
  22. teq r2, #0
  23. reteq lr
  24. tst r1, #3
  25. bne .Linsw_align
  26. stmfd sp!, {r4, r5, lr}
  27. subs r2, r2, #8
  28. bmi .Lno_insw_8
  29. .Linsw_8_lp: ldrh r3, [r0]
  30. ldrh r4, [r0]
  31. pack r3, r3, r4
  32. ldrh r4, [r0]
  33. ldrh r5, [r0]
  34. pack r4, r4, r5
  35. ldrh r5, [r0]
  36. ldrh ip, [r0]
  37. pack r5, r5, ip
  38. ldrh ip, [r0]
  39. ldrh lr, [r0]
  40. pack ip, ip, lr
  41. subs r2, r2, #8
  42. stmia r1!, {r3 - r5, ip}
  43. bpl .Linsw_8_lp
  44. .Lno_insw_8: tst r2, #4
  45. beq .Lno_insw_4
  46. ldrh r3, [r0]
  47. ldrh r4, [r0]
  48. pack r3, r3, r4
  49. ldrh r4, [r0]
  50. ldrh ip, [r0]
  51. pack r4, r4, ip
  52. stmia r1!, {r3, r4}
  53. .Lno_insw_4: movs r2, r2, lsl #31
  54. bcc .Lno_insw_2
  55. ldrh r3, [r0]
  56. ldrh ip, [r0]
  57. pack r3, r3, ip
  58. str r3, [r1], #4
  59. .Lno_insw_2: ldrhne r3, [r0]
  60. strhne r3, [r1]
  61. ldmfd sp!, {r4, r5, pc}
  62. #ifdef __ARMEB__
  63. #define _BE_ONLY_(code...) code
  64. #define _LE_ONLY_(code...)
  65. #define push_hbyte0 lsr #8
  66. #define pull_hbyte1 lsl #24
  67. #else
  68. #define _BE_ONLY_(code...)
  69. #define _LE_ONLY_(code...) code
  70. #define push_hbyte0 lsl #24
  71. #define pull_hbyte1 lsr #8
  72. #endif
  73. .Linsw_noalign: stmfd sp!, {r4, lr}
  74. ldrbcc ip, [r1, #-1]!
  75. bcc 1f
  76. ldrh ip, [r0]
  77. sub r2, r2, #1
  78. _BE_ONLY_( mov ip, ip, ror #8 )
  79. strb ip, [r1], #1
  80. _LE_ONLY_( mov ip, ip, lsr #8 )
  81. _BE_ONLY_( mov ip, ip, lsr #24 )
  82. 1: subs r2, r2, #2
  83. bmi 3f
  84. _BE_ONLY_( mov ip, ip, lsl #24 )
  85. 2: ldrh r3, [r0]
  86. ldrh r4, [r0]
  87. subs r2, r2, #2
  88. orr ip, ip, r3, lsl #8
  89. orr ip, ip, r4, push_hbyte0
  90. str ip, [r1], #4
  91. mov ip, r4, pull_hbyte1
  92. bpl 2b
  93. _BE_ONLY_( mov ip, ip, lsr #24 )
  94. 3: tst r2, #1
  95. strb ip, [r1], #1
  96. ldrhne ip, [r0]
  97. _BE_ONLY_( movne ip, ip, ror #8 )
  98. strbne ip, [r1], #1
  99. _LE_ONLY_( movne ip, ip, lsr #8 )
  100. _BE_ONLY_( movne ip, ip, lsr #24 )
  101. strbne ip, [r1]
  102. ldmfd sp!, {r4, pc}
  103. ENDPROC(__raw_readsw)