/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:general.h 12.0$ */
/* $ACIS:general.h 12.0$ */
/* $Source: /ibm/acis/usr/src/usr.lib/libfp/genfp/RCS/general.h,v $ */

#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsidgeneral = "$Header:general.h 12.0$";
#endif

/*
 * Definitions here are considered NOT f.p. hardware specific, but
 * for use by all different f.p. hardware routines.  Examples are
 * definitions of RT assembler instructions, general purpose
 * macros, etc.
 */

/*
 * These "RT_" def's will gradually be replaced by "RTi_" macros.
 */
#define RT_AIS			0x9000
#define RT_BRBIT		0x8000		/* class of "br on bit" */
#define RT_BRREG		0xe800		/* class of "br on reg" */
#define RT_BR			0xe880
#define RT_BRX			0xe980
#define RT_BRXr15		0xe98f
#define RT_BALR			0xec00
#define RT_CAL			0xc800
#define RT_CAL16		0xc200
#define RT_CAS			0x6000
#define RT_CAU			0xd800
#define RT_CLI			0xd300
#define RT_CLRBL		0x9900
#define RT_JUMP			0x0000		/* class of "jump" instrs */
#define RT_JNE			0x0200
#define RT_L			0xcd00
#define RT_LHS			0xeb00
#define RT_LIS			0xa400
#define RT_LS			0x7000
#define RT_MFS			0x9600
#define RT_MFTBIL		0x9d00
#define RT_MTS			0xb500
#define RT_MTTBIL		0x9f00
#define RT_MTTBIU		0x9e00
#define RT_N			0xe500
#define RT_NILO			0xc600
#define RT_NILZ			0xc500
#define RT_NIUZ			0xd500
#define RT_O			0xe300
#define RT_OIU			0xc300
#define RT_ONEC			0xf400
#define RT_SL			0xba00
#define RT_SLI			0xaa00
#define RT_SLI16		0xab00
#define RT_SIS			0x9200
#define RT_SFI			0xd200
#define RT_SR			0xb800
#define RT_SRI			0xa800
#define RT_SRI16		0xa900
#define RT_ST			0xdd00
#define RT_STS			0x3000
#define RT_SYNC			0x95f8
#define RT_TWOC			0xe400
#define RT_X			0xe700
#define RT_XIL			0xc700
#define IMASK			0xf000		/* mask, hi nibble of instr */
#define OPMASK			0xff00		/* mask, hi byte of instr */
#define SP			1
#define r0			0
#define r1			1
#define r2			2
#define r3			3
#define r4			4
#define r5			5
#define r6			6
#define r7			7
#define r8			8
#define r9			9
#define r10			10
#define r11			11
#define r12			12
#define r13			13
#define r14			14
#define r15			15
#define NULL			0
#define MQ			10
#define SCR15			15
#define SCR_CS			SCR15
#define TRUE			1
#define FALSE			0
#define USABLE_REGS		0x3ffc	/* general scratch register mask */
					/* will not use r0,r1,r14,r15 */
#define FIRST_SAVEF		2	/* first fl. pt. register saveable */
#define LAST_SAVEF		7	/* last fl. pt. register saveable */
#define typenum			HI
#define regnum			LO
#define C_setbit(mask,bitnum)	(mask) |= (0x80 >> (bitnum))
#define C_clrbit(mask,bitnum)	(mask) &= (~(0x80 >> (bitnum)))
#define S_setbit(mask,bitnum)	(mask) |= (0x1 << (15 - (bitnum)))
#define S_clrbit(mask,bitnum)	(mask) &= (~(0x1 << (15 - (bitnum))))
#define L_setbit(mask,bitnum)	(mask) |= (0x80000000 >> (bitnum))
#define L_clrbit(mask,bitnum)	(mask) &= (~(0x80000000 >> (bitnum)))
#define tstbit(val,bitpattern)	(((val) & (bitpattern)) == (bitpattern))
#define S_sign_of(x)		((x) >> 15)
#define RT_short(op,rx,ry)	((op) | ((rx) << 4) | (ry))
#define hi_nibble_of(b)		((b) & 0xf0)
#define lo_nibble_of(b)		((b) & 0x0f)
#define hi_nibble_val(b)	(hi_nibble_of(b) >> 4)
#define lo_nibble_val(b)	lo_nibble_of(b)
#define hi_optype_of(gi,optnum)	(gi->data->opr.opt[(optnum)].ch.typenum & 0xf0)
#define lo_optype_of(gi,optnum)	(gi->data->opr.opt[(optnum)].ch.typenum & 0x0f)
#define byteval_of(gi,optnum)	(gi->data->opr.opt[(optnum)].ch.regnum)
#define fp_free_genr(gi,grnum)	S_setbit(gi->avail_genr,grnum)
#define fp_free_fltr(gi,frnum)	C_setbit(gi->avail_fltr,frnum)
#define freg_num(n)		(0x80 >> (n))
#define greg_num(n)		(0x1 << (15 - (n)))

