return create_const_graph_value(abi, irn, block, value);
}
-
/**
* Creates code for a Firm Const node.
*/
-static ir_node *gen_Const(ir_node *irn, arm_code_gen_t *cg) {
+static ir_node *gen_arm_Const(ir_node *irn, ir_node *block, arm_code_gen_t *cg) {
ir_graph *irg = current_ir_graph;
- ir_node *block = get_nodes_block(irn);
ir_mode *mode = get_irn_mode(irn);
dbg_info *dbg = get_irn_dbg_info(irn);
if (mode_is_float(mode)) {
- if (USE_FPA(cg->isa))
- return new_rd_arm_fpaConst(dbg, irg, block, mode, get_Const_tarval(irn));
+ cg->have_fp = 1;
+ if (USE_FPA(cg->isa)) {
+ irn = new_rd_arm_fpaConst(dbg, irg, block, get_Const_tarval(irn));
+ /* ensure the const is schedules AFTER the barrier */
+ add_irn_dep(irn, be_abi_get_start_barrier(cg->birg->abi));
+ return irn;
+ }
else if (USE_VFP(cg->isa))
assert(mode != mode_E && "IEEE Extended FP not supported");
assert(0 && "NYI");
}
- const_node = new_rd_Const(dbg, irg, block, mode_Iu, new_tarval_from_long(translation, mode_Iu));
- const_graph = gen_Const(const_node, cg);
+ const_node = new_rd_Const(dbg, irg, block, mode_Iu, new_tarval_from_long(translation, mode_Iu));
+ const_graph = create_const_graph(cg->birg->abi, const_node, block);
sub = new_rd_arm_Sub(dbg, irg, block, op, const_graph, get_irn_mode(op), ARM_SHF_NONE, NULL);
result = new_rd_arm_SwitchJmp(dbg, irg, block, sub,
n_projs, get_Cond_defaultProj(irn)-translation);
ir_node *pred = get_irn_n(node,i);
ir_opcode pred_code = get_irn_opcode(pred);
if (pred_code == iro_Const) {
- ir_node *const_graph;
- const_graph = create_const_graph(cg->birg->abi, pred, get_nodes_block(get_irn_n(get_nodes_block(node),i)));
- set_irn_n(node, i, const_graph);
+ ir_node *block = get_nodes_block(get_irn_n(get_nodes_block(node),i));
+ ir_node *nn = gen_arm_Const(pred, block, cg);
+ set_irn_n(node, i, nn);
}
else if (pred_code == iro_SymConst) {
/* FIXME: in general, SymConst always require a load, so it
for (i = 0; i < get_irn_arity(node); i++) {
ir_node *pred = get_irn_n(node,i);
ir_opcode pred_code = get_irn_opcode(pred);
+
if (pred_code == iro_Const) {
- ir_node *const_graph;
- const_graph = create_const_graph(cg->birg->abi, pred, get_nodes_block(node));
- set_irn_n(node, i, const_graph);
+ ir_node *block = get_nodes_block(node);
+ ir_node *nn = gen_arm_Const(pred, block, cg);
+ set_irn_n(node, i, nn);
} else if (pred_code == iro_SymConst) {
ident *id = get_sc_ident(pred);
ir_node *symconst_node;
}
}
+/**
+ * Do not transform Proj, but check for floating point value.
+ */
+static ir_node *gen_Proj(ir_node *irn, arm_code_gen_t *cg) {
+ if (mode_is_float(get_irn_mode(irn)))
+ cg->have_fp = 1;
+ return NULL;
+}
+
/**
* the BAD transformer.
return NULL;
}
+/**
+ * The type of a transform function.
+ */
+typedef ir_node *(transform_func)(ir_node *irn, arm_code_gen_t *cg);
+
+/**
+ * Set a node emitter. Make it a bit more type safe.
+ */
+static INLINE void set_transformer(ir_op *op, transform_func arm_transform_func) {
+ op->ops.generic = (op_func)arm_transform_func;
+}
+
/**
* Enters all transform functions into the generic pointer
*/
/* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func();
-#define FIRM_OP(a) op_##a->ops.generic = (op_func)gen_##a
-#define BAD(a) op_##a->ops.generic = (op_func)bad_transform
+#define FIRM_OP(a) set_transformer(op_##a, gen_##a)
+#define BAD(a) set_transformer(op_##a, bad_transform)
#define IGN(a)
FIRM_OP(Add); // done
FIRM_OP(Abs); // done
FIRM_OP(CopyB); // done
- FIRM_OP(Const); // TODO: floating point consts
+ BAD(Const); /* should be handled by arm_move_const */
FIRM_OP(Conv); // TODO: floating point conversions
FIRM_OP(Load); // done
/* You probably don't need to handle the following nodes */
IGN(Call);
- IGN(Proj);
+ FIRM_OP(Proj);
IGN(Alloc);
IGN(Block);
#undef BAD
}
-typedef ir_node *(transform_func)(ir_node *irn, arm_code_gen_t *cg);
-
/**
* Transforms the given firm node (and maybe some other related nodes)
* into one or more assembler nodes.