~ubuntu-branches/ubuntu/raring/avr-libc/raring-proposed

« back to all changes in this revision

Viewing changes to libm/fplib/fp_cmp.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-04-04 17:05:32 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20080404170532-t84huz4qk2928pt3
Tags: upstream-1.6.2
ImportĀ upstreamĀ versionĀ 1.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  -*- Mode: Asm -*-  */
2
 
 
3
1
/* Copyright (c) 2002  Michael Stumpf  <mistumpf@de.pepperl-fuchs.com>
 
2
   Copyright (c) 2006,2008  Dmitry Xmelkov
4
3
   All rights reserved.
5
4
 
6
 
 
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:
9
7
 
10
8
   * Redistributions of source code must retain the above copyright
11
9
     notice, this list of conditions and the following disclaimer.
12
 
   
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
16
13
     distribution.
17
 
     
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. 
33
 
*/
34
 
 
35
 
/* $Id: fp_cmp.S,v 1.4.2.1 2005/12/22 23:16:31 aesok Exp $ */
36
 
 
37
 
/*
38
 
    fp_cmp.S is part of     FPlib V 0.3.0       ported to avr-as
39
 
    for details see readme.fplib
40
 
 
41
 
 *----------------------------------------------------------------------------------------
42
 
 */
43
 
 
44
 
#include "gasava.inc"
45
 
#include "macros.inc"
46
 
#include "fplib.inc"
 
28
   POSSIBILITY OF SUCH DAMAGE. */
 
29
 
 
30
/* $Id: fp_cmp.S,v 1.6.2.1 2008/03/22 04:13:12 dmix Exp $ */
 
31
 
 
32
#include "fp32def.h"
 
33
#include "asmdef.h"
47
34
 
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 */
52
39
 
53
 
          TEXT_SEG(fplib, __fp_cmp)
54
 
 
55
 
          FUNCTION(__eqsf2)
56
 
 
57
 
GLOBAL(__eqsf2)                  ; equal : true, if Z set (and T clear)
58
 
GLOBAL(__nesf2)
59
 
GLOBAL(__ltsf2)
60
 
GLOBAL(__lesf2)
61
 
    rcall   .fp_cmp
62
 
    brts    .Lfp_cmp_gt  ; return 1 (not equal / false) if we got a NaN
63
 
    rjmp    .Lfp_cmp_ret
64
 
 
65
 
          ENDFUNC
66
 
 
67
 
          FUNCTION(__gtsf2)
68
 
 
69
 
GLOBAL(__gtsf2)                  ; greater than : true, if Z clear and C clear
70
 
GLOBAL(__gesf2)
71
 
    rcall   .fp_cmp
72
 
    brts    .Lfp_cmp_lt
73
 
    rjmp    .Lfp_cmp_ret
74
 
 
75
 
          ENDFUNC
76
 
 
77
 
          FUNCTION(__cmpsf2)
78
 
 
79
 
GLOBAL(__cmpsf2)  ; returns 1 for A > B ; 0 for A == B ; -1 for A < B ; NaN ?
80
 
    rcall   .fp_cmp
81
 
.Lfp_cmp_ret:
82
 
    breq    .Lfp_cmp_eq
83
 
    brcc    .Lfp_cmp_gt
84
 
.Lfp_cmp_lt:
85
 
    ldi     rByte,0xFF
86
 
    ret
87
 
.Lfp_cmp_eq:
88
 
    ldi     rByte,0x00
89
 
    ret
90
 
.Lfp_cmp_gt:
91
 
    ldi     rByte,0x01
92
 
    ret
93
 
 
94
 
          ENDFUNC
95
 
 
96
 
/*------------------------------------------------------------------------
97
 
 * compare  A == B
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,
101
 
 *                                   {             T = 1 NAN
 
40
#define ret_lo  r24     /* return value (signed byte)   */
 
41
.ifnc   ret_lo, rA2     ; This is used in __fp_cmp() function.
 
42
  .err
 
43
.endif
 
44
 
 
45
/* The base compare function.
 
46
   Return:
 
47
     if (A < B)
 
48
        rA2 = -1, C = 0
 
49
     elif (A == B)
 
50
        rA2 = 0, C = 0
 
51
     elif (A > B)
 
52
        rA2 = 1, C = 0
 
53
     else // isnan(A) || isnan(B)
 
54
        C = 1
102
55
 */
103
 
 
104
 
          .func .fp_cmp
105
 
 
106
 
.fp_cmp:
107
 
    BST    rA3,7
108
 
    MOV    rT0,rA3
109
 
    EOR    rT0,rB3
110
 
    BLD    rT0,0                ; rT0.7 = sign(A) EOR sign(B), rT0.0 = sign(A)
111
 
    SET
112
 
    RCALL  _U(__fp_split2)      ; does not return on NaN (T set then)
113
 
    CLT
114
 
    SBRC   rT0,7
115
 
    RJMP   1f                   ; different signs
116
 
 
117
 
    ; same signs : compare
118
 
    CP     rA0,rB0
119
 
    CPC    rA1,rB1
120
 
    CPC    rA2,rB2
121
 
    CPC    rA3,rB3              ; A - B ; set Z if equal, sets C if A < B (unsigned)
122
 
    BREQ   2f
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)
129
 
    CLZ                 ; Z = 0
130
 
2:
131
 
    ret
132
 
 
133
 
          ENDFUNC
134
 
 
 
56
ENTRY   __fp_cmp
 
57
        lsl     rA3
 
58
        sbc     r0, r0          ; r0 = (A < 0) ? -1 : 0
 
59
        lsl     rB3
 
60
        sbc     rBE, rBE        ; rBE = (B < 0) ? -1 : 0
 
61
  ; isnan(A) ?
 
62
        ldi     ZL, 0x80        ; NaN: 0x{f/7}f800001..0x{f/7}fffffff
 
63
        ldi     ZH, 0xfe
 
64
        cp      r1, rA0
 
65
        cpc     r1, rA1
 
66
        cpc     ZL, rA2
 
67
        cpc     ZH, rA3
 
68
        brlo    9f              ; branch, if C == 1
 
69
  ; isnan(B) ?
 
70
        cp      r1, rB0
 
71
        cpc     r1, rB1
 
72
        cpc     ZL, rB2
 
73
        cpc     ZH, rB3
 
74
        brlo    9f              ; branch, if C == 1
 
75
  ; compare
 
76
        sub     rA0, rB0
 
77
        sbc     rA1, rB1
 
78
        sbc     rA2, rB2
 
79
        sbc     rA3, rB3        ; C is set, if A < B
 
80
        brne    1f
 
81
  ; absolute values are equal, check signs
 
82
        eor     r0, rBE
 
83
        breq    9f              ; if branch, rA2 = 0, C = 0
 
84
  ; force -0.0 == +0.0
 
85
        or      rB0, rB1
 
86
        or      rB0, rB2
 
87
        or      rB0, rB3
 
88
        brne    2f              ; evaluate sign(B)
 
89
        ret
 
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
 
96
        ldi     rA2, -1
 
97
        adc     rA2, r1
 
98
        adc     rA2, r1         ; C = 0 at any case
 
99
9:      ret
 
100
ENDFUNC