Predicates can now take numeric arguments. The PowerPC predicates have been

turned into generic ones (as they'll be useful everywhere). Node arguments for
predicates require the '%' prefix for consistency. Hex numbers are permitted.
This commit is contained in:
David Given 2016-10-09 12:32:36 +02:00
parent d75cc0a663
commit cfe5312fcc
9 changed files with 101 additions and 46 deletions

View file

@ -8,8 +8,9 @@
extern void burm_panic_cannot_match(NODEPTR_TYPE node); extern void burm_panic_cannot_match(NODEPTR_TYPE node);
extern bool burm_predicate_constant_signed_16_bit(struct burm_node* node); extern bool burm_predicate_signed_constant(struct burm_node* node, arith size);
extern bool burm_predicate_constant_is_zero(struct burm_node* node); extern bool burm_predicate_unsigned_constant(struct burm_node* node, arith size);
extern bool burm_predicate_specific_constant(struct burm_node* node, arith value);
/* vim: set sw=4 ts=4 expandtab : */ /* vim: set sw=4 ts=4 expandtab : */

View file

@ -1,19 +0,0 @@
#include "mcg.h"
bool burm_predicate_constant_signed_16_bit(struct burm_node* node)
{
struct ir* ir = node->ir;
assert(ir->opcode == IR_CONST);
return (ir->u.ivalue >= -0x8000) && (ir->u.ivalue <= 0x7fff);
}
bool burm_predicate_constant_is_zero(struct burm_node* node)
{
struct ir* ir = node->ir;
assert(ir->opcode == IR_CONST);
return (ir->u.ivalue == 0);
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -0,0 +1,32 @@
#include "mcg.h"
bool burm_predicate_signed_constant(struct burm_node* node, arith size)
{
struct ir* ir = node->ir;
arith pivot = 1<<(size-1);
arith mask = ~((1<<size) - 1);
assert(ir->opcode == IR_CONST);
return ((ir->u.ivalue + pivot) & mask) == 0;
}
bool burm_predicate_unsigned_constant(struct burm_node* node, arith size)
{
struct ir* ir = node->ir;
arith mask = ~((1<<size) - 1);
assert(ir->opcode == IR_CONST);
return (ir->u.ivalue & mask) == 0;
}
bool burm_predicate_specific_constant(struct burm_node* node, arith val)
{
struct ir* ir = node->ir;
assert(ir->opcode == IR_CONST);
return ir->u.ivalue == val;
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -111,7 +111,7 @@ PATTERNS
cost 1; cost 1;
STACKADJUST4(delta:CONST4) STACKADJUST4(delta:CONST4)
when constant_signed_16_bit(delta) when signed_constant(%delta, 16)
emit "addi sp, sp, $delta" emit "addi sp, sp, $delta"
cost 4; cost 4;
@ -167,7 +167,7 @@ PATTERNS
/* Memory addressing modes */ /* Memory addressing modes */
address = ADD4(addr:(int)reg, offset:CONST4) address = ADD4(addr:(int)reg, offset:CONST4)
when constant_signed_16_bit(offset) when signed_constant(%offset, 16)
emit "$offset(%addr)"; emit "$offset(%addr)";
address = addr:(int)reg address = addr:(int)reg
@ -218,7 +218,7 @@ PATTERNS
cost 4; cost 4;
cr:(cr)cr = COMPARES4(left:(int)reg, right:CONST4) cr:(cr)cr = COMPARES4(left:(int)reg, right:CONST4)
when constant_signed_16_bit(right) when signed_constant(%right, 16)
emit "cmpi %cr, 0, %left, $right" emit "cmpi %cr, 0, %left, $right"
cost 4; cost 4;
@ -227,23 +227,23 @@ PATTERNS
cost 4; cost 4;
cr:(cr)cr = COMPAREU4(left:(int)reg, right:CONST4) cr:(cr)cr = COMPAREU4(left:(int)reg, right:CONST4)
when constant_signed_16_bit(right) when signed_constant(%right, 16)
emit "cmpli %cr, 0, %left, $right" emit "cmpli %cr, 0, %left, $right"
cost 4; cost 4;
cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:(int)reg), result:CONST4) cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:(int)reg), result:CONST4)
when constant_is_zero(result) when specific_constant(%result, 0)
emit "cmp %cr, 0, %left, %right" emit "cmp %cr, 0, %left, %right"
cost 4; cost 4;
cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:CONST4), result:CONST4) cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:CONST4), result:CONST4)
when constant_is_zero(result) when specific_constant(%result, 0)
when constant_signed_16_bit(right) when signed_constant(%right, 16)
emit "cmpi %cr, 0, %left, $right" emit "cmpi %cr, 0, %left, $right"
cost 4; cost 4;
cr:(cr)cr = COMPARES4(COMPAREU4(left:(int)reg, right:(int)reg), result:CONST4) cr:(cr)cr = COMPARES4(COMPAREU4(left:(int)reg, right:(int)reg), result:CONST4)
when constant_is_zero(result) when specific_constant(%result, 0)
emit "cmpl %cr, 0, %left, %right" emit "cmpl %cr, 0, %left, %right"
cost 4; cost 4;
@ -280,7 +280,7 @@ PATTERNS
cost 4; cost 4;
out:(int)reg = ADD4(left:(int)reg, right:CONST4) out:(int)reg = ADD4(left:(int)reg, right:CONST4)
when constant_signed_16_bit(right) when signed_constant(%right, 16)
emit "addi %out, %left, $right" emit "addi %out, %left, $right"
cost 4; cost 4;

