1 |
/* -*- Mode: Asm -*- */ |
2 |
|
3 |
/* Copyright (c) 2002 Michael Stumpf <Michael.Stumpf@t-online.de> |
4 |
|
5 |
This file is free software; you can redistribute it and/or modify it under |
6 |
the terms of the GNU General Public License as published by the Free |
7 |
Software Foundation; either version 2, or (at your option) any later |
8 |
version. |
9 |
|
10 |
In addition to the permissions in the GNU General Public License, the |
11 |
author gives you unlimited permission to link the compiled version of this |
12 |
file into combinations with other programs, and to distribute those |
13 |
combinations without any restriction coming from the use of this file. |
14 |
(The General Public License restrictions do apply in other respects; for |
15 |
example, they cover modification of the file, and distribution when not |
16 |
linked into a combine executable.) |
17 |
|
18 |
This file is distributed in the hope that it will be useful, but WITHOUT |
19 |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
20 |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
21 |
more details. */ |
22 |
|
23 |
/* |
24 |
tanh.S is part of FPlib V 0.3.0 ported to avr-as |
25 |
for details see readme.fplib |
26 |
|
27 |
*---------------------------------------------------------------------------------------- |
28 |
* |
29 |
* A = tanh(A) |
30 |
* |
31 |
* tanh( x ) = sinh(x)/cosh(x) |
32 |
* (exp(x) - exp(-x)) 1 - exp(-2x) (exp(2x) - 1 |
33 |
* = ------------------- = ------------- = ------------- |
34 |
* (exp(x) + exp(-x)) = 1 + exp(-2x) (exp(2x) + 1 |
35 |
* |
36 |
* if exp(x) +- exp(-x) == exp(x) => exp(2x) +- 1 == exp(2x) => exp(2x) >= 2^24 -> x = ln(2^24)/2 |
37 |
*/ |
38 |
|
39 |
#if !defined(DOXYGEN) |
40 |
|
41 |
#include "gasava.inc" |
42 |
#include "fplib.inc" |
43 |
|
44 |
TEXT_SEG(fplib, tanh) |
45 |
FUNCTION(tanh) |
46 |
|
47 |
GLOBAL(tanh) |
48 |
/* check for x > 8.3177661895751953 [41051592] |
49 |
*/ |
50 |
BST rA3,7 |
51 |
ANDI rA3,0x7F |
52 |
LDI rB3,0x41 |
53 |
LDI rB2,0x05 |
54 |
LDI rB1,0x15 |
55 |
CPI rA0,0x92+1 |
56 |
CPC rA1,rB1 |
57 |
CPC rA2,rB2 |
58 |
CPC rA3,rB3 ; compare with 8.3177661895751953 = | ln(2^24)/2 | |
59 |
BRCS _tanh_00 |
60 |
LDI rA3,0x3F |
61 |
LDI rA2,0x80 |
62 |
LDI rA1,0x00 |
63 |
LDI rA0,0x00 ; load 1 |
64 |
BLD rA3,7 ; if x positivive _tanh(x) = 1 |
65 |
RET |
66 |
|
67 |
_tanh_00: |
68 |
BLD rA3,7 |
69 |
|
70 |
PUSH rA0 /* LDI rB3,1 */ |
71 |
PUSH rA1 /* RCALL _ldexp ; x -> 2x */ |
72 |
PUSH rA2 /* */ |
73 |
PUSH rA3 /* RCALL _exp */ |
74 |
RCALL _U(cosh) /* PUSH rA0 */ |
75 |
POP rB3 /* PUSH rA1 */ |
76 |
POP rB2 /* PUSH rA2 */ |
77 |
POP rB1 /* PUSH rA3 */ |
78 |
POP rB0 /* CLR rB0 */ |
79 |
PUSH rA3 /* CLR rB1 */ |
80 |
PUSH rA2 /* LDI rB2,0x80 */ |
81 |
PUSH rA1 /* LDI rB3,0x3F ; B = 1.0 */ |
82 |
PUSH rA0 /* RCALL ___addsf3 */ |
83 |
MOV rA3,rB3 /* POP rB3 */ |
84 |
MOV rA2,rB2 /* POP rB2 */ |
85 |
MOV rA1,rB1 /* POP rB1 */ |
86 |
MOV rA0,rB0 /* POP rB0 ; B = exp(2x) */ |
87 |
RCALL _U(sinh) /* PUSH rA0 */ |
88 |
POP rB0 /* PUSH rA1 */ |
89 |
POP rB1 /* PUSH rA2 */ |
90 |
POP rB2 /* PUSH rA3 */ |
91 |
POP rB3 /* CLR rA0 */ |
92 |
RJMP _U(__divsf3) /* CLR rA1 */ |
93 |
/* LDI rA2,0x80 */ |
94 |
/* LDI rA3,0xBF ; A = -1.0 */ |
95 |
/* RCALL ___addsf3 */ |
96 |
/* POP rB3 */ |
97 |
/* POP rB2 */ |
98 |
/* POP rB1 */ |
99 |
/* POP rB0 ; B = exp(2x)+1 */ |
100 |
/* RJMP ___divsf3 */ |
101 |
|
102 |
ENDFUNC |
103 |
|
104 |
#endif /* not DOXYGEN */ |