home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
gnu
/
f2c-1993.04.28-src.lha
/
f2c-1993.04.28
/
src
/
putpcc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-28
|
40KB
|
1,842 lines
/****************************************************************
Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the names of AT&T Bell Laboratories or
Bellcore or any of their entities not be used in advertising or
publicity pertaining to distribution of the software without
specific, written prior permission.
AT&T and Bellcore disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall AT&T or Bellcore be liable for
any special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
****************************************************************/
/* INTERMEDIATE CODE GENERATION FOR S. C. JOHNSON C COMPILERS */
/* NEW VERSION USING BINARY POLISH POSTFIX INTERMEDIATE */
#include "defs.h"
#include "pccdefs.h"
#include "output.h" /* for nice_printf */
#include "names.h"
#include "p1defs.h"
Addrp realpart();
LOCAL Addrp intdouble(), putcx1(), putcxeq (), putch1 ();
LOCAL putct1 ();
expptr putcxop();
LOCAL expptr putcall (), putmnmx (), putcheq(), putcat ();
LOCAL expptr putaddr(), putchcmp (), putpower(), putop();
LOCAL expptr putcxcmp ();
expptr imagpart();
ftnint lencat();
#define FOUR 4
extern int ops2[];
extern int proc_argchanges, proc_protochanges;
extern int krparens;
#define P2BUFFMAX 128
/* Puthead -- output the header information about subroutines, functions
and entry points */
puthead(s, class)
char *s;
int class;
{
if (headerdone == NO) {
if (class == CLMAIN)
s = "MAIN__";
p1_head (class, s);
headerdone = YES;
}
}
putif(p, else_if_p)
register expptr p;
int else_if_p;
{
register int k;
int n;
long where;
if (else_if_p) {
p1put(P1_ELSEIFSTART);
where = ftell(pass1_file);
}
if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype )) )
{
if(k != TYERROR)
err("non-logical expression in IF statement");
}
else {
if (else_if_p) {
if (ei_next >= ei_last)
{
k = ei_last - ei_first;
n = k + 100;
ei_next = mem(n,0);
ei_last = ei_first + n;
if (k)
memcpy(ei_next, ei_first, k);
ei_first = ei_next;
ei_next += k;
ei_last = ei_first + n;
}
p = putx(p);
if (*ei_next++ = ftell(pass1_file) > where) {
p1_if(p);
new_endif();
}
else
p1_elif(p);
}
else {
p = putx(p);
p1_if(p);
}
}
}
putout(p)
expptr p;
{
p1_expr (p);
/* Used to make temporaries in holdtemps available here, but they */
/* may be reused too soon (e.g. when multiple **'s are involved). */
}
putcmgo(index, nlab, labs)
expptr index;
int nlab;
struct Labelblock *labs[];
{
if(! ISINT(index->headblock.vtype) )
{
execerr("computed goto index must be integer", CNULL);
return;
}
p1comp_goto (index, nlab, labs);
}
static expptr
krput(p)
register expptr p;
{
register expptr e, e1;
register unsigned op;
int t = krparens == 2 ? TYDREAL : p->exprblock.vtype;
op = p->exprblock.opcode;
e = p->exprblock.leftp;
if (e->tag == TEXPR && e->exprblock.opcode == op) {
e1 = (expptr)mktmp(t, ENULL);
putout(putassign(cpexpr(e1), e));
p->exprblock.leftp = e1;
}
else
p->exprblock.leftp = putx(e);
e = p->exprblock.rightp;
if (e->tag == TEXPR && e->exprblock.opcode == op) {
e1 = (expptr)mktmp(t, ENULL);
putout(putassign(cpexpr(e1), e));
p->exprblock.rightp = e1;
}
else
p->exprblock.rightp = putx(e);
return p;
}
expptr putx(p)
register expptr p;
{
int opc;
int k;
if (p)
switch(p->tag)
{
case TERROR:
break;
case TCONST:
switch(p->constblock.vtype)
{
case TYLOGICAL1:
case TYLOGICAL2:
case TYLOGICAL:
#ifdef TYQUAD
case TYQUAD:
#endif
case TYLONG:
case TYSHORT:
case TYINT1:
break;
case TYADDR:
break;
case TYREAL:
case TYDREAL:
/* Don't write it out to the p2 file, since you'd need to call putconst,
which is just what we need to avoid in the translator */
break;
default:
p = putx( (expptr)putconst((Constp)p) );
break;
}
break;
case TEXPR:
switch(opc = p->exprblock.opcode)
{
case OPCALL:
case OPCCALL:
if( ISCOMPLEX(p->exprblock.vtype) )
p = putcxop(p);
else p = putcall(p, (Addrp *)NULL);
break;
case OPMIN:
case OPMAX:
p = putmnmx(p);
break;
case OPASSIGN:
if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
|| ISCOMPLEX(p->exprblock.rightp->headblock.vtype)) {
(void) putcxeq(p);
p = ENULL;
} else if( ISCHAR(p) )
p = putcheq(p);
else
goto putopp;
break;
case OPEQ:
case OPNE:
if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
{
p = putcxcmp(p);
break;
}
case OPLT:
case OPLE:
case OPGT:
case OPGE:
if(ISCHAR(p->exprblock.leftp))
{
p = putchcmp(p);
break;
}
goto putopp;
case OPPOWER:
p = putpower(p);
break;
case OPSTAR:
/* m * (2**k) -> m<<k */
if(INT(p->exprblock.leftp->headblock.vtype) &&
ISICON(p->exprblock.rightp) &&
( (k = log_2(p->exprblock.rightp->constblock.Const.ci))>0) )
{
p->exprblock.opcode = OPLSHIFT;
frexpr(p->exprblock.rightp);
p->exprblock.rightp = ICON(k);
goto putopp;
}
if (krparens && ISREAL(p->exprblock.vtype))
return krput(p);
case OPMOD:
goto putopp;
case OPPLUS:
if (krparens && ISREAL(p->exprblock.vtype))
return krput(p);
case OPMINUS:
case OPSLASH:
case OPNEG:
case OPNEG1:
case OPABS:
case OPDABS:
if( ISCOMPLEX(p->exprblock.vtype) )
p = putcxop(p);
else goto putopp;
break;
case OPCONV:
if( ISCOMPLEX(p->exprblock.vtype) )
p = putcxop(p);
else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
{
p = putx( mkconv(p->exprblock.vtype,
(expptr)realpart(putcx1(p->exprblock.leftp))));
}
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:
case OPASSIGNI:
case OPIDENTITY:
case OPCHARCAST:
case OPMIN2:
case OPMAX2:
case OPDMIN:
case OPDMAX:
putopp:
p = putop(p);
break;
case OPCONCAT:
/* weird things like ichar(a//a) */
p = (expptr)putch1(p);
break;
default:
badop("putx", opc);
p = errnode ();
}
break;
case TADDR:
p = putaddr(p);
break;
default:
badtag("putx", p->tag);
p = errnode ();
}
return p;
}
LOCAL expptr putop(p)
expptr p;
{
expptr lp, tp;
int pt, lt, lt1;
int comma;
switch(p->exprblock.opcode) /* check for special cases and rewrite */
{
case OPCONV:
pt = p->exprblock.vtype;
lp = p->exprblock.leftp;
lt = lp->headblock.vtype;
/* Simplify nested type casts */
while(p->tag==TEXPR && p->exprblock.opcode==OPCONV &&
( (ISREAL(pt)&&ONEOF(lt,MSKREAL|MSKCOMPLEX)) ||
(INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
{
if(pt==TYDREAL && lt==TYREAL)
{
if(lp->tag==TEXPR
&& lp->exprblock.opcode == OPCONV) {
lt1 = lp->exprblock.leftp->headblock.vtype;
if (lt1 == TYDREAL) {
lp->exprblock.leftp =
putx(lp->exprblock.leftp);
return p;
}
if (lt1 == TYDCOMPLEX) {
lp->exprblock.leftp = putx(
(expptr)realpart(
putcx1(lp->exprblock.leftp)));
return p;
}
}
break;
}
else if (ISREAL(pt) && ISCOMPLEX(lt)) {
p->exprblock.leftp = putx(mkconv(pt,
(expptr)realpart(
putcx1(p->exprblock.leftp))));
break;
}
if(lt==TYCHAR && lp->tag==TEXPR &&
lp->exprblock.opcode==OPCALL)
{