/* branch to address constant or integer variable */ void putbranch(struct bigblock *q) { NODE *p; p = mkunode(GOTO, putex1(q), 0, INT); sendp2(p); }
/* put out code for goto l */ void putgoto(int label) { NODE *p; p = mkunode(GOTO, mklnode(ICON, label, 0, INT), 0, INT); sendp2(p); }
/* * Create a tree that can later be converted to an OREG. */ static NODE * oregtree(int off, int reg, int type) { NODE *p, *q; p = mklnode(REG, 0, reg, INCREF(type)); q = mklnode(ICON, off, 0, INT); return mkunode(UMUL, mkbinode(PLUS, p, q, INCREF(type)), 0, type); }
/* * Put return values into correct register. */ void putforce(int t, bigptr p) { NODE *p1; p = mkconv(t, fixtype(p)); p1 = putx(p); p1 = mkunode(FORCE, p1, 0, (t==TYSHORT ? SHORT : (t==TYLONG ? LONG : LDOUBLE))); sendp2(p1); }
static void fcheck(NODE *p, void *arg) { NODE *r, *l; switch (p->n_op) { case CALL: /* fix arguments */ for (r = p->n_right; r->n_op == CM; r = r->n_left) { r->n_right = mkunode(FUNARG, r->n_right, 0, r->n_right->n_type); } l = talloc(); *l = *r; r->n_op = FUNARG; r->n_left = l; r->n_type = l->n_type; break; } }
LOCAL NODE * putop(bigptr q) { NODE *p; int k; bigptr lp, tp; int pt, lt; #ifdef PCC_DEBUG if (tflag) { printf("putop %p\n", q); fprint(q, 0); } #endif switch(q->b_expr.opcode) { /* check for special cases and rewrite */ case OPCONV: pt = q->vtype; lp = q->b_expr.leftp; lt = lp->vtype; while(q->tag==TEXPR && q->b_expr.opcode==OPCONV && ((ISREAL(pt)&&ISREAL(lt)) || (XINT(pt)&&(ONEOF(lt,MSKINT|MSKADDR))) )) { if(lp->tag != TEXPR) { if(pt==TYINT && lt==TYLONG) break; if(lt==TYINT && pt==TYLONG) break; } ckfree(q); q = lp; pt = lt; lp = q->b_expr.leftp; lt = lp->vtype; } if(q->tag==TEXPR && q->b_expr.opcode==OPCONV) break; p = putx(q); return p; case OPADDR: lp = q->b_expr.leftp; if(lp->tag != TADDR) { tp = fmktemp(lp->vtype, lp->vleng); p = putx(mkexpr(OPASSIGN, cpexpr(tp), lp)); sendp2(p); lp = tp; } p = putaddr(lp, NO); ckfree(q); return p; } if ((k = ops2[q->b_expr.opcode]) <= 0) fatal1("putop: invalid opcode %d (%d)", q->b_expr.opcode, k); p = putx(q->b_expr.leftp); if(q->b_expr.rightp) p = mkbinode(k, p, putx(q->b_expr.rightp), types2[q->vtype]); else p = mkunode(k, p, 0, types2[q->vtype]); if(q->vleng) frexpr(q->vleng); ckfree(q); return p; }
static NODE * putaddr(bigptr q, int indir) { int type, type2, funct; NODE *p, *p1, *p2; ftnint offset; bigptr offp; p = p1 = p2 = NULL; /* XXX */ type = q->vtype; type2 = types2[type]; funct = (q->vclass==CLPROC ? FTN<<TSHIFT : 0); offp = (q->b_addr.memoffset ? cpexpr(q->b_addr.memoffset) : NULL); offset = simoffset(&offp); if(offp) offp = mkconv(TYINT, offp); switch(q->vstg) { case STGAUTO: if(indir && !offp) { p = oregtree(offset, AUTOREG, type2); break; } if(!indir && !offp && !offset) { p = mklnode(REG, 0, AUTOREG, INCREF(type2)); break; } p = mklnode(REG, 0, AUTOREG, INCREF(type2)); if(offp) { p1 = putx(offp); if(offset) p2 = mklnode(ICON, offset, 0, INT); } else p1 = mklnode(ICON, offset, 0, INT); if (offp && offset) p1 = mkbinode(PLUS, p1, p2, INCREF(type2)); p = mkbinode(PLUS, p, p1, INCREF(type2)); if (indir) p = mkunode(UMUL, p, 0, type2); break; case STGARG: p = oregtree(ARGOFFSET + (ftnint)(q->b_addr.memno), ARGREG, INCREF(type2)|funct); if (offp) p1 = putx(offp); if (offset) p2 = mklnode(ICON, offset, 0, INT); if (offp && offset) p1 = mkbinode(PLUS, p1, p2, INCREF(type2)); else if (offset) p1 = p2; if (offp || offset) p = mkbinode(PLUS, p, p1, INCREF(type2)); if (indir) p = mkunode(UMUL, p, 0, type2); break; case STGLENG: if(indir) { p = oregtree(ARGOFFSET + (ftnint)(q->b_addr.memno), ARGREG, INCREF(type2)|funct); } else { fatal1("faddrnode: STGLENG: fixme!"); #if 0 p2op(P2PLUS, types2[TYLENG] | P2PTR ); p2reg(ARGREG, types2[TYLENG] | P2PTR ); p2icon( ARGOFFSET + (ftnint) (FUDGEOFFSET*p->b_addr.memno), P2INT); #endif } break; case STGBSS: case STGINIT: case STGEXT: case STGCOMMON: case STGEQUIV: case STGCONST: if(offp) { p1 = putx(offp); p2 = putmem(q, ICON, offset); p = mkbinode(PLUS, p1, p2, INCREF(type2)); if(indir) p = mkunode(UMUL, p, 0, type2); } else p = putmem(q, (indir ? NAME : ICON), offset); break; case STGREG: if(indir) p = mklnode(REG, 0, q->b_addr.memno, type2); else fatal("attempt to take address of a register"); break; default: fatal1("putaddr: invalid vstg %d", q->vstg); } frexpr(q); return p; }