Add support for preserved registers.

This commit is contained in:
David Given 2016-10-29 20:22:44 +02:00
parent e3ebf986e9
commit a311e61360
8 changed files with 43 additions and 0 deletions

View file

@ -617,12 +617,14 @@ PATTERNS
cost 4; cost 4;
out:(int)reg = MOD.I(left:(int)reg, right:(int)reg) out:(int)reg = MOD.I(left:(int)reg, right:(int)reg)
with preserved(%left), preserved(%right)
emit "divw %out, %left, %right" emit "divw %out, %left, %right"
emit "mullw %out, %out, %right" emit "mullw %out, %out, %right"
emit "subf %out, %out, %left" emit "subf %out, %out, %left"
cost 12; cost 12;
out:(int)reg = MODU.I(left:(int)reg, right:(int)reg) out:(int)reg = MODU.I(left:(int)reg, right:(int)reg)
with preserved(%left), preserved(%right)
emit "divwu %out, %left, %right" emit "divwu %out, %left, %right"
emit "mullw %out, %out, %right" emit "mullw %out, %out, %right"
emit "subf %out, %out, %left" emit "subf %out, %out, %left"

View file

@ -31,6 +31,7 @@ struct insel
struct constraint struct constraint
{ {
uint32_t attrs; uint32_t attrs;
bool preserved;
struct vreg* equals_to; struct vreg* equals_to;
}; };

View file

@ -100,6 +100,16 @@ static void constrain_input_reg(int child, uint32_t attr)
get_constraint(vreg)->attrs = 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) static uint32_t find_type_from_constraint(uint32_t attr)
{ {
/* Looks through the registers and finds a concrete register implementing /* 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_value,
&emit_eoi, &emit_eoi,
&constrain_input_reg, &constrain_input_reg,
&constrain_input_reg_preserved,
&constrain_output_reg, &constrain_output_reg,
&constrain_output_reg_equal_to, &constrain_output_reg_equal_to,
}; };

View file

@ -38,6 +38,7 @@ extern int yylex(void);
%term NOTEQUALS %term NOTEQUALS
%term PATTERNS %term PATTERNS
%term PREFERS %term PREFERS
%term PRESERVED
%term REGISTERS %term REGISTERS
%term WHEN %term WHEN
%term WITH %term WITH
@ -170,6 +171,8 @@ constraint
$$->type = CONSTRAINT_EQUALS; $$->left = $2; $$->right = $5; } $$->type = CONSTRAINT_EQUALS; $$->left = $2; $$->right = $5; }
| CORRUPTED '(' ID ')' { $$ = calloc(1, sizeof(*$$)); | CORRUPTED '(' ID ')' { $$ = calloc(1, sizeof(*$$));
$$->type = CONSTRAINT_CORRUPTED_ATTR; $$->left = $3; } $$->type = CONSTRAINT_CORRUPTED_ATTR; $$->left = $3; }
| PRESERVED '(' '%' ID ')' { $$ = calloc(1, sizeof(*$$));
$$->type = CONSTRAINT_PRESERVED; $$->left = $4; }
; ;
qfragments qfragments

View 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 */ /* emitinsndata - emit the code generation data */
static void emitinsndata(Rule rules) static void emitinsndata(Rule rules)
{ {
@ -1234,6 +1256,7 @@ static void emitinsndata(Rule rules)
} }
emit_output_constraints(r); emit_output_constraints(r);
emit_input_constraints(r);
while (f) while (f)
{ {

View file

@ -21,6 +21,7 @@ enum
{ {
CONSTRAINT_EQUALS, CONSTRAINT_EQUALS,
CONSTRAINT_CORRUPTED_ATTR, CONSTRAINT_CORRUPTED_ATTR,
CONSTRAINT_PRESERVED,
}; };
struct constraint struct constraint

View file

@ -45,6 +45,7 @@ struct burm_emitter_data
void (*emit_value)(int child); void (*emit_value)(int child);
void (*emit_eoi)(void); void (*emit_eoi)(void);
void (*constrain_input_reg)(int child, uint32_t attr); 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)(uint32_t attr);
void (*constrain_output_reg_equal_to)(int child); void (*constrain_output_reg_equal_to)(int child);
}; };

View file

@ -46,6 +46,7 @@ static int braces = 0;
"fragment" return FRAGMENT; "fragment" return FRAGMENT;
"named" return NAMED; "named" return NAMED;
"prefers" return PREFERS; "prefers" return PREFERS;
"preserved" return PRESERVED;
"when" return WHEN; "when" return WHEN;
"with" return WITH; "with" return WITH;
"==" return EQUALS; "==" return EQUALS;