/*
 *
 * Copyright 1998-1999, University of Notre Dame.
 * Authors: Jeffrey M. Squyres, Kinis L. Meyer with M. D. McNally 
 *          and Andrew Lumsdaine
 *
 * This file is part of the Notre Dame LAM implementation of MPI.
 *
 * You should have received a copy of the License Agreement for the
 * Notre Dame LAM implementation of MPI along with the software; see
 * the file LICENSE.  If not, contact Office of Research, University
 * of Notre Dame, Notre Dame, IN 46556.
 *
 * Permission to modify the code and to distribute modified code is
 * granted, provided the text of this NOTICE is retained, a notice that
 * the code was modified is included with the above COPYRIGHT NOTICE and
 * with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
 * file is distributed with the modified code.
 *
 * LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
 * By way of example, but not limitation, Licensor MAKES NO
 * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
 * PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
 * OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
 * OR OTHER RIGHTS.  
 *
 * Additional copyrights may follow.
 *
 *	Ohio Trollius
 *	Copyright 1997 The Ohio State University
 *	RBD/NJN
 *
 *	$Id: ieee.c,v 6.5 1999/09/02 02:43:46 jsquyres Exp $
 * 
 *	Function:	- change floating point to/from IEEE big-endian
 *			- handles floats, doubles and long doubles
 *			- requires XDR support for floating point numbers
 *			- OTB version
 */

#include <lam_config.h>

#include <stdio.h>
#if HAVE_RPC_TYPES_H
#include <rpc/types.h>
#endif
#if HAVE_RPC_XDR_H
#include <rpc/xdr.h>
#endif

/*
 *	ltoieeef
 *
 *	Function:	- change a float from local to IEEE big-endian
 *	Accepts:	- ptr source float
 *			- ptr destination area
 */
void
ltoieeef(src, dest)

float			*src;
void			*dest;

{
	float		orig;
	XDR		xdrs;

	orig = *src;
	xdrmem_create(&xdrs, (char *) dest, sizeof(float), XDR_ENCODE);

	(void) xdr_float(&xdrs, &orig);
	xdr_destroy(&xdrs);
}

/*
 *	ltoieeed
 *
 *	Function:	- change a double from local to IEEE big-endian
 *	Accepts:	- ptr source double
 *			- ptr destination area
 */
void
ltoieeed(src, dest)

double			*src;
void			*dest;

{
	double		orig;
	XDR		xdrs;

	orig = *src;
	xdrmem_create(&xdrs, (char *) dest, sizeof(double), XDR_ENCODE);

	(void) xdr_double(&xdrs, &orig);
	xdr_destroy(&xdrs);
}

#if LAM_SIZEOF_LONG_DOUBLE == 16
/*
 *	ltoieeeld
 *
 *	Function:	- change a long double from local to IEEE big-endian
 *	Accepts:	- ptr source long double
 *			- ptr destination area
 */
void
ltoieeeld(src, dest)

long double		*src;
void			*dest;

{
	long double	orig;
	XDR		xdrs;

	orig = *src;
	xdrmem_create(&xdrs, (char *) dest, sizeof(long double), XDR_ENCODE);

	(void) xdr_quadruple(&xdrs, &orig);
	xdr_destroy(&xdrs);
}
#endif

/*
 *	ieeetolf
 *
 *	Function:	- change a float from IEEE big-endian to local
 *	Accepts:	- ptr source area
 *			- ptr destination float
 */
void
ieeetolf(src, dest)

void			*src;
float			*dest;

{
	float		result;
	XDR		xdrs;

	xdrmem_create(&xdrs, (char *) src, sizeof(float), XDR_DECODE);

	(void) xdr_float(&xdrs, &result);
	*dest = result;

	xdr_destroy(&xdrs);
}

/*
 *	ieeetold
 *
 *	Function:	- change a double from IEEE big-endian to local
 *	Accepts:	- ptr source area
 *			- ptr destination double
 */
void
ieeetold(src, dest)

void			*src;
double			*dest;

{
	double		result;
	XDR		xdrs;

	xdrmem_create(&xdrs, (char *) src, sizeof(double), XDR_DECODE);

	(void) xdr_double(&xdrs, &result);
	*dest = result;

	xdr_destroy(&xdrs);
}

#if LAM_SIZEOF_LONG_DOUBLE == 16
/*
 *	ieeetolld
 *
 *	Function:	- change a long double from IEEE big-endian to local
 *	Accepts:	- ptr source area
 *			- ptr destination long double
 */
void
ieeetolld(src, dest)

void			*src;
long double		*dest;

{
	long double	result;
	XDR		xdrs;

	xdrmem_create(&xdrs, (char *) src, sizeof(long double), XDR_DECODE);

	(void) xdr_quadruple(&xdrs, &result);
	*dest = result;

	xdr_destroy(&xdrs);
}
#endif

/*
 *	mltoieeef
 *
 *	Function:	- change array of floats from local to IEEE big-endian
 *	Accepts:	- ptr array
 *			- # elements in array
 */
void
mltoieeef(array, num)

float			*array;
int			num;

{
	for ( ; num > 0; --num, ++array) {
		ltoieeef(array, (void *) array);
	}
}

/*
 *	mieeetolf
 *
 *	Function:	- change array of floats from IEEE big-endian to local
 *	Accepts:	- ptr array
 *			- # elements in array
 */
void
mieeetolf(array, num)

float			*array;
int			num;

{
	for ( ; num > 0; --num, ++array) {
		ieeetolf((void *) array, array);
	}
}

/*
 *	mltoieeed
 *
 *	Function:	- change array of doubles from local to IEEE big-endian
 *	Accepts:	- ptr array
 *			- # elements in array
 */
void
mltoieeed(array, num)

double			*array;
int			num;

{
	for ( ; num > 0; --num, ++array) {
		ltoieeed(array, (void *) array);
	}
}

/*
 *	mieeetold
 *
 *	Function:	- change array of doubles from IEEE big-endian to local
 *	Accepts:	- ptr array
 *			- # elements in array
 */
void
mieeetold(array, num)

double			*array;
int			num;

{
	for ( ; num > 0; --num, ++array) {
		ieeetold((void *) array, array);
	}
}

#if LAM_SIZEOF_LONG_DOUBLE == 16
/*
 *	mieeetolld
 *
 *	Function:	- change array of long doubles from IEEE big-endian
 *			  to local
 *	Accepts:	- ptr array
 *			- # elements in array
 */
void
mieeetolld(array, num)

long double		*array;
int			num;

{
	for ( ; num > 0; --num, ++array) {
		ieeetolld((void *) array, array);
	}
}

/*
 *	mltoieeeld
 *
 *	Function:	- change array of long doubles from local
 *			  to IEEE big-endian
 *	Accepts:	- ptr array
 *			- # elements in array
 */
void
mltoieeeld(array, num)

long double		*array;
int			num;

{
	for ( ; num > 0; --num, ++array) {
		ltoieeeld(array, (void *) array);
	}
}
#endif
