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 "nexttowardl.s" 30 31#include "libm.h" 32LIBM_ANSI_PRAGMA_WEAK(nexttowardl,function) 33 34 .section .rodata 35 .align 4 36.LFmaxl: .long 0xffffffff,0xffffffff,0x00007ffe 37.LFminl: .long 0x1,0x0,0x0 38 39 40 ENTRY(nexttowardl) 41 pushl %ebp 42 movl %esp,%ebp 43 fldt 20(%ebp) / y 44 subl $12,%esp 45 fldt 8(%ebp) / load x 46 fucom / x : y 47 fstsw %ax 48 sahf 49 jp .LNaN 50 je .Lequal 51 fstp %st(1) / x 52 ja .Lbigger 53 / x < y 54 ftst 55 movl $1,-12(%ebp) /// -12(%ebp) contains Fminl 56 movl $0,-8(%ebp) 57 movl $0,%ecx /// final needs this 58 movl %ecx,-4(%ebp) 59 fnstsw %ax 60 sahf 61 je .Lfinal 62 ja .Laddulp 63 jb .Lsubulp 64.Lbigger: 65 / x > y 66 ftst 67 movl $1,-12(%ebp) /// -12(%ebp) contains -Fminl 68 movl $0,-8(%ebp) 69 movl $0x00008000,%ecx /// final needs this 70 movl %ecx,-4(%ebp) 71 fnstsw %ax 72 sahf 73 je .Lfinal 74 jb .Laddulp 75.Lsubulp: 76 movl 12(%ebp),%edx / high word of significand of x 77 movl 16(%ebp),%ecx / x's exponent 78 andl $0x0000ffff,%ecx 79 movl %edx,%eax 80 not %eax 81 andl $0x80000000,%eax / look at explicit leading bit 82 orl %ecx,%eax 83 andl $0x80007fff,%eax 84 jnz .Lnot_pseudonormal / zero value implies pseudonormal 85 addl $1,%ecx / if pseudonormal, turn into equivalent normal 86.Lnot_pseudonormal: 87 movl 8(%ebp),%eax / low x 88 subl $1,%eax / low x - ulp 89 movl %eax,-12(%ebp) 90 cmpl $0xffffffff,%eax / this means low x was 0 91 jz .Lborrow 92 movl %edx,-8(%ebp) 93 movl %ecx,-4(%ebp) 94 jmp .Lfinal 95.Lborrow: 96 cmpl $0x80000000,%edx / look at high x 97 je .Lsecond_borrow 98 subl $1,%edx 99 movl %edx,-8(%ebp) 100 movl %ecx,-4(%ebp) 101 jmp .Lfinal 102.Lsecond_borrow: 103 movl %ecx,%eax 104 andl $0x7fff,%eax / look at exp x without sign bit 105 cmpl $1,%eax 106 jbe .Lsubnormal_result / exp > 1 ==> result will be normal 107 movl $0xffffffff,-8(%ebp) 108 subl $1,%ecx 109 movl %ecx,-4(%ebp) 110 jmp .Lfinal 111.Lsubnormal_result: 112 movl $0x7fffffff,-8(%ebp) 113 movl %ecx,%eax 114 andl $0x8000,%eax / look at sign bit 115 jz .Lpositive 116 movl $0x8000,%ecx 117 movl %ecx,-4(%ebp) 118 jmp .Lfinal 119.Lpositive: 120 movl $0,%ecx 121 movl %ecx,-4(%ebp) 122 jmp .Lfinal 123.Laddulp: 124 movl 12(%ebp),%edx / high x 125 movl 16(%ebp),%ecx / x's exponent 126 andl $0x0000ffff,%ecx 127 movl %edx,%eax 128 not %eax 129 andl $0x80000000,%eax / look at explicit leading bit 130 orl %ecx,%eax 131 andl $0x80007fff,%eax 132 jnz .Lnot_pseudonormal_2 / zero value implies pseudonormal 133 addl $1,%ecx 134.Lnot_pseudonormal_2: 135 movl 8(%ebp),%eax / low x 136 addl $1,%eax / low x + ulp 137 movl %eax,-12(%ebp) 138 jz .Lcarry / jump if the content of %eax is 0 139 movl %edx,-8(%ebp) 140 movl %ecx,-4(%ebp) 141 jmp .Lfinal 142.Lcarry: 143 movl %edx,%eax 144 andl $0x7fffffff,%eax 145 cmpl $0x7fffffff,%eax / look at high x 146 je .Lsecond_carry 147 addl $1,%edx 148 movl %edx,-8(%ebp) 149 movl %ecx,-4(%ebp) 150 jmp .Lfinal 151.Lsecond_carry: 152 movl $0x80000000,-8(%ebp) 153 addl $1,%ecx 154 movl %ecx,-4(%ebp) 155.Lfinal: 156 fstp %st(0) 157 fldt -12(%ebp) 158 andl $0x00007fff,%ecx 159 jz .Lunderflow 160 cmpw $0x7fff,%cx 161 je .Loverflow 162 jmp .Lreturn 163.Loverflow: 164 PIC_SETUP(1) 165 fldt PIC_L(.LFmaxl) 166 PIC_WRAPUP 167 fmulp %st,%st(0) / create overflow signal 168 jmp .Lreturn 169.Lunderflow: 170 PIC_SETUP(2) 171 fldt PIC_L(.LFminl) 172 PIC_WRAPUP 173 fmulp %st,%st(0) / create underflow signal 174 jmp .Lreturn 175.Lequal: 176 fstp %st(0) / C99 says to return y when x == y 177 jmp .Lreturn 178.LNaN: 179 faddp %st,%st(1) / x+y,x 180.Lreturn: 181 fwait 182 leave 183 ret 184 .align 4 185 SET_SIZE(nexttowardl) 186