Exemplo n.º 1
0
static struct symtab *
addstr(char *n)
{
	NODE *p = block(NAME, NIL, NIL, FLOAT, 0, 0);
	struct symtab *sp;
	NODE *q;
	struct attr *ap;
	struct rstack *rp;
	extern struct rstack *rpole;

	p->n_type = ctype(ULONGLONG);
	rpole = rp = bstruct(NULL, STNAME, NULL);
	soumemb(p, loti, 0);
	soumemb(p, hiti, 0);
	q = dclstruct(rp);
	sp = q->n_sp = lookup(addname(n), 0);
	defid(q, TYPEDEF);
	ap = attr_new(GCC_ATYP_MODE, 3);
	ap->sarg(0) = addname("TI");
	ap->iarg(1) = 0;
	sp->sap = attr_add(sp->sap, ap);
	nfree(q);
	nfree(p);

	return sp;
}
Exemplo n.º 2
0
/*
 * The "initial exec" tls model.
 */
static NODE *
tlsinitialexec(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * movq %fs:0,%rax
	 * addq x@GOTTPOFF(%rip),%rax
	 */

	q = bcon(0);
	q->n_type = STRTY;

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=r", r);
	r = block(XASM, r, q, INT, 0, 0);

	s1 = "movq %%fs:0,%0\n\taddq ";
	s2 = "@GOTTPOFF(%%rip),%0";
	if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) {
		p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1));
		p->n_sp->sap->sarg(0) = p->n_sp->sname;
	}
	r->n_name = mk3str(s1,
	    attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2);

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
Exemplo n.º 3
0
/*
 * Declare a namespace.
 */
