1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Linux/PA-RISC Project (http://www.parisc-linux.org/) |
4 | * |
5 | * Floating-point emulation code |
6 | * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> |
7 | */ |
8 | /* |
9 | * BEGIN_DESC |
10 | * |
11 | * File: |
12 | * @(#) pa/spmath/sfcmp.c $Revision: 1.1 $ |
13 | * |
14 | * Purpose: |
15 | * sgl_cmp: compare two values |
16 | * |
17 | * External Interfaces: |
18 | * sgl_fcmp(leftptr, rightptr, cond, status) |
19 | * |
20 | * Internal Interfaces: |
21 | * |
22 | * Theory: |
23 | * <<please update with a overview of the operation of this file>> |
24 | * |
25 | * END_DESC |
26 | */ |
27 | |
28 | |
29 | #include "float.h" |
30 | #include "sgl_float.h" |
31 | |
32 | /* |
33 | * sgl_cmp: compare two values |
34 | */ |
35 | int |
36 | sgl_fcmp (sgl_floating_point * leftptr, sgl_floating_point * rightptr, |
37 | unsigned int cond, unsigned int *status) |
38 | |
39 | /* The predicate to be tested */ |
40 | |
41 | { |
42 | register unsigned int left, right; |
43 | register int xorresult; |
44 | |
45 | /* Create local copies of the numbers */ |
46 | left = *leftptr; |
47 | right = *rightptr; |
48 | |
49 | /* |
50 | * Test for NaN |
51 | */ |
52 | if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT) |
53 | || (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) ) |
54 | { |
55 | /* Check if a NaN is involved. Signal an invalid exception when |
56 | * comparing a signaling NaN or when comparing quiet NaNs and the |
57 | * low bit of the condition is set */ |
58 | if( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT) |
59 | && Sgl_isnotzero_mantissa(left) |
60 | && (Exception(cond) || Sgl_isone_signaling(left))) |
61 | || |
62 | ( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) |
63 | && Sgl_isnotzero_mantissa(right) |
64 | && (Exception(cond) || Sgl_isone_signaling(right)) ) ) |
65 | { |
66 | if( Is_invalidtrap_enabled() ) { |
67 | Set_status_cbit(Unordered(cond)); |
68 | return(INVALIDEXCEPTION); |
69 | } |
70 | else Set_invalidflag(); |
71 | Set_status_cbit(Unordered(cond)); |
72 | return(NOEXCEPTION); |
73 | } |
74 | /* All the exceptional conditions are handled, now special case |
75 | NaN compares */ |
76 | else if( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT) |
77 | && Sgl_isnotzero_mantissa(left)) |
78 | || |
79 | ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT) |
80 | && Sgl_isnotzero_mantissa(right)) ) |
81 | { |
82 | /* NaNs always compare unordered. */ |
83 | Set_status_cbit(Unordered(cond)); |
84 | return(NOEXCEPTION); |
85 | } |
86 | /* infinities will drop down to the normal compare mechanisms */ |
87 | } |
88 | /* First compare for unequal signs => less or greater or |
89 | * special equal case */ |
90 | Sgl_xortointp1(left,right,xorresult); |
91 | if( xorresult < 0 ) |
92 | { |
93 | /* left negative => less, left positive => greater. |
94 | * equal is possible if both operands are zeros. */ |
95 | if( Sgl_iszero_exponentmantissa(left) |
96 | && Sgl_iszero_exponentmantissa(right) ) |
97 | { |
98 | Set_status_cbit(Equal(cond)); |
99 | } |
100 | else if( Sgl_isone_sign(left) ) |
101 | { |
102 | Set_status_cbit(Lessthan(cond)); |
103 | } |
104 | else |
105 | { |
106 | Set_status_cbit(Greaterthan(cond)); |
107 | } |
108 | } |
109 | /* Signs are the same. Treat negative numbers separately |
110 | * from the positives because of the reversed sense. */ |
111 | else if( Sgl_all(left) == Sgl_all(right) ) |
112 | { |
113 | Set_status_cbit(Equal(cond)); |
114 | } |
115 | else if( Sgl_iszero_sign(left) ) |
116 | { |
117 | /* Positive compare */ |
118 | if( Sgl_all(left) < Sgl_all(right) ) |
119 | { |
120 | Set_status_cbit(Lessthan(cond)); |
121 | } |
122 | else |
123 | { |
124 | Set_status_cbit(Greaterthan(cond)); |
125 | } |
126 | } |
127 | else |
128 | { |
129 | /* Negative compare. Signed or unsigned compares |
130 | * both work the same. That distinction is only |
131 | * important when the sign bits differ. */ |
132 | if( Sgl_all(left) > Sgl_all(right) ) |
133 | { |
134 | Set_status_cbit(Lessthan(cond)); |
135 | } |
136 | else |
137 | { |
138 | Set_status_cbit(Greaterthan(cond)); |
139 | } |
140 | } |
141 | return(NOEXCEPTION); |
142 | } |
143 | |