1/* Copyright (c) 2002  Michael Stumpf  <mistumpf@de.pepperl-fuchs.com>
2   Copyright (c) 2006  Dmitry Xmelkov
3   All rights reserved.
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7
8   * Redistributions of source code must retain the above copyright
9     notice, this list of conditions and the following disclaimer.
10   * Redistributions in binary form must reproduce the above copyright
11     notice, this list of conditions and the following disclaimer in
12     the documentation and/or other materials provided with the
13     distribution.
14   * Neither the name of the copyright holders nor the names of
15     contributors may be used to endorse or promote products derived
16     from this software without specific prior written permission.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28   POSSIBILITY OF SUCH DAMAGE. */
29
30/* $Id: fp_split3.S 2191 2010-11-05 13:45:57Z arcanum $ */
31
32#if !defined(__AVR_TINY__)
33
34#include "fp32def.h"
35#include "asmdef.h"
36
37/* <non_standart> __fp_split3 (float A, float B);
38     It splits two float numbers.
39
40   Return:
41     rA3, rA2.rA1.rA0	- exponent and mantissa of A (see __fp_splitA)
42     rB3, rB2.rB1.rB0	- exponent and mantissa of B (see __fp_splitA)
43     Flags:
44        C = 0	- both numbers are finite
45	C = 1   - A and/or B is Inf/NaN
46	T = sign(A) ^ sign(B)
47
48   Notes:
49     * Flag is different sense vs __fp_splitA()
50     * All other registers are not changed.
51 */
52ENTRY   __fp_split3
53  ; rA3[7] := sign(A) ^ sign(B)
54	sbrc	rB3, 7
55	subi	rA3, 0x80
56  ; split B
57	lsl	rB2
58	rol	rB3		; exponent
59	breq	4f
60	cpi	rB3, 0xff	; C = 1, if rB3 != 0xff
61	breq	5f
621:	ror	rB2		; restore rB2 and (possible) hidden bit
63
64/* <non_standart> __fp_splitA (float A);
65     It splits an A float number.
66
67   Return:
68     rA3 - exponent:
69        0	for +0.0/-0.0
70	1..254	for finite number
71	255	for Inf/NaN
72     rA2.rA1.rA0 - mantissa:
73        0			for +0.0/-0.0
74	0x000001..0x7fffff	for subnormal (and rA3 = 1)
75	0x800000..0xffffff	for normal (rA3 = 1..254)
76	0x000000		for Inf
77	0x000001..0x7fffff	for NaN
78     Flags:
79        C = 0		for finite number
80	C = 1, Z = 1	for Inf
81	C = 1, Z = 0	for NaN
82        T = sign
83
84   Notes:
85     * Other registers are not scratched.
86 */
87ENTRY   __fp_splitA
88	lsl	rA2
892:	bst	rA3, 7
90	rol	rA3
91	breq	6f
92	cpi	rA3, 0xff
93	breq	7f
943:	ror	rA2
95	ret
96
97  ; B is zero or subnormal
984:	cp	r1, rB0
99	cpc	r1, rB1
100	cpc	r1, rB2		; C = 1, if B is not a zero
101	rol	rB3		; C = 0
102	rjmp	1b
103  ; B is not a finite
1045:	lsr	rB2
105	rcall	__fp_splitA
106	rjmp	8f
107
108  ; A is zero or subnormal
1096:	cp	r1, rA0
110	cpc	r1, rA1
111	cpc	r1, rA2
112	rol	rA3
113	rjmp	3b
114  ; A is not a finite
1157:	lsr	rA2		; C = 0
116	cpc	rA1, r1
117	cpc	rA0, r1
1188:	sec
119	ret
120ENDFUNC
121
122#endif /* !defined(__AVR_TINY__) */
123