add LCC - a better C-Compiler for WEGA

This commit is contained in:
Oliver Lehmann 1990-04-11 16:05:25 +00:00
parent 87526ef35a
commit e300d3d2c5
2 changed files with 656 additions and 0 deletions

View File

@ -0,0 +1,419 @@
# include <stdio.h>
/* macro definitions for common cases of type collapsing */
# ifdef NOSHORT
# define SZSHORT SZINT
# define ALSHORT ALINT
# endif
# ifdef NOLONG
# define SZLONG SZINT
# define ALLONG ALINT
# endif
# ifdef NOFLOAT
# define SZFLOAT SZLONG
# define SZDOUBLE SZLONG
# define ALFLOAT ALLONG
# define ALDOUBLE ALLONG
# endif
# ifdef ONEFLOAT
# define SZFLOAT SZDOUBLE
# define ALFLOAT ALDOUBLE
# endif
/* define default assembly language comment starter */
# ifndef COMMENTSTR
# define COMMENTSTR "//"
#endif
/* manifest constant file for the lex/yacc interface */
# define ERROR 1
# define NAME 2
# define STRING 3
# define ICON 4
# define FCON 5
# define PLUS 6
# define MINUS 8
# define MUL 11
# define STAR (UNARY MUL)
# define AND 14
# define OR 17
# define ER 19
# define QUEST 21
# define COLON 22
# define ANDAND 23
# define OROR 24
/* special interfaces for yacc alone */
/* These serve as abbreviations of 2 or more ops:
ASOP =, = ops
RELOP LE,LT,GE,GT
EQUOP EQ,NE
DIVOP DIV,MOD
SHIFTOP LS,RS
ICOP INCR,DECR
UNOP NOT,COMPL
STROP DOT,STREF
*/
# define ASOP 25
# define RELOP 26
# define EQUOP 27
# define DIVOP 28
# define SHIFTOP 29
# define INCOP 30
# define UNOP 31
# define STROP 32
/* reserved words, etc */
# define TYPE 33
# define CLASS 34
# define STRUCT 35
# define RETURN 36
# define GOTO 37
# define IF 38
# define ELSE 39
# define SWITCH 40
# define BREAK 41
# define CONTINUE 42
# define WHILE 43
# define DO 44
# define FOR 45
# define DEFAULT 46
# define CASE 47
# define SIZEOF 48
# define ENUM 49
/* little symbols, etc. */
/* namely,
LP (
RP )
LC {
RC }
LB [
RB ]
CM ,
SM ;
*/
# define LP 50
# define RP 51
# define LC 52
# define RC 53
# define LB 54
# define RB 55
# define CM 56
# define SM 57
# define ASSIGN 58
/* ASM returned only by yylex, and totally eaten by yyparse */
# define ASM 59
/* END OF YACC */
/* left over tree building operators */
# define COMOP 59
# define DIV 60
# define MOD 62
# define LS 64
# define RS 66
# define DOT 68
# define STREF 69
# define CALL 70
# define FORTCALL 73
# define NOT 76
# define COMPL 77
# define INCR 78
# define DECR 79
# define EQ 80
# define NE 81
# define LE 82
# define LT 83
# define GE 84
# define GT 85
# define ULE 86
# define ULT 87
# define UGE 88
# define UGT 89
# define SETBIT 90
# define TESTBIT 91
# define RESETBIT 92
# define ARS 93
# define REG 94
# define TEMP 95
# define CCODES 96
# define FREE 97
# define STASG 98
# define STARG 99
# define STCALL 100
/* some conversion operators */
# define FLD 103
# define CONV 104
# define PMUL 105
# define PDIV 106
/* special node operators, used for special contexts */
/* # define FORCE 107 */
# define GENLAB 108
# define CBRANCH 109
# define GENBR 110
# define CMP 111
# define GENUBR 112
# define INIT 113
# define CAST 114
# define FUNARG 115
# define VAUTO 116
# define VPARAM 117
# define RNODE 118
# define SNODE 119
# define QNODE 120
/* a whole bunch of ops, done with unary; I don't need to tackle prec */
# define UOP0 121
# define UOP1 122
# define UOP2 123
# define UOP3 124
# define UOP4 125
# define UOP5 126
# define UOP6 127
# define UOP7 128
# define UOP8 129
# define UOP9 130
/* op used in second pass */
# define MANY 131
/* node types */
# define LTYPE 02
# define UTYPE 04
# define BITYPE 010
/* DSIZE is the size of the dope array */
# define DSIZE MANY+1
/* type names, used in symbol table building */
# define TNULL 0
# define FARG 1
# define CHAR 2
# define SHORT 3
# define INT 4
# define LONG 5
# define FLOAT 6
# define DOUBLE 7
# define STRTY 8
# define UNIONTY 9
# define ENUMTY 10
# define MOETY 11
# define UCHAR 12
# define USHORT 13
# define UNSIGNED 14
# define ULONG 15
# define VOID 16
# define UNDEF 17
# define ASG 1+
# define UNARY 2+
# define NOASG (-1)+
# define NOUNARY (-2)+
/* various flags */
# define NOLAB (-1)
/* type modifiers */
# define PTR 040
# define FTN 0100
# define ARY 0140
/* type packing constants */
# define MTMASK 03
# define BTMASK 037
# define BTSHIFT 5
# define TSHIFT 2
# define TMASK (MTMASK<<BTSHIFT)
# define TMASK1 (MTMASK<<(BTSHIFT+TSHIFT))
# define TMASK2 (TMASK||MTMASK)
/* macros */
# ifndef BITMASK
/* beware 1's complement */
# define BITMASK(n) (((n)==SZLONG)?-1L:((1L<<(n))-1))
# endif
# define ONEBIT(n) (1L<<(n))
# define MODTYPE(x,y) x = (x&(~BTMASK))|y /* set basic type of x to y */
# define BTYPE(x) (x&BTMASK) /* basic type of x */
# define ISUNSIGNED(x) ((x)<=ULONG&&(x)>=UCHAR)
# define UNSIGNABLE(x) ((x)<=LONG&&(x)>=CHAR)
# define ENUNSIGN(x) ((x)+(UNSIGNED-INT))
# define DEUNSIGN(x) ((x)+(INT-UNSIGNED))
# define ISPTR(x) ((x&TMASK)==PTR)
# define ISFTN(x) ((x&TMASK)==FTN) /* is x a function type */
# define ISARY(x) ((x&TMASK)==ARY) /* is x an array type */
# define INCREF(x) (((x&~BTMASK)<<TSHIFT)|PTR|(x&BTMASK))
# define DECREF(x) (((x>>TSHIFT)&~BTMASK)|(x&BTMASK))
# define SETOFF(x,y) if( (x)%(y) != 0 ) x = ( ((x)/(y) + 1) * (y))
/* advance x to a multiple of y */
# define NOFIT(x,y,z) ( ((x)%(z) + (y)) > (z) )
/* can y bits be added to x without overflowing z */
/* pack and unpack field descriptors (size and offset) */
# define PKFIELD(s,o) (((o)<<6)|(s))
# define UPKFSZ(v) ((v)&077)
# define UPKFOFF(v) ((v)>>6)
/* operator information */
# define TYFLG 016
# define ASGFLG 01
# define LOGFLG 020
# define SIMPFLG 040
# define COMMFLG 0100
# define DIVFLG 0200
# define FLOFLG 0400
# define LTYFLG 01000
# define CALLFLG 02000
# define MULFLG 04000
# define SHFFLG 010000
# define ASGOPFLG 020000
# define SPFLG 040000
#define optype(o) (dope[o]&TYFLG)
#define asgop(o) (dope[o]&ASGFLG)
#define asgbinop(o) (dope[o]&ASGOPFLG)
#define logop(o) (dope[o]&LOGFLG)
#define callop(o) (dope[o]&CALLFLG)
/* table sizes */
# define BCSZ 100 /* size of the table to save break and continue labels */
# define MAXNEST BCSZ /* maximum nesting depth for scopestack() */
# ifndef SYMTSZ
# define SYMTSZ 750 /* size of the symbol table */
# endif
# define DIMTABSZ 2000 /* size of the dimension/size table */
# define PARAMSZ 150 /* size of the parameter stack */
# define ARGSZ 50 /* size of the argument stack */
# ifndef TREESZ
# ifndef FORT
# define TREESZ 350 /* space for building parse tree */
# else
# define TREESZ 1000
# endif
# endif
# define SWITSZ 250 /* size of switch table */
char *hash();
char *savestr();
char *tstr();
extern int tstrused;
extern char *tstrbuf[];
extern char **curtstr;
#define freestr() ( curtstr = tstrbuf, tstrused = 0 )
# define NCHNAM 8 /* number of characters in a truncated name */
/* common defined variables */
extern int nerrors; /* number of errors seen so far */
typedef union ndu NODE;
typedef unsigned int TWORD;
typedef long CONSZ; /* size in which constants are converted */
typedef long OFFSZ;
/* default is byte addressing */
/* BITOOR(x) converts bit width x into address offset */
# ifndef BITOOR
# define BITOOR(x) ((x)/SZCHAR)
# endif
# ifdef SDB
# define STABS
# endif
# define NIL (NODE *)0
extern int dope[]; /* a vector containing operator information */
extern char *opst[]; /* a vector containing names for ops */
extern OFFSZ maxarg;
# define NCOSTS (NRGS+4)
/* in one-pass operation, define the tree nodes */
union ndu {
struct {
int op;
int goal;
TWORD type;
int cst[NCOSTS];
short OFdummy;
char * name;
char pad[NCHNAM-sizeof(char *)]; /* padding hack! */
NODE *left;
NODE *right;
}in; /* interior node */
struct {
int op;
int goal;
TWORD type;
int cst[NCOSTS];
short OFdummy;
char * name;
char pad[NCHNAM-sizeof(char *)]; /* padding hack! */
CONSZ lval;
int rval;
}tn; /* terminal node */
struct {
int op;
int goal;
TWORD type;
int cst[NCOSTS];
short OFdummy;
int label; /* for use with branching */
int lop; /* the opcode being branched on */
}bn; /* branch node */
struct {
int op;
int goal;
TWORD type;
int cst[NCOSTS];
OFFSZ stsize; /* sizes of structure objects */
short stalign; /* alignment of structure objects */
OFFSZ argsize; /* size of argument list for call */
}stn; /* structure node */
struct {
int op;
int goal;
TWORD type;
int cdim;
int csiz;
}fn; /* front node */
struct {
/* this structure is used when a floating point constant
is being computed */
int op;
int goal;
TWORD type;
int cdim;
int csiz;
double dval;
}fpn; /* floating point node */
};

