Example #1
0
/*
 * Push a structure on stack as argument.
 * the scratch registers are already free here
 */
static void
starg(NODE *p)
{
#if defined(MACHOABI)
	printf("	subl $%d,%%esp\n", p->n_stsize);
	printf("	subl $4,%%esp\n");
	printf("	pushl $%d\n", p->n_stsize);
	expand(p, 0, "	pushl AL\n");
	expand(p, 0, "	leal 12(%esp),A1\n");
	expand(p, 0, "	pushl A1\n");
	if (kflag) {
		printf("	call L%s$stub\n", EXPREFIX "memcpy");
		addstub(&stublist, EXPREFIX "memcpy");
	} else {
		printf("	call %s\n", EXPREFIX "memcpy");
	}
	printf("	addl $16,%%esp\n");
#else
	NODE *q = p->n_left;

	printf("	subl $%d,%%esp\n", (p->n_stsize + 3) & ~3);
	p->n_left = mklnode(OREG, 0, ESP, INT);
	zzzcode(p, 'Q');
	tfree(p->n_left);
	p->n_left = q;
#endif
}
Example #2
0
/*
 * Push a structure on stack as argument.
 * the scratch registers are already free here
 */
static void
starg(NODE *p)
{
	NODE *q = p->n_left;

	printf("	subl $%d,%%esp\n", (p->n_stsize + 3) & ~3);
	p->n_left = mklnode(OREG, 0, ESP, INT);
	zzzcode(p, 'Q');
	tfree(p->n_left);
	p->n_left = q;
}
Example #3
0
/*
 * Push a structure on stack as argument.
 * the scratch registers are already free here
 */
static void
starg(NODE *p)
{
	struct attr *ap;
	NODE *q = p->n_left;

	ap = attr_find(p->n_ap, ATTR_P2STRUCT);
	printf("	subl $%d,%%esp\n", (ap->iarg(0) + 3) & ~3);
	p->n_left = mklnode(OREG, 0, ESP, INT);
	zzzcode(p, 'Q');
	tfree(p->n_left);
	p->n_left = q;
}
Example #4
0
/*
 * Push a structure on stack as argument.
 * the scratch registers are already free here
 */
static void
starg(NODE *p)
{
	NODE *q = p->n_left;
	int s = (attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0) + 1) & ~1;

	if (s == 2)
		printf("	dec sp\n	dec sp\n");
	else
		printf("	sub sp,#%d\n", s);
	p->n_left = mklnode(OREG, 0, SP, INT);
	zzzcode(p, 'Q');
	tfree(p->n_left);
	p->n_left = q;
}
Example #5
0
void
zzzcode(NODE *p, int c)
{
	NODE *l, *r;
	TWORD t;
	int m;
	char *ch;

	switch (c) {
	case 'N':  /* logical ops, turned into 0-1 */
		/* use register given by register 1 */
		cbgen( 0, m=getlab2());
		deflab( p->n_label );
		printf( "	clrl	%s\n", rnames[getlr( p, '1' )->n_rval] );
		deflab( m );
		return;

	case 'A': /* Assign a constant directly to a memory position */
		printf("\t");
		if (p->n_type < LONG || ISPTR(p->n_type))
			casg(p);
		else
			casg64(p);
		printf("\n");
		break;

	case 'B': /* long long compare */
		twollcomp(p);
		break;

	case 'C':	/* num words pushed on arg stack */
		printf("$%d", p->n_qual);
		break;

	case 'D':	/* INCR and DECR */
		zzzcode(p->n_left, 'A');
		printf("\n	");

#if 0
	case 'E':	/* INCR and DECR, FOREFF */
		if (p->n_right->n_lval == 1)
			{
			printf("%s", (p->n_op == INCR ? "inc" : "dec") );
			prtype(p->n_left);
			printf("	");
			adrput(stdout, p->n_left);
			return;
			}
		printf("%s", (p->n_op == INCR ? "add" : "sub") );
		prtype(p->n_left);
		printf("2	");
		adrput(stdout, p->n_right);
		printf(",");
		adrput(p->n_left);
		return;
#endif

	case 'F':	/* register type of right operand */
		{
		register NODE *n;
		register int ty;

		n = getlr( p, 'R' );
		ty = n->n_type;

		if (x2debug) printf("->%d<-", ty);

		if ( ty==DOUBLE) printf("d");
		else if ( ty==FLOAT ) printf("f");
		else printf("l");
		return;
		}

	case 'G': /* emit conversion instructions */
		sconv(p);
		break;

	case 'J': /* jump or ret? */
		{
			struct interpass *ip =
			    DLIST_PREV((struct interpass *)p2env.epp, qelem);
			if (ip->type != IP_DEFLAB ||
			    ip->ip_lbl != getlr(p, 'L')->n_lval)
				expand(p, FOREFF, "jbr	LL");
			else
				printf("ret");
		}
		break;

	case 'L':	/* type of left operand */
	case 'R':	/* type of right operand */
		{
		register NODE *n;

		n = getlr ( p, c);
		if (x2debug) printf("->%d<-", n->n_type);

		prtype(n);
		return;
		}

	case 'O': /* print out emulated ops */
		expand(p, FOREFF, "\tmovq	AR,-(%sp)\n");
		expand(p, FOREFF, "\tmovq	AL,-(%sp)\n");
		if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
		else if (p->n_op == DIV) ch = "div";
		else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
		else if (p->n_op == MOD) ch = "mod";
		else if (p->n_op == MUL) ch = "mul";
		else ch = 0, comperr("ZO %d", p->n_op);
		printf("\tcalls	$4,__%sdi3\n", ch);
		break;


	case 'Z':	/* complement mask for bit instr */
		printf("$%Ld", ~p->n_right->n_lval);
		return;

	case 'U':	/* 32 - n, for unsigned right shifts */
		t = DEUNSIGN(p->n_left->n_type);
		m = t == CHAR ? 8 : t == SHORT ? 16 : 32;
		printf("$" CONFMT, m - p->n_right->n_lval);
		return;

	case 'T':	/* rounded structure length for arguments */
		{
		int size;

		size = p->n_stsize;
		SETOFF( size, 4);
		printf("$%d", size);
		return;
		}

	case 'S':  /* structure assignment */
		{
			register int size;

			size = p->n_stsize;
			l = r = NULL; /* XXX gcc */
			if( p->n_op == STASG ){
				l = p->n_left;
				r = p->n_right;

				}
			else if( p->n_op == STARG ){
				/* store an arg into a temporary */
				printf("\tsubl2 $%d,%%sp\n",
				    size < 4 ? 4 : size);
				l = mklnode(OREG, 0, SP, INT);
				r = p->n_left;
				}
			else cerror( "STASG bad" );

			if( r->n_op == ICON ) r->n_op = NAME;
			else if( r->n_op == REG ) r->n_op = OREG;
			else if( r->n_op != OREG ) cerror( "STASG-r" );

		if (size != 0) {
			if( size <= 0 || size > 65535 )
				cerror("structure size <0=0 or >65535");

			switch(size) {
				case 1:
					printf("	movb	");
					break;
				case 2:
					printf("	movw	");
					break;
				case 4:
					printf("	movl	");
					break;
				case 8:
					printf("	movq	");
					break;
				default:
					printf("	movc3	$%d,", size);
					break;
			}
			adrput(stdout, r);
			printf(",");
			adrput(stdout, l);
			printf("\n");
		}

			if( r->n_op == NAME ) r->n_op = ICON;
			else if( r->n_op == OREG ) r->n_op = REG;
			if (p->n_op == STARG)
				tfree(l);

			}
		break;

	default:
		comperr("illegal zzzcode '%c'", c);
	}
}
Example #6
0
/*
 * generate code by interpreting table entry
 */
