putpcc.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,859 行 · 第 1/3 页
C
1,859 行
#ifndef lintstatic char *sccsid = " @(#)putpcc.c 1.4 (ULTRIX) 1/15/86";#endif lint/************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************** Modification History** David Metsky 14-Jan-86** 001 Replaced old version with BSD 4.3 version as part of upgrade.** Based on: putpcc.c 5.1 6/7/85**************************************************************************//* * putpcc.c * * Intermediate code generation for S. C. Johnson C compilers * New version using binary polish postfix intermediate * * University of Utah CS Dept modification history: * * $Header: putpcc.c,v 3.2 85/03/25 09:35:57 root Exp $ * $Log: putpcc.c,v $ * Revision 3.2 85/03/25 09:35:57 root * fseek return -1 on error. * * Revision 3.1 85/02/27 19:06:55 donn * Changed to use pcc.h instead of pccdefs.h. * * Revision 2.12 85/02/22 01:05:54 donn * putaddr() didn't know about intrinsic functions... * * Revision 2.11 84/11/28 21:28:49 donn * Hacked putop() to handle any character expression being converted to int, * not just function calls. Previously it bombed on concatenations. * * Revision 2.10 84/11/01 22:07:07 donn * Yet another try at getting putop() to work right. It appears that the * second pass can't abide certain explicit conversions (e.g. short to long) * so the conversion code in putop() tries to remove them. I think this * version (finally) works. * * Revision 2.9 84/10/29 02:30:57 donn * Earlier fix to putop() for conversions was insufficient -- we NEVER want to * see the type of the left operand of the thing left over from stripping off * conversions... * * Revision 2.8 84/09/18 03:09:21 donn * Fixed bug in putop() where the left operand of an addrblock was being * extracted... This caused an extremely obscure conversion error when * an array of longs was subscripted by a short. * * Revision 2.7 84/08/19 20:10:19 donn * Removed stuff in putbranch that treats STGARG parameters specially -- the * bug in the code generation pass that motivated it has been fixed. * * Revision 2.6 84/08/07 21:32:23 donn * Bumped the size of the buffer for the intermediate code file from 0.5K * to 4K on a VAX. * * Revision 2.5 84/08/04 20:26:43 donn * Fixed a goof in the new putbranch() -- it now calls mkaltemp instead of * mktemp(). Correction due to Jerry Berkman. * * Revision 2.4 84/07/24 19:07:15 donn * Fixed bug reported by Craig Leres in which putmnmx() mistakenly assumed * that mkaltemp() returns tempblocks, and tried to free them with frtemp(). * * Revision 2.3 84/07/19 17:22:09 donn * Changed putch1() so that OPPAREN expressions of type CHARACTER are legal. * * Revision 2.2 84/07/19 12:30:38 donn * Fixed a type clash in Bob Corbett's new putbranch(). * * Revision 2.1 84/07/19 12:04:27 donn * Changed comment headers for UofU. * * Revision 1.8 84/07/19 11:38:23 donn * Replaced putbranch() routine so that you can ASSIGN into argument variables. * The code is from Bob Corbett, donated by Jerry Berkman. * * Revision 1.7 84/05/31 00:48:32 donn * Fixed an extremely obscure bug dealing with the comparison of CHARACTER*1 * expressions -- a foulup in the order of COMOP and the comparison caused * one operand of the comparison to be garbage. * * Revision 1.6 84/04/16 09:54:19 donn * Backed out earlier fix for bug where items in the argtemplist were * (incorrectly) being given away; this is now fixed in mkargtemp(). * * Revision 1.5 84/03/23 22:49:48 donn * Took out the initialization of the subroutine argument temporary list in * putcall() -- it needs to be done once per statement instead of once per call. * * Revision 1.4 84/03/01 06:48:05 donn * Fixed bug in Bob Corbett's code for argument temporaries that caused an * addrblock to get thrown out inadvertently when it was needed for recycling * purposes later on. * * Revision 1.3 84/02/26 06:32:38 donn * Added Berkeley changes to move data definitions around and reduce offsets. * * Revision 1.2 84/02/26 06:27:45 donn * Added code to catch TTEMP values passed to putx(). * */#if FAMILY != PCC WRONG put FILE !!!!#endif#include "defs.h"#include <pcc.h>Addrp putcall(), putcxeq(), putcx1(), realpart();expptr imagpart();ftnint lencat();#define FOUR 4extern int ops2[];extern int types2[];#if HERE==VAX#define PCC_BUFFMAX 1024#else#define PCC_BUFFMAX 128#endifstatic long int p2buff[PCC_BUFFMAX];static long int *p2bufp = &p2buff[0];static long int *p2bufend = &p2buff[PCC_BUFFMAX];puthead(s, class)char *s;int class;{char buff[100];#if TARGET == VAX if(s) p2ps("\t.globl\t_%s", s);#endif/* put out fake copy of left bracket line, to be redone later */if( ! headerdone ) {#if FAMILY == PCC p2flush();#endif headoffset = ftell(textfile); prhead(textfile); headerdone = YES; p2triple(PCCF_FEXPR, (strlen(infname)+FOUR-1)/FOUR, 0); p2str(infname);#if TARGET == PDP11 /* fake jump to start the optimizer */ if(class != CLBLOCK) putgoto( fudgelabel = newlabel() );#endif#if TARGET == VAX /* jump from top to bottom */ if(s!=CNULL && class!=CLBLOCK) { int proflab = newlabel(); p2ps("_%s:", s); p2pi("\t.word\tLWM%d", procno); prsave(proflab); p2pi("\tjbr\tL%d", fudgelabel = newlabel()); }#endif }}/* It is necessary to precede each procedure with a "left bracket" * line that tells pass 2 how many register variables and how * much automatic space is required for the function. This compiler * does not know how much automatic space is needed until the * entire procedure has been processed. Therefore, "puthead" * is called at the begining to record the current location in textfile, * then to put out a placeholder left bracket line. This procedure * repositions the file and rewrites that line, then puts the * file pointer back to the end of the file. */putbracket(){long int hereoffset;#if FAMILY == PCC p2flush();#endifhereoffset = ftell(textfile);if(fseek(textfile, headoffset, 0) == -1) fatal("fseek failed");prhead(textfile);if(fseek(textfile, hereoffset, 0) == -1) fatal("fseek failed 2");}putrbrack(k)int k;{p2op(PCCF_FRBRAC, k);}putnreg(){}puteof(){p2op(PCCF_FEOF, 0);p2flush();}putstmt(){p2triple(PCCF_FEXPR, 0, lineno);}/* put out code for if( ! p) goto l */putif(p,l)register expptr p;int l;{register int k;if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) { if(k != TYERROR) err("non-logical expression in IF statement"); frexpr(p); }else { putex1(p); p2icon( (long int) l , PCCT_INT); p2op(PCC_CBRANCH, 0); putstmt(); }}/* put out code for goto l */putgoto(label)int label;{p2triple(PCC_GOTO, 1, label);putstmt();}/* branch to address constant or integer variable */putbranch(p)register Addrp p;{ putex1((expptr) p); p2op(PCC_GOTO, PCCT_INT); putstmt();}/* put out label l: */putlabel(label)int label;{p2op(PCCF_FLABEL, label);}putexpr(p)expptr p;{putex1(p);putstmt();}putcmgo(index, nlab, labs)expptr index;int nlab;struct Labelblock *labs[];{int i, labarray, skiplabel;if(! ISINT(index->headblock.vtype) ) { execerr("computed goto index must be integer", CNULL); return; }#if TARGET == VAX /* use special case instruction */ vaxgoto(index, nlab, labs);#else labarray = newlabel(); preven(ALIADDR); prlabel(asmfile, labarray); prcona(asmfile, (ftnint) (skiplabel = newlabel()) ); for(i = 0 ; i < nlab ; ++i) if( labs[i] ) prcona(asmfile, (ftnint)(labs[i]->labelno) ); prcmgoto(index, nlab, skiplabel, labarray); putlabel(skiplabel);#endif}putx(p)expptr p;{char *memname();int opc;int ncomma;int type, k;if (!p) return;switch(p->tag) { case TERROR: free( (charptr) p ); break; case TCONST: switch(type = p->constblock.vtype) { case TYLOGICAL: type = tyint; case TYLONG: case TYSHORT: p2icon(p->constblock.const.ci, types2[type]); free( (charptr) p ); break; case TYADDR: p2triple(PCC_ICON, 1, PCCT_INT|PCCTM_PTR); p2word(0L); p2name(memname(STGCONST, (int) p->constblock.const.ci) ); free( (charptr) p ); break; default: putx( putconst(p) ); break; } break; case TEXPR: switch(opc = p->exprblock.opcode) { case OPCALL: case OPCCALL: if( ISCOMPLEX(p->exprblock.vtype) ) putcxop(p); else putcall(p); break; case OPMIN: case OPMAX: putmnmx(p); break; case OPASSIGN: if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype) || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) ) frexpr( putcxeq(p) ); else if( ISCHAR(p) ) putcheq(p); else goto putopp; break; case OPEQ: case OPNE: if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) ) { putcxcmp(p); break; } case OPLT: case OPLE: case OPGT: case OPGE: if(ISCHAR(p->exprblock.leftp)) { putchcmp(p); break; } goto putopp; case OPPOWER: putpower(p); break; case OPSTAR:#if FAMILY == PCC /* m * (2**k) -> m<<k */ if(INT(p->exprblock.leftp->headblock.vtype) && ISICON(p->exprblock.rightp) && ( (k = log2(p->exprblock.rightp->constblock.const.ci))>0) ) { p->exprblock.opcode = OPLSHIFT; frexpr(p->exprblock.rightp); p->exprblock.rightp = ICON(k); goto putopp; }#endif case OPMOD: goto putopp; case OPPLUS: case OPMINUS: case OPSLASH: case OPNEG: if( ISCOMPLEX(p->exprblock.vtype) ) putcxop(p); else goto putopp; break; case OPCONV: if( ISCOMPLEX(p->exprblock.vtype) ) putcxop(p); else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ) { ncomma = 0; putx( mkconv(p->exprblock.vtype, realpart(putcx1(p->exprblock.leftp, &ncomma)))); putcomma(ncomma, p->exprblock.vtype, NO); free( (charptr) p ); } else goto putopp; break; case OPNOT: case OPOR: case OPAND: case OPEQV: case OPNEQV: case OPADDR: case OPPLUSEQ: case OPSTAREQ: case OPCOMMA: case OPQUEST: case OPCOLON: case OPBITOR: case OPBITAND: case OPBITXOR: case OPBITNOT: case OPLSHIFT: case OPRSHIFT: putopp: putop(p); break; case OPPAREN: putx (p->exprblock.leftp); break; default: badop("putx", opc); } break; case TADDR: putaddr(p, YES); break; case TTEMP: /* * This type is sometimes passed to putx when errors occur * upstream, I don't know why. */ frexpr(p); break; default: badtag("putx", p->tag); }}LOCAL putop(p)expptr p;{int k;expptr lp, tp;int pt, lt, tt;int comma;Addrp putch1();switch(p->exprblock.opcode) /* check for special cases and rewrite */ { case OPCONV: tt = pt = p->exprblock.vtype; lp = p->exprblock.leftp; lt = lp->headblock.vtype; if (pt == TYREAL && lt == TYDREAL) { putx(lp); p2op(PCC_SCONV, PCCT_FLOAT); return; } while(p->tag==TEXPR && p->exprblock.opcode==OPCONV && ( (ISREAL(pt)&&ISREAL(lt)) || (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) )) {#if SZINT < SZLONG if(lp->tag != TEXPR) { if(pt==TYINT && lt==TYLONG) break; if(lt==TYINT && pt==TYLONG) break; }#endif#if TARGET == VAX if(pt==TYDREAL && lt==TYREAL) { if(lp->tag==TEXPR && lp->exprblock.opcode==OPCONV && lp->exprblock.leftp->headblock.vtype==TYDREAL) { putx(lp->exprblock.leftp); p2op(PCC_SCONV, PCCT_FLOAT); p2op(PCC_SCONV, PCCT_DOUBLE); free( (charptr) p ); return; } else break; }#endif if(lt==TYCHAR && lp->tag==TEXPR) { int ncomma = 0; p->exprblock.leftp = (expptr) putch1(lp, &ncomma); putop(p); putcomma(ncomma, pt, NO); free( (charptr) p ); return; } free( (charptr) p ); p = lp; pt = lt; if (p->tag == TEXPR) { lp = p->exprblock.leftp; lt = lp->headblock.vtype; } } if(p->tag==TEXPR && p->exprblock.opcode==OPCONV) break; putx(p); if (types2[tt] != types2[pt] && ! ( (ISREAL(tt)&&ISREAL(pt)) || (INT(tt)&&(ONEOF(pt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) )) p2op(PCC_SCONV,types2[tt]); return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?