1
2/*
3===============================================================================
4
5This C source file is part of TestFloat, Release 2a, a package of programs
6for testing the correctness of floating-point arithmetic complying to the
7IEC/IEEE Standard for Floating-Point.
8
9Written by John R. Hauser.  More information is available through the Web
10page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11
12THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17
18Derivative works are acceptable, even for commercial purposes, so long as
19(1) they include prominent notice that the work is derivative, and (2) they
20include prominent notice akin to these four paragraphs for those parts of
21this code that are retained.
22
23===============================================================================
24*/
25
26#include <stdio.h>
27#include "milieu.h"
28#include "softfloat.h"
29#include "writeHex.h"
30
31void writeHex_flag( flag a, FILE *stream )
32{
33
34    fputc( a ? '1' : '0', stream );
35
36}
37
38static void writeHex_bits8( bits8 a, FILE *stream )
39{
40    int digit;
41
42    digit = ( a>>4 ) & 0xF;
43    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
44    fputc( '0' + digit, stream );
45    digit = a & 0xF;
46    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
47    fputc( '0' + digit, stream );
48
49}
50
51static void writeHex_bits12( int16 a, FILE *stream )
52{
53    int digit;
54
55    digit = ( a>>8 ) & 0xF;
56    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
57    fputc( '0' + digit, stream );
58    digit = ( a>>4 ) & 0xF;
59    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
60    fputc( '0' + digit, stream );
61    digit = a & 0xF;
62    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
63    fputc( '0' + digit, stream );
64
65}
66
67static void writeHex_bits16( bits16 a, FILE *stream )
68{
69    int digit;
70
71    digit = ( a>>12 ) & 0xF;
72    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
73    fputc( '0' + digit, stream );
74    digit = ( a>>8 ) & 0xF;
75    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
76    fputc( '0' + digit, stream );
77    digit = ( a>>4 ) & 0xF;
78    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
79    fputc( '0' + digit, stream );
80    digit = a & 0xF;
81    if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
82    fputc( '0' + digit, stream );
83
84}
85
86void writeHex_bits32( bits32 a, FILE *stream )
87{
88
89    writeHex_bits16( a>>16, stream );
90    writeHex_bits16( a, stream );
91
92}
93
94#ifdef BITS64
95
96void writeHex_bits64( bits64 a, FILE *stream )
97{
98
99    writeHex_bits32( a>>32, stream );
100    writeHex_bits32( a, stream );
101
102}
103
104#endif
105
106void writeHex_float32( float32 a, FILE *stream )
107{
108
109    fputc( ( ( (sbits32) a ) < 0 ) ? '8' : '0', stream );
110    writeHex_bits8( a>>23, stream );
111    fputc( '.', stream );
112    writeHex_bits8( ( a>>16 ) & 0x7F, stream );
113    writeHex_bits16( a, stream );
114
115}
116
117#ifdef BITS64
118
119void writeHex_float64( float64 a, FILE *stream )
120{
121
122    writeHex_bits12( a>>52, stream );
123    fputc( '.', stream );
124    writeHex_bits12( a>>40, stream );
125    writeHex_bits8( a>>32, stream );
126    writeHex_bits32( a, stream );
127
128}
129
130#else
131
132void writeHex_float64( float64 a, FILE *stream )
133{
134
135    writeHex_bits12( a.high>>20, stream );
136    fputc( '.', stream );
137    writeHex_bits12( a.high>>8, stream );
138    writeHex_bits8( a.high, stream );
139    writeHex_bits32( a.low, stream );
140
141}
142
143#endif
144
145#ifdef FLOATX80
146
147void writeHex_floatx80( floatx80 a, FILE *stream )
148{
149
150    writeHex_bits16( a.high, stream );
151    fputc( '.', stream );
152    writeHex_bits64( a.low, stream );
153
154}
155
156#endif
157
158#ifdef FLOAT128
159
160void writeHex_float128( float128 a, FILE *stream )
161{
162
163    writeHex_bits16( a.high>>48, stream );
164    fputc( '.', stream );
165    writeHex_bits16( a.high>>32, stream );
166    writeHex_bits32( a.high, stream );
167    writeHex_bits64( a.low, stream );
168
169}
170
171#endif
172
173void writeHex_float_flags( uint8 flags, FILE *stream )
174{
175
176    fputc( flags & float_flag_invalid   ? 'v' : '.', stream );
177    fputc( flags & float_flag_divbyzero ? 'z' : '.', stream );
178    fputc( flags & float_flag_overflow  ? 'o' : '.', stream );
179    fputc( flags & float_flag_underflow ? 'u' : '.', stream );
180    fputc( flags & float_flag_inexact   ? 'x' : '.', stream );
181
182}
183
184