162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * IEEE754 floating point
462306a36Sopenharmony_ci * common internal header file
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci/*
762306a36Sopenharmony_ci * MIPS floating point support
862306a36Sopenharmony_ci * Copyright (C) 1994-2000 Algorithmics Ltd.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#ifndef __IEEE754INT_H
1162306a36Sopenharmony_ci#define __IEEE754INT_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "ieee754.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define CLPAIR(x, y)	((x)*6+(y))
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cienum maddf_flags {
1862306a36Sopenharmony_ci	MADDF_NEGATE_PRODUCT	= 1 << 0,
1962306a36Sopenharmony_ci	MADDF_NEGATE_ADDITION	= 1 << 1,
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic inline void ieee754_clearcx(void)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	ieee754_csr.cx = 0;
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic inline void ieee754_setcx(const unsigned int flags)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	ieee754_csr.cx |= flags;
3062306a36Sopenharmony_ci	ieee754_csr.sx |= flags;
3162306a36Sopenharmony_ci}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic inline int ieee754_setandtestcx(const unsigned int x)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	ieee754_setcx(x);
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	return ieee754_csr.mx & x;
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic inline int ieee754_class_nan(int xc)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	return xc >= IEEE754_CLASS_SNAN;
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define COMPXSP \
4662306a36Sopenharmony_ci	unsigned int xm; int xe; int xs __maybe_unused; int xc
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define COMPYSP \
4962306a36Sopenharmony_ci	unsigned int ym; int ye; int ys; int yc
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define COMPZSP \
5262306a36Sopenharmony_ci	unsigned int zm; int ze; int zs; int zc
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define EXPLODESP(v, vc, vs, ve, vm)					\
5562306a36Sopenharmony_ci{									\
5662306a36Sopenharmony_ci	vs = SPSIGN(v);							\
5762306a36Sopenharmony_ci	ve = SPBEXP(v);							\
5862306a36Sopenharmony_ci	vm = SPMANT(v);							\
5962306a36Sopenharmony_ci	if (ve == SP_EMAX+1+SP_EBIAS) {					\
6062306a36Sopenharmony_ci		if (vm == 0)						\
6162306a36Sopenharmony_ci			vc = IEEE754_CLASS_INF;				\
6262306a36Sopenharmony_ci		else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
6362306a36Sopenharmony_ci			vc = IEEE754_CLASS_QNAN;			\
6462306a36Sopenharmony_ci		else							\
6562306a36Sopenharmony_ci			vc = IEEE754_CLASS_SNAN;			\
6662306a36Sopenharmony_ci	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
6762306a36Sopenharmony_ci		if (vm) {						\
6862306a36Sopenharmony_ci			ve = SP_EMIN;					\
6962306a36Sopenharmony_ci			vc = IEEE754_CLASS_DNORM;			\
7062306a36Sopenharmony_ci		} else							\
7162306a36Sopenharmony_ci			vc = IEEE754_CLASS_ZERO;			\
7262306a36Sopenharmony_ci	} else {							\
7362306a36Sopenharmony_ci		ve -= SP_EBIAS;						\
7462306a36Sopenharmony_ci		vm |= SP_HIDDEN_BIT;					\
7562306a36Sopenharmony_ci		vc = IEEE754_CLASS_NORM;				\
7662306a36Sopenharmony_ci	}								\
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
7962306a36Sopenharmony_ci#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
8062306a36Sopenharmony_ci#define EXPLODEZSP EXPLODESP(z, zc, zs, ze, zm)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#define COMPXDP \
8462306a36Sopenharmony_ci	u64 xm; int xe; int xs __maybe_unused; int xc
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#define COMPYDP \
8762306a36Sopenharmony_ci	u64 ym; int ye; int ys; int yc
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define COMPZDP \
9062306a36Sopenharmony_ci	u64 zm; int ze; int zs; int zc
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#define EXPLODEDP(v, vc, vs, ve, vm)					\
9362306a36Sopenharmony_ci{									\
9462306a36Sopenharmony_ci	vm = DPMANT(v);							\
9562306a36Sopenharmony_ci	vs = DPSIGN(v);							\
9662306a36Sopenharmony_ci	ve = DPBEXP(v);							\
9762306a36Sopenharmony_ci	if (ve == DP_EMAX+1+DP_EBIAS) {					\
9862306a36Sopenharmony_ci		if (vm == 0)						\
9962306a36Sopenharmony_ci			vc = IEEE754_CLASS_INF;				\
10062306a36Sopenharmony_ci		else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
10162306a36Sopenharmony_ci			vc = IEEE754_CLASS_QNAN;			\
10262306a36Sopenharmony_ci		else							\
10362306a36Sopenharmony_ci			vc = IEEE754_CLASS_SNAN;			\
10462306a36Sopenharmony_ci	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
10562306a36Sopenharmony_ci		if (vm) {						\
10662306a36Sopenharmony_ci			ve = DP_EMIN;					\
10762306a36Sopenharmony_ci			vc = IEEE754_CLASS_DNORM;			\
10862306a36Sopenharmony_ci		} else							\
10962306a36Sopenharmony_ci			vc = IEEE754_CLASS_ZERO;			\
11062306a36Sopenharmony_ci	} else {							\
11162306a36Sopenharmony_ci		ve -= DP_EBIAS;						\
11262306a36Sopenharmony_ci		vm |= DP_HIDDEN_BIT;					\
11362306a36Sopenharmony_ci		vc = IEEE754_CLASS_NORM;				\
11462306a36Sopenharmony_ci	}								\
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
11762306a36Sopenharmony_ci#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
11862306a36Sopenharmony_ci#define EXPLODEZDP EXPLODEDP(z, zc, zs, ze, zm)
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#define FLUSHDP(v, vc, vs, ve, vm)					\
12162306a36Sopenharmony_ci	if (vc==IEEE754_CLASS_DNORM) {					\
12262306a36Sopenharmony_ci		if (ieee754_csr.nod) {					\
12362306a36Sopenharmony_ci			ieee754_setcx(IEEE754_INEXACT);			\
12462306a36Sopenharmony_ci			vc = IEEE754_CLASS_ZERO;			\
12562306a36Sopenharmony_ci			ve = DP_EMIN-1+DP_EBIAS;			\
12662306a36Sopenharmony_ci			vm = 0;						\
12762306a36Sopenharmony_ci			v = ieee754dp_zero(vs);				\
12862306a36Sopenharmony_ci		}							\
12962306a36Sopenharmony_ci	}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci#define FLUSHSP(v, vc, vs, ve, vm)					\
13262306a36Sopenharmony_ci	if (vc==IEEE754_CLASS_DNORM) {					\
13362306a36Sopenharmony_ci		if (ieee754_csr.nod) {					\
13462306a36Sopenharmony_ci			ieee754_setcx(IEEE754_INEXACT);			\
13562306a36Sopenharmony_ci			vc = IEEE754_CLASS_ZERO;			\
13662306a36Sopenharmony_ci			ve = SP_EMIN-1+SP_EBIAS;			\
13762306a36Sopenharmony_ci			vm = 0;						\
13862306a36Sopenharmony_ci			v = ieee754sp_zero(vs);				\
13962306a36Sopenharmony_ci		}							\
14062306a36Sopenharmony_ci	}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
14362306a36Sopenharmony_ci#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
14462306a36Sopenharmony_ci#define FLUSHZDP FLUSHDP(z, zc, zs, ze, zm)
14562306a36Sopenharmony_ci#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
14662306a36Sopenharmony_ci#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
14762306a36Sopenharmony_ci#define FLUSHZSP FLUSHSP(z, zc, zs, ze, zm)
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#endif /* __IEEE754INT_H  */
150