1*584ea656SEvan Green/* SPDX-License-Identifier: GPL-2.0 */
2*584ea656SEvan Green/* Copyright (C) 2023 Rivos Inc. */
3*584ea656SEvan Green
4*584ea656SEvan Green#include <linux/linkage.h>
5*584ea656SEvan Green#include <asm/asm.h>
6*584ea656SEvan Green
7*584ea656SEvan Green	.text
8*584ea656SEvan Green
9*584ea656SEvan Green/* void __riscv_copy_words_unaligned(void *, const void *, size_t) */
10*584ea656SEvan Green/* Performs a memcpy without aligning buffers, using word loads and stores. */
11*584ea656SEvan Green/* Note: The size is truncated to a multiple of 8 * SZREG */
12*584ea656SEvan GreenENTRY(__riscv_copy_words_unaligned)
13*584ea656SEvan Green	andi  a4, a2, ~((8*SZREG)-1)
14*584ea656SEvan Green	beqz  a4, 2f
15*584ea656SEvan Green	add   a3, a1, a4
16*584ea656SEvan Green1:
17*584ea656SEvan Green	REG_L a4,       0(a1)
18*584ea656SEvan Green	REG_L a5,   SZREG(a1)
19*584ea656SEvan Green	REG_L a6, 2*SZREG(a1)
20*584ea656SEvan Green	REG_L a7, 3*SZREG(a1)
21*584ea656SEvan Green	REG_L t0, 4*SZREG(a1)
22*584ea656SEvan Green	REG_L t1, 5*SZREG(a1)
23*584ea656SEvan Green	REG_L t2, 6*SZREG(a1)
24*584ea656SEvan Green	REG_L t3, 7*SZREG(a1)
25*584ea656SEvan Green	REG_S a4,       0(a0)
26*584ea656SEvan Green	REG_S a5,   SZREG(a0)
27*584ea656SEvan Green	REG_S a6, 2*SZREG(a0)
28*584ea656SEvan Green	REG_S a7, 3*SZREG(a0)
29*584ea656SEvan Green	REG_S t0, 4*SZREG(a0)
30*584ea656SEvan Green	REG_S t1, 5*SZREG(a0)
31*584ea656SEvan Green	REG_S t2, 6*SZREG(a0)
32*584ea656SEvan Green	REG_S t3, 7*SZREG(a0)
33*584ea656SEvan Green	addi  a0, a0, 8*SZREG
34*584ea656SEvan Green	addi  a1, a1, 8*SZREG
35*584ea656SEvan Green	bltu  a1, a3, 1b
36*584ea656SEvan Green
37*584ea656SEvan Green2:
38*584ea656SEvan Green	ret
39*584ea656SEvan GreenEND(__riscv_copy_words_unaligned)
40*584ea656SEvan Green
41*584ea656SEvan Green/* void __riscv_copy_bytes_unaligned(void *, const void *, size_t) */
42*584ea656SEvan Green/* Performs a memcpy without aligning buffers, using only byte accesses. */
43*584ea656SEvan Green/* Note: The size is truncated to a multiple of 8 */
44*584ea656SEvan GreenENTRY(__riscv_copy_bytes_unaligned)
45*584ea656SEvan Green	andi a4, a2, ~(8-1)
46*584ea656SEvan Green	beqz a4, 2f
47*584ea656SEvan Green	add  a3, a1, a4
48*584ea656SEvan Green1:
49*584ea656SEvan Green	lb   a4, 0(a1)
50*584ea656SEvan Green	lb   a5, 1(a1)
51*584ea656SEvan Green	lb   a6, 2(a1)
52*584ea656SEvan Green	lb   a7, 3(a1)
53*584ea656SEvan Green	lb   t0, 4(a1)
54*584ea656SEvan Green	lb   t1, 5(a1)
55*584ea656SEvan Green	lb   t2, 6(a1)
56*584ea656SEvan Green	lb   t3, 7(a1)
57*584ea656SEvan Green	sb   a4, 0(a0)
58*584ea656SEvan Green	sb   a5, 1(a0)
59*584ea656SEvan Green	sb   a6, 2(a0)
60*584ea656SEvan Green	sb   a7, 3(a0)
61*584ea656SEvan Green	sb   t0, 4(a0)
62*584ea656SEvan Green	sb   t1, 5(a0)
63*584ea656SEvan Green	sb   t2, 6(a0)
64*584ea656SEvan Green	sb   t3, 7(a0)
65*584ea656SEvan Green	addi a0, a0, 8
66*584ea656SEvan Green	addi a1, a1, 8
67*584ea656SEvan Green	bltu a1, a3, 1b
68*584ea656SEvan Green
69*584ea656SEvan Green2:
70*584ea656SEvan Green	ret
71*584ea656SEvan GreenEND(__riscv_copy_bytes_unaligned)
72