2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
50 #include "../benode.h"
51 #include "../besched.h"
53 #include "../beutil.h"
55 #include "../betranshlp.h"
58 #include "bearch_ia32_t.h"
59 #include "ia32_common_transform.h"
60 #include "ia32_nodes_attr.h"
61 #include "ia32_transform.h"
62 #include "ia32_new_nodes.h"
63 #include "ia32_dbg_stat.h"
64 #include "ia32_optimize.h"
65 #include "ia32_util.h"
66 #include "ia32_address_mode.h"
67 #include "ia32_architecture.h"
69 #include "gen_ia32_regalloc_if.h"
71 /* define this to construct SSE constants instead of load them */
72 #undef CONSTRUCT_SSE_CONST
75 #define SFP_SIGN "0x80000000"
76 #define DFP_SIGN "0x8000000000000000"
77 #define SFP_ABS "0x7FFFFFFF"
78 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
80 #define ULL_BIAS "18446744073709551616"
82 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
83 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
84 #define ENT_SFP_ABS "C_ia32_sfp_abs"
85 #define ENT_DFP_ABS "C_ia32_dfp_abs"
86 #define ENT_ULL_BIAS "C_ia32_ull_bias"
88 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
89 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
91 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
93 static ir_node *initial_fpcw = NULL;
94 int ia32_no_pic_adjust;
96 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
97 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
100 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
101 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
104 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
108 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
110 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
111 ir_node *base, ir_node *index, ir_node *mem);
113 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
114 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
117 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
119 static ir_node *create_immediate_or_transform(ir_node *node,
120 char immediate_constraint_type);
122 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
123 dbg_info *dbgi, ir_node *block,
124 ir_node *op, ir_node *orig_node);
126 /* its enough to have those once */
127 static ir_node *nomem, *noreg_GP;
129 /** a list to postprocess all calls */
130 static ir_node **call_list;
131 static ir_type **call_types;
133 /** Return non-zero is a node represents the 0 constant. */
134 static bool is_Const_0(ir_node *node)
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
148 return is_Const(node) && is_Const_all_one(node);
152 * returns true if constant can be created with a simple float command
154 static bool is_simple_x87_Const(ir_node *node)
156 ir_tarval *tv = get_Const_tarval(node);
157 if (tarval_is_null(tv) || tarval_is_one(tv))
160 /* TODO: match all the other float constants */
165 * returns true if constant can be created with a simple float command
167 static bool is_simple_sse_Const(ir_node *node)
169 ir_tarval *tv = get_Const_tarval(node);
170 ir_mode *mode = get_tarval_mode(tv);
175 if (tarval_is_null(tv)
176 #ifdef CONSTRUCT_SSE_CONST
181 #ifdef CONSTRUCT_SSE_CONST
182 if (mode == mode_D) {
183 unsigned val = get_tarval_sub_bits(tv, 0) |
184 (get_tarval_sub_bits(tv, 1) << 8) |
185 (get_tarval_sub_bits(tv, 2) << 16) |
186 (get_tarval_sub_bits(tv, 3) << 24);
188 /* lower 32bit are zero, really a 32bit constant */
191 #endif /* CONSTRUCT_SSE_CONST */
192 /* TODO: match all the other float constants */
197 * return NoREG or pic_base in case of PIC.
198 * This is necessary as base address for newly created symbols
200 static ir_node *get_symconst_base(void)
202 ir_graph *irg = current_ir_graph;
204 if (be_get_irg_options(irg)->pic) {
205 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
206 return arch_env->impl->get_pic_base(irg);
213 * Transforms a Const.
215 static ir_node *gen_Const(ir_node *node)
217 ir_node *old_block = get_nodes_block(node);
218 ir_node *block = be_transform_node(old_block);
219 dbg_info *dbgi = get_irn_dbg_info(node);
220 ir_mode *mode = get_irn_mode(node);
222 assert(is_Const(node));
224 if (mode_is_float(mode)) {
230 if (ia32_cg_config.use_sse2) {
231 ir_tarval *tv = get_Const_tarval(node);
232 if (tarval_is_null(tv)) {
233 load = new_bd_ia32_xZero(dbgi, block);
234 set_ia32_ls_mode(load, mode);
236 #ifdef CONSTRUCT_SSE_CONST
237 } else if (tarval_is_one(tv)) {
238 int cnst = mode == mode_F ? 26 : 55;
239 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
240 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
241 ir_node *pslld, *psrld;
243 load = new_bd_ia32_xAllOnes(dbgi, block);
244 set_ia32_ls_mode(load, mode);
245 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
246 set_ia32_ls_mode(pslld, mode);
247 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
248 set_ia32_ls_mode(psrld, mode);
250 #endif /* CONSTRUCT_SSE_CONST */
251 } else if (mode == mode_F) {
252 /* we can place any 32bit constant by using a movd gp, sse */
253 unsigned val = get_tarval_sub_bits(tv, 0) |
254 (get_tarval_sub_bits(tv, 1) << 8) |
255 (get_tarval_sub_bits(tv, 2) << 16) |
256 (get_tarval_sub_bits(tv, 3) << 24);
257 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
258 load = new_bd_ia32_xMovd(dbgi, block, cnst);
259 set_ia32_ls_mode(load, mode);
262 #ifdef CONSTRUCT_SSE_CONST
263 if (mode == mode_D) {
264 unsigned val = get_tarval_sub_bits(tv, 0) |
265 (get_tarval_sub_bits(tv, 1) << 8) |
266 (get_tarval_sub_bits(tv, 2) << 16) |
267 (get_tarval_sub_bits(tv, 3) << 24);
269 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
270 ir_node *cnst, *psllq;
272 /* fine, lower 32bit are zero, produce 32bit value */
273 val = get_tarval_sub_bits(tv, 4) |
274 (get_tarval_sub_bits(tv, 5) << 8) |
275 (get_tarval_sub_bits(tv, 6) << 16) |
276 (get_tarval_sub_bits(tv, 7) << 24);
277 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
278 load = new_bd_ia32_xMovd(dbgi, block, cnst);
279 set_ia32_ls_mode(load, mode);
280 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
281 set_ia32_ls_mode(psllq, mode);
286 #endif /* CONSTRUCT_SSE_CONST */
287 floatent = ia32_create_float_const_entity(node);
289 base = get_symconst_base();
290 load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
292 set_ia32_op_type(load, ia32_AddrModeS);
293 set_ia32_am_sc(load, floatent);
294 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
295 res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
298 if (is_Const_null(node)) {
299 load = new_bd_ia32_vfldz(dbgi, block);
301 set_ia32_ls_mode(load, mode);
302 } else if (is_Const_one(node)) {
303 load = new_bd_ia32_vfld1(dbgi, block);
305 set_ia32_ls_mode(load, mode);
310 floatent = ia32_create_float_const_entity(node);
311 /* create_float_const_ent is smart and sometimes creates
313 ls_mode = get_type_mode(get_entity_type(floatent));
314 base = get_symconst_base();
315 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
317 set_ia32_op_type(load, ia32_AddrModeS);
318 set_ia32_am_sc(load, floatent);
319 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
320 res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
323 #ifdef CONSTRUCT_SSE_CONST
325 #endif /* CONSTRUCT_SSE_CONST */
326 SET_IA32_ORIG_NODE(load, node);
328 be_dep_on_frame(load);
330 } else { /* non-float mode */
332 ir_tarval *tv = get_Const_tarval(node);
335 tv = tarval_convert_to(tv, mode_Iu);
337 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
339 panic("couldn't convert constant tarval (%+F)", node);
341 val = get_tarval_long(tv);
343 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
344 SET_IA32_ORIG_NODE(cnst, node);
346 be_dep_on_frame(cnst);
352 * Transforms a SymConst.
354 static ir_node *gen_SymConst(ir_node *node)
356 ir_node *old_block = get_nodes_block(node);
357 ir_node *block = be_transform_node(old_block);
358 dbg_info *dbgi = get_irn_dbg_info(node);
359 ir_mode *mode = get_irn_mode(node);
362 if (mode_is_float(mode)) {
363 if (ia32_cg_config.use_sse2)
364 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
366 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
367 set_ia32_am_sc(cnst, get_SymConst_entity(node));
368 set_ia32_use_frame(cnst);
372 if (get_SymConst_kind(node) != symconst_addr_ent) {
373 panic("backend only support symconst_addr_ent (at %+F)", node);
375 entity = get_SymConst_entity(node);
376 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
379 SET_IA32_ORIG_NODE(cnst, node);
381 be_dep_on_frame(cnst);
386 * Create a float type for the given mode and cache it.
388 * @param mode the mode for the float type (might be integer mode for SSE2 types)
389 * @param align alignment
391 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
397 if (mode == mode_Iu) {
398 static ir_type *int_Iu[16] = {NULL, };
400 if (int_Iu[align] == NULL) {
401 int_Iu[align] = tp = new_type_primitive(mode);
402 /* set the specified alignment */
403 set_type_alignment_bytes(tp, align);
405 return int_Iu[align];
406 } else if (mode == mode_Lu) {
407 static ir_type *int_Lu[16] = {NULL, };
409 if (int_Lu[align] == NULL) {
410 int_Lu[align] = tp = new_type_primitive(mode);
411 /* set the specified alignment */
412 set_type_alignment_bytes(tp, align);
414 return int_Lu[align];
415 } else if (mode == mode_F) {
416 static ir_type *float_F[16] = {NULL, };
418 if (float_F[align] == NULL) {
419 float_F[align] = tp = new_type_primitive(mode);
420 /* set the specified alignment */
421 set_type_alignment_bytes(tp, align);
423 return float_F[align];
424 } else if (mode == mode_D) {
425 static ir_type *float_D[16] = {NULL, };
427 if (float_D[align] == NULL) {
428 float_D[align] = tp = new_type_primitive(mode);
429 /* set the specified alignment */
430 set_type_alignment_bytes(tp, align);
432 return float_D[align];
434 static ir_type *float_E[16] = {NULL, };
436 if (float_E[align] == NULL) {
437 float_E[align] = tp = new_type_primitive(mode);
438 /* set the specified alignment */
439 set_type_alignment_bytes(tp, align);
441 return float_E[align];
446 * Create a float[2] array type for the given atomic type.
448 * @param tp the atomic type
450 static ir_type *ia32_create_float_array(ir_type *tp)
452 ir_mode *mode = get_type_mode(tp);
453 unsigned align = get_type_alignment_bytes(tp);
458 if (mode == mode_F) {
459 static ir_type *float_F[16] = {NULL, };
461 if (float_F[align] != NULL)
462 return float_F[align];
463 arr = float_F[align] = new_type_array(1, tp);
464 } else if (mode == mode_D) {
465 static ir_type *float_D[16] = {NULL, };
467 if (float_D[align] != NULL)
468 return float_D[align];
469 arr = float_D[align] = new_type_array(1, tp);
471 static ir_type *float_E[16] = {NULL, };
473 if (float_E[align] != NULL)
474 return float_E[align];
475 arr = float_E[align] = new_type_array(1, tp);
477 set_type_alignment_bytes(arr, align);
478 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
479 set_type_state(arr, layout_fixed);
483 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
484 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
486 static const struct {
487 const char *ent_name;
488 const char *cnst_str;
491 } names [ia32_known_const_max] = {
492 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
493 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
494 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
495 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
496 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
498 static ir_entity *ent_cache[ia32_known_const_max];
500 const char *ent_name, *cnst_str;
506 ent_name = names[kct].ent_name;
507 if (! ent_cache[kct]) {
508 cnst_str = names[kct].cnst_str;
510 switch (names[kct].mode) {
511 case 0: mode = mode_Iu; break;
512 case 1: mode = mode_Lu; break;
513 default: mode = mode_F; break;
515 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
516 tp = ia32_create_float_type(mode, names[kct].align);
518 if (kct == ia32_ULLBIAS)
519 tp = ia32_create_float_array(tp);
520 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
522 set_entity_ld_ident(ent, get_entity_ident(ent));
523 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
524 set_entity_visibility(ent, ir_visibility_private);
526 if (kct == ia32_ULLBIAS) {
527 ir_initializer_t *initializer = create_initializer_compound(2);
529 set_initializer_compound_value(initializer, 0,
530 create_initializer_tarval(get_mode_null(mode)));
531 set_initializer_compound_value(initializer, 1,
532 create_initializer_tarval(tv));
534 set_entity_initializer(ent, initializer);
536 set_entity_initializer(ent, create_initializer_tarval(tv));
539 /* cache the entry */
540 ent_cache[kct] = ent;
543 return ent_cache[kct];
547 * return true if the node is a Proj(Load) and could be used in source address
548 * mode for another node. Will return only true if the @p other node is not
549 * dependent on the memory of the Load (for binary operations use the other
550 * input here, for unary operations use NULL).
552 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
553 ir_node *other, ir_node *other2, match_flags_t flags)
558 /* float constants are always available */
559 if (is_Const(node)) {
560 ir_mode *mode = get_irn_mode(node);
561 if (mode_is_float(mode)) {
562 if (ia32_cg_config.use_sse2) {
563 if (is_simple_sse_Const(node))
566 if (is_simple_x87_Const(node))
569 if (get_irn_n_edges(node) > 1)
577 load = get_Proj_pred(node);
578 pn = get_Proj_proj(node);
579 if (!is_Load(load) || pn != pn_Load_res)
581 if (get_nodes_block(load) != block)
583 /* we only use address mode if we're the only user of the load */
584 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
586 /* in some edge cases with address mode we might reach the load normally
587 * and through some AM sequence, if it is already materialized then we
588 * can't create an AM node from it */
589 if (be_is_transformed(node))
592 /* don't do AM if other node inputs depend on the load (via mem-proj) */
593 if (other != NULL && ia32_prevents_AM(block, load, other))
596 if (other2 != NULL && ia32_prevents_AM(block, load, other2))
602 typedef struct ia32_address_mode_t ia32_address_mode_t;
603 struct ia32_address_mode_t {
608 ia32_op_type_t op_type;
612 unsigned commutative : 1;
613 unsigned ins_permuted : 1;
616 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
618 /* construct load address */
619 memset(addr, 0, sizeof(addr[0]));
620 ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
622 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
623 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
624 addr->mem = be_transform_node(mem);
627 static void build_address(ia32_address_mode_t *am, ir_node *node,
628 ia32_create_am_flags_t flags)
630 ia32_address_t *addr = &am->addr;
636 /* floating point immediates */
637 if (is_Const(node)) {
638 ir_entity *entity = ia32_create_float_const_entity(node);
639 addr->base = get_symconst_base();
640 addr->index = noreg_GP;
642 addr->symconst_ent = entity;
644 am->ls_mode = get_type_mode(get_entity_type(entity));
645 am->pinned = op_pin_state_floats;
649 load = get_Proj_pred(node);
650 ptr = get_Load_ptr(load);
651 mem = get_Load_mem(load);
652 new_mem = be_transform_node(mem);
653 am->pinned = get_irn_pinned(load);
654 am->ls_mode = get_Load_mode(load);
655 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
658 /* construct load address */
659 ia32_create_address_mode(addr, ptr, flags);
661 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
662 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
666 static void set_address(ir_node *node, const ia32_address_t *addr)
668 set_ia32_am_scale(node, addr->scale);
669 set_ia32_am_sc(node, addr->symconst_ent);
670 set_ia32_am_offs_int(node, addr->offset);
671 if (addr->symconst_sign)
672 set_ia32_am_sc_sign(node);
674 set_ia32_use_frame(node);
675 set_ia32_frame_ent(node, addr->frame_entity);
679 * Apply attributes of a given address mode to a node.
681 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
683 set_address(node, &am->addr);
685 set_ia32_op_type(node, am->op_type);
686 set_ia32_ls_mode(node, am->ls_mode);
687 if (am->pinned == op_pin_state_pinned) {
688 /* beware: some nodes are already pinned and did not allow to change the state */
689 if (get_irn_pinned(node) != op_pin_state_pinned)
690 set_irn_pinned(node, op_pin_state_pinned);
693 set_ia32_commutative(node);
697 * Check, if a given node is a Down-Conv, ie. a integer Conv
698 * from a mode with a mode with more bits to a mode with lesser bits.
699 * Moreover, we return only true if the node has not more than 1 user.
701 * @param node the node
702 * @return non-zero if node is a Down-Conv
704 static int is_downconv(const ir_node *node)
712 /* we only want to skip the conv when we're the only user
713 * (because this test is used in the context of address-mode selection
714 * and we don't want to use address mode for multiple users) */
715 if (get_irn_n_edges(node) > 1)
718 src_mode = get_irn_mode(get_Conv_op(node));
719 dest_mode = get_irn_mode(node);
721 ia32_mode_needs_gp_reg(src_mode) &&
722 ia32_mode_needs_gp_reg(dest_mode) &&
723 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
726 /** Skip all Down-Conv's on a given node and return the resulting node. */
727 ir_node *ia32_skip_downconv(ir_node *node)
729 while (is_downconv(node))
730 node = get_Conv_op(node);
735 static bool is_sameconv(ir_node *node)
743 /* we only want to skip the conv when we're the only user
744 * (because this test is used in the context of address-mode selection
745 * and we don't want to use address mode for multiple users) */
746 if (get_irn_n_edges(node) > 1)
749 src_mode = get_irn_mode(get_Conv_op(node));
750 dest_mode = get_irn_mode(node);
752 ia32_mode_needs_gp_reg(src_mode) &&
753 ia32_mode_needs_gp_reg(dest_mode) &&
754 get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
757 /** Skip all signedness convs */
758 static ir_node *ia32_skip_sameconv(ir_node *node)
760 while (is_sameconv(node))
761 node = get_Conv_op(node);
766 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
768 ir_mode *mode = get_irn_mode(node);
773 if (mode_is_signed(mode)) {
778 block = get_nodes_block(node);
779 dbgi = get_irn_dbg_info(node);
781 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
785 * matches operands of a node into ia32 addressing/operand modes. This covers
786 * usage of source address mode, immediates, operations with non 32-bit modes,
788 * The resulting data is filled into the @p am struct. block is the block
789 * of the node whose arguments are matched. op1, op2 are the first and second
790 * input that are matched (op1 may be NULL). other_op is another unrelated
791 * input that is not matched! but which is needed sometimes to check if AM
792 * for op1/op2 is legal.
793 * @p flags describes the supported modes of the operation in detail.
795 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
796 ir_node *op1, ir_node *op2, ir_node *other_op,
799 ia32_address_t *addr = &am->addr;
800 ir_mode *mode = get_irn_mode(op2);
801 int mode_bits = get_mode_size_bits(mode);
802 ir_node *new_op1, *new_op2;
804 unsigned commutative;
805 int use_am_and_immediates;
808 memset(am, 0, sizeof(am[0]));
810 commutative = (flags & match_commutative) != 0;
811 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
812 use_am = (flags & match_am) != 0;
813 use_immediate = (flags & match_immediate) != 0;
814 assert(!use_am_and_immediates || use_immediate);
817 assert(!commutative || op1 != NULL);
818 assert(use_am || !(flags & match_8bit_am));
819 assert(use_am || !(flags & match_16bit_am));
821 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
822 (mode_bits == 16 && !(flags & match_16bit_am))) {
826 /* we can simply skip downconvs for mode neutral nodes: the upper bits
827 * can be random for these operations */
828 if (flags & match_mode_neutral) {
829 op2 = ia32_skip_downconv(op2);
831 op1 = ia32_skip_downconv(op1);
834 op2 = ia32_skip_sameconv(op2);
836 op1 = ia32_skip_sameconv(op1);
840 /* match immediates. firm nodes are normalized: constants are always on the
843 if (!(flags & match_try_am) && use_immediate) {
844 new_op2 = ia32_try_create_Immediate(op2, 0);
847 if (new_op2 == NULL &&
848 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849 build_address(am, op2, ia32_create_am_normal);
850 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
851 if (mode_is_float(mode)) {
852 new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
856 am->op_type = ia32_AddrModeS;
857 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
859 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
861 build_address(am, op1, ia32_create_am_normal);
863 if (mode_is_float(mode)) {
864 noreg = ia32_new_NoReg_vfp(current_ir_graph);
869 if (new_op2 != NULL) {
872 new_op1 = be_transform_node(op2);
874 am->ins_permuted = true;
876 am->op_type = ia32_AddrModeS;
879 am->op_type = ia32_Normal;
881 if (flags & match_try_am) {
887 mode = get_irn_mode(op2);
888 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
889 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
891 new_op2 = create_upconv(op2, NULL);
892 am->ls_mode = mode_Iu;
894 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
896 new_op2 = be_transform_node(op2);
897 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
900 if (addr->base == NULL)
901 addr->base = noreg_GP;
902 if (addr->index == NULL)
903 addr->index = noreg_GP;
904 if (addr->mem == NULL)
907 am->new_op1 = new_op1;
908 am->new_op2 = new_op2;
909 am->commutative = commutative;
913 * "Fixes" a node that uses address mode by turning it into mode_T
914 * and returning a pn_ia32_res Proj.
916 * @param node the node
917 * @param am its address mode
919 * @return a Proj(pn_ia32_res) if a memory address mode is used,
922 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
927 if (am->mem_proj == NULL)
930 /* we have to create a mode_T so the old MemProj can attach to us */
931 mode = get_irn_mode(node);
932 load = get_Proj_pred(am->mem_proj);
934 be_set_transformed_node(load, node);
936 if (mode != mode_T) {
937 set_irn_mode(node, mode_T);
938 return new_rd_Proj(NULL, node, mode, pn_ia32_res);
945 * Construct a standard binary operation, set AM and immediate if required.
947 * @param node The original node for which the binop is created
948 * @param op1 The first operand
949 * @param op2 The second operand
950 * @param func The node constructor function
951 * @return The constructed ia32 node.
953 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
954 construct_binop_func *func, match_flags_t flags)
957 ir_node *block, *new_block, *new_node;
958 ia32_address_mode_t am;
959 ia32_address_t *addr = &am.addr;
961 block = get_nodes_block(node);
962 match_arguments(&am, block, op1, op2, NULL, flags);
964 dbgi = get_irn_dbg_info(node);
965 new_block = be_transform_node(block);
966 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
967 am.new_op1, am.new_op2);
968 set_am_attributes(new_node, &am);
969 /* we can't use source address mode anymore when using immediates */
970 if (!(flags & match_am_and_immediates) &&
971 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
972 set_ia32_am_support(new_node, ia32_am_none);
973 SET_IA32_ORIG_NODE(new_node, node);
975 new_node = fix_mem_proj(new_node, &am);
981 * Generic names for the inputs of an ia32 binary op.
984 n_ia32_l_binop_left, /**< ia32 left input */
985 n_ia32_l_binop_right, /**< ia32 right input */
986 n_ia32_l_binop_eflags /**< ia32 eflags input */
988 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Adc_left, n_Adc_left)
989 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Adc_right, n_Adc_right)
990 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Adc_eflags, n_Adc_eflags)
991 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Sbb_minuend, n_Sbb_minuend)
992 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
993 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Sbb_eflags, n_Sbb_eflags)
996 * Construct a binary operation which also consumes the eflags.
998 * @param node The node to transform
999 * @param func The node constructor function
1000 * @param flags The match flags
1001 * @return The constructor ia32 node
1003 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
1004 match_flags_t flags)
1006 ir_node *src_block = get_nodes_block(node);
1007 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
1008 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
1009 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1011 ir_node *block, *new_node, *new_eflags;
1012 ia32_address_mode_t am;
1013 ia32_address_t *addr = &am.addr;
1015 match_arguments(&am, src_block, op1, op2, eflags, flags);
1017 dbgi = get_irn_dbg_info(node);
1018 block = be_transform_node(src_block);
1019 new_eflags = be_transform_node(eflags);
1020 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
1021 am.new_op1, am.new_op2, new_eflags);
1022 set_am_attributes(new_node, &am);
1023 /* we can't use source address mode anymore when using immediates */
1024 if (!(flags & match_am_and_immediates) &&
1025 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
1026 set_ia32_am_support(new_node, ia32_am_none);
1027 SET_IA32_ORIG_NODE(new_node, node);
1029 new_node = fix_mem_proj(new_node, &am);
1034 static ir_node *get_fpcw(void)
1037 if (initial_fpcw != NULL)
1038 return initial_fpcw;
1040 fpcw = be_abi_get_ignore_irn(be_get_irg_abi(current_ir_graph),
1041 &ia32_registers[REG_FPCW]);
1042 initial_fpcw = be_transform_node(fpcw);
1044 return initial_fpcw;
1048 * Construct a standard binary operation, set AM and immediate if required.
1050 * @param op1 The first operand
1051 * @param op2 The second operand
1052 * @param func The node constructor function
1053 * @return The constructed ia32 node.
1055 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1056 construct_binop_float_func *func)
1058 ir_mode *mode = get_irn_mode(node);
1060 ir_node *block, *new_block, *new_node;
1061 ia32_address_mode_t am;
1062 ia32_address_t *addr = &am.addr;
1063 ia32_x87_attr_t *attr;
1064 /* All operations are considered commutative, because there are reverse
1066 match_flags_t flags = match_commutative;
1068 /* happens for div nodes... */
1069 if (mode == mode_T) {
1071 mode = get_Div_resmode(node);
1073 panic("can't determine mode");
1076 /* cannot use address mode with long double on x87 */
1077 if (get_mode_size_bits(mode) <= 64)
1080 block = get_nodes_block(node);
1081 match_arguments(&am, block, op1, op2, NULL, flags);
1083 dbgi = get_irn_dbg_info(node);
1084 new_block = be_transform_node(block);
1085 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1086 am.new_op1, am.new_op2, get_fpcw());
1087 set_am_attributes(new_node, &am);
1089 attr = get_ia32_x87_attr(new_node);
1090 attr->attr.data.ins_permuted = am.ins_permuted;
1092 SET_IA32_ORIG_NODE(new_node, node);
1094 new_node = fix_mem_proj(new_node, &am);
1100 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1102 * @param op1 The first operand
1103 * @param op2 The second operand
1104 * @param func The node constructor function
1105 * @return The constructed ia32 node.
1107 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1108 construct_shift_func *func,
1109 match_flags_t flags)
1112 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1114 assert(! mode_is_float(get_irn_mode(node)));
1115 assert(flags & match_immediate);
1116 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1118 if (flags & match_mode_neutral) {
1119 op1 = ia32_skip_downconv(op1);
1120 new_op1 = be_transform_node(op1);
1121 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1122 new_op1 = create_upconv(op1, node);
1124 new_op1 = be_transform_node(op1);
1127 /* the shift amount can be any mode that is bigger than 5 bits, since all
1128 * other bits are ignored anyway */
1129 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1130 ir_node *const op = get_Conv_op(op2);
1131 if (mode_is_float(get_irn_mode(op)))
1134 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1136 new_op2 = create_immediate_or_transform(op2, 0);
1138 dbgi = get_irn_dbg_info(node);
1139 block = get_nodes_block(node);
1140 new_block = be_transform_node(block);
1141 new_node = func(dbgi, new_block, new_op1, new_op2);
1142 SET_IA32_ORIG_NODE(new_node, node);
1144 /* lowered shift instruction may have a dependency operand, handle it here */
1145 if (get_irn_arity(node) == 3) {
1146 /* we have a dependency */
1147 ir_node* dep = get_irn_n(node, 2);
1148 if (get_irn_n_edges(dep) > 1) {
1149 /* ... which has at least one user other than 'node' */
1150 ir_node *new_dep = be_transform_node(dep);
1151 add_irn_dep(new_node, new_dep);
1160 * Construct a standard unary operation, set AM and immediate if required.
1162 * @param op The operand
1163 * @param func The node constructor function
1164 * @return The constructed ia32 node.
1166 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1167 match_flags_t flags)
1170 ir_node *block, *new_block, *new_op, *new_node;
1172 assert(flags == 0 || flags == match_mode_neutral);
1173 if (flags & match_mode_neutral) {
1174 op = ia32_skip_downconv(op);
1177 new_op = be_transform_node(op);
1178 dbgi = get_irn_dbg_info(node);
1179 block = get_nodes_block(node);
1180 new_block = be_transform_node(block);
1181 new_node = func(dbgi, new_block, new_op);
1183 SET_IA32_ORIG_NODE(new_node, node);
1188 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1189 ia32_address_t *addr)
1191 ir_node *base, *index, *res;
1197 base = be_transform_node(base);
1200 index = addr->index;
1201 if (index == NULL) {
1204 index = be_transform_node(index);
1207 res = new_bd_ia32_Lea(dbgi, block, base, index);
1208 set_address(res, addr);
1214 * Returns non-zero if a given address mode has a symbolic or
1215 * numerical offset != 0.
1217 static int am_has_immediates(const ia32_address_t *addr)
1219 return addr->offset != 0 || addr->symconst_ent != NULL
1220 || addr->frame_entity || addr->use_frame;
1224 * Creates an ia32 Add.
1226 * @return the created ia32 Add node
1228 static ir_node *gen_Add(ir_node *node)
1230 ir_mode *mode = get_irn_mode(node);
1231 ir_node *op1 = get_Add_left(node);
1232 ir_node *op2 = get_Add_right(node);
1234 ir_node *block, *new_block, *new_node, *add_immediate_op;
1235 ia32_address_t addr;
1236 ia32_address_mode_t am;
1238 if (mode_is_float(mode)) {
1239 if (ia32_cg_config.use_sse2)
1240 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1241 match_commutative | match_am);
1243 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1246 ia32_mark_non_am(node);
1248 op2 = ia32_skip_downconv(op2);
1249 op1 = ia32_skip_downconv(op1);
1253 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1254 * 1. Add with immediate -> Lea
1255 * 2. Add with possible source address mode -> Add
1256 * 3. Otherwise -> Lea
1258 memset(&addr, 0, sizeof(addr));
1259 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1260 add_immediate_op = NULL;
1262 dbgi = get_irn_dbg_info(node);
1263 block = get_nodes_block(node);
1264 new_block = be_transform_node(block);
1267 if (addr.base == NULL && addr.index == NULL) {
1268 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1269 addr.symconst_sign, 0, addr.offset);
1270 be_dep_on_frame(new_node);
1271 SET_IA32_ORIG_NODE(new_node, node);
1274 /* add with immediate? */
1275 if (addr.index == NULL) {
1276 add_immediate_op = addr.base;
1277 } else if (addr.base == NULL && addr.scale == 0) {
1278 add_immediate_op = addr.index;
1281 if (add_immediate_op != NULL) {
1282 if (!am_has_immediates(&addr)) {
1283 #ifdef DEBUG_libfirm
1284 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1287 return be_transform_node(add_immediate_op);
1290 new_node = create_lea_from_address(dbgi, new_block, &addr);
1291 SET_IA32_ORIG_NODE(new_node, node);
1295 /* test if we can use source address mode */
1296 match_arguments(&am, block, op1, op2, NULL, match_commutative
1297 | match_mode_neutral | match_am | match_immediate | match_try_am);
1299 /* construct an Add with source address mode */
1300 if (am.op_type == ia32_AddrModeS) {
1301 ia32_address_t *am_addr = &am.addr;
1302 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1303 am_addr->index, am_addr->mem, am.new_op1,
1305 set_am_attributes(new_node, &am);
1306 SET_IA32_ORIG_NODE(new_node, node);
1308 new_node = fix_mem_proj(new_node, &am);
1313 /* otherwise construct a lea */
1314 new_node = create_lea_from_address(dbgi, new_block, &addr);
1315 SET_IA32_ORIG_NODE(new_node, node);
1320 * Creates an ia32 Mul.
1322 * @return the created ia32 Mul node
1324 static ir_node *gen_Mul(ir_node *node)
1326 ir_node *op1 = get_Mul_left(node);
1327 ir_node *op2 = get_Mul_right(node);
1328 ir_mode *mode = get_irn_mode(node);
1330 if (mode_is_float(mode)) {
1331 if (ia32_cg_config.use_sse2)
1332 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1333 match_commutative | match_am);
1335 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1337 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1338 match_commutative | match_am | match_mode_neutral |
1339 match_immediate | match_am_and_immediates);
1343 * Creates an ia32 Mulh.
1344 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1345 * this result while Mul returns the lower 32 bit.
1347 * @return the created ia32 Mulh node
1349 static ir_node *gen_Mulh(ir_node *node)
1351 dbg_info *dbgi = get_irn_dbg_info(node);
1352 ir_node *op1 = get_Mulh_left(node);
1353 ir_node *op2 = get_Mulh_right(node);
1354 ir_mode *mode = get_irn_mode(node);
1356 ir_node *proj_res_high;
1358 if (get_mode_size_bits(mode) != 32) {
1359 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1362 if (mode_is_signed(mode)) {
1363 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1364 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1366 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1367 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1369 return proj_res_high;
1373 * Creates an ia32 And.
1375 * @return The created ia32 And node
1377 static ir_node *gen_And(ir_node *node)
1379 ir_node *op1 = get_And_left(node);
1380 ir_node *op2 = get_And_right(node);
1381 assert(! mode_is_float(get_irn_mode(node)));
1383 /* is it a zero extension? */
1384 if (is_Const(op2)) {
1385 ir_tarval *tv = get_Const_tarval(op2);
1386 long v = get_tarval_long(tv);
1388 if (v == 0xFF || v == 0xFFFF) {
1389 dbg_info *dbgi = get_irn_dbg_info(node);
1390 ir_node *block = get_nodes_block(node);
1397 assert(v == 0xFFFF);
1400 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1405 return gen_binop(node, op1, op2, new_bd_ia32_And,
1406 match_commutative | match_mode_neutral | match_am | match_immediate);
1412 * Creates an ia32 Or.
1414 * @return The created ia32 Or node
1416 static ir_node *gen_Or(ir_node *node)
1418 ir_node *op1 = get_Or_left(node);
1419 ir_node *op2 = get_Or_right(node);
1421 assert (! mode_is_float(get_irn_mode(node)));
1422 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1423 | match_mode_neutral | match_am | match_immediate);
1429 * Creates an ia32 Eor.
1431 * @return The created ia32 Eor node
1433 static ir_node *gen_Eor(ir_node *node)
1435 ir_node *op1 = get_Eor_left(node);
1436 ir_node *op2 = get_Eor_right(node);
1438 assert(! mode_is_float(get_irn_mode(node)));
1439 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1440 | match_mode_neutral | match_am | match_immediate);
1445 * Creates an ia32 Sub.
1447 * @return The created ia32 Sub node
1449 static ir_node *gen_Sub(ir_node *node)
1451 ir_node *op1 = get_Sub_left(node);
1452 ir_node *op2 = get_Sub_right(node);
1453 ir_mode *mode = get_irn_mode(node);
1455 if (mode_is_float(mode)) {
1456 if (ia32_cg_config.use_sse2)
1457 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1459 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1462 if (is_Const(op2)) {
1463 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1467 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1468 | match_am | match_immediate);
1471 static ir_node *transform_AM_mem(ir_node *const block,
1472 ir_node *const src_val,
1473 ir_node *const src_mem,
1474 ir_node *const am_mem)
1476 if (is_NoMem(am_mem)) {
1477 return be_transform_node(src_mem);
1478 } else if (is_Proj(src_val) &&
1480 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1481 /* avoid memory loop */
1483 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1484 ir_node *const ptr_pred = get_Proj_pred(src_val);
1485 int const arity = get_Sync_n_preds(src_mem);
1490 NEW_ARR_A(ir_node*, ins, arity + 1);
1492 /* NOTE: This sometimes produces dead-code because the old sync in
1493 * src_mem might not be used anymore, we should detect this case
1494 * and kill the sync... */
1495 for (i = arity - 1; i >= 0; --i) {
1496 ir_node *const pred = get_Sync_pred(src_mem, i);
1498 /* avoid memory loop */
1499 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1502 ins[n++] = be_transform_node(pred);
1505 if (n==1 && ins[0] == am_mem) {
1507 /* creating a new Sync and relying on CSE may fail,
1508 * if am_mem is a ProjM, which does not yet verify. */
1512 return new_r_Sync(block, n, ins);
1516 ins[0] = be_transform_node(src_mem);
1518 return new_r_Sync(block, 2, ins);
1523 * Create a 32bit to 64bit signed extension.
1525 * @param dbgi debug info
1526 * @param block the block where node nodes should be placed
1527 * @param val the value to extend
1528 * @param orig the original node
1530 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1531 ir_node *val, const ir_node *orig)
1536 if (ia32_cg_config.use_short_sex_eax) {
1537 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1538 be_dep_on_frame(pval);
1539 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1541 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1542 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1544 SET_IA32_ORIG_NODE(res, orig);
1549 * Generates an ia32 Div with additional infrastructure for the
1550 * register allocator if needed.
1552 static ir_node *create_Div(ir_node *node)
1554 dbg_info *dbgi = get_irn_dbg_info(node);
1555 ir_node *block = get_nodes_block(node);
1556 ir_node *new_block = be_transform_node(block);
1563 ir_node *sign_extension;
1564 ia32_address_mode_t am;
1565 ia32_address_t *addr = &am.addr;
1567 /* the upper bits have random contents for smaller modes */
1568 switch (get_irn_opcode(node)) {
1570 op1 = get_Div_left(node);
1571 op2 = get_Div_right(node);
1572 mem = get_Div_mem(node);
1573 mode = get_Div_resmode(node);
1576 op1 = get_Mod_left(node);
1577 op2 = get_Mod_right(node);
1578 mem = get_Mod_mem(node);
1579 mode = get_Mod_resmode(node);
1582 panic("invalid divmod node %+F", node);
1585 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1587 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1588 is the memory of the consumed address. We can have only the second op as address
1589 in Div nodes, so check only op2. */
1590 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1592 if (mode_is_signed(mode)) {
1593 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1594 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1595 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1597 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1598 be_dep_on_frame(sign_extension);
1600 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1601 addr->index, new_mem, am.new_op2,
1602 am.new_op1, sign_extension);
1605 set_irn_pinned(new_node, get_irn_pinned(node));
1607 set_am_attributes(new_node, &am);
1608 SET_IA32_ORIG_NODE(new_node, node);
1610 new_node = fix_mem_proj(new_node, &am);
1616 * Generates an ia32 Mod.
1618 static ir_node *gen_Mod(ir_node *node)
1620 return create_Div(node);
1624 * Generates an ia32 Div.
1626 static ir_node *gen_Div(ir_node *node)
1628 ir_mode *mode = get_Div_resmode(node);
1629 if (mode_is_float(mode)) {
1630 ir_node *op1 = get_Div_left(node);
1631 ir_node *op2 = get_Div_right(node);
1633 if (ia32_cg_config.use_sse2) {
1634 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1636 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1640 return create_Div(node);
1644 * Creates an ia32 Shl.
1646 * @return The created ia32 Shl node
1648 static ir_node *gen_Shl(ir_node *node)
1650 ir_node *left = get_Shl_left(node);
1651 ir_node *right = get_Shl_right(node);
1653 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1654 match_mode_neutral | match_immediate);
1658 * Creates an ia32 Shr.
1660 * @return The created ia32 Shr node
1662 static ir_node *gen_Shr(ir_node *node)
1664 ir_node *left = get_Shr_left(node);
1665 ir_node *right = get_Shr_right(node);
1667 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1673 * Creates an ia32 Sar.
1675 * @return The created ia32 Shrs node
1677 static ir_node *gen_Shrs(ir_node *node)
1679 ir_node *left = get_Shrs_left(node);
1680 ir_node *right = get_Shrs_right(node);
1682 if (is_Const(right)) {
1683 ir_tarval *tv = get_Const_tarval(right);
1684 long val = get_tarval_long(tv);
1686 /* this is a sign extension */
1687 dbg_info *dbgi = get_irn_dbg_info(node);
1688 ir_node *block = be_transform_node(get_nodes_block(node));
1689 ir_node *new_op = be_transform_node(left);
1691 return create_sex_32_64(dbgi, block, new_op, node);
1695 /* 8 or 16 bit sign extension? */
1696 if (is_Const(right) && is_Shl(left)) {
1697 ir_node *shl_left = get_Shl_left(left);
1698 ir_node *shl_right = get_Shl_right(left);
1699 if (is_Const(shl_right)) {
1700 ir_tarval *tv1 = get_Const_tarval(right);
1701 ir_tarval *tv2 = get_Const_tarval(shl_right);
1702 if (tv1 == tv2 && tarval_is_long(tv1)) {
1703 long val = get_tarval_long(tv1);
1704 if (val == 16 || val == 24) {
1705 dbg_info *dbgi = get_irn_dbg_info(node);
1706 ir_node *block = get_nodes_block(node);
1716 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1725 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1731 * Creates an ia32 Rol.
1733 * @param op1 The first operator
1734 * @param op2 The second operator
1735 * @return The created ia32 RotL node
1737 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1739 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1745 * Creates an ia32 Ror.
1746 * NOTE: There is no RotR with immediate because this would always be a RotL
1747 * "imm-mode_size_bits" which can be pre-calculated.
1749 * @param op1 The first operator
1750 * @param op2 The second operator
1751 * @return The created ia32 RotR node
1753 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1755 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1761 * Creates an ia32 RotR or RotL (depending on the found pattern).
1763 * @return The created ia32 RotL or RotR node
1765 static ir_node *gen_Rotl(ir_node *node)
1767 ir_node *op1 = get_Rotl_left(node);
1768 ir_node *op2 = get_Rotl_right(node);
1770 if (is_Minus(op2)) {
1771 return gen_Ror(node, op1, get_Minus_op(op2));
1774 return gen_Rol(node, op1, op2);
1780 * Transforms a Minus node.
1782 * @return The created ia32 Minus node
1784 static ir_node *gen_Minus(ir_node *node)
1786 ir_node *op = get_Minus_op(node);
1787 ir_node *block = be_transform_node(get_nodes_block(node));
1788 dbg_info *dbgi = get_irn_dbg_info(node);
1789 ir_mode *mode = get_irn_mode(node);
1794 if (mode_is_float(mode)) {
1795 ir_node *new_op = be_transform_node(op);
1796 if (ia32_cg_config.use_sse2) {
1797 /* TODO: non-optimal... if we have many xXors, then we should
1798 * rather create a load for the const and use that instead of
1799 * several AM nodes... */
1800 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1802 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1803 noreg_GP, nomem, new_op, noreg_xmm);
1805 size = get_mode_size_bits(mode);
1806 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1808 set_ia32_am_sc(new_node, ent);
1809 set_ia32_op_type(new_node, ia32_AddrModeS);
1810 set_ia32_ls_mode(new_node, mode);
1812 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1815 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1818 SET_IA32_ORIG_NODE(new_node, node);
1824 * Transforms a Not node.
1826 * @return The created ia32 Not node
1828 static ir_node *gen_Not(ir_node *node)
1830 ir_node *op = get_Not_op(node);
1832 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1833 assert (! mode_is_float(get_irn_mode(node)));
1835 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1838 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1839 bool negate, ir_node *node)
1841 ir_node *new_block = be_transform_node(block);
1842 ir_mode *mode = get_irn_mode(op);
1848 if (mode_is_float(mode)) {
1849 new_op = be_transform_node(op);
1851 if (ia32_cg_config.use_sse2) {
1852 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1853 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1854 noreg_GP, nomem, new_op, noreg_fp);
1856 size = get_mode_size_bits(mode);
1857 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1859 set_ia32_am_sc(new_node, ent);
1861 SET_IA32_ORIG_NODE(new_node, node);
1863 set_ia32_op_type(new_node, ia32_AddrModeS);
1864 set_ia32_ls_mode(new_node, mode);
1866 /* TODO, implement -Abs case */
1869 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1870 SET_IA32_ORIG_NODE(new_node, node);
1872 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1873 SET_IA32_ORIG_NODE(new_node, node);
1878 ir_node *sign_extension;
1880 if (get_mode_size_bits(mode) == 32) {
1881 new_op = be_transform_node(op);
1883 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1886 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1888 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1889 nomem, new_op, sign_extension);
1890 SET_IA32_ORIG_NODE(xorn, node);
1893 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1894 nomem, sign_extension, xorn);
1896 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1897 nomem, xorn, sign_extension);
1899 SET_IA32_ORIG_NODE(new_node, node);
1906 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1908 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1910 dbg_info *dbgi = get_irn_dbg_info(cmp);
1911 ir_node *block = get_nodes_block(cmp);
1912 ir_node *new_block = be_transform_node(block);
1913 ir_node *op1 = be_transform_node(x);
1914 ir_node *op2 = be_transform_node(n);
1916 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1919 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
1922 if (mode_is_float(mode)) {
1924 case ir_relation_equal: return ia32_cc_float_equal;
1925 case ir_relation_less: return ia32_cc_float_below;
1926 case ir_relation_less_equal: return ia32_cc_float_below_equal;
1927 case ir_relation_greater: return ia32_cc_float_above;
1928 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
1929 case ir_relation_less_greater: return ia32_cc_not_equal;
1930 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
1931 case ir_relation_unordered: return ia32_cc_parity;
1932 case ir_relation_unordered_equal: return ia32_cc_equal;
1933 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
1934 case ir_relation_unordered_less_equal:
1935 return ia32_cc_float_unordered_below_equal;
1936 case ir_relation_unordered_greater:
1937 return ia32_cc_float_unordered_above;
1938 case ir_relation_unordered_greater_equal:
1939 return ia32_cc_float_unordered_above_equal;
1940 case ir_relation_unordered_less_greater:
1941 return ia32_cc_float_not_equal;
1942 case ir_relation_false:
1943 case ir_relation_true:
1944 /* should we introduce a jump always/jump never? */
1947 panic("Unexpected float pnc");
1948 } else if (mode_is_signed(mode)) {
1950 case ir_relation_unordered_equal:
1951 case ir_relation_equal: return ia32_cc_equal;
1952 case ir_relation_unordered_less:
1953 case ir_relation_less: return ia32_cc_less;
1954 case ir_relation_unordered_less_equal:
1955 case ir_relation_less_equal: return ia32_cc_less_equal;
1956 case ir_relation_unordered_greater:
1957 case ir_relation_greater: return ia32_cc_greater;
1958 case ir_relation_unordered_greater_equal:
1959 case ir_relation_greater_equal: return ia32_cc_greater_equal;
1960 case ir_relation_unordered_less_greater:
1961 case ir_relation_less_greater: return ia32_cc_not_equal;
1962 case ir_relation_less_equal_greater:
1963 case ir_relation_unordered:
1964 case ir_relation_false:
1965 case ir_relation_true:
1966 /* introduce jump always/jump never? */
1969 panic("Unexpected pnc");
1972 case ir_relation_unordered_equal:
1973 case ir_relation_equal: return ia32_cc_equal;
1974 case ir_relation_unordered_less:
1975 case ir_relation_less: return ia32_cc_below;
1976 case ir_relation_unordered_less_equal:
1977 case ir_relation_less_equal: return ia32_cc_below_equal;
1978 case ir_relation_unordered_greater:
1979 case ir_relation_greater: return ia32_cc_above;
1980 case ir_relation_unordered_greater_equal:
1981 case ir_relation_greater_equal: return ia32_cc_above_equal;
1982 case ir_relation_unordered_less_greater:
1983 case ir_relation_less_greater: return ia32_cc_not_equal;
1984 case ir_relation_less_equal_greater:
1985 case ir_relation_unordered:
1986 case ir_relation_false:
1987 case ir_relation_true:
1988 /* introduce jump always/jump never? */
1991 panic("Unexpected pnc");
1995 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
1997 /* a mode_b value, we have to compare it against 0 */
1998 dbg_info *dbgi = get_irn_dbg_info(node);
1999 ir_node *new_block = be_transform_node(get_nodes_block(node));
2000 ir_node *new_op = be_transform_node(node);
2001 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2002 *cc_out = ia32_cc_not_equal;
2006 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2008 /* must have a Cmp as input */
2009 ir_relation relation = get_Cmp_relation(cmp);
2010 ir_relation possible;
2011 ir_node *l = get_Cmp_left(cmp);
2012 ir_node *r = get_Cmp_right(cmp);
2013 ir_mode *mode = get_irn_mode(l);
2016 /* check for bit-test */
2017 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2018 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2019 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2021 ir_node *la = get_And_left(l);
2022 ir_node *ra = get_And_right(l);
2029 ir_node *c = get_Shl_left(la);
2030 if (is_Const_1(c) && is_Const_0(r)) {
2031 /* (1 << n) & ra) */
2032 ir_node *n = get_Shl_right(la);
2033 flags = gen_bt(cmp, ra, n);
2034 /* the bit is copied into the CF flag */
2035 if (relation & ir_relation_equal)
2036 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2038 *cc_out = ia32_cc_below; /* test for CF=1 */
2044 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2045 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2046 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2047 * a predecessor node). So add the < bit */
2048 possible = ir_get_possible_cmp_relations(l, r);
2049 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2050 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2051 relation |= ir_relation_less_greater;
2053 /* just do a normal transformation of the Cmp */
2054 *cc_out = relation_to_condition_code(relation, mode);
2055 flags = be_transform_node(cmp);
2060 * Transform a node returning a "flag" result.
2062 * @param node the node to transform
2063 * @param cc_out the compare mode to use
2065 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2068 return get_flags_node_cmp(node, cc_out);
2069 assert(get_irn_mode(node) == mode_b);
2070 return get_flags_mode_b(node, cc_out);
2074 * Transforms a Load.
2076 * @return the created ia32 Load node
2078 static ir_node *gen_Load(ir_node *node)
2080 ir_node *old_block = get_nodes_block(node);
2081 ir_node *block = be_transform_node(old_block);
2082 ir_node *ptr = get_Load_ptr(node);
2083 ir_node *mem = get_Load_mem(node);
2084 ir_node *new_mem = be_transform_node(mem);
2085 dbg_info *dbgi = get_irn_dbg_info(node);
2086 ir_mode *mode = get_Load_mode(node);
2090 ia32_address_t addr;
2092 /* construct load address */
2093 memset(&addr, 0, sizeof(addr));
2094 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2101 base = be_transform_node(base);
2104 if (index == NULL) {
2107 index = be_transform_node(index);
2110 if (mode_is_float(mode)) {
2111 if (ia32_cg_config.use_sse2) {
2112 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2115 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2119 assert(mode != mode_b);
2121 /* create a conv node with address mode for smaller modes */
2122 if (get_mode_size_bits(mode) < 32) {
2123 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2124 new_mem, noreg_GP, mode);
2126 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2130 set_irn_pinned(new_node, get_irn_pinned(node));
2131 set_ia32_op_type(new_node, ia32_AddrModeS);
2132 set_ia32_ls_mode(new_node, mode);
2133 set_address(new_node, &addr);
2135 if (get_irn_pinned(node) == op_pin_state_floats) {
2136 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2137 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2138 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2139 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2142 SET_IA32_ORIG_NODE(new_node, node);
2144 be_dep_on_frame(new_node);
2148 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2149 ir_node *ptr, ir_node *other)
2156 /* we only use address mode if we're the only user of the load */
2157 if (get_irn_n_edges(node) > 1)
2160 load = get_Proj_pred(node);
2163 if (get_nodes_block(load) != block)
2166 /* store should have the same pointer as the load */
2167 if (get_Load_ptr(load) != ptr)
2170 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2171 if (other != NULL &&
2172 get_nodes_block(other) == block &&
2173 heights_reachable_in_block(ia32_heights, other, load)) {
2177 if (ia32_prevents_AM(block, load, mem))
2179 /* Store should be attached to the load via mem */
2180 assert(heights_reachable_in_block(ia32_heights, mem, load));
2185 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2186 ir_node *mem, ir_node *ptr, ir_mode *mode,
2187 construct_binop_dest_func *func,
2188 construct_binop_dest_func *func8bit,
2189 match_flags_t flags)
2191 ir_node *src_block = get_nodes_block(node);
2199 ia32_address_mode_t am;
2200 ia32_address_t *addr = &am.addr;
2201 memset(&am, 0, sizeof(am));
2203 assert(flags & match_immediate); /* there is no destam node without... */
2204 commutative = (flags & match_commutative) != 0;
2206 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2207 build_address(&am, op1, ia32_create_am_double_use);
2208 new_op = create_immediate_or_transform(op2, 0);
2209 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2210 build_address(&am, op2, ia32_create_am_double_use);
2211 new_op = create_immediate_or_transform(op1, 0);
2216 if (addr->base == NULL)
2217 addr->base = noreg_GP;
2218 if (addr->index == NULL)
2219 addr->index = noreg_GP;
2220 if (addr->mem == NULL)
2223 dbgi = get_irn_dbg_info(node);
2224 block = be_transform_node(src_block);
2225 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2227 if (get_mode_size_bits(mode) == 8) {
2228 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2230 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2232 set_address(new_node, addr);
2233 set_ia32_op_type(new_node, ia32_AddrModeD);
2234 set_ia32_ls_mode(new_node, mode);
2235 SET_IA32_ORIG_NODE(new_node, node);
2237 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2238 mem_proj = be_transform_node(am.mem_proj);
2239 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2244 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2245 ir_node *ptr, ir_mode *mode,
2246 construct_unop_dest_func *func)
2248 ir_node *src_block = get_nodes_block(node);
2254 ia32_address_mode_t am;
2255 ia32_address_t *addr = &am.addr;
2257 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2260 memset(&am, 0, sizeof(am));
2261 build_address(&am, op, ia32_create_am_double_use);
2263 dbgi = get_irn_dbg_info(node);
2264 block = be_transform_node(src_block);
2265 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2266 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2267 set_address(new_node, addr);
2268 set_ia32_op_type(new_node, ia32_AddrModeD);
2269 set_ia32_ls_mode(new_node, mode);
2270 SET_IA32_ORIG_NODE(new_node, node);
2272 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2273 mem_proj = be_transform_node(am.mem_proj);
2274 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2279 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2281 ir_mode *mode = get_irn_mode(node);
2282 ir_node *mux_true = get_Mux_true(node);
2283 ir_node *mux_false = get_Mux_false(node);
2291 ia32_condition_code_t cc;
2292 ia32_address_t addr;
2294 if (get_mode_size_bits(mode) != 8)
2297 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2299 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2305 cond = get_Mux_sel(node);
2306 flags = get_flags_node(cond, &cc);
2307 /* we can't handle the float special cases with SetM */
2308 if (cc & ia32_cc_additional_float_cases)
2311 cc = ia32_negate_condition_code(cc);
2313 build_address_ptr(&addr, ptr, mem);
2315 dbgi = get_irn_dbg_info(node);
2316 block = get_nodes_block(node);
2317 new_block = be_transform_node(block);
2318 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2319 addr.index, addr.mem, flags, cc);
2320 set_address(new_node, &addr);
2321 set_ia32_op_type(new_node, ia32_AddrModeD);
2322 set_ia32_ls_mode(new_node, mode);
2323 SET_IA32_ORIG_NODE(new_node, node);
2328 static ir_node *try_create_dest_am(ir_node *node)
2330 ir_node *val = get_Store_value(node);
2331 ir_node *mem = get_Store_mem(node);
2332 ir_node *ptr = get_Store_ptr(node);
2333 ir_mode *mode = get_irn_mode(val);
2334 unsigned bits = get_mode_size_bits(mode);
2339 /* handle only GP modes for now... */
2340 if (!ia32_mode_needs_gp_reg(mode))
2344 /* store must be the only user of the val node */
2345 if (get_irn_n_edges(val) > 1)
2347 /* skip pointless convs */
2349 ir_node *conv_op = get_Conv_op(val);
2350 ir_mode *pred_mode = get_irn_mode(conv_op);
2351 if (!ia32_mode_needs_gp_reg(pred_mode))
2353 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2361 /* value must be in the same block */
2362 if (get_nodes_block(node) != get_nodes_block(val))
2365 switch (get_irn_opcode(val)) {
2367 op1 = get_Add_left(val);
2368 op2 = get_Add_right(val);
2369 if (ia32_cg_config.use_incdec) {
2370 if (is_Const_1(op2)) {
2371 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2373 } else if (is_Const_Minus_1(op2)) {
2374 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2378 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2379 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2380 match_commutative | match_immediate);
2383 op1 = get_Sub_left(val);
2384 op2 = get_Sub_right(val);
2385 if (is_Const(op2)) {
2386 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2388 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2389 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2393 op1 = get_And_left(val);
2394 op2 = get_And_right(val);
2395 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2396 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2397 match_commutative | match_immediate);
2400 op1 = get_Or_left(val);
2401 op2 = get_Or_right(val);
2402 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2403 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2404 match_commutative | match_immediate);
2407 op1 = get_Eor_left(val);
2408 op2 = get_Eor_right(val);
2409 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2410 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2411 match_commutative | match_immediate);
2414 op1 = get_Shl_left(val);
2415 op2 = get_Shl_right(val);
2416 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2417 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2421 op1 = get_Shr_left(val);
2422 op2 = get_Shr_right(val);
2423 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2424 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2428 op1 = get_Shrs_left(val);
2429 op2 = get_Shrs_right(val);
2430 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2431 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2435 op1 = get_Rotl_left(val);
2436 op2 = get_Rotl_right(val);
2437 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2438 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2441 /* TODO: match ROR patterns... */
2443 new_node = try_create_SetMem(val, ptr, mem);
2447 op1 = get_Minus_op(val);
2448 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2451 /* should be lowered already */
2452 assert(mode != mode_b);
2453 op1 = get_Not_op(val);
2454 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2460 if (new_node != NULL) {
2461 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2462 get_irn_pinned(node) == op_pin_state_pinned) {
2463 set_irn_pinned(new_node, op_pin_state_pinned);
2470 static bool possible_int_mode_for_fp(ir_mode *mode)
2474 if (!mode_is_signed(mode))
2476 size = get_mode_size_bits(mode);
2477 if (size != 16 && size != 32)
2482 static int is_float_to_int_conv(const ir_node *node)
2484 ir_mode *mode = get_irn_mode(node);
2488 if (!possible_int_mode_for_fp(mode))
2493 conv_op = get_Conv_op(node);
2494 conv_mode = get_irn_mode(conv_op);
2496 if (!mode_is_float(conv_mode))
2503 * Transform a Store(floatConst) into a sequence of
2506 * @return the created ia32 Store node
2508 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2510 ir_mode *mode = get_irn_mode(cns);
2511 unsigned size = get_mode_size_bytes(mode);
2512 ir_tarval *tv = get_Const_tarval(cns);
2513 ir_node *block = get_nodes_block(node);
2514 ir_node *new_block = be_transform_node(block);
2515 ir_node *ptr = get_Store_ptr(node);
2516 ir_node *mem = get_Store_mem(node);
2517 dbg_info *dbgi = get_irn_dbg_info(node);
2521 ia32_address_t addr;
2523 assert(size % 4 == 0);
2526 build_address_ptr(&addr, ptr, mem);
2530 get_tarval_sub_bits(tv, ofs) |
2531 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2532 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2533 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2534 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2536 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2537 addr.index, addr.mem, imm);
2539 set_irn_pinned(new_node, get_irn_pinned(node));
2540 set_ia32_op_type(new_node, ia32_AddrModeD);
2541 set_ia32_ls_mode(new_node, mode_Iu);
2542 set_address(new_node, &addr);
2543 SET_IA32_ORIG_NODE(new_node, node);
2546 ins[i++] = new_node;
2551 } while (size != 0);
2554 return new_rd_Sync(dbgi, new_block, i, ins);
2561 * Generate a vfist or vfisttp instruction.
2563 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2564 ir_node *mem, ir_node *val, ir_node **fist)
2568 if (ia32_cg_config.use_fisttp) {
2569 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2570 if other users exists */
2571 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2572 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2573 be_new_Keep(block, 1, &value);
2575 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2578 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2581 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2587 * Transforms a general (no special case) Store.
2589 * @return the created ia32 Store node
2591 static ir_node *gen_general_Store(ir_node *node)
2593 ir_node *val = get_Store_value(node);
2594 ir_mode *mode = get_irn_mode(val);
2595 ir_node *block = get_nodes_block(node);
2596 ir_node *new_block = be_transform_node(block);
2597 ir_node *ptr = get_Store_ptr(node);
2598 ir_node *mem = get_Store_mem(node);
2599 dbg_info *dbgi = get_irn_dbg_info(node);
2600 ir_node *new_val, *new_node, *store;
2601 ia32_address_t addr;
2603 /* check for destination address mode */
2604 new_node = try_create_dest_am(node);
2605 if (new_node != NULL)
2608 /* construct store address */
2609 memset(&addr, 0, sizeof(addr));
2610 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2612 if (addr.base == NULL) {
2613 addr.base = noreg_GP;
2615 addr.base = be_transform_node(addr.base);
2618 if (addr.index == NULL) {
2619 addr.index = noreg_GP;
2621 addr.index = be_transform_node(addr.index);
2623 addr.mem = be_transform_node(mem);
2625 if (mode_is_float(mode)) {
2626 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2628 while (is_Conv(val) && mode == get_irn_mode(val)) {
2629 ir_node *op = get_Conv_op(val);
2630 if (!mode_is_float(get_irn_mode(op)))
2634 new_val = be_transform_node(val);
2635 if (ia32_cg_config.use_sse2) {
2636 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2637 addr.index, addr.mem, new_val);
2639 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2640 addr.index, addr.mem, new_val, mode);
2643 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2644 val = get_Conv_op(val);
2646 /* TODO: is this optimisation still necessary at all (middleend)? */
2647 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2648 while (is_Conv(val)) {
2649 ir_node *op = get_Conv_op(val);
2650 if (!mode_is_float(get_irn_mode(op)))
2652 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2656 new_val = be_transform_node(val);
2657 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2659 new_val = create_immediate_or_transform(val, 0);
2660 assert(mode != mode_b);
2662 if (get_mode_size_bits(mode) == 8) {
2663 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2664 addr.index, addr.mem, new_val);
2666 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2667 addr.index, addr.mem, new_val);
2672 set_irn_pinned(store, get_irn_pinned(node));
2673 set_ia32_op_type(store, ia32_AddrModeD);
2674 set_ia32_ls_mode(store, mode);
2676 set_address(store, &addr);
2677 SET_IA32_ORIG_NODE(store, node);
2683 * Transforms a Store.
2685 * @return the created ia32 Store node
2687 static ir_node *gen_Store(ir_node *node)
2689 ir_node *val = get_Store_value(node);
2690 ir_mode *mode = get_irn_mode(val);
2692 if (mode_is_float(mode) && is_Const(val)) {
2693 /* We can transform every floating const store
2694 into a sequence of integer stores.
2695 If the constant is already in a register,
2696 it would be better to use it, but we don't
2697 have this information here. */
2698 return gen_float_const_Store(node, val);
2700 return gen_general_Store(node);
2704 * Transforms a Switch.
2706 * @return the created ia32 SwitchJmp node
2708 static ir_node *create_Switch(ir_node *node)
2710 dbg_info *dbgi = get_irn_dbg_info(node);
2711 ir_node *block = be_transform_node(get_nodes_block(node));
2712 ir_node *sel = get_Cond_selector(node);
2713 ir_node *new_sel = be_transform_node(sel);
2714 long switch_min = LONG_MAX;
2715 long switch_max = LONG_MIN;
2716 long default_pn = get_Cond_default_proj(node);
2718 const ir_edge_t *edge;
2720 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2722 /* determine the smallest switch case value */
2723 foreach_out_edge(node, edge) {
2724 ir_node *proj = get_edge_src_irn(edge);
2725 long pn = get_Proj_proj(proj);
2726 if (pn == default_pn)
2729 if (pn < switch_min)
2731 if (pn > switch_max)
2735 if ((unsigned long) (switch_max - switch_min) > 128000) {
2736 panic("Size of switch %+F bigger than 128000", node);
2739 if (switch_min != 0) {
2740 /* if smallest switch case is not 0 we need an additional sub */
2741 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2742 add_ia32_am_offs_int(new_sel, -switch_min);
2743 set_ia32_op_type(new_sel, ia32_AddrModeS);
2745 SET_IA32_ORIG_NODE(new_sel, node);
2748 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2749 SET_IA32_ORIG_NODE(new_node, node);
2755 * Transform a Cond node.
2757 static ir_node *gen_Cond(ir_node *node)
2759 ir_node *block = get_nodes_block(node);
2760 ir_node *new_block = be_transform_node(block);
2761 dbg_info *dbgi = get_irn_dbg_info(node);
2762 ir_node *sel = get_Cond_selector(node);
2763 ir_mode *sel_mode = get_irn_mode(sel);
2764 ir_node *flags = NULL;
2766 ia32_condition_code_t cc;
2768 if (sel_mode != mode_b) {
2769 return create_Switch(node);
2772 /* we get flags from a Cmp */
2773 flags = get_flags_node(sel, &cc);
2775 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2776 SET_IA32_ORIG_NODE(new_node, node);
2782 * Transform a be_Copy.
2784 static ir_node *gen_be_Copy(ir_node *node)
2786 ir_node *new_node = be_duplicate_node(node);
2787 ir_mode *mode = get_irn_mode(new_node);
2789 if (ia32_mode_needs_gp_reg(mode)) {
2790 set_irn_mode(new_node, mode_Iu);
2796 static ir_node *create_Fucom(ir_node *node)
2798 dbg_info *dbgi = get_irn_dbg_info(node);
2799 ir_node *block = get_nodes_block(node);
2800 ir_node *new_block = be_transform_node(block);
2801 ir_node *left = get_Cmp_left(node);
2802 ir_node *new_left = be_transform_node(left);
2803 ir_node *right = get_Cmp_right(node);
2807 if (ia32_cg_config.use_fucomi) {
2808 new_right = be_transform_node(right);
2809 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2811 set_ia32_commutative(new_node);
2812 SET_IA32_ORIG_NODE(new_node, node);
2814 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2815 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2817 new_right = be_transform_node(right);
2818 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2821 set_ia32_commutative(new_node);
2823 SET_IA32_ORIG_NODE(new_node, node);
2825 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2826 SET_IA32_ORIG_NODE(new_node, node);
2832 static ir_node *create_Ucomi(ir_node *node)
2834 dbg_info *dbgi = get_irn_dbg_info(node);
2835 ir_node *src_block = get_nodes_block(node);
2836 ir_node *new_block = be_transform_node(src_block);
2837 ir_node *left = get_Cmp_left(node);
2838 ir_node *right = get_Cmp_right(node);
2840 ia32_address_mode_t am;
2841 ia32_address_t *addr = &am.addr;
2843 match_arguments(&am, src_block, left, right, NULL,
2844 match_commutative | match_am);
2846 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2847 addr->mem, am.new_op1, am.new_op2,
2849 set_am_attributes(new_node, &am);
2851 SET_IA32_ORIG_NODE(new_node, node);
2853 new_node = fix_mem_proj(new_node, &am);
2859 * returns true if it is assured, that the upper bits of a node are "clean"
2860 * which means for a 16 or 8 bit value, that the upper bits in the register
2861 * are 0 for unsigned and a copy of the last significant bit for signed
2864 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2866 assert(ia32_mode_needs_gp_reg(mode));
2867 if (get_mode_size_bits(mode) >= 32)
2870 if (is_Proj(transformed_node))
2871 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2873 switch (get_ia32_irn_opcode(transformed_node)) {
2874 case iro_ia32_Conv_I2I:
2875 case iro_ia32_Conv_I2I8Bit: {
2876 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2877 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2879 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2886 if (mode_is_signed(mode)) {
2887 return false; /* TODO handle signed modes */
2889 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2890 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2891 const ia32_immediate_attr_t *attr
2892 = get_ia32_immediate_attr_const(right);
2893 if (attr->symconst == 0 &&
2894 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2898 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2902 /* TODO too conservative if shift amount is constant */
2903 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2906 if (!mode_is_signed(mode)) {
2908 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2909 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2911 /* TODO if one is known to be zero extended, then || is sufficient */
2916 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2917 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2919 case iro_ia32_Const:
2920 case iro_ia32_Immediate: {
2921 const ia32_immediate_attr_t *attr =
2922 get_ia32_immediate_attr_const(transformed_node);
2923 if (mode_is_signed(mode)) {
2924 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2925 return shifted == 0 || shifted == -1;
2927 unsigned long shifted = (unsigned long)attr->offset;
2928 shifted >>= get_mode_size_bits(mode);
2929 return shifted == 0;
2939 * Generate code for a Cmp.
2941 static ir_node *gen_Cmp(ir_node *node)
2943 dbg_info *dbgi = get_irn_dbg_info(node);
2944 ir_node *block = get_nodes_block(node);
2945 ir_node *new_block = be_transform_node(block);
2946 ir_node *left = get_Cmp_left(node);
2947 ir_node *right = get_Cmp_right(node);
2948 ir_mode *cmp_mode = get_irn_mode(left);
2950 ia32_address_mode_t am;
2951 ia32_address_t *addr = &am.addr;
2953 if (mode_is_float(cmp_mode)) {
2954 if (ia32_cg_config.use_sse2) {
2955 return create_Ucomi(node);
2957 return create_Fucom(node);
2961 assert(ia32_mode_needs_gp_reg(cmp_mode));
2963 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2964 if (is_Const_0(right) &&
2966 get_irn_n_edges(left) == 1) {
2967 /* Test(and_left, and_right) */
2968 ir_node *and_left = get_And_left(left);
2969 ir_node *and_right = get_And_right(left);
2971 /* matze: code here used mode instead of cmd_mode, I think it is always
2972 * the same as cmp_mode, but I leave this here to see if this is really
2975 assert(get_irn_mode(and_left) == cmp_mode);
2977 match_arguments(&am, block, and_left, and_right, NULL,
2979 match_am | match_8bit_am | match_16bit_am |
2980 match_am_and_immediates | match_immediate);
2982 /* use 32bit compare mode if possible since the opcode is smaller */
2983 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2984 upper_bits_clean(am.new_op2, cmp_mode)) {
2985 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2988 if (get_mode_size_bits(cmp_mode) == 8) {
2989 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2990 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
2992 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2993 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
2996 /* Cmp(left, right) */
2997 match_arguments(&am, block, left, right, NULL,
2998 match_commutative | match_am | match_8bit_am |
2999 match_16bit_am | match_am_and_immediates |
3001 /* use 32bit compare mode if possible since the opcode is smaller */
3002 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3003 upper_bits_clean(am.new_op2, cmp_mode)) {
3004 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3007 if (get_mode_size_bits(cmp_mode) == 8) {
3008 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3009 addr->index, addr->mem, am.new_op1,
3010 am.new_op2, am.ins_permuted);
3012 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3013 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3016 set_am_attributes(new_node, &am);
3017 set_ia32_ls_mode(new_node, cmp_mode);
3019 SET_IA32_ORIG_NODE(new_node, node);
3021 new_node = fix_mem_proj(new_node, &am);
3026 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3027 ia32_condition_code_t cc)
3029 dbg_info *dbgi = get_irn_dbg_info(node);
3030 ir_node *block = get_nodes_block(node);
3031 ir_node *new_block = be_transform_node(block);
3032 ir_node *val_true = get_Mux_true(node);
3033 ir_node *val_false = get_Mux_false(node);
3035 ia32_address_mode_t am;
3036 ia32_address_t *addr;
3038 assert(ia32_cg_config.use_cmov);
3039 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3043 match_arguments(&am, block, val_false, val_true, flags,
3044 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3046 if (am.ins_permuted)
3047 cc = ia32_invert_condition_code(cc);
3049 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3050 addr->mem, am.new_op1, am.new_op2, new_flags,
3052 set_am_attributes(new_node, &am);
3054 SET_IA32_ORIG_NODE(new_node, node);
3056 new_node = fix_mem_proj(new_node, &am);
3062 * Creates a ia32 Setcc instruction.
3064 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3065 ir_node *flags, ia32_condition_code_t cc,
3068 ir_mode *mode = get_irn_mode(orig_node);
3071 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3072 SET_IA32_ORIG_NODE(new_node, orig_node);
3074 /* we might need to conv the result up */
3075 if (get_mode_size_bits(mode) > 8) {
3076 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3077 nomem, new_node, mode_Bu);
3078 SET_IA32_ORIG_NODE(new_node, orig_node);
3085 * Create instruction for an unsigned Difference or Zero.
3087 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3089 ir_mode *mode = get_irn_mode(psi);
3099 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3100 match_mode_neutral | match_am | match_immediate | match_two_users);
3102 block = get_nodes_block(new_node);
3104 if (is_Proj(new_node)) {
3105 sub = get_Proj_pred(new_node);
3108 set_irn_mode(sub, mode_T);
3109 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3111 assert(is_ia32_Sub(sub));
3112 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3114 dbgi = get_irn_dbg_info(psi);
3115 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3116 notn = new_bd_ia32_Not(dbgi, block, sbb);
3118 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3119 set_ia32_commutative(new_node);
3124 * Create an const array of two float consts.
3126 * @param c0 the first constant
3127 * @param c1 the second constant
3128 * @param new_mode IN/OUT for the mode of the constants, if NULL
3129 * smallest possible mode will be used
3131 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3134 ir_mode *mode = *new_mode;
3136 ir_initializer_t *initializer;
3137 ir_tarval *tv0 = get_Const_tarval(c0);
3138 ir_tarval *tv1 = get_Const_tarval(c1);
3141 /* detect the best mode for the constants */
3142 mode = get_tarval_mode(tv0);
3144 if (mode != mode_F) {
3145 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3146 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3148 tv0 = tarval_convert_to(tv0, mode);
3149 tv1 = tarval_convert_to(tv1, mode);
3150 } else if (mode != mode_D) {
3151 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3152 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3154 tv0 = tarval_convert_to(tv0, mode);
3155 tv1 = tarval_convert_to(tv1, mode);
3162 tp = ia32_create_float_type(mode, 4);
3163 tp = ia32_create_float_array(tp);
3165 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3167 set_entity_ld_ident(ent, get_entity_ident(ent));
3168 set_entity_visibility(ent, ir_visibility_private);
3169 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3171 initializer = create_initializer_compound(2);
3173 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3174 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3176 set_entity_initializer(ent, initializer);
3183 * Possible transformations for creating a Setcc.
3185 enum setcc_transform_insn {
3198 typedef struct setcc_transform {
3200 ia32_condition_code_t cc;
3202 enum setcc_transform_insn transform;
3206 } setcc_transform_t;
3209 * Setcc can only handle 0 and 1 result.
3210 * Find a transformation that creates 0 and 1 from
3213 static void find_const_transform(ia32_condition_code_t cc,
3214 ir_tarval *t, ir_tarval *f,
3215 setcc_transform_t *res)
3221 if (tarval_is_null(t)) {
3225 cc = ia32_negate_condition_code(cc);
3226 } else if (tarval_cmp(t, f) == ir_relation_less) {
3227 // now, t is the bigger one
3231 cc = ia32_negate_condition_code(cc);
3235 if (! tarval_is_null(f)) {
3236 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3239 res->steps[step].transform = SETCC_TR_ADD;
3241 if (t == tarval_bad)
3242 panic("constant subtract failed");
3243 if (! tarval_is_long(f))
3244 panic("tarval is not long");
3246 res->steps[step].val = get_tarval_long(f);
3248 f = tarval_sub(f, f, NULL);
3249 assert(tarval_is_null(f));
3252 if (tarval_is_one(t)) {
3253 res->steps[step].transform = SETCC_TR_SET;
3254 res->num_steps = ++step;
3258 if (tarval_is_minus_one(t)) {
3259 res->steps[step].transform = SETCC_TR_NEG;
3261 res->steps[step].transform = SETCC_TR_SET;
3262 res->num_steps = ++step;
3265 if (tarval_is_long(t)) {
3266 long v = get_tarval_long(t);
3268 res->steps[step].val = 0;
3271 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3273 res->steps[step].transform = SETCC_TR_LEAxx;
3274 res->steps[step].scale = 3; /* (a << 3) + a */
3277 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3279 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3280 res->steps[step].scale = 3; /* (a << 3) */
3283 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3285 res->steps[step].transform = SETCC_TR_LEAxx;
3286 res->steps[step].scale = 2; /* (a << 2) + a */
3289 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3291 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3292 res->steps[step].scale = 2; /* (a << 2) */
3295 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3297 res->steps[step].transform = SETCC_TR_LEAxx;
3298 res->steps[step].scale = 1; /* (a << 1) + a */
3301 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3303 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3304 res->steps[step].scale = 1; /* (a << 1) */
3307 res->num_steps = step;
3310 if (! tarval_is_single_bit(t)) {
3311 res->steps[step].transform = SETCC_TR_AND;
3312 res->steps[step].val = v;
3314 res->steps[step].transform = SETCC_TR_NEG;
3316 int v = get_tarval_lowest_bit(t);
3319 res->steps[step].transform = SETCC_TR_SHL;
3320 res->steps[step].scale = v;
3324 res->steps[step].transform = SETCC_TR_SET;
3325 res->num_steps = ++step;
3328 panic("tarval is not long");
3332 * Transforms a Mux node into some code sequence.
3334 * @return The transformed node.
3336 static ir_node *gen_Mux(ir_node *node)
3338 dbg_info *dbgi = get_irn_dbg_info(node);
3339 ir_node *block = get_nodes_block(node);
3340 ir_node *new_block = be_transform_node(block);
3341 ir_node *mux_true = get_Mux_true(node);
3342 ir_node *mux_false = get_Mux_false(node);
3343 ir_node *sel = get_Mux_sel(node);
3344 ir_mode *mode = get_irn_mode(node);
3348 ia32_condition_code_t cc;
3350 assert(get_irn_mode(sel) == mode_b);
3352 is_abs = be_mux_is_abs(sel, mux_true, mux_false);
3354 return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
3357 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3358 if (mode_is_float(mode)) {
3359 ir_node *cmp_left = get_Cmp_left(sel);
3360 ir_node *cmp_right = get_Cmp_right(sel);
3361 ir_relation relation = get_Cmp_relation(sel);
3363 if (ia32_cg_config.use_sse2) {
3364 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3365 if (cmp_left == mux_true && cmp_right == mux_false) {
3366 /* Mux(a <= b, a, b) => MIN */
3367 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3368 match_commutative | match_am | match_two_users);
3369 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3370 /* Mux(a <= b, b, a) => MAX */
3371 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3372 match_commutative | match_am | match_two_users);
3374 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3375 if (cmp_left == mux_true && cmp_right == mux_false) {
3376 /* Mux(a >= b, a, b) => MAX */
3377 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3378 match_commutative | match_am | match_two_users);
3379 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3380 /* Mux(a >= b, b, a) => MIN */
3381 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3382 match_commutative | match_am | match_two_users);
3387 if (is_Const(mux_true) && is_Const(mux_false)) {
3388 ia32_address_mode_t am;
3393 flags = get_flags_node(sel, &cc);
3394 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3396 if (ia32_cg_config.use_sse2) {
3397 /* cannot load from different mode on SSE */
3400 /* x87 can load any mode */
3404 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3406 switch (get_mode_size_bytes(new_mode)) {
3416 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3417 set_ia32_am_scale(new_node, 2);
3422 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3423 set_ia32_am_scale(new_node, 1);
3426 /* arg, shift 16 NOT supported */
3428 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3431 panic("Unsupported constant size");
3434 am.ls_mode = new_mode;
3435 am.addr.base = get_symconst_base();
3436 am.addr.index = new_node;
3437 am.addr.mem = nomem;
3439 am.addr.scale = scale;
3440 am.addr.use_frame = 0;
3441 am.addr.frame_entity = NULL;
3442 am.addr.symconst_sign = 0;
3443 am.mem_proj = am.addr.mem;
3444 am.op_type = ia32_AddrModeS;
3447 am.pinned = op_pin_state_floats;
3449 am.ins_permuted = false;
3451 if (ia32_cg_config.use_sse2)
3452 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3454 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3455 set_am_attributes(load, &am);
3457 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3459 panic("cannot transform floating point Mux");
3462 assert(ia32_mode_needs_gp_reg(mode));
3465 ir_node *cmp_left = get_Cmp_left(sel);
3466 ir_node *cmp_right = get_Cmp_right(sel);
3467 ir_relation relation = get_Cmp_relation(sel);
3468 ir_node *val_true = mux_true;
3469 ir_node *val_false = mux_false;
3471 if (is_Const(val_true) && is_Const_null(val_true)) {
3472 ir_node *tmp = val_false;
3473 val_false = val_true;
3475 relation = get_negated_relation(relation);
3477 if (is_Const_0(val_false) && is_Sub(val_true)) {
3478 if ((relation & ir_relation_greater)
3479 && get_Sub_left(val_true) == cmp_left
3480 && get_Sub_right(val_true) == cmp_right) {
3481 return create_doz(node, cmp_left, cmp_right);
3483 if ((relation & ir_relation_less)
3484 && get_Sub_left(val_true) == cmp_right
3485 && get_Sub_right(val_true) == cmp_left) {
3486 return create_doz(node, cmp_right, cmp_left);
3491 flags = get_flags_node(sel, &cc);
3493 if (is_Const(mux_true) && is_Const(mux_false)) {
3494 /* both are const, good */
3495 ir_tarval *tv_true = get_Const_tarval(mux_true);
3496 ir_tarval *tv_false = get_Const_tarval(mux_false);
3497 setcc_transform_t res;
3500 find_const_transform(cc, tv_true, tv_false, &res);
3502 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3505 switch (res.steps[step].transform) {
3507 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3508 add_ia32_am_offs_int(new_node, res.steps[step].val);
3510 case SETCC_TR_ADDxx:
3511 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3514 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3515 set_ia32_am_scale(new_node, res.steps[step].scale);
3516 set_ia32_am_offs_int(new_node, res.steps[step].val);
3518 case SETCC_TR_LEAxx:
3519 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3520 set_ia32_am_scale(new_node, res.steps[step].scale);
3521 set_ia32_am_offs_int(new_node, res.steps[step].val);
3524 imm = ia32_immediate_from_long(res.steps[step].scale);
3525 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3528 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3531 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3534 imm = ia32_immediate_from_long(res.steps[step].val);
3535 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3538 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3541 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3544 panic("unknown setcc transform");
3548 new_node = create_CMov(node, sel, flags, cc);
3556 * Create a conversion from x87 state register to general purpose.
3558 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3560 ir_node *block = be_transform_node(get_nodes_block(node));
3561 ir_node *op = get_Conv_op(node);
3562 ir_node *new_op = be_transform_node(op);
3563 ir_graph *irg = current_ir_graph;
3564 dbg_info *dbgi = get_irn_dbg_info(node);
3565 ir_mode *mode = get_irn_mode(node);
3566 ir_node *fist, *load, *mem;
3568 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3569 set_irn_pinned(fist, op_pin_state_floats);
3570 set_ia32_use_frame(fist);
3571 set_ia32_op_type(fist, ia32_AddrModeD);
3573 assert(get_mode_size_bits(mode) <= 32);
3574 /* exception we can only store signed 32 bit integers, so for unsigned
3575 we store a 64bit (signed) integer and load the lower bits */
3576 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3577 set_ia32_ls_mode(fist, mode_Ls);
3579 set_ia32_ls_mode(fist, mode_Is);
3581 SET_IA32_ORIG_NODE(fist, node);
3584 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3586 set_irn_pinned(load, op_pin_state_floats);
3587 set_ia32_use_frame(load);
3588 set_ia32_op_type(load, ia32_AddrModeS);
3589 set_ia32_ls_mode(load, mode_Is);
3590 if (get_ia32_ls_mode(fist) == mode_Ls) {
3591 ia32_attr_t *attr = get_ia32_attr(load);
3592 attr->data.need_64bit_stackent = 1;
3594 ia32_attr_t *attr = get_ia32_attr(load);
3595 attr->data.need_32bit_stackent = 1;
3597 SET_IA32_ORIG_NODE(load, node);
3599 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3603 * Creates a x87 strict Conv by placing a Store and a Load
3605 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3607 ir_node *block = get_nodes_block(node);
3608 ir_graph *irg = get_Block_irg(block);
3609 dbg_info *dbgi = get_irn_dbg_info(node);
3610 ir_node *frame = get_irg_frame(irg);
3611 ir_node *store, *load;
3614 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3615 set_ia32_use_frame(store);
3616 set_ia32_op_type(store, ia32_AddrModeD);
3617 SET_IA32_ORIG_NODE(store, node);
3619 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3620 set_ia32_use_frame(load);
3621 set_ia32_op_type(load, ia32_AddrModeS);
3622 SET_IA32_ORIG_NODE(load, node);
3624 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3628 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3629 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3631 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3633 func = get_mode_size_bits(mode) == 8 ?
3634 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3635 return func(dbgi, block, base, index, mem, val, mode);
3639 * Create a conversion from general purpose to x87 register
3641 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3643 ir_node *src_block = get_nodes_block(node);
3644 ir_node *block = be_transform_node(src_block);
3645 ir_graph *irg = get_Block_irg(block);
3646 dbg_info *dbgi = get_irn_dbg_info(node);
3647 ir_node *op = get_Conv_op(node);
3648 ir_node *new_op = NULL;
3650 ir_mode *store_mode;
3655 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3656 if (possible_int_mode_for_fp(src_mode)) {
3657 ia32_address_mode_t am;
3659 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3660 if (am.op_type == ia32_AddrModeS) {
3661 ia32_address_t *addr = &am.addr;
3663 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3664 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3666 set_am_attributes(fild, &am);
3667 SET_IA32_ORIG_NODE(fild, node);
3669 fix_mem_proj(fild, &am);
3674 if (new_op == NULL) {
3675 new_op = be_transform_node(op);
3678 mode = get_irn_mode(op);
3680 /* first convert to 32 bit signed if necessary */
3681 if (get_mode_size_bits(src_mode) < 32) {
3682 if (!upper_bits_clean(new_op, src_mode)) {
3683 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3684 SET_IA32_ORIG_NODE(new_op, node);
3689 assert(get_mode_size_bits(mode) == 32);
3692 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3694 set_ia32_use_frame(store);
3695 set_ia32_op_type(store, ia32_AddrModeD);
3696 set_ia32_ls_mode(store, mode_Iu);
3698 /* exception for 32bit unsigned, do a 64bit spill+load */
3699 if (!mode_is_signed(mode)) {
3702 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3704 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3705 noreg_GP, nomem, zero_const);
3707 set_ia32_use_frame(zero_store);
3708 set_ia32_op_type(zero_store, ia32_AddrModeD);
3709 add_ia32_am_offs_int(zero_store, 4);
3710 set_ia32_ls_mode(zero_store, mode_Iu);
3715 store = new_rd_Sync(dbgi, block, 2, in);
3716 store_mode = mode_Ls;
3718 store_mode = mode_Is;
3722 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3724 set_ia32_use_frame(fild);
3725 set_ia32_op_type(fild, ia32_AddrModeS);
3726 set_ia32_ls_mode(fild, store_mode);
3728 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3734 * Create a conversion from one integer mode into another one
3736 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3737 dbg_info *dbgi, ir_node *block, ir_node *op,
3740 ir_node *new_block = be_transform_node(block);
3742 ir_mode *smaller_mode;
3743 ia32_address_mode_t am;
3744 ia32_address_t *addr = &am.addr;
3747 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3748 smaller_mode = src_mode;
3750 smaller_mode = tgt_mode;
3753 #ifdef DEBUG_libfirm
3755 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3760 match_arguments(&am, block, NULL, op, NULL,
3761 match_am | match_8bit_am | match_16bit_am);
3763 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3764 /* unnecessary conv. in theory it shouldn't have been AM */
3765 assert(is_ia32_NoReg_GP(addr->base));
3766 assert(is_ia32_NoReg_GP(addr->index));
3767 assert(is_NoMem(addr->mem));
3768 assert(am.addr.offset == 0);
3769 assert(am.addr.symconst_ent == NULL);
3773 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3774 addr->mem, am.new_op2, smaller_mode);
3775 set_am_attributes(new_node, &am);
3776 /* match_arguments assume that out-mode = in-mode, this isn't true here
3778 set_ia32_ls_mode(new_node, smaller_mode);
3779 SET_IA32_ORIG_NODE(new_node, node);
3780 new_node = fix_mem_proj(new_node, &am);
3785 * Transforms a Conv node.
3787 * @return The created ia32 Conv node
3789 static ir_node *gen_Conv(ir_node *node)
3791 ir_node *block = get_nodes_block(node);
3792 ir_node *new_block = be_transform_node(block);
3793 ir_node *op = get_Conv_op(node);
3794 ir_node *new_op = NULL;
3795 dbg_info *dbgi = get_irn_dbg_info(node);
3796 ir_mode *src_mode = get_irn_mode(op);
3797 ir_mode *tgt_mode = get_irn_mode(node);
3798 int src_bits = get_mode_size_bits(src_mode);
3799 int tgt_bits = get_mode_size_bits(tgt_mode);
3800 ir_node *res = NULL;
3802 assert(!mode_is_int(src_mode) || src_bits <= 32);
3803 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3805 /* modeB -> X should already be lowered by the lower_mode_b pass */
3806 if (src_mode == mode_b) {
3807 panic("ConvB not lowered %+F", node);
3810 if (src_mode == tgt_mode) {
3811 if (get_Conv_strict(node)) {
3812 if (ia32_cg_config.use_sse2) {
3813 /* when we are in SSE mode, we can kill all strict no-op conversion */
3814 return be_transform_node(op);
3817 /* this should be optimized already, but who knows... */
3818 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3819 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3820 return be_transform_node(op);
3824 if (mode_is_float(src_mode)) {
3825 new_op = be_transform_node(op);
3826 /* we convert from float ... */
3827 if (mode_is_float(tgt_mode)) {
3829 if (ia32_cg_config.use_sse2) {
3830 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3831 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3833 set_ia32_ls_mode(res, tgt_mode);
3835 if (get_Conv_strict(node)) {
3836 /* if fp_no_float_fold is not set then we assume that we
3837 * don't have any float operations in a non
3838 * mode_float_arithmetic mode and can skip strict upconvs */
3839 if (src_bits < tgt_bits) {
3840 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3843 res = gen_x87_strict_conv(tgt_mode, new_op);
3844 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3848 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3853 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3854 if (ia32_cg_config.use_sse2) {
3855 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3857 set_ia32_ls_mode(res, src_mode);
3859 return gen_x87_fp_to_gp(node);
3863 /* we convert from int ... */
3864 if (mode_is_float(tgt_mode)) {
3866 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3867 if (ia32_cg_config.use_sse2) {
3868 new_op = be_transform_node(op);
3869 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3871 set_ia32_ls_mode(res, tgt_mode);
3873 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3874 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3875 res = gen_x87_gp_to_fp(node, src_mode);
3877 /* we need a strict-Conv, if the int mode has more bits than the
3879 if (float_mantissa < int_mantissa) {
3880 res = gen_x87_strict_conv(tgt_mode, res);
3881 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3885 } else if (tgt_mode == mode_b) {
3886 /* mode_b lowering already took care that we only have 0/1 values */
3887 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3888 src_mode, tgt_mode));
3889 return be_transform_node(op);
3892 if (src_bits == tgt_bits) {
3893 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3894 src_mode, tgt_mode));
3895 return be_transform_node(op);
3898 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3906 static ir_node *create_immediate_or_transform(ir_node *node,
3907 char immediate_constraint_type)
3909 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3910 if (new_node == NULL) {
3911 new_node = be_transform_node(node);
3917 * Transforms a FrameAddr into an ia32 Add.
3919 static ir_node *gen_be_FrameAddr(ir_node *node)
3921 ir_node *block = be_transform_node(get_nodes_block(node));
3922 ir_node *op = be_get_FrameAddr_frame(node);
3923 ir_node *new_op = be_transform_node(op);
3924 dbg_info *dbgi = get_irn_dbg_info(node);
3927 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3928 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3929 set_ia32_use_frame(new_node);
3931 SET_IA32_ORIG_NODE(new_node, node);
3937 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3939 static ir_node *gen_be_Return(ir_node *node)
3941 ir_graph *irg = current_ir_graph;
3942 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3943 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3944 ir_entity *ent = get_irg_entity(irg);
3945 ir_type *tp = get_entity_type(ent);
3950 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3951 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3953 int pn_ret_val, pn_ret_mem, arity, i;
3955 assert(ret_val != NULL);
3956 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3957 return be_duplicate_node(node);
3960 res_type = get_method_res_type(tp, 0);
3962 if (! is_Primitive_type(res_type)) {
3963 return be_duplicate_node(node);
3966 mode = get_type_mode(res_type);
3967 if (! mode_is_float(mode)) {
3968 return be_duplicate_node(node);
3971 assert(get_method_n_ress(tp) == 1);
3973 pn_ret_val = get_Proj_proj(ret_val);
3974 pn_ret_mem = get_Proj_proj(ret_mem);
3976 /* get the Barrier */
3977 barrier = get_Proj_pred(ret_val);
3979 /* get result input of the Barrier */
3980 ret_val = get_irn_n(barrier, pn_ret_val);
3981 new_ret_val = be_transform_node(ret_val);
3983 /* get memory input of the Barrier */
3984 ret_mem = get_irn_n(barrier, pn_ret_mem);
3985 new_ret_mem = be_transform_node(ret_mem);
3987 frame = get_irg_frame(irg);
3989 dbgi = get_irn_dbg_info(barrier);
3990 block = be_transform_node(get_nodes_block(barrier));
3992 /* store xmm0 onto stack */
3993 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3994 new_ret_mem, new_ret_val);
3995 set_ia32_ls_mode(sse_store, mode);
3996 set_ia32_op_type(sse_store, ia32_AddrModeD);
3997 set_ia32_use_frame(sse_store);
3999 /* load into x87 register */
4000 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4001 set_ia32_op_type(fld, ia32_AddrModeS);
4002 set_ia32_use_frame(fld);
4004 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4005 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4007 /* create a new barrier */
4008 arity = get_irn_arity(barrier);
4009 in = ALLOCAN(ir_node*, arity);
4010 for (i = 0; i < arity; ++i) {
4013 if (i == pn_ret_val) {
4015 } else if (i == pn_ret_mem) {
4018 ir_node *in = get_irn_n(barrier, i);
4019 new_in = be_transform_node(in);
4024 new_barrier = new_ir_node(dbgi, irg, block,
4025 get_irn_op(barrier), get_irn_mode(barrier),
4027 copy_node_attr(irg, barrier, new_barrier);
4028 be_duplicate_deps(barrier, new_barrier);
4029 be_set_transformed_node(barrier, new_barrier);
4031 /* transform normally */
4032 return be_duplicate_node(node);
4036 * Transform a be_AddSP into an ia32_SubSP.
4038 static ir_node *gen_be_AddSP(ir_node *node)
4040 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4041 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4043 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4044 match_am | match_immediate);
4048 * Transform a be_SubSP into an ia32_AddSP
4050 static ir_node *gen_be_SubSP(ir_node *node)
4052 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4053 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4055 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4056 match_am | match_immediate);
4060 * Change some phi modes
4062 static ir_node *gen_Phi(ir_node *node)
4064 const arch_register_req_t *req;
4065 ir_node *block = be_transform_node(get_nodes_block(node));
4066 ir_graph *irg = current_ir_graph;
4067 dbg_info *dbgi = get_irn_dbg_info(node);
4068 ir_mode *mode = get_irn_mode(node);
4071 if (ia32_mode_needs_gp_reg(mode)) {
4072 /* we shouldn't have any 64bit stuff around anymore */
4073 assert(get_mode_size_bits(mode) <= 32);
4074 /* all integer operations are on 32bit registers now */
4076 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4077 } else if (mode_is_float(mode)) {
4078 if (ia32_cg_config.use_sse2) {
4080 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4083 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4086 req = arch_no_register_req;
4089 /* phi nodes allow loops, so we use the old arguments for now
4090 * and fix this later */
4091 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4092 get_irn_in(node) + 1);
4093 copy_node_attr(irg, node, phi);
4094 be_duplicate_deps(node, phi);
4096 arch_set_out_register_req(phi, 0, req);
4098 be_enqueue_preds(node);
4103 static ir_node *gen_Jmp(ir_node *node)
4105 ir_node *block = get_nodes_block(node);
4106 ir_node *new_block = be_transform_node(block);
4107 dbg_info *dbgi = get_irn_dbg_info(node);
4110 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4111 SET_IA32_ORIG_NODE(new_node, node);
4119 static ir_node *gen_IJmp(ir_node *node)
4121 ir_node *block = get_nodes_block(node);
4122 ir_node *new_block = be_transform_node(block);
4123 dbg_info *dbgi = get_irn_dbg_info(node);
4124 ir_node *op = get_IJmp_target(node);
4126 ia32_address_mode_t am;
4127 ia32_address_t *addr = &am.addr;
4129 assert(get_irn_mode(op) == mode_P);
4131 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4133 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4134 addr->mem, am.new_op2);
4135 set_am_attributes(new_node, &am);
4136 SET_IA32_ORIG_NODE(new_node, node);
4138 new_node = fix_mem_proj(new_node, &am);
4143 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4145 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4146 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4148 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4149 match_immediate | match_mode_neutral);
4152 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4154 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4155 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4156 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4160 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4162 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4163 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4164 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4168 static ir_node *gen_ia32_l_Add(ir_node *node)
4170 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4171 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4172 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4173 match_commutative | match_am | match_immediate |
4174 match_mode_neutral);
4176 if (is_Proj(lowered)) {
4177 lowered = get_Proj_pred(lowered);
4179 assert(is_ia32_Add(lowered));
4180 set_irn_mode(lowered, mode_T);
4186 static ir_node *gen_ia32_l_Adc(ir_node *node)
4188 return gen_binop_flags(node, new_bd_ia32_Adc,
4189 match_commutative | match_am | match_immediate |
4190 match_mode_neutral);
4194 * Transforms a l_MulS into a "real" MulS node.
4196 * @return the created ia32 Mul node
4198 static ir_node *gen_ia32_l_Mul(ir_node *node)
4200 ir_node *left = get_binop_left(node);
4201 ir_node *right = get_binop_right(node);
4203 return gen_binop(node, left, right, new_bd_ia32_Mul,
4204 match_commutative | match_am | match_mode_neutral);
4208 * Transforms a l_IMulS into a "real" IMul1OPS node.
4210 * @return the created ia32 IMul1OP node
4212 static ir_node *gen_ia32_l_IMul(ir_node *node)
4214 ir_node *left = get_binop_left(node);
4215 ir_node *right = get_binop_right(node);
4217 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4218 match_commutative | match_am | match_mode_neutral);
4221 static ir_node *gen_ia32_l_Sub(ir_node *node)
4223 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4224 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4225 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4226 match_am | match_immediate | match_mode_neutral);
4228 if (is_Proj(lowered)) {
4229 lowered = get_Proj_pred(lowered);
4231 assert(is_ia32_Sub(lowered));
4232 set_irn_mode(lowered, mode_T);
4238 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4240 return gen_binop_flags(node, new_bd_ia32_Sbb,
4241 match_am | match_immediate | match_mode_neutral);
4245 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4246 * op1 - target to be shifted
4247 * op2 - contains bits to be shifted into target
4249 * Only op3 can be an immediate.
4251 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4252 ir_node *low, ir_node *count)
4254 ir_node *block = get_nodes_block(node);
4255 ir_node *new_block = be_transform_node(block);
4256 dbg_info *dbgi = get_irn_dbg_info(node);
4257 ir_node *new_high = be_transform_node(high);
4258 ir_node *new_low = be_transform_node(low);
4262 /* the shift amount can be any mode that is bigger than 5 bits, since all
4263 * other bits are ignored anyway */
4264 while (is_Conv(count) &&
4265 get_irn_n_edges(count) == 1 &&
4266 mode_is_int(get_irn_mode(count))) {
4267 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4268 count = get_Conv_op(count);
4270 new_count = create_immediate_or_transform(count, 0);
4272 if (is_ia32_l_ShlD(node)) {
4273 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4276 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4279 SET_IA32_ORIG_NODE(new_node, node);
4284 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4286 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4287 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4288 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4289 return gen_lowered_64bit_shifts(node, high, low, count);
4292 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4294 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4295 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4296 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4297 return gen_lowered_64bit_shifts(node, high, low, count);
4300 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4302 ir_node *src_block = get_nodes_block(node);
4303 ir_node *block = be_transform_node(src_block);
4304 ir_graph *irg = current_ir_graph;
4305 dbg_info *dbgi = get_irn_dbg_info(node);
4306 ir_node *frame = get_irg_frame(irg);
4307 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4308 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4309 ir_node *new_val_low = be_transform_node(val_low);
4310 ir_node *new_val_high = be_transform_node(val_high);
4312 ir_node *sync, *fild, *res;
4313 ir_node *store_low, *store_high;
4315 if (ia32_cg_config.use_sse2) {
4316 panic("ia32_l_LLtoFloat not implemented for SSE2");
4320 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4322 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4324 SET_IA32_ORIG_NODE(store_low, node);
4325 SET_IA32_ORIG_NODE(store_high, node);
4327 set_ia32_use_frame(store_low);
4328 set_ia32_use_frame(store_high);
4329 set_ia32_op_type(store_low, ia32_AddrModeD);
4330 set_ia32_op_type(store_high, ia32_AddrModeD);
4331 set_ia32_ls_mode(store_low, mode_Iu);
4332 set_ia32_ls_mode(store_high, mode_Is);
4333 add_ia32_am_offs_int(store_high, 4);
4337 sync = new_rd_Sync(dbgi, block, 2, in);
4340 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4342 set_ia32_use_frame(fild);
4343 set_ia32_op_type(fild, ia32_AddrModeS);
4344 set_ia32_ls_mode(fild, mode_Ls);
4346 SET_IA32_ORIG_NODE(fild, node);
4348 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4350 if (! mode_is_signed(get_irn_mode(val_high))) {
4351 ia32_address_mode_t am;
4353 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4356 am.addr.base = get_symconst_base();
4357 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4358 am.addr.mem = nomem;
4361 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4362 am.addr.use_frame = 0;
4363 am.addr.frame_entity = NULL;
4364 am.addr.symconst_sign = 0;
4365 am.ls_mode = mode_F;
4366 am.mem_proj = nomem;
4367 am.op_type = ia32_AddrModeS;
4369 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4370 am.pinned = op_pin_state_floats;
4372 am.ins_permuted = false;
4374 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4375 am.new_op1, am.new_op2, get_fpcw());
4376 set_am_attributes(fadd, &am);
4378 set_irn_mode(fadd, mode_T);
4379 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4384 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4386 ir_node *src_block = get_nodes_block(node);
4387 ir_node *block = be_transform_node(src_block);
4388 ir_graph *irg = get_Block_irg(block);
4389 dbg_info *dbgi = get_irn_dbg_info(node);
4390 ir_node *frame = get_irg_frame(irg);
4391 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4392 ir_node *new_val = be_transform_node(val);
4393 ir_node *fist, *mem;
4395 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4396 SET_IA32_ORIG_NODE(fist, node);
4397 set_ia32_use_frame(fist);
4398 set_ia32_op_type(fist, ia32_AddrModeD);
4399 set_ia32_ls_mode(fist, mode_Ls);
4404 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4406 ir_node *block = be_transform_node(get_nodes_block(node));
4407 ir_graph *irg = get_Block_irg(block);
4408 ir_node *pred = get_Proj_pred(node);
4409 ir_node *new_pred = be_transform_node(pred);
4410 ir_node *frame = get_irg_frame(irg);
4411 dbg_info *dbgi = get_irn_dbg_info(node);
4412 long pn = get_Proj_proj(node);
4417 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4418 SET_IA32_ORIG_NODE(load, node);
4419 set_ia32_use_frame(load);
4420 set_ia32_op_type(load, ia32_AddrModeS);
4421 set_ia32_ls_mode(load, mode_Iu);
4422 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4423 * 32 bit from it with this particular load */
4424 attr = get_ia32_attr(load);
4425 attr->data.need_64bit_stackent = 1;
4427 if (pn == pn_ia32_l_FloattoLL_res_high) {
4428 add_ia32_am_offs_int(load, 4);
4430 assert(pn == pn_ia32_l_FloattoLL_res_low);
4433 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4439 * Transform the Projs of an AddSP.
4441 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4443 ir_node *pred = get_Proj_pred(node);
4444 ir_node *new_pred = be_transform_node(pred);
4445 dbg_info *dbgi = get_irn_dbg_info(node);
4446 long proj = get_Proj_proj(node);
4448 if (proj == pn_be_AddSP_sp) {
4449 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4450 pn_ia32_SubSP_stack);
4451 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4453 } else if (proj == pn_be_AddSP_res) {
4454 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4455 pn_ia32_SubSP_addr);
4456 } else if (proj == pn_be_AddSP_M) {
4457 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4460 panic("No idea how to transform proj->AddSP");
4464 * Transform the Projs of a SubSP.
4466 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4468 ir_node *pred = get_Proj_pred(node);
4469 ir_node *new_pred = be_transform_node(pred);
4470 dbg_info *dbgi = get_irn_dbg_info(node);
4471 long proj = get_Proj_proj(node);
4473 if (proj == pn_be_SubSP_sp) {
4474 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4475 pn_ia32_AddSP_stack);
4476 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4478 } else if (proj == pn_be_SubSP_M) {
4479 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4482 panic("No idea how to transform proj->SubSP");
4486 * Transform and renumber the Projs from a Load.
4488 static ir_node *gen_Proj_Load(ir_node *node)
4491 ir_node *block = be_transform_node(get_nodes_block(node));
4492 ir_node *pred = get_Proj_pred(node);
4493 dbg_info *dbgi = get_irn_dbg_info(node);
4494 long proj = get_Proj_proj(node);
4496 /* loads might be part of source address mode matches, so we don't
4497 * transform the ProjMs yet (with the exception of loads whose result is
4500 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4503 /* this is needed, because sometimes we have loops that are only
4504 reachable through the ProjM */
4505 be_enqueue_preds(node);
4506 /* do it in 2 steps, to silence firm verifier */
4507 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4508 set_Proj_proj(res, pn_ia32_mem);
4512 /* renumber the proj */
4513 new_pred = be_transform_node(pred);
4514 if (is_ia32_Load(new_pred)) {
4517 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4519 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4520 case pn_Load_X_regular:
4521 return new_rd_Jmp(dbgi, block);
4522 case pn_Load_X_except:
4523 /* This Load might raise an exception. Mark it. */
4524 set_ia32_exc_label(new_pred, 1);
4525 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4529 } else if (is_ia32_Conv_I2I(new_pred) ||
4530 is_ia32_Conv_I2I8Bit(new_pred)) {
4531 set_irn_mode(new_pred, mode_T);
4532 if (proj == pn_Load_res) {
4533 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4534 } else if (proj == pn_Load_M) {
4535 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4537 } else if (is_ia32_xLoad(new_pred)) {
4540 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4542 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4543 case pn_Load_X_regular:
4544 return new_rd_Jmp(dbgi, block);
4545 case pn_Load_X_except:
4546 /* This Load might raise an exception. Mark it. */
4547 set_ia32_exc_label(new_pred, 1);
4548 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4552 } else if (is_ia32_vfld(new_pred)) {
4555 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4557 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4558 case pn_Load_X_regular:
4559 return new_rd_Jmp(dbgi, block);
4560 case pn_Load_X_except:
4561 /* This Load might raise an exception. Mark it. */
4562 set_ia32_exc_label(new_pred, 1);
4563 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4568 /* can happen for ProJMs when source address mode happened for the
4571 /* however it should not be the result proj, as that would mean the
4572 load had multiple users and should not have been used for
4574 if (proj != pn_Load_M) {
4575 panic("internal error: transformed node not a Load");
4577 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4580 panic("No idea how to transform proj");
4584 * Transform and renumber the Projs from a Div or Mod instruction.
4586 static ir_node *gen_Proj_Div(ir_node *node)
4588 ir_node *block = be_transform_node(get_nodes_block(node));
4589 ir_node *pred = get_Proj_pred(node);
4590 ir_node *new_pred = be_transform_node(pred);
4591 dbg_info *dbgi = get_irn_dbg_info(node);
4592 long proj = get_Proj_proj(node);
4594 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4595 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4599 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4600 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4601 } else if (is_ia32_xDiv(new_pred)) {
4602 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4603 } else if (is_ia32_vfdiv(new_pred)) {
4604 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4606 panic("Div transformed to unexpected thing %+F", new_pred);
4609 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4610 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4611 } else if (is_ia32_xDiv(new_pred)) {
4612 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4613 } else if (is_ia32_vfdiv(new_pred)) {
4614 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4616 panic("Div transformed to unexpected thing %+F", new_pred);
4618 case pn_Div_X_regular:
4619 return new_rd_Jmp(dbgi, block);
4620 case pn_Div_X_except:
4621 set_ia32_exc_label(new_pred, 1);
4622 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4627 panic("No idea how to transform proj->Div");
4631 * Transform and renumber the Projs from a Div or Mod instruction.
4633 static ir_node *gen_Proj_Mod(ir_node *node)
4635 ir_node *pred = get_Proj_pred(node);
4636 ir_node *new_pred = be_transform_node(pred);
4637 dbg_info *dbgi = get_irn_dbg_info(node);
4638 long proj = get_Proj_proj(node);
4640 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4641 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4642 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4646 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4648 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4649 case pn_Mod_X_except:
4650 set_ia32_exc_label(new_pred, 1);
4651 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4655 panic("No idea how to transform proj->Mod");
4659 * Transform and renumber the Projs from a CopyB.
4661 static ir_node *gen_Proj_CopyB(ir_node *node)
4663 ir_node *pred = get_Proj_pred(node);
4664 ir_node *new_pred = be_transform_node(pred);
4665 dbg_info *dbgi = get_irn_dbg_info(node);
4666 long proj = get_Proj_proj(node);
4670 if (is_ia32_CopyB_i(new_pred)) {
4671 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4672 } else if (is_ia32_CopyB(new_pred)) {
4673 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4680 panic("No idea how to transform proj->CopyB");
4683 static ir_node *gen_be_Call(ir_node *node)
4685 dbg_info *const dbgi = get_irn_dbg_info(node);
4686 ir_node *const src_block = get_nodes_block(node);
4687 ir_node *const block = be_transform_node(src_block);
4688 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4689 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4690 ir_node *const sp = be_transform_node(src_sp);
4691 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4692 ia32_address_mode_t am;
4693 ia32_address_t *const addr = &am.addr;
4698 ir_node * eax = noreg_GP;
4699 ir_node * ecx = noreg_GP;
4700 ir_node * edx = noreg_GP;
4701 unsigned const pop = be_Call_get_pop(node);
4702 ir_type *const call_tp = be_Call_get_type(node);
4703 int old_no_pic_adjust;
4705 /* Run the x87 simulator if the call returns a float value */
4706 if (get_method_n_ress(call_tp) > 0) {
4707 ir_type *const res_type = get_method_res_type(call_tp, 0);
4708 ir_mode *const res_mode = get_type_mode(res_type);
4710 if (res_mode != NULL && mode_is_float(res_mode)) {
4711 ir_graph *irg = current_ir_graph;
4712 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4713 irg_data->do_x87_sim = 1;
4717 /* We do not want be_Call direct calls */
4718 assert(be_Call_get_entity(node) == NULL);
4720 /* special case for PIC trampoline calls */
4721 old_no_pic_adjust = ia32_no_pic_adjust;
4722 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4724 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4725 match_am | match_immediate);
4727 ia32_no_pic_adjust = old_no_pic_adjust;
4729 i = get_irn_arity(node) - 1;
4730 fpcw = be_transform_node(get_irn_n(node, i--));
4731 for (; i >= be_pos_Call_first_arg; --i) {
4732 arch_register_req_t const *const req = arch_get_register_req(node, i);
4733 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4735 assert(req->type == arch_register_req_type_limited);
4736 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4738 switch (*req->limited) {
4739 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4740 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4741 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4742 default: panic("Invalid GP register for register parameter");
4746 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4747 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4748 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4749 set_am_attributes(call, &am);
4750 call = fix_mem_proj(call, &am);
4752 if (get_irn_pinned(node) == op_pin_state_pinned)
4753 set_irn_pinned(call, op_pin_state_pinned);
4755 SET_IA32_ORIG_NODE(call, node);
4757 if (ia32_cg_config.use_sse2) {
4758 /* remember this call for post-processing */
4759 ARR_APP1(ir_node *, call_list, call);
4760 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4767 * Transform Builtin trap
4769 static ir_node *gen_trap(ir_node *node)
4771 dbg_info *dbgi = get_irn_dbg_info(node);
4772 ir_node *block = be_transform_node(get_nodes_block(node));
4773 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4775 return new_bd_ia32_UD2(dbgi, block, mem);
4779 * Transform Builtin debugbreak
4781 static ir_node *gen_debugbreak(ir_node *node)
4783 dbg_info *dbgi = get_irn_dbg_info(node);
4784 ir_node *block = be_transform_node(get_nodes_block(node));
4785 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4787 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4791 * Transform Builtin return_address
4793 static ir_node *gen_return_address(ir_node *node)
4795 ir_node *param = get_Builtin_param(node, 0);
4796 ir_node *frame = get_Builtin_param(node, 1);
4797 dbg_info *dbgi = get_irn_dbg_info(node);
4798 ir_tarval *tv = get_Const_tarval(param);
4799 unsigned long value = get_tarval_long(tv);
4801 ir_node *block = be_transform_node(get_nodes_block(node));
4802 ir_node *ptr = be_transform_node(frame);
4806 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4807 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4808 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4811 /* load the return address from this frame */
4812 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4814 set_irn_pinned(load, get_irn_pinned(node));
4815 set_ia32_op_type(load, ia32_AddrModeS);
4816 set_ia32_ls_mode(load, mode_Iu);
4818 set_ia32_am_offs_int(load, 0);
4819 set_ia32_use_frame(load);
4820 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4822 if (get_irn_pinned(node) == op_pin_state_floats) {
4823 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4824 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4825 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4826 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4829 SET_IA32_ORIG_NODE(load, node);
4830 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4834 * Transform Builtin frame_address
4836 static ir_node *gen_frame_address(ir_node *node)
4838 ir_node *param = get_Builtin_param(node, 0);
4839 ir_node *frame = get_Builtin_param(node, 1);
4840 dbg_info *dbgi = get_irn_dbg_info(node);
4841 ir_tarval *tv = get_Const_tarval(param);
4842 unsigned long value = get_tarval_long(tv);
4844 ir_node *block = be_transform_node(get_nodes_block(node));
4845 ir_node *ptr = be_transform_node(frame);
4850 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4851 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4852 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4855 /* load the frame address from this frame */
4856 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4858 set_irn_pinned(load, get_irn_pinned(node));
4859 set_ia32_op_type(load, ia32_AddrModeS);
4860 set_ia32_ls_mode(load, mode_Iu);
4862 ent = ia32_get_frame_address_entity();
4864 set_ia32_am_offs_int(load, 0);
4865 set_ia32_use_frame(load);
4866 set_ia32_frame_ent(load, ent);
4868 /* will fail anyway, but gcc does this: */
4869 set_ia32_am_offs_int(load, 0);
4872 if (get_irn_pinned(node) == op_pin_state_floats) {
4873 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4874 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4875 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4876 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4879 SET_IA32_ORIG_NODE(load, node);
4880 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4884 * Transform Builtin frame_address
4886 static ir_node *gen_prefetch(ir_node *node)
4889 ir_node *ptr, *block, *mem, *base, *index;
4890 ir_node *param, *new_node;
4893 ia32_address_t addr;
4895 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4896 /* no prefetch at all, route memory */
4897 return be_transform_node(get_Builtin_mem(node));
4900 param = get_Builtin_param(node, 1);
4901 tv = get_Const_tarval(param);
4902 rw = get_tarval_long(tv);
4904 /* construct load address */
4905 memset(&addr, 0, sizeof(addr));
4906 ptr = get_Builtin_param(node, 0);
4907 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4914 base = be_transform_node(base);
4917 if (index == NULL) {
4920 index = be_transform_node(index);
4923 dbgi = get_irn_dbg_info(node);
4924 block = be_transform_node(get_nodes_block(node));
4925 mem = be_transform_node(get_Builtin_mem(node));
4927 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4928 /* we have 3DNow!, this was already checked above */
4929 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4930 } else if (ia32_cg_config.use_sse_prefetch) {
4931 /* note: rw == 1 is IGNORED in that case */
4932 param = get_Builtin_param(node, 2);
4933 tv = get_Const_tarval(param);
4934 locality = get_tarval_long(tv);
4936 /* SSE style prefetch */
4939 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4942 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4945 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4948 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4952 assert(ia32_cg_config.use_3dnow_prefetch);
4953 /* 3DNow! style prefetch */
4954 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4957 set_irn_pinned(new_node, get_irn_pinned(node));
4958 set_ia32_op_type(new_node, ia32_AddrModeS);
4959 set_ia32_ls_mode(new_node, mode_Bu);
4960 set_address(new_node, &addr);
4962 SET_IA32_ORIG_NODE(new_node, node);
4964 be_dep_on_frame(new_node);
4965 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4969 * Transform bsf like node
4971 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4973 ir_node *param = get_Builtin_param(node, 0);
4974 dbg_info *dbgi = get_irn_dbg_info(node);
4976 ir_node *block = get_nodes_block(node);
4977 ir_node *new_block = be_transform_node(block);
4979 ia32_address_mode_t am;
4980 ia32_address_t *addr = &am.addr;
4983 match_arguments(&am, block, NULL, param, NULL, match_am);
4985 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4986 set_am_attributes(cnt, &am);
4987 set_ia32_ls_mode(cnt, get_irn_mode(param));
4989 SET_IA32_ORIG_NODE(cnt, node);
4990 return fix_mem_proj(cnt, &am);
4994 * Transform builtin ffs.
4996 static ir_node *gen_ffs(ir_node *node)
4998 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
4999 ir_node *real = skip_Proj(bsf);
5000 dbg_info *dbgi = get_irn_dbg_info(real);
5001 ir_node *block = get_nodes_block(real);
5002 ir_node *flag, *set, *conv, *neg, *orn, *add;
5005 if (get_irn_mode(real) != mode_T) {
5006 set_irn_mode(real, mode_T);
5007 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5010 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5013 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5014 SET_IA32_ORIG_NODE(set, node);
5017 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5018 SET_IA32_ORIG_NODE(conv, node);
5021 neg = new_bd_ia32_Neg(dbgi, block, conv);
5024 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5025 set_ia32_commutative(orn);
5028 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5029 add_ia32_am_offs_int(add, 1);
5034 * Transform builtin clz.
5036 static ir_node *gen_clz(ir_node *node)
5038 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5039 ir_node *real = skip_Proj(bsr);
5040 dbg_info *dbgi = get_irn_dbg_info(real);
5041 ir_node *block = get_nodes_block(real);
5042 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5044 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5048 * Transform builtin ctz.
5050 static ir_node *gen_ctz(ir_node *node)
5052 return gen_unop_AM(node, new_bd_ia32_Bsf);
5056 * Transform builtin parity.
5058 static ir_node *gen_parity(ir_node *node)
5060 dbg_info *dbgi = get_irn_dbg_info(node);
5061 ir_node *block = get_nodes_block(node);
5062 ir_node *new_block = be_transform_node(block);
5063 ir_node *param = get_Builtin_param(node, 0);
5064 ir_node *new_param = be_transform_node(param);
5067 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5068 * so we have to do complicated xoring first.
5069 * (we should also better lower this before the backend so we still have a
5070 * chance for CSE, constant folding and other goodies for some of these
5073 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5074 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5075 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5077 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5080 set_irn_mode(xor2, mode_T);
5081 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5084 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5085 SET_IA32_ORIG_NODE(new_node, node);
5088 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5089 nomem, new_node, mode_Bu);
5090 SET_IA32_ORIG_NODE(new_node, node);
5095 * Transform builtin popcount
5097 static ir_node *gen_popcount(ir_node *node)
5099 ir_node *param = get_Builtin_param(node, 0);
5100 dbg_info *dbgi = get_irn_dbg_info(node);
5102 ir_node *block = get_nodes_block(node);
5103 ir_node *new_block = be_transform_node(block);
5106 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5108 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5109 if (ia32_cg_config.use_popcnt) {
5110 ia32_address_mode_t am;
5111 ia32_address_t *addr = &am.addr;
5114 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5116 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5117 set_am_attributes(cnt, &am);
5118 set_ia32_ls_mode(cnt, get_irn_mode(param));
5120 SET_IA32_ORIG_NODE(cnt, node);
5121 return fix_mem_proj(cnt, &am);
5124 new_param = be_transform_node(param);
5126 /* do the standard popcount algo */
5127 /* TODO: This is stupid, we should transform this before the backend,
5128 * to get CSE, localopts, etc. for the operations
5129 * TODO: This is also not the optimal algorithm (it is just the starting
5130 * example in hackers delight, they optimize it more on the following page)
5131 * But I'm too lazy to fix this now, as the code should get lowered before
5132 * the backend anyway.
5135 /* m1 = x & 0x55555555 */
5136 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5137 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5140 simm = ia32_create_Immediate(NULL, 0, 1);
5141 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5143 /* m2 = s1 & 0x55555555 */
5144 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5147 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5149 /* m4 = m3 & 0x33333333 */
5150 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5151 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5154 simm = ia32_create_Immediate(NULL, 0, 2);
5155 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5157 /* m5 = s2 & 0x33333333 */
5158 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5161 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5163 /* m7 = m6 & 0x0F0F0F0F */
5164 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5165 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5168 simm = ia32_create_Immediate(NULL, 0, 4);
5169 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5171 /* m8 = s3 & 0x0F0F0F0F */
5172 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5175 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5177 /* m10 = m9 & 0x00FF00FF */
5178 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5179 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5182 simm = ia32_create_Immediate(NULL, 0, 8);
5183 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5185 /* m11 = s4 & 0x00FF00FF */
5186 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5188 /* m12 = m10 + m11 */
5189 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5191 /* m13 = m12 & 0x0000FFFF */
5192 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5193 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5195 /* s5 = m12 >> 16 */
5196 simm = ia32_create_Immediate(NULL, 0, 16);
5197 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5199 /* res = m13 + s5 */
5200 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5204 * Transform builtin byte swap.
5206 static ir_node *gen_bswap(ir_node *node)
5208 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5209 dbg_info *dbgi = get_irn_dbg_info(node);
5211 ir_node *block = get_nodes_block(node);
5212 ir_node *new_block = be_transform_node(block);
5213 ir_mode *mode = get_irn_mode(param);
5214 unsigned size = get_mode_size_bits(mode);
5215 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5219 if (ia32_cg_config.use_i486) {
5220 /* swap available */
5221 return new_bd_ia32_Bswap(dbgi, new_block, param);
5223 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5224 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5226 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5227 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5229 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5231 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5232 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5234 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5235 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5238 /* swap16 always available */
5239 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5242 panic("Invalid bswap size (%d)", size);
5247 * Transform builtin outport.
5249 static ir_node *gen_outport(ir_node *node)
5251 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5252 ir_node *oldv = get_Builtin_param(node, 1);
5253 ir_mode *mode = get_irn_mode(oldv);
5254 ir_node *value = be_transform_node(oldv);
5255 ir_node *block = be_transform_node(get_nodes_block(node));
5256 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5257 dbg_info *dbgi = get_irn_dbg_info(node);
5259 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5260 set_ia32_ls_mode(res, mode);
5265 * Transform builtin inport.
5267 static ir_node *gen_inport(ir_node *node)
5269 ir_type *tp = get_Builtin_type(node);
5270 ir_type *rstp = get_method_res_type(tp, 0);
5271 ir_mode *mode = get_type_mode(rstp);
5272 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5273 ir_node *block = be_transform_node(get_nodes_block(node));
5274 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5275 dbg_info *dbgi = get_irn_dbg_info(node);
5277 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5278 set_ia32_ls_mode(res, mode);
5280 /* check for missing Result Proj */
5285 * Transform a builtin inner trampoline
5287 static ir_node *gen_inner_trampoline(ir_node *node)
5289 ir_node *ptr = get_Builtin_param(node, 0);
5290 ir_node *callee = get_Builtin_param(node, 1);
5291 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5292 ir_node *mem = get_Builtin_mem(node);
5293 ir_node *block = get_nodes_block(node);
5294 ir_node *new_block = be_transform_node(block);
5298 ir_node *trampoline;
5300 dbg_info *dbgi = get_irn_dbg_info(node);
5301 ia32_address_t addr;
5303 /* construct store address */
5304 memset(&addr, 0, sizeof(addr));
5305 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5307 if (addr.base == NULL) {
5308 addr.base = noreg_GP;
5310 addr.base = be_transform_node(addr.base);
5313 if (addr.index == NULL) {
5314 addr.index = noreg_GP;
5316 addr.index = be_transform_node(addr.index);
5318 addr.mem = be_transform_node(mem);
5320 /* mov ecx, <env> */
5321 val = ia32_create_Immediate(NULL, 0, 0xB9);
5322 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5323 addr.index, addr.mem, val);
5324 set_irn_pinned(store, get_irn_pinned(node));
5325 set_ia32_op_type(store, ia32_AddrModeD);
5326 set_ia32_ls_mode(store, mode_Bu);
5327 set_address(store, &addr);
5331 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5332 addr.index, addr.mem, env);
5333 set_irn_pinned(store, get_irn_pinned(node));
5334 set_ia32_op_type(store, ia32_AddrModeD);
5335 set_ia32_ls_mode(store, mode_Iu);
5336 set_address(store, &addr);
5340 /* jmp rel <callee> */
5341 val = ia32_create_Immediate(NULL, 0, 0xE9);
5342 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5343 addr.index, addr.mem, val);
5344 set_irn_pinned(store, get_irn_pinned(node));
5345 set_ia32_op_type(store, ia32_AddrModeD);
5346 set_ia32_ls_mode(store, mode_Bu);
5347 set_address(store, &addr);
5351 trampoline = be_transform_node(ptr);
5353 /* the callee is typically an immediate */
5354 if (is_SymConst(callee)) {
5355 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5357 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5358 add_ia32_am_offs_int(rel, -10);
5360 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5362 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5363 addr.index, addr.mem, rel);
5364 set_irn_pinned(store, get_irn_pinned(node));
5365 set_ia32_op_type(store, ia32_AddrModeD);
5366 set_ia32_ls_mode(store, mode_Iu);
5367 set_address(store, &addr);
5372 return new_r_Tuple(new_block, 2, in);
5376 * Transform Builtin node.
5378 static ir_node *gen_Builtin(ir_node *node)
5380 ir_builtin_kind kind = get_Builtin_kind(node);
5384 return gen_trap(node);
5385 case ir_bk_debugbreak:
5386 return gen_debugbreak(node);
5387 case ir_bk_return_address:
5388 return gen_return_address(node);
5389 case ir_bk_frame_address:
5390 return gen_frame_address(node);
5391 case ir_bk_prefetch:
5392 return gen_prefetch(node);
5394 return gen_ffs(node);
5396 return gen_clz(node);
5398 return gen_ctz(node);
5400 return gen_parity(node);
5401 case ir_bk_popcount:
5402 return gen_popcount(node);
5404 return gen_bswap(node);
5406 return gen_outport(node);
5408 return gen_inport(node);
5409 case ir_bk_inner_trampoline:
5410 return gen_inner_trampoline(node);
5412 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5416 * Transform Proj(Builtin) node.
5418 static ir_node *gen_Proj_Builtin(ir_node *proj)
5420 ir_node *node = get_Proj_pred(proj);
5421 ir_node *new_node = be_transform_node(node);
5422 ir_builtin_kind kind = get_Builtin_kind(node);
5425 case ir_bk_return_address:
5426 case ir_bk_frame_address:
5431 case ir_bk_popcount:
5433 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5436 case ir_bk_debugbreak:
5437 case ir_bk_prefetch:
5439 assert(get_Proj_proj(proj) == pn_Builtin_M);
5442 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5443 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5445 assert(get_Proj_proj(proj) == pn_Builtin_M);
5446 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5448 case ir_bk_inner_trampoline:
5449 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5450 return get_Tuple_pred(new_node, 1);
5452 assert(get_Proj_proj(proj) == pn_Builtin_M);
5453 return get_Tuple_pred(new_node, 0);
5456 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5459 static ir_node *gen_be_IncSP(ir_node *node)
5461 ir_node *res = be_duplicate_node(node);
5462 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5468 * Transform the Projs from a be_Call.
5470 static ir_node *gen_Proj_be_Call(ir_node *node)
5472 ir_node *call = get_Proj_pred(node);
5473 ir_node *new_call = be_transform_node(call);
5474 dbg_info *dbgi = get_irn_dbg_info(node);
5475 long proj = get_Proj_proj(node);
5476 ir_mode *mode = get_irn_mode(node);
5479 if (proj == pn_be_Call_M_regular) {
5480 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5482 /* transform call modes */
5483 if (mode_is_data(mode)) {
5484 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5488 /* Map from be_Call to ia32_Call proj number */
5489 if (proj == pn_be_Call_sp) {
5490 proj = pn_ia32_Call_stack;
5491 } else if (proj == pn_be_Call_M_regular) {
5492 proj = pn_ia32_Call_M;
5494 arch_register_req_t const *const req = arch_get_register_req_out(node);
5495 int const n_outs = arch_irn_get_n_outs(new_call);
5498 assert(proj >= pn_be_Call_first_res);
5499 assert(req->type & arch_register_req_type_limited);
5501 for (i = 0; i < n_outs; ++i) {
5502 arch_register_req_t const *const new_req
5503 = arch_get_out_register_req(new_call, i);
5505 if (!(new_req->type & arch_register_req_type_limited) ||
5506 new_req->cls != req->cls ||
5507 *new_req->limited != *req->limited)
5516 res = new_rd_Proj(dbgi, new_call, mode, proj);
5518 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5520 case pn_ia32_Call_stack:
5521 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5524 case pn_ia32_Call_fpcw:
5525 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5533 * Transform the Projs from a Cmp.
5535 static ir_node *gen_Proj_Cmp(ir_node *node)
5537 /* this probably means not all mode_b nodes were lowered... */
5538 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5542 static ir_node *gen_Proj_ASM(ir_node *node)
5544 ir_mode *mode = get_irn_mode(node);
5545 ir_node *pred = get_Proj_pred(node);
5546 ir_node *new_pred = be_transform_node(pred);
5547 long pos = get_Proj_proj(node);
5549 if (mode == mode_M) {
5550 pos = arch_irn_get_n_outs(new_pred)-1;
5551 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5553 } else if (mode_is_float(mode)) {
5556 panic("unexpected proj mode at ASM");
5559 return new_r_Proj(new_pred, mode, pos);
5563 * Transform and potentially renumber Proj nodes.
5565 static ir_node *gen_Proj(ir_node *node)
5567 ir_node *pred = get_Proj_pred(node);
5570 switch (get_irn_opcode(pred)) {
5572 proj = get_Proj_proj(node);
5573 if (proj == pn_Store_M) {
5574 return be_transform_node(pred);
5576 panic("No idea how to transform proj->Store");
5579 return gen_Proj_Load(node);
5581 return gen_Proj_ASM(node);
5583 return gen_Proj_Builtin(node);
5585 return gen_Proj_Div(node);
5587 return gen_Proj_Mod(node);
5589 return gen_Proj_CopyB(node);
5591 return gen_Proj_be_SubSP(node);
5593 return gen_Proj_be_AddSP(node);
5595 return gen_Proj_be_Call(node);
5597 return gen_Proj_Cmp(node);
5599 proj = get_Proj_proj(node);
5601 case pn_Start_X_initial_exec: {
5602 ir_node *block = get_nodes_block(pred);
5603 ir_node *new_block = be_transform_node(block);
5604 dbg_info *dbgi = get_irn_dbg_info(node);
5605 /* we exchange the ProjX with a jump */
5606 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5611 case pn_Start_P_tls:
5612 return ia32_gen_Proj_tls(node);
5617 if (is_ia32_l_FloattoLL(pred)) {
5618 return gen_Proj_l_FloattoLL(node);
5620 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5624 ir_mode *mode = get_irn_mode(node);
5625 if (ia32_mode_needs_gp_reg(mode)) {
5626 ir_node *new_pred = be_transform_node(pred);
5627 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5628 get_Proj_proj(node));
5629 new_proj->node_nr = node->node_nr;
5634 return be_duplicate_node(node);
5638 * Enters all transform functions into the generic pointer
5640 static void register_transformers(void)
5642 /* first clear the generic function pointer for all ops */
5643 be_start_transform_setup();
5645 be_set_transform_function(op_Add, gen_Add);
5646 be_set_transform_function(op_And, gen_And);
5647 be_set_transform_function(op_ASM, ia32_gen_ASM);
5648 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5649 be_set_transform_function(op_be_Call, gen_be_Call);
5650 be_set_transform_function(op_be_Copy, gen_be_Copy);
5651 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5652 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5653 be_set_transform_function(op_be_Return, gen_be_Return);
5654 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5655 be_set_transform_function(op_Builtin, gen_Builtin);
5656 be_set_transform_function(op_Cmp, gen_Cmp);
5657 be_set_transform_function(op_Cond, gen_Cond);
5658 be_set_transform_function(op_Const, gen_Const);
5659 be_set_transform_function(op_Conv, gen_Conv);
5660 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5661 be_set_transform_function(op_Div, gen_Div);
5662 be_set_transform_function(op_Eor, gen_Eor);
5663 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5664 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5665 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5666 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5667 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5668 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5669 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5670 be_set_transform_function(op_ia32_l_SarDep, gen_ia32_l_SarDep);
5671 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5672 be_set_transform_function(op_ia32_l_ShlDep, gen_ia32_l_ShlDep);
5673 be_set_transform_function(op_ia32_l_ShlD, gen_ia32_l_ShlD);
5674 be_set_transform_function(op_ia32_l_ShrDep, gen_ia32_l_ShrDep);
5675 be_set_transform_function(op_ia32_l_ShrD, gen_ia32_l_ShrD);
5676 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5677 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5678 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5679 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5680 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5681 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5682 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5683 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5684 be_set_transform_function(op_IJmp, gen_IJmp);
5685 be_set_transform_function(op_Jmp, gen_Jmp);
5686 be_set_transform_function(op_Load, gen_Load);
5687 be_set_transform_function(op_Minus, gen_Minus);
5688 be_set_transform_function(op_Mod, gen_Mod);
5689 be_set_transform_function(op_Mul, gen_Mul);
5690 be_set_transform_function(op_Mulh, gen_Mulh);
5691 be_set_transform_function(op_Mux, gen_Mux);
5692 be_set_transform_function(op_Not, gen_Not);
5693 be_set_transform_function(op_Or, gen_Or);
5694 be_set_transform_function(op_Phi, gen_Phi);
5695 be_set_transform_function(op_Proj, gen_Proj);
5696 be_set_transform_function(op_Rotl, gen_Rotl);
5697 be_set_transform_function(op_Shl, gen_Shl);
5698 be_set_transform_function(op_Shr, gen_Shr);
5699 be_set_transform_function(op_Shrs, gen_Shrs);
5700 be_set_transform_function(op_Store, gen_Store);
5701 be_set_transform_function(op_Sub, gen_Sub);
5702 be_set_transform_function(op_SymConst, gen_SymConst);
5703 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5707 * Pre-transform all unknown and noreg nodes.
5709 static void ia32_pretransform_node(void)
5711 ir_graph *irg = current_ir_graph;
5712 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5714 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5715 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5716 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5718 nomem = get_irg_no_mem(irg);
5719 noreg_GP = ia32_new_NoReg_gp(irg);
5725 * Post-process all calls if we are in SSE mode.
5726 * The ABI requires that the results are in st0, copy them
5727 * to a xmm register.
5729 static void postprocess_fp_call_results(void)
5733 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5734 ir_node *call = call_list[i];
5735 ir_type *mtp = call_types[i];
5738 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5739 ir_type *res_tp = get_method_res_type(mtp, j);
5740 ir_node *res, *new_res;
5741 const ir_edge_t *edge, *next;
5744 if (! is_atomic_type(res_tp)) {
5745 /* no floating point return */
5748 mode = get_type_mode(res_tp);
5749 if (! mode_is_float(mode)) {
5750 /* no floating point return */
5754 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5757 /* now patch the users */
5758 foreach_out_edge_safe(res, edge, next) {
5759 ir_node *succ = get_edge_src_irn(edge);
5762 if (be_is_Keep(succ))
5765 if (is_ia32_xStore(succ)) {
5766 /* an xStore can be patched into an vfst */
5767 dbg_info *db = get_irn_dbg_info(succ);
5768 ir_node *block = get_nodes_block(succ);
5769 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5770 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5771 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5772 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5773 ir_mode *mode = get_ia32_ls_mode(succ);
5775 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5776 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5777 if (is_ia32_use_frame(succ))
5778 set_ia32_use_frame(st);
5779 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5780 set_irn_pinned(st, get_irn_pinned(succ));
5781 set_ia32_op_type(st, ia32_AddrModeD);
5785 if (new_res == NULL) {
5786 dbg_info *db = get_irn_dbg_info(call);
5787 ir_node *block = get_nodes_block(call);
5788 ir_node *frame = get_irg_frame(current_ir_graph);
5789 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5790 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5791 ir_node *vfst, *xld, *new_mem;
5793 /* store st(0) on stack */
5794 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5795 set_ia32_op_type(vfst, ia32_AddrModeD);
5796 set_ia32_use_frame(vfst);
5798 /* load into SSE register */
5799 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5800 set_ia32_op_type(xld, ia32_AddrModeS);
5801 set_ia32_use_frame(xld);
5803 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5804 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5806 if (old_mem != NULL) {
5807 edges_reroute(old_mem, new_mem, current_ir_graph);
5811 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5818 /* do the transformation */
5819 void ia32_transform_graph(ir_graph *irg)
5823 register_transformers();
5824 initial_fpcw = NULL;
5825 ia32_no_pic_adjust = 0;
5827 be_timer_push(T_HEIGHTS);
5828 ia32_heights = heights_new(irg);
5829 be_timer_pop(T_HEIGHTS);
5830 ia32_calculate_non_address_mode_nodes(irg);
5832 /* the transform phase is not safe for CSE (yet) because several nodes get
5833 * attributes set after their creation */
5834 cse_last = get_opt_cse();
5837 call_list = NEW_ARR_F(ir_node *, 0);
5838 call_types = NEW_ARR_F(ir_type *, 0);
5839 be_transform_graph(irg, ia32_pretransform_node);
5841 if (ia32_cg_config.use_sse2)
5842 postprocess_fp_call_results();
5843 DEL_ARR_F(call_types);
5844 DEL_ARR_F(call_list);
5846 set_opt_cse(cse_last);
5848 ia32_free_non_address_mode_nodes();
5849 heights_free(ia32_heights);
5850 ia32_heights = NULL;
5853 void ia32_init_transform(void)
5855 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");