asm-utils.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright (C) 2015-2021 ARM Limited.
  3. // Original author: Dave Martin <[email protected]>
  4. //
  5. // Utility functions for assembly code.
  6. #include <asm/unistd.h>
  7. #include "assembler.h"
  8. // Print a single character x0 to stdout
  9. // Clobbers x0-x2,x8
  10. function putc
  11. str x0, [sp, #-16]!
  12. mov x0, #1 // STDOUT_FILENO
  13. mov x1, sp
  14. mov x2, #1
  15. mov x8, #__NR_write
  16. svc #0
  17. add sp, sp, #16
  18. ret
  19. endfunction
  20. .globl putc
  21. // Print a NUL-terminated string starting at address x0 to stdout
  22. // Clobbers x0-x3,x8
  23. function puts
  24. mov x1, x0
  25. mov x2, #0
  26. 0: ldrb w3, [x0], #1
  27. cbz w3, 1f
  28. add x2, x2, #1
  29. b 0b
  30. 1: mov w0, #1 // STDOUT_FILENO
  31. mov x8, #__NR_write
  32. svc #0
  33. ret
  34. endfunction
  35. .globl puts
  36. // Print an unsigned decimal number x0 to stdout
  37. // Clobbers x0-x4,x8
  38. function putdec
  39. mov x1, sp
  40. str x30, [sp, #-32]! // Result can't be > 20 digits
  41. mov x2, #0
  42. strb w2, [x1, #-1]! // Write the NUL terminator
  43. mov x2, #10
  44. 0: udiv x3, x0, x2 // div-mod loop to generate the digits
  45. msub x0, x3, x2, x0
  46. add w0, w0, #'0'
  47. strb w0, [x1, #-1]!
  48. mov x0, x3
  49. cbnz x3, 0b
  50. ldrb w0, [x1]
  51. cbnz w0, 1f
  52. mov w0, #'0' // Print "0" for 0, not ""
  53. strb w0, [x1, #-1]!
  54. 1: mov x0, x1
  55. bl puts
  56. ldr x30, [sp], #32
  57. ret
  58. endfunction
  59. .globl putdec
  60. // Print an unsigned decimal number x0 to stdout, followed by a newline
  61. // Clobbers x0-x5,x8
  62. function putdecn
  63. mov x5, x30
  64. bl putdec
  65. mov x0, #'\n'
  66. bl putc
  67. ret x5
  68. endfunction
  69. .globl putdecn
  70. // Clobbers x0-x3,x8
  71. function puthexb
  72. str x30, [sp, #-0x10]!
  73. mov w3, w0
  74. lsr w0, w0, #4
  75. bl puthexnibble
  76. mov w0, w3
  77. ldr x30, [sp], #0x10
  78. // fall through to puthexnibble
  79. endfunction
  80. .globl puthexb
  81. // Clobbers x0-x2,x8
  82. function puthexnibble
  83. and w0, w0, #0xf
  84. cmp w0, #10
  85. blo 1f
  86. add w0, w0, #'a' - ('9' + 1)
  87. 1: add w0, w0, #'0'
  88. b putc
  89. endfunction
  90. .globl puthexnibble
  91. // x0=data in, x1=size in, clobbers x0-x5,x8
  92. function dumphex
  93. str x30, [sp, #-0x10]!
  94. mov x4, x0
  95. mov x5, x1
  96. 0: subs x5, x5, #1
  97. b.lo 1f
  98. ldrb w0, [x4], #1
  99. bl puthexb
  100. b 0b
  101. 1: ldr x30, [sp], #0x10
  102. ret
  103. endfunction
  104. .globl dumphex
  105. // Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
  106. // Clobbers x0-x3
  107. function memcpy
  108. cmp x2, #0
  109. b.eq 1f
  110. 0: ldrb w3, [x1], #1
  111. strb w3, [x0], #1
  112. subs x2, x2, #1
  113. b.ne 0b
  114. 1: ret
  115. endfunction
  116. .globl memcpy
  117. // Fill x1 bytes starting at x0 with 0xae (for canary purposes)
  118. // Clobbers x1, x2.
  119. function memfill_ae
  120. mov w2, #0xae
  121. b memfill
  122. endfunction
  123. .globl memfill_ae
  124. // Fill x1 bytes starting at x0 with 0.
  125. // Clobbers x1, x2.
  126. function memclr
  127. mov w2, #0
  128. endfunction
  129. .globl memclr
  130. // fall through to memfill
  131. // Trivial memory fill: fill x1 bytes starting at address x0 with byte w2
  132. // Clobbers x1
  133. function memfill
  134. cmp x1, #0
  135. b.eq 1f
  136. 0: strb w2, [x0], #1
  137. subs x1, x1, #1
  138. b.ne 0b
  139. 1: ret
  140. endfunction
  141. .globl memfill