1 
2 /*============================================================================
3 
4 This C source file is part of TestFloat, Release 3e, a package of programs for
5 testing the correctness of floating-point arithmetic complying with the IEEE
6 Standard for Floating-Point, by John R. Hauser.
7 
8 Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
9 University of California.  All rights reserved.
10 
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions are met:
13 
14  1. Redistributions of source code must retain the above copyright notice,
15     this list of conditions, and the following disclaimer.
16 
17  2. Redistributions in binary form must reproduce the above copyright notice,
18     this list of conditions, and the following disclaimer in the documentation
19     and/or other materials provided with the distribution.
20 
21  3. Neither the name of the University nor the names of its contributors may
22     be used to endorse or promote products derived from this software without
23     specific prior written permission.
24 
25 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
26 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
28 DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 
36 =============================================================================*/
37 
38 #include <stdbool.h>
39 #include <stdint.h>
40 #include <stdio.h>
41 #include "platform.h"
42 #include "uint128.h"
43 #include "softfloat.h"
44 #include "writeHex.h"
45 
writeHex_bool(bool a,char sepChar)46 void writeHex_bool( bool a, char sepChar )
47 {
48 
49     fputc( a ? '1' : '0', stdout );
50     if ( sepChar ) fputc( sepChar, stdout );
51 
52 }
53 
writeHex_ui8(uint_fast8_t a,char sepChar)54 void writeHex_ui8( uint_fast8_t a, char sepChar )
55 {
56     int digit;
57 
58     digit = a>>4 & 0xF;
59     if ( 9 < digit ) digit += 'A' - ('0' + 10);
60     fputc( '0' + digit, stdout );
61     digit = a & 0xF;
62     if ( 9 < digit ) digit += 'A' - ('0' + 10);
63     fputc( '0' + digit, stdout );
64     if ( sepChar ) fputc( sepChar, stdout );
65 
66 }
67 
writeHex_ui12(uint_fast16_t a,char sepChar)68 static void writeHex_ui12( uint_fast16_t a, char sepChar )
69 {
70     int digit;
71 
72     digit = a>>8 & 0xF;
73     if ( 9 < digit ) digit += 'A' - ('0' + 10);
74     fputc( '0' + digit, stdout );
75     digit = a>>4 & 0xF;
76     if ( 9 < digit ) digit += 'A' - ('0' + 10);
77     fputc( '0' + digit, stdout );
78     digit = a & 0xF;
79     if ( 9 < digit ) digit += 'A' - ('0' + 10);
80     fputc( '0' + digit, stdout );
81     if ( sepChar ) fputc( sepChar, stdout );
82 
83 }
84 
writeHex_ui16(uint_fast16_t a,char sepChar)85 void writeHex_ui16( uint_fast16_t a, char sepChar )
86 {
87     int digit;
88 
89     digit = a>>12 & 0xF;
90     if ( 9 < digit ) digit += 'A' - ('0' + 10);
91     fputc( '0' + digit, stdout );
92     digit = a>>8 & 0xF;
93     if ( 9 < digit ) digit += 'A' - ('0' + 10);
94     fputc( '0' + digit, stdout );
95     digit = a>>4 & 0xF;
96     if ( 9 < digit ) digit += 'A' - ('0' + 10);
97     fputc( '0' + digit, stdout );
98     digit = a & 0xF;
99     if ( 9 < digit ) digit += 'A' - ('0' + 10);
100     fputc( '0' + digit, stdout );
101     if ( sepChar ) fputc( sepChar, stdout );
102 
103 }
104 
writeHex_ui32(uint_fast32_t a,char sepChar)105 void writeHex_ui32( uint_fast32_t a, char sepChar )
106 {
107 
108     writeHex_ui16( a>>16, 0 );
109     writeHex_ui16( a, sepChar );
110 
111 }
112 
writeHex_ui64(uint_fast64_t a,char sepChar)113 void writeHex_ui64( uint_fast64_t a, char sepChar )
114 {
115 
116     writeHex_ui32( a>>32, 0 );
117     writeHex_ui32( a, sepChar );
118 
119 }
120 
121 #ifdef FLOAT16
122 
writeHex_f16(float16_t a,char sepChar)123 void writeHex_f16( float16_t a, char sepChar )
124 {
125     union { uint16_t ui; float16_t f; } uA;
126     uint_fast16_t uiA;
127 
128     uA.f = a;
129     uiA = uA.ui;
130     fputc( uiA & 0x8000 ? '-' : '+', stdout );
131     writeHex_ui8( uiA>>10 & 0x1F, 0 );
132     fputc( '.', stdout );
133     fputc( '0' + (uiA>>8 & 3), stdout );
134     writeHex_ui8( uiA, sepChar );
135 
136 }
137 
138 #endif
139 
writeHex_f32(float32_t a,char sepChar)140 void writeHex_f32( float32_t a, char sepChar )
141 {
142     union { uint32_t ui; float32_t f; } uA;
143     uint_fast32_t uiA;
144 
145     uA.f = a;
146     uiA = uA.ui;
147     fputc( uiA & 0x80000000 ? '-' : '+', stdout );
148     writeHex_ui8( uiA>>23, 0 );
149     fputc( '.', stdout );
150     writeHex_ui8( uiA>>16 & 0x7F, 0 );
151     writeHex_ui16( uiA, sepChar );
152 
153 }
154 
155 #ifdef FLOAT64
156 
writeHex_f64(float64_t a,char sepChar)157 void writeHex_f64( float64_t a, char sepChar )
158 {
159     union { uint64_t ui; float64_t f; } uA;
160     uint_fast64_t uiA;
161 
162     uA.f = a;
163     uiA = uA.ui;
164     fputc( uiA & UINT64_C( 0x8000000000000000 ) ? '-' : '+', stdout );
165     writeHex_ui12( uiA>>52 & 0x7FF, 0 );
166     fputc( '.', stdout );
167     writeHex_ui12( uiA>>40, 0 );
168     writeHex_ui8( uiA>>32, 0 );
169     writeHex_ui32( uiA, sepChar );
170 
171 }
172 
173 #endif
174 
175 #ifdef EXTFLOAT80
176 
writeHex_extF80M(const extFloat80_t * aPtr,char sepChar)177 void writeHex_extF80M( const extFloat80_t *aPtr, char sepChar )
178 {
179     const struct extFloat80M *aSPtr;
180     uint_fast16_t uiA64;
181 
182     aSPtr = (const struct extFloat80M *) aPtr;
183     uiA64 = aSPtr->signExp;
184     fputc( uiA64 & 0x8000 ? '-' : '+', stdout );
185     writeHex_ui16( uiA64 & 0x7FFF, 0 );
186     fputc( '.', stdout );
187     writeHex_ui64( aSPtr->signif, sepChar );
188 
189 }
190 
191 #endif
192 
193 #ifdef FLOAT128
194 
writeHex_f128M(const float128_t * aPtr,char sepChar)195 void writeHex_f128M( const float128_t *aPtr, char sepChar )
196 {
197     const struct uint128 *uiAPtr;
198     uint_fast64_t uiA64;
199 
200     uiAPtr = (const struct uint128 *) aPtr;
201     uiA64 = uiAPtr->v64;
202     fputc( uiA64 & UINT64_C( 0x8000000000000000 ) ? '-' : '+', stdout );
203     writeHex_ui16( uiA64>>48 & 0x7FFF, 0 );
204     fputc( '.', stdout );
205     writeHex_ui16( uiA64>>32, 0 );
206     writeHex_ui32( uiA64, 0 );
207     writeHex_ui64( uiAPtr->v0, sepChar );
208 
209 }
210 
211 #endif
212 
writeHex_softfloat_flags(uint_fast8_t flags,char sepChar)213 void writeHex_softfloat_flags( uint_fast8_t flags, char sepChar )
214 {
215 
216     fputc( flags & softfloat_flag_invalid   ? 'v' : '.', stdout );
217     fputc( flags & softfloat_flag_infinite  ? 'i' : '.', stdout );
218     fputc( flags & softfloat_flag_overflow  ? 'o' : '.', stdout );
219     fputc( flags & softfloat_flag_underflow ? 'u' : '.', stdout );
220     fputc( flags & softfloat_flag_inexact   ? 'x' : '.', stdout );
221     if ( sepChar ) fputc( sepChar, stdout );
222 
223 }
224 
225