Commit 2370649c authored by Michael Beck's avatar Michael Beck
Browse files

BugFixes:

- added missing break for gen_Load
- fixed gen_Conv
- fixed create_const_graph*(): now uses the new_block

[r14541]
parent cdbf0d29
...@@ -26,8 +26,9 @@ ...@@ -26,8 +26,9 @@
#ifndef FIRM_BE_ARM_ARM_NODES_ATTR_H #ifndef FIRM_BE_ARM_ARM_NODES_ATTR_H
#define FIRM_BE_ARM_ARM_NODES_ATTR_H #define FIRM_BE_ARM_ARM_NODES_ATTR_H
#include "../bearch_t.h"
#include "firm_types.h" #include "firm_types.h"
#include "irnode_t.h"
#include "../bearch_t.h"
/** /**
* Possible ARM register shift types. * Possible ARM register shift types.
...@@ -82,6 +83,7 @@ typedef enum _arm_condition { ...@@ -82,6 +83,7 @@ typedef enum _arm_condition {
/** Generic ARM node attributes. */ /** Generic ARM node attributes. */
typedef struct _arm_attr_t { 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. */ arch_irn_flags_t flags; /**< indicating if spillable, rematerializeable ... etc. */
const arch_register_req_t **in_req; /**< register requirements for arguments */ const arch_register_req_t **in_req; /**< register requirements for arguments */
......
...@@ -131,10 +131,9 @@ static void gen_vals_from_word(unsigned int value, vals *result) ...@@ -131,10 +131,9 @@ static void gen_vals_from_word(unsigned int value, vals *result)
/** /**
* Creates a arm_Const node. * Creates a arm_Const node.
*/ */
static ir_node *create_const_node(be_abi_irg_t *abi, ir_node *irn, ir_node *block, long value) { static ir_node *create_const_node(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, long value) {
tarval *tv = new_tarval_from_long(value, mode_Iu); ir_mode *mode = mode_Iu;
dbg_info *dbg = get_irn_dbg_info(irn); tarval *tv = new_tarval_from_long(value, mode);
ir_mode *mode = get_irn_mode(irn);
ir_node *res; ir_node *res;
if (mode_needs_gp_reg(mode)) 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 ...@@ -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. * 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) { static ir_node *create_const_neg_node(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, long value) {
tarval *tv = new_tarval_from_long(value, mode_Iu); ir_mode *mode = mode_Iu;
dbg_info *dbg = get_irn_dbg_info(irn); tarval *tv = new_tarval_from_long(value, mode);
ir_mode *mode = get_irn_mode(irn);
ir_node *res; ir_node *res;
if (mode_needs_gp_reg(mode)) if (mode_needs_gp_reg(mode))
...@@ -184,35 +182,31 @@ unsigned int arm_decode_imm_w_shift(tarval *tv) { ...@@ -184,35 +182,31 @@ unsigned int arm_decode_imm_w_shift(tarval *tv) {
/** /**
* Creates a possible DAG for an constant. * 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; ir_node *result;
vals v, vn; vals v, vn;
int cnt; int cnt;
ir_mode *mode = get_irn_mode(irn); ir_mode *mode = mode_Iu;
dbg_info *dbg = get_irn_dbg_info(irn);
gen_vals_from_word(value, &v); gen_vals_from_word(value, &v);
gen_vals_from_word(~value, &vn); gen_vals_from_word(~value, &vn);
if (mode_needs_gp_reg(mode))
mode = mode_Iu;
if (vn.ops < v.ops) { if (vn.ops < v.ops) {
/* remove bits */ /* 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) { 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); ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode, tv);
result = bic_i_node; result = bic_i_node;
} }
} }
else { else {
/* add bits */ /* 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) { 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); ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode, tv);
result = orr_i_node; 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 ...@@ -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); tv = tarval_convert_to(tv, mode_Iu);
} }
value = get_tarval_long(tv); 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; unsigned mask_bits = (1 << result_bits) - 1;
ir_node *mask_node = create_const_graph_value(abi, irn, block, mask_bits); ir_node *mask_node = create_const_graph_value(abi, dbg, block, mask_bits);
dbg_info *dbg = get_irn_dbg_info(irn); return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, mode_Iu, ARM_SHF_NONE, NULL);
return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, get_irn_mode(irn), 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; int shift_width = 32 - result_bits;
ir_graph *irg = current_ir_graph; ir_node *shift_const_node = create_const_graph_value(abi, dbg, block, shift_width);
ir_node *shift_const_node = create_const_graph_value(abi, irn, block, shift_width); ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, mode_Iu);
dbg_info *dbg = get_irn_dbg_info(irn); ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, mode_Iu);
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));
return rshift_node; return rshift_node;
} }
...@@ -272,9 +268,6 @@ static ir_node *gen_Conv(ir_node *node) { ...@@ -272,9 +268,6 @@ static ir_node *gen_Conv(ir_node *node) {
ir_mode *dst_mode = get_irn_mode(node); ir_mode *dst_mode = get_irn_mode(node);
dbg_info *dbg = get_irn_dbg_info(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) if (src_mode == dst_mode)
return new_op; return new_op;
...@@ -309,64 +302,38 @@ static ir_node *gen_Conv(ir_node *node) { ...@@ -309,64 +302,38 @@ static ir_node *gen_Conv(ir_node *node) {
else { /* complete in gp registers */ else { /* complete in gp registers */
int src_bits = get_mode_size_bits(src_mode); int src_bits = get_mode_size_bits(src_mode);
int dst_bits = get_mode_size_bits(dst_mode); int dst_bits = get_mode_size_bits(dst_mode);
int src_sign = get_mode_sign(src_mode); int min_bits;
int dst_sign = get_mode_sign(dst_mode); ir_mode *min_mode;
if (src_bits == dst_bits) { if (is_Load(skip_Proj(op))) {
/* kill 32 -> 32 convs */ if (src_bits == dst_bits) {
if (src_bits == 32) { /* kill unneccessary conv */
return new_op; 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 if (src_bits == dst_bits) {
// unsigned -> unsigned /* kill unneccessary conv */
// NOP return new_op;
// unsigned -> signed } else if (dst_bits <= 32 && src_bits <= 32) {
// NOP if (src_bits < dst_bits) {
// signed -> unsigned min_bits = src_bits;
// sign extension (31:16)=(15) min_mode = src_mode;
// signed -> signed
// sign extension (31:16)=(15)
if (src_sign) {
return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits);
} else { } else {
return new_op; min_bits = dst_bits;
min_mode = dst_mode;
} }
} if (mode_is_signed(min_mode)) {
else { return gen_sign_extension(env_cg->birg->abi, dbg, block, new_op, min_bits);
// 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);
} else { } 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) { ...@@ -810,9 +777,12 @@ static ir_node *gen_Load(ir_node *node) {
switch (get_mode_size_bits(mode)) { switch (get_mode_size_bits(mode)) {
case 8: case 8:
new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem); new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
break;
case 16: case 16:
new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem); new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
break;
case 32: case 32:
new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
break; break;
default: default:
panic("mode size not supported\n"); panic("mode size not supported\n");
...@@ -822,15 +792,17 @@ static ir_node *gen_Load(ir_node *node) { ...@@ -822,15 +792,17 @@ static ir_node *gen_Load(ir_node *node) {
switch (get_mode_size_bits(mode)) { switch (get_mode_size_bits(mode)) {
case 8: case 8:
new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem); new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
break;
case 16: case 16:
new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem); new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
break;
case 32: case 32:
new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
break; break;
default: default:
panic("mode size not supported\n"); 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)); set_irn_pinned(new_load, get_irn_pinned(node));
return new_load; return new_load;
...@@ -935,7 +907,7 @@ static ir_node *gen_Cond(ir_node *node) { ...@@ -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); 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); 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) { ...@@ -1120,8 +1092,8 @@ static ir_node *gen_be_FrameAddr(ir_node *node) {
int offset = get_entity_offset(ent); int offset = get_entity_offset(ent);
ir_node *op = be_get_FrameAddr_frame(node); ir_node *op = be_get_FrameAddr_frame(node);
ir_node *new_op = be_transform_node(op); ir_node *new_op = be_transform_node(op);
ir_mode *mode = get_irn_mode(node);
dbg_info *dbg = get_irn_dbg_info(node); dbg_info *dbg = get_irn_dbg_info(node);
ir_mode *mode = mode_Iu;
ir_node *cnst; ir_node *cnst;
if (be_is_IncSP(op)) { if (be_is_IncSP(op)) {
...@@ -1129,7 +1101,7 @@ static ir_node *gen_be_FrameAddr(ir_node *node) { ...@@ -1129,7 +1101,7 @@ static ir_node *gen_be_FrameAddr(ir_node *node) {
is relative. Both must be merged */ is relative. Both must be merged */
offset += get_sp_expand_offset(op); 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)) 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_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); return new_rd_arm_Add(dbg, current_ir_graph, block, new_op, cnst, mode, ARM_SHF_NONE, NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment