Skip to content

Commit 30d1d92

Browse files
committed
Merge tag 'nds32-for-linux-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux
Pull nds32 fixes from Greentime Hu: - fix warning for math-emu - fix nds32 fpu exception handling - fix nds32 fpu emulation implementation * tag 'nds32-for-linux-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux: nds32: add new emulations for floating point instruction nds32: Avoid IEX status being incorrectly modified math-emu: Use statement expressions to fix Wshift-count-overflow warning
2 parents 01e7a84 + 9322961 commit 30d1d92

File tree

26 files changed

+464
-66
lines changed

26 files changed

+464
-66
lines changed

arch/nds32/include/asm/bitfield.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@
937937
#define FPCSR_mskDNIT ( 0x1 << FPCSR_offDNIT )
938938
#define FPCSR_mskRIT ( 0x1 << FPCSR_offRIT )
939939
#define FPCSR_mskALL (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX)
940-
#define FPCSR_mskALLE_NO_UDFE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskIEXE)
940+
#define FPCSR_mskALLE_NO_UDF_IEXE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE)
941941
#define FPCSR_mskALLE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE)
942942
#define FPCSR_mskALLT (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT)
943943

arch/nds32/include/asm/fpu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu);
3636
* enabled by default and kerenl will re-execute it by fpu emulator
3737
* when getting underflow exception.
3838
*/
39-
#define FPCSR_INIT FPCSR_mskUDFE
39+
#define FPCSR_INIT (FPCSR_mskUDFE | FPCSR_mskIEXE)
4040
#else
4141
#define FPCSR_INIT 0x0UL
4242
#endif

arch/nds32/include/asm/fpuemu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ void fsubs(void *ft, void *fa, void *fb);
1313
void fmuls(void *ft, void *fa, void *fb);
1414
void fdivs(void *ft, void *fa, void *fb);
1515
void fs2d(void *ft, void *fa);
16+
void fs2si(void *ft, void *fa);
17+
void fs2si_z(void *ft, void *fa);
18+
void fs2ui(void *ft, void *fa);
19+
void fs2ui_z(void *ft, void *fa);
20+
void fsi2s(void *ft, void *fa);
21+
void fui2s(void *ft, void *fa);
1622
void fsqrts(void *ft, void *fa);
1723
void fnegs(void *ft, void *fa);
1824
int fcmps(void *ft, void *fa, void *fb, int cop);
@@ -26,6 +32,12 @@ void fmuld(void *ft, void *fa, void *fb);
2632
void fdivd(void *ft, void *fa, void *fb);
2733
void fsqrtd(void *ft, void *fa);
2834
void fd2s(void *ft, void *fa);
35+
void fd2si(void *ft, void *fa);
36+
void fd2si_z(void *ft, void *fa);
37+
void fd2ui(void *ft, void *fa);
38+
void fd2ui_z(void *ft, void *fa);
39+
void fsi2d(void *ft, void *fa);
40+
void fui2d(void *ft, void *fa);
2941
void fnegd(void *ft, void *fa);
3042
int fcmpd(void *ft, void *fa, void *fb, int cop);
3143

arch/nds32/include/asm/syscalls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
asmlinkage long sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op);
88
asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len);
99
asmlinkage long sys_rt_sigreturn_wrapper(void);
10-
asmlinkage long sys_udftrap(int option);
10+
asmlinkage long sys_fp_udfiex_crtl(int cmd, int act);
1111

1212
#include <asm-generic/syscalls.h>
1313

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (C) 2005-2019 Andes Technology Corporation */
3+
#ifndef _FP_UDF_IEX_CRTL_H
4+
#define _FP_UDF_IEX_CRTL_H
5+
6+
/*
7+
* The cmd list of sys_fp_udfiex_crtl()
8+
*/
9+
/* Disable UDF or IEX trap based on the content of parameter act */
10+
#define DISABLE_UDF_IEX_TRAP 0
11+
/* Enable UDF or IEX trap based on the content of parameter act */
12+
#define ENABLE_UDF_IEX_TRAP 1
13+
/* Get current status of UDF and IEX trap */
14+
#define GET_UDF_IEX_TRAP 2
15+
16+
#endif /* _FP_UDF_IEX_CRTL_H */

arch/nds32/include/uapi/asm/sigcontext.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,24 @@ struct fpu_struct {
1313
unsigned long long fd_regs[32];
1414
unsigned long fpcsr;
1515
/*
16-
* UDF_trap is used to recognize whether underflow trap is enabled
17-
* or not. When UDF_trap == 1, this process will be traped and then
18-
* get a SIGFPE signal when encountering an underflow exception.
19-
* UDF_trap is only modified through setfputrap syscall. Therefore,
20-
* UDF_trap needn't be saved or loaded to context in each context
21-
* switch.
16+
* When CONFIG_SUPPORT_DENORMAL_ARITHMETIC is defined, kernel prevents
17+
* hardware from treating the denormalized output as an underflow case
18+
* and rounding it to a normal number. Hence kernel enables the UDF and
19+
* IEX trap in the fpcsr register to step in the calculation.
20+
* However, the UDF and IEX trap enable bit in $fpcsr also lose
21+
* their use.
22+
*
23+
* UDF_IEX_trap replaces the feature of UDF and IEX trap enable bit in
24+
* $fpcsr to control the trap of underflow and inexact. The bit filed
25+
* of UDF_IEX_trap is the same as $fpcsr, 10th bit is used to enable UDF
26+
* exception trapping and 11th bit is used to enable IEX exception
27+
* trapping.
28+
*
29+
* UDF_IEX_trap is only modified through fp_udfiex_crtl syscall.
30+
* Therefore, UDF_IEX_trap needn't be saved and restored in each
31+
* context switch.
2232
*/
23-
unsigned long UDF_trap;
33+
unsigned long UDF_IEX_trap;
2434
};
2535

