Linux Audio

Check our new training course

Loading...
v3.1
 
  1/*---------------------------------------------------------------------------+
  2 |  fpu_etc.c                                                                |
  3 |                                                                           |
  4 | Implement a few FPU instructions.                                         |
  5 |                                                                           |
  6 | Copyright (C) 1992,1993,1994,1997                                         |
  7 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  8 |                       Australia.  E-mail   billm@suburbia.net             |
  9 |                                                                           |
 10 |                                                                           |
 11 +---------------------------------------------------------------------------*/
 12
 13#include "fpu_system.h"
 14#include "exception.h"
 15#include "fpu_emu.h"
 16#include "status_w.h"
 17#include "reg_constant.h"
 18
 19static void fchs(FPU_REG *st0_ptr, u_char st0tag)
 20{
 21	if (st0tag ^ TAG_Empty) {
 22		signbyte(st0_ptr) ^= SIGN_NEG;
 23		clear_C1();
 24	} else
 25		FPU_stack_underflow();
 26}
 27
 28static void fabs(FPU_REG *st0_ptr, u_char st0tag)
 29{
 30	if (st0tag ^ TAG_Empty) {
 31		setpositive(st0_ptr);
 32		clear_C1();
 33	} else
 34		FPU_stack_underflow();
 35}
 36
 37static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
 38{
 39	switch (st0tag) {
 40	case TAG_Zero:
 41		setcc(SW_C3);
 42		break;
 43	case TAG_Valid:
 44		if (getsign(st0_ptr) == SIGN_POS)
 45			setcc(0);
 46		else
 47			setcc(SW_C0);
 48		break;
 49	case TAG_Special:
 50		switch (FPU_Special(st0_ptr)) {
 51		case TW_Denormal:
 52			if (getsign(st0_ptr) == SIGN_POS)
 53				setcc(0);
 54			else
 55				setcc(SW_C0);
 56			if (denormal_operand() < 0) {
 57#ifdef PECULIAR_486
 58				/* This is weird! */
 59				if (getsign(st0_ptr) == SIGN_POS)
 60					setcc(SW_C3);
 61#endif /* PECULIAR_486 */
 62				return;
 63			}
 64			break;
 65		case TW_NaN:
 66			setcc(SW_C0 | SW_C2 | SW_C3);	/* Operand is not comparable */
 67			EXCEPTION(EX_Invalid);
 68			break;
 69		case TW_Infinity:
 70			if (getsign(st0_ptr) == SIGN_POS)
 71				setcc(0);
 72			else
 73				setcc(SW_C0);
 74			break;
 75		default:
 76			setcc(SW_C0 | SW_C2 | SW_C3);	/* Operand is not comparable */
 77			EXCEPTION(EX_INTERNAL | 0x14);
 78			break;
 79		}
 80		break;
 81	case TAG_Empty:
 82		setcc(SW_C0 | SW_C2 | SW_C3);
 83		EXCEPTION(EX_StackUnder);
 84		break;
 85	}
 86}
 87
 88static void fxam(FPU_REG *st0_ptr, u_char st0tag)
 89{
 90	int c = 0;
 91	switch (st0tag) {
 92	case TAG_Empty:
 93		c = SW_C3 | SW_C0;
 94		break;
 95	case TAG_Zero:
 96		c = SW_C3;
 97		break;
 98	case TAG_Valid:
 99		c = SW_C2;
100		break;
101	case TAG_Special:
102		switch (FPU_Special(st0_ptr)) {
103		case TW_Denormal:
104			c = SW_C2 | SW_C3;	/* Denormal */
105			break;
106		case TW_NaN:
107			/* We also use NaN for unsupported types. */
108			if ((st0_ptr->sigh & 0x80000000)
109			    && (exponent(st0_ptr) == EXP_OVER))
110				c = SW_C0;
111			break;
112		case TW_Infinity:
113			c = SW_C2 | SW_C0;
114			break;
115		}
116	}
117	if (getsign(st0_ptr) == SIGN_NEG)
118		c |= SW_C1;
119	setcc(c);
120}
121
 
 
 
 
 
