match_commutative = 1 << 0,
match_am_and_immediates = 1 << 1,
match_no_am = 1 << 2,
- match_8_16_bit_am = 1 << 3,
- match_no_immediate = 1 << 4
+ match_8_bit_am = 1 << 3,
+ match_16_bit_am = 1 << 4,
+ match_no_immediate = 1 << 5,
+ match_force_32bit_op = 1 << 6
} match_flags_t;
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
int commutative;
int use_am_and_immediates;
int use_immediate;
+ int mode_bits = get_mode_size_bits(mode);
memset(am, 0, sizeof(am[0]));
assert(op2 != NULL);
assert(!commutative || op1 != NULL);
- if(!(flags & match_8_16_bit_am)
- && get_mode_size_bits(mode) < 32)
+ if(mode_bits == 8 && !(flags & match_8_bit_am)) {
use_am = 0;
+ } else if(mode_bits == 16 && !(flags & match_16_bit_am)) {
+ use_am = 0;
+ }
new_op2 = (use_immediate ? try_create_Immediate(op2, 0) : NULL);
if(new_op2 == NULL && use_am && use_source_address_mode(block, op2, op1)) {
if(new_op2 == NULL)
new_op2 = be_transform_node(op2);
am->op_type = ia32_Normal;
+ if(flags & match_force_32bit_op) {
+ am->ls_mode = mode_Iu;
+ } else {
+ am->ls_mode = get_irn_mode(op2);
+ }
}
if(addr->base == NULL)
addr->base = noreg_gp;
* @return The constructed ia32 node.
*/
static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
- construct_binop_func *func, int commutative)
+ construct_binop_func *func, match_flags_t flags)
{
- ir_node *src_block = get_nodes_block(node);
- ir_node *block = be_transform_node(src_block);
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(block);
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_node;
ia32_address_mode_t am;
ia32_address_t *addr = &am.addr;
- match_flags_t flags = 0;
- if(commutative)
- flags |= match_commutative;
+ flags |= match_force_32bit_op;
- match_arguments(&am, src_block, op1, op2, flags);
+ match_arguments(&am, block, op1, op2, flags);
- new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
+ new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
am.new_op1, am.new_op2);
set_am_attributes(new_node, &am);
/* we can't use source address mode anymore when using immediates */
*/
static ir_node *gen_binop_sse_float(ir_node *node, ir_node *op1, ir_node *op2,
construct_binop_func *func,
- int commutative)
+ match_flags_t flags)
{
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *new_op1 = be_transform_node(op1);
- ir_node *new_op2 = be_transform_node(op2);
- ir_node *new_node = NULL;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_graph *irg = current_ir_graph;
- ir_mode *mode = get_irn_mode(node);
- ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
- ir_node *nomem = new_NoMem();
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(block);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_graph *irg = current_ir_graph;
+ ir_node *new_node;
+ ia32_address_mode_t am;
+ ia32_address_t *addr = &am.addr;
- new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, nomem, new_op1,
- new_op2);
- if (commutative) {
- set_ia32_commutative(new_node);
- }
- set_ia32_ls_mode(new_node, mode);
+ match_arguments(&am, block, op1, op2, flags);
+
+ new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
+ am.new_op1, am.new_op2);
+ set_am_attributes(new_node, &am);
SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
+ new_node = fix_mem_proj(new_node, &am);
+
return new_node;
}
*/
static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
construct_binop_float_func *func,
- int commutative)
+ match_flags_t flags)
{
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *src_block = get_nodes_block(node);
- ir_node *new_block = be_transform_node(src_block);
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(block);
ir_node *new_node;
ia32_address_mode_t am;
ia32_address_t *addr = &am.addr;
- match_flags_t flags = 0;
-
- if(commutative)
- flags |= match_commutative;
- match_arguments(&am, src_block, op1, op2, flags);
+ match_arguments(&am, block, op1, op2, flags);
new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
am.new_op1, am.new_op2, get_fpcw());
* @return the created ia32 Add node
*/
static ir_node *gen_Add(ir_node *node) {
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *op1 = get_Add_left(node);
- ir_node *op2 = get_Add_right(node);
- ir_node *new_op;
+ ir_graph *irg = current_ir_graph;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(block);
+ ir_node *op1 = get_Add_left(node);
+ ir_node *op2 = get_Add_right(node);
+ ir_mode *mode = get_irn_mode(node);
+ ir_node *noreg = ia32_new_NoReg_gp(env_cg);
+ ir_node *new_node;
ir_node *new_op1;
- ir_graph *irg = current_ir_graph;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_mode *mode = get_irn_mode(node);
- ir_node *noreg = ia32_new_NoReg_gp(env_cg);
- ir_node *src_block = get_nodes_block(node);
ir_node *add_immediate_op;
ia32_address_t addr;
ia32_address_mode_t am;
if (mode_is_float(mode)) {
if (USE_SSE2(env_cg))
- return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd, 1);
+ return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd, match_commutative);
else
- return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd, 1);
+ return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd, match_commutative);
}
/**
add_immediate_op = NULL;
/* a constant? */
if(addr.base == NULL && addr.index == NULL) {
- new_op = new_rd_ia32_Const(dbgi, irg, block, addr.symconst_ent,
- addr.symconst_sign, addr.offset);
- add_irn_dep(new_op, get_irg_frame(irg));
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
- return new_op;
+ new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
+ addr.symconst_sign, addr.offset);
+ add_irn_dep(new_node, get_irg_frame(irg));
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
+ return new_node;
}
/* add with immediate? */
if(addr.index == NULL) {
return be_transform_node(add_immediate_op);
}
- new_op = create_lea_from_address(dbgi, block, &addr);
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
- return new_op;
+ new_node = create_lea_from_address(dbgi, new_block, &addr);
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
+ return new_node;
}
/* test if we can use source address mode */
memset(&am, 0, sizeof(am));
new_op1 = NULL;
- if(use_source_address_mode(src_block, op2, op1)) {
+ if(use_source_address_mode(block, op2, op1)) {
build_address(&am, op2);
new_op1 = be_transform_node(op1);
- } else if(use_source_address_mode(src_block, op1, op2)) {
+ } else if(use_source_address_mode(block, op1, op2)) {
build_address(&am, op1);
new_op1 = be_transform_node(op2);
}
/* construct an Add with source address mode */
if(new_op1 != NULL) {
ia32_address_t *am_addr = &am.addr;
- new_op = new_rd_ia32_Add(dbgi, irg, block, am_addr->base, am_addr->index,
- am_addr->mem, new_op1, noreg);
- set_address(new_op, am_addr);
- set_ia32_op_type(new_op, ia32_AddrModeS);
- set_ia32_ls_mode(new_op, am.ls_mode);
- set_ia32_commutative(new_op);
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
+ new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
+ am_addr->index, am_addr->mem, new_op1, noreg);
+ set_address(new_node, am_addr);
+ set_ia32_op_type(new_node, ia32_AddrModeS);
+ set_ia32_ls_mode(new_node, am.ls_mode);
+ set_ia32_commutative(new_node);
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
- new_op = fix_mem_proj(new_op, &am);
+ new_node = fix_mem_proj(new_node, &am);
- return new_op;
+ return new_node;
}
/* otherwise construct a lea */
- new_op = create_lea_from_address(dbgi, block, &addr);
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
- return new_op;
+ new_node = create_lea_from_address(dbgi, new_block, &addr);
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
+ return new_node;
}
/**
if (mode_is_float(mode)) {
if (USE_SSE2(env_cg))
- return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul, 1);
+ return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul, match_commutative);
else
- return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul, 1);
+ return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul, match_commutative);
}
/*
signed or unsigned multiplication so we use IMul as it has fewer
constraints
*/
- return gen_binop(node, op1, op2, new_rd_ia32_IMul, 1);
+ return gen_binop(node, op1, op2, new_rd_ia32_IMul, match_commutative);
}
/**
set_ia32_commutative(res);
- proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX);
+ proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_ia32_IMul1OP_EDX);
return proj_EDX;
}
}
}
- return gen_binop(node, op1, op2, new_rd_ia32_And, 1);
+ return gen_binop(node, op1, op2, new_rd_ia32_And, match_commutative);
}
ir_node *op2 = get_Or_right(node);
assert (! mode_is_float(get_irn_mode(node)));
- return gen_binop(node, op1, op2, new_rd_ia32_Or, 1);
+ return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative);
}
ir_node *op2 = get_Eor_right(node);
assert(! mode_is_float(get_irn_mode(node)));
- return gen_binop(node, op1, op2, new_rd_ia32_Xor, 1);
+ return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative);
}
return gen_binop(node, op1, op2, new_rd_ia32_Sub, 0);
}
-
+typedef enum { flavour_Div = 1, flavour_Mod, flavour_DivMod } ia32_op_flavour_t;
/**
* Generates an ia32 DivMod with additional infrastructure for the
if (mode_is_signed(mode)) {
res = new_rd_ia32_IDiv(dbgi, irg, block, noreg, noreg, new_mem,
- new_dividend, sign_extension, new_divisor, dm_flav);
+ new_dividend, sign_extension, new_divisor);
} else {
- res = new_rd_ia32_Div(dbgi, irg, block, noreg, noreg, new_mem, new_dividend,
- sign_extension, new_divisor, dm_flav);
+ res = new_rd_ia32_Div(dbgi, irg, block, noreg, noreg, new_mem,
+ new_dividend, sign_extension, new_divisor);
}
set_ia32_exc_label(res, has_exc);
if (mode_is_float(mode)) {
ir_node *new_op = be_transform_node(op);
if (USE_SSE2(env_cg)) {
- ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
- ir_node *noreg_fp = ia32_new_NoReg_fp(env_cg);
- ir_node *nomem = new_rd_NoMem(irg);
+ ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
+ ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
+ ir_node *nomem = new_rd_NoMem(irg);
res = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp, nomem,
- new_op, noreg_fp);
+ new_op, noreg_xmm);
size = get_mode_size_bits(mode);
ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
assert(get_mode_size_bits(mode) <= 32);
match_arguments(&am, block, left, right, match_commutative |
- match_8_16_bit_am | match_am_and_immediates);
+ match_8_bit_am | match_16_bit_am | match_am_and_immediates);
cmp_unsigned = !mode_is_signed(mode);
if(get_mode_size_bits(mode) == 8) {
ir_node *new_right;
ir_node *res;
- if(1 || transform_config.use_fucomi) {
+ if(transform_config.use_fucomi) {
new_right = be_transform_node(right);
res = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left, new_right, 0);
set_ia32_commutative(res);
{
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *block = get_nodes_block(node);
- ir_node *new_block = be_transform_node(block);
+ ir_node *src_block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(src_block);
ir_node *left = get_Cmp_left(node);
- ir_node *new_left = be_transform_node(left);
ir_node *right = get_Cmp_right(node);
- ir_node *new_right = be_transform_node(right);
- ir_mode *mode = get_irn_mode(left);
- ir_node *noreg = ia32_new_NoReg_gp(env_cg);
- ir_node *nomem = new_NoMem();
- ir_node *res;
+ ir_node *new_node;
+ ia32_address_mode_t am;
+ ia32_address_t *addr = &am.addr;
- res = new_rd_ia32_Ucomi(dbgi, irg, new_block, noreg, noreg, nomem, new_left,
- new_right, 0);
- set_ia32_commutative(res);
- set_ia32_ls_mode(res, mode);
+ match_arguments(&am, src_block, left, right, match_commutative);
- SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
+ new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
+ addr->mem, am.new_op1, am.new_op2, am.flipped);
+ set_am_attributes(new_node, &am);
- return res;
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
+
+ new_node = fix_mem_proj(new_node, &am);
+
+ return new_node;
}
static ir_node *gen_Cmp(ir_node *node)
}
match_arguments(&am, block, left, right,
- match_commutative | match_8_16_bit_am |
+ match_commutative | match_8_bit_am | match_16_bit_am |
match_am_and_immediates);
cmp_unsigned = !mode_is_signed(get_irn_mode(left));
static ir_node *create_CMov(ir_node *node, ir_node *new_flags, pn_Cmp pnc)
{
- ir_graph *irg = current_ir_graph;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *block = get_nodes_block(node);
- ir_node *new_block = be_transform_node(block);
- ir_node *val_true = get_Psi_val(node, 0);
- ir_node *new_val_true = be_transform_node(val_true);
- ir_node *val_false = get_Psi_default(node);
- ir_node *new_val_false = be_transform_node(val_false);
- ir_mode *mode = get_irn_mode(node);
- ir_node *noreg = ia32_new_NoReg_gp(env_cg);
- ir_node *nomem = new_NoMem();
- ir_node *res;
+ ir_graph *irg = current_ir_graph;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(block);
+ ir_node *val_true = get_Psi_val(node, 0);
+ ir_node *val_false = get_Psi_default(node);
+ ir_node *new_node;
+ match_flags_t match_flags;
- assert(mode_needs_gp_reg(mode));
+ assert(transform_config.use_cmov);
- res = new_rd_ia32_CMov(dbgi, irg, new_block, noreg, noreg, nomem,
- new_val_false, new_val_true, new_flags, pnc);
- SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
+ assert(mode_needs_gp_reg(get_irn_mode(val_true)));
- return res;
+ ia32_address_mode_t am;
+ ia32_address_t *addr = &am.addr;
+
+ match_flags = match_commutative | match_no_immediate | match_16_bit_am
+ | match_force_32bit_op;
+
+ match_arguments(&am, block, val_false, val_true, match_flags);
+
+ new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
+ addr->mem, am.new_op1, am.new_op2, new_flags,
+ am.flipped, pnc);
+ set_am_attributes(new_node, &am);
+
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
+
+ new_node = fix_mem_proj(new_node, &am);
+
+ return new_node;
}
}
/**
- * Transform a be_AddSP into an ia32_AddSP. Eat up const sizes.
+ * Transform a be_AddSP into an ia32_SubSP.
*/
-static ir_node *gen_be_AddSP(ir_node *node) {
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
- ir_node *new_sz;
- ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
- ir_node *new_sp = be_transform_node(sp);
- ir_graph *irg = current_ir_graph;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *noreg = ia32_new_NoReg_gp(env_cg);
- ir_node *nomem = new_NoMem();
- ir_node *new_op;
+static ir_node *gen_be_AddSP(ir_node *node)
+{
+ ir_node *src_block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(src_block);
+ ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
+ ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
+ ir_graph *irg = current_ir_graph;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *new_node;
+ ia32_address_mode_t am;
+ ia32_address_t *addr = &am.addr;
+ match_flags_t flags = 0;
- new_sz = create_immediate_or_transform(sz, 0);
+ match_arguments(&am, src_block, sp, sz, flags);
- /* ia32 stack grows in reverse direction, make a SubSP */
- new_op = new_rd_ia32_SubSP(dbgi, irg, block, noreg, noreg, nomem, new_sp,
- new_sz);
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
+ new_node = new_rd_ia32_SubSP(dbgi, irg, new_block, addr->base, addr->index,
+ addr->mem, am.new_op1, am.new_op2);
+ set_am_attributes(new_node, &am);
+ /* we can't use source address mode anymore when using immediates */
+ if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
+ set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
- return new_op;
+ new_node = fix_mem_proj(new_node, &am);
+
+ return new_node;
}
/**
- * Transform a be_SubSP into an ia32_SubSP. Eat up const sizes.
+ * Transform a be_SubSP into an ia32_AddSP
*/
-static ir_node *gen_be_SubSP(ir_node *node) {
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
- ir_node *new_sz;
- ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
- ir_node *new_sp = be_transform_node(sp);
- ir_graph *irg = current_ir_graph;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *noreg = ia32_new_NoReg_gp(env_cg);
- ir_node *nomem = new_NoMem();
- ir_node *new_op;
+static ir_node *gen_be_SubSP(ir_node *node)
+{
+ ir_node *src_block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(src_block);
+ ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
+ ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
+ ir_graph *irg = current_ir_graph;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *new_node;
+ ia32_address_mode_t am;
+ ia32_address_t *addr = &am.addr;
+ match_flags_t flags = 0;
- new_sz = create_immediate_or_transform(sz, 0);
+ match_arguments(&am, src_block, sp, sz, flags);
- /* ia32 stack grows in reverse direction, make an AddSP */
- new_op = new_rd_ia32_AddSP(dbgi, irg, block, noreg, noreg, nomem, new_sp,
- new_sz);
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
+ new_node = new_rd_ia32_AddSP(dbgi, irg, new_block, addr->base, addr->index,
+ addr->mem, am.new_op1, am.new_op2);
+ set_am_attributes(new_node, &am);
+ /* we can't use source address mode anymore when using immediates */
+ if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
+ set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
+ SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
- return new_op;
+ new_node = fix_mem_proj(new_node, &am);
+
+ return new_node;
}
/**
* @param node The node to transform
* @return the created ia32 XXX node
*/
-#define GEN_LOWERED_OP(op) \
- static ir_node *gen_ia32_l_##op(ir_node *node) { \
- return gen_binop(node, get_binop_left(node), \
- get_binop_right(node), new_rd_ia32_##op,0); \
- }
-
-#define GEN_LOWERED_x87_OP(op) \
- static ir_node *gen_ia32_l_##op(ir_node *node) { \
- ir_node *new_op; \
- new_op = gen_binop_x87_float(node, get_binop_left(node), \
- get_binop_right(node), new_rd_ia32_##op, 0); \
- return new_op; \
- }
-
#define GEN_LOWERED_SHIFT_OP(l_op, op) \
static ir_node *gen_ia32_##l_op(ir_node *node) { \
return gen_shift_binop(node, get_irn_n(node, 0), \
get_irn_n(node, 1), new_rd_ia32_##op); \
}
-GEN_LOWERED_x87_OP(vfprem)
-GEN_LOWERED_x87_OP(vfmul)
-GEN_LOWERED_x87_OP(vfsub)
GEN_LOWERED_SHIFT_OP(l_ShlDep, Shl)
GEN_LOWERED_SHIFT_OP(l_ShrDep, Shr)
-GEN_LOWERED_SHIFT_OP(l_Sar, Sar)
GEN_LOWERED_SHIFT_OP(l_SarDep, Sar)
static ir_node *gen_ia32_l_Add(ir_node *node) {
ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
- ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add, 1);
+ ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add, match_commutative);
if(is_Proj(lowered)) {
lowered = get_Proj_pred(lowered);
return new_op;
}
-/**
- * Transforms a l_vfdiv into a "real" vfdiv node.
- *
- * @param env The transformation environment
- * @return the created ia32 vfdiv node
- */
-static ir_node *gen_ia32_l_vfdiv(ir_node *node) {
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *left = get_binop_left(node);
- ir_node *new_left = be_transform_node(left);
- ir_node *right = get_binop_right(node);
- ir_node *new_right = be_transform_node(right);
- ir_node *noreg = ia32_new_NoReg_gp(env_cg);
- ir_graph *irg = current_ir_graph;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *fpcw = get_fpcw();
- ir_node *vfdiv;
-
- vfdiv = new_rd_ia32_vfdiv(dbgi, irg, block, noreg, noreg, new_NoMem(),
- new_left, new_right, fpcw);
- clear_ia32_commutative(vfdiv);
-
- SET_IA32_ORIG_NODE(vfdiv, ia32_get_old_node_name(env_cg, node));
-
- return vfdiv;
-}
-
/**
* Transforms a l_MulS into a "real" MulS node.
*
- * @param env The transformation environment
* @return the created ia32 Mul node
*/
static ir_node *gen_ia32_l_Mul(ir_node *node) {
/**
* Transforms a l_IMulS into a "real" IMul1OPS node.
*
- * @param env The transformation environment
* @return the created ia32 IMul1OP node
*/
static ir_node *gen_ia32_l_IMul(ir_node *node) {
return new_rd_Unknown(irg, mode);
}
-/**
- * Transform and renumber the Projs from a vfdiv.
- */
-static ir_node *gen_Proj_l_vfdiv(ir_node *node) {
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *pred = get_Proj_pred(node);
- ir_node *new_pred = be_transform_node(pred);
- ir_graph *irg = current_ir_graph;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_mode *mode = get_irn_mode(node);
- long proj = get_Proj_proj(node);
-
- switch (proj) {
- case pn_ia32_l_vfdiv_M:
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
- case pn_ia32_l_vfdiv_res:
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
- default:
- assert(0);
- }
-
- return new_rd_Unknown(irg, mode);
-}
-
/**
* Transform and renumber the Projs from a Quot.
*/
return gen_Proj_CopyB(node);
} else if (is_Quot(pred)) {
return gen_Proj_Quot(node);
- } else if (is_ia32_l_vfdiv(pred)) {
- return gen_Proj_l_vfdiv(node);
} else if (be_is_SubSP(pred)) {
return gen_Proj_be_SubSP(node);
} else if (be_is_AddSP(pred)) {
GEN(ia32_l_IMul);
GEN(ia32_l_ShlDep);
GEN(ia32_l_ShrDep);
- GEN(ia32_l_Sar);
GEN(ia32_l_SarDep);
GEN(ia32_l_ShlD);
GEN(ia32_l_ShrD);
GEN(ia32_l_Sub);
GEN(ia32_l_Sbb);
- GEN(ia32_l_vfdiv);
- GEN(ia32_l_vfprem);
- GEN(ia32_l_vfmul);
- GEN(ia32_l_vfsub);
GEN(ia32_l_vfild);
GEN(ia32_l_Load);
GEN(ia32_l_vfist);
void ia32_transform_graph(ia32_code_gen_t *cg) {
ir_graph *irg = cg->irg;
+ /* TODO: look at cpu and fill transform config in with that... */
+ transform_config.use_incdec = 1;
+ transform_config.use_sse2 = 0;
+ transform_config.use_ffreep = 0;
+ transform_config.use_ftst = 0;
+ transform_config.use_femms = 0;
+ transform_config.use_fucomi = 1;
+ transform_config.use_cmov = 1;
+
register_transformers();
env_cg = cg;
initial_fpcw = NULL;