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:
parent
d75cc0a663
commit
cfe5312fcc
|
@ -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 : */
|
||||||
|
|
||||||
|
|
|
@ -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 : */
|
|
||||||
|
|
||||||
|
|
32
mach/proto/mcg/predicates.c
Normal file
32
mach/proto/mcg/predicates.c
Normal 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 : */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ cprogram {
|
||||||
"+lib",
|
"+lib",
|
||||||
"+yacc",
|
"+yacc",
|
||||||
"modules/src/data+lib",
|
"modules/src/data+lib",
|
||||||
|
"modules+headers",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
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);
|
print_path(path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PREDICATE_NUMBER:
|
||||||
|
{
|
||||||
|
print("%d", p->u.number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue