xref: /linux/arch/riscv/lib/ashrdi3.S (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/**
3 * Adopted for the Linux kernel from IPXE project, see
4 * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
5 */
6
7#include <linux/linkage.h>
8#include <asm/asm.h>
9
10/**
11 * Arithmetic shift right
12 *
13 * @v a1:a0             Value to shift
14 * @v a2                Shift amount
15 * @ret a1:a0           Shifted value
16 */
17
18SYM_FUNC_START(__ashrdi3)
19
20        /* Perform shift by 32 bits, if applicable */
21        li      t0, 32
22        sub     t1, t0, a2
23        bgtz    t1, 1f
24        mv      a0, a1
25        srai    a1, a1, 31
261:      /* Perform shift by modulo-32 bits, if applicable */
27        andi    a2, a2, 0x1f
28        beqz    a2, 2f
29        sll     t2, a1, t1
30        sra     a1, a1, a2
31        srl     a0, a0, a2
32        or      a0, a0, t2
332:      ret
34
35SYM_FUNC_END(__ashrdi3)
36EXPORT_SYMBOL(__ashrdi3)
37