コード例 #1
0
ファイル: code.c プロジェクト: didickman/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	static char *loctbl[] = { "text", "data", "data" };
	TWORD t;
	char *n;
	int s;

	if (sp == NULL) {
		lastloc = -1;
		return;
	}
	t = sp->stype;
	s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
	if (s != lastloc)
		printf("	.%s\n", loctbl[s]);
	lastloc = s;
	while (ISARY(t))
		t = DECREF(t);
	n = sp->soname ? sp->soname : exname(sp->sname);
	if (sp->sclass == EXTDEF)
		printf("	.globl %s\n", n);
	if (ISFTN(sp->stype) || talign(sp->stype, sp->ssue) > ALCHAR)
		printf(".even\n");
	if (sp->slevel == 0) {
		printf("%s:\n", n);
	} else {
		printf(LABFMT ":\n", sp->soffset);
	}
}
コード例 #2
0
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	char *nextsect = NULL;	/* notyet */
	static char *loctbl[] = { "text", "data", "section .rodata" };
	static int lastloc = -1;
	TWORD t;
	int s;

	if (sp == NULL) {
		lastloc = -1;
		return;
	}
	t = sp->stype;
	s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
	if (nextsect) {
		printf("	.section %s\n", nextsect);
		nextsect = NULL;
		s = -1;
	} else if (s != lastloc)
		printf("	.%s\n", loctbl[s]);
	lastloc = s;
	if (sp->sclass == EXTDEF)
		printf("	.globl %s\n", sp->soname);
	if (sp->slevel == 0)
		printf("%s:\n", sp->soname);
	else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #3
0
/*
 * Do name mangling of a symbol table entry.
 * The resulting name is saved in soname.
 */
char *
decoratename(struct symtab *sp, int type)
{
	char *n;

#define	QNM(m,s) case m: n = s; break
	switch (type) {
	QNM(NM_NEW,"_Znwm");
	QNM(NM_NWA,"_Znam");
	QNM(NM_DEL,"_ZdlPv");
	QNM(NM_DLA,"_ZdaPv");
	case NM_NORMAL: /* Defined in defid() */
		break;
	default:
		uerror("missed mangling %d\n", type);
		return "";
	}
	if (type != NM_NORMAL)
		return addname(n);

	/* special non-mangled cases:
	 * "C" linkage
	 * main() function
	 * variables outside namespaces and classes
	 */
	if (elnk == LINK_C || strcmp(sp->sname, "main") == 0 ||
	    (sp->sdown == spole && ISFTN(sp->stype) == 0)) {
		n = exname(sp->sname);
		return addname(n);
	}
	/* Compute the mangled name for other symbols */
	nmptr = 0;
	subptr = 0;
	nmch('_'); nmch('Z');
	if (sp->sdown != NULL) {
		nmch('N');
		recnpsh(sp->sdown);
	}
	pshsln(sp->sname);
	if (sp->sdown != NULL)
		nmch('E');
	if (ISFTN(sp->stype) && sp->sdf->dfun)
		pshargs(sp->sdf->dfun);
	nmch(0);
	return addname(nmblk);
}
コード例 #4
0
ファイル: common.c プロジェクト: pauley/pcc
/*
 * output a nice description of the type of t
 */
void
tprint(FILE *fp, TWORD t, TWORD q)
{
	static char * tnames[] = {
		"undef",
		"farg",
		"char",
		"uchar",
		"short",
		"ushort",
		"int",
		"unsigned",
		"long",
		"ulong",
		"longlong",
		"ulonglong",
		"float",
		"double",
		"ldouble",
		"strty",
		"unionty",
		"enumty",
		"moety",
		"void",
		"signed", /* pass1 */
		"bool", /* pass1 */
		"fimag", /* pass1 */
		"dimag", /* pass1 */
		"limag", /* pass1 */
		"fcomplex", /* pass1 */
		"dcomplex", /* pass1 */
		"lcomplex", /* pass1 */
		"enumty", /* pass1 */
		"?", "?"
		};

	for(;; t = DECREF(t), q = DECREF(q)) {
		if (ISCON(q))
			fputc('C', fp);
		if (ISVOL(q))
			fputc('V', fp);

		if (ISPTR(t))
			fprintf(fp, "PTR ");
		else if (ISFTN(t))
			fprintf(fp, "FTN ");
		else if (ISARY(t))
			fprintf(fp, "ARY ");
		else {
			fprintf(fp, "%s%s%s", ISCON(q << TSHIFT) ? "const " : "",
			    ISVOL(q << TSHIFT) ? "volatile " : "", tnames[t]);
			return;
		}
	}
}
コード例 #5
0
ファイル: code.c プロジェクト: rheoli/pcc
/*
 * Called with a function call with arguments as argument.
 * This is done early in buildtree() and only done once.
 * Returns p.
 */
