1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 23 */ 24/* 25 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 .file "nextafterl.s" 30 31#include "libm.h" 32LIBM_ANSI_PRAGMA_WEAK(nextafterl,function) 33#include "libm_synonyms.h" 34 35 .section .rodata 36 .align 4 37.LFmaxl: .long 0xffffffff,0xffffffff,0x00007ffe 38.LFminl: .long 0x1,0x0,0x0 39 40 41 ENTRY(nextafterl) 42 pushl %ebp 43 movl %esp,%ebp 44 fldt 20(%ebp) / y 45 subl $12,%esp 46 fldt 8(%ebp) / load x 47 fucom / x : y 48 fstsw %ax 49 sahf 50 jp .LNaN 51 je .Lequal 52 fstp %st(1) / x 53 ja .Lbigger 54 / x < y 55 ftst 56 movl $1,-12(%ebp) /// -12(%ebp) contains Fminl 57 movl $0,-8(%ebp) 58 movl $0,%ecx /// final needs this 59 movl %ecx,-4(%ebp) 60 fnstsw %ax 61 sahf 62 je .Lfinal 63 ja .Laddulp 64 jb .Lsubulp 65.Lbigger: 66 / x > y 67 ftst 68 movl $1,-12(%ebp) /// -12(%ebp) contains -Fminl 69 movl $0,-8(%ebp) 70 movl $0x00008000,%ecx /// final needs this 71 movl %ecx,-4(%ebp) 72 fnstsw %ax 73 sahf 74 je .Lfinal 75 jb .Laddulp 76.Lsubulp: 77 movl 12(%ebp),%edx / high word of significand of x 78 movl 16(%ebp),%ecx / x's exponent 79 andl $0x0000ffff,%ecx 80 movl %edx,%eax 81 not %eax 82 andl $0x80000000,%eax / look at explicit leading bit 83 orl %ecx,%eax 84 andl $0x80007fff,%eax 85 jnz .Lnot_pseudonormal / zero value implies pseudonormal 86 addl $1,%ecx / if pseudonormal, turn into equivalent normal 87.Lnot_pseudonormal: 88 movl 8(%ebp),%eax / low x 89 subl $1,%eax / low x - ulp 90 movl %eax,-12(%ebp) 91 cmpl $0xffffffff,%eax / this means low x was 0 92 jz .Lborrow 93 movl %edx,-8(%ebp) 94 movl %ecx,-4(%ebp) 95 jmp .Lfinal 96.Lborrow: 97 cmpl $0x80000000,%edx / look at high x 98 je .Lsecond_borrow 99 subl $1,%edx 100 movl %edx,-8(%ebp) 101 movl %ecx,-4(%ebp) 102 jmp .Lfinal 103.Lsecond_borrow: 104 movl %ecx,%eax 105 andl $0x7fff,%eax / look at exp x without sign bit 106 cmpl $1,%eax 107 jbe .Lsubnormal_result / exp > 1 ==> result will be normal 108 movl $0xffffffff,-8(%ebp) 109 subl $1,%ecx 110 movl %ecx,-4(%ebp) 111 jmp .Lfinal 112.Lsubnormal_result: 113 movl $0x7fffffff,-8(%ebp) 114 movl %ecx,%eax 115 andl $0x8000,%eax / look at sign bit 116 jz .Lpositive 117 movl $0x8000,%ecx 118 movl %ecx,-4(%ebp) 119 jmp .Lfinal 120.Lpositive: 121 movl $0,%ecx 122 movl %ecx,-4(%ebp) 123 jmp .Lfinal 124.Laddulp: 125 movl 12(%ebp),%edx / high x 126 movl 16(%ebp),%ecx / x's exponent 127 andl $0x0000ffff,%ecx 128 movl %edx,%eax 129 not %eax 130 andl $0x80000000,%eax / look at explicit leading bit 131 orl %ecx,%eax 132 andl $0x80007fff,%eax 133 jnz .Lnot_pseudonormal_2 / zero value implies pseudonormal 134 addl $1,%ecx 135.Lnot_pseudonormal_2: 136 movl 8(%ebp),%eax / low x 137 addl $1,%eax / low x + ulp 138 movl %eax,-12(%ebp) 139 jz .Lcarry / jump if the content of %eax is 0 140 movl %edx,-8(%ebp) 141 movl %ecx,-4(%ebp) 142 jmp .Lfinal 143.Lcarry: 144 movl %edx,%eax 145 andl $0x7fffffff,%eax 146 cmpl $0x7fffffff,%eax / look at high x 147 je .Lsecond_carry 148 addl $1,%edx 149 movl %edx,-8(%ebp) 150 movl %ecx,-4(%ebp) 151 jmp .Lfinal 152.Lsecond_carry: 153 movl $0x80000000,-8(%ebp) 154 addl $1,%ecx 155 movl %ecx,-4(%ebp) 156.Lfinal: 157 fstp %st(0) 158 fldt -12(%ebp) 159 andl $0x00007fff,%ecx 160 jz .Lunderflow 161 cmpw $0x7fff,%cx 162 je .Loverflow 163 jmp .Lreturn 164.Loverflow: 165 PIC_SETUP(1) 166 fldt PIC_L(.LFmaxl) 167 PIC_WRAPUP 168 fmulp %st,%st(0) / create overflow signal 169 jmp .Lreturn 170.Lunderflow: 171 PIC_SETUP(2) 172 fldt PIC_L(.LFminl) 173 PIC_WRAPUP 174 fmulp %st,%st(0) / create underflow signal 175 jmp .Lreturn 176.Lequal: 177 fstp %st(0) / C99 says to return y when x == y 178 jmp .Lreturn 179.LNaN: 180 faddp %st,%st(1) / x+y,x 181.Lreturn: 182 fwait 183 leave 184 ret 185 .align 4 186 SET_SIZE(nextafterl) 187