void myp2tree(NODE *p) { struct symtab *sp, sps; static int dblxor, fltxor; 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.soname = ""; 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_label = p->n_type == FLOAT ? fltxor : dblxor; return; }
void myp2tree(NODE *p) { struct symtab *sp; if (p->n_op != FCON) return; /* Write float constants to memory */ sp = IALLOC(sizeof(struct symtab)); sp->sclass = STATIC; sp->sap = 0; sp->slevel = 1; /* fake numeric label */ sp->soffset = getlab(); sp->sflags = 0; sp->stype = p->n_type; sp->squal = (CON >> TSHIFT); defloc(sp); ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p); p->n_op = NAME; p->n_lval = 0; p->n_sp = sp; }
void myp2tree(NODE *p) { struct symtab *sp; int o = p->n_op; if (o != FCON) return; sp = inlalloc(sizeof(struct symtab)); sp->sclass = STATIC; sp->ssue = 0; sp->slevel = 1; /* fake numeric label */ sp->soffset = getlab(); sp->sflags = 0; sp->stype = p->n_type; sp->squal = (CON >> TSHIFT); defloc(sp); ninval(0, sp->ssue->suesize, p); p->n_op = NAME; p->n_lval = 0; p->n_sp = sp; }
efcode(){ /* code for the end of a function */ if( strftn ){ /* copy output (in r0) to caller */ register struct symtab *p; register int stlab; register int count; int size; p = &stab[curftn]; deflab( retlab ); stlab = getlab(); printf( " mov $L%d,r1\n", stlab ); size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR; count = size/2; while( count-- ) { printf( " mov (r0)+,(r1)+\n" ); } printf( " mov $L%d,r0\n", stlab ); printf( " .bss\nL%d: .=.+%d.\n .text\n", stlab, size ); /* turn off strftn flag, so return sequence will be generated */ strftn = 0; } branch( retlab ); p2bend(); }
/* * Find number of beginning 0's in a word of type t. * t should be deunsigned. */ static NODE * builtin_ff(NODE *f, NODE *a, TWORD t) { NODE *t101, *t102; NODE *rn, *p; int l15, l16, l17; int sz; tfree(f); t = ctype(t); sz = (int)tsize(t, 0, 0)+1; t101 = tempnode(0, INT, 0, 0); t102 = tempnode(0, t, 0, 0); l15 = getlab(); l16 = getlab(); l17 = getlab(); rn = buildtree(ASSIGN, ccopy(t101), bcon(0)); rn = cmop(rn, buildtree(ASSIGN, ccopy(t102), a)); p = buildtree(CBRANCH, buildtree(EQ, ccopy(t102), bcon(0)), bcon(l15)); rn = cmop(rn, p); rn = cmop(rn, buildtree(INCR, ccopy(t101), bcon(1))); rn = cmop(rn, lblnod(l16)); p = buildtree(CBRANCH, buildtree(GE, ccopy(t101), bcon(sz)), bcon(l15)); rn = cmop(rn, p); p = buildtree(CBRANCH, buildtree(EQ, buildtree(AND, ccopy(t102), bcon(1)), bcon(0)), bcon(l17)); rn = cmop(rn, p); rn = cmop(rn, block(GOTO, bcon(l15), NIL, INT, 0, 0)); rn = cmop(rn, lblnod(l17)); rn = cmop(rn, buildtree(RSEQ, t102, bcon(1))); rn = cmop(rn, buildtree(INCR, ccopy(t101), bcon(1))); rn = cmop(rn, block(GOTO, bcon(l16), NIL, INT, 0, 0)); rn = cmop(rn, lblnod(l15)); return cmop(rn, t101); }
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; }
void myp2tree(NODE *p) { struct symtab *sp; NODE *l, *r; int o = p->n_op; switch (o) { case NAME: /* reading from a name must be done with a subroutine */ if (p->n_type != CHAR && p->n_type != UCHAR) break; l = buildtree(ADDROF, ccopy(p), NIL); r = block(NAME, NIL, NIL, INT, 0, 0); r->n_sp = lookup(addname("__nova_rbyte"), SNORMAL); if (r->n_sp->sclass == SNULL) { r->n_sp->sclass = EXTERN; r->n_sp->stype = INCREF(p->n_type)+(FTN-PTR); } r->n_type = r->n_sp->stype; r = clocal(r); r = optim(buildtree(CALL, r, l)); *p = *r; nfree(r); break; case FCON: sp = tmpalloc(sizeof(struct symtab)); sp->sclass = STATIC; sp->sap = 0; sp->slevel = 1; /* fake numeric label */ sp->soffset = getlab(); sp->sflags = 0; sp->stype = p->n_type; sp->squal = (CON >> TSHIFT); defloc(sp); ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p); p->n_op = NAME; p->n_lval = 0; p->n_sp = sp; } }
static char * tistack(void) { struct symtab *sp, *sp2; char buf[12]; NODE *q; char *n; /* allocate space on stack */ snprintf(buf, 12, "%d", getlab()); n = addname(buf); sp = lookup(n, 0); sp2 = tisp; q = block(TYPE, NIL, NIL, sp2->stype, sp2->sdf, sp2->sap); q->n_sp = sp; nidcl2(q, AUTO, 0); nfree(q); return n; }
void myp2tree(NODE *p) { struct symtab *sp; NODE *l; if (cdope(p->n_op) & CALLFLG) { if (p->n_left->n_op == ADDROF && p->n_left->n_left->n_op == NAME) { p->n_left = nfree(p->n_left); l = p->n_left; l->n_op = ICON; if (l->n_sp->sclass != STATIC && l->n_sp->sclass != USTATIC) l->n_sp = picsymtab(l->n_sp->sname, "@PLTPC", ""); } } if (p->n_op != FCON) return; sp = IALLOC(sizeof(struct symtab)); sp->sclass = STATIC; sp->sap = 0; sp->slevel = 1; /* fake numeric label */ sp->soffset = getlab(); sp->sflags = 0; sp->stype = p->n_type; sp->squal = (CON >> TSHIFT); sp->sname = NULL; locctr(DATA, sp); defloc(sp); ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p); p->n_op = NAME; slval(p, 0); p->n_sp = sp; }
walkheap(int start, int limit) { int label; if( start > limit ) return; printf(" cmpl r0,$%d\n", heapsw[start].sval); printf(" jeql " LBLFMT "\n", heapsw[start].slab); if( (2*start) > limit ) { printf(" jbr " LBLFMT "\n", heapsw[0].slab); return; } if( (2*start+1) <= limit ) { label = getlab(); printf(" jgtr " LBLFMT "\n", label); } else printf(" jgtr " LBLFMT "\n", heapsw[0].slab); walkheap( 2*start, limit); if( (2*start+1) <= limit ) { deflab1(label); walkheap( 2*start+1, limit); } }
/* * special handling before tree is written out. */ void myp2tree(NODE *p) { struct symtab *sp; union dimfun *df; union arglist *al; NODE *q; int i; switch (p->n_op) { case MOD: case DIV: if (p->n_type == LONG || p->n_type == ULONG) { /* Swap arguments for hardops() later */ q = p->n_left; p->n_left = p->n_right; p->n_right = q; } break; case CALL: case STCALL: /* * inform pass2 about varargs. * store first variadic argument number in n_stalign * in the CM node. */ if (p->n_right->n_op != CM) break; /* nothing to care about */ df = p->n_left->n_df; if (df && (al = df->dfun)) { for (i = 0; i < 6; i++, al++) { if (al->type == TELLIPSIS || al->type == TNULL) break; } p->n_right->n_stalign = al->type == TELLIPSIS ? i : 0; } else p->n_right->n_stalign = 0; break; case FCON: /* Write float constants to memory */ sp = inlalloc(sizeof(struct symtab)); sp->sclass = STATIC; sp->ssue = 0; sp->slevel = 1; /* fake numeric label */ sp->soffset = getlab(); sp->sflags = 0; sp->stype = p->n_type; sp->squal = (CON >> TSHIFT); defloc(sp); ninval(0, sp->ssue->suesize, p); p->n_op = NAME; p->n_lval = 0; p->n_sp = sp; break; } }
genswitch(register struct sw *p, int n) { /* p points to an array of structures, each consisting of a constant value and a label. The first is >=0 if there is a default label; its value is the label number The entries p[1] to p[n] are the nontrivial cases */ register i; register CONSZ j, range; register dlab, swlab; range = p[n].sval-p[1].sval; if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */ swlab = getlab(); dlab = p->slab >= 0 ? p->slab : getlab(); /* already in r0 */ printf(" casel r0,$%ld,$%ld\n", p[1].sval, range); deflab1(swlab); for( i=1,j=p[1].sval; i<=n; j++) { printf(" .word " LABFMT "-" LABFMT "\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab), swlab); } if( p->slab >= 0 ) branch( dlab ); else deflab1(dlab); return; } if( n>8 ) { /* heap switch */ heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab(); makeheap(p, n, 1); /* build heap */ walkheap(1, n); /* produce code */ if( p->slab >= 0 ) branch( dlab ); else deflab1(dlab); return; } /* debugging code */ /* out for the moment if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) ); */ /* simple switch code */ for( i=1; i<=n; ++i ){ /* already in r0 */ printf( " cmpl r0,$" ); printf( CONFMT, p[i].sval ); printf( "\n jeql " LBLFMT "\n", p[i].slab ); } if( p->slab>=0 ) branch( p->slab ); }