1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 #pragma ident "%Z%%M% %I% %E% SMI" 23 24 /* 25 * Copyright (c) 1988 by Sun Microsystems, Inc. 26 */ 27 28 /* Unpack procedures for Sparc FPU simulator. */ 29 30 #include "_Qquad.h" 31 #include "_Qglobals.h" 32 33 PRIVATE void 34 unpackinteger(pu, x) 35 unpacked *pu; /* unpacked result */ 36 int x; /* packed integer */ 37 { 38 unsigned ux; 39 pu->sticky = pu->rounded = 0; 40 if (x == 0) { 41 pu->sign = 0; 42 pu->fpclass = fp_zero; 43 } else { 44 (*pu).sign = x < 0; 45 (*pu).fpclass = fp_normal; 46 (*pu).exponent = INTEGER_BIAS; 47 if(x<0) ux = -x; else ux = x; 48 (*pu).significand[0] = ux>>15; 49 (*pu).significand[1] = (ux&0x7fff)<<17; 50 (*pu).significand[2] = 0; 51 (*pu).significand[3] = 0; 52 fpu_normalize(pu); 53 } 54 } 55 56 void 57 unpacksingle(pu, x) 58 unpacked *pu; /* unpacked result */ 59 single_type x; /* packed single */ 60 { 61 unsigned u; 62 pu->sticky = pu->rounded = 0; 63 u = x.significand; 64 (*pu).sign = x.sign; 65 pu->significand[1] = 0; 66 pu->significand[2] = 0; 67 pu->significand[3] = 0; 68 if (x.exponent == 0) { /* zero or sub */ 69 if (x.significand == 0) { /* zero */ 70 pu->fpclass = fp_zero; 71 return; 72 } else { /* subnormal */ 73 pu->fpclass = fp_normal; 74 pu->exponent = -SINGLE_BIAS-6; 75 pu->significand[0]=u; 76 fpu_normalize(pu); 77 return; 78 } 79 } else if (x.exponent == 0xff) { /* inf or nan */ 80 if (x.significand == 0) { /* inf */ 81 pu->fpclass = fp_infinity; 82 return; 83 } else { /* nan */ 84 if ((u & 0x400000) != 0) { /* quiet */ 85 pu->fpclass = fp_quiet; 86 } else {/* signaling */ 87 pu->fpclass = fp_signaling; 88 fpu_set_exception(fp_invalid); 89 } 90 pu->significand[0] = 0x18000 | (u >> 7); 91 (*pu).significand[1]=((u&0x7f)<<25); 92 return; 93 } 94 } 95 (*pu).exponent = x.exponent - SINGLE_BIAS; 96 (*pu).fpclass = fp_normal; 97 (*pu).significand[0]=0x10000|(u>>7); 98 (*pu).significand[1]=((u&0x7f)<<25); 99 } 100 101 void 102 unpackdouble(pu, x, y) 103 unpacked *pu; /* unpacked result */ 104 double_type x; /* packed double */ 105 unsigned y; 106 { 107 unsigned u; 108 pu->sticky = pu->rounded = 0; 109 u = x.significand; 110 (*pu).sign = x.sign; 111 pu->significand[1] = y; 112 pu->significand[2] = 0; 113 pu->significand[3] = 0; 114 if (x.exponent == 0) { /* zero or sub */ 115 if ((x.significand == 0) && (y == 0)) { /* zero */ 116 pu->fpclass = fp_zero; 117 return; 118 } else { /* subnormal */ 119 pu->fpclass = fp_normal; 120 pu->exponent = -DOUBLE_BIAS-3; 121 pu->significand[0] = u; 122 fpu_normalize(pu); 123 return; 124 } 125 } else if (x.exponent == 0x7ff) { /* inf or nan */ 126 if ((u|y) == 0) { /* inf */ 127 pu->fpclass = fp_infinity; 128 return; 129 } else { /* nan */ 130 if ((u & 0x80000) != 0) { /* quiet */ 131 pu->fpclass = fp_quiet; 132 } else {/* signaling */ 133 pu->fpclass = fp_signaling; 134 fpu_set_exception(fp_invalid); 135 } 136 pu->significand[0] = 0x18000 | (u >> 4); 137 (*pu).significand[1]=((u&0xf)<<28)|(y>>4); 138 (*pu).significand[2]=((y&0xf)<<28); 139 return; 140 } 141 } 142 (*pu).exponent = x.exponent - DOUBLE_BIAS; 143 (*pu).fpclass = fp_normal; 144 (*pu).significand[0]=0x10000|(u>>4); 145 (*pu).significand[1]=((u&0xf)<<28)|(y>>4); 146 (*pu).significand[2]=((y&0xf)<<28); 147 } 148 149 PRIVATE void 150 unpackextended(pu, x, y, z, w) 151 unpacked *pu; /* unpacked result */ 152 extended_type x; /* packed extended */ 153 unsigned y, z, w; 154 { 155 unsigned u; 156 pu->sticky = pu->rounded = 0; 157 u = x.significand; 158 (*pu).sign = x.sign; 159 (*pu).fpclass = fp_normal; 160 (*pu).exponent = x.exponent - EXTENDED_BIAS; 161 (*pu).significand[0] = (x.exponent==0)? u:0x10000|u; 162 (*pu).significand[1] = y; 163 (*pu).significand[2] = z; 164 (*pu).significand[3] = w; 165 if (x.exponent < 0x7fff) { /* zero, normal, or subnormal */ 166 if ((z|y|w|pu->significand[0]) == 0) { /* zero */ 167 pu->fpclass = fp_zero; 168 return; 169 } else { /* normal or subnormal */ 170 if(x.exponent==0) { 171 fpu_normalize(pu); 172 pu->exponent += 1; 173 } 174 return; 175 } 176 } else { /* inf or nan */ 177 if ((u|z|y|w) == 0) { /* inf */ 178 pu->fpclass = fp_infinity; 179 return; 180 } else { /* nan */ 181 if ((u & 0x00008000) != 0) { /* quiet */ 182 pu->fpclass = fp_quiet; 183 } else {/* signaling */ 184 pu->fpclass = fp_signaling; 185 fpu_set_exception(fp_invalid); 186 } 187 pu->significand[0] |= 0x8000; /* make quiet */ 188 return; 189 } 190 } 191 } 192 193 void 194 _fp_unpack(pu, n, dtype) 195 unpacked *pu; /* unpacked result */ 196 int *n; /* input array */ 197 enum fp_op_type dtype; /* type of datum */ 198 199 { 200 switch ((int) dtype) { 201 case fp_op_integer: 202 unpackinteger(pu, n[0]); 203 break; 204 case fp_op_single: 205 { 206 single_type x; 207 *(int*)&x = n[0]; 208 unpacksingle(pu, x); 209 break; 210 } 211 case fp_op_double: 212 { 213 double_type x; 214 double t=1.0; int i0,i1; 215 if((*(int*)&t)!=0) {i0=0;i1=1;} else {i0=1;i1=0;} 216 *(int*)&x = n[i0]; 217 unpackdouble(pu, x, n[i1]); 218 break; 219 } 220 case fp_op_extended: 221 { 222 extended_type x; 223 double t=1.0; int i0,i1,i2,i3; 224 if((*(int*)&t)!=0) {i0=0;i1=1;i2=2;i3=3;} 225 else {i0=3;i1=2;i2=1;i3=0;} 226 *(int*)&x = n[i0]; 227 unpackextended(pu, x, n[i1], n[i2], n[i3]); 228 break; 229 } 230 } 231 } 232