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