}
/**
- * Get an atomic entity that is initialized with a tarval
+ * Get an atomic entity that is initialized with a tarval forming
+ * a given constant.
+ *
+ * @param cnst the node representing the constant
*/
static ir_entity *create_float_const_entity(ir_node *cnst)
{
ia32_isa_t *isa = env_cg->isa;
- tarval *tv = get_Const_tarval(cnst);
- pmap_entry *e = pmap_find(isa->tv_ent, tv);
+ tarval *key = get_Const_tarval(cnst);
+ pmap_entry *e = pmap_find(isa->tv_ent, key);
ir_entity *res;
ir_graph *rem;
if (e == NULL) {
- ir_mode *mode = get_irn_mode(cnst);
- ir_type *tp = get_Const_type(cnst);
- if (tp == firm_unknown_type)
+ tarval *tv = key;
+ ir_mode *mode = get_tarval_mode(tv);
+ ir_type *tp;
+
+ if (! ia32_cg_config.use_sse2) {
+ /* try to reduce the mode to produce smaller sized entities */
+ if (mode != mode_F) {
+ if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
+ mode = mode_F;
+ tv = tarval_convert_to(tv, mode);
+ } else if (mode != mode_D) {
+ if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
+ mode = mode_D;
+ tv = tarval_convert_to(tv, mode);
+ }
+ }
+ }
+ }
+
+ if (mode == get_irn_mode(cnst)) {
+ /* mode was not changed */
+ tp = get_Const_type(cnst);
+ if (tp == firm_unknown_type)
+ tp = get_prim_type(isa->types, mode);
+ } else
tp = get_prim_type(isa->types, mode);
res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
set_atomic_ent_value(res, new_Const_type(tv, tp));
current_ir_graph = rem;
- pmap_insert(isa->tv_ent, tv, res);
+ pmap_insert(isa->tv_ent, key, res);
} else {
res = e->value;
}
if (is_Const_null(node)) {
load = new_rd_ia32_vfldz(dbgi, irg, block);
res = load;
+ set_ia32_ls_mode(load, mode);
} else if (is_Const_one(node)) {
load = new_rd_ia32_vfld1(dbgi, irg, block);
res = load;
+ set_ia32_ls_mode(load, mode);
} else {
floatent = create_float_const_entity(node);
set_ia32_am_sc(load, floatent);
set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
+ /* take the mode from the entity */
+ set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
}
- set_ia32_ls_mode(load, mode);
}
end:
/* Const Nodes before the initial IncSP are a bad idea, because
if (ia32_cg_config.use_sse2) {
return ia32_new_Unknown_xmm(env_cg);
} else {
- /* Unknown nodes are buggy in x87 sim, use zero for now... */
+ /* Unknown nodes are buggy in x87 simulator, use zero for now... */
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = get_irg_start_block(irg);