#include "irdump.h"
#include "error.h"
-#include "../be_t.h"
-#include "../beabi.h"
-#include "../benode.h"
-#include "../besched.h"
-#include "../bepeephole.h"
+#include "be_t.h"
+#include "beabi.h"
+#include "benode.h"
+#include "besched.h"
+#include "bepeephole.h"
#include "ia32_new_nodes.h"
#include "ia32_optimize.h"
#include "ia32_common_transform.h"
#include "ia32_transform.h"
#include "ia32_dbg_stat.h"
-#include "ia32_util.h"
#include "ia32_architecture.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
ir_node *op;
ia32_attr_t const *attr;
int ins_permuted;
- int cmp_unsigned;
ir_node *test;
arch_register_t const *reg;
ir_edge_t const *edge;
op = get_irn_n(node, n_ia32_Cmp_left);
attr = get_ia32_attr(node);
ins_permuted = attr->data.ins_permuted;
- cmp_unsigned = attr->data.cmp_unsigned;
if (is_ia32_Cmp(node)) {
test = new_bd_ia32_Test(dbgi, block, noreg, noreg, nomem,
- op, op, ins_permuted, cmp_unsigned);
+ op, op, ins_permuted);
} else {
test = new_bd_ia32_Test8Bit(dbgi, block, noreg, noreg, nomem,
- op, op, ins_permuted, cmp_unsigned);
+ op, op, ins_permuted);
}
set_ia32_ls_mode(test, get_ia32_ls_mode(node));
- reg = arch_irn_get_register(node, pn_ia32_Cmp_eflags);
- arch_irn_set_register(test, pn_ia32_Test_eflags, reg);
+ reg = arch_get_irn_register_out(node, pn_ia32_Cmp_eflags);
+ arch_set_irn_register_out(test, pn_ia32_Test_eflags, reg);
foreach_out_edge_safe(node, edge, tmp) {
ir_node *const user = get_edge_src_irn(edge);
if (left == right) { /* we need a test for 0 */
ir_node *block = get_nodes_block(node);
int pn = pn_ia32_res;
+ ir_node *op = left;
ir_node *flags_proj;
ir_mode *flags_mode;
+ ir_mode *op_mode;
ir_node *schedpoint;
const ir_edge_t *edge;
if (get_nodes_block(left) != block)
return;
- if (is_Proj(left)) {
- pn = get_Proj_proj(left);
- left = get_Proj_pred(left);
+ if (is_Proj(op)) {
+ pn = get_Proj_proj(op);
+ op = get_Proj_pred(op);
}
/* walk schedule up and abort when we find left or some other node
schedpoint = node;
for (;;) {
schedpoint = sched_prev(schedpoint);
- if (schedpoint == left)
+ if (schedpoint == op)
break;
if (arch_irn_is(schedpoint, modify_flags))
return;
/* make sure only Lg/Eq tests are used */
foreach_out_edge(node, edge) {
- ir_node *user = get_edge_src_irn(edge);
- int pnc = get_ia32_condcode(user);
+ ir_node *user = get_edge_src_irn(edge);
+ ia32_condition_code_t cc = get_ia32_condcode(user);
- if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg) {
+ if (cc != ia32_cc_equal && cc != ia32_cc_not_equal) {
return;
}
}
- switch (produces_test_flag(left, pn)) {
+ switch (produces_test_flag(op, pn)) {
case produces_flag_zero:
break;
case produces_flag_carry:
foreach_out_edge(node, edge) {
- ir_node *user = get_edge_src_irn(edge);
- int pnc = get_ia32_condcode(user);
+ ir_node *user = get_edge_src_irn(edge);
+ ia32_condition_code_t cc = get_ia32_condcode(user);
- switch (pnc) {
- case pn_Cmp_Eq: pnc = ia32_pn_Cmp_not_carry; break;
- case pn_Cmp_Lg: pnc = ia32_pn_Cmp_carry; break;
- default: panic("unexpected pn");
+ switch (cc) {
+ case ia32_cc_equal: cc = ia32_cc_above_equal; break; /* CF = 0 */
+ case ia32_cc_not_equal: cc = ia32_cc_below; break; /* CF = 1 */
+ default: panic("unexpected pn");
}
- set_ia32_condcode(user, pnc);
+ set_ia32_condcode(user, cc);
}
break;
return;
}
- if (get_irn_mode(left) != mode_T) {
- set_irn_mode(left, mode_T);
+ op_mode = get_ia32_ls_mode(op);
+ if (op_mode == NULL)
+ op_mode = get_irn_mode(op);
+
+ /* Make sure we operate on the same bit size */
+ if (get_mode_size_bits(op_mode) != get_mode_size_bits(get_ia32_ls_mode(node)))
+ return;
+
+ if (get_irn_mode(op) != mode_T) {
+ set_irn_mode(op, mode_T);
/* If there are other users, reroute them to result proj */
- if (get_irn_n_edges(left) != 2) {
- ir_node *res = new_r_Proj(left, mode_Iu, pn_ia32_res);
+ if (get_irn_n_edges(op) != 2) {
+ ir_node *res = new_r_Proj(op, mode_Iu, pn_ia32_res);
- edges_reroute(left, res, current_ir_graph);
+ edges_reroute(op, res);
/* Reattach the result proj to left */
- set_Proj_pred(res, left);
+ set_Proj_pred(res, op);
}
+ } else {
+ if (get_irn_n_edges(left) == 2)
+ kill_node(left);
}
flags_mode = ia32_reg_classes[CLASS_ia32_flags].mode;
- flags_proj = new_r_Proj(left, flags_mode, pn_ia32_flags);
+ flags_proj = new_r_Proj(op, flags_mode, pn_ia32_flags);
arch_set_irn_register(flags_proj, &ia32_registers[REG_EFLAGS]);
assert(get_irn_mode(node) != mode_T);
if ((offset & 0xFFFFFF00) == 0) {
/* attr->am_offs += 0; */
} else if ((offset & 0xFFFF00FF) == 0) {
- ir_node *imm = ia32_create_Immediate(NULL, 0, offset >> 8);
- set_irn_n(node, n_ia32_Test_right, imm);
+ ir_node *imm_node = ia32_create_Immediate(NULL, 0, offset>>8);
+ set_irn_n(node, n_ia32_Test_right, imm_node);
attr->am_offs += 1;
} else if ((offset & 0xFF00FFFF) == 0) {
- ir_node *imm = ia32_create_Immediate(NULL, 0, offset >> 16);
- set_irn_n(node, n_ia32_Test_right, imm);
+ ir_node *imm_node = ia32_create_Immediate(NULL, 0, offset>>16);
+ set_irn_n(node, n_ia32_Test_right, imm_node);
attr->am_offs += 2;
} else if ((offset & 0x00FFFFFF) == 0) {
- ir_node *imm = ia32_create_Immediate(NULL, 0, offset >> 24);
- set_irn_n(node, n_ia32_Test_right, imm);
+ ir_node *imm_node = ia32_create_Immediate(NULL, 0, offset>>24);
+ set_irn_n(node, n_ia32_Test_right, imm_node);
attr->am_offs += 3;
} else {
return;
*/
static void peephole_ia32_Return(ir_node *node)
{
- ir_node *block, *irn;
+ ir_node *irn;
if (!ia32_cg_config.use_pad_return)
return;
- block = get_nodes_block(node);
-
/* check if this return is the first on the block */
sched_foreach_reverse_from(node, irn) {
switch (get_irn_opcode(irn)) {
continue;
case iro_Start:
case beo_Start:
- case beo_Barrier:
/* ignore no code generated */
continue;
case beo_IncSP:
mem = get_irn_n(store, n_ia32_mem);
spreg = arch_get_irn_register(curr_sp);
- push = new_bd_ia32_Push(get_irn_dbg_info(store), block, noreg, noreg, mem, val, curr_sp);
+ push = new_bd_ia32_Push(get_irn_dbg_info(store), block, noreg, noreg,
+ mem, val, curr_sp);
copy_mark(store, push);
if (first_push == NULL)
/* create memory Proj */
mem_proj = new_r_Proj(push, mode_M, pn_ia32_Push_M);
+ /* rewire Store Projs */
+ foreach_out_edge_safe(store, edge, next) {
+ ir_node *proj = get_edge_src_irn(edge);
+ if (!is_Proj(proj))
+ continue;
+ switch (get_Proj_proj(proj)) {
+ case pn_ia32_Store_M:
+ exchange(proj, mem_proj);
+ break;
+ default:
+ panic("unexpected Proj on Store->IncSp");
+ }
+ }
+
/* use the memproj now */
- be_peephole_exchange(store, mem_proj);
+ be_peephole_exchange(store, push);
inc_ofs -= 4;
}
ir_node *val = ia32_new_NoReg_gp(cg);
ir_node *noreg = ia32_new_NoReg_gp(cg);
ir_graph *irg = get_irn_irg(block);
- ir_node *nomem = new_r_NoMem(irg);
+ ir_node *nomem = get_irg_no_mem(irg);
ir_node *push = new_bd_ia32_Push(dbgi, block, noreg, noreg, nomem, val, stack);
sched_add_before(schedpoint, push);
/* we have to be at offset 0 */
int my_offset = get_ia32_am_offs_int(store);
if (my_offset != 0) {
- /* TODO here: find out wether there is a store with offset 0 before
- * us and wether we can move it down to our place */
+ /* TODO here: find out whether there is a store with offset 0 before
+ * us and whether we can move it down to our place */
return;
}
ir_mode *ls_mode = get_ia32_ls_mode(store);
*/
static inline int mode_needs_gp_reg(ir_mode *mode)
{
- if (mode == mode_fpcw)
+ if (mode == ia32_mode_fpcw)
return 0;
if (get_mode_size_bits(mode) > 32)
return 0;
int i, maxslot, inc_ofs, ofs;
ir_node *node, *pred_sp, *block;
ir_node *loads[MAXPUSH_OPTIMIZE];
- ir_graph *irg;
unsigned regmask = 0;
unsigned copymask = ~0;
if (loads[loadslot] != NULL)
break;
- dreg = arch_irn_get_register(node, pn_ia32_Load_res);
+ dreg = arch_get_irn_register_out(node, pn_ia32_Load_res);
if (regmask & (1 << dreg->index)) {
/* this register is already used */
break;
/* create a new IncSP if needed */
block = get_nodes_block(irn);
- irg = get_irn_irg(irn);
if (inc_ofs > 0) {
pred_sp = be_new_IncSP(esp, block, pred_sp, -inc_ofs, be_get_IncSP_align(irn));
sched_add_before(irn, pred_sp);
const arch_register_t *reg;
mem = get_irn_n(load, n_ia32_mem);
- reg = arch_irn_get_register(load, pn_ia32_Load_res);
+ reg = arch_get_irn_register_out(load, pn_ia32_Load_res);
pop = new_bd_ia32_Pop(get_irn_dbg_info(load), block, mem, pred_sp);
- arch_irn_set_register(pop, pn_ia32_Load_res, reg);
+ arch_set_irn_register_out(pop, pn_ia32_Load_res, reg);
copy_mark(load, pop);
if (!rbitset_is_set(birg->allocatable_regs, reg->global_index))
continue;
- if (be_peephole_get_value(CLASS_ia32_gp, i) == NULL)
+ if (be_peephole_get_value(reg->global_index) == NULL)
return reg;
}
ir_node *val;
ir_node *in[1];
- pop = new_bd_ia32_Pop(dbgi, block, new_r_NoMem(irg), stack);
+ pop = new_bd_ia32_Pop(dbgi, block, get_irg_no_mem(irg), stack);
stack = new_r_Proj(pop, mode_Iu, pn_ia32_Pop_stack);
arch_set_irn_register(stack, esp);
if (ia32_cg_config.use_mov_0)
return;
/* xor destroys the flags, so no-one must be using them */
- if (be_peephole_get_value(CLASS_ia32_flags, REG_FLAGS_EFLAGS) != NULL)
+ if (be_peephole_get_value(REG_EFLAGS) != NULL)
return;
reg = arch_get_irn_register(node);
assert(is_ia32_Lea(node));
/* we can only do this if it is allowed to clobber the flags */
- if (be_peephole_get_value(CLASS_ia32_flags, REG_FLAGS_EFLAGS) != NULL)
+ if (be_peephole_get_value(REG_EFLAGS) != NULL)
return;
base = get_irn_n(node, n_ia32_Lea_base);
block = get_nodes_block(node);
irg = get_irn_irg(node);
noreg = ia32_new_NoReg_gp(irg);
- nomem = new_r_NoMem(irg);
+ nomem = get_irg_no_mem(irg);
res = new_bd_ia32_Add(dbgi, block, noreg, noreg, nomem, op1, op2);
arch_set_irn_register(res, out_reg);
set_ia32_commutative(res);
block = get_nodes_block(node);
irg = get_irn_irg(node);
noreg = ia32_new_NoReg_gp(irg);
- nomem = new_r_NoMem(irg);
+ nomem = get_irg_no_mem(irg);
res = new_bd_ia32_Shl(dbgi, block, op1, op2);
arch_set_irn_register(res, out_reg);
goto exchange;
return;
/* fine, we can rebuild it */
- res = turn_back_am(imul);
+ res = ia32_turn_back_am(imul);
arch_set_irn_register(res, reg);
}
if (get_mode_size_bits(smaller_mode) != 16 ||
!mode_is_signed(smaller_mode) ||
eax != arch_get_irn_register(val) ||
- eax != arch_irn_get_register(node, pn_ia32_Conv_I2I_res))
+ eax != arch_get_irn_register_out(node, pn_ia32_Conv_I2I_res))
return;
dbgi = get_irn_dbg_info(node);
/**
* Removes node from schedule if it is not used anymore. If irn is a mode_T node
- * all it's Projs are removed as well.
+ * all its Projs are removed as well.
* @param irn The irn to be removed from schedule
*/
static inline void try_kill(ir_node *node)
/* Argh:We must change the opcode to 8bit AND copy the register constraints */
if (get_mode_size_bits(conv_mode) == 8) {
+ const arch_register_req_t **reqs = arch_get_irn_register_reqs_in(node);
set_irn_op(pred, op_ia32_Conv_I2I8Bit);
- arch_set_in_register_reqs(pred,
- arch_get_in_register_reqs(node));
+ arch_set_irn_register_reqs_in(pred, reqs);
}
} else {
/* we don't want to end up with 2 loads, so we better do nothing */
/* Argh:We must change the opcode to 8bit AND copy the register constraints */
if (get_mode_size_bits(conv_mode) == 8) {
+ const arch_register_req_t **reqs = arch_get_irn_register_reqs_in(node);
set_irn_op(result_conv, op_ia32_Conv_I2I8Bit);
- arch_set_in_register_reqs(result_conv,
- arch_get_in_register_reqs(node));
+ arch_set_irn_register_reqs_in(result_conv, reqs);
}
}
} else {