diff --git a/arch/nds32/include/asm/bitfield.h b/arch/nds32/include/asm/bitfield.h
index e75212c76b2044aa17badc5d77f5f5ad61cf8f30..b02a58e71f8097ec56dd7ee089c5ed76ed0e2ee7 100644
--- a/arch/nds32/include/asm/bitfield.h
+++ b/arch/nds32/include/asm/bitfield.h
@@ -937,7 +937,7 @@
 #define FPCSR_mskDNIT           ( 0x1  << FPCSR_offDNIT )
 #define FPCSR_mskRIT		( 0x1  << FPCSR_offRIT )
 #define FPCSR_mskALL		(FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX)
-#define FPCSR_mskALLE_NO_UDFE	(FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskIEXE)
+#define FPCSR_mskALLE_NO_UDF_IEXE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE)
 #define FPCSR_mskALLE		(FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE)
 #define FPCSR_mskALLT           (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT)
 
diff --git a/arch/nds32/include/asm/fpu.h b/arch/nds32/include/asm/fpu.h
index 019f1bcfc5ee17e4f5390ebaa7806ec90395e9f2..8294ed4aaa2cc950aec294aa69d50c16ee7f443d 100644
--- a/arch/nds32/include/asm/fpu.h
+++ b/arch/nds32/include/asm/fpu.h
@@ -36,7 +36,7 @@ extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu);
  * enabled by default and kerenl will re-execute it by fpu emulator
  * when getting underflow exception.
  */
-#define FPCSR_INIT  FPCSR_mskUDFE
+#define FPCSR_INIT  (FPCSR_mskUDFE | FPCSR_mskIEXE)
 #else
 #define FPCSR_INIT  0x0UL
 #endif
diff --git a/arch/nds32/include/asm/fpuemu.h b/arch/nds32/include/asm/fpuemu.h
index c4bd0c7faa75facfdb5002b90292e1514cedc1b6..63e7ef5f7969ba543c75366bcabd6e70951b63c5 100644
--- a/arch/nds32/include/asm/fpuemu.h
+++ b/arch/nds32/include/asm/fpuemu.h
@@ -13,6 +13,12 @@ void fsubs(void *ft, void *fa, void *fb);
 void fmuls(void *ft, void *fa, void *fb);
 void fdivs(void *ft, void *fa, void *fb);
 void fs2d(void *ft, void *fa);
+void fs2si(void *ft, void *fa);
+void fs2si_z(void *ft, void *fa);
+void fs2ui(void *ft, void *fa);
+void fs2ui_z(void *ft, void *fa);
+void fsi2s(void *ft, void *fa);
+void fui2s(void *ft, void *fa);
 void fsqrts(void *ft, void *fa);
 void fnegs(void *ft, void *fa);
 int fcmps(void *ft, void *fa, void *fb, int cop);
@@ -26,6 +32,12 @@ void fmuld(void *ft, void *fa, void *fb);
 void fdivd(void *ft, void *fa, void *fb);
 void fsqrtd(void *ft, void *fa);
 void fd2s(void *ft, void *fa);
+void fd2si(void *ft, void *fa);
+void fd2si_z(void *ft, void *fa);
+void fd2ui(void *ft, void *fa);
+void fd2ui_z(void *ft, void *fa);
+void fsi2d(void *ft, void *fa);
+void fui2d(void *ft, void *fa);
 void fnegd(void *ft, void *fa);
 int fcmpd(void *ft, void *fa, void *fb, int cop);
 
diff --git a/arch/nds32/include/asm/syscalls.h b/arch/nds32/include/asm/syscalls.h
index f3b16f602cb5389c924a18c57e4d105407faaee4..4e7216082a6725e79030c8a06c19a4996d2e4319 100644
--- a/arch/nds32/include/asm/syscalls.h
+++ b/arch/nds32/include/asm/syscalls.h
@@ -7,7 +7,7 @@
 asmlinkage long sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op);
 asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len);
 asmlinkage long sys_rt_sigreturn_wrapper(void);
