2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
51 #include "../benode.h"
52 #include "../besched.h"
54 #include "../beutil.h"
56 #include "../betranshlp.h"
59 #include "bearch_ia32_t.h"
60 #include "ia32_common_transform.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
71 #include "gen_ia32_regalloc_if.h"
73 /* define this to construct SSE constants instead of load them */
74 #undef CONSTRUCT_SSE_CONST
77 #define SFP_SIGN "0x80000000"
78 #define DFP_SIGN "0x8000000000000000"
79 #define SFP_ABS "0x7FFFFFFF"
80 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
81 #define DFP_INTMAX "9223372036854775807"
82 #define ULL_BIAS "18446744073709551616"
84 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
85 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
86 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
87 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
88 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
90 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
91 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
93 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
95 static ir_node *initial_fpcw = NULL;
98 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
99 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
102 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
103 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
106 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
107 ir_node *op1, ir_node *op2);
109 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
110 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
112 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
113 ir_node *base, ir_node *index, ir_node *mem);
115 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
116 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
119 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
121 static ir_node *create_immediate_or_transform(ir_node *node,
122 char immediate_constraint_type);
124 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
125 dbg_info *dbgi, ir_node *block,
126 ir_node *op, ir_node *orig_node);
128 /* its enough to have those once */
129 static ir_node *nomem, *noreg_GP;
131 /** a list to postprocess all calls */
132 static ir_node **call_list;
133 static ir_type **call_types;
135 /** Return non-zero is a node represents the 0 constant. */
136 static bool is_Const_0(ir_node *node)
138 return is_Const(node) && is_Const_null(node);
141 /** Return non-zero is a node represents the 1 constant. */
142 static bool is_Const_1(ir_node *node)
144 return is_Const(node) && is_Const_one(node);
147 /** Return non-zero is a node represents the -1 constant. */
148 static bool is_Const_Minus_1(ir_node *node)
150 return is_Const(node) && is_Const_all_one(node);
154 * returns true if constant can be created with a simple float command
156 static bool is_simple_x87_Const(ir_node *node)
158 tarval *tv = get_Const_tarval(node);
159 if (tarval_is_null(tv) || tarval_is_one(tv))
162 /* TODO: match all the other float constants */
167 * returns true if constant can be created with a simple float command
169 static bool is_simple_sse_Const(ir_node *node)
171 tarval *tv = get_Const_tarval(node);
172 ir_mode *mode = get_tarval_mode(tv);
177 if (tarval_is_null(tv)
178 #ifdef CONSTRUCT_SSE_CONST
183 #ifdef CONSTRUCT_SSE_CONST
184 if (mode == mode_D) {
185 unsigned val = get_tarval_sub_bits(tv, 0) |
186 (get_tarval_sub_bits(tv, 1) << 8) |
187 (get_tarval_sub_bits(tv, 2) << 16) |
188 (get_tarval_sub_bits(tv, 3) << 24);
190 /* lower 32bit are zero, really a 32bit constant */
193 #endif /* CONSTRUCT_SSE_CONST */
194 /* TODO: match all the other float constants */
199 * Transforms a Const.
201 static ir_node *gen_Const(ir_node *node)
203 ir_node *old_block = get_nodes_block(node);
204 ir_node *block = be_transform_node(old_block);
205 dbg_info *dbgi = get_irn_dbg_info(node);
206 ir_mode *mode = get_irn_mode(node);
208 assert(is_Const(node));
210 if (mode_is_float(mode)) {
215 if (ia32_cg_config.use_sse2) {
216 tarval *tv = get_Const_tarval(node);
217 if (tarval_is_null(tv)) {
218 load = new_bd_ia32_xZero(dbgi, block);
219 set_ia32_ls_mode(load, mode);
221 #ifdef CONSTRUCT_SSE_CONST
222 } else if (tarval_is_one(tv)) {
223 int cnst = mode == mode_F ? 26 : 55;
224 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
225 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
226 ir_node *pslld, *psrld;
228 load = new_bd_ia32_xAllOnes(dbgi, block);
229 set_ia32_ls_mode(load, mode);
230 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
231 set_ia32_ls_mode(pslld, mode);
232 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
233 set_ia32_ls_mode(psrld, mode);
235 #endif /* CONSTRUCT_SSE_CONST */
236 } else if (mode == mode_F) {
237 /* we can place any 32bit constant by using a movd gp, sse */
238 unsigned val = get_tarval_sub_bits(tv, 0) |
239 (get_tarval_sub_bits(tv, 1) << 8) |
240 (get_tarval_sub_bits(tv, 2) << 16) |
241 (get_tarval_sub_bits(tv, 3) << 24);
242 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
243 load = new_bd_ia32_xMovd(dbgi, block, cnst);
244 set_ia32_ls_mode(load, mode);
247 #ifdef CONSTRUCT_SSE_CONST
248 if (mode == mode_D) {
249 unsigned val = get_tarval_sub_bits(tv, 0) |
250 (get_tarval_sub_bits(tv, 1) << 8) |
251 (get_tarval_sub_bits(tv, 2) << 16) |
252 (get_tarval_sub_bits(tv, 3) << 24);
254 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
255 ir_node *cnst, *psllq;
257 /* fine, lower 32bit are zero, produce 32bit value */
258 val = get_tarval_sub_bits(tv, 4) |
259 (get_tarval_sub_bits(tv, 5) << 8) |
260 (get_tarval_sub_bits(tv, 6) << 16) |
261 (get_tarval_sub_bits(tv, 7) << 24);
262 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
263 load = new_bd_ia32_xMovd(dbgi, block, cnst);
264 set_ia32_ls_mode(load, mode);
265 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
266 set_ia32_ls_mode(psllq, mode);
271 #endif /* CONSTRUCT_SSE_CONST */
272 floatent = create_float_const_entity(node);
274 load = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode);
275 set_ia32_op_type(load, ia32_AddrModeS);
276 set_ia32_am_sc(load, floatent);
277 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
278 res = new_r_Proj(block, load, mode_xmm, pn_ia32_xLoad_res);
281 if (is_Const_null(node)) {
282 load = new_bd_ia32_vfldz(dbgi, block);
284 set_ia32_ls_mode(load, mode);
285 } else if (is_Const_one(node)) {
286 load = new_bd_ia32_vfld1(dbgi, block);
288 set_ia32_ls_mode(load, mode);
293 floatent = create_float_const_entity(node);
294 /* create_float_const_ent is smart and sometimes creates
296 ls_mode = get_type_mode(get_entity_type(floatent));
298 if (env_cg->birg->main_env->options->pic) {
299 base = arch_code_generator_get_pic_base(env_cg);
304 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
306 set_ia32_op_type(load, ia32_AddrModeS);
307 set_ia32_am_sc(load, floatent);
308 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
309 res = new_r_Proj(block, load, mode_vfp, pn_ia32_vfld_res);
312 #ifdef CONSTRUCT_SSE_CONST
314 #endif /* CONSTRUCT_SSE_CONST */
315 SET_IA32_ORIG_NODE(load, node);
317 be_dep_on_frame(load);
319 } else { /* non-float mode */
321 tarval *tv = get_Const_tarval(node);
324 tv = tarval_convert_to(tv, mode_Iu);
326 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
328 panic("couldn't convert constant tarval (%+F)", node);
330 val = get_tarval_long(tv);
332 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
333 SET_IA32_ORIG_NODE(cnst, node);
335 be_dep_on_frame(cnst);
341 * Transforms a SymConst.
343 static ir_node *gen_SymConst(ir_node *node)
345 ir_node *old_block = get_nodes_block(node);
346 ir_node *block = be_transform_node(old_block);
347 dbg_info *dbgi = get_irn_dbg_info(node);
348 ir_mode *mode = get_irn_mode(node);
351 if (mode_is_float(mode)) {
352 if (ia32_cg_config.use_sse2)
353 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
355 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
356 set_ia32_am_sc(cnst, get_SymConst_entity(node));
357 set_ia32_use_frame(cnst);
361 if (get_SymConst_kind(node) != symconst_addr_ent) {
362 panic("backend only support symconst_addr_ent (at %+F)", node);
364 entity = get_SymConst_entity(node);
365 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
368 SET_IA32_ORIG_NODE(cnst, node);
370 be_dep_on_frame(cnst);
375 * Create a float type for the given mode and cache it.
377 * @param mode the mode for the float type (might be integer mode for SSE2 types)
378 * @param align alignment
380 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
386 if (mode == mode_Iu) {
387 static ir_type *int_Iu[16] = {NULL, };
389 if (int_Iu[align] == NULL) {
390 int_Iu[align] = tp = new_type_primitive(mode);
391 /* set the specified alignment */
392 set_type_alignment_bytes(tp, align);
394 return int_Iu[align];
395 } else if (mode == mode_Lu) {
396 static ir_type *int_Lu[16] = {NULL, };
398 if (int_Lu[align] == NULL) {
399 int_Lu[align] = tp = new_type_primitive(mode);
400 /* set the specified alignment */
401 set_type_alignment_bytes(tp, align);
403 return int_Lu[align];
404 } else if (mode == mode_F) {
405 static ir_type *float_F[16] = {NULL, };
407 if (float_F[align] == NULL) {
408 float_F[align] = tp = new_type_primitive(mode);
409 /* set the specified alignment */
410 set_type_alignment_bytes(tp, align);
412 return float_F[align];
413 } else if (mode == mode_D) {
414 static ir_type *float_D[16] = {NULL, };
416 if (float_D[align] == NULL) {
417 float_D[align] = tp = new_type_primitive(mode);
418 /* set the specified alignment */
419 set_type_alignment_bytes(tp, align);
421 return float_D[align];
423 static ir_type *float_E[16] = {NULL, };
425 if (float_E[align] == NULL) {
426 float_E[align] = tp = new_type_primitive(mode);
427 /* set the specified alignment */
428 set_type_alignment_bytes(tp, align);
430 return float_E[align];
435 * Create a float[2] array type for the given atomic type.
437 * @param tp the atomic type
439 static ir_type *ia32_create_float_array(ir_type *tp)
441 ir_mode *mode = get_type_mode(tp);
442 unsigned align = get_type_alignment_bytes(tp);
447 if (mode == mode_F) {
448 static ir_type *float_F[16] = {NULL, };
450 if (float_F[align] != NULL)
451 return float_F[align];
452 arr = float_F[align] = new_type_array(1, tp);
453 } else if (mode == mode_D) {
454 static ir_type *float_D[16] = {NULL, };
456 if (float_D[align] != NULL)
457 return float_D[align];
458 arr = float_D[align] = new_type_array(1, tp);
460 static ir_type *float_E[16] = {NULL, };
462 if (float_E[align] != NULL)
463 return float_E[align];
464 arr = float_E[align] = new_type_array(1, tp);
466 set_type_alignment_bytes(arr, align);
467 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
468 set_type_state(arr, layout_fixed);
472 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
473 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
475 static const struct {
476 const char *ent_name;
477 const char *cnst_str;
480 } names [ia32_known_const_max] = {
481 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
482 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
483 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
484 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
485 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
487 static ir_entity *ent_cache[ia32_known_const_max];
489 const char *ent_name, *cnst_str;
495 ent_name = names[kct].ent_name;
496 if (! ent_cache[kct]) {
497 cnst_str = names[kct].cnst_str;
499 switch (names[kct].mode) {
500 case 0: mode = mode_Iu; break;
501 case 1: mode = mode_Lu; break;
502 default: mode = mode_F; break;
504 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
505 tp = ia32_create_float_type(mode, names[kct].align);
507 if (kct == ia32_ULLBIAS)
508 tp = ia32_create_float_array(tp);
509 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
511 set_entity_ld_ident(ent, get_entity_ident(ent));
512 set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
514 if (kct == ia32_ULLBIAS) {
515 ir_initializer_t *initializer = create_initializer_compound(2);
517 set_initializer_compound_value(initializer, 0,
518 create_initializer_tarval(get_tarval_null(mode)));
519 set_initializer_compound_value(initializer, 1,
520 create_initializer_tarval(tv));
522 set_entity_initializer(ent, initializer);
524 set_entity_initializer(ent, create_initializer_tarval(tv));
527 /* cache the entry */
528 ent_cache[kct] = ent;
531 return ent_cache[kct];
535 * return true if the node is a Proj(Load) and could be used in source address
536 * mode for another node. Will return only true if the @p other node is not
537 * dependent on the memory of the Load (for binary operations use the other
538 * input here, for unary operations use NULL).
540 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
541 ir_node *other, ir_node *other2, match_flags_t flags)
546 /* float constants are always available */
547 if (is_Const(node)) {
548 ir_mode *mode = get_irn_mode(node);
549 if (mode_is_float(mode)) {
550 if (ia32_cg_config.use_sse2) {
551 if (is_simple_sse_Const(node))
554 if (is_simple_x87_Const(node))
557 if (get_irn_n_edges(node) > 1)
565 load = get_Proj_pred(node);
566 pn = get_Proj_proj(node);
567 if (!is_Load(load) || pn != pn_Load_res)
569 if (get_nodes_block(load) != block)
571 /* we only use address mode if we're the only user of the load */
572 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
574 /* in some edge cases with address mode we might reach the load normally
575 * and through some AM sequence, if it is already materialized then we
576 * can't create an AM node from it */
577 if (be_is_transformed(node))
580 /* don't do AM if other node inputs depend on the load (via mem-proj) */
581 if (other != NULL && prevents_AM(block, load, other))
584 if (other2 != NULL && prevents_AM(block, load, other2))
590 typedef struct ia32_address_mode_t ia32_address_mode_t;
591 struct ia32_address_mode_t {
596 ia32_op_type_t op_type;
600 unsigned commutative : 1;
601 unsigned ins_permuted : 1;
604 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
606 /* construct load address */
607 memset(addr, 0, sizeof(addr[0]));
608 ia32_create_address_mode(addr, ptr, 0);
610 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
611 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
612 addr->mem = be_transform_node(mem);
615 static void build_address(ia32_address_mode_t *am, ir_node *node,
616 ia32_create_am_flags_t flags)
618 ia32_address_t *addr = &am->addr;
624 if (is_Const(node)) {
625 ir_entity *entity = create_float_const_entity(node);
626 addr->base = noreg_GP;
627 addr->index = noreg_GP;
629 addr->symconst_ent = entity;
631 am->ls_mode = get_type_mode(get_entity_type(entity));
632 am->pinned = op_pin_state_floats;
636 load = get_Proj_pred(node);
637 ptr = get_Load_ptr(load);
638 mem = get_Load_mem(load);
639 new_mem = be_transform_node(mem);
640 am->pinned = get_irn_pinned(load);
641 am->ls_mode = get_Load_mode(load);
642 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
645 /* construct load address */
646 ia32_create_address_mode(addr, ptr, flags);
648 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
649 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
653 static void set_address(ir_node *node, const ia32_address_t *addr)
655 set_ia32_am_scale(node, addr->scale);
656 set_ia32_am_sc(node, addr->symconst_ent);
657 set_ia32_am_offs_int(node, addr->offset);
658 if (addr->symconst_sign)
659 set_ia32_am_sc_sign(node);
661 set_ia32_use_frame(node);
662 set_ia32_frame_ent(node, addr->frame_entity);
666 * Apply attributes of a given address mode to a node.
668 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
670 set_address(node, &am->addr);
672 set_ia32_op_type(node, am->op_type);
673 set_ia32_ls_mode(node, am->ls_mode);
674 if (am->pinned == op_pin_state_pinned) {
675 /* beware: some nodes are already pinned and did not allow to change the state */
676 if (get_irn_pinned(node) != op_pin_state_pinned)
677 set_irn_pinned(node, op_pin_state_pinned);
680 set_ia32_commutative(node);
684 * Check, if a given node is a Down-Conv, ie. a integer Conv
685 * from a mode with a mode with more bits to a mode with lesser bits.
686 * Moreover, we return only true if the node has not more than 1 user.
688 * @param node the node
689 * @return non-zero if node is a Down-Conv
691 static int is_downconv(const ir_node *node)
699 /* we only want to skip the conv when we're the only user
700 * (not optimal but for now...)
702 if (get_irn_n_edges(node) > 1)
705 src_mode = get_irn_mode(get_Conv_op(node));
706 dest_mode = get_irn_mode(node);
708 ia32_mode_needs_gp_reg(src_mode) &&
709 ia32_mode_needs_gp_reg(dest_mode) &&
710 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
713 /* Skip all Down-Conv's on a given node and return the resulting node. */
714 ir_node *ia32_skip_downconv(ir_node *node)
716 while (is_downconv(node))
717 node = get_Conv_op(node);
722 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
724 ir_mode *mode = get_irn_mode(node);
729 if (mode_is_signed(mode)) {
734 block = get_nodes_block(node);
735 dbgi = get_irn_dbg_info(node);
737 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
741 * matches operands of a node into ia32 addressing/operand modes. This covers
742 * usage of source address mode, immediates, operations with non 32-bit modes,
744 * The resulting data is filled into the @p am struct. block is the block
745 * of the node whose arguments are matched. op1, op2 are the first and second
746 * input that are matched (op1 may be NULL). other_op is another unrelated
747 * input that is not matched! but which is needed sometimes to check if AM
748 * for op1/op2 is legal.
749 * @p flags describes the supported modes of the operation in detail.
751 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
752 ir_node *op1, ir_node *op2, ir_node *other_op,
755 ia32_address_t *addr = &am->addr;
756 ir_mode *mode = get_irn_mode(op2);
757 int mode_bits = get_mode_size_bits(mode);
758 ir_node *new_op1, *new_op2;
760 unsigned commutative;
761 int use_am_and_immediates;
764 memset(am, 0, sizeof(am[0]));
766 commutative = (flags & match_commutative) != 0;
767 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
768 use_am = (flags & match_am) != 0;
769 use_immediate = (flags & match_immediate) != 0;
770 assert(!use_am_and_immediates || use_immediate);
773 assert(!commutative || op1 != NULL);
774 assert(use_am || !(flags & match_8bit_am));
775 assert(use_am || !(flags & match_16bit_am));
777 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
778 (mode_bits == 16 && !(flags & match_16bit_am))) {
782 /* we can simply skip downconvs for mode neutral nodes: the upper bits
783 * can be random for these operations */
784 if (flags & match_mode_neutral) {
785 op2 = ia32_skip_downconv(op2);
787 op1 = ia32_skip_downconv(op1);
791 /* match immediates. firm nodes are normalized: constants are always on the
794 if (!(flags & match_try_am) && use_immediate) {
795 new_op2 = try_create_Immediate(op2, 0);
798 if (new_op2 == NULL &&
799 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
800 build_address(am, op2, 0);
801 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
802 if (mode_is_float(mode)) {
803 new_op2 = ia32_new_NoReg_vfp(env_cg);
807 am->op_type = ia32_AddrModeS;
808 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
810 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
812 build_address(am, op1, 0);
814 if (mode_is_float(mode)) {
815 noreg = ia32_new_NoReg_vfp(env_cg);
820 if (new_op2 != NULL) {
823 new_op1 = be_transform_node(op2);
825 am->ins_permuted = 1;
827 am->op_type = ia32_AddrModeS;
830 am->op_type = ia32_Normal;
832 if (flags & match_try_am) {
838 mode = get_irn_mode(op2);
839 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
840 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
842 new_op2 = create_upconv(op2, NULL);
843 am->ls_mode = mode_Iu;
845 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
847 new_op2 = be_transform_node(op2);
848 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
851 if (addr->base == NULL)
852 addr->base = noreg_GP;
853 if (addr->index == NULL)
854 addr->index = noreg_GP;
855 if (addr->mem == NULL)
858 am->new_op1 = new_op1;
859 am->new_op2 = new_op2;
860 am->commutative = commutative;
864 * "Fixes" a node that uses address mode by turning it into mode_T
865 * and returning a pn_ia32_res Proj.
867 * @param node the node
868 * @param am its address mode
870 * @return a Proj(pn_ia32_res) if a memory address mode is used,
873 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
878 if (am->mem_proj == NULL)
881 /* we have to create a mode_T so the old MemProj can attach to us */
882 mode = get_irn_mode(node);
883 load = get_Proj_pred(am->mem_proj);
885 be_set_transformed_node(load, node);
887 if (mode != mode_T) {
888 set_irn_mode(node, mode_T);
889 return new_rd_Proj(NULL, get_nodes_block(node), node, mode, pn_ia32_res);
896 * Construct a standard binary operation, set AM and immediate if required.
898 * @param node The original node for which the binop is created
899 * @param op1 The first operand
900 * @param op2 The second operand
901 * @param func The node constructor function
902 * @return The constructed ia32 node.
904 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
905 construct_binop_func *func, match_flags_t flags)
908 ir_node *block, *new_block, *new_node;
909 ia32_address_mode_t am;
910 ia32_address_t *addr = &am.addr;
912 block = get_nodes_block(node);
913 match_arguments(&am, block, op1, op2, NULL, flags);
915 dbgi = get_irn_dbg_info(node);
916 new_block = be_transform_node(block);
917 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
918 am.new_op1, am.new_op2);
919 set_am_attributes(new_node, &am);
920 /* we can't use source address mode anymore when using immediates */
921 if (!(flags & match_am_and_immediates) &&
922 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
923 set_ia32_am_support(new_node, ia32_am_none);
924 SET_IA32_ORIG_NODE(new_node, node);
926 new_node = fix_mem_proj(new_node, &am);
932 * Generic names for the inputs of an ia32 binary op.
935 n_ia32_l_binop_left, /**< ia32 left input */
936 n_ia32_l_binop_right, /**< ia32 right input */
937 n_ia32_l_binop_eflags /**< ia32 eflags input */
939 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
940 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
941 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
942 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
943 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
944 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
947 * Construct a binary operation which also consumes the eflags.
949 * @param node The node to transform
950 * @param func The node constructor function
951 * @param flags The match flags
952 * @return The constructor ia32 node
954 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
957 ir_node *src_block = get_nodes_block(node);
958 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
959 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
960 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
962 ir_node *block, *new_node, *new_eflags;
963 ia32_address_mode_t am;
964 ia32_address_t *addr = &am.addr;
966 match_arguments(&am, src_block, op1, op2, eflags, flags);
968 dbgi = get_irn_dbg_info(node);
969 block = be_transform_node(src_block);
970 new_eflags = be_transform_node(eflags);
971 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
972 am.new_op1, am.new_op2, new_eflags);
973 set_am_attributes(new_node, &am);
974 /* we can't use source address mode anymore when using immediates */
975 if (!(flags & match_am_and_immediates) &&
976 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
977 set_ia32_am_support(new_node, ia32_am_none);
978 SET_IA32_ORIG_NODE(new_node, node);
980 new_node = fix_mem_proj(new_node, &am);
985 static ir_node *get_fpcw(void)
988 if (initial_fpcw != NULL)
991 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
992 &ia32_fp_cw_regs[REG_FPCW]);
993 initial_fpcw = be_transform_node(fpcw);
999 * Construct a standard binary operation, set AM and immediate if required.
1001 * @param op1 The first operand
1002 * @param op2 The second operand
1003 * @param func The node constructor function
1004 * @return The constructed ia32 node.
1006 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1007 construct_binop_float_func *func)
1009 ir_mode *mode = get_irn_mode(node);
1011 ir_node *block, *new_block, *new_node;
1012 ia32_address_mode_t am;
1013 ia32_address_t *addr = &am.addr;
1014 ia32_x87_attr_t *attr;
1015 /* All operations are considered commutative, because there are reverse
1017 match_flags_t flags = match_commutative;
1019 /* happens for div nodes... */
1021 mode = get_divop_resmod(node);
1023 /* cannot use address mode with long double on x87 */
1024 if (get_mode_size_bits(mode) <= 64)
1027 block = get_nodes_block(node);
1028 match_arguments(&am, block, op1, op2, NULL, flags);
1030 dbgi = get_irn_dbg_info(node);
1031 new_block = be_transform_node(block);
1032 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1033 am.new_op1, am.new_op2, get_fpcw());
1034 set_am_attributes(new_node, &am);
1036 attr = get_ia32_x87_attr(new_node);
1037 attr->attr.data.ins_permuted = am.ins_permuted;
1039 SET_IA32_ORIG_NODE(new_node, node);
1041 new_node = fix_mem_proj(new_node, &am);
1047 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1049 * @param op1 The first operand
1050 * @param op2 The second operand
1051 * @param func The node constructor function
1052 * @return The constructed ia32 node.
1054 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1055 construct_shift_func *func,
1056 match_flags_t flags)
1059 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1061 assert(! mode_is_float(get_irn_mode(node)));
1062 assert(flags & match_immediate);
1063 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1065 if (flags & match_mode_neutral) {
1066 op1 = ia32_skip_downconv(op1);
1067 new_op1 = be_transform_node(op1);
1068 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1069 new_op1 = create_upconv(op1, node);
1071 new_op1 = be_transform_node(op1);
1074 /* the shift amount can be any mode that is bigger than 5 bits, since all
1075 * other bits are ignored anyway */
1076 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1077 ir_node *const op = get_Conv_op(op2);
1078 if (mode_is_float(get_irn_mode(op)))
1081 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1083 new_op2 = create_immediate_or_transform(op2, 0);
1085 dbgi = get_irn_dbg_info(node);
1086 block = get_nodes_block(node);
1087 new_block = be_transform_node(block);
1088 new_node = func(dbgi, new_block, new_op1, new_op2);
1089 SET_IA32_ORIG_NODE(new_node, node);
1091 /* lowered shift instruction may have a dependency operand, handle it here */
1092 if (get_irn_arity(node) == 3) {
1093 /* we have a dependency */
1094 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1095 add_irn_dep(new_node, new_dep);
1103 * Construct a standard unary operation, set AM and immediate if required.
1105 * @param op The operand
1106 * @param func The node constructor function
1107 * @return The constructed ia32 node.
1109 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1110 match_flags_t flags)
1113 ir_node *block, *new_block, *new_op, *new_node;
1115 assert(flags == 0 || flags == match_mode_neutral);
1116 if (flags & match_mode_neutral) {
1117 op = ia32_skip_downconv(op);
1120 new_op = be_transform_node(op);
1121 dbgi = get_irn_dbg_info(node);
1122 block = get_nodes_block(node);
1123 new_block = be_transform_node(block);
1124 new_node = func(dbgi, new_block, new_op);
1126 SET_IA32_ORIG_NODE(new_node, node);
1131 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1132 ia32_address_t *addr)
1134 ir_node *base, *index, *res;
1140 base = be_transform_node(base);
1143 index = addr->index;
1144 if (index == NULL) {
1147 index = be_transform_node(index);
1150 res = new_bd_ia32_Lea(dbgi, block, base, index);
1151 set_address(res, addr);
1157 * Returns non-zero if a given address mode has a symbolic or
1158 * numerical offset != 0.
1160 static int am_has_immediates(const ia32_address_t *addr)
1162 return addr->offset != 0 || addr->symconst_ent != NULL
1163 || addr->frame_entity || addr->use_frame;
1167 * Creates an ia32 Add.
1169 * @return the created ia32 Add node
1171 static ir_node *gen_Add(ir_node *node)
1173 ir_mode *mode = get_irn_mode(node);
1174 ir_node *op1 = get_Add_left(node);
1175 ir_node *op2 = get_Add_right(node);
1177 ir_node *block, *new_block, *new_node, *add_immediate_op;
1178 ia32_address_t addr;
1179 ia32_address_mode_t am;
1181 if (mode_is_float(mode)) {
1182 if (ia32_cg_config.use_sse2)
1183 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1184 match_commutative | match_am);
1186 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1189 ia32_mark_non_am(node);
1191 op2 = ia32_skip_downconv(op2);
1192 op1 = ia32_skip_downconv(op1);
1196 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1197 * 1. Add with immediate -> Lea
1198 * 2. Add with possible source address mode -> Add
1199 * 3. Otherwise -> Lea
1201 memset(&addr, 0, sizeof(addr));
1202 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1203 add_immediate_op = NULL;
1205 dbgi = get_irn_dbg_info(node);
1206 block = get_nodes_block(node);
1207 new_block = be_transform_node(block);
1210 if (addr.base == NULL && addr.index == NULL) {
1211 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1212 addr.symconst_sign, 0, addr.offset);
1213 be_dep_on_frame(new_node);
1214 SET_IA32_ORIG_NODE(new_node, node);
1217 /* add with immediate? */
1218 if (addr.index == NULL) {
1219 add_immediate_op = addr.base;
1220 } else if (addr.base == NULL && addr.scale == 0) {
1221 add_immediate_op = addr.index;
1224 if (add_immediate_op != NULL) {
1225 if (!am_has_immediates(&addr)) {
1226 #ifdef DEBUG_libfirm
1227 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1230 return be_transform_node(add_immediate_op);
1233 new_node = create_lea_from_address(dbgi, new_block, &addr);
1234 SET_IA32_ORIG_NODE(new_node, node);
1238 /* test if we can use source address mode */
1239 match_arguments(&am, block, op1, op2, NULL, match_commutative
1240 | match_mode_neutral | match_am | match_immediate | match_try_am);
1242 /* construct an Add with source address mode */
1243 if (am.op_type == ia32_AddrModeS) {
1244 ia32_address_t *am_addr = &am.addr;
1245 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1246 am_addr->index, am_addr->mem, am.new_op1,
1248 set_am_attributes(new_node, &am);
1249 SET_IA32_ORIG_NODE(new_node, node);
1251 new_node = fix_mem_proj(new_node, &am);
1256 /* otherwise construct a lea */
1257 new_node = create_lea_from_address(dbgi, new_block, &addr);
1258 SET_IA32_ORIG_NODE(new_node, node);
1263 * Creates an ia32 Mul.
1265 * @return the created ia32 Mul node
1267 static ir_node *gen_Mul(ir_node *node)
1269 ir_node *op1 = get_Mul_left(node);
1270 ir_node *op2 = get_Mul_right(node);
1271 ir_mode *mode = get_irn_mode(node);
1273 if (mode_is_float(mode)) {
1274 if (ia32_cg_config.use_sse2)
1275 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1276 match_commutative | match_am);
1278 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1280 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1281 match_commutative | match_am | match_mode_neutral |
1282 match_immediate | match_am_and_immediates);
1286 * Creates an ia32 Mulh.
1287 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1288 * this result while Mul returns the lower 32 bit.
1290 * @return the created ia32 Mulh node
1292 static ir_node *gen_Mulh(ir_node *node)
1294 ir_node *block = get_nodes_block(node);
1295 ir_node *new_block = be_transform_node(block);
1296 dbg_info *dbgi = get_irn_dbg_info(node);
1297 ir_node *op1 = get_Mulh_left(node);
1298 ir_node *op2 = get_Mulh_right(node);
1299 ir_mode *mode = get_irn_mode(node);
1301 ir_node *proj_res_high;
1303 if (get_mode_size_bits(mode) != 32) {
1304 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1307 if (mode_is_signed(mode)) {
1308 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1309 proj_res_high = new_rd_Proj(dbgi, new_block, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1311 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1312 proj_res_high = new_rd_Proj(dbgi, new_block, new_node, mode_Iu, pn_ia32_Mul_res_high);
1314 return proj_res_high;
1318 * Creates an ia32 And.
1320 * @return The created ia32 And node
1322 static ir_node *gen_And(ir_node *node)
1324 ir_node *op1 = get_And_left(node);
1325 ir_node *op2 = get_And_right(node);
1326 assert(! mode_is_float(get_irn_mode(node)));
1328 /* is it a zero extension? */
1329 if (is_Const(op2)) {
1330 tarval *tv = get_Const_tarval(op2);
1331 long v = get_tarval_long(tv);
1333 if (v == 0xFF || v == 0xFFFF) {
1334 dbg_info *dbgi = get_irn_dbg_info(node);
1335 ir_node *block = get_nodes_block(node);
1342 assert(v == 0xFFFF);
1345 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1350 return gen_binop(node, op1, op2, new_bd_ia32_And,
1351 match_commutative | match_mode_neutral | match_am | match_immediate);
1357 * Creates an ia32 Or.
1359 * @return The created ia32 Or node
1361 static ir_node *gen_Or(ir_node *node)
1363 ir_node *op1 = get_Or_left(node);
1364 ir_node *op2 = get_Or_right(node);
1366 assert (! mode_is_float(get_irn_mode(node)));
1367 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1368 | match_mode_neutral | match_am | match_immediate);
1374 * Creates an ia32 Eor.
1376 * @return The created ia32 Eor node
1378 static ir_node *gen_Eor(ir_node *node)
1380 ir_node *op1 = get_Eor_left(node);
1381 ir_node *op2 = get_Eor_right(node);
1383 assert(! mode_is_float(get_irn_mode(node)));
1384 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1385 | match_mode_neutral | match_am | match_immediate);
1390 * Creates an ia32 Sub.
1392 * @return The created ia32 Sub node
1394 static ir_node *gen_Sub(ir_node *node)
1396 ir_node *op1 = get_Sub_left(node);
1397 ir_node *op2 = get_Sub_right(node);
1398 ir_mode *mode = get_irn_mode(node);
1400 if (mode_is_float(mode)) {
1401 if (ia32_cg_config.use_sse2)
1402 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1404 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1407 if (is_Const(op2)) {
1408 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1412 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1413 | match_am | match_immediate);
1416 static ir_node *transform_AM_mem(ir_node *const block,
1417 ir_node *const src_val,
1418 ir_node *const src_mem,
1419 ir_node *const am_mem)
1421 if (is_NoMem(am_mem)) {
1422 return be_transform_node(src_mem);
1423 } else if (is_Proj(src_val) &&
1425 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1426 /* avoid memory loop */
1428 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1429 ir_node *const ptr_pred = get_Proj_pred(src_val);
1430 int const arity = get_Sync_n_preds(src_mem);
1435 NEW_ARR_A(ir_node*, ins, arity + 1);
1437 /* NOTE: This sometimes produces dead-code because the old sync in
1438 * src_mem might not be used anymore, we should detect this case
1439 * and kill the sync... */
1440 for (i = arity - 1; i >= 0; --i) {
1441 ir_node *const pred = get_Sync_pred(src_mem, i);
1443 /* avoid memory loop */
1444 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1447 ins[n++] = be_transform_node(pred);
1452 return new_r_Sync(block, n, ins);
1456 ins[0] = be_transform_node(src_mem);
1458 return new_r_Sync(block, 2, ins);
1463 * Create a 32bit to 64bit signed extension.
1465 * @param dbgi debug info
1466 * @param block the block where node nodes should be placed
1467 * @param val the value to extend
1468 * @param orig the original node
1470 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1471 ir_node *val, const ir_node *orig)
1476 if (ia32_cg_config.use_short_sex_eax) {
1477 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1478 be_dep_on_frame(pval);
1479 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1481 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1482 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1484 SET_IA32_ORIG_NODE(res, orig);
1489 * Generates an ia32 DivMod with additional infrastructure for the
1490 * register allocator if needed.
1492 static ir_node *create_Div(ir_node *node)
1494 dbg_info *dbgi = get_irn_dbg_info(node);
1495 ir_node *block = get_nodes_block(node);
1496 ir_node *new_block = be_transform_node(block);
1503 ir_node *sign_extension;
1504 ia32_address_mode_t am;
1505 ia32_address_t *addr = &am.addr;
1507 /* the upper bits have random contents for smaller modes */
1508 switch (get_irn_opcode(node)) {
1510 op1 = get_Div_left(node);
1511 op2 = get_Div_right(node);
1512 mem = get_Div_mem(node);
1513 mode = get_Div_resmode(node);
1516 op1 = get_Mod_left(node);
1517 op2 = get_Mod_right(node);
1518 mem = get_Mod_mem(node);
1519 mode = get_Mod_resmode(node);
1522 op1 = get_DivMod_left(node);
1523 op2 = get_DivMod_right(node);
1524 mem = get_DivMod_mem(node);
1525 mode = get_DivMod_resmode(node);
1528 panic("invalid divmod node %+F", node);
1531 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1533 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1534 is the memory of the consumed address. We can have only the second op as address
1535 in Div nodes, so check only op2. */
1536 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1538 if (mode_is_signed(mode)) {
1539 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1540 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1541 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1543 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1544 be_dep_on_frame(sign_extension);
1546 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1547 addr->index, new_mem, am.new_op2,
1548 am.new_op1, sign_extension);
1551 set_irn_pinned(new_node, get_irn_pinned(node));
1553 set_am_attributes(new_node, &am);
1554 SET_IA32_ORIG_NODE(new_node, node);
1556 new_node = fix_mem_proj(new_node, &am);
1562 * Generates an ia32 Mod.
1564 static ir_node *gen_Mod(ir_node *node)
1566 return create_Div(node);
1570 * Generates an ia32 Div.
1572 static ir_node *gen_Div(ir_node *node)
1574 return create_Div(node);
1578 * Generates an ia32 DivMod.
1580 static ir_node *gen_DivMod(ir_node *node)
1582 return create_Div(node);
1588 * Creates an ia32 floating Div.
1590 * @return The created ia32 xDiv node
1592 static ir_node *gen_Quot(ir_node *node)
1594 ir_node *op1 = get_Quot_left(node);
1595 ir_node *op2 = get_Quot_right(node);
1597 if (ia32_cg_config.use_sse2) {
1598 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1600 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1606 * Creates an ia32 Shl.
1608 * @return The created ia32 Shl node
1610 static ir_node *gen_Shl(ir_node *node)
1612 ir_node *left = get_Shl_left(node);
1613 ir_node *right = get_Shl_right(node);
1615 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1616 match_mode_neutral | match_immediate);
1620 * Creates an ia32 Shr.
1622 * @return The created ia32 Shr node
1624 static ir_node *gen_Shr(ir_node *node)
1626 ir_node *left = get_Shr_left(node);
1627 ir_node *right = get_Shr_right(node);
1629 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1635 * Creates an ia32 Sar.
1637 * @return The created ia32 Shrs node
1639 static ir_node *gen_Shrs(ir_node *node)
1641 ir_node *left = get_Shrs_left(node);
1642 ir_node *right = get_Shrs_right(node);
1644 if (is_Const(right)) {
1645 tarval *tv = get_Const_tarval(right);
1646 long val = get_tarval_long(tv);
1648 /* this is a sign extension */
1649 dbg_info *dbgi = get_irn_dbg_info(node);
1650 ir_node *block = be_transform_node(get_nodes_block(node));
1651 ir_node *new_op = be_transform_node(left);
1653 return create_sex_32_64(dbgi, block, new_op, node);
1657 /* 8 or 16 bit sign extension? */
1658 if (is_Const(right) && is_Shl(left)) {
1659 ir_node *shl_left = get_Shl_left(left);
1660 ir_node *shl_right = get_Shl_right(left);
1661 if (is_Const(shl_right)) {
1662 tarval *tv1 = get_Const_tarval(right);
1663 tarval *tv2 = get_Const_tarval(shl_right);
1664 if (tv1 == tv2 && tarval_is_long(tv1)) {
1665 long val = get_tarval_long(tv1);
1666 if (val == 16 || val == 24) {
1667 dbg_info *dbgi = get_irn_dbg_info(node);
1668 ir_node *block = get_nodes_block(node);
1678 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1687 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1693 * Creates an ia32 Rol.
1695 * @param op1 The first operator
1696 * @param op2 The second operator
1697 * @return The created ia32 RotL node
1699 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1701 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1707 * Creates an ia32 Ror.
1708 * NOTE: There is no RotR with immediate because this would always be a RotL
1709 * "imm-mode_size_bits" which can be pre-calculated.
1711 * @param op1 The first operator
1712 * @param op2 The second operator
1713 * @return The created ia32 RotR node
1715 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1717 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1723 * Creates an ia32 RotR or RotL (depending on the found pattern).
1725 * @return The created ia32 RotL or RotR node
1727 static ir_node *gen_Rotl(ir_node *node)
1729 ir_node *rotate = NULL;
1730 ir_node *op1 = get_Rotl_left(node);
1731 ir_node *op2 = get_Rotl_right(node);
1733 /* Firm has only RotL, so we are looking for a right (op2)
1734 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1735 that means we can create a RotR instead of an Add and a RotL */
1739 ir_node *left = get_Add_left(add);
1740 ir_node *right = get_Add_right(add);
1741 if (is_Const(right)) {
1742 tarval *tv = get_Const_tarval(right);
1743 ir_mode *mode = get_irn_mode(node);
1744 long bits = get_mode_size_bits(mode);
1746 if (is_Minus(left) &&
1747 tarval_is_long(tv) &&
1748 get_tarval_long(tv) == bits &&
1751 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1752 rotate = gen_Ror(node, op1, get_Minus_op(left));
1757 if (rotate == NULL) {
1758 rotate = gen_Rol(node, op1, op2);
1767 * Transforms a Minus node.
1769 * @return The created ia32 Minus node
1771 static ir_node *gen_Minus(ir_node *node)
1773 ir_node *op = get_Minus_op(node);
1774 ir_node *block = be_transform_node(get_nodes_block(node));
1775 dbg_info *dbgi = get_irn_dbg_info(node);
1776 ir_mode *mode = get_irn_mode(node);
1781 if (mode_is_float(mode)) {
1782 ir_node *new_op = be_transform_node(op);
1783 if (ia32_cg_config.use_sse2) {
1784 /* TODO: non-optimal... if we have many xXors, then we should
1785 * rather create a load for the const and use that instead of
1786 * several AM nodes... */
1787 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1789 new_node = new_bd_ia32_xXor(dbgi, block, noreg_GP, noreg_GP,
1790 nomem, new_op, noreg_xmm);
1792 size = get_mode_size_bits(mode);
1793 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1795 set_ia32_am_sc(new_node, ent);
1796 set_ia32_op_type(new_node, ia32_AddrModeS);
1797 set_ia32_ls_mode(new_node, mode);
1799 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1802 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1805 SET_IA32_ORIG_NODE(new_node, node);
1811 * Transforms a Not node.
1813 * @return The created ia32 Not node
1815 static ir_node *gen_Not(ir_node *node)
1817 ir_node *op = get_Not_op(node);
1819 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1820 assert (! mode_is_float(get_irn_mode(node)));
1822 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1828 * Transforms an Abs node.
1830 * @return The created ia32 Abs node
1832 static ir_node *gen_Abs(ir_node *node)
1834 ir_node *block = get_nodes_block(node);
1835 ir_node *new_block = be_transform_node(block);
1836 ir_node *op = get_Abs_op(node);
1837 dbg_info *dbgi = get_irn_dbg_info(node);
1838 ir_mode *mode = get_irn_mode(node);
1844 if (mode_is_float(mode)) {
1845 new_op = be_transform_node(op);
1847 if (ia32_cg_config.use_sse2) {
1848 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1849 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_GP, noreg_GP,
1850 nomem, new_op, noreg_fp);
1852 size = get_mode_size_bits(mode);
1853 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1855 set_ia32_am_sc(new_node, ent);
1857 SET_IA32_ORIG_NODE(new_node, node);
1859 set_ia32_op_type(new_node, ia32_AddrModeS);
1860 set_ia32_ls_mode(new_node, mode);
1862 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1863 SET_IA32_ORIG_NODE(new_node, node);
1866 ir_node *xor, *sign_extension;
1868 if (get_mode_size_bits(mode) == 32) {
1869 new_op = be_transform_node(op);
1871 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1874 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1876 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1877 nomem, new_op, sign_extension);
1878 SET_IA32_ORIG_NODE(xor, node);
1880 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1881 nomem, xor, sign_extension);
1882 SET_IA32_ORIG_NODE(new_node, node);
1889 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1891 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1893 dbg_info *dbgi = get_irn_dbg_info(cmp);
1894 ir_node *block = get_nodes_block(cmp);
1895 ir_node *new_block = be_transform_node(block);
1896 ir_node *op1 = be_transform_node(x);
1897 ir_node *op2 = be_transform_node(n);
1899 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1903 * Transform a node returning a "flag" result.
1905 * @param node the node to transform
1906 * @param pnc_out the compare mode to use
1908 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1915 /* we have a Cmp as input */
1916 if (is_Proj(node)) {
1917 ir_node *pred = get_Proj_pred(node);
1919 pn_Cmp pnc = get_Proj_proj(node);
1920 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1921 ir_node *l = get_Cmp_left(pred);
1922 ir_node *r = get_Cmp_right(pred);
1924 ir_node *la = get_And_left(l);
1925 ir_node *ra = get_And_right(l);
1927 ir_node *c = get_Shl_left(la);
1928 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1929 /* (1 << n) & ra) */
1930 ir_node *n = get_Shl_right(la);
1931 flags = gen_bt(pred, ra, n);
1932 /* we must generate a Jc/Jnc jump */
1933 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1936 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1941 ir_node *c = get_Shl_left(ra);
1942 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1943 /* la & (1 << n)) */
1944 ir_node *n = get_Shl_right(ra);
1945 flags = gen_bt(pred, la, n);
1946 /* we must generate a Jc/Jnc jump */
1947 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1950 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1956 flags = be_transform_node(pred);
1957 if (mode_is_float(get_irn_mode(get_Cmp_left(pred))))
1958 pnc |= ia32_pn_Cmp_float;
1964 /* a mode_b value, we have to compare it against 0 */
1965 dbgi = get_irn_dbg_info(node);
1966 new_block = be_transform_node(get_nodes_block(node));
1967 new_op = be_transform_node(node);
1968 flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op,
1969 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1970 *pnc_out = pn_Cmp_Lg;
1975 * Transforms a Load.
1977 * @return the created ia32 Load node
1979 static ir_node *gen_Load(ir_node *node)
1981 ir_node *old_block = get_nodes_block(node);
1982 ir_node *block = be_transform_node(old_block);
1983 ir_node *ptr = get_Load_ptr(node);
1984 ir_node *mem = get_Load_mem(node);
1985 ir_node *new_mem = be_transform_node(mem);
1988 dbg_info *dbgi = get_irn_dbg_info(node);
1989 ir_mode *mode = get_Load_mode(node);
1992 ia32_address_t addr;
1994 /* construct load address */
1995 memset(&addr, 0, sizeof(addr));
1996 ia32_create_address_mode(&addr, ptr, 0);
2003 base = be_transform_node(base);
2006 if (index == NULL) {
2009 index = be_transform_node(index);
2012 if (mode_is_float(mode)) {
2013 if (ia32_cg_config.use_sse2) {
2014 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2016 res_mode = mode_xmm;
2018 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2020 res_mode = mode_vfp;
2023 assert(mode != mode_b);
2025 /* create a conv node with address mode for smaller modes */
2026 if (get_mode_size_bits(mode) < 32) {
2027 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2028 new_mem, noreg_GP, mode);
2030 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2035 set_irn_pinned(new_node, get_irn_pinned(node));
2036 set_ia32_op_type(new_node, ia32_AddrModeS);
2037 set_ia32_ls_mode(new_node, mode);
2038 set_address(new_node, &addr);
2040 if (get_irn_pinned(node) == op_pin_state_floats) {
2041 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
2042 && pn_ia32_vfld_res == pn_ia32_Load_res
2043 && pn_ia32_Load_res == pn_ia32_res);
2044 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2047 SET_IA32_ORIG_NODE(new_node, node);
2049 be_dep_on_frame(new_node);
2053 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2054 ir_node *ptr, ir_node *other)
2061 /* we only use address mode if we're the only user of the load */
2062 if (get_irn_n_edges(node) > 1)
2065 load = get_Proj_pred(node);
2068 if (get_nodes_block(load) != block)
2071 /* store should have the same pointer as the load */
2072 if (get_Load_ptr(load) != ptr)
2075 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2076 if (other != NULL &&
2077 get_nodes_block(other) == block &&
2078 heights_reachable_in_block(heights, other, load)) {
2082 if (prevents_AM(block, load, mem))
2084 /* Store should be attached to the load via mem */
2085 assert(heights_reachable_in_block(heights, mem, load));
2090 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2091 ir_node *mem, ir_node *ptr, ir_mode *mode,
2092 construct_binop_dest_func *func,
2093 construct_binop_dest_func *func8bit,
2094 match_flags_t flags)
2096 ir_node *src_block = get_nodes_block(node);
2104 ia32_address_mode_t am;
2105 ia32_address_t *addr = &am.addr;
2106 memset(&am, 0, sizeof(am));
2108 assert(flags & match_immediate); /* there is no destam node without... */
2109 commutative = (flags & match_commutative) != 0;
2111 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2112 build_address(&am, op1, ia32_create_am_double_use);
2113 new_op = create_immediate_or_transform(op2, 0);
2114 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2115 build_address(&am, op2, ia32_create_am_double_use);
2116 new_op = create_immediate_or_transform(op1, 0);
2121 if (addr->base == NULL)
2122 addr->base = noreg_GP;
2123 if (addr->index == NULL)
2124 addr->index = noreg_GP;
2125 if (addr->mem == NULL)
2128 dbgi = get_irn_dbg_info(node);
2129 block = be_transform_node(src_block);
2130 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2132 if (get_mode_size_bits(mode) == 8) {
2133 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2135 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2137 set_address(new_node, addr);
2138 set_ia32_op_type(new_node, ia32_AddrModeD);
2139 set_ia32_ls_mode(new_node, mode);
2140 SET_IA32_ORIG_NODE(new_node, node);
2142 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2143 mem_proj = be_transform_node(am.mem_proj);
2144 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2149 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2150 ir_node *ptr, ir_mode *mode,
2151 construct_unop_dest_func *func)
2153 ir_node *src_block = get_nodes_block(node);
2159 ia32_address_mode_t am;
2160 ia32_address_t *addr = &am.addr;
2162 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2165 memset(&am, 0, sizeof(am));
2166 build_address(&am, op, ia32_create_am_double_use);
2168 dbgi = get_irn_dbg_info(node);
2169 block = be_transform_node(src_block);
2170 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2171 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2172 set_address(new_node, addr);
2173 set_ia32_op_type(new_node, ia32_AddrModeD);
2174 set_ia32_ls_mode(new_node, mode);
2175 SET_IA32_ORIG_NODE(new_node, node);
2177 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2178 mem_proj = be_transform_node(am.mem_proj);
2179 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2184 static pn_Cmp ia32_get_negated_pnc(pn_Cmp pnc)
2186 ir_mode *mode = pnc & ia32_pn_Cmp_float ? mode_F : mode_Iu;
2187 return get_negated_pnc(pnc, mode);
2190 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2192 ir_mode *mode = get_irn_mode(node);
2193 ir_node *mux_true = get_Mux_true(node);
2194 ir_node *mux_false = get_Mux_false(node);
2204 ia32_address_t addr;
2206 if (get_mode_size_bits(mode) != 8)
2209 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2211 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2217 cond = get_Mux_sel(node);
2218 flags = get_flags_node(cond, &pnc);
2219 /* we can't handle the float special cases with SetM */
2220 if (pnc & ia32_pn_Cmp_float)
2223 pnc = ia32_get_negated_pnc(pnc);
2225 build_address_ptr(&addr, ptr, mem);
2227 dbgi = get_irn_dbg_info(node);
2228 block = get_nodes_block(node);
2229 new_block = be_transform_node(block);
2230 new_mem = be_transform_node(mem);
2231 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2232 addr.index, addr.mem, flags, pnc);
2233 set_address(new_node, &addr);
2234 set_ia32_op_type(new_node, ia32_AddrModeD);
2235 set_ia32_ls_mode(new_node, mode);
2236 SET_IA32_ORIG_NODE(new_node, node);
2241 static ir_node *try_create_dest_am(ir_node *node)
2243 ir_node *val = get_Store_value(node);
2244 ir_node *mem = get_Store_mem(node);
2245 ir_node *ptr = get_Store_ptr(node);
2246 ir_mode *mode = get_irn_mode(val);
2247 unsigned bits = get_mode_size_bits(mode);
2252 /* handle only GP modes for now... */
2253 if (!ia32_mode_needs_gp_reg(mode))
2257 /* store must be the only user of the val node */
2258 if (get_irn_n_edges(val) > 1)
2260 /* skip pointless convs */
2262 ir_node *conv_op = get_Conv_op(val);
2263 ir_mode *pred_mode = get_irn_mode(conv_op);
2264 if (!ia32_mode_needs_gp_reg(pred_mode))
2266 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2274 /* value must be in the same block */
2275 if (get_nodes_block(node) != get_nodes_block(val))
2278 switch (get_irn_opcode(val)) {
2280 op1 = get_Add_left(val);
2281 op2 = get_Add_right(val);
2282 if (ia32_cg_config.use_incdec) {
2283 if (is_Const_1(op2)) {
2284 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2286 } else if (is_Const_Minus_1(op2)) {
2287 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2291 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2292 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2293 match_commutative | match_immediate);
2296 op1 = get_Sub_left(val);
2297 op2 = get_Sub_right(val);
2298 if (is_Const(op2)) {
2299 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2301 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2302 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2306 op1 = get_And_left(val);
2307 op2 = get_And_right(val);
2308 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2309 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2310 match_commutative | match_immediate);
2313 op1 = get_Or_left(val);
2314 op2 = get_Or_right(val);
2315 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2316 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2317 match_commutative | match_immediate);
2320 op1 = get_Eor_left(val);
2321 op2 = get_Eor_right(val);
2322 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2323 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2324 match_commutative | match_immediate);
2327 op1 = get_Shl_left(val);
2328 op2 = get_Shl_right(val);
2329 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2330 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2334 op1 = get_Shr_left(val);
2335 op2 = get_Shr_right(val);
2336 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2337 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2341 op1 = get_Shrs_left(val);
2342 op2 = get_Shrs_right(val);
2343 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2344 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2348 op1 = get_Rotl_left(val);
2349 op2 = get_Rotl_right(val);
2350 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2351 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2354 /* TODO: match ROR patterns... */
2356 new_node = try_create_SetMem(val, ptr, mem);
2360 op1 = get_Minus_op(val);
2361 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2364 /* should be lowered already */
2365 assert(mode != mode_b);
2366 op1 = get_Not_op(val);
2367 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2373 if (new_node != NULL) {
2374 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2375 get_irn_pinned(node) == op_pin_state_pinned) {
2376 set_irn_pinned(new_node, op_pin_state_pinned);
2383 static bool possible_int_mode_for_fp(ir_mode *mode)
2387 if (!mode_is_signed(mode))
2389 size = get_mode_size_bits(mode);
2390 if (size != 16 && size != 32)
2395 static int is_float_to_int_conv(const ir_node *node)
2397 ir_mode *mode = get_irn_mode(node);
2401 if (!possible_int_mode_for_fp(mode))
2406 conv_op = get_Conv_op(node);
2407 conv_mode = get_irn_mode(conv_op);
2409 if (!mode_is_float(conv_mode))
2416 * Transform a Store(floatConst) into a sequence of
2419 * @return the created ia32 Store node
2421 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2423 ir_mode *mode = get_irn_mode(cns);
2424 unsigned size = get_mode_size_bytes(mode);
2425 tarval *tv = get_Const_tarval(cns);
2426 ir_node *block = get_nodes_block(node);
2427 ir_node *new_block = be_transform_node(block);
2428 ir_node *ptr = get_Store_ptr(node);
2429 ir_node *mem = get_Store_mem(node);
2430 dbg_info *dbgi = get_irn_dbg_info(node);
2434 ia32_address_t addr;
2436 assert(size % 4 == 0);
2439 build_address_ptr(&addr, ptr, mem);
2443 get_tarval_sub_bits(tv, ofs) |
2444 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2445 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2446 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2447 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2449 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2450 addr.index, addr.mem, imm);
2452 set_irn_pinned(new_node, get_irn_pinned(node));
2453 set_ia32_op_type(new_node, ia32_AddrModeD);
2454 set_ia32_ls_mode(new_node, mode_Iu);
2455 set_address(new_node, &addr);
2456 SET_IA32_ORIG_NODE(new_node, node);
2459 ins[i++] = new_node;
2464 } while (size != 0);
2467 return new_rd_Sync(dbgi, new_block, i, ins);
2474 * Generate a vfist or vfisttp instruction.
2476 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2477 ir_node *mem, ir_node *val, ir_node **fist)
2481 if (ia32_cg_config.use_fisttp) {
2482 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2483 if other users exists */
2484 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2485 ir_node *value = new_r_Proj(block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2486 be_new_Keep(block, 1, &value);
2488 new_node = new_r_Proj(block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2491 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2494 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2500 * Transforms a general (no special case) Store.
2502 * @return the created ia32 Store node
2504 static ir_node *gen_general_Store(ir_node *node)
2506 ir_node *val = get_Store_value(node);
2507 ir_mode *mode = get_irn_mode(val);
2508 ir_node *block = get_nodes_block(node);
2509 ir_node *new_block = be_transform_node(block);
2510 ir_node *ptr = get_Store_ptr(node);
2511 ir_node *mem = get_Store_mem(node);
2512 dbg_info *dbgi = get_irn_dbg_info(node);
2513 ir_node *new_val, *new_node, *store;
2514 ia32_address_t addr;
2516 /* check for destination address mode */
2517 new_node = try_create_dest_am(node);
2518 if (new_node != NULL)
2521 /* construct store address */
2522 memset(&addr, 0, sizeof(addr));
2523 ia32_create_address_mode(&addr, ptr, 0);
2525 if (addr.base == NULL) {
2526 addr.base = noreg_GP;
2528 addr.base = be_transform_node(addr.base);
2531 if (addr.index == NULL) {
2532 addr.index = noreg_GP;
2534 addr.index = be_transform_node(addr.index);
2536 addr.mem = be_transform_node(mem);
2538 if (mode_is_float(mode)) {
2539 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2541 while (is_Conv(val) && mode == get_irn_mode(val)) {
2542 ir_node *op = get_Conv_op(val);
2543 if (!mode_is_float(get_irn_mode(op)))
2547 new_val = be_transform_node(val);
2548 if (ia32_cg_config.use_sse2) {
2549 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2550 addr.index, addr.mem, new_val);
2552 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2553 addr.index, addr.mem, new_val, mode);
2556 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2557 val = get_Conv_op(val);
2559 /* TODO: is this optimisation still necessary at all (middleend)? */
2560 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2561 while (is_Conv(val)) {
2562 ir_node *op = get_Conv_op(val);
2563 if (!mode_is_float(get_irn_mode(op)))
2565 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2569 new_val = be_transform_node(val);
2570 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2572 new_val = create_immediate_or_transform(val, 0);
2573 assert(mode != mode_b);
2575 if (get_mode_size_bits(mode) == 8) {
2576 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2577 addr.index, addr.mem, new_val);
2579 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2580 addr.index, addr.mem, new_val);
2585 set_irn_pinned(store, get_irn_pinned(node));
2586 set_ia32_op_type(store, ia32_AddrModeD);
2587 set_ia32_ls_mode(store, mode);
2589 set_address(store, &addr);
2590 SET_IA32_ORIG_NODE(store, node);
2596 * Transforms a Store.
2598 * @return the created ia32 Store node
2600 static ir_node *gen_Store(ir_node *node)
2602 ir_node *val = get_Store_value(node);
2603 ir_mode *mode = get_irn_mode(val);
2605 if (mode_is_float(mode) && is_Const(val)) {
2606 /* We can transform every floating const store
2607 into a sequence of integer stores.
2608 If the constant is already in a register,
2609 it would be better to use it, but we don't
2610 have this information here. */
2611 return gen_float_const_Store(node, val);
2613 return gen_general_Store(node);
2617 * Transforms a Switch.
2619 * @return the created ia32 SwitchJmp node
2621 static ir_node *create_Switch(ir_node *node)
2623 dbg_info *dbgi = get_irn_dbg_info(node);
2624 ir_node *block = be_transform_node(get_nodes_block(node));
2625 ir_node *sel = get_Cond_selector(node);
2626 ir_node *new_sel = be_transform_node(sel);
2627 long switch_min = LONG_MAX;
2628 long switch_max = LONG_MIN;
2629 long default_pn = get_Cond_default_proj(node);
2631 const ir_edge_t *edge;
2633 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2635 /* determine the smallest switch case value */
2636 foreach_out_edge(node, edge) {
2637 ir_node *proj = get_edge_src_irn(edge);
2638 long pn = get_Proj_proj(proj);
2639 if (pn == default_pn)
2642 if (pn < switch_min)
2644 if (pn > switch_max)
2648 if ((unsigned long) (switch_max - switch_min) > 128000) {
2649 panic("Size of switch %+F bigger than 128000", node);
2652 if (switch_min != 0) {
2653 /* if smallest switch case is not 0 we need an additional sub */
2654 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2655 add_ia32_am_offs_int(new_sel, -switch_min);
2656 set_ia32_op_type(new_sel, ia32_AddrModeS);
2658 SET_IA32_ORIG_NODE(new_sel, node);
2661 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2662 SET_IA32_ORIG_NODE(new_node, node);
2668 * Transform a Cond node.
2670 static ir_node *gen_Cond(ir_node *node)
2672 ir_node *block = get_nodes_block(node);
2673 ir_node *new_block = be_transform_node(block);
2674 dbg_info *dbgi = get_irn_dbg_info(node);
2675 ir_node *sel = get_Cond_selector(node);
2676 ir_mode *sel_mode = get_irn_mode(sel);
2677 ir_node *flags = NULL;
2681 if (sel_mode != mode_b) {
2682 return create_Switch(node);
2685 /* we get flags from a Cmp */
2686 flags = get_flags_node(sel, &pnc);
2688 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2689 SET_IA32_ORIG_NODE(new_node, node);
2695 * Transform a be_Copy.
2697 static ir_node *gen_be_Copy(ir_node *node)
2699 ir_node *new_node = be_duplicate_node(node);
2700 ir_mode *mode = get_irn_mode(new_node);
2702 if (ia32_mode_needs_gp_reg(mode)) {
2703 set_irn_mode(new_node, mode_Iu);
2709 static ir_node *create_Fucom(ir_node *node)
2711 dbg_info *dbgi = get_irn_dbg_info(node);
2712 ir_node *block = get_nodes_block(node);
2713 ir_node *new_block = be_transform_node(block);
2714 ir_node *left = get_Cmp_left(node);
2715 ir_node *new_left = be_transform_node(left);
2716 ir_node *right = get_Cmp_right(node);
2720 if (ia32_cg_config.use_fucomi) {
2721 new_right = be_transform_node(right);
2722 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2724 set_ia32_commutative(new_node);
2725 SET_IA32_ORIG_NODE(new_node, node);
2727 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2728 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2730 new_right = be_transform_node(right);
2731 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2734 set_ia32_commutative(new_node);
2736 SET_IA32_ORIG_NODE(new_node, node);
2738 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2739 SET_IA32_ORIG_NODE(new_node, node);
2745 static ir_node *create_Ucomi(ir_node *node)
2747 dbg_info *dbgi = get_irn_dbg_info(node);
2748 ir_node *src_block = get_nodes_block(node);
2749 ir_node *new_block = be_transform_node(src_block);
2750 ir_node *left = get_Cmp_left(node);
2751 ir_node *right = get_Cmp_right(node);
2753 ia32_address_mode_t am;
2754 ia32_address_t *addr = &am.addr;
2756 match_arguments(&am, src_block, left, right, NULL,
2757 match_commutative | match_am);
2759 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2760 addr->mem, am.new_op1, am.new_op2,
2762 set_am_attributes(new_node, &am);
2764 SET_IA32_ORIG_NODE(new_node, node);
2766 new_node = fix_mem_proj(new_node, &am);
2772 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2773 * to fold an and into a test node
2775 static bool can_fold_test_and(ir_node *node)
2777 const ir_edge_t *edge;
2779 /** we can only have eq and lg projs */
2780 foreach_out_edge(node, edge) {
2781 ir_node *proj = get_edge_src_irn(edge);
2782 pn_Cmp pnc = get_Proj_proj(proj);
2783 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2791 * returns true if it is assured, that the upper bits of a node are "clean"
2792 * which means for a 16 or 8 bit value, that the upper bits in the register
2793 * are 0 for unsigned and a copy of the last significant bit for signed
2796 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2798 assert(ia32_mode_needs_gp_reg(mode));
2799 if (get_mode_size_bits(mode) >= 32)
2802 if (is_Proj(transformed_node))
2803 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2805 switch (get_ia32_irn_opcode(transformed_node)) {
2806 case iro_ia32_Conv_I2I:
2807 case iro_ia32_Conv_I2I8Bit: {
2808 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2809 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2811 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2818 if (mode_is_signed(mode)) {
2819 return false; /* TODO handle signed modes */
2821 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2822 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2823 const ia32_immediate_attr_t *attr
2824 = get_ia32_immediate_attr_const(right);
2825 if (attr->symconst == 0 &&
2826 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2830 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2834 /* TODO too conservative if shift amount is constant */
2835 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2838 if (!mode_is_signed(mode)) {
2840 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2841 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2843 /* TODO if one is known to be zero extended, then || is sufficient */
2848 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2849 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2851 case iro_ia32_Const:
2852 case iro_ia32_Immediate: {
2853 const ia32_immediate_attr_t *attr =
2854 get_ia32_immediate_attr_const(transformed_node);
2855 if (mode_is_signed(mode)) {
2856 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2857 return shifted == 0 || shifted == -1;
2859 unsigned long shifted = (unsigned long)attr->offset;
2860 shifted >>= get_mode_size_bits(mode);
2861 return shifted == 0;
2871 * Generate code for a Cmp.
2873 static ir_node *gen_Cmp(ir_node *node)
2875 dbg_info *dbgi = get_irn_dbg_info(node);
2876 ir_node *block = get_nodes_block(node);
2877 ir_node *new_block = be_transform_node(block);
2878 ir_node *left = get_Cmp_left(node);
2879 ir_node *right = get_Cmp_right(node);
2880 ir_mode *cmp_mode = get_irn_mode(left);
2882 ia32_address_mode_t am;
2883 ia32_address_t *addr = &am.addr;
2886 if (mode_is_float(cmp_mode)) {
2887 if (ia32_cg_config.use_sse2) {
2888 return create_Ucomi(node);
2890 return create_Fucom(node);
2894 assert(ia32_mode_needs_gp_reg(cmp_mode));
2896 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2897 cmp_unsigned = !mode_is_signed(cmp_mode);
2898 if (is_Const_0(right) &&
2900 get_irn_n_edges(left) == 1 &&
2901 can_fold_test_and(node)) {
2902 /* Test(and_left, and_right) */
2903 ir_node *and_left = get_And_left(left);
2904 ir_node *and_right = get_And_right(left);
2906 /* matze: code here used mode instead of cmd_mode, I think it is always
2907 * the same as cmp_mode, but I leave this here to see if this is really
2910 assert(get_irn_mode(and_left) == cmp_mode);
2912 match_arguments(&am, block, and_left, and_right, NULL,
2914 match_am | match_8bit_am | match_16bit_am |
2915 match_am_and_immediates | match_immediate);
2917 /* use 32bit compare mode if possible since the opcode is smaller */
2918 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2919 upper_bits_clean(am.new_op2, cmp_mode)) {
2920 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2923 if (get_mode_size_bits(cmp_mode) == 8) {
2924 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2925 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2928 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2929 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2932 /* Cmp(left, right) */
2933 match_arguments(&am, block, left, right, NULL,
2934 match_commutative | match_am | match_8bit_am |
2935 match_16bit_am | match_am_and_immediates |
2937 /* use 32bit compare mode if possible since the opcode is smaller */
2938 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2939 upper_bits_clean(am.new_op2, cmp_mode)) {
2940 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2943 if (get_mode_size_bits(cmp_mode) == 8) {
2944 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2945 addr->index, addr->mem, am.new_op1,
2946 am.new_op2, am.ins_permuted,
2949 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2950 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2953 set_am_attributes(new_node, &am);
2954 set_ia32_ls_mode(new_node, cmp_mode);
2956 SET_IA32_ORIG_NODE(new_node, node);
2958 new_node = fix_mem_proj(new_node, &am);
2963 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2966 dbg_info *dbgi = get_irn_dbg_info(node);
2967 ir_node *block = get_nodes_block(node);
2968 ir_node *new_block = be_transform_node(block);
2969 ir_node *val_true = get_Mux_true(node);
2970 ir_node *val_false = get_Mux_false(node);
2972 ia32_address_mode_t am;
2973 ia32_address_t *addr;
2975 assert(ia32_cg_config.use_cmov);
2976 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2980 match_arguments(&am, block, val_false, val_true, flags,
2981 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2983 if (am.ins_permuted)
2984 pnc = ia32_get_negated_pnc(pnc);
2986 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
2987 addr->mem, am.new_op1, am.new_op2, new_flags,
2989 set_am_attributes(new_node, &am);
2991 SET_IA32_ORIG_NODE(new_node, node);
2993 new_node = fix_mem_proj(new_node, &am);
2999 * Creates a ia32 Setcc instruction.
3001 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3002 ir_node *flags, pn_Cmp pnc,
3005 ir_mode *mode = get_irn_mode(orig_node);
3008 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, pnc);
3009 SET_IA32_ORIG_NODE(new_node, orig_node);
3011 /* we might need to conv the result up */
3012 if (get_mode_size_bits(mode) > 8) {
3013 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3014 nomem, new_node, mode_Bu);
3015 SET_IA32_ORIG_NODE(new_node, orig_node);
3022 * Create instruction for an unsigned Difference or Zero.
3024 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3026 ir_mode *mode = get_irn_mode(psi);
3036 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3037 match_mode_neutral | match_am | match_immediate | match_two_users);
3039 block = get_nodes_block(new_node);
3041 if (is_Proj(new_node)) {
3042 sub = get_Proj_pred(new_node);
3043 assert(is_ia32_Sub(sub));
3046 set_irn_mode(sub, mode_T);
3047 new_node = new_rd_Proj(NULL, block, sub, mode, pn_ia32_res);
3049 eflags = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_Sub_flags);
3051 dbgi = get_irn_dbg_info(psi);
3052 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3053 not = new_bd_ia32_Not(dbgi, block, sbb);
3055 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, not);
3056 set_ia32_commutative(new_node);
3061 * Create an const array of two float consts.
3063 * @param c0 the first constant
3064 * @param c1 the second constant
3065 * @param new_mode IN/OUT for the mode of the constants, if NULL
3066 * smallest possible mode will be used
3068 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode) {
3070 ir_mode *mode = *new_mode;
3072 ir_initializer_t *initializer;
3073 tarval *tv0 = get_Const_tarval(c0);
3074 tarval *tv1 = get_Const_tarval(c1);
3077 /* detect the best mode for the constants */
3078 mode = get_tarval_mode(tv0);
3080 if (mode != mode_F) {
3081 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3082 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3084 tv0 = tarval_convert_to(tv0, mode);
3085 tv1 = tarval_convert_to(tv1, mode);
3086 } else if (mode != mode_D) {
3087 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3088 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3090 tv0 = tarval_convert_to(tv0, mode);
3091 tv1 = tarval_convert_to(tv1, mode);
3098 tp = ia32_create_float_type(mode, 4);
3099 tp = ia32_create_float_array(tp);
3101 ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
3103 set_entity_ld_ident(ent, get_entity_ident(ent));
3104 set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
3106 initializer = create_initializer_compound(2);
3108 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3109 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3111 set_entity_initializer(ent, initializer);
3118 * Transforms a Mux node into some code sequence.
3120 * @return The transformed node.
3122 static ir_node *gen_Mux(ir_node *node)
3124 dbg_info *dbgi = get_irn_dbg_info(node);
3125 ir_node *block = get_nodes_block(node);
3126 ir_node *new_block = be_transform_node(block);
3127 ir_node *mux_true = get_Mux_true(node);
3128 ir_node *mux_false = get_Mux_false(node);
3129 ir_node *cond = get_Mux_sel(node);
3130 ir_mode *mode = get_irn_mode(node);
3135 assert(get_irn_mode(cond) == mode_b);
3137 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3138 if (mode_is_float(mode)) {
3139 ir_node *cmp = get_Proj_pred(cond);
3140 ir_node *cmp_left = get_Cmp_left(cmp);
3141 ir_node *cmp_right = get_Cmp_right(cmp);
3142 pn_Cmp pnc = get_Proj_proj(cond);
3144 if (ia32_cg_config.use_sse2) {
3145 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3146 if (cmp_left == mux_true && cmp_right == mux_false) {
3147 /* Mux(a <= b, a, b) => MIN */
3148 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3149 match_commutative | match_am | match_two_users);
3150 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3151 /* Mux(a <= b, b, a) => MAX */
3152 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3153 match_commutative | match_am | match_two_users);
3155 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3156 if (cmp_left == mux_true && cmp_right == mux_false) {
3157 /* Mux(a >= b, a, b) => MAX */
3158 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3159 match_commutative | match_am | match_two_users);
3160 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3161 /* Mux(a >= b, b, a) => MIN */
3162 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3163 match_commutative | match_am | match_two_users);
3168 if (is_Const(mux_true) && is_Const(mux_false)) {
3169 ia32_address_mode_t am;
3174 flags = get_flags_node(cond, &pnc);
3175 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node);
3177 if (ia32_cg_config.use_sse2) {
3178 /* cannot load from different mode on SSE */
3181 /* x87 can load any mode */
3185 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3187 switch (get_mode_size_bytes(new_mode)) {
3197 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3198 set_ia32_am_scale(new_node, 2);
3203 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3204 set_ia32_am_scale(new_node, 1);
3207 /* arg, shift 16 NOT supported */
3209 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node);
3212 panic("Unsupported constant size");
3215 am.ls_mode = new_mode;
3216 am.addr.base = noreg_GP;
3217 am.addr.index = new_node;
3218 am.addr.mem = nomem;
3220 am.addr.scale = scale;
3221 am.addr.use_frame = 0;
3222 am.addr.frame_entity = NULL;
3223 am.addr.symconst_sign = 0;
3224 am.mem_proj = am.addr.mem;
3225 am.op_type = ia32_AddrModeS;
3228 am.pinned = op_pin_state_floats;
3230 am.ins_permuted = 0;
3232 if (ia32_cg_config.use_sse2)
3233 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3235 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3236 set_am_attributes(load, &am);
3238 return new_rd_Proj(NULL, block, load, mode_vfp, pn_ia32_res);
3240 panic("cannot transform floating point Mux");
3243 assert(ia32_mode_needs_gp_reg(mode));
3245 if (is_Proj(cond)) {
3246 ir_node *cmp = get_Proj_pred(cond);
3248 ir_node *cmp_left = get_Cmp_left(cmp);
3249 ir_node *cmp_right = get_Cmp_right(cmp);
3250 pn_Cmp pnc = get_Proj_proj(cond);
3252 /* check for unsigned Doz first */
3253 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3254 is_Const_0(mux_false) && is_Sub(mux_true) &&
3255 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3256 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3257 return create_doz(node, cmp_left, cmp_right);
3258 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3259 is_Const_0(mux_true) && is_Sub(mux_false) &&
3260 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3261 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3262 return create_doz(node, cmp_left, cmp_right);
3267 flags = get_flags_node(cond, &pnc);
3269 if (is_Const(mux_true) && is_Const(mux_false)) {
3270 /* both are const, good */
3271 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3272 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node);
3273 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3274 pnc = ia32_get_negated_pnc(pnc);
3275 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node);
3277 /* Not that simple. */
3282 new_node = create_CMov(node, cond, flags, pnc);
3290 * Create a conversion from x87 state register to general purpose.
3292 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3294 ir_node *block = be_transform_node(get_nodes_block(node));
3295 ir_node *op = get_Conv_op(node);
3296 ir_node *new_op = be_transform_node(op);
3297 ir_graph *irg = current_ir_graph;
3298 dbg_info *dbgi = get_irn_dbg_info(node);
3299 ir_mode *mode = get_irn_mode(node);
3300 ir_node *fist, *load, *mem;
3302 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3303 set_irn_pinned(fist, op_pin_state_floats);
3304 set_ia32_use_frame(fist);
3305 set_ia32_op_type(fist, ia32_AddrModeD);
3307 assert(get_mode_size_bits(mode) <= 32);
3308 /* exception we can only store signed 32 bit integers, so for unsigned
3309 we store a 64bit (signed) integer and load the lower bits */
3310 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3311 set_ia32_ls_mode(fist, mode_Ls);
3313 set_ia32_ls_mode(fist, mode_Is);
3315 SET_IA32_ORIG_NODE(fist, node);
3318 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3320 set_irn_pinned(load, op_pin_state_floats);
3321 set_ia32_use_frame(load);
3322 set_ia32_op_type(load, ia32_AddrModeS);
3323 set_ia32_ls_mode(load, mode_Is);
3324 if (get_ia32_ls_mode(fist) == mode_Ls) {
3325 ia32_attr_t *attr = get_ia32_attr(load);
3326 attr->data.need_64bit_stackent = 1;
3328 ia32_attr_t *attr = get_ia32_attr(load);
3329 attr->data.need_32bit_stackent = 1;
3331 SET_IA32_ORIG_NODE(load, node);
3333 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
3337 * Creates a x87 strict Conv by placing a Store and a Load
3339 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3341 ir_node *block = get_nodes_block(node);
3342 ir_graph *irg = get_Block_irg(block);
3343 dbg_info *dbgi = get_irn_dbg_info(node);
3344 ir_node *frame = get_irg_frame(irg);
3345 ir_node *store, *load;
3348 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3349 set_ia32_use_frame(store);
3350 set_ia32_op_type(store, ia32_AddrModeD);
3351 SET_IA32_ORIG_NODE(store, node);
3353 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3354 set_ia32_use_frame(load);
3355 set_ia32_op_type(load, ia32_AddrModeS);
3356 SET_IA32_ORIG_NODE(load, node);
3358 new_node = new_r_Proj(block, load, mode_E, pn_ia32_vfld_res);
3362 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3363 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3365 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3367 func = get_mode_size_bits(mode) == 8 ?
3368 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3369 return func(dbgi, block, base, index, mem, val, mode);
3373 * Create a conversion from general purpose to x87 register
3375 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3377 ir_node *src_block = get_nodes_block(node);
3378 ir_node *block = be_transform_node(src_block);
3379 ir_graph *irg = get_Block_irg(block);
3380 dbg_info *dbgi = get_irn_dbg_info(node);
3381 ir_node *op = get_Conv_op(node);
3382 ir_node *new_op = NULL;
3384 ir_mode *store_mode;
3389 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3390 if (possible_int_mode_for_fp(src_mode)) {
3391 ia32_address_mode_t am;
3393 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3394 if (am.op_type == ia32_AddrModeS) {
3395 ia32_address_t *addr = &am.addr;
3397 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3398 new_node = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
3400 set_am_attributes(fild, &am);
3401 SET_IA32_ORIG_NODE(fild, node);
3403 fix_mem_proj(fild, &am);
3408 if (new_op == NULL) {
3409 new_op = be_transform_node(op);
3412 mode = get_irn_mode(op);
3414 /* first convert to 32 bit signed if necessary */
3415 if (get_mode_size_bits(src_mode) < 32) {
3416 if (!upper_bits_clean(new_op, src_mode)) {
3417 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3418 SET_IA32_ORIG_NODE(new_op, node);
3423 assert(get_mode_size_bits(mode) == 32);
3426 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3428 set_ia32_use_frame(store);
3429 set_ia32_op_type(store, ia32_AddrModeD);
3430 set_ia32_ls_mode(store, mode_Iu);
3432 /* exception for 32bit unsigned, do a 64bit spill+load */
3433 if (!mode_is_signed(mode)) {
3436 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3438 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3439 noreg_GP, nomem, zero_const);
3441 set_ia32_use_frame(zero_store);
3442 set_ia32_op_type(zero_store, ia32_AddrModeD);
3443 add_ia32_am_offs_int(zero_store, 4);
3444 set_ia32_ls_mode(zero_store, mode_Iu);
3449 store = new_rd_Sync(dbgi, block, 2, in);
3450 store_mode = mode_Ls;
3452 store_mode = mode_Is;
3456 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3458 set_ia32_use_frame(fild);
3459 set_ia32_op_type(fild, ia32_AddrModeS);
3460 set_ia32_ls_mode(fild, store_mode);
3462 new_node = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
3468 * Create a conversion from one integer mode into another one
3470 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3471 dbg_info *dbgi, ir_node *block, ir_node *op,
3474 ir_node *new_block = be_transform_node(block);
3476 ir_mode *smaller_mode;
3477 ia32_address_mode_t am;
3478 ia32_address_t *addr = &am.addr;
3481 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3482 smaller_mode = src_mode;
3484 smaller_mode = tgt_mode;
3487 #ifdef DEBUG_libfirm
3489 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3494 match_arguments(&am, block, NULL, op, NULL,
3495 match_am | match_8bit_am | match_16bit_am);
3497 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3498 /* unnecessary conv. in theory it shouldn't have been AM */
3499 assert(is_ia32_NoReg_GP(addr->base));
3500 assert(is_ia32_NoReg_GP(addr->index));
3501 assert(is_NoMem(addr->mem));
3502 assert(am.addr.offset == 0);
3503 assert(am.addr.symconst_ent == NULL);
3507 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3508 addr->mem, am.new_op2, smaller_mode);
3509 set_am_attributes(new_node, &am);
3510 /* match_arguments assume that out-mode = in-mode, this isn't true here
3512 set_ia32_ls_mode(new_node, smaller_mode);
3513 SET_IA32_ORIG_NODE(new_node, node);
3514 new_node = fix_mem_proj(new_node, &am);
3519 * Transforms a Conv node.
3521 * @return The created ia32 Conv node
3523 static ir_node *gen_Conv(ir_node *node)
3525 ir_node *block = get_nodes_block(node);
3526 ir_node *new_block = be_transform_node(block);
3527 ir_node *op = get_Conv_op(node);
3528 ir_node *new_op = NULL;
3529 dbg_info *dbgi = get_irn_dbg_info(node);
3530 ir_mode *src_mode = get_irn_mode(op);
3531 ir_mode *tgt_mode = get_irn_mode(node);
3532 int src_bits = get_mode_size_bits(src_mode);
3533 int tgt_bits = get_mode_size_bits(tgt_mode);
3534 ir_node *res = NULL;
3536 assert(!mode_is_int(src_mode) || src_bits <= 32);
3537 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3539 /* modeB -> X should already be lowered by the lower_mode_b pass */
3540 if (src_mode == mode_b) {
3541 panic("ConvB not lowered %+F", node);
3544 if (src_mode == tgt_mode) {
3545 if (get_Conv_strict(node)) {
3546 if (ia32_cg_config.use_sse2) {
3547 /* when we are in SSE mode, we can kill all strict no-op conversion */
3548 return be_transform_node(op);
3551 /* this should be optimized already, but who knows... */
3552 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3553 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3554 return be_transform_node(op);
3558 if (mode_is_float(src_mode)) {
3559 new_op = be_transform_node(op);
3560 /* we convert from float ... */
3561 if (mode_is_float(tgt_mode)) {
3563 if (ia32_cg_config.use_sse2) {
3564 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3565 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3567 set_ia32_ls_mode(res, tgt_mode);
3569 if (get_Conv_strict(node)) {
3570 /* if fp_no_float_fold is not set then we assume that we
3571 * don't have any float operations in a non
3572 * mode_float_arithmetic mode and can skip strict upconvs */
3573 if (src_bits < tgt_bits
3574 && !(get_irg_fp_model(current_ir_graph) & fp_no_float_fold)) {
3575 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3578 res = gen_x87_strict_conv(tgt_mode, new_op);
3579 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3583 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3588 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3589 if (ia32_cg_config.use_sse2) {
3590 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3592 set_ia32_ls_mode(res, src_mode);
3594 return gen_x87_fp_to_gp(node);
3598 /* we convert from int ... */
3599 if (mode_is_float(tgt_mode)) {
3601 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3602 if (ia32_cg_config.use_sse2) {
3603 new_op = be_transform_node(op);
3604 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3606 set_ia32_ls_mode(res, tgt_mode);
3608 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3609 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3610 res = gen_x87_gp_to_fp(node, src_mode);
3612 /* we need a strict-Conv, if the int mode has more bits than the
3614 if (float_mantissa < int_mantissa) {
3615 res = gen_x87_strict_conv(tgt_mode, res);
3616 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3620 } else if (tgt_mode == mode_b) {
3621 /* mode_b lowering already took care that we only have 0/1 values */
3622 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3623 src_mode, tgt_mode));
3624 return be_transform_node(op);
3627 if (src_bits == tgt_bits) {
3628 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3629 src_mode, tgt_mode));
3630 return be_transform_node(op);
3633 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3641 static ir_node *create_immediate_or_transform(ir_node *node,
3642 char immediate_constraint_type)
3644 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3645 if (new_node == NULL) {
3646 new_node = be_transform_node(node);
3652 * Transforms a FrameAddr into an ia32 Add.
3654 static ir_node *gen_be_FrameAddr(ir_node *node)
3656 ir_node *block = be_transform_node(get_nodes_block(node));
3657 ir_node *op = be_get_FrameAddr_frame(node);
3658 ir_node *new_op = be_transform_node(op);
3659 dbg_info *dbgi = get_irn_dbg_info(node);
3662 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3663 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3664 set_ia32_use_frame(new_node);
3666 SET_IA32_ORIG_NODE(new_node, node);
3672 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3674 static ir_node *gen_be_Return(ir_node *node)
3676 ir_graph *irg = current_ir_graph;
3677 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3678 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3679 ir_entity *ent = get_irg_entity(irg);
3680 ir_type *tp = get_entity_type(ent);
3685 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3686 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3688 int pn_ret_val, pn_ret_mem, arity, i;
3690 assert(ret_val != NULL);
3691 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3692 return be_duplicate_node(node);
3695 res_type = get_method_res_type(tp, 0);
3697 if (! is_Primitive_type(res_type)) {
3698 return be_duplicate_node(node);
3701 mode = get_type_mode(res_type);
3702 if (! mode_is_float(mode)) {
3703 return be_duplicate_node(node);
3706 assert(get_method_n_ress(tp) == 1);
3708 pn_ret_val = get_Proj_proj(ret_val);
3709 pn_ret_mem = get_Proj_proj(ret_mem);
3711 /* get the Barrier */
3712 barrier = get_Proj_pred(ret_val);
3714 /* get result input of the Barrier */
3715 ret_val = get_irn_n(barrier, pn_ret_val);
3716 new_ret_val = be_transform_node(ret_val);
3718 /* get memory input of the Barrier */
3719 ret_mem = get_irn_n(barrier, pn_ret_mem);
3720 new_ret_mem = be_transform_node(ret_mem);
3722 frame = get_irg_frame(irg);
3724 dbgi = get_irn_dbg_info(barrier);
3725 block = be_transform_node(get_nodes_block(barrier));
3727 /* store xmm0 onto stack */
3728 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3729 new_ret_mem, new_ret_val);
3730 set_ia32_ls_mode(sse_store, mode);
3731 set_ia32_op_type(sse_store, ia32_AddrModeD);
3732 set_ia32_use_frame(sse_store);
3734 /* load into x87 register */
3735 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
3736 set_ia32_op_type(fld, ia32_AddrModeS);
3737 set_ia32_use_frame(fld);
3739 mproj = new_r_Proj(block, fld, mode_M, pn_ia32_vfld_M);
3740 fld = new_r_Proj(block, fld, mode_vfp, pn_ia32_vfld_res);
3742 /* create a new barrier */
3743 arity = get_irn_arity(barrier);
3744 in = ALLOCAN(ir_node*, arity);
3745 for (i = 0; i < arity; ++i) {
3748 if (i == pn_ret_val) {
3750 } else if (i == pn_ret_mem) {
3753 ir_node *in = get_irn_n(barrier, i);
3754 new_in = be_transform_node(in);
3759 new_barrier = new_ir_node(dbgi, irg, block,
3760 get_irn_op(barrier), get_irn_mode(barrier),
3762 copy_node_attr(barrier, new_barrier);
3763 be_duplicate_deps(barrier, new_barrier);
3764 be_set_transformed_node(barrier, new_barrier);
3766 /* transform normally */
3767 return be_duplicate_node(node);
3771 * Transform a be_AddSP into an ia32_SubSP.
3773 static ir_node *gen_be_AddSP(ir_node *node)
3775 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3776 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3778 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3779 match_am | match_immediate);
3783 * Transform a be_SubSP into an ia32_AddSP
3785 static ir_node *gen_be_SubSP(ir_node *node)
3787 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3788 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3790 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3791 match_am | match_immediate);
3795 * Change some phi modes
3797 static ir_node *gen_Phi(ir_node *node)
3799 const arch_register_req_t *req;
3800 ir_node *block = be_transform_node(get_nodes_block(node));
3801 ir_graph *irg = current_ir_graph;
3802 dbg_info *dbgi = get_irn_dbg_info(node);
3803 ir_mode *mode = get_irn_mode(node);
3806 if (ia32_mode_needs_gp_reg(mode)) {
3807 /* we shouldn't have any 64bit stuff around anymore */
3808 assert(get_mode_size_bits(mode) <= 32);
3809 /* all integer operations are on 32bit registers now */
3811 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
3812 } else if (mode_is_float(mode)) {
3813 if (ia32_cg_config.use_sse2) {
3815 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
3818 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
3821 req = arch_no_register_req;
3824 /* phi nodes allow loops, so we use the old arguments for now
3825 * and fix this later */
3826 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3827 get_irn_in(node) + 1);
3828 copy_node_attr(node, phi);
3829 be_duplicate_deps(node, phi);
3831 arch_set_out_register_req(phi, 0, req);
3833 be_enqueue_preds(node);
3838 static ir_node *gen_Jmp(ir_node *node)
3840 ir_node *block = get_nodes_block(node);
3841 ir_node *new_block = be_transform_node(block);
3842 dbg_info *dbgi = get_irn_dbg_info(node);
3845 new_node = new_bd_ia32_Jmp(dbgi, new_block);
3846 SET_IA32_ORIG_NODE(new_node, node);
3854 static ir_node *gen_IJmp(ir_node *node)
3856 ir_node *block = get_nodes_block(node);
3857 ir_node *new_block = be_transform_node(block);
3858 dbg_info *dbgi = get_irn_dbg_info(node);
3859 ir_node *op = get_IJmp_target(node);
3861 ia32_address_mode_t am;
3862 ia32_address_t *addr = &am.addr;
3864 assert(get_irn_mode(op) == mode_P);
3866 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3868 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3869 addr->mem, am.new_op2);
3870 set_am_attributes(new_node, &am);
3871 SET_IA32_ORIG_NODE(new_node, node);
3873 new_node = fix_mem_proj(new_node, &am);
3879 * Transform a Bound node.
3881 static ir_node *gen_Bound(ir_node *node)
3884 ir_node *lower = get_Bound_lower(node);
3885 dbg_info *dbgi = get_irn_dbg_info(node);
3887 if (is_Const_0(lower)) {
3888 /* typical case for Java */
3889 ir_node *sub, *res, *flags, *block;
3891 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3892 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3894 block = get_nodes_block(res);
3895 if (! is_Proj(res)) {
3897 set_irn_mode(sub, mode_T);
3898 res = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_res);
3900 sub = get_Proj_pred(res);
3902 flags = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_Sub_flags);
3903 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3904 SET_IA32_ORIG_NODE(new_node, node);
3906 panic("generic Bound not supported in ia32 Backend");
3912 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3914 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3915 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3917 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3918 match_immediate | match_mode_neutral);
3921 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3923 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3924 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3925 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3929 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3931 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3932 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3933 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3937 static ir_node *gen_ia32_l_Add(ir_node *node)
3939 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3940 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3941 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3942 match_commutative | match_am | match_immediate |
3943 match_mode_neutral);
3945 if (is_Proj(lowered)) {
3946 lowered = get_Proj_pred(lowered);
3948 assert(is_ia32_Add(lowered));
3949 set_irn_mode(lowered, mode_T);
3955 static ir_node *gen_ia32_l_Adc(ir_node *node)
3957 return gen_binop_flags(node, new_bd_ia32_Adc,
3958 match_commutative | match_am | match_immediate |
3959 match_mode_neutral);
3963 * Transforms a l_MulS into a "real" MulS node.
3965 * @return the created ia32 Mul node
3967 static ir_node *gen_ia32_l_Mul(ir_node *node)
3969 ir_node *left = get_binop_left(node);
3970 ir_node *right = get_binop_right(node);
3972 return gen_binop(node, left, right, new_bd_ia32_Mul,
3973 match_commutative | match_am | match_mode_neutral);
3977 * Transforms a l_IMulS into a "real" IMul1OPS node.
3979 * @return the created ia32 IMul1OP node
3981 static ir_node *gen_ia32_l_IMul(ir_node *node)
3983 ir_node *left = get_binop_left(node);
3984 ir_node *right = get_binop_right(node);
3986 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3987 match_commutative | match_am | match_mode_neutral);
3990 static ir_node *gen_ia32_l_Sub(ir_node *node)
3992 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3993 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3994 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3995 match_am | match_immediate | match_mode_neutral);
3997 if (is_Proj(lowered)) {
3998 lowered = get_Proj_pred(lowered);
4000 assert(is_ia32_Sub(lowered));
4001 set_irn_mode(lowered, mode_T);
4007 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4009 return gen_binop_flags(node, new_bd_ia32_Sbb,
4010 match_am | match_immediate | match_mode_neutral);
4014 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4015 * op1 - target to be shifted
4016 * op2 - contains bits to be shifted into target
4018 * Only op3 can be an immediate.
4020 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4021 ir_node *low, ir_node *count)
4023 ir_node *block = get_nodes_block(node);
4024 ir_node *new_block = be_transform_node(block);
4025 dbg_info *dbgi = get_irn_dbg_info(node);
4026 ir_node *new_high = be_transform_node(high);
4027 ir_node *new_low = be_transform_node(low);
4031 /* the shift amount can be any mode that is bigger than 5 bits, since all
4032 * other bits are ignored anyway */
4033 while (is_Conv(count) &&
4034 get_irn_n_edges(count) == 1 &&
4035 mode_is_int(get_irn_mode(count))) {
4036 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4037 count = get_Conv_op(count);
4039 new_count = create_immediate_or_transform(count, 0);
4041 if (is_ia32_l_ShlD(node)) {
4042 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4045 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4048 SET_IA32_ORIG_NODE(new_node, node);
4053 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4055 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4056 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4057 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4058 return gen_lowered_64bit_shifts(node, high, low, count);
4061 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4063 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4064 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4065 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4066 return gen_lowered_64bit_shifts(node, high, low, count);
4069 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4071 ir_node *src_block = get_nodes_block(node);
4072 ir_node *block = be_transform_node(src_block);
4073 ir_graph *irg = current_ir_graph;
4074 dbg_info *dbgi = get_irn_dbg_info(node);
4075 ir_node *frame = get_irg_frame(irg);
4076 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4077 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4078 ir_node *new_val_low = be_transform_node(val_low);
4079 ir_node *new_val_high = be_transform_node(val_high);
4081 ir_node *sync, *fild, *res;
4082 ir_node *store_low, *store_high;
4084 if (ia32_cg_config.use_sse2) {
4085 panic("ia32_l_LLtoFloat not implemented for SSE2");
4089 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4091 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4093 SET_IA32_ORIG_NODE(store_low, node);
4094 SET_IA32_ORIG_NODE(store_high, node);
4096 set_ia32_use_frame(store_low);
4097 set_ia32_use_frame(store_high);
4098 set_ia32_op_type(store_low, ia32_AddrModeD);
4099 set_ia32_op_type(store_high, ia32_AddrModeD);
4100 set_ia32_ls_mode(store_low, mode_Iu);
4101 set_ia32_ls_mode(store_high, mode_Is);
4102 add_ia32_am_offs_int(store_high, 4);
4106 sync = new_rd_Sync(dbgi, block, 2, in);
4109 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4111 set_ia32_use_frame(fild);
4112 set_ia32_op_type(fild, ia32_AddrModeS);
4113 set_ia32_ls_mode(fild, mode_Ls);
4115 SET_IA32_ORIG_NODE(fild, node);
4117 res = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
4119 if (! mode_is_signed(get_irn_mode(val_high))) {
4120 ia32_address_mode_t am;
4122 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4125 am.addr.base = noreg_GP;
4126 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4127 am.addr.mem = nomem;
4130 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4131 am.addr.use_frame = 0;
4132 am.addr.frame_entity = NULL;
4133 am.addr.symconst_sign = 0;
4134 am.ls_mode = mode_F;
4135 am.mem_proj = nomem;
4136 am.op_type = ia32_AddrModeS;
4138 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
4139 am.pinned = op_pin_state_floats;
4141 am.ins_permuted = 0;
4143 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4144 am.new_op1, am.new_op2, get_fpcw());
4145 set_am_attributes(fadd, &am);
4147 set_irn_mode(fadd, mode_T);
4148 res = new_rd_Proj(NULL, block, fadd, mode_vfp, pn_ia32_res);
4153 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4155 ir_node *src_block = get_nodes_block(node);
4156 ir_node *block = be_transform_node(src_block);
4157 ir_graph *irg = get_Block_irg(block);
4158 dbg_info *dbgi = get_irn_dbg_info(node);
4159 ir_node *frame = get_irg_frame(irg);
4160 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4161 ir_node *new_val = be_transform_node(val);
4162 ir_node *fist, *mem;
4164 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4165 SET_IA32_ORIG_NODE(fist, node);
4166 set_ia32_use_frame(fist);
4167 set_ia32_op_type(fist, ia32_AddrModeD);
4168 set_ia32_ls_mode(fist, mode_Ls);
4174 * the BAD transformer.
4176 static ir_node *bad_transform(ir_node *node)
4178 panic("No transform function for %+F available.", node);
4182 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4184 ir_node *block = be_transform_node(get_nodes_block(node));
4185 ir_graph *irg = get_Block_irg(block);
4186 ir_node *pred = get_Proj_pred(node);
4187 ir_node *new_pred = be_transform_node(pred);
4188 ir_node *frame = get_irg_frame(irg);
4189 dbg_info *dbgi = get_irn_dbg_info(node);
4190 long pn = get_Proj_proj(node);
4195 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4196 SET_IA32_ORIG_NODE(load, node);
4197 set_ia32_use_frame(load);
4198 set_ia32_op_type(load, ia32_AddrModeS);
4199 set_ia32_ls_mode(load, mode_Iu);
4200 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4201 * 32 bit from it with this particular load */
4202 attr = get_ia32_attr(load);
4203 attr->data.need_64bit_stackent = 1;
4205 if (pn == pn_ia32_l_FloattoLL_res_high) {
4206 add_ia32_am_offs_int(load, 4);
4208 assert(pn == pn_ia32_l_FloattoLL_res_low);
4211 proj = new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4217 * Transform the Projs of an AddSP.
4219 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4221 ir_node *block = be_transform_node(get_nodes_block(node));
4222 ir_node *pred = get_Proj_pred(node);
4223 ir_node *new_pred = be_transform_node(pred);
4224 dbg_info *dbgi = get_irn_dbg_info(node);
4225 long proj = get_Proj_proj(node);
4227 if (proj == pn_be_AddSP_sp) {
4228 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4229 pn_ia32_SubSP_stack);
4230 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4232 } else if (proj == pn_be_AddSP_res) {
4233 return new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4234 pn_ia32_SubSP_addr);
4235 } else if (proj == pn_be_AddSP_M) {
4236 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_SubSP_M);
4239 panic("No idea how to transform proj->AddSP");
4243 * Transform the Projs of a SubSP.
4245 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4247 ir_node *block = be_transform_node(get_nodes_block(node));
4248 ir_node *pred = get_Proj_pred(node);
4249 ir_node *new_pred = be_transform_node(pred);
4250 dbg_info *dbgi = get_irn_dbg_info(node);
4251 long proj = get_Proj_proj(node);
4253 if (proj == pn_be_SubSP_sp) {
4254 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4255 pn_ia32_AddSP_stack);
4256 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4258 } else if (proj == pn_be_SubSP_M) {
4259 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_AddSP_M);
4262 panic("No idea how to transform proj->SubSP");
4266 * Transform and renumber the Projs from a Load.
4268 static ir_node *gen_Proj_Load(ir_node *node)
4271 ir_node *block = be_transform_node(get_nodes_block(node));
4272 ir_node *pred = get_Proj_pred(node);
4273 dbg_info *dbgi = get_irn_dbg_info(node);
4274 long proj = get_Proj_proj(node);
4276 /* loads might be part of source address mode matches, so we don't
4277 * transform the ProjMs yet (with the exception of loads whose result is
4280 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4282 ir_node *old_block = get_nodes_block(node);
4284 /* this is needed, because sometimes we have loops that are only
4285 reachable through the ProjM */
4286 be_enqueue_preds(node);
4287 /* do it in 2 steps, to silence firm verifier */
4288 res = new_rd_Proj(dbgi, old_block, pred, mode_M, pn_Load_M);
4289 set_Proj_proj(res, pn_ia32_mem);
4293 /* renumber the proj */
4294 new_pred = be_transform_node(pred);
4295 if (is_ia32_Load(new_pred)) {
4298 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Load_res);
4300 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Load_M);
4301 case pn_Load_X_regular:
4302 return new_rd_Jmp(dbgi, block);
4303 case pn_Load_X_except:
4304 /* This Load might raise an exception. Mark it. */
4305 set_ia32_exc_label(new_pred, 1);
4306 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4310 } else if (is_ia32_Conv_I2I(new_pred) ||
4311 is_ia32_Conv_I2I8Bit(new_pred)) {
4312 set_irn_mode(new_pred, mode_T);
4313 if (proj == pn_Load_res) {
4314 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_res);
4315 } else if (proj == pn_Load_M) {
4316 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_mem);
4318 } else if (is_ia32_xLoad(new_pred)) {
4321 return new_rd_Proj(dbgi, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4323 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_xLoad_M);
4324 case pn_Load_X_regular:
4325 return new_rd_Jmp(dbgi, block);
4326 case pn_Load_X_except:
4327 /* This Load might raise an exception. Mark it. */
4328 set_ia32_exc_label(new_pred, 1);
4329 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4333 } else if (is_ia32_vfld(new_pred)) {
4336 return new_rd_Proj(dbgi, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4338 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_vfld_M);
4339 case pn_Load_X_regular:
4340 return new_rd_Jmp(dbgi, block);
4341 case pn_Load_X_except:
4342 /* This Load might raise an exception. Mark it. */
4343 set_ia32_exc_label(new_pred, 1);
4344 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_vfld_X_exc);
4349 /* can happen for ProJMs when source address mode happened for the
4352 /* however it should not be the result proj, as that would mean the
4353 load had multiple users and should not have been used for
4355 if (proj != pn_Load_M) {
4356 panic("internal error: transformed node not a Load");
4358 return new_rd_Proj(dbgi, block, new_pred, mode_M, 1);
4361 panic("No idea how to transform proj");
4365 * Transform and renumber the Projs from a DivMod like instruction.
4367 static ir_node *gen_Proj_DivMod(ir_node *node)
4369 ir_node *block = be_transform_node(get_nodes_block(node));
4370 ir_node *pred = get_Proj_pred(node);
4371 ir_node *new_pred = be_transform_node(pred);
4372 dbg_info *dbgi = get_irn_dbg_info(node);
4373 long proj = get_Proj_proj(node);
4375 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4377 switch (get_irn_opcode(pred)) {
4381 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4383 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4384 case pn_Div_X_regular:
4385 return new_rd_Jmp(dbgi, block);
4386 case pn_Div_X_except:
4387 set_ia32_exc_label(new_pred, 1);
4388 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4396 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4398 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4399 case pn_Mod_X_except:
4400 set_ia32_exc_label(new_pred, 1);
4401 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4409 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4410 case pn_DivMod_res_div:
4411 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4412 case pn_DivMod_res_mod:
4413 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4414 case pn_DivMod_X_regular:
4415 return new_rd_Jmp(dbgi, block);
4416 case pn_DivMod_X_except:
4417 set_ia32_exc_label(new_pred, 1);
4418 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4427 panic("No idea how to transform proj->DivMod");
4431 * Transform and renumber the Projs from a CopyB.
4433 static ir_node *gen_Proj_CopyB(ir_node *node)
4435 ir_node *block = be_transform_node(get_nodes_block(node));
4436 ir_node *pred = get_Proj_pred(node);
4437 ir_node *new_pred = be_transform_node(pred);
4438 dbg_info *dbgi = get_irn_dbg_info(node);
4439 long proj = get_Proj_proj(node);
4442 case pn_CopyB_M_regular:
4443 if (is_ia32_CopyB_i(new_pred)) {
4444 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4445 } else if (is_ia32_CopyB(new_pred)) {
4446 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_CopyB_M);
4453 panic("No idea how to transform proj->CopyB");
4457 * Transform and renumber the Projs from a Quot.
4459 static ir_node *gen_Proj_Quot(ir_node *node)
4461 ir_node *block = be_transform_node(get_nodes_block(node));
4462 ir_node *pred = get_Proj_pred(node);
4463 ir_node *new_pred = be_transform_node(pred);
4464 dbg_info *dbgi = get_irn_dbg_info(node);
4465 long proj = get_Proj_proj(node);
4469 if (is_ia32_xDiv(new_pred)) {
4470 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_xDiv_M);
4471 } else if (is_ia32_vfdiv(new_pred)) {
4472 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4476 if (is_ia32_xDiv(new_pred)) {
4477 return new_rd_Proj(dbgi, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4478 } else if (is_ia32_vfdiv(new_pred)) {
4479 return new_rd_Proj(dbgi, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4482 case pn_Quot_X_regular:
4483 case pn_Quot_X_except:
4488 panic("No idea how to transform proj->Quot");
4491 static ir_node *gen_be_Call(ir_node *node)
4493 dbg_info *const dbgi = get_irn_dbg_info(node);
4494 ir_node *const src_block = get_nodes_block(node);
4495 ir_node *const block = be_transform_node(src_block);
4496 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4497 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4498 ir_node *const sp = be_transform_node(src_sp);
4499 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4500 ia32_address_mode_t am;
4501 ia32_address_t *const addr = &am.addr;
4506 ir_node * eax = noreg_GP;
4507 ir_node * ecx = noreg_GP;
4508 ir_node * edx = noreg_GP;
4509 unsigned const pop = be_Call_get_pop(node);
4510 ir_type *const call_tp = be_Call_get_type(node);
4511 int old_no_pic_adjust;
4513 /* Run the x87 simulator if the call returns a float value */
4514 if (get_method_n_ress(call_tp) > 0) {
4515 ir_type *const res_type = get_method_res_type(call_tp, 0);
4516 ir_mode *const res_mode = get_type_mode(res_type);
4518 if (res_mode != NULL && mode_is_float(res_mode)) {
4519 env_cg->do_x87_sim = 1;
4523 /* We do not want be_Call direct calls */
4524 assert(be_Call_get_entity(node) == NULL);
4526 /* special case for PIC trampoline calls */
4527 old_no_pic_adjust = no_pic_adjust;
4528 no_pic_adjust = env_cg->birg->main_env->options->pic;
4530 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4531 match_am | match_immediate);
4533 no_pic_adjust = old_no_pic_adjust;
4535 i = get_irn_arity(node) - 1;
4536 fpcw = be_transform_node(get_irn_n(node, i--));
4537 for (; i >= be_pos_Call_first_arg; --i) {
4538 arch_register_req_t const *const req = arch_get_register_req(node, i);
4539 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4541 assert(req->type == arch_register_req_type_limited);
4542 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4544 switch (*req->limited) {
4545 case 1 << REG_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4546 case 1 << REG_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4547 case 1 << REG_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4548 default: panic("Invalid GP register for register parameter");
4552 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4553 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4554 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4555 set_am_attributes(call, &am);
4556 call = fix_mem_proj(call, &am);
4558 if (get_irn_pinned(node) == op_pin_state_pinned)
4559 set_irn_pinned(call, op_pin_state_pinned);
4561 SET_IA32_ORIG_NODE(call, node);
4563 if (ia32_cg_config.use_sse2) {
4564 /* remember this call for post-processing */
4565 ARR_APP1(ir_node *, call_list, call);
4566 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4573 * Transform Builtin trap
4575 static ir_node *gen_trap(ir_node *node) {
4576 dbg_info *dbgi = get_irn_dbg_info(node);
4577 ir_node *block = be_transform_node(get_nodes_block(node));
4578 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4580 return new_bd_ia32_UD2(dbgi, block, mem);
4584 * Transform Builtin debugbreak
4586 static ir_node *gen_debugbreak(ir_node *node) {
4587 dbg_info *dbgi = get_irn_dbg_info(node);
4588 ir_node *block = be_transform_node(get_nodes_block(node));
4589 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4591 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4595 * Transform Builtin return_address
4597 static ir_node *gen_return_address(ir_node *node) {
4598 ir_node *param = get_Builtin_param(node, 0);
4599 ir_node *frame = get_Builtin_param(node, 1);
4600 dbg_info *dbgi = get_irn_dbg_info(node);
4601 tarval *tv = get_Const_tarval(param);
4602 unsigned long value = get_tarval_long(tv);
4604 ir_node *block = be_transform_node(get_nodes_block(node));
4605 ir_node *ptr = be_transform_node(frame);
4609 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4610 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4611 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4614 /* load the return address from this frame */
4615 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4617 set_irn_pinned(load, get_irn_pinned(node));
4618 set_ia32_op_type(load, ia32_AddrModeS);
4619 set_ia32_ls_mode(load, mode_Iu);
4621 set_ia32_am_offs_int(load, 0);
4622 set_ia32_use_frame(load);
4623 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4625 if (get_irn_pinned(node) == op_pin_state_floats) {
4626 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4627 && pn_ia32_vfld_res == pn_ia32_Load_res
4628 && pn_ia32_Load_res == pn_ia32_res);
4629 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4632 SET_IA32_ORIG_NODE(load, node);
4633 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4637 * Transform Builtin frame_address
4639 static ir_node *gen_frame_address(ir_node *node) {
4640 ir_node *param = get_Builtin_param(node, 0);
4641 ir_node *frame = get_Builtin_param(node, 1);
4642 dbg_info *dbgi = get_irn_dbg_info(node);
4643 tarval *tv = get_Const_tarval(param);
4644 unsigned long value = get_tarval_long(tv);
4646 ir_node *block = be_transform_node(get_nodes_block(node));
4647 ir_node *ptr = be_transform_node(frame);
4652 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4653 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4654 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4657 /* load the frame address from this frame */
4658 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4660 set_irn_pinned(load, get_irn_pinned(node));
4661 set_ia32_op_type(load, ia32_AddrModeS);
4662 set_ia32_ls_mode(load, mode_Iu);
4664 ent = ia32_get_frame_address_entity();
4666 set_ia32_am_offs_int(load, 0);
4667 set_ia32_use_frame(load);
4668 set_ia32_frame_ent(load, ent);
4670 /* will fail anyway, but gcc does this: */
4671 set_ia32_am_offs_int(load, 0);
4674 if (get_irn_pinned(node) == op_pin_state_floats) {
4675 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4676 && pn_ia32_vfld_res == pn_ia32_Load_res
4677 && pn_ia32_Load_res == pn_ia32_res);
4678 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4681 SET_IA32_ORIG_NODE(load, node);
4682 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4686 * Transform Builtin frame_address
4688 static ir_node *gen_prefetch(ir_node *node) {
4690 ir_node *ptr, *block, *mem, *base, *index;
4691 ir_node *param, *new_node;
4694 ia32_address_t addr;
4696 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4697 /* no prefetch at all, route memory */
4698 return be_transform_node(get_Builtin_mem(node));
4701 param = get_Builtin_param(node, 1);
4702 tv = get_Const_tarval(param);
4703 rw = get_tarval_long(tv);
4705 /* construct load address */
4706 memset(&addr, 0, sizeof(addr));
4707 ptr = get_Builtin_param(node, 0);
4708 ia32_create_address_mode(&addr, ptr, 0);
4715 base = be_transform_node(base);
4718 if (index == NULL) {
4721 index = be_transform_node(index);
4724 dbgi = get_irn_dbg_info(node);
4725 block = be_transform_node(get_nodes_block(node));
4726 mem = be_transform_node(get_Builtin_mem(node));
4728 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4729 /* we have 3DNow!, this was already checked above */
4730 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4731 } else if (ia32_cg_config.use_sse_prefetch) {
4732 /* note: rw == 1 is IGNORED in that case */
4733 param = get_Builtin_param(node, 2);
4734 tv = get_Const_tarval(param);
4735 locality = get_tarval_long(tv);
4737 /* SSE style prefetch */
4740 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4743 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4746 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4749 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4753 assert(ia32_cg_config.use_3dnow_prefetch);
4754 /* 3DNow! style prefetch */
4755 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4758 set_irn_pinned(new_node, get_irn_pinned(node));
4759 set_ia32_op_type(new_node, ia32_AddrModeS);
4760 set_ia32_ls_mode(new_node, mode_Bu);
4761 set_address(new_node, &addr);
4763 SET_IA32_ORIG_NODE(new_node, node);
4765 be_dep_on_frame(new_node);
4766 return new_r_Proj(block, new_node, mode_M, pn_ia32_Prefetch_M);
4770 * Transform bsf like node
4772 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4774 ir_node *param = get_Builtin_param(node, 0);
4775 dbg_info *dbgi = get_irn_dbg_info(node);
4777 ir_node *block = get_nodes_block(node);
4778 ir_node *new_block = be_transform_node(block);
4780 ia32_address_mode_t am;
4781 ia32_address_t *addr = &am.addr;
4784 match_arguments(&am, block, NULL, param, NULL, match_am);
4786 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4787 set_am_attributes(cnt, &am);
4788 set_ia32_ls_mode(cnt, get_irn_mode(param));
4790 SET_IA32_ORIG_NODE(cnt, node);
4791 return fix_mem_proj(cnt, &am);
4795 * Transform builtin ffs.
4797 static ir_node *gen_ffs(ir_node *node)
4799 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
4800 ir_node *real = skip_Proj(bsf);
4801 dbg_info *dbgi = get_irn_dbg_info(real);
4802 ir_node *block = get_nodes_block(real);
4803 ir_node *flag, *set, *conv, *neg, *or;
4806 if (get_irn_mode(real) != mode_T) {
4807 set_irn_mode(real, mode_T);
4808 bsf = new_r_Proj(block, real, mode_Iu, pn_ia32_res);
4811 flag = new_r_Proj(block, real, mode_b, pn_ia32_flags);
4814 set = new_bd_ia32_Setcc(dbgi, block, flag, pn_Cmp_Eq);
4815 SET_IA32_ORIG_NODE(set, node);
4818 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
4819 SET_IA32_ORIG_NODE(conv, node);
4822 neg = new_bd_ia32_Neg(dbgi, block, conv);
4825 or = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
4826 set_ia32_commutative(or);
4829 return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, ia32_create_Immediate(NULL, 0, 1));
4833 * Transform builtin clz.
4835 static ir_node *gen_clz(ir_node *node)
4837 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
4838 ir_node *real = skip_Proj(bsr);
4839 dbg_info *dbgi = get_irn_dbg_info(real);
4840 ir_node *block = get_nodes_block(real);
4841 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
4843 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
4847 * Transform builtin ctz.
4849 static ir_node *gen_ctz(ir_node *node)
4851 return gen_unop_AM(node, new_bd_ia32_Bsf);
4855 * Transform builtin parity.
4857 static ir_node *gen_parity(ir_node *node)
4859 ir_node *param = get_Builtin_param(node, 0);
4860 dbg_info *dbgi = get_irn_dbg_info(node);
4862 ir_node *block = get_nodes_block(node);
4864 ir_node *new_block = be_transform_node(block);
4865 ir_node *imm, *cmp, *new_node;
4867 ia32_address_mode_t am;
4868 ia32_address_t *addr = &am.addr;
4872 match_arguments(&am, block, NULL, param, NULL, match_am);
4873 imm = ia32_create_Immediate(NULL, 0, 0);
4874 cmp = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
4875 addr->mem, imm, am.new_op2, am.ins_permuted, 0);
4876 set_am_attributes(cmp, &am);
4877 set_ia32_ls_mode(cmp, mode_Iu);
4879 SET_IA32_ORIG_NODE(cmp, node);
4881 cmp = fix_mem_proj(cmp, &am);
4884 new_node = new_bd_ia32_Setcc(dbgi, new_block, cmp, ia32_pn_Cmp_parity);
4885 SET_IA32_ORIG_NODE(new_node, node);
4888 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
4889 nomem, new_node, mode_Bu);
4890 SET_IA32_ORIG_NODE(new_node, node);
4895 * Transform builtin popcount
4897 static ir_node *gen_popcount(ir_node *node) {
4898 ir_node *param = get_Builtin_param(node, 0);
4899 dbg_info *dbgi = get_irn_dbg_info(node);
4901 ir_node *block = get_nodes_block(node);
4902 ir_node *new_block = be_transform_node(block);
4905 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
4907 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
4908 if (ia32_cg_config.use_popcnt) {
4909 ia32_address_mode_t am;
4910 ia32_address_t *addr = &am.addr;
4913 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
4915 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4916 set_am_attributes(cnt, &am);
4917 set_ia32_ls_mode(cnt, get_irn_mode(param));
4919 SET_IA32_ORIG_NODE(cnt, node);
4920 return fix_mem_proj(cnt, &am);
4923 new_param = be_transform_node(param);
4925 /* do the standard popcount algo */
4927 /* m1 = x & 0x55555555 */
4928 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
4929 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
4932 simm = ia32_create_Immediate(NULL, 0, 1);
4933 s1 = new_bd_ia32_Shl(dbgi, new_block, new_param, simm);
4935 /* m2 = s1 & 0x55555555 */
4936 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
4939 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
4941 /* m4 = m3 & 0x33333333 */
4942 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
4943 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
4946 simm = ia32_create_Immediate(NULL, 0, 2);
4947 s2 = new_bd_ia32_Shl(dbgi, new_block, m3, simm);
4949 /* m5 = s2 & 0x33333333 */
4950 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
4953 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
4955 /* m7 = m6 & 0x0F0F0F0F */
4956 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
4957 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
4960 simm = ia32_create_Immediate(NULL, 0, 4);
4961 s3 = new_bd_ia32_Shl(dbgi, new_block, m6, simm);
4963 /* m8 = s3 & 0x0F0F0F0F */
4964 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
4967 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
4969 /* m10 = m9 & 0x00FF00FF */
4970 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
4971 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
4974 simm = ia32_create_Immediate(NULL, 0, 8);
4975 s4 = new_bd_ia32_Shl(dbgi, new_block, m9, simm);
4977 /* m11 = s4 & 0x00FF00FF */
4978 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
4980 /* m12 = m10 + m11 */
4981 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
4983 /* m13 = m12 & 0x0000FFFF */
4984 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
4985 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
4987 /* s5 = m12 >> 16 */
4988 simm = ia32_create_Immediate(NULL, 0, 16);
4989 s5 = new_bd_ia32_Shl(dbgi, new_block, m12, simm);
4991 /* res = m13 + s5 */
4992 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
4996 * Transform builtin byte swap.
4998 static ir_node *gen_bswap(ir_node *node) {
4999 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5000 dbg_info *dbgi = get_irn_dbg_info(node);
5002 ir_node *block = get_nodes_block(node);
5003 ir_node *new_block = be_transform_node(block);
5004 ir_mode *mode = get_irn_mode(param);
5005 unsigned size = get_mode_size_bits(mode);
5006 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5010 if (ia32_cg_config.use_i486) {
5011 /* swap available */
5012 return new_bd_ia32_Bswap(dbgi, new_block, param);
5014 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5015 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5017 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5018 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5020 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5022 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5023 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5025 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5026 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5029 /* swap16 always available */
5030 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5033 panic("Invalid bswap size (%d)", size);
5038 * Transform builtin outport.
5040 static ir_node *gen_outport(ir_node *node) {
5041 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5042 ir_node *oldv = get_Builtin_param(node, 1);
5043 ir_mode *mode = get_irn_mode(oldv);
5044 ir_node *value = be_transform_node(oldv);
5045 ir_node *block = be_transform_node(get_nodes_block(node));
5046 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5047 dbg_info *dbgi = get_irn_dbg_info(node);
5049 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5050 set_ia32_ls_mode(res, mode);
5055 * Transform builtin inport.
5057 static ir_node *gen_inport(ir_node *node) {
5058 ir_type *tp = get_Builtin_type(node);
5059 ir_type *rstp = get_method_res_type(tp, 0);
5060 ir_mode *mode = get_type_mode(rstp);
5061 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5062 ir_node *block = be_transform_node(get_nodes_block(node));
5063 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5064 dbg_info *dbgi = get_irn_dbg_info(node);
5066 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5067 set_ia32_ls_mode(res, mode);
5069 /* check for missing Result Proj */
5074 * Transform a builtin inner trampoline
5076 static ir_node *gen_inner_trampoline(ir_node *node) {
5077 ir_node *ptr = get_Builtin_param(node, 0);
5078 ir_node *callee = get_Builtin_param(node, 1);
5079 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5080 ir_node *mem = get_Builtin_mem(node);
5081 ir_node *block = get_nodes_block(node);
5082 ir_node *new_block = be_transform_node(block);
5086 ir_node *trampoline;
5088 dbg_info *dbgi = get_irn_dbg_info(node);
5089 ia32_address_t addr;
5091 /* construct store address */
5092 memset(&addr, 0, sizeof(addr));
5093 ia32_create_address_mode(&addr, ptr, 0);
5095 if (addr.base == NULL) {
5096 addr.base = noreg_GP;
5098 addr.base = be_transform_node(addr.base);
5101 if (addr.index == NULL) {
5102 addr.index = noreg_GP;
5104 addr.index = be_transform_node(addr.index);
5106 addr.mem = be_transform_node(mem);
5108 /* mov ecx, <env> */
5109 val = ia32_create_Immediate(NULL, 0, 0xB9);
5110 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5111 addr.index, addr.mem, val);
5112 set_irn_pinned(store, get_irn_pinned(node));
5113 set_ia32_op_type(store, ia32_AddrModeD);
5114 set_ia32_ls_mode(store, mode_Bu);
5115 set_address(store, &addr);
5119 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5120 addr.index, addr.mem, env);
5121 set_irn_pinned(store, get_irn_pinned(node));
5122 set_ia32_op_type(store, ia32_AddrModeD);
5123 set_ia32_ls_mode(store, mode_Iu);
5124 set_address(store, &addr);
5128 /* jmp rel <callee> */
5129 val = ia32_create_Immediate(NULL, 0, 0xE9);
5130 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5131 addr.index, addr.mem, val);
5132 set_irn_pinned(store, get_irn_pinned(node));
5133 set_ia32_op_type(store, ia32_AddrModeD);
5134 set_ia32_ls_mode(store, mode_Bu);
5135 set_address(store, &addr);
5139 trampoline = be_transform_node(ptr);
5141 /* the callee is typically an immediate */
5142 if (is_SymConst(callee)) {
5143 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5145 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), ia32_create_Immediate(NULL, 0, -10));
5147 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5149 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5150 addr.index, addr.mem, rel);
5151 set_irn_pinned(store, get_irn_pinned(node));
5152 set_ia32_op_type(store, ia32_AddrModeD);
5153 set_ia32_ls_mode(store, mode_Iu);
5154 set_address(store, &addr);
5159 return new_r_Tuple(new_block, 2, in);
5163 * Transform Builtin node.
5165 static ir_node *gen_Builtin(ir_node *node) {
5166 ir_builtin_kind kind = get_Builtin_kind(node);
5170 return gen_trap(node);
5171 case ir_bk_debugbreak:
5172 return gen_debugbreak(node);
5173 case ir_bk_return_address:
5174 return gen_return_address(node);
5175 case ir_bk_frame_address:
5176 return gen_frame_address(node);
5177 case ir_bk_prefetch:
5178 return gen_prefetch(node);
5180 return gen_ffs(node);
5182 return gen_clz(node);
5184 return gen_ctz(node);
5186 return gen_parity(node);
5187 case ir_bk_popcount:
5188 return gen_popcount(node);
5190 return gen_bswap(node);
5192 return gen_outport(node);
5194 return gen_inport(node);
5195 case ir_bk_inner_trampoline:
5196 return gen_inner_trampoline(node);
5198 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5202 * Transform Proj(Builtin) node.
5204 static ir_node *gen_Proj_Builtin(ir_node *proj) {
5205 ir_node *node = get_Proj_pred(proj);
5206 ir_node *new_node = be_transform_node(node);
5207 ir_builtin_kind kind = get_Builtin_kind(node);
5210 case ir_bk_return_address:
5211 case ir_bk_frame_address:
5216 case ir_bk_popcount:
5218 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5221 case ir_bk_debugbreak:
5222 case ir_bk_prefetch:
5224 assert(get_Proj_proj(proj) == pn_Builtin_M);
5227 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5228 return new_r_Proj(get_nodes_block(new_node),
5229 new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5231 assert(get_Proj_proj(proj) == pn_Builtin_M);
5232 return new_r_Proj(get_nodes_block(new_node),
5233 new_node, mode_M, pn_ia32_Inport_M);
5235 case ir_bk_inner_trampoline:
5236 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5237 return get_Tuple_pred(new_node, 1);
5239 assert(get_Proj_proj(proj) == pn_Builtin_M);
5240 return get_Tuple_pred(new_node, 0);
5243 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5246 static ir_node *gen_be_IncSP(ir_node *node)
5248 ir_node *res = be_duplicate_node(node);
5249 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5255 * Transform the Projs from a be_Call.
5257 static ir_node *gen_Proj_be_Call(ir_node *node)
5259 ir_node *block = be_transform_node(get_nodes_block(node));
5260 ir_node *call = get_Proj_pred(node);
5261 ir_node *new_call = be_transform_node(call);
5262 dbg_info *dbgi = get_irn_dbg_info(node);
5263 long proj = get_Proj_proj(node);
5264 ir_mode *mode = get_irn_mode(node);
5267 if (proj == pn_be_Call_M_regular) {
5268 return new_rd_Proj(dbgi, block, new_call, mode_M, n_ia32_Call_mem);
5270 /* transform call modes */
5271 if (mode_is_data(mode)) {
5272 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5276 /* Map from be_Call to ia32_Call proj number */
5277 if (proj == pn_be_Call_sp) {
5278 proj = pn_ia32_Call_stack;
5279 } else if (proj == pn_be_Call_M_regular) {
5280 proj = pn_ia32_Call_M;
5282 arch_register_req_t const *const req = arch_get_register_req_out(node);
5283 int const n_outs = arch_irn_get_n_outs(new_call);
5286 assert(proj >= pn_be_Call_first_res);
5287 assert(req->type & arch_register_req_type_limited);
5289 for (i = 0; i < n_outs; ++i) {
5290 arch_register_req_t const *const new_req
5291 = arch_get_out_register_req(new_call, i);
5293 if (!(new_req->type & arch_register_req_type_limited) ||
5294 new_req->cls != req->cls ||
5295 *new_req->limited != *req->limited)
5304 res = new_rd_Proj(dbgi, block, new_call, mode, proj);
5306 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5308 case pn_ia32_Call_stack:
5309 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
5312 case pn_ia32_Call_fpcw:
5313 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
5321 * Transform the Projs from a Cmp.
5323 static ir_node *gen_Proj_Cmp(ir_node *node)
5325 /* this probably means not all mode_b nodes were lowered... */
5326 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5331 * Transform the Projs from a Bound.
5333 static ir_node *gen_Proj_Bound(ir_node *node)
5335 ir_node *new_node, *block;
5336 ir_node *pred = get_Proj_pred(node);
5338 switch (get_Proj_proj(node)) {
5340 return be_transform_node(get_Bound_mem(pred));
5341 case pn_Bound_X_regular:
5342 new_node = be_transform_node(pred);
5343 block = get_nodes_block(new_node);
5344 return new_r_Proj(block, new_node, mode_X, pn_ia32_Jcc_true);
5345 case pn_Bound_X_except:
5346 new_node = be_transform_node(pred);
5347 block = get_nodes_block(new_node);
5348 return new_r_Proj(block, new_node, mode_X, pn_ia32_Jcc_false);
5350 return be_transform_node(get_Bound_index(pred));
5352 panic("unsupported Proj from Bound");
5356 static ir_node *gen_Proj_ASM(ir_node *node)
5358 ir_mode *mode = get_irn_mode(node);
5359 ir_node *pred = get_Proj_pred(node);
5360 ir_node *new_pred = be_transform_node(pred);
5361 ir_node *block = get_nodes_block(new_pred);
5362 long pos = get_Proj_proj(node);
5364 if (mode == mode_M) {
5365 pos = arch_irn_get_n_outs(new_pred)-1;
5366 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5368 } else if (mode_is_float(mode)) {
5371 panic("unexpected proj mode at ASM");
5374 return new_r_Proj(block, new_pred, mode, pos);
5378 * Transform and potentially renumber Proj nodes.
5380 static ir_node *gen_Proj(ir_node *node)
5382 ir_node *pred = get_Proj_pred(node);
5385 switch (get_irn_opcode(pred)) {
5387 proj = get_Proj_proj(node);
5388 if (proj == pn_Store_M) {
5389 return be_transform_node(pred);
5391 panic("No idea how to transform proj->Store");
5394 return gen_Proj_Load(node);
5396 return gen_Proj_ASM(node);
5398 return gen_Proj_Builtin(node);
5402 return gen_Proj_DivMod(node);
5404 return gen_Proj_CopyB(node);
5406 return gen_Proj_Quot(node);
5408 return gen_Proj_be_SubSP(node);
5410 return gen_Proj_be_AddSP(node);
5412 return gen_Proj_be_Call(node);
5414 return gen_Proj_Cmp(node);
5416 return gen_Proj_Bound(node);
5418 proj = get_Proj_proj(node);
5420 case pn_Start_X_initial_exec: {
5421 ir_node *block = get_nodes_block(pred);
5422 ir_node *new_block = be_transform_node(block);
5423 dbg_info *dbgi = get_irn_dbg_info(node);
5424 /* we exchange the ProjX with a jump */
5425 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5430 case pn_Start_P_tls:
5431 return gen_Proj_tls(node);
5436 if (is_ia32_l_FloattoLL(pred)) {
5437 return gen_Proj_l_FloattoLL(node);
5439 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5443 ir_mode *mode = get_irn_mode(node);
5444 if (ia32_mode_needs_gp_reg(mode)) {
5445 ir_node *new_pred = be_transform_node(pred);
5446 ir_node *block = be_transform_node(get_nodes_block(node));
5447 ir_node *new_proj = new_r_Proj(block, new_pred,
5448 mode_Iu, get_Proj_proj(node));
5449 new_proj->node_nr = node->node_nr;
5454 return be_duplicate_node(node);
5458 * Enters all transform functions into the generic pointer
5460 static void register_transformers(void)
5462 /* first clear the generic function pointer for all ops */
5463 clear_irp_opcodes_generic_func();
5465 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5466 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5506 /* transform ops from intrinsic lowering */
5518 GEN(ia32_l_LLtoFloat);
5519 GEN(ia32_l_FloattoLL);
5525 /* we should never see these nodes */
5540 /* handle builtins */
5543 /* handle generic backend nodes */
5557 * Pre-transform all unknown and noreg nodes.
5559 static void ia32_pretransform_node(void)
5561 ia32_code_gen_t *cg = env_cg;
5563 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5564 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5565 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5566 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5567 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5568 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5570 nomem = get_irg_no_mem(current_ir_graph);
5571 noreg_GP = ia32_new_NoReg_gp(cg);
5577 * Walker, checks if all ia32 nodes producing more than one result have their
5578 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
5580 static void add_missing_keep_walker(ir_node *node, void *data)
5583 unsigned found_projs = 0;
5584 const ir_edge_t *edge;
5585 ir_mode *mode = get_irn_mode(node);
5590 if (!is_ia32_irn(node))
5593 n_outs = arch_irn_get_n_outs(node);
5596 if (is_ia32_SwitchJmp(node))
5599 assert(n_outs < (int) sizeof(unsigned) * 8);
5600 foreach_out_edge(node, edge) {
5601 ir_node *proj = get_edge_src_irn(edge);
5604 /* The node could be kept */
5608 if (get_irn_mode(proj) == mode_M)
5611 pn = get_Proj_proj(proj);
5612 assert(pn < n_outs);
5613 found_projs |= 1 << pn;
5617 /* are keeps missing? */
5619 for (i = 0; i < n_outs; ++i) {
5622 const arch_register_req_t *req;
5623 const arch_register_class_t *cls;
5625 if (found_projs & (1 << i)) {
5629 req = arch_get_out_register_req(node, i);
5634 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5638 block = get_nodes_block(node);
5639 in[0] = new_r_Proj(block, node, arch_register_class_mode(cls), i);
5640 if (last_keep != NULL) {
5641 be_Keep_add_node(last_keep, cls, in[0]);
5643 last_keep = be_new_Keep(block, 1, in);
5644 if (sched_is_scheduled(node)) {
5645 sched_add_after(node, last_keep);
5652 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5655 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5657 ir_graph *irg = be_get_birg_irg(cg->birg);
5658 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5662 * Post-process all calls if we are in SSE mode.
5663 * The ABI requires that the results are in st0, copy them
5664 * to a xmm register.
5666 static void postprocess_fp_call_results(void) {
5669 for (i = ARR_LEN(call_list) - 1; i >= 0; --i) {
5670 ir_node *call = call_list[i];
5671 ir_type *mtp = call_types[i];
5674 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5675 ir_type *res_tp = get_method_res_type(mtp, j);
5676 ir_node *res, *new_res;
5677 const ir_edge_t *edge, *next;
5680 if (! is_atomic_type(res_tp)) {
5681 /* no floating point return */
5684 mode = get_type_mode(res_tp);
5685 if (! mode_is_float(mode)) {
5686 /* no floating point return */
5690 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5693 /* now patch the users */
5694 foreach_out_edge_safe(res, edge, next) {
5695 ir_node *succ = get_edge_src_irn(edge);
5698 if (be_is_Keep(succ))
5701 if (is_ia32_xStore(succ)) {
5702 /* an xStore can be patched into an vfst */
5703 dbg_info *db = get_irn_dbg_info(succ);
5704 ir_node *block = get_nodes_block(succ);
5705 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5706 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5707 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5708 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5709 ir_mode *mode = get_ia32_ls_mode(succ);
5711 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5712 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5713 if (is_ia32_use_frame(succ))
5714 set_ia32_use_frame(st);
5715 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5716 set_irn_pinned(st, get_irn_pinned(succ));
5717 set_ia32_op_type(st, ia32_AddrModeD);
5721 if (new_res == NULL) {
5722 dbg_info *db = get_irn_dbg_info(call);
5723 ir_node *block = get_nodes_block(call);
5724 ir_node *frame = get_irg_frame(current_ir_graph);
5725 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5726 ir_node *call_mem = new_r_Proj(block, call, mode_M, pn_ia32_Call_M);
5727 ir_node *vfst, *xld, *new_mem;
5729 /* store st(0) on stack */
5730 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5731 set_ia32_op_type(vfst, ia32_AddrModeD);
5732 set_ia32_use_frame(vfst);
5734 /* load into SSE register */
5735 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5736 set_ia32_op_type(xld, ia32_AddrModeS);
5737 set_ia32_use_frame(xld);
5739 new_res = new_r_Proj(block, xld, mode, pn_ia32_xLoad_res);
5740 new_mem = new_r_Proj(block, xld, mode_M, pn_ia32_xLoad_M);
5742 if (old_mem != NULL) {
5743 edges_reroute(old_mem, new_mem, current_ir_graph);
5747 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5754 /* do the transformation */
5755 void ia32_transform_graph(ia32_code_gen_t *cg)
5759 register_transformers();
5761 initial_fpcw = NULL;
5764 be_timer_push(T_HEIGHTS);
5765 heights = heights_new(cg->irg);
5766 be_timer_pop(T_HEIGHTS);
5767 ia32_calculate_non_address_mode_nodes(cg->birg);
5769 /* the transform phase is not safe for CSE (yet) because several nodes get
5770 * attributes set after their creation */
5771 cse_last = get_opt_cse();
5774 call_list = NEW_ARR_F(ir_node *, 0);
5775 call_types = NEW_ARR_F(ir_type *, 0);
5776 be_transform_graph(cg->birg, ia32_pretransform_node);
5778 if (ia32_cg_config.use_sse2)
5779 postprocess_fp_call_results();
5780 DEL_ARR_F(call_types);
5781 DEL_ARR_F(call_list);
5783 set_opt_cse(cse_last);
5785 ia32_free_non_address_mode_nodes();
5786 heights_free(heights);
5790 void ia32_init_transform(void)
5792 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");