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