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 173