io-readsw-armv4.S 2.3 KB

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