示例#1
0
void
zzzcode(NODE * p, int c)
{
	int sz;

	switch (c) {

	case 'C':	/* remove arguments from stack after subroutine call */
		sz = p->n_qual > 16 ? p->n_qual : 16;
		printf("\taddiu %s,%s,%d\n", rnames[SP], rnames[SP], sz);
		break;

	case 'D':	/* long long comparison */
		twollcomp(p);
		break;

	case 'E':	/* emit emulated ops */
		emulop(p);
		break;

	case 'F':	/* emit emulate floating point ops */
		fpemulop(p);
		break;

	case 'G':	/* emit hardware floating-point compare op */
		fpcmpops(p);
		break;

	case 'H':	/* structure argument */
		starg(p);
		break;

	case 'I':		/* high part of init constant */
		if (p->n_name[0] != '\0')
			comperr("named highword");
		fprintf(stdout, CONFMT, (p->n_lval >> 32) & 0xffffffff);
		break;

        case 'O': /* 64-bit left and right shift operators */
		shiftop(p);
		break;

	case 'Q':		/* emit struct assign */
		stasg(p);
		break;

	default:
		comperr("zzzcode %c", c);
	}
}
示例#2
0
void
zzzcode(NODE *p, int c)
{
	TWORD t = p->n_type;
	char *s;

	switch (c) {
	case 'L':
		t = p->n_left->n_type;
		/* FALLTHROUGH */
	case 'A':
		s = (t == CHAR || t == UCHAR ? "b" :
		    t == SHORT || t == USHORT ? "w" : 
		    t == FLOAT ? "s" :
		    t == DOUBLE ? "d" :
		    t == LDOUBLE ? "x" : "l");
		printf("%s", s);
		break;

	case 'B':
		if (p->n_qual)
			printf("	add.l #%d,%%sp\n", (int)p->n_qual);
		break;

	case 'C': /* jsr or bsr.l XXX - type of CPU? */
		printf("%s", kflag ? "bsr.l" : "jsr");
		break;

	case 'F': /* Emit float branches */
		switch (p->n_op) {
		case GT: s = "fjnle"; break;
		case GE: s = "fjnlt"; break;
		case LE: s = "fjngt"; break;
		case LT: s = "fjnge"; break;
		case NE: s = "fjne"; break;
		case EQ: s = "fjeq"; break;
		default: comperr("ZF"); s = 0;
		}
		printf("%s " LABFMT "\n", s, p->n_label);
		break;

	case 'P':
		printf("	lea -%d(%%fp),%%a0\n", stkpos);
		break;

	case 'Q': /* struct assign */
		printf("	move.l %d,-(%%sp)\n", 
		    attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0));
		expand(p, INAREG, "	move.l AR,-(%sp)\n");
		expand(p, INAREG, "	move.l AL,-(%sp)\n");
		printf("	jsr memcpy\n");
		printf("	add.l #12,%%sp\n");
		break;

	case 'S': /* struct arg */
		starg(p);
		break;

	case '2':
		if (regno(getlr(p, '2')) != regno(getlr(p, 'L')))
			expand(p, INAREG, "	fmove.x AL,A2\n");
		break;

	default:
		comperr("zzzcode %c", c);
	}
}
示例#3
0
文件: local2.c 项目: didickman/pcc
void
zzzcode(NODE *p, int c)
{
	NODE *l;
	int pr, lr;
	char *ch;

	switch (c) {
	case 'A': /* swap st0 and st1 if right is evaluated second */
		if ((p->n_su & DORIGHT) == 0) {
			if (logop(p->n_op))
				printf("	fxch\n");
			else
				printf("r");
		}
		break;

	case 'C':  /* remove from stack after subroutine call */
#ifdef notyet
		if (p->n_left->n_flags & FSTDCALL)
			break;
#endif
		pr = p->n_qual;
		if (p->n_op == STCALL || p->n_op == USTCALL)
			pr += 4;
		if (p->n_flags & FFPPOP)
			printf("	fstp	%%st(0)\n");
		if (p->n_op == UCALL)
			return; /* XXX remove ZC from UCALL */
		if (pr)
			printf("	addl $%d, %s\n", pr, rnames[ESP]);
		break;

	case 'D': /* Long long comparision */
		twollcomp(p);
		break;

	case 'F': /* Structure argument */
		if (p->n_stalign != 0) /* already on stack */
			starg(p);
		break;

	case 'G': /* Floating point compare */
		fcomp(p);
		break;

	case 'H': /* assign of longlong between regs */
		rmove(DECRA(p->n_right->n_reg, 0),
		    DECRA(p->n_left->n_reg, 0), LONGLONG);
		break;

	case 'I': /* float casts */
		fcast(p);
		break;

	case 'J': /* convert unsigned long long to floating point */
		ulltofp(p);
		break;

	case 'K': /* Load longlong reg into another reg */
		rmove(regno(p), DECRA(p->n_reg, 0), LONGLONG);
		break;

	case 'M': /* Output sconv move, if needed */
		l = getlr(p, 'L');
		/* XXX fixneed: regnum */
		pr = DECRA(p->n_reg, 0);
		lr = DECRA(l->n_reg, 0);
		if ((pr == AL && lr == EAX) || (pr == BL && lr == EBX) ||
		    (pr == CL && lr == ECX) || (pr == DL && lr == EDX))
			;
		else
			printf("	movb %%%cl,%s\n",
			    rnames[lr][2], rnames[pr]);
		l->n_rval = l->n_reg = p->n_reg; /* XXX - not pretty */
		break;

	case 'N': /* output extended reg name */
		printf("%s", rnames[getlr(p, '1')->n_rval]);
		break;

	case 'O': /* print out emulated ops */
		pr = 16;
		if (p->n_op == RS || p->n_op == LS) {
			llshft(p);
			break;
		} else if (p->n_op == MUL) {
			printf("\timull %%ecx, %%edx\n");
			printf("\timull %%eax, %%esi\n");
			printf("\taddl %%edx, %%esi\n");
			printf("\tmull %%ecx\n");
			printf("\taddl %%esi, %%edx\n");
			break;
		}
		expand(p, INCREG, "\tpushl UR\n\tpushl AR\n");
		expand(p, INCREG, "\tpushl UL\n\tpushl AL\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 ch = 0, comperr("ZO");
#ifdef ELFABI
		printf("\tcall " EXPREFIX "__%sdi3%s\n\taddl $%d,%s\n",
			ch, (kflag ? "@PLT" : ""), pr, rnames[ESP]);
#else
		printf("\tcall " EXPREFIX "__%sdi3\n\taddl $%d,%s\n",
			ch, pr, rnames[ESP]);
#endif
                break;

	case 'P': /* push hidden argument on stack */
		printf("\tleal -%d(%%ebp),", stkpos);
		adrput(stdout, getlr(p, '1'));
		printf("\n\tpushl ");
		adrput(stdout, getlr(p, '1'));
		putchar('\n');
		break;

	case 'Q': /* emit struct assign */
		/*
		 * With <= 16 bytes, put out mov's, otherwise use movsb/w/l.
		 * esi/edi/ecx are available.
		 * XXX should not need esi/edi if not rep movsX.
		 * XXX can save one insn if src ptr in reg.
		 */
		switch (p->n_stsize) {
		case 1:
			expand(p, INAREG, "	movb (%esi),%cl\n");
			expand(p, INAREG, "	movb %cl,AL\n");
			break;
		case 2:
			expand(p, INAREG, "	movw (%esi),%cx\n");
			expand(p, INAREG, "	movw %cx,AL\n");
			break;
		case 4:
			expand(p, INAREG, "	movl (%esi),%ecx\n");
			expand(p, INAREG, "	movl %ecx,AL\n");
			break;
		default:
			expand(p, INAREG, "	leal AL,%edi\n");
			if (p->n_stsize <= 16 && (p->n_stsize & 3) == 0) {
				printf("	movl (%%esi),%%ecx\n");
				printf("	movl %%ecx,(%%edi)\n");
				printf("	movl 4(%%esi),%%ecx\n");
				printf("	movl %%ecx,4(%%edi)\n");
				if (p->n_stsize > 8) {
					printf("	movl 8(%%esi),%%ecx\n");
					printf("	movl %%ecx,8(%%edi)\n");
				}
				if (p->n_stsize == 16) {
					printf("\tmovl 12(%%esi),%%ecx\n");
					printf("\tmovl %%ecx,12(%%edi)\n");
				}
			} else {
				if (p->n_stsize > 4) {
					printf("\tmovl $%d,%%ecx\n",
					    p->n_stsize >> 2);
					printf("	rep movsl\n");
				}
				if (p->n_stsize & 2)
					printf("	movsw\n");
				if (p->n_stsize & 1)
					printf("	movsb\n");
			}
			break;
		}
		break;

	case 'S': /* emit eventual move after cast from longlong */
		pr = DECRA(p->n_reg, 0);
		lr = p->n_left->n_rval;
		switch (p->n_type) {
		case CHAR:
		case UCHAR:
			if (rnames[pr][2] == 'l' && rnames[lr][2] == 'x' &&
			    rnames[pr][1] == rnames[lr][1])
				break;
			if (rnames[lr][2] == 'x') {
				printf("\tmovb %%%cl,%s\n",
				    rnames[lr][1], rnames[pr]);
				break;
			}
			/* Must go via stack */
			expand(p, INAREG, "\tmovl AL,A2\n");
			expand(p, INBREG, "\tmovb A2,A1\n");
#ifdef notdef
			/* cannot use freetemp() in instruction emission */
			s = BITOOR(freetemp(1));
			printf("\tmovl %%e%ci,%d(%%ebp)\n", rnames[lr][1], s);
			printf("\tmovb %d(%%ebp),%s\n", s, rnames[pr]);
#endif
			break;

		case SHORT:
		case USHORT:
			if (rnames[lr][1] == rnames[pr][2] &&
			    rnames[lr][2] == rnames[pr][3])
				break;
			printf("\tmovw %%%c%c,%%%s\n",
			    rnames[lr][1], rnames[lr][2], rnames[pr]+2);
			break;
		case INT:
		case UNSIGNED:
			if (rnames[lr][1] == rnames[pr][2] &&
			    rnames[lr][2] == rnames[pr][3])
				break;
			printf("\tmovl %%e%c%c,%s\n",
				    rnames[lr][1], rnames[lr][2], rnames[pr]);
			break;

		default:
			if (rnames[lr][1] == rnames[pr][2] &&
			    rnames[lr][2] == rnames[pr][3])
				break;
			comperr("SCONV2 %s->%s", rnames[lr], rnames[pr]);
			break;
		}
		break;

	default:
		comperr("zzzcode %c", c);
	}
示例#4
0
文件: local2.c 项目: JamesLinus/pcc
void
zzzcode(NODE *p, int c)
{
	struct attr *ap;
	NODE *l;
	int pr, lr;
	char *ch;

	switch (c) {
	case 'A': /* swap st0 and st1 if right is evaluated second */
		if ((p->n_su & DORIGHT) == 0) {
			if (logop(p->n_op))
				printf("	fxch\n");
			else
				printf("r");
		}
		break;

	case 'C':  /* remove from stack after subroutine call */
#ifdef GCC_COMPAT
		if (attr_find(p->n_left->n_ap, GCC_ATYP_STDCALL))
			break;
#endif
		pr = p->n_qual;
		if (attr_find(p->n_ap, ATTR_I386_FPPOP))
			printf("	fstp	%%st(0)\n");
		if (p->n_op == UCALL)
			return; /* XXX remove ZC from UCALL */
		if (pr)
			printf("	addl $%d, %s\n", pr, rnames[ESP]);
#if defined(os_openbsd)
		ap = attr_find(p->n_ap, ATTR_P2STRUCT);
		if (p->n_op == STCALL && (ap->iarg(0) == 1 ||
		    ap->iarg(0) == 2 || ap->iarg(0) == 4 || 
		    ap->iarg(0) == 8)) {
			/* save on stack */
			printf("\tmovl %%eax,-%d(%%ebp)\n", stkpos);
			printf("\tmovl %%edx,-%d(%%ebp)\n", stkpos+4);
			printf("\tleal -%d(%%ebp),%%eax\n", stkpos);
		}
#endif
		break;

	case 'D': /* Long long comparision */
		twollcomp(p);
		break;

	case 'F': /* Structure argument */
		starg(p);
		break;

	case 'G': /* Floating point compare */
		fcomp(p);
		break;

	case 'H': /* assign of longlong between regs */
		rmove(DECRA(p->n_right->n_reg, 0),
		    DECRA(p->n_left->n_reg, 0), LONGLONG);
		break;

	case 'I': /* float casts */
		fcast(p);
		break;

	case 'J': /* convert unsigned long long to floating point */
		ulltofp(p);
		break;

	case 'K': /* Load longlong reg into another reg */
		rmove(regno(p), DECRA(p->n_reg, 0), LONGLONG);
		break;

	case 'M': /* Output sconv move, if needed */
		l = getlr(p, 'L');
		/* XXX fixneed: regnum */
		pr = DECRA(p->n_reg, 0);
		lr = DECRA(l->n_reg, 0);
		if ((pr == AL && lr == EAX) || (pr == BL && lr == EBX) ||
		    (pr == CL && lr == ECX) || (pr == DL && lr == EDX))
			;
		else
			printf("	movb %%%cl,%s\n",
			    rnames[lr][2], rnames[pr]);
		l->n_rval = l->n_reg = p->n_reg; /* XXX - not pretty */
		break;

	case 'N': /* output extended reg name */
		printf("%s", rnames[getlr(p, '1')->n_rval]);
		break;

	case 'O': /* print out emulated ops */
		pr = 16;
		if (p->n_op == RS || p->n_op == LS) {
			llshft(p);
			break;
		} else if (p->n_op == MUL) {
			printf("\timull %%ecx, %%edx\n");
			printf("\timull %%eax, %%esi\n");
			printf("\taddl %%edx, %%esi\n");
			printf("\tmull %%ecx\n");
			printf("\taddl %%esi, %%edx\n");
			break;
		}
		expand(p, INCREG, "\tpushl UR\n\tpushl AR\n");
		expand(p, INCREG, "\tpushl UL\n\tpushl AL\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 ch = 0, comperr("ZO");
#ifdef ELFABI
		printf("\tcall " EXPREFIX "__%sdi3%s\n\taddl $%d,%s\n",
			ch, (kflag ? "@PLT" : ""), pr, rnames[ESP]);
#else
		printf("\tcall " EXPREFIX "__%sdi3\n\taddl $%d,%s\n",
			ch, pr, rnames[ESP]);
#endif
                break;

	case 'Q': /* emit struct assign */
		/*
		 * Put out some combination of movs{b,w,l}
		 * esi/edi/ecx are available.
		 */
		expand(p, INAREG, "	leal AL,%edi\n");
		ap = attr_find(p->n_ap, ATTR_P2STRUCT);
		if (ap->iarg(0) < 32) {
			int i = ap->iarg(0) >> 2;
			while (i) {
				expand(p, INAREG, "	movsl\n");
				i--;
			}
		} else {
示例#5
0
void
zzzcode(NODE *p, int c)
{
	struct attr *ap;
	NODE *l;
	int pr, lr;
	char *ch;
	char sv;

	switch (c) {
	case 'A': /* swap st0 and st1 if right is evaluated second */
		if ((p->n_su & DORIGHT) == 0) {
			if (logop(p->n_op))
				printf("	fxch\n");
			else
				printf("r");
		}
		break;

	case 'C':  /* remove from stack after subroutine call */
#ifdef notdef
		if (p->n_left->n_flags & FSTDCALL)
			break;
#endif
		pr = p->n_qual;
		if (attr_find(p->n_ap, ATTR_I86_FPPOP))
			printf("	fstp	st(0)\n");
		if (p->n_op == UCALL)
			return; /* XXX remove ZC from UCALL */
		if (pr) {
			if (pr == 2)
				printf("	inc sp\n	inc sp\n");
			else
				printf("	add sp,#%d\n", pr);
		}
		break;

	case 'D': /* Long comparision */
		twollcomp(p);
		break;

	case 'F': /* Structure argument */
		starg(p);
		break;

	case 'G': /* Floating point compare */
		fcomp(p);
		break;

	case 'H': /* assign of long between regs */
		rmove(DECRA(p->n_right->n_reg, 0),
		    DECRA(p->n_left->n_reg, 0), LONGLONG);
		break;

	case 'I': /* float casts */
		fcast(p);
		break;

	case 'J': /* convert unsigned long long to floating point */
		ulltofp(p);
		break;

	case 'K': /* Load long reg into another reg */
		rmove(regno(p), DECRA(p->n_reg, 0), LONGLONG);
		break;

	case 'M': /* Output sconv move, if needed */
		l = getlr(p, 'L');
		/* XXX fixneed: regnum */
		pr = DECRA(p->n_reg, 0);
		lr = DECRA(l->n_reg, 0);
		if ((pr == AL && lr == AX) || (pr == BL && lr == BX) ||
		    (pr == CL && lr == CX) || (pr == DL && lr == DX))
			;
		else
			printf("	mov %s, %cL\n",
			    rnames[pr], rnames[lr][1]);
		l->n_rval = l->n_reg = p->n_reg; /* XXX - not pretty */
		break;

	case 'N': /* output extended reg name */
		printf("%s", rnames[getlr(p, '1')->n_rval]);
		break;

	case 'O': /* print out emulated ops */
		pr = 8;
		sv = 'l';
#if 0		
		if (p->n_op == RS || p->n_op == LS) {
			llshft(p);
			break;
		}
#endif
		if (p->n_op != RS && p->n_op != LS) {
			/* For 64bit we will need to push pointers
			   not u64 */
			expand(p, INCREG, "\tpush UR\n\tpush AR\n");
			expand(p, INCREG, "\tpush UL\n\tpush AL\n");
		} else {
			/* AR is a BREG so this goes wrong.. need an AREG
			   but putting an AREG in the table rule makes the
			   compiler shit itself - FIXME */
			expand(p, INAREG, "\tpush AR\n");
			expand(p, INCREG, "\tpush UL\n\tpush AL\n");
			pr = 6;
		}
		
		if (p->n_type == LONGLONG || p->n_type == ULONGLONG)
			sv = 'L';
		if (p->n_op == DIV && (p->n_type == ULONG || p->n_type == ULONGLONG))
			ch = "udiv";
		else if (p->n_op == MUL && (p->n_type == ULONG || p->n_type == ULONGLONG))
			ch = "umul";
		else if (p->n_op == DIV) ch = "div";
		else if (p->n_op == MUL) ch = "mul";
		else if (p->n_op == MOD && (p->n_type == ULONG || p->n_type == ULONGLONG))
			ch = "umod";
		else if (p->n_op == MOD) ch = "mod";
		else if (p->n_op == LS) ch = "ls";
		else if (p->n_op == RS && (p->n_type == ULONG || p->n_type == ULONGLONG))
			ch = "rs";
		else if (p->n_op == RS) ch = "urs";
		else ch = 0, comperr("ZO");
		printf("\tcall " EXPREFIX "__%c%sdi3\n\tadd %s,#%d\n",
			sv, ch, rnames[SP], pr);
                break;
	
	case 'P': /* typeless right hand */
		suppress_type = 1;
		break;

	case 'Q': /* emit struct assign */
		/*
		 * Put out some combination of movs{b,w}
		 * si/di/cx are available.
		 * FIXME: review es: and direction flag implications
		 */
		expand(p, INAREG, "	lea al,di\n");
		ap = attr_find(p->n_ap, ATTR_P2STRUCT);
		if (ap->iarg(0) < 32) {
			int i = ap->iarg(0) >> 1;
			while (i) {
				expand(p, INAREG, "	movsw\n");
				i--;
			}
		} else {