void
dclns(NODE *attr, char *n)
{
	struct symtab *sp;
	struct attr *ap = gcc_attr_parse(attr);

	if (cppdebug)printf("declaring namespace %s\n", n);
	n = addname(n);

	sp = sfind(n, nscur->sup);
	while (sp != NULL) {
		if (sp->sname == n && sp->sclass == NSPACE)
			break;
		sp = sfind(n, sp->snext);
	}
	if (sp == NULL) {
		/* New namespace */
		sp = getsymtab(n, 0);
		sp->sclass = NSPACE;
		INSSYM(sp);
	}
	nscur = sp;
	if (cppdebug)printf("declaring namespace2 %s\n", nscur->sname);
	sp->sap = attr_add(sp->sap, ap); /* XXX check attributes */
}
Exemplo n.º 4
0
void
myp2tree(NODE *p)
{
	struct attr *ap;
	struct symtab *sp, sps;
	static int dblxor, fltxor;
	int codeatyp(NODE *);

	if (p->n_op == STCALL || p->n_op == USTCALL) {
		/* save struct encoding */
		p->n_ap = attr_add(p->n_ap,
		    ap = attr_new(ATTR_AMD64_CMPLRET, 1));
		ap->iarg(0) = codeatyp(p);
	}

	if (p->n_op == UMINUS && (p->n_type == FLOAT || p->n_type == DOUBLE)) {
		/* Store xor code for sign change */
		if (dblxor == 0) {
			dblxor = getlab();
			fltxor = getlab();
			sps.stype = LDOUBLE;
			sps.squal = CON >> TSHIFT;
			sps.sflags = sps.sclass = 0;
			sps.sname = "";
			sps.slevel = 1;
			sps.sap = NULL;
			sps.soffset = dblxor;
			locctr(DATA, &sps);
			defloc(&sps);
			printf("\t.long 0,0x80000000,0,0\n");
			printf(LABFMT ":\n", fltxor);
			printf("\t.long 0x80000000,0,0,0\n");
		}
		p->n_ap = attr_add(p->n_ap,
		    ap = attr_new(ATTR_AMD64_XORLBL, 1));
		ap->iarg(0) = p->n_type == FLOAT ? fltxor : dblxor;
		return;
	}
Exemplo n.º 5
0
/*
 * Check if we may have to do a cast to/from TI.
 */
NODE *
gcc_eval_ticast(int op, NODE *p1, NODE *p2)
{
	struct attr *a1, *a2;
	int t;

	a2 = NULL; /* XXX flow analysis */
	if ((a1 = isti(p1)) == NULL && (a2 = isti(p2)) == NULL)
		return NIL;

	if (op == RETURN)
		p1 = p1tcopy(p1);
	if (a1 == NULL) {
		if (a2 == NULL)
			cerror("gcc_eval_ticast error");
		switch (p1->n_type) {
		case LDOUBLE:
			p2 = doacall(floatuntixfsp,
			    nametree(floatuntixfsp), p2);
			tfree(p1);
			break;
		case ULONG:
		case LONG:
			p2 = cast(structref(p2, DOT, loti), p1->n_type, 0);
			tfree(p1);
			break;
		case VOID:
			return NIL;
		default:
			uerror("gcc_eval_ticast: %d", p1->n_type);
		}
		return p2;
	}
	/* p2 can be anything, but we must cast it to p1 */
	t = a1->iarg(1);

	if (p2->n_type == STRTY &&
	    (a2 = attr_find(p2->n_ap, GCC_ATYP_MODE)) &&
	    strcmp(a2->sarg(0), TISTR) == 0) {
		/* Already TI, just add extra mode bits */
		a2 = attr_new(GCC_ATYP_MODE, 3);
		a2->sarg(0) = TISTR;
		a2->iarg(1) = t;
		p2->n_ap = attr_add(p2->n_ap, a2);
	} else  {
		p2 = ticast(p2, t);
	}
	tfree(p1);
	return p2;
}
Exemplo n.º 6
0
/*
 * Called when a identifier has been declared.
 */
void
fixdef(struct symtab *sp)
{
	struct attr *ga;

#ifdef HAVE_WEAKREF
	/* not many as'es have this directive */
	if ((ga = attr_find(sp->sap, GCC_ATYP_WEAKREF)) != NULL) {
		char *wr = ga->sarg(0);
		char *sn = getsoname(sp);
		if (wr == NULL) {
			if ((ga = attr_find(sp->sap, GCC_ATYP_ALIAS))) {
				wr = ga->sarg(0);
			}
		}
		if (wr == NULL)
			printf("\t.weak %s\n", sn);
		else
			printf("\t.weakref %s,%s\n", sn, wr);
	} else
	       if ((ga = attr_find(sp->sap, GCC_ATYP_ALIAS)) != NULL) {
		char *an = ga->sarg(0);
		char *sn = getsoname(sp);
		char *v;

		v = attr_find(sp->sap, GCC_ATYP_WEAK) ? "weak" : "globl";
		printf("\t.%s %s\n", v, sn);
		printf("\t.set %s,%s\n", sn, an);
	}
	if (alias != NULL && (sp->sclass != PARAM)) {
		char *name = getexname(sp);
		printf("\t.globl %s\n", name);
		printf("%s = ", name);
		printf("%s\n", exname(alias));
		alias = NULL;
	}
	if ((constructor || destructor) && (sp->sclass != PARAM)) {
		NODE *p = p1alloc();

		p->n_op = NAME;
		p->n_sp =
		  (struct symtab *)(constructor ? "constructor" : "destructor");
		sp->sap = attr_add(sp->sap, gcc_attr_parse(p));
		constructor = destructor = 0;
	}
#endif
}
Exemplo n.º 7
0
/*
 * Create a reference for a TLS variable.
 * This is the "General dynamic" version.
 */
static NODE *
tlspic(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * .byte   0x66
	 * leaq x@TLSGD(%rip),%rdi
	 * .word   0x6666
	 * rex64
	 * call __tls_get_addr@PLT
	 */

	/* Need the .byte stuff around.  Why? */
	/* Use inline assembler */
	q = mkx("%rdx", bcon(0));
	q = cmop(q, mkx("%rcx", bcon(0)));
	q = cmop(q, mkx("%rsi", bcon(0)));
	q = cmop(q, mkx("%rdi", bcon(0)));
	q = cmop(q, mkx("%r8", bcon(0)));
	q = cmop(q, mkx("%r9", bcon(0)));
	q = cmop(q, mkx("%r10", bcon(0)));
	q = cmop(q, mkx("%r11", bcon(0)));

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=a", r);
	r = block(XASM, r, q, INT, 0, 0);

	/* Create the magic string */
	s1 = ".byte 0x66\n\tleaq ";
	s2 = "@TLSGD(%%rip),%%rdi\n"
	    "\t.word 0x6666\n\trex64\n\tcall __tls_get_addr@PLT";
	if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) {
		p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1));
		p->n_sp->sap->sarg(0) = p->n_sp->sname;
	}
	r->n_name = addstring(mk3str(s1,
	    attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2));

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
Exemplo n.º 8
0
/*
 * Extract attributes from a node tree and return attribute entries 
 * based on its contents.
 */
