diff options
author | Nick Clifton <nickc@redhat.com> | 2005-09-09 08:39:18 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 2005-09-09 08:39:18 +0000 |
commit | dcfae47c5e2507e490b278ae5db3365b31c9654e (patch) | |
tree | ac8df5d57a52e84f47e0d0efe6a0dda135e8261b /gcc/config/stormy16 | |
parent | a174b2f8ec2e48a091a8857099451912a69f5e99 (diff) | |
download | gcc-dcfae47c5e2507e490b278ae5db3365b31c9654e.zip gcc-dcfae47c5e2507e490b278ae5db3365b31c9654e.tar.gz gcc-dcfae47c5e2507e490b278ae5db3365b31c9654e.tar.bz2 |
Makefile.in (LIBGCC_DEPS): Add libgcc2.h.
* Makefile.in (LIBGCC_DEPS): Add libgcc2.h.
* libgcc2.c (__clz_tab[], __popcount_tab[]): Set the fixed dimension of
these arrays.
* libgcc2.h (__clz_tab[], __popcount_tab[]): Add exports of these arrays.
* longlong.h: Only provide a prototype for the __clz_tab[] array if this
header has not been included from libgcc2.h.
* config/stormy16/stormy16-lib2.c: Include libgcc2.h rather than defining
own types.
Provide prototypes for exported functions.
Use the __clz_tab[] and __popcount_tab[] arrays provided by libgcc2.c.
From-SVN: r104081
Diffstat (limited to 'gcc/config/stormy16')
-rw-r--r-- | gcc/config/stormy16/stormy16-lib2.c | 148 |
1 files changed, 104 insertions, 44 deletions
diff --git a/gcc/config/stormy16/stormy16-lib2.c b/gcc/config/stormy16/stormy16-lib2.c index 8ca9484..e8b2158 100644 --- a/gcc/config/stormy16/stormy16-lib2.c +++ b/gcc/config/stormy16/stormy16-lib2.c @@ -1,19 +1,79 @@ -typedef int HItype __attribute__ ((mode (HI))); -typedef int SItype __attribute__ ((mode (SI))); -typedef unsigned int USItype __attribute__ ((mode (SI))); +/* 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); + -typedef int word_type __attribute__ ((mode (__word__))); USItype -udivmodsi4(USItype num, USItype den, word_type modwanted) +udivmodsi4 (USItype num, USItype den, word_type modwanted) { USItype bit = 1; USItype res = 0; - while (den < num && bit && !(den & (1L<<31))) + while (den < num && bit && !(den & (1L << 31))) { - den <<=1; - bit <<=1; + den <<= 1; + bit <<= 1; } while (bit) { @@ -22,15 +82,15 @@ udivmodsi4(USItype num, USItype den, word_type modwanted) num -= den; res |= bit; } - bit >>=1; - den >>=1; + bit >>= 1; + den >>= 1; } - if (modwanted) return num; + + if (modwanted) + return num; return res; } - - SItype __divsi3 (SItype a, SItype b) { @@ -57,8 +117,6 @@ __divsi3 (SItype a, SItype b) return res; } - - SItype __modsi3 (SItype a, SItype b) { @@ -82,17 +140,12 @@ __modsi3 (SItype a, SItype b) return res; } - - - SItype __udivsi3 (SItype a, SItype b) { return udivmodsi4 (a, b, 0); } - - SItype __umodsi3 (SItype a, SItype b) { @@ -141,22 +194,13 @@ __lshrsi3 (USItype a, USItype b) return a; } -static const unsigned char __popcount_tab[] = -{ - 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, -}; - +/* 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 (unsigned int x) +__popcounthi2 (UHWtype x) { - unsigned int ret; + int ret; ret = __popcount_tab [x & 0xff]; ret += __popcount_tab [(x >> 8) & 0xff]; @@ -164,8 +208,12 @@ __popcounthi2 (unsigned int x) 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 (unsigned int x) +__parityhi2 (UHWtype x) { x ^= x >> 8; x ^= x >> 4; @@ -173,19 +221,31 @@ __parityhi2 (unsigned int x) 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 -__ctzhi2 (unsigned int x) +__clzhi2 (UHWtype x) { - extern int __ctzsi2 (unsigned long); - unsigned long y = x; - - return __ctzsi2 (y << 16) - 16; + 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 -__clzhi2 (unsigned int x) +__ctzhi2 (UHWtype x) { - extern int __clzsi2 (unsigned long); - - return __clzsi2 (x) - 16; + /* 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; } |