]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/or1k/lib1funcs.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / or1k / lib1funcs.S
CommitLineData
83ffe9cd 1/* Copyright (C) 2018-2023 Free Software Foundation, Inc.
d929e137
SH
2
3This file is free software; you can redistribute it and/or modify it
4under the terms of the GNU General Public License as published by the
5Free Software Foundation; either version 3, or (at your option) any
6later version.
7
8This file is distributed in the hope that it will be useful, but
9WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11General Public License for more details.
12
13Under Section 7 of GPL version 3, you are granted additional
14permissions described in the GCC Runtime Library Exception, version
153.1, as published by the Free Software Foundation.
16
17You should have received a copy of the GNU General Public License and
18a copy of the GCC Runtime Library Exception along with this program;
19see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
20<http://www.gnu.org/licenses/>. */
21
22
23#ifdef L__mulsi3
24 .balign 4
25 .globl __mulsi3
26 .type __mulsi3, @function
27__mulsi3:
28 l.movhi r11, 0 /* initial r */
29
30 /* Given R = X * Y ... */
311: l.sfeq r4, r0 /* while (y != 0) */
32 l.bf 2f
33 l.andi r5, r4, 1 /* if (y & 1) ... */
34 l.add r12, r11, r3
35 l.sfne r5, r0
36#if defined(__or1k_cmov__)
37 l.cmov r11, r12, r11 /* ... r += x. */
38 l.srli r4, r4, 1 /* y >>= 1 */
39#else
40 l.bnf 3f
41 l.srli r4, r4, 1 /* y >>= 1 */
42 l.ori r11, r12, 0
433:
44#endif
45 l.j 1b
46 l.add r3, r3, r3 /* x <<= 1 */
47
482: l.jr r9
49 l.nop
50
51 .size __mulsi3, . - __mulsi3
52#endif
53
54#if defined(L__udivsi3) || defined(L__umodsi3) \
55 || defined(L__divsi3) || defined(L__modsi3)
56 .global __udivmodsi3_internal
57 .hidden __udivmodsi3_internal
58 .type __udivmodsi3_internal, @function
59#endif
60
61#ifdef L__udivsi3
62 .balign 4
63 .global __udivsi3
64 .type __udivsi3, @function
65__udivsi3:
66__udivmodsi3_internal:
67 /* Note that the other division routines assume that r13
68 is not clobbered by this routine, and use that as to
69 save a return address without creating a stack frame. */
70
9c0dba7c 71 l.sfeq r4, r0 /* division by zero; return 0. */
d929e137
SH
72 l.ori r11, r0, 0 /* initial quotient */
73 l.bf 9f
74 l.ori r12, r3, 0 /* initial remainder */
75
76 /* Given X/Y, shift Y left until Y >= X. */
77 l.ori r6, r0, 1 /* mask = 1 */
9c0dba7c 781: l.sflts r4, r0 /* y has msb set */
d929e137
SH
79 l.bf 2f
80 l.sfltu r4, r12 /* y < x */
81 l.add r4, r4, r4 /* y <<= 1 */
9c0dba7c 82 l.bf 1b
d929e137
SH
83 l.add r6, r6, r6 /* mask <<= 1 */
84
85 /* Shift Y back to the right again, subtracting from X. */
862: l.add r7, r11, r6 /* tmp1 = quot + mask */
873: l.srli r6, r6, 1 /* mask >>= 1 */
88 l.sub r8, r12, r4 /* tmp2 = x - y */
89 l.sfleu r4, r12 /* y <= x */
90 l.srli r4, r4, 1 /* y >>= 1 */
91#if defined(__or1k_cmov__)
92 l.cmov r11, r7, r11 /* if (y <= x) quot = tmp1 */
93 l.cmov r12, r8, r12 /* if (y <= x) x = tmp2 */
94#else
95 l.bnf 4f
96 l.nop
97 l.ori r11, r7, 0
98 l.ori r12, r8, 0
994:
100#endif
101 l.sfne r6, r0 /* loop until mask == 0 */
102 l.bf 3b
103 l.add r7, r11, r6 /* delay fill from loop start */
104
1059: l.jr r9
106 l.nop
107
108 .size __udivsi3, . - __udivsi3
109 .size __udivmodsi3_internal, . - __udivmodsi3_internal
110#endif
111
112#ifdef L__umodsi3
113 .balign 4
114 .global __umodsi3
115 .type __umodsi3, @function
116 .cfi_startproc
117__umodsi3:
118 /* Know that __udivmodsi3_internal does not clobber r13. */
119 l.ori r13, r9, 0
120 .cfi_register 9, 13
121 l.jal __udivmodsi3_internal
122 l.nop
123 l.jr r13 /* return to saved lr */
124 l.ori r11, r12, 0 /* move remainder to rv */
125
126 .cfi_endproc
127 .size __umodsi3, . - __umodsi3
128#endif
129
130/* For signed division we do:
131
132 -x / y = x / -y = -(x / y)
133 -x % y = -(x % y)
134 x % -y = x % y
135
136 which has the property that (x/y)*y + (x%y) = x. */
137
138#ifdef L__divsi3
139 .balign 4
140 .global __divsi3
141 .type __divsi3, @function
142 .cfi_startproc
143__divsi3:
144 l.xor r6, r3, r4 /* need result negate? */
145
146 l.sflts r3, r0 /* abs(x) */
147#if defined(__or1k_cmov__)
148 l.sub r5, r0, r3
149 l.cmov r3, r5, r3
150#else
151 l.bnf 1f
152 l.sub r5, r0, r3
153 l.ori r3, r5, 0
1541:
155#endif
156 l.sflts r4, r0 /* abs(y) */
157#if defined(__or1k_cmov__)
158 l.sub r5, r0, r4
159 l.cmov r4, r5, r4
160#else
161 l.bnf 2f
162 l.sub r5, r0, r4
163 l.ori r4, r5, 0
1642:
165#endif
166
167 /* If the result will not require sign flip, tail call. */
168 l.sflts r6, r0
169 l.bnf __udivmodsi3_internal
170 l.ori r13, r9, 0 /* save lr */
171
172 /* Otherwise, know that __udivmodsi3_internal does not clobber r13.
173 Perform a normal call, then negate and return via saved lr. */
174 .cfi_register 9, 13
175 l.jal __udivmodsi3_internal
176 l.nop
177 l.jr r13
178 l.sub r11, r0, r11
179
180 .cfi_endproc
181 .size __divsi3, . - __divsi3
182#endif
183
184#ifdef L__modsi3
185 .balign 4
186 .global __modsi3
187 .type __modsi3, @function
188 .cfi_startproc
189__modsi3:
190 l.sflts r4, r0 /* abs(y) */
191#if defined(__or1k_cmov__)
192 l.sub r5, r0, r4
193 l.cmov r4, r5, r4
194#else
195 l.bnf 2f
196 l.sub r5, r0, r4
197 l.ori r4, r5, 0
1982:
199#endif
200
201 l.sflts r3, r0 /* x negative? */
202 l.bf 1f
203 l.ori r13, r9, 0 /* save lr */
204
205 /* Know that __udivmodsi3_internal does not clobber r13. */
206 .cfi_register 9, 13
207
208 /* X positive; no negate of the result required. */
209 l.jal __udivmodsi3_internal
210 l.nop
211 l.jr r13 /* return to saved lr */
212 l.ori r11, r12, 0 /* move remainder to rv */
213
214 /* X negative; negate both X and the result. */
2151: l.jal __udivmodsi3_internal
216 l.sub r3, r0, r3
217 l.jr r13 /* return to saved lr */
218 l.sub r11, r0, r12 /* negate remainder to rv */
219
220 .cfi_endproc
221 .size __modsi3, .- __modsi3
222#endif