-asmlinkage long sys_udftrap(int option);
+asmlinkage long sys_fp_udfiex_crtl(int cmd, int act);
 
 #include <asm-generic/syscalls.h>
 
diff --git a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
new file mode 100644
index 0000000000000000000000000000000000000000..d54a5d6c65389b8fff804962c052995671be1c5a
--- /dev/null
+++ b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2005-2019 Andes Technology Corporation */
+#ifndef	_FP_UDF_IEX_CRTL_H
+#define	_FP_UDF_IEX_CRTL_H
+
+/*
+ * The cmd list of sys_fp_udfiex_crtl()
+ */
+/* Disable UDF or IEX trap based on the content of parameter act */
+#define DISABLE_UDF_IEX_TRAP	0
+/* Enable UDF or IEX trap based on the content of parameter act */
+#define ENABLE_UDF_IEX_TRAP	1
+/* Get current status of UDF and IEX trap */
+#define GET_UDF_IEX_TRAP	2
+
+#endif /* _FP_UDF_IEX_CRTL_H */
diff --git a/arch/nds32/include/uapi/asm/sigcontext.h b/arch/nds32/include/uapi/asm/sigcontext.h
index 628ff6b75825a18c77562c1285268c3c189846e7..dc89af7ddcc3d0ce497c13a04787c78f12df12ba 100644
--- a/arch/nds32/include/uapi/asm/sigcontext.h
+++ b/arch/nds32/include/uapi/asm/sigcontext.h
@@ -13,14 +13,24 @@ struct fpu_struct {
 	unsigned long long fd_regs[32];
 	unsigned long fpcsr;
 	/*
-	 * UDF_trap is used to recognize whether underflow trap is enabled
-	 * or not. When UDF_trap == 1, this process will be traped and then
-	 * get a SIGFPE signal when encountering an underflow exception.
-	 * UDF_trap is only modified through setfputrap syscall. Therefore,
-	 * UDF_trap needn't be saved or loaded to context in each context
-	 * switch.
+	 * When CONFIG_SUPPORT_DENORMAL_ARITHMETIC is defined, kernel prevents
+	 * hardware from treating the denormalized output as an underflow case
+	 * and rounding it to a normal number. Hence kernel enables the UDF and
+	 * IEX trap in the fpcsr register to step in the calculation.
+	 * However, the UDF and IEX trap enable bit in $fpcsr also lose
+	 * their use.
+	 *
+	 * UDF_IEX_trap replaces the feature of UDF and IEX trap enable bit in
+	 * $fpcsr to control the trap of underflow and inexact. The bit filed
+	 * of UDF_IEX_trap is the same as $fpcsr, 10th bit is used to enable UDF
+	 * exception trapping and 11th bit is used to enable IEX exception
+	 * trapping.
+	 *
+	 * UDF_IEX_trap is only modified through fp_udfiex_crtl syscall.
+	 * Therefore, UDF_IEX_trap needn't be saved and restored in each
+	 * context switch.
 	 */
-	unsigned long UDF_trap;
+	unsigned long UDF_IEX_trap;
 };
 
 struct zol_struct {
diff --git a/arch/nds32/include/uapi/asm/udftrap.h b/arch/nds32/include/uapi/asm/udftrap.h
deleted file mode 100644
index 433f79d679c0acedcbf4dfd6e356b3fc2047998d..0000000000000000000000000000000000000000
--- a/arch/nds32/include/uapi/asm/udftrap.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2005-2018 Andes Technology Corporation */
-#ifndef	_ASM_SETFPUTRAP
-#define	_ASM_SETFPUTRAP
-
-/*
- * Options for setfputrap system call
- */
-#define	DISABLE_UDFTRAP	0	/* disable underflow exception trap */
-#define	ENABLE_UDFTRAP	1	/* enable undeflos exception trap */
-#define	GET_UDFTRAP	2	/* only get undeflos exception trap status */
-
-#endif /* _ASM_CACHECTL */
diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h
index c691735017ed59724f760b859a2c739780835b10..a0b2f7b9c0f29a8b1b2c5a42f6c7032033590d22 100644
--- a/arch/nds32/include/uapi/asm/unistd.h
+++ b/arch/nds32/include/uapi/asm/unistd.h
@@ -11,6 +11,6 @@
 
 /* Additional NDS32 specific syscalls. */
 #define __NR_cacheflush		(__NR_arch_specific_syscall)
-#define __NR_udftrap		(__NR_arch_specific_syscall + 1)
+#define __NR_fp_udfiex_crtl	(__NR_arch_specific_syscall + 1)
 __SYSCALL(__NR_cacheflush, sys_cacheflush)
-__SYSCALL(__NR_udftrap, sys_udftrap)
+__SYSCALL(__NR_fp_udfiex_crtl, sys_fp_udfiex_crtl)
diff --git a/arch/nds32/kernel/fpu.c b/arch/nds32/kernel/fpu.c
index fddd40c7a16f9880d2082cb71aa3431ac4192ac5..cf0b8760f2616d287fe238854dbe0b53e55a40ea 100644
--- a/arch/nds32/kernel/fpu.c
+++ b/arch/nds32/kernel/fpu.c
@@ -14,7 +14,7 @@ const struct fpu_struct init_fpuregs = {
 	.fd_regs = {[0 ... 31] = sNAN64},
 	.fpcsr = FPCSR_INIT,
 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-	.UDF_trap = 0
+	.UDF_IEX_trap = 0
 #endif
 };
 
@@ -178,7 +178,7 @@ inline void do_fpu_context_switch(struct pt_regs *regs)
 		/* First time FPU user.  */
 		load_fpu(&init_fpuregs);
 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-		current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap;
+		current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
 #endif
 		set_used_math();
 	}
