1 |
/*---------------------------------------------------------------------------------------------- |
2 |
|
3 |
Port of Michael Stumpfs FPlib.s to the binutils version of avr-gcc. |
4 |
Issues specific to the state of porting are found at the end of this file. |
5 |
*/ |
6 |
/*---------------------------------------------------------------------------------------------- |
7 |
|
8 |
FPlib.s |
9 |
|
10 |
V 0.3.0 |
11 |
|
12 |
Copyright (c) Michael Stumpf <Michael.Stumpf@t-online.de> |
13 |
|
14 |
This file is free software; you can redistribute it and/or modify it |
15 |
under the terms of the GNU General Public License as published by the |
16 |
Free Software Foundation; either version 2, or (at your option) any |
17 |
later version. |
18 |
|
19 |
In addition to the permissions in the GNU General Public License, the |
20 |
author gives you unlimited permission to link the |
21 |
compiled version of this file into combinations with other programs, |
22 |
and to distribute those combinations without any restriction coming |
23 |
from the use of this file. (The General Public License restrictions |
24 |
do apply in other respects; for example, they cover modification of |
25 |
the file, and distribution when not linked into a combine |
26 |
executable.) |
27 |
|
28 |
This file is distributed in the hope that it will be useful, but |
29 |
WITHOUT ANY WARRANTY; without even the implied warranty of |
30 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
31 |
General Public License for more details. |
32 |
|
33 |
Floating point library for Atmel AVR uC |
34 |
full arithmetic and maths functionality |
35 |
do not mix up this file with the FPalib source - doesn't work! |
36 |
|
37 |
Author : Michael Stumpf |
38 |
Michael.Stumpf@t-online.de |
39 |
|
40 |
Versions : The floating point library comes in three different versions (sometimes...) |
41 |
FPlibOs.s90 - optimized for size, rather slow |
42 |
FPlibO5.s90 - optimized for speed, rather large |
43 |
FPlib .s90 - something in between .._O2 and .._Os |
44 |
optimized for size if it doesn't cost too much time |
45 |
optimized for speed in loops etc |
46 |
implemented is floating point arithmetic for float and double the same size of 4 byte |
47 |
right now simple Nans are realized - |
48 |
anything with exp == 0xFF is a NaN and remains NaN |
49 |
(and the only point that I know turning an exp==0xFF off is |
50 |
the division of x/ħINF -> 0.0) |
51 |
|
52 |
Implementation limits: |
53 |
|
54 |
* only one type of NaN supported : 0xFFC0XXXX |
55 |
* only one type of zero supported : 0x00000000 |
56 |
(no -0) |
57 |
* no subnormals supported |
58 |
mathematical functions : |
59 |
* no call to matherr or _matherr |
60 |
* overflow/underflow may occur even when result is withing valid range e.g. sinh etc. |
61 |
* |
62 |
================================================================================ |
63 |
Version Date Changes |
64 |
0.1 * first release different version numbers |
65 |
0.1.1 (immidiately after first release) |
66 |
* bug in ___addsf3x adding 0.0 + 0.0 the result was FLT_MIN instead of 0.0 |
67 |
* bug in _fmod sign was incorrect |
68 |
0.2.0 * version numbers set to 0.2.0 |
69 |
* bug fix in _sin sin(A) = cos( A + 3PI/2 ) |
70 |
least significant byte of constant 3PI/2 was nibble swapped |
71 |
* change in coefficient tables no need for extended precision to store |
72 |
saves time and space |
73 |
* fabs added |
74 |
* _fabs does the same inline |
75 |
* modf added |
76 |
* bug in ___fixsfsi one of my stupid errors |
77 |
0.2.1 * changed segment names from |
78 |
seg removable flash.code.FPaddx |
79 |
to |
80 |
seg removable flash.code.FPlib.FPaddx |
81 |
* tables now placed in (e.g.) |
82 |
seg removable flash.table.FPlin.FPcos |
83 |
* _C_FPsquare and _C_FPinv (which exist and are used anyway) |
84 |
new named to _square and _inverse and made public (two non-standard functions) |
85 |
0.2.2 * include "AVR.inc" for macros and target |
86 |
0.2.3 18.8.1999 * bug in frexp : 1- parameter pointer to integer handled correctly |
87 |
2- exponent calculated correctly |
88 |
* include "CtoASM.inc" for parameter passing |
89 |
* ldexp added |
90 |
* exp added |
91 |
* sinh added |
92 |
* cosh added |
93 |
* tanh added |
94 |
* fp_merge : clear __zero_reg__ on all return paths! |
95 |
0.2.4 25.8.1999 * ___negsf2 declared public |
96 |
* ___cmpsf2 ; returns 1 for A>B ; 0 for A==B ; -1 for A<B |
97 |
* return values for ___cmpsf2, ___eqsf2 etc. passed in rByte |
98 |
0.2.5 07.09.1999 * added some more comments :) |
99 |
(not released) * removed obsolete labels _C_xxx |
100 |
internal functions now are named fp_xxxx |
101 |
* ___floatsisf changed |
102 |
* fp_powerloop : save Z over add |
103 |
0.2.6 17.09.1999 * function fp_zero now public |
104 |
(not released) * function _C_FP_PFTtoBX renamed to fp_flashconst |
105 |
and made public (-Os version will use that later on) |
106 |
* macro LPMRdZpp instead of |
107 |
code LPM MOV Rd,R0 ADIW ZL,1 (use of Atmega161 instruction) |
108 |
* #undef all define register nicknames at end of file |
109 |
0.2.7 01.10.1999 * fp_powerseries : load constants now with sign : exp[rB3]:sign[rB2.7]:mantissae[rB2.6::rB0.0] |
110 |
(not released) * seg removable flash.table.FPlib.FPasin renamed seg removable flash.table.FPlib.asin |
111 |
seg removable flash.table.FPlib.FPacos renamed seg removable flash.code.FPlib.acos |
112 |
* _exp and _tanh now public ;-) |
113 |
* _modf : don't store integer part twice with ST Y+,..!! |
114 |
14.10.1999 * new : _strtod (seperate file strtod.s) |
115 |
* new : _dtostre (seperate file dtostre.s) |
116 |
... 18.10.1999 * _exp debugged |
117 |
... 19.10.1999 * _log added |
118 |
* _log10, _pow added |
119 |
* bug : call fp_split *allways* before pushing anything to stack |
120 |
-> modf, fp_powerseries |
121 |
... 25.10.1999 * rounding / normalizing error in fp_powerseries |
122 |
leads to low precision sometimes |
123 |
0.2.8 27.10.1999 * bug : rare rounding error if the extended results |
124 |
(not released) mantissae is like 80NNNN , NNNN != 0 |
125 |
only sub/add & mul, problem solved |
126 |
* fp comparison functions return 1 rather than 0xFF if true |
127 |
* size optimization : fp_split3 moves sign(A)^sign(B) to T |
128 |
* add: changed shift right break criterium: |
129 |
now get diff of exp(B)-exp(A) (negative!) and count up |
130 |
break if diff is < -25 |
131 |
* bug in ___gtsf2: BREQ isfalse rather than BRNE isfalse |
132 |
|
133 |
* changes in fp_cmp |
134 |
* changes in sqrt |
135 |
0.2.9 * changes in sin: if arg < 397FFFFF -> sin(A) = A |
136 |
(not released) tan: if arg < 39000000 -> tan(A) = A |
137 |
(( cos: if arg < 39000000 -> cos(A) = 1.0 )) |
138 |
* fp_powerseries : sign handling optimized |
139 |
21.11.99 * bug in frexp frexp(0,&int) -> 0 / 0 (was 0x00800000!) |
140 |
30.11.99 * bug in ldexp |
141 |
0.3.0 30.11.99 Release version |
142 |
* lots of testing/benchmarking - see file FPlib.bench |
143 |
|
144 |
AVRgcc interface: |
145 |
All functions use the AVR-gcc function call interface : |
146 |
|
147 |
double func( double A [, double B] ) |
148 |
|
149 |
A := R25:R24:R23:R22 with R25 holding sign and exponent, R22 LSB of mantissa |
150 |
B := R21:R20:R19:R18 with R21 holding sign and exponent, R18 LSB of mantissa |
151 |
return value := A |
152 |
|
153 |
register usage |
154 |
R0 scratch register |
155 |
R1 allways zero (cleared after use) |
156 |
R2-R17 left unchanged (pushed) |
157 |
R18-R27 used |
158 |
R29:R28 Y unused (pushed) |
159 |
R31:R30 Z used |
160 |
|
161 |
----------------------------------------------------------------------------------------------*/ |
162 |
|