add LCC - a better C-Compiler for WEGA
This commit is contained in:
parent
87526ef35a
commit
e300d3d2c5
|
|
@ -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 */
|
||||
|
||||
};
|
||||
|
|
@ -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;
|
||||
Loading…
Reference in New Issue