@@ -206,7 +206,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
 	unsigned int fpcsr;
 	int si_code = 0, si_signo = SIGFPE;
 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-	unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT;
+	unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT|FPCSR_mskIEXT;
 #else
 	unsigned long redo_except = FPCSR_mskDNIT;
 #endif
@@ -215,21 +215,18 @@ inline void handle_fpu_exception(struct pt_regs *regs)
 	fpcsr = current->thread.fpu.fpcsr;
 
 	if (fpcsr & redo_except) {
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-		if (fpcsr & FPCSR_mskUDFT)
-			current->thread.fpu.fpcsr &= ~FPCSR_mskIEX;
-#endif
 		si_signo = do_fpuemu(regs, &current->thread.fpu);
 		fpcsr = current->thread.fpu.fpcsr;
-		if (!si_signo)
+		if (!si_signo) {
+			current->thread.fpu.fpcsr &= ~(redo_except);
 			goto done;
+		}
 	} else if (fpcsr & FPCSR_mskRIT) {
 		if (!user_mode(regs))
 			do_exit(SIGILL);
 		si_signo = SIGILL;
 	}
 
-
 	switch (si_signo) {
 	case SIGFPE:
 		fill_sigfpe_signo(fpcsr, &si_code);
diff --git a/arch/nds32/kernel/sys_nds32.c b/arch/nds32/kernel/sys_nds32.c
index 0835277636ce31f1a3ba75dbbcd33a7d0f0d31eb..cb2d1e219bb3b77387ff7607231edf8a2475b55c 100644
--- a/arch/nds32/kernel/sys_nds32.c
+++ b/arch/nds32/kernel/sys_nds32.c
@@ -6,8 +6,8 @@
 
 #include <asm/cachectl.h>
 #include <asm/proc-fns.h>
-#include <asm/udftrap.h>
 #include <asm/fpu.h>
+#include <asm/fp_udfiex_crtl.h>
 
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 	       unsigned long, prot, unsigned long, flags,
@@ -51,31 +51,33 @@ SYSCALL_DEFINE3(cacheflush, unsigned int, start, unsigned int, end, int, cache)
 	return 0;
 }
 