struct attr *
gcc_attr_parse(NODE *p)
{
	struct attr *b, *c;

	if (p == NIL)
		return NULL;

	if (p->n_op != CM) {
		b = gcc_attribs(p);
		tfree(p);
	} else {
		b = gcc_attr_parse(p->n_left);
		c = gcc_attr_parse(p->n_right);
		nfree(p);
		b = b ? attr_add(b, c) : c;
	}
	return b;
}
Exemplo n.º 9
0
SLPError generic_set_val(struct xx_SLPAttributes *slp_attr, const char *tag, value_t *value, SLPInsertionPolicy policy, SLPType attr_type) 
/* Finds and sets the value named in tag.                                    */
/* 
 * slp_attr  - The attr object to add to.
 * tag       - the name of the tag to add to.
 * value     - the already-allocated value object with fields set
 * policy    - the policy to use when inserting.
 * attr_type - the type of the value being added.
 *****************************************************************************/
{
	var_t *var;
	/***** Create a new attribute. *****/	
	if ( (var = attr_val_find_str(slp_attr, tag)) == NULL) {	
		/*** Couldn't find a value with this tag. Make a new one. ***/	
		var = var_new((char *)tag);	
		if (var == NULL) {	
			return SLP_MEMORY_ALLOC_FAILED;	
		}	
		var->type = attr_type;	
		/** Add variable to list. **/	
		attr_add(slp_attr, var);	
	} else {
		SLPError err;
		/*** The attribute already exists. ***/ 
		/*** Verify type. ***/	
		err = attr_type_verify(slp_attr, var, attr_type);	
		if (err == SLP_TYPE_ERROR && policy == SLP_REPLACE) { 
			var_list_destroy(var); 
			var->type = attr_type; 
		} 
		else if (err != SLP_OK) {	
			value_free(value); 
			return err;	
		}	
	}	
	/***** Set value *****/	
	var_insert(var, value, policy); 

	return SLP_OK;
}
Exemplo n.º 10
0
/*
 * Create a reference for an extern variable.
 */
static P1ND *
picext(P1ND *p)
{
	struct attr *ap;

#if defined(ELFABI)
	P1ND *q, *r;
	struct symtab *sp;
	char *name;

	q = tempnode(gotnr, PTR|VOID, 0, 0);
	name = getexname(p->n_sp);

#ifdef GCC_COMPAT
	if ((ap = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) &&
	    strcmp(ap->sarg(0), "hidden") == 0) {
		/* For hidden vars use GOTOFF */
		sp = picsymtab("", name, "@GOTOFF");
		r = xbcon(0, sp, INT);
		q = buildtree(PLUS, q, r);
		q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
		q->n_sp = p->n_sp; /* for init */
		p1nfree(p);
		return q;
	}
#endif

	sp = picsymtab("", name, "@GOT");
#ifdef GCC_COMPAT
	if (attr_find(p->n_sp->sap, GCC_ATYP_STDCALL) != NULL)
		p->n_sp->sflags |= SSTDCALL;
#endif
	sp->sflags = p->n_sp->sflags & SSTDCALL;
	sp->sap = attr_add(p->n_sp->sap, sp->sap);
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);
	q = block(UMUL, q, 0, PTR|VOID, 0, 0);
	q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
	q->n_sp = p->n_sp; /* for init */
	p1nfree(p);
	return q;

#elif defined(MACHOABI)

	P1ND *q, *r;
	struct symtab *sp;
	char buf2[256], *name, *pspn;

	name = getsoname(cftnsp);
	pspn = getexname(p->n_sp);

	if (p->n_sp->sclass == EXTDEF) {
		snprintf(buf2, 256, "-L%s$pb", name);
		sp = picsymtab("", pspn, buf2);
	} else {
		snprintf(buf2, 256, "$non_lazy_ptr-L%s$pb", name);
		sp = picsymtab("L", pspn, buf2);
		addstub(&nlplist, pspn);
	}

	sp->stype = p->n_sp->stype;

	q = tempnode(gotnr, PTR+VOID, 0, 0);
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);

	if (p->n_sp->sclass != EXTDEF)
		q = block(UMUL, q, 0, PTR+VOID, 0, 0);
	q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
	q->n_sp = p->n_sp; /* for init */
	p1nfree(p);
	return q;

