Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / fp / extend.c
1 /*
2   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3   See the copyright notice in the ACK home directory, in the file "Copyright".
4 */
5
6 /* $Id: extend.c,v 1.12 1994/06/24 13:31:57 ceriel Exp $ */
7
8 /*
9         CONVERTS FLOATING POINT TO EXTENDED FORMAT
10
11         Two sizes of FLOATING Point are known:
12                 SINGLE and DOUBLE
13 */
14 /********************************************************/
15 /*
16         It is not required to normalize in extended
17         format, but it has been chosen to do so.
18         Extended Format is as follows (at exit):
19
20 ->sign  S000 0000 | 0000 0000           <SIGN>
21 ->exp   0EEE EEEE | EEEE EEEE           <EXPONENT>
22 ->m1    LFFF FFFF | FFFF FFFF           <L.Fraction>
23         FFFF FFFF | FFFF FFFF           <Fraction>
24 ->m2    FFFF FFFF | FFFF FFFF           <Fraction>
25         FFFF F000 | 0000 0000           <Fraction>
26 */
27 /********************************************************/
28
29 #include "FP_bias.h"
30 #include "FP_shift.h"
31 #include "FP_types.h"
32 #include "get_put.h"
33 /********************************************************/
34
35 void
36 extend(from,to,size)
37 unsigned long   *from;
38 EXTEND  *to;
39 int     size;
40 {
41         register char *cpt1;
42         unsigned long   tmp;
43         int     leadbit = 0;
44
45         cpt1 = (char *) from;
46
47 #if FL_MSL_AT_LOW_ADDRESS
48 #if FL_MSW_AT_LOW_ADDRESS
49         to->exp = uget2(cpt1);
50 #else
51         to->exp = uget2(cpt1+2);
52 #endif
53 #else
54 #if FL_MSW_AT_LOW_ADDRESS
55         to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 4 : 0));
56 #else
57         to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 6 : 2));
58 #endif
59 #endif
60         to->sign = (to->exp & 0x8000);  /* set sign bit */
61         to->exp ^= to->sign;
62         if (size == sizeof(DOUBLE))
63                 to->exp >>= DBL_EXPSHIFT;
64         else
65                 to->exp >>= SGL_EXPSHIFT;
66         if (to->exp > 0)
67                 leadbit++;      /* will set Lead bit later      */
68         else to->exp++;
69
70         if (size == sizeof(DOUBLE))     {
71 #if FL_MSL_AT_LOW_ADDRESS
72                 to->m1 = get4(cpt1);
73                 cpt1 += 4;
74                 tmp = get4(cpt1);
75 #else
76                 tmp = get4(cpt1);
77                 cpt1 += 4;
78                 to->m1 = get4(cpt1);
79 #endif
80                 if (to->exp == 1 && to->m1 == 0 && tmp == 0) {
81                         to->exp = 0;
82                         to->sign = 0;
83                         to->m1 = 0;
84                         to->m2 = 0;
85                         return;
86                 }
87                 to->m1 <<= DBL_M1LEFT;          /* shift        */
88                 to->exp -= DBL_BIAS;            /* remove bias  */
89                 to->m1 |= (tmp>>DBL_RPACK);     /* plus 10 == 32        */
90                 to->m2 = (tmp<<DBL_LPACK);      /* plus 22 == 32        */
91         }
92         else    {       /* size == sizeof(SINGLE)               */
93                 to->m1 = get4(cpt1);
94                 to->m1  <<= SGL_M1LEFT; /* shift        */
95                 if (to->exp == 1 && to->m1 == 0) {
96                         to->exp = 0;
97                         to->sign = 0;
98                         to->m1 = 0;
99                         to->m2 = 0;
100                         return;
101                 }
102                 to->exp -= SGL_BIAS;            /* remove bias  */
103                 to->m2 = 0L;
104         }
105
106         to->m1 |= NORMBIT;                              /* set bit L    */
107         if (leadbit == 0) {             /* set or clear Leading Bit     */
108                 to->m1 &= ~NORMBIT;                     /* clear bit L  */
109                 nrm_ext(to);                            /* and normalize */
110         }
111 }