2 ##########################################################################
7 # IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
8 # independent tool to test whether an implementation of #
9 # floating-point arithmetic (in hardware or software) is compliant #
10 # with the principles of the IEEE 754-854 floating-point standards. #
11 # You can find out more about the testing tool IeeeCC754 at #
13 # http://win-www.uia.ac.be/u/cant/ieeecc754.html #
15 # This tool is in parts based on and greatly benefited from the #
16 # the program FPTEST developed by Jerome Coonen. For a full #
17 # description of the extensions to FPTEST and a reference to #
18 # the original Coonen program, please refer to the URL given above. #
19 # For the options available with the program IeeeCC754 and its #
20 # compatibility with David Hough's hexadecimal UCB format, we #
21 # also refer to the file readme.usage. #
23 # Usage: see readme.usage #
25 # Responsible authors: #
30 # Johan Bogo (1998-1999) #
31 # Tim Gevers (10-12/2000) #
32 # Debby Ooms (1996-1997) #
33 # Geert Vermuyten (1996-1997) #
34 # Dennis Verschaeren (09/1996-06/2000) #
36 # Copyright (C) 2000 University of Antwerp #
38 # This program can be obtained from the authors, free, but WITHOUT ANY #
39 # WARRANTY; without even the implied warranty of MERCHANTABILITY or #
40 # FITNESS FOR A PARTICULAR PURPOSE. #
43 # Brigitte.Verdonk@uia.ua.ac.be #
44 # Department of Mathematics and Computer Science #
45 # University of Antwerp (UIA) #
46 # Universiteitsplein 1 #
47 # B2610 Antwerp, BELGIUM #
49 ##########################################################################
60 #include <DriverFloatRepr.h>
69 By default, all functions in this file are declared in the header file
73 except for two functions
75 DriverFloatRepr::DriverFloatRepr(<MyDatatype &D>)
76 <MyDatatype> DriverFloatRepr::to()
78 These two functions, for conversion between the floating-point
79 data type of your target implementation and DriverFloatRepr, the
80 floating-point data type of the driver program, should be declared
81 explicitly in the header file DriverFloatRepr.h, with MyDatatype
82 replaced by the appropriate identifier. */
84 void DriverFloatRepr::SetLibRound()
86 /* Make your library calls for changing the rounding mode */
91 // change rounding mode to round to nearest break;
92 fc_set_rounding_mode(FC_TONEAREST);
95 // change rounding mode to round to zero break;
96 fc_set_rounding_mode(FC_TOZERO);
99 // change rounding mode to round up break;
100 fc_set_rounding_mode(FC_TOPOSITIVE);
103 // change rounding mode to round down break;
104 fc_set_rounding_mode(FC_TONEGATIVE);
109 void DriverFloatRepr::SetLibEnvironment()
111 // clear all floating-point exceptions
114 void DriverFloatRepr::GetLibExceptions()
116 // do nothing, exceptions are unsupported
119 DriverFloatRepr::DriverFloatRepr(void* val) {
120 // convert your floating-point data type to the floating-point
121 // representation of the driver program
122 // replace MyDatatype by the appropriate identifier
124 unsigned int mantissa0;
125 unsigned int mantissa1;
134 mant = Bitstring(sizeMant);
135 exp = Bitstring(sizeExp);
137 if (fc_is_negative(val))
144 exponent = ((int)(fc_sub_bits(val, 64, 7) & 0x7F)) << 4;
145 exponent |= ((fc_sub_bits(NULL, 64, 6) & 0xF0) >> 4);
146 for (int i = sizeExp - 1;i >= 0; i--) {
147 exp.PutBit(i,exponent%2);
151 mantissa0 = ((int)(fc_sub_bits(NULL, 64, 6) & 0x0F)) << 16;
152 mantissa0 |= ((int)fc_sub_bits(NULL, 64, 5)) << 8;
153 mantissa0 |= (int)fc_sub_bits(NULL, 64, 4);
155 mantissa1 = ((int)fc_sub_bits(NULL, 64, 3)) << 24;
156 mantissa1 |= ((int)fc_sub_bits(NULL, 64, 2)) << 16;
157 mantissa1 |= ((int)fc_sub_bits(NULL, 64, 1)) << 8;
158 mantissa1 |= ((int)fc_sub_bits(NULL, 64, 0));
160 for (int i = 19;i >= 0; i--) {
161 mant.PutBit(i,mantissa0%2);
164 for (int i = 31;i >= 0; i--) {
165 mant.PutBit(20+i,mantissa1%2);
170 exponent = ((int)(fc_sub_bits(val, 32, 3) & 0x7F)) << 1;
171 exponent |= ((fc_sub_bits(NULL, 32, 2) & 0x80) >> 7);
172 for (int i = sizeExp - 1;i >= 0; i--) {
173 exp.PutBit(i,exponent%2);
177 mantissa0 = ((int)(fc_sub_bits(NULL, 32, 2) & 0x7F)) << 16;
178 mantissa0 |= ((int)fc_sub_bits(NULL, 32, 1)) << 8;
179 mantissa0 |= (int)fc_sub_bits(NULL, 32, 0);
181 for (int i = 22;i >= 0; i--) {
182 mant.PutBit(i,mantissa0%2);
188 void *DriverFloatRepr::to(void *buf)
189 // convert the the floating-point representation of the driver program
190 // to the floating-point data type of your implementation
192 unsigned int upper = 0;
193 unsigned int lower = 0;
203 for (int i = 0;i < sizeExp; i++) {
204 if (exp.GetBit(i) == 1)
208 for (int i = 0;i < 20; i++) {
209 if (mant.GetBit(i) == 1)
212 for (int i = 20;i < sizeMant; i++) {
213 if (mant.GetBit(i) == 1)
217 if (Endian == MYLITTLE_ENDIAN)
219 ((unsigned int*)&im_val)[0] = lower;
220 ((unsigned int*)&im_val)[1] = upper;
224 ((unsigned int*)&im_val)[1] = lower;
225 ((unsigned int*)&im_val)[0] = upper;
227 fc_val_from_float(im_val, 11, 52, (char*)buf);
229 for (int i = 0;i < sizeMant; i++) {
230 if (mant.GetBit(i) == 1)
234 *((unsigned int*)&im_val) = upper;
235 fc_val_from_float(im_val, 8, 23, (char*)buf);
240 // conversions between DriverFloatRepr and hardware integer
241 // data types; implementation should not be modified !
243 DriverFloatRepr::DriverFloatRepr(long i) {
248 temp[0] = (unsigned long) i;
249 temp.SubBitstring(0,mant);
252 DriverFloatRepr::DriverFloatRepr(unsigned long i) {
257 temp[0] = (unsigned long) i;
258 temp.SubBitstring(0,mant);
261 DriverFloatRepr::DriverFloatRepr(long long i) {
262 unsigned long *tmparray=new unsigned long[2];
263 tmparray = (unsigned long *)&i;
265 if (Endian == MYLITTLE_ENDIAN)
267 temp[0] = tmparray[0];
268 temp[1] = tmparray[1];
272 temp[0] = tmparray[1];
273 temp[1] = tmparray[0];
278 temp.SubBitstring(0,mant);
281 DriverFloatRepr::DriverFloatRepr(unsigned long long i) {
282 unsigned long *tmparray=new unsigned long[2];
283 tmparray = (unsigned long *)&i;
285 if (Endian == MYLITTLE_ENDIAN)
287 temp[0] = tmparray[0];
288 temp[1] = tmparray[1];
292 temp[0] = tmparray[1];
293 temp[1] = tmparray[0];
298 temp.SubBitstring(0,mant);
301 int DriverFloatRepr::toint() {
302 return (int&)mant[0];
305 unsigned int DriverFloatRepr::touint() {
306 return (unsigned int&)mant[0];
309 long long int DriverFloatRepr::tolonglong() {
310 unsigned long tmparray[2];
312 if (Endian == MYLITTLE_ENDIAN)
314 tmparray[0] = mant[0];
315 tmparray[1] = mant[1];
319 tmparray[0] = mant[1];
320 tmparray[1] = mant[0];
322 return (long long int&)*tmparray;
325 unsigned long long int DriverFloatRepr::toulonglong() {
326 unsigned long tmparray[2];
327 if (Endian == MYLITTLE_ENDIAN)
329 tmparray[0] = mant[0];
330 tmparray[1] = mant[1];
334 tmparray[0] = mant[1];
335 tmparray[1] = mant[0];
337 return (unsigned long long int&)*tmparray;