14fee23f9Smrg /* _divsi3 for Lattice Mico32.
24fee23f9Smrg Contributed by Jon Beniston <jon@beniston.com>
34fee23f9Smrg
4*b1e83836Smrg Copyright (C) 2009-2022 Free Software Foundation, Inc.
54fee23f9Smrg
64fee23f9Smrg This file is free software; you can redistribute it and/or modify it
74fee23f9Smrg under the terms of the GNU General Public License as published by the
84fee23f9Smrg Free Software Foundation; either version 3, or (at your option) any
94fee23f9Smrg later version.
104fee23f9Smrg
114fee23f9Smrg This file is distributed in the hope that it will be useful, but
124fee23f9Smrg WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
144fee23f9Smrg General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg 3.1, as published by the Free Software Foundation.
194fee23f9Smrg
204fee23f9Smrg You should have received a copy of the GNU General Public License and
214fee23f9Smrg a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
234fee23f9Smrg <http://www.gnu.org/licenses/>. */
244fee23f9Smrg
254fee23f9Smrg #include "libgcc_lm32.h"
264fee23f9Smrg
274fee23f9Smrg /* Signed integer division. */
284fee23f9Smrg
294fee23f9Smrg static const UQItype __divsi3_table[] = {
304fee23f9Smrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314fee23f9Smrg 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
324fee23f9Smrg 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
334fee23f9Smrg 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344fee23f9Smrg 0, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
354fee23f9Smrg 0, 5, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
364fee23f9Smrg 0, 6, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
374fee23f9Smrg 0, 7, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
384fee23f9Smrg 0, 8, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
394fee23f9Smrg 0, 9, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
404fee23f9Smrg 0, 10, 5, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
414fee23f9Smrg 0, 11, 5, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
424fee23f9Smrg 0, 12, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0,
434fee23f9Smrg 0, 13, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0,
444fee23f9Smrg 0, 14, 7, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0,
454fee23f9Smrg 0, 15, 7, 5, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
464fee23f9Smrg };
474fee23f9Smrg
484fee23f9Smrg SItype
__divsi3(SItype a,SItype b)494fee23f9Smrg __divsi3 (SItype a, SItype b)
504fee23f9Smrg {
514fee23f9Smrg int neg = 0;
524fee23f9Smrg SItype res;
534fee23f9Smrg int cfg;
544fee23f9Smrg
554fee23f9Smrg if (b == 0)
564fee23f9Smrg {
574fee23f9Smrg /* Raise divide by zero exception. */
584fee23f9Smrg int eba, sr;
594fee23f9Smrg /* Save interrupt enable. */
604fee23f9Smrg __asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
614fee23f9Smrg sr = (sr & 1) << 1;
624fee23f9Smrg __asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
634fee23f9Smrg /* Branch to exception handler. */
644fee23f9Smrg __asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
654fee23f9Smrg eba += 32 * 5;
664fee23f9Smrg __asm__ __volatile__ ("mv ea, ra");
674fee23f9Smrg __asm__ __volatile__ ("b %0"::"r" (eba));
684fee23f9Smrg __builtin_unreachable ();
694fee23f9Smrg }
704fee23f9Smrg
714fee23f9Smrg if (((USItype) (a | b)) < 16)
724fee23f9Smrg res = __divsi3_table[(a << 4) + b];
734fee23f9Smrg else
744fee23f9Smrg {
754fee23f9Smrg
764fee23f9Smrg if (a < 0)
774fee23f9Smrg {
784fee23f9Smrg a = -a;
794fee23f9Smrg neg = !neg;
804fee23f9Smrg }
814fee23f9Smrg
824fee23f9Smrg if (b < 0)
834fee23f9Smrg {
844fee23f9Smrg b = -b;
854fee23f9Smrg neg = !neg;
864fee23f9Smrg }
874fee23f9Smrg
884fee23f9Smrg __asm__ ("rcsr %0, CFG":"=r" (cfg));
894fee23f9Smrg if (cfg & 2)
904fee23f9Smrg __asm__ ("divu %0, %1, %2": "=r" (res):"r" (a), "r" (b));
914fee23f9Smrg else
924fee23f9Smrg res = __udivmodsi4 (a, b, 0);
934fee23f9Smrg
944fee23f9Smrg if (neg)
954fee23f9Smrg res = -res;
964fee23f9Smrg }
974fee23f9Smrg
984fee23f9Smrg return res;
994fee23f9Smrg }
100