View file

@ -50,6 +50,7 @@ cprogram {
"+lib", "+lib",
"+yacc", "+yacc",
"modules/src/data+lib", "modules/src/data+lib",
"modules+headers",
} }
} }

View file

@ -13,8 +13,8 @@ extern int yylex(void);
%} %}
%union { %union {
int n; arith n;
char* string; const char* string;
Nonterm nonterm; Nonterm nonterm;
Tree tree; Tree tree;
Rule rule; Rule rule;
@ -44,16 +44,17 @@ extern int yylex(void);
%type <constraint> constraint %type <constraint> constraint
%type <constraint> constraints %type <constraint> constraints
%type <expr> predicate
%type <expr> predicate_arg
%type <expr> predicate_args
%type <nonterm> declaration %type <nonterm> declaration
%type <reg> register %type <reg> register
%type <rule> pattern
%type <rule> pattern_constraints %type <rule> pattern_constraints
%type <rule> pattern_emit %type <rule> pattern_emit
%type <rule> pattern
%type <stringlist> qfragments %type <stringlist> qfragments
%type <terminfo> terminfo %type <terminfo> terminfo
%type <tree> rhs %type <tree> rhs
%type <expr> predicate
%type <expr> predicate_args
%% %%
spec spec
@ -155,13 +156,23 @@ qfragments
; ;
predicate predicate
: ID '(' predicate_args ')' { $$ = calloc(1, sizeof *$$); $$->name = $1; $$->next = $3; } : ID '(' predicate_args ')' {
$$ = calloc(1, sizeof *$$);
$$->type = PREDICATE_FUNCTION;
$$->u.name = $1;
$$->next = $3;
}
; ;
predicate_args predicate_args
: /* nothing */ { $$ = NULL; } : /* nothing */ { $$ = NULL; }
| ID { $$ = calloc(1, sizeof *$$); $$->name = $1; } | predicate_arg { $$ = $1; }
| ID ',' predicate_args { $$ = calloc(1, sizeof *$$); $$->name = $1; $$->next = $3; } | predicate_arg ',' predicate_args { $$ = $1; $$->next = $3; }
;
predicate_arg
: '%' ID { $$ = calloc(1, sizeof *$$); $$->type = PREDICATE_NODE; $$->u.name = $2; }
| INT { $$ = calloc(1, sizeof *$$); $$->type = PREDICATE_NUMBER; $$->u.number = $1; }
; ;
%% %%

View file

@ -1004,21 +1004,36 @@ static void emit_predicate_expr(Rule r, struct expr* p)
{ {
bool first = true; bool first = true;
print("%1if (%Ppredicate_%s(", p->name); assert(p->type == PREDICATE_FUNCTION);
print("%1if (%Ppredicate_%s(", p->u.name);
p = p->next; p = p->next;
while (p) while (p)
{ {
uint32_t path = find_label(r->pattern, p->name, 0, NULL);
if (path == PATH_MISSING)
label_not_found(r, p->name);
if (!first) if (!first)
print(", "); print(", ");
else else
first = false; first = false;
print_path(path); switch (p->type)
{
case PREDICATE_NODE:
{
uint32_t path = find_label(r->pattern, p->u.name, 0, NULL);
if (path == PATH_MISSING)
label_not_found(r, p->u.name);
print_path(path);
break;
}
case PREDICATE_NUMBER:
{
print("%d", p->u.number);
break;
}
}
p = p->next; p = p->next;
} }

View file

@ -1,6 +1,7 @@
#ifndef BURG_INCLUDED #ifndef BURG_INCLUDED
#define BURG_INCLUDED #define BURG_INCLUDED
#include "em_arith.h"
#include "stringlist.h" #include "stringlist.h"
#include "array.h" #include "array.h"
@ -31,10 +32,22 @@ struct constraint
struct constraint* next; struct constraint* next;
}; };
enum
{
PREDICATE_FUNCTION,
PREDICATE_NODE,
PREDICATE_NUMBER
};
struct expr struct expr
{ {
const char* name; int type;
struct expr* next; struct expr* next;
union
{
const char* name;
arith number;
} u;
}; };
struct terminfo struct terminfo

View file

@ -50,7 +50,8 @@ static int braces = 0;
"//"[^\n]*\n ; "//"[^\n]*\n ;
[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; }
-?0x[0-9a-fA-F]+ { yylval.n = strtol(yytext, NULL, 0); return INT; }
[ \t\r\n]* ; [ \t\r\n]* ;
. return yytext[0]; . return yytext[0];