2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
50 #include "../benode.h"
51 #include "../besched.h"
53 #include "../beutil.h"
55 #include "../betranshlp.h"
58 #include "bearch_ia32_t.h"
59 #include "ia32_common_transform.h"
60 #include "ia32_nodes_attr.h"
61 #include "ia32_transform.h"
62 #include "ia32_new_nodes.h"
63 #include "ia32_dbg_stat.h"
64 #include "ia32_optimize.h"
65 #include "ia32_util.h"
66 #include "ia32_address_mode.h"
67 #include "ia32_architecture.h"
69 #include "gen_ia32_regalloc_if.h"
71 /* define this to construct SSE constants instead of load them */
72 #undef CONSTRUCT_SSE_CONST
75 #define SFP_SIGN "0x80000000"
76 #define DFP_SIGN "0x8000000000000000"
77 #define SFP_ABS "0x7FFFFFFF"
78 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
80 #define ULL_BIAS "18446744073709551616"
82 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
83 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
84 #define ENT_SFP_ABS "C_ia32_sfp_abs"
85 #define ENT_DFP_ABS "C_ia32_dfp_abs"
86 #define ENT_ULL_BIAS "C_ia32_ull_bias"
88 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
89 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
91 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
93 static ir_node *initial_fpcw = NULL;
94 int ia32_no_pic_adjust;
96 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
97 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
100 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
101 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
104 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
108 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
110 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
111 ir_node *base, ir_node *index, ir_node *mem);
113 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
114 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
117 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
119 static ir_node *create_immediate_or_transform(ir_node *node,
120 char immediate_constraint_type);
122 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
123 dbg_info *dbgi, ir_node *block,
124 ir_node *op, ir_node *orig_node);
126 /* its enough to have those once */
127 static ir_node *nomem, *noreg_GP;
129 /** a list to postprocess all calls */
130 static ir_node **call_list;
131 static ir_type **call_types;
133 /** Return non-zero is a node represents the 0 constant. */
134 static bool is_Const_0(ir_node *node)
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
148 return is_Const(node) && is_Const_all_one(node);
152 * returns true if constant can be created with a simple float command
154 static bool is_simple_x87_Const(ir_node *node)
156 ir_tarval *tv = get_Const_tarval(node);
157 if (tarval_is_null(tv) || tarval_is_one(tv))
160 /* TODO: match all the other float constants */
165 * returns true if constant can be created with a simple float command
167 static bool is_simple_sse_Const(ir_node *node)
169 ir_tarval *tv = get_Const_tarval(node);
170 ir_mode *mode = get_tarval_mode(tv);
175 if (tarval_is_null(tv)
176 #ifdef CONSTRUCT_SSE_CONST
181 #ifdef CONSTRUCT_SSE_CONST
182 if (mode == mode_D) {
183 unsigned val = get_tarval_sub_bits(tv, 0) |
184 (get_tarval_sub_bits(tv, 1) << 8) |
185 (get_tarval_sub_bits(tv, 2) << 16) |
186 (get_tarval_sub_bits(tv, 3) << 24);
188 /* lower 32bit are zero, really a 32bit constant */
191 #endif /* CONSTRUCT_SSE_CONST */
192 /* TODO: match all the other float constants */
197 * return NoREG or pic_base in case of PIC.
198 * This is necessary as base address for newly created symbols
200 static ir_node *get_symconst_base(void)
202 ir_graph *irg = current_ir_graph;
204 if (be_get_irg_options(irg)->pic) {
205 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
206 return arch_env->impl->get_pic_base(irg);
213 * Transforms a Const.
215 static ir_node *gen_Const(ir_node *node)
217 ir_node *old_block = get_nodes_block(node);
218 ir_node *block = be_transform_node(old_block);
219 dbg_info *dbgi = get_irn_dbg_info(node);
220 ir_mode *mode = get_irn_mode(node);
222 assert(is_Const(node));
224 if (mode_is_float(mode)) {
230 if (ia32_cg_config.use_sse2) {
231 ir_tarval *tv = get_Const_tarval(node);
232 if (tarval_is_null(tv)) {
233 load = new_bd_ia32_xZero(dbgi, block);
234 set_ia32_ls_mode(load, mode);
236 #ifdef CONSTRUCT_SSE_CONST
237 } else if (tarval_is_one(tv)) {
238 int cnst = mode == mode_F ? 26 : 55;
239 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
240 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
241 ir_node *pslld, *psrld;
243 load = new_bd_ia32_xAllOnes(dbgi, block);
244 set_ia32_ls_mode(load, mode);
245 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
246 set_ia32_ls_mode(pslld, mode);
247 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
248 set_ia32_ls_mode(psrld, mode);
250 #endif /* CONSTRUCT_SSE_CONST */
251 } else if (mode == mode_F) {
252 /* we can place any 32bit constant by using a movd gp, sse */
253 unsigned val = get_tarval_sub_bits(tv, 0) |
254 (get_tarval_sub_bits(tv, 1) << 8) |
255 (get_tarval_sub_bits(tv, 2) << 16) |
256 (get_tarval_sub_bits(tv, 3) << 24);
257 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
258 load = new_bd_ia32_xMovd(dbgi, block, cnst);
259 set_ia32_ls_mode(load, mode);
262 #ifdef CONSTRUCT_SSE_CONST
263 if (mode == mode_D) {
264 unsigned val = get_tarval_sub_bits(tv, 0) |
265 (get_tarval_sub_bits(tv, 1) << 8) |
266 (get_tarval_sub_bits(tv, 2) << 16) |
267 (get_tarval_sub_bits(tv, 3) << 24);
269 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
270 ir_node *cnst, *psllq;
272 /* fine, lower 32bit are zero, produce 32bit value */
273 val = get_tarval_sub_bits(tv, 4) |
274 (get_tarval_sub_bits(tv, 5) << 8) |
275 (get_tarval_sub_bits(tv, 6) << 16) |
276 (get_tarval_sub_bits(tv, 7) << 24);
277 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
278 load = new_bd_ia32_xMovd(dbgi, block, cnst);
279 set_ia32_ls_mode(load, mode);
280 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
281 set_ia32_ls_mode(psllq, mode);
286 #endif /* CONSTRUCT_SSE_CONST */
287 floatent = ia32_create_float_const_entity(node);
289 base = get_symconst_base();
290 load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
292 set_ia32_op_type(load, ia32_AddrModeS);
293 set_ia32_am_sc(load, floatent);
294 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
295 res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
298 if (is_Const_null(node)) {
299 load = new_bd_ia32_vfldz(dbgi, block);
301 set_ia32_ls_mode(load, mode);
302 } else if (is_Const_one(node)) {
303 load = new_bd_ia32_vfld1(dbgi, block);
305 set_ia32_ls_mode(load, mode);
310 floatent = ia32_create_float_const_entity(node);
311 /* create_float_const_ent is smart and sometimes creates
313 ls_mode = get_type_mode(get_entity_type(floatent));
314 base = get_symconst_base();
315 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
317 set_ia32_op_type(load, ia32_AddrModeS);
318 set_ia32_am_sc(load, floatent);
319 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
320 res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
323 #ifdef CONSTRUCT_SSE_CONST
325 #endif /* CONSTRUCT_SSE_CONST */
326 SET_IA32_ORIG_NODE(load, node);
328 be_dep_on_frame(load);
330 } else { /* non-float mode */
332 ir_tarval *tv = get_Const_tarval(node);
335 tv = tarval_convert_to(tv, mode_Iu);
337 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
339 panic("couldn't convert constant tarval (%+F)", node);
341 val = get_tarval_long(tv);
343 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
344 SET_IA32_ORIG_NODE(cnst, node);
346 be_dep_on_frame(cnst);
352 * Transforms a SymConst.
354 static ir_node *gen_SymConst(ir_node *node)
356 ir_node *old_block = get_nodes_block(node);
357 ir_node *block = be_transform_node(old_block);
358 dbg_info *dbgi = get_irn_dbg_info(node);
359 ir_mode *mode = get_irn_mode(node);
362 if (mode_is_float(mode)) {
363 if (ia32_cg_config.use_sse2)
364 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
366 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
367 set_ia32_am_sc(cnst, get_SymConst_entity(node));
368 set_ia32_use_frame(cnst);
372 if (get_SymConst_kind(node) != symconst_addr_ent) {
373 panic("backend only support symconst_addr_ent (at %+F)", node);
375 entity = get_SymConst_entity(node);
376 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
379 SET_IA32_ORIG_NODE(cnst, node);
381 be_dep_on_frame(cnst);
386 * Create a float type for the given mode and cache it.
388 * @param mode the mode for the float type (might be integer mode for SSE2 types)
389 * @param align alignment
391 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
397 if (mode == mode_Iu) {
398 static ir_type *int_Iu[16] = {NULL, };
400 if (int_Iu[align] == NULL) {
401 int_Iu[align] = tp = new_type_primitive(mode);
402 /* set the specified alignment */
403 set_type_alignment_bytes(tp, align);
405 return int_Iu[align];
406 } else if (mode == mode_Lu) {
407 static ir_type *int_Lu[16] = {NULL, };
409 if (int_Lu[align] == NULL) {
410 int_Lu[align] = tp = new_type_primitive(mode);
411 /* set the specified alignment */
412 set_type_alignment_bytes(tp, align);
414 return int_Lu[align];
415 } else if (mode == mode_F) {
416 static ir_type *float_F[16] = {NULL, };
418 if (float_F[align] == NULL) {
419 float_F[align] = tp = new_type_primitive(mode);
420 /* set the specified alignment */
421 set_type_alignment_bytes(tp, align);
423 return float_F[align];
424 } else if (mode == mode_D) {
425 static ir_type *float_D[16] = {NULL, };
427 if (float_D[align] == NULL) {
428 float_D[align] = tp = new_type_primitive(mode);
429 /* set the specified alignment */
430 set_type_alignment_bytes(tp, align);
432 return float_D[align];
434 static ir_type *float_E[16] = {NULL, };
436 if (float_E[align] == NULL) {
437 float_E[align] = tp = new_type_primitive(mode);
438 /* set the specified alignment */
439 set_type_alignment_bytes(tp, align);
441 return float_E[align];
446 * Create a float[2] array type for the given atomic type.
448 * @param tp the atomic type
450 static ir_type *ia32_create_float_array(ir_type *tp)
452 ir_mode *mode = get_type_mode(tp);
453 unsigned align = get_type_alignment_bytes(tp);
458 if (mode == mode_F) {
459 static ir_type *float_F[16] = {NULL, };
461 if (float_F[align] != NULL)
462 return float_F[align];
463 arr = float_F[align] = new_type_array(1, tp);
464 } else if (mode == mode_D) {
465 static ir_type *float_D[16] = {NULL, };
467 if (float_D[align] != NULL)
468 return float_D[align];
469 arr = float_D[align] = new_type_array(1, tp);
471 static ir_type *float_E[16] = {NULL, };
473 if (float_E[align] != NULL)
474 return float_E[align];
475 arr = float_E[align] = new_type_array(1, tp);
477 set_type_alignment_bytes(arr, align);
478 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
479 set_type_state(arr, layout_fixed);
483 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
484 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
486 static const struct {
487 const char *ent_name;
488 const char *cnst_str;
491 } names [ia32_known_const_max] = {
492 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
493 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
494 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
495 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
496 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
498 static ir_entity *ent_cache[ia32_known_const_max];
500 const char *ent_name, *cnst_str;
506 ent_name = names[kct].ent_name;
507 if (! ent_cache[kct]) {
508 cnst_str = names[kct].cnst_str;
510 switch (names[kct].mode) {
511 case 0: mode = mode_Iu; break;
512 case 1: mode = mode_Lu; break;
513 default: mode = mode_F; break;
515 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
516 tp = ia32_create_float_type(mode, names[kct].align);
518 if (kct == ia32_ULLBIAS)
519 tp = ia32_create_float_array(tp);
520 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
522 set_entity_ld_ident(ent, get_entity_ident(ent));
523 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
524 set_entity_visibility(ent, ir_visibility_private);
526 if (kct == ia32_ULLBIAS) {
527 ir_initializer_t *initializer = create_initializer_compound(2);
529 set_initializer_compound_value(initializer, 0,
530 create_initializer_tarval(get_mode_null(mode)));
531 set_initializer_compound_value(initializer, 1,
532 create_initializer_tarval(tv));
534 set_entity_initializer(ent, initializer);
536 set_entity_initializer(ent, create_initializer_tarval(tv));
539 /* cache the entry */
540 ent_cache[kct] = ent;
543 return ent_cache[kct];
547 * return true if the node is a Proj(Load) and could be used in source address
548 * mode for another node. Will return only true if the @p other node is not
549 * dependent on the memory of the Load (for binary operations use the other
550 * input here, for unary operations use NULL).
552 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
553 ir_node *other, ir_node *other2, match_flags_t flags)
558 /* float constants are always available */
559 if (is_Const(node)) {
560 ir_mode *mode = get_irn_mode(node);
561 if (mode_is_float(mode)) {
562 if (ia32_cg_config.use_sse2) {
563 if (is_simple_sse_Const(node))
566 if (is_simple_x87_Const(node))
569 if (get_irn_n_edges(node) > 1)
577 load = get_Proj_pred(node);
578 pn = get_Proj_proj(node);
579 if (!is_Load(load) || pn != pn_Load_res)
581 if (get_nodes_block(load) != block)
583 /* we only use address mode if we're the only user of the load */
584 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
586 /* in some edge cases with address mode we might reach the load normally
587 * and through some AM sequence, if it is already materialized then we
588 * can't create an AM node from it */
589 if (be_is_transformed(node))
592 /* don't do AM if other node inputs depend on the load (via mem-proj) */
593 if (other != NULL && ia32_prevents_AM(block, load, other))
596 if (other2 != NULL && ia32_prevents_AM(block, load, other2))
602 typedef struct ia32_address_mode_t ia32_address_mode_t;
603 struct ia32_address_mode_t {
608 ia32_op_type_t op_type;
612 unsigned commutative : 1;
613 unsigned ins_permuted : 1;
616 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
618 /* construct load address */
619 memset(addr, 0, sizeof(addr[0]));
620 ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
622 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
623 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
624 addr->mem = be_transform_node(mem);
627 static void build_address(ia32_address_mode_t *am, ir_node *node,
628 ia32_create_am_flags_t flags)
630 ia32_address_t *addr = &am->addr;
636 /* floating point immediates */
637 if (is_Const(node)) {
638 ir_entity *entity = ia32_create_float_const_entity(node);
639 addr->base = get_symconst_base();
640 addr->index = noreg_GP;
642 addr->symconst_ent = entity;
644 am->ls_mode = get_type_mode(get_entity_type(entity));
645 am->pinned = op_pin_state_floats;
649 load = get_Proj_pred(node);
650 ptr = get_Load_ptr(load);
651 mem = get_Load_mem(load);
652 new_mem = be_transform_node(mem);
653 am->pinned = get_irn_pinned(load);
654 am->ls_mode = get_Load_mode(load);
655 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
658 /* construct load address */
659 ia32_create_address_mode(addr, ptr, flags);
661 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
662 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
666 static void set_address(ir_node *node, const ia32_address_t *addr)
668 set_ia32_am_scale(node, addr->scale);
669 set_ia32_am_sc(node, addr->symconst_ent);
670 set_ia32_am_offs_int(node, addr->offset);
671 if (addr->symconst_sign)
672 set_ia32_am_sc_sign(node);
674 set_ia32_use_frame(node);
675 set_ia32_frame_ent(node, addr->frame_entity);
679 * Apply attributes of a given address mode to a node.
681 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
683 set_address(node, &am->addr);
685 set_ia32_op_type(node, am->op_type);
686 set_ia32_ls_mode(node, am->ls_mode);
687 if (am->pinned == op_pin_state_pinned) {
688 /* beware: some nodes are already pinned and did not allow to change the state */
689 if (get_irn_pinned(node) != op_pin_state_pinned)
690 set_irn_pinned(node, op_pin_state_pinned);
693 set_ia32_commutative(node);
697 * Check, if a given node is a Down-Conv, ie. a integer Conv
698 * from a mode with a mode with more bits to a mode with lesser bits.
699 * Moreover, we return only true if the node has not more than 1 user.
701 * @param node the node
702 * @return non-zero if node is a Down-Conv
704 static int is_downconv(const ir_node *node)
712 /* we only want to skip the conv when we're the only user
713 * (because this test is used in the context of address-mode selection
714 * and we don't want to use address mode for multiple users) */
715 if (get_irn_n_edges(node) > 1)
718 src_mode = get_irn_mode(get_Conv_op(node));
719 dest_mode = get_irn_mode(node);
721 ia32_mode_needs_gp_reg(src_mode) &&
722 ia32_mode_needs_gp_reg(dest_mode) &&
723 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
726 /** Skip all Down-Conv's on a given node and return the resulting node. */
727 ir_node *ia32_skip_downconv(ir_node *node)
729 while (is_downconv(node))
730 node = get_Conv_op(node);
735 static bool is_sameconv(ir_node *node)
743 /* we only want to skip the conv when we're the only user
744 * (because this test is used in the context of address-mode selection
745 * and we don't want to use address mode for multiple users) */
746 if (get_irn_n_edges(node) > 1)
749 src_mode = get_irn_mode(get_Conv_op(node));
750 dest_mode = get_irn_mode(node);
752 ia32_mode_needs_gp_reg(src_mode) &&
753 ia32_mode_needs_gp_reg(dest_mode) &&
754 get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
757 /** Skip all signedness convs */
758 static ir_node *ia32_skip_sameconv(ir_node *node)
760 while (is_sameconv(node))
761 node = get_Conv_op(node);
766 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
768 ir_mode *mode = get_irn_mode(node);
773 if (mode_is_signed(mode)) {
778 block = get_nodes_block(node);
779 dbgi = get_irn_dbg_info(node);
781 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
785 * matches operands of a node into ia32 addressing/operand modes. This covers
786 * usage of source address mode, immediates, operations with non 32-bit modes,
788 * The resulting data is filled into the @p am struct. block is the block
789 * of the node whose arguments are matched. op1, op2 are the first and second
790 * input that are matched (op1 may be NULL). other_op is another unrelated
791 * input that is not matched! but which is needed sometimes to check if AM
792 * for op1/op2 is legal.
793 * @p flags describes the supported modes of the operation in detail.
795 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
796 ir_node *op1, ir_node *op2, ir_node *other_op,
799 ia32_address_t *addr = &am->addr;
800 ir_mode *mode = get_irn_mode(op2);
801 int mode_bits = get_mode_size_bits(mode);
802 ir_node *new_op1, *new_op2;
804 unsigned commutative;
805 int use_am_and_immediates;
808 memset(am, 0, sizeof(am[0]));
810 commutative = (flags & match_commutative) != 0;
811 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
812 use_am = (flags & match_am) != 0;
813 use_immediate = (flags & match_immediate) != 0;
814 assert(!use_am_and_immediates || use_immediate);
817 assert(!commutative || op1 != NULL);
818 assert(use_am || !(flags & match_8bit_am));
819 assert(use_am || !(flags & match_16bit_am));
821 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
822 (mode_bits == 16 && !(flags & match_16bit_am))) {
826 /* we can simply skip downconvs for mode neutral nodes: the upper bits
827 * can be random for these operations */
828 if (flags & match_mode_neutral) {
829 op2 = ia32_skip_downconv(op2);
831 op1 = ia32_skip_downconv(op1);
834 op2 = ia32_skip_sameconv(op2);
836 op1 = ia32_skip_sameconv(op1);
840 /* match immediates. firm nodes are normalized: constants are always on the
843 if (!(flags & match_try_am) && use_immediate) {
844 new_op2 = ia32_try_create_Immediate(op2, 0);
847 if (new_op2 == NULL &&
848 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849 build_address(am, op2, ia32_create_am_normal);
850 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
851 if (mode_is_float(mode)) {
852 new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
856 am->op_type = ia32_AddrModeS;
857 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
859 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
861 build_address(am, op1, ia32_create_am_normal);
863 if (mode_is_float(mode)) {
864 noreg = ia32_new_NoReg_vfp(current_ir_graph);
869 if (new_op2 != NULL) {
872 new_op1 = be_transform_node(op2);
874 am->ins_permuted = true;
876 am->op_type = ia32_AddrModeS;
879 am->op_type = ia32_Normal;
881 if (flags & match_try_am) {
887 mode = get_irn_mode(op2);
888 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
889 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
891 new_op2 = create_upconv(op2, NULL);
892 am->ls_mode = mode_Iu;
894 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
896 new_op2 = be_transform_node(op2);
897 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
900 if (addr->base == NULL)
901 addr->base = noreg_GP;
902 if (addr->index == NULL)
903 addr->index = noreg_GP;
904 if (addr->mem == NULL)
907 am->new_op1 = new_op1;
908 am->new_op2 = new_op2;
909 am->commutative = commutative;
913 * "Fixes" a node that uses address mode by turning it into mode_T
914 * and returning a pn_ia32_res Proj.
916 * @param node the node
917 * @param am its address mode
919 * @return a Proj(pn_ia32_res) if a memory address mode is used,
922 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
927 if (am->mem_proj == NULL)
930 /* we have to create a mode_T so the old MemProj can attach to us */
931 mode = get_irn_mode(node);
932 load = get_Proj_pred(am->mem_proj);
934 be_set_transformed_node(load, node);
936 if (mode != mode_T) {
937 set_irn_mode(node, mode_T);
938 return new_rd_Proj(NULL, node, mode, pn_ia32_res);
945 * Construct a standard binary operation, set AM and immediate if required.
947 * @param node The original node for which the binop is created
948 * @param op1 The first operand
949 * @param op2 The second operand
950 * @param func The node constructor function
951 * @return The constructed ia32 node.
953 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
954 construct_binop_func *func, match_flags_t flags)
957 ir_node *block, *new_block, *new_node;
958 ia32_address_mode_t am;
959 ia32_address_t *addr = &am.addr;
961 block = get_nodes_block(node);
962 match_arguments(&am, block, op1, op2, NULL, flags);
964 dbgi = get_irn_dbg_info(node);
965 new_block = be_transform_node(block);
966 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
967 am.new_op1, am.new_op2);
968 set_am_attributes(new_node, &am);
969 /* we can't use source address mode anymore when using immediates */
970 if (!(flags & match_am_and_immediates) &&
971 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
972 set_ia32_am_support(new_node, ia32_am_none);
973 SET_IA32_ORIG_NODE(new_node, node);
975 new_node = fix_mem_proj(new_node, &am);
981 * Generic names for the inputs of an ia32 binary op.
984 n_ia32_l_binop_left, /**< ia32 left input */
985 n_ia32_l_binop_right, /**< ia32 right input */
986 n_ia32_l_binop_eflags /**< ia32 eflags input */
988 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Adc_left, n_Adc_left)
989 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Adc_right, n_Adc_right)
990 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Adc_eflags, n_Adc_eflags)
991 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Sbb_minuend, n_Sbb_minuend)
992 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
993 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Sbb_eflags, n_Sbb_eflags)
996 * Construct a binary operation which also consumes the eflags.
998 * @param node The node to transform
999 * @param func The node constructor function
1000 * @param flags The match flags
1001 * @return The constructor ia32 node
1003 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
1004 match_flags_t flags)
1006 ir_node *src_block = get_nodes_block(node);
1007 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
1008 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
1009 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1011 ir_node *block, *new_node, *new_eflags;
1012 ia32_address_mode_t am;
1013 ia32_address_t *addr = &am.addr;
1015 match_arguments(&am, src_block, op1, op2, eflags, flags);
1017 dbgi = get_irn_dbg_info(node);
1018 block = be_transform_node(src_block);
1019 new_eflags = be_transform_node(eflags);
1020 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
1021 am.new_op1, am.new_op2, new_eflags);
1022 set_am_attributes(new_node, &am);
1023 /* we can't use source address mode anymore when using immediates */
1024 if (!(flags & match_am_and_immediates) &&
1025 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
1026 set_ia32_am_support(new_node, ia32_am_none);
1027 SET_IA32_ORIG_NODE(new_node, node);
1029 new_node = fix_mem_proj(new_node, &am);
1034 static ir_node *get_fpcw(void)
1037 if (initial_fpcw != NULL)
1038 return initial_fpcw;
1040 fpcw = be_abi_get_ignore_irn(be_get_irg_abi(current_ir_graph),
1041 &ia32_registers[REG_FPCW]);
1042 initial_fpcw = be_transform_node(fpcw);
1044 return initial_fpcw;
1048 * Construct a standard binary operation, set AM and immediate if required.
1050 * @param op1 The first operand
1051 * @param op2 The second operand
1052 * @param func The node constructor function
1053 * @return The constructed ia32 node.
1055 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1056 construct_binop_float_func *func)
1058 ir_mode *mode = get_irn_mode(node);
1060 ir_node *block, *new_block, *new_node;
1061 ia32_address_mode_t am;
1062 ia32_address_t *addr = &am.addr;
1063 ia32_x87_attr_t *attr;
1064 /* All operations are considered commutative, because there are reverse
1066 match_flags_t flags = match_commutative;
1068 /* happens for div nodes... */
1069 if (mode == mode_T) {
1071 mode = get_Div_resmode(node);
1073 panic("can't determine mode");
1076 /* cannot use address mode with long double on x87 */
1077 if (get_mode_size_bits(mode) <= 64)
1080 block = get_nodes_block(node);
1081 match_arguments(&am, block, op1, op2, NULL, flags);
1083 dbgi = get_irn_dbg_info(node);
1084 new_block = be_transform_node(block);
1085 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1086 am.new_op1, am.new_op2, get_fpcw());
1087 set_am_attributes(new_node, &am);
1089 attr = get_ia32_x87_attr(new_node);
1090 attr->attr.data.ins_permuted = am.ins_permuted;
1092 SET_IA32_ORIG_NODE(new_node, node);
1094 new_node = fix_mem_proj(new_node, &am);
1100 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1102 * @param op1 The first operand
1103 * @param op2 The second operand
1104 * @param func The node constructor function
1105 * @return The constructed ia32 node.
1107 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1108 construct_shift_func *func,
1109 match_flags_t flags)
1112 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1114 assert(! mode_is_float(get_irn_mode(node)));
1115 assert(flags & match_immediate);
1116 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1118 if (flags & match_mode_neutral) {
1119 op1 = ia32_skip_downconv(op1);
1120 new_op1 = be_transform_node(op1);
1121 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1122 new_op1 = create_upconv(op1, node);
1124 new_op1 = be_transform_node(op1);
1127 /* the shift amount can be any mode that is bigger than 5 bits, since all
1128 * other bits are ignored anyway */
1129 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1130 ir_node *const op = get_Conv_op(op2);
1131 if (mode_is_float(get_irn_mode(op)))
1134 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1136 new_op2 = create_immediate_or_transform(op2, 0);
1138 dbgi = get_irn_dbg_info(node);
1139 block = get_nodes_block(node);
1140 new_block = be_transform_node(block);
1141 new_node = func(dbgi, new_block, new_op1, new_op2);
1142 SET_IA32_ORIG_NODE(new_node, node);
1144 /* lowered shift instruction may have a dependency operand, handle it here */
1145 if (get_irn_arity(node) == 3) {
1146 /* we have a dependency */
1147 ir_node* dep = get_irn_n(node, 2);
1148 if (get_irn_n_edges(dep) > 1) {
1149 /* ... which has at least one user other than 'node' */
1150 ir_node *new_dep = be_transform_node(dep);
1151 add_irn_dep(new_node, new_dep);
1160 * Construct a standard unary operation, set AM and immediate if required.
1162 * @param op The operand
1163 * @param func The node constructor function
1164 * @return The constructed ia32 node.
1166 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1167 match_flags_t flags)
1170 ir_node *block, *new_block, *new_op, *new_node;
1172 assert(flags == 0 || flags == match_mode_neutral);
1173 if (flags & match_mode_neutral) {
1174 op = ia32_skip_downconv(op);
1177 new_op = be_transform_node(op);
1178 dbgi = get_irn_dbg_info(node);
1179 block = get_nodes_block(node);
1180 new_block = be_transform_node(block);
1181 new_node = func(dbgi, new_block, new_op);
1183 SET_IA32_ORIG_NODE(new_node, node);
1188 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1189 ia32_address_t *addr)
1191 ir_node *base, *index, *res;
1197 base = be_transform_node(base);
1200 index = addr->index;
1201 if (index == NULL) {
1204 index = be_transform_node(index);
1207 res = new_bd_ia32_Lea(dbgi, block, base, index);
1208 set_address(res, addr);
1214 * Returns non-zero if a given address mode has a symbolic or
1215 * numerical offset != 0.
1217 static int am_has_immediates(const ia32_address_t *addr)
1219 return addr->offset != 0 || addr->symconst_ent != NULL
1220 || addr->frame_entity || addr->use_frame;
1224 * Creates an ia32 Add.
1226 * @return the created ia32 Add node
1228 static ir_node *gen_Add(ir_node *node)
1230 ir_mode *mode = get_irn_mode(node);
1231 ir_node *op1 = get_Add_left(node);
1232 ir_node *op2 = get_Add_right(node);
1234 ir_node *block, *new_block, *new_node, *add_immediate_op;
1235 ia32_address_t addr;
1236 ia32_address_mode_t am;
1238 if (mode_is_float(mode)) {
1239 if (ia32_cg_config.use_sse2)
1240 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1241 match_commutative | match_am);
1243 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1246 ia32_mark_non_am(node);
1248 op2 = ia32_skip_downconv(op2);
1249 op1 = ia32_skip_downconv(op1);
1253 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1254 * 1. Add with immediate -> Lea
1255 * 2. Add with possible source address mode -> Add
1256 * 3. Otherwise -> Lea
1258 memset(&addr, 0, sizeof(addr));
1259 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1260 add_immediate_op = NULL;
1262 dbgi = get_irn_dbg_info(node);
1263 block = get_nodes_block(node);
1264 new_block = be_transform_node(block);
1267 if (addr.base == NULL && addr.index == NULL) {
1268 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1269 addr.symconst_sign, 0, addr.offset);
1270 be_dep_on_frame(new_node);
1271 SET_IA32_ORIG_NODE(new_node, node);
1274 /* add with immediate? */
1275 if (addr.index == NULL) {
1276 add_immediate_op = addr.base;
1277 } else if (addr.base == NULL && addr.scale == 0) {
1278 add_immediate_op = addr.index;
1281 if (add_immediate_op != NULL) {
1282 if (!am_has_immediates(&addr)) {
1283 #ifdef DEBUG_libfirm
1284 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1287 return be_transform_node(add_immediate_op);
1290 new_node = create_lea_from_address(dbgi, new_block, &addr);
1291 SET_IA32_ORIG_NODE(new_node, node);
1295 /* test if we can use source address mode */
1296 match_arguments(&am, block, op1, op2, NULL, match_commutative
1297 | match_mode_neutral | match_am | match_immediate | match_try_am);
1299 /* construct an Add with source address mode */
1300 if (am.op_type == ia32_AddrModeS) {
1301 ia32_address_t *am_addr = &am.addr;
1302 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1303 am_addr->index, am_addr->mem, am.new_op1,
1305 set_am_attributes(new_node, &am);
1306 SET_IA32_ORIG_NODE(new_node, node);
1308 new_node = fix_mem_proj(new_node, &am);
1313 /* otherwise construct a lea */
1314 new_node = create_lea_from_address(dbgi, new_block, &addr);
1315 SET_IA32_ORIG_NODE(new_node, node);
1320 * Creates an ia32 Mul.
1322 * @return the created ia32 Mul node
1324 static ir_node *gen_Mul(ir_node *node)
1326 ir_node *op1 = get_Mul_left(node);
1327 ir_node *op2 = get_Mul_right(node);
1328 ir_mode *mode = get_irn_mode(node);
1330 if (mode_is_float(mode)) {
1331 if (ia32_cg_config.use_sse2)
1332 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1333 match_commutative | match_am);
1335 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1337 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1338 match_commutative | match_am | match_mode_neutral |
1339 match_immediate | match_am_and_immediates);
1343 * Creates an ia32 Mulh.
1344 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1345 * this result while Mul returns the lower 32 bit.
1347 * @return the created ia32 Mulh node
1349 static ir_node *gen_Mulh(ir_node *node)
1351 dbg_info *dbgi = get_irn_dbg_info(node);
1352 ir_node *op1 = get_Mulh_left(node);
1353 ir_node *op2 = get_Mulh_right(node);
1354 ir_mode *mode = get_irn_mode(node);
1356 ir_node *proj_res_high;
1358 if (get_mode_size_bits(mode) != 32) {
1359 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1362 if (mode_is_signed(mode)) {
1363 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1364 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1366 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1367 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1369 return proj_res_high;
1373 * Creates an ia32 And.
1375 * @return The created ia32 And node
1377 static ir_node *gen_And(ir_node *node)
1379 ir_node *op1 = get_And_left(node);
1380 ir_node *op2 = get_And_right(node);
1381 assert(! mode_is_float(get_irn_mode(node)));
1383 /* is it a zero extension? */
1384 if (is_Const(op2)) {
1385 ir_tarval *tv = get_Const_tarval(op2);
1386 long v = get_tarval_long(tv);
1388 if (v == 0xFF || v == 0xFFFF) {
1389 dbg_info *dbgi = get_irn_dbg_info(node);
1390 ir_node *block = get_nodes_block(node);
1397 assert(v == 0xFFFF);
1400 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1405 return gen_binop(node, op1, op2, new_bd_ia32_And,
1406 match_commutative | match_mode_neutral | match_am | match_immediate);
1412 * Creates an ia32 Or.
1414 * @return The created ia32 Or node
1416 static ir_node *gen_Or(ir_node *node)
1418 ir_node *op1 = get_Or_left(node);
1419 ir_node *op2 = get_Or_right(node);
1421 assert (! mode_is_float(get_irn_mode(node)));
1422 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1423 | match_mode_neutral | match_am | match_immediate);
1429 * Creates an ia32 Eor.
1431 * @return The created ia32 Eor node
1433 static ir_node *gen_Eor(ir_node *node)
1435 ir_node *op1 = get_Eor_left(node);
1436 ir_node *op2 = get_Eor_right(node);
1438 assert(! mode_is_float(get_irn_mode(node)));
1439 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1440 | match_mode_neutral | match_am | match_immediate);
1445 * Creates an ia32 Sub.
1447 * @return The created ia32 Sub node
1449 static ir_node *gen_Sub(ir_node *node)
1451 ir_node *op1 = get_Sub_left(node);
1452 ir_node *op2 = get_Sub_right(node);
1453 ir_mode *mode = get_irn_mode(node);
1455 if (mode_is_float(mode)) {
1456 if (ia32_cg_config.use_sse2)
1457 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1459 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1462 if (is_Const(op2)) {
1463 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1467 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1468 | match_am | match_immediate);
1471 static ir_node *transform_AM_mem(ir_node *const block,
1472 ir_node *const src_val,
1473 ir_node *const src_mem,
1474 ir_node *const am_mem)
1476 if (is_NoMem(am_mem)) {
1477 return be_transform_node(src_mem);
1478 } else if (is_Proj(src_val) &&
1480 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1481 /* avoid memory loop */
1483 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1484 ir_node *const ptr_pred = get_Proj_pred(src_val);
1485 int const arity = get_Sync_n_preds(src_mem);
1490 NEW_ARR_A(ir_node*, ins, arity + 1);
1492 /* NOTE: This sometimes produces dead-code because the old sync in
1493 * src_mem might not be used anymore, we should detect this case
1494 * and kill the sync... */
1495 for (i = arity - 1; i >= 0; --i) {
1496 ir_node *const pred = get_Sync_pred(src_mem, i);
1498 /* avoid memory loop */
1499 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1502 ins[n++] = be_transform_node(pred);
1505 if (n==1 && ins[0] == am_mem) {
1507 /* creating a new Sync and relying on CSE may fail,
1508 * if am_mem is a ProjM, which does not yet verify. */
1512 return new_r_Sync(block, n, ins);
1516 ins[0] = be_transform_node(src_mem);
1518 return new_r_Sync(block, 2, ins);
1523 * Create a 32bit to 64bit signed extension.
1525 * @param dbgi debug info
1526 * @param block the block where node nodes should be placed
1527 * @param val the value to extend
1528 * @param orig the original node
1530 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1531 ir_node *val, const ir_node *orig)
1536 if (ia32_cg_config.use_short_sex_eax) {
1537 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1538 be_dep_on_frame(pval);
1539 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1541 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1542 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1544 SET_IA32_ORIG_NODE(res, orig);
1549 * Generates an ia32 Div with additional infrastructure for the
1550 * register allocator if needed.
1552 static ir_node *create_Div(ir_node *node)
1554 dbg_info *dbgi = get_irn_dbg_info(node);
1555 ir_node *block = get_nodes_block(node);
1556 ir_node *new_block = be_transform_node(block);
1563 ir_node *sign_extension;
1564 ia32_address_mode_t am;
1565 ia32_address_t *addr = &am.addr;
1567 /* the upper bits have random contents for smaller modes */
1568 switch (get_irn_opcode(node)) {
1570 op1 = get_Div_left(node);
1571 op2 = get_Div_right(node);
1572 mem = get_Div_mem(node);
1573 mode = get_Div_resmode(node);
1576 op1 = get_Mod_left(node);
1577 op2 = get_Mod_right(node);
1578 mem = get_Mod_mem(node);
1579 mode = get_Mod_resmode(node);
1582 panic("invalid divmod node %+F", node);
1585 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1587 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1588 is the memory of the consumed address. We can have only the second op as address
1589 in Div nodes, so check only op2. */
1590 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1592 if (mode_is_signed(mode)) {
1593 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1594 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1595 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1597 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1598 be_dep_on_frame(sign_extension);
1600 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1601 addr->index, new_mem, am.new_op2,
1602 am.new_op1, sign_extension);
1605 set_irn_pinned(new_node, get_irn_pinned(node));
1607 set_am_attributes(new_node, &am);
1608 SET_IA32_ORIG_NODE(new_node, node);
1610 new_node = fix_mem_proj(new_node, &am);
1616 * Generates an ia32 Mod.
1618 static ir_node *gen_Mod(ir_node *node)
1620 return create_Div(node);
1624 * Generates an ia32 Div.
1626 static ir_node *gen_Div(ir_node *node)
1628 ir_mode *mode = get_Div_resmode(node);
1629 if (mode_is_float(mode)) {
1630 ir_node *op1 = get_Div_left(node);
1631 ir_node *op2 = get_Div_right(node);
1633 if (ia32_cg_config.use_sse2) {
1634 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1636 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1640 return create_Div(node);
1644 * Creates an ia32 Shl.
1646 * @return The created ia32 Shl node
1648 static ir_node *gen_Shl(ir_node *node)
1650 ir_node *left = get_Shl_left(node);
1651 ir_node *right = get_Shl_right(node);
1653 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1654 match_mode_neutral | match_immediate);
1658 * Creates an ia32 Shr.
1660 * @return The created ia32 Shr node
1662 static ir_node *gen_Shr(ir_node *node)
1664 ir_node *left = get_Shr_left(node);
1665 ir_node *right = get_Shr_right(node);
1667 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1673 * Creates an ia32 Sar.
1675 * @return The created ia32 Shrs node
1677 static ir_node *gen_Shrs(ir_node *node)
1679 ir_node *left = get_Shrs_left(node);
1680 ir_node *right = get_Shrs_right(node);
1682 if (is_Const(right)) {
1683 ir_tarval *tv = get_Const_tarval(right);
1684 long val = get_tarval_long(tv);
1686 /* this is a sign extension */
1687 dbg_info *dbgi = get_irn_dbg_info(node);
1688 ir_node *block = be_transform_node(get_nodes_block(node));
1689 ir_node *new_op = be_transform_node(left);
1691 return create_sex_32_64(dbgi, block, new_op, node);
1695 /* 8 or 16 bit sign extension? */
1696 if (is_Const(right) && is_Shl(left)) {
1697 ir_node *shl_left = get_Shl_left(left);
1698 ir_node *shl_right = get_Shl_right(left);
1699 if (is_Const(shl_right)) {
1700 ir_tarval *tv1 = get_Const_tarval(right);
1701 ir_tarval *tv2 = get_Const_tarval(shl_right);
1702 if (tv1 == tv2 && tarval_is_long(tv1)) {
1703 long val = get_tarval_long(tv1);
1704 if (val == 16 || val == 24) {
1705 dbg_info *dbgi = get_irn_dbg_info(node);
1706 ir_node *block = get_nodes_block(node);
1716 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1725 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1731 * Creates an ia32 Rol.
1733 * @param op1 The first operator
1734 * @param op2 The second operator
1735 * @return The created ia32 RotL node
1737 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1739 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1745 * Creates an ia32 Ror.
1746 * NOTE: There is no RotR with immediate because this would always be a RotL
1747 * "imm-mode_size_bits" which can be pre-calculated.
1749 * @param op1 The first operator
1750 * @param op2 The second operator
1751 * @return The created ia32 RotR node
1753 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1755 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1761 * Creates an ia32 RotR or RotL (depending on the found pattern).
1763 * @return The created ia32 RotL or RotR node
1765 static ir_node *gen_Rotl(ir_node *node)
1767 ir_node *op1 = get_Rotl_left(node);
1768 ir_node *op2 = get_Rotl_right(node);
1770 if (is_Minus(op2)) {
1771 return gen_Ror(node, op1, get_Minus_op(op2));
1774 return gen_Rol(node, op1, op2);
1780 * Transforms a Minus node.
1782 * @return The created ia32 Minus node
1784 static ir_node *gen_Minus(ir_node *node)
1786 ir_node *op = get_Minus_op(node);
1787 ir_node *block = be_transform_node(get_nodes_block(node));
1788 dbg_info *dbgi = get_irn_dbg_info(node);
1789 ir_mode *mode = get_irn_mode(node);
1794 if (mode_is_float(mode)) {
1795 ir_node *new_op = be_transform_node(op);
1796 if (ia32_cg_config.use_sse2) {
1797 /* TODO: non-optimal... if we have many xXors, then we should
1798 * rather create a load for the const and use that instead of
1799 * several AM nodes... */
1800 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1802 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1803 noreg_GP, nomem, new_op, noreg_xmm);
1805 size = get_mode_size_bits(mode);
1806 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1808 set_ia32_am_sc(new_node, ent);
1809 set_ia32_op_type(new_node, ia32_AddrModeS);
1810 set_ia32_ls_mode(new_node, mode);
1812 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1815 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1818 SET_IA32_ORIG_NODE(new_node, node);
1824 * Transforms a Not node.
1826 * @return The created ia32 Not node
1828 static ir_node *gen_Not(ir_node *node)
1830 ir_node *op = get_Not_op(node);
1832 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1833 assert (! mode_is_float(get_irn_mode(node)));
1835 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1838 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1839 bool negate, ir_node *node)
1841 ir_node *new_block = be_transform_node(block);
1842 ir_mode *mode = get_irn_mode(op);
1848 if (mode_is_float(mode)) {
1849 new_op = be_transform_node(op);
1851 if (ia32_cg_config.use_sse2) {
1852 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1853 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1854 noreg_GP, nomem, new_op, noreg_fp);
1856 size = get_mode_size_bits(mode);
1857 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1859 set_ia32_am_sc(new_node, ent);
1861 SET_IA32_ORIG_NODE(new_node, node);
1863 set_ia32_op_type(new_node, ia32_AddrModeS);
1864 set_ia32_ls_mode(new_node, mode);
1866 /* TODO, implement -Abs case */
1869 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1870 SET_IA32_ORIG_NODE(new_node, node);
1872 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1873 SET_IA32_ORIG_NODE(new_node, node);
1878 ir_node *sign_extension;
1880 if (get_mode_size_bits(mode) == 32) {
1881 new_op = be_transform_node(op);
1883 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1886 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1888 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1889 nomem, new_op, sign_extension);
1890 SET_IA32_ORIG_NODE(xorn, node);
1893 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1894 nomem, sign_extension, xorn);
1896 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1897 nomem, xorn, sign_extension);
1899 SET_IA32_ORIG_NODE(new_node, node);
1906 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1908 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1910 dbg_info *dbgi = get_irn_dbg_info(cmp);
1911 ir_node *block = get_nodes_block(cmp);
1912 ir_node *new_block = be_transform_node(block);
1913 ir_node *op1 = be_transform_node(x);
1914 ir_node *op2 = be_transform_node(n);
1916 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1919 static ia32_condition_code_t pnc_to_condition_code(pn_Cmp pnc, ir_mode *mode)
1921 if (mode_is_float(mode)) {
1923 case pn_Cmp_Eq: return ia32_cc_float_equal;
1924 case pn_Cmp_Lt: return ia32_cc_float_below;
1925 case pn_Cmp_Le: return ia32_cc_float_below_equal;
1926 case pn_Cmp_Gt: return ia32_cc_float_above;
1927 case pn_Cmp_Ge: return ia32_cc_float_above_equal;
1928 case pn_Cmp_Lg: return ia32_cc_not_equal;
1929 case pn_Cmp_Leg: return ia32_cc_not_parity;
1930 case pn_Cmp_Uo: return ia32_cc_parity;
1931 case pn_Cmp_Ue: return ia32_cc_equal;
1932 case pn_Cmp_Ul: return ia32_cc_float_unordered_below;
1933 case pn_Cmp_Ule: return ia32_cc_float_unordered_below_equal;
1934 case pn_Cmp_Ug: return ia32_cc_float_unordered_above;
1935 case pn_Cmp_Uge: return ia32_cc_float_unordered_above_equal;
1936 case pn_Cmp_Ne: return ia32_cc_float_not_equal;
1940 /* should we introduce a jump always/jump never? */
1943 panic("Unexpected float pnc");
1944 } else if (mode_is_signed(mode)) {
1947 case pn_Cmp_Eq: return ia32_cc_equal;
1949 case pn_Cmp_Lt: return ia32_cc_less;
1951 case pn_Cmp_Le: return ia32_cc_less_equal;
1953 case pn_Cmp_Gt: return ia32_cc_greater;
1955 case pn_Cmp_Ge: return ia32_cc_greater_equal;
1957 case pn_Cmp_Ne: return ia32_cc_not_equal;
1963 /* introduce jump always/jump never? */
1966 panic("Unexpected pnc");
1970 case pn_Cmp_Eq: return ia32_cc_equal;
1972 case pn_Cmp_Lt: return ia32_cc_below;
1974 case pn_Cmp_Le: return ia32_cc_below_equal;
1976 case pn_Cmp_Gt: return ia32_cc_above;
1978 case pn_Cmp_Ge: return ia32_cc_above_equal;
1980 case pn_Cmp_Ne: return ia32_cc_not_equal;
1986 /* introduce jump always/jump never? */
1989 panic("Unexpected pnc");
1993 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
1995 /* a mode_b value, we have to compare it against 0 */
1996 dbg_info *dbgi = get_irn_dbg_info(node);
1997 ir_node *new_block = be_transform_node(get_nodes_block(node));
1998 ir_node *new_op = be_transform_node(node);
1999 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2000 *cc_out = ia32_cc_not_equal;
2004 static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out)
2006 /* must have a Proj(Cmp) as input */
2007 ir_node *cmp = get_Proj_pred(node);
2008 int pnc = get_Proj_pn_cmp(node);
2009 ir_node *l = get_Cmp_left(cmp);
2010 ir_mode *mode = get_irn_mode(l);
2013 /* check for bit-test */
2014 if (ia32_cg_config.use_bt
2015 && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq || pnc == pn_Cmp_Ne
2016 || pnc == pn_Cmp_Ue)) {
2017 ir_node *l = get_Cmp_left(cmp);
2018 ir_node *r = get_Cmp_right(cmp);
2020 ir_node *la = get_And_left(l);
2021 ir_node *ra = get_And_right(l);
2028 ir_node *c = get_Shl_left(la);
2029 if (is_Const_1(c) && is_Const_0(r)) {
2030 /* (1 << n) & ra) */
2031 ir_node *n = get_Shl_right(la);
2032 flags = gen_bt(cmp, ra, n);
2033 /* the bit is copied into the CF flag */
2034 if (pnc & pn_Cmp_Eq)
2035 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2037 *cc_out = ia32_cc_below; /* test for CF=1 */
2044 /* just do a normal transformation of the Cmp */
2045 *cc_out = pnc_to_condition_code(pnc, mode);
2046 flags = be_transform_node(cmp);
2051 * Transform a node returning a "flag" result.
2053 * @param node the node to transform
2054 * @param cc_out the compare mode to use
2056 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2058 if (is_Proj(node) && is_Cmp(get_Proj_pred(node)))
2059 return get_flags_node_cmp(node, cc_out);
2060 assert(get_irn_mode(node) == mode_b);
2061 return get_flags_mode_b(node, cc_out);
2065 * Transforms a Load.
2067 * @return the created ia32 Load node
2069 static ir_node *gen_Load(ir_node *node)
2071 ir_node *old_block = get_nodes_block(node);
2072 ir_node *block = be_transform_node(old_block);
2073 ir_node *ptr = get_Load_ptr(node);
2074 ir_node *mem = get_Load_mem(node);
2075 ir_node *new_mem = be_transform_node(mem);
2078 dbg_info *dbgi = get_irn_dbg_info(node);
2079 ir_mode *mode = get_Load_mode(node);
2081 ia32_address_t addr;
2083 /* construct load address */
2084 memset(&addr, 0, sizeof(addr));
2085 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2092 base = be_transform_node(base);
2095 if (index == NULL) {
2098 index = be_transform_node(index);
2101 if (mode_is_float(mode)) {
2102 if (ia32_cg_config.use_sse2) {
2103 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2106 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2110 assert(mode != mode_b);
2112 /* create a conv node with address mode for smaller modes */
2113 if (get_mode_size_bits(mode) < 32) {
2114 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2115 new_mem, noreg_GP, mode);
2117 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2121 set_irn_pinned(new_node, get_irn_pinned(node));
2122 set_ia32_op_type(new_node, ia32_AddrModeS);
2123 set_ia32_ls_mode(new_node, mode);
2124 set_address(new_node, &addr);
2126 if (get_irn_pinned(node) == op_pin_state_floats) {
2127 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2128 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2129 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2130 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2133 SET_IA32_ORIG_NODE(new_node, node);
2135 be_dep_on_frame(new_node);
2139 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2140 ir_node *ptr, ir_node *other)
2147 /* we only use address mode if we're the only user of the load */
2148 if (get_irn_n_edges(node) > 1)
2151 load = get_Proj_pred(node);
2154 if (get_nodes_block(load) != block)
2157 /* store should have the same pointer as the load */
2158 if (get_Load_ptr(load) != ptr)
2161 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2162 if (other != NULL &&
2163 get_nodes_block(other) == block &&
2164 heights_reachable_in_block(ia32_heights, other, load)) {
2168 if (ia32_prevents_AM(block, load, mem))
2170 /* Store should be attached to the load via mem */
2171 assert(heights_reachable_in_block(ia32_heights, mem, load));
2176 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2177 ir_node *mem, ir_node *ptr, ir_mode *mode,
2178 construct_binop_dest_func *func,
2179 construct_binop_dest_func *func8bit,
2180 match_flags_t flags)
2182 ir_node *src_block = get_nodes_block(node);
2190 ia32_address_mode_t am;
2191 ia32_address_t *addr = &am.addr;
2192 memset(&am, 0, sizeof(am));
2194 assert(flags & match_immediate); /* there is no destam node without... */
2195 commutative = (flags & match_commutative) != 0;
2197 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2198 build_address(&am, op1, ia32_create_am_double_use);
2199 new_op = create_immediate_or_transform(op2, 0);
2200 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2201 build_address(&am, op2, ia32_create_am_double_use);
2202 new_op = create_immediate_or_transform(op1, 0);
2207 if (addr->base == NULL)
2208 addr->base = noreg_GP;
2209 if (addr->index == NULL)
2210 addr->index = noreg_GP;
2211 if (addr->mem == NULL)
2214 dbgi = get_irn_dbg_info(node);
2215 block = be_transform_node(src_block);
2216 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2218 if (get_mode_size_bits(mode) == 8) {
2219 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2221 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2223 set_address(new_node, addr);
2224 set_ia32_op_type(new_node, ia32_AddrModeD);
2225 set_ia32_ls_mode(new_node, mode);
2226 SET_IA32_ORIG_NODE(new_node, node);
2228 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2229 mem_proj = be_transform_node(am.mem_proj);
2230 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2235 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2236 ir_node *ptr, ir_mode *mode,
2237 construct_unop_dest_func *func)
2239 ir_node *src_block = get_nodes_block(node);
2245 ia32_address_mode_t am;
2246 ia32_address_t *addr = &am.addr;
2248 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2251 memset(&am, 0, sizeof(am));
2252 build_address(&am, op, ia32_create_am_double_use);
2254 dbgi = get_irn_dbg_info(node);
2255 block = be_transform_node(src_block);
2256 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2257 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2258 set_address(new_node, addr);
2259 set_ia32_op_type(new_node, ia32_AddrModeD);
2260 set_ia32_ls_mode(new_node, mode);
2261 SET_IA32_ORIG_NODE(new_node, node);
2263 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2264 mem_proj = be_transform_node(am.mem_proj);
2265 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2270 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2272 ir_mode *mode = get_irn_mode(node);
2273 ir_node *mux_true = get_Mux_true(node);
2274 ir_node *mux_false = get_Mux_false(node);
2282 ia32_condition_code_t cc;
2283 ia32_address_t addr;
2285 if (get_mode_size_bits(mode) != 8)
2288 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2290 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2296 cond = get_Mux_sel(node);
2297 flags = get_flags_node(cond, &cc);
2298 /* we can't handle the float special cases with SetM */
2299 if (cc & ia32_cc_additional_float_cases)
2302 cc = ia32_negate_condition_code(cc);
2304 build_address_ptr(&addr, ptr, mem);
2306 dbgi = get_irn_dbg_info(node);
2307 block = get_nodes_block(node);
2308 new_block = be_transform_node(block);
2309 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2310 addr.index, addr.mem, flags, cc);
2311 set_address(new_node, &addr);
2312 set_ia32_op_type(new_node, ia32_AddrModeD);
2313 set_ia32_ls_mode(new_node, mode);
2314 SET_IA32_ORIG_NODE(new_node, node);
2319 static ir_node *try_create_dest_am(ir_node *node)
2321 ir_node *val = get_Store_value(node);
2322 ir_node *mem = get_Store_mem(node);
2323 ir_node *ptr = get_Store_ptr(node);
2324 ir_mode *mode = get_irn_mode(val);
2325 unsigned bits = get_mode_size_bits(mode);
2330 /* handle only GP modes for now... */
2331 if (!ia32_mode_needs_gp_reg(mode))
2335 /* store must be the only user of the val node */
2336 if (get_irn_n_edges(val) > 1)
2338 /* skip pointless convs */
2340 ir_node *conv_op = get_Conv_op(val);
2341 ir_mode *pred_mode = get_irn_mode(conv_op);
2342 if (!ia32_mode_needs_gp_reg(pred_mode))
2344 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2352 /* value must be in the same block */
2353 if (get_nodes_block(node) != get_nodes_block(val))
2356 switch (get_irn_opcode(val)) {
2358 op1 = get_Add_left(val);
2359 op2 = get_Add_right(val);
2360 if (ia32_cg_config.use_incdec) {
2361 if (is_Const_1(op2)) {
2362 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2364 } else if (is_Const_Minus_1(op2)) {
2365 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2369 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2370 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2371 match_commutative | match_immediate);
2374 op1 = get_Sub_left(val);
2375 op2 = get_Sub_right(val);
2376 if (is_Const(op2)) {
2377 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2379 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2380 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2384 op1 = get_And_left(val);
2385 op2 = get_And_right(val);
2386 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2387 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2388 match_commutative | match_immediate);
2391 op1 = get_Or_left(val);
2392 op2 = get_Or_right(val);
2393 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2394 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2395 match_commutative | match_immediate);
2398 op1 = get_Eor_left(val);
2399 op2 = get_Eor_right(val);
2400 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2401 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2402 match_commutative | match_immediate);
2405 op1 = get_Shl_left(val);
2406 op2 = get_Shl_right(val);
2407 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2408 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2412 op1 = get_Shr_left(val);
2413 op2 = get_Shr_right(val);
2414 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2415 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2419 op1 = get_Shrs_left(val);
2420 op2 = get_Shrs_right(val);
2421 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2422 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2426 op1 = get_Rotl_left(val);
2427 op2 = get_Rotl_right(val);
2428 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2429 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2432 /* TODO: match ROR patterns... */
2434 new_node = try_create_SetMem(val, ptr, mem);
2438 op1 = get_Minus_op(val);
2439 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2442 /* should be lowered already */
2443 assert(mode != mode_b);
2444 op1 = get_Not_op(val);
2445 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2451 if (new_node != NULL) {
2452 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2453 get_irn_pinned(node) == op_pin_state_pinned) {
2454 set_irn_pinned(new_node, op_pin_state_pinned);
2461 static bool possible_int_mode_for_fp(ir_mode *mode)
2465 if (!mode_is_signed(mode))
2467 size = get_mode_size_bits(mode);
2468 if (size != 16 && size != 32)
2473 static int is_float_to_int_conv(const ir_node *node)
2475 ir_mode *mode = get_irn_mode(node);
2479 if (!possible_int_mode_for_fp(mode))
2484 conv_op = get_Conv_op(node);
2485 conv_mode = get_irn_mode(conv_op);
2487 if (!mode_is_float(conv_mode))
2494 * Transform a Store(floatConst) into a sequence of
2497 * @return the created ia32 Store node
2499 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2501 ir_mode *mode = get_irn_mode(cns);
2502 unsigned size = get_mode_size_bytes(mode);
2503 ir_tarval *tv = get_Const_tarval(cns);
2504 ir_node *block = get_nodes_block(node);
2505 ir_node *new_block = be_transform_node(block);
2506 ir_node *ptr = get_Store_ptr(node);
2507 ir_node *mem = get_Store_mem(node);
2508 dbg_info *dbgi = get_irn_dbg_info(node);
2512 ia32_address_t addr;
2514 assert(size % 4 == 0);
2517 build_address_ptr(&addr, ptr, mem);
2521 get_tarval_sub_bits(tv, ofs) |
2522 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2523 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2524 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2525 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2527 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2528 addr.index, addr.mem, imm);
2530 set_irn_pinned(new_node, get_irn_pinned(node));
2531 set_ia32_op_type(new_node, ia32_AddrModeD);
2532 set_ia32_ls_mode(new_node, mode_Iu);
2533 set_address(new_node, &addr);
2534 SET_IA32_ORIG_NODE(new_node, node);
2537 ins[i++] = new_node;
2542 } while (size != 0);
2545 return new_rd_Sync(dbgi, new_block, i, ins);
2552 * Generate a vfist or vfisttp instruction.
2554 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2555 ir_node *mem, ir_node *val, ir_node **fist)
2559 if (ia32_cg_config.use_fisttp) {
2560 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2561 if other users exists */
2562 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2563 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2564 be_new_Keep(block, 1, &value);
2566 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2569 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2572 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2578 * Transforms a general (no special case) Store.
2580 * @return the created ia32 Store node
2582 static ir_node *gen_general_Store(ir_node *node)
2584 ir_node *val = get_Store_value(node);
2585 ir_mode *mode = get_irn_mode(val);
2586 ir_node *block = get_nodes_block(node);
2587 ir_node *new_block = be_transform_node(block);
2588 ir_node *ptr = get_Store_ptr(node);
2589 ir_node *mem = get_Store_mem(node);
2590 dbg_info *dbgi = get_irn_dbg_info(node);
2591 ir_node *new_val, *new_node, *store;
2592 ia32_address_t addr;
2594 /* check for destination address mode */
2595 new_node = try_create_dest_am(node);
2596 if (new_node != NULL)
2599 /* construct store address */
2600 memset(&addr, 0, sizeof(addr));
2601 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2603 if (addr.base == NULL) {
2604 addr.base = noreg_GP;
2606 addr.base = be_transform_node(addr.base);
2609 if (addr.index == NULL) {
2610 addr.index = noreg_GP;
2612 addr.index = be_transform_node(addr.index);
2614 addr.mem = be_transform_node(mem);
2616 if (mode_is_float(mode)) {
2617 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2619 while (is_Conv(val) && mode == get_irn_mode(val)) {
2620 ir_node *op = get_Conv_op(val);
2621 if (!mode_is_float(get_irn_mode(op)))
2625 new_val = be_transform_node(val);
2626 if (ia32_cg_config.use_sse2) {
2627 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2628 addr.index, addr.mem, new_val);
2630 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2631 addr.index, addr.mem, new_val, mode);
2634 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2635 val = get_Conv_op(val);
2637 /* TODO: is this optimisation still necessary at all (middleend)? */
2638 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2639 while (is_Conv(val)) {
2640 ir_node *op = get_Conv_op(val);
2641 if (!mode_is_float(get_irn_mode(op)))
2643 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2647 new_val = be_transform_node(val);
2648 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2650 new_val = create_immediate_or_transform(val, 0);
2651 assert(mode != mode_b);
2653 if (get_mode_size_bits(mode) == 8) {
2654 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2655 addr.index, addr.mem, new_val);
2657 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2658 addr.index, addr.mem, new_val);
2663 set_irn_pinned(store, get_irn_pinned(node));
2664 set_ia32_op_type(store, ia32_AddrModeD);
2665 set_ia32_ls_mode(store, mode);
2667 set_address(store, &addr);
2668 SET_IA32_ORIG_NODE(store, node);
2674 * Transforms a Store.
2676 * @return the created ia32 Store node
2678 static ir_node *gen_Store(ir_node *node)
2680 ir_node *val = get_Store_value(node);
2681 ir_mode *mode = get_irn_mode(val);
2683 if (mode_is_float(mode) && is_Const(val)) {
2684 /* We can transform every floating const store
2685 into a sequence of integer stores.
2686 If the constant is already in a register,
2687 it would be better to use it, but we don't
2688 have this information here. */
2689 return gen_float_const_Store(node, val);
2691 return gen_general_Store(node);
2695 * Transforms a Switch.
2697 * @return the created ia32 SwitchJmp node
2699 static ir_node *create_Switch(ir_node *node)
2701 dbg_info *dbgi = get_irn_dbg_info(node);
2702 ir_node *block = be_transform_node(get_nodes_block(node));
2703 ir_node *sel = get_Cond_selector(node);
2704 ir_node *new_sel = be_transform_node(sel);
2705 long switch_min = LONG_MAX;
2706 long switch_max = LONG_MIN;
2707 long default_pn = get_Cond_default_proj(node);
2709 const ir_edge_t *edge;
2711 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2713 /* determine the smallest switch case value */
2714 foreach_out_edge(node, edge) {
2715 ir_node *proj = get_edge_src_irn(edge);
2716 long pn = get_Proj_proj(proj);
2717 if (pn == default_pn)
2720 if (pn < switch_min)
2722 if (pn > switch_max)
2726 if ((unsigned long) (switch_max - switch_min) > 128000) {
2727 panic("Size of switch %+F bigger than 128000", node);
2730 if (switch_min != 0) {
2731 /* if smallest switch case is not 0 we need an additional sub */
2732 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2733 add_ia32_am_offs_int(new_sel, -switch_min);
2734 set_ia32_op_type(new_sel, ia32_AddrModeS);
2736 SET_IA32_ORIG_NODE(new_sel, node);
2739 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2740 SET_IA32_ORIG_NODE(new_node, node);
2746 * Transform a Cond node.
2748 static ir_node *gen_Cond(ir_node *node)
2750 ir_node *block = get_nodes_block(node);
2751 ir_node *new_block = be_transform_node(block);
2752 dbg_info *dbgi = get_irn_dbg_info(node);
2753 ir_node *sel = get_Cond_selector(node);
2754 ir_mode *sel_mode = get_irn_mode(sel);
2755 ir_node *flags = NULL;
2757 ia32_condition_code_t cc;
2759 if (sel_mode != mode_b) {
2760 return create_Switch(node);
2763 /* we get flags from a Cmp */
2764 flags = get_flags_node(sel, &cc);
2766 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2767 SET_IA32_ORIG_NODE(new_node, node);
2773 * Transform a be_Copy.
2775 static ir_node *gen_be_Copy(ir_node *node)
2777 ir_node *new_node = be_duplicate_node(node);
2778 ir_mode *mode = get_irn_mode(new_node);
2780 if (ia32_mode_needs_gp_reg(mode)) {
2781 set_irn_mode(new_node, mode_Iu);
2787 static ir_node *create_Fucom(ir_node *node)
2789 dbg_info *dbgi = get_irn_dbg_info(node);
2790 ir_node *block = get_nodes_block(node);
2791 ir_node *new_block = be_transform_node(block);
2792 ir_node *left = get_Cmp_left(node);
2793 ir_node *new_left = be_transform_node(left);
2794 ir_node *right = get_Cmp_right(node);
2798 if (ia32_cg_config.use_fucomi) {
2799 new_right = be_transform_node(right);
2800 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2802 set_ia32_commutative(new_node);
2803 SET_IA32_ORIG_NODE(new_node, node);
2805 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2806 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2808 new_right = be_transform_node(right);
2809 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2812 set_ia32_commutative(new_node);
2814 SET_IA32_ORIG_NODE(new_node, node);
2816 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2817 SET_IA32_ORIG_NODE(new_node, node);
2823 static ir_node *create_Ucomi(ir_node *node)
2825 dbg_info *dbgi = get_irn_dbg_info(node);
2826 ir_node *src_block = get_nodes_block(node);
2827 ir_node *new_block = be_transform_node(src_block);
2828 ir_node *left = get_Cmp_left(node);
2829 ir_node *right = get_Cmp_right(node);
2831 ia32_address_mode_t am;
2832 ia32_address_t *addr = &am.addr;
2834 match_arguments(&am, src_block, left, right, NULL,
2835 match_commutative | match_am);
2837 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2838 addr->mem, am.new_op1, am.new_op2,
2840 set_am_attributes(new_node, &am);
2842 SET_IA32_ORIG_NODE(new_node, node);
2844 new_node = fix_mem_proj(new_node, &am);
2850 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2851 * to fold an and into a test node
2853 static bool can_fold_test_and(ir_node *node)
2855 const ir_edge_t *edge;
2857 /** we can only have eq and lg projs */
2858 foreach_out_edge(node, edge) {
2859 ir_node *proj = get_edge_src_irn(edge);
2860 pn_Cmp pnc = get_Proj_pn_cmp(proj);
2861 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2869 * returns true if it is assured, that the upper bits of a node are "clean"
2870 * which means for a 16 or 8 bit value, that the upper bits in the register
2871 * are 0 for unsigned and a copy of the last significant bit for signed
2874 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2876 assert(ia32_mode_needs_gp_reg(mode));
2877 if (get_mode_size_bits(mode) >= 32)
2880 if (is_Proj(transformed_node))
2881 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2883 switch (get_ia32_irn_opcode(transformed_node)) {
2884 case iro_ia32_Conv_I2I:
2885 case iro_ia32_Conv_I2I8Bit: {
2886 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2887 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2889 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2896 if (mode_is_signed(mode)) {
2897 return false; /* TODO handle signed modes */
2899 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2900 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2901 const ia32_immediate_attr_t *attr
2902 = get_ia32_immediate_attr_const(right);
2903 if (attr->symconst == 0 &&
2904 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2908 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2912 /* TODO too conservative if shift amount is constant */
2913 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2916 if (!mode_is_signed(mode)) {
2918 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2919 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2921 /* TODO if one is known to be zero extended, then || is sufficient */
2926 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2927 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2929 case iro_ia32_Const:
2930 case iro_ia32_Immediate: {
2931 const ia32_immediate_attr_t *attr =
2932 get_ia32_immediate_attr_const(transformed_node);
2933 if (mode_is_signed(mode)) {
2934 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2935 return shifted == 0 || shifted == -1;
2937 unsigned long shifted = (unsigned long)attr->offset;
2938 shifted >>= get_mode_size_bits(mode);
2939 return shifted == 0;
2949 * Generate code for a Cmp.
2951 static ir_node *gen_Cmp(ir_node *node)
2953 dbg_info *dbgi = get_irn_dbg_info(node);
2954 ir_node *block = get_nodes_block(node);
2955 ir_node *new_block = be_transform_node(block);
2956 ir_node *left = get_Cmp_left(node);
2957 ir_node *right = get_Cmp_right(node);
2958 ir_mode *cmp_mode = get_irn_mode(left);
2960 ia32_address_mode_t am;
2961 ia32_address_t *addr = &am.addr;
2963 if (mode_is_float(cmp_mode)) {
2964 if (ia32_cg_config.use_sse2) {
2965 return create_Ucomi(node);
2967 return create_Fucom(node);
2971 assert(ia32_mode_needs_gp_reg(cmp_mode));
2973 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2974 if (is_Const_0(right) &&
2976 get_irn_n_edges(left) == 1 &&
2977 can_fold_test_and(node)) {
2978 /* Test(and_left, and_right) */
2979 ir_node *and_left = get_And_left(left);
2980 ir_node *and_right = get_And_right(left);
2982 /* matze: code here used mode instead of cmd_mode, I think it is always
2983 * the same as cmp_mode, but I leave this here to see if this is really
2986 assert(get_irn_mode(and_left) == cmp_mode);
2988 match_arguments(&am, block, and_left, and_right, NULL,
2990 match_am | match_8bit_am | match_16bit_am |
2991 match_am_and_immediates | match_immediate);
2993 /* use 32bit compare mode if possible since the opcode is smaller */
2994 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2995 upper_bits_clean(am.new_op2, cmp_mode)) {
2996 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2999 if (get_mode_size_bits(cmp_mode) == 8) {
3000 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3001 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3003 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3004 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3007 /* Cmp(left, right) */
3008 match_arguments(&am, block, left, right, NULL,
3009 match_commutative | match_am | match_8bit_am |
3010 match_16bit_am | match_am_and_immediates |
3012 /* use 32bit compare mode if possible since the opcode is smaller */
3013 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3014 upper_bits_clean(am.new_op2, cmp_mode)) {
3015 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3018 if (get_mode_size_bits(cmp_mode) == 8) {
3019 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3020 addr->index, addr->mem, am.new_op1,
3021 am.new_op2, am.ins_permuted);
3023 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3024 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3027 set_am_attributes(new_node, &am);
3028 set_ia32_ls_mode(new_node, cmp_mode);
3030 SET_IA32_ORIG_NODE(new_node, node);
3032 new_node = fix_mem_proj(new_node, &am);
3037 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3038 ia32_condition_code_t cc)
3040 dbg_info *dbgi = get_irn_dbg_info(node);
3041 ir_node *block = get_nodes_block(node);
3042 ir_node *new_block = be_transform_node(block);
3043 ir_node *val_true = get_Mux_true(node);
3044 ir_node *val_false = get_Mux_false(node);
3046 ia32_address_mode_t am;
3047 ia32_address_t *addr;
3049 assert(ia32_cg_config.use_cmov);
3050 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3054 match_arguments(&am, block, val_false, val_true, flags,
3055 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3057 if (am.ins_permuted)
3058 cc = ia32_invert_condition_code(cc);
3060 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3061 addr->mem, am.new_op1, am.new_op2, new_flags,
3063 set_am_attributes(new_node, &am);
3065 SET_IA32_ORIG_NODE(new_node, node);
3067 new_node = fix_mem_proj(new_node, &am);
3073 * Creates a ia32 Setcc instruction.
3075 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3076 ir_node *flags, ia32_condition_code_t cc,
3079 ir_mode *mode = get_irn_mode(orig_node);
3082 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3083 SET_IA32_ORIG_NODE(new_node, orig_node);
3085 /* we might need to conv the result up */
3086 if (get_mode_size_bits(mode) > 8) {
3087 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3088 nomem, new_node, mode_Bu);
3089 SET_IA32_ORIG_NODE(new_node, orig_node);
3096 * Create instruction for an unsigned Difference or Zero.
3098 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3100 ir_mode *mode = get_irn_mode(psi);
3110 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3111 match_mode_neutral | match_am | match_immediate | match_two_users);
3113 block = get_nodes_block(new_node);
3115 if (is_Proj(new_node)) {
3116 sub = get_Proj_pred(new_node);
3117 assert(is_ia32_Sub(sub));
3120 set_irn_mode(sub, mode_T);
3121 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3123 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3125 dbgi = get_irn_dbg_info(psi);
3126 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3127 notn = new_bd_ia32_Not(dbgi, block, sbb);
3129 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3130 set_ia32_commutative(new_node);
3135 * Create an const array of two float consts.
3137 * @param c0 the first constant
3138 * @param c1 the second constant
3139 * @param new_mode IN/OUT for the mode of the constants, if NULL
3140 * smallest possible mode will be used
3142 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3145 ir_mode *mode = *new_mode;
3147 ir_initializer_t *initializer;
3148 ir_tarval *tv0 = get_Const_tarval(c0);
3149 ir_tarval *tv1 = get_Const_tarval(c1);
3152 /* detect the best mode for the constants */
3153 mode = get_tarval_mode(tv0);
3155 if (mode != mode_F) {
3156 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3157 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3159 tv0 = tarval_convert_to(tv0, mode);
3160 tv1 = tarval_convert_to(tv1, mode);
3161 } else if (mode != mode_D) {
3162 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3163 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3165 tv0 = tarval_convert_to(tv0, mode);
3166 tv1 = tarval_convert_to(tv1, mode);
3173 tp = ia32_create_float_type(mode, 4);
3174 tp = ia32_create_float_array(tp);
3176 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3178 set_entity_ld_ident(ent, get_entity_ident(ent));
3179 set_entity_visibility(ent, ir_visibility_private);
3180 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3182 initializer = create_initializer_compound(2);
3184 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3185 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3187 set_entity_initializer(ent, initializer);
3194 * Possible transformations for creating a Setcc.
3196 enum setcc_transform_insn {
3209 typedef struct setcc_transform {
3211 ia32_condition_code_t cc;
3213 enum setcc_transform_insn transform;
3217 } setcc_transform_t;
3220 * Setcc can only handle 0 and 1 result.
3221 * Find a transformation that creates 0 and 1 from
3224 static void find_const_transform(ia32_condition_code_t cc,
3225 ir_tarval *t, ir_tarval *f,
3226 setcc_transform_t *res)
3232 if (tarval_is_null(t)) {
3236 cc = ia32_negate_condition_code(cc);
3237 } else if (tarval_cmp(t, f) == pn_Cmp_Lt) {
3238 // now, t is the bigger one
3242 cc = ia32_negate_condition_code(cc);
3246 if (! tarval_is_null(f)) {
3247 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3250 res->steps[step].transform = SETCC_TR_ADD;
3252 if (t == tarval_bad)
3253 panic("constant subtract failed");
3254 if (! tarval_is_long(f))
3255 panic("tarval is not long");
3257 res->steps[step].val = get_tarval_long(f);
3259 f = tarval_sub(f, f, NULL);
3260 assert(tarval_is_null(f));
3263 if (tarval_is_one(t)) {
3264 res->steps[step].transform = SETCC_TR_SET;
3265 res->num_steps = ++step;
3269 if (tarval_is_minus_one(t)) {
3270 res->steps[step].transform = SETCC_TR_NEG;
3272 res->steps[step].transform = SETCC_TR_SET;
3273 res->num_steps = ++step;
3276 if (tarval_is_long(t)) {
3277 long v = get_tarval_long(t);
3279 res->steps[step].val = 0;
3282 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3284 res->steps[step].transform = SETCC_TR_LEAxx;
3285 res->steps[step].scale = 3; /* (a << 3) + a */
3288 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3290 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3291 res->steps[step].scale = 3; /* (a << 3) */
3294 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3296 res->steps[step].transform = SETCC_TR_LEAxx;
3297 res->steps[step].scale = 2; /* (a << 2) + a */
3300 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3302 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3303 res->steps[step].scale = 2; /* (a << 2) */
3306 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3308 res->steps[step].transform = SETCC_TR_LEAxx;
3309 res->steps[step].scale = 1; /* (a << 1) + a */
3312 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3314 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3315 res->steps[step].scale = 1; /* (a << 1) */
3318 res->num_steps = step;
3321 if (! tarval_is_single_bit(t)) {
3322 res->steps[step].transform = SETCC_TR_AND;
3323 res->steps[step].val = v;
3325 res->steps[step].transform = SETCC_TR_NEG;
3327 int v = get_tarval_lowest_bit(t);
3330 res->steps[step].transform = SETCC_TR_SHL;
3331 res->steps[step].scale = v;
3335 res->steps[step].transform = SETCC_TR_SET;
3336 res->num_steps = ++step;
3339 panic("tarval is not long");
3343 * Transforms a Mux node into some code sequence.
3345 * @return The transformed node.
3347 static ir_node *gen_Mux(ir_node *node)
3349 dbg_info *dbgi = get_irn_dbg_info(node);
3350 ir_node *block = get_nodes_block(node);
3351 ir_node *new_block = be_transform_node(block);
3352 ir_node *mux_true = get_Mux_true(node);
3353 ir_node *mux_false = get_Mux_false(node);
3354 ir_node *cond = get_Mux_sel(node);
3355 ir_mode *mode = get_irn_mode(node);
3359 ia32_condition_code_t cc;
3361 assert(get_irn_mode(cond) == mode_b);
3363 is_abs = be_mux_is_abs(cond, mux_true, mux_false);
3365 return create_abs(dbgi, block, be_get_abs_op(cond), is_abs < 0, node);
3368 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3369 if (mode_is_float(mode)) {
3370 ir_node *cmp = get_Proj_pred(cond);
3371 ir_node *cmp_left = get_Cmp_left(cmp);
3372 ir_node *cmp_right = get_Cmp_right(cmp);
3373 int pnc = get_Proj_proj(cond);
3375 if (ia32_cg_config.use_sse2) {
3376 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3377 if (cmp_left == mux_true && cmp_right == mux_false) {
3378 /* Mux(a <= b, a, b) => MIN */
3379 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3380 match_commutative | match_am | match_two_users);
3381 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3382 /* Mux(a <= b, b, a) => MAX */
3383 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3384 match_commutative | match_am | match_two_users);
3386 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3387 if (cmp_left == mux_true && cmp_right == mux_false) {
3388 /* Mux(a >= b, a, b) => MAX */
3389 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3390 match_commutative | match_am | match_two_users);
3391 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3392 /* Mux(a >= b, b, a) => MIN */
3393 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3394 match_commutative | match_am | match_two_users);
3399 if (is_Const(mux_true) && is_Const(mux_false)) {
3400 ia32_address_mode_t am;
3405 flags = get_flags_node(cond, &cc);
3406 new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3408 if (ia32_cg_config.use_sse2) {
3409 /* cannot load from different mode on SSE */
3412 /* x87 can load any mode */
3416 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3418 switch (get_mode_size_bytes(new_mode)) {
3428 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3429 set_ia32_am_scale(new_node, 2);
3434 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3435 set_ia32_am_scale(new_node, 1);
3438 /* arg, shift 16 NOT supported */
3440 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node);
3443 panic("Unsupported constant size");
3446 am.ls_mode = new_mode;
3447 am.addr.base = get_symconst_base();
3448 am.addr.index = new_node;
3449 am.addr.mem = nomem;
3451 am.addr.scale = scale;
3452 am.addr.use_frame = 0;
3453 am.addr.frame_entity = NULL;
3454 am.addr.symconst_sign = 0;
3455 am.mem_proj = am.addr.mem;
3456 am.op_type = ia32_AddrModeS;
3459 am.pinned = op_pin_state_floats;
3461 am.ins_permuted = false;
3463 if (ia32_cg_config.use_sse2)
3464 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3466 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3467 set_am_attributes(load, &am);
3469 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3471 panic("cannot transform floating point Mux");
3474 assert(ia32_mode_needs_gp_reg(mode));
3476 if (is_Proj(cond)) {
3477 ir_node *cmp = get_Proj_pred(cond);
3479 ir_node *cmp_left = get_Cmp_left(cmp);
3480 ir_node *cmp_right = get_Cmp_right(cmp);
3481 ir_node *val_true = mux_true;
3482 ir_node *val_false = mux_false;
3483 int pnc = get_Proj_proj(cond);
3485 if (is_Const(val_true) && is_Const_null(val_true)) {
3486 ir_node *tmp = val_false;
3487 val_false = val_true;
3489 pnc = get_negated_pnc(pnc, get_irn_mode(cmp_left));
3491 if (is_Const_0(val_false) && is_Sub(val_true)) {
3492 if ((pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge)
3493 && get_Sub_left(val_true) == cmp_left
3494 && get_Sub_right(val_true) == cmp_right) {
3495 return create_doz(node, cmp_left, cmp_right);
3497 if ((pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le)
3498 && get_Sub_left(val_true) == cmp_right
3499 && get_Sub_right(val_true) == cmp_left) {
3500 return create_doz(node, cmp_right, cmp_left);
3506 flags = get_flags_node(cond, &cc);
3508 if (is_Const(mux_true) && is_Const(mux_false)) {
3509 /* both are const, good */
3510 ir_tarval *tv_true = get_Const_tarval(mux_true);
3511 ir_tarval *tv_false = get_Const_tarval(mux_false);
3512 setcc_transform_t res;
3515 find_const_transform(cc, tv_true, tv_false, &res);
3517 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3520 switch (res.steps[step].transform) {
3522 imm = ia32_immediate_from_long(res.steps[step].val);
3523 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3525 case SETCC_TR_ADDxx:
3526 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3529 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3530 set_ia32_am_scale(new_node, res.steps[step].scale);
3531 set_ia32_am_offs_int(new_node, res.steps[step].val);
3533 case SETCC_TR_LEAxx:
3534 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3535 set_ia32_am_scale(new_node, res.steps[step].scale);
3536 set_ia32_am_offs_int(new_node, res.steps[step].val);
3539 imm = ia32_immediate_from_long(res.steps[step].scale);
3540 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3543 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3546 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3549 imm = ia32_immediate_from_long(res.steps[step].val);
3550 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3553 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3556 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3559 panic("unknown setcc transform");
3563 new_node = create_CMov(node, cond, flags, cc);
3571 * Create a conversion from x87 state register to general purpose.
3573 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3575 ir_node *block = be_transform_node(get_nodes_block(node));
3576 ir_node *op = get_Conv_op(node);
3577 ir_node *new_op = be_transform_node(op);
3578 ir_graph *irg = current_ir_graph;
3579 dbg_info *dbgi = get_irn_dbg_info(node);
3580 ir_mode *mode = get_irn_mode(node);
3581 ir_node *fist, *load, *mem;
3583 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3584 set_irn_pinned(fist, op_pin_state_floats);
3585 set_ia32_use_frame(fist);
3586 set_ia32_op_type(fist, ia32_AddrModeD);
3588 assert(get_mode_size_bits(mode) <= 32);
3589 /* exception we can only store signed 32 bit integers, so for unsigned
3590 we store a 64bit (signed) integer and load the lower bits */
3591 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3592 set_ia32_ls_mode(fist, mode_Ls);
3594 set_ia32_ls_mode(fist, mode_Is);
3596 SET_IA32_ORIG_NODE(fist, node);
3599 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3601 set_irn_pinned(load, op_pin_state_floats);
3602 set_ia32_use_frame(load);
3603 set_ia32_op_type(load, ia32_AddrModeS);
3604 set_ia32_ls_mode(load, mode_Is);
3605 if (get_ia32_ls_mode(fist) == mode_Ls) {
3606 ia32_attr_t *attr = get_ia32_attr(load);
3607 attr->data.need_64bit_stackent = 1;
3609 ia32_attr_t *attr = get_ia32_attr(load);
3610 attr->data.need_32bit_stackent = 1;
3612 SET_IA32_ORIG_NODE(load, node);
3614 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3618 * Creates a x87 strict Conv by placing a Store and a Load
3620 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3622 ir_node *block = get_nodes_block(node);
3623 ir_graph *irg = get_Block_irg(block);
3624 dbg_info *dbgi = get_irn_dbg_info(node);
3625 ir_node *frame = get_irg_frame(irg);
3626 ir_node *store, *load;
3629 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3630 set_ia32_use_frame(store);
3631 set_ia32_op_type(store, ia32_AddrModeD);
3632 SET_IA32_ORIG_NODE(store, node);
3634 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3635 set_ia32_use_frame(load);
3636 set_ia32_op_type(load, ia32_AddrModeS);
3637 SET_IA32_ORIG_NODE(load, node);
3639 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3643 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3644 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3646 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3648 func = get_mode_size_bits(mode) == 8 ?
3649 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3650 return func(dbgi, block, base, index, mem, val, mode);
3654 * Create a conversion from general purpose to x87 register
3656 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3658 ir_node *src_block = get_nodes_block(node);
3659 ir_node *block = be_transform_node(src_block);
3660 ir_graph *irg = get_Block_irg(block);
3661 dbg_info *dbgi = get_irn_dbg_info(node);
3662 ir_node *op = get_Conv_op(node);
3663 ir_node *new_op = NULL;
3665 ir_mode *store_mode;
3670 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3671 if (possible_int_mode_for_fp(src_mode)) {
3672 ia32_address_mode_t am;
3674 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3675 if (am.op_type == ia32_AddrModeS) {
3676 ia32_address_t *addr = &am.addr;
3678 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3679 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3681 set_am_attributes(fild, &am);
3682 SET_IA32_ORIG_NODE(fild, node);
3684 fix_mem_proj(fild, &am);
3689 if (new_op == NULL) {
3690 new_op = be_transform_node(op);
3693 mode = get_irn_mode(op);
3695 /* first convert to 32 bit signed if necessary */
3696 if (get_mode_size_bits(src_mode) < 32) {
3697 if (!upper_bits_clean(new_op, src_mode)) {
3698 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3699 SET_IA32_ORIG_NODE(new_op, node);
3704 assert(get_mode_size_bits(mode) == 32);
3707 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3709 set_ia32_use_frame(store);
3710 set_ia32_op_type(store, ia32_AddrModeD);
3711 set_ia32_ls_mode(store, mode_Iu);
3713 /* exception for 32bit unsigned, do a 64bit spill+load */
3714 if (!mode_is_signed(mode)) {
3717 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3719 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3720 noreg_GP, nomem, zero_const);
3722 set_ia32_use_frame(zero_store);
3723 set_ia32_op_type(zero_store, ia32_AddrModeD);
3724 add_ia32_am_offs_int(zero_store, 4);
3725 set_ia32_ls_mode(zero_store, mode_Iu);
3730 store = new_rd_Sync(dbgi, block, 2, in);
3731 store_mode = mode_Ls;
3733 store_mode = mode_Is;
3737 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3739 set_ia32_use_frame(fild);
3740 set_ia32_op_type(fild, ia32_AddrModeS);
3741 set_ia32_ls_mode(fild, store_mode);
3743 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3749 * Create a conversion from one integer mode into another one
3751 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3752 dbg_info *dbgi, ir_node *block, ir_node *op,
3755 ir_node *new_block = be_transform_node(block);
3757 ir_mode *smaller_mode;
3758 ia32_address_mode_t am;
3759 ia32_address_t *addr = &am.addr;
3762 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3763 smaller_mode = src_mode;
3765 smaller_mode = tgt_mode;
3768 #ifdef DEBUG_libfirm
3770 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3775 match_arguments(&am, block, NULL, op, NULL,
3776 match_am | match_8bit_am | match_16bit_am);
3778 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3779 /* unnecessary conv. in theory it shouldn't have been AM */
3780 assert(is_ia32_NoReg_GP(addr->base));
3781 assert(is_ia32_NoReg_GP(addr->index));
3782 assert(is_NoMem(addr->mem));
3783 assert(am.addr.offset == 0);
3784 assert(am.addr.symconst_ent == NULL);
3788 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3789 addr->mem, am.new_op2, smaller_mode);
3790 set_am_attributes(new_node, &am);
3791 /* match_arguments assume that out-mode = in-mode, this isn't true here
3793 set_ia32_ls_mode(new_node, smaller_mode);
3794 SET_IA32_ORIG_NODE(new_node, node);
3795 new_node = fix_mem_proj(new_node, &am);
3800 * Transforms a Conv node.
3802 * @return The created ia32 Conv node
3804 static ir_node *gen_Conv(ir_node *node)
3806 ir_node *block = get_nodes_block(node);
3807 ir_node *new_block = be_transform_node(block);
3808 ir_node *op = get_Conv_op(node);
3809 ir_node *new_op = NULL;
3810 dbg_info *dbgi = get_irn_dbg_info(node);
3811 ir_mode *src_mode = get_irn_mode(op);
3812 ir_mode *tgt_mode = get_irn_mode(node);
3813 int src_bits = get_mode_size_bits(src_mode);
3814 int tgt_bits = get_mode_size_bits(tgt_mode);
3815 ir_node *res = NULL;
3817 assert(!mode_is_int(src_mode) || src_bits <= 32);
3818 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3820 /* modeB -> X should already be lowered by the lower_mode_b pass */
3821 if (src_mode == mode_b) {
3822 panic("ConvB not lowered %+F", node);
3825 if (src_mode == tgt_mode) {
3826 if (get_Conv_strict(node)) {
3827 if (ia32_cg_config.use_sse2) {
3828 /* when we are in SSE mode, we can kill all strict no-op conversion */
3829 return be_transform_node(op);
3832 /* this should be optimized already, but who knows... */
3833 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3834 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3835 return be_transform_node(op);
3839 if (mode_is_float(src_mode)) {
3840 new_op = be_transform_node(op);
3841 /* we convert from float ... */
3842 if (mode_is_float(tgt_mode)) {
3844 if (ia32_cg_config.use_sse2) {
3845 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3846 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3848 set_ia32_ls_mode(res, tgt_mode);
3850 if (get_Conv_strict(node)) {
3851 /* if fp_no_float_fold is not set then we assume that we
3852 * don't have any float operations in a non
3853 * mode_float_arithmetic mode and can skip strict upconvs */
3854 if (src_bits < tgt_bits) {
3855 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3858 res = gen_x87_strict_conv(tgt_mode, new_op);
3859 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3863 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3868 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3869 if (ia32_cg_config.use_sse2) {
3870 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3872 set_ia32_ls_mode(res, src_mode);
3874 return gen_x87_fp_to_gp(node);
3878 /* we convert from int ... */
3879 if (mode_is_float(tgt_mode)) {
3881 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3882 if (ia32_cg_config.use_sse2) {
3883 new_op = be_transform_node(op);
3884 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3886 set_ia32_ls_mode(res, tgt_mode);
3888 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3889 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3890 res = gen_x87_gp_to_fp(node, src_mode);
3892 /* we need a strict-Conv, if the int mode has more bits than the
3894 if (float_mantissa < int_mantissa) {
3895 res = gen_x87_strict_conv(tgt_mode, res);
3896 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3900 } else if (tgt_mode == mode_b) {
3901 /* mode_b lowering already took care that we only have 0/1 values */
3902 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3903 src_mode, tgt_mode));
3904 return be_transform_node(op);
3907 if (src_bits == tgt_bits) {
3908 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3909 src_mode, tgt_mode));
3910 return be_transform_node(op);
3913 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3921 static ir_node *create_immediate_or_transform(ir_node *node,
3922 char immediate_constraint_type)
3924 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3925 if (new_node == NULL) {
3926 new_node = be_transform_node(node);
3932 * Transforms a FrameAddr into an ia32 Add.
3934 static ir_node *gen_be_FrameAddr(ir_node *node)
3936 ir_node *block = be_transform_node(get_nodes_block(node));
3937 ir_node *op = be_get_FrameAddr_frame(node);
3938 ir_node *new_op = be_transform_node(op);
3939 dbg_info *dbgi = get_irn_dbg_info(node);
3942 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3943 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3944 set_ia32_use_frame(new_node);
3946 SET_IA32_ORIG_NODE(new_node, node);
3952 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3954 static ir_node *gen_be_Return(ir_node *node)
3956 ir_graph *irg = current_ir_graph;
3957 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3958 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3959 ir_entity *ent = get_irg_entity(irg);
3960 ir_type *tp = get_entity_type(ent);
3965 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3966 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3968 int pn_ret_val, pn_ret_mem, arity, i;
3970 assert(ret_val != NULL);
3971 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3972 return be_duplicate_node(node);
3975 res_type = get_method_res_type(tp, 0);
3977 if (! is_Primitive_type(res_type)) {
3978 return be_duplicate_node(node);
3981 mode = get_type_mode(res_type);
3982 if (! mode_is_float(mode)) {
3983 return be_duplicate_node(node);
3986 assert(get_method_n_ress(tp) == 1);
3988 pn_ret_val = get_Proj_proj(ret_val);
3989 pn_ret_mem = get_Proj_proj(ret_mem);
3991 /* get the Barrier */
3992 barrier = get_Proj_pred(ret_val);
3994 /* get result input of the Barrier */
3995 ret_val = get_irn_n(barrier, pn_ret_val);
3996 new_ret_val = be_transform_node(ret_val);
3998 /* get memory input of the Barrier */
3999 ret_mem = get_irn_n(barrier, pn_ret_mem);
4000 new_ret_mem = be_transform_node(ret_mem);
4002 frame = get_irg_frame(irg);
4004 dbgi = get_irn_dbg_info(barrier);
4005 block = be_transform_node(get_nodes_block(barrier));
4007 /* store xmm0 onto stack */
4008 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
4009 new_ret_mem, new_ret_val);
4010 set_ia32_ls_mode(sse_store, mode);
4011 set_ia32_op_type(sse_store, ia32_AddrModeD);
4012 set_ia32_use_frame(sse_store);
4014 /* load into x87 register */
4015 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4016 set_ia32_op_type(fld, ia32_AddrModeS);
4017 set_ia32_use_frame(fld);
4019 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4020 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4022 /* create a new barrier */
4023 arity = get_irn_arity(barrier);
4024 in = ALLOCAN(ir_node*, arity);
4025 for (i = 0; i < arity; ++i) {
4028 if (i == pn_ret_val) {
4030 } else if (i == pn_ret_mem) {
4033 ir_node *in = get_irn_n(barrier, i);
4034 new_in = be_transform_node(in);
4039 new_barrier = new_ir_node(dbgi, irg, block,
4040 get_irn_op(barrier), get_irn_mode(barrier),
4042 copy_node_attr(irg, barrier, new_barrier);
4043 be_duplicate_deps(barrier, new_barrier);
4044 be_set_transformed_node(barrier, new_barrier);
4046 /* transform normally */
4047 return be_duplicate_node(node);
4051 * Transform a be_AddSP into an ia32_SubSP.
4053 static ir_node *gen_be_AddSP(ir_node *node)
4055 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4056 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4058 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4059 match_am | match_immediate);
4063 * Transform a be_SubSP into an ia32_AddSP
4065 static ir_node *gen_be_SubSP(ir_node *node)
4067 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4068 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4070 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4071 match_am | match_immediate);
4075 * Change some phi modes
4077 static ir_node *gen_Phi(ir_node *node)
4079 const arch_register_req_t *req;
4080 ir_node *block = be_transform_node(get_nodes_block(node));
4081 ir_graph *irg = current_ir_graph;
4082 dbg_info *dbgi = get_irn_dbg_info(node);
4083 ir_mode *mode = get_irn_mode(node);
4086 if (ia32_mode_needs_gp_reg(mode)) {
4087 /* we shouldn't have any 64bit stuff around anymore */
4088 assert(get_mode_size_bits(mode) <= 32);
4089 /* all integer operations are on 32bit registers now */
4091 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4092 } else if (mode_is_float(mode)) {
4093 if (ia32_cg_config.use_sse2) {
4095 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4098 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4101 req = arch_no_register_req;
4104 /* phi nodes allow loops, so we use the old arguments for now
4105 * and fix this later */
4106 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4107 get_irn_in(node) + 1);
4108 copy_node_attr(irg, node, phi);
4109 be_duplicate_deps(node, phi);
4111 arch_set_out_register_req(phi, 0, req);
4113 be_enqueue_preds(node);
4118 static ir_node *gen_Jmp(ir_node *node)
4120 ir_node *block = get_nodes_block(node);
4121 ir_node *new_block = be_transform_node(block);
4122 dbg_info *dbgi = get_irn_dbg_info(node);
4125 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4126 SET_IA32_ORIG_NODE(new_node, node);
4134 static ir_node *gen_IJmp(ir_node *node)
4136 ir_node *block = get_nodes_block(node);
4137 ir_node *new_block = be_transform_node(block);
4138 dbg_info *dbgi = get_irn_dbg_info(node);
4139 ir_node *op = get_IJmp_target(node);
4141 ia32_address_mode_t am;
4142 ia32_address_t *addr = &am.addr;
4144 assert(get_irn_mode(op) == mode_P);
4146 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4148 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4149 addr->mem, am.new_op2);
4150 set_am_attributes(new_node, &am);
4151 SET_IA32_ORIG_NODE(new_node, node);
4153 new_node = fix_mem_proj(new_node, &am);
4158 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4160 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4161 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4163 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4164 match_immediate | match_mode_neutral);
4167 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4169 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4170 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4171 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4175 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4177 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4178 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4179 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4183 static ir_node *gen_ia32_l_Add(ir_node *node)
4185 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4186 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4187 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4188 match_commutative | match_am | match_immediate |
4189 match_mode_neutral);
4191 if (is_Proj(lowered)) {
4192 lowered = get_Proj_pred(lowered);
4194 assert(is_ia32_Add(lowered));
4195 set_irn_mode(lowered, mode_T);
4201 static ir_node *gen_ia32_l_Adc(ir_node *node)
4203 return gen_binop_flags(node, new_bd_ia32_Adc,
4204 match_commutative | match_am | match_immediate |
4205 match_mode_neutral);
4209 * Transforms a l_MulS into a "real" MulS node.
4211 * @return the created ia32 Mul node
4213 static ir_node *gen_ia32_l_Mul(ir_node *node)
4215 ir_node *left = get_binop_left(node);
4216 ir_node *right = get_binop_right(node);
4218 return gen_binop(node, left, right, new_bd_ia32_Mul,
4219 match_commutative | match_am | match_mode_neutral);
4223 * Transforms a l_IMulS into a "real" IMul1OPS node.
4225 * @return the created ia32 IMul1OP node
4227 static ir_node *gen_ia32_l_IMul(ir_node *node)
4229 ir_node *left = get_binop_left(node);
4230 ir_node *right = get_binop_right(node);
4232 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4233 match_commutative | match_am | match_mode_neutral);
4236 static ir_node *gen_ia32_l_Sub(ir_node *node)
4238 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4239 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4240 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4241 match_am | match_immediate | match_mode_neutral);
4243 if (is_Proj(lowered)) {
4244 lowered = get_Proj_pred(lowered);
4246 assert(is_ia32_Sub(lowered));
4247 set_irn_mode(lowered, mode_T);
4253 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4255 return gen_binop_flags(node, new_bd_ia32_Sbb,
4256 match_am | match_immediate | match_mode_neutral);
4260 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4261 * op1 - target to be shifted
4262 * op2 - contains bits to be shifted into target
4264 * Only op3 can be an immediate.
4266 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4267 ir_node *low, ir_node *count)
4269 ir_node *block = get_nodes_block(node);
4270 ir_node *new_block = be_transform_node(block);
4271 dbg_info *dbgi = get_irn_dbg_info(node);
4272 ir_node *new_high = be_transform_node(high);
4273 ir_node *new_low = be_transform_node(low);
4277 /* the shift amount can be any mode that is bigger than 5 bits, since all
4278 * other bits are ignored anyway */
4279 while (is_Conv(count) &&
4280 get_irn_n_edges(count) == 1 &&
4281 mode_is_int(get_irn_mode(count))) {
4282 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4283 count = get_Conv_op(count);
4285 new_count = create_immediate_or_transform(count, 0);
4287 if (is_ia32_l_ShlD(node)) {
4288 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4291 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4294 SET_IA32_ORIG_NODE(new_node, node);
4299 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4301 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4302 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4303 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4304 return gen_lowered_64bit_shifts(node, high, low, count);
4307 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4309 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4310 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4311 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4312 return gen_lowered_64bit_shifts(node, high, low, count);
4315 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4317 ir_node *src_block = get_nodes_block(node);
4318 ir_node *block = be_transform_node(src_block);
4319 ir_graph *irg = current_ir_graph;
4320 dbg_info *dbgi = get_irn_dbg_info(node);
4321 ir_node *frame = get_irg_frame(irg);
4322 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4323 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4324 ir_node *new_val_low = be_transform_node(val_low);
4325 ir_node *new_val_high = be_transform_node(val_high);
4327 ir_node *sync, *fild, *res;
4328 ir_node *store_low, *store_high;
4330 if (ia32_cg_config.use_sse2) {
4331 panic("ia32_l_LLtoFloat not implemented for SSE2");
4335 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4337 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4339 SET_IA32_ORIG_NODE(store_low, node);
4340 SET_IA32_ORIG_NODE(store_high, node);
4342 set_ia32_use_frame(store_low);
4343 set_ia32_use_frame(store_high);
4344 set_ia32_op_type(store_low, ia32_AddrModeD);
4345 set_ia32_op_type(store_high, ia32_AddrModeD);
4346 set_ia32_ls_mode(store_low, mode_Iu);
4347 set_ia32_ls_mode(store_high, mode_Is);
4348 add_ia32_am_offs_int(store_high, 4);
4352 sync = new_rd_Sync(dbgi, block, 2, in);
4355 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4357 set_ia32_use_frame(fild);
4358 set_ia32_op_type(fild, ia32_AddrModeS);
4359 set_ia32_ls_mode(fild, mode_Ls);
4361 SET_IA32_ORIG_NODE(fild, node);
4363 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4365 if (! mode_is_signed(get_irn_mode(val_high))) {
4366 ia32_address_mode_t am;
4368 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4371 am.addr.base = get_symconst_base();
4372 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4373 am.addr.mem = nomem;
4376 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4377 am.addr.use_frame = 0;
4378 am.addr.frame_entity = NULL;
4379 am.addr.symconst_sign = 0;
4380 am.ls_mode = mode_F;
4381 am.mem_proj = nomem;
4382 am.op_type = ia32_AddrModeS;
4384 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4385 am.pinned = op_pin_state_floats;
4387 am.ins_permuted = false;
4389 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4390 am.new_op1, am.new_op2, get_fpcw());
4391 set_am_attributes(fadd, &am);
4393 set_irn_mode(fadd, mode_T);
4394 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4399 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4401 ir_node *src_block = get_nodes_block(node);
4402 ir_node *block = be_transform_node(src_block);
4403 ir_graph *irg = get_Block_irg(block);
4404 dbg_info *dbgi = get_irn_dbg_info(node);
4405 ir_node *frame = get_irg_frame(irg);
4406 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4407 ir_node *new_val = be_transform_node(val);
4408 ir_node *fist, *mem;
4410 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4411 SET_IA32_ORIG_NODE(fist, node);
4412 set_ia32_use_frame(fist);
4413 set_ia32_op_type(fist, ia32_AddrModeD);
4414 set_ia32_ls_mode(fist, mode_Ls);
4419 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4421 ir_node *block = be_transform_node(get_nodes_block(node));
4422 ir_graph *irg = get_Block_irg(block);
4423 ir_node *pred = get_Proj_pred(node);
4424 ir_node *new_pred = be_transform_node(pred);
4425 ir_node *frame = get_irg_frame(irg);
4426 dbg_info *dbgi = get_irn_dbg_info(node);
4427 long pn = get_Proj_proj(node);
4432 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4433 SET_IA32_ORIG_NODE(load, node);
4434 set_ia32_use_frame(load);
4435 set_ia32_op_type(load, ia32_AddrModeS);
4436 set_ia32_ls_mode(load, mode_Iu);
4437 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4438 * 32 bit from it with this particular load */
4439 attr = get_ia32_attr(load);
4440 attr->data.need_64bit_stackent = 1;
4442 if (pn == pn_ia32_l_FloattoLL_res_high) {
4443 add_ia32_am_offs_int(load, 4);
4445 assert(pn == pn_ia32_l_FloattoLL_res_low);
4448 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4454 * Transform the Projs of an AddSP.
4456 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4458 ir_node *pred = get_Proj_pred(node);
4459 ir_node *new_pred = be_transform_node(pred);
4460 dbg_info *dbgi = get_irn_dbg_info(node);
4461 long proj = get_Proj_proj(node);
4463 if (proj == pn_be_AddSP_sp) {
4464 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4465 pn_ia32_SubSP_stack);
4466 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4468 } else if (proj == pn_be_AddSP_res) {
4469 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4470 pn_ia32_SubSP_addr);
4471 } else if (proj == pn_be_AddSP_M) {
4472 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4475 panic("No idea how to transform proj->AddSP");
4479 * Transform the Projs of a SubSP.
4481 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4483 ir_node *pred = get_Proj_pred(node);
4484 ir_node *new_pred = be_transform_node(pred);
4485 dbg_info *dbgi = get_irn_dbg_info(node);
4486 long proj = get_Proj_proj(node);
4488 if (proj == pn_be_SubSP_sp) {
4489 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4490 pn_ia32_AddSP_stack);
4491 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4493 } else if (proj == pn_be_SubSP_M) {
4494 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4497 panic("No idea how to transform proj->SubSP");
4501 * Transform and renumber the Projs from a Load.
4503 static ir_node *gen_Proj_Load(ir_node *node)
4506 ir_node *block = be_transform_node(get_nodes_block(node));
4507 ir_node *pred = get_Proj_pred(node);
4508 dbg_info *dbgi = get_irn_dbg_info(node);
4509 long proj = get_Proj_proj(node);
4511 /* loads might be part of source address mode matches, so we don't
4512 * transform the ProjMs yet (with the exception of loads whose result is
4515 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4518 /* this is needed, because sometimes we have loops that are only
4519 reachable through the ProjM */
4520 be_enqueue_preds(node);
4521 /* do it in 2 steps, to silence firm verifier */
4522 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4523 set_Proj_proj(res, pn_ia32_mem);
4527 /* renumber the proj */
4528 new_pred = be_transform_node(pred);
4529 if (is_ia32_Load(new_pred)) {
4532 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4534 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4535 case pn_Load_X_regular:
4536 return new_rd_Jmp(dbgi, block);
4537 case pn_Load_X_except:
4538 /* This Load might raise an exception. Mark it. */
4539 set_ia32_exc_label(new_pred, 1);
4540 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4544 } else if (is_ia32_Conv_I2I(new_pred) ||
4545 is_ia32_Conv_I2I8Bit(new_pred)) {
4546 set_irn_mode(new_pred, mode_T);
4547 if (proj == pn_Load_res) {
4548 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4549 } else if (proj == pn_Load_M) {
4550 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4552 } else if (is_ia32_xLoad(new_pred)) {
4555 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4557 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4558 case pn_Load_X_regular:
4559 return new_rd_Jmp(dbgi, block);
4560 case pn_Load_X_except:
4561 /* This Load might raise an exception. Mark it. */
4562 set_ia32_exc_label(new_pred, 1);
4563 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4567 } else if (is_ia32_vfld(new_pred)) {
4570 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4572 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4573 case pn_Load_X_regular:
4574 return new_rd_Jmp(dbgi, block);
4575 case pn_Load_X_except:
4576 /* This Load might raise an exception. Mark it. */
4577 set_ia32_exc_label(new_pred, 1);
4578 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4583 /* can happen for ProJMs when source address mode happened for the
4586 /* however it should not be the result proj, as that would mean the
4587 load had multiple users and should not have been used for
4589 if (proj != pn_Load_M) {
4590 panic("internal error: transformed node not a Load");
4592 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4595 panic("No idea how to transform proj");
4599 * Transform and renumber the Projs from a Div or Mod instruction.
4601 static ir_node *gen_Proj_Div(ir_node *node)
4603 ir_node *block = be_transform_node(get_nodes_block(node));
4604 ir_node *pred = get_Proj_pred(node);
4605 ir_node *new_pred = be_transform_node(pred);
4606 dbg_info *dbgi = get_irn_dbg_info(node);
4607 long proj = get_Proj_proj(node);
4609 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4610 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4614 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4615 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4616 } else if (is_ia32_xDiv(new_pred)) {
4617 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4618 } else if (is_ia32_vfdiv(new_pred)) {
4619 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4621 panic("Div transformed to unexpected thing %+F", new_pred);
4624 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4625 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4626 } else if (is_ia32_xDiv(new_pred)) {
4627 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4628 } else if (is_ia32_vfdiv(new_pred)) {
4629 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4631 panic("Div transformed to unexpected thing %+F", new_pred);
4633 case pn_Div_X_regular:
4634 return new_rd_Jmp(dbgi, block);
4635 case pn_Div_X_except:
4636 set_ia32_exc_label(new_pred, 1);
4637 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4642 panic("No idea how to transform proj->Div");
4646 * Transform and renumber the Projs from a Div or Mod instruction.
4648 static ir_node *gen_Proj_Mod(ir_node *node)
4650 ir_node *pred = get_Proj_pred(node);
4651 ir_node *new_pred = be_transform_node(pred);
4652 dbg_info *dbgi = get_irn_dbg_info(node);
4653 long proj = get_Proj_proj(node);
4655 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4656 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4657 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4661 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4663 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4664 case pn_Mod_X_except:
4665 set_ia32_exc_label(new_pred, 1);
4666 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4670 panic("No idea how to transform proj->Mod");
4674 * Transform and renumber the Projs from a CopyB.
4676 static ir_node *gen_Proj_CopyB(ir_node *node)
4678 ir_node *pred = get_Proj_pred(node);
4679 ir_node *new_pred = be_transform_node(pred);
4680 dbg_info *dbgi = get_irn_dbg_info(node);
4681 long proj = get_Proj_proj(node);
4685 if (is_ia32_CopyB_i(new_pred)) {
4686 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4687 } else if (is_ia32_CopyB(new_pred)) {
4688 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4695 panic("No idea how to transform proj->CopyB");
4698 static ir_node *gen_be_Call(ir_node *node)
4700 dbg_info *const dbgi = get_irn_dbg_info(node);
4701 ir_node *const src_block = get_nodes_block(node);
4702 ir_node *const block = be_transform_node(src_block);
4703 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4704 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4705 ir_node *const sp = be_transform_node(src_sp);
4706 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4707 ia32_address_mode_t am;
4708 ia32_address_t *const addr = &am.addr;
4713 ir_node * eax = noreg_GP;
4714 ir_node * ecx = noreg_GP;
4715 ir_node * edx = noreg_GP;
4716 unsigned const pop = be_Call_get_pop(node);
4717 ir_type *const call_tp = be_Call_get_type(node);
4718 int old_no_pic_adjust;
4720 /* Run the x87 simulator if the call returns a float value */
4721 if (get_method_n_ress(call_tp) > 0) {
4722 ir_type *const res_type = get_method_res_type(call_tp, 0);
4723 ir_mode *const res_mode = get_type_mode(res_type);
4725 if (res_mode != NULL && mode_is_float(res_mode)) {
4726 ir_graph *irg = current_ir_graph;
4727 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4728 irg_data->do_x87_sim = 1;
4732 /* We do not want be_Call direct calls */
4733 assert(be_Call_get_entity(node) == NULL);
4735 /* special case for PIC trampoline calls */
4736 old_no_pic_adjust = ia32_no_pic_adjust;
4737 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4739 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4740 match_am | match_immediate);
4742 ia32_no_pic_adjust = old_no_pic_adjust;
4744 i = get_irn_arity(node) - 1;
4745 fpcw = be_transform_node(get_irn_n(node, i--));
4746 for (; i >= be_pos_Call_first_arg; --i) {
4747 arch_register_req_t const *const req = arch_get_register_req(node, i);
4748 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4750 assert(req->type == arch_register_req_type_limited);
4751 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4753 switch (*req->limited) {
4754 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4755 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4756 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4757 default: panic("Invalid GP register for register parameter");
4761 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4762 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4763 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4764 set_am_attributes(call, &am);
4765 call = fix_mem_proj(call, &am);
4767 if (get_irn_pinned(node) == op_pin_state_pinned)
4768 set_irn_pinned(call, op_pin_state_pinned);
4770 SET_IA32_ORIG_NODE(call, node);
4772 if (ia32_cg_config.use_sse2) {
4773 /* remember this call for post-processing */
4774 ARR_APP1(ir_node *, call_list, call);
4775 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4782 * Transform Builtin trap
4784 static ir_node *gen_trap(ir_node *node)
4786 dbg_info *dbgi = get_irn_dbg_info(node);
4787 ir_node *block = be_transform_node(get_nodes_block(node));
4788 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4790 return new_bd_ia32_UD2(dbgi, block, mem);
4794 * Transform Builtin debugbreak
4796 static ir_node *gen_debugbreak(ir_node *node)
4798 dbg_info *dbgi = get_irn_dbg_info(node);
4799 ir_node *block = be_transform_node(get_nodes_block(node));
4800 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4802 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4806 * Transform Builtin return_address
4808 static ir_node *gen_return_address(ir_node *node)
4810 ir_node *param = get_Builtin_param(node, 0);
4811 ir_node *frame = get_Builtin_param(node, 1);
4812 dbg_info *dbgi = get_irn_dbg_info(node);
4813 ir_tarval *tv = get_Const_tarval(param);
4814 unsigned long value = get_tarval_long(tv);
4816 ir_node *block = be_transform_node(get_nodes_block(node));
4817 ir_node *ptr = be_transform_node(frame);
4821 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4822 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4823 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4826 /* load the return address from this frame */
4827 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4829 set_irn_pinned(load, get_irn_pinned(node));
4830 set_ia32_op_type(load, ia32_AddrModeS);
4831 set_ia32_ls_mode(load, mode_Iu);
4833 set_ia32_am_offs_int(load, 0);
4834 set_ia32_use_frame(load);
4835 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4837 if (get_irn_pinned(node) == op_pin_state_floats) {
4838 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4839 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4840 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4841 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4844 SET_IA32_ORIG_NODE(load, node);
4845 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4849 * Transform Builtin frame_address
4851 static ir_node *gen_frame_address(ir_node *node)
4853 ir_node *param = get_Builtin_param(node, 0);
4854 ir_node *frame = get_Builtin_param(node, 1);
4855 dbg_info *dbgi = get_irn_dbg_info(node);
4856 ir_tarval *tv = get_Const_tarval(param);
4857 unsigned long value = get_tarval_long(tv);
4859 ir_node *block = be_transform_node(get_nodes_block(node));
4860 ir_node *ptr = be_transform_node(frame);
4865 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4866 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4867 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4870 /* load the frame address from this frame */
4871 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4873 set_irn_pinned(load, get_irn_pinned(node));
4874 set_ia32_op_type(load, ia32_AddrModeS);
4875 set_ia32_ls_mode(load, mode_Iu);
4877 ent = ia32_get_frame_address_entity();
4879 set_ia32_am_offs_int(load, 0);
4880 set_ia32_use_frame(load);
4881 set_ia32_frame_ent(load, ent);
4883 /* will fail anyway, but gcc does this: */
4884 set_ia32_am_offs_int(load, 0);
4887 if (get_irn_pinned(node) == op_pin_state_floats) {
4888 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4889 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4890 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4891 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4894 SET_IA32_ORIG_NODE(load, node);
4895 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4899 * Transform Builtin frame_address
4901 static ir_node *gen_prefetch(ir_node *node)
4904 ir_node *ptr, *block, *mem, *base, *index;
4905 ir_node *param, *new_node;
4908 ia32_address_t addr;
4910 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4911 /* no prefetch at all, route memory */
4912 return be_transform_node(get_Builtin_mem(node));
4915 param = get_Builtin_param(node, 1);
4916 tv = get_Const_tarval(param);
4917 rw = get_tarval_long(tv);
4919 /* construct load address */
4920 memset(&addr, 0, sizeof(addr));
4921 ptr = get_Builtin_param(node, 0);
4922 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4929 base = be_transform_node(base);
4932 if (index == NULL) {
4935 index = be_transform_node(index);
4938 dbgi = get_irn_dbg_info(node);
4939 block = be_transform_node(get_nodes_block(node));
4940 mem = be_transform_node(get_Builtin_mem(node));
4942 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4943 /* we have 3DNow!, this was already checked above */
4944 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4945 } else if (ia32_cg_config.use_sse_prefetch) {
4946 /* note: rw == 1 is IGNORED in that case */
4947 param = get_Builtin_param(node, 2);
4948 tv = get_Const_tarval(param);
4949 locality = get_tarval_long(tv);
4951 /* SSE style prefetch */
4954 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4957 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4960 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4963 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4967 assert(ia32_cg_config.use_3dnow_prefetch);
4968 /* 3DNow! style prefetch */
4969 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4972 set_irn_pinned(new_node, get_irn_pinned(node));
4973 set_ia32_op_type(new_node, ia32_AddrModeS);
4974 set_ia32_ls_mode(new_node, mode_Bu);
4975 set_address(new_node, &addr);
4977 SET_IA32_ORIG_NODE(new_node, node);
4979 be_dep_on_frame(new_node);
4980 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4984 * Transform bsf like node
4986 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4988 ir_node *param = get_Builtin_param(node, 0);
4989 dbg_info *dbgi = get_irn_dbg_info(node);
4991 ir_node *block = get_nodes_block(node);
4992 ir_node *new_block = be_transform_node(block);
4994 ia32_address_mode_t am;
4995 ia32_address_t *addr = &am.addr;
4998 match_arguments(&am, block, NULL, param, NULL, match_am);
5000 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5001 set_am_attributes(cnt, &am);
5002 set_ia32_ls_mode(cnt, get_irn_mode(param));
5004 SET_IA32_ORIG_NODE(cnt, node);
5005 return fix_mem_proj(cnt, &am);
5009 * Transform builtin ffs.
5011 static ir_node *gen_ffs(ir_node *node)
5013 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5014 ir_node *real = skip_Proj(bsf);
5015 dbg_info *dbgi = get_irn_dbg_info(real);
5016 ir_node *block = get_nodes_block(real);
5017 ir_node *flag, *set, *conv, *neg, *orn;
5020 if (get_irn_mode(real) != mode_T) {
5021 set_irn_mode(real, mode_T);
5022 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5025 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5028 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5029 SET_IA32_ORIG_NODE(set, node);
5032 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5033 SET_IA32_ORIG_NODE(conv, node);
5036 neg = new_bd_ia32_Neg(dbgi, block, conv);
5039 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5040 set_ia32_commutative(orn);
5043 return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, orn, ia32_create_Immediate(NULL, 0, 1));
5047 * Transform builtin clz.
5049 static ir_node *gen_clz(ir_node *node)
5051 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5052 ir_node *real = skip_Proj(bsr);
5053 dbg_info *dbgi = get_irn_dbg_info(real);
5054 ir_node *block = get_nodes_block(real);
5055 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5057 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5061 * Transform builtin ctz.
5063 static ir_node *gen_ctz(ir_node *node)
5065 return gen_unop_AM(node, new_bd_ia32_Bsf);
5069 * Transform builtin parity.
5071 static ir_node *gen_parity(ir_node *node)
5073 dbg_info *dbgi = get_irn_dbg_info(node);
5074 ir_node *block = get_nodes_block(node);
5075 ir_node *new_block = be_transform_node(block);
5076 ir_node *param = get_Builtin_param(node, 0);
5077 ir_node *new_param = be_transform_node(param);
5080 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5081 * so we have to do complicated xoring first.
5082 * (we should also better lower this before the backend so we still have a
5083 * chance for CSE, constant folding and other goodies for some of these
5086 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5087 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5088 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5090 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5093 set_irn_mode(xor2, mode_T);
5094 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5097 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5098 SET_IA32_ORIG_NODE(new_node, node);
5101 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5102 nomem, new_node, mode_Bu);
5103 SET_IA32_ORIG_NODE(new_node, node);
5108 * Transform builtin popcount
5110 static ir_node *gen_popcount(ir_node *node)
5112 ir_node *param = get_Builtin_param(node, 0);
5113 dbg_info *dbgi = get_irn_dbg_info(node);
5115 ir_node *block = get_nodes_block(node);
5116 ir_node *new_block = be_transform_node(block);
5119 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5121 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5122 if (ia32_cg_config.use_popcnt) {
5123 ia32_address_mode_t am;
5124 ia32_address_t *addr = &am.addr;
5127 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5129 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5130 set_am_attributes(cnt, &am);
5131 set_ia32_ls_mode(cnt, get_irn_mode(param));
5133 SET_IA32_ORIG_NODE(cnt, node);
5134 return fix_mem_proj(cnt, &am);
5137 new_param = be_transform_node(param);
5139 /* do the standard popcount algo */
5140 /* TODO: This is stupid, we should transform this before the backend,
5141 * to get CSE, localopts, etc. for the operations
5142 * TODO: This is also not the optimal algorithm (it is just the starting
5143 * example in hackers delight, they optimize it more on the following page)
5144 * But I'm too lazy to fix this now, as the code should get lowered before
5145 * the backend anyway.
5148 /* m1 = x & 0x55555555 */
5149 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5150 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5153 simm = ia32_create_Immediate(NULL, 0, 1);
5154 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5156 /* m2 = s1 & 0x55555555 */
5157 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5160 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5162 /* m4 = m3 & 0x33333333 */
5163 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5164 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5167 simm = ia32_create_Immediate(NULL, 0, 2);
5168 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5170 /* m5 = s2 & 0x33333333 */
5171 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5174 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5176 /* m7 = m6 & 0x0F0F0F0F */
5177 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5178 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5181 simm = ia32_create_Immediate(NULL, 0, 4);
5182 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5184 /* m8 = s3 & 0x0F0F0F0F */
5185 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5188 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5190 /* m10 = m9 & 0x00FF00FF */
5191 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5192 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5195 simm = ia32_create_Immediate(NULL, 0, 8);
5196 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5198 /* m11 = s4 & 0x00FF00FF */
5199 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5201 /* m12 = m10 + m11 */
5202 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5204 /* m13 = m12 & 0x0000FFFF */
5205 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5206 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5208 /* s5 = m12 >> 16 */
5209 simm = ia32_create_Immediate(NULL, 0, 16);
5210 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5212 /* res = m13 + s5 */
5213 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5217 * Transform builtin byte swap.
5219 static ir_node *gen_bswap(ir_node *node)
5221 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5222 dbg_info *dbgi = get_irn_dbg_info(node);
5224 ir_node *block = get_nodes_block(node);
5225 ir_node *new_block = be_transform_node(block);
5226 ir_mode *mode = get_irn_mode(param);
5227 unsigned size = get_mode_size_bits(mode);
5228 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5232 if (ia32_cg_config.use_i486) {
5233 /* swap available */
5234 return new_bd_ia32_Bswap(dbgi, new_block, param);
5236 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5237 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5239 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5240 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5242 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5244 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5245 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5247 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5248 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5251 /* swap16 always available */
5252 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5255 panic("Invalid bswap size (%d)", size);
5260 * Transform builtin outport.
5262 static ir_node *gen_outport(ir_node *node)
5264 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5265 ir_node *oldv = get_Builtin_param(node, 1);
5266 ir_mode *mode = get_irn_mode(oldv);
5267 ir_node *value = be_transform_node(oldv);
5268 ir_node *block = be_transform_node(get_nodes_block(node));
5269 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5270 dbg_info *dbgi = get_irn_dbg_info(node);
5272 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5273 set_ia32_ls_mode(res, mode);
5278 * Transform builtin inport.
5280 static ir_node *gen_inport(ir_node *node)
5282 ir_type *tp = get_Builtin_type(node);
5283 ir_type *rstp = get_method_res_type(tp, 0);
5284 ir_mode *mode = get_type_mode(rstp);
5285 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5286 ir_node *block = be_transform_node(get_nodes_block(node));
5287 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5288 dbg_info *dbgi = get_irn_dbg_info(node);
5290 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5291 set_ia32_ls_mode(res, mode);
5293 /* check for missing Result Proj */
5298 * Transform a builtin inner trampoline
5300 static ir_node *gen_inner_trampoline(ir_node *node)
5302 ir_node *ptr = get_Builtin_param(node, 0);
5303 ir_node *callee = get_Builtin_param(node, 1);
5304 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5305 ir_node *mem = get_Builtin_mem(node);
5306 ir_node *block = get_nodes_block(node);
5307 ir_node *new_block = be_transform_node(block);
5311 ir_node *trampoline;
5313 dbg_info *dbgi = get_irn_dbg_info(node);
5314 ia32_address_t addr;
5316 /* construct store address */
5317 memset(&addr, 0, sizeof(addr));
5318 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5320 if (addr.base == NULL) {
5321 addr.base = noreg_GP;
5323 addr.base = be_transform_node(addr.base);
5326 if (addr.index == NULL) {
5327 addr.index = noreg_GP;
5329 addr.index = be_transform_node(addr.index);
5331 addr.mem = be_transform_node(mem);
5333 /* mov ecx, <env> */
5334 val = ia32_create_Immediate(NULL, 0, 0xB9);
5335 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5336 addr.index, addr.mem, val);
5337 set_irn_pinned(store, get_irn_pinned(node));
5338 set_ia32_op_type(store, ia32_AddrModeD);
5339 set_ia32_ls_mode(store, mode_Bu);
5340 set_address(store, &addr);
5344 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5345 addr.index, addr.mem, env);
5346 set_irn_pinned(store, get_irn_pinned(node));
5347 set_ia32_op_type(store, ia32_AddrModeD);
5348 set_ia32_ls_mode(store, mode_Iu);
5349 set_address(store, &addr);
5353 /* jmp rel <callee> */
5354 val = ia32_create_Immediate(NULL, 0, 0xE9);
5355 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5356 addr.index, addr.mem, val);
5357 set_irn_pinned(store, get_irn_pinned(node));
5358 set_ia32_op_type(store, ia32_AddrModeD);
5359 set_ia32_ls_mode(store, mode_Bu);
5360 set_address(store, &addr);
5364 trampoline = be_transform_node(ptr);
5366 /* the callee is typically an immediate */
5367 if (is_SymConst(callee)) {
5368 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5370 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), ia32_create_Immediate(NULL, 0, -10));
5372 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5374 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5375 addr.index, addr.mem, rel);
5376 set_irn_pinned(store, get_irn_pinned(node));
5377 set_ia32_op_type(store, ia32_AddrModeD);
5378 set_ia32_ls_mode(store, mode_Iu);
5379 set_address(store, &addr);
5384 return new_r_Tuple(new_block, 2, in);
5388 * Transform Builtin node.
5390 static ir_node *gen_Builtin(ir_node *node)
5392 ir_builtin_kind kind = get_Builtin_kind(node);
5396 return gen_trap(node);
5397 case ir_bk_debugbreak:
5398 return gen_debugbreak(node);
5399 case ir_bk_return_address:
5400 return gen_return_address(node);
5401 case ir_bk_frame_address:
5402 return gen_frame_address(node);
5403 case ir_bk_prefetch:
5404 return gen_prefetch(node);
5406 return gen_ffs(node);
5408 return gen_clz(node);
5410 return gen_ctz(node);
5412 return gen_parity(node);
5413 case ir_bk_popcount:
5414 return gen_popcount(node);
5416 return gen_bswap(node);
5418 return gen_outport(node);
5420 return gen_inport(node);
5421 case ir_bk_inner_trampoline:
5422 return gen_inner_trampoline(node);
5424 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5428 * Transform Proj(Builtin) node.
5430 static ir_node *gen_Proj_Builtin(ir_node *proj)
5432 ir_node *node = get_Proj_pred(proj);
5433 ir_node *new_node = be_transform_node(node);
5434 ir_builtin_kind kind = get_Builtin_kind(node);
5437 case ir_bk_return_address:
5438 case ir_bk_frame_address:
5443 case ir_bk_popcount:
5445 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5448 case ir_bk_debugbreak:
5449 case ir_bk_prefetch:
5451 assert(get_Proj_proj(proj) == pn_Builtin_M);
5454 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5455 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5457 assert(get_Proj_proj(proj) == pn_Builtin_M);
5458 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5460 case ir_bk_inner_trampoline:
5461 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5462 return get_Tuple_pred(new_node, 1);
5464 assert(get_Proj_proj(proj) == pn_Builtin_M);
5465 return get_Tuple_pred(new_node, 0);
5468 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5471 static ir_node *gen_be_IncSP(ir_node *node)
5473 ir_node *res = be_duplicate_node(node);
5474 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5480 * Transform the Projs from a be_Call.
5482 static ir_node *gen_Proj_be_Call(ir_node *node)
5484 ir_node *call = get_Proj_pred(node);
5485 ir_node *new_call = be_transform_node(call);
5486 dbg_info *dbgi = get_irn_dbg_info(node);
5487 long proj = get_Proj_proj(node);
5488 ir_mode *mode = get_irn_mode(node);
5491 if (proj == pn_be_Call_M_regular) {
5492 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5494 /* transform call modes */
5495 if (mode_is_data(mode)) {
5496 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5500 /* Map from be_Call to ia32_Call proj number */
5501 if (proj == pn_be_Call_sp) {
5502 proj = pn_ia32_Call_stack;
5503 } else if (proj == pn_be_Call_M_regular) {
5504 proj = pn_ia32_Call_M;
5506 arch_register_req_t const *const req = arch_get_register_req_out(node);
5507 int const n_outs = arch_irn_get_n_outs(new_call);
5510 assert(proj >= pn_be_Call_first_res);
5511 assert(req->type & arch_register_req_type_limited);
5513 for (i = 0; i < n_outs; ++i) {
5514 arch_register_req_t const *const new_req
5515 = arch_get_out_register_req(new_call, i);
5517 if (!(new_req->type & arch_register_req_type_limited) ||
5518 new_req->cls != req->cls ||
5519 *new_req->limited != *req->limited)
5528 res = new_rd_Proj(dbgi, new_call, mode, proj);
5530 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5532 case pn_ia32_Call_stack:
5533 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5536 case pn_ia32_Call_fpcw:
5537 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5545 * Transform the Projs from a Cmp.
5547 static ir_node *gen_Proj_Cmp(ir_node *node)
5549 /* this probably means not all mode_b nodes were lowered... */
5550 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5554 static ir_node *gen_Proj_ASM(ir_node *node)
5556 ir_mode *mode = get_irn_mode(node);
5557 ir_node *pred = get_Proj_pred(node);
5558 ir_node *new_pred = be_transform_node(pred);
5559 long pos = get_Proj_proj(node);
5561 if (mode == mode_M) {
5562 pos = arch_irn_get_n_outs(new_pred)-1;
5563 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5565 } else if (mode_is_float(mode)) {
5568 panic("unexpected proj mode at ASM");
5571 return new_r_Proj(new_pred, mode, pos);
5575 * Transform and potentially renumber Proj nodes.
5577 static ir_node *gen_Proj(ir_node *node)
5579 ir_node *pred = get_Proj_pred(node);
5582 switch (get_irn_opcode(pred)) {
5584 proj = get_Proj_proj(node);
5585 if (proj == pn_Store_M) {
5586 return be_transform_node(pred);
5588 panic("No idea how to transform proj->Store");
5591 return gen_Proj_Load(node);
5593 return gen_Proj_ASM(node);
5595 return gen_Proj_Builtin(node);
5597 return gen_Proj_Div(node);
5599 return gen_Proj_Mod(node);
5601 return gen_Proj_CopyB(node);
5603 return gen_Proj_be_SubSP(node);
5605 return gen_Proj_be_AddSP(node);
5607 return gen_Proj_be_Call(node);
5609 return gen_Proj_Cmp(node);
5611 proj = get_Proj_proj(node);
5613 case pn_Start_X_initial_exec: {
5614 ir_node *block = get_nodes_block(pred);
5615 ir_node *new_block = be_transform_node(block);
5616 dbg_info *dbgi = get_irn_dbg_info(node);
5617 /* we exchange the ProjX with a jump */
5618 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5623 case pn_Start_P_tls:
5624 return ia32_gen_Proj_tls(node);
5629 if (is_ia32_l_FloattoLL(pred)) {
5630 return gen_Proj_l_FloattoLL(node);
5632 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5636 ir_mode *mode = get_irn_mode(node);
5637 if (ia32_mode_needs_gp_reg(mode)) {
5638 ir_node *new_pred = be_transform_node(pred);
5639 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5640 get_Proj_proj(node));
5641 new_proj->node_nr = node->node_nr;
5646 return be_duplicate_node(node);
5650 * Enters all transform functions into the generic pointer
5652 static void register_transformers(void)
5654 /* first clear the generic function pointer for all ops */
5655 be_start_transform_setup();
5657 be_set_transform_function(op_Add, gen_Add);
5658 be_set_transform_function(op_And, gen_And);
5659 be_set_transform_function(op_ASM, ia32_gen_ASM);
5660 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5661 be_set_transform_function(op_be_Call, gen_be_Call);
5662 be_set_transform_function(op_be_Copy, gen_be_Copy);
5663 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5664 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5665 be_set_transform_function(op_be_Return, gen_be_Return);
5666 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5667 be_set_transform_function(op_Builtin, gen_Builtin);
5668 be_set_transform_function(op_Cmp, gen_Cmp);
5669 be_set_transform_function(op_Cond, gen_Cond);
5670 be_set_transform_function(op_Const, gen_Const);
5671 be_set_transform_function(op_Conv, gen_Conv);
5672 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5673 be_set_transform_function(op_Div, gen_Div);
5674 be_set_transform_function(op_Eor, gen_Eor);
5675 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5676 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5677 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5678 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5679 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5680 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5681 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5682 be_set_transform_function(op_ia32_l_SarDep, gen_ia32_l_SarDep);
5683 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5684 be_set_transform_function(op_ia32_l_ShlDep, gen_ia32_l_ShlDep);
5685 be_set_transform_function(op_ia32_l_ShlD, gen_ia32_l_ShlD);
5686 be_set_transform_function(op_ia32_l_ShrDep, gen_ia32_l_ShrDep);
5687 be_set_transform_function(op_ia32_l_ShrD, gen_ia32_l_ShrD);
5688 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5689 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5690 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5691 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5692 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5693 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5694 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5695 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5696 be_set_transform_function(op_IJmp, gen_IJmp);
5697 be_set_transform_function(op_Jmp, gen_Jmp);
5698 be_set_transform_function(op_Load, gen_Load);
5699 be_set_transform_function(op_Minus, gen_Minus);
5700 be_set_transform_function(op_Mod, gen_Mod);
5701 be_set_transform_function(op_Mul, gen_Mul);
5702 be_set_transform_function(op_Mulh, gen_Mulh);
5703 be_set_transform_function(op_Mux, gen_Mux);
5704 be_set_transform_function(op_Not, gen_Not);
5705 be_set_transform_function(op_Or, gen_Or);
5706 be_set_transform_function(op_Phi, gen_Phi);
5707 be_set_transform_function(op_Proj, gen_Proj);
5708 be_set_transform_function(op_Rotl, gen_Rotl);
5709 be_set_transform_function(op_Shl, gen_Shl);
5710 be_set_transform_function(op_Shr, gen_Shr);
5711 be_set_transform_function(op_Shrs, gen_Shrs);
5712 be_set_transform_function(op_Store, gen_Store);
5713 be_set_transform_function(op_Sub, gen_Sub);
5714 be_set_transform_function(op_SymConst, gen_SymConst);
5715 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5719 * Pre-transform all unknown and noreg nodes.
5721 static void ia32_pretransform_node(void)
5723 ir_graph *irg = current_ir_graph;
5724 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5726 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5727 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5728 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5730 nomem = get_irg_no_mem(irg);
5731 noreg_GP = ia32_new_NoReg_gp(irg);
5737 * Post-process all calls if we are in SSE mode.
5738 * The ABI requires that the results are in st0, copy them
5739 * to a xmm register.
5741 static void postprocess_fp_call_results(void)
5745 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5746 ir_node *call = call_list[i];
5747 ir_type *mtp = call_types[i];
5750 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5751 ir_type *res_tp = get_method_res_type(mtp, j);
5752 ir_node *res, *new_res;
5753 const ir_edge_t *edge, *next;
5756 if (! is_atomic_type(res_tp)) {
5757 /* no floating point return */
5760 mode = get_type_mode(res_tp);
5761 if (! mode_is_float(mode)) {
5762 /* no floating point return */
5766 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5769 /* now patch the users */
5770 foreach_out_edge_safe(res, edge, next) {
5771 ir_node *succ = get_edge_src_irn(edge);
5774 if (be_is_Keep(succ))
5777 if (is_ia32_xStore(succ)) {
5778 /* an xStore can be patched into an vfst */
5779 dbg_info *db = get_irn_dbg_info(succ);
5780 ir_node *block = get_nodes_block(succ);
5781 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5782 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5783 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5784 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5785 ir_mode *mode = get_ia32_ls_mode(succ);
5787 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5788 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5789 if (is_ia32_use_frame(succ))
5790 set_ia32_use_frame(st);
5791 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5792 set_irn_pinned(st, get_irn_pinned(succ));
5793 set_ia32_op_type(st, ia32_AddrModeD);
5797 if (new_res == NULL) {
5798 dbg_info *db = get_irn_dbg_info(call);
5799 ir_node *block = get_nodes_block(call);
5800 ir_node *frame = get_irg_frame(current_ir_graph);
5801 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5802 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5803 ir_node *vfst, *xld, *new_mem;
5805 /* store st(0) on stack */
5806 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5807 set_ia32_op_type(vfst, ia32_AddrModeD);
5808 set_ia32_use_frame(vfst);
5810 /* load into SSE register */
5811 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5812 set_ia32_op_type(xld, ia32_AddrModeS);
5813 set_ia32_use_frame(xld);
5815 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5816 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5818 if (old_mem != NULL) {
5819 edges_reroute(old_mem, new_mem, current_ir_graph);
5823 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5830 /* do the transformation */
5831 void ia32_transform_graph(ir_graph *irg)
5835 register_transformers();
5836 initial_fpcw = NULL;
5837 ia32_no_pic_adjust = 0;
5839 be_timer_push(T_HEIGHTS);
5840 ia32_heights = heights_new(irg);
5841 be_timer_pop(T_HEIGHTS);
5842 ia32_calculate_non_address_mode_nodes(irg);
5844 /* the transform phase is not safe for CSE (yet) because several nodes get
5845 * attributes set after their creation */
5846 cse_last = get_opt_cse();
5849 call_list = NEW_ARR_F(ir_node *, 0);
5850 call_types = NEW_ARR_F(ir_type *, 0);
5851 be_transform_graph(irg, ia32_pretransform_node);
5853 if (ia32_cg_config.use_sse2)
5854 postprocess_fp_call_results();
5855 DEL_ARR_F(call_types);
5856 DEL_ARR_F(call_list);
5858 set_opt_cse(cse_last);
5860 ia32_free_non_address_mode_nodes();
5861 heights_free(ia32_heights);
5862 ia32_heights = NULL;
5865 void ia32_init_transform(void)
5867 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");