NODE *
funcode(NODE *p)
{
	NODE *l, *r;
	TWORD t;
	int i;

	nsse = ngpr = nrsp = 0;
	/* Check if hidden arg needed */
	/* If so, add it in pass2 */
	if ((l = p->n_left)->n_type == INCREF(FTN)+STRTY ||
	    l->n_type == INCREF(FTN)+UNIONTY) {
		int ssz = tsize(BTYPE(l->n_type), l->n_df, l->n_ap);
		if (ssz > 2*SZLONG)
			ngpr++;
	}

	/* Convert just regs to assign insn's */
	p->n_right = argput(p->n_right);

	/* Must sort arglist so that STASG ends up first */
	/* This avoids registers being clobbered */
	while (argsort(p->n_right))
		;
	/* Check if there are varargs */
	if (nsse || l->n_df == NULL || l->n_df->dfun == NULL) {
		; /* Need RAX */
	} else {
		union arglist *al = l->n_df->dfun;

		for (; al->type != TELLIPSIS; al++) {
			if ((t = al->type) == TNULL)
				return p; /* No need */
			if (ISSOU(BTYPE(t)))
				al++;
			for (i = 0; t > BTMASK; t = DECREF(t))
				if (ISARY(t) || ISFTN(t))
					i++;
			if (i)
				al++;
		}
	}

	/* Always emit number of SSE regs used */
	l = movtoreg(bcon(nsse), RAX);
	if (p->n_right->n_op != CM) {
		p->n_right = block(CM, l, p->n_right, INT, 0, 0);
	} else {
		for (r = p->n_right; r->n_left->n_op == CM; r = r->n_left)
			;
		r->n_left = block(CM, l, r->n_left, INT, 0, 0);
	}
	return p;
}
コード例 #6
0
ファイル: code.c プロジェクト: paploo/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	extern char *nextsect;
	static int lastloc = -1;
	TWORD t;
	char *n;
	int s;

	if (sp == NULL) {
		lastloc = -1;
		return;
	}
	t = sp->stype;
	s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
	if (nextsect) {
		printf("\t.section %s\n", nextsect);
		nextsect = NULL;
		s = -1;
	} else if (s != lastloc)
		printf("\t.%s\n", loctbl[s]);
	lastloc = s;
	while (ISARY(t))
		t = DECREF(t);
	s = ISFTN(t) ? ALINT : talign(t, sp->ssue);
	if (s > ALCHAR)
		printf("\t.align\t%d\n", s / ALCHAR);
	n = sp->soname ? sp->soname : sp->sname;
	if (sp->sclass == EXTDEF)
		printf("\t.export %s, %s\n", n,
		    ISFTN(t)? "code" : "data");
	if (sp->slevel == 0)
		printf("\t.type\t%s, @%s\n\t.label %s\n",
		    n, ISFTN(t)? "function" : "object", n);
	else
		printf("\t.type\t" LABFMT ", @%s\n\t.label\t" LABFMT "\n", 
		    sp->soffset, ISFTN(t)? "function" : "object", sp->soffset);
}
コード例 #7
0
ファイル: code.c プロジェクト: JamesLinus/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	char *n;

	if (ISFTN(sp->stype))
		return; /* XXX until fixed */

	n = getexname(sp);

	if (sp->sclass == EXTDEF)
		printf("	.globl %s\n", n);
	if (sp->slevel == 0) {
#ifdef USE_GAS
		printf("\t.type %s,@%s\n", n,
		    ISFTN(sp->stype) ? "function" : "object");
		if (!ISFTN(sp->stype))
			printf("\t.size %s," CONFMT "\n", n,
			    tsize(sp->stype, sp->sdf, sp->sap));
#endif
		printf("%s:\n", n);
	} else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #8
