2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
51 #include "../benode.h"
52 #include "../besched.h"
54 #include "../beutil.h"
56 #include "../betranshlp.h"
59 #include "bearch_ia32_t.h"
60 #include "ia32_common_transform.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
71 #include "gen_ia32_regalloc_if.h"
73 /* define this to construct SSE constants instead of load them */
74 #undef CONSTRUCT_SSE_CONST
77 #define SFP_SIGN "0x80000000"
78 #define DFP_SIGN "0x8000000000000000"
79 #define SFP_ABS "0x7FFFFFFF"
80 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
81 #define DFP_INTMAX "9223372036854775807"
82 #define ULL_BIAS "18446744073709551616"
84 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
85 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
86 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
87 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
88 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
90 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
91 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
93 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
95 static ir_node *initial_fpcw = NULL;
98 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
99 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
102 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
103 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
106 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
107 ir_node *op1, ir_node *op2);
109 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
110 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
112 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
113 ir_node *base, ir_node *index, ir_node *mem);
115 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
116 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
119 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
121 static ir_node *create_immediate_or_transform(ir_node *node,
122 char immediate_constraint_type);
124 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
125 dbg_info *dbgi, ir_node *block,
126 ir_node *op, ir_node *orig_node);
128 /* its enough to have those once */
129 static ir_node *nomem, *noreg_GP;
131 /** a list to postprocess all calls */
132 static ir_node **call_list;
133 static ir_type **call_types;
135 /** Return non-zero is a node represents the 0 constant. */
136 static bool is_Const_0(ir_node *node)
138 return is_Const(node) && is_Const_null(node);
141 /** Return non-zero is a node represents the 1 constant. */
142 static bool is_Const_1(ir_node *node)
144 return is_Const(node) && is_Const_one(node);
147 /** Return non-zero is a node represents the -1 constant. */
148 static bool is_Const_Minus_1(ir_node *node)
150 return is_Const(node) && is_Const_all_one(node);
154 * returns true if constant can be created with a simple float command
156 static bool is_simple_x87_Const(ir_node *node)
158 tarval *tv = get_Const_tarval(node);
159 if (tarval_is_null(tv) || tarval_is_one(tv))
162 /* TODO: match all the other float constants */
167 * returns true if constant can be created with a simple float command
169 static bool is_simple_sse_Const(ir_node *node)
171 tarval *tv = get_Const_tarval(node);
172 ir_mode *mode = get_tarval_mode(tv);
177 if (tarval_is_null(tv)
178 #ifdef CONSTRUCT_SSE_CONST
183 #ifdef CONSTRUCT_SSE_CONST
184 if (mode == mode_D) {
185 unsigned val = get_tarval_sub_bits(tv, 0) |
186 (get_tarval_sub_bits(tv, 1) << 8) |
187 (get_tarval_sub_bits(tv, 2) << 16) |
188 (get_tarval_sub_bits(tv, 3) << 24);
190 /* lower 32bit are zero, really a 32bit constant */
193 #endif /* CONSTRUCT_SSE_CONST */
194 /* TODO: match all the other float constants */
199 * return NoREG or pic_base in case of PIC.
200 * This is necessary as base address for newly created symbols
202 static ir_node *get_symconst_base(void)
204 if (env_cg->birg->main_env->options->pic) {
205 return arch_code_generator_get_pic_base(env_cg);
212 * Transforms a Const.
214 static ir_node *gen_Const(ir_node *node)
216 ir_node *old_block = get_nodes_block(node);
217 ir_node *block = be_transform_node(old_block);
218 dbg_info *dbgi = get_irn_dbg_info(node);
219 ir_mode *mode = get_irn_mode(node);
221 assert(is_Const(node));
223 if (mode_is_float(mode)) {
229 if (ia32_cg_config.use_sse2) {
230 tarval *tv = get_Const_tarval(node);
231 if (tarval_is_null(tv)) {
232 load = new_bd_ia32_xZero(dbgi, block);
233 set_ia32_ls_mode(load, mode);
235 #ifdef CONSTRUCT_SSE_CONST
236 } else if (tarval_is_one(tv)) {
237 int cnst = mode == mode_F ? 26 : 55;
238 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
239 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
240 ir_node *pslld, *psrld;
242 load = new_bd_ia32_xAllOnes(dbgi, block);
243 set_ia32_ls_mode(load, mode);
244 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
245 set_ia32_ls_mode(pslld, mode);
246 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
247 set_ia32_ls_mode(psrld, mode);
249 #endif /* CONSTRUCT_SSE_CONST */
250 } else if (mode == mode_F) {
251 /* we can place any 32bit constant by using a movd gp, sse */
252 unsigned val = get_tarval_sub_bits(tv, 0) |
253 (get_tarval_sub_bits(tv, 1) << 8) |
254 (get_tarval_sub_bits(tv, 2) << 16) |
255 (get_tarval_sub_bits(tv, 3) << 24);
256 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
257 load = new_bd_ia32_xMovd(dbgi, block, cnst);
258 set_ia32_ls_mode(load, mode);
261 #ifdef CONSTRUCT_SSE_CONST
262 if (mode == mode_D) {
263 unsigned val = get_tarval_sub_bits(tv, 0) |
264 (get_tarval_sub_bits(tv, 1) << 8) |
265 (get_tarval_sub_bits(tv, 2) << 16) |
266 (get_tarval_sub_bits(tv, 3) << 24);
268 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
269 ir_node *cnst, *psllq;
271 /* fine, lower 32bit are zero, produce 32bit value */
272 val = get_tarval_sub_bits(tv, 4) |
273 (get_tarval_sub_bits(tv, 5) << 8) |
274 (get_tarval_sub_bits(tv, 6) << 16) |
275 (get_tarval_sub_bits(tv, 7) << 24);
276 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
277 load = new_bd_ia32_xMovd(dbgi, block, cnst);
278 set_ia32_ls_mode(load, mode);
279 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
280 set_ia32_ls_mode(psllq, mode);
285 #endif /* CONSTRUCT_SSE_CONST */
286 floatent = create_float_const_entity(node);
288 base = get_symconst_base();
289 load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
291 set_ia32_op_type(load, ia32_AddrModeS);
292 set_ia32_am_sc(load, floatent);
293 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
294 res = new_r_Proj(block, load, mode_xmm, pn_ia32_xLoad_res);
297 if (is_Const_null(node)) {
298 load = new_bd_ia32_vfldz(dbgi, block);
300 set_ia32_ls_mode(load, mode);
301 } else if (is_Const_one(node)) {
302 load = new_bd_ia32_vfld1(dbgi, block);
304 set_ia32_ls_mode(load, mode);
309 floatent = create_float_const_entity(node);
310 /* create_float_const_ent is smart and sometimes creates
312 ls_mode = get_type_mode(get_entity_type(floatent));
313 base = get_symconst_base();
314 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
316 set_ia32_op_type(load, ia32_AddrModeS);
317 set_ia32_am_sc(load, floatent);
318 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
319 res = new_r_Proj(block, load, mode_vfp, pn_ia32_vfld_res);
322 #ifdef CONSTRUCT_SSE_CONST
324 #endif /* CONSTRUCT_SSE_CONST */
325 SET_IA32_ORIG_NODE(load, node);
327 be_dep_on_frame(load);
329 } else { /* non-float mode */
331 tarval *tv = get_Const_tarval(node);
334 tv = tarval_convert_to(tv, mode_Iu);
336 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
338 panic("couldn't convert constant tarval (%+F)", node);
340 val = get_tarval_long(tv);
342 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
343 SET_IA32_ORIG_NODE(cnst, node);
345 be_dep_on_frame(cnst);
351 * Transforms a SymConst.
353 static ir_node *gen_SymConst(ir_node *node)
355 ir_node *old_block = get_nodes_block(node);
356 ir_node *block = be_transform_node(old_block);
357 dbg_info *dbgi = get_irn_dbg_info(node);
358 ir_mode *mode = get_irn_mode(node);
361 if (mode_is_float(mode)) {
362 if (ia32_cg_config.use_sse2)
363 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
365 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
366 set_ia32_am_sc(cnst, get_SymConst_entity(node));
367 set_ia32_use_frame(cnst);
371 if (get_SymConst_kind(node) != symconst_addr_ent) {
372 panic("backend only support symconst_addr_ent (at %+F)", node);
374 entity = get_SymConst_entity(node);
375 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
378 SET_IA32_ORIG_NODE(cnst, node);
380 be_dep_on_frame(cnst);
385 * Create a float type for the given mode and cache it.
387 * @param mode the mode for the float type (might be integer mode for SSE2 types)
388 * @param align alignment
390 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
396 if (mode == mode_Iu) {
397 static ir_type *int_Iu[16] = {NULL, };
399 if (int_Iu[align] == NULL) {
400 int_Iu[align] = tp = new_type_primitive(mode);
401 /* set the specified alignment */
402 set_type_alignment_bytes(tp, align);
404 return int_Iu[align];
405 } else if (mode == mode_Lu) {
406 static ir_type *int_Lu[16] = {NULL, };
408 if (int_Lu[align] == NULL) {
409 int_Lu[align] = tp = new_type_primitive(mode);
410 /* set the specified alignment */
411 set_type_alignment_bytes(tp, align);
413 return int_Lu[align];
414 } else if (mode == mode_F) {
415 static ir_type *float_F[16] = {NULL, };
417 if (float_F[align] == NULL) {
418 float_F[align] = tp = new_type_primitive(mode);
419 /* set the specified alignment */
420 set_type_alignment_bytes(tp, align);
422 return float_F[align];
423 } else if (mode == mode_D) {
424 static ir_type *float_D[16] = {NULL, };
426 if (float_D[align] == NULL) {
427 float_D[align] = tp = new_type_primitive(mode);
428 /* set the specified alignment */
429 set_type_alignment_bytes(tp, align);
431 return float_D[align];
433 static ir_type *float_E[16] = {NULL, };
435 if (float_E[align] == NULL) {
436 float_E[align] = tp = new_type_primitive(mode);
437 /* set the specified alignment */
438 set_type_alignment_bytes(tp, align);
440 return float_E[align];
445 * Create a float[2] array type for the given atomic type.
447 * @param tp the atomic type
449 static ir_type *ia32_create_float_array(ir_type *tp)
451 ir_mode *mode = get_type_mode(tp);
452 unsigned align = get_type_alignment_bytes(tp);
457 if (mode == mode_F) {
458 static ir_type *float_F[16] = {NULL, };
460 if (float_F[align] != NULL)
461 return float_F[align];
462 arr = float_F[align] = new_type_array(1, tp);
463 } else if (mode == mode_D) {
464 static ir_type *float_D[16] = {NULL, };
466 if (float_D[align] != NULL)
467 return float_D[align];
468 arr = float_D[align] = new_type_array(1, tp);
470 static ir_type *float_E[16] = {NULL, };
472 if (float_E[align] != NULL)
473 return float_E[align];
474 arr = float_E[align] = new_type_array(1, tp);
476 set_type_alignment_bytes(arr, align);
477 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
478 set_type_state(arr, layout_fixed);
482 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
483 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
485 static const struct {
486 const char *ent_name;
487 const char *cnst_str;
490 } names [ia32_known_const_max] = {
491 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
492 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
493 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
494 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
495 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
497 static ir_entity *ent_cache[ia32_known_const_max];
499 const char *ent_name, *cnst_str;
505 ent_name = names[kct].ent_name;
506 if (! ent_cache[kct]) {
507 cnst_str = names[kct].cnst_str;
509 switch (names[kct].mode) {
510 case 0: mode = mode_Iu; break;
511 case 1: mode = mode_Lu; break;
512 default: mode = mode_F; break;
514 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
515 tp = ia32_create_float_type(mode, names[kct].align);
517 if (kct == ia32_ULLBIAS)
518 tp = ia32_create_float_array(tp);
519 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
521 set_entity_ld_ident(ent, get_entity_ident(ent));
522 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
523 set_entity_visibility(ent, ir_visibility_local);
525 if (kct == ia32_ULLBIAS) {
526 ir_initializer_t *initializer = create_initializer_compound(2);
528 set_initializer_compound_value(initializer, 0,
529 create_initializer_tarval(get_tarval_null(mode)));
530 set_initializer_compound_value(initializer, 1,
531 create_initializer_tarval(tv));
533 set_entity_initializer(ent, initializer);
535 set_entity_initializer(ent, create_initializer_tarval(tv));
538 /* cache the entry */
539 ent_cache[kct] = ent;
542 return ent_cache[kct];
546 * return true if the node is a Proj(Load) and could be used in source address
547 * mode for another node. Will return only true if the @p other node is not
548 * dependent on the memory of the Load (for binary operations use the other
549 * input here, for unary operations use NULL).
551 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
552 ir_node *other, ir_node *other2, match_flags_t flags)
557 /* float constants are always available */
558 if (is_Const(node)) {
559 ir_mode *mode = get_irn_mode(node);
560 if (mode_is_float(mode)) {
561 if (ia32_cg_config.use_sse2) {
562 if (is_simple_sse_Const(node))
565 if (is_simple_x87_Const(node))
568 if (get_irn_n_edges(node) > 1)
576 load = get_Proj_pred(node);
577 pn = get_Proj_proj(node);
578 if (!is_Load(load) || pn != pn_Load_res)
580 if (get_nodes_block(load) != block)
582 /* we only use address mode if we're the only user of the load */
583 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
585 /* in some edge cases with address mode we might reach the load normally
586 * and through some AM sequence, if it is already materialized then we
587 * can't create an AM node from it */
588 if (be_is_transformed(node))
591 /* don't do AM if other node inputs depend on the load (via mem-proj) */
592 if (other != NULL && prevents_AM(block, load, other))
595 if (other2 != NULL && prevents_AM(block, load, other2))
601 typedef struct ia32_address_mode_t ia32_address_mode_t;
602 struct ia32_address_mode_t {
607 ia32_op_type_t op_type;
611 unsigned commutative : 1;
612 unsigned ins_permuted : 1;
615 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
617 /* construct load address */
618 memset(addr, 0, sizeof(addr[0]));
619 ia32_create_address_mode(addr, ptr, 0);
621 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
622 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
623 addr->mem = be_transform_node(mem);
626 static void build_address(ia32_address_mode_t *am, ir_node *node,
627 ia32_create_am_flags_t flags)
629 ia32_address_t *addr = &am->addr;
635 /* floating point immediates */
636 if (is_Const(node)) {
637 ir_entity *entity = create_float_const_entity(node);
638 addr->base = get_symconst_base();
639 addr->index = noreg_GP;
641 addr->symconst_ent = entity;
643 am->ls_mode = get_type_mode(get_entity_type(entity));
644 am->pinned = op_pin_state_floats;
648 load = get_Proj_pred(node);
649 ptr = get_Load_ptr(load);
650 mem = get_Load_mem(load);
651 new_mem = be_transform_node(mem);
652 am->pinned = get_irn_pinned(load);
653 am->ls_mode = get_Load_mode(load);
654 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
657 /* construct load address */
658 ia32_create_address_mode(addr, ptr, flags);
660 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
661 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
665 static void set_address(ir_node *node, const ia32_address_t *addr)
667 set_ia32_am_scale(node, addr->scale);
668 set_ia32_am_sc(node, addr->symconst_ent);
669 set_ia32_am_offs_int(node, addr->offset);
670 if (addr->symconst_sign)
671 set_ia32_am_sc_sign(node);
673 set_ia32_use_frame(node);
674 set_ia32_frame_ent(node, addr->frame_entity);
678 * Apply attributes of a given address mode to a node.
680 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
682 set_address(node, &am->addr);
684 set_ia32_op_type(node, am->op_type);
685 set_ia32_ls_mode(node, am->ls_mode);
686 if (am->pinned == op_pin_state_pinned) {
687 /* beware: some nodes are already pinned and did not allow to change the state */
688 if (get_irn_pinned(node) != op_pin_state_pinned)
689 set_irn_pinned(node, op_pin_state_pinned);
692 set_ia32_commutative(node);
696 * Check, if a given node is a Down-Conv, ie. a integer Conv
697 * from a mode with a mode with more bits to a mode with lesser bits.
698 * Moreover, we return only true if the node has not more than 1 user.
700 * @param node the node
701 * @return non-zero if node is a Down-Conv
703 static int is_downconv(const ir_node *node)
711 /* we only want to skip the conv when we're the only user
712 * (not optimal but for now...)
714 if (get_irn_n_edges(node) > 1)
717 src_mode = get_irn_mode(get_Conv_op(node));
718 dest_mode = get_irn_mode(node);
720 ia32_mode_needs_gp_reg(src_mode) &&
721 ia32_mode_needs_gp_reg(dest_mode) &&
722 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
725 /* Skip all Down-Conv's on a given node and return the resulting node. */
726 ir_node *ia32_skip_downconv(ir_node *node)
728 while (is_downconv(node))
729 node = get_Conv_op(node);
734 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
736 ir_mode *mode = get_irn_mode(node);
741 if (mode_is_signed(mode)) {
746 block = get_nodes_block(node);
747 dbgi = get_irn_dbg_info(node);
749 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
753 * matches operands of a node into ia32 addressing/operand modes. This covers
754 * usage of source address mode, immediates, operations with non 32-bit modes,
756 * The resulting data is filled into the @p am struct. block is the block
757 * of the node whose arguments are matched. op1, op2 are the first and second
758 * input that are matched (op1 may be NULL). other_op is another unrelated
759 * input that is not matched! but which is needed sometimes to check if AM
760 * for op1/op2 is legal.
761 * @p flags describes the supported modes of the operation in detail.
763 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
764 ir_node *op1, ir_node *op2, ir_node *other_op,
767 ia32_address_t *addr = &am->addr;
768 ir_mode *mode = get_irn_mode(op2);
769 int mode_bits = get_mode_size_bits(mode);
770 ir_node *new_op1, *new_op2;
772 unsigned commutative;
773 int use_am_and_immediates;
776 memset(am, 0, sizeof(am[0]));
778 commutative = (flags & match_commutative) != 0;
779 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
780 use_am = (flags & match_am) != 0;
781 use_immediate = (flags & match_immediate) != 0;
782 assert(!use_am_and_immediates || use_immediate);
785 assert(!commutative || op1 != NULL);
786 assert(use_am || !(flags & match_8bit_am));
787 assert(use_am || !(flags & match_16bit_am));
789 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
790 (mode_bits == 16 && !(flags & match_16bit_am))) {
794 /* we can simply skip downconvs for mode neutral nodes: the upper bits
795 * can be random for these operations */
796 if (flags & match_mode_neutral) {
797 op2 = ia32_skip_downconv(op2);
799 op1 = ia32_skip_downconv(op1);
803 /* match immediates. firm nodes are normalized: constants are always on the
806 if (!(flags & match_try_am) && use_immediate) {
807 new_op2 = try_create_Immediate(op2, 0);
810 if (new_op2 == NULL &&
811 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
812 build_address(am, op2, 0);
813 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
814 if (mode_is_float(mode)) {
815 new_op2 = ia32_new_NoReg_vfp(env_cg);
819 am->op_type = ia32_AddrModeS;
820 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
822 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
824 build_address(am, op1, 0);
826 if (mode_is_float(mode)) {
827 noreg = ia32_new_NoReg_vfp(env_cg);
832 if (new_op2 != NULL) {
835 new_op1 = be_transform_node(op2);
837 am->ins_permuted = 1;
839 am->op_type = ia32_AddrModeS;
842 am->op_type = ia32_Normal;
844 if (flags & match_try_am) {
850 mode = get_irn_mode(op2);
851 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
852 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
854 new_op2 = create_upconv(op2, NULL);
855 am->ls_mode = mode_Iu;
857 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
859 new_op2 = be_transform_node(op2);
860 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
863 if (addr->base == NULL)
864 addr->base = noreg_GP;
865 if (addr->index == NULL)
866 addr->index = noreg_GP;
867 if (addr->mem == NULL)
870 am->new_op1 = new_op1;
871 am->new_op2 = new_op2;
872 am->commutative = commutative;
876 * "Fixes" a node that uses address mode by turning it into mode_T
877 * and returning a pn_ia32_res Proj.
879 * @param node the node
880 * @param am its address mode
882 * @return a Proj(pn_ia32_res) if a memory address mode is used,
885 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
890 if (am->mem_proj == NULL)
893 /* we have to create a mode_T so the old MemProj can attach to us */
894 mode = get_irn_mode(node);
895 load = get_Proj_pred(am->mem_proj);
897 be_set_transformed_node(load, node);
899 if (mode != mode_T) {
900 set_irn_mode(node, mode_T);
901 return new_rd_Proj(NULL, get_nodes_block(node), node, mode, pn_ia32_res);
908 * Construct a standard binary operation, set AM and immediate if required.
910 * @param node The original node for which the binop is created
911 * @param op1 The first operand
912 * @param op2 The second operand
913 * @param func The node constructor function
914 * @return The constructed ia32 node.
916 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
917 construct_binop_func *func, match_flags_t flags)
920 ir_node *block, *new_block, *new_node;
921 ia32_address_mode_t am;
922 ia32_address_t *addr = &am.addr;
924 block = get_nodes_block(node);
925 match_arguments(&am, block, op1, op2, NULL, flags);
927 dbgi = get_irn_dbg_info(node);
928 new_block = be_transform_node(block);
929 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
930 am.new_op1, am.new_op2);
931 set_am_attributes(new_node, &am);
932 /* we can't use source address mode anymore when using immediates */
933 if (!(flags & match_am_and_immediates) &&
934 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
935 set_ia32_am_support(new_node, ia32_am_none);
936 SET_IA32_ORIG_NODE(new_node, node);
938 new_node = fix_mem_proj(new_node, &am);
944 * Generic names for the inputs of an ia32 binary op.
947 n_ia32_l_binop_left, /**< ia32 left input */
948 n_ia32_l_binop_right, /**< ia32 right input */
949 n_ia32_l_binop_eflags /**< ia32 eflags input */
951 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
952 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
953 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
954 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
955 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
956 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
959 * Construct a binary operation which also consumes the eflags.
961 * @param node The node to transform
962 * @param func The node constructor function
963 * @param flags The match flags
964 * @return The constructor ia32 node
966 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
969 ir_node *src_block = get_nodes_block(node);
970 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
971 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
972 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
974 ir_node *block, *new_node, *new_eflags;
975 ia32_address_mode_t am;
976 ia32_address_t *addr = &am.addr;
978 match_arguments(&am, src_block, op1, op2, eflags, flags);
980 dbgi = get_irn_dbg_info(node);
981 block = be_transform_node(src_block);
982 new_eflags = be_transform_node(eflags);
983 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
984 am.new_op1, am.new_op2, new_eflags);
985 set_am_attributes(new_node, &am);
986 /* we can't use source address mode anymore when using immediates */
987 if (!(flags & match_am_and_immediates) &&
988 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
989 set_ia32_am_support(new_node, ia32_am_none);
990 SET_IA32_ORIG_NODE(new_node, node);
992 new_node = fix_mem_proj(new_node, &am);
997 static ir_node *get_fpcw(void)
1000 if (initial_fpcw != NULL)
1001 return initial_fpcw;
1003 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1004 &ia32_fp_cw_regs[REG_FPCW]);
1005 initial_fpcw = be_transform_node(fpcw);
1007 return initial_fpcw;
1011 * Construct a standard binary operation, set AM and immediate if required.
1013 * @param op1 The first operand
1014 * @param op2 The second operand
1015 * @param func The node constructor function
1016 * @return The constructed ia32 node.
1018 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1019 construct_binop_float_func *func)
1021 ir_mode *mode = get_irn_mode(node);
1023 ir_node *block, *new_block, *new_node;
1024 ia32_address_mode_t am;
1025 ia32_address_t *addr = &am.addr;
1026 ia32_x87_attr_t *attr;
1027 /* All operations are considered commutative, because there are reverse
1029 match_flags_t flags = match_commutative;
1031 /* happens for div nodes... */
1033 mode = get_divop_resmod(node);
1035 /* cannot use address mode with long double on x87 */
1036 if (get_mode_size_bits(mode) <= 64)
1039 block = get_nodes_block(node);
1040 match_arguments(&am, block, op1, op2, NULL, flags);
1042 dbgi = get_irn_dbg_info(node);
1043 new_block = be_transform_node(block);
1044 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1045 am.new_op1, am.new_op2, get_fpcw());
1046 set_am_attributes(new_node, &am);
1048 attr = get_ia32_x87_attr(new_node);
1049 attr->attr.data.ins_permuted = am.ins_permuted;
1051 SET_IA32_ORIG_NODE(new_node, node);
1053 new_node = fix_mem_proj(new_node, &am);
1059 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1061 * @param op1 The first operand
1062 * @param op2 The second operand
1063 * @param func The node constructor function
1064 * @return The constructed ia32 node.
1066 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1067 construct_shift_func *func,
1068 match_flags_t flags)
1071 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1073 assert(! mode_is_float(get_irn_mode(node)));
1074 assert(flags & match_immediate);
1075 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1077 if (flags & match_mode_neutral) {
1078 op1 = ia32_skip_downconv(op1);
1079 new_op1 = be_transform_node(op1);
1080 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1081 new_op1 = create_upconv(op1, node);
1083 new_op1 = be_transform_node(op1);
1086 /* the shift amount can be any mode that is bigger than 5 bits, since all
1087 * other bits are ignored anyway */
1088 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1089 ir_node *const op = get_Conv_op(op2);
1090 if (mode_is_float(get_irn_mode(op)))
1093 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1095 new_op2 = create_immediate_or_transform(op2, 0);
1097 dbgi = get_irn_dbg_info(node);
1098 block = get_nodes_block(node);
1099 new_block = be_transform_node(block);
1100 new_node = func(dbgi, new_block, new_op1, new_op2);
1101 SET_IA32_ORIG_NODE(new_node, node);
1103 /* lowered shift instruction may have a dependency operand, handle it here */
1104 if (get_irn_arity(node) == 3) {
1105 /* we have a dependency */
1106 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1107 add_irn_dep(new_node, new_dep);
1115 * Construct a standard unary operation, set AM and immediate if required.
1117 * @param op The operand
1118 * @param func The node constructor function
1119 * @return The constructed ia32 node.
1121 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1122 match_flags_t flags)
1125 ir_node *block, *new_block, *new_op, *new_node;
1127 assert(flags == 0 || flags == match_mode_neutral);
1128 if (flags & match_mode_neutral) {
1129 op = ia32_skip_downconv(op);
1132 new_op = be_transform_node(op);
1133 dbgi = get_irn_dbg_info(node);
1134 block = get_nodes_block(node);
1135 new_block = be_transform_node(block);
1136 new_node = func(dbgi, new_block, new_op);
1138 SET_IA32_ORIG_NODE(new_node, node);
1143 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1144 ia32_address_t *addr)
1146 ir_node *base, *index, *res;
1152 base = be_transform_node(base);
1155 index = addr->index;
1156 if (index == NULL) {
1159 index = be_transform_node(index);
1162 res = new_bd_ia32_Lea(dbgi, block, base, index);
1163 set_address(res, addr);
1169 * Returns non-zero if a given address mode has a symbolic or
1170 * numerical offset != 0.
1172 static int am_has_immediates(const ia32_address_t *addr)
1174 return addr->offset != 0 || addr->symconst_ent != NULL
1175 || addr->frame_entity || addr->use_frame;
1179 * Creates an ia32 Add.
1181 * @return the created ia32 Add node
1183 static ir_node *gen_Add(ir_node *node)
1185 ir_mode *mode = get_irn_mode(node);
1186 ir_node *op1 = get_Add_left(node);
1187 ir_node *op2 = get_Add_right(node);
1189 ir_node *block, *new_block, *new_node, *add_immediate_op;
1190 ia32_address_t addr;
1191 ia32_address_mode_t am;
1193 if (mode_is_float(mode)) {
1194 if (ia32_cg_config.use_sse2)
1195 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1196 match_commutative | match_am);
1198 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1201 ia32_mark_non_am(node);
1203 op2 = ia32_skip_downconv(op2);
1204 op1 = ia32_skip_downconv(op1);
1208 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1209 * 1. Add with immediate -> Lea
1210 * 2. Add with possible source address mode -> Add
1211 * 3. Otherwise -> Lea
1213 memset(&addr, 0, sizeof(addr));
1214 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1215 add_immediate_op = NULL;
1217 dbgi = get_irn_dbg_info(node);
1218 block = get_nodes_block(node);
1219 new_block = be_transform_node(block);
1222 if (addr.base == NULL && addr.index == NULL) {
1223 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1224 addr.symconst_sign, 0, addr.offset);
1225 be_dep_on_frame(new_node);
1226 SET_IA32_ORIG_NODE(new_node, node);
1229 /* add with immediate? */
1230 if (addr.index == NULL) {
1231 add_immediate_op = addr.base;
1232 } else if (addr.base == NULL && addr.scale == 0) {
1233 add_immediate_op = addr.index;
1236 if (add_immediate_op != NULL) {
1237 if (!am_has_immediates(&addr)) {
1238 #ifdef DEBUG_libfirm
1239 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1242 return be_transform_node(add_immediate_op);
1245 new_node = create_lea_from_address(dbgi, new_block, &addr);
1246 SET_IA32_ORIG_NODE(new_node, node);
1250 /* test if we can use source address mode */
1251 match_arguments(&am, block, op1, op2, NULL, match_commutative
1252 | match_mode_neutral | match_am | match_immediate | match_try_am);
1254 /* construct an Add with source address mode */
1255 if (am.op_type == ia32_AddrModeS) {
1256 ia32_address_t *am_addr = &am.addr;
1257 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1258 am_addr->index, am_addr->mem, am.new_op1,
1260 set_am_attributes(new_node, &am);
1261 SET_IA32_ORIG_NODE(new_node, node);
1263 new_node = fix_mem_proj(new_node, &am);
1268 /* otherwise construct a lea */
1269 new_node = create_lea_from_address(dbgi, new_block, &addr);
1270 SET_IA32_ORIG_NODE(new_node, node);
1275 * Creates an ia32 Mul.
1277 * @return the created ia32 Mul node
1279 static ir_node *gen_Mul(ir_node *node)
1281 ir_node *op1 = get_Mul_left(node);
1282 ir_node *op2 = get_Mul_right(node);
1283 ir_mode *mode = get_irn_mode(node);
1285 if (mode_is_float(mode)) {
1286 if (ia32_cg_config.use_sse2)
1287 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1288 match_commutative | match_am);
1290 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1292 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1293 match_commutative | match_am | match_mode_neutral |
1294 match_immediate | match_am_and_immediates);
1298 * Creates an ia32 Mulh.
1299 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1300 * this result while Mul returns the lower 32 bit.
1302 * @return the created ia32 Mulh node
1304 static ir_node *gen_Mulh(ir_node *node)
1306 ir_node *block = get_nodes_block(node);
1307 ir_node *new_block = be_transform_node(block);
1308 dbg_info *dbgi = get_irn_dbg_info(node);
1309 ir_node *op1 = get_Mulh_left(node);
1310 ir_node *op2 = get_Mulh_right(node);
1311 ir_mode *mode = get_irn_mode(node);
1313 ir_node *proj_res_high;
1315 if (get_mode_size_bits(mode) != 32) {
1316 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1319 if (mode_is_signed(mode)) {
1320 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1321 proj_res_high = new_rd_Proj(dbgi, new_block, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1323 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1324 proj_res_high = new_rd_Proj(dbgi, new_block, new_node, mode_Iu, pn_ia32_Mul_res_high);
1326 return proj_res_high;
1330 * Creates an ia32 And.
1332 * @return The created ia32 And node
1334 static ir_node *gen_And(ir_node *node)
1336 ir_node *op1 = get_And_left(node);
1337 ir_node *op2 = get_And_right(node);
1338 assert(! mode_is_float(get_irn_mode(node)));
1340 /* is it a zero extension? */
1341 if (is_Const(op2)) {
1342 tarval *tv = get_Const_tarval(op2);
1343 long v = get_tarval_long(tv);
1345 if (v == 0xFF || v == 0xFFFF) {
1346 dbg_info *dbgi = get_irn_dbg_info(node);
1347 ir_node *block = get_nodes_block(node);
1354 assert(v == 0xFFFF);
1357 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1362 return gen_binop(node, op1, op2, new_bd_ia32_And,
1363 match_commutative | match_mode_neutral | match_am | match_immediate);
1369 * Creates an ia32 Or.
1371 * @return The created ia32 Or node
1373 static ir_node *gen_Or(ir_node *node)
1375 ir_node *op1 = get_Or_left(node);
1376 ir_node *op2 = get_Or_right(node);
1378 assert (! mode_is_float(get_irn_mode(node)));
1379 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1380 | match_mode_neutral | match_am | match_immediate);
1386 * Creates an ia32 Eor.
1388 * @return The created ia32 Eor node
1390 static ir_node *gen_Eor(ir_node *node)
1392 ir_node *op1 = get_Eor_left(node);
1393 ir_node *op2 = get_Eor_right(node);
1395 assert(! mode_is_float(get_irn_mode(node)));
1396 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1397 | match_mode_neutral | match_am | match_immediate);
1402 * Creates an ia32 Sub.
1404 * @return The created ia32 Sub node
1406 static ir_node *gen_Sub(ir_node *node)
1408 ir_node *op1 = get_Sub_left(node);
1409 ir_node *op2 = get_Sub_right(node);
1410 ir_mode *mode = get_irn_mode(node);
1412 if (mode_is_float(mode)) {
1413 if (ia32_cg_config.use_sse2)
1414 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1416 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1419 if (is_Const(op2)) {
1420 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1424 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1425 | match_am | match_immediate);
1428 static ir_node *transform_AM_mem(ir_node *const block,
1429 ir_node *const src_val,
1430 ir_node *const src_mem,
1431 ir_node *const am_mem)
1433 if (is_NoMem(am_mem)) {
1434 return be_transform_node(src_mem);
1435 } else if (is_Proj(src_val) &&
1437 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1438 /* avoid memory loop */
1440 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1441 ir_node *const ptr_pred = get_Proj_pred(src_val);
1442 int const arity = get_Sync_n_preds(src_mem);
1447 NEW_ARR_A(ir_node*, ins, arity + 1);
1449 /* NOTE: This sometimes produces dead-code because the old sync in
1450 * src_mem might not be used anymore, we should detect this case
1451 * and kill the sync... */
1452 for (i = arity - 1; i >= 0; --i) {
1453 ir_node *const pred = get_Sync_pred(src_mem, i);
1455 /* avoid memory loop */
1456 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1459 ins[n++] = be_transform_node(pred);
1464 return new_r_Sync(block, n, ins);
1468 ins[0] = be_transform_node(src_mem);
1470 return new_r_Sync(block, 2, ins);
1475 * Create a 32bit to 64bit signed extension.
1477 * @param dbgi debug info
1478 * @param block the block where node nodes should be placed
1479 * @param val the value to extend
1480 * @param orig the original node
1482 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1483 ir_node *val, const ir_node *orig)
1488 if (ia32_cg_config.use_short_sex_eax) {
1489 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1490 be_dep_on_frame(pval);
1491 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1493 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1494 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1496 SET_IA32_ORIG_NODE(res, orig);
1501 * Generates an ia32 DivMod with additional infrastructure for the
1502 * register allocator if needed.
1504 static ir_node *create_Div(ir_node *node)
1506 dbg_info *dbgi = get_irn_dbg_info(node);
1507 ir_node *block = get_nodes_block(node);
1508 ir_node *new_block = be_transform_node(block);
1515 ir_node *sign_extension;
1516 ia32_address_mode_t am;
1517 ia32_address_t *addr = &am.addr;
1519 /* the upper bits have random contents for smaller modes */
1520 switch (get_irn_opcode(node)) {
1522 op1 = get_Div_left(node);
1523 op2 = get_Div_right(node);
1524 mem = get_Div_mem(node);
1525 mode = get_Div_resmode(node);
1528 op1 = get_Mod_left(node);
1529 op2 = get_Mod_right(node);
1530 mem = get_Mod_mem(node);
1531 mode = get_Mod_resmode(node);
1534 op1 = get_DivMod_left(node);
1535 op2 = get_DivMod_right(node);
1536 mem = get_DivMod_mem(node);
1537 mode = get_DivMod_resmode(node);
1540 panic("invalid divmod node %+F", node);
1543 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1545 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1546 is the memory of the consumed address. We can have only the second op as address
1547 in Div nodes, so check only op2. */
1548 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1550 if (mode_is_signed(mode)) {
1551 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1552 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1553 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1555 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1556 be_dep_on_frame(sign_extension);
1558 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1559 addr->index, new_mem, am.new_op2,
1560 am.new_op1, sign_extension);
1563 set_irn_pinned(new_node, get_irn_pinned(node));
1565 set_am_attributes(new_node, &am);
1566 SET_IA32_ORIG_NODE(new_node, node);
1568 new_node = fix_mem_proj(new_node, &am);
1574 * Generates an ia32 Mod.
1576 static ir_node *gen_Mod(ir_node *node)
1578 return create_Div(node);
1582 * Generates an ia32 Div.
1584 static ir_node *gen_Div(ir_node *node)
1586 return create_Div(node);
1590 * Generates an ia32 DivMod.
1592 static ir_node *gen_DivMod(ir_node *node)
1594 return create_Div(node);
1600 * Creates an ia32 floating Div.
1602 * @return The created ia32 xDiv node
1604 static ir_node *gen_Quot(ir_node *node)
1606 ir_node *op1 = get_Quot_left(node);
1607 ir_node *op2 = get_Quot_right(node);
1609 if (ia32_cg_config.use_sse2) {
1610 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1612 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1618 * Creates an ia32 Shl.
1620 * @return The created ia32 Shl node
1622 static ir_node *gen_Shl(ir_node *node)
1624 ir_node *left = get_Shl_left(node);
1625 ir_node *right = get_Shl_right(node);
1627 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1628 match_mode_neutral | match_immediate);
1632 * Creates an ia32 Shr.
1634 * @return The created ia32 Shr node
1636 static ir_node *gen_Shr(ir_node *node)
1638 ir_node *left = get_Shr_left(node);
1639 ir_node *right = get_Shr_right(node);
1641 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1647 * Creates an ia32 Sar.
1649 * @return The created ia32 Shrs node
1651 static ir_node *gen_Shrs(ir_node *node)
1653 ir_node *left = get_Shrs_left(node);
1654 ir_node *right = get_Shrs_right(node);
1656 if (is_Const(right)) {
1657 tarval *tv = get_Const_tarval(right);
1658 long val = get_tarval_long(tv);
1660 /* this is a sign extension */
1661 dbg_info *dbgi = get_irn_dbg_info(node);
1662 ir_node *block = be_transform_node(get_nodes_block(node));
1663 ir_node *new_op = be_transform_node(left);
1665 return create_sex_32_64(dbgi, block, new_op, node);
1669 /* 8 or 16 bit sign extension? */
1670 if (is_Const(right) && is_Shl(left)) {
1671 ir_node *shl_left = get_Shl_left(left);
1672 ir_node *shl_right = get_Shl_right(left);
1673 if (is_Const(shl_right)) {
1674 tarval *tv1 = get_Const_tarval(right);
1675 tarval *tv2 = get_Const_tarval(shl_right);
1676 if (tv1 == tv2 && tarval_is_long(tv1)) {
1677 long val = get_tarval_long(tv1);
1678 if (val == 16 || val == 24) {
1679 dbg_info *dbgi = get_irn_dbg_info(node);
1680 ir_node *block = get_nodes_block(node);
1690 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1699 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1705 * Creates an ia32 Rol.
1707 * @param op1 The first operator
1708 * @param op2 The second operator
1709 * @return The created ia32 RotL node
1711 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1713 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1719 * Creates an ia32 Ror.
1720 * NOTE: There is no RotR with immediate because this would always be a RotL
1721 * "imm-mode_size_bits" which can be pre-calculated.
1723 * @param op1 The first operator
1724 * @param op2 The second operator
1725 * @return The created ia32 RotR node
1727 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1729 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1735 * Creates an ia32 RotR or RotL (depending on the found pattern).
1737 * @return The created ia32 RotL or RotR node
1739 static ir_node *gen_Rotl(ir_node *node)
1741 ir_node *rotate = NULL;
1742 ir_node *op1 = get_Rotl_left(node);
1743 ir_node *op2 = get_Rotl_right(node);
1745 /* Firm has only RotL, so we are looking for a right (op2)
1746 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1747 that means we can create a RotR instead of an Add and a RotL */
1751 ir_node *left = get_Add_left(add);
1752 ir_node *right = get_Add_right(add);
1753 if (is_Const(right)) {
1754 tarval *tv = get_Const_tarval(right);
1755 ir_mode *mode = get_irn_mode(node);
1756 long bits = get_mode_size_bits(mode);
1758 if (is_Minus(left) &&
1759 tarval_is_long(tv) &&
1760 get_tarval_long(tv) == bits &&
1763 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1764 rotate = gen_Ror(node, op1, get_Minus_op(left));
1769 if (rotate == NULL) {
1770 rotate = gen_Rol(node, op1, op2);
1779 * Transforms a Minus node.
1781 * @return The created ia32 Minus node
1783 static ir_node *gen_Minus(ir_node *node)
1785 ir_node *op = get_Minus_op(node);
1786 ir_node *block = be_transform_node(get_nodes_block(node));
1787 dbg_info *dbgi = get_irn_dbg_info(node);
1788 ir_mode *mode = get_irn_mode(node);
1793 if (mode_is_float(mode)) {
1794 ir_node *new_op = be_transform_node(op);
1795 if (ia32_cg_config.use_sse2) {
1796 /* TODO: non-optimal... if we have many xXors, then we should
1797 * rather create a load for the const and use that instead of
1798 * several AM nodes... */
1799 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1801 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1802 noreg_GP, nomem, new_op, noreg_xmm);
1804 size = get_mode_size_bits(mode);
1805 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1807 set_ia32_am_sc(new_node, ent);
1808 set_ia32_op_type(new_node, ia32_AddrModeS);
1809 set_ia32_ls_mode(new_node, mode);
1811 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1814 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1817 SET_IA32_ORIG_NODE(new_node, node);
1823 * Transforms a Not node.
1825 * @return The created ia32 Not node
1827 static ir_node *gen_Not(ir_node *node)
1829 ir_node *op = get_Not_op(node);
1831 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1832 assert (! mode_is_float(get_irn_mode(node)));
1834 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1840 * Transforms an Abs node.
1842 * @return The created ia32 Abs node
1844 static ir_node *gen_Abs(ir_node *node)
1846 ir_node *block = get_nodes_block(node);
1847 ir_node *new_block = be_transform_node(block);
1848 ir_node *op = get_Abs_op(node);
1849 dbg_info *dbgi = get_irn_dbg_info(node);
1850 ir_mode *mode = get_irn_mode(node);
1856 if (mode_is_float(mode)) {
1857 new_op = be_transform_node(op);
1859 if (ia32_cg_config.use_sse2) {
1860 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1861 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1862 noreg_GP, nomem, new_op, noreg_fp);
1864 size = get_mode_size_bits(mode);
1865 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1867 set_ia32_am_sc(new_node, ent);
1869 SET_IA32_ORIG_NODE(new_node, node);
1871 set_ia32_op_type(new_node, ia32_AddrModeS);
1872 set_ia32_ls_mode(new_node, mode);
1874 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1875 SET_IA32_ORIG_NODE(new_node, node);
1878 ir_node *xor, *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 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1889 nomem, new_op, sign_extension);
1890 SET_IA32_ORIG_NODE(xor, node);
1892 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1893 nomem, xor, sign_extension);
1894 SET_IA32_ORIG_NODE(new_node, node);
1901 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1903 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1905 dbg_info *dbgi = get_irn_dbg_info(cmp);
1906 ir_node *block = get_nodes_block(cmp);
1907 ir_node *new_block = be_transform_node(block);
1908 ir_node *op1 = be_transform_node(x);
1909 ir_node *op2 = be_transform_node(n);
1911 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1915 * Transform a node returning a "flag" result.
1917 * @param node the node to transform
1918 * @param pnc_out the compare mode to use
1920 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1927 /* we have a Cmp as input */
1928 if (is_Proj(node)) {
1929 ir_node *pred = get_Proj_pred(node);
1931 pn_Cmp pnc = get_Proj_proj(node);
1932 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1933 ir_node *l = get_Cmp_left(pred);
1934 ir_node *r = get_Cmp_right(pred);
1936 ir_node *la = get_And_left(l);
1937 ir_node *ra = get_And_right(l);
1939 ir_node *c = get_Shl_left(la);
1940 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1941 /* (1 << n) & ra) */
1942 ir_node *n = get_Shl_right(la);
1943 flags = gen_bt(pred, ra, n);
1944 /* we must generate a Jc/Jnc jump */
1945 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1948 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1953 ir_node *c = get_Shl_left(ra);
1954 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1955 /* la & (1 << n)) */
1956 ir_node *n = get_Shl_right(ra);
1957 flags = gen_bt(pred, la, n);
1958 /* we must generate a Jc/Jnc jump */
1959 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1962 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1968 /* add ia32 compare flags */
1970 ir_node *l = get_Cmp_left(pred);
1971 ir_mode *mode = get_irn_mode(l);
1972 if (mode_is_float(mode))
1973 pnc |= ia32_pn_Cmp_float;
1974 else if (! mode_is_signed(mode))
1975 pnc |= ia32_pn_Cmp_unsigned;
1978 flags = be_transform_node(pred);
1983 /* a mode_b value, we have to compare it against 0 */
1984 dbgi = get_irn_dbg_info(node);
1985 new_block = be_transform_node(get_nodes_block(node));
1986 new_op = be_transform_node(node);
1987 flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op,
1988 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1989 *pnc_out = pn_Cmp_Lg;
1994 * Transforms a Load.
1996 * @return the created ia32 Load node
1998 static ir_node *gen_Load(ir_node *node)
2000 ir_node *old_block = get_nodes_block(node);
2001 ir_node *block = be_transform_node(old_block);
2002 ir_node *ptr = get_Load_ptr(node);
2003 ir_node *mem = get_Load_mem(node);
2004 ir_node *new_mem = be_transform_node(mem);
2007 dbg_info *dbgi = get_irn_dbg_info(node);
2008 ir_mode *mode = get_Load_mode(node);
2011 ia32_address_t addr;
2013 /* construct load address */
2014 memset(&addr, 0, sizeof(addr));
2015 ia32_create_address_mode(&addr, ptr, 0);
2022 base = be_transform_node(base);
2025 if (index == NULL) {
2028 index = be_transform_node(index);
2031 if (mode_is_float(mode)) {
2032 if (ia32_cg_config.use_sse2) {
2033 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2035 res_mode = mode_xmm;
2037 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2039 res_mode = mode_vfp;
2042 assert(mode != mode_b);
2044 /* create a conv node with address mode for smaller modes */
2045 if (get_mode_size_bits(mode) < 32) {
2046 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2047 new_mem, noreg_GP, mode);
2049 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2054 set_irn_pinned(new_node, get_irn_pinned(node));
2055 set_ia32_op_type(new_node, ia32_AddrModeS);
2056 set_ia32_ls_mode(new_node, mode);
2057 set_address(new_node, &addr);
2059 if (get_irn_pinned(node) == op_pin_state_floats) {
2060 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
2061 && pn_ia32_vfld_res == pn_ia32_Load_res
2062 && pn_ia32_Load_res == pn_ia32_res);
2063 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2066 SET_IA32_ORIG_NODE(new_node, node);
2068 be_dep_on_frame(new_node);
2072 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2073 ir_node *ptr, ir_node *other)
2080 /* we only use address mode if we're the only user of the load */
2081 if (get_irn_n_edges(node) > 1)
2084 load = get_Proj_pred(node);
2087 if (get_nodes_block(load) != block)
2090 /* store should have the same pointer as the load */
2091 if (get_Load_ptr(load) != ptr)
2094 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2095 if (other != NULL &&
2096 get_nodes_block(other) == block &&
2097 heights_reachable_in_block(heights, other, load)) {
2101 if (prevents_AM(block, load, mem))
2103 /* Store should be attached to the load via mem */
2104 assert(heights_reachable_in_block(heights, mem, load));
2109 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2110 ir_node *mem, ir_node *ptr, ir_mode *mode,
2111 construct_binop_dest_func *func,
2112 construct_binop_dest_func *func8bit,
2113 match_flags_t flags)
2115 ir_node *src_block = get_nodes_block(node);
2123 ia32_address_mode_t am;
2124 ia32_address_t *addr = &am.addr;
2125 memset(&am, 0, sizeof(am));
2127 assert(flags & match_immediate); /* there is no destam node without... */
2128 commutative = (flags & match_commutative) != 0;
2130 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2131 build_address(&am, op1, ia32_create_am_double_use);
2132 new_op = create_immediate_or_transform(op2, 0);
2133 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2134 build_address(&am, op2, ia32_create_am_double_use);
2135 new_op = create_immediate_or_transform(op1, 0);
2140 if (addr->base == NULL)
2141 addr->base = noreg_GP;
2142 if (addr->index == NULL)
2143 addr->index = noreg_GP;
2144 if (addr->mem == NULL)
2147 dbgi = get_irn_dbg_info(node);
2148 block = be_transform_node(src_block);
2149 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2151 if (get_mode_size_bits(mode) == 8) {
2152 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2154 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2156 set_address(new_node, addr);
2157 set_ia32_op_type(new_node, ia32_AddrModeD);
2158 set_ia32_ls_mode(new_node, mode);
2159 SET_IA32_ORIG_NODE(new_node, node);
2161 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2162 mem_proj = be_transform_node(am.mem_proj);
2163 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2168 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2169 ir_node *ptr, ir_mode *mode,
2170 construct_unop_dest_func *func)
2172 ir_node *src_block = get_nodes_block(node);
2178 ia32_address_mode_t am;
2179 ia32_address_t *addr = &am.addr;
2181 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2184 memset(&am, 0, sizeof(am));
2185 build_address(&am, op, ia32_create_am_double_use);
2187 dbgi = get_irn_dbg_info(node);
2188 block = be_transform_node(src_block);
2189 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2190 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2191 set_address(new_node, addr);
2192 set_ia32_op_type(new_node, ia32_AddrModeD);
2193 set_ia32_ls_mode(new_node, mode);
2194 SET_IA32_ORIG_NODE(new_node, node);
2196 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2197 mem_proj = be_transform_node(am.mem_proj);
2198 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2203 static pn_Cmp ia32_get_negated_pnc(pn_Cmp pnc)
2205 ir_mode *mode = pnc & ia32_pn_Cmp_float ? mode_F : mode_Iu;
2206 return get_negated_pnc(pnc, mode);
2209 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2211 ir_mode *mode = get_irn_mode(node);
2212 ir_node *mux_true = get_Mux_true(node);
2213 ir_node *mux_false = get_Mux_false(node);
2223 ia32_address_t addr;
2225 if (get_mode_size_bits(mode) != 8)
2228 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2230 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2236 cond = get_Mux_sel(node);
2237 flags = get_flags_node(cond, &pnc);
2238 /* we can't handle the float special cases with SetM */
2239 if (pnc & ia32_pn_Cmp_float)
2242 pnc = ia32_get_negated_pnc(pnc);
2244 build_address_ptr(&addr, ptr, mem);
2246 dbgi = get_irn_dbg_info(node);
2247 block = get_nodes_block(node);
2248 new_block = be_transform_node(block);
2249 new_mem = be_transform_node(mem);
2250 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2251 addr.index, addr.mem, flags, pnc);
2252 set_address(new_node, &addr);
2253 set_ia32_op_type(new_node, ia32_AddrModeD);
2254 set_ia32_ls_mode(new_node, mode);
2255 SET_IA32_ORIG_NODE(new_node, node);
2260 static ir_node *try_create_dest_am(ir_node *node)
2262 ir_node *val = get_Store_value(node);
2263 ir_node *mem = get_Store_mem(node);
2264 ir_node *ptr = get_Store_ptr(node);
2265 ir_mode *mode = get_irn_mode(val);
2266 unsigned bits = get_mode_size_bits(mode);
2271 /* handle only GP modes for now... */
2272 if (!ia32_mode_needs_gp_reg(mode))
2276 /* store must be the only user of the val node */
2277 if (get_irn_n_edges(val) > 1)
2279 /* skip pointless convs */
2281 ir_node *conv_op = get_Conv_op(val);
2282 ir_mode *pred_mode = get_irn_mode(conv_op);
2283 if (!ia32_mode_needs_gp_reg(pred_mode))
2285 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2293 /* value must be in the same block */
2294 if (get_nodes_block(node) != get_nodes_block(val))
2297 switch (get_irn_opcode(val)) {
2299 op1 = get_Add_left(val);
2300 op2 = get_Add_right(val);
2301 if (ia32_cg_config.use_incdec) {
2302 if (is_Const_1(op2)) {
2303 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2305 } else if (is_Const_Minus_1(op2)) {
2306 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2310 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2311 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2312 match_commutative | match_immediate);
2315 op1 = get_Sub_left(val);
2316 op2 = get_Sub_right(val);
2317 if (is_Const(op2)) {
2318 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2320 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2321 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2325 op1 = get_And_left(val);
2326 op2 = get_And_right(val);
2327 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2328 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2329 match_commutative | match_immediate);
2332 op1 = get_Or_left(val);
2333 op2 = get_Or_right(val);
2334 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2335 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2336 match_commutative | match_immediate);
2339 op1 = get_Eor_left(val);
2340 op2 = get_Eor_right(val);
2341 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2342 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2343 match_commutative | match_immediate);
2346 op1 = get_Shl_left(val);
2347 op2 = get_Shl_right(val);
2348 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2349 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2353 op1 = get_Shr_left(val);
2354 op2 = get_Shr_right(val);
2355 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2356 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2360 op1 = get_Shrs_left(val);
2361 op2 = get_Shrs_right(val);
2362 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2363 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2367 op1 = get_Rotl_left(val);
2368 op2 = get_Rotl_right(val);
2369 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2370 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2373 /* TODO: match ROR patterns... */
2375 new_node = try_create_SetMem(val, ptr, mem);
2379 op1 = get_Minus_op(val);
2380 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2383 /* should be lowered already */
2384 assert(mode != mode_b);
2385 op1 = get_Not_op(val);
2386 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2392 if (new_node != NULL) {
2393 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2394 get_irn_pinned(node) == op_pin_state_pinned) {
2395 set_irn_pinned(new_node, op_pin_state_pinned);
2402 static bool possible_int_mode_for_fp(ir_mode *mode)
2406 if (!mode_is_signed(mode))
2408 size = get_mode_size_bits(mode);
2409 if (size != 16 && size != 32)
2414 static int is_float_to_int_conv(const ir_node *node)
2416 ir_mode *mode = get_irn_mode(node);
2420 if (!possible_int_mode_for_fp(mode))
2425 conv_op = get_Conv_op(node);
2426 conv_mode = get_irn_mode(conv_op);
2428 if (!mode_is_float(conv_mode))
2435 * Transform a Store(floatConst) into a sequence of
2438 * @return the created ia32 Store node
2440 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2442 ir_mode *mode = get_irn_mode(cns);
2443 unsigned size = get_mode_size_bytes(mode);
2444 tarval *tv = get_Const_tarval(cns);
2445 ir_node *block = get_nodes_block(node);
2446 ir_node *new_block = be_transform_node(block);
2447 ir_node *ptr = get_Store_ptr(node);
2448 ir_node *mem = get_Store_mem(node);
2449 dbg_info *dbgi = get_irn_dbg_info(node);
2453 ia32_address_t addr;
2455 assert(size % 4 == 0);
2458 build_address_ptr(&addr, ptr, mem);
2462 get_tarval_sub_bits(tv, ofs) |
2463 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2464 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2465 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2466 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2468 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2469 addr.index, addr.mem, imm);
2471 set_irn_pinned(new_node, get_irn_pinned(node));
2472 set_ia32_op_type(new_node, ia32_AddrModeD);
2473 set_ia32_ls_mode(new_node, mode_Iu);
2474 set_address(new_node, &addr);
2475 SET_IA32_ORIG_NODE(new_node, node);
2478 ins[i++] = new_node;
2483 } while (size != 0);
2486 return new_rd_Sync(dbgi, new_block, i, ins);
2493 * Generate a vfist or vfisttp instruction.
2495 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2496 ir_node *mem, ir_node *val, ir_node **fist)
2500 if (ia32_cg_config.use_fisttp) {
2501 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2502 if other users exists */
2503 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2504 ir_node *value = new_r_Proj(block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2505 be_new_Keep(block, 1, &value);
2507 new_node = new_r_Proj(block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2510 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2513 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2519 * Transforms a general (no special case) Store.
2521 * @return the created ia32 Store node
2523 static ir_node *gen_general_Store(ir_node *node)
2525 ir_node *val = get_Store_value(node);
2526 ir_mode *mode = get_irn_mode(val);
2527 ir_node *block = get_nodes_block(node);
2528 ir_node *new_block = be_transform_node(block);
2529 ir_node *ptr = get_Store_ptr(node);
2530 ir_node *mem = get_Store_mem(node);
2531 dbg_info *dbgi = get_irn_dbg_info(node);
2532 ir_node *new_val, *new_node, *store;
2533 ia32_address_t addr;
2535 /* check for destination address mode */
2536 new_node = try_create_dest_am(node);
2537 if (new_node != NULL)
2540 /* construct store address */
2541 memset(&addr, 0, sizeof(addr));
2542 ia32_create_address_mode(&addr, ptr, 0);
2544 if (addr.base == NULL) {
2545 addr.base = noreg_GP;
2547 addr.base = be_transform_node(addr.base);
2550 if (addr.index == NULL) {
2551 addr.index = noreg_GP;
2553 addr.index = be_transform_node(addr.index);
2555 addr.mem = be_transform_node(mem);
2557 if (mode_is_float(mode)) {
2558 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2560 while (is_Conv(val) && mode == get_irn_mode(val)) {
2561 ir_node *op = get_Conv_op(val);
2562 if (!mode_is_float(get_irn_mode(op)))
2566 new_val = be_transform_node(val);
2567 if (ia32_cg_config.use_sse2) {
2568 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2569 addr.index, addr.mem, new_val);
2571 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2572 addr.index, addr.mem, new_val, mode);
2575 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2576 val = get_Conv_op(val);
2578 /* TODO: is this optimisation still necessary at all (middleend)? */
2579 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2580 while (is_Conv(val)) {
2581 ir_node *op = get_Conv_op(val);
2582 if (!mode_is_float(get_irn_mode(op)))
2584 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2588 new_val = be_transform_node(val);
2589 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2591 new_val = create_immediate_or_transform(val, 0);
2592 assert(mode != mode_b);
2594 if (get_mode_size_bits(mode) == 8) {
2595 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2596 addr.index, addr.mem, new_val);
2598 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2599 addr.index, addr.mem, new_val);
2604 set_irn_pinned(store, get_irn_pinned(node));
2605 set_ia32_op_type(store, ia32_AddrModeD);
2606 set_ia32_ls_mode(store, mode);
2608 set_address(store, &addr);
2609 SET_IA32_ORIG_NODE(store, node);
2615 * Transforms a Store.
2617 * @return the created ia32 Store node
2619 static ir_node *gen_Store(ir_node *node)
2621 ir_node *val = get_Store_value(node);
2622 ir_mode *mode = get_irn_mode(val);
2624 if (mode_is_float(mode) && is_Const(val)) {
2625 /* We can transform every floating const store
2626 into a sequence of integer stores.
2627 If the constant is already in a register,
2628 it would be better to use it, but we don't
2629 have this information here. */
2630 return gen_float_const_Store(node, val);
2632 return gen_general_Store(node);
2636 * Transforms a Switch.
2638 * @return the created ia32 SwitchJmp node
2640 static ir_node *create_Switch(ir_node *node)
2642 dbg_info *dbgi = get_irn_dbg_info(node);
2643 ir_node *block = be_transform_node(get_nodes_block(node));
2644 ir_node *sel = get_Cond_selector(node);
2645 ir_node *new_sel = be_transform_node(sel);
2646 long switch_min = LONG_MAX;
2647 long switch_max = LONG_MIN;
2648 long default_pn = get_Cond_default_proj(node);
2650 const ir_edge_t *edge;
2652 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2654 /* determine the smallest switch case value */
2655 foreach_out_edge(node, edge) {
2656 ir_node *proj = get_edge_src_irn(edge);
2657 long pn = get_Proj_proj(proj);
2658 if (pn == default_pn)
2661 if (pn < switch_min)
2663 if (pn > switch_max)
2667 if ((unsigned long) (switch_max - switch_min) > 128000) {
2668 panic("Size of switch %+F bigger than 128000", node);
2671 if (switch_min != 0) {
2672 /* if smallest switch case is not 0 we need an additional sub */
2673 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2674 add_ia32_am_offs_int(new_sel, -switch_min);
2675 set_ia32_op_type(new_sel, ia32_AddrModeS);
2677 SET_IA32_ORIG_NODE(new_sel, node);
2680 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2681 SET_IA32_ORIG_NODE(new_node, node);
2687 * Transform a Cond node.
2689 static ir_node *gen_Cond(ir_node *node)
2691 ir_node *block = get_nodes_block(node);
2692 ir_node *new_block = be_transform_node(block);
2693 dbg_info *dbgi = get_irn_dbg_info(node);
2694 ir_node *sel = get_Cond_selector(node);
2695 ir_mode *sel_mode = get_irn_mode(sel);
2696 ir_node *flags = NULL;
2700 if (sel_mode != mode_b) {
2701 return create_Switch(node);
2704 /* we get flags from a Cmp */
2705 flags = get_flags_node(sel, &pnc);
2707 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2708 SET_IA32_ORIG_NODE(new_node, node);
2714 * Transform a be_Copy.
2716 static ir_node *gen_be_Copy(ir_node *node)
2718 ir_node *new_node = be_duplicate_node(node);
2719 ir_mode *mode = get_irn_mode(new_node);
2721 if (ia32_mode_needs_gp_reg(mode)) {
2722 set_irn_mode(new_node, mode_Iu);
2728 static ir_node *create_Fucom(ir_node *node)
2730 dbg_info *dbgi = get_irn_dbg_info(node);
2731 ir_node *block = get_nodes_block(node);
2732 ir_node *new_block = be_transform_node(block);
2733 ir_node *left = get_Cmp_left(node);
2734 ir_node *new_left = be_transform_node(left);
2735 ir_node *right = get_Cmp_right(node);
2739 if (ia32_cg_config.use_fucomi) {
2740 new_right = be_transform_node(right);
2741 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2743 set_ia32_commutative(new_node);
2744 SET_IA32_ORIG_NODE(new_node, node);
2746 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2747 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2749 new_right = be_transform_node(right);
2750 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2753 set_ia32_commutative(new_node);
2755 SET_IA32_ORIG_NODE(new_node, node);
2757 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2758 SET_IA32_ORIG_NODE(new_node, node);
2764 static ir_node *create_Ucomi(ir_node *node)
2766 dbg_info *dbgi = get_irn_dbg_info(node);
2767 ir_node *src_block = get_nodes_block(node);
2768 ir_node *new_block = be_transform_node(src_block);
2769 ir_node *left = get_Cmp_left(node);
2770 ir_node *right = get_Cmp_right(node);
2772 ia32_address_mode_t am;
2773 ia32_address_t *addr = &am.addr;
2775 match_arguments(&am, src_block, left, right, NULL,
2776 match_commutative | match_am);
2778 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2779 addr->mem, am.new_op1, am.new_op2,
2781 set_am_attributes(new_node, &am);
2783 SET_IA32_ORIG_NODE(new_node, node);
2785 new_node = fix_mem_proj(new_node, &am);
2791 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2792 * to fold an and into a test node
2794 static bool can_fold_test_and(ir_node *node)
2796 const ir_edge_t *edge;
2798 /** we can only have eq and lg projs */
2799 foreach_out_edge(node, edge) {
2800 ir_node *proj = get_edge_src_irn(edge);
2801 pn_Cmp pnc = get_Proj_proj(proj);
2802 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2810 * returns true if it is assured, that the upper bits of a node are "clean"
2811 * which means for a 16 or 8 bit value, that the upper bits in the register
2812 * are 0 for unsigned and a copy of the last significant bit for signed
2815 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2817 assert(ia32_mode_needs_gp_reg(mode));
2818 if (get_mode_size_bits(mode) >= 32)
2821 if (is_Proj(transformed_node))
2822 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2824 switch (get_ia32_irn_opcode(transformed_node)) {
2825 case iro_ia32_Conv_I2I:
2826 case iro_ia32_Conv_I2I8Bit: {
2827 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2828 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2830 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2837 if (mode_is_signed(mode)) {
2838 return false; /* TODO handle signed modes */
2840 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2841 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2842 const ia32_immediate_attr_t *attr
2843 = get_ia32_immediate_attr_const(right);
2844 if (attr->symconst == 0 &&
2845 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2849 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2853 /* TODO too conservative if shift amount is constant */
2854 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2857 if (!mode_is_signed(mode)) {
2859 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2860 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2862 /* TODO if one is known to be zero extended, then || is sufficient */
2867 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2868 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2870 case iro_ia32_Const:
2871 case iro_ia32_Immediate: {
2872 const ia32_immediate_attr_t *attr =
2873 get_ia32_immediate_attr_const(transformed_node);
2874 if (mode_is_signed(mode)) {
2875 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2876 return shifted == 0 || shifted == -1;
2878 unsigned long shifted = (unsigned long)attr->offset;
2879 shifted >>= get_mode_size_bits(mode);
2880 return shifted == 0;
2890 * Generate code for a Cmp.
2892 static ir_node *gen_Cmp(ir_node *node)
2894 dbg_info *dbgi = get_irn_dbg_info(node);
2895 ir_node *block = get_nodes_block(node);
2896 ir_node *new_block = be_transform_node(block);
2897 ir_node *left = get_Cmp_left(node);
2898 ir_node *right = get_Cmp_right(node);
2899 ir_mode *cmp_mode = get_irn_mode(left);
2901 ia32_address_mode_t am;
2902 ia32_address_t *addr = &am.addr;
2905 if (mode_is_float(cmp_mode)) {
2906 if (ia32_cg_config.use_sse2) {
2907 return create_Ucomi(node);
2909 return create_Fucom(node);
2913 assert(ia32_mode_needs_gp_reg(cmp_mode));
2915 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2916 cmp_unsigned = !mode_is_signed(cmp_mode);
2917 if (is_Const_0(right) &&
2919 get_irn_n_edges(left) == 1 &&
2920 can_fold_test_and(node)) {
2921 /* Test(and_left, and_right) */
2922 ir_node *and_left = get_And_left(left);
2923 ir_node *and_right = get_And_right(left);
2925 /* matze: code here used mode instead of cmd_mode, I think it is always
2926 * the same as cmp_mode, but I leave this here to see if this is really
2929 assert(get_irn_mode(and_left) == cmp_mode);
2931 match_arguments(&am, block, and_left, and_right, NULL,
2933 match_am | match_8bit_am | match_16bit_am |
2934 match_am_and_immediates | match_immediate);
2936 /* use 32bit compare mode if possible since the opcode is smaller */
2937 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2938 upper_bits_clean(am.new_op2, cmp_mode)) {
2939 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2942 if (get_mode_size_bits(cmp_mode) == 8) {
2943 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2944 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2947 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2948 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2951 /* Cmp(left, right) */
2952 match_arguments(&am, block, left, right, NULL,
2953 match_commutative | match_am | match_8bit_am |
2954 match_16bit_am | match_am_and_immediates |
2956 /* use 32bit compare mode if possible since the opcode is smaller */
2957 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2958 upper_bits_clean(am.new_op2, cmp_mode)) {
2959 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2962 if (get_mode_size_bits(cmp_mode) == 8) {
2963 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2964 addr->index, addr->mem, am.new_op1,
2965 am.new_op2, am.ins_permuted,
2968 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2969 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2972 set_am_attributes(new_node, &am);
2973 set_ia32_ls_mode(new_node, cmp_mode);
2975 SET_IA32_ORIG_NODE(new_node, node);
2977 new_node = fix_mem_proj(new_node, &am);
2982 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2985 dbg_info *dbgi = get_irn_dbg_info(node);
2986 ir_node *block = get_nodes_block(node);
2987 ir_node *new_block = be_transform_node(block);
2988 ir_node *val_true = get_Mux_true(node);
2989 ir_node *val_false = get_Mux_false(node);
2991 ia32_address_mode_t am;
2992 ia32_address_t *addr;
2994 assert(ia32_cg_config.use_cmov);
2995 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2999 match_arguments(&am, block, val_false, val_true, flags,
3000 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3002 if (am.ins_permuted)
3003 pnc = ia32_get_negated_pnc(pnc);
3005 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3006 addr->mem, am.new_op1, am.new_op2, new_flags,
3008 set_am_attributes(new_node, &am);
3010 SET_IA32_ORIG_NODE(new_node, node);
3012 new_node = fix_mem_proj(new_node, &am);
3018 * Creates a ia32 Setcc instruction.
3020 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3021 ir_node *flags, pn_Cmp pnc,
3024 ir_mode *mode = get_irn_mode(orig_node);
3027 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, pnc);
3028 SET_IA32_ORIG_NODE(new_node, orig_node);
3030 /* we might need to conv the result up */
3031 if (get_mode_size_bits(mode) > 8) {
3032 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3033 nomem, new_node, mode_Bu);
3034 SET_IA32_ORIG_NODE(new_node, orig_node);
3041 * Create instruction for an unsigned Difference or Zero.
3043 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3045 ir_mode *mode = get_irn_mode(psi);
3055 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3056 match_mode_neutral | match_am | match_immediate | match_two_users);
3058 block = get_nodes_block(new_node);
3060 if (is_Proj(new_node)) {
3061 sub = get_Proj_pred(new_node);
3062 assert(is_ia32_Sub(sub));
3065 set_irn_mode(sub, mode_T);
3066 new_node = new_rd_Proj(NULL, block, sub, mode, pn_ia32_res);
3068 eflags = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_Sub_flags);
3070 dbgi = get_irn_dbg_info(psi);
3071 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3072 not = new_bd_ia32_Not(dbgi, block, sbb);
3074 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, not);
3075 set_ia32_commutative(new_node);
3080 * Create an const array of two float consts.
3082 * @param c0 the first constant
3083 * @param c1 the second constant
3084 * @param new_mode IN/OUT for the mode of the constants, if NULL
3085 * smallest possible mode will be used
3087 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode) {
3089 ir_mode *mode = *new_mode;
3091 ir_initializer_t *initializer;
3092 tarval *tv0 = get_Const_tarval(c0);
3093 tarval *tv1 = get_Const_tarval(c1);
3096 /* detect the best mode for the constants */
3097 mode = get_tarval_mode(tv0);
3099 if (mode != mode_F) {
3100 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3101 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3103 tv0 = tarval_convert_to(tv0, mode);
3104 tv1 = tarval_convert_to(tv1, mode);
3105 } else if (mode != mode_D) {
3106 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3107 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3109 tv0 = tarval_convert_to(tv0, mode);
3110 tv1 = tarval_convert_to(tv1, mode);
3117 tp = ia32_create_float_type(mode, 4);
3118 tp = ia32_create_float_array(tp);
3120 ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
3122 set_entity_ld_ident(ent, get_entity_ident(ent));
3123 set_entity_visibility(ent, ir_visibility_local);
3124 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3126 initializer = create_initializer_compound(2);
3128 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3129 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3131 set_entity_initializer(ent, initializer);
3138 * Possible transformations for creating a Setcc.
3140 enum setcc_transform_insn {
3153 typedef struct setcc_transform {
3155 unsigned permutate_cmp_ins;
3158 enum setcc_transform_insn transform;
3162 } setcc_transform_t;
3165 * Setcc can only handle 0 and 1 result.
3166 * Find a transformation that creates 0 and 1 from
3169 static void find_const_transform(pn_Cmp pnc, tarval *t, tarval *f, setcc_transform_t *res, int can_permutate)
3174 res->permutate_cmp_ins = 0;
3176 if (tarval_is_null(t)) {
3180 pnc = ia32_get_negated_pnc(pnc);
3181 } else if (tarval_cmp(t, f) == pn_Cmp_Lt) {
3182 // now, t is the bigger one
3186 pnc = ia32_get_negated_pnc(pnc);
3190 if (tarval_is_one(t)) {
3191 res->steps[step].transform = SETCC_TR_SET;
3192 res->num_steps = ++step;
3196 if (! tarval_is_null(f)) {
3197 tarval *t_sub = tarval_sub(t, f, NULL);
3200 res->steps[step].transform = SETCC_TR_ADD;
3202 if (t == tarval_bad)
3203 panic("constant subtract failed");
3204 if (! tarval_is_long(f))
3205 panic("tarval is not long");
3207 res->steps[step].val = get_tarval_long(f);
3209 f = tarval_sub(f, f, NULL);
3210 assert(tarval_is_null(f));
3213 if (tarval_is_minus_one(t)) {
3214 if (pnc == (pn_Cmp_Lt | ia32_pn_Cmp_unsigned)) {
3215 res->steps[step].transform = SETCC_TR_SBB;
3216 res->num_steps = ++step;
3218 res->steps[step].transform = SETCC_TR_NEG;
3220 res->steps[step].transform = SETCC_TR_SET;
3221 res->num_steps = ++step;
3225 if (tarval_is_long(t)) {
3226 long v = get_tarval_long(t);
3228 if (pnc & ia32_pn_Cmp_unsigned) {
3229 if (pnc == (pn_Cmp_Lt | ia32_pn_Cmp_unsigned)) {
3230 res->steps[step].transform = SETCC_TR_AND;
3231 res->steps[step].val = v;
3234 res->steps[step].transform = SETCC_TR_SBB;
3235 res->num_steps = ++step;
3237 } else if (pnc == (pn_Cmp_Ge | ia32_pn_Cmp_unsigned)) {
3238 res->steps[step].transform = SETCC_TR_AND;
3239 res->steps[step].val = v;
3242 res->steps[step].transform = SETCC_TR_NOT;
3245 res->steps[step].transform = SETCC_TR_SBB;
3246 res->num_steps = ++step;
3248 } else if (can_permutate && pnc == (pn_Cmp_Gt | ia32_pn_Cmp_unsigned)) {
3249 res->permutate_cmp_ins ^= 1;
3251 res->steps[step].transform = SETCC_TR_NOT;
3254 res->steps[step].transform = SETCC_TR_AND;
3255 res->steps[step].val = v;
3258 res->steps[step].transform = SETCC_TR_SBB;
3259 res->num_steps = ++step;
3261 } else if (can_permutate && pnc == (pn_Cmp_Le | ia32_pn_Cmp_unsigned)) {
3262 res->permutate_cmp_ins ^= 1;
3264 res->steps[step].transform = SETCC_TR_AND;
3265 res->steps[step].val = v;
3268 res->steps[step].transform = SETCC_TR_SBB;
3269 res->num_steps = ++step;
3274 res->steps[step].val = 0;
3277 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3279 res->steps[step].transform = SETCC_TR_LEAxx;
3280 res->steps[step].scale = 3; /* (a << 3) + a */
3283 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3285 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3286 res->steps[step].scale = 3; /* (a << 3) */
3289 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3291 res->steps[step].transform = SETCC_TR_LEAxx;
3292 res->steps[step].scale = 2; /* (a << 2) + a */
3295 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3297 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3298 res->steps[step].scale = 2; /* (a << 2) */
3301 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3303 res->steps[step].transform = SETCC_TR_LEAxx;
3304 res->steps[step].scale = 1; /* (a << 1) + a */
3307 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3309 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3310 res->steps[step].scale = 1; /* (a << 1) */
3313 res->num_steps = step;
3316 if (! tarval_is_single_bit(t)) {
3317 res->steps[step].transform = SETCC_TR_AND;
3318 res->steps[step].val = v;
3320 res->steps[step].transform = SETCC_TR_NEG;
3322 int v = get_tarval_lowest_bit(t);
3325 res->steps[step].transform = SETCC_TR_SHL;
3326 res->steps[step].scale = v;
3330 res->steps[step].transform = SETCC_TR_SET;
3331 res->num_steps = ++step;
3334 panic("tarval is not long");
3338 * Transforms a Mux node into some code sequence.
3340 * @return The transformed node.
3342 static ir_node *gen_Mux(ir_node *node)
3344 dbg_info *dbgi = get_irn_dbg_info(node);
3345 ir_node *block = get_nodes_block(node);
3346 ir_node *new_block = be_transform_node(block);
3347 ir_node *mux_true = get_Mux_true(node);
3348 ir_node *mux_false = get_Mux_false(node);
3349 ir_node *cond = get_Mux_sel(node);
3350 ir_mode *mode = get_irn_mode(node);
3355 assert(get_irn_mode(cond) == mode_b);
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 = get_Proj_pred(cond);
3360 ir_node *cmp_left = get_Cmp_left(cmp);
3361 ir_node *cmp_right = get_Cmp_right(cmp);
3362 pn_Cmp pnc = get_Proj_proj(cond);
3364 if (ia32_cg_config.use_sse2) {
3365 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3366 if (cmp_left == mux_true && cmp_right == mux_false) {
3367 /* Mux(a <= b, a, b) => MIN */
3368 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3369 match_commutative | match_am | match_two_users);
3370 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3371 /* Mux(a <= b, b, a) => MAX */
3372 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3373 match_commutative | match_am | match_two_users);
3375 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3376 if (cmp_left == mux_true && cmp_right == mux_false) {
3377 /* Mux(a >= b, a, b) => MAX */
3378 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3379 match_commutative | match_am | match_two_users);
3380 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3381 /* Mux(a >= b, b, a) => MIN */
3382 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3383 match_commutative | match_am | match_two_users);
3388 if (is_Const(mux_true) && is_Const(mux_false)) {
3389 ia32_address_mode_t am;
3394 flags = get_flags_node(cond, &pnc);
3395 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node);
3397 if (ia32_cg_config.use_sse2) {
3398 /* cannot load from different mode on SSE */
3401 /* x87 can load any mode */
3405 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3407 switch (get_mode_size_bytes(new_mode)) {
3417 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3418 set_ia32_am_scale(new_node, 2);
3423 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3424 set_ia32_am_scale(new_node, 1);
3427 /* arg, shift 16 NOT supported */
3429 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node);
3432 panic("Unsupported constant size");
3435 am.ls_mode = new_mode;
3436 am.addr.base = get_symconst_base();
3437 am.addr.index = new_node;
3438 am.addr.mem = nomem;
3440 am.addr.scale = scale;
3441 am.addr.use_frame = 0;
3442 am.addr.frame_entity = NULL;
3443 am.addr.symconst_sign = 0;
3444 am.mem_proj = am.addr.mem;
3445 am.op_type = ia32_AddrModeS;
3448 am.pinned = op_pin_state_floats;
3450 am.ins_permuted = 0;
3452 if (ia32_cg_config.use_sse2)
3453 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3455 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3456 set_am_attributes(load, &am);
3458 return new_rd_Proj(NULL, block, load, mode_vfp, pn_ia32_res);
3460 panic("cannot transform floating point Mux");
3463 assert(ia32_mode_needs_gp_reg(mode));
3465 if (is_Proj(cond)) {
3466 ir_node *cmp = get_Proj_pred(cond);
3468 ir_node *cmp_left = get_Cmp_left(cmp);
3469 ir_node *cmp_right = get_Cmp_right(cmp);
3470 pn_Cmp pnc = get_Proj_proj(cond);
3472 /* check for unsigned Doz first */
3473 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3474 is_Const_0(mux_false) && is_Sub(mux_true) &&
3475 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3476 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3477 return create_doz(node, cmp_left, cmp_right);
3478 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3479 is_Const_0(mux_true) && is_Sub(mux_false) &&
3480 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3481 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3482 return create_doz(node, cmp_left, cmp_right);
3487 flags = get_flags_node(cond, &pnc);
3489 if (is_Const(mux_true) && is_Const(mux_false)) {
3490 /* both are const, good */
3491 tarval *tv_true = get_Const_tarval(mux_true);
3492 tarval *tv_false = get_Const_tarval(mux_false);
3493 setcc_transform_t res;
3496 /* check if flags is a cmp node and we are the only user,
3497 i.e no other user yet */
3498 int permutate_allowed = 0;
3499 if (is_ia32_Cmp(flags) && get_irn_n_edges(flags) == 0) {
3500 /* yes, we can permutate its inputs */
3501 permutate_allowed = 1;
3503 find_const_transform(pnc, tv_true, tv_false, &res, 0);
3505 if (res.permutate_cmp_ins) {
3506 ia32_attr_t *attr = get_ia32_attr(flags);
3507 attr->data.ins_permuted ^= 1;
3509 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3512 switch (res.steps[step].transform) {
3514 imm = ia32_immediate_from_long(res.steps[step].val);
3515 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3517 case SETCC_TR_ADDxx:
3518 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3521 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3522 set_ia32_am_scale(new_node, res.steps[step].scale);
3523 set_ia32_am_offs_int(new_node, res.steps[step].val);
3525 case SETCC_TR_LEAxx:
3526 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3527 set_ia32_am_scale(new_node, res.steps[step].scale);
3528 set_ia32_am_offs_int(new_node, res.steps[step].val);
3531 imm = ia32_immediate_from_long(res.steps[step].scale);
3532 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3535 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3538 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3541 imm = ia32_immediate_from_long(res.steps[step].val);
3542 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3545 new_node = create_set_32bit(dbgi, new_block, flags, res.pnc, new_node);
3548 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3551 panic("unknown setcc transform");
3555 new_node = create_CMov(node, cond, flags, pnc);
3563 * Create a conversion from x87 state register to general purpose.
3565 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3567 ir_node *block = be_transform_node(get_nodes_block(node));
3568 ir_node *op = get_Conv_op(node);
3569 ir_node *new_op = be_transform_node(op);
3570 ir_graph *irg = current_ir_graph;
3571 dbg_info *dbgi = get_irn_dbg_info(node);
3572 ir_mode *mode = get_irn_mode(node);
3573 ir_node *fist, *load, *mem;
3575 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3576 set_irn_pinned(fist, op_pin_state_floats);
3577 set_ia32_use_frame(fist);
3578 set_ia32_op_type(fist, ia32_AddrModeD);
3580 assert(get_mode_size_bits(mode) <= 32);
3581 /* exception we can only store signed 32 bit integers, so for unsigned
3582 we store a 64bit (signed) integer and load the lower bits */
3583 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3584 set_ia32_ls_mode(fist, mode_Ls);
3586 set_ia32_ls_mode(fist, mode_Is);
3588 SET_IA32_ORIG_NODE(fist, node);
3591 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3593 set_irn_pinned(load, op_pin_state_floats);
3594 set_ia32_use_frame(load);
3595 set_ia32_op_type(load, ia32_AddrModeS);
3596 set_ia32_ls_mode(load, mode_Is);
3597 if (get_ia32_ls_mode(fist) == mode_Ls) {
3598 ia32_attr_t *attr = get_ia32_attr(load);
3599 attr->data.need_64bit_stackent = 1;
3601 ia32_attr_t *attr = get_ia32_attr(load);
3602 attr->data.need_32bit_stackent = 1;
3604 SET_IA32_ORIG_NODE(load, node);
3606 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
3610 * Creates a x87 strict Conv by placing a Store and a Load
3612 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3614 ir_node *block = get_nodes_block(node);
3615 ir_graph *irg = get_Block_irg(block);
3616 dbg_info *dbgi = get_irn_dbg_info(node);
3617 ir_node *frame = get_irg_frame(irg);
3618 ir_node *store, *load;
3621 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3622 set_ia32_use_frame(store);
3623 set_ia32_op_type(store, ia32_AddrModeD);
3624 SET_IA32_ORIG_NODE(store, node);
3626 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3627 set_ia32_use_frame(load);
3628 set_ia32_op_type(load, ia32_AddrModeS);
3629 SET_IA32_ORIG_NODE(load, node);
3631 new_node = new_r_Proj(block, load, mode_E, pn_ia32_vfld_res);
3635 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3636 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3638 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3640 func = get_mode_size_bits(mode) == 8 ?
3641 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3642 return func(dbgi, block, base, index, mem, val, mode);
3646 * Create a conversion from general purpose to x87 register
3648 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3650 ir_node *src_block = get_nodes_block(node);
3651 ir_node *block = be_transform_node(src_block);
3652 ir_graph *irg = get_Block_irg(block);
3653 dbg_info *dbgi = get_irn_dbg_info(node);
3654 ir_node *op = get_Conv_op(node);
3655 ir_node *new_op = NULL;
3657 ir_mode *store_mode;
3662 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3663 if (possible_int_mode_for_fp(src_mode)) {
3664 ia32_address_mode_t am;
3666 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3667 if (am.op_type == ia32_AddrModeS) {
3668 ia32_address_t *addr = &am.addr;
3670 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3671 new_node = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
3673 set_am_attributes(fild, &am);
3674 SET_IA32_ORIG_NODE(fild, node);
3676 fix_mem_proj(fild, &am);
3681 if (new_op == NULL) {
3682 new_op = be_transform_node(op);
3685 mode = get_irn_mode(op);
3687 /* first convert to 32 bit signed if necessary */
3688 if (get_mode_size_bits(src_mode) < 32) {
3689 if (!upper_bits_clean(new_op, src_mode)) {
3690 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3691 SET_IA32_ORIG_NODE(new_op, node);
3696 assert(get_mode_size_bits(mode) == 32);
3699 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3701 set_ia32_use_frame(store);
3702 set_ia32_op_type(store, ia32_AddrModeD);
3703 set_ia32_ls_mode(store, mode_Iu);
3705 /* exception for 32bit unsigned, do a 64bit spill+load */
3706 if (!mode_is_signed(mode)) {
3709 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3711 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3712 noreg_GP, nomem, zero_const);
3714 set_ia32_use_frame(zero_store);
3715 set_ia32_op_type(zero_store, ia32_AddrModeD);
3716 add_ia32_am_offs_int(zero_store, 4);
3717 set_ia32_ls_mode(zero_store, mode_Iu);
3722 store = new_rd_Sync(dbgi, block, 2, in);
3723 store_mode = mode_Ls;
3725 store_mode = mode_Is;
3729 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3731 set_ia32_use_frame(fild);
3732 set_ia32_op_type(fild, ia32_AddrModeS);
3733 set_ia32_ls_mode(fild, store_mode);
3735 new_node = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
3741 * Create a conversion from one integer mode into another one
3743 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3744 dbg_info *dbgi, ir_node *block, ir_node *op,
3747 ir_node *new_block = be_transform_node(block);
3749 ir_mode *smaller_mode;
3750 ia32_address_mode_t am;
3751 ia32_address_t *addr = &am.addr;
3754 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3755 smaller_mode = src_mode;
3757 smaller_mode = tgt_mode;
3760 #ifdef DEBUG_libfirm
3762 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3767 match_arguments(&am, block, NULL, op, NULL,
3768 match_am | match_8bit_am | match_16bit_am);
3770 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3771 /* unnecessary conv. in theory it shouldn't have been AM */
3772 assert(is_ia32_NoReg_GP(addr->base));
3773 assert(is_ia32_NoReg_GP(addr->index));
3774 assert(is_NoMem(addr->mem));
3775 assert(am.addr.offset == 0);
3776 assert(am.addr.symconst_ent == NULL);
3780 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3781 addr->mem, am.new_op2, smaller_mode);
3782 set_am_attributes(new_node, &am);
3783 /* match_arguments assume that out-mode = in-mode, this isn't true here
3785 set_ia32_ls_mode(new_node, smaller_mode);
3786 SET_IA32_ORIG_NODE(new_node, node);
3787 new_node = fix_mem_proj(new_node, &am);
3792 * Transforms a Conv node.
3794 * @return The created ia32 Conv node
3796 static ir_node *gen_Conv(ir_node *node)
3798 ir_node *block = get_nodes_block(node);
3799 ir_node *new_block = be_transform_node(block);
3800 ir_node *op = get_Conv_op(node);
3801 ir_node *new_op = NULL;
3802 dbg_info *dbgi = get_irn_dbg_info(node);
3803 ir_mode *src_mode = get_irn_mode(op);
3804 ir_mode *tgt_mode = get_irn_mode(node);
3805 int src_bits = get_mode_size_bits(src_mode);
3806 int tgt_bits = get_mode_size_bits(tgt_mode);
3807 ir_node *res = NULL;
3809 assert(!mode_is_int(src_mode) || src_bits <= 32);
3810 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3812 /* modeB -> X should already be lowered by the lower_mode_b pass */
3813 if (src_mode == mode_b) {
3814 panic("ConvB not lowered %+F", node);
3817 if (src_mode == tgt_mode) {
3818 if (get_Conv_strict(node)) {
3819 if (ia32_cg_config.use_sse2) {
3820 /* when we are in SSE mode, we can kill all strict no-op conversion */
3821 return be_transform_node(op);
3824 /* this should be optimized already, but who knows... */
3825 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3826 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3827 return be_transform_node(op);
3831 if (mode_is_float(src_mode)) {
3832 new_op = be_transform_node(op);
3833 /* we convert from float ... */
3834 if (mode_is_float(tgt_mode)) {
3836 if (ia32_cg_config.use_sse2) {
3837 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3838 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3840 set_ia32_ls_mode(res, tgt_mode);
3842 if (get_Conv_strict(node)) {
3843 /* if fp_no_float_fold is not set then we assume that we
3844 * don't have any float operations in a non
3845 * mode_float_arithmetic mode and can skip strict upconvs */
3846 if (src_bits < tgt_bits
3847 && !(get_irg_fp_model(current_ir_graph) & fp_no_float_fold)) {
3848 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3851 res = gen_x87_strict_conv(tgt_mode, new_op);
3852 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3856 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3861 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3862 if (ia32_cg_config.use_sse2) {
3863 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3865 set_ia32_ls_mode(res, src_mode);
3867 return gen_x87_fp_to_gp(node);
3871 /* we convert from int ... */
3872 if (mode_is_float(tgt_mode)) {
3874 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3875 if (ia32_cg_config.use_sse2) {
3876 new_op = be_transform_node(op);
3877 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3879 set_ia32_ls_mode(res, tgt_mode);
3881 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3882 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3883 res = gen_x87_gp_to_fp(node, src_mode);
3885 /* we need a strict-Conv, if the int mode has more bits than the
3887 if (float_mantissa < int_mantissa) {
3888 res = gen_x87_strict_conv(tgt_mode, res);
3889 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3893 } else if (tgt_mode == mode_b) {
3894 /* mode_b lowering already took care that we only have 0/1 values */
3895 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3896 src_mode, tgt_mode));
3897 return be_transform_node(op);
3900 if (src_bits == tgt_bits) {
3901 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3902 src_mode, tgt_mode));
3903 return be_transform_node(op);
3906 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3914 static ir_node *create_immediate_or_transform(ir_node *node,
3915 char immediate_constraint_type)
3917 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3918 if (new_node == NULL) {
3919 new_node = be_transform_node(node);
3925 * Transforms a FrameAddr into an ia32 Add.
3927 static ir_node *gen_be_FrameAddr(ir_node *node)
3929 ir_node *block = be_transform_node(get_nodes_block(node));
3930 ir_node *op = be_get_FrameAddr_frame(node);
3931 ir_node *new_op = be_transform_node(op);
3932 dbg_info *dbgi = get_irn_dbg_info(node);
3935 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3936 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3937 set_ia32_use_frame(new_node);
3939 SET_IA32_ORIG_NODE(new_node, node);
3945 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3947 static ir_node *gen_be_Return(ir_node *node)
3949 ir_graph *irg = current_ir_graph;
3950 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3951 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3952 ir_entity *ent = get_irg_entity(irg);
3953 ir_type *tp = get_entity_type(ent);
3958 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3959 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3961 int pn_ret_val, pn_ret_mem, arity, i;
3963 assert(ret_val != NULL);
3964 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3965 return be_duplicate_node(node);
3968 res_type = get_method_res_type(tp, 0);
3970 if (! is_Primitive_type(res_type)) {
3971 return be_duplicate_node(node);
3974 mode = get_type_mode(res_type);
3975 if (! mode_is_float(mode)) {
3976 return be_duplicate_node(node);
3979 assert(get_method_n_ress(tp) == 1);
3981 pn_ret_val = get_Proj_proj(ret_val);
3982 pn_ret_mem = get_Proj_proj(ret_mem);
3984 /* get the Barrier */
3985 barrier = get_Proj_pred(ret_val);
3987 /* get result input of the Barrier */
3988 ret_val = get_irn_n(barrier, pn_ret_val);
3989 new_ret_val = be_transform_node(ret_val);
3991 /* get memory input of the Barrier */
3992 ret_mem = get_irn_n(barrier, pn_ret_mem);
3993 new_ret_mem = be_transform_node(ret_mem);
3995 frame = get_irg_frame(irg);
3997 dbgi = get_irn_dbg_info(barrier);
3998 block = be_transform_node(get_nodes_block(barrier));
4000 /* store xmm0 onto stack */
4001 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
4002 new_ret_mem, new_ret_val);
4003 set_ia32_ls_mode(sse_store, mode);
4004 set_ia32_op_type(sse_store, ia32_AddrModeD);
4005 set_ia32_use_frame(sse_store);
4007 /* load into x87 register */
4008 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4009 set_ia32_op_type(fld, ia32_AddrModeS);
4010 set_ia32_use_frame(fld);
4012 mproj = new_r_Proj(block, fld, mode_M, pn_ia32_vfld_M);
4013 fld = new_r_Proj(block, fld, mode_vfp, pn_ia32_vfld_res);
4015 /* create a new barrier */
4016 arity = get_irn_arity(barrier);
4017 in = ALLOCAN(ir_node*, arity);
4018 for (i = 0; i < arity; ++i) {
4021 if (i == pn_ret_val) {
4023 } else if (i == pn_ret_mem) {
4026 ir_node *in = get_irn_n(barrier, i);
4027 new_in = be_transform_node(in);
4032 new_barrier = new_ir_node(dbgi, irg, block,
4033 get_irn_op(barrier), get_irn_mode(barrier),
4035 copy_node_attr(barrier, new_barrier);
4036 be_duplicate_deps(barrier, new_barrier);
4037 be_set_transformed_node(barrier, new_barrier);
4039 /* transform normally */
4040 return be_duplicate_node(node);
4044 * Transform a be_AddSP into an ia32_SubSP.
4046 static ir_node *gen_be_AddSP(ir_node *node)
4048 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4049 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4051 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4052 match_am | match_immediate);
4056 * Transform a be_SubSP into an ia32_AddSP
4058 static ir_node *gen_be_SubSP(ir_node *node)
4060 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4061 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4063 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4064 match_am | match_immediate);
4068 * Change some phi modes
4070 static ir_node *gen_Phi(ir_node *node)
4072 const arch_register_req_t *req;
4073 ir_node *block = be_transform_node(get_nodes_block(node));
4074 ir_graph *irg = current_ir_graph;
4075 dbg_info *dbgi = get_irn_dbg_info(node);
4076 ir_mode *mode = get_irn_mode(node);
4079 if (ia32_mode_needs_gp_reg(mode)) {
4080 /* we shouldn't have any 64bit stuff around anymore */
4081 assert(get_mode_size_bits(mode) <= 32);
4082 /* all integer operations are on 32bit registers now */
4084 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4085 } else if (mode_is_float(mode)) {
4086 if (ia32_cg_config.use_sse2) {
4088 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4091 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4094 req = arch_no_register_req;
4097 /* phi nodes allow loops, so we use the old arguments for now
4098 * and fix this later */
4099 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4100 get_irn_in(node) + 1);
4101 copy_node_attr(node, phi);
4102 be_duplicate_deps(node, phi);
4104 arch_set_out_register_req(phi, 0, req);
4106 be_enqueue_preds(node);
4111 static ir_node *gen_Jmp(ir_node *node)
4113 ir_node *block = get_nodes_block(node);
4114 ir_node *new_block = be_transform_node(block);
4115 dbg_info *dbgi = get_irn_dbg_info(node);
4118 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4119 SET_IA32_ORIG_NODE(new_node, node);
4127 static ir_node *gen_IJmp(ir_node *node)
4129 ir_node *block = get_nodes_block(node);
4130 ir_node *new_block = be_transform_node(block);
4131 dbg_info *dbgi = get_irn_dbg_info(node);
4132 ir_node *op = get_IJmp_target(node);
4134 ia32_address_mode_t am;
4135 ia32_address_t *addr = &am.addr;
4137 assert(get_irn_mode(op) == mode_P);
4139 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4141 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4142 addr->mem, am.new_op2);
4143 set_am_attributes(new_node, &am);
4144 SET_IA32_ORIG_NODE(new_node, node);
4146 new_node = fix_mem_proj(new_node, &am);
4152 * Transform a Bound node.
4154 static ir_node *gen_Bound(ir_node *node)
4157 ir_node *lower = get_Bound_lower(node);
4158 dbg_info *dbgi = get_irn_dbg_info(node);
4160 if (is_Const_0(lower)) {
4161 /* typical case for Java */
4162 ir_node *sub, *res, *flags, *block;
4164 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
4165 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
4167 block = get_nodes_block(res);
4168 if (! is_Proj(res)) {
4170 set_irn_mode(sub, mode_T);
4171 res = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_res);
4173 sub = get_Proj_pred(res);
4175 flags = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_Sub_flags);
4176 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
4177 SET_IA32_ORIG_NODE(new_node, node);
4179 panic("generic Bound not supported in ia32 Backend");
4185 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4187 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4188 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4190 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4191 match_immediate | match_mode_neutral);
4194 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4196 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4197 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4198 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4202 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4204 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4205 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4206 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4210 static ir_node *gen_ia32_l_Add(ir_node *node)
4212 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4213 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4214 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4215 match_commutative | match_am | match_immediate |
4216 match_mode_neutral);
4218 if (is_Proj(lowered)) {
4219 lowered = get_Proj_pred(lowered);
4221 assert(is_ia32_Add(lowered));
4222 set_irn_mode(lowered, mode_T);
4228 static ir_node *gen_ia32_l_Adc(ir_node *node)
4230 return gen_binop_flags(node, new_bd_ia32_Adc,
4231 match_commutative | match_am | match_immediate |
4232 match_mode_neutral);
4236 * Transforms a l_MulS into a "real" MulS node.
4238 * @return the created ia32 Mul node
4240 static ir_node *gen_ia32_l_Mul(ir_node *node)
4242 ir_node *left = get_binop_left(node);
4243 ir_node *right = get_binop_right(node);
4245 return gen_binop(node, left, right, new_bd_ia32_Mul,
4246 match_commutative | match_am | match_mode_neutral);
4250 * Transforms a l_IMulS into a "real" IMul1OPS node.
4252 * @return the created ia32 IMul1OP node
4254 static ir_node *gen_ia32_l_IMul(ir_node *node)
4256 ir_node *left = get_binop_left(node);
4257 ir_node *right = get_binop_right(node);
4259 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4260 match_commutative | match_am | match_mode_neutral);
4263 static ir_node *gen_ia32_l_Sub(ir_node *node)
4265 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4266 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4267 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4268 match_am | match_immediate | match_mode_neutral);
4270 if (is_Proj(lowered)) {
4271 lowered = get_Proj_pred(lowered);
4273 assert(is_ia32_Sub(lowered));
4274 set_irn_mode(lowered, mode_T);
4280 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4282 return gen_binop_flags(node, new_bd_ia32_Sbb,
4283 match_am | match_immediate | match_mode_neutral);
4287 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4288 * op1 - target to be shifted
4289 * op2 - contains bits to be shifted into target
4291 * Only op3 can be an immediate.
4293 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4294 ir_node *low, ir_node *count)
4296 ir_node *block = get_nodes_block(node);
4297 ir_node *new_block = be_transform_node(block);
4298 dbg_info *dbgi = get_irn_dbg_info(node);
4299 ir_node *new_high = be_transform_node(high);
4300 ir_node *new_low = be_transform_node(low);
4304 /* the shift amount can be any mode that is bigger than 5 bits, since all
4305 * other bits are ignored anyway */
4306 while (is_Conv(count) &&
4307 get_irn_n_edges(count) == 1 &&
4308 mode_is_int(get_irn_mode(count))) {
4309 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4310 count = get_Conv_op(count);
4312 new_count = create_immediate_or_transform(count, 0);
4314 if (is_ia32_l_ShlD(node)) {
4315 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4318 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4321 SET_IA32_ORIG_NODE(new_node, node);
4326 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4328 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4329 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4330 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4331 return gen_lowered_64bit_shifts(node, high, low, count);
4334 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4336 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4337 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4338 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4339 return gen_lowered_64bit_shifts(node, high, low, count);
4342 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4344 ir_node *src_block = get_nodes_block(node);
4345 ir_node *block = be_transform_node(src_block);
4346 ir_graph *irg = current_ir_graph;
4347 dbg_info *dbgi = get_irn_dbg_info(node);
4348 ir_node *frame = get_irg_frame(irg);
4349 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4350 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4351 ir_node *new_val_low = be_transform_node(val_low);
4352 ir_node *new_val_high = be_transform_node(val_high);
4354 ir_node *sync, *fild, *res;
4355 ir_node *store_low, *store_high;
4357 if (ia32_cg_config.use_sse2) {
4358 panic("ia32_l_LLtoFloat not implemented for SSE2");
4362 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4364 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4366 SET_IA32_ORIG_NODE(store_low, node);
4367 SET_IA32_ORIG_NODE(store_high, node);
4369 set_ia32_use_frame(store_low);
4370 set_ia32_use_frame(store_high);
4371 set_ia32_op_type(store_low, ia32_AddrModeD);
4372 set_ia32_op_type(store_high, ia32_AddrModeD);
4373 set_ia32_ls_mode(store_low, mode_Iu);
4374 set_ia32_ls_mode(store_high, mode_Is);
4375 add_ia32_am_offs_int(store_high, 4);
4379 sync = new_rd_Sync(dbgi, block, 2, in);
4382 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4384 set_ia32_use_frame(fild);
4385 set_ia32_op_type(fild, ia32_AddrModeS);
4386 set_ia32_ls_mode(fild, mode_Ls);
4388 SET_IA32_ORIG_NODE(fild, node);
4390 res = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
4392 if (! mode_is_signed(get_irn_mode(val_high))) {
4393 ia32_address_mode_t am;
4395 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4398 am.addr.base = get_symconst_base();
4399 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4400 am.addr.mem = nomem;
4403 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4404 am.addr.use_frame = 0;
4405 am.addr.frame_entity = NULL;
4406 am.addr.symconst_sign = 0;
4407 am.ls_mode = mode_F;
4408 am.mem_proj = nomem;
4409 am.op_type = ia32_AddrModeS;
4411 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
4412 am.pinned = op_pin_state_floats;
4414 am.ins_permuted = 0;
4416 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4417 am.new_op1, am.new_op2, get_fpcw());
4418 set_am_attributes(fadd, &am);
4420 set_irn_mode(fadd, mode_T);
4421 res = new_rd_Proj(NULL, block, fadd, mode_vfp, pn_ia32_res);
4426 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4428 ir_node *src_block = get_nodes_block(node);
4429 ir_node *block = be_transform_node(src_block);
4430 ir_graph *irg = get_Block_irg(block);
4431 dbg_info *dbgi = get_irn_dbg_info(node);
4432 ir_node *frame = get_irg_frame(irg);
4433 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4434 ir_node *new_val = be_transform_node(val);
4435 ir_node *fist, *mem;
4437 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4438 SET_IA32_ORIG_NODE(fist, node);
4439 set_ia32_use_frame(fist);
4440 set_ia32_op_type(fist, ia32_AddrModeD);
4441 set_ia32_ls_mode(fist, mode_Ls);
4447 * the BAD transformer.
4449 static ir_node *bad_transform(ir_node *node)
4451 panic("No transform function for %+F available.", node);
4455 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4457 ir_node *block = be_transform_node(get_nodes_block(node));
4458 ir_graph *irg = get_Block_irg(block);
4459 ir_node *pred = get_Proj_pred(node);
4460 ir_node *new_pred = be_transform_node(pred);
4461 ir_node *frame = get_irg_frame(irg);
4462 dbg_info *dbgi = get_irn_dbg_info(node);
4463 long pn = get_Proj_proj(node);
4468 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4469 SET_IA32_ORIG_NODE(load, node);
4470 set_ia32_use_frame(load);
4471 set_ia32_op_type(load, ia32_AddrModeS);
4472 set_ia32_ls_mode(load, mode_Iu);
4473 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4474 * 32 bit from it with this particular load */
4475 attr = get_ia32_attr(load);
4476 attr->data.need_64bit_stackent = 1;
4478 if (pn == pn_ia32_l_FloattoLL_res_high) {
4479 add_ia32_am_offs_int(load, 4);
4481 assert(pn == pn_ia32_l_FloattoLL_res_low);
4484 proj = new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4490 * Transform the Projs of an AddSP.
4492 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4494 ir_node *block = be_transform_node(get_nodes_block(node));
4495 ir_node *pred = get_Proj_pred(node);
4496 ir_node *new_pred = be_transform_node(pred);
4497 dbg_info *dbgi = get_irn_dbg_info(node);
4498 long proj = get_Proj_proj(node);
4500 if (proj == pn_be_AddSP_sp) {
4501 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4502 pn_ia32_SubSP_stack);
4503 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4505 } else if (proj == pn_be_AddSP_res) {
4506 return new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4507 pn_ia32_SubSP_addr);
4508 } else if (proj == pn_be_AddSP_M) {
4509 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_SubSP_M);
4512 panic("No idea how to transform proj->AddSP");
4516 * Transform the Projs of a SubSP.
4518 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4520 ir_node *block = be_transform_node(get_nodes_block(node));
4521 ir_node *pred = get_Proj_pred(node);
4522 ir_node *new_pred = be_transform_node(pred);
4523 dbg_info *dbgi = get_irn_dbg_info(node);
4524 long proj = get_Proj_proj(node);
4526 if (proj == pn_be_SubSP_sp) {
4527 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4528 pn_ia32_AddSP_stack);
4529 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4531 } else if (proj == pn_be_SubSP_M) {
4532 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_AddSP_M);
4535 panic("No idea how to transform proj->SubSP");
4539 * Transform and renumber the Projs from a Load.
4541 static ir_node *gen_Proj_Load(ir_node *node)
4544 ir_node *block = be_transform_node(get_nodes_block(node));
4545 ir_node *pred = get_Proj_pred(node);
4546 dbg_info *dbgi = get_irn_dbg_info(node);
4547 long proj = get_Proj_proj(node);
4549 /* loads might be part of source address mode matches, so we don't
4550 * transform the ProjMs yet (with the exception of loads whose result is
4553 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4555 ir_node *old_block = get_nodes_block(node);
4557 /* this is needed, because sometimes we have loops that are only
4558 reachable through the ProjM */
4559 be_enqueue_preds(node);
4560 /* do it in 2 steps, to silence firm verifier */
4561 res = new_rd_Proj(dbgi, old_block, pred, mode_M, pn_Load_M);
4562 set_Proj_proj(res, pn_ia32_mem);
4566 /* renumber the proj */
4567 new_pred = be_transform_node(pred);
4568 if (is_ia32_Load(new_pred)) {
4571 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Load_res);
4573 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Load_M);
4574 case pn_Load_X_regular:
4575 return new_rd_Jmp(dbgi, block);
4576 case pn_Load_X_except:
4577 /* This Load might raise an exception. Mark it. */
4578 set_ia32_exc_label(new_pred, 1);
4579 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4583 } else if (is_ia32_Conv_I2I(new_pred) ||
4584 is_ia32_Conv_I2I8Bit(new_pred)) {
4585 set_irn_mode(new_pred, mode_T);
4586 if (proj == pn_Load_res) {
4587 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_res);
4588 } else if (proj == pn_Load_M) {
4589 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_mem);
4591 } else if (is_ia32_xLoad(new_pred)) {
4594 return new_rd_Proj(dbgi, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4596 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_xLoad_M);
4597 case pn_Load_X_regular:
4598 return new_rd_Jmp(dbgi, block);
4599 case pn_Load_X_except:
4600 /* This Load might raise an exception. Mark it. */
4601 set_ia32_exc_label(new_pred, 1);
4602 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4606 } else if (is_ia32_vfld(new_pred)) {
4609 return new_rd_Proj(dbgi, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4611 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_vfld_M);
4612 case pn_Load_X_regular:
4613 return new_rd_Jmp(dbgi, block);
4614 case pn_Load_X_except:
4615 /* This Load might raise an exception. Mark it. */
4616 set_ia32_exc_label(new_pred, 1);
4617 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_vfld_X_exc);
4622 /* can happen for ProJMs when source address mode happened for the
4625 /* however it should not be the result proj, as that would mean the
4626 load had multiple users and should not have been used for
4628 if (proj != pn_Load_M) {
4629 panic("internal error: transformed node not a Load");
4631 return new_rd_Proj(dbgi, block, new_pred, mode_M, 1);
4634 panic("No idea how to transform proj");
4638 * Transform and renumber the Projs from a DivMod like instruction.
4640 static ir_node *gen_Proj_DivMod(ir_node *node)
4642 ir_node *block = be_transform_node(get_nodes_block(node));
4643 ir_node *pred = get_Proj_pred(node);
4644 ir_node *new_pred = be_transform_node(pred);
4645 dbg_info *dbgi = get_irn_dbg_info(node);
4646 long proj = get_Proj_proj(node);
4648 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4650 switch (get_irn_opcode(pred)) {
4654 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4656 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4657 case pn_Div_X_regular:
4658 return new_rd_Jmp(dbgi, block);
4659 case pn_Div_X_except:
4660 set_ia32_exc_label(new_pred, 1);
4661 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4669 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4671 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4672 case pn_Mod_X_except:
4673 set_ia32_exc_label(new_pred, 1);
4674 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4682 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4683 case pn_DivMod_res_div:
4684 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4685 case pn_DivMod_res_mod:
4686 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4687 case pn_DivMod_X_regular:
4688 return new_rd_Jmp(dbgi, block);
4689 case pn_DivMod_X_except:
4690 set_ia32_exc_label(new_pred, 1);
4691 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4700 panic("No idea how to transform proj->DivMod");
4704 * Transform and renumber the Projs from a CopyB.
4706 static ir_node *gen_Proj_CopyB(ir_node *node)
4708 ir_node *block = be_transform_node(get_nodes_block(node));
4709 ir_node *pred = get_Proj_pred(node);
4710 ir_node *new_pred = be_transform_node(pred);
4711 dbg_info *dbgi = get_irn_dbg_info(node);
4712 long proj = get_Proj_proj(node);
4715 case pn_CopyB_M_regular:
4716 if (is_ia32_CopyB_i(new_pred)) {
4717 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4718 } else if (is_ia32_CopyB(new_pred)) {
4719 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_CopyB_M);
4726 panic("No idea how to transform proj->CopyB");
4730 * Transform and renumber the Projs from a Quot.
4732 static ir_node *gen_Proj_Quot(ir_node *node)
4734 ir_node *block = be_transform_node(get_nodes_block(node));
4735 ir_node *pred = get_Proj_pred(node);
4736 ir_node *new_pred = be_transform_node(pred);
4737 dbg_info *dbgi = get_irn_dbg_info(node);
4738 long proj = get_Proj_proj(node);
4742 if (is_ia32_xDiv(new_pred)) {
4743 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_xDiv_M);
4744 } else if (is_ia32_vfdiv(new_pred)) {
4745 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4749 if (is_ia32_xDiv(new_pred)) {
4750 return new_rd_Proj(dbgi, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4751 } else if (is_ia32_vfdiv(new_pred)) {
4752 return new_rd_Proj(dbgi, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4755 case pn_Quot_X_regular:
4756 case pn_Quot_X_except:
4761 panic("No idea how to transform proj->Quot");
4764 static ir_node *gen_be_Call(ir_node *node)
4766 dbg_info *const dbgi = get_irn_dbg_info(node);
4767 ir_node *const src_block = get_nodes_block(node);
4768 ir_node *const block = be_transform_node(src_block);
4769 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4770 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4771 ir_node *const sp = be_transform_node(src_sp);
4772 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4773 ia32_address_mode_t am;
4774 ia32_address_t *const addr = &am.addr;
4779 ir_node * eax = noreg_GP;
4780 ir_node * ecx = noreg_GP;
4781 ir_node * edx = noreg_GP;
4782 unsigned const pop = be_Call_get_pop(node);
4783 ir_type *const call_tp = be_Call_get_type(node);
4784 int old_no_pic_adjust;
4786 /* Run the x87 simulator if the call returns a float value */
4787 if (get_method_n_ress(call_tp) > 0) {
4788 ir_type *const res_type = get_method_res_type(call_tp, 0);
4789 ir_mode *const res_mode = get_type_mode(res_type);
4791 if (res_mode != NULL && mode_is_float(res_mode)) {
4792 env_cg->do_x87_sim = 1;
4796 /* We do not want be_Call direct calls */
4797 assert(be_Call_get_entity(node) == NULL);
4799 /* special case for PIC trampoline calls */
4800 old_no_pic_adjust = no_pic_adjust;
4801 no_pic_adjust = env_cg->birg->main_env->options->pic;
4803 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4804 match_am | match_immediate);
4806 no_pic_adjust = old_no_pic_adjust;
4808 i = get_irn_arity(node) - 1;
4809 fpcw = be_transform_node(get_irn_n(node, i--));
4810 for (; i >= be_pos_Call_first_arg; --i) {
4811 arch_register_req_t const *const req = arch_get_register_req(node, i);
4812 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4814 assert(req->type == arch_register_req_type_limited);
4815 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4817 switch (*req->limited) {
4818 case 1 << REG_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4819 case 1 << REG_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4820 case 1 << REG_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4821 default: panic("Invalid GP register for register parameter");
4825 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4826 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4827 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4828 set_am_attributes(call, &am);
4829 call = fix_mem_proj(call, &am);
4831 if (get_irn_pinned(node) == op_pin_state_pinned)
4832 set_irn_pinned(call, op_pin_state_pinned);
4834 SET_IA32_ORIG_NODE(call, node);
4836 if (ia32_cg_config.use_sse2) {
4837 /* remember this call for post-processing */
4838 ARR_APP1(ir_node *, call_list, call);
4839 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4846 * Transform Builtin trap
4848 static ir_node *gen_trap(ir_node *node) {
4849 dbg_info *dbgi = get_irn_dbg_info(node);
4850 ir_node *block = be_transform_node(get_nodes_block(node));
4851 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4853 return new_bd_ia32_UD2(dbgi, block, mem);
4857 * Transform Builtin debugbreak
4859 static ir_node *gen_debugbreak(ir_node *node) {
4860 dbg_info *dbgi = get_irn_dbg_info(node);
4861 ir_node *block = be_transform_node(get_nodes_block(node));
4862 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4864 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4868 * Transform Builtin return_address
4870 static ir_node *gen_return_address(ir_node *node) {
4871 ir_node *param = get_Builtin_param(node, 0);
4872 ir_node *frame = get_Builtin_param(node, 1);
4873 dbg_info *dbgi = get_irn_dbg_info(node);
4874 tarval *tv = get_Const_tarval(param);
4875 unsigned long value = get_tarval_long(tv);
4877 ir_node *block = be_transform_node(get_nodes_block(node));
4878 ir_node *ptr = be_transform_node(frame);
4882 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4883 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4884 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4887 /* load the return address from this frame */
4888 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4890 set_irn_pinned(load, get_irn_pinned(node));
4891 set_ia32_op_type(load, ia32_AddrModeS);
4892 set_ia32_ls_mode(load, mode_Iu);
4894 set_ia32_am_offs_int(load, 0);
4895 set_ia32_use_frame(load);
4896 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4898 if (get_irn_pinned(node) == op_pin_state_floats) {
4899 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4900 && pn_ia32_vfld_res == pn_ia32_Load_res
4901 && pn_ia32_Load_res == pn_ia32_res);
4902 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4905 SET_IA32_ORIG_NODE(load, node);
4906 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4910 * Transform Builtin frame_address
4912 static ir_node *gen_frame_address(ir_node *node) {
4913 ir_node *param = get_Builtin_param(node, 0);
4914 ir_node *frame = get_Builtin_param(node, 1);
4915 dbg_info *dbgi = get_irn_dbg_info(node);
4916 tarval *tv = get_Const_tarval(param);
4917 unsigned long value = get_tarval_long(tv);
4919 ir_node *block = be_transform_node(get_nodes_block(node));
4920 ir_node *ptr = be_transform_node(frame);
4925 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4926 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4927 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4930 /* load the frame address from this frame */
4931 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4933 set_irn_pinned(load, get_irn_pinned(node));
4934 set_ia32_op_type(load, ia32_AddrModeS);
4935 set_ia32_ls_mode(load, mode_Iu);
4937 ent = ia32_get_frame_address_entity();
4939 set_ia32_am_offs_int(load, 0);
4940 set_ia32_use_frame(load);
4941 set_ia32_frame_ent(load, ent);
4943 /* will fail anyway, but gcc does this: */
4944 set_ia32_am_offs_int(load, 0);
4947 if (get_irn_pinned(node) == op_pin_state_floats) {
4948 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4949 && pn_ia32_vfld_res == pn_ia32_Load_res
4950 && pn_ia32_Load_res == pn_ia32_res);
4951 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4954 SET_IA32_ORIG_NODE(load, node);
4955 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4959 * Transform Builtin frame_address
4961 static ir_node *gen_prefetch(ir_node *node) {
4963 ir_node *ptr, *block, *mem, *base, *index;
4964 ir_node *param, *new_node;
4967 ia32_address_t addr;
4969 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4970 /* no prefetch at all, route memory */
4971 return be_transform_node(get_Builtin_mem(node));
4974 param = get_Builtin_param(node, 1);
4975 tv = get_Const_tarval(param);
4976 rw = get_tarval_long(tv);
4978 /* construct load address */
4979 memset(&addr, 0, sizeof(addr));
4980 ptr = get_Builtin_param(node, 0);
4981 ia32_create_address_mode(&addr, ptr, 0);
4988 base = be_transform_node(base);
4991 if (index == NULL) {
4994 index = be_transform_node(index);
4997 dbgi = get_irn_dbg_info(node);
4998 block = be_transform_node(get_nodes_block(node));
4999 mem = be_transform_node(get_Builtin_mem(node));
5001 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
5002 /* we have 3DNow!, this was already checked above */
5003 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
5004 } else if (ia32_cg_config.use_sse_prefetch) {
5005 /* note: rw == 1 is IGNORED in that case */
5006 param = get_Builtin_param(node, 2);
5007 tv = get_Const_tarval(param);
5008 locality = get_tarval_long(tv);
5010 /* SSE style prefetch */
5013 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
5016 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
5019 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
5022 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
5026 assert(ia32_cg_config.use_3dnow_prefetch);
5027 /* 3DNow! style prefetch */
5028 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
5031 set_irn_pinned(new_node, get_irn_pinned(node));
5032 set_ia32_op_type(new_node, ia32_AddrModeS);
5033 set_ia32_ls_mode(new_node, mode_Bu);
5034 set_address(new_node, &addr);
5036 SET_IA32_ORIG_NODE(new_node, node);
5038 be_dep_on_frame(new_node);
5039 return new_r_Proj(block, new_node, mode_M, pn_ia32_Prefetch_M);
5043 * Transform bsf like node
5045 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
5047 ir_node *param = get_Builtin_param(node, 0);
5048 dbg_info *dbgi = get_irn_dbg_info(node);
5050 ir_node *block = get_nodes_block(node);
5051 ir_node *new_block = be_transform_node(block);
5053 ia32_address_mode_t am;
5054 ia32_address_t *addr = &am.addr;
5057 match_arguments(&am, block, NULL, param, NULL, match_am);
5059 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5060 set_am_attributes(cnt, &am);
5061 set_ia32_ls_mode(cnt, get_irn_mode(param));
5063 SET_IA32_ORIG_NODE(cnt, node);
5064 return fix_mem_proj(cnt, &am);
5068 * Transform builtin ffs.
5070 static ir_node *gen_ffs(ir_node *node)
5072 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5073 ir_node *real = skip_Proj(bsf);
5074 dbg_info *dbgi = get_irn_dbg_info(real);
5075 ir_node *block = get_nodes_block(real);
5076 ir_node *flag, *set, *conv, *neg, *or;
5079 if (get_irn_mode(real) != mode_T) {
5080 set_irn_mode(real, mode_T);
5081 bsf = new_r_Proj(block, real, mode_Iu, pn_ia32_res);
5084 flag = new_r_Proj(block, real, mode_b, pn_ia32_flags);
5087 set = new_bd_ia32_Setcc(dbgi, block, flag, pn_Cmp_Eq);
5088 SET_IA32_ORIG_NODE(set, node);
5091 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5092 SET_IA32_ORIG_NODE(conv, node);
5095 neg = new_bd_ia32_Neg(dbgi, block, conv);
5098 or = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5099 set_ia32_commutative(or);
5102 return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, ia32_create_Immediate(NULL, 0, 1));
5106 * Transform builtin clz.
5108 static ir_node *gen_clz(ir_node *node)
5110 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5111 ir_node *real = skip_Proj(bsr);
5112 dbg_info *dbgi = get_irn_dbg_info(real);
5113 ir_node *block = get_nodes_block(real);
5114 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5116 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5120 * Transform builtin ctz.
5122 static ir_node *gen_ctz(ir_node *node)
5124 return gen_unop_AM(node, new_bd_ia32_Bsf);
5128 * Transform builtin parity.
5130 static ir_node *gen_parity(ir_node *node)
5132 ir_node *param = get_Builtin_param(node, 0);
5133 dbg_info *dbgi = get_irn_dbg_info(node);
5135 ir_node *block = get_nodes_block(node);
5137 ir_node *new_block = be_transform_node(block);
5138 ir_node *imm, *cmp, *new_node;
5140 ia32_address_mode_t am;
5141 ia32_address_t *addr = &am.addr;
5145 match_arguments(&am, block, NULL, param, NULL, match_am);
5146 imm = ia32_create_Immediate(NULL, 0, 0);
5147 cmp = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
5148 addr->mem, imm, am.new_op2, am.ins_permuted, 0);
5149 set_am_attributes(cmp, &am);
5150 set_ia32_ls_mode(cmp, mode_Iu);
5152 SET_IA32_ORIG_NODE(cmp, node);
5154 cmp = fix_mem_proj(cmp, &am);
5157 new_node = new_bd_ia32_Setcc(dbgi, new_block, cmp, ia32_pn_Cmp_parity);
5158 SET_IA32_ORIG_NODE(new_node, node);
5161 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5162 nomem, new_node, mode_Bu);
5163 SET_IA32_ORIG_NODE(new_node, node);
5168 * Transform builtin popcount
5170 static ir_node *gen_popcount(ir_node *node) {
5171 ir_node *param = get_Builtin_param(node, 0);
5172 dbg_info *dbgi = get_irn_dbg_info(node);
5174 ir_node *block = get_nodes_block(node);
5175 ir_node *new_block = be_transform_node(block);
5178 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5180 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5181 if (ia32_cg_config.use_popcnt) {
5182 ia32_address_mode_t am;
5183 ia32_address_t *addr = &am.addr;
5186 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5188 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5189 set_am_attributes(cnt, &am);
5190 set_ia32_ls_mode(cnt, get_irn_mode(param));
5192 SET_IA32_ORIG_NODE(cnt, node);
5193 return fix_mem_proj(cnt, &am);
5196 new_param = be_transform_node(param);
5198 /* do the standard popcount algo */
5200 /* m1 = x & 0x55555555 */
5201 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5202 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5205 simm = ia32_create_Immediate(NULL, 0, 1);
5206 s1 = new_bd_ia32_Shl(dbgi, new_block, new_param, simm);
5208 /* m2 = s1 & 0x55555555 */
5209 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5212 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5214 /* m4 = m3 & 0x33333333 */
5215 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5216 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5219 simm = ia32_create_Immediate(NULL, 0, 2);
5220 s2 = new_bd_ia32_Shl(dbgi, new_block, m3, simm);
5222 /* m5 = s2 & 0x33333333 */
5223 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5226 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5228 /* m7 = m6 & 0x0F0F0F0F */
5229 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5230 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5233 simm = ia32_create_Immediate(NULL, 0, 4);
5234 s3 = new_bd_ia32_Shl(dbgi, new_block, m6, simm);
5236 /* m8 = s3 & 0x0F0F0F0F */
5237 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5240 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5242 /* m10 = m9 & 0x00FF00FF */
5243 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5244 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5247 simm = ia32_create_Immediate(NULL, 0, 8);
5248 s4 = new_bd_ia32_Shl(dbgi, new_block, m9, simm);
5250 /* m11 = s4 & 0x00FF00FF */
5251 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5253 /* m12 = m10 + m11 */
5254 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5256 /* m13 = m12 & 0x0000FFFF */
5257 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5258 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5260 /* s5 = m12 >> 16 */
5261 simm = ia32_create_Immediate(NULL, 0, 16);
5262 s5 = new_bd_ia32_Shl(dbgi, new_block, m12, simm);
5264 /* res = m13 + s5 */
5265 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5269 * Transform builtin byte swap.
5271 static ir_node *gen_bswap(ir_node *node) {
5272 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5273 dbg_info *dbgi = get_irn_dbg_info(node);
5275 ir_node *block = get_nodes_block(node);
5276 ir_node *new_block = be_transform_node(block);
5277 ir_mode *mode = get_irn_mode(param);
5278 unsigned size = get_mode_size_bits(mode);
5279 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5283 if (ia32_cg_config.use_i486) {
5284 /* swap available */
5285 return new_bd_ia32_Bswap(dbgi, new_block, param);
5287 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5288 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5290 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5291 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5293 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5295 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5296 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5298 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5299 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5302 /* swap16 always available */
5303 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5306 panic("Invalid bswap size (%d)", size);
5311 * Transform builtin outport.
5313 static ir_node *gen_outport(ir_node *node) {
5314 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5315 ir_node *oldv = get_Builtin_param(node, 1);
5316 ir_mode *mode = get_irn_mode(oldv);
5317 ir_node *value = be_transform_node(oldv);
5318 ir_node *block = be_transform_node(get_nodes_block(node));
5319 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5320 dbg_info *dbgi = get_irn_dbg_info(node);
5322 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5323 set_ia32_ls_mode(res, mode);
5328 * Transform builtin inport.
5330 static ir_node *gen_inport(ir_node *node) {
5331 ir_type *tp = get_Builtin_type(node);
5332 ir_type *rstp = get_method_res_type(tp, 0);
5333 ir_mode *mode = get_type_mode(rstp);
5334 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5335 ir_node *block = be_transform_node(get_nodes_block(node));
5336 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5337 dbg_info *dbgi = get_irn_dbg_info(node);
5339 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5340 set_ia32_ls_mode(res, mode);
5342 /* check for missing Result Proj */
5347 * Transform a builtin inner trampoline
5349 static ir_node *gen_inner_trampoline(ir_node *node) {
5350 ir_node *ptr = get_Builtin_param(node, 0);
5351 ir_node *callee = get_Builtin_param(node, 1);
5352 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5353 ir_node *mem = get_Builtin_mem(node);
5354 ir_node *block = get_nodes_block(node);
5355 ir_node *new_block = be_transform_node(block);
5359 ir_node *trampoline;
5361 dbg_info *dbgi = get_irn_dbg_info(node);
5362 ia32_address_t addr;
5364 /* construct store address */
5365 memset(&addr, 0, sizeof(addr));
5366 ia32_create_address_mode(&addr, ptr, 0);
5368 if (addr.base == NULL) {
5369 addr.base = noreg_GP;
5371 addr.base = be_transform_node(addr.base);
5374 if (addr.index == NULL) {
5375 addr.index = noreg_GP;
5377 addr.index = be_transform_node(addr.index);
5379 addr.mem = be_transform_node(mem);
5381 /* mov ecx, <env> */
5382 val = ia32_create_Immediate(NULL, 0, 0xB9);
5383 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5384 addr.index, addr.mem, val);
5385 set_irn_pinned(store, get_irn_pinned(node));
5386 set_ia32_op_type(store, ia32_AddrModeD);
5387 set_ia32_ls_mode(store, mode_Bu);
5388 set_address(store, &addr);
5392 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5393 addr.index, addr.mem, env);
5394 set_irn_pinned(store, get_irn_pinned(node));
5395 set_ia32_op_type(store, ia32_AddrModeD);
5396 set_ia32_ls_mode(store, mode_Iu);
5397 set_address(store, &addr);
5401 /* jmp rel <callee> */
5402 val = ia32_create_Immediate(NULL, 0, 0xE9);
5403 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5404 addr.index, addr.mem, val);
5405 set_irn_pinned(store, get_irn_pinned(node));
5406 set_ia32_op_type(store, ia32_AddrModeD);
5407 set_ia32_ls_mode(store, mode_Bu);
5408 set_address(store, &addr);
5412 trampoline = be_transform_node(ptr);
5414 /* the callee is typically an immediate */
5415 if (is_SymConst(callee)) {
5416 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5418 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), ia32_create_Immediate(NULL, 0, -10));
5420 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5422 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5423 addr.index, addr.mem, rel);
5424 set_irn_pinned(store, get_irn_pinned(node));
5425 set_ia32_op_type(store, ia32_AddrModeD);
5426 set_ia32_ls_mode(store, mode_Iu);
5427 set_address(store, &addr);
5432 return new_r_Tuple(new_block, 2, in);
5436 * Transform Builtin node.
5438 static ir_node *gen_Builtin(ir_node *node) {
5439 ir_builtin_kind kind = get_Builtin_kind(node);
5443 return gen_trap(node);
5444 case ir_bk_debugbreak:
5445 return gen_debugbreak(node);
5446 case ir_bk_return_address:
5447 return gen_return_address(node);
5448 case ir_bk_frame_address:
5449 return gen_frame_address(node);
5450 case ir_bk_prefetch:
5451 return gen_prefetch(node);
5453 return gen_ffs(node);
5455 return gen_clz(node);
5457 return gen_ctz(node);
5459 return gen_parity(node);
5460 case ir_bk_popcount:
5461 return gen_popcount(node);
5463 return gen_bswap(node);
5465 return gen_outport(node);
5467 return gen_inport(node);
5468 case ir_bk_inner_trampoline:
5469 return gen_inner_trampoline(node);
5471 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5475 * Transform Proj(Builtin) node.
5477 static ir_node *gen_Proj_Builtin(ir_node *proj) {
5478 ir_node *node = get_Proj_pred(proj);
5479 ir_node *new_node = be_transform_node(node);
5480 ir_builtin_kind kind = get_Builtin_kind(node);
5483 case ir_bk_return_address:
5484 case ir_bk_frame_address:
5489 case ir_bk_popcount:
5491 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5494 case ir_bk_debugbreak:
5495 case ir_bk_prefetch:
5497 assert(get_Proj_proj(proj) == pn_Builtin_M);
5500 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5501 return new_r_Proj(get_nodes_block(new_node),
5502 new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5504 assert(get_Proj_proj(proj) == pn_Builtin_M);
5505 return new_r_Proj(get_nodes_block(new_node),
5506 new_node, mode_M, pn_ia32_Inport_M);
5508 case ir_bk_inner_trampoline:
5509 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5510 return get_Tuple_pred(new_node, 1);
5512 assert(get_Proj_proj(proj) == pn_Builtin_M);
5513 return get_Tuple_pred(new_node, 0);
5516 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5519 static ir_node *gen_be_IncSP(ir_node *node)
5521 ir_node *res = be_duplicate_node(node);
5522 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5528 * Transform the Projs from a be_Call.
5530 static ir_node *gen_Proj_be_Call(ir_node *node)
5532 ir_node *block = be_transform_node(get_nodes_block(node));
5533 ir_node *call = get_Proj_pred(node);
5534 ir_node *new_call = be_transform_node(call);
5535 dbg_info *dbgi = get_irn_dbg_info(node);
5536 long proj = get_Proj_proj(node);
5537 ir_mode *mode = get_irn_mode(node);
5540 if (proj == pn_be_Call_M_regular) {
5541 return new_rd_Proj(dbgi, block, new_call, mode_M, n_ia32_Call_mem);
5543 /* transform call modes */
5544 if (mode_is_data(mode)) {
5545 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5549 /* Map from be_Call to ia32_Call proj number */
5550 if (proj == pn_be_Call_sp) {
5551 proj = pn_ia32_Call_stack;
5552 } else if (proj == pn_be_Call_M_regular) {
5553 proj = pn_ia32_Call_M;
5555 arch_register_req_t const *const req = arch_get_register_req_out(node);
5556 int const n_outs = arch_irn_get_n_outs(new_call);
5559 assert(proj >= pn_be_Call_first_res);
5560 assert(req->type & arch_register_req_type_limited);
5562 for (i = 0; i < n_outs; ++i) {
5563 arch_register_req_t const *const new_req
5564 = arch_get_out_register_req(new_call, i);
5566 if (!(new_req->type & arch_register_req_type_limited) ||
5567 new_req->cls != req->cls ||
5568 *new_req->limited != *req->limited)
5577 res = new_rd_Proj(dbgi, block, new_call, mode, proj);
5579 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5581 case pn_ia32_Call_stack:
5582 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
5585 case pn_ia32_Call_fpcw:
5586 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
5594 * Transform the Projs from a Cmp.
5596 static ir_node *gen_Proj_Cmp(ir_node *node)
5598 /* this probably means not all mode_b nodes were lowered... */
5599 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5604 * Transform the Projs from a Bound.
5606 static ir_node *gen_Proj_Bound(ir_node *node)
5608 ir_node *new_node, *block;
5609 ir_node *pred = get_Proj_pred(node);
5611 switch (get_Proj_proj(node)) {
5613 return be_transform_node(get_Bound_mem(pred));
5614 case pn_Bound_X_regular:
5615 new_node = be_transform_node(pred);
5616 block = get_nodes_block(new_node);
5617 return new_r_Proj(block, new_node, mode_X, pn_ia32_Jcc_true);
5618 case pn_Bound_X_except:
5619 new_node = be_transform_node(pred);
5620 block = get_nodes_block(new_node);
5621 return new_r_Proj(block, new_node, mode_X, pn_ia32_Jcc_false);
5623 return be_transform_node(get_Bound_index(pred));
5625 panic("unsupported Proj from Bound");
5629 static ir_node *gen_Proj_ASM(ir_node *node)
5631 ir_mode *mode = get_irn_mode(node);
5632 ir_node *pred = get_Proj_pred(node);
5633 ir_node *new_pred = be_transform_node(pred);
5634 ir_node *block = get_nodes_block(new_pred);
5635 long pos = get_Proj_proj(node);
5637 if (mode == mode_M) {
5638 pos = arch_irn_get_n_outs(new_pred)-1;
5639 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5641 } else if (mode_is_float(mode)) {
5644 panic("unexpected proj mode at ASM");
5647 return new_r_Proj(block, new_pred, mode, pos);
5651 * Transform and potentially renumber Proj nodes.
5653 static ir_node *gen_Proj(ir_node *node)
5655 ir_node *pred = get_Proj_pred(node);
5658 switch (get_irn_opcode(pred)) {
5660 proj = get_Proj_proj(node);
5661 if (proj == pn_Store_M) {
5662 return be_transform_node(pred);
5664 panic("No idea how to transform proj->Store");
5667 return gen_Proj_Load(node);
5669 return gen_Proj_ASM(node);
5671 return gen_Proj_Builtin(node);
5675 return gen_Proj_DivMod(node);
5677 return gen_Proj_CopyB(node);
5679 return gen_Proj_Quot(node);
5681 return gen_Proj_be_SubSP(node);
5683 return gen_Proj_be_AddSP(node);
5685 return gen_Proj_be_Call(node);
5687 return gen_Proj_Cmp(node);
5689 return gen_Proj_Bound(node);
5691 proj = get_Proj_proj(node);
5693 case pn_Start_X_initial_exec: {
5694 ir_node *block = get_nodes_block(pred);
5695 ir_node *new_block = be_transform_node(block);
5696 dbg_info *dbgi = get_irn_dbg_info(node);
5697 /* we exchange the ProjX with a jump */
5698 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5703 case pn_Start_P_tls:
5704 return gen_Proj_tls(node);
5709 if (is_ia32_l_FloattoLL(pred)) {
5710 return gen_Proj_l_FloattoLL(node);
5712 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5716 ir_mode *mode = get_irn_mode(node);
5717 if (ia32_mode_needs_gp_reg(mode)) {
5718 ir_node *new_pred = be_transform_node(pred);
5719 ir_node *block = be_transform_node(get_nodes_block(node));
5720 ir_node *new_proj = new_r_Proj(block, new_pred,
5721 mode_Iu, get_Proj_proj(node));
5722 new_proj->node_nr = node->node_nr;
5727 return be_duplicate_node(node);
5731 * Enters all transform functions into the generic pointer
5733 static void register_transformers(void)
5735 /* first clear the generic function pointer for all ops */
5736 clear_irp_opcodes_generic_func();
5738 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5739 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5779 /* transform ops from intrinsic lowering */
5791 GEN(ia32_l_LLtoFloat);
5792 GEN(ia32_l_FloattoLL);
5798 /* we should never see these nodes */
5813 /* handle builtins */
5816 /* handle generic backend nodes */
5830 * Pre-transform all unknown and noreg nodes.
5832 static void ia32_pretransform_node(void)
5834 ia32_code_gen_t *cg = env_cg;
5836 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5837 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5838 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5839 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5840 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5841 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5843 nomem = get_irg_no_mem(current_ir_graph);
5844 noreg_GP = ia32_new_NoReg_gp(cg);
5850 * Walker, checks if all ia32 nodes producing more than one result have their
5851 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
5853 static void add_missing_keep_walker(ir_node *node, void *data)
5856 unsigned found_projs = 0;
5857 const ir_edge_t *edge;
5858 ir_mode *mode = get_irn_mode(node);
5863 if (!is_ia32_irn(node))
5866 n_outs = arch_irn_get_n_outs(node);
5869 if (is_ia32_SwitchJmp(node))
5872 assert(n_outs < (int) sizeof(unsigned) * 8);
5873 foreach_out_edge(node, edge) {
5874 ir_node *proj = get_edge_src_irn(edge);
5877 /* The node could be kept */
5881 if (get_irn_mode(proj) == mode_M)
5884 pn = get_Proj_proj(proj);
5885 assert(pn < n_outs);
5886 found_projs |= 1 << pn;
5890 /* are keeps missing? */
5892 for (i = 0; i < n_outs; ++i) {
5895 const arch_register_req_t *req;
5896 const arch_register_class_t *cls;
5898 if (found_projs & (1 << i)) {
5902 req = arch_get_out_register_req(node, i);
5907 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5911 block = get_nodes_block(node);
5912 in[0] = new_r_Proj(block, node, arch_register_class_mode(cls), i);
5913 if (last_keep != NULL) {
5914 be_Keep_add_node(last_keep, cls, in[0]);
5916 last_keep = be_new_Keep(block, 1, in);
5917 if (sched_is_scheduled(node)) {
5918 sched_add_after(node, last_keep);
5925 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5928 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5930 ir_graph *irg = be_get_birg_irg(cg->birg);
5931 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5935 * Post-process all calls if we are in SSE mode.
5936 * The ABI requires that the results are in st0, copy them
5937 * to a xmm register.
5939 static void postprocess_fp_call_results(void) {
5942 for (i = ARR_LEN(call_list) - 1; i >= 0; --i) {
5943 ir_node *call = call_list[i];
5944 ir_type *mtp = call_types[i];
5947 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5948 ir_type *res_tp = get_method_res_type(mtp, j);
5949 ir_node *res, *new_res;
5950 const ir_edge_t *edge, *next;
5953 if (! is_atomic_type(res_tp)) {
5954 /* no floating point return */
5957 mode = get_type_mode(res_tp);
5958 if (! mode_is_float(mode)) {
5959 /* no floating point return */
5963 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5966 /* now patch the users */
5967 foreach_out_edge_safe(res, edge, next) {
5968 ir_node *succ = get_edge_src_irn(edge);
5971 if (be_is_Keep(succ))
5974 if (is_ia32_xStore(succ)) {
5975 /* an xStore can be patched into an vfst */
5976 dbg_info *db = get_irn_dbg_info(succ);
5977 ir_node *block = get_nodes_block(succ);
5978 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5979 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5980 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5981 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5982 ir_mode *mode = get_ia32_ls_mode(succ);
5984 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5985 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5986 if (is_ia32_use_frame(succ))
5987 set_ia32_use_frame(st);
5988 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5989 set_irn_pinned(st, get_irn_pinned(succ));
5990 set_ia32_op_type(st, ia32_AddrModeD);
5994 if (new_res == NULL) {
5995 dbg_info *db = get_irn_dbg_info(call);
5996 ir_node *block = get_nodes_block(call);
5997 ir_node *frame = get_irg_frame(current_ir_graph);
5998 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5999 ir_node *call_mem = new_r_Proj(block, call, mode_M, pn_ia32_Call_M);
6000 ir_node *vfst, *xld, *new_mem;
6002 /* store st(0) on stack */
6003 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
6004 set_ia32_op_type(vfst, ia32_AddrModeD);
6005 set_ia32_use_frame(vfst);
6007 /* load into SSE register */
6008 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
6009 set_ia32_op_type(xld, ia32_AddrModeS);
6010 set_ia32_use_frame(xld);
6012 new_res = new_r_Proj(block, xld, mode, pn_ia32_xLoad_res);
6013 new_mem = new_r_Proj(block, xld, mode_M, pn_ia32_xLoad_M);
6015 if (old_mem != NULL) {
6016 edges_reroute(old_mem, new_mem, current_ir_graph);
6020 set_irn_n(succ, get_edge_src_pos(edge), new_res);
6027 /* do the transformation */
6028 void ia32_transform_graph(ia32_code_gen_t *cg)
6032 register_transformers();
6034 initial_fpcw = NULL;
6037 be_timer_push(T_HEIGHTS);
6038 heights = heights_new(cg->irg);
6039 be_timer_pop(T_HEIGHTS);
6040 ia32_calculate_non_address_mode_nodes(cg->birg);
6042 /* the transform phase is not safe for CSE (yet) because several nodes get
6043 * attributes set after their creation */
6044 cse_last = get_opt_cse();
6047 call_list = NEW_ARR_F(ir_node *, 0);
6048 call_types = NEW_ARR_F(ir_type *, 0);
6049 be_transform_graph(cg->birg, ia32_pretransform_node);
6051 if (ia32_cg_config.use_sse2)
6052 postprocess_fp_call_results();
6053 DEL_ARR_F(call_types);
6054 DEL_ARR_F(call_list);
6056 set_opt_cse(cse_last);
6058 ia32_free_non_address_mode_nodes();
6059 heights_free(heights);
6063 void ia32_init_transform(void)
6065 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");