xref: /optee_os/core/arch/riscv/include/riscv_macros.S (revision d7b20c1ef25f6ac67c8889c4db9348fae29aaa14)
1/* SPDX-License-Identifier: BSD-2-Clause */
2/*
3 * Copyright 2022-2023 NXP
4 * Copyright (c) 2015, Linaro Limited
5 */
6
7	.altmacro
8
9
10	/*
11	 * This helper macro concatenates instr_prefix, instr_suffix, to
12	 * create a l(w,d)/s(w,d) instruction.
13	 */
14	.macro __do_reg instr_prefix, base_reg, base_offs, reg
15		\instr_prefix x\reg, \base_offs(\base_reg)
16	.endm
17
18	/*
19	 * This helper macro uses recursion to create a loop with a single
20	 * load/store.
21	 */
22	.macro _do_regs instr_prefix, reg_bytes, base_reg, base_offs, \
23			from_regnum, to_regnum
24
25		.if (\to_regnum - \from_regnum + 1) > 1
26			_do_regs \instr_prefix, \reg_bytes, \base_reg, \
27				%(\base_offs + 1 * \reg_bytes), \
28				%(\from_regnum + 1), \to_regnum
29		.endif
30
31		__do_reg \instr_prefix, \base_reg, \base_offs, \from_regnum
32	.endm
33
34	/*
35	 * Stores registers x[from_regnum]..x[to_regnum] at
36	 * [base_reg, #base_offs]
37	 */
38	.macro store_xregs base_reg, base_offs, from_regnum, to_regnum
39		_do_regs STR, RISCV_XLEN_BYTES, \base_reg, \base_offs, \
40			 \from_regnum, \to_regnum
41	.endm
42
43	/*
44	 * Loads registers x[from_regnum]..x[to_regnum] at
45	 * [base_reg, #base_offs]
46	 */
47	.macro load_xregs base_reg, base_offs, from_regnum, to_regnum
48		_do_regs LDR, RISCV_XLEN_BYTES, \base_reg, \base_offs, \
49			 \from_regnum, \to_regnum
50	.endm
51
52	/*
53	 * Multiplication macro for RISC-V harts without M extension.
54	 */
55	.macro mult, reg_op0, reg_op1, reg_res
56		li	\reg_res, 0
57		mv	a0, \reg_op0
58		mv	a1, \reg_op1
59		mv	a2, a0
60		li	a0, 0
61	1:
62		andi	a3, a1, 1
63		beqz	a3, 2f
64		add	a0, a0, a2
65	2:
66		srli	a1, a1, 1
67		slli	a2, a2, 1
68		bnez	a1, 1b
69		add	\reg_res, \reg_res, a0
70	.endm
71
72	.macro panic_at_abi_return
73#if defined(CFG_TEE_CORE_DEBUG)
74		jal	__panic_at_abi_return
75#else
76		j	.
77#endif
78	.endm
79