simplify Sel lowering code
[libfirm] / ir / tv / IeeeCC754 / src / fp.cc
1 /*
2 ##########################################################################
3 #                                                                        #
4 # Program: IeeeCC754                                                     #
5 #                                                                        #
6 # Description:                                                           #
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            #
12 #                                                                        #
13 #         http://win-www.uia.ac.be/u/cant/ieeecc754.html                 #
14 #                                                                        #
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.                                 #
22 #                                                                        #
23 #  Usage: see readme.usage                                               #
24 #                                                                        #
25 #  Responsible authors:                                                  #
26 #         Brigitte Verdonk                                               #
27 #         Annie Cuyt                                                     #
28 #                                                                        #
29 #  Contributors:                                                         #
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)                           #
35 #                                                                        #
36 #  Copyright (C) 2000  University of Antwerp                             #
37 #                                                                        #
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.                                     #
41 #                                                                        #
42 #  Contact:                                                              #
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                                           #
48 #                                                                        #
49 ##########################################################################
50
51 Filename:
52        $RCSfile$
53
54 Last updated:
55        $Date$
56
57 */
58 #include "Fp.h"
59
60 #ifdef IntelPentium
61 #include <string.h>
62 #endif
63
64
65 int FP::Endian = NOT_KNOWN;
66 Bitstring FP::fpEnv(32);
67
68 int FP::GetFPRound()
69 {
70   Bitstring temp(2);
71   //cout << "fpEnv = " << fpEnv << endl;
72   fpEnv.SubBitstring(21,temp);
73   //cout << "temp = " << temp << endl;
74   return (temp[0]>>30);
75 }
76
77 void FP::ClearFPEnvironment()
78 {
79   fpEnv.Clear(0);
80   fpEnv.Clear(1);
81   fpEnv.Clear(2);
82   fpEnv.Clear(3);
83   fpEnv.Clear(4);
84 }
85
86 /***********************************************************************
87 * Member:  CheckEndian()
88 * Purpose:
89 * Return:  void
90 ***********************************************************************/
91 void FP::CheckEndian()
92 {
93   //  char *tmp = new char[4];
94   char *tmp;
95   unsigned long tmplong =1;
96
97   if (FP::Endian == NOT_KNOWN)
98     {
99       tmp= (char*)&tmplong;
100       if (tmp[0]== 1)
101   Endian= MYLITTLE_ENDIAN;
102       else
103   Endian= MYBIG_ENDIAN;
104     }
105
106   //  delete tmp;
107 }
108
109
110 /***********************************************************************
111 * Member:  FP () Constructor
112 * Purpose: Create a floating point number
113 * Return:  Nothing
114 ***********************************************************************/
115 FP::FP()
116 {
117   CheckEndian();
118   sign= -1;
119   hidden =-1;
120   sizeMant=0;
121   sizeExp=0;
122   decimal = NULL;
123   //  fpEnv.Resize(32);
124 }
125
126 /***********************************************************************
127 * Member:  FP (int sizeM, int sizeE, int hiddenbit=0) Constructor
128 * Purpose: Create a floating point number with the size of the exponent
129 *          and the mantissa defined and if the there is a hidden bit
130 *          0 -> false
131 *          1 -> true
132 * Return:  Nothing
133 ***********************************************************************/
134 FP::FP(int sizeM, int sizeE,int hiddenbit)
135 {
136   CheckEndian();
137   sign= -1;
138   hidden=hiddenbit;
139   sizeMant=sizeM;
140   sizeExp=sizeE;
141   decimal = NULL;
142   mant.Resize(sizeM);
143   exp.Resize(sizeE);
144   //  fpEnv.Resize(32);
145 }
146
147 /***********************************************************************
148 * Member:  FP (Bitstring &fp,int sizeM,int sizeE,int hiddenbit=0) Constructor
149 * Purpose: Create a floating point number with the size of the exponent
150 *          and the mantissa defined and if the there is a hidden bit
151 *          0 -> false, 1 -> true and initialize it with "fp" as a
152 *          bit representation of a IEEE 754 floating point number
153 * Return:  Nothing
154 ***********************************************************************/
155
156 FP::FP(Bitstring &fp,int sizeM, int sizeE,int hiddenbit)
157 {
158   CheckEndian();
159   //  fpEnv.Resize(32);
160   sign= -1;
161   hidden =hiddenbit;
162   sizeMant=sizeM;
163   sizeExp=sizeE;
164   decimal = NULL;
165
166   mant = Bitstring(sizeMant);
167   if (sizeExp > 0)
168     exp = Bitstring(sizeExp);
169   else
170     exp = Bitstring();
171
172   sign = fp.GetBit(0);
173   // cout << "exp (voor) = " << exp << endl;
174   if (sizeExp > 0) {
175     fp.SubBitstring(1,exp);
176     fp.SubBitstring(sizeExp+1,mant);
177   }
178   else // integer
179     fp.SubBitstring(0,mant);
180 }
181
182 /***********************************************************************
183 * Member:  FP(FP & copy)  Copy constructor
184 * Purpose: Create a floating point number with initiale value the
185 *          floating point "copy"
186 * Return:  Nothing
187 ***********************************************************************/
188 FP::FP(FP & copy)
189 {
190   CheckEndian();
191   //  fpEnv.Resize(32);
192   sign = copy.sign;
193   hidden = copy.hidden;
194   sizeExp = copy.sizeExp;
195   sizeMant = copy.sizeMant;
196   mant = copy.mant;
197   exp = copy.exp;
198   if (copy.decimal != NULL) {
199     decimal = new char[256];
200     strcpy(decimal,copy.decimal);
201   }
202   else
203     decimal = NULL;
204   // cout << "copy decimal" << decimal << endl << flush;
205 }
206
207
208
209 FP& FP::operator = ( const FP &copy)
210 {
211   sign = copy.sign;
212   hidden = copy.hidden;
213   sizeExp = copy.sizeExp;
214   sizeMant = copy.sizeMant;
215   mant = copy.mant;
216   exp = copy.exp;
217   if (copy.decimal != NULL) {
218     decimal = new char[maxstr];
219     strcpy(decimal,copy.decimal);
220   }
221   else
222     decimal = NULL;
223   // cout << "copy decimal" << decimal << endl << flush;
224   return *this;
225 }
226
227
228 int FP::Sign(int sgn)
229 {
230   int temp = sign;
231   if (sgn != -1)
232     {
233       if ((sgn == 0)||(sgn==1))
234   sign = sgn;
235     }
236   return temp;
237 }
238
239 Bitstring & FP::GetMantissa()
240 {
241   // cout << "sizeMant = " << sizeMant << endl;
242   return mant;
243 }
244
245 Bitstring & FP::GetExponent()
246 {
247     return exp;
248 }
249
250 Bitstring  FP::PutMantissa(Bitstring &mantissa)
251 {
252   Bitstring temp(mant);
253
254   mant=mantissa;
255   // mant.Resize(sizeMant+hidden);       //in case the mantisa is too big
256   return temp;
257 }
258
259 Bitstring  FP::PutExponent(Bitstring &exponent)
260 {
261   Bitstring temp(exp);
262
263   exp=exponent;
264   exp.Resize(sizeExp);       //in case the mantisa is too big
265   return temp;
266 }
267
268 int FP::IsNaN()
269 {
270   int i;
271   Bitstring fullExp(sizeExp);
272   Bitstring fullMant(sizeMant+hidden);
273
274   if (sizeExp > 0) {
275     for (i=0; i < sizeExp ; i++)
276       fullExp.PutBit(i,1);
277     if (fullExp != exp)
278       return 0;
279     for (i=0; i < sizeMant ; i++)
280       fullMant.PutBit(i,0);
281     if (!hidden)
282       fullMant.PutBit(0,1);
283     return(fullMant != mant);
284   }
285   else
286     return 0;
287 }
288
289 int FP::istiny()
290 {
291   int i;
292   Bitstring fullExp(sizeExp);
293   Bitstring fullMant(sizeMant);
294   if ((sizeMant > 0) && (sizeExp > 0)) {
295     for (i=0; i < sizeExp; i++)
296       fullExp.PutBit(i,0);
297     for (i=0; i < sizeMant ; i++)
298       fullMant.PutBit(i,0);
299     return ((fullExp == exp) && (fullMant != mant));
300   }
301   else
302     return 0;
303 }
304
305 int FP::isInf()
306 {
307   int i;
308   Bitstring fullExp(sizeExp);
309   Bitstring fullMant(sizeMant);
310   if ((sizeMant > 0) && (sizeExp > 0)) {
311     for (i=0; i < sizeExp ; i++)
312       fullExp.PutBit(i,1);
313     if (fullExp == exp) {
314       i = 0;
315       if (!hidden)
316   i++;
317       for (;i < sizeMant;i++)
318   if (mant.GetBit(i) != 0)
319     return 0;
320       return 1;
321     }
322     else
323       return 0;
324   }
325   else
326     return 0;
327 }
328
329 int FP::isNan()
330 {
331   int i;
332   Bitstring fullExp(sizeExp);
333   Bitstring fullMant(sizeMant);
334   if ((sizeMant > 0) && (sizeExp > 0)) {
335     for (i=0; i < sizeExp ; i++)
336       fullExp.PutBit(i,1);
337     if (fullExp == exp) {
338       i = 0;
339       if (!hidden)
340   i++;
341       for (;i < sizeMant;i++)
342   if (mant.GetBit(i) != 0)
343     return 1;
344       return 0;
345     }
346     else
347       return 0;
348   }
349   else
350     return 0;
351 }
352
353
354 void  FP::CreateQFPNan()
355 {
356
357   int i;
358   for (i=0; i < sizeExp ; i++)
359     exp.PutBit(i,1);
360
361   mant.PutBit(sizeMant-1,1); //PLAATS
362 }
363
364
365 FP& FP::operator = (const Bitstring &copy)
366 {
367   copy.SubBitstring(0,mant);
368   copy.SubBitstring(sizeMant,exp);
369   sign = copy.GetBit(sizeMant+sizeExp);
370 /*
371   if (hidden)
372     {
373       mant.Resize(sizeMant+1);
374
375       Bitstring emptyExp(sizeExp);
376       for (int i=0; i< sizeExp; i++)
377   emptyExp.PutBit(i,0);
378
379       if (emptyExp != exp)                 //denormalized
380   mant.PutBit(sizeMant,1);
381     }
382 */
383   return *this;
384 }
385
386
387 void FP::SetFPRound (int rm)
388 {
389   fpEnv.Clear(21);
390   fpEnv.Clear(22);
391   // cout << "fpEnv (SetFPR) = " << fpEnv << endl;
392   switch (rm)
393     {
394     case RM_UP:
395       fpEnv.Set(21);
396       break;
397     case RM_DOWN:
398       fpEnv.Set(22);
399       break;
400     case RM_ZERO:
401       fpEnv.Set(21);
402       fpEnv.Set(22);
403       break;
404     }
405   // cout << "fpEnv = " << fpEnv << endl;
406 }
407
408 void FP::GetFPExceptions(Bitstring E)
409 {
410   fpEnv.SubBitstring(0,E);
411 }
412
413 ostream& operator << (ostream& outs, FP &strout)
414 {int i;
415
416   if (strout.decimal != NULL) // decimal representation
417     outs << strout.decimal;
418   else {
419 /*
420     if (strout.sizeExp > 0) {
421       if (strout.sign)
422          outs << '1';
423       else
424          outs << '0';
425       outs << " " << hex << strout.exp << " " << strout.mant;
426     }
427     else
428       outs << hex << strout.mant;
429 */
430     int size;
431     if (strout.sizeExp > 0)
432       size = 1+strout.sizeExp+strout.sizeMant;
433     else
434       size = strout.sizeMant;
435     Bitstring merge(size);
436     if (strout.sizeExp > 0) {
437       if (strout.sign)
438   merge.PutBit(0,1);
439       else
440   merge.PutBit(0,0);
441       for (i = 0; i < strout.sizeExp;i++)
442   merge.PutBit(i+1,strout.exp.GetBit(i));
443       for (i = 0; i < strout.sizeMant;i++)
444   merge.PutBit(1+strout.sizeExp+i,strout.mant.GetBit(i));
445     }
446     else { // integer
447       for (i = 0; i < strout.sizeMant;i++)
448   merge.PutBit(i,strout.mant.GetBit(i));
449     }
450     outs << merge;
451   }
452   return outs;
453 }
454
455 /*
456 istream& operator >> (istream& ins, FP &instr)
457 {
458   char str[255];
459
460   cin>> str;
461   instr.StringToBitstr(str);
462
463   return ins;
464 }*/
465
466 int FP::IsZero()
467 {
468   int i;
469   if ((sizeMant > 0) && (sizeExp > 0)) {
470     for (i=0; i < sizeExp ; i++)
471       if ( exp.GetBit(i) != 0 ){
472         return 0;
473       }
474   i=0;
475   if (!hidden)
476     i++;
477   for (;i < sizeMant;i++)
478     if (mant.GetBit(i) != 0)
479       return 0;
480   }
481   return 1;
482 }
483
484 int FP::IsNegZero()
485 {
486   return 0;
487   if ( sign == 0 )
488     return 0;
489   int i;
490   if ((sizeMant > 0) && (sizeExp > 0)) {
491     for (i=0; i < sizeExp ; i++)
492       if ( exp.GetBit(i) != 0 ){
493         return 0;
494       }
495   i=0;
496   if (!hidden)
497     i++;
498   for (;i < sizeMant;i++)
499     if (mant.GetBit(i) != 0)
500       return 0;
501   }
502   return 1;
503 }