View File

@ -0,0 +1,237 @@
# include "macdefs.h"
# include "manifest.h"
/* code generation goals, used in table entries */
# define FOREFF 01 /* compute for effects only */
# define INREG 02 /* compute into a register */
# define FORCC 04 /* compute for condition codes only */
/* types of operators and shapes; optab.tyop, optab.ltype optab.rtype */
# define TCHAR 01
# define TUCHAR 0100
# define TSHORT 02
# define TUSHORT 0200
# define TLONG 010
# define TULONG 01000
/* make INT match SHORT, LONG, or both depending on NOSHORT, NOLONG */
# define urTINT 04
# define urTUNSIGNED 0400
# ifdef NOSHORT
/* shorts == ints */
# ifdef NOLONG
/* longs == ints */
# define TINT (urTINT|TSHORT|TLONG)
# define TUNSIGNED (urTUNSIGNED|TUSHORT|TULONG)
# else
/* longs != ints, and shorts == ints */
# define TINT (urTINT|TSHORT)
# define TUNSIGNED (urTUNSIGNED|TUSHORT)
# endif
# else
/* shorts != ints */
# ifdef NOLONG
/* longs == ints */
# define TINT (urTINT|TLONG)
# define TUNSIGNED (urTUNSIGNED|TULONG)
# else
/* longs, shorts, and ints all distinct */
# define TINT urTINT
# define TUNSIGNED urTUNSIGNED
# endif
# endif
# define TDOUBLE 040
/* handle floats: match doubles if ONEFLOAT */
# ifdef ONEFLOAT
/* floats are the same as doubles in this case */
# define TFLOAT (TDOUBLE|020)
# else
# define TFLOAT 020
# endif
# define TSTRUCT 02000 /* structure or union */
# define TPOINT 04000
# define TPOINT2 010000
# define TVOID 020000
# define TANY 077777 /* matches anything within reason */
/* 0100000 (SPTYPE) is reserved for matches */
/* reclamation cookies */
# define RLEFT 0x0001
# define RRIGHT 0x0002
# define RESC1 0x0004
# define RESC2 0x0008
# define RESC3 0x0010
# define RESC4 0x0020
# define RESCC 0x0040
# define RNOP 0x0080 /* DANGER: can cause loops.. */
# define RNULL 0x0100 /* clobber result */
# define RHIGHT 0x0200
# define RLOW 0x0400
/* needs */
# define NREG 01
# define NMASK 0777
# define LSHARE 0x1000 /* share left register */
# define RSHARE 0x2000 /* share right register */
# define LPREF 0x4000 /* prefer left register, if any */
# define RPREF 0x8000 /* prefer right register, if any */
#define NPAIR 0x400 /* need Pair */
#define NQUAD 0x200 /* need Quadrupel */
# define NCOUNT 0x000f /* allocate registers in shorts*/
# define PCOUNT 0x00f0 /* allocate registers in pairs */
# define QCOUNT 0x0f00 /* allocate registers in quads */
/* register allocation */
extern int busy[];
# define INFINITY 10000
extern NODE node[];
typedef struct shape SHAPE;
/* special shapes (enforced by making costs high) */
# define SPECIAL 0170000
# define SPTYPE 0100000
# define STMASK 070000
# define SVAL 010000 /* positive constant value */
# define SNVAL 020000 /* negative constant value */
# define SRANGE0 030000 /* positive range [0, 2**mm - 1] */
# define SSRANGE 040000 /* signed range [-2**mm, 2**mm] */
# define NACON 050000 /* nameless contant */
# define SUSER 070000 /* user's cost function */
# define SVMASK 07777 /* shape value mask */
extern struct shape {
int op; /* operator */
SHAPE *sl; /* pointers to left- and right-hand shape */
SHAPE *sr;
int sh; /* flags for special shape and type matches */
int sc; /* cost of applying this shape */
} shapes[];
extern SHAPE *pshape[];
typedef struct optab OPTAB;
struct optab {
int op; /* operator */
int tyop; /* type of the operator node itself */
OPTAB *nextop;
SHAPE **lshape; /* pointer to pointer to left shape */
int ltype; /* type of left shape */
SHAPE **rshape; /* likewise for the right shape */
int rtype;
int needs;
int rewrite;
char *cstring;
int cost;
int lcount; /* number of times left used */
/*
int rcount; /* number of times right used */
int stinline; /* line number in stin file */
};
extern OPTAB
*match(),
*ophead[],
table[];
extern NODE resc[];
extern OFFSZ tmpoff;
extern OFFSZ maxboff;
extern OFFSZ maxtemp;
extern int ftnno;
extern int sideff;
extern NODE
*eread(),
*talloc(),
*ind2type(),
*tcopy(),
*getadr(),
*getlr();
extern OFFSZ
argsize(),
freetemp();
# define getlt(p,t) ((t)==LTYPE?p:p->in.left)
# define getlo(p,o) (getlt(p,optype(o)))
# define getl(p) (getlo(p,p->tn.op))
# define getrt(p,t) ((t)==BITYPE?p->in.right:p)
# define getro(p,o) (getrt(p,optype(o)))
# define getr(p) (getro(p,p->tn.op))
extern CONSZ rdin();
extern char *rnames[];
extern int lineno;
extern char ftitle[];
extern int fldshf, fldsz;
extern int lflag, udebug, e2debug, odebug, rdebug, radebug, sdebug;
extern int fast; /* try to make the compiler run faster */
#ifndef callchk
#define callchk(x) allchk()
#endif
#ifndef callreg
/* try to number so results returned in 0 */
#define callreg(x) ( x->in.type == TDOUBLE ? 0 : 2 )
#endif
#ifndef szty
/* it would be nice if number of registers to hold type t were 1 */
/* on most machines, this will be overridden in macdefs.h */
# define szty(t) 1
#endif
#ifndef PUTCHAR
# define PUTCHAR(x) putchar(x)
#endif
# define CEFF (NRGS+1)
# define CTEMP (NRGS+2)
# define CCC (NRGS+3)
/* the assumption is that registers 0 through NRGS-1 are scratch */
/* the others are real */
/* some are used for args and temps, etc... */
# define istreg(r) ((r)<NRGS)
typedef struct inst INST;
struct inst {
NODE *p;
OPTAB *q;
int goal;
};
# define NINS 300
extern INST inst[NINS];
extern nins;
/* definitions of strategies legal for ops */
# define STORE 01
# define LTOR 02
# define RTOL 04
/* shape matching */
# ifndef NSHP
# define NSHP 20
# endif
typedef SHAPE *SHTABLE[2][NSHP];
extern SHTABLE sha;