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(be_get_irg_abi(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 assert(addr->symconst_ent != NULL);
1216 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
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(mem_proj ? mem_proj : am.mem_proj, new_node);
2257 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2258 ir_node *ptr, ir_mode *mode,
2259 construct_unop_dest_func *func)
2261 ir_node *src_block = get_nodes_block(node);
2267 ia32_address_mode_t am;
2268 ia32_address_t *addr = &am.addr;
2270 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2273 memset(&am, 0, sizeof(am));
2274 build_address(&am, op, ia32_create_am_double_use);
2276 dbgi = get_irn_dbg_info(node);
2277 block = be_transform_node(src_block);
2278 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2279 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2280 set_address(new_node, addr);
2281 set_ia32_op_type(new_node, ia32_AddrModeD);
2282 set_ia32_ls_mode(new_node, mode);
2283 SET_IA32_ORIG_NODE(new_node, node);
2285 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2286 mem_proj = be_transform_node(am.mem_proj);
2287 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2292 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2294 ir_mode *mode = get_irn_mode(node);
2295 ir_node *mux_true = get_Mux_true(node);
2296 ir_node *mux_false = get_Mux_false(node);
2304 ia32_condition_code_t cc;
2305 ia32_address_t addr;
2307 if (get_mode_size_bits(mode) != 8)
2310 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2312 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2318 cond = get_Mux_sel(node);
2319 flags = get_flags_node(cond, &cc);
2320 /* we can't handle the float special cases with SetM */
2321 if (cc & ia32_cc_additional_float_cases)
2324 cc = ia32_negate_condition_code(cc);
2326 build_address_ptr(&addr, ptr, mem);
2328 dbgi = get_irn_dbg_info(node);
2329 block = get_nodes_block(node);
2330 new_block = be_transform_node(block);
2331 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2332 addr.index, addr.mem, flags, cc);
2333 set_address(new_node, &addr);
2334 set_ia32_op_type(new_node, ia32_AddrModeD);
2335 set_ia32_ls_mode(new_node, mode);
2336 SET_IA32_ORIG_NODE(new_node, node);
2341 static ir_node *try_create_dest_am(ir_node *node)
2343 ir_node *val = get_Store_value(node);
2344 ir_node *mem = get_Store_mem(node);
2345 ir_node *ptr = get_Store_ptr(node);
2346 ir_mode *mode = get_irn_mode(val);
2347 unsigned bits = get_mode_size_bits(mode);
2352 /* handle only GP modes for now... */
2353 if (!ia32_mode_needs_gp_reg(mode))
2357 /* store must be the only user of the val node */
2358 if (get_irn_n_edges(val) > 1)
2360 /* skip pointless convs */
2362 ir_node *conv_op = get_Conv_op(val);
2363 ir_mode *pred_mode = get_irn_mode(conv_op);
2364 if (!ia32_mode_needs_gp_reg(pred_mode))
2366 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2374 /* value must be in the same block */
2375 if (get_nodes_block(node) != get_nodes_block(val))
2378 switch (get_irn_opcode(val)) {
2380 op1 = get_Add_left(val);
2381 op2 = get_Add_right(val);
2382 if (ia32_cg_config.use_incdec) {
2383 if (is_Const_1(op2)) {
2384 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2386 } else if (is_Const_Minus_1(op2)) {
2387 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2391 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2392 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2393 match_commutative | match_immediate);
2396 op1 = get_Sub_left(val);
2397 op2 = get_Sub_right(val);
2398 if (is_Const(op2)) {
2399 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2401 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2402 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2406 op1 = get_And_left(val);
2407 op2 = get_And_right(val);
2408 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2409 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2410 match_commutative | match_immediate);
2413 op1 = get_Or_left(val);
2414 op2 = get_Or_right(val);
2415 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2416 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2417 match_commutative | match_immediate);
2420 op1 = get_Eor_left(val);
2421 op2 = get_Eor_right(val);
2422 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2423 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2424 match_commutative | match_immediate);
2427 op1 = get_Shl_left(val);
2428 op2 = get_Shl_right(val);
2429 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2430 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2434 op1 = get_Shr_left(val);
2435 op2 = get_Shr_right(val);
2436 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2437 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2441 op1 = get_Shrs_left(val);
2442 op2 = get_Shrs_right(val);
2443 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2444 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2448 op1 = get_Rotl_left(val);
2449 op2 = get_Rotl_right(val);
2450 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2451 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2454 /* TODO: match ROR patterns... */
2456 new_node = try_create_SetMem(val, ptr, mem);
2460 op1 = get_Minus_op(val);
2461 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2464 /* should be lowered already */
2465 assert(mode != mode_b);
2466 op1 = get_Not_op(val);
2467 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2473 if (new_node != NULL) {
2474 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2475 get_irn_pinned(node) == op_pin_state_pinned) {
2476 set_irn_pinned(new_node, op_pin_state_pinned);
2483 static bool possible_int_mode_for_fp(ir_mode *mode)
2487 if (!mode_is_signed(mode))
2489 size = get_mode_size_bits(mode);
2490 if (size != 16 && size != 32)
2495 static int is_float_to_int_conv(const ir_node *node)
2497 ir_mode *mode = get_irn_mode(node);
2501 if (!possible_int_mode_for_fp(mode))
2506 conv_op = get_Conv_op(node);
2507 conv_mode = get_irn_mode(conv_op);
2509 if (!mode_is_float(conv_mode))
2516 * Transform a Store(floatConst) into a sequence of
2519 * @return the created ia32 Store node
2521 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2523 ir_mode *mode = get_irn_mode(cns);
2524 unsigned size = get_mode_size_bytes(mode);
2525 ir_tarval *tv = get_Const_tarval(cns);
2526 ir_node *block = get_nodes_block(node);
2527 ir_node *new_block = be_transform_node(block);
2528 ir_node *ptr = get_Store_ptr(node);
2529 ir_node *mem = get_Store_mem(node);
2530 dbg_info *dbgi = get_irn_dbg_info(node);
2534 ia32_address_t addr;
2536 assert(size % 4 == 0);
2539 build_address_ptr(&addr, ptr, mem);
2543 get_tarval_sub_bits(tv, ofs) |
2544 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2545 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2546 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2547 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2549 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2550 addr.index, addr.mem, imm);
2552 set_irn_pinned(new_node, get_irn_pinned(node));
2553 set_ia32_op_type(new_node, ia32_AddrModeD);
2554 set_ia32_ls_mode(new_node, mode_Iu);
2555 set_address(new_node, &addr);
2556 SET_IA32_ORIG_NODE(new_node, node);
2559 ins[i++] = new_node;
2564 } while (size != 0);
2567 return new_rd_Sync(dbgi, new_block, i, ins);
2574 * Generate a vfist or vfisttp instruction.
2576 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2577 ir_node *mem, ir_node *val, ir_node **fist)
2581 if (ia32_cg_config.use_fisttp) {
2582 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2583 if other users exists */
2584 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2585 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2586 be_new_Keep(block, 1, &value);
2588 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2591 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2594 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2600 * Transforms a general (no special case) Store.
2602 * @return the created ia32 Store node
2604 static ir_node *gen_general_Store(ir_node *node)
2606 ir_node *val = get_Store_value(node);
2607 ir_mode *mode = get_irn_mode(val);
2608 ir_node *block = get_nodes_block(node);
2609 ir_node *new_block = be_transform_node(block);
2610 ir_node *ptr = get_Store_ptr(node);
2611 ir_node *mem = get_Store_mem(node);
2612 dbg_info *dbgi = get_irn_dbg_info(node);
2613 ir_node *new_val, *new_node, *store;
2614 ia32_address_t addr;
2616 /* check for destination address mode */
2617 new_node = try_create_dest_am(node);
2618 if (new_node != NULL)
2621 /* construct store address */
2622 memset(&addr, 0, sizeof(addr));
2623 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2625 if (addr.base == NULL) {
2626 addr.base = noreg_GP;
2628 addr.base = be_transform_node(addr.base);
2631 if (addr.index == NULL) {
2632 addr.index = noreg_GP;
2634 addr.index = be_transform_node(addr.index);
2636 addr.mem = be_transform_node(mem);
2638 if (mode_is_float(mode)) {
2639 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2641 while (is_Conv(val) && mode == get_irn_mode(val)) {
2642 ir_node *op = get_Conv_op(val);
2643 if (!mode_is_float(get_irn_mode(op)))
2647 new_val = be_transform_node(val);
2648 if (ia32_cg_config.use_sse2) {
2649 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2650 addr.index, addr.mem, new_val);
2652 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2653 addr.index, addr.mem, new_val, mode);
2656 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2657 val = get_Conv_op(val);
2659 /* TODO: is this optimisation still necessary at all (middleend)? */
2660 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2661 while (is_Conv(val)) {
2662 ir_node *op = get_Conv_op(val);
2663 if (!mode_is_float(get_irn_mode(op)))
2665 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2669 new_val = be_transform_node(val);
2670 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2672 new_val = create_immediate_or_transform(val, 0);
2673 assert(mode != mode_b);
2675 if (get_mode_size_bits(mode) == 8) {
2676 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2677 addr.index, addr.mem, new_val);
2679 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2680 addr.index, addr.mem, new_val);
2685 set_irn_pinned(store, get_irn_pinned(node));
2686 set_ia32_op_type(store, ia32_AddrModeD);
2687 set_ia32_ls_mode(store, mode);
2689 set_address(store, &addr);
2690 SET_IA32_ORIG_NODE(store, node);
2696 * Transforms a Store.
2698 * @return the created ia32 Store node
2700 static ir_node *gen_Store(ir_node *node)
2702 ir_node *val = get_Store_value(node);
2703 ir_mode *mode = get_irn_mode(val);
2705 if (mode_is_float(mode) && is_Const(val)) {
2706 /* We can transform every floating const store
2707 into a sequence of integer stores.
2708 If the constant is already in a register,
2709 it would be better to use it, but we don't
2710 have this information here. */
2711 return gen_float_const_Store(node, val);
2713 return gen_general_Store(node);
2717 * Transforms a Switch.
2719 * @return the created ia32 SwitchJmp node
2721 static ir_node *create_Switch(ir_node *node)
2723 dbg_info *dbgi = get_irn_dbg_info(node);
2724 ir_node *block = be_transform_node(get_nodes_block(node));
2725 ir_node *sel = get_Cond_selector(node);
2726 ir_node *new_sel = be_transform_node(sel);
2727 long switch_min = LONG_MAX;
2728 long switch_max = LONG_MIN;
2729 long default_pn = get_Cond_default_proj(node);
2731 const ir_edge_t *edge;
2733 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2735 /* determine the smallest switch case value */
2736 foreach_out_edge(node, edge) {
2737 ir_node *proj = get_edge_src_irn(edge);
2738 long pn = get_Proj_proj(proj);
2739 if (pn == default_pn)
2742 if (pn < switch_min)
2744 if (pn > switch_max)
2748 if ((unsigned long) (switch_max - switch_min) > 128000) {
2749 panic("Size of switch %+F bigger than 128000", node);
2752 if (switch_min != 0) {
2753 /* if smallest switch case is not 0 we need an additional sub */
2754 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2755 add_ia32_am_offs_int(new_sel, -switch_min);
2756 set_ia32_op_type(new_sel, ia32_AddrModeS);
2758 SET_IA32_ORIG_NODE(new_sel, node);
2761 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2762 SET_IA32_ORIG_NODE(new_node, node);
2768 * Transform a Cond node.
2770 static ir_node *gen_Cond(ir_node *node)
2772 ir_node *block = get_nodes_block(node);
2773 ir_node *new_block = be_transform_node(block);
2774 dbg_info *dbgi = get_irn_dbg_info(node);
2775 ir_node *sel = get_Cond_selector(node);
2776 ir_mode *sel_mode = get_irn_mode(sel);
2777 ir_node *flags = NULL;
2779 ia32_condition_code_t cc;
2781 if (sel_mode != mode_b) {
2782 return create_Switch(node);
2785 /* we get flags from a Cmp */
2786 flags = get_flags_node(sel, &cc);
2788 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2789 SET_IA32_ORIG_NODE(new_node, node);
2795 * Transform a be_Copy.
2797 static ir_node *gen_be_Copy(ir_node *node)
2799 ir_node *new_node = be_duplicate_node(node);
2800 ir_mode *mode = get_irn_mode(new_node);
2802 if (ia32_mode_needs_gp_reg(mode)) {
2803 set_irn_mode(new_node, mode_Iu);
2809 static ir_node *create_Fucom(ir_node *node)
2811 dbg_info *dbgi = get_irn_dbg_info(node);
2812 ir_node *block = get_nodes_block(node);
2813 ir_node *new_block = be_transform_node(block);
2814 ir_node *left = get_Cmp_left(node);
2815 ir_node *new_left = be_transform_node(left);
2816 ir_node *right = get_Cmp_right(node);
2820 if (ia32_cg_config.use_fucomi) {
2821 new_right = be_transform_node(right);
2822 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2824 set_ia32_commutative(new_node);
2825 SET_IA32_ORIG_NODE(new_node, node);
2827 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2828 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2830 new_right = be_transform_node(right);
2831 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2834 set_ia32_commutative(new_node);
2836 SET_IA32_ORIG_NODE(new_node, node);
2838 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2839 SET_IA32_ORIG_NODE(new_node, node);
2845 static ir_node *create_Ucomi(ir_node *node)
2847 dbg_info *dbgi = get_irn_dbg_info(node);
2848 ir_node *src_block = get_nodes_block(node);
2849 ir_node *new_block = be_transform_node(src_block);
2850 ir_node *left = get_Cmp_left(node);
2851 ir_node *right = get_Cmp_right(node);
2853 ia32_address_mode_t am;
2854 ia32_address_t *addr = &am.addr;
2856 match_arguments(&am, src_block, left, right, NULL,
2857 match_commutative | match_am);
2859 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2860 addr->mem, am.new_op1, am.new_op2,
2862 set_am_attributes(new_node, &am);
2864 SET_IA32_ORIG_NODE(new_node, node);
2866 new_node = fix_mem_proj(new_node, &am);
2872 * returns true if it is assured, that the upper bits of a node are "clean"
2873 * which means for a 16 or 8 bit value, that the upper bits in the register
2874 * are 0 for unsigned and a copy of the last significant bit for signed
2877 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2879 assert(ia32_mode_needs_gp_reg(mode));
2880 if (get_mode_size_bits(mode) >= 32)
2883 if (is_Proj(transformed_node))
2884 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2886 switch (get_ia32_irn_opcode(transformed_node)) {
2887 case iro_ia32_Conv_I2I:
2888 case iro_ia32_Conv_I2I8Bit: {
2889 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2890 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2892 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2899 if (mode_is_signed(mode)) {
2900 return false; /* TODO handle signed modes */
2902 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2903 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2904 const ia32_immediate_attr_t *attr
2905 = get_ia32_immediate_attr_const(right);
2906 if (attr->symconst == 0 &&
2907 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2911 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2915 /* TODO too conservative if shift amount is constant */
2916 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2919 if (!mode_is_signed(mode)) {
2921 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2922 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2924 /* TODO if one is known to be zero extended, then || is sufficient */
2929 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2930 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2932 case iro_ia32_Const:
2933 case iro_ia32_Immediate: {
2934 const ia32_immediate_attr_t *attr =
2935 get_ia32_immediate_attr_const(transformed_node);
2936 if (mode_is_signed(mode)) {
2937 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2938 return shifted == 0 || shifted == -1;
2940 unsigned long shifted = (unsigned long)attr->offset;
2941 shifted >>= get_mode_size_bits(mode);
2942 return shifted == 0;
2952 * Generate code for a Cmp.
2954 static ir_node *gen_Cmp(ir_node *node)
2956 dbg_info *dbgi = get_irn_dbg_info(node);
2957 ir_node *block = get_nodes_block(node);
2958 ir_node *new_block = be_transform_node(block);
2959 ir_node *left = get_Cmp_left(node);
2960 ir_node *right = get_Cmp_right(node);
2961 ir_mode *cmp_mode = get_irn_mode(left);
2963 ia32_address_mode_t am;
2964 ia32_address_t *addr = &am.addr;
2966 if (mode_is_float(cmp_mode)) {
2967 if (ia32_cg_config.use_sse2) {
2968 return create_Ucomi(node);
2970 return create_Fucom(node);
2974 assert(ia32_mode_needs_gp_reg(cmp_mode));
2976 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2977 if (is_Const_0(right) &&
2979 get_irn_n_edges(left) == 1) {
2980 /* Test(and_left, and_right) */
2981 ir_node *and_left = get_And_left(left);
2982 ir_node *and_right = get_And_right(left);
2984 /* matze: code here used mode instead of cmd_mode, I think it is always
2985 * the same as cmp_mode, but I leave this here to see if this is really
2988 assert(get_irn_mode(and_left) == cmp_mode);
2990 match_arguments(&am, block, and_left, and_right, NULL,
2992 match_am | match_8bit_am | match_16bit_am |
2993 match_am_and_immediates | match_immediate);
2995 /* use 32bit compare mode if possible since the opcode is smaller */
2996 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2997 upper_bits_clean(am.new_op2, cmp_mode)) {
2998 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3001 if (get_mode_size_bits(cmp_mode) == 8) {
3002 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3003 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3005 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3006 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3009 /* Cmp(left, right) */
3010 match_arguments(&am, block, left, right, NULL,
3011 match_commutative | match_am | match_8bit_am |
3012 match_16bit_am | match_am_and_immediates |
3014 /* use 32bit compare mode if possible since the opcode is smaller */
3015 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3016 upper_bits_clean(am.new_op2, cmp_mode)) {
3017 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3020 if (get_mode_size_bits(cmp_mode) == 8) {
3021 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3022 addr->index, addr->mem, am.new_op1,
3023 am.new_op2, am.ins_permuted);
3025 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3026 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3029 set_am_attributes(new_node, &am);
3030 set_ia32_ls_mode(new_node, cmp_mode);
3032 SET_IA32_ORIG_NODE(new_node, node);
3034 new_node = fix_mem_proj(new_node, &am);
3039 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3040 ia32_condition_code_t cc)
3042 dbg_info *dbgi = get_irn_dbg_info(node);
3043 ir_node *block = get_nodes_block(node);
3044 ir_node *new_block = be_transform_node(block);
3045 ir_node *val_true = get_Mux_true(node);
3046 ir_node *val_false = get_Mux_false(node);
3048 ia32_address_mode_t am;
3049 ia32_address_t *addr;
3051 assert(ia32_cg_config.use_cmov);
3052 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3056 match_arguments(&am, block, val_false, val_true, flags,
3057 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3059 if (am.ins_permuted)
3060 cc = ia32_negate_condition_code(cc);
3062 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3063 addr->mem, am.new_op1, am.new_op2, new_flags,
3065 set_am_attributes(new_node, &am);
3067 SET_IA32_ORIG_NODE(new_node, node);
3069 new_node = fix_mem_proj(new_node, &am);
3075 * Creates a ia32 Setcc instruction.
3077 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3078 ir_node *flags, ia32_condition_code_t cc,
3081 ir_mode *mode = get_irn_mode(orig_node);
3084 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3085 SET_IA32_ORIG_NODE(new_node, orig_node);
3087 /* we might need to conv the result up */
3088 if (get_mode_size_bits(mode) > 8) {
3089 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3090 nomem, new_node, mode_Bu);
3091 SET_IA32_ORIG_NODE(new_node, orig_node);
3098 * Create instruction for an unsigned Difference or Zero.
3100 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3102 ir_mode *mode = get_irn_mode(psi);
3112 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3113 match_mode_neutral | match_am | match_immediate | match_two_users);
3115 block = get_nodes_block(new_node);
3117 if (is_Proj(new_node)) {
3118 sub = get_Proj_pred(new_node);
3121 set_irn_mode(sub, mode_T);
3122 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3124 assert(is_ia32_Sub(sub));
3125 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3127 dbgi = get_irn_dbg_info(psi);
3128 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3129 notn = new_bd_ia32_Not(dbgi, block, sbb);
3131 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3132 set_ia32_commutative(new_node);
3137 * Create an const array of two float consts.
3139 * @param c0 the first constant
3140 * @param c1 the second constant
3141 * @param new_mode IN/OUT for the mode of the constants, if NULL
3142 * smallest possible mode will be used
3144 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3147 ir_mode *mode = *new_mode;
3149 ir_initializer_t *initializer;
3150 ir_tarval *tv0 = get_Const_tarval(c0);
3151 ir_tarval *tv1 = get_Const_tarval(c1);
3154 /* detect the best mode for the constants */
3155 mode = get_tarval_mode(tv0);
3157 if (mode != mode_F) {
3158 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3159 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3161 tv0 = tarval_convert_to(tv0, mode);
3162 tv1 = tarval_convert_to(tv1, mode);
3163 } else if (mode != mode_D) {
3164 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3165 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3167 tv0 = tarval_convert_to(tv0, mode);
3168 tv1 = tarval_convert_to(tv1, mode);
3175 tp = ia32_create_float_type(mode, 4);
3176 tp = ia32_create_float_array(tp);
3178 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3180 set_entity_ld_ident(ent, get_entity_ident(ent));
3181 set_entity_visibility(ent, ir_visibility_private);
3182 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3184 initializer = create_initializer_compound(2);
3186 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3187 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3189 set_entity_initializer(ent, initializer);
3196 * Possible transformations for creating a Setcc.
3198 enum setcc_transform_insn {
3211 typedef struct setcc_transform {
3213 ia32_condition_code_t cc;
3215 enum setcc_transform_insn transform;
3219 } setcc_transform_t;
3222 * Setcc can only handle 0 and 1 result.
3223 * Find a transformation that creates 0 and 1 from
3226 static void find_const_transform(ia32_condition_code_t cc,
3227 ir_tarval *t, ir_tarval *f,
3228 setcc_transform_t *res)
3234 if (tarval_is_null(t)) {
3238 cc = ia32_negate_condition_code(cc);
3239 } else if (tarval_cmp(t, f) == ir_relation_less) {
3240 // now, t is the bigger one
3244 cc = ia32_negate_condition_code(cc);
3248 if (! tarval_is_null(f)) {
3249 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3252 res->steps[step].transform = SETCC_TR_ADD;
3254 if (t == tarval_bad)
3255 panic("constant subtract failed");
3256 if (! tarval_is_long(f))
3257 panic("tarval is not long");
3259 res->steps[step].val = get_tarval_long(f);
3261 f = tarval_sub(f, f, NULL);
3262 assert(tarval_is_null(f));
3265 if (tarval_is_one(t)) {
3266 res->steps[step].transform = SETCC_TR_SET;
3267 res->num_steps = ++step;
3271 if (tarval_is_minus_one(t)) {
3272 res->steps[step].transform = SETCC_TR_NEG;
3274 res->steps[step].transform = SETCC_TR_SET;
3275 res->num_steps = ++step;
3278 if (tarval_is_long(t)) {
3279 long v = get_tarval_long(t);
3281 res->steps[step].val = 0;
3284 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3286 res->steps[step].transform = SETCC_TR_LEAxx;
3287 res->steps[step].scale = 3; /* (a << 3) + a */
3290 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3292 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3293 res->steps[step].scale = 3; /* (a << 3) */
3296 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3298 res->steps[step].transform = SETCC_TR_LEAxx;
3299 res->steps[step].scale = 2; /* (a << 2) + a */
3302 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3304 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3305 res->steps[step].scale = 2; /* (a << 2) */
3308 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3310 res->steps[step].transform = SETCC_TR_LEAxx;
3311 res->steps[step].scale = 1; /* (a << 1) + a */
3314 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3316 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3317 res->steps[step].scale = 1; /* (a << 1) */
3320 res->num_steps = step;
3323 if (! tarval_is_single_bit(t)) {
3324 res->steps[step].transform = SETCC_TR_AND;
3325 res->steps[step].val = v;
3327 res->steps[step].transform = SETCC_TR_NEG;
3329 int v = get_tarval_lowest_bit(t);
3332 res->steps[step].transform = SETCC_TR_SHL;
3333 res->steps[step].scale = v;
3337 res->steps[step].transform = SETCC_TR_SET;
3338 res->num_steps = ++step;
3341 panic("tarval is not long");
3345 * Transforms a Mux node into some code sequence.
3347 * @return The transformed node.
3349 static ir_node *gen_Mux(ir_node *node)
3351 dbg_info *dbgi = get_irn_dbg_info(node);
3352 ir_node *block = get_nodes_block(node);
3353 ir_node *new_block = be_transform_node(block);
3354 ir_node *mux_true = get_Mux_true(node);
3355 ir_node *mux_false = get_Mux_false(node);
3356 ir_node *sel = get_Mux_sel(node);
3357 ir_mode *mode = get_irn_mode(node);
3361 ia32_condition_code_t cc;
3363 assert(get_irn_mode(sel) == mode_b);
3365 is_abs = be_mux_is_abs(sel, mux_true, mux_false);
3367 return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
3370 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3371 if (mode_is_float(mode)) {
3372 ir_node *cmp_left = get_Cmp_left(sel);
3373 ir_node *cmp_right = get_Cmp_right(sel);
3374 ir_relation relation = get_Cmp_relation(sel);
3376 if (ia32_cg_config.use_sse2) {
3377 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3378 if (cmp_left == mux_true && cmp_right == mux_false) {
3379 /* Mux(a <= b, a, b) => MIN */
3380 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3381 match_commutative | match_am | match_two_users);
3382 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3383 /* Mux(a <= b, b, a) => MAX */
3384 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3385 match_commutative | match_am | match_two_users);
3387 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3388 if (cmp_left == mux_true && cmp_right == mux_false) {
3389 /* Mux(a >= b, a, b) => MAX */
3390 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3391 match_commutative | match_am | match_two_users);
3392 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3393 /* Mux(a >= b, b, a) => MIN */
3394 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3395 match_commutative | match_am | match_two_users);
3400 if (is_Const(mux_true) && is_Const(mux_false)) {
3401 ia32_address_mode_t am;
3406 flags = get_flags_node(sel, &cc);
3407 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3409 if (ia32_cg_config.use_sse2) {
3410 /* cannot load from different mode on SSE */
3413 /* x87 can load any mode */
3417 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3419 switch (get_mode_size_bytes(new_mode)) {
3429 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3430 set_ia32_am_scale(new_node, 2);
3435 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3436 set_ia32_am_scale(new_node, 1);
3439 /* arg, shift 16 NOT supported */
3441 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3444 panic("Unsupported constant size");
3447 am.ls_mode = new_mode;
3448 am.addr.base = get_symconst_base();
3449 am.addr.index = new_node;
3450 am.addr.mem = nomem;
3452 am.addr.scale = scale;
3453 am.addr.use_frame = 0;
3454 am.addr.frame_entity = NULL;
3455 am.addr.symconst_sign = 0;
3456 am.mem_proj = am.addr.mem;
3457 am.op_type = ia32_AddrModeS;
3460 am.pinned = op_pin_state_floats;
3462 am.ins_permuted = false;
3464 if (ia32_cg_config.use_sse2)
3465 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3467 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3468 set_am_attributes(load, &am);
3470 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3472 panic("cannot transform floating point Mux");
3475 assert(ia32_mode_needs_gp_reg(mode));
3478 ir_node *cmp_left = get_Cmp_left(sel);
3479 ir_node *cmp_right = get_Cmp_right(sel);
3480 ir_relation relation = get_Cmp_relation(sel);
3481 ir_node *val_true = mux_true;
3482 ir_node *val_false = mux_false;
3484 if (is_Const(val_true) && is_Const_null(val_true)) {
3485 ir_node *tmp = val_false;
3486 val_false = val_true;
3488 relation = get_negated_relation(relation);
3490 if (is_Const_0(val_false) && is_Sub(val_true)) {
3491 if ((relation & ir_relation_greater)
3492 && get_Sub_left(val_true) == cmp_left
3493 && get_Sub_right(val_true) == cmp_right) {
3494 return create_doz(node, cmp_left, cmp_right);
3496 if ((relation & ir_relation_less)
3497 && get_Sub_left(val_true) == cmp_right
3498 && get_Sub_right(val_true) == cmp_left) {
3499 return create_doz(node, cmp_right, cmp_left);
3504 flags = get_flags_node(sel, &cc);
3506 if (is_Const(mux_true) && is_Const(mux_false)) {
3507 /* both are const, good */
3508 ir_tarval *tv_true = get_Const_tarval(mux_true);
3509 ir_tarval *tv_false = get_Const_tarval(mux_false);
3510 setcc_transform_t res;
3513 find_const_transform(cc, tv_true, tv_false, &res);
3515 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3518 switch (res.steps[step].transform) {
3520 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3521 add_ia32_am_offs_int(new_node, res.steps[step].val);
3523 case SETCC_TR_ADDxx:
3524 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3527 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3528 set_ia32_am_scale(new_node, res.steps[step].scale);
3529 set_ia32_am_offs_int(new_node, res.steps[step].val);
3531 case SETCC_TR_LEAxx:
3532 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3533 set_ia32_am_scale(new_node, res.steps[step].scale);
3534 set_ia32_am_offs_int(new_node, res.steps[step].val);
3537 imm = ia32_immediate_from_long(res.steps[step].scale);
3538 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3541 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3544 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3547 imm = ia32_immediate_from_long(res.steps[step].val);
3548 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3551 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3554 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3557 panic("unknown setcc transform");
3561 new_node = create_CMov(node, sel, flags, cc);
3569 * Create a conversion from x87 state register to general purpose.
3571 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3573 ir_node *block = be_transform_node(get_nodes_block(node));
3574 ir_node *op = get_Conv_op(node);
3575 ir_node *new_op = be_transform_node(op);
3576 ir_graph *irg = current_ir_graph;
3577 dbg_info *dbgi = get_irn_dbg_info(node);
3578 ir_mode *mode = get_irn_mode(node);
3579 ir_node *fist, *load, *mem;
3581 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3582 set_irn_pinned(fist, op_pin_state_floats);
3583 set_ia32_use_frame(fist);
3584 set_ia32_op_type(fist, ia32_AddrModeD);
3586 assert(get_mode_size_bits(mode) <= 32);
3587 /* exception we can only store signed 32 bit integers, so for unsigned
3588 we store a 64bit (signed) integer and load the lower bits */
3589 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3590 set_ia32_ls_mode(fist, mode_Ls);
3592 set_ia32_ls_mode(fist, mode_Is);
3594 SET_IA32_ORIG_NODE(fist, node);
3597 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3599 set_irn_pinned(load, op_pin_state_floats);
3600 set_ia32_use_frame(load);
3601 set_ia32_op_type(load, ia32_AddrModeS);
3602 set_ia32_ls_mode(load, mode_Is);
3603 if (get_ia32_ls_mode(fist) == mode_Ls) {
3604 ia32_attr_t *attr = get_ia32_attr(load);
3605 attr->data.need_64bit_stackent = 1;
3607 ia32_attr_t *attr = get_ia32_attr(load);
3608 attr->data.need_32bit_stackent = 1;
3610 SET_IA32_ORIG_NODE(load, node);
3612 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3616 * Creates a x87 strict Conv by placing a Store and a Load
3618 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3620 ir_node *block = get_nodes_block(node);
3621 ir_graph *irg = get_Block_irg(block);
3622 dbg_info *dbgi = get_irn_dbg_info(node);
3623 ir_node *frame = get_irg_frame(irg);
3624 ir_node *store, *load;
3627 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3628 set_ia32_use_frame(store);
3629 set_ia32_op_type(store, ia32_AddrModeD);
3630 SET_IA32_ORIG_NODE(store, node);
3632 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3633 set_ia32_use_frame(load);
3634 set_ia32_op_type(load, ia32_AddrModeS);
3635 SET_IA32_ORIG_NODE(load, node);
3637 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3641 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3642 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3644 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3646 func = get_mode_size_bits(mode) == 8 ?
3647 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3648 return func(dbgi, block, base, index, mem, val, mode);
3652 * Create a conversion from general purpose to x87 register
3654 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3656 ir_node *src_block = get_nodes_block(node);
3657 ir_node *block = be_transform_node(src_block);
3658 ir_graph *irg = get_Block_irg(block);
3659 dbg_info *dbgi = get_irn_dbg_info(node);
3660 ir_node *op = get_Conv_op(node);
3661 ir_node *new_op = NULL;
3663 ir_mode *store_mode;
3668 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3669 if (possible_int_mode_for_fp(src_mode)) {
3670 ia32_address_mode_t am;
3672 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3673 if (am.op_type == ia32_AddrModeS) {
3674 ia32_address_t *addr = &am.addr;
3676 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3677 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3679 set_am_attributes(fild, &am);
3680 SET_IA32_ORIG_NODE(fild, node);
3682 fix_mem_proj(fild, &am);
3687 if (new_op == NULL) {
3688 new_op = be_transform_node(op);
3691 mode = get_irn_mode(op);
3693 /* first convert to 32 bit signed if necessary */
3694 if (get_mode_size_bits(src_mode) < 32) {
3695 if (!upper_bits_clean(new_op, src_mode)) {
3696 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3697 SET_IA32_ORIG_NODE(new_op, node);
3702 assert(get_mode_size_bits(mode) == 32);
3705 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3707 set_ia32_use_frame(store);
3708 set_ia32_op_type(store, ia32_AddrModeD);
3709 set_ia32_ls_mode(store, mode_Iu);
3711 /* exception for 32bit unsigned, do a 64bit spill+load */
3712 if (!mode_is_signed(mode)) {
3715 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3717 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3718 noreg_GP, nomem, zero_const);
3720 set_ia32_use_frame(zero_store);
3721 set_ia32_op_type(zero_store, ia32_AddrModeD);
3722 add_ia32_am_offs_int(zero_store, 4);
3723 set_ia32_ls_mode(zero_store, mode_Iu);
3728 store = new_rd_Sync(dbgi, block, 2, in);
3729 store_mode = mode_Ls;
3731 store_mode = mode_Is;
3735 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3737 set_ia32_use_frame(fild);
3738 set_ia32_op_type(fild, ia32_AddrModeS);
3739 set_ia32_ls_mode(fild, store_mode);
3741 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3747 * Create a conversion from one integer mode into another one
3749 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3750 dbg_info *dbgi, ir_node *block, ir_node *op,
3753 ir_node *new_block = be_transform_node(block);
3755 ir_mode *smaller_mode;
3756 ia32_address_mode_t am;
3757 ia32_address_t *addr = &am.addr;
3760 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3761 smaller_mode = src_mode;
3763 smaller_mode = tgt_mode;
3766 #ifdef DEBUG_libfirm
3768 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3773 match_arguments(&am, block, NULL, op, NULL,
3774 match_am | match_8bit_am | match_16bit_am);
3776 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3777 /* unnecessary conv. in theory it shouldn't have been AM */
3778 assert(is_ia32_NoReg_GP(addr->base));
3779 assert(is_ia32_NoReg_GP(addr->index));
3780 assert(is_NoMem(addr->mem));
3781 assert(am.addr.offset == 0);
3782 assert(am.addr.symconst_ent == NULL);
3786 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3787 addr->mem, am.new_op2, smaller_mode);
3788 set_am_attributes(new_node, &am);
3789 /* match_arguments assume that out-mode = in-mode, this isn't true here
3791 set_ia32_ls_mode(new_node, smaller_mode);
3792 SET_IA32_ORIG_NODE(new_node, node);
3793 new_node = fix_mem_proj(new_node, &am);
3798 * Transforms a Conv node.
3800 * @return The created ia32 Conv node
3802 static ir_node *gen_Conv(ir_node *node)
3804 ir_node *block = get_nodes_block(node);
3805 ir_node *new_block = be_transform_node(block);
3806 ir_node *op = get_Conv_op(node);
3807 ir_node *new_op = NULL;
3808 dbg_info *dbgi = get_irn_dbg_info(node);
3809 ir_mode *src_mode = get_irn_mode(op);
3810 ir_mode *tgt_mode = get_irn_mode(node);
3811 int src_bits = get_mode_size_bits(src_mode);
3812 int tgt_bits = get_mode_size_bits(tgt_mode);
3813 ir_node *res = NULL;
3815 assert(!mode_is_int(src_mode) || src_bits <= 32);
3816 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3818 /* modeB -> X should already be lowered by the lower_mode_b pass */
3819 if (src_mode == mode_b) {
3820 panic("ConvB not lowered %+F", node);
3823 if (src_mode == tgt_mode) {
3824 if (get_Conv_strict(node)) {
3825 if (ia32_cg_config.use_sse2) {
3826 /* when we are in SSE mode, we can kill all strict no-op conversion */
3827 return be_transform_node(op);
3830 /* this should be optimized already, but who knows... */
3831 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3832 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3833 return be_transform_node(op);
3837 if (mode_is_float(src_mode)) {
3838 new_op = be_transform_node(op);
3839 /* we convert from float ... */
3840 if (mode_is_float(tgt_mode)) {
3842 if (ia32_cg_config.use_sse2) {
3843 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3844 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3846 set_ia32_ls_mode(res, tgt_mode);
3848 if (get_Conv_strict(node)) {
3849 /* if fp_no_float_fold is not set then we assume that we
3850 * don't have any float operations in a non
3851 * mode_float_arithmetic mode and can skip strict upconvs */
3852 if (src_bits < tgt_bits) {
3853 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3856 res = gen_x87_strict_conv(tgt_mode, new_op);
3857 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3861 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3866 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3867 if (ia32_cg_config.use_sse2) {
3868 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3870 set_ia32_ls_mode(res, src_mode);
3872 return gen_x87_fp_to_gp(node);
3876 /* we convert from int ... */
3877 if (mode_is_float(tgt_mode)) {
3879 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3880 if (ia32_cg_config.use_sse2) {
3881 new_op = be_transform_node(op);
3882 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3884 set_ia32_ls_mode(res, tgt_mode);
3886 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3887 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3888 res = gen_x87_gp_to_fp(node, src_mode);
3890 /* we need a strict-Conv, if the int mode has more bits than the
3892 if (float_mantissa < int_mantissa) {
3893 res = gen_x87_strict_conv(tgt_mode, res);
3894 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3898 } else if (tgt_mode == mode_b) {
3899 /* mode_b lowering already took care that we only have 0/1 values */
3900 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3901 src_mode, tgt_mode));
3902 return be_transform_node(op);
3905 if (src_bits == tgt_bits) {
3906 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3907 src_mode, tgt_mode));
3908 return be_transform_node(op);
3911 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3919 static ir_node *create_immediate_or_transform(ir_node *node,
3920 char immediate_constraint_type)
3922 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3923 if (new_node == NULL) {
3924 new_node = be_transform_node(node);
3930 * Transforms a FrameAddr into an ia32 Add.
3932 static ir_node *gen_be_FrameAddr(ir_node *node)
3934 ir_node *block = be_transform_node(get_nodes_block(node));
3935 ir_node *op = be_get_FrameAddr_frame(node);
3936 ir_node *new_op = be_transform_node(op);
3937 dbg_info *dbgi = get_irn_dbg_info(node);
3940 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3941 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3942 set_ia32_use_frame(new_node);
3944 SET_IA32_ORIG_NODE(new_node, node);
3950 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3952 static ir_node *gen_be_Return(ir_node *node)
3954 ir_graph *irg = current_ir_graph;
3955 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3956 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3957 ir_node *new_ret_val = be_transform_node(ret_val);
3958 ir_node *new_ret_mem = be_transform_node(ret_mem);
3959 ir_entity *ent = get_irg_entity(irg);
3960 ir_type *tp = get_entity_type(ent);
3961 dbg_info *dbgi = get_irn_dbg_info(node);
3962 ir_node *block = be_transform_node(get_nodes_block(node));
3965 ir_node *frame, *sse_store, *fld, *mproj;
3972 assert(ret_val != NULL);
3973 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3974 return be_duplicate_node(node);
3977 res_type = get_method_res_type(tp, 0);
3979 if (! is_Primitive_type(res_type)) {
3980 return be_duplicate_node(node);
3983 mode = get_type_mode(res_type);
3984 if (! mode_is_float(mode)) {
3985 return be_duplicate_node(node);
3988 assert(get_method_n_ress(tp) == 1);
3990 frame = get_irg_frame(irg);
3992 /* store xmm0 onto stack */
3993 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3994 new_ret_mem, new_ret_val);
3995 set_ia32_ls_mode(sse_store, mode);
3996 set_ia32_op_type(sse_store, ia32_AddrModeD);
3997 set_ia32_use_frame(sse_store);
3999 /* load into x87 register */
4000 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4001 set_ia32_op_type(fld, ia32_AddrModeS);
4002 set_ia32_use_frame(fld);
4004 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4005 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4007 /* create a new return */
4008 arity = get_irn_arity(node);
4009 in = ALLOCAN(ir_node*, arity);
4010 pop = be_Return_get_pop(node);
4011 for (i = 0; i < arity; ++i) {
4012 ir_node *op = get_irn_n(node, i);
4013 if (op == ret_val) {
4015 } else if (op == ret_mem) {
4018 in[i] = be_transform_node(op);
4021 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4022 copy_node_attr(irg, node, new_node);
4028 * Transform a be_AddSP into an ia32_SubSP.
4030 static ir_node *gen_be_AddSP(ir_node *node)
4032 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4033 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4035 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4036 match_am | match_immediate);
4037 assert(is_ia32_SubSP(new_node));
4038 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4039 &ia32_registers[REG_ESP]);
4044 * Transform a be_SubSP into an ia32_AddSP
4046 static ir_node *gen_be_SubSP(ir_node *node)
4048 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4049 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4051 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4052 match_am | match_immediate);
4053 assert(is_ia32_AddSP(new_node));
4054 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4055 &ia32_registers[REG_ESP]);
4060 * Change some phi modes
4062 static ir_node *gen_Phi(ir_node *node)
4064 const arch_register_req_t *req;
4065 ir_node *block = be_transform_node(get_nodes_block(node));
4066 ir_graph *irg = current_ir_graph;
4067 dbg_info *dbgi = get_irn_dbg_info(node);
4068 ir_mode *mode = get_irn_mode(node);
4071 if (ia32_mode_needs_gp_reg(mode)) {
4072 /* we shouldn't have any 64bit stuff around anymore */
4073 assert(get_mode_size_bits(mode) <= 32);
4074 /* all integer operations are on 32bit registers now */
4076 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4077 } else if (mode_is_float(mode)) {
4078 if (ia32_cg_config.use_sse2) {
4080 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4083 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4086 req = arch_no_register_req;
4089 /* phi nodes allow loops, so we use the old arguments for now
4090 * and fix this later */
4091 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4092 get_irn_in(node) + 1);
4093 copy_node_attr(irg, node, phi);
4094 be_duplicate_deps(node, phi);
4096 arch_set_out_register_req(phi, 0, req);
4098 be_enqueue_preds(node);
4103 static ir_node *gen_Jmp(ir_node *node)
4105 ir_node *block = get_nodes_block(node);
4106 ir_node *new_block = be_transform_node(block);
4107 dbg_info *dbgi = get_irn_dbg_info(node);
4110 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4111 SET_IA32_ORIG_NODE(new_node, node);
4119 static ir_node *gen_IJmp(ir_node *node)
4121 ir_node *block = get_nodes_block(node);
4122 ir_node *new_block = be_transform_node(block);
4123 dbg_info *dbgi = get_irn_dbg_info(node);
4124 ir_node *op = get_IJmp_target(node);
4126 ia32_address_mode_t am;
4127 ia32_address_t *addr = &am.addr;
4129 assert(get_irn_mode(op) == mode_P);
4131 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4133 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4134 addr->mem, am.new_op2);
4135 set_am_attributes(new_node, &am);
4136 SET_IA32_ORIG_NODE(new_node, node);
4138 new_node = fix_mem_proj(new_node, &am);
4143 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4145 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4146 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4148 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4149 match_immediate | match_mode_neutral);
4152 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4154 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4155 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4156 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4160 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4162 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4163 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4164 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4168 static ir_node *gen_ia32_l_Add(ir_node *node)
4170 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4171 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4172 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4173 match_commutative | match_am | match_immediate |
4174 match_mode_neutral);
4176 if (is_Proj(lowered)) {
4177 lowered = get_Proj_pred(lowered);
4179 assert(is_ia32_Add(lowered));
4180 set_irn_mode(lowered, mode_T);
4186 static ir_node *gen_ia32_l_Adc(ir_node *node)
4188 return gen_binop_flags(node, new_bd_ia32_Adc,
4189 match_commutative | match_am | match_immediate |
4190 match_mode_neutral);
4194 * Transforms a l_MulS into a "real" MulS node.
4196 * @return the created ia32 Mul node
4198 static ir_node *gen_ia32_l_Mul(ir_node *node)
4200 ir_node *left = get_binop_left(node);
4201 ir_node *right = get_binop_right(node);
4203 return gen_binop(node, left, right, new_bd_ia32_Mul,
4204 match_commutative | match_am | match_mode_neutral);
4208 * Transforms a l_IMulS into a "real" IMul1OPS node.
4210 * @return the created ia32 IMul1OP node
4212 static ir_node *gen_ia32_l_IMul(ir_node *node)
4214 ir_node *left = get_binop_left(node);
4215 ir_node *right = get_binop_right(node);
4217 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4218 match_commutative | match_am | match_mode_neutral);
4221 static ir_node *gen_ia32_l_Sub(ir_node *node)
4223 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4224 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4225 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4226 match_am | match_immediate | match_mode_neutral);
4228 if (is_Proj(lowered)) {
4229 lowered = get_Proj_pred(lowered);
4231 assert(is_ia32_Sub(lowered));
4232 set_irn_mode(lowered, mode_T);
4238 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4240 return gen_binop_flags(node, new_bd_ia32_Sbb,
4241 match_am | match_immediate | match_mode_neutral);
4245 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4246 * op1 - target to be shifted
4247 * op2 - contains bits to be shifted into target
4249 * Only op3 can be an immediate.
4251 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4252 ir_node *low, ir_node *count)
4254 ir_node *block = get_nodes_block(node);
4255 ir_node *new_block = be_transform_node(block);
4256 dbg_info *dbgi = get_irn_dbg_info(node);
4257 ir_node *new_high = be_transform_node(high);
4258 ir_node *new_low = be_transform_node(low);
4262 /* the shift amount can be any mode that is bigger than 5 bits, since all
4263 * other bits are ignored anyway */
4264 while (is_Conv(count) &&
4265 get_irn_n_edges(count) == 1 &&
4266 mode_is_int(get_irn_mode(count))) {
4267 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4268 count = get_Conv_op(count);
4270 new_count = create_immediate_or_transform(count, 0);
4272 if (is_ia32_l_ShlD(node)) {
4273 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4276 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4279 SET_IA32_ORIG_NODE(new_node, node);
4284 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4286 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4287 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4288 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4289 return gen_lowered_64bit_shifts(node, high, low, count);
4292 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4294 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4295 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4296 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4297 return gen_lowered_64bit_shifts(node, high, low, count);
4300 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4302 ir_node *src_block = get_nodes_block(node);
4303 ir_node *block = be_transform_node(src_block);
4304 ir_graph *irg = current_ir_graph;
4305 dbg_info *dbgi = get_irn_dbg_info(node);
4306 ir_node *frame = get_irg_frame(irg);
4307 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4308 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4309 ir_node *new_val_low = be_transform_node(val_low);
4310 ir_node *new_val_high = be_transform_node(val_high);
4312 ir_node *sync, *fild, *res;
4313 ir_node *store_low, *store_high;
4315 if (ia32_cg_config.use_sse2) {
4316 panic("ia32_l_LLtoFloat not implemented for SSE2");
4320 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4322 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4324 SET_IA32_ORIG_NODE(store_low, node);
4325 SET_IA32_ORIG_NODE(store_high, node);
4327 set_ia32_use_frame(store_low);
4328 set_ia32_use_frame(store_high);
4329 set_ia32_op_type(store_low, ia32_AddrModeD);
4330 set_ia32_op_type(store_high, ia32_AddrModeD);
4331 set_ia32_ls_mode(store_low, mode_Iu);
4332 set_ia32_ls_mode(store_high, mode_Is);
4333 add_ia32_am_offs_int(store_high, 4);
4337 sync = new_rd_Sync(dbgi, block, 2, in);
4340 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4342 set_ia32_use_frame(fild);
4343 set_ia32_op_type(fild, ia32_AddrModeS);
4344 set_ia32_ls_mode(fild, mode_Ls);
4346 SET_IA32_ORIG_NODE(fild, node);
4348 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4350 if (! mode_is_signed(get_irn_mode(val_high))) {
4351 ia32_address_mode_t am;
4353 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4356 am.addr.base = get_symconst_base();
4357 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4358 am.addr.mem = nomem;
4361 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4362 am.addr.tls_segment = false;
4363 am.addr.use_frame = 0;
4364 am.addr.frame_entity = NULL;
4365 am.addr.symconst_sign = 0;
4366 am.ls_mode = mode_F;
4367 am.mem_proj = nomem;
4368 am.op_type = ia32_AddrModeS;
4370 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4371 am.pinned = op_pin_state_floats;
4373 am.ins_permuted = false;
4375 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4376 am.new_op1, am.new_op2, get_fpcw());
4377 set_am_attributes(fadd, &am);
4379 set_irn_mode(fadd, mode_T);
4380 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4385 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4387 ir_node *src_block = get_nodes_block(node);
4388 ir_node *block = be_transform_node(src_block);
4389 ir_graph *irg = get_Block_irg(block);
4390 dbg_info *dbgi = get_irn_dbg_info(node);
4391 ir_node *frame = get_irg_frame(irg);
4392 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4393 ir_node *new_val = be_transform_node(val);
4394 ir_node *fist, *mem;
4396 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4397 SET_IA32_ORIG_NODE(fist, node);
4398 set_ia32_use_frame(fist);
4399 set_ia32_op_type(fist, ia32_AddrModeD);
4400 set_ia32_ls_mode(fist, mode_Ls);
4405 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4407 ir_node *block = be_transform_node(get_nodes_block(node));
4408 ir_graph *irg = get_Block_irg(block);
4409 ir_node *pred = get_Proj_pred(node);
4410 ir_node *new_pred = be_transform_node(pred);
4411 ir_node *frame = get_irg_frame(irg);
4412 dbg_info *dbgi = get_irn_dbg_info(node);
4413 long pn = get_Proj_proj(node);
4418 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4419 SET_IA32_ORIG_NODE(load, node);
4420 set_ia32_use_frame(load);
4421 set_ia32_op_type(load, ia32_AddrModeS);
4422 set_ia32_ls_mode(load, mode_Iu);
4423 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4424 * 32 bit from it with this particular load */
4425 attr = get_ia32_attr(load);
4426 attr->data.need_64bit_stackent = 1;
4428 if (pn == pn_ia32_l_FloattoLL_res_high) {
4429 add_ia32_am_offs_int(load, 4);
4431 assert(pn == pn_ia32_l_FloattoLL_res_low);
4434 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4440 * Transform the Projs of an AddSP.
4442 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4444 ir_node *pred = get_Proj_pred(node);
4445 ir_node *new_pred = be_transform_node(pred);
4446 dbg_info *dbgi = get_irn_dbg_info(node);
4447 long proj = get_Proj_proj(node);
4449 if (proj == pn_be_AddSP_sp) {
4450 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4451 pn_ia32_SubSP_stack);
4452 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4454 } else if (proj == pn_be_AddSP_res) {
4455 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4456 pn_ia32_SubSP_addr);
4457 } else if (proj == pn_be_AddSP_M) {
4458 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4461 panic("No idea how to transform proj->AddSP");
4465 * Transform the Projs of a SubSP.
4467 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4469 ir_node *pred = get_Proj_pred(node);
4470 ir_node *new_pred = be_transform_node(pred);
4471 dbg_info *dbgi = get_irn_dbg_info(node);
4472 long proj = get_Proj_proj(node);
4474 if (proj == pn_be_SubSP_sp) {
4475 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4476 pn_ia32_AddSP_stack);
4477 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4479 } else if (proj == pn_be_SubSP_M) {
4480 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4483 panic("No idea how to transform proj->SubSP");
4487 * Transform and renumber the Projs from a Load.
4489 static ir_node *gen_Proj_Load(ir_node *node)
4492 ir_node *block = be_transform_node(get_nodes_block(node));
4493 ir_node *pred = get_Proj_pred(node);
4494 dbg_info *dbgi = get_irn_dbg_info(node);
4495 long proj = get_Proj_proj(node);
4497 /* loads might be part of source address mode matches, so we don't
4498 * transform the ProjMs yet (with the exception of loads whose result is
4501 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4504 /* this is needed, because sometimes we have loops that are only
4505 reachable through the ProjM */
4506 be_enqueue_preds(node);
4507 /* do it in 2 steps, to silence firm verifier */
4508 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4509 set_Proj_proj(res, pn_ia32_mem);
4513 /* renumber the proj */
4514 new_pred = be_transform_node(pred);
4515 if (is_ia32_Load(new_pred)) {
4518 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4520 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4521 case pn_Load_X_regular:
4522 return new_rd_Jmp(dbgi, block);
4523 case pn_Load_X_except:
4524 /* This Load might raise an exception. Mark it. */
4525 set_ia32_exc_label(new_pred, 1);
4526 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4530 } else if (is_ia32_Conv_I2I(new_pred) ||
4531 is_ia32_Conv_I2I8Bit(new_pred)) {
4532 set_irn_mode(new_pred, mode_T);
4533 if (proj == pn_Load_res) {
4534 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4535 } else if (proj == pn_Load_M) {
4536 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4538 } else if (is_ia32_xLoad(new_pred)) {
4541 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4543 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4544 case pn_Load_X_regular:
4545 return new_rd_Jmp(dbgi, block);
4546 case pn_Load_X_except:
4547 /* This Load might raise an exception. Mark it. */
4548 set_ia32_exc_label(new_pred, 1);
4549 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4553 } else if (is_ia32_vfld(new_pred)) {
4556 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4558 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4559 case pn_Load_X_regular:
4560 return new_rd_Jmp(dbgi, block);
4561 case pn_Load_X_except:
4562 /* This Load might raise an exception. Mark it. */
4563 set_ia32_exc_label(new_pred, 1);
4564 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4569 /* can happen for ProJMs when source address mode happened for the
4572 /* however it should not be the result proj, as that would mean the
4573 load had multiple users and should not have been used for
4575 if (proj != pn_Load_M) {
4576 panic("internal error: transformed node not a Load");
4578 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4581 panic("No idea how to transform proj");
4585 * Transform and renumber the Projs from a Div or Mod instruction.
4587 static ir_node *gen_Proj_Div(ir_node *node)
4589 ir_node *block = be_transform_node(get_nodes_block(node));
4590 ir_node *pred = get_Proj_pred(node);
4591 ir_node *new_pred = be_transform_node(pred);
4592 dbg_info *dbgi = get_irn_dbg_info(node);
4593 long proj = get_Proj_proj(node);
4595 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4596 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4600 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4601 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4602 } else if (is_ia32_xDiv(new_pred)) {
4603 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4604 } else if (is_ia32_vfdiv(new_pred)) {
4605 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4607 panic("Div transformed to unexpected thing %+F", new_pred);
4610 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4611 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4612 } else if (is_ia32_xDiv(new_pred)) {
4613 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4614 } else if (is_ia32_vfdiv(new_pred)) {
4615 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4617 panic("Div transformed to unexpected thing %+F", new_pred);
4619 case pn_Div_X_regular:
4620 return new_rd_Jmp(dbgi, block);
4621 case pn_Div_X_except:
4622 set_ia32_exc_label(new_pred, 1);
4623 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4628 panic("No idea how to transform proj->Div");
4632 * Transform and renumber the Projs from a Div or Mod instruction.
4634 static ir_node *gen_Proj_Mod(ir_node *node)
4636 ir_node *pred = get_Proj_pred(node);
4637 ir_node *new_pred = be_transform_node(pred);
4638 dbg_info *dbgi = get_irn_dbg_info(node);
4639 long proj = get_Proj_proj(node);
4641 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4642 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4643 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4647 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4649 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4650 case pn_Mod_X_except:
4651 set_ia32_exc_label(new_pred, 1);
4652 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4656 panic("No idea how to transform proj->Mod");
4660 * Transform and renumber the Projs from a CopyB.
4662 static ir_node *gen_Proj_CopyB(ir_node *node)
4664 ir_node *pred = get_Proj_pred(node);
4665 ir_node *new_pred = be_transform_node(pred);
4666 dbg_info *dbgi = get_irn_dbg_info(node);
4667 long proj = get_Proj_proj(node);
4671 if (is_ia32_CopyB_i(new_pred)) {
4672 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4673 } else if (is_ia32_CopyB(new_pred)) {
4674 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4681 panic("No idea how to transform proj->CopyB");
4684 static ir_node *gen_be_Call(ir_node *node)
4686 dbg_info *const dbgi = get_irn_dbg_info(node);
4687 ir_node *const src_block = get_nodes_block(node);
4688 ir_node *const block = be_transform_node(src_block);
4689 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4690 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4691 ir_node *const sp = be_transform_node(src_sp);
4692 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4693 ia32_address_mode_t am;
4694 ia32_address_t *const addr = &am.addr;
4699 ir_node * eax = noreg_GP;
4700 ir_node * ecx = noreg_GP;
4701 ir_node * edx = noreg_GP;
4702 unsigned const pop = be_Call_get_pop(node);
4703 ir_type *const call_tp = be_Call_get_type(node);
4704 int old_no_pic_adjust;
4706 /* Run the x87 simulator if the call returns a float value */
4707 if (get_method_n_ress(call_tp) > 0) {
4708 ir_type *const res_type = get_method_res_type(call_tp, 0);
4709 ir_mode *const res_mode = get_type_mode(res_type);
4711 if (res_mode != NULL && mode_is_float(res_mode)) {
4712 ir_graph *irg = current_ir_graph;
4713 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4714 irg_data->do_x87_sim = 1;
4718 /* We do not want be_Call direct calls */
4719 assert(be_Call_get_entity(node) == NULL);
4721 /* special case for PIC trampoline calls */
4722 old_no_pic_adjust = ia32_no_pic_adjust;
4723 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4725 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4726 match_am | match_immediate);
4728 ia32_no_pic_adjust = old_no_pic_adjust;
4730 i = get_irn_arity(node) - 1;
4731 fpcw = be_transform_node(get_irn_n(node, i--));
4732 for (; i >= be_pos_Call_first_arg; --i) {
4733 arch_register_req_t const *const req = arch_get_register_req(node, i);
4734 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4736 assert(req->type == arch_register_req_type_limited);
4737 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4739 switch (*req->limited) {
4740 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4741 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4742 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4743 default: panic("Invalid GP register for register parameter");
4747 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4748 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4749 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4750 set_am_attributes(call, &am);
4751 call = fix_mem_proj(call, &am);
4753 if (get_irn_pinned(node) == op_pin_state_pinned)
4754 set_irn_pinned(call, op_pin_state_pinned);
4756 SET_IA32_ORIG_NODE(call, node);
4758 if (ia32_cg_config.use_sse2) {
4759 /* remember this call for post-processing */
4760 ARR_APP1(ir_node *, call_list, call);
4761 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4768 * Transform Builtin trap
4770 static ir_node *gen_trap(ir_node *node)
4772 dbg_info *dbgi = get_irn_dbg_info(node);
4773 ir_node *block = be_transform_node(get_nodes_block(node));
4774 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4776 return new_bd_ia32_UD2(dbgi, block, mem);
4780 * Transform Builtin debugbreak
4782 static ir_node *gen_debugbreak(ir_node *node)
4784 dbg_info *dbgi = get_irn_dbg_info(node);
4785 ir_node *block = be_transform_node(get_nodes_block(node));
4786 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4788 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4792 * Transform Builtin return_address
4794 static ir_node *gen_return_address(ir_node *node)
4796 ir_node *param = get_Builtin_param(node, 0);
4797 ir_node *frame = get_Builtin_param(node, 1);
4798 dbg_info *dbgi = get_irn_dbg_info(node);
4799 ir_tarval *tv = get_Const_tarval(param);
4800 unsigned long value = get_tarval_long(tv);
4802 ir_node *block = be_transform_node(get_nodes_block(node));
4803 ir_node *ptr = be_transform_node(frame);
4807 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4808 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4809 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4812 /* load the return address from this frame */
4813 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4815 set_irn_pinned(load, get_irn_pinned(node));
4816 set_ia32_op_type(load, ia32_AddrModeS);
4817 set_ia32_ls_mode(load, mode_Iu);
4819 set_ia32_am_offs_int(load, 0);
4820 set_ia32_use_frame(load);
4821 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4823 if (get_irn_pinned(node) == op_pin_state_floats) {
4824 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4825 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4826 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4827 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4830 SET_IA32_ORIG_NODE(load, node);
4831 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4835 * Transform Builtin frame_address
4837 static ir_node *gen_frame_address(ir_node *node)
4839 ir_node *param = get_Builtin_param(node, 0);
4840 ir_node *frame = get_Builtin_param(node, 1);
4841 dbg_info *dbgi = get_irn_dbg_info(node);
4842 ir_tarval *tv = get_Const_tarval(param);
4843 unsigned long value = get_tarval_long(tv);
4845 ir_node *block = be_transform_node(get_nodes_block(node));
4846 ir_node *ptr = be_transform_node(frame);
4851 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4852 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4853 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4856 /* load the frame address from this frame */
4857 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4859 set_irn_pinned(load, get_irn_pinned(node));
4860 set_ia32_op_type(load, ia32_AddrModeS);
4861 set_ia32_ls_mode(load, mode_Iu);
4863 ent = ia32_get_frame_address_entity();
4865 set_ia32_am_offs_int(load, 0);
4866 set_ia32_use_frame(load);
4867 set_ia32_frame_ent(load, ent);
4869 /* will fail anyway, but gcc does this: */
4870 set_ia32_am_offs_int(load, 0);
4873 if (get_irn_pinned(node) == op_pin_state_floats) {
4874 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4875 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4876 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4877 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4880 SET_IA32_ORIG_NODE(load, node);
4881 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4885 * Transform Builtin frame_address
4887 static ir_node *gen_prefetch(ir_node *node)
4890 ir_node *ptr, *block, *mem, *base, *index;
4891 ir_node *param, *new_node;
4894 ia32_address_t addr;
4896 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4897 /* no prefetch at all, route memory */
4898 return be_transform_node(get_Builtin_mem(node));
4901 param = get_Builtin_param(node, 1);
4902 tv = get_Const_tarval(param);
4903 rw = get_tarval_long(tv);
4905 /* construct load address */
4906 memset(&addr, 0, sizeof(addr));
4907 ptr = get_Builtin_param(node, 0);
4908 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4915 base = be_transform_node(base);
4918 if (index == NULL) {
4921 index = be_transform_node(index);
4924 dbgi = get_irn_dbg_info(node);
4925 block = be_transform_node(get_nodes_block(node));
4926 mem = be_transform_node(get_Builtin_mem(node));
4928 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4929 /* we have 3DNow!, this was already checked above */
4930 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4931 } else if (ia32_cg_config.use_sse_prefetch) {
4932 /* note: rw == 1 is IGNORED in that case */
4933 param = get_Builtin_param(node, 2);
4934 tv = get_Const_tarval(param);
4935 locality = get_tarval_long(tv);
4937 /* SSE style prefetch */
4940 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4943 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4946 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4949 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4953 assert(ia32_cg_config.use_3dnow_prefetch);
4954 /* 3DNow! style prefetch */
4955 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4958 set_irn_pinned(new_node, get_irn_pinned(node));
4959 set_ia32_op_type(new_node, ia32_AddrModeS);
4960 set_ia32_ls_mode(new_node, mode_Bu);
4961 set_address(new_node, &addr);
4963 SET_IA32_ORIG_NODE(new_node, node);
4965 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4969 * Transform bsf like node
4971 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4973 ir_node *param = get_Builtin_param(node, 0);
4974 dbg_info *dbgi = get_irn_dbg_info(node);
4976 ir_node *block = get_nodes_block(node);
4977 ir_node *new_block = be_transform_node(block);
4979 ia32_address_mode_t am;
4980 ia32_address_t *addr = &am.addr;
4983 match_arguments(&am, block, NULL, param, NULL, match_am);
4985 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4986 set_am_attributes(cnt, &am);
4987 set_ia32_ls_mode(cnt, get_irn_mode(param));
4989 SET_IA32_ORIG_NODE(cnt, node);
4990 return fix_mem_proj(cnt, &am);
4994 * Transform builtin ffs.
4996 static ir_node *gen_ffs(ir_node *node)
4998 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
4999 ir_node *real = skip_Proj(bsf);
5000 dbg_info *dbgi = get_irn_dbg_info(real);
5001 ir_node *block = get_nodes_block(real);
5002 ir_node *flag, *set, *conv, *neg, *orn, *add;
5005 if (get_irn_mode(real) != mode_T) {
5006 set_irn_mode(real, mode_T);
5007 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5010 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5013 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5014 SET_IA32_ORIG_NODE(set, node);
5017 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5018 SET_IA32_ORIG_NODE(conv, node);
5021 neg = new_bd_ia32_Neg(dbgi, block, conv);
5024 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5025 set_ia32_commutative(orn);
5028 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5029 add_ia32_am_offs_int(add, 1);
5034 * Transform builtin clz.
5036 static ir_node *gen_clz(ir_node *node)
5038 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5039 ir_node *real = skip_Proj(bsr);
5040 dbg_info *dbgi = get_irn_dbg_info(real);
5041 ir_node *block = get_nodes_block(real);
5042 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5044 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5048 * Transform builtin ctz.
5050 static ir_node *gen_ctz(ir_node *node)
5052 return gen_unop_AM(node, new_bd_ia32_Bsf);
5056 * Transform builtin parity.
5058 static ir_node *gen_parity(ir_node *node)
5060 dbg_info *dbgi = get_irn_dbg_info(node);
5061 ir_node *block = get_nodes_block(node);
5062 ir_node *new_block = be_transform_node(block);
5063 ir_node *param = get_Builtin_param(node, 0);
5064 ir_node *new_param = be_transform_node(param);
5067 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5068 * so we have to do complicated xoring first.
5069 * (we should also better lower this before the backend so we still have a
5070 * chance for CSE, constant folding and other goodies for some of these
5073 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5074 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5075 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5077 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5080 set_irn_mode(xor2, mode_T);
5081 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5084 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5085 SET_IA32_ORIG_NODE(new_node, node);
5088 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5089 nomem, new_node, mode_Bu);
5090 SET_IA32_ORIG_NODE(new_node, node);
5095 * Transform builtin popcount
5097 static ir_node *gen_popcount(ir_node *node)
5099 ir_node *param = get_Builtin_param(node, 0);
5100 dbg_info *dbgi = get_irn_dbg_info(node);
5102 ir_node *block = get_nodes_block(node);
5103 ir_node *new_block = be_transform_node(block);
5106 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5108 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5109 if (ia32_cg_config.use_popcnt) {
5110 ia32_address_mode_t am;
5111 ia32_address_t *addr = &am.addr;
5114 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5116 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5117 set_am_attributes(cnt, &am);
5118 set_ia32_ls_mode(cnt, get_irn_mode(param));
5120 SET_IA32_ORIG_NODE(cnt, node);
5121 return fix_mem_proj(cnt, &am);
5124 new_param = be_transform_node(param);
5126 /* do the standard popcount algo */
5127 /* TODO: This is stupid, we should transform this before the backend,
5128 * to get CSE, localopts, etc. for the operations
5129 * TODO: This is also not the optimal algorithm (it is just the starting
5130 * example in hackers delight, they optimize it more on the following page)
5131 * But I'm too lazy to fix this now, as the code should get lowered before
5132 * the backend anyway.
5135 /* m1 = x & 0x55555555 */
5136 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5137 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5140 simm = ia32_create_Immediate(NULL, 0, 1);
5141 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5143 /* m2 = s1 & 0x55555555 */
5144 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5147 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5149 /* m4 = m3 & 0x33333333 */
5150 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5151 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5154 simm = ia32_create_Immediate(NULL, 0, 2);
5155 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5157 /* m5 = s2 & 0x33333333 */
5158 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5161 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5163 /* m7 = m6 & 0x0F0F0F0F */
5164 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5165 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5168 simm = ia32_create_Immediate(NULL, 0, 4);
5169 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5171 /* m8 = s3 & 0x0F0F0F0F */
5172 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5175 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5177 /* m10 = m9 & 0x00FF00FF */
5178 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5179 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5182 simm = ia32_create_Immediate(NULL, 0, 8);
5183 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5185 /* m11 = s4 & 0x00FF00FF */
5186 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5188 /* m12 = m10 + m11 */
5189 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5191 /* m13 = m12 & 0x0000FFFF */
5192 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5193 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5195 /* s5 = m12 >> 16 */
5196 simm = ia32_create_Immediate(NULL, 0, 16);
5197 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5199 /* res = m13 + s5 */
5200 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5204 * Transform builtin byte swap.
5206 static ir_node *gen_bswap(ir_node *node)
5208 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5209 dbg_info *dbgi = get_irn_dbg_info(node);
5211 ir_node *block = get_nodes_block(node);
5212 ir_node *new_block = be_transform_node(block);
5213 ir_mode *mode = get_irn_mode(param);
5214 unsigned size = get_mode_size_bits(mode);
5215 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5219 if (ia32_cg_config.use_i486) {
5220 /* swap available */
5221 return new_bd_ia32_Bswap(dbgi, new_block, param);
5223 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5224 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5226 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5227 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5229 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5231 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5232 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5234 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5235 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5238 /* swap16 always available */
5239 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5242 panic("Invalid bswap size (%d)", size);
5247 * Transform builtin outport.
5249 static ir_node *gen_outport(ir_node *node)
5251 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5252 ir_node *oldv = get_Builtin_param(node, 1);
5253 ir_mode *mode = get_irn_mode(oldv);
5254 ir_node *value = be_transform_node(oldv);
5255 ir_node *block = be_transform_node(get_nodes_block(node));
5256 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5257 dbg_info *dbgi = get_irn_dbg_info(node);
5259 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5260 set_ia32_ls_mode(res, mode);
5265 * Transform builtin inport.
5267 static ir_node *gen_inport(ir_node *node)
5269 ir_type *tp = get_Builtin_type(node);
5270 ir_type *rstp = get_method_res_type(tp, 0);
5271 ir_mode *mode = get_type_mode(rstp);
5272 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5273 ir_node *block = be_transform_node(get_nodes_block(node));
5274 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5275 dbg_info *dbgi = get_irn_dbg_info(node);
5277 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5278 set_ia32_ls_mode(res, mode);
5280 /* check for missing Result Proj */
5285 * Transform a builtin inner trampoline
5287 static ir_node *gen_inner_trampoline(ir_node *node)
5289 ir_node *ptr = get_Builtin_param(node, 0);
5290 ir_node *callee = get_Builtin_param(node, 1);
5291 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5292 ir_node *mem = get_Builtin_mem(node);
5293 ir_node *block = get_nodes_block(node);
5294 ir_node *new_block = be_transform_node(block);
5298 ir_node *trampoline;
5300 dbg_info *dbgi = get_irn_dbg_info(node);
5301 ia32_address_t addr;
5303 /* construct store address */
5304 memset(&addr, 0, sizeof(addr));
5305 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5307 if (addr.base == NULL) {
5308 addr.base = noreg_GP;
5310 addr.base = be_transform_node(addr.base);
5313 if (addr.index == NULL) {
5314 addr.index = noreg_GP;
5316 addr.index = be_transform_node(addr.index);
5318 addr.mem = be_transform_node(mem);
5320 /* mov ecx, <env> */
5321 val = ia32_create_Immediate(NULL, 0, 0xB9);
5322 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5323 addr.index, addr.mem, val);
5324 set_irn_pinned(store, get_irn_pinned(node));
5325 set_ia32_op_type(store, ia32_AddrModeD);
5326 set_ia32_ls_mode(store, mode_Bu);
5327 set_address(store, &addr);
5331 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5332 addr.index, addr.mem, env);
5333 set_irn_pinned(store, get_irn_pinned(node));
5334 set_ia32_op_type(store, ia32_AddrModeD);
5335 set_ia32_ls_mode(store, mode_Iu);
5336 set_address(store, &addr);
5340 /* jmp rel <callee> */
5341 val = ia32_create_Immediate(NULL, 0, 0xE9);
5342 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5343 addr.index, addr.mem, val);
5344 set_irn_pinned(store, get_irn_pinned(node));
5345 set_ia32_op_type(store, ia32_AddrModeD);
5346 set_ia32_ls_mode(store, mode_Bu);
5347 set_address(store, &addr);
5351 trampoline = be_transform_node(ptr);
5353 /* the callee is typically an immediate */
5354 if (is_SymConst(callee)) {
5355 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5357 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5358 add_ia32_am_offs_int(rel, -10);
5360 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5362 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5363 addr.index, addr.mem, rel);
5364 set_irn_pinned(store, get_irn_pinned(node));
5365 set_ia32_op_type(store, ia32_AddrModeD);
5366 set_ia32_ls_mode(store, mode_Iu);
5367 set_address(store, &addr);
5372 return new_r_Tuple(new_block, 2, in);
5376 * Transform Builtin node.
5378 static ir_node *gen_Builtin(ir_node *node)
5380 ir_builtin_kind kind = get_Builtin_kind(node);
5384 return gen_trap(node);
5385 case ir_bk_debugbreak:
5386 return gen_debugbreak(node);
5387 case ir_bk_return_address:
5388 return gen_return_address(node);
5389 case ir_bk_frame_address:
5390 return gen_frame_address(node);
5391 case ir_bk_prefetch:
5392 return gen_prefetch(node);
5394 return gen_ffs(node);
5396 return gen_clz(node);
5398 return gen_ctz(node);
5400 return gen_parity(node);
5401 case ir_bk_popcount:
5402 return gen_popcount(node);
5404 return gen_bswap(node);
5406 return gen_outport(node);
5408 return gen_inport(node);
5409 case ir_bk_inner_trampoline:
5410 return gen_inner_trampoline(node);
5412 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5416 * Transform Proj(Builtin) node.
5418 static ir_node *gen_Proj_Builtin(ir_node *proj)
5420 ir_node *node = get_Proj_pred(proj);
5421 ir_node *new_node = be_transform_node(node);
5422 ir_builtin_kind kind = get_Builtin_kind(node);
5425 case ir_bk_return_address:
5426 case ir_bk_frame_address:
5431 case ir_bk_popcount:
5433 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5436 case ir_bk_debugbreak:
5437 case ir_bk_prefetch:
5439 assert(get_Proj_proj(proj) == pn_Builtin_M);
5442 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5443 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5445 assert(get_Proj_proj(proj) == pn_Builtin_M);
5446 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5448 case ir_bk_inner_trampoline:
5449 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5450 return get_Tuple_pred(new_node, 1);
5452 assert(get_Proj_proj(proj) == pn_Builtin_M);
5453 return get_Tuple_pred(new_node, 0);
5456 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5459 static ir_node *gen_be_IncSP(ir_node *node)
5461 ir_node *res = be_duplicate_node(node);
5462 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5468 * Transform the Projs from a be_Call.
5470 static ir_node *gen_Proj_be_Call(ir_node *node)
5472 ir_node *call = get_Proj_pred(node);
5473 ir_node *new_call = be_transform_node(call);
5474 dbg_info *dbgi = get_irn_dbg_info(node);
5475 long proj = get_Proj_proj(node);
5476 ir_mode *mode = get_irn_mode(node);
5479 if (proj == pn_be_Call_M_regular) {
5480 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5482 /* transform call modes */
5483 if (mode_is_data(mode)) {
5484 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5488 /* Map from be_Call to ia32_Call proj number */
5489 if (proj == pn_be_Call_sp) {
5490 proj = pn_ia32_Call_stack;
5491 } else if (proj == pn_be_Call_M_regular) {
5492 proj = pn_ia32_Call_M;
5494 arch_register_req_t const *const req = arch_get_register_req_out(node);
5495 int const n_outs = arch_irn_get_n_outs(new_call);
5498 assert(proj >= pn_be_Call_first_res);
5499 assert(req->type & arch_register_req_type_limited);
5501 for (i = 0; i < n_outs; ++i) {
5502 arch_register_req_t const *const new_req
5503 = arch_get_out_register_req(new_call, i);
5505 if (!(new_req->type & arch_register_req_type_limited) ||
5506 new_req->cls != req->cls ||
5507 *new_req->limited != *req->limited)
5516 res = new_rd_Proj(dbgi, new_call, mode, proj);
5518 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5520 case pn_ia32_Call_stack:
5521 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5524 case pn_ia32_Call_fpcw:
5525 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5533 * Transform the Projs from a Cmp.
5535 static ir_node *gen_Proj_Cmp(ir_node *node)
5537 /* this probably means not all mode_b nodes were lowered... */
5538 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5542 static ir_node *gen_Proj_ASM(ir_node *node)
5544 ir_mode *mode = get_irn_mode(node);
5545 ir_node *pred = get_Proj_pred(node);
5546 ir_node *new_pred = be_transform_node(pred);
5547 long pos = get_Proj_proj(node);
5549 if (mode == mode_M) {
5550 pos = arch_irn_get_n_outs(new_pred)-1;
5551 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5553 } else if (mode_is_float(mode)) {
5556 panic("unexpected proj mode at ASM");
5559 return new_r_Proj(new_pred, mode, pos);
5563 * Transform and potentially renumber Proj nodes.
5565 static ir_node *gen_Proj(ir_node *node)
5567 ir_node *pred = get_Proj_pred(node);
5570 switch (get_irn_opcode(pred)) {
5572 proj = get_Proj_proj(node);
5573 if (proj == pn_Store_M) {
5574 return be_transform_node(pred);
5576 panic("No idea how to transform proj->Store");
5579 return gen_Proj_Load(node);
5581 return gen_Proj_ASM(node);
5583 return gen_Proj_Builtin(node);
5585 return gen_Proj_Div(node);
5587 return gen_Proj_Mod(node);
5589 return gen_Proj_CopyB(node);
5591 return gen_Proj_be_SubSP(node);
5593 return gen_Proj_be_AddSP(node);
5595 return gen_Proj_be_Call(node);
5597 return gen_Proj_Cmp(node);
5599 proj = get_Proj_proj(node);
5601 case pn_Start_X_initial_exec: {
5602 ir_node *block = get_nodes_block(pred);
5603 ir_node *new_block = be_transform_node(block);
5604 dbg_info *dbgi = get_irn_dbg_info(node);
5605 /* we exchange the ProjX with a jump */
5606 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5614 if (is_ia32_l_FloattoLL(pred)) {
5615 return gen_Proj_l_FloattoLL(node);
5617 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5621 ir_mode *mode = get_irn_mode(node);
5622 if (ia32_mode_needs_gp_reg(mode)) {
5623 ir_node *new_pred = be_transform_node(pred);
5624 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5625 get_Proj_proj(node));
5626 new_proj->node_nr = node->node_nr;
5631 return be_duplicate_node(node);
5635 * Enters all transform functions into the generic pointer
5637 static void register_transformers(void)
5639 /* first clear the generic function pointer for all ops */
5640 be_start_transform_setup();
5642 be_set_transform_function(op_Add, gen_Add);
5643 be_set_transform_function(op_And, gen_And);
5644 be_set_transform_function(op_ASM, ia32_gen_ASM);
5645 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5646 be_set_transform_function(op_be_Call, gen_be_Call);
5647 be_set_transform_function(op_be_Copy, gen_be_Copy);
5648 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5649 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5650 be_set_transform_function(op_be_Return, gen_be_Return);
5651 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5652 be_set_transform_function(op_Builtin, gen_Builtin);
5653 be_set_transform_function(op_Cmp, gen_Cmp);
5654 be_set_transform_function(op_Cond, gen_Cond);
5655 be_set_transform_function(op_Const, gen_Const);
5656 be_set_transform_function(op_Conv, gen_Conv);
5657 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5658 be_set_transform_function(op_Div, gen_Div);
5659 be_set_transform_function(op_Eor, gen_Eor);
5660 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5661 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5662 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5663 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5664 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5665 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5666 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5667 be_set_transform_function(op_ia32_l_SarDep, gen_ia32_l_SarDep);
5668 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5669 be_set_transform_function(op_ia32_l_ShlDep, gen_ia32_l_ShlDep);
5670 be_set_transform_function(op_ia32_l_ShlD, gen_ia32_l_ShlD);
5671 be_set_transform_function(op_ia32_l_ShrDep, gen_ia32_l_ShrDep);
5672 be_set_transform_function(op_ia32_l_ShrD, gen_ia32_l_ShrD);
5673 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5674 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5675 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5676 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5677 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5678 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5679 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5680 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5681 be_set_transform_function(op_IJmp, gen_IJmp);
5682 be_set_transform_function(op_Jmp, gen_Jmp);
5683 be_set_transform_function(op_Load, gen_Load);
5684 be_set_transform_function(op_Minus, gen_Minus);
5685 be_set_transform_function(op_Mod, gen_Mod);
5686 be_set_transform_function(op_Mul, gen_Mul);
5687 be_set_transform_function(op_Mulh, gen_Mulh);
5688 be_set_transform_function(op_Mux, gen_Mux);
5689 be_set_transform_function(op_Not, gen_Not);
5690 be_set_transform_function(op_Or, gen_Or);
5691 be_set_transform_function(op_Phi, gen_Phi);
5692 be_set_transform_function(op_Proj, gen_Proj);
5693 be_set_transform_function(op_Rotl, gen_Rotl);
5694 be_set_transform_function(op_Shl, gen_Shl);
5695 be_set_transform_function(op_Shr, gen_Shr);
5696 be_set_transform_function(op_Shrs, gen_Shrs);
5697 be_set_transform_function(op_Store, gen_Store);
5698 be_set_transform_function(op_Sub, gen_Sub);
5699 be_set_transform_function(op_SymConst, gen_SymConst);
5700 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5704 * Pre-transform all unknown and noreg nodes.
5706 static void ia32_pretransform_node(void)
5708 ir_graph *irg = current_ir_graph;
5709 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5711 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5712 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5713 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5714 irg_data->get_eip = be_pre_transform_node(irg_data->get_eip);
5715 irg_data->fpu_trunc_mode = be_pre_transform_node(irg_data->fpu_trunc_mode);
5717 nomem = get_irg_no_mem(irg);
5718 noreg_GP = ia32_new_NoReg_gp(irg);
5724 * Post-process all calls if we are in SSE mode.
5725 * The ABI requires that the results are in st0, copy them
5726 * to a xmm register.
5728 static void postprocess_fp_call_results(void)
5732 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5733 ir_node *call = call_list[i];
5734 ir_type *mtp = call_types[i];
5737 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5738 ir_type *res_tp = get_method_res_type(mtp, j);
5739 ir_node *res, *new_res;
5740 const ir_edge_t *edge, *next;
5743 if (! is_atomic_type(res_tp)) {
5744 /* no floating point return */
5747 mode = get_type_mode(res_tp);
5748 if (! mode_is_float(mode)) {
5749 /* no floating point return */
5753 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5756 /* now patch the users */
5757 foreach_out_edge_safe(res, edge, next) {
5758 ir_node *succ = get_edge_src_irn(edge);
5761 if (be_is_Keep(succ))
5764 if (is_ia32_xStore(succ)) {
5765 /* an xStore can be patched into an vfst */
5766 dbg_info *db = get_irn_dbg_info(succ);
5767 ir_node *block = get_nodes_block(succ);
5768 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5769 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5770 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5771 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5772 ir_mode *mode = get_ia32_ls_mode(succ);
5774 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5775 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5776 if (is_ia32_use_frame(succ))
5777 set_ia32_use_frame(st);
5778 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5779 set_irn_pinned(st, get_irn_pinned(succ));
5780 set_ia32_op_type(st, ia32_AddrModeD);
5784 if (new_res == NULL) {
5785 dbg_info *db = get_irn_dbg_info(call);
5786 ir_node *block = get_nodes_block(call);
5787 ir_node *frame = get_irg_frame(current_ir_graph);
5788 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5789 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5790 ir_node *vfst, *xld, *new_mem;
5792 /* store st(0) on stack */
5793 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5794 set_ia32_op_type(vfst, ia32_AddrModeD);
5795 set_ia32_use_frame(vfst);
5797 /* load into SSE register */
5798 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5799 set_ia32_op_type(xld, ia32_AddrModeS);
5800 set_ia32_use_frame(xld);
5802 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5803 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5805 if (old_mem != NULL) {
5806 edges_reroute(old_mem, new_mem, current_ir_graph);
5810 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5817 /* do the transformation */
5818 void ia32_transform_graph(ir_graph *irg)
5822 register_transformers();
5823 initial_fpcw = NULL;
5824 ia32_no_pic_adjust = 0;
5826 be_timer_push(T_HEIGHTS);
5827 ia32_heights = heights_new(irg);
5828 be_timer_pop(T_HEIGHTS);
5829 ia32_calculate_non_address_mode_nodes(irg);
5831 /* the transform phase is not safe for CSE (yet) because several nodes get
5832 * attributes set after their creation */
5833 cse_last = get_opt_cse();
5836 call_list = NEW_ARR_F(ir_node *, 0);
5837 call_types = NEW_ARR_F(ir_type *, 0);
5838 be_transform_graph(irg, ia32_pretransform_node);
5840 if (ia32_cg_config.use_sse2)
5841 postprocess_fp_call_results();
5842 DEL_ARR_F(call_types);
5843 DEL_ARR_F(call_list);
5845 set_opt_cse(cse_last);
5847 ia32_free_non_address_mode_nodes();
5848 heights_free(ia32_heights);
5849 ia32_heights = NULL;
5852 void ia32_init_transform(void)
5854 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");