You can still attach NoMem if no memory input is present.
This makes it more consistent with the Call node and fixes failing
get_ASM_mem in case of no memory input.
*
* @param *db A pointer for debug information.
* @param *block The block the node belong to.
+ * @param *mem memory dependency
* @param arity The number of data inputs to the node.
* @param *in The array of length arity of data inputs.
* @param *inputs The array of length arity of input constraints.
* @param *clobber The array of length n_clobber of clobbered registers.
* @param *asm_text The assembler text.
*/
-FIRM_API ir_node *new_rd_ASM(dbg_info *db, ir_node *block,
+FIRM_API 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, ident *clobber[],
/** Constructor for an ASM pseudo node.
*
* @param *block The block the node belong to.
+ * @param *mem memory dependency
* @param arity The number of data inputs to the node.
* @param *in The array of length arity of data inputs.
* @param *inputs The array of length arity of input constraints.
* @param *clobber The array of length n_clobber of clobbered registers.
* @param *asm_text The assembler text.
*/
-FIRM_API ir_node *new_r_ASM(ir_node *block,
+FIRM_API 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,
size_t n_clobber, ident *clobber[],
/** Constructor for an ASM pseudo node.
*
* @param *db A pointer for debug information.
+ * @param *mem memory dependency
* @param arity The number of data inputs to the node.
* @param *in The array of length arity of data inputs.
* @param *inputs The array of length arity of input constraints.
* @param *asm_text The assembler text.
* @ingroup ASM
*/
-FIRM_API ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[],
- ir_asm_constraint *inputs,
+FIRM_API 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_clobber, ident *clobber[],
ident *asm_text);
/** Constructor for an ASM pseudo node.
*
+ * @param *mem memory dependency
* @param arity The number of data inputs to the node.
* @param *in The array of length arity of data inputs.
* @param *inputs The array of length arity of input constraints.
* @param *asm_text The assembler text.
* @ingroup ASM
*/
-FIRM_API ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
- size_t n_outs, ir_asm_constraint *outputs,
+FIRM_API 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, ident *clobber[], ident *asm_text);
/** @} */
*/
/** Returns the number of input constraints for an ASM node. */
-FIRM_API size_t get_ASM_n_input_constraints(const ir_node *node);
+FIRM_API int get_ASM_n_inputs(const ir_node *node);
+/** Returns input number @p pos of an ASM node. */
+FIRM_API ir_node *get_ASM_input(const ir_node *node, int pos);
/** Returns the number of output constraints for an ASM node. */
FIRM_API size_t get_ASM_n_output_constraints(const ir_node *node);
/** Returns the number of clobbered registers for an ASM node. */
ir_node *ia32_gen_ASM(ir_node *node)
{
- ir_node *block = get_nodes_block(node);
- ir_node *new_block = get_new_node(block);
- dbg_info *dbgi = get_irn_dbg_info(node);
- int arity;
- size_t value_arity;
- size_t out_idx;
- ir_node **in;
- ir_node *new_node;
- size_t out_arity;
- size_t n_out_constraints;
- size_t n_clobbers;
- const arch_register_req_t **out_reg_reqs;
- const arch_register_req_t **in_reg_reqs;
- ia32_asm_reg_t *register_map;
- unsigned reg_map_size = 0;
- struct obstack *obst;
- const ir_asm_constraint *in_constraints;
- const ir_asm_constraint *out_constraints;
- ident **clobbers;
- unsigned clobber_bits[N_IA32_CLASSES];
- size_t out_size;
- backend_info_t *info;
- int i;
- size_t c;
- size_t o;
-
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = get_new_node(block);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ int n_inputs = get_ASM_n_inputs(node);
+ int n_ins = n_inputs+1;
+ ir_node **in = ALLOCANZ(ir_node*, n_ins);
+ size_t n_clobbers = 0;
+ ident **clobbers = get_ASM_clobbers(node);
+ unsigned reg_map_size = 0;
+ ir_graph *irg = get_irn_irg(node);
+ struct obstack *obst = get_irg_obstack(irg);
+ unsigned clobber_bits[N_IA32_CLASSES];
memset(&clobber_bits, 0, sizeof(clobber_bits));
- arity = get_irn_arity(node);
- in = ALLOCANZ(ir_node*, arity);
-
- clobbers = get_ASM_clobbers(node);
- n_clobbers = 0;
- for (c = 0; c < get_ASM_n_clobbers(node); ++c) {
- const arch_register_req_t *req;
+ for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) {
const char *clobber = get_id_str(clobbers[c]);
-
- if (strcmp(clobber, "memory") == 0)
+ const arch_register_req_t *req = ia32_parse_clobber(clobber);
+ if (req == NULL)
continue;
- if (strcmp(clobber, "cc") == 0) {
- continue;
- }
- req = ia32_parse_clobber(clobber);
clobber_bits[req->cls->index] |= *req->limited;
-
- n_clobbers++;
+ assert(req->cls->n_regs <= sizeof(unsigned)*8);
+ ++n_clobbers;
}
- n_out_constraints = get_ASM_n_output_constraints(node);
- out_arity = n_out_constraints + n_clobbers;
+ size_t n_out_constraints = get_ASM_n_output_constraints(node);
+ size_t out_arity = n_out_constraints + n_clobbers;
- in_constraints = get_ASM_input_constraints(node);
- out_constraints = get_ASM_output_constraints(node);
+ const ir_asm_constraint *in_constraints = get_ASM_input_constraints(node);
+ const ir_asm_constraint *out_constraints = get_ASM_output_constraints(node);
/* determine size of register_map */
- for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
+ for (size_t out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
const ir_asm_constraint *constraint = &out_constraints[out_idx];
- if (constraint->pos > reg_map_size)
- reg_map_size = constraint->pos;
+ if (constraint->pos+1 > reg_map_size)
+ reg_map_size = constraint->pos+1;
}
- for (i = 0; i < arity; ++i) {
+ for (int i = 0; i < n_inputs; ++i) {
const ir_asm_constraint *constraint = &in_constraints[i];
- if (constraint->pos > reg_map_size)
- reg_map_size = constraint->pos;
+ if (constraint->pos+1 > reg_map_size)
+ reg_map_size = constraint->pos+1;
}
- ++reg_map_size;
- obst = get_irg_obstack(current_ir_graph);
- register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
+ ia32_asm_reg_t *register_map
+ = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
/* construct output constraints */
- out_size = out_arity + 1;
- out_reg_reqs = OALLOCN(obst, const arch_register_req_t*, out_size);
+ size_t out_size = out_arity + 1;
+ const arch_register_req_t **out_reg_reqs
+ = OALLOCN(obst, const arch_register_req_t*, out_size);
+ size_t out_idx;
for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
- const ir_asm_constraint *constraint = &out_constraints[out_idx];
- const char *c = get_id_str(constraint->constraint);
- unsigned pos = constraint->pos;
- constraint_t parsed_constraint;
- const arch_register_req_t *req;
-
+ constraint_t parsed_constraint;
+ const ir_asm_constraint *constraint = &out_constraints[out_idx];
+ const char *c = get_id_str(constraint->constraint);
+ unsigned pos = constraint->pos;
parse_asm_constraints(&parsed_constraint, c, true);
- req = ia32_make_register_req(&parsed_constraint, n_out_constraints,
+ const arch_register_req_t *req
+ = ia32_make_register_req(&parsed_constraint, n_out_constraints,
out_reg_reqs, out_idx);
out_reg_reqs[out_idx] = req;
}
/* inputs + input constraints */
- in_reg_reqs = OALLOCN(obst, const arch_register_req_t*, arity);
- for (i = 0; i < arity; ++i) {
- ir_node *pred = get_irn_n(node, i);
+ const arch_register_req_t **in_reg_reqs
+ = OALLOCN(obst, const arch_register_req_t*, n_ins);
+ for (int i = 0; i < n_inputs; ++i) {
+ constraint_t parsed_constraint;
+ ir_node *pred = get_ASM_input(node, i);
const ir_asm_constraint *constraint = &in_constraints[i];
ident *constr_id = constraint->constraint;
const char *c = get_id_str(constr_id);
unsigned pos = constraint->pos;
int is_memory_op = 0;
ir_node *input = NULL;
- unsigned r_clobber_bits;
- constraint_t parsed_constraint;
- const arch_register_req_t *req;
parse_asm_constraints(&parsed_constraint, c, false);
if (parsed_constraint.cls != NULL) {
- r_clobber_bits = clobber_bits[parsed_constraint.cls->index];
+ unsigned r_clobber_bits
+ = clobber_bits[parsed_constraint.cls->index];
if (r_clobber_bits != 0) {
if (parsed_constraint.all_registers_allowed) {
parsed_constraint.all_registers_allowed = 0;
- be_set_allocatable_regs(current_ir_graph,
+ be_set_allocatable_regs(irg,
parsed_constraint.cls,
&parsed_constraint.allowed_registers);
}
}
}
- req = ia32_make_register_req(&parsed_constraint, n_out_constraints,
- out_reg_reqs, i);
+ const arch_register_req_t *req
+ = ia32_make_register_req(&parsed_constraint, n_out_constraints,
+ out_reg_reqs, i);
in_reg_reqs[i] = req;
if (parsed_constraint.immediate_type != '\0') {
register_map[pos].mode = constraint->mode;
}
+ assert(n_inputs == n_ins-1);
+ ir_node *mem = get_ASM_mem(node);
+ in[n_inputs] = be_transform_node(mem);
+ in_reg_reqs[n_inputs] = arch_no_register_req;
+
/* parse clobbers */
- for (c = 0; c < get_ASM_n_clobbers(node); ++c) {
+ for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) {
const char *clobber = get_id_str(clobbers[c]);
- const arch_register_req_t *req;
-
- if (strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0)
+ const arch_register_req_t *req = ia32_parse_clobber(clobber);
+ if (req == NULL)
continue;
-
- req = ia32_parse_clobber(clobber);
out_reg_reqs[out_idx] = req;
++out_idx;
}
- /* count inputs which are real values (and not memory) */
- value_arity = 0;
- for (i = 0; i < arity; ++i) {
- ir_node *node_in = get_irn_n(node, i);
- if (get_irn_mode(node_in) == mode_M)
- continue;
- ++value_arity;
- }
-
/* Attempt to make ASM node register pressure faithful.
* (This does not work for complicated cases yet!)
*
* before...
* FIXME: need to do this per register class...
*/
- if (out_arity <= value_arity) {
- int orig_arity = arity;
- int in_size = arity;
- bitset_t *used_ins = bitset_alloca(arity);
- size_t o;
- for (o = 0; o < out_arity; ++o) {
+ if (out_arity <= (size_t)n_inputs) {
+ int orig_inputs = n_ins;
+ int in_size = n_ins;
+ bitset_t *used_ins = bitset_alloca(n_ins);
+ for (size_t o = 0; o < out_arity; ++o) {
const arch_register_req_t *outreq = out_reg_reqs[o];
if (outreq->cls == NULL) {
continue;
}
- for (i = 0; i < orig_arity; ++i) {
- const arch_register_req_t *inreq;
+ int i;
+ for (i = 0; i < orig_inputs; ++i) {
if (bitset_is_set(used_ins, i))
continue;
- inreq = in_reg_reqs[i];
+ const arch_register_req_t *inreq = in_reg_reqs[i];
if (!can_match(outreq, inreq))
continue;
bitset_set(used_ins, i);
break;
}
/* did we find any match? */
- if (i < orig_arity)
+ if (i < orig_inputs)
continue;
/* we might need more space in the input arrays */
- if (arity >= in_size) {
- const arch_register_req_t **new_in_reg_reqs;
- ir_node **new_in;
-
+ if (n_ins >= in_size) {
in_size *= 2;
- new_in_reg_reqs = OALLOCN(obst, const arch_register_req_t*,
+ const arch_register_req_t **new_in_reg_reqs
+ = OALLOCN(obst, const arch_register_req_t*,
in_size);
- memcpy(new_in_reg_reqs, in_reg_reqs, arity * sizeof(new_in_reg_reqs[0]));
- new_in = ALLOCANZ(ir_node*, in_size);
- memcpy(new_in, in, arity*sizeof(new_in[0]));
+ memcpy(new_in_reg_reqs, in_reg_reqs,
+ n_ins*sizeof(new_in_reg_reqs[0]));
+ ir_node **new_in = ALLOCANZ(ir_node*, in_size);
+ memcpy(new_in, in, n_ins*sizeof(new_in[0]));
in_reg_reqs = new_in_reg_reqs;
in = new_in;
/* add a new (dummy) input which occupies the register */
assert(outreq->type & arch_register_req_type_limited);
- in_reg_reqs[arity] = outreq;
- in[arity] = new_bd_ia32_ProduceVal(NULL, block);
- ++arity;
+ in_reg_reqs[n_ins] = outreq;
+ in[n_ins] = new_bd_ia32_ProduceVal(NULL, block);
+ ++n_ins;
}
} else {
bitset_t *used_outs = bitset_alloca(out_arity);
size_t orig_out_arity = out_arity;
- for (i = 0; i < arity; ++i) {
+ for (int i = 0; i < n_inputs; ++i) {
const arch_register_req_t *inreq = in_reg_reqs[i];
- size_t o;
- if (inreq->cls == NULL) {
+ if (inreq->cls == NULL)
continue;
- }
+ size_t o;
for (o = 0; o < orig_out_arity; ++o) {
const arch_register_req_t *outreq;
if (bitset_is_set(used_outs, o))
out_reg_reqs[out_arity] = arch_no_register_req;
++out_arity;
- new_node = new_bd_ia32_Asm(dbgi, new_block, arity, in, out_arity,
- get_ASM_text(node), register_map);
+ ir_node *new_node = new_bd_ia32_Asm(dbgi, new_block, n_ins, in, out_arity,
+ get_ASM_text(node), register_map);
- info = be_get_info(new_node);
- for (o = 0; o < out_arity; ++o) {
+ backend_info_t *info = be_get_info(new_node);
+ for (size_t o = 0; o < out_arity; ++o) {
info->out_infos[o].req = out_reg_reqs[o];
}
arch_set_irn_register_reqs_in(new_node, in_reg_reqs);
return res;
}
-const arch_register_req_t *ia32_make_register_req(const constraint_t *constraint,
- int n_outs, const arch_register_req_t **out_reqs, int pos)
+const arch_register_req_t *ia32_make_register_req(
+ const constraint_t *constraint, int n_outs,
+ const arch_register_req_t **out_reqs, int pos)
{
struct obstack *obst = get_irg_obstack(current_ir_graph);
int same_as = constraint->same_as;
const arch_register_req_t *ia32_parse_clobber(const char *clobber)
{
+ if (strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0)
+ return NULL;
+
struct obstack *obst = get_irg_obstack(current_ir_graph);
const arch_register_t *reg = ia32_get_clobber_register(clobber);
arch_register_req_t *req;
return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
}
-ir_node *new_rd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[],
- ir_asm_constraint *inputs, size_t n_outs,
- ir_asm_constraint *outputs, size_t n_clobber,
+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,
ident *clobber[], ident *text)
{
ir_graph *irg = get_irn_irg(block);
- ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, arity, in);
+
+ int r_arity = arity+1;
+ ir_node **r_in;
+ NEW_ARR_A(ir_node*, r_in, r_arity);
+ r_in[0] = mem;
+ memcpy(&r_in[1], in, arity*sizeof(ir_node*));
+
+ ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, r_arity, r_in);
res->attr.assem.pin_state = op_pin_state_pinned;
res->attr.assem.input_constraints
{
return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent);
}
-ir_node *new_r_ASM(ir_node *block,
+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,
size_t n_clobber, ident *clobber[], ident *text)
{
- return new_rd_ASM(NULL, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
+ return new_rd_ASM(NULL, block, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
}
/** Creates a Phi node with 0 predecessors. */
return new_rd_SymConst(db, current_ir_graph, mode, value, kind);
}
-ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[],
+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_clobber, ident *clobber[], ident *text)
{
assert(get_irg_phase_state(current_ir_graph) == phase_building);
- return new_rd_ASM(db, current_ir_graph->current_block, arity, in, inputs,
- n_outs, outputs, n_clobber, clobber, text);
+ return new_rd_ASM(db, current_ir_graph->current_block, mem, arity, in,
+ inputs, n_outs, outputs, n_clobber, clobber, text);
}
ir_node *new_rd_strictConv(dbg_info *dbgi, ir_node *block, ir_node * irn_op, ir_mode * mode)
{
return new_d_simpleSel(NULL, store, objptr, ent);
}
-ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
- size_t n_outs, ir_asm_constraint *outputs,
- size_t n_clobber, ident *clobber[], ident *text)
+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,
+ ident *clobber[], ident *text)
{
- return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
+ return new_d_ASM(NULL, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
}
ir_node *new_r_Anchor(ir_graph *irg)
fprintf(F, " compare operation: %s\n", get_relation_string(get_Confirm_relation(n)));
break;
case iro_ASM: {
- const ir_asm_constraint *cons;
- ident **clobber;
- int l;
-
fprintf(F, " assembler text: %s", get_id_str(get_ASM_text(n)));
- l = get_ASM_n_input_constraints(n);
- if (l > 0) {
- int i;
- fprintf(F, "\n inputs: ");
- cons = get_ASM_input_constraints(n);
- for (i = 0; i < l; ++i)
- fprintf(F, "%%%u %s ", cons[i].pos, get_id_str(cons[i].constraint));
- }
- l = get_ASM_n_output_constraints(n);
- if (l > 0) {
- int i;
- fprintf(F, "\n outputs: ");
- cons = get_ASM_output_constraints(n);
- for (i = 0; i < l; ++i)
- fprintf(F, "%%%u %s ", cons[i].pos, get_id_str(cons[i].constraint));
+ fprintf(F, "\n inputs: ");
+ const ir_asm_constraint *in_cons = get_ASM_input_constraints(n);
+ int n_inputs = get_ASM_n_inputs(n);
+ for (int i = 0; i < n_inputs; ++i) {
+ fprintf(F, "%%%u %s ", in_cons[i].pos,
+ get_id_str(in_cons[i].constraint));
}
- l = get_ASM_n_clobbers(n);
- if (l > 0) {
- int i;
- fprintf(F, "\n clobber: ");
- clobber = get_ASM_clobbers(n);
- for (i = 0; i < l; ++i)
- fprintf(F, "%s ", get_id_str(clobber[i]));
+ fprintf(F, "\n outputs: ");
+ const ir_asm_constraint *out_cons = get_ASM_output_constraints(n);
+ int n_outputs = get_ASM_n_output_constraints(n);
+ for (int i = 0; i < n_outputs; ++i) {
+ fprintf(F, "%%%u %s ", out_cons[i].pos,
+ get_id_str(out_cons[i].constraint));
}
+
+ fprintf(F, "\n clobber: ");
+ ident **clobber = get_ASM_clobbers(n);
+ int n_clobbers = get_ASM_n_clobbers(n);
+ for (int i = 0; i < n_clobbers; ++i)
+ fprintf(F, "%s ", get_id_str(clobber[i]));
if (get_irn_pinned(n) != op_pin_state_floats)
fprintf(F, "\n volatile");
fprintf(F, "\n");
- } break;
+ break;
+ }
default:
break;
static void write_ASM(write_env_t *env, const ir_node *node)
{
- ir_asm_constraint *input_constraints = get_ASM_input_constraints(node);
- ir_asm_constraint *output_constraints = get_ASM_output_constraints(node);
- ident **clobbers = get_ASM_clobbers(node);
- size_t n_input_constraints = get_ASM_n_input_constraints(node);
- size_t n_output_constraints = get_ASM_n_output_constraints(node);
- size_t n_clobbers = get_ASM_n_clobbers(node);
- size_t i;
-
write_symbol(env, "ASM");
write_node_nr(env, node);
write_node_nr(env, get_nodes_block(node));
+ write_node_nr(env, get_ASM_mem(node));
write_ident(env, get_ASM_text(node));
write_list_begin(env);
- for (i = 0; i < n_input_constraints; ++i) {
+ 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_list_end(env);
write_list_begin(env);
- for (i = 0; i < n_output_constraints; ++i) {
+ 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);
write_ident(env, constraint->constraint);
write_list_end(env);
write_list_begin(env);
- for (i = 0; i < n_clobbers; ++i) {
+ ident **clobbers = get_ASM_clobbers(node);
+ size_t n_clobbers = get_ASM_n_clobbers(node);
+ for (size_t i = 0; i < n_clobbers; ++i) {
ident *clobber = clobbers[i];
write_ident(env, clobber);
}
ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0);
ident **clobbers = NEW_ARR_F(ident*, 0);
ir_node *block = read_node_ref(env);
+ ir_node *mem = read_node_ref(env);
op_pin_state pin_state;
ident *asm_text = read_ident(env);
return new_r_Bad(env->irg, mode_T);
}
- newnode = new_r_ASM(block, n_in, in,
+ newnode = new_r_ASM(block, mem, n_in, in,
input_constraints, ARR_LEN(output_constraints),
output_constraints, ARR_LEN(clobbers),
clobbers, asm_text);
in the in array */
#define CALL_PARAM_OFFSET (n_Call_max+1)
#define BUILTIN_PARAM_OFFSET (n_Builtin_max+1)
+#define ASM_PARAM_OFFSET (n_ASM_max+1)
#define SEL_INDEX_OFFSET (n_Sel_max+1)
#define RETURN_RESULT_OFFSET (n_Return_max+1)
#define END_KEEPALIVE_OFFSET 0
set_irn_n(node, pos, pred);
}
-size_t get_ASM_n_input_constraints(const ir_node *node)
+int get_ASM_n_inputs(const ir_node *node)
{
assert(is_ASM(node));
- return ARR_LEN(node->attr.assem.input_constraints);
+ return get_irn_arity(node) - ASM_PARAM_OFFSET;
+}
+
+ir_node *get_ASM_input(const ir_node *node, int pos)
+{
+ return get_irn_n(node, ASM_PARAM_OFFSET + pos);
}
size_t get_ASM_n_output_constraints(const ir_node *node)
/** Compares the attributes of two ASM nodes. */
static int node_cmp_attr_ASM(const ir_node *a, const ir_node *b)
{
- size_t n;
- size_t i;
- const ir_asm_constraint *ca;
- const ir_asm_constraint *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))
+ int n_inputs = get_ASM_n_inputs(a);
+ if (n_inputs != get_ASM_n_inputs(b))
return 1;
- 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
- || ca[i].mode != cb[i].mode)
+ 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 1;
}
- n = get_ASM_n_output_constraints(a);
- if (n != get_ASM_n_output_constraints(b))
+ size_t n_outputs = get_ASM_n_output_constraints(a);
+ if (n_outputs != get_ASM_n_output_constraints(b))
return 1;
- 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
- || ca[i].mode != cb[i].mode)
+ 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)
return 1;
}
- n = get_ASM_n_clobbers(a);
- if (n != get_ASM_n_clobbers(b))
+ size_t n_clobbers = get_ASM_n_clobbers(a);
+ if (n_clobbers != get_ASM_n_clobbers(b))
return 1;
- cla = get_ASM_clobbers(a);
- clb = get_ASM_clobbers(b);
- for (i = 0; i < n; ++i) {
+ ident **cla = get_ASM_clobbers(a);
+ ident **clb = get_ASM_clobbers(b);
+ for (size_t i = 0; i < n_clobbers; ++i) {
if (cla[i] != clb[i])
return 1;
}
ir_asm_constraint *output_constraints = get_ASM_output_constraints(asmn);
ir_asm_constraint *input_constraints = get_ASM_input_constraints(asmn);
unsigned n_64bit_outs = 0;
- int i;
(void)mode;
- for (i = get_irn_arity(asmn) - 1; i >= 0; --i) {
+ for (int i = get_irn_arity(asmn) - 1; i >= 0; --i) {
ir_node *op = get_irn_n(asmn, i);
ir_mode *op_mode = get_irn_mode(op);
if (op_mode == high_signed || op_mode == high_unsigned) {
}
}
- for (i = 0; i < n_outs; ++i) {
- const ir_asm_constraint *constraint = &output_constraints[i];
+ for (int o = 0; o < n_outs; ++o) {
+ const ir_asm_constraint *constraint = &output_constraints[o];
if (constraint->mode == high_signed || constraint->mode == high_unsigned) {
const char *constr = get_id_str(constraint->constraint);
++n_64bit_outs;
if (n_64bit_outs == 0)
return;
- {
- dbg_info *dbgi = get_irn_dbg_info(asmn);
- ir_node *block = get_nodes_block(asmn);
- int arity = get_irn_arity(asmn);
- ir_node **in = get_irn_in(asmn) + 1;
- int new_n_outs = 0;
- int n_clobber = get_ASM_n_clobbers(asmn);
- long *proj_map = ALLOCAN(long, n_outs);
- ident **clobbers = get_ASM_clobbers(asmn);
- ident *asm_text = get_ASM_text(asmn);
- ir_asm_constraint *new_outputs
- = ALLOCAN(ir_asm_constraint, n_outs+n_64bit_outs);
- ir_node *new_asm;
-
- for (i = 0; i < n_outs; ++i) {
- const ir_asm_constraint *constraint = &output_constraints[i];
- if (constraint->mode == high_signed || constraint->mode == high_unsigned) {
- new_outputs[new_n_outs].pos = constraint->pos;
- new_outputs[new_n_outs].constraint = new_id_from_str("=a");
- new_outputs[new_n_outs].mode = env->low_unsigned;
- proj_map[i] = new_n_outs;
- ++new_n_outs;
- new_outputs[new_n_outs].pos = constraint->pos;
- new_outputs[new_n_outs].constraint = new_id_from_str("=d");
- if (constraint->mode == high_signed)
- new_outputs[new_n_outs].mode = env->low_signed;
- else
- new_outputs[new_n_outs].mode = env->low_unsigned;
- ++new_n_outs;
- } else {
- new_outputs[new_n_outs] = *constraint;
- proj_map[i] = new_n_outs;
- ++new_n_outs;
- }
+ dbg_info *dbgi = get_irn_dbg_info(asmn);
+ ir_node *block = get_nodes_block(asmn);
+ ir_node *mem = get_ASM_mem(asmn);
+ int new_n_outs = 0;
+ int n_clobber = get_ASM_n_clobbers(asmn);
+ long *proj_map = ALLOCAN(long, n_outs);
+ ident **clobbers = get_ASM_clobbers(asmn);
+ ident *asm_text = get_ASM_text(asmn);
+ ir_asm_constraint *new_outputs
+ = ALLOCAN(ir_asm_constraint, n_outs+n_64bit_outs);
+ ir_node *new_asm;
+
+ for (int o = 0; o < n_outs; ++o) {
+ const ir_asm_constraint *constraint = &output_constraints[o];
+ if (constraint->mode == high_signed || constraint->mode == high_unsigned) {
+ new_outputs[new_n_outs].pos = constraint->pos;
+ new_outputs[new_n_outs].constraint = new_id_from_str("=a");
+ new_outputs[new_n_outs].mode = env->low_unsigned;
+ proj_map[o] = new_n_outs;
+ ++new_n_outs;
+ new_outputs[new_n_outs].pos = constraint->pos;
+ new_outputs[new_n_outs].constraint = new_id_from_str("=d");
+ if (constraint->mode == high_signed)
+ new_outputs[new_n_outs].mode = env->low_signed;
+ else
+ new_outputs[new_n_outs].mode = env->low_unsigned;
+ ++new_n_outs;
+ } else {
+ new_outputs[new_n_outs] = *constraint;
+ proj_map[o] = new_n_outs;
+ ++new_n_outs;
}
- assert(new_n_outs == n_outs+(int)n_64bit_outs);
+ }
+ assert(new_n_outs == n_outs+(int)n_64bit_outs);
- new_asm = new_rd_ASM(dbgi, block, arity, in, input_constraints,
- new_n_outs, new_outputs, n_clobber, clobbers,
- asm_text);
+ int n_inputs = get_ASM_n_inputs(asmn);
+ ir_node **new_ins = ALLOCAN(ir_node*, n_inputs);
+ for (int i = 0; i < n_inputs; ++i)
+ new_ins[i] = get_ASM_input(asmn, i);
- foreach_out_edge_safe(asmn, edge) {
- ir_node *proj = get_edge_src_irn(edge);
- ir_mode *proj_mode = get_irn_mode(proj);
- long pn;
+ new_asm = new_rd_ASM(dbgi, block, mem, n_inputs, new_ins, input_constraints,
+ new_n_outs, new_outputs, n_clobber, clobbers,
+ asm_text);
- if (!is_Proj(proj))
- continue;
- pn = get_Proj_proj(proj);
+ foreach_out_edge_safe(asmn, edge) {
+ ir_node *proj = get_edge_src_irn(edge);
+ ir_mode *proj_mode = get_irn_mode(proj);
+ long pn;
- if (pn < n_outs)
- pn = proj_map[pn];
- else
- pn = new_n_outs + pn - n_outs;
-
- if (proj_mode == high_signed || proj_mode == high_unsigned) {
- ir_mode *high_mode
- = proj_mode == high_signed ? env->low_signed : env->low_unsigned;
- ir_node *np_low = new_r_Proj(new_asm, env->low_unsigned, pn);
- ir_node *np_high = new_r_Proj(new_asm, high_mode, pn+1);
- ir_set_dw_lowered(proj, np_low, np_high);
- } else {
- ir_node *np = new_r_Proj(new_asm, proj_mode, pn);
- exchange(proj, np);
- }
+ if (!is_Proj(proj))
+ continue;
+ pn = get_Proj_proj(proj);
+
+ if (pn < n_outs)
+ pn = proj_map[pn];
+ else
+ pn = new_n_outs + pn - n_outs;
+
+ if (proj_mode == high_signed || proj_mode == high_unsigned) {
+ ir_mode *high_mode
+ = proj_mode == high_signed ? env->low_signed : env->low_unsigned;
+ ir_node *np_low = new_r_Proj(new_asm, env->low_unsigned, pn);
+ ir_node *np_high = new_r_Proj(new_asm, high_mode, pn+1);
+ ir_set_dw_lowered(proj, np_low, np_high);
+ } else {
+ ir_node *np = new_r_Proj(new_asm, proj_mode, pn);
+ exchange(proj, np);
}
}
}