0
ファイル: code.c プロジェクト: MoochMcGee/pcc-optimized
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	char *n;

	n = sp->soname ? sp->soname : exname(sp->sname);
#ifdef USE_GAS
	if (ISFTN(t))
		printf("\t.type %s,%%function\n", n);
#endif
	if (sp->sclass == EXTDEF)
		printf("\t.global %s\n", n);
	if (sp->slevel == 0)
		printf("%s:\n", n);
	else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #9
0
ファイル: code.c プロジェクト: JamesLinus/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	char *name;

	if ((name = sp->soname) == NULL)
		name = exname(sp->sname);

	if (ISFTN(sp->stype))
		return;
	if (sp->sclass == EXTDEF)
		printf("\t.globl %s\n", name);
	if (sp->slevel == 0)
		printf("%s:\n", name);
	else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #10
0
/*
 * Compare a matching prototype for a function.
 */
static int
cxxpcmp(struct symtab *sp, NODE *p)
{
	union arglist *a1, *a2;
	int i;

	if (!ISFTN(sp->stype) || p->n_df == NULL || sp->sdf == NULL)
		return 0; /* no dimfun */
	if ((a1 = sp->sdf->dfun) == NULL || (a2 = p->n_df->dfun) == NULL)
		return 0; /* no argument */

	for (i = 0; ; i++) {
		if (a1[i].type == TNULL && a2[i].type == TNULL)
			return 1; /* equal prototypes */
		if (a1[i].type != a2[i].type)
			return 1; /* unequal prototypes */
	}
}
コード例 #11
0
ファイル: code.c プロジェクト: Sciumo/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	char *name;

	if ((name = sp->soname) == NULL)
		name = exname(sp->sname);

	if (sp->sclass == EXTDEF) {
		printf("\t.globl %s\n", name);
		printf("\t.type %s,@%s\n", name,
		    ISFTN(sp->stype)? "function" : "object");
	}
	if (sp->slevel == 0)
		printf("%s:\n", name);
	else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #12
0
/*
 * Watch out for references to static members.
 */
NODE *
cxxstructref(NODE *p, int f, char *n)
{
	struct symtab *sp = strmemb(p->n_ap);

	if (sp == NULL)
		cerror("ref to unknown struct");
	sp = sfind(n, sp);
	while (sp != NULL) {
		if (ISFTN(sp->stype) == 0) {
			if (sp->sclass == STATIC || sp->sclass == USTATIC) {
				tfree(p);
				return nametree(sp);
			}
			break;
		}
		sp = sfind(n, sp->snext);
	}
	return structref(p, f, n);
}
コード例 #13
0
/*
 * Compare a matching prototype for an argument tree.
 * Here we can expand to also do inexact matches.
 * Return 0 if equal, -1 if failed.
 */
static int
cxxptreecmp(struct symtab *sp, NODE *p)
{
	struct ckstr ckstr;
	union arglist *a1;

	if (!ISFTN(sp->stype) || sp->sdf == NULL ||
	    (a1 = sp->sdf->dfun) == NULL)
		return 0; /* no dimfun */

	if (p == NULL && a1[0].type == TNULL)
		return 1; /* arg-less */

	ckstr.rv = 0;
	ckstr.al = a1;
	flist(p, cxxckproto, &ckstr);

	if (ckstr.al[0].type != TNULL)
		return -1; /* arg number error */
	return ckstr.rv;
}
コード例 #14
0
ファイル: code.c プロジェクト: ajinkya93/netbsd-src
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	char *name;

	name = getexname(sp);

	if (sp->sclass == EXTDEF) {
		printf("\t.globl %s\n", name);
		if (ISFTN(sp->stype)) {
			printf("\t.type %s,@function\n", name);
		} else {
			printf("\t.type %s,@object\n", name);
			printf("\t.size %s,%d\n", name,
			    (int)tsize(sp->stype, sp->sdf, sp->sap)/SZCHAR);
		}
	}
	if (sp->slevel == 0)
		printf("%s:\n", name);
	else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #15
