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_t.h"
52 #include "../besched.h"
54 #include "../beutil.h"
55 #include "../beirg_t.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 SFP_SIGN "0x80000000"
74 #define DFP_SIGN "0x8000000000000000"
75 #define SFP_ABS "0x7FFFFFFF"
76 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
78 #define ULL_BIAS "18446744073709551616"
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS "ia32_sfp_abs"
83 #define TP_DFP_ABS "ia32_dfp_abs"
84 #define TP_ULL_BIAS "ia32_ull_bias"
86 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
87 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
88 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
89 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
90 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
92 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
97 static ir_node *initial_fpcw = NULL;
99 extern ir_op *get_op_Mulh(void);
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
102 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
106 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
110 ir_node *op1, ir_node *op2);
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
113 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
115 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
116 ir_node *base, ir_node *index, ir_node *mem);
118 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
119 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
122 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
124 static ir_node *create_immediate_or_transform(ir_node *node,
125 char immediate_constraint_type);
127 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
128 dbg_info *dbgi, ir_node *block,
129 ir_node *op, ir_node *orig_node);
131 /** Return non-zero is a node represents the 0 constant. */
132 static bool is_Const_0(ir_node *node)
134 return is_Const(node) && is_Const_null(node);
137 /** Return non-zero is a node represents the 1 constant. */
138 static bool is_Const_1(ir_node *node)
140 return is_Const(node) && is_Const_one(node);
143 /** Return non-zero is a node represents the -1 constant. */
144 static bool is_Const_Minus_1(ir_node *node)
146 return is_Const(node) && is_Const_all_one(node);
150 * returns true if constant can be created with a simple float command
152 static bool is_simple_x87_Const(ir_node *node)
154 tarval *tv = get_Const_tarval(node);
155 if (tarval_is_null(tv) || tarval_is_one(tv))
158 /* TODO: match all the other float constants */
163 * returns true if constant can be created with a simple float command
165 static bool is_simple_sse_Const(ir_node *node)
167 tarval *tv = get_Const_tarval(node);
168 ir_mode *mode = get_tarval_mode(tv);
173 if (tarval_is_null(tv) || tarval_is_one(tv))
176 if (mode == mode_D) {
177 unsigned val = get_tarval_sub_bits(tv, 0) |
178 (get_tarval_sub_bits(tv, 1) << 8) |
179 (get_tarval_sub_bits(tv, 2) << 16) |
180 (get_tarval_sub_bits(tv, 3) << 24);
182 /* lower 32bit are zero, really a 32bit constant */
186 /* TODO: match all the other float constants */
191 * Transforms a Const.
193 static ir_node *gen_Const(ir_node *node)
195 ir_node *old_block = get_nodes_block(node);
196 ir_node *block = be_transform_node(old_block);
197 dbg_info *dbgi = get_irn_dbg_info(node);
198 ir_mode *mode = get_irn_mode(node);
200 assert(is_Const(node));
202 if (mode_is_float(mode)) {
204 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
205 ir_node *nomem = new_NoMem();
209 if (ia32_cg_config.use_sse2) {
210 tarval *tv = get_Const_tarval(node);
211 if (tarval_is_null(tv)) {
212 load = new_bd_ia32_xZero(dbgi, block);
213 set_ia32_ls_mode(load, mode);
215 } else if (tarval_is_one(tv)) {
216 int cnst = mode == mode_F ? 26 : 55;
217 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
218 ir_node *imm2 = create_Immediate(NULL, 0, 2);
219 ir_node *pslld, *psrld;
221 load = new_bd_ia32_xAllOnes(dbgi, block);
222 set_ia32_ls_mode(load, mode);
223 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
224 set_ia32_ls_mode(pslld, mode);
225 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
226 set_ia32_ls_mode(psrld, mode);
228 } else if (mode == mode_F) {
229 /* we can place any 32bit constant by using a movd gp, sse */
230 unsigned val = get_tarval_sub_bits(tv, 0) |
231 (get_tarval_sub_bits(tv, 1) << 8) |
232 (get_tarval_sub_bits(tv, 2) << 16) |
233 (get_tarval_sub_bits(tv, 3) << 24);
234 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
235 load = new_bd_ia32_xMovd(dbgi, block, cnst);
236 set_ia32_ls_mode(load, mode);
239 if (mode == mode_D) {
240 unsigned val = get_tarval_sub_bits(tv, 0) |
241 (get_tarval_sub_bits(tv, 1) << 8) |
242 (get_tarval_sub_bits(tv, 2) << 16) |
243 (get_tarval_sub_bits(tv, 3) << 24);
245 ir_node *imm32 = create_Immediate(NULL, 0, 32);
246 ir_node *cnst, *psllq;
248 /* fine, lower 32bit are zero, produce 32bit value */
249 val = get_tarval_sub_bits(tv, 4) |
250 (get_tarval_sub_bits(tv, 5) << 8) |
251 (get_tarval_sub_bits(tv, 6) << 16) |
252 (get_tarval_sub_bits(tv, 7) << 24);
253 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
254 load = new_bd_ia32_xMovd(dbgi, block, cnst);
255 set_ia32_ls_mode(load, mode);
256 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
257 set_ia32_ls_mode(psllq, mode);
262 floatent = create_float_const_entity(node);
264 load = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem,
266 set_ia32_op_type(load, ia32_AddrModeS);
267 set_ia32_am_sc(load, floatent);
268 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
269 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
272 if (is_Const_null(node)) {
273 load = new_bd_ia32_vfldz(dbgi, block);
275 set_ia32_ls_mode(load, mode);
276 } else if (is_Const_one(node)) {
277 load = new_bd_ia32_vfld1(dbgi, block);
279 set_ia32_ls_mode(load, mode);
281 floatent = create_float_const_entity(node);
283 load = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
284 set_ia32_op_type(load, ia32_AddrModeS);
285 set_ia32_am_sc(load, floatent);
286 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
287 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
288 /* take the mode from the entity */
289 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
293 SET_IA32_ORIG_NODE(load, node);
295 be_dep_on_frame(load);
297 } else { /* non-float mode */
299 tarval *tv = get_Const_tarval(node);
302 tv = tarval_convert_to(tv, mode_Iu);
304 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
306 panic("couldn't convert constant tarval (%+F)", node);
308 val = get_tarval_long(tv);
310 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
311 SET_IA32_ORIG_NODE(cnst, node);
313 be_dep_on_frame(cnst);
319 * Transforms a SymConst.
321 static ir_node *gen_SymConst(ir_node *node)
323 ir_node *old_block = get_nodes_block(node);
324 ir_node *block = be_transform_node(old_block);
325 dbg_info *dbgi = get_irn_dbg_info(node);
326 ir_mode *mode = get_irn_mode(node);
329 if (mode_is_float(mode)) {
330 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
331 ir_node *nomem = new_NoMem();
333 if (ia32_cg_config.use_sse2)
334 cnst = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem, mode_E);
336 cnst = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode_E);
337 set_ia32_am_sc(cnst, get_SymConst_entity(node));
338 set_ia32_use_frame(cnst);
342 if (get_SymConst_kind(node) != symconst_addr_ent) {
343 panic("backend only support symconst_addr_ent (at %+F)", node);
345 entity = get_SymConst_entity(node);
346 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
349 SET_IA32_ORIG_NODE(cnst, node);
351 be_dep_on_frame(cnst);
355 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
356 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
358 static const struct {
360 const char *ent_name;
361 const char *cnst_str;
364 } names [ia32_known_const_max] = {
365 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
366 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
367 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
368 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
369 { TP_ULL_BIAS, ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
371 static ir_entity *ent_cache[ia32_known_const_max];
373 const char *tp_name, *ent_name, *cnst_str;
379 ent_name = names[kct].ent_name;
380 if (! ent_cache[kct]) {
381 tp_name = names[kct].tp_name;
382 cnst_str = names[kct].cnst_str;
384 switch (names[kct].mode) {
385 case 0: mode = mode_Iu; break;
386 case 1: mode = mode_Lu; break;
387 default: mode = mode_F; break;
389 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
390 tp = new_type_primitive(new_id_from_str(tp_name), mode);
391 /* set the specified alignment */
392 set_type_alignment_bytes(tp, names[kct].align);
394 if (kct == ia32_ULLBIAS) {
395 /* we are in the backend, construct a fixed type here */
396 unsigned size = get_type_size_bytes(tp);
397 tp = new_type_array(new_id_from_str(tp_name), 1, tp);
398 set_type_alignment_bytes(tp, names[kct].align);
399 set_type_size_bytes(tp, 2 * size);
400 set_type_state(tp, layout_fixed);
402 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
404 set_entity_ld_ident(ent, get_entity_ident(ent));
405 set_entity_visibility(ent, visibility_local);
406 set_entity_variability(ent, variability_constant);
407 set_entity_allocation(ent, allocation_static);
409 if (kct == ia32_ULLBIAS) {
410 ir_initializer_t *initializer = create_initializer_compound(2);
412 set_initializer_compound_value(initializer, 0,
413 create_initializer_tarval(get_tarval_null(mode)));
414 set_initializer_compound_value(initializer, 1,
415 create_initializer_tarval(tv));
417 set_entity_initializer(ent, initializer);
419 set_entity_initializer(ent, create_initializer_tarval(tv));
422 /* cache the entry */
423 ent_cache[kct] = ent;
426 return ent_cache[kct];
430 * return true if the node is a Proj(Load) and could be used in source address
431 * mode for another node. Will return only true if the @p other node is not
432 * dependent on the memory of the Load (for binary operations use the other
433 * input here, for unary operations use NULL).
435 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
436 ir_node *other, ir_node *other2, match_flags_t flags)
441 /* float constants are always available */
442 if (is_Const(node)) {
443 ir_mode *mode = get_irn_mode(node);
444 if (mode_is_float(mode)) {
445 if (ia32_cg_config.use_sse2) {
446 if (is_simple_sse_Const(node))
449 if (is_simple_x87_Const(node))
452 if (get_irn_n_edges(node) > 1)
460 load = get_Proj_pred(node);
461 pn = get_Proj_proj(node);
462 if (!is_Load(load) || pn != pn_Load_res)
464 if (get_nodes_block(load) != block)
466 /* we only use address mode if we're the only user of the load */
467 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
469 /* in some edge cases with address mode we might reach the load normally
470 * and through some AM sequence, if it is already materialized then we
471 * can't create an AM node from it */
472 if (be_is_transformed(node))
475 /* don't do AM if other node inputs depend on the load (via mem-proj) */
476 if (other != NULL && prevents_AM(block, load, other))
479 if (other2 != NULL && prevents_AM(block, load, other2))
485 typedef struct ia32_address_mode_t ia32_address_mode_t;
486 struct ia32_address_mode_t {
491 ia32_op_type_t op_type;
495 unsigned commutative : 1;
496 unsigned ins_permuted : 1;
499 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
503 /* construct load address */
504 memset(addr, 0, sizeof(addr[0]));
505 ia32_create_address_mode(addr, ptr, 0);
507 noreg_gp = ia32_new_NoReg_gp(env_cg);
508 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
509 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
510 addr->mem = be_transform_node(mem);
513 static void build_address(ia32_address_mode_t *am, ir_node *node,
514 ia32_create_am_flags_t flags)
516 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
517 ia32_address_t *addr = &am->addr;
523 if (is_Const(node)) {
524 ir_entity *entity = create_float_const_entity(node);
525 addr->base = noreg_gp;
526 addr->index = noreg_gp;
527 addr->mem = new_NoMem();
528 addr->symconst_ent = entity;
530 am->ls_mode = get_type_mode(get_entity_type(entity));
531 am->pinned = op_pin_state_floats;
535 load = get_Proj_pred(node);
536 ptr = get_Load_ptr(load);
537 mem = get_Load_mem(load);
538 new_mem = be_transform_node(mem);
539 am->pinned = get_irn_pinned(load);
540 am->ls_mode = get_Load_mode(load);
541 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
544 /* construct load address */
545 ia32_create_address_mode(addr, ptr, flags);
547 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
548 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
552 static void set_address(ir_node *node, const ia32_address_t *addr)
554 set_ia32_am_scale(node, addr->scale);
555 set_ia32_am_sc(node, addr->symconst_ent);
556 set_ia32_am_offs_int(node, addr->offset);
557 if (addr->symconst_sign)
558 set_ia32_am_sc_sign(node);
560 set_ia32_use_frame(node);
561 set_ia32_frame_ent(node, addr->frame_entity);
565 * Apply attributes of a given address mode to a node.
567 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
569 set_address(node, &am->addr);
571 set_ia32_op_type(node, am->op_type);
572 set_ia32_ls_mode(node, am->ls_mode);
573 if (am->pinned == op_pin_state_pinned) {
574 /* beware: some nodes are already pinned and did not allow to change the state */
575 if (get_irn_pinned(node) != op_pin_state_pinned)
576 set_irn_pinned(node, op_pin_state_pinned);
579 set_ia32_commutative(node);
583 * Check, if a given node is a Down-Conv, ie. a integer Conv
584 * from a mode with a mode with more bits to a mode with lesser bits.
585 * Moreover, we return only true if the node has not more than 1 user.
587 * @param node the node
588 * @return non-zero if node is a Down-Conv
590 static int is_downconv(const ir_node *node)
598 /* we only want to skip the conv when we're the only user
599 * (not optimal but for now...)
601 if (get_irn_n_edges(node) > 1)
604 src_mode = get_irn_mode(get_Conv_op(node));
605 dest_mode = get_irn_mode(node);
607 ia32_mode_needs_gp_reg(src_mode) &&
608 ia32_mode_needs_gp_reg(dest_mode) &&
609 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
612 /* Skip all Down-Conv's on a given node and return the resulting node. */
613 ir_node *ia32_skip_downconv(ir_node *node)
615 while (is_downconv(node))
616 node = get_Conv_op(node);
621 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
623 ir_mode *mode = get_irn_mode(node);
628 if (mode_is_signed(mode)) {
633 block = get_nodes_block(node);
634 dbgi = get_irn_dbg_info(node);
636 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
640 * matches operands of a node into ia32 addressing/operand modes. This covers
641 * usage of source address mode, immediates, operations with non 32-bit modes,
643 * The resulting data is filled into the @p am struct. block is the block
644 * of the node whose arguments are matched. op1, op2 are the first and second
645 * input that are matched (op1 may be NULL). other_op is another unrelated
646 * input that is not matched! but which is needed sometimes to check if AM
647 * for op1/op2 is legal.
648 * @p flags describes the supported modes of the operation in detail.
650 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
651 ir_node *op1, ir_node *op2, ir_node *other_op,
654 ia32_address_t *addr = &am->addr;
655 ir_mode *mode = get_irn_mode(op2);
656 int mode_bits = get_mode_size_bits(mode);
657 ir_node *noreg_gp, *new_op1, *new_op2;
659 unsigned commutative;
660 int use_am_and_immediates;
663 memset(am, 0, sizeof(am[0]));
665 commutative = (flags & match_commutative) != 0;
666 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
667 use_am = (flags & match_am) != 0;
668 use_immediate = (flags & match_immediate) != 0;
669 assert(!use_am_and_immediates || use_immediate);
672 assert(!commutative || op1 != NULL);
673 assert(use_am || !(flags & match_8bit_am));
674 assert(use_am || !(flags & match_16bit_am));
676 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
677 (mode_bits == 16 && !(flags & match_16bit_am))) {
681 /* we can simply skip downconvs for mode neutral nodes: the upper bits
682 * can be random for these operations */
683 if (flags & match_mode_neutral) {
684 op2 = ia32_skip_downconv(op2);
686 op1 = ia32_skip_downconv(op1);
690 /* match immediates. firm nodes are normalized: constants are always on the
693 if (!(flags & match_try_am) && use_immediate) {
694 new_op2 = try_create_Immediate(op2, 0);
697 noreg_gp = ia32_new_NoReg_gp(env_cg);
698 if (new_op2 == NULL &&
699 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
700 build_address(am, op2, 0);
701 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
702 if (mode_is_float(mode)) {
703 new_op2 = ia32_new_NoReg_vfp(env_cg);
707 am->op_type = ia32_AddrModeS;
708 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
710 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
712 build_address(am, op1, 0);
714 if (mode_is_float(mode)) {
715 noreg = ia32_new_NoReg_vfp(env_cg);
720 if (new_op2 != NULL) {
723 new_op1 = be_transform_node(op2);
725 am->ins_permuted = 1;
727 am->op_type = ia32_AddrModeS;
729 am->op_type = ia32_Normal;
731 if (flags & match_try_am) {
737 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
739 new_op2 = be_transform_node(op2);
741 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
743 if (addr->base == NULL)
744 addr->base = noreg_gp;
745 if (addr->index == NULL)
746 addr->index = noreg_gp;
747 if (addr->mem == NULL)
748 addr->mem = new_NoMem();
750 am->new_op1 = new_op1;
751 am->new_op2 = new_op2;
752 am->commutative = commutative;
755 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
760 if (am->mem_proj == NULL)
763 /* we have to create a mode_T so the old MemProj can attach to us */
764 mode = get_irn_mode(node);
765 load = get_Proj_pred(am->mem_proj);
767 be_set_transformed_node(load, node);
769 if (mode != mode_T) {
770 set_irn_mode(node, mode_T);
771 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
778 * Construct a standard binary operation, set AM and immediate if required.
780 * @param node The original node for which the binop is created
781 * @param op1 The first operand
782 * @param op2 The second operand
783 * @param func The node constructor function
784 * @return The constructed ia32 node.
786 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
787 construct_binop_func *func, match_flags_t flags)
790 ir_node *block, *new_block, *new_node;
791 ia32_address_mode_t am;
792 ia32_address_t *addr = &am.addr;
794 block = get_nodes_block(node);
795 match_arguments(&am, block, op1, op2, NULL, flags);
797 dbgi = get_irn_dbg_info(node);
798 new_block = be_transform_node(block);
799 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
800 am.new_op1, am.new_op2);
801 set_am_attributes(new_node, &am);
802 /* we can't use source address mode anymore when using immediates */
803 if (!(flags & match_am_and_immediates) &&
804 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
805 set_ia32_am_support(new_node, ia32_am_none);
806 SET_IA32_ORIG_NODE(new_node, node);
808 new_node = fix_mem_proj(new_node, &am);
815 n_ia32_l_binop_right,
816 n_ia32_l_binop_eflags
818 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
819 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
820 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
821 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
822 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
823 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
826 * Construct a binary operation which also consumes the eflags.
828 * @param node The node to transform
829 * @param func The node constructor function
830 * @param flags The match flags
831 * @return The constructor ia32 node
833 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
836 ir_node *src_block = get_nodes_block(node);
837 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
838 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
839 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
841 ir_node *block, *new_node, *new_eflags;
842 ia32_address_mode_t am;
843 ia32_address_t *addr = &am.addr;
845 match_arguments(&am, src_block, op1, op2, eflags, flags);
847 dbgi = get_irn_dbg_info(node);
848 block = be_transform_node(src_block);
849 new_eflags = be_transform_node(eflags);
850 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
851 am.new_op1, am.new_op2, new_eflags);
852 set_am_attributes(new_node, &am);
853 /* we can't use source address mode anymore when using immediates */
854 if (!(flags & match_am_and_immediates) &&
855 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
856 set_ia32_am_support(new_node, ia32_am_none);
857 SET_IA32_ORIG_NODE(new_node, node);
859 new_node = fix_mem_proj(new_node, &am);
864 static ir_node *get_fpcw(void)
867 if (initial_fpcw != NULL)
870 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
871 &ia32_fp_cw_regs[REG_FPCW]);
872 initial_fpcw = be_transform_node(fpcw);
878 * Construct a standard binary operation, set AM and immediate if required.
880 * @param op1 The first operand
881 * @param op2 The second operand
882 * @param func The node constructor function
883 * @return The constructed ia32 node.
885 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
886 construct_binop_float_func *func)
888 ir_mode *mode = get_irn_mode(node);
890 ir_node *block, *new_block, *new_node;
891 ia32_address_mode_t am;
892 ia32_address_t *addr = &am.addr;
893 ia32_x87_attr_t *attr;
894 /* All operations are considered commutative, because there are reverse
896 match_flags_t flags = match_commutative;
898 /* cannot use address mode with long double on x87 */
899 if (get_mode_size_bits(mode) <= 64)
902 block = get_nodes_block(node);
903 match_arguments(&am, block, op1, op2, NULL, flags);
905 dbgi = get_irn_dbg_info(node);
906 new_block = be_transform_node(block);
907 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
908 am.new_op1, am.new_op2, get_fpcw());
909 set_am_attributes(new_node, &am);
911 attr = get_ia32_x87_attr(new_node);
912 attr->attr.data.ins_permuted = am.ins_permuted;
914 SET_IA32_ORIG_NODE(new_node, node);
916 new_node = fix_mem_proj(new_node, &am);
922 * Construct a shift/rotate binary operation, sets AM and immediate if required.
924 * @param op1 The first operand
925 * @param op2 The second operand
926 * @param func The node constructor function
927 * @return The constructed ia32 node.
929 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
930 construct_shift_func *func,
934 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
936 assert(! mode_is_float(get_irn_mode(node)));
937 assert(flags & match_immediate);
938 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
940 if (flags & match_mode_neutral) {
941 op1 = ia32_skip_downconv(op1);
942 new_op1 = be_transform_node(op1);
943 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
944 new_op1 = create_upconv(op1, node);
946 new_op1 = be_transform_node(op1);
949 /* the shift amount can be any mode that is bigger than 5 bits, since all
950 * other bits are ignored anyway */
951 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
952 ir_node *const op = get_Conv_op(op2);
953 if (mode_is_float(get_irn_mode(op)))
956 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
958 new_op2 = create_immediate_or_transform(op2, 0);
960 dbgi = get_irn_dbg_info(node);
961 block = get_nodes_block(node);
962 new_block = be_transform_node(block);
963 new_node = func(dbgi, new_block, new_op1, new_op2);
964 SET_IA32_ORIG_NODE(new_node, node);
966 /* lowered shift instruction may have a dependency operand, handle it here */
967 if (get_irn_arity(node) == 3) {
968 /* we have a dependency */
969 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
970 add_irn_dep(new_node, new_dep);
978 * Construct a standard unary operation, set AM and immediate if required.
980 * @param op The operand
981 * @param func The node constructor function
982 * @return The constructed ia32 node.
984 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
988 ir_node *block, *new_block, *new_op, *new_node;
990 assert(flags == 0 || flags == match_mode_neutral);
991 if (flags & match_mode_neutral) {
992 op = ia32_skip_downconv(op);
995 new_op = be_transform_node(op);
996 dbgi = get_irn_dbg_info(node);
997 block = get_nodes_block(node);
998 new_block = be_transform_node(block);
999 new_node = func(dbgi, new_block, new_op);
1001 SET_IA32_ORIG_NODE(new_node, node);
1006 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1007 ia32_address_t *addr)
1009 ir_node *base, *index, *res;
1013 base = ia32_new_NoReg_gp(env_cg);
1015 base = be_transform_node(base);
1018 index = addr->index;
1019 if (index == NULL) {
1020 index = ia32_new_NoReg_gp(env_cg);
1022 index = be_transform_node(index);
1025 res = new_bd_ia32_Lea(dbgi, block, base, index);
1026 set_address(res, addr);
1032 * Returns non-zero if a given address mode has a symbolic or
1033 * numerical offset != 0.
1035 static int am_has_immediates(const ia32_address_t *addr)
1037 return addr->offset != 0 || addr->symconst_ent != NULL
1038 || addr->frame_entity || addr->use_frame;
1042 * Creates an ia32 Add.
1044 * @return the created ia32 Add node
1046 static ir_node *gen_Add(ir_node *node)
1048 ir_mode *mode = get_irn_mode(node);
1049 ir_node *op1 = get_Add_left(node);
1050 ir_node *op2 = get_Add_right(node);
1052 ir_node *block, *new_block, *new_node, *add_immediate_op;
1053 ia32_address_t addr;
1054 ia32_address_mode_t am;
1056 if (mode_is_float(mode)) {
1057 if (ia32_cg_config.use_sse2)
1058 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1059 match_commutative | match_am);
1061 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1064 ia32_mark_non_am(node);
1066 op2 = ia32_skip_downconv(op2);
1067 op1 = ia32_skip_downconv(op1);
1071 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1072 * 1. Add with immediate -> Lea
1073 * 2. Add with possible source address mode -> Add
1074 * 3. Otherwise -> Lea
1076 memset(&addr, 0, sizeof(addr));
1077 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1078 add_immediate_op = NULL;
1080 dbgi = get_irn_dbg_info(node);
1081 block = get_nodes_block(node);
1082 new_block = be_transform_node(block);
1085 if (addr.base == NULL && addr.index == NULL) {
1086 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1087 addr.symconst_sign, addr.offset);
1088 be_dep_on_frame(new_node);
1089 SET_IA32_ORIG_NODE(new_node, node);
1092 /* add with immediate? */
1093 if (addr.index == NULL) {
1094 add_immediate_op = addr.base;
1095 } else if (addr.base == NULL && addr.scale == 0) {
1096 add_immediate_op = addr.index;
1099 if (add_immediate_op != NULL) {
1100 if (!am_has_immediates(&addr)) {
1101 #ifdef DEBUG_libfirm
1102 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1105 return be_transform_node(add_immediate_op);
1108 new_node = create_lea_from_address(dbgi, new_block, &addr);
1109 SET_IA32_ORIG_NODE(new_node, node);
1113 /* test if we can use source address mode */
1114 match_arguments(&am, block, op1, op2, NULL, match_commutative
1115 | match_mode_neutral | match_am | match_immediate | match_try_am);
1117 /* construct an Add with source address mode */
1118 if (am.op_type == ia32_AddrModeS) {
1119 ia32_address_t *am_addr = &am.addr;
1120 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1121 am_addr->index, am_addr->mem, am.new_op1,
1123 set_am_attributes(new_node, &am);
1124 SET_IA32_ORIG_NODE(new_node, node);
1126 new_node = fix_mem_proj(new_node, &am);
1131 /* otherwise construct a lea */
1132 new_node = create_lea_from_address(dbgi, new_block, &addr);
1133 SET_IA32_ORIG_NODE(new_node, node);
1138 * Creates an ia32 Mul.
1140 * @return the created ia32 Mul node
1142 static ir_node *gen_Mul(ir_node *node)
1144 ir_node *op1 = get_Mul_left(node);
1145 ir_node *op2 = get_Mul_right(node);
1146 ir_mode *mode = get_irn_mode(node);
1148 if (mode_is_float(mode)) {
1149 if (ia32_cg_config.use_sse2)
1150 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1151 match_commutative | match_am);
1153 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1155 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1156 match_commutative | match_am | match_mode_neutral |
1157 match_immediate | match_am_and_immediates);
1161 * Creates an ia32 Mulh.
1162 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1163 * this result while Mul returns the lower 32 bit.
1165 * @return the created ia32 Mulh node
1167 static ir_node *gen_Mulh(ir_node *node)
1169 ir_node *block = get_nodes_block(node);
1170 ir_node *new_block = be_transform_node(block);
1171 dbg_info *dbgi = get_irn_dbg_info(node);
1172 ir_node *op1 = get_Mulh_left(node);
1173 ir_node *op2 = get_Mulh_right(node);
1174 ir_mode *mode = get_irn_mode(node);
1176 ir_node *proj_res_high;
1178 if (mode_is_signed(mode)) {
1179 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1180 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1181 mode_Iu, pn_ia32_IMul1OP_res_high);
1183 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1184 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1185 mode_Iu, pn_ia32_Mul_res_high);
1187 return proj_res_high;
1191 * Creates an ia32 And.
1193 * @return The created ia32 And node
1195 static ir_node *gen_And(ir_node *node)
1197 ir_node *op1 = get_And_left(node);
1198 ir_node *op2 = get_And_right(node);
1199 assert(! mode_is_float(get_irn_mode(node)));
1201 /* is it a zero extension? */
1202 if (is_Const(op2)) {
1203 tarval *tv = get_Const_tarval(op2);
1204 long v = get_tarval_long(tv);
1206 if (v == 0xFF || v == 0xFFFF) {
1207 dbg_info *dbgi = get_irn_dbg_info(node);
1208 ir_node *block = get_nodes_block(node);
1215 assert(v == 0xFFFF);
1218 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1223 return gen_binop(node, op1, op2, new_bd_ia32_And,
1224 match_commutative | match_mode_neutral | match_am | match_immediate);
1230 * Creates an ia32 Or.
1232 * @return The created ia32 Or node
1234 static ir_node *gen_Or(ir_node *node)
1236 ir_node *op1 = get_Or_left(node);
1237 ir_node *op2 = get_Or_right(node);
1239 assert (! mode_is_float(get_irn_mode(node)));
1240 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1241 | match_mode_neutral | match_am | match_immediate);
1247 * Creates an ia32 Eor.
1249 * @return The created ia32 Eor node
1251 static ir_node *gen_Eor(ir_node *node)
1253 ir_node *op1 = get_Eor_left(node);
1254 ir_node *op2 = get_Eor_right(node);
1256 assert(! mode_is_float(get_irn_mode(node)));
1257 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1258 | match_mode_neutral | match_am | match_immediate);
1263 * Creates an ia32 Sub.
1265 * @return The created ia32 Sub node
1267 static ir_node *gen_Sub(ir_node *node)
1269 ir_node *op1 = get_Sub_left(node);
1270 ir_node *op2 = get_Sub_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_xSub, match_am);
1277 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1280 if (is_Const(op2)) {
1281 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1285 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1286 | match_am | match_immediate);
1289 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1290 ir_node *const src_val,
1291 ir_node *const src_mem,
1292 ir_node *const am_mem)
1294 if (is_NoMem(am_mem)) {
1295 return be_transform_node(src_mem);
1296 } else if (is_Proj(src_val) &&
1298 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1299 /* avoid memory loop */
1301 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1302 ir_node *const ptr_pred = get_Proj_pred(src_val);
1303 int const arity = get_Sync_n_preds(src_mem);
1308 NEW_ARR_A(ir_node*, ins, arity + 1);
1310 /* NOTE: This sometimes produces dead-code because the old sync in
1311 * src_mem might not be used anymore, we should detect this case
1312 * and kill the sync... */
1313 for (i = arity - 1; i >= 0; --i) {
1314 ir_node *const pred = get_Sync_pred(src_mem, i);
1316 /* avoid memory loop */
1317 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1320 ins[n++] = be_transform_node(pred);
1325 return new_r_Sync(irg, block, n, ins);
1329 ins[0] = be_transform_node(src_mem);
1331 return new_r_Sync(irg, block, 2, ins);
1335 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1336 ir_node *val, const ir_node *orig)
1341 if (ia32_cg_config.use_short_sex_eax) {
1342 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1343 be_dep_on_frame(pval);
1344 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1346 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1347 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1349 SET_IA32_ORIG_NODE(res, orig);
1354 * Generates an ia32 DivMod with additional infrastructure for the
1355 * register allocator if needed.
1357 static ir_node *create_Div(ir_node *node)
1359 dbg_info *dbgi = get_irn_dbg_info(node);
1360 ir_node *block = get_nodes_block(node);
1361 ir_node *new_block = be_transform_node(block);
1368 ir_node *sign_extension;
1369 ia32_address_mode_t am;
1370 ia32_address_t *addr = &am.addr;
1372 /* the upper bits have random contents for smaller modes */
1373 switch (get_irn_opcode(node)) {
1375 op1 = get_Div_left(node);
1376 op2 = get_Div_right(node);
1377 mem = get_Div_mem(node);
1378 mode = get_Div_resmode(node);
1381 op1 = get_Mod_left(node);
1382 op2 = get_Mod_right(node);
1383 mem = get_Mod_mem(node);
1384 mode = get_Mod_resmode(node);
1387 op1 = get_DivMod_left(node);
1388 op2 = get_DivMod_right(node);
1389 mem = get_DivMod_mem(node);
1390 mode = get_DivMod_resmode(node);
1393 panic("invalid divmod node %+F", node);
1396 match_arguments(&am, block, op1, op2, NULL, match_am);
1398 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1399 is the memory of the consumed address. We can have only the second op as address
1400 in Div nodes, so check only op2. */
1401 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1403 if (mode_is_signed(mode)) {
1404 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1405 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1406 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1408 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1409 be_dep_on_frame(sign_extension);
1411 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1412 addr->index, new_mem, am.new_op2,
1413 am.new_op1, sign_extension);
1416 set_irn_pinned(new_node, get_irn_pinned(node));
1418 set_am_attributes(new_node, &am);
1419 SET_IA32_ORIG_NODE(new_node, node);
1421 new_node = fix_mem_proj(new_node, &am);
1427 static ir_node *gen_Mod(ir_node *node)
1429 return create_Div(node);
1432 static ir_node *gen_Div(ir_node *node)
1434 return create_Div(node);
1437 static ir_node *gen_DivMod(ir_node *node)
1439 return create_Div(node);
1445 * Creates an ia32 floating Div.
1447 * @return The created ia32 xDiv node
1449 static ir_node *gen_Quot(ir_node *node)
1451 ir_node *op1 = get_Quot_left(node);
1452 ir_node *op2 = get_Quot_right(node);
1454 if (ia32_cg_config.use_sse2) {
1455 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1457 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1463 * Creates an ia32 Shl.
1465 * @return The created ia32 Shl node
1467 static ir_node *gen_Shl(ir_node *node)
1469 ir_node *left = get_Shl_left(node);
1470 ir_node *right = get_Shl_right(node);
1472 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1473 match_mode_neutral | match_immediate);
1477 * Creates an ia32 Shr.
1479 * @return The created ia32 Shr node
1481 static ir_node *gen_Shr(ir_node *node)
1483 ir_node *left = get_Shr_left(node);
1484 ir_node *right = get_Shr_right(node);
1486 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1492 * Creates an ia32 Sar.
1494 * @return The created ia32 Shrs node
1496 static ir_node *gen_Shrs(ir_node *node)
1498 ir_node *left = get_Shrs_left(node);
1499 ir_node *right = get_Shrs_right(node);
1501 if (is_Const(right)) {
1502 tarval *tv = get_Const_tarval(right);
1503 long val = get_tarval_long(tv);
1505 /* this is a sign extension */
1506 dbg_info *dbgi = get_irn_dbg_info(node);
1507 ir_node *block = be_transform_node(get_nodes_block(node));
1508 ir_node *new_op = be_transform_node(left);
1510 return create_sex_32_64(dbgi, block, new_op, node);
1514 /* 8 or 16 bit sign extension? */
1515 if (is_Const(right) && is_Shl(left)) {
1516 ir_node *shl_left = get_Shl_left(left);
1517 ir_node *shl_right = get_Shl_right(left);
1518 if (is_Const(shl_right)) {
1519 tarval *tv1 = get_Const_tarval(right);
1520 tarval *tv2 = get_Const_tarval(shl_right);
1521 if (tv1 == tv2 && tarval_is_long(tv1)) {
1522 long val = get_tarval_long(tv1);
1523 if (val == 16 || val == 24) {
1524 dbg_info *dbgi = get_irn_dbg_info(node);
1525 ir_node *block = get_nodes_block(node);
1535 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1544 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1550 * Creates an ia32 Rol.
1552 * @param op1 The first operator
1553 * @param op2 The second operator
1554 * @return The created ia32 RotL node
1556 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1558 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1564 * Creates an ia32 Ror.
1565 * NOTE: There is no RotR with immediate because this would always be a RotL
1566 * "imm-mode_size_bits" which can be pre-calculated.
1568 * @param op1 The first operator
1569 * @param op2 The second operator
1570 * @return The created ia32 RotR node
1572 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1574 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1580 * Creates an ia32 RotR or RotL (depending on the found pattern).
1582 * @return The created ia32 RotL or RotR node
1584 static ir_node *gen_Rotl(ir_node *node)
1586 ir_node *rotate = NULL;
1587 ir_node *op1 = get_Rotl_left(node);
1588 ir_node *op2 = get_Rotl_right(node);
1590 /* Firm has only RotL, so we are looking for a right (op2)
1591 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1592 that means we can create a RotR instead of an Add and a RotL */
1596 ir_node *left = get_Add_left(add);
1597 ir_node *right = get_Add_right(add);
1598 if (is_Const(right)) {
1599 tarval *tv = get_Const_tarval(right);
1600 ir_mode *mode = get_irn_mode(node);
1601 long bits = get_mode_size_bits(mode);
1603 if (is_Minus(left) &&
1604 tarval_is_long(tv) &&
1605 get_tarval_long(tv) == bits &&
1608 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1609 rotate = gen_Ror(node, op1, get_Minus_op(left));
1614 if (rotate == NULL) {
1615 rotate = gen_Rol(node, op1, op2);
1624 * Transforms a Minus node.
1626 * @return The created ia32 Minus node
1628 static ir_node *gen_Minus(ir_node *node)
1630 ir_node *op = get_Minus_op(node);
1631 ir_node *block = be_transform_node(get_nodes_block(node));
1632 dbg_info *dbgi = get_irn_dbg_info(node);
1633 ir_mode *mode = get_irn_mode(node);
1638 if (mode_is_float(mode)) {
1639 ir_node *new_op = be_transform_node(op);
1640 if (ia32_cg_config.use_sse2) {
1641 /* TODO: non-optimal... if we have many xXors, then we should
1642 * rather create a load for the const and use that instead of
1643 * several AM nodes... */
1644 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1645 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1646 ir_node *nomem = new_NoMem();
1648 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1649 nomem, new_op, noreg_xmm);
1651 size = get_mode_size_bits(mode);
1652 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1654 set_ia32_am_sc(new_node, ent);
1655 set_ia32_op_type(new_node, ia32_AddrModeS);
1656 set_ia32_ls_mode(new_node, mode);
1658 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1661 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1664 SET_IA32_ORIG_NODE(new_node, node);
1670 * Transforms a Not node.
1672 * @return The created ia32 Not node
1674 static ir_node *gen_Not(ir_node *node)
1676 ir_node *op = get_Not_op(node);
1678 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1679 assert (! mode_is_float(get_irn_mode(node)));
1681 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1687 * Transforms an Abs node.
1689 * @return The created ia32 Abs node
1691 static ir_node *gen_Abs(ir_node *node)
1693 ir_node *block = get_nodes_block(node);
1694 ir_node *new_block = be_transform_node(block);
1695 ir_node *op = get_Abs_op(node);
1696 dbg_info *dbgi = get_irn_dbg_info(node);
1697 ir_mode *mode = get_irn_mode(node);
1698 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1699 ir_node *nomem = new_NoMem();
1705 if (mode_is_float(mode)) {
1706 new_op = be_transform_node(op);
1708 if (ia32_cg_config.use_sse2) {
1709 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1710 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1711 nomem, new_op, noreg_fp);
1713 size = get_mode_size_bits(mode);
1714 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1716 set_ia32_am_sc(new_node, ent);
1718 SET_IA32_ORIG_NODE(new_node, node);
1720 set_ia32_op_type(new_node, ia32_AddrModeS);
1721 set_ia32_ls_mode(new_node, mode);
1723 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1724 SET_IA32_ORIG_NODE(new_node, node);
1727 ir_node *xor, *sign_extension;
1729 if (get_mode_size_bits(mode) == 32) {
1730 new_op = be_transform_node(op);
1732 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1735 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1737 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1738 nomem, new_op, sign_extension);
1739 SET_IA32_ORIG_NODE(xor, node);
1741 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1742 nomem, xor, sign_extension);
1743 SET_IA32_ORIG_NODE(new_node, node);
1750 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1752 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1754 dbg_info *dbgi = get_irn_dbg_info(cmp);
1755 ir_node *block = get_nodes_block(cmp);
1756 ir_node *new_block = be_transform_node(block);
1757 ir_node *op1 = be_transform_node(x);
1758 ir_node *op2 = be_transform_node(n);
1760 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1764 * Transform a node returning a "flag" result.
1766 * @param node the node to transform
1767 * @param pnc_out the compare mode to use
1769 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1778 /* we have a Cmp as input */
1779 if (is_Proj(node)) {
1780 ir_node *pred = get_Proj_pred(node);
1782 pn_Cmp pnc = get_Proj_proj(node);
1783 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1784 ir_node *l = get_Cmp_left(pred);
1785 ir_node *r = get_Cmp_right(pred);
1787 ir_node *la = get_And_left(l);
1788 ir_node *ra = get_And_right(l);
1790 ir_node *c = get_Shl_left(la);
1791 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1792 /* (1 << n) & ra) */
1793 ir_node *n = get_Shl_right(la);
1794 flags = gen_bt(pred, ra, n);
1795 /* we must generate a Jc/Jnc jump */
1796 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1799 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1804 ir_node *c = get_Shl_left(ra);
1805 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1806 /* la & (1 << n)) */
1807 ir_node *n = get_Shl_right(ra);
1808 flags = gen_bt(pred, la, n);
1809 /* we must generate a Jc/Jnc jump */
1810 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1813 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1819 flags = be_transform_node(pred);
1825 /* a mode_b value, we have to compare it against 0 */
1826 dbgi = get_irn_dbg_info(node);
1827 new_block = be_transform_node(get_nodes_block(node));
1828 new_op = be_transform_node(node);
1829 noreg = ia32_new_NoReg_gp(env_cg);
1830 nomem = new_NoMem();
1831 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1832 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1833 *pnc_out = pn_Cmp_Lg;
1838 * Transforms a Load.
1840 * @return the created ia32 Load node
1842 static ir_node *gen_Load(ir_node *node)
1844 ir_node *old_block = get_nodes_block(node);
1845 ir_node *block = be_transform_node(old_block);
1846 ir_node *ptr = get_Load_ptr(node);
1847 ir_node *mem = get_Load_mem(node);
1848 ir_node *new_mem = be_transform_node(mem);
1851 dbg_info *dbgi = get_irn_dbg_info(node);
1852 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1853 ir_mode *mode = get_Load_mode(node);
1856 ia32_address_t addr;
1858 /* construct load address */
1859 memset(&addr, 0, sizeof(addr));
1860 ia32_create_address_mode(&addr, ptr, 0);
1867 base = be_transform_node(base);
1870 if (index == NULL) {
1873 index = be_transform_node(index);
1876 if (mode_is_float(mode)) {
1877 if (ia32_cg_config.use_sse2) {
1878 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1880 res_mode = mode_xmm;
1882 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1884 res_mode = mode_vfp;
1887 assert(mode != mode_b);
1889 /* create a conv node with address mode for smaller modes */
1890 if (get_mode_size_bits(mode) < 32) {
1891 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1892 new_mem, noreg, mode);
1894 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1899 set_irn_pinned(new_node, get_irn_pinned(node));
1900 set_ia32_op_type(new_node, ia32_AddrModeS);
1901 set_ia32_ls_mode(new_node, mode);
1902 set_address(new_node, &addr);
1904 if (get_irn_pinned(node) == op_pin_state_floats) {
1905 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1906 && pn_ia32_vfld_res == pn_ia32_Load_res
1907 && pn_ia32_Load_res == pn_ia32_res);
1908 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1911 SET_IA32_ORIG_NODE(new_node, node);
1913 be_dep_on_frame(new_node);
1917 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1918 ir_node *ptr, ir_node *other)
1925 /* we only use address mode if we're the only user of the load */
1926 if (get_irn_n_edges(node) > 1)
1929 load = get_Proj_pred(node);
1932 if (get_nodes_block(load) != block)
1935 /* store should have the same pointer as the load */
1936 if (get_Load_ptr(load) != ptr)
1939 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1940 if (other != NULL &&
1941 get_nodes_block(other) == block &&
1942 heights_reachable_in_block(heights, other, load)) {
1946 if (prevents_AM(block, load, mem))
1948 /* Store should be attached to the load via mem */
1949 assert(heights_reachable_in_block(heights, mem, load));
1954 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1955 ir_node *mem, ir_node *ptr, ir_mode *mode,
1956 construct_binop_dest_func *func,
1957 construct_binop_dest_func *func8bit,
1958 match_flags_t flags)
1960 ir_node *src_block = get_nodes_block(node);
1962 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1969 ia32_address_mode_t am;
1970 ia32_address_t *addr = &am.addr;
1971 memset(&am, 0, sizeof(am));
1973 assert(flags & match_immediate); /* there is no destam node without... */
1974 commutative = (flags & match_commutative) != 0;
1976 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1977 build_address(&am, op1, ia32_create_am_double_use);
1978 new_op = create_immediate_or_transform(op2, 0);
1979 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1980 build_address(&am, op2, ia32_create_am_double_use);
1981 new_op = create_immediate_or_transform(op1, 0);
1986 if (addr->base == NULL)
1987 addr->base = noreg_gp;
1988 if (addr->index == NULL)
1989 addr->index = noreg_gp;
1990 if (addr->mem == NULL)
1991 addr->mem = new_NoMem();
1993 dbgi = get_irn_dbg_info(node);
1994 block = be_transform_node(src_block);
1995 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1997 if (get_mode_size_bits(mode) == 8) {
1998 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2000 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2002 set_address(new_node, addr);
2003 set_ia32_op_type(new_node, ia32_AddrModeD);
2004 set_ia32_ls_mode(new_node, mode);
2005 SET_IA32_ORIG_NODE(new_node, node);
2007 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2008 mem_proj = be_transform_node(am.mem_proj);
2009 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2014 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2015 ir_node *ptr, ir_mode *mode,
2016 construct_unop_dest_func *func)
2018 ir_node *src_block = get_nodes_block(node);
2024 ia32_address_mode_t am;
2025 ia32_address_t *addr = &am.addr;
2027 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2030 memset(&am, 0, sizeof(am));
2031 build_address(&am, op, ia32_create_am_double_use);
2033 dbgi = get_irn_dbg_info(node);
2034 block = be_transform_node(src_block);
2035 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2036 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2037 set_address(new_node, addr);
2038 set_ia32_op_type(new_node, ia32_AddrModeD);
2039 set_ia32_ls_mode(new_node, mode);
2040 SET_IA32_ORIG_NODE(new_node, node);
2042 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2043 mem_proj = be_transform_node(am.mem_proj);
2044 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2049 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2051 ir_mode *mode = get_irn_mode(node);
2052 ir_node *mux_true = get_Mux_true(node);
2053 ir_node *mux_false = get_Mux_false(node);
2063 ia32_address_t addr;
2065 if (get_mode_size_bits(mode) != 8)
2068 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2070 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2076 build_address_ptr(&addr, ptr, mem);
2078 dbgi = get_irn_dbg_info(node);
2079 block = get_nodes_block(node);
2080 new_block = be_transform_node(block);
2081 cond = get_Mux_sel(node);
2082 flags = get_flags_node(cond, &pnc);
2083 new_mem = be_transform_node(mem);
2084 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2085 addr.index, addr.mem, flags, pnc, negated);
2086 set_address(new_node, &addr);
2087 set_ia32_op_type(new_node, ia32_AddrModeD);
2088 set_ia32_ls_mode(new_node, mode);
2089 SET_IA32_ORIG_NODE(new_node, node);
2094 static ir_node *try_create_dest_am(ir_node *node)
2096 ir_node *val = get_Store_value(node);
2097 ir_node *mem = get_Store_mem(node);
2098 ir_node *ptr = get_Store_ptr(node);
2099 ir_mode *mode = get_irn_mode(val);
2100 unsigned bits = get_mode_size_bits(mode);
2105 /* handle only GP modes for now... */
2106 if (!ia32_mode_needs_gp_reg(mode))
2110 /* store must be the only user of the val node */
2111 if (get_irn_n_edges(val) > 1)
2113 /* skip pointless convs */
2115 ir_node *conv_op = get_Conv_op(val);
2116 ir_mode *pred_mode = get_irn_mode(conv_op);
2117 if (!ia32_mode_needs_gp_reg(pred_mode))
2119 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2127 /* value must be in the same block */
2128 if (get_nodes_block(node) != get_nodes_block(val))
2131 switch (get_irn_opcode(val)) {
2133 op1 = get_Add_left(val);
2134 op2 = get_Add_right(val);
2135 if (ia32_cg_config.use_incdec) {
2136 if (is_Const_1(op2)) {
2137 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2139 } else if (is_Const_Minus_1(op2)) {
2140 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2144 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2145 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2146 match_commutative | match_immediate);
2149 op1 = get_Sub_left(val);
2150 op2 = get_Sub_right(val);
2151 if (is_Const(op2)) {
2152 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2154 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2155 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2159 op1 = get_And_left(val);
2160 op2 = get_And_right(val);
2161 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2162 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2163 match_commutative | match_immediate);
2166 op1 = get_Or_left(val);
2167 op2 = get_Or_right(val);
2168 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2169 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2170 match_commutative | match_immediate);
2173 op1 = get_Eor_left(val);
2174 op2 = get_Eor_right(val);
2175 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2176 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2177 match_commutative | match_immediate);
2180 op1 = get_Shl_left(val);
2181 op2 = get_Shl_right(val);
2182 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2183 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2187 op1 = get_Shr_left(val);
2188 op2 = get_Shr_right(val);
2189 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2190 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2194 op1 = get_Shrs_left(val);
2195 op2 = get_Shrs_right(val);
2196 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2197 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2201 op1 = get_Rotl_left(val);
2202 op2 = get_Rotl_right(val);
2203 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2204 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2207 /* TODO: match ROR patterns... */
2209 new_node = try_create_SetMem(val, ptr, mem);
2212 op1 = get_Minus_op(val);
2213 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2216 /* should be lowered already */
2217 assert(mode != mode_b);
2218 op1 = get_Not_op(val);
2219 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2225 if (new_node != NULL) {
2226 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2227 get_irn_pinned(node) == op_pin_state_pinned) {
2228 set_irn_pinned(new_node, op_pin_state_pinned);
2235 static bool possible_int_mode_for_fp(ir_mode *mode)
2239 if (!mode_is_signed(mode))
2241 size = get_mode_size_bits(mode);
2242 if (size != 16 && size != 32)
2247 static int is_float_to_int_conv(const ir_node *node)
2249 ir_mode *mode = get_irn_mode(node);
2253 if (!possible_int_mode_for_fp(mode))
2258 conv_op = get_Conv_op(node);
2259 conv_mode = get_irn_mode(conv_op);
2261 if (!mode_is_float(conv_mode))
2268 * Transform a Store(floatConst) into a sequence of
2271 * @return the created ia32 Store node
2273 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2275 ir_mode *mode = get_irn_mode(cns);
2276 unsigned size = get_mode_size_bytes(mode);
2277 tarval *tv = get_Const_tarval(cns);
2278 ir_node *block = get_nodes_block(node);
2279 ir_node *new_block = be_transform_node(block);
2280 ir_node *ptr = get_Store_ptr(node);
2281 ir_node *mem = get_Store_mem(node);
2282 dbg_info *dbgi = get_irn_dbg_info(node);
2286 ia32_address_t addr;
2288 assert(size % 4 == 0);
2291 build_address_ptr(&addr, ptr, mem);
2295 get_tarval_sub_bits(tv, ofs) |
2296 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2297 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2298 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2299 ir_node *imm = create_Immediate(NULL, 0, val);
2301 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2302 addr.index, addr.mem, imm);
2304 set_irn_pinned(new_node, get_irn_pinned(node));
2305 set_ia32_op_type(new_node, ia32_AddrModeD);
2306 set_ia32_ls_mode(new_node, mode_Iu);
2307 set_address(new_node, &addr);
2308 SET_IA32_ORIG_NODE(new_node, node);
2311 ins[i++] = new_node;
2316 } while (size != 0);
2319 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2326 * Generate a vfist or vfisttp instruction.
2328 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2329 ir_node *mem, ir_node *val, ir_node **fist)
2333 if (ia32_cg_config.use_fisttp) {
2334 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2335 if other users exists */
2336 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2337 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2338 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2339 be_new_Keep(reg_class, irg, block, 1, &value);
2341 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2344 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2347 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2353 * Transforms a general (no special case) Store.
2355 * @return the created ia32 Store node
2357 static ir_node *gen_general_Store(ir_node *node)
2359 ir_node *val = get_Store_value(node);
2360 ir_mode *mode = get_irn_mode(val);
2361 ir_node *block = get_nodes_block(node);
2362 ir_node *new_block = be_transform_node(block);
2363 ir_node *ptr = get_Store_ptr(node);
2364 ir_node *mem = get_Store_mem(node);
2365 dbg_info *dbgi = get_irn_dbg_info(node);
2366 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2367 ir_node *new_val, *new_node, *store;
2368 ia32_address_t addr;
2370 /* check for destination address mode */
2371 new_node = try_create_dest_am(node);
2372 if (new_node != NULL)
2375 /* construct store address */
2376 memset(&addr, 0, sizeof(addr));
2377 ia32_create_address_mode(&addr, ptr, 0);
2379 if (addr.base == NULL) {
2382 addr.base = be_transform_node(addr.base);
2385 if (addr.index == NULL) {
2388 addr.index = be_transform_node(addr.index);
2390 addr.mem = be_transform_node(mem);
2392 if (mode_is_float(mode)) {
2393 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2395 while (is_Conv(val) && mode == get_irn_mode(val)) {
2396 ir_node *op = get_Conv_op(val);
2397 if (!mode_is_float(get_irn_mode(op)))
2401 new_val = be_transform_node(val);
2402 if (ia32_cg_config.use_sse2) {
2403 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2404 addr.index, addr.mem, new_val);
2406 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2407 addr.index, addr.mem, new_val, mode);
2410 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2411 val = get_Conv_op(val);
2413 /* TODO: is this optimisation still necessary at all (middleend)? */
2414 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2415 while (is_Conv(val)) {
2416 ir_node *op = get_Conv_op(val);
2417 if (!mode_is_float(get_irn_mode(op)))
2419 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2423 new_val = be_transform_node(val);
2424 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2426 new_val = create_immediate_or_transform(val, 0);
2427 assert(mode != mode_b);
2429 if (get_mode_size_bits(mode) == 8) {
2430 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2431 addr.index, addr.mem, new_val);
2433 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2434 addr.index, addr.mem, new_val);
2439 set_irn_pinned(store, get_irn_pinned(node));
2440 set_ia32_op_type(store, ia32_AddrModeD);
2441 set_ia32_ls_mode(store, mode);
2443 set_address(store, &addr);
2444 SET_IA32_ORIG_NODE(store, node);
2450 * Transforms a Store.
2452 * @return the created ia32 Store node
2454 static ir_node *gen_Store(ir_node *node)
2456 ir_node *val = get_Store_value(node);
2457 ir_mode *mode = get_irn_mode(val);
2459 if (mode_is_float(mode) && is_Const(val)) {
2460 /* We can transform every floating const store
2461 into a sequence of integer stores.
2462 If the constant is already in a register,
2463 it would be better to use it, but we don't
2464 have this information here. */
2465 return gen_float_const_Store(node, val);
2467 return gen_general_Store(node);
2471 * Transforms a Switch.
2473 * @return the created ia32 SwitchJmp node
2475 static ir_node *create_Switch(ir_node *node)
2477 dbg_info *dbgi = get_irn_dbg_info(node);
2478 ir_node *block = be_transform_node(get_nodes_block(node));
2479 ir_node *sel = get_Cond_selector(node);
2480 ir_node *new_sel = be_transform_node(sel);
2481 int switch_min = INT_MAX;
2482 int switch_max = INT_MIN;
2483 long default_pn = get_Cond_defaultProj(node);
2485 const ir_edge_t *edge;
2487 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2489 /* determine the smallest switch case value */
2490 foreach_out_edge(node, edge) {
2491 ir_node *proj = get_edge_src_irn(edge);
2492 long pn = get_Proj_proj(proj);
2493 if (pn == default_pn)
2496 if (pn < switch_min)
2498 if (pn > switch_max)
2502 if ((unsigned) (switch_max - switch_min) > 256000) {
2503 panic("Size of switch %+F bigger than 256000", node);
2506 if (switch_min != 0) {
2507 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2509 /* if smallest switch case is not 0 we need an additional sub */
2510 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2511 add_ia32_am_offs_int(new_sel, -switch_min);
2512 set_ia32_op_type(new_sel, ia32_AddrModeS);
2514 SET_IA32_ORIG_NODE(new_sel, node);
2517 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2518 SET_IA32_ORIG_NODE(new_node, node);
2524 * Transform a Cond node.
2526 static ir_node *gen_Cond(ir_node *node)
2528 ir_node *block = get_nodes_block(node);
2529 ir_node *new_block = be_transform_node(block);
2530 dbg_info *dbgi = get_irn_dbg_info(node);
2531 ir_node *sel = get_Cond_selector(node);
2532 ir_mode *sel_mode = get_irn_mode(sel);
2533 ir_node *flags = NULL;
2537 if (sel_mode != mode_b) {
2538 return create_Switch(node);
2541 /* we get flags from a Cmp */
2542 flags = get_flags_node(sel, &pnc);
2544 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2545 SET_IA32_ORIG_NODE(new_node, node);
2550 static ir_node *gen_be_Copy(ir_node *node)
2552 ir_node *new_node = be_duplicate_node(node);
2553 ir_mode *mode = get_irn_mode(new_node);
2555 if (ia32_mode_needs_gp_reg(mode)) {
2556 set_irn_mode(new_node, mode_Iu);
2562 static ir_node *create_Fucom(ir_node *node)
2564 dbg_info *dbgi = get_irn_dbg_info(node);
2565 ir_node *block = get_nodes_block(node);
2566 ir_node *new_block = be_transform_node(block);
2567 ir_node *left = get_Cmp_left(node);
2568 ir_node *new_left = be_transform_node(left);
2569 ir_node *right = get_Cmp_right(node);
2573 if (ia32_cg_config.use_fucomi) {
2574 new_right = be_transform_node(right);
2575 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2577 set_ia32_commutative(new_node);
2578 SET_IA32_ORIG_NODE(new_node, node);
2580 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2581 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2583 new_right = be_transform_node(right);
2584 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2587 set_ia32_commutative(new_node);
2589 SET_IA32_ORIG_NODE(new_node, node);
2591 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2592 SET_IA32_ORIG_NODE(new_node, node);
2598 static ir_node *create_Ucomi(ir_node *node)
2600 dbg_info *dbgi = get_irn_dbg_info(node);
2601 ir_node *src_block = get_nodes_block(node);
2602 ir_node *new_block = be_transform_node(src_block);
2603 ir_node *left = get_Cmp_left(node);
2604 ir_node *right = get_Cmp_right(node);
2606 ia32_address_mode_t am;
2607 ia32_address_t *addr = &am.addr;
2609 match_arguments(&am, src_block, left, right, NULL,
2610 match_commutative | match_am);
2612 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2613 addr->mem, am.new_op1, am.new_op2,
2615 set_am_attributes(new_node, &am);
2617 SET_IA32_ORIG_NODE(new_node, node);
2619 new_node = fix_mem_proj(new_node, &am);
2625 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2626 * to fold an and into a test node
2628 static bool can_fold_test_and(ir_node *node)
2630 const ir_edge_t *edge;
2632 /** we can only have eq and lg projs */
2633 foreach_out_edge(node, edge) {
2634 ir_node *proj = get_edge_src_irn(edge);
2635 pn_Cmp pnc = get_Proj_proj(proj);
2636 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2644 * returns true if it is assured, that the upper bits of a node are "clean"
2645 * which means for a 16 or 8 bit value, that the upper bits in the register
2646 * are 0 for unsigned and a copy of the last significant bit for signed
2649 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2651 assert(ia32_mode_needs_gp_reg(mode));
2652 if (get_mode_size_bits(mode) >= 32)
2655 if (is_Proj(transformed_node))
2656 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2658 switch (get_ia32_irn_opcode(transformed_node)) {
2659 case iro_ia32_Conv_I2I:
2660 case iro_ia32_Conv_I2I8Bit: {
2661 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2662 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2664 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2671 if (mode_is_signed(mode)) {
2672 return false; /* TODO handle signed modes */
2674 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2675 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2676 const ia32_immediate_attr_t *attr
2677 = get_ia32_immediate_attr_const(right);
2678 if (attr->symconst == 0 &&
2679 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2683 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2687 /* TODO too conservative if shift amount is constant */
2688 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2691 if (!mode_is_signed(mode)) {
2693 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2694 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2696 /* TODO if one is known to be zero extended, then || is sufficient */
2701 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2702 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2704 case iro_ia32_Const:
2705 case iro_ia32_Immediate: {
2706 const ia32_immediate_attr_t *attr =
2707 get_ia32_immediate_attr_const(transformed_node);
2708 if (mode_is_signed(mode)) {
2709 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2710 return shifted == 0 || shifted == -1;
2712 unsigned long shifted = (unsigned long)attr->offset;
2713 shifted >>= get_mode_size_bits(mode);
2714 return shifted == 0;
2724 * Generate code for a Cmp.
2726 static ir_node *gen_Cmp(ir_node *node)
2728 dbg_info *dbgi = get_irn_dbg_info(node);
2729 ir_node *block = get_nodes_block(node);
2730 ir_node *new_block = be_transform_node(block);
2731 ir_node *left = get_Cmp_left(node);
2732 ir_node *right = get_Cmp_right(node);
2733 ir_mode *cmp_mode = get_irn_mode(left);
2735 ia32_address_mode_t am;
2736 ia32_address_t *addr = &am.addr;
2739 if (mode_is_float(cmp_mode)) {
2740 if (ia32_cg_config.use_sse2) {
2741 return create_Ucomi(node);
2743 return create_Fucom(node);
2747 assert(ia32_mode_needs_gp_reg(cmp_mode));
2749 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2750 cmp_unsigned = !mode_is_signed(cmp_mode);
2751 if (is_Const_0(right) &&
2753 get_irn_n_edges(left) == 1 &&
2754 can_fold_test_and(node)) {
2755 /* Test(and_left, and_right) */
2756 ir_node *and_left = get_And_left(left);
2757 ir_node *and_right = get_And_right(left);
2759 /* matze: code here used mode instead of cmd_mode, I think it is always
2760 * the same as cmp_mode, but I leave this here to see if this is really
2763 assert(get_irn_mode(and_left) == cmp_mode);
2765 match_arguments(&am, block, and_left, and_right, NULL,
2767 match_am | match_8bit_am | match_16bit_am |
2768 match_am_and_immediates | match_immediate);
2770 /* use 32bit compare mode if possible since the opcode is smaller */
2771 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2772 upper_bits_clean(am.new_op2, cmp_mode)) {
2773 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2776 if (get_mode_size_bits(cmp_mode) == 8) {
2777 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2778 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2781 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2782 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2785 /* Cmp(left, right) */
2786 match_arguments(&am, block, left, right, NULL,
2787 match_commutative | match_am | match_8bit_am |
2788 match_16bit_am | match_am_and_immediates |
2790 /* use 32bit compare mode if possible since the opcode is smaller */
2791 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2792 upper_bits_clean(am.new_op2, cmp_mode)) {
2793 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2796 if (get_mode_size_bits(cmp_mode) == 8) {
2797 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2798 addr->index, addr->mem, am.new_op1,
2799 am.new_op2, am.ins_permuted,
2802 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2803 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2806 set_am_attributes(new_node, &am);
2807 set_ia32_ls_mode(new_node, cmp_mode);
2809 SET_IA32_ORIG_NODE(new_node, node);
2811 new_node = fix_mem_proj(new_node, &am);
2816 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2819 dbg_info *dbgi = get_irn_dbg_info(node);
2820 ir_node *block = get_nodes_block(node);
2821 ir_node *new_block = be_transform_node(block);
2822 ir_node *val_true = get_Mux_true(node);
2823 ir_node *val_false = get_Mux_false(node);
2825 ia32_address_mode_t am;
2826 ia32_address_t *addr;
2828 assert(ia32_cg_config.use_cmov);
2829 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2833 match_arguments(&am, block, val_false, val_true, flags,
2834 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2836 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2837 addr->mem, am.new_op1, am.new_op2, new_flags,
2838 am.ins_permuted, pnc);
2839 set_am_attributes(new_node, &am);
2841 SET_IA32_ORIG_NODE(new_node, node);
2843 new_node = fix_mem_proj(new_node, &am);
2849 * Creates a ia32 Setcc instruction.
2851 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2852 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2855 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2856 ir_node *nomem = new_NoMem();
2857 ir_mode *mode = get_irn_mode(orig_node);
2860 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2861 SET_IA32_ORIG_NODE(new_node, orig_node);
2863 /* we might need to conv the result up */
2864 if (get_mode_size_bits(mode) > 8) {
2865 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2866 nomem, new_node, mode_Bu);
2867 SET_IA32_ORIG_NODE(new_node, orig_node);
2874 * Create instruction for an unsigned Difference or Zero.
2876 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2878 ir_graph *irg = current_ir_graph;
2879 ir_mode *mode = get_irn_mode(psi);
2880 ir_node *nomem = new_NoMem();
2881 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg;
2885 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2886 match_mode_neutral | match_am | match_immediate | match_two_users);
2888 block = get_nodes_block(new_node);
2890 if (is_Proj(new_node)) {
2891 sub = get_Proj_pred(new_node);
2892 assert(is_ia32_Sub(sub));
2895 set_irn_mode(sub, mode_T);
2896 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2898 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2900 dbgi = get_irn_dbg_info(psi);
2901 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
2903 noreg = ia32_new_NoReg_gp(env_cg);
2904 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2905 set_ia32_commutative(new_node);
2910 * Transforms a Mux node into CMov.
2912 * @return The transformed node.
2914 static ir_node *gen_Mux(ir_node *node)
2916 dbg_info *dbgi = get_irn_dbg_info(node);
2917 ir_node *block = get_nodes_block(node);
2918 ir_node *new_block = be_transform_node(block);
2919 ir_node *mux_true = get_Mux_true(node);
2920 ir_node *mux_false = get_Mux_false(node);
2921 ir_node *cond = get_Mux_sel(node);
2922 ir_mode *mode = get_irn_mode(node);
2925 assert(get_irn_mode(cond) == mode_b);
2927 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2928 if (mode_is_float(mode)) {
2929 ir_node *cmp = get_Proj_pred(cond);
2930 ir_node *cmp_left = get_Cmp_left(cmp);
2931 ir_node *cmp_right = get_Cmp_right(cmp);
2932 pn_Cmp pnc = get_Proj_proj(cond);
2934 if (ia32_cg_config.use_sse2) {
2935 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2936 if (cmp_left == mux_true && cmp_right == mux_false) {
2937 /* Mux(a <= b, a, b) => MIN */
2938 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2939 match_commutative | match_am | match_two_users);
2940 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2941 /* Mux(a <= b, b, a) => MAX */
2942 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2943 match_commutative | match_am | match_two_users);
2945 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2946 if (cmp_left == mux_true && cmp_right == mux_false) {
2947 /* Mux(a >= b, a, b) => MAX */
2948 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2949 match_commutative | match_am | match_two_users);
2950 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2951 /* Mux(a >= b, b, a) => MIN */
2952 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2953 match_commutative | match_am | match_two_users);
2957 panic("cannot transform floating point Mux");
2963 assert(ia32_mode_needs_gp_reg(mode));
2965 if (is_Proj(cond)) {
2966 ir_node *cmp = get_Proj_pred(cond);
2968 ir_node *cmp_left = get_Cmp_left(cmp);
2969 ir_node *cmp_right = get_Cmp_right(cmp);
2970 pn_Cmp pnc = get_Proj_proj(cond);
2972 /* check for unsigned Doz first */
2973 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2974 is_Const_0(mux_false) && is_Sub(mux_true) &&
2975 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2976 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2977 return create_Doz(node, cmp_left, cmp_right);
2978 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2979 is_Const_0(mux_true) && is_Sub(mux_false) &&
2980 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2981 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2982 return create_Doz(node, cmp_left, cmp_right);
2987 flags = get_flags_node(cond, &pnc);
2989 if (is_Const(mux_true) && is_Const(mux_false)) {
2990 /* both are const, good */
2991 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2992 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2993 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2994 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2996 /* Not that simple. */
3001 new_node = create_CMov(node, cond, flags, pnc);
3009 * Create a conversion from x87 state register to general purpose.
3011 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3013 ir_node *block = be_transform_node(get_nodes_block(node));
3014 ir_node *op = get_Conv_op(node);
3015 ir_node *new_op = be_transform_node(op);
3016 ia32_code_gen_t *cg = env_cg;
3017 ir_graph *irg = current_ir_graph;
3018 dbg_info *dbgi = get_irn_dbg_info(node);
3019 ir_node *noreg = ia32_new_NoReg_gp(cg);
3020 ir_mode *mode = get_irn_mode(node);
3021 ir_node *fist, *load, *mem;
3023 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3024 set_irn_pinned(fist, op_pin_state_floats);
3025 set_ia32_use_frame(fist);
3026 set_ia32_op_type(fist, ia32_AddrModeD);
3028 assert(get_mode_size_bits(mode) <= 32);
3029 /* exception we can only store signed 32 bit integers, so for unsigned
3030 we store a 64bit (signed) integer and load the lower bits */
3031 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3032 set_ia32_ls_mode(fist, mode_Ls);
3034 set_ia32_ls_mode(fist, mode_Is);
3036 SET_IA32_ORIG_NODE(fist, node);
3039 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3041 set_irn_pinned(load, op_pin_state_floats);
3042 set_ia32_use_frame(load);
3043 set_ia32_op_type(load, ia32_AddrModeS);
3044 set_ia32_ls_mode(load, mode_Is);
3045 if (get_ia32_ls_mode(fist) == mode_Ls) {
3046 ia32_attr_t *attr = get_ia32_attr(load);
3047 attr->data.need_64bit_stackent = 1;
3049 ia32_attr_t *attr = get_ia32_attr(load);
3050 attr->data.need_32bit_stackent = 1;
3052 SET_IA32_ORIG_NODE(load, node);
3054 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3058 * Creates a x87 strict Conv by placing a Store and a Load
3060 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3062 ir_node *block = get_nodes_block(node);
3063 ir_graph *irg = current_ir_graph;
3064 dbg_info *dbgi = get_irn_dbg_info(node);
3065 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3066 ir_node *nomem = new_NoMem();
3067 ir_node *frame = get_irg_frame(irg);
3068 ir_node *store, *load;
3071 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3072 set_ia32_use_frame(store);
3073 set_ia32_op_type(store, ia32_AddrModeD);
3074 SET_IA32_ORIG_NODE(store, node);
3076 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3077 set_ia32_use_frame(load);
3078 set_ia32_op_type(load, ia32_AddrModeS);
3079 SET_IA32_ORIG_NODE(load, node);
3081 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3085 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3086 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3088 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3090 func = get_mode_size_bits(mode) == 8 ?
3091 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3092 return func(dbgi, block, base, index, mem, val, mode);
3096 * Create a conversion from general purpose to x87 register
3098 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3100 ir_node *src_block = get_nodes_block(node);
3101 ir_node *block = be_transform_node(src_block);
3102 ir_graph *irg = current_ir_graph;
3103 dbg_info *dbgi = get_irn_dbg_info(node);
3104 ir_node *op = get_Conv_op(node);
3105 ir_node *new_op = NULL;
3109 ir_mode *store_mode;
3114 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3115 if (possible_int_mode_for_fp(src_mode)) {
3116 ia32_address_mode_t am;
3118 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3119 if (am.op_type == ia32_AddrModeS) {
3120 ia32_address_t *addr = &am.addr;
3122 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3124 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3127 set_am_attributes(fild, &am);
3128 SET_IA32_ORIG_NODE(fild, node);
3130 fix_mem_proj(fild, &am);
3135 if (new_op == NULL) {
3136 new_op = be_transform_node(op);
3139 noreg = ia32_new_NoReg_gp(env_cg);
3140 nomem = new_NoMem();
3141 mode = get_irn_mode(op);
3143 /* first convert to 32 bit signed if necessary */
3144 if (get_mode_size_bits(src_mode) < 32) {
3145 if (!upper_bits_clean(new_op, src_mode)) {
3146 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3147 SET_IA32_ORIG_NODE(new_op, node);
3152 assert(get_mode_size_bits(mode) == 32);
3155 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3158 set_ia32_use_frame(store);
3159 set_ia32_op_type(store, ia32_AddrModeD);
3160 set_ia32_ls_mode(store, mode_Iu);
3162 /* exception for 32bit unsigned, do a 64bit spill+load */
3163 if (!mode_is_signed(mode)) {
3166 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3168 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3169 noreg, nomem, zero_const);
3171 set_ia32_use_frame(zero_store);
3172 set_ia32_op_type(zero_store, ia32_AddrModeD);
3173 add_ia32_am_offs_int(zero_store, 4);
3174 set_ia32_ls_mode(zero_store, mode_Iu);
3179 store = new_rd_Sync(dbgi, irg, block, 2, in);
3180 store_mode = mode_Ls;
3182 store_mode = mode_Is;
3186 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3188 set_ia32_use_frame(fild);
3189 set_ia32_op_type(fild, ia32_AddrModeS);
3190 set_ia32_ls_mode(fild, store_mode);
3192 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3198 * Create a conversion from one integer mode into another one
3200 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3201 dbg_info *dbgi, ir_node *block, ir_node *op,
3204 ir_node *new_block = be_transform_node(block);
3206 ir_mode *smaller_mode;
3207 ia32_address_mode_t am;
3208 ia32_address_t *addr = &am.addr;
3211 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3212 smaller_mode = src_mode;
3214 smaller_mode = tgt_mode;
3217 #ifdef DEBUG_libfirm
3219 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3224 match_arguments(&am, block, NULL, op, NULL,
3225 match_am | match_8bit_am | match_16bit_am);
3227 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3228 /* unnecessary conv. in theory it shouldn't have been AM */
3229 assert(is_ia32_NoReg_GP(addr->base));
3230 assert(is_ia32_NoReg_GP(addr->index));
3231 assert(is_NoMem(addr->mem));
3232 assert(am.addr.offset == 0);
3233 assert(am.addr.symconst_ent == NULL);
3237 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3238 addr->mem, am.new_op2, smaller_mode);
3239 set_am_attributes(new_node, &am);
3240 /* match_arguments assume that out-mode = in-mode, this isn't true here
3242 set_ia32_ls_mode(new_node, smaller_mode);
3243 SET_IA32_ORIG_NODE(new_node, node);
3244 new_node = fix_mem_proj(new_node, &am);
3249 * Transforms a Conv node.
3251 * @return The created ia32 Conv node
3253 static ir_node *gen_Conv(ir_node *node)
3255 ir_node *block = get_nodes_block(node);
3256 ir_node *new_block = be_transform_node(block);
3257 ir_node *op = get_Conv_op(node);
3258 ir_node *new_op = NULL;
3259 dbg_info *dbgi = get_irn_dbg_info(node);
3260 ir_mode *src_mode = get_irn_mode(op);
3261 ir_mode *tgt_mode = get_irn_mode(node);
3262 int src_bits = get_mode_size_bits(src_mode);
3263 int tgt_bits = get_mode_size_bits(tgt_mode);
3264 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3265 ir_node *nomem = new_NoMem();
3266 ir_node *res = NULL;
3268 assert(!mode_is_int(src_mode) || src_bits <= 32);
3269 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3271 if (src_mode == mode_b) {
3272 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3273 /* nothing to do, we already model bools as 0/1 ints */
3274 return be_transform_node(op);
3277 if (src_mode == tgt_mode) {
3278 if (get_Conv_strict(node)) {
3279 if (ia32_cg_config.use_sse2) {
3280 /* when we are in SSE mode, we can kill all strict no-op conversion */
3281 return be_transform_node(op);
3284 /* this should be optimized already, but who knows... */
3285 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3286 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3287 return be_transform_node(op);
3291 if (mode_is_float(src_mode)) {
3292 new_op = be_transform_node(op);
3293 /* we convert from float ... */
3294 if (mode_is_float(tgt_mode)) {
3295 if (src_mode == mode_E && tgt_mode == mode_D
3296 && !get_Conv_strict(node)) {
3297 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3302 if (ia32_cg_config.use_sse2) {
3303 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3304 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3306 set_ia32_ls_mode(res, tgt_mode);
3308 if (get_Conv_strict(node)) {
3309 res = gen_x87_strict_conv(tgt_mode, new_op);
3310 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3313 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3318 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3319 if (ia32_cg_config.use_sse2) {
3320 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3322 set_ia32_ls_mode(res, src_mode);
3324 return gen_x87_fp_to_gp(node);
3328 /* we convert from int ... */
3329 if (mode_is_float(tgt_mode)) {
3331 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3332 if (ia32_cg_config.use_sse2) {
3333 new_op = be_transform_node(op);
3334 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3336 set_ia32_ls_mode(res, tgt_mode);
3338 res = gen_x87_gp_to_fp(node, src_mode);
3339 if (get_Conv_strict(node)) {
3340 /* The strict-Conv is only necessary, if the int mode has more bits
3341 * than the float mantissa */
3342 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3343 size_t float_mantissa;
3344 /* FIXME There is no way to get the mantissa size of a mode */
3345 switch (get_mode_size_bits(tgt_mode)) {
3346 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3347 case 64: float_mantissa = 52 + 1; break;
3349 case 96: float_mantissa = 64; break;
3350 default: float_mantissa = 0; break;
3352 if (float_mantissa < int_mantissa) {
3353 res = gen_x87_strict_conv(tgt_mode, res);
3354 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3359 } else if (tgt_mode == mode_b) {
3360 /* mode_b lowering already took care that we only have 0/1 values */
3361 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3362 src_mode, tgt_mode));
3363 return be_transform_node(op);
3366 if (src_bits == tgt_bits) {
3367 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3368 src_mode, tgt_mode));
3369 return be_transform_node(op);
3372 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3380 static ir_node *create_immediate_or_transform(ir_node *node,
3381 char immediate_constraint_type)
3383 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3384 if (new_node == NULL) {
3385 new_node = be_transform_node(node);
3391 * Transforms a FrameAddr into an ia32 Add.
3393 static ir_node *gen_be_FrameAddr(ir_node *node)
3395 ir_node *block = be_transform_node(get_nodes_block(node));
3396 ir_node *op = be_get_FrameAddr_frame(node);
3397 ir_node *new_op = be_transform_node(op);
3398 dbg_info *dbgi = get_irn_dbg_info(node);
3399 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3402 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3403 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3404 set_ia32_use_frame(new_node);
3406 SET_IA32_ORIG_NODE(new_node, node);
3412 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3414 static ir_node *gen_be_Return(ir_node *node)
3416 ir_graph *irg = current_ir_graph;
3417 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3418 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3419 ir_entity *ent = get_irg_entity(irg);
3420 ir_type *tp = get_entity_type(ent);
3425 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3426 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3429 int pn_ret_val, pn_ret_mem, arity, i;
3431 assert(ret_val != NULL);
3432 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3433 return be_duplicate_node(node);
3436 res_type = get_method_res_type(tp, 0);
3438 if (! is_Primitive_type(res_type)) {
3439 return be_duplicate_node(node);
3442 mode = get_type_mode(res_type);
3443 if (! mode_is_float(mode)) {
3444 return be_duplicate_node(node);
3447 assert(get_method_n_ress(tp) == 1);
3449 pn_ret_val = get_Proj_proj(ret_val);
3450 pn_ret_mem = get_Proj_proj(ret_mem);
3452 /* get the Barrier */
3453 barrier = get_Proj_pred(ret_val);
3455 /* get result input of the Barrier */
3456 ret_val = get_irn_n(barrier, pn_ret_val);
3457 new_ret_val = be_transform_node(ret_val);
3459 /* get memory input of the Barrier */
3460 ret_mem = get_irn_n(barrier, pn_ret_mem);
3461 new_ret_mem = be_transform_node(ret_mem);
3463 frame = get_irg_frame(irg);
3465 dbgi = get_irn_dbg_info(barrier);
3466 block = be_transform_node(get_nodes_block(barrier));
3468 noreg = ia32_new_NoReg_gp(env_cg);
3470 /* store xmm0 onto stack */
3471 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3472 new_ret_mem, new_ret_val);
3473 set_ia32_ls_mode(sse_store, mode);
3474 set_ia32_op_type(sse_store, ia32_AddrModeD);
3475 set_ia32_use_frame(sse_store);
3477 /* load into x87 register */
3478 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3479 set_ia32_op_type(fld, ia32_AddrModeS);
3480 set_ia32_use_frame(fld);
3482 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3483 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3485 /* create a new barrier */
3486 arity = get_irn_arity(barrier);
3487 in = ALLOCAN(ir_node*, arity);
3488 for (i = 0; i < arity; ++i) {
3491 if (i == pn_ret_val) {
3493 } else if (i == pn_ret_mem) {
3496 ir_node *in = get_irn_n(barrier, i);
3497 new_in = be_transform_node(in);
3502 new_barrier = new_ir_node(dbgi, irg, block,
3503 get_irn_op(barrier), get_irn_mode(barrier),
3505 copy_node_attr(barrier, new_barrier);
3506 be_duplicate_deps(barrier, new_barrier);
3507 be_set_transformed_node(barrier, new_barrier);
3509 /* transform normally */
3510 return be_duplicate_node(node);
3514 * Transform a be_AddSP into an ia32_SubSP.
3516 static ir_node *gen_be_AddSP(ir_node *node)
3518 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3519 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3521 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3522 match_am | match_immediate);
3526 * Transform a be_SubSP into an ia32_AddSP
3528 static ir_node *gen_be_SubSP(ir_node *node)
3530 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3531 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3533 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3534 match_am | match_immediate);
3538 * Change some phi modes
3540 static ir_node *gen_Phi(ir_node *node)
3542 ir_node *block = be_transform_node(get_nodes_block(node));
3543 ir_graph *irg = current_ir_graph;
3544 dbg_info *dbgi = get_irn_dbg_info(node);
3545 ir_mode *mode = get_irn_mode(node);
3548 if (ia32_mode_needs_gp_reg(mode)) {
3549 /* we shouldn't have any 64bit stuff around anymore */
3550 assert(get_mode_size_bits(mode) <= 32);
3551 /* all integer operations are on 32bit registers now */
3553 } else if (mode_is_float(mode)) {
3554 if (ia32_cg_config.use_sse2) {
3561 /* phi nodes allow loops, so we use the old arguments for now
3562 * and fix this later */
3563 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3564 get_irn_in(node) + 1);
3565 copy_node_attr(node, phi);
3566 be_duplicate_deps(node, phi);
3568 be_enqueue_preds(node);
3576 static ir_node *gen_IJmp(ir_node *node)
3578 ir_node *block = get_nodes_block(node);
3579 ir_node *new_block = be_transform_node(block);
3580 dbg_info *dbgi = get_irn_dbg_info(node);
3581 ir_node *op = get_IJmp_target(node);
3583 ia32_address_mode_t am;
3584 ia32_address_t *addr = &am.addr;
3586 assert(get_irn_mode(op) == mode_P);
3588 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3590 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3591 addr->mem, am.new_op2);
3592 set_am_attributes(new_node, &am);
3593 SET_IA32_ORIG_NODE(new_node, node);
3595 new_node = fix_mem_proj(new_node, &am);
3601 * Transform a Bound node.
3603 static ir_node *gen_Bound(ir_node *node)
3606 ir_node *lower = get_Bound_lower(node);
3607 dbg_info *dbgi = get_irn_dbg_info(node);
3609 if (is_Const_0(lower)) {
3610 /* typical case for Java */
3611 ir_node *sub, *res, *flags, *block;
3612 ir_graph *irg = current_ir_graph;
3614 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3615 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3617 block = get_nodes_block(res);
3618 if (! is_Proj(res)) {
3620 set_irn_mode(sub, mode_T);
3621 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3623 sub = get_Proj_pred(res);
3625 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3626 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3627 SET_IA32_ORIG_NODE(new_node, node);
3629 panic("generic Bound not supported in ia32 Backend");
3635 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3637 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3638 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3640 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3641 match_immediate | match_mode_neutral);
3644 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3646 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3647 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3648 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3652 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3654 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3655 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3656 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3660 static ir_node *gen_ia32_l_Add(ir_node *node)
3662 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3663 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3664 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3665 match_commutative | match_am | match_immediate |
3666 match_mode_neutral);
3668 if (is_Proj(lowered)) {
3669 lowered = get_Proj_pred(lowered);
3671 assert(is_ia32_Add(lowered));
3672 set_irn_mode(lowered, mode_T);
3678 static ir_node *gen_ia32_l_Adc(ir_node *node)
3680 return gen_binop_flags(node, new_bd_ia32_Adc,
3681 match_commutative | match_am | match_immediate |
3682 match_mode_neutral);
3686 * Transforms a l_MulS into a "real" MulS node.
3688 * @return the created ia32 Mul node
3690 static ir_node *gen_ia32_l_Mul(ir_node *node)
3692 ir_node *left = get_binop_left(node);
3693 ir_node *right = get_binop_right(node);
3695 return gen_binop(node, left, right, new_bd_ia32_Mul,
3696 match_commutative | match_am | match_mode_neutral);
3700 * Transforms a l_IMulS into a "real" IMul1OPS node.
3702 * @return the created ia32 IMul1OP node
3704 static ir_node *gen_ia32_l_IMul(ir_node *node)
3706 ir_node *left = get_binop_left(node);
3707 ir_node *right = get_binop_right(node);
3709 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3710 match_commutative | match_am | match_mode_neutral);
3713 static ir_node *gen_ia32_l_Sub(ir_node *node)
3715 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3716 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3717 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3718 match_am | match_immediate | match_mode_neutral);
3720 if (is_Proj(lowered)) {
3721 lowered = get_Proj_pred(lowered);
3723 assert(is_ia32_Sub(lowered));
3724 set_irn_mode(lowered, mode_T);
3730 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3732 return gen_binop_flags(node, new_bd_ia32_Sbb,
3733 match_am | match_immediate | match_mode_neutral);
3737 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3738 * op1 - target to be shifted
3739 * op2 - contains bits to be shifted into target
3741 * Only op3 can be an immediate.
3743 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3744 ir_node *low, ir_node *count)
3746 ir_node *block = get_nodes_block(node);
3747 ir_node *new_block = be_transform_node(block);
3748 dbg_info *dbgi = get_irn_dbg_info(node);
3749 ir_node *new_high = be_transform_node(high);
3750 ir_node *new_low = be_transform_node(low);
3754 /* the shift amount can be any mode that is bigger than 5 bits, since all
3755 * other bits are ignored anyway */
3756 while (is_Conv(count) &&
3757 get_irn_n_edges(count) == 1 &&
3758 mode_is_int(get_irn_mode(count))) {
3759 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3760 count = get_Conv_op(count);
3762 new_count = create_immediate_or_transform(count, 0);
3764 if (is_ia32_l_ShlD(node)) {
3765 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3768 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3771 SET_IA32_ORIG_NODE(new_node, node);
3776 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3778 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3779 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3780 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3781 return gen_lowered_64bit_shifts(node, high, low, count);
3784 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3786 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3787 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3788 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3789 return gen_lowered_64bit_shifts(node, high, low, count);
3792 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3794 ir_node *src_block = get_nodes_block(node);
3795 ir_node *block = be_transform_node(src_block);
3796 ir_graph *irg = current_ir_graph;
3797 dbg_info *dbgi = get_irn_dbg_info(node);
3798 ir_node *frame = get_irg_frame(irg);
3799 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3800 ir_node *nomem = new_NoMem();
3801 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3802 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3803 ir_node *new_val_low = be_transform_node(val_low);
3804 ir_node *new_val_high = be_transform_node(val_high);
3806 ir_node *sync, *fild, *res;
3807 ir_node *store_low, *store_high;
3809 if (ia32_cg_config.use_sse2) {
3810 panic("ia32_l_LLtoFloat not implemented for SSE2");
3814 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3816 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3818 SET_IA32_ORIG_NODE(store_low, node);
3819 SET_IA32_ORIG_NODE(store_high, node);
3821 set_ia32_use_frame(store_low);
3822 set_ia32_use_frame(store_high);
3823 set_ia32_op_type(store_low, ia32_AddrModeD);
3824 set_ia32_op_type(store_high, ia32_AddrModeD);
3825 set_ia32_ls_mode(store_low, mode_Iu);
3826 set_ia32_ls_mode(store_high, mode_Is);
3827 add_ia32_am_offs_int(store_high, 4);
3831 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3834 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3836 set_ia32_use_frame(fild);
3837 set_ia32_op_type(fild, ia32_AddrModeS);
3838 set_ia32_ls_mode(fild, mode_Ls);
3840 SET_IA32_ORIG_NODE(fild, node);
3842 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3844 if (! mode_is_signed(get_irn_mode(val_high))) {
3845 ia32_address_mode_t am;
3847 ir_node *count = create_Immediate(NULL, 0, 31);
3850 am.addr.base = ia32_new_NoReg_gp(env_cg);
3851 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
3852 am.addr.mem = nomem;
3855 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
3856 am.addr.use_frame = 0;
3857 am.addr.frame_entity = NULL;
3858 am.addr.symconst_sign = 0;
3859 am.ls_mode = mode_F;
3860 am.mem_proj = nomem;
3861 am.op_type = ia32_AddrModeS;
3863 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
3864 am.pinned = op_pin_state_floats;
3866 am.ins_permuted = 0;
3868 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
3869 am.new_op1, am.new_op2, get_fpcw());
3870 set_am_attributes(fadd, &am);
3872 set_irn_mode(fadd, mode_T);
3873 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
3878 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3880 ir_node *src_block = get_nodes_block(node);
3881 ir_node *block = be_transform_node(src_block);
3882 ir_graph *irg = current_ir_graph;
3883 dbg_info *dbgi = get_irn_dbg_info(node);
3884 ir_node *frame = get_irg_frame(irg);
3885 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3886 ir_node *nomem = new_NoMem();
3887 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3888 ir_node *new_val = be_transform_node(val);
3889 ir_node *fist, *mem;
3891 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3892 SET_IA32_ORIG_NODE(fist, node);
3893 set_ia32_use_frame(fist);
3894 set_ia32_op_type(fist, ia32_AddrModeD);
3895 set_ia32_ls_mode(fist, mode_Ls);
3901 * the BAD transformer.
3903 static ir_node *bad_transform(ir_node *node)
3905 panic("No transform function for %+F available.", node);
3909 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3911 ir_graph *irg = current_ir_graph;
3912 ir_node *block = be_transform_node(get_nodes_block(node));
3913 ir_node *pred = get_Proj_pred(node);
3914 ir_node *new_pred = be_transform_node(pred);
3915 ir_node *frame = get_irg_frame(irg);
3916 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3917 dbg_info *dbgi = get_irn_dbg_info(node);
3918 long pn = get_Proj_proj(node);
3923 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3924 SET_IA32_ORIG_NODE(load, node);
3925 set_ia32_use_frame(load);
3926 set_ia32_op_type(load, ia32_AddrModeS);
3927 set_ia32_ls_mode(load, mode_Iu);
3928 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3929 * 32 bit from it with this particular load */
3930 attr = get_ia32_attr(load);
3931 attr->data.need_64bit_stackent = 1;
3933 if (pn == pn_ia32_l_FloattoLL_res_high) {
3934 add_ia32_am_offs_int(load, 4);
3936 assert(pn == pn_ia32_l_FloattoLL_res_low);
3939 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3945 * Transform the Projs of an AddSP.
3947 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3949 ir_node *block = be_transform_node(get_nodes_block(node));
3950 ir_node *pred = get_Proj_pred(node);
3951 ir_node *new_pred = be_transform_node(pred);
3952 ir_graph *irg = current_ir_graph;
3953 dbg_info *dbgi = get_irn_dbg_info(node);
3954 long proj = get_Proj_proj(node);
3956 if (proj == pn_be_AddSP_sp) {
3957 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3958 pn_ia32_SubSP_stack);
3959 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3961 } else if (proj == pn_be_AddSP_res) {
3962 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3963 pn_ia32_SubSP_addr);
3964 } else if (proj == pn_be_AddSP_M) {
3965 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3968 panic("No idea how to transform proj->AddSP");
3972 * Transform the Projs of a SubSP.
3974 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3976 ir_node *block = be_transform_node(get_nodes_block(node));
3977 ir_node *pred = get_Proj_pred(node);
3978 ir_node *new_pred = be_transform_node(pred);
3979 ir_graph *irg = current_ir_graph;
3980 dbg_info *dbgi = get_irn_dbg_info(node);
3981 long proj = get_Proj_proj(node);
3983 if (proj == pn_be_SubSP_sp) {
3984 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3985 pn_ia32_AddSP_stack);
3986 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3988 } else if (proj == pn_be_SubSP_M) {
3989 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3992 panic("No idea how to transform proj->SubSP");
3996 * Transform and renumber the Projs from a Load.
3998 static ir_node *gen_Proj_Load(ir_node *node)
4001 ir_node *block = be_transform_node(get_nodes_block(node));
4002 ir_node *pred = get_Proj_pred(node);
4003 ir_graph *irg = current_ir_graph;
4004 dbg_info *dbgi = get_irn_dbg_info(node);
4005 long proj = get_Proj_proj(node);
4007 /* loads might be part of source address mode matches, so we don't
4008 * transform the ProjMs yet (with the exception of loads whose result is
4011 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4014 /* this is needed, because sometimes we have loops that are only
4015 reachable through the ProjM */
4016 be_enqueue_preds(node);
4017 /* do it in 2 steps, to silence firm verifier */
4018 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4019 set_Proj_proj(res, pn_ia32_mem);
4023 /* renumber the proj */
4024 new_pred = be_transform_node(pred);
4025 if (is_ia32_Load(new_pred)) {
4028 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4030 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4031 case pn_Load_X_regular:
4032 return new_rd_Jmp(dbgi, irg, block);
4033 case pn_Load_X_except:
4034 /* This Load might raise an exception. Mark it. */
4035 set_ia32_exc_label(new_pred, 1);
4036 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4040 } else if (is_ia32_Conv_I2I(new_pred) ||
4041 is_ia32_Conv_I2I8Bit(new_pred)) {
4042 set_irn_mode(new_pred, mode_T);
4043 if (proj == pn_Load_res) {
4044 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4045 } else if (proj == pn_Load_M) {
4046 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4048 } else if (is_ia32_xLoad(new_pred)) {
4051 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4053 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4054 case pn_Load_X_regular:
4055 return new_rd_Jmp(dbgi, irg, block);
4056 case pn_Load_X_except:
4057 /* This Load might raise an exception. Mark it. */
4058 set_ia32_exc_label(new_pred, 1);
4059 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4063 } else if (is_ia32_vfld(new_pred)) {
4066 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4068 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4069 case pn_Load_X_regular:
4070 return new_rd_Jmp(dbgi, irg, block);
4071 case pn_Load_X_except:
4072 /* This Load might raise an exception. Mark it. */
4073 set_ia32_exc_label(new_pred, 1);
4074 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4079 /* can happen for ProJMs when source address mode happened for the
4082 /* however it should not be the result proj, as that would mean the
4083 load had multiple users and should not have been used for
4085 if (proj != pn_Load_M) {
4086 panic("internal error: transformed node not a Load");
4088 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4091 panic("No idea how to transform proj");
4095 * Transform and renumber the Projs from a DivMod like instruction.
4097 static ir_node *gen_Proj_DivMod(ir_node *node)
4099 ir_node *block = be_transform_node(get_nodes_block(node));
4100 ir_node *pred = get_Proj_pred(node);
4101 ir_node *new_pred = be_transform_node(pred);
4102 ir_graph *irg = current_ir_graph;
4103 dbg_info *dbgi = get_irn_dbg_info(node);
4104 long proj = get_Proj_proj(node);
4106 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4108 switch (get_irn_opcode(pred)) {
4112 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4114 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4115 case pn_Div_X_regular:
4116 return new_rd_Jmp(dbgi, irg, block);
4117 case pn_Div_X_except:
4118 set_ia32_exc_label(new_pred, 1);
4119 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4127 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4129 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4130 case pn_Mod_X_except:
4131 set_ia32_exc_label(new_pred, 1);
4132 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4141 case pn_DivMod_res_div:
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4143 case pn_DivMod_res_mod:
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4145 case pn_DivMod_X_regular:
4146 return new_rd_Jmp(dbgi, irg, block);
4147 case pn_DivMod_X_except:
4148 set_ia32_exc_label(new_pred, 1);
4149 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4158 panic("No idea how to transform proj->DivMod");
4162 * Transform and renumber the Projs from a CopyB.
4164 static ir_node *gen_Proj_CopyB(ir_node *node)
4166 ir_node *block = be_transform_node(get_nodes_block(node));
4167 ir_node *pred = get_Proj_pred(node);
4168 ir_node *new_pred = be_transform_node(pred);
4169 ir_graph *irg = current_ir_graph;
4170 dbg_info *dbgi = get_irn_dbg_info(node);
4171 long proj = get_Proj_proj(node);
4174 case pn_CopyB_M_regular:
4175 if (is_ia32_CopyB_i(new_pred)) {
4176 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4177 } else if (is_ia32_CopyB(new_pred)) {
4178 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4185 panic("No idea how to transform proj->CopyB");
4189 * Transform and renumber the Projs from a Quot.
4191 static ir_node *gen_Proj_Quot(ir_node *node)
4193 ir_node *block = be_transform_node(get_nodes_block(node));
4194 ir_node *pred = get_Proj_pred(node);
4195 ir_node *new_pred = be_transform_node(pred);
4196 ir_graph *irg = current_ir_graph;
4197 dbg_info *dbgi = get_irn_dbg_info(node);
4198 long proj = get_Proj_proj(node);
4202 if (is_ia32_xDiv(new_pred)) {
4203 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4204 } else if (is_ia32_vfdiv(new_pred)) {
4205 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4209 if (is_ia32_xDiv(new_pred)) {
4210 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4211 } else if (is_ia32_vfdiv(new_pred)) {
4212 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4215 case pn_Quot_X_regular:
4216 case pn_Quot_X_except:
4221 panic("No idea how to transform proj->Quot");
4224 static ir_node *gen_be_Call(ir_node *node)
4226 dbg_info *const dbgi = get_irn_dbg_info(node);
4227 ir_graph *const irg = current_ir_graph;
4228 ir_node *const src_block = get_nodes_block(node);
4229 ir_node *const block = be_transform_node(src_block);
4230 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4231 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4232 ir_node *const sp = be_transform_node(src_sp);
4233 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4234 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4235 ia32_address_mode_t am;
4236 ia32_address_t *const addr = &am.addr;
4241 ir_node * eax = noreg;
4242 ir_node * ecx = noreg;
4243 ir_node * edx = noreg;
4244 unsigned const pop = be_Call_get_pop(node);
4245 ir_type *const call_tp = be_Call_get_type(node);
4247 /* Run the x87 simulator if the call returns a float value */
4248 if (get_method_n_ress(call_tp) > 0) {
4249 ir_type *const res_type = get_method_res_type(call_tp, 0);
4250 ir_mode *const res_mode = get_type_mode(res_type);
4252 if (res_mode != NULL && mode_is_float(res_mode)) {
4253 env_cg->do_x87_sim = 1;
4257 /* We do not want be_Call direct calls */
4258 assert(be_Call_get_entity(node) == NULL);
4260 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4261 match_am | match_immediate);
4263 i = get_irn_arity(node) - 1;
4264 fpcw = be_transform_node(get_irn_n(node, i--));
4265 for (; i >= be_pos_Call_first_arg; --i) {
4266 arch_register_req_t const *const req = arch_get_register_req(node, i);
4267 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4269 assert(req->type == arch_register_req_type_limited);
4270 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4272 switch (*req->limited) {
4273 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4274 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4275 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4276 default: panic("Invalid GP register for register parameter");
4280 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4281 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4282 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4283 set_am_attributes(call, &am);
4284 call = fix_mem_proj(call, &am);
4286 if (get_irn_pinned(node) == op_pin_state_pinned)
4287 set_irn_pinned(call, op_pin_state_pinned);
4289 SET_IA32_ORIG_NODE(call, node);
4293 static ir_node *gen_be_IncSP(ir_node *node)
4295 ir_node *res = be_duplicate_node(node);
4296 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4302 * Transform the Projs from a be_Call.
4304 static ir_node *gen_Proj_be_Call(ir_node *node)
4306 ir_node *block = be_transform_node(get_nodes_block(node));
4307 ir_node *call = get_Proj_pred(node);
4308 ir_node *new_call = be_transform_node(call);
4309 ir_graph *irg = current_ir_graph;
4310 dbg_info *dbgi = get_irn_dbg_info(node);
4311 ir_type *method_type = be_Call_get_type(call);
4312 int n_res = get_method_n_ress(method_type);
4313 long proj = get_Proj_proj(node);
4314 ir_mode *mode = get_irn_mode(node);
4318 /* The following is kinda tricky: If we're using SSE, then we have to
4319 * move the result value of the call in floating point registers to an
4320 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4321 * after the call, we have to make sure to correctly make the
4322 * MemProj and the result Proj use these 2 nodes
4324 if (proj == pn_be_Call_M_regular) {
4325 // get new node for result, are we doing the sse load/store hack?
4326 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4327 ir_node *call_res_new;
4328 ir_node *call_res_pred = NULL;
4330 if (call_res != NULL) {
4331 call_res_new = be_transform_node(call_res);
4332 call_res_pred = get_Proj_pred(call_res_new);
4335 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4336 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4339 assert(is_ia32_xLoad(call_res_pred));
4340 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4344 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4345 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4347 ir_node *frame = get_irg_frame(irg);
4348 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4350 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4353 /* in case there is no memory output: create one to serialize the copy
4355 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4356 pn_be_Call_M_regular);
4357 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4358 pn_be_Call_first_res);
4360 /* store st(0) onto stack */
4361 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4363 set_ia32_op_type(fstp, ia32_AddrModeD);
4364 set_ia32_use_frame(fstp);
4366 /* load into SSE register */
4367 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4368 set_ia32_op_type(sse_load, ia32_AddrModeS);
4369 set_ia32_use_frame(sse_load);
4371 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4377 /* transform call modes */
4378 if (mode_is_data(mode)) {
4379 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4383 /* Map from be_Call to ia32_Call proj number */
4384 if (proj == pn_be_Call_sp) {
4385 proj = pn_ia32_Call_stack;
4386 } else if (proj == pn_be_Call_M_regular) {
4387 proj = pn_ia32_Call_M;
4389 arch_register_req_t const *const req = arch_get_register_req_out(node);
4390 int const n_outs = arch_irn_get_n_outs(new_call);
4393 assert(proj >= pn_be_Call_first_res);
4394 assert(req->type & arch_register_req_type_limited);
4396 for (i = 0; i < n_outs; ++i) {
4397 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4399 if (!(new_req->type & arch_register_req_type_limited) ||
4400 new_req->cls != req->cls ||
4401 *new_req->limited != *req->limited)
4410 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4412 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4414 case pn_ia32_Call_stack:
4415 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4418 case pn_ia32_Call_fpcw:
4419 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4427 * Transform the Projs from a Cmp.
4429 static ir_node *gen_Proj_Cmp(ir_node *node)
4431 /* this probably means not all mode_b nodes were lowered... */
4432 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4437 * Transform the Projs from a Bound.
4439 static ir_node *gen_Proj_Bound(ir_node *node)
4441 ir_node *new_node, *block;
4442 ir_node *pred = get_Proj_pred(node);
4444 switch (get_Proj_proj(node)) {
4446 return be_transform_node(get_Bound_mem(pred));
4447 case pn_Bound_X_regular:
4448 new_node = be_transform_node(pred);
4449 block = get_nodes_block(new_node);
4450 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4451 case pn_Bound_X_except:
4452 new_node = be_transform_node(pred);
4453 block = get_nodes_block(new_node);
4454 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4456 return be_transform_node(get_Bound_index(pred));
4458 panic("unsupported Proj from Bound");
4462 static ir_node *gen_Proj_ASM(ir_node *node)
4468 if (get_irn_mode(node) != mode_M)
4469 return be_duplicate_node(node);
4471 pred = get_Proj_pred(node);
4472 new_pred = be_transform_node(pred);
4473 block = get_nodes_block(new_pred);
4474 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4475 arch_irn_get_n_outs(new_pred) + 1);
4479 * Transform and potentially renumber Proj nodes.
4481 static ir_node *gen_Proj(ir_node *node)
4483 ir_node *pred = get_Proj_pred(node);
4486 switch (get_irn_opcode(pred)) {
4488 proj = get_Proj_proj(node);
4489 if (proj == pn_Store_M) {
4490 return be_transform_node(pred);
4492 panic("No idea how to transform proj->Store");
4495 return gen_Proj_Load(node);
4497 return gen_Proj_ASM(node);
4501 return gen_Proj_DivMod(node);
4503 return gen_Proj_CopyB(node);
4505 return gen_Proj_Quot(node);
4507 return gen_Proj_be_SubSP(node);
4509 return gen_Proj_be_AddSP(node);
4511 return gen_Proj_be_Call(node);
4513 return gen_Proj_Cmp(node);
4515 return gen_Proj_Bound(node);
4517 proj = get_Proj_proj(node);
4519 case pn_Start_X_initial_exec: {
4520 ir_node *block = get_nodes_block(pred);
4521 ir_node *new_block = be_transform_node(block);
4522 dbg_info *dbgi = get_irn_dbg_info(node);
4523 /* we exchange the ProjX with a jump */
4524 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4529 case pn_Start_P_tls:
4530 return gen_Proj_tls(node);
4535 if (is_ia32_l_FloattoLL(pred)) {
4536 return gen_Proj_l_FloattoLL(node);
4538 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4542 ir_mode *mode = get_irn_mode(node);
4543 if (ia32_mode_needs_gp_reg(mode)) {
4544 ir_node *new_pred = be_transform_node(pred);
4545 ir_node *block = be_transform_node(get_nodes_block(node));
4546 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4547 mode_Iu, get_Proj_proj(node));
4548 #ifdef DEBUG_libfirm
4549 new_proj->node_nr = node->node_nr;
4555 return be_duplicate_node(node);
4559 * Enters all transform functions into the generic pointer
4561 static void register_transformers(void)
4565 /* first clear the generic function pointer for all ops */
4566 clear_irp_opcodes_generic_func();
4568 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4569 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4607 /* transform ops from intrinsic lowering */
4619 GEN(ia32_l_LLtoFloat);
4620 GEN(ia32_l_FloattoLL);
4626 /* we should never see these nodes */
4641 /* handle generic backend nodes */
4650 op_Mulh = get_op_Mulh();
4659 * Pre-transform all unknown and noreg nodes.
4661 static void ia32_pretransform_node(void)
4663 ia32_code_gen_t *cg = env_cg;
4665 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4666 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4667 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4668 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4669 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4670 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4675 * Walker, checks if all ia32 nodes producing more than one result have their
4676 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4678 static void add_missing_keep_walker(ir_node *node, void *data)
4681 unsigned found_projs = 0;
4682 const ir_edge_t *edge;
4683 ir_mode *mode = get_irn_mode(node);
4688 if (!is_ia32_irn(node))
4691 n_outs = arch_irn_get_n_outs(node);
4694 if (is_ia32_SwitchJmp(node))
4697 assert(n_outs < (int) sizeof(unsigned) * 8);
4698 foreach_out_edge(node, edge) {
4699 ir_node *proj = get_edge_src_irn(edge);
4702 /* The node could be kept */
4706 if (get_irn_mode(proj) == mode_M)
4709 pn = get_Proj_proj(proj);
4710 assert(pn < n_outs);
4711 found_projs |= 1 << pn;
4715 /* are keeps missing? */
4717 for (i = 0; i < n_outs; ++i) {
4720 const arch_register_req_t *req;
4721 const arch_register_class_t *cls;
4723 if (found_projs & (1 << i)) {
4727 req = get_ia32_out_req(node, i);
4732 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4736 block = get_nodes_block(node);
4737 in[0] = new_r_Proj(current_ir_graph, block, node,
4738 arch_register_class_mode(cls), i);
4739 if (last_keep != NULL) {
4740 be_Keep_add_node(last_keep, cls, in[0]);
4742 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4743 if (sched_is_scheduled(node)) {
4744 sched_add_after(node, last_keep);
4751 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4754 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4756 ir_graph *irg = be_get_birg_irg(cg->birg);
4757 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4760 /* do the transformation */
4761 void ia32_transform_graph(ia32_code_gen_t *cg)
4765 register_transformers();
4767 initial_fpcw = NULL;
4769 BE_TIMER_PUSH(t_heights);
4770 heights = heights_new(cg->irg);
4771 BE_TIMER_POP(t_heights);
4772 ia32_calculate_non_address_mode_nodes(cg->birg);
4774 /* the transform phase is not safe for CSE (yet) because several nodes get
4775 * attributes set after their creation */
4776 cse_last = get_opt_cse();
4779 be_transform_graph(cg->birg, ia32_pretransform_node);
4781 set_opt_cse(cse_last);
4783 ia32_free_non_address_mode_nodes();
4784 heights_free(heights);
4788 void ia32_init_transform(void)
4790 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");