set_irn_mode(irn, mode);
}
+ /*
+ Annotate mode of stored value to link field of the Store
+ as floating point converts might be optimized and we would
+ loose the mode.
+ */
+ if (get_irn_opcode(irn) == iro_Store) {
+ set_irn_link(irn, get_irn_mode(get_Store_value(irn)));
+ }
+
tenv.block = get_nodes_block(irn);
tenv.cg = cg;
tenv.irg = cg->irg;
* - the load must not have other users than the irn AND
* - the irn must not have a frame entity set
*
+ * @param cg The ia32 code generator
* @param h The height information of the irg
* @param block The block the Loads must/mustnot be in
* @param irn The irn to check
* return 0 if irn is no candidate, 1 if left load can be used, 2 if right one, 3 for both
*/
-static ia32_am_cand_t is_am_candidate(heights_t *h, const ir_node *block, ir_node *irn) {
+static ia32_am_cand_t is_am_candidate(ia32_code_gen_t *cg, heights_t *h, const ir_node *block, ir_node *irn) {
ir_node *in, *load, *other, *left, *right;
int n, is_cand = 0, cand;
cand = is_cand ? (cand | IA32_AM_CAND_RIGHT) : cand;
+ /* check some special cases */
+ if (USE_SSE2(cg) && is_ia32_Conv_I2FP(irn)) {
+ /* SSE Conv I -> FP cvtsi2s(s|d) can only load 32 bit values */
+ if (get_mode_size_bits(get_ia32_tgt_mode(irn)) != 32)
+ cand = IA32_AM_CAND_NONE;
+ }
+ else if (is_ia32_Conv_I2I(irn)) {
+ /* we cannot load an N bit value and implicitly convert it into an M bit value if N > M */
+ if (get_mode_size_bits(get_ia32_src_mode(irn)) > get_mode_size_bits(get_ia32_tgt_mode(irn)))
+ cand = IA32_AM_CAND_NONE;
+ }
+
/* if the irn has a frame entity: we do not use address mode */
return get_ia32_frame_ent(irn) ? IA32_AM_CAND_NONE : cand;
}
/* - nobody else uses the result of the op */
if ((get_ia32_am_support(irn) != ia32_am_None) && ! is_ia32_Lea(irn)) {
- ia32_am_cand_t cand = is_am_candidate(h, block, irn);
+ ia32_am_cand_t cand = is_am_candidate(cg, h, block, irn);
ia32_am_cand_t orig_cand = cand;
/* cand == 1: load is left; cand == 2: load is right; */