bd52d17906
too large to list, but see: http://gcc.gnu.org/gcc-3.4/changes.html http://gcc.gnu.org/gcc-4.0/changes.html http://gcc.gnu.org/gcc-4.1/changes.html for the details.
252 lines
5.2 KiB
C
252 lines
5.2 KiB
C
/* This file contains 16-bit versions of some of the functions found in
|
|
libgcc2.c. Really libgcc ought to be moved out of the gcc directory
|
|
and into its own top level directory, and then split up into multiple
|
|
files. On this glorious day maybe this code can be integrated into
|
|
it too. */
|
|
|
|
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 2, or (at your option) any later
|
|
version.
|
|
|
|
In addition to the permissions in the GNU General Public License, the
|
|
Free Software Foundation gives you unlimited permission to link the
|
|
compiled version of this file into combinations with other programs,
|
|
and to distribute those combinations without any restriction coming
|
|
from the use of this file. (The General Public License restrictions
|
|
do apply in other respects; for example, they cover modification of
|
|
the file, and distribution when not linked into a combine
|
|
executable.)
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING. If not, write to the Free
|
|
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA. */
|
|
|
|
#include "tconfig.h"
|
|
#include "tsystem.h"
|
|
#include "coretypes.h"
|
|
#include "tm.h"
|
|
|
|
#ifdef HAVE_GAS_HIDDEN
|
|
#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
|
|
#else
|
|
#define ATTRIBUTE_HIDDEN
|
|
#endif
|
|
|
|
#include "libgcc2.h"
|
|
#undef int
|
|
|
|
/* These prototypes would normally live in libgcc2.h, but this can
|
|
only happen once the code below is integrated into libgcc2.c. */
|
|
|
|
extern USItype udivmodsi4 (USItype, USItype, word_type);
|
|
extern SItype __divsi3 (SItype, SItype);
|
|
extern SItype __modsi3 (SItype, SItype);
|
|
extern SItype __udivsi3 (SItype, SItype);
|
|
extern SItype __umodsi3 (SItype, SItype);
|
|
extern SItype __ashlsi3 (SItype, SItype);
|
|
extern SItype __ashrsi3 (SItype, SItype);
|
|
extern USItype __lshrsi3 (USItype, USItype);
|
|
extern int __popcounthi2 (UHWtype);
|
|
extern int __parityhi2 (UHWtype);
|
|
extern int __clzhi2 (UHWtype);
|
|
extern int __ctzhi2 (UHWtype);
|
|
|
|
|
|
|
|
USItype
|
|
udivmodsi4 (USItype num, USItype den, word_type modwanted)
|
|
{
|
|
USItype bit = 1;
|
|
USItype res = 0;
|
|
|
|
while (den < num && bit && !(den & (1L << 31)))
|
|
{
|
|
den <<= 1;
|
|
bit <<= 1;
|
|
}
|
|
while (bit)
|
|
{
|
|
if (num >= den)
|
|
{
|
|
num -= den;
|
|
res |= bit;
|
|
}
|
|
bit >>= 1;
|
|
den >>= 1;
|
|
}
|
|
|
|
if (modwanted)
|
|
return num;
|
|
return res;
|
|
}
|
|
|
|
SItype
|
|
__divsi3 (SItype a, SItype b)
|
|
{
|
|
word_type neg = 0;
|
|
SItype res;
|
|
|
|
if (a < 0)
|
|
{
|
|
a = -a;
|
|
neg = !neg;
|
|
}
|
|
|
|
if (b < 0)
|
|
{
|
|
b = -b;
|
|
neg = !neg;
|
|
}
|
|
|
|
res = udivmodsi4 (a, b, 0);
|
|
|
|
if (neg)
|
|
res = -res;
|
|
|
|
return res;
|
|
}
|
|
|
|
SItype
|
|
__modsi3 (SItype a, SItype b)
|
|
{
|
|
word_type neg = 0;
|
|
SItype res;
|
|
|
|
if (a < 0)
|
|
{
|
|
a = -a;
|
|
neg = 1;
|
|
}
|
|
|
|
if (b < 0)
|
|
b = -b;
|
|
|
|
res = udivmodsi4 (a, b, 1);
|
|
|
|
if (neg)
|
|
res = -res;
|
|
|
|
return res;
|
|
}
|
|
|
|
SItype
|
|
__udivsi3 (SItype a, SItype b)
|
|
{
|
|
return udivmodsi4 (a, b, 0);
|
|
}
|
|
|
|
SItype
|
|
__umodsi3 (SItype a, SItype b)
|
|
{
|
|
return udivmodsi4 (a, b, 1);
|
|
}
|
|
|
|
SItype
|
|
__ashlsi3 (SItype a, SItype b)
|
|
{
|
|
word_type i;
|
|
|
|
if (b & 16)
|
|
a <<= 16;
|
|
if (b & 8)
|
|
a <<= 8;
|
|
for (i = (b & 0x7); i > 0; --i)
|
|
a <<= 1;
|
|
return a;
|
|
}
|
|
|
|
SItype
|
|
__ashrsi3 (SItype a, SItype b)
|
|
{
|
|
word_type i;
|
|
|
|
if (b & 16)
|
|
a >>= 16;
|
|
if (b & 8)
|
|
a >>= 8;
|
|
for (i = (b & 0x7); i > 0; --i)
|
|
a >>= 1;
|
|
return a;
|
|
}
|
|
|
|
USItype
|
|
__lshrsi3 (USItype a, USItype b)
|
|
{
|
|
word_type i;
|
|
|
|
if (b & 16)
|
|
a >>= 16;
|
|
if (b & 8)
|
|
a >>= 8;
|
|
for (i = (b & 0x7); i > 0; --i)
|
|
a >>= 1;
|
|
return a;
|
|
}
|
|
|
|
/* Returns the number of set bits in X.
|
|
FIXME: The return type really should be unsigned,
|
|
but this is not how the builtin is prototyped. */
|
|
int
|
|
__popcounthi2 (UHWtype x)
|
|
{
|
|
int ret;
|
|
|
|
ret = __popcount_tab [x & 0xff];
|
|
ret += __popcount_tab [(x >> 8) & 0xff];
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* Returns the number of set bits in X, modulo 2.
|
|
FIXME: The return type really should be unsigned,
|
|
but this is not how the builtin is prototyped. */
|
|
|
|
int
|
|
__parityhi2 (UHWtype x)
|
|
{
|
|
x ^= x >> 8;
|
|
x ^= x >> 4;
|
|
x &= 0xf;
|
|
return (0x6996 >> x) & 1;
|
|
}
|
|
|
|
/* Returns the number of leading zero bits in X.
|
|
FIXME: The return type really should be unsigned,
|
|
but this is not how the builtin is prototyped. */
|
|
|
|
int
|
|
__clzhi2 (UHWtype x)
|
|
{
|
|
if (x > 0xff)
|
|
return 8 - __clz_tab[x >> 8];
|
|
return 16 - __clz_tab[x];
|
|
}
|
|
|
|
/* Returns the number of trailing zero bits in X.
|
|
FIXME: The return type really should be unsigned,
|
|
but this is not how the builtin is prototyped. */
|
|
|
|
int
|
|
__ctzhi2 (UHWtype x)
|
|
{
|
|
/* This is cunning. It converts X into a number with only the one bit
|
|
set, the bit was the least significant bit in X. From this we can
|
|
use the __clz_tab[] array to compute the number of trailing bits. */
|
|
x &= - x;
|
|
|
|
if (x > 0xff)
|
|
return __clz_tab[x >> 8] + 7;
|
|
return __clz_tab[x] - 1;
|
|
}
|