136ac495dSmrg /* _divsi3 for Lattice Mico32.
236ac495dSmrg Contributed by Jon Beniston <jon@beniston.com>
336ac495dSmrg
4*8feb0f0bSmrg Copyright (C) 2009-2020 Free Software Foundation, Inc.
536ac495dSmrg
636ac495dSmrg This file is free software; you can redistribute it and/or modify it
736ac495dSmrg under the terms of the GNU General Public License as published by the
836ac495dSmrg Free Software Foundation; either version 3, or (at your option) any
936ac495dSmrg later version.
1036ac495dSmrg
1136ac495dSmrg This file is distributed in the hope that it will be useful, but
1236ac495dSmrg WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1436ac495dSmrg General Public License for more details.
1536ac495dSmrg
1636ac495dSmrg Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg 3.1, as published by the Free Software Foundation.
1936ac495dSmrg
2036ac495dSmrg You should have received a copy of the GNU General Public License and
2136ac495dSmrg a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2336ac495dSmrg <http://www.gnu.org/licenses/>. */
2436ac495dSmrg
2536ac495dSmrg #include "libgcc_lm32.h"
2636ac495dSmrg
2736ac495dSmrg /* Signed integer division. */
2836ac495dSmrg
2936ac495dSmrg static const UQItype __divsi3_table[] = {
3036ac495dSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3136ac495dSmrg 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3236ac495dSmrg 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3336ac495dSmrg 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3436ac495dSmrg 0, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3536ac495dSmrg 0, 5, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3636ac495dSmrg 0, 6, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3736ac495dSmrg 0, 7, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
3836ac495dSmrg 0, 8, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
3936ac495dSmrg 0, 9, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
4036ac495dSmrg 0, 10, 5, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
4136ac495dSmrg 0, 11, 5, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
4236ac495dSmrg 0, 12, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0,
4336ac495dSmrg 0, 13, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0,
4436ac495dSmrg 0, 14, 7, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0,
4536ac495dSmrg 0, 15, 7, 5, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
4636ac495dSmrg };
4736ac495dSmrg
4836ac495dSmrg SItype
__divsi3(SItype a,SItype b)4936ac495dSmrg __divsi3 (SItype a, SItype b)
5036ac495dSmrg {
5136ac495dSmrg int neg = 0;
5236ac495dSmrg SItype res;
5336ac495dSmrg int cfg;
5436ac495dSmrg
5536ac495dSmrg if (b == 0)
5636ac495dSmrg {
5736ac495dSmrg /* Raise divide by zero exception. */
5836ac495dSmrg int eba, sr;
5936ac495dSmrg /* Save interrupt enable. */
6036ac495dSmrg __asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
6136ac495dSmrg sr = (sr & 1) << 1;
6236ac495dSmrg __asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
6336ac495dSmrg /* Branch to exception handler. */
6436ac495dSmrg __asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
6536ac495dSmrg eba += 32 * 5;
6636ac495dSmrg __asm__ __volatile__ ("mv ea, ra");
6736ac495dSmrg __asm__ __volatile__ ("b %0"::"r" (eba));
6836ac495dSmrg __builtin_unreachable ();
6936ac495dSmrg }
7036ac495dSmrg
7136ac495dSmrg if (((USItype) (a | b)) < 16)
7236ac495dSmrg res = __divsi3_table[(a << 4) + b];
7336ac495dSmrg else
7436ac495dSmrg {
7536ac495dSmrg
7636ac495dSmrg if (a < 0)
7736ac495dSmrg {
7836ac495dSmrg a = -a;
7936ac495dSmrg neg = !neg;
8036ac495dSmrg }
8136ac495dSmrg
8236ac495dSmrg if (b < 0)
8336ac495dSmrg {
8436ac495dSmrg b = -b;
8536ac495dSmrg neg = !neg;
8636ac495dSmrg }
8736ac495dSmrg
8836ac495dSmrg __asm__ ("rcsr %0, CFG":"=r" (cfg));
8936ac495dSmrg if (cfg & 2)
9036ac495dSmrg __asm__ ("divu %0, %1, %2": "=r" (res):"r" (a), "r" (b));
9136ac495dSmrg else
9236ac495dSmrg res = __udivmodsi4 (a, b, 0);
9336ac495dSmrg
9436ac495dSmrg if (neg)
9536ac495dSmrg res = -res;
9636ac495dSmrg }
9736ac495dSmrg
9836ac495dSmrg return res;
9936ac495dSmrg }
100