Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93229612 authored by Vincent Chen's avatar Vincent Chen Committed by Greentime Hu
Browse files

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: default avatarVincent Chen <vincentc@andestech.com>
Acked-by: default avatarGreentime Hu <greentime@andestech.com>
Signed-off-by: default avatarGreentime Hu <greentime@andestech.com>
parent ed32949e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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);

+3 −1
Original line number Diff line number Diff line
@@ -4,4 +4,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
+30 −0
Original line number Diff line number Diff line
// 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;
	}

}
+30 −0
Original line number Diff line number Diff line
// 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;
	}

}
+30 −0
Original line number Diff line number Diff line
// 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;
	}

}
Loading