Commit 33211378 authored by Matthias Braun's avatar Matthias Braun
Browse files

improve float->int conversion

[r16257]
parent db6fd292
......@@ -1416,12 +1416,13 @@ static void ia32_collect_frame_entity_nodes(ir_node *node, void *data)
be_node_needs_frame_entity(env, node, mode, align);
} else if (is_ia32_vfild(node) || is_ia32_xLoad(node)
|| is_ia32_vfld(node)) {
const ir_mode *mode = get_ia32_ls_mode(node);
int align = 4;
const ir_mode *mode = get_ia32_ls_mode(node);
int align = 4;
be_node_needs_frame_entity(env, node, mode, align);
} else if(is_ia32_FldCW(node)) {
const ir_mode *mode = ia32_reg_classes[CLASS_ia32_fp_cw].mode;
int align = 4;
/* although 2 byte would be enough 4 byte performs best */
const ir_mode *mode = mode_Iu;
int align = 4;
be_node_needs_frame_entity(env, node, mode, align);
} else {
#ifndef NDEBUG
......@@ -2320,6 +2321,7 @@ static const lc_opt_table_entry_t ia32_options[] = {
LC_OPT_ENT_ENUM_INT("opt", "optimize for instruction architecture", &opt_arch_var),
LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit", &fp_unit_var),
LC_OPT_ENT_NEGBIT("nooptcc", "do not optimize calling convention", &ia32_isa_template.opt, IA32_OPT_CC),
LC_OPT_ENT_BIT("unsafe_floatconv", "do unsage floating point controlword optimisations", &ia32_isa_template.opt, IA32_OPT_UNSAFE_FLOATCONV),
LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
LC_OPT_LAST
};
......
......@@ -54,7 +54,12 @@ typedef enum fp_support fp_support;
*/
enum ia32_optimize_t {
IA32_OPT_INCDEC = 1 << 0, /**< optimize add/sub 1/-1 to inc/dec */
IA32_OPT_CC = 1 << 1,
IA32_OPT_CC = 1 << 1, /**< optimize caling convention of private
functions */
IA32_OPT_UNSAFE_FLOATCONV = 1 << 2, /**< disrespect current floating
point rounding mode at entry and exit of
functions (this is ok for programs that don't
explicitely change the rounding mode) */
};
/**
......
......@@ -114,10 +114,12 @@ static int do_is_immediate(const ir_node *node, int *symconsts, int negate)
*
* @return non-zero if the DAG represents an immediate, 0 else
*/
#if 0
static int is_immediate_simple(const ir_node *node) {
int symconsts = 0;
return do_is_immediate(node, &symconsts, 0);
}
#endif
/**
* Check if a DAG starting with root node can be folded into an address mode
......
......@@ -35,6 +35,7 @@
#include "irprog_t.h"
#include "lowering.h"
#include "array.h"
#include "error.h"
#include "ia32_new_nodes.h"
#include "bearch_ia32_t.h"
......
......@@ -2036,24 +2036,43 @@ static ir_node *try_create_dest_am(ir_node *node) {
return new_node;
}
static int is_float_to_int32_conv(const ir_node *node)
{
ir_mode *mode = get_irn_mode(node);
ir_node *conv_op;
ir_mode *conv_mode;
if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
return 0;
if(!is_Conv(node))
return 0;
conv_op = get_Conv_op(node);
conv_mode = get_irn_mode(conv_op);
if(!mode_is_float(conv_mode))
return 0;
return 1;
}
/**
* Transforms a Store.
*
* @return the created ia32 Store node
*/
static ir_node *gen_Store(ir_node *node) {
ir_node *block = be_transform_node(get_nodes_block(node));
ir_node *ptr = get_Store_ptr(node);
ir_node *base;
ir_node *index;
ir_node *val = get_Store_value(node);
static ir_node *gen_Store(ir_node *node)
{
ir_node *block = get_nodes_block(node);
ir_node *new_block = be_transform_node(block);
ir_node *ptr = get_Store_ptr(node);
ir_node *val = get_Store_value(node);
ir_node *mem = get_Store_mem(node);
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *noreg = ia32_new_NoReg_gp(env_cg);
ir_mode *mode = get_irn_mode(val);
ir_node *new_val;
ir_node *mem = get_Store_mem(node);
ir_node *new_mem = be_transform_node(mem);
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *noreg = ia32_new_NoReg_gp(env_cg);
ir_mode *mode = get_irn_mode(val);
ir_node *new_node;
ia32_address_t addr;
......@@ -2065,20 +2084,19 @@ static ir_node *gen_Store(ir_node *node) {
/* construct store address */
memset(&addr, 0, sizeof(addr));
ia32_create_address_mode(&addr, ptr, /*force=*/0);
base = addr.base;
index = addr.index;
if(base == NULL) {
base = noreg;
if(addr.base == NULL) {
addr.base = noreg;
} else {
base = be_transform_node(base);
addr.base = be_transform_node(addr.base);
}
if(index == NULL) {
index = noreg;
if(addr.index == NULL) {
addr.index = noreg;
} else {
index = be_transform_node(index);
addr.index = be_transform_node(addr.index);
}
addr.mem = be_transform_node(mem);
if (mode_is_float(mode)) {
/* convs (and strict-convs) before stores are unnecessary if the mode
......@@ -2088,23 +2106,35 @@ static ir_node *gen_Store(ir_node *node) {
}
new_val = be_transform_node(val);
if (USE_SSE2(env_cg)) {
new_node = new_rd_ia32_xStore(dbgi, irg, block, base, index,
new_mem, new_val);
new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
addr.index, addr.mem, new_val);
} else {
new_node = new_rd_ia32_vfst(dbgi, irg, block, base, index, new_mem,
new_val, mode);
new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
addr.index, addr.mem, new_val, mode);
}
} else if(is_float_to_int32_conv(val)) {
ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
val = get_Conv_op(val);
/* convs (and strict-convs) before stores are unnecessary if the mode
is the same */
while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
val = get_Conv_op(val);
}
new_val = be_transform_node(val);
new_node = new_rd_ia32_vfist(dbgi, irg, new_block, addr.base,
addr.index, addr.mem, new_val, trunc_mode);
} else {
new_val = create_immediate_or_transform(val, 0);
if(mode == mode_b)
mode = mode_Iu;
assert(mode != mode_b);
if (get_mode_size_bits(mode) == 8) {
new_node = new_rd_ia32_Store8Bit(dbgi, irg, block, base, index,
new_mem, new_val);
new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
addr.index, addr.mem, new_val);
} else {
new_node = new_rd_ia32_Store(dbgi, irg, block, base, index, new_mem,
new_val);
new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
addr.index, addr.mem, new_val);
}
}
......
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