1
/* -*- Mode: Asm -*- */
3
1
/* Copyright (c) 2002 Michael Stumpf <mistumpf@de.pepperl-fuchs.com>
2
Copyright (c) 2006,2008 Dmitry Xmelkov
7
5
Redistribution and use in source and binary forms, with or without
8
6
modification, are permitted provided that the following conditions are met:
10
8
* Redistributions of source code must retain the above copyright
11
9
notice, this list of conditions and the following disclaimer.
13
10
* Redistributions in binary form must reproduce the above copyright
14
11
notice, this list of conditions and the following disclaimer in
15
12
the documentation and/or other materials provided with the
18
14
* Neither the name of the copyright holders nor the names of
19
15
contributors may be used to endorse or promote products derived
20
16
from this software without specific prior written permission.
29
25
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
26
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
27
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
POSSIBILITY OF SUCH DAMAGE.
35
/* $Id: fp_cmp.S,v 1.4.2.1 2005/12/22 23:16:31 aesok Exp $ */
38
fp_cmp.S is part of FPlib V 0.3.0 ported to avr-as
39
for details see readme.fplib
41
*----------------------------------------------------------------------------------------
28
POSSIBILITY OF SUCH DAMAGE. */
30
/* $Id: fp_cmp.S,v 1.6.2.1 2008/03/22 04:13:12 dmix Exp $ */
48
35
/* GCC expects all these functions to return -1/0/1 as for __cmpsf2 -
49
36
compare with gcc/config/fp-bit.c (the only difference is with NaNs
50
37
where we should always return nonzero for EQ/NE, -1 for GT/GE,
51
38
1 for LT/LE). -MM 2000-11-18 */
53
TEXT_SEG(fplib, __fp_cmp)
57
GLOBAL(__eqsf2) ; equal : true, if Z set (and T clear)
62
brts .Lfp_cmp_gt ; return 1 (not equal / false) if we got a NaN
69
GLOBAL(__gtsf2) ; greater than : true, if Z clear and C clear
79
GLOBAL(__cmpsf2) ; returns 1 for A > B ; 0 for A == B ; -1 for A < B ; NaN ?
96
/*------------------------------------------------------------------------
98
* { C = 1 Z = 0 T = 0 A < B
99
* compares x to y and sets flags : { C = 0 Z = 1 T = 0 A == B
100
* { C = 0 Z = 0 T = 0 A > B,
40
#define ret_lo r24 /* return value (signed byte) */
41
.ifnc ret_lo, rA2 ; This is used in __fp_cmp() function.
45
/* The base compare function.
53
else // isnan(A) || isnan(B)
110
BLD rT0,0 ; rT0.7 = sign(A) EOR sign(B), rT0.0 = sign(A)
112
RCALL _U(__fp_split2) ; does not return on NaN (T set then)
115
RJMP 1f ; different signs
117
; same signs : compare
121
CPC rA3,rB3 ; A - B ; set Z if equal, sets C if A < B (unsigned)
123
BRCC 1f ; A > B (unsigned)
124
COM rT0 ; A < B (unsigned)
125
1: ; different signs (-0 < +0!)
126
; sign(A) == 0 (positive) -> A > B, C = 0 , Z = 0
127
; sign(A) == 1 (negative) -> A < B, C = 1 , Z = 0
128
ROR rT0 ; C = sign(A)
58
sbc r0, r0 ; r0 = (A < 0) ? -1 : 0
60
sbc rBE, rBE ; rBE = (B < 0) ? -1 : 0
62
ldi ZL, 0x80 ; NaN: 0x{f/7}f800001..0x{f/7}fffffff
68
brlo 9f ; branch, if C == 1
74
brlo 9f ; branch, if C == 1
79
sbc rA3, rB3 ; C is set, if A < B
81
; absolute values are equal, check signs
83
breq 9f ; if branch, rA2 = 0, C = 0
88
brne 2f ; evaluate sign(B)
90
; view argument signes
91
1: eor r0, rBE ; C is not changed
92
brne 2f ; signs are different
93
sbci rBE, 1 ; rBE[0] = (A < B && A > 0) ? 0 : 1
94
2: lsr rBE ; C = above result OR sign(B)
95
; build return value, C is set, if A > B
98
adc rA2, r1 ; C = 0 at any case