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 "hypot.s" 30 31 #include "libm.h" 32 LIBM_ANSI_PRAGMA_WEAK(hypot,function) 33 #include "libm_synonyms.h" 34 #include "libm_protos.h" 35 36 #undef fabs 37 38 .data 39 .align 4 40 inf: 41 .long 0x7f800000 42 43 ENTRY(hypot) 44 movl 8(%esp),%eax / eax <-- hi_32(x) 45 andl $0x7fffffff,%eax / eax <-- hi_32(|x|) 46 jz .x_maybe_0 / if x = +/-0, return |y| 47 subl $0x7ff00000,%eax / eax <-- hi_32(|x|) - hi_32(INF) 48 jz .x_maybe_inf 49 .check_y: 50 movl 16(%esp),%eax / eax <-- hi_32(y) 51 andl $0x7fffffff,%eax / eax <-- hi_32(|y|) 52 jz .y_maybe_0 / if y = +/-0, return |x| 53 subl $0x7ff00000,%eax / eax <-- hi_32(|y|) - hi_32(INF) 54 jz .y_maybe_inf 55 .do_hypot: 56 fldl 12(%esp) / ,y 57 fmul %st(0),%st / ,y*y 58 fldl 4(%esp) / x,y*y 59 fmul %st(0),%st / x*x,y*y 60 faddp %st,%st(1) / x*x+y*y 61 fsqrt / sqrt(x*x+y*y) 62 subl $8,%esp 63 fstpl (%esp) / round to double 64 fldl (%esp) / sqrt(x*x+y*y) rounded to double 65 PIC_SETUP(1) 66 flds PIC_L(inf) / inf , sqrt(x*x+y*y) 67 PIC_WRAPUP 68 addl $8,%esp 69 fucomp 70 fstsw %ax / store status in %ax 71 sahf / 80387 flags in %ah to 80386 flags 72 jz .maybe_ovflw 73 ret 74 75 .maybe_ovflw: 76 jnp .ovflw 77 ret 78 79 .ovflw: 80 / overflow occurred 81 fstp %st(0) / stack empty 82 pushl %ebp 83 movl %esp,%ebp 84 PIC_SETUP(2) 85 pushl $4 86 pushl 20(%ebp) / high y 87 pushl 16(%ebp) / low y 88 pushl 12(%ebp) / high x 89 pushl 8(%ebp) / low x 90 call PIC_F(_SVID_libm_err) 91 addl $20,%esp 92 PIC_WRAPUP 93 leave 94 ret 95 96 .x_maybe_0: 97 movl 4(%esp),%ecx / ecx <-- lo_32(x) 98 orl %ecx,%eax / is x = +/-0? 99 jnz .check_y / branch if x is denormal 100 / x = +/-0, so return |y| 101 fldl 12(%esp) 102 fabs 103 ret 104 105 .x_maybe_inf: 106 movl 4(%esp),%ecx / ecx <-- lo_32(x) 107 orl %ecx,%eax / is x = +/-INF? 108 jnz .check_y / branch if x is NaN 109 / push&pop y in case y is a SNaN 110 fldl 12(%esp) 111 fstp %st(0) 112 / x = +/-INF, so return |x| 113 fldl 4(%esp) 114 fabs 115 ret 116 117 .y_maybe_0: 118 movl 12(%esp),%ecx / ecx <-- lo_32(y) 119 orl %ecx,%eax / is y = +/-0? 120 jnz .do_hypot / branch if y is denormal 121 / y = +/-0, so return |x| 122 fldl 4(%esp) 123 fabs 124 ret 125 126 .y_maybe_inf: 127 movl 12(%esp),%ecx / ecx <-- lo_32(y) 128 orl %ecx,%eax / is y = +/-INF? 129 jnz .do_hypot / branch if y is NaN 130 / push&pop x in case x is a SNaN 131 fldl 4(%esp) 132 fstp %st(0) 133 / y = +/-INF, so return |y| 134 fldl 12(%esp) 135 fabs 136 ret 137 .align 4 138 SET_SIZE(hypot)