1/* Definitions of target machine for GNU compiler, for IBM S/390
2   Copyright (C) 1999-2015 Free Software Foundation, Inc.
3   Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4                  Ulrich Weigand (uweigand@de.ibm.com).
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25<http://www.gnu.org/licenses/>.  */
26
27#ifndef __s390x__
28
29#define EXPONENT_BIAS   127
30#define MANTISSA_BITS   23
31#define EXP(fp)         (((fp.l) >> MANTISSA_BITS) & 0xFF)
32#define SIGNBIT         0x80000000
33#define SIGN(fp)        ((fp.l) & SIGNBIT)
34#define HIDDEN          (1 << MANTISSA_BITS)
35#define MANT(fp)        (((fp.l) & 0x7FFFFF) | HIDDEN)
36#define FRAC(fp)        ((fp.l) & 0x7FFFFF)
37
38typedef int DItype_x __attribute__ ((mode (DI)));
39typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
40typedef int SItype_x __attribute__ ((mode (SI)));
41typedef unsigned int USItype_x __attribute__ ((mode (SI)));
42
43union float_long
44  {
45    float f;
46    USItype_x l;
47  };
48
49static __inline__ void
50fexceptdiv (float d, float e)
51{
52  __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
53}
54
55UDItype_x __fixunssfdi (float a1);
56
57/* convert float to unsigned int */
58UDItype_x
59__fixunssfdi (float a1)
60{
61    register union float_long fl1;
62    register int exp;
63    register UDItype_x l;
64
65    fl1.f = a1;
66
67    /* +/- 0, denormalized  */
68    if (!EXP (fl1))
69      return 0;
70
71    /* Negative.  */
72    if (SIGN (fl1))
73      {
74	/* Value is <= -1.0
75	   C99 Annex F.4 requires an "invalid" exception to be thrown.  */
76	if (EXP (fl1) >= EXPONENT_BIAS)
77	  fexceptdiv (0.0, 0.0);
78	return 0;
79      }
80
81    exp = EXP (fl1) - EXPONENT_BIAS - MANTISSA_BITS;
82
83    /* number < 1 */
84    if (exp < -24)
85      return 0;
86
87    /* NaN */
88
89    if ((EXP (fl1) == 0xff) && (FRAC (fl1) != 0)) /* NaN */
90      {
91	/* C99 Annex F.4 requires an "invalid" exception to be thrown.  */
92	fexceptdiv (0.0, 0.0);
93	return 0x0ULL;
94      }
95
96    /* Number big number & + inf */
97
98    if (exp >= 41)
99      {
100	/* C99 Annex F.4 requires an "invalid" exception to be thrown.  */
101	fexceptdiv (0.0, 0.0);
102	return 0xFFFFFFFFFFFFFFFFULL;
103      }
104
105    l = MANT (fl1);
106
107    if (exp > 0)
108      l <<= exp;
109    else
110      l >>= -exp;
111
112    return l;
113}
114#endif /* !__s390x__ */
115