#include "irdom.h"
#include "archop.h"
#include "error.h"
+#include "array_t.h"
#include "height.h"
#include "../benode_t.h"
return ent_cache[kct];
}
-static int prevents_AM(ir_node *const block, ir_node *const am_candidate,
- ir_node *const other)
-{
- if (get_nodes_block(other) != block)
- return 0;
-
- if (is_Sync(other)) {
- int i;
-
- for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
- ir_node *const pred = get_Sync_pred(other, i);
-
- if (get_nodes_block(pred) != block)
- continue;
-
- /* Do not block ourselves from getting eaten */
- if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
- continue;
-
- if (!heights_reachable_in_block(heights, pred, am_candidate))
- continue;
-
- return 1;
- }
-
- return 0;
- } else {
- /* Do not block ourselves from getting eaten */
- if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
- return 0;
-
- if (!heights_reachable_in_block(heights, other, am_candidate))
- return 0;
-
- return 1;
- }
-}
-
/**
* return true if the node is a Proj(Load) and could be used in source address
* mode for another node. Will return only true if the @p other node is not
}
am->op_type = ia32_AddrModeS;
} else {
+ am->op_type = ia32_Normal;
+
if (flags & match_try_am) {
am->new_op1 = NULL;
am->new_op2 = NULL;
- am->op_type = ia32_Normal;
return;
}
new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
if (new_op2 == NULL)
new_op2 = be_transform_node(op2);
- am->op_type = ia32_Normal;
- am->ls_mode = get_irn_mode(op2);
- if (flags & match_mode_neutral)
- am->ls_mode = mode_Iu;
+ am->ls_mode =
+ (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
}
if (addr->base == NULL)
addr->base = noreg_gp;
am->commutative = commutative;
}
+static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
+{
+ mark_irn_visited(old_node);
+ be_set_transformed_node(old_node, new_node);
+}
+
static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
{
ir_mode *mode;
mode = get_irn_mode(node);
load = get_Proj_pred(am->mem_proj);
- mark_irn_visited(load);
- be_set_transformed_node(load, node);
+ set_transformed_and_mark(load, node);
if (mode != mode_T) {
set_irn_mode(node, mode_T);
return 1;
}
-static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
-{
- mark_irn_visited(old_node);
- be_set_transformed_node(old_node, new_node);
-}
-
static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
ir_node *mem, ir_node *ptr, ir_mode *mode,
construct_binop_dest_func *func,
if (get_mode_size_bits(mode) >= 32)
return true;
+ if (is_Proj(transformed_node))
+ return upper_bits_clean(get_Proj_pred(transformed_node), mode);
+
if (is_ia32_Conv_I2I(transformed_node)
|| is_ia32_Conv_I2I8Bit(transformed_node)) {
ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
return true;
}
}
+ return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
}
if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
return true;
}
}
+ /* TODO recurse? */
}
+ /* TODO recurse on Or, Xor, ... if appropriate? */
+
if (is_ia32_Immediate(transformed_node)
|| is_ia32_Const(transformed_node)) {
const ia32_immediate_attr_t *attr
/* Test(and_left, and_right) */
ir_node *and_left = get_And_left(left);
ir_node *and_right = get_And_right(left);
- ir_mode *mode = get_irn_mode(and_left);
/* matze: code here used mode instead of cmd_mode, I think it is always
* the same as cmp_mode, but I leave this here to see if this is really
* true...
*/
- assert(mode == cmp_mode);
+ assert(get_irn_mode(and_left) == cmp_mode);
match_arguments(&am, block, and_left, and_right, NULL,
match_commutative |
match_8bit | match_16bit);
/* use 32bit compare mode if possible since the opcode is smaller */
- if (upper_bits_clean(am.new_op1, cmp_mode)
- && upper_bits_clean(am.new_op2, cmp_mode)) {
+ if (upper_bits_clean(am.new_op1, cmp_mode) &&
+ upper_bits_clean(am.new_op2, cmp_mode)) {
cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
}
match_16bit_am | match_am_and_immediates |
match_immediate | match_8bit | match_16bit);
/* use 32bit compare mode if possible since the opcode is smaller */
- if (upper_bits_clean(am.new_op1, cmp_mode)
- && upper_bits_clean(am.new_op2, cmp_mode)) {
+ if (upper_bits_clean(am.new_op1, cmp_mode) &&
+ upper_bits_clean(am.new_op2, cmp_mode)) {
cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
}
arity, in);
copy_node_attr(barrier, new_barrier);
be_duplicate_deps(barrier, new_barrier);
- be_set_transformed_node(barrier, new_barrier);
- mark_irn_visited(barrier);
+ set_transformed_and_mark(barrier, new_barrier);
/* transform normally */
return be_duplicate_node(node);