Add support for preserved registers.
This commit is contained in:
parent
e3ebf986e9
commit
a311e61360
|
@ -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"
|
||||
|
|
|
@ -31,6 +31,7 @@ struct insel
|
|||
struct constraint
|
||||
{
|
||||
uint32_t attrs;
|
||||
bool preserved;
|
||||
struct vreg* equals_to;
|
||||
};
|
||||
|
||||
|
|
|
@ -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(¤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
|
||||
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@ enum
|
|||
{
|
||||
CONSTRAINT_EQUALS,
|
||||
CONSTRAINT_CORRUPTED_ATTR,
|
||||
CONSTRAINT_PRESERVED,
|
||||
};
|
||||
|
||||
struct constraint
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue