+#ifndef _C2_H_
+#define _C2_H_
+
/* c2.h 4.10 85/08/22 */
/*
#define RT4 15
#define LABHS 127
-char *copy();
-long getnum();
-struct node *codemove();
-struct node *insertl();
-struct node *nonlab();
+/*char *copy();*/
+/*long getnum();*/
+/*struct node *codemove();*/
+/*struct node *insertl();*/
+/*struct node *nonlab();*/
#ifdef notdef
#define decref(p) \
((p) && --(p)->refc <= 0 ? nrlab++, delnode(p) : 0)
#define delnode(p) \
((p)->back->forw = (p)->forw, (p)->forw->back = (p)->back)
-#endif notdef
+#endif
-char *xalloc();
+/*char *xalloc();*/
extern char *newa;
extern char *lasta;
extern char *lastr;
((newa = lasta) + (n) > lastr ? \
xalloc(n) : \
(lasta += XALIGN(n), newa)))
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif
+
+/* c20.c */
+char *xalloc __P((int n));
+int main __P((int argc, char **argv));
+int input __P((void));
+struct optab *getline __P((void));
+long getnum __P((register char *p));
+int locuse __P((register char *p));
+int locdef __P((register char *p));
+int output __P((void));
+char *copy __P((char *ap));
+int opsetup __P((void));
+struct optab *oplook __P((void));
+int refcount __P((void));
+int iterate __P((void));
+int xjump __P((register struct node *p1));
+struct node *insertl __P((register struct node *np));
+struct node *codemove __P((struct node *ap));
+int comjump __P((void));
+int backjmp __P((struct node *ap1, struct node *ap2));
+
+/* c21.c */
+int redun3 __P((register struct node *p, int split));
+int bmove __P((void));
+int rmove __P((void));
+char *byondrd __P((register struct node *p));
+struct node *bflow __P((register struct node *p));
+int ispow2 __P((register long n));
+int bitopt __P((register struct node *p));
+int isfield __P((register long n));
+int bixprep __P((register struct node *p, int bix));
+struct node *bicopt __P((register struct node *p));
+int jumpsw __P((void));
+int addsob __P((void));
+int equop __P((register struct node *p1, struct node *p2));
+int XXXdelnode __P((register struct node *p));
+int XXXdecref __P((register struct node *p));
+struct node *nonlab __P((struct node *ap));
+int clearuse __P((void));
+int clearreg __P((void));
+int savereg __P((int ai, register char *s, int type));
+int dest __P((register char *s, int type));
+int splitrand __P((struct node *p));
+int compat __P((int have, int want));
+int equtype __P((int t1, int t2));
+int findrand __P((char *as, int type));
+int isreg __P((register char *s));
+int check __P((void));
+int source __P((char *ap));
+int newcode __P((struct node *p));
+int repladdr __P((struct node *p));
+int redunbr __P((register struct node *p));
+char *findcon __P((int i, int type));
+int compare __P((int opc, char *acp1, char *acp2));
+int setcon __P((register char *cv, register char *cl, int type));
+int equstr __P((register char *p1, register char *p2));
+int setcc __P((char *ap, int type));
+int okio __P((register char *p));
+int indexa __P((register char *p));
+int natural __P((register char *p));
+int isstatic __P((register char *cp));
+int autoid __P((register char *p));
+
+#endif
-#ifndef lint
+/*#include <ctype.h> gen.h*/
+#include <gen.h>
+#include <stdio.h>
+/*#include <strings.h> gen.h*/
+#include "c2.h"
+
+#if defined(DOSCCS) && !defined(lint)
static char sccsid[] = "@(#)c20.c 4.10 (Berkeley) 8/22/85";
#endif
* C object code improver
*/
-#include "c2.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
+/*#include "c2.h"*/
+/*#include <stdio.h>*/
+/*#include <ctype.h>*/
+/*#include <sys/types.h>*/
/* moved here from c2.h which now just declares them extern */
char line[512];
char conval[C2_ASIZE];
char ccloc[C2_ASIZE];
-char *malloc();
+/*char *malloc();*/
char firstr[sizeof (char *)];
char *currentb;
char *newa;
long isn = 2000000;
-struct optab *oplook();
-struct optab *getline();
+/*struct optab *oplook();*/
+/*struct optab *getline();*/
long lgensym[10] =
{100000L,200000L,300000L,400000L,500000L,600000L,700000L,800000L,900000L,1000000L};
* and doesn't clash with stdio. Assumes that no one requests more than
* ALLOCSIZE bytes at a time.
*/
-char *
-xalloc(n)
-int n;
-{
+char *xalloc(n) int n; {
register char *nextb = * (char **) currentb;
if (n == 0) { /* Free everything */
return(newa);
}
-main(argc, argv)
-char **argv;
-{
+int main(argc, argv) int argc; char **argv; {
register int niter, maxiter, isend;
int nflag,infound;
fflush(stdout); exit(0);
}
-input()
-{
+int input() {
register struct node *p, *lastp;
struct optab *opp; register char *cp1;
static struct optab F77JSW = {".long", T(JSW,1)};
}
}
-struct optab *
-getline()
-{
+struct optab *getline() {
register char *lp;
register c;
static struct optab OPLABEL={"",LABEL};
return(&OPEND);
}
-long
-getnum(p)
-register char *p;
-{
+long getnum(p) register char *p; {
register c; int neg; register long n;
n = 0; neg=0; if (*p=='-') {++neg; ++p;}
return(n);
}
-locuse(p)
-register char *p;
-{
+int locuse(p) register char *p; {
if (!isdigit(p[0]) || p[1] != 'f' && p[1] != 'b' || p[2]) return(0);
return (lgensym[p[0] - '0'] - (p[1] == 'b'));
}
-locdef(p)
-register char *p;
-{
+int locdef(p) register char *p; {
if (!isdigit(p[0]) || p[1]) return(0);
return (lgensym[p[0] - '0']++);
}
-output()
-{
+int output() {
register struct node *t;
int casebas;
if (!fflag) goto std;
if (t->forw) if(t->forw->op == CBR) goto std;
if (*t->code == '$') goto std;
- if (t->subop == FFLOAT)
- {
+ if (t->subop == FFLOAT) {
printf("movl\t%s\n", t->code);
continue;
}
- if (t->subop == DFLOAT || t->subop == GFLOAT)
- {
+ if (t->subop == DFLOAT || t->subop == GFLOAT) {
printf("movq\t%s\n", t->code);
continue;
}
- if (t->subop == HFLOAT)
- {
+ if (t->subop == HFLOAT) {
printf("movo\t%s\n", t->code);
continue;
}
}
}
-char *
-copy(ap)
-char *ap;
-{
+char *copy(ap) char *ap; {
#if 1 /* in this application there is never more than one argument */
int len;
char *strcpy();
#define OPHS 560
struct optab *ophash[OPHS];
-opsetup()
-{
+int opsetup() {
register struct optab *optp, **ophp;
register int i,t;
}
}
-struct optab *
-oplook()
-{
+struct optab *oplook() {
register struct optab *optp,**ophp;
register char *p,*p2;
register int t;
return(&OPNULL);
}
-refcount()
-{
+int refcount() {
register struct node *p, *lp, *tp;
struct node *labhash[LABHS];
register struct node **hp;
decref(p);
}
-iterate()
-{
+int iterate() {
register struct node *p, *rp, *p1;
nchange = 0;
}
}
-xjump(p1)
-register struct node *p1;
-{
+int xjump(p1) register struct node *p1; {
register struct node *p2, *p3;
if ((p2 = p1->ref)==0)
}
}
-struct node *
-insertl(np)
-register struct node *np;
-{
+struct node *insertl(np) register struct node *np; {
register struct node *lp;
if (np->op == LABEL) {
return(lp);
}
-struct node *
-codemove(ap)
-struct node *ap;
-{
+struct node *codemove(ap) struct node *ap; {
register struct node *p1, *p2, *p3;
struct node *t, *tl;
int n;
return(p3);
}
-comjump()
-{
+int comjump() {
register struct node *p1, *p2, *p3;
for (p1 = first.forw; p1!=0; p1 = p1->forw)
backjmp(p1, p3);
}
-backjmp(ap1, ap2)
-struct node *ap1, *ap2;
-{
+int backjmp(ap1, ap2) struct node *ap1; struct node *ap2; {
register struct node *p1, *p2, *p3;
p1 = ap1;
-#ifndef lint
+/*#include <ctype.h> gen.h*/
+#include <gen.h>
+#include <stdio.h>
+/*#include <strings.h> gen.h*/
+#include "c2.h"
+
+#if defined(DOSCCS) && !defined(lint)
static char sccsid[] = "@(#)c21.c 4.19 4/27/86";
#endif
/* char C21[] = {"@(#)c21.c 1.83 80/10/16 21:18:22 JFR"}; /* sccs ident */
* C object code improver-- second part
*/
-#include "c2.h"
-#include <stdio.h>
-#include <ctype.h>
+/*#include "c2.h"*/
+/*#include <stdio.h>*/
+/*#include <ctype.h>*/
#define NUSE 6
int ioflag;
int pos,siz; long f; /* for bit field communication */
struct node *uses[NUSE]; /* for backwards flow analysis */
char *lastrand; /* last operand of instruction */
-struct node *bflow();
-struct node *bicopt();
-char *findcon();
-char *strcpy();
+/*struct node *bflow();*/
+/*struct node *bicopt();*/
+/*char *findcon();*/
+/*char *strcpy();*/
-redun3(p,split) register struct node *p; int split; {
+int redun3(p, split) register struct node *p; int split; {
/* check for 3 addr instr which should be 2 addr */
if (OP3==((p->subop>>4)&0xF)) {
if (split) splitrand(p);
} return(0);
}
-bmove() {
+int bmove() {
register struct node *p, *lastp; register char *cp1,*cp2; register int r;
refcount();
for (p=lastp= &first; 0!=(p=p->forw); lastp=p);
case ADD:
if ((p->subop&0xF)!=LONG) goto std; cp1=p->code;
if (*cp1++!='$') goto std; splitrand(p);
- if (isstatic(cp1) && (r=isreg(regs[RT2]))>=0 && r<NUSE && uses[r]==p->forw)
- {
+ if (isstatic(cp1) && (r=isreg(regs[RT2]))>=0 && r<NUSE && uses[r]==p->forw) {
/* address comp:
** addl2 $_foo,r0 \ movab _foo[r0],bar
** movl r0,bar /
register struct node *pnext = p->forw;
char buf[C2_ASIZE];
- if (pnext->op == MOV && pnext->subop == LONG)
- {
+ if (pnext->op == MOV && pnext->subop == LONG) {
cp1 = ®s[RT1][1]; cp2 = &buf[0];
while (*cp2++ = *cp1++) ; cp2--;
splitrand(pnext);
- if (r == isreg(regs[RT1]))
- {
+ if (r == isreg(regs[RT1])) {
delnode(p); p = pnext;
p->op = MOVA; p->subop = BYTE;
p->pop = 0;
case CASE:
default: std:
p=bflow(p); break;
- case MUL:
- {
+ case MUL: {
/*
** Change multiplication by constant powers of 2 to
** shifts.
splitrand(p);
if (regs[RT1][0] != '$' || regs[RT1][1] == '-') goto std;
if ((r = ispow2(getnum(®s[RT1][1]))) < 0) goto std;
- switch (r)
- {
+ switch (r) {
case 0: /* mull3 $1,x,y */
- if (p->subop == U(LONG,OP3))
- {
- if (equstr(regs[RT2], regs[RT3]))
- {
+ if (p->subop == U(LONG,OP3)) {
+ if (equstr(regs[RT2], regs[RT3])) {
delnode(p); p = p->forw;
}
- else
- {
+ else {
p->op = MOV; p->subop = LONG;
p->pop = 0; newcode(p); nchange++;
}
}
else
- if (p->subop == U(LONG,OP2))
- {
+ if (p->subop == U(LONG,OP2)) {
delnode(p); p = p->forw;
}
goto std;
case 1: /* mull2 $2,x */
- if (p->subop == U(LONG, OP2) && !source(regs[RT2]))
- {
+ if (p->subop == U(LONG, OP2) && !source(regs[RT2])) {
strcpy(regs[RT1], regs[RT2]);
p->op = ADD; p->pop = 0; newcode(p); nchange++;
}
goto std;
}
- if(p->subop==U(LONG,OP3)||(p->subop==U(LONG,OP2)&&!source(regs[RT2])))
- {
+ if(p->subop==U(LONG,OP3)||(p->subop==U(LONG,OP2)&&!source(regs[RT2]))) {
if (p->subop == U(LONG,OP2))
strcpy(regs[RT3], regs[RT2]);
sprintf(regs[RT1], "$%d", r);
}
goto std;
}
- case ASH:
- {
+ case ASH: {
/* address comp:
** ashl $1,bar,r0 \ movl bar,r0
** movab _foo[r0] / movaw _foo[r0]
if ((shcnt = getnum(®s[RT1][1])) < 1 || shcnt > 3) goto std;
if ((shfrom = isreg(regs[RT2])) >= 0)
regfrom = copy(regs[RT2]);
- if ((shto = isreg(regs[RT3])) >= 0 && shto<NUSE)
- {
+ if ((shto = isreg(regs[RT3])) >= 0 && shto<NUSE) {
int regnum;
if (uses[shto] != (pf = p->forw)) goto ashadd;
while (*cp2++ != '[') ;
if (*cp2++ != 'r' || !isdigit(*cp2)) goto std;
regnum = *cp2++ - '0';
- if (isdigit(*cp2))
- {
+ if (isdigit(*cp2)) {
if (cp2[1] != ']') goto std;
regnum *= 10; regnum += *cp2 - '0';
}
if (regnum != shto) goto std;
- if (shfrom >= 0) /* ashl $N,r*,r0 */
- {
+ if (shfrom >= 0) /* ashl $N,r*,r0 */ {
delnode(p);
- if (shfrom != shto)
- {
+ if (shfrom != shto) {
uses[shto] = NULL; splitrand(pf);
cp2=regs[RT1]; while (*cp2++!='[');
cp1=regfrom; while (*cp2++= *cp1++);
newcode(pf);
}
}
- else
- {
+ else {
p->op = MOV; splitrand(p);
strcpy(regs[RT1], regs[RT2]);
strcpy(regs[RT2], regs[RT3]);
regs[RT3][0] = '\0';
p->pop = 0; newcode(p);
}
- switch (shcnt)
- {
+ switch (shcnt) {
case 1: pf->subop = WORD; break;
case 2: pf->subop = LONG; break;
case 3: pf->subop = QUAD; break;
}
ashadd:
/* at this point, RT2 and RT3 are guaranteed to be simple regs*/
- if (shcnt == 1 && equstr(regs[RT2], regs[RT3]))
- {
+ if (shcnt == 1 && equstr(regs[RT2], regs[RT3])) {
/*
** quickie:
** ashl $1,A,A > addl2 A,A
}
case EXTV:
- case EXTZV:
- {
+ case EXTZV: {
/* bit tests:
** extv A,$1,B,rC \
** tstl rC > jbc A,B,D
splitrand(p);
if (regs[RT2][0] != '$') goto std;
if ((flen = getnum(®s[RT2][1])) < 0) goto std;
- if (flen == 1)
- {
+ if (flen == 1) {
register int extreg; /* reg extracted to */
extreg = isreg(regs[RT4]);
uses[extreg] = NULL;
}
else
- if (flen == 8 || flen == 16)
- {
+ if (flen == 8 || flen == 16) {
register int boff; /* bit offset */
register int coff; /* chunk (byte or word) offset*/
goto std;
}
- case CMP:
- {
+ case CMP: {
/* comparison to -63 to -1:
** cmpl r0,$-1 > incl r0
** jeql ...
reg = r = isreg(regs[RT1]);
if (r < 0) goto std;
if (r < NUSE && uses[r] != 0) goto std;
- if (r >= NUSE && regp->op == MOV && p->subop == regp->subop)
- {
+ if (r >= NUSE && regp->op == MOV && p->subop == regp->subop) {
if (*regp->code != 'r') goto std;
reg = regp->code[1] - '0';
if (isdigit(regp->code[2]) || reg >= NUSE || uses[reg])
if (reg != r)
sprintf(regs[RT1], "r%d", reg);
if ((num = getnum(®s[RT2][2])) <= 0 || num > 63) goto std;
- if (num == 1)
- {
+ if (num == 1) {
p->op = INC; regs[RT2][0] = '\0';
}
- else
- {
+ else {
register char *t;
t=regs[RT1];regs[RT1]=regs[RT2];regs[RT2]=t;
if (p->op==LABEL || p->op==DLABEL) p->ref=0; /* erase our tracks */
}
-rmove()
-{
+int rmove() {
register struct node *p;
register int r;
int r1;
}
}
-char *
-byondrd(p) register struct node *p; {
+char *byondrd(p) register struct node *p; {
/* return pointer to register which is "beyond last read/modify operand" */
if (OP2==(p->subop>>4)) return(regs[RT3]);
switch (p->op) {
return(lastrand);
}
-struct node *
-bflow(p)
-register struct node *p;
-{
+struct node *bflow(p) register struct node *p; {
register char *cp1,*cp2,**preg; register int r;
int flow= -1;
struct node *olduse=0;
return(p);
}
-ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
+int ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
register int log;
if (n==0 || n&(n-1)) return(-1); log=0;
for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}
}
-bitopt(p) register struct node *p; {
+int bitopt(p) register struct node *p; {
/* change "bitx $<power_of_2>,a" followed by JEQ or JNE
/* into JBC or JBS. watch out for I/O registers. (?)
/* assumes that 'splitrand' has already been called.
p->pop=0;
}
-isfield(n) register long n; {/* -1 -> no; else -> position of low bit */
+int isfield(n) register long n; {/* -1 -> no; else -> position of low bit */
register int p; register long t;
t= ((n-1)|n) +1;
if (n!=0 && (0==t || 0<=ispow2(t))) {
} else return(-1);
}
-bixprep(p,bix) register struct node *p; {
+int bixprep(p, bix) register struct node *p; int bix; {
/* initial setup, single-bit checking for bisopt, bicopt.
/* return: 0->don't bother any more; 1->worthwhile trying
*/
return(1);
}
-
-struct node *
-bicopt(p) register struct node *p; {
+struct node *bicopt(p) register struct node *p; {
/* use field operations or MOVZ if possible. done as part of 'bflow'.
*/
register char *cp1,*cp2; int r;
return(p);
}
-jumpsw()
-{
+int jumpsw() {
register struct node *p, *p1;
register struct node *tp;
long tl;
return(nj);
}
-addsob()
-{
+int addsob() {
register struct node *p, *p1, *p2, *p3;
for (p = &first; (p1 = p->forw)!=0; p = p1) {
}
}
-equop(p1, p2)
-register struct node *p1;
-struct node *p2;
-{
+int equop(p1, p2) register struct node *p1; struct node *p2; {
register char *cp1, *cp2;
if (p1->combop != p2->combop)
}
#ifndef delnode
-XXXdelnode(p) register struct node *p; {
+int XXXdelnode(p) register struct node *p; {
p->back->forw = p->forw;
p->forw->back = p->back;
}
#endif
#ifndef decref
-XXXdecref(p)
-register struct node *p;
-{
+int XXXdecref(p) register struct node *p; {
if (p && --p->refc <= 0) {
nrlab++;
delnode(p);
}
#endif
-struct node *
-nonlab(ap)
-struct node *ap;
-{
+struct node *nonlab(ap) struct node *ap; {
register struct node *p;
p = ap;
return(p);
}
-clearuse() {
+int clearuse() {
register struct node **i;
for (i=uses+NUSE; i>uses;) *--i=0;
}
-clearreg() {
+int clearreg() {
register char **i;
for (i=regs; i<regs+NREG; ++i) {
**i = 0;
ccloc[0] = 0;
}
-savereg(ai, s, type)
-register char *s;
-{
+int savereg(ai, s, type) int ai; register char *s; int type; {
register char *p, *sp;
sp = p = regs[ai];
if (*s=='[' || *s++=='(' && *s!='a' && *s!='f') {*sp = 0; return;}
}
-dest(s,type)
-register char *s;
-{
+int dest(s, type) register char *s; int type; {
register int i;
(void) source(s); /* handle addressing side effects */
}
/* separate operands at commas, set up 'regs' and 'lastrand' */
-splitrand(p) struct node *p; {
+int splitrand(p) struct node *p; {
register char *p1, *p2;
register char **preg;
*(*preg++) = 0;
}
-compat(have, want) {
+int compat(have, want) int have; int want; {
register int hsrc, hdst;
if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
hsrc=have&0xF;
return(hsrc>=want && hdst>=want && hdst<FFLOAT);
}
-equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
+int equtype(t1, t2) int t1; int t2; {return(compat(t1,t2) && compat(t2,t1));}
-findrand(as, type)
-char *as;
-{
+int findrand(as, type) char *as; int type; {
register char **i;
for (i = regs+NREG; --i>=regs;) {
if (**i && equstr(*i+1, as) && compat(**i,type))
return(-1);
}
-isreg(s)
-register char *s;
-{
+int isreg(s) register char *s; {
if (*s++!='r' || !isdigit(*s++)) return(-1);
if (*s==0) return(*--s-'0');
if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
return(-1);
}
-check()
-{
+int check() {
register struct node *p, *lp;
lp = &first;
}
}
-source(ap)
-char *ap;
-{
+int source(ap) char *ap; {
register char *p1, *p2;
p1 = ap;
return(0);
}
-newcode(p) struct node *p; {
+int newcode(p) struct node *p; {
register char *p1,*p2,**preg;
preg=regs+RT1; p2=line;
while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
p->code=copy(line);
}
-repladdr(p)
-struct node *p;
-{
+int repladdr(p) struct node *p; {
register r;
register char *p1;
char **preg; int nrepl;
/* }
*/
-redunbr(p)
-register struct node *p;
-{
+int redunbr(p) register struct node *p; {
register struct node *p1;
register char *ap1;
char *ap2;
}
}
-char *
-findcon(i, type)
-{
+char *findcon(i, type) int i; int type; {
register char *p;
register r;
return(p);
}
-compare(opc, acp1, acp2)
-char *acp1, *acp2;
-{
+int compare(opc, acp1, acp2) int opc; char *acp1; char *acp2; {
register char *cp1, *cp2;
register n1;
int n2; int sign;
return(0);
}
-setcon(cv, cl, type)
-register char *cv, *cl;
-{
+int setcon(cv, cl, type) register char *cv; register char *cl; int type; {
register char *p;
if (*cv != '$')
while (*p++ = *cv++);
}
-equstr(p1, p2)
-register char *p1, *p2;
-{
+int equstr(p1, p2) register char *p1; register char *p2; {
do {
if (*p1++ != *p2)
return(0);
return(1);
}
-setcc(ap,type)
-char *ap;
-{
+int setcc(ap, type) char *ap; int type; {
register char *p, *p1;
p = ap;
while (*p1++ = *p++);
}
-okio(p) register char *p; {/* 0->probable I/O space address; 1->not */
+int okio(p) register char *p; {/* 0->probable I/O space address; 1->not */
if (ioflag && (!natural(p) || 0>getnum(p))) return(0);
return(1);
}
-indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
+int indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
while (*p) if (*p++=='[') return(1);
return(0);
}
-natural(p)
-register char *p;
-{/* 1->simple local, parameter, global, or register; 0->otherwise */
+int natural(p) register char *p; {/* 1->simple local, parameter, global, or register; 0->otherwise */
if (*p=='*' || *p=='(' || *p=='-'&&p[1]=='(' || *p=='$'&&getnum(p+1))
return(0);
while (*p++);
** Tell if an argument is most likely static.
*/
-isstatic(cp)
-register char *cp;
-{
+int isstatic(cp) register char *cp; {
if (*cp == '_' || *cp == 'L' || (*cp++ == 'v' && *cp == '.'))
return (1);
return (0);
}
-autoid(p) register char *p; {/* 1-> uses autoincrement/autodecrement; 0->doesn't */
+int autoid(p) register char *p; {/* 1-> uses autoincrement/autodecrement; 0->doesn't */
if (*p == '-' && *(p+1) == '(') return(1);
while (*p) p++;
if (*--p == '+' && *--p == ')') return(1);