* [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates
@ 2015-04-03 22:23 Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 01/48] doc: kernel-parameters.txt: Mark `nofpu' for MIPS too Maciej W. Rozycki
` (46 more replies)
0 siblings, 47 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:23 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Hi,
These are fixes to address code structuring and coding style problems
and then bug fixes I discovered in the course of implementing an
upcoming FPU feature. There are some minor feature updates too. They
are related to one another to a various extent, sometimes very loosely,
but I decided to keep them as a series because there is a lot of
syntactical overlap, as changes are made in steps, one issue at a time.
Keeping them in order guarantees that they apply on top of one another.
Clean-ups come first as they should be completely uncontroversial,
followed by restructuring, bug fixes and new features.
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 01/48] doc: kernel-parameters.txt: Mark `nofpu' for MIPS too
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
@ 2015-04-03 22:23 ` Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 02/48] MIPS: mipsregs.h: Remove broken comments Maciej W. Rozycki
` (45 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:23 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
The MIPS port has supported this option since forever, long before SH
was even in plans.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-nofpu.diff
Index: linux/Documentation/kernel-parameters.txt
===================================================================
--- linux.orig/Documentation/kernel-parameters.txt 2015-04-02 20:27:51.263153000 +0100
+++ linux/Documentation/kernel-parameters.txt 2015-04-02 20:27:51.477157000 +0100
@@ -2321,7 +2321,7 @@ bytes respectively. Such letter suffixes
noexec32=off: disable non-executable mappings
read implies executable mappings
- nofpu [SH] Disable hardware FPU at boot time.
+ nofpu [MIPS,SH] Disable hardware FPU at boot time.
nofxsr [BUGS=X86-32] Disables x86 floating point extended
register save and restore. The kernel will only save
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 02/48] MIPS: mipsregs.h: Remove broken comments
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 01/48] doc: kernel-parameters.txt: Mark `nofpu' for MIPS too Maciej W. Rozycki
@ 2015-04-03 22:23 ` Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 03/48] MIPS: mipsregs.h: Reorder CP1 macro definitions Maciej W. Rozycki
` (44 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:23 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Remove a duplicate FPU Status Register reference that has been there
since forever and a mistakenly copied and pasted R4xx0 manual reference.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-regs-fcsr-comment.diff
Index: linux/arch/mips/include/asm/mipsregs.h
===================================================================
--- linux.orig/arch/mips/include/asm/mipsregs.h 2015-04-02 20:18:53.073537000 +0100
+++ linux/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:51.667161000 +0100
@@ -120,10 +120,6 @@
/*
* FPU Status Register Values
*/
-/*
- * Status Register Values
- */
-
#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
#define FPU_CSR_COND 0x00800000 /* $fcc0 */
#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
@@ -425,8 +421,6 @@
/*
* Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2)
- *
- * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
*/
#define INTCTLB_IPPCI 26
#define INTCTLF_IPPCI (_ULCAST_(7) << INTCTLB_IPPCI)
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 03/48] MIPS: mipsregs.h: Reorder CP1 macro definitions
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 01/48] doc: kernel-parameters.txt: Mark `nofpu' for MIPS too Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 02/48] MIPS: mipsregs.h: Remove broken comments Maciej W. Rozycki
@ 2015-04-03 22:23 ` Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 04/48] MIPS: mipsregs.h: Move TX39 macros out of the way Maciej W. Rozycki
` (43 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:23 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Originally CP1 macros were placed between CP0 register name macros and
CP0 register value macros. As changes were applied to the header the
position of CP1 macros gradually has become more and more arbitrary and
two separate blocks were created. This may only cause confusion.
Move them out of the way then and place together after all the CP0
macros. No semantic change.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
Ralf,
FYI, checkpatch.pl has bogus issues with this change:
ERROR: Macros with complex values should be enclosed in parentheses
#99: FILE: arch/mips/include/asm/mipsregs.h:680:
+#define CP1_REVISION $0
ERROR: Macros with complex values should be enclosed in parentheses
#100: FILE: arch/mips/include/asm/mipsregs.h:681:
+#define CP1_STATUS $31
I hope that's not going to disturb your patch handling flow.
Maciej
linux-mips-regs-cp1.diff
Index: linux/arch/mips/include/asm/mipsregs.h
===================================================================
--- linux.orig/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:51.667161000 +0100
+++ linux/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:51.855157000 +0100
@@ -111,66 +111,6 @@
*/
#define CP0_TX39_CACHE $7
-/*
- * Coprocessor 1 (FPU) register names
- */
-#define CP1_REVISION $0
-#define CP1_STATUS $31
-
-/*
- * FPU Status Register Values
- */
-#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
-#define FPU_CSR_COND 0x00800000 /* $fcc0 */
-#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
-#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
-#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
-#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
-#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
-#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
-#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
-#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
-
-/*
- * Bits 18 - 20 of the FPU Status Register will be read as 0,
- * and should be written as zero.
- */
-#define FPU_CSR_RSVD 0x001c0000
-
-/*
- * X the exception cause indicator
- * E the exception enable
- * S the sticky/flag bit
-*/
-#define FPU_CSR_ALL_X 0x0003f000
-#define FPU_CSR_UNI_X 0x00020000
-#define FPU_CSR_INV_X 0x00010000
-#define FPU_CSR_DIV_X 0x00008000
-#define FPU_CSR_OVF_X 0x00004000
-#define FPU_CSR_UDF_X 0x00002000
-#define FPU_CSR_INE_X 0x00001000
-
-#define FPU_CSR_ALL_E 0x00000f80
-#define FPU_CSR_INV_E 0x00000800
-#define FPU_CSR_DIV_E 0x00000400
-#define FPU_CSR_OVF_E 0x00000200
-#define FPU_CSR_UDF_E 0x00000100
-#define FPU_CSR_INE_E 0x00000080
-
-#define FPU_CSR_ALL_S 0x0000007c
-#define FPU_CSR_INV_S 0x00000040
-#define FPU_CSR_DIV_S 0x00000020
-#define FPU_CSR_OVF_S 0x00000010
-#define FPU_CSR_UDF_S 0x00000008
-#define FPU_CSR_INE_S 0x00000004
-
-/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
-#define FPU_CSR_RM 0x00000003
-#define FPU_CSR_RN 0x0 /* nearest */
-#define FPU_CSR_RZ 0x1 /* towards zero */
-#define FPU_CSR_RU 0x2 /* towards +Infinity */
-#define FPU_CSR_RD 0x3 /* towards -Infinity */
-
/*
* Values for PageMask register
@@ -683,18 +623,6 @@
#define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
/*
- * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
- */
-#define MIPS_FPIR_S (_ULCAST_(1) << 16)
-#define MIPS_FPIR_D (_ULCAST_(1) << 17)
-#define MIPS_FPIR_PS (_ULCAST_(1) << 18)
-#define MIPS_FPIR_3D (_ULCAST_(1) << 19)
-#define MIPS_FPIR_W (_ULCAST_(1) << 20)
-#define MIPS_FPIR_L (_ULCAST_(1) << 21)
-#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
-#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
-
-/*
* Bits in the MIPS32 Memory Segmentation registers.
*/
#define MIPS_SEGCFG_PA_SHIFT 9
@@ -745,6 +673,81 @@
#define MIPS_PWCTL_PSN_SHIFT 0
#define MIPS_PWCTL_PSN_MASK 0x0000003f
+
+/*
+ * Coprocessor 1 (FPU) register names
+ */
+#define CP1_REVISION $0
+#define CP1_STATUS $31
+
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S (_ULCAST_(1) << 16)
+#define MIPS_FPIR_D (_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS (_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D (_ULCAST_(1) << 19)
+#define MIPS_FPIR_W (_ULCAST_(1) << 20)
+#define MIPS_FPIR_L (_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
+#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
+
+/*
+ * FPU Status Register Values
+ */
+#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
+#define FPU_CSR_COND 0x00800000 /* $fcc0 */
+#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
+#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
+#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
+#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
+#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
+#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
+#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
+#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
+
+/*
+ * Bits 18 - 20 of the FPU Status Register will be read as 0,
+ * and should be written as zero.
+ */
+#define FPU_CSR_RSVD 0x001c0000
+
+/*
+ * X the exception cause indicator
+ * E the exception enable
+ * S the sticky/flag bit
+*/
+#define FPU_CSR_ALL_X 0x0003f000
+#define FPU_CSR_UNI_X 0x00020000
+#define FPU_CSR_INV_X 0x00010000
+#define FPU_CSR_DIV_X 0x00008000
+#define FPU_CSR_OVF_X 0x00004000
+#define FPU_CSR_UDF_X 0x00002000
+#define FPU_CSR_INE_X 0x00001000
+
+#define FPU_CSR_ALL_E 0x00000f80
+#define FPU_CSR_INV_E 0x00000800
+#define FPU_CSR_DIV_E 0x00000400
+#define FPU_CSR_OVF_E 0x00000200
+#define FPU_CSR_UDF_E 0x00000100
+#define FPU_CSR_INE_E 0x00000080
+
+#define FPU_CSR_ALL_S 0x0000007c
+#define FPU_CSR_INV_S 0x00000040
+#define FPU_CSR_DIV_S 0x00000020
+#define FPU_CSR_OVF_S 0x00000010
+#define FPU_CSR_UDF_S 0x00000008
+#define FPU_CSR_INE_S 0x00000004
+
+/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
+#define FPU_CSR_RM 0x00000003
+#define FPU_CSR_RN 0x0 /* nearest */
+#define FPU_CSR_RZ 0x1 /* towards zero */
+#define FPU_CSR_RU 0x2 /* towards +Infinity */
+#define FPU_CSR_RD 0x3 /* towards -Infinity */
+
+
#ifndef __ASSEMBLY__
/*
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 04/48] MIPS: mipsregs.h: Move TX39 macros out of the way
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (2 preceding siblings ...)
2015-04-03 22:23 ` [PATCH 03/48] MIPS: mipsregs.h: Reorder CP1 macro definitions Maciej W. Rozycki
@ 2015-04-03 22:23 ` Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 05/48] MIPS: mipsregs.h: Reindent CP0 Cause macros Maciej W. Rozycki
` (42 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:23 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
TX39 CP0 Configuration Register 3 macro definitions have been randomly
thrown in the middle of a block of CP0 Status register value macros.
Move them to the end of the whole CP0 register value macro block,
complementing the location of the TX39 Cache register name macro at the
end of the CP0 register name macro block.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-regs-tx39-conf.diff
Index: linux/arch/mips/include/asm/mipsregs.h
===================================================================
--- linux.orig/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:51.855157000 +0100
+++ linux/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:52.045161000 +0100
@@ -277,39 +277,6 @@
#define ST0_MX 0x01000000
/*
- * Bitfields in the TX39 family CP0 Configuration Register 3
- */
-#define TX39_CONF_ICS_SHIFT 19
-#define TX39_CONF_ICS_MASK 0x00380000
-#define TX39_CONF_ICS_1KB 0x00000000
-#define TX39_CONF_ICS_2KB 0x00080000
-#define TX39_CONF_ICS_4KB 0x00100000
-#define TX39_CONF_ICS_8KB 0x00180000
-#define TX39_CONF_ICS_16KB 0x00200000
-
-#define TX39_CONF_DCS_SHIFT 16
-#define TX39_CONF_DCS_MASK 0x00070000
-#define TX39_CONF_DCS_1KB 0x00000000
-#define TX39_CONF_DCS_2KB 0x00010000
-#define TX39_CONF_DCS_4KB 0x00020000
-#define TX39_CONF_DCS_8KB 0x00030000
-#define TX39_CONF_DCS_16KB 0x00040000
-
-#define TX39_CONF_CWFON 0x00004000
-#define TX39_CONF_WBON 0x00002000
-#define TX39_CONF_RF_SHIFT 10
-#define TX39_CONF_RF_MASK 0x00000c00
-#define TX39_CONF_DOZE 0x00000200
-#define TX39_CONF_HALT 0x00000100
-#define TX39_CONF_LOCK 0x00000080
-#define TX39_CONF_ICE 0x00000020
-#define TX39_CONF_DCE 0x00000010
-#define TX39_CONF_IRSIZE_SHIFT 2
-#define TX39_CONF_IRSIZE_MASK 0x0000000c
-#define TX39_CONF_DRSIZE_SHIFT 0
-#define TX39_CONF_DRSIZE_MASK 0x00000003
-
-/*
* Status register bits available in all MIPS CPUs.
*/
#define ST0_IM 0x0000ff00
@@ -673,6 +640,39 @@
#define MIPS_PWCTL_PSN_SHIFT 0
#define MIPS_PWCTL_PSN_MASK 0x0000003f
+/*
+ * Bitfields in the TX39 family CP0 Configuration Register 3
+ */
+#define TX39_CONF_ICS_SHIFT 19
+#define TX39_CONF_ICS_MASK 0x00380000
+#define TX39_CONF_ICS_1KB 0x00000000
+#define TX39_CONF_ICS_2KB 0x00080000
+#define TX39_CONF_ICS_4KB 0x00100000
+#define TX39_CONF_ICS_8KB 0x00180000
+#define TX39_CONF_ICS_16KB 0x00200000
+
+#define TX39_CONF_DCS_SHIFT 16
+#define TX39_CONF_DCS_MASK 0x00070000
+#define TX39_CONF_DCS_1KB 0x00000000
+#define TX39_CONF_DCS_2KB 0x00010000
+#define TX39_CONF_DCS_4KB 0x00020000
+#define TX39_CONF_DCS_8KB 0x00030000
+#define TX39_CONF_DCS_16KB 0x00040000
+
+#define TX39_CONF_CWFON 0x00004000
+#define TX39_CONF_WBON 0x00002000
+#define TX39_CONF_RF_SHIFT 10
+#define TX39_CONF_RF_MASK 0x00000c00
+#define TX39_CONF_DOZE 0x00000200
+#define TX39_CONF_HALT 0x00000100
+#define TX39_CONF_LOCK 0x00000080
+#define TX39_CONF_ICE 0x00000020
+#define TX39_CONF_DCE 0x00000010
+#define TX39_CONF_IRSIZE_SHIFT 2
+#define TX39_CONF_IRSIZE_MASK 0x0000000c
+#define TX39_CONF_DRSIZE_SHIFT 0
+#define TX39_CONF_DRSIZE_MASK 0x00000003
+
/*
* Coprocessor 1 (FPU) register names
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 05/48] MIPS: mipsregs.h: Reindent CP0 Cause macros
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (3 preceding siblings ...)
2015-04-03 22:23 ` [PATCH 04/48] MIPS: mipsregs.h: Move TX39 macros out of the way Maciej W. Rozycki
@ 2015-04-03 22:23 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 06/48] MIPS: ieee754.h: Correct comments for special values Maciej W. Rozycki
` (41 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:23 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Reindent CP0 Cause macros for a single space after #define, leaving
extra indentation for individual Interrupt Pending bits as with CP0
Status register's Interrupt Mask bits.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-regs-cause.diff
Index: linux/arch/mips/include/asm/mipsregs.h
===================================================================
--- linux.orig/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:52.045161000 +0100
+++ linux/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:52.242161000 +0100
@@ -339,10 +339,10 @@
*
* Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
*/
-#define CAUSEB_EXCCODE 2
-#define CAUSEF_EXCCODE (_ULCAST_(31) << 2)
-#define CAUSEB_IP 8
-#define CAUSEF_IP (_ULCAST_(255) << 8)
+#define CAUSEB_EXCCODE 2
+#define CAUSEF_EXCCODE (_ULCAST_(31) << 2)
+#define CAUSEB_IP 8
+#define CAUSEF_IP (_ULCAST_(255) << 8)
#define CAUSEB_IP0 8
#define CAUSEF_IP0 (_ULCAST_(1) << 8)
#define CAUSEB_IP1 9
@@ -359,16 +359,16 @@
#define CAUSEF_IP6 (_ULCAST_(1) << 14)
#define CAUSEB_IP7 15
#define CAUSEF_IP7 (_ULCAST_(1) << 15)
-#define CAUSEB_IV 23
-#define CAUSEF_IV (_ULCAST_(1) << 23)
-#define CAUSEB_PCI 26
-#define CAUSEF_PCI (_ULCAST_(1) << 26)
-#define CAUSEB_CE 28
-#define CAUSEF_CE (_ULCAST_(3) << 28)
-#define CAUSEB_TI 30
-#define CAUSEF_TI (_ULCAST_(1) << 30)
-#define CAUSEB_BD 31
-#define CAUSEF_BD (_ULCAST_(1) << 31)
+#define CAUSEB_IV 23
+#define CAUSEF_IV (_ULCAST_(1) << 23)
+#define CAUSEB_PCI 26
+#define CAUSEF_PCI (_ULCAST_(1) << 26)
+#define CAUSEB_CE 28
+#define CAUSEF_CE (_ULCAST_(3) << 28)
+#define CAUSEB_TI 30
+#define CAUSEF_TI (_ULCAST_(1) << 30)
+#define CAUSEB_BD 31
+#define CAUSEF_BD (_ULCAST_(1) << 31)
/*
* Bits in the coprocessor 0 config register.
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 06/48] MIPS: ieee754.h: Correct comments for special values
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (4 preceding siblings ...)
2015-04-03 22:23 ` [PATCH 05/48] MIPS: mipsregs.h: Reindent CP0 Cause macros Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 07/48] MIPS: ieee754.h: Supplement " Maciej W. Rozycki
` (40 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
IEEE754_SPCVAL_NMIN denotes the index into the special value array where
the closest to zero negative normal number expressible is stored.
Similarly IEEE754_SPCVAL_NMIND denotes such index for the closest to
zero negative subnormal number expressible. Make comments match that.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-ieee754-comment-fix.diff
Index: linux/arch/mips/math-emu/ieee754.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754.h 2015-04-02 20:18:52.566531000 +0100
+++ linux/arch/mips/math-emu/ieee754.h 2015-04-02 20:27:52.428168000 +0100
@@ -269,9 +269,9 @@ union ieee754dp ieee754dp_dump(char *s,
#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
-#define IEEE754_SPCVAL_NMIN 12 /* +min norm */
+#define IEEE754_SPCVAL_NMIN 12 /* -min norm */
#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
-#define IEEE754_SPCVAL_NMIND 14 /* +min denorm */
+#define IEEE754_SPCVAL_NMIND 14 /* -min denorm */
#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 07/48] MIPS: ieee754.h: Supplement comments for special values
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (5 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 06/48] MIPS: ieee754.h: Correct comments for special values Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 08/48] MIPS: Correct the comment for FPU emulator traps Maciej W. Rozycki
` (39 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Add the remaining missing comments for IEEE 754 special value array
indices. Reindent macro definitions for consistency.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-ieee754-comment.diff
Index: linux/arch/mips/math-emu/ieee754.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754.h 2015-04-02 20:27:52.428168000 +0100
+++ linux/arch/mips/math-emu/ieee754.h 2015-04-02 20:27:52.599179000 +0100
@@ -257,23 +257,23 @@ static inline int ieee754_sxtest(unsigne
union ieee754sp ieee754sp_dump(char *s, union ieee754sp x);
union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
-#define IEEE754_SPCVAL_PZERO 0
-#define IEEE754_SPCVAL_NZERO 1
-#define IEEE754_SPCVAL_PONE 2
-#define IEEE754_SPCVAL_NONE 3
-#define IEEE754_SPCVAL_PTEN 4
-#define IEEE754_SPCVAL_NTEN 5
-#define IEEE754_SPCVAL_PINFINITY 6
-#define IEEE754_SPCVAL_NINFINITY 7
-#define IEEE754_SPCVAL_INDEF 8
-#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
-#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
-#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
-#define IEEE754_SPCVAL_NMIN 12 /* -min norm */
-#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
-#define IEEE754_SPCVAL_NMIND 14 /* -min denorm */
-#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
+#define IEEE754_SPCVAL_PZERO 0 /* +0.0 */
+#define IEEE754_SPCVAL_NZERO 1 /* -0.0 */
+#define IEEE754_SPCVAL_PONE 2 /* +1.0 */
+#define IEEE754_SPCVAL_NONE 3 /* -1.0 */
+#define IEEE754_SPCVAL_PTEN 4 /* +10.0 */
+#define IEEE754_SPCVAL_NTEN 5 /* -10.0 */
+#define IEEE754_SPCVAL_PINFINITY 6 /* +inf */
+#define IEEE754_SPCVAL_NINFINITY 7 /* -inf */
+#define IEEE754_SPCVAL_INDEF 8 /* quiet NaN */
+#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
+#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
+#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
+#define IEEE754_SPCVAL_NMIN 12 /* -min norm */
+#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
+#define IEEE754_SPCVAL_NMIND 14 /* -min denorm */
+#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
extern const union ieee754dp __ieee754dp_spcvals[];
extern const union ieee754sp __ieee754sp_spcvals[];
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 08/48] MIPS: Correct the comment for FPU emulator traps
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (6 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 07/48] MIPS: ieee754.h: Supplement " Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 09/48] MIPS: Clarify the comment for `__cpu_has_fpu' Maciej W. Rozycki
` (38 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Adjust the explanatory comment for FPU emulator traps according to
ba3049ed [MIPS: Switch FPU emulator trap to BREAK instruction.];
originally coming from `do_ade'.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-brk-memu-comment.patch
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:18:52.208524000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:52.799182000 +0100
@@ -879,9 +879,9 @@ void do_trap_or_bp(struct pt_regs *regs,
break;
case BRK_MEMU:
/*
- * Address errors may be deliberately induced by the FPU
- * emulator to retake control of the CPU after executing the
- * instruction in the delay slot of an emulated branch.
+ * This breakpoint code is used by the FPU emulator to retake
+ * control of the CPU after executing the instruction from the
+ * delay slot of an emulated branch.
*
* Terminate if exception was recognized as a delay slot return
* otherwise handle as normal.
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 09/48] MIPS: Clarify the comment for `__cpu_has_fpu'
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (7 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 08/48] MIPS: Correct the comment for FPU emulator traps Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 10/48] MIPS: math-emu: Reindent `bc_op' emulation Maciej W. Rozycki
` (37 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Reword the comment for `__cpu_has_fpu' to make it unambiguous this code
is for external floating-point units only, generally MIPS I processors
using the original CP1 hardware interface.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-cpu-has-fpu-comment.diff
Index: linux/arch/mips/kernel/cpu-probe.c
===================================================================
--- linux.orig/arch/mips/kernel/cpu-probe.c 2015-04-02 20:18:52.108532000 +0100
+++ linux/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:52.971189000 +0100
@@ -193,7 +193,7 @@ static inline unsigned long cpu_get_fpu_
}
/*
- * Check the CPU has an FPU the official way.
+ * Check if the CPU has an external FPU.
*/
static inline int __cpu_has_fpu(void)
{
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 10/48] MIPS: math-emu: Reindent `bc_op' emulation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (8 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 09/48] MIPS: Clarify the comment for `__cpu_has_fpu' Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 11/48] MIPS: Correct the comment for and reformat `movf_func' Maciej W. Rozycki
` (36 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Correct the double-tab indentation of the branch-likely not-taken case.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-bc1x-indent.patch
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:18:52.010538000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:53.154170000 +0100
@@ -1192,17 +1192,17 @@ static int cop1Emulate(struct pt_regs *x
*/
return mips_dsemul(xcp, ir, contpc);
} else if (likely) { /* branch not taken */
- /*
- * branch likely nullifies
- * dslot if not taken
- */
- xcp->cp0_epc += dec_insn.pc_inc;
- contpc += dec_insn.pc_inc;
- /*
- * else continue & execute
- * dslot as normal insn
- */
- }
+ /*
+ * branch likely nullifies
+ * dslot if not taken
+ */
+ xcp->cp0_epc += dec_insn.pc_inc;
+ contpc += dec_insn.pc_inc;
+ /*
+ * else continue & execute
+ * dslot as normal insn
+ */
+ }
break;
default:
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 11/48] MIPS: Correct the comment for and reformat `movf_func'
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (9 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 10/48] MIPS: math-emu: Reindent `bc_op' emulation Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 12/48] MIPS: math-emu: Fix oversize lines in comparisons Maciej W. Rozycki
` (35 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Correct a copy-and-paste issue with the description for `movf_func'
referring to `movt_func'. Reformat the former function to match the
latter.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-r6-movf-comment.patch
Index: linux/arch/mips/kernel/mips-r2-to-r6-emul.c
===================================================================
--- linux.orig/arch/mips/kernel/mips-r2-to-r6-emul.c 2015-04-02 20:18:51.890522000 +0100
+++ linux/arch/mips/kernel/mips-r2-to-r6-emul.c 2015-04-02 20:27:53.338178000 +0100
@@ -187,7 +187,7 @@ static inline int mipsr6_emul(struct pt_
}
/**
- * movt_func - Emulate a MOVT instruction
+ * movf_func - Emulate a MOVF instruction
* @regs: Process register set
* @ir: Instruction
*
@@ -200,9 +200,12 @@ static int movf_func(struct pt_regs *reg
csr = current->thread.fpu.fcr31;
cond = fpucondbit[MIPSInst_RT(ir) >> 2];
+
if (((csr & cond) == 0) && MIPSInst_RD(ir))
regs->regs[MIPSInst_RD(ir)] = regs->regs[MIPSInst_RS(ir)];
+
MIPS_R2_STATS(movs);
+
return 0;
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 12/48] MIPS: math-emu: Fix oversize lines in comparisons
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (10 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 11/48] MIPS: Correct the comment for and reformat `movf_func' Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 13/48] MIPS: ELF: Drop `get_fp_abi' Maciej W. Rozycki
` (34 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
Ralf,
There's another line going past 79 columns in these functions, it'll be
removed altogether with a later functional change.
Maciej
linux-mips-emu-cmp-indent.diff
Index: linux/arch/mips/math-emu/dp_cmp.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_cmp.c 2015-04-03 12:57:39.280529000 +0100
+++ linux/arch/mips/math-emu/dp_cmp.c 2015-04-03 12:57:45.552589000 +0100
@@ -36,7 +36,8 @@ int ieee754dp_cmp(union ieee754dp x, uni
ieee754_clearcx(); /* Even clear inexact flag here */
if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
- if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+ if (sig ||
+ xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
ieee754_setcx(IEEE754_INVALID_OPERATION);
if (cmp & IEEE754_CUN)
return 1;
Index: linux/arch/mips/math-emu/sp_cmp.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_cmp.c 2015-04-03 12:57:39.282535000 +0100
+++ linux/arch/mips/math-emu/sp_cmp.c 2015-04-03 12:57:45.554593000 +0100
@@ -36,7 +36,8 @@ int ieee754sp_cmp(union ieee754sp x, uni
ieee754_clearcx(); /* Even clear inexact flag here */
if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
- if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+ if (sig ||
+ xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
ieee754_setcx(IEEE754_INVALID_OPERATION);
if (cmp & IEEE754_CUN)
return 1;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 13/48] MIPS: ELF: Drop `get_fp_abi'
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (11 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 12/48] MIPS: math-emu: Fix oversize lines in comparisons Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 14/48] MIPS: mips-r2-to-r6-emul.h: Inline empty `mipsr2_decoder' Maciej W. Rozycki
` (33 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Markos Chandras, linux-mips
Commit 46490b57 [MIPS: kernel: elf: Improve the overall ABI and FPU mode
checks] reduced `get_fp_abi' to an elaborate pass-through. Drop it
then.
Cc: Markos Chandras <markos.chandras@imgtec.com>
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-get-fp-abi.diff
Index: linux/arch/mips/kernel/elf.c
===================================================================
--- linux.orig/arch/mips/kernel/elf.c 2015-04-02 20:18:51.786524000 +0100
+++ linux/arch/mips/kernel/elf.c 2015-04-02 20:27:53.523178000 +0100
@@ -131,16 +131,6 @@ int arch_elf_pt_proc(void *_ehdr, void *
return 0;
}
-static inline unsigned get_fp_abi(int in_abi)
-{
- /* If the ABI requirement is provided, simply return that */
- if (in_abi != MIPS_ABI_FP_UNKNOWN)
- return in_abi;
-
- /* Unknown ABI */
- return MIPS_ABI_FP_UNKNOWN;
-}
-
int arch_check_elf(void *_ehdr, bool has_interpreter,
struct arch_elf_state *state)
{
@@ -151,10 +141,10 @@ int arch_check_elf(void *_ehdr, bool has
if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
return 0;
- fp_abi = get_fp_abi(state->fp_abi);
+ fp_abi = state->fp_abi;
if (has_interpreter) {
- interp_fp_abi = get_fp_abi(state->interp_fp_abi);
+ interp_fp_abi = state->interp_fp_abi;
abi0 = min(fp_abi, interp_fp_abi);
abi1 = max(fp_abi, interp_fp_abi);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 14/48] MIPS: mips-r2-to-r6-emul.h: Inline empty `mipsr2_decoder'
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (12 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 13/48] MIPS: ELF: Drop `get_fp_abi' Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 15/48] MIPS: Reindent R6 RI exception emulation Maciej W. Rozycki
` (32 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Leonid Yegoshin, linux-mips
Use `static inline' rather than `static __maybe_unused' for
`mipsr2_decoder' in the empty case, making inlining explicit where it
will happen anyway.
Cc: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-r2-decoder-inline.patch
Index: linux/arch/mips/include/asm/mips-r2-to-r6-emul.h
===================================================================
--- linux.orig/arch/mips/include/asm/mips-r2-to-r6-emul.h 2015-04-02 20:18:51.667537000 +0100
+++ linux/arch/mips/include/asm/mips-r2-to-r6-emul.h 2015-04-02 20:27:53.724187000 +0100
@@ -84,7 +84,7 @@ extern void do_trap_or_bp(struct pt_regs
#ifndef CONFIG_MIPSR2_TO_R6_EMULATOR
static int mipsr2_emulation;
-static __maybe_unused int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; };
+static inline int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; };
#else
/* MIPS R2 Emulator ON/OFF */
extern int mipsr2_emulation;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 15/48] MIPS: Reindent R6 RI exception emulation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (13 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 14/48] MIPS: mips-r2-to-r6-emul.h: Inline empty `mipsr2_decoder' Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 16/48] MIPS: math-emu: Remove `modeindex' macro Maciej W. Rozycki
` (31 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Leonid Yegoshin, linux-mips
Fold a nested `if' statement for the R6 case in `do_ri' into its
containing `if' block, removing excessive indentation causing code to
extend beyond 79 columns.
Cc: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-do-ri-r6-indent.patch
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:52.799182000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:53.911190000 +0100
@@ -1033,22 +1033,21 @@ asmlinkage void do_ri(struct pt_regs *re
* as quickly as possible.
*/
if (mipsr2_emulation && cpu_has_mips_r6 &&
- likely(user_mode(regs))) {
- if (likely(get_user(opcode, epc) >= 0)) {
- status = mipsr2_decoder(regs, opcode);
- switch (status) {
- case 0:
- case SIGEMT:
- task_thread_info(current)->r2_emul_return = 1;
- return;
- case SIGILL:
- goto no_r2_instr;
- default:
- process_fpemu_return(status,
- ¤t->thread.cp0_baduaddr);
- task_thread_info(current)->r2_emul_return = 1;
- return;
- }
+ likely(user_mode(regs)) &&
+ likely(get_user(opcode, epc) >= 0)) {
+ status = mipsr2_decoder(regs, opcode);
+ switch (status) {
+ case 0:
+ case SIGEMT:
+ task_thread_info(current)->r2_emul_return = 1;
+ return;
+ case SIGILL:
+ goto no_r2_instr;
+ default:
+ process_fpemu_return(status,
+ ¤t->thread.cp0_baduaddr);
+ task_thread_info(current)->r2_emul_return = 1;
+ return;
}
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 16/48] MIPS: math-emu: Remove `modeindex' macro
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (14 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 15/48] MIPS: Reindent R6 RI exception emulation Maciej W. Rozycki
@ 2015-04-03 22:24 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 17/48] MIPS: bitops.h: Avoid inline asm for constant FLS Maciej W. Rozycki
` (30 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Commit 56a64733 [MIPS: math-emu: Switch to using the MIPS rounding
modes.] removed the distinction between hardware and emulator rounding
mode encodings, the hardware encoding is now used in emulation as well.
Complement the change and remove the `modeindex' macro previously used
for indexing into encoding translation tables, it now does nothing and
only obfuscates code by reinserting the value extracted from FCSR.
Adjust comments accordingly.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-fcsr-rm-modeindex.diff
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:53.154170000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:54.099185000 +0100
@@ -65,9 +65,6 @@ static int fpux_emu(struct pt_regs *,
#define FPCREG_RID 0 /* $0 = revision id */
#define FPCREG_CSR 31 /* $31 = csr */
-/* Determine rounding mode from the RM bits of the FCSR */
-#define modeindex(v) ((v) & FPU_CSR_RM)
-
/* convert condition code register number to csr bit */
const unsigned int fpucondbit[8] = {
FPU_CSR_COND0,
@@ -1051,7 +1048,6 @@ static int cop1Emulate(struct pt_regs *x
/* cop control register rd -> gpr[rt] */
if (MIPSInst_RD(ir) == FPCREG_CSR) {
value = ctx->fcr31;
- value = (value & ~FPU_CSR_RM) | modeindex(value);
pr_debug("%p gpr[%d]<-csr=%08x\n",
(void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
@@ -1078,12 +1074,8 @@ static int cop1Emulate(struct pt_regs *x
(void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
- /*
- * Don't write reserved bits,
- * and convert to ieee library modes
- */
- ctx->fcr31 = (value & ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
- modeindex(value);
+ /* Don't write reserved bits. */
+ ctx->fcr31 = value & ~FPU_CSR_RSVD;
}
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
return SIGFPE;
@@ -1675,7 +1667,7 @@ static int fpu_emu(struct pt_regs *xcp,
oldrm = ieee754_csr.rm;
SPFROMREG(fs, MIPSInst_FS(ir));
- ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+ ieee754_csr.rm = MIPSInst_FUNC(ir);
rv.w = ieee754sp_tint(fs);
ieee754_csr.rm = oldrm;
rfmt = w_fmt;
@@ -1699,7 +1691,7 @@ static int fpu_emu(struct pt_regs *xcp,
oldrm = ieee754_csr.rm;
SPFROMREG(fs, MIPSInst_FS(ir));
- ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+ ieee754_csr.rm = MIPSInst_FUNC(ir);
rv.l = ieee754sp_tlong(fs);
ieee754_csr.rm = oldrm;
rfmt = l_fmt;
@@ -1852,7 +1844,7 @@ static int fpu_emu(struct pt_regs *xcp,
oldrm = ieee754_csr.rm;
DPFROMREG(fs, MIPSInst_FS(ir));
- ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+ ieee754_csr.rm = MIPSInst_FUNC(ir);
rv.w = ieee754dp_tint(fs);
ieee754_csr.rm = oldrm;
rfmt = w_fmt;
@@ -1876,7 +1868,7 @@ static int fpu_emu(struct pt_regs *xcp,
oldrm = ieee754_csr.rm;
DPFROMREG(fs, MIPSInst_FS(ir));
- ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+ ieee754_csr.rm = MIPSInst_FUNC(ir);
rv.l = ieee754dp_tlong(fs);
ieee754_csr.rm = oldrm;
rfmt = l_fmt;
@@ -2081,10 +2073,8 @@ int fpu_emulator_cop1Handler(struct pt_r
xcp->cp0_epc += dec_insn.pc_inc; /* Skip NOPs */
else {
/*
- * The 'ieee754_csr' is an alias of
- * ctx->fcr31. No need to copy ctx->fcr31 to
- * ieee754_csr. But ieee754_csr.rm is ieee
- * library modes. (not mips rounding mode)
+ * The 'ieee754_csr' is an alias of ctx->fcr31.
+ * No need to copy ctx->fcr31 to ieee754_csr.
*/
sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 17/48] MIPS: bitops.h: Avoid inline asm for constant FLS
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (15 preceding siblings ...)
2015-04-03 22:24 ` [PATCH 16/48] MIPS: math-emu: Remove `modeindex' macro Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation Maciej W. Rozycki
` (29 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
GCC is smart enough to substitute the final result for FLS calculations
as implemented in the fallback C code we have in `__fls' and `fls'
applied to constant values. The presence of inline asm defeats the
compiler though, forcing it to emit extraneous CLZ/DCLZ calculation for
processors that support these instructions.
Use `__builtin_constant_p' then to avoid inline asm altogether for
constants.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
Ralf,
Even my good old trusty 4.1.2 can do it...
Maciej
linux-mips-const-fls.diff
Index: linux/arch/mips/include/asm/bitops.h
===================================================================
--- linux.orig/arch/mips/include/asm/bitops.h 2015-04-02 20:18:51.384515000 +0100
+++ linux/arch/mips/include/asm/bitops.h 2015-04-02 20:27:54.273191000 +0100
@@ -481,7 +481,7 @@ static inline unsigned long __fls(unsign
{
int num;
- if (BITS_PER_LONG == 32 &&
+ if (BITS_PER_LONG == 32 && !__builtin_constant_p(word) &&
__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
__asm__(
" .set push \n"
@@ -494,7 +494,7 @@ static inline unsigned long __fls(unsign
return 31 - num;
}
- if (BITS_PER_LONG == 64 &&
+ if (BITS_PER_LONG == 64 && !__builtin_constant_p(word) &&
__builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
__asm__(
" .set push \n"
@@ -559,7 +559,8 @@ static inline int fls(int x)
{
int r;
- if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
+ if (!__builtin_constant_p(x) &&
+ __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
__asm__(
" .set push \n"
" .set "MIPS_ISA_LEVEL" \n"
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (16 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 17/48] MIPS: bitops.h: Avoid inline asm for constant FLS Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 23:33 ` Sergei Shtylyov
2015-04-03 22:25 ` [PATCH 19/48] MIPS: Normalise code flow in the CpU exception handler Maciej W. Rozycki
` (28 subsequent siblings)
46 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Move CFC1/CTC1 emulation code to separate functions to avoid excessive
indentation in forthcoming changes. Adjust formatting in a minor way
and remove extraneous round brackets.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-cxc.diff
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:54.099185000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:54.459192000 +0100
@@ -840,6 +840,52 @@ do { \
#define DPTOREG(dp, x) DITOREG((dp).bits, x)
/*
+ * Emulate a CFC1 instruction.
+ */
+static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ mips_instruction ir)
+{
+ u32 value;
+
+ if (MIPSInst_RD(ir) == FPCREG_CSR) {
+ value = ctx->fcr31;
+ pr_debug("%p gpr[%d]<-csr=%08x\n",
+ (void *)xcp->cp0_epc,
+ MIPSInst_RT(ir), value);
+ } else if (MIPSInst_RD(ir) == FPCREG_RID)
+ value = 0;
+ else
+ value = 0;
+ if (MIPSInst_RT(ir))
+ xcp->regs[MIPSInst_RT(ir)] = value;
+}
+
+/*
+ * Emulate a CTC1 instruction.
+ */
+static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ mips_instruction ir)
+{
+ u32 value;
+
+ if (MIPSInst_RT(ir) == 0)
+ value = 0;
+ else
+ value = xcp->regs[MIPSInst_RT(ir)];
+
+ /* we only have one writable control reg
+ */
+ if (MIPSInst_RD(ir) == FPCREG_CSR) {
+ pr_debug("%p gpr[%d]->csr=%08x\n",
+ (void *)xcp->cp0_epc,
+ MIPSInst_RT(ir), value);
+
+ /* Don't write reserved bits. */
+ ctx->fcr31 = value & ~FPU_CSR_RSVD;
+ }
+}
+
+/*
* Emulate the single floating point instruction pointed at by EPC.
* Two instructions if the instruction is in a branch delay slot.
*/
@@ -853,7 +899,6 @@ static int cop1Emulate(struct pt_regs *x
int likely, pc_inc;
u32 __user *wva;
u64 __user *dva;
- u32 value;
u32 wval;
u64 dval;
int sig;
@@ -1046,37 +1091,12 @@ static int cop1Emulate(struct pt_regs *x
case cfc_op:
/* cop control register rd -> gpr[rt] */
- if (MIPSInst_RD(ir) == FPCREG_CSR) {
- value = ctx->fcr31;
- pr_debug("%p gpr[%d]<-csr=%08x\n",
- (void *) (xcp->cp0_epc),
- MIPSInst_RT(ir), value);
- }
- else if (MIPSInst_RD(ir) == FPCREG_RID)
- value = 0;
- else
- value = 0;
- if (MIPSInst_RT(ir))
- xcp->regs[MIPSInst_RT(ir)] = value;
+ cop1_cfc(xcp, ctx, ir);
break;
case ctc_op:
/* copregister rd <- rt */
- if (MIPSInst_RT(ir) == 0)
- value = 0;
- else
- value = xcp->regs[MIPSInst_RT(ir)];
-
- /* we only have one writable control reg
- */
- if (MIPSInst_RD(ir) == FPCREG_CSR) {
- pr_debug("%p gpr[%d]->csr=%08x\n",
- (void *) (xcp->cp0_epc),
- MIPSInst_RT(ir), value);
-
- /* Don't write reserved bits. */
- ctx->fcr31 = value & ~FPU_CSR_RSVD;
- }
+ cop1_ctc(xcp, ctx, ir);
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
return SIGFPE;
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 19/48] MIPS: Normalise code flow in the CpU exception handler
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (17 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 20/48] MIPS: Use `FPU_CSR_ALL_X' in `__build_clear_fpe' Maciej W. Rozycki
` (27 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Changes applied to `do_cpu' over time reduced the use of the SIGILL
issued with `force_sig' at the end to a single CU3 case only in the
switch statement there. Move that `force_sig' call over to right where
required then and toss out the pile of gotos now not needed to skip over
the call, replacing them with regular breaks out of the switch.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-cpu-switch.diff
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:53.911190000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:54.637186000 +0100
@@ -1312,7 +1312,7 @@ asmlinkage void do_cpu(struct pt_regs *r
status = -1;
if (unlikely(compute_return_epc(regs) < 0))
- goto out;
+ break;
if (get_isa16_mode(regs->cp0_epc)) {
unsigned short mmop[2] = { 0 };
@@ -1345,7 +1345,7 @@ asmlinkage void do_cpu(struct pt_regs *r
force_sig(status, current);
}
- goto out;
+ break;
case 3:
/*
@@ -1361,8 +1361,10 @@ asmlinkage void do_cpu(struct pt_regs *r
* erroneously too, so they are covered by this choice
* as well.
*/
- if (raw_cpu_has_fpu)
+ if (raw_cpu_has_fpu) {
+ force_sig(SIGILL, current);
break;
+ }
/* Fall through. */
case 1:
@@ -1378,16 +1380,13 @@ asmlinkage void do_cpu(struct pt_regs *r
mt_ase_fp_affinity();
}
- goto out;
+ break;
case 2:
raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
- goto out;
+ break;
}
- force_sig(SIGILL, current);
-
-out:
exception_exit(prev_state);
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 20/48] MIPS: Use `FPU_CSR_ALL_X' in `__build_clear_fpe'
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (18 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 19/48] MIPS: Normalise code flow in the CpU exception handler Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 21/48] MIPS: math-emu: Update sNaN quieting handlers Maciej W. Rozycki
` (26 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Replace a hardcoded numeric bitmask for FCSR cause bits with
`FPU_CSR_ALL_X' in `__build_clear_fpe'.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-genex-fpe-all-x.diff
Index: linux/arch/mips/kernel/genex.S
===================================================================
--- linux.orig/arch/mips/kernel/genex.S 2015-04-02 20:18:51.068520000 +0100
+++ linux/arch/mips/kernel/genex.S 2015-04-02 20:27:54.807188000 +0100
@@ -360,7 +360,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
.set mips1
SET_HARDFLOAT
cfc1 a1, fcr31
- li a2, ~(0x3f << 12)
+ li a2, ~FPU_CSR_ALL_X
and a2, a1
ctc1 a2, fcr31
.set pop
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 21/48] MIPS: math-emu: Update sNaN quieting handlers
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (19 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 20/48] MIPS: Use `FPU_CSR_ALL_X' in `__build_clear_fpe' Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 23/48] MIPS: math-emu: Don't pass qNaNs through " Maciej W. Rozycki
` (25 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Commit fdffbafb [Lots of FPU bug fixes from Kjeld Borch Egevang.]
replaced the two single `ieee754sp_nanxcpt' and `ieee754dp_nanxcpt'
places, where sNaN quieting used to happen for single and double
floating-point operations respectively, with individual qNaN
instantiations across all the call sites instead. It also made most of
these two functions dead code as where called on a qNaN they return
right away.
To revert the damage and make sNaN quieting uniform again first rewrite
`ieee754sp_nanxcpt' and `ieee754dp_nanxcpt' to do the same quieting all
the call sites do, that is return the default qNaN encoding for all
input sNaN values; never propagate any sNaN payload bits from its
trailing significand field.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-nanxcpt-snan.diff
Index: linux/arch/mips/math-emu/ieee754dp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754dp.c 2015-04-02 20:18:51.033516000 +0100
+++ linux/arch/mips/math-emu/ieee754dp.c 2015-04-02 20:27:54.976193000 +0100
@@ -49,14 +49,9 @@ union ieee754dp __cold ieee754dp_nanxcpt
if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */
return r;
- if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) {
- /* not enabled convert to a quiet NaN */
- DPMANT(r) &= (~DP_MBIT(DP_FBITS-1));
- if (ieee754dp_isnan(r))
- return r;
- else
- return ieee754dp_indef();
- }
+ /* If not enabled convert to a quiet NaN. */
+ if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
+ return ieee754dp_indef();
return r;
}
Index: linux/arch/mips/math-emu/ieee754sp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754sp.c 2015-04-02 20:18:51.036515000 +0100
+++ linux/arch/mips/math-emu/ieee754sp.c 2015-04-02 20:27:54.979190000 +0100
@@ -49,14 +49,9 @@ union ieee754sp __cold ieee754sp_nanxcpt
if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */
return r;
- if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) {
- /* not enabled convert to a quiet NaN */
- SPMANT(r) &= (~SP_MBIT(SP_FBITS-1));
- if (ieee754sp_isnan(r))
- return r;
- else
- return ieee754sp_indef();
- }
+ /* If not enabled convert to a quiet NaN. */
+ if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
+ return ieee754sp_indef();
return r;
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 23/48] MIPS: math-emu: Don't pass qNaNs through quieting handlers
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (20 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 21/48] MIPS: math-emu: Update sNaN quieting handlers Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 24/48] MIPS: math-emu: Reinstate sNaN " Maciej W. Rozycki
` (24 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Don't call the `ieee754sp_nanxcpt' and `ieee754dp_nanxcpt' sNaN quieting
handlers for a qNaN supplied to floating-point format conversions or
SQRT.S/SQRT.D instructions, or for a qNaN produced out of a negative
operand supplied to SQRT.S/SQRT.D instructions. Return the qNaN right
away in these cases.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-nanxcpt-qnan.diff
Index: linux/arch/mips/math-emu/dp_fsp.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_fsp.c 2015-04-03 04:57:50.206062000 +0100
+++ linux/arch/mips/math-emu/dp_fsp.c 2015-04-03 04:58:06.696244000 +0100
@@ -44,7 +44,7 @@ union ieee754dp ieee754dp_fsp(union ieee
return ieee754dp_nanxcpt(ieee754dp_indef());
case IEEE754_CLASS_QNAN:
- return ieee754dp_nanxcpt(ieee754dp_nan_fsp(xs, xm));
+ return ieee754dp_nan_fsp(xs, xm);
case IEEE754_CLASS_INF:
return ieee754dp_inf(xs);
Index: linux/arch/mips/math-emu/dp_sqrt.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_sqrt.c 2015-04-03 04:57:13.570713000 +0100
+++ linux/arch/mips/math-emu/dp_sqrt.c 2015-04-03 04:58:06.699229000 +0100
@@ -44,7 +44,7 @@ union ieee754dp ieee754dp_sqrt(union iee
switch (xc) {
case IEEE754_CLASS_QNAN:
/* sqrt(Nan) = Nan */
- return ieee754dp_nanxcpt(x);
+ return x;
case IEEE754_CLASS_SNAN:
ieee754_setcx(IEEE754_INVALID_OPERATION);
@@ -58,7 +58,7 @@ union ieee754dp ieee754dp_sqrt(union iee
if (xs) {
/* sqrt(-Inf) = Nan */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_indef();
}
/* sqrt(+Inf) = Inf */
return x;
@@ -71,7 +71,7 @@ union ieee754dp ieee754dp_sqrt(union iee
if (xs) {
/* sqrt(-x) = Nan */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_indef();
}
break;
}
Index: linux/arch/mips/math-emu/sp_fdp.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_fdp.c 2015-04-03 04:57:50.208062000 +0100
+++ linux/arch/mips/math-emu/sp_fdp.c 2015-04-03 04:58:06.701235000 +0100
@@ -50,7 +50,7 @@ union ieee754sp ieee754sp_fdp(union ieee
nan = ieee754sp_nan_fdp(xs, xm);
if (!ieee754sp_isnan(nan))
nan = ieee754sp_indef();
- return ieee754sp_nanxcpt(nan);
+ return nan;
case IEEE754_CLASS_INF:
return ieee754sp_inf(xs);
Index: linux/arch/mips/math-emu/sp_sqrt.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_sqrt.c 2015-04-03 04:57:13.582698000 +0100
+++ linux/arch/mips/math-emu/sp_sqrt.c 2015-04-03 04:58:06.703246000 +0100
@@ -37,7 +37,7 @@ union ieee754sp ieee754sp_sqrt(union iee
switch (xc) {
case IEEE754_CLASS_QNAN:
/* sqrt(Nan) = Nan */
- return ieee754sp_nanxcpt(x);
+ return x;
case IEEE754_CLASS_SNAN:
ieee754_setcx(IEEE754_INVALID_OPERATION);
@@ -51,7 +51,7 @@ union ieee754sp ieee754sp_sqrt(union iee
if (xs) {
/* sqrt(-Inf) = Nan */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_indef();
}
/* sqrt(+Inf) = Inf */
return x;
@@ -61,7 +61,7 @@ union ieee754sp ieee754sp_sqrt(union iee
if (xs) {
/* sqrt(-x) = Nan */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_indef();
}
break;
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 24/48] MIPS: math-emu: Reinstate sNaN quieting handlers
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (21 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 23/48] MIPS: math-emu: Don't pass qNaNs through " Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 25/48] MIPS: math-emu: Optimise NaN handling in comparisons Maciej W. Rozycki
` (23 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Revert the changes made by commit fdffbafb [Lots of FPU bug fixes from
Kjeld Borch Egevang.] to `ieee754sp_nanxcpt' and `ieee754dp_nanxcpt'
sNaN quieting handlers and their callers so that sNaN processing is done
within the handlers againg. Pass the sNaN causing an IEEE 754 invalid
operation exception down to the relevant handler. Pass the sNaN in `fs'
where two sNaNs are supplied to a binary operation.
Set the Invalid Operation FCSR exception bits in the quieting handlers
rather than at their call sites throughout. Make the handlers exclusive
for sNaN processing.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-nanxcpt.diff
Index: linux/arch/mips/math-emu/dp_add.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_add.c 2015-04-03 04:57:13.565700000 +0100
+++ linux/arch/mips/math-emu/dp_add.c 2015-04-03 04:58:15.978323000 +0100
@@ -37,19 +37,20 @@ union ieee754dp ieee754dp_add(union ieee
FLUSHYDP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754dp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/dp_div.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_div.c 2015-04-03 04:57:13.566710000 +0100
+++ linux/arch/mips/math-emu/dp_div.c 2015-04-03 04:58:15.980324000 +0100
@@ -39,19 +39,20 @@ union ieee754dp ieee754dp_div(union ieee
FLUSHYDP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754dp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/dp_fsp.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_fsp.c 2015-04-03 04:58:06.696244000 +0100
+++ linux/arch/mips/math-emu/dp_fsp.c 2015-04-03 04:58:15.982329000 +0100
@@ -40,8 +40,7 @@ union ieee754dp ieee754dp_fsp(union ieee
switch (xc) {
case IEEE754_CLASS_SNAN:
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_nanxcpt(ieee754dp_nan_fsp(xs, xm));
case IEEE754_CLASS_QNAN:
return ieee754dp_nan_fsp(xs, xm);
Index: linux/arch/mips/math-emu/dp_mul.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_mul.c 2015-04-03 04:57:13.569704000 +0100
+++ linux/arch/mips/math-emu/dp_mul.c 2015-04-03 04:58:15.985318000 +0100
@@ -47,19 +47,20 @@ union ieee754dp ieee754dp_mul(union ieee
FLUSHYDP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754dp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/dp_sqrt.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_sqrt.c 2015-04-03 04:58:06.699229000 +0100
+++ linux/arch/mips/math-emu/dp_sqrt.c 2015-04-03 04:58:15.986332000 +0100
@@ -42,14 +42,13 @@ union ieee754dp ieee754dp_sqrt(union iee
/* x == INF or NAN? */
switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ return ieee754dp_nanxcpt(x);
+
case IEEE754_CLASS_QNAN:
/* sqrt(Nan) = Nan */
return x;
- case IEEE754_CLASS_SNAN:
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
-
case IEEE754_CLASS_ZERO:
/* sqrt(0) = 0 */
return x;
Index: linux/arch/mips/math-emu/dp_sub.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_sub.c 2015-04-03 04:57:13.572700000 +0100
+++ linux/arch/mips/math-emu/dp_sub.c 2015-04-03 04:58:15.989320000 +0100
@@ -37,19 +37,20 @@ union ieee754dp ieee754dp_sub(union ieee
FLUSHYDP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754dp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
+ return ieee754dp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/ieee754dp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754dp.c 2015-04-03 04:57:47.065031000 +0100
+++ linux/arch/mips/math-emu/ieee754dp.c 2015-04-03 04:58:15.991322000 +0100
@@ -42,18 +42,16 @@ static inline int ieee754dp_issnan(union
}
+/*
+ * Raise the Invalid Operation IEEE 754 exception
+ * and convert the signaling NaN supplied to a quiet NaN.
+ */
union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
{
- assert(ieee754dp_isnan(r));
-
- if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */
- return r;
-
- /* If not enabled convert to a quiet NaN. */
- if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
- return ieee754dp_indef();
+ assert(ieee754dp_issnan(r));
- return r;
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754dp_indef();
}
static u64 ieee754dp_get_rounding(int sn, u64 xm)
Index: linux/arch/mips/math-emu/ieee754sp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754sp.c 2015-04-03 04:57:47.067040000 +0100
+++ linux/arch/mips/math-emu/ieee754sp.c 2015-04-03 04:58:15.993327000 +0100
@@ -42,18 +42,16 @@ static inline int ieee754sp_issnan(union
}
+/*
+ * Raise the Invalid Operation IEEE 754 exception
+ * and convert the signaling NaN supplied to a quiet NaN.
+ */
union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
{
- assert(ieee754sp_isnan(r));
-
- if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */
- return r;
-
- /* If not enabled convert to a quiet NaN. */
- if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
- return ieee754sp_indef();
+ assert(ieee754sp_issnan(r));
- return r;
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754sp_indef();
}
static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
Index: linux/arch/mips/math-emu/sp_add.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_add.c 2015-04-03 04:57:13.576708000 +0100
+++ linux/arch/mips/math-emu/sp_add.c 2015-04-03 04:58:16.002321000 +0100
@@ -37,19 +37,20 @@ union ieee754sp ieee754sp_add(union ieee
FLUSHYSP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754sp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/sp_div.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_div.c 2015-04-03 04:57:13.578697000 +0100
+++ linux/arch/mips/math-emu/sp_div.c 2015-04-03 04:58:16.005320000 +0100
@@ -39,19 +39,20 @@ union ieee754sp ieee754sp_div(union ieee
FLUSHYSP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754sp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/sp_fdp.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_fdp.c 2015-04-03 04:58:06.701235000 +0100
+++ linux/arch/mips/math-emu/sp_fdp.c 2015-04-03 04:58:16.006329000 +0100
@@ -43,8 +43,7 @@ union ieee754sp ieee754sp_fdp(union ieee
switch (xc) {
case IEEE754_CLASS_SNAN:
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm));
case IEEE754_CLASS_QNAN:
nan = ieee754sp_nan_fdp(xs, xm);
Index: linux/arch/mips/math-emu/sp_mul.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_mul.c 2015-04-03 04:57:13.580714000 +0100
+++ linux/arch/mips/math-emu/sp_mul.c 2015-04-03 04:58:16.009320000 +0100
@@ -47,19 +47,20 @@ union ieee754sp ieee754sp_mul(union ieee
FLUSHYSP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754sp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
Index: linux/arch/mips/math-emu/sp_sqrt.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_sqrt.c 2015-04-03 04:58:06.703246000 +0100
+++ linux/arch/mips/math-emu/sp_sqrt.c 2015-04-03 04:58:16.011320000 +0100
@@ -35,14 +35,13 @@ union ieee754sp ieee754sp_sqrt(union iee
/* x == INF or NAN? */
switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ return ieee754sp_nanxcpt(x);
+
case IEEE754_CLASS_QNAN:
/* sqrt(Nan) = Nan */
return x;
- case IEEE754_CLASS_SNAN:
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
-
case IEEE754_CLASS_ZERO:
/* sqrt(0) = 0 */
return x;
Index: linux/arch/mips/math-emu/sp_sub.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_sub.c 2015-04-03 04:57:13.584711000 +0100
+++ linux/arch/mips/math-emu/sp_sub.c 2015-04-03 04:58:16.013323000 +0100
@@ -37,19 +37,20 @@ union ieee754sp ieee754sp_sub(union ieee
FLUSHYSP;
switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ return ieee754sp_nanxcpt(y);
+
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
+ return ieee754sp_nanxcpt(x);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 25/48] MIPS: math-emu: Optimise NaN handling in comparisons
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (22 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 24/48] MIPS: math-emu: Reinstate sNaN " Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 26/48] MIPS: math-emu: Remove redundant code from NaN comparison Maciej W. Rozycki
` (22 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
We have the input operands already classified in `ieee754sp_cmp' and
`ieee754dp_cmp' comparison operations, so use the class obtained to tell
NaNs and numbers apart rather than classifying inputs again for this
purpose, reducing the size of code by 24 and 40 instructions or 96 and
160 bytes respectively.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-cmp-nan.diff
Index: linux/arch/mips/math-emu/dp_cmp.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_cmp.c 2015-04-03 13:23:28.348835000 +0100
+++ linux/arch/mips/math-emu/dp_cmp.c 2015-04-03 13:23:31.663867000 +0100
@@ -35,7 +35,7 @@ int ieee754dp_cmp(union ieee754dp x, uni
FLUSHYDP;
ieee754_clearcx(); /* Even clear inexact flag here */
- if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
+ if (ieee754_class_nan(xc) || ieee754_class_nan(yc)) {
if (sig ||
xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
ieee754_setcx(IEEE754_INVALID_OPERATION);
Index: linux/arch/mips/math-emu/ieee754dp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754dp.c 2015-04-03 13:23:28.349836000 +0100
+++ linux/arch/mips/math-emu/ieee754dp.c 2015-04-03 13:23:31.665869000 +0100
@@ -32,7 +32,7 @@ int ieee754dp_class(union ieee754dp x)
int ieee754dp_isnan(union ieee754dp x)
{
- return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
+ return ieee754_class_nan(ieee754dp_class(x));
}
static inline int ieee754dp_issnan(union ieee754dp x)
Index: linux/arch/mips/math-emu/ieee754int.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754int.h 2015-04-03 13:23:28.350839000 +0100
+++ linux/arch/mips/math-emu/ieee754int.h 2015-04-03 13:23:31.667874000 +0100
@@ -44,6 +44,11 @@ static inline int ieee754_setandtestcx(c
return ieee754_csr.mx & x;
}
+static inline int ieee754_class_nan(int xc)
+{
+ return xc >= IEEE754_CLASS_SNAN;
+}
+
#define COMPXSP \
unsigned xm; int xe; int xs __maybe_unused; int xc
Index: linux/arch/mips/math-emu/ieee754sp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754sp.c 2015-04-03 13:23:28.352832000 +0100
+++ linux/arch/mips/math-emu/ieee754sp.c 2015-04-03 13:23:31.678870000 +0100
@@ -32,7 +32,7 @@ int ieee754sp_class(union ieee754sp x)
int ieee754sp_isnan(union ieee754sp x)
{
- return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
+ return ieee754_class_nan(ieee754sp_class(x));
}
static inline int ieee754sp_issnan(union ieee754sp x)
Index: linux/arch/mips/math-emu/sp_cmp.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_cmp.c 2015-04-03 13:23:28.354835000 +0100
+++ linux/arch/mips/math-emu/sp_cmp.c 2015-04-03 13:23:31.680870000 +0100
@@ -35,7 +35,7 @@ int ieee754sp_cmp(union ieee754sp x, uni
FLUSHYSP;
ieee754_clearcx(); /* Even clear inexact flag here */
- if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
+ if (ieee754_class_nan(xc) || ieee754_class_nan(yc)) {
if (sig ||
xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
ieee754_setcx(IEEE754_INVALID_OPERATION);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 26/48] MIPS: math-emu: Remove redundant code from NaN comparison
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (23 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 25/48] MIPS: math-emu: Optimise NaN handling in comparisons Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 27/48] MIPS: math-emu: Remove dead comparison helpers Maciej W. Rozycki
` (21 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Remove a redundant call to `ieee754_setandtestcx' in `ieee754sp_cmp' and
`ieee754dp_cmp'. The IEEE 754 exception requested will have already
been set by a call to `ieee754_setcx' immediately above, because `sig'
has to be non-zero to reach here, and the comparison result returned
will be 0 regardless of the result from the call. Simplify the return
expression remaining. All this reducing the size of code by 16 and 12
instructions or 64 and 48 bytes respectively.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-cmp.diff
Index: linux/arch/mips/math-emu/dp_cmp.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_cmp.c 2015-04-03 13:23:31.663867000 +0100
+++ linux/arch/mips/math-emu/dp_cmp.c 2015-04-03 13:23:37.279924000 +0100
@@ -39,13 +39,7 @@ int ieee754dp_cmp(union ieee754dp x, uni
if (sig ||
xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
ieee754_setcx(IEEE754_INVALID_OPERATION);
- if (cmp & IEEE754_CUN)
- return 1;
- if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
- if (sig && ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
- return 0;
- }
- return 0;
+ return (cmp & IEEE754_CUN) != 0;
} else {
vx = x.bits;
vy = y.bits;
Index: linux/arch/mips/math-emu/sp_cmp.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_cmp.c 2015-04-03 13:23:31.680870000 +0100
+++ linux/arch/mips/math-emu/sp_cmp.c 2015-04-03 13:23:37.281921000 +0100
@@ -39,13 +39,7 @@ int ieee754sp_cmp(union ieee754sp x, uni
if (sig ||
xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
ieee754_setcx(IEEE754_INVALID_OPERATION);
- if (cmp & IEEE754_CUN)
- return 1;
- if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
- if (sig && ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
- return 0;
- }
- return 0;
+ return (cmp & IEEE754_CUN) != 0;
} else {
vx = x.bits;
vy = y.bits;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 27/48] MIPS: math-emu: Remove dead comparison helpers
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (24 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 26/48] MIPS: math-emu: Remove redundant code from NaN comparison Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 29/48] MIPS: math-emu: Make NaN classifiers static Maciej W. Rozycki
` (20 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
None of the comparison helpers in ieee754.h is used, remove them.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-cmp-helper.diff
Index: linux/arch/mips/math-emu/ieee754.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754.h 2015-04-03 12:38:50.000000000 +0100
+++ linux/arch/mips/math-emu/ieee754.h 2015-04-03 13:42:52.928882000 +0100
@@ -126,71 +126,6 @@ enum {
#define IEEE754_CGT 0x04
#define IEEE754_CUN 0x08
-/* "normal" comparisons
-*/
-static inline int ieee754sp_eq(union ieee754sp x, union ieee754sp y)
-{
- return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
-}
-
-static inline int ieee754sp_ne(union ieee754sp x, union ieee754sp y)
-{
- return ieee754sp_cmp(x, y,
- IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
-}
-
-static inline int ieee754sp_lt(union ieee754sp x, union ieee754sp y)
-{
- return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
-}
-
-static inline int ieee754sp_le(union ieee754sp x, union ieee754sp y)
-{
- return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
-}
-
-static inline int ieee754sp_gt(union ieee754sp x, union ieee754sp y)
-{
- return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
-}
-
-
-static inline int ieee754sp_ge(union ieee754sp x, union ieee754sp y)
-{
- return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
-}
-
-static inline int ieee754dp_eq(union ieee754dp x, union ieee754dp y)
-{
- return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
-}
-
-static inline int ieee754dp_ne(union ieee754dp x, union ieee754dp y)
-{
- return ieee754dp_cmp(x, y,
- IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
-}
-
-static inline int ieee754dp_lt(union ieee754dp x, union ieee754dp y)
-{
- return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
-}
-
-static inline int ieee754dp_le(union ieee754dp x, union ieee754dp y)
-{
- return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
-}
-
-static inline int ieee754dp_gt(union ieee754dp x, union ieee754dp y)
-{
- return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
-}
-
-static inline int ieee754dp_ge(union ieee754dp x, union ieee754dp y)
-{
- return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
-}
-
/*
* The control status register
*/
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 29/48] MIPS: math-emu: Make NaN classifiers static
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (25 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 27/48] MIPS: math-emu: Remove dead comparison helpers Maciej W. Rozycki
@ 2015-04-03 22:25 ` Maciej W. Rozycki
2015-04-03 23:22 ` Sergei Shtylyov
2015-04-03 22:26 ` [PATCH 30/48] MIPS: Correct `nofpu' non-functionality Maciej W. Rozycki
` (19 subsequent siblings)
46 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:25 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
The `ieee754sp_isnan' and `ieee754dp_isnan' NaN classifiers are now no
longer externally referred, remove their header prototypes and make them
local to the two only respective places still making use of them.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-isnan.diff
Index: linux/arch/mips/math-emu/ieee754dp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754dp.c 2015-04-02 20:27:55.587207000 +0100
+++ linux/arch/mips/math-emu/ieee754dp.c 2015-04-02 20:27:56.032207000 +0100
@@ -30,7 +30,7 @@ int ieee754dp_class(union ieee754dp x)
return xc;
}
-int ieee754dp_isnan(union ieee754dp x)
+static inline int ieee754dp_isnan(union ieee754dp x)
{
return ieee754_class_nan(ieee754dp_class(x));
}
Index: linux/arch/mips/math-emu/ieee754dp.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754dp.h 2015-04-02 20:18:50.309509000 +0100
+++ linux/arch/mips/math-emu/ieee754dp.h 2015-04-02 20:27:56.035204000 +0100
@@ -77,6 +77,5 @@ static inline union ieee754dp builddp(in
return r;
}
-extern int ieee754dp_isnan(union ieee754dp);
extern union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp);
extern union ieee754dp ieee754dp_format(int, int, u64);
Index: linux/arch/mips/math-emu/ieee754sp.c
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754sp.c 2015-04-02 20:27:55.601223000 +0100
+++ linux/arch/mips/math-emu/ieee754sp.c 2015-04-02 20:27:56.037202000 +0100
@@ -30,7 +30,7 @@ int ieee754sp_class(union ieee754sp x)
return xc;
}
-int ieee754sp_isnan(union ieee754sp x)
+static inline int ieee754sp_isnan(union ieee754sp x)
{
return ieee754_class_nan(ieee754sp_class(x));
}
Index: linux/arch/mips/math-emu/ieee754sp.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754sp.h 2015-04-02 20:18:50.314505000 +0100
+++ linux/arch/mips/math-emu/ieee754sp.h 2015-04-02 20:27:56.039206000 +0100
@@ -82,6 +82,5 @@ static inline union ieee754sp buildsp(in
return r;
}
-extern int ieee754sp_isnan(union ieee754sp);
extern union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp);
extern union ieee754sp ieee754sp_format(int, int, unsigned);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 30/48] MIPS: Correct `nofpu' non-functionality
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (26 preceding siblings ...)
2015-04-03 22:25 ` [PATCH 29/48] MIPS: math-emu: Make NaN classifiers static Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 31/48] MIPS: Correct MIPS16 BREAK code interpretation Maciej W. Rozycki
` (18 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
The `cpu_has_fpu' feature flag must not be hardcoded to 1 or the `nofpu'
kernel option will be ignored. Remove any such overrides and add a
cautionary note. Hardcoding to 0 is fine for FPU-less platforms.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-cpu-has-fpu.patch
Index: linux/arch/mips/include/asm/cpu-features.h
===================================================================
--- linux.orig/arch/mips/include/asm/cpu-features.h 2015-04-02 20:18:50.163509000 +0100
+++ linux/arch/mips/include/asm/cpu-features.h 2015-04-02 20:27:56.252205000 +0100
@@ -68,6 +68,7 @@
#ifndef cpu_has_octeon_cache
#define cpu_has_octeon_cache 0
#endif
+/* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work. */
#ifndef cpu_has_fpu
#define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU)
#define raw_cpu_has_fpu (raw_current_cpu_data.options & MIPS_CPU_FPU)
Index: linux/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
===================================================================
--- linux.orig/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h 2015-04-02 20:18:50.166512000 +0100
+++ linux/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h 2015-04-02 20:27:56.276209000 +0100
@@ -14,7 +14,6 @@
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_tx39_cache 0
-#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
#define cpu_has_watch 0
Index: linux/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h
===================================================================
--- linux.orig/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h 2015-04-02 20:18:50.169511000 +0100
+++ linux/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h 2015-04-02 20:27:56.289206000 +0100
@@ -15,7 +15,6 @@
/* Generic ones first. */
#define cpu_has_tlb 1
#define cpu_has_tx39_cache 0
-#define cpu_has_fpu 1
#define cpu_has_divec 0
#define cpu_has_prefetch 0
#define cpu_has_mcheck 0
Index: linux/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
===================================================================
--- linux.orig/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h 2015-04-02 20:18:50.172504000 +0100
+++ linux/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h 2015-04-02 20:27:56.299204000 +0100
@@ -16,7 +16,6 @@
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_4k_cache 1
-#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
#define cpu_has_mips16 0
Index: linux/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
===================================================================
--- linux.orig/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h 2015-04-02 20:18:50.175504000 +0100
+++ linux/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h 2015-04-02 20:27:56.306207000 +0100
@@ -26,7 +26,6 @@
/* Settings which are common for all ip32 CPUs */
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
#define cpu_has_mips16 0
Index: linux/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
===================================================================
--- linux.orig/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2015-04-02 20:18:50.178504000 +0100
+++ linux/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2015-04-02 20:27:56.323205000 +0100
@@ -34,7 +34,6 @@
#define cpu_has_dsp 0
#define cpu_has_dsp2 0
#define cpu_has_ejtag 0
-#define cpu_has_fpu 1
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_inclusive_pcaches 1
#define cpu_has_llsc 1
Index: linux/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
===================================================================
--- linux.orig/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h 2015-04-02 20:18:50.182511000 +0100
+++ linux/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h 2015-04-02 20:27:56.333207000 +0100
@@ -15,7 +15,6 @@
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_4k_cache 1
-#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
#define cpu_has_watch 0
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 31/48] MIPS: Correct MIPS16 BREAK code interpretation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (27 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 30/48] MIPS: Correct `nofpu' non-functionality Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 32/48] MIPS: BREAK instruction interpretation corrections Maciej W. Rozycki
` (17 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Correct the interpretation of the immediate MIPS16 BREAK instruction
code embedded in the instruction word across bits 10:5 rather than 11:6
as current code implies, fixing the interpretation of integer overflow
and divide by zero traps.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-do-bp16.diff
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:54.637186000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:56.610207000 +0100
@@ -925,7 +925,7 @@ asmlinkage void do_bp(struct pt_regs *re
if (__get_user(instr[0],
(u16 __user *)msk_isa16_mode(epc)))
goto out_sigsegv;
- bcode = (instr[0] >> 6) & 0x3f;
+ bcode = (instr[0] >> 5) & 0x3f;
do_trap_or_bp(regs, bcode, "Break");
goto out;
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 32/48] MIPS: BREAK instruction interpretation corrections
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (28 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 31/48] MIPS: Correct MIPS16 BREAK code interpretation Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 33/48] MIPS: Fix BREAK code interpretation heuristics Maciej W. Rozycki
` (16 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Add the missing microMIPS BREAK16 instruction code interpretation and
reshape code removing instruction fetching duplication and the separate
call to `do_trap_or_bp' in the MIPS16 path.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-do-bp.diff
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:56.610207000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:56.780209000 +0100
@@ -901,10 +901,9 @@ void do_trap_or_bp(struct pt_regs *regs,
asmlinkage void do_bp(struct pt_regs *regs)
{
+ unsigned long epc = msk_isa16_mode(exception_epc(regs));
unsigned int opcode, bcode;
enum ctx_state prev_state;
- unsigned long epc;
- u16 instr[2];
mm_segment_t seg;
seg = get_fs();
@@ -913,26 +912,28 @@ asmlinkage void do_bp(struct pt_regs *re
prev_state = exception_enter();
if (get_isa16_mode(regs->cp0_epc)) {
- /* Calculate EPC. */
- epc = exception_epc(regs);
- if (cpu_has_mmips) {
- if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)) ||
- (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))))
- goto out_sigsegv;
- opcode = (instr[0] << 16) | instr[1];
- } else {
+ u16 instr[2];
+
+ if (__get_user(instr[0], (u16 __user *)epc))
+ goto out_sigsegv;
+
+ if (!cpu_has_mmips) {
/* MIPS16e mode */
- if (__get_user(instr[0],
- (u16 __user *)msk_isa16_mode(epc)))
- goto out_sigsegv;
bcode = (instr[0] >> 5) & 0x3f;
- do_trap_or_bp(regs, bcode, "Break");
- goto out;
+ } else if (mm_insn_16bit(instr[0])) {
+ /* 16-bit microMIPS BREAK */
+ bcode = instr[0] & 0xf;
+ } else {
+ /* 32-bit microMIPS BREAK */
+ if (__get_user(instr[1], (u16 __user *)(epc + 2)))
+ goto out_sigsegv;
+ opcode = (instr[0] << 16) | instr[1];
+ bcode = (opcode >> 6) & ((1 << 20) - 1);
}
} else {
- if (__get_user(opcode,
- (unsigned int __user *) exception_epc(regs)))
+ if (__get_user(opcode, (unsigned int __user *)epc))
goto out_sigsegv;
+ bcode = (opcode >> 6) & ((1 << 20) - 1);
}
/*
@@ -941,7 +942,6 @@ asmlinkage void do_bp(struct pt_regs *re
* Gas is bug-compatible, but not always, grrr...
* We handle both cases with a simple heuristics. --macro
*/
- bcode = ((opcode >> 6) & ((1 << 20) - 1));
if (bcode >= (1 << 10))
bcode >>= 10;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 33/48] MIPS: Fix BREAK code interpretation heuristics
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (29 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 32/48] MIPS: BREAK instruction interpretation corrections Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 34/48] MIPS: math-emu: Fix delay-slot emulation cache incoherency Maciej W. Rozycki
` (15 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Do not lose the other half of the BREAK code where there is an upper
half. This is so that e.g. `BREAK 7, 7' is not interpreted as a divide
by zero trap, while `BREAK 0, 7' or `BREAK 7, 0' still are.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-do-bp-code.diff
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:56.780209000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:56.948213000 +0100
@@ -943,7 +943,7 @@ asmlinkage void do_bp(struct pt_regs *re
* We handle both cases with a simple heuristics. --macro
*/
if (bcode >= (1 << 10))
- bcode >>= 10;
+ bcode = ((bcode & ((1 << 10) - 1)) << 10) | (bcode >> 10);
/*
* notify the kprobe handlers, if instruction is likely to
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 34/48] MIPS: math-emu: Fix delay-slot emulation cache incoherency
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (30 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 33/48] MIPS: Fix BREAK code interpretation heuristics Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 35/48] MIPS: Correct MIPS I FP context layout Maciej W. Rozycki
` (14 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Correct a cache coherency regression introduced with be1664c4 [Another
round of fixes for the fp emulator.] for the emulation frame used in
delay-slot emulation.
Two instructions are copied into the frame and as from the commit
referred a cache synchronisation call is made for the second instruction
aka `badinst' of the two only. The `flush_cache_sigtramp' interface is
reused that guarantees that synchronisation will be made for 8 bytes or
2 instructions starting from the address requested, although if cache
lines are wider then a larger area may be synchronised.
Change the call to point to the first of the two instructions aka `emul'
instead, removing unpredictable behaviour resulting from cache
incoherency.
This bug only ever manifested itself on systems implementing 4-byte
cache lines, typically MIPS I systems, causing all kinds of weirdness.
This is because the sequence of two instructions starting from `emul' is
8-byte aligned and for 8-byte or wider cache lines the line synchronised
will span both, so the vast majority of systems have escaped unharmed.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-dsemul-flush-cache.patch
Index: linux/arch/mips/math-emu/dsemul.c
===================================================================
--- linux.orig/arch/mips/math-emu/dsemul.c 2015-04-02 20:18:49.616501000 +0100
+++ linux/arch/mips/math-emu/dsemul.c 2015-04-02 20:27:57.133225000 +0100
@@ -94,7 +94,7 @@ int mips_dsemul(struct pt_regs *regs, mi
regs->cp0_epc = ((unsigned long) &fr->emul) |
get_isa16_mode(regs->cp0_epc);
- flush_cache_sigtramp((unsigned long)&fr->badinst);
+ flush_cache_sigtramp((unsigned long)&fr->emul);
return SIGILL; /* force out of emulation loop */
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 35/48] MIPS: Correct MIPS I FP context layout
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (31 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 34/48] MIPS: math-emu: Fix delay-slot emulation cache incoherency Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 36/48] MIPS: Correct FP ISA requirements Maciej W. Rozycki
` (13 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Implement the correct ordering of individual floating-point registers
within double-precision register pairs for the MIPS I FP context, as
required by our FP emulation code and expected by userland talking via
ptrace(2). Use L.D and S.D assembly macros that do the right thing like
LDC1 and SDC1 from MIPS II up, avoiding the need to mess up with
endianness conditionals.
This in particular fixes the handling of denormals and NaN generation in
Unimplemented Operation emulation traps.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-isa1-fp-context.patch
Index: linux/arch/mips/include/asm/asmmacro-32.h
===================================================================
--- linux.orig/arch/mips/include/asm/asmmacro-32.h 2015-04-02 20:18:49.474495000 +0100
+++ linux/arch/mips/include/asm/asmmacro-32.h 2015-04-02 20:27:57.304220000 +0100
@@ -16,38 +16,22 @@
.set push
SET_HARDFLOAT
cfc1 \tmp, fcr31
- swc1 $f0, THREAD_FPR0_LS64(\thread)
- swc1 $f1, THREAD_FPR1_LS64(\thread)
- swc1 $f2, THREAD_FPR2_LS64(\thread)
- swc1 $f3, THREAD_FPR3_LS64(\thread)
- swc1 $f4, THREAD_FPR4_LS64(\thread)
- swc1 $f5, THREAD_FPR5_LS64(\thread)
- swc1 $f6, THREAD_FPR6_LS64(\thread)
- swc1 $f7, THREAD_FPR7_LS64(\thread)
- swc1 $f8, THREAD_FPR8_LS64(\thread)
- swc1 $f9, THREAD_FPR9_LS64(\thread)
- swc1 $f10, THREAD_FPR10_LS64(\thread)
- swc1 $f11, THREAD_FPR11_LS64(\thread)
- swc1 $f12, THREAD_FPR12_LS64(\thread)
- swc1 $f13, THREAD_FPR13_LS64(\thread)
- swc1 $f14, THREAD_FPR14_LS64(\thread)
- swc1 $f15, THREAD_FPR15_LS64(\thread)
- swc1 $f16, THREAD_FPR16_LS64(\thread)
- swc1 $f17, THREAD_FPR17_LS64(\thread)
- swc1 $f18, THREAD_FPR18_LS64(\thread)
- swc1 $f19, THREAD_FPR19_LS64(\thread)
- swc1 $f20, THREAD_FPR20_LS64(\thread)
- swc1 $f21, THREAD_FPR21_LS64(\thread)
- swc1 $f22, THREAD_FPR22_LS64(\thread)
- swc1 $f23, THREAD_FPR23_LS64(\thread)
- swc1 $f24, THREAD_FPR24_LS64(\thread)
- swc1 $f25, THREAD_FPR25_LS64(\thread)
- swc1 $f26, THREAD_FPR26_LS64(\thread)
- swc1 $f27, THREAD_FPR27_LS64(\thread)
- swc1 $f28, THREAD_FPR28_LS64(\thread)
- swc1 $f29, THREAD_FPR29_LS64(\thread)
- swc1 $f30, THREAD_FPR30_LS64(\thread)
- swc1 $f31, THREAD_FPR31_LS64(\thread)
+ s.d $f0, THREAD_FPR0_LS64(\thread)
+ s.d $f2, THREAD_FPR2_LS64(\thread)
+ s.d $f4, THREAD_FPR4_LS64(\thread)
+ s.d $f6, THREAD_FPR6_LS64(\thread)
+ s.d $f8, THREAD_FPR8_LS64(\thread)
+ s.d $f10, THREAD_FPR10_LS64(\thread)
+ s.d $f12, THREAD_FPR12_LS64(\thread)
+ s.d $f14, THREAD_FPR14_LS64(\thread)
+ s.d $f16, THREAD_FPR16_LS64(\thread)
+ s.d $f18, THREAD_FPR18_LS64(\thread)
+ s.d $f20, THREAD_FPR20_LS64(\thread)
+ s.d $f22, THREAD_FPR22_LS64(\thread)
+ s.d $f24, THREAD_FPR24_LS64(\thread)
+ s.d $f26, THREAD_FPR26_LS64(\thread)
+ s.d $f28, THREAD_FPR28_LS64(\thread)
+ s.d $f30, THREAD_FPR30_LS64(\thread)
sw \tmp, THREAD_FCR31(\thread)
.set pop
.endm
@@ -56,38 +40,22 @@
.set push
SET_HARDFLOAT
lw \tmp, THREAD_FCR31(\thread)
- lwc1 $f0, THREAD_FPR0_LS64(\thread)
- lwc1 $f1, THREAD_FPR1_LS64(\thread)
- lwc1 $f2, THREAD_FPR2_LS64(\thread)
- lwc1 $f3, THREAD_FPR3_LS64(\thread)
- lwc1 $f4, THREAD_FPR4_LS64(\thread)
- lwc1 $f5, THREAD_FPR5_LS64(\thread)
- lwc1 $f6, THREAD_FPR6_LS64(\thread)
- lwc1 $f7, THREAD_FPR7_LS64(\thread)
- lwc1 $f8, THREAD_FPR8_LS64(\thread)
- lwc1 $f9, THREAD_FPR9_LS64(\thread)
- lwc1 $f10, THREAD_FPR10_LS64(\thread)
- lwc1 $f11, THREAD_FPR11_LS64(\thread)
- lwc1 $f12, THREAD_FPR12_LS64(\thread)
- lwc1 $f13, THREAD_FPR13_LS64(\thread)
- lwc1 $f14, THREAD_FPR14_LS64(\thread)
- lwc1 $f15, THREAD_FPR15_LS64(\thread)
- lwc1 $f16, THREAD_FPR16_LS64(\thread)
- lwc1 $f17, THREAD_FPR17_LS64(\thread)
- lwc1 $f18, THREAD_FPR18_LS64(\thread)
- lwc1 $f19, THREAD_FPR19_LS64(\thread)
- lwc1 $f20, THREAD_FPR20_LS64(\thread)
- lwc1 $f21, THREAD_FPR21_LS64(\thread)
- lwc1 $f22, THREAD_FPR22_LS64(\thread)
- lwc1 $f23, THREAD_FPR23_LS64(\thread)
- lwc1 $f24, THREAD_FPR24_LS64(\thread)
- lwc1 $f25, THREAD_FPR25_LS64(\thread)
- lwc1 $f26, THREAD_FPR26_LS64(\thread)
- lwc1 $f27, THREAD_FPR27_LS64(\thread)
- lwc1 $f28, THREAD_FPR28_LS64(\thread)
- lwc1 $f29, THREAD_FPR29_LS64(\thread)
- lwc1 $f30, THREAD_FPR30_LS64(\thread)
- lwc1 $f31, THREAD_FPR31_LS64(\thread)
+ l.d $f0, THREAD_FPR0_LS64(\thread)
+ l.d $f2, THREAD_FPR2_LS64(\thread)
+ l.d $f4, THREAD_FPR4_LS64(\thread)
+ l.d $f6, THREAD_FPR6_LS64(\thread)
+ l.d $f8, THREAD_FPR8_LS64(\thread)
+ l.d $f10, THREAD_FPR10_LS64(\thread)
+ l.d $f12, THREAD_FPR12_LS64(\thread)
+ l.d $f14, THREAD_FPR14_LS64(\thread)
+ l.d $f16, THREAD_FPR16_LS64(\thread)
+ l.d $f18, THREAD_FPR18_LS64(\thread)
+ l.d $f20, THREAD_FPR20_LS64(\thread)
+ l.d $f22, THREAD_FPR22_LS64(\thread)
+ l.d $f24, THREAD_FPR24_LS64(\thread)
+ l.d $f26, THREAD_FPR26_LS64(\thread)
+ l.d $f28, THREAD_FPR28_LS64(\thread)
+ l.d $f30, THREAD_FPR30_LS64(\thread)
ctc1 \tmp, fcr31
.set pop
.endm
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 36/48] MIPS: Correct FP ISA requirements
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (32 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 35/48] MIPS: Correct MIPS I FP context layout Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation Maciej W. Rozycki
` (12 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Correct ISA requirements for floating-point instructions:
* the CU3 exception signifies a real COP3 instruction in MIPS I & II,
* the BC1FL and BC1TL instructions are not supported in MIPS I,
* the SQRT.fmt instructions are indeed supported in MIPS II,
* the LDC1 and SDC1 instructions are indeed supported in MIPS32r1,
* the CEIL.W.fmt, FLOOR.W.fmt, ROUND.W.fmt and TRUNC.W.fmt instructions
are indeed supported in MIPS32,
* the CVT.L.fmt and CVT.fmt.L instructions are indeed supported in
MIPS32r2 and MIPS32r6,
* the CEIL.L.fmt, FLOOR.L.fmt, ROUND.L.fmt and TRUNC.L.fmt instructions
are indeed supported in MIPS32r2 and MIPS32r6,
* the RSQRT.fmt and RECIP.fmt instructions are indeed supported in
MIPS64r1,
Also simplify conditionals for MIPS III and MIPS IV FPU instructions and
the handling of the MOVCI minor opcode.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-isa.diff
Index: linux/arch/mips/include/asm/cpu-features.h
===================================================================
--- linux.orig/arch/mips/include/asm/cpu-features.h 2015-04-02 20:27:56.252205000 +0100
+++ linux/arch/mips/include/asm/cpu-features.h 2015-04-02 20:27:57.478232000 +0100
@@ -221,8 +221,11 @@
#define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r)
#define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r)
-#define cpu_has_mips_4_5_r2_r6 (cpu_has_mips_4_5 | cpu_has_mips_r2 | \
- cpu_has_mips_r6)
+#define cpu_has_mips_3_4_5_64_r2_r6 \
+ (cpu_has_mips_3 | cpu_has_mips_4_5_64_r2_r6)
+#define cpu_has_mips_4_5_64_r2_r6 \
+ (cpu_has_mips_4_5 | cpu_has_mips64r1 | \
+ cpu_has_mips_r2 | cpu_has_mips_r6)
#define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2 | cpu_has_mips32r6)
#define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2 | cpu_has_mips64r6)
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:56.948213000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:57.489216000 +0100
@@ -1349,19 +1349,18 @@ asmlinkage void do_cpu(struct pt_regs *r
case 3:
/*
- * Old (MIPS I and MIPS II) processors will set this code
- * for COP1X opcode instructions that replaced the original
- * COP3 space. We don't limit COP1 space instructions in
- * the emulator according to the CPU ISA, so we want to
- * treat COP1X instructions consistently regardless of which
- * code the CPU chose. Therefore we redirect this trap to
- * the FP emulator too.
- *
- * Then some newer FPU-less processors use this code
- * erroneously too, so they are covered by this choice
- * as well.
+ * The COP3 opcode space and consequently the CP0.Status.CU3
+ * bit and the CP0.Cause.CE=3 encoding have been removed as
+ * of the MIPS III ISA. From the MIPS IV and MIPS32r2 ISAs
+ * up the space has been reused for COP1X instructions, that
+ * are enabled by the CP0.Status.CU1 bit and consequently
+ * use the CP0.Cause.CE=1 encoding for Coprocessor Unusable
+ * exceptions. Some FPU-less processors that implement one
+ * of these ISAs however use this code erroneously for COP1X
+ * instructions. Therefore we redirect this trap to the FP
+ * emulator too.
*/
- if (raw_cpu_has_fpu) {
+ if (raw_cpu_has_fpu || !cpu_has_mips_4_5_64_r2_r6) {
force_sig(SIGILL, current);
break;
}
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:54.459192000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:57.493218000 +0100
@@ -1115,17 +1115,18 @@ static int cop1Emulate(struct pt_regs *x
likely = 0;
switch (MIPSInst_RT(ir) & 3) {
case bcfl_op:
- likely = 1;
+ if (cpu_has_mips_2_3_4_5_r)
+ likely = 1;
+ /* Fall through */
case bcf_op:
cond = !cond;
break;
case bctl_op:
- likely = 1;
+ if (cpu_has_mips_2_3_4_5_r)
+ likely = 1;
+ /* Fall through */
case bct_op:
break;
- default:
- /* thats an illegal instruction */
- return SIGILL;
}
set_delay_slot(xcp);
@@ -1165,36 +1166,34 @@ static int cop1Emulate(struct pt_regs *x
switch (MIPSInst_OPCODE(ir)) {
case lwc1_op:
- goto emul;
-
case swc1_op:
goto emul;
case ldc1_op:
case sdc1_op:
- if (cpu_has_mips_2_3_4_5 ||
- cpu_has_mips64)
+ if (cpu_has_mips_2_3_4_5_r)
goto emul;
return SIGILL;
- goto emul;
case cop1_op:
goto emul;
case cop1x_op:
- if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2)
+ if (cpu_has_mips_4_5_64_r2_r6)
/* its one of ours */
goto emul;
return SIGILL;
case spec_op:
- if (!cpu_has_mips_4_5_r)
- return SIGILL;
+ switch (MIPSInst_FUNC(ir)) {
+ case movc_op:
+ if (cpu_has_mips_4_5_r)
+ goto emul;
- if (MIPSInst_FUNC(ir) == movc_op)
- goto emul;
+ return SIGILL;
+ }
break;
}
@@ -1228,7 +1227,7 @@ static int cop1Emulate(struct pt_regs *x
break;
case cop1x_op:
- if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2)
+ if (!cpu_has_mips_4_5_64_r2_r6)
return SIGILL;
sig = fpux_emu(xcp, ctx, ir, fault_addr);
@@ -1561,7 +1560,7 @@ static int fpu_emu(struct pt_regs *xcp,
/* unary ops */
case fsqrt_op:
- if (!cpu_has_mips_4_5_r)
+ if (!cpu_has_mips_2_3_4_5_r)
return SIGILL;
handler.u = ieee754sp_sqrt;
@@ -1573,14 +1572,14 @@ static int fpu_emu(struct pt_regs *xcp,
* achieve full IEEE-754 accuracy - however this emulator does.
*/
case frsqrt_op:
- if (!cpu_has_mips_4_5_r2_r6)
+ if (!cpu_has_mips_4_5_64_r2_r6)
return SIGILL;
handler.u = fpemu_sp_rsqrt;
goto scopuop;
case frecip_op:
- if (!cpu_has_mips_4_5_r2_r6)
+ if (!cpu_has_mips_4_5_64_r2_r6)
return SIGILL;
handler.u = fpemu_sp_recip;
@@ -1682,7 +1681,7 @@ static int fpu_emu(struct pt_regs *xcp,
case ftrunc_op:
case fceil_op:
case ffloor_op:
- if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_2_3_4_5_r)
return SIGILL;
oldrm = ieee754_csr.rm;
@@ -1694,7 +1693,7 @@ static int fpu_emu(struct pt_regs *xcp,
goto copcsr;
case fcvtl_op:
- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_3_4_5_64_r2_r6)
return SIGILL;
SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1706,7 +1705,7 @@ static int fpu_emu(struct pt_regs *xcp,
case ftruncl_op:
case fceill_op:
case ffloorl_op:
- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_3_4_5_64_r2_r6)
return SIGILL;
oldrm = ieee754_csr.rm;
@@ -1775,13 +1774,13 @@ static int fpu_emu(struct pt_regs *xcp,
* achieve full IEEE-754 accuracy - however this emulator does.
*/
case frsqrt_op:
- if (!cpu_has_mips_4_5_r2_r6)
+ if (!cpu_has_mips_4_5_64_r2_r6)
return SIGILL;
handler.u = fpemu_dp_rsqrt;
goto dcopuop;
case frecip_op:
- if (!cpu_has_mips_4_5_r2_r6)
+ if (!cpu_has_mips_4_5_64_r2_r6)
return SIGILL;
handler.u = fpemu_dp_recip;
@@ -1871,7 +1870,7 @@ static int fpu_emu(struct pt_regs *xcp,
goto copcsr;
case fcvtl_op:
- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_3_4_5_64_r2_r6)
return SIGILL;
DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1883,7 +1882,7 @@ static int fpu_emu(struct pt_regs *xcp,
case ftruncl_op:
case fceill_op:
case ffloorl_op:
- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_3_4_5_64_r2_r6)
return SIGILL;
oldrm = ieee754_csr.rm;
@@ -1942,7 +1941,7 @@ static int fpu_emu(struct pt_regs *xcp,
case l_fmt:
- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_3_4_5_64_r2_r6)
return SIGILL;
DIFROMREG(bits, MIPSInst_FS(ir));
@@ -2006,7 +2005,7 @@ static int fpu_emu(struct pt_regs *xcp,
SITOREG(rv.w, MIPSInst_FD(ir));
break;
case l_fmt:
- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+ if (!cpu_has_mips_3_4_5_64_r2_r6)
return SIGILL;
DITOREG(rv.l, MIPSInst_FD(ir));
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (33 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 36/48] MIPS: Correct FP ISA requirements Maciej W. Rozycki
@ 2015-04-03 22:26 ` Maciej W. Rozycki
2016-01-20 10:50 ` Aurelien Jarno
2015-04-03 22:27 ` [PATCH 38/48] MIPS: math-emu: Move long fixed-point support into an `ar' library Maciej W. Rozycki
` (11 subsequent siblings)
46 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Restore EPC at the branch whose delay slot is emulated if the delay-slot
instruction signals. This is so that code in `fpu_emulator_cop1Handler'
does not see EPC having advanced and mistakenly successfully resume
userland execution from the location at the branch target in that case.
Restoring EPC guarantees an immediate exit from the emulation loop and
if EPC hasn't advanced at all since entering the loop, also issuing the
signal reported by the delay-slot instruction.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-bc1x-sigill.patch
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:57.493218000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:57.710224000 +0100
@@ -1134,6 +1134,14 @@ static int cop1Emulate(struct pt_regs *x
/*
* Branch taken: emulate dslot instruction
*/
+ unsigned long bcpc;
+
+ /*
+ * Remember EPC at the branch to point back
+ * at so that any delay-slot instruction
+ * signal is not silently ignored.
+ */
+ bcpc = xcp->cp0_epc;
xcp->cp0_epc += dec_insn.pc_inc;
contpc = MIPSInst_SIMM(ir);
@@ -1159,7 +1167,15 @@ static int cop1Emulate(struct pt_regs *x
* Single step the non-CP1
* instruction in the dslot.
*/
- return mips_dsemul(xcp, ir, contpc);
+ sig = mips_dsemul(xcp, ir,
+ contpc);
+ if (sig)
+ xcp->cp0_epc = bcpc;
+ /*
+ * SIGILL forces out of
+ * the emulation loop.
+ */
+ return sig ? sig : SIGILL;
}
} else
contpc = (xcp->cp0_epc + (contpc << 2));
@@ -1174,7 +1190,7 @@ static int cop1Emulate(struct pt_regs *x
if (cpu_has_mips_2_3_4_5_r)
goto emul;
- return SIGILL;
+ goto bc_sigill;
case cop1_op:
goto emul;
@@ -1184,7 +1200,7 @@ static int cop1Emulate(struct pt_regs *x
/* its one of ours */
goto emul;
- return SIGILL;
+ goto bc_sigill;
case spec_op:
switch (MIPSInst_FUNC(ir)) {
@@ -1192,16 +1208,24 @@ static int cop1Emulate(struct pt_regs *x
if (cpu_has_mips_4_5_r)
goto emul;
- return SIGILL;
+ goto bc_sigill;
}
break;
+
+ bc_sigill:
+ xcp->cp0_epc = bcpc;
+ return SIGILL;
}
/*
* Single step the non-cp1
* instruction in the dslot
*/
- return mips_dsemul(xcp, ir, contpc);
+ sig = mips_dsemul(xcp, ir, contpc);
+ if (sig)
+ xcp->cp0_epc = bcpc;
+ /* SIGILL forces out of the emulation loop. */
+ return sig ? sig : SIGILL;
} else if (likely) { /* branch not taken */
/*
* branch likely nullifies
Index: linux/arch/mips/math-emu/dsemul.c
===================================================================
--- linux.orig/arch/mips/math-emu/dsemul.c 2015-04-02 20:27:57.133225000 +0100
+++ linux/arch/mips/math-emu/dsemul.c 2015-04-02 20:27:57.713219000 +0100
@@ -96,7 +96,7 @@ int mips_dsemul(struct pt_regs *regs, mi
flush_cache_sigtramp((unsigned long)&fr->emul);
- return SIGILL; /* force out of emulation loop */
+ return 0;
}
int do_dsemulret(struct pt_regs *xcp)
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 38/48] MIPS: math-emu: Move long fixed-point support into an `ar' library
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (34 preceding siblings ...)
2015-04-03 22:26 ` [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 39/48] MIPS: Respect the FCSR exception mask for `si_code' Maciej W. Rozycki
` (10 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Complement 593d33fe [MIPS: math-emu: Move various objects into an ar
library.] and also move sp_tlong.o, sp_flong.o, dp_tlong.o, and
dp_flong.o into an `ar' library. These objects implement long
fixed-point format support that can be omitted from MIPS I, MIPS II and
MIPS32r1 configurations.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
Ralf,
Please note however that contrary to your comment for 593d33fe
sp_sqrt.o and dp_sqrt.o will be omitted from MIPS I configurations only.
Maciej
linux-mips-emu-lib.diff
Index: linux/arch/mips/math-emu/Makefile
===================================================================
--- linux.orig/arch/mips/math-emu/Makefile 2015-04-02 20:18:48.993504000 +0100
+++ linux/arch/mips/math-emu/Makefile 2015-04-02 20:27:57.896229000 +0100
@@ -2,12 +2,15 @@
# Makefile for the Linux/MIPS kernel FPU emulation.
#
-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_tint.o \
- dp_fint.o dp_tlong.o dp_flong.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_tlong.o sp_flong.o dsemul.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_tint.o dp_fint.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 \
+ dsemul.o
-lib-y += ieee754d.o dp_sqrt.o sp_sqrt.o
+lib-y += ieee754d.o \
+ dp_tlong.o dp_flong.o dp_sqrt.o \
+ sp_tlong.o sp_flong.o sp_sqrt.o
obj-$(CONFIG_DEBUG_FS) += me-debugfs.o
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 39/48] MIPS: Respect the FCSR exception mask for `si_code'
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (35 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 38/48] MIPS: math-emu: Move long fixed-point support into an `ar' library Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 40/48] MIPS: Always clear FCSR cause bits after emulation Maciej W. Rozycki
` (9 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Respect the FCSR exception mask when interpreting the IEEE 754 exception
condition to report with SIGFPE in `si_code', so as not to use one that
has been masked where a different one set in parallel caused the FPE
hardware exception to trigger. As per the IEEE Std 754 the Inexact
exception can happen together with Overflow or Underflow.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-fpe-except-mask.diff
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:57.489216000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:58.065226000 +0100
@@ -12,6 +12,7 @@
* Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2014, Imagination Technologies Ltd.
*/
+#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/context_tracking.h>
@@ -817,7 +818,15 @@ asmlinkage void do_fpe(struct pt_regs *r
process_fpemu_return(sig, fault_addr);
goto out;
- } else if (fcr31 & FPU_CSR_INV_X)
+ }
+
+ /*
+ * Inexact can happen together with Overflow or Underflow.
+ * Respect the mask to deliver the correct exception.
+ */
+ fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
+ (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
+ if (fcr31 & FPU_CSR_INV_X)
info.si_code = FPE_FLTINV;
else if (fcr31 & FPU_CSR_DIV_X)
info.si_code = FPE_FLTDIV;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 40/48] MIPS: Always clear FCSR cause bits after emulation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (36 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 39/48] MIPS: Respect the FCSR exception mask for `si_code' Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 41/48] MIPS: Set `si_code' for SIGFPE signals sent from emulation too Maciej W. Rozycki
` (8 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Clear any FCSR cause bits recorded in the saved FPU context after
emulation in all cases rather than in `do_fpe' only, so that any
unmasked IEEE 754 exception left from emulation does not cause a fatal
kernel-mode FPE hardware exception with the CTC1 instruction used by the
kernel to subsequently restore FCSR hardware from the saved FPU context.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-fpe-emu-fcsr-cause.diff
Index: linux/arch/mips/kernel/mips-r2-to-r6-emul.c
===================================================================
--- linux.orig/arch/mips/kernel/mips-r2-to-r6-emul.c 2015-04-02 20:27:53.338178000 +0100
+++ linux/arch/mips/kernel/mips-r2-to-r6-emul.c 2015-04-02 20:27:58.241225000 +0100
@@ -1170,6 +1170,12 @@ int mipsr2_decoder(struct pt_regs *regs,
&fault_addr);
/*
+ * We can't allow the emulated instruction to leave any of
+ * the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
+ /*
* this is a tricky issue - lose_fpu() uses LL/SC atomics
* if FPU is owned and effectively cancels user level LL/SC.
* So, it could be logical to don't restore FPU ownership here.
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:58.065226000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:58.244233000 +0100
@@ -761,6 +761,12 @@ static int simulate_fp(struct pt_regs *r
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
&fault_addr);
+ /*
+ * We can't allow the emulated instruction to leave any of
+ * the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
/* If something went wrong, signal */
process_fpemu_return(sig, fault_addr);
@@ -807,7 +813,7 @@ asmlinkage void do_fpe(struct pt_regs *r
/*
* We can't allow the emulated instruction to leave any of
- * the cause bit set in $fcr31.
+ * the cause bits set in $fcr31.
*/
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
@@ -1384,6 +1390,13 @@ asmlinkage void do_cpu(struct pt_regs *r
sig = fpu_emulator_cop1Handler(regs,
¤t->thread.fpu,
0, &fault_addr);
+
+ /*
+ * We can't allow the emulated instruction to leave
+ * any of the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
if (!process_fpemu_return(sig, fault_addr) && !err)
mt_ase_fp_affinity();
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 41/48] MIPS: Set `si_code' for SIGFPE signals sent from emulation too
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (37 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 40/48] MIPS: Always clear FCSR cause bits after emulation Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 42/48] MIPS: Correct ISA masking in FPU feature determination Maciej W. Rozycki
` (7 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Rework `process_fpemu_return' and move IEEE 754 exception interpretation
there, from `do_fpe'. Record the cause bits set in FCSR before they are
cleared and pass them through to `process_fpemu_return' so as to set
`si_code' correctly too for SIGFPE signals sent from emulation rather
than those issued by hardware with the FPE processor exception only.
For simplicity `mipsr2_decoder' assumes `*fcr31' has been preinitialised
and only sets it to anything if an FPU instruction has been emulated,
which in turn is the only case SIGFPE can be issued for here.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-fpe-emu-siginfo.diff
Index: linux/arch/mips/include/asm/fpu_emulator.h
===================================================================
--- linux.orig/arch/mips/include/asm/fpu_emulator.h 2015-04-02 20:18:48.693493000 +0100
+++ linux/arch/mips/include/asm/fpu_emulator.h 2015-04-02 20:27:58.453234000 +0100
@@ -65,7 +65,8 @@ extern int do_dsemulret(struct pt_regs *
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_struct *ctx, int has_fpu,
void *__user *fault_addr);
-int process_fpemu_return(int sig, void __user *fault_addr);
+int process_fpemu_return(int sig, void __user *fault_addr,
+ unsigned long fcr31);
int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
unsigned long *contpc);
Index: linux/arch/mips/include/asm/mips-r2-to-r6-emul.h
===================================================================
--- linux.orig/arch/mips/include/asm/mips-r2-to-r6-emul.h 2015-04-02 20:27:53.724187000 +0100
+++ linux/arch/mips/include/asm/mips-r2-to-r6-emul.h 2015-04-02 20:27:58.456228000 +0100
@@ -84,11 +84,16 @@ extern void do_trap_or_bp(struct pt_regs
#ifndef CONFIG_MIPSR2_TO_R6_EMULATOR
static int mipsr2_emulation;
-static inline int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; };
+static inline int mipsr2_decoder(struct pt_regs *regs, u32 inst,
+ unsigned long *fcr31)
+{
+ return 0;
+};
#else
/* MIPS R2 Emulator ON/OFF */
extern int mipsr2_emulation;
-extern int mipsr2_decoder(struct pt_regs *regs, u32 inst);
+extern int mipsr2_decoder(struct pt_regs *regs, u32 inst,
+ unsigned long *fcr31);
#endif /* CONFIG_MIPSR2_TO_R6_EMULATOR */
#define NO_R6EMU (cpu_has_mips_r6 && !mipsr2_emulation)
Index: linux/arch/mips/kernel/mips-r2-to-r6-emul.c
===================================================================
--- linux.orig/arch/mips/kernel/mips-r2-to-r6-emul.c 2015-04-02 20:27:58.241225000 +0100
+++ linux/arch/mips/kernel/mips-r2-to-r6-emul.c 2015-04-02 20:27:58.460231000 +0100
@@ -898,8 +898,9 @@ static inline int mipsr2_find_op_func(st
* mipsr2_decoder: Decode and emulate a MIPS R2 instruction
* @regs: Process register set
* @inst: Instruction to decode and emulate
+ * @fcr31: Floating Point Control and Status Register returned
*/
-int mipsr2_decoder(struct pt_regs *regs, u32 inst)
+int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
{
int err = 0;
unsigned long vaddr;
@@ -1168,6 +1169,7 @@ int mipsr2_decoder(struct pt_regs *regs,
err = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0,
&fault_addr);
+ *fcr31 = current->thread.fpu.fcr31;
/*
* We can't allow the emulated instruction to leave any of
Index: linux/arch/mips/kernel/traps.c
===================================================================
--- linux.orig/arch/mips/kernel/traps.c 2015-04-02 20:27:58.244233000 +0100
+++ linux/arch/mips/kernel/traps.c 2015-04-02 20:27:58.463232000 +0100
@@ -700,29 +700,60 @@ asmlinkage void do_ov(struct pt_regs *re
exception_exit(prev_state);
}
-int process_fpemu_return(int sig, void __user *fault_addr)
+int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
{
- if (sig == SIGSEGV || sig == SIGBUS) {
- struct siginfo si = {0};
+ struct siginfo si = { 0 };
+
+ switch (sig) {
+ case 0:
+ return 0;
+
+ case SIGFPE:
si.si_addr = fault_addr;
si.si_signo = sig;
- if (sig == SIGSEGV) {
- down_read(¤t->mm->mmap_sem);
- if (find_vma(current->mm, (unsigned long)fault_addr))
- si.si_code = SEGV_ACCERR;
- else
- si.si_code = SEGV_MAPERR;
- up_read(¤t->mm->mmap_sem);
- } else {
- si.si_code = BUS_ADRERR;
- }
+ /*
+ * Inexact can happen together with Overflow or Underflow.
+ * Respect the mask to deliver the correct exception.
+ */
+ fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
+ (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
+ if (fcr31 & FPU_CSR_INV_X)
+ si.si_code = FPE_FLTINV;
+ else if (fcr31 & FPU_CSR_DIV_X)
+ si.si_code = FPE_FLTDIV;
+ else if (fcr31 & FPU_CSR_OVF_X)
+ si.si_code = FPE_FLTOVF;
+ else if (fcr31 & FPU_CSR_UDF_X)
+ si.si_code = FPE_FLTUND;
+ else if (fcr31 & FPU_CSR_INE_X)
+ si.si_code = FPE_FLTRES;
+ else
+ si.si_code = __SI_FAULT;
force_sig_info(sig, &si, current);
return 1;
- } else if (sig) {
+
+ case SIGBUS:
+ si.si_addr = fault_addr;
+ si.si_signo = sig;
+ si.si_code = BUS_ADRERR;
+ force_sig_info(sig, &si, current);
+ return 1;
+
+ case SIGSEGV:
+ si.si_addr = fault_addr;
+ si.si_signo = sig;
+ down_read(¤t->mm->mmap_sem);
+ if (find_vma(current->mm, (unsigned long)fault_addr))
+ si.si_code = SEGV_ACCERR;
+ else
+ si.si_code = SEGV_MAPERR;
+ up_read(¤t->mm->mmap_sem);
+ force_sig_info(sig, &si, current);
+ return 1;
+
+ default:
force_sig(sig, current);
return 1;
- } else {
- return 0;
}
}
@@ -730,7 +761,8 @@ static int simulate_fp(struct pt_regs *r
unsigned long old_epc, unsigned long old_ra)
{
union mips_instruction inst = { .word = opcode };
- void __user *fault_addr = NULL;
+ void __user *fault_addr;
+ unsigned long fcr31;
int sig;
/* If it's obviously not an FP instruction, skip it */
@@ -760,6 +792,7 @@ static int simulate_fp(struct pt_regs *r
/* Run the emulator */
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
&fault_addr);
+ fcr31 = current->thread.fpu.fcr31;
/*
* We can't allow the emulated instruction to leave any of
@@ -767,12 +800,12 @@ static int simulate_fp(struct pt_regs *r
*/
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
- /* If something went wrong, signal */
- process_fpemu_return(sig, fault_addr);
-
/* Restore the hardware register state */
own_fpu(1);
+ /* Send a signal if required. */
+ process_fpemu_return(sig, fault_addr, fcr31);
+
return 0;
}
@@ -782,7 +815,8 @@ static int simulate_fp(struct pt_regs *r
asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
{
enum ctx_state prev_state;
- siginfo_t info = {0};
+ void __user *fault_addr;
+ int sig;
prev_state = exception_enter();
if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
@@ -791,9 +825,6 @@ asmlinkage void do_fpe(struct pt_regs *r
die_if_kernel("FP exception in kernel code", regs);
if (fcr31 & FPU_CSR_UNI_X) {
- int sig;
- void __user *fault_addr = NULL;
-
/*
* Unimplemented operation exception. If we've got the full
* software emulator on-board, let's use it...
@@ -810,6 +841,7 @@ asmlinkage void do_fpe(struct pt_regs *r
/* Run the emulator */
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
&fault_addr);
+ fcr31 = current->thread.fpu.fcr31;
/*
* We can't allow the emulated instruction to leave any of
@@ -819,35 +851,13 @@ asmlinkage void do_fpe(struct pt_regs *r
/* Restore the hardware register state */
own_fpu(1); /* Using the FPU again. */
-
- /* If something went wrong, signal */
- process_fpemu_return(sig, fault_addr);
-
- goto out;
+ } else {
+ sig = SIGFPE;
+ fault_addr = (void __user *) regs->cp0_epc;
}
- /*
- * Inexact can happen together with Overflow or Underflow.
- * Respect the mask to deliver the correct exception.
- */
- fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
- (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
- if (fcr31 & FPU_CSR_INV_X)
- info.si_code = FPE_FLTINV;
- else if (fcr31 & FPU_CSR_DIV_X)
- info.si_code = FPE_FLTDIV;
- else if (fcr31 & FPU_CSR_OVF_X)
- info.si_code = FPE_FLTOVF;
- else if (fcr31 & FPU_CSR_UDF_X)
- info.si_code = FPE_FLTUND;
- else if (fcr31 & FPU_CSR_INE_X)
- info.si_code = FPE_FLTRES;
- else
- info.si_code = __SI_FAULT;
- info.si_signo = SIGFPE;
- info.si_errno = 0;
- info.si_addr = (void __user *) regs->cp0_epc;
- force_sig_info(SIGFPE, &info, current);
+ /* Send a signal if required. */
+ process_fpemu_return(sig, fault_addr, fcr31);
out:
exception_exit(prev_state);
@@ -1050,7 +1060,9 @@ asmlinkage void do_ri(struct pt_regs *re
if (mipsr2_emulation && cpu_has_mips_r6 &&
likely(user_mode(regs)) &&
likely(get_user(opcode, epc) >= 0)) {
- status = mipsr2_decoder(regs, opcode);
+ unsigned long fcr31 = 0;
+
+ status = mipsr2_decoder(regs, opcode, &fcr31);
switch (status) {
case 0:
case SIGEMT:
@@ -1060,7 +1072,8 @@ asmlinkage void do_ri(struct pt_regs *re
goto no_r2_instr;
default:
process_fpemu_return(status,
- ¤t->thread.cp0_baduaddr);
+ ¤t->thread.cp0_baduaddr,
+ fcr31);
task_thread_info(current)->r2_emul_return = 1;
return;
}
@@ -1307,10 +1320,13 @@ asmlinkage void do_cpu(struct pt_regs *r
enum ctx_state prev_state;
unsigned int __user *epc;
unsigned long old_epc, old31;
+ void __user *fault_addr;
unsigned int opcode;
+ unsigned long fcr31;
unsigned int cpid;
int status, err;
unsigned long __maybe_unused flags;
+ int sig;
prev_state = exception_enter();
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
@@ -1384,22 +1400,22 @@ asmlinkage void do_cpu(struct pt_regs *r
case 1:
err = enable_restore_fp_context(0);
- if (!raw_cpu_has_fpu || err) {
- int sig;
- void __user *fault_addr = NULL;
- sig = fpu_emulator_cop1Handler(regs,
- ¤t->thread.fpu,
- 0, &fault_addr);
+ if (raw_cpu_has_fpu && !err)
+ break;
- /*
- * We can't allow the emulated instruction to leave
- * any of the cause bits set in $fcr31.
- */
- current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+ sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0,
+ &fault_addr);
+ fcr31 = current->thread.fpu.fcr31;
- if (!process_fpemu_return(sig, fault_addr) && !err)
- mt_ase_fp_affinity();
- }
+ /*
+ * We can't allow the emulated instruction to leave
+ * any of the cause bits set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
+ /* Send a signal if required. */
+ if (!process_fpemu_return(sig, fault_addr, fcr31) && !err)
+ mt_ase_fp_affinity();
break;
Index: linux/arch/mips/kernel/unaligned.c
===================================================================
--- linux.orig/arch/mips/kernel/unaligned.c 2015-04-02 20:18:48.702496000 +0100
+++ linux/arch/mips/kernel/unaligned.c 2015-04-02 20:27:58.466232000 +0100
@@ -1076,7 +1076,7 @@ static void emulate_load_store_insn(stru
own_fpu(1); /* Restore FPU state. */
/* Signal if something went wrong. */
- process_fpemu_return(res, fault_addr);
+ process_fpemu_return(res, fault_addr, 0);
if (res == 0)
break;
@@ -1511,7 +1511,7 @@ static void emulate_load_store_microMIPS
own_fpu(1); /* restore FPU state */
/* If something went wrong, signal */
- process_fpemu_return(res, fault_addr);
+ process_fpemu_return(res, fault_addr, 0);
if (res == 0)
goto success;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 42/48] MIPS: Correct ISA masking in FPU feature determination
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (38 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 41/48] MIPS: Set `si_code' for SIGFPE signals sent from emulation too Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 43/48] MIPS: math-emu: Set FIR feature flags for full emulation Maciej W. Rozycki
` (6 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Leonid Yegoshin, linux-mips
Correct an ISA level determination problem introduced with 8b8aa636
[MIPS: kernel: cpu-probe.c: Add support for MIPS R6], reverting explicit
masking against individual `MIPS_CPU_ISA_*' macros in FPU feature
determination.
Feature macros such as `cpu_has_mips_r' cannot be used here, because
they operate on CPU #0 and we want to refer to the current CPU instead.
They cannot be used for masking against the current CPU either because
they mask against CPU #0 too, e.g.:
# define cpu_has_mips32r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1)
Cc: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-fpu-probe-isa.diff
Index: linux/arch/mips/kernel/cpu-probe.c
===================================================================
--- linux.orig/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:52.971189000 +0100
+++ linux/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:58.700229000 +0100
@@ -1367,7 +1367,9 @@ void cpu_probe(void)
if (c->options & MIPS_CPU_FPU) {
c->fpu_id = cpu_get_fpu_id();
- if (c->isa_level & cpu_has_mips_r) {
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+ MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
if (c->fpu_id & MIPS_FPIR_3D)
c->ases |= MIPS_ASE_MIPS3D;
if (c->fpu_id & MIPS_FPIR_FREP)
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 43/48] MIPS: math-emu: Set FIR feature flags for full emulation
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (39 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 42/48] MIPS: Correct ISA masking in FPU feature determination Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 23:18 ` Sergei Shtylyov
2015-04-03 22:27 ` [PATCH 44/48] MIPS: math-emu: Implement the FCCR, FEXR and FENR registers Maciej W. Rozycki
` (5 subsequent siblings)
46 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Implement FIR feature flags in the FPU emulator according to features
supported and architecture level requirements. The W, L and F64 bits
have only been added at level #2 even though the features they refer to
were also included with the MIPS64r1 ISA and the W fixed-point format
also with the MIPS32r1 ISA.
This is only relevant for the full emulation mode and the emulated CFC1
instruction as well as ptrace(2) accesses.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-fir.diff
Index: linux/arch/mips/kernel/cpu-probe.c
===================================================================
--- linux.orig/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:58.700229000 +0100
+++ linux/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:58.890231000 +0100
@@ -20,6 +20,7 @@
#include <asm/bugs.h>
#include <asm/cpu.h>
+#include <asm/cpu-features.h>
#include <asm/cpu-type.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
@@ -31,11 +32,30 @@
#include <asm/spram.h>
#include <asm/uaccess.h>
+/*
+ * Set the FIR feature flags for the FPU emulator.
+ */
+static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
+{
+ u32 value;
+
+ value = 0;
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+ MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
+ value |= MIPS_FPIR_D | MIPS_FPIR_S;
+ if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
+ value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
+ c->fpu_id = value;
+}
+
static int mips_fpu_disabled;
static int __init fpu_disable(char *s)
{
- cpu_data[0].options &= ~MIPS_CPU_FPU;
+ boot_cpu_data.options &= ~MIPS_CPU_FPU;
+ cpu_set_nofpu_id(&boot_cpu_data);
mips_fpu_disabled = 1;
return 1;
@@ -1375,7 +1395,8 @@ void cpu_probe(void)
if (c->fpu_id & MIPS_FPIR_FREP)
c->options |= MIPS_CPU_FRE;
}
- }
+ } else
+ cpu_set_nofpu_id(c);
if (cpu_has_mips_r2_r6) {
c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:57.710224000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:58.894230000 +0100
@@ -45,6 +45,7 @@
#include <asm/signal.h>
#include <asm/uaccess.h>
+#include <asm/cpu-info.h>
#include <asm/processor.h>
#include <asm/fpu_emulator.h>
#include <asm/fpu.h>
@@ -853,7 +854,7 @@ static inline void cop1_cfc(struct pt_re
(void *)xcp->cp0_epc,
MIPSInst_RT(ir), value);
} else if (MIPSInst_RD(ir) == FPCREG_RID)
- value = 0;
+ value = current_cpu_data.fpu_id;
else
value = 0;
if (MIPSInst_RT(ir))
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 44/48] MIPS: math-emu: Implement the FCCR, FEXR and FENR registers
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (40 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 43/48] MIPS: math-emu: Set FIR feature flags for full emulation Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 45/48] MIPS: math-emu: Define IEEE 754-2008 feature control bits Maciej W. Rozycki
` (4 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Implement the FCCR, FEXR and FENR "shadow" FPU registers for the
architecture levels that include them, for the CFC1 and CTC1
instructions in the full emulation mode.
For completeness add macros for the CP1 UFR and UNFR registers too, no
actual implementation though.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
Ralf,
Again, this causes a flood of checkpatch.pl errors:
ERROR: Macros with complex values should be enclosed in parentheses
#11: FILE: arch/mips/include/asm/mipsregs.h:680:
+#define CP1_REVISION $0
ERROR: Macros with complex values should be enclosed in parentheses
#12: FILE: arch/mips/include/asm/mipsregs.h:681:
+#define CP1_UFR $1
ERROR: Macros with complex values should be enclosed in parentheses
#13: FILE: arch/mips/include/asm/mipsregs.h:682:
+#define CP1_UNFR $4
ERROR: Macros with complex values should be enclosed in parentheses
#14: FILE: arch/mips/include/asm/mipsregs.h:683:
+#define CP1_FCCR $25
ERROR: Macros with complex values should be enclosed in parentheses
#15: FILE: arch/mips/include/asm/mipsregs.h:684:
+#define CP1_FEXR $26
ERROR: Macros with complex values should be enclosed in parentheses
#16: FILE: arch/mips/include/asm/mipsregs.h:685:
+#define CP1_FENR $28
ERROR: Macros with complex values should be enclosed in parentheses
#17: FILE: arch/mips/include/asm/mipsregs.h:686:
+#define CP1_STATUS $31
that I think we'll just have to live with, there's nothing wrong with
these macros and their intended purpose.
Maciej
linux-mips-emu-fcr.diff
Index: linux/arch/mips/include/asm/mipsregs.h
===================================================================
--- linux.orig/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:52.242161000 +0100
+++ linux/arch/mips/include/asm/mipsregs.h 2015-04-02 20:27:59.089235000 +0100
@@ -677,8 +677,13 @@
/*
* Coprocessor 1 (FPU) register names
*/
-#define CP1_REVISION $0
-#define CP1_STATUS $31
+#define CP1_REVISION $0
+#define CP1_UFR $1
+#define CP1_UNFR $4
+#define CP1_FCCR $25
+#define CP1_FEXR $26
+#define CP1_FENR $28
+#define CP1_STATUS $31
/*
@@ -694,18 +699,58 @@
#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) condition codes register.
+ */
+#define MIPS_FCCR_CONDX_S 0
+#define MIPS_FCCR_CONDX (_ULCAST_(255) << MIPS_FCCR_CONDX_S)
+#define MIPS_FCCR_COND0_S 0
+#define MIPS_FCCR_COND0 (_ULCAST_(1) << MIPS_FCCR_COND0_S)
+#define MIPS_FCCR_COND1_S 1
+#define MIPS_FCCR_COND1 (_ULCAST_(1) << MIPS_FCCR_COND1_S)
+#define MIPS_FCCR_COND2_S 2
+#define MIPS_FCCR_COND2 (_ULCAST_(1) << MIPS_FCCR_COND2_S)
+#define MIPS_FCCR_COND3_S 3
+#define MIPS_FCCR_COND3 (_ULCAST_(1) << MIPS_FCCR_COND3_S)
+#define MIPS_FCCR_COND4_S 4
+#define MIPS_FCCR_COND4 (_ULCAST_(1) << MIPS_FCCR_COND4_S)
+#define MIPS_FCCR_COND5_S 5
+#define MIPS_FCCR_COND5 (_ULCAST_(1) << MIPS_FCCR_COND5_S)
+#define MIPS_FCCR_COND6_S 6
+#define MIPS_FCCR_COND6 (_ULCAST_(1) << MIPS_FCCR_COND6_S)
+#define MIPS_FCCR_COND7_S 7
+#define MIPS_FCCR_COND7 (_ULCAST_(1) << MIPS_FCCR_COND7_S)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) enables register.
+ */
+#define MIPS_FENR_FS_S 2
+#define MIPS_FENR_FS (_ULCAST_(1) << MIPS_FENR_FS_S)
+
+/*
* FPU Status Register Values
*/
-#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
-#define FPU_CSR_COND 0x00800000 /* $fcc0 */
-#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
-#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
-#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
-#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
-#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
-#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
-#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
-#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
+#define FPU_CSR_COND_S 23 /* $fcc0 */
+#define FPU_CSR_COND (_ULCAST_(1) << FPU_CSR_COND_S)
+
+#define FPU_CSR_FS_S 24 /* flush denormalised results to 0 */
+#define FPU_CSR_FS (_ULCAST_(1) << FPU_CSR_FS_S)
+
+#define FPU_CSR_CONDX_S 25 /* $fcc[7:1] */
+#define FPU_CSR_CONDX (_ULCAST_(127) << FPU_CSR_CONDX_S)
+#define FPU_CSR_COND1_S 25 /* $fcc1 */
+#define FPU_CSR_COND1 (_ULCAST_(1) << FPU_CSR_COND1_S)
+#define FPU_CSR_COND2_S 26 /* $fcc2 */
+#define FPU_CSR_COND2 (_ULCAST_(1) << FPU_CSR_COND2_S)
+#define FPU_CSR_COND3_S 27 /* $fcc3 */
+#define FPU_CSR_COND3 (_ULCAST_(1) << FPU_CSR_COND3_S)
+#define FPU_CSR_COND4_S 28 /* $fcc4 */
+#define FPU_CSR_COND4 (_ULCAST_(1) << FPU_CSR_COND4_S)
+#define FPU_CSR_COND5_S 29 /* $fcc5 */
+#define FPU_CSR_COND5 (_ULCAST_(1) << FPU_CSR_COND5_S)
+#define FPU_CSR_COND6_S 30 /* $fcc6 */
+#define FPU_CSR_COND6 (_ULCAST_(1) << FPU_CSR_COND6_S)
+#define FPU_CSR_COND7_S 31 /* $fcc7 */
+#define FPU_CSR_COND7 (_ULCAST_(1) << FPU_CSR_COND7_S)
/*
* Bits 18 - 20 of the FPU Status Register will be read as 0,
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:58.894230000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:59.094235000 +0100
@@ -64,11 +64,14 @@ static int fpux_emu(struct pt_regs *,
/* Control registers */
#define FPCREG_RID 0 /* $0 = revision id */
+#define FPCREG_FCCR 25 /* $25 = fccr */
+#define FPCREG_FEXR 26 /* $26 = fexr */
+#define FPCREG_FENR 28 /* $28 = fenr */
#define FPCREG_CSR 31 /* $31 = csr */
/* convert condition code register number to csr bit */
const unsigned int fpucondbit[8] = {
- FPU_CSR_COND0,
+ FPU_CSR_COND,
FPU_CSR_COND1,
FPU_CSR_COND2,
FPU_CSR_COND3,
@@ -846,17 +849,53 @@ do { \
static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
mips_instruction ir)
{
- u32 value;
+ u32 fcr31 = ctx->fcr31;
+ u32 value = 0;
- if (MIPSInst_RD(ir) == FPCREG_CSR) {
- value = ctx->fcr31;
+ switch (MIPSInst_RD(ir)) {
+ case FPCREG_CSR:
+ value = fcr31;
pr_debug("%p gpr[%d]<-csr=%08x\n",
- (void *)xcp->cp0_epc,
- MIPSInst_RT(ir), value);
- } else if (MIPSInst_RD(ir) == FPCREG_RID)
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ break;
+
+ case FPCREG_FENR:
+ if (!cpu_has_mips_r)
+ break;
+ value = (fcr31 >> (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
+ MIPS_FENR_FS;
+ value |= fcr31 & (FPU_CSR_ALL_E | FPU_CSR_RM);
+ pr_debug("%p gpr[%d]<-enr=%08x\n",
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ break;
+
+ case FPCREG_FEXR:
+ if (!cpu_has_mips_r)
+ break;
+ value = fcr31 & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
+ pr_debug("%p gpr[%d]<-exr=%08x\n",
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ break;
+
+ case FPCREG_FCCR:
+ if (!cpu_has_mips_r)
+ break;
+ value = (fcr31 >> (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
+ MIPS_FCCR_COND0;
+ value |= (fcr31 >> (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
+ (MIPS_FCCR_CONDX & ~MIPS_FCCR_COND0);
+ pr_debug("%p gpr[%d]<-ccr=%08x\n",
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ break;
+
+ case FPCREG_RID:
value = current_cpu_data.fpu_id;
- else
- value = 0;
+ break;
+
+ default:
+ break;
+ }
+
if (MIPSInst_RT(ir))
xcp->regs[MIPSInst_RT(ir)] = value;
}
@@ -867,6 +906,7 @@ static inline void cop1_cfc(struct pt_re
static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
mips_instruction ir)
{
+ u32 fcr31 = ctx->fcr31;
u32 value;
if (MIPSInst_RT(ir) == 0)
@@ -874,16 +914,52 @@ static inline void cop1_ctc(struct pt_re
else
value = xcp->regs[MIPSInst_RT(ir)];
- /* we only have one writable control reg
- */
- if (MIPSInst_RD(ir) == FPCREG_CSR) {
+ switch (MIPSInst_RD(ir)) {
+ case FPCREG_CSR:
pr_debug("%p gpr[%d]->csr=%08x\n",
- (void *)xcp->cp0_epc,
- MIPSInst_RT(ir), value);
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
/* Don't write reserved bits. */
- ctx->fcr31 = value & ~FPU_CSR_RSVD;
+ fcr31 = value & ~FPU_CSR_RSVD;
+ break;
+
+ case FPCREG_FENR:
+ if (!cpu_has_mips_r)
+ break;
+ pr_debug("%p gpr[%d]->enr=%08x\n",
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ fcr31 &= ~(FPU_CSR_FS | FPU_CSR_ALL_E | FPU_CSR_RM);
+ fcr31 |= (value << (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
+ FPU_CSR_FS;
+ fcr31 |= value & (FPU_CSR_ALL_E | FPU_CSR_RM);
+ break;
+
+ case FPCREG_FEXR:
+ if (!cpu_has_mips_r)
+ break;
+ pr_debug("%p gpr[%d]->exr=%08x\n",
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ fcr31 &= ~(FPU_CSR_ALL_X | FPU_CSR_ALL_S);
+ fcr31 |= value & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
+ break;
+
+ case FPCREG_FCCR:
+ if (!cpu_has_mips_r)
+ break;
+ pr_debug("%p gpr[%d]->ccr=%08x\n",
+ (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+ fcr31 &= ~(FPU_CSR_CONDX | FPU_CSR_COND);
+ fcr31 |= (value << (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
+ FPU_CSR_COND;
+ fcr31 |= (value << (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
+ FPU_CSR_CONDX;
+ break;
+
+ default:
+ break;
}
+
+ ctx->fcr31 = fcr31;
}
/*
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 45/48] MIPS: math-emu: Define IEEE 754-2008 feature control bits
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (41 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 44/48] MIPS: math-emu: Implement the FCCR, FEXR and FENR registers Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again Maciej W. Rozycki
` (3 subsequent siblings)
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Define IEEE 754-2008 feature control bits: FIR.HAS2008, FCSR.ABS2008 and
FCSR.NAN2008, and update the `_ieee754_csr' structure accordingly.
For completeness define FIR.UFRP too.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-cp1-fcsr.diff
Index: linux/arch/mips/include/asm/mipsregs.h
===================================================================
--- linux.orig/arch/mips/include/asm/mipsregs.h 2015-04-03 15:55:16.641969000 +0100
+++ linux/arch/mips/include/asm/mipsregs.h 2015-04-03 15:55:17.630977000 +0100
@@ -696,6 +696,8 @@
#define MIPS_FPIR_W (_ULCAST_(1) << 20)
#define MIPS_FPIR_L (_ULCAST_(1) << 21)
#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
+#define MIPS_FPIR_HAS2008 (_ULCAST_(1) << 23)
+#define MIPS_FPIR_UFRP (_ULCAST_(1) << 28)
#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
/*
@@ -753,10 +755,13 @@
#define FPU_CSR_COND7 (_ULCAST_(1) << FPU_CSR_COND7_S)
/*
- * Bits 18 - 20 of the FPU Status Register will be read as 0,
+ * Bits 22:20 of the FPU Status Register will be read as 0,
* and should be written as zero.
*/
-#define FPU_CSR_RSVD 0x001c0000
+#define FPU_CSR_RSVD (_ULCAST_(7) << 20)
+
+#define FPU_CSR_ABS2008 (_ULCAST_(1) << 19)
+#define FPU_CSR_NAN2008 (_ULCAST_(1) << 18)
/*
* X the exception cause indicator
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-03 15:55:16.656968000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-03 15:55:17.635977000 +0100
@@ -919,8 +919,9 @@ static inline void cop1_ctc(struct pt_re
pr_debug("%p gpr[%d]->csr=%08x\n",
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
- /* Don't write reserved bits. */
- fcr31 = value & ~FPU_CSR_RSVD;
+ /* Don't write unsupported bits. */
+ fcr31 = value &
+ ~(FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
break;
case FPCREG_FENR:
Index: linux/arch/mips/math-emu/ieee754.h
===================================================================
--- linux.orig/arch/mips/math-emu/ieee754.h 2015-04-03 13:42:52.928882000 +0100
+++ linux/arch/mips/math-emu/ieee754.h 2015-04-03 15:55:17.637981000 +0100
@@ -130,15 +130,17 @@ enum {
* The control status register
*/
struct _ieee754_csr {
- __BITFIELD_FIELD(unsigned pad0:7,
- __BITFIELD_FIELD(unsigned nod:1, /* set 1 for no denormalised numbers */
- __BITFIELD_FIELD(unsigned c:1, /* condition */
- __BITFIELD_FIELD(unsigned pad1:5,
+ __BITFIELD_FIELD(unsigned fcc:7, /* condition[7:1] */
+ __BITFIELD_FIELD(unsigned nod:1, /* set 1 for no denormals */
+ __BITFIELD_FIELD(unsigned c:1, /* condition[0] */
+ __BITFIELD_FIELD(unsigned pad0:3,
+ __BITFIELD_FIELD(unsigned abs2008:1, /* IEEE 754-2008 ABS/NEG.fmt */
+ __BITFIELD_FIELD(unsigned nan2008:1, /* IEEE 754-2008 NaN mode */
__BITFIELD_FIELD(unsigned cx:6, /* exceptions this operation */
__BITFIELD_FIELD(unsigned mx:5, /* exception enable mask */
__BITFIELD_FIELD(unsigned sx:5, /* exceptions total */
__BITFIELD_FIELD(unsigned rm:2, /* current rounding mode */
- ;))))))))
+ ;))))))))))
};
#define ieee754_csr (*(struct _ieee754_csr *)(¤t->thread.fpu.fcr31))
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (42 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 45/48] MIPS: math-emu: Define IEEE 754-2008 feature control bits Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-07 15:24 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling Maciej W. Rozycki
` (2 subsequent siblings)
46 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
The ABS.fmt and NEG.fmt instructions have been specified as arithmetic
in the MIPS architecture, which in particular implies handling NaN data
in the usual way with qNaN bit patterns propagated unchanged and sNaN
bit patterns signalling the usual IEEE 754 Invalid Operation exception
and quieted by default.
A series of changes applied over time to our implementation:
c5033d78 [MIPS] ieee754[sd]p_neg workaround
cea2be44 MIPS: Fix abs.[sd] and neg.[sd] emulation for NaN operands
has led to the current situation where the sign bit is updated according
to the operation requested even for NaN inputs. This is according to
these commits a workaround so that broken binaries produced by GCC
disregarding the properties of these instructions have a chance to work.
For sNaN inputs this remains within IEEE Std 754 as the standard leaves
the choice of output qNaN bit patterns produced under the default
Invalid Operation exception handling for individual sNaN input bit
patterns to implementer's discretion, even though it still recommends as
much NaN input information to be preserved in NaN outputs.
For qNaN inputs however it violates the standard as it requires a qNaN
input bit patterns to propagate unchanged to output.
This is also unlike real MIPS FPU hardware behaves where sNaN and/or
qNaN processing has been fully implemented with no Unimplemented
Operation exception signalled. Such hardware propagates any input qNaN
bit pattern unchanged. It also quiets any input sNaN bit pattern in an
implementer-specific manner, for example the MIPS 74Kf processor returns
the default qNaN pattern with the sign bit always clear and the Broadcom
SB-1 and BMIPS5000 processors propagate the input sNaN bit pattern with
the sign bit unchanged and the quiet bit first cleared in the trailing
significand field and then the next lower bit set if clearing the quiet
bit left the field with no other bit set.
Especially the latter observation indicates the limited usefulness of
the workaround as it will cover many hardware configurations, but not
all of them, only making it harder to discover such broken binaries that
need to be recompiled with GCC told to avoid the use of ABS.fmt and
NEG.fmt instructions where non-arithmetic semantics is required by the
algorithm used.
Revert the damage done by the series of changes then, and take the
opportunity to simplify implementation by calling `ieee754dp_sub' and
`ieee754dp_add' as required and also the rounding mode set towards -Inf
temporarily so that the sign of 0 is correctly handled.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-fpe-emu-abs.diff
Index: linux/arch/mips/math-emu/dp_simple.c
===================================================================
--- linux.orig/arch/mips/math-emu/dp_simple.c 2015-04-02 20:18:47.633483000 +0100
+++ linux/arch/mips/math-emu/dp_simple.c 2015-04-02 20:27:59.532238000 +0100
@@ -23,44 +23,27 @@
union ieee754dp ieee754dp_neg(union ieee754dp x)
{
- COMPXDP;
-
- EXPLODEXDP;
- ieee754_clearcx();
- FLUSHXDP;
-
- /*
- * Invert the sign ALWAYS to prevent an endless recursion on
- * pow() in libc.
- */
- /* quick fix up */
- DPSIGN(x) ^= 1;
-
- if (xc == IEEE754_CLASS_SNAN) {
- union ieee754dp y = ieee754dp_indef();
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- DPSIGN(y) = DPSIGN(x);
- return ieee754dp_nanxcpt(y);
- }
+ unsigned int oldrm;
+ union ieee754dp y;
- return x;
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ y = ieee754dp_sub(ieee754dp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ return y;
}
union ieee754dp ieee754dp_abs(union ieee754dp x)
{
- COMPXDP;
-
- EXPLODEXDP;
- ieee754_clearcx();
- FLUSHXDP;
-
- /* Clear sign ALWAYS, irrespective of NaN */
- DPSIGN(x) = 0;
-
- if (xc == IEEE754_CLASS_SNAN) {
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_nanxcpt(ieee754dp_indef());
- }
+ unsigned int oldrm;
+ union ieee754dp y;
- return x;
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ if (DPSIGN(x))
+ y = ieee754dp_sub(ieee754dp_zero(0), x);
+ else
+ y = ieee754dp_add(ieee754dp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ return y;
}
Index: linux/arch/mips/math-emu/sp_simple.c
===================================================================
--- linux.orig/arch/mips/math-emu/sp_simple.c 2015-04-02 20:18:47.637483000 +0100
+++ linux/arch/mips/math-emu/sp_simple.c 2015-04-02 20:27:59.534255000 +0100
@@ -23,44 +23,27 @@
union ieee754sp ieee754sp_neg(union ieee754sp x)
{
- COMPXSP;
-
- EXPLODEXSP;
- ieee754_clearcx();
- FLUSHXSP;
-
- /*
- * Invert the sign ALWAYS to prevent an endless recursion on
- * pow() in libc.
- */
- /* quick fix up */
- SPSIGN(x) ^= 1;
-
- if (xc == IEEE754_CLASS_SNAN) {
- union ieee754sp y = ieee754sp_indef();
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- SPSIGN(y) = SPSIGN(x);
- return ieee754sp_nanxcpt(y);
- }
+ unsigned int oldrm;
+ union ieee754sp y;
- return x;
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ y = ieee754sp_sub(ieee754sp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ return y;
}
union ieee754sp ieee754sp_abs(union ieee754sp x)
{
- COMPXSP;
-
- EXPLODEXSP;
- ieee754_clearcx();
- FLUSHXSP;
-
- /* Clear sign ALWAYS, irrespective of NaN */
- SPSIGN(x) = 0;
-
- if (xc == IEEE754_CLASS_SNAN) {
- ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef());
- }
+ unsigned int oldrm;
+ union ieee754sp y;
- return x;
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ if (SPSIGN(x))
+ y = ieee754sp_sub(ieee754sp_zero(0), x);
+ else
+ y = ieee754sp_add(ieee754sp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ return y;
}
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (43 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-07 12:54 ` Ralf Baechle
2015-04-03 22:27 ` [PATCH 48/48] MIPS: Factor out FPU feature probing Maciej W. Rozycki
2015-04-04 20:04 ` [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Ralf Baechle
46 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Define the central place the default FCSR value is set from, initialised
in `cpu_probe'. Determine the FCSR mask applied to values written to
the register with CTC1 in the full emulation mode and via ptrace(2),
according to the ISA level of processor hardware or the writability of
bits 31:18 if actual FPU hardware is used.
Software may rely on FCSR bits whose functions our emulator does not
implement, so it should not allow them to be set or software may get
confused. For ptrace(2) it's just sanity.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-emu-fcsr-isa.diff
Index: linux/arch/mips/include/asm/cpu-info.h
===================================================================
--- linux.orig/arch/mips/include/asm/cpu-info.h 2015-04-02 20:18:47.496475000 +0100
+++ linux/arch/mips/include/asm/cpu-info.h 2015-04-02 20:27:59.740240000 +0100
@@ -49,6 +49,8 @@ struct cpuinfo_mips {
unsigned int udelay_val;
unsigned int processor_id;
unsigned int fpu_id;
+ unsigned int fpu_csr31;
+ unsigned int fpu_msk31;
unsigned int msa_id;
unsigned int cputype;
int isa_level;
Index: linux/arch/mips/include/asm/elf.h
===================================================================
--- linux.orig/arch/mips/include/asm/elf.h 2015-04-02 20:18:47.497482000 +0100
+++ linux/arch/mips/include/asm/elf.h 2015-04-02 20:27:59.742251000 +0100
@@ -11,6 +11,9 @@
#include <linux/fs.h>
#include <uapi/linux/elf.h>
+#include <asm/cpu-info.h>
+#include <asm/current.h>
+
/* ELF header e_flags defines. */
/* MIPS architecture level. */
#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
@@ -297,6 +300,8 @@ do { \
mips_set_personality_fp(state); \
\
current->thread.abi = &mips_abi; \
+ \
+ current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31; \
} while (0)
#endif /* CONFIG_32BIT */
@@ -356,6 +361,8 @@ do { \
else \
current->thread.abi = &mips_abi; \
\
+ current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31; \
+ \
p = personality(current->personality); \
if (p != PER_LINUX32 && p != PER_LINUX) \
set_personality(PER_LINUX); \
Index: linux/arch/mips/include/asm/fpu.h
===================================================================
--- linux.orig/arch/mips/include/asm/fpu.h 2015-04-02 20:18:47.499480000 +0100
+++ linux/arch/mips/include/asm/fpu.h 2015-04-02 20:27:59.745241000 +0100
@@ -14,6 +14,7 @@
#include <linux/thread_info.h>
#include <linux/bitops.h>
+#include <asm/current.h>
#include <asm/mipsregs.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -30,7 +31,7 @@
struct sigcontext;
struct sigcontext32;
-extern void _init_fpu(void);
+extern void _init_fpu(unsigned int);
extern void _save_fp(struct task_struct *);
extern void _restore_fp(struct task_struct *);
@@ -182,6 +183,7 @@ static inline void lose_fpu(int save)
static inline int init_fpu(void)
{
+ unsigned int fcr31 = current->thread.fpu.fcr31;
int ret = 0;
if (cpu_has_fpu) {
@@ -192,7 +194,7 @@ static inline int init_fpu(void)
return ret;
if (!cpu_has_fre) {
- _init_fpu();
+ _init_fpu(fcr31);
return 0;
}
@@ -206,7 +208,7 @@ static inline int init_fpu(void)
config5 = clear_c0_config5(MIPS_CONF5_FRE);
enable_fpu_hazard();
- _init_fpu();
+ _init_fpu(fcr31);
/* Restore FRE */
write_c0_config5(config5);
Index: linux/arch/mips/include/asm/fpu_emulator.h
===================================================================
--- linux.orig/arch/mips/include/asm/fpu_emulator.h 2015-04-02 20:27:58.453234000 +0100
+++ linux/arch/mips/include/asm/fpu_emulator.h 2015-04-02 20:27:59.747241000 +0100
@@ -87,8 +87,6 @@ static inline void fpu_emulator_init_fpu
struct task_struct *t = current;
int i;
- t->thread.fpu.fcr31 = 0;
-
for (i = 0; i < 32; i++)
set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
}
Index: linux/arch/mips/kernel/cpu-probe.c
===================================================================
--- linux.orig/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:58.890231000 +0100
+++ linux/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:59.750245000 +0100
@@ -33,6 +33,35 @@
#include <asm/uaccess.h>
/*
+ * Determine the FCSR mask for FPU hardware.
+ */
+static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
+{
+ unsigned long sr, mask, fcsr, fcsr0, fcsr1;
+
+ mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM;
+
+ sr = read_c0_status();
+ __enable_fpu(FPU_AS_IS);
+
+ fcsr = read_32bit_cp1_register(CP1_STATUS);
+
+ fcsr0 = fcsr & mask;
+ write_32bit_cp1_register(CP1_STATUS, fcsr0);
+ fcsr0 = read_32bit_cp1_register(CP1_STATUS);
+
+ fcsr1 = fcsr | ~mask;
+ write_32bit_cp1_register(CP1_STATUS, fcsr1);
+ fcsr1 = read_32bit_cp1_register(CP1_STATUS);
+
+ write_32bit_cp1_register(CP1_STATUS, fcsr);
+
+ write_c0_status(sr);
+
+ c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
+}
+
+/*
* Set the FIR feature flags for the FPU emulator.
*/
static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
@@ -50,11 +79,15 @@ static void cpu_set_nofpu_id(struct cpui
c->fpu_id = value;
}
+/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */
+static unsigned int mips_nofpu_msk31;
+
static int mips_fpu_disabled;
static int __init fpu_disable(char *s)
{
boot_cpu_data.options &= ~MIPS_CPU_FPU;
+ boot_cpu_data.fpu_msk31 = mips_nofpu_msk31;
cpu_set_nofpu_id(&boot_cpu_data);
mips_fpu_disabled = 1;
@@ -595,6 +628,7 @@ static inline void cpu_probe_legacy(stru
case PRID_IMP_R2000:
c->cputype = CPU_R2000;
__cpu_name[cpu] = "R2000";
+ c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
@@ -614,6 +648,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R3000;
__cpu_name[cpu] = "R3000";
}
+ c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
@@ -662,6 +697,7 @@ static inline void cpu_probe_legacy(stru
}
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
MIPS_CPU_WATCH | MIPS_CPU_VCE |
MIPS_CPU_LLSC;
@@ -669,6 +705,7 @@ static inline void cpu_probe_legacy(stru
break;
case PRID_IMP_VR41XX:
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS;
c->tlbsize = 32;
switch (c->processor_id & 0xf0) {
@@ -710,6 +747,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R4300;
__cpu_name[cpu] = "R4300";
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
MIPS_CPU_LLSC;
c->tlbsize = 32;
@@ -718,6 +756,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R4600;
__cpu_name[cpu] = "R4600";
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
MIPS_CPU_LLSC;
c->tlbsize = 48;
@@ -733,11 +772,13 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R4650;
__cpu_name[cpu] = "R4650";
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
c->tlbsize = 48;
break;
#endif
case PRID_IMP_TX39:
+ c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
@@ -763,6 +804,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R4700;
__cpu_name[cpu] = "R4700";
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
MIPS_CPU_LLSC;
c->tlbsize = 48;
@@ -771,6 +813,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_TX49XX;
__cpu_name[cpu] = "R49XX";
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
c->options = R4K_OPTS | MIPS_CPU_LLSC;
if (!(c->processor_id & 0x08))
c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
@@ -812,6 +855,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R6000;
__cpu_name[cpu] = "R6000";
set_isa(c, MIPS_CPU_ISA_II);
+ c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
MIPS_CPU_LLSC;
c->tlbsize = 32;
@@ -820,6 +864,7 @@ static inline void cpu_probe_legacy(stru
c->cputype = CPU_R6000A;
__cpu_name[cpu] = "R6000A";
set_isa(c, MIPS_CPU_ISA_II);
+ c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
MIPS_CPU_LLSC;
c->tlbsize = 32;
@@ -886,12 +931,14 @@ static inline void cpu_probe_legacy(stru
__cpu_name[cpu] = "ICT Loongson-2";
set_elf_platform(cpu, "loongson2e");
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
break;
case PRID_REV_LOONGSON2F:
c->cputype = CPU_LOONGSON2;
__cpu_name[cpu] = "ICT Loongson-2";
set_elf_platform(cpu, "loongson2f");
set_isa(c, MIPS_CPU_ISA_III);
+ c->fpu_msk31 |= FPU_CSR_CONDX;
break;
case PRID_REV_LOONGSON3A:
c->cputype = CPU_LOONGSON3;
@@ -1328,6 +1375,9 @@ void cpu_probe(void)
c->cputype = CPU_UNKNOWN;
c->writecombine = _CACHE_UNCACHED;
+ c->fpu_csr31 = FPU_CSR_RN;
+ c->fpu_msk31 = FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+
c->processor_id = read_c0_prid();
switch (c->processor_id & PRID_COMP_MASK) {
case PRID_COMP_LEGACY:
@@ -1386,6 +1436,7 @@ void cpu_probe(void)
if (c->options & MIPS_CPU_FPU) {
c->fpu_id = cpu_get_fpu_id();
+ mips_nofpu_msk31 = c->fpu_msk31;
if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
@@ -1395,6 +1446,8 @@ void cpu_probe(void)
if (c->fpu_id & MIPS_FPIR_FREP)
c->options |= MIPS_CPU_FRE;
}
+
+ cpu_set_fpu_fcsr_mask(c);
} else
cpu_set_nofpu_id(c);
Index: linux/arch/mips/kernel/ptrace.c
===================================================================
--- linux.orig/arch/mips/kernel/ptrace.c 2015-04-02 20:18:47.505476000 +0100
+++ linux/arch/mips/kernel/ptrace.c 2015-04-02 20:27:59.753242000 +0100
@@ -32,6 +32,7 @@
#include <asm/byteorder.h>
#include <asm/cpu.h>
+#include <asm/cpu-info.h>
#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
@@ -137,6 +138,9 @@ int ptrace_setfpregs(struct task_struct
{
union fpureg *fregs;
u64 fpr_val;
+ u32 fcr31;
+ u32 value;
+ u32 mask;
int i;
if (!access_ok(VERIFY_READ, data, 33 * 8))
@@ -149,8 +153,10 @@ int ptrace_setfpregs(struct task_struct
set_fpr64(&fregs[i], 0, fpr_val);
}
- __get_user(child->thread.fpu.fcr31, data + 64);
- child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+ __get_user(value, data + 64);
+ fcr31 = child->thread.fpu.fcr31;
+ mask = current_cpu_data.fpu_msk31;
+ child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
/* FIR may not be written. */
Index: linux/arch/mips/kernel/r2300_switch.S
===================================================================
--- linux.orig/arch/mips/kernel/r2300_switch.S 2015-04-02 20:18:47.506481000 +0100
+++ linux/arch/mips/kernel/r2300_switch.S 2015-04-02 20:27:59.755248000 +0100
@@ -115,11 +115,9 @@ LEAF(_restore_fp)
* the property that no matter whether considered as single or as double
* precision represents signaling NANS.
*
- * We initialize fcr31 to rounding to nearest, no exceptions.
+ * The value to initialize fcr31 to comes in $a0.
*/
-#define FPU_DEFAULT 0x00000000
-
.set push
SET_HARDFLOAT
@@ -129,8 +127,7 @@ LEAF(_init_fpu)
or t0, t1
mtc0 t0, CP0_STATUS
- li t1, FPU_DEFAULT
- ctc1 t1, fcr31
+ ctc1 a0, fcr31
li t0, -1
Index: linux/arch/mips/kernel/r4k_switch.S
===================================================================
--- linux.orig/arch/mips/kernel/r4k_switch.S 2015-04-02 20:18:47.508482000 +0100
+++ linux/arch/mips/kernel/r4k_switch.S 2015-04-02 20:27:59.758240000 +0100
@@ -165,11 +165,9 @@ LEAF(_init_msa_upper)
* the property that no matter whether considered as single or as double
* precision represents signaling NANS.
*
- * We initialize fcr31 to rounding to nearest, no exceptions.
+ * The value to initialize fcr31 to comes in $a0.
*/
-#define FPU_DEFAULT 0x00000000
-
.set push
SET_HARDFLOAT
@@ -180,8 +178,7 @@ LEAF(_init_fpu)
mtc0 t0, CP0_STATUS
enable_fpu_hazard
- li t1, FPU_DEFAULT
- ctc1 t1, fcr31
+ ctc1 a0, fcr31
li t1, -1 # SNaN
Index: linux/arch/mips/loongson/loongson-3/cop2-ex.c
===================================================================
--- linux.orig/arch/mips/loongson/loongson-3/cop2-ex.c 2015-04-02 20:18:47.515499000 +0100
+++ linux/arch/mips/loongson/loongson-3/cop2-ex.c 2015-04-02 20:27:59.767246000 +0100
@@ -43,7 +43,7 @@ static int loongson_cu2_call(struct noti
if (!fpu_owned) {
set_thread_flag(TIF_USEDFPU);
if (!used_math()) {
- _init_fpu();
+ _init_fpu(current->thread.fpu.fcr31);
set_used_math();
} else
_restore_fp(current);
Index: linux/arch/mips/math-emu/cp1emu.c
===================================================================
--- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:59.304242000 +0100
+++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:59.771244000 +0100
@@ -908,6 +908,7 @@ static inline void cop1_ctc(struct pt_re
{
u32 fcr31 = ctx->fcr31;
u32 value;
+ u32 mask;
if (MIPSInst_RT(ir) == 0)
value = 0;
@@ -919,9 +920,9 @@ static inline void cop1_ctc(struct pt_re
pr_debug("%p gpr[%d]->csr=%08x\n",
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
- /* Don't write unsupported bits. */
- fcr31 = value &
- ~(FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+ /* Preserve read-only bits. */
+ mask = current_cpu_data.fpu_msk31;
+ fcr31 = (value & ~mask) | (fcr31 & mask);
break;
case FPCREG_FENR:
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 48/48] MIPS: Factor out FPU feature probing
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (44 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling Maciej W. Rozycki
@ 2015-04-03 22:27 ` Maciej W. Rozycki
2015-04-04 20:04 ` [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Ralf Baechle
46 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-03 22:27 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Factor out FPU feature probing, mainly to remove code duplication from
`fpu_disable'. No functional change although shuffle some code to avoid
forward references.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
---
linux-mips-fpu-probe.diff
Index: linux/arch/mips/kernel/cpu-probe.c
===================================================================
--- linux.orig/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:59.750245000 +0100
+++ linux/arch/mips/kernel/cpu-probe.c 2015-04-02 20:28:00.091243000 +0100
@@ -33,6 +33,41 @@
#include <asm/uaccess.h>
/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+ unsigned long tmp, fpu_id;
+
+ tmp = read_c0_status();
+ __enable_fpu(FPU_AS_IS);
+ fpu_id = read_32bit_cp1_register(CP1_REVISION);
+ write_c0_status(tmp);
+ return fpu_id;
+}
+
+/*
+ * Check if the CPU has an external FPU.
+ */
+static inline int __cpu_has_fpu(void)
+{
+ return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
+}
+
+static inline unsigned long cpu_get_msa_id(void)
+{
+ unsigned long status, msa_id;
+
+ status = read_c0_status();
+ __enable_fpu(FPU_64BIT);
+ enable_msa();
+ msa_id = read_msa_ir();
+ disable_msa();
+ write_c0_status(status);
+ return msa_id;
+}
+
+/*
* Determine the FCSR mask for FPU hardware.
*/
static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
@@ -82,13 +117,42 @@ static void cpu_set_nofpu_id(struct cpui
/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */
static unsigned int mips_nofpu_msk31;
+/*
+ * Set options for FPU hardware.
+ */
+static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
+{
+ c->fpu_id = cpu_get_fpu_id();
+ mips_nofpu_msk31 = c->fpu_msk31;
+
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+ MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+ if (c->fpu_id & MIPS_FPIR_3D)
+ c->ases |= MIPS_ASE_MIPS3D;
+ if (c->fpu_id & MIPS_FPIR_FREP)
+ c->options |= MIPS_CPU_FRE;
+ }
+
+ cpu_set_fpu_fcsr_mask(c);
+}
+
+/*
+ * Set options for the FPU emulator.
+ */
+static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
+{
+ c->options &= ~MIPS_CPU_FPU;
+ c->fpu_msk31 = mips_nofpu_msk31;
+
+ cpu_set_nofpu_id(c);
+}
+
static int mips_fpu_disabled;
static int __init fpu_disable(char *s)
{
- boot_cpu_data.options &= ~MIPS_CPU_FPU;
- boot_cpu_data.fpu_msk31 = mips_nofpu_msk31;
- cpu_set_nofpu_id(&boot_cpu_data);
+ cpu_set_nofpu_opts(&boot_cpu_data);
mips_fpu_disabled = 1;
return 1;
@@ -231,41 +295,6 @@ static inline void set_elf_platform(int
__elf_platform = plat;
}
-/*
- * Get the FPU Implementation/Revision.
- */
-static inline unsigned long cpu_get_fpu_id(void)
-{
- unsigned long tmp, fpu_id;
-
- tmp = read_c0_status();
- __enable_fpu(FPU_AS_IS);
- fpu_id = read_32bit_cp1_register(CP1_REVISION);
- write_c0_status(tmp);
- return fpu_id;
-}
-
-/*
- * Check if the CPU has an external FPU.
- */
-static inline int __cpu_has_fpu(void)
-{
- return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
-}
-
-static inline unsigned long cpu_get_msa_id(void)
-{
- unsigned long status, msa_id;
-
- status = read_c0_status();
- __enable_fpu(FPU_64BIT);
- enable_msa();
- msa_id = read_msa_ir();
- disable_msa();
- write_c0_status(status);
- return msa_id;
-}
-
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
{
#ifdef __NEED_VMBITS_PROBE
@@ -1434,22 +1463,10 @@ void cpu_probe(void)
~(1 << MIPS_PWCTL_PWEN_SHIFT));
}
- if (c->options & MIPS_CPU_FPU) {
- c->fpu_id = cpu_get_fpu_id();
- mips_nofpu_msk31 = c->fpu_msk31;
-
- if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
- MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
- if (c->fpu_id & MIPS_FPIR_3D)
- c->ases |= MIPS_ASE_MIPS3D;
- if (c->fpu_id & MIPS_FPIR_FREP)
- c->options |= MIPS_CPU_FRE;
- }
-
- cpu_set_fpu_fcsr_mask(c);
- } else
- cpu_set_nofpu_id(c);
+ if (c->options & MIPS_CPU_FPU)
+ cpu_set_fpu_opts(c);
+ else
+ cpu_set_nofpu_opts(c);
if (cpu_has_mips_r2_r6) {
c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 43/48] MIPS: math-emu: Set FIR feature flags for full emulation
2015-04-03 22:27 ` [PATCH 43/48] MIPS: math-emu: Set FIR feature flags for full emulation Maciej W. Rozycki
@ 2015-04-03 23:18 ` Sergei Shtylyov
0 siblings, 0 replies; 62+ messages in thread
From: Sergei Shtylyov @ 2015-04-03 23:18 UTC (permalink / raw)
To: Maciej W. Rozycki, Ralf Baechle; +Cc: linux-mips
Hello.
On 04/04/2015 01:27 AM, Maciej W. Rozycki wrote:
> Implement FIR feature flags in the FPU emulator according to features
> supported and architecture level requirements. The W, L and F64 bits
> have only been added at level #2 even though the features they refer to
> were also included with the MIPS64r1 ISA and the W fixed-point format
> also with the MIPS32r1 ISA.
> This is only relevant for the full emulation mode and the emulated CFC1
> instruction as well as ptrace(2) accesses.
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> ---
> linux-mips-emu-fir.diff
> Index: linux/arch/mips/kernel/cpu-probe.c
> ===================================================================
> --- linux.orig/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:58.700229000 +0100
> +++ linux/arch/mips/kernel/cpu-probe.c 2015-04-02 20:27:58.890231000 +0100
[...]
> @@ -31,11 +32,30 @@
> #include <asm/spram.h>
> #include <asm/uaccess.h>
>
> +/*
> + * Set the FIR feature flags for the FPU emulator.
> + */
> +static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
> +{
> + u32 value;
> +
> + value = 0;
Why not just do it in an initializer?
> + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
> + MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
> + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
> + value |= MIPS_FPIR_D | MIPS_FPIR_S;
> + if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
> + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
> + value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
> + c->fpu_id = value;
> +}
> +
> static int mips_fpu_disabled;
>
> static int __init fpu_disable(char *s)
> {
> - cpu_data[0].options &= ~MIPS_CPU_FPU;
> + boot_cpu_data.options &= ~MIPS_CPU_FPU;
> + cpu_set_nofpu_id(&boot_cpu_data);
> mips_fpu_disabled = 1;
>
> return 1;
> @@ -1375,7 +1395,8 @@ void cpu_probe(void)
> if (c->fpu_id & MIPS_FPIR_FREP)
> c->options |= MIPS_CPU_FRE;
> }
> - }
> + } else
> + cpu_set_nofpu_id(c);
CodingStyle: need {} in the *else* branch as well.
[...]
WBR, Sergei
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 29/48] MIPS: math-emu: Make NaN classifiers static
2015-04-03 22:25 ` [PATCH 29/48] MIPS: math-emu: Make NaN classifiers static Maciej W. Rozycki
@ 2015-04-03 23:22 ` Sergei Shtylyov
0 siblings, 0 replies; 62+ messages in thread
From: Sergei Shtylyov @ 2015-04-03 23:22 UTC (permalink / raw)
To: Maciej W. Rozycki, Ralf Baechle; +Cc: linux-mips
Hello.
On 04/04/2015 01:25 AM, Maciej W. Rozycki wrote:
> The `ieee754sp_isnan' and `ieee754dp_isnan' NaN classifiers are now no
> longer externally referred, remove their header prototypes and make them
> local to the two only respective places still making use of them.
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> ---
> linux-mips-emu-isnan.diff
> Index: linux/arch/mips/math-emu/ieee754dp.c
> ===================================================================
> --- linux.orig/arch/mips/math-emu/ieee754dp.c 2015-04-02 20:27:55.587207000 +0100
> +++ linux/arch/mips/math-emu/ieee754dp.c 2015-04-02 20:27:56.032207000 +0100
> @@ -30,7 +30,7 @@ int ieee754dp_class(union ieee754dp x)
> return xc;
> }
>
> -int ieee754dp_isnan(union ieee754dp x)
> +static inline int ieee754dp_isnan(union ieee754dp x)
I think the current trend is to let gcc figure out whether to inline or not.
[...]
WBR, Sergei
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation
2015-04-03 22:25 ` [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation Maciej W. Rozycki
@ 2015-04-03 23:33 ` Sergei Shtylyov
2015-04-04 0:07 ` Maciej W. Rozycki
0 siblings, 1 reply; 62+ messages in thread
From: Sergei Shtylyov @ 2015-04-03 23:33 UTC (permalink / raw)
To: Maciej W. Rozycki, Ralf Baechle; +Cc: linux-mips
Hello.
On 04/04/2015 01:25 AM, Maciej W. Rozycki wrote:
> Move CFC1/CTC1 emulation code to separate functions to avoid excessive
> indentation in forthcoming changes. Adjust formatting in a minor way
> and remove extraneous round brackets.
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> ---
> linux-mips-emu-cxc.diff
> Index: linux/arch/mips/math-emu/cp1emu.c
> ===================================================================
> --- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:54.099185000 +0100
> +++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:54.459192000 +0100
> @@ -840,6 +840,52 @@ do { \
> #define DPTOREG(dp, x) DITOREG((dp).bits, x)
>
> /*
> + * Emulate a CFC1 instruction.
> + */
> +static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
> + mips_instruction ir)
> +{
> + u32 value;
> +
> + if (MIPSInst_RD(ir) == FPCREG_CSR) {
> + value = ctx->fcr31;
> + pr_debug("%p gpr[%d]<-csr=%08x\n",
> + (void *)xcp->cp0_epc,
> + MIPSInst_RT(ir), value);
> + } else if (MIPSInst_RD(ir) == FPCREG_RID)
> + value = 0;
> + else
> + value = 0;
CodingStyle: all arms of the *if* statement shouyld have {} if at leats
one has them.
> + if (MIPSInst_RT(ir))
> + xcp->regs[MIPSInst_RT(ir)] = value;
> +}
> +
> +/*
> + * Emulate a CTC1 instruction.
> + */
> +static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
> + mips_instruction ir)
> +{
> + u32 value;
> +
> + if (MIPSInst_RT(ir) == 0)
> + value = 0;
> + else
> + value = xcp->regs[MIPSInst_RT(ir)];
> +
> + /* we only have one writable control reg
> + */
This comment would fit on a single line.
[...]
WBR, Sergei
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation
2015-04-03 23:33 ` Sergei Shtylyov
@ 2015-04-04 0:07 ` Maciej W. Rozycki
0 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-04 0:07 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Ralf Baechle, linux-mips
On Sat, 4 Apr 2015, Sergei Shtylyov wrote:
> > + if (MIPSInst_RD(ir) == FPCREG_CSR) {
> > + value = ctx->fcr31;
> > + pr_debug("%p gpr[%d]<-csr=%08x\n",
> > + (void *)xcp->cp0_epc,
> > + MIPSInst_RT(ir), value);
> > + } else if (MIPSInst_RD(ir) == FPCREG_RID)
> > + value = 0;
> > + else
> > + value = 0;
>
> CodingStyle: all arms of the *if* statement shouyld have {} if at leats one
> has them.
>
> > + if (MIPSInst_RT(ir))
> > + xcp->regs[MIPSInst_RT(ir)] = value;
> > +}
> > +
> > +/*
> > + * Emulate a CTC1 instruction.
> > + */
> > +static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct
> > *ctx,
> > + mips_instruction ir)
> > +{
> > + u32 value;
> > +
> > + if (MIPSInst_RT(ir) == 0)
> > + value = 0;
> > + else
> > + value = xcp->regs[MIPSInst_RT(ir)];
> > +
> > + /* we only have one writable control reg
> > + */
>
> This comment would fit on a single line.
Thanks for your comments.
These patches move lots of preexisting code around, in some cases copying
preexiting problems. These problems are addressed as code is updated by
later changes, so please have a look there too before pointing out issues.
If I missed anything and a problem remains in code being poked at after
all the changes have been applied, then please do let me know, I'll
correct it.
Thanks for your assistance with keeping our code clean!
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
` (45 preceding siblings ...)
2015-04-03 22:27 ` [PATCH 48/48] MIPS: Factor out FPU feature probing Maciej W. Rozycki
@ 2015-04-04 20:04 ` Ralf Baechle
2015-04-04 20:55 ` Maciej W. Rozycki
46 siblings, 1 reply; 62+ messages in thread
From: Ralf Baechle @ 2015-04-04 20:04 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Fri, Apr 03, 2015 at 11:23:29PM +0100, Maciej W. Rozycki wrote:
> These are fixes to address code structuring and coding style problems
> and then bug fixes I discovered in the course of implementing an
> upcoming FPU feature. There are some minor feature updates too. They
> are related to one another to a various extent, sometimes very loosely,
> but I decided to keep them as a series because there is a lot of
> syntactical overlap, as changes are made in steps, one issue at a time.
> Keeping them in order guarantees that they apply on top of one another.
>
> Clean-ups come first as they should be completely uncontroversial,
> followed by restructuring, bug fixes and new features.
It would have been nice if the bug fixes or at least those relevant to
4.0 and older were at the beginning to reduce issue when applying them
to the 4.0-fixes and possibly -stable branches.
I applied your patches on top of my working branch and ran into a number
of conflicts. Will push the result out as soon as I'm done with the
conflict resolution.
Thanks!
Ralf
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates
2015-04-04 20:04 ` [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Ralf Baechle
@ 2015-04-04 20:55 ` Maciej W. Rozycki
2015-04-04 21:57 ` Ralf Baechle
0 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-04 20:55 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
On Sat, 4 Apr 2015, Ralf Baechle wrote:
> > Clean-ups come first as they should be completely uncontroversial,
> > followed by restructuring, bug fixes and new features.
>
> It would have been nice if the bug fixes or at least those relevant to
> 4.0 and older were at the beginning to reduce issue when applying them
> to the 4.0-fixes and possibly -stable branches.
Good point, I will keep it in mind in the future. I think there's
actually little if any overlap here though, you should be able to ignore
comment and formatting changes when doing any backports and the rest
should just apply right away.
I can send you a pre-r6 version of the relevant patches too if that would
help -- I think there are 3 or 4 that I had to rework while rebasing from
3.19 to 4.0.
> I applied your patches on top of my working branch and ran into a number
> of conflicts. Will push the result out as soon as I'm done with the
> conflict resolution.
Great, thanks!
Is there a better branch than master of ralf/linux.git to base patches
submitted against so as to save you from the need to sort out conflicts?
Let me know if you need help with any unobvious 3-way merge too.
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates
2015-04-04 20:55 ` Maciej W. Rozycki
@ 2015-04-04 21:57 ` Ralf Baechle
0 siblings, 0 replies; 62+ messages in thread
From: Ralf Baechle @ 2015-04-04 21:57 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Sat, Apr 04, 2015 at 09:55:09PM +0100, Maciej W. Rozycki wrote:
> Is there a better branch than master of ralf/linux.git to base patches
> submitted against so as to save you from the need to sort out conflicts?
> Let me know if you need help with any unobvious 3-way merge too.
That's a little harder this time. Normally the top of upstream-sfr's
mips-for-linux-next is a good choice for the base but this time I have
another branch, 4.1-fp in upstream-sfr and I want to keep the merge
commit pulling this branch and the 4.0-fixes branch on top which lands
me in a bunch of conflicts.
The conflicts are in
arch/mips/include/asm/asmmacro-32.h
arch/mips/kernel/traps.c
I've tested a number of defconfigs and I'm pushing a new upstream-sfr
now. I'd appreciate if you could test/review the result.
Ralf
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling
2015-04-03 22:27 ` [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling Maciej W. Rozycki
@ 2015-04-07 12:54 ` Ralf Baechle
2015-04-07 21:13 ` Maciej W. Rozycki
0 siblings, 1 reply; 62+ messages in thread
From: Ralf Baechle @ 2015-04-07 12:54 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Fri, Apr 03, 2015 at 11:27:48PM +0100, Maciej W. Rozycki wrote:
> Date: Fri, 3 Apr 2015 23:27:48 +0100 (BST)
> Index: linux/arch/mips/include/asm/fpu.h
> ===================================================================
> --- linux.orig/arch/mips/include/asm/fpu.h 2015-04-02 20:18:47.499480000 +0100
> +++ linux/arch/mips/include/asm/fpu.h 2015-04-02 20:27:59.745241000 +0100
> @@ -14,6 +14,7 @@
> #include <linux/thread_info.h>
> #include <linux/bitops.h>
>
> +#include <asm/current.h>
> #include <asm/mipsregs.h>
> #include <asm/cpu.h>
> #include <asm/cpu-features.h>
This is adding a 2nd inclusion of <asm/current.h>. Will fix that.
Ralf
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again
2015-04-03 22:27 ` [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again Maciej W. Rozycki
@ 2015-04-07 15:24 ` Maciej W. Rozycki
2015-04-07 17:31 ` Ralf Baechle
0 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-07 15:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
On Fri, 3 Apr 2015, Maciej W. Rozycki wrote:
> The ABS.fmt and NEG.fmt instructions have been specified as arithmetic
> in the MIPS architecture, which in particular implies handling NaN data
> in the usual way with qNaN bit patterns propagated unchanged and sNaN
> bit patterns signalling the usual IEEE 754 Invalid Operation exception
> and quieted by default.
>
> A series of changes applied over time to our implementation:
>
> c5033d78 [MIPS] ieee754[sd]p_neg workaround
> cea2be44 MIPS: Fix abs.[sd] and neg.[sd] emulation for NaN operands
>
> has led to the current situation where the sign bit is updated according
> to the operation requested even for NaN inputs. This is according to
> these commits a workaround so that broken binaries produced by GCC
> disregarding the properties of these instructions have a chance to work.
>
> For sNaN inputs this remains within IEEE Std 754 as the standard leaves
> the choice of output qNaN bit patterns produced under the default
> Invalid Operation exception handling for individual sNaN input bit
> patterns to implementer's discretion, even though it still recommends as
> much NaN input information to be preserved in NaN outputs.
>
> For qNaN inputs however it violates the standard as it requires a qNaN
> input bit patterns to propagate unchanged to output.
>
> This is also unlike real MIPS FPU hardware behaves where sNaN and/or
> qNaN processing has been fully implemented with no Unimplemented
> Operation exception signalled. Such hardware propagates any input qNaN
> bit pattern unchanged. It also quiets any input sNaN bit pattern in an
> implementer-specific manner, for example the MIPS 74Kf processor returns
> the default qNaN pattern with the sign bit always clear and the Broadcom
> SB-1 and BMIPS5000 processors propagate the input sNaN bit pattern with
> the sign bit unchanged and the quiet bit first cleared in the trailing
> significand field and then the next lower bit set if clearing the quiet
> bit left the field with no other bit set.
>
> Especially the latter observation indicates the limited usefulness of
> the workaround as it will cover many hardware configurations, but not
> all of them, only making it harder to discover such broken binaries that
> need to be recompiled with GCC told to avoid the use of ABS.fmt and
> NEG.fmt instructions where non-arithmetic semantics is required by the
> algorithm used.
>
> Revert the damage done by the series of changes then, and take the
> opportunity to simplify implementation by calling `ieee754dp_sub' and
> `ieee754dp_add' as required and also the rounding mode set towards -Inf
> temporarily so that the sign of 0 is correctly handled.
>
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> ---
One point to make here is the use of `ieee754dp_sub' and `ieee754dp_add'
makes emulated ABS.fmt and NEG.fmt respect FCSR.FS for denormals just as
hardware does. I should have noted that in the commit message, perhaps it
can be retrofitted?
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again
2015-04-07 15:24 ` Maciej W. Rozycki
@ 2015-04-07 17:31 ` Ralf Baechle
2015-04-07 23:11 ` Maciej W. Rozycki
0 siblings, 1 reply; 62+ messages in thread
From: Ralf Baechle @ 2015-04-07 17:31 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Tue, Apr 07, 2015 at 04:24:32PM +0100, Maciej W. Rozycki wrote:
> > Revert the damage done by the series of changes then, and take the
> > opportunity to simplify implementation by calling `ieee754dp_sub' and
> > `ieee754dp_add' as required and also the rounding mode set towards -Inf
> > temporarily so that the sign of 0 is correctly handled.
> >
> > Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> > ---
>
> One point to make here is the use of `ieee754dp_sub' and `ieee754dp_add'
> makes emulated ABS.fmt and NEG.fmt respect FCSR.FS for denormals just as
> hardware does. I should have noted that in the commit message, perhaps it
> can be retrofitted?
Yes, it can. Just send the new commit message.
Ralf
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling
2015-04-07 12:54 ` Ralf Baechle
@ 2015-04-07 21:13 ` Maciej W. Rozycki
2015-04-07 22:45 ` Ralf Baechle
0 siblings, 1 reply; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-07 21:13 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
On Tue, 7 Apr 2015, Ralf Baechle wrote:
> > Index: linux/arch/mips/include/asm/fpu.h
> > ===================================================================
> > --- linux.orig/arch/mips/include/asm/fpu.h 2015-04-02 20:18:47.499480000 +0100
> > +++ linux/arch/mips/include/asm/fpu.h 2015-04-02 20:27:59.745241000 +0100
> > @@ -14,6 +14,7 @@
> > #include <linux/thread_info.h>
> > #include <linux/bitops.h>
> >
> > +#include <asm/current.h>
> > #include <asm/mipsregs.h>
> > #include <asm/cpu.h>
> > #include <asm/cpu-features.h>
>
> This is adding a 2nd inclusion of <asm/current.h>. Will fix that.
Thanks! I resisted the temptation to include changes to sort inclusions
with this series or it would risk becoming an ever going effort. Though
it would have avoided an oversight like this.
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling
2015-04-07 21:13 ` Maciej W. Rozycki
@ 2015-04-07 22:45 ` Ralf Baechle
0 siblings, 0 replies; 62+ messages in thread
From: Ralf Baechle @ 2015-04-07 22:45 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Tue, Apr 07, 2015 at 10:13:38PM +0100, Maciej W. Rozycki wrote:
> > > Index: linux/arch/mips/include/asm/fpu.h
> > > ===================================================================
> > > --- linux.orig/arch/mips/include/asm/fpu.h 2015-04-02 20:18:47.499480000 +0100
> > > +++ linux/arch/mips/include/asm/fpu.h 2015-04-02 20:27:59.745241000 +0100
> > > @@ -14,6 +14,7 @@
> > > #include <linux/thread_info.h>
> > > #include <linux/bitops.h>
> > >
> > > +#include <asm/current.h>
> > > #include <asm/mipsregs.h>
> > > #include <asm/cpu.h>
> > > #include <asm/cpu-features.h>
> >
> > This is adding a 2nd inclusion of <asm/current.h>. Will fix that.
>
> Thanks! I resisted the temptation to include changes to sort inclusions
> with this series or it would risk becoming an ever going effort. Though
> it would have avoided an oversight like this.
I found it only because once in a blue moon I run the various checkers
that ship with the kernel. Turns out half of them don't work out of
the box, at least not for my setup so there's yet more work to do.
Ralf
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again
2015-04-07 17:31 ` Ralf Baechle
@ 2015-04-07 23:11 ` Maciej W. Rozycki
0 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2015-04-07 23:11 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
On Tue, 7 Apr 2015, Ralf Baechle wrote:
> > One point to make here is the use of `ieee754dp_sub' and `ieee754dp_add'
> > makes emulated ABS.fmt and NEG.fmt respect FCSR.FS for denormals just as
> > hardware does. I should have noted that in the commit message, perhaps it
> > can be retrofitted?
>
> Yes, it can. Just send the new commit message.
I take it back, the FLUSHXSP and FLUSHXDP macros the old implementation
had did handle FCSR.FS. So the original message is good. Sorry for the
confusion.
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation
2015-04-03 22:26 ` [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation Maciej W. Rozycki
@ 2016-01-20 10:50 ` Aurelien Jarno
2016-01-20 15:15 ` Maciej W. Rozycki
0 siblings, 1 reply; 62+ messages in thread
From: Aurelien Jarno @ 2016-01-20 10:50 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips
Hi,
On 2015-04-03 23:26, Maciej W. Rozycki wrote:
> Restore EPC at the branch whose delay slot is emulated if the delay-slot
> instruction signals. This is so that code in `fpu_emulator_cop1Handler'
> does not see EPC having advanced and mistakenly successfully resume
> userland execution from the location at the branch target in that case.
> Restoring EPC guarantees an immediate exit from the emulation loop and
> if EPC hasn't advanced at all since entering the loop, also issuing the
> signal reported by the delay-slot instruction.
>
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> ---
Unfortunately this patch broke the case where the delay slot contains a
NOP instruction. In practice this causes a lot of code to now fails with
a SIGILL. For example the following code, extracted from R, reports a
SIGILL address 0x76f29670.
=> 0x76f29670: ldc1 $f2,40(s8)
0x76f29674: ldc1 $f0,40(s8)
0x76f29678: add.d $f0,$f2,$f0
0x76f2967c: sdc1 $f0,40(s8)
0x76f29680: ldc1 $f2,40(s8)
0x76f29684: ldc1 $f0,80(s8)
0x76f29688: add.d $f0,$f2,$f0
0x76f2968c: sdc1 $f0,96(s8)
0x76f29690: ldc1 $f2,96(s8)
0x76f29694: ldc1 $f0,40(s8)
0x76f29698: sub.d $f0,$f2,$f0
0x76f2969c: sdc1 $f0,112(s8)
0x76f296a0: ldc1 $f2,112(s8)
0x76f296a4: ldc1 $f0,80(s8)
0x76f296a8: sub.d $f2,$f2,$f0
0x76f296ac: ldc1 $f0,144(s8)
0x76f296b0: c.eq.d $f2,$f0
0x76f296b4: bc1t 0x76f29670
0x76f296b8: nop
The issues lies in the following part of the patch:
> --- linux.orig/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:57.493218000 +0100
> +++ linux/arch/mips/math-emu/cp1emu.c 2015-04-02 20:27:57.710224000 +0100
> @@ -1192,16 +1208,24 @@ static int cop1Emulate(struct pt_regs *x
> if (cpu_has_mips_4_5_r)
> goto emul;
>
> - return SIGILL;
> + goto bc_sigill;
> }
> break;
> +
> + bc_sigill:
> + xcp->cp0_epc = bcpc;
> + return SIGILL;
> }
>
> /*
> * Single step the non-cp1
> * instruction in the dslot
> */
> - return mips_dsemul(xcp, ir, contpc);
> + sig = mips_dsemul(xcp, ir, contpc);
> + if (sig)
> + xcp->cp0_epc = bcpc;
> + /* SIGILL forces out of the emulation loop. */
> + return sig ? sig : SIGILL;
This assumes we should get out of the emulation loop if the returned
value is 0. However this value is used to signal the instruction has
been emulated in case of a NOP.
> } else if (likely) { /* branch not taken */
> /*
> * branch likely nullifies
> Index: linux/arch/mips/math-emu/dsemul.c
> ===================================================================
> --- linux.orig/arch/mips/math-emu/dsemul.c 2015-04-02 20:27:57.133225000 +0100
> +++ linux/arch/mips/math-emu/dsemul.c 2015-04-02 20:27:57.713219000 +0100
> @@ -96,7 +96,7 @@ int mips_dsemul(struct pt_regs *regs, mi
>
> flush_cache_sigtramp((unsigned long)&fr->emul);
>
> - return SIGILL; /* force out of emulation loop */
> + return 0;
With this change there is no way to distinguish the NOP case and the
normal instruction case anymore.
An easy workaround to the issue (with performance impact though) is to
get rid of the NOP special case in dsemul.c
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index cbb36c1..c6e3901 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -35,7 +35,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
{
struct emuframe __user *fr;
int err;
-
+#if 0
if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) ||
(ir == 0)) {
/* NOP is easy */
@@ -43,7 +43,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
clear_delay_slot(regs);
return 0;
}
-
+#endif
pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
/*
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation
2016-01-20 10:50 ` Aurelien Jarno
@ 2016-01-20 15:15 ` Maciej W. Rozycki
0 siblings, 0 replies; 62+ messages in thread
From: Maciej W. Rozycki @ 2016-01-20 15:15 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: Ralf Baechle, linux-mips
Hi Aurelien,
> On 2015-04-03 23:26, Maciej W. Rozycki wrote:
> > Restore EPC at the branch whose delay slot is emulated if the delay-slot
> > instruction signals. This is so that code in `fpu_emulator_cop1Handler'
> > does not see EPC having advanced and mistakenly successfully resume
> > userland execution from the location at the branch target in that case.
> > Restoring EPC guarantees an immediate exit from the emulation loop and
> > if EPC hasn't advanced at all since entering the loop, also issuing the
> > signal reported by the delay-slot instruction.
> >
> > Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
> > ---
>
> Unfortunately this patch broke the case where the delay slot contains a
> NOP instruction. In practice this causes a lot of code to now fails with
> a SIGILL. For example the following code, extracted from R, reports a
> SIGILL address 0x76f29670.
>
> => 0x76f29670: ldc1 $f2,40(s8)
> 0x76f29674: ldc1 $f0,40(s8)
> 0x76f29678: add.d $f0,$f2,$f0
> 0x76f2967c: sdc1 $f0,40(s8)
> 0x76f29680: ldc1 $f2,40(s8)
> 0x76f29684: ldc1 $f0,80(s8)
> 0x76f29688: add.d $f0,$f2,$f0
> 0x76f2968c: sdc1 $f0,96(s8)
> 0x76f29690: ldc1 $f2,96(s8)
> 0x76f29694: ldc1 $f0,40(s8)
> 0x76f29698: sub.d $f0,$f2,$f0
> 0x76f2969c: sdc1 $f0,112(s8)
> 0x76f296a0: ldc1 $f2,112(s8)
> 0x76f296a4: ldc1 $f0,80(s8)
> 0x76f296a8: sub.d $f2,$f2,$f0
> 0x76f296ac: ldc1 $f0,144(s8)
> 0x76f296b0: c.eq.d $f2,$f0
> 0x76f296b4: bc1t 0x76f29670
> 0x76f296b8: nop
Thanks for your report, I'll have a look ASAP.
Maciej
^ permalink raw reply [flat|nested] 62+ messages in thread
end of thread, other threads:[~2016-01-20 15:15 UTC | newest]
Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-03 22:23 [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 01/48] doc: kernel-parameters.txt: Mark `nofpu' for MIPS too Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 02/48] MIPS: mipsregs.h: Remove broken comments Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 03/48] MIPS: mipsregs.h: Reorder CP1 macro definitions Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 04/48] MIPS: mipsregs.h: Move TX39 macros out of the way Maciej W. Rozycki
2015-04-03 22:23 ` [PATCH 05/48] MIPS: mipsregs.h: Reindent CP0 Cause macros Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 06/48] MIPS: ieee754.h: Correct comments for special values Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 07/48] MIPS: ieee754.h: Supplement " Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 08/48] MIPS: Correct the comment for FPU emulator traps Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 09/48] MIPS: Clarify the comment for `__cpu_has_fpu' Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 10/48] MIPS: math-emu: Reindent `bc_op' emulation Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 11/48] MIPS: Correct the comment for and reformat `movf_func' Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 12/48] MIPS: math-emu: Fix oversize lines in comparisons Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 13/48] MIPS: ELF: Drop `get_fp_abi' Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 14/48] MIPS: mips-r2-to-r6-emul.h: Inline empty `mipsr2_decoder' Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 15/48] MIPS: Reindent R6 RI exception emulation Maciej W. Rozycki
2015-04-03 22:24 ` [PATCH 16/48] MIPS: math-emu: Remove `modeindex' macro Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 17/48] MIPS: bitops.h: Avoid inline asm for constant FLS Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 18/48] MIPS: math-emu: Factor out CFC1/CTC1 emulation Maciej W. Rozycki
2015-04-03 23:33 ` Sergei Shtylyov
2015-04-04 0:07 ` Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 19/48] MIPS: Normalise code flow in the CpU exception handler Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 20/48] MIPS: Use `FPU_CSR_ALL_X' in `__build_clear_fpe' Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 21/48] MIPS: math-emu: Update sNaN quieting handlers Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 23/48] MIPS: math-emu: Don't pass qNaNs through " Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 24/48] MIPS: math-emu: Reinstate sNaN " Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 25/48] MIPS: math-emu: Optimise NaN handling in comparisons Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 26/48] MIPS: math-emu: Remove redundant code from NaN comparison Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 27/48] MIPS: math-emu: Remove dead comparison helpers Maciej W. Rozycki
2015-04-03 22:25 ` [PATCH 29/48] MIPS: math-emu: Make NaN classifiers static Maciej W. Rozycki
2015-04-03 23:22 ` Sergei Shtylyov
2015-04-03 22:26 ` [PATCH 30/48] MIPS: Correct `nofpu' non-functionality Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 31/48] MIPS: Correct MIPS16 BREAK code interpretation Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 32/48] MIPS: BREAK instruction interpretation corrections Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 33/48] MIPS: Fix BREAK code interpretation heuristics Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 34/48] MIPS: math-emu: Fix delay-slot emulation cache incoherency Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 35/48] MIPS: Correct MIPS I FP context layout Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 36/48] MIPS: Correct FP ISA requirements Maciej W. Rozycki
2015-04-03 22:26 ` [PATCH 37/48] MIPS: math-emu: Correct delay-slot exception propagation Maciej W. Rozycki
2016-01-20 10:50 ` Aurelien Jarno
2016-01-20 15:15 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 38/48] MIPS: math-emu: Move long fixed-point support into an `ar' library Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 39/48] MIPS: Respect the FCSR exception mask for `si_code' Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 40/48] MIPS: Always clear FCSR cause bits after emulation Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 41/48] MIPS: Set `si_code' for SIGFPE signals sent from emulation too Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 42/48] MIPS: Correct ISA masking in FPU feature determination Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 43/48] MIPS: math-emu: Set FIR feature flags for full emulation Maciej W. Rozycki
2015-04-03 23:18 ` Sergei Shtylyov
2015-04-03 22:27 ` [PATCH 44/48] MIPS: math-emu: Implement the FCCR, FEXR and FENR registers Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 45/48] MIPS: math-emu: Define IEEE 754-2008 feature control bits Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 46/48] MIPS: math-emu: Make ABS.fmt and NEG.fmt arithmetic again Maciej W. Rozycki
2015-04-07 15:24 ` Maciej W. Rozycki
2015-04-07 17:31 ` Ralf Baechle
2015-04-07 23:11 ` Maciej W. Rozycki
2015-04-03 22:27 ` [PATCH 47/48] MIPS: Respect the ISA level in FCSR handling Maciej W. Rozycki
2015-04-07 12:54 ` Ralf Baechle
2015-04-07 21:13 ` Maciej W. Rozycki
2015-04-07 22:45 ` Ralf Baechle
2015-04-03 22:27 ` [PATCH 48/48] MIPS: Factor out FPU feature probing Maciej W. Rozycki
2015-04-04 20:04 ` [PATCH 00/48] FPU and FP emulation clean-ups, fixes and feature updates Ralf Baechle
2015-04-04 20:55 ` Maciej W. Rozycki
2015-04-04 21:57 ` Ralf Baechle
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.