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"
struct constraint
{
uint32_t attrs;
+ bool preserved;
struct vreg* equals_to;
};
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(¤t_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
&emit_value,
&emit_eoi,
&constrain_input_reg,
+ &constrain_input_reg_preserved,
&constrain_output_reg,
&constrain_output_reg_equal_to,
};
%term NOTEQUALS
%term PATTERNS
%term PREFERS
+%term PRESERVED
%term REGISTERS
%term WHEN
%term WITH
$$->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
}
}
+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)
{
}
emit_output_constraints(r);
+ emit_input_constraints(r);
while (f)
{
{
CONSTRAINT_EQUALS,
CONSTRAINT_CORRUPTED_ATTR,
+ CONSTRAINT_PRESERVED,
};
struct constraint
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);
};
"fragment" return FRAGMENT;
"named" return NAMED;
"prefers" return PREFERS;
+"preserved" return PRESERVED;
"when" return WHEN;
"with" return WITH;
"==" return EQUALS;