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.
934 lines
23 KiB
934 lines
23 KiB
// TITLE("Alpha AXP Tangent")
|
|
//++
|
|
//
|
|
// Copyright (c) 1993, 1994 Digital Equipment Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// tan.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements a high-performance Alpha AXP specific routine
|
|
// for IEEE double format tangent.
|
|
//
|
|
// Author:
|
|
//
|
|
// Bob Hanek 1-Oct-1991
|
|
//
|
|
// Environment:
|
|
//
|
|
// User mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Thomas Van Baak (tvb) 13-Feb-1994
|
|
//
|
|
// Adapted for NT.
|
|
//
|
|
//--
|
|
|
|
#include "ksalpha.h"
|
|
|
|
//
|
|
// Define DPML exception record for NT.
|
|
//
|
|
|
|
.struct 0
|
|
ErErr: .space 4 // error code
|
|
ErCxt: .space 4 // context
|
|
ErPlat: .space 4 // platform
|
|
ErEnv: .space 4 // environment
|
|
ErRet: .space 4 // return value pointer
|
|
ErName: .space 4 // function name
|
|
ErType: .space 8 // flags and fill
|
|
ErVal: .space 8 // return value
|
|
ErArg0: .space 8 // arg 0
|
|
ErArg1: .space 8 // arg 1
|
|
ErArg2: .space 8 // arg 2
|
|
ErArg3: .space 8 // arg 3
|
|
DpmlExceptionLength:
|
|
|
|
//
|
|
// Define stack frame.
|
|
//
|
|
|
|
.struct 0
|
|
SaveS0: .space 8 //
|
|
SaveS1: .space 8 //
|
|
SaveS2: .space 8 //
|
|
SaveRa: .space 8 //
|
|
SaveF2: .space 8 //
|
|
SaveF3: .space 8 //
|
|
SaveF4: .space 8 //
|
|
SaveF5: .space 8 //
|
|
SaveF6: .space 8 //
|
|
SaveF7: .space 8 //
|
|
SaveF8: .space 8 //
|
|
SaveF9: .space 8 //
|
|
Temp0: .space 8 //
|
|
Temp1: .space 8 //
|
|
Temp2: .space 8 //
|
|
Temp3: .space 8 //
|
|
ExRec: .space DpmlExceptionLength // exception record
|
|
.space 8 // for 16-byte stack alignment
|
|
FrameLength:
|
|
|
|
//
|
|
// Define lower and upper 32-bit parts of 64-bit double.
|
|
//
|
|
|
|
#define LowPart 0x0
|
|
#define HighPart 0x4
|
|
|
|
//
|
|
// Define argument range values.
|
|
//
|
|
|
|
#define BIG_X_HI 0x4169 // upper bound of medium argument range
|
|
#define BIG_X_LO 0x21fb
|
|
#define SMALL_X_HI 0x3e40 // lower bound of medium argument range
|
|
#define SMALL_X_LO 0x0000
|
|
#define EXP_WORD_OF_TWO_PI_HI 0x4019
|
|
#define EXP_WORD_OF_TWO_PI_LO 0x21fb
|
|
|
|
//
|
|
// Define table offsets.
|
|
//
|
|
|
|
#define D_2_POW_K_OVER_PI_OVER_4 0x0
|
|
#define PI_OVER_4_OVER_2_POW_K_0 0x08
|
|
#define PI_OVER_4_OVER_2_POW_K_1 0x10
|
|
#define PI_OVER_4_OVER_2_POW_K_2 0x18
|
|
#define PI_OVER_4_OVER_2_POW_K_3 0x20
|
|
#define PI_OVER_4_OVER_2_POW_K_4 0x28
|
|
|
|
#define PI_OVER_2_HI 0x30
|
|
#define PI_OVER_2_LO 0x38
|
|
#define PI_HI 0x40
|
|
#define PI_LO 0x48
|
|
#define THREE_PI_OVER_2_HI 0x50
|
|
#define THREE_PI_OVER_2_LO 0x58
|
|
#define TWO_PI_HI 0x60
|
|
#define TWO_PI_LO 0x68
|
|
#define TWO_POW_K_OVER_PI_OVER_4 0x70
|
|
|
|
#define E_POLY0 0xa58
|
|
#define E_POLY1 E_POLY0 + 8
|
|
#define E_POLY2 E_POLY1 + 8
|
|
#define E_POLY3 E_POLY2 + 8
|
|
#define E_POLY4 E_POLY3 + 8
|
|
#define E_POLY5 E_POLY4 + 8
|
|
#define E_POLY6 E_POLY5 + 8
|
|
|
|
#define F_POLY0 0xa90
|
|
#define F_POLY1 F_POLY0 + 8
|
|
#define F_POLY2 F_POLY1 + 8
|
|
#define F_POLY3 F_POLY2 + 8
|
|
#define F_POLY4 F_POLY3 + 8
|
|
#define F_POLY5 F_POLY4 + 8
|
|
|
|
#define G_POLY0 0xac0
|
|
#define G_POLY1 G_POLY0 + 8
|
|
|
|
#define TANCOT_A 0xad0
|
|
#define TAN_A 0xad8
|
|
#define COT_A 0xae0
|
|
#define TAN_COT_A 0xae8
|
|
|
|
SBTTL("Tangent")
|
|
|
|
//++
|
|
//
|
|
// double
|
|
// tan (
|
|
// IN double x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function returns the tangent of the given double argument.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// x (f16) - Supplies the argument value.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The double tangent result is returned as the function value in f0.
|
|
//
|
|
//--
|
|
|
|
NESTED_ENTRY(tan, FrameLength, ra)
|
|
|
|
lda sp, -FrameLength(sp) // allocate stack frame
|
|
stq s0, SaveS0(sp)
|
|
stq s1, SaveS1(sp)
|
|
stq s2, SaveS2(sp)
|
|
stq ra, SaveRa(sp)
|
|
stt f2, SaveF2(sp)
|
|
stt f3, SaveF3(sp)
|
|
stt f4, SaveF4(sp)
|
|
stt f5, SaveF5(sp)
|
|
stt f6, SaveF6(sp)
|
|
stt f7, SaveF7(sp)
|
|
stt f8, SaveF8(sp)
|
|
stt f9, SaveF9(sp)
|
|
|
|
PROLOGUE_END
|
|
|
|
ornot zero, zero, t0
|
|
srl t0, 33, t0
|
|
ldah t1, SMALL_X_HI(zero)
|
|
ldah t2, BIG_X_HI - SMALL_X_HI(zero)
|
|
lda t2, BIG_X_LO - SMALL_X_LO(t2)
|
|
stt f16, Temp2(sp)
|
|
cpys f31, f16, f2
|
|
ldl v0, Temp2 + HighPart(sp)
|
|
cpys f16, f16, f3
|
|
and v0, t0, v0 // the exponent field of the argument
|
|
subl v0, t1, t0 // if v0 - small <= big - small
|
|
cmpult t0, t2, t0 // we've got an abnormal argument
|
|
beq t0, abnormal_argument
|
|
|
|
ldah t2, EXP_WORD_OF_TWO_PI_HI(zero) // if (j >= EXP_WORD_OF_TWO_PI)
|
|
lda t2, EXP_WORD_OF_TWO_PI_LO(t2) // we have a medium argument
|
|
cmplt v0, t2, t2
|
|
beq t2, medium_argument
|
|
|
|
//
|
|
// small argument reduction
|
|
//
|
|
// reduce the argument X to ( 8 * N + I ) * pi / 2 + y
|
|
// and let the reduced argument be y' where
|
|
// y' = X - floor( ( 8 * N + I + 1 ) / 2 ) * pi / 2
|
|
// the low 3 bits of I are the octant
|
|
//
|
|
|
|
lda t0, __trig_cons
|
|
ldt f0, TWO_POW_K_OVER_PI_OVER_4(t0)
|
|
mult f2, f0, f0
|
|
cvttqc f0, f1
|
|
stt f1, Temp2(sp)
|
|
ldl t2, Temp2(sp)
|
|
sra t2, 7, t4
|
|
cmpule t4, 7, t12
|
|
beq t12, small_tan // if octant > 7; shouldn't happen
|
|
|
|
// dispatch on octant
|
|
|
|
lda t12, Switch2
|
|
s4addl t4, t12, t12
|
|
ldl t12, 0(t12)
|
|
jmp zero, (t12)
|
|
|
|
//
|
|
// 1st octant; compute tan(y')
|
|
//
|
|
Switch20:
|
|
and t2, 127, t5
|
|
subl t5, 35, t5
|
|
blt t5, small_tan
|
|
|
|
s4addl t5, zero, t5
|
|
s8addl t5, t0, s0
|
|
ldt f0, TANCOT_A(s0)
|
|
ldt f5, TAN_A(s0)
|
|
ldt f6, COT_A(s0)
|
|
subt f2, f0, f4
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 2nd octant; compute -cot(y')
|
|
//
|
|
Switch21:
|
|
ldt f1, PI_OVER_2_HI(t0)
|
|
ornot zero, t2, t4
|
|
and t4, 127, t4
|
|
ldt f10, PI_OVER_2_LO(t0)
|
|
subl t4, 35, t4
|
|
subt f2, f1, f1
|
|
blt t4, neg_cot_1
|
|
|
|
s4addl t4, zero, t4
|
|
s8addl t4, t0, s0
|
|
ldt f0, TANCOT_A(s0)
|
|
ldt f6, TAN_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
addt f1, f0, f0
|
|
subt f0, f10, f4
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 3rd octant; compute -cot(y')
|
|
//
|
|
Switch22:
|
|
ldt f0, PI_OVER_2_HI(t0)
|
|
and t2, 127, t3
|
|
ldt f10, PI_OVER_2_LO(t0)
|
|
subl t3, 35, t3
|
|
subt f2, f0, f1
|
|
blt t3, neg_cot_1
|
|
|
|
s4addl t3, zero, t3
|
|
s8addl t3, t0, s0
|
|
ldt f6, TANCOT_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
subt f1, f6, f6
|
|
subt f10, f6, f4
|
|
ldt f6, TAN_A(s0)
|
|
br zero, neg_tab_eval
|
|
|
|
//
|
|
// 4th octant; compute tan(y')
|
|
//
|
|
Switch23:
|
|
ldt f0, PI_HI(t0)
|
|
ornot zero, t2, t5
|
|
and t5, 127, t5
|
|
ldt f11, PI_LO(t0)
|
|
subl t5, 35, t5
|
|
subt f2, f0, f0
|
|
blt t5, pos_tan_1
|
|
|
|
s4addl t5, zero, t5
|
|
s8addl t5, t0, s0
|
|
ldt f6, TANCOT_A(s0)
|
|
addt f0, f6, f6
|
|
subt f11, f6, f4
|
|
br zero, neg_tab_eval1
|
|
|
|
//
|
|
// 5th octant; compute tan(y')
|
|
//
|
|
Switch24:
|
|
ldt f11, PI_HI(t0)
|
|
and t2, 127, t4
|
|
subl t4, 35, t4
|
|
subt f2, f11, f0
|
|
ldt f11, PI_LO(t0)
|
|
blt t4, pos_tan_1
|
|
|
|
s4addl t4, zero, t4
|
|
s8addl t4, t0, s0
|
|
ldt f6, TANCOT_A(s0)
|
|
ldt f5, TAN_A(s0)
|
|
subt f0, f6, f6
|
|
subt f6, f11, f4
|
|
ldt f6, COT_A(s0)
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 6th octant; compute -cot(y')
|
|
//
|
|
Switch25:
|
|
ldt f11, THREE_PI_OVER_2_HI(t0)
|
|
ornot zero, t2, t3
|
|
and t3, 127, t3
|
|
ldt f10, THREE_PI_OVER_2_LO(t0)
|
|
subl t3, 35, t3
|
|
subt f2, f11, f1
|
|
blt t3, neg_cot_1
|
|
|
|
s4addl t3, zero, t3
|
|
s8addl t3, t0, s0
|
|
ldt f6, TANCOT_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
addt f1, f6, f6
|
|
subt f6, f10, f4
|
|
ldt f6, TAN_A(s0)
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 7th octant; compute -cot(y')
|
|
//
|
|
Switch26:
|
|
ldt f10, THREE_PI_OVER_2_HI(t0)
|
|
and t2, 127, t5
|
|
subl t5, 35, t5
|
|
subt f2, f10, f1
|
|
ldt f10, THREE_PI_OVER_2_LO(t0)
|
|
blt t5, neg_cot_1
|
|
|
|
s4addl t5, zero, t5
|
|
s8addl t5, t0, s0
|
|
ldt f6, TANCOT_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
subt f1, f6, f6
|
|
subt f10, f6, f4
|
|
ldt f6, TAN_A(s0)
|
|
br zero, neg_tab_eval
|
|
|
|
neg_cot_1:
|
|
subt f1, f10, f2
|
|
ldt f14, F_POLY5(t0)
|
|
ldt f4, One
|
|
ldt f19, F_POLY3(t0)
|
|
ldt f15, F_POLY4(t0)
|
|
divt f4, f2, f6
|
|
mult f2, f2, f12
|
|
cvtts f2, f13
|
|
mult f12, f14, f14
|
|
mult f12, f12, f18
|
|
mult f12, f19, f19
|
|
subt f1, f13, f1
|
|
addt f14, f15, f14
|
|
ldt f15, F_POLY2(t0)
|
|
subt f1, f10, f1
|
|
addt f19, f15, f15
|
|
ldt f19, F_POLY1(t0)
|
|
ldt f10, F_POLY0(t0)
|
|
mult f14, f18, f14
|
|
mult f12, f19, f12
|
|
mult f15, f18, f15
|
|
mult f14, f18, f14
|
|
addt f12, f10, f10
|
|
addt f15, f14, f14
|
|
addt f10, f14, f10
|
|
mult f2, f10, f2
|
|
cvtts f6, f17
|
|
mult f17, f13, f13
|
|
mult f17, f1, f1
|
|
subt f6, f17, f17
|
|
subt f4, f13, f4
|
|
subt f4, f1, f1
|
|
mult f1, f6, f1
|
|
subt f1, f17, f1
|
|
subt f2, f1, f1
|
|
subt f1, f6, f7
|
|
fbge f3, adjust_sign
|
|
cpysn f7, f7, f7
|
|
cpys f7, f7, f0
|
|
br zero, done
|
|
|
|
//
|
|
// 8th octant; compute tan(y')
|
|
//
|
|
Switch27:
|
|
ldt f18, TWO_PI_HI(t0)
|
|
ornot zero, t2, t2
|
|
and t2, 127, t2
|
|
ldt f11, TWO_PI_LO(t0)
|
|
subl t2, 35, t2
|
|
subt f2, f18, f0
|
|
blt t2, pos_tan_1
|
|
|
|
s4addl t2, zero, t2
|
|
s8addl t2, t0, s0
|
|
ldt f19, TANCOT_A(s0)
|
|
addt f0, f19, f19
|
|
subt f11, f19, f4
|
|
br zero, neg_tab_eval1
|
|
|
|
pos_tan_1:
|
|
subt f0, f11, f13
|
|
ldt f14, E_POLY1(t0)
|
|
ldt f10, E_POLY3(t0)
|
|
ldt f17, E_POLY4(t0)
|
|
ldt f18, E_POLY0(t0)
|
|
ldt f7, E_POLY2(t0)
|
|
ldt f1, E_POLY5(t0)
|
|
mult f13, f13, f15
|
|
ldt f2, E_POLY6(t0)
|
|
mult f15, f15, f12
|
|
mult f14, f15, f14
|
|
mult f10, f15, f10
|
|
mult f1, f15, f1
|
|
mult f13, f15, f13
|
|
mult f17, f12, f17
|
|
mult f2, f12, f2
|
|
addt f14, f18, f14
|
|
mult f7, f12, f7
|
|
mult f12, f12, f19
|
|
addt f10, f17, f10
|
|
addt f1, f2, f1
|
|
addt f14, f7, f7
|
|
mult f10, f12, f10
|
|
mult f1, f19, f1
|
|
addt f7, f10, f7
|
|
addt f1, f7, f1
|
|
mult f13, f1, f1
|
|
addt f11, f1, f1
|
|
subt f0, f1, f7
|
|
fbge f3, adjust_sign
|
|
cpysn f7, f7, f7
|
|
cpys f7, f7, f0
|
|
br zero, done
|
|
|
|
small_tan:
|
|
mult f2, f2, f6
|
|
ldt f17, E_POLY1(t0)
|
|
ldt f14, E_POLY3(t0)
|
|
ldt f12, E_POLY4(t0)
|
|
ldt f15, E_POLY0(t0)
|
|
ldt f13, E_POLY2(t0)
|
|
ldt f19, E_POLY5(t0)
|
|
mult f6, f6, f18
|
|
mult f17, f6, f17
|
|
ldt f10, E_POLY6(t0)
|
|
mult f14, f6, f14
|
|
mult f19, f6, f19
|
|
mult f2, f6, f6
|
|
mult f12, f18, f12
|
|
mult f10, f18, f10
|
|
addt f17, f15, f15
|
|
mult f13, f18, f13
|
|
mult f18, f18, f11
|
|
addt f14, f12, f12
|
|
addt f19, f10, f10
|
|
addt f15, f13, f13
|
|
mult f12, f18, f12
|
|
mult f10, f11, f10
|
|
addt f13, f12, f12
|
|
addt f10, f12, f10
|
|
mult f6, f10, f6
|
|
subt f2, f6, f7
|
|
fbge f3, adjust_sign
|
|
cpysn f7, f7, f7
|
|
cpys f7, f7, f0
|
|
br zero, done
|
|
|
|
//
|
|
// a medium argument
|
|
//
|
|
medium_argument:
|
|
lda t5, __trig_cons // reduce the argument with extra precision
|
|
ldt f0, D_2_POW_K_OVER_PI_OVER_4(t5)
|
|
mult f2, f0, f0
|
|
cvttqc f0, f1
|
|
stt f1, Temp2(sp)
|
|
ldl s1, Temp2(sp)
|
|
addl s1, 0x80, t2
|
|
bic t2, 0xff, t2
|
|
stq t2, Temp3(sp)
|
|
ldt f17, Temp3(sp)
|
|
ldt f19, PI_OVER_4_OVER_2_POW_K_0(t5)
|
|
ldt f15, PI_OVER_4_OVER_2_POW_K_1(t5)
|
|
cvtqt f17, f17
|
|
ldt f11, PI_OVER_4_OVER_2_POW_K_2(t5)
|
|
mult f17, f19, f19
|
|
mult f17, f15, f15
|
|
mult f17, f11, f11
|
|
subt f2, f19, f19
|
|
subt f19, f15, f18
|
|
subt f18, f19, f19
|
|
addt f15, f19, f15
|
|
addt f11, f15, f8
|
|
subt f18, f8, f9
|
|
cmpteq f9, f18, f13
|
|
fbne f13, evaluate
|
|
|
|
subt f9, f18, f18
|
|
ldt f12, PI_OVER_4_OVER_2_POW_K_3(t5)
|
|
mult f17, f12, f12
|
|
addt f8, f18, f8
|
|
addt f12, f8, f8
|
|
subt f9, f8, f10
|
|
cmpteq f10, f9, f6
|
|
fbne f6, evaluate
|
|
|
|
subt f10, f9, f9
|
|
ldt f0, PI_OVER_4_OVER_2_POW_K_4(t5)
|
|
mult f17, f0, f0
|
|
addt f8, f9, f8
|
|
addt f0, f8, f8
|
|
subt f10, f8, f9
|
|
cmpteq f9, f10, f1
|
|
fbne f1, evaluate
|
|
|
|
subt f9, f10, f10
|
|
addt f8, f10, f8
|
|
br zero, evaluate
|
|
|
|
//
|
|
// process an abnormal argument
|
|
// it's either very small, very big, a NaN or an Inf
|
|
//
|
|
abnormal_argument:
|
|
cmple v0, t1, t1
|
|
beq t1, big_NaN_or_Inf
|
|
|
|
cpys f3, f2, f0 // very small argument; simply return it.
|
|
br zero, done
|
|
|
|
//
|
|
// Process big arguments or NaNs or Infs
|
|
//
|
|
big_NaN_or_Inf:
|
|
ldah s2, 0x7ff0(zero) // mask is 0x7ff00000
|
|
and v0, s2, v0
|
|
xor v0, s2, v0
|
|
beq v0, NaN_or_Inf // NaN or an infinity
|
|
|
|
cpys f2, f2, f16 // reduce the very big argument carefully
|
|
mov zero, a1
|
|
lda a2, Temp0(sp)
|
|
lda a3, Temp1(sp)
|
|
bsr ra, __trig_reduce
|
|
mov v0, s1
|
|
ldt f9, Temp0(sp)
|
|
ldt f8, Temp1(sp)
|
|
|
|
//
|
|
// evaluate the function
|
|
//
|
|
evaluate:
|
|
sra s1, 7, t1
|
|
and t1, 7, t1
|
|
cmpule t1, 7, t12
|
|
beq t12, pos_tan_2
|
|
|
|
lda t12, Switch1
|
|
s4addl t1, t12, t12
|
|
ldl t12, 0(t12)
|
|
jmp zero, (t12)
|
|
|
|
//
|
|
// 1st octant; compute tan(y')
|
|
//
|
|
Switch10:
|
|
and s1, 127, t3
|
|
subl t3, 35, t3
|
|
blt t3, pos_tan_2
|
|
|
|
s4addl t3, zero, t3
|
|
lda t4, __trig_cons
|
|
s8addl t3, t4, s0
|
|
ldt f5, TANCOT_A(s0)
|
|
ldt f6, COT_A(s0)
|
|
subt f9, f5, f5
|
|
subt f5, f8, f4
|
|
ldt f5, TAN_A(s0)
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 2nd octant; compute -cot(y')
|
|
//
|
|
Switch11:
|
|
ornot zero, s1, t6
|
|
and t6, 127, t6
|
|
subl t6, 35, t6
|
|
blt t6, neg_cot_2
|
|
|
|
s4addl t6, zero, t6
|
|
lda t7, __trig_cons
|
|
s8addl t6, t7, s0
|
|
ldt f0, TANCOT_A(s0)
|
|
ldt f6, TAN_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
addt f9, f0, f0
|
|
subt f0, f8, f4
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 3rd octant; compute -cot(y')
|
|
//
|
|
Switch12:
|
|
and s1, 127, a1
|
|
subl a1, 35, a1
|
|
blt a1, neg_cot_2
|
|
|
|
s4addl a1, zero, a1
|
|
lda a2, __trig_cons
|
|
s8addl a1, a2, s0
|
|
ldt f1, TANCOT_A(s0)
|
|
ldt f6, TAN_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
subt f9, f1, f1
|
|
subt f8, f1, f4
|
|
br zero, neg_tab_eval
|
|
|
|
//
|
|
// 4th octant; compute tan(y')
|
|
//
|
|
Switch13:
|
|
ornot zero, s1, a4
|
|
and a4, 127, a4
|
|
subl a4, 35, a4
|
|
blt a4, pos_tan_2
|
|
|
|
s4addl a4, zero, a4
|
|
lda a5, __trig_cons
|
|
s8addl a4, a5, s0
|
|
ldt f10, TANCOT_A(s0)
|
|
addt f9, f10, f10
|
|
subt f8, f10, f4
|
|
br zero, neg_tab_eval1
|
|
|
|
//
|
|
// 5th octant; compute tan(y')
|
|
//
|
|
Switch14:
|
|
and s1, 127, t9
|
|
subl t9, 35, t9
|
|
blt t9, pos_tan_2
|
|
|
|
s4addl t9, zero, t9
|
|
lda t10, __trig_cons
|
|
s8addl t9, t10, s0
|
|
ldt f11, TANCOT_A(s0)
|
|
ldt f5, TAN_A(s0)
|
|
ldt f6, COT_A(s0)
|
|
subt f9, f11, f11
|
|
subt f11, f8, f4
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 6th octant; compute -cot(y')
|
|
//
|
|
Switch15:
|
|
ornot zero, s1, ra
|
|
and ra, 127, ra
|
|
subl ra, 35, ra
|
|
blt ra, neg_cot_2
|
|
|
|
s4addl ra, zero, ra
|
|
lda t12, __trig_cons
|
|
s8addl ra, t12, s0
|
|
ldt f12, TANCOT_A(s0)
|
|
ldt f6, TAN_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
addt f9, f12, f12
|
|
subt f12, f8, f4
|
|
br zero, pos_tab_eval
|
|
|
|
//
|
|
// 7th octant; compute -cot(y')
|
|
//
|
|
Switch16:
|
|
and s1, 127, t0
|
|
subl t0, 35, t0
|
|
blt t0, neg_cot_2
|
|
|
|
s4addl t0, zero, t0
|
|
lda t1, __trig_cons
|
|
s8addl t0, t1, s0
|
|
ldt f13, TANCOT_A(s0)
|
|
ldt f6, TAN_A(s0)
|
|
ldt f5, COT_A(s0)
|
|
subt f9, f13, f13
|
|
subt f8, f13, f4
|
|
br zero, neg_tab_eval
|
|
|
|
neg_cot_2:
|
|
mult f9, f9, f16
|
|
cvtts f9, f17
|
|
ldt f14, One
|
|
lda t3, __trig_cons
|
|
ldt f18, F_POLY5(t3)
|
|
divt f14, f9, f15
|
|
ldt f21, F_POLY3(t3)
|
|
mult f16, f16, f22
|
|
mult f16, f18, f18
|
|
ldt f19, F_POLY4(t3)
|
|
subt f9, f17, f23
|
|
ldt f24, F_POLY2(t3)
|
|
mult f16, f21, f21
|
|
ldt f25, F_POLY1(t3)
|
|
ldt f26, F_POLY0(t3)
|
|
mult f16, f25, f16
|
|
addt f18, f19, f18
|
|
subt f23, f8, f8
|
|
addt f21, f24, f21
|
|
addt f16, f26, f16
|
|
mult f18, f22, f18
|
|
mult f21, f22, f21
|
|
mult f18, f22, f18
|
|
addt f21, f18, f18
|
|
addt f16, f18, f16
|
|
mult f9, f16, f16
|
|
cvtts f15, f20
|
|
mult f20, f17, f17
|
|
mult f20, f8, f8
|
|
subt f15, f20, f20
|
|
subt f14, f17, f14
|
|
subt f14, f8, f8
|
|
mult f8, f15, f8
|
|
subt f8, f20, f8
|
|
subt f16, f8, f8
|
|
subt f8, f15, f7
|
|
fbge f3, adjust_sign
|
|
cpysn f7, f7, f7
|
|
cpys f7, f7, f0
|
|
br zero, done
|
|
|
|
//
|
|
// 8th octant; compute tan(y')
|
|
//
|
|
Switch17:
|
|
ornot zero, s1, s1
|
|
and s1, 127, s1
|
|
subl s1, 35, s1
|
|
blt s1, pos_tan_2
|
|
|
|
s4addl s1, zero, s1
|
|
lda t4, __trig_cons
|
|
s8addl s1, t4, s0
|
|
ldt f27, TANCOT_A(s0)
|
|
addt f9, f27, f27
|
|
subt f8, f27, f4
|
|
|
|
neg_tab_eval1:
|
|
ldt f5, TAN_A(s0)
|
|
ldt f6, COT_A(s0)
|
|
|
|
neg_tab_eval:
|
|
cpysn f3, f3, f3
|
|
|
|
pos_tab_eval:
|
|
mult f4, f4, f28
|
|
lda t6, __trig_cons
|
|
ldt f0, TAN_COT_A(s0)
|
|
ldt f29, G_POLY1(t6)
|
|
ldt f30, G_POLY0(t6)
|
|
mult f29, f28, f29
|
|
mult f4, f28, f28
|
|
addt f29, f30, f29
|
|
mult f28, f29, f28
|
|
subt f4, f28, f4
|
|
mult f0, f4, f0
|
|
subt f4, f6, f4
|
|
divt f0, f4, f0
|
|
subt f5, f0, f7
|
|
fbge f3, adjust_sign
|
|
cpysn f7, f7, f7
|
|
cpys f7, f7, f0
|
|
br zero, done
|
|
|
|
pos_tan_2:
|
|
mult f9, f9, f1
|
|
lda t7, __trig_cons
|
|
ldt f11, E_POLY1(t7)
|
|
ldt f12, E_POLY3(t7)
|
|
ldt f13, E_POLY4(t7)
|
|
mult f1, f1, f10
|
|
ldt f23, E_POLY0(t7)
|
|
mult f11, f1, f11
|
|
ldt f22, E_POLY2(t7)
|
|
mult f12, f1, f12
|
|
ldt f19, E_POLY5(t7)
|
|
ldt f24, E_POLY6(t7)
|
|
mult f19, f1, f19
|
|
mult f13, f10, f13
|
|
mult f24, f10, f24
|
|
addt f11, f23, f11
|
|
mult f22, f10, f22
|
|
mult f10, f10, f25
|
|
mult f9, f1, f1
|
|
addt f12, f13, f12
|
|
addt f19, f24, f19
|
|
addt f11, f22, f11
|
|
mult f12, f10, f10
|
|
mult f19, f25, f19
|
|
addt f11, f10, f10
|
|
addt f19, f10, f10
|
|
mult f1, f10, f1
|
|
addt f8, f1, f1
|
|
subt f9, f1, f7
|
|
fbge f3, adjust_sign
|
|
cpysn f7, f7, f7
|
|
|
|
adjust_sign:
|
|
cpys f7, f7, f0
|
|
br zero, done
|
|
|
|
//
|
|
// Determine if we have a NaN or an Inf
|
|
//
|
|
NaN_or_Inf:
|
|
stt f2, Temp2(sp)
|
|
ldl a1, Temp2 + HighPart(sp)
|
|
and a1, s2, a2
|
|
cmpeq a2, s2, s2
|
|
beq s2, NaN_or_Inf1
|
|
|
|
ldl a3, Temp2(sp)
|
|
ldah a4, 0x10(zero)
|
|
lda a4, -1(a4)
|
|
and a1, a4, a1
|
|
bis a1, a3, a1
|
|
cmpult zero, a1, a1
|
|
and s2, a1, s2
|
|
bne s2, NaN_or_Inf2
|
|
|
|
//
|
|
// report an exception
|
|
//
|
|
NaN_or_Inf1:
|
|
lda a5, tanName
|
|
stl a5, ExRec + ErName(sp)
|
|
ldah t10, 0x800(zero)
|
|
stt f2, ExRec + ErArg0(sp)
|
|
lda t10, 0x5f(t10)
|
|
stl t10, ExRec + ErErr(sp)
|
|
lda v0, ExRec(sp)
|
|
bsr ra, __dpml_exception
|
|
ldt f2, 0(v0)
|
|
|
|
//
|
|
// return the argument
|
|
//
|
|
NaN_or_Inf2:
|
|
cpys f2, f2, f0
|
|
|
|
//
|
|
// Restore registers and return with result in f0.
|
|
//
|
|
|
|
done:
|
|
ldq s0, SaveS0(sp)
|
|
ldq s1, SaveS1(sp)
|
|
ldq s2, SaveS2(sp)
|
|
ldq ra, SaveRa(sp)
|
|
ldt f2, SaveF2(sp)
|
|
ldt f3, SaveF3(sp)
|
|
ldt f4, SaveF4(sp)
|
|
ldt f5, SaveF5(sp)
|
|
ldt f6, SaveF6(sp)
|
|
ldt f7, SaveF7(sp)
|
|
ldt f8, SaveF8(sp)
|
|
ldt f9, SaveF9(sp)
|
|
lda sp, FrameLength(sp) // deallocate stack frame
|
|
ret zero, (ra) // return
|
|
|
|
.end tan
|
|
|
|
.rdata
|
|
.align 3
|
|
|
|
//
|
|
// Define floating point constants.
|
|
//
|
|
|
|
One: .double 1.0
|
|
|
|
//
|
|
// dispatch on octant
|
|
//
|
|
|
|
Switch1:
|
|
.long Switch10
|
|
.long Switch11
|
|
.long Switch12
|
|
.long Switch13
|
|
.long Switch14
|
|
.long Switch15
|
|
.long Switch16
|
|
.long Switch17
|
|
|
|
//
|
|
// dispatch on octant
|
|
//
|
|
|
|
Switch2:
|
|
.long Switch20
|
|
.long Switch21
|
|
.long Switch22
|
|
.long Switch23
|
|
.long Switch24
|
|
.long Switch25
|
|
.long Switch26
|
|
.long Switch27
|
|
|
|
tanName:
|
|
.ascii "tan\0"
|