0
ファイル: code.c プロジェクト: JamesLinus/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	static char *loctbl[] = { "text", "data", "data" };
	TWORD t;
	char *n;
	int s;

	t = sp->stype;
	s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
	if (s != lastloc)
		printf("	.%s\n", loctbl[s]);
	lastloc = s;
	n = sp->soname ? sp->soname : exname(sp->sname);
	if (sp->sclass == EXTDEF)
		printf("	.globl %s\n", n);
	if (sp->slevel == 0) {
		printf("%s:\n", n);
	} else {
		printf(LABFMT ":\n", sp->soffset);
	}
}
コード例 #16
0
ファイル: code.c プロジェクト: MoochMcGee/pcc-optimized
void
defloc(struct symtab *sp)
{
	TWORD t;
	char *name;

	t = sp->stype;

	if ((name = sp->soname) == NULL)
		name = exname(sp->sname);

	if (!ISFTN(t)) {
		printf("\t.type %s,#object\n", name);
		printf("\t.size %s," CONFMT "\n", name,
			tsize(sp->stype, sp->sdf, sp->sap) / SZCHAR);
	}
	if (sp->sclass == EXTDEF)
		printf("\t.global %s\n", name);
	if (sp->slevel == 0) {
		printf("%s:\n", name);
	} else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #17
0
/*
 * Search for correct matching function in a struct depending on 
 * argument list a.  Return a call node for this function.
 * Do not touch neither f nor a.
 * return a name tree suitable for a function call.
 * We know here that f is a struct reference.
 */
NODE *
cxxmatchftn(NODE *f, NODE *a)
{
	struct attr *ap;
	struct symtab *sp;
	char *n = (char *)f->n_right->n_sp;

	f = f->n_left;

	if ((ap = attr_find(f->n_ap, ATTR_STRUCT)) == NULL) {
		uerror("undefined class");
		sp = getsymtab(n, 0);
	} else
		sp = ap->amlist;
	sp = sfind(n, sp);
	while (sp != NULL) {
		if (ISFTN(sp->stype) && cxxptreecmp(sp, a) == 0)
			break;
		sp = sfind(n, sp->snext);
	}
	if (sp == NULL)
		uerror("undefined class member");
	return nametree(sp);
}
コード例 #18
0
ファイル: code.c プロジェクト: fhector/helenOS-0.5-Hector
/*
 * code for the beginning of a function; a is an array of
 * indices in symtab for the arguments; n is the number
 * On m16k, space is allocated on stack for register arguments,
 * arguments are moved to the stack and symtab is updated accordingly.
 */
void
bfcode(struct symtab **a, int n)
{
	struct symtab *s;
	int i, r0l, r0h, a0, r2, sz, hasch, stk;
	int argoff = ARGINIT;

	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		/* Function returns struct, adjust arg offset */
		for (i = 0; i < n; i++)
			a[i]->soffset += SZPOINT(INT);
	}
	/* first check if there are 1-byte parameters */
	for (hasch = i = 0; i < n && i < 6; i++)
		if (DEUNSIGN(a[i]->stype) == CHAR)
			hasch = 1;

	stk = r0l = r0h = a0 = r2 = 0;
	for (i = 0; i < n; i++) {
		s = a[i];
		sz = tsize(s->stype, s->sdf, s->ssue);
		if (ISPTR(s->stype) && ISFTN(DECREF(s->stype)))
			sz = SZLONG; /* function pointers are always 32 */
		if (stk == 0)
		    switch (sz) {
		case SZCHAR:
			if (r0l) {
				if (r0h)
					break;
				argmove(s, 1);
				r0h = 1;
			} else {
				argmove(s, 0);
				r0l = 1;
			}
			continue;

		case SZINT:
			if (s->stype > BTMASK) {
				/* is a pointer */
				if (a0) {
					if (r0l || hasch) {
						if (r2)
							break;
						argmove(s, R2);
						r2 = 1;
					} else {
						argmove(s, R0);
						r0l = r0h = 1;
					}
				} else {
					argmove(s, A0);
					a0 = 1;
				}
			} else if (r0l || hasch) {
				if (r2) {
					if (a0)
						break;
					argmove(s, A0);
					a0 = 1;
				} else {
					argmove(s, R2);
					r2 = 1;
				}
			} else {
				argmove(s, R0);
				r0l = r0h = 1;
			}
			continue;
		case SZLONG:
			if (r0l||r0h||r2)
				break;
			argmove(s, R0);
			r0l = r0h = r2 = 1;
			continue;

		default:
			break;
		}
		stk = 1;
		s->soffset = argoff;
		argoff += sz;
	}
}
コード例 #19
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);
}
コード例 #20
0
ファイル: code.c プロジェクト: fhector/helenOS-0.5-Hector
/*
 * code for the beginning of a function; a is an array of
 * indices in symtab for the arguments; n is the number
 */