void
expand(NODE *p, int cookie, char *cp)
{
	CONSZ val;

#if 0
	printf("expand\n");
	fwalk(p, e2print, 0);
#endif

	for( ; *cp; ++cp ){
		switch( *cp ){

		default:
			putchar(*cp);
			continue;  /* this is the usual case... */

		case 'Z':  /* special machine dependent operations */
			zzzcode( p, *++cp );
			continue;

		case 'F':  /* this line deleted if FOREFF is active */
			if (cookie & FOREFF) {
				while (*cp && *cp != '\n')
					cp++;
				if (*cp == 0)
					return;
			}
			continue;

		case 'S':  /* field size */
			if (fldexpand(p, cookie, &cp))
				continue;
			printf("%d", FLDSZ(p->n_rval));
			continue;

		case 'H':  /* field shift */
			if (fldexpand(p, cookie, &cp))
				continue;
			printf("%d", FLDSHF(p->n_rval));
			continue;

		case 'M':  /* field mask */
		case 'N':  /* complement of field mask */
			if (fldexpand(p, cookie, &cp))
				continue;
			val = 1;
			val <<= FLDSZ(p->n_rval);
			--val;
			val <<= FLDSHF(p->n_rval);
			adrcon( *cp=='M' ? val : ~val );
			continue;

		case 'L':  /* output special label field */
			if (*++cp == 'C')
				printf(LABFMT, p->n_label);
			else
				printf(LABFMT, (int)getlval(getlr(p,*cp)));
			continue;

		case 'O':  /* opcode string */
#ifdef FINDMOPS
			if (p->n_op == ASSIGN)
				hopcode(*++cp, p->n_right->n_op);
			else
#endif
			hopcode( *++cp, p->n_op );
			continue;

		case 'B':  /* byte offset in word */
			val = getlval(getlr(p,*++cp));
			val = BYTEOFF(val);
			printf( CONFMT, val );
			continue;

		case 'C': /* for constant value only */
			conput(stdout, getlr( p, *++cp ) );
			continue;

		case 'I': /* in instruction */
			insput( getlr( p, *++cp ) );
			continue;

		case 'A': /* address of */
			adrput(stdout, getlr( p, *++cp ) );
			continue;

		case 'U': /* for upper half of address, only */
			upput(getlr(p, *++cp), SZLONG);
			continue;

			}

		}

	}