diff --git a/mach/proto/mcg/mcgg_generated_header.h b/mach/proto/mcg/mcgg_generated_header.h index 47c2bd9e6..5d9b3ae2e 100644 --- a/mach/proto/mcg/mcgg_generated_header.h +++ b/mach/proto/mcg/mcgg_generated_header.h @@ -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 : */ diff --git a/mach/proto/mcg/powerpc_predicates.c b/mach/proto/mcg/powerpc_predicates.c deleted file mode 100644 index 2748b43d0..000000000 --- a/mach/proto/mcg/powerpc_predicates.c +++ /dev/null @@ -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 : */ - - diff --git a/mach/proto/mcg/predicates.c b/mach/proto/mcg/predicates.c new file mode 100644 index 000000000..427a59836 --- /dev/null +++ b/mach/proto/mcg/predicates.c @@ -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<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<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 : */ + + diff --git a/mach/proto/mcg/table b/mach/proto/mcg/table index 932172480..e19f56d07 100644 --- a/mach/proto/mcg/table +++ b/mach/proto/mcg/table @@ -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; diff --git a/util/mcgg/build.lua b/util/mcgg/build.lua index 83d800eaf..aa575667a 100644 --- a/util/mcgg/build.lua +++ b/util/mcgg/build.lua @@ -50,6 +50,7 @@ cprogram { "+lib", "+yacc", "modules/src/data+lib", + "modules+headers", } } diff --git a/util/mcgg/gram.y b/util/mcgg/gram.y index 30c61cb4c..74c0c0502 100644 --- a/util/mcgg/gram.y +++ b/util/mcgg/gram.y @@ -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 %type constraints +%type predicate +%type predicate_arg +%type predicate_args %type declaration %type register +%type pattern %type pattern_constraints %type pattern_emit -%type pattern %type qfragments %type terminfo %type rhs -%type predicate -%type 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; } ; %% diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 550011140..c93a1b373 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -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; } diff --git a/util/mcgg/iburg.h b/util/mcgg/iburg.h index 48981722b..d9d69b8c6 100644 --- a/util/mcgg/iburg.h +++ b/util/mcgg/iburg.h @@ -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 diff --git a/util/mcgg/scan.l b/util/mcgg/scan.l index 6bd50d294..68de96ed4 100644 --- a/util/mcgg/scan.l +++ b/util/mcgg/scan.l @@ -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];