#define is_scratchf(gi,freg)	(gi->data->scratchf & (0x80 >> (freg)))
#define is_scratchg(gi,greg)	(gi->data->scratchg & (0x1 << (15 - (greg))))
#define is_commutative(opcode)	(((opcode) == FP_ADD) || ((opcode) == FP_MUL))
#define is_compare(opcode)	(((opcode) == FP_CMP) || ((opcode) == FP_CMPT))
#define is_slow_ops(opcode)	(_opinfo[(opcode)].speed == SLOW)
#define is_uint(prec)		((prec) == UINTTYPE)
#define is_int(prec)		(((prec) == INTTYPE) || is_uint(prec))

#define getopnd(gi,opnum,x)	(gi->data->opr.operand[gi->wordopnd[opnum]+x]).UL
/*
 * These two macros test for 16 bit signed quantities
 *
 * small_pos_num(x) test for	0	<= x <=	0x07fff=32767
 * small_neg_num(x) test for	-32768	<= x <=	-1
 */
#define small_pos_num(x)	(( (unsigned) (x) >> 15) == 0)
#define small_neg_num(x)	(( (unsigned) (x) >> 15) == 0x0001ffff)

#define MAXCODELEN		100

#ifdef DEBUG
#define debugf(cond,stmt)	if (cond) stmt
#else
#define debugf(cond,stmt)
#endif DEBUG

#define MAGIC_NUMBER		0xdfdedfdf

/*
 * These are RT opcodes from appendix A of the RT PC
 * Hardware Technical Reference Manual (volume 1).
 */
#define RTOP_AIS		0x90		/* R  */
#define RTOP_BALR		0xec		/* R  */
#define RTOP_BALRX		0xed		/* R  */
#define RTOP_CAL		0xc8		/* D  */
#define RTOP_CAL16		0xc2		/* D  */
#define RTOP_CAS		0x6		/* X  */
#define RTOP_CAU		0xd8		/* D  */
#define RTOP_CLI		0xd3		/* D  */
#define RTOP_CLRBL		0x99		/* R  */
#define RTOP_CLRSB		0x95		/* R  */
#define RTOP_INC		0x91		/* R  */
#define RTOP_JB			0x08		/* JI 08-0f */
#define RTOP_JNB		0x00		/* JI 00-07 */
#define RTOP_L			0xcd		/* D  */
#define RTOP_LCS		0x4		/* DS */
#define RTOP_LHAS		0x5		/* DS */
#define RTOP_LHS		0xeb		/* R  */
#define RTOP_LIS		0xa4		/* R  */
#define RTOP_LM			0xc9		/* D  */
#define RTOP_LS			0x7		/* DS */
#define RTOP_MFS		0x96		/* R  */
#define RTOP_MFTBIL		0x9d		/* R  */
#define RTOP_MTS		0xb5		/* R  */
#define RTOP_MTTBIL		0x9f		/* R  */
#define RTOP_MTTBIU		0x9e		/* R  */
#define RTOP_N			0xe5		/* R  */
#define RTOP_NILO		0xc6		/* D  */
#define RTOP_NILZ		0xc5		/* D  */
#define RTOP_NIUO		0xd6		/* D  */
#define RTOP_NIUZ		0xd5		/* D  */
#define RTOP_O			0xe3		/* R  */
#define RTOP_OIL		0xc4		/* D  */
#define RTOP_OIU		0xc3		/* D  */
#define RTOP_ONEC		0xf4		/* R  */
#define RTOP_SETSB		0x97		/* R  */
#define RTOP_SL			0xba		/* R  */
#define RTOP_SLI		0xaa		/* R  */
#define RTOP_SLI16		0xab		/* R  */
#define RTOP_SIS		0x92		/* R  */
#define RTOP_SR			0xb8		/* R  */
#define RTOP_SRI		0xa8		/* R  */
#define RTOP_SRI16		0xa9		/* R  */
#define RTOP_ST			0xdd		/* D  */
#define RTOP_STCS		0x1		/* DS */
#define RTOP_STHS		0x2		/* DS */
#define RTOP_STM		0xd9		/* D  */
#define RTOP_STS		0x3		/* DS */
#define RTOP_TWOC		0xe4		/* R  */
#define RTOP_X			0xe7		/* R  */
#define RTOP_XIL		0xc7		/* D  */
#define RTOP_XIU		0xd7		/* D  */

