We now record the code fragments to be emitted by each rule.
This commit is contained in:
parent
717b77dd0a
commit
7c028bdd45
|
@ -48,7 +48,7 @@ static void queue_instructions(struct ir* ir, int goal)
|
|||
for (i=0; nts[i]; i++)
|
||||
queue_instructions(children[i], nts[i]);
|
||||
|
||||
printf("selected insn %d: %s\n", ruleno, burm_string[ruleno]);
|
||||
tracef('I', "I: $%d selected insn %d: %s\n", ir->id, ruleno, burm_string[ruleno]);
|
||||
}
|
||||
|
||||
static void select_instructions(struct basicblock* bb)
|
||||
|
|
|
@ -53,18 +53,18 @@ PATTERNS
|
|||
|
||||
reg = in:LOCAL4
|
||||
outs out:GPR
|
||||
emit "add %out, fp, #%in.ivalue"
|
||||
emit "add %out, fp, #%in"
|
||||
cost 4;
|
||||
|
||||
address = in:LOCAL4
|
||||
fragment "[fp, #%in.ivalue]";
|
||||
fragment "[fp, #%in]";
|
||||
|
||||
|
||||
/* Memory addressing modes */
|
||||
|
||||
address = ADD4(addr:reg, offset:CONST)
|
||||
ins addr:GPR
|
||||
fragment "[%addr, #%offset.ivalue]";
|
||||
fragment "[%addr, #%offset]";
|
||||
|
||||
address = addr:reg
|
||||
ins addr:GPR
|
||||
|
@ -74,12 +74,12 @@ PATTERNS
|
|||
/* Branches */
|
||||
|
||||
JUMP(addr:BLOCK4)
|
||||
emit "b %addr.bvalue"
|
||||
emit "b %addr"
|
||||
cost 4;
|
||||
|
||||
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
|
||||
emit "beq %trueblock.bvalue"
|
||||
emit "bne %falseblock.bvalue"
|
||||
emit "beq %true"
|
||||
emit "bne %false"
|
||||
cost 8;
|
||||
|
||||
|
||||
|
@ -136,15 +136,15 @@ PATTERNS
|
|||
|
||||
reg = value:LABEL4
|
||||
outs out:GPR
|
||||
emit "adr %out, %value.lvalue"
|
||||
emit "adr %out, %value"
|
||||
cost 4;
|
||||
|
||||
reg = value:BLOCK4
|
||||
outs out:GPR
|
||||
emit "adr %out, %value.bvalue"
|
||||
emit "adr %out, %value"
|
||||
cost 4;
|
||||
|
||||
reg = value:CONST4
|
||||
outs out:GPR
|
||||
emit "ldr %out, #value.lvalue"
|
||||
emit "ldr %out, #value"
|
||||
cost 4;
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
%{
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include "iburg.h"
|
||||
|
||||
#define YYDEBUG 1
|
||||
|
||||
static char rcsid[] = "$Id$";
|
||||
extern int yylex(void);
|
||||
|
||||
static int nextern = 1;
|
||||
|
||||
%}
|
||||
|
@ -33,15 +35,16 @@ static int nextern = 1;
|
|||
%token <n> INT
|
||||
%token <string> ID
|
||||
%token <string> CFRAGMENT
|
||||
%token <string> STRING
|
||||
%token <string> QFRAGMENT
|
||||
|
||||
%type <n> cost
|
||||
%type <rule> pattern
|
||||
%type <stringlist> stringlist
|
||||
%type <stringlist> when
|
||||
%type <rule> emit
|
||||
%type <stringlist> cfragments
|
||||
%type <stringlist> qfragments
|
||||
%type <tree> rhs
|
||||
%type <stringpair> labelledid
|
||||
%%
|
||||
|
||||
spec
|
||||
: PATTERNS patterns
|
||||
;
|
||||
|
@ -50,17 +53,15 @@ patterns
|
|||
: /* nothing */
|
||||
| patterns pattern ';'
|
||||
| patterns ';'
|
||||
| patterns error ';' { yyerrok; }
|
||||
;
|
||||
|
||||
pattern
|
||||
: ID '=' rhs { nonterm($1); $$ = rule($1, $3, nextern++); }
|
||||
| rhs { $$ = rule("stmt", $1, nextern++); }
|
||||
| pattern WHEN stringlist { $$ = $1; $$->when = $3; }
|
||||
| pattern WHEN cfragments { $$ = $1; $$->when = $3; }
|
||||
| pattern INS ins { $$ = $1; }
|
||||
| pattern OUTS outs { $$ = $1; }
|
||||
| pattern EMIT STRING { $$ = $1; }
|
||||
| pattern FRAGMENT STRING { $$ = $1; }
|
||||
| emit { $$ = $1; }
|
||||
| pattern COST INT { $$ = $1; $$->cost = $3; }
|
||||
;
|
||||
|
||||
|
@ -75,14 +76,9 @@ labelledid
|
|||
| ID ':' ID { $$[0] = $1; $$[1] = $3; }
|
||||
;
|
||||
|
||||
when
|
||||
cfragments
|
||||
: /* nothing */ { $$ = NULL; }
|
||||
| WHEN stringlist { $$ = $2; }
|
||||
;
|
||||
|
||||
stringlist
|
||||
: /* nothing */ { $$ = NULL; }
|
||||
| CFRAGMENT stringlist { $$ = pushstring($1, $2); }
|
||||
| CFRAGMENT cfragments { $$ = pushstring($1, $2); }
|
||||
;
|
||||
|
||||
ins
|
||||
|
@ -100,7 +96,18 @@ outs
|
|||
;
|
||||
|
||||
out
|
||||
: ID ':' ID
|
||||
: ID
|
||||
| ID ':' ID
|
||||
;
|
||||
|
||||
emit
|
||||
: pattern EMIT qfragments { $$ = $1; $$->code = $3; $$->is_fragment = false; }
|
||||
| pattern FRAGMENT qfragments { $$ = $1; $$->code = $3; $$->is_fragment = true; }
|
||||
;
|
||||
|
||||
qfragments
|
||||
: QFRAGMENT { $$ = pushstring($1, NULL); }
|
||||
| QFRAGMENT qfragments { $$ = pushstring($1, $2); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
@ -45,6 +46,8 @@ static void emitstruct(Nonterm nts, int ntnumber);
|
|||
static void emitterms(Term terms);
|
||||
static void emittest(Tree t, char* v, char* suffix);
|
||||
|
||||
extern int yy_flex_debug;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int c, i;
|
||||
|
@ -57,10 +60,11 @@ int main(int argc, char* argv[])
|
|||
|
||||
infp = stdin;
|
||||
outfp = stdout;
|
||||
yy_flex_debug = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int opt = getopt(argc, argv, "p:i:o:y");
|
||||
int opt = getopt(argc, argv, "p:i:o:yf");
|
||||
if (opt == -1)
|
||||
break;
|
||||
|
||||
|
@ -95,6 +99,12 @@ int main(int argc, char* argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
yy_flex_debug = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
yyerror("usage: %s [-p prefix] < input > output\n", argv[0]);
|
||||
exit(1);
|
||||
|
|
|
@ -67,6 +67,8 @@ struct rule
|
|||
Rule decode; /* next rule with same lhs */
|
||||
Rule kids; /* next rule with same burm_kids pattern */
|
||||
Stringlist when; /* C predicate string */
|
||||
Stringlist code; /* compiler output code strings */
|
||||
bool is_fragment; /* does this rule generate an instruction fragment? */
|
||||
};
|
||||
extern Rule rule(char* id, Tree pattern, int ern);
|
||||
extern int maxcost; /* maximum cost */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
%{
|
||||
#include <stdbool.h>
|
||||
#include "iburg.h"
|
||||
#include "y.tab.h"
|
||||
|
||||
|
@ -9,18 +10,14 @@ static int braces = 0;
|
|||
%option nodefault
|
||||
%option noyywrap
|
||||
%option yylineno
|
||||
%option debug
|
||||
|
||||
%x CSTRING
|
||||
%x QSTRING
|
||||
%x ECHO
|
||||
|
||||
%%
|
||||
|
||||
<INITIAL>"%{" { printlineno(); BEGIN(ECHO); }
|
||||
|
||||
<ECHO>"%}" BEGIN(INITIAL);
|
||||
<ECHO>[%\n] fputc(yytext[0], outfp);
|
||||
<ECHO>[^%\n]* fputs(yytext, outfp);
|
||||
|
||||
<INITIAL>"{" {
|
||||
yylval.string = ""; //stringf("#line %d\n", yylineno);
|
||||
braces = 1;
|
||||
|
@ -50,6 +47,19 @@ static int braces = 0;
|
|||
return CFRAGMENT;
|
||||
}
|
||||
|
||||
<INITIAL>"\"" BEGIN(QSTRING);
|
||||
<QSTRING>"\"" BEGIN(INITIAL);
|
||||
|
||||
<QSTRING>%[a-zA-Z_]+ {
|
||||
yylval.string = strdup(yytext);
|
||||
return QFRAGMENT;
|
||||
}
|
||||
|
||||
<QSTRING>[^\r\n%"]+ {
|
||||
yylval.string = strdup(yytext);
|
||||
return QFRAGMENT;
|
||||
}
|
||||
|
||||
"%%" return PPERCENT;
|
||||
"%term" return TERMINAL;
|
||||
"%start" return START;
|
||||
|
@ -62,7 +72,6 @@ static int braces = 0;
|
|||
"fragment" return FRAGMENT;
|
||||
"cost" return COST;
|
||||
|
||||
\"[^"\n]*\" { yylval.string = strdup(yytext); return STRING; }
|
||||
[A-Za-z_][A-Za-z0-9_]* { yylval.string = strdup(yytext); return ID; }
|
||||
[0-9]+ { yylval.n = atoi(yytext); return INT; }
|
||||
[ \t\r\n]* ;
|
||||
|
|
Loading…
Reference in a new issue