void
bfcode(struct symtab **s, int cnt)
{
	union arglist *al;
	struct symtab *sp;
	NODE *p, *r;
	TWORD t;
	int i, rno, typ;

	/* recalculate the arg offset and create TEMP moves */
	/* Always do this for reg, even if not optimizing, to free arg regs */
	nsse = ngpr = 0;
	nrsp = ARGINIT;
	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		sp = cftnsp;
		if (argtyp(DECREF(sp->stype), sp->sdf, sp->sap) == STRMEM) {
			r = block(REG, NIL, NIL, LONG, 0, MKAP(LONG));
			regno(r) = argregsi[ngpr++];
			p = tempnode(0, r->n_type, r->n_df, r->n_ap);
			stroffset = regno(p);
			ecomp(buildtree(ASSIGN, p, r));
		}
	}

	for (i = 0; i < cnt; i++) {
		sp = s[i];

		if (sp == NULL)
			continue; /* XXX when happens this? */

		switch (typ = argtyp(sp->stype, sp->sdf, sp->sap)) {
		case INTEGER:
		case SSE:
			if (typ == SSE)
				rno = XMM0 + nsse++;
			else
				rno = argregsi[ngpr++];
			r = block(REG, NIL, NIL, sp->stype, sp->sdf, sp->sap);
			regno(r) = rno;
			p = tempnode(0, sp->stype, sp->sdf, sp->sap);
			sp->soffset = regno(p);
			sp->sflags |= STNODE;
			ecomp(buildtree(ASSIGN, p, r));
			break;

		case SSEMEM:
			sp->soffset = nrsp;
			nrsp += SZDOUBLE;
			if (xtemps) {
				p = tempnode(0, sp->stype, sp->sdf, sp->sap);
				p = buildtree(ASSIGN, p, nametree(sp));
				sp->soffset = regno(p->n_left);
				sp->sflags |= STNODE;
				ecomp(p);
			}
			break;

		case INTMEM:
			sp->soffset = nrsp;
			nrsp += SZLONG;
			if (xtemps) {
				p = tempnode(0, sp->stype, sp->sdf, sp->sap);
				p = buildtree(ASSIGN, p, nametree(sp));
				sp->soffset = regno(p->n_left);
				sp->sflags |= STNODE;
				ecomp(p);
			}
			break;

		case STRMEM: /* Struct in memory */
			sp->soffset = nrsp;
			nrsp += tsize(sp->stype, sp->sdf, sp->sap);
			break;

		case X87: /* long double args */
			sp->soffset = nrsp;
			nrsp += SZLDOUBLE;
			break;

		case STRCPX:
		case STRREG: /* Struct in register */
			/* Allocate space on stack for the struct */
			/* For simplicity always fetch two longwords */
			autooff += (2*SZLONG);

			if (typ == STRCPX) {
				t = DOUBLE;
				rno = XMM0 + nsse++;
			} else {
				t = LONG;
				rno = argregsi[ngpr++];
			}
			r = block(REG, NIL, NIL, t, 0, MKAP(t));
			regno(r) = rno;
			ecomp(movtomem(r, -autooff, FPREG));

			if (tsize(sp->stype, sp->sdf, sp->sap) > SZLONG) {
				r = block(REG, NIL, NIL, t, 0, MKAP(t));
				regno(r) = (typ == STRCPX ?
				    XMM0 + nsse++ : argregsi[ngpr++]);
				ecomp(movtomem(r, -autooff+SZLONG, FPREG));
			}

			sp->soffset = -autooff;
			break;

		default:
			cerror("bfcode: %d", typ);
		}
	}

	/* Check if there are varargs */
	if (cftnsp->sdf == NULL || cftnsp->sdf->dfun == NULL)
		return; /* no prototype */
	al = cftnsp->sdf->dfun;

	for (; al->type != TELLIPSIS; al++) {
		t = al->type;
		if (t == TNULL)
			return;
		if (BTYPE(t) == STRTY || BTYPE(t) == UNIONTY)
			al++;
		for (; t > BTMASK; t = DECREF(t))
			if (ISARY(t) || ISFTN(t))
				al++;
	}

	/* fix stack offset */
	SETOFF(autooff, ALMAX);

	/* Save reg arguments in the reg save area */
	p = NIL;
	for (i = ngpr; i < 6; i++) {
		r = block(REG, NIL, NIL, LONG, 0, MKAP(LONG));
		regno(r) = argregsi[i];
		r = movtomem(r, -RSALONGOFF(i)-autooff, FPREG);
		p = (p == NIL ? r : block(COMOP, p, r, INT, 0, MKAP(INT)));
	}
	for (i = nsse; i < 8; i++) {
		r = block(REG, NIL, NIL, DOUBLE, 0, MKAP(DOUBLE));
		regno(r) = i + XMM0;
		r = movtomem(r, -RSADBLOFF(i)-autooff, FPREG);
		p = (p == NIL ? r : block(COMOP, p, r, INT, 0, MKAP(INT)));
	}
	autooff += RSASZ;
	rsaoff = autooff;
	thissse = nsse;
	thisgpr = ngpr;
	thisrsp = nrsp;

	ecomp(p);
}
コード例 #21
0
ファイル: match.c プロジェクト: JamesLinus/pcc
/*
 * does the type t match tword
 */
