OpenSolaris_b135/lib/libbc/libc/gen/common/unpack_float.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 1988 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

/* IEEE function implementations.	 */

#include "base_conversion.h"

enum fp_class_type
_class_single(single *x)
{
	single_equivalence kluge;

	kluge.x = *x;
	if (kluge.f.msw.exponent == 0) {	/* 0 or sub */
		if (kluge.f.msw.significand == 0)
			return fp_zero;
		else
			return fp_subnormal;
	} else if (kluge.f.msw.exponent == 0xff) {	/* inf or nan */
		if (kluge.f.msw.significand == 0)
			return fp_infinity;
		else if (kluge.f.msw.significand >= 0x400000)
			return fp_quiet;
		else
			return fp_signaling;
	} else
		return fp_normal;
}

enum fp_class_type
_class_extended(extended *x)
{
	extended_equivalence kluge;

	kluge.x[0] = (*x)[0];
	kluge.x[1] = (*x)[1];
	kluge.x[2] = (*x)[2];
	if (kluge.f.msw.exponent == 0) {	/* 0 or sub */
		if ((kluge.f.significand == 0) && (kluge.f.significand2 == 0))
			return fp_zero;
		else
			return fp_subnormal;
	} else if (kluge.f.msw.exponent == 0x7fff) {	/* inf or nan */
		if (((kluge.f.significand & 0x7fffffff) == 0) && (kluge.f.significand2 == 0))
			return fp_infinity;
		else if ((kluge.f.significand & 0x7fffffff) >= 0x40000000)
			return fp_quiet;
		else
			return fp_signaling;
	} else
		return fp_normal;
}

void
_unpack_single(unpacked *pu, single *px)
{
	single_equivalence x;
	int             i;

	x.x = *px;
	(*pu).sign = x.f.msw.sign;
	for (i = 1; i < UNPACKED_SIZE; i++)
		pu->significand[i] = 0;
	if (x.f.msw.exponent == 0) {	/* zero or sub */
		if (x.f.msw.significand == 0) {	/* zero */
			pu->fpclass = fp_zero;
			return;
		} else {	/* subnormal */
			pu->fpclass = fp_normal;
			pu->exponent = -SINGLE_BIAS;
			pu->significand[0] = x.f.msw.significand << 9;
			_fp_normalize(pu);
			return;
		}
	} else if (x.f.msw.exponent == 0xff) {	/* inf or nan */
		if (x.f.msw.significand == 0) {	/* inf */
			pu->fpclass = fp_infinity;
			return;
		} else {	/* nan */
			if ((x.f.msw.significand & 0x400000) != 0) {	/* quiet */
				pu->fpclass = fp_quiet;
			} else {/* signaling */
				pu->fpclass = fp_quiet;
				_fp_set_exception(fp_invalid);
			}
			pu->significand[0] = 0x40000000 | (x.f.msw.significand << 8);
			return;
		}
	}
	(*pu).exponent = x.f.msw.exponent - SINGLE_BIAS;
	(*pu).fpclass = fp_normal;
	(*pu).significand[0] = 0x80000000 | (x.f.msw.significand << 8);
}

void
_unpack_extended(unpacked *pu, extended *px)
{
	extended_equivalence x;
	int             i;

	x.x[0] = (*px)[0];
	x.x[1] = (*px)[1];
	x.x[2] = (*px)[2];
	pu->sign = x.f.msw.sign;
	pu->fpclass = fp_normal;
	pu->exponent = x.f.msw.exponent - EXTENDED_BIAS;
	pu->significand[0] = x.f.significand;
	pu->significand[1] = x.f.significand2;
	for (i = 2; i < UNPACKED_SIZE; i++)
		pu->significand[i] = 0;
	if (x.f.msw.exponent == 0x7fff) {	/* inf or nan */
		if (((x.f.significand & 0x7fffffff) == 0) && (x.f.significand2 == 0)) {	/* inf */
			pu->fpclass = fp_infinity;
			return;
		} else {	/* nan */
			if ((x.f.significand & 0x40000000) != 0) {	/* quiet */
				pu->fpclass = fp_quiet;
			} else {/* signaling */
				pu->fpclass = fp_quiet;
				_fp_set_exception(fp_invalid);
			}
			return;
		}
	}
	if (x.f.significand < 0x80000000) {	/* zero or unnormal */
		if ((x.f.significand == 0) && (x.f.significand2 == 0)) {	/* zero */
			pu->fpclass = fp_zero;
			return;
		} else {	/* unnormal */
			pu->fpclass = fp_normal;
			_fp_normalize(pu);
			return;
		}
	}
}

void
_display_unpacked(unpacked *pu)
{
	int             i, e;

	(void) printf(" unpacked ");
	if (pu->sign == 1)
		(void) printf("-");
	else
		(void) printf("+");
	switch (pu->fpclass) {
	case fp_zero:
		(void) printf("0");
		break;
	case fp_infinity:
		(void) printf("Infinity");
		break;
	case fp_quiet:
		(void) printf("NaN(quiet)");
		break;
	case fp_signaling:
		(void) printf("NaN(signaling)");
		break;
	case fp_subnormal:
	case fp_normal:
		e = 1 + pu->exponent;
		for (i = 0; i < UNPACKED_SIZE; i++) {
			e -= 32;
			(void) printf(" %8X *2**%d + ", pu->significand[i], e);
		}
	}
	(void) printf("\n");
}