Misc.s 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. @ vim:filetype=armasm
  2. @ Generic memory routines.
  3. @ (c) Copyright 2007, Grazvydas "notaz" Ignotas
  4. .global memcpy16 @ unsigned short *dest, unsigned short *src, int count
  5. memcpy16:
  6. eor r3, r0, r1
  7. tst r3, #2
  8. bne mcp16_cant_align
  9. tst r0, #2
  10. ldrneh r3, [r1], #2
  11. subne r2, r2, #1
  12. strneh r3, [r0], #2
  13. subs r2, r2, #4
  14. bmi mcp16_fin
  15. mcp16_loop:
  16. ldmia r1!, {r3,r12}
  17. subs r2, r2, #4
  18. stmia r0!, {r3,r12}
  19. bpl mcp16_loop
  20. mcp16_fin:
  21. tst r2, #2
  22. ldrne r3, [r1], #4
  23. strne r3, [r0], #4
  24. ands r2, r2, #1
  25. bxeq lr
  26. mcp16_cant_align:
  27. ldrh r3, [r1], #2
  28. subs r2, r2, #1
  29. strh r3, [r0], #2
  30. bne mcp16_cant_align
  31. bx lr
  32. @ 0x12345678 -> 0x34127856
  33. @ r4=temp, lr=0x00ff00ff
  34. .macro bswap reg
  35. and r4, \reg, lr
  36. and \reg, lr, \reg, lsr #8
  37. orr \reg, \reg, r4, lsl #8
  38. .endm
  39. @ dest must be halfword aligned, src can be unaligned
  40. .global memcpy16bswap @ unsigned short *dest, void *src, int count
  41. memcpy16bswap:
  42. tst r1, #1
  43. bne mcp16bs_cant_align2
  44. eor r3, r0, r1
  45. tst r3, #2
  46. bne mcp16bs_cant_align
  47. tst r0, #2
  48. beq mcp16bs_aligned
  49. ldrh r3, [r1], #2
  50. sub r2, r2, #1
  51. orr r3, r3, r3, lsl #16
  52. mov r3, r3, lsr #8
  53. strh r3, [r0], #2
  54. mcp16bs_aligned:
  55. stmfd sp!, {r4,lr}
  56. mov lr, #0xff
  57. orr lr, lr, lr, lsl #16
  58. subs r2, r2, #4
  59. bmi mcp16bs_fin4
  60. mcp16bs_loop:
  61. ldmia r1!, {r3,r12}
  62. subs r2, r2, #4
  63. bswap r3
  64. bswap r12
  65. stmia r0!, {r3,r12}
  66. bpl mcp16bs_loop
  67. mcp16bs_fin4:
  68. tst r2, #2
  69. beq mcp16bs_fin2
  70. ldr r3, [r1], #4
  71. bswap r3
  72. str r3, [r0], #4
  73. mcp16bs_fin2:
  74. ldmfd sp!, {r4,lr}
  75. ands r2, r2, #1
  76. bxeq lr
  77. mcp16bs_cant_align:
  78. ldrh r3, [r1], #2
  79. subs r2, r2, #1
  80. orr r3, r3, r3, lsl #16
  81. mov r3, r3, lsr #8
  82. strh r3, [r0], #2
  83. bne mcp16bs_cant_align
  84. bx lr
  85. @ worst case
  86. mcp16bs_cant_align2:
  87. ldrb r3, [r1], #1
  88. ldrb r12,[r1], #1
  89. subs r2, r2, #1
  90. mov r3, r3, lsl #8
  91. orr r3, r3, r12
  92. strh r3, [r0], #2
  93. bne mcp16bs_cant_align2
  94. bx lr
  95. .global memcpy32 @ int *dest, int *src, int count
  96. memcpy32:
  97. stmfd sp!, {r4,lr}
  98. subs r2, r2, #4
  99. bmi mcp32_fin
  100. mcp32_loop:
  101. ldmia r1!, {r3,r4,r12,lr}
  102. subs r2, r2, #4
  103. stmia r0!, {r3,r4,r12,lr}
  104. bpl mcp32_loop
  105. mcp32_fin:
  106. tst r2, #3
  107. ldmeqfd sp!, {r4,pc}
  108. tst r2, #1
  109. ldrne r3, [r1], #4
  110. strne r3, [r0], #4
  111. mcp32_no_unal1:
  112. tst r2, #2
  113. ldmneia r1!, {r3,r12}
  114. ldmfd sp!, {r4,lr}
  115. stmneia r0!, {r3,r12}
  116. bx lr
  117. .global memset32 @ int *dest, int c, int count
  118. memset32:
  119. stmfd sp!, {lr}
  120. mov r3, r1
  121. subs r2, r2, #4
  122. bmi mst32_fin
  123. mov r12,r1
  124. mov lr, r1
  125. mst32_loop:
  126. subs r2, r2, #4
  127. stmia r0!, {r1,r3,r12,lr}
  128. bpl mst32_loop
  129. mst32_fin:
  130. tst r2, #1
  131. strne r1, [r0], #4
  132. tst r2, #2
  133. stmneia r0!, {r1,r3}
  134. ldmfd sp!, {lr}
  135. bx lr