io-readsw-armv4.S 2.4 KB

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