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 bool burm_predicate_constant_signed_16_bit(struct burm_node* node);
extern bool burm_predicate_constant_is_zero(struct burm_node* node);
extern bool burm_predicate_signed_constant(struct burm_node* node, arith size);
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 : */

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;
STACKADJUST4(delta:CONST4)
when constant_signed_16_bit(delta)
when signed_constant(%delta, 16)
emit "addi sp, sp, $delta"
cost 4;
@ -167,7 +167,7 @@ PATTERNS
/* Memory addressing modes */
address = ADD4(addr:(int)reg, offset:CONST4)
when constant_signed_16_bit(offset)
when signed_constant(%offset, 16)
emit "$offset(%addr)";
address = addr:(int)reg
@ -218,7 +218,7 @@ PATTERNS
cost 4;
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"
cost 4;
@ -227,23 +227,23 @@ PATTERNS
cost 4;
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"
cost 4;
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"
cost 4;
cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:CONST4), result:CONST4)
when constant_is_zero(result)
when constant_signed_16_bit(right)
when specific_constant(%result, 0)
when signed_constant(%right, 16)
emit "cmpi %cr, 0, %left, $right"
cost 4;
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"
cost 4;
@ -280,7 +280,7 @@ PATTERNS
cost 4;
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"
cost 4;

View file

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

View file

@ -13,8 +13,8 @@ extern int yylex(void);
%}
%union {
int n;
char* string;
arith n;
const char* string;
Nonterm nonterm;
Tree tree;
Rule rule;
@ -44,16 +44,17 @@ extern int yylex(void);
%type <constraint> constraint
%type <constraint> constraints
%type <expr> predicate
%type <expr> predicate_arg
%type <expr> predicate_args
%type <nonterm> declaration
%type <reg> register
%type <rule> pattern
%type <rule> pattern_constraints
%type <rule> pattern_emit
%type <rule> pattern
%type <stringlist> qfragments
%type <terminfo> terminfo
%type <tree> rhs
%type <expr> predicate
%type <expr> predicate_args
%%
spec
@ -155,13 +156,23 @@ qfragments
;
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
: /* nothing */ { $$ = NULL; }
| ID { $$ = calloc(1, sizeof *$$); $$->name = $1; }
| ID ',' predicate_args { $$ = calloc(1, sizeof *$$); $$->name = $1; $$->next = $3; }
| predicate_arg { $$ = $1; }
| 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;
print("%1if (%Ppredicate_%s(", p->name);
assert(p->type == PREDICATE_FUNCTION);
print("%1if (%Ppredicate_%s(", p->u.name);
p = p->next;
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)
print(", ");
else
first = false;
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;
}

View file

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

View file

@ -50,7 +50,8 @@ static int braces = 0;
"//"[^\n]*\n ;
[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]* ;
. return yytext[0];