We now record the code fragments to be emitted by each rule.

This commit is contained in:
David Given 2016-09-25 00:21:46 +02:00
parent 717b77dd0a
commit 7c028bdd45
6 changed files with 63 additions and 35 deletions

View file

@ -48,7 +48,7 @@ static void queue_instructions(struct ir* ir, int goal)
for (i=0; nts[i]; i++) for (i=0; nts[i]; i++)
queue_instructions(children[i], nts[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) static void select_instructions(struct basicblock* bb)

View file

@ -53,18 +53,18 @@ PATTERNS
reg = in:LOCAL4 reg = in:LOCAL4
outs out:GPR outs out:GPR
emit "add %out, fp, #%in.ivalue" emit "add %out, fp, #%in"
cost 4; cost 4;
address = in:LOCAL4 address = in:LOCAL4
fragment "[fp, #%in.ivalue]"; fragment "[fp, #%in]";
/* Memory addressing modes */ /* Memory addressing modes */
address = ADD4(addr:reg, offset:CONST) address = ADD4(addr:reg, offset:CONST)
ins addr:GPR ins addr:GPR
fragment "[%addr, #%offset.ivalue]"; fragment "[%addr, #%offset]";
address = addr:reg address = addr:reg
ins addr:GPR ins addr:GPR
@ -74,12 +74,12 @@ PATTERNS
/* Branches */ /* Branches */
JUMP(addr:BLOCK4) JUMP(addr:BLOCK4)
emit "b %addr.bvalue" emit "b %addr"
cost 4; cost 4;
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4)) CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
emit "beq %trueblock.bvalue" emit "beq %true"
emit "bne %falseblock.bvalue" emit "bne %false"
cost 8; cost 8;
@ -136,15 +136,15 @@ PATTERNS
reg = value:LABEL4 reg = value:LABEL4
outs out:GPR outs out:GPR
emit "adr %out, %value.lvalue" emit "adr %out, %value"
cost 4; cost 4;
reg = value:BLOCK4 reg = value:BLOCK4
outs out:GPR outs out:GPR
emit "adr %out, %value.bvalue" emit "adr %out, %value"
cost 4; cost 4;
reg = value:CONST4 reg = value:CONST4
outs out:GPR outs out:GPR
emit "ldr %out, #value.lvalue" emit "ldr %out, #value"
cost 4; cost 4;

View file

@ -1,12 +1,14 @@
%{ %{
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include <limits.h> #include <limits.h>
#include "iburg.h" #include "iburg.h"
#define YYDEBUG 1 #define YYDEBUG 1
static char rcsid[] = "$Id$"; extern int yylex(void);
static int nextern = 1; static int nextern = 1;
%} %}
@ -33,15 +35,16 @@ static int nextern = 1;
%token <n> INT %token <n> INT
%token <string> ID %token <string> ID
%token <string> CFRAGMENT %token <string> CFRAGMENT
%token <string> STRING %token <string> QFRAGMENT
%type <n> cost
%type <rule> pattern %type <rule> pattern
%type <stringlist> stringlist %type <rule> emit
%type <stringlist> when %type <stringlist> cfragments
%type <stringlist> qfragments
%type <tree> rhs %type <tree> rhs
%type <stringpair> labelledid %type <stringpair> labelledid
%% %%
spec spec
: PATTERNS patterns : PATTERNS patterns
; ;
@ -50,17 +53,15 @@ patterns
: /* nothing */ : /* nothing */
| patterns pattern ';' | patterns pattern ';'
| patterns ';' | patterns ';'
| patterns error ';' { yyerrok; }
; ;
pattern pattern
: ID '=' rhs { nonterm($1); $$ = rule($1, $3, nextern++); } : ID '=' rhs { nonterm($1); $$ = rule($1, $3, nextern++); }
| rhs { $$ = rule("stmt", $1, nextern++); } | rhs { $$ = rule("stmt", $1, nextern++); }
| pattern WHEN stringlist { $$ = $1; $$->when = $3; } | pattern WHEN cfragments { $$ = $1; $$->when = $3; }
| pattern INS ins { $$ = $1; } | pattern INS ins { $$ = $1; }
| pattern OUTS outs { $$ = $1; } | pattern OUTS outs { $$ = $1; }
| pattern EMIT STRING { $$ = $1; } | emit { $$ = $1; }
| pattern FRAGMENT STRING { $$ = $1; }
| pattern COST INT { $$ = $1; $$->cost = $3; } | pattern COST INT { $$ = $1; $$->cost = $3; }
; ;
@ -75,14 +76,9 @@ labelledid
| ID ':' ID { $$[0] = $1; $$[1] = $3; } | ID ':' ID { $$[0] = $1; $$[1] = $3; }
; ;
when cfragments
: /* nothing */ { $$ = NULL; } : /* nothing */ { $$ = NULL; }
| WHEN stringlist { $$ = $2; } | CFRAGMENT cfragments { $$ = pushstring($1, $2); }
;
stringlist
: /* nothing */ { $$ = NULL; }
| CFRAGMENT stringlist { $$ = pushstring($1, $2); }
; ;
ins ins
@ -100,7 +96,18 @@ outs
; ;
out 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); }
; ;
%% %%

