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 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
1216 assert(addr->symconst_ent != NULL);
1217 if (base == noreg_GP)
1220 base = new_bd_ia32_Lea(dbgi, block, tls_base, base);
1221 addr->tls_segment = false;
1224 res = new_bd_ia32_Lea(dbgi, block, base, index);
1225 set_address(res, addr);
1231 * Returns non-zero if a given address mode has a symbolic or
1232 * numerical offset != 0.
1234 static int am_has_immediates(const ia32_address_t *addr)
1236 return addr->offset != 0 || addr->symconst_ent != NULL
1237 || addr->frame_entity || addr->use_frame;
1241 * Creates an ia32 Add.
1243 * @return the created ia32 Add node
1245 static ir_node *gen_Add(ir_node *node)
1247 ir_mode *mode = get_irn_mode(node);
1248 ir_node *op1 = get_Add_left(node);
1249 ir_node *op2 = get_Add_right(node);
1251 ir_node *block, *new_block, *new_node, *add_immediate_op;
1252 ia32_address_t addr;
1253 ia32_address_mode_t am;
1255 if (mode_is_float(mode)) {
1256 if (ia32_cg_config.use_sse2)
1257 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1258 match_commutative | match_am);
1260 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1263 ia32_mark_non_am(node);
1265 op2 = ia32_skip_downconv(op2);
1266 op1 = ia32_skip_downconv(op1);
1270 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1271 * 1. Add with immediate -> Lea
1272 * 2. Add with possible source address mode -> Add
1273 * 3. Otherwise -> Lea
1275 memset(&addr, 0, sizeof(addr));
1276 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1277 add_immediate_op = NULL;
1279 dbgi = get_irn_dbg_info(node);
1280 block = get_nodes_block(node);
1281 new_block = be_transform_node(block);
1284 if (addr.base == NULL && addr.index == NULL) {
1285 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1286 addr.symconst_sign, 0, addr.offset);
1287 SET_IA32_ORIG_NODE(new_node, node);
1290 /* add with immediate? */
1291 if (addr.index == NULL) {
1292 add_immediate_op = addr.base;
1293 } else if (addr.base == NULL && addr.scale == 0) {
1294 add_immediate_op = addr.index;
1297 if (add_immediate_op != NULL) {
1298 if (!am_has_immediates(&addr)) {
1299 #ifdef DEBUG_libfirm
1300 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1303 return be_transform_node(add_immediate_op);
1306 new_node = create_lea_from_address(dbgi, new_block, &addr);
1307 SET_IA32_ORIG_NODE(new_node, node);
1311 /* test if we can use source address mode */
1312 match_arguments(&am, block, op1, op2, NULL, match_commutative
1313 | match_mode_neutral | match_am | match_immediate | match_try_am);
1315 /* construct an Add with source address mode */
1316 if (am.op_type == ia32_AddrModeS) {
1317 ia32_address_t *am_addr = &am.addr;
1318 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1319 am_addr->index, am_addr->mem, am.new_op1,
1321 set_am_attributes(new_node, &am);
1322 SET_IA32_ORIG_NODE(new_node, node);
1324 new_node = fix_mem_proj(new_node, &am);
1329 /* otherwise construct a lea */
1330 new_node = create_lea_from_address(dbgi, new_block, &addr);
1331 SET_IA32_ORIG_NODE(new_node, node);
1336 * Creates an ia32 Mul.
1338 * @return the created ia32 Mul node
1340 static ir_node *gen_Mul(ir_node *node)
1342 ir_node *op1 = get_Mul_left(node);
1343 ir_node *op2 = get_Mul_right(node);
1344 ir_mode *mode = get_irn_mode(node);
1346 if (mode_is_float(mode)) {
1347 if (ia32_cg_config.use_sse2)
1348 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1349 match_commutative | match_am);
1351 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1353 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1354 match_commutative | match_am | match_mode_neutral |
1355 match_immediate | match_am_and_immediates);
1359 * Creates an ia32 Mulh.
1360 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1361 * this result while Mul returns the lower 32 bit.
1363 * @return the created ia32 Mulh node
1365 static ir_node *gen_Mulh(ir_node *node)
1367 dbg_info *dbgi = get_irn_dbg_info(node);
1368 ir_node *op1 = get_Mulh_left(node);
1369 ir_node *op2 = get_Mulh_right(node);
1370 ir_mode *mode = get_irn_mode(node);
1372 ir_node *proj_res_high;
1374 if (get_mode_size_bits(mode) != 32) {
1375 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1378 if (mode_is_signed(mode)) {
1379 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1380 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1382 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1383 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1385 return proj_res_high;
1389 * Creates an ia32 And.
1391 * @return The created ia32 And node
1393 static ir_node *gen_And(ir_node *node)
1395 ir_node *op1 = get_And_left(node);
1396 ir_node *op2 = get_And_right(node);
1397 assert(! mode_is_float(get_irn_mode(node)));
1399 /* is it a zero extension? */
1400 if (is_Const(op2)) {
1401 ir_tarval *tv = get_Const_tarval(op2);
1402 long v = get_tarval_long(tv);
1404 if (v == 0xFF || v == 0xFFFF) {
1405 dbg_info *dbgi = get_irn_dbg_info(node);
1406 ir_node *block = get_nodes_block(node);
1413 assert(v == 0xFFFF);
1416 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1421 return gen_binop(node, op1, op2, new_bd_ia32_And,
1422 match_commutative | match_mode_neutral | match_am | match_immediate);
1428 * Creates an ia32 Or.
1430 * @return The created ia32 Or node
1432 static ir_node *gen_Or(ir_node *node)
1434 ir_node *op1 = get_Or_left(node);
1435 ir_node *op2 = get_Or_right(node);
1437 assert (! mode_is_float(get_irn_mode(node)));
1438 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1439 | match_mode_neutral | match_am | match_immediate);
1445 * Creates an ia32 Eor.
1447 * @return The created ia32 Eor node
1449 static ir_node *gen_Eor(ir_node *node)
1451 ir_node *op1 = get_Eor_left(node);
1452 ir_node *op2 = get_Eor_right(node);
1454 assert(! mode_is_float(get_irn_mode(node)));
1455 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1456 | match_mode_neutral | match_am | match_immediate);
1461 * Creates an ia32 Sub.
1463 * @return The created ia32 Sub node
1465 static ir_node *gen_Sub(ir_node *node)
1467 ir_node *op1 = get_Sub_left(node);
1468 ir_node *op2 = get_Sub_right(node);
1469 ir_mode *mode = get_irn_mode(node);
1471 if (mode_is_float(mode)) {
1472 if (ia32_cg_config.use_sse2)
1473 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1475 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1478 if (is_Const(op2)) {
1479 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1483 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1484 | match_am | match_immediate);
1487 static ir_node *transform_AM_mem(ir_node *const block,
1488 ir_node *const src_val,
1489 ir_node *const src_mem,
1490 ir_node *const am_mem)
1492 if (is_NoMem(am_mem)) {
1493 return be_transform_node(src_mem);
1494 } else if (is_Proj(src_val) &&
1496 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1497 /* avoid memory loop */
1499 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1500 ir_node *const ptr_pred = get_Proj_pred(src_val);
1501 int const arity = get_Sync_n_preds(src_mem);
1506 NEW_ARR_A(ir_node*, ins, arity + 1);
1508 /* NOTE: This sometimes produces dead-code because the old sync in
1509 * src_mem might not be used anymore, we should detect this case
1510 * and kill the sync... */
1511 for (i = arity - 1; i >= 0; --i) {
1512 ir_node *const pred = get_Sync_pred(src_mem, i);
1514 /* avoid memory loop */
1515 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1518 ins[n++] = be_transform_node(pred);
1521 if (n==1 && ins[0] == am_mem) {
1523 /* creating a new Sync and relying on CSE may fail,
1524 * if am_mem is a ProjM, which does not yet verify. */
1528 return new_r_Sync(block, n, ins);
1532 ins[0] = be_transform_node(src_mem);
1534 return new_r_Sync(block, 2, ins);
1539 * Create a 32bit to 64bit signed extension.
1541 * @param dbgi debug info
1542 * @param block the block where node nodes should be placed
1543 * @param val the value to extend
1544 * @param orig the original node
1546 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1547 ir_node *val, const ir_node *orig)
1552 if (ia32_cg_config.use_short_sex_eax) {
1553 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1554 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1556 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1557 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1559 SET_IA32_ORIG_NODE(res, orig);
1564 * Generates an ia32 Div with additional infrastructure for the
1565 * register allocator if needed.
1567 static ir_node *create_Div(ir_node *node)
1569 dbg_info *dbgi = get_irn_dbg_info(node);
1570 ir_node *block = get_nodes_block(node);
1571 ir_node *new_block = be_transform_node(block);
1578 ir_node *sign_extension;
1579 ia32_address_mode_t am;
1580 ia32_address_t *addr = &am.addr;
1582 /* the upper bits have random contents for smaller modes */
1583 switch (get_irn_opcode(node)) {
1585 op1 = get_Div_left(node);
1586 op2 = get_Div_right(node);
1587 mem = get_Div_mem(node);
1588 mode = get_Div_resmode(node);
1591 op1 = get_Mod_left(node);
1592 op2 = get_Mod_right(node);
1593 mem = get_Mod_mem(node);
1594 mode = get_Mod_resmode(node);
1597 panic("invalid divmod node %+F", node);
1600 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1602 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1603 is the memory of the consumed address. We can have only the second op as address
1604 in Div nodes, so check only op2. */
1605 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1607 if (mode_is_signed(mode)) {
1608 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1609 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1610 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1612 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1614 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1615 addr->index, new_mem, am.new_op2,
1616 am.new_op1, sign_extension);
1619 set_irn_pinned(new_node, get_irn_pinned(node));
1621 set_am_attributes(new_node, &am);
1622 SET_IA32_ORIG_NODE(new_node, node);
1624 new_node = fix_mem_proj(new_node, &am);
1630 * Generates an ia32 Mod.
1632 static ir_node *gen_Mod(ir_node *node)
1634 return create_Div(node);
1638 * Generates an ia32 Div.
1640 static ir_node *gen_Div(ir_node *node)
1642 ir_mode *mode = get_Div_resmode(node);
1643 if (mode_is_float(mode)) {
1644 ir_node *op1 = get_Div_left(node);
1645 ir_node *op2 = get_Div_right(node);
1647 if (ia32_cg_config.use_sse2) {
1648 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1650 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1654 return create_Div(node);
1658 * Creates an ia32 Shl.
1660 * @return The created ia32 Shl node
1662 static ir_node *gen_Shl(ir_node *node)
1664 ir_node *left = get_Shl_left(node);
1665 ir_node *right = get_Shl_right(node);
1667 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1668 match_mode_neutral | match_immediate);
1672 * Creates an ia32 Shr.
1674 * @return The created ia32 Shr node
1676 static ir_node *gen_Shr(ir_node *node)
1678 ir_node *left = get_Shr_left(node);
1679 ir_node *right = get_Shr_right(node);
1681 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1687 * Creates an ia32 Sar.
1689 * @return The created ia32 Shrs node
1691 static ir_node *gen_Shrs(ir_node *node)
1693 ir_node *left = get_Shrs_left(node);
1694 ir_node *right = get_Shrs_right(node);
1696 if (is_Const(right)) {
1697 ir_tarval *tv = get_Const_tarval(right);
1698 long val = get_tarval_long(tv);
1700 /* this is a sign extension */
1701 dbg_info *dbgi = get_irn_dbg_info(node);
1702 ir_node *block = be_transform_node(get_nodes_block(node));
1703 ir_node *new_op = be_transform_node(left);
1705 return create_sex_32_64(dbgi, block, new_op, node);
1709 /* 8 or 16 bit sign extension? */
1710 if (is_Const(right) && is_Shl(left)) {
1711 ir_node *shl_left = get_Shl_left(left);
1712 ir_node *shl_right = get_Shl_right(left);
1713 if (is_Const(shl_right)) {
1714 ir_tarval *tv1 = get_Const_tarval(right);
1715 ir_tarval *tv2 = get_Const_tarval(shl_right);
1716 if (tv1 == tv2 && tarval_is_long(tv1)) {
1717 long val = get_tarval_long(tv1);
1718 if (val == 16 || val == 24) {
1719 dbg_info *dbgi = get_irn_dbg_info(node);
1720 ir_node *block = get_nodes_block(node);
1730 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1739 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1745 * Creates an ia32 Rol.
1747 * @param op1 The first operator
1748 * @param op2 The second operator
1749 * @return The created ia32 RotL node
1751 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1753 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1759 * Creates an ia32 Ror.
1760 * NOTE: There is no RotR with immediate because this would always be a RotL
1761 * "imm-mode_size_bits" which can be pre-calculated.
1763 * @param op1 The first operator
1764 * @param op2 The second operator
1765 * @return The created ia32 RotR node
1767 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1769 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1775 * Creates an ia32 RotR or RotL (depending on the found pattern).
1777 * @return The created ia32 RotL or RotR node
1779 static ir_node *gen_Rotl(ir_node *node)
1781 ir_node *op1 = get_Rotl_left(node);
1782 ir_node *op2 = get_Rotl_right(node);
1784 if (is_Minus(op2)) {
1785 return gen_Ror(node, op1, get_Minus_op(op2));
1788 return gen_Rol(node, op1, op2);
1794 * Transforms a Minus node.
1796 * @return The created ia32 Minus node
1798 static ir_node *gen_Minus(ir_node *node)
1800 ir_node *op = get_Minus_op(node);
1801 ir_node *block = be_transform_node(get_nodes_block(node));
1802 dbg_info *dbgi = get_irn_dbg_info(node);
1803 ir_mode *mode = get_irn_mode(node);
1808 if (mode_is_float(mode)) {
1809 ir_node *new_op = be_transform_node(op);
1810 if (ia32_cg_config.use_sse2) {
1811 /* TODO: non-optimal... if we have many xXors, then we should
1812 * rather create a load for the const and use that instead of
1813 * several AM nodes... */
1814 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1816 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1817 noreg_GP, nomem, new_op, noreg_xmm);
1819 size = get_mode_size_bits(mode);
1820 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1822 set_ia32_am_sc(new_node, ent);
1823 set_ia32_op_type(new_node, ia32_AddrModeS);
1824 set_ia32_ls_mode(new_node, mode);
1826 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1829 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1832 SET_IA32_ORIG_NODE(new_node, node);
1838 * Transforms a Not node.
1840 * @return The created ia32 Not node
1842 static ir_node *gen_Not(ir_node *node)
1844 ir_node *op = get_Not_op(node);
1846 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1847 assert (! mode_is_float(get_irn_mode(node)));
1849 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1852 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1853 bool negate, ir_node *node)
1855 ir_node *new_block = be_transform_node(block);
1856 ir_mode *mode = get_irn_mode(op);
1862 if (mode_is_float(mode)) {
1863 new_op = be_transform_node(op);
1865 if (ia32_cg_config.use_sse2) {
1866 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1867 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1868 noreg_GP, nomem, new_op, noreg_fp);
1870 size = get_mode_size_bits(mode);
1871 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1873 set_ia32_am_sc(new_node, ent);
1875 SET_IA32_ORIG_NODE(new_node, node);
1877 set_ia32_op_type(new_node, ia32_AddrModeS);
1878 set_ia32_ls_mode(new_node, mode);
1880 /* TODO, implement -Abs case */
1883 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1884 SET_IA32_ORIG_NODE(new_node, node);
1886 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1887 SET_IA32_ORIG_NODE(new_node, node);
1892 ir_node *sign_extension;
1894 if (get_mode_size_bits(mode) == 32) {
1895 new_op = be_transform_node(op);
1897 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1900 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1902 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1903 nomem, new_op, sign_extension);
1904 SET_IA32_ORIG_NODE(xorn, node);
1907 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1908 nomem, sign_extension, xorn);
1910 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1911 nomem, xorn, sign_extension);
1913 SET_IA32_ORIG_NODE(new_node, node);
1920 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1922 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1924 dbg_info *dbgi = get_irn_dbg_info(cmp);
1925 ir_node *block = get_nodes_block(cmp);
1926 ir_node *new_block = be_transform_node(block);
1927 ir_node *op1 = be_transform_node(x);
1928 ir_node *op2 = be_transform_node(n);
1930 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1933 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
1936 if (mode_is_float(mode)) {
1938 case ir_relation_equal: return ia32_cc_float_equal;
1939 case ir_relation_less: return ia32_cc_float_below;
1940 case ir_relation_less_equal: return ia32_cc_float_below_equal;
1941 case ir_relation_greater: return ia32_cc_float_above;
1942 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
1943 case ir_relation_less_greater: return ia32_cc_not_equal;
1944 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
1945 case ir_relation_unordered: return ia32_cc_parity;
1946 case ir_relation_unordered_equal: return ia32_cc_equal;
1947 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
1948 case ir_relation_unordered_less_equal:
1949 return ia32_cc_float_unordered_below_equal;
1950 case ir_relation_unordered_greater:
1951 return ia32_cc_float_unordered_above;
1952 case ir_relation_unordered_greater_equal:
1953 return ia32_cc_float_unordered_above_equal;
1954 case ir_relation_unordered_less_greater:
1955 return ia32_cc_float_not_equal;
1956 case ir_relation_false:
1957 case ir_relation_true:
1958 /* should we introduce a jump always/jump never? */
1961 panic("Unexpected float pnc");
1962 } else if (mode_is_signed(mode)) {
1964 case ir_relation_unordered_equal:
1965 case ir_relation_equal: return ia32_cc_equal;
1966 case ir_relation_unordered_less:
1967 case ir_relation_less: return ia32_cc_less;
1968 case ir_relation_unordered_less_equal:
1969 case ir_relation_less_equal: return ia32_cc_less_equal;
1970 case ir_relation_unordered_greater:
1971 case ir_relation_greater: return ia32_cc_greater;
1972 case ir_relation_unordered_greater_equal:
1973 case ir_relation_greater_equal: return ia32_cc_greater_equal;
1974 case ir_relation_unordered_less_greater:
1975 case ir_relation_less_greater: return ia32_cc_not_equal;
1976 case ir_relation_less_equal_greater:
1977 case ir_relation_unordered:
1978 case ir_relation_false:
1979 case ir_relation_true:
1980 /* introduce jump always/jump never? */
1983 panic("Unexpected pnc");
1986 case ir_relation_unordered_equal:
1987 case ir_relation_equal: return ia32_cc_equal;
1988 case ir_relation_unordered_less:
1989 case ir_relation_less: return ia32_cc_below;
1990 case ir_relation_unordered_less_equal:
1991 case ir_relation_less_equal: return ia32_cc_below_equal;
1992 case ir_relation_unordered_greater:
1993 case ir_relation_greater: return ia32_cc_above;
1994 case ir_relation_unordered_greater_equal:
1995 case ir_relation_greater_equal: return ia32_cc_above_equal;
1996 case ir_relation_unordered_less_greater:
1997 case ir_relation_less_greater: return ia32_cc_not_equal;
1998 case ir_relation_less_equal_greater:
1999 case ir_relation_unordered:
2000 case ir_relation_false:
2001 case ir_relation_true:
2002 /* introduce jump always/jump never? */
2005 panic("Unexpected pnc");
2009 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
2011 /* a mode_b value, we have to compare it against 0 */
2012 dbg_info *dbgi = get_irn_dbg_info(node);
2013 ir_node *new_block = be_transform_node(get_nodes_block(node));
2014 ir_node *new_op = be_transform_node(node);
2015 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2016 *cc_out = ia32_cc_not_equal;
2020 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2022 /* must have a Cmp as input */
2023 ir_relation relation = get_Cmp_relation(cmp);
2024 ir_relation possible;
2025 ir_node *l = get_Cmp_left(cmp);
2026 ir_node *r = get_Cmp_right(cmp);
2027 ir_mode *mode = get_irn_mode(l);
2030 /* check for bit-test */
2031 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2032 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2033 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2035 ir_node *la = get_And_left(l);
2036 ir_node *ra = get_And_right(l);
2043 ir_node *c = get_Shl_left(la);
2044 if (is_Const_1(c) && is_Const_0(r)) {
2045 /* (1 << n) & ra) */
2046 ir_node *n = get_Shl_right(la);
2047 flags = gen_bt(cmp, ra, n);
2048 /* the bit is copied into the CF flag */
2049 if (relation & ir_relation_equal)
2050 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2052 *cc_out = ia32_cc_below; /* test for CF=1 */
2058 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2059 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2060 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2061 * a predecessor node). So add the < bit */
2062 possible = ir_get_possible_cmp_relations(l, r);
2063 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2064 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2065 relation |= ir_relation_less_greater;
2067 /* just do a normal transformation of the Cmp */
2068 *cc_out = relation_to_condition_code(relation, mode);
2069 flags = be_transform_node(cmp);
2074 * Transform a node returning a "flag" result.
2076 * @param node the node to transform
2077 * @param cc_out the compare mode to use
2079 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2082 return get_flags_node_cmp(node, cc_out);
2083 assert(get_irn_mode(node) == mode_b);
2084 return get_flags_mode_b(node, cc_out);
2088 * Transforms a Load.
2090 * @return the created ia32 Load node
2092 static ir_node *gen_Load(ir_node *node)
2094 ir_node *old_block = get_nodes_block(node);
2095 ir_node *block = be_transform_node(old_block);
2096 ir_node *ptr = get_Load_ptr(node);
2097 ir_node *mem = get_Load_mem(node);
2098 ir_node *new_mem = be_transform_node(mem);
2099 dbg_info *dbgi = get_irn_dbg_info(node);
2100 ir_mode *mode = get_Load_mode(node);
2104 ia32_address_t addr;
2106 /* construct load address */
2107 memset(&addr, 0, sizeof(addr));
2108 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2115 base = be_transform_node(base);
2118 if (index == NULL) {
2121 index = be_transform_node(index);
2124 if (mode_is_float(mode)) {
2125 if (ia32_cg_config.use_sse2) {
2126 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2129 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2133 assert(mode != mode_b);
2135 /* create a conv node with address mode for smaller modes */
2136 if (get_mode_size_bits(mode) < 32) {
2137 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2138 new_mem, noreg_GP, mode);
2140 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2144 set_irn_pinned(new_node, get_irn_pinned(node));
2145 set_ia32_op_type(new_node, ia32_AddrModeS);
2146 set_ia32_ls_mode(new_node, mode);
2147 set_address(new_node, &addr);
2149 if (get_irn_pinned(node) == op_pin_state_floats) {
2150 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2151 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2152 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2153 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2156 SET_IA32_ORIG_NODE(new_node, node);
2161 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2162 ir_node *ptr, ir_node *other)
2169 /* we only use address mode if we're the only user of the load */
2170 if (get_irn_n_edges(node) > 1)
2173 load = get_Proj_pred(node);
2176 if (get_nodes_block(load) != block)
2179 /* store should have the same pointer as the load */
2180 if (get_Load_ptr(load) != ptr)
2183 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2184 if (other != NULL &&
2185 get_nodes_block(other) == block &&
2186 heights_reachable_in_block(ia32_heights, other, load)) {
2190 if (ia32_prevents_AM(block, load, mem))
2192 /* Store should be attached to the load via mem */
2193 assert(heights_reachable_in_block(ia32_heights, mem, load));
2198 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2199 ir_node *mem, ir_node *ptr, ir_mode *mode,
2200 construct_binop_dest_func *func,
2201 construct_binop_dest_func *func8bit,
2202 match_flags_t flags)
2204 ir_node *src_block = get_nodes_block(node);
2212 ia32_address_mode_t am;
2213 ia32_address_t *addr = &am.addr;
2214 memset(&am, 0, sizeof(am));
2216 assert(flags & match_immediate); /* there is no destam node without... */
2217 commutative = (flags & match_commutative) != 0;
2219 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2220 build_address(&am, op1, ia32_create_am_double_use);
2221 new_op = create_immediate_or_transform(op2, 0);
2222 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2223 build_address(&am, op2, ia32_create_am_double_use);
2224 new_op = create_immediate_or_transform(op1, 0);
2229 if (addr->base == NULL)
2230 addr->base = noreg_GP;
2231 if (addr->index == NULL)
2232 addr->index = noreg_GP;
2233 if (addr->mem == NULL)
2236 dbgi = get_irn_dbg_info(node);
2237 block = be_transform_node(src_block);
2238 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2240 if (get_mode_size_bits(mode) == 8) {
2241 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2243 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2245 set_address(new_node, addr);
2246 set_ia32_op_type(new_node, ia32_AddrModeD);
2247 set_ia32_ls_mode(new_node, mode);
2248 SET_IA32_ORIG_NODE(new_node, node);
2250 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2251 mem_proj = be_transform_node(am.mem_proj);
2252 be_set_transformed_node(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.tls_segment = false;
3455 am.addr.frame_entity = NULL;
3456 am.addr.symconst_sign = 0;
3457 am.mem_proj = am.addr.mem;
3458 am.op_type = ia32_AddrModeS;
3461 am.pinned = op_pin_state_floats;
3463 am.ins_permuted = false;
3465 if (ia32_cg_config.use_sse2)
3466 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3468 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3469 set_am_attributes(load, &am);
3471 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3473 panic("cannot transform floating point Mux");
3476 assert(ia32_mode_needs_gp_reg(mode));
3479 ir_node *cmp_left = get_Cmp_left(sel);
3480 ir_node *cmp_right = get_Cmp_right(sel);
3481 ir_relation relation = get_Cmp_relation(sel);
3482 ir_node *val_true = mux_true;
3483 ir_node *val_false = mux_false;
3485 if (is_Const(val_true) && is_Const_null(val_true)) {
3486 ir_node *tmp = val_false;
3487 val_false = val_true;
3489 relation = get_negated_relation(relation);
3491 if (is_Const_0(val_false) && is_Sub(val_true)) {
3492 if ((relation & ir_relation_greater)
3493 && get_Sub_left(val_true) == cmp_left
3494 && get_Sub_right(val_true) == cmp_right) {
3495 return create_doz(node, cmp_left, cmp_right);
3497 if ((relation & ir_relation_less)
3498 && get_Sub_left(val_true) == cmp_right
3499 && get_Sub_right(val_true) == cmp_left) {
3500 return create_doz(node, cmp_right, cmp_left);
3505 flags = get_flags_node(sel, &cc);
3507 if (is_Const(mux_true) && is_Const(mux_false)) {
3508 /* both are const, good */
3509 ir_tarval *tv_true = get_Const_tarval(mux_true);
3510 ir_tarval *tv_false = get_Const_tarval(mux_false);
3511 setcc_transform_t res;
3514 find_const_transform(cc, tv_true, tv_false, &res);
3516 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3519 switch (res.steps[step].transform) {
3521 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3522 add_ia32_am_offs_int(new_node, res.steps[step].val);
3524 case SETCC_TR_ADDxx:
3525 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3528 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3529 set_ia32_am_scale(new_node, res.steps[step].scale);
3530 set_ia32_am_offs_int(new_node, res.steps[step].val);
3532 case SETCC_TR_LEAxx:
3533 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3534 set_ia32_am_scale(new_node, res.steps[step].scale);
3535 set_ia32_am_offs_int(new_node, res.steps[step].val);
3538 imm = ia32_immediate_from_long(res.steps[step].scale);
3539 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3542 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3545 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3548 imm = ia32_immediate_from_long(res.steps[step].val);
3549 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3552 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3555 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3558 panic("unknown setcc transform");
3562 new_node = create_CMov(node, sel, flags, cc);
3570 * Create a conversion from x87 state register to general purpose.
3572 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3574 ir_node *block = be_transform_node(get_nodes_block(node));
3575 ir_node *op = get_Conv_op(node);
3576 ir_node *new_op = be_transform_node(op);
3577 ir_graph *irg = current_ir_graph;
3578 dbg_info *dbgi = get_irn_dbg_info(node);
3579 ir_mode *mode = get_irn_mode(node);
3580 ir_node *fist, *load, *mem;
3582 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3583 set_irn_pinned(fist, op_pin_state_floats);
3584 set_ia32_use_frame(fist);
3585 set_ia32_op_type(fist, ia32_AddrModeD);
3587 assert(get_mode_size_bits(mode) <= 32);
3588 /* exception we can only store signed 32 bit integers, so for unsigned
3589 we store a 64bit (signed) integer and load the lower bits */
3590 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3591 set_ia32_ls_mode(fist, mode_Ls);
3593 set_ia32_ls_mode(fist, mode_Is);
3595 SET_IA32_ORIG_NODE(fist, node);
3598 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3600 set_irn_pinned(load, op_pin_state_floats);
3601 set_ia32_use_frame(load);
3602 set_ia32_op_type(load, ia32_AddrModeS);
3603 set_ia32_ls_mode(load, mode_Is);
3604 if (get_ia32_ls_mode(fist) == mode_Ls) {
3605 ia32_attr_t *attr = get_ia32_attr(load);
3606 attr->data.need_64bit_stackent = 1;
3608 ia32_attr_t *attr = get_ia32_attr(load);
3609 attr->data.need_32bit_stackent = 1;
3611 SET_IA32_ORIG_NODE(load, node);
3613 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3617 * Creates a x87 strict Conv by placing a Store and a Load
3619 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3621 ir_node *block = get_nodes_block(node);
3622 ir_graph *irg = get_Block_irg(block);
3623 dbg_info *dbgi = get_irn_dbg_info(node);
3624 ir_node *frame = get_irg_frame(irg);
3625 ir_node *store, *load;
3628 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3629 set_ia32_use_frame(store);
3630 set_ia32_op_type(store, ia32_AddrModeD);
3631 SET_IA32_ORIG_NODE(store, node);
3633 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3634 set_ia32_use_frame(load);
3635 set_ia32_op_type(load, ia32_AddrModeS);
3636 SET_IA32_ORIG_NODE(load, node);
3638 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3642 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3643 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3645 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3647 func = get_mode_size_bits(mode) == 8 ?
3648 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3649 return func(dbgi, block, base, index, mem, val, mode);
3653 * Create a conversion from general purpose to x87 register
3655 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3657 ir_node *src_block = get_nodes_block(node);
3658 ir_node *block = be_transform_node(src_block);
3659 ir_graph *irg = get_Block_irg(block);
3660 dbg_info *dbgi = get_irn_dbg_info(node);
3661 ir_node *op = get_Conv_op(node);
3662 ir_node *new_op = NULL;
3664 ir_mode *store_mode;
3669 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3670 if (possible_int_mode_for_fp(src_mode)) {
3671 ia32_address_mode_t am;
3673 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3674 if (am.op_type == ia32_AddrModeS) {
3675 ia32_address_t *addr = &am.addr;
3677 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3678 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3680 set_am_attributes(fild, &am);
3681 SET_IA32_ORIG_NODE(fild, node);
3683 fix_mem_proj(fild, &am);
3688 if (new_op == NULL) {
3689 new_op = be_transform_node(op);
3692 mode = get_irn_mode(op);
3694 /* first convert to 32 bit signed if necessary */
3695 if (get_mode_size_bits(src_mode) < 32) {
3696 if (!upper_bits_clean(new_op, src_mode)) {
3697 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3698 SET_IA32_ORIG_NODE(new_op, node);
3703 assert(get_mode_size_bits(mode) == 32);
3706 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3708 set_ia32_use_frame(store);
3709 set_ia32_op_type(store, ia32_AddrModeD);
3710 set_ia32_ls_mode(store, mode_Iu);
3712 /* exception for 32bit unsigned, do a 64bit spill+load */
3713 if (!mode_is_signed(mode)) {
3716 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3718 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3719 noreg_GP, nomem, zero_const);
3721 set_ia32_use_frame(zero_store);
3722 set_ia32_op_type(zero_store, ia32_AddrModeD);
3723 add_ia32_am_offs_int(zero_store, 4);
3724 set_ia32_ls_mode(zero_store, mode_Iu);
3729 store = new_rd_Sync(dbgi, block, 2, in);
3730 store_mode = mode_Ls;
3732 store_mode = mode_Is;
3736 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3738 set_ia32_use_frame(fild);
3739 set_ia32_op_type(fild, ia32_AddrModeS);
3740 set_ia32_ls_mode(fild, store_mode);
3742 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3748 * Create a conversion from one integer mode into another one
3750 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3751 dbg_info *dbgi, ir_node *block, ir_node *op,
3754 ir_node *new_block = be_transform_node(block);
3756 ir_mode *smaller_mode;
3757 ia32_address_mode_t am;
3758 ia32_address_t *addr = &am.addr;
3761 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3762 smaller_mode = src_mode;
3764 smaller_mode = tgt_mode;
3767 #ifdef DEBUG_libfirm
3769 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3774 match_arguments(&am, block, NULL, op, NULL,
3775 match_am | match_8bit_am | match_16bit_am);
3777 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3778 /* unnecessary conv. in theory it shouldn't have been AM */
3779 assert(is_ia32_NoReg_GP(addr->base));
3780 assert(is_ia32_NoReg_GP(addr->index));
3781 assert(is_NoMem(addr->mem));
3782 assert(am.addr.offset == 0);
3783 assert(am.addr.symconst_ent == NULL);
3787 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3788 addr->mem, am.new_op2, smaller_mode);
3789 set_am_attributes(new_node, &am);
3790 /* match_arguments assume that out-mode = in-mode, this isn't true here
3792 set_ia32_ls_mode(new_node, smaller_mode);
3793 SET_IA32_ORIG_NODE(new_node, node);
3794 new_node = fix_mem_proj(new_node, &am);
3799 * Transforms a Conv node.
3801 * @return The created ia32 Conv node
3803 static ir_node *gen_Conv(ir_node *node)
3805 ir_node *block = get_nodes_block(node);
3806 ir_node *new_block = be_transform_node(block);
3807 ir_node *op = get_Conv_op(node);
3808 ir_node *new_op = NULL;
3809 dbg_info *dbgi = get_irn_dbg_info(node);
3810 ir_mode *src_mode = get_irn_mode(op);
3811 ir_mode *tgt_mode = get_irn_mode(node);
3812 int src_bits = get_mode_size_bits(src_mode);
3813 int tgt_bits = get_mode_size_bits(tgt_mode);
3814 ir_node *res = NULL;
3816 assert(!mode_is_int(src_mode) || src_bits <= 32);
3817 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3819 /* modeB -> X should already be lowered by the lower_mode_b pass */
3820 if (src_mode == mode_b) {
3821 panic("ConvB not lowered %+F", node);
3824 if (src_mode == tgt_mode) {
3825 if (get_Conv_strict(node)) {
3826 if (ia32_cg_config.use_sse2) {
3827 /* when we are in SSE mode, we can kill all strict no-op conversion */
3828 return be_transform_node(op);
3831 /* this should be optimized already, but who knows... */
3832 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3833 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3834 return be_transform_node(op);
3838 if (mode_is_float(src_mode)) {
3839 new_op = be_transform_node(op);
3840 /* we convert from float ... */
3841 if (mode_is_float(tgt_mode)) {
3843 if (ia32_cg_config.use_sse2) {
3844 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3845 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3847 set_ia32_ls_mode(res, tgt_mode);
3849 if (get_Conv_strict(node)) {
3850 /* if fp_no_float_fold is not set then we assume that we
3851 * don't have any float operations in a non
3852 * mode_float_arithmetic mode and can skip strict upconvs */
3853 if (src_bits < tgt_bits) {
3854 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3857 res = gen_x87_strict_conv(tgt_mode, new_op);
3858 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3862 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3867 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3868 if (ia32_cg_config.use_sse2) {
3869 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3871 set_ia32_ls_mode(res, src_mode);
3873 return gen_x87_fp_to_gp(node);
3877 /* we convert from int ... */
3878 if (mode_is_float(tgt_mode)) {
3880 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3881 if (ia32_cg_config.use_sse2) {
3882 new_op = be_transform_node(op);
3883 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3885 set_ia32_ls_mode(res, tgt_mode);
3887 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3888 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3889 res = gen_x87_gp_to_fp(node, src_mode);
3891 /* we need a strict-Conv, if the int mode has more bits than the
3893 if (float_mantissa < int_mantissa) {
3894 res = gen_x87_strict_conv(tgt_mode, res);
3895 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3899 } else if (tgt_mode == mode_b) {
3900 /* mode_b lowering already took care that we only have 0/1 values */
3901 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3902 src_mode, tgt_mode));
3903 return be_transform_node(op);
3906 if (src_bits == tgt_bits) {
3907 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3908 src_mode, tgt_mode));
3909 return be_transform_node(op);
3912 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3920 static ir_node *create_immediate_or_transform(ir_node *node,
3921 char immediate_constraint_type)
3923 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3924 if (new_node == NULL) {
3925 new_node = be_transform_node(node);
3931 * Transforms a FrameAddr into an ia32 Add.
3933 static ir_node *gen_be_FrameAddr(ir_node *node)
3935 ir_node *block = be_transform_node(get_nodes_block(node));
3936 ir_node *op = be_get_FrameAddr_frame(node);
3937 ir_node *new_op = be_transform_node(op);
3938 dbg_info *dbgi = get_irn_dbg_info(node);
3941 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3942 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3943 set_ia32_use_frame(new_node);
3945 SET_IA32_ORIG_NODE(new_node, node);
3951 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3953 static ir_node *gen_be_Return(ir_node *node)
3955 ir_graph *irg = current_ir_graph;
3956 ir_node *ret_val = get_irn_n(node, n_be_Return_val);
3957 ir_node *ret_mem = get_irn_n(node, n_be_Return_mem);
3958 ir_node *new_ret_val = be_transform_node(ret_val);
3959 ir_node *new_ret_mem = be_transform_node(ret_mem);
3960 ir_entity *ent = get_irg_entity(irg);
3961 ir_type *tp = get_entity_type(ent);
3962 dbg_info *dbgi = get_irn_dbg_info(node);
3963 ir_node *block = be_transform_node(get_nodes_block(node));
3966 ir_node *frame, *sse_store, *fld, *mproj;
3973 assert(ret_val != NULL);
3974 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3975 return be_duplicate_node(node);
3978 res_type = get_method_res_type(tp, 0);
3980 if (! is_Primitive_type(res_type)) {
3981 return be_duplicate_node(node);
3984 mode = get_type_mode(res_type);
3985 if (! mode_is_float(mode)) {
3986 return be_duplicate_node(node);
3989 assert(get_method_n_ress(tp) == 1);
3991 frame = get_irg_frame(irg);
3993 /* store xmm0 onto stack */
3994 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3995 new_ret_mem, new_ret_val);
3996 set_ia32_ls_mode(sse_store, mode);
3997 set_ia32_op_type(sse_store, ia32_AddrModeD);
3998 set_ia32_use_frame(sse_store);
4000 /* load into x87 register */
4001 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4002 set_ia32_op_type(fld, ia32_AddrModeS);
4003 set_ia32_use_frame(fld);
4005 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4006 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4008 /* create a new return */
4009 arity = get_irn_arity(node);
4010 in = ALLOCAN(ir_node*, arity);
4011 pop = be_Return_get_pop(node);
4012 for (i = 0; i < arity; ++i) {
4013 ir_node *op = get_irn_n(node, i);
4014 if (op == ret_val) {
4016 } else if (op == ret_mem) {
4019 in[i] = be_transform_node(op);
4022 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4023 copy_node_attr(irg, node, new_node);
4029 * Transform a be_AddSP into an ia32_SubSP.
4031 static ir_node *gen_be_AddSP(ir_node *node)
4033 ir_node *sz = get_irn_n(node, n_be_AddSP_size);
4034 ir_node *sp = get_irn_n(node, n_be_AddSP_old_sp);
4036 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4037 match_am | match_immediate);
4038 assert(is_ia32_SubSP(new_node));
4039 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4040 &ia32_registers[REG_ESP]);
4045 * Transform a be_SubSP into an ia32_AddSP
4047 static ir_node *gen_be_SubSP(ir_node *node)
4049 ir_node *sz = get_irn_n(node, n_be_SubSP_size);
4050 ir_node *sp = get_irn_n(node, n_be_SubSP_old_sp);
4052 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4053 match_am | match_immediate);
4054 assert(is_ia32_AddSP(new_node));
4055 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4056 &ia32_registers[REG_ESP]);
4061 * Change some phi modes
4063 static ir_node *gen_Phi(ir_node *node)
4065 const arch_register_req_t *req;
4066 ir_node *block = be_transform_node(get_nodes_block(node));
4067 ir_graph *irg = current_ir_graph;
4068 dbg_info *dbgi = get_irn_dbg_info(node);
4069 ir_mode *mode = get_irn_mode(node);
4072 if (ia32_mode_needs_gp_reg(mode)) {
4073 /* we shouldn't have any 64bit stuff around anymore */
4074 assert(get_mode_size_bits(mode) <= 32);
4075 /* all integer operations are on 32bit registers now */
4077 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4078 } else if (mode_is_float(mode)) {
4079 if (ia32_cg_config.use_sse2) {
4081 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4084 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4087 req = arch_no_register_req;
4090 /* phi nodes allow loops, so we use the old arguments for now
4091 * and fix this later */
4092 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4093 get_irn_in(node) + 1);
4094 copy_node_attr(irg, node, phi);
4095 be_duplicate_deps(node, phi);
4097 arch_set_out_register_req(phi, 0, req);
4099 be_enqueue_preds(node);
4104 static ir_node *gen_Jmp(ir_node *node)
4106 ir_node *block = get_nodes_block(node);
4107 ir_node *new_block = be_transform_node(block);
4108 dbg_info *dbgi = get_irn_dbg_info(node);
4111 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4112 SET_IA32_ORIG_NODE(new_node, node);
4120 static ir_node *gen_IJmp(ir_node *node)
4122 ir_node *block = get_nodes_block(node);
4123 ir_node *new_block = be_transform_node(block);
4124 dbg_info *dbgi = get_irn_dbg_info(node);
4125 ir_node *op = get_IJmp_target(node);
4127 ia32_address_mode_t am;
4128 ia32_address_t *addr = &am.addr;
4130 assert(get_irn_mode(op) == mode_P);
4132 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4134 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4135 addr->mem, am.new_op2);
4136 set_am_attributes(new_node, &am);
4137 SET_IA32_ORIG_NODE(new_node, node);
4139 new_node = fix_mem_proj(new_node, &am);
4144 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4146 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4147 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4149 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4150 match_immediate | match_mode_neutral);
4153 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4155 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4156 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4157 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4161 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4163 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4164 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4165 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4169 static ir_node *gen_ia32_l_Add(ir_node *node)
4171 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4172 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4173 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4174 match_commutative | match_am | match_immediate |
4175 match_mode_neutral);
4177 if (is_Proj(lowered)) {
4178 lowered = get_Proj_pred(lowered);
4180 assert(is_ia32_Add(lowered));
4181 set_irn_mode(lowered, mode_T);
4187 static ir_node *gen_ia32_l_Adc(ir_node *node)
4189 return gen_binop_flags(node, new_bd_ia32_Adc,
4190 match_commutative | match_am | match_immediate |
4191 match_mode_neutral);
4195 * Transforms a l_MulS into a "real" MulS node.
4197 * @return the created ia32 Mul node
4199 static ir_node *gen_ia32_l_Mul(ir_node *node)
4201 ir_node *left = get_binop_left(node);
4202 ir_node *right = get_binop_right(node);
4204 return gen_binop(node, left, right, new_bd_ia32_Mul,
4205 match_commutative | match_am | match_mode_neutral);
4209 * Transforms a l_IMulS into a "real" IMul1OPS node.
4211 * @return the created ia32 IMul1OP node
4213 static ir_node *gen_ia32_l_IMul(ir_node *node)
4215 ir_node *left = get_binop_left(node);
4216 ir_node *right = get_binop_right(node);
4218 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4219 match_commutative | match_am | match_mode_neutral);
4222 static ir_node *gen_ia32_l_Sub(ir_node *node)
4224 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4225 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4226 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4227 match_am | match_immediate | match_mode_neutral);
4229 if (is_Proj(lowered)) {
4230 lowered = get_Proj_pred(lowered);
4232 assert(is_ia32_Sub(lowered));
4233 set_irn_mode(lowered, mode_T);
4239 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4241 return gen_binop_flags(node, new_bd_ia32_Sbb,
4242 match_am | match_immediate | match_mode_neutral);
4246 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4247 * op1 - target to be shifted
4248 * op2 - contains bits to be shifted into target
4250 * Only op3 can be an immediate.
4252 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4253 ir_node *low, ir_node *count)
4255 ir_node *block = get_nodes_block(node);
4256 ir_node *new_block = be_transform_node(block);
4257 dbg_info *dbgi = get_irn_dbg_info(node);
4258 ir_node *new_high = be_transform_node(high);
4259 ir_node *new_low = be_transform_node(low);
4263 /* the shift amount can be any mode that is bigger than 5 bits, since all
4264 * other bits are ignored anyway */
4265 while (is_Conv(count) &&
4266 get_irn_n_edges(count) == 1 &&
4267 mode_is_int(get_irn_mode(count))) {
4268 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4269 count = get_Conv_op(count);
4271 new_count = create_immediate_or_transform(count, 0);
4273 if (is_ia32_l_ShlD(node)) {
4274 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4277 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4280 SET_IA32_ORIG_NODE(new_node, node);
4285 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4287 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4288 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4289 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4290 return gen_lowered_64bit_shifts(node, high, low, count);
4293 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4295 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4296 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4297 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4298 return gen_lowered_64bit_shifts(node, high, low, count);
4301 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4303 ir_node *src_block = get_nodes_block(node);
4304 ir_node *block = be_transform_node(src_block);
4305 ir_graph *irg = current_ir_graph;
4306 dbg_info *dbgi = get_irn_dbg_info(node);
4307 ir_node *frame = get_irg_frame(irg);
4308 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4309 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4310 ir_node *new_val_low = be_transform_node(val_low);
4311 ir_node *new_val_high = be_transform_node(val_high);
4313 ir_node *sync, *fild, *res;
4314 ir_node *store_low, *store_high;
4316 if (ia32_cg_config.use_sse2) {
4317 panic("ia32_l_LLtoFloat not implemented for SSE2");
4321 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4323 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4325 SET_IA32_ORIG_NODE(store_low, node);
4326 SET_IA32_ORIG_NODE(store_high, node);
4328 set_ia32_use_frame(store_low);
4329 set_ia32_use_frame(store_high);
4330 set_ia32_op_type(store_low, ia32_AddrModeD);
4331 set_ia32_op_type(store_high, ia32_AddrModeD);
4332 set_ia32_ls_mode(store_low, mode_Iu);
4333 set_ia32_ls_mode(store_high, mode_Is);
4334 add_ia32_am_offs_int(store_high, 4);
4338 sync = new_rd_Sync(dbgi, block, 2, in);
4341 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4343 set_ia32_use_frame(fild);
4344 set_ia32_op_type(fild, ia32_AddrModeS);
4345 set_ia32_ls_mode(fild, mode_Ls);
4347 SET_IA32_ORIG_NODE(fild, node);
4349 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4351 if (! mode_is_signed(get_irn_mode(val_high))) {
4352 ia32_address_mode_t am;
4354 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4357 am.addr.base = get_symconst_base();
4358 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4359 am.addr.mem = nomem;
4362 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4363 am.addr.tls_segment = false;
4364 am.addr.use_frame = 0;
4365 am.addr.frame_entity = NULL;
4366 am.addr.symconst_sign = 0;
4367 am.ls_mode = mode_F;
4368 am.mem_proj = nomem;
4369 am.op_type = ia32_AddrModeS;
4371 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4372 am.pinned = op_pin_state_floats;
4374 am.ins_permuted = false;
4376 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4377 am.new_op1, am.new_op2, get_fpcw());
4378 set_am_attributes(fadd, &am);
4380 set_irn_mode(fadd, mode_T);
4381 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4386 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4388 ir_node *src_block = get_nodes_block(node);
4389 ir_node *block = be_transform_node(src_block);
4390 ir_graph *irg = get_Block_irg(block);
4391 dbg_info *dbgi = get_irn_dbg_info(node);
4392 ir_node *frame = get_irg_frame(irg);
4393 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4394 ir_node *new_val = be_transform_node(val);
4395 ir_node *fist, *mem;
4397 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4398 SET_IA32_ORIG_NODE(fist, node);
4399 set_ia32_use_frame(fist);
4400 set_ia32_op_type(fist, ia32_AddrModeD);
4401 set_ia32_ls_mode(fist, mode_Ls);
4406 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4408 ir_node *block = be_transform_node(get_nodes_block(node));
4409 ir_graph *irg = get_Block_irg(block);
4410 ir_node *pred = get_Proj_pred(node);
4411 ir_node *new_pred = be_transform_node(pred);
4412 ir_node *frame = get_irg_frame(irg);
4413 dbg_info *dbgi = get_irn_dbg_info(node);
4414 long pn = get_Proj_proj(node);
4419 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4420 SET_IA32_ORIG_NODE(load, node);
4421 set_ia32_use_frame(load);
4422 set_ia32_op_type(load, ia32_AddrModeS);
4423 set_ia32_ls_mode(load, mode_Iu);
4424 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4425 * 32 bit from it with this particular load */
4426 attr = get_ia32_attr(load);
4427 attr->data.need_64bit_stackent = 1;
4429 if (pn == pn_ia32_l_FloattoLL_res_high) {
4430 add_ia32_am_offs_int(load, 4);
4432 assert(pn == pn_ia32_l_FloattoLL_res_low);
4435 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4441 * Transform the Projs of an AddSP.
4443 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4445 ir_node *pred = get_Proj_pred(node);
4446 ir_node *new_pred = be_transform_node(pred);
4447 dbg_info *dbgi = get_irn_dbg_info(node);
4448 long proj = get_Proj_proj(node);
4450 if (proj == pn_be_AddSP_sp) {
4451 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4452 pn_ia32_SubSP_stack);
4453 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4455 } else if (proj == pn_be_AddSP_res) {
4456 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4457 pn_ia32_SubSP_addr);
4458 } else if (proj == pn_be_AddSP_M) {
4459 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4462 panic("No idea how to transform proj->AddSP");
4466 * Transform the Projs of a SubSP.
4468 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4470 ir_node *pred = get_Proj_pred(node);
4471 ir_node *new_pred = be_transform_node(pred);
4472 dbg_info *dbgi = get_irn_dbg_info(node);
4473 long proj = get_Proj_proj(node);
4475 if (proj == pn_be_SubSP_sp) {
4476 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4477 pn_ia32_AddSP_stack);
4478 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4480 } else if (proj == pn_be_SubSP_M) {
4481 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4484 panic("No idea how to transform proj->SubSP");
4488 * Transform and renumber the Projs from a Load.
4490 static ir_node *gen_Proj_Load(ir_node *node)
4493 ir_node *block = be_transform_node(get_nodes_block(node));
4494 ir_node *pred = get_Proj_pred(node);
4495 dbg_info *dbgi = get_irn_dbg_info(node);
4496 long proj = get_Proj_proj(node);
4498 /* loads might be part of source address mode matches, so we don't
4499 * transform the ProjMs yet (with the exception of loads whose result is
4502 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4505 /* this is needed, because sometimes we have loops that are only
4506 reachable through the ProjM */
4507 be_enqueue_preds(node);
4508 /* do it in 2 steps, to silence firm verifier */
4509 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4510 set_Proj_proj(res, pn_ia32_mem);
4514 /* renumber the proj */
4515 new_pred = be_transform_node(pred);
4516 if (is_ia32_Load(new_pred)) {
4519 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4521 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4522 case pn_Load_X_regular:
4523 return new_rd_Jmp(dbgi, block);
4524 case pn_Load_X_except:
4525 /* This Load might raise an exception. Mark it. */
4526 set_ia32_exc_label(new_pred, 1);
4527 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4531 } else if (is_ia32_Conv_I2I(new_pred) ||
4532 is_ia32_Conv_I2I8Bit(new_pred)) {
4533 set_irn_mode(new_pred, mode_T);
4534 if (proj == pn_Load_res) {
4535 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4536 } else if (proj == pn_Load_M) {
4537 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4539 } else if (is_ia32_xLoad(new_pred)) {
4542 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4544 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4545 case pn_Load_X_regular:
4546 return new_rd_Jmp(dbgi, block);
4547 case pn_Load_X_except:
4548 /* This Load might raise an exception. Mark it. */
4549 set_ia32_exc_label(new_pred, 1);
4550 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4554 } else if (is_ia32_vfld(new_pred)) {
4557 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4559 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4560 case pn_Load_X_regular:
4561 return new_rd_Jmp(dbgi, block);
4562 case pn_Load_X_except:
4563 /* This Load might raise an exception. Mark it. */
4564 set_ia32_exc_label(new_pred, 1);
4565 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4570 /* can happen for ProJMs when source address mode happened for the
4573 /* however it should not be the result proj, as that would mean the
4574 load had multiple users and should not have been used for
4576 if (proj != pn_Load_M) {
4577 panic("internal error: transformed node not a Load");
4579 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4582 panic("No idea how to transform proj");
4586 * Transform and renumber the Projs from a Div or Mod instruction.
4588 static ir_node *gen_Proj_Div(ir_node *node)
4590 ir_node *block = be_transform_node(get_nodes_block(node));
4591 ir_node *pred = get_Proj_pred(node);
4592 ir_node *new_pred = be_transform_node(pred);
4593 dbg_info *dbgi = get_irn_dbg_info(node);
4594 long proj = get_Proj_proj(node);
4596 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4597 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4601 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4602 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4603 } else if (is_ia32_xDiv(new_pred)) {
4604 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4605 } else if (is_ia32_vfdiv(new_pred)) {
4606 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4608 panic("Div transformed to unexpected thing %+F", new_pred);
4611 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4612 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4613 } else if (is_ia32_xDiv(new_pred)) {
4614 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4615 } else if (is_ia32_vfdiv(new_pred)) {
4616 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4618 panic("Div transformed to unexpected thing %+F", new_pred);
4620 case pn_Div_X_regular:
4621 return new_rd_Jmp(dbgi, block);
4622 case pn_Div_X_except:
4623 set_ia32_exc_label(new_pred, 1);
4624 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4629 panic("No idea how to transform proj->Div");
4633 * Transform and renumber the Projs from a Div or Mod instruction.
4635 static ir_node *gen_Proj_Mod(ir_node *node)
4637 ir_node *pred = get_Proj_pred(node);
4638 ir_node *new_pred = be_transform_node(pred);
4639 dbg_info *dbgi = get_irn_dbg_info(node);
4640 long proj = get_Proj_proj(node);
4642 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4643 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4644 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4648 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4650 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4651 case pn_Mod_X_except:
4652 set_ia32_exc_label(new_pred, 1);
4653 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4657 panic("No idea how to transform proj->Mod");
4661 * Transform and renumber the Projs from a CopyB.
4663 static ir_node *gen_Proj_CopyB(ir_node *node)
4665 ir_node *pred = get_Proj_pred(node);
4666 ir_node *new_pred = be_transform_node(pred);
4667 dbg_info *dbgi = get_irn_dbg_info(node);
4668 long proj = get_Proj_proj(node);
4672 if (is_ia32_CopyB_i(new_pred)) {
4673 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4674 } else if (is_ia32_CopyB(new_pred)) {
4675 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4682 panic("No idea how to transform proj->CopyB");
4685 static ir_node *gen_be_Call(ir_node *node)
4687 dbg_info *const dbgi = get_irn_dbg_info(node);
4688 ir_node *const src_block = get_nodes_block(node);
4689 ir_node *const block = be_transform_node(src_block);
4690 ir_node *const src_mem = get_irn_n(node, n_be_Call_mem);
4691 ir_node *const src_sp = get_irn_n(node, n_be_Call_sp);
4692 ir_node *const sp = be_transform_node(src_sp);
4693 ir_node *const src_ptr = get_irn_n(node, n_be_Call_ptr);
4694 ia32_address_mode_t am;
4695 ia32_address_t *const addr = &am.addr;
4700 ir_node * eax = noreg_GP;
4701 ir_node * ecx = noreg_GP;
4702 ir_node * edx = noreg_GP;
4703 unsigned const pop = be_Call_get_pop(node);
4704 ir_type *const call_tp = be_Call_get_type(node);
4705 int old_no_pic_adjust;
4707 /* Run the x87 simulator if the call returns a float value */
4708 if (get_method_n_ress(call_tp) > 0) {
4709 ir_type *const res_type = get_method_res_type(call_tp, 0);
4710 ir_mode *const res_mode = get_type_mode(res_type);
4712 if (res_mode != NULL && mode_is_float(res_mode)) {
4713 ir_graph *irg = current_ir_graph;
4714 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4715 irg_data->do_x87_sim = 1;
4719 /* We do not want be_Call direct calls */
4720 assert(be_Call_get_entity(node) == NULL);
4722 /* special case for PIC trampoline calls */
4723 old_no_pic_adjust = ia32_no_pic_adjust;
4724 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4726 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4727 match_am | match_immediate);
4729 ia32_no_pic_adjust = old_no_pic_adjust;
4731 i = get_irn_arity(node) - 1;
4732 fpcw = be_transform_node(get_irn_n(node, i--));
4733 for (; i >= n_be_Call_first_arg; --i) {
4734 arch_register_req_t const *const req = arch_get_register_req(node, i);
4735 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4737 assert(req->type == arch_register_req_type_limited);
4738 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4740 switch (*req->limited) {
4741 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4742 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4743 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4744 default: panic("Invalid GP register for register parameter");
4748 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4749 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4750 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4751 set_am_attributes(call, &am);
4752 call = fix_mem_proj(call, &am);
4754 if (get_irn_pinned(node) == op_pin_state_pinned)
4755 set_irn_pinned(call, op_pin_state_pinned);
4757 SET_IA32_ORIG_NODE(call, node);
4759 if (ia32_cg_config.use_sse2) {
4760 /* remember this call for post-processing */
4761 ARR_APP1(ir_node *, call_list, call);
4762 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4769 * Transform Builtin trap
4771 static ir_node *gen_trap(ir_node *node)
4773 dbg_info *dbgi = get_irn_dbg_info(node);
4774 ir_node *block = be_transform_node(get_nodes_block(node));
4775 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4777 return new_bd_ia32_UD2(dbgi, block, mem);
4781 * Transform Builtin debugbreak
4783 static ir_node *gen_debugbreak(ir_node *node)
4785 dbg_info *dbgi = get_irn_dbg_info(node);
4786 ir_node *block = be_transform_node(get_nodes_block(node));
4787 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4789 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4793 * Transform Builtin return_address
4795 static ir_node *gen_return_address(ir_node *node)
4797 ir_node *param = get_Builtin_param(node, 0);
4798 ir_node *frame = get_Builtin_param(node, 1);
4799 dbg_info *dbgi = get_irn_dbg_info(node);
4800 ir_tarval *tv = get_Const_tarval(param);
4801 unsigned long value = get_tarval_long(tv);
4803 ir_node *block = be_transform_node(get_nodes_block(node));
4804 ir_node *ptr = be_transform_node(frame);
4808 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4809 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4810 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4813 /* load the return address from this frame */
4814 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4816 set_irn_pinned(load, get_irn_pinned(node));
4817 set_ia32_op_type(load, ia32_AddrModeS);
4818 set_ia32_ls_mode(load, mode_Iu);
4820 set_ia32_am_offs_int(load, 0);
4821 set_ia32_use_frame(load);
4822 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4824 if (get_irn_pinned(node) == op_pin_state_floats) {
4825 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4826 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4827 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4828 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4831 SET_IA32_ORIG_NODE(load, node);
4832 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4836 * Transform Builtin frame_address
4838 static ir_node *gen_frame_address(ir_node *node)
4840 ir_node *param = get_Builtin_param(node, 0);
4841 ir_node *frame = get_Builtin_param(node, 1);
4842 dbg_info *dbgi = get_irn_dbg_info(node);
4843 ir_tarval *tv = get_Const_tarval(param);
4844 unsigned long value = get_tarval_long(tv);
4846 ir_node *block = be_transform_node(get_nodes_block(node));
4847 ir_node *ptr = be_transform_node(frame);
4852 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4853 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4854 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4857 /* load the frame address from this frame */
4858 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4860 set_irn_pinned(load, get_irn_pinned(node));
4861 set_ia32_op_type(load, ia32_AddrModeS);
4862 set_ia32_ls_mode(load, mode_Iu);
4864 ent = ia32_get_frame_address_entity();
4866 set_ia32_am_offs_int(load, 0);
4867 set_ia32_use_frame(load);
4868 set_ia32_frame_ent(load, ent);
4870 /* will fail anyway, but gcc does this: */
4871 set_ia32_am_offs_int(load, 0);
4874 if (get_irn_pinned(node) == op_pin_state_floats) {
4875 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4876 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4877 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4878 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4881 SET_IA32_ORIG_NODE(load, node);
4882 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4886 * Transform Builtin frame_address
4888 static ir_node *gen_prefetch(ir_node *node)
4891 ir_node *ptr, *block, *mem, *base, *index;
4892 ir_node *param, *new_node;
4895 ia32_address_t addr;
4897 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4898 /* no prefetch at all, route memory */
4899 return be_transform_node(get_Builtin_mem(node));
4902 param = get_Builtin_param(node, 1);
4903 tv = get_Const_tarval(param);
4904 rw = get_tarval_long(tv);
4906 /* construct load address */
4907 memset(&addr, 0, sizeof(addr));
4908 ptr = get_Builtin_param(node, 0);
4909 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4916 base = be_transform_node(base);
4919 if (index == NULL) {
4922 index = be_transform_node(index);
4925 dbgi = get_irn_dbg_info(node);
4926 block = be_transform_node(get_nodes_block(node));
4927 mem = be_transform_node(get_Builtin_mem(node));
4929 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4930 /* we have 3DNow!, this was already checked above */
4931 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4932 } else if (ia32_cg_config.use_sse_prefetch) {
4933 /* note: rw == 1 is IGNORED in that case */
4934 param = get_Builtin_param(node, 2);
4935 tv = get_Const_tarval(param);
4936 locality = get_tarval_long(tv);
4938 /* SSE style prefetch */
4941 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4944 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4947 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4950 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4954 assert(ia32_cg_config.use_3dnow_prefetch);
4955 /* 3DNow! style prefetch */
4956 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4959 set_irn_pinned(new_node, get_irn_pinned(node));
4960 set_ia32_op_type(new_node, ia32_AddrModeS);
4961 set_ia32_ls_mode(new_node, mode_Bu);
4962 set_address(new_node, &addr);
4964 SET_IA32_ORIG_NODE(new_node, node);
4966 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4970 * Transform bsf like node
4972 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4974 ir_node *param = get_Builtin_param(node, 0);
4975 dbg_info *dbgi = get_irn_dbg_info(node);
4977 ir_node *block = get_nodes_block(node);
4978 ir_node *new_block = be_transform_node(block);
4980 ia32_address_mode_t am;
4981 ia32_address_t *addr = &am.addr;
4984 match_arguments(&am, block, NULL, param, NULL, match_am);
4986 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4987 set_am_attributes(cnt, &am);
4988 set_ia32_ls_mode(cnt, get_irn_mode(param));
4990 SET_IA32_ORIG_NODE(cnt, node);
4991 return fix_mem_proj(cnt, &am);
4995 * Transform builtin ffs.
4997 static ir_node *gen_ffs(ir_node *node)
4999 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5000 ir_node *real = skip_Proj(bsf);
5001 dbg_info *dbgi = get_irn_dbg_info(real);
5002 ir_node *block = get_nodes_block(real);
5003 ir_node *flag, *set, *conv, *neg, *orn, *add;
5006 if (get_irn_mode(real) != mode_T) {
5007 set_irn_mode(real, mode_T);
5008 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5011 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5014 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5015 SET_IA32_ORIG_NODE(set, node);
5018 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5019 SET_IA32_ORIG_NODE(conv, node);
5022 neg = new_bd_ia32_Neg(dbgi, block, conv);
5025 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5026 set_ia32_commutative(orn);
5029 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5030 add_ia32_am_offs_int(add, 1);
5035 * Transform builtin clz.
5037 static ir_node *gen_clz(ir_node *node)
5039 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5040 ir_node *real = skip_Proj(bsr);
5041 dbg_info *dbgi = get_irn_dbg_info(real);
5042 ir_node *block = get_nodes_block(real);
5043 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5045 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5049 * Transform builtin ctz.
5051 static ir_node *gen_ctz(ir_node *node)
5053 return gen_unop_AM(node, new_bd_ia32_Bsf);
5057 * Transform builtin parity.
5059 static ir_node *gen_parity(ir_node *node)
5061 dbg_info *dbgi = get_irn_dbg_info(node);
5062 ir_node *block = get_nodes_block(node);
5063 ir_node *new_block = be_transform_node(block);
5064 ir_node *param = get_Builtin_param(node, 0);
5065 ir_node *new_param = be_transform_node(param);
5068 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5069 * so we have to do complicated xoring first.
5070 * (we should also better lower this before the backend so we still have a
5071 * chance for CSE, constant folding and other goodies for some of these
5074 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5075 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5076 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5078 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5081 set_irn_mode(xor2, mode_T);
5082 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5085 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5086 SET_IA32_ORIG_NODE(new_node, node);
5089 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5090 nomem, new_node, mode_Bu);
5091 SET_IA32_ORIG_NODE(new_node, node);
5096 * Transform builtin popcount
5098 static ir_node *gen_popcount(ir_node *node)
5100 ir_node *param = get_Builtin_param(node, 0);
5101 dbg_info *dbgi = get_irn_dbg_info(node);
5103 ir_node *block = get_nodes_block(node);
5104 ir_node *new_block = be_transform_node(block);
5107 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5109 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5110 if (ia32_cg_config.use_popcnt) {
5111 ia32_address_mode_t am;
5112 ia32_address_t *addr = &am.addr;
5115 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5117 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5118 set_am_attributes(cnt, &am);
5119 set_ia32_ls_mode(cnt, get_irn_mode(param));
5121 SET_IA32_ORIG_NODE(cnt, node);
5122 return fix_mem_proj(cnt, &am);
5125 new_param = be_transform_node(param);
5127 /* do the standard popcount algo */
5128 /* TODO: This is stupid, we should transform this before the backend,
5129 * to get CSE, localopts, etc. for the operations
5130 * TODO: This is also not the optimal algorithm (it is just the starting
5131 * example in hackers delight, they optimize it more on the following page)
5132 * But I'm too lazy to fix this now, as the code should get lowered before
5133 * the backend anyway.
5136 /* m1 = x & 0x55555555 */
5137 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5138 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5141 simm = ia32_create_Immediate(NULL, 0, 1);
5142 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5144 /* m2 = s1 & 0x55555555 */
5145 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5148 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5150 /* m4 = m3 & 0x33333333 */
5151 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5152 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5155 simm = ia32_create_Immediate(NULL, 0, 2);
5156 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5158 /* m5 = s2 & 0x33333333 */
5159 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5162 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5164 /* m7 = m6 & 0x0F0F0F0F */
5165 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5166 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5169 simm = ia32_create_Immediate(NULL, 0, 4);
5170 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5172 /* m8 = s3 & 0x0F0F0F0F */
5173 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5176 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5178 /* m10 = m9 & 0x00FF00FF */
5179 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5180 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5183 simm = ia32_create_Immediate(NULL, 0, 8);
5184 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5186 /* m11 = s4 & 0x00FF00FF */
5187 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5189 /* m12 = m10 + m11 */
5190 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5192 /* m13 = m12 & 0x0000FFFF */
5193 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5194 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5196 /* s5 = m12 >> 16 */
5197 simm = ia32_create_Immediate(NULL, 0, 16);
5198 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5200 /* res = m13 + s5 */
5201 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5205 * Transform builtin byte swap.
5207 static ir_node *gen_bswap(ir_node *node)
5209 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5210 dbg_info *dbgi = get_irn_dbg_info(node);
5212 ir_node *block = get_nodes_block(node);
5213 ir_node *new_block = be_transform_node(block);
5214 ir_mode *mode = get_irn_mode(param);
5215 unsigned size = get_mode_size_bits(mode);
5216 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5220 if (ia32_cg_config.use_i486) {
5221 /* swap available */
5222 return new_bd_ia32_Bswap(dbgi, new_block, param);
5224 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5225 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5227 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5228 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5230 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5232 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5233 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5235 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5236 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5239 /* swap16 always available */
5240 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5243 panic("Invalid bswap size (%d)", size);
5248 * Transform builtin outport.
5250 static ir_node *gen_outport(ir_node *node)
5252 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5253 ir_node *oldv = get_Builtin_param(node, 1);
5254 ir_mode *mode = get_irn_mode(oldv);
5255 ir_node *value = be_transform_node(oldv);
5256 ir_node *block = be_transform_node(get_nodes_block(node));
5257 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5258 dbg_info *dbgi = get_irn_dbg_info(node);
5260 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5261 set_ia32_ls_mode(res, mode);
5266 * Transform builtin inport.
5268 static ir_node *gen_inport(ir_node *node)
5270 ir_type *tp = get_Builtin_type(node);
5271 ir_type *rstp = get_method_res_type(tp, 0);
5272 ir_mode *mode = get_type_mode(rstp);
5273 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5274 ir_node *block = be_transform_node(get_nodes_block(node));
5275 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5276 dbg_info *dbgi = get_irn_dbg_info(node);
5278 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5279 set_ia32_ls_mode(res, mode);
5281 /* check for missing Result Proj */
5286 * Transform a builtin inner trampoline
5288 static ir_node *gen_inner_trampoline(ir_node *node)
5290 ir_node *ptr = get_Builtin_param(node, 0);
5291 ir_node *callee = get_Builtin_param(node, 1);
5292 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5293 ir_node *mem = get_Builtin_mem(node);
5294 ir_node *block = get_nodes_block(node);
5295 ir_node *new_block = be_transform_node(block);
5299 ir_node *trampoline;
5301 dbg_info *dbgi = get_irn_dbg_info(node);
5302 ia32_address_t addr;
5304 /* construct store address */
5305 memset(&addr, 0, sizeof(addr));
5306 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5308 if (addr.base == NULL) {
5309 addr.base = noreg_GP;
5311 addr.base = be_transform_node(addr.base);
5314 if (addr.index == NULL) {
5315 addr.index = noreg_GP;
5317 addr.index = be_transform_node(addr.index);
5319 addr.mem = be_transform_node(mem);
5321 /* mov ecx, <env> */
5322 val = ia32_create_Immediate(NULL, 0, 0xB9);
5323 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5324 addr.index, addr.mem, val);
5325 set_irn_pinned(store, get_irn_pinned(node));
5326 set_ia32_op_type(store, ia32_AddrModeD);
5327 set_ia32_ls_mode(store, mode_Bu);
5328 set_address(store, &addr);
5332 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5333 addr.index, addr.mem, env);
5334 set_irn_pinned(store, get_irn_pinned(node));
5335 set_ia32_op_type(store, ia32_AddrModeD);
5336 set_ia32_ls_mode(store, mode_Iu);
5337 set_address(store, &addr);
5341 /* jmp rel <callee> */
5342 val = ia32_create_Immediate(NULL, 0, 0xE9);
5343 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5344 addr.index, addr.mem, val);
5345 set_irn_pinned(store, get_irn_pinned(node));
5346 set_ia32_op_type(store, ia32_AddrModeD);
5347 set_ia32_ls_mode(store, mode_Bu);
5348 set_address(store, &addr);
5352 trampoline = be_transform_node(ptr);
5354 /* the callee is typically an immediate */
5355 if (is_SymConst(callee)) {
5356 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5358 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5359 add_ia32_am_offs_int(rel, -10);
5361 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5363 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5364 addr.index, addr.mem, rel);
5365 set_irn_pinned(store, get_irn_pinned(node));
5366 set_ia32_op_type(store, ia32_AddrModeD);
5367 set_ia32_ls_mode(store, mode_Iu);
5368 set_address(store, &addr);
5373 return new_r_Tuple(new_block, 2, in);
5377 * Transform Builtin node.
5379 static ir_node *gen_Builtin(ir_node *node)
5381 ir_builtin_kind kind = get_Builtin_kind(node);
5385 return gen_trap(node);
5386 case ir_bk_debugbreak:
5387 return gen_debugbreak(node);
5388 case ir_bk_return_address:
5389 return gen_return_address(node);
5390 case ir_bk_frame_address:
5391 return gen_frame_address(node);
5392 case ir_bk_prefetch:
5393 return gen_prefetch(node);
5395 return gen_ffs(node);
5397 return gen_clz(node);
5399 return gen_ctz(node);
5401 return gen_parity(node);
5402 case ir_bk_popcount:
5403 return gen_popcount(node);
5405 return gen_bswap(node);
5407 return gen_outport(node);
5409 return gen_inport(node);
5410 case ir_bk_inner_trampoline:
5411 return gen_inner_trampoline(node);
5413 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5417 * Transform Proj(Builtin) node.
5419 static ir_node *gen_Proj_Builtin(ir_node *proj)
5421 ir_node *node = get_Proj_pred(proj);
5422 ir_node *new_node = be_transform_node(node);
5423 ir_builtin_kind kind = get_Builtin_kind(node);
5426 case ir_bk_return_address:
5427 case ir_bk_frame_address:
5432 case ir_bk_popcount:
5434 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5437 case ir_bk_debugbreak:
5438 case ir_bk_prefetch:
5440 assert(get_Proj_proj(proj) == pn_Builtin_M);
5443 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5444 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5446 assert(get_Proj_proj(proj) == pn_Builtin_M);
5447 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5449 case ir_bk_inner_trampoline:
5450 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5451 return get_Tuple_pred(new_node, 1);
5453 assert(get_Proj_proj(proj) == pn_Builtin_M);
5454 return get_Tuple_pred(new_node, 0);
5457 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5460 static ir_node *gen_be_IncSP(ir_node *node)
5462 ir_node *res = be_duplicate_node(node);
5463 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5469 * Transform the Projs from a be_Call.
5471 static ir_node *gen_Proj_be_Call(ir_node *node)
5473 ir_node *call = get_Proj_pred(node);
5474 ir_node *new_call = be_transform_node(call);
5475 dbg_info *dbgi = get_irn_dbg_info(node);
5476 long proj = get_Proj_proj(node);
5477 ir_mode *mode = get_irn_mode(node);
5480 if (proj == pn_be_Call_M_regular) {
5481 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5483 /* transform call modes */
5484 if (mode_is_data(mode)) {
5485 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5489 /* Map from be_Call to ia32_Call proj number */
5490 if (proj == pn_be_Call_sp) {
5491 proj = pn_ia32_Call_stack;
5492 } else if (proj == pn_be_Call_M_regular) {
5493 proj = pn_ia32_Call_M;
5495 arch_register_req_t const *const req = arch_get_register_req_out(node);
5496 int const n_outs = arch_irn_get_n_outs(new_call);
5499 assert(proj >= pn_be_Call_first_res);
5500 assert(req->type & arch_register_req_type_limited);
5502 for (i = 0; i < n_outs; ++i) {
5503 arch_register_req_t const *const new_req
5504 = arch_get_out_register_req(new_call, i);
5506 if (!(new_req->type & arch_register_req_type_limited) ||
5507 new_req->cls != req->cls ||
5508 *new_req->limited != *req->limited)
5517 res = new_rd_Proj(dbgi, new_call, mode, proj);
5519 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5521 case pn_ia32_Call_stack:
5522 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5525 case pn_ia32_Call_fpcw:
5526 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5534 * Transform the Projs from a Cmp.
5536 static ir_node *gen_Proj_Cmp(ir_node *node)
5538 /* this probably means not all mode_b nodes were lowered... */
5539 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5543 static ir_node *gen_Proj_ASM(ir_node *node)
5545 ir_mode *mode = get_irn_mode(node);
5546 ir_node *pred = get_Proj_pred(node);
5547 ir_node *new_pred = be_transform_node(pred);
5548 long pos = get_Proj_proj(node);
5550 if (mode == mode_M) {
5551 pos = arch_irn_get_n_outs(new_pred)-1;
5552 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5554 } else if (mode_is_float(mode)) {
5557 panic("unexpected proj mode at ASM");
5560 return new_r_Proj(new_pred, mode, pos);
5564 * Transform and potentially renumber Proj nodes.
5566 static ir_node *gen_Proj(ir_node *node)
5568 ir_node *pred = get_Proj_pred(node);
5571 switch (get_irn_opcode(pred)) {
5573 proj = get_Proj_proj(node);
5574 if (proj == pn_Store_M) {
5575 return be_transform_node(pred);
5577 panic("No idea how to transform proj->Store");
5580 return gen_Proj_Load(node);
5582 return gen_Proj_ASM(node);
5584 return gen_Proj_Builtin(node);
5586 return gen_Proj_Div(node);
5588 return gen_Proj_Mod(node);
5590 return gen_Proj_CopyB(node);
5592 return gen_Proj_be_SubSP(node);
5594 return gen_Proj_be_AddSP(node);
5596 return gen_Proj_be_Call(node);
5598 return gen_Proj_Cmp(node);
5600 proj = get_Proj_proj(node);
5602 case pn_Start_X_initial_exec: {
5603 ir_node *block = get_nodes_block(pred);
5604 ir_node *new_block = be_transform_node(block);
5605 dbg_info *dbgi = get_irn_dbg_info(node);
5606 /* we exchange the ProjX with a jump */
5607 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5615 if (is_ia32_l_FloattoLL(pred)) {
5616 return gen_Proj_l_FloattoLL(node);
5618 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5622 ir_mode *mode = get_irn_mode(node);
5623 if (ia32_mode_needs_gp_reg(mode)) {
5624 ir_node *new_pred = be_transform_node(pred);
5625 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5626 get_Proj_proj(node));
5627 new_proj->node_nr = node->node_nr;
5632 return be_duplicate_node(node);
5636 * Enters all transform functions into the generic pointer
5638 static void register_transformers(void)
5640 /* first clear the generic function pointer for all ops */
5641 be_start_transform_setup();
5643 be_set_transform_function(op_Add, gen_Add);
5644 be_set_transform_function(op_And, gen_And);
5645 be_set_transform_function(op_ASM, ia32_gen_ASM);
5646 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5647 be_set_transform_function(op_be_Call, gen_be_Call);
5648 be_set_transform_function(op_be_Copy, gen_be_Copy);
5649 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5650 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5651 be_set_transform_function(op_be_Return, gen_be_Return);
5652 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5653 be_set_transform_function(op_Builtin, gen_Builtin);
5654 be_set_transform_function(op_Cmp, gen_Cmp);
5655 be_set_transform_function(op_Cond, gen_Cond);
5656 be_set_transform_function(op_Const, gen_Const);
5657 be_set_transform_function(op_Conv, gen_Conv);
5658 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5659 be_set_transform_function(op_Div, gen_Div);
5660 be_set_transform_function(op_Eor, gen_Eor);
5661 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5662 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5663 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5664 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5665 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5666 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5667 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5668 be_set_transform_function(op_ia32_l_SarDep, gen_ia32_l_SarDep);
5669 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5670 be_set_transform_function(op_ia32_l_ShlDep, gen_ia32_l_ShlDep);
5671 be_set_transform_function(op_ia32_l_ShlD, gen_ia32_l_ShlD);
5672 be_set_transform_function(op_ia32_l_ShrDep, gen_ia32_l_ShrDep);
5673 be_set_transform_function(op_ia32_l_ShrD, gen_ia32_l_ShrD);
5674 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5675 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5676 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5677 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5678 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5679 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5680 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5681 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5682 be_set_transform_function(op_IJmp, gen_IJmp);
5683 be_set_transform_function(op_Jmp, gen_Jmp);
5684 be_set_transform_function(op_Load, gen_Load);
5685 be_set_transform_function(op_Minus, gen_Minus);
5686 be_set_transform_function(op_Mod, gen_Mod);
5687 be_set_transform_function(op_Mul, gen_Mul);
5688 be_set_transform_function(op_Mulh, gen_Mulh);
5689 be_set_transform_function(op_Mux, gen_Mux);
5690 be_set_transform_function(op_Not, gen_Not);
5691 be_set_transform_function(op_Or, gen_Or);
5692 be_set_transform_function(op_Phi, gen_Phi);
5693 be_set_transform_function(op_Proj, gen_Proj);
5694 be_set_transform_function(op_Rotl, gen_Rotl);
5695 be_set_transform_function(op_Shl, gen_Shl);
5696 be_set_transform_function(op_Shr, gen_Shr);
5697 be_set_transform_function(op_Shrs, gen_Shrs);
5698 be_set_transform_function(op_Store, gen_Store);
5699 be_set_transform_function(op_Sub, gen_Sub);
5700 be_set_transform_function(op_SymConst, gen_SymConst);
5701 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5705 * Pre-transform all unknown and noreg nodes.
5707 static void ia32_pretransform_node(void)
5709 ir_graph *irg = current_ir_graph;
5710 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5712 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5713 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5714 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5715 irg_data->get_eip = be_pre_transform_node(irg_data->get_eip);
5716 irg_data->fpu_trunc_mode = be_pre_transform_node(irg_data->fpu_trunc_mode);
5718 nomem = get_irg_no_mem(irg);
5719 noreg_GP = ia32_new_NoReg_gp(irg);
5725 * Post-process all calls if we are in SSE mode.
5726 * The ABI requires that the results are in st0, copy them
5727 * to a xmm register.
5729 static void postprocess_fp_call_results(void)
5733 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5734 ir_node *call = call_list[i];
5735 ir_type *mtp = call_types[i];
5738 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5739 ir_type *res_tp = get_method_res_type(mtp, j);
5740 ir_node *res, *new_res;
5741 const ir_edge_t *edge, *next;
5744 if (! is_atomic_type(res_tp)) {
5745 /* no floating point return */
5748 mode = get_type_mode(res_tp);
5749 if (! mode_is_float(mode)) {
5750 /* no floating point return */
5754 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5757 /* now patch the users */
5758 foreach_out_edge_safe(res, edge, next) {
5759 ir_node *succ = get_edge_src_irn(edge);
5762 if (be_is_Keep(succ))
5765 if (is_ia32_xStore(succ)) {
5766 /* an xStore can be patched into an vfst */
5767 dbg_info *db = get_irn_dbg_info(succ);
5768 ir_node *block = get_nodes_block(succ);
5769 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5770 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5771 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5772 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5773 ir_mode *mode = get_ia32_ls_mode(succ);
5775 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5776 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5777 if (is_ia32_use_frame(succ))
5778 set_ia32_use_frame(st);
5779 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5780 set_irn_pinned(st, get_irn_pinned(succ));
5781 set_ia32_op_type(st, ia32_AddrModeD);
5785 if (new_res == NULL) {
5786 dbg_info *db = get_irn_dbg_info(call);
5787 ir_node *block = get_nodes_block(call);
5788 ir_node *frame = get_irg_frame(current_ir_graph);
5789 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5790 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5791 ir_node *vfst, *xld, *new_mem;
5793 /* store st(0) on stack */
5794 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5795 set_ia32_op_type(vfst, ia32_AddrModeD);
5796 set_ia32_use_frame(vfst);
5798 /* load into SSE register */
5799 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5800 set_ia32_op_type(xld, ia32_AddrModeS);
5801 set_ia32_use_frame(xld);
5803 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5804 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5806 if (old_mem != NULL) {
5807 edges_reroute(old_mem, new_mem);
5811 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5818 /* do the transformation */
5819 void ia32_transform_graph(ir_graph *irg)
5823 register_transformers();
5824 initial_fpcw = NULL;
5825 ia32_no_pic_adjust = 0;
5827 be_timer_push(T_HEIGHTS);
5828 ia32_heights = heights_new(irg);
5829 be_timer_pop(T_HEIGHTS);
5830 ia32_calculate_non_address_mode_nodes(irg);
5832 /* the transform phase is not safe for CSE (yet) because several nodes get
5833 * attributes set after their creation */
5834 cse_last = get_opt_cse();
5837 call_list = NEW_ARR_F(ir_node *, 0);
5838 call_types = NEW_ARR_F(ir_type *, 0);
5839 be_transform_graph(irg, ia32_pretransform_node);
5841 if (ia32_cg_config.use_sse2)
5842 postprocess_fp_call_results();
5843 DEL_ARR_F(call_types);
5844 DEL_ARR_F(call_list);
5846 set_opt_cse(cse_last);
5848 ia32_free_non_address_mode_nodes();
5849 heights_free(ia32_heights);
5850 ia32_heights = NULL;
5853 void ia32_init_transform(void)
5855 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");