#else /* defined(PECOFFABI) || defined(AOUTABI) */

	return p;

#endif

}
Exemplo n.º 11
0
/*
 * Parse attributes from an argument list.
 */
static void
gcc_attribs(NODE *p, void *arg)
{
    NODE *q, *r;
    struct attr *apo = arg, *ap;
    char *name = NULL, *c;
    int cw, attr, narg, i;

    if (p->n_op == NAME) {
        name = (char *)p->n_sp;
    } else if (p->n_op == CALL || p->n_op == UCALL) {
        name = (char *)p->n_left->n_sp;
    } else
        cerror("bad variable attribute");

    if ((attr = amatch(name, atax, GCC_ATYP_MAX)) == 0) {
        werror("unsupported attribute '%s'", name);
        goto out;
    }
    narg = 0;
    if (p->n_op == CALL)
        for (narg = 1, q = p->n_right; q->n_op == CM; q = q->n_left)
            narg++;

    cw = atax[attr].typ;
    if (!(cw & A_MANY) && ((narg > 3) || ((cw & (1 << narg)) == 0))) {
        uerror("wrong attribute arg count");
        return;
    }
    ap = attr_new(attr, 3); /* XXX should be narg */
    apo->next = attr_add(apo->next, ap);
    q = p->n_right;

    switch (narg) {
    default:
        /* XXX */
        while (narg-- > 3) {
            r = q;
            q = q->n_left;
            tfree(r->n_right);
            nfree(r);
        }
    /* FALLTHROUGH */
    case 3:
        setaarg(cw & (A3_NAME|A3_STR), &ap->aa[2], q->n_right);
        r = q;
        q = q->n_left;
        nfree(r);
    /* FALLTHROUGH */
    case 2:
        setaarg(cw & (A2_NAME|A2_STR), &ap->aa[1], q->n_right);
        r = q;
        q = q->n_left;
        nfree(r);
    /* FALLTHROUGH */
    case 1:
        setaarg(cw & (A1_NAME|A1_STR), &ap->aa[0], q);
        p->n_op = UCALL;
    /* FALLTHROUGH */
    case 0:
        break;
    }

    /* some attributes must be massaged special */
    switch (attr) {
    case GCC_ATYP_ALIGNED:
        if (narg == 0)
            ap->aa[0].iarg = ALMAX;
        else
            ap->aa[0].iarg *= SZCHAR;
        break;
    case GCC_ATYP_PACKED:
        if (narg == 0)
            ap->aa[0].iarg = 1; /* bitwise align */
        else
            ap->aa[0].iarg *= SZCHAR;
        break;

    case GCC_ATYP_MODE:
        if ((i = amatch(ap->aa[0].sarg, mods, ATSZ)) == 0)
            werror("unknown mode arg %s", ap->aa[0].sarg);
        ap->aa[0].iarg = mods[i].typ;
        break;

    case GCC_ATYP_VISIBILITY:
        c = ap->aa[0].sarg;
        if (strcmp(c, "default") && strcmp(c, "hidden") &&
                strcmp(c, "internal") && strcmp(c, "protected"))
            werror("unknown visibility %s", c);
        break;

    case GCC_ATYP_TLSMODEL:
        c = ap->aa[0].sarg;
        if (strcmp(c, "global-dynamic") && strcmp(c, "local-dynamic") &&
                strcmp(c, "initial-exec") && strcmp(c, "local-exec"))
            werror("unknown tls model %s", c);
        break;

    default:
        break;
    }
out:
    ;
}
Exemplo n.º 12
0
/*
 * Fixup types when modes given in defid().
 */
