(root)/
gcc-13.2.0/
libgcc/
config/
stormy16/
lib2funcs.c
       1  /* This file contains 16-bit versions of some of the functions found in
       2     libgcc2.c.  Really libgcc ought to be moved out of the gcc directory
       3     and into its own top level directory, and then split up into multiple
       4     files.  On this glorious day maybe this code can be integrated into
       5     it too.  */
       6  
       7  /* Copyright (C) 2005-2023 Free Software Foundation, Inc.
       8  
       9     This file is part of GCC.
      10  
      11     GCC is free software; you can redistribute it and/or modify it under
      12     the terms of the GNU General Public License as published by the Free
      13     Software Foundation; either version 3, or (at your option) any later
      14     version.
      15  
      16     GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      17     WARRANTY; without even the implied warranty of MERCHANTABILITY or
      18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      19     for more details.
      20  
      21     Under Section 7 of GPL version 3, you are granted additional
      22     permissions described in the GCC Runtime Library Exception, version
      23     3.1, as published by the Free Software Foundation.
      24  
      25     You should have received a copy of the GNU General Public License and
      26     a copy of the GCC Runtime Library Exception along with this program;
      27     see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      28     <http://www.gnu.org/licenses/>.  */
      29  
      30  #include "tconfig.h"
      31  #include "tsystem.h"
      32  #include "coretypes.h"
      33  #include "tm.h"
      34  #include "libgcc_tm.h"
      35  
      36  #ifdef HAVE_GAS_HIDDEN
      37  #define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
      38  #else
      39  #define ATTRIBUTE_HIDDEN
      40  #endif
      41  
      42  #ifndef MIN_UNITS_PER_WORD
      43  #define MIN_UNITS_PER_WORD UNITS_PER_WORD
      44  #endif
      45  
      46  #ifndef LIBGCC2_UNITS_PER_WORD
      47  # if MIN_UNITS_PER_WORD > 4
      48  #  define LIBGCC2_UNITS_PER_WORD 8
      49  # elif (MIN_UNITS_PER_WORD > 2 \
      50          || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
      51  #  define LIBGCC2_UNITS_PER_WORD 4
      52  # else
      53  #  define LIBGCC2_UNITS_PER_WORD MIN_UNITS_PER_WORD
      54  # endif
      55  #endif
      56  
      57  #define word_type Wtype
      58  
      59  #include "libgcc2.h"
      60  #undef int
      61  
      62  /* These prototypes would normally live in libgcc2.h, but this can
      63     only happen once the code below is integrated into libgcc2.c.  */
      64  
      65  extern USItype udivmodsi4 (USItype, USItype, word_type);
      66  extern SItype __divsi3 (SItype, SItype);
      67  extern SItype __modsi3 (SItype, SItype);
      68  extern SItype __udivsi3 (SItype, SItype);
      69  extern SItype __umodsi3 (SItype, SItype);
      70  extern SItype __ashlsi3 (SItype, SItype);
      71  extern SItype __ashrsi3 (SItype, SItype);
      72  extern USItype __lshrsi3 (USItype, USItype);
      73  extern int __popcounthi2 (UHWtype);
      74  extern int __parityhi2 (UHWtype);
      75  extern int __clzhi2 (UHWtype);
      76  extern int __ctzhi2 (UHWtype);
      77  
      78  
      79  #ifdef XSTORMY16_UDIVMODSI4
      80  USItype
      81  udivmodsi4 (USItype num, USItype den, word_type modwanted)
      82  {
      83    USItype bit = 1;
      84    USItype res = 0;
      85  
      86    while (den < num && bit && !(den & (1L << 31)))
      87      {
      88        den <<= 1;
      89        bit <<= 1;
      90      }
      91    while (bit)
      92      {
      93        if (num >= den)
      94  	{
      95  	  num -= den;
      96  	  res |= bit;
      97  	}
      98        bit >>= 1;
      99        den >>= 1;
     100      }
     101  
     102    if (modwanted)
     103      return num;
     104    return res;
     105  }
     106  #endif
     107  
     108  #ifdef XSTORMY16_DIVSI3
     109  SItype
     110  __divsi3 (SItype a, SItype b)
     111  {
     112    word_type neg = 0;
     113    SItype res;
     114  
     115    if (a < 0)
     116      {
     117        a = -a;
     118        neg = !neg;
     119      }
     120  
     121    if (b < 0)
     122      {
     123        b = -b;
     124        neg = !neg;
     125      }
     126  
     127    res = udivmodsi4 (a, b, 0);
     128  
     129    if (neg)
     130      res = -res;
     131  
     132    return res;
     133  }
     134  #endif
     135  
     136  #ifdef XSTORMY16_MODSI3
     137  SItype
     138  __modsi3 (SItype a, SItype b)
     139  {
     140    word_type neg = 0;
     141    SItype res;
     142  
     143    if (a < 0)
     144      {
     145        a = -a;
     146        neg = 1;
     147      }
     148  
     149    if (b < 0)
     150      b = -b;
     151  
     152    res = udivmodsi4 (a, b, 1);
     153  
     154    if (neg)
     155      res = -res;
     156  
     157    return res;
     158  }
     159  #endif
     160  
     161  #ifdef XSTORMY16_UDIVSI3
     162  SItype
     163  __udivsi3 (SItype a, SItype b)
     164  {
     165    return udivmodsi4 (a, b, 0);
     166  }
     167  #endif
     168  
     169  #ifdef XSTORMY16_UMODSI3
     170  SItype
     171  __umodsi3 (SItype a, SItype b)
     172  {
     173    return udivmodsi4 (a, b, 1);
     174  }
     175  #endif
     176  
     177  #ifdef XSTORMY16_ASHLSI3
     178  SItype
     179  __ashlsi3 (SItype a, SItype b)
     180  {
     181    word_type i;
     182    
     183    if (b & 16)
     184      a <<= 16;
     185    if (b & 8)
     186      a <<= 8;
     187    for (i = (b & 0x7); i > 0; --i)
     188      a <<= 1;
     189    return a;
     190  }
     191  #endif
     192  
     193  #ifdef XSTORMY16_ASHRSI3
     194  SItype
     195  __ashrsi3 (SItype a, SItype b)
     196  {
     197    word_type i;
     198    
     199    if (b & 16)
     200      a >>= 16;
     201    if (b & 8)
     202      a >>= 8;
     203    for (i = (b & 0x7); i > 0; --i)
     204      a >>= 1;
     205    return a;
     206  }
     207  #endif
     208  
     209  #ifdef XSTORMY16_LSHRSI3
     210  USItype
     211  __lshrsi3 (USItype a, USItype b)
     212  {
     213    word_type i;
     214    
     215    if (b & 16)
     216      a >>= 16;
     217    if (b & 8)
     218      a >>= 8;
     219    for (i = (b & 0x7); i > 0; --i)
     220      a >>= 1;
     221    return a;
     222  }
     223  #endif
     224  
     225  #ifdef XSTORMY16_POPCOUNTHI2
     226  /* Returns the number of set bits in X.
     227     FIXME:  The return type really should be "unsigned int"
     228     but this is not how the builtin is prototyped.  */
     229  int
     230  __popcounthi2 (UHWtype x)
     231  {
     232    int ret;
     233  
     234    ret = __popcount_tab [x & 0xff];
     235    ret += __popcount_tab [(x >> 8) & 0xff];
     236  
     237    return ret;
     238  }
     239  #endif
     240  
     241  #ifdef XSTORMY16_PARITYHI2
     242  /* Returns the number of set bits in X, modulo 2.
     243     FIXME:  The return type really should be "unsigned int"
     244     but this is not how the builtin is prototyped.  */
     245  
     246  int
     247  __parityhi2 (UHWtype x)
     248  {
     249    x ^= x >> 8;
     250    x ^= x >> 4;
     251    x &= 0xf;
     252    return (0x6996 >> x) & 1;
     253  }
     254  #endif
     255  
     256  #ifdef XSTORMY16_CLZHI2
     257  /* Returns the number of zero-bits from the most significant bit to the
     258     first nonzero bit in X.  Returns 16 for X == 0.  Implemented as a
     259     simple for loop in order to save space by removing the need for
     260     the __clz_tab array.
     261     FIXME:  The return type really should be "unsigned int" but this is
     262     not how the builtin is prototyped.  */
     263  #undef unsigned
     264  int
     265  __clzhi2 (UHWtype x)
     266  {
     267    unsigned int i;
     268    unsigned int c;
     269    unsigned int value = x;
     270  
     271    for (c = 0, i = 1 << 15; i; i >>= 1, c++)
     272      if (i & value)
     273        break;
     274    return c;
     275  }
     276  #endif
     277  
     278  #ifdef XSTORMY16_CTZHI2
     279  /* Returns the number of trailing zero bits in X.
     280     FIXME:  The return type really should be "signed int" since
     281     ctz(0) returns -1, but this is not how the builtin is prototyped.  */
     282  
     283  int
     284  __ctzhi2 (UHWtype x)
     285  {
     286    /* This is cunning.  It converts X into a number with only the one bit
     287       set, the bit that was the least significant bit in X.  From this we
     288       can use the count_leading_zeros to compute the number of trailing
     289       bits.  */
     290    x &= - x;
     291  
     292    return 15 - __builtin_clz (x);
     293  }
     294  #endif
     295  
     296  #ifdef XSTORMY16_FFSHI2
     297  /* Returns one plus the index of the least significant 1-bit of X,
     298     or if X is zero, returns zero.  FIXME:  The return type really
     299     should be "unsigned int" but this is not how the builtin is
     300     prototyped.  */
     301  
     302  int
     303  __ffshi2 (UHWtype u)
     304  {
     305    UHWtype count;
     306  
     307    if (u == 0)
     308      return 0;
     309  
     310    return 16 - __builtin_clz (u & - u);
     311  }
     312  #endif
     313  
     314  #ifdef XSTORMY16_CLRSBHI2
     315  /* Returns the number of leading redundant sign bits in X.
     316     I.e. the number of bits following the most significant bit which are
     317     identical to it.  There are no special cases for 0 or other values.  */
     318  
     319  int
     320  __clrsbhi2 (HWtype x)
     321  {
     322    if (x < 0)
     323      x = ~x;
     324    if (x == 0)
     325      return 15;
     326    return __builtin_clz (x) - 1;
     327  }
     328  #endif
     329  
     330  #ifdef XSTORMY16_UCMPSI2
     331  /* Performs an unsigned comparison of two 32-bit values: A and B.
     332     If A is less than B, then 0 is returned.  If A is greater than B,
     333     then 2 is returned.  Otherwise A and B are equal and 1 is returned.  */
     334  
     335  word_type
     336  __ucmpsi2 (USItype a, USItype b)
     337  {
     338    word_type hi_a = (a >> 16);
     339    word_type hi_b = (b >> 16);
     340  
     341    if (hi_a == hi_b)
     342      {
     343        word_type low_a = (a & 0xffff);
     344        word_type low_b = (b & 0xffff);
     345  
     346        return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1);
     347      }
     348  
     349    return hi_a < hi_b ? 0 : 2;
     350  }
     351  #endif
     352  
     353  #ifdef XSTORMY16_CMPSI2
     354  /* Performs an signed comparison of two 32-bit values: A and B.
     355     If A is less than B, then 0 is returned.  If A is greater than B,
     356     then 2 is returned.  Otherwise A and B are equal and 1 is returned.  */
     357  
     358  word_type
     359  __cmpsi2 (SItype a, SItype b)
     360  {
     361    word_type hi_a = (a >> 16);
     362    word_type hi_b = (b >> 16);
     363  
     364    if (hi_a == hi_b)
     365      {
     366        word_type low_a = (a & 0xffff);
     367        word_type low_b = (b & 0xffff);
     368  
     369        return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1);
     370      }
     371  
     372    return hi_a < hi_b ? 0 : 2;
     373  }
     374  #endif