fnmsub.c 1.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
#include <linux/types.h>
#include <linux/errno.h>
#include <asm/uaccess.h>

5 6 7
#include <asm/sfp-machine.h>
#include <math-emu/soft-fp.h>
#include <math-emu/double.h>
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15 16

int
fnmsub(void *frD, void *frA, void *frB, void *frC)
{
	FP_DECL_D(R);
	FP_DECL_D(A);
	FP_DECL_D(B);
	FP_DECL_D(C);
	FP_DECL_D(T);
17
	FP_DECL_EX;
L
Linus Torvalds 已提交
18 19 20
	int ret = 0;

#ifdef DEBUG
21
	printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
L
Linus Torvalds 已提交
22 23
#endif

24 25 26
	FP_UNPACK_DP(A, frA);
	FP_UNPACK_DP(B, frB);
	FP_UNPACK_DP(C, frC);
L
Linus Torvalds 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

#ifdef DEBUG
	printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
	printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
	printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
#endif

	if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
	    (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
		ret |= EFLAG_VXIMZ;

	FP_MUL_D(T, A, C);

	if (B_c != FP_CLS_NAN)
		B_s ^= 1;

	if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
		ret |= EFLAG_VXISI;

	FP_ADD_D(R, T, B);

	if (R_c != FP_CLS_NAN)
		R_s ^= 1;

#ifdef DEBUG
	printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif

55 56 57
	__FP_PACK_D(frD, R);

	return FP_CUR_EXCEPTIONS;
L
Linus Torvalds 已提交
58
}