* sysdeps/unix/sysv/linux/m68k/sysdep.h (INLINE_SYSCALL): Don't
[glibc.git] / sysdeps / ia64 / fpu / s_ceilf.S
blob2636e85debcfc8c87b206cdfc55d9583ab4e0a8f
1 .file "ceilf.s"
3 // Copyright (c) 2000, 2001, Intel Corporation
4 // All rights reserved.
5 // 
6 // Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
7 // and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
8 // 
9 // WARRANTY DISCLAIMER
10 // 
11 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
12 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
13 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
14 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS 
15 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
17 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
18 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
19 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
20 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
21 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
22 // 
23 // Intel Corporation is the author of this code, and requests that all
24 // problem reports or change requests be submitted to it directly at 
25 // http://developer.intel.com/opensource.
28 #include "libm_support.h"
30 .align 32
31 .global ceilf#
33 .section .text
34 .proc  ceilf#
35 .align 32
37 // History
38 //==============================================================
39 // 2/02/00: Initial version
40 // 6/13/00: Improved speed
41 // 6/27/00: Eliminated incorrect invalid flag setting
43 // API
44 //==============================================================
45 // float ceilf(float x)
47 // general input registers:  
49 ceil_GR_FFFF      = r14
50 ceil_GR_signexp   = r15
51 ceil_GR_exponent  = r16
52 ceil_GR_expmask   = r17
53 ceil_GR_bigexp    = r18
56 // predicate registers used: 
58 // p6  ==> Input is NaN, infinity, zero
59 // p7  ==> Input is denormal
60 // p8  ==> Input is <0
61 // p9  ==> Input is >=0
62 // p10 ==> Input is already an integer (bigger than largest integer)
63 // p11 ==> Input is not a large integer
64 // p12 ==> Input is a smaller integer
65 // p13 ==> Input is not an even integer, so inexact must be set
66 // p14 ==> Input is between -1 and 0, so result will be -0 and inexact
69 // floating-point registers used: 
71 CEIL_SIGNED_ZERO  = f7
72 CEIL_NORM_f8      = f9                        
73 CEIL_FFFF         = f10 
74 CEIL_INEXACT      = f11 
75 CEIL_FLOAT_INT_f8 = f12
76 CEIL_INT_f8       = f13
77 CEIL_adj          = f14
78 CEIL_MINUS_ONE    = f15
80 // Overview of operation
81 //==============================================================
83 // float ceilf(float x)
84 // Return an integer value (represented as a float) that is the smallest 
85 // value not less than x
86 // This is x rounded toward +infinity to an integral value.
87 // Inexact is set if x != ceilf(x)
88 // **************************************************************************
90 // Set denormal flag for denormal input and
91 // and take denormal fault if necessary.
93 // Is the input an integer value already?
95 // double_extended
96 // if the exponent is > 1003e => 3F(true) = 63(decimal)
97 // we have a significand of 64 bits 1.63-bits.
98 // If we multiply by 2^63, we no longer have a fractional part
99 // So input is an integer value already.
101 // double
102 // if the exponent is >= 10033 => 34(true) = 52(decimal)
103 // 34 + 3ff = 433
104 // we have a significand of 53 bits 1.52-bits. (implicit 1)
105 // If we multiply by 2^52, we no longer have a fractional part
106 // So input is an integer value already.
108 // single
109 // if the exponent is > 10016 => 17(true) = 23(decimal)
110 // we have a significand of 24 bits 1.23-bits. (implicit 1)
111 // If we multiply by 2^23, we no longer have a fractional part
112 // So input is an integer value already.
114 // If x is NAN, ZERO, or INFINITY, then  return
116 // qnan snan inf norm     unorm 0 -+
117 // 1    1    1   0        0     1 11     0xe7
120 ceilf:
122 { .mfi
123       getf.exp ceil_GR_signexp  = f8
124       fcvt.fx.trunc.s1     CEIL_INT_f8  = f8
125       addl        ceil_GR_bigexp = 0x10016, r0
127 { .mfi
128       addl        ceil_GR_FFFF      = -1,r0
129       fcmp.lt.s1  p8,p9 = f8,f0
130       mov         ceil_GR_expmask    = 0x1FFFF ;;
133 // p7 ==> denorm
134 { .mfi
135       setf.sig    CEIL_FFFF  = ceil_GR_FFFF
136       fclass.m    p7,p0 = f8, 0x0b
137       nop.i 999
139 { .mfi
140       nop.m 999
141       fnorm           CEIL_NORM_f8  = f8
142       nop.i 999 ;;
145 // Form 0 with sign of input in case negative zero is needed
146 { .mfi
147       nop.m 999
148       fmerge.s           CEIL_SIGNED_ZERO = f8, f0
149       nop.i 999
151 { .mfi
152       nop.m 999
153       fsub.s1           CEIL_MINUS_ONE = f0, f1
154       nop.i 999 ;;
157 // p6 ==> NAN, INF, ZERO
158 { .mfb
159       nop.m 999
160       fclass.m      p6,p10 = f8, 0xe7
161 (p7)  br.cond.spnt  L(CEIL_DENORM) ;;
164 L(CEIL_COMMON):
165 .pred.rel "mutex",p8,p9
166 // Set adjustment to add to trunc(x) for result
167 //   If x>0,  adjustment is 1.0
168 //   If x<=0, adjustment is 0.0
169 { .mfi
170       and      ceil_GR_exponent = ceil_GR_signexp, ceil_GR_expmask
171 (p9)  fadd.s1  CEIL_adj = f1,f0
172       nop.i 999
174 { .mfi
175       nop.m 999
176 (p8)  fadd.s1  CEIL_adj = f0,f0
177       nop.i 999 ;;
180 { .mfi
181 (p10) cmp.ge.unc    p10,p11 = ceil_GR_exponent, ceil_GR_bigexp
182 (p6)  fnorm.s f8 = f8
183       nop.i 999 ;;
186 { .mfi
187       nop.m 999
188 (p11) fcvt.xf         CEIL_FLOAT_INT_f8   = CEIL_INT_f8
189       nop.i 999 ;;
192 { .mfi
193       nop.m 999
194 (p10) fnorm.s f8 = CEIL_NORM_f8
195       nop.i 999 ;;
198 // Is -1 < x < 0?  If so, result will be -0.  Special case it with p14 set.
199 { .mfi
200       nop.m 999
201 (p8)  fcmp.gt.unc.s1 p14,p0 = CEIL_NORM_f8, CEIL_MINUS_ONE
202       nop.i 999 ;;
205 { .mfi
206 (p14) cmp.ne  p11,p0 = r0,r0
207 (p14) fnorm.s f8 = CEIL_SIGNED_ZERO
208       nop.i 999
210 { .mfi
211       nop.m 999
212 (p14) fmpy.s0     CEIL_INEXACT = CEIL_FFFF,CEIL_FFFF
213       nop.i 999 ;;
216 { .mfi
217       nop.m 999
218 (p11) fadd.s   f8 = CEIL_FLOAT_INT_f8,CEIL_adj
219       nop.i 999 ;;
221 { .mfi
222       nop.m 999
223 (p11) fcmp.eq.unc.s1  p12,p13  = CEIL_FLOAT_INT_f8, CEIL_NORM_f8
224       nop.i 999 ;;
227 // Set inexact if result not equal to input
228 { .mfi
229       nop.m 999
230 (p13) fmpy.s0     CEIL_INEXACT = CEIL_FFFF,CEIL_FFFF
231       nop.i 999
233 // Set result to input if integer
234 { .mfb
235       nop.m 999
236 (p12) fnorm.s f8 = CEIL_NORM_f8
237       br.ret.sptk    b0 ;;
240 // Here if input denorm
241 L(CEIL_DENORM):
242 { .mfb
243       getf.exp ceil_GR_signexp  = CEIL_NORM_f8
244       fcvt.fx.trunc.s1     CEIL_INT_f8  = CEIL_NORM_f8
245       br.cond.sptk  L(CEIL_COMMON) ;;
248 .endp ceilf
249 ASM_SIZE_DIRECTIVE(ceilf)