Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

264 lines
5.5 KiB

/*
* |-----------------------------------------------------------|
* | Copyright (c) 1991, 1990 MIPS Computer Systems, Inc. |
* | All Rights Reserved |
* |-----------------------------------------------------------|
* | Restricted Rights Legend |
* | Use, duplication, or disclosure by the Government is |
* | subject to restrictions as set forth in |
* | subparagraph (c)(1)(ii) of the Rights in Technical |
* | Data and Computer Software Clause of DFARS 252.227-7013. |
* | MIPS Computer Systems, Inc. |
* | 950 DeGuigne Avenue |
* | Sunnyvale, California 94088-3650, USA |
* |-----------------------------------------------------------|
*/
/* $Header: atan.s,v 3000.10.1.3 91/07/17 14:05:38 zaineb Exp $ */
/* These functions are based on the 4.3bsd algorithm. */
#include <kxmips.h>
#include <trans.h>
#define OP_ATAN 15
#define OP_ATAN2 16
#define r7_16 0.4375
#define r11_16 0.6875
#define r19_16 1.1875
#define r39_16 2.4375
#define one 1.0
#define athfhi 4.6364760900080609352E-1
#define athflo 4.6249969567426939759E-18
#define PIo4 7.8539816339744827900E-1
#define at1fhi 9.8279372324732905408E-1
#define at1flo -2.4407677060164810007E-17
#define PIo2 1.5707963267948965580E0
#define PI 3.1415926535897931160E0
#define p11 1.6438029044759730479E-2
#define p10 -3.6700606902093604877E-2
#define p9 4.9850617156082015213E-2
#define p8 -5.8358371008508623523E-2
#define p7 6.6614695906082474486E-2
#define p6 -7.6919217767468239799E-2
#define p5 9.0908906105474668324E-2
#define p4 -1.1111110579344973814E-1
#define p3 1.4285714278004377209E-1
#define p2 -1.9999999999979536924E-1
#define p1 3.3333333333333942106E-1
/* double atan(double y) */
.text .text$atanm
.globl atan
.ent atan
atan:
.set noreorder
.frame sp, 0, ra
.prologue 0
c.un.d $f12, $f12 /* if Y is NaN */
mfc1 t0, $f13 /* save sign of Y */
li t7, OP_ATAN
bc1t 91f
li t1, 0 /* sign of X */
abs.d $f12
li.d $f14, one /* X = 1.0 */
mov.d $f2, $f12 /* Y/X = Y */
cfc1 t4, $31 /* save FCSR, set round to nearest */
ctc1 $0, $31 /* mode and no exceptions */
b atan0
nop
.set reorder
.end atan
/* double atan2(double y, double x) */
.text .text$atanm
.globl atan2
.ent atan2
atan2:
.frame sp, 0, ra
.prologue 0
c.un.d $f12, $f14 /* if either Y or X is NaN */
mfc1 t0, $f13 /* save signs of Y and X */
mfc1 t1, $f15
li t7, OP_ATAN2
bc1t 90f
abs.d $f12
abs.d $f14
cfc1 t4, $31 /* save FCSR, set round to nearest */
ctc1 $0, $31 /* mode and no exceptions */
div.d $f2, $f12, $f14 /* atan2(y,x) = atan(y/x) */
li t5, 0x7ff00000<<1
sll t3, t1, 1
#define _FPC_CSR_INVALID 0x00000040
cfc1 t6, $31 /* check if it is a 0/0 */
and t6, _FPC_CSR_INVALID
beq t3, t5, 80f
bne t6, 0, 78f
atan0:
/* analyze range of y/x */
li.d $f6, r19_16
li.d $f8, r11_16
c.lt.d $f2, $f6
li.d $f6, r39_16
bc1f 30f
c.lt.d $f2, $f8
li.d $f8, r7_16
bc1f 20f
c.lt.d $f2, $f8
bc1f 10f
/* [0, 7/16] */
li.d $f12, 0.0
mov.d $f14, $f12
b 70f
10: /* [7/16,11/16] */
add.d $f4, $f14, $f14
add.d $f2, $f12, $f12
sub.d $f2, $f14
add.d $f4, $f12
div.d $f2, $f4
li.d $f12, athfhi
li.d $f14, athflo
b 70f
20: /* [11/16,19/16] */
sub.d $f2, $f12, $f14
add.d $f4, $f12, $f14
div.d $f2, $f4
li.d $f12, PIo4
li.d $f14, 0.0
b 70f
30: /* >= 19/16 */
c.lt.d $f2, $f6
bc1f 40f
/* [19/16,39/16] */
add.d $f2, $f12, $f12
add.d $f2, $f12
add.d $f4, $f14, $f14
add.d $f2, $f4
sub.d $f4, $f12, $f14
add.d $f4, $f4
sub.d $f4, $f14
div.d $f2, $f4, $f2
li.d $f12, at1fhi
li.d $f14, at1flo
b 70f
40: /* >= 39/16 */
neg.d $f14
div.d $f2, $f14, $f12
li.d $f12, PIo2
li.d $f14, 0.0
70: mul.d $f4, $f2, $f2
li.d $f6, p11
li.d $f8, p10
mul.d $f0, $f4, $f6
add.d $f0, $f8
li.d $f6, p9
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p8
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p7
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p6
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p5
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p4
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p3
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p2
mul.d $f0, $f4
add.d $f0, $f6
li.d $f6, p1
mul.d $f0, $f4
add.d $f0, $f6
mul.d $f0, $f4
mul.d $f0, $f2
sub.d $f0, $f14, $f0
add.d $f0, $f2
ctc1 t4, $31
li.d $f6, PI
add.d $f0, $f12
bgez t1, 72f
sub.d $f0, $f6, $f0
72:
bgez t0, 74f
neg.d $f0
74:
j ra
78: /* x = y = 0 */
j setup_atan2_error
li.d $f0, 0.0
b 82f
80: /* x = +-Infinity */
li.d $f0, 0.0
sll t2, t0, 1
bne t2, t5, 82f
/* x = +-Infinity, y = +-Infinity */
li.d $f0, PIo4
82: li.d $f6, PI
bgez t1, 84f
sub.d $f0, $f6, $f0
84: ctc1 t4, $31
bgez t0, 86f
neg.d $f0
86: j ra
90: /* x NaN or y NaN */
c.eq.d $f12, $f12
bc1t 92f
91: mov.d $f0, $f12
j ra
92: mov.d $f0, $f14
j ra
.end atan2
.extern _except2
.extern _d_ind 8
#define QNAN_ATAN2 D_IND
#define D_IND _d_ind
.ent setup_atan2_error
setup_atan2_error:
#define FSIZE 48
.frame sp, FSIZE, ra
.mask 0x80000000, -4
subu sp, FSIZE
sw ra, FSIZE-4(sp)
.prologue 1
li $4, FP_I // exception mask
move $5, t7 // operation code (funtion name index)
mfc1.d $6, $f12 // arg1
s.d $f14, 16(sp) // arg2
l.d $f0, QNAN_ATAN2
s.d $f0, 24(sp) // default result
xor t7, t4, 0xf80 // inverse exception enable bits (t4 = saved FCSR)
sw t7, 32(sp)
jal _except2
lw ra, FSIZE-4(sp)
addu sp, FSIZE
j ra
#undef FSIZE
.end setup_atan2_error