summaryrefslogtreecommitdiff
path: root/arch/nds32/math-emu/fpuemu.c
diff options
context:
space:
mode:
authorVincent Chen <vincentc@andestech.com>2019-05-20 09:21:13 +0800
committerGreentime Hu <greentime@andestech.com>2019-05-31 15:23:26 +0800
commit932296120543149e3397af252e7daee7af37eb05 (patch)
treead3c0a00a16cae8cab3d85c3b74060893003ee83 /arch/nds32/math-emu/fpuemu.c
parented32949e0acb73e7bc054bb02e0453d4d561ceda (diff)
nds32: add new emulations for floating point instruction
The existing floating point emulations is only available for floating instruction that possibly issue denormalized input and underflow exceptions. These existing FPU emulations are not sufficient when IEx Trap is enabled because some floating point instructions only issue inexact exception. This patch adds the emulations of such floating point instructions. Signed-off-by: Vincent Chen <vincentc@andestech.com> Acked-by: Greentime Hu <greentime@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com>
Diffstat (limited to 'arch/nds32/math-emu/fpuemu.c')
-rw-r--r--arch/nds32/math-emu/fpuemu.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/arch/nds32/math-emu/fpuemu.c b/arch/nds32/math-emu/fpuemu.c
index 75cf1643fa78..46558a15c0dc 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: