xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/lm32/_modsi3.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg /* _modsi3 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 modulus.  */
2836ac495dSmrg 
2936ac495dSmrg SItype
__modsi3(SItype a,SItype b)3036ac495dSmrg __modsi3 (SItype a, SItype b)
3136ac495dSmrg {
3236ac495dSmrg   int neg = 0;
3336ac495dSmrg   SItype res;
3436ac495dSmrg   int cfg;
3536ac495dSmrg 
3636ac495dSmrg   if (b == 0)
3736ac495dSmrg     {
3836ac495dSmrg       /* Raise divide by zero exception.  */
3936ac495dSmrg       int eba, sr;
4036ac495dSmrg       /* Save interrupt enable.  */
4136ac495dSmrg       __asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
4236ac495dSmrg       sr = (sr & 1) << 1;
4336ac495dSmrg       __asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
4436ac495dSmrg       /* Branch to exception handler.  */
4536ac495dSmrg       __asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
4636ac495dSmrg       eba += 32 * 5;
4736ac495dSmrg       __asm__ __volatile__ ("mv ea, ra");
4836ac495dSmrg       __asm__ __volatile__ ("b %0"::"r" (eba));
4936ac495dSmrg       __builtin_unreachable ();
5036ac495dSmrg     }
5136ac495dSmrg 
5236ac495dSmrg   if (a < 0)
5336ac495dSmrg     {
5436ac495dSmrg       a = -a;
5536ac495dSmrg       neg = 1;
5636ac495dSmrg     }
5736ac495dSmrg 
5836ac495dSmrg   if (b < 0)
5936ac495dSmrg     b = -b;
6036ac495dSmrg 
6136ac495dSmrg __asm__ ("rcsr %0, CFG":"=r" (cfg));
6236ac495dSmrg   if (cfg & 2)
6336ac495dSmrg   __asm__ ("modu %0, %1, %2": "=r" (res):"r" (a), "r" (b));
6436ac495dSmrg   else
6536ac495dSmrg     res = __udivmodsi4 (a, b, 1);
6636ac495dSmrg 
6736ac495dSmrg   if (neg)
6836ac495dSmrg     res = -res;
6936ac495dSmrg 
7036ac495dSmrg   return res;
7136ac495dSmrg }
72