int
ttype(TWORD t, int tword)
{
	if (tword & TANY)
		return(1);

#ifdef PCC_DEBUG
	if (t2debug)
		printf("ttype(0x%x, 0x%x)\n", t, tword);
#endif
	if (ISPTR(t) && ISFTN(DECREF(t)) && (tword & TFTN)) {
		/* For funny function pointers */
		return 1;
	}
	if (ISPTR(t) && (tword&TPTRTO)) {
		do {
			t = DECREF(t);
		} while (ISARY(t));
			/* arrays that are left are usually only
			 * in structure references...
			 */
		return (ttype(t, tword&(~TPTRTO)));
	}
	if (t != BTYPE(t))
		return (tword & TPOINT); /* TPOINT means not simple! */
	if (tword & TPTRTO)
		return(0);

	switch (t) {
	case CHAR:
		return( tword & TCHAR );
	case SHORT:
		return( tword & TSHORT );
	case STRTY:
	case UNIONTY:
		return( tword & TSTRUCT );
	case INT:
		return( tword & TINT );
	case UNSIGNED:
		return( tword & TUNSIGNED );
	case USHORT:
		return( tword & TUSHORT );
	case UCHAR:
		return( tword & TUCHAR );
	case ULONG:
		return( tword & TULONG );
	case LONG:
		return( tword & TLONG );
	case LONGLONG:
		return( tword & TLONGLONG );
	case ULONGLONG:
		return( tword & TULONGLONG );
	case FLOAT:
		return( tword & TFLOAT );
	case DOUBLE:
		return( tword & TDOUBLE );
	case LDOUBLE:
		return( tword & TLDOUBLE );
	}

	return(0);
}
コード例 #22
0
ファイル: local.c プロジェクト: arnoldrobbins/pcc-revived
/* clocal() is called to do local transformations on
 * an expression tree preparitory to its being
 * written out in intermediate code.
 *
 * the major essential job is rewriting the
 * automatic variables and arguments in terms of
 * REG and OREG nodes
 * conversion ops which are not necessary are also clobbered here
 * in addition, any special features (such as rewriting
 * exclusive or) are easily handled here as well
 */
