Add a syntax to declare functions in a top table
Use the new syntax in the mips, pdp, powerpc tables to declare functions before calling them. These declarations prevent compiler warnings about implicitly declaring functions. They also provide prototypes of the function parameters. Also fix a warning in the powerpc table: use `bsearch(...) != NULL` to avoid converting the pointer from bsearch() to an int. The syntax for topgen is a block `{...}` among the parameters in the top table. It looks like the syntax of LLgen, but topgen doesn't allow nested blocks, so declarations like `struct whatever {...};` don't work. The token OPEN_BRACKET that begins a declaration_block doesn't conflict with the LETTER that begins a parameter_line or the '%' that begins a separator. Because a block writes a #line command to gen.h, a parameter line now also writes a #line command to gen.h, so it doesn't get a wrong line number from a previous block.
This commit is contained in:
parent
777d0abb00
commit
51e34acab1
|
@ -4,6 +4,10 @@
|
||||||
MAXOP 5;
|
MAXOP 5;
|
||||||
LABEL_STARTER '.';
|
LABEL_STARTER '.';
|
||||||
|
|
||||||
|
{
|
||||||
|
int plus(const char *, const char *, const char *);
|
||||||
|
}
|
||||||
|
|
||||||
%%;
|
%%;
|
||||||
|
|
||||||
X, Y, Z { TRUE };
|
X, Y, Z { TRUE };
|
||||||
|
|
|
@ -6,6 +6,13 @@ MAXOP 2;
|
||||||
LABEL_STARTER 'I';
|
LABEL_STARTER 'I';
|
||||||
OPC_TERMINATOR ' ';
|
OPC_TERMINATOR ' ';
|
||||||
|
|
||||||
|
{
|
||||||
|
int no_side_effects(char *);
|
||||||
|
int is_register(char *);
|
||||||
|
int is_scratchreg(char *);
|
||||||
|
int carry_dead(char *);
|
||||||
|
}
|
||||||
|
|
||||||
%%;
|
%%;
|
||||||
|
|
||||||
/* useful addressing modes: */
|
/* useful addressing modes: */
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
MAXOP 5;
|
MAXOP 5;
|
||||||
LABEL_STARTER '.';
|
LABEL_STARTER '.';
|
||||||
|
|
||||||
|
{
|
||||||
|
int not_using_sp(const char *);
|
||||||
|
int positive(const char *);
|
||||||
|
int lift(const char *);
|
||||||
|
int plus(const char *, const char *, const char *);
|
||||||
|
}
|
||||||
|
|
||||||
%%;
|
%%;
|
||||||
|
|
||||||
L1, L2, L3, L4, L5 { not_using_sp(VAL) };
|
L1, L2, L3, L4, L5 { not_using_sp(VAL) };
|
||||||
|
@ -160,7 +167,7 @@ static int liftcmp(const void *a, const void *b) {
|
||||||
int lift(const char *s) {
|
int lift(const char *s) {
|
||||||
return bsearch(&s, liftables,
|
return bsearch(&s, liftables,
|
||||||
sizeof(liftables) / sizeof(liftables[0]),
|
sizeof(liftables) / sizeof(liftables[0]),
|
||||||
sizeof(liftables[0]), liftcmp);
|
sizeof(liftables[0]), liftcmp) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,14 @@ extern void error(char *s, char* s1);
|
||||||
|
|
||||||
optim_description
|
optim_description
|
||||||
{ struct symtab *p; } :
|
{ struct symtab *p; } :
|
||||||
SPACE* parameter_line*
|
SPACE* parameters
|
||||||
{ p = findident("MAXOP",LOOKING,&deftable);
|
{ p = findident("MAXOP",LOOKING,&deftable);
|
||||||
if (p == 0) maxoperand = 2; /* default */
|
if (p == 0) maxoperand = 2; /* default */
|
||||||
else maxoperand = p->s_num;
|
else maxoperand = p->s_num;
|
||||||
}
|
}
|
||||||
separator SPACE* mode_definitions
|
separator SPACE* mode_definitions
|
||||||
separator SPACE* patterns
|
separator SPACE* patterns
|
||||||
separator
|
separator
|
||||||
{ register int c;
|
{ register int c;
|
||||||
fprintf(genc, linedir, lineno, inpfile);
|
fprintf(genc, linedir, lineno, inpfile);
|
||||||
while ((c = getc(input)) != EOF) {
|
while ((c = getc(input)) != EOF) {
|
||||||
|
@ -57,17 +57,25 @@ optim_description
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
parameters :
|
||||||
|
[ parameter_line | declaration_block ]*
|
||||||
|
;
|
||||||
|
|
||||||
parameter_line
|
parameter_line
|
||||||
{ struct symtab *p;} :
|
{ struct symtab *p;
|
||||||
|
int lin;
|
||||||
|
} :
|
||||||
identifier
|
identifier
|
||||||
{ p = findident(idbuf,ENTERING,&deftable);}
|
{ p = findident(idbuf,ENTERING,&deftable);}
|
||||||
SPACE
|
SPACE
|
||||||
|
{ lin = lineno;}
|
||||||
value
|
value
|
||||||
{ p->s_num = atoi(buf);}
|
{ p->s_num = atoi(buf);}
|
||||||
/* This action in fact only needed for MAXOP */
|
/* This action in fact only needed for MAXOP */
|
||||||
LINE_TERMINATOR
|
LINE_TERMINATOR
|
||||||
SPACE*
|
SPACE*
|
||||||
{ fprintf(genh,"#define %s %s\n",p->s_name,buf);}
|
{ fprintf(genh, linedir, lin, inpfile);
|
||||||
|
fprintf(genh,"#define %s %s\n",p->s_name,buf);}
|
||||||
;
|
;
|
||||||
|
|
||||||
value
|
value
|
||||||
|
@ -89,6 +97,27 @@ value
|
||||||
{ *p1 = '\0';}
|
{ *p1 = '\0';}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
declaration_block :
|
||||||
|
OPEN_BRACKET
|
||||||
|
{ fprintf(genh, linedir, lineno, inpfile);}
|
||||||
|
[
|
||||||
|
[ LINE_TERMINATOR
|
||||||
|
| OPERAND_SEPARATOR
|
||||||
|
| PATTERN_SEPARATOR
|
||||||
|
| INSTRUCTION_SEPARATOR
|
||||||
|
| SPACE
|
||||||
|
| LETTER
|
||||||
|
| DIGIT
|
||||||
|
| OTHER
|
||||||
|
| '%'
|
||||||
|
]
|
||||||
|
{ putc(dot.t_attrib, genh);}
|
||||||
|
]*
|
||||||
|
CLOSE_BRACKET
|
||||||
|
SPACE*
|
||||||
|
{ putc('\n', genh);}
|
||||||
|
;
|
||||||
|
|
||||||
mode_definitions
|
mode_definitions
|
||||||
{ int lin; } :
|
{ int lin; } :
|
||||||
{ fputs("tok_chk(varno) {\n\tint r;\n", genc);
|
{ fputs("tok_chk(varno) {\n\tint r;\n", genc);
|
||||||
|
|
Loading…
Reference in a new issue