cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

denormal.c (2646B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
      4 *
      5 * Floating-point emulation code
      6 *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
      7 */
      8/*
      9 * BEGIN_DESC
     10 *
     11 *  File:
     12 *	@(#)	pa/fp/denormal.c		$ Revision: $
     13 *
     14 *  Purpose:
     15 *	<<please update with a synopsis of the functionality provided by this file>>
     16 *
     17 *  External Interfaces:
     18 *	<<the following list was autogenerated, please review>>
     19 *	dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
     20 *	sgl_denormalize(sgl_opnd,inexactflag,rmode)
     21 *
     22 *  Internal Interfaces:
     23 *	<<please update>>
     24 *
     25 *  Theory:
     26 *	<<please update with a overview of the operation of this file>>
     27 *
     28 * END_DESC
     29*/
     30
     31
     32
     33#include "float.h"
     34#include "sgl_float.h"
     35#include "dbl_float.h"
     36#include "hppa.h"
     37#include <linux/kernel.h>
     38/* #include <machine/sys/mdep_private.h> */
     39
     40#undef Fpustatus_register
     41#define Fpustatus_register Fpu_register[0]
     42
     43void
     44sgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
     45{
     46	unsigned int opnd;
     47	int sign, exponent;
     48	boolean guardbit = FALSE, stickybit, inexact;
     49
     50	opnd = *sgl_opnd;
     51	stickybit = *inexactflag;
     52        exponent = Sgl_exponent(opnd) - SGL_WRAP;
     53        sign = Sgl_sign(opnd);
     54	Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
     55	if (inexact) {
     56	    switch (rmode) {
     57	      case ROUNDPLUS:
     58		if (sign == 0) {
     59			Sgl_increment(opnd);
     60		}
     61		break;
     62	      case ROUNDMINUS:
     63		if (sign != 0) {
     64			Sgl_increment(opnd);
     65		}
     66		break;
     67	      case ROUNDNEAREST:
     68		if (guardbit && (stickybit || 
     69		       Sgl_isone_lowmantissa(opnd))) {
     70			   Sgl_increment(opnd);
     71		}
     72		break;
     73	    }
     74	}
     75	Sgl_set_sign(opnd,sign);
     76	*sgl_opnd = opnd;
     77	*inexactflag = inexact;
     78	return;
     79}
     80
     81void
     82dbl_denormalize(unsigned int *dbl_opndp1,
     83	unsigned int * dbl_opndp2,
     84	boolean *inexactflag,
     85	int rmode)
     86{
     87	unsigned int opndp1, opndp2;
     88	int sign, exponent;
     89	boolean guardbit = FALSE, stickybit, inexact;
     90
     91	opndp1 = *dbl_opndp1;
     92	opndp2 = *dbl_opndp2;
     93	stickybit = *inexactflag;
     94	exponent = Dbl_exponent(opndp1) - DBL_WRAP;
     95	sign = Dbl_sign(opndp1);
     96	Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
     97	if (inexact) {
     98	    switch (rmode) {
     99	      case ROUNDPLUS:
    100		if (sign == 0) {
    101			Dbl_increment(opndp1,opndp2);
    102		}
    103		break;
    104	      case ROUNDMINUS:
    105		if (sign != 0) {
    106			Dbl_increment(opndp1,opndp2);
    107		}
    108		break;
    109	      case ROUNDNEAREST:
    110		if (guardbit && (stickybit || 
    111		       Dbl_isone_lowmantissap2(opndp2))) {
    112			   Dbl_increment(opndp1,opndp2);
    113		}
    114		break;
    115	    }
    116	}
    117	Dbl_set_sign(opndp1,sign);
    118	*dbl_opndp1 = opndp1;
    119	*dbl_opndp2 = opndp2;
    120	*inexactflag = inexact;
    121	return;
    122}