NODE *
clocal(NODE *p)
{

	register struct symtab *q;
	register NODE *r, *l;
	register int o;
	TWORD t;

#ifdef PCC_DEBUG
	if (xdebug) {
		printf("clocal: %p\n", p);
		fwalk(p, eprint, 0);
	}
#endif
	switch( o = p->n_op ){

	case NAME:
		if ((q = p->n_sp) == NULL)
			return p; /* Nothing to care about */

		switch (q->sclass) {

		case PARAM:
		case AUTO:
			/* fake up a structure reference */
			r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
			slval(r, 0);
			r->n_rval = FPREG;
			p = stref(block(STREF, r, p, 0, 0, 0));
			break;

		case REGISTER:
			p->n_op = REG;
			slval(p, 0);
			p->n_rval = q->soffset;
			break;

		case USTATIC:
		case STATIC:
			if (kflag == 0)
				break;
			if (blevel > 0 && !statinit)
				p = picstatic(p);
			break;

		case EXTERN:
		case EXTDEF:
			if (kflag == 0)
				break;
			if (blevel > 0 && !statinit)
				p = picext(p);
			break;
		}
		break;

	case ADDROF:
		if (kflag == 0 || blevel == 0 || statinit)
			break;
		/* char arrays may end up here */
		l = p->n_left;
		if (l->n_op != NAME ||
		    (l->n_type != ARY+CHAR && l->n_type != ARY+WCHAR_TYPE))
			break;
		l = p;
		p = picstatic(p->n_left);
		nfree(l);
		if (p->n_op != UMUL)
			cerror("ADDROF error");
		l = p;
		p = p->n_left;
		nfree(l);
		break;

	case STASG: /* convert struct assignment to call memcpy */
		l = p->n_left;
		if (l->n_op == NAME && ISFTN(l->n_sp->stype))
			break; /* struct return, do nothing */
		/* first construct arg list */
		p->n_left = buildtree(ADDROF, p->n_left, 0);
		r = bcon(tsize(STRTY, p->n_df, p->n_ap)/SZCHAR);
		p->n_left = buildtree(CM, p->n_left, p->n_right);
		p->n_right = r;
		p->n_op = CM;
		p->n_type = INT;

		r = block(NAME, NIL, NIL, INT, 0, 0);
		r->n_sp = lookup(addname("memcpy"), SNORMAL);
		if (r->n_sp->sclass == SNULL) {
			r->n_sp->sclass = EXTERN;
			r->n_sp->stype = INCREF(VOID+PTR)+(FTN-PTR);
		}
		r->n_type = r->n_sp->stype;
		p = buildtree(CALL, r, p);
		break;

	case SCONV:
		l = p->n_left;
		if (l->n_op == ICON && ISPTR(l->n_type)) {
			/* Do immediate cast here */
			/* Should be common code */
			q = l->n_sp;
			l->n_sp = NULL;
			l->n_type = UNSIGNED;
			if (concast(l, p->n_type) == 0)
				cerror("clocal");
			p = nfree(p);
			p->n_sp = q;
		}
		break;

	case FORCE:
		/* put return value in return reg */
		p->n_op = ASSIGN;
		p->n_right = p->n_left;
		p->n_left = block(REG, NIL, NIL, p->n_type, 0, 0);
		t = p->n_type;
		if (ISITY(t))
			t = t - (FIMAG-FLOAT);
		p->n_left->n_rval = RETREG(t);
		break;
	}
#ifdef PCC_DEBUG
	if (xdebug) {
		printf("clocal end: %p\n", p);
		fwalk(p, eprint, 0);
	}
#endif
	return(p);
}
コード例 #23
0
ファイル: code.c プロジェクト: pauley/pcc
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	extern char *nextsect;
	static char *loctbl[] = { "text", "data", "section .rodata" };
	extern int tbss;
	int weak = 0;
	char *name;
	TWORD t;
	int s;

	if (sp == NULL) {
		lastloc = -1;
		return;
	}
	if (kflag) {
		loctbl[DATA] = "section .data.rel.rw,\"aw\",@progbits";
		loctbl[RDATA] = "section .data.rel.ro,\"aw\",@progbits";
	}
	t = sp->stype;
	s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
	if ((name = sp->soname) == NULL)
		name = exname(sp->sname);

	if (sp->sflags & STLS) {
		if (s != DATA)
			cerror("non-data symbol in tls section");
		if (tbss)
			nextsect = ".tbss,\"awT\",@nobits";
		else
			nextsect = ".tdata,\"awT\",@progbits";
		tbss = 0;
		lastloc = -1;
	}

