From 2370649c560484a881c8a59d3ffc0b39de371cd0 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Sun, 17 Jun 2007 00:59:13 +0000 Subject: [PATCH] BugFixes: - added missing break for gen_Load - fixed gen_Conv - fixed create_const_graph*(): now uses the new_block [r14541] --- ir/be/arm/arm_nodes_attr.h | 4 +- ir/be/arm/arm_transform.c | 148 +++++++++++++++---------------------- 2 files changed, 63 insertions(+), 89 deletions(-) diff --git a/ir/be/arm/arm_nodes_attr.h b/ir/be/arm/arm_nodes_attr.h index 8a0ace3e2..7d7bf37a2 100644 --- a/ir/be/arm/arm_nodes_attr.h +++ b/ir/be/arm/arm_nodes_attr.h @@ -26,8 +26,9 @@ #ifndef FIRM_BE_ARM_ARM_NODES_ATTR_H #define FIRM_BE_ARM_ARM_NODES_ATTR_H -#include "../bearch_t.h" #include "firm_types.h" +#include "irnode_t.h" +#include "../bearch_t.h" /** * Possible ARM register shift types. @@ -82,6 +83,7 @@ typedef enum _arm_condition { /** Generic ARM node attributes. */ typedef struct _arm_attr_t { + except_attr exc; /**< the exception attribute. MUST be the first one. */ arch_irn_flags_t flags; /**< indicating if spillable, rematerializeable ... etc. */ const arch_register_req_t **in_req; /**< register requirements for arguments */ diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index 17f65beb9..8f012cce0 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -131,10 +131,9 @@ static void gen_vals_from_word(unsigned int value, vals *result) /** * Creates a arm_Const node. */ -static ir_node *create_const_node(be_abi_irg_t *abi, ir_node *irn, ir_node *block, long value) { - tarval *tv = new_tarval_from_long(value, mode_Iu); - dbg_info *dbg = get_irn_dbg_info(irn); - ir_mode *mode = get_irn_mode(irn); +static ir_node *create_const_node(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, long value) { + ir_mode *mode = mode_Iu; + tarval *tv = new_tarval_from_long(value, mode); ir_node *res; if (mode_needs_gp_reg(mode)) @@ -148,10 +147,9 @@ static ir_node *create_const_node(be_abi_irg_t *abi, ir_node *irn, ir_node *bloc /** * Creates a arm_Const_Neg node. */ -static ir_node *create_const_neg_node(be_abi_irg_t *abi, ir_node *irn, ir_node *block, long value) { - tarval *tv = new_tarval_from_long(value, mode_Iu); - dbg_info *dbg = get_irn_dbg_info(irn); - ir_mode *mode = get_irn_mode(irn); +static ir_node *create_const_neg_node(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, long value) { + ir_mode *mode = mode_Iu; + tarval *tv = new_tarval_from_long(value, mode); ir_node *res; if (mode_needs_gp_reg(mode)) @@ -184,35 +182,31 @@ unsigned int arm_decode_imm_w_shift(tarval *tv) { /** * Creates a possible DAG for an constant. */ -static ir_node *create_const_graph_value(be_abi_irg_t *abi, ir_node *irn, ir_node *block, unsigned int value) { +static ir_node *create_const_graph_value(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, unsigned int value) { ir_node *result; vals v, vn; int cnt; - ir_mode *mode = get_irn_mode(irn); - dbg_info *dbg = get_irn_dbg_info(irn); + ir_mode *mode = mode_Iu; gen_vals_from_word(value, &v); gen_vals_from_word(~value, &vn); - if (mode_needs_gp_reg(mode)) - mode = mode_Iu; - if (vn.ops < v.ops) { /* remove bits */ - result = create_const_neg_node(abi, irn, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0])); + result = create_const_neg_node(abi, dbg, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0])); for (cnt = 1; cnt < vn.ops; ++cnt) { - tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]), mode_Iu); + tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]), mode); ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode, tv); result = bic_i_node; } } else { /* add bits */ - result = create_const_node(abi, irn, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0])); + result = create_const_node(abi, dbg, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0])); for (cnt = 1; cnt < v.ops; ++cnt) { - tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]), mode_Iu); + tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]), mode); ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode, tv); result = orr_i_node; } @@ -236,25 +230,27 @@ static ir_node *create_const_graph(be_abi_irg_t *abi, ir_node *irn, ir_node *blo tv = tarval_convert_to(tv, mode_Iu); } value = get_tarval_long(tv); - return create_const_graph_value(abi, irn, block, value); + return create_const_graph_value(abi, get_irn_dbg_info(irn), block, value); } -static ir_node *gen_mask(be_abi_irg_t *abi, ir_node *irn, ir_node *op, int result_bits) { - ir_node *block = get_nodes_block(irn); +/** + * Create an And that will mask all upper bits + */ +static ir_node *gen_zero_extension(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) { unsigned mask_bits = (1 << result_bits) - 1; - ir_node *mask_node = create_const_graph_value(abi, irn, block, mask_bits); - dbg_info *dbg = get_irn_dbg_info(irn); - return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, get_irn_mode(irn), ARM_SHF_NONE, NULL); + ir_node *mask_node = create_const_graph_value(abi, dbg, block, mask_bits); + return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, mode_Iu, ARM_SHF_NONE, NULL); } -static ir_node *gen_sign_extension(be_abi_irg_t *abi, ir_node *irn, ir_node *op, int result_bits) { - ir_node *block = get_nodes_block(irn); +/** + * Generate code for a sign extension. + */ +static ir_node *gen_sign_extension(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) { + ir_graph *irg = current_ir_graph; int shift_width = 32 - result_bits; - ir_graph *irg = current_ir_graph; - ir_node *shift_const_node = create_const_graph_value(abi, irn, block, shift_width); - dbg_info *dbg = get_irn_dbg_info(irn); - ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, get_irn_mode(op)); - ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, get_irn_mode(irn)); + ir_node *shift_const_node = create_const_graph_value(abi, dbg, block, shift_width); + ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, mode_Iu); + ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, mode_Iu); return rshift_node; } @@ -272,9 +268,6 @@ static ir_node *gen_Conv(ir_node *node) { ir_mode *dst_mode = get_irn_mode(node); dbg_info *dbg = get_irn_dbg_info(node); - if (mode_needs_gp_reg(dst_mode)) - dst_mode = mode_Iu; - if (src_mode == dst_mode) return new_op; @@ -309,64 +302,38 @@ static ir_node *gen_Conv(ir_node *node) { else { /* complete in gp registers */ int src_bits = get_mode_size_bits(src_mode); int dst_bits = get_mode_size_bits(dst_mode); - int src_sign = get_mode_sign(src_mode); - int dst_sign = get_mode_sign(dst_mode); + int min_bits; + ir_mode *min_mode; - if (src_bits == dst_bits) { - /* kill 32 -> 32 convs */ - if (src_bits == 32) { + if (is_Load(skip_Proj(op))) { + if (src_bits == dst_bits) { + /* kill unneccessary conv */ return new_op; - } else if (dst_bits < 32) { - // 16 -> 16 - // unsigned -> unsigned - // NOP - // unsigned -> signed - // sign extension (31:16)=(15) - // signed -> unsigned - // zero extension (31:16)=0 - // signed -> signed - // NOP - if (src_sign && !dst_sign) { - return gen_mask(env_cg->birg->abi, node, new_op, dst_bits); - } else { - return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits); - } - } else { - panic("Cannot handle mode %+F with %d bits\n", dst_mode, dst_bits); - return NULL; } + /* after a load, the bit size is already converted */ + src_bits = 32; } - else if (src_bits < dst_bits) { - // 16 -> 32 - // unsigned -> unsigned - // NOP - // unsigned -> signed - // NOP - // signed -> unsigned - // sign extension (31:16)=(15) - // signed -> signed - // sign extension (31:16)=(15) - if (src_sign) { - return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits); + + if (src_bits == dst_bits) { + /* kill unneccessary conv */ + return new_op; + } else if (dst_bits <= 32 && src_bits <= 32) { + if (src_bits < dst_bits) { + min_bits = src_bits; + min_mode = src_mode; } else { - return new_op; + min_bits = dst_bits; + min_mode = dst_mode; } - } - else { - // 32 -> 16 - // unsigned -> unsigned - // maskieren (31:16)=0 - // unsigned -> signed - // maskieren (31:16)=0 - // signed -> unsigned - // maskieren (31:16)=0 - // signed -> signed - // sign extension (erledigt auch maskieren) (31:16)=(15) - if (src_sign && dst_sign) { - return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits); + if (mode_is_signed(min_mode)) { + return gen_sign_extension(env_cg->birg->abi, dbg, block, new_op, min_bits); } else { - return gen_mask(env_cg->birg->abi, node, new_op, dst_bits); + return gen_zero_extension(env_cg->birg->abi, dbg, block, new_op, min_bits); } + } else { + panic("Cannot handle Conv %+F->%+F with %d->%d bits\n", src_mode, dst_mode, + src_bits, dst_bits); + return NULL; } } } @@ -810,9 +777,12 @@ static ir_node *gen_Load(ir_node *node) { switch (get_mode_size_bits(mode)) { case 8: new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem); + break; case 16: new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem); + break; case 32: + new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem); break; default: panic("mode size not supported\n"); @@ -822,15 +792,17 @@ static ir_node *gen_Load(ir_node *node) { switch (get_mode_size_bits(mode)) { case 8: new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem); + break; case 16: new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem); + break; case 32: + new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem); break; default: panic("mode size not supported\n"); } } - new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem); } set_irn_pinned(new_load, get_irn_pinned(node)); return new_load; @@ -935,7 +907,7 @@ static ir_node *gen_Cond(ir_node *node) { } - const_graph = create_const_graph_value(env_cg->birg->abi, node, block, translation); + const_graph = create_const_graph_value(env_cg->birg->abi, dbg, block, translation); sub = new_rd_arm_Sub(dbg, irg, block, new_op, const_graph, mode, ARM_SHF_NONE, NULL); return new_rd_arm_SwitchJmp(dbg, irg, block, sub, n_projs, get_Cond_defaultProj(node) - translation); } @@ -1120,8 +1092,8 @@ static ir_node *gen_be_FrameAddr(ir_node *node) { int offset = get_entity_offset(ent); ir_node *op = be_get_FrameAddr_frame(node); ir_node *new_op = be_transform_node(op); - ir_mode *mode = get_irn_mode(node); dbg_info *dbg = get_irn_dbg_info(node); + ir_mode *mode = mode_Iu; ir_node *cnst; if (be_is_IncSP(op)) { @@ -1129,7 +1101,7 @@ static ir_node *gen_be_FrameAddr(ir_node *node) { is relative. Both must be merged */ offset += get_sp_expand_offset(op); } - cnst = create_const_graph_value(env_cg->birg->abi, node, block, (unsigned)offset); + cnst = create_const_graph_value(env_cg->birg->abi, dbg, block, (unsigned)offset); if (is_arm_Mov_i(cnst)) return new_rd_arm_Add_i(dbg, current_ir_graph, block, new_op, mode, get_arm_value(cnst)); return new_rd_arm_Add(dbg, current_ir_graph, block, new_op, cnst, mode, ARM_SHF_NONE, NULL); -- 2.20.1