divmodhi.S revision 1.1 1 1.1 mrg /* HImode div/mod functions for the GCC support library for the Renesas RL78 processors.
2 1.1 mrg Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Red Hat.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify
8 1.1 mrg it under the terms of the GNU General Public License as published by
9 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
10 1.1 mrg any later version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful,
13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 mrg GNU General Public License for more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.1 mrg #include "vregs.h"
27 1.1 mrg
28 1.1 mrg .macro MAKE_GENERIC which,need_result
29 1.1 mrg
30 1.1 mrg .if \need_result
31 1.1 mrg quot = r8
32 1.1 mrg num = r10
33 1.1 mrg den = r12
34 1.1 mrg bit = r14
35 1.1 mrg .else
36 1.1 mrg num = r8
37 1.1 mrg quot = r10
38 1.1 mrg den = r12
39 1.1 mrg bit = r14
40 1.1 mrg .endif
41 1.1 mrg
42 1.1 mrg quotB0 = quot
43 1.1 mrg quotB1 = quot+1
44 1.1 mrg
45 1.1 mrg numB0 = num
46 1.1 mrg numB1 = num+1
47 1.1 mrg
48 1.1 mrg denB0 = den
49 1.1 mrg denB1 = den+1
50 1.1 mrg
51 1.1 mrg bitB0 = bit
52 1.1 mrg bitB1 = bit+1
53 1.1 mrg
54 1.1 mrg #define bit bc
55 1.1 mrg #define bitB0 c
56 1.1 mrg #define bitB1 b
57 1.1 mrg
58 1.1 mrg START_FUNC __generic_hidivmod\which
59 1.1 mrg
60 1.1 mrg num_lt_den\which:
61 1.1 mrg .if \need_result
62 1.1 mrg movw r8, #0
63 1.1 mrg .else
64 1.1 mrg movw ax, [sp+8]
65 1.1 mrg movw r8, ax
66 1.1 mrg .endif
67 1.1 mrg ret
68 1.1 mrg
69 1.1 mrg ;; These routines leave DE alone - the signed functions use DE
70 1.1 mrg ;; to store sign information that must remain intact
71 1.1 mrg
72 1.1 mrg .if \need_result
73 1.1 mrg .global __generic_hidiv
74 1.1 mrg __generic_hidiv:
75 1.1 mrg
76 1.1 mrg .else
77 1.1 mrg
78 1.1 mrg .global __generic_himod
79 1.1 mrg __generic_himod:
80 1.1 mrg
81 1.1 mrg .endif
82 1.1 mrg
83 1.1 mrg ;; (quot,rem) = 8[sp] /% 10[sp]
84 1.1 mrg
85 1.1 mrg movw hl, sp
86 1.1 mrg movw ax, [hl+10] ; denH
87 1.1 mrg cmpw ax, [hl+8] ; numH
88 1.1 mrg bh $num_lt_den\which
89 1.1 mrg
90 1.1 mrg ;; (quot,rem) = 16[sp] /% 20[sp]
91 1.1 mrg
92 1.1 mrg ;; copy numerator
93 1.1 mrg movw ax, [hl+8]
94 1.1 mrg movw num, ax
95 1.1 mrg
96 1.1 mrg ;; copy denomonator
97 1.1 mrg movw ax, [hl+10]
98 1.1 mrg movw den, ax
99 1.1 mrg
100 1.1 mrg movw ax, den
101 1.1 mrg cmpw ax, #0
102 1.1 mrg bnz $den_not_zero\which
103 1.1 mrg movw num, #0
104 1.1 mrg ret
105 1.1 mrg
106 1.1 mrg den_not_zero\which:
107 1.1 mrg .if \need_result
108 1.1 mrg ;; zero out quot
109 1.1 mrg movw quot, #0
110 1.1 mrg .endif
111 1.1 mrg
112 1.1 mrg ;; initialize bit to 1
113 1.1 mrg movw bit, #1
114 1.1 mrg
115 1.1 mrg ; while (den < num && !(den & (1L << BITS_MINUS_1)))
116 1.1 mrg
117 1.1 mrg shift_den_bit\which:
118 1.1 mrg movw ax, den
119 1.1 mrg mov1 cy,a.7
120 1.1 mrg bc $enter_main_loop\which
121 1.1 mrg cmpw ax, num
122 1.1 mrg bh $enter_main_loop\which
123 1.1 mrg
124 1.1 mrg ;; den <<= 1
125 1.1 mrg ; movw ax, den ; already has it from the cmpw above
126 1.1 mrg shlw ax, 1
127 1.1 mrg movw den, ax
128 1.1 mrg
129 1.1 mrg ;; bit <<= 1
130 1.1 mrg .if \need_result
131 1.1 mrg #ifdef bit
132 1.1 mrg shlw bit, 1
133 1.1 mrg #else
134 1.1 mrg movw ax, bit
135 1.1 mrg shlw ax, 1
136 1.1 mrg movw bit, ax
137 1.1 mrg #endif
138 1.1 mrg .else
139 1.1 mrg ;; if we don't need to compute the quotent, we don't need an
140 1.1 mrg ;; actual bit *mask*, we just need to keep track of which bit
141 1.1 mrg inc bitB0
142 1.1 mrg .endif
143 1.1 mrg
144 1.1 mrg br $shift_den_bit\which
145 1.1 mrg
146 1.1 mrg main_loop\which:
147 1.1 mrg
148 1.1 mrg ;; if (num >= den) (cmp den > num)
149 1.1 mrg movw ax, den
150 1.1 mrg cmpw ax, num
151 1.1 mrg bh $next_loop\which
152 1.1 mrg
153 1.1 mrg ;; num -= den
154 1.1 mrg movw ax, num
155 1.1 mrg subw ax, den
156 1.1 mrg movw num, ax
157 1.1 mrg
158 1.1 mrg .if \need_result
159 1.1 mrg ;; res |= bit
160 1.1 mrg mov a, quotB0
161 1.1 mrg or a, bitB0
162 1.1 mrg mov quotB0, a
163 1.1 mrg mov a, quotB1
164 1.1 mrg or a, bitB1
165 1.1 mrg mov quotB1, a
166 1.1 mrg .endif
167 1.1 mrg
168 1.1 mrg next_loop\which:
169 1.1 mrg
170 1.1 mrg ;; den >>= 1
171 1.1 mrg movw ax, den
172 1.1 mrg shrw ax, 1
173 1.1 mrg movw den, ax
174 1.1 mrg
175 1.1 mrg .if \need_result
176 1.1 mrg ;; bit >>= 1
177 1.1 mrg movw ax, bit
178 1.1 mrg shrw ax, 1
179 1.1 mrg movw bit, ax
180 1.1 mrg .else
181 1.1 mrg dec bitB0
182 1.1 mrg .endif
183 1.1 mrg
184 1.1 mrg enter_main_loop\which:
185 1.1 mrg .if \need_result
186 1.1 mrg movw ax, bit
187 1.1 mrg cmpw ax, #0
188 1.1 mrg .else
189 1.1 mrg cmp0 bitB0
190 1.1 mrg .endif
191 1.1 mrg bnz $main_loop\which
192 1.1 mrg
193 1.1 mrg main_loop_done\which:
194 1.1 mrg ret
195 1.1 mrg END_FUNC __generic_hidivmod\which
196 1.1 mrg .endm
197 1.1 mrg ;----------------------------------------------------------------------
198 1.1 mrg
199 1.1 mrg MAKE_GENERIC _d 1
200 1.1 mrg MAKE_GENERIC _m 0
201 1.1 mrg
202 1.1 mrg ;----------------------------------------------------------------------
203 1.1 mrg
204 1.1 mrg START_FUNC ___udivhi3
205 1.1 mrg ;; r8 = 4[sp] / 6[sp]
206 1.1 mrg call $!__generic_hidiv
207 1.1 mrg ret
208 1.1 mrg END_FUNC ___udivhi3
209 1.1 mrg
210 1.1 mrg
211 1.1 mrg START_FUNC ___umodhi3
212 1.1 mrg ;; r8 = 4[sp] % 6[sp]
213 1.1 mrg call $!__generic_himod
214 1.1 mrg ret
215 1.1 mrg END_FUNC ___umodhi3
216 1.1 mrg
217 1.1 mrg ;----------------------------------------------------------------------
218 1.1 mrg
219 1.1 mrg .macro NEG_AX
220 1.1 mrg movw hl, ax
221 1.1 mrg movw ax, #0
222 1.1 mrg subw ax, [hl]
223 1.1 mrg movw [hl], ax
224 1.1 mrg .endm
225 1.1 mrg
226 1.1 mrg ;----------------------------------------------------------------------
227 1.1 mrg
228 1.1 mrg START_FUNC ___divhi3
229 1.1 mrg ;; r8 = 4[sp] / 6[sp]
230 1.1 mrg movw de, #0
231 1.1 mrg mov a, [sp+5]
232 1.1 mrg mov1 cy, a.7
233 1.1 mrg bc $div_signed_num
234 1.1 mrg mov a, [sp+7]
235 1.1 mrg mov1 cy, a.7
236 1.1 mrg bc $div_signed_den
237 1.1 mrg call $!__generic_hidiv
238 1.1 mrg ret
239 1.1 mrg
240 1.1 mrg div_signed_num:
241 1.1 mrg ;; neg [sp+4]
242 1.1 mrg movw ax, sp
243 1.1 mrg addw ax, #4
244 1.1 mrg NEG_AX
245 1.1 mrg mov d, #1
246 1.1 mrg mov a, [sp+7]
247 1.1 mrg mov1 cy, a.7
248 1.1 mrg bnc $div_unsigned_den
249 1.1 mrg div_signed_den:
250 1.1 mrg ;; neg [sp+6]
251 1.1 mrg movw ax, sp
252 1.1 mrg addw ax, #6
253 1.1 mrg NEG_AX
254 1.1 mrg mov e, #1
255 1.1 mrg div_unsigned_den:
256 1.1 mrg call $!__generic_hidiv
257 1.1 mrg
258 1.1 mrg mov a, d
259 1.1 mrg cmp0 a
260 1.1 mrg bz $div_skip_restore_num
261 1.1 mrg ;; We have to restore the numerator [sp+4]
262 1.1 mrg movw ax, sp
263 1.1 mrg addw ax, #4
264 1.1 mrg NEG_AX
265 1.1 mrg mov a, d
266 1.1 mrg div_skip_restore_num:
267 1.1 mrg xor a, e
268 1.1 mrg bz $div_no_neg
269 1.1 mrg movw ax, #r8
270 1.1 mrg NEG_AX
271 1.1 mrg div_no_neg:
272 1.1 mrg mov a, e
273 1.1 mrg cmp0 a
274 1.1 mrg bz $div_skip_restore_den
275 1.1 mrg movw ax, sp
276 1.1 mrg addw ax, #6
277 1.1 mrg NEG_AX
278 1.1 mrg div_skip_restore_den:
279 1.1 mrg ret
280 1.1 mrg END_FUNC ___divhi3
281 1.1 mrg
282 1.1 mrg
283 1.1 mrg START_FUNC ___modhi3
284 1.1 mrg ;; r8 = 4[sp] % 6[sp]
285 1.1 mrg movw de, #0
286 1.1 mrg mov a, [sp+5]
287 1.1 mrg mov1 cy, a.7
288 1.1 mrg bc $mod_signed_num
289 1.1 mrg mov a, [sp+7]
290 1.1 mrg mov1 cy, a.7
291 1.1 mrg bc $mod_signed_den
292 1.1 mrg call $!__generic_himod
293 1.1 mrg ret
294 1.1 mrg
295 1.1 mrg mod_signed_num:
296 1.1 mrg ;; neg [sp+4]
297 1.1 mrg movw ax, sp
298 1.1 mrg addw ax, #4
299 1.1 mrg NEG_AX
300 1.1 mrg mov d, #1
301 1.1 mrg mov a, [sp+7]
302 1.1 mrg mov1 cy, a.7
303 1.1 mrg bnc $mod_unsigned_den
304 1.1 mrg mod_signed_den:
305 1.1 mrg ;; neg [sp+6]
306 1.1 mrg movw ax, sp
307 1.1 mrg addw ax, #6
308 1.1 mrg NEG_AX
309 1.1 mrg mod_unsigned_den:
310 1.1 mrg call $!__generic_himod
311 1.1 mrg
312 1.1 mrg mov a, d
313 1.1 mrg cmp0 a
314 1.1 mrg bz $mod_no_neg
315 1.1 mrg movw ax, #r8
316 1.1 mrg NEG_AX
317 1.1 mrg ;; Also restore numerator
318 1.1 mrg movw ax, sp
319 1.1 mrg addw ax, #4
320 1.1 mrg NEG_AX
321 1.1 mrg mod_no_neg:
322 1.1 mrg mov a, e
323 1.1 mrg cmp0 a
324 1.1 mrg bz $mod_skip_restore_den
325 1.1 mrg movw ax, sp
326 1.1 mrg addw ax, #6
327 1.1 mrg NEG_AX
328 1.1 mrg mod_skip_restore_den:
329 1.1 mrg ret
330 1.1 mrg END_FUNC ___modhi3
331