Add support for preserved registers.
authorDavid Given <dg@cowlark.com>
Sat, 29 Oct 2016 18:22:44 +0000 (20:22 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 29 Oct 2016 18:22:44 +0000 (20:22 +0200)
mach/powerpc/mcg/table
mach/proto/mcg/hop.h
mach/proto/mcg/pass_instructionselection.c
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/mcgg.h
util/mcgg/scan.l

index 3be30c3..7023c08 100644 (file)
@@ -617,12 +617,14 @@ PATTERNS
                cost 4;
 
        out:(int)reg = MOD.I(left:(int)reg, right:(int)reg)
+        with preserved(%left), preserved(%right)
                emit "divw %out, %left, %right"
         emit "mullw %out, %out, %right"
         emit "subf %out, %out, %left"
                cost 12;
 
        out:(int)reg = MODU.I(left:(int)reg, right:(int)reg)
+        with preserved(%left), preserved(%right)
                emit "divwu %out, %left, %right"
         emit "mullw %out, %out, %right"
         emit "subf %out, %out, %left"
index 0cc5dc0..21c7e92 100644 (file)
@@ -31,6 +31,7 @@ struct insel
 struct constraint
 {
     uint32_t attrs;
+       bool preserved;
     struct vreg* equals_to;
 };
 
index 2bf5e5b..860dad0 100644 (file)
@@ -100,6 +100,16 @@ static void constrain_input_reg(int child, uint32_t attr)
     get_constraint(vreg)->attrs = attr;
 }
 
+static void constrain_input_reg_preserved(int child)
+{
+    struct vreg* vreg = find_vreg_of_child(child);
+    struct constraint* c;
+
+    assert(vreg);
+    array_appendu(&current_hop->throughs, vreg);
+    get_constraint(vreg)->preserved = true;
+}
+
 static uint32_t find_type_from_constraint(uint32_t attr)
 {
     /* Looks through the registers and finds a concrete register implementing
@@ -158,6 +168,7 @@ static const struct burm_emitter_data emitter_data =
     &emit_value,
     &emit_eoi,
     &constrain_input_reg,
+    &constrain_input_reg_preserved,
     &constrain_output_reg,
     &constrain_output_reg_equal_to,
 };
index 99fdeda..891030a 100644 (file)
@@ -38,6 +38,7 @@ extern int yylex(void);
 %term NOTEQUALS
 %term PATTERNS
 %term PREFERS
+%term PRESERVED
 %term REGISTERS
 %term WHEN
 %term WITH
@@ -170,6 +171,8 @@ constraint
                                           $$->type = CONSTRAINT_EQUALS; $$->left = $2; $$->right = $5; }
     | CORRUPTED '(' ID ')'              { $$ = calloc(1, sizeof(*$$));
                                           $$->type = CONSTRAINT_CORRUPTED_ATTR; $$->left = $3; }
+    | PRESERVED '(' '%' ID ')'          { $$ = calloc(1, sizeof(*$$));
+                                          $$->type = CONSTRAINT_PRESERVED; $$->left = $4; }
     ;
 
 qfragments
index 55a24e7..23705c7 100644 (file)
@@ -1199,6 +1199,28 @@ static void emit_output_constraints(Rule r)
        }
 }
 
+static void emit_input_constraints(Rule r)
+{
+       int i;
+       for (i=0; i<r->constraints.count; i++)
+       {
+               int index;
+               struct constraint* c = r->constraints.item[i];
+
+               if (c->type == CONSTRAINT_PRESERVED)
+               {
+                       if (strcmp(c->left, r->label) == 0)
+                               yyerror("cannot preserve an output register!");
+
+                       index = 0;
+                       if (!find_child_index(r->pattern, c->left, &index, NULL))
+                               label_not_found(r, c->left);
+
+                       print("%1data->constrain_input_reg_preserved(%d);\n", index);
+               }
+       }
+}
+
 /* emitinsndata - emit the code generation data */
 static void emitinsndata(Rule rules)
 {
@@ -1234,6 +1256,7 @@ static void emitinsndata(Rule rules)
                }
                
                emit_output_constraints(r);
+               emit_input_constraints(r);
                
                while (f)
                {
index 8ba4f5a..739641d 100644 (file)
@@ -21,6 +21,7 @@ enum
 {
        CONSTRAINT_EQUALS,
        CONSTRAINT_CORRUPTED_ATTR,
+       CONSTRAINT_PRESERVED,
 };
 
 struct constraint
index a068fa6..c0c930a 100644 (file)
@@ -45,6 +45,7 @@ struct burm_emitter_data
     void (*emit_value)(int child);
     void (*emit_eoi)(void);
     void (*constrain_input_reg)(int child, uint32_t attr);
+    void (*constrain_input_reg_preserved)(int child);
     void (*constrain_output_reg)(uint32_t attr);
     void (*constrain_output_reg_equal_to)(int child);
 };
index 272dd2b..447a7d3 100644 (file)
@@ -46,6 +46,7 @@ static int braces = 0;
 "fragment"                  return FRAGMENT;
 "named"                     return NAMED;
 "prefers"                   return PREFERS;
+"preserved"                 return PRESERVED;
 "when"                      return WHEN;
 "with"                      return WITH;
 "=="                        return EQUALS;