summaryrefslogtreecommitdiffhomepage
path: root/ir/be/mips
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2018-05-10 06:23:18 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2018-05-11 07:15:44 +0200
commit9a825064696eebf733ccfc8d72f22c1aef3ec1ff (patch)
tree491ac35c915c549bb4925e9519f282eb307acc1a /ir/be/mips
parentb3791a21b6ee22c0533cc513dec7f2edddf6be8c (diff)
ir: Overhaul representation of ASM constraints in the IR.
Now the constraints are a mapping from the template position to the input/output positions instead of the other way round. Also there is only one list of constraints instead of a separate one for input and output. This simplifies handling quite a bit, in particular the numbering. E.g. "=m" actually is an input (for the address) and this caused miscounting when the constraints were processed. Also processing of 64 bit operands also lead to miscounting. This fixes x86code/asm_test15.c and x86code/asm_test19.c
Diffstat (limited to 'ir/be/mips')
-rw-r--r--ir/be/mips/mips_transform.c80
1 files changed, 35 insertions, 45 deletions
diff --git a/ir/be/mips/mips_transform.c b/ir/be/mips/mips_transform.c
index b503041..2b4ff04 100644
--- a/ir/be/mips/mips_transform.c
+++ b/ir/be/mips/mips_transform.c
@@ -251,54 +251,44 @@ static bool mips_match_immediate(mips_asm_operand_t *const operand, ir_node *con
return true;
}
-static void parse_asm_constraints(be_asm_constraint_t *const constraint, ident *const constraint_text, bool const is_output)
-{
- be_parse_asm_constraints_internal(constraint, constraint_text, is_output, &mips_parse_constraint_letter, NULL);
-}
-
static ir_node *gen_ASM(ir_node *const node)
{
- be_asm_info_t info = be_asm_prepare_info();
-
- unsigned const n_operands = be_count_asm_operands(node);
- ir_graph *const irg = get_irn_irg(node);
- struct obstack *const obst = get_irg_obstack(irg);
- mips_asm_operand_t *const operands = NEW_ARR_DZ(mips_asm_operand_t, obst, n_operands);
-
- ir_asm_constraint const *const out_constraints = get_ASM_output_constraints(node);
- size_t const n_out_constraints = get_ASM_n_output_constraints(node);
- for (size_t o = 0; o != n_out_constraints; ++o) {
- ir_asm_constraint const *const constraint = &out_constraints[o];
- be_asm_constraint_t parsed_constraint;
- parse_asm_constraints(&parsed_constraint, constraint->constraint, true);
-
- be_asm_add_out(&info, &operands[constraint->pos].op, obst, &parsed_constraint, n_out_constraints, o);
- }
-
- ir_asm_constraint const *const in_constraints = get_ASM_input_constraints(node);
- int const n_inputs = get_ASM_n_inputs(node);
- for (int i = 0; i < n_inputs; ++i) {
- ir_node *const pred = get_ASM_input(node, i);
- ir_asm_constraint const *const constraint = &in_constraints[i];
-
- be_asm_constraint_t parsed_constraint;
- parse_asm_constraints(&parsed_constraint, constraint->constraint, false);
-
- mips_asm_operand_t *const operand = &operands[constraint->pos];
-
- char const imm_type = parsed_constraint.immediate_type;
- if (imm_type != '\0' && mips_match_immediate(operand, pred, imm_type))
- continue;
-
- ir_node *const new_pred = be_transform_node(pred);
- be_asm_operand_kind_t kind = BE_ASM_OPERAND_INPUT_VALUE;
- arch_register_req_t const *req = be_make_register_req(obst, &parsed_constraint, n_out_constraints, info.out_reqs, i);
- if (req == arch_no_register_req) {
- kind = BE_ASM_OPERAND_MEMORY;
- req = arch_get_irn_register_req(new_pred)->cls->class_req;
+ be_asm_info_t info = be_asm_prepare_info(node);
+
+ ir_asm_constraint const *const constraints = get_ASM_constraints(node);
+ size_t const n_constraints = get_ASM_n_constraints(node);
+ ir_graph *const irg = get_irn_irg(node);
+ struct obstack *const obst = get_irg_obstack(irg);
+ mips_asm_operand_t *const operands = NEW_ARR_DZ(mips_asm_operand_t, obst, n_constraints);
+ for (size_t i = 0; i != n_constraints; ++i) {
+ ir_asm_constraint const *const c = &constraints[i];
+
+ be_asm_constraint_t be_constraint;
+ be_parse_asm_constraints_internal(&be_constraint, c->constraint, &mips_parse_constraint_letter, NULL);
+
+ mips_asm_operand_t *const op = &operands[i];
+
+ int const in_pos = c->in_pos;
+ if (in_pos >= 0) {
+ ir_node *const in = get_ASM_input(node, in_pos);
+ char const imm = be_constraint.immediate_type;
+ if (imm != '\0' && mips_match_immediate(op, in, imm)) {
+ be_set_asm_operand(&op->op, BE_ASM_OPERAND_IMMEDIATE, -1);
+ } else if (be_constraint.same_as >= 0) {
+ int const out_pos = operands[be_constraint.same_as].op.pos;
+ arch_register_req_t const *const ireq = info.out_reqs[out_pos];
+ be_asm_add_inout(&info, &op->op, obst, in, ireq, out_pos);
+ } else if (be_constraint.cls) {
+ arch_register_req_t const *const ireq = be_make_register_req(obst, &be_constraint);
+ be_asm_add_inout(&info, &op->op, obst, in, ireq, c->out_pos);
+ } else {
+ ir_node *const new_in = be_transform_node(in);
+ arch_register_req_t const *const ireq = arch_get_irn_register_req(new_in)->cls->class_req;
+ be_asm_add_in(&info, &op->op, BE_ASM_OPERAND_MEMORY, new_in, ireq);
+ }
+ } else {
+ be_asm_add_out(&info, &op->op, obst, &be_constraint, c->out_pos);
}
-
- be_asm_add_in(&info, &operand->op, kind, new_pred, req);
}
return be_make_asm(node, &info, operands);