From 8c3b27cd7be200bcc9bf61757f7e745ff19f4bd0 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Thu, 14 Jun 2007 04:38:01 +0000 Subject: [PATCH] fpa constants implemented [r14485] --- ir/be/arm/arm_transform.c | 61 +++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index 8af57d182..b6bc0645a 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -209,19 +209,22 @@ static ir_node *create_const_graph(be_abi_irg_t *abi, ir_node *irn, ir_node *blo 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"); @@ -885,8 +888,8 @@ static ir_node *gen_Cond(ir_node *irn, arm_code_gen_t *cg) { } - 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); @@ -1164,9 +1167,9 @@ void arm_move_consts(ir_node *node, void *env) { 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 @@ -1185,10 +1188,11 @@ void arm_move_consts(ir_node *node, void *env) { 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; @@ -1200,6 +1204,15 @@ void arm_move_consts(ir_node *node, void *env) { } } +/** + * 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. @@ -1210,6 +1223,18 @@ static ir_node *bad_transform(ir_node *irn, arm_code_gen_t *cg) { 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 */ @@ -1219,8 +1244,8 @@ void arm_register_transformers(void) { /* 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 @@ -1240,7 +1265,7 @@ void arm_register_transformers(void) { 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 @@ -1262,7 +1287,7 @@ void arm_register_transformers(void) { /* You probably don't need to handle the following nodes */ IGN(Call); - IGN(Proj); + FIRM_OP(Proj); IGN(Alloc); IGN(Block); @@ -1306,8 +1331,6 @@ void arm_register_transformers(void) { #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. -- 2.20.1