void put_code(OCODE *cd) /* * outputFile a generic instruction. */ { int op = cd->opcode,len=0,len2=0; AMODE *aps = cd->oper1,*apd = cd->oper2, *ap3 = cd->oper3; if (!prm_asmfile) return; if (op == op_line) { if (!prm_lines) return; fprintf(outputFile,";\n; Line %d:\t%s\n;\n",(int)apd,(char *)aps); return; } if (aps) len = aps->length; if (apd) len2 = apd->length; needpointer = (len != len2) || ((!aps || aps->mode !=am_dreg) && (!apd || apd->mode !=am_dreg)); putop(op); if (prm_nasm && op >=op_ja && op <= op_jns) fprintf(outputFile,"\tNEAR"); switch (op) { case op_rep: case op_repz: case op_repe: case op_repnz: case op_repne: case op_lock: return; } putlen(len); if( aps != 0 ) { fprintf(outputFile,"\t"); if (op == op_dd) nosize = TRUE; putamode(aps); nosize = FALSE; if( apd != 0 ) { fprintf(outputFile,","); putamode(apd); } if( ap3 != 0 ) { fprintf(outputFile,","); putamode(ap3); } } fprintf(outputFile,"\n"); }
/* * Compare character(s) code. */ LOCAL NODE * putchcmp(struct bigblock *p) { NODE *p1, *p2, *p3; if(ISONE(p->b_expr.leftp->vleng) && ISONE(p->b_expr.rightp->vleng) ) { p1 = putaddr( putch1(p->b_expr.leftp) , YES ); p2 = putaddr( putch1(p->b_expr.rightp) , YES ); p3 = mkbinode(ops2[p->b_expr.opcode], p1, p2, CHAR); ckfree(p); } else { p->b_expr.leftp = call2(TYINT,"s_cmp", p->b_expr.leftp, p->b_expr.rightp); p->b_expr.rightp = MKICON(0); p3 = putop(p); } return p3; }
/* * output a generic instruction. */ PRIVATE void put_code P1 (const CODE *, ip) { putop (ip->opcode); putlen (ip->length); if (ip->oper1 != NIL_ADDRESS) { oprintf ("\t"); putamode (ip->oper1, ip->length); if (ip->oper2 != NIL_ADDRESS) { if (ip->opcode == op_line) { oprintf ("%s%s>>>>\t", newline, comment); } else { oprintf (","); } putamode (ip->oper2, ip->length); } } oprintf ("%s", newline); }
/* * output a generic instruction. */ void put_code(int op, int len,AMODE *aps,AMODE *apd,AMODE *ap3) { if( op == op_dc ) { switch( len ) { case 1: fprintf(output,"\tdb"); break; case 2: fprintf(output,"\tdh"); break; case 4: fprintf(output,"\tdw"); break; } } else { putop(op); } if( aps != 0 ) { fprintf(output,"\t"); PutAddressMode(aps); if( apd != 0 ) { fprintf(output,","); PutAddressMode(apd); if (ap3 != NULL) { fprintf(output,","); PutAddressMode(ap3); } } } fprintf(output,"\n"); }
/* * Convert a f77 tree statement to something that looks like a * pcc expression tree. */ NODE * putx(bigptr q) { struct bigblock *x1; NODE *p = NULL; /* XXX */ int opc; int type, k; #ifdef PCC_DEBUG if (tflag) { printf("putx %p\n", q); fprint(q, 0); } #endif switch(q->tag) { case TERROR: ckfree(q); break; case TCONST: switch(type = q->vtype) { case TYLOGICAL: type = tyint; case TYLONG: case TYSHORT: p = mklnode(ICON, q->b_const.fconst.ci, 0, types2[type]); ckfree(q); break; case TYADDR: p = mklnode(ICON, 0, 0, types2[type]); p->n_name = copys(memname(STGCONST, (int)q->b_const.fconst.ci)); ckfree(q); break; default: p = putx(putconst(q)); break; } break; case TEXPR: switch(opc = q->b_expr.opcode) { case OPCALL: case OPCCALL: if( ISCOMPLEX(q->vtype) ) p = putcxop(q); else { putcall(q); p = callval; } break; case OPMIN: case OPMAX: p = putmnmx(q); break; case OPASSIGN: if (ISCOMPLEX(q->b_expr.leftp->vtype) || ISCOMPLEX(q->b_expr.rightp->vtype)) { frexpr(putcxeq(q)); } else if (ISCHAR(q)) p = putcheq(q); else goto putopp; break; case OPEQ: case OPNE: if (ISCOMPLEX(q->b_expr.leftp->vtype) || ISCOMPLEX(q->b_expr.rightp->vtype) ) { p = putcxcmp(q); break; } case OPLT: case OPLE: case OPGT: case OPGE: if(ISCHAR(q->b_expr.leftp)) p = putchcmp(q); else goto putopp; break; case OPPOWER: p = putpower(q); break; case OPSTAR: /* m * (2**k) -> m<<k */ if (XINT(q->b_expr.leftp->vtype) && ISICON(q->b_expr.rightp) && ((k = flog2(q->b_expr.rightp->b_const.fconst.ci))>0) ) { q->b_expr.opcode = OPLSHIFT; frexpr(q->b_expr.rightp); q->b_expr.rightp = MKICON(k); goto putopp; } case OPMOD: goto putopp; case OPPLUS: case OPMINUS: case OPSLASH: case OPNEG: if( ISCOMPLEX(q->vtype) ) p = putcxop(q); else goto putopp; break; case OPCONV: if( ISCOMPLEX(q->vtype) ) p = putcxop(q); else if (ISCOMPLEX(q->b_expr.leftp->vtype)) { p = putx(mkconv(q->vtype, realpart(putcx1(q->b_expr.leftp)))); ckfree(q); } else goto putopp; break; case OPAND: /* Create logical AND */ x1 = fmktemp(TYLOGICAL, NULL); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(0))); k = newlabel(); putif(q->b_expr.leftp, k); putif(q->b_expr.rightp, k); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(1))); putlabel(k); p = putx(x1); break; case OPNOT: /* Logical NOT */ x1 = fmktemp(TYLOGICAL, NULL); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(1))); k = newlabel(); putif(q->b_expr.leftp, k); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(0))); putlabel(k); p = putx(x1); break; case OPOR: /* Create logical OR */ x1 = fmktemp(TYLOGICAL, NULL); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(1))); k = newlabel(); putif(mkexpr(OPEQ, q->b_expr.leftp, mklogcon(0)), k); putif(mkexpr(OPEQ, q->b_expr.rightp, mklogcon(0)), k); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(0))); putlabel(k); p = putx(x1); break; case OPCOMMA: for (x1 = q; x1->b_expr.opcode == OPCOMMA; x1 = x1->b_expr.leftp) putexpr(x1->b_expr.rightp); p = putx(x1); break; case OPEQV: case OPNEQV: case OPADDR: case OPBITOR: case OPBITAND: case OPBITXOR: case OPBITNOT: case OPLSHIFT: case OPRSHIFT: putopp: p = putop(q); break; default: fatal1("putx: invalid opcode %d", opc); } break; case TADDR: p = putaddr(q, YES); break; default: fatal1("putx: impossible tag %d", q->tag); } return p; }