Commit 5435e3c7 authored by Michael Beck's avatar Michael Beck
Browse files

Add constraints to the ASM node

[r14220]
parent 91e2f8d4
......@@ -838,7 +838,7 @@ new_bd_Pin(dbg_info *db, ir_node *block, ir_node *node) {
static ir_node *
new_bd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text) {
int n_outs, ir_asm_constraint *outputs, int n_clobber, ident *clobber[], ident *asm_text) {
ir_node *res;
ir_graph *irg = current_ir_graph;
......@@ -846,6 +846,7 @@ new_bd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[], ir_asm_constr
res->attr.assem.pin_state = op_pin_state_pinned;
res->attr.assem.inputs = NEW_ARR_D(ir_asm_constraint, irg->obst, arity);
res->attr.assem.outputs = NEW_ARR_D(ir_asm_constraint, irg->obst, n_outs);
res->attr.assem.clobber = NEW_ARR_D(ident *, irg->obst, n_clobber);
res->attr.assem.asm_text = asm_text;
memcpy(res->attr.assem.inputs, inputs, sizeof(inputs[0]) * arity);
......@@ -1440,12 +1441,13 @@ ir_node *new_rd_Pin(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *node)
ir_node *new_rd_ASM(dbg_info *db, ir_graph *irg, ir_node *block,
int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text) {
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text) {
ir_node *res;
ir_graph *rem = current_ir_graph;
current_ir_graph = irg;
res = new_bd_ASM(db, block, arity, in, inputs, n_outs, outputs, asm_text);
res = new_bd_ASM(db, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, asm_text);
current_ir_graph = rem;
return res;
......@@ -1687,8 +1689,9 @@ ir_node *new_r_Pin(ir_graph *irg, ir_node *block, ir_node *node) {
}
ir_node *new_r_ASM(ir_graph *irg, ir_node *block,
int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text) {
return new_rd_ASM(NULL, irg, block, arity, in, inputs, n_outs, outputs, asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text) {
return new_rd_ASM(NULL, irg, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, asm_text);
}
/** ********************/
......@@ -2926,8 +2929,9 @@ new_d_Pin(dbg_info *db, ir_node *node) {
ir_node *
new_d_ASM(dbg_info *db, int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text) {
return new_bd_ASM(db, current_ir_graph->current_block, arity, in, inputs, n_outs, outputs, asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text) {
return new_bd_ASM(db, current_ir_graph->current_block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, asm_text);
} /* new_d_ASM */
/* ********************************************************************* */
......@@ -3345,6 +3349,7 @@ ir_node *new_Pin(ir_node *node) {
return new_d_Pin(NULL, node);
}
ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text) {
return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text) {
return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, asm_text);
}
......@@ -2001,11 +2001,14 @@ ir_node *new_rd_Pin(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *node);
* @param *inputs The array of length arity of input constraints.
* @param n_outs The number of data outputs to the node.
* @param *outputs The array of length n_outs of output constraints.
* @param n_clobber The number of clobbered registers.
* @param *clobber The array of length n_clobber of clobbered registers.
* @param *asm_text The assembler text.
*/
ir_node *new_rd_ASM(dbg_info *db, ir_graph *irg, ir_node *block,
int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text);
/*-------------------------------------------------------------------------*/
/* The raw interface without debug support */
......@@ -2791,11 +2794,14 @@ ir_node *new_r_Pin(ir_graph *irg, ir_node *block, ir_node *node);
* @param *inputs The array of length arity of input constraints.
* @param n_outs The number of data outputs to the node.
* @param *outputs The array of length n_outs of output constraints.
* @param n_clobber The number of clobbered registers.
* @param *clobber The array of length n_clobber of clobbered registers.
* @param *asm_text The assembler text.
*/
ir_node *new_r_ASM(ir_graph *irg, ir_node *block,
int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text);
/*-----------------------------------------------------------------------*/
/* The block oriented interface */
......@@ -3570,10 +3576,13 @@ ir_node *new_d_Pin(dbg_info *db, ir_node *node);
* @param *inputs The array of length arity of input constraints.
* @param n_outs The number of data outputs to the node.
* @param *outputs The array of length n_outs of output constraints.
* @param n_clobber The number of clobbered registers.
* @param *clobber The array of length n_clobber of clobbered registers.
* @param *asm_text The assembler text.
*/
ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text);
/*-----------------------------------------------------------------------*/
/* The block oriented interface without debug support */
......@@ -4290,10 +4299,13 @@ ir_node *new_Pin (ir_node *node);
* @param *inputs The array of length arity of input constraints.
* @param n_outs The number of data outputs to the node.
* @param *outputs The array of length n_outs of output constraints.
* @param n_clobber The number of clobbered registers.
* @param *clobber The array of length n_clobber of clobbered registers.
* @param *asm_text The assembler text.
*/
ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, ident *asm_text);
int n_outs, ir_asm_constraint *outputs,
int n_clobber, ident *clobber[], ident *asm_text);
/*---------------------------------------------------------------------*/
/* The comfortable interface. */
......
This diff is collapsed.
......@@ -2342,18 +2342,42 @@ const char *get_ASM_text(const ir_node *node) {
return get_id_str(node->attr.assem.asm_text);
}
/* Return the number of input constraints for an ASM node. */
int get_ASM_n_input_constraints(const ir_node *node) {
assert(node->op == op_ASM);
return ARR_LEN(node->attr.assem.inputs);
}
/* Return the input constraints for an ASM node. This is a flexible array. */
const ir_asm_constraint *get_ASM_input_constraints(const ir_node *node) {
assert(node->op == op_ASM);
return node->attr.assem.inputs;
}
/** Return the output constraints for an ASM node. This is a flexible array. */
/* Return the number of output constraints for an ASM node. */
int get_ASM_n_output_constraints(const ir_node *node) {
assert(node->op == op_ASM);
return ARR_LEN(node->attr.assem.outputs);
}
/* Return the output constraints for an ASM node. */
const ir_asm_constraint *get_ASM_output_constraints(const ir_node *node) {
assert(node->op == op_ASM);
return node->attr.assem.outputs;
}
/* Return the number of clobbered registers for an ASM node. */
int get_ASM_n_clobbers(const ir_node *node) {
assert(node->op == op_ASM);
return ARR_LEN(node->attr.assem.clobber);
}
/* Return the list of clobbered registers for an ASM node. */
ident **get_ASM_clobbers(const ir_node *node) {
assert(node->op == op_ASM);
return node->attr.assem.clobber;
}
/* returns the graph of a node */
ir_graph *
get_irn_irg(const ir_node *node) {
......
......@@ -1161,101 +1161,105 @@ typedef struct {
/** Return the assembler text of an ASM pseudo node. */
const char *get_ASM_text(const ir_node *node);
/** Return the input constraints for an ASM node. This is a flexible array. */
/** Return the number of input constraints for an ASM node. */
int get_ASM_n_input_constraints(const ir_node *node);
/** Return the input constraints for an ASM node. */
const ir_asm_constraint *get_ASM_input_constraints(const ir_node *node);
/** Return the output constraints for an ASM node. This is a flexible array. */
/** Return the number of output constraints for an ASM node. */
int get_ASM_n_output_constraints(const ir_node *node);
/** Return the output constraints for an ASM node. */
const ir_asm_constraint *get_ASM_output_constraints(const ir_node *node);
/** Return the number of clobbered registers for an ASM node. */
int get_ASM_n_clobbers(const ir_node *node);
/** Return the list of clobbered registers for an ASM node. */
ident **get_ASM_clobbers(const ir_node *node);
/*
*
* NAME Auxiliary routines
*
* Not properly documented ;-)
*
*/
/** returns operand of node if node is a Proj. */
/** Returns operand of node if node is a Proj. */
ir_node *skip_Proj(ir_node *node);
/** returns operand of node if node is a Proj. */
/** Returns operand of node if node is a Proj. */
const ir_node *skip_Proj_const(const ir_node *node);
/** returns operand of node if node is a Id */
/** Returns operand of node if node is a Id. */
ir_node *skip_Id(ir_node *node); /* Old name is skip_nop(). */
/** returns corresponding operand of Tuple if node is a Proj from
/** Returns corresponding operand of Tuple if node is a Proj from
a Tuple. */
ir_node *skip_Tuple(ir_node *node);
/** returns operand of node if node is a Cast */
/** returns operand of node if node is a Cast. */
ir_node *skip_Cast(ir_node *node);
/** returns operand of node if node is a Confirm */
/** Returns operand of node if node is a Confirm */
ir_node *skip_Confirm(ir_node *node);
/** Skip all high-level Operations. */
ir_node *skip_HighLevel(ir_node *node);
/** returns true if irn is a Const node. */
/** Returns true if irn is a Const node. */
int is_Const(const ir_node *node);
/** returns true if a node is a Conv node */
/** Returns true if a node is a Conv node. */
int is_Conv(const ir_node *node);
/** returns true if node is a Bad node. */
/** Returns true if node is a Bad node. */
int is_Bad(const ir_node *node);
/** returns true if node is a NoMem node. */
/** Returns true if node is a NoMem node. */
int is_NoMem(const ir_node *node);
/** returns true if node is a Start node. */
/** Returns true if node is a Start node. */
int is_Start(const ir_node *node);
/** return true if node is a Mod node. */
/** Returns true if node is a Mod node. */
int is_Mod(const ir_node *node);
/** return true if node is a Div node. */
/** Returns true if node is a Div node. */
int is_Div(const ir_node *node);
/** return true if node is a DivMod node. */
/** Returns true if node is a DivMod node. */
int is_DivMod(const ir_node *node);
/** return true if node is a Quot node. */
/** Returns true if node is a Quot node. */
int is_Quot(const ir_node *node);
/** return true if node is an Add node. */
/** Returns true if node is an Add node. */
int is_Add(const ir_node *node);
/** return true if node is a Sub node. */
/** Returns true if node is a Sub node. */
int is_Sub(const ir_node *node);
/** returns true if the node is not a Block */
/** Returns true if the node is not a Block */
int is_no_Block(const ir_node *node);
/** returns true if the node is a Block */
/** Returns true if the node is a Block */
int is_Block(const ir_node *node);
/** returns true if node is an Unknown node. */
/** Returns true if node is an Unknown node. */
int is_Unknown(const ir_node *node);
/** returns true if node is a Return node. */
/** Returns true if node is a Return node. */
int is_Return(const ir_node *node);
/** returns true if node is a Call node. */
/** Returns true if node is a Call node. */
int is_Call(const ir_node *node);
/** returns true if node is a Sel node. */
/** Returns true if node is a Sel node. */
int is_Sel(const ir_node *node);
/** returns true if node is a Mul node. */
/** Returns true if node is a Mul node. */
int is_Mul(const ir_node *node);
/** returns true if node is a Mux node or a Psi with only one condition. */
/** Returns true if node is a Mux node or a Psi with only one condition. */
int is_Mux(const ir_node *node);
/** returns true if node is a Load node. */
/** Returns true if node is a Load node. */
int is_Load(const ir_node *node);
/** returns true if node is a Store node. */
/** Returns true if node is a Store node. */
int is_Store(const ir_node *node);
/** returns true if node is a Sync node. */
/** Returns true if node is a Sync node. */
int is_Sync(const ir_node *node);
/** returns true if node is a Confirm node. */
/** Returns true if node is a Confirm node. */
int is_Confirm(const ir_node *node);
/** returns true if node is a Pin node. */
/** Returns true if node is a Pin node. */
int is_Pin(const ir_node *node);
/** returns true if node is a SymConst node. */
/** Returns true if node is a SymConst node. */
int is_SymConst(const ir_node *node);
/** returns true if node is a Cond node. */
/** Returns true if node is a Cond node. */
int is_Cond(const ir_node *node);
/** returns true of node is a CopyB node */
/** Returns true of node is a CopyB node */
int is_CopyB(const ir_node *node);
/** returns true if node is a Cmp node. */
/** Returns true if node is a Cmp node. */
int is_Cmp(const ir_node *node);
/** returns true if node is an Alloc node */
/** Returns true if node is an Alloc node */
int is_Alloc(const ir_node *node);
/** returns true if a node is a Jmp node */
/** Returns true if a node is a Jmp node */
int is_Jmp(const ir_node *node);
/** returns true if a node is a Raise node */
/** Returns true if a node is a Raise node */
int is_Raise(const ir_node *node);
/** returns true if a node is an ASM node */
/** Returns true if a node is an ASM node */
int is_ASM(const ir_node *node);
/** returns true if node is a Proj node or a Filter node in
/** Returns true if node is a Proj node or a Filter node in
* intraprocedural view */
int is_Proj(const ir_node *node);
/** Returns true if the operation manipulates control flow:
......
......@@ -172,12 +172,12 @@ typedef struct {
} store_attr;
typedef struct {
int pos; /**< For Phi. Used to remember the value defined by
this Phi node. Needed when the Phi is completed
to call get_r_internal_value to find the
predecessors. If this attribute is set, the Phi
node takes the role of the obsolete Phi0 node,
therefore the name. */
int pos; /**< For Phi0. Used to remember the value defined by
this Phi node. Needed when the Phi is completed
to call get_r_internal_value to find the
predecessors. If this attribute is set, the Phi
node takes the role of the obsolete Phi0 node,
therefore the name. */
} phi0_attr;
......@@ -211,6 +211,7 @@ typedef struct {
ident *asm_text; /**< The inline assembler text. */
ir_asm_constraint *inputs; /**< Input constraints. */
ir_asm_constraint *outputs; /**< Output constraints. */
ident **clobber; /**< List of clobbered registers. */
} asm_attr;
/** Some IR-nodes just have one attribute, these are stored here,
......
......@@ -187,6 +187,7 @@ ASM_copy_attr(const ir_node *old_node, ir_node *new_node) {
default_copy_attr(old_node, new_node);
new_node->attr.assem.inputs = DUP_ARR_D(ir_asm_constraint, irg->obst, old_node->attr.assem.inputs);
new_node->attr.assem.outputs = DUP_ARR_D(ir_asm_constraint, irg->obst, old_node->attr.assem.outputs);
new_node->attr.assem.clobber = DUP_ARR_D(ir_asm_constraint, irg->obst, old_node->attr.assem.clobber);
}
/**
......
......@@ -3510,6 +3510,51 @@ static int node_cmp_attr_Confirm(ir_node *a, ir_node *b) {
return (get_Confirm_cmp(a) != get_Confirm_cmp(b));
} /* node_cmp_attr_Confirm */
/** Compares the attributes of two ASM nodes. */
static int node_cmp_attr_ASM(ir_node *a, ir_node *b) {
int i, n;
ir_asm_constraint *ca, *cb;
ident **cla, **clb;
if (get_ASM_text(a) != get_ASM_text(b));
return 1;
/* Should we really check the constraints here? Should be better, but is strange. */
n = get_ASM_n_input_constraints(a);
if (n != get_ASM_n_input_constraints(b))
return 0;
ca = get_ASM_input_constraints(a);
cb = get_ASM_input_constraints(b);
for (i = 0; i < n; ++i) {
if (ca[i].pos != cb[i].pos || ca[i].constraint != cb[i].constraint)
return 1;
}
n = get_ASM_n_output_constraints(a);
if (n != get_ASM_n_output_constraints(b))
return 0;
ca = get_ASM_output_constraints(a);
cb = get_ASM_output_constraints(b);
for (i = 0; i < n; ++i) {
if (ca[i].pos != cb[i].pos || ca[i].constraint != cb[i].constraint)
return 1;
}
n = get_ASM_n_clobbers(a);
if (n != get_ASM_n_clobbers(b))
return 0;
cla = get_ASM_clobbers(a);
clb = get_ASM_clobbers(b);
for (i = 0; i < n; ++i) {
if (cla[i] != clb[i])
return 1;
}
return 0;
} /* node_cmp_attr_ASM */
/**
* Set the default node attribute compare operation for an ir_op_ops.
*
......@@ -3541,6 +3586,7 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
CASE(Load);
CASE(Store);
CASE(Confirm);
CASE(ASM);
default:
/* leave NULL */;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment