File:  [MW Coherent from dump] / coherent / b / bin / c / n1 / i386 / amd.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:37 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * n1/i386/amd.c
 * Access mode determination.
 * This routine sets the addressing flags for a tree node.
 * There is no provision for double indexed address modes;
 * the compiler does not attempt to use them at this time.
 * i386.
 */

#ifdef	vax
#include "INC$LIB:cc1.h"
#else
#include "cc1.h"
#endif

TREE	*findoffs();

/*
 * Determine access mode and store it into the 't_flag' field.
 * The subtrees have already been marked.
 * This routine is usually called by 'walk'.
 */
amd(tp, ptp) register TREE *tp; TREE *ptp;
{
	register FLAG	flag;
	register int	op;
	register TREE	*xp;
	register FLAG	mask;
	register lval_t	n;
	register int	i;

	if ((op=tp->t_op) == LEAF) {
		/* Leaf nodes inherit flags of subtree. */
		tp->t_flag = tp->t_lp->t_flag;
		return;
	}
	flag = 0;
	if (op==ICON || op==LCON) {		/* integer constants */
		flag |= T_NUM;
		if ((n = grabnval(tp)) >= 0) {
			if (n == 0)
				flag |= T_0|T_SHCNT|T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
			else if (n == 1)
				flag |= T_1|T_SHCNT|T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
			else if (n <= 31)
				flag |= T_SHCNT|T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
			else if (n <= 127)
				flag |= T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
			else if (n <= 255)
				flag |= T_UBYTE|T_SWORD|T_UWORD;
			else if (n <= 32767L)
				flag |= T_SWORD|T_UWORD;
			else if (n <= 65535L)
				flag |= T_UWORD;
		} else {
			if (n >= -128)
				flag |= T_SBYTE|T_SWORD;
			else if (n >= -32768L)
				flag |= T_SWORD;
		}
	} else if (op == DCON) {		/* double constants */
		flag |= T_DCN;
		for (i = 0; i < sizeof(dval_t) && tp->t_dval[i]==0; i++)
			;
		if (i == sizeof(dval_t))
			flag |= T_0;
	} else if (op == REG)			/* registers */
		flag |= T_REG;
	else if (op == ADDR)			/* address of ... */
		flag |= T_ADDR;
	else if (op==LID || op==GID)		/* identifiers */
		flag |= T_DIR;
	else if ((op == ADD || op == SUB) && ispoint(tp->t_type)) {
		/* Check for effective address, e.g. %ebp+12 or &i+1. */
		mask = (op == ADD) ? T_CON : T_NUM;
		xp = tp;
		do {
			if ((xp->t_rp->t_flag & mask) == 0)
				break;
			xp = xp->t_lp;
		} while (xp->t_op==ADD || xp->t_op==SUB);
		if (isreg(xp))
			flag |= T_LEA;
	} else if (op == STAR) {
		xp = findoffs(tp);
		if ((xp->t_flag & T_CON) != 0 || isreg(xp))
			flag |= T_DIR;
		flag |= T_OFS;
	}
	tp->t_flag = flag;
}

/*
 * Given a pointer to an offset type tree, return a pointer to the tree
 * that must be loaded into a register to get an addressable tree.
 */
TREE *
findoffs(tp) register TREE *tp;
{
	register flag, n;

	while (tp->t_op == LEAF)
		tp = tp->t_lp;
	for (n = 0;;) {
		tp = tp->t_lp;
		switch (tp->t_op) {
		case SUB:		/* can't load neg addr */
			if (tp->t_rp->t_flag & T_NUM)
				break;
			return tp;
		case ADD:		/* add one addr max */
			if ((flag = (tp->t_rp->t_flag)) & T_NUM)
				break;
			else if ((flag & T_CON) && n++ == 0)
				break;
			/* else fall through... */
		default:
			return tp;
		}
	}
}

/*
 * Return true if xp represents a dword register other than ESP.
 */
isreg(xp) register TREE *xp;
{
	register REGNAME r;

	if ((xp->t_flag&T_REG) == 0)
		return 0;
	while (xp->t_op == LEAF)
		xp = xp->t_lp;
	r = xp->t_reg;
	return (r==EAX || r==EBX || r==ECX || r==EDX
	     || r==ESI || r==EDI || r==EBP);
}

/* end of n1/i386/amd.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.