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"
51 #include "../benode.h"
52 #include "../besched.h"
54 #include "../beutil.h"
56 #include "../betranshlp.h"
59 #include "bearch_ia32_t.h"
60 #include "ia32_common_transform.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_dbg_stat.h"
65 #include "ia32_optimize.h"
66 #include "ia32_address_mode.h"
67 #include "ia32_architecture.h"
69 #include "gen_ia32_regalloc_if.h"
71 /* define this to construct SSE constants instead of load them */
72 #undef CONSTRUCT_SSE_CONST
75 #define SFP_SIGN "0x80000000"
76 #define DFP_SIGN "0x8000000000000000"
77 #define SFP_ABS "0x7FFFFFFF"
78 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
80 #define ULL_BIAS "18446744073709551616"
82 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
83 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
84 #define ENT_SFP_ABS "C_ia32_sfp_abs"
85 #define ENT_DFP_ABS "C_ia32_dfp_abs"
86 #define ENT_ULL_BIAS "C_ia32_ull_bias"
88 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
89 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
91 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
93 static ir_node *old_initial_fpcw = NULL;
94 static ir_node *initial_fpcw = NULL;
95 int ia32_no_pic_adjust;
97 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
98 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
101 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
102 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
105 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
106 ir_node *op1, ir_node *op2);
108 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
109 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
111 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
112 ir_node *base, ir_node *index, ir_node *mem);
114 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
115 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
118 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
120 static ir_node *create_immediate_or_transform(ir_node *node,
121 char immediate_constraint_type);
123 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
124 dbg_info *dbgi, ir_node *block,
125 ir_node *op, ir_node *orig_node);
127 /* its enough to have those once */
128 static ir_node *nomem, *noreg_GP;
130 /** a list to postprocess all calls */
131 static ir_node **call_list;
132 static ir_type **call_types;
134 /** Return non-zero is a node represents the 0 constant. */
135 static bool is_Const_0(ir_node *node)
137 return is_Const(node) && is_Const_null(node);
140 /** Return non-zero is a node represents the 1 constant. */
141 static bool is_Const_1(ir_node *node)
143 return is_Const(node) && is_Const_one(node);
146 /** Return non-zero is a node represents the -1 constant. */
147 static bool is_Const_Minus_1(ir_node *node)
149 return is_Const(node) && is_Const_all_one(node);
153 * returns true if constant can be created with a simple float command
155 static bool is_simple_x87_Const(ir_node *node)
157 ir_tarval *tv = get_Const_tarval(node);
158 if (tarval_is_null(tv) || tarval_is_one(tv))
161 /* TODO: match all the other float constants */
166 * returns true if constant can be created with a simple float command
168 static bool is_simple_sse_Const(ir_node *node)
170 ir_tarval *tv = get_Const_tarval(node);
171 ir_mode *mode = get_tarval_mode(tv);
176 if (tarval_is_null(tv)
177 #ifdef CONSTRUCT_SSE_CONST
182 #ifdef CONSTRUCT_SSE_CONST
183 if (mode == mode_D) {
184 unsigned val = get_tarval_sub_bits(tv, 0) |
185 (get_tarval_sub_bits(tv, 1) << 8) |
186 (get_tarval_sub_bits(tv, 2) << 16) |
187 (get_tarval_sub_bits(tv, 3) << 24);
189 /* lower 32bit are zero, really a 32bit constant */
192 #endif /* CONSTRUCT_SSE_CONST */
193 /* TODO: match all the other float constants */
198 * return NoREG or pic_base in case of PIC.
199 * This is necessary as base address for newly created symbols
201 static ir_node *get_symconst_base(void)
203 ir_graph *irg = current_ir_graph;
205 if (be_get_irg_options(irg)->pic) {
206 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
207 return arch_env->impl->get_pic_base(irg);
214 * Transforms a Const.
216 static ir_node *gen_Const(ir_node *node)
218 ir_node *old_block = get_nodes_block(node);
219 ir_node *block = be_transform_node(old_block);
220 dbg_info *dbgi = get_irn_dbg_info(node);
221 ir_mode *mode = get_irn_mode(node);
223 assert(is_Const(node));
225 if (mode_is_float(mode)) {
231 if (ia32_cg_config.use_sse2) {
232 ir_tarval *tv = get_Const_tarval(node);
233 if (tarval_is_null(tv)) {
234 load = new_bd_ia32_xZero(dbgi, block);
235 set_ia32_ls_mode(load, mode);
237 #ifdef CONSTRUCT_SSE_CONST
238 } else if (tarval_is_one(tv)) {
239 int cnst = mode == mode_F ? 26 : 55;
240 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
241 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
242 ir_node *pslld, *psrld;
244 load = new_bd_ia32_xAllOnes(dbgi, block);
245 set_ia32_ls_mode(load, mode);
246 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
247 set_ia32_ls_mode(pslld, mode);
248 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
249 set_ia32_ls_mode(psrld, mode);
251 #endif /* CONSTRUCT_SSE_CONST */
252 } else if (mode == mode_F) {
253 /* we can place any 32bit constant by using a movd gp, sse */
254 unsigned val = get_tarval_sub_bits(tv, 0) |
255 (get_tarval_sub_bits(tv, 1) << 8) |
256 (get_tarval_sub_bits(tv, 2) << 16) |
257 (get_tarval_sub_bits(tv, 3) << 24);
258 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
259 load = new_bd_ia32_xMovd(dbgi, block, cnst);
260 set_ia32_ls_mode(load, mode);
263 #ifdef CONSTRUCT_SSE_CONST
264 if (mode == mode_D) {
265 unsigned val = get_tarval_sub_bits(tv, 0) |
266 (get_tarval_sub_bits(tv, 1) << 8) |
267 (get_tarval_sub_bits(tv, 2) << 16) |
268 (get_tarval_sub_bits(tv, 3) << 24);
270 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
271 ir_node *cnst, *psllq;
273 /* fine, lower 32bit are zero, produce 32bit value */
274 val = get_tarval_sub_bits(tv, 4) |
275 (get_tarval_sub_bits(tv, 5) << 8) |
276 (get_tarval_sub_bits(tv, 6) << 16) |
277 (get_tarval_sub_bits(tv, 7) << 24);
278 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
279 load = new_bd_ia32_xMovd(dbgi, block, cnst);
280 set_ia32_ls_mode(load, mode);
281 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
282 set_ia32_ls_mode(psllq, mode);
287 #endif /* CONSTRUCT_SSE_CONST */
288 floatent = ia32_create_float_const_entity(node);
290 base = get_symconst_base();
291 load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
293 set_ia32_op_type(load, ia32_AddrModeS);
294 set_ia32_am_sc(load, floatent);
295 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
296 res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
299 if (is_Const_null(node)) {
300 load = new_bd_ia32_vfldz(dbgi, block);
302 set_ia32_ls_mode(load, mode);
303 } else if (is_Const_one(node)) {
304 load = new_bd_ia32_vfld1(dbgi, block);
306 set_ia32_ls_mode(load, mode);
311 floatent = ia32_create_float_const_entity(node);
312 /* create_float_const_ent is smart and sometimes creates
314 ls_mode = get_type_mode(get_entity_type(floatent));
315 base = get_symconst_base();
316 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
318 set_ia32_op_type(load, ia32_AddrModeS);
319 set_ia32_am_sc(load, floatent);
320 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
321 res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
324 #ifdef CONSTRUCT_SSE_CONST
326 #endif /* CONSTRUCT_SSE_CONST */
327 SET_IA32_ORIG_NODE(load, node);
329 } else { /* non-float mode */
331 ir_tarval *tv = get_Const_tarval(node);
334 tv = tarval_convert_to(tv, mode_Iu);
336 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
338 panic("couldn't convert constant tarval (%+F)", node);
340 val = get_tarval_long(tv);
342 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
343 SET_IA32_ORIG_NODE(cnst, node);
350 * Transforms a SymConst.
352 static ir_node *gen_SymConst(ir_node *node)
354 ir_node *old_block = get_nodes_block(node);
355 ir_node *block = be_transform_node(old_block);
356 dbg_info *dbgi = get_irn_dbg_info(node);
357 ir_mode *mode = get_irn_mode(node);
360 if (mode_is_float(mode)) {
361 if (ia32_cg_config.use_sse2)
362 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
364 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
365 set_ia32_am_sc(cnst, get_SymConst_entity(node));
366 set_ia32_use_frame(cnst);
370 if (get_SymConst_kind(node) != symconst_addr_ent) {
371 panic("backend only support symconst_addr_ent (at %+F)", node);
373 entity = get_SymConst_entity(node);
374 if (get_entity_owner(entity) == get_tls_type()) {
375 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
376 ir_node *lea = new_bd_ia32_Lea(dbgi, block, tls_base, noreg_GP);
377 set_ia32_am_sc(lea, entity);
380 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
384 SET_IA32_ORIG_NODE(cnst, node);
390 * Create a float type for the given mode and cache it.
392 * @param mode the mode for the float type (might be integer mode for SSE2 types)
393 * @param align alignment
395 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
401 if (mode == mode_Iu) {
402 static ir_type *int_Iu[16] = {NULL, };
404 if (int_Iu[align] == NULL) {
405 int_Iu[align] = tp = new_type_primitive(mode);
406 /* set the specified alignment */
407 set_type_alignment_bytes(tp, align);
409 return int_Iu[align];
410 } else if (mode == mode_Lu) {
411 static ir_type *int_Lu[16] = {NULL, };
413 if (int_Lu[align] == NULL) {
414 int_Lu[align] = tp = new_type_primitive(mode);
415 /* set the specified alignment */
416 set_type_alignment_bytes(tp, align);
418 return int_Lu[align];
419 } else if (mode == mode_F) {
420 static ir_type *float_F[16] = {NULL, };
422 if (float_F[align] == NULL) {
423 float_F[align] = tp = new_type_primitive(mode);
424 /* set the specified alignment */
425 set_type_alignment_bytes(tp, align);
427 return float_F[align];
428 } else if (mode == mode_D) {
429 static ir_type *float_D[16] = {NULL, };
431 if (float_D[align] == NULL) {
432 float_D[align] = tp = new_type_primitive(mode);
433 /* set the specified alignment */
434 set_type_alignment_bytes(tp, align);
436 return float_D[align];
438 static ir_type *float_E[16] = {NULL, };
440 if (float_E[align] == NULL) {
441 float_E[align] = tp = new_type_primitive(mode);
442 /* set the specified alignment */
443 set_type_alignment_bytes(tp, align);
445 return float_E[align];
450 * Create a float[2] array type for the given atomic type.
452 * @param tp the atomic type
454 static ir_type *ia32_create_float_array(ir_type *tp)
456 ir_mode *mode = get_type_mode(tp);
457 unsigned align = get_type_alignment_bytes(tp);
462 if (mode == mode_F) {
463 static ir_type *float_F[16] = {NULL, };
465 if (float_F[align] != NULL)
466 return float_F[align];
467 arr = float_F[align] = new_type_array(1, tp);
468 } else if (mode == mode_D) {
469 static ir_type *float_D[16] = {NULL, };
471 if (float_D[align] != NULL)
472 return float_D[align];
473 arr = float_D[align] = new_type_array(1, tp);
475 static ir_type *float_E[16] = {NULL, };
477 if (float_E[align] != NULL)
478 return float_E[align];
479 arr = float_E[align] = new_type_array(1, tp);
481 set_type_alignment_bytes(arr, align);
482 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
483 set_type_state(arr, layout_fixed);
487 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
488 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
490 static const struct {
491 const char *ent_name;
492 const char *cnst_str;
495 } names [ia32_known_const_max] = {
496 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
497 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
498 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
499 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
500 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
502 static ir_entity *ent_cache[ia32_known_const_max];
504 const char *ent_name, *cnst_str;
510 ent_name = names[kct].ent_name;
511 if (! ent_cache[kct]) {
512 cnst_str = names[kct].cnst_str;
514 switch (names[kct].mode) {
515 case 0: mode = mode_Iu; break;
516 case 1: mode = mode_Lu; break;
517 default: mode = mode_F; break;
519 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
520 tp = ia32_create_float_type(mode, names[kct].align);
522 if (kct == ia32_ULLBIAS)
523 tp = ia32_create_float_array(tp);
524 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
526 set_entity_ld_ident(ent, get_entity_ident(ent));
527 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
528 set_entity_visibility(ent, ir_visibility_private);
530 if (kct == ia32_ULLBIAS) {
531 ir_initializer_t *initializer = create_initializer_compound(2);
533 set_initializer_compound_value(initializer, 0,
534 create_initializer_tarval(get_mode_null(mode)));
535 set_initializer_compound_value(initializer, 1,
536 create_initializer_tarval(tv));
538 set_entity_initializer(ent, initializer);
540 set_entity_initializer(ent, create_initializer_tarval(tv));
543 /* cache the entry */
544 ent_cache[kct] = ent;
547 return ent_cache[kct];
551 * return true if the node is a Proj(Load) and could be used in source address
552 * mode for another node. Will return only true if the @p other node is not
553 * dependent on the memory of the Load (for binary operations use the other
554 * input here, for unary operations use NULL).
556 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
557 ir_node *other, ir_node *other2, match_flags_t flags)
562 /* float constants are always available */
563 if (is_Const(node)) {
564 ir_mode *mode = get_irn_mode(node);
565 if (mode_is_float(mode)) {
566 if (ia32_cg_config.use_sse2) {
567 if (is_simple_sse_Const(node))
570 if (is_simple_x87_Const(node))
573 if (get_irn_n_edges(node) > 1)
581 load = get_Proj_pred(node);
582 pn = get_Proj_proj(node);
583 if (!is_Load(load) || pn != pn_Load_res)
585 if (get_nodes_block(load) != block)
587 /* we only use address mode if we're the only user of the load */
588 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
590 /* in some edge cases with address mode we might reach the load normally
591 * and through some AM sequence, if it is already materialized then we
592 * can't create an AM node from it */
593 if (be_is_transformed(node))
596 /* don't do AM if other node inputs depend on the load (via mem-proj) */
597 if (other != NULL && ia32_prevents_AM(block, load, other))
600 if (other2 != NULL && ia32_prevents_AM(block, load, other2))
606 typedef struct ia32_address_mode_t ia32_address_mode_t;
607 struct ia32_address_mode_t {
612 ia32_op_type_t op_type;
616 unsigned commutative : 1;
617 unsigned ins_permuted : 1;
620 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
622 /* construct load address */
623 memset(addr, 0, sizeof(addr[0]));
624 ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
626 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
627 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
628 addr->mem = be_transform_node(mem);
631 static void build_address(ia32_address_mode_t *am, ir_node *node,
632 ia32_create_am_flags_t flags)
634 ia32_address_t *addr = &am->addr;
640 /* floating point immediates */
641 if (is_Const(node)) {
642 ir_entity *entity = ia32_create_float_const_entity(node);
643 addr->base = get_symconst_base();
644 addr->index = noreg_GP;
646 addr->symconst_ent = entity;
647 addr->tls_segment = false;
649 am->ls_mode = get_type_mode(get_entity_type(entity));
650 am->pinned = op_pin_state_floats;
654 load = get_Proj_pred(node);
655 ptr = get_Load_ptr(load);
656 mem = get_Load_mem(load);
657 new_mem = be_transform_node(mem);
658 am->pinned = get_irn_pinned(load);
659 am->ls_mode = get_Load_mode(load);
660 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
663 /* construct load address */
664 ia32_create_address_mode(addr, ptr, flags);
666 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
667 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
671 static void set_address(ir_node *node, const ia32_address_t *addr)
673 set_ia32_am_scale(node, addr->scale);
674 set_ia32_am_sc(node, addr->symconst_ent);
675 set_ia32_am_offs_int(node, addr->offset);
676 set_ia32_am_tls_segment(node, addr->tls_segment);
677 if (addr->symconst_sign)
678 set_ia32_am_sc_sign(node);
680 set_ia32_use_frame(node);
681 set_ia32_frame_ent(node, addr->frame_entity);
685 * Apply attributes of a given address mode to a node.
687 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
689 set_address(node, &am->addr);
691 set_ia32_op_type(node, am->op_type);
692 set_ia32_ls_mode(node, am->ls_mode);
693 if (am->pinned == op_pin_state_pinned) {
694 /* beware: some nodes are already pinned and did not allow to change the state */
695 if (get_irn_pinned(node) != op_pin_state_pinned)
696 set_irn_pinned(node, op_pin_state_pinned);
699 set_ia32_commutative(node);
703 * Check, if a given node is a Down-Conv, ie. a integer Conv
704 * from a mode with a mode with more bits to a mode with lesser bits.
705 * Moreover, we return only true if the node has not more than 1 user.
707 * @param node the node
708 * @return non-zero if node is a Down-Conv
710 static int is_downconv(const ir_node *node)
718 /* we only want to skip the conv when we're the only user
719 * (because this test is used in the context of address-mode selection
720 * and we don't want to use address mode for multiple users) */
721 if (get_irn_n_edges(node) > 1)
724 src_mode = get_irn_mode(get_Conv_op(node));
725 dest_mode = get_irn_mode(node);
727 ia32_mode_needs_gp_reg(src_mode) &&
728 ia32_mode_needs_gp_reg(dest_mode) &&
729 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
732 /** Skip all Down-Conv's on a given node and return the resulting node. */
733 ir_node *ia32_skip_downconv(ir_node *node)
735 while (is_downconv(node))
736 node = get_Conv_op(node);
741 static bool is_sameconv(ir_node *node)
749 /* we only want to skip the conv when we're the only user
750 * (because this test is used in the context of address-mode selection
751 * and we don't want to use address mode for multiple users) */
752 if (get_irn_n_edges(node) > 1)
755 src_mode = get_irn_mode(get_Conv_op(node));
756 dest_mode = get_irn_mode(node);
758 ia32_mode_needs_gp_reg(src_mode) &&
759 ia32_mode_needs_gp_reg(dest_mode) &&
760 get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
763 /** Skip all signedness convs */
764 static ir_node *ia32_skip_sameconv(ir_node *node)
766 while (is_sameconv(node))
767 node = get_Conv_op(node);
772 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
774 ir_mode *mode = get_irn_mode(node);
779 if (mode_is_signed(mode)) {
784 block = get_nodes_block(node);
785 dbgi = get_irn_dbg_info(node);
787 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
791 * matches operands of a node into ia32 addressing/operand modes. This covers
792 * usage of source address mode, immediates, operations with non 32-bit modes,
794 * The resulting data is filled into the @p am struct. block is the block
795 * of the node whose arguments are matched. op1, op2 are the first and second
796 * input that are matched (op1 may be NULL). other_op is another unrelated
797 * input that is not matched! but which is needed sometimes to check if AM
798 * for op1/op2 is legal.
799 * @p flags describes the supported modes of the operation in detail.
801 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
802 ir_node *op1, ir_node *op2, ir_node *other_op,
805 ia32_address_t *addr = &am->addr;
806 ir_mode *mode = get_irn_mode(op2);
807 int mode_bits = get_mode_size_bits(mode);
808 ir_node *new_op1, *new_op2;
810 unsigned commutative;
811 int use_am_and_immediates;
814 memset(am, 0, sizeof(am[0]));
816 commutative = (flags & match_commutative) != 0;
817 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
818 use_am = (flags & match_am) != 0;
819 use_immediate = (flags & match_immediate) != 0;
820 assert(!use_am_and_immediates || use_immediate);
823 assert(!commutative || op1 != NULL);
824 assert(use_am || !(flags & match_8bit_am));
825 assert(use_am || !(flags & match_16bit_am));
827 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
828 (mode_bits == 16 && !(flags & match_16bit_am))) {
832 /* we can simply skip downconvs for mode neutral nodes: the upper bits
833 * can be random for these operations */
834 if (flags & match_mode_neutral) {
835 op2 = ia32_skip_downconv(op2);
837 op1 = ia32_skip_downconv(op1);
840 op2 = ia32_skip_sameconv(op2);
842 op1 = ia32_skip_sameconv(op1);
846 /* match immediates. firm nodes are normalized: constants are always on the
849 if (!(flags & match_try_am) && use_immediate) {
850 new_op2 = ia32_try_create_Immediate(op2, 0);
853 if (new_op2 == NULL &&
854 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
855 build_address(am, op2, ia32_create_am_normal);
856 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
857 if (mode_is_float(mode)) {
858 new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
862 am->op_type = ia32_AddrModeS;
863 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
865 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
867 build_address(am, op1, ia32_create_am_normal);
869 if (mode_is_float(mode)) {
870 noreg = ia32_new_NoReg_vfp(current_ir_graph);
875 if (new_op2 != NULL) {
878 new_op1 = be_transform_node(op2);
880 am->ins_permuted = true;
882 am->op_type = ia32_AddrModeS;
885 am->op_type = ia32_Normal;
887 if (flags & match_try_am) {
893 mode = get_irn_mode(op2);
894 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
895 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
897 new_op2 = create_upconv(op2, NULL);
898 am->ls_mode = mode_Iu;
900 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
902 new_op2 = be_transform_node(op2);
903 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
906 if (addr->base == NULL)
907 addr->base = noreg_GP;
908 if (addr->index == NULL)
909 addr->index = noreg_GP;
910 if (addr->mem == NULL)
913 am->new_op1 = new_op1;
914 am->new_op2 = new_op2;
915 am->commutative = commutative;
919 * "Fixes" a node that uses address mode by turning it into mode_T
920 * and returning a pn_ia32_res Proj.
922 * @param node the node
923 * @param am its address mode
925 * @return a Proj(pn_ia32_res) if a memory address mode is used,
928 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
933 if (am->mem_proj == NULL)
936 /* we have to create a mode_T so the old MemProj can attach to us */
937 mode = get_irn_mode(node);
938 load = get_Proj_pred(am->mem_proj);
940 be_set_transformed_node(load, node);
942 if (mode != mode_T) {
943 set_irn_mode(node, mode_T);
944 return new_rd_Proj(NULL, node, mode, pn_ia32_res);
951 * Construct a standard binary operation, set AM and immediate if required.
953 * @param node The original node for which the binop is created
954 * @param op1 The first operand
955 * @param op2 The second operand
956 * @param func The node constructor function
957 * @return The constructed ia32 node.
959 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
960 construct_binop_func *func, match_flags_t flags)
963 ir_node *block, *new_block, *new_node;
964 ia32_address_mode_t am;
965 ia32_address_t *addr = &am.addr;
967 block = get_nodes_block(node);
968 match_arguments(&am, block, op1, op2, NULL, flags);
970 dbgi = get_irn_dbg_info(node);
971 new_block = be_transform_node(block);
972 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
973 am.new_op1, am.new_op2);
974 set_am_attributes(new_node, &am);
975 /* we can't use source address mode anymore when using immediates */
976 if (!(flags & match_am_and_immediates) &&
977 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
978 set_ia32_am_support(new_node, ia32_am_none);
979 SET_IA32_ORIG_NODE(new_node, node);
981 new_node = fix_mem_proj(new_node, &am);
987 * Generic names for the inputs of an ia32 binary op.
990 n_ia32_l_binop_left, /**< ia32 left input */
991 n_ia32_l_binop_right, /**< ia32 right input */
992 n_ia32_l_binop_eflags /**< ia32 eflags input */
994 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Adc_left, n_Adc_left)
995 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Adc_right, n_Adc_right)
996 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Adc_eflags, n_Adc_eflags)
997 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Sbb_minuend, n_Sbb_minuend)
998 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
999 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Sbb_eflags, n_Sbb_eflags)
1002 * Construct a binary operation which also consumes the eflags.
1004 * @param node The node to transform
1005 * @param func The node constructor function
1006 * @param flags The match flags
1007 * @return The constructor ia32 node
1009 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
1010 match_flags_t flags)
1012 ir_node *src_block = get_nodes_block(node);
1013 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
1014 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
1015 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1017 ir_node *block, *new_node, *new_eflags;
1018 ia32_address_mode_t am;
1019 ia32_address_t *addr = &am.addr;
1021 match_arguments(&am, src_block, op1, op2, eflags, flags);
1023 dbgi = get_irn_dbg_info(node);
1024 block = be_transform_node(src_block);
1025 new_eflags = be_transform_node(eflags);
1026 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
1027 am.new_op1, am.new_op2, new_eflags);
1028 set_am_attributes(new_node, &am);
1029 /* we can't use source address mode anymore when using immediates */
1030 if (!(flags & match_am_and_immediates) &&
1031 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
1032 set_ia32_am_support(new_node, ia32_am_none);
1033 SET_IA32_ORIG_NODE(new_node, node);
1035 new_node = fix_mem_proj(new_node, &am);
1040 static ir_node *get_fpcw(void)
1042 if (initial_fpcw != NULL)
1043 return initial_fpcw;
1045 initial_fpcw = be_transform_node(old_initial_fpcw);
1046 return initial_fpcw;
1050 * Construct a standard binary operation, set AM and immediate if required.
1052 * @param op1 The first operand
1053 * @param op2 The second operand
1054 * @param func The node constructor function
1055 * @return The constructed ia32 node.
1057 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1058 construct_binop_float_func *func)
1060 ir_mode *mode = get_irn_mode(node);
1062 ir_node *block, *new_block, *new_node;
1063 ia32_address_mode_t am;
1064 ia32_address_t *addr = &am.addr;
1065 ia32_x87_attr_t *attr;
1066 /* All operations are considered commutative, because there are reverse
1068 match_flags_t flags = match_commutative;
1070 /* happens for div nodes... */
1071 if (mode == mode_T) {
1073 mode = get_Div_resmode(node);
1075 panic("can't determine mode");
1078 /* cannot use address mode with long double on x87 */
1079 if (get_mode_size_bits(mode) <= 64)
1082 block = get_nodes_block(node);
1083 match_arguments(&am, block, op1, op2, NULL, flags);
1085 dbgi = get_irn_dbg_info(node);
1086 new_block = be_transform_node(block);
1087 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1088 am.new_op1, am.new_op2, get_fpcw());
1089 set_am_attributes(new_node, &am);
1091 attr = get_ia32_x87_attr(new_node);
1092 attr->attr.data.ins_permuted = am.ins_permuted;
1094 SET_IA32_ORIG_NODE(new_node, node);
1096 new_node = fix_mem_proj(new_node, &am);
1102 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1104 * @param op1 The first operand
1105 * @param op2 The second operand
1106 * @param func The node constructor function
1107 * @return The constructed ia32 node.
1109 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1110 construct_shift_func *func,
1111 match_flags_t flags)
1114 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1116 assert(! mode_is_float(get_irn_mode(node)));
1117 assert(flags & match_immediate);
1118 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1120 if (flags & match_mode_neutral) {
1121 op1 = ia32_skip_downconv(op1);
1122 new_op1 = be_transform_node(op1);
1123 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1124 new_op1 = create_upconv(op1, node);
1126 new_op1 = be_transform_node(op1);
1129 /* the shift amount can be any mode that is bigger than 5 bits, since all
1130 * other bits are ignored anyway */
1131 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1132 ir_node *const op = get_Conv_op(op2);
1133 if (mode_is_float(get_irn_mode(op)))
1136 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1138 new_op2 = create_immediate_or_transform(op2, 0);
1140 dbgi = get_irn_dbg_info(node);
1141 block = get_nodes_block(node);
1142 new_block = be_transform_node(block);
1143 new_node = func(dbgi, new_block, new_op1, new_op2);
1144 SET_IA32_ORIG_NODE(new_node, node);
1146 /* lowered shift instruction may have a dependency operand, handle it here */
1147 if (get_irn_arity(node) == 3) {
1148 /* we have a dependency */
1149 ir_node* dep = get_irn_n(node, 2);
1150 if (get_irn_n_edges(dep) > 1) {
1151 /* ... which has at least one user other than 'node' */
1152 ir_node *new_dep = be_transform_node(dep);
1153 add_irn_dep(new_node, new_dep);
1162 * Construct a standard unary operation, set AM and immediate if required.
1164 * @param op The operand
1165 * @param func The node constructor function
1166 * @return The constructed ia32 node.
1168 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1169 match_flags_t flags)
1172 ir_node *block, *new_block, *new_op, *new_node;
1174 assert(flags == 0 || flags == match_mode_neutral);
1175 if (flags & match_mode_neutral) {
1176 op = ia32_skip_downconv(op);
1179 new_op = be_transform_node(op);
1180 dbgi = get_irn_dbg_info(node);
1181 block = get_nodes_block(node);
1182 new_block = be_transform_node(block);
1183 new_node = func(dbgi, new_block, new_op);
1185 SET_IA32_ORIG_NODE(new_node, node);
1190 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1191 ia32_address_t *addr)
1193 ir_node *base, *index, *res;
1199 base = be_transform_node(base);
1202 index = addr->index;
1203 if (index == NULL) {
1206 index = be_transform_node(index);
1209 /* segment overrides are ineffective for Leas :-( so we have to patch
1211 if (addr->tls_segment) {
1212 ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
1213 assert(addr->symconst_ent != NULL);
1214 if (base == noreg_GP)
1217 base = new_bd_ia32_Lea(dbgi, block, tls_base, base);
1218 addr->tls_segment = false;
1221 res = new_bd_ia32_Lea(dbgi, block, base, index);
1222 set_address(res, addr);
1228 * Returns non-zero if a given address mode has a symbolic or
1229 * numerical offset != 0.
1231 static int am_has_immediates(const ia32_address_t *addr)
1233 return addr->offset != 0 || addr->symconst_ent != NULL
1234 || addr->frame_entity || addr->use_frame;
1238 * Creates an ia32 Add.
1240 * @return the created ia32 Add node
1242 static ir_node *gen_Add(ir_node *node)
1244 ir_mode *mode = get_irn_mode(node);
1245 ir_node *op1 = get_Add_left(node);
1246 ir_node *op2 = get_Add_right(node);
1248 ir_node *block, *new_block, *new_node, *add_immediate_op;
1249 ia32_address_t addr;
1250 ia32_address_mode_t am;
1252 if (mode_is_float(mode)) {
1253 if (ia32_cg_config.use_sse2)
1254 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1255 match_commutative | match_am);
1257 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1260 ia32_mark_non_am(node);
1262 op2 = ia32_skip_downconv(op2);
1263 op1 = ia32_skip_downconv(op1);
1267 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1268 * 1. Add with immediate -> Lea
1269 * 2. Add with possible source address mode -> Add
1270 * 3. Otherwise -> Lea
1272 memset(&addr, 0, sizeof(addr));
1273 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1274 add_immediate_op = NULL;
1276 dbgi = get_irn_dbg_info(node);
1277 block = get_nodes_block(node);
1278 new_block = be_transform_node(block);
1281 if (addr.base == NULL && addr.index == NULL) {
1282 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1283 addr.symconst_sign, 0, addr.offset);
1284 SET_IA32_ORIG_NODE(new_node, node);
1287 /* add with immediate? */
1288 if (addr.index == NULL) {
1289 add_immediate_op = addr.base;
1290 } else if (addr.base == NULL && addr.scale == 0) {
1291 add_immediate_op = addr.index;
1294 if (add_immediate_op != NULL) {
1295 if (!am_has_immediates(&addr)) {
1296 #ifdef DEBUG_libfirm
1297 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1300 return be_transform_node(add_immediate_op);
1303 new_node = create_lea_from_address(dbgi, new_block, &addr);
1304 SET_IA32_ORIG_NODE(new_node, node);
1308 /* test if we can use source address mode */
1309 match_arguments(&am, block, op1, op2, NULL, match_commutative
1310 | match_mode_neutral | match_am | match_immediate | match_try_am);
1312 /* construct an Add with source address mode */
1313 if (am.op_type == ia32_AddrModeS) {
1314 ia32_address_t *am_addr = &am.addr;
1315 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1316 am_addr->index, am_addr->mem, am.new_op1,
1318 set_am_attributes(new_node, &am);
1319 SET_IA32_ORIG_NODE(new_node, node);
1321 new_node = fix_mem_proj(new_node, &am);
1326 /* otherwise construct a lea */
1327 new_node = create_lea_from_address(dbgi, new_block, &addr);
1328 SET_IA32_ORIG_NODE(new_node, node);
1333 * Creates an ia32 Mul.
1335 * @return the created ia32 Mul node
1337 static ir_node *gen_Mul(ir_node *node)
1339 ir_node *op1 = get_Mul_left(node);
1340 ir_node *op2 = get_Mul_right(node);
1341 ir_mode *mode = get_irn_mode(node);
1343 if (mode_is_float(mode)) {
1344 if (ia32_cg_config.use_sse2)
1345 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1346 match_commutative | match_am);
1348 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1350 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1351 match_commutative | match_am | match_mode_neutral |
1352 match_immediate | match_am_and_immediates);
1356 * Creates an ia32 Mulh.
1357 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1358 * this result while Mul returns the lower 32 bit.
1360 * @return the created ia32 Mulh node
1362 static ir_node *gen_Mulh(ir_node *node)
1364 dbg_info *dbgi = get_irn_dbg_info(node);
1365 ir_node *op1 = get_Mulh_left(node);
1366 ir_node *op2 = get_Mulh_right(node);
1367 ir_mode *mode = get_irn_mode(node);
1369 ir_node *proj_res_high;
1371 if (get_mode_size_bits(mode) != 32) {
1372 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1375 if (mode_is_signed(mode)) {
1376 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1377 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1379 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1380 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1382 return proj_res_high;
1386 * Creates an ia32 And.
1388 * @return The created ia32 And node
1390 static ir_node *gen_And(ir_node *node)
1392 ir_node *op1 = get_And_left(node);
1393 ir_node *op2 = get_And_right(node);
1394 assert(! mode_is_float(get_irn_mode(node)));
1396 /* is it a zero extension? */
1397 if (is_Const(op2)) {
1398 ir_tarval *tv = get_Const_tarval(op2);
1399 long v = get_tarval_long(tv);
1401 if (v == 0xFF || v == 0xFFFF) {
1402 dbg_info *dbgi = get_irn_dbg_info(node);
1403 ir_node *block = get_nodes_block(node);
1410 assert(v == 0xFFFF);
1413 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1418 return gen_binop(node, op1, op2, new_bd_ia32_And,
1419 match_commutative | match_mode_neutral | match_am | match_immediate);
1423 * test wether 2 values result in 'x' and '32-x' when interpreted as a shift
1426 static bool is_complementary_shifts(ir_node *value1, ir_node *value2)
1428 if (is_Const(value1) && is_Const(value2)) {
1429 ir_tarval *tv1 = get_Const_tarval(value1);
1430 ir_tarval *tv2 = get_Const_tarval(value2);
1431 if (tarval_is_long(tv1) && tarval_is_long(tv2)) {
1432 long v1 = get_tarval_long(tv1);
1433 long v2 = get_tarval_long(tv2);
1434 return v1 <= v2 && v2 == 32-v1;
1440 typedef ir_node* (*new_shiftd_func)(dbg_info *dbgi, ir_node *block,
1441 ir_node *high, ir_node *low,
1445 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
1446 * op1 - target to be shifted
1447 * op2 - contains bits to be shifted into target
1449 * Only op3 can be an immediate.
1451 static ir_node *gen_64bit_shifts(dbg_info *dbgi, ir_node *block,
1452 ir_node *high, ir_node *low, ir_node *count,
1453 new_shiftd_func func)
1455 ir_node *new_block = be_transform_node(block);
1456 ir_node *new_high = be_transform_node(high);
1457 ir_node *new_low = be_transform_node(low);
1461 /* the shift amount can be any mode that is bigger than 5 bits, since all
1462 * other bits are ignored anyway */
1463 while (is_Conv(count) &&
1464 get_irn_n_edges(count) == 1 &&
1465 mode_is_int(get_irn_mode(count))) {
1466 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
1467 count = get_Conv_op(count);
1469 new_count = create_immediate_or_transform(count, 0);
1471 new_node = func(dbgi, new_block, new_high, new_low, new_count);
1475 static ir_node *match_64bit_shift(ir_node *node)
1477 ir_node *op1 = get_Or_left(node);
1478 ir_node *op2 = get_Or_right(node);
1486 /* match ShlD operation */
1487 if (is_Shl(op1) && is_Shr(op2)) {
1488 ir_node *shl_right = get_Shl_right(op1);
1489 ir_node *shl_left = get_Shl_left(op1);
1490 ir_node *shr_right = get_Shr_right(op2);
1491 ir_node *shr_left = get_Shr_left(op2);
1492 /* constant ShlD operation */
1493 if (is_complementary_shifts(shl_right, shr_right)) {
1494 dbg_info *dbgi = get_irn_dbg_info(node);
1495 ir_node *block = get_nodes_block(node);
1496 return gen_64bit_shifts(dbgi, block, shl_left, shr_left, shl_right,
1499 /* constant ShrD operation */
1500 if (is_complementary_shifts(shr_right, shl_right)) {
1501 dbg_info *dbgi = get_irn_dbg_info(node);
1502 ir_node *block = get_nodes_block(node);
1503 return gen_64bit_shifts(dbgi, block, shr_left, shl_left, shr_right,
1506 /* lower_dw produces the following for ShlD:
1507 * Or(Shr(Shr(high,1),Not(c)),Shl(low,c)) */
1508 if (is_Shr(shr_left) && is_Not(shr_right)
1509 && is_Const_1(get_Shr_right(shr_left))
1510 && get_Not_op(shr_right) == shl_right) {
1511 dbg_info *dbgi = get_irn_dbg_info(node);
1512 ir_node *block = get_nodes_block(node);
1513 ir_node *val_h = get_Shr_left(shr_left);
1514 return gen_64bit_shifts(dbgi, block, shl_left, val_h, shl_right,
1517 /* lower_dw produces the following for ShrD:
1518 * Or(Shl(Shl(high,1),Not(c)), Shr(low,c)) */
1519 if (is_Shl(shl_left) && is_Not(shl_right)
1520 && is_Const_1(get_Shl_right(shl_left))
1521 && get_Not_op(shl_right) == shr_right) {
1522 dbg_info *dbgi = get_irn_dbg_info(node);
1523 ir_node *block = get_nodes_block(node);
1524 ir_node *val_h = get_Shl_left(shl_left);
1525 return gen_64bit_shifts(dbgi, block, shr_left, val_h, shr_right,
1534 * Creates an ia32 Or.
1536 * @return The created ia32 Or node
1538 static ir_node *gen_Or(ir_node *node)
1540 ir_node *op1 = get_Or_left(node);
1541 ir_node *op2 = get_Or_right(node);
1544 res = match_64bit_shift(node);
1548 assert (! mode_is_float(get_irn_mode(node)));
1549 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1550 | match_mode_neutral | match_am | match_immediate);
1556 * Creates an ia32 Eor.
1558 * @return The created ia32 Eor node
1560 static ir_node *gen_Eor(ir_node *node)
1562 ir_node *op1 = get_Eor_left(node);
1563 ir_node *op2 = get_Eor_right(node);
1565 assert(! mode_is_float(get_irn_mode(node)));
1566 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1567 | match_mode_neutral | match_am | match_immediate);
1572 * Creates an ia32 Sub.
1574 * @return The created ia32 Sub node
1576 static ir_node *gen_Sub(ir_node *node)
1578 ir_node *op1 = get_Sub_left(node);
1579 ir_node *op2 = get_Sub_right(node);
1580 ir_mode *mode = get_irn_mode(node);
1582 if (mode_is_float(mode)) {
1583 if (ia32_cg_config.use_sse2)
1584 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1586 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1589 if (is_Const(op2)) {
1590 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1594 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1595 | match_am | match_immediate);
1598 static ir_node *transform_AM_mem(ir_node *const block,
1599 ir_node *const src_val,
1600 ir_node *const src_mem,
1601 ir_node *const am_mem)
1603 if (is_NoMem(am_mem)) {
1604 return be_transform_node(src_mem);
1605 } else if (is_Proj(src_val) &&
1607 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1608 /* avoid memory loop */
1610 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1611 ir_node *const ptr_pred = get_Proj_pred(src_val);
1612 int const arity = get_Sync_n_preds(src_mem);
1617 NEW_ARR_A(ir_node*, ins, arity + 1);
1619 /* NOTE: This sometimes produces dead-code because the old sync in
1620 * src_mem might not be used anymore, we should detect this case
1621 * and kill the sync... */
1622 for (i = arity - 1; i >= 0; --i) {
1623 ir_node *const pred = get_Sync_pred(src_mem, i);
1625 /* avoid memory loop */
1626 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1629 ins[n++] = be_transform_node(pred);
1632 if (n==1 && ins[0] == am_mem) {
1634 /* creating a new Sync and relying on CSE may fail,
1635 * if am_mem is a ProjM, which does not yet verify. */
1639 return new_r_Sync(block, n, ins);
1643 ins[0] = be_transform_node(src_mem);
1645 return new_r_Sync(block, 2, ins);
1650 * Create a 32bit to 64bit signed extension.
1652 * @param dbgi debug info
1653 * @param block the block where node nodes should be placed
1654 * @param val the value to extend
1655 * @param orig the original node
1657 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1658 ir_node *val, const ir_node *orig)
1663 if (ia32_cg_config.use_short_sex_eax) {
1664 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1665 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1667 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1668 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1670 SET_IA32_ORIG_NODE(res, orig);
1675 * Generates an ia32 Div with additional infrastructure for the
1676 * register allocator if needed.
1678 static ir_node *create_Div(ir_node *node)
1680 dbg_info *dbgi = get_irn_dbg_info(node);
1681 ir_node *block = get_nodes_block(node);
1682 ir_node *new_block = be_transform_node(block);
1689 ir_node *sign_extension;
1690 ia32_address_mode_t am;
1691 ia32_address_t *addr = &am.addr;
1693 /* the upper bits have random contents for smaller modes */
1694 switch (get_irn_opcode(node)) {
1696 op1 = get_Div_left(node);
1697 op2 = get_Div_right(node);
1698 mem = get_Div_mem(node);
1699 mode = get_Div_resmode(node);
1702 op1 = get_Mod_left(node);
1703 op2 = get_Mod_right(node);
1704 mem = get_Mod_mem(node);
1705 mode = get_Mod_resmode(node);
1708 panic("invalid divmod node %+F", node);
1711 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1713 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1714 is the memory of the consumed address. We can have only the second op as address
1715 in Div nodes, so check only op2. */
1716 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1718 if (mode_is_signed(mode)) {
1719 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1720 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1721 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1723 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1725 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1726 addr->index, new_mem, am.new_op2,
1727 am.new_op1, sign_extension);
1730 set_irn_pinned(new_node, get_irn_pinned(node));
1732 set_am_attributes(new_node, &am);
1733 SET_IA32_ORIG_NODE(new_node, node);
1735 new_node = fix_mem_proj(new_node, &am);
1741 * Generates an ia32 Mod.
1743 static ir_node *gen_Mod(ir_node *node)
1745 return create_Div(node);
1749 * Generates an ia32 Div.
1751 static ir_node *gen_Div(ir_node *node)
1753 ir_mode *mode = get_Div_resmode(node);
1754 if (mode_is_float(mode)) {
1755 ir_node *op1 = get_Div_left(node);
1756 ir_node *op2 = get_Div_right(node);
1758 if (ia32_cg_config.use_sse2) {
1759 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1761 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1765 return create_Div(node);
1769 * Creates an ia32 Shl.
1771 * @return The created ia32 Shl node
1773 static ir_node *gen_Shl(ir_node *node)
1775 ir_node *left = get_Shl_left(node);
1776 ir_node *right = get_Shl_right(node);
1778 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1779 match_mode_neutral | match_immediate);
1783 * Creates an ia32 Shr.
1785 * @return The created ia32 Shr node
1787 static ir_node *gen_Shr(ir_node *node)
1789 ir_node *left = get_Shr_left(node);
1790 ir_node *right = get_Shr_right(node);
1792 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1798 * Creates an ia32 Sar.
1800 * @return The created ia32 Shrs node
1802 static ir_node *gen_Shrs(ir_node *node)
1804 ir_node *left = get_Shrs_left(node);
1805 ir_node *right = get_Shrs_right(node);
1807 if (is_Const(right)) {
1808 ir_tarval *tv = get_Const_tarval(right);
1809 long val = get_tarval_long(tv);
1811 /* this is a sign extension */
1812 dbg_info *dbgi = get_irn_dbg_info(node);
1813 ir_node *block = be_transform_node(get_nodes_block(node));
1814 ir_node *new_op = be_transform_node(left);
1816 return create_sex_32_64(dbgi, block, new_op, node);
1820 /* 8 or 16 bit sign extension? */
1821 if (is_Const(right) && is_Shl(left)) {
1822 ir_node *shl_left = get_Shl_left(left);
1823 ir_node *shl_right = get_Shl_right(left);
1824 if (is_Const(shl_right)) {
1825 ir_tarval *tv1 = get_Const_tarval(right);
1826 ir_tarval *tv2 = get_Const_tarval(shl_right);
1827 if (tv1 == tv2 && tarval_is_long(tv1)) {
1828 long val = get_tarval_long(tv1);
1829 if (val == 16 || val == 24) {
1830 dbg_info *dbgi = get_irn_dbg_info(node);
1831 ir_node *block = get_nodes_block(node);
1841 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1850 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1856 * Creates an ia32 Rol.
1858 * @param op1 The first operator
1859 * @param op2 The second operator
1860 * @return The created ia32 RotL node
1862 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1864 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1870 * Creates an ia32 Ror.
1871 * NOTE: There is no RotR with immediate because this would always be a RotL
1872 * "imm-mode_size_bits" which can be pre-calculated.
1874 * @param op1 The first operator
1875 * @param op2 The second operator
1876 * @return The created ia32 RotR node
1878 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1880 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1886 * Creates an ia32 RotR or RotL (depending on the found pattern).
1888 * @return The created ia32 RotL or RotR node
1890 static ir_node *gen_Rotl(ir_node *node)
1892 ir_node *op1 = get_Rotl_left(node);
1893 ir_node *op2 = get_Rotl_right(node);
1895 if (is_Minus(op2)) {
1896 return gen_Ror(node, op1, get_Minus_op(op2));
1899 return gen_Rol(node, op1, op2);
1905 * Transforms a Minus node.
1907 * @return The created ia32 Minus node
1909 static ir_node *gen_Minus(ir_node *node)
1911 ir_node *op = get_Minus_op(node);
1912 ir_node *block = be_transform_node(get_nodes_block(node));
1913 dbg_info *dbgi = get_irn_dbg_info(node);
1914 ir_mode *mode = get_irn_mode(node);
1919 if (mode_is_float(mode)) {
1920 ir_node *new_op = be_transform_node(op);
1921 if (ia32_cg_config.use_sse2) {
1922 /* TODO: non-optimal... if we have many xXors, then we should
1923 * rather create a load for the const and use that instead of
1924 * several AM nodes... */
1925 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1927 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1928 noreg_GP, nomem, new_op, noreg_xmm);
1930 size = get_mode_size_bits(mode);
1931 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1933 set_ia32_am_sc(new_node, ent);
1934 set_ia32_op_type(new_node, ia32_AddrModeS);
1935 set_ia32_ls_mode(new_node, mode);
1937 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1940 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1943 SET_IA32_ORIG_NODE(new_node, node);
1949 * Transforms a Not node.
1951 * @return The created ia32 Not node
1953 static ir_node *gen_Not(ir_node *node)
1955 ir_node *op = get_Not_op(node);
1957 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1958 assert (! mode_is_float(get_irn_mode(node)));
1960 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1963 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1964 bool negate, ir_node *node)
1966 ir_node *new_block = be_transform_node(block);
1967 ir_mode *mode = get_irn_mode(op);
1973 if (mode_is_float(mode)) {
1974 new_op = be_transform_node(op);
1976 if (ia32_cg_config.use_sse2) {
1977 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1978 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1979 noreg_GP, nomem, new_op, noreg_fp);
1981 size = get_mode_size_bits(mode);
1982 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1984 set_ia32_am_sc(new_node, ent);
1986 SET_IA32_ORIG_NODE(new_node, node);
1988 set_ia32_op_type(new_node, ia32_AddrModeS);
1989 set_ia32_ls_mode(new_node, mode);
1991 /* TODO, implement -Abs case */
1994 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1995 SET_IA32_ORIG_NODE(new_node, node);
1997 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1998 SET_IA32_ORIG_NODE(new_node, node);
2007 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
2009 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
2011 dbg_info *dbgi = get_irn_dbg_info(cmp);
2012 ir_node *block = get_nodes_block(cmp);
2013 ir_node *new_block = be_transform_node(block);
2014 ir_node *op1 = be_transform_node(x);
2015 ir_node *op2 = be_transform_node(n);
2017 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
2020 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
2023 if (mode_is_float(mode)) {
2025 case ir_relation_equal: return ia32_cc_float_equal;
2026 case ir_relation_less: return ia32_cc_float_below;
2027 case ir_relation_less_equal: return ia32_cc_float_below_equal;
2028 case ir_relation_greater: return ia32_cc_float_above;
2029 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
2030 case ir_relation_less_greater: return ia32_cc_not_equal;
2031 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
2032 case ir_relation_unordered: return ia32_cc_parity;
2033 case ir_relation_unordered_equal: return ia32_cc_equal;
2034 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
2035 case ir_relation_unordered_less_equal:
2036 return ia32_cc_float_unordered_below_equal;
2037 case ir_relation_unordered_greater:
2038 return ia32_cc_float_unordered_above;
2039 case ir_relation_unordered_greater_equal:
2040 return ia32_cc_float_unordered_above_equal;
2041 case ir_relation_unordered_less_greater:
2042 return ia32_cc_float_not_equal;
2043 case ir_relation_false:
2044 case ir_relation_true:
2045 /* should we introduce a jump always/jump never? */
2048 panic("Unexpected float pnc");
2049 } else if (mode_is_signed(mode)) {
2051 case ir_relation_unordered_equal:
2052 case ir_relation_equal: return ia32_cc_equal;
2053 case ir_relation_unordered_less:
2054 case ir_relation_less: return ia32_cc_less;
2055 case ir_relation_unordered_less_equal:
2056 case ir_relation_less_equal: return ia32_cc_less_equal;
2057 case ir_relation_unordered_greater:
2058 case ir_relation_greater: return ia32_cc_greater;
2059 case ir_relation_unordered_greater_equal:
2060 case ir_relation_greater_equal: return ia32_cc_greater_equal;
2061 case ir_relation_unordered_less_greater:
2062 case ir_relation_less_greater: return ia32_cc_not_equal;
2063 case ir_relation_less_equal_greater:
2064 case ir_relation_unordered:
2065 case ir_relation_false:
2066 case ir_relation_true:
2067 /* introduce jump always/jump never? */
2070 panic("Unexpected pnc");
2073 case ir_relation_unordered_equal:
2074 case ir_relation_equal: return ia32_cc_equal;
2075 case ir_relation_unordered_less:
2076 case ir_relation_less: return ia32_cc_below;
2077 case ir_relation_unordered_less_equal:
2078 case ir_relation_less_equal: return ia32_cc_below_equal;
2079 case ir_relation_unordered_greater:
2080 case ir_relation_greater: return ia32_cc_above;
2081 case ir_relation_unordered_greater_equal:
2082 case ir_relation_greater_equal: return ia32_cc_above_equal;
2083 case ir_relation_unordered_less_greater:
2084 case ir_relation_less_greater: return ia32_cc_not_equal;
2085 case ir_relation_less_equal_greater:
2086 case ir_relation_unordered:
2087 case ir_relation_false:
2088 case ir_relation_true:
2089 /* introduce jump always/jump never? */
2092 panic("Unexpected pnc");
2096 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
2098 /* a mode_b value, we have to compare it against 0 */
2099 dbg_info *dbgi = get_irn_dbg_info(node);
2100 ir_node *new_block = be_transform_node(get_nodes_block(node));
2101 ir_node *new_op = be_transform_node(node);
2102 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2103 *cc_out = ia32_cc_not_equal;
2107 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2109 /* must have a Cmp as input */
2110 ir_relation relation = get_Cmp_relation(cmp);
2111 ir_relation possible;
2112 ir_node *l = get_Cmp_left(cmp);
2113 ir_node *r = get_Cmp_right(cmp);
2114 ir_mode *mode = get_irn_mode(l);
2117 /* check for bit-test */
2118 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2119 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2120 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2122 ir_node *la = get_And_left(l);
2123 ir_node *ra = get_And_right(l);
2130 ir_node *c = get_Shl_left(la);
2131 if (is_Const_1(c) && is_Const_0(r)) {
2132 /* (1 << n) & ra) */
2133 ir_node *n = get_Shl_right(la);
2134 flags = gen_bt(cmp, ra, n);
2135 /* the bit is copied into the CF flag */
2136 if (relation & ir_relation_equal)
2137 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2139 *cc_out = ia32_cc_below; /* test for CF=1 */
2145 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2146 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2147 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2148 * a predecessor node). So add the < bit */
2149 possible = ir_get_possible_cmp_relations(l, r);
2150 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2151 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2152 relation |= ir_relation_less_greater;
2154 /* just do a normal transformation of the Cmp */
2155 *cc_out = relation_to_condition_code(relation, mode);
2156 flags = be_transform_node(cmp);
2161 * Transform a node returning a "flag" result.
2163 * @param node the node to transform
2164 * @param cc_out the compare mode to use
2166 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2169 return get_flags_node_cmp(node, cc_out);
2170 assert(get_irn_mode(node) == mode_b);
2171 return get_flags_mode_b(node, cc_out);
2175 * Transforms a Load.
2177 * @return the created ia32 Load node
2179 static ir_node *gen_Load(ir_node *node)
2181 ir_node *old_block = get_nodes_block(node);
2182 ir_node *block = be_transform_node(old_block);
2183 ir_node *ptr = get_Load_ptr(node);
2184 ir_node *mem = get_Load_mem(node);
2185 ir_node *new_mem = be_transform_node(mem);
2186 dbg_info *dbgi = get_irn_dbg_info(node);
2187 ir_mode *mode = get_Load_mode(node);
2191 ia32_address_t addr;
2193 /* construct load address */
2194 memset(&addr, 0, sizeof(addr));
2195 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2202 base = be_transform_node(base);
2205 if (index == NULL) {
2208 index = be_transform_node(index);
2211 if (mode_is_float(mode)) {
2212 if (ia32_cg_config.use_sse2) {
2213 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2216 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2220 assert(mode != mode_b);
2222 /* create a conv node with address mode for smaller modes */
2223 if (get_mode_size_bits(mode) < 32) {
2224 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2225 new_mem, noreg_GP, mode);
2227 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2231 set_irn_pinned(new_node, get_irn_pinned(node));
2232 set_ia32_op_type(new_node, ia32_AddrModeS);
2233 set_ia32_ls_mode(new_node, mode);
2234 set_address(new_node, &addr);
2236 if (get_irn_pinned(node) == op_pin_state_floats) {
2237 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2238 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2239 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2240 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2243 SET_IA32_ORIG_NODE(new_node, node);
2248 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2249 ir_node *ptr, ir_node *other)
2256 /* we only use address mode if we're the only user of the load */
2257 if (get_irn_n_edges(node) > 1)
2260 load = get_Proj_pred(node);
2263 if (get_nodes_block(load) != block)
2266 /* store should have the same pointer as the load */
2267 if (get_Load_ptr(load) != ptr)
2270 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2271 if (other != NULL &&
2272 get_nodes_block(other) == block &&
2273 heights_reachable_in_block(ia32_heights, other, load)) {
2277 if (ia32_prevents_AM(block, load, mem))
2279 /* Store should be attached to the load via mem */
2280 assert(heights_reachable_in_block(ia32_heights, mem, load));
2285 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2286 ir_node *mem, ir_node *ptr, ir_mode *mode,
2287 construct_binop_dest_func *func,
2288 construct_binop_dest_func *func8bit,
2289 match_flags_t flags)
2291 ir_node *src_block = get_nodes_block(node);
2299 ia32_address_mode_t am;
2300 ia32_address_t *addr = &am.addr;
2301 memset(&am, 0, sizeof(am));
2303 assert(flags & match_immediate); /* there is no destam node without... */
2304 commutative = (flags & match_commutative) != 0;
2306 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2307 build_address(&am, op1, ia32_create_am_double_use);
2308 new_op = create_immediate_or_transform(op2, 0);
2309 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2310 build_address(&am, op2, ia32_create_am_double_use);
2311 new_op = create_immediate_or_transform(op1, 0);
2316 if (addr->base == NULL)
2317 addr->base = noreg_GP;
2318 if (addr->index == NULL)
2319 addr->index = noreg_GP;
2320 if (addr->mem == NULL)
2323 dbgi = get_irn_dbg_info(node);
2324 block = be_transform_node(src_block);
2325 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2327 if (get_mode_size_bits(mode) == 8) {
2328 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2330 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2332 set_address(new_node, addr);
2333 set_ia32_op_type(new_node, ia32_AddrModeD);
2334 set_ia32_ls_mode(new_node, mode);
2335 SET_IA32_ORIG_NODE(new_node, node);
2337 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2338 mem_proj = be_transform_node(am.mem_proj);
2339 be_set_transformed_node(am.mem_proj, new_node);
2340 be_set_transformed_node(mem_proj, new_node);
2345 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2346 ir_node *ptr, ir_mode *mode,
2347 construct_unop_dest_func *func)
2349 ir_node *src_block = get_nodes_block(node);
2355 ia32_address_mode_t am;
2356 ia32_address_t *addr = &am.addr;
2358 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2361 memset(&am, 0, sizeof(am));
2362 build_address(&am, op, ia32_create_am_double_use);
2364 dbgi = get_irn_dbg_info(node);
2365 block = be_transform_node(src_block);
2366 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2367 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2368 set_address(new_node, addr);
2369 set_ia32_op_type(new_node, ia32_AddrModeD);
2370 set_ia32_ls_mode(new_node, mode);
2371 SET_IA32_ORIG_NODE(new_node, node);
2373 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2374 mem_proj = be_transform_node(am.mem_proj);
2375 be_set_transformed_node(am.mem_proj, new_node);
2376 be_set_transformed_node(mem_proj, new_node);
2381 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2383 ir_mode *mode = get_irn_mode(node);
2384 ir_node *mux_true = get_Mux_true(node);
2385 ir_node *mux_false = get_Mux_false(node);
2393 ia32_condition_code_t cc;
2394 ia32_address_t addr;
2396 if (get_mode_size_bits(mode) != 8)
2399 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2401 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2407 cond = get_Mux_sel(node);
2408 flags = get_flags_node(cond, &cc);
2409 /* we can't handle the float special cases with SetM */
2410 if (cc & ia32_cc_additional_float_cases)
2413 cc = ia32_negate_condition_code(cc);
2415 build_address_ptr(&addr, ptr, mem);
2417 dbgi = get_irn_dbg_info(node);
2418 block = get_nodes_block(node);
2419 new_block = be_transform_node(block);
2420 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2421 addr.index, addr.mem, flags, cc);
2422 set_address(new_node, &addr);
2423 set_ia32_op_type(new_node, ia32_AddrModeD);
2424 set_ia32_ls_mode(new_node, mode);
2425 SET_IA32_ORIG_NODE(new_node, node);
2430 static ir_node *try_create_dest_am(ir_node *node)
2432 ir_node *val = get_Store_value(node);
2433 ir_node *mem = get_Store_mem(node);
2434 ir_node *ptr = get_Store_ptr(node);
2435 ir_mode *mode = get_irn_mode(val);
2436 unsigned bits = get_mode_size_bits(mode);
2441 /* handle only GP modes for now... */
2442 if (!ia32_mode_needs_gp_reg(mode))
2446 /* store must be the only user of the val node */
2447 if (get_irn_n_edges(val) > 1)
2449 /* skip pointless convs */
2451 ir_node *conv_op = get_Conv_op(val);
2452 ir_mode *pred_mode = get_irn_mode(conv_op);
2453 if (!ia32_mode_needs_gp_reg(pred_mode))
2455 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2463 /* value must be in the same block */
2464 if (get_nodes_block(node) != get_nodes_block(val))
2467 switch (get_irn_opcode(val)) {
2469 op1 = get_Add_left(val);
2470 op2 = get_Add_right(val);
2471 if (ia32_cg_config.use_incdec) {
2472 if (is_Const_1(op2)) {
2473 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2475 } else if (is_Const_Minus_1(op2)) {
2476 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2480 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2481 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2482 match_commutative | match_immediate);
2485 op1 = get_Sub_left(val);
2486 op2 = get_Sub_right(val);
2487 if (is_Const(op2)) {
2488 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2490 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2491 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2495 op1 = get_And_left(val);
2496 op2 = get_And_right(val);
2497 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2498 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2499 match_commutative | match_immediate);
2502 op1 = get_Or_left(val);
2503 op2 = get_Or_right(val);
2504 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2505 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2506 match_commutative | match_immediate);
2509 op1 = get_Eor_left(val);
2510 op2 = get_Eor_right(val);
2511 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2512 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2513 match_commutative | match_immediate);
2516 op1 = get_Shl_left(val);
2517 op2 = get_Shl_right(val);
2518 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2519 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2523 op1 = get_Shr_left(val);
2524 op2 = get_Shr_right(val);
2525 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2526 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2530 op1 = get_Shrs_left(val);
2531 op2 = get_Shrs_right(val);
2532 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2533 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2537 op1 = get_Rotl_left(val);
2538 op2 = get_Rotl_right(val);
2539 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2540 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2543 /* TODO: match ROR patterns... */
2545 new_node = try_create_SetMem(val, ptr, mem);
2549 op1 = get_Minus_op(val);
2550 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2553 /* should be lowered already */
2554 assert(mode != mode_b);
2555 op1 = get_Not_op(val);
2556 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2562 if (new_node != NULL) {
2563 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2564 get_irn_pinned(node) == op_pin_state_pinned) {
2565 set_irn_pinned(new_node, op_pin_state_pinned);
2572 static bool possible_int_mode_for_fp(ir_mode *mode)
2576 if (!mode_is_signed(mode))
2578 size = get_mode_size_bits(mode);
2579 if (size != 16 && size != 32)
2584 static int is_float_to_int_conv(const ir_node *node)
2586 ir_mode *mode = get_irn_mode(node);
2590 if (!possible_int_mode_for_fp(mode))
2595 conv_op = get_Conv_op(node);
2596 conv_mode = get_irn_mode(conv_op);
2598 if (!mode_is_float(conv_mode))
2605 * Transform a Store(floatConst) into a sequence of
2608 * @return the created ia32 Store node
2610 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2612 ir_mode *mode = get_irn_mode(cns);
2613 unsigned size = get_mode_size_bytes(mode);
2614 ir_tarval *tv = get_Const_tarval(cns);
2615 ir_node *block = get_nodes_block(node);
2616 ir_node *new_block = be_transform_node(block);
2617 ir_node *ptr = get_Store_ptr(node);
2618 ir_node *mem = get_Store_mem(node);
2619 dbg_info *dbgi = get_irn_dbg_info(node);
2623 ia32_address_t addr;
2625 assert(size % 4 == 0);
2628 build_address_ptr(&addr, ptr, mem);
2632 get_tarval_sub_bits(tv, ofs) |
2633 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2634 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2635 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2636 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2638 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2639 addr.index, addr.mem, imm);
2641 set_irn_pinned(new_node, get_irn_pinned(node));
2642 set_ia32_op_type(new_node, ia32_AddrModeD);
2643 set_ia32_ls_mode(new_node, mode_Iu);
2644 set_address(new_node, &addr);
2645 SET_IA32_ORIG_NODE(new_node, node);
2648 ins[i++] = new_node;
2653 } while (size != 0);
2656 return new_rd_Sync(dbgi, new_block, i, ins);
2663 * Generate a vfist or vfisttp instruction.
2665 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2666 ir_node *mem, ir_node *val, ir_node **fist)
2670 if (ia32_cg_config.use_fisttp) {
2671 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2672 if other users exists */
2673 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2674 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2675 be_new_Keep(block, 1, &value);
2677 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2680 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2683 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2689 * Transforms a general (no special case) Store.
2691 * @return the created ia32 Store node
2693 static ir_node *gen_general_Store(ir_node *node)
2695 ir_node *val = get_Store_value(node);
2696 ir_mode *mode = get_irn_mode(val);
2697 ir_node *block = get_nodes_block(node);
2698 ir_node *new_block = be_transform_node(block);
2699 ir_node *ptr = get_Store_ptr(node);
2700 ir_node *mem = get_Store_mem(node);
2701 dbg_info *dbgi = get_irn_dbg_info(node);
2702 ir_node *new_val, *new_node, *store;
2703 ia32_address_t addr;
2705 /* check for destination address mode */
2706 new_node = try_create_dest_am(node);
2707 if (new_node != NULL)
2710 /* construct store address */
2711 memset(&addr, 0, sizeof(addr));
2712 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2714 if (addr.base == NULL) {
2715 addr.base = noreg_GP;
2717 addr.base = be_transform_node(addr.base);
2720 if (addr.index == NULL) {
2721 addr.index = noreg_GP;
2723 addr.index = be_transform_node(addr.index);
2725 addr.mem = be_transform_node(mem);
2727 if (mode_is_float(mode)) {
2728 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2730 while (is_Conv(val) && mode == get_irn_mode(val)) {
2731 ir_node *op = get_Conv_op(val);
2732 if (!mode_is_float(get_irn_mode(op)))
2736 new_val = be_transform_node(val);
2737 if (ia32_cg_config.use_sse2) {
2738 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2739 addr.index, addr.mem, new_val);
2741 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2742 addr.index, addr.mem, new_val, mode);
2745 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2746 val = get_Conv_op(val);
2748 /* TODO: is this optimisation still necessary at all (middleend)? */
2749 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2750 while (is_Conv(val)) {
2751 ir_node *op = get_Conv_op(val);
2752 if (!mode_is_float(get_irn_mode(op)))
2754 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2758 new_val = be_transform_node(val);
2759 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2761 new_val = create_immediate_or_transform(val, 0);
2762 assert(mode != mode_b);
2764 if (get_mode_size_bits(mode) == 8) {
2765 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2766 addr.index, addr.mem, new_val);
2768 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2769 addr.index, addr.mem, new_val);
2774 set_irn_pinned(store, get_irn_pinned(node));
2775 set_ia32_op_type(store, ia32_AddrModeD);
2776 set_ia32_ls_mode(store, mode);
2778 set_address(store, &addr);
2779 SET_IA32_ORIG_NODE(store, node);
2785 * Transforms a Store.
2787 * @return the created ia32 Store node
2789 static ir_node *gen_Store(ir_node *node)
2791 ir_node *val = get_Store_value(node);
2792 ir_mode *mode = get_irn_mode(val);
2794 if (mode_is_float(mode) && is_Const(val)) {
2795 /* We can transform every floating const store
2796 into a sequence of integer stores.
2797 If the constant is already in a register,
2798 it would be better to use it, but we don't
2799 have this information here. */
2800 return gen_float_const_Store(node, val);
2802 return gen_general_Store(node);
2806 * Transforms a Switch.
2808 * @return the created ia32 SwitchJmp node
2810 static ir_node *create_Switch(ir_node *node)
2812 dbg_info *dbgi = get_irn_dbg_info(node);
2813 ir_node *block = be_transform_node(get_nodes_block(node));
2814 ir_node *sel = get_Cond_selector(node);
2815 ir_node *new_sel = be_transform_node(sel);
2816 long switch_min = LONG_MAX;
2817 long switch_max = LONG_MIN;
2818 long default_pn = get_Cond_default_proj(node);
2820 const ir_edge_t *edge;
2822 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2824 /* determine the smallest switch case value */
2825 foreach_out_edge(node, edge) {
2826 ir_node *proj = get_edge_src_irn(edge);
2827 long pn = get_Proj_proj(proj);
2828 if (pn == default_pn)
2831 if (pn < switch_min)
2833 if (pn > switch_max)
2837 if ((unsigned long) (switch_max - switch_min) > 128000) {
2838 panic("Size of switch %+F bigger than 128000", node);
2841 if (switch_min != 0) {
2842 /* if smallest switch case is not 0 we need an additional sub */
2843 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2844 add_ia32_am_offs_int(new_sel, -switch_min);
2845 set_ia32_op_type(new_sel, ia32_AddrModeS);
2847 SET_IA32_ORIG_NODE(new_sel, node);
2850 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2851 SET_IA32_ORIG_NODE(new_node, node);
2857 * Transform a Cond node.
2859 static ir_node *gen_Cond(ir_node *node)
2861 ir_node *block = get_nodes_block(node);
2862 ir_node *new_block = be_transform_node(block);
2863 dbg_info *dbgi = get_irn_dbg_info(node);
2864 ir_node *sel = get_Cond_selector(node);
2865 ir_mode *sel_mode = get_irn_mode(sel);
2866 ir_node *flags = NULL;
2868 ia32_condition_code_t cc;
2870 if (sel_mode != mode_b) {
2871 return create_Switch(node);
2874 /* we get flags from a Cmp */
2875 flags = get_flags_node(sel, &cc);
2877 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2878 SET_IA32_ORIG_NODE(new_node, node);
2884 * Transform a be_Copy.
2886 static ir_node *gen_be_Copy(ir_node *node)
2888 ir_node *new_node = be_duplicate_node(node);
2889 ir_mode *mode = get_irn_mode(new_node);
2891 if (ia32_mode_needs_gp_reg(mode)) {
2892 set_irn_mode(new_node, mode_Iu);
2898 static ir_node *create_Fucom(ir_node *node)
2900 dbg_info *dbgi = get_irn_dbg_info(node);
2901 ir_node *block = get_nodes_block(node);
2902 ir_node *new_block = be_transform_node(block);
2903 ir_node *left = get_Cmp_left(node);
2904 ir_node *new_left = be_transform_node(left);
2905 ir_node *right = get_Cmp_right(node);
2909 if (ia32_cg_config.use_fucomi) {
2910 new_right = be_transform_node(right);
2911 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2913 set_ia32_commutative(new_node);
2914 SET_IA32_ORIG_NODE(new_node, node);
2916 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2917 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2919 new_right = be_transform_node(right);
2920 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2923 set_ia32_commutative(new_node);
2925 SET_IA32_ORIG_NODE(new_node, node);
2927 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2928 SET_IA32_ORIG_NODE(new_node, node);
2934 static ir_node *create_Ucomi(ir_node *node)
2936 dbg_info *dbgi = get_irn_dbg_info(node);
2937 ir_node *src_block = get_nodes_block(node);
2938 ir_node *new_block = be_transform_node(src_block);
2939 ir_node *left = get_Cmp_left(node);
2940 ir_node *right = get_Cmp_right(node);
2942 ia32_address_mode_t am;
2943 ia32_address_t *addr = &am.addr;
2945 match_arguments(&am, src_block, left, right, NULL,
2946 match_commutative | match_am);
2948 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2949 addr->mem, am.new_op1, am.new_op2,
2951 set_am_attributes(new_node, &am);
2953 SET_IA32_ORIG_NODE(new_node, node);
2955 new_node = fix_mem_proj(new_node, &am);
2961 * returns true if it is assured, that the upper bits of a node are "clean"
2962 * which means for a 16 or 8 bit value, that the upper bits in the register
2963 * are 0 for unsigned and a copy of the last significant bit for signed
2966 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2968 assert(ia32_mode_needs_gp_reg(mode));
2969 if (get_mode_size_bits(mode) >= 32)
2972 if (is_Proj(transformed_node))
2973 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2975 switch (get_ia32_irn_opcode(transformed_node)) {
2976 case iro_ia32_Conv_I2I:
2977 case iro_ia32_Conv_I2I8Bit: {
2978 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2979 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2981 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2988 if (mode_is_signed(mode)) {
2989 return false; /* TODO handle signed modes */
2991 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2992 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2993 const ia32_immediate_attr_t *attr
2994 = get_ia32_immediate_attr_const(right);
2995 if (attr->symconst == 0 &&
2996 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
3000 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
3004 /* TODO too conservative if shift amount is constant */
3005 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
3008 if (!mode_is_signed(mode)) {
3010 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
3011 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
3013 /* TODO if one is known to be zero extended, then || is sufficient */
3018 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
3019 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
3021 case iro_ia32_Const:
3022 case iro_ia32_Immediate: {
3023 const ia32_immediate_attr_t *attr =
3024 get_ia32_immediate_attr_const(transformed_node);
3025 if (mode_is_signed(mode)) {
3026 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
3027 return shifted == 0 || shifted == -1;
3029 unsigned long shifted = (unsigned long)attr->offset;
3030 shifted >>= get_mode_size_bits(mode);
3031 return shifted == 0;
3041 * Generate code for a Cmp.
3043 static ir_node *gen_Cmp(ir_node *node)
3045 dbg_info *dbgi = get_irn_dbg_info(node);
3046 ir_node *block = get_nodes_block(node);
3047 ir_node *new_block = be_transform_node(block);
3048 ir_node *left = get_Cmp_left(node);
3049 ir_node *right = get_Cmp_right(node);
3050 ir_mode *cmp_mode = get_irn_mode(left);
3052 ia32_address_mode_t am;
3053 ia32_address_t *addr = &am.addr;
3055 if (mode_is_float(cmp_mode)) {
3056 if (ia32_cg_config.use_sse2) {
3057 return create_Ucomi(node);
3059 return create_Fucom(node);
3063 assert(ia32_mode_needs_gp_reg(cmp_mode));
3065 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
3066 if (is_Const_0(right) &&
3068 get_irn_n_edges(left) == 1) {
3069 /* Test(and_left, and_right) */
3070 ir_node *and_left = get_And_left(left);
3071 ir_node *and_right = get_And_right(left);
3073 /* matze: code here used mode instead of cmd_mode, I think it is always
3074 * the same as cmp_mode, but I leave this here to see if this is really
3077 assert(get_irn_mode(and_left) == cmp_mode);
3079 match_arguments(&am, block, and_left, and_right, NULL,
3081 match_am | match_8bit_am | match_16bit_am |
3082 match_am_and_immediates | match_immediate);
3084 /* use 32bit compare mode if possible since the opcode is smaller */
3085 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3086 upper_bits_clean(am.new_op2, cmp_mode)) {
3087 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3090 if (get_mode_size_bits(cmp_mode) == 8) {
3091 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3092 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3094 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3095 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3098 /* Cmp(left, right) */
3099 match_arguments(&am, block, left, right, NULL,
3100 match_commutative | match_am | match_8bit_am |
3101 match_16bit_am | match_am_and_immediates |
3103 /* use 32bit compare mode if possible since the opcode is smaller */
3104 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3105 upper_bits_clean(am.new_op2, cmp_mode)) {
3106 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3109 if (get_mode_size_bits(cmp_mode) == 8) {
3110 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3111 addr->index, addr->mem, am.new_op1,
3112 am.new_op2, am.ins_permuted);
3114 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3115 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3118 set_am_attributes(new_node, &am);
3119 set_ia32_ls_mode(new_node, cmp_mode);
3121 SET_IA32_ORIG_NODE(new_node, node);
3123 new_node = fix_mem_proj(new_node, &am);
3128 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3129 ia32_condition_code_t cc)
3131 dbg_info *dbgi = get_irn_dbg_info(node);
3132 ir_node *block = get_nodes_block(node);
3133 ir_node *new_block = be_transform_node(block);
3134 ir_node *val_true = get_Mux_true(node);
3135 ir_node *val_false = get_Mux_false(node);
3137 ia32_address_mode_t am;
3138 ia32_address_t *addr;
3140 assert(ia32_cg_config.use_cmov);
3141 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3145 match_arguments(&am, block, val_false, val_true, flags,
3146 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3148 if (am.ins_permuted)
3149 cc = ia32_negate_condition_code(cc);
3151 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3152 addr->mem, am.new_op1, am.new_op2, new_flags,
3154 set_am_attributes(new_node, &am);
3156 SET_IA32_ORIG_NODE(new_node, node);
3158 new_node = fix_mem_proj(new_node, &am);
3164 * Creates a ia32 Setcc instruction.
3166 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3167 ir_node *flags, ia32_condition_code_t cc,
3170 ir_mode *mode = get_irn_mode(orig_node);
3173 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3174 SET_IA32_ORIG_NODE(new_node, orig_node);
3176 /* we might need to conv the result up */
3177 if (get_mode_size_bits(mode) > 8) {
3178 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3179 nomem, new_node, mode_Bu);
3180 SET_IA32_ORIG_NODE(new_node, orig_node);
3187 * Create instruction for an unsigned Difference or Zero.
3189 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3191 ir_mode *mode = get_irn_mode(psi);
3201 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3202 match_mode_neutral | match_am | match_immediate | match_two_users);
3204 block = get_nodes_block(new_node);
3206 if (is_Proj(new_node)) {
3207 sub = get_Proj_pred(new_node);
3210 set_irn_mode(sub, mode_T);
3211 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3213 assert(is_ia32_Sub(sub));
3214 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3216 dbgi = get_irn_dbg_info(psi);
3217 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3218 notn = new_bd_ia32_Not(dbgi, block, sbb);
3220 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3221 set_ia32_commutative(new_node);
3226 * Create an const array of two float consts.
3228 * @param c0 the first constant
3229 * @param c1 the second constant
3230 * @param new_mode IN/OUT for the mode of the constants, if NULL
3231 * smallest possible mode will be used
3233 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3236 ir_mode *mode = *new_mode;
3238 ir_initializer_t *initializer;
3239 ir_tarval *tv0 = get_Const_tarval(c0);
3240 ir_tarval *tv1 = get_Const_tarval(c1);
3243 /* detect the best mode for the constants */
3244 mode = get_tarval_mode(tv0);
3246 if (mode != mode_F) {
3247 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3248 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3250 tv0 = tarval_convert_to(tv0, mode);
3251 tv1 = tarval_convert_to(tv1, mode);
3252 } else if (mode != mode_D) {
3253 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3254 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3256 tv0 = tarval_convert_to(tv0, mode);
3257 tv1 = tarval_convert_to(tv1, mode);
3264 tp = ia32_create_float_type(mode, 4);
3265 tp = ia32_create_float_array(tp);
3267 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3269 set_entity_ld_ident(ent, get_entity_ident(ent));
3270 set_entity_visibility(ent, ir_visibility_private);
3271 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3273 initializer = create_initializer_compound(2);
3275 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3276 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3278 set_entity_initializer(ent, initializer);
3285 * Possible transformations for creating a Setcc.
3287 enum setcc_transform_insn {
3300 typedef struct setcc_transform {
3302 ia32_condition_code_t cc;
3304 enum setcc_transform_insn transform;
3308 } setcc_transform_t;
3311 * Setcc can only handle 0 and 1 result.
3312 * Find a transformation that creates 0 and 1 from
3315 static void find_const_transform(ia32_condition_code_t cc,
3316 ir_tarval *t, ir_tarval *f,
3317 setcc_transform_t *res)
3323 if (tarval_is_null(t)) {
3327 cc = ia32_negate_condition_code(cc);
3328 } else if (tarval_cmp(t, f) == ir_relation_less) {
3329 // now, t is the bigger one
3333 cc = ia32_negate_condition_code(cc);
3337 if (! tarval_is_null(f)) {
3338 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3341 res->steps[step].transform = SETCC_TR_ADD;
3343 if (t == tarval_bad)
3344 panic("constant subtract failed");
3345 if (! tarval_is_long(f))
3346 panic("tarval is not long");
3348 res->steps[step].val = get_tarval_long(f);
3350 f = tarval_sub(f, f, NULL);
3351 assert(tarval_is_null(f));
3354 if (tarval_is_one(t)) {
3355 res->steps[step].transform = SETCC_TR_SET;
3356 res->num_steps = ++step;
3360 if (tarval_is_minus_one(t)) {
3361 res->steps[step].transform = SETCC_TR_NEG;
3363 res->steps[step].transform = SETCC_TR_SET;
3364 res->num_steps = ++step;
3367 if (tarval_is_long(t)) {
3368 long v = get_tarval_long(t);
3370 res->steps[step].val = 0;
3373 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3375 res->steps[step].transform = SETCC_TR_LEAxx;
3376 res->steps[step].scale = 3; /* (a << 3) + a */
3379 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3381 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3382 res->steps[step].scale = 3; /* (a << 3) */
3385 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3387 res->steps[step].transform = SETCC_TR_LEAxx;
3388 res->steps[step].scale = 2; /* (a << 2) + a */
3391 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3393 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3394 res->steps[step].scale = 2; /* (a << 2) */
3397 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3399 res->steps[step].transform = SETCC_TR_LEAxx;
3400 res->steps[step].scale = 1; /* (a << 1) + a */
3403 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3405 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3406 res->steps[step].scale = 1; /* (a << 1) */
3409 res->num_steps = step;
3412 if (! tarval_is_single_bit(t)) {
3413 res->steps[step].transform = SETCC_TR_AND;
3414 res->steps[step].val = v;
3416 res->steps[step].transform = SETCC_TR_NEG;
3418 int v = get_tarval_lowest_bit(t);
3421 res->steps[step].transform = SETCC_TR_SHL;
3422 res->steps[step].scale = v;
3426 res->steps[step].transform = SETCC_TR_SET;
3427 res->num_steps = ++step;
3430 panic("tarval is not long");
3434 * Transforms a Mux node into some code sequence.
3436 * @return The transformed node.
3438 static ir_node *gen_Mux(ir_node *node)
3440 dbg_info *dbgi = get_irn_dbg_info(node);
3441 ir_node *block = get_nodes_block(node);
3442 ir_node *new_block = be_transform_node(block);
3443 ir_node *mux_true = get_Mux_true(node);
3444 ir_node *mux_false = get_Mux_false(node);
3445 ir_node *sel = get_Mux_sel(node);
3446 ir_mode *mode = get_irn_mode(node);
3450 ia32_condition_code_t cc;
3452 assert(get_irn_mode(sel) == mode_b);
3454 is_abs = ir_mux_is_abs(sel, mux_true, mux_false);
3456 if (ia32_mode_needs_gp_reg(mode)) {
3457 ir_fprintf(stderr, "Optimisation warning: Integer abs %+F not transformed\n",
3460 ir_node *op = ir_get_abs_op(sel, mux_true, mux_false);
3461 return create_abs(dbgi, block, op, is_abs < 0, node);
3465 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3466 if (mode_is_float(mode)) {
3467 ir_node *cmp_left = get_Cmp_left(sel);
3468 ir_node *cmp_right = get_Cmp_right(sel);
3469 ir_relation relation = get_Cmp_relation(sel);
3471 if (ia32_cg_config.use_sse2) {
3472 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3473 if (cmp_left == mux_true && cmp_right == mux_false) {
3474 /* Mux(a <= b, a, b) => MIN */
3475 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3476 match_commutative | match_am | match_two_users);
3477 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3478 /* Mux(a <= b, b, a) => MAX */
3479 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3480 match_commutative | match_am | match_two_users);
3482 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3483 if (cmp_left == mux_true && cmp_right == mux_false) {
3484 /* Mux(a >= b, a, b) => MAX */
3485 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3486 match_commutative | match_am | match_two_users);
3487 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3488 /* Mux(a >= b, b, a) => MIN */
3489 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3490 match_commutative | match_am | match_two_users);
3495 if (is_Const(mux_true) && is_Const(mux_false)) {
3496 ia32_address_mode_t am;
3501 flags = get_flags_node(sel, &cc);
3502 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3504 if (ia32_cg_config.use_sse2) {
3505 /* cannot load from different mode on SSE */
3508 /* x87 can load any mode */
3512 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3514 switch (get_mode_size_bytes(new_mode)) {
3524 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3525 set_ia32_am_scale(new_node, 2);
3530 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3531 set_ia32_am_scale(new_node, 1);
3534 /* arg, shift 16 NOT supported */
3536 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3539 panic("Unsupported constant size");
3542 am.ls_mode = new_mode;
3543 am.addr.base = get_symconst_base();
3544 am.addr.index = new_node;
3545 am.addr.mem = nomem;
3547 am.addr.scale = scale;
3548 am.addr.use_frame = 0;
3549 am.addr.tls_segment = false;
3550 am.addr.frame_entity = NULL;
3551 am.addr.symconst_sign = 0;
3552 am.mem_proj = am.addr.mem;
3553 am.op_type = ia32_AddrModeS;
3556 am.pinned = op_pin_state_floats;
3558 am.ins_permuted = false;
3560 if (ia32_cg_config.use_sse2)
3561 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3563 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3564 set_am_attributes(load, &am);
3566 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3568 panic("cannot transform floating point Mux");
3571 assert(ia32_mode_needs_gp_reg(mode));
3574 ir_node *cmp_left = get_Cmp_left(sel);
3575 ir_node *cmp_right = get_Cmp_right(sel);
3576 ir_relation relation = get_Cmp_relation(sel);
3577 ir_node *val_true = mux_true;
3578 ir_node *val_false = mux_false;
3580 if (is_Const(val_true) && is_Const_null(val_true)) {
3581 ir_node *tmp = val_false;
3582 val_false = val_true;
3584 relation = get_negated_relation(relation);
3586 if (is_Const_0(val_false) && is_Sub(val_true)) {
3587 if ((relation & ir_relation_greater)
3588 && get_Sub_left(val_true) == cmp_left
3589 && get_Sub_right(val_true) == cmp_right) {
3590 return create_doz(node, cmp_left, cmp_right);
3592 if ((relation & ir_relation_less)
3593 && get_Sub_left(val_true) == cmp_right
3594 && get_Sub_right(val_true) == cmp_left) {
3595 return create_doz(node, cmp_right, cmp_left);
3600 flags = get_flags_node(sel, &cc);
3602 if (is_Const(mux_true) && is_Const(mux_false)) {
3603 /* both are const, good */
3604 ir_tarval *tv_true = get_Const_tarval(mux_true);
3605 ir_tarval *tv_false = get_Const_tarval(mux_false);
3606 setcc_transform_t res;
3609 find_const_transform(cc, tv_true, tv_false, &res);
3611 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3614 switch (res.steps[step].transform) {
3616 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3617 add_ia32_am_offs_int(new_node, res.steps[step].val);
3619 case SETCC_TR_ADDxx:
3620 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3623 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3624 set_ia32_am_scale(new_node, res.steps[step].scale);
3625 set_ia32_am_offs_int(new_node, res.steps[step].val);
3627 case SETCC_TR_LEAxx:
3628 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3629 set_ia32_am_scale(new_node, res.steps[step].scale);
3630 set_ia32_am_offs_int(new_node, res.steps[step].val);
3633 imm = ia32_immediate_from_long(res.steps[step].scale);
3634 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3637 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3640 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3643 imm = ia32_immediate_from_long(res.steps[step].val);
3644 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3647 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3650 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3653 panic("unknown setcc transform");
3657 new_node = create_CMov(node, sel, flags, cc);
3665 * Create a conversion from x87 state register to general purpose.
3667 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3669 ir_node *block = be_transform_node(get_nodes_block(node));
3670 ir_node *op = get_Conv_op(node);
3671 ir_node *new_op = be_transform_node(op);
3672 ir_graph *irg = current_ir_graph;
3673 dbg_info *dbgi = get_irn_dbg_info(node);
3674 ir_mode *mode = get_irn_mode(node);
3675 ir_node *fist, *load, *mem;
3677 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3678 set_irn_pinned(fist, op_pin_state_floats);
3679 set_ia32_use_frame(fist);
3680 set_ia32_op_type(fist, ia32_AddrModeD);
3682 assert(get_mode_size_bits(mode) <= 32);
3683 /* exception we can only store signed 32 bit integers, so for unsigned
3684 we store a 64bit (signed) integer and load the lower bits */
3685 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3686 set_ia32_ls_mode(fist, mode_Ls);
3688 set_ia32_ls_mode(fist, mode_Is);
3690 SET_IA32_ORIG_NODE(fist, node);
3693 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3695 set_irn_pinned(load, op_pin_state_floats);
3696 set_ia32_use_frame(load);
3697 set_ia32_op_type(load, ia32_AddrModeS);
3698 set_ia32_ls_mode(load, mode_Is);
3699 if (get_ia32_ls_mode(fist) == mode_Ls) {
3700 ia32_attr_t *attr = get_ia32_attr(load);
3701 attr->data.need_64bit_stackent = 1;
3703 ia32_attr_t *attr = get_ia32_attr(load);
3704 attr->data.need_32bit_stackent = 1;
3706 SET_IA32_ORIG_NODE(load, node);
3708 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3712 * Creates a x87 strict Conv by placing a Store and a Load
3714 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3716 ir_node *block = get_nodes_block(node);
3717 ir_graph *irg = get_Block_irg(block);
3718 dbg_info *dbgi = get_irn_dbg_info(node);
3719 ir_node *frame = get_irg_frame(irg);
3720 ir_node *store, *load;
3723 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3724 set_ia32_use_frame(store);
3725 set_ia32_op_type(store, ia32_AddrModeD);
3726 SET_IA32_ORIG_NODE(store, node);
3728 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3729 set_ia32_use_frame(load);
3730 set_ia32_op_type(load, ia32_AddrModeS);
3731 SET_IA32_ORIG_NODE(load, node);
3733 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3737 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3738 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3740 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3742 func = get_mode_size_bits(mode) == 8 ?
3743 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3744 return func(dbgi, block, base, index, mem, val, mode);
3748 * Create a conversion from general purpose to x87 register
3750 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3752 ir_node *src_block = get_nodes_block(node);
3753 ir_node *block = be_transform_node(src_block);
3754 ir_graph *irg = get_Block_irg(block);
3755 dbg_info *dbgi = get_irn_dbg_info(node);
3756 ir_node *op = get_Conv_op(node);
3757 ir_node *new_op = NULL;
3759 ir_mode *store_mode;
3764 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3765 if (possible_int_mode_for_fp(src_mode)) {
3766 ia32_address_mode_t am;
3768 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3769 if (am.op_type == ia32_AddrModeS) {
3770 ia32_address_t *addr = &am.addr;
3772 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3773 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3775 set_am_attributes(fild, &am);
3776 SET_IA32_ORIG_NODE(fild, node);
3778 fix_mem_proj(fild, &am);
3783 if (new_op == NULL) {
3784 new_op = be_transform_node(op);
3787 mode = get_irn_mode(op);
3789 /* first convert to 32 bit signed if necessary */
3790 if (get_mode_size_bits(src_mode) < 32) {
3791 if (!upper_bits_clean(new_op, src_mode)) {
3792 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3793 SET_IA32_ORIG_NODE(new_op, node);
3798 assert(get_mode_size_bits(mode) == 32);
3801 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3803 set_ia32_use_frame(store);
3804 set_ia32_op_type(store, ia32_AddrModeD);
3805 set_ia32_ls_mode(store, mode_Iu);
3807 /* exception for 32bit unsigned, do a 64bit spill+load */
3808 if (!mode_is_signed(mode)) {
3811 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3813 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3814 noreg_GP, nomem, zero_const);
3816 set_ia32_use_frame(zero_store);
3817 set_ia32_op_type(zero_store, ia32_AddrModeD);
3818 add_ia32_am_offs_int(zero_store, 4);
3819 set_ia32_ls_mode(zero_store, mode_Iu);
3824 store = new_rd_Sync(dbgi, block, 2, in);
3825 store_mode = mode_Ls;
3827 store_mode = mode_Is;
3831 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3833 set_ia32_use_frame(fild);
3834 set_ia32_op_type(fild, ia32_AddrModeS);
3835 set_ia32_ls_mode(fild, store_mode);
3837 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3843 * Create a conversion from one integer mode into another one
3845 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3846 dbg_info *dbgi, ir_node *block, ir_node *op,
3849 ir_node *new_block = be_transform_node(block);
3851 ir_mode *smaller_mode;
3852 ia32_address_mode_t am;
3853 ia32_address_t *addr = &am.addr;
3856 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3857 smaller_mode = src_mode;
3859 smaller_mode = tgt_mode;
3862 #ifdef DEBUG_libfirm
3864 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3869 match_arguments(&am, block, NULL, op, NULL,
3870 match_am | match_8bit_am | match_16bit_am);
3872 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3873 /* unnecessary conv. in theory it shouldn't have been AM */
3874 assert(is_ia32_NoReg_GP(addr->base));
3875 assert(is_ia32_NoReg_GP(addr->index));
3876 assert(is_NoMem(addr->mem));
3877 assert(am.addr.offset == 0);
3878 assert(am.addr.symconst_ent == NULL);
3882 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3883 addr->mem, am.new_op2, smaller_mode);
3884 set_am_attributes(new_node, &am);
3885 /* match_arguments assume that out-mode = in-mode, this isn't true here
3887 set_ia32_ls_mode(new_node, smaller_mode);
3888 SET_IA32_ORIG_NODE(new_node, node);
3889 new_node = fix_mem_proj(new_node, &am);
3894 * Transforms a Conv node.
3896 * @return The created ia32 Conv node
3898 static ir_node *gen_Conv(ir_node *node)
3900 ir_node *block = get_nodes_block(node);
3901 ir_node *new_block = be_transform_node(block);
3902 ir_node *op = get_Conv_op(node);
3903 ir_node *new_op = NULL;
3904 dbg_info *dbgi = get_irn_dbg_info(node);
3905 ir_mode *src_mode = get_irn_mode(op);
3906 ir_mode *tgt_mode = get_irn_mode(node);
3907 int src_bits = get_mode_size_bits(src_mode);
3908 int tgt_bits = get_mode_size_bits(tgt_mode);
3909 ir_node *res = NULL;
3911 assert(!mode_is_int(src_mode) || src_bits <= 32);
3912 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3914 /* modeB -> X should already be lowered by the lower_mode_b pass */
3915 if (src_mode == mode_b) {
3916 panic("ConvB not lowered %+F", node);
3919 if (src_mode == tgt_mode) {
3920 if (get_Conv_strict(node)) {
3921 if (ia32_cg_config.use_sse2) {
3922 /* when we are in SSE mode, we can kill all strict no-op conversion */
3923 return be_transform_node(op);
3926 /* this should be optimized already, but who knows... */
3927 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3928 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3929 return be_transform_node(op);
3933 if (mode_is_float(src_mode)) {
3934 new_op = be_transform_node(op);
3935 /* we convert from float ... */
3936 if (mode_is_float(tgt_mode)) {
3938 if (ia32_cg_config.use_sse2) {
3939 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3940 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3942 set_ia32_ls_mode(res, tgt_mode);
3944 if (get_Conv_strict(node)) {
3945 /* if fp_no_float_fold is not set then we assume that we
3946 * don't have any float operations in a non
3947 * mode_float_arithmetic mode and can skip strict upconvs */
3948 if (src_bits < tgt_bits) {
3949 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3952 res = gen_x87_strict_conv(tgt_mode, new_op);
3953 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3957 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3962 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3963 if (ia32_cg_config.use_sse2) {
3964 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3966 set_ia32_ls_mode(res, src_mode);
3968 return gen_x87_fp_to_gp(node);
3972 /* we convert from int ... */
3973 if (mode_is_float(tgt_mode)) {
3975 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3976 if (ia32_cg_config.use_sse2) {
3977 new_op = be_transform_node(op);
3978 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3980 set_ia32_ls_mode(res, tgt_mode);
3982 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3983 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3984 res = gen_x87_gp_to_fp(node, src_mode);
3986 /* we need a strict-Conv, if the int mode has more bits than the
3988 if (float_mantissa < int_mantissa) {
3989 res = gen_x87_strict_conv(tgt_mode, res);
3990 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3994 } else if (tgt_mode == mode_b) {
3995 /* mode_b lowering already took care that we only have 0/1 values */
3996 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3997 src_mode, tgt_mode));
3998 return be_transform_node(op);
4001 if (src_bits == tgt_bits) {
4002 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
4003 src_mode, tgt_mode));
4004 return be_transform_node(op);
4007 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
4015 static ir_node *create_immediate_or_transform(ir_node *node,
4016 char immediate_constraint_type)
4018 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
4019 if (new_node == NULL) {
4020 new_node = be_transform_node(node);
4026 * Transforms a FrameAddr into an ia32 Add.
4028 static ir_node *gen_be_FrameAddr(ir_node *node)
4030 ir_node *block = be_transform_node(get_nodes_block(node));
4031 ir_node *op = be_get_FrameAddr_frame(node);
4032 ir_node *new_op = be_transform_node(op);
4033 dbg_info *dbgi = get_irn_dbg_info(node);
4036 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
4037 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
4038 set_ia32_use_frame(new_node);
4040 SET_IA32_ORIG_NODE(new_node, node);
4046 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4048 static ir_node *gen_be_Return(ir_node *node)
4050 ir_graph *irg = current_ir_graph;
4051 ir_node *ret_val = get_irn_n(node, n_be_Return_val);
4052 ir_node *ret_mem = get_irn_n(node, n_be_Return_mem);
4053 ir_node *new_ret_val = be_transform_node(ret_val);
4054 ir_node *new_ret_mem = be_transform_node(ret_mem);
4055 ir_entity *ent = get_irg_entity(irg);
4056 ir_type *tp = get_entity_type(ent);
4057 dbg_info *dbgi = get_irn_dbg_info(node);
4058 ir_node *block = be_transform_node(get_nodes_block(node));
4061 ir_node *frame, *sse_store, *fld, *mproj;
4068 assert(ret_val != NULL);
4069 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4070 return be_duplicate_node(node);
4073 res_type = get_method_res_type(tp, 0);
4075 if (! is_Primitive_type(res_type)) {
4076 return be_duplicate_node(node);
4079 mode = get_type_mode(res_type);
4080 if (! mode_is_float(mode)) {
4081 return be_duplicate_node(node);
4084 assert(get_method_n_ress(tp) == 1);
4086 frame = get_irg_frame(irg);
4088 /* store xmm0 onto stack */
4089 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
4090 new_ret_mem, new_ret_val);
4091 set_ia32_ls_mode(sse_store, mode);
4092 set_ia32_op_type(sse_store, ia32_AddrModeD);
4093 set_ia32_use_frame(sse_store);
4095 /* load into x87 register */
4096 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4097 set_ia32_op_type(fld, ia32_AddrModeS);
4098 set_ia32_use_frame(fld);
4100 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4101 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4103 /* create a new return */
4104 arity = get_irn_arity(node);
4105 in = ALLOCAN(ir_node*, arity);
4106 pop = be_Return_get_pop(node);
4107 for (i = 0; i < arity; ++i) {
4108 ir_node *op = get_irn_n(node, i);
4109 if (op == ret_val) {
4111 } else if (op == ret_mem) {
4114 in[i] = be_transform_node(op);
4117 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4118 copy_node_attr(irg, node, new_node);
4124 * Transform a be_AddSP into an ia32_SubSP.
4126 static ir_node *gen_be_AddSP(ir_node *node)
4128 ir_node *sz = get_irn_n(node, n_be_AddSP_size);
4129 ir_node *sp = get_irn_n(node, n_be_AddSP_old_sp);
4131 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4132 match_am | match_immediate);
4133 assert(is_ia32_SubSP(new_node));
4134 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4135 &ia32_registers[REG_ESP]);
4140 * Transform a be_SubSP into an ia32_AddSP
4142 static ir_node *gen_be_SubSP(ir_node *node)
4144 ir_node *sz = get_irn_n(node, n_be_SubSP_size);
4145 ir_node *sp = get_irn_n(node, n_be_SubSP_old_sp);
4147 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4148 match_am | match_immediate);
4149 assert(is_ia32_AddSP(new_node));
4150 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4151 &ia32_registers[REG_ESP]);
4156 * Change some phi modes
4158 static ir_node *gen_Phi(ir_node *node)
4160 const arch_register_req_t *req;
4161 ir_node *block = be_transform_node(get_nodes_block(node));
4162 ir_graph *irg = current_ir_graph;
4163 dbg_info *dbgi = get_irn_dbg_info(node);
4164 ir_mode *mode = get_irn_mode(node);
4167 if (ia32_mode_needs_gp_reg(mode)) {
4168 /* we shouldn't have any 64bit stuff around anymore */
4169 assert(get_mode_size_bits(mode) <= 32);
4170 /* all integer operations are on 32bit registers now */
4172 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4173 } else if (mode_is_float(mode)) {
4174 if (ia32_cg_config.use_sse2) {
4176 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4179 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4182 req = arch_no_register_req;
4185 /* phi nodes allow loops, so we use the old arguments for now
4186 * and fix this later */
4187 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4188 get_irn_in(node) + 1);
4189 copy_node_attr(irg, node, phi);
4190 be_duplicate_deps(node, phi);
4192 arch_set_out_register_req(phi, 0, req);
4194 be_enqueue_preds(node);
4199 static ir_node *gen_Jmp(ir_node *node)
4201 ir_node *block = get_nodes_block(node);
4202 ir_node *new_block = be_transform_node(block);
4203 dbg_info *dbgi = get_irn_dbg_info(node);
4206 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4207 SET_IA32_ORIG_NODE(new_node, node);
4215 static ir_node *gen_IJmp(ir_node *node)
4217 ir_node *block = get_nodes_block(node);
4218 ir_node *new_block = be_transform_node(block);
4219 dbg_info *dbgi = get_irn_dbg_info(node);
4220 ir_node *op = get_IJmp_target(node);
4222 ia32_address_mode_t am;
4223 ia32_address_t *addr = &am.addr;
4225 assert(get_irn_mode(op) == mode_P);
4227 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4229 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4230 addr->mem, am.new_op2);
4231 set_am_attributes(new_node, &am);
4232 SET_IA32_ORIG_NODE(new_node, node);
4234 new_node = fix_mem_proj(new_node, &am);
4239 static ir_node *gen_ia32_l_Add(ir_node *node)
4241 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4242 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4243 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4244 match_commutative | match_am | match_immediate |
4245 match_mode_neutral);
4247 if (is_Proj(lowered)) {
4248 lowered = get_Proj_pred(lowered);
4250 assert(is_ia32_Add(lowered));
4251 set_irn_mode(lowered, mode_T);
4257 static ir_node *gen_ia32_l_Adc(ir_node *node)
4259 return gen_binop_flags(node, new_bd_ia32_Adc,
4260 match_commutative | match_am | match_immediate |
4261 match_mode_neutral);
4265 * Transforms a l_MulS into a "real" MulS node.
4267 * @return the created ia32 Mul node
4269 static ir_node *gen_ia32_l_Mul(ir_node *node)
4271 ir_node *left = get_binop_left(node);
4272 ir_node *right = get_binop_right(node);
4274 return gen_binop(node, left, right, new_bd_ia32_Mul,
4275 match_commutative | match_am | match_mode_neutral);
4279 * Transforms a l_IMulS into a "real" IMul1OPS node.
4281 * @return the created ia32 IMul1OP node
4283 static ir_node *gen_ia32_l_IMul(ir_node *node)
4285 ir_node *left = get_binop_left(node);
4286 ir_node *right = get_binop_right(node);
4288 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4289 match_commutative | match_am | match_mode_neutral);
4292 static ir_node *gen_ia32_l_Sub(ir_node *node)
4294 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4295 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4296 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4297 match_am | match_immediate | match_mode_neutral);
4299 if (is_Proj(lowered)) {
4300 lowered = get_Proj_pred(lowered);
4302 assert(is_ia32_Sub(lowered));
4303 set_irn_mode(lowered, mode_T);
4309 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4311 return gen_binop_flags(node, new_bd_ia32_Sbb,
4312 match_am | match_immediate | match_mode_neutral);
4315 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4317 ir_node *src_block = get_nodes_block(node);
4318 ir_node *block = be_transform_node(src_block);
4319 ir_graph *irg = current_ir_graph;
4320 dbg_info *dbgi = get_irn_dbg_info(node);
4321 ir_node *frame = get_irg_frame(irg);
4322 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4323 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4324 ir_node *new_val_low = be_transform_node(val_low);
4325 ir_node *new_val_high = be_transform_node(val_high);
4327 ir_node *sync, *fild, *res;
4328 ir_node *store_low, *store_high;
4330 if (ia32_cg_config.use_sse2) {
4331 panic("ia32_l_LLtoFloat not implemented for SSE2");
4335 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4337 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4339 SET_IA32_ORIG_NODE(store_low, node);
4340 SET_IA32_ORIG_NODE(store_high, node);
4342 set_ia32_use_frame(store_low);
4343 set_ia32_use_frame(store_high);
4344 set_ia32_op_type(store_low, ia32_AddrModeD);
4345 set_ia32_op_type(store_high, ia32_AddrModeD);
4346 set_ia32_ls_mode(store_low, mode_Iu);
4347 set_ia32_ls_mode(store_high, mode_Is);
4348 add_ia32_am_offs_int(store_high, 4);
4352 sync = new_rd_Sync(dbgi, block, 2, in);
4355 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4357 set_ia32_use_frame(fild);
4358 set_ia32_op_type(fild, ia32_AddrModeS);
4359 set_ia32_ls_mode(fild, mode_Ls);
4361 SET_IA32_ORIG_NODE(fild, node);
4363 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4365 if (! mode_is_signed(get_irn_mode(val_high))) {
4366 ia32_address_mode_t am;
4368 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4371 am.addr.base = get_symconst_base();
4372 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4373 am.addr.mem = nomem;
4376 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4377 am.addr.tls_segment = false;
4378 am.addr.use_frame = 0;
4379 am.addr.frame_entity = NULL;
4380 am.addr.symconst_sign = 0;
4381 am.ls_mode = mode_F;
4382 am.mem_proj = nomem;
4383 am.op_type = ia32_AddrModeS;
4385 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4386 am.pinned = op_pin_state_floats;
4388 am.ins_permuted = false;
4390 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4391 am.new_op1, am.new_op2, get_fpcw());
4392 set_am_attributes(fadd, &am);
4394 set_irn_mode(fadd, mode_T);
4395 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4400 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4402 ir_node *src_block = get_nodes_block(node);
4403 ir_node *block = be_transform_node(src_block);
4404 ir_graph *irg = get_Block_irg(block);
4405 dbg_info *dbgi = get_irn_dbg_info(node);
4406 ir_node *frame = get_irg_frame(irg);
4407 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4408 ir_node *new_val = be_transform_node(val);
4409 ir_node *fist, *mem;
4411 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4412 SET_IA32_ORIG_NODE(fist, node);
4413 set_ia32_use_frame(fist);
4414 set_ia32_op_type(fist, ia32_AddrModeD);
4415 set_ia32_ls_mode(fist, mode_Ls);
4420 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4422 ir_node *block = be_transform_node(get_nodes_block(node));
4423 ir_graph *irg = get_Block_irg(block);
4424 ir_node *pred = get_Proj_pred(node);
4425 ir_node *new_pred = be_transform_node(pred);
4426 ir_node *frame = get_irg_frame(irg);
4427 dbg_info *dbgi = get_irn_dbg_info(node);
4428 long pn = get_Proj_proj(node);
4433 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4434 SET_IA32_ORIG_NODE(load, node);
4435 set_ia32_use_frame(load);
4436 set_ia32_op_type(load, ia32_AddrModeS);
4437 set_ia32_ls_mode(load, mode_Iu);
4438 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4439 * 32 bit from it with this particular load */
4440 attr = get_ia32_attr(load);
4441 attr->data.need_64bit_stackent = 1;
4443 if (pn == pn_ia32_l_FloattoLL_res_high) {
4444 add_ia32_am_offs_int(load, 4);
4446 assert(pn == pn_ia32_l_FloattoLL_res_low);
4449 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4455 * Transform the Projs of an AddSP.
4457 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4459 ir_node *pred = get_Proj_pred(node);
4460 ir_node *new_pred = be_transform_node(pred);
4461 dbg_info *dbgi = get_irn_dbg_info(node);
4462 long proj = get_Proj_proj(node);
4464 if (proj == pn_be_AddSP_sp) {
4465 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4466 pn_ia32_SubSP_stack);
4467 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4469 } else if (proj == pn_be_AddSP_res) {
4470 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4471 pn_ia32_SubSP_addr);
4472 } else if (proj == pn_be_AddSP_M) {
4473 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4476 panic("No idea how to transform proj->AddSP");
4480 * Transform the Projs of a SubSP.
4482 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4484 ir_node *pred = get_Proj_pred(node);
4485 ir_node *new_pred = be_transform_node(pred);
4486 dbg_info *dbgi = get_irn_dbg_info(node);
4487 long proj = get_Proj_proj(node);
4489 if (proj == pn_be_SubSP_sp) {
4490 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4491 pn_ia32_AddSP_stack);
4492 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4494 } else if (proj == pn_be_SubSP_M) {
4495 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4498 panic("No idea how to transform proj->SubSP");
4502 * Transform and renumber the Projs from a Load.
4504 static ir_node *gen_Proj_Load(ir_node *node)
4507 ir_node *pred = get_Proj_pred(node);
4508 dbg_info *dbgi = get_irn_dbg_info(node);
4509 long proj = get_Proj_proj(node);
4511 /* loads might be part of source address mode matches, so we don't
4512 * transform the ProjMs yet (with the exception of loads whose result is
4515 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4518 /* this is needed, because sometimes we have loops that are only
4519 reachable through the ProjM */
4520 be_enqueue_preds(node);
4521 /* do it in 2 steps, to silence firm verifier */
4522 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4523 set_Proj_proj(res, pn_ia32_mem);
4527 /* renumber the proj */
4528 new_pred = be_transform_node(pred);
4529 if (is_ia32_Load(new_pred)) {
4530 switch ((pn_Load)proj) {
4532 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4534 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4535 case pn_Load_X_except:
4536 /* This Load might raise an exception. Mark it. */
4537 set_ia32_exc_label(new_pred, 1);
4538 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_except);
4539 case pn_Load_X_regular:
4540 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_regular);
4542 } else if (is_ia32_Conv_I2I(new_pred) ||
4543 is_ia32_Conv_I2I8Bit(new_pred)) {
4544 set_irn_mode(new_pred, mode_T);
4545 if (proj == pn_Load_res) {
4546 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4547 } else if (proj == pn_Load_M) {
4548 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4550 } else if (is_ia32_xLoad(new_pred)) {
4551 switch ((pn_Load)proj) {
4553 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4555 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4556 case pn_Load_X_except:
4557 /* This Load might raise an exception. Mark it. */
4558 set_ia32_exc_label(new_pred, 1);
4559 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_except);
4560 case pn_Load_X_regular:
4561 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_regular);
4563 } else if (is_ia32_vfld(new_pred)) {
4564 switch ((pn_Load)proj) {
4566 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4568 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4569 case pn_Load_X_except:
4570 /* This Load might raise an exception. Mark it. */
4571 set_ia32_exc_label(new_pred, 1);
4572 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_except);
4573 case pn_Load_X_regular:
4574 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_regular);
4577 /* can happen for ProJMs when source address mode happened for the
4580 /* however it should not be the result proj, as that would mean the
4581 load had multiple users and should not have been used for
4583 if (proj != pn_Load_M) {
4584 panic("internal error: transformed node not a Load");
4586 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4589 panic("No idea how to transform proj");
4593 * Transform and renumber the Projs from a Div or Mod instruction.
4595 static ir_node *gen_Proj_Div(ir_node *node)
4597 ir_node *pred = get_Proj_pred(node);
4598 ir_node *new_pred = be_transform_node(pred);
4599 dbg_info *dbgi = get_irn_dbg_info(node);
4600 long proj = get_Proj_proj(node);
4602 assert((long)pn_ia32_Div_M == (long)pn_ia32_IDiv_M);
4603 assert((long)pn_ia32_Div_div_res == (long)pn_ia32_IDiv_div_res);
4605 switch ((pn_Div)proj) {
4607 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4608 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4609 } else if (is_ia32_xDiv(new_pred)) {
4610 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4611 } else if (is_ia32_vfdiv(new_pred)) {
4612 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4614 panic("Div transformed to unexpected thing %+F", new_pred);
4617 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4618 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4619 } else if (is_ia32_xDiv(new_pred)) {
4620 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4621 } else if (is_ia32_vfdiv(new_pred)) {
4622 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4624 panic("Div transformed to unexpected thing %+F", new_pred);
4626 case pn_Div_X_except:
4627 set_ia32_exc_label(new_pred, 1);
4628 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_except);
4629 case pn_Div_X_regular:
4630 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_regular);
4633 panic("No idea how to transform proj->Div");
4637 * Transform and renumber the Projs from a Div or Mod instruction.
4639 static ir_node *gen_Proj_Mod(ir_node *node)
4641 ir_node *pred = get_Proj_pred(node);
4642 ir_node *new_pred = be_transform_node(pred);
4643 dbg_info *dbgi = get_irn_dbg_info(node);
4644 long proj = get_Proj_proj(node);
4646 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4647 assert((long)pn_ia32_Div_M == (long)pn_ia32_IDiv_M);
4648 assert((long)pn_ia32_Div_mod_res == (long)pn_ia32_IDiv_mod_res);
4650 switch ((pn_Mod)proj) {
4652 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4654 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4655 case pn_Mod_X_except:
4656 set_ia32_exc_label(new_pred, 1);
4657 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_except);
4658 case pn_Mod_X_regular:
4659 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_regular);
4661 panic("No idea how to transform proj->Mod");
4665 * Transform and renumber the Projs from a CopyB.
4667 static ir_node *gen_Proj_CopyB(ir_node *node)
4669 ir_node *pred = get_Proj_pred(node);
4670 ir_node *new_pred = be_transform_node(pred);
4671 dbg_info *dbgi = get_irn_dbg_info(node);
4672 long proj = get_Proj_proj(node);
4676 if (is_ia32_CopyB_i(new_pred)) {
4677 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4678 } else if (is_ia32_CopyB(new_pred)) {
4679 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4686 panic("No idea how to transform proj->CopyB");
4689 static ir_node *gen_be_Call(ir_node *node)
4691 dbg_info *const dbgi = get_irn_dbg_info(node);
4692 ir_node *const src_block = get_nodes_block(node);
4693 ir_node *const block = be_transform_node(src_block);
4694 ir_node *const src_mem = get_irn_n(node, n_be_Call_mem);
4695 ir_node *const src_sp = get_irn_n(node, n_be_Call_sp);
4696 ir_node *const sp = be_transform_node(src_sp);
4697 ir_node *const src_ptr = get_irn_n(node, n_be_Call_ptr);
4698 ia32_address_mode_t am;
4699 ia32_address_t *const addr = &am.addr;
4704 ir_node * eax = noreg_GP;
4705 ir_node * ecx = noreg_GP;
4706 ir_node * edx = noreg_GP;
4707 unsigned const pop = be_Call_get_pop(node);
4708 ir_type *const call_tp = be_Call_get_type(node);
4709 int old_no_pic_adjust;
4711 /* Run the x87 simulator if the call returns a float value */
4712 if (get_method_n_ress(call_tp) > 0) {
4713 ir_type *const res_type = get_method_res_type(call_tp, 0);
4714 ir_mode *const res_mode = get_type_mode(res_type);
4716 if (res_mode != NULL && mode_is_float(res_mode)) {
4717 ir_graph *irg = current_ir_graph;
4718 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4719 irg_data->do_x87_sim = 1;
4723 /* We do not want be_Call direct calls */
4724 assert(be_Call_get_entity(node) == NULL);
4726 /* special case for PIC trampoline calls */
4727 old_no_pic_adjust = ia32_no_pic_adjust;
4728 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4730 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4731 match_am | match_immediate);
4733 ia32_no_pic_adjust = old_no_pic_adjust;
4735 i = get_irn_arity(node) - 1;
4736 fpcw = be_transform_node(get_irn_n(node, i--));
4737 for (; i >= n_be_Call_first_arg; --i) {
4738 arch_register_req_t const *const req = arch_get_register_req(node, i);
4739 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4741 assert(req->type == arch_register_req_type_limited);
4742 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4744 switch (*req->limited) {
4745 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4746 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4747 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4748 default: panic("Invalid GP register for register parameter");
4752 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4753 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4754 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4755 set_am_attributes(call, &am);
4756 call = fix_mem_proj(call, &am);
4758 if (get_irn_pinned(node) == op_pin_state_pinned)
4759 set_irn_pinned(call, op_pin_state_pinned);
4761 SET_IA32_ORIG_NODE(call, node);
4763 if (ia32_cg_config.use_sse2) {
4764 /* remember this call for post-processing */
4765 ARR_APP1(ir_node *, call_list, call);
4766 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4773 * Transform Builtin trap
4775 static ir_node *gen_trap(ir_node *node)
4777 dbg_info *dbgi = get_irn_dbg_info(node);
4778 ir_node *block = be_transform_node(get_nodes_block(node));
4779 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4781 return new_bd_ia32_UD2(dbgi, block, mem);
4785 * Transform Builtin debugbreak
4787 static ir_node *gen_debugbreak(ir_node *node)
4789 dbg_info *dbgi = get_irn_dbg_info(node);
4790 ir_node *block = be_transform_node(get_nodes_block(node));
4791 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4793 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4797 * Transform Builtin return_address
4799 static ir_node *gen_return_address(ir_node *node)
4801 ir_node *param = get_Builtin_param(node, 0);
4802 ir_node *frame = get_Builtin_param(node, 1);
4803 dbg_info *dbgi = get_irn_dbg_info(node);
4804 ir_tarval *tv = get_Const_tarval(param);
4805 ir_graph *irg = get_irn_irg(node);
4806 unsigned long value = get_tarval_long(tv);
4808 ir_node *block = be_transform_node(get_nodes_block(node));
4809 ir_node *ptr = be_transform_node(frame);
4813 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4814 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4815 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4818 /* load the return address from this frame */
4819 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4821 set_irn_pinned(load, get_irn_pinned(node));
4822 set_ia32_op_type(load, ia32_AddrModeS);
4823 set_ia32_ls_mode(load, mode_Iu);
4825 set_ia32_am_offs_int(load, 0);
4826 set_ia32_use_frame(load);
4827 set_ia32_frame_ent(load, ia32_get_return_address_entity(irg));
4829 if (get_irn_pinned(node) == op_pin_state_floats) {
4830 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4831 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4832 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4833 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4836 SET_IA32_ORIG_NODE(load, node);
4837 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4841 * Transform Builtin frame_address
4843 static ir_node *gen_frame_address(ir_node *node)
4845 ir_node *param = get_Builtin_param(node, 0);
4846 ir_node *frame = get_Builtin_param(node, 1);
4847 dbg_info *dbgi = get_irn_dbg_info(node);
4848 ir_tarval *tv = get_Const_tarval(param);
4849 ir_graph *irg = get_irn_irg(node);
4850 unsigned long value = get_tarval_long(tv);
4852 ir_node *block = be_transform_node(get_nodes_block(node));
4853 ir_node *ptr = be_transform_node(frame);
4858 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4859 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4860 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4863 /* load the frame address from this frame */
4864 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4866 set_irn_pinned(load, get_irn_pinned(node));
4867 set_ia32_op_type(load, ia32_AddrModeS);
4868 set_ia32_ls_mode(load, mode_Iu);
4870 ent = ia32_get_frame_address_entity(irg);
4872 set_ia32_am_offs_int(load, 0);
4873 set_ia32_use_frame(load);
4874 set_ia32_frame_ent(load, ent);
4876 /* will fail anyway, but gcc does this: */
4877 set_ia32_am_offs_int(load, 0);
4880 if (get_irn_pinned(node) == op_pin_state_floats) {
4881 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4882 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4883 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4884 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4887 SET_IA32_ORIG_NODE(load, node);
4888 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4892 * Transform Builtin frame_address
4894 static ir_node *gen_prefetch(ir_node *node)
4897 ir_node *ptr, *block, *mem, *base, *index;
4898 ir_node *param, *new_node;
4901 ia32_address_t addr;
4903 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4904 /* no prefetch at all, route memory */
4905 return be_transform_node(get_Builtin_mem(node));
4908 param = get_Builtin_param(node, 1);
4909 tv = get_Const_tarval(param);
4910 rw = get_tarval_long(tv);
4912 /* construct load address */
4913 memset(&addr, 0, sizeof(addr));
4914 ptr = get_Builtin_param(node, 0);
4915 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4922 base = be_transform_node(base);
4925 if (index == NULL) {
4928 index = be_transform_node(index);
4931 dbgi = get_irn_dbg_info(node);
4932 block = be_transform_node(get_nodes_block(node));
4933 mem = be_transform_node(get_Builtin_mem(node));
4935 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4936 /* we have 3DNow!, this was already checked above */
4937 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4938 } else if (ia32_cg_config.use_sse_prefetch) {
4939 /* note: rw == 1 is IGNORED in that case */
4940 param = get_Builtin_param(node, 2);
4941 tv = get_Const_tarval(param);
4942 locality = get_tarval_long(tv);
4944 /* SSE style prefetch */
4947 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4950 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4953 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4956 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4960 assert(ia32_cg_config.use_3dnow_prefetch);
4961 /* 3DNow! style prefetch */
4962 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4965 set_irn_pinned(new_node, get_irn_pinned(node));
4966 set_ia32_op_type(new_node, ia32_AddrModeS);
4967 set_ia32_ls_mode(new_node, mode_Bu);
4968 set_address(new_node, &addr);
4970 SET_IA32_ORIG_NODE(new_node, node);
4972 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4976 * Transform bsf like node
4978 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4980 ir_node *param = get_Builtin_param(node, 0);
4981 dbg_info *dbgi = get_irn_dbg_info(node);
4983 ir_node *block = get_nodes_block(node);
4984 ir_node *new_block = be_transform_node(block);
4986 ia32_address_mode_t am;
4987 ia32_address_t *addr = &am.addr;
4990 match_arguments(&am, block, NULL, param, NULL, match_am);
4992 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4993 set_am_attributes(cnt, &am);
4994 set_ia32_ls_mode(cnt, get_irn_mode(param));
4996 SET_IA32_ORIG_NODE(cnt, node);
4997 return fix_mem_proj(cnt, &am);
5001 * Transform builtin ffs.
5003 static ir_node *gen_ffs(ir_node *node)
5005 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5006 ir_node *real = skip_Proj(bsf);
5007 dbg_info *dbgi = get_irn_dbg_info(real);
5008 ir_node *block = get_nodes_block(real);
5009 ir_node *flag, *set, *conv, *neg, *orn, *add;
5012 if (get_irn_mode(real) != mode_T) {
5013 set_irn_mode(real, mode_T);
5014 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5017 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5020 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5021 SET_IA32_ORIG_NODE(set, node);
5024 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5025 SET_IA32_ORIG_NODE(conv, node);
5028 neg = new_bd_ia32_Neg(dbgi, block, conv);
5031 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5032 set_ia32_commutative(orn);
5035 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5036 add_ia32_am_offs_int(add, 1);
5041 * Transform builtin clz.
5043 static ir_node *gen_clz(ir_node *node)
5045 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5046 ir_node *real = skip_Proj(bsr);
5047 dbg_info *dbgi = get_irn_dbg_info(real);
5048 ir_node *block = get_nodes_block(real);
5049 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5051 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5055 * Transform builtin ctz.
5057 static ir_node *gen_ctz(ir_node *node)
5059 return gen_unop_AM(node, new_bd_ia32_Bsf);
5063 * Transform builtin parity.
5065 static ir_node *gen_parity(ir_node *node)
5067 dbg_info *dbgi = get_irn_dbg_info(node);
5068 ir_node *block = get_nodes_block(node);
5069 ir_node *new_block = be_transform_node(block);
5070 ir_node *param = get_Builtin_param(node, 0);
5071 ir_node *new_param = be_transform_node(param);
5074 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5075 * so we have to do complicated xoring first.
5076 * (we should also better lower this before the backend so we still have a
5077 * chance for CSE, constant folding and other goodies for some of these
5080 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5081 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5082 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5084 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5087 set_irn_mode(xor2, mode_T);
5088 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5091 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5092 SET_IA32_ORIG_NODE(new_node, node);
5095 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5096 nomem, new_node, mode_Bu);
5097 SET_IA32_ORIG_NODE(new_node, node);
5102 * Transform builtin popcount
5104 static ir_node *gen_popcount(ir_node *node)
5106 ir_node *param = get_Builtin_param(node, 0);
5107 dbg_info *dbgi = get_irn_dbg_info(node);
5109 ir_node *block = get_nodes_block(node);
5110 ir_node *new_block = be_transform_node(block);
5113 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5115 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5116 if (ia32_cg_config.use_popcnt) {
5117 ia32_address_mode_t am;
5118 ia32_address_t *addr = &am.addr;
5121 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5123 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5124 set_am_attributes(cnt, &am);
5125 set_ia32_ls_mode(cnt, get_irn_mode(param));
5127 SET_IA32_ORIG_NODE(cnt, node);
5128 return fix_mem_proj(cnt, &am);
5131 new_param = be_transform_node(param);
5133 /* do the standard popcount algo */
5134 /* TODO: This is stupid, we should transform this before the backend,
5135 * to get CSE, localopts, etc. for the operations
5136 * TODO: This is also not the optimal algorithm (it is just the starting
5137 * example in hackers delight, they optimize it more on the following page)
5138 * But I'm too lazy to fix this now, as the code should get lowered before
5139 * the backend anyway.
5142 /* m1 = x & 0x55555555 */
5143 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5144 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5147 simm = ia32_create_Immediate(NULL, 0, 1);
5148 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5150 /* m2 = s1 & 0x55555555 */
5151 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5154 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5156 /* m4 = m3 & 0x33333333 */
5157 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5158 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5161 simm = ia32_create_Immediate(NULL, 0, 2);
5162 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5164 /* m5 = s2 & 0x33333333 */
5165 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5168 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5170 /* m7 = m6 & 0x0F0F0F0F */
5171 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5172 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5175 simm = ia32_create_Immediate(NULL, 0, 4);
5176 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5178 /* m8 = s3 & 0x0F0F0F0F */
5179 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5182 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5184 /* m10 = m9 & 0x00FF00FF */
5185 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5186 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5189 simm = ia32_create_Immediate(NULL, 0, 8);
5190 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5192 /* m11 = s4 & 0x00FF00FF */
5193 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5195 /* m12 = m10 + m11 */
5196 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5198 /* m13 = m12 & 0x0000FFFF */
5199 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5200 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5202 /* s5 = m12 >> 16 */
5203 simm = ia32_create_Immediate(NULL, 0, 16);
5204 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5206 /* res = m13 + s5 */
5207 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5211 * Transform builtin byte swap.
5213 static ir_node *gen_bswap(ir_node *node)
5215 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5216 dbg_info *dbgi = get_irn_dbg_info(node);
5218 ir_node *block = get_nodes_block(node);
5219 ir_node *new_block = be_transform_node(block);
5220 ir_mode *mode = get_irn_mode(param);
5221 unsigned size = get_mode_size_bits(mode);
5222 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5226 if (ia32_cg_config.use_i486) {
5227 /* swap available */
5228 return new_bd_ia32_Bswap(dbgi, new_block, param);
5230 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5231 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5233 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5234 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5236 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5238 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5239 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5241 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5242 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5245 /* swap16 always available */
5246 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5249 panic("Invalid bswap size (%d)", size);
5254 * Transform builtin outport.
5256 static ir_node *gen_outport(ir_node *node)
5258 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5259 ir_node *oldv = get_Builtin_param(node, 1);
5260 ir_mode *mode = get_irn_mode(oldv);
5261 ir_node *value = be_transform_node(oldv);
5262 ir_node *block = be_transform_node(get_nodes_block(node));
5263 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5264 dbg_info *dbgi = get_irn_dbg_info(node);
5266 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5267 set_ia32_ls_mode(res, mode);
5272 * Transform builtin inport.
5274 static ir_node *gen_inport(ir_node *node)
5276 ir_type *tp = get_Builtin_type(node);
5277 ir_type *rstp = get_method_res_type(tp, 0);
5278 ir_mode *mode = get_type_mode(rstp);
5279 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5280 ir_node *block = be_transform_node(get_nodes_block(node));
5281 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5282 dbg_info *dbgi = get_irn_dbg_info(node);
5284 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5285 set_ia32_ls_mode(res, mode);
5287 /* check for missing Result Proj */
5292 * Transform a builtin inner trampoline
5294 static ir_node *gen_inner_trampoline(ir_node *node)
5296 ir_node *ptr = get_Builtin_param(node, 0);
5297 ir_node *callee = get_Builtin_param(node, 1);
5298 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5299 ir_node *mem = get_Builtin_mem(node);
5300 ir_node *block = get_nodes_block(node);
5301 ir_node *new_block = be_transform_node(block);
5305 ir_node *trampoline;
5307 dbg_info *dbgi = get_irn_dbg_info(node);
5308 ia32_address_t addr;
5310 /* construct store address */
5311 memset(&addr, 0, sizeof(addr));
5312 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5314 if (addr.base == NULL) {
5315 addr.base = noreg_GP;
5317 addr.base = be_transform_node(addr.base);
5320 if (addr.index == NULL) {
5321 addr.index = noreg_GP;
5323 addr.index = be_transform_node(addr.index);
5325 addr.mem = be_transform_node(mem);
5327 /* mov ecx, <env> */
5328 val = ia32_create_Immediate(NULL, 0, 0xB9);
5329 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5330 addr.index, addr.mem, val);
5331 set_irn_pinned(store, get_irn_pinned(node));
5332 set_ia32_op_type(store, ia32_AddrModeD);
5333 set_ia32_ls_mode(store, mode_Bu);
5334 set_address(store, &addr);
5338 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5339 addr.index, addr.mem, env);
5340 set_irn_pinned(store, get_irn_pinned(node));
5341 set_ia32_op_type(store, ia32_AddrModeD);
5342 set_ia32_ls_mode(store, mode_Iu);
5343 set_address(store, &addr);
5347 /* jmp rel <callee> */
5348 val = ia32_create_Immediate(NULL, 0, 0xE9);
5349 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5350 addr.index, addr.mem, val);
5351 set_irn_pinned(store, get_irn_pinned(node));
5352 set_ia32_op_type(store, ia32_AddrModeD);
5353 set_ia32_ls_mode(store, mode_Bu);
5354 set_address(store, &addr);
5358 trampoline = be_transform_node(ptr);
5360 /* the callee is typically an immediate */
5361 if (is_SymConst(callee)) {
5362 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5364 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5365 add_ia32_am_offs_int(rel, -10);
5367 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5369 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5370 addr.index, addr.mem, rel);
5371 set_irn_pinned(store, get_irn_pinned(node));
5372 set_ia32_op_type(store, ia32_AddrModeD);
5373 set_ia32_ls_mode(store, mode_Iu);
5374 set_address(store, &addr);
5379 return new_r_Tuple(new_block, 2, in);
5383 * Transform Builtin node.
5385 static ir_node *gen_Builtin(ir_node *node)
5387 ir_builtin_kind kind = get_Builtin_kind(node);
5391 return gen_trap(node);
5392 case ir_bk_debugbreak:
5393 return gen_debugbreak(node);
5394 case ir_bk_return_address:
5395 return gen_return_address(node);
5396 case ir_bk_frame_address:
5397 return gen_frame_address(node);
5398 case ir_bk_prefetch:
5399 return gen_prefetch(node);
5401 return gen_ffs(node);
5403 return gen_clz(node);
5405 return gen_ctz(node);
5407 return gen_parity(node);
5408 case ir_bk_popcount:
5409 return gen_popcount(node);
5411 return gen_bswap(node);
5413 return gen_outport(node);
5415 return gen_inport(node);
5416 case ir_bk_inner_trampoline:
5417 return gen_inner_trampoline(node);
5419 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5423 * Transform Proj(Builtin) node.
5425 static ir_node *gen_Proj_Builtin(ir_node *proj)
5427 ir_node *node = get_Proj_pred(proj);
5428 ir_node *new_node = be_transform_node(node);
5429 ir_builtin_kind kind = get_Builtin_kind(node);
5432 case ir_bk_return_address:
5433 case ir_bk_frame_address:
5438 case ir_bk_popcount:
5440 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5443 case ir_bk_debugbreak:
5444 case ir_bk_prefetch:
5446 assert(get_Proj_proj(proj) == pn_Builtin_M);
5449 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5450 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5452 assert(get_Proj_proj(proj) == pn_Builtin_M);
5453 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5455 case ir_bk_inner_trampoline:
5456 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5457 return get_Tuple_pred(new_node, 1);
5459 assert(get_Proj_proj(proj) == pn_Builtin_M);
5460 return get_Tuple_pred(new_node, 0);
5463 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5466 static ir_node *gen_be_IncSP(ir_node *node)
5468 ir_node *res = be_duplicate_node(node);
5469 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5475 * Transform the Projs from a be_Call.
5477 static ir_node *gen_Proj_be_Call(ir_node *node)
5479 ir_node *call = get_Proj_pred(node);
5480 ir_node *new_call = be_transform_node(call);
5481 dbg_info *dbgi = get_irn_dbg_info(node);
5482 long proj = get_Proj_proj(node);
5483 ir_mode *mode = get_irn_mode(node);
5486 if (proj == pn_be_Call_M_regular) {
5487 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5489 /* transform call modes */
5490 if (mode_is_data(mode)) {
5491 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5495 /* Map from be_Call to ia32_Call proj number */
5496 if (proj == pn_be_Call_sp) {
5497 proj = pn_ia32_Call_stack;
5498 } else if (proj == pn_be_Call_M_regular) {
5499 proj = pn_ia32_Call_M;
5501 arch_register_req_t const *const req = arch_get_register_req_out(node);
5502 int const n_outs = arch_irn_get_n_outs(new_call);
5505 assert(proj >= pn_be_Call_first_res);
5506 assert(req->type & arch_register_req_type_limited);
5508 for (i = 0; i < n_outs; ++i) {
5509 arch_register_req_t const *const new_req
5510 = arch_get_out_register_req(new_call, i);
5512 if (!(new_req->type & arch_register_req_type_limited) ||
5513 new_req->cls != req->cls ||
5514 *new_req->limited != *req->limited)
5523 res = new_rd_Proj(dbgi, new_call, mode, proj);
5525 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5527 case pn_ia32_Call_stack:
5528 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5531 case pn_ia32_Call_fpcw:
5532 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5540 * Transform the Projs from a Cmp.
5542 static ir_node *gen_Proj_Cmp(ir_node *node)
5544 /* this probably means not all mode_b nodes were lowered... */
5545 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5549 static ir_node *gen_Proj_ASM(ir_node *node)
5551 ir_mode *mode = get_irn_mode(node);
5552 ir_node *pred = get_Proj_pred(node);
5553 ir_node *new_pred = be_transform_node(pred);
5554 long pos = get_Proj_proj(node);
5556 if (mode == mode_M) {
5557 pos = arch_irn_get_n_outs(new_pred)-1;
5558 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5560 } else if (mode_is_float(mode)) {
5563 panic("unexpected proj mode at ASM");
5566 return new_r_Proj(new_pred, mode, pos);
5570 * Transform and potentially renumber Proj nodes.
5572 static ir_node *gen_Proj(ir_node *node)
5574 ir_node *pred = get_Proj_pred(node);
5577 switch (get_irn_opcode(pred)) {
5579 proj = get_Proj_proj(node);
5580 if (proj == pn_Store_M) {
5581 return be_transform_node(pred);
5583 panic("No idea how to transform proj->Store");
5586 return gen_Proj_Load(node);
5588 return gen_Proj_ASM(node);
5590 return gen_Proj_Builtin(node);
5592 return gen_Proj_Div(node);
5594 return gen_Proj_Mod(node);
5596 return gen_Proj_CopyB(node);
5598 return gen_Proj_be_SubSP(node);
5600 return gen_Proj_be_AddSP(node);
5602 return gen_Proj_be_Call(node);
5604 return gen_Proj_Cmp(node);
5606 proj = get_Proj_proj(node);
5608 case pn_Start_X_initial_exec: {
5609 ir_node *block = get_nodes_block(pred);
5610 ir_node *new_block = be_transform_node(block);
5611 dbg_info *dbgi = get_irn_dbg_info(node);
5612 /* we exchange the ProjX with a jump */
5613 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5621 if (is_ia32_l_FloattoLL(pred)) {
5622 return gen_Proj_l_FloattoLL(node);
5624 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5628 ir_mode *mode = get_irn_mode(node);
5629 if (ia32_mode_needs_gp_reg(mode)) {
5630 ir_node *new_pred = be_transform_node(pred);
5631 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5632 get_Proj_proj(node));
5633 new_proj->node_nr = node->node_nr;
5638 return be_duplicate_node(node);
5642 * Enters all transform functions into the generic pointer
5644 static void register_transformers(void)
5646 /* first clear the generic function pointer for all ops */
5647 be_start_transform_setup();
5649 be_set_transform_function(op_Add, gen_Add);
5650 be_set_transform_function(op_And, gen_And);
5651 be_set_transform_function(op_ASM, ia32_gen_ASM);
5652 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5653 be_set_transform_function(op_be_Call, gen_be_Call);
5654 be_set_transform_function(op_be_Copy, gen_be_Copy);
5655 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5656 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5657 be_set_transform_function(op_be_Return, gen_be_Return);
5658 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5659 be_set_transform_function(op_Builtin, gen_Builtin);
5660 be_set_transform_function(op_Cmp, gen_Cmp);
5661 be_set_transform_function(op_Cond, gen_Cond);
5662 be_set_transform_function(op_Const, gen_Const);
5663 be_set_transform_function(op_Conv, gen_Conv);
5664 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5665 be_set_transform_function(op_Div, gen_Div);
5666 be_set_transform_function(op_Eor, gen_Eor);
5667 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5668 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5669 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5670 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5671 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5672 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5673 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5674 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5675 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5676 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5677 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5678 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5679 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5680 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5681 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5682 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5683 be_set_transform_function(op_IJmp, gen_IJmp);
5684 be_set_transform_function(op_Jmp, gen_Jmp);
5685 be_set_transform_function(op_Load, gen_Load);
5686 be_set_transform_function(op_Minus, gen_Minus);
5687 be_set_transform_function(op_Mod, gen_Mod);
5688 be_set_transform_function(op_Mul, gen_Mul);
5689 be_set_transform_function(op_Mulh, gen_Mulh);
5690 be_set_transform_function(op_Mux, gen_Mux);
5691 be_set_transform_function(op_Not, gen_Not);
5692 be_set_transform_function(op_Or, gen_Or);
5693 be_set_transform_function(op_Phi, gen_Phi);
5694 be_set_transform_function(op_Proj, gen_Proj);
5695 be_set_transform_function(op_Rotl, gen_Rotl);
5696 be_set_transform_function(op_Shl, gen_Shl);
5697 be_set_transform_function(op_Shr, gen_Shr);
5698 be_set_transform_function(op_Shrs, gen_Shrs);
5699 be_set_transform_function(op_Store, gen_Store);
5700 be_set_transform_function(op_Sub, gen_Sub);
5701 be_set_transform_function(op_SymConst, gen_SymConst);
5702 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5706 * Pre-transform all unknown and noreg nodes.
5708 static void ia32_pretransform_node(void)
5710 ir_graph *irg = current_ir_graph;
5711 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5713 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5714 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5715 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5716 irg_data->get_eip = be_pre_transform_node(irg_data->get_eip);
5717 irg_data->fpu_trunc_mode = be_pre_transform_node(irg_data->fpu_trunc_mode);
5719 nomem = get_irg_no_mem(irg);
5720 noreg_GP = ia32_new_NoReg_gp(irg);
5724 * Post-process all calls if we are in SSE mode.
5725 * The ABI requires that the results are in st0, copy them
5726 * to a xmm register.
5728 static void postprocess_fp_call_results(void)
5732 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5733 ir_node *call = call_list[i];
5734 ir_type *mtp = call_types[i];
5737 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5738 ir_type *res_tp = get_method_res_type(mtp, j);
5739 ir_node *res, *new_res;
5740 const ir_edge_t *edge, *next;
5743 if (! is_atomic_type(res_tp)) {
5744 /* no floating point return */
5747 mode = get_type_mode(res_tp);
5748 if (! mode_is_float(mode)) {
5749 /* no floating point return */
5753 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5756 /* now patch the users */
5757 foreach_out_edge_safe(res, edge, next) {
5758 ir_node *succ = get_edge_src_irn(edge);
5761 if (be_is_Keep(succ))
5764 if (is_ia32_xStore(succ)) {
5765 /* an xStore can be patched into an vfst */
5766 dbg_info *db = get_irn_dbg_info(succ);
5767 ir_node *block = get_nodes_block(succ);
5768 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5769 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5770 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5771 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5772 ir_mode *mode = get_ia32_ls_mode(succ);
5774 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5775 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5776 if (is_ia32_use_frame(succ))
5777 set_ia32_use_frame(st);
5778 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5779 set_irn_pinned(st, get_irn_pinned(succ));
5780 set_ia32_op_type(st, ia32_AddrModeD);
5784 if (new_res == NULL) {
5785 dbg_info *db = get_irn_dbg_info(call);
5786 ir_node *block = get_nodes_block(call);
5787 ir_node *frame = get_irg_frame(current_ir_graph);
5788 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5789 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5790 ir_node *vfst, *xld, *new_mem;
5792 /* store st(0) on stack */
5793 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5794 set_ia32_op_type(vfst, ia32_AddrModeD);
5795 set_ia32_use_frame(vfst);
5797 /* load into SSE register */
5798 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5799 set_ia32_op_type(xld, ia32_AddrModeS);
5800 set_ia32_use_frame(xld);
5802 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5803 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5805 if (old_mem != NULL) {
5806 edges_reroute(old_mem, new_mem);
5810 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5817 /* do the transformation */
5818 void ia32_transform_graph(ir_graph *irg)
5822 register_transformers();
5823 initial_fpcw = NULL;
5824 ia32_no_pic_adjust = 0;
5826 old_initial_fpcw = be_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");