mirror of https://github.com/lianthony/NT4.0
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
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
|