xref: /linux/arch/riscv/kernel/vec-copy-unaligned.S (revision a2e5b58811c7bb7d63f366f586cc7317f20e62e7)
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2024 Rivos Inc. */
3
4#include <linux/args.h>
5#include <linux/cfi_types.h>
6#include <linux/linkage.h>
7#include <asm/asm.h>
8
9	.text
10
11#define WORD_EEW 32
12
13#define WORD_SEW CONCATENATE(e, WORD_EEW)
14#define VEC_L CONCATENATE(vle, WORD_EEW).v
15#define VEC_S CONCATENATE(vse, WORD_EEW).v
16
17/* void __riscv_copy_vec_words_unaligned(void *, const void *, size_t) */
18/* Performs a memcpy without aligning buffers, using word loads and stores. */
19/* Note: The size is truncated to a multiple of WORD_EEW */
20SYM_TYPED_FUNC_START(__riscv_copy_vec_words_unaligned)
21	andi  a4, a2, ~(WORD_EEW-1)
22	beqz  a4, 2f
23	add   a3, a1, a4
24	.option push
25	.option arch, +zve32x
261:
27	vsetivli t0, 8, WORD_SEW, m8, ta, ma
28	VEC_L v0, (a1)
29	VEC_S v0, (a0)
30	addi  a0, a0, WORD_EEW
31	addi  a1, a1, WORD_EEW
32	bltu  a1, a3, 1b
33
342:
35	.option pop
36	ret
37SYM_FUNC_END(__riscv_copy_vec_words_unaligned)
38
39/* void __riscv_copy_vec_bytes_unaligned(void *, const void *, size_t) */
40/* Performs a memcpy without aligning buffers, using only byte accesses. */
41/* Note: The size is truncated to a multiple of 8 */
42SYM_TYPED_FUNC_START(__riscv_copy_vec_bytes_unaligned)
43	andi a4, a2, ~(8-1)
44	beqz a4, 2f
45	add  a3, a1, a4
46	.option push
47	.option arch, +zve32x
481:
49	vsetivli t0, 8, e8, m8, ta, ma
50	vle8.v v0, (a1)
51	vse8.v v0, (a0)
52	addi a0, a0, 8
53	addi a1, a1, 8
54	bltu a1, a3, 1b
55
562:
57	.option pop
58	ret
59SYM_FUNC_END(__riscv_copy_vec_bytes_unaligned)
60