/*
 * Condition Status bits for the RT (SCR15)
 * RT Technical Reference Manual (Volume 1).
 */
#define COND_TB			31		/* Test bit */
#define COND_OV			30		/* Overflow */
#define COND_RSVD		29		/* Reserved */
#define COND_C0			28		/* Carry zero */
#define COND_GT			27		/* Greater than */
#define COND_EQ			26		/* Equal */
#define COND_LT			25		/* Less than */
#define COND_PZ			24		/* Permanent zero */

/* RT instructions are either 2 or 4 bytes in length.
 * The opcodes could be 4, 5 or 8 bit long.
 * The instruction set is divided into 7 formats:
 *
 *	Format	Opcode (bits)	Length (bytes)	Note
 *	JI	5		2		3 bit flag, 8 bit displacement 
 *	X	4		2		3 regs
 *	D-Short	4		2		2 regs, 4 bit immediate data
 *	R	8		2		2 regs
 *	BI	8		4		1 reg, 20 bit displacement
 *	BA	8		4		24 bit displacement
 *	D	8		4		2 regs, 16 bit immediate data
 *
 * The folowing macros only cover the first 2 bytes of the instruction.
 */
#define OP4FMT(op,a,b,c)	(((op) << 12) | ((a) << 8) | ((b) << 4) | (c))
#define OP5FMT(op,a,b)		(((op) << 8)  | ((a) << 8) | (b))
#define OP8FMT(op,a,b)		(((op) << 8)  | ((a) << 4) | (b))
#define JIFMT(op,cond,i)	OP5FMT(op,(cond)-24,((i) & 0xff))
#define XFMT(op,ra,rb,rc)	OP4FMT(op,ra,rb,rc)
#define DSFMT(op,i,rb,rc)	OP4FMT(op,i,rb,rc)
#define RFMT(op,rb,rc)		OP8FMT(op,rb,rc)
#define BIFMT(op,rb,addr)	OP8FMT(op,rb,((addr) >> 16) & 0x0f)
#define BAFMT(op,addr)		(((op) << 8) | (((addr) >> 16) & 0xff))
#define DFMT(op,rb,rc)		OP8FMT(op,rb,rc)
#define JUMPFMT(op,i)		(((op) << 8) | (i))

/*
 * The instructions are NOT complete.  They are listed in
 * alphabetical order.
 */
