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_address_mode.h"
66 #include "ia32_architecture.h"
68 #include "gen_ia32_regalloc_if.h"
70 /* define this to construct SSE constants instead of load them */
71 #undef CONSTRUCT_SSE_CONST
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
79 #define ULL_BIAS "18446744073709551616"
81 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
82 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
83 #define ENT_SFP_ABS "C_ia32_sfp_abs"
84 #define ENT_DFP_ABS "C_ia32_dfp_abs"
85 #define ENT_ULL_BIAS "C_ia32_ull_bias"
87 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
88 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
90 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
92 static ir_node *old_initial_fpcw = 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)
1041 if (initial_fpcw != NULL)
1042 return initial_fpcw;
1044 initial_fpcw = be_transform_node(old_initial_fpcw);
1045 return initial_fpcw;
1049 * Construct a standard binary operation, set AM and immediate if required.
1051 * @param op1 The first operand
1052 * @param op2 The second operand
1053 * @param func The node constructor function
1054 * @return The constructed ia32 node.
1056 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1057 construct_binop_float_func *func)
1059 ir_mode *mode = get_irn_mode(node);
1061 ir_node *block, *new_block, *new_node;
1062 ia32_address_mode_t am;
1063 ia32_address_t *addr = &am.addr;
1064 ia32_x87_attr_t *attr;
1065 /* All operations are considered commutative, because there are reverse
1067 match_flags_t flags = match_commutative;
1069 /* happens for div nodes... */
1070 if (mode == mode_T) {
1072 mode = get_Div_resmode(node);
1074 panic("can't determine mode");
1077 /* cannot use address mode with long double on x87 */
1078 if (get_mode_size_bits(mode) <= 64)
1081 block = get_nodes_block(node);
1082 match_arguments(&am, block, op1, op2, NULL, flags);
1084 dbgi = get_irn_dbg_info(node);
1085 new_block = be_transform_node(block);
1086 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1087 am.new_op1, am.new_op2, get_fpcw());
1088 set_am_attributes(new_node, &am);
1090 attr = get_ia32_x87_attr(new_node);
1091 attr->attr.data.ins_permuted = am.ins_permuted;
1093 SET_IA32_ORIG_NODE(new_node, node);
1095 new_node = fix_mem_proj(new_node, &am);
1101 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1103 * @param op1 The first operand
1104 * @param op2 The second operand
1105 * @param func The node constructor function
1106 * @return The constructed ia32 node.
1108 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1109 construct_shift_func *func,
1110 match_flags_t flags)
1113 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1115 assert(! mode_is_float(get_irn_mode(node)));
1116 assert(flags & match_immediate);
1117 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1119 if (flags & match_mode_neutral) {
1120 op1 = ia32_skip_downconv(op1);
1121 new_op1 = be_transform_node(op1);
1122 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1123 new_op1 = create_upconv(op1, node);
1125 new_op1 = be_transform_node(op1);
1128 /* the shift amount can be any mode that is bigger than 5 bits, since all
1129 * other bits are ignored anyway */
1130 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1131 ir_node *const op = get_Conv_op(op2);
1132 if (mode_is_float(get_irn_mode(op)))
1135 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1137 new_op2 = create_immediate_or_transform(op2, 0);
1139 dbgi = get_irn_dbg_info(node);
1140 block = get_nodes_block(node);
1141 new_block = be_transform_node(block);
1142 new_node = func(dbgi, new_block, new_op1, new_op2);
1143 SET_IA32_ORIG_NODE(new_node, node);
1145 /* lowered shift instruction may have a dependency operand, handle it here */
1146 if (get_irn_arity(node) == 3) {
1147 /* we have a dependency */
1148 ir_node* dep = get_irn_n(node, 2);
1149 if (get_irn_n_edges(dep) > 1) {
1150 /* ... which has at least one user other than 'node' */
1151 ir_node *new_dep = be_transform_node(dep);
1152 add_irn_dep(new_node, new_dep);
1161 * Construct a standard unary operation, set AM and immediate if required.
1163 * @param op The operand
1164 * @param func The node constructor function
1165 * @return The constructed ia32 node.
1167 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1168 match_flags_t flags)
1171 ir_node *block, *new_block, *new_op, *new_node;
1173 assert(flags == 0 || flags == match_mode_neutral);
1174 if (flags & match_mode_neutral) {
1175 op = ia32_skip_downconv(op);
1178 new_op = be_transform_node(op);
1179 dbgi = get_irn_dbg_info(node);
1180 block = get_nodes_block(node);
1181 new_block = be_transform_node(block);
1182 new_node = func(dbgi, new_block, new_op);
1184 SET_IA32_ORIG_NODE(new_node, node);
1189 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1190 ia32_address_t *addr)
1192 ir_node *base, *index, *res;
1198 base = be_transform_node(base);
1201 index = addr->index;
1202 if (index == NULL) {
1205 index = be_transform_node(index);
1208 /* segment overrides are ineffective for Leas :-( so we have to patch
1210 if (addr->tls_segment) {
1211 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
1212 assert(addr->symconst_ent != NULL);
1213 if (base == noreg_GP)
1216 base = new_bd_ia32_Lea(dbgi, block, tls_base, base);
1217 addr->tls_segment = false;
1220 res = new_bd_ia32_Lea(dbgi, block, base, index);
1221 set_address(res, addr);
1227 * Returns non-zero if a given address mode has a symbolic or
1228 * numerical offset != 0.
1230 static int am_has_immediates(const ia32_address_t *addr)
1232 return addr->offset != 0 || addr->symconst_ent != NULL
1233 || addr->frame_entity || addr->use_frame;
1237 * Creates an ia32 Add.
1239 * @return the created ia32 Add node
1241 static ir_node *gen_Add(ir_node *node)
1243 ir_mode *mode = get_irn_mode(node);
1244 ir_node *op1 = get_Add_left(node);
1245 ir_node *op2 = get_Add_right(node);
1247 ir_node *block, *new_block, *new_node, *add_immediate_op;
1248 ia32_address_t addr;
1249 ia32_address_mode_t am;
1251 if (mode_is_float(mode)) {
1252 if (ia32_cg_config.use_sse2)
1253 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1254 match_commutative | match_am);
1256 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1259 ia32_mark_non_am(node);
1261 op2 = ia32_skip_downconv(op2);
1262 op1 = ia32_skip_downconv(op1);
1266 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1267 * 1. Add with immediate -> Lea
1268 * 2. Add with possible source address mode -> Add
1269 * 3. Otherwise -> Lea
1271 memset(&addr, 0, sizeof(addr));
1272 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1273 add_immediate_op = NULL;
1275 dbgi = get_irn_dbg_info(node);
1276 block = get_nodes_block(node);
1277 new_block = be_transform_node(block);
1280 if (addr.base == NULL && addr.index == NULL) {
1281 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1282 addr.symconst_sign, 0, addr.offset);
1283 SET_IA32_ORIG_NODE(new_node, node);
1286 /* add with immediate? */
1287 if (addr.index == NULL) {
1288 add_immediate_op = addr.base;
1289 } else if (addr.base == NULL && addr.scale == 0) {
1290 add_immediate_op = addr.index;
1293 if (add_immediate_op != NULL) {
1294 if (!am_has_immediates(&addr)) {
1295 #ifdef DEBUG_libfirm
1296 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1299 return be_transform_node(add_immediate_op);
1302 new_node = create_lea_from_address(dbgi, new_block, &addr);
1303 SET_IA32_ORIG_NODE(new_node, node);
1307 /* test if we can use source address mode */
1308 match_arguments(&am, block, op1, op2, NULL, match_commutative
1309 | match_mode_neutral | match_am | match_immediate | match_try_am);
1311 /* construct an Add with source address mode */
1312 if (am.op_type == ia32_AddrModeS) {
1313 ia32_address_t *am_addr = &am.addr;
1314 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1315 am_addr->index, am_addr->mem, am.new_op1,
1317 set_am_attributes(new_node, &am);
1318 SET_IA32_ORIG_NODE(new_node, node);
1320 new_node = fix_mem_proj(new_node, &am);
1325 /* otherwise construct a lea */
1326 new_node = create_lea_from_address(dbgi, new_block, &addr);
1327 SET_IA32_ORIG_NODE(new_node, node);
1332 * Creates an ia32 Mul.
1334 * @return the created ia32 Mul node
1336 static ir_node *gen_Mul(ir_node *node)
1338 ir_node *op1 = get_Mul_left(node);
1339 ir_node *op2 = get_Mul_right(node);
1340 ir_mode *mode = get_irn_mode(node);
1342 if (mode_is_float(mode)) {
1343 if (ia32_cg_config.use_sse2)
1344 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1345 match_commutative | match_am);
1347 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1349 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1350 match_commutative | match_am | match_mode_neutral |
1351 match_immediate | match_am_and_immediates);
1355 * Creates an ia32 Mulh.
1356 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1357 * this result while Mul returns the lower 32 bit.
1359 * @return the created ia32 Mulh node
1361 static ir_node *gen_Mulh(ir_node *node)
1363 dbg_info *dbgi = get_irn_dbg_info(node);
1364 ir_node *op1 = get_Mulh_left(node);
1365 ir_node *op2 = get_Mulh_right(node);
1366 ir_mode *mode = get_irn_mode(node);
1368 ir_node *proj_res_high;
1370 if (get_mode_size_bits(mode) != 32) {
1371 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1374 if (mode_is_signed(mode)) {
1375 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1376 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1378 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1379 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1381 return proj_res_high;
1385 * Creates an ia32 And.
1387 * @return The created ia32 And node
1389 static ir_node *gen_And(ir_node *node)
1391 ir_node *op1 = get_And_left(node);
1392 ir_node *op2 = get_And_right(node);
1393 assert(! mode_is_float(get_irn_mode(node)));
1395 /* is it a zero extension? */
1396 if (is_Const(op2)) {
1397 ir_tarval *tv = get_Const_tarval(op2);
1398 long v = get_tarval_long(tv);
1400 if (v == 0xFF || v == 0xFFFF) {
1401 dbg_info *dbgi = get_irn_dbg_info(node);
1402 ir_node *block = get_nodes_block(node);
1409 assert(v == 0xFFFF);
1412 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1417 return gen_binop(node, op1, op2, new_bd_ia32_And,
1418 match_commutative | match_mode_neutral | match_am | match_immediate);
1424 * Creates an ia32 Or.
1426 * @return The created ia32 Or node
1428 static ir_node *gen_Or(ir_node *node)
1430 ir_node *op1 = get_Or_left(node);
1431 ir_node *op2 = get_Or_right(node);
1433 assert (! mode_is_float(get_irn_mode(node)));
1434 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1435 | match_mode_neutral | match_am | match_immediate);
1441 * Creates an ia32 Eor.
1443 * @return The created ia32 Eor node
1445 static ir_node *gen_Eor(ir_node *node)
1447 ir_node *op1 = get_Eor_left(node);
1448 ir_node *op2 = get_Eor_right(node);
1450 assert(! mode_is_float(get_irn_mode(node)));
1451 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1452 | match_mode_neutral | match_am | match_immediate);
1457 * Creates an ia32 Sub.
1459 * @return The created ia32 Sub node
1461 static ir_node *gen_Sub(ir_node *node)
1463 ir_node *op1 = get_Sub_left(node);
1464 ir_node *op2 = get_Sub_right(node);
1465 ir_mode *mode = get_irn_mode(node);
1467 if (mode_is_float(mode)) {
1468 if (ia32_cg_config.use_sse2)
1469 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1471 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1474 if (is_Const(op2)) {
1475 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1479 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1480 | match_am | match_immediate);
1483 static ir_node *transform_AM_mem(ir_node *const block,
1484 ir_node *const src_val,
1485 ir_node *const src_mem,
1486 ir_node *const am_mem)
1488 if (is_NoMem(am_mem)) {
1489 return be_transform_node(src_mem);
1490 } else if (is_Proj(src_val) &&
1492 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1493 /* avoid memory loop */
1495 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1496 ir_node *const ptr_pred = get_Proj_pred(src_val);
1497 int const arity = get_Sync_n_preds(src_mem);
1502 NEW_ARR_A(ir_node*, ins, arity + 1);
1504 /* NOTE: This sometimes produces dead-code because the old sync in
1505 * src_mem might not be used anymore, we should detect this case
1506 * and kill the sync... */
1507 for (i = arity - 1; i >= 0; --i) {
1508 ir_node *const pred = get_Sync_pred(src_mem, i);
1510 /* avoid memory loop */
1511 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1514 ins[n++] = be_transform_node(pred);
1517 if (n==1 && ins[0] == am_mem) {
1519 /* creating a new Sync and relying on CSE may fail,
1520 * if am_mem is a ProjM, which does not yet verify. */
1524 return new_r_Sync(block, n, ins);
1528 ins[0] = be_transform_node(src_mem);
1530 return new_r_Sync(block, 2, ins);
1535 * Create a 32bit to 64bit signed extension.
1537 * @param dbgi debug info
1538 * @param block the block where node nodes should be placed
1539 * @param val the value to extend
1540 * @param orig the original node
1542 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1543 ir_node *val, const ir_node *orig)
1548 if (ia32_cg_config.use_short_sex_eax) {
1549 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1550 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1552 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1553 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1555 SET_IA32_ORIG_NODE(res, orig);
1560 * Generates an ia32 Div with additional infrastructure for the
1561 * register allocator if needed.
1563 static ir_node *create_Div(ir_node *node)
1565 dbg_info *dbgi = get_irn_dbg_info(node);
1566 ir_node *block = get_nodes_block(node);
1567 ir_node *new_block = be_transform_node(block);
1574 ir_node *sign_extension;
1575 ia32_address_mode_t am;
1576 ia32_address_t *addr = &am.addr;
1578 /* the upper bits have random contents for smaller modes */
1579 switch (get_irn_opcode(node)) {
1581 op1 = get_Div_left(node);
1582 op2 = get_Div_right(node);
1583 mem = get_Div_mem(node);
1584 mode = get_Div_resmode(node);
1587 op1 = get_Mod_left(node);
1588 op2 = get_Mod_right(node);
1589 mem = get_Mod_mem(node);
1590 mode = get_Mod_resmode(node);
1593 panic("invalid divmod node %+F", node);
1596 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1598 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1599 is the memory of the consumed address. We can have only the second op as address
1600 in Div nodes, so check only op2. */
1601 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1603 if (mode_is_signed(mode)) {
1604 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1605 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1606 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1608 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1610 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1611 addr->index, new_mem, am.new_op2,
1612 am.new_op1, sign_extension);
1615 set_irn_pinned(new_node, get_irn_pinned(node));
1617 set_am_attributes(new_node, &am);
1618 SET_IA32_ORIG_NODE(new_node, node);
1620 new_node = fix_mem_proj(new_node, &am);
1626 * Generates an ia32 Mod.
1628 static ir_node *gen_Mod(ir_node *node)
1630 return create_Div(node);
1634 * Generates an ia32 Div.
1636 static ir_node *gen_Div(ir_node *node)
1638 ir_mode *mode = get_Div_resmode(node);
1639 if (mode_is_float(mode)) {
1640 ir_node *op1 = get_Div_left(node);
1641 ir_node *op2 = get_Div_right(node);
1643 if (ia32_cg_config.use_sse2) {
1644 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1646 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1650 return create_Div(node);
1654 * Creates an ia32 Shl.
1656 * @return The created ia32 Shl node
1658 static ir_node *gen_Shl(ir_node *node)
1660 ir_node *left = get_Shl_left(node);
1661 ir_node *right = get_Shl_right(node);
1663 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1664 match_mode_neutral | match_immediate);
1668 * Creates an ia32 Shr.
1670 * @return The created ia32 Shr node
1672 static ir_node *gen_Shr(ir_node *node)
1674 ir_node *left = get_Shr_left(node);
1675 ir_node *right = get_Shr_right(node);
1677 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1683 * Creates an ia32 Sar.
1685 * @return The created ia32 Shrs node
1687 static ir_node *gen_Shrs(ir_node *node)
1689 ir_node *left = get_Shrs_left(node);
1690 ir_node *right = get_Shrs_right(node);
1692 if (is_Const(right)) {
1693 ir_tarval *tv = get_Const_tarval(right);
1694 long val = get_tarval_long(tv);
1696 /* this is a sign extension */
1697 dbg_info *dbgi = get_irn_dbg_info(node);
1698 ir_node *block = be_transform_node(get_nodes_block(node));
1699 ir_node *new_op = be_transform_node(left);
1701 return create_sex_32_64(dbgi, block, new_op, node);
1705 /* 8 or 16 bit sign extension? */
1706 if (is_Const(right) && is_Shl(left)) {
1707 ir_node *shl_left = get_Shl_left(left);
1708 ir_node *shl_right = get_Shl_right(left);
1709 if (is_Const(shl_right)) {
1710 ir_tarval *tv1 = get_Const_tarval(right);
1711 ir_tarval *tv2 = get_Const_tarval(shl_right);
1712 if (tv1 == tv2 && tarval_is_long(tv1)) {
1713 long val = get_tarval_long(tv1);
1714 if (val == 16 || val == 24) {
1715 dbg_info *dbgi = get_irn_dbg_info(node);
1716 ir_node *block = get_nodes_block(node);
1726 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1735 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1741 * Creates an ia32 Rol.
1743 * @param op1 The first operator
1744 * @param op2 The second operator
1745 * @return The created ia32 RotL node
1747 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1749 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1755 * Creates an ia32 Ror.
1756 * NOTE: There is no RotR with immediate because this would always be a RotL
1757 * "imm-mode_size_bits" which can be pre-calculated.
1759 * @param op1 The first operator
1760 * @param op2 The second operator
1761 * @return The created ia32 RotR node
1763 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1765 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1771 * Creates an ia32 RotR or RotL (depending on the found pattern).
1773 * @return The created ia32 RotL or RotR node
1775 static ir_node *gen_Rotl(ir_node *node)
1777 ir_node *op1 = get_Rotl_left(node);
1778 ir_node *op2 = get_Rotl_right(node);
1780 if (is_Minus(op2)) {
1781 return gen_Ror(node, op1, get_Minus_op(op2));
1784 return gen_Rol(node, op1, op2);
1790 * Transforms a Minus node.
1792 * @return The created ia32 Minus node
1794 static ir_node *gen_Minus(ir_node *node)
1796 ir_node *op = get_Minus_op(node);
1797 ir_node *block = be_transform_node(get_nodes_block(node));
1798 dbg_info *dbgi = get_irn_dbg_info(node);
1799 ir_mode *mode = get_irn_mode(node);
1804 if (mode_is_float(mode)) {
1805 ir_node *new_op = be_transform_node(op);
1806 if (ia32_cg_config.use_sse2) {
1807 /* TODO: non-optimal... if we have many xXors, then we should
1808 * rather create a load for the const and use that instead of
1809 * several AM nodes... */
1810 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1812 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1813 noreg_GP, nomem, new_op, noreg_xmm);
1815 size = get_mode_size_bits(mode);
1816 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1818 set_ia32_am_sc(new_node, ent);
1819 set_ia32_op_type(new_node, ia32_AddrModeS);
1820 set_ia32_ls_mode(new_node, mode);
1822 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1825 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1828 SET_IA32_ORIG_NODE(new_node, node);
1834 * Transforms a Not node.
1836 * @return The created ia32 Not node
1838 static ir_node *gen_Not(ir_node *node)
1840 ir_node *op = get_Not_op(node);
1842 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1843 assert (! mode_is_float(get_irn_mode(node)));
1845 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1848 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1849 bool negate, ir_node *node)
1851 ir_node *new_block = be_transform_node(block);
1852 ir_mode *mode = get_irn_mode(op);
1858 if (mode_is_float(mode)) {
1859 new_op = be_transform_node(op);
1861 if (ia32_cg_config.use_sse2) {
1862 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1863 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1864 noreg_GP, nomem, new_op, noreg_fp);
1866 size = get_mode_size_bits(mode);
1867 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1869 set_ia32_am_sc(new_node, ent);
1871 SET_IA32_ORIG_NODE(new_node, node);
1873 set_ia32_op_type(new_node, ia32_AddrModeS);
1874 set_ia32_ls_mode(new_node, mode);
1876 /* TODO, implement -Abs case */
1879 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1880 SET_IA32_ORIG_NODE(new_node, node);
1882 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1883 SET_IA32_ORIG_NODE(new_node, node);
1888 ir_node *sign_extension;
1890 if (get_mode_size_bits(mode) == 32) {
1891 new_op = be_transform_node(op);
1893 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1896 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1898 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1899 nomem, new_op, sign_extension);
1900 SET_IA32_ORIG_NODE(xorn, node);
1903 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1904 nomem, sign_extension, xorn);
1906 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1907 nomem, xorn, sign_extension);
1909 SET_IA32_ORIG_NODE(new_node, node);
1916 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1918 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1920 dbg_info *dbgi = get_irn_dbg_info(cmp);
1921 ir_node *block = get_nodes_block(cmp);
1922 ir_node *new_block = be_transform_node(block);
1923 ir_node *op1 = be_transform_node(x);
1924 ir_node *op2 = be_transform_node(n);
1926 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1929 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
1932 if (mode_is_float(mode)) {
1934 case ir_relation_equal: return ia32_cc_float_equal;
1935 case ir_relation_less: return ia32_cc_float_below;
1936 case ir_relation_less_equal: return ia32_cc_float_below_equal;
1937 case ir_relation_greater: return ia32_cc_float_above;
1938 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
1939 case ir_relation_less_greater: return ia32_cc_not_equal;
1940 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
1941 case ir_relation_unordered: return ia32_cc_parity;
1942 case ir_relation_unordered_equal: return ia32_cc_equal;
1943 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
1944 case ir_relation_unordered_less_equal:
1945 return ia32_cc_float_unordered_below_equal;
1946 case ir_relation_unordered_greater:
1947 return ia32_cc_float_unordered_above;
1948 case ir_relation_unordered_greater_equal:
1949 return ia32_cc_float_unordered_above_equal;
1950 case ir_relation_unordered_less_greater:
1951 return ia32_cc_float_not_equal;
1952 case ir_relation_false:
1953 case ir_relation_true:
1954 /* should we introduce a jump always/jump never? */
1957 panic("Unexpected float pnc");
1958 } else if (mode_is_signed(mode)) {
1960 case ir_relation_unordered_equal:
1961 case ir_relation_equal: return ia32_cc_equal;
1962 case ir_relation_unordered_less:
1963 case ir_relation_less: return ia32_cc_less;
1964 case ir_relation_unordered_less_equal:
1965 case ir_relation_less_equal: return ia32_cc_less_equal;
1966 case ir_relation_unordered_greater:
1967 case ir_relation_greater: return ia32_cc_greater;
1968 case ir_relation_unordered_greater_equal:
1969 case ir_relation_greater_equal: return ia32_cc_greater_equal;
1970 case ir_relation_unordered_less_greater:
1971 case ir_relation_less_greater: return ia32_cc_not_equal;
1972 case ir_relation_less_equal_greater:
1973 case ir_relation_unordered:
1974 case ir_relation_false:
1975 case ir_relation_true:
1976 /* introduce jump always/jump never? */
1979 panic("Unexpected pnc");
1982 case ir_relation_unordered_equal:
1983 case ir_relation_equal: return ia32_cc_equal;
1984 case ir_relation_unordered_less:
1985 case ir_relation_less: return ia32_cc_below;
1986 case ir_relation_unordered_less_equal:
1987 case ir_relation_less_equal: return ia32_cc_below_equal;
1988 case ir_relation_unordered_greater:
1989 case ir_relation_greater: return ia32_cc_above;
1990 case ir_relation_unordered_greater_equal:
1991 case ir_relation_greater_equal: return ia32_cc_above_equal;
1992 case ir_relation_unordered_less_greater:
1993 case ir_relation_less_greater: return ia32_cc_not_equal;
1994 case ir_relation_less_equal_greater:
1995 case ir_relation_unordered:
1996 case ir_relation_false:
1997 case ir_relation_true:
1998 /* introduce jump always/jump never? */
2001 panic("Unexpected pnc");
2005 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
2007 /* a mode_b value, we have to compare it against 0 */
2008 dbg_info *dbgi = get_irn_dbg_info(node);
2009 ir_node *new_block = be_transform_node(get_nodes_block(node));
2010 ir_node *new_op = be_transform_node(node);
2011 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2012 *cc_out = ia32_cc_not_equal;
2016 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2018 /* must have a Cmp as input */
2019 ir_relation relation = get_Cmp_relation(cmp);
2020 ir_relation possible;
2021 ir_node *l = get_Cmp_left(cmp);
2022 ir_node *r = get_Cmp_right(cmp);
2023 ir_mode *mode = get_irn_mode(l);
2026 /* check for bit-test */
2027 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2028 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2029 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2031 ir_node *la = get_And_left(l);
2032 ir_node *ra = get_And_right(l);
2039 ir_node *c = get_Shl_left(la);
2040 if (is_Const_1(c) && is_Const_0(r)) {
2041 /* (1 << n) & ra) */
2042 ir_node *n = get_Shl_right(la);
2043 flags = gen_bt(cmp, ra, n);
2044 /* the bit is copied into the CF flag */
2045 if (relation & ir_relation_equal)
2046 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2048 *cc_out = ia32_cc_below; /* test for CF=1 */
2054 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2055 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2056 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2057 * a predecessor node). So add the < bit */
2058 possible = ir_get_possible_cmp_relations(l, r);
2059 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2060 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2061 relation |= ir_relation_less_greater;
2063 /* just do a normal transformation of the Cmp */
2064 *cc_out = relation_to_condition_code(relation, mode);
2065 flags = be_transform_node(cmp);
2070 * Transform a node returning a "flag" result.
2072 * @param node the node to transform
2073 * @param cc_out the compare mode to use
2075 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2078 return get_flags_node_cmp(node, cc_out);
2079 assert(get_irn_mode(node) == mode_b);
2080 return get_flags_mode_b(node, cc_out);
2084 * Transforms a Load.
2086 * @return the created ia32 Load node
2088 static ir_node *gen_Load(ir_node *node)
2090 ir_node *old_block = get_nodes_block(node);
2091 ir_node *block = be_transform_node(old_block);
2092 ir_node *ptr = get_Load_ptr(node);
2093 ir_node *mem = get_Load_mem(node);
2094 ir_node *new_mem = be_transform_node(mem);
2095 dbg_info *dbgi = get_irn_dbg_info(node);
2096 ir_mode *mode = get_Load_mode(node);
2100 ia32_address_t addr;
2102 /* construct load address */
2103 memset(&addr, 0, sizeof(addr));
2104 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2111 base = be_transform_node(base);
2114 if (index == NULL) {
2117 index = be_transform_node(index);
2120 if (mode_is_float(mode)) {
2121 if (ia32_cg_config.use_sse2) {
2122 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2125 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2129 assert(mode != mode_b);
2131 /* create a conv node with address mode for smaller modes */
2132 if (get_mode_size_bits(mode) < 32) {
2133 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2134 new_mem, noreg_GP, mode);
2136 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2140 set_irn_pinned(new_node, get_irn_pinned(node));
2141 set_ia32_op_type(new_node, ia32_AddrModeS);
2142 set_ia32_ls_mode(new_node, mode);
2143 set_address(new_node, &addr);
2145 if (get_irn_pinned(node) == op_pin_state_floats) {
2146 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2147 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2148 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2149 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2152 SET_IA32_ORIG_NODE(new_node, node);
2157 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2158 ir_node *ptr, ir_node *other)
2165 /* we only use address mode if we're the only user of the load */
2166 if (get_irn_n_edges(node) > 1)
2169 load = get_Proj_pred(node);
2172 if (get_nodes_block(load) != block)
2175 /* store should have the same pointer as the load */
2176 if (get_Load_ptr(load) != ptr)
2179 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2180 if (other != NULL &&
2181 get_nodes_block(other) == block &&
2182 heights_reachable_in_block(ia32_heights, other, load)) {
2186 if (ia32_prevents_AM(block, load, mem))
2188 /* Store should be attached to the load via mem */
2189 assert(heights_reachable_in_block(ia32_heights, mem, load));
2194 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2195 ir_node *mem, ir_node *ptr, ir_mode *mode,
2196 construct_binop_dest_func *func,
2197 construct_binop_dest_func *func8bit,
2198 match_flags_t flags)
2200 ir_node *src_block = get_nodes_block(node);
2208 ia32_address_mode_t am;
2209 ia32_address_t *addr = &am.addr;
2210 memset(&am, 0, sizeof(am));
2212 assert(flags & match_immediate); /* there is no destam node without... */
2213 commutative = (flags & match_commutative) != 0;
2215 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2216 build_address(&am, op1, ia32_create_am_double_use);
2217 new_op = create_immediate_or_transform(op2, 0);
2218 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2219 build_address(&am, op2, ia32_create_am_double_use);
2220 new_op = create_immediate_or_transform(op1, 0);
2225 if (addr->base == NULL)
2226 addr->base = noreg_GP;
2227 if (addr->index == NULL)
2228 addr->index = noreg_GP;
2229 if (addr->mem == NULL)
2232 dbgi = get_irn_dbg_info(node);
2233 block = be_transform_node(src_block);
2234 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2236 if (get_mode_size_bits(mode) == 8) {
2237 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2239 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2241 set_address(new_node, addr);
2242 set_ia32_op_type(new_node, ia32_AddrModeD);
2243 set_ia32_ls_mode(new_node, mode);
2244 SET_IA32_ORIG_NODE(new_node, node);
2246 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2247 mem_proj = be_transform_node(am.mem_proj);
2248 be_set_transformed_node(am.mem_proj, new_node);
2249 be_set_transformed_node(mem_proj, new_node);
2254 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2255 ir_node *ptr, ir_mode *mode,
2256 construct_unop_dest_func *func)
2258 ir_node *src_block = get_nodes_block(node);
2264 ia32_address_mode_t am;
2265 ia32_address_t *addr = &am.addr;
2267 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2270 memset(&am, 0, sizeof(am));
2271 build_address(&am, op, ia32_create_am_double_use);
2273 dbgi = get_irn_dbg_info(node);
2274 block = be_transform_node(src_block);
2275 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2276 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2277 set_address(new_node, addr);
2278 set_ia32_op_type(new_node, ia32_AddrModeD);
2279 set_ia32_ls_mode(new_node, mode);
2280 SET_IA32_ORIG_NODE(new_node, node);
2282 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2283 mem_proj = be_transform_node(am.mem_proj);
2284 be_set_transformed_node(am.mem_proj, new_node);
2285 be_set_transformed_node(mem_proj, new_node);
2290 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2292 ir_mode *mode = get_irn_mode(node);
2293 ir_node *mux_true = get_Mux_true(node);
2294 ir_node *mux_false = get_Mux_false(node);
2302 ia32_condition_code_t cc;
2303 ia32_address_t addr;
2305 if (get_mode_size_bits(mode) != 8)
2308 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2310 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2316 cond = get_Mux_sel(node);
2317 flags = get_flags_node(cond, &cc);
2318 /* we can't handle the float special cases with SetM */
2319 if (cc & ia32_cc_additional_float_cases)
2322 cc = ia32_negate_condition_code(cc);
2324 build_address_ptr(&addr, ptr, mem);
2326 dbgi = get_irn_dbg_info(node);
2327 block = get_nodes_block(node);
2328 new_block = be_transform_node(block);
2329 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2330 addr.index, addr.mem, flags, cc);
2331 set_address(new_node, &addr);
2332 set_ia32_op_type(new_node, ia32_AddrModeD);
2333 set_ia32_ls_mode(new_node, mode);
2334 SET_IA32_ORIG_NODE(new_node, node);
2339 static ir_node *try_create_dest_am(ir_node *node)
2341 ir_node *val = get_Store_value(node);
2342 ir_node *mem = get_Store_mem(node);
2343 ir_node *ptr = get_Store_ptr(node);
2344 ir_mode *mode = get_irn_mode(val);
2345 unsigned bits = get_mode_size_bits(mode);
2350 /* handle only GP modes for now... */
2351 if (!ia32_mode_needs_gp_reg(mode))
2355 /* store must be the only user of the val node */
2356 if (get_irn_n_edges(val) > 1)
2358 /* skip pointless convs */
2360 ir_node *conv_op = get_Conv_op(val);
2361 ir_mode *pred_mode = get_irn_mode(conv_op);
2362 if (!ia32_mode_needs_gp_reg(pred_mode))
2364 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2372 /* value must be in the same block */
2373 if (get_nodes_block(node) != get_nodes_block(val))
2376 switch (get_irn_opcode(val)) {
2378 op1 = get_Add_left(val);
2379 op2 = get_Add_right(val);
2380 if (ia32_cg_config.use_incdec) {
2381 if (is_Const_1(op2)) {
2382 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2384 } else if (is_Const_Minus_1(op2)) {
2385 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2389 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2390 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2391 match_commutative | match_immediate);
2394 op1 = get_Sub_left(val);
2395 op2 = get_Sub_right(val);
2396 if (is_Const(op2)) {
2397 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2399 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2400 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2404 op1 = get_And_left(val);
2405 op2 = get_And_right(val);
2406 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2407 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2408 match_commutative | match_immediate);
2411 op1 = get_Or_left(val);
2412 op2 = get_Or_right(val);
2413 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2414 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2415 match_commutative | match_immediate);
2418 op1 = get_Eor_left(val);
2419 op2 = get_Eor_right(val);
2420 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2421 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2422 match_commutative | match_immediate);
2425 op1 = get_Shl_left(val);
2426 op2 = get_Shl_right(val);
2427 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2428 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2432 op1 = get_Shr_left(val);
2433 op2 = get_Shr_right(val);
2434 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2435 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2439 op1 = get_Shrs_left(val);
2440 op2 = get_Shrs_right(val);
2441 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2442 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2446 op1 = get_Rotl_left(val);
2447 op2 = get_Rotl_right(val);
2448 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2449 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2452 /* TODO: match ROR patterns... */
2454 new_node = try_create_SetMem(val, ptr, mem);
2458 op1 = get_Minus_op(val);
2459 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2462 /* should be lowered already */
2463 assert(mode != mode_b);
2464 op1 = get_Not_op(val);
2465 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2471 if (new_node != NULL) {
2472 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2473 get_irn_pinned(node) == op_pin_state_pinned) {
2474 set_irn_pinned(new_node, op_pin_state_pinned);
2481 static bool possible_int_mode_for_fp(ir_mode *mode)
2485 if (!mode_is_signed(mode))
2487 size = get_mode_size_bits(mode);
2488 if (size != 16 && size != 32)
2493 static int is_float_to_int_conv(const ir_node *node)
2495 ir_mode *mode = get_irn_mode(node);
2499 if (!possible_int_mode_for_fp(mode))
2504 conv_op = get_Conv_op(node);
2505 conv_mode = get_irn_mode(conv_op);
2507 if (!mode_is_float(conv_mode))
2514 * Transform a Store(floatConst) into a sequence of
2517 * @return the created ia32 Store node
2519 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2521 ir_mode *mode = get_irn_mode(cns);
2522 unsigned size = get_mode_size_bytes(mode);
2523 ir_tarval *tv = get_Const_tarval(cns);
2524 ir_node *block = get_nodes_block(node);
2525 ir_node *new_block = be_transform_node(block);
2526 ir_node *ptr = get_Store_ptr(node);
2527 ir_node *mem = get_Store_mem(node);
2528 dbg_info *dbgi = get_irn_dbg_info(node);
2532 ia32_address_t addr;
2534 assert(size % 4 == 0);
2537 build_address_ptr(&addr, ptr, mem);
2541 get_tarval_sub_bits(tv, ofs) |
2542 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2543 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2544 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2545 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2547 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2548 addr.index, addr.mem, imm);
2550 set_irn_pinned(new_node, get_irn_pinned(node));
2551 set_ia32_op_type(new_node, ia32_AddrModeD);
2552 set_ia32_ls_mode(new_node, mode_Iu);
2553 set_address(new_node, &addr);
2554 SET_IA32_ORIG_NODE(new_node, node);
2557 ins[i++] = new_node;
2562 } while (size != 0);
2565 return new_rd_Sync(dbgi, new_block, i, ins);
2572 * Generate a vfist or vfisttp instruction.
2574 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2575 ir_node *mem, ir_node *val, ir_node **fist)
2579 if (ia32_cg_config.use_fisttp) {
2580 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2581 if other users exists */
2582 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2583 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2584 be_new_Keep(block, 1, &value);
2586 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2589 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2592 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2598 * Transforms a general (no special case) Store.
2600 * @return the created ia32 Store node
2602 static ir_node *gen_general_Store(ir_node *node)
2604 ir_node *val = get_Store_value(node);
2605 ir_mode *mode = get_irn_mode(val);
2606 ir_node *block = get_nodes_block(node);
2607 ir_node *new_block = be_transform_node(block);
2608 ir_node *ptr = get_Store_ptr(node);
2609 ir_node *mem = get_Store_mem(node);
2610 dbg_info *dbgi = get_irn_dbg_info(node);
2611 ir_node *new_val, *new_node, *store;
2612 ia32_address_t addr;
2614 /* check for destination address mode */
2615 new_node = try_create_dest_am(node);
2616 if (new_node != NULL)
2619 /* construct store address */
2620 memset(&addr, 0, sizeof(addr));
2621 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2623 if (addr.base == NULL) {
2624 addr.base = noreg_GP;
2626 addr.base = be_transform_node(addr.base);
2629 if (addr.index == NULL) {
2630 addr.index = noreg_GP;
2632 addr.index = be_transform_node(addr.index);
2634 addr.mem = be_transform_node(mem);
2636 if (mode_is_float(mode)) {
2637 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2639 while (is_Conv(val) && mode == get_irn_mode(val)) {
2640 ir_node *op = get_Conv_op(val);
2641 if (!mode_is_float(get_irn_mode(op)))
2645 new_val = be_transform_node(val);
2646 if (ia32_cg_config.use_sse2) {
2647 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2648 addr.index, addr.mem, new_val);
2650 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2651 addr.index, addr.mem, new_val, mode);
2654 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2655 val = get_Conv_op(val);
2657 /* TODO: is this optimisation still necessary at all (middleend)? */
2658 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2659 while (is_Conv(val)) {
2660 ir_node *op = get_Conv_op(val);
2661 if (!mode_is_float(get_irn_mode(op)))
2663 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2667 new_val = be_transform_node(val);
2668 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2670 new_val = create_immediate_or_transform(val, 0);
2671 assert(mode != mode_b);
2673 if (get_mode_size_bits(mode) == 8) {
2674 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2675 addr.index, addr.mem, new_val);
2677 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2678 addr.index, addr.mem, new_val);
2683 set_irn_pinned(store, get_irn_pinned(node));
2684 set_ia32_op_type(store, ia32_AddrModeD);
2685 set_ia32_ls_mode(store, mode);
2687 set_address(store, &addr);
2688 SET_IA32_ORIG_NODE(store, node);
2694 * Transforms a Store.
2696 * @return the created ia32 Store node
2698 static ir_node *gen_Store(ir_node *node)
2700 ir_node *val = get_Store_value(node);
2701 ir_mode *mode = get_irn_mode(val);
2703 if (mode_is_float(mode) && is_Const(val)) {
2704 /* We can transform every floating const store
2705 into a sequence of integer stores.
2706 If the constant is already in a register,
2707 it would be better to use it, but we don't
2708 have this information here. */
2709 return gen_float_const_Store(node, val);
2711 return gen_general_Store(node);
2715 * Transforms a Switch.
2717 * @return the created ia32 SwitchJmp node
2719 static ir_node *create_Switch(ir_node *node)
2721 dbg_info *dbgi = get_irn_dbg_info(node);
2722 ir_node *block = be_transform_node(get_nodes_block(node));
2723 ir_node *sel = get_Cond_selector(node);
2724 ir_node *new_sel = be_transform_node(sel);
2725 long switch_min = LONG_MAX;
2726 long switch_max = LONG_MIN;
2727 long default_pn = get_Cond_default_proj(node);
2729 const ir_edge_t *edge;
2731 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2733 /* determine the smallest switch case value */
2734 foreach_out_edge(node, edge) {
2735 ir_node *proj = get_edge_src_irn(edge);
2736 long pn = get_Proj_proj(proj);
2737 if (pn == default_pn)
2740 if (pn < switch_min)
2742 if (pn > switch_max)
2746 if ((unsigned long) (switch_max - switch_min) > 128000) {
2747 panic("Size of switch %+F bigger than 128000", node);
2750 if (switch_min != 0) {
2751 /* if smallest switch case is not 0 we need an additional sub */
2752 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2753 add_ia32_am_offs_int(new_sel, -switch_min);
2754 set_ia32_op_type(new_sel, ia32_AddrModeS);
2756 SET_IA32_ORIG_NODE(new_sel, node);
2759 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2760 SET_IA32_ORIG_NODE(new_node, node);
2766 * Transform a Cond node.
2768 static ir_node *gen_Cond(ir_node *node)
2770 ir_node *block = get_nodes_block(node);
2771 ir_node *new_block = be_transform_node(block);
2772 dbg_info *dbgi = get_irn_dbg_info(node);
2773 ir_node *sel = get_Cond_selector(node);
2774 ir_mode *sel_mode = get_irn_mode(sel);
2775 ir_node *flags = NULL;
2777 ia32_condition_code_t cc;
2779 if (sel_mode != mode_b) {
2780 return create_Switch(node);
2783 /* we get flags from a Cmp */
2784 flags = get_flags_node(sel, &cc);
2786 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2787 SET_IA32_ORIG_NODE(new_node, node);
2793 * Transform a be_Copy.
2795 static ir_node *gen_be_Copy(ir_node *node)
2797 ir_node *new_node = be_duplicate_node(node);
2798 ir_mode *mode = get_irn_mode(new_node);
2800 if (ia32_mode_needs_gp_reg(mode)) {
2801 set_irn_mode(new_node, mode_Iu);
2807 static ir_node *create_Fucom(ir_node *node)
2809 dbg_info *dbgi = get_irn_dbg_info(node);
2810 ir_node *block = get_nodes_block(node);
2811 ir_node *new_block = be_transform_node(block);
2812 ir_node *left = get_Cmp_left(node);
2813 ir_node *new_left = be_transform_node(left);
2814 ir_node *right = get_Cmp_right(node);
2818 if (ia32_cg_config.use_fucomi) {
2819 new_right = be_transform_node(right);
2820 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2822 set_ia32_commutative(new_node);
2823 SET_IA32_ORIG_NODE(new_node, node);
2825 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2826 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2828 new_right = be_transform_node(right);
2829 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2832 set_ia32_commutative(new_node);
2834 SET_IA32_ORIG_NODE(new_node, node);
2836 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2837 SET_IA32_ORIG_NODE(new_node, node);
2843 static ir_node *create_Ucomi(ir_node *node)
2845 dbg_info *dbgi = get_irn_dbg_info(node);
2846 ir_node *src_block = get_nodes_block(node);
2847 ir_node *new_block = be_transform_node(src_block);
2848 ir_node *left = get_Cmp_left(node);
2849 ir_node *right = get_Cmp_right(node);
2851 ia32_address_mode_t am;
2852 ia32_address_t *addr = &am.addr;
2854 match_arguments(&am, src_block, left, right, NULL,
2855 match_commutative | match_am);
2857 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2858 addr->mem, am.new_op1, am.new_op2,
2860 set_am_attributes(new_node, &am);
2862 SET_IA32_ORIG_NODE(new_node, node);
2864 new_node = fix_mem_proj(new_node, &am);
2870 * returns true if it is assured, that the upper bits of a node are "clean"
2871 * which means for a 16 or 8 bit value, that the upper bits in the register
2872 * are 0 for unsigned and a copy of the last significant bit for signed
2875 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2877 assert(ia32_mode_needs_gp_reg(mode));
2878 if (get_mode_size_bits(mode) >= 32)
2881 if (is_Proj(transformed_node))
2882 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2884 switch (get_ia32_irn_opcode(transformed_node)) {
2885 case iro_ia32_Conv_I2I:
2886 case iro_ia32_Conv_I2I8Bit: {
2887 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2888 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2890 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2897 if (mode_is_signed(mode)) {
2898 return false; /* TODO handle signed modes */
2900 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2901 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2902 const ia32_immediate_attr_t *attr
2903 = get_ia32_immediate_attr_const(right);
2904 if (attr->symconst == 0 &&
2905 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2909 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2913 /* TODO too conservative if shift amount is constant */
2914 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2917 if (!mode_is_signed(mode)) {
2919 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2920 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2922 /* TODO if one is known to be zero extended, then || is sufficient */
2927 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2928 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2930 case iro_ia32_Const:
2931 case iro_ia32_Immediate: {
2932 const ia32_immediate_attr_t *attr =
2933 get_ia32_immediate_attr_const(transformed_node);
2934 if (mode_is_signed(mode)) {
2935 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2936 return shifted == 0 || shifted == -1;
2938 unsigned long shifted = (unsigned long)attr->offset;
2939 shifted >>= get_mode_size_bits(mode);
2940 return shifted == 0;
2950 * Generate code for a Cmp.
2952 static ir_node *gen_Cmp(ir_node *node)
2954 dbg_info *dbgi = get_irn_dbg_info(node);
2955 ir_node *block = get_nodes_block(node);
2956 ir_node *new_block = be_transform_node(block);
2957 ir_node *left = get_Cmp_left(node);
2958 ir_node *right = get_Cmp_right(node);
2959 ir_mode *cmp_mode = get_irn_mode(left);
2961 ia32_address_mode_t am;
2962 ia32_address_t *addr = &am.addr;
2964 if (mode_is_float(cmp_mode)) {
2965 if (ia32_cg_config.use_sse2) {
2966 return create_Ucomi(node);
2968 return create_Fucom(node);
2972 assert(ia32_mode_needs_gp_reg(cmp_mode));
2974 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2975 if (is_Const_0(right) &&
2977 get_irn_n_edges(left) == 1) {
2978 /* Test(and_left, and_right) */
2979 ir_node *and_left = get_And_left(left);
2980 ir_node *and_right = get_And_right(left);
2982 /* matze: code here used mode instead of cmd_mode, I think it is always
2983 * the same as cmp_mode, but I leave this here to see if this is really
2986 assert(get_irn_mode(and_left) == cmp_mode);
2988 match_arguments(&am, block, and_left, and_right, NULL,
2990 match_am | match_8bit_am | match_16bit_am |
2991 match_am_and_immediates | match_immediate);
2993 /* use 32bit compare mode if possible since the opcode is smaller */
2994 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2995 upper_bits_clean(am.new_op2, cmp_mode)) {
2996 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2999 if (get_mode_size_bits(cmp_mode) == 8) {
3000 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3001 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3003 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3004 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3007 /* Cmp(left, right) */
3008 match_arguments(&am, block, left, right, NULL,
3009 match_commutative | match_am | match_8bit_am |
3010 match_16bit_am | match_am_and_immediates |
3012 /* use 32bit compare mode if possible since the opcode is smaller */
3013 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3014 upper_bits_clean(am.new_op2, cmp_mode)) {
3015 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3018 if (get_mode_size_bits(cmp_mode) == 8) {
3019 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3020 addr->index, addr->mem, am.new_op1,
3021 am.new_op2, am.ins_permuted);
3023 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3024 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3027 set_am_attributes(new_node, &am);
3028 set_ia32_ls_mode(new_node, cmp_mode);
3030 SET_IA32_ORIG_NODE(new_node, node);
3032 new_node = fix_mem_proj(new_node, &am);
3037 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3038 ia32_condition_code_t cc)
3040 dbg_info *dbgi = get_irn_dbg_info(node);
3041 ir_node *block = get_nodes_block(node);
3042 ir_node *new_block = be_transform_node(block);
3043 ir_node *val_true = get_Mux_true(node);
3044 ir_node *val_false = get_Mux_false(node);
3046 ia32_address_mode_t am;
3047 ia32_address_t *addr;
3049 assert(ia32_cg_config.use_cmov);
3050 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3054 match_arguments(&am, block, val_false, val_true, flags,
3055 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3057 if (am.ins_permuted)
3058 cc = ia32_negate_condition_code(cc);
3060 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3061 addr->mem, am.new_op1, am.new_op2, new_flags,
3063 set_am_attributes(new_node, &am);
3065 SET_IA32_ORIG_NODE(new_node, node);
3067 new_node = fix_mem_proj(new_node, &am);
3073 * Creates a ia32 Setcc instruction.
3075 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3076 ir_node *flags, ia32_condition_code_t cc,
3079 ir_mode *mode = get_irn_mode(orig_node);
3082 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3083 SET_IA32_ORIG_NODE(new_node, orig_node);
3085 /* we might need to conv the result up */
3086 if (get_mode_size_bits(mode) > 8) {
3087 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3088 nomem, new_node, mode_Bu);
3089 SET_IA32_ORIG_NODE(new_node, orig_node);
3096 * Create instruction for an unsigned Difference or Zero.
3098 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3100 ir_mode *mode = get_irn_mode(psi);
3110 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3111 match_mode_neutral | match_am | match_immediate | match_two_users);
3113 block = get_nodes_block(new_node);
3115 if (is_Proj(new_node)) {
3116 sub = get_Proj_pred(new_node);
3119 set_irn_mode(sub, mode_T);
3120 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3122 assert(is_ia32_Sub(sub));
3123 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3125 dbgi = get_irn_dbg_info(psi);
3126 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3127 notn = new_bd_ia32_Not(dbgi, block, sbb);
3129 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3130 set_ia32_commutative(new_node);
3135 * Create an const array of two float consts.
3137 * @param c0 the first constant
3138 * @param c1 the second constant
3139 * @param new_mode IN/OUT for the mode of the constants, if NULL
3140 * smallest possible mode will be used
3142 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3145 ir_mode *mode = *new_mode;
3147 ir_initializer_t *initializer;
3148 ir_tarval *tv0 = get_Const_tarval(c0);
3149 ir_tarval *tv1 = get_Const_tarval(c1);
3152 /* detect the best mode for the constants */
3153 mode = get_tarval_mode(tv0);
3155 if (mode != mode_F) {
3156 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3157 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3159 tv0 = tarval_convert_to(tv0, mode);
3160 tv1 = tarval_convert_to(tv1, mode);
3161 } else if (mode != mode_D) {
3162 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3163 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3165 tv0 = tarval_convert_to(tv0, mode);
3166 tv1 = tarval_convert_to(tv1, mode);
3173 tp = ia32_create_float_type(mode, 4);
3174 tp = ia32_create_float_array(tp);
3176 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3178 set_entity_ld_ident(ent, get_entity_ident(ent));
3179 set_entity_visibility(ent, ir_visibility_private);
3180 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3182 initializer = create_initializer_compound(2);
3184 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3185 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3187 set_entity_initializer(ent, initializer);
3194 * Possible transformations for creating a Setcc.
3196 enum setcc_transform_insn {
3209 typedef struct setcc_transform {
3211 ia32_condition_code_t cc;
3213 enum setcc_transform_insn transform;
3217 } setcc_transform_t;
3220 * Setcc can only handle 0 and 1 result.
3221 * Find a transformation that creates 0 and 1 from
3224 static void find_const_transform(ia32_condition_code_t cc,
3225 ir_tarval *t, ir_tarval *f,
3226 setcc_transform_t *res)
3232 if (tarval_is_null(t)) {
3236 cc = ia32_negate_condition_code(cc);
3237 } else if (tarval_cmp(t, f) == ir_relation_less) {
3238 // now, t is the bigger one
3242 cc = ia32_negate_condition_code(cc);
3246 if (! tarval_is_null(f)) {
3247 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3250 res->steps[step].transform = SETCC_TR_ADD;
3252 if (t == tarval_bad)
3253 panic("constant subtract failed");
3254 if (! tarval_is_long(f))
3255 panic("tarval is not long");
3257 res->steps[step].val = get_tarval_long(f);
3259 f = tarval_sub(f, f, NULL);
3260 assert(tarval_is_null(f));
3263 if (tarval_is_one(t)) {
3264 res->steps[step].transform = SETCC_TR_SET;
3265 res->num_steps = ++step;
3269 if (tarval_is_minus_one(t)) {
3270 res->steps[step].transform = SETCC_TR_NEG;
3272 res->steps[step].transform = SETCC_TR_SET;
3273 res->num_steps = ++step;
3276 if (tarval_is_long(t)) {
3277 long v = get_tarval_long(t);
3279 res->steps[step].val = 0;
3282 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3284 res->steps[step].transform = SETCC_TR_LEAxx;
3285 res->steps[step].scale = 3; /* (a << 3) + a */
3288 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3290 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3291 res->steps[step].scale = 3; /* (a << 3) */
3294 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3296 res->steps[step].transform = SETCC_TR_LEAxx;
3297 res->steps[step].scale = 2; /* (a << 2) + a */
3300 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3302 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3303 res->steps[step].scale = 2; /* (a << 2) */
3306 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3308 res->steps[step].transform = SETCC_TR_LEAxx;
3309 res->steps[step].scale = 1; /* (a << 1) + a */
3312 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3314 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3315 res->steps[step].scale = 1; /* (a << 1) */
3318 res->num_steps = step;
3321 if (! tarval_is_single_bit(t)) {
3322 res->steps[step].transform = SETCC_TR_AND;
3323 res->steps[step].val = v;
3325 res->steps[step].transform = SETCC_TR_NEG;
3327 int v = get_tarval_lowest_bit(t);
3330 res->steps[step].transform = SETCC_TR_SHL;
3331 res->steps[step].scale = v;
3335 res->steps[step].transform = SETCC_TR_SET;
3336 res->num_steps = ++step;
3339 panic("tarval is not long");
3343 * Transforms a Mux node into some code sequence.
3345 * @return The transformed node.
3347 static ir_node *gen_Mux(ir_node *node)
3349 dbg_info *dbgi = get_irn_dbg_info(node);
3350 ir_node *block = get_nodes_block(node);
3351 ir_node *new_block = be_transform_node(block);
3352 ir_node *mux_true = get_Mux_true(node);
3353 ir_node *mux_false = get_Mux_false(node);
3354 ir_node *sel = get_Mux_sel(node);
3355 ir_mode *mode = get_irn_mode(node);
3359 ia32_condition_code_t cc;
3361 assert(get_irn_mode(sel) == mode_b);
3363 is_abs = be_mux_is_abs(sel, mux_true, mux_false);
3365 return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
3368 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3369 if (mode_is_float(mode)) {
3370 ir_node *cmp_left = get_Cmp_left(sel);
3371 ir_node *cmp_right = get_Cmp_right(sel);
3372 ir_relation relation = get_Cmp_relation(sel);
3374 if (ia32_cg_config.use_sse2) {
3375 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3376 if (cmp_left == mux_true && cmp_right == mux_false) {
3377 /* Mux(a <= b, a, b) => MIN */
3378 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3379 match_commutative | match_am | match_two_users);
3380 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3381 /* Mux(a <= b, b, a) => MAX */
3382 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3383 match_commutative | match_am | match_two_users);
3385 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3386 if (cmp_left == mux_true && cmp_right == mux_false) {
3387 /* Mux(a >= b, a, b) => MAX */
3388 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3389 match_commutative | match_am | match_two_users);
3390 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3391 /* Mux(a >= b, b, a) => MIN */
3392 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3393 match_commutative | match_am | match_two_users);
3398 if (is_Const(mux_true) && is_Const(mux_false)) {
3399 ia32_address_mode_t am;
3404 flags = get_flags_node(sel, &cc);
3405 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3407 if (ia32_cg_config.use_sse2) {
3408 /* cannot load from different mode on SSE */
3411 /* x87 can load any mode */
3415 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3417 switch (get_mode_size_bytes(new_mode)) {
3427 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3428 set_ia32_am_scale(new_node, 2);
3433 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3434 set_ia32_am_scale(new_node, 1);
3437 /* arg, shift 16 NOT supported */
3439 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3442 panic("Unsupported constant size");
3445 am.ls_mode = new_mode;
3446 am.addr.base = get_symconst_base();
3447 am.addr.index = new_node;
3448 am.addr.mem = nomem;
3450 am.addr.scale = scale;
3451 am.addr.use_frame = 0;
3452 am.addr.tls_segment = false;
3453 am.addr.frame_entity = NULL;
3454 am.addr.symconst_sign = 0;
3455 am.mem_proj = am.addr.mem;
3456 am.op_type = ia32_AddrModeS;
3459 am.pinned = op_pin_state_floats;
3461 am.ins_permuted = false;
3463 if (ia32_cg_config.use_sse2)
3464 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3466 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3467 set_am_attributes(load, &am);
3469 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3471 panic("cannot transform floating point Mux");
3474 assert(ia32_mode_needs_gp_reg(mode));
3477 ir_node *cmp_left = get_Cmp_left(sel);
3478 ir_node *cmp_right = get_Cmp_right(sel);
3479 ir_relation relation = get_Cmp_relation(sel);
3480 ir_node *val_true = mux_true;
3481 ir_node *val_false = mux_false;
3483 if (is_Const(val_true) && is_Const_null(val_true)) {
3484 ir_node *tmp = val_false;
3485 val_false = val_true;
3487 relation = get_negated_relation(relation);
3489 if (is_Const_0(val_false) && is_Sub(val_true)) {
3490 if ((relation & ir_relation_greater)
3491 && get_Sub_left(val_true) == cmp_left
3492 && get_Sub_right(val_true) == cmp_right) {
3493 return create_doz(node, cmp_left, cmp_right);
3495 if ((relation & ir_relation_less)
3496 && get_Sub_left(val_true) == cmp_right
3497 && get_Sub_right(val_true) == cmp_left) {
3498 return create_doz(node, cmp_right, cmp_left);
3503 flags = get_flags_node(sel, &cc);
3505 if (is_Const(mux_true) && is_Const(mux_false)) {
3506 /* both are const, good */
3507 ir_tarval *tv_true = get_Const_tarval(mux_true);
3508 ir_tarval *tv_false = get_Const_tarval(mux_false);
3509 setcc_transform_t res;
3512 find_const_transform(cc, tv_true, tv_false, &res);
3514 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3517 switch (res.steps[step].transform) {
3519 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3520 add_ia32_am_offs_int(new_node, res.steps[step].val);
3522 case SETCC_TR_ADDxx:
3523 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3526 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3527 set_ia32_am_scale(new_node, res.steps[step].scale);
3528 set_ia32_am_offs_int(new_node, res.steps[step].val);
3530 case SETCC_TR_LEAxx:
3531 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3532 set_ia32_am_scale(new_node, res.steps[step].scale);
3533 set_ia32_am_offs_int(new_node, res.steps[step].val);
3536 imm = ia32_immediate_from_long(res.steps[step].scale);
3537 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3540 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3543 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3546 imm = ia32_immediate_from_long(res.steps[step].val);
3547 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3550 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3553 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3556 panic("unknown setcc transform");
3560 new_node = create_CMov(node, sel, flags, cc);
3568 * Create a conversion from x87 state register to general purpose.
3570 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3572 ir_node *block = be_transform_node(get_nodes_block(node));
3573 ir_node *op = get_Conv_op(node);
3574 ir_node *new_op = be_transform_node(op);
3575 ir_graph *irg = current_ir_graph;
3576 dbg_info *dbgi = get_irn_dbg_info(node);
3577 ir_mode *mode = get_irn_mode(node);
3578 ir_node *fist, *load, *mem;
3580 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3581 set_irn_pinned(fist, op_pin_state_floats);
3582 set_ia32_use_frame(fist);
3583 set_ia32_op_type(fist, ia32_AddrModeD);
3585 assert(get_mode_size_bits(mode) <= 32);
3586 /* exception we can only store signed 32 bit integers, so for unsigned
3587 we store a 64bit (signed) integer and load the lower bits */
3588 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3589 set_ia32_ls_mode(fist, mode_Ls);
3591 set_ia32_ls_mode(fist, mode_Is);
3593 SET_IA32_ORIG_NODE(fist, node);
3596 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3598 set_irn_pinned(load, op_pin_state_floats);
3599 set_ia32_use_frame(load);
3600 set_ia32_op_type(load, ia32_AddrModeS);
3601 set_ia32_ls_mode(load, mode_Is);
3602 if (get_ia32_ls_mode(fist) == mode_Ls) {
3603 ia32_attr_t *attr = get_ia32_attr(load);
3604 attr->data.need_64bit_stackent = 1;
3606 ia32_attr_t *attr = get_ia32_attr(load);
3607 attr->data.need_32bit_stackent = 1;
3609 SET_IA32_ORIG_NODE(load, node);
3611 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3615 * Creates a x87 strict Conv by placing a Store and a Load
3617 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3619 ir_node *block = get_nodes_block(node);
3620 ir_graph *irg = get_Block_irg(block);
3621 dbg_info *dbgi = get_irn_dbg_info(node);
3622 ir_node *frame = get_irg_frame(irg);
3623 ir_node *store, *load;
3626 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3627 set_ia32_use_frame(store);
3628 set_ia32_op_type(store, ia32_AddrModeD);
3629 SET_IA32_ORIG_NODE(store, node);
3631 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3632 set_ia32_use_frame(load);
3633 set_ia32_op_type(load, ia32_AddrModeS);
3634 SET_IA32_ORIG_NODE(load, node);
3636 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3640 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3641 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3643 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3645 func = get_mode_size_bits(mode) == 8 ?
3646 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3647 return func(dbgi, block, base, index, mem, val, mode);
3651 * Create a conversion from general purpose to x87 register
3653 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3655 ir_node *src_block = get_nodes_block(node);
3656 ir_node *block = be_transform_node(src_block);
3657 ir_graph *irg = get_Block_irg(block);
3658 dbg_info *dbgi = get_irn_dbg_info(node);
3659 ir_node *op = get_Conv_op(node);
3660 ir_node *new_op = NULL;
3662 ir_mode *store_mode;
3667 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3668 if (possible_int_mode_for_fp(src_mode)) {
3669 ia32_address_mode_t am;
3671 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3672 if (am.op_type == ia32_AddrModeS) {
3673 ia32_address_t *addr = &am.addr;
3675 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3676 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3678 set_am_attributes(fild, &am);
3679 SET_IA32_ORIG_NODE(fild, node);
3681 fix_mem_proj(fild, &am);
3686 if (new_op == NULL) {
3687 new_op = be_transform_node(op);
3690 mode = get_irn_mode(op);
3692 /* first convert to 32 bit signed if necessary */
3693 if (get_mode_size_bits(src_mode) < 32) {
3694 if (!upper_bits_clean(new_op, src_mode)) {
3695 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3696 SET_IA32_ORIG_NODE(new_op, node);
3701 assert(get_mode_size_bits(mode) == 32);
3704 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3706 set_ia32_use_frame(store);
3707 set_ia32_op_type(store, ia32_AddrModeD);
3708 set_ia32_ls_mode(store, mode_Iu);
3710 /* exception for 32bit unsigned, do a 64bit spill+load */
3711 if (!mode_is_signed(mode)) {
3714 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3716 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3717 noreg_GP, nomem, zero_const);
3719 set_ia32_use_frame(zero_store);
3720 set_ia32_op_type(zero_store, ia32_AddrModeD);
3721 add_ia32_am_offs_int(zero_store, 4);
3722 set_ia32_ls_mode(zero_store, mode_Iu);
3727 store = new_rd_Sync(dbgi, block, 2, in);
3728 store_mode = mode_Ls;
3730 store_mode = mode_Is;
3734 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3736 set_ia32_use_frame(fild);
3737 set_ia32_op_type(fild, ia32_AddrModeS);
3738 set_ia32_ls_mode(fild, store_mode);
3740 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3746 * Create a conversion from one integer mode into another one
3748 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3749 dbg_info *dbgi, ir_node *block, ir_node *op,
3752 ir_node *new_block = be_transform_node(block);
3754 ir_mode *smaller_mode;
3755 ia32_address_mode_t am;
3756 ia32_address_t *addr = &am.addr;
3759 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3760 smaller_mode = src_mode;
3762 smaller_mode = tgt_mode;
3765 #ifdef DEBUG_libfirm
3767 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3772 match_arguments(&am, block, NULL, op, NULL,
3773 match_am | match_8bit_am | match_16bit_am);
3775 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3776 /* unnecessary conv. in theory it shouldn't have been AM */
3777 assert(is_ia32_NoReg_GP(addr->base));
3778 assert(is_ia32_NoReg_GP(addr->index));
3779 assert(is_NoMem(addr->mem));
3780 assert(am.addr.offset == 0);
3781 assert(am.addr.symconst_ent == NULL);
3785 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3786 addr->mem, am.new_op2, smaller_mode);
3787 set_am_attributes(new_node, &am);
3788 /* match_arguments assume that out-mode = in-mode, this isn't true here
3790 set_ia32_ls_mode(new_node, smaller_mode);
3791 SET_IA32_ORIG_NODE(new_node, node);
3792 new_node = fix_mem_proj(new_node, &am);
3797 * Transforms a Conv node.
3799 * @return The created ia32 Conv node
3801 static ir_node *gen_Conv(ir_node *node)
3803 ir_node *block = get_nodes_block(node);
3804 ir_node *new_block = be_transform_node(block);
3805 ir_node *op = get_Conv_op(node);
3806 ir_node *new_op = NULL;
3807 dbg_info *dbgi = get_irn_dbg_info(node);
3808 ir_mode *src_mode = get_irn_mode(op);
3809 ir_mode *tgt_mode = get_irn_mode(node);
3810 int src_bits = get_mode_size_bits(src_mode);
3811 int tgt_bits = get_mode_size_bits(tgt_mode);
3812 ir_node *res = NULL;
3814 assert(!mode_is_int(src_mode) || src_bits <= 32);
3815 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3817 /* modeB -> X should already be lowered by the lower_mode_b pass */
3818 if (src_mode == mode_b) {
3819 panic("ConvB not lowered %+F", node);
3822 if (src_mode == tgt_mode) {
3823 if (get_Conv_strict(node)) {
3824 if (ia32_cg_config.use_sse2) {
3825 /* when we are in SSE mode, we can kill all strict no-op conversion */
3826 return be_transform_node(op);
3829 /* this should be optimized already, but who knows... */
3830 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3831 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3832 return be_transform_node(op);
3836 if (mode_is_float(src_mode)) {
3837 new_op = be_transform_node(op);
3838 /* we convert from float ... */
3839 if (mode_is_float(tgt_mode)) {
3841 if (ia32_cg_config.use_sse2) {
3842 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3843 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3845 set_ia32_ls_mode(res, tgt_mode);
3847 if (get_Conv_strict(node)) {
3848 /* if fp_no_float_fold is not set then we assume that we
3849 * don't have any float operations in a non
3850 * mode_float_arithmetic mode and can skip strict upconvs */
3851 if (src_bits < tgt_bits) {
3852 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3855 res = gen_x87_strict_conv(tgt_mode, new_op);
3856 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3860 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3865 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3866 if (ia32_cg_config.use_sse2) {
3867 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3869 set_ia32_ls_mode(res, src_mode);
3871 return gen_x87_fp_to_gp(node);
3875 /* we convert from int ... */
3876 if (mode_is_float(tgt_mode)) {
3878 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3879 if (ia32_cg_config.use_sse2) {
3880 new_op = be_transform_node(op);
3881 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3883 set_ia32_ls_mode(res, tgt_mode);
3885 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3886 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3887 res = gen_x87_gp_to_fp(node, src_mode);
3889 /* we need a strict-Conv, if the int mode has more bits than the
3891 if (float_mantissa < int_mantissa) {
3892 res = gen_x87_strict_conv(tgt_mode, res);
3893 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3897 } else if (tgt_mode == mode_b) {
3898 /* mode_b lowering already took care that we only have 0/1 values */
3899 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3900 src_mode, tgt_mode));
3901 return be_transform_node(op);
3904 if (src_bits == tgt_bits) {
3905 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3906 src_mode, tgt_mode));
3907 return be_transform_node(op);
3910 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3918 static ir_node *create_immediate_or_transform(ir_node *node,
3919 char immediate_constraint_type)
3921 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3922 if (new_node == NULL) {
3923 new_node = be_transform_node(node);
3929 * Transforms a FrameAddr into an ia32 Add.
3931 static ir_node *gen_be_FrameAddr(ir_node *node)
3933 ir_node *block = be_transform_node(get_nodes_block(node));
3934 ir_node *op = be_get_FrameAddr_frame(node);
3935 ir_node *new_op = be_transform_node(op);
3936 dbg_info *dbgi = get_irn_dbg_info(node);
3939 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3940 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3941 set_ia32_use_frame(new_node);
3943 SET_IA32_ORIG_NODE(new_node, node);
3949 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3951 static ir_node *gen_be_Return(ir_node *node)
3953 ir_graph *irg = current_ir_graph;
3954 ir_node *ret_val = get_irn_n(node, n_be_Return_val);
3955 ir_node *ret_mem = get_irn_n(node, n_be_Return_mem);
3956 ir_node *new_ret_val = be_transform_node(ret_val);
3957 ir_node *new_ret_mem = be_transform_node(ret_mem);
3958 ir_entity *ent = get_irg_entity(irg);
3959 ir_type *tp = get_entity_type(ent);
3960 dbg_info *dbgi = get_irn_dbg_info(node);
3961 ir_node *block = be_transform_node(get_nodes_block(node));
3964 ir_node *frame, *sse_store, *fld, *mproj;
3971 assert(ret_val != NULL);
3972 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3973 return be_duplicate_node(node);
3976 res_type = get_method_res_type(tp, 0);
3978 if (! is_Primitive_type(res_type)) {
3979 return be_duplicate_node(node);
3982 mode = get_type_mode(res_type);
3983 if (! mode_is_float(mode)) {
3984 return be_duplicate_node(node);
3987 assert(get_method_n_ress(tp) == 1);
3989 frame = get_irg_frame(irg);
3991 /* store xmm0 onto stack */
3992 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3993 new_ret_mem, new_ret_val);
3994 set_ia32_ls_mode(sse_store, mode);
3995 set_ia32_op_type(sse_store, ia32_AddrModeD);
3996 set_ia32_use_frame(sse_store);
3998 /* load into x87 register */
3999 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4000 set_ia32_op_type(fld, ia32_AddrModeS);
4001 set_ia32_use_frame(fld);
4003 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4004 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4006 /* create a new return */
4007 arity = get_irn_arity(node);
4008 in = ALLOCAN(ir_node*, arity);
4009 pop = be_Return_get_pop(node);
4010 for (i = 0; i < arity; ++i) {
4011 ir_node *op = get_irn_n(node, i);
4012 if (op == ret_val) {
4014 } else if (op == ret_mem) {
4017 in[i] = be_transform_node(op);
4020 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4021 copy_node_attr(irg, node, new_node);
4027 * Transform a be_AddSP into an ia32_SubSP.
4029 static ir_node *gen_be_AddSP(ir_node *node)
4031 ir_node *sz = get_irn_n(node, n_be_AddSP_size);
4032 ir_node *sp = get_irn_n(node, n_be_AddSP_old_sp);
4034 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4035 match_am | match_immediate);
4036 assert(is_ia32_SubSP(new_node));
4037 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4038 &ia32_registers[REG_ESP]);
4043 * Transform a be_SubSP into an ia32_AddSP
4045 static ir_node *gen_be_SubSP(ir_node *node)
4047 ir_node *sz = get_irn_n(node, n_be_SubSP_size);
4048 ir_node *sp = get_irn_n(node, n_be_SubSP_old_sp);
4050 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4051 match_am | match_immediate);
4052 assert(is_ia32_AddSP(new_node));
4053 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4054 &ia32_registers[REG_ESP]);
4059 * Change some phi modes
4061 static ir_node *gen_Phi(ir_node *node)
4063 const arch_register_req_t *req;
4064 ir_node *block = be_transform_node(get_nodes_block(node));
4065 ir_graph *irg = current_ir_graph;
4066 dbg_info *dbgi = get_irn_dbg_info(node);
4067 ir_mode *mode = get_irn_mode(node);
4070 if (ia32_mode_needs_gp_reg(mode)) {
4071 /* we shouldn't have any 64bit stuff around anymore */
4072 assert(get_mode_size_bits(mode) <= 32);
4073 /* all integer operations are on 32bit registers now */
4075 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4076 } else if (mode_is_float(mode)) {
4077 if (ia32_cg_config.use_sse2) {
4079 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4082 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4085 req = arch_no_register_req;
4088 /* phi nodes allow loops, so we use the old arguments for now
4089 * and fix this later */
4090 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4091 get_irn_in(node) + 1);
4092 copy_node_attr(irg, node, phi);
4093 be_duplicate_deps(node, phi);
4095 arch_set_out_register_req(phi, 0, req);
4097 be_enqueue_preds(node);
4102 static ir_node *gen_Jmp(ir_node *node)
4104 ir_node *block = get_nodes_block(node);
4105 ir_node *new_block = be_transform_node(block);
4106 dbg_info *dbgi = get_irn_dbg_info(node);
4109 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4110 SET_IA32_ORIG_NODE(new_node, node);
4118 static ir_node *gen_IJmp(ir_node *node)
4120 ir_node *block = get_nodes_block(node);
4121 ir_node *new_block = be_transform_node(block);
4122 dbg_info *dbgi = get_irn_dbg_info(node);
4123 ir_node *op = get_IJmp_target(node);
4125 ia32_address_mode_t am;
4126 ia32_address_t *addr = &am.addr;
4128 assert(get_irn_mode(op) == mode_P);
4130 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4132 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4133 addr->mem, am.new_op2);
4134 set_am_attributes(new_node, &am);
4135 SET_IA32_ORIG_NODE(new_node, node);
4137 new_node = fix_mem_proj(new_node, &am);
4142 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4144 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4145 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4147 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4148 match_immediate | match_mode_neutral);
4151 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4153 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4154 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4155 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4159 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4161 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4162 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4163 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4167 static ir_node *gen_ia32_l_Add(ir_node *node)
4169 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4170 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4171 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4172 match_commutative | match_am | match_immediate |
4173 match_mode_neutral);
4175 if (is_Proj(lowered)) {
4176 lowered = get_Proj_pred(lowered);
4178 assert(is_ia32_Add(lowered));
4179 set_irn_mode(lowered, mode_T);
4185 static ir_node *gen_ia32_l_Adc(ir_node *node)
4187 return gen_binop_flags(node, new_bd_ia32_Adc,
4188 match_commutative | match_am | match_immediate |
4189 match_mode_neutral);
4193 * Transforms a l_MulS into a "real" MulS node.
4195 * @return the created ia32 Mul node
4197 static ir_node *gen_ia32_l_Mul(ir_node *node)
4199 ir_node *left = get_binop_left(node);
4200 ir_node *right = get_binop_right(node);
4202 return gen_binop(node, left, right, new_bd_ia32_Mul,
4203 match_commutative | match_am | match_mode_neutral);
4207 * Transforms a l_IMulS into a "real" IMul1OPS node.
4209 * @return the created ia32 IMul1OP node
4211 static ir_node *gen_ia32_l_IMul(ir_node *node)
4213 ir_node *left = get_binop_left(node);
4214 ir_node *right = get_binop_right(node);
4216 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4217 match_commutative | match_am | match_mode_neutral);
4220 static ir_node *gen_ia32_l_Sub(ir_node *node)
4222 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4223 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4224 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4225 match_am | match_immediate | match_mode_neutral);
4227 if (is_Proj(lowered)) {
4228 lowered = get_Proj_pred(lowered);
4230 assert(is_ia32_Sub(lowered));
4231 set_irn_mode(lowered, mode_T);
4237 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4239 return gen_binop_flags(node, new_bd_ia32_Sbb,
4240 match_am | match_immediate | match_mode_neutral);
4244 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4245 * op1 - target to be shifted
4246 * op2 - contains bits to be shifted into target
4248 * Only op3 can be an immediate.
4250 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4251 ir_node *low, ir_node *count)
4253 ir_node *block = get_nodes_block(node);
4254 ir_node *new_block = be_transform_node(block);
4255 dbg_info *dbgi = get_irn_dbg_info(node);
4256 ir_node *new_high = be_transform_node(high);
4257 ir_node *new_low = be_transform_node(low);
4261 /* the shift amount can be any mode that is bigger than 5 bits, since all
4262 * other bits are ignored anyway */
4263 while (is_Conv(count) &&
4264 get_irn_n_edges(count) == 1 &&
4265 mode_is_int(get_irn_mode(count))) {
4266 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4267 count = get_Conv_op(count);
4269 new_count = create_immediate_or_transform(count, 0);
4271 if (is_ia32_l_ShlD(node)) {
4272 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4275 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4278 SET_IA32_ORIG_NODE(new_node, node);
4283 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4285 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4286 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4287 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4288 return gen_lowered_64bit_shifts(node, high, low, count);
4291 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4293 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4294 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4295 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4296 return gen_lowered_64bit_shifts(node, high, low, count);
4299 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4301 ir_node *src_block = get_nodes_block(node);
4302 ir_node *block = be_transform_node(src_block);
4303 ir_graph *irg = current_ir_graph;
4304 dbg_info *dbgi = get_irn_dbg_info(node);
4305 ir_node *frame = get_irg_frame(irg);
4306 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4307 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4308 ir_node *new_val_low = be_transform_node(val_low);
4309 ir_node *new_val_high = be_transform_node(val_high);
4311 ir_node *sync, *fild, *res;
4312 ir_node *store_low, *store_high;
4314 if (ia32_cg_config.use_sse2) {
4315 panic("ia32_l_LLtoFloat not implemented for SSE2");
4319 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4321 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4323 SET_IA32_ORIG_NODE(store_low, node);
4324 SET_IA32_ORIG_NODE(store_high, node);
4326 set_ia32_use_frame(store_low);
4327 set_ia32_use_frame(store_high);
4328 set_ia32_op_type(store_low, ia32_AddrModeD);
4329 set_ia32_op_type(store_high, ia32_AddrModeD);
4330 set_ia32_ls_mode(store_low, mode_Iu);
4331 set_ia32_ls_mode(store_high, mode_Is);
4332 add_ia32_am_offs_int(store_high, 4);
4336 sync = new_rd_Sync(dbgi, block, 2, in);
4339 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4341 set_ia32_use_frame(fild);
4342 set_ia32_op_type(fild, ia32_AddrModeS);
4343 set_ia32_ls_mode(fild, mode_Ls);
4345 SET_IA32_ORIG_NODE(fild, node);
4347 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4349 if (! mode_is_signed(get_irn_mode(val_high))) {
4350 ia32_address_mode_t am;
4352 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4355 am.addr.base = get_symconst_base();
4356 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4357 am.addr.mem = nomem;
4360 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4361 am.addr.tls_segment = false;
4362 am.addr.use_frame = 0;
4363 am.addr.frame_entity = NULL;
4364 am.addr.symconst_sign = 0;
4365 am.ls_mode = mode_F;
4366 am.mem_proj = nomem;
4367 am.op_type = ia32_AddrModeS;
4369 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4370 am.pinned = op_pin_state_floats;
4372 am.ins_permuted = false;
4374 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4375 am.new_op1, am.new_op2, get_fpcw());
4376 set_am_attributes(fadd, &am);
4378 set_irn_mode(fadd, mode_T);
4379 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4384 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4386 ir_node *src_block = get_nodes_block(node);
4387 ir_node *block = be_transform_node(src_block);
4388 ir_graph *irg = get_Block_irg(block);
4389 dbg_info *dbgi = get_irn_dbg_info(node);
4390 ir_node *frame = get_irg_frame(irg);
4391 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4392 ir_node *new_val = be_transform_node(val);
4393 ir_node *fist, *mem;
4395 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4396 SET_IA32_ORIG_NODE(fist, node);
4397 set_ia32_use_frame(fist);
4398 set_ia32_op_type(fist, ia32_AddrModeD);
4399 set_ia32_ls_mode(fist, mode_Ls);
4404 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4406 ir_node *block = be_transform_node(get_nodes_block(node));
4407 ir_graph *irg = get_Block_irg(block);
4408 ir_node *pred = get_Proj_pred(node);
4409 ir_node *new_pred = be_transform_node(pred);
4410 ir_node *frame = get_irg_frame(irg);
4411 dbg_info *dbgi = get_irn_dbg_info(node);
4412 long pn = get_Proj_proj(node);
4417 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4418 SET_IA32_ORIG_NODE(load, node);
4419 set_ia32_use_frame(load);
4420 set_ia32_op_type(load, ia32_AddrModeS);
4421 set_ia32_ls_mode(load, mode_Iu);
4422 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4423 * 32 bit from it with this particular load */
4424 attr = get_ia32_attr(load);
4425 attr->data.need_64bit_stackent = 1;
4427 if (pn == pn_ia32_l_FloattoLL_res_high) {
4428 add_ia32_am_offs_int(load, 4);
4430 assert(pn == pn_ia32_l_FloattoLL_res_low);
4433 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4439 * Transform the Projs of an AddSP.
4441 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4443 ir_node *pred = get_Proj_pred(node);
4444 ir_node *new_pred = be_transform_node(pred);
4445 dbg_info *dbgi = get_irn_dbg_info(node);
4446 long proj = get_Proj_proj(node);
4448 if (proj == pn_be_AddSP_sp) {
4449 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4450 pn_ia32_SubSP_stack);
4451 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4453 } else if (proj == pn_be_AddSP_res) {
4454 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4455 pn_ia32_SubSP_addr);
4456 } else if (proj == pn_be_AddSP_M) {
4457 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4460 panic("No idea how to transform proj->AddSP");
4464 * Transform the Projs of a SubSP.
4466 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4468 ir_node *pred = get_Proj_pred(node);
4469 ir_node *new_pred = be_transform_node(pred);
4470 dbg_info *dbgi = get_irn_dbg_info(node);
4471 long proj = get_Proj_proj(node);
4473 if (proj == pn_be_SubSP_sp) {
4474 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4475 pn_ia32_AddSP_stack);
4476 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4478 } else if (proj == pn_be_SubSP_M) {
4479 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4482 panic("No idea how to transform proj->SubSP");
4486 * Transform and renumber the Projs from a Load.
4488 static ir_node *gen_Proj_Load(ir_node *node)
4491 ir_node *block = be_transform_node(get_nodes_block(node));
4492 ir_node *pred = get_Proj_pred(node);
4493 dbg_info *dbgi = get_irn_dbg_info(node);
4494 long proj = get_Proj_proj(node);
4496 /* loads might be part of source address mode matches, so we don't
4497 * transform the ProjMs yet (with the exception of loads whose result is
4500 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4503 /* this is needed, because sometimes we have loops that are only
4504 reachable through the ProjM */
4505 be_enqueue_preds(node);
4506 /* do it in 2 steps, to silence firm verifier */
4507 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4508 set_Proj_proj(res, pn_ia32_mem);
4512 /* renumber the proj */
4513 new_pred = be_transform_node(pred);
4514 if (is_ia32_Load(new_pred)) {
4517 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4519 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4520 case pn_Load_X_regular:
4521 return new_rd_Jmp(dbgi, block);
4522 case pn_Load_X_except:
4523 /* This Load might raise an exception. Mark it. */
4524 set_ia32_exc_label(new_pred, 1);
4525 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4529 } else if (is_ia32_Conv_I2I(new_pred) ||
4530 is_ia32_Conv_I2I8Bit(new_pred)) {
4531 set_irn_mode(new_pred, mode_T);
4532 if (proj == pn_Load_res) {
4533 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4534 } else if (proj == pn_Load_M) {
4535 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4537 } else if (is_ia32_xLoad(new_pred)) {
4540 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4542 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4543 case pn_Load_X_regular:
4544 return new_rd_Jmp(dbgi, block);
4545 case pn_Load_X_except:
4546 /* This Load might raise an exception. Mark it. */
4547 set_ia32_exc_label(new_pred, 1);
4548 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4552 } else if (is_ia32_vfld(new_pred)) {
4555 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4557 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4558 case pn_Load_X_regular:
4559 return new_rd_Jmp(dbgi, block);
4560 case pn_Load_X_except:
4561 /* This Load might raise an exception. Mark it. */
4562 set_ia32_exc_label(new_pred, 1);
4563 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4568 /* can happen for ProJMs when source address mode happened for the
4571 /* however it should not be the result proj, as that would mean the
4572 load had multiple users and should not have been used for
4574 if (proj != pn_Load_M) {
4575 panic("internal error: transformed node not a Load");
4577 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4580 panic("No idea how to transform proj");
4584 * Transform and renumber the Projs from a Div or Mod instruction.
4586 static ir_node *gen_Proj_Div(ir_node *node)
4588 ir_node *block = be_transform_node(get_nodes_block(node));
4589 ir_node *pred = get_Proj_pred(node);
4590 ir_node *new_pred = be_transform_node(pred);
4591 dbg_info *dbgi = get_irn_dbg_info(node);
4592 long proj = get_Proj_proj(node);
4594 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4595 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4599 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4600 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4601 } else if (is_ia32_xDiv(new_pred)) {
4602 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4603 } else if (is_ia32_vfdiv(new_pred)) {
4604 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4606 panic("Div transformed to unexpected thing %+F", new_pred);
4609 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4610 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4611 } else if (is_ia32_xDiv(new_pred)) {
4612 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4613 } else if (is_ia32_vfdiv(new_pred)) {
4614 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4616 panic("Div transformed to unexpected thing %+F", new_pred);
4618 case pn_Div_X_regular:
4619 return new_rd_Jmp(dbgi, block);
4620 case pn_Div_X_except:
4621 set_ia32_exc_label(new_pred, 1);
4622 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4627 panic("No idea how to transform proj->Div");
4631 * Transform and renumber the Projs from a Div or Mod instruction.
4633 static ir_node *gen_Proj_Mod(ir_node *node)
4635 ir_node *pred = get_Proj_pred(node);
4636 ir_node *new_pred = be_transform_node(pred);
4637 dbg_info *dbgi = get_irn_dbg_info(node);
4638 long proj = get_Proj_proj(node);
4640 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4641 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4642 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4646 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4648 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4649 case pn_Mod_X_except:
4650 set_ia32_exc_label(new_pred, 1);
4651 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4655 panic("No idea how to transform proj->Mod");
4659 * Transform and renumber the Projs from a CopyB.
4661 static ir_node *gen_Proj_CopyB(ir_node *node)
4663 ir_node *pred = get_Proj_pred(node);
4664 ir_node *new_pred = be_transform_node(pred);
4665 dbg_info *dbgi = get_irn_dbg_info(node);
4666 long proj = get_Proj_proj(node);
4670 if (is_ia32_CopyB_i(new_pred)) {
4671 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4672 } else if (is_ia32_CopyB(new_pred)) {
4673 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4680 panic("No idea how to transform proj->CopyB");
4683 static ir_node *gen_be_Call(ir_node *node)
4685 dbg_info *const dbgi = get_irn_dbg_info(node);
4686 ir_node *const src_block = get_nodes_block(node);
4687 ir_node *const block = be_transform_node(src_block);
4688 ir_node *const src_mem = get_irn_n(node, n_be_Call_mem);
4689 ir_node *const src_sp = get_irn_n(node, n_be_Call_sp);
4690 ir_node *const sp = be_transform_node(src_sp);
4691 ir_node *const src_ptr = get_irn_n(node, n_be_Call_ptr);
4692 ia32_address_mode_t am;
4693 ia32_address_t *const addr = &am.addr;
4698 ir_node * eax = noreg_GP;
4699 ir_node * ecx = noreg_GP;
4700 ir_node * edx = noreg_GP;
4701 unsigned const pop = be_Call_get_pop(node);
4702 ir_type *const call_tp = be_Call_get_type(node);
4703 int old_no_pic_adjust;
4705 /* Run the x87 simulator if the call returns a float value */
4706 if (get_method_n_ress(call_tp) > 0) {
4707 ir_type *const res_type = get_method_res_type(call_tp, 0);
4708 ir_mode *const res_mode = get_type_mode(res_type);
4710 if (res_mode != NULL && mode_is_float(res_mode)) {
4711 ir_graph *irg = current_ir_graph;
4712 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4713 irg_data->do_x87_sim = 1;
4717 /* We do not want be_Call direct calls */
4718 assert(be_Call_get_entity(node) == NULL);
4720 /* special case for PIC trampoline calls */
4721 old_no_pic_adjust = ia32_no_pic_adjust;
4722 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4724 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4725 match_am | match_immediate);
4727 ia32_no_pic_adjust = old_no_pic_adjust;
4729 i = get_irn_arity(node) - 1;
4730 fpcw = be_transform_node(get_irn_n(node, i--));
4731 for (; i >= n_be_Call_first_arg; --i) {
4732 arch_register_req_t const *const req = arch_get_register_req(node, i);
4733 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4735 assert(req->type == arch_register_req_type_limited);
4736 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4738 switch (*req->limited) {
4739 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4740 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4741 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4742 default: panic("Invalid GP register for register parameter");
4746 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4747 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4748 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4749 set_am_attributes(call, &am);
4750 call = fix_mem_proj(call, &am);
4752 if (get_irn_pinned(node) == op_pin_state_pinned)
4753 set_irn_pinned(call, op_pin_state_pinned);
4755 SET_IA32_ORIG_NODE(call, node);
4757 if (ia32_cg_config.use_sse2) {
4758 /* remember this call for post-processing */
4759 ARR_APP1(ir_node *, call_list, call);
4760 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4767 * Transform Builtin trap
4769 static ir_node *gen_trap(ir_node *node)
4771 dbg_info *dbgi = get_irn_dbg_info(node);
4772 ir_node *block = be_transform_node(get_nodes_block(node));
4773 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4775 return new_bd_ia32_UD2(dbgi, block, mem);
4779 * Transform Builtin debugbreak
4781 static ir_node *gen_debugbreak(ir_node *node)
4783 dbg_info *dbgi = get_irn_dbg_info(node);
4784 ir_node *block = be_transform_node(get_nodes_block(node));
4785 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4787 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4791 * Transform Builtin return_address
4793 static ir_node *gen_return_address(ir_node *node)
4795 ir_node *param = get_Builtin_param(node, 0);
4796 ir_node *frame = get_Builtin_param(node, 1);
4797 dbg_info *dbgi = get_irn_dbg_info(node);
4798 ir_tarval *tv = get_Const_tarval(param);
4799 ir_graph *irg = get_irn_irg(node);
4800 unsigned long value = get_tarval_long(tv);
4802 ir_node *block = be_transform_node(get_nodes_block(node));
4803 ir_node *ptr = be_transform_node(frame);
4807 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4808 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4809 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4812 /* load the return address from this frame */
4813 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4815 set_irn_pinned(load, get_irn_pinned(node));
4816 set_ia32_op_type(load, ia32_AddrModeS);
4817 set_ia32_ls_mode(load, mode_Iu);
4819 set_ia32_am_offs_int(load, 0);
4820 set_ia32_use_frame(load);
4821 set_ia32_frame_ent(load, ia32_get_return_address_entity(irg));
4823 if (get_irn_pinned(node) == op_pin_state_floats) {
4824 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4825 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4826 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4827 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4830 SET_IA32_ORIG_NODE(load, node);
4831 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4835 * Transform Builtin frame_address
4837 static ir_node *gen_frame_address(ir_node *node)
4839 ir_node *param = get_Builtin_param(node, 0);
4840 ir_node *frame = get_Builtin_param(node, 1);
4841 dbg_info *dbgi = get_irn_dbg_info(node);
4842 ir_tarval *tv = get_Const_tarval(param);
4843 ir_graph *irg = get_irn_irg(node);
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(irg);
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);
5723 * Post-process all calls if we are in SSE mode.
5724 * The ABI requires that the results are in st0, copy them
5725 * to a xmm register.
5727 static void postprocess_fp_call_results(void)
5731 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5732 ir_node *call = call_list[i];
5733 ir_type *mtp = call_types[i];
5736 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5737 ir_type *res_tp = get_method_res_type(mtp, j);
5738 ir_node *res, *new_res;
5739 const ir_edge_t *edge, *next;
5742 if (! is_atomic_type(res_tp)) {
5743 /* no floating point return */
5746 mode = get_type_mode(res_tp);
5747 if (! mode_is_float(mode)) {
5748 /* no floating point return */
5752 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5755 /* now patch the users */
5756 foreach_out_edge_safe(res, edge, next) {
5757 ir_node *succ = get_edge_src_irn(edge);
5760 if (be_is_Keep(succ))
5763 if (is_ia32_xStore(succ)) {
5764 /* an xStore can be patched into an vfst */
5765 dbg_info *db = get_irn_dbg_info(succ);
5766 ir_node *block = get_nodes_block(succ);
5767 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5768 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5769 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5770 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5771 ir_mode *mode = get_ia32_ls_mode(succ);
5773 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5774 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5775 if (is_ia32_use_frame(succ))
5776 set_ia32_use_frame(st);
5777 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5778 set_irn_pinned(st, get_irn_pinned(succ));
5779 set_ia32_op_type(st, ia32_AddrModeD);
5783 if (new_res == NULL) {
5784 dbg_info *db = get_irn_dbg_info(call);
5785 ir_node *block = get_nodes_block(call);
5786 ir_node *frame = get_irg_frame(current_ir_graph);
5787 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5788 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5789 ir_node *vfst, *xld, *new_mem;
5791 /* store st(0) on stack */
5792 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5793 set_ia32_op_type(vfst, ia32_AddrModeD);
5794 set_ia32_use_frame(vfst);
5796 /* load into SSE register */
5797 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5798 set_ia32_op_type(xld, ia32_AddrModeS);
5799 set_ia32_use_frame(xld);
5801 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5802 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5804 if (old_mem != NULL) {
5805 edges_reroute(old_mem, new_mem);
5809 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5816 /* do the transformation */
5817 void ia32_transform_graph(ir_graph *irg)
5821 register_transformers();
5822 initial_fpcw = NULL;
5823 ia32_no_pic_adjust = 0;
5826 = ia32_get_initial_reg_value(irg, &ia32_registers[REG_FPCW]);
5828 be_timer_push(T_HEIGHTS);
5829 ia32_heights = heights_new(irg);
5830 be_timer_pop(T_HEIGHTS);
5831 ia32_calculate_non_address_mode_nodes(irg);
5833 /* the transform phase is not safe for CSE (yet) because several nodes get
5834 * attributes set after their creation */
5835 cse_last = get_opt_cse();
5838 call_list = NEW_ARR_F(ir_node *, 0);
5839 call_types = NEW_ARR_F(ir_type *, 0);
5840 be_transform_graph(irg, ia32_pretransform_node);
5842 if (ia32_cg_config.use_sse2)
5843 postprocess_fp_call_results();
5844 DEL_ARR_F(call_types);
5845 DEL_ARR_F(call_list);
5847 set_opt_cse(cse_last);
5849 ia32_free_non_address_mode_nodes();
5850 heights_free(ia32_heights);
5851 ia32_heights = NULL;
5854 void ia32_init_transform(void)
5856 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");