Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 // Copyright (C) 2015-2021 ARM Limited.
0003 // Original author: Dave Martin <Dave.Martin@arm.com>
0004 //
0005 // Utility functions for assembly code.
0006 
0007 #include <asm/unistd.h>
0008 #include "assembler.h"
0009 
0010 // Print a single character x0 to stdout
0011 // Clobbers x0-x2,x8
0012 function putc
0013     str x0, [sp, #-16]!
0014 
0015     mov x0, #1          // STDOUT_FILENO
0016     mov x1, sp
0017     mov x2, #1
0018     mov x8, #__NR_write
0019     svc #0
0020 
0021     add sp, sp, #16
0022     ret
0023 endfunction
0024 .globl  putc
0025     
0026 // Print a NUL-terminated string starting at address x0 to stdout
0027 // Clobbers x0-x3,x8
0028 function puts
0029     mov x1, x0
0030 
0031     mov x2, #0
0032 0:  ldrb    w3, [x0], #1
0033     cbz w3, 1f
0034     add x2, x2, #1
0035     b   0b
0036 
0037 1:  mov w0, #1          // STDOUT_FILENO
0038     mov x8, #__NR_write
0039     svc #0
0040 
0041     ret
0042 endfunction
0043 .globl  puts
0044 
0045 // Print an unsigned decimal number x0 to stdout
0046 // Clobbers x0-x4,x8
0047 function putdec
0048     mov x1, sp
0049     str x30, [sp, #-32]!    // Result can't be > 20 digits
0050 
0051     mov x2, #0
0052     strb    w2, [x1, #-1]!      // Write the NUL terminator
0053 
0054     mov x2, #10
0055 0:  udiv    x3, x0, x2      // div-mod loop to generate the digits
0056     msub    x0, x3, x2, x0
0057     add w0, w0, #'0'
0058     strb    w0, [x1, #-1]!
0059     mov x0, x3
0060     cbnz    x3, 0b
0061 
0062     ldrb    w0, [x1]
0063     cbnz    w0, 1f
0064     mov w0, #'0'        // Print "0" for 0, not ""
0065     strb    w0, [x1, #-1]!
0066 
0067 1:  mov x0, x1
0068     bl  puts
0069 
0070     ldr x30, [sp], #32
0071     ret
0072 endfunction
0073 .globl  putdec
0074 
0075 // Print an unsigned decimal number x0 to stdout, followed by a newline
0076 // Clobbers x0-x5,x8
0077 function putdecn
0078     mov x5, x30
0079 
0080     bl  putdec
0081     mov x0, #'\n'
0082     bl  putc
0083 
0084     ret x5
0085 endfunction
0086 .globl  putdecn
0087 
0088 // Clobbers x0-x3,x8
0089 function puthexb
0090     str x30, [sp, #-0x10]!
0091 
0092     mov w3, w0
0093     lsr w0, w0, #4
0094     bl  puthexnibble
0095     mov w0, w3
0096 
0097     ldr x30, [sp], #0x10
0098     // fall through to puthexnibble
0099 endfunction
0100 .globl  puthexb
0101 
0102 // Clobbers x0-x2,x8
0103 function puthexnibble
0104     and w0, w0, #0xf
0105     cmp w0, #10
0106     blo 1f
0107     add w0, w0, #'a' - ('9' + 1)
0108 1:  add w0, w0, #'0'
0109     b   putc
0110 endfunction
0111 .globl  puthexnibble
0112 
0113 // x0=data in, x1=size in, clobbers x0-x5,x8
0114 function dumphex
0115     str x30, [sp, #-0x10]!
0116 
0117     mov x4, x0
0118     mov x5, x1
0119 
0120 0:  subs    x5, x5, #1
0121     b.lo    1f
0122     ldrb    w0, [x4], #1
0123     bl  puthexb
0124     b   0b
0125 
0126 1:  ldr x30, [sp], #0x10
0127     ret
0128 endfunction
0129 .globl  dumphex
0130 
0131     // Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
0132 // Clobbers x0-x3
0133 function memcpy
0134     cmp x2, #0
0135     b.eq    1f
0136 0:  ldrb    w3, [x1], #1
0137     strb    w3, [x0], #1
0138     subs    x2, x2, #1
0139     b.ne    0b
0140 1:  ret
0141 endfunction
0142 .globl  memcpy
0143 
0144 // Fill x1 bytes starting at x0 with 0xae (for canary purposes)
0145 // Clobbers x1, x2.
0146 function memfill_ae
0147     mov w2, #0xae
0148     b   memfill
0149 endfunction
0150 .globl  memfill_ae
0151     
0152 // Fill x1 bytes starting at x0 with 0.
0153 // Clobbers x1, x2.
0154 function memclr
0155     mov w2, #0
0156 endfunction
0157 .globl  memclr
0158     // fall through to memfill
0159 
0160 // Trivial memory fill: fill x1 bytes starting at address x0 with byte w2
0161 // Clobbers x1
0162 function memfill
0163     cmp x1, #0
0164     b.eq    1f
0165 
0166 0:  strb    w2, [x0], #1
0167     subs    x1, x1, #1
0168     b.ne    0b
0169 
0170 1:  ret
0171 endfunction
0172 .globl  memfill