lib2funcs.c revision 1.6
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-2017 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 65extern USItype udivmodsi4 (USItype, USItype, word_type); 66extern SItype __divsi3 (SItype, SItype); 67extern SItype __modsi3 (SItype, SItype); 68extern SItype __udivsi3 (SItype, SItype); 69extern SItype __umodsi3 (SItype, SItype); 70extern SItype __ashlsi3 (SItype, SItype); 71extern SItype __ashrsi3 (SItype, SItype); 72extern USItype __lshrsi3 (USItype, USItype); 73extern int __popcounthi2 (UHWtype); 74extern int __parityhi2 (UHWtype); 75extern int __clzhi2 (UHWtype); 76extern int __ctzhi2 (UHWtype); 77 78 79#ifdef XSTORMY16_UDIVMODSI4 80USItype 81udivmodsi4 (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 109SItype 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 137SItype 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 162SItype 163__udivsi3 (SItype a, SItype b) 164{ 165 return udivmodsi4 (a, b, 0); 166} 167#endif 168 169#ifdef XSTORMY16_UMODSI3 170SItype 171__umodsi3 (SItype a, SItype b) 172{ 173 return udivmodsi4 (a, b, 1); 174} 175#endif 176 177#ifdef XSTORMY16_ASHLSI3 178SItype 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 194SItype 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 210USItype 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. */ 229int 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 246int 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 264int 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 283int 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 302int 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 319int 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 335word_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 358word_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 375