1 /* SImode div/mod functions for the GCC support library for the Renesas RL78 processors.
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License 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/>. */
28 .macro MAKE_GENERIC which,need_result
70 START_FUNC __generic_sidivmod\which
84 shift_den_bit16\which:
97 br $shift_den_bit\which
99 ;; These routines leave DE alone - the signed functions use DE
100 ;; to store sign information that must remain intact
103 .global __generic_sidiv
108 .global __generic_simod
113 ;; (quot,rem) = 8[sp] /% 12[sp]
116 movw ax, [hl+14] ; denH
117 cmpw ax, [hl+10] ; numH
118 movw ax, [hl+12] ; denL
120 cmpw ax, [hl+8] ; numL
135 push hl ; bitH - stored in BC
139 ;; (quot,rem) = 16[sp] /% 20[sp]
157 bnz $den_not_zero\which
169 ;; initialize bit to 1
173 ; while (den < num && !(den & (1L << BITS_MINUS_1)))
176 ;; see if we can short-circuit a bunch of shifts
179 bnz $shift_den_bit\which
182 bnh $shift_den_bit16\which
188 bc $enter_main_loop\which
190 movw ax, denL ; we re-use this below
193 bh $enter_main_loop\which
196 ; movw ax, denL ; already has it from the cmpw above
212 ;; if we don't need to compute the quotent, we don't need an
213 ;; actual bit *mask*, we just need to keep track of which bit
217 br $shift_den_bit\which
222 ;; if (num >= den) (cmp den > num)
232 ; movw ax, numL ; already has it from the cmpw above
285 enter_main_loop\which:
294 ;; bit is HImode now; check others
295 movw ax, numH ; numerator
297 bnz $bit_high_set\which
298 movw ax, denH ; denominator
300 bz $switch_to_himode\which
310 switch_to_himode\which:
317 bz $main_loop_done_himode\which
319 ;; From here on in, r22, r14, and r18 are all zero
321 main_loop_himode\which:
323 ;; if (num >= den) (cmp den > num)
326 bh $next_loop_himode\which
348 next_loop_himode\which:
370 bnz $main_loop_himode\which
372 main_loop_done_himode\which:
382 pop hl ; bitH - stored in BC
390 END_FUNC __generic_sidivmod\which
393 ;----------------------------------------------------------------------
398 ;----------------------------------------------------------------------
400 START_FUNC ___udivsi3
401 ;; r8 = 4[sp] / 8[sp]
402 call $!__generic_sidiv
407 START_FUNC ___umodsi3
408 ;; r8 = 4[sp] % 8[sp]
409 call $!__generic_simod
413 ;----------------------------------------------------------------------
427 ;----------------------------------------------------------------------
430 ;; r8 = 4[sp] / 8[sp]
438 call $!__generic_sidiv
449 bnc $div_unsigned_den
457 call $!__generic_sidiv
461 bz $div_skip_restore_num
462 ;; We have to restore the numerator [sp+4]
467 div_skip_restore_num:
475 bz $div_skip_restore_den
476 ;; We have to restore the denominator [sp+8]
480 div_skip_restore_den:
486 ;; r8 = 4[sp] % 8[sp]
494 call $!__generic_simod
505 bnc $mod_unsigned_den
513 call $!__generic_simod
520 ;; We have to restore [sp+4] as well.
528 bz $mod_skip_restore_den
532 mod_skip_restore_den: