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);
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);
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
--- /dev/null
+// 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;
+ }
+
+}
--- /dev/null
+// 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;
+ }
+
+}
--- /dev/null
+// 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;
+ }
+
+}
--- /dev/null
+// 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;
+ }
+
+}
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;
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;
* 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;
if (NDS32Insn_OPCODE(insn) != cop0_op)
return SIGILL;
+
switch (NDS32Insn_OPCODE_COP0(insn)) {
case fs1_op:
case fs2_op:
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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;
+ }
+
+}
--- /dev/null
+// 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;
+
+}
--- /dev/null
+// 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;
+
+}
--- /dev/null
+// 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;
+
+}
--- /dev/null
+// 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;
+
+}