void
gcc_modefix(NODE *p)
{
	struct attr *ap;
#ifdef TARGET_TIMODE
	struct attr *a2;
#endif
	struct symtab *sp;
	char *s;
	int i, u;

	if ((ap = attr_find(p->n_ap, GCC_ATYP_MODE)) == NULL)
		return;

	u = ISUNSIGNED(BTYPE(p->n_type));
	if ((i = amatch(ap->aa[0].sarg, mods, ATSZ)) == 0) {
		werror("unknown mode arg %s", ap->aa[0].sarg);
		return;
	}
	i = mods[i].typ;
	if (i >= 1 && i <= MAXTYPES) {
		MODTYPE(p->n_type, ctype(i));
		if (u)
			p->n_type = ENUNSIGN(p->n_type);
	} else switch (i) {
#ifdef TARGET_TIMODE
	case 800:
		if (BTYPE(p->n_type) == STRTY)
			break;
		MODTYPE(p->n_type, tisp->stype);
		p->n_df = tisp->sdf;
		p->n_ap = tisp->sap;
		if (ap->iarg(1) == u)
			break;
		/* must add a new mode struct to avoid overwriting */
		a2 = attr_new(GCC_ATYP_MODE, 3);
		a2->sarg(0) = ap->sarg(0);
		a2->iarg(1) = u;
		p->n_ap = attr_add(p->n_ap, a2);
		break;
#endif
	case FCOMPLEX:
	case COMPLEX:
	case LCOMPLEX:
		/* Destination should have been converted to a struct already */
		if (BTYPE(p->n_type) != STRTY)
			uerror("gcc_modefix: complex not STRTY");
		i -= (FCOMPLEX-FLOAT);
		ap = strattr(p->n_ap);
		sp = ap->amlist;
		if (sp->stype == (unsigned)i)
			return; /* Already correct type */
		/* we must change to another struct */
		s = i == FLOAT ? "0f" :
		    i == DOUBLE ? "0d" :
		    i == LDOUBLE ? "0l" : 0;
		sp = lookup(addname(s), 0);
		for (ap = sp->sap; ap != NULL; ap = ap->next)
			p->n_ap = attr_add(p->n_ap, attr_dup(ap));
		break;

	default:
		cerror("gcc_modefix");
	}
}
Exemplo n.º 13
0
void
gcc_init(void)
{
	struct kw *kwp;
	NODE *p;
	TWORD t;
	int i, d_debug;

	d_debug = ddebug;
	ddebug = 0;
	for (kwp = kw; kwp->name; kwp++)
		kwp->ptr = addname(kwp->name);

	for (i = 0; i < 4; i++) {
		struct symtab *sp;
		t = ctype(g77t[i]);
		p = block(NAME, NIL, NIL, t, NULL, 0);
		sp = lookup(addname(g77n[i]), 0);
		p->n_sp = sp;
		defid(p, TYPEDEF);
		nfree(p);
	}
	ddebug = d_debug;
#ifdef TARGET_TIMODE
	{
		struct attr *ap;

		loti = addname("__loti");
		hiti = addname("__hiti");
		TISTR = addname("TI");

		tisp = addstr("0ti");

		cmpti2sp = addftn("__cmpti2", INT);
		ucmpti2sp = addftn("__ucmpti2", INT);

		addvti3sp = addftn("__addvti3", STRTY);
		addvti3sp->sap = tisp->sap;
		subvti3sp = addftn("__subvti3", STRTY);
		subvti3sp->sap = tisp->sap;
		mulvti3sp = addftn("__mulvti3", STRTY);
		mulvti3sp->sap = tisp->sap;
		divti3sp = addftn("__divti3", STRTY);
		divti3sp->sap = tisp->sap;
		modti3sp = addftn("__modti3", STRTY);
		modti3sp->sap = tisp->sap;

		ap = attr_new(GCC_ATYP_MODE, 3);
		ap->sarg(0) = TISTR;
		ap->iarg(1) = 1;
		ap = attr_add(tisp->sap, ap);
		udivti3sp = addftn("__udivti3", STRTY);
		udivti3sp->sap = ap;
		umodti3sp = addftn("__umodti3", STRTY);
		umodti3sp->sap = ap;
		ashldi3sp = addftn("__ashldi3", ctype(LONGLONG));
		ashldi3sp->sap = ap;
		ashrdi3sp = addftn("__ashrdi3", ctype(LONGLONG));
		ashrdi3sp->sap = ap;
		lshrdi3sp = addftn("__lshrdi3", ctype(LONGLONG));
		lshrdi3sp->sap = ap;

		floatuntixfsp = addftn("__floatuntixf", LDOUBLE);
	}
#endif
}