xref: /optee_os/core/arch/riscv/include/riscv_macros.S (revision d7b20c1ef25f6ac67c8889c4db9348fae29aaa14)
1ef501733SMarouene Boubakri/* SPDX-License-Identifier: BSD-2-Clause */
2ef501733SMarouene Boubakri/*
3643a0582SMarouene Boubakri * Copyright 2022-2023 NXP
4643a0582SMarouene Boubakri * Copyright (c) 2015, Linaro Limited
5ef501733SMarouene Boubakri */
6ef501733SMarouene Boubakri
7ef501733SMarouene Boubakri	.altmacro
8643a0582SMarouene Boubakri
9643a0582SMarouene Boubakri
10643a0582SMarouene Boubakri	/*
11643a0582SMarouene Boubakri	 * This helper macro concatenates instr_prefix, instr_suffix, to
12643a0582SMarouene Boubakri	 * create a l(w,d)/s(w,d) instruction.
13643a0582SMarouene Boubakri	 */
14643a0582SMarouene Boubakri	.macro __do_reg instr_prefix, base_reg, base_offs, reg
15643a0582SMarouene Boubakri		\instr_prefix x\reg, \base_offs(\base_reg)
16643a0582SMarouene Boubakri	.endm
17643a0582SMarouene Boubakri
18643a0582SMarouene Boubakri	/*
19643a0582SMarouene Boubakri	 * This helper macro uses recursion to create a loop with a single
20643a0582SMarouene Boubakri	 * load/store.
21643a0582SMarouene Boubakri	 */
22643a0582SMarouene Boubakri	.macro _do_regs instr_prefix, reg_bytes, base_reg, base_offs, \
23643a0582SMarouene Boubakri			from_regnum, to_regnum
24643a0582SMarouene Boubakri
25643a0582SMarouene Boubakri		.if (\to_regnum - \from_regnum + 1) > 1
26643a0582SMarouene Boubakri			_do_regs \instr_prefix, \reg_bytes, \base_reg, \
27643a0582SMarouene Boubakri				%(\base_offs + 1 * \reg_bytes), \
28643a0582SMarouene Boubakri				%(\from_regnum + 1), \to_regnum
29643a0582SMarouene Boubakri		.endif
30643a0582SMarouene Boubakri
31643a0582SMarouene Boubakri		__do_reg \instr_prefix, \base_reg, \base_offs, \from_regnum
32643a0582SMarouene Boubakri	.endm
33643a0582SMarouene Boubakri
34643a0582SMarouene Boubakri	/*
35643a0582SMarouene Boubakri	 * Stores registers x[from_regnum]..x[to_regnum] at
36643a0582SMarouene Boubakri	 * [base_reg, #base_offs]
37643a0582SMarouene Boubakri	 */
38643a0582SMarouene Boubakri	.macro store_xregs base_reg, base_offs, from_regnum, to_regnum
39643a0582SMarouene Boubakri		_do_regs STR, RISCV_XLEN_BYTES, \base_reg, \base_offs, \
40643a0582SMarouene Boubakri			 \from_regnum, \to_regnum
41643a0582SMarouene Boubakri	.endm
42643a0582SMarouene Boubakri
43643a0582SMarouene Boubakri	/*
44643a0582SMarouene Boubakri	 * Loads registers x[from_regnum]..x[to_regnum] at
45643a0582SMarouene Boubakri	 * [base_reg, #base_offs]
46643a0582SMarouene Boubakri	 */
47643a0582SMarouene Boubakri	.macro load_xregs base_reg, base_offs, from_regnum, to_regnum
48643a0582SMarouene Boubakri		_do_regs LDR, RISCV_XLEN_BYTES, \base_reg, \base_offs, \
49643a0582SMarouene Boubakri			 \from_regnum, \to_regnum
50643a0582SMarouene Boubakri	.endm
51643a0582SMarouene Boubakri
52ef501733SMarouene Boubakri	/*
53ef501733SMarouene Boubakri	 * Multiplication macro for RISC-V harts without M extension.
54ef501733SMarouene Boubakri	 */
55ef501733SMarouene Boubakri	.macro mult, reg_op0, reg_op1, reg_res
56ef501733SMarouene Boubakri		li	\reg_res, 0
57ef501733SMarouene Boubakri		mv	a0, \reg_op0
58ef501733SMarouene Boubakri		mv	a1, \reg_op1
59ef501733SMarouene Boubakri		mv	a2, a0
60ef501733SMarouene Boubakri		li	a0, 0
61ef501733SMarouene Boubakri	1:
62ef501733SMarouene Boubakri		andi	a3, a1, 1
63ef501733SMarouene Boubakri		beqz	a3, 2f
64ef501733SMarouene Boubakri		add	a0, a0, a2
65ef501733SMarouene Boubakri	2:
66ef501733SMarouene Boubakri		srli	a1, a1, 1
67ef501733SMarouene Boubakri		slli	a2, a2, 1
68ef501733SMarouene Boubakri		bnez	a1, 1b
69ef501733SMarouene Boubakri		add	\reg_res, \reg_res, a0
70ef501733SMarouene Boubakri	.endm
71*d7b20c1eSAlvin Chang
72*d7b20c1eSAlvin Chang	.macro panic_at_abi_return
73*d7b20c1eSAlvin Chang#if defined(CFG_TEE_CORE_DEBUG)
74*d7b20c1eSAlvin Chang		jal	__panic_at_abi_return
75*d7b20c1eSAlvin Chang#else
76*d7b20c1eSAlvin Chang		j	.
77*d7b20c1eSAlvin Chang#endif
78*d7b20c1eSAlvin Chang	.endm
79