2636
struct zol_struct {

arch/nds32/include/uapi/asm/udftrap.h

Lines changed: 0 additions & 13 deletions
This file was deleted.

arch/nds32/include/uapi/asm/unistd.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
/* Additional NDS32 specific syscalls. */
1313
#define __NR_cacheflush (__NR_arch_specific_syscall)
14-
#define __NR_udftrap (__NR_arch_specific_syscall + 1)
14+
#define __NR_fp_udfiex_crtl (__NR_arch_specific_syscall + 1)
1515
__SYSCALL(__NR_cacheflush, sys_cacheflush)
16-
__SYSCALL(__NR_udftrap, sys_udftrap)
16+
__SYSCALL(__NR_fp_udfiex_crtl, sys_fp_udfiex_crtl)

arch/nds32/kernel/fpu.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const struct fpu_struct init_fpuregs = {
1414
.fd_regs = {[0 ... 31] = sNAN64},
1515
.fpcsr = FPCSR_INIT,
1616
#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
17-
.UDF_trap = 0
17+
.UDF_IEX_trap = 0
1818
#endif
1919
};
2020

@@ -178,7 +178,7 @@ inline void do_fpu_context_switch(struct pt_regs *regs)
178178
/* First time FPU user. */
179179
load_fpu(&init_fpuregs);
180180
#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
181-
current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap;
181+
current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
182182
#endif
183183
set_used_math();
184184
}
@@ -206,7 +206,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
206206
unsigned int fpcsr;
207207
int si_code = 0, si_signo = SIGFPE;
208208
#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
209-
unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT;
209+
unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT|FPCSR_mskIEXT;
210210
#else
211211
unsigned long redo_except = FPCSR_mskDNIT;
212212
#endif
@@ -215,21 +215,18 @@ inline void handle_fpu_exception(struct pt_regs *regs)
215215
fpcsr = current->thread.fpu.fpcsr;
216216

217217
if (fpcsr & redo_except) {
218-
#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
219-
if (fpcsr & FPCSR_mskUDFT)
220-
current->thread.fpu.fpcsr &= ~FPCSR_mskIEX;
221-
#endif
222218
si_signo = do_fpuemu(regs, &current->thread.fpu);
223219
fpcsr = current->thread.fpu.fpcsr;
224-
if (!si_signo)
220+
if (!si_signo) {
221+
current->thread.fpu.fpcsr &= ~(redo_except);
225222
goto done;
223+
}
226224
} else if (fpcsr & FPCSR_mskRIT) {
227225
if (!user_mode(regs))
228226
do_exit(SIGILL);
229227
si_signo = SIGILL;
230228
}
231229

232-
233230
switch (si_signo) {
234231
case SIGFPE:
235232
fill_sigfpe_signo(fpcsr, &si_code);

arch/nds32/kernel/sys_nds32.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
#include <asm/cachectl.h>
88
#include <asm/proc-fns.h>
9-
#include <asm/udftrap.h>
109
#include <asm/fpu.h>
10+
#include <asm/fp_udfiex_crtl.h>
1111

1212
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
1313
unsigned long, prot, unsigned long, flags,
@@ -51,31 +51,33 @@ SYSCALL_DEFINE3(cacheflush, unsigned int, start, unsigned int, end, int, cache)
5151
return 0;
5252
}
5353

54-
SYSCALL_DEFINE1(udftrap, int, option)
54+
SYSCALL_DEFINE2(fp_udfiex_crtl, unsigned int, cmd, unsigned int, act)
5555
{
5656
#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
57-
int old_udftrap;
57+
int old_udf_iex;
5858

5959
if (!used_math()) {
6060
load_fpu(&init_fpuregs);
61-
current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap;
61+
current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
6262
set_used_math();
6363
}
6464

65-
old_udftrap = current->thread.fpu.UDF_trap;
66-
switch (option) {
67-
case DISABLE_UDFTRAP:
68-
current->thread.fpu.UDF_trap = 0;
65+
old_udf_iex = current->thread.fpu.UDF_IEX_trap;
66+
act &= (FPCSR_mskUDFE | FPCSR_mskIEXE);
67+
68+
switch (cmd) {
69+
case DISABLE_UDF_IEX_TRAP:
70+
current->thread.fpu.UDF_IEX_trap &= ~act;
6971
break;
70-
case ENABLE_UDFTRAP:
71-
current->thread.fpu.UDF_trap = FPCSR_mskUDFE;
72+
case ENABLE_UDF_IEX_TRAP:
73+
current->thread.fpu.UDF_IEX_trap |= act;
7274
break;
73-
case GET_UDFTRAP:
75+
case GET_UDF_IEX_TRAP:
7476
break;
7577
default:
7678
return -EINVAL;
7779
}
78-
return old_udftrap;
80+
return old_udf_iex;
7981
#else
8082
return -ENOTSUPP;
8183
#endif

0 commit comments

Comments
 (0)