1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * IEEE754 floating point
4 * common internal header file
5 */
6/*
7 * MIPS floating point support
8 * Copyright (C) 1994-2000 Algorithmics Ltd.
9 */
10#ifndef __IEEE754INT_H
11#define __IEEE754INT_H
12
13#include "ieee754.h"
14
15#define CLPAIR(x, y)	((x)*6+(y))
16
17enum maddf_flags {
18	MADDF_NEGATE_PRODUCT	= 1 << 0,
19	MADDF_NEGATE_ADDITION	= 1 << 1,
20};
21
22static inline void ieee754_clearcx(void)
23{
24	ieee754_csr.cx = 0;
25}
26
27static inline void ieee754_setcx(const unsigned int flags)
28{
29	ieee754_csr.cx |= flags;
30	ieee754_csr.sx |= flags;
31}
32
33static inline int ieee754_setandtestcx(const unsigned int x)
34{
35	ieee754_setcx(x);
36
37	return ieee754_csr.mx & x;
38}
39
40static inline int ieee754_class_nan(int xc)
41{
42	return xc >= IEEE754_CLASS_SNAN;
43}
44
45#define COMPXSP \
46	unsigned int xm; int xe; int xs __maybe_unused; int xc
47
48#define COMPYSP \
49	unsigned int ym; int ye; int ys; int yc
50
51#define COMPZSP \
52	unsigned int zm; int ze; int zs; int zc
53
54#define EXPLODESP(v, vc, vs, ve, vm)					\
55{									\
56	vs = SPSIGN(v);							\
57	ve = SPBEXP(v);							\
58	vm = SPMANT(v);							\
59	if (ve == SP_EMAX+1+SP_EBIAS) {					\
60		if (vm == 0)						\
61			vc = IEEE754_CLASS_INF;				\
62		else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
63			vc = IEEE754_CLASS_QNAN;			\
64		else							\
65			vc = IEEE754_CLASS_SNAN;			\
66	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
67		if (vm) {						\
68			ve = SP_EMIN;					\
69			vc = IEEE754_CLASS_DNORM;			\
70		} else							\
71			vc = IEEE754_CLASS_ZERO;			\
72	} else {							\
73		ve -= SP_EBIAS;						\
74		vm |= SP_HIDDEN_BIT;					\
75		vc = IEEE754_CLASS_NORM;				\
76	}								\
77}
78#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
79#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
80#define EXPLODEZSP EXPLODESP(z, zc, zs, ze, zm)
81
82
83#define COMPXDP \
84	u64 xm; int xe; int xs __maybe_unused; int xc
85
86#define COMPYDP \
87	u64 ym; int ye; int ys; int yc
88
89#define COMPZDP \
90	u64 zm; int ze; int zs; int zc
91
92#define EXPLODEDP(v, vc, vs, ve, vm)					\
93{									\
94	vm = DPMANT(v);							\
95	vs = DPSIGN(v);							\
96	ve = DPBEXP(v);							\
97	if (ve == DP_EMAX+1+DP_EBIAS) {					\
98		if (vm == 0)						\
99			vc = IEEE754_CLASS_INF;				\
100		else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
101			vc = IEEE754_CLASS_QNAN;			\
102		else							\
103			vc = IEEE754_CLASS_SNAN;			\
104	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
105		if (vm) {						\
106			ve = DP_EMIN;					\
107			vc = IEEE754_CLASS_DNORM;			\
108		} else							\
109			vc = IEEE754_CLASS_ZERO;			\
110	} else {							\
111		ve -= DP_EBIAS;						\
112		vm |= DP_HIDDEN_BIT;					\
113		vc = IEEE754_CLASS_NORM;				\
114	}								\
115}
116#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
117#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
118#define EXPLODEZDP EXPLODEDP(z, zc, zs, ze, zm)
119
120#define FLUSHDP(v, vc, vs, ve, vm)					\
121	if (vc==IEEE754_CLASS_DNORM) {					\
122		if (ieee754_csr.nod) {					\
123			ieee754_setcx(IEEE754_INEXACT);			\
124			vc = IEEE754_CLASS_ZERO;			\
125			ve = DP_EMIN-1+DP_EBIAS;			\
126			vm = 0;						\
127			v = ieee754dp_zero(vs);				\
128		}							\
129	}
130
131#define FLUSHSP(v, vc, vs, ve, vm)					\
132	if (vc==IEEE754_CLASS_DNORM) {					\
133		if (ieee754_csr.nod) {					\
134			ieee754_setcx(IEEE754_INEXACT);			\
135			vc = IEEE754_CLASS_ZERO;			\
136			ve = SP_EMIN-1+SP_EBIAS;			\
137			vm = 0;						\
138			v = ieee754sp_zero(vs);				\
139		}							\
140	}
141
142#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
143#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
144#define FLUSHZDP FLUSHDP(z, zc, zs, ze, zm)
145#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
146#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
147#define FLUSHZSP FLUSHSP(z, zc, zs, ze, zm)
148
149#endif /* __IEEE754INT_H  */
150