xref: /openbmc/linux/arch/arm/nwfpe/single_cpdo.c (revision 74ba9207)
174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds     NetWinder Floating Point Emulator
41da177e4SLinus Torvalds     (c) Rebel.COM, 1998,1999
51da177e4SLinus Torvalds     (c) Philip Blundell, 2001
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds */
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include "fpa11.h"
121da177e4SLinus Torvalds #include "softfloat.h"
131da177e4SLinus Torvalds #include "fpopcode.h"
141da177e4SLinus Torvalds 
151da177e4SLinus Torvalds float32 float32_exp(float32 Fm);
161da177e4SLinus Torvalds float32 float32_ln(float32 Fm);
171da177e4SLinus Torvalds float32 float32_sin(float32 rFm);
181da177e4SLinus Torvalds float32 float32_cos(float32 rFm);
191da177e4SLinus Torvalds float32 float32_arcsin(float32 rFm);
201da177e4SLinus Torvalds float32 float32_arctan(float32 rFm);
211da177e4SLinus Torvalds float32 float32_log(float32 rFm);
221da177e4SLinus Torvalds float32 float32_tan(float32 rFm);
231da177e4SLinus Torvalds float32 float32_arccos(float32 rFm);
241da177e4SLinus Torvalds float32 float32_pow(float32 rFn, float32 rFm);
251da177e4SLinus Torvalds float32 float32_pol(float32 rFn, float32 rFm);
261da177e4SLinus Torvalds 
float32_rsf(struct roundingData * roundData,float32 rFn,float32 rFm)27f148af25SRichard Purdie static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm)
281da177e4SLinus Torvalds {
29f148af25SRichard Purdie 	return float32_sub(roundData, rFm, rFn);
301da177e4SLinus Torvalds }
311da177e4SLinus Torvalds 
float32_rdv(struct roundingData * roundData,float32 rFn,float32 rFm)32f148af25SRichard Purdie static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
331da177e4SLinus Torvalds {
34f148af25SRichard Purdie 	return float32_div(roundData, rFm, rFn);
351da177e4SLinus Torvalds }
361da177e4SLinus Torvalds 
37f148af25SRichard Purdie static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = {
381da177e4SLinus Torvalds 	[ADF_CODE >> 20] = float32_add,
391da177e4SLinus Torvalds 	[MUF_CODE >> 20] = float32_mul,
401da177e4SLinus Torvalds 	[SUF_CODE >> 20] = float32_sub,
411da177e4SLinus Torvalds 	[RSF_CODE >> 20] = float32_rsf,
421da177e4SLinus Torvalds 	[DVF_CODE >> 20] = float32_div,
431da177e4SLinus Torvalds 	[RDF_CODE >> 20] = float32_rdv,
441da177e4SLinus Torvalds 	[RMF_CODE >> 20] = float32_rem,
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds 	[FML_CODE >> 20] = float32_mul,
471da177e4SLinus Torvalds 	[FDV_CODE >> 20] = float32_div,
481da177e4SLinus Torvalds 	[FRD_CODE >> 20] = float32_rdv,
491da177e4SLinus Torvalds };
501da177e4SLinus Torvalds 
float32_mvf(struct roundingData * roundData,float32 rFm)51f148af25SRichard Purdie static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
521da177e4SLinus Torvalds {
531da177e4SLinus Torvalds 	return rFm;
541da177e4SLinus Torvalds }
551da177e4SLinus Torvalds 
float32_mnf(struct roundingData * roundData,float32 rFm)56f148af25SRichard Purdie static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
571da177e4SLinus Torvalds {
581da177e4SLinus Torvalds 	return rFm ^ 0x80000000;
591da177e4SLinus Torvalds }
601da177e4SLinus Torvalds 
float32_abs(struct roundingData * roundData,float32 rFm)61f148af25SRichard Purdie static float32 float32_abs(struct roundingData *roundData, float32 rFm)
621da177e4SLinus Torvalds {
631da177e4SLinus Torvalds 	return rFm & 0x7fffffff;
641da177e4SLinus Torvalds }
651da177e4SLinus Torvalds 
66f148af25SRichard Purdie static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = {
671da177e4SLinus Torvalds 	[MVF_CODE >> 20] = float32_mvf,
681da177e4SLinus Torvalds 	[MNF_CODE >> 20] = float32_mnf,
691da177e4SLinus Torvalds 	[ABS_CODE >> 20] = float32_abs,
701da177e4SLinus Torvalds 	[RND_CODE >> 20] = float32_round_to_int,
711da177e4SLinus Torvalds 	[URD_CODE >> 20] = float32_round_to_int,
721da177e4SLinus Torvalds 	[SQT_CODE >> 20] = float32_sqrt,
731da177e4SLinus Torvalds 	[NRM_CODE >> 20] = float32_mvf,
741da177e4SLinus Torvalds };
751da177e4SLinus Torvalds 
SingleCPDO(struct roundingData * roundData,const unsigned int opcode,FPREG * rFd)76f148af25SRichard Purdie unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
771da177e4SLinus Torvalds {
781da177e4SLinus Torvalds 	FPA11 *fpa11 = GET_FPA11();
791da177e4SLinus Torvalds 	float32 rFm;
801da177e4SLinus Torvalds 	unsigned int Fm, opc_mask_shift;
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds 	Fm = getFm(opcode);
831da177e4SLinus Torvalds 	if (CONSTANT_FM(opcode)) {
841da177e4SLinus Torvalds 		rFm = getSingleConstant(Fm);
851da177e4SLinus Torvalds 	} else if (fpa11->fType[Fm] == typeSingle) {
861da177e4SLinus Torvalds 		rFm = fpa11->fpreg[Fm].fSingle;
871da177e4SLinus Torvalds 	} else {
881da177e4SLinus Torvalds 		return 0;
891da177e4SLinus Torvalds 	}
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds 	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
921da177e4SLinus Torvalds 	if (!MONADIC_INSTRUCTION(opcode)) {
931da177e4SLinus Torvalds 		unsigned int Fn = getFn(opcode);
941da177e4SLinus Torvalds 		float32 rFn;
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds 		if (fpa11->fType[Fn] == typeSingle &&
971da177e4SLinus Torvalds 		    dyadic_single[opc_mask_shift]) {
981da177e4SLinus Torvalds 			rFn = fpa11->fpreg[Fn].fSingle;
99f148af25SRichard Purdie 			rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm);
1001da177e4SLinus Torvalds 		} else {
1011da177e4SLinus Torvalds 			return 0;
1021da177e4SLinus Torvalds 		}
1031da177e4SLinus Torvalds 	} else {
1041da177e4SLinus Torvalds 		if (monadic_single[opc_mask_shift]) {
105f148af25SRichard Purdie 			rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm);
1061da177e4SLinus Torvalds 		} else {
1071da177e4SLinus Torvalds 			return 0;
1081da177e4SLinus Torvalds 		}
1091da177e4SLinus Torvalds 	}
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds 	return 1;
1121da177e4SLinus Torvalds }
113