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);
2003 ir_node *sign_extension;
2005 if (get_mode_size_bits(mode) == 32) {
2006 new_op = be_transform_node(op);
2008 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
2011 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
2013 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
2014 nomem, new_op, sign_extension);
2015 SET_IA32_ORIG_NODE(xorn, node);
2018 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
2019 nomem, sign_extension, xorn);
2021 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
2022 nomem, xorn, sign_extension);
2024 SET_IA32_ORIG_NODE(new_node, node);
2031 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
2033 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
2035 dbg_info *dbgi = get_irn_dbg_info(cmp);
2036 ir_node *block = get_nodes_block(cmp);
2037 ir_node *new_block = be_transform_node(block);
2038 ir_node *op1 = be_transform_node(x);
2039 ir_node *op2 = be_transform_node(n);
2041 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
2044 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
2047 if (mode_is_float(mode)) {
2049 case ir_relation_equal: return ia32_cc_float_equal;
2050 case ir_relation_less: return ia32_cc_float_below;
2051 case ir_relation_less_equal: return ia32_cc_float_below_equal;
2052 case ir_relation_greater: return ia32_cc_float_above;
2053 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
2054 case ir_relation_less_greater: return ia32_cc_not_equal;
2055 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
2056 case ir_relation_unordered: return ia32_cc_parity;
2057 case ir_relation_unordered_equal: return ia32_cc_equal;
2058 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
2059 case ir_relation_unordered_less_equal:
2060 return ia32_cc_float_unordered_below_equal;
2061 case ir_relation_unordered_greater:
2062 return ia32_cc_float_unordered_above;
2063 case ir_relation_unordered_greater_equal:
2064 return ia32_cc_float_unordered_above_equal;
2065 case ir_relation_unordered_less_greater:
2066 return ia32_cc_float_not_equal;
2067 case ir_relation_false:
2068 case ir_relation_true:
2069 /* should we introduce a jump always/jump never? */
2072 panic("Unexpected float pnc");
2073 } else if (mode_is_signed(mode)) {
2075 case ir_relation_unordered_equal:
2076 case ir_relation_equal: return ia32_cc_equal;
2077 case ir_relation_unordered_less:
2078 case ir_relation_less: return ia32_cc_less;
2079 case ir_relation_unordered_less_equal:
2080 case ir_relation_less_equal: return ia32_cc_less_equal;
2081 case ir_relation_unordered_greater:
2082 case ir_relation_greater: return ia32_cc_greater;
2083 case ir_relation_unordered_greater_equal:
2084 case ir_relation_greater_equal: return ia32_cc_greater_equal;
2085 case ir_relation_unordered_less_greater:
2086 case ir_relation_less_greater: return ia32_cc_not_equal;
2087 case ir_relation_less_equal_greater:
2088 case ir_relation_unordered:
2089 case ir_relation_false:
2090 case ir_relation_true:
2091 /* introduce jump always/jump never? */
2094 panic("Unexpected pnc");
2097 case ir_relation_unordered_equal:
2098 case ir_relation_equal: return ia32_cc_equal;
2099 case ir_relation_unordered_less:
2100 case ir_relation_less: return ia32_cc_below;
2101 case ir_relation_unordered_less_equal:
2102 case ir_relation_less_equal: return ia32_cc_below_equal;
2103 case ir_relation_unordered_greater:
2104 case ir_relation_greater: return ia32_cc_above;
2105 case ir_relation_unordered_greater_equal:
2106 case ir_relation_greater_equal: return ia32_cc_above_equal;
2107 case ir_relation_unordered_less_greater:
2108 case ir_relation_less_greater: return ia32_cc_not_equal;
2109 case ir_relation_less_equal_greater:
2110 case ir_relation_unordered:
2111 case ir_relation_false:
2112 case ir_relation_true:
2113 /* introduce jump always/jump never? */
2116 panic("Unexpected pnc");
2120 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
2122 /* a mode_b value, we have to compare it against 0 */
2123 dbg_info *dbgi = get_irn_dbg_info(node);
2124 ir_node *new_block = be_transform_node(get_nodes_block(node));
2125 ir_node *new_op = be_transform_node(node);
2126 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2127 *cc_out = ia32_cc_not_equal;
2131 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2133 /* must have a Cmp as input */
2134 ir_relation relation = get_Cmp_relation(cmp);
2135 ir_relation possible;
2136 ir_node *l = get_Cmp_left(cmp);
2137 ir_node *r = get_Cmp_right(cmp);
2138 ir_mode *mode = get_irn_mode(l);
2141 /* check for bit-test */
2142 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2143 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2144 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2146 ir_node *la = get_And_left(l);
2147 ir_node *ra = get_And_right(l);
2154 ir_node *c = get_Shl_left(la);
2155 if (is_Const_1(c) && is_Const_0(r)) {
2156 /* (1 << n) & ra) */
2157 ir_node *n = get_Shl_right(la);
2158 flags = gen_bt(cmp, ra, n);
2159 /* the bit is copied into the CF flag */
2160 if (relation & ir_relation_equal)
2161 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2163 *cc_out = ia32_cc_below; /* test for CF=1 */
2169 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2170 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2171 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2172 * a predecessor node). So add the < bit */
2173 possible = ir_get_possible_cmp_relations(l, r);
2174 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2175 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2176 relation |= ir_relation_less_greater;
2178 /* just do a normal transformation of the Cmp */
2179 *cc_out = relation_to_condition_code(relation, mode);
2180 flags = be_transform_node(cmp);
2185 * Transform a node returning a "flag" result.
2187 * @param node the node to transform
2188 * @param cc_out the compare mode to use
2190 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2193 return get_flags_node_cmp(node, cc_out);
2194 assert(get_irn_mode(node) == mode_b);
2195 return get_flags_mode_b(node, cc_out);
2199 * Transforms a Load.
2201 * @return the created ia32 Load node
2203 static ir_node *gen_Load(ir_node *node)
2205 ir_node *old_block = get_nodes_block(node);
2206 ir_node *block = be_transform_node(old_block);
2207 ir_node *ptr = get_Load_ptr(node);
2208 ir_node *mem = get_Load_mem(node);
2209 ir_node *new_mem = be_transform_node(mem);
2210 dbg_info *dbgi = get_irn_dbg_info(node);
2211 ir_mode *mode = get_Load_mode(node);
2215 ia32_address_t addr;
2217 /* construct load address */
2218 memset(&addr, 0, sizeof(addr));
2219 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2226 base = be_transform_node(base);
2229 if (index == NULL) {
2232 index = be_transform_node(index);
2235 if (mode_is_float(mode)) {
2236 if (ia32_cg_config.use_sse2) {
2237 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2240 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2244 assert(mode != mode_b);
2246 /* create a conv node with address mode for smaller modes */
2247 if (get_mode_size_bits(mode) < 32) {
2248 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2249 new_mem, noreg_GP, mode);
2251 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2255 set_irn_pinned(new_node, get_irn_pinned(node));
2256 set_ia32_op_type(new_node, ia32_AddrModeS);
2257 set_ia32_ls_mode(new_node, mode);
2258 set_address(new_node, &addr);
2260 if (get_irn_pinned(node) == op_pin_state_floats) {
2261 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2262 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2263 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2264 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2267 SET_IA32_ORIG_NODE(new_node, node);
2272 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2273 ir_node *ptr, ir_node *other)
2280 /* we only use address mode if we're the only user of the load */
2281 if (get_irn_n_edges(node) > 1)
2284 load = get_Proj_pred(node);
2287 if (get_nodes_block(load) != block)
2290 /* store should have the same pointer as the load */
2291 if (get_Load_ptr(load) != ptr)
2294 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2295 if (other != NULL &&
2296 get_nodes_block(other) == block &&
2297 heights_reachable_in_block(ia32_heights, other, load)) {
2301 if (ia32_prevents_AM(block, load, mem))
2303 /* Store should be attached to the load via mem */
2304 assert(heights_reachable_in_block(ia32_heights, mem, load));
2309 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2310 ir_node *mem, ir_node *ptr, ir_mode *mode,
2311 construct_binop_dest_func *func,
2312 construct_binop_dest_func *func8bit,
2313 match_flags_t flags)
2315 ir_node *src_block = get_nodes_block(node);
2323 ia32_address_mode_t am;
2324 ia32_address_t *addr = &am.addr;
2325 memset(&am, 0, sizeof(am));
2327 assert(flags & match_immediate); /* there is no destam node without... */
2328 commutative = (flags & match_commutative) != 0;
2330 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2331 build_address(&am, op1, ia32_create_am_double_use);
2332 new_op = create_immediate_or_transform(op2, 0);
2333 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2334 build_address(&am, op2, ia32_create_am_double_use);
2335 new_op = create_immediate_or_transform(op1, 0);
2340 if (addr->base == NULL)
2341 addr->base = noreg_GP;
2342 if (addr->index == NULL)
2343 addr->index = noreg_GP;
2344 if (addr->mem == NULL)
2347 dbgi = get_irn_dbg_info(node);
2348 block = be_transform_node(src_block);
2349 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2351 if (get_mode_size_bits(mode) == 8) {
2352 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2354 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2356 set_address(new_node, addr);
2357 set_ia32_op_type(new_node, ia32_AddrModeD);
2358 set_ia32_ls_mode(new_node, mode);
2359 SET_IA32_ORIG_NODE(new_node, node);
2361 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2362 mem_proj = be_transform_node(am.mem_proj);
2363 be_set_transformed_node(am.mem_proj, new_node);
2364 be_set_transformed_node(mem_proj, new_node);
2369 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2370 ir_node *ptr, ir_mode *mode,
2371 construct_unop_dest_func *func)
2373 ir_node *src_block = get_nodes_block(node);
2379 ia32_address_mode_t am;
2380 ia32_address_t *addr = &am.addr;
2382 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2385 memset(&am, 0, sizeof(am));
2386 build_address(&am, op, ia32_create_am_double_use);
2388 dbgi = get_irn_dbg_info(node);
2389 block = be_transform_node(src_block);
2390 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2391 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2392 set_address(new_node, addr);
2393 set_ia32_op_type(new_node, ia32_AddrModeD);
2394 set_ia32_ls_mode(new_node, mode);
2395 SET_IA32_ORIG_NODE(new_node, node);
2397 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2398 mem_proj = be_transform_node(am.mem_proj);
2399 be_set_transformed_node(am.mem_proj, new_node);
2400 be_set_transformed_node(mem_proj, new_node);
2405 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2407 ir_mode *mode = get_irn_mode(node);
2408 ir_node *mux_true = get_Mux_true(node);
2409 ir_node *mux_false = get_Mux_false(node);
2417 ia32_condition_code_t cc;
2418 ia32_address_t addr;
2420 if (get_mode_size_bits(mode) != 8)
2423 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2425 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2431 cond = get_Mux_sel(node);
2432 flags = get_flags_node(cond, &cc);
2433 /* we can't handle the float special cases with SetM */
2434 if (cc & ia32_cc_additional_float_cases)
2437 cc = ia32_negate_condition_code(cc);
2439 build_address_ptr(&addr, ptr, mem);
2441 dbgi = get_irn_dbg_info(node);
2442 block = get_nodes_block(node);
2443 new_block = be_transform_node(block);
2444 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2445 addr.index, addr.mem, flags, cc);
2446 set_address(new_node, &addr);
2447 set_ia32_op_type(new_node, ia32_AddrModeD);
2448 set_ia32_ls_mode(new_node, mode);
2449 SET_IA32_ORIG_NODE(new_node, node);
2454 static ir_node *try_create_dest_am(ir_node *node)
2456 ir_node *val = get_Store_value(node);
2457 ir_node *mem = get_Store_mem(node);
2458 ir_node *ptr = get_Store_ptr(node);
2459 ir_mode *mode = get_irn_mode(val);
2460 unsigned bits = get_mode_size_bits(mode);
2465 /* handle only GP modes for now... */
2466 if (!ia32_mode_needs_gp_reg(mode))
2470 /* store must be the only user of the val node */
2471 if (get_irn_n_edges(val) > 1)
2473 /* skip pointless convs */
2475 ir_node *conv_op = get_Conv_op(val);
2476 ir_mode *pred_mode = get_irn_mode(conv_op);
2477 if (!ia32_mode_needs_gp_reg(pred_mode))
2479 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2487 /* value must be in the same block */
2488 if (get_nodes_block(node) != get_nodes_block(val))
2491 switch (get_irn_opcode(val)) {
2493 op1 = get_Add_left(val);
2494 op2 = get_Add_right(val);
2495 if (ia32_cg_config.use_incdec) {
2496 if (is_Const_1(op2)) {
2497 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2499 } else if (is_Const_Minus_1(op2)) {
2500 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2504 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2505 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2506 match_commutative | match_immediate);
2509 op1 = get_Sub_left(val);
2510 op2 = get_Sub_right(val);
2511 if (is_Const(op2)) {
2512 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2514 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2515 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2519 op1 = get_And_left(val);
2520 op2 = get_And_right(val);
2521 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2522 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2523 match_commutative | match_immediate);
2526 op1 = get_Or_left(val);
2527 op2 = get_Or_right(val);
2528 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2529 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2530 match_commutative | match_immediate);
2533 op1 = get_Eor_left(val);
2534 op2 = get_Eor_right(val);
2535 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2536 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2537 match_commutative | match_immediate);
2540 op1 = get_Shl_left(val);
2541 op2 = get_Shl_right(val);
2542 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2543 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2547 op1 = get_Shr_left(val);
2548 op2 = get_Shr_right(val);
2549 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2550 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2554 op1 = get_Shrs_left(val);
2555 op2 = get_Shrs_right(val);
2556 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2557 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2561 op1 = get_Rotl_left(val);
2562 op2 = get_Rotl_right(val);
2563 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2564 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2567 /* TODO: match ROR patterns... */
2569 new_node = try_create_SetMem(val, ptr, mem);
2573 op1 = get_Minus_op(val);
2574 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2577 /* should be lowered already */
2578 assert(mode != mode_b);
2579 op1 = get_Not_op(val);
2580 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2586 if (new_node != NULL) {
2587 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2588 get_irn_pinned(node) == op_pin_state_pinned) {
2589 set_irn_pinned(new_node, op_pin_state_pinned);
2596 static bool possible_int_mode_for_fp(ir_mode *mode)
2600 if (!mode_is_signed(mode))
2602 size = get_mode_size_bits(mode);
2603 if (size != 16 && size != 32)
2608 static int is_float_to_int_conv(const ir_node *node)
2610 ir_mode *mode = get_irn_mode(node);
2614 if (!possible_int_mode_for_fp(mode))
2619 conv_op = get_Conv_op(node);
2620 conv_mode = get_irn_mode(conv_op);
2622 if (!mode_is_float(conv_mode))
2629 * Transform a Store(floatConst) into a sequence of
2632 * @return the created ia32 Store node
2634 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2636 ir_mode *mode = get_irn_mode(cns);
2637 unsigned size = get_mode_size_bytes(mode);
2638 ir_tarval *tv = get_Const_tarval(cns);
2639 ir_node *block = get_nodes_block(node);
2640 ir_node *new_block = be_transform_node(block);
2641 ir_node *ptr = get_Store_ptr(node);
2642 ir_node *mem = get_Store_mem(node);
2643 dbg_info *dbgi = get_irn_dbg_info(node);
2647 ia32_address_t addr;
2649 assert(size % 4 == 0);
2652 build_address_ptr(&addr, ptr, mem);
2656 get_tarval_sub_bits(tv, ofs) |
2657 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2658 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2659 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2660 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2662 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2663 addr.index, addr.mem, imm);
2665 set_irn_pinned(new_node, get_irn_pinned(node));
2666 set_ia32_op_type(new_node, ia32_AddrModeD);
2667 set_ia32_ls_mode(new_node, mode_Iu);
2668 set_address(new_node, &addr);
2669 SET_IA32_ORIG_NODE(new_node, node);
2672 ins[i++] = new_node;
2677 } while (size != 0);
2680 return new_rd_Sync(dbgi, new_block, i, ins);
2687 * Generate a vfist or vfisttp instruction.
2689 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2690 ir_node *mem, ir_node *val, ir_node **fist)
2694 if (ia32_cg_config.use_fisttp) {
2695 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2696 if other users exists */
2697 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2698 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2699 be_new_Keep(block, 1, &value);
2701 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2704 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2707 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2713 * Transforms a general (no special case) Store.
2715 * @return the created ia32 Store node
2717 static ir_node *gen_general_Store(ir_node *node)
2719 ir_node *val = get_Store_value(node);
2720 ir_mode *mode = get_irn_mode(val);
2721 ir_node *block = get_nodes_block(node);
2722 ir_node *new_block = be_transform_node(block);
2723 ir_node *ptr = get_Store_ptr(node);
2724 ir_node *mem = get_Store_mem(node);
2725 dbg_info *dbgi = get_irn_dbg_info(node);
2726 ir_node *new_val, *new_node, *store;
2727 ia32_address_t addr;
2729 /* check for destination address mode */
2730 new_node = try_create_dest_am(node);
2731 if (new_node != NULL)
2734 /* construct store address */
2735 memset(&addr, 0, sizeof(addr));
2736 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2738 if (addr.base == NULL) {
2739 addr.base = noreg_GP;
2741 addr.base = be_transform_node(addr.base);
2744 if (addr.index == NULL) {
2745 addr.index = noreg_GP;
2747 addr.index = be_transform_node(addr.index);
2749 addr.mem = be_transform_node(mem);
2751 if (mode_is_float(mode)) {
2752 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2754 while (is_Conv(val) && mode == get_irn_mode(val)) {
2755 ir_node *op = get_Conv_op(val);
2756 if (!mode_is_float(get_irn_mode(op)))
2760 new_val = be_transform_node(val);
2761 if (ia32_cg_config.use_sse2) {
2762 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2763 addr.index, addr.mem, new_val);
2765 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2766 addr.index, addr.mem, new_val, mode);
2769 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2770 val = get_Conv_op(val);
2772 /* TODO: is this optimisation still necessary at all (middleend)? */
2773 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2774 while (is_Conv(val)) {
2775 ir_node *op = get_Conv_op(val);
2776 if (!mode_is_float(get_irn_mode(op)))
2778 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2782 new_val = be_transform_node(val);
2783 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2785 new_val = create_immediate_or_transform(val, 0);
2786 assert(mode != mode_b);
2788 if (get_mode_size_bits(mode) == 8) {
2789 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2790 addr.index, addr.mem, new_val);
2792 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2793 addr.index, addr.mem, new_val);
2798 set_irn_pinned(store, get_irn_pinned(node));
2799 set_ia32_op_type(store, ia32_AddrModeD);
2800 set_ia32_ls_mode(store, mode);
2802 set_address(store, &addr);
2803 SET_IA32_ORIG_NODE(store, node);
2809 * Transforms a Store.
2811 * @return the created ia32 Store node
2813 static ir_node *gen_Store(ir_node *node)
2815 ir_node *val = get_Store_value(node);
2816 ir_mode *mode = get_irn_mode(val);
2818 if (mode_is_float(mode) && is_Const(val)) {
2819 /* We can transform every floating const store
2820 into a sequence of integer stores.
2821 If the constant is already in a register,
2822 it would be better to use it, but we don't
2823 have this information here. */
2824 return gen_float_const_Store(node, val);
2826 return gen_general_Store(node);
2830 * Transforms a Switch.
2832 * @return the created ia32 SwitchJmp node
2834 static ir_node *create_Switch(ir_node *node)
2836 dbg_info *dbgi = get_irn_dbg_info(node);
2837 ir_node *block = be_transform_node(get_nodes_block(node));
2838 ir_node *sel = get_Cond_selector(node);
2839 ir_node *new_sel = be_transform_node(sel);
2840 long switch_min = LONG_MAX;
2841 long switch_max = LONG_MIN;
2842 long default_pn = get_Cond_default_proj(node);
2844 const ir_edge_t *edge;
2846 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2848 /* determine the smallest switch case value */
2849 foreach_out_edge(node, edge) {
2850 ir_node *proj = get_edge_src_irn(edge);
2851 long pn = get_Proj_proj(proj);
2852 if (pn == default_pn)
2855 if (pn < switch_min)
2857 if (pn > switch_max)
2861 if ((unsigned long) (switch_max - switch_min) > 128000) {
2862 panic("Size of switch %+F bigger than 128000", node);
2865 if (switch_min != 0) {
2866 /* if smallest switch case is not 0 we need an additional sub */
2867 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2868 add_ia32_am_offs_int(new_sel, -switch_min);
2869 set_ia32_op_type(new_sel, ia32_AddrModeS);
2871 SET_IA32_ORIG_NODE(new_sel, node);
2874 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2875 SET_IA32_ORIG_NODE(new_node, node);
2881 * Transform a Cond node.
2883 static ir_node *gen_Cond(ir_node *node)
2885 ir_node *block = get_nodes_block(node);
2886 ir_node *new_block = be_transform_node(block);
2887 dbg_info *dbgi = get_irn_dbg_info(node);
2888 ir_node *sel = get_Cond_selector(node);
2889 ir_mode *sel_mode = get_irn_mode(sel);
2890 ir_node *flags = NULL;
2892 ia32_condition_code_t cc;
2894 if (sel_mode != mode_b) {
2895 return create_Switch(node);
2898 /* we get flags from a Cmp */
2899 flags = get_flags_node(sel, &cc);
2901 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2902 SET_IA32_ORIG_NODE(new_node, node);
2908 * Transform a be_Copy.
2910 static ir_node *gen_be_Copy(ir_node *node)
2912 ir_node *new_node = be_duplicate_node(node);
2913 ir_mode *mode = get_irn_mode(new_node);
2915 if (ia32_mode_needs_gp_reg(mode)) {
2916 set_irn_mode(new_node, mode_Iu);
2922 static ir_node *create_Fucom(ir_node *node)
2924 dbg_info *dbgi = get_irn_dbg_info(node);
2925 ir_node *block = get_nodes_block(node);
2926 ir_node *new_block = be_transform_node(block);
2927 ir_node *left = get_Cmp_left(node);
2928 ir_node *new_left = be_transform_node(left);
2929 ir_node *right = get_Cmp_right(node);
2933 if (ia32_cg_config.use_fucomi) {
2934 new_right = be_transform_node(right);
2935 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2937 set_ia32_commutative(new_node);
2938 SET_IA32_ORIG_NODE(new_node, node);
2940 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2941 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2943 new_right = be_transform_node(right);
2944 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2947 set_ia32_commutative(new_node);
2949 SET_IA32_ORIG_NODE(new_node, node);
2951 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2952 SET_IA32_ORIG_NODE(new_node, node);
2958 static ir_node *create_Ucomi(ir_node *node)
2960 dbg_info *dbgi = get_irn_dbg_info(node);
2961 ir_node *src_block = get_nodes_block(node);
2962 ir_node *new_block = be_transform_node(src_block);
2963 ir_node *left = get_Cmp_left(node);
2964 ir_node *right = get_Cmp_right(node);
2966 ia32_address_mode_t am;
2967 ia32_address_t *addr = &am.addr;
2969 match_arguments(&am, src_block, left, right, NULL,
2970 match_commutative | match_am);
2972 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2973 addr->mem, am.new_op1, am.new_op2,
2975 set_am_attributes(new_node, &am);
2977 SET_IA32_ORIG_NODE(new_node, node);
2979 new_node = fix_mem_proj(new_node, &am);
2985 * returns true if it is assured, that the upper bits of a node are "clean"
2986 * which means for a 16 or 8 bit value, that the upper bits in the register
2987 * are 0 for unsigned and a copy of the last significant bit for signed
2990 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2992 assert(ia32_mode_needs_gp_reg(mode));
2993 if (get_mode_size_bits(mode) >= 32)
2996 if (is_Proj(transformed_node))
2997 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2999 switch (get_ia32_irn_opcode(transformed_node)) {
3000 case iro_ia32_Conv_I2I:
3001 case iro_ia32_Conv_I2I8Bit: {
3002 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
3003 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
3005 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
3012 if (mode_is_signed(mode)) {
3013 return false; /* TODO handle signed modes */
3015 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
3016 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
3017 const ia32_immediate_attr_t *attr
3018 = get_ia32_immediate_attr_const(right);
3019 if (attr->symconst == 0 &&
3020 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
3024 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
3028 /* TODO too conservative if shift amount is constant */
3029 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
3032 if (!mode_is_signed(mode)) {
3034 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
3035 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
3037 /* TODO if one is known to be zero extended, then || is sufficient */
3042 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
3043 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
3045 case iro_ia32_Const:
3046 case iro_ia32_Immediate: {
3047 const ia32_immediate_attr_t *attr =
3048 get_ia32_immediate_attr_const(transformed_node);
3049 if (mode_is_signed(mode)) {
3050 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
3051 return shifted == 0 || shifted == -1;
3053 unsigned long shifted = (unsigned long)attr->offset;
3054 shifted >>= get_mode_size_bits(mode);
3055 return shifted == 0;
3065 * Generate code for a Cmp.
3067 static ir_node *gen_Cmp(ir_node *node)
3069 dbg_info *dbgi = get_irn_dbg_info(node);
3070 ir_node *block = get_nodes_block(node);
3071 ir_node *new_block = be_transform_node(block);
3072 ir_node *left = get_Cmp_left(node);
3073 ir_node *right = get_Cmp_right(node);
3074 ir_mode *cmp_mode = get_irn_mode(left);
3076 ia32_address_mode_t am;
3077 ia32_address_t *addr = &am.addr;
3079 if (mode_is_float(cmp_mode)) {
3080 if (ia32_cg_config.use_sse2) {
3081 return create_Ucomi(node);
3083 return create_Fucom(node);
3087 assert(ia32_mode_needs_gp_reg(cmp_mode));
3089 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
3090 if (is_Const_0(right) &&
3092 get_irn_n_edges(left) == 1) {
3093 /* Test(and_left, and_right) */
3094 ir_node *and_left = get_And_left(left);
3095 ir_node *and_right = get_And_right(left);
3097 /* matze: code here used mode instead of cmd_mode, I think it is always
3098 * the same as cmp_mode, but I leave this here to see if this is really
3101 assert(get_irn_mode(and_left) == cmp_mode);
3103 match_arguments(&am, block, and_left, and_right, NULL,
3105 match_am | match_8bit_am | match_16bit_am |
3106 match_am_and_immediates | match_immediate);
3108 /* use 32bit compare mode if possible since the opcode is smaller */
3109 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3110 upper_bits_clean(am.new_op2, cmp_mode)) {
3111 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3114 if (get_mode_size_bits(cmp_mode) == 8) {
3115 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3116 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3118 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3119 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3122 /* Cmp(left, right) */
3123 match_arguments(&am, block, left, right, NULL,
3124 match_commutative | match_am | match_8bit_am |
3125 match_16bit_am | match_am_and_immediates |
3127 /* use 32bit compare mode if possible since the opcode is smaller */
3128 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3129 upper_bits_clean(am.new_op2, cmp_mode)) {
3130 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3133 if (get_mode_size_bits(cmp_mode) == 8) {
3134 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3135 addr->index, addr->mem, am.new_op1,
3136 am.new_op2, am.ins_permuted);
3138 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3139 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3142 set_am_attributes(new_node, &am);
3143 set_ia32_ls_mode(new_node, cmp_mode);
3145 SET_IA32_ORIG_NODE(new_node, node);
3147 new_node = fix_mem_proj(new_node, &am);
3152 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3153 ia32_condition_code_t cc)
3155 dbg_info *dbgi = get_irn_dbg_info(node);
3156 ir_node *block = get_nodes_block(node);
3157 ir_node *new_block = be_transform_node(block);
3158 ir_node *val_true = get_Mux_true(node);
3159 ir_node *val_false = get_Mux_false(node);
3161 ia32_address_mode_t am;
3162 ia32_address_t *addr;
3164 assert(ia32_cg_config.use_cmov);
3165 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3169 match_arguments(&am, block, val_false, val_true, flags,
3170 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3172 if (am.ins_permuted)
3173 cc = ia32_negate_condition_code(cc);
3175 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3176 addr->mem, am.new_op1, am.new_op2, new_flags,
3178 set_am_attributes(new_node, &am);
3180 SET_IA32_ORIG_NODE(new_node, node);
3182 new_node = fix_mem_proj(new_node, &am);
3188 * Creates a ia32 Setcc instruction.
3190 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3191 ir_node *flags, ia32_condition_code_t cc,
3194 ir_mode *mode = get_irn_mode(orig_node);
3197 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3198 SET_IA32_ORIG_NODE(new_node, orig_node);
3200 /* we might need to conv the result up */
3201 if (get_mode_size_bits(mode) > 8) {
3202 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3203 nomem, new_node, mode_Bu);
3204 SET_IA32_ORIG_NODE(new_node, orig_node);
3211 * Create instruction for an unsigned Difference or Zero.
3213 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3215 ir_mode *mode = get_irn_mode(psi);
3225 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3226 match_mode_neutral | match_am | match_immediate | match_two_users);
3228 block = get_nodes_block(new_node);
3230 if (is_Proj(new_node)) {
3231 sub = get_Proj_pred(new_node);
3234 set_irn_mode(sub, mode_T);
3235 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3237 assert(is_ia32_Sub(sub));
3238 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3240 dbgi = get_irn_dbg_info(psi);
3241 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3242 notn = new_bd_ia32_Not(dbgi, block, sbb);
3244 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3245 set_ia32_commutative(new_node);
3250 * Create an const array of two float consts.
3252 * @param c0 the first constant
3253 * @param c1 the second constant
3254 * @param new_mode IN/OUT for the mode of the constants, if NULL
3255 * smallest possible mode will be used
3257 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3260 ir_mode *mode = *new_mode;
3262 ir_initializer_t *initializer;
3263 ir_tarval *tv0 = get_Const_tarval(c0);
3264 ir_tarval *tv1 = get_Const_tarval(c1);
3267 /* detect the best mode for the constants */
3268 mode = get_tarval_mode(tv0);
3270 if (mode != mode_F) {
3271 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3272 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3274 tv0 = tarval_convert_to(tv0, mode);
3275 tv1 = tarval_convert_to(tv1, mode);
3276 } else if (mode != mode_D) {
3277 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3278 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3280 tv0 = tarval_convert_to(tv0, mode);
3281 tv1 = tarval_convert_to(tv1, mode);
3288 tp = ia32_create_float_type(mode, 4);
3289 tp = ia32_create_float_array(tp);
3291 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3293 set_entity_ld_ident(ent, get_entity_ident(ent));
3294 set_entity_visibility(ent, ir_visibility_private);
3295 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3297 initializer = create_initializer_compound(2);
3299 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3300 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3302 set_entity_initializer(ent, initializer);
3309 * Possible transformations for creating a Setcc.
3311 enum setcc_transform_insn {
3324 typedef struct setcc_transform {
3326 ia32_condition_code_t cc;
3328 enum setcc_transform_insn transform;
3332 } setcc_transform_t;
3335 * Setcc can only handle 0 and 1 result.
3336 * Find a transformation that creates 0 and 1 from
3339 static void find_const_transform(ia32_condition_code_t cc,
3340 ir_tarval *t, ir_tarval *f,
3341 setcc_transform_t *res)
3347 if (tarval_is_null(t)) {
3351 cc = ia32_negate_condition_code(cc);
3352 } else if (tarval_cmp(t, f) == ir_relation_less) {
3353 // now, t is the bigger one
3357 cc = ia32_negate_condition_code(cc);
3361 if (! tarval_is_null(f)) {
3362 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3365 res->steps[step].transform = SETCC_TR_ADD;
3367 if (t == tarval_bad)
3368 panic("constant subtract failed");
3369 if (! tarval_is_long(f))
3370 panic("tarval is not long");
3372 res->steps[step].val = get_tarval_long(f);
3374 f = tarval_sub(f, f, NULL);
3375 assert(tarval_is_null(f));
3378 if (tarval_is_one(t)) {
3379 res->steps[step].transform = SETCC_TR_SET;
3380 res->num_steps = ++step;
3384 if (tarval_is_minus_one(t)) {
3385 res->steps[step].transform = SETCC_TR_NEG;
3387 res->steps[step].transform = SETCC_TR_SET;
3388 res->num_steps = ++step;
3391 if (tarval_is_long(t)) {
3392 long v = get_tarval_long(t);
3394 res->steps[step].val = 0;
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 = 3; /* (a << 3) + 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 = 3; /* (a << 3) */
3409 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3411 res->steps[step].transform = SETCC_TR_LEAxx;
3412 res->steps[step].scale = 2; /* (a << 2) + a */
3415 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3417 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3418 res->steps[step].scale = 2; /* (a << 2) */
3421 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3423 res->steps[step].transform = SETCC_TR_LEAxx;
3424 res->steps[step].scale = 1; /* (a << 1) + a */
3427 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3429 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3430 res->steps[step].scale = 1; /* (a << 1) */
3433 res->num_steps = step;
3436 if (! tarval_is_single_bit(t)) {
3437 res->steps[step].transform = SETCC_TR_AND;
3438 res->steps[step].val = v;
3440 res->steps[step].transform = SETCC_TR_NEG;
3442 int v = get_tarval_lowest_bit(t);
3445 res->steps[step].transform = SETCC_TR_SHL;
3446 res->steps[step].scale = v;
3450 res->steps[step].transform = SETCC_TR_SET;
3451 res->num_steps = ++step;
3454 panic("tarval is not long");
3458 * Transforms a Mux node into some code sequence.
3460 * @return The transformed node.
3462 static ir_node *gen_Mux(ir_node *node)
3464 dbg_info *dbgi = get_irn_dbg_info(node);
3465 ir_node *block = get_nodes_block(node);
3466 ir_node *new_block = be_transform_node(block);
3467 ir_node *mux_true = get_Mux_true(node);
3468 ir_node *mux_false = get_Mux_false(node);
3469 ir_node *sel = get_Mux_sel(node);
3470 ir_mode *mode = get_irn_mode(node);
3474 ia32_condition_code_t cc;
3476 assert(get_irn_mode(sel) == mode_b);
3478 is_abs = be_mux_is_abs(sel, mux_true, mux_false);
3480 return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
3483 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3484 if (mode_is_float(mode)) {
3485 ir_node *cmp_left = get_Cmp_left(sel);
3486 ir_node *cmp_right = get_Cmp_right(sel);
3487 ir_relation relation = get_Cmp_relation(sel);
3489 if (ia32_cg_config.use_sse2) {
3490 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3491 if (cmp_left == mux_true && cmp_right == mux_false) {
3492 /* Mux(a <= b, a, b) => MIN */
3493 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3494 match_commutative | match_am | match_two_users);
3495 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3496 /* Mux(a <= b, b, a) => MAX */
3497 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3498 match_commutative | match_am | match_two_users);
3500 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3501 if (cmp_left == mux_true && cmp_right == mux_false) {
3502 /* Mux(a >= b, a, b) => MAX */
3503 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3504 match_commutative | match_am | match_two_users);
3505 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3506 /* Mux(a >= b, b, a) => MIN */
3507 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3508 match_commutative | match_am | match_two_users);
3513 if (is_Const(mux_true) && is_Const(mux_false)) {
3514 ia32_address_mode_t am;
3519 flags = get_flags_node(sel, &cc);
3520 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3522 if (ia32_cg_config.use_sse2) {
3523 /* cannot load from different mode on SSE */
3526 /* x87 can load any mode */
3530 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3532 switch (get_mode_size_bytes(new_mode)) {
3542 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3543 set_ia32_am_scale(new_node, 2);
3548 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3549 set_ia32_am_scale(new_node, 1);
3552 /* arg, shift 16 NOT supported */
3554 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3557 panic("Unsupported constant size");
3560 am.ls_mode = new_mode;
3561 am.addr.base = get_symconst_base();
3562 am.addr.index = new_node;
3563 am.addr.mem = nomem;
3565 am.addr.scale = scale;
3566 am.addr.use_frame = 0;
3567 am.addr.tls_segment = false;
3568 am.addr.frame_entity = NULL;
3569 am.addr.symconst_sign = 0;
3570 am.mem_proj = am.addr.mem;
3571 am.op_type = ia32_AddrModeS;
3574 am.pinned = op_pin_state_floats;
3576 am.ins_permuted = false;
3578 if (ia32_cg_config.use_sse2)
3579 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3581 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3582 set_am_attributes(load, &am);
3584 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3586 panic("cannot transform floating point Mux");
3589 assert(ia32_mode_needs_gp_reg(mode));
3592 ir_node *cmp_left = get_Cmp_left(sel);
3593 ir_node *cmp_right = get_Cmp_right(sel);
3594 ir_relation relation = get_Cmp_relation(sel);
3595 ir_node *val_true = mux_true;
3596 ir_node *val_false = mux_false;
3598 if (is_Const(val_true) && is_Const_null(val_true)) {
3599 ir_node *tmp = val_false;
3600 val_false = val_true;
3602 relation = get_negated_relation(relation);
3604 if (is_Const_0(val_false) && is_Sub(val_true)) {
3605 if ((relation & ir_relation_greater)
3606 && get_Sub_left(val_true) == cmp_left
3607 && get_Sub_right(val_true) == cmp_right) {
3608 return create_doz(node, cmp_left, cmp_right);
3610 if ((relation & ir_relation_less)
3611 && get_Sub_left(val_true) == cmp_right
3612 && get_Sub_right(val_true) == cmp_left) {
3613 return create_doz(node, cmp_right, cmp_left);
3618 flags = get_flags_node(sel, &cc);
3620 if (is_Const(mux_true) && is_Const(mux_false)) {
3621 /* both are const, good */
3622 ir_tarval *tv_true = get_Const_tarval(mux_true);
3623 ir_tarval *tv_false = get_Const_tarval(mux_false);
3624 setcc_transform_t res;
3627 find_const_transform(cc, tv_true, tv_false, &res);
3629 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3632 switch (res.steps[step].transform) {
3634 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3635 add_ia32_am_offs_int(new_node, res.steps[step].val);
3637 case SETCC_TR_ADDxx:
3638 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3641 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3642 set_ia32_am_scale(new_node, res.steps[step].scale);
3643 set_ia32_am_offs_int(new_node, res.steps[step].val);
3645 case SETCC_TR_LEAxx:
3646 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3647 set_ia32_am_scale(new_node, res.steps[step].scale);
3648 set_ia32_am_offs_int(new_node, res.steps[step].val);
3651 imm = ia32_immediate_from_long(res.steps[step].scale);
3652 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3655 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3658 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3661 imm = ia32_immediate_from_long(res.steps[step].val);
3662 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3665 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3668 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3671 panic("unknown setcc transform");
3675 new_node = create_CMov(node, sel, flags, cc);
3683 * Create a conversion from x87 state register to general purpose.
3685 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3687 ir_node *block = be_transform_node(get_nodes_block(node));
3688 ir_node *op = get_Conv_op(node);
3689 ir_node *new_op = be_transform_node(op);
3690 ir_graph *irg = current_ir_graph;
3691 dbg_info *dbgi = get_irn_dbg_info(node);
3692 ir_mode *mode = get_irn_mode(node);
3693 ir_node *fist, *load, *mem;
3695 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3696 set_irn_pinned(fist, op_pin_state_floats);
3697 set_ia32_use_frame(fist);
3698 set_ia32_op_type(fist, ia32_AddrModeD);
3700 assert(get_mode_size_bits(mode) <= 32);
3701 /* exception we can only store signed 32 bit integers, so for unsigned
3702 we store a 64bit (signed) integer and load the lower bits */
3703 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3704 set_ia32_ls_mode(fist, mode_Ls);
3706 set_ia32_ls_mode(fist, mode_Is);
3708 SET_IA32_ORIG_NODE(fist, node);
3711 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3713 set_irn_pinned(load, op_pin_state_floats);
3714 set_ia32_use_frame(load);
3715 set_ia32_op_type(load, ia32_AddrModeS);
3716 set_ia32_ls_mode(load, mode_Is);
3717 if (get_ia32_ls_mode(fist) == mode_Ls) {
3718 ia32_attr_t *attr = get_ia32_attr(load);
3719 attr->data.need_64bit_stackent = 1;
3721 ia32_attr_t *attr = get_ia32_attr(load);
3722 attr->data.need_32bit_stackent = 1;
3724 SET_IA32_ORIG_NODE(load, node);
3726 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3730 * Creates a x87 strict Conv by placing a Store and a Load
3732 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3734 ir_node *block = get_nodes_block(node);
3735 ir_graph *irg = get_Block_irg(block);
3736 dbg_info *dbgi = get_irn_dbg_info(node);
3737 ir_node *frame = get_irg_frame(irg);
3738 ir_node *store, *load;
3741 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3742 set_ia32_use_frame(store);
3743 set_ia32_op_type(store, ia32_AddrModeD);
3744 SET_IA32_ORIG_NODE(store, node);
3746 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3747 set_ia32_use_frame(load);
3748 set_ia32_op_type(load, ia32_AddrModeS);
3749 SET_IA32_ORIG_NODE(load, node);
3751 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3755 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3756 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3758 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3760 func = get_mode_size_bits(mode) == 8 ?
3761 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3762 return func(dbgi, block, base, index, mem, val, mode);
3766 * Create a conversion from general purpose to x87 register
3768 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3770 ir_node *src_block = get_nodes_block(node);
3771 ir_node *block = be_transform_node(src_block);
3772 ir_graph *irg = get_Block_irg(block);
3773 dbg_info *dbgi = get_irn_dbg_info(node);
3774 ir_node *op = get_Conv_op(node);
3775 ir_node *new_op = NULL;
3777 ir_mode *store_mode;
3782 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3783 if (possible_int_mode_for_fp(src_mode)) {
3784 ia32_address_mode_t am;
3786 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3787 if (am.op_type == ia32_AddrModeS) {
3788 ia32_address_t *addr = &am.addr;
3790 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3791 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3793 set_am_attributes(fild, &am);
3794 SET_IA32_ORIG_NODE(fild, node);
3796 fix_mem_proj(fild, &am);
3801 if (new_op == NULL) {
3802 new_op = be_transform_node(op);
3805 mode = get_irn_mode(op);
3807 /* first convert to 32 bit signed if necessary */
3808 if (get_mode_size_bits(src_mode) < 32) {
3809 if (!upper_bits_clean(new_op, src_mode)) {
3810 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3811 SET_IA32_ORIG_NODE(new_op, node);
3816 assert(get_mode_size_bits(mode) == 32);
3819 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3821 set_ia32_use_frame(store);
3822 set_ia32_op_type(store, ia32_AddrModeD);
3823 set_ia32_ls_mode(store, mode_Iu);
3825 /* exception for 32bit unsigned, do a 64bit spill+load */
3826 if (!mode_is_signed(mode)) {
3829 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3831 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3832 noreg_GP, nomem, zero_const);
3834 set_ia32_use_frame(zero_store);
3835 set_ia32_op_type(zero_store, ia32_AddrModeD);
3836 add_ia32_am_offs_int(zero_store, 4);
3837 set_ia32_ls_mode(zero_store, mode_Iu);
3842 store = new_rd_Sync(dbgi, block, 2, in);
3843 store_mode = mode_Ls;
3845 store_mode = mode_Is;
3849 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3851 set_ia32_use_frame(fild);
3852 set_ia32_op_type(fild, ia32_AddrModeS);
3853 set_ia32_ls_mode(fild, store_mode);
3855 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3861 * Create a conversion from one integer mode into another one
3863 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3864 dbg_info *dbgi, ir_node *block, ir_node *op,
3867 ir_node *new_block = be_transform_node(block);
3869 ir_mode *smaller_mode;
3870 ia32_address_mode_t am;
3871 ia32_address_t *addr = &am.addr;
3874 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3875 smaller_mode = src_mode;
3877 smaller_mode = tgt_mode;
3880 #ifdef DEBUG_libfirm
3882 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3887 match_arguments(&am, block, NULL, op, NULL,
3888 match_am | match_8bit_am | match_16bit_am);
3890 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3891 /* unnecessary conv. in theory it shouldn't have been AM */
3892 assert(is_ia32_NoReg_GP(addr->base));
3893 assert(is_ia32_NoReg_GP(addr->index));
3894 assert(is_NoMem(addr->mem));
3895 assert(am.addr.offset == 0);
3896 assert(am.addr.symconst_ent == NULL);
3900 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3901 addr->mem, am.new_op2, smaller_mode);
3902 set_am_attributes(new_node, &am);
3903 /* match_arguments assume that out-mode = in-mode, this isn't true here
3905 set_ia32_ls_mode(new_node, smaller_mode);
3906 SET_IA32_ORIG_NODE(new_node, node);
3907 new_node = fix_mem_proj(new_node, &am);
3912 * Transforms a Conv node.
3914 * @return The created ia32 Conv node
3916 static ir_node *gen_Conv(ir_node *node)
3918 ir_node *block = get_nodes_block(node);
3919 ir_node *new_block = be_transform_node(block);
3920 ir_node *op = get_Conv_op(node);
3921 ir_node *new_op = NULL;
3922 dbg_info *dbgi = get_irn_dbg_info(node);
3923 ir_mode *src_mode = get_irn_mode(op);
3924 ir_mode *tgt_mode = get_irn_mode(node);
3925 int src_bits = get_mode_size_bits(src_mode);
3926 int tgt_bits = get_mode_size_bits(tgt_mode);
3927 ir_node *res = NULL;
3929 assert(!mode_is_int(src_mode) || src_bits <= 32);
3930 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3932 /* modeB -> X should already be lowered by the lower_mode_b pass */
3933 if (src_mode == mode_b) {
3934 panic("ConvB not lowered %+F", node);
3937 if (src_mode == tgt_mode) {
3938 if (get_Conv_strict(node)) {
3939 if (ia32_cg_config.use_sse2) {
3940 /* when we are in SSE mode, we can kill all strict no-op conversion */
3941 return be_transform_node(op);
3944 /* this should be optimized already, but who knows... */
3945 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3946 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3947 return be_transform_node(op);
3951 if (mode_is_float(src_mode)) {
3952 new_op = be_transform_node(op);
3953 /* we convert from float ... */
3954 if (mode_is_float(tgt_mode)) {
3956 if (ia32_cg_config.use_sse2) {
3957 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3958 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3960 set_ia32_ls_mode(res, tgt_mode);
3962 if (get_Conv_strict(node)) {
3963 /* if fp_no_float_fold is not set then we assume that we
3964 * don't have any float operations in a non
3965 * mode_float_arithmetic mode and can skip strict upconvs */
3966 if (src_bits < tgt_bits) {
3967 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3970 res = gen_x87_strict_conv(tgt_mode, new_op);
3971 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3975 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3980 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3981 if (ia32_cg_config.use_sse2) {
3982 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3984 set_ia32_ls_mode(res, src_mode);
3986 return gen_x87_fp_to_gp(node);
3990 /* we convert from int ... */
3991 if (mode_is_float(tgt_mode)) {
3993 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3994 if (ia32_cg_config.use_sse2) {
3995 new_op = be_transform_node(op);
3996 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3998 set_ia32_ls_mode(res, tgt_mode);
4000 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
4001 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
4002 res = gen_x87_gp_to_fp(node, src_mode);
4004 /* we need a strict-Conv, if the int mode has more bits than the
4006 if (float_mantissa < int_mantissa) {
4007 res = gen_x87_strict_conv(tgt_mode, res);
4008 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
4012 } else if (tgt_mode == mode_b) {
4013 /* mode_b lowering already took care that we only have 0/1 values */
4014 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
4015 src_mode, tgt_mode));
4016 return be_transform_node(op);
4019 if (src_bits == tgt_bits) {
4020 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
4021 src_mode, tgt_mode));
4022 return be_transform_node(op);
4025 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
4033 static ir_node *create_immediate_or_transform(ir_node *node,
4034 char immediate_constraint_type)
4036 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
4037 if (new_node == NULL) {
4038 new_node = be_transform_node(node);
4044 * Transforms a FrameAddr into an ia32 Add.
4046 static ir_node *gen_be_FrameAddr(ir_node *node)
4048 ir_node *block = be_transform_node(get_nodes_block(node));
4049 ir_node *op = be_get_FrameAddr_frame(node);
4050 ir_node *new_op = be_transform_node(op);
4051 dbg_info *dbgi = get_irn_dbg_info(node);
4054 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
4055 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
4056 set_ia32_use_frame(new_node);
4058 SET_IA32_ORIG_NODE(new_node, node);
4064 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4066 static ir_node *gen_be_Return(ir_node *node)
4068 ir_graph *irg = current_ir_graph;
4069 ir_node *ret_val = get_irn_n(node, n_be_Return_val);
4070 ir_node *ret_mem = get_irn_n(node, n_be_Return_mem);
4071 ir_node *new_ret_val = be_transform_node(ret_val);
4072 ir_node *new_ret_mem = be_transform_node(ret_mem);
4073 ir_entity *ent = get_irg_entity(irg);
4074 ir_type *tp = get_entity_type(ent);
4075 dbg_info *dbgi = get_irn_dbg_info(node);
4076 ir_node *block = be_transform_node(get_nodes_block(node));
4079 ir_node *frame, *sse_store, *fld, *mproj;
4086 assert(ret_val != NULL);
4087 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4088 return be_duplicate_node(node);
4091 res_type = get_method_res_type(tp, 0);
4093 if (! is_Primitive_type(res_type)) {
4094 return be_duplicate_node(node);
4097 mode = get_type_mode(res_type);
4098 if (! mode_is_float(mode)) {
4099 return be_duplicate_node(node);
4102 assert(get_method_n_ress(tp) == 1);
4104 frame = get_irg_frame(irg);
4106 /* store xmm0 onto stack */
4107 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
4108 new_ret_mem, new_ret_val);
4109 set_ia32_ls_mode(sse_store, mode);
4110 set_ia32_op_type(sse_store, ia32_AddrModeD);
4111 set_ia32_use_frame(sse_store);
4113 /* load into x87 register */
4114 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4115 set_ia32_op_type(fld, ia32_AddrModeS);
4116 set_ia32_use_frame(fld);
4118 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4119 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4121 /* create a new return */
4122 arity = get_irn_arity(node);
4123 in = ALLOCAN(ir_node*, arity);
4124 pop = be_Return_get_pop(node);
4125 for (i = 0; i < arity; ++i) {
4126 ir_node *op = get_irn_n(node, i);
4127 if (op == ret_val) {
4129 } else if (op == ret_mem) {
4132 in[i] = be_transform_node(op);
4135 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4136 copy_node_attr(irg, node, new_node);
4142 * Transform a be_AddSP into an ia32_SubSP.
4144 static ir_node *gen_be_AddSP(ir_node *node)
4146 ir_node *sz = get_irn_n(node, n_be_AddSP_size);
4147 ir_node *sp = get_irn_n(node, n_be_AddSP_old_sp);
4149 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4150 match_am | match_immediate);
4151 assert(is_ia32_SubSP(new_node));
4152 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4153 &ia32_registers[REG_ESP]);
4158 * Transform a be_SubSP into an ia32_AddSP
4160 static ir_node *gen_be_SubSP(ir_node *node)
4162 ir_node *sz = get_irn_n(node, n_be_SubSP_size);
4163 ir_node *sp = get_irn_n(node, n_be_SubSP_old_sp);
4165 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4166 match_am | match_immediate);
4167 assert(is_ia32_AddSP(new_node));
4168 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4169 &ia32_registers[REG_ESP]);
4174 * Change some phi modes
4176 static ir_node *gen_Phi(ir_node *node)
4178 const arch_register_req_t *req;
4179 ir_node *block = be_transform_node(get_nodes_block(node));
4180 ir_graph *irg = current_ir_graph;
4181 dbg_info *dbgi = get_irn_dbg_info(node);
4182 ir_mode *mode = get_irn_mode(node);
4185 if (ia32_mode_needs_gp_reg(mode)) {
4186 /* we shouldn't have any 64bit stuff around anymore */
4187 assert(get_mode_size_bits(mode) <= 32);
4188 /* all integer operations are on 32bit registers now */
4190 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4191 } else if (mode_is_float(mode)) {
4192 if (ia32_cg_config.use_sse2) {
4194 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4197 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4200 req = arch_no_register_req;
4203 /* phi nodes allow loops, so we use the old arguments for now
4204 * and fix this later */
4205 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4206 get_irn_in(node) + 1);
4207 copy_node_attr(irg, node, phi);
4208 be_duplicate_deps(node, phi);
4210 arch_set_out_register_req(phi, 0, req);
4212 be_enqueue_preds(node);
4217 static ir_node *gen_Jmp(ir_node *node)
4219 ir_node *block = get_nodes_block(node);
4220 ir_node *new_block = be_transform_node(block);
4221 dbg_info *dbgi = get_irn_dbg_info(node);
4224 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4225 SET_IA32_ORIG_NODE(new_node, node);
4233 static ir_node *gen_IJmp(ir_node *node)
4235 ir_node *block = get_nodes_block(node);
4236 ir_node *new_block = be_transform_node(block);
4237 dbg_info *dbgi = get_irn_dbg_info(node);
4238 ir_node *op = get_IJmp_target(node);
4240 ia32_address_mode_t am;
4241 ia32_address_t *addr = &am.addr;
4243 assert(get_irn_mode(op) == mode_P);
4245 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4247 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4248 addr->mem, am.new_op2);
4249 set_am_attributes(new_node, &am);
4250 SET_IA32_ORIG_NODE(new_node, node);
4252 new_node = fix_mem_proj(new_node, &am);
4257 static ir_node *gen_ia32_l_Add(ir_node *node)
4259 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4260 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4261 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4262 match_commutative | match_am | match_immediate |
4263 match_mode_neutral);
4265 if (is_Proj(lowered)) {
4266 lowered = get_Proj_pred(lowered);
4268 assert(is_ia32_Add(lowered));
4269 set_irn_mode(lowered, mode_T);
4275 static ir_node *gen_ia32_l_Adc(ir_node *node)
4277 return gen_binop_flags(node, new_bd_ia32_Adc,
4278 match_commutative | match_am | match_immediate |
4279 match_mode_neutral);
4283 * Transforms a l_MulS into a "real" MulS node.
4285 * @return the created ia32 Mul node
4287 static ir_node *gen_ia32_l_Mul(ir_node *node)
4289 ir_node *left = get_binop_left(node);
4290 ir_node *right = get_binop_right(node);
4292 return gen_binop(node, left, right, new_bd_ia32_Mul,
4293 match_commutative | match_am | match_mode_neutral);
4297 * Transforms a l_IMulS into a "real" IMul1OPS node.
4299 * @return the created ia32 IMul1OP node
4301 static ir_node *gen_ia32_l_IMul(ir_node *node)
4303 ir_node *left = get_binop_left(node);
4304 ir_node *right = get_binop_right(node);
4306 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4307 match_commutative | match_am | match_mode_neutral);
4310 static ir_node *gen_ia32_l_Sub(ir_node *node)
4312 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4313 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4314 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4315 match_am | match_immediate | match_mode_neutral);
4317 if (is_Proj(lowered)) {
4318 lowered = get_Proj_pred(lowered);
4320 assert(is_ia32_Sub(lowered));
4321 set_irn_mode(lowered, mode_T);
4327 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4329 return gen_binop_flags(node, new_bd_ia32_Sbb,
4330 match_am | match_immediate | match_mode_neutral);
4333 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4335 ir_node *src_block = get_nodes_block(node);
4336 ir_node *block = be_transform_node(src_block);
4337 ir_graph *irg = current_ir_graph;
4338 dbg_info *dbgi = get_irn_dbg_info(node);
4339 ir_node *frame = get_irg_frame(irg);
4340 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4341 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4342 ir_node *new_val_low = be_transform_node(val_low);
4343 ir_node *new_val_high = be_transform_node(val_high);
4345 ir_node *sync, *fild, *res;
4346 ir_node *store_low, *store_high;
4348 if (ia32_cg_config.use_sse2) {
4349 panic("ia32_l_LLtoFloat not implemented for SSE2");
4353 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4355 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4357 SET_IA32_ORIG_NODE(store_low, node);
4358 SET_IA32_ORIG_NODE(store_high, node);
4360 set_ia32_use_frame(store_low);
4361 set_ia32_use_frame(store_high);
4362 set_ia32_op_type(store_low, ia32_AddrModeD);
4363 set_ia32_op_type(store_high, ia32_AddrModeD);
4364 set_ia32_ls_mode(store_low, mode_Iu);
4365 set_ia32_ls_mode(store_high, mode_Is);
4366 add_ia32_am_offs_int(store_high, 4);
4370 sync = new_rd_Sync(dbgi, block, 2, in);
4373 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4375 set_ia32_use_frame(fild);
4376 set_ia32_op_type(fild, ia32_AddrModeS);
4377 set_ia32_ls_mode(fild, mode_Ls);
4379 SET_IA32_ORIG_NODE(fild, node);
4381 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4383 if (! mode_is_signed(get_irn_mode(val_high))) {
4384 ia32_address_mode_t am;
4386 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4389 am.addr.base = get_symconst_base();
4390 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4391 am.addr.mem = nomem;
4394 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4395 am.addr.tls_segment = false;
4396 am.addr.use_frame = 0;
4397 am.addr.frame_entity = NULL;
4398 am.addr.symconst_sign = 0;
4399 am.ls_mode = mode_F;
4400 am.mem_proj = nomem;
4401 am.op_type = ia32_AddrModeS;
4403 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4404 am.pinned = op_pin_state_floats;
4406 am.ins_permuted = false;
4408 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4409 am.new_op1, am.new_op2, get_fpcw());
4410 set_am_attributes(fadd, &am);
4412 set_irn_mode(fadd, mode_T);
4413 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4418 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4420 ir_node *src_block = get_nodes_block(node);
4421 ir_node *block = be_transform_node(src_block);
4422 ir_graph *irg = get_Block_irg(block);
4423 dbg_info *dbgi = get_irn_dbg_info(node);
4424 ir_node *frame = get_irg_frame(irg);
4425 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4426 ir_node *new_val = be_transform_node(val);
4427 ir_node *fist, *mem;
4429 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4430 SET_IA32_ORIG_NODE(fist, node);
4431 set_ia32_use_frame(fist);
4432 set_ia32_op_type(fist, ia32_AddrModeD);
4433 set_ia32_ls_mode(fist, mode_Ls);
4438 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4440 ir_node *block = be_transform_node(get_nodes_block(node));
4441 ir_graph *irg = get_Block_irg(block);
4442 ir_node *pred = get_Proj_pred(node);
4443 ir_node *new_pred = be_transform_node(pred);
4444 ir_node *frame = get_irg_frame(irg);
4445 dbg_info *dbgi = get_irn_dbg_info(node);
4446 long pn = get_Proj_proj(node);
4451 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4452 SET_IA32_ORIG_NODE(load, node);
4453 set_ia32_use_frame(load);
4454 set_ia32_op_type(load, ia32_AddrModeS);
4455 set_ia32_ls_mode(load, mode_Iu);
4456 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4457 * 32 bit from it with this particular load */
4458 attr = get_ia32_attr(load);
4459 attr->data.need_64bit_stackent = 1;
4461 if (pn == pn_ia32_l_FloattoLL_res_high) {
4462 add_ia32_am_offs_int(load, 4);
4464 assert(pn == pn_ia32_l_FloattoLL_res_low);
4467 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4473 * Transform the Projs of an AddSP.
4475 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4477 ir_node *pred = get_Proj_pred(node);
4478 ir_node *new_pred = be_transform_node(pred);
4479 dbg_info *dbgi = get_irn_dbg_info(node);
4480 long proj = get_Proj_proj(node);
4482 if (proj == pn_be_AddSP_sp) {
4483 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4484 pn_ia32_SubSP_stack);
4485 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4487 } else if (proj == pn_be_AddSP_res) {
4488 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4489 pn_ia32_SubSP_addr);
4490 } else if (proj == pn_be_AddSP_M) {
4491 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4494 panic("No idea how to transform proj->AddSP");
4498 * Transform the Projs of a SubSP.
4500 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4502 ir_node *pred = get_Proj_pred(node);
4503 ir_node *new_pred = be_transform_node(pred);
4504 dbg_info *dbgi = get_irn_dbg_info(node);
4505 long proj = get_Proj_proj(node);
4507 if (proj == pn_be_SubSP_sp) {
4508 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4509 pn_ia32_AddSP_stack);
4510 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4512 } else if (proj == pn_be_SubSP_M) {
4513 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4516 panic("No idea how to transform proj->SubSP");
4520 * Transform and renumber the Projs from a Load.
4522 static ir_node *gen_Proj_Load(ir_node *node)
4525 ir_node *pred = get_Proj_pred(node);
4526 dbg_info *dbgi = get_irn_dbg_info(node);
4527 long proj = get_Proj_proj(node);
4529 /* loads might be part of source address mode matches, so we don't
4530 * transform the ProjMs yet (with the exception of loads whose result is
4533 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4536 /* this is needed, because sometimes we have loops that are only
4537 reachable through the ProjM */
4538 be_enqueue_preds(node);
4539 /* do it in 2 steps, to silence firm verifier */
4540 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4541 set_Proj_proj(res, pn_ia32_mem);
4545 /* renumber the proj */
4546 new_pred = be_transform_node(pred);
4547 if (is_ia32_Load(new_pred)) {
4548 switch ((pn_Load)proj) {
4550 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4552 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4553 case pn_Load_X_except:
4554 /* This Load might raise an exception. Mark it. */
4555 set_ia32_exc_label(new_pred, 1);
4556 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_except);
4557 case pn_Load_X_regular:
4558 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_regular);
4562 } else if (is_ia32_Conv_I2I(new_pred) ||
4563 is_ia32_Conv_I2I8Bit(new_pred)) {
4564 set_irn_mode(new_pred, mode_T);
4565 if (proj == pn_Load_res) {
4566 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4567 } else if (proj == pn_Load_M) {
4568 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4570 } else if (is_ia32_xLoad(new_pred)) {
4571 switch ((pn_Load)proj) {
4573 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4575 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4576 case pn_Load_X_except:
4577 /* This Load might raise an exception. Mark it. */
4578 set_ia32_exc_label(new_pred, 1);
4579 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_except);
4580 case pn_Load_X_regular:
4581 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_regular);
4585 } else if (is_ia32_vfld(new_pred)) {
4586 switch ((pn_Load)proj) {
4588 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4590 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4591 case pn_Load_X_except:
4592 /* This Load might raise an exception. Mark it. */
4593 set_ia32_exc_label(new_pred, 1);
4594 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_except);
4595 case pn_Load_X_regular:
4596 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_regular);
4601 /* can happen for ProJMs when source address mode happened for the
4604 /* however it should not be the result proj, as that would mean the
4605 load had multiple users and should not have been used for
4607 if (proj != pn_Load_M) {
4608 panic("internal error: transformed node not a Load");
4610 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4613 panic("No idea how to transform proj");
4617 * Transform and renumber the Projs from a Div or Mod instruction.
4619 static ir_node *gen_Proj_Div(ir_node *node)
4621 ir_node *pred = get_Proj_pred(node);
4622 ir_node *new_pred = be_transform_node(pred);
4623 dbg_info *dbgi = get_irn_dbg_info(node);
4624 long proj = get_Proj_proj(node);
4626 assert((long)pn_ia32_Div_M == (long)pn_ia32_IDiv_M);
4627 assert((long)pn_ia32_Div_div_res == (long)pn_ia32_IDiv_div_res);
4629 switch ((pn_Div)proj) {
4631 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4632 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4633 } else if (is_ia32_xDiv(new_pred)) {
4634 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4635 } else if (is_ia32_vfdiv(new_pred)) {
4636 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4638 panic("Div transformed to unexpected thing %+F", new_pred);
4641 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4642 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4643 } else if (is_ia32_xDiv(new_pred)) {
4644 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4645 } else if (is_ia32_vfdiv(new_pred)) {
4646 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4648 panic("Div transformed to unexpected thing %+F", new_pred);
4650 case pn_Div_X_except:
4651 set_ia32_exc_label(new_pred, 1);
4652 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_except);
4653 case pn_Div_X_regular:
4654 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_regular);
4659 panic("No idea how to transform proj->Div");
4663 * Transform and renumber the Projs from a Div or Mod instruction.
4665 static ir_node *gen_Proj_Mod(ir_node *node)
4667 ir_node *pred = get_Proj_pred(node);
4668 ir_node *new_pred = be_transform_node(pred);
4669 dbg_info *dbgi = get_irn_dbg_info(node);
4670 long proj = get_Proj_proj(node);
4672 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4673 assert((long)pn_ia32_Div_M == (long)pn_ia32_IDiv_M);
4674 assert((long)pn_ia32_Div_mod_res == (long)pn_ia32_IDiv_mod_res);
4676 switch ((pn_Mod)proj) {
4678 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4680 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4681 case pn_Mod_X_except:
4682 set_ia32_exc_label(new_pred, 1);
4683 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_except);
4684 case pn_Mod_X_regular:
4685 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_regular);
4689 panic("No idea how to transform proj->Mod");
4693 * Transform and renumber the Projs from a CopyB.
4695 static ir_node *gen_Proj_CopyB(ir_node *node)
4697 ir_node *pred = get_Proj_pred(node);
4698 ir_node *new_pred = be_transform_node(pred);
4699 dbg_info *dbgi = get_irn_dbg_info(node);
4700 long proj = get_Proj_proj(node);
4704 if (is_ia32_CopyB_i(new_pred)) {
4705 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4706 } else if (is_ia32_CopyB(new_pred)) {
4707 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4714 panic("No idea how to transform proj->CopyB");
4717 static ir_node *gen_be_Call(ir_node *node)
4719 dbg_info *const dbgi = get_irn_dbg_info(node);
4720 ir_node *const src_block = get_nodes_block(node);
4721 ir_node *const block = be_transform_node(src_block);
4722 ir_node *const src_mem = get_irn_n(node, n_be_Call_mem);
4723 ir_node *const src_sp = get_irn_n(node, n_be_Call_sp);
4724 ir_node *const sp = be_transform_node(src_sp);
4725 ir_node *const src_ptr = get_irn_n(node, n_be_Call_ptr);
4726 ia32_address_mode_t am;
4727 ia32_address_t *const addr = &am.addr;
4732 ir_node * eax = noreg_GP;
4733 ir_node * ecx = noreg_GP;
4734 ir_node * edx = noreg_GP;
4735 unsigned const pop = be_Call_get_pop(node);
4736 ir_type *const call_tp = be_Call_get_type(node);
4737 int old_no_pic_adjust;
4739 /* Run the x87 simulator if the call returns a float value */
4740 if (get_method_n_ress(call_tp) > 0) {
4741 ir_type *const res_type = get_method_res_type(call_tp, 0);
4742 ir_mode *const res_mode = get_type_mode(res_type);
4744 if (res_mode != NULL && mode_is_float(res_mode)) {
4745 ir_graph *irg = current_ir_graph;
4746 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4747 irg_data->do_x87_sim = 1;
4751 /* We do not want be_Call direct calls */
4752 assert(be_Call_get_entity(node) == NULL);
4754 /* special case for PIC trampoline calls */
4755 old_no_pic_adjust = ia32_no_pic_adjust;
4756 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4758 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4759 match_am | match_immediate);
4761 ia32_no_pic_adjust = old_no_pic_adjust;
4763 i = get_irn_arity(node) - 1;
4764 fpcw = be_transform_node(get_irn_n(node, i--));
4765 for (; i >= n_be_Call_first_arg; --i) {
4766 arch_register_req_t const *const req = arch_get_register_req(node, i);
4767 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4769 assert(req->type == arch_register_req_type_limited);
4770 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4772 switch (*req->limited) {
4773 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4774 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4775 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4776 default: panic("Invalid GP register for register parameter");
4780 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4781 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4782 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4783 set_am_attributes(call, &am);
4784 call = fix_mem_proj(call, &am);
4786 if (get_irn_pinned(node) == op_pin_state_pinned)
4787 set_irn_pinned(call, op_pin_state_pinned);
4789 SET_IA32_ORIG_NODE(call, node);
4791 if (ia32_cg_config.use_sse2) {
4792 /* remember this call for post-processing */
4793 ARR_APP1(ir_node *, call_list, call);
4794 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4801 * Transform Builtin trap
4803 static ir_node *gen_trap(ir_node *node)
4805 dbg_info *dbgi = get_irn_dbg_info(node);
4806 ir_node *block = be_transform_node(get_nodes_block(node));
4807 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4809 return new_bd_ia32_UD2(dbgi, block, mem);
4813 * Transform Builtin debugbreak
4815 static ir_node *gen_debugbreak(ir_node *node)
4817 dbg_info *dbgi = get_irn_dbg_info(node);
4818 ir_node *block = be_transform_node(get_nodes_block(node));
4819 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4821 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4825 * Transform Builtin return_address
4827 static ir_node *gen_return_address(ir_node *node)
4829 ir_node *param = get_Builtin_param(node, 0);
4830 ir_node *frame = get_Builtin_param(node, 1);
4831 dbg_info *dbgi = get_irn_dbg_info(node);
4832 ir_tarval *tv = get_Const_tarval(param);
4833 ir_graph *irg = get_irn_irg(node);
4834 unsigned long value = get_tarval_long(tv);
4836 ir_node *block = be_transform_node(get_nodes_block(node));
4837 ir_node *ptr = be_transform_node(frame);
4841 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4842 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4843 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4846 /* load the return address from this frame */
4847 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4849 set_irn_pinned(load, get_irn_pinned(node));
4850 set_ia32_op_type(load, ia32_AddrModeS);
4851 set_ia32_ls_mode(load, mode_Iu);
4853 set_ia32_am_offs_int(load, 0);
4854 set_ia32_use_frame(load);
4855 set_ia32_frame_ent(load, ia32_get_return_address_entity(irg));
4857 if (get_irn_pinned(node) == op_pin_state_floats) {
4858 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4859 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4860 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4861 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4864 SET_IA32_ORIG_NODE(load, node);
4865 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4869 * Transform Builtin frame_address
4871 static ir_node *gen_frame_address(ir_node *node)
4873 ir_node *param = get_Builtin_param(node, 0);
4874 ir_node *frame = get_Builtin_param(node, 1);
4875 dbg_info *dbgi = get_irn_dbg_info(node);
4876 ir_tarval *tv = get_Const_tarval(param);
4877 ir_graph *irg = get_irn_irg(node);
4878 unsigned long value = get_tarval_long(tv);
4880 ir_node *block = be_transform_node(get_nodes_block(node));
4881 ir_node *ptr = be_transform_node(frame);
4886 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4887 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4888 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4891 /* load the frame address from this frame */
4892 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4894 set_irn_pinned(load, get_irn_pinned(node));
4895 set_ia32_op_type(load, ia32_AddrModeS);
4896 set_ia32_ls_mode(load, mode_Iu);
4898 ent = ia32_get_frame_address_entity(irg);
4900 set_ia32_am_offs_int(load, 0);
4901 set_ia32_use_frame(load);
4902 set_ia32_frame_ent(load, ent);
4904 /* will fail anyway, but gcc does this: */
4905 set_ia32_am_offs_int(load, 0);
4908 if (get_irn_pinned(node) == op_pin_state_floats) {
4909 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4910 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4911 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4912 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4915 SET_IA32_ORIG_NODE(load, node);
4916 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4920 * Transform Builtin frame_address
4922 static ir_node *gen_prefetch(ir_node *node)
4925 ir_node *ptr, *block, *mem, *base, *index;
4926 ir_node *param, *new_node;
4929 ia32_address_t addr;
4931 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4932 /* no prefetch at all, route memory */
4933 return be_transform_node(get_Builtin_mem(node));
4936 param = get_Builtin_param(node, 1);
4937 tv = get_Const_tarval(param);
4938 rw = get_tarval_long(tv);
4940 /* construct load address */
4941 memset(&addr, 0, sizeof(addr));
4942 ptr = get_Builtin_param(node, 0);
4943 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4950 base = be_transform_node(base);
4953 if (index == NULL) {
4956 index = be_transform_node(index);
4959 dbgi = get_irn_dbg_info(node);
4960 block = be_transform_node(get_nodes_block(node));
4961 mem = be_transform_node(get_Builtin_mem(node));
4963 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4964 /* we have 3DNow!, this was already checked above */
4965 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4966 } else if (ia32_cg_config.use_sse_prefetch) {
4967 /* note: rw == 1 is IGNORED in that case */
4968 param = get_Builtin_param(node, 2);
4969 tv = get_Const_tarval(param);
4970 locality = get_tarval_long(tv);
4972 /* SSE style prefetch */
4975 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4978 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4981 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4984 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4988 assert(ia32_cg_config.use_3dnow_prefetch);
4989 /* 3DNow! style prefetch */
4990 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4993 set_irn_pinned(new_node, get_irn_pinned(node));
4994 set_ia32_op_type(new_node, ia32_AddrModeS);
4995 set_ia32_ls_mode(new_node, mode_Bu);
4996 set_address(new_node, &addr);
4998 SET_IA32_ORIG_NODE(new_node, node);
5000 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
5004 * Transform bsf like node
5006 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
5008 ir_node *param = get_Builtin_param(node, 0);
5009 dbg_info *dbgi = get_irn_dbg_info(node);
5011 ir_node *block = get_nodes_block(node);
5012 ir_node *new_block = be_transform_node(block);
5014 ia32_address_mode_t am;
5015 ia32_address_t *addr = &am.addr;
5018 match_arguments(&am, block, NULL, param, NULL, match_am);
5020 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5021 set_am_attributes(cnt, &am);
5022 set_ia32_ls_mode(cnt, get_irn_mode(param));
5024 SET_IA32_ORIG_NODE(cnt, node);
5025 return fix_mem_proj(cnt, &am);
5029 * Transform builtin ffs.
5031 static ir_node *gen_ffs(ir_node *node)
5033 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5034 ir_node *real = skip_Proj(bsf);
5035 dbg_info *dbgi = get_irn_dbg_info(real);
5036 ir_node *block = get_nodes_block(real);
5037 ir_node *flag, *set, *conv, *neg, *orn, *add;
5040 if (get_irn_mode(real) != mode_T) {
5041 set_irn_mode(real, mode_T);
5042 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5045 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5048 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5049 SET_IA32_ORIG_NODE(set, node);
5052 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5053 SET_IA32_ORIG_NODE(conv, node);
5056 neg = new_bd_ia32_Neg(dbgi, block, conv);
5059 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5060 set_ia32_commutative(orn);
5063 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5064 add_ia32_am_offs_int(add, 1);
5069 * Transform builtin clz.
5071 static ir_node *gen_clz(ir_node *node)
5073 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5074 ir_node *real = skip_Proj(bsr);
5075 dbg_info *dbgi = get_irn_dbg_info(real);
5076 ir_node *block = get_nodes_block(real);
5077 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5079 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5083 * Transform builtin ctz.
5085 static ir_node *gen_ctz(ir_node *node)
5087 return gen_unop_AM(node, new_bd_ia32_Bsf);
5091 * Transform builtin parity.
5093 static ir_node *gen_parity(ir_node *node)
5095 dbg_info *dbgi = get_irn_dbg_info(node);
5096 ir_node *block = get_nodes_block(node);
5097 ir_node *new_block = be_transform_node(block);
5098 ir_node *param = get_Builtin_param(node, 0);
5099 ir_node *new_param = be_transform_node(param);
5102 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5103 * so we have to do complicated xoring first.
5104 * (we should also better lower this before the backend so we still have a
5105 * chance for CSE, constant folding and other goodies for some of these
5108 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5109 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5110 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5112 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5115 set_irn_mode(xor2, mode_T);
5116 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5119 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5120 SET_IA32_ORIG_NODE(new_node, node);
5123 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5124 nomem, new_node, mode_Bu);
5125 SET_IA32_ORIG_NODE(new_node, node);
5130 * Transform builtin popcount
5132 static ir_node *gen_popcount(ir_node *node)
5134 ir_node *param = get_Builtin_param(node, 0);
5135 dbg_info *dbgi = get_irn_dbg_info(node);
5137 ir_node *block = get_nodes_block(node);
5138 ir_node *new_block = be_transform_node(block);
5141 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5143 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5144 if (ia32_cg_config.use_popcnt) {
5145 ia32_address_mode_t am;
5146 ia32_address_t *addr = &am.addr;
5149 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5151 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5152 set_am_attributes(cnt, &am);
5153 set_ia32_ls_mode(cnt, get_irn_mode(param));
5155 SET_IA32_ORIG_NODE(cnt, node);
5156 return fix_mem_proj(cnt, &am);
5159 new_param = be_transform_node(param);
5161 /* do the standard popcount algo */
5162 /* TODO: This is stupid, we should transform this before the backend,
5163 * to get CSE, localopts, etc. for the operations
5164 * TODO: This is also not the optimal algorithm (it is just the starting
5165 * example in hackers delight, they optimize it more on the following page)
5166 * But I'm too lazy to fix this now, as the code should get lowered before
5167 * the backend anyway.
5170 /* m1 = x & 0x55555555 */
5171 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5172 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5175 simm = ia32_create_Immediate(NULL, 0, 1);
5176 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5178 /* m2 = s1 & 0x55555555 */
5179 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5182 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5184 /* m4 = m3 & 0x33333333 */
5185 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5186 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5189 simm = ia32_create_Immediate(NULL, 0, 2);
5190 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5192 /* m5 = s2 & 0x33333333 */
5193 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5196 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5198 /* m7 = m6 & 0x0F0F0F0F */
5199 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5200 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5203 simm = ia32_create_Immediate(NULL, 0, 4);
5204 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5206 /* m8 = s3 & 0x0F0F0F0F */
5207 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5210 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5212 /* m10 = m9 & 0x00FF00FF */
5213 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5214 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5217 simm = ia32_create_Immediate(NULL, 0, 8);
5218 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5220 /* m11 = s4 & 0x00FF00FF */
5221 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5223 /* m12 = m10 + m11 */
5224 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5226 /* m13 = m12 & 0x0000FFFF */
5227 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5228 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5230 /* s5 = m12 >> 16 */
5231 simm = ia32_create_Immediate(NULL, 0, 16);
5232 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5234 /* res = m13 + s5 */
5235 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5239 * Transform builtin byte swap.
5241 static ir_node *gen_bswap(ir_node *node)
5243 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5244 dbg_info *dbgi = get_irn_dbg_info(node);
5246 ir_node *block = get_nodes_block(node);
5247 ir_node *new_block = be_transform_node(block);
5248 ir_mode *mode = get_irn_mode(param);
5249 unsigned size = get_mode_size_bits(mode);
5250 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5254 if (ia32_cg_config.use_i486) {
5255 /* swap available */
5256 return new_bd_ia32_Bswap(dbgi, new_block, param);
5258 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5259 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5261 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5262 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5264 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5266 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5267 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5269 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5270 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5273 /* swap16 always available */
5274 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5277 panic("Invalid bswap size (%d)", size);
5282 * Transform builtin outport.
5284 static ir_node *gen_outport(ir_node *node)
5286 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5287 ir_node *oldv = get_Builtin_param(node, 1);
5288 ir_mode *mode = get_irn_mode(oldv);
5289 ir_node *value = be_transform_node(oldv);
5290 ir_node *block = be_transform_node(get_nodes_block(node));
5291 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5292 dbg_info *dbgi = get_irn_dbg_info(node);
5294 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5295 set_ia32_ls_mode(res, mode);
5300 * Transform builtin inport.
5302 static ir_node *gen_inport(ir_node *node)
5304 ir_type *tp = get_Builtin_type(node);
5305 ir_type *rstp = get_method_res_type(tp, 0);
5306 ir_mode *mode = get_type_mode(rstp);
5307 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5308 ir_node *block = be_transform_node(get_nodes_block(node));
5309 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5310 dbg_info *dbgi = get_irn_dbg_info(node);
5312 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5313 set_ia32_ls_mode(res, mode);
5315 /* check for missing Result Proj */
5320 * Transform a builtin inner trampoline
5322 static ir_node *gen_inner_trampoline(ir_node *node)
5324 ir_node *ptr = get_Builtin_param(node, 0);
5325 ir_node *callee = get_Builtin_param(node, 1);
5326 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5327 ir_node *mem = get_Builtin_mem(node);
5328 ir_node *block = get_nodes_block(node);
5329 ir_node *new_block = be_transform_node(block);
5333 ir_node *trampoline;
5335 dbg_info *dbgi = get_irn_dbg_info(node);
5336 ia32_address_t addr;
5338 /* construct store address */
5339 memset(&addr, 0, sizeof(addr));
5340 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5342 if (addr.base == NULL) {
5343 addr.base = noreg_GP;
5345 addr.base = be_transform_node(addr.base);
5348 if (addr.index == NULL) {
5349 addr.index = noreg_GP;
5351 addr.index = be_transform_node(addr.index);
5353 addr.mem = be_transform_node(mem);
5355 /* mov ecx, <env> */
5356 val = ia32_create_Immediate(NULL, 0, 0xB9);
5357 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5358 addr.index, addr.mem, val);
5359 set_irn_pinned(store, get_irn_pinned(node));
5360 set_ia32_op_type(store, ia32_AddrModeD);
5361 set_ia32_ls_mode(store, mode_Bu);
5362 set_address(store, &addr);
5366 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5367 addr.index, addr.mem, env);
5368 set_irn_pinned(store, get_irn_pinned(node));
5369 set_ia32_op_type(store, ia32_AddrModeD);
5370 set_ia32_ls_mode(store, mode_Iu);
5371 set_address(store, &addr);
5375 /* jmp rel <callee> */
5376 val = ia32_create_Immediate(NULL, 0, 0xE9);
5377 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5378 addr.index, addr.mem, val);
5379 set_irn_pinned(store, get_irn_pinned(node));
5380 set_ia32_op_type(store, ia32_AddrModeD);
5381 set_ia32_ls_mode(store, mode_Bu);
5382 set_address(store, &addr);
5386 trampoline = be_transform_node(ptr);
5388 /* the callee is typically an immediate */
5389 if (is_SymConst(callee)) {
5390 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5392 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5393 add_ia32_am_offs_int(rel, -10);
5395 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5397 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5398 addr.index, addr.mem, rel);
5399 set_irn_pinned(store, get_irn_pinned(node));
5400 set_ia32_op_type(store, ia32_AddrModeD);
5401 set_ia32_ls_mode(store, mode_Iu);
5402 set_address(store, &addr);
5407 return new_r_Tuple(new_block, 2, in);
5411 * Transform Builtin node.
5413 static ir_node *gen_Builtin(ir_node *node)
5415 ir_builtin_kind kind = get_Builtin_kind(node);
5419 return gen_trap(node);
5420 case ir_bk_debugbreak:
5421 return gen_debugbreak(node);
5422 case ir_bk_return_address:
5423 return gen_return_address(node);
5424 case ir_bk_frame_address:
5425 return gen_frame_address(node);
5426 case ir_bk_prefetch:
5427 return gen_prefetch(node);
5429 return gen_ffs(node);
5431 return gen_clz(node);
5433 return gen_ctz(node);
5435 return gen_parity(node);
5436 case ir_bk_popcount:
5437 return gen_popcount(node);
5439 return gen_bswap(node);
5441 return gen_outport(node);
5443 return gen_inport(node);
5444 case ir_bk_inner_trampoline:
5445 return gen_inner_trampoline(node);
5447 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5451 * Transform Proj(Builtin) node.
5453 static ir_node *gen_Proj_Builtin(ir_node *proj)
5455 ir_node *node = get_Proj_pred(proj);
5456 ir_node *new_node = be_transform_node(node);
5457 ir_builtin_kind kind = get_Builtin_kind(node);
5460 case ir_bk_return_address:
5461 case ir_bk_frame_address:
5466 case ir_bk_popcount:
5468 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5471 case ir_bk_debugbreak:
5472 case ir_bk_prefetch:
5474 assert(get_Proj_proj(proj) == pn_Builtin_M);
5477 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5478 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5480 assert(get_Proj_proj(proj) == pn_Builtin_M);
5481 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5483 case ir_bk_inner_trampoline:
5484 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5485 return get_Tuple_pred(new_node, 1);
5487 assert(get_Proj_proj(proj) == pn_Builtin_M);
5488 return get_Tuple_pred(new_node, 0);
5491 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5494 static ir_node *gen_be_IncSP(ir_node *node)
5496 ir_node *res = be_duplicate_node(node);
5497 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5503 * Transform the Projs from a be_Call.
5505 static ir_node *gen_Proj_be_Call(ir_node *node)
5507 ir_node *call = get_Proj_pred(node);
5508 ir_node *new_call = be_transform_node(call);
5509 dbg_info *dbgi = get_irn_dbg_info(node);
5510 long proj = get_Proj_proj(node);
5511 ir_mode *mode = get_irn_mode(node);
5514 if (proj == pn_be_Call_M_regular) {
5515 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5517 /* transform call modes */
5518 if (mode_is_data(mode)) {
5519 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5523 /* Map from be_Call to ia32_Call proj number */
5524 if (proj == pn_be_Call_sp) {
5525 proj = pn_ia32_Call_stack;
5526 } else if (proj == pn_be_Call_M_regular) {
5527 proj = pn_ia32_Call_M;
5529 arch_register_req_t const *const req = arch_get_register_req_out(node);
5530 int const n_outs = arch_irn_get_n_outs(new_call);
5533 assert(proj >= pn_be_Call_first_res);
5534 assert(req->type & arch_register_req_type_limited);
5536 for (i = 0; i < n_outs; ++i) {
5537 arch_register_req_t const *const new_req
5538 = arch_get_out_register_req(new_call, i);
5540 if (!(new_req->type & arch_register_req_type_limited) ||
5541 new_req->cls != req->cls ||
5542 *new_req->limited != *req->limited)
5551 res = new_rd_Proj(dbgi, new_call, mode, proj);
5553 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5555 case pn_ia32_Call_stack:
5556 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5559 case pn_ia32_Call_fpcw:
5560 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5568 * Transform the Projs from a Cmp.
5570 static ir_node *gen_Proj_Cmp(ir_node *node)
5572 /* this probably means not all mode_b nodes were lowered... */
5573 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5577 static ir_node *gen_Proj_ASM(ir_node *node)
5579 ir_mode *mode = get_irn_mode(node);
5580 ir_node *pred = get_Proj_pred(node);
5581 ir_node *new_pred = be_transform_node(pred);
5582 long pos = get_Proj_proj(node);
5584 if (mode == mode_M) {
5585 pos = arch_irn_get_n_outs(new_pred)-1;
5586 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5588 } else if (mode_is_float(mode)) {
5591 panic("unexpected proj mode at ASM");
5594 return new_r_Proj(new_pred, mode, pos);
5598 * Transform and potentially renumber Proj nodes.
5600 static ir_node *gen_Proj(ir_node *node)
5602 ir_node *pred = get_Proj_pred(node);
5605 switch (get_irn_opcode(pred)) {
5607 proj = get_Proj_proj(node);
5608 if (proj == pn_Store_M) {
5609 return be_transform_node(pred);
5611 panic("No idea how to transform proj->Store");
5614 return gen_Proj_Load(node);
5616 return gen_Proj_ASM(node);
5618 return gen_Proj_Builtin(node);
5620 return gen_Proj_Div(node);
5622 return gen_Proj_Mod(node);
5624 return gen_Proj_CopyB(node);
5626 return gen_Proj_be_SubSP(node);
5628 return gen_Proj_be_AddSP(node);
5630 return gen_Proj_be_Call(node);
5632 return gen_Proj_Cmp(node);
5634 proj = get_Proj_proj(node);
5636 case pn_Start_X_initial_exec: {
5637 ir_node *block = get_nodes_block(pred);
5638 ir_node *new_block = be_transform_node(block);
5639 dbg_info *dbgi = get_irn_dbg_info(node);
5640 /* we exchange the ProjX with a jump */
5641 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5649 if (is_ia32_l_FloattoLL(pred)) {
5650 return gen_Proj_l_FloattoLL(node);
5652 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5656 ir_mode *mode = get_irn_mode(node);
5657 if (ia32_mode_needs_gp_reg(mode)) {
5658 ir_node *new_pred = be_transform_node(pred);
5659 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5660 get_Proj_proj(node));
5661 new_proj->node_nr = node->node_nr;
5666 return be_duplicate_node(node);
5670 * Enters all transform functions into the generic pointer
5672 static void register_transformers(void)
5674 /* first clear the generic function pointer for all ops */
5675 be_start_transform_setup();
5677 be_set_transform_function(op_Add, gen_Add);
5678 be_set_transform_function(op_And, gen_And);
5679 be_set_transform_function(op_ASM, ia32_gen_ASM);
5680 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5681 be_set_transform_function(op_be_Call, gen_be_Call);
5682 be_set_transform_function(op_be_Copy, gen_be_Copy);
5683 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5684 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5685 be_set_transform_function(op_be_Return, gen_be_Return);
5686 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5687 be_set_transform_function(op_Builtin, gen_Builtin);
5688 be_set_transform_function(op_Cmp, gen_Cmp);
5689 be_set_transform_function(op_Cond, gen_Cond);
5690 be_set_transform_function(op_Const, gen_Const);
5691 be_set_transform_function(op_Conv, gen_Conv);
5692 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5693 be_set_transform_function(op_Div, gen_Div);
5694 be_set_transform_function(op_Eor, gen_Eor);
5695 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5696 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5697 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5698 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5699 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5700 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5701 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5702 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5703 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5704 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5705 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5706 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5707 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5708 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5709 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5710 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5711 be_set_transform_function(op_IJmp, gen_IJmp);
5712 be_set_transform_function(op_Jmp, gen_Jmp);
5713 be_set_transform_function(op_Load, gen_Load);
5714 be_set_transform_function(op_Minus, gen_Minus);
5715 be_set_transform_function(op_Mod, gen_Mod);
5716 be_set_transform_function(op_Mul, gen_Mul);
5717 be_set_transform_function(op_Mulh, gen_Mulh);
5718 be_set_transform_function(op_Mux, gen_Mux);
5719 be_set_transform_function(op_Not, gen_Not);
5720 be_set_transform_function(op_Or, gen_Or);
5721 be_set_transform_function(op_Phi, gen_Phi);
5722 be_set_transform_function(op_Proj, gen_Proj);
5723 be_set_transform_function(op_Rotl, gen_Rotl);
5724 be_set_transform_function(op_Shl, gen_Shl);
5725 be_set_transform_function(op_Shr, gen_Shr);
5726 be_set_transform_function(op_Shrs, gen_Shrs);
5727 be_set_transform_function(op_Store, gen_Store);
5728 be_set_transform_function(op_Sub, gen_Sub);
5729 be_set_transform_function(op_SymConst, gen_SymConst);
5730 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5734 * Pre-transform all unknown and noreg nodes.
5736 static void ia32_pretransform_node(void)
5738 ir_graph *irg = current_ir_graph;
5739 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5741 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5742 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5743 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5744 irg_data->get_eip = be_pre_transform_node(irg_data->get_eip);
5745 irg_data->fpu_trunc_mode = be_pre_transform_node(irg_data->fpu_trunc_mode);
5747 nomem = get_irg_no_mem(irg);
5748 noreg_GP = ia32_new_NoReg_gp(irg);
5752 * Post-process all calls if we are in SSE mode.
5753 * The ABI requires that the results are in st0, copy them
5754 * to a xmm register.
5756 static void postprocess_fp_call_results(void)
5760 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5761 ir_node *call = call_list[i];
5762 ir_type *mtp = call_types[i];
5765 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5766 ir_type *res_tp = get_method_res_type(mtp, j);
5767 ir_node *res, *new_res;
5768 const ir_edge_t *edge, *next;
5771 if (! is_atomic_type(res_tp)) {
5772 /* no floating point return */
5775 mode = get_type_mode(res_tp);
5776 if (! mode_is_float(mode)) {
5777 /* no floating point return */
5781 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5784 /* now patch the users */
5785 foreach_out_edge_safe(res, edge, next) {
5786 ir_node *succ = get_edge_src_irn(edge);
5789 if (be_is_Keep(succ))
5792 if (is_ia32_xStore(succ)) {
5793 /* an xStore can be patched into an vfst */
5794 dbg_info *db = get_irn_dbg_info(succ);
5795 ir_node *block = get_nodes_block(succ);
5796 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5797 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5798 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5799 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5800 ir_mode *mode = get_ia32_ls_mode(succ);
5802 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5803 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5804 if (is_ia32_use_frame(succ))
5805 set_ia32_use_frame(st);
5806 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5807 set_irn_pinned(st, get_irn_pinned(succ));
5808 set_ia32_op_type(st, ia32_AddrModeD);
5812 if (new_res == NULL) {
5813 dbg_info *db = get_irn_dbg_info(call);
5814 ir_node *block = get_nodes_block(call);
5815 ir_node *frame = get_irg_frame(current_ir_graph);
5816 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5817 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5818 ir_node *vfst, *xld, *new_mem;
5820 /* store st(0) on stack */
5821 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5822 set_ia32_op_type(vfst, ia32_AddrModeD);
5823 set_ia32_use_frame(vfst);
5825 /* load into SSE register */
5826 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5827 set_ia32_op_type(xld, ia32_AddrModeS);
5828 set_ia32_use_frame(xld);
5830 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5831 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5833 if (old_mem != NULL) {
5834 edges_reroute(old_mem, new_mem);
5838 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5845 /* do the transformation */
5846 void ia32_transform_graph(ir_graph *irg)
5850 register_transformers();
5851 initial_fpcw = NULL;
5852 ia32_no_pic_adjust = 0;
5854 old_initial_fpcw = be_get_initial_reg_value(irg, &ia32_registers[REG_FPCW]);
5856 be_timer_push(T_HEIGHTS);
5857 ia32_heights = heights_new(irg);
5858 be_timer_pop(T_HEIGHTS);
5859 ia32_calculate_non_address_mode_nodes(irg);
5861 /* the transform phase is not safe for CSE (yet) because several nodes get
5862 * attributes set after their creation */
5863 cse_last = get_opt_cse();
5866 call_list = NEW_ARR_F(ir_node *, 0);
5867 call_types = NEW_ARR_F(ir_type *, 0);
5868 be_transform_graph(irg, ia32_pretransform_node);
5870 if (ia32_cg_config.use_sse2)
5871 postprocess_fp_call_results();
5872 DEL_ARR_F(call_types);
5873 DEL_ARR_F(call_list);
5875 set_opt_cse(cse_last);
5877 ia32_free_non_address_mode_nodes();
5878 heights_free(ia32_heights);
5879 ia32_heights = NULL;
5882 void ia32_init_transform(void)
5884 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");