11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IEEE754 floating point
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * common internal header file
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MIPS floating point support
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1994-2000 Algorithmics Ltd.
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  This program is free software; you can distribute it and/or modify it
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  under the terms of the GNU General Public License (Version 2) as
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  published by the Free Software Foundation.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  This program is distributed in the hope it will be useful, but WITHOUT
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  for more details.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  You should have received a copy of the GNU General Public License along
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  with this program; if not, write to the Free Software Foundation, Inc.,
203f7cac416b5e62d37aa693538729c6c23e9b938bRalf Baechle *  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
22bee1653593b39ac85b45a057bb8c22dc1489cf6aRalf Baechle#ifndef __IEEE754INT_H
23bee1653593b39ac85b45a057bb8c22dc1489cf6aRalf Baechle#define __IEEE754INT_H
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ieee754.h"
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2721a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define CLPAIR(x, y)	((x)*6+(y))
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
299e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechlestatic inline void ieee754_clearcx(void)
309e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle{
319e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle	ieee754_csr.cx = 0;
329e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle}
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
349e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechlestatic inline void ieee754_setcx(const unsigned int flags)
359e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle{
369e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle	ieee754_csr.cx |= flags;
379e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle	ieee754_csr.sx |= flags;
389e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle}
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
409e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechlestatic inline int ieee754_setandtestcx(const unsigned int x)
419e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle{
429e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle	ieee754_setcx(x);
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
449e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle	return ieee754_csr.mx & x;
459e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle}
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COMPXSP \
4847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	unsigned xm; int xe; int xs __maybe_unused; int xc
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COMPYSP \
5147fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	unsigned ym; int ye; int ys; int yc
5247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle
5347fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle#define EXPLODESP(v, vc, vs, ve, vm)					\
5447fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle{									\
5547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	vs = SPSIGN(v);							\
5647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	ve = SPBEXP(v);							\
5747fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	vm = SPMANT(v);							\
5847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	if (ve == SP_EMAX+1+SP_EBIAS) {					\
5947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		if (vm == 0)						\
6047fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_INF;				\
61ad8fb5537a7747187e92434dc096d3914472b51bRalf Baechle		else if (vm & SP_MBIT(SP_FBITS-1))			\
6247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_SNAN;			\
6347fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	else								\
6447fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		vc = IEEE754_CLASS_QNAN;				\
6547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
6647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		if (vm) {						\
6747fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			ve = SP_EMIN;					\
6847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_DNORM;			\
6947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		} else							\
7047fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_ZERO;			\
7147fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	} else {							\
7247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		ve -= SP_EBIAS;						\
7347fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		vm |= SP_HIDDEN_BIT;					\
7447fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		vc = IEEE754_CLASS_NORM;				\
7547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	}								\
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7721a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
7821a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COMPXDP \
8247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	u64 xm; int xe; int xs __maybe_unused; int xc
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COMPYDP \
8547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	u64 ym; int ye; int ys; int yc
8647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle
8747fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle#define EXPLODEDP(v, vc, vs, ve, vm)					\
8847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle{									\
8947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	vm = DPMANT(v);							\
9047fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	vs = DPSIGN(v);							\
9147fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	ve = DPBEXP(v);							\
9247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	if (ve == DP_EMAX+1+DP_EBIAS) {					\
9347fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		if (vm == 0)						\
9447fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_INF;				\
95ad8fb5537a7747187e92434dc096d3914472b51bRalf Baechle		else if (vm & DP_MBIT(DP_FBITS-1))			\
9647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_SNAN;			\
9747fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		else							\
9847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_QNAN;			\
9947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
10047fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		if (vm) {						\
10147fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			ve = DP_EMIN;					\
10247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_DNORM;			\
10347fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	} else								\
10447fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		vc = IEEE754_CLASS_ZERO;				\
10547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	} else {							\
10647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		ve -= DP_EBIAS;						\
10747fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		vm |= DP_HIDDEN_BIT;					\
10847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		vc = IEEE754_CLASS_NORM;				\
10947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	}								\
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11121a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
11221a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11447fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle#define FLUSHDP(v, vc, vs, ve, vm)					\
11547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	if (vc==IEEE754_CLASS_DNORM) {					\
11647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		if (ieee754_csr.nod) {					\
1179e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle			ieee754_setcx(IEEE754_INEXACT);			\
11847fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_ZERO;			\
11947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			ve = DP_EMIN-1+DP_EBIAS;			\
12047fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vm = 0;						\
12147fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			v = ieee754dp_zero(vs);				\
12247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		}							\
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12547fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle#define FLUSHSP(v, vc, vs, ve, vm)					\
12647fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle	if (vc==IEEE754_CLASS_DNORM) {					\
12747fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		if (ieee754_csr.nod) {					\
1289e8bad1f9c0370b2635175b34d6151b90a53da5cRalf Baechle			ieee754_setcx(IEEE754_INEXACT);			\
12947fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vc = IEEE754_CLASS_ZERO;			\
13047fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			ve = SP_EMIN-1+SP_EBIAS;			\
13147fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			vm = 0;						\
13247fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle			v = ieee754sp_zero(vs);				\
13347fa0c0251413db66a9018fbac6f6266201195aeRalf Baechle		}							\
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13621a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
13721a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
13821a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
13921a151d8ca3aa74ee79f9791a9d4dc370d3e0636Ralf Baechle#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
140bee1653593b39ac85b45a057bb8c22dc1489cf6aRalf Baechle
141bee1653593b39ac85b45a057bb8c22dc1489cf6aRalf Baechle#endif /* __IEEE754INT_H  */
142