#define RTi_AIS(rb,i)		RFMT(RTOP_AIS,rb,i)
#define RTi_BALR(rb,rc)		RFMT(RTOP_BALR,rb,rc)
#define RTi_BALRX(rb,rc)	RFMT(RTOP_BALRX,rb,rc)
#define RTi_CAL(rb,rc)		DFMT(RTOP_CAL,rb,rc)
#define RTi_CAL16(rb,rc)	DFMT(RTOP_CAL16,rb,rc)
#define RTi_CAS(ra,rb,rc)	XFMT(RTOP_CAS,ra,rb,rc)
#define RTi_CAU(rb,rc)		DFMT(RTOP_CAU,rb,rc)
#define RTi_CLI(rc)		DFMT(RTOP_CLI,0,rc)
#define RTi_CLRBL(rb,i)		RFMT(RTOP_CLRBL,rb,i)
#define RTi_CLRSB(srb,i)	RFMT(RTOP_CLRSB,srb,i)
#define RTi_INC(rb,i)		RFMT(RTOP_INC,rb,i)
#define RTi_JB(cond,i)		JIFMT(RTOP_JB,cond,i)
#define RTi_JNB(cond,i)		JIFMT(RTOP_JNB,cond,i)
#define RTi_J(i)		RTi_JNB(COND_PZ,i)
#define RTi_JC0(i)		RTi_JB(COND_C0,i)
#define RTi_JEQ(i)		RTi_JB(COND_EQ,i)
#define RTi_JH(i)		RTi_JB(COND_GT,i)
#define RTi_JHE(i)		RTi_JNB(COND_LT,i)
#define RTi_JL(i)		RTi_JB(COND_LT,i)
#define RTi_JLE(i)		RTi_JNB(COND_GT,i)
#define RTi_JNC0(i)		RTi_JNB(COND_C0,i)
#define RTi_JNE(i)		RTi_JNB(COND_EQ,i)
#define RTi_JNO(i)		RTi_JNB(COND_OV,i)
#define RTi_JNOP(i)		RTi_JB(COND_PZ,i)
#define RTi_JNTB(i)		RTi_JNB(COND_TB,i)
#define RTi_JO(i)		RTi_JB(COND_OV,i)
#define RTi_JTB(i)		RTi_JB(COND_TB,i)
#define RTi_L(rb,rc)		DFMT(RTOP_L,rb,rc)
#define RTi_LCS(rb,i,rc)	DSFMT(RTOP_LCS,i,rb,rc)
#define RTi_LHAS(rb,i,rc)	DSFMT(RTOP_LHAS,i,rb,rc)
#define RTi_LHS(rb,rc)		RFMT(RTOP_LHS,rb,rc)
#define RTi_LIS(rb,i)		RFMT(RTOP_LIS,rb,i)
#define RTi_LM(rb,rc)		DFMT(RTOP_LM,rb,rc)
#define RTi_LS(rb,i,rc)		DSFMT(RTOP_LS,i,rb,rc)
#define RTi_MFS(srb,rc)		RFMT(RTOP_MFS,srb,rc)
#define RTi_MFTBIL(rb,i)	RFMT(RTOP_MFTBIL,rb,i)
#define RTi_MTS(srb,rc)		RFMT(RTOP_MTS,srb,rc)
#define RTi_MTTBIL(rb,i)	RFMT(RTOP_MTTBIL,rb,i)
#define RTi_MTTBIU(rb,i)	RFMT(RTOP_MTTBIU,rb,i)
#define RTi_N(rb,rc)		RFMT(RTOP_N,rb,rc)
#define RTi_NILZ(rb,rc)		DFMT(RTOP_NILZ,rb,rc)
#define RTi_NILO(rb,rc)		DFMT(RTOP_NILO,rb,rc)
#define RTi_NIUZ(rb,rc)		DFMT(RTOP_NIUZ,rb,rc)
#define RTi_NIUO(rb,rc)		DFMT(RTOP_NIUO,rb,rc)
#define RTi_O(rb,rc)		RFMT(RTOP_O,rb,rc)
#define RTi_OIL(rb,rc)		DFMT(RTOP_OIL,rb,rc)
#define RTi_OIU(rb,rc)		DFMT(RTOP_OIU,rb,rc)
#define RTi_ONEC(rb,rc)		RFMT(RTOP_ONEC,rb,rc)
#define RTi_SETSB(srb,i)	RFMT(RTOP_SETSB,srb,i)
#define RTi_SL(rb,rc)		RFMT(RTOP_SL,rb,rc)
#define RTi_SLI(rb,i)		RFMT(RTOP_SLI,rb,i)
#define RTi_SLI16(rb,i)		RFMT(RTOP_SLI16,rb,i)
#define RTi_SIS(rb,i)		RFMT(RTOP_SIS,rb,i)
#define RTi_SR(rb,rc)		RFMT(RTOP_SR,rb,rc)
#define RTi_SRI(rb,i)		RFMT(RTOP_SRI,rb,i)
#define RTi_SRI16(rb,i)		RFMT(RTOP_SRI16,rb,i)
#define RTi_ST(rb,rc)		DFMT(RTOP_ST,rb,rc)
#define RTi_STCS(rb,i,rc)	DSFMT(RTOP_STCS,i,rb,rc)
#define RTi_STHS(rb,i,rc)	DSFMT(RTOP_STHS,i,rb,rc)
#define RTi_STM(rb,rc)		DFMT(RTOP_STM,rb,rc)
#define RTi_STS(rb,i,rc)	DSFMT(RTOP_STS,i,rb,rc)
#define RTi_TWOC(rb,rc)		RFMT(RTOP_TWOC,rb,rc)
#define RTi_X(rb,rc)		RFMT(RTOP_X,rb,rc)
#define RTi_XIL(rb,rc)		DFMT(RTOP_XIL,rb,rc)
#define RTi_XIU(rb,rc)		DFMT(RTOP_XIU,rb,rc)

/* RTi_SYNC gets RT in sync by clearing the Permanent Zero bit */
#ifdef DEBUG
#define RTi_SYNC		(printf("	setsb	scr15,8\n"), \
				RTi_CLRSB(SCR_CS,8))
#else
#define RTi_SYNC		RTi_CLRSB(SCR_CS,8)
#endif DEBUG

#define	swap(x,y,t)		{t = x; x = y; y = t;}
#define FPABORT(gi,msg)		gi->fp_state->fpabort(msg)
