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 : */
+++ /dev/null
-#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 : */
-
-
--- /dev/null
+#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 : */
+
+
cost 1;
STACKADJUST4(delta:CONST4)
- when constant_signed_16_bit(delta)
+ when signed_constant(%delta, 16)
emit "addi sp, sp, $delta"
cost 4;
/* 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
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;
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;
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;
"+lib",
"+yacc",
"modules/src/data+lib",
+ "modules+headers",
}
}
%}
%union {
- int n;
- char* string;
+ arith n;
+ const char* string;
Nonterm nonterm;
Tree tree;
Rule rule;
%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
;
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; }
;
%%
{
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;
}
#ifndef BURG_INCLUDED
#define BURG_INCLUDED
+#include "em_arith.h"
#include "stringlist.h"
#include "array.h"
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
"//"[^\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];