Predicates can now take numeric arguments. The PowerPC predicates have been
authorDavid Given <dg@cowlark.com>
Sun, 9 Oct 2016 10:32:36 +0000 (12:32 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 9 Oct 2016 10:32:36 +0000 (12:32 +0200)
turned into generic ones (as they'll be useful everywhere). Node arguments for
predicates require the '%' prefix for consistency. Hex numbers are permitted.

mach/proto/mcg/mcgg_generated_header.h
mach/proto/mcg/powerpc_predicates.c [deleted file]
mach/proto/mcg/predicates.c [new file with mode: 0644]
mach/proto/mcg/table
util/mcgg/build.lua
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/scan.l

index 47c2bd9..5d9b3ae 100644 (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 : */
 
diff --git a/mach/proto/mcg/powerpc_predicates.c b/mach/proto/mcg/powerpc_predicates.c
deleted file mode 100644 (file)
index 2748b43..0000000
+++ /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 (file)
index 0000000..427a598
--- /dev/null
@@ -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 : */
+
+
index 9321724..e19f56d 100644 (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;
 
index 83d800e..aa57566 100644 (file)
@@ -50,6 +50,7 @@ cprogram {
                "+lib",
                "+yacc",
                "modules/src/data+lib",
+               "modules+headers",
        }
 }
        
index 30c61cb..74c0c05 100644 (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; }
     ;
 
 %%
index 5500111..c93a1b3 100644 (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;
 
-               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;
        }
 
index 4898172..d9d69b8 100644 (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
index 6bd50d2..68de96e 100644 (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];