2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
50 #include "../benode.h"
51 #include "../besched.h"
53 #include "../beutil.h"
55 #include "../betranshlp.h"
58 #include "bearch_ia32_t.h"
59 #include "ia32_common_transform.h"
60 #include "ia32_nodes_attr.h"
61 #include "ia32_transform.h"
62 #include "ia32_new_nodes.h"
63 #include "ia32_dbg_stat.h"
64 #include "ia32_optimize.h"
65 #include "ia32_util.h"
66 #include "ia32_address_mode.h"
67 #include "ia32_architecture.h"
69 #include "gen_ia32_regalloc_if.h"
71 /* define this to construct SSE constants instead of load them */
72 #undef CONSTRUCT_SSE_CONST
75 #define SFP_SIGN "0x80000000"
76 #define DFP_SIGN "0x8000000000000000"
77 #define SFP_ABS "0x7FFFFFFF"
78 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
80 #define ULL_BIAS "18446744073709551616"
82 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
83 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
84 #define ENT_SFP_ABS "C_ia32_sfp_abs"
85 #define ENT_DFP_ABS "C_ia32_dfp_abs"
86 #define ENT_ULL_BIAS "C_ia32_ull_bias"
88 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
89 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
91 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
93 static ir_node *initial_fpcw = NULL;
94 int ia32_no_pic_adjust;
96 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
97 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
100 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
101 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
104 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
108 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
110 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
111 ir_node *base, ir_node *index, ir_node *mem);
113 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
114 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
117 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
119 static ir_node *create_immediate_or_transform(ir_node *node,
120 char immediate_constraint_type);
122 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
123 dbg_info *dbgi, ir_node *block,
124 ir_node *op, ir_node *orig_node);
126 /* its enough to have those once */
127 static ir_node *nomem, *noreg_GP;
129 /** a list to postprocess all calls */
130 static ir_node **call_list;
131 static ir_type **call_types;
133 /** Return non-zero is a node represents the 0 constant. */
134 static bool is_Const_0(ir_node *node)
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
148 return is_Const(node) && is_Const_all_one(node);
152 * returns true if constant can be created with a simple float command
154 static bool is_simple_x87_Const(ir_node *node)
156 ir_tarval *tv = get_Const_tarval(node);
157 if (tarval_is_null(tv) || tarval_is_one(tv))
160 /* TODO: match all the other float constants */
165 * returns true if constant can be created with a simple float command
167 static bool is_simple_sse_Const(ir_node *node)
169 ir_tarval *tv = get_Const_tarval(node);
170 ir_mode *mode = get_tarval_mode(tv);
175 if (tarval_is_null(tv)
176 #ifdef CONSTRUCT_SSE_CONST
181 #ifdef CONSTRUCT_SSE_CONST
182 if (mode == mode_D) {
183 unsigned val = get_tarval_sub_bits(tv, 0) |
184 (get_tarval_sub_bits(tv, 1) << 8) |
185 (get_tarval_sub_bits(tv, 2) << 16) |
186 (get_tarval_sub_bits(tv, 3) << 24);
188 /* lower 32bit are zero, really a 32bit constant */
191 #endif /* CONSTRUCT_SSE_CONST */
192 /* TODO: match all the other float constants */
197 * return NoREG or pic_base in case of PIC.
198 * This is necessary as base address for newly created symbols
200 static ir_node *get_symconst_base(void)
202 ir_graph *irg = current_ir_graph;
204 if (be_get_irg_options(irg)->pic) {
205 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
206 return arch_env->impl->get_pic_base(irg);
213 * Transforms a Const.
215 static ir_node *gen_Const(ir_node *node)
217 ir_node *old_block = get_nodes_block(node);
218 ir_node *block = be_transform_node(old_block);
219 dbg_info *dbgi = get_irn_dbg_info(node);
220 ir_mode *mode = get_irn_mode(node);
222 assert(is_Const(node));
224 if (mode_is_float(mode)) {
230 if (ia32_cg_config.use_sse2) {
231 ir_tarval *tv = get_Const_tarval(node);
232 if (tarval_is_null(tv)) {
233 load = new_bd_ia32_xZero(dbgi, block);
234 set_ia32_ls_mode(load, mode);
236 #ifdef CONSTRUCT_SSE_CONST
237 } else if (tarval_is_one(tv)) {
238 int cnst = mode == mode_F ? 26 : 55;
239 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
240 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
241 ir_node *pslld, *psrld;
243 load = new_bd_ia32_xAllOnes(dbgi, block);
244 set_ia32_ls_mode(load, mode);
245 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
246 set_ia32_ls_mode(pslld, mode);
247 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
248 set_ia32_ls_mode(psrld, mode);
250 #endif /* CONSTRUCT_SSE_CONST */
251 } else if (mode == mode_F) {
252 /* we can place any 32bit constant by using a movd gp, sse */
253 unsigned val = get_tarval_sub_bits(tv, 0) |
254 (get_tarval_sub_bits(tv, 1) << 8) |
255 (get_tarval_sub_bits(tv, 2) << 16) |
256 (get_tarval_sub_bits(tv, 3) << 24);
257 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
258 load = new_bd_ia32_xMovd(dbgi, block, cnst);
259 set_ia32_ls_mode(load, mode);
262 #ifdef CONSTRUCT_SSE_CONST
263 if (mode == mode_D) {
264 unsigned val = get_tarval_sub_bits(tv, 0) |
265 (get_tarval_sub_bits(tv, 1) << 8) |
266 (get_tarval_sub_bits(tv, 2) << 16) |
267 (get_tarval_sub_bits(tv, 3) << 24);
269 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
270 ir_node *cnst, *psllq;
272 /* fine, lower 32bit are zero, produce 32bit value */
273 val = get_tarval_sub_bits(tv, 4) |
274 (get_tarval_sub_bits(tv, 5) << 8) |
275 (get_tarval_sub_bits(tv, 6) << 16) |
276 (get_tarval_sub_bits(tv, 7) << 24);
277 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
278 load = new_bd_ia32_xMovd(dbgi, block, cnst);
279 set_ia32_ls_mode(load, mode);
280 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
281 set_ia32_ls_mode(psllq, mode);
286 #endif /* CONSTRUCT_SSE_CONST */
287 floatent = ia32_create_float_const_entity(node);
289 base = get_symconst_base();
290 load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
292 set_ia32_op_type(load, ia32_AddrModeS);
293 set_ia32_am_sc(load, floatent);
294 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
295 res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
298 if (is_Const_null(node)) {
299 load = new_bd_ia32_vfldz(dbgi, block);
301 set_ia32_ls_mode(load, mode);
302 } else if (is_Const_one(node)) {
303 load = new_bd_ia32_vfld1(dbgi, block);
305 set_ia32_ls_mode(load, mode);
310 floatent = ia32_create_float_const_entity(node);
311 /* create_float_const_ent is smart and sometimes creates
313 ls_mode = get_type_mode(get_entity_type(floatent));
314 base = get_symconst_base();
315 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
317 set_ia32_op_type(load, ia32_AddrModeS);
318 set_ia32_am_sc(load, floatent);
319 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
320 res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
323 #ifdef CONSTRUCT_SSE_CONST
325 #endif /* CONSTRUCT_SSE_CONST */
326 SET_IA32_ORIG_NODE(load, node);
328 } else { /* non-float mode */
330 ir_tarval *tv = get_Const_tarval(node);
333 tv = tarval_convert_to(tv, mode_Iu);
335 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
337 panic("couldn't convert constant tarval (%+F)", node);
339 val = get_tarval_long(tv);
341 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
342 SET_IA32_ORIG_NODE(cnst, node);
349 * Transforms a SymConst.
351 static ir_node *gen_SymConst(ir_node *node)
353 ir_node *old_block = get_nodes_block(node);
354 ir_node *block = be_transform_node(old_block);
355 dbg_info *dbgi = get_irn_dbg_info(node);
356 ir_mode *mode = get_irn_mode(node);
359 if (mode_is_float(mode)) {
360 if (ia32_cg_config.use_sse2)
361 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
363 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
364 set_ia32_am_sc(cnst, get_SymConst_entity(node));
365 set_ia32_use_frame(cnst);
369 if (get_SymConst_kind(node) != symconst_addr_ent) {
370 panic("backend only support symconst_addr_ent (at %+F)", node);
372 entity = get_SymConst_entity(node);
373 if (get_entity_owner(entity) == get_tls_type()) {
374 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
375 ir_node *lea = new_bd_ia32_Lea(dbgi, block, tls_base, noreg_GP);
376 set_ia32_am_sc(lea, entity);
379 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
383 SET_IA32_ORIG_NODE(cnst, node);
389 * Create a float type for the given mode and cache it.
391 * @param mode the mode for the float type (might be integer mode for SSE2 types)
392 * @param align alignment
394 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
400 if (mode == mode_Iu) {
401 static ir_type *int_Iu[16] = {NULL, };
403 if (int_Iu[align] == NULL) {
404 int_Iu[align] = tp = new_type_primitive(mode);
405 /* set the specified alignment */
406 set_type_alignment_bytes(tp, align);
408 return int_Iu[align];
409 } else if (mode == mode_Lu) {
410 static ir_type *int_Lu[16] = {NULL, };
412 if (int_Lu[align] == NULL) {
413 int_Lu[align] = tp = new_type_primitive(mode);
414 /* set the specified alignment */
415 set_type_alignment_bytes(tp, align);
417 return int_Lu[align];
418 } else if (mode == mode_F) {
419 static ir_type *float_F[16] = {NULL, };
421 if (float_F[align] == NULL) {
422 float_F[align] = tp = new_type_primitive(mode);
423 /* set the specified alignment */
424 set_type_alignment_bytes(tp, align);
426 return float_F[align];
427 } else if (mode == mode_D) {
428 static ir_type *float_D[16] = {NULL, };
430 if (float_D[align] == NULL) {
431 float_D[align] = tp = new_type_primitive(mode);
432 /* set the specified alignment */
433 set_type_alignment_bytes(tp, align);
435 return float_D[align];
437 static ir_type *float_E[16] = {NULL, };
439 if (float_E[align] == NULL) {
440 float_E[align] = tp = new_type_primitive(mode);
441 /* set the specified alignment */
442 set_type_alignment_bytes(tp, align);
444 return float_E[align];
449 * Create a float[2] array type for the given atomic type.
451 * @param tp the atomic type
453 static ir_type *ia32_create_float_array(ir_type *tp)
455 ir_mode *mode = get_type_mode(tp);
456 unsigned align = get_type_alignment_bytes(tp);
461 if (mode == mode_F) {
462 static ir_type *float_F[16] = {NULL, };
464 if (float_F[align] != NULL)
465 return float_F[align];
466 arr = float_F[align] = new_type_array(1, tp);
467 } else if (mode == mode_D) {
468 static ir_type *float_D[16] = {NULL, };
470 if (float_D[align] != NULL)
471 return float_D[align];
472 arr = float_D[align] = new_type_array(1, tp);
474 static ir_type *float_E[16] = {NULL, };
476 if (float_E[align] != NULL)
477 return float_E[align];
478 arr = float_E[align] = new_type_array(1, tp);
480 set_type_alignment_bytes(arr, align);
481 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
482 set_type_state(arr, layout_fixed);
486 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
487 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
489 static const struct {
490 const char *ent_name;
491 const char *cnst_str;
494 } names [ia32_known_const_max] = {
495 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
496 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
497 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
498 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
499 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
501 static ir_entity *ent_cache[ia32_known_const_max];
503 const char *ent_name, *cnst_str;
509 ent_name = names[kct].ent_name;
510 if (! ent_cache[kct]) {
511 cnst_str = names[kct].cnst_str;
513 switch (names[kct].mode) {
514 case 0: mode = mode_Iu; break;
515 case 1: mode = mode_Lu; break;
516 default: mode = mode_F; break;
518 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
519 tp = ia32_create_float_type(mode, names[kct].align);
521 if (kct == ia32_ULLBIAS)
522 tp = ia32_create_float_array(tp);
523 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
525 set_entity_ld_ident(ent, get_entity_ident(ent));
526 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
527 set_entity_visibility(ent, ir_visibility_private);
529 if (kct == ia32_ULLBIAS) {
530 ir_initializer_t *initializer = create_initializer_compound(2);
532 set_initializer_compound_value(initializer, 0,
533 create_initializer_tarval(get_mode_null(mode)));
534 set_initializer_compound_value(initializer, 1,
535 create_initializer_tarval(tv));
537 set_entity_initializer(ent, initializer);
539 set_entity_initializer(ent, create_initializer_tarval(tv));
542 /* cache the entry */
543 ent_cache[kct] = ent;
546 return ent_cache[kct];
550 * return true if the node is a Proj(Load) and could be used in source address
551 * mode for another node. Will return only true if the @p other node is not
552 * dependent on the memory of the Load (for binary operations use the other
553 * input here, for unary operations use NULL).
555 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
556 ir_node *other, ir_node *other2, match_flags_t flags)
561 /* float constants are always available */
562 if (is_Const(node)) {
563 ir_mode *mode = get_irn_mode(node);
564 if (mode_is_float(mode)) {
565 if (ia32_cg_config.use_sse2) {
566 if (is_simple_sse_Const(node))
569 if (is_simple_x87_Const(node))
572 if (get_irn_n_edges(node) > 1)
580 load = get_Proj_pred(node);
581 pn = get_Proj_proj(node);
582 if (!is_Load(load) || pn != pn_Load_res)
584 if (get_nodes_block(load) != block)
586 /* we only use address mode if we're the only user of the load */
587 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
589 /* in some edge cases with address mode we might reach the load normally
590 * and through some AM sequence, if it is already materialized then we
591 * can't create an AM node from it */
592 if (be_is_transformed(node))
595 /* don't do AM if other node inputs depend on the load (via mem-proj) */
596 if (other != NULL && ia32_prevents_AM(block, load, other))
599 if (other2 != NULL && ia32_prevents_AM(block, load, other2))
605 typedef struct ia32_address_mode_t ia32_address_mode_t;
606 struct ia32_address_mode_t {
611 ia32_op_type_t op_type;
615 unsigned commutative : 1;
616 unsigned ins_permuted : 1;
619 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
621 /* construct load address */
622 memset(addr, 0, sizeof(addr[0]));
623 ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
625 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
626 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
627 addr->mem = be_transform_node(mem);
630 static void build_address(ia32_address_mode_t *am, ir_node *node,
631 ia32_create_am_flags_t flags)
633 ia32_address_t *addr = &am->addr;
639 /* floating point immediates */
640 if (is_Const(node)) {
641 ir_entity *entity = ia32_create_float_const_entity(node);
642 addr->base = get_symconst_base();
643 addr->index = noreg_GP;
645 addr->symconst_ent = entity;
646 addr->tls_segment = false;
648 am->ls_mode = get_type_mode(get_entity_type(entity));
649 am->pinned = op_pin_state_floats;
653 load = get_Proj_pred(node);
654 ptr = get_Load_ptr(load);
655 mem = get_Load_mem(load);
656 new_mem = be_transform_node(mem);
657 am->pinned = get_irn_pinned(load);
658 am->ls_mode = get_Load_mode(load);
659 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
662 /* construct load address */
663 ia32_create_address_mode(addr, ptr, flags);
665 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
666 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
670 static void set_address(ir_node *node, const ia32_address_t *addr)
672 set_ia32_am_scale(node, addr->scale);
673 set_ia32_am_sc(node, addr->symconst_ent);
674 set_ia32_am_offs_int(node, addr->offset);
675 set_ia32_am_tls_segment(node, addr->tls_segment);
676 if (addr->symconst_sign)
677 set_ia32_am_sc_sign(node);
679 set_ia32_use_frame(node);
680 set_ia32_frame_ent(node, addr->frame_entity);
684 * Apply attributes of a given address mode to a node.
686 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
688 set_address(node, &am->addr);
690 set_ia32_op_type(node, am->op_type);
691 set_ia32_ls_mode(node, am->ls_mode);
692 if (am->pinned == op_pin_state_pinned) {
693 /* beware: some nodes are already pinned and did not allow to change the state */
694 if (get_irn_pinned(node) != op_pin_state_pinned)
695 set_irn_pinned(node, op_pin_state_pinned);
698 set_ia32_commutative(node);
702 * Check, if a given node is a Down-Conv, ie. a integer Conv
703 * from a mode with a mode with more bits to a mode with lesser bits.
704 * Moreover, we return only true if the node has not more than 1 user.
706 * @param node the node
707 * @return non-zero if node is a Down-Conv
709 static int is_downconv(const ir_node *node)
717 /* we only want to skip the conv when we're the only user
718 * (because this test is used in the context of address-mode selection
719 * and we don't want to use address mode for multiple users) */
720 if (get_irn_n_edges(node) > 1)
723 src_mode = get_irn_mode(get_Conv_op(node));
724 dest_mode = get_irn_mode(node);
726 ia32_mode_needs_gp_reg(src_mode) &&
727 ia32_mode_needs_gp_reg(dest_mode) &&
728 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
731 /** Skip all Down-Conv's on a given node and return the resulting node. */
732 ir_node *ia32_skip_downconv(ir_node *node)
734 while (is_downconv(node))
735 node = get_Conv_op(node);
740 static bool is_sameconv(ir_node *node)
748 /* we only want to skip the conv when we're the only user
749 * (because this test is used in the context of address-mode selection
750 * and we don't want to use address mode for multiple users) */
751 if (get_irn_n_edges(node) > 1)
754 src_mode = get_irn_mode(get_Conv_op(node));
755 dest_mode = get_irn_mode(node);
757 ia32_mode_needs_gp_reg(src_mode) &&
758 ia32_mode_needs_gp_reg(dest_mode) &&
759 get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
762 /** Skip all signedness convs */
763 static ir_node *ia32_skip_sameconv(ir_node *node)
765 while (is_sameconv(node))
766 node = get_Conv_op(node);
771 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
773 ir_mode *mode = get_irn_mode(node);
778 if (mode_is_signed(mode)) {
783 block = get_nodes_block(node);
784 dbgi = get_irn_dbg_info(node);
786 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
790 * matches operands of a node into ia32 addressing/operand modes. This covers
791 * usage of source address mode, immediates, operations with non 32-bit modes,
793 * The resulting data is filled into the @p am struct. block is the block
794 * of the node whose arguments are matched. op1, op2 are the first and second
795 * input that are matched (op1 may be NULL). other_op is another unrelated
796 * input that is not matched! but which is needed sometimes to check if AM
797 * for op1/op2 is legal.
798 * @p flags describes the supported modes of the operation in detail.
800 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
801 ir_node *op1, ir_node *op2, ir_node *other_op,
804 ia32_address_t *addr = &am->addr;
805 ir_mode *mode = get_irn_mode(op2);
806 int mode_bits = get_mode_size_bits(mode);
807 ir_node *new_op1, *new_op2;
809 unsigned commutative;
810 int use_am_and_immediates;
813 memset(am, 0, sizeof(am[0]));
815 commutative = (flags & match_commutative) != 0;
816 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
817 use_am = (flags & match_am) != 0;
818 use_immediate = (flags & match_immediate) != 0;
819 assert(!use_am_and_immediates || use_immediate);
822 assert(!commutative || op1 != NULL);
823 assert(use_am || !(flags & match_8bit_am));
824 assert(use_am || !(flags & match_16bit_am));
826 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
827 (mode_bits == 16 && !(flags & match_16bit_am))) {
831 /* we can simply skip downconvs for mode neutral nodes: the upper bits
832 * can be random for these operations */
833 if (flags & match_mode_neutral) {
834 op2 = ia32_skip_downconv(op2);
836 op1 = ia32_skip_downconv(op1);
839 op2 = ia32_skip_sameconv(op2);
841 op1 = ia32_skip_sameconv(op1);
845 /* match immediates. firm nodes are normalized: constants are always on the
848 if (!(flags & match_try_am) && use_immediate) {
849 new_op2 = ia32_try_create_Immediate(op2, 0);
852 if (new_op2 == NULL &&
853 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
854 build_address(am, op2, ia32_create_am_normal);
855 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
856 if (mode_is_float(mode)) {
857 new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
861 am->op_type = ia32_AddrModeS;
862 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
864 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
866 build_address(am, op1, ia32_create_am_normal);
868 if (mode_is_float(mode)) {
869 noreg = ia32_new_NoReg_vfp(current_ir_graph);
874 if (new_op2 != NULL) {
877 new_op1 = be_transform_node(op2);
879 am->ins_permuted = true;
881 am->op_type = ia32_AddrModeS;
884 am->op_type = ia32_Normal;
886 if (flags & match_try_am) {
892 mode = get_irn_mode(op2);
893 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
894 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
896 new_op2 = create_upconv(op2, NULL);
897 am->ls_mode = mode_Iu;
899 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
901 new_op2 = be_transform_node(op2);
902 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
905 if (addr->base == NULL)
906 addr->base = noreg_GP;
907 if (addr->index == NULL)
908 addr->index = noreg_GP;
909 if (addr->mem == NULL)
912 am->new_op1 = new_op1;
913 am->new_op2 = new_op2;
914 am->commutative = commutative;
918 * "Fixes" a node that uses address mode by turning it into mode_T
919 * and returning a pn_ia32_res Proj.
921 * @param node the node
922 * @param am its address mode
924 * @return a Proj(pn_ia32_res) if a memory address mode is used,
927 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
932 if (am->mem_proj == NULL)
935 /* we have to create a mode_T so the old MemProj can attach to us */
936 mode = get_irn_mode(node);
937 load = get_Proj_pred(am->mem_proj);
939 be_set_transformed_node(load, node);
941 if (mode != mode_T) {
942 set_irn_mode(node, mode_T);
943 return new_rd_Proj(NULL, node, mode, pn_ia32_res);
950 * Construct a standard binary operation, set AM and immediate if required.
952 * @param node The original node for which the binop is created
953 * @param op1 The first operand
954 * @param op2 The second operand
955 * @param func The node constructor function
956 * @return The constructed ia32 node.
958 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
959 construct_binop_func *func, match_flags_t flags)
962 ir_node *block, *new_block, *new_node;
963 ia32_address_mode_t am;
964 ia32_address_t *addr = &am.addr;
966 block = get_nodes_block(node);
967 match_arguments(&am, block, op1, op2, NULL, flags);
969 dbgi = get_irn_dbg_info(node);
970 new_block = be_transform_node(block);
971 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
972 am.new_op1, am.new_op2);
973 set_am_attributes(new_node, &am);
974 /* we can't use source address mode anymore when using immediates */
975 if (!(flags & match_am_and_immediates) &&
976 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
977 set_ia32_am_support(new_node, ia32_am_none);
978 SET_IA32_ORIG_NODE(new_node, node);
980 new_node = fix_mem_proj(new_node, &am);
986 * Generic names for the inputs of an ia32 binary op.
989 n_ia32_l_binop_left, /**< ia32 left input */
990 n_ia32_l_binop_right, /**< ia32 right input */
991 n_ia32_l_binop_eflags /**< ia32 eflags input */
993 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Adc_left, n_Adc_left)
994 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Adc_right, n_Adc_right)
995 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Adc_eflags, n_Adc_eflags)
996 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Sbb_minuend, n_Sbb_minuend)
997 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
998 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Sbb_eflags, n_Sbb_eflags)
1001 * Construct a binary operation which also consumes the eflags.
1003 * @param node The node to transform
1004 * @param func The node constructor function
1005 * @param flags The match flags
1006 * @return The constructor ia32 node
1008 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
1009 match_flags_t flags)
1011 ir_node *src_block = get_nodes_block(node);
1012 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
1013 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
1014 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1016 ir_node *block, *new_node, *new_eflags;
1017 ia32_address_mode_t am;
1018 ia32_address_t *addr = &am.addr;
1020 match_arguments(&am, src_block, op1, op2, eflags, flags);
1022 dbgi = get_irn_dbg_info(node);
1023 block = be_transform_node(src_block);
1024 new_eflags = be_transform_node(eflags);
1025 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
1026 am.new_op1, am.new_op2, new_eflags);
1027 set_am_attributes(new_node, &am);
1028 /* we can't use source address mode anymore when using immediates */
1029 if (!(flags & match_am_and_immediates) &&
1030 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
1031 set_ia32_am_support(new_node, ia32_am_none);
1032 SET_IA32_ORIG_NODE(new_node, node);
1034 new_node = fix_mem_proj(new_node, &am);
1039 static ir_node *get_fpcw(void)
1042 if (initial_fpcw != NULL)
1043 return initial_fpcw;
1045 fpcw = be_abi_get_ignore_irn(current_ir_graph,
1046 &ia32_registers[REG_FPCW]);
1047 initial_fpcw = be_transform_node(fpcw);
1049 return initial_fpcw;
1053 * Construct a standard binary operation, set AM and immediate if required.
1055 * @param op1 The first operand
1056 * @param op2 The second operand
1057 * @param func The node constructor function
1058 * @return The constructed ia32 node.
1060 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1061 construct_binop_float_func *func)
1063 ir_mode *mode = get_irn_mode(node);
1065 ir_node *block, *new_block, *new_node;
1066 ia32_address_mode_t am;
1067 ia32_address_t *addr = &am.addr;
1068 ia32_x87_attr_t *attr;
1069 /* All operations are considered commutative, because there are reverse
1071 match_flags_t flags = match_commutative;
1073 /* happens for div nodes... */
1074 if (mode == mode_T) {
1076 mode = get_Div_resmode(node);
1078 panic("can't determine mode");
1081 /* cannot use address mode with long double on x87 */
1082 if (get_mode_size_bits(mode) <= 64)
1085 block = get_nodes_block(node);
1086 match_arguments(&am, block, op1, op2, NULL, flags);
1088 dbgi = get_irn_dbg_info(node);
1089 new_block = be_transform_node(block);
1090 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1091 am.new_op1, am.new_op2, get_fpcw());
1092 set_am_attributes(new_node, &am);
1094 attr = get_ia32_x87_attr(new_node);
1095 attr->attr.data.ins_permuted = am.ins_permuted;
1097 SET_IA32_ORIG_NODE(new_node, node);
1099 new_node = fix_mem_proj(new_node, &am);
1105 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1107 * @param op1 The first operand
1108 * @param op2 The second operand
1109 * @param func The node constructor function
1110 * @return The constructed ia32 node.
1112 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1113 construct_shift_func *func,
1114 match_flags_t flags)
1117 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1119 assert(! mode_is_float(get_irn_mode(node)));
1120 assert(flags & match_immediate);
1121 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1123 if (flags & match_mode_neutral) {
1124 op1 = ia32_skip_downconv(op1);
1125 new_op1 = be_transform_node(op1);
1126 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1127 new_op1 = create_upconv(op1, node);
1129 new_op1 = be_transform_node(op1);
1132 /* the shift amount can be any mode that is bigger than 5 bits, since all
1133 * other bits are ignored anyway */
1134 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1135 ir_node *const op = get_Conv_op(op2);
1136 if (mode_is_float(get_irn_mode(op)))
1139 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1141 new_op2 = create_immediate_or_transform(op2, 0);
1143 dbgi = get_irn_dbg_info(node);
1144 block = get_nodes_block(node);
1145 new_block = be_transform_node(block);
1146 new_node = func(dbgi, new_block, new_op1, new_op2);
1147 SET_IA32_ORIG_NODE(new_node, node);
1149 /* lowered shift instruction may have a dependency operand, handle it here */
1150 if (get_irn_arity(node) == 3) {
1151 /* we have a dependency */
1152 ir_node* dep = get_irn_n(node, 2);
1153 if (get_irn_n_edges(dep) > 1) {
1154 /* ... which has at least one user other than 'node' */
1155 ir_node *new_dep = be_transform_node(dep);
1156 add_irn_dep(new_node, new_dep);
1165 * Construct a standard unary operation, set AM and immediate if required.
1167 * @param op The operand
1168 * @param func The node constructor function
1169 * @return The constructed ia32 node.
1171 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1172 match_flags_t flags)
1175 ir_node *block, *new_block, *new_op, *new_node;
1177 assert(flags == 0 || flags == match_mode_neutral);
1178 if (flags & match_mode_neutral) {
1179 op = ia32_skip_downconv(op);
1182 new_op = be_transform_node(op);
1183 dbgi = get_irn_dbg_info(node);
1184 block = get_nodes_block(node);
1185 new_block = be_transform_node(block);
1186 new_node = func(dbgi, new_block, new_op);
1188 SET_IA32_ORIG_NODE(new_node, node);
1193 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1194 ia32_address_t *addr)
1196 ir_node *base, *index, *res;
1202 base = be_transform_node(base);
1205 index = addr->index;
1206 if (index == NULL) {
1209 index = be_transform_node(index);
1212 /* segment overrides are ineffective for Leas :-( so we have to patch
1214 if (addr->tls_segment) {
1215 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
1216 assert(addr->symconst_ent != NULL);
1217 if (base == noreg_GP)
1220 base = new_bd_ia32_Lea(dbgi, block, tls_base, base);
1221 addr->tls_segment = false;
1224 res = new_bd_ia32_Lea(dbgi, block, base, index);
1225 set_address(res, addr);
1231 * Returns non-zero if a given address mode has a symbolic or
1232 * numerical offset != 0.
1234 static int am_has_immediates(const ia32_address_t *addr)
1236 return addr->offset != 0 || addr->symconst_ent != NULL
1237 || addr->frame_entity || addr->use_frame;
1241 * Creates an ia32 Add.
1243 * @return the created ia32 Add node
1245 static ir_node *gen_Add(ir_node *node)
1247 ir_mode *mode = get_irn_mode(node);
1248 ir_node *op1 = get_Add_left(node);
1249 ir_node *op2 = get_Add_right(node);
1251 ir_node *block, *new_block, *new_node, *add_immediate_op;
1252 ia32_address_t addr;
1253 ia32_address_mode_t am;
1255 if (mode_is_float(mode)) {
1256 if (ia32_cg_config.use_sse2)
1257 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1258 match_commutative | match_am);
1260 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1263 ia32_mark_non_am(node);
1265 op2 = ia32_skip_downconv(op2);
1266 op1 = ia32_skip_downconv(op1);
1270 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1271 * 1. Add with immediate -> Lea
1272 * 2. Add with possible source address mode -> Add
1273 * 3. Otherwise -> Lea
1275 memset(&addr, 0, sizeof(addr));
1276 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1277 add_immediate_op = NULL;
1279 dbgi = get_irn_dbg_info(node);
1280 block = get_nodes_block(node);
1281 new_block = be_transform_node(block);
1284 if (addr.base == NULL && addr.index == NULL) {
1285 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1286 addr.symconst_sign, 0, addr.offset);
1287 SET_IA32_ORIG_NODE(new_node, node);
1290 /* add with immediate? */
1291 if (addr.index == NULL) {
1292 add_immediate_op = addr.base;
1293 } else if (addr.base == NULL && addr.scale == 0) {
1294 add_immediate_op = addr.index;
1297 if (add_immediate_op != NULL) {
1298 if (!am_has_immediates(&addr)) {
1299 #ifdef DEBUG_libfirm
1300 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1303 return be_transform_node(add_immediate_op);
1306 new_node = create_lea_from_address(dbgi, new_block, &addr);
1307 SET_IA32_ORIG_NODE(new_node, node);
1311 /* test if we can use source address mode */
1312 match_arguments(&am, block, op1, op2, NULL, match_commutative
1313 | match_mode_neutral | match_am | match_immediate | match_try_am);
1315 /* construct an Add with source address mode */
1316 if (am.op_type == ia32_AddrModeS) {
1317 ia32_address_t *am_addr = &am.addr;
1318 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1319 am_addr->index, am_addr->mem, am.new_op1,
1321 set_am_attributes(new_node, &am);
1322 SET_IA32_ORIG_NODE(new_node, node);
1324 new_node = fix_mem_proj(new_node, &am);
1329 /* otherwise construct a lea */
1330 new_node = create_lea_from_address(dbgi, new_block, &addr);
1331 SET_IA32_ORIG_NODE(new_node, node);
1336 * Creates an ia32 Mul.
1338 * @return the created ia32 Mul node
1340 static ir_node *gen_Mul(ir_node *node)
1342 ir_node *op1 = get_Mul_left(node);
1343 ir_node *op2 = get_Mul_right(node);
1344 ir_mode *mode = get_irn_mode(node);
1346 if (mode_is_float(mode)) {
1347 if (ia32_cg_config.use_sse2)
1348 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1349 match_commutative | match_am);
1351 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1353 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1354 match_commutative | match_am | match_mode_neutral |
1355 match_immediate | match_am_and_immediates);
1359 * Creates an ia32 Mulh.
1360 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1361 * this result while Mul returns the lower 32 bit.
1363 * @return the created ia32 Mulh node
1365 static ir_node *gen_Mulh(ir_node *node)
1367 dbg_info *dbgi = get_irn_dbg_info(node);
1368 ir_node *op1 = get_Mulh_left(node);
1369 ir_node *op2 = get_Mulh_right(node);
1370 ir_mode *mode = get_irn_mode(node);
1372 ir_node *proj_res_high;
1374 if (get_mode_size_bits(mode) != 32) {
1375 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1378 if (mode_is_signed(mode)) {
1379 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1380 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1382 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1383 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1385 return proj_res_high;
1389 * Creates an ia32 And.
1391 * @return The created ia32 And node
1393 static ir_node *gen_And(ir_node *node)
1395 ir_node *op1 = get_And_left(node);
1396 ir_node *op2 = get_And_right(node);
1397 assert(! mode_is_float(get_irn_mode(node)));
1399 /* is it a zero extension? */
1400 if (is_Const(op2)) {
1401 ir_tarval *tv = get_Const_tarval(op2);
1402 long v = get_tarval_long(tv);
1404 if (v == 0xFF || v == 0xFFFF) {
1405 dbg_info *dbgi = get_irn_dbg_info(node);
1406 ir_node *block = get_nodes_block(node);
1413 assert(v == 0xFFFF);
1416 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1421 return gen_binop(node, op1, op2, new_bd_ia32_And,
1422 match_commutative | match_mode_neutral | match_am | match_immediate);
1428 * Creates an ia32 Or.
1430 * @return The created ia32 Or node
1432 static ir_node *gen_Or(ir_node *node)
1434 ir_node *op1 = get_Or_left(node);
1435 ir_node *op2 = get_Or_right(node);
1437 assert (! mode_is_float(get_irn_mode(node)));
1438 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1439 | match_mode_neutral | match_am | match_immediate);
1445 * Creates an ia32 Eor.
1447 * @return The created ia32 Eor node
1449 static ir_node *gen_Eor(ir_node *node)
1451 ir_node *op1 = get_Eor_left(node);
1452 ir_node *op2 = get_Eor_right(node);
1454 assert(! mode_is_float(get_irn_mode(node)));
1455 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1456 | match_mode_neutral | match_am | match_immediate);
1461 * Creates an ia32 Sub.
1463 * @return The created ia32 Sub node
1465 static ir_node *gen_Sub(ir_node *node)
1467 ir_node *op1 = get_Sub_left(node);
1468 ir_node *op2 = get_Sub_right(node);
1469 ir_mode *mode = get_irn_mode(node);
1471 if (mode_is_float(mode)) {
1472 if (ia32_cg_config.use_sse2)
1473 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1475 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1478 if (is_Const(op2)) {
1479 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1483 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1484 | match_am | match_immediate);
1487 static ir_node *transform_AM_mem(ir_node *const block,
1488 ir_node *const src_val,
1489 ir_node *const src_mem,
1490 ir_node *const am_mem)
1492 if (is_NoMem(am_mem)) {
1493 return be_transform_node(src_mem);
1494 } else if (is_Proj(src_val) &&
1496 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1497 /* avoid memory loop */
1499 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1500 ir_node *const ptr_pred = get_Proj_pred(src_val);
1501 int const arity = get_Sync_n_preds(src_mem);
1506 NEW_ARR_A(ir_node*, ins, arity + 1);
1508 /* NOTE: This sometimes produces dead-code because the old sync in
1509 * src_mem might not be used anymore, we should detect this case
1510 * and kill the sync... */
1511 for (i = arity - 1; i >= 0; --i) {
1512 ir_node *const pred = get_Sync_pred(src_mem, i);
1514 /* avoid memory loop */
1515 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1518 ins[n++] = be_transform_node(pred);
1521 if (n==1 && ins[0] == am_mem) {
1523 /* creating a new Sync and relying on CSE may fail,
1524 * if am_mem is a ProjM, which does not yet verify. */
1528 return new_r_Sync(block, n, ins);
1532 ins[0] = be_transform_node(src_mem);
1534 return new_r_Sync(block, 2, ins);
1539 * Create a 32bit to 64bit signed extension.
1541 * @param dbgi debug info
1542 * @param block the block where node nodes should be placed
1543 * @param val the value to extend
1544 * @param orig the original node
1546 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1547 ir_node *val, const ir_node *orig)
1552 if (ia32_cg_config.use_short_sex_eax) {
1553 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1554 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1556 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1557 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1559 SET_IA32_ORIG_NODE(res, orig);
1564 * Generates an ia32 Div with additional infrastructure for the
1565 * register allocator if needed.
1567 static ir_node *create_Div(ir_node *node)
1569 dbg_info *dbgi = get_irn_dbg_info(node);
1570 ir_node *block = get_nodes_block(node);
1571 ir_node *new_block = be_transform_node(block);
1578 ir_node *sign_extension;
1579 ia32_address_mode_t am;
1580 ia32_address_t *addr = &am.addr;
1582 /* the upper bits have random contents for smaller modes */
1583 switch (get_irn_opcode(node)) {
1585 op1 = get_Div_left(node);
1586 op2 = get_Div_right(node);
1587 mem = get_Div_mem(node);
1588 mode = get_Div_resmode(node);
1591 op1 = get_Mod_left(node);
1592 op2 = get_Mod_right(node);
1593 mem = get_Mod_mem(node);
1594 mode = get_Mod_resmode(node);
1597 panic("invalid divmod node %+F", node);
1600 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1602 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1603 is the memory of the consumed address. We can have only the second op as address
1604 in Div nodes, so check only op2. */
1605 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1607 if (mode_is_signed(mode)) {
1608 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1609 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1610 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1612 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1614 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1615 addr->index, new_mem, am.new_op2,
1616 am.new_op1, sign_extension);
1619 set_irn_pinned(new_node, get_irn_pinned(node));
1621 set_am_attributes(new_node, &am);
1622 SET_IA32_ORIG_NODE(new_node, node);
1624 new_node = fix_mem_proj(new_node, &am);
1630 * Generates an ia32 Mod.
1632 static ir_node *gen_Mod(ir_node *node)
1634 return create_Div(node);
1638 * Generates an ia32 Div.
1640 static ir_node *gen_Div(ir_node *node)
1642 ir_mode *mode = get_Div_resmode(node);
1643 if (mode_is_float(mode)) {
1644 ir_node *op1 = get_Div_left(node);
1645 ir_node *op2 = get_Div_right(node);
1647 if (ia32_cg_config.use_sse2) {
1648 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1650 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1654 return create_Div(node);
1658 * Creates an ia32 Shl.
1660 * @return The created ia32 Shl node
1662 static ir_node *gen_Shl(ir_node *node)
1664 ir_node *left = get_Shl_left(node);
1665 ir_node *right = get_Shl_right(node);
1667 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1668 match_mode_neutral | match_immediate);
1672 * Creates an ia32 Shr.
1674 * @return The created ia32 Shr node
1676 static ir_node *gen_Shr(ir_node *node)
1678 ir_node *left = get_Shr_left(node);
1679 ir_node *right = get_Shr_right(node);
1681 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1687 * Creates an ia32 Sar.
1689 * @return The created ia32 Shrs node
1691 static ir_node *gen_Shrs(ir_node *node)
1693 ir_node *left = get_Shrs_left(node);
1694 ir_node *right = get_Shrs_right(node);
1696 if (is_Const(right)) {
1697 ir_tarval *tv = get_Const_tarval(right);
1698 long val = get_tarval_long(tv);
1700 /* this is a sign extension */
1701 dbg_info *dbgi = get_irn_dbg_info(node);
1702 ir_node *block = be_transform_node(get_nodes_block(node));
1703 ir_node *new_op = be_transform_node(left);
1705 return create_sex_32_64(dbgi, block, new_op, node);
1709 /* 8 or 16 bit sign extension? */
1710 if (is_Const(right) && is_Shl(left)) {
1711 ir_node *shl_left = get_Shl_left(left);
1712 ir_node *shl_right = get_Shl_right(left);
1713 if (is_Const(shl_right)) {
1714 ir_tarval *tv1 = get_Const_tarval(right);
1715 ir_tarval *tv2 = get_Const_tarval(shl_right);
1716 if (tv1 == tv2 && tarval_is_long(tv1)) {
1717 long val = get_tarval_long(tv1);
1718 if (val == 16 || val == 24) {
1719 dbg_info *dbgi = get_irn_dbg_info(node);
1720 ir_node *block = get_nodes_block(node);
1730 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1739 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1745 * Creates an ia32 Rol.
1747 * @param op1 The first operator
1748 * @param op2 The second operator
1749 * @return The created ia32 RotL node
1751 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1753 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1759 * Creates an ia32 Ror.
1760 * NOTE: There is no RotR with immediate because this would always be a RotL
1761 * "imm-mode_size_bits" which can be pre-calculated.
1763 * @param op1 The first operator
1764 * @param op2 The second operator
1765 * @return The created ia32 RotR node
1767 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1769 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1775 * Creates an ia32 RotR or RotL (depending on the found pattern).
1777 * @return The created ia32 RotL or RotR node
1779 static ir_node *gen_Rotl(ir_node *node)
1781 ir_node *op1 = get_Rotl_left(node);
1782 ir_node *op2 = get_Rotl_right(node);
1784 if (is_Minus(op2)) {
1785 return gen_Ror(node, op1, get_Minus_op(op2));
1788 return gen_Rol(node, op1, op2);
1794 * Transforms a Minus node.
1796 * @return The created ia32 Minus node
1798 static ir_node *gen_Minus(ir_node *node)
1800 ir_node *op = get_Minus_op(node);
1801 ir_node *block = be_transform_node(get_nodes_block(node));
1802 dbg_info *dbgi = get_irn_dbg_info(node);
1803 ir_mode *mode = get_irn_mode(node);
1808 if (mode_is_float(mode)) {
1809 ir_node *new_op = be_transform_node(op);
1810 if (ia32_cg_config.use_sse2) {
1811 /* TODO: non-optimal... if we have many xXors, then we should
1812 * rather create a load for the const and use that instead of
1813 * several AM nodes... */
1814 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1816 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1817 noreg_GP, nomem, new_op, noreg_xmm);
1819 size = get_mode_size_bits(mode);
1820 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1822 set_ia32_am_sc(new_node, ent);
1823 set_ia32_op_type(new_node, ia32_AddrModeS);
1824 set_ia32_ls_mode(new_node, mode);
1826 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1829 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1832 SET_IA32_ORIG_NODE(new_node, node);
1838 * Transforms a Not node.
1840 * @return The created ia32 Not node
1842 static ir_node *gen_Not(ir_node *node)
1844 ir_node *op = get_Not_op(node);
1846 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1847 assert (! mode_is_float(get_irn_mode(node)));
1849 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1852 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1853 bool negate, ir_node *node)
1855 ir_node *new_block = be_transform_node(block);
1856 ir_mode *mode = get_irn_mode(op);
1862 if (mode_is_float(mode)) {
1863 new_op = be_transform_node(op);
1865 if (ia32_cg_config.use_sse2) {
1866 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1867 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1868 noreg_GP, nomem, new_op, noreg_fp);
1870 size = get_mode_size_bits(mode);
1871 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1873 set_ia32_am_sc(new_node, ent);
1875 SET_IA32_ORIG_NODE(new_node, node);
1877 set_ia32_op_type(new_node, ia32_AddrModeS);
1878 set_ia32_ls_mode(new_node, mode);
1880 /* TODO, implement -Abs case */
1883 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1884 SET_IA32_ORIG_NODE(new_node, node);
1886 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1887 SET_IA32_ORIG_NODE(new_node, node);
1892 ir_node *sign_extension;
1894 if (get_mode_size_bits(mode) == 32) {
1895 new_op = be_transform_node(op);
1897 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1900 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1902 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1903 nomem, new_op, sign_extension);
1904 SET_IA32_ORIG_NODE(xorn, node);
1907 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1908 nomem, sign_extension, xorn);
1910 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1911 nomem, xorn, sign_extension);
1913 SET_IA32_ORIG_NODE(new_node, node);
1920 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1922 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1924 dbg_info *dbgi = get_irn_dbg_info(cmp);
1925 ir_node *block = get_nodes_block(cmp);
1926 ir_node *new_block = be_transform_node(block);
1927 ir_node *op1 = be_transform_node(x);
1928 ir_node *op2 = be_transform_node(n);
1930 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1933 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
1936 if (mode_is_float(mode)) {
1938 case ir_relation_equal: return ia32_cc_float_equal;
1939 case ir_relation_less: return ia32_cc_float_below;
1940 case ir_relation_less_equal: return ia32_cc_float_below_equal;
1941 case ir_relation_greater: return ia32_cc_float_above;
1942 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
1943 case ir_relation_less_greater: return ia32_cc_not_equal;
1944 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
1945 case ir_relation_unordered: return ia32_cc_parity;
1946 case ir_relation_unordered_equal: return ia32_cc_equal;
1947 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
1948 case ir_relation_unordered_less_equal:
1949 return ia32_cc_float_unordered_below_equal;
1950 case ir_relation_unordered_greater:
1951 return ia32_cc_float_unordered_above;
1952 case ir_relation_unordered_greater_equal:
1953 return ia32_cc_float_unordered_above_equal;
1954 case ir_relation_unordered_less_greater:
1955 return ia32_cc_float_not_equal;
1956 case ir_relation_false:
1957 case ir_relation_true:
1958 /* should we introduce a jump always/jump never? */
1961 panic("Unexpected float pnc");
1962 } else if (mode_is_signed(mode)) {
1964 case ir_relation_unordered_equal:
1965 case ir_relation_equal: return ia32_cc_equal;
1966 case ir_relation_unordered_less:
1967 case ir_relation_less: return ia32_cc_less;
1968 case ir_relation_unordered_less_equal:
1969 case ir_relation_less_equal: return ia32_cc_less_equal;
1970 case ir_relation_unordered_greater:
1971 case ir_relation_greater: return ia32_cc_greater;
1972 case ir_relation_unordered_greater_equal:
1973 case ir_relation_greater_equal: return ia32_cc_greater_equal;
1974 case ir_relation_unordered_less_greater:
1975 case ir_relation_less_greater: return ia32_cc_not_equal;
1976 case ir_relation_less_equal_greater:
1977 case ir_relation_unordered:
1978 case ir_relation_false:
1979 case ir_relation_true:
1980 /* introduce jump always/jump never? */
1983 panic("Unexpected pnc");
1986 case ir_relation_unordered_equal:
1987 case ir_relation_equal: return ia32_cc_equal;
1988 case ir_relation_unordered_less:
1989 case ir_relation_less: return ia32_cc_below;
1990 case ir_relation_unordered_less_equal:
1991 case ir_relation_less_equal: return ia32_cc_below_equal;
1992 case ir_relation_unordered_greater:
1993 case ir_relation_greater: return ia32_cc_above;
1994 case ir_relation_unordered_greater_equal:
1995 case ir_relation_greater_equal: return ia32_cc_above_equal;
1996 case ir_relation_unordered_less_greater:
1997 case ir_relation_less_greater: return ia32_cc_not_equal;
1998 case ir_relation_less_equal_greater:
1999 case ir_relation_unordered:
2000 case ir_relation_false:
2001 case ir_relation_true:
2002 /* introduce jump always/jump never? */
2005 panic("Unexpected pnc");
2009 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
2011 /* a mode_b value, we have to compare it against 0 */
2012 dbg_info *dbgi = get_irn_dbg_info(node);
2013 ir_node *new_block = be_transform_node(get_nodes_block(node));
2014 ir_node *new_op = be_transform_node(node);
2015 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2016 *cc_out = ia32_cc_not_equal;
2020 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2022 /* must have a Cmp as input */
2023 ir_relation relation = get_Cmp_relation(cmp);
2024 ir_relation possible;
2025 ir_node *l = get_Cmp_left(cmp);
2026 ir_node *r = get_Cmp_right(cmp);
2027 ir_mode *mode = get_irn_mode(l);
2030 /* check for bit-test */
2031 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2032 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2033 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2035 ir_node *la = get_And_left(l);
2036 ir_node *ra = get_And_right(l);
2043 ir_node *c = get_Shl_left(la);
2044 if (is_Const_1(c) && is_Const_0(r)) {
2045 /* (1 << n) & ra) */
2046 ir_node *n = get_Shl_right(la);
2047 flags = gen_bt(cmp, ra, n);
2048 /* the bit is copied into the CF flag */
2049 if (relation & ir_relation_equal)
2050 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2052 *cc_out = ia32_cc_below; /* test for CF=1 */
2058 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2059 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2060 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2061 * a predecessor node). So add the < bit */
2062 possible = ir_get_possible_cmp_relations(l, r);
2063 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2064 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2065 relation |= ir_relation_less_greater;
2067 /* just do a normal transformation of the Cmp */
2068 *cc_out = relation_to_condition_code(relation, mode);
2069 flags = be_transform_node(cmp);
2074 * Transform a node returning a "flag" result.
2076 * @param node the node to transform
2077 * @param cc_out the compare mode to use
2079 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2082 return get_flags_node_cmp(node, cc_out);
2083 assert(get_irn_mode(node) == mode_b);
2084 return get_flags_mode_b(node, cc_out);
2088 * Transforms a Load.
2090 * @return the created ia32 Load node
2092 static ir_node *gen_Load(ir_node *node)
2094 ir_node *old_block = get_nodes_block(node);
2095 ir_node *block = be_transform_node(old_block);
2096 ir_node *ptr = get_Load_ptr(node);
2097 ir_node *mem = get_Load_mem(node);
2098 ir_node *new_mem = be_transform_node(mem);
2099 dbg_info *dbgi = get_irn_dbg_info(node);
2100 ir_mode *mode = get_Load_mode(node);
2104 ia32_address_t addr;
2106 /* construct load address */
2107 memset(&addr, 0, sizeof(addr));
2108 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2115 base = be_transform_node(base);
2118 if (index == NULL) {
2121 index = be_transform_node(index);
2124 if (mode_is_float(mode)) {
2125 if (ia32_cg_config.use_sse2) {
2126 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2129 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2133 assert(mode != mode_b);
2135 /* create a conv node with address mode for smaller modes */
2136 if (get_mode_size_bits(mode) < 32) {
2137 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2138 new_mem, noreg_GP, mode);
2140 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2144 set_irn_pinned(new_node, get_irn_pinned(node));
2145 set_ia32_op_type(new_node, ia32_AddrModeS);
2146 set_ia32_ls_mode(new_node, mode);
2147 set_address(new_node, &addr);
2149 if (get_irn_pinned(node) == op_pin_state_floats) {
2150 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2151 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2152 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2153 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2156 SET_IA32_ORIG_NODE(new_node, node);
2161 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2162 ir_node *ptr, ir_node *other)
2169 /* we only use address mode if we're the only user of the load */
2170 if (get_irn_n_edges(node) > 1)
2173 load = get_Proj_pred(node);
2176 if (get_nodes_block(load) != block)
2179 /* store should have the same pointer as the load */
2180 if (get_Load_ptr(load) != ptr)
2183 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2184 if (other != NULL &&
2185 get_nodes_block(other) == block &&
2186 heights_reachable_in_block(ia32_heights, other, load)) {
2190 if (ia32_prevents_AM(block, load, mem))
2192 /* Store should be attached to the load via mem */
2193 assert(heights_reachable_in_block(ia32_heights, mem, load));
2198 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2199 ir_node *mem, ir_node *ptr, ir_mode *mode,
2200 construct_binop_dest_func *func,
2201 construct_binop_dest_func *func8bit,
2202 match_flags_t flags)
2204 ir_node *src_block = get_nodes_block(node);
2212 ia32_address_mode_t am;
2213 ia32_address_t *addr = &am.addr;
2214 memset(&am, 0, sizeof(am));
2216 assert(flags & match_immediate); /* there is no destam node without... */
2217 commutative = (flags & match_commutative) != 0;
2219 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2220 build_address(&am, op1, ia32_create_am_double_use);
2221 new_op = create_immediate_or_transform(op2, 0);
2222 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2223 build_address(&am, op2, ia32_create_am_double_use);
2224 new_op = create_immediate_or_transform(op1, 0);
2229 if (addr->base == NULL)
2230 addr->base = noreg_GP;
2231 if (addr->index == NULL)
2232 addr->index = noreg_GP;
2233 if (addr->mem == NULL)
2236 dbgi = get_irn_dbg_info(node);
2237 block = be_transform_node(src_block);
2238 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2240 if (get_mode_size_bits(mode) == 8) {
2241 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2243 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2245 set_address(new_node, addr);
2246 set_ia32_op_type(new_node, ia32_AddrModeD);
2247 set_ia32_ls_mode(new_node, mode);
2248 SET_IA32_ORIG_NODE(new_node, node);
2250 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2251 mem_proj = be_transform_node(am.mem_proj);
2252 be_set_transformed_node(am.mem_proj, new_node);
2253 be_set_transformed_node(mem_proj, new_node);
2258 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2259 ir_node *ptr, ir_mode *mode,
2260 construct_unop_dest_func *func)
2262 ir_node *src_block = get_nodes_block(node);
2268 ia32_address_mode_t am;
2269 ia32_address_t *addr = &am.addr;
2271 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2274 memset(&am, 0, sizeof(am));
2275 build_address(&am, op, ia32_create_am_double_use);
2277 dbgi = get_irn_dbg_info(node);
2278 block = be_transform_node(src_block);
2279 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2280 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2281 set_address(new_node, addr);
2282 set_ia32_op_type(new_node, ia32_AddrModeD);
2283 set_ia32_ls_mode(new_node, mode);
2284 SET_IA32_ORIG_NODE(new_node, node);
2286 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2287 mem_proj = be_transform_node(am.mem_proj);
2288 be_set_transformed_node(am.mem_proj, new_node);
2289 be_set_transformed_node(mem_proj, new_node);
2294 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2296 ir_mode *mode = get_irn_mode(node);
2297 ir_node *mux_true = get_Mux_true(node);
2298 ir_node *mux_false = get_Mux_false(node);
2306 ia32_condition_code_t cc;
2307 ia32_address_t addr;
2309 if (get_mode_size_bits(mode) != 8)
2312 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2314 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2320 cond = get_Mux_sel(node);
2321 flags = get_flags_node(cond, &cc);
2322 /* we can't handle the float special cases with SetM */
2323 if (cc & ia32_cc_additional_float_cases)
2326 cc = ia32_negate_condition_code(cc);
2328 build_address_ptr(&addr, ptr, mem);
2330 dbgi = get_irn_dbg_info(node);
2331 block = get_nodes_block(node);
2332 new_block = be_transform_node(block);
2333 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2334 addr.index, addr.mem, flags, cc);
2335 set_address(new_node, &addr);
2336 set_ia32_op_type(new_node, ia32_AddrModeD);
2337 set_ia32_ls_mode(new_node, mode);
2338 SET_IA32_ORIG_NODE(new_node, node);
2343 static ir_node *try_create_dest_am(ir_node *node)
2345 ir_node *val = get_Store_value(node);
2346 ir_node *mem = get_Store_mem(node);
2347 ir_node *ptr = get_Store_ptr(node);
2348 ir_mode *mode = get_irn_mode(val);
2349 unsigned bits = get_mode_size_bits(mode);
2354 /* handle only GP modes for now... */
2355 if (!ia32_mode_needs_gp_reg(mode))
2359 /* store must be the only user of the val node */
2360 if (get_irn_n_edges(val) > 1)
2362 /* skip pointless convs */
2364 ir_node *conv_op = get_Conv_op(val);
2365 ir_mode *pred_mode = get_irn_mode(conv_op);
2366 if (!ia32_mode_needs_gp_reg(pred_mode))
2368 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2376 /* value must be in the same block */
2377 if (get_nodes_block(node) != get_nodes_block(val))
2380 switch (get_irn_opcode(val)) {
2382 op1 = get_Add_left(val);
2383 op2 = get_Add_right(val);
2384 if (ia32_cg_config.use_incdec) {
2385 if (is_Const_1(op2)) {
2386 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2388 } else if (is_Const_Minus_1(op2)) {
2389 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2393 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2394 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2395 match_commutative | match_immediate);
2398 op1 = get_Sub_left(val);
2399 op2 = get_Sub_right(val);
2400 if (is_Const(op2)) {
2401 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2403 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2404 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2408 op1 = get_And_left(val);
2409 op2 = get_And_right(val);
2410 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2411 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2412 match_commutative | match_immediate);
2415 op1 = get_Or_left(val);
2416 op2 = get_Or_right(val);
2417 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2418 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2419 match_commutative | match_immediate);
2422 op1 = get_Eor_left(val);
2423 op2 = get_Eor_right(val);
2424 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2425 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2426 match_commutative | match_immediate);
2429 op1 = get_Shl_left(val);
2430 op2 = get_Shl_right(val);
2431 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2432 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2436 op1 = get_Shr_left(val);
2437 op2 = get_Shr_right(val);
2438 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2439 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2443 op1 = get_Shrs_left(val);
2444 op2 = get_Shrs_right(val);
2445 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2446 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2450 op1 = get_Rotl_left(val);
2451 op2 = get_Rotl_right(val);
2452 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2453 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2456 /* TODO: match ROR patterns... */
2458 new_node = try_create_SetMem(val, ptr, mem);
2462 op1 = get_Minus_op(val);
2463 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2466 /* should be lowered already */
2467 assert(mode != mode_b);
2468 op1 = get_Not_op(val);
2469 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2475 if (new_node != NULL) {
2476 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2477 get_irn_pinned(node) == op_pin_state_pinned) {
2478 set_irn_pinned(new_node, op_pin_state_pinned);
2485 static bool possible_int_mode_for_fp(ir_mode *mode)
2489 if (!mode_is_signed(mode))
2491 size = get_mode_size_bits(mode);
2492 if (size != 16 && size != 32)
2497 static int is_float_to_int_conv(const ir_node *node)
2499 ir_mode *mode = get_irn_mode(node);
2503 if (!possible_int_mode_for_fp(mode))
2508 conv_op = get_Conv_op(node);
2509 conv_mode = get_irn_mode(conv_op);
2511 if (!mode_is_float(conv_mode))
2518 * Transform a Store(floatConst) into a sequence of
2521 * @return the created ia32 Store node
2523 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2525 ir_mode *mode = get_irn_mode(cns);
2526 unsigned size = get_mode_size_bytes(mode);
2527 ir_tarval *tv = get_Const_tarval(cns);
2528 ir_node *block = get_nodes_block(node);
2529 ir_node *new_block = be_transform_node(block);
2530 ir_node *ptr = get_Store_ptr(node);
2531 ir_node *mem = get_Store_mem(node);
2532 dbg_info *dbgi = get_irn_dbg_info(node);
2536 ia32_address_t addr;
2538 assert(size % 4 == 0);
2541 build_address_ptr(&addr, ptr, mem);
2545 get_tarval_sub_bits(tv, ofs) |
2546 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2547 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2548 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2549 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2551 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2552 addr.index, addr.mem, imm);
2554 set_irn_pinned(new_node, get_irn_pinned(node));
2555 set_ia32_op_type(new_node, ia32_AddrModeD);
2556 set_ia32_ls_mode(new_node, mode_Iu);
2557 set_address(new_node, &addr);
2558 SET_IA32_ORIG_NODE(new_node, node);
2561 ins[i++] = new_node;
2566 } while (size != 0);
2569 return new_rd_Sync(dbgi, new_block, i, ins);
2576 * Generate a vfist or vfisttp instruction.
2578 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2579 ir_node *mem, ir_node *val, ir_node **fist)
2583 if (ia32_cg_config.use_fisttp) {
2584 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2585 if other users exists */
2586 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2587 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2588 be_new_Keep(block, 1, &value);
2590 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2593 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2596 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2602 * Transforms a general (no special case) Store.
2604 * @return the created ia32 Store node
2606 static ir_node *gen_general_Store(ir_node *node)
2608 ir_node *val = get_Store_value(node);
2609 ir_mode *mode = get_irn_mode(val);
2610 ir_node *block = get_nodes_block(node);
2611 ir_node *new_block = be_transform_node(block);
2612 ir_node *ptr = get_Store_ptr(node);
2613 ir_node *mem = get_Store_mem(node);
2614 dbg_info *dbgi = get_irn_dbg_info(node);
2615 ir_node *new_val, *new_node, *store;
2616 ia32_address_t addr;
2618 /* check for destination address mode */
2619 new_node = try_create_dest_am(node);
2620 if (new_node != NULL)
2623 /* construct store address */
2624 memset(&addr, 0, sizeof(addr));
2625 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2627 if (addr.base == NULL) {
2628 addr.base = noreg_GP;
2630 addr.base = be_transform_node(addr.base);
2633 if (addr.index == NULL) {
2634 addr.index = noreg_GP;
2636 addr.index = be_transform_node(addr.index);
2638 addr.mem = be_transform_node(mem);
2640 if (mode_is_float(mode)) {
2641 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2643 while (is_Conv(val) && mode == get_irn_mode(val)) {
2644 ir_node *op = get_Conv_op(val);
2645 if (!mode_is_float(get_irn_mode(op)))
2649 new_val = be_transform_node(val);
2650 if (ia32_cg_config.use_sse2) {
2651 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2652 addr.index, addr.mem, new_val);
2654 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2655 addr.index, addr.mem, new_val, mode);
2658 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2659 val = get_Conv_op(val);
2661 /* TODO: is this optimisation still necessary at all (middleend)? */
2662 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2663 while (is_Conv(val)) {
2664 ir_node *op = get_Conv_op(val);
2665 if (!mode_is_float(get_irn_mode(op)))
2667 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2671 new_val = be_transform_node(val);
2672 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2674 new_val = create_immediate_or_transform(val, 0);
2675 assert(mode != mode_b);
2677 if (get_mode_size_bits(mode) == 8) {
2678 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2679 addr.index, addr.mem, new_val);
2681 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2682 addr.index, addr.mem, new_val);
2687 set_irn_pinned(store, get_irn_pinned(node));
2688 set_ia32_op_type(store, ia32_AddrModeD);
2689 set_ia32_ls_mode(store, mode);
2691 set_address(store, &addr);
2692 SET_IA32_ORIG_NODE(store, node);
2698 * Transforms a Store.
2700 * @return the created ia32 Store node
2702 static ir_node *gen_Store(ir_node *node)
2704 ir_node *val = get_Store_value(node);
2705 ir_mode *mode = get_irn_mode(val);
2707 if (mode_is_float(mode) && is_Const(val)) {
2708 /* We can transform every floating const store
2709 into a sequence of integer stores.
2710 If the constant is already in a register,
2711 it would be better to use it, but we don't
2712 have this information here. */
2713 return gen_float_const_Store(node, val);
2715 return gen_general_Store(node);
2719 * Transforms a Switch.
2721 * @return the created ia32 SwitchJmp node
2723 static ir_node *create_Switch(ir_node *node)
2725 dbg_info *dbgi = get_irn_dbg_info(node);
2726 ir_node *block = be_transform_node(get_nodes_block(node));
2727 ir_node *sel = get_Cond_selector(node);
2728 ir_node *new_sel = be_transform_node(sel);
2729 long switch_min = LONG_MAX;
2730 long switch_max = LONG_MIN;
2731 long default_pn = get_Cond_default_proj(node);
2733 const ir_edge_t *edge;
2735 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2737 /* determine the smallest switch case value */
2738 foreach_out_edge(node, edge) {
2739 ir_node *proj = get_edge_src_irn(edge);
2740 long pn = get_Proj_proj(proj);
2741 if (pn == default_pn)
2744 if (pn < switch_min)
2746 if (pn > switch_max)
2750 if ((unsigned long) (switch_max - switch_min) > 128000) {
2751 panic("Size of switch %+F bigger than 128000", node);
2754 if (switch_min != 0) {
2755 /* if smallest switch case is not 0 we need an additional sub */
2756 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2757 add_ia32_am_offs_int(new_sel, -switch_min);
2758 set_ia32_op_type(new_sel, ia32_AddrModeS);
2760 SET_IA32_ORIG_NODE(new_sel, node);
2763 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2764 SET_IA32_ORIG_NODE(new_node, node);
2770 * Transform a Cond node.
2772 static ir_node *gen_Cond(ir_node *node)
2774 ir_node *block = get_nodes_block(node);
2775 ir_node *new_block = be_transform_node(block);
2776 dbg_info *dbgi = get_irn_dbg_info(node);
2777 ir_node *sel = get_Cond_selector(node);
2778 ir_mode *sel_mode = get_irn_mode(sel);
2779 ir_node *flags = NULL;
2781 ia32_condition_code_t cc;
2783 if (sel_mode != mode_b) {
2784 return create_Switch(node);
2787 /* we get flags from a Cmp */
2788 flags = get_flags_node(sel, &cc);
2790 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2791 SET_IA32_ORIG_NODE(new_node, node);
2797 * Transform a be_Copy.
2799 static ir_node *gen_be_Copy(ir_node *node)
2801 ir_node *new_node = be_duplicate_node(node);
2802 ir_mode *mode = get_irn_mode(new_node);
2804 if (ia32_mode_needs_gp_reg(mode)) {
2805 set_irn_mode(new_node, mode_Iu);
2811 static ir_node *create_Fucom(ir_node *node)
2813 dbg_info *dbgi = get_irn_dbg_info(node);
2814 ir_node *block = get_nodes_block(node);
2815 ir_node *new_block = be_transform_node(block);
2816 ir_node *left = get_Cmp_left(node);
2817 ir_node *new_left = be_transform_node(left);
2818 ir_node *right = get_Cmp_right(node);
2822 if (ia32_cg_config.use_fucomi) {
2823 new_right = be_transform_node(right);
2824 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2826 set_ia32_commutative(new_node);
2827 SET_IA32_ORIG_NODE(new_node, node);
2829 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2830 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2832 new_right = be_transform_node(right);
2833 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2836 set_ia32_commutative(new_node);
2838 SET_IA32_ORIG_NODE(new_node, node);
2840 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2841 SET_IA32_ORIG_NODE(new_node, node);
2847 static ir_node *create_Ucomi(ir_node *node)
2849 dbg_info *dbgi = get_irn_dbg_info(node);
2850 ir_node *src_block = get_nodes_block(node);
2851 ir_node *new_block = be_transform_node(src_block);
2852 ir_node *left = get_Cmp_left(node);
2853 ir_node *right = get_Cmp_right(node);
2855 ia32_address_mode_t am;
2856 ia32_address_t *addr = &am.addr;
2858 match_arguments(&am, src_block, left, right, NULL,
2859 match_commutative | match_am);
2861 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2862 addr->mem, am.new_op1, am.new_op2,
2864 set_am_attributes(new_node, &am);
2866 SET_IA32_ORIG_NODE(new_node, node);
2868 new_node = fix_mem_proj(new_node, &am);
2874 * returns true if it is assured, that the upper bits of a node are "clean"
2875 * which means for a 16 or 8 bit value, that the upper bits in the register
2876 * are 0 for unsigned and a copy of the last significant bit for signed
2879 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2881 assert(ia32_mode_needs_gp_reg(mode));
2882 if (get_mode_size_bits(mode) >= 32)
2885 if (is_Proj(transformed_node))
2886 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2888 switch (get_ia32_irn_opcode(transformed_node)) {
2889 case iro_ia32_Conv_I2I:
2890 case iro_ia32_Conv_I2I8Bit: {
2891 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2892 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2894 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2901 if (mode_is_signed(mode)) {
2902 return false; /* TODO handle signed modes */
2904 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2905 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2906 const ia32_immediate_attr_t *attr
2907 = get_ia32_immediate_attr_const(right);
2908 if (attr->symconst == 0 &&
2909 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2913 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2917 /* TODO too conservative if shift amount is constant */
2918 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2921 if (!mode_is_signed(mode)) {
2923 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2924 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2926 /* TODO if one is known to be zero extended, then || is sufficient */
2931 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2932 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2934 case iro_ia32_Const:
2935 case iro_ia32_Immediate: {
2936 const ia32_immediate_attr_t *attr =
2937 get_ia32_immediate_attr_const(transformed_node);
2938 if (mode_is_signed(mode)) {
2939 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2940 return shifted == 0 || shifted == -1;
2942 unsigned long shifted = (unsigned long)attr->offset;
2943 shifted >>= get_mode_size_bits(mode);
2944 return shifted == 0;
2954 * Generate code for a Cmp.
2956 static ir_node *gen_Cmp(ir_node *node)
2958 dbg_info *dbgi = get_irn_dbg_info(node);
2959 ir_node *block = get_nodes_block(node);
2960 ir_node *new_block = be_transform_node(block);
2961 ir_node *left = get_Cmp_left(node);
2962 ir_node *right = get_Cmp_right(node);
2963 ir_mode *cmp_mode = get_irn_mode(left);
2965 ia32_address_mode_t am;
2966 ia32_address_t *addr = &am.addr;
2968 if (mode_is_float(cmp_mode)) {
2969 if (ia32_cg_config.use_sse2) {
2970 return create_Ucomi(node);
2972 return create_Fucom(node);
2976 assert(ia32_mode_needs_gp_reg(cmp_mode));
2978 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2979 if (is_Const_0(right) &&
2981 get_irn_n_edges(left) == 1) {
2982 /* Test(and_left, and_right) */
2983 ir_node *and_left = get_And_left(left);
2984 ir_node *and_right = get_And_right(left);
2986 /* matze: code here used mode instead of cmd_mode, I think it is always
2987 * the same as cmp_mode, but I leave this here to see if this is really
2990 assert(get_irn_mode(and_left) == cmp_mode);
2992 match_arguments(&am, block, and_left, and_right, NULL,
2994 match_am | match_8bit_am | match_16bit_am |
2995 match_am_and_immediates | match_immediate);
2997 /* use 32bit compare mode if possible since the opcode is smaller */
2998 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2999 upper_bits_clean(am.new_op2, cmp_mode)) {
3000 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3003 if (get_mode_size_bits(cmp_mode) == 8) {
3004 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3005 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3007 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3008 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3011 /* Cmp(left, right) */
3012 match_arguments(&am, block, left, right, NULL,
3013 match_commutative | match_am | match_8bit_am |
3014 match_16bit_am | match_am_and_immediates |
3016 /* use 32bit compare mode if possible since the opcode is smaller */
3017 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3018 upper_bits_clean(am.new_op2, cmp_mode)) {
3019 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3022 if (get_mode_size_bits(cmp_mode) == 8) {
3023 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3024 addr->index, addr->mem, am.new_op1,
3025 am.new_op2, am.ins_permuted);
3027 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3028 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3031 set_am_attributes(new_node, &am);
3032 set_ia32_ls_mode(new_node, cmp_mode);
3034 SET_IA32_ORIG_NODE(new_node, node);
3036 new_node = fix_mem_proj(new_node, &am);
3041 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3042 ia32_condition_code_t cc)
3044 dbg_info *dbgi = get_irn_dbg_info(node);
3045 ir_node *block = get_nodes_block(node);
3046 ir_node *new_block = be_transform_node(block);
3047 ir_node *val_true = get_Mux_true(node);
3048 ir_node *val_false = get_Mux_false(node);
3050 ia32_address_mode_t am;
3051 ia32_address_t *addr;
3053 assert(ia32_cg_config.use_cmov);
3054 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3058 match_arguments(&am, block, val_false, val_true, flags,
3059 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3061 if (am.ins_permuted)
3062 cc = ia32_negate_condition_code(cc);
3064 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3065 addr->mem, am.new_op1, am.new_op2, new_flags,
3067 set_am_attributes(new_node, &am);
3069 SET_IA32_ORIG_NODE(new_node, node);
3071 new_node = fix_mem_proj(new_node, &am);
3077 * Creates a ia32 Setcc instruction.
3079 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3080 ir_node *flags, ia32_condition_code_t cc,
3083 ir_mode *mode = get_irn_mode(orig_node);
3086 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3087 SET_IA32_ORIG_NODE(new_node, orig_node);
3089 /* we might need to conv the result up */
3090 if (get_mode_size_bits(mode) > 8) {
3091 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3092 nomem, new_node, mode_Bu);
3093 SET_IA32_ORIG_NODE(new_node, orig_node);
3100 * Create instruction for an unsigned Difference or Zero.
3102 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3104 ir_mode *mode = get_irn_mode(psi);
3114 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3115 match_mode_neutral | match_am | match_immediate | match_two_users);
3117 block = get_nodes_block(new_node);
3119 if (is_Proj(new_node)) {
3120 sub = get_Proj_pred(new_node);
3123 set_irn_mode(sub, mode_T);
3124 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3126 assert(is_ia32_Sub(sub));
3127 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3129 dbgi = get_irn_dbg_info(psi);
3130 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3131 notn = new_bd_ia32_Not(dbgi, block, sbb);
3133 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3134 set_ia32_commutative(new_node);
3139 * Create an const array of two float consts.
3141 * @param c0 the first constant
3142 * @param c1 the second constant
3143 * @param new_mode IN/OUT for the mode of the constants, if NULL
3144 * smallest possible mode will be used
3146 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3149 ir_mode *mode = *new_mode;
3151 ir_initializer_t *initializer;
3152 ir_tarval *tv0 = get_Const_tarval(c0);
3153 ir_tarval *tv1 = get_Const_tarval(c1);
3156 /* detect the best mode for the constants */
3157 mode = get_tarval_mode(tv0);
3159 if (mode != mode_F) {
3160 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3161 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3163 tv0 = tarval_convert_to(tv0, mode);
3164 tv1 = tarval_convert_to(tv1, mode);
3165 } else if (mode != mode_D) {
3166 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3167 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3169 tv0 = tarval_convert_to(tv0, mode);
3170 tv1 = tarval_convert_to(tv1, mode);
3177 tp = ia32_create_float_type(mode, 4);
3178 tp = ia32_create_float_array(tp);
3180 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3182 set_entity_ld_ident(ent, get_entity_ident(ent));
3183 set_entity_visibility(ent, ir_visibility_private);
3184 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3186 initializer = create_initializer_compound(2);
3188 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3189 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3191 set_entity_initializer(ent, initializer);
3198 * Possible transformations for creating a Setcc.
3200 enum setcc_transform_insn {
3213 typedef struct setcc_transform {
3215 ia32_condition_code_t cc;
3217 enum setcc_transform_insn transform;
3221 } setcc_transform_t;
3224 * Setcc can only handle 0 and 1 result.
3225 * Find a transformation that creates 0 and 1 from
3228 static void find_const_transform(ia32_condition_code_t cc,
3229 ir_tarval *t, ir_tarval *f,
3230 setcc_transform_t *res)
3236 if (tarval_is_null(t)) {
3240 cc = ia32_negate_condition_code(cc);
3241 } else if (tarval_cmp(t, f) == ir_relation_less) {
3242 // now, t is the bigger one
3246 cc = ia32_negate_condition_code(cc);
3250 if (! tarval_is_null(f)) {
3251 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3254 res->steps[step].transform = SETCC_TR_ADD;
3256 if (t == tarval_bad)
3257 panic("constant subtract failed");
3258 if (! tarval_is_long(f))
3259 panic("tarval is not long");
3261 res->steps[step].val = get_tarval_long(f);
3263 f = tarval_sub(f, f, NULL);
3264 assert(tarval_is_null(f));
3267 if (tarval_is_one(t)) {
3268 res->steps[step].transform = SETCC_TR_SET;
3269 res->num_steps = ++step;
3273 if (tarval_is_minus_one(t)) {
3274 res->steps[step].transform = SETCC_TR_NEG;
3276 res->steps[step].transform = SETCC_TR_SET;
3277 res->num_steps = ++step;
3280 if (tarval_is_long(t)) {
3281 long v = get_tarval_long(t);
3283 res->steps[step].val = 0;
3286 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3288 res->steps[step].transform = SETCC_TR_LEAxx;
3289 res->steps[step].scale = 3; /* (a << 3) + a */
3292 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3294 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3295 res->steps[step].scale = 3; /* (a << 3) */
3298 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3300 res->steps[step].transform = SETCC_TR_LEAxx;
3301 res->steps[step].scale = 2; /* (a << 2) + a */
3304 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3306 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3307 res->steps[step].scale = 2; /* (a << 2) */
3310 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3312 res->steps[step].transform = SETCC_TR_LEAxx;
3313 res->steps[step].scale = 1; /* (a << 1) + a */
3316 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3318 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3319 res->steps[step].scale = 1; /* (a << 1) */
3322 res->num_steps = step;
3325 if (! tarval_is_single_bit(t)) {
3326 res->steps[step].transform = SETCC_TR_AND;
3327 res->steps[step].val = v;
3329 res->steps[step].transform = SETCC_TR_NEG;
3331 int v = get_tarval_lowest_bit(t);
3334 res->steps[step].transform = SETCC_TR_SHL;
3335 res->steps[step].scale = v;
3339 res->steps[step].transform = SETCC_TR_SET;
3340 res->num_steps = ++step;
3343 panic("tarval is not long");
3347 * Transforms a Mux node into some code sequence.
3349 * @return The transformed node.
3351 static ir_node *gen_Mux(ir_node *node)
3353 dbg_info *dbgi = get_irn_dbg_info(node);
3354 ir_node *block = get_nodes_block(node);
3355 ir_node *new_block = be_transform_node(block);
3356 ir_node *mux_true = get_Mux_true(node);
3357 ir_node *mux_false = get_Mux_false(node);
3358 ir_node *sel = get_Mux_sel(node);
3359 ir_mode *mode = get_irn_mode(node);
3363 ia32_condition_code_t cc;
3365 assert(get_irn_mode(sel) == mode_b);
3367 is_abs = be_mux_is_abs(sel, mux_true, mux_false);
3369 return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
3372 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3373 if (mode_is_float(mode)) {
3374 ir_node *cmp_left = get_Cmp_left(sel);
3375 ir_node *cmp_right = get_Cmp_right(sel);
3376 ir_relation relation = get_Cmp_relation(sel);
3378 if (ia32_cg_config.use_sse2) {
3379 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3380 if (cmp_left == mux_true && cmp_right == mux_false) {
3381 /* Mux(a <= b, a, b) => MIN */
3382 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3383 match_commutative | match_am | match_two_users);
3384 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3385 /* Mux(a <= b, b, a) => MAX */
3386 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3387 match_commutative | match_am | match_two_users);
3389 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3390 if (cmp_left == mux_true && cmp_right == mux_false) {
3391 /* Mux(a >= b, a, b) => MAX */
3392 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3393 match_commutative | match_am | match_two_users);
3394 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3395 /* Mux(a >= b, b, a) => MIN */
3396 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3397 match_commutative | match_am | match_two_users);
3402 if (is_Const(mux_true) && is_Const(mux_false)) {
3403 ia32_address_mode_t am;
3408 flags = get_flags_node(sel, &cc);
3409 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3411 if (ia32_cg_config.use_sse2) {
3412 /* cannot load from different mode on SSE */
3415 /* x87 can load any mode */
3419 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3421 switch (get_mode_size_bytes(new_mode)) {
3431 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3432 set_ia32_am_scale(new_node, 2);
3437 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3438 set_ia32_am_scale(new_node, 1);
3441 /* arg, shift 16 NOT supported */
3443 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3446 panic("Unsupported constant size");
3449 am.ls_mode = new_mode;
3450 am.addr.base = get_symconst_base();
3451 am.addr.index = new_node;
3452 am.addr.mem = nomem;
3454 am.addr.scale = scale;
3455 am.addr.use_frame = 0;
3456 am.addr.tls_segment = false;
3457 am.addr.frame_entity = NULL;
3458 am.addr.symconst_sign = 0;
3459 am.mem_proj = am.addr.mem;
3460 am.op_type = ia32_AddrModeS;
3463 am.pinned = op_pin_state_floats;
3465 am.ins_permuted = false;
3467 if (ia32_cg_config.use_sse2)
3468 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3470 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3471 set_am_attributes(load, &am);
3473 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3475 panic("cannot transform floating point Mux");
3478 assert(ia32_mode_needs_gp_reg(mode));
3481 ir_node *cmp_left = get_Cmp_left(sel);
3482 ir_node *cmp_right = get_Cmp_right(sel);
3483 ir_relation relation = get_Cmp_relation(sel);
3484 ir_node *val_true = mux_true;
3485 ir_node *val_false = mux_false;
3487 if (is_Const(val_true) && is_Const_null(val_true)) {
3488 ir_node *tmp = val_false;
3489 val_false = val_true;
3491 relation = get_negated_relation(relation);
3493 if (is_Const_0(val_false) && is_Sub(val_true)) {
3494 if ((relation & ir_relation_greater)
3495 && get_Sub_left(val_true) == cmp_left
3496 && get_Sub_right(val_true) == cmp_right) {
3497 return create_doz(node, cmp_left, cmp_right);
3499 if ((relation & ir_relation_less)
3500 && get_Sub_left(val_true) == cmp_right
3501 && get_Sub_right(val_true) == cmp_left) {
3502 return create_doz(node, cmp_right, cmp_left);
3507 flags = get_flags_node(sel, &cc);
3509 if (is_Const(mux_true) && is_Const(mux_false)) {
3510 /* both are const, good */
3511 ir_tarval *tv_true = get_Const_tarval(mux_true);
3512 ir_tarval *tv_false = get_Const_tarval(mux_false);
3513 setcc_transform_t res;
3516 find_const_transform(cc, tv_true, tv_false, &res);
3518 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3521 switch (res.steps[step].transform) {
3523 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3524 add_ia32_am_offs_int(new_node, res.steps[step].val);
3526 case SETCC_TR_ADDxx:
3527 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3530 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3531 set_ia32_am_scale(new_node, res.steps[step].scale);
3532 set_ia32_am_offs_int(new_node, res.steps[step].val);
3534 case SETCC_TR_LEAxx:
3535 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3536 set_ia32_am_scale(new_node, res.steps[step].scale);
3537 set_ia32_am_offs_int(new_node, res.steps[step].val);
3540 imm = ia32_immediate_from_long(res.steps[step].scale);
3541 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3544 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3547 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3550 imm = ia32_immediate_from_long(res.steps[step].val);
3551 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3554 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3557 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3560 panic("unknown setcc transform");
3564 new_node = create_CMov(node, sel, flags, cc);
3572 * Create a conversion from x87 state register to general purpose.
3574 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3576 ir_node *block = be_transform_node(get_nodes_block(node));
3577 ir_node *op = get_Conv_op(node);
3578 ir_node *new_op = be_transform_node(op);
3579 ir_graph *irg = current_ir_graph;
3580 dbg_info *dbgi = get_irn_dbg_info(node);
3581 ir_mode *mode = get_irn_mode(node);
3582 ir_node *fist, *load, *mem;
3584 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3585 set_irn_pinned(fist, op_pin_state_floats);
3586 set_ia32_use_frame(fist);
3587 set_ia32_op_type(fist, ia32_AddrModeD);
3589 assert(get_mode_size_bits(mode) <= 32);
3590 /* exception we can only store signed 32 bit integers, so for unsigned
3591 we store a 64bit (signed) integer and load the lower bits */
3592 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3593 set_ia32_ls_mode(fist, mode_Ls);
3595 set_ia32_ls_mode(fist, mode_Is);
3597 SET_IA32_ORIG_NODE(fist, node);
3600 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3602 set_irn_pinned(load, op_pin_state_floats);
3603 set_ia32_use_frame(load);
3604 set_ia32_op_type(load, ia32_AddrModeS);
3605 set_ia32_ls_mode(load, mode_Is);
3606 if (get_ia32_ls_mode(fist) == mode_Ls) {
3607 ia32_attr_t *attr = get_ia32_attr(load);
3608 attr->data.need_64bit_stackent = 1;
3610 ia32_attr_t *attr = get_ia32_attr(load);
3611 attr->data.need_32bit_stackent = 1;
3613 SET_IA32_ORIG_NODE(load, node);
3615 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3619 * Creates a x87 strict Conv by placing a Store and a Load
3621 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3623 ir_node *block = get_nodes_block(node);
3624 ir_graph *irg = get_Block_irg(block);
3625 dbg_info *dbgi = get_irn_dbg_info(node);
3626 ir_node *frame = get_irg_frame(irg);
3627 ir_node *store, *load;
3630 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3631 set_ia32_use_frame(store);
3632 set_ia32_op_type(store, ia32_AddrModeD);
3633 SET_IA32_ORIG_NODE(store, node);
3635 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3636 set_ia32_use_frame(load);
3637 set_ia32_op_type(load, ia32_AddrModeS);
3638 SET_IA32_ORIG_NODE(load, node);
3640 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3644 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3645 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3647 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3649 func = get_mode_size_bits(mode) == 8 ?
3650 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3651 return func(dbgi, block, base, index, mem, val, mode);
3655 * Create a conversion from general purpose to x87 register
3657 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3659 ir_node *src_block = get_nodes_block(node);
3660 ir_node *block = be_transform_node(src_block);
3661 ir_graph *irg = get_Block_irg(block);
3662 dbg_info *dbgi = get_irn_dbg_info(node);
3663 ir_node *op = get_Conv_op(node);
3664 ir_node *new_op = NULL;
3666 ir_mode *store_mode;
3671 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3672 if (possible_int_mode_for_fp(src_mode)) {
3673 ia32_address_mode_t am;
3675 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3676 if (am.op_type == ia32_AddrModeS) {
3677 ia32_address_t *addr = &am.addr;
3679 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3680 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3682 set_am_attributes(fild, &am);
3683 SET_IA32_ORIG_NODE(fild, node);
3685 fix_mem_proj(fild, &am);
3690 if (new_op == NULL) {
3691 new_op = be_transform_node(op);
3694 mode = get_irn_mode(op);
3696 /* first convert to 32 bit signed if necessary */
3697 if (get_mode_size_bits(src_mode) < 32) {
3698 if (!upper_bits_clean(new_op, src_mode)) {
3699 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3700 SET_IA32_ORIG_NODE(new_op, node);
3705 assert(get_mode_size_bits(mode) == 32);
3708 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3710 set_ia32_use_frame(store);
3711 set_ia32_op_type(store, ia32_AddrModeD);
3712 set_ia32_ls_mode(store, mode_Iu);
3714 /* exception for 32bit unsigned, do a 64bit spill+load */
3715 if (!mode_is_signed(mode)) {
3718 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3720 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3721 noreg_GP, nomem, zero_const);
3723 set_ia32_use_frame(zero_store);
3724 set_ia32_op_type(zero_store, ia32_AddrModeD);
3725 add_ia32_am_offs_int(zero_store, 4);
3726 set_ia32_ls_mode(zero_store, mode_Iu);
3731 store = new_rd_Sync(dbgi, block, 2, in);
3732 store_mode = mode_Ls;
3734 store_mode = mode_Is;
3738 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3740 set_ia32_use_frame(fild);
3741 set_ia32_op_type(fild, ia32_AddrModeS);
3742 set_ia32_ls_mode(fild, store_mode);
3744 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3750 * Create a conversion from one integer mode into another one
3752 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3753 dbg_info *dbgi, ir_node *block, ir_node *op,
3756 ir_node *new_block = be_transform_node(block);
3758 ir_mode *smaller_mode;
3759 ia32_address_mode_t am;
3760 ia32_address_t *addr = &am.addr;
3763 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3764 smaller_mode = src_mode;
3766 smaller_mode = tgt_mode;
3769 #ifdef DEBUG_libfirm
3771 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3776 match_arguments(&am, block, NULL, op, NULL,
3777 match_am | match_8bit_am | match_16bit_am);
3779 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3780 /* unnecessary conv. in theory it shouldn't have been AM */
3781 assert(is_ia32_NoReg_GP(addr->base));
3782 assert(is_ia32_NoReg_GP(addr->index));
3783 assert(is_NoMem(addr->mem));
3784 assert(am.addr.offset == 0);
3785 assert(am.addr.symconst_ent == NULL);
3789 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3790 addr->mem, am.new_op2, smaller_mode);
3791 set_am_attributes(new_node, &am);
3792 /* match_arguments assume that out-mode = in-mode, this isn't true here
3794 set_ia32_ls_mode(new_node, smaller_mode);
3795 SET_IA32_ORIG_NODE(new_node, node);
3796 new_node = fix_mem_proj(new_node, &am);
3801 * Transforms a Conv node.
3803 * @return The created ia32 Conv node
3805 static ir_node *gen_Conv(ir_node *node)
3807 ir_node *block = get_nodes_block(node);
3808 ir_node *new_block = be_transform_node(block);
3809 ir_node *op = get_Conv_op(node);
3810 ir_node *new_op = NULL;
3811 dbg_info *dbgi = get_irn_dbg_info(node);
3812 ir_mode *src_mode = get_irn_mode(op);
3813 ir_mode *tgt_mode = get_irn_mode(node);
3814 int src_bits = get_mode_size_bits(src_mode);
3815 int tgt_bits = get_mode_size_bits(tgt_mode);
3816 ir_node *res = NULL;
3818 assert(!mode_is_int(src_mode) || src_bits <= 32);
3819 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3821 /* modeB -> X should already be lowered by the lower_mode_b pass */
3822 if (src_mode == mode_b) {
3823 panic("ConvB not lowered %+F", node);
3826 if (src_mode == tgt_mode) {
3827 if (get_Conv_strict(node)) {
3828 if (ia32_cg_config.use_sse2) {
3829 /* when we are in SSE mode, we can kill all strict no-op conversion */
3830 return be_transform_node(op);
3833 /* this should be optimized already, but who knows... */
3834 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3835 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3836 return be_transform_node(op);
3840 if (mode_is_float(src_mode)) {
3841 new_op = be_transform_node(op);
3842 /* we convert from float ... */
3843 if (mode_is_float(tgt_mode)) {
3845 if (ia32_cg_config.use_sse2) {
3846 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3847 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3849 set_ia32_ls_mode(res, tgt_mode);
3851 if (get_Conv_strict(node)) {
3852 /* if fp_no_float_fold is not set then we assume that we
3853 * don't have any float operations in a non
3854 * mode_float_arithmetic mode and can skip strict upconvs */
3855 if (src_bits < tgt_bits) {
3856 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3859 res = gen_x87_strict_conv(tgt_mode, new_op);
3860 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3864 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3869 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3870 if (ia32_cg_config.use_sse2) {
3871 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3873 set_ia32_ls_mode(res, src_mode);
3875 return gen_x87_fp_to_gp(node);
3879 /* we convert from int ... */
3880 if (mode_is_float(tgt_mode)) {
3882 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3883 if (ia32_cg_config.use_sse2) {
3884 new_op = be_transform_node(op);
3885 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3887 set_ia32_ls_mode(res, tgt_mode);
3889 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3890 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3891 res = gen_x87_gp_to_fp(node, src_mode);
3893 /* we need a strict-Conv, if the int mode has more bits than the
3895 if (float_mantissa < int_mantissa) {
3896 res = gen_x87_strict_conv(tgt_mode, res);
3897 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3901 } else if (tgt_mode == mode_b) {
3902 /* mode_b lowering already took care that we only have 0/1 values */
3903 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3904 src_mode, tgt_mode));
3905 return be_transform_node(op);
3908 if (src_bits == tgt_bits) {
3909 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3910 src_mode, tgt_mode));
3911 return be_transform_node(op);
3914 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3922 static ir_node *create_immediate_or_transform(ir_node *node,
3923 char immediate_constraint_type)
3925 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3926 if (new_node == NULL) {
3927 new_node = be_transform_node(node);
3933 * Transforms a FrameAddr into an ia32 Add.
3935 static ir_node *gen_be_FrameAddr(ir_node *node)
3937 ir_node *block = be_transform_node(get_nodes_block(node));
3938 ir_node *op = be_get_FrameAddr_frame(node);
3939 ir_node *new_op = be_transform_node(op);
3940 dbg_info *dbgi = get_irn_dbg_info(node);
3943 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3944 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3945 set_ia32_use_frame(new_node);
3947 SET_IA32_ORIG_NODE(new_node, node);
3953 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3955 static ir_node *gen_be_Return(ir_node *node)
3957 ir_graph *irg = current_ir_graph;
3958 ir_node *ret_val = get_irn_n(node, n_be_Return_val);
3959 ir_node *ret_mem = get_irn_n(node, n_be_Return_mem);
3960 ir_node *new_ret_val = be_transform_node(ret_val);
3961 ir_node *new_ret_mem = be_transform_node(ret_mem);
3962 ir_entity *ent = get_irg_entity(irg);
3963 ir_type *tp = get_entity_type(ent);
3964 dbg_info *dbgi = get_irn_dbg_info(node);
3965 ir_node *block = be_transform_node(get_nodes_block(node));
3968 ir_node *frame, *sse_store, *fld, *mproj;
3975 assert(ret_val != NULL);
3976 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3977 return be_duplicate_node(node);
3980 res_type = get_method_res_type(tp, 0);
3982 if (! is_Primitive_type(res_type)) {
3983 return be_duplicate_node(node);
3986 mode = get_type_mode(res_type);
3987 if (! mode_is_float(mode)) {
3988 return be_duplicate_node(node);
3991 assert(get_method_n_ress(tp) == 1);
3993 frame = get_irg_frame(irg);
3995 /* store xmm0 onto stack */
3996 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3997 new_ret_mem, new_ret_val);
3998 set_ia32_ls_mode(sse_store, mode);
3999 set_ia32_op_type(sse_store, ia32_AddrModeD);
4000 set_ia32_use_frame(sse_store);
4002 /* load into x87 register */
4003 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4004 set_ia32_op_type(fld, ia32_AddrModeS);
4005 set_ia32_use_frame(fld);
4007 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4008 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4010 /* create a new return */
4011 arity = get_irn_arity(node);
4012 in = ALLOCAN(ir_node*, arity);
4013 pop = be_Return_get_pop(node);
4014 for (i = 0; i < arity; ++i) {
4015 ir_node *op = get_irn_n(node, i);
4016 if (op == ret_val) {
4018 } else if (op == ret_mem) {
4021 in[i] = be_transform_node(op);
4024 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4025 copy_node_attr(irg, node, new_node);
4031 * Transform a be_AddSP into an ia32_SubSP.
4033 static ir_node *gen_be_AddSP(ir_node *node)
4035 ir_node *sz = get_irn_n(node, n_be_AddSP_size);
4036 ir_node *sp = get_irn_n(node, n_be_AddSP_old_sp);
4038 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4039 match_am | match_immediate);
4040 assert(is_ia32_SubSP(new_node));
4041 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4042 &ia32_registers[REG_ESP]);
4047 * Transform a be_SubSP into an ia32_AddSP
4049 static ir_node *gen_be_SubSP(ir_node *node)
4051 ir_node *sz = get_irn_n(node, n_be_SubSP_size);
4052 ir_node *sp = get_irn_n(node, n_be_SubSP_old_sp);
4054 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4055 match_am | match_immediate);
4056 assert(is_ia32_AddSP(new_node));
4057 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4058 &ia32_registers[REG_ESP]);
4063 * Change some phi modes
4065 static ir_node *gen_Phi(ir_node *node)
4067 const arch_register_req_t *req;
4068 ir_node *block = be_transform_node(get_nodes_block(node));
4069 ir_graph *irg = current_ir_graph;
4070 dbg_info *dbgi = get_irn_dbg_info(node);
4071 ir_mode *mode = get_irn_mode(node);
4074 if (ia32_mode_needs_gp_reg(mode)) {
4075 /* we shouldn't have any 64bit stuff around anymore */
4076 assert(get_mode_size_bits(mode) <= 32);
4077 /* all integer operations are on 32bit registers now */
4079 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4080 } else if (mode_is_float(mode)) {
4081 if (ia32_cg_config.use_sse2) {
4083 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4086 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4089 req = arch_no_register_req;
4092 /* phi nodes allow loops, so we use the old arguments for now
4093 * and fix this later */
4094 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4095 get_irn_in(node) + 1);
4096 copy_node_attr(irg, node, phi);
4097 be_duplicate_deps(node, phi);
4099 arch_set_out_register_req(phi, 0, req);
4101 be_enqueue_preds(node);
4106 static ir_node *gen_Jmp(ir_node *node)
4108 ir_node *block = get_nodes_block(node);
4109 ir_node *new_block = be_transform_node(block);
4110 dbg_info *dbgi = get_irn_dbg_info(node);
4113 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4114 SET_IA32_ORIG_NODE(new_node, node);
4122 static ir_node *gen_IJmp(ir_node *node)
4124 ir_node *block = get_nodes_block(node);
4125 ir_node *new_block = be_transform_node(block);
4126 dbg_info *dbgi = get_irn_dbg_info(node);
4127 ir_node *op = get_IJmp_target(node);
4129 ia32_address_mode_t am;
4130 ia32_address_t *addr = &am.addr;
4132 assert(get_irn_mode(op) == mode_P);
4134 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4136 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4137 addr->mem, am.new_op2);
4138 set_am_attributes(new_node, &am);
4139 SET_IA32_ORIG_NODE(new_node, node);
4141 new_node = fix_mem_proj(new_node, &am);
4146 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4148 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4149 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4151 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4152 match_immediate | match_mode_neutral);
4155 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4157 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4158 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4159 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4163 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4165 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4166 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4167 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4171 static ir_node *gen_ia32_l_Add(ir_node *node)
4173 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4174 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4175 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4176 match_commutative | match_am | match_immediate |
4177 match_mode_neutral);
4179 if (is_Proj(lowered)) {
4180 lowered = get_Proj_pred(lowered);
4182 assert(is_ia32_Add(lowered));
4183 set_irn_mode(lowered, mode_T);
4189 static ir_node *gen_ia32_l_Adc(ir_node *node)
4191 return gen_binop_flags(node, new_bd_ia32_Adc,
4192 match_commutative | match_am | match_immediate |
4193 match_mode_neutral);
4197 * Transforms a l_MulS into a "real" MulS node.
4199 * @return the created ia32 Mul node
4201 static ir_node *gen_ia32_l_Mul(ir_node *node)
4203 ir_node *left = get_binop_left(node);
4204 ir_node *right = get_binop_right(node);
4206 return gen_binop(node, left, right, new_bd_ia32_Mul,
4207 match_commutative | match_am | match_mode_neutral);
4211 * Transforms a l_IMulS into a "real" IMul1OPS node.
4213 * @return the created ia32 IMul1OP node
4215 static ir_node *gen_ia32_l_IMul(ir_node *node)
4217 ir_node *left = get_binop_left(node);
4218 ir_node *right = get_binop_right(node);
4220 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4221 match_commutative | match_am | match_mode_neutral);
4224 static ir_node *gen_ia32_l_Sub(ir_node *node)
4226 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4227 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4228 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4229 match_am | match_immediate | match_mode_neutral);
4231 if (is_Proj(lowered)) {
4232 lowered = get_Proj_pred(lowered);
4234 assert(is_ia32_Sub(lowered));
4235 set_irn_mode(lowered, mode_T);
4241 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4243 return gen_binop_flags(node, new_bd_ia32_Sbb,
4244 match_am | match_immediate | match_mode_neutral);
4248 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4249 * op1 - target to be shifted
4250 * op2 - contains bits to be shifted into target
4252 * Only op3 can be an immediate.
4254 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4255 ir_node *low, ir_node *count)
4257 ir_node *block = get_nodes_block(node);
4258 ir_node *new_block = be_transform_node(block);
4259 dbg_info *dbgi = get_irn_dbg_info(node);
4260 ir_node *new_high = be_transform_node(high);
4261 ir_node *new_low = be_transform_node(low);
4265 /* the shift amount can be any mode that is bigger than 5 bits, since all
4266 * other bits are ignored anyway */
4267 while (is_Conv(count) &&
4268 get_irn_n_edges(count) == 1 &&
4269 mode_is_int(get_irn_mode(count))) {
4270 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4271 count = get_Conv_op(count);
4273 new_count = create_immediate_or_transform(count, 0);
4275 if (is_ia32_l_ShlD(node)) {
4276 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4279 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4282 SET_IA32_ORIG_NODE(new_node, node);
4287 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4289 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4290 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4291 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4292 return gen_lowered_64bit_shifts(node, high, low, count);
4295 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4297 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4298 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4299 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4300 return gen_lowered_64bit_shifts(node, high, low, count);
4303 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4305 ir_node *src_block = get_nodes_block(node);
4306 ir_node *block = be_transform_node(src_block);
4307 ir_graph *irg = current_ir_graph;
4308 dbg_info *dbgi = get_irn_dbg_info(node);
4309 ir_node *frame = get_irg_frame(irg);
4310 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4311 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4312 ir_node *new_val_low = be_transform_node(val_low);
4313 ir_node *new_val_high = be_transform_node(val_high);
4315 ir_node *sync, *fild, *res;
4316 ir_node *store_low, *store_high;
4318 if (ia32_cg_config.use_sse2) {
4319 panic("ia32_l_LLtoFloat not implemented for SSE2");
4323 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4325 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4327 SET_IA32_ORIG_NODE(store_low, node);
4328 SET_IA32_ORIG_NODE(store_high, node);
4330 set_ia32_use_frame(store_low);
4331 set_ia32_use_frame(store_high);
4332 set_ia32_op_type(store_low, ia32_AddrModeD);
4333 set_ia32_op_type(store_high, ia32_AddrModeD);
4334 set_ia32_ls_mode(store_low, mode_Iu);
4335 set_ia32_ls_mode(store_high, mode_Is);
4336 add_ia32_am_offs_int(store_high, 4);
4340 sync = new_rd_Sync(dbgi, block, 2, in);
4343 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4345 set_ia32_use_frame(fild);
4346 set_ia32_op_type(fild, ia32_AddrModeS);
4347 set_ia32_ls_mode(fild, mode_Ls);
4349 SET_IA32_ORIG_NODE(fild, node);
4351 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4353 if (! mode_is_signed(get_irn_mode(val_high))) {
4354 ia32_address_mode_t am;
4356 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4359 am.addr.base = get_symconst_base();
4360 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4361 am.addr.mem = nomem;
4364 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4365 am.addr.tls_segment = false;
4366 am.addr.use_frame = 0;
4367 am.addr.frame_entity = NULL;
4368 am.addr.symconst_sign = 0;
4369 am.ls_mode = mode_F;
4370 am.mem_proj = nomem;
4371 am.op_type = ia32_AddrModeS;
4373 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4374 am.pinned = op_pin_state_floats;
4376 am.ins_permuted = false;
4378 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4379 am.new_op1, am.new_op2, get_fpcw());
4380 set_am_attributes(fadd, &am);
4382 set_irn_mode(fadd, mode_T);
4383 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4388 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4390 ir_node *src_block = get_nodes_block(node);
4391 ir_node *block = be_transform_node(src_block);
4392 ir_graph *irg = get_Block_irg(block);
4393 dbg_info *dbgi = get_irn_dbg_info(node);
4394 ir_node *frame = get_irg_frame(irg);
4395 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4396 ir_node *new_val = be_transform_node(val);
4397 ir_node *fist, *mem;
4399 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4400 SET_IA32_ORIG_NODE(fist, node);
4401 set_ia32_use_frame(fist);
4402 set_ia32_op_type(fist, ia32_AddrModeD);
4403 set_ia32_ls_mode(fist, mode_Ls);
4408 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4410 ir_node *block = be_transform_node(get_nodes_block(node));
4411 ir_graph *irg = get_Block_irg(block);
4412 ir_node *pred = get_Proj_pred(node);
4413 ir_node *new_pred = be_transform_node(pred);
4414 ir_node *frame = get_irg_frame(irg);
4415 dbg_info *dbgi = get_irn_dbg_info(node);
4416 long pn = get_Proj_proj(node);
4421 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4422 SET_IA32_ORIG_NODE(load, node);
4423 set_ia32_use_frame(load);
4424 set_ia32_op_type(load, ia32_AddrModeS);
4425 set_ia32_ls_mode(load, mode_Iu);
4426 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4427 * 32 bit from it with this particular load */
4428 attr = get_ia32_attr(load);
4429 attr->data.need_64bit_stackent = 1;
4431 if (pn == pn_ia32_l_FloattoLL_res_high) {
4432 add_ia32_am_offs_int(load, 4);
4434 assert(pn == pn_ia32_l_FloattoLL_res_low);
4437 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4443 * Transform the Projs of an AddSP.
4445 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4447 ir_node *pred = get_Proj_pred(node);
4448 ir_node *new_pred = be_transform_node(pred);
4449 dbg_info *dbgi = get_irn_dbg_info(node);
4450 long proj = get_Proj_proj(node);
4452 if (proj == pn_be_AddSP_sp) {
4453 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4454 pn_ia32_SubSP_stack);
4455 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4457 } else if (proj == pn_be_AddSP_res) {
4458 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4459 pn_ia32_SubSP_addr);
4460 } else if (proj == pn_be_AddSP_M) {
4461 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4464 panic("No idea how to transform proj->AddSP");
4468 * Transform the Projs of a SubSP.
4470 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4472 ir_node *pred = get_Proj_pred(node);
4473 ir_node *new_pred = be_transform_node(pred);
4474 dbg_info *dbgi = get_irn_dbg_info(node);
4475 long proj = get_Proj_proj(node);
4477 if (proj == pn_be_SubSP_sp) {
4478 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4479 pn_ia32_AddSP_stack);
4480 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4482 } else if (proj == pn_be_SubSP_M) {
4483 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4486 panic("No idea how to transform proj->SubSP");
4490 * Transform and renumber the Projs from a Load.
4492 static ir_node *gen_Proj_Load(ir_node *node)
4495 ir_node *block = be_transform_node(get_nodes_block(node));
4496 ir_node *pred = get_Proj_pred(node);
4497 dbg_info *dbgi = get_irn_dbg_info(node);
4498 long proj = get_Proj_proj(node);
4500 /* loads might be part of source address mode matches, so we don't
4501 * transform the ProjMs yet (with the exception of loads whose result is
4504 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4507 /* this is needed, because sometimes we have loops that are only
4508 reachable through the ProjM */
4509 be_enqueue_preds(node);
4510 /* do it in 2 steps, to silence firm verifier */
4511 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4512 set_Proj_proj(res, pn_ia32_mem);
4516 /* renumber the proj */
4517 new_pred = be_transform_node(pred);
4518 if (is_ia32_Load(new_pred)) {
4521 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4523 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4524 case pn_Load_X_regular:
4525 return new_rd_Jmp(dbgi, block);
4526 case pn_Load_X_except:
4527 /* This Load might raise an exception. Mark it. */
4528 set_ia32_exc_label(new_pred, 1);
4529 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4533 } else if (is_ia32_Conv_I2I(new_pred) ||
4534 is_ia32_Conv_I2I8Bit(new_pred)) {
4535 set_irn_mode(new_pred, mode_T);
4536 if (proj == pn_Load_res) {
4537 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4538 } else if (proj == pn_Load_M) {
4539 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4541 } else if (is_ia32_xLoad(new_pred)) {
4544 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4546 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4547 case pn_Load_X_regular:
4548 return new_rd_Jmp(dbgi, block);
4549 case pn_Load_X_except:
4550 /* This Load might raise an exception. Mark it. */
4551 set_ia32_exc_label(new_pred, 1);
4552 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4556 } else if (is_ia32_vfld(new_pred)) {
4559 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4561 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4562 case pn_Load_X_regular:
4563 return new_rd_Jmp(dbgi, block);
4564 case pn_Load_X_except:
4565 /* This Load might raise an exception. Mark it. */
4566 set_ia32_exc_label(new_pred, 1);
4567 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4572 /* can happen for ProJMs when source address mode happened for the
4575 /* however it should not be the result proj, as that would mean the
4576 load had multiple users and should not have been used for
4578 if (proj != pn_Load_M) {
4579 panic("internal error: transformed node not a Load");
4581 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4584 panic("No idea how to transform proj");
4588 * Transform and renumber the Projs from a Div or Mod instruction.
4590 static ir_node *gen_Proj_Div(ir_node *node)
4592 ir_node *block = be_transform_node(get_nodes_block(node));
4593 ir_node *pred = get_Proj_pred(node);
4594 ir_node *new_pred = be_transform_node(pred);
4595 dbg_info *dbgi = get_irn_dbg_info(node);
4596 long proj = get_Proj_proj(node);
4598 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4599 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4603 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4604 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4605 } else if (is_ia32_xDiv(new_pred)) {
4606 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4607 } else if (is_ia32_vfdiv(new_pred)) {
4608 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4610 panic("Div transformed to unexpected thing %+F", new_pred);
4613 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4614 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4615 } else if (is_ia32_xDiv(new_pred)) {
4616 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4617 } else if (is_ia32_vfdiv(new_pred)) {
4618 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4620 panic("Div transformed to unexpected thing %+F", new_pred);
4622 case pn_Div_X_regular:
4623 return new_rd_Jmp(dbgi, block);
4624 case pn_Div_X_except:
4625 set_ia32_exc_label(new_pred, 1);
4626 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4631 panic("No idea how to transform proj->Div");
4635 * Transform and renumber the Projs from a Div or Mod instruction.
4637 static ir_node *gen_Proj_Mod(ir_node *node)
4639 ir_node *pred = get_Proj_pred(node);
4640 ir_node *new_pred = be_transform_node(pred);
4641 dbg_info *dbgi = get_irn_dbg_info(node);
4642 long proj = get_Proj_proj(node);
4644 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4645 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4646 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4650 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4652 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4653 case pn_Mod_X_except:
4654 set_ia32_exc_label(new_pred, 1);
4655 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4659 panic("No idea how to transform proj->Mod");
4663 * Transform and renumber the Projs from a CopyB.
4665 static ir_node *gen_Proj_CopyB(ir_node *node)
4667 ir_node *pred = get_Proj_pred(node);
4668 ir_node *new_pred = be_transform_node(pred);
4669 dbg_info *dbgi = get_irn_dbg_info(node);
4670 long proj = get_Proj_proj(node);
4674 if (is_ia32_CopyB_i(new_pred)) {
4675 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4676 } else if (is_ia32_CopyB(new_pred)) {
4677 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4684 panic("No idea how to transform proj->CopyB");
4687 static ir_node *gen_be_Call(ir_node *node)
4689 dbg_info *const dbgi = get_irn_dbg_info(node);
4690 ir_node *const src_block = get_nodes_block(node);
4691 ir_node *const block = be_transform_node(src_block);
4692 ir_node *const src_mem = get_irn_n(node, n_be_Call_mem);
4693 ir_node *const src_sp = get_irn_n(node, n_be_Call_sp);
4694 ir_node *const sp = be_transform_node(src_sp);
4695 ir_node *const src_ptr = get_irn_n(node, n_be_Call_ptr);
4696 ia32_address_mode_t am;
4697 ia32_address_t *const addr = &am.addr;
4702 ir_node * eax = noreg_GP;
4703 ir_node * ecx = noreg_GP;
4704 ir_node * edx = noreg_GP;
4705 unsigned const pop = be_Call_get_pop(node);
4706 ir_type *const call_tp = be_Call_get_type(node);
4707 int old_no_pic_adjust;
4709 /* Run the x87 simulator if the call returns a float value */
4710 if (get_method_n_ress(call_tp) > 0) {
4711 ir_type *const res_type = get_method_res_type(call_tp, 0);
4712 ir_mode *const res_mode = get_type_mode(res_type);
4714 if (res_mode != NULL && mode_is_float(res_mode)) {
4715 ir_graph *irg = current_ir_graph;
4716 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4717 irg_data->do_x87_sim = 1;
4721 /* We do not want be_Call direct calls */
4722 assert(be_Call_get_entity(node) == NULL);
4724 /* special case for PIC trampoline calls */
4725 old_no_pic_adjust = ia32_no_pic_adjust;
4726 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4728 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4729 match_am | match_immediate);
4731 ia32_no_pic_adjust = old_no_pic_adjust;
4733 i = get_irn_arity(node) - 1;
4734 fpcw = be_transform_node(get_irn_n(node, i--));
4735 for (; i >= n_be_Call_first_arg; --i) {
4736 arch_register_req_t const *const req = arch_get_register_req(node, i);
4737 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4739 assert(req->type == arch_register_req_type_limited);
4740 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4742 switch (*req->limited) {
4743 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4744 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4745 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4746 default: panic("Invalid GP register for register parameter");
4750 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4751 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4752 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4753 set_am_attributes(call, &am);
4754 call = fix_mem_proj(call, &am);
4756 if (get_irn_pinned(node) == op_pin_state_pinned)
4757 set_irn_pinned(call, op_pin_state_pinned);
4759 SET_IA32_ORIG_NODE(call, node);
4761 if (ia32_cg_config.use_sse2) {
4762 /* remember this call for post-processing */
4763 ARR_APP1(ir_node *, call_list, call);
4764 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4771 * Transform Builtin trap
4773 static ir_node *gen_trap(ir_node *node)
4775 dbg_info *dbgi = get_irn_dbg_info(node);
4776 ir_node *block = be_transform_node(get_nodes_block(node));
4777 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4779 return new_bd_ia32_UD2(dbgi, block, mem);
4783 * Transform Builtin debugbreak
4785 static ir_node *gen_debugbreak(ir_node *node)
4787 dbg_info *dbgi = get_irn_dbg_info(node);
4788 ir_node *block = be_transform_node(get_nodes_block(node));
4789 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4791 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4795 * Transform Builtin return_address
4797 static ir_node *gen_return_address(ir_node *node)
4799 ir_node *param = get_Builtin_param(node, 0);
4800 ir_node *frame = get_Builtin_param(node, 1);
4801 dbg_info *dbgi = get_irn_dbg_info(node);
4802 ir_tarval *tv = get_Const_tarval(param);
4803 ir_graph *irg = get_irn_irg(node);
4804 unsigned long value = get_tarval_long(tv);
4806 ir_node *block = be_transform_node(get_nodes_block(node));
4807 ir_node *ptr = be_transform_node(frame);
4811 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4812 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4813 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4816 /* load the return address from this frame */
4817 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4819 set_irn_pinned(load, get_irn_pinned(node));
4820 set_ia32_op_type(load, ia32_AddrModeS);
4821 set_ia32_ls_mode(load, mode_Iu);
4823 set_ia32_am_offs_int(load, 0);
4824 set_ia32_use_frame(load);
4825 set_ia32_frame_ent(load, ia32_get_return_address_entity(irg));
4827 if (get_irn_pinned(node) == op_pin_state_floats) {
4828 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4829 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4830 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4831 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4834 SET_IA32_ORIG_NODE(load, node);
4835 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4839 * Transform Builtin frame_address
4841 static ir_node *gen_frame_address(ir_node *node)
4843 ir_node *param = get_Builtin_param(node, 0);
4844 ir_node *frame = get_Builtin_param(node, 1);
4845 dbg_info *dbgi = get_irn_dbg_info(node);
4846 ir_tarval *tv = get_Const_tarval(param);
4847 ir_graph *irg = get_irn_irg(node);
4848 unsigned long value = get_tarval_long(tv);
4850 ir_node *block = be_transform_node(get_nodes_block(node));
4851 ir_node *ptr = be_transform_node(frame);
4856 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4857 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4858 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4861 /* load the frame address from this frame */
4862 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4864 set_irn_pinned(load, get_irn_pinned(node));
4865 set_ia32_op_type(load, ia32_AddrModeS);
4866 set_ia32_ls_mode(load, mode_Iu);
4868 ent = ia32_get_frame_address_entity(irg);
4870 set_ia32_am_offs_int(load, 0);
4871 set_ia32_use_frame(load);
4872 set_ia32_frame_ent(load, ent);
4874 /* will fail anyway, but gcc does this: */
4875 set_ia32_am_offs_int(load, 0);
4878 if (get_irn_pinned(node) == op_pin_state_floats) {
4879 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4880 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4881 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4882 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4885 SET_IA32_ORIG_NODE(load, node);
4886 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4890 * Transform Builtin frame_address
4892 static ir_node *gen_prefetch(ir_node *node)
4895 ir_node *ptr, *block, *mem, *base, *index;
4896 ir_node *param, *new_node;
4899 ia32_address_t addr;
4901 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4902 /* no prefetch at all, route memory */
4903 return be_transform_node(get_Builtin_mem(node));
4906 param = get_Builtin_param(node, 1);
4907 tv = get_Const_tarval(param);
4908 rw = get_tarval_long(tv);
4910 /* construct load address */
4911 memset(&addr, 0, sizeof(addr));
4912 ptr = get_Builtin_param(node, 0);
4913 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4920 base = be_transform_node(base);
4923 if (index == NULL) {
4926 index = be_transform_node(index);
4929 dbgi = get_irn_dbg_info(node);
4930 block = be_transform_node(get_nodes_block(node));
4931 mem = be_transform_node(get_Builtin_mem(node));
4933 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4934 /* we have 3DNow!, this was already checked above */
4935 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4936 } else if (ia32_cg_config.use_sse_prefetch) {
4937 /* note: rw == 1 is IGNORED in that case */
4938 param = get_Builtin_param(node, 2);
4939 tv = get_Const_tarval(param);
4940 locality = get_tarval_long(tv);
4942 /* SSE style prefetch */
4945 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4948 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4951 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4954 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4958 assert(ia32_cg_config.use_3dnow_prefetch);
4959 /* 3DNow! style prefetch */
4960 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4963 set_irn_pinned(new_node, get_irn_pinned(node));
4964 set_ia32_op_type(new_node, ia32_AddrModeS);
4965 set_ia32_ls_mode(new_node, mode_Bu);
4966 set_address(new_node, &addr);
4968 SET_IA32_ORIG_NODE(new_node, node);
4970 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4974 * Transform bsf like node
4976 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4978 ir_node *param = get_Builtin_param(node, 0);
4979 dbg_info *dbgi = get_irn_dbg_info(node);
4981 ir_node *block = get_nodes_block(node);
4982 ir_node *new_block = be_transform_node(block);
4984 ia32_address_mode_t am;
4985 ia32_address_t *addr = &am.addr;
4988 match_arguments(&am, block, NULL, param, NULL, match_am);
4990 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4991 set_am_attributes(cnt, &am);
4992 set_ia32_ls_mode(cnt, get_irn_mode(param));
4994 SET_IA32_ORIG_NODE(cnt, node);
4995 return fix_mem_proj(cnt, &am);
4999 * Transform builtin ffs.
5001 static ir_node *gen_ffs(ir_node *node)
5003 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5004 ir_node *real = skip_Proj(bsf);
5005 dbg_info *dbgi = get_irn_dbg_info(real);
5006 ir_node *block = get_nodes_block(real);
5007 ir_node *flag, *set, *conv, *neg, *orn, *add;
5010 if (get_irn_mode(real) != mode_T) {
5011 set_irn_mode(real, mode_T);
5012 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5015 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5018 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5019 SET_IA32_ORIG_NODE(set, node);
5022 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5023 SET_IA32_ORIG_NODE(conv, node);
5026 neg = new_bd_ia32_Neg(dbgi, block, conv);
5029 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5030 set_ia32_commutative(orn);
5033 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5034 add_ia32_am_offs_int(add, 1);
5039 * Transform builtin clz.
5041 static ir_node *gen_clz(ir_node *node)
5043 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5044 ir_node *real = skip_Proj(bsr);
5045 dbg_info *dbgi = get_irn_dbg_info(real);
5046 ir_node *block = get_nodes_block(real);
5047 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5049 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5053 * Transform builtin ctz.
5055 static ir_node *gen_ctz(ir_node *node)
5057 return gen_unop_AM(node, new_bd_ia32_Bsf);
5061 * Transform builtin parity.
5063 static ir_node *gen_parity(ir_node *node)
5065 dbg_info *dbgi = get_irn_dbg_info(node);
5066 ir_node *block = get_nodes_block(node);
5067 ir_node *new_block = be_transform_node(block);
5068 ir_node *param = get_Builtin_param(node, 0);
5069 ir_node *new_param = be_transform_node(param);
5072 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5073 * so we have to do complicated xoring first.
5074 * (we should also better lower this before the backend so we still have a
5075 * chance for CSE, constant folding and other goodies for some of these
5078 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5079 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5080 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5082 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5085 set_irn_mode(xor2, mode_T);
5086 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5089 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5090 SET_IA32_ORIG_NODE(new_node, node);
5093 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5094 nomem, new_node, mode_Bu);
5095 SET_IA32_ORIG_NODE(new_node, node);
5100 * Transform builtin popcount
5102 static ir_node *gen_popcount(ir_node *node)
5104 ir_node *param = get_Builtin_param(node, 0);
5105 dbg_info *dbgi = get_irn_dbg_info(node);
5107 ir_node *block = get_nodes_block(node);
5108 ir_node *new_block = be_transform_node(block);
5111 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5113 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5114 if (ia32_cg_config.use_popcnt) {
5115 ia32_address_mode_t am;
5116 ia32_address_t *addr = &am.addr;
5119 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5121 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5122 set_am_attributes(cnt, &am);
5123 set_ia32_ls_mode(cnt, get_irn_mode(param));
5125 SET_IA32_ORIG_NODE(cnt, node);
5126 return fix_mem_proj(cnt, &am);
5129 new_param = be_transform_node(param);
5131 /* do the standard popcount algo */
5132 /* TODO: This is stupid, we should transform this before the backend,
5133 * to get CSE, localopts, etc. for the operations
5134 * TODO: This is also not the optimal algorithm (it is just the starting
5135 * example in hackers delight, they optimize it more on the following page)
5136 * But I'm too lazy to fix this now, as the code should get lowered before
5137 * the backend anyway.
5140 /* m1 = x & 0x55555555 */
5141 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5142 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5145 simm = ia32_create_Immediate(NULL, 0, 1);
5146 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5148 /* m2 = s1 & 0x55555555 */
5149 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5152 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5154 /* m4 = m3 & 0x33333333 */
5155 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5156 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5159 simm = ia32_create_Immediate(NULL, 0, 2);
5160 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5162 /* m5 = s2 & 0x33333333 */
5163 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5166 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5168 /* m7 = m6 & 0x0F0F0F0F */
5169 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5170 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5173 simm = ia32_create_Immediate(NULL, 0, 4);
5174 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5176 /* m8 = s3 & 0x0F0F0F0F */
5177 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5180 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5182 /* m10 = m9 & 0x00FF00FF */
5183 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5184 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5187 simm = ia32_create_Immediate(NULL, 0, 8);
5188 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5190 /* m11 = s4 & 0x00FF00FF */
5191 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5193 /* m12 = m10 + m11 */
5194 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5196 /* m13 = m12 & 0x0000FFFF */
5197 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5198 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5200 /* s5 = m12 >> 16 */
5201 simm = ia32_create_Immediate(NULL, 0, 16);
5202 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5204 /* res = m13 + s5 */
5205 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5209 * Transform builtin byte swap.
5211 static ir_node *gen_bswap(ir_node *node)
5213 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5214 dbg_info *dbgi = get_irn_dbg_info(node);
5216 ir_node *block = get_nodes_block(node);
5217 ir_node *new_block = be_transform_node(block);
5218 ir_mode *mode = get_irn_mode(param);
5219 unsigned size = get_mode_size_bits(mode);
5220 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5224 if (ia32_cg_config.use_i486) {
5225 /* swap available */
5226 return new_bd_ia32_Bswap(dbgi, new_block, param);
5228 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5229 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5231 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5232 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5234 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5236 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5237 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5239 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5240 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5243 /* swap16 always available */
5244 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5247 panic("Invalid bswap size (%d)", size);
5252 * Transform builtin outport.
5254 static ir_node *gen_outport(ir_node *node)
5256 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5257 ir_node *oldv = get_Builtin_param(node, 1);
5258 ir_mode *mode = get_irn_mode(oldv);
5259 ir_node *value = be_transform_node(oldv);
5260 ir_node *block = be_transform_node(get_nodes_block(node));
5261 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5262 dbg_info *dbgi = get_irn_dbg_info(node);
5264 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5265 set_ia32_ls_mode(res, mode);
5270 * Transform builtin inport.
5272 static ir_node *gen_inport(ir_node *node)
5274 ir_type *tp = get_Builtin_type(node);
5275 ir_type *rstp = get_method_res_type(tp, 0);
5276 ir_mode *mode = get_type_mode(rstp);
5277 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5278 ir_node *block = be_transform_node(get_nodes_block(node));
5279 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5280 dbg_info *dbgi = get_irn_dbg_info(node);
5282 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5283 set_ia32_ls_mode(res, mode);
5285 /* check for missing Result Proj */
5290 * Transform a builtin inner trampoline
5292 static ir_node *gen_inner_trampoline(ir_node *node)
5294 ir_node *ptr = get_Builtin_param(node, 0);
5295 ir_node *callee = get_Builtin_param(node, 1);
5296 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5297 ir_node *mem = get_Builtin_mem(node);
5298 ir_node *block = get_nodes_block(node);
5299 ir_node *new_block = be_transform_node(block);
5303 ir_node *trampoline;
5305 dbg_info *dbgi = get_irn_dbg_info(node);
5306 ia32_address_t addr;
5308 /* construct store address */
5309 memset(&addr, 0, sizeof(addr));
5310 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5312 if (addr.base == NULL) {
5313 addr.base = noreg_GP;
5315 addr.base = be_transform_node(addr.base);
5318 if (addr.index == NULL) {
5319 addr.index = noreg_GP;
5321 addr.index = be_transform_node(addr.index);
5323 addr.mem = be_transform_node(mem);
5325 /* mov ecx, <env> */
5326 val = ia32_create_Immediate(NULL, 0, 0xB9);
5327 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5328 addr.index, addr.mem, val);
5329 set_irn_pinned(store, get_irn_pinned(node));
5330 set_ia32_op_type(store, ia32_AddrModeD);
5331 set_ia32_ls_mode(store, mode_Bu);
5332 set_address(store, &addr);
5336 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5337 addr.index, addr.mem, env);
5338 set_irn_pinned(store, get_irn_pinned(node));
5339 set_ia32_op_type(store, ia32_AddrModeD);
5340 set_ia32_ls_mode(store, mode_Iu);
5341 set_address(store, &addr);
5345 /* jmp rel <callee> */
5346 val = ia32_create_Immediate(NULL, 0, 0xE9);
5347 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5348 addr.index, addr.mem, val);
5349 set_irn_pinned(store, get_irn_pinned(node));
5350 set_ia32_op_type(store, ia32_AddrModeD);
5351 set_ia32_ls_mode(store, mode_Bu);
5352 set_address(store, &addr);
5356 trampoline = be_transform_node(ptr);
5358 /* the callee is typically an immediate */
5359 if (is_SymConst(callee)) {
5360 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5362 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5363 add_ia32_am_offs_int(rel, -10);
5365 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5367 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5368 addr.index, addr.mem, rel);
5369 set_irn_pinned(store, get_irn_pinned(node));
5370 set_ia32_op_type(store, ia32_AddrModeD);
5371 set_ia32_ls_mode(store, mode_Iu);
5372 set_address(store, &addr);
5377 return new_r_Tuple(new_block, 2, in);
5381 * Transform Builtin node.
5383 static ir_node *gen_Builtin(ir_node *node)
5385 ir_builtin_kind kind = get_Builtin_kind(node);
5389 return gen_trap(node);
5390 case ir_bk_debugbreak:
5391 return gen_debugbreak(node);
5392 case ir_bk_return_address:
5393 return gen_return_address(node);
5394 case ir_bk_frame_address:
5395 return gen_frame_address(node);
5396 case ir_bk_prefetch:
5397 return gen_prefetch(node);
5399 return gen_ffs(node);
5401 return gen_clz(node);
5403 return gen_ctz(node);
5405 return gen_parity(node);
5406 case ir_bk_popcount:
5407 return gen_popcount(node);
5409 return gen_bswap(node);
5411 return gen_outport(node);
5413 return gen_inport(node);
5414 case ir_bk_inner_trampoline:
5415 return gen_inner_trampoline(node);
5417 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5421 * Transform Proj(Builtin) node.
5423 static ir_node *gen_Proj_Builtin(ir_node *proj)
5425 ir_node *node = get_Proj_pred(proj);
5426 ir_node *new_node = be_transform_node(node);
5427 ir_builtin_kind kind = get_Builtin_kind(node);
5430 case ir_bk_return_address:
5431 case ir_bk_frame_address:
5436 case ir_bk_popcount:
5438 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5441 case ir_bk_debugbreak:
5442 case ir_bk_prefetch:
5444 assert(get_Proj_proj(proj) == pn_Builtin_M);
5447 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5448 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5450 assert(get_Proj_proj(proj) == pn_Builtin_M);
5451 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5453 case ir_bk_inner_trampoline:
5454 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5455 return get_Tuple_pred(new_node, 1);
5457 assert(get_Proj_proj(proj) == pn_Builtin_M);
5458 return get_Tuple_pred(new_node, 0);
5461 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5464 static ir_node *gen_be_IncSP(ir_node *node)
5466 ir_node *res = be_duplicate_node(node);
5467 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5473 * Transform the Projs from a be_Call.
5475 static ir_node *gen_Proj_be_Call(ir_node *node)
5477 ir_node *call = get_Proj_pred(node);
5478 ir_node *new_call = be_transform_node(call);
5479 dbg_info *dbgi = get_irn_dbg_info(node);
5480 long proj = get_Proj_proj(node);
5481 ir_mode *mode = get_irn_mode(node);
5484 if (proj == pn_be_Call_M_regular) {
5485 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5487 /* transform call modes */
5488 if (mode_is_data(mode)) {
5489 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5493 /* Map from be_Call to ia32_Call proj number */
5494 if (proj == pn_be_Call_sp) {
5495 proj = pn_ia32_Call_stack;
5496 } else if (proj == pn_be_Call_M_regular) {
5497 proj = pn_ia32_Call_M;
5499 arch_register_req_t const *const req = arch_get_register_req_out(node);
5500 int const n_outs = arch_irn_get_n_outs(new_call);
5503 assert(proj >= pn_be_Call_first_res);
5504 assert(req->type & arch_register_req_type_limited);
5506 for (i = 0; i < n_outs; ++i) {
5507 arch_register_req_t const *const new_req
5508 = arch_get_out_register_req(new_call, i);
5510 if (!(new_req->type & arch_register_req_type_limited) ||
5511 new_req->cls != req->cls ||
5512 *new_req->limited != *req->limited)
5521 res = new_rd_Proj(dbgi, new_call, mode, proj);
5523 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5525 case pn_ia32_Call_stack:
5526 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5529 case pn_ia32_Call_fpcw:
5530 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5538 * Transform the Projs from a Cmp.
5540 static ir_node *gen_Proj_Cmp(ir_node *node)
5542 /* this probably means not all mode_b nodes were lowered... */
5543 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5547 static ir_node *gen_Proj_ASM(ir_node *node)
5549 ir_mode *mode = get_irn_mode(node);
5550 ir_node *pred = get_Proj_pred(node);
5551 ir_node *new_pred = be_transform_node(pred);
5552 long pos = get_Proj_proj(node);
5554 if (mode == mode_M) {
5555 pos = arch_irn_get_n_outs(new_pred)-1;
5556 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5558 } else if (mode_is_float(mode)) {
5561 panic("unexpected proj mode at ASM");
5564 return new_r_Proj(new_pred, mode, pos);
5568 * Transform and potentially renumber Proj nodes.
5570 static ir_node *gen_Proj(ir_node *node)
5572 ir_node *pred = get_Proj_pred(node);
5575 switch (get_irn_opcode(pred)) {
5577 proj = get_Proj_proj(node);
5578 if (proj == pn_Store_M) {
5579 return be_transform_node(pred);
5581 panic("No idea how to transform proj->Store");
5584 return gen_Proj_Load(node);
5586 return gen_Proj_ASM(node);
5588 return gen_Proj_Builtin(node);
5590 return gen_Proj_Div(node);
5592 return gen_Proj_Mod(node);
5594 return gen_Proj_CopyB(node);
5596 return gen_Proj_be_SubSP(node);
5598 return gen_Proj_be_AddSP(node);
5600 return gen_Proj_be_Call(node);
5602 return gen_Proj_Cmp(node);
5604 proj = get_Proj_proj(node);
5606 case pn_Start_X_initial_exec: {
5607 ir_node *block = get_nodes_block(pred);
5608 ir_node *new_block = be_transform_node(block);
5609 dbg_info *dbgi = get_irn_dbg_info(node);
5610 /* we exchange the ProjX with a jump */
5611 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5619 if (is_ia32_l_FloattoLL(pred)) {
5620 return gen_Proj_l_FloattoLL(node);
5622 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5626 ir_mode *mode = get_irn_mode(node);
5627 if (ia32_mode_needs_gp_reg(mode)) {
5628 ir_node *new_pred = be_transform_node(pred);
5629 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5630 get_Proj_proj(node));
5631 new_proj->node_nr = node->node_nr;
5636 return be_duplicate_node(node);
5640 * Enters all transform functions into the generic pointer
5642 static void register_transformers(void)
5644 /* first clear the generic function pointer for all ops */
5645 be_start_transform_setup();
5647 be_set_transform_function(op_Add, gen_Add);
5648 be_set_transform_function(op_And, gen_And);
5649 be_set_transform_function(op_ASM, ia32_gen_ASM);
5650 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5651 be_set_transform_function(op_be_Call, gen_be_Call);
5652 be_set_transform_function(op_be_Copy, gen_be_Copy);
5653 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5654 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5655 be_set_transform_function(op_be_Return, gen_be_Return);
5656 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5657 be_set_transform_function(op_Builtin, gen_Builtin);
5658 be_set_transform_function(op_Cmp, gen_Cmp);
5659 be_set_transform_function(op_Cond, gen_Cond);
5660 be_set_transform_function(op_Const, gen_Const);
5661 be_set_transform_function(op_Conv, gen_Conv);
5662 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5663 be_set_transform_function(op_Div, gen_Div);
5664 be_set_transform_function(op_Eor, gen_Eor);
5665 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5666 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5667 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5668 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5669 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5670 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5671 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5672 be_set_transform_function(op_ia32_l_SarDep, gen_ia32_l_SarDep);
5673 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5674 be_set_transform_function(op_ia32_l_ShlDep, gen_ia32_l_ShlDep);
5675 be_set_transform_function(op_ia32_l_ShlD, gen_ia32_l_ShlD);
5676 be_set_transform_function(op_ia32_l_ShrDep, gen_ia32_l_ShrDep);
5677 be_set_transform_function(op_ia32_l_ShrD, gen_ia32_l_ShrD);
5678 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5679 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5680 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5681 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5682 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5683 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5684 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5685 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5686 be_set_transform_function(op_IJmp, gen_IJmp);
5687 be_set_transform_function(op_Jmp, gen_Jmp);
5688 be_set_transform_function(op_Load, gen_Load);
5689 be_set_transform_function(op_Minus, gen_Minus);
5690 be_set_transform_function(op_Mod, gen_Mod);
5691 be_set_transform_function(op_Mul, gen_Mul);
5692 be_set_transform_function(op_Mulh, gen_Mulh);
5693 be_set_transform_function(op_Mux, gen_Mux);
5694 be_set_transform_function(op_Not, gen_Not);
5695 be_set_transform_function(op_Or, gen_Or);
5696 be_set_transform_function(op_Phi, gen_Phi);
5697 be_set_transform_function(op_Proj, gen_Proj);
5698 be_set_transform_function(op_Rotl, gen_Rotl);
5699 be_set_transform_function(op_Shl, gen_Shl);
5700 be_set_transform_function(op_Shr, gen_Shr);
5701 be_set_transform_function(op_Shrs, gen_Shrs);
5702 be_set_transform_function(op_Store, gen_Store);
5703 be_set_transform_function(op_Sub, gen_Sub);
5704 be_set_transform_function(op_SymConst, gen_SymConst);
5705 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5709 * Pre-transform all unknown and noreg nodes.
5711 static void ia32_pretransform_node(void)
5713 ir_graph *irg = current_ir_graph;
5714 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5716 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5717 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5718 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5719 irg_data->get_eip = be_pre_transform_node(irg_data->get_eip);
5720 irg_data->fpu_trunc_mode = be_pre_transform_node(irg_data->fpu_trunc_mode);
5722 nomem = get_irg_no_mem(irg);
5723 noreg_GP = ia32_new_NoReg_gp(irg);
5729 * Post-process all calls if we are in SSE mode.
5730 * The ABI requires that the results are in st0, copy them
5731 * to a xmm register.
5733 static void postprocess_fp_call_results(void)
5737 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5738 ir_node *call = call_list[i];
5739 ir_type *mtp = call_types[i];
5742 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5743 ir_type *res_tp = get_method_res_type(mtp, j);
5744 ir_node *res, *new_res;
5745 const ir_edge_t *edge, *next;
5748 if (! is_atomic_type(res_tp)) {
5749 /* no floating point return */
5752 mode = get_type_mode(res_tp);
5753 if (! mode_is_float(mode)) {
5754 /* no floating point return */
5758 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5761 /* now patch the users */
5762 foreach_out_edge_safe(res, edge, next) {
5763 ir_node *succ = get_edge_src_irn(edge);
5766 if (be_is_Keep(succ))
5769 if (is_ia32_xStore(succ)) {
5770 /* an xStore can be patched into an vfst */
5771 dbg_info *db = get_irn_dbg_info(succ);
5772 ir_node *block = get_nodes_block(succ);
5773 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5774 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5775 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5776 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5777 ir_mode *mode = get_ia32_ls_mode(succ);
5779 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5780 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5781 if (is_ia32_use_frame(succ))
5782 set_ia32_use_frame(st);
5783 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5784 set_irn_pinned(st, get_irn_pinned(succ));
5785 set_ia32_op_type(st, ia32_AddrModeD);
5789 if (new_res == NULL) {
5790 dbg_info *db = get_irn_dbg_info(call);
5791 ir_node *block = get_nodes_block(call);
5792 ir_node *frame = get_irg_frame(current_ir_graph);
5793 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5794 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5795 ir_node *vfst, *xld, *new_mem;
5797 /* store st(0) on stack */
5798 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5799 set_ia32_op_type(vfst, ia32_AddrModeD);
5800 set_ia32_use_frame(vfst);
5802 /* load into SSE register */
5803 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5804 set_ia32_op_type(xld, ia32_AddrModeS);
5805 set_ia32_use_frame(xld);
5807 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5808 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5810 if (old_mem != NULL) {
5811 edges_reroute(old_mem, new_mem);
5815 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5822 /* do the transformation */
5823 void ia32_transform_graph(ir_graph *irg)
5827 register_transformers();
5828 initial_fpcw = NULL;
5829 ia32_no_pic_adjust = 0;
5831 be_timer_push(T_HEIGHTS);
5832 ia32_heights = heights_new(irg);
5833 be_timer_pop(T_HEIGHTS);
5834 ia32_calculate_non_address_mode_nodes(irg);
5836 /* the transform phase is not safe for CSE (yet) because several nodes get
5837 * attributes set after their creation */
5838 cse_last = get_opt_cse();
5841 call_list = NEW_ARR_F(ir_node *, 0);
5842 call_types = NEW_ARR_F(ir_type *, 0);
5843 be_transform_graph(irg, ia32_pretransform_node);
5845 if (ia32_cg_config.use_sse2)
5846 postprocess_fp_call_results();
5847 DEL_ARR_F(call_types);
5848 DEL_ARR_F(call_list);
5850 set_opt_cse(cse_last);
5852 ia32_free_non_address_mode_nodes();
5853 heights_free(ia32_heights);
5854 ia32_heights = NULL;
5857 void ia32_init_transform(void)
5859 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");