]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/riscv/div.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / riscv / div.S
CommitLineData
36387fad 1/* Integer division routines for RISC-V.
2
fbd26352 3 Copyright (C) 2016-2019 Free Software Foundation, Inc.
36387fad 4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
25
1817431e 26#include "riscv-asm.h"
27
36387fad 28 .text
29 .align 2
30
31#if __riscv_xlen == 32
32/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */
33# define __udivdi3 __udivsi3
34# define __umoddi3 __umodsi3
35# define __divdi3 __divsi3
36# define __moddi3 __modsi3
37#else
1817431e 38FUNC_BEGIN (__udivsi3)
36387fad 39 /* Compute __udivdi3(a0 << 32, a1 << 32); cast result to uint32_t. */
40 sll a0, a0, 32
41 sll a1, a1, 32
42 move t0, ra
43 jal __udivdi3
44 sext.w a0, a0
45 jr t0
1817431e 46FUNC_END (__udivsi3)
36387fad 47
1817431e 48FUNC_BEGIN (__umodsi3)
36387fad 49 /* Compute __udivdi3((uint32_t)a0, (uint32_t)a1); cast a1 to uint32_t. */
50 sll a0, a0, 32
51 sll a1, a1, 32
52 srl a0, a0, 32
53 srl a1, a1, 32
54 move t0, ra
55 jal __udivdi3
56 sext.w a0, a1
57 jr t0
1817431e 58FUNC_END (__umodsi3)
36387fad 59
1817431e 60FUNC_ALIAS (__modsi3, __moddi3)
36387fad 61
1817431e 62FUNC_BEGIN( __divsi3)
36387fad 63 /* Check for special case of INT_MIN/-1. Otherwise, fall into __divdi3. */
64 li t0, -1
65 beq a1, t0, .L20
66#endif
67
1817431e 68FUNC_BEGIN (__divdi3)
36387fad 69 bltz a0, .L10
70 bltz a1, .L11
71 /* Since the quotient is positive, fall into __udivdi3. */
72
1817431e 73FUNC_BEGIN (__udivdi3)
36387fad 74 mv a2, a1
75 mv a1, a0
76 li a0, -1
77 beqz a2, .L5
78 li a3, 1
79 bgeu a2, a1, .L2
80.L1:
81 blez a2, .L2
82 slli a2, a2, 1
83 slli a3, a3, 1
84 bgtu a1, a2, .L1
85.L2:
86 li a0, 0
87.L3:
88 bltu a1, a2, .L4
89 sub a1, a1, a2
90 or a0, a0, a3
91.L4:
92 srli a3, a3, 1
93 srli a2, a2, 1
94 bnez a3, .L3
95.L5:
96 ret
1817431e 97FUNC_END (__udivdi3)
36387fad 98
1817431e 99FUNC_BEGIN (__umoddi3)
36387fad 100 /* Call __udivdi3(a0, a1), then return the remainder, which is in a1. */
101 move t0, ra
102 jal __udivdi3
103 move a0, a1
104 jr t0
1817431e 105FUNC_END (__umoddi3)
36387fad 106
107 /* Handle negative arguments to __divdi3. */
108.L10:
109 neg a0, a0
110 bgez a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */
111 neg a1, a1
112 j __udivdi3 /* Compute __udivdi3(-a0, -a1). */
113.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */
114 neg a1, a1
115.L12:
116 move t0, ra
117 jal __udivdi3
118 neg a0, a0
119 jr t0
1817431e 120FUNC_END (__divdi3)
36387fad 121
1817431e 122FUNC_BEGIN (__moddi3)
36387fad 123 move t0, ra
124 bltz a1, .L31
125 bltz a0, .L32
126.L30:
127 jal __udivdi3 /* The dividend is not negative. */
128 move a0, a1
129 jr t0
130.L31:
131 neg a1, a1
132 bgez a0, .L30
133.L32:
134 neg a0, a0
135 jal __udivdi3 /* The dividend is hella negative. */
136 neg a0, a1
137 jr t0
1817431e 138FUNC_END (__moddi3)
36387fad 139
140#if __riscv_xlen == 64
141 /* continuation of __divsi3 */
142.L20:
143 sll t0, t0, 31
144 bne a0, t0, __divdi3
145 ret
1817431e 146FUNC_END (__divsi3)
36387fad 147#endif