Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38db37ba authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: math-emu: Add support for the MIPS R6 CLASS FPU instruction



MIPS R6 introduced the following instruction:
Stores in fd a bit mask reflecting the floating-point class of the
floating point scalar value fs.

CLASS.fmt: FPR[fd] = class(FPR[fs])

Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/10959/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 400bd2e4
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -4,9 +4,9 @@


obj-y	+= cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
obj-y	+= cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
	   dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \
	   dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \
	   dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o \
	   dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o dp_2008class.o \
	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \
	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \
	   sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o \
	   sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o sp_2008class.o \
	   dsemul.o
	   dsemul.o


lib-y	+= ieee754d.o \
lib-y	+= ieee754d.o \
+24 −0
Original line number Original line Diff line number Diff line
@@ -1803,6 +1803,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
			goto copcsr;
			goto copcsr;
		}
		}


		case fclass_op: {
			union ieee754sp fs;

			if (!cpu_has_mips_r6)
				return SIGILL;

			SPFROMREG(fs, MIPSInst_FS(ir));
			rv.w = ieee754sp_2008class(fs);
			rfmt = w_fmt;
			break;
		}

		case fabs_op:
		case fabs_op:
			handler.u = ieee754sp_abs;
			handler.u = ieee754sp_abs;
			goto scopuop;
			goto scopuop;
@@ -2061,6 +2073,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
			goto copcsr;
			goto copcsr;
		}
		}


		case fclass_op: {
			union ieee754dp fs;

			if (!cpu_has_mips_r6)
				return SIGILL;

			DPFROMREG(fs, MIPSInst_FS(ir));
			rv.w = ieee754dp_2008class(fs);
			rfmt = w_fmt;
			break;
		}

		case fabs_op:
		case fabs_op:
			handler.u = ieee754dp_abs;
			handler.u = ieee754dp_abs;
			goto dcopuop;
			goto dcopuop;
+55 −0
Original line number Original line Diff line number Diff line
/*
 * IEEE754 floating point arithmetic
 * double precision: CLASS.f
 * FPR[fd] = class(FPR[fs])
 *
 * MIPS floating point support
 * Copyright (C) 2015 Imagination Technologies, Ltd.
 * Author: Markos Chandras <markos.chandras@imgtec.com>
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; version 2 of the License.
 */

#include "ieee754dp.h"

int ieee754dp_2008class(union ieee754dp x)
{
	COMPXDP;

	EXPLODEXDP;

	/*
	 * 10 bit mask as follows:
	 *
	 * bit0 = SNAN
	 * bit1 = QNAN
	 * bit2 = -INF
	 * bit3 = -NORM
	 * bit4 = -DNORM
	 * bit5 = -ZERO
	 * bit6 = INF
	 * bit7 = NORM
	 * bit8 = DNORM
	 * bit9 = ZERO
	 */

	switch(xc) {
	case IEEE754_CLASS_SNAN:
		return 0x01;
	case IEEE754_CLASS_QNAN:
		return 0x02;
	case IEEE754_CLASS_INF:
		return 0x04 << (xs ? 0 : 4);
	case IEEE754_CLASS_NORM:
		return 0x08 << (xs ? 0 : 4);
	case IEEE754_CLASS_DNORM:
		return 0x10 << (xs ? 0 : 4);
	case IEEE754_CLASS_ZERO:
		return 0x20 << (xs ? 0 : 4);
	default:
		pr_err("Unknown class: %d\n", xc);
		return 0;
	}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -79,6 +79,7 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
				union ieee754sp y);
				union ieee754sp y);
union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
				union ieee754sp y);
				union ieee754sp y);
int ieee754sp_2008class(union ieee754sp x);


/*
/*
 * double precision (often aka double)
 * double precision (often aka double)
@@ -108,6 +109,7 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
				union ieee754dp y);
				union ieee754dp y);
union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
				union ieee754dp y);
				union ieee754dp y);
int ieee754dp_2008class(union ieee754dp x);




/* 5 types of floating point number
/* 5 types of floating point number
+55 −0
Original line number Original line Diff line number Diff line
/*
 * IEEE754 floating point arithmetic
 * single precision: CLASS.f
 * FPR[fd] = class(FPR[fs])
 *
 * MIPS floating point support
 * Copyright (C) 2015 Imagination Technologies, Ltd.
 * Author: Markos Chandras <markos.chandras@imgtec.com>
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; version 2 of the License.
 */

#include "ieee754sp.h"

int ieee754sp_2008class(union ieee754sp x)
{
	COMPXSP;

	EXPLODEXSP;

	/*
	 * 10 bit mask as follows:
	 *
	 * bit0 = SNAN
	 * bit1 = QNAN
	 * bit2 = -INF
	 * bit3 = -NORM
	 * bit4 = -DNORM
	 * bit5 = -ZERO
	 * bit6 = INF
	 * bit7 = NORM
	 * bit8 = DNORM
	 * bit9 = ZERO
	 */

	switch(xc) {
	case IEEE754_CLASS_SNAN:
		return 0x01;
	case IEEE754_CLASS_QNAN:
		return 0x02;
	case IEEE754_CLASS_INF:
		return 0x04 << (xs ? 0 : 4);
	case IEEE754_CLASS_NORM:
		return 0x08 << (xs ? 0 : 4);
	case IEEE754_CLASS_DNORM:
		return 0x10 << (xs ? 0 : 4);
	case IEEE754_CLASS_ZERO:
		return 0x20 << (xs ? 0 : 4);
	default:
		pr_err("Unknown class: %d\n", xc);
		return 0;
	}
}