Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/10959/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Markos Chandras and committed by
Ralf Baechle
38db37ba 400bd2e4

+138 -2
+2 -2
arch/mips/math-emu/Makefile
··· 4 4 5 5 obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ 6 6 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \ 7 - dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o \ 7 + dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o dp_2008class.o \ 8 8 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \ 9 - sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o \ 9 + sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o sp_2008class.o \ 10 10 dsemul.o 11 11 12 12 lib-y += ieee754d.o \
+24
arch/mips/math-emu/cp1emu.c
··· 1803 1803 goto copcsr; 1804 1804 } 1805 1805 1806 + case fclass_op: { 1807 + union ieee754sp fs; 1808 + 1809 + if (!cpu_has_mips_r6) 1810 + return SIGILL; 1811 + 1812 + SPFROMREG(fs, MIPSInst_FS(ir)); 1813 + rv.w = ieee754sp_2008class(fs); 1814 + rfmt = w_fmt; 1815 + break; 1816 + } 1817 + 1806 1818 case fabs_op: 1807 1819 handler.u = ieee754sp_abs; 1808 1820 goto scopuop; ··· 2071 2059 rv.l = ieee754dp_tlong(fs); 2072 2060 rv.d = ieee754dp_flong(rv.l); 2073 2061 goto copcsr; 2062 + } 2063 + 2064 + case fclass_op: { 2065 + union ieee754dp fs; 2066 + 2067 + if (!cpu_has_mips_r6) 2068 + return SIGILL; 2069 + 2070 + DPFROMREG(fs, MIPSInst_FS(ir)); 2071 + rv.w = ieee754dp_2008class(fs); 2072 + rfmt = w_fmt; 2073 + break; 2074 2074 } 2075 2075 2076 2076 case fabs_op:
+55
arch/mips/math-emu/dp_2008class.c
··· 1 + /* 2 + * IEEE754 floating point arithmetic 3 + * double precision: CLASS.f 4 + * FPR[fd] = class(FPR[fs]) 5 + * 6 + * MIPS floating point support 7 + * Copyright (C) 2015 Imagination Technologies, Ltd. 8 + * Author: Markos Chandras <markos.chandras@imgtec.com> 9 + * 10 + * This program is free software; you can distribute it and/or modify it 11 + * under the terms of the GNU General Public License as published by the 12 + * Free Software Foundation; version 2 of the License. 13 + */ 14 + 15 + #include "ieee754dp.h" 16 + 17 + int ieee754dp_2008class(union ieee754dp x) 18 + { 19 + COMPXDP; 20 + 21 + EXPLODEXDP; 22 + 23 + /* 24 + * 10 bit mask as follows: 25 + * 26 + * bit0 = SNAN 27 + * bit1 = QNAN 28 + * bit2 = -INF 29 + * bit3 = -NORM 30 + * bit4 = -DNORM 31 + * bit5 = -ZERO 32 + * bit6 = INF 33 + * bit7 = NORM 34 + * bit8 = DNORM 35 + * bit9 = ZERO 36 + */ 37 + 38 + switch(xc) { 39 + case IEEE754_CLASS_SNAN: 40 + return 0x01; 41 + case IEEE754_CLASS_QNAN: 42 + return 0x02; 43 + case IEEE754_CLASS_INF: 44 + return 0x04 << (xs ? 0 : 4); 45 + case IEEE754_CLASS_NORM: 46 + return 0x08 << (xs ? 0 : 4); 47 + case IEEE754_CLASS_DNORM: 48 + return 0x10 << (xs ? 0 : 4); 49 + case IEEE754_CLASS_ZERO: 50 + return 0x20 << (xs ? 0 : 4); 51 + default: 52 + pr_err("Unknown class: %d\n", xc); 53 + return 0; 54 + } 55 + }
+2
arch/mips/math-emu/ieee754.h
··· 79 79 union ieee754sp y); 80 80 union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, 81 81 union ieee754sp y); 82 + int ieee754sp_2008class(union ieee754sp x); 82 83 83 84 /* 84 85 * double precision (often aka double) ··· 109 108 union ieee754dp y); 110 109 union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, 111 110 union ieee754dp y); 111 + int ieee754dp_2008class(union ieee754dp x); 112 112 113 113 114 114 /* 5 types of floating point number
+55
arch/mips/math-emu/sp_2008class.c
··· 1 + /* 2 + * IEEE754 floating point arithmetic 3 + * single precision: CLASS.f 4 + * FPR[fd] = class(FPR[fs]) 5 + * 6 + * MIPS floating point support 7 + * Copyright (C) 2015 Imagination Technologies, Ltd. 8 + * Author: Markos Chandras <markos.chandras@imgtec.com> 9 + * 10 + * This program is free software; you can distribute it and/or modify it 11 + * under the terms of the GNU General Public License as published by the 12 + * Free Software Foundation; version 2 of the License. 13 + */ 14 + 15 + #include "ieee754sp.h" 16 + 17 + int ieee754sp_2008class(union ieee754sp x) 18 + { 19 + COMPXSP; 20 + 21 + EXPLODEXSP; 22 + 23 + /* 24 + * 10 bit mask as follows: 25 + * 26 + * bit0 = SNAN 27 + * bit1 = QNAN 28 + * bit2 = -INF 29 + * bit3 = -NORM 30 + * bit4 = -DNORM 31 + * bit5 = -ZERO 32 + * bit6 = INF 33 + * bit7 = NORM 34 + * bit8 = DNORM 35 + * bit9 = ZERO 36 + */ 37 + 38 + switch(xc) { 39 + case IEEE754_CLASS_SNAN: 40 + return 0x01; 41 + case IEEE754_CLASS_QNAN: 42 + return 0x02; 43 + case IEEE754_CLASS_INF: 44 + return 0x04 << (xs ? 0 : 4); 45 + case IEEE754_CLASS_NORM: 46 + return 0x08 << (xs ? 0 : 4); 47 + case IEEE754_CLASS_DNORM: 48 + return 0x10 << (xs ? 0 : 4); 49 + case IEEE754_CLASS_ZERO: 50 + return 0x20 << (xs ? 0 : 4); 51 + default: 52 + pr_err("Unknown class: %d\n", xc); 53 + return 0; 54 + } 55 + }