コード例 #1
0
ファイル: local2.c プロジェクト: didickman/pcc
/*
 * Convert an unsigned long long to floating point number.
 */
static void
ulltofp(NODE *p)
{
#if defined(ELFABI) || defined(PECOFFABI)
	static int loadlab;
	int jmplab;

	if (loadlab == 0) {
		loadlab = getlab2();
		expand(p, 0, "	.data\n");
		printf(LABFMT ":	.long 0,0x80000000,0x403f\n", loadlab);
		expand(p, 0, "	.text\n");
	}
	jmplab = getlab2();
	expand(p, 0, "	pushl UL\n	pushl AL\n");
	expand(p, 0, "	fildq (%esp)\n");
	expand(p, 0, "	addl $8,%esp\n");
	expand(p, 0, "	cmpl $0,UL\n");
	printf("	jge " LABFMT "\n", jmplab);
	printf("	fldt " LABFMT "%s\n", loadlab, kflag ? "@GOTOFF" : "");
	printf("	faddp %%st,%%st(1)\n");
	printf(LABFMT ":\n", jmplab);
#else
#error incomplete implementation
#endif
}
コード例 #2
0
ファイル: local2.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * Convert an unsigned long long to floating point number.
 */
static void
ulltofp(NODE *p)
{
	int jmplab = getlab2();

	if (loadlab == 0)
		loadlab = getlab2();
	expand(p, 0, "	movl UL,4+A2\n	movl AL,A2\n");
	expand(p, 0, "	fildq A2\n");
	expand(p, 0, "	test UL,UL\n");
	printf("	jge " LABFMT "\n", jmplab);
	printf("	fadds " LABFMT "%s\n", loadlab, kflag ? "@GOTOFF" : "");
	printf(LABFMT ":\n", jmplab);
}
コード例 #3
0
ファイル: local2.c プロジェクト: enukane/netbsd-src
/*
 * Emit code to compare two longlong numbers.
 */
static void
twollcomp(NODE *p)
{
	int o = p->n_op;
	int s = getlab2();
	int e = p->n_label;
	int cb1, cb2;

	if (o >= ULE)
		o -= (ULE-LE);
	switch (o) {
	case NE:
		cb1 = 0;
		cb2 = NE;
		break;
	case EQ:
		cb1 = NE;
		cb2 = 0;
		break;
	case LE:
	case LT:
		cb1 = GT;
		cb2 = LT;
		break;
	case GE:
	case GT:
		cb1 = LT;
		cb2 = GT;
		break;
	
	default:
		cb1 = cb2 = 0; /* XXX gcc */
	}
	if (p->n_op >= ULE)
		cb1 += 4, cb2 += 4;
	expand(p, 0, "\tsub A1,UL,UR\t# compare 64-bit values (upper)\n");
	if (cb1) {
		printf("\t");
		hopcode(' ', cb1);
		expand(p, 0, "A1");
		printf("," LABFMT "\n", s);
		printf("\tnop\n");
	}
	if (cb2) {
		printf("\t");
		hopcode(' ', cb2);
		expand(p, 0, "A1");
		printf("," LABFMT "\n", e);
		printf("\tnop\n");
	}
	expand(p, 0, "\tsub A1,AL,AR\t# (and lower)\n");
	printf("\t");
	hopcode(' ', o);
	expand(p, 0, "A1");
	printf("," LABFMT "\n", e);
	printf("\tnop\n");
	deflab(s);
}
コード例 #4
0
void
prologue(int regs, int autos)
{
	int i, addto;

	offlab = getlab2();
	if (regs < 0 || autos < 0) {
		/*
		 * non-optimized code, jump to epilogue for code generation.
		 */
		ftlab1 = getlab2();
		ftlab2 = getlab2();
		printf("	jrst L%d\n", ftlab1);
		printf("L%d:\n", ftlab2);
	} else {
		/*
		 * We here know what register to save and how much to 
		 * add to the stack.
		 */
		autos = autos + (SZINT-1);
		addto = (autos - AUTOINIT)/SZINT + (MAXRVAR-regs);
		if (addto || gflag) {
			printf("	push %s,%s\n",rnames[017], rnames[016]);
			printf("	move %s,%s\n", rnames[016],rnames[017]);
			for (i = regs; i < MAXRVAR; i++) {
				int db = ((i+1) < MAXRVAR);
				printf("	%smovem %s,0%o(%s)\n",
				    db ? "d" : "",
				    rnames[i+1], i+1-regs, rnames[016]);
				if (db)
					i++;
			}
			if (addto)
				printf("	addi %s,0%o\n", rnames[017], addto);
		} else
			offarg = 1;
	}
}
コード例 #5
0
ファイル: local2.c プロジェクト: didickman/pcc
/*
 * Emit code to compare two longlong numbers.
 */
