summaryrefslogtreecommitdiffhomepage
path: root/ir/ir
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/ir
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/ir')
-rw-r--r--ir/ir/ircons.c34
-rw-r--r--ir/ir/irdumptxt.c24
-rw-r--r--ir/ir/irio.c51
-rw-r--r--ir/ir/irnode.c4
-rw-r--r--ir/ir/irnode_t.h9
-rw-r--r--ir/ir/irop.c31
6 files changed, 56 insertions, 97 deletions
diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c
index 8360e4f..01cf4f4 100644
--- a/ir/ir/ircons.c
+++ b/ir/ir/ircons.c
@@ -41,8 +41,8 @@ ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode,
}
ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem,
- int arity, ir_node *in[], ir_asm_constraint *inputs,
- size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber,
+ int arity, ir_node *in[],
+ size_t n_constraints, ir_asm_constraint *constraints, size_t n_clobber,
ident *clobber[], ident *text)
{
ir_graph *const irg = get_irn_irg(block);
@@ -56,15 +56,13 @@ ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem,
struct obstack *const obst = get_irg_obstack(irg);
asm_attr *const a = &res->attr.assem;
- a->exc.pinned = true;
- a->input_constraints = NEW_ARR_D(ir_asm_constraint, obst, arity);
- a->output_constraints = NEW_ARR_D(ir_asm_constraint, obst, n_outs);
- a->clobbers = NEW_ARR_D(ident*, obst, n_clobber);
- a->text = text;
+ a->exc.pinned = true;
+ a->constraints = NEW_ARR_D(ir_asm_constraint, obst, n_constraints);
+ a->clobbers = NEW_ARR_D(ident*, obst, n_clobber);
+ a->text = text;
- MEMCPY(a->input_constraints, inputs, arity);
- MEMCPY(a->output_constraints, outputs, n_outs);
- MEMCPY(a->clobbers, clobber, n_clobber);
+ MEMCPY(a->constraints, constraints, n_constraints);
+ MEMCPY(a->clobbers, clobber, n_clobber);
verify_new_node(res);
res = optimize_node(res);
@@ -77,11 +75,11 @@ ir_node *new_r_Const_long(ir_graph *irg, ir_mode *mode, long value)
}
ir_node *new_r_ASM(ir_node *block, ir_node *mem,
- int arity, ir_node *in[], ir_asm_constraint *inputs,
- size_t n_outs, ir_asm_constraint *outputs,
+ int arity, ir_node *in[],
+ size_t n_constraints, ir_asm_constraint *constraints,
size_t n_clobber, ident *clobber[], ident *text)
{
- return new_rd_ASM(NULL, block, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
+ return new_rd_ASM(NULL, block, mem, arity, in, n_constraints, constraints, n_clobber, clobber, text);
}
/** Creates a Phi node with 0 predecessors. */
@@ -305,13 +303,12 @@ ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
}
ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, ir_node *in[],
- ir_asm_constraint *inputs,
- size_t n_outs, ir_asm_constraint *outputs,
+ size_t n_constraints, ir_asm_constraint *constraints,
size_t n_clobber, ident *clobber[], ident *text)
{
assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
return new_rd_ASM(db, current_ir_graph->current_block, mem, arity, in,
- inputs, n_outs, outputs, n_clobber, clobber, text);
+ n_constraints, constraints, n_clobber, clobber, text);
}
ir_node *new_rd_DivRL(dbg_info *dbgi, ir_node *block, ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, int pinned)
@@ -570,11 +567,10 @@ ir_node *new_Const_long(ir_mode *mode, long value)
}
ir_node *new_ASM(ir_node *mem, int arity, ir_node *in[],
- ir_asm_constraint *inputs, size_t n_outs,
- ir_asm_constraint *outputs, size_t n_clobber,
+ size_t n_constraints, ir_asm_constraint *constraints, size_t n_clobber,
ident *clobber[], ident *text)
{
- return new_d_ASM(NULL, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
+ return new_d_ASM(NULL, mem, arity, in, n_constraints, constraints, n_clobber, clobber, text);
}
ir_node *new_r_Anchor(ir_graph *irg)
diff --git a/ir/ir/irdumptxt.c b/ir/ir/irdumptxt.c
index 98ac002..1428c6b 100644
--- a/ir/ir/irdumptxt.c
+++ b/ir/ir/irdumptxt.c
@@ -308,18 +308,18 @@ void dump_irnode_to_file(FILE *const F, const ir_node *const n)
break;
case iro_ASM: {
fprintf(F, " assembler text: %s", get_id_str(get_ASM_text(n)));
- fprintf(F, "\n inputs: ");
- const ir_asm_constraint *in_cons = get_ASM_input_constraints(n);
- for (int i = 0, n_inputs = get_ASM_n_inputs(n); i < n_inputs; ++i) {
- fprintf(F, "%%%u %s ", in_cons[i].pos,
- get_id_str(in_cons[i].constraint));
- }
- fprintf(F, "\n outputs: ");
- const ir_asm_constraint *out_cons = get_ASM_output_constraints(n);
- for (int i = 0, n_outputs = get_ASM_n_output_constraints(n);
- i < n_outputs; ++i) {
- fprintf(F, "%%%u %s ", out_cons[i].pos,
- get_id_str(out_cons[i].constraint));
+ fprintf(F, "\n constraints:");
+ char const *sep = "";
+ ir_asm_constraint const *const cons = get_ASM_constraints(n);
+ for (size_t i = 0, n_cons = get_ASM_n_constraints(n); i < n_cons; sep = ",", ++i) {
+ ir_asm_constraint const *const c = &cons[i];
+ fprintf(F, "%s %%%zu: \\\"%s\\\"", sep, i, c->constraint);
+ int const in_pos = c->in_pos;
+ if (in_pos != -1)
+ fprintf(F, " [in: %d]", n_ASM_max + 1 + in_pos);
+ int const out_pos = c->out_pos;
+ if (out_pos != -1)
+ fprintf(F, " [out: %d]", out_pos);
}
fprintf(F, "\n clobber: ");
diff --git a/ir/ir/irio.c b/ir/ir/irio.c
index 469f141..77a08b4 100644
--- a/ir/ir/irio.c
+++ b/ir/ir/irio.c
@@ -794,22 +794,11 @@ static void write_ASM(write_env_t *env, const ir_node *node)
write_ident(env, get_ASM_text(node));
write_list_begin(env);
- ir_asm_constraint *input_constraints = get_ASM_input_constraints(node);
- int n_inputs = get_ASM_n_inputs(node);
- for (int i = 0; i < n_inputs; ++i) {
- const ir_asm_constraint *constraint = &input_constraints[i];
- write_unsigned(env, constraint->pos);
- write_ident(env, constraint->constraint);
- write_mode_ref(env, constraint->mode);
- }
- write_list_end(env);
-
- write_list_begin(env);
- ir_asm_constraint *output_constraints = get_ASM_output_constraints(node);
- size_t n_output_constraints = get_ASM_n_output_constraints(node);
- for (size_t i = 0; i < n_output_constraints; ++i) {
- const ir_asm_constraint *constraint = &output_constraints[i];
- write_unsigned(env, constraint->pos);
+ ir_asm_constraint *const constraints = get_ASM_constraints(node);
+ for (int i = 0, n = get_ASM_n_constraints(node); i < n; ++i) {
+ ir_asm_constraint const *const constraint = &constraints[i];
+ write_int(env, constraint->in_pos);
+ write_int(env, constraint->out_pos);
write_ident(env, constraint->constraint);
write_mode_ref(env, constraint->mode);
}
@@ -1909,23 +1898,14 @@ static ir_node *read_ASM(read_env_t *env)
ident *asm_text = read_ident(env);
expect_list_begin(env);
- ir_asm_constraint *input_constraints = NEW_ARR_F(ir_asm_constraint, 0);
+ ir_asm_constraint *constraints = NEW_ARR_F(ir_asm_constraint, 0);
while (list_has_next(env)) {
ir_asm_constraint constraint;
- constraint.pos = read_unsigned(env);
+ constraint.in_pos = read_int(env);
+ constraint.out_pos = read_int(env);
constraint.constraint = read_ident(env);
constraint.mode = read_mode_ref(env);
- ARR_APP1(ir_asm_constraint, input_constraints, constraint);
- }
-
- expect_list_begin(env);
- ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0);
- while (list_has_next(env)) {
- ir_asm_constraint constraint;
- constraint.pos = read_unsigned(env);
- constraint.constraint = read_ident(env);
- constraint.mode = read_mode_ref(env);
- ARR_APP1(ir_asm_constraint, output_constraints, constraint);
+ ARR_APP1(ir_asm_constraint, constraints, constraint);
}
expect_list_begin(env);
@@ -1940,20 +1920,13 @@ static ir_node *read_ASM(read_env_t *env)
int n_in = read_preds(env);
ir_node **in = (ir_node**)obstack_finish(&env->preds_obst);
- if (ARR_LEN(input_constraints) != (size_t)n_in) {
- parse_error(env, "input_constraints != n_in in ir file");
- return new_r_Bad(env->irg, mode_T);
- }
-
ir_node *newnode = new_r_ASM(block, mem, n_in, in,
- input_constraints, ARR_LEN(output_constraints),
- output_constraints, ARR_LEN(clobbers),
- clobbers, asm_text);
+ ARR_LEN(constraints), constraints,
+ ARR_LEN(clobbers), clobbers, asm_text);
set_irn_pinned(newnode, pinned);
obstack_free(&env->preds_obst, in);
DEL_ARR_F(clobbers);
- DEL_ARR_F(output_constraints);
- DEL_ARR_F(input_constraints);
+ DEL_ARR_F(constraints);
return newnode;
}
diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c
index 3956108..28185c3 100644
--- a/ir/ir/irnode.c
+++ b/ir/ir/irnode.c
@@ -674,10 +674,10 @@ int ir_throws_exception(const ir_node *node)
return attr->throws_exception;
}
-size_t get_ASM_n_output_constraints(const ir_node *node)
+size_t get_ASM_n_constraints(const ir_node *node)
{
assert(is_ASM(node));
- return ARR_LEN(node->attr.assem.output_constraints);
+ return ARR_LEN(node->attr.assem.constraints);
}
size_t get_ASM_n_clobbers(const ir_node *node)
diff --git a/ir/ir/irnode_t.h b/ir/ir/irnode_t.h
index 741cc8f..e75ff1a 100644
--- a/ir/ir/irnode_t.h
+++ b/ir/ir/irnode_t.h
@@ -219,11 +219,10 @@ typedef struct mod_attr {
/** Attributes for ASM nodes. */
typedef struct asm_attr {
- except_attr exc; /**< Exception attribute. MUST be first. */
- ident *text; /**< The inline assembler text. */
- ir_asm_constraint *input_constraints; /**< Input constraints. */
- ir_asm_constraint *output_constraints; /**< Output constraints. */
- ident **clobbers; /**< List of clobbered registers. */
+ except_attr exc; /**< Exception attribute. MUST be first. */
+ ident *text; /**< The inline assembler text. */
+ ir_asm_constraint *constraints; /**< The constraints. */
+ ident **clobbers; /**< List of clobbered registers. */
} asm_attr;
/** Attributes for Proj nodes. */
diff --git a/ir/ir/irop.c b/ir/ir/irop.c
index a985af7..fc42303 100644
--- a/ir/ir/irop.c
+++ b/ir/ir/irop.c
@@ -399,25 +399,17 @@ static int attrs_equal_ASM(const ir_node *a, const ir_node *b)
if (n_inputs != get_ASM_n_inputs(b))
return false;
- const ir_asm_constraint *in_a = get_ASM_input_constraints(a);
- const ir_asm_constraint *in_b = get_ASM_input_constraints(b);
- for (int i = 0; i < n_inputs; ++i) {
- if (in_a[i].pos != in_b[i].pos
- || in_a[i].constraint != in_b[i].constraint
- || in_a[i].mode != in_b[i].mode)
- return false;
- }
-
- size_t n_outputs = get_ASM_n_output_constraints(a);
- if (n_outputs != get_ASM_n_output_constraints(b))
+ size_t const n_constraints = get_ASM_n_constraints(a);
+ if (n_constraints != get_ASM_n_constraints(b))
return false;
- const ir_asm_constraint *out_a = get_ASM_output_constraints(a);
- const ir_asm_constraint *out_b = get_ASM_output_constraints(b);
- for (size_t i = 0; i < n_outputs; ++i) {
- if (out_a[i].pos != out_b[i].pos
- || out_a[i].constraint != out_b[i].constraint
- || out_a[i].mode != out_b[i].mode)
+ ir_asm_constraint const *const cons_a = get_ASM_constraints(a);
+ ir_asm_constraint const *const cons_b = get_ASM_constraints(b);
+ for (size_t i = 0; i < n_constraints; ++i) {
+ if (cons_a[i].in_pos != cons_b[i].in_pos ||
+ cons_a[i].out_pos != cons_b[i].out_pos ||
+ cons_a[i].constraint != cons_b[i].constraint ||
+ cons_a[i].mode != cons_b[i].mode)
return false;
}
@@ -492,9 +484,8 @@ static void ASM_copy_attr(ir_graph *irg, const ir_node *old_node,
{
default_copy_attr(irg, old_node, new_node);
struct obstack *const obst = get_irg_obstack(irg);
- new_node->attr.assem.input_constraints = DUP_ARR_D(ir_asm_constraint, obst, old_node->attr.assem.input_constraints);
- new_node->attr.assem.output_constraints = DUP_ARR_D(ir_asm_constraint, obst, old_node->attr.assem.output_constraints);
- new_node->attr.assem.clobbers = DUP_ARR_D(ident*, obst, old_node->attr.assem.clobbers);
+ new_node->attr.assem.constraints = DUP_ARR_D(ir_asm_constraint, obst, old_node->attr.assem.constraints);
+ new_node->attr.assem.clobbers = DUP_ARR_D(ident*, obst, old_node->attr.assem.clobbers);
}
static void switch_copy_attr(ir_graph *irg, const ir_node *old_node,