122static FUNC_ST0 const fp_etc_table[] = {
123	fchs, fabs, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal,
124	ftst_, fxam, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal
125};
126
127void FPU_etc(void)
128{
129	(fp_etc_table[FPU_rm]) (&st(0), FPU_gettag0());
130}
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/*---------------------------------------------------------------------------+
  3 |  fpu_etc.c                                                                |
  4 |                                                                           |
  5 | Implement a few FPU instructions.                                         |
  6 |                                                                           |
  7 | Copyright (C) 1992,1993,1994,1997                                         |
  8 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  9 |                       Australia.  E-mail   billm@suburbia.net             |
 10 |                                                                           |
 11 |                                                                           |
 12 +---------------------------------------------------------------------------*/
 13
 14#include "fpu_system.h"
 15#include "exception.h"
 16#include "fpu_emu.h"
 17#include "status_w.h"
 18#include "reg_constant.h"
 19
 20static void fchs(FPU_REG *st0_ptr, u_char st0tag)
 21{
 22	if (st0tag ^ TAG_Empty) {
 23		signbyte(st0_ptr) ^= SIGN_NEG;
 24		clear_C1();
 25	} else
 26		FPU_stack_underflow();
 27}
 28
 29static void fabs(FPU_REG *st0_ptr, u_char st0tag)
 30{
 31	if (st0tag ^ TAG_Empty) {
 32		setpositive(st0_ptr);
 33		clear_C1();
 34	} else
 35		FPU_stack_underflow();
 36}
 37
 38static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
 39{
 40	switch (st0tag) {
 41	case TAG_Zero:
 42		setcc(SW_C3);
 43		break;
 44	case TAG_Valid:
 45		if (getsign(st0_ptr) == SIGN_POS)
 46			setcc(0);
 47		else
 48			setcc(SW_C0);
 49		break;
 50	case TAG_Special:
 51		switch (FPU_Special(st0_ptr)) {
 52		case TW_Denormal:
 53			if (getsign(st0_ptr) == SIGN_POS)
 54				setcc(0);
 55			else
 56				setcc(SW_C0);
 57			if (denormal_operand() < 0) {
 58#ifdef PECULIAR_486
 59				/* This is weird! */
 60				if (getsign(st0_ptr) == SIGN_POS)
 61					setcc(SW_C3);
 62#endif /* PECULIAR_486 */
 63				return;
 64			}
 65			break;
 66		case TW_NaN:
 67			setcc(SW_C0 | SW_C2 | SW_C3);	/* Operand is not comparable */
 68			EXCEPTION(EX_Invalid);
 69			break;
 70		case TW_Infinity:
 71			if (getsign(st0_ptr) == SIGN_POS)
 72				setcc(0);
 73			else
 74				setcc(SW_C0);
 75			break;
 76		default:
 77			setcc(SW_C0 | SW_C2 | SW_C3);	/* Operand is not comparable */
 78			EXCEPTION(EX_INTERNAL | 0x14);
 79			break;
 80		}
 81		break;
 82	case TAG_Empty:
 83		setcc(SW_C0 | SW_C2 | SW_C3);
 84		EXCEPTION(EX_StackUnder);
 85		break;
 86	}
 87}
 88
 89static void fxam(FPU_REG *st0_ptr, u_char st0tag)
 90{
 91	int c = 0;
 92	switch (st0tag) {
 93	case TAG_Empty:
 94		c = SW_C3 | SW_C0;
 95		break;
 96	case TAG_Zero:
 97		c = SW_C3;
 98		break;
 99	case TAG_Valid:
100		c = SW_C2;
101		break;
102	case TAG_Special:
103		switch (FPU_Special(st0_ptr)) {
104		case TW_Denormal:
105			c = SW_C2 | SW_C3;	/* Denormal */
106			break;
107		case TW_NaN:
108			/* We also use NaN for unsupported types. */
109			if ((st0_ptr->sigh & 0x80000000)
110			    && (exponent(st0_ptr) == EXP_OVER))
111				c = SW_C0;
112			break;
113		case TW_Infinity:
114			c = SW_C2 | SW_C0;
115			break;
116		}
117	}
118	if (getsign(st0_ptr) == SIGN_NEG)
119		c |= SW_C1;
120	setcc(c);
121}
122
123static void FPU_ST0_illegal(FPU_REG *st0_ptr, u_char st0_tag)
124{
125	FPU_illegal();
126}
127
128static FUNC_ST0 const fp_etc_table[] = {
129	fchs, fabs, FPU_ST0_illegal, FPU_ST0_illegal,
130	ftst_, fxam, FPU_ST0_illegal, FPU_ST0_illegal,
131};
132
133void FPU_etc(void)
134{
135	(fp_etc_table[FPU_rm]) (&st(0), FPU_gettag0());
136}