1 /* $NetBSD: n_atan2.S,v 1.9 2014/10/10 20:58:09 martin Exp $ */
3 * Copyright (c) 1985, 1993
4 * The Regents of the University of California. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * @(#)atan2.s 8.1 (Berkeley) 6/4/93
33 #include <machine/asm.h>
38 * VAX D FORMAT (56 BITS PRECISION)
39 * CODED IN VAX ASSEMBLY LANGUAGE BY K.C. NG, 4/16/85;
43 * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
44 * 2. Reduce x to positive by (if x and y are unexceptional):
45 * ARG (x+iy) = arctan(y/x) ... if x > 0,
46 * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
47 * 3. According to the integer k=4t+0.25 truncated , t=y/x, the argument
48 * is further reduced to one of the following intervals and the
49 * arctangent of y/x is evaluated by the corresponding formula:
51 * [0,7/16] atan(y/x) = t - t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
52 * [7/16,11/16] atan(y/x) = atan(1/2) + atan( (y-x/2)/(x+y/2) )
53 * [11/16.19/16] atan(y/x) = atan( 1 ) + atan( (y-x)/(x+y) )
54 * [19/16,39/16] atan(y/x) = atan(3/2) + atan( (y-1.5x)/(x+1.5y) )
55 * [39/16,INF] atan(y/x) = atan(INF) + atan( -x/y )
58 * Notations: atan2(y,x) == ARG (x+iy) == ARG(x,y).
60 * ARG( NAN , (anything) ) is NaN;
61 * ARG( (anything), NaN ) is NaN;
62 * ARG(+(anything but NaN), +-0) is +-0 ;
63 * ARG(-(anything but NaN), +-0) is +-PI ;
64 * ARG( 0, +-(anything but 0 and NaN) ) is +-PI/2;
65 * ARG( +INF,+-(anything but INF and NaN) ) is +-0 ;
66 * ARG( -INF,+-(anything but INF and NaN) ) is +-PI;
67 * ARG( +INF,+-INF ) is +-PI/4 ;
68 * ARG( -INF,+-INF ) is +-3PI/4;
69 * ARG( (anything but,0,NaN, and INF),+-INF ) is +-PI/2;
72 * atan2(y,x) returns the exact ARG(x+iy) nearly rounded.
76 WEAK_ALIAS(atan2f, _atan2f)
81 calls $2,_C_LABEL(_atan2)
86 WEAK_ALIAS(atan2, _atan2)
87 WEAK_ALIAS(_atan2l, _atan2)
91 movq 4(%ap),%r2 # %r2 = y
92 movq 12(%ap),%r4 # %r4 = x
95 cmpw %r0,$0x8000 # y is the reserved operand
97 cmpw %r1,$0x8000 # x is the reserved operand
100 bicw3 $0x7fff,%r2,-4(%fp) # copy y sign bit to -4(%fp)
101 bicw3 $0x7fff,%r4,-8(%fp) # copy x sign bit to -8(%fp)
102 cmpd %r4,$0x4080 # x = 1.0 ?
105 bicw2 $0x8000,%r0 # t = |y|
106 movq %r0,%r2 # y = |y|
109 bicw3 $0x807f,%r2,%r11 # yexp
110 jeql yeq0 # if y=0 goto yeq0
111 bicw3 $0x807f,%r4,%r10 # xexp
112 jeql pio2 # if x=0 goto pio2
113 subw2 %r10,%r11 # k = yexp - xexp
114 cmpw %r11,$0x2000 # k >= 64 (exp) ?
115 jgeq pio2 # atan2 = +-pi/2
116 divd3 %r4,%r2,%r0 # t = y/x never overflow
117 bicw2 $0x8000,%r0 # t > 0
118 bicw2 $0xff80,%r2 # clear the exponent of y
119 bicw2 $0xff80,%r4 # clear the exponent of x
120 bisw2 $0x4080,%r2 # normalize y to [1,2)
121 bisw2 $0x4080,%r4 # normalize x to [1,2)
122 subw2 %r11,%r4 # scale x so that yexp-xexp=k
124 cmpw %r0,$0x411c # t : 39/16
126 addl3 $0x180,%r0,%r10 # 8*t
127 cvtrfl %r10,%r10 # [8*t] rounded to int
128 ashl $-1,%r10,%r10 # [8*t]/2
137 movq $0xb4d9940f985e407b,%r6 # Hi=.98279372324732906796d0
138 movq $0x21b1879a3bc2a2fc,%r8 # Lo=-.17092002525602665777d-17
139 subd3 %r4,%r2,%r0 # y-x
140 addw2 $0x80,%r0 # 2(y-x)
141 subd2 %r4,%r0 # 2(y-x)-x
144 addw2 $0x80,%r10 # 2y
146 addd2 %r4,%r2 # 3y+2x
147 divd2 %r2,%r0 # (2y-3x)/(2x+3y)
150 cmpw %r0,$0x3280 # t : 2**(-28)
152 clrq %r6 # Hi=%r6=0, Lo=%r8=0
156 movq $0xda7b2b0d63383fed,%r6 # Hi=.46364760900080611433d0
157 movq $0xf0ea17b2bf912295,%r8 # Lo=.10147340032515978826d-17
163 divd2 %r4,%r0 # (2y-x)/(2x+y)
166 movq $0x68c2a2210fda40c9,%r6 # Hi=1.5707963267948966135d1
167 movq $0x06e0145c26332326,%r8 # Lo=.22517417741562176079d-17
168 cmpw %r0,$0x5100 # y : 2**57
171 bisw2 $0x8000,%r0 # -x/y
174 movq $0x68c2a2210fda4049,%r6 # Hi=.78539816339744830676d0
175 movq $0x06e0145c263322a6,%r8 # Lo=.11258708870781088040d-17
176 subd3 %r4,%r2,%r0 # y-x
178 divd2 %r2,%r0 # (y-x)/(y+x)
190 bisw2 -4(%fp),%r0 # return sign(y)*%r0
196 subd3 %r0,$0x68c2a2210fda4149,%r0 # pi-t
201 beql zero # if sign(x)=1 return pi
202 movq $0x68c2a2210fda4149,%r0 # pi=3.1415926535897932270d1
208 movq $0x68c2a2210fda40c9,%r0 # pi/2=1.5707963267948966135d1
209 bisw2 -4(%fp),%r0 # return sign(y)*pi/2
212 movq $0x8000,%r0 # propagate the reserved operand
217 .quad 0xb50f5ce96e7abd60
218 .quad 0x51e44a42c1073e02
219 .quad 0x3487e3289643be35
220 .quad 0xdb62066dffba3e54
221 .quad 0xcf8e2d5199abbe70
222 .quad 0x26f39cb884883e88
223 .quad 0x135117d18998be9d
224 .quad 0x602ce9742e883eba
225 .quad 0xa35ad0be8e38bee3
226 .quad 0xffac922249243f12
227 .quad 0x7f14ccccccccbf4c
228 .quad 0xaa8faaaaaaaa3faa
229 .quad 0x0000000000000000