#ifdef GCC_COMPAT
	{
		struct attr *ga;

		if ((ga = attr_find(sp->sap, GCC_ATYP_SECTION)) != NULL)
			nextsect = ga->sarg(0);
		if ((ga = attr_find(sp->sap, GCC_ATYP_WEAK)) != NULL)
			weak = 1;
		if (attr_find(sp->sap, GCC_ATYP_DESTRUCTOR)) {
			printf("\t.section\t.dtors,\"aw\",@progbits\n");
			printf("\t.align 8\n\t.quad\t%s\n", name);
			lastloc = -1;
		}
		if (attr_find(sp->sap, GCC_ATYP_CONSTRUCTOR)) {
			printf("\t.section\t.ctors,\"aw\",@progbits\n");
			printf("\t.align 8\n\t.quad\t%s\n", name);
			lastloc = -1;
		}
		if ((ga = attr_find(sp->sap, GCC_ATYP_VISIBILITY)) &&
		    strcmp(ga->sarg(0), "default"))
			printf("\t.%s %s\n", ga->sarg(0), name);
	}
#endif

	if (nextsect) {
		printf("	.section %s\n", nextsect);
		nextsect = NULL;
		s = -1;
	} else if (s != lastloc)
		printf("	.%s\n", loctbl[s]);
	lastloc = s;
	while (ISARY(t))
		t = DECREF(t);
	s = ISFTN(t) ? ALINT : talign(t, sp->sap);
	if (s > ALCHAR)
		printf("	.align %d\n", s/ALCHAR);
	if (weak)
		printf("        .weak %s\n", name);
	else if (sp->sclass == EXTDEF) {
		printf("\t.globl %s\n", name);
		printf("\t.type %s,@%s\n", name,
		    ISFTN(t)? "function" : "object");
	}
	if (sp->slevel == 0)
		printf("%s:\n", name);
	else
		printf(LABFMT ":\n", sp->soffset);
}
コード例 #24
0
ファイル: code.c プロジェクト: fhector/helenOS-0.5-Hector
/*
 * Define everything needed to print out some data (or text).
 * This means segment, alignment, visibility, etc.
 */
void
defloc(struct symtab *sp)
{
	extern char *nextsect;
	static char *loctbl[] = { "text", "data", "section .rodata" };
	extern int tbss;
	char *name;
	TWORD t;
	int s;

	if (sp == NULL) {
		lastloc = -1;
		return;
	}
	if (kflag) {
#ifdef MACHOABI
		loctbl[DATA] = "section .data.rel.rw,\"aw\"";
		loctbl[RDATA] = "section .data.rel.ro,\"aw\"";
#else
		loctbl[DATA] = "section .data.rel.rw,\"aw\",@progbits";
		loctbl[RDATA] = "section .data.rel.ro,\"aw\",@progbits";
#endif
	}
	t = sp->stype;
	s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
	if ((name = sp->soname) == NULL)
		name = exname(sp->sname);

	if (sp->sflags & STLS) {
		if (s != DATA)
			cerror("non-data symbol in tls section");
		if (tbss)
			nextsect = ".tbss,\"awT\",@nobits";
		else
			nextsect = ".tdata,\"awT\",@progbits";
		tbss = 0;
		lastloc = -1;
	}

	varattrib(name, sp->sap);

	if (nextsect) {
		printf("	.section %s\n", nextsect);
		nextsect = NULL;
		s = -1;
	} else if (s != lastloc)
		printf("	.%s\n", loctbl[s]);
	lastloc = s;
	while (ISARY(t))
		t = DECREF(t);
	s = ISFTN(t) ? ALINT : talign(t, sp->sap);
	if (s > ALCHAR)
		printf("	.align %d\n", s/ALCHAR);
	if (sp->sclass == EXTDEF) {
		printf("\t.globl %s\n", name);
#ifndef MACHOABI
		printf("\t.type %s,@%s\n", name,
		    ISFTN(t)? "function" : "object");
#endif
	}
	if (sp->slevel == 0)
		printf("%s:\n", name);
	else
		printf(LABFMT ":\n", sp->soffset);
}