static void
twollcomp(NODE *p)
{
	int u;
	int s = getlab2();
	int e = p->n_label;
	int cb1, cb2;

	u = p->n_op;
	switch (p->n_op) {
	case NE:
		cb1 = 0;
		cb2 = NE;
		break;
	case EQ:
		cb1 = NE;
		cb2 = 0;
		break;
	case LE:
	case LT:
		u += (ULE-LE);
		/* FALLTHROUGH */
	case ULE:
	case ULT:
		cb1 = GT;
		cb2 = LT;
		break;
	case GE:
	case GT:
		u += (ULE-LE);
		/* FALLTHROUGH */
	case UGE:
	case UGT:
		cb1 = LT;
		cb2 = GT;
		break;
	
	default:
		cb1 = cb2 = 0; /* XXX gcc */
	}
	if (p->n_op >= ULE)
		cb1 += 4, cb2 += 4;
	expand(p, 0, "	cmpl UR,UL\n");
	if (cb1) cbgen(cb1, s);
	if (cb2) cbgen(cb2, e);
	expand(p, 0, "	cmpl AR,AL\n");
	cbgen(u, e);
	deflab(s);
}
コード例 #6
0
ファイル: local2.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * Convert an unsigned long long to floating point number.
 */
static void
ulltofp(NODE *p)
{
	int jmplab;

	jmplab = getlab2();
	expand(p, 0, "	push UL\n	push AL\n");
	expand(p, 0, "	fildq [sp]\n");
	expand(p, 0, "	add sp, #8\n");
	expand(p, 0, "	cmp UL, #0\n");
	printf("	jge " LABFMT "\n", jmplab);

	printf("	faddp %%st,%%st(1)\n");
	printf(LABFMT ":\n", jmplab);
}
コード例 #7
0
ファイル: local2.c プロジェクト: mutoso-mirrors/pcc
/*
 * Print out the prolog assembler.
 * addto and regoff are already calculated.
 */
void
prologue(struct interpass_prolog *ipp)
{
	printf("	.word 0x%llx\n", (unsigned long long)ipp->ipp_regs[0]);
	if (p2maxautooff)
		printf("	subl2 $%d,%%sp\n", p2maxautooff);
	if (pflag) {
		int i = getlab2();
		printf("\tmovab\t" LABFMT ",%%r0\n", i);
		printf("\tjsb\t__mcount\n");
		printf("\t.data\n");
		printf("\t.align  2\n");
		printf(LABFMT ":\t.long\t0\n", i);
		printf("\t.text\n");
	}
}
コード例 #8
0
ファイル: local2.c プロジェクト: mutoso-mirrors/pcc
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);
	}
}
コード例 #9
0
void
prologue(struct interpass_prolog *ipp)
{
    ftype = ipp->ipp_type;

#if 0
    if (ipp->ipp_regs > 0 && ipp->ipp_regs != MINRVAR)
	comperr("fix prologue register savings", ipp->ipp_regs);
#endif
    
    printf("	RSEG CODE:CODE:REORDER:NOROOT(0)\n");
    if (ipp->ipp_vis)	
	printf("	PUBLIC %s\n", ipp->ipp_name);
    printf("%s:\n", ipp->ipp_name);
    
#if 0	
    if (xsaveip) {
	/* Optimizer running, save space on stack */
	addto = (p2maxautooff - AUTOINIT)/SZCHAR;
	printf("	enter #%d\n", addto);
    } else {
#endif

	/* non-optimized code, jump to epilogue for code generation */
	ftlab1 = getlab2();
	ftlab2 = getlab2();
	printf("	jmp.w " LABFMT "\n", ftlab1);
	deflab(ftlab2);
}

/*
 * End of block.
 */
void
eoftn(struct interpass_prolog *ipp)
{
#if 0
	if (ipp->ipp_regs != MINRVAR)
		comperr("fix eoftn register savings %x", ipp->ipp_regs);
#endif

	//	if (xsaveip == 0)
	addto = (p2maxautooff - AUTOINIT)/SZCHAR;

	/* return from function code */
	//deflab(ipp->ipp_ip.ip_lbl);   //XXX - is this necessary?
	
	/* If retval is a pointer and not a function pointer, put in A0 */
	if (ISPTR(DECREF(ipp->ipp_type)) &&
	    !ISFTN(DECREF(DECREF(ipp->ipp_type))))
	    printf("	mov.w r0,a0\n");
	
	/* struct return needs special treatment */
	if (ftype == STRTY || ftype == UNIONTY) {
		comperr("fix struct return in eoftn");
	} else
		printf("	exitd\n");

	/* Prolog code */
	//	if (xsaveip == 0) {
		deflab(ftlab1);
		printf("	enter #%d\n", addto);
		printf("	jmp.w " LABFMT "\n", ftlab2);
		//}
}

/*
 * add/sub/...
 *
 * Param given:
 */
void
hopcode(int f, int o)
{
	char *str;

	switch (o) {
	case PLUS:
		str = "add";
		break;
	case MINUS:
		str = "sub";
		break;
	case AND:
		str = "and";
		break;
	case OR:
		str = "or";
		break;
	case ER:
		str = "xor";
		break;
	default:
		comperr("hopcode2: %d", o);
		str = 0; /* XXX gcc */
	}
	printf("%s.%c", str, f);
}