diff options
author | Markos Chandras <markos.chandras@imgtec.com> | 2015-08-13 03:56:34 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-09-03 06:08:14 -0400 |
commit | 38db37ba069f9d801ef56b820cfc7c247a7ffc02 (patch) | |
tree | 9a053440a3afabd7f7f19bcc65a9cd9d0735f028 | |
parent | 400bd2e41393a783e0532321fdb369d2cc15ea26 (diff) |
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>
-rw-r--r-- | arch/mips/math-emu/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 24 | ||||
-rw-r--r-- | arch/mips/math-emu/dp_2008class.c | 55 | ||||
-rw-r--r-- | arch/mips/math-emu/ieee754.h | 2 | ||||
-rw-r--r-- | arch/mips/math-emu/sp_2008class.c | 55 |
5 files changed, 138 insertions, 2 deletions
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile index 0037690521ee..ea8db2607d07 100644 --- a/arch/mips/math-emu/Makefile +++ b/arch/mips/math-emu/Makefile | |||
@@ -4,9 +4,9 @@ | |||
4 | 4 | ||
5 | obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ | 5 | obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ |
6 | dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \ | 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 | sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \ | 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 | dsemul.o | 10 | dsemul.o |
11 | 11 | ||
12 | lib-y += ieee754d.o \ | 12 | lib-y += ieee754d.o \ |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index a348cbefe4a8..b65b4ea60232 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -1803,6 +1803,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1803 | goto copcsr; | 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 | case fabs_op: | 1818 | case fabs_op: |
1807 | handler.u = ieee754sp_abs; | 1819 | handler.u = ieee754sp_abs; |
1808 | goto scopuop; | 1820 | goto scopuop; |
@@ -2061,6 +2073,18 @@ copcsr: | |||
2061 | goto copcsr; | 2073 | goto copcsr; |
2062 | } | 2074 | } |
2063 | 2075 | ||
2076 | case fclass_op: { | ||
2077 | union ieee754dp fs; | ||
2078 | |||
2079 | if (!cpu_has_mips_r6) | ||
2080 | return SIGILL; | ||
2081 | |||
2082 | DPFROMREG(fs, MIPSInst_FS(ir)); | ||
2083 | rv.w = ieee754dp_2008class(fs); | ||
2084 | rfmt = w_fmt; | ||
2085 | break; | ||
2086 | } | ||
2087 | |||
2064 | case fabs_op: | 2088 | case fabs_op: |
2065 | handler.u = ieee754dp_abs; | 2089 | handler.u = ieee754dp_abs; |
2066 | goto dcopuop; | 2090 | goto dcopuop; |
diff --git a/arch/mips/math-emu/dp_2008class.c b/arch/mips/math-emu/dp_2008class.c new file mode 100644 index 000000000000..9dc39fc4835e --- /dev/null +++ b/arch/mips/math-emu/dp_2008class.c | |||
@@ -0,0 +1,55 @@ | |||
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 | } | ||
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h index 8c780190a059..3b833eac48f5 100644 --- a/arch/mips/math-emu/ieee754.h +++ b/arch/mips/math-emu/ieee754.h | |||
@@ -79,6 +79,7 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
79 | union ieee754sp y); | 79 | union ieee754sp y); |
80 | union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, | 80 | union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, |
81 | union ieee754sp y); | 81 | union ieee754sp y); |
82 | int ieee754sp_2008class(union ieee754sp x); | ||
82 | 83 | ||
83 | /* | 84 | /* |
84 | * double precision (often aka double) | 85 | * double precision (often aka double) |
@@ -108,6 +109,7 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
108 | union ieee754dp y); | 109 | union ieee754dp y); |
109 | union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, | 110 | union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, |
110 | union ieee754dp y); | 111 | union ieee754dp y); |
112 | int ieee754dp_2008class(union ieee754dp x); | ||
111 | 113 | ||
112 | 114 | ||
113 | /* 5 types of floating point number | 115 | /* 5 types of floating point number |
diff --git a/arch/mips/math-emu/sp_2008class.c b/arch/mips/math-emu/sp_2008class.c new file mode 100644 index 000000000000..ff62606a1465 --- /dev/null +++ b/arch/mips/math-emu/sp_2008class.c | |||
@@ -0,0 +1,55 @@ | |||
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 | } | ||