sequences of PUSHes to a single STACKADJUST followed by STOREs. This should dramatically improve code on stack-unfriendly architectures like MIPS.
		
			
				
	
	
		
			161 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef BURG_INCLUDED
 | |
| #define BURG_INCLUDED
 | |
| 
 | |
| #include "em_arith.h"
 | |
| #include "stringlist.h"
 | |
| #include "array.h"
 | |
| 
 | |
| extern char* stringf(char* fmt, ...);
 | |
| 
 | |
| typedef enum
 | |
| {
 | |
| 	TERM = 1,
 | |
| 	NONTERM,
 | |
| 	REG,
 | |
| 	REGCLASS
 | |
| } Kind;
 | |
| typedef struct rule* Rule;
 | |
| typedef struct term* Term;
 | |
| 
 | |
| enum
 | |
| {
 | |
| 	CONSTRAINT_EQUALS,
 | |
| 	CONSTRAINT_CORRUPTED_ATTR,
 | |
| 	CONSTRAINT_PRESERVED,
 | |
| };
 | |
| 
 | |
| struct constraint
 | |
| {
 | |
| 	int type;
 | |
| 	const char* left;
 | |
| 	const char* right;
 | |
| 	struct constraint* next;
 | |
| };
 | |
| 
 | |
| enum
 | |
| {
 | |
| 	PREDICATE_FUNCTION,
 | |
| 	PREDICATE_NODE,
 | |
| 	PREDICATE_NUMBER
 | |
| };
 | |
| 
 | |
| struct expr
 | |
| {
 | |
| 	int type;
 | |
| 	struct expr* next;
 | |
| 	union
 | |
| 	{
 | |
| 		const char* name;
 | |
| 		arith number;
 | |
| 	} u;
 | |
| };
 | |
| 
 | |
| struct terminfo
 | |
| {
 | |
| 	const char* name;
 | |
| 	const char* label;
 | |
| 	const char* attr;
 | |
| };
 | |
| 
 | |
| struct reg
 | |
| {
 | |
| 	const char* name;          /* friendly register name */
 | |
| 	int number;                /* identifying number */
 | |
| 	uint32_t attrs;            /* bitfield of register attributes */
 | |
| 	struct stringlist* names;  /* register names */
 | |
| 	ARRAYOF(struct reg) aliases; /* registers that this one aliases */
 | |
| };
 | |
| 
 | |
| struct regattr
 | |
| {
 | |
| 	const char* name;      /* class name */
 | |
| 	int number;            /* identifying number */
 | |
| };
 | |
| 
 | |
| extern void option(const char* name);
 | |
| extern struct reg* makereg(const char* name);
 | |
| extern void setregnames(struct reg* reg, struct stringlist* names);
 | |
| extern void addregattr(struct reg* reg, const char* regattr);
 | |
| extern void addregaliases(struct reg* reg, struct stringlist* aliases);
 | |
| extern struct regattr* getregattr(const char* name);
 | |
| 
 | |
| struct term
 | |
| { /* terminals: */
 | |
| 	char* name; /* terminal name */
 | |
| 	Kind kind; /* TERM */
 | |
| 	int esn; /* external symbol number */
 | |
| 	int arity; /* operator arity */
 | |
| 	Term link; /* next terminal in esn order */
 | |
| 	Rule rules; /* rules whose pattern starts with term */
 | |
| };
 | |
| 
 | |
| typedef struct nonterm* Nonterm;
 | |
| struct nonterm
 | |
| { /* non-terminals: */
 | |
| 	char* name;       /* non-terminal name */
 | |
| 	Kind kind;        /* NONTERM */
 | |
| 	int number;       /* identifying number */
 | |
| 	int lhscount;     /* # times nt appears in a rule lhs */
 | |
| 	int reached;      /* 1 iff reached from start non-terminal */
 | |
| 	Rule rules;       /* rules w/non-terminal on lhs */
 | |
| 	Rule chain;       /* chain rules w/non-terminal on rhs */
 | |
| 	Nonterm link;     /* next terminal in number order */
 | |
| 	bool is_fragment; /* these instructions are all fragments */
 | |
| };
 | |
| extern void* lookup(const char* name);
 | |
| extern Nonterm nonterm(const char* id, bool allocate);
 | |
| extern Term term(const char* id, int esn);
 | |
| 
 | |
| typedef struct tree* Tree;
 | |
| struct tree
 | |
| { /* tree patterns: */
 | |
| 	void* op;           /* a terminal or non-terminal */
 | |
| 	const char* label;  /* user label for this node */
 | |
| 	Tree left, right;   /* operands */
 | |
| 	int nterms;         /* number of terminal nodes in this tree */
 | |
| 	struct regattr* attr; /* input register attribute */
 | |
| };
 | |
| extern Tree tree(const struct terminfo* ti, Tree left, Tree right);
 | |
| 
 | |
| struct rule
 | |
| { /* rules: */
 | |
| 	Nonterm lhs;             /* lefthand side non-terminal */
 | |
| 	Tree pattern;            /* rule pattern */
 | |
| 	int lineno;              /* line number where allocated */
 | |
| 	int ern;                 /* external rule number */
 | |
| 	int packed;              /* packed external rule number */
 | |
| 	int cost;                /* associated cost */
 | |
| 	const char* label;       /* label for LHS */
 | |
| 	struct regattr* attr;    /* register attribute of result */
 | |
| 	Rule link;               /* next rule in ern order */
 | |
| 	Rule next;               /* next rule with same pattern root */
 | |
| 	Rule chain;              /* next chain rule with same rhs */
 | |
| 	Rule decode;             /* next rule with same lhs */
 | |
| 	Rule kids;               /* next rule with same burm_kids pattern */
 | |
| 	ARRAYOF(struct expr) prefers;  /* C predicates */
 | |
| 	ARRAYOF(struct expr) requires; /* C predicates */
 | |
| 	ARRAYOF(struct constraint) constraints; /* register constraints */
 | |
| 	struct stringlist code;  /* compiler output code strings */
 | |
| };
 | |
| extern Rule rule(const struct terminfo* ti, Tree pattern);
 | |
| extern int maxcost; /* maximum cost */
 | |
| 
 | |
| /* gram.y: */
 | |
| void yyerror(char* fmt, ...);
 | |
| int yyparse(void);
 | |
| void yywarn(char* fmt, ...);
 | |
| extern int errcnt;
 | |
| extern FILE* infp;
 | |
| extern FILE* outfp;
 | |
| extern FILE* hdrfp;
 | |
| 
 | |
| /* Stupid flex imports --- why mo header file? */
 | |
| 
 | |
| extern FILE* yyin;
 | |
| extern int yylineno;
 | |
| 
 | |
| extern void printlineno(void);
 | |
| 
 | |
| #include "mcgg.h"
 | |
| 
 | |
| #endif
 |