X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Farm%2Farm_transform.c;h=91e75e3649c8c7b8149f87aec918f7c4d865abd2;hb=863d31d7a5c8210432fef88b30fc3e8353131538;hp=e665bb4fde25482abc177de2ecce182e6a45018a;hpb=c6c92c65654bcfc3b99c3c41a365b23cc502bf7c;p=libfirm diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index e665bb4fd..91e75e364 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -1,4 +1,4 @@ -/* The codegenrator (transform FIRM into arm FIRM */ +/* The codegenerator (transform FIRM into arm FIRM */ /* $Id$ */ #ifdef HAVE_CONFIG_H @@ -139,7 +139,6 @@ unsigned int arm_decode_imm_w_shift(tarval *tv) { */ static ir_node *create_const_graph_value(ir_node *irn, ir_node *block, unsigned int value) { ir_node *result; - int negate = 0; vals v, vn; int cnt; ir_mode *mode = get_irn_mode(irn); @@ -182,24 +181,25 @@ static ir_node *create_const_graph(ir_node *irn, ir_node *block) { } - +/** + * Creates code for a Firm Const node. + */ static ir_node *gen_Const(ir_node *irn, arm_code_gen_t *cg) { - ir_node *result; 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); - assert(mode != mode_E && "IEEE Extended FP not supported"); - if (mode == mode_F) - result = new_rd_arm_fConst(dbg, irg, block, mode, get_Const_tarval(irn)); - else if (mode == mode_D) - result = new_rd_arm_fConst(dbg, irg, block, mode, get_Const_tarval(irn)); - else if (mode == mode_P) + if (mode_is_float(mode)) { + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaConst(dbg, irg, block, mode, get_Const_tarval(irn)); + else if (USE_VFP(cg->isa)) + assert(mode != mode_E && "IEEE Extended FP not supported"); + assert(0 && "NYI"); + } + else if (mode_is_reference(mode)) return irn; - else - result = create_const_graph(irn, block); - return result; + return create_const_graph(irn, block); } static ir_node *gen_mask(ir_node *irn, ir_node *op, int result_bits) { @@ -235,21 +235,34 @@ static ir_node *gen_Conv(ir_node *irn, arm_code_gen_t *cg) { ir_mode *out_mode = get_irn_mode(irn); dbg_info *dbg = get_irn_dbg_info(irn); - assert( in_mode != mode_E && ""); - assert( in_mode != mode_Ls && ""); - assert( in_mode != mode_Lu && ""); - assert( out_mode != mode_E && ""); - assert( out_mode != mode_Ls && ""); - assert( out_mode != mode_Lu && ""); - if (in_mode == out_mode) return op; - if ((mode_is_int(in_mode) || mode_is_reference(in_mode)) - && (mode_is_reference(out_mode) || mode_is_int(out_mode))) { - int in_bits = get_mode_size_bits(in_mode); + if (mode_is_float(in_mode) || mode_is_float(out_mode)) { + cg->have_fp = 1; + + if (USE_FPA(cg->isa)) { + if (mode_is_float(in_mode)) { + if (mode_is_float(out_mode)) { + /* from float to float */ + return new_rd_arm_fpaMov(dbg, irg, block, op, out_mode); + } + else { + /* from float to int */ + return new_rd_arm_fpaFix(dbg, irg, block, op, out_mode); + } + } + else { + /* from int to float */ + return new_rd_arm_fpaFlt(dbg, irg, block, op, out_mode); + } + } + assert(0 && "NYI"); + } + else { /* complete in gp registers */ + int in_bits = get_mode_size_bits(in_mode); int out_bits = get_mode_size_bits(out_mode); - int in_sign = get_mode_sign(in_mode); + int in_sign = get_mode_sign(in_mode); int out_sign = get_mode_sign(out_mode); // 32 -> 32 @@ -309,20 +322,8 @@ static ir_node *gen_Conv(ir_node *irn, arm_code_gen_t *cg) { } assert(0 && "recheck integer conversion logic!"); return irn; - } else if (in_mode == mode_D && out_mode == mode_F) { - return new_rd_arm_fConvD2S(dbg, irg, block, op, out_mode); - } else if (in_mode == mode_F && out_mode == mode_D) { - return new_rd_arm_fConvS2D(dbg, irg, block, op, out_mode); - } else if (mode_is_int(in_mode) && mode_is_float(out_mode)) { - cg->have_fp = 1; - return irn; /* TODO: implement int->float conversion*/ - } else if (mode_is_float(in_mode) && mode_is_int(out_mode)) { - cg->have_fp = 1; - return irn; /* TODO: implement float->int conversion*/ - } else { - assert(0 && "not implemented conversion"); - return irn; } + return NULL; } /** @@ -360,11 +361,14 @@ static ir_node *gen_Add(ir_node *irn, arm_code_gen_t *cg) { arm_shift_modifier mod; dbg_info *dbg = get_irn_dbg_info(irn); - assert(mode != mode_E && "IEEE Extended FP not supported"); - if (mode_is_float(mode)) { cg->have_fp = 1; - return new_rd_arm_fAdd(dbg, irg, block, op1, op2, mode); + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaAdd(dbg, irg, block, op1, op2, mode); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } if (mode_is_numP(mode)) { if (is_arm_Mov_i(op1)) @@ -423,11 +427,14 @@ static ir_node *gen_Mul(ir_node *irn, arm_code_gen_t *cg) { ir_graph *irg = current_ir_graph; dbg_info *dbg = get_irn_dbg_info(irn); - assert(mode != mode_E && "IEEE Extended FP not supported"); - if (mode_is_float(mode)) { cg->have_fp = 1; - return new_rd_arm_fMul(dbg, irg, block, op1, op2, mode); + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaMul(dbg, irg, block, op1, op2, mode); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } return new_rd_arm_Mul(dbg, irg, block, op1, op2, mode); } @@ -447,7 +454,15 @@ static ir_node *gen_Quot(ir_node *irn, arm_code_gen_t *cg) { assert(mode != mode_E && "IEEE Extended FP not supported"); - return new_rd_arm_fDiv(dbg, current_ir_graph, block, op1, op2, mode); + cg->have_fp = 1; + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaDiv(dbg, current_ir_graph, block, op1, op2, mode); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); + + return NULL; } #define GEN_INT_OP(op) \ @@ -525,11 +540,14 @@ static ir_node *gen_Sub(ir_node *irn, arm_code_gen_t *cg) { ir_graph *irg = current_ir_graph; dbg_info *dbg = get_irn_dbg_info(irn); - assert(mode != mode_E && "IEEE Extended FP not supported"); - if (mode_is_float(mode)) { cg->have_fp = 1; - return new_rd_arm_fSub(dbg, irg, block, op1, op2, mode); + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaSub(dbg, irg, block, op1, op2, mode); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } if (mode_is_numP(mode)) { if (is_arm_Mov_i(op1)) @@ -658,11 +676,14 @@ static ir_node *gen_Abs(ir_node *irn, arm_code_gen_t *cg) { ir_mode *mode = get_irn_mode(irn); dbg_info *dbg = get_irn_dbg_info(irn); - assert(mode != mode_E && "IEEE Extended FP not supported"); - if (mode_is_float(mode)) { cg->have_fp = 1; - return new_rd_arm_fAbs(dbg, current_ir_graph, block, op, mode); + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaAbs(dbg, current_ir_graph, block, op, mode); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } return new_rd_arm_Abs(dbg, current_ir_graph, block, op, mode); } @@ -681,7 +702,13 @@ static ir_node *gen_Minus(ir_node *irn, arm_code_gen_t *cg) { dbg_info *dbg = get_irn_dbg_info(irn); if (mode_is_float(mode)) { - return new_rd_arm_fNeg(dbg, irg, block, op, mode); + cg->have_fp = 1; + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaMnv(dbg, irg, block, op, mode); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } return new_rd_arm_Rsb_i(dbg, irg, block, op, mode, get_mode_null(mode)); } @@ -703,8 +730,13 @@ static ir_node *gen_Load(ir_node *irn, arm_code_gen_t *cg) { if (mode_is_float(mode)) { cg->have_fp = 1; - /* FIXME: set the load mode */ - return new_rd_arm_fLoad(dbg, irg, block, get_Load_ptr(irn), get_Load_mem(irn)); + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaLdf(dbg, irg, block, get_Load_ptr(irn), get_Load_mem(irn), + get_Load_mode(irn)); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } if (mode == mode_Bu) { return new_rd_arm_Loadb(dbg, irg, block, get_Load_ptr(irn), get_Load_mem(irn)); @@ -742,8 +774,13 @@ static ir_node *gen_Store(ir_node *irn, arm_code_gen_t *cg) { assert(mode != mode_E && "IEEE Extended FP not supported"); if (mode_is_float(mode)) { cg->have_fp = 1; - /* FIXME: set the store mode */ - return new_rd_arm_fStore(dbg, irg, block, get_Store_ptr(irn), get_Store_value(irn), get_Store_mem(irn)); + if (USE_FPA(cg->isa)) + return new_rd_arm_fpaStf(dbg, irg, block, get_Store_ptr(irn), get_Store_value(irn), + get_Store_mem(irn), get_irn_mode(get_Store_value(irn))); + else if (USE_VFP(cg->isa)) { + assert(mode != mode_E && "IEEE Extended FP not supported"); + } + assert(0 && "NYI"); } if (mode == mode_Bu) { return new_rd_arm_Storeb(dbg, irg, block, get_Store_ptr(irn), get_Store_value(irn), get_Store_mem(irn)); @@ -913,23 +950,23 @@ static ir_node *gen_CopyB(ir_node *irn, arm_code_gen_t *cg) { * access must be done relative the the fist IncSP ... */ static int get_sp_expand_offset(ir_node *inc_sp) { - unsigned offset = be_get_IncSP_offset(inc_sp); - be_stack_dir_t dir = be_get_IncSP_direction(inc_sp); + int offset = be_get_IncSP_offset(inc_sp); - if (offset == BE_STACK_FRAME_SIZE) + if (offset == BE_STACK_FRAME_SIZE_EXPAND) return 0; - return dir == be_stack_dir_expand ? (int)offset : -(int)offset; + + return offset; } -static ir_node *gen_StackParam(ir_node *irn, arm_code_gen_t *cg) { #if 0 - ir_node *new_op = NULL; - ir_node *block = get_nodes_block(irn); - ir_node *noreg = ia32_new_NoReg_gp(env->cg); - ir_node *mem = new_rd_NoMem(env->irg); - ir_node *ptr = get_irn_n(irn, 0); - entity *ent = be_get_frame_entity(irn); - ir_mode *mode = env->mode; +static ir_node *gen_StackParam(ir_node *irn, arm_code_gen_t *cg) { + ir_node *new_op = NULL; + ir_node *block = get_nodes_block(irn); + ir_node *noreg = ia32_new_NoReg_gp(env->cg); + ir_node *mem = new_rd_NoMem(env->irg); + ir_node *ptr = get_irn_n(irn, 0); + ir_entity *ent = be_get_frame_entity(irn); + ir_mode *mode = env->mode; // /* If the StackParam has only one user -> */ // /* put it in the Block where the user resides */ @@ -960,16 +997,16 @@ static ir_node *gen_StackParam(ir_node *irn, arm_code_gen_t *cg) { SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); return new_rd_Proj(env->dbg, env->irg, block, new_op, mode, 0); -#endif } +#endif /** * Transforms a FrameAddr into an ia32 Add. */ static ir_node *gen_be_FrameAddr(ir_node *irn, arm_code_gen_t *cg) { ir_node *block = get_nodes_block(irn); - entity *ent = be_get_frame_entity(irn); - int offset = get_entity_offset_bytes(ent); + ir_entity *ent = be_get_frame_entity(irn); + int offset = get_entity_offset(ent); ir_node *op = get_irn_n(irn, 0); ir_node *cnst; ir_mode *mode = get_irn_mode(irn); @@ -986,17 +1023,17 @@ static ir_node *gen_be_FrameAddr(ir_node *irn, arm_code_gen_t *cg) { return new_rd_arm_Add(dbg, current_ir_graph, block, op, cnst, mode, ARM_SHF_NONE, NULL); } +#if 0 /** * Transforms a FrameLoad into an ia32 Load. */ static ir_node *gen_FrameLoad(ir_node *irn, arm_code_gen_t *cg) { -#if 0 - ir_node *new_op = NULL; - ir_node *noreg = ia32_new_NoReg_gp(env->cg); - ir_node *mem = get_irn_n(irn, 0); - ir_node *ptr = get_irn_n(irn, 1); - entity *ent = be_get_frame_entity(irn); - ir_mode *mode = get_type_mode(get_entity_type(ent)); + ir_node *new_op = NULL; + ir_node *noreg = ia32_new_NoReg_gp(env->cg); + ir_node *mem = get_irn_n(irn, 0); + ir_node *ptr = get_irn_n(irn, 1); + ir_entity *ent = be_get_frame_entity(irn); + ir_mode *mode = get_type_mode(get_entity_type(ent)); if (mode_is_float(mode)) { if (USE_SSE2(env->cg)) @@ -1021,22 +1058,21 @@ static ir_node *gen_FrameLoad(ir_node *irn, arm_code_gen_t *cg) { SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); return new_op; -#endif } +#endif - +#if 0 /** * Transforms a FrameStore into an ia32 Store. */ static ir_node *gen_FrameStore(ir_node *irn, arm_code_gen_t *cg) { -#if 0 - ir_node *new_op = NULL; - ir_node *noreg = ia32_new_NoReg_gp(env->cg); - ir_node *mem = get_irn_n(irn, 0); - ir_node *ptr = get_irn_n(irn, 1); - ir_node *val = get_irn_n(irn, 2); - entity *ent = be_get_frame_entity(irn); - ir_mode *mode = get_irn_mode(val); + ir_node *new_op = NULL; + ir_node *noreg = ia32_new_NoReg_gp(env->cg); + ir_node *mem = get_irn_n(irn, 0); + ir_node *ptr = get_irn_n(irn, 1); + ir_node *val = get_irn_n(irn, 2); + ir_entity *ent = be_get_frame_entity(irn); + ir_mode *mode = get_irn_mode(val); if (mode_is_float(mode)) { if (USE_SSE2(env->cg)) @@ -1064,8 +1100,8 @@ static ir_node *gen_FrameStore(ir_node *irn, arm_code_gen_t *cg) { SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); return new_op; -#endif } +#endif // static ir_node *gen_be_Copy(ir_node *irn, arm_code_gen_t *cg) { @@ -1082,25 +1118,28 @@ static ir_node *gen_FrameStore(ir_node *irn, arm_code_gen_t *cg) { * *********************************************************/ -/************************************************************************/ -/* move constants out of startblock */ -/************************************************************************/ +/** + * move constants out of the start block + */ void arm_move_consts(ir_node *node, void *env) { - arm_code_gen_t *cgenv = (arm_code_gen_t *)env; int i; if (is_Block(node)) return; if (is_Phi(node)) { - for (i = 0; i < get_irn_arity(node); i++) { + for (i = get_irn_arity(node) - 1; i >= 0; --i) { ir_node *pred = get_irn_n(node,i); - opcode pred_code = get_irn_opcode(pred); + ir_opcode pred_code = get_irn_opcode(pred); if (pred_code == iro_Const) { ir_node *const_graph; const_graph = create_const_graph(pred, get_nodes_block(get_irn_n(get_nodes_block(node),i))); set_irn_n(node, i, const_graph); - } else if (pred_code == iro_SymConst) { + } + else if (pred_code == iro_SymConst) { + /* FIXME: in general, SymConst always require a load, so it + might be better to place them into the first real block + and let the spiller rematerialize them. */ const char *str = get_sc_name(pred); ir_node *symconst_node; symconst_node = new_rd_arm_SymConst(get_irn_dbg_info(pred), @@ -1113,7 +1152,7 @@ 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); - opcode pred_code = get_irn_opcode(pred); + ir_opcode pred_code = get_irn_opcode(pred); if (pred_code == iro_Const) { ir_node *const_graph; const_graph = create_const_graph(pred, get_nodes_block(node)); @@ -1140,8 +1179,8 @@ void arm_move_symconsts(ir_node *node, void *env) { return; for (i = 0; i < get_irn_arity(node); i++) { - ir_node *pred = get_irn_n(node,i); - opcode pred_code = get_irn_opcode(pred); + ir_node *pred = get_irn_n(node,i); + ir_opcode pred_code = get_irn_opcode(pred); if (pred_code == iro_SymConst) { const char *str = get_sc_name(pred);