View file

@ -3,6 +3,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
@ -45,6 +46,8 @@ static void emitstruct(Nonterm nts, int ntnumber);
static void emitterms(Term terms); static void emitterms(Term terms);
static void emittest(Tree t, char* v, char* suffix); static void emittest(Tree t, char* v, char* suffix);
extern int yy_flex_debug;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int c, i; int c, i;
@ -57,10 +60,11 @@ int main(int argc, char* argv[])
infp = stdin; infp = stdin;
outfp = stdout; outfp = stdout;
yy_flex_debug = 0;
for (;;) for (;;)
{ {
int opt = getopt(argc, argv, "p:i:o:y"); int opt = getopt(argc, argv, "p:i:o:yf");
if (opt == -1) if (opt == -1)
break; break;
@ -95,6 +99,12 @@ int main(int argc, char* argv[])
break; break;
} }
case 'f':
{
yy_flex_debug = 1;
break;
}
default: default:
yyerror("usage: %s [-p prefix] < input > output\n", argv[0]); yyerror("usage: %s [-p prefix] < input > output\n", argv[0]);
exit(1); exit(1);

View file

@ -67,6 +67,8 @@ struct rule
Rule decode; /* next rule with same lhs */ Rule decode; /* next rule with same lhs */
Rule kids; /* next rule with same burm_kids pattern */ Rule kids; /* next rule with same burm_kids pattern */
Stringlist when; /* C predicate string */ 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 Rule rule(char* id, Tree pattern, int ern);
extern int maxcost; /* maximum cost */ extern int maxcost; /* maximum cost */

View file

@ -1,4 +1,5 @@
%{ %{
#include <stdbool.h>
#include "iburg.h" #include "iburg.h"
#include "y.tab.h" #include "y.tab.h"
@ -9,18 +10,14 @@ static int braces = 0;
%option nodefault %option nodefault
%option noyywrap %option noyywrap
%option yylineno %option yylineno
%option debug
%x CSTRING %x CSTRING
%x QSTRING
%x ECHO %x ECHO
%% %%
<INITIAL>"%{" { printlineno(); BEGIN(ECHO); }
<ECHO>"%}" BEGIN(INITIAL);
<ECHO>[%\n] fputc(yytext[0], outfp);
<ECHO>[^%\n]* fputs(yytext, outfp);
<INITIAL>"{" { <INITIAL>"{" {
yylval.string = ""; //stringf("#line %d\n", yylineno); yylval.string = ""; //stringf("#line %d\n", yylineno);
braces = 1; braces = 1;
@ -50,6 +47,19 @@ static int braces = 0;
return CFRAGMENT; 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; "%%" return PPERCENT;
"%term" return TERMINAL; "%term" return TERMINAL;
"%start" return START; "%start" return START;
@ -62,7 +72,6 @@ static int braces = 0;
"fragment" return FRAGMENT; "fragment" return FRAGMENT;
"cost" return COST; "cost" return COST;
\"[^"\n]*\" { yylval.string = strdup(yytext); return STRING; }
[A-Za-z_][A-Za-z0-9_]* { yylval.string = strdup(yytext); return ID; } [A-Za-z_][A-Za-z0-9_]* { yylval.string = strdup(yytext); return ID; }
[0-9]+ { yylval.n = atoi(yytext); return INT; } [0-9]+ { yylval.n = atoi(yytext); return INT; }
[ \t\r\n]* ; [ \t\r\n]* ;