nuttx/libs/libc/machine/risc-v/gnu/arch_memcpy.S
Tiago Medicci Serrano 58e97e521c libc/string: prevent libc in the kernel/userspace optionally
Add the `LIBC_PREVENT_STRING_KERNEL` and `LIBC_PREVENT_STRING_USER`
that are meant to be selected by the chip if no libc implementation
is going to be built. If selected, neither NuttX's software version
of the libc nor any architecture-specific implementation will be
built in the kernel or in the userspace, respectively. In this
case, the linker may provide a ROM-defined version of the libc
functions instead.
2023-05-17 13:58:48 +08:00

141 lines
3.3 KiB
ArmAsm

/****************************************************************************
* libs/libc/machine/risc-v/gnu/arch_memcpy.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include "libc.h"
#ifdef LIBC_BUILD_STRING
/************************************************************************************
* Public Symbols
************************************************************************************/
.globl memcpy
.file "arch_memcpy.S"
/************************************************************************************
* Name: memcpy
************************************************************************************/
.text
memcpy:
move t6, a0 /* Preserve return value */
/* Defer to byte-oriented copy for small sizes */
sltiu a3, a2, 128
bnez a3, 4f
/* Use word-oriented copy only if low-order bits match */
andi a3, t6, 3
andi a4, a1, 3
bne a3, a4, 4f
beqz a3, 2f /* Skip if already aligned */
/*
* Round to nearest double word-aligned address
* greater than or equal to start address
*/
andi a3, a1, ~3
addi a3, a3, 4
/* Handle initial misalignment */
sub a4, a3, a1
1:
lb a5, 0(a1)
addi a1, a1, 1
sb a5, 0(t6)
addi t6, t6, 1
bltu a1, a3, 1b
sub a2, a2, a4 /* Update count */
2:
andi a4, a2, ~63
beqz a4, 4f
add a3, a1, a4
3:
lw a4, 0(a1)
lw a5, 4(a1)
lw a6, 2*4(a1)
lw a7, 3*4(a1)
lw t0, 4*4(a1)
lw t1, 5*4(a1)
lw t2, 6*4(a1)
lw t3, 7*4(a1)
lw t4, 8*4(a1)
lw t5, 9*4(a1)
sw a4, 0(t6)
sw a5, 4(t6)
sw a6, 2*4(t6)
sw a7, 3*4(t6)
sw t0, 4*4(t6)
sw t1, 5*4(t6)
sw t2, 6*4(t6)
sw t3, 7*4(t6)
sw t4, 8*4(t6)
sw t5, 9*4(t6)
lw a4, 10*4(a1)
lw a5, 11*4(a1)
lw a6, 12*4(a1)
lw a7, 13*4(a1)
lw t0, 14*4(a1)
lw t1, 15*4(a1)
addi a1, a1, 16*4
sw a4, 10*4(t6)
sw a5, 11*4(t6)
sw a6, 12*4(t6)
sw a7, 13*4(t6)
sw t0, 14*4(t6)
sw t1, 15*4(t6)
addi t6, t6, 16*4
bltu a1, a3, 3b
andi a2, a2, 63 /* Update count */
4:
/* Handle trailing misalignment */
beqz a2, 6f
add a3, a1, a2
/* Use word-oriented copy if co-aligned to word boundary */
or a5, a1, t6
or a5, a5, a3
andi a5, a5, 3
bnez a5, 5f
7:
lw a4, 0(a1)
addi a1, a1, 4
sw a4, 0(t6)
addi t6, t6, 4
bltu a1, a3, 7b
ret
5:
lb a4, 0(a1)
addi a1, a1, 1
sb a4, 0(t6)
addi t6, t6, 1
bltu a1, a3, 5b
6:
ret
#endif