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 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 : */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ cprogram {
|
|||
"+lib",
|
||||
"+yacc",
|
||||
"modules/src/data+lib",
|
||||
"modules+headers",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
Loading…
Reference in a new issue