-SYSCALL_DEFINE1(udftrap, int, option)
+SYSCALL_DEFINE2(fp_udfiex_crtl, unsigned int, cmd, unsigned int, act)
 {
 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-	int old_udftrap;
+	int old_udf_iex;
 
 	if (!used_math()) {
 		load_fpu(&init_fpuregs);
-		current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap;
+		current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
 		set_used_math();
 	}
 
-	old_udftrap = current->thread.fpu.UDF_trap;
-	switch (option) {
-	case DISABLE_UDFTRAP:
-		current->thread.fpu.UDF_trap = 0;
+	old_udf_iex = current->thread.fpu.UDF_IEX_trap;
+	act &= (FPCSR_mskUDFE | FPCSR_mskIEXE);
+
+	switch (cmd) {
+	case DISABLE_UDF_IEX_TRAP:
+		current->thread.fpu.UDF_IEX_trap &= ~act;
 		break;
-	case ENABLE_UDFTRAP:
-		current->thread.fpu.UDF_trap = FPCSR_mskUDFE;
+	case ENABLE_UDF_IEX_TRAP:
+		current->thread.fpu.UDF_IEX_trap |= act;
 		break;
-	case GET_UDFTRAP:
+	case GET_UDF_IEX_TRAP:
 		break;
 	default:
 		return -EINVAL;
 	}
-	return old_udftrap;
+	return old_udf_iex;
 #else
 	return -ENOTSUPP;
 #endif
diff --git a/arch/nds32/math-emu/Makefile b/arch/nds32/math-emu/Makefile
index 14fa01f4574ae8679ef5662eba64ccd7967c4728..3bed7e5d5d05d7d7e6025e6b6e94fe13777fc767 100644
--- a/arch/nds32/math-emu/Makefile
+++ b/arch/nds32/math-emu/Makefile
@@ -5,4 +5,6 @@
 
 obj-y	:= fpuemu.o \
 	   fdivd.o fmuld.o fsubd.o faddd.o fs2d.o fsqrtd.o fcmpd.o fnegs.o \
-	   fdivs.o fmuls.o fsubs.o fadds.o fd2s.o fsqrts.o fcmps.o fnegd.o
+	   fd2si.o fd2ui.o fd2siz.o fd2uiz.o fsi2d.o fui2d.o \
+	   fdivs.o fmuls.o fsubs.o fadds.o fd2s.o fsqrts.o fcmps.o fnegd.o \
+	   fs2si.o fs2ui.o fs2siz.o fs2uiz.o fsi2s.o fui2s.o
diff --git a/arch/nds32/math-emu/fd2si.c b/arch/nds32/math-emu/fd2si.c
new file mode 100644
index 0000000000000000000000000000000000000000..fae3e16a0a10317925613ca6fe5704dce7228889
--- /dev/null
+++ b/arch/nds32/math-emu/fd2si.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+
+void fd2si(void *ft, void *fa)
+{
+	int r;
+
+	FP_DECL_D(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_DP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_ROUND_D(r, A, 32, 1);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(int *)ft = r;
+	}
+
+}
diff --git a/arch/nds32/math-emu/fd2siz.c b/arch/nds32/math-emu/fd2siz.c
new file mode 100644
index 0000000000000000000000000000000000000000..92fe6774f112e623f90ac37cb0478dc239ba9bfd
--- /dev/null
+++ b/arch/nds32/math-emu/fd2siz.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+
+void fd2si_z(void *ft, void *fa)
+{
+	int r;
+
+	FP_DECL_D(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_DP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_D(r, A, 32, 1);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(int *)ft = r;
+	}
+
+}
diff --git a/arch/nds32/math-emu/fd2ui.c b/arch/nds32/math-emu/fd2ui.c
new file mode 100644
index 0000000000000000000000000000000000000000..a0423b699aa4a14d1eb1506298ba57009fbafa0d
--- /dev/null
+++ b/arch/nds32/math-emu/fd2ui.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+
+void fd2ui(void *ft, void *fa)
+{
+	unsigned int r;
+
+	FP_DECL_D(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_DP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(unsigned int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_ROUND_D(r, A, 32, 0);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(unsigned int *)ft = r;
+	}
+
+}
diff --git a/arch/nds32/math-emu/fd2uiz.c b/arch/nds32/math-emu/fd2uiz.c
new file mode 100644
index 0000000000000000000000000000000000000000..8ae17cfce90d93d33157f655cafa3d5fb01b932b
--- /dev/null
+++ b/arch/nds32/math-emu/fd2uiz.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+
+void fd2ui_z(void *ft, void *fa)
+{
+	unsigned int r;
+
+	FP_DECL_D(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_DP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(unsigned int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_D(r, A, 32, 0);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(unsigned int *)ft = r;
+	}
+
+}
diff --git a/arch/nds32/math-emu/fpuemu.c b/arch/nds32/math-emu/fpuemu.c
index 75cf1643fa78e6ede16924169cdddb49187e05ce..46558a15c0dce5cbec114af536d1aedfc79ef35c 100644
--- a/arch/nds32/math-emu/fpuemu.c
+++ b/arch/nds32/math-emu/fpuemu.c
@@ -113,6 +113,30 @@ static int fpu_emu(struct fpu_struct *fpu_reg, unsigned long insn)
 					func.b = fs2d;
 					ftype = S1D;
 					break;
+				case fs2si_op:
+					func.b = fs2si;
+					ftype = S1S;
+					break;
+				case fs2si_z_op:
+					func.b = fs2si_z;
+					ftype = S1S;
+					break;
+				case fs2ui_op:
+					func.b = fs2ui;
+					ftype = S1S;
+					break;
+				case fs2ui_z_op:
+					func.b = fs2ui_z;
+					ftype = S1S;
+					break;
+				case fsi2s_op:
+					func.b = fsi2s;
+					ftype = S1S;
+					break;
+				case fui2s_op:
+					func.b = fui2s;
+					ftype = S1S;
+					break;
 				case fsqrts_op:
 					func.b = fsqrts;
 					ftype = S1S;
@@ -182,6 +206,30 @@ static int fpu_emu(struct fpu_struct *fpu_reg, unsigned long insn)
 					func.b = fd2s;
 					ftype = D1S;
 					break;
+				case fd2si_op:
+					func.b = fd2si;
+					ftype = D1S;
+					break;
+				case fd2si_z_op:
+					func.b = fd2si_z;
+					ftype = D1S;
+					break;
+				case fd2ui_op:
+					func.b = fd2ui;
+					ftype = D1S;
+					break;
+				case fd2ui_z_op:
+					func.b = fd2ui_z;
+					ftype = D1S;
+					break;
+				case fsi2d_op:
+					func.b = fsi2d;
+					ftype = D1S;
+					break;
+				case fui2d_op:
+					func.b = fui2d;
+					ftype = D1S;
+					break;
 				case fsqrtd_op:
 					func.b = fsqrtd;
 					ftype = D1D;
@@ -305,16 +353,16 @@ static int fpu_emu(struct fpu_struct *fpu_reg, unsigned long insn)
 	 * If an exception is required, generate a tidy SIGFPE exception.
 	 */
 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-	if (((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE_NO_UDFE) ||
-	    ((fpu_reg->fpcsr & FPCSR_mskUDF) && (fpu_reg->UDF_trap)))
+	if (((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE_NO_UDF_IEXE)
+	    || ((fpu_reg->fpcsr << 5) & (fpu_reg->UDF_IEX_trap))) {
 #else
-	if ((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE)
+	if ((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE) {
 #endif
 		return SIGFPE;
+	}
 	return 0;
 }
 
-
 int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu)
 {
 	unsigned long insn = 0, addr = regs->ipc;
@@ -336,6 +384,7 @@ int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu)
 
 	if (NDS32Insn_OPCODE(insn) != cop0_op)
 		return SIGILL;
+
 	switch (NDS32Insn_OPCODE_COP0(insn)) {
 	case fs1_op:
 	case fs2_op:
diff --git a/arch/nds32/math-emu/fs2si.c b/arch/nds32/math-emu/fs2si.c
new file mode 100644
index 0000000000000000000000000000000000000000..b4931d60980eef2bd1756a59b772876d60060e28
--- /dev/null
+++ b/arch/nds32/math-emu/fs2si.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+void fs2si(void *ft, void *fa)
+{
+	int r;
+
+	FP_DECL_S(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_SP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_ROUND_S(r, A, 32, 1);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(int *)ft = r;
+	}
+}
diff --git a/arch/nds32/math-emu/fs2siz.c b/arch/nds32/math-emu/fs2siz.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c2b99ce3e382d5c9c2b8f9672d25464dd1c4fd5
--- /dev/null
+++ b/arch/nds32/math-emu/fs2siz.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+void fs2si_z(void *ft, void *fa)
+{
+	int r;
+
+	FP_DECL_S(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_SP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_S(r, A, 32, 1);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(int *)ft = r;
+	}
+}
diff --git a/arch/nds32/math-emu/fs2ui.c b/arch/nds32/math-emu/fs2ui.c
new file mode 100644
index 0000000000000000000000000000000000000000..c337f0384d06796d4dc19171062faeee6b0d2792
--- /dev/null
+++ b/arch/nds32/math-emu/fs2ui.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+void fs2ui(void *ft, void *fa)
+{
+	unsigned int r;
+
+	FP_DECL_S(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_SP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(unsigned int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_ROUND_S(r, A, 32, 0);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(unsigned int *)ft = r;
+	}
+}
diff --git a/arch/nds32/math-emu/fs2uiz.c b/arch/nds32/math-emu/fs2uiz.c
new file mode 100644
index 0000000000000000000000000000000000000000..22c5e4768044a88d0b87cbabf2a1e6d9b1341b14
--- /dev/null
+++ b/arch/nds32/math-emu/fs2uiz.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+void fs2ui_z(void *ft, void *fa)
+{
+	unsigned int r;
+
+	FP_DECL_S(A);
+	FP_DECL_EX;
+
+	FP_UNPACK_SP(A, fa);
+
+	if (A_c == FP_CLS_INF) {
+		*(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else if (A_c == FP_CLS_NAN) {
+		*(unsigned int *)ft = 0xffffffff;
+		__FPU_FPCSR |= FP_EX_INVALID;
+	} else {
+		FP_TO_INT_S(r, A, 32, 0);
+		__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+		*(unsigned int *)ft = r;
+	}
+
+}
diff --git a/arch/nds32/math-emu/fsi2d.c b/arch/nds32/math-emu/fsi2d.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b04cec0c5c54ee089ff124d10098f7ce61e0ad0
--- /dev/null
+++ b/arch/nds32/math-emu/fsi2d.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+
+void fsi2d(void *ft, void *fa)
+{
+	int a = *(int *)fa;
+
+	FP_DECL_D(R);
+	FP_DECL_EX;
+
+	FP_FROM_INT_D(R, a, 32, int);
+
+	FP_PACK_DP(ft, R);
+
+	__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+
+}
diff --git a/arch/nds32/math-emu/fsi2s.c b/arch/nds32/math-emu/fsi2s.c
new file mode 100644
index 0000000000000000000000000000000000000000..689864a5df905b44c216d0e9435b24a0376fd2f3
--- /dev/null
+++ b/arch/nds32/math-emu/fsi2s.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+void fsi2s(void *ft, void *fa)
+{
+	int a = *(int *)fa;
+
+	FP_DECL_S(R);
+	FP_DECL_EX;
+
+	FP_FROM_INT_S(R, a, 32, int);
+
+	FP_PACK_SP(ft, R);
+
+	__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+
+}
diff --git a/arch/nds32/math-emu/fui2d.c b/arch/nds32/math-emu/fui2d.c
new file mode 100644
index 0000000000000000000000000000000000000000..9689d33a8d5094fd20467aa41948ca269a9c3b54
--- /dev/null
+++ b/arch/nds32/math-emu/fui2d.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+
+void fui2d(void *ft, void *fa)
+{
+	unsigned int a = *(unsigned int *)fa;
+
+	FP_DECL_D(R);
+	FP_DECL_EX;
+
+	FP_FROM_INT_D(R, a, 32, int);
+
+	FP_PACK_DP(ft, R);
+
+	__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+
+}
diff --git a/arch/nds32/math-emu/fui2s.c b/arch/nds32/math-emu/fui2s.c
new file mode 100644
index 0000000000000000000000000000000000000000..f70f0762547dea26e71e42de98b429e39ff563bb
--- /dev/null
+++ b/arch/nds32/math-emu/fui2s.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2019 Andes Technology Corporation
+#include <linux/uaccess.h>
+
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+void fui2s(void *ft, void *fa)
+{
+	unsigned int a = *(unsigned int *)fa;
+
+	FP_DECL_S(R);
+	FP_DECL_EX;
+
+	FP_FROM_INT_S(R, a, 32, int);
+
+	FP_PACK_SP(ft, R);
+
+	__FPU_FPCSR |= FP_CUR_EXCEPTIONS;
+
+}
diff --git a/include/math-emu/op-2.h b/include/math-emu/op-2.h
index 13a374f51a225bf77f9b19189a1145001fae3c5a..244522b020769cb96aeadf7cb64823b3493088ea 100644
--- a/include/math-emu/op-2.h
+++ b/include/math-emu/op-2.h
@@ -567,16 +567,13 @@
  */
 
 #define _FP_FRAC_ASSEMBLE_2(r, X, rsize)	\
-  do {						\
-    if (rsize <= _FP_W_TYPE_SIZE)		\
-      r = X##_f0;				\
-    else					\
-      {						\
-	r = X##_f1;				\
-	r <<= _FP_W_TYPE_SIZE;			\
-	r += X##_f0;				\
-      }						\
-  } while (0)
+	(void) (((rsize) <= _FP_W_TYPE_SIZE)	\
+		? ({ (r) = X##_f0; })		\
+		: ({				\
+		     (r) = X##_f1;		\
+		     (r) <<= _FP_W_TYPE_SIZE;	\
+		     (r) += X##_f0;		\
+		    }))
 
 #define _FP_FRAC_DISASSEMBLE_2(X, r, rsize)				\
   do {									\
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index 6bdf8c61d221f7267914974958f96f2cc2156460..f37d12877754b05a3f534097d7fd7c957326c94e 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -795,11 +795,12 @@ do {									\
 	  ur_ = (unsigned rtype) -r;					\
 	else								\
 	  ur_ = (unsigned rtype) r;					\
-	if (rsize <= _FP_W_TYPE_SIZE)					\
-	  __FP_CLZ(X##_e, ur_);						\
-	else								\
-	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), 	\
-		     (_FP_W_TYPE)ur_);					\
+	(void) (((rsize) <= _FP_W_TYPE_SIZE)				\
+		? ({ __FP_CLZ(X##_e, ur_); })				\
+		: ({							\
+		     __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE),  \
+							    (_FP_W_TYPE)ur_); \
+		  }));							\
 	if (rsize < _FP_W_TYPE_SIZE)					\
 		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
 	X##_e = rsize - X##_e - 1;					\