18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Linux/PA-RISC Project (http://www.parisc-linux.org/)
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Floating-point emulation code
68c2ecf20Sopenharmony_ci *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * BEGIN_DESC
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci *  File:
128c2ecf20Sopenharmony_ci *	@(#)	pa/fp/denormal.c		$ Revision: $
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *  Purpose:
158c2ecf20Sopenharmony_ci *	<<please update with a synopsis of the functionality provided by this file>>
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci *  External Interfaces:
188c2ecf20Sopenharmony_ci *	<<the following list was autogenerated, please review>>
198c2ecf20Sopenharmony_ci *	dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
208c2ecf20Sopenharmony_ci *	sgl_denormalize(sgl_opnd,inexactflag,rmode)
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci *  Internal Interfaces:
238c2ecf20Sopenharmony_ci *	<<please update>>
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci *  Theory:
268c2ecf20Sopenharmony_ci *	<<please update with a overview of the operation of this file>>
278c2ecf20Sopenharmony_ci *
288c2ecf20Sopenharmony_ci * END_DESC
298c2ecf20Sopenharmony_ci*/
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#include "float.h"
348c2ecf20Sopenharmony_ci#include "sgl_float.h"
358c2ecf20Sopenharmony_ci#include "dbl_float.h"
368c2ecf20Sopenharmony_ci#include "hppa.h"
378c2ecf20Sopenharmony_ci#include <linux/kernel.h>
388c2ecf20Sopenharmony_ci/* #include <machine/sys/mdep_private.h> */
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#undef Fpustatus_register
418c2ecf20Sopenharmony_ci#define Fpustatus_register Fpu_register[0]
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_civoid
448c2ecf20Sopenharmony_cisgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
458c2ecf20Sopenharmony_ci{
468c2ecf20Sopenharmony_ci	unsigned int opnd;
478c2ecf20Sopenharmony_ci	int sign, exponent;
488c2ecf20Sopenharmony_ci	boolean guardbit = FALSE, stickybit, inexact;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	opnd = *sgl_opnd;
518c2ecf20Sopenharmony_ci	stickybit = *inexactflag;
528c2ecf20Sopenharmony_ci        exponent = Sgl_exponent(opnd) - SGL_WRAP;
538c2ecf20Sopenharmony_ci        sign = Sgl_sign(opnd);
548c2ecf20Sopenharmony_ci	Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
558c2ecf20Sopenharmony_ci	if (inexact) {
568c2ecf20Sopenharmony_ci	    switch (rmode) {
578c2ecf20Sopenharmony_ci	      case ROUNDPLUS:
588c2ecf20Sopenharmony_ci		if (sign == 0) {
598c2ecf20Sopenharmony_ci			Sgl_increment(opnd);
608c2ecf20Sopenharmony_ci		}
618c2ecf20Sopenharmony_ci		break;
628c2ecf20Sopenharmony_ci	      case ROUNDMINUS:
638c2ecf20Sopenharmony_ci		if (sign != 0) {
648c2ecf20Sopenharmony_ci			Sgl_increment(opnd);
658c2ecf20Sopenharmony_ci		}
668c2ecf20Sopenharmony_ci		break;
678c2ecf20Sopenharmony_ci	      case ROUNDNEAREST:
688c2ecf20Sopenharmony_ci		if (guardbit && (stickybit ||
698c2ecf20Sopenharmony_ci		       Sgl_isone_lowmantissa(opnd))) {
708c2ecf20Sopenharmony_ci			   Sgl_increment(opnd);
718c2ecf20Sopenharmony_ci		}
728c2ecf20Sopenharmony_ci		break;
738c2ecf20Sopenharmony_ci	    }
748c2ecf20Sopenharmony_ci	}
758c2ecf20Sopenharmony_ci	Sgl_set_sign(opnd,sign);
768c2ecf20Sopenharmony_ci	*sgl_opnd = opnd;
778c2ecf20Sopenharmony_ci	*inexactflag = inexact;
788c2ecf20Sopenharmony_ci	return;
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_civoid
828c2ecf20Sopenharmony_cidbl_denormalize(unsigned int *dbl_opndp1,
838c2ecf20Sopenharmony_ci	unsigned int * dbl_opndp2,
848c2ecf20Sopenharmony_ci	boolean *inexactflag,
858c2ecf20Sopenharmony_ci	int rmode)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	unsigned int opndp1, opndp2;
888c2ecf20Sopenharmony_ci	int sign, exponent;
898c2ecf20Sopenharmony_ci	boolean guardbit = FALSE, stickybit, inexact;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	opndp1 = *dbl_opndp1;
928c2ecf20Sopenharmony_ci	opndp2 = *dbl_opndp2;
938c2ecf20Sopenharmony_ci	stickybit = *inexactflag;
948c2ecf20Sopenharmony_ci	exponent = Dbl_exponent(opndp1) - DBL_WRAP;
958c2ecf20Sopenharmony_ci	sign = Dbl_sign(opndp1);
968c2ecf20Sopenharmony_ci	Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
978c2ecf20Sopenharmony_ci	if (inexact) {
988c2ecf20Sopenharmony_ci	    switch (rmode) {
998c2ecf20Sopenharmony_ci	      case ROUNDPLUS:
1008c2ecf20Sopenharmony_ci		if (sign == 0) {
1018c2ecf20Sopenharmony_ci			Dbl_increment(opndp1,opndp2);
1028c2ecf20Sopenharmony_ci		}
1038c2ecf20Sopenharmony_ci		break;
1048c2ecf20Sopenharmony_ci	      case ROUNDMINUS:
1058c2ecf20Sopenharmony_ci		if (sign != 0) {
1068c2ecf20Sopenharmony_ci			Dbl_increment(opndp1,opndp2);
1078c2ecf20Sopenharmony_ci		}
1088c2ecf20Sopenharmony_ci		break;
1098c2ecf20Sopenharmony_ci	      case ROUNDNEAREST:
1108c2ecf20Sopenharmony_ci		if (guardbit && (stickybit ||
1118c2ecf20Sopenharmony_ci		       Dbl_isone_lowmantissap2(opndp2))) {
1128c2ecf20Sopenharmony_ci			   Dbl_increment(opndp1,opndp2);
1138c2ecf20Sopenharmony_ci		}
1148c2ecf20Sopenharmony_ci		break;
1158c2ecf20Sopenharmony_ci	    }
1168c2ecf20Sopenharmony_ci	}
1178c2ecf20Sopenharmony_ci	Dbl_set_sign(opndp1,sign);
1188c2ecf20Sopenharmony_ci	*dbl_opndp1 = opndp1;
1198c2ecf20Sopenharmony_ci	*dbl_opndp2 = opndp2;
1208c2ecf20Sopenharmony_ci	*inexactflag = inexact;
1218c2ecf20Sopenharmony_ci	return;